AgentSkillsCN

analyze-web

分析网络剪辑,以 Layer 1 内容创建资源笔记,并返回轻量级提案。它负责内容的丰富、分析、笔记创建以及 Layer 1 注入,确保内容始终不经过协调器。这是用于分诊协调器的工作者技能。

SKILL.md
--- frontmatter
name: analyze-web
description: Analyze web clippings, create resource notes with Layer 1 content, and return lightweight proposals. Handles enrichment, analysis, note creation, and Layer 1 injection so content never flows through coordinator. Worker skill for triage orchestrator.
user-invocable: false

Analyze Web Clipping

Analyze a single web clipping, create the resource note with Layer 1 content, and return a lightweight proposal.

Key design: This skill creates the resource note AND populates Layer 1 before returning. The full content stays in subagent context - only the proposal flows back to the coordinator.

Input

You receive:

  • file: Path to clipping in inbox (e.g., 00 Inbox/✂️ Article Title.md)
  • areas: Available areas in vault
  • projects: Available projects in vault

Output

Return a JSON proposal per @plugins/para-obsidian/skills/triage/references/proposal-schema.md.

Key: Use area (single wikilink), project (single wikilink or null), resourceType (camelCase). Include file, type: "clipping", created, and layer1_injected alongside the standard proposal fields.

Workflow

Step 1: Read Clipping

code
para_read({ file: "[input file]", response_format: "json" })

Extract frontmatter fields (source, domain, capture_reason, pre-filled areas/projects) from the YAML header in the para_read response. Do NOT call para_fm_get separately — para_read returns the full file including frontmatter.

Also extract existing body content.

Step 2: Fetch Full Content

CRITICAL: Select tool based on domain. Use ToolSearch to load deferred tools before calling them.

DomainToolToolSearch Query
youtube.com / youtu.beget_transcript (fallback: get_video_info)"youtube transcript"
x.com / twitter.comx_get_tweet (parse tweet_id from URL)"x-api tweet"
github.com / other articlesfirecrawl_scrape"firecrawl scrape"

X/Twitter is MANDATORY enrichment — Web Clipper captures only stubs. Always fetch via X-API regardless of clipping content.

See @plugins/para-obsidian/skills/triage/references/enrichment-strategies.md for the full routing table and constraints.

See @plugins/para-obsidian/references/content-sourcing/url-routing.md for detailed per-domain patterns.

Step 3: Analyze Content

Determine:

  1. Template: Is this learning material (resource) or reference (gift, booking, etc.)?
  2. Resource type: article, tutorial, reference, thread, issue, idea
  3. Source format: video, article, thread, document
  4. Categorization hints: 3 bullets for organizing (NOT deep learning - use /para-obsidian:distill-resource)
  5. Connections: Which areas/projects does this relate to?

Step 3.5: Pre-Creation Self-Check

Before calling para_create, verify your args object includes these critical fields:

  • summary — one-sentence description of the resource
  • areas — wikilink(s) to vault areas
  • source_formatarticle, thread, video, document
  • resource_typearticle, tutorial, reference, thread, issue, idea

If any field is missing but you determined a value in Step 3, add it to args now.

Step 4: Create Resource & Inject Layer 1 (Single Call)

This is where content stays isolated. Use para_create with the content parameter to create the note AND inject Layer 1 in a single tool call:

code
para_create({
  template: "resource",
  title: proposed_title,
  args: { ...fields from validArgs },
  content: {
    "<content-target-heading>": formattedLayerOneContent
  },
  response_format: "json"
})

The content parameter maps heading names to body content. The CLI internally creates the note, injects content into the matching section, and auto-commits — all in one invocation. No separate para_commit or para_replace_section calls needed.

Content target heading: Use creation_meta.contentTargets[0] from template fields (typically "Layer 1: Captured Notes"). If template fields were pre-loaded in the prompt context (triage mode), use those directly.

See @references/layer1-formatting.md for Layer 1 content formatting patterns (articles, YouTube, threads).

If para_create fails: Set created: null, layer1_injected: null, and continue with the proposal. The content parameter failure is atomic — no partial state.

Step 5: Verify & Repair

During triage: Skip this step entirely. Set verification_status: "pending_coordinator" and verification_issues: []. The coordinator handles verification in Phase 2.5 — it stamps and checks all critical fields from PROPOSAL_JSON.

Standalone callers (non-triage): Call para_fm_get on the created file. Compare each critical field:

FieldYour intended valueFile valueAction
summaryfrom Step 3from para_fm_getMISMATCH → repair
areasfrom Step 3from para_fm_getMISMATCH → repair
source_formatfrom Step 3from para_fm_getMISMATCH → repair
resource_typefrom Step 3from para_fm_getMISMATCH → repair

If any MISMATCH: para_fm_set({ file, set: { ...repairs }, response_format: "json" })

Set verification_status: "verified" (all match), "repaired" (fixed), "needs_review" (empty fields), "skipped" (para_create failed).

Step 6: Return Proposal

Return the lightweight JSON proposal. The resource is already created with Layer 1 populated.

json
{
  "file": "00 Inbox/✂️ Original.md",
  "type": "clipping",
  "proposed_title": "Title",
  "proposed_template": "resource",
  "summary": "...",
  "created": "03 Resources/Title.md",
  "layer1_injected": true,
  "verification_status": "verified",
  "verification_issues": [],
  ...
}

The coordinator receives only this ~500 byte proposal, not the 10-20k token content.

Template Routing

Content TypeTemplateResource Type
Tutorial/how-toresourcetutorial
News/opinionresourcearticle
Twitter threadresourcethread
API docsresourcereference
GitHub issueresourceissue
Product pagegift-
Booking confirmationbooking-
Flight/hotelbooking-

Confidence Levels

LevelMeaning
highClear content, obvious categorization
mediumReasonable guess, user may want to adjust
lowAmbiguous content, multiple valid interpretations

Example Output

json
{
  "file": "00 Inbox/✂️ Matt Pocock TypeScript Tips.md",
  "type": "clipping",
  "proposed_title": "TypeScript 5.5 Inference Improvements",
  "proposed_template": "resource",
  "summary": "Matt Pocock explains new type inference features in TypeScript 5.5, focusing on const type parameters and improved narrowing in control flow.",
  "categorization_hints": [
    "Const type parameters preserve literal types without 'as const'",
    "Control flow analysis now narrows in more cases",
    "New 'satisfies' patterns for type-safe object literals"
  ],
  "area": "[[🌱 AI Practice]]",
  "project": "[[🎯 TypeScript Migration]]",
  "resourceType": "tutorial",
  "source_format": "thread",
  "author": "Matt Pocock",
  "confidence": "high",
  "notes": null,
  "created": "03 Resources/TypeScript 5.5 Inference Improvements.md",
  "layer1_injected": true,
  "verification_status": "verified",
  "verification_issues": []
}

Error Handling

ScenarioAction
para_create (with content) failsSet created: null, layer1_injected: null, return error proposal
Content empty/unparseableCreate note without content parameter, set layer1_injected: false

Atomic creation: When using the content parameter, creation and injection are a single atomic operation. If it fails, there's no partial state to clean up.