Stable identifier (
SoftwareAgent.id) for the forge engine. Forge is the engine behind thecapturemeta verb — one of Tap’s three primitive planes (Capture / Replay / Verify). Plans produced by forge carrycompiled_bymetadata so consumers can distinguish forge output from hand-edits.
Forge is exposed via the single capture meta verb (per the v2 surface vocabulary — three meta verbs: capture / verify / mark). Internally it runs three stages that share an inspect cache:
Inspect — pulls the live page’s structural signal: JSON-LD, schema.org, Annotation/RDFa data, semantic HTML, network-layer JSON the page actually fetches, agents.json descriptors, OpenAPI references. Output is a normalised structural report; no plan is written.
intent) and emits a bare v2 Plan. Two paths:
observe (or act+confirm+key) array. The model writes Plan ops within the closed 11-op vocabulary, not arbitrary code. Requires the Capture tier or higher (core/auth.ts:gateAiForge).lintPlan before saving. Non-conformant outputs are rejected; the AI is reprompted up to N times. Saved plans land in ~/.tap/plans/<site>/<name>.plan.json. The core/auth.ts:gateCaptureSave fleet-cap gate fires before persistence: re-saves of an existing <site>/<name> (overwrite / heal) are exempt; new entries count against the tier budget (3 / 5 / 20).forge is part of the proprietary Tap CLI (closed engine). The output conforms to @taprun/spec v1.0+.
{
"id": { "site": "github", "name": "trending" },
"description": "Trending repos via the search API",
"observe": [
{
"op": "fetch",
"url": "https://api.github.com/search/repositories?q=stars:>1000",
"format": "json",
"save": "raw"
}
],
"return": "$.raw.items"
}
{
"id": { "site": "twitter", "name": "post" },
"args": { "text": { "type": "string", "required": true } },
"key": "$.args.text",
"observe": [
{ "op": "fetch", "url": "https://twitter.com/api/me/drafts", "save": "drafts" }
],
"act": [
{ "op": "input", "kind": "fill", "target": "[data-testid='tweetTextarea_0']", "value": "" },
{ "op": "input", "kind": "click", "target": "[data-testid='tweetButton']" }
],
"confirm": [
{ "op": "wait", "selector": "[data-testid='toast']", "timeout_ms": 5000 }
],
"return": "$.confirm[0]"
}
The read variant has no act or key (TypeScript: never). The write variant requires both. Invalid combinations are unrepresentable at the type level, not just at lint time.
Plan reference@taprun/from-playwright · @taprun/from-puppeteer · (@taprun/from-stagehand is deprecated — see migration guide)