ワンクリックで
wise-scraper
Structured web scraping for AI coders: explore, then exploit with shipped templates, runner, and hooks.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Structured web scraping for AI coders: explore, then exploit with shipped templates, runner, and hooks.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
Select and apply the right agentic design pattern when building an AI agent, workflow, or multi-step LLM system. Use this skill whenever the user is designing, architecting, debugging, or reviewing an agent/LLM pipeline and needs to decide HOW to structure it -- e.g. they mention agents, orchestration, multi-step workflows, RAG, routing, tool use, retries, evaluation, guardrails, memory, planning, or ask "how should I build/structure this agent?" or "which pattern fits this problem?". Maps problem symptoms to one of 20 patterns and specifies, for each, which steps are LLM calls vs deterministic code and what context each call carries. Use it even when the user does not say the word "pattern".
Build MCP servers, author routes/pipelines/functions, and manage all Cribl Stream artifacts (Stream, Edge, Search, Lake) via REST API and YAML configs. Use when user mentions Cribl, Cribl Stream/Edge/Search/Lake, routes, pipelines, sources, destinations, packs, or observability pipeline management.
Spec-driven development loop (plan → go → review → project) with lifecycle states, YAML frontmatter, a code-grounded feature projection (FEATURES.md), and docs refresh. ALWAYS LOAD THIS SKILL when working on any project that has a `.kiro/specs/` or `specs/` directory, or any CLAUDE.md/AGENTS.md that mentions specs. Use for planning, implementing, refining, or auditing specs, regenerating the feature ledger, or syncing README/docs/CHANGELOG with specs and code. Trigger on: any implementation work in a spec-managed project, specs, requirements/design/tasks, spec-plan, spec-go, spec-project, spec-docs, spec-audit, feature ledger, `.kiro`, `specs/`, 'keep working', 'continue', or resuming prior work. Never hand-edit FEATURES.md — it is derived.
Umbrella skill for agent work discipline across development, analysis, and documentation: inspect the repo before restructuring, keep durable truth in repo artifacts instead of chat memory, co-evolve specs/design/steering/user docs with code, apply sound coding patterns, verify work honestly, avoid shortcuts, work efficiently with subagents without hallucinating, and keep moving through the next concrete work item when the human is away. References cover coding patterns, AI-authored code review, and artifact co-evolution. Trigger when the user asks for workflow discipline, coding patterns, doc/artifact maintenance, code review of AI-authored code, project hygiene, execution guardrails, repo normalization, or when a task risks drifting across architecture, storage, specs, continuity, or tooling boundaries.
Plan and configure ralph-orchestrator deployments for projects at any stage — from a vague phase plan to a mature codebase. Use this skill whenever the user wants to set up ralph for a new project, choose between deployment topologies (direct, Claude+MCP, multi-project supervisor), pick the right config for their project's maturity, run oneshot autonomous builds, or manage multiple concurrent ralph loops across tmux sessions. Also use when the user asks "how should I run ralph on this?", mentions phase plans, or wants to configure cost budgets, hat workflows, or guardrails for a specific project type.
Deep skill for Splunk development, administration, SDK/REST integrations, dashboards, UCC add-ons, ITSI automation, SPL2 authoring, and AI-facing tooling. Use for Splunk SDK, REST, jobs/export, SPL, dashboards, packaging, and MCP-backed analysis workflows.
| name | wise-scraper |
| description | Structured web scraping for AI coders: explore, then exploit with shipped templates, runner, and hooks. |
| metadata | {"author":"kundeng","version":"2.0.0"} |
WISE teaches an AI coding agent structured, repeatable web scraping for JS-rendered sites. The goal is a working scraping project built from shipped WISE assets.
Rule 0 — Orient before acting. Before opening a browser or writing any code, read
references/guide.md § Big Pictureto understand what you're building and what decisions you need to make. Only then start exploration.
Orient → Explore → Evidence → Choose tier → Exploit → TreeRecord → Assemble
agent-browser, test selectors, map navigationUse when: JS-rendered sites, pagination, UI state, filter combos, structured repeatable output.
Not when: a stable API/export exists, or static curl is clearly enough.
WISE profiles define a graph of NER nodes. Each node is a deterministic (state, action) → observation triple:
| Part | Schema field | What it answers |
|---|---|---|
| State | state | "Am I where I expect to be?" — precondition check |
| Action | action | "What deterministic thing do I do?" — browser primitives |
| Observation | extract | "What do I read/emit from this state?" — extraction rules |
| Successors | expand | "How many successor states?" — elements, pages, or combinations |
| Retry | retry | "Re-execute parent actions if state check fails" — { max, delay_ms } |
Nodes form a DAG via parents[]. The engine walks top-down: check state, execute actions, extract, expand, recurse into children. The root node (named in entry.root) must have parents: [] — it is the entry point and has no parent. All other nodes must reference at least one parent that exists in the same resource's nodes list.
text, attr, link, table, ai, html, image, grouped. See references/field-guide.md § Extraction for details.
click, select, scroll, wait, reveal, navigate, input. See references/field-guide.md § Actions for details.
Instead of separate type: pagination / type: matrix / multiple: true, all successor-state generation goes through expand:
expand.over | What it does | Old equivalent |
|---|---|---|
elements | One successor per CSS match | multiple: true |
pages | One successor per page (next/numeric/infinite) | type: pagination |
combinations | Cartesian product of filter axes | type: matrix |
Each expand block supports order: dfs | bfs (default: dfs).
Stop conditions on page expansion: sentinel (CSS appears), sentinel_gone (CSS disappears), stable (element count stops changing), limit (hard cap). See references/field-guide.md § Stop Conditions.
Emit + expand interaction: When a node has both emit and expand, node-level extraction is skipped; extraction happens per-element inside the expansion. See references/guide.md § Data Flow.
After exploration, the agent declares what data it expects to produce in the artifacts block. This serves as:
consumes / produces wire resources into a DAGartifacts:
page_urls:
fields:
url: { type: string, required: true }
title: { type: string, required: true }
dedupe: url # deduplicate by this field
page_content:
fields:
title: { type: string, required: true }
body: { type: string, required: true }
consumes: page_urls # DAG edge: depends on page_urls
output: true # final deliverable (written to disk)
format: jsonl # output format: jsonl | csv | json | markdown
structure: nested # nested (tree JSON, default) or flat (denormalized)
Full artifact fields: fields, consumes, output, format, dedupe, structure, query, description. See schema.ts ArtifactSchema.
Resources declare produces and consumes to link into the artifact DAG. The runner resolves execution order automatically. The runner prevents double-writes automatically — when nodes emit directly, the resource-level store write is skipped.
The internal representation is TreeRecord (schema.ts):
interface TreeRecord {
node: string; // which NER node
url: string; // page URL at extraction time
data: Record<string, unknown>; // extracted payload
children: Record<string, TreeRecord[]>; // nested subtrees
extracted_at: string;
}
Children without emit nest inside their parent's children. Children with emit snip off into their own artifact bucket. emit copies/flattens subtrees into artifacts.
emit modes:
emit: "artifact_name" — shorthand: snapshot nested subtree to this artifactemit: [{ to: "artifact", flatten: ... }] — full form with per-target shaping
flatten: true — denormalize entire subtree (leaves only; interior nodes contribute context)flatten: "child_name" — flatten only a named child node's records or data fieldArtifactSchema.structure controls output shape:
"nested" (default) — tree JSON preserved"flat" — denormalized via flattenTree (records at leaves only)ArtifactSchema.query — optional JMESPath expression applied to tree records before output. The tree is converted to a clean document (data fields promoted to top-level, children keyed by node name) then queried. Enables both downward denormalization ([].pages[].books[].{title: title}) and upward aggregation ([].pages[].{titles: books[].title}). When query is set, it takes precedence over structure.
Template references — three scopes for {...} placeholders in URLs, navigate targets, and field refs:
{field} — local context (consumed record data, parent extraction){artifacts.name.field} — cross-artifact reference (latest record from named artifact){config.key} — input config reference (from CLI/YAML config)Entry URL cross-resource reference — entry.url can be { from: "resource.node.field" } instead of a string. This resolves to multiple visit targets by walking the named resource's tree records and extracting the field from matching nodes.
consumes — two levels:
consumes — drives entry URL iteration (the resource runs once per record in the consumed artifact)consumes — iterates within a walk (the node runs once per record, with fields available as {field_ref})consumes accepts a string or string[] (multiple artifacts merged)BFS is required for discovery + emit. When a node discovers URLs and emits them, use order: bfs so all URLs are collected before any child navigates away.
See references/field-guide.md § Emit and Consumes and references/guide.md § Data Flow for full details.
references/guide.md § Big Picture and scan templates/*.yaml before touching agent-browser or writing code.agent-browser to inspect DOM, interactions, and state.templates/*.yaml are composable — combine them. They are not alternatives.| Tier | When | What |
|---|---|---|
| 1 | Target fits declarative flow | Assemble template fragments + shipped runner |
| 2 | Target needs adaptation | Copy/adapt runner modules, hooks, AI adapter |
| 3 | Target exceeds reference boundary | Bespoke project, carrying WISE discipline |
| 4 | User prefers alternative runtime | Same YAML profile, different backend (profile format is runtime-agnostic by design; no multi-backend runner is shipped today) |
YAML profile → Zod validation → Engine → BrowserDriver → TreeRecord → Assembly
↕ ↕
AIAdapter agent-browser
schema.ts): runtime validation, TypeScript types, JSON Schema exportAgentBrowserDriver (CLI) is shipped. The interface is abstract and additional drivers can be implemented.NullAIAdapter (no-op); AIChatAdapter wraps aichat CLI and is opt-in via --ai-model flagexpand (elements/pages/combinations)post_discover, pre_extract, post_extract, pre_assemble, and post_assemble. pre_extract and post_extract can run at both resource and node scope; node hooks are selected by name from the module registry.skip_when (CSS check if already logged in) and a sequence of setup actions (open, click, input, password). See schema.ts StateSetup.Resources support a globals block for timing and retry defaults: timeout_ms, retries, user_agent, request_interval_ms, page_load_delay_ms. See schema.ts Resource.globals.
Do not read all references upfront. Read only what the current step needs:
| Step | Read |
|---|---|
| Orient | references/guide.md § Big Picture |
| Explore | agent-browser CLI help (agent-browser --help) |
| Choose tier / runtime | SKILL.md § Exploit Tiers, references/comparisons.md (if Tier 4) |
| Write profile | references/field-guide.md, references/schema.ts, scan templates/*.yaml |
| Add hooks | references/guide.md § Hook System |
| Add AI extraction | references/ai-adapter.md |
| Config / CLI | references/guide.md § Config Composition, § Runner CLI Reference |
| Worked examples | examples/overview.md |
state checkorder: bfs when you need to collect all URLs before visitingThese patterns recur across real scraping targets. Internalize them before writing profiles.
textContent on an element is often truncated or includes child-element noise. When the full value lives in an HTML attribute (e.g., title, aria-label, data-name), use attr extraction instead of text:
# Prefer this when <a> text is truncated but title has the full name
- attr: { name: company, css: "a.company-link", attr: "title" }
# Instead of
- text: { name: company, css: "a.company-link" }
Tip: During exploration, compare element.textContent with element.getAttribute('title') (or other attrs) to decide which source is authoritative.
When sorting is triggered by clicking a column header that changes the URL (e.g., ?sort=price), the sort is navigation-based, not JS-based. The child node's state.url_pattern check implicitly verifies the sort applied:
- name: sort
action:
- click: { css: "a.sort-by-price" }
- wait: { idle: true }
- name: rows
parents: [sort]
state:
url_pattern: "sort=price" # proves sort navigation succeeded
expand: { over: elements, scope: "table tbody tr" }
No separate sort-verification node is needed when the URL itself encodes the sort state.
link extraction returns raw href attribute values, which are often relative paths (/docs/page). When a consuming resource or node navigates to these URLs, prepend the base URL in the entry template or navigate action:
# In the consuming resource's entry
entry:
url: "https://example.com{url}" # {url} = "/docs/page" from artifact
root: page_node
# Or in a navigate action
action:
- navigate: { to: "https://example.com{url}" }
When expanding over elements for extraction, expand over the parent wrapper, not the leaf element you want to extract from. Expanding over <a> tags directly and then extracting link: { css: "a" } fails because the extractor looks for <a> children of <a>:
# Correct: expand over wrapper, extract from child
expand: { over: elements, scope: ".link-wrapper:has(a)" }
extract:
- link: { name: url, css: "a" }
# Wrong: expand over <a> directly, then extract <a> finds nothing
expand: { over: elements, scope: "a.doc-link" }
extract:
- link: { name: url, css: "a" } # looks for <a> inside <a> — fails
agent-browser or code before reading the frameworkentry.root) must have parents: []. A common mistake is setting parents: [root] on the entry root node itself, or on a pagination node that IS the root — this causes "unknown node" validation errors.entry.root: root but no node named root exists in nodes[], validation fails. Either add a root node or set entry.root to the actual first node name.