@gobing-ai/spur 0.3.94 → 0.3.95
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/README.md +42 -0
- package/board/index.d.ts +38 -0
- package/config/plugin-scripts.json +5 -0
- package/config/workflows/feature-verification.yaml +7 -4
- package/config/workflows/idea-pipeline.yaml +10 -4
- package/config/workflows/task-pipeline.yaml +54 -26
- package/config/workflows/wrapup-pipeline.yaml +92 -17
- package/package.json +15 -11
- package/plugins/sp/commands/dev-verify.md +7 -4
- package/plugins/sp/commands/dev-verifyall.md +4 -3
- package/plugins/sp/commands/dev-wrap.md +1 -1
- package/plugins/sp/hooks/context-post-tool.ts +2 -2
- package/plugins/sp/hooks/context-session-start.ts +2 -1
- package/plugins/sp/hooks/context-session-stop.ts +22 -14
- package/plugins/sp/hooks/pi/guard-extension.ts +109 -150
- package/plugins/sp/lib/idea-handoff.generated.mjs +2 -2
- package/plugins/sp/lib/inline-run.generated.d.mts +2 -2
- package/plugins/sp/lib/inline-run.generated.mjs +10 -10
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/scripts/daily-summary/daily-summary.mjs +3 -3
- package/plugins/sp/scripts/daily-summary/daily-summary.ts +3 -3
- package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.mjs +2 -0
- package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.ts +1 -0
- package/plugins/sp/scripts/dogfood-testing/validate-report.mjs +9 -7
- package/plugins/sp/scripts/dogfood-testing/validate-report.ts +8 -7
- package/plugins/sp/scripts/feature-sync-bounded.mjs +5 -2
- package/plugins/sp/scripts/feature-sync-bounded.ts +3 -1
- package/plugins/sp/scripts/feature-verification-steps.ts +6 -6
- package/plugins/sp/scripts/history-anatomy-cache.mjs +3 -3
- package/plugins/sp/scripts/history-anatomy-cache.ts +4 -4
- package/plugins/sp/scripts/inline-run-setup.mjs +23 -13
- package/plugins/sp/scripts/inline-run-setup.ts +60 -27
- package/plugins/sp/scripts/pr-reviewing.mjs +2 -0
- package/plugins/sp/scripts/pr-reviewing.ts +1 -0
- package/plugins/sp/scripts/quality-gate.mjs +4 -2
- package/plugins/sp/scripts/quality-gate.ts +8 -2
- package/plugins/sp/scripts/residual-scan.mjs +3 -3
- package/plugins/sp/scripts/residual-scan.ts +3 -3
- package/plugins/sp/scripts/script-contract-check.ts +175 -46
- package/plugins/sp/scripts/script-root.mjs +125 -0
- package/plugins/sp/scripts/script-root.ts +195 -0
- package/plugins/sp/scripts/stage-registry-adapter.ts +1 -1
- package/plugins/sp/scripts/task-evidence-precheck.ts +4 -2
- package/plugins/sp/scripts/task-size-precheck.ts +3 -1
- package/plugins/sp/scripts/validate-commands.ts +12 -12
- package/plugins/sp/scripts/validate-flag-contracts.ts +42 -30
- package/plugins/sp/scripts/verify-answer-lint.ts +3 -1
- package/plugins/sp/scripts/workflow-step-profile.mjs +5 -2
- package/plugins/sp/scripts/workflow-step-profile.ts +3 -1
- package/plugins/sp/scripts/wrapup-drift-probe.mjs +5 -2
- package/plugins/sp/scripts/wrapup-drift-probe.ts +4 -2
- package/plugins/sp/scripts/wrapup-steps.mjs +32 -8
- package/plugins/sp/scripts/wrapup-steps.ts +56 -10
- package/plugins/sp/skills/code-verification/SKILL.md +12 -7
- package/plugins/sp/skills/code-verification/references/verdict-schema.md +11 -0
- package/plugins/sp/skills/functional-review/SKILL.md +1 -1
- package/plugins/sp/skills/next-router/references/routing-table.md +1 -1
- package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +9 -1
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +30 -10
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +6 -3
- package/plugins/sp/tsconfig.json +8 -0
- package/spur.js +5194 -4457
- package/web/_astro/{BoardApp.FTEs3-N8.js → BoardApp.BxJuwD7I.js} +150 -153
- package/web/_astro/BoardApp.Cpxntzad.js +1 -0
- package/web/_astro/TaskDetail.C5bW4WGV.js +1 -0
- package/web/_astro/_commonjsHelpers.CqkleIqs.js +1 -0
- package/web/_astro/{arc.uuAf51IT.js → arc.CyjRvNMY.js} +1 -1
- package/web/_astro/architectureDiagram-3BPJPVTR.B4lWRzJA.js +36 -0
- package/web/_astro/{blockDiagram-GPEHLZMM.D1mGCq3p.js → blockDiagram-GPEHLZMM.Be38USQ2.js} +1 -1
- package/web/_astro/board-facade-react-dom-client.B2U5wMvk.js +1 -0
- package/web/_astro/board-facade-react-dom.Cd2MuMhF.js +1 -0
- package/web/_astro/board-facade-react-jsx-dev-runtime.B_L3JzfC.js +1 -0
- package/web/_astro/board-facade-react-jsx-runtime.BY2yfHRi.js +1 -0
- package/web/_astro/board-facade-react-router-dom.Dy5pjzOw.js +1 -0
- package/web/_astro/board-facade-react-router.DjjqU27_.js +1 -0
- package/web/_astro/board-facade-react.Dgf4GRyj.js +1 -0
- package/web/_astro/{c4Diagram-AAUBKEIU.CMsolcde.js → c4Diagram-AAUBKEIU.DT9Fj5Qx.js} +1 -1
- package/web/_astro/channel.CI6N_tCg.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.CrGA3fik.js → chunk-2J33WTMH.SeSBWLg5.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.DsLVVla0.js → chunk-4BX2VUAB.DoO4VE14.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.Dxc59Tfi.js → chunk-55IACEB6.DrmTFA53.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.CaEVE2Wy.js → chunk-727SXJPM.Bi-TUb_V.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.BiJ4HXeI.js → chunk-AQP2D5EJ.B-xp8Uhi.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.Mxf1fru5.js → chunk-FMBD7UC4.DGWrDnUU.js} +1 -1
- package/web/_astro/chunk-JMJ3UQ3L.BQJEJHu4.js +34 -0
- package/web/_astro/{chunk-ND2GUHAM.pyOWQixH.js → chunk-ND2GUHAM._BagvPDy.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.BmEsg4vr.js → chunk-QZHKN3VN.VOboYWQ0.js} +1 -1
- package/web/_astro/chunk-YNUBSHFH.CxeAygfi.js +7 -0
- package/web/_astro/{classDiagram-4FO5ZUOK.BHhhMFTO.js → classDiagram-4FO5ZUOK.D_apfHS7.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.BHhhMFTO.js → classDiagram-v2-Q7XG4LA2.D_apfHS7.js} +1 -1
- package/web/_astro/client.BhluLQqe.js +1 -0
- package/web/_astro/client.DBpSRLnx.js +9 -0
- package/web/_astro/cose-bilkent-S5V4N54A.DNLU_L-x.js +1 -0
- package/web/_astro/{cynefin-OW5HDTMX.C2j1_lKL.js → cynefin-OW5HDTMX.D8borhV-.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.hZ2NCTdT.js → dagre-BM42HDAG.Uc0lvjcV.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.Bfw5_EzK.js → diagram-2AECGRRQ.DDIxtDBo.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.Bt1V_Tmk.js → diagram-5GNKFQAL.DVoDnD3H.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.DEk-YFwp.js → diagram-KO2AKTUF.CRubTJ-0.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.CDjndtQm.js → diagram-LMA3HP47.m9SeYcXQ.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.cFnUHScG.js → diagram-OG6HWLK6.C6s2ZjV5.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.DlhYp7NV.js → erDiagram-TEJ5UH35.nSzr5KTj.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.DNTpsxfx.js → flowDiagram-I6XJVG4X.DrZcys16.js} +1 -1
- package/web/_astro/ganttDiagram-6RSMTGT7.Do4M1b-K.js +292 -0
- package/web/_astro/{gitGraphDiagram-PVQCEYII.DkEqNI0P.js → gitGraphDiagram-PVQCEYII.BWc9oJ4l.js} +1 -1
- package/web/_astro/index.5dn-Zm-2.js +1 -0
- package/web/_astro/index.C-IqPpW2.js +1 -0
- package/web/_astro/index.CENnIEqT.css +1 -0
- package/web/_astro/index.Cyc_GA4f.js +1 -0
- package/web/_astro/index.tZfqwSut.js +1 -0
- package/web/_astro/{infoDiagram-5YYISTIA.CrjioCTG.js → infoDiagram-5YYISTIA.BIdOctFk.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.BcK0CN8n.js → ishikawaDiagram-YF4QCWOH.CV5SuG2t.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.p0CbBDX1.js → journeyDiagram-JHISSGLW.CxE-rEJ-.js} +1 -1
- package/web/_astro/jsx-runtime.DWOiEOII.js +1 -0
- package/web/_astro/{kanban-definition-UN3LZRKU.puHIFt6J.js → kanban-definition-UN3LZRKU.BPRdKWs_.js} +1 -1
- package/web/_astro/{linear.Bb-3a1d7.js → linear.zRsuuDTE.js} +1 -1
- package/web/_astro/{mermaid.core.CJDgXOJs.js → mermaid.core.jAJTcMKc.js} +4 -4
- package/web/_astro/{mindmap-definition-RKZ34NQL.BoAZEI9t.js → mindmap-definition-RKZ34NQL.BffJxfCr.js} +1 -1
- package/web/_astro/{pieDiagram-4H26LBE5.CJNSdqY7.js → pieDiagram-4H26LBE5.CacwWaE3.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.DtTy7_0Z.js → quadrantDiagram-W4KKPZXB.hXELD06-.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.BNYV98Xg.js → requirementDiagram-4Y6WPE33.DdEbPcqT.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.DRq9DGHp.js → sankeyDiagram-5OEKKPKP.DgaDocKv.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.B7KdBFCm.js → sequenceDiagram-3UESZ5HK.B0KScnAu.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.CD62ZJ2H.js → stateDiagram-AJRCARHV.CV9M_WNc.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.CeVk1TAj.js → stateDiagram-v2-BHNVJYJU.BOAo74Et.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.C_ZPA5tT.js → timeline-definition-PNZ67QCA.CqqepUMe.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.CrThO_FQ.js → vennDiagram-CIIHVFJN.DDqe4dOG.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.DSZCA5nl.js → wardleyDiagram-YWT4CUSO.B3R9OPdO.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.KI7baTuk.js → xychartDiagram-2RQKCTM6.B3SvgXpQ.js} +1 -1
- package/web/board-runtime.json +69 -0
- package/web/index.html +2 -2
- package/web/_astro/BoardApp.C02hAHPO.js +0 -1
- package/web/_astro/TaskDetail.C-GdsS-t.js +0 -1
- package/web/_astro/architectureDiagram-3BPJPVTR.CGe629A1.js +0 -36
- package/web/_astro/channel.fsgl7o5j.js +0 -1
- package/web/_astro/client.yhYJvxCU.js +0 -9
- package/web/_astro/cose-bilkent-S5V4N54A.2fH4YOlp.js +0 -1
- package/web/_astro/ganttDiagram-6RSMTGT7.DC_p36PI.js +0 -292
- package/web/_astro/index.De90oHcH.js +0 -1
- package/web/_astro/index.Hjbr15fG.css +0 -1
|
@@ -407,12 +407,7 @@ END`;var MEASURE_COLS="messages, tool_calls, skill_calls, fresh_input_tokens, ca
|
|
|
407
407
|
''
|
|
408
408
|
)
|
|
409
409
|
ELSE ''
|
|
410
|
-
END`;var POST_WATERMARK_TABLES=[...KEYED_ROLLUP_TABLES,...GLOBAL_RANKED_ROLLUP_TABLES,"history_daily_stats","history_board_source_daily"];init_zod();import{createHash}from"node:crypto";function stableJson(value){if(Array.isArray(value))return`[${value.map((entry)=>entry===void 0?"null":stableJson(entry)).join(",")}]`;if(value!==null&&typeof value==="object"){let record2=value;return`{${Object.keys(record2).filter((key)=>record2[key]!==void 0).sort().map((key)=>`${JSON.stringify(key)}:${stableJson(record2[key])}`).join(",")}}`}return JSON.stringify(value)??"null"}function sha256(value){return createHash("sha256").update(stableJson(value)).digest("hex")}var MESSAGE_MAPPER_KEYS=["_codexUsageCarrier","session_id","seq","turn_index","role","record_type","disposition","ts","duration_ms","model","input_tokens","output_tokens","cache_read_tokens","cache_write_tokens","cost_usd","content_text","cwd","provenance","run_id","task_wbs","request_id"],TOOL_CALL_MAPPER_KEYS=["_messageSplitIndex","session_id","seq","tool_name","call_id","args_digest","args_raw","status","started_at","completed_at","duration_ms","result_bytes","error_text"],SKILL_CALL_MAPPER_KEYS=["_messageSplitIndex","session_id","seq","skill_name","invocation_kind","skill_path","args_raw","args_digest","call_id","status","started_at","completed_at","duration_ms"];function identityFieldMap(keys){let map2={};for(let key of keys)map2[key]=key;return map2}var HARNESS_SKILL_PACKAGES=new Set(["sp","rd3"]);function canonicalizeSkillName(raw){let name=raw.trim();if(name.startsWith("/")||name.startsWith("$"))name=name.slice(1);if(name.startsWith("skill:"))name=name.slice(6);let canonical=name.match(/^([a-z][a-z0-9]*):([a-z0-9-]+)$/);if(canonical!==null&&HARNESS_SKILL_PACKAGES.has(canonical[1]??""))return name;let dialect=name.match(/^([a-z][a-z0-9]*)-([a-z0-9-]+)$/);if(dialect!==null&&HARNESS_SKILL_PACKAGES.has(dialect[1]??""))return`${dialect[1]}:${dialect[2]}`;return name}function extractSkillCalls(raw,context,identity){switch(context?.source){case"claude":return detectClaudeSkillCalls(raw,identity);case"pi":return detectPiSkillCalls(raw,identity);case"omp":return detectOmpSkillCalls(raw,identity);case"codex":return detectCodexSkillCalls(raw,identity);case"agy":return detectAgySkillCalls(raw,identity);case"gemini":return detectGeminiSkillCalls(raw,identity);case"grok":return detectGrokSkillCalls(raw,identity);default:return[]}}function skillCallEntry(record2){return{targetTable:"history_skill_call",record:record2}}function skillRecord(identity,skillName,invocationKind,extra={}){return{_messageSplitIndex:identity.messageSplitIndex,session_id:identity.sessionId,seq:identity.seq,skill_name:canonicalizeSkillName(skillName),invocation_kind:invocationKind,skill_path:null,args_raw:null,args_digest:null,call_id:null,status:"ok",started_at:null,completed_at:null,duration_ms:null,...extra}}function skillNameFromPath(path){let normalized=path.replace(/\\/g,"/"),bySkillsSegment=normalized.match(/\/skills\/([^/]+)\/SKILL\.md$/i);if(bySkillsSegment!==null)return bySkillsSegment[1]??"";let stem=normalized.slice(0,normalized.length-9);return stem.split("/").pop()??stem}function detectClaudeSkillCalls(raw,identity){let contentBlocks=raw.content??o(raw.message).content;if(!Array.isArray(contentBlocks))return[];let rows=[];for(let block of contentBlocks){if(typeof block!=="object"||block===null)continue;let b=block;if(b.type!=="tool_use"||b.name!=="Skill")continue;let input=b.input??{},skill=s(input.skill);if(skill===void 0)continue;rows.push(skillRecord(identity,skill,s(o(b.caller).type)==="direct"?"user":"model",{args_raw:maybeArgsRaw("claude","Skill",input)??null,args_digest:argsDigest(input),call_id:s(b.id)??null}))}return rows}var PI_SKILL_WRAPPER=/<skill\s+name="([^"]+)"(?:\s+location="([^"]*)")?\s*>/g;function detectPiSkillCalls(raw,identity){let msg=raw.message;if(piRole(msg?.role??raw.role??raw.recordType??raw.type)!=="user")return[];let text=extractContentText(msg?.content??raw.content);if(text===void 0)return[];let rows=[];for(let match of text.matchAll(PI_SKILL_WRAPPER))rows.push(skillRecord(identity,match[1]??"","user",{skill_path:match[2]||null}));return rows}function detectOmpSkillCalls(raw,identity){let msg=raw.message;if(mapRole(msg?.role??raw.type??raw.role)!=="assistant")return[];let contentBlocks=msg?.content??raw.content;if(!Array.isArray(contentBlocks))return[];let rows=[];for(let block of contentBlocks){let call=normalizeOmpToolCall(block);if(call===null||call.name!=="Skill")continue;let input=call.input??call.arguments,skill=s(input?.skill);if(skill===void 0)continue;rows.push(skillRecord(identity,skill,"model",{args_raw:maybeArgsRaw("omp","Skill",input)??null,args_digest:argsDigest(input),call_id:s(call.id)??null}))}return rows}var CODEX_SKILL_BLOCK=/<skill>\s*<name>([^<]+)<\/name>\s*<path>([^<]+)<\/path>\s*<\/skill>/g;function detectCodexSkillCalls(raw,identity){let payload=raw.payload??raw,recordType=String(raw.type??""),payloadType=String(payload.type??""),role;if(recordType==="response_item")role=payloadType==="message"?mapRole(payload.role):payloadType==="agent_message"?"assistant":"meta";else if(recordType==="user"||recordType==="assistant")role=mapRole(recordType);else if(recordType==="message")role=mapRole(raw.role??payload.role);else return[];if(role!=="user")return[];let text=extractContentText(payload.content??raw.content)??s(payload.text,raw.text);if(text===void 0)return[];let rows=[];for(let match of text.matchAll(CODEX_SKILL_BLOCK))rows.push(skillRecord(identity,match[1]??"","user",{skill_path:match[2]??null}));return rows}function detectAgySkillCalls(raw,identity){if(String(raw.type??"")!=="PLANNER_RESPONSE"||!Array.isArray(raw.tool_calls))return[];let rows=[];for(let tc of raw.tool_calls){if(s(tc.name,tc.tool_name)!=="view_file")continue;let args=tc.args??tc.arguments??{};if(args.toolAction!=="Viewing skill file")continue;let path=s(args.AbsolutePath,args.absolute_path);if(path===void 0||!path.replace(/\\/g,"/").endsWith("/SKILL.md"))continue;let skillName=s(args.toolSummary)?.match(/SKILL\.md for (.+)$/)?.[1]??skillNameFromPath(path);rows.push(skillRecord(identity,skillName,"model",{skill_path:path,args_raw:maybeArgsRaw("agy","view_file",args)??null,args_digest:argsDigest(args)}))}return rows}var GEMINI_L0_PREFIX=/^\s*\/((?:sp|rd3)-[a-z0-9-]+)/;function detectGeminiSkillCalls(raw,identity){if(String(raw.type??"")!=="user")return[];let content=geminiContent(raw);if(content===null)return[];let match=content.match(GEMINI_L0_PREFIX);if(match===null)return[];return[skillRecord(identity,match[1]??"","user")]}function detectGrokSkillCalls(raw,identity){let n=normalizeGrokRecord(raw);if(n.recordType!=="tool_call"||n.toolName!=="read_file")return[];let meta3=n.body._meta??raw._meta??{};if(o(meta3["x.ai/tool"]).namespace!=="grok_build")return[];let targetFile=s(o(n.toolArgs).target_file);if(targetFile===void 0||!targetFile.replace(/\\/g,"/").endsWith("/SKILL.md"))return[];return[skillRecord(identity,skillNameFromPath(targetFile),"model",{skill_path:targetFile,args_raw:maybeArgsRaw("grok","read_file",n.toolArgs)??null,args_digest:argsDigest(n.toolArgs),started_at:n.ts??null})]}function argsDigest(args){let redacted=redactArgs(args);return sha256(redacted)}function redactArgs(args){if(typeof args==="string"){if(args.length>80)return"[REDACTED:long]";if(/[A-Za-z0-9+/]{40,}=*|[A-Za-z0-9_-]{20,}/.test(args))return"[REDACTED:secret]";return args}if(Array.isArray(args))return args.map(redactArgs);if(args!==null&&typeof args==="object"){let result={};for(let[key,value]of Object.entries(args))result[key]=redactArgs(value);return result}return args}var BASH_COMMAND_MAX_CHARS=8192,GENERIC_ARGS_MAX_CHARS=8192;function bashCommandOf(args){if(args===null||typeof args!=="object")return;let rec=args,command=rec.command??rec.CommandLine??rec.cmd??rec.script;if(typeof command==="string")return command;if(Array.isArray(command))return command.map(String).join(" ");return}var BULKY_PAYLOAD_KEYS=new Set(["content","codecontent","replacementcontent","targetcontent","filedata","buffer","blob","image","imagebase64"]);function normalizeKey(key){return key.toLowerCase().replace(/[^a-z0-9]/g,"")}function isShellTool(toolName){return/^(?:bash|shell|cmd|command|exec|execcommand|executecommand|runcommand|shellcommand|runshellcommand)$/.test(normalizeKey(toolName))}function sanitizeValue(value){if(typeof value==="string")return value.length>1000?`${value.slice(0,1000)}[truncated ${value.length} chars]`:value;if(Array.isArray(value))return value.map(sanitizeValue);if(value!==null&&typeof value==="object"){let out={};for(let[key,entry]of Object.entries(value))out[key]=typeof entry==="string"&&entry.length>120&&BULKY_PAYLOAD_KEYS.has(normalizeKey(key))?`[omitted ${entry.length} chars]`:sanitizeValue(entry);return out}return value}function serializeBounded(value){let serialized=JSON.stringify(sanitizeValue(value));if(serialized.length<=GENERIC_ARGS_MAX_CHARS)return serialized;let preview=serialized;for(;;){let wrapper=JSON.stringify({_truncated:!0,omittedChars:serialized.length-preview.length,preview});if(wrapper.length<=GENERIC_ARGS_MAX_CHARS)return wrapper;preview=preview.slice(0,preview.length-(wrapper.length-GENERIC_ARGS_MAX_CHARS))}}function maybeArgsRaw(_source,toolName,args){if(args===void 0||args===null)return;let value=args;if(typeof args==="string")try{value=JSON.parse(args)}catch{return args.length>BASH_COMMAND_MAX_CHARS?args.slice(0,BASH_COMMAND_MAX_CHARS):args}if(value!==null&&typeof value==="object"){let cmd=bashCommandOf(value);if(cmd!==void 0&&isShellTool(toolName))return cmd.length>BASH_COMMAND_MAX_CHARS?cmd.slice(0,BASH_COMMAND_MAX_CHARS):cmd;return serializeBounded(value)}return JSON.stringify(value)}function claudeSplit(raw,context){let entries=[],sessionId=s(raw.sessionId,raw.conversation_uuid)??"unknown",seq=typeof raw.seq==="number"?raw.seq:typeof raw.messageIndex==="number"?raw.messageIndex:0,ts=timestampOf(raw.ts,raw.timestamp,raw.createdAt),role=mapRole(raw.type??raw.role),recordType=String(raw.type??""),model=s(raw.model,o(raw.message).model),cwd=s(raw.cwd,raw.dir);if(raw.subtype==="turn_duration"&&typeof raw.durationMs==="number")return entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role:"system",record_type:"turn_duration",disposition:"meta",ts,duration_ms:raw.durationMs,content_text:null,provenance:"ambient"}}),entries;if(recordType==="attachment"||recordType.startsWith("file-history"))return entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role:"meta",record_type:recordType,disposition:"meta",ts,provenance:"ambient"}}),entries;let usage=typeof raw.usage==="object"&&raw.usage!==null?raw.usage:o(raw.message).usage,inputTokens=raw.inputTokens??usage?.input_tokens,outputTokens=raw.outputTokens??usage?.output_tokens,cacheRead=usage?.cacheReadTokens??usage?.cache_read_tokens??usage?.cache_read_input_tokens,cacheWrite=usage?.cacheWriteTokens??usage?.cache_write_tokens??usage?.cache_creation_input_tokens,costUsd=computeCost(inputTokens,outputTokens,model),contentBlocks=raw.content??o(raw.message).content,contentText=extractContentText(contentBlocks),messageSplitIndex=entries.length;if(entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,turn_index:typeof raw.turnIndex==="number"?raw.turnIndex:void 0,role,record_type:recordType,disposition:"keep",ts,duration_ms:void 0,model:model??null,input_tokens:inputTokens??null,output_tokens:outputTokens??null,cache_read_tokens:cacheRead??null,cache_write_tokens:cacheWrite??null,cost_usd:costUsd??null,content_text:contentText??null,cwd:cwd??null,provenance:"ambient",request_id:s(raw.requestId)??null}}),Array.isArray(contentBlocks)&&role==="assistant")for(let block of contentBlocks){if(typeof block!=="object"||block===null)continue;let b=block;if(b.type==="tool_use")entries.push({targetTable:"history_tool_call",record:{_messageSplitIndex:messageSplitIndex,session_id:sessionId,seq,call_id:s(b.id),tool_name:String(b.name??""),args_digest:argsDigest(b.input),args_raw:maybeArgsRaw("claude",String(b.name??""),b.input),status:"ok",started_at:void 0,completed_at:void 0,duration_ms:void 0,result_bytes:void 0,error_text:void 0}})}for(let record2 of extractSkillCalls(raw,context,{sessionId,seq,messageSplitIndex}))entries.push(skillCallEntry(record2));return entries}function piSplit(raw,context){let msg=raw.message,recordType=String(raw.type??raw.recordType??""),sessionId=sessionIdFromContext(context,raw),seq=context?.sourceLine??(typeof raw.seq==="number"?raw.seq:0),ts=timestampOf(raw.timestamp,raw.createdAt,raw.ts);if(recordType==="title"||recordType==="title_change"||recordType==="service_tier_change"||recordType==="session_info"||recordType==="ttsr_injection"||recordType==="session_init"||recordType==="session"||recordType==="model_change"||recordType==="thinking_level_change"||recordType==="compaction"||recordType==="custom"||recordType==="custom_message"||recordType.startsWith("custom."))return[{targetTable:"history_message",record:{session_id:sessionId,seq,role:"meta",record_type:recordType,disposition:"meta",ts,provenance:"ambient"}}];let entries=[],role=piRole(msg?.role??raw.role??recordType),model=s(raw.model,o(msg).model),cwd=s(raw.cwd,raw.dir),usage=msg?.usage??raw.usage,inputTokens=usage?.input??usage?.input_tokens??void 0,outputTokens=usage?.output??usage?.output_tokens??void 0,cacheRead=usage?.cacheRead??usage?.cache_read_tokens??void 0,cacheWrite=usage?.cacheWrite??usage?.cache_write_tokens??void 0,costObj=msg?.cost??raw.cost,costUsd=typeof costObj?.total==="number"?costObj.total:computeCost(inputTokens,outputTokens,model),contentBlocks=msg?.content??raw.content,durationMs=typeof msg?.duration==="number"&&Number.isFinite(msg.duration)?msg.duration:void 0,messageSplitIndex=entries.length;if(entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role,record_type:recordType,disposition:"keep",ts,duration_ms:durationMs,model:model??null,input_tokens:inputTokens??null,output_tokens:outputTokens??null,cache_read_tokens:cacheRead??null,cache_write_tokens:cacheWrite??null,cost_usd:costUsd??null,content_text:extractContentText(contentBlocks)??s(raw.content,raw.text,msg?.content)??null,cwd:cwd??null,provenance:"ambient"}}),Array.isArray(contentBlocks)&&role==="assistant")for(let block of contentBlocks){let call=normalizeOmpToolCall(block);if(call===null)continue;entries.push({targetTable:"history_tool_call",record:{_messageSplitIndex:messageSplitIndex,session_id:sessionId,seq,tool_name:String(call.name??""),call_id:s(call.id),args_digest:argsDigest(call.input??call.arguments),args_raw:maybeArgsRaw("pi",String(call.name??""),call.input??call.arguments),status:"ok",started_at:void 0,completed_at:void 0,duration_ms:void 0,result_bytes:void 0,error_text:void 0}})}for(let record2 of extractSkillCalls(raw,context,{sessionId,seq,messageSplitIndex}))entries.push(skillCallEntry(record2));return entries}function piRole(type){let t=String(type??"").toLowerCase();if(t==="toolresult"||t==="tool_result"||t==="bashexecution"||t==="tool")return"user";let mapped=mapRole(t);if(mapped==="user"||mapped==="assistant"||mapped==="system")return mapped;return"unknown"}function ompSplit(raw,context){let msg=raw.message,recordType=String(raw.type??""),sessionId=sessionIdFromContext(context,raw),seq=context?.sourceLine??(typeof raw.seq==="number"?raw.seq:0),ts=timestampOf(raw.ts,raw.timestamp,raw.createdAt);if(recordType==="title"||recordType==="title_change"||recordType==="service_tier_change"||recordType==="ttsr_injection"||recordType==="session_init"||recordType==="session"||recordType==="model_change"||recordType==="thinking_level_change"||recordType==="compaction"||recordType==="custom"||recordType==="custom_message"||recordType.startsWith("custom."))return[{targetTable:"history_message",record:{session_id:sessionId,seq,role:"meta",record_type:recordType,disposition:"meta",ts,provenance:"ambient"}}];let entries=[],role=mapRole(msg?.role??raw.type??raw.role),model=s(raw.model,o(msg).model),cwd=s(raw.cwd,raw.dir),usage=msg?.usage??raw.usage,inputTokens=usage?.input??usage?.input_tokens??void 0,outputTokens=usage?.output??usage?.output_tokens??void 0,cacheRead=usage?.cacheRead??usage?.cache_read_tokens??void 0,cacheWrite=usage?.cacheWrite??usage?.cache_write_tokens??void 0,costObj=msg?.cost??raw.cost,costUsd=typeof costObj?.total==="number"?costObj.total:computeCost(inputTokens,outputTokens,model),contentBlocks=msg?.content??raw.content,durationMs=typeof msg?.duration==="number"&&Number.isFinite(msg.duration)?msg.duration:void 0,messageSplitIndex=entries.length;if(entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role,record_type:recordType,disposition:"keep",ts,duration_ms:durationMs,model:model??null,input_tokens:inputTokens??null,output_tokens:outputTokens??null,cache_read_tokens:cacheRead??null,cache_write_tokens:cacheWrite??null,cost_usd:costUsd??null,content_text:extractContentText(contentBlocks)??s(raw.content,raw.text,msg?.content)??null,cwd:cwd??null,provenance:"ambient"}}),Array.isArray(contentBlocks)&&role==="assistant")for(let block of contentBlocks){let call=normalizeOmpToolCall(block);if(call===null)continue;entries.push({targetTable:"history_tool_call",record:{_messageSplitIndex:messageSplitIndex,session_id:sessionId,seq,tool_name:String(call.name??""),call_id:s(call.id),args_digest:argsDigest(call.input??call.arguments),args_raw:maybeArgsRaw("omp",String(call.name??""),call.input??call.arguments),status:"ok",started_at:void 0,completed_at:void 0,duration_ms:void 0,result_bytes:void 0,error_text:void 0}})}for(let record2 of extractSkillCalls(raw,context,{sessionId,seq,messageSplitIndex}))entries.push(skillCallEntry(record2));return entries}function normalizeOmpToolCall(block){if(typeof block!=="object"||block===null)return null;let nested=o(block.toolCall);if(Object.keys(nested).length>0)return nested;if(block.type==="toolCall")return block;return null}function codexSplit(raw,context){let entries=[],payload=raw.payload??raw,seq=typeof raw.seq==="number"?raw.seq:0,ts=timestampOf(raw.timestamp,raw.ts,payload.ts),recordType=String(raw.type??""),payloadType=String(payload.type??""),isShortFormat=recordType===""&&raw.id!==void 0&&raw.timestamp!==void 0&&raw.instructions!==void 0,explicitSessionId=s(raw.session_id,o(raw.session_meta).id);if(explicitSessionId===void 0&&recordType==="session_meta")explicitSessionId=s(payload.id,o(raw.payload).id);if(explicitSessionId===void 0&&isShortFormat)explicitSessionId=s(raw.id);let pathSessionId=context?.sourceFile?sessionIdFromSourcePath("codex",context.sourceFile):void 0,sessionId=explicitSessionId??pathSessionId??"unknown";if(isShortFormat)return[{targetTable:"history_message",record:{session_id:sessionId,seq,role:"meta",record_type:"short_format",disposition:"meta",ts,provenance:"ambient"}}];let role,disposition,contentText,usage;if(recordType==="response_item")if(payloadType==="message")role=mapRole(payload.role),disposition="keep",contentText=extractContentText(payload.content)??s(payload.text)??null;else if(payloadType==="agent_message")role="assistant",disposition="keep",contentText=extractContentText(payload.content)??s(payload.text,payload.message)??null;else if(payloadType==="reasoning")role="assistant",disposition="keep",contentText=extractContentText(payload.summary)??s(payload.text)??null;else if(payloadType==="function_call"||payloadType==="custom_tool_call")role="tool",disposition="keep",contentText=null;else role="meta",disposition="meta",contentText=s(payload.text)??null;else if(recordType==="user"||recordType==="assistant")role=mapRole(recordType),disposition="keep",contentText=extractContentText(payload.content)??s(raw.content,payload.text)??null;else if(recordType==="message")role=mapRole(raw.role??payload.role),disposition="keep",contentText=extractContentText(payload.content??raw.content)??s(payload.text,raw.text)??null;else if(recordType==="event_msg")role="meta",disposition="meta",contentText=s(payload.message,payload.text)??null,usage=o(o(payload.info).last_token_usage);else role="meta",disposition="meta",contentText=s(payload.text,raw.instructions)??null;let model=s(raw.model,payload.model,o(o(raw.turn_context).payload).model),cwd=s(raw.cwd,raw.dir),tokenCount=payload.token_count,usageInput=usage?.input_tokens??tokenCount?.input??tokenCount?.input_tokens??void 0,usageOutput=usage?.output_tokens??tokenCount?.output??tokenCount?.output_tokens??void 0,cacheRead=usage?.cached_input_tokens??void 0,turnPayload=raw.turn_context?.payload,turnInputTokens=turnPayload?.input_tokens,turnOutputTokens=turnPayload?.output_tokens,finalInput=usageInput!==void 0?usageInput:turnInputTokens,finalOutput=usageOutput!==void 0?usageOutput:turnOutputTokens,costUsd=computeCost(finalInput,finalOutput,model),usageCarrier=finalInput!==void 0||finalOutput!==void 0?{input:finalInput??null,output:finalOutput??null,cacheRead:cacheRead??null}:void 0,stripUsage=role==="meta"&&usageCarrier!==void 0,messageSplitIndex=entries.length;entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role,record_type:recordType,disposition,ts,duration_ms:void 0,model:model??null,input_tokens:stripUsage?null:finalInput??null,output_tokens:stripUsage?null:finalOutput??null,cache_read_tokens:stripUsage?null:cacheRead??null,...usageCarrier!==void 0?{_codexUsageCarrier:usageCarrier}:{},cache_write_tokens:null,cost_usd:costUsd??null,content_text:contentText,cwd:cwd??null,provenance:"ambient"}});let toolItems=[];if((recordType==="response_item"||recordType==="function_call"||recordType==="custom_tool_call")&&(payloadType==="function_call"||payloadType==="custom_tool_call"))toolItems.push(payload);else if(payload.response_item)toolItems.push(payload.response_item);else if(Array.isArray(payload.response_items))toolItems.push(...payload.response_items);for(let item of toolItems){let fc=item.function_call??item,toolName=s(fc.name)??"",args=fc.arguments??fc.input;entries.push({targetTable:"history_tool_call",record:{_messageSplitIndex:messageSplitIndex,session_id:sessionId,seq,tool_name:toolName,call_id:s(fc.call_id),args_digest:argsDigest(args),args_raw:maybeArgsRaw("codex",toolName,args),status:"ok",started_at:void 0,completed_at:void 0,duration_ms:void 0,result_bytes:void 0,error_text:void 0}})}for(let record2 of extractSkillCalls(raw,context,{sessionId,seq,messageSplitIndex}))entries.push(skillCallEntry(record2));return entries}function agySplit(raw,context){let entries=[],recordType=String(raw.type??""),explicitSessionId=s(raw.session_id,raw.conversation_id,raw.conversationId),pathSessionId=context?.sourceFile?sessionIdFromSourcePath("agy",context.sourceFile):void 0,sessionId=explicitSessionId??pathSessionId??"unknown",seq=typeof raw.seq==="number"?raw.seq:typeof raw.step_index==="number"?raw.step_index:context?.sourceLine??0,ts=timestampOf(raw.created_at,raw.timestamp,raw.ts),role,disposition,contentText=null,messageRecordType=recordType;if(raw.display!==void 0)role="user",disposition="keep",contentText=s(raw.display)??null,messageRecordType=recordType.length>0?recordType:"USER_INPUT";else switch(recordType){case"USER_INPUT":case"ASK_QUESTION":role="user",disposition="keep",contentText=s(raw.content,raw.text,raw.message)??null;break;case"PLANNER_RESPONSE":role="assistant",disposition="keep",contentText=s(raw.content,raw.text,raw.message,raw.plan)??null;break;case"ERROR_MESSAGE":role="system",disposition="keep",contentText=s(raw.content,raw.text,raw.message)??null;break;case"RUN_COMMAND":case"VIEW_FILE":case"GREP_SEARCH":case"LIST_DIRECTORY":case"READ_URL_CONTENT":role="tool",disposition="keep",contentText=s(raw.content,raw.command,raw.file_path,raw.pattern)??null;break;case"CODE_ACTION":case"INVOKE_SUBAGENT":role="tool",disposition="keep",contentText=s(raw.content,raw.text)??null;break;case"CONVERSATION_HISTORY":case"CHECKPOINT":case"GENERIC":role="meta",disposition="meta",contentText=s(raw.content,raw.text)??null;break;default:if(recordType.length===0)role="unknown",disposition="unknown";else role="meta",disposition="meta",contentText=s(raw.content,raw.text)??null;break}let messageSplitIndex=entries.length;if(entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role,record_type:messageRecordType,disposition,ts,duration_ms:void 0,model:null,input_tokens:null,output_tokens:null,cache_read_tokens:null,cache_write_tokens:null,cost_usd:null,content_text:contentText,cwd:s(raw.workspace,raw.cwd)??null,provenance:"ambient"}}),recordType==="PLANNER_RESPONSE"&&Array.isArray(raw.tool_calls))for(let tc of raw.tool_calls)entries.push({targetTable:"history_tool_call",record:{_messageSplitIndex:messageSplitIndex,session_id:sessionId,seq:typeof tc.step_index==="number"?tc.step_index:seq,tool_name:String(tc.name??tc.tool_name??""),args_digest:argsDigest(tc.input??tc.arguments),args_raw:maybeArgsRaw("agy",String(tc.name??tc.tool_name??""),tc.input??tc.arguments),status:"ok",started_at:void 0,completed_at:void 0,duration_ms:void 0,result_bytes:void 0,error_text:void 0}});for(let record2 of extractSkillCalls(raw,context,{sessionId,seq,messageSplitIndex}))entries.push(skillCallEntry(record2));return entries}function geminiSplit(raw,context){let recordType=String(raw.type??(raw.kind!==void 0?"session":raw.$set!==void 0?"state":"")),state=o(raw.$set),sessionId=sessionIdFromContext(context,raw),seq=context?.sourceLine??0,ts=timestampOf(raw.timestamp,raw.startTime,raw.lastUpdated,state.lastUpdated);if(recordType==="session"||recordType==="state")return[{targetTable:"history_message",record:{session_id:sessionId,seq,role:"meta",record_type:recordType,disposition:"meta",ts,content_text:s(state.summary)??null,provenance:"ambient"}}];let role=recordType==="gemini"?"assistant":recordType==="user"?"user":"system",tokens=o(raw.tokens),content=geminiContent(raw),entries=[{targetTable:"history_message",record:{session_id:sessionId,seq,role,record_type:recordType,disposition:"keep",ts,duration_ms:null,model:s(raw.model)??null,input_tokens:numberOrNull(tokens.input),output_tokens:numberOrNull(tokens.output),cache_read_tokens:numberOrNull(tokens.cached),cache_write_tokens:null,cost_usd:null,content_text:content,cwd:null,provenance:"ambient"}}];if(Array.isArray(raw.toolCalls))for(let value of raw.toolCalls){if(value===null||typeof value!=="object"||Array.isArray(value))continue;let tool=value,status=s(tool.status)??"unknown",timestamp=s(tool.timestamp),result=tool.result??tool.resultDisplay;entries.push({targetTable:"history_tool_call",record:{_messageSplitIndex:0,session_id:sessionId,seq,tool_name:s(tool.name,tool.displayName)??"unknown",args_digest:argsDigest(tool.args),args_raw:maybeArgsRaw("gemini",s(tool.name,tool.displayName)??"",tool.args),status,started_at:timestamp,completed_at:timestamp,duration_ms:null,result_bytes:result===void 0?null:new TextEncoder().encode(JSON.stringify(result)).byteLength,error_text:status==="error"?s(tool.resultDisplay,tool.result)??null:null}})}for(let record2 of extractSkillCalls(raw,context,{sessionId,seq,messageSplitIndex:0}))entries.push(skillCallEntry(record2));return entries}function dshSplit(raw,context){let recordType=String(raw.type??"");if(recordType==="session")return[{targetTable:"history_message",record:{session_id:s(raw.id)??sessionIdFromSourcePath("deepseek",context?.sourceFile??"")??"unknown",seq:0,role:"meta",record_type:"session",disposition:"meta",ts:timestampOf(raw.createdAt),cwd:s(raw.cwd)??null,content_text:null,provenance:"ambient"}}];if(recordType!=="user/message"&&recordType!=="assistant/message")return[];let data=o(raw.data),msg=o(data.message),seq=typeof raw.seq==="number"?raw.seq:context?.sourceLine??0,sessionId=sessionIdFromSourcePath("deepseek",context?.sourceFile??"")??"unknown",role=recordType==="user/message"?"user":"assistant",source=o(data.source??msg.source),model=s(source.model,o(data.model??msg.model).model),usage=data.usage??msg.usage,messageId=s(msg.id,data.id);return[{targetTable:"history_message",record:{session_id:sessionId,seq,role,record_type:recordType,disposition:"keep",...messageId!==void 0?{source_record_id:messageId}:{},ts:timestampOf(raw.time,data.time,msg.time),duration_ms:null,model:model??null,input_tokens:numberOrNull(usage?.input_tokens??usage?.input)??null,output_tokens:numberOrNull(usage?.output_tokens??usage?.output)??null,cache_read_tokens:null,cache_write_tokens:null,cost_usd:null,content_text:extractContentText(data.content??msg.content)??s(data.text,msg.text)??null,cwd:null,provenance:"ambient"}}]}var UUID_PATTERN="[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}",AGY_BRAIN_REGEX=new RegExp(`(?:^|\\/)brain\\/(${UUID_PATTERN})(?:\\/|$)`,"i"),DSH_SESSION_REGEX=new RegExp(`(?:^|\\/)session-(${UUID_PATTERN})(?:\\/|$)`,"i"),CODEX_ROLLOUT_REGEX=new RegExp(`(?:^|-|_)(${UUID_PATTERN})$`,"i");function sessionIdFromSourcePath(source,sourceFile){let normalized=sourceFile.replace(/\\/g,"/"),sLower=source.toLowerCase();if(sLower==="agy"||sLower==="antigravity")return normalized.match(AGY_BRAIN_REGEX)?.[1];if(sLower==="deepseek")return normalized.match(DSH_SESSION_REGEX)?.[1];if(sLower==="codex"){let basename=normalized.split("/").at(-1)??"";if(basename.startsWith("rollout-")&&basename.endsWith(".jsonl"))return basename.slice(0,-6).match(CODEX_ROLLOUT_REGEX)?.[1]}return}function sessionIdFromContext(context,raw){if(context!==void 0){let file2=context.sourceFile.split("/").at(-1);if(file2!==void 0)return file2.replace(/\.jsonl$/,"")}return s(raw.sessionId,raw.id)??"unknown"}function geminiContent(raw){let content=extractContentText(raw.content)??s(raw.text),thoughts=Array.isArray(raw.thoughts)?raw.thoughts.map((value)=>value!==null&&typeof value==="object"?s(o(value).description):void 0).filter((value)=>value!==void 0).join(`
|
|
411
|
-
`):"";return[content,thoughts].filter((value)=>value!==void 0&&value.length>0).join(`
|
|
412
|
-
`)||null}function numberOrNull(value){return typeof value==="number"&&Number.isFinite(value)?value:null}function normalizeGrokRecord(raw){let params=raw.params,update=params?.update,isUpdatesShape=typeof raw.method==="string"&¶ms!==void 0&&update!==void 0,body=isUpdatesShape?update:raw,recordType=String((isUpdatesShape?update?.sessionUpdate:raw.type)??raw.sessionUpdate??raw.eventType??(raw.file_snapshots!==void 0||raw.after_snapshots!==void 0?"file_snapshot":raw.prompt!==void 0?"user_message":raw.answer!==void 0||raw.question!==void 0?"assistant":"")),sessionId=s(params?.sessionId,raw.session_id,raw.sessionId,raw.parentSessionId,raw.btwSessionId,raw.params?.sessionId)??"unknown",ts=normalizeTs(raw.ts??raw.timestamp??raw.created_at??raw.askedAt??body.ts??body.timestamp),seq=typeof raw.seq==="number"?raw.seq:typeof body.seq==="number"?body.seq:0,meta3=body._meta??params?._meta??raw._meta,model=s(meta3?.modelId,body.model,raw.model),contentText=extractGrokContent(body.content??body.text??raw.content??raw.text??raw.prompt??(raw.answer!==void 0||raw.question!==void 0?[raw.question,raw.answer].filter((value)=>typeof value==="string").join(`
|
|
413
|
-
`):void 0)),usage=body.usage??raw.usage,toolMeta=meta3?.["x.ai/tool"],titleFallback=s(body.title)?.split("`")[0]?.trim(),toolName=s(toolMeta?.name,body.kind,body.tool_name,body.name,raw.tool_name,raw.name)??(titleFallback!==void 0&&titleFallback.length>0&&titleFallback.length<=40?titleFallback:""),toolArgs=body.rawInput??body.input??body.arguments??toolMeta?.input??raw.input??raw.arguments,toolStatus=s(body.status,raw.outcome,raw.status)??"ok",durationMs=typeof body.duration_ms==="number"?body.duration_ms:typeof raw.duration_ms==="number"?raw.duration_ms:typeof usage?.apiDurationMs==="number"?usage.apiDurationMs:void 0,errorText=body.error!==void 0?String(body.error):raw.error!==void 0?String(raw.error):void 0,hasTypeDiscriminator=recordType.length>0||isUpdatesShape;return{recordType,sessionId,ts,seq,body,model,contentText,usage,toolName,toolArgs,toolStatus,durationMs,errorText,hasTypeDiscriminator}}function normalizeTs(value){return timestampOf(value)}function extractGrokContent(content){if(typeof content==="string")return content;if(content!==null&&typeof content==="object"&&!Array.isArray(content)){let c=content;if(typeof c.text==="string")return c.text;if(typeof c.content==="string")return c.content}if(Array.isArray(content)){let parts=[];for(let block of content)if(typeof block==="string")parts.push(block);else if(block!==null&&typeof block==="object"){let b=block;if(typeof b.text==="string")parts.push(b.text)}return parts.length>0?parts.join(`
|
|
414
|
-
`):null}return null}var GROK_META_TYPES=new Set(["phase_changed","permission_requested","permission_resolved","mcp_server_starting","mcp_server_connected","mcp_config_resolved","mcp_managed_config_result","mcp_transport_decode_error","mcp_init_completed","mcp_health_check","loop_started","first_token","agent_thought_chunk","hook_execution","plan","session_recap","task_backgrounded","task_completed","retry_state","auto_compact_started","auto_compact_completed","compaction_checkpoint","image_compressed","reasoning","system","turn_started","turn_ended","yolo_toggled"]);function grokSplit(raw,context){let entries=[],n=normalizeGrokRecord(raw),{recordType,sessionId,ts,seq}=n;if(recordType==="turn_completed"){let usage=n.usage,modelUsage=usage?.modelUsage,modelFromUsage=modelUsage!==null&&typeof modelUsage==="object"?Object.keys(modelUsage)[0]:void 0,model=s(n.model,modelFromUsage),inputTokens=usage?.inputTokens??usage?.input??usage?.input_tokens,outputTokens=usage?.outputTokens??usage?.output??usage?.output_tokens,cacheRead=usage?.cachedReadTokens??usage?.cache_read_tokens;return entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role:"assistant",record_type:recordType,disposition:"keep",ts,duration_ms:n.durationMs??usage?.apiDurationMs??null,model:model??null,input_tokens:inputTokens??null,output_tokens:outputTokens??null,cache_read_tokens:cacheRead??null,cache_write_tokens:null,cost_usd:null,content_text:n.contentText,cwd:null,provenance:"ambient"}}),entries}if(recordType==="tool_started")return entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role:"assistant",record_type:recordType,disposition:"keep",ts,duration_ms:void 0,model:n.model??null,input_tokens:null,output_tokens:null,cache_read_tokens:null,cache_write_tokens:null,cost_usd:null,content_text:n.contentText,cwd:null,provenance:"ambient"}}),entries.push({targetTable:"history_tool_call",record:{_messageSplitIndex:0,session_id:sessionId,seq,tool_name:n.toolName,args_digest:argsDigest(n.toolArgs),args_raw:maybeArgsRaw("grok",n.toolName,n.toolArgs),status:n.toolStatus||"ok",started_at:ts,completed_at:void 0,duration_ms:void 0,result_bytes:void 0,error_text:n.errorText}}),entries;if(recordType==="tool_completed")return entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role:"assistant",record_type:recordType,disposition:"keep",ts,duration_ms:n.durationMs??null,model:n.model??null,input_tokens:null,output_tokens:null,cache_read_tokens:null,cache_write_tokens:null,cost_usd:null,content_text:n.contentText,cwd:null,provenance:"ambient"}}),entries.push({targetTable:"history_tool_call",record:{_messageSplitIndex:0,session_id:sessionId,seq,tool_name:n.toolName,args_digest:null,args_raw:void 0,status:n.toolStatus||"ok",started_at:void 0,completed_at:ts,duration_ms:n.durationMs,result_bytes:void 0,error_text:n.errorText}}),entries;if(recordType==="tool_call"||recordType==="tool_call_update"){entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role:"assistant",record_type:recordType,disposition:"keep",ts,duration_ms:void 0,model:n.model??null,input_tokens:null,output_tokens:null,cache_read_tokens:null,cache_write_tokens:null,cost_usd:null,content_text:n.contentText,cwd:null,provenance:"ambient"}}),entries.push({targetTable:"history_tool_call",record:{_messageSplitIndex:0,session_id:sessionId,seq,tool_name:n.toolName,args_digest:argsDigest(n.toolArgs),args_raw:maybeArgsRaw("grok",n.toolName,n.toolArgs),status:n.toolStatus||"ok",started_at:recordType==="tool_call"?ts:void 0,completed_at:recordType==="tool_call_update"?ts:void 0,duration_ms:n.durationMs,result_bytes:void 0,error_text:n.errorText}});for(let record2 of extractSkillCalls(raw,context,{sessionId,seq,messageSplitIndex:0}))entries.push(skillCallEntry(record2));return entries}if(recordType==="user"||recordType==="user_message"||recordType==="user_message_chunk"||recordType==="message")return entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role:"user",record_type:recordType||"user_message",disposition:"keep",ts,duration_ms:void 0,model:null,input_tokens:null,output_tokens:null,cache_read_tokens:null,cache_write_tokens:null,cost_usd:null,content_text:n.contentText,cwd:null,provenance:"ambient"}}),entries;if(recordType==="assistant"||recordType==="agent_message_chunk")return entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role:"assistant",record_type:recordType,disposition:"keep",ts,duration_ms:void 0,model:n.model??null,input_tokens:null,output_tokens:null,cache_read_tokens:null,cache_write_tokens:null,cost_usd:null,content_text:n.contentText,cwd:null,provenance:"ambient"}}),entries;if(GROK_META_TYPES.has(recordType))return entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role:"meta",record_type:recordType,disposition:"meta",ts,duration_ms:n.durationMs??null,model:n.model??null,input_tokens:null,output_tokens:null,cache_read_tokens:null,cache_write_tokens:null,cost_usd:null,content_text:n.contentText,cwd:null,provenance:"ambient"}}),entries;if(!n.hasTypeDiscriminator||recordType.length===0)return entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role:"unknown",record_type:stableFieldShape(raw),disposition:"unknown",ts,duration_ms:void 0,model:null,input_tokens:null,output_tokens:null,cache_read_tokens:null,cache_write_tokens:null,cost_usd:null,content_text:n.contentText,cwd:null,provenance:"ambient"}}),entries;return entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role:"meta",record_type:recordType,disposition:"meta",ts,duration_ms:n.durationMs??null,model:n.model??null,input_tokens:null,output_tokens:null,cache_read_tokens:null,cache_write_tokens:null,cost_usd:null,content_text:n.contentText,cwd:null,provenance:"ambient"}}),entries}function o(value){return typeof value==="object"&&value!==null?value:{}}function s(...values){for(let value of values){if(typeof value==="string"&&value.length>0)return value;if(typeof value==="number"&&Number.isFinite(value))return String(value)}return}function timestampOf(...values){for(let value of values){if(typeof value==="number"&&Number.isFinite(value)){let ms=value>1000000000000?value:value*1000;return new Date(ms).toISOString()}if(typeof value==="string"&&value.length>0){let asNum=Number(value);if(Number.isFinite(asNum)&&/^\d+(\.\d+)?$/.test(value.trim())){let ms=asNum>1000000000000?asNum:asNum*1000;return new Date(ms).toISOString()}return value}}return}function mapRole(type){let t=String(type??"").toLowerCase();if(t==="user"||t==="human"||t==="developer")return"user";if(t==="assistant"||t==="ai"||t==="model")return"assistant";if(t==="system"||t==="error")return"system";return t||"unknown"}function computeCost(inputTokens,outputTokens,model){if(inputTokens===void 0||inputTokens===null)return;if(outputTokens===void 0||outputTokens===null)return;let inputRate=model?.toLowerCase().includes("claude")?3:1,outputRate=model?.toLowerCase().includes("claude")?15:5;return(inputTokens*inputRate+outputTokens*outputRate)/1e6}function extractContentText(content){if(typeof content==="string")return content;if(!Array.isArray(content))return;let parts=[];for(let block of content){if(typeof block!=="object"||block===null)continue;let b=block;if(typeof b.text==="string")parts.push(b.text)}return parts.length>0?parts.join(`
|
|
415
|
-
`):void 0}function stableFieldShape(raw){return Object.keys(raw).map((k)=>k.toLowerCase()).sort().join("+")}var CLAUDE_FIELD_MAP=identityFieldMap(MESSAGE_MAPPER_KEYS.concat(TOOL_CALL_MAPPER_KEYS,SKILL_CALL_MAPPER_KEYS)),PI_FIELD_MAP=identityFieldMap(MESSAGE_MAPPER_KEYS.concat(TOOL_CALL_MAPPER_KEYS,SKILL_CALL_MAPPER_KEYS)),OMP_FIELD_MAP=identityFieldMap(MESSAGE_MAPPER_KEYS.concat(TOOL_CALL_MAPPER_KEYS,SKILL_CALL_MAPPER_KEYS)),CODEX_FIELD_MAP=identityFieldMap(MESSAGE_MAPPER_KEYS.concat(TOOL_CALL_MAPPER_KEYS,SKILL_CALL_MAPPER_KEYS)),AGY_FIELD_MAP=identityFieldMap(MESSAGE_MAPPER_KEYS.concat(TOOL_CALL_MAPPER_KEYS,SKILL_CALL_MAPPER_KEYS)),GROK_FIELD_MAP=identityFieldMap(MESSAGE_MAPPER_KEYS.concat(TOOL_CALL_MAPPER_KEYS,SKILL_CALL_MAPPER_KEYS)),GEMINI_FIELD_MAP=identityFieldMap(MESSAGE_MAPPER_KEYS.concat(TOOL_CALL_MAPPER_KEYS,SKILL_CALL_MAPPER_KEYS)),DSH_FIELD_MAP=identityFieldMap(MESSAGE_MAPPER_KEYS.concat(["source_record_id"])),passthroughSchema=exports_external.object({}).passthrough(),CLAUDE_SCHEMA=passthroughSchema,PI_SCHEMA=passthroughSchema,OMP_SCHEMA=passthroughSchema,CODEX_SCHEMA=passthroughSchema,AGY_SCHEMA=passthroughSchema,GROK_SCHEMA=passthroughSchema,GEMINI_SCHEMA=passthroughSchema,DSH_SCHEMA=passthroughSchema;var HISTORY_IMPORT_SCHEMA_VERSION="0.5.9",HISTORY_IMPORT_SCHEMA_SQL=`
|
|
410
|
+
END`;var POST_WATERMARK_TABLES=[...KEYED_ROLLUP_TABLES,...GLOBAL_RANKED_ROLLUP_TABLES,"history_daily_stats","history_board_source_daily"];var HISTORY_IMPORT_SCHEMA_VERSION="0.5.11",HISTORY_IMPORT_SCHEMA_SQL=`
|
|
416
411
|
CREATE TABLE IF NOT EXISTS history_import_checkpoint (
|
|
417
412
|
source TEXT NOT NULL,
|
|
418
413
|
source_file TEXT NOT NULL,
|
|
@@ -529,7 +524,12 @@ CREATE INDEX IF NOT EXISTS idx_history_skill_call_message_hash
|
|
|
529
524
|
ON history_skill_call(message_hash);
|
|
530
525
|
CREATE INDEX IF NOT EXISTS idx_history_skill_call_invocation_kind
|
|
531
526
|
ON history_skill_call(invocation_kind);
|
|
532
|
-
`.trim();init_zod();var sourceRecordSchema=exports_external.object({source_record_id:exports_external.string().min(1),created_at:exports_external.string().min(1),content:exports_external.string().min(1),role:exports_external.string().optional(),model:exports_external.string().optional()}).passthrough();function firstString(...values){for(let value of values){if(typeof value==="string"&&value.length>0)return value;if(typeof value==="number"&&Number.isFinite(value))return String(value)}return}function defaultCreatedAt(value){return firstString(value)??new Date(0).toISOString()}function defaultRecordId(value,raw,context){return firstString(value,raw.id,raw.uuid,raw.message_id,raw.messageId,raw.session_id,raw.sessionId,raw.conversation_id)??`${context.source}:${context.sourceFile}:${context.sourceLine}:${context.splitIndex}`}function defaultContent(value,raw){return firstString(value,raw.content,raw.text,raw.message,raw.prompt,raw.response,raw.output)}function transforms(){return{source_record_id:defaultRecordId,created_at:defaultCreatedAt,content:defaultContent,role:(value,raw)=>firstString(value,raw.role,raw.type),model:(value,raw)=>firstString(value,raw.model,raw.model_name,raw.modelName)}}function sourceDefinition(source,displayName,defaultRoots,filePatterns){return{source,displayName,defaultRoots,filePatterns,targetTable:`history_etl_${source}`,splitConfig:source==="pi"?{mode:"one-to-many",field:"messages"}:{mode:"one-to-one"},fieldMap:{id:"source_record_id",uuid:"source_record_id",message_id:"source_record_id",messageId:"source_record_id",session_id:"source_record_id",sessionId:"source_record_id",conversation_id:"source_record_id",timestamp:"created_at",created_at:"created_at",createdAt:"created_at",time:"created_at",content:"content",text:"content",message:"content",prompt:"content",response:"content",output:"content",role:"role",type:"role",model:"model",model_name:"model",modelName:"model"},fieldTransforms:transforms(),schema:sourceRecordSchema}}function customSourceDefinition(source,displayName,defaultRoots,filePatterns,split,fieldMap,schema){return{source,displayName,defaultRoots,filePatterns,targetTable:`history_etl_${source}`,splitConfig:{mode:"custom",split},fieldMap,fieldTransforms:{},schema}}var SOURCE_DEFINITIONS={pi:customSourceDefinition("pi","Pi",[".pi/agent/sessions"],["*.jsonl"],piSplit,PI_FIELD_MAP,PI_SCHEMA),claude:customSourceDefinition("claude","Claude Code",[".claude/projects"],["*.jsonl"],claudeSplit,CLAUDE_FIELD_MAP,CLAUDE_SCHEMA),codex:customSourceDefinition("codex","Codex",[".codex/sessions"],["*.jsonl"],codexSplit,CODEX_FIELD_MAP,CODEX_SCHEMA),omp:customSourceDefinition("omp","OMP",[".omp/agent/sessions"],["*.jsonl"],ompSplit,OMP_FIELD_MAP,OMP_SCHEMA),grok:customSourceDefinition("grok","Grok",[".grok/sessions"],["*.jsonl"],grokSplit,GROK_FIELD_MAP,GROK_SCHEMA),agy:{...customSourceDefinition("agy","Antigravity CLI",[".gemini/antigravity-cli"],["*.jsonl"],agySplit,AGY_FIELD_MAP,AGY_SCHEMA),corruptLinePolicy:"skip"},gemini:customSourceDefinition("gemini","Gemini CLI",[".gemini/tmp",".config/gemini"],["*.jsonl"],geminiSplit,GEMINI_FIELD_MAP,GEMINI_SCHEMA),deepseek:{...customSourceDefinition("deepseek","DeepSeek dsh",[".dsh/sessions"],["session.v3.jsonl","session.v3.jsonl.zstd"],dshSplit,DSH_FIELD_MAP,DSH_SCHEMA),corruptLinePolicy:"skip"},opencode:sourceDefinition("opencode","OpenCode",[".opencode",".local/share/opencode"],["*.jsonl"]),antigravity:sourceDefinition("antigravity","Antigravity",[".antigravity"],["*.jsonl"]),openclaw:sourceDefinition("openclaw","OpenClaw",[".openclaw"],["*.jsonl"])};var TYPED_HISTORY_TABLES=["history_message","history_tool_call","history_skill_call"];var BOOKKEEPING_HISTORY_TABLES=["history_import_checkpoint","history_import_ledger"],IMPORTER_OWNED_TABLES=[...TYPED_HISTORY_TABLES,...BOOKKEEPING_HISTORY_TABLES,...Object.values(SOURCE_DEFINITIONS).map((def)=>def.targetTable)];var SPUR_OWNED_HISTORY_TABLES=["history_run_session","history_task_session","history_tool_alias_map","history_daily_stats","history_board_loop_findings","history_board_message_5m","history_board_model_stats","history_board_ranked_steps","history_board_rollup_meta","history_board_rollup_watermark","history_board_rollup_bucket","history_board_session_stats","history_board_skill_5m","history_board_source_daily","history_board_source_stats","history_board_dimension_daily","history_board_kpi_window","history_board_tool_5m","history_board_tool_stats"],HISTORY_RESET_TABLES=[...IMPORTER_OWNED_TABLES,...SPUR_OWNED_HISTORY_TABLES];var IMPORTER_SCHEMA_LEDGER_PREFIX="importer_schema@";class ActionRunDao{db;constructor(db2){this.db=db2}async completedAtById(id){return(await this.db.queryFirst("SELECT completed_at FROM action_runs WHERE id = ?",id))?.completed_at??null}async setStartedAt(id,startedAt){await this.db.run("UPDATE action_runs SET started_at = ? WHERE id = ?",startedAt,id)}async actionRowsByRunId(runId){try{return await this.db.queryAll("SELECT id, node, kind, status, duration_ms, ok, result_json, started_at, completed_at, created_at FROM action_runs WHERE run_id = ? ORDER BY created_at",runId)}catch(error51){if(error51 instanceof Error&&error51.message.includes("no such table: action_runs"))return[];throw error51}}}init_dist4();init_schema();init_schema();init_schema();var workspacesTable=defineTable("workspaces",{id:text("id").primaryKey(),name:text("name").notNull().unique(),root:text("root").notNull(),purpose:text("purpose"),defaultAgent:text("default_agent"),...standardColumns}),workspaces=workspacesTable.table;var runsTable=defineTable("runs",{id:text("id").primaryKey(),workspaceId:text("workspace_id").references(()=>workspaces.id),workflowName:text("workflow_name"),mode:text("mode"),status:text("status").notNull(),agent:text("agent"),externalKey:text("external_key"),startedAt:integer2("started_at").notNull(),completedAt:integer2("completed_at"),metadataJson:text("metadata_json").notNull().default("{}"),...standardColumns}),runs=runsTable.table;var artifactsTable=defineTable("artifacts",{id:text("id").primaryKey(),runId:text("run_id").references(()=>runs.id),path:text("path").notNull(),kind:text("kind").notNull(),...standardColumns}),artifacts=artifactsTable.table;function createId(prefix){return`${prefix}_${crypto.randomUUID()}`}class ArtifactDao extends EntityDao{constructor(adapter){super(adapter,artifacts,[artifacts.id],"artifacts")}record(input){return super.create({id:createId("artifact"),runId:input.runId??null,path:input.path,kind:input.kind})}artifactsByRunId(runId){return this.adapter.queryAll("SELECT path, kind FROM artifacts WHERE run_id = ? ORDER BY id",runId)}artifactsWithIdByRunId(runId){return this.adapter.queryAll("SELECT id, path, kind FROM artifacts WHERE run_id = ? ORDER BY id",runId)}}init_schema();var phaseRunsTable=defineTable("phase_runs",{id:text("id").primaryKey(),runId:text("run_id").notNull().references(()=>runs.id),phase:text("phase").notNull(),status:text("status").notNull(),startedAt:integer2("started_at"),completedAt:integer2("completed_at"),...standardColumns}),phaseRuns=phaseRunsTable.table;init_dist4();function normalizePersistedWorkflowLayer(layer){if(layer==="bundled")return"shared";if(layer==="project"||layer==="registered"||layer==="shared")return layer;return null}class RunDao extends EntityDao{constructor(adapter){super(adapter,runs,[runs.id],"runs")}open(input={}){return super.create({id:createId("run"),workspaceId:input.workspaceId??null,status:input.status??"pending",agent:input.agent??null,startedAt:Date.now(),completedAt:null})}traceRows(filter){return this.adapter.queryAll(`SELECT id, workflow_name, mode, status, agent, started_at, completed_at, metadata_json
|
|
527
|
+
`.trim();init_zod();init_zod();import{createHash}from"node:crypto";function stableJson(value){if(Array.isArray(value))return`[${value.map((entry)=>entry===void 0?"null":stableJson(entry)).join(",")}]`;if(value!==null&&typeof value==="object"){let record2=value;return`{${Object.keys(record2).filter((key)=>record2[key]!==void 0).sort().map((key)=>`${JSON.stringify(key)}:${stableJson(record2[key])}`).join(",")}}`}return JSON.stringify(value)??"null"}function sha256(value){return createHash("sha256").update(stableJson(value)).digest("hex")}var MESSAGE_MAPPER_KEYS=["_codexUsageCarrier","session_id","seq","turn_index","role","record_type","disposition","ts","duration_ms","model","input_tokens","output_tokens","cache_read_tokens","cache_write_tokens","cost_usd","content_text","cwd","provenance","run_id","task_wbs","request_id"],TOOL_CALL_MAPPER_KEYS=["_messageSplitIndex","session_id","seq","tool_name","call_id","args_digest","args_raw","status","started_at","completed_at","duration_ms","result_bytes","error_text"],SKILL_CALL_MAPPER_KEYS=["_messageSplitIndex","session_id","seq","skill_name","invocation_kind","skill_path","args_raw","args_digest","call_id","status","started_at","completed_at","duration_ms"];function identityFieldMap(keys){let map2={};for(let key of keys)map2[key]=key;return map2}var HARNESS_SKILL_PACKAGES=new Set(["sp","rd3"]);function canonicalizeSkillName(raw){let name=raw.trim();if(name.startsWith("/")||name.startsWith("$"))name=name.slice(1);if(name.startsWith("skill:"))name=name.slice(6);let canonical=name.match(/^([a-z][a-z0-9]*):([a-z0-9-]+)$/);if(canonical!==null&&HARNESS_SKILL_PACKAGES.has(canonical[1]??""))return name;let dialect=name.match(/^([a-z][a-z0-9]*)-([a-z0-9-]+)$/);if(dialect!==null&&HARNESS_SKILL_PACKAGES.has(dialect[1]??""))return`${dialect[1]}:${dialect[2]}`;return name}function extractSkillCalls(raw,context,identity){switch(context?.source){case"claude":return detectClaudeSkillCalls(raw,identity);case"pi":return detectPiSkillCalls(raw,identity);case"omp":return detectOmpSkillCalls(raw,identity);case"codex":return detectCodexSkillCalls(raw,identity);case"agy":return detectAgySkillCalls(raw,identity);case"gemini":return detectGeminiSkillCalls(raw,identity);case"grok":return detectGrokSkillCalls(raw,identity);default:return[]}}function skillCallEntry(record2){return{targetTable:"history_skill_call",record:record2}}function skillRecord(identity,skillName,invocationKind,extra={}){return{_messageSplitIndex:identity.messageSplitIndex,session_id:identity.sessionId,seq:identity.seq,skill_name:canonicalizeSkillName(skillName),invocation_kind:invocationKind,skill_path:null,args_raw:null,args_digest:null,call_id:null,status:"ok",started_at:null,completed_at:null,duration_ms:null,...extra}}function skillNameFromPath(path){let normalized=path.replace(/\\/g,"/"),bySkillsSegment=normalized.match(/\/skills\/([^/]+)\/SKILL\.md$/i);if(bySkillsSegment!==null)return bySkillsSegment[1]??"";let stem=normalized.slice(0,normalized.length-9);return stem.split("/").pop()??stem}function detectClaudeSkillCalls(raw,identity){let contentBlocks=raw.content??o(raw.message).content;if(!Array.isArray(contentBlocks))return[];let rows=[];for(let block of contentBlocks){if(typeof block!=="object"||block===null)continue;let b=block;if(b.type!=="tool_use"||b.name!=="Skill")continue;let input=b.input??{},skill=s(input.skill);if(skill===void 0)continue;rows.push(skillRecord(identity,skill,s(o(b.caller).type)==="direct"?"user":"model",{args_raw:maybeArgsRaw("claude","Skill",input)??null,args_digest:argsDigest(input),call_id:s(b.id)??null}))}return rows}var PI_SKILL_WRAPPER=/<skill\s+name="([^"]+)"(?:\s+location="([^"]*)")?\s*>/g;function detectPiSkillCalls(raw,identity){let msg=raw.message;if(piRole(msg?.role??raw.role??raw.recordType??raw.type)!=="user")return[];let text=extractContentText(msg?.content??raw.content);if(text===void 0)return[];let rows=[];for(let match of text.matchAll(PI_SKILL_WRAPPER))rows.push(skillRecord(identity,match[1]??"","user",{skill_path:match[2]||null}));return rows}function detectOmpSkillCalls(raw,identity){let msg=raw.message;if(mapRole(msg?.role??raw.type??raw.role)!=="assistant")return[];let contentBlocks=msg?.content??raw.content;if(!Array.isArray(contentBlocks))return[];let rows=[];for(let block of contentBlocks){let call=normalizeOmpToolCall(block);if(call===null||call.name!=="Skill")continue;let input=call.input??call.arguments,skill=s(input?.skill);if(skill===void 0)continue;rows.push(skillRecord(identity,skill,"model",{args_raw:maybeArgsRaw("omp","Skill",input)??null,args_digest:argsDigest(input),call_id:s(call.id)??null}))}return rows}var CODEX_SKILL_BLOCK=/<skill>\s*<name>([^<]+)<\/name>\s*<path>([^<]+)<\/path>\s*<\/skill>/g;function detectCodexSkillCalls(raw,identity){let payload=raw.payload??raw,recordType=String(raw.type??""),payloadType=String(payload.type??""),role;if(recordType==="response_item")role=payloadType==="message"?mapRole(payload.role):payloadType==="agent_message"?"assistant":"meta";else if(recordType==="user"||recordType==="assistant")role=mapRole(recordType);else if(recordType==="message")role=mapRole(raw.role??payload.role);else return[];if(role!=="user")return[];let text=extractContentText(payload.content??raw.content)??s(payload.text,raw.text);if(text===void 0)return[];let rows=[];for(let match of text.matchAll(CODEX_SKILL_BLOCK))rows.push(skillRecord(identity,match[1]??"","user",{skill_path:match[2]??null}));return rows}function detectAgySkillCalls(raw,identity){if(String(raw.type??"")!=="PLANNER_RESPONSE"||!Array.isArray(raw.tool_calls))return[];let rows=[];for(let tc of raw.tool_calls){if(s(tc.name,tc.tool_name)!=="view_file")continue;let args=tc.args??tc.arguments??{};if(args.toolAction!=="Viewing skill file")continue;let path=s(args.AbsolutePath,args.absolute_path);if(path===void 0||!path.replace(/\\/g,"/").endsWith("/SKILL.md"))continue;let skillName=s(args.toolSummary)?.match(/SKILL\.md for (.+)$/)?.[1]??skillNameFromPath(path);rows.push(skillRecord(identity,skillName,"model",{skill_path:path,args_raw:maybeArgsRaw("agy","view_file",args)??null,args_digest:argsDigest(args)}))}return rows}var GEMINI_L0_PREFIX=/^\s*\/((?:sp|rd3)-[a-z0-9-]+)/;function detectGeminiSkillCalls(raw,identity){if(String(raw.type??"")!=="user")return[];let content=geminiContent(raw);if(content===null)return[];let match=content.match(GEMINI_L0_PREFIX);if(match===null)return[];return[skillRecord(identity,match[1]??"","user")]}function detectGrokSkillCalls(raw,identity){let n=normalizeGrokRecord(raw);if(n.recordType!=="tool_call"||n.toolName!=="read_file")return[];let meta3=n.body._meta??raw._meta??{};if(o(meta3["x.ai/tool"]).namespace!=="grok_build")return[];let targetFile=s(o(n.toolArgs).target_file);if(targetFile===void 0||!targetFile.replace(/\\/g,"/").endsWith("/SKILL.md"))return[];return[skillRecord(identity,skillNameFromPath(targetFile),"model",{skill_path:targetFile,args_raw:maybeArgsRaw("grok","read_file",n.toolArgs)??null,args_digest:argsDigest(n.toolArgs),started_at:n.ts??null})]}function argsDigest(args){let redacted=redactArgs(args);return sha256(redacted)}function redactArgs(args){if(typeof args==="string"){if(args.length>80)return"[REDACTED:long]";if(/[A-Za-z0-9+/]{40,}=*|[A-Za-z0-9_-]{20,}/.test(args))return"[REDACTED:secret]";return args}if(Array.isArray(args))return args.map(redactArgs);if(args!==null&&typeof args==="object"){let result={};for(let[key,value]of Object.entries(args))result[key]=redactArgs(value);return result}return args}var BASH_COMMAND_MAX_CHARS=8192,GENERIC_ARGS_MAX_CHARS=8192;function bashCommandOf(args){if(args===null||typeof args!=="object")return;let rec=args,command=rec.command??rec.CommandLine??rec.cmd??rec.script;if(typeof command==="string")return command;if(Array.isArray(command))return command.map(String).join(" ");return}var BULKY_PAYLOAD_KEYS=new Set(["content","codecontent","replacementcontent","targetcontent","filedata","buffer","blob","image","imagebase64"]);function normalizeKey(key){return key.toLowerCase().replace(/[^a-z0-9]/g,"")}function isShellTool(toolName){return/^(?:bash|shell|cmd|command|exec|execcommand|executecommand|runcommand|shellcommand|runshellcommand)$/.test(normalizeKey(toolName))}function sanitizeValue(value){if(typeof value==="string")return value.length>1000?`${value.slice(0,1000)}[truncated ${value.length} chars]`:value;if(Array.isArray(value))return value.map(sanitizeValue);if(value!==null&&typeof value==="object"){let out={};for(let[key,entry]of Object.entries(value))out[key]=typeof entry==="string"&&entry.length>120&&BULKY_PAYLOAD_KEYS.has(normalizeKey(key))?`[omitted ${entry.length} chars]`:sanitizeValue(entry);return out}return value}function serializeBounded(value){let serialized=JSON.stringify(sanitizeValue(value));if(serialized.length<=GENERIC_ARGS_MAX_CHARS)return serialized;let preview=serialized;for(;;){let wrapper=JSON.stringify({_truncated:!0,omittedChars:serialized.length-preview.length,preview});if(wrapper.length<=GENERIC_ARGS_MAX_CHARS)return wrapper;preview=preview.slice(0,preview.length-(wrapper.length-GENERIC_ARGS_MAX_CHARS))}}function maybeArgsRaw(_source,toolName,args){if(args===void 0||args===null)return;let value=args;if(typeof args==="string")try{value=JSON.parse(args)}catch{return args.length>BASH_COMMAND_MAX_CHARS?args.slice(0,BASH_COMMAND_MAX_CHARS):args}if(value!==null&&typeof value==="object"){let cmd=bashCommandOf(value);if(cmd!==void 0&&isShellTool(toolName))return cmd.length>BASH_COMMAND_MAX_CHARS?cmd.slice(0,BASH_COMMAND_MAX_CHARS):cmd;return serializeBounded(value)}return JSON.stringify(value)}function claudeSplit(raw,context){let entries=[],sessionId=s(raw.sessionId,raw.conversation_uuid)??"unknown",seq=typeof raw.seq==="number"?raw.seq:typeof raw.messageIndex==="number"?raw.messageIndex:0,ts=timestampOf(raw.ts,raw.timestamp,raw.createdAt),role=mapRole(raw.type??raw.role),recordType=String(raw.type??""),model=s(raw.model,o(raw.message).model),cwd=s(raw.cwd,raw.dir);if(raw.subtype==="turn_duration"&&typeof raw.durationMs==="number")return entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role:"system",record_type:"turn_duration",disposition:"meta",ts,duration_ms:raw.durationMs,content_text:null,provenance:"ambient"}}),entries;if(recordType==="attachment"||recordType.startsWith("file-history"))return entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role:"meta",record_type:recordType,disposition:"meta",ts,provenance:"ambient"}}),entries;let usage=typeof raw.usage==="object"&&raw.usage!==null?raw.usage:o(raw.message).usage,inputTokens=raw.inputTokens??usage?.input_tokens,outputTokens=raw.outputTokens??usage?.output_tokens,cacheRead=usage?.cacheReadTokens??usage?.cache_read_tokens??usage?.cache_read_input_tokens,cacheWrite=usage?.cacheWriteTokens??usage?.cache_write_tokens??usage?.cache_creation_input_tokens,costUsd=computeCost(inputTokens,outputTokens,model),contentBlocks=raw.content??o(raw.message).content,contentText=extractContentText(contentBlocks),messageSplitIndex=entries.length;if(entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,turn_index:typeof raw.turnIndex==="number"?raw.turnIndex:void 0,role,record_type:recordType,disposition:"keep",ts,duration_ms:void 0,model:model??null,input_tokens:inputTokens??null,output_tokens:outputTokens??null,cache_read_tokens:cacheRead??null,cache_write_tokens:cacheWrite??null,cost_usd:costUsd??null,content_text:contentText??null,cwd:cwd??null,provenance:"ambient",request_id:s(raw.requestId)??null}}),Array.isArray(contentBlocks)&&role==="assistant")for(let block of contentBlocks){if(typeof block!=="object"||block===null)continue;let b=block;if(b.type==="tool_use")entries.push({targetTable:"history_tool_call",record:{_messageSplitIndex:messageSplitIndex,session_id:sessionId,seq,call_id:s(b.id),tool_name:String(b.name??""),args_digest:argsDigest(b.input),args_raw:maybeArgsRaw("claude",String(b.name??""),b.input),status:"ok",started_at:void 0,completed_at:void 0,duration_ms:void 0,result_bytes:void 0,error_text:void 0}})}for(let record2 of extractSkillCalls(raw,context,{sessionId,seq,messageSplitIndex}))entries.push(skillCallEntry(record2));return entries}function piSplit(raw,context){let msg=raw.message,recordType=String(raw.type??raw.recordType??""),sessionId=sessionIdFromContext(context,raw),seq=context?.sourceLine??(typeof raw.seq==="number"?raw.seq:0),ts=timestampOf(raw.timestamp,raw.createdAt,raw.ts);if(recordType==="title"||recordType==="title_change"||recordType==="service_tier_change"||recordType==="session_info"||recordType==="ttsr_injection"||recordType==="session_init"||recordType==="session"||recordType==="model_change"||recordType==="thinking_level_change"||recordType==="compaction"||recordType==="custom"||recordType==="custom_message"||recordType.startsWith("custom."))return[{targetTable:"history_message",record:{session_id:sessionId,seq,role:"meta",record_type:recordType,disposition:"meta",ts,provenance:"ambient"}}];let entries=[],role=piRole(msg?.role??raw.role??recordType),model=s(raw.model,o(msg).model),cwd=s(raw.cwd,raw.dir),usage=msg?.usage??raw.usage,inputTokens=usage?.input??usage?.input_tokens??void 0,outputTokens=usage?.output??usage?.output_tokens??void 0,cacheRead=usage?.cacheRead??usage?.cache_read_tokens??void 0,cacheWrite=usage?.cacheWrite??usage?.cache_write_tokens??void 0,costObj=msg?.cost??raw.cost,costUsd=typeof costObj?.total==="number"?costObj.total:computeCost(inputTokens,outputTokens,model),contentBlocks=msg?.content??raw.content,durationMs=typeof msg?.duration==="number"&&Number.isFinite(msg.duration)?msg.duration:void 0,messageSplitIndex=entries.length;if(entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role,record_type:recordType,disposition:"keep",ts,duration_ms:durationMs,model:model??null,input_tokens:inputTokens??null,output_tokens:outputTokens??null,cache_read_tokens:cacheRead??null,cache_write_tokens:cacheWrite??null,cost_usd:costUsd??null,content_text:extractContentText(contentBlocks)??s(raw.content,raw.text,msg?.content)??null,cwd:cwd??null,provenance:"ambient"}}),Array.isArray(contentBlocks)&&role==="assistant")for(let block of contentBlocks){let call=normalizeOmpToolCall(block);if(call===null)continue;entries.push({targetTable:"history_tool_call",record:{_messageSplitIndex:messageSplitIndex,session_id:sessionId,seq,tool_name:String(call.name??""),call_id:s(call.id),args_digest:argsDigest(call.input??call.arguments),args_raw:maybeArgsRaw("pi",String(call.name??""),call.input??call.arguments),status:"ok",started_at:void 0,completed_at:void 0,duration_ms:void 0,result_bytes:void 0,error_text:void 0}})}for(let record2 of extractSkillCalls(raw,context,{sessionId,seq,messageSplitIndex}))entries.push(skillCallEntry(record2));return entries}function piRole(type){let t=String(type??"").toLowerCase();if(t==="toolresult"||t==="tool_result"||t==="bashexecution"||t==="tool")return"user";let mapped=mapRole(t);if(mapped==="user"||mapped==="assistant"||mapped==="system")return mapped;return"unknown"}function ompSplit(raw,context){let msg=raw.message,recordType=String(raw.type??""),sessionId=sessionIdFromContext(context,raw),seq=context?.sourceLine??(typeof raw.seq==="number"?raw.seq:0),ts=timestampOf(raw.ts,raw.timestamp,raw.createdAt);if(recordType==="title"||recordType==="title_change"||recordType==="service_tier_change"||recordType==="ttsr_injection"||recordType==="session_init"||recordType==="session"||recordType==="model_change"||recordType==="thinking_level_change"||recordType==="compaction"||recordType==="custom"||recordType==="custom_message"||recordType.startsWith("custom."))return[{targetTable:"history_message",record:{session_id:sessionId,seq,role:"meta",record_type:recordType,disposition:"meta",ts,provenance:"ambient"}}];let entries=[],role=mapRole(msg?.role??raw.type??raw.role),model=s(raw.model,o(msg).model),cwd=s(raw.cwd,raw.dir),usage=msg?.usage??raw.usage,inputTokens=usage?.input??usage?.input_tokens??void 0,outputTokens=usage?.output??usage?.output_tokens??void 0,cacheRead=usage?.cacheRead??usage?.cache_read_tokens??void 0,cacheWrite=usage?.cacheWrite??usage?.cache_write_tokens??void 0,costObj=msg?.cost??raw.cost,costUsd=typeof costObj?.total==="number"?costObj.total:computeCost(inputTokens,outputTokens,model),contentBlocks=msg?.content??raw.content,durationMs=typeof msg?.duration==="number"&&Number.isFinite(msg.duration)?msg.duration:void 0,messageSplitIndex=entries.length;if(entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role,record_type:recordType,disposition:"keep",ts,duration_ms:durationMs,model:model??null,input_tokens:inputTokens??null,output_tokens:outputTokens??null,cache_read_tokens:cacheRead??null,cache_write_tokens:cacheWrite??null,cost_usd:costUsd??null,content_text:extractContentText(contentBlocks)??s(raw.content,raw.text,msg?.content)??null,cwd:cwd??null,provenance:"ambient"}}),Array.isArray(contentBlocks)&&role==="assistant")for(let block of contentBlocks){let call=normalizeOmpToolCall(block);if(call===null)continue;entries.push({targetTable:"history_tool_call",record:{_messageSplitIndex:messageSplitIndex,session_id:sessionId,seq,tool_name:String(call.name??""),call_id:s(call.id),args_digest:argsDigest(call.input??call.arguments),args_raw:maybeArgsRaw("omp",String(call.name??""),call.input??call.arguments),status:"ok",started_at:void 0,completed_at:void 0,duration_ms:void 0,result_bytes:void 0,error_text:void 0}})}for(let record2 of extractSkillCalls(raw,context,{sessionId,seq,messageSplitIndex}))entries.push(skillCallEntry(record2));return entries}function normalizeOmpToolCall(block){if(typeof block!=="object"||block===null)return null;let nested=o(block.toolCall);if(Object.keys(nested).length>0)return nested;if(block.type==="toolCall")return block;return null}function codexSplit(raw,context){let entries=[],payload=raw.payload??raw,seq=typeof raw.seq==="number"?raw.seq:0,ts=timestampOf(raw.timestamp,raw.ts,payload.ts),recordType=String(raw.type??""),payloadType=String(payload.type??""),isShortFormat=recordType===""&&raw.id!==void 0&&raw.timestamp!==void 0&&raw.instructions!==void 0,explicitSessionId=s(raw.session_id,o(raw.session_meta).id);if(explicitSessionId===void 0&&recordType==="session_meta")explicitSessionId=s(payload.id,o(raw.payload).id);if(explicitSessionId===void 0&&isShortFormat)explicitSessionId=s(raw.id);let pathSessionId=context?.sourceFile?sessionIdFromSourcePath("codex",context.sourceFile):void 0,sessionId=explicitSessionId??pathSessionId??"unknown";if(isShortFormat)return[{targetTable:"history_message",record:{session_id:sessionId,seq,role:"meta",record_type:"short_format",disposition:"meta",ts,provenance:"ambient"}}];let role,disposition,contentText,usage;if(recordType==="response_item")if(payloadType==="message")role=mapRole(payload.role),disposition="keep",contentText=extractContentText(payload.content)??s(payload.text)??null;else if(payloadType==="agent_message")role="assistant",disposition="keep",contentText=extractContentText(payload.content)??s(payload.text,payload.message)??null;else if(payloadType==="reasoning")role="assistant",disposition="keep",contentText=extractContentText(payload.summary)??s(payload.text)??null;else if(payloadType==="function_call"||payloadType==="custom_tool_call")role="tool",disposition="keep",contentText=null;else role="meta",disposition="meta",contentText=s(payload.text)??null;else if(recordType==="user"||recordType==="assistant")role=mapRole(recordType),disposition="keep",contentText=extractContentText(payload.content)??s(raw.content,payload.text)??null;else if(recordType==="message")role=mapRole(raw.role??payload.role),disposition="keep",contentText=extractContentText(payload.content??raw.content)??s(payload.text,raw.text)??null;else if(recordType==="event_msg")role="meta",disposition="meta",contentText=s(payload.message,payload.text)??null,usage=o(o(payload.info).last_token_usage);else role="meta",disposition="meta",contentText=s(payload.text,raw.instructions)??null;let model=s(raw.model,payload.model,o(o(raw.turn_context).payload).model),cwd=s(raw.cwd,raw.dir),tokenCount=payload.token_count,usageInput=usage?.input_tokens??tokenCount?.input??tokenCount?.input_tokens??void 0,usageOutput=usage?.output_tokens??tokenCount?.output??tokenCount?.output_tokens??void 0,cacheRead=usage?.cached_input_tokens??void 0,turnPayload=raw.turn_context?.payload,turnInputTokens=turnPayload?.input_tokens,turnOutputTokens=turnPayload?.output_tokens,finalInput=usageInput!==void 0?usageInput:turnInputTokens,finalOutput=usageOutput!==void 0?usageOutput:turnOutputTokens,costUsd=computeCost(finalInput,finalOutput,model),usageCarrier=finalInput!==void 0||finalOutput!==void 0?{input:finalInput??null,output:finalOutput??null,cacheRead:cacheRead??null}:void 0,stripUsage=role==="meta"&&usageCarrier!==void 0,messageSplitIndex=entries.length;entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role,record_type:recordType,disposition,ts,duration_ms:void 0,model:model??null,input_tokens:stripUsage?null:finalInput??null,output_tokens:stripUsage?null:finalOutput??null,cache_read_tokens:stripUsage?null:cacheRead??null,...usageCarrier!==void 0?{_codexUsageCarrier:usageCarrier}:{},cache_write_tokens:null,cost_usd:costUsd??null,content_text:contentText,cwd:cwd??null,provenance:"ambient"}});let toolItems=[];if((recordType==="response_item"||recordType==="function_call"||recordType==="custom_tool_call")&&(payloadType==="function_call"||payloadType==="custom_tool_call"))toolItems.push(payload);else if(payload.response_item)toolItems.push(payload.response_item);else if(Array.isArray(payload.response_items))toolItems.push(...payload.response_items);for(let item of toolItems){let fc=item.function_call??item,toolName=s(fc.name)??"",args=fc.arguments??fc.input;entries.push({targetTable:"history_tool_call",record:{_messageSplitIndex:messageSplitIndex,session_id:sessionId,seq,tool_name:toolName,call_id:s(fc.call_id),args_digest:argsDigest(args),args_raw:maybeArgsRaw("codex",toolName,args),status:"ok",started_at:void 0,completed_at:void 0,duration_ms:void 0,result_bytes:void 0,error_text:void 0}})}for(let record2 of extractSkillCalls(raw,context,{sessionId,seq,messageSplitIndex}))entries.push(skillCallEntry(record2));return entries}function agySplit(raw,context){let entries=[],recordType=String(raw.type??""),explicitSessionId=s(raw.session_id,raw.conversation_id,raw.conversationId),pathSessionId=context?.sourceFile?sessionIdFromSourcePath("agy",context.sourceFile):void 0,sessionId=explicitSessionId??pathSessionId??"unknown",seq=typeof raw.seq==="number"?raw.seq:typeof raw.step_index==="number"?raw.step_index:context?.sourceLine??0,ts=timestampOf(raw.created_at,raw.timestamp,raw.ts),role,disposition,contentText=null,messageRecordType=recordType;if(raw.display!==void 0)role="user",disposition="keep",contentText=s(raw.display)??null,messageRecordType=recordType.length>0?recordType:"USER_INPUT";else switch(recordType){case"USER_INPUT":case"ASK_QUESTION":role="user",disposition="keep",contentText=s(raw.content,raw.text,raw.message)??null;break;case"PLANNER_RESPONSE":role="assistant",disposition="keep",contentText=s(raw.content,raw.text,raw.message,raw.plan)??null;break;case"ERROR_MESSAGE":role="system",disposition="keep",contentText=s(raw.content,raw.text,raw.message)??null;break;case"RUN_COMMAND":case"VIEW_FILE":case"GREP_SEARCH":case"LIST_DIRECTORY":case"READ_URL_CONTENT":role="tool",disposition="keep",contentText=s(raw.content,raw.command,raw.file_path,raw.pattern)??null;break;case"CODE_ACTION":case"INVOKE_SUBAGENT":role="tool",disposition="keep",contentText=s(raw.content,raw.text)??null;break;case"CONVERSATION_HISTORY":case"CHECKPOINT":case"GENERIC":role="meta",disposition="meta",contentText=s(raw.content,raw.text)??null;break;default:if(recordType.length===0)role="unknown",disposition="unknown";else role="meta",disposition="meta",contentText=s(raw.content,raw.text)??null;break}let messageSplitIndex=entries.length;if(entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role,record_type:messageRecordType,disposition,ts,duration_ms:void 0,model:null,input_tokens:null,output_tokens:null,cache_read_tokens:null,cache_write_tokens:null,cost_usd:null,content_text:contentText,cwd:s(raw.workspace,raw.cwd)??null,provenance:"ambient"}}),recordType==="PLANNER_RESPONSE"&&Array.isArray(raw.tool_calls))for(let tc of raw.tool_calls)entries.push({targetTable:"history_tool_call",record:{_messageSplitIndex:messageSplitIndex,session_id:sessionId,seq:typeof tc.step_index==="number"?tc.step_index:seq,tool_name:String(tc.name??tc.tool_name??""),args_digest:argsDigest(tc.input??tc.arguments),args_raw:maybeArgsRaw("agy",String(tc.name??tc.tool_name??""),tc.input??tc.arguments),status:"ok",started_at:void 0,completed_at:void 0,duration_ms:void 0,result_bytes:void 0,error_text:void 0}});for(let record2 of extractSkillCalls(raw,context,{sessionId,seq,messageSplitIndex}))entries.push(skillCallEntry(record2));return entries}function geminiSplit(raw,context){let recordType=String(raw.type??(raw.kind!==void 0?"session":raw.$set!==void 0?"state":"")),state=o(raw.$set),sessionId=sessionIdFromContext(context,raw),seq=context?.sourceLine??0,ts=timestampOf(raw.timestamp,raw.startTime,raw.lastUpdated,state.lastUpdated);if(recordType==="session"||recordType==="state")return[{targetTable:"history_message",record:{session_id:sessionId,seq,role:"meta",record_type:recordType,disposition:"meta",ts,content_text:s(state.summary)??null,provenance:"ambient"}}];let role=recordType==="gemini"?"assistant":recordType==="user"?"user":"system",tokens=o(raw.tokens),content=geminiContent(raw),entries=[{targetTable:"history_message",record:{session_id:sessionId,seq,role,record_type:recordType,disposition:"keep",ts,duration_ms:null,model:s(raw.model)??null,input_tokens:numberOrNull(tokens.input),output_tokens:numberOrNull(tokens.output),cache_read_tokens:numberOrNull(tokens.cached),cache_write_tokens:null,cost_usd:null,content_text:content,cwd:null,provenance:"ambient"}}];if(Array.isArray(raw.toolCalls))for(let value of raw.toolCalls){if(value===null||typeof value!=="object"||Array.isArray(value))continue;let tool=value,status=s(tool.status)??"unknown",timestamp=s(tool.timestamp),result=tool.result??tool.resultDisplay;entries.push({targetTable:"history_tool_call",record:{_messageSplitIndex:0,session_id:sessionId,seq,tool_name:s(tool.name,tool.displayName)??"unknown",args_digest:argsDigest(tool.args),args_raw:maybeArgsRaw("gemini",s(tool.name,tool.displayName)??"",tool.args),status,started_at:timestamp,completed_at:timestamp,duration_ms:null,result_bytes:result===void 0?null:new TextEncoder().encode(JSON.stringify(result)).byteLength,error_text:status==="error"?s(tool.resultDisplay,tool.result)??null:null}})}for(let record2 of extractSkillCalls(raw,context,{sessionId,seq,messageSplitIndex:0}))entries.push(skillCallEntry(record2));return entries}function dshSplit(raw,context){let recordType=String(raw.type??"");if(recordType==="session")return[{targetTable:"history_message",record:{session_id:s(raw.id)??sessionIdFromSourcePath("deepseek",context?.sourceFile??"")??"unknown",seq:0,role:"meta",record_type:"session",disposition:"meta",ts:timestampOf(raw.createdAt),cwd:s(raw.cwd)??null,content_text:null,provenance:"ambient"}}];if(recordType!=="user/message"&&recordType!=="assistant/message")return[];let data=o(raw.data),msg=o(data.message),seq=typeof raw.seq==="number"?raw.seq:context?.sourceLine??0,sessionId=sessionIdFromSourcePath("deepseek",context?.sourceFile??"")??"unknown",role=recordType==="user/message"?"user":"assistant",source=o(data.source??msg.source),model=s(source.model,o(data.model??msg.model).model),usage=data.usage??msg.usage,messageId=s(msg.id,data.id);return[{targetTable:"history_message",record:{session_id:sessionId,seq,role,record_type:recordType,disposition:"keep",...messageId!==void 0?{source_record_id:messageId}:{},ts:timestampOf(raw.time,data.time,msg.time),duration_ms:null,model:model??null,input_tokens:numberOrNull(usage?.input_tokens??usage?.input)??null,output_tokens:numberOrNull(usage?.output_tokens??usage?.output)??null,cache_read_tokens:null,cache_write_tokens:null,cost_usd:null,content_text:extractContentText(data.content??msg.content)??s(data.text,msg.text)??null,cwd:null,provenance:"ambient"}}]}var UUID_PATTERN="[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}",AGY_BRAIN_REGEX=new RegExp(`(?:^|\\/)brain\\/(${UUID_PATTERN})(?:\\/|$)`,"i"),DSH_SESSION_REGEX=new RegExp(`(?:^|\\/)session-(${UUID_PATTERN})(?:\\/|$)`,"i"),CODEX_ROLLOUT_REGEX=new RegExp(`(?:^|-|_)(${UUID_PATTERN})$`,"i");function sessionIdFromSourcePath(source,sourceFile){let normalized=sourceFile.replace(/\\/g,"/"),sLower=source.toLowerCase();if(sLower==="agy"||sLower==="antigravity")return normalized.match(AGY_BRAIN_REGEX)?.[1];if(sLower==="deepseek")return normalized.match(DSH_SESSION_REGEX)?.[1];if(sLower==="codex"){let basename=normalized.split("/").at(-1)??"";if(basename.startsWith("rollout-")&&basename.endsWith(".jsonl"))return basename.slice(0,-6).match(CODEX_ROLLOUT_REGEX)?.[1]}return}function sessionIdFromContext(context,raw){if(context!==void 0){let file2=context.sourceFile.split("/").at(-1);if(file2!==void 0)return file2.replace(/\.jsonl$/,"")}return s(raw.sessionId,raw.id)??"unknown"}function geminiContent(raw){let content=extractContentText(raw.content)??s(raw.text),thoughts=Array.isArray(raw.thoughts)?raw.thoughts.map((value)=>value!==null&&typeof value==="object"?s(o(value).description):void 0).filter((value)=>value!==void 0).join(`
|
|
528
|
+
`):"";return[content,thoughts].filter((value)=>value!==void 0&&value.length>0).join(`
|
|
529
|
+
`)||null}function numberOrNull(value){return typeof value==="number"&&Number.isFinite(value)?value:null}function normalizeGrokRecord(raw){let params=raw.params,update=params?.update,isUpdatesShape=typeof raw.method==="string"&¶ms!==void 0&&update!==void 0,body=isUpdatesShape?update:raw,recordType=String((isUpdatesShape?update?.sessionUpdate:raw.type)??raw.sessionUpdate??raw.eventType??(raw.file_snapshots!==void 0||raw.after_snapshots!==void 0?"file_snapshot":raw.prompt!==void 0?"user_message":raw.answer!==void 0||raw.question!==void 0?"assistant":"")),sessionId=s(params?.sessionId,raw.session_id,raw.sessionId,raw.parentSessionId,raw.btwSessionId,raw.params?.sessionId)??"unknown",ts=normalizeTs(raw.ts??raw.timestamp??raw.created_at??raw.askedAt??body.ts??body.timestamp),seq=typeof raw.seq==="number"?raw.seq:typeof body.seq==="number"?body.seq:0,meta3=body._meta??params?._meta??raw._meta,model=s(meta3?.modelId,body.model,raw.model),contentText=extractGrokContent(body.content??body.text??raw.content??raw.text??raw.prompt??(raw.answer!==void 0||raw.question!==void 0?[raw.question,raw.answer].filter((value)=>typeof value==="string").join(`
|
|
530
|
+
`):void 0)),usage=body.usage??raw.usage,toolMeta=meta3?.["x.ai/tool"],titleFallback=s(body.title)?.split("`")[0]?.trim(),toolName=s(toolMeta?.name,body.kind,body.tool_name,body.name,raw.tool_name,raw.name)??(titleFallback!==void 0&&titleFallback.length>0&&titleFallback.length<=40?titleFallback:""),toolArgs=body.rawInput??body.input??body.arguments??toolMeta?.input??raw.input??raw.arguments,toolStatus=s(body.status,raw.outcome,raw.status)??"ok",durationMs=typeof body.duration_ms==="number"?body.duration_ms:typeof raw.duration_ms==="number"?raw.duration_ms:typeof usage?.apiDurationMs==="number"?usage.apiDurationMs:void 0,errorText=body.error!==void 0?String(body.error):raw.error!==void 0?String(raw.error):void 0,hasTypeDiscriminator=recordType.length>0||isUpdatesShape;return{recordType,sessionId,ts,seq,body,model,contentText,usage,toolName,toolArgs,toolStatus,durationMs,errorText,hasTypeDiscriminator}}function normalizeTs(value){return timestampOf(value)}function extractGrokContent(content){if(typeof content==="string")return content;if(content!==null&&typeof content==="object"&&!Array.isArray(content)){let c=content;if(typeof c.text==="string")return c.text;if(typeof c.content==="string")return c.content}if(Array.isArray(content)){let parts=[];for(let block of content)if(typeof block==="string")parts.push(block);else if(block!==null&&typeof block==="object"){let b=block;if(typeof b.text==="string")parts.push(b.text)}return parts.length>0?parts.join(`
|
|
531
|
+
`):null}return null}var GROK_META_TYPES=new Set(["phase_changed","permission_requested","permission_resolved","mcp_server_starting","mcp_server_connected","mcp_config_resolved","mcp_managed_config_result","mcp_transport_decode_error","mcp_init_completed","mcp_health_check","loop_started","first_token","agent_thought_chunk","hook_execution","plan","session_recap","task_backgrounded","task_completed","retry_state","auto_compact_started","auto_compact_completed","compaction_checkpoint","image_compressed","reasoning","system","turn_started","turn_ended","yolo_toggled"]);function grokSplit(raw,context){let entries=[],n=normalizeGrokRecord(raw),{recordType,sessionId,ts,seq}=n;if(recordType==="turn_completed"){let usage=n.usage,modelUsage=usage?.modelUsage,modelFromUsage=modelUsage!==null&&typeof modelUsage==="object"?Object.keys(modelUsage)[0]:void 0,model=s(n.model,modelFromUsage),inputTokens=usage?.inputTokens??usage?.input??usage?.input_tokens,outputTokens=usage?.outputTokens??usage?.output??usage?.output_tokens,cacheRead=usage?.cachedReadTokens??usage?.cache_read_tokens;return entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role:"assistant",record_type:recordType,disposition:"keep",ts,duration_ms:n.durationMs??usage?.apiDurationMs??null,model:model??null,input_tokens:inputTokens??null,output_tokens:outputTokens??null,cache_read_tokens:cacheRead??null,cache_write_tokens:null,cost_usd:null,content_text:n.contentText,cwd:null,provenance:"ambient"}}),entries}if(recordType==="tool_started")return entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role:"assistant",record_type:recordType,disposition:"keep",ts,duration_ms:void 0,model:n.model??null,input_tokens:null,output_tokens:null,cache_read_tokens:null,cache_write_tokens:null,cost_usd:null,content_text:n.contentText,cwd:null,provenance:"ambient"}}),entries.push({targetTable:"history_tool_call",record:{_messageSplitIndex:0,session_id:sessionId,seq,tool_name:n.toolName,args_digest:argsDigest(n.toolArgs),args_raw:maybeArgsRaw("grok",n.toolName,n.toolArgs),status:n.toolStatus||"ok",started_at:ts,completed_at:void 0,duration_ms:void 0,result_bytes:void 0,error_text:n.errorText}}),entries;if(recordType==="tool_completed")return entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role:"assistant",record_type:recordType,disposition:"keep",ts,duration_ms:n.durationMs??null,model:n.model??null,input_tokens:null,output_tokens:null,cache_read_tokens:null,cache_write_tokens:null,cost_usd:null,content_text:n.contentText,cwd:null,provenance:"ambient"}}),entries.push({targetTable:"history_tool_call",record:{_messageSplitIndex:0,session_id:sessionId,seq,tool_name:n.toolName,args_digest:null,args_raw:void 0,status:n.toolStatus||"ok",started_at:void 0,completed_at:ts,duration_ms:n.durationMs,result_bytes:void 0,error_text:n.errorText}}),entries;if(recordType==="tool_call"||recordType==="tool_call_update"){entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role:"assistant",record_type:recordType,disposition:"keep",ts,duration_ms:void 0,model:n.model??null,input_tokens:null,output_tokens:null,cache_read_tokens:null,cache_write_tokens:null,cost_usd:null,content_text:n.contentText,cwd:null,provenance:"ambient"}}),entries.push({targetTable:"history_tool_call",record:{_messageSplitIndex:0,session_id:sessionId,seq,tool_name:n.toolName,args_digest:argsDigest(n.toolArgs),args_raw:maybeArgsRaw("grok",n.toolName,n.toolArgs),status:n.toolStatus||"ok",started_at:recordType==="tool_call"?ts:void 0,completed_at:recordType==="tool_call_update"?ts:void 0,duration_ms:n.durationMs,result_bytes:void 0,error_text:n.errorText}});for(let record2 of extractSkillCalls(raw,context,{sessionId,seq,messageSplitIndex:0}))entries.push(skillCallEntry(record2));return entries}if(recordType==="user"||recordType==="user_message"||recordType==="user_message_chunk"||recordType==="message")return entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role:"user",record_type:recordType||"user_message",disposition:"keep",ts,duration_ms:void 0,model:null,input_tokens:null,output_tokens:null,cache_read_tokens:null,cache_write_tokens:null,cost_usd:null,content_text:n.contentText,cwd:null,provenance:"ambient"}}),entries;if(recordType==="assistant"||recordType==="agent_message_chunk")return entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role:"assistant",record_type:recordType,disposition:"keep",ts,duration_ms:void 0,model:n.model??null,input_tokens:null,output_tokens:null,cache_read_tokens:null,cache_write_tokens:null,cost_usd:null,content_text:n.contentText,cwd:null,provenance:"ambient"}}),entries;if(GROK_META_TYPES.has(recordType))return entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role:"meta",record_type:recordType,disposition:"meta",ts,duration_ms:n.durationMs??null,model:n.model??null,input_tokens:null,output_tokens:null,cache_read_tokens:null,cache_write_tokens:null,cost_usd:null,content_text:n.contentText,cwd:null,provenance:"ambient"}}),entries;if(!n.hasTypeDiscriminator||recordType.length===0)return entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role:"unknown",record_type:stableFieldShape(raw),disposition:"unknown",ts,duration_ms:void 0,model:null,input_tokens:null,output_tokens:null,cache_read_tokens:null,cache_write_tokens:null,cost_usd:null,content_text:n.contentText,cwd:null,provenance:"ambient"}}),entries;return entries.push({targetTable:"history_message",record:{session_id:sessionId,seq,role:"meta",record_type:recordType,disposition:"meta",ts,duration_ms:n.durationMs??null,model:n.model??null,input_tokens:null,output_tokens:null,cache_read_tokens:null,cache_write_tokens:null,cost_usd:null,content_text:n.contentText,cwd:null,provenance:"ambient"}}),entries}function o(value){return typeof value==="object"&&value!==null?value:{}}function s(...values){for(let value of values){if(typeof value==="string"&&value.length>0)return value;if(typeof value==="number"&&Number.isFinite(value))return String(value)}return}function timestampOf(...values){for(let value of values){if(typeof value==="number"&&Number.isFinite(value)){let ms=value>1000000000000?value:value*1000;return new Date(ms).toISOString()}if(typeof value==="string"&&value.length>0){let asNum=Number(value);if(Number.isFinite(asNum)&&/^\d+(\.\d+)?$/.test(value.trim())){let ms=asNum>1000000000000?asNum:asNum*1000;return new Date(ms).toISOString()}return value}}return}function mapRole(type){let t=String(type??"").toLowerCase();if(t==="user"||t==="human"||t==="developer")return"user";if(t==="assistant"||t==="ai"||t==="model")return"assistant";if(t==="system"||t==="error")return"system";return t||"unknown"}function computeCost(inputTokens,outputTokens,model){if(inputTokens===void 0||inputTokens===null)return;if(outputTokens===void 0||outputTokens===null)return;let inputRate=model?.toLowerCase().includes("claude")?3:1,outputRate=model?.toLowerCase().includes("claude")?15:5;return(inputTokens*inputRate+outputTokens*outputRate)/1e6}function extractContentText(content){if(typeof content==="string")return content;if(!Array.isArray(content))return;let parts=[];for(let block of content){if(typeof block!=="object"||block===null)continue;let b=block;if(typeof b.text==="string")parts.push(b.text)}return parts.length>0?parts.join(`
|
|
532
|
+
`):void 0}function stableFieldShape(raw){return Object.keys(raw).map((k)=>k.toLowerCase()).sort().join("+")}var CLAUDE_FIELD_MAP=identityFieldMap(MESSAGE_MAPPER_KEYS.concat(TOOL_CALL_MAPPER_KEYS,SKILL_CALL_MAPPER_KEYS)),PI_FIELD_MAP=identityFieldMap(MESSAGE_MAPPER_KEYS.concat(TOOL_CALL_MAPPER_KEYS,SKILL_CALL_MAPPER_KEYS)),OMP_FIELD_MAP=identityFieldMap(MESSAGE_MAPPER_KEYS.concat(TOOL_CALL_MAPPER_KEYS,SKILL_CALL_MAPPER_KEYS)),CODEX_FIELD_MAP=identityFieldMap(MESSAGE_MAPPER_KEYS.concat(TOOL_CALL_MAPPER_KEYS,SKILL_CALL_MAPPER_KEYS)),AGY_FIELD_MAP=identityFieldMap(MESSAGE_MAPPER_KEYS.concat(TOOL_CALL_MAPPER_KEYS,SKILL_CALL_MAPPER_KEYS)),GROK_FIELD_MAP=identityFieldMap(MESSAGE_MAPPER_KEYS.concat(TOOL_CALL_MAPPER_KEYS,SKILL_CALL_MAPPER_KEYS)),GEMINI_FIELD_MAP=identityFieldMap(MESSAGE_MAPPER_KEYS.concat(TOOL_CALL_MAPPER_KEYS,SKILL_CALL_MAPPER_KEYS)),DSH_FIELD_MAP=identityFieldMap(MESSAGE_MAPPER_KEYS.concat(["source_record_id"])),passthroughSchema=exports_external.object({}).passthrough(),CLAUDE_SCHEMA=passthroughSchema,PI_SCHEMA=passthroughSchema,OMP_SCHEMA=passthroughSchema,CODEX_SCHEMA=passthroughSchema,AGY_SCHEMA=passthroughSchema,GROK_SCHEMA=passthroughSchema,GEMINI_SCHEMA=passthroughSchema,DSH_SCHEMA=passthroughSchema;var sourceRecordSchema=exports_external.object({source_record_id:exports_external.string().min(1),created_at:exports_external.string().min(1),content:exports_external.string().min(1),role:exports_external.string().optional(),model:exports_external.string().optional()}).passthrough();function firstString(...values){for(let value of values){if(typeof value==="string"&&value.length>0)return value;if(typeof value==="number"&&Number.isFinite(value))return String(value)}return}function defaultCreatedAt(value){return firstString(value)??new Date(0).toISOString()}function defaultRecordId(value,raw,context){return firstString(value,raw.id,raw.uuid,raw.message_id,raw.messageId,raw.session_id,raw.sessionId,raw.conversation_id)??`${context.source}:${context.sourceFile}:${context.sourceLine}:${context.splitIndex}`}function defaultContent(value,raw){return firstString(value,raw.content,raw.text,raw.message,raw.prompt,raw.response,raw.output)}function transforms(){return{source_record_id:defaultRecordId,created_at:defaultCreatedAt,content:defaultContent,role:(value,raw)=>firstString(value,raw.role,raw.type),model:(value,raw)=>firstString(value,raw.model,raw.model_name,raw.modelName)}}function sourceDefinition(source,displayName,defaultRoots,filePatterns){return{source,displayName,defaultRoots,filePatterns,targetTable:`history_etl_${source}`,splitConfig:source==="pi"?{mode:"one-to-many",field:"messages"}:{mode:"one-to-one"},fieldMap:{id:"source_record_id",uuid:"source_record_id",message_id:"source_record_id",messageId:"source_record_id",session_id:"source_record_id",sessionId:"source_record_id",conversation_id:"source_record_id",timestamp:"created_at",created_at:"created_at",createdAt:"created_at",time:"created_at",content:"content",text:"content",message:"content",prompt:"content",response:"content",output:"content",role:"role",type:"role",model:"model",model_name:"model",modelName:"model"},fieldTransforms:transforms(),schema:sourceRecordSchema}}function customSourceDefinition(source,displayName,defaultRoots,filePatterns,split,fieldMap,schema){return{source,displayName,defaultRoots,filePatterns,targetTable:`history_etl_${source}`,splitConfig:{mode:"custom",split},fieldMap,fieldTransforms:{},schema}}var SOURCE_DEFINITIONS={pi:customSourceDefinition("pi","Pi",[".pi/agent/sessions"],["*.jsonl"],piSplit,PI_FIELD_MAP,PI_SCHEMA),claude:customSourceDefinition("claude","Claude Code",[".claude/projects"],["*.jsonl"],claudeSplit,CLAUDE_FIELD_MAP,CLAUDE_SCHEMA),codex:customSourceDefinition("codex","Codex",[".codex/sessions"],["*.jsonl"],codexSplit,CODEX_FIELD_MAP,CODEX_SCHEMA),omp:customSourceDefinition("omp","OMP",[".omp/agent/sessions"],["*.jsonl"],ompSplit,OMP_FIELD_MAP,OMP_SCHEMA),grok:customSourceDefinition("grok","Grok",[".grok/sessions"],["*.jsonl"],grokSplit,GROK_FIELD_MAP,GROK_SCHEMA),agy:{...customSourceDefinition("agy","Antigravity CLI",[".gemini/antigravity-cli"],["*.jsonl"],agySplit,AGY_FIELD_MAP,AGY_SCHEMA),corruptLinePolicy:"skip"},gemini:customSourceDefinition("gemini","Gemini CLI",[".gemini/tmp",".config/gemini"],["*.jsonl"],geminiSplit,GEMINI_FIELD_MAP,GEMINI_SCHEMA),deepseek:{...customSourceDefinition("deepseek","DeepSeek dsh",[".dsh/sessions"],["session.v3.jsonl","session.v3.jsonl.zstd"],dshSplit,DSH_FIELD_MAP,DSH_SCHEMA),corruptLinePolicy:"skip"},opencode:sourceDefinition("opencode","OpenCode",[".opencode",".local/share/opencode"],["*.jsonl"]),antigravity:sourceDefinition("antigravity","Antigravity",[".antigravity"],["*.jsonl"]),openclaw:sourceDefinition("openclaw","OpenClaw",[".openclaw"],["*.jsonl"])};var TYPED_HISTORY_TABLES=["history_message","history_tool_call","history_skill_call"];var BOOKKEEPING_HISTORY_TABLES=["history_import_checkpoint","history_import_ledger"],IMPORTER_OWNED_TABLES=[...TYPED_HISTORY_TABLES,...BOOKKEEPING_HISTORY_TABLES,...Object.values(SOURCE_DEFINITIONS).map((def)=>def.targetTable)];var SPUR_OWNED_HISTORY_TABLES=["history_run_session","history_task_session","history_tool_alias_map","history_daily_stats","history_board_loop_findings","history_board_message_5m","history_board_model_stats","history_board_ranked_steps","history_board_rollup_meta","history_board_rollup_watermark","history_board_rollup_bucket","history_board_session_stats","history_board_skill_5m","history_board_source_daily","history_board_source_stats","history_board_dimension_daily","history_board_kpi_window","history_board_tool_5m","history_board_tool_stats"],HISTORY_RESET_TABLES=[...IMPORTER_OWNED_TABLES,...SPUR_OWNED_HISTORY_TABLES];var IMPORTER_SCHEMA_LEDGER_PREFIX="importer_schema@";class ActionRunDao{db;constructor(db2){this.db=db2}async completedAtById(id){return(await this.db.queryFirst("SELECT completed_at FROM action_runs WHERE id = ?",id))?.completed_at??null}async setStartedAt(id,startedAt){await this.db.run("UPDATE action_runs SET started_at = ? WHERE id = ?",startedAt,id)}async actionRowsByRunId(runId){try{return await this.db.queryAll("SELECT id, node, kind, status, duration_ms, ok, result_json, started_at, completed_at, created_at FROM action_runs WHERE run_id = ? ORDER BY created_at",runId)}catch(error51){if(error51 instanceof Error&&error51.message.includes("no such table: action_runs"))return[];throw error51}}}init_dist4();init_schema();init_schema();init_schema();var workspacesTable=defineTable("workspaces",{id:text("id").primaryKey(),name:text("name").notNull().unique(),root:text("root").notNull(),purpose:text("purpose"),defaultAgent:text("default_agent"),...standardColumns}),workspaces=workspacesTable.table;var runsTable=defineTable("runs",{id:text("id").primaryKey(),workspaceId:text("workspace_id").references(()=>workspaces.id),workflowName:text("workflow_name"),mode:text("mode"),status:text("status").notNull(),agent:text("agent"),externalKey:text("external_key"),startedAt:integer2("started_at").notNull(),completedAt:integer2("completed_at"),metadataJson:text("metadata_json").notNull().default("{}"),...standardColumns}),runs=runsTable.table;var artifactsTable=defineTable("artifacts",{id:text("id").primaryKey(),runId:text("run_id").references(()=>runs.id),path:text("path").notNull(),kind:text("kind").notNull(),...standardColumns}),artifacts=artifactsTable.table;function createId(prefix){return`${prefix}_${crypto.randomUUID()}`}class ArtifactDao extends EntityDao{constructor(adapter){super(adapter,artifacts,[artifacts.id],"artifacts")}record(input){return super.create({id:createId("artifact"),runId:input.runId??null,path:input.path,kind:input.kind})}artifactsByRunId(runId){return this.adapter.queryAll("SELECT path, kind FROM artifacts WHERE run_id = ? ORDER BY id",runId)}artifactsWithIdByRunId(runId){return this.adapter.queryAll("SELECT id, path, kind FROM artifacts WHERE run_id = ? ORDER BY id",runId)}}init_schema();var phaseRunsTable=defineTable("phase_runs",{id:text("id").primaryKey(),runId:text("run_id").notNull().references(()=>runs.id),phase:text("phase").notNull(),status:text("status").notNull(),startedAt:integer2("started_at"),completedAt:integer2("completed_at"),...standardColumns}),phaseRuns=phaseRunsTable.table;init_dist4();function normalizePersistedWorkflowLayer(layer){if(layer==="bundled")return"shared";if(layer==="project"||layer==="registered"||layer==="shared")return layer;return null}class RunDao extends EntityDao{constructor(adapter){super(adapter,runs,[runs.id],"runs")}open(input={}){return super.create({id:createId("run"),workspaceId:input.workspaceId??null,status:input.status??"pending",agent:input.agent??null,startedAt:Date.now(),completedAt:null})}traceRows(filter){return this.adapter.queryAll(`SELECT id, workflow_name, mode, status, agent, started_at, completed_at, metadata_json
|
|
533
533
|
FROM runs
|
|
534
534
|
WHERE (?1 IS NULL OR workflow_name = ?1)
|
|
535
535
|
AND (?2 IS NULL OR status = ?2)
|
|
@@ -571,7 +571,7 @@ CREATE INDEX IF NOT EXISTS idx_history_skill_call_invocation_kind
|
|
|
571
571
|
ORDER BY started_at ASC`,cutoffIso)}async finalizeStale(runId,reason){let nowIso=new Date().toISOString();await this.adapter.run(`UPDATE runs
|
|
572
572
|
SET status = 'failed', completed_at = ?1, updated_at = ?1,
|
|
573
573
|
metadata_json = json_set(COALESCE(NULLIF(metadata_json, ''), '{}'), '$.staleReason', ?2)
|
|
574
|
-
WHERE id = ?3 AND status IN ('running', 'pending')`,nowIso,reason,runId)}async setPid(runId,pid){await this.adapter.run("UPDATE runs SET pid = ? WHERE id = ?",pid,runId)}async getPid(runId){return(await this.adapter.queryFirst("SELECT pid FROM runs WHERE id = ?",runId))?.pid??null}}var CHILD_TABLES=["action_runs","phase_runs","transition_runs","workflow_states"];function insertIfAbsentOps(table3,rows,targetColumns){return rows.map((row)=>{let columns2=Object.keys(row).filter((column2)=>targetColumns.has(column2));return{sql:`INSERT INTO ${table3} (${columns2.join(", ")}) VALUES (${columns2.map(()=>"?").join(", ")}) ON CONFLICT(id) DO NOTHING`,params:columns2.map((column2)=>row[column2])}})}async function tableColumns(db2,table3){let rows=await db2.queryAll(`PRAGMA table_info(${table3})`);return new Set(rows.map((row)=>row.name))}async function listRunIds(from){return(await from.queryAll("SELECT id FROM runs")).map((row)=>row.id)}async function transferRunTables(from,to){let persistedIds=[],skipped=[],targetRunsColumns=await tableColumns(to,"runs"),sourceRows=await from.queryAll("SELECT * FROM runs");for(let row of sourceRows){let id=String(row.id);if(await to.queryFirst("SELECT id FROM runs WHERE id = ?",id)!==void 0){skipped.push({id,reason:"id-exists"});continue}if(row.external_key!==null&&row.external_key!==void 0){if(await to.queryFirst("SELECT id FROM runs WHERE external_key IS NOT NULL AND workflow_name IS ? AND external_key = ?",row.workflow_name??null,row.external_key)!==void 0){skipped.push({id,reason:"external-key-conflict"});continue}}let ops=insertIfAbsentOps("runs",[row],targetRunsColumns);for(let table3 of CHILD_TABLES)ops.push(...insertIfAbsentOps(table3,await from.queryAll(`SELECT * FROM ${table3} WHERE run_id = ?`,id),await tableColumns(to,table3)));await to.batch(ops),persistedIds.push(id)}return{persistedIds,skipped}}init_schema();var transitionRunsTable=defineTable("transition_runs",{id:text("id").primaryKey(),runId:text("run_id").notNull().references(()=>runs.id),fromState:text("from_state").notNull(),toState:text("to_state").notNull(),trigger:text("trigger"),status:text("status").notNull(),...standardColumns}),transitionRuns=transitionRunsTable.table;init_schema();var workflowStatesTable=defineTable("workflow_states",{id:text("id").primaryKey(),runId:text("run_id").notNull().references(()=>runs.id),state:text("state").notNull(),dataJson:text("data_json").notNull(),...standardColumns}),workflowStates=workflowStatesTable.table;init_dist6();class WorkflowValidationError extends Error{details;constructor(message,details){super(message);this.details=details,this.name="WorkflowValidationError"}}class FSMError extends Error{details;constructor(message,details){super(message);this.details=details,this.name="FSMError"}}class RunCollisionError extends Error{constructor(runId){super(`Workflow run "${runId}" already exists`);this.name="RunCollisionError"}}class WorkflowResumeError extends Error{details;constructor(message,details){super(message);this.details=details,this.name="WorkflowResumeError"}}init_dist7();init_dist6();var RUNTIME_BUILTIN_KEYS=["workflow","runId","task","state","node","iteration","run","runtime"];function runtimeBuiltins(workflowName,stateOrNodeId,runId,transitionsTaken,mode){return{workflow:workflowName,runId,task:workflowName,state:stateOrNodeId,node:stateOrNodeId,iteration:transitionsTaken,run:runId,runtime:mode}}function allowedEnv(names,source=getProcessEnv()){return Object.fromEntries(names.flatMap((name)=>source[name]===void 0?[]:[[name,source[name]]]))}class RunLifecycle{workflowName;mode;runId;externalKey;persistence;events;logger;ownerAttempt;constructor(runId,workflowName,mode,deps,externalKey){this.workflowName=workflowName,this.mode=mode,this.runId=runId,this.externalKey=externalKey,this.persistence=deps.persistence,this.events=deps.events??(deps.lifecycleBus?new EventBus({lifecycleBus:deps.lifecycleBus}):void 0),this.logger=(deps.logger??getLogger2("workflow")).child({runId,workflow:workflowName,mode})}static forExternalTransition(workflowName,runId,deps,externalKey){return new RunLifecycle(runId,workflowName,"state-machine",deps,externalKey)}static async run(workflowName,mode,deps,options,loop){return await traceAsync("workflow.run",async()=>{let startedAt=new Date().toISOString(),proposed={...RunLifecycle.runRecord(options.runId??crypto.randomUUID(),workflowName,mode,startedAt,options.metadata,options.externalKey),owner_attempt:crypto.randomUUID()},record2=proposed;if(options.externalKey===void 0)await deps.persistence.createRun(proposed);else if(record2=await deps.persistence.createOrAttachRun(proposed),record2.owner_attempt!==proposed.owner_attempt){let snapshot=await deps.persistence.loadLatestStateSnapshot(record2.id);return{runId:record2.id,workflowName:record2.workflow_name,mode:record2.mode==="transition-flow"?"transition-flow":"state-machine",status:record2.status,finalState:snapshot?.state??"",transitionsTaken:snapshotTransitions(snapshot?.data)}}let extKey=record2.external_key??void 0,lifecycle=new RunLifecycle(record2.id,workflowName,mode,deps,extKey);return lifecycle.ownerAttempt=proposed.owner_attempt??void 0,lifecycle.logger.info("workflow run started"),addSpanEvent("workflow.run.started",{workflowName,mode,runId:lifecycle.runId,dryRun:options.dryRun??!1}),lifecycle.events?.emit("workflow.run.started",{workflowName,mode,runId:lifecycle.runId,dryRun:options.dryRun??!1,externalKey:extKey,severity:"info"}),await lifecycle.execute(loop)},{attributes:{"workflow.name":workflowName,"workflow.mode":mode}})}static async resume(workflowName,mode,deps,runId,externalKey,loop,ownerAttempt){return await traceAsync("workflow.run",async()=>{let lifecycle=new RunLifecycle(runId,workflowName,mode,deps,externalKey);return lifecycle.ownerAttempt=ownerAttempt,lifecycle.logger.info("workflow run resumed"),await lifecycle.execute(loop)},{attributes:{"workflow.name":workflowName,"workflow.mode":mode}})}async finalizeAsOwner(status,completedAt,reason){if(this.ownerAttempt===void 0){await this.persistence.finalizeRun(this.runId,status,completedAt,void 0,reason);return}if(await this.persistence.finalizeRun(this.runId,status,completedAt,{ownerAttempt:this.ownerAttempt},reason)===!1)throw this.events?.emit("workflow.run.stale_owner",{runId:this.runId,ownerAttemptId:this.ownerAttempt,status,severity:"warning"}),new WorkflowResumeError(`stale owner "${this.ownerAttempt}" cannot finalize run "${this.runId}" as "${status}": ownership was lost`)}async execute(loop){try{return await loop(this)}catch(error51){try{await this.finalizeAsOwner("failed",new Date().toISOString(),"failed")}catch(finalizeError){throw AggregateError([error51,finalizeError],"Workflow execution and failure persistence failed")}throw error51}}async enter(stateOrNodeId,transitionsTaken,persist=!0,vars){if(persist){let data={transitionsTaken};if(vars!==void 0)data.effectiveVars=vars;await this.persistence.saveWorkflowState(this.runId,stateOrNodeId,data),await this.persistence.savePhase(this.runId,stateOrNodeId,"running")}addSpanEvent("workflow.node.enter",{runId:this.runId,node:stateOrNodeId,transitionsTaken}),this.events?.emit("workflow.node.enter",{runId:this.runId,node:stateOrNodeId,transitionsTaken,severity:"info"})}async commitHop(from,to,trigger,transitionsTaken,phase,vars){let data={transitionsTaken};if(vars!==void 0)data.effectiveVars=vars;await this.persistence.commitTransition(this.runId,from,to,trigger,to,data,phase),addSpanEvent("workflow.node.transition",{runId:this.runId,from,to,...trigger===null?{}:{trigger}}),this.events?.emit("workflow.node.transition",{runId:this.runId,from,to,trigger,externalKey:this.externalKey,severity:"info"})}async recordTransition(from,to,trigger){await this.persistence.saveTransition(this.runId,from,to,trigger),addSpanEvent("workflow.node.transition",{runId:this.runId,from,to,...trigger===null?{}:{trigger}}),this.events?.emit("workflow.node.transition",{runId:this.runId,from,to,trigger,externalKey:this.externalKey,severity:"info"})}async done(finalState,transitionsTaken,reason){return await this.persistence.savePhase(this.runId,finalState,"done"),await this.finalizeAsOwner("done",new Date().toISOString(),reason),this.logger.info("workflow run done",{finalState,transitionsTaken}),addSpanEvent("workflow.run.done",{runId:this.runId,finalState,transitionsTaken}),this.events?.emit("workflow.run.done",{runId:this.runId,finalState,transitionsTaken,externalKey:this.externalKey,severity:"info"}),this.result("done",finalState,transitionsTaken,reason)}async fail(finalState,transitionsTaken,reason="failed"){return await this.persistence.savePhase(this.runId,finalState,"failed"),await this.finalizeAsOwner("failed",new Date().toISOString(),reason),addSpanEvent("workflow.run.failed",{runId:this.runId,finalState,reason}),this.events?.emit("workflow.run.failed",{runId:this.runId,finalState,reason,externalKey:this.externalKey,severity:"error"}),this.logger.warn("workflow run failed",{finalState,transitionsTaken,reason}),this.result("failed",finalState,transitionsTaken,reason)}async pause(stateOrNodeId,transitionsTaken,vars,lastActionResult,reason){let data={transitionsTaken};if(vars!==void 0)data.effectiveVars=vars;if(lastActionResult!==void 0)data.lastActionResult={ok:lastActionResult.ok};return await this.persistence.saveWorkflowState(this.runId,stateOrNodeId,data),await this.persistence.savePhase(this.runId,stateOrNodeId,"paused"),await this.finalizeAsOwner("paused",new Date().toISOString(),reason),this.logger.info("workflow run paused",{stateOrNodeId,transitionsTaken}),addSpanEvent("workflow.run.paused",{runId:this.runId,node:stateOrNodeId,transitionsTaken}),this.events?.emit("workflow.run.paused",{runId:this.runId,node:stateOrNodeId,transitionsTaken,externalKey:this.externalKey,severity:"warning"}),this.result("paused",stateOrNodeId,transitionsTaken)}actionStart(stateOrNodeId,kind){addSpanEvent("workflow.action.start",{runId:this.runId,node:stateOrNodeId,kind}),this.events?.emit("workflow.action.start",{runId:this.runId,node:stateOrNodeId,kind,severity:"info"})}actionDone(stateOrNodeId,kind,durationMs,ok){addSpanEvent("workflow.action.done",{runId:this.runId,node:stateOrNodeId,kind,durationMs,ok}),this.events?.emit("workflow.action.done",{runId:this.runId,node:stateOrNodeId,kind,durationMs,ok,severity:ok?"info":"error"})}warnActionFailed(stateOrNodeId,transitionsTaken,error51){addSpanEvent("workflow.action.failed_continue",{runId:this.runId,node:stateOrNodeId,transitionsTaken,...error51===void 0?{}:{error:error51}}),this.events?.emit("workflow.action.failed_continue",{runId:this.runId,node:stateOrNodeId,transitionsTaken,...error51===void 0?{}:{error:error51},severity:"warning"}),this.logger.warn("action failed (continuing)",{node:stateOrNodeId,transitionsTaken,error:error51})}guardEvaluated(from,to,kind,passed){this.events?.emit("workflow.guard.evaluated",{runId:this.runId,from,to,kind,passed,externalKey:this.externalKey,severity:passed?"info":"warning"})}hitlAsk(node,kind,message){this.events?.emit("workflow.hitl.ask",{runId:this.runId,node,kind,message,severity:"info"})}hitlResponse(node,ok){this.events?.emit("workflow.hitl.response",{runId:this.runId,node,ok,severity:ok?"info":"warning"})}result(status,finalState,transitionsTaken,reason){return{runId:this.runId,workflowName:this.workflowName,mode:this.mode,status,finalState,transitionsTaken,...reason===void 0?{}:{reason}}}static runRecord(runId,workflowName,mode,startedAt,metadata,externalKey){return{id:runId,workflow_name:workflowName,mode,status:"running",started_at:startedAt,metadata_json:JSON.stringify(metadata??{}),completed_at:null,external_key:externalKey??null}}}function snapshotTransitions(data){let value=data?.transitionsTaken;return typeof value==="number"&&Number.isSafeInteger(value)&&value>=0?value:0}function snapshotActionResult(data){let value=data?.lastActionResult;return value!==null&&typeof value==="object"&&"ok"in value&&typeof value.ok==="boolean"?{ok:value.ok}:void 0}class CapabilityRegistry{kind;capabilities=new Map;constructor(kind){this.kind=kind}register(name,capability,origin2="extension"){this.capabilities.set(name,{capability,origin:origin2})}has(name){return this.capabilities.has(name)}get(name){let entry=this.capabilities.get(name);if(entry===void 0)throw Error(`Unknown ${this.kind}: ${name}`);return entry.capability}getEntry(name){return this.capabilities.get(name)}list(){return[...this.capabilities.keys()]}entries(){return[...this.capabilities.entries()]}}function assertRelativeExtensionPath(path8,options={}){let where=options.sourceName!==void 0?` declared by "${options.sourceName}"`:"";if(/^([/\\]|[A-Za-z]:[/\\])/.test(path8))throw Error(`extension path "${path8}"${where} must be relative (no absolute paths)`);if(path8.split(/[/\\]/).includes(".."))throw Error(`extension path "${path8}"${where} must not contain ".." traversal`)}init_zod();var RESERVED_VAR_NAMES=new Set(["task","state","node","iteration","run","runtime"]),IDENTIFIER=/^[A-Za-z_][A-Za-z0-9_]*$/,VarsSchema=exports_external.record(exports_external.string(),exports_external.string()).superRefine((vars,ctx)=>{for(let key of Object.keys(vars)){if(!IDENTIFIER.test(key))ctx.addIssue({code:"custom",message:`Invalid variable name "${key}" (must be a valid identifier)`});if(RESERVED_VAR_NAMES.has(key))ctx.addIssue({code:"custom",message:`Variable name "${key}" is reserved for runtime use`})}}),EnvSchema=exports_external.object({allow:exports_external.array(exports_external.string().regex(IDENTIFIER,"env.allow entries must be valid identifiers")).optional()}),relativeExtensionPath=exports_external.string().min(1).superRefine((value,ctx)=>{try{assertRelativeExtensionPath(value)}catch(error51){ctx.addIssue({code:"custom",message:error51 instanceof Error?error51.message:"invalid extension path"})}}),WorkflowExtensionsSchema=exports_external.object({actions:exports_external.array(relativeExtensionPath).optional(),guards:exports_external.array(relativeExtensionPath).optional()}).strict(),ActionDefSchema=exports_external.object({kind:exports_external.string().min(1),options:exports_external.record(exports_external.string(),exports_external.unknown()).optional(),onError:exports_external.enum(["fail","continue"]).optional()}),GuardDefSchema=exports_external.object({kind:exports_external.string().min(1),options:exports_external.record(exports_external.string(),exports_external.unknown()).optional()}),StateMachineWorkflowDefSchema=exports_external.object({$schema:exports_external.string().optional(),kind:exports_external.literal("state-machine").optional(),name:exports_external.string().min(1),version:exports_external.string().optional(),description:exports_external.string().optional(),initialState:exports_external.string().min(1),terminalStates:exports_external.array(exports_external.string().min(1)).optional(),failureStates:exports_external.array(exports_external.string().min(1)).optional(),iterationBound:exports_external.number().int().positive().optional(),defaultOnError:exports_external.enum(["fail","continue"]).optional(),vars:VarsSchema.optional(),env:EnvSchema.optional(),states:exports_external.array(exports_external.object({id:exports_external.string().min(1),description:exports_external.string().optional(),onEnter:exports_external.array(ActionDefSchema).optional(),onExit:exports_external.array(ActionDefSchema).optional(),pause:exports_external.boolean().optional(),resumeRerun:exports_external.boolean().optional()}).strict()),transitions:exports_external.array(exports_external.object({from:exports_external.string().min(1),to:exports_external.string().min(1),description:exports_external.string().optional(),trigger:exports_external.string().optional(),guard:GuardDefSchema.optional(),terminalReason:exports_external.string().optional()}).strict()),extensions:WorkflowExtensionsSchema.optional()}).strict(),TransitionFlowWorkflowDefSchema=exports_external.object({$schema:exports_external.string().optional(),kind:exports_external.literal("transition-flow"),name:exports_external.string().min(1),version:exports_external.string().optional(),description:exports_external.string().optional(),initialNode:exports_external.string().min(1),terminalNodes:exports_external.array(exports_external.string().min(1)).optional(),iterationBound:exports_external.number().int().positive().optional(),defaultOnError:exports_external.enum(["fail","continue"]).optional(),vars:VarsSchema.optional(),env:EnvSchema.optional(),nodes:exports_external.array(exports_external.object({id:exports_external.string().min(1),description:exports_external.string().optional(),type:exports_external.enum(["action","gate","parallel","decision"]).optional(),action:ActionDefSchema.optional(),pause:exports_external.boolean().optional(),resumeRerun:exports_external.boolean().optional()}).strict()),edges:exports_external.array(exports_external.object({from:exports_external.string().min(1),to:exports_external.string().min(1),description:exports_external.string().optional(),condition:GuardDefSchema.optional()}).strict()),extensions:WorkflowExtensionsSchema.optional()}).strict(),WorkflowDefSchema=exports_external.union([StateMachineWorkflowDefSchema,TransitionFlowWorkflowDefSchema]);async function loadWorkflowDef(path8,options={}){return parseWorkflowDef(await loadStructuredConfig(path8,options),path8)}function validateWorkflowDef(workflow){if(workflow.kind==="transition-flow")validateTransitionFlow(workflow);else validateStateMachine(workflow)}function validateStateMachine(workflow){let errors6=[],ids=workflow.states.map((state)=>state.id),states=new Set(ids),terminals=new Set(workflow.terminalStates??[]),failures=new Set(workflow.failureStates??[]);for(let id of duplicates(ids))errors6.push(`State "${id}" is declared more than once`);for(let failure of failures)if(!states.has(failure))errors6.push(`Failure state "${failure}" is not declared`);else if(!terminals.has(failure))errors6.push(`Failure state "${failure}" must also be declared as a terminal state`);if(!states.has(workflow.initialState))errors6.push(`Initial state "${workflow.initialState}" is not declared`);else if(terminals.has(workflow.initialState))errors6.push(`Initial state "${workflow.initialState}" must not be a terminal state`);for(let terminal of terminals)if(!states.has(terminal))errors6.push(`Terminal state "${terminal}" is not declared`);let outboundByState=new Map;for(let transition of workflow.transitions){if(!states.has(transition.from))errors6.push(`Transition source "${transition.from}" is not declared`);if(!states.has(transition.to))errors6.push(`Transition target "${transition.to}" is not declared`);let list=outboundByState.get(transition.from)??[];list.push(transition),outboundByState.set(transition.from,list)}for(let state of workflow.states){let outbound=outboundByState.get(state.id)??[];if(terminals.has(state.id)){if(outbound.length>0)errors6.push(`Terminal state "${state.id}" must not declare transitions`);continue}let ungatedIndex=outbound.findIndex((transition)=>transition.guard===void 0);if(ungatedIndex!==-1&&ungatedIndex<outbound.length-1)errors6.push(`State "${state.id}" has an unguarded transition that is not last; later transitions are unreachable`)}errors6.push(...checkVariableReferences(collectActionOptions(workflow),workflow.vars,workflow.env)),throwIfErrors(workflow,errors6)}function parseWorkflowDef(parsed,source){let result=selectWorkflowSchema(parsed).safeParse(parsed);if(!result.success)throw new WorkflowValidationError(`Workflow definition failed schema validation for ${source}: ${formatWorkflowIssues(result.error.issues)}`,result.error.issues);return validateWorkflowDef(result.data),result.data}function selectWorkflowSchema(parsed){if(parsed!==null&&typeof parsed==="object"){let value=parsed;if(value.kind==="transition-flow"||"nodes"in value||"edges"in value||"initialNode"in value)return TransitionFlowWorkflowDefSchema}return StateMachineWorkflowDefSchema}function formatWorkflowIssues(issues){return issues.map((issue2)=>{let path8=issue2.path.map(String).join(".");return path8.length>0?`${path8}: ${issue2.message}`:issue2.message}).join("; ")}function validateTransitionFlow(workflow){let errors6=[],ids=workflow.nodes.map((node)=>node.id),nodes=new Set(ids);for(let id of duplicates(ids))errors6.push(`Node "${id}" is declared more than once`);if(!nodes.has(workflow.initialNode))errors6.push(`Initial node "${workflow.initialNode}" is not declared`);let seenEdges=new Set;for(let edge of workflow.edges){if(!nodes.has(edge.from))errors6.push(`Edge source "${edge.from}" is not declared`);if(!nodes.has(edge.to))errors6.push(`Edge target "${edge.to}" is not declared`);let key=`${edge.from}→${edge.to}`;if(seenEdges.has(key))errors6.push(`Duplicate edge "${key}"`);seenEdges.add(key)}for(let terminal of workflow.terminalNodes??[]){if(!nodes.has(terminal))errors6.push(`Terminal node "${terminal}" is not declared`);if(workflow.edges.some((edge)=>edge.from===terminal))errors6.push(`Terminal node "${terminal}" must not declare edges`)}for(let node of workflow.nodes){let outbound=workflow.edges.filter((edge)=>edge.from===node.id),unconditional=outbound.findIndex((edge)=>edge.condition===void 0);if(unconditional!==-1&&unconditional<outbound.length-1)errors6.push(`Node "${node.id}" has an unconditional edge that is not last; later edges are unreachable`)}errors6.push(...checkVariableReferences(collectActionOptions(workflow),workflow.vars,workflow.env)),throwIfErrors(workflow,errors6)}function duplicates(ids){let seen=new Set,dupes=new Set;for(let id of ids){if(seen.has(id))dupes.add(id);seen.add(id)}return[...dupes]}function collectActionOptions(workflow){let optionSets=[],actions=workflow.kind==="transition-flow"?workflow.nodes.flatMap((node)=>node.action?[node.action]:[]):workflow.states.flatMap((state)=>[...state.onEnter??[],...state.onExit??[]]);for(let action of actions)if(action.options)optionSets.push(action.options);return optionSets}var RUNTIME_TEMPLATE_NAMESPACES=new Set(RUNTIME_BUILTIN_KEYS);function checkVariableReferences(optionSets,vars,env2){let declaredVars=new Set(Object.keys(vars??{})),allowedEnv2=new Set(env2?.allow??[]),errors6=[],reference=/\$\{([^}]+)\}/g;for(let options of optionSets)for(let value of Object.values(options)){if(typeof value!=="string")continue;for(let match of value.matchAll(reference)){let expr=(match[1]??"").trim(),[namespace,name]=expr.includes(".")?expr.split(".",2):[expr,void 0];if(namespace==="vars"){if(name!==void 0&&!declaredVars.has(name))errors6.push(`Unknown variable reference "\${${expr}}" (no var "${name}" declared)`)}else if(namespace==="env"){if(name!==void 0&&!allowedEnv2.has(name))errors6.push(`Env reference "\${${expr}}" is not in env.allow`)}else if(namespace!==void 0&&!RUNTIME_TEMPLATE_NAMESPACES.has(namespace))errors6.push(`Unknown template reference "\${${expr}}"`)}}return errors6}function throwIfErrors(workflow,errors6){if(errors6.length>0)throw new WorkflowValidationError(`Workflow "${workflow.name}" is invalid: ${errors6.join("; ")}`,errors6)}init_dist6();var TEMPLATE_REF=/\$\{([^}]+)\}/g;function mergeVars(workflowVars={},overrideVars={}){return{...workflowVars,...overrideVars}}function mergeSetVars(vars,setVars){if(setVars===void 0)return vars;let filtered={};for(let[key,value]of Object.entries(setVars))if(typeof value==="string")filtered[key]=value;return mergeVars(vars,filtered)}function resolveTemplates(value,context4){if(typeof value==="string")return resolveTemplateString(value,context4);if(Array.isArray(value))return value.map((entry)=>resolveTemplates(entry,context4));if(value!==null&&typeof value==="object")return Object.fromEntries(Object.entries(value).map(([key,entry])=>[key,resolveTemplates(entry,context4)]));return value}function resolveTemplateString(value,context4){return value.replace(TEMPLATE_REF,(_match,name)=>{return lookupRef(name,context4)})}function lookupRef(name,context4){if(name.startsWith("vars.")){let key=name.slice(5),resolved2=context4.vars[key];if(resolved2===void 0)throw new WorkflowValidationError(`Workflow variable "${key}" is not defined`);return resolved2}if(name.startsWith("env.")){let key=name.slice(4),resolved2=context4.env[key];if(resolved2===void 0)throw new WorkflowValidationError(`Environment variable "${key}" is not defined`);return resolved2}let resolved=context4.builtins?.[name];if(resolved===void 0)throw new WorkflowValidationError(`Workflow builtin "${name}" is not defined`);return String(resolved)}var SHELL_ENV_OPTION="__wfShellEnv",SHELL_BINDING=/^\$\{__WF_\d+\}$/,SHELL_BINDING_ANY=/\$\{__WF_\d+\}|\$__WF_\d+\b/;function resolveShellCommandTemplates(options,context4){let{command,args,...rest}=options;if(typeof command!=="string")return resolveTemplates(rest,context4);if(args!==void 0&&!Array.isArray(args))throw Error(`shell action "args" must be a string array when defined; got ${typeof args}`);if(Array.isArray(args)&&args.length>0)return{...resolveTemplates(rest,context4),command:resolveTemplateString(command,context4),args:resolveTemplates(args,context4)};let env2={},index2=0;if(!(SHELL_ENV_OPTION in options)&&SHELL_BINDING_ANY.test(command))throw Error("shell command must not contain the reserved $__WF_ placeholder namespace; it is minted by the template-binding pass");let existingBindings=options[SHELL_ENV_OPTION];if(existingBindings!==void 0&&typeof existingBindings==="object"&&existingBindings!==null){Object.assign(env2,existingBindings);while(`__WF_${index2}`in env2)index2++}let bound=command.replace(TEMPLATE_REF,(match,name)=>{if(SHELL_BINDING.test(match))return match;let key=`__WF_${index2++}`;return env2[key]=lookupRef(name,context4),`\${${key}}`});return{...resolveTemplates(rest,context4),command:bound,[SHELL_ENV_OPTION]:env2}}function resolveOnErrorPolicy(actionOnError,workflowDefault,runOptionOverride){return actionOnError??workflowDefault??runOptionOverride??"fail"}class WorkflowEngineHost{lifecycleBus;actions=new CapabilityRegistry("workflow action");guards=new CapabilityRegistry("workflow guard");constructor(lifecycleBus){this.lifecycleBus=lifecycleBus}registerAction(action,origin2="extension"){return this.actions.register(action.kind,action,origin2),this}registerGuard(guard,origin2="extension"){return this.guards.register(guard.kind,guard,origin2),this}hasAction(kind){return this.actions.has(kind)}hasGuard(kind){return this.guards.has(kind)}listActions(){return this.actions.list()}listGuards(){return this.guards.list()}actionOrigin(kind){return this.actions.getEntry(kind)?.origin}guardOrigin(kind){return this.guards.getEntry(kind)?.origin}async runAction(kind,options,context4){if(!this.actions.has(kind))throw new WorkflowValidationError(`Unknown workflow action "${kind}"`);return await this.actions.get(kind).execute(options,context4)}async evaluateGuard(kind,options,context4){return(await this.evaluateGuardResult(kind,options,context4)).passed}async evaluateGuardResult(kind,options,context4){if(!this.guards.has(kind))throw new WorkflowValidationError(`Unknown workflow guard "${kind}"`);let result=await this.guards.get(kind).evaluate(options,context4);return typeof result==="boolean"?{passed:result}:result}}function createDefaultWorkflowEngineHost(options={}){let host=new WorkflowEngineHost(options.lifecycleBus);return host.registerAction(new NoteActionRunner,"builtin"),host.registerAction(new ShellActionRunner(options.processExecutor??nodeBunFactory2.createProcessExecutor()),"builtin"),host.registerAction(new EventEmitActionRunner,"builtin"),host.registerGuard(new ShellGuardRunner(options.processExecutor??nodeBunFactory2.createProcessExecutor()),"builtin"),host.registerGuard({kind:"always",evaluate:async()=>!0},"builtin"),host.registerGuard({kind:"never",evaluate:async()=>!1},"builtin"),host.registerGuard({kind:"action-ok",evaluate:async(_options,context4)=>context4.lastActionResult?.ok===!0},"builtin"),host}class NoteActionRunner{kind="note";async execute(options,context4){let message=String(options.message??"");return context4?.events?.emit("workflow.hitl.note",{runId:context4.runId,node:context4.stateOrNodeId,message,severity:"info"}),{ok:!0,data:{message}}}}class EventEmitActionRunner{kind="event.emit";async execute(options,context4){let name=String(options.name??"");if(!name)return{ok:!1,error:'event.emit requires a non-empty "name" option'};let payload=options.payload??{};return context4?.events?.emit("workflow.custom",{name,payload,severity:"info"}),{ok:!0,data:{name,payload}}}}async function spawnShellCommand(processExecutor,options,workdir){let command=stringOption(options,"command"),explicitArgs=arrayOption(options,"args"),spawn2=explicitArgs.length===0?{command:"/bin/sh",args:["-c",command]}:{command,args:explicitArgs},timeout=optionalTimeoutOption(options),envOption=options[SHELL_ENV_OPTION],env2=envOption!==null&&typeof envOption==="object"?envOption:void 0,result=await processExecutor.run({command:spawn2.command,args:spawn2.args,cwd:optionalStringOption(options,"cwd",workdir),...env2!==void 0?{env:env2,envMode:"merge"}:{},...timeout!==void 0?{timeout}:{},rejectOnError:!1,forceBuffered:!0});return{stdout:result.stdout,stderr:result.stderr,exitCode:result.exitCode,timedOut:result.outcome==="timeout"}}class ShellActionRunner{processExecutor;kind="shell";constructor(processExecutor){this.processExecutor=processExecutor}async execute(options,context4){let spawn2=await spawnShellCommand(this.processExecutor,options,context4.workdir);if(spawn2.timedOut){let timeout=optionalTimeoutOption(options);return{ok:!1,data:{stdout:spawn2.stdout,stderr:spawn2.stderr,exitCode:spawn2.exitCode,timedOut:!0},error:`Shell action timed out after ${timeout}ms`}}let command=stringOption(options,"command");return{ok:spawn2.exitCode===0,data:{stdout:spawn2.stdout,stderr:spawn2.stderr,exitCode:spawn2.exitCode},...spawn2.exitCode===0?{}:{error:`Command "${command}" exited with ${spawn2.exitCode}`}}}}class ShellGuardRunner{processExecutor;kind="shell";constructor(processExecutor){this.processExecutor=processExecutor}async evaluate(options,context4){let spawn2=await spawnShellCommand(this.processExecutor,options,context4.workdir);return{passed:!spawn2.timedOut&&spawn2.exitCode===0,report:{stdout:spawn2.stdout,stderr:spawn2.stderr,exitCode:spawn2.exitCode,...spawn2.timedOut?{timedOut:!0}:{}}}}}function stringOption(options,key,fallback){let value=options[key];if(typeof value==="string")return value;if(fallback!==void 0)return fallback;throw new WorkflowValidationError(`Action option "${key}" must be a string`)}function optionalStringOption(options,key,fallback){let value=options[key];if(typeof value==="string")return value;if(value===void 0)return fallback;throw new WorkflowValidationError(`Action option "${key}" must be a string`)}function arrayOption(options,key){let value=options[key];if(value===void 0)return[];if(Array.isArray(value)&&value.every((entry)=>typeof entry==="string"))return value;throw new WorkflowValidationError(`Action option "${key}" must be a string array`)}function optionalTimeoutOption(options){let value=options.timeout;if(value===void 0)return;if(typeof value==="number"&&Number.isFinite(value)&&value>0)return value;throw new WorkflowValidationError('shell option "timeout" must be a positive number of milliseconds')}var WORKFLOW_ENGINE_SCHEMA_SQL=`
|
|
574
|
+
WHERE id = ?3 AND status IN ('running', 'pending')`,nowIso,reason,runId)}async setPid(runId,pid){await this.adapter.run("UPDATE runs SET pid = ? WHERE id = ?",pid,runId)}async getPid(runId){return(await this.adapter.queryFirst("SELECT pid FROM runs WHERE id = ?",runId))?.pid??null}}var CHILD_TABLES=["action_runs","phase_runs","transition_runs","workflow_states"];function insertIfAbsentOps(table3,rows,targetColumns){return rows.map((row)=>{let columns2=Object.keys(row).filter((column2)=>targetColumns.has(column2));return{sql:`INSERT INTO ${table3} (${columns2.join(", ")}) VALUES (${columns2.map(()=>"?").join(", ")}) ON CONFLICT(id) DO NOTHING`,params:columns2.map((column2)=>row[column2])}})}async function tableColumns(db2,table3){let rows=await db2.queryAll(`PRAGMA table_info(${table3})`);return new Set(rows.map((row)=>row.name))}async function listRunIdRows(from){return(await from.queryAll("SELECT id, workflow_name FROM runs")).map((row)=>({id:row.id,workflowName:row.workflow_name}))}async function transferRunTables(from,to){let persistedIds=[],skipped=[],targetRunsColumns=await tableColumns(to,"runs"),sourceRows=await from.queryAll("SELECT * FROM runs");for(let row of sourceRows){let id=String(row.id);if(await to.queryFirst("SELECT id FROM runs WHERE id = ?",id)!==void 0){skipped.push({id,reason:"id-exists"});continue}if(row.external_key!==null&&row.external_key!==void 0){if(await to.queryFirst("SELECT id FROM runs WHERE external_key IS NOT NULL AND workflow_name IS ? AND external_key = ?",row.workflow_name??null,row.external_key)!==void 0){skipped.push({id,reason:"external-key-conflict"});continue}}let ops=insertIfAbsentOps("runs",[row],targetRunsColumns);for(let table3 of CHILD_TABLES)ops.push(...insertIfAbsentOps(table3,await from.queryAll(`SELECT * FROM ${table3} WHERE run_id = ?`,id),await tableColumns(to,table3)));await to.batch(ops),persistedIds.push(id)}return{persistedIds,skipped}}init_schema();var transitionRunsTable=defineTable("transition_runs",{id:text("id").primaryKey(),runId:text("run_id").notNull().references(()=>runs.id),fromState:text("from_state").notNull(),toState:text("to_state").notNull(),trigger:text("trigger"),status:text("status").notNull(),...standardColumns}),transitionRuns=transitionRunsTable.table;init_schema();var workflowStatesTable=defineTable("workflow_states",{id:text("id").primaryKey(),runId:text("run_id").notNull().references(()=>runs.id),state:text("state").notNull(),dataJson:text("data_json").notNull(),...standardColumns}),workflowStates=workflowStatesTable.table;init_dist6();class WorkflowValidationError extends Error{details;constructor(message,details){super(message);this.details=details,this.name="WorkflowValidationError"}}class FSMError extends Error{details;constructor(message,details){super(message);this.details=details,this.name="FSMError"}}class RunCollisionError extends Error{constructor(runId){super(`Workflow run "${runId}" already exists`);this.name="RunCollisionError"}}class WorkflowResumeError extends Error{details;constructor(message,details){super(message);this.details=details,this.name="WorkflowResumeError"}}init_dist7();init_dist6();var RUNTIME_BUILTIN_KEYS=["workflow","runId","task","state","node","iteration","run","runtime"];function runtimeBuiltins(workflowName,stateOrNodeId,runId,transitionsTaken,mode){return{workflow:workflowName,runId,task:workflowName,state:stateOrNodeId,node:stateOrNodeId,iteration:transitionsTaken,run:runId,runtime:mode}}function allowedEnv(names,source=getProcessEnv()){return Object.fromEntries(names.flatMap((name)=>source[name]===void 0?[]:[[name,source[name]]]))}class RunLifecycle{workflowName;mode;runId;externalKey;persistence;events;logger;ownerAttempt;constructor(runId,workflowName,mode,deps,externalKey){this.workflowName=workflowName,this.mode=mode,this.runId=runId,this.externalKey=externalKey,this.persistence=deps.persistence,this.events=deps.events??(deps.lifecycleBus?new EventBus({lifecycleBus:deps.lifecycleBus}):void 0),this.logger=(deps.logger??getLogger2("workflow")).child({runId,workflow:workflowName,mode})}static forExternalTransition(workflowName,runId,deps,externalKey){return new RunLifecycle(runId,workflowName,"state-machine",deps,externalKey)}static async run(workflowName,mode,deps,options,loop){return await traceAsync("workflow.run",async()=>{let startedAt=new Date().toISOString(),proposed={...RunLifecycle.runRecord(options.runId??crypto.randomUUID(),workflowName,mode,startedAt,options.metadata,options.externalKey),owner_attempt:crypto.randomUUID()},record2=proposed;if(options.externalKey===void 0)await deps.persistence.createRun(proposed);else if(record2=await deps.persistence.createOrAttachRun(proposed),record2.owner_attempt!==proposed.owner_attempt){let snapshot=await deps.persistence.loadLatestStateSnapshot(record2.id);return{runId:record2.id,workflowName:record2.workflow_name,mode:record2.mode==="transition-flow"?"transition-flow":"state-machine",status:record2.status,finalState:snapshot?.state??"",transitionsTaken:snapshotTransitions(snapshot?.data)}}let extKey=record2.external_key??void 0,lifecycle=new RunLifecycle(record2.id,workflowName,mode,deps,extKey);return lifecycle.ownerAttempt=proposed.owner_attempt??void 0,lifecycle.logger.info("workflow run started"),addSpanEvent("workflow.run.started",{workflowName,mode,runId:lifecycle.runId,dryRun:options.dryRun??!1}),lifecycle.events?.emit("workflow.run.started",{workflowName,mode,runId:lifecycle.runId,dryRun:options.dryRun??!1,externalKey:extKey,severity:"info"}),await lifecycle.execute(loop)},{attributes:{"workflow.name":workflowName,"workflow.mode":mode}})}static async resume(workflowName,mode,deps,runId,externalKey,loop,ownerAttempt){return await traceAsync("workflow.run",async()=>{let lifecycle=new RunLifecycle(runId,workflowName,mode,deps,externalKey);return lifecycle.ownerAttempt=ownerAttempt,lifecycle.logger.info("workflow run resumed"),await lifecycle.execute(loop)},{attributes:{"workflow.name":workflowName,"workflow.mode":mode}})}async finalizeAsOwner(status,completedAt,reason){if(this.ownerAttempt===void 0){await this.persistence.finalizeRun(this.runId,status,completedAt,void 0,reason);return}if(await this.persistence.finalizeRun(this.runId,status,completedAt,{ownerAttempt:this.ownerAttempt},reason)===!1)throw this.events?.emit("workflow.run.stale_owner",{runId:this.runId,ownerAttemptId:this.ownerAttempt,status,severity:"warning"}),new WorkflowResumeError(`stale owner "${this.ownerAttempt}" cannot finalize run "${this.runId}" as "${status}": ownership was lost`)}async execute(loop){try{return await loop(this)}catch(error51){try{await this.finalizeAsOwner("failed",new Date().toISOString(),"failed")}catch(finalizeError){throw AggregateError([error51,finalizeError],"Workflow execution and failure persistence failed")}throw error51}}async enter(stateOrNodeId,transitionsTaken,persist=!0,vars){if(persist){let data={transitionsTaken};if(vars!==void 0)data.effectiveVars=vars;await this.persistence.saveWorkflowState(this.runId,stateOrNodeId,data),await this.persistence.savePhase(this.runId,stateOrNodeId,"running")}addSpanEvent("workflow.node.enter",{runId:this.runId,node:stateOrNodeId,transitionsTaken}),this.events?.emit("workflow.node.enter",{runId:this.runId,node:stateOrNodeId,transitionsTaken,severity:"info"})}async commitHop(from,to,trigger,transitionsTaken,phase,vars){let data={transitionsTaken};if(vars!==void 0)data.effectiveVars=vars;await this.persistence.commitTransition(this.runId,from,to,trigger,to,data,phase),addSpanEvent("workflow.node.transition",{runId:this.runId,from,to,...trigger===null?{}:{trigger}}),this.events?.emit("workflow.node.transition",{runId:this.runId,from,to,trigger,externalKey:this.externalKey,severity:"info"})}async recordTransition(from,to,trigger){await this.persistence.saveTransition(this.runId,from,to,trigger),addSpanEvent("workflow.node.transition",{runId:this.runId,from,to,...trigger===null?{}:{trigger}}),this.events?.emit("workflow.node.transition",{runId:this.runId,from,to,trigger,externalKey:this.externalKey,severity:"info"})}async done(finalState,transitionsTaken,reason){return await this.persistence.savePhase(this.runId,finalState,"done"),await this.finalizeAsOwner("done",new Date().toISOString(),reason),this.logger.info("workflow run done",{finalState,transitionsTaken}),addSpanEvent("workflow.run.done",{runId:this.runId,finalState,transitionsTaken}),this.events?.emit("workflow.run.done",{runId:this.runId,finalState,transitionsTaken,externalKey:this.externalKey,severity:"info"}),this.result("done",finalState,transitionsTaken,reason)}async fail(finalState,transitionsTaken,reason="failed"){return await this.persistence.savePhase(this.runId,finalState,"failed"),await this.finalizeAsOwner("failed",new Date().toISOString(),reason),addSpanEvent("workflow.run.failed",{runId:this.runId,finalState,reason}),this.events?.emit("workflow.run.failed",{runId:this.runId,finalState,reason,externalKey:this.externalKey,severity:"error"}),this.logger.warn("workflow run failed",{finalState,transitionsTaken,reason}),this.result("failed",finalState,transitionsTaken,reason)}async pause(stateOrNodeId,transitionsTaken,vars,lastActionResult,reason){let data={transitionsTaken};if(vars!==void 0)data.effectiveVars=vars;if(lastActionResult!==void 0)data.lastActionResult={ok:lastActionResult.ok};return await this.persistence.saveWorkflowState(this.runId,stateOrNodeId,data),await this.persistence.savePhase(this.runId,stateOrNodeId,"paused"),await this.finalizeAsOwner("paused",new Date().toISOString(),reason),this.logger.info("workflow run paused",{stateOrNodeId,transitionsTaken}),addSpanEvent("workflow.run.paused",{runId:this.runId,node:stateOrNodeId,transitionsTaken}),this.events?.emit("workflow.run.paused",{runId:this.runId,node:stateOrNodeId,transitionsTaken,externalKey:this.externalKey,severity:"warning"}),this.result("paused",stateOrNodeId,transitionsTaken)}actionStart(stateOrNodeId,kind){addSpanEvent("workflow.action.start",{runId:this.runId,node:stateOrNodeId,kind}),this.events?.emit("workflow.action.start",{runId:this.runId,node:stateOrNodeId,kind,severity:"info"})}actionDone(stateOrNodeId,kind,durationMs,ok){addSpanEvent("workflow.action.done",{runId:this.runId,node:stateOrNodeId,kind,durationMs,ok}),this.events?.emit("workflow.action.done",{runId:this.runId,node:stateOrNodeId,kind,durationMs,ok,severity:ok?"info":"error"})}warnActionFailed(stateOrNodeId,transitionsTaken,error51){addSpanEvent("workflow.action.failed_continue",{runId:this.runId,node:stateOrNodeId,transitionsTaken,...error51===void 0?{}:{error:error51}}),this.events?.emit("workflow.action.failed_continue",{runId:this.runId,node:stateOrNodeId,transitionsTaken,...error51===void 0?{}:{error:error51},severity:"warning"}),this.logger.warn("action failed (continuing)",{node:stateOrNodeId,transitionsTaken,error:error51})}guardEvaluated(from,to,kind,passed){this.events?.emit("workflow.guard.evaluated",{runId:this.runId,from,to,kind,passed,externalKey:this.externalKey,severity:passed?"info":"warning"})}hitlAsk(node,kind,message){this.events?.emit("workflow.hitl.ask",{runId:this.runId,node,kind,message,severity:"info"})}hitlResponse(node,ok){this.events?.emit("workflow.hitl.response",{runId:this.runId,node,ok,severity:ok?"info":"warning"})}result(status,finalState,transitionsTaken,reason){return{runId:this.runId,workflowName:this.workflowName,mode:this.mode,status,finalState,transitionsTaken,...reason===void 0?{}:{reason}}}static runRecord(runId,workflowName,mode,startedAt,metadata,externalKey){return{id:runId,workflow_name:workflowName,mode,status:"running",started_at:startedAt,metadata_json:JSON.stringify(metadata??{}),completed_at:null,external_key:externalKey??null}}}function snapshotTransitions(data){let value=data?.transitionsTaken;return typeof value==="number"&&Number.isSafeInteger(value)&&value>=0?value:0}function snapshotActionResult(data){let value=data?.lastActionResult;return value!==null&&typeof value==="object"&&"ok"in value&&typeof value.ok==="boolean"?{ok:value.ok}:void 0}class CapabilityRegistry{kind;capabilities=new Map;constructor(kind){this.kind=kind}register(name,capability,origin2="extension"){this.capabilities.set(name,{capability,origin:origin2})}has(name){return this.capabilities.has(name)}get(name){let entry=this.capabilities.get(name);if(entry===void 0)throw Error(`Unknown ${this.kind}: ${name}`);return entry.capability}getEntry(name){return this.capabilities.get(name)}list(){return[...this.capabilities.keys()]}entries(){return[...this.capabilities.entries()]}}function assertRelativeExtensionPath(path8,options={}){let where=options.sourceName!==void 0?` declared by "${options.sourceName}"`:"";if(/^([/\\]|[A-Za-z]:[/\\])/.test(path8))throw Error(`extension path "${path8}"${where} must be relative (no absolute paths)`);if(path8.split(/[/\\]/).includes(".."))throw Error(`extension path "${path8}"${where} must not contain ".." traversal`)}init_zod();var RESERVED_VAR_NAMES=new Set(["task","state","node","iteration","run","runtime"]),IDENTIFIER=/^[A-Za-z_][A-Za-z0-9_]*$/,VarsSchema=exports_external.record(exports_external.string(),exports_external.string()).superRefine((vars,ctx)=>{for(let key of Object.keys(vars)){if(!IDENTIFIER.test(key))ctx.addIssue({code:"custom",message:`Invalid variable name "${key}" (must be a valid identifier)`});if(RESERVED_VAR_NAMES.has(key))ctx.addIssue({code:"custom",message:`Variable name "${key}" is reserved for runtime use`})}}),EnvSchema=exports_external.object({allow:exports_external.array(exports_external.string().regex(IDENTIFIER,"env.allow entries must be valid identifiers")).optional()}),relativeExtensionPath=exports_external.string().min(1).superRefine((value,ctx)=>{try{assertRelativeExtensionPath(value)}catch(error51){ctx.addIssue({code:"custom",message:error51 instanceof Error?error51.message:"invalid extension path"})}}),WorkflowExtensionsSchema=exports_external.object({actions:exports_external.array(relativeExtensionPath).optional(),guards:exports_external.array(relativeExtensionPath).optional()}).strict(),ActionDefSchema=exports_external.object({kind:exports_external.string().min(1),options:exports_external.record(exports_external.string(),exports_external.unknown()).optional(),onError:exports_external.enum(["fail","continue"]).optional()}),GuardDefSchema=exports_external.object({kind:exports_external.string().min(1),options:exports_external.record(exports_external.string(),exports_external.unknown()).optional()}),StateMachineWorkflowDefSchema=exports_external.object({$schema:exports_external.string().optional(),kind:exports_external.literal("state-machine").optional(),name:exports_external.string().min(1),version:exports_external.string().optional(),description:exports_external.string().optional(),initialState:exports_external.string().min(1),terminalStates:exports_external.array(exports_external.string().min(1)).optional(),failureStates:exports_external.array(exports_external.string().min(1)).optional(),iterationBound:exports_external.number().int().positive().optional(),defaultOnError:exports_external.enum(["fail","continue"]).optional(),vars:VarsSchema.optional(),env:EnvSchema.optional(),states:exports_external.array(exports_external.object({id:exports_external.string().min(1),description:exports_external.string().optional(),onEnter:exports_external.array(ActionDefSchema).optional(),onExit:exports_external.array(ActionDefSchema).optional(),pause:exports_external.boolean().optional(),resumeRerun:exports_external.boolean().optional()}).strict()),transitions:exports_external.array(exports_external.object({from:exports_external.string().min(1),to:exports_external.string().min(1),description:exports_external.string().optional(),trigger:exports_external.string().optional(),guard:GuardDefSchema.optional(),terminalReason:exports_external.string().optional()}).strict()),extensions:WorkflowExtensionsSchema.optional()}).strict(),TransitionFlowWorkflowDefSchema=exports_external.object({$schema:exports_external.string().optional(),kind:exports_external.literal("transition-flow"),name:exports_external.string().min(1),version:exports_external.string().optional(),description:exports_external.string().optional(),initialNode:exports_external.string().min(1),terminalNodes:exports_external.array(exports_external.string().min(1)).optional(),iterationBound:exports_external.number().int().positive().optional(),defaultOnError:exports_external.enum(["fail","continue"]).optional(),vars:VarsSchema.optional(),env:EnvSchema.optional(),nodes:exports_external.array(exports_external.object({id:exports_external.string().min(1),description:exports_external.string().optional(),type:exports_external.enum(["action","gate","parallel","decision"]).optional(),action:ActionDefSchema.optional(),pause:exports_external.boolean().optional(),resumeRerun:exports_external.boolean().optional()}).strict()),edges:exports_external.array(exports_external.object({from:exports_external.string().min(1),to:exports_external.string().min(1),description:exports_external.string().optional(),condition:GuardDefSchema.optional()}).strict()),extensions:WorkflowExtensionsSchema.optional()}).strict(),WorkflowDefSchema=exports_external.union([StateMachineWorkflowDefSchema,TransitionFlowWorkflowDefSchema]);async function loadWorkflowDef(path8,options={}){return parseWorkflowDef(await loadStructuredConfig(path8,options),path8)}function validateWorkflowDef(workflow){if(workflow.kind==="transition-flow")validateTransitionFlow(workflow);else validateStateMachine(workflow)}function validateStateMachine(workflow){let errors6=[],ids=workflow.states.map((state)=>state.id),states=new Set(ids),terminals=new Set(workflow.terminalStates??[]),failures=new Set(workflow.failureStates??[]);for(let id of duplicates(ids))errors6.push(`State "${id}" is declared more than once`);for(let failure of failures)if(!states.has(failure))errors6.push(`Failure state "${failure}" is not declared`);else if(!terminals.has(failure))errors6.push(`Failure state "${failure}" must also be declared as a terminal state`);if(!states.has(workflow.initialState))errors6.push(`Initial state "${workflow.initialState}" is not declared`);else if(terminals.has(workflow.initialState))errors6.push(`Initial state "${workflow.initialState}" must not be a terminal state`);for(let terminal of terminals)if(!states.has(terminal))errors6.push(`Terminal state "${terminal}" is not declared`);let outboundByState=new Map;for(let transition of workflow.transitions){if(!states.has(transition.from))errors6.push(`Transition source "${transition.from}" is not declared`);if(!states.has(transition.to))errors6.push(`Transition target "${transition.to}" is not declared`);let list=outboundByState.get(transition.from)??[];list.push(transition),outboundByState.set(transition.from,list)}for(let state of workflow.states){let outbound=outboundByState.get(state.id)??[];if(terminals.has(state.id)){if(outbound.length>0)errors6.push(`Terminal state "${state.id}" must not declare transitions`);continue}let ungatedIndex=outbound.findIndex((transition)=>transition.guard===void 0);if(ungatedIndex!==-1&&ungatedIndex<outbound.length-1)errors6.push(`State "${state.id}" has an unguarded transition that is not last; later transitions are unreachable`)}errors6.push(...checkVariableReferences(collectActionOptions(workflow),workflow.vars,workflow.env)),throwIfErrors(workflow,errors6)}function parseWorkflowDef(parsed,source){let result=selectWorkflowSchema(parsed).safeParse(parsed);if(!result.success)throw new WorkflowValidationError(`Workflow definition failed schema validation for ${source}: ${formatWorkflowIssues(result.error.issues)}`,result.error.issues);return validateWorkflowDef(result.data),result.data}function selectWorkflowSchema(parsed){if(parsed!==null&&typeof parsed==="object"){let value=parsed;if(value.kind==="transition-flow"||"nodes"in value||"edges"in value||"initialNode"in value)return TransitionFlowWorkflowDefSchema}return StateMachineWorkflowDefSchema}function formatWorkflowIssues(issues){return issues.map((issue2)=>{let path8=issue2.path.map(String).join(".");return path8.length>0?`${path8}: ${issue2.message}`:issue2.message}).join("; ")}function validateTransitionFlow(workflow){let errors6=[],ids=workflow.nodes.map((node)=>node.id),nodes=new Set(ids);for(let id of duplicates(ids))errors6.push(`Node "${id}" is declared more than once`);if(!nodes.has(workflow.initialNode))errors6.push(`Initial node "${workflow.initialNode}" is not declared`);let seenEdges=new Set;for(let edge of workflow.edges){if(!nodes.has(edge.from))errors6.push(`Edge source "${edge.from}" is not declared`);if(!nodes.has(edge.to))errors6.push(`Edge target "${edge.to}" is not declared`);let key=`${edge.from}→${edge.to}`;if(seenEdges.has(key))errors6.push(`Duplicate edge "${key}"`);seenEdges.add(key)}for(let terminal of workflow.terminalNodes??[]){if(!nodes.has(terminal))errors6.push(`Terminal node "${terminal}" is not declared`);if(workflow.edges.some((edge)=>edge.from===terminal))errors6.push(`Terminal node "${terminal}" must not declare edges`)}for(let node of workflow.nodes){let outbound=workflow.edges.filter((edge)=>edge.from===node.id),unconditional=outbound.findIndex((edge)=>edge.condition===void 0);if(unconditional!==-1&&unconditional<outbound.length-1)errors6.push(`Node "${node.id}" has an unconditional edge that is not last; later edges are unreachable`)}errors6.push(...checkVariableReferences(collectActionOptions(workflow),workflow.vars,workflow.env)),throwIfErrors(workflow,errors6)}function duplicates(ids){let seen=new Set,dupes=new Set;for(let id of ids){if(seen.has(id))dupes.add(id);seen.add(id)}return[...dupes]}function collectActionOptions(workflow){let optionSets=[],actions=workflow.kind==="transition-flow"?workflow.nodes.flatMap((node)=>node.action?[node.action]:[]):workflow.states.flatMap((state)=>[...state.onEnter??[],...state.onExit??[]]);for(let action of actions)if(action.options)optionSets.push(action.options);return optionSets}var RUNTIME_TEMPLATE_NAMESPACES=new Set(RUNTIME_BUILTIN_KEYS);function checkVariableReferences(optionSets,vars,env2){let declaredVars=new Set(Object.keys(vars??{})),allowedEnv2=new Set(env2?.allow??[]),errors6=[],reference=/\$\{([^}]+)\}/g;for(let options of optionSets)for(let value of Object.values(options)){if(typeof value!=="string")continue;for(let match of value.matchAll(reference)){let expr=(match[1]??"").trim(),[namespace,name]=expr.includes(".")?expr.split(".",2):[expr,void 0];if(namespace==="vars"){if(name!==void 0&&!declaredVars.has(name))errors6.push(`Unknown variable reference "\${${expr}}" (no var "${name}" declared)`)}else if(namespace==="env"){if(name!==void 0&&!allowedEnv2.has(name))errors6.push(`Env reference "\${${expr}}" is not in env.allow`)}else if(namespace!==void 0&&!RUNTIME_TEMPLATE_NAMESPACES.has(namespace))errors6.push(`Unknown template reference "\${${expr}}"`)}}return errors6}function throwIfErrors(workflow,errors6){if(errors6.length>0)throw new WorkflowValidationError(`Workflow "${workflow.name}" is invalid: ${errors6.join("; ")}`,errors6)}init_dist6();var TEMPLATE_REF=/\$\{([^}]+)\}/g;function mergeVars(workflowVars={},overrideVars={}){return{...workflowVars,...overrideVars}}function mergeSetVars(vars,setVars){if(setVars===void 0)return vars;let filtered={};for(let[key,value]of Object.entries(setVars))if(typeof value==="string")filtered[key]=value;return mergeVars(vars,filtered)}function resolveTemplates(value,context4){if(typeof value==="string")return resolveTemplateString(value,context4);if(Array.isArray(value))return value.map((entry)=>resolveTemplates(entry,context4));if(value!==null&&typeof value==="object")return Object.fromEntries(Object.entries(value).map(([key,entry])=>[key,resolveTemplates(entry,context4)]));return value}function resolveTemplateString(value,context4){return value.replace(TEMPLATE_REF,(_match,name)=>{return lookupRef(name,context4)})}function lookupRef(name,context4){if(name.startsWith("vars.")){let key=name.slice(5),resolved2=context4.vars[key];if(resolved2===void 0)throw new WorkflowValidationError(`Workflow variable "${key}" is not defined`);return resolved2}if(name.startsWith("env.")){let key=name.slice(4),resolved2=context4.env[key];if(resolved2===void 0)throw new WorkflowValidationError(`Environment variable "${key}" is not defined`);return resolved2}let resolved=context4.builtins?.[name];if(resolved===void 0)throw new WorkflowValidationError(`Workflow builtin "${name}" is not defined`);return String(resolved)}var SHELL_ENV_OPTION="__wfShellEnv",SHELL_BINDING=/^\$\{__WF_\d+\}$/,SHELL_BINDING_ANY=/\$\{__WF_\d+\}|\$__WF_\d+\b/;function resolveShellCommandTemplates(options,context4){let{command,args,...rest}=options;if(typeof command!=="string")return resolveTemplates(rest,context4);if(args!==void 0&&!Array.isArray(args))throw Error(`shell action "args" must be a string array when defined; got ${typeof args}`);if(Array.isArray(args)&&args.length>0)return{...resolveTemplates(rest,context4),command:resolveTemplateString(command,context4),args:resolveTemplates(args,context4)};let env2={},index2=0;if(!(SHELL_ENV_OPTION in options)&&SHELL_BINDING_ANY.test(command))throw Error("shell command must not contain the reserved $__WF_ placeholder namespace; it is minted by the template-binding pass");let existingBindings=options[SHELL_ENV_OPTION];if(existingBindings!==void 0&&typeof existingBindings==="object"&&existingBindings!==null){Object.assign(env2,existingBindings);while(`__WF_${index2}`in env2)index2++}let bound=command.replace(TEMPLATE_REF,(match,name)=>{if(SHELL_BINDING.test(match))return match;let key=`__WF_${index2++}`;return env2[key]=lookupRef(name,context4),`\${${key}}`});return{...resolveTemplates(rest,context4),command:bound,[SHELL_ENV_OPTION]:env2}}function resolveOnErrorPolicy(actionOnError,workflowDefault,runOptionOverride){return actionOnError??workflowDefault??runOptionOverride??"fail"}class WorkflowEngineHost{lifecycleBus;actions=new CapabilityRegistry("workflow action");guards=new CapabilityRegistry("workflow guard");constructor(lifecycleBus){this.lifecycleBus=lifecycleBus}registerAction(action,origin2="extension"){return this.actions.register(action.kind,action,origin2),this}registerGuard(guard,origin2="extension"){return this.guards.register(guard.kind,guard,origin2),this}hasAction(kind){return this.actions.has(kind)}hasGuard(kind){return this.guards.has(kind)}listActions(){return this.actions.list()}listGuards(){return this.guards.list()}actionOrigin(kind){return this.actions.getEntry(kind)?.origin}guardOrigin(kind){return this.guards.getEntry(kind)?.origin}async runAction(kind,options,context4){if(!this.actions.has(kind))throw new WorkflowValidationError(`Unknown workflow action "${kind}"`);return await this.actions.get(kind).execute(options,context4)}async evaluateGuard(kind,options,context4){return(await this.evaluateGuardResult(kind,options,context4)).passed}async evaluateGuardResult(kind,options,context4){if(!this.guards.has(kind))throw new WorkflowValidationError(`Unknown workflow guard "${kind}"`);let result=await this.guards.get(kind).evaluate(options,context4);return typeof result==="boolean"?{passed:result}:result}}function createDefaultWorkflowEngineHost(options={}){let host=new WorkflowEngineHost(options.lifecycleBus);return host.registerAction(new NoteActionRunner,"builtin"),host.registerAction(new ShellActionRunner(options.processExecutor??nodeBunFactory2.createProcessExecutor()),"builtin"),host.registerAction(new EventEmitActionRunner,"builtin"),host.registerGuard(new ShellGuardRunner(options.processExecutor??nodeBunFactory2.createProcessExecutor()),"builtin"),host.registerGuard({kind:"always",evaluate:async()=>!0},"builtin"),host.registerGuard({kind:"never",evaluate:async()=>!1},"builtin"),host.registerGuard({kind:"action-ok",evaluate:async(_options,context4)=>context4.lastActionResult?.ok===!0},"builtin"),host}class NoteActionRunner{kind="note";async execute(options,context4){let message=String(options.message??"");return context4?.events?.emit("workflow.hitl.note",{runId:context4.runId,node:context4.stateOrNodeId,message,severity:"info"}),{ok:!0,data:{message}}}}class EventEmitActionRunner{kind="event.emit";async execute(options,context4){let name=String(options.name??"");if(!name)return{ok:!1,error:'event.emit requires a non-empty "name" option'};let payload=options.payload??{};return context4?.events?.emit("workflow.custom",{name,payload,severity:"info"}),{ok:!0,data:{name,payload}}}}async function spawnShellCommand(processExecutor,options,workdir){let command=stringOption(options,"command"),explicitArgs=arrayOption(options,"args"),spawn2=explicitArgs.length===0?{command:"/bin/sh",args:["-c",command]}:{command,args:explicitArgs},timeout=optionalTimeoutOption(options),envOption=options[SHELL_ENV_OPTION],env2=envOption!==null&&typeof envOption==="object"?envOption:void 0,result=await processExecutor.run({command:spawn2.command,args:spawn2.args,cwd:optionalStringOption(options,"cwd",workdir),...env2!==void 0?{env:env2,envMode:"merge"}:{},...timeout!==void 0?{timeout}:{},rejectOnError:!1,forceBuffered:!0});return{stdout:result.stdout,stderr:result.stderr,exitCode:result.exitCode,timedOut:result.outcome==="timeout"}}class ShellActionRunner{processExecutor;kind="shell";constructor(processExecutor){this.processExecutor=processExecutor}async execute(options,context4){let spawn2=await spawnShellCommand(this.processExecutor,options,context4.workdir);if(spawn2.timedOut){let timeout=optionalTimeoutOption(options);return{ok:!1,data:{stdout:spawn2.stdout,stderr:spawn2.stderr,exitCode:spawn2.exitCode,timedOut:!0},error:`Shell action timed out after ${timeout}ms`}}let command=stringOption(options,"command");return{ok:spawn2.exitCode===0,data:{stdout:spawn2.stdout,stderr:spawn2.stderr,exitCode:spawn2.exitCode},...spawn2.exitCode===0?{}:{error:`Command "${command}" exited with ${spawn2.exitCode}`}}}}class ShellGuardRunner{processExecutor;kind="shell";constructor(processExecutor){this.processExecutor=processExecutor}async evaluate(options,context4){let spawn2=await spawnShellCommand(this.processExecutor,options,context4.workdir);return{passed:!spawn2.timedOut&&spawn2.exitCode===0,report:{stdout:spawn2.stdout,stderr:spawn2.stderr,exitCode:spawn2.exitCode,...spawn2.timedOut?{timedOut:!0}:{}}}}}function stringOption(options,key,fallback){let value=options[key];if(typeof value==="string")return value;if(fallback!==void 0)return fallback;throw new WorkflowValidationError(`Action option "${key}" must be a string`)}function optionalStringOption(options,key,fallback){let value=options[key];if(typeof value==="string")return value;if(value===void 0)return fallback;throw new WorkflowValidationError(`Action option "${key}" must be a string`)}function arrayOption(options,key){let value=options[key];if(value===void 0)return[];if(Array.isArray(value)&&value.every((entry)=>typeof entry==="string"))return value;throw new WorkflowValidationError(`Action option "${key}" must be a string array`)}function optionalTimeoutOption(options){let value=options.timeout;if(value===void 0)return;if(typeof value==="number"&&Number.isFinite(value)&&value>0)return value;throw new WorkflowValidationError('shell option "timeout" must be a positive number of milliseconds')}var WORKFLOW_ENGINE_SCHEMA_SQL=`
|
|
575
575
|
CREATE TABLE IF NOT EXISTS runs (
|
|
576
576
|
id TEXT PRIMARY KEY,
|
|
577
577
|
workflow_name TEXT,
|
|
@@ -1480,10 +1480,10 @@ ${fieldLine}
|
|
|
1480
1480
|
${raw}
|
|
1481
1481
|
---
|
|
1482
1482
|
`:this._frontmatterBlock.slice(0,rawStart)+raw+this._frontmatterBlock.slice(rawStart+oldRaw.length)}serialize(){let result=this._frontmatterBlock;result+=this._preamble;for(let section of this._sections)result+=section.modifiedText??section.originalText;return result}}function escapeYamlArrayElement(value){return`"${value.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}"`}function escapeYamlValue(value){if(value.startsWith('"')&&value.endsWith('"'))return value;if(/[:{}[\],&*?|>!%@`#"'\\\n\r]/.test(value))return`"${value.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}"`;if(/^(null|true|false|yes|no|on|off)$/i.test(value))return`"${value}"`;if(/^\d/.test(value)&&!/^\d{4}-\d{2}-\d{2}/.test(value))return`"${value}"`;return value}init_zod();var TASK_STATUSES=["backlog","todo","wip","testing","blocked","done","cancelled"],FEATURE_STATUSES=["backlog","active","verifying","blocked","done","cancelled"];var PRIORITIES=["P0","P1","P2","P3"],PROFILES=["simple","standard","complex","research","refine","plan","unit","review","docs"],TASK_TYPES=["task","issue","review","meta","brainstorm"],TASK_VARIANTS=["standard","feature-impl","issue","review","meta","brainstorm"];var FEATURE_ID_PATTERN=/^[A-Z][1-9]*$/;var TASK_STATUS_ALIASES={completed:"done",complete:"done","in-progress":"wip","in progress":"wip",in_progress:"wip",dropped:"cancelled",cancel:"cancelled",canceled:"cancelled",new:"backlog",pending:"backlog",blocked:"blocked",wip:"wip",testing:"testing",done:"done",cancelled:"cancelled",backlog:"backlog",todo:"todo"};function normalizeTaskStatus(raw){let key=raw.trim().toLowerCase(),resolved=TASK_STATUS_ALIASES[key];if(resolved===void 0)throw Error(`Unknown task status: ${JSON.stringify(raw)} (allowed: ${TASK_STATUSES.join(", ")})`);return resolved}var isoDateString=exports_external.string().min(1).refine((value)=>!Number.isNaN(Date.parse(value)),{message:"must be an ISO 8601 timestamp"}),featureId=exports_external.string().regex(FEATURE_ID_PATTERN,{message:"feature id must match ^[A-Z][1-9]*$ (DD-14)"}).nullable().optional(),wbsString=exports_external.string().regex(/^\d{4}$/,{message:"parent_wbs must be a 4-digit WBS string"}).nullable().optional(),taskFrontmatterSchema=exports_external.object({schema_version:exports_external.literal(1),name:exports_external.string().min(1),description:exports_external.string().optional(),status:exports_external.preprocess((val)=>{if(typeof val==="string")try{return normalizeTaskStatus(val)}catch{}return val},exports_external.enum(TASK_STATUSES)),type:exports_external.enum(TASK_TYPES).optional().default("task"),template:exports_external.enum(TASK_VARIANTS).optional(),profile:exports_external.enum(PROFILES).optional(),feature_id:featureId,parent_wbs:wbsString,priority:exports_external.enum(PRIORITIES).optional(),tags:exports_external.array(exports_external.string()).optional(),dependencies:exports_external.array(exports_external.string()).optional(),ac_numbering:exports_external.literal("task-local").optional(),ac_altitude:exports_external.enum(["graduating","task-local"]).optional(),done_forced:exports_external.preprocess((v)=>typeof v==="string"?v==="true":v,exports_external.boolean().optional()),done_reason:exports_external.string().optional(),feature_link_declined:exports_external.preprocess((v)=>typeof v==="string"?v==="true":v,exports_external.boolean().optional()),estimate_hours:exports_external.preprocess((v)=>typeof v==="string"&&v.trim()!==""?Number(v):v,exports_external.number().positive().optional()),created_at:isoDateString,updated_at:isoDateString}),featureFrontmatterSchema=exports_external.object({schema_version:exports_external.literal(1),id:exports_external.string().regex(FEATURE_ID_PATTERN,{message:"feature id must match ^[A-Z][1-9]*$ (DD-14)"}),name:exports_external.string().min(1),status:exports_external.enum(FEATURE_STATUSES),priority:exports_external.enum(PRIORITIES).optional(),tags:exports_external.array(exports_external.string()).optional(),created_at:isoDateString,updated_at:isoDateString});var taskBatchItemSchema=exports_external.object({name:exports_external.string().min(1,"name is required"),background:exports_external.string().optional(),requirements:exports_external.string().optional(),design:exports_external.string().optional(),plan:exports_external.string().optional(),acceptance_criteria:exports_external.string().optional(),feature_id:featureId,parent_wbs:wbsString,priority:exports_external.enum(PRIORITIES).optional(),tags:exports_external.array(exports_external.string()).optional(),template:exports_external.enum(TASK_VARIANTS).optional(),estimate_hours:exports_external.number().positive().optional()}).strict(),taskBatchSchema=exports_external.array(taskBatchItemSchema).min(1,"batch must contain at least one task");init_dist2();init_zod();var sectionNameSchema=exports_external.enum(TASK_CANONICAL_SECTIONS),matrixEntrySchema=exports_external.object({required:exports_external.array(sectionNameSchema).optional(),optional:exports_external.array(sectionNameSchema).optional(),forbidden:exports_external.array(sectionNameSchema).optional(),gate:exports_external.boolean().optional()}).strict(),matrixStatusSchema=exports_external.enum(["backlog","todo","wip","testing","blocked","done","cancelled"]),sectionMatrixSchema=exports_external.object({variants:exports_external.record(exports_external.string(),exports_external.partialRecord(matrixStatusSchema,matrixEntrySchema))}).strict();var CANONICAL_INDEX=new Map(TASK_CANONICAL_SECTIONS.map((s2,i2)=>[s2,i2]));init_dist6();init_zod();import{join}from"node:path";init_dist9();var SECRET_PATTERN=/(?:sk-[a-z0-9_-]{8,}|(?:api[_-]?key|token|secret|password)\s*[:=]\s*\S+|bearer\s+\S+)/gi;function redactAndBound(value,secrets,maxChars){let redacted=value.replace(SECRET_PATTERN,"[REDACTED]");for(let secret of secrets)if(secret!=="")redacted=redacted.split(secret).join("[REDACTED]");return redacted.length<=maxChars?redacted:`${redacted.slice(0,maxChars)}…`}import{createHash as createHash3}from"node:crypto";import crypto3 from"node:crypto";function canonicalJsonStringify(obj){if(obj===null||typeof obj!=="object")return JSON.stringify(obj);if(Array.isArray(obj))return`[${obj.map(canonicalJsonStringify).join(",")}]`;return`{${Object.keys(obj).sort().map((key)=>`${JSON.stringify(key)}:${canonicalJsonStringify(obj[key])}`).join(",")}}`}function computeDefinitionDigest(workflow){let canonical=canonicalJsonStringify(workflow);return`sha256:${crypto3.createHash("sha256").update(canonical,"utf8").digest("hex")}`}function evidencePayloadDigest(payload){return`sha256:${createHash3("sha256").update(canonicalJsonStringify(payload),"utf8").digest("hex")}`}async function defaultDecisionMaker(){return(await Promise.resolve().then(() => (init_dist9(),exports_dist3))).createDecisionMaker({timeoutMs:15000,maxRetries:0})}var DEFAULT_MIN_CONFIDENCE=0.8,NOUL_YES_THRESHOLD=0.5,DECIDE_EVIDENCE_MAX_CHARS=2000;async function runDecide(options,deps){let started=deps.now(),base2={schemaVersion:1,id:options.id,method:options.method},degraded=(reason,backend=null,confidence=null,evidenceDigest2=null)=>({...base2,value:options.default,backend,confidence,degraded:!0,reason,source:"default",evidenceDigest:evidenceDigest2,durationMs:deps.now()-started});if(!deps.enabled)return degraded("disabled");let maker;try{maker=deps.decisionMaker?await deps.decisionMaker():await defaultDecisionMaker()}catch{return degraded("no-backend")}let evidence=[],evidenceDigest=null;if(options.evidence!==void 0&&options.evidence.length>0)try{evidence=await Promise.all(options.evidence.map(async(path8)=>redactAndBound(await deps.readFile(path8),[],DECIDE_EVIDENCE_MAX_CHARS))),evidenceDigest=evidencePayloadDigest(evidence)}catch{return degraded("error")}let state={id:options.id,evidence},minConfidence=options.minConfidence??DEFAULT_MIN_CONFIDENCE;try{if(options.method==="choice"){let labels=Object.fromEntries((options.choices??[]).map((c3)=>[c3,c3])),answer2=await maker.choice(state,options.question,labels);if(!(answer2.label in labels))return degraded("error",maker.driver,answer2.confidence,evidenceDigest);if(answer2.confidence<minConfidence)return degraded("low-confidence",maker.driver,answer2.confidence,evidenceDigest);return{...base2,value:answer2.label,backend:maker.driver,confidence:answer2.confidence,degraded:!1,reason:"accepted",source:"model",evidenceDigest,durationMs:deps.now()-started}}let confidence=(await maker.noul(state,options.question)).probability;if(confidence<minConfidence)return degraded("low-confidence",maker.driver,confidence,evidenceDigest);return{...base2,value:confidence>=NOUL_YES_THRESHOLD?"yes":"no",backend:maker.driver,confidence,degraded:!1,reason:"accepted",source:"model",evidenceDigest,durationMs:deps.now()-started}}catch(error51){return degraded(error51 instanceof DecisionTimeoutError?"timeout":"error",maker.driver,null,evidenceDigest)}}var DECIDE_KIND="decide",DecideOptionsSchema=exports_external.object({id:exports_external.string().min(1),method:exports_external.enum(["choice","noul"]),question:exports_external.string().min(1),choices:exports_external.array(exports_external.string().min(1)).min(2).optional(),evidence:exports_external.array(exports_external.string().min(1)).optional(),default:exports_external.string().min(1),minConfidence:exports_external.number().min(0).max(1).optional(),resultFile:exports_external.string().min(1)}).strict().superRefine((options,ctx)=>{if(options.method==="choice"){if(options.choices===void 0)ctx.addIssue({code:"custom",message:"choices is required for method choice (at least 2 labels)"});else if(!options.choices.includes(options.default))ctx.addIssue({code:"custom",message:`default "${options.default}" is not one of choices [${options.choices.join(", ")}]`});return}if(options.choices!==void 0)ctx.addIssue({code:"custom",message:"choices is only valid for method choice; noul uses the engine yes/no outcomes"});if(options.default!=="yes"&&options.default!=="no")ctx.addIssue({code:"custom",message:'default must be "yes" or "no" for method noul'})});class DecideActionRunner{fileSystem;deps;kind=DECIDE_KIND;constructor(fileSystem,deps){this.fileSystem=fileSystem;this.deps=deps}async execute(rawOptions,context4){let parsed=DecideOptionsSchema.safeParse(rawOptions);if(!parsed.success)return{ok:!1,error:`${DECIDE_KIND}: invalid options — ${parsed.error.issues.map((i2)=>i2.message).join("; ")}`};let options=parsed.data,workdir=context4.workdir??".",result=await runDecide({...options,...options.evidence!==void 0?{evidence:options.evidence.map((path8)=>join(workdir,path8))}:{},resultFile:join(workdir,options.resultFile)},{enabled:this.deps.enabled,...this.deps.decisionMaker!==void 0?{decisionMaker:this.deps.decisionMaker}:{},readFile:async(path8)=>await this.fileSystem.readFile(path8),now:Date.now.bind(Date)});return await this.fileSystem.writeFile(join(workdir,options.resultFile),`${JSON.stringify(result,null,2)}
|
|
1483
|
-
`),{ok:!0,data:{value:result.value,decision:result}}}}class InvalidWorkflowRunIdError extends Error{code="invalid-run-id";constructor(runId){super(`Invalid workflow run id: ${JSON.stringify(runId)}`);this.name="InvalidWorkflowRunIdError"}}function parseWorkflowInventory(json3){if(typeof json3!=="object"||json3===null)return{ok:!1,error:"workflow inventory: projection is not an object"};let obj=json3,name=typeof obj.name==="string"?obj.name:"",kind=typeof obj.kind==="string"?obj.kind:"",format2=typeof obj.format==="string"?obj.format:"",version3=typeof obj.version==="string"||typeof obj.version==="number"?String(obj.version):"",definitionDigest=typeof obj.definitionDigest==="string"?obj.definitionDigest:"",source;if(obj.source!==void 0){if(typeof obj.source!=="object"||obj.source===null)return{ok:!1,error:"workflow inventory: invalid definition source"};let value=obj.source;if(typeof value.path!=="string"||value.path===""||typeof value.layer!=="string"||!["project","registered","shared"].includes(value.layer))return{ok:!1,error:"workflow inventory: invalid definition source path/layer"};source={path:value.path,layer:value.layer}}if(name==="")return{ok:!1,error:"workflow inventory: missing name"};if(kind==="")return{ok:!1,error:"workflow inventory: missing kind"};if(definitionDigest==="")return{ok:!1,error:"workflow inventory: missing definitionDigest"};if(!Array.isArray(obj.steps)||obj.steps.length===0)return{ok:!1,error:"workflow inventory: no declared steps"};let steps=[];for(let raw of obj.steps){if(typeof raw!=="object"||raw===null)return{ok:!1,error:"workflow inventory: a step is not an object"};let s2=raw;if(typeof s2.id!=="string"||s2.id==="")return{ok:!1,error:"workflow inventory: a step is missing its id"};steps.push({id:s2.id,initial:s2.initial===!0,terminal:s2.terminal===!0,failure:s2.failure===!0,pause:s2.pause===!0,loopBack:s2.loopBack===!0,conditional:s2.conditional===!0,...typeof s2.nodeType==="string"?{nodeType:s2.nodeType}:{},...typeof s2.description==="string"?{description:s2.description}:{}})}return{ok:!0,inventory:{name,kind,format:format2,version:version3,definitionDigest,steps,...source?{source}:{}}}}function assertInventoryIdentity(inventory,expectedDigest){if(expectedDigest==="")return{ok:!1,error:"workflow inventory: no expected definition digest to bind against"};if(inventory.definitionDigest!==expectedDigest)return{ok:!1,error:`workflow inventory: identity drift — projected ${inventory.definitionDigest} ≠ execution ${expectedDigest}`};return{ok:!0}}import{basename,isAbsolute,join as join4,resolve as resolve2}from"node:path";init_dist6();init_dist();init_dist2();init_zod();import{existsSync as existsSync3,statSync as statSync4}from"node:fs";import{homedir}from"node:os";import{dirname as dirname3,join as join3,resolve}from"node:path";import{fileURLToPath as fileURLToPath3}from"node:url";init_zod();var RFC3339_PATTERN=/^\d{4}-\d{2}-\d{2}[Tt]\d{2}:\d{2}:\d{2}(\.\d+)?([Zz]|[+-]\d{2}:\d{2})$/;function isRfc3339Timestamp(value){return RFC3339_PATTERN.test(value)&&Number.isFinite(Date.parse(value))}var ALL_FINDING_CODES=["L1.markdown-parse","L1.schema-validation","L2.missing-required-section","L2.forbidden-section","L2.disallowed-section","L2.heading-level","L2.section-order","L3.requirements-format","L3.requirements-checkbox","L3.requirements-empty","L3.ac-empty","L3.ac-requirement-coverage","L3.solution-file-line","L3.review-priority-table","L3.required-section-placeholder","L3.plan-format","L3.unchecked-checklist","L3.ac-checklist-text","L3.ac-bdd-error","L3.ac-bdd-warning","L3.ac-bdd-invalid","L3.scope-delineation","L3.one-active-goal","L3.children-limit","L3.review-testing-contradiction","L4.design-placeholder","L4.feature-not-found","L4.feature-terminal","L4.missing-feature-id","L4.parent-not-found","L4.dependency-not-found","L4.rollup-subtasks-open","L4.rollup-parent-open","L4.rollup-missing-roster","L4.rollup-roster-not-declared-dependency","L4.readiness-blocked","L4.prose-prerequisite-unlisted","L4.prerequisite-cycle","L4.prerequisite-not-done","L4.gate-language","L4.linked-task-parse-failed","L4.orphan-scenarios","L4.uncovered-task-scenario","L4.uncovered-feature-scenario","L4.verdict-rows-match-no-scenario","L4.verifying-incomplete-tasks","L4.dogfood-missing","L4.stale-line-anchor","L4.anchor-subject-mismatch","L4.malformed-verdict-artifact","L4.scenario-unverified","L4.testing-verdict-stub","L4.evidence-not-recoverable","L4.feature-receipt-missing","L4.feature-receipt-malformed","L4.feature-receipt-cross-feature","L4.feature-receipt-divergent","L4.feature-receipt-failed","L4.feature-receipt-run","L4.feature-receipt-stale","L4.feature-receipt-contract"];function isFindingCode(code){return ALL_FINDING_CODES.includes(code)}init_dist();init_zod();var projectEntrySchema=exports_external.object({name:exports_external.string().min(1),path:exports_external.string().min(1),port:exports_external.number().int().nonnegative().default(0)}),projectsFileSchema=exports_external.object({schema_version:exports_external.literal(1).default(1),projects:exports_external.array(projectEntrySchema).default([])});init_zod();var slashCommandCategorySchema=exports_external.enum(["git","dev","sys","harness"]),slashCommandItemSchema=exports_external.object({name:exports_external.string().min(1),description:exports_external.string().min(1),category:slashCommandCategorySchema.default("dev"),argumentHint:exports_external.string().optional(),tags:exports_external.array(exports_external.string()).default([]),role:exports_external.string().optional(),source:exports_external.string().optional()}),slashCommandsFileSchema=exports_external.object({version:exports_external.number().int().default(1),updatedAt:exports_external.string().optional(),commands:exports_external.array(slashCommandItemSchema).default([])});var SPUR_LOG_LEVELS=["debug","info","warn","error"],DEFAULT_TASKS_DIR="docs/tasks",DEFAULT_FEATURES_DIR="docs/features",DEFAULT_DATABASE_URL=".spur/spur.db";var folderConfigSchema=exports_external.object({baseCounter:exports_external.number().int().nonnegative().default(0),label:exports_external.string().optional()});function folderPathWithDefault(defaultPath){return exports_external.preprocess((v)=>v==null?void 0:v,exports_external.string().default(defaultPath))}var tasksConfigSchema=exports_external.object({folders:exports_external.record(exports_external.string(),folderConfigSchema).default({}),active:folderPathWithDefault(DEFAULT_TASKS_DIR),severity:exports_external.record(exports_external.string(),exports_external.enum(["error","warning","off"])).optional()}).superRefine((data,ctx)=>{if(data.severity){for(let code of Object.keys(data.severity))if(!isFindingCode(code))ctx.addIssue({code:exports_external.ZodIssueCode.custom,path:["severity",code],message:`Unknown finding code "${code}" in severity overrides map`})}}),featuresConfigSchema=exports_external.object({dir:folderPathWithDefault(DEFAULT_FEATURES_DIR)}),EXECUTOR_CAPABILITY_TIERS=["cheap","standard","capable-1","capable-2","capable-3"];function normalizeExecutorTier(value){return value==="capable"?"capable-1":value}var executorCapabilityTierSchema=exports_external.preprocess((value)=>{if(value===void 0||value===null)return;return typeof value==="string"?normalizeExecutorTier(value):value},exports_external.enum(EXECUTOR_CAPABILITY_TIERS).optional()),AGENT_ROLE_NAMES=["scribe","coder","reviewer","planner"];var EXECUTION_CAPABILITY_AXES=["fsRead","fsWrite","networkEgress","processSpawn","externalMutationApproval"],SESSION_CAPABILITY_AXES=["resumeById","sessionDir","persistentStdin","structuredOutput"],AGENT_RUN_CAPABILITY_AXES=[...EXECUTION_CAPABILITY_AXES,...SESSION_CAPABILITY_AXES],EXECUTION_CAPABILITY_STATES=["enforced","available","unavailable","unknown"],EXECUTION_CAPABILITY_PROVENANCES=["native-known","operator-configured","unattested"],ExecutionCapabilityAttestationSchema=exports_external.object({state:exports_external.enum(EXECUTION_CAPABILITY_STATES),provenance:exports_external.enum(EXECUTION_CAPABILITY_PROVENANCES)}),ExecutionCapabilitiesSchema=exports_external.object({version:exports_external.literal(1),axes:exports_external.partialRecord(exports_external.enum(EXECUTION_CAPABILITY_AXES),ExecutionCapabilityAttestationSchema)}),EXECUTION_CAPABILITY_REQUIREMENTS=["available","enforced"],RequiresCapabilitiesSchema=exports_external.partialRecord(exports_external.enum(AGENT_RUN_CAPABILITY_AXES),exports_external.enum(EXECUTION_CAPABILITY_REQUIREMENTS)),executorAvailabilityOwnerSchema=exports_external.enum(["operator","quota","probe"]),executorDisabledObjectSchema=exports_external.object({owner:executorAvailabilityOwnerSchema,since:exports_external.string().refine(isRfc3339Timestamp,{message:"since must be an RFC 3339 timestamp"}),reason:exports_external.string().min(1)}),AgentExecutorConfigSchema=exports_external.object({name:exports_external.string().min(1),agent:exports_external.string().min(1),model:exports_external.string().min(1).optional(),tier:executorCapabilityTierSchema.optional(),executionCapabilities:ExecutionCapabilitiesSchema.optional(),disabled:exports_external.union([exports_external.boolean(),executorDisabledObjectSchema]).default(!1)});var AgentRoleConfigSchema=exports_external.object({tier:exports_external.enum(EXECUTOR_CAPABILITY_TIERS).optional(),stages:exports_external.array(exports_external.string().min(1)).min(1).optional()});var FleetMemberSchema=exports_external.object({id:exports_external.string().min(1).optional(),role:exports_external.enum(AGENT_ROLE_NAMES,{error:(issue2)=>Error(`Unknown role "${issue2.input}" — expected one of: ${AGENT_ROLE_NAMES.join(", ")}`)}).optional(),executor:exports_external.string().min(1).optional(),purpose:exports_external.string().optional(),enabled:exports_external.boolean().optional()}),FLEET_STRATEGIES=["rest","gtd"],FleetMemberEntrySchema=FleetMemberSchema.superRefine((member,ctx)=>{if(member.role===void 0&&member.executor===void 0)ctx.addIssue({code:exports_external.ZodIssueCode.custom,message:"must declare a role or an executor — at least one is required"})}),AgentFleetSchema=exports_external.object({enabled:exports_external.boolean().default(!1),strategy:exports_external.enum(FLEET_STRATEGIES).default("rest"),orchestrator:exports_external.string().min(1).optional(),members:exports_external.array(FleetMemberEntrySchema).default([])});var AgentOutputConfigSchema=exports_external.object({"max-bytes":exports_external.number().int().positive().optional(),"max-lines":exports_external.number().int().positive().optional()}),AgentConfigSchema=exports_external.object({default:exports_external.string().optional(),executors:exports_external.array(AgentExecutorConfigSchema).optional(),roles:exports_external.record(exports_external.string(),AgentRoleConfigSchema).optional(),output:AgentOutputConfigSchema.optional(),sessionAffinity:exports_external.boolean().optional(),fleet:AgentFleetSchema.optional()}).superRefine((value,ctx)=>{for(let key of Object.keys(value.roles??{}))if(!AGENT_ROLE_NAMES.includes(key))ctx.addIssue({code:exports_external.ZodIssueCode.custom,path:["roles",key],message:`Unknown role "${key}" — expected one of: ${AGENT_ROLE_NAMES.join(", ")}`});let executors=value.executors,executorNames=new Set;if(executors!==void 0){let seen=new Set;for(let[index2,executor]of executors.entries()){if(seen.has(executor.name))ctx.addIssue({code:exports_external.ZodIssueCode.custom,message:`Duplicate executor name: ${executor.name}`,path:["executors",index2,"name"]});if(executor.name==="inline"||executor.name==="auto")ctx.addIssue({code:exports_external.ZodIssueCode.custom,message:`Executor name "${executor.name}" is reserved (the --agent selector value '${executor.name}' has fixed semantics); rename executor at index ${index2}.`,path:["executors",index2,"name"]});if(AGENT_ROLE_NAMES.includes(executor.name))ctx.addIssue({code:exports_external.ZodIssueCode.custom,message:`Executor name "${executor.name}" collides with the role selector namespace ("${executor.name}"); rename executor at index ${index2}.`,path:["executors",index2,"name"]});seen.add(executor.name),executorNames.add(executor.name)}}}),RulesConfigSchema=exports_external.object({paths:exports_external.array(exports_external.string()).optional()}),WorkflowsConfigSchema=exports_external.object({paths:exports_external.array(exports_external.string()).optional()}),WorkflowConfigSchema=exports_external.object({hitlDecisionMaker:exports_external.boolean().optional(),decideDecisionMaker:exports_external.boolean().optional(),logRetentionDays:exports_external.number().int().positive().default(30)}),RedactionConfigSchema=exports_external.object({enabled:exports_external.boolean().optional()}),HistoryRefreshConfigSchema=exports_external.object({on_completion:exports_external.boolean().default(!1),debounce_ms:exports_external.number().int().min(1000).default(600000)}),HistoryConfigSchema=exports_external.object({refresh:HistoryRefreshConfigSchema.optional()}),VersionCarrierEntrySchema=exports_external.looseObject({type:exports_external.string().min(1)}),BuilderBumpVerConfigSchema=exports_external.object({tagVersionSeparator:exports_external.string().min(1).default("-v"),aggregatePackage:exports_external.string().min(1).optional(),publishWorkflow:exports_external.string().min(1).default("publish.yml"),releaseCommitType:exports_external.string().min(1).default("chore"),releaseCommitScope:exports_external.string().min(1).default("release"),ghRunListLimit:exports_external.number().int().positive().default(5),versionCarriers:exports_external.array(VersionCarrierEntrySchema).default([])}),BuilderConfigSchema=exports_external.object({"bump-ver":BuilderBumpVerConfigSchema.optional()});var bootstrapOptionsSchema=exports_external.object({options:exports_external.record(exports_external.string(),exports_external.unknown()).optional()}),spurConfigSchema=exports_external.object({version:exports_external.string().optional(),name:exports_external.string().optional(),bootstrap:bootstrapOptionsSchema.optional(),agent:AgentConfigSchema.optional(),rules:RulesConfigSchema.optional(),workflows:WorkflowsConfigSchema.optional(),workflow:WorkflowConfigSchema.optional(),redaction:RedactionConfigSchema.optional(),history:HistoryConfigSchema.optional(),builder:BuilderConfigSchema.optional(),tasks:tasksConfigSchema.optional(),features:featuresConfigSchema.optional()});var configSchema3=exports_external.object({database:exports_external.object({url:exports_external.string().default(DEFAULT_DATABASE_URL)}).default({url:DEFAULT_DATABASE_URL}),server:exports_external.object({port:exports_external.coerce.number().int().positive().default(3000),host:exports_external.string().default("localhost"),openBrowser:exports_external.boolean().default(!0),webDistPath:exports_external.string().nullable().default(null)}).default({port:3000,host:"localhost",openBrowser:!0,webDistPath:null}),telemetry:exports_external.object({enabled:exports_external.boolean().default(!1),endpoint:exports_external.string().optional()}).default({enabled:!1}),logging:exports_external.object({level:exports_external.enum(SPUR_LOG_LEVELS).default("info")}).default({level:"info"})});import{existsSync as existsSync2,readdirSync as readdirSync2,statSync as statSync3}from"node:fs";import{dirname as dirname2,join as join2}from"node:path";var BUNDLED_CONFIG_DIRS=["config","spur-cli/config"],cachedRoot;function bundledConfigRoot(){if(cachedRoot!==void 0)return cachedRoot;let dir=import.meta.dirname;while(!0){for(let name of BUNDLED_CONFIG_DIRS){let candidate=join2(dir,name);if(isBundledConfigDir(candidate))return cachedRoot=candidate,cachedRoot}let parent=dirname2(dir);if(parent===dir)break;dir=parent}return cachedRoot=null,cachedRoot}function isBundledConfigDir(candidate){return existsSync2(candidate)&&statSync3(candidate).isDirectory()&&existsSync2(join2(candidate,"rules"))&&existsSync2(join2(candidate,"workflows"))}init_dist2();var SPUR_CONFIG_DIR=".spur",SPUR_CONFIG_FILE="config.yaml",GLOBAL_CONFIG_FILE=join3(homedir(),".config","spur","config.yaml"),LOADER_DIR=dirname3(fileURLToPath3(import.meta.url)),nextEmbeddedSchemasId=1,embeddedSchemasIds=new WeakMap,spurConfigCache=new Map;function embeddedSchemasId(embeddedSchemas){if(embeddedSchemas===void 0)return"disk";let id=embeddedSchemasIds.get(embeddedSchemas);if(id===void 0)id=nextEmbeddedSchemasId,nextEmbeddedSchemasId+=1,embeddedSchemasIds.set(embeddedSchemas,id);return`embedded:${id}`}function cacheKey(configPath,opts,validateJsonSchema2){return[configPath,validateJsonSchema2?"schema":"zod",opts?.schemaManifestSpecifier??"@gobing-ai/spur/package.json",embeddedSchemasId(opts?.embeddedSchemas)].join("\x00")}function resolveSchemaSpecifier(specifier,manifestSpecifier){if(specifier===manifestSpecifier){let workspaceManifest=join3(LOADER_DIR,"..","..","..","apps","cli","package.json");if(existsSync3(workspaceManifest))return workspaceManifest}try{let resolved=import.meta.resolve(specifier);return resolved.startsWith("file:")?fileURLToPath3(resolved):resolved}catch{return specifier}}function resolveConfigLayers(cwd){let layers={};if(!(cwd===void 0&&getEnvVar("SPUR_SKIP_PROJECT_CONFIG")==="true")){let projectConfig=join3(cwd??process.cwd(),SPUR_CONFIG_DIR,SPUR_CONFIG_FILE);if(existsSync3(projectConfig))layers.project=projectConfig}if(getEnvVar("SPUR_SKIP_GLOBAL_CONFIG")!=="true"&&existsSync3(GLOBAL_CONFIG_FILE))layers.global=GLOBAL_CONFIG_FILE;return layers}var EMBEDDED_PREFIX="\x00embedded-spur";function makeEmbeddedReader(embeddedSchemas){return async function(path8){if(path8.startsWith(EMBEDDED_PREFIX)){let subpath=path8.slice(EMBEDDED_PREFIX.length+1),embedded=embeddedSchemas.get(subpath);if(embedded===void 0)throw Error(`No embedded schema registered for "${subpath}".`);return embedded}return createNodeFileSystem2().readFile(path8)}}async function loadSpurConfig(cwd,opts){let layers=resolveConfigLayers(cwd),projectRoot=resolve(cwd??process.cwd());if(assertNoLegacyFleetFile(projectRoot,layers.project),layers.global===void 0&&layers.project===void 0)return spurConfigSchema.parse({});let validateJsonSchema2=opts?.validateJsonSchema??getEnvVar("NODE_ENV")!=="test",mtimeOf=(path8)=>path8!==void 0?String(statSync4(path8).mtimeMs):"-",key=[cacheKey(layers.project??layers.global??"",opts,validateJsonSchema2),layers.global??"-",mtimeOf(layers.project),mtimeOf(layers.global)].join("\x00"),cached2=spurConfigCache.get(key);if(cached2!==void 0)return cached2;let promise2=loadMergedConfig(layers,opts,validateJsonSchema2);return spurConfigCache.set(key,promise2),promise2.catch(()=>spurConfigCache.delete(key)),promise2}async function resolveDecideDecisionMakerEnabled(cwd,opts){return(await loadSpurConfig(cwd,opts)).workflow?.decideDecisionMaker===!0}function assertNoRetiredTeamKey(parsed,layerPath,replacementFile){let agent=parsed.agent;if(!isPlainObject5(agent)||!("team"in agent))return;throw Error(`agent.team is no longer supported (${layerPath??"the merged config"}). Declare the project fleet under agent.fleet in ${replacementFile}.`)}function assertNoGlobalFleetSection(globalRaw,layerPath,projectFile){let agent=globalRaw.agent;if(!isPlainObject5(agent)||!("fleet"in agent))return;throw Error(`agent.fleet is not supported in the global config (${layerPath??SPUR_CONFIG_FILE}). Declare the project fleet under agent.fleet in ${projectFile} — the flock belongs to a project, not to the machine.`)}function assertNoLegacyFleetFile(projectRoot,projectConfigPath){let candidates=new Set([join3(projectRoot,SPUR_CONFIG_DIR,"fleet.json")]);if(projectConfigPath!==void 0)candidates.add(join3(dirname3(projectConfigPath),"fleet.json"));for(let legacyFile of candidates){if(!existsSync3(legacyFile))continue;throw Error(`The retired fleet declaration ${legacyFile} still exists. Move its members and orchestrator under agent.fleet in the project config, then delete the file.`)}}function projectConfigReplacement(layers){return layers.project??join3(SPUR_CONFIG_DIR,SPUR_CONFIG_FILE)}function schemaValidationContext(opts){let embeddedSchemas=opts?.embeddedSchemas,manifestSpecifier=opts?.schemaManifestSpecifier??"@gobing-ai/spur/package.json",resolve2=(specifier)=>{if(embeddedSchemas!==void 0&&specifier===manifestSpecifier)return`${EMBEDDED_PREFIX}/package.json`;return resolveSchemaSpecifier(specifier,manifestSpecifier)},fileSystem=embeddedSchemas?{readFile:makeEmbeddedReader(embeddedSchemas)}:void 0;return{resolve:resolve2,...fileSystem!==void 0?{fileSystem}:{}}}async function readRawYamlLayer(configPath,kind){let nodeFs=createNodeFileSystem2(),text3;try{text3=await nodeFs.readFile(nodeFs.resolve(configPath))}catch(error51){throw Error(`Failed to read ${kind} config ${configPath}: ${error51.message}`)}try{return $parse(text3)??{}}catch(error51){throw Error(`Failed to parse ${kind} config ${configPath}: ${error51.message}`)}}function isPlainObject5(value){return typeof value==="object"&&value!==null&&!Array.isArray(value)}function executorNameOf(item){return isPlainObject5(item)&&typeof item.name==="string"?item.name:void 0}function isConcatPath(segments){return segments.length===2&&segments[0]==="rules"&&segments[1]==="paths"||segments.length===2&&segments[0]==="workflows"&&segments[1]==="paths"}function byKeyIdentityFor(segments){if(segments.length===2&&segments[0]==="agent"&&segments[1]==="executors")return executorNameOf;return}function concatUnique(globalItems,projectItems){let out=[...globalItems];for(let item of projectItems)if(!out.includes(item))out.push(item);return out}function mergeByKeyIdentity(globalItems,projectItems,identityOf,segments){let merged=[],indexByIdentity=new Map;for(let item of globalItems){let identity5=identityOf(item);if(identity5!==void 0&&!indexByIdentity.has(identity5))indexByIdentity.set(identity5,merged.length);merged.push(item)}let matchedProjectIdentities=new Set;for(let item of projectItems){let identity5=identityOf(item),existing=identity5===void 0||matchedProjectIdentities.has(identity5)?void 0:indexByIdentity.get(identity5);if(existing===void 0){merged.push(item);continue}if(identity5!==void 0)matchedProjectIdentities.add(identity5);let base2=merged[existing];merged[existing]=isPlainObject5(base2)&&isPlainObject5(item)?mergeDeep(base2,item,[...segments,existing]):item}return merged}function mergeDeep(globalValue,projectValue,segments){if(isPlainObject5(globalValue)&&isPlainObject5(projectValue)){let out={...globalValue};for(let[key,projectItem]of Object.entries(projectValue))out[key]=key in out?mergeDeep(out[key],projectItem,[...segments,key]):projectItem;return out}if(Array.isArray(globalValue)&&Array.isArray(projectValue)){if(isConcatPath(segments))return concatUnique(globalValue,projectValue);let identityOf=byKeyIdentityFor(segments);if(identityOf!==void 0)return mergeByKeyIdentity(globalValue,projectValue,identityOf,segments);return projectValue}return projectValue}function mergeSpurConfigLayers(globalRaw,projectRaw){return mergeDeep(globalRaw,projectRaw,[])}function formatZodPath(path8){return path8.map((segment,index2)=>typeof segment==="number"?`[${segment}]`:index2===0?segment:`.${segment}`).join("")}function parseViolationPath(path8){let segments=[];for(let part of path8.split(".")){let bracket=part.indexOf("["),key=bracket===-1?part:part.slice(0,bracket);if(key!=="")segments.push(key);if(bracket!==-1)for(let match of part.slice(bracket).matchAll(/\[(\d+)\]/g))segments.push(Number(match[1]))}return segments}function findItemByIdentity(node,identityOf,identity5){return Array.isArray(node)?node.find((entry)=>identityOf(entry)===identity5):void 0}function describeIssueProvenance(issuePath,merged,globalRaw,projectRaw){let g2=globalRaw,p=projectRaw,m=merged,segments=[],parentG=globalRaw,parentP=projectRaw,identityPrefix="";for(let segment of issuePath){if(parentG=g2,parentP=p,segments=[...segments,segment],typeof segment==="number"){let mergedItem=Array.isArray(m)?m[segment]:void 0,identityOf=byKeyIdentityFor(segments.slice(0,-1));if(identityOf!==void 0&&mergedItem!==void 0){let identity5=identityOf(mergedItem);if(identity5!==void 0)identityPrefix=`executor "${identity5}" `,g2=findItemByIdentity(g2,identityOf,identity5),p=findItemByIdentity(p,identityOf,identity5)}else g2=Array.isArray(g2)&&segment<g2.length?g2[segment]:void 0,p=Array.isArray(p)&&segment<p.length?p[segment]:void 0;m=mergedItem;continue}g2=isPlainObject5(g2)?g2[segment]:void 0,p=isPlainObject5(p)?p[segment]:void 0,m=isPlainObject5(m)?m[segment]:void 0}let label;if(g2!==void 0&&p!==void 0)label="set in both layers (project value wins)";else if(g2!==void 0)label="from global layer";else if(p!==void 0)label="from project layer";else if(parentP!==void 0&&parentG===void 0)label="from project layer (key absent there)";else if(parentG!==void 0&&parentP===void 0)label="from global layer (key absent there)";else label="missing in both layers";return`${identityPrefix}${label}`}function parseMergedWithProvenance(merged,globalRaw,projectRaw,layers){try{return spurConfigSchema.parse(merged)}catch(error51){if(!(error51 instanceof ZodError))throw error51;let details=error51.issues.map((issue2)=>{let path8=issue2.path.filter((segment)=>typeof segment!=="symbol");return` ${formatZodPath(path8)}: ${issue2.message} (${describeIssueProvenance(path8,merged,globalRaw,projectRaw)})`}).join(`
|
|
1483
|
+
`),{ok:!0,data:{value:result.value,decision:result}}}}class InvalidWorkflowRunIdError extends Error{code="invalid-run-id";constructor(runId){super(`Invalid workflow run id: ${JSON.stringify(runId)}`);this.name="InvalidWorkflowRunIdError"}}var TERMINAL_REASONS=["done","paused-operator","failed-check","failed-agent","failed-timeout","failed-guard","cancelled","interrupted","retry-exhausted"];function isTerminalReason(value){return TERMINAL_REASONS.includes(value)}var BOOKKEEPING_WORKFLOWS=["task-lifecycle","feature-lifecycle"];function isBookkeepingWorkflow(workflowName){return BOOKKEEPING_WORKFLOWS.includes(workflowName)}function classifyTerminalReason({status,engineReason,actionKind,errorText}){if(engineReason!==void 0&&engineReason!==null&&isTerminalReason(engineReason))return engineReason;if(status==="interrupted")return"interrupted";if(status==="paused")return"paused-operator";if(status==="done")return"done";if(engineReason==="no-passing-transition"||engineReason==="no-passing-edge")return"failed-guard";if(engineReason==="iteration-bound-exceeded")return"retry-exhausted";if(errorText!==void 0&&errorText!==null&&/timeout/i.test(errorText))return"failed-timeout";if(actionKind==="agent.run")return"failed-agent";return"failed-check"}function parseWorkflowInventory(json3){if(typeof json3!=="object"||json3===null)return{ok:!1,error:"workflow inventory: projection is not an object"};let obj=json3,name=typeof obj.name==="string"?obj.name:"",kind=typeof obj.kind==="string"?obj.kind:"",format2=typeof obj.format==="string"?obj.format:"",version3=typeof obj.version==="string"||typeof obj.version==="number"?String(obj.version):"",definitionDigest=typeof obj.definitionDigest==="string"?obj.definitionDigest:"",source;if(obj.source!==void 0){if(typeof obj.source!=="object"||obj.source===null)return{ok:!1,error:"workflow inventory: invalid definition source"};let value=obj.source;if(typeof value.path!=="string"||value.path===""||typeof value.layer!=="string"||!["project","registered","shared"].includes(value.layer))return{ok:!1,error:"workflow inventory: invalid definition source path/layer"};source={path:value.path,layer:value.layer}}if(name==="")return{ok:!1,error:"workflow inventory: missing name"};if(kind==="")return{ok:!1,error:"workflow inventory: missing kind"};if(definitionDigest==="")return{ok:!1,error:"workflow inventory: missing definitionDigest"};if(!Array.isArray(obj.steps)||obj.steps.length===0)return{ok:!1,error:"workflow inventory: no declared steps"};let steps=[];for(let raw of obj.steps){if(typeof raw!=="object"||raw===null)return{ok:!1,error:"workflow inventory: a step is not an object"};let s2=raw;if(typeof s2.id!=="string"||s2.id==="")return{ok:!1,error:"workflow inventory: a step is missing its id"};steps.push({id:s2.id,initial:s2.initial===!0,terminal:s2.terminal===!0,failure:s2.failure===!0,pause:s2.pause===!0,loopBack:s2.loopBack===!0,conditional:s2.conditional===!0,...typeof s2.nodeType==="string"?{nodeType:s2.nodeType}:{},...typeof s2.description==="string"?{description:s2.description}:{}})}return{ok:!0,inventory:{name,kind,format:format2,version:version3,definitionDigest,steps,...source?{source}:{}}}}function assertInventoryIdentity(inventory,expectedDigest){if(expectedDigest==="")return{ok:!1,error:"workflow inventory: no expected definition digest to bind against"};if(inventory.definitionDigest!==expectedDigest)return{ok:!1,error:`workflow inventory: identity drift — projected ${inventory.definitionDigest} ≠ execution ${expectedDigest}`};return{ok:!0}}import{basename,isAbsolute,join as join4,resolve as resolve2}from"node:path";init_dist6();init_dist();init_dist2();init_zod();import{existsSync as existsSync3,statSync as statSync4}from"node:fs";import{homedir}from"node:os";import{dirname as dirname3,join as join3,resolve}from"node:path";import{fileURLToPath as fileURLToPath3}from"node:url";init_zod();init_zod();var BOARD_MODULE_ID_PATTERN=/^[a-z][a-z0-9-]*$/;function isSafeFrameUrl(value){let parsed;try{parsed=new URL(value)}catch{return!1}if(parsed.protocol!=="http:"&&parsed.protocol!=="https:")return!1;return parsed.username===""&&parsed.password===""}var sharedDeclarationFields={id:exports_external.string().regex(BOARD_MODULE_ID_PATTERN,"module id must match ^[a-z][a-z0-9-]*$"),name:exports_external.string().min(1,"module name must not be empty"),icon:exports_external.string().min(1,"module icon must not be empty"),sidebarLabel:exports_external.string().optional(),description:exports_external.string().optional(),order:exports_external.number().refine((value)=>Number.isFinite(value),{message:"module order must be a finite number"}).optional(),enabled:exports_external.boolean().optional().default(!0)},boardModuleDeclarationSchema=exports_external.discriminatedUnion("type",[exports_external.object({...sharedDeclarationFields,type:exports_external.literal("react"),directory:exports_external.string().min(1),entry:exports_external.string().min(1),styles:exports_external.array(exports_external.string().min(1)).optional().default(()=>[])}).strict(),exports_external.object({...sharedDeclarationFields,type:exports_external.literal("iframe"),url:exports_external.string().refine(isSafeFrameUrl,{message:"iframe url must be an absolute http(s) URL without embedded credentials (relative URLs and other schemes are rejected)"})}).strict()]),boardModuleDeclarationsSchema=exports_external.array(boardModuleDeclarationSchema);var RFC3339_PATTERN=/^\d{4}-\d{2}-\d{2}[Tt]\d{2}:\d{2}:\d{2}(\.\d+)?([Zz]|[+-]\d{2}:\d{2})$/;function isRfc3339Timestamp(value){return RFC3339_PATTERN.test(value)&&Number.isFinite(Date.parse(value))}var ALL_FINDING_CODES=["L1.markdown-parse","L1.schema-validation","L2.missing-required-section","L2.forbidden-section","L2.disallowed-section","L2.heading-level","L2.section-order","L3.requirements-format","L3.requirements-checkbox","L3.requirements-empty","L3.ac-empty","L3.ac-requirement-coverage","L3.solution-file-line","L3.review-priority-table","L3.required-section-placeholder","L3.plan-format","L3.unchecked-checklist","L3.ac-checklist-text","L3.ac-bdd-error","L3.ac-bdd-warning","L3.ac-bdd-invalid","L3.scope-delineation","L3.one-active-goal","L3.children-limit","L3.review-testing-contradiction","L4.design-placeholder","L4.feature-not-found","L4.feature-terminal","L4.missing-feature-id","L4.parent-not-found","L4.dependency-not-found","L4.rollup-subtasks-open","L4.rollup-parent-open","L4.rollup-missing-roster","L4.rollup-roster-not-declared-dependency","L4.readiness-blocked","L4.prose-prerequisite-unlisted","L4.prerequisite-cycle","L4.prerequisite-not-done","L4.gate-language","L4.linked-task-parse-failed","L4.orphan-scenarios","L4.uncovered-task-scenario","L4.uncovered-feature-scenario","L4.verdict-rows-match-no-scenario","L4.verifying-incomplete-tasks","L4.dogfood-missing","L4.stale-line-anchor","L4.anchor-unresolved","L4.anchor-subject-mismatch","L4.malformed-verdict-artifact","L4.scenario-unverified","L4.testing-verdict-stub","L4.evidence-not-recoverable","L4.feature-receipt-missing","L4.feature-receipt-malformed","L4.feature-receipt-cross-feature","L4.feature-receipt-divergent","L4.feature-receipt-failed","L4.feature-receipt-run","L4.feature-receipt-stale","L4.feature-receipt-contract"];function isFindingCode(code){return ALL_FINDING_CODES.includes(code)}init_dist();init_zod();var projectEntrySchema=exports_external.object({name:exports_external.string().min(1),path:exports_external.string().min(1),port:exports_external.number().int().nonnegative().default(0)}),projectsFileSchema=exports_external.object({schema_version:exports_external.literal(1).default(1),projects:exports_external.array(projectEntrySchema).default([])});init_zod();var slashCommandCategorySchema=exports_external.enum(["git","dev","sys","harness"]),slashCommandItemSchema=exports_external.object({name:exports_external.string().min(1),description:exports_external.string().min(1),category:slashCommandCategorySchema.default("dev"),argumentHint:exports_external.string().optional(),tags:exports_external.array(exports_external.string()).default([]),role:exports_external.string().optional(),source:exports_external.string().optional()}),slashCommandsFileSchema=exports_external.object({version:exports_external.number().int().default(1),updatedAt:exports_external.string().optional(),commands:exports_external.array(slashCommandItemSchema).default([])});var SPUR_LOG_LEVELS=["debug","info","warn","error"],DEFAULT_TASKS_DIR="docs/tasks",DEFAULT_FEATURES_DIR="docs/features",DEFAULT_DATABASE_URL=".spur/spur.db";var folderConfigSchema=exports_external.object({baseCounter:exports_external.number().int().nonnegative().default(0),label:exports_external.string().optional()});function folderPathWithDefault(defaultPath){return exports_external.preprocess((v)=>v==null?void 0:v,exports_external.string().default(defaultPath))}var tasksConfigSchema=exports_external.object({folders:exports_external.record(exports_external.string(),folderConfigSchema).default({}),active:folderPathWithDefault(DEFAULT_TASKS_DIR),severity:exports_external.record(exports_external.string(),exports_external.enum(["error","warning","off"])).optional()}).superRefine((data,ctx)=>{if(data.severity){for(let code of Object.keys(data.severity))if(!isFindingCode(code))ctx.addIssue({code:exports_external.ZodIssueCode.custom,path:["severity",code],message:`Unknown finding code "${code}" in severity overrides map`})}}),featuresConfigSchema=exports_external.object({dir:folderPathWithDefault(DEFAULT_FEATURES_DIR)}),EXECUTOR_CAPABILITY_TIERS=["cheap","standard","capable-1","capable-2","capable-3"];function normalizeExecutorTier(value){return value==="capable"?"capable-1":value}var executorCapabilityTierSchema=exports_external.preprocess((value)=>{if(value===void 0||value===null)return;return typeof value==="string"?normalizeExecutorTier(value):value},exports_external.enum(EXECUTOR_CAPABILITY_TIERS).optional()),AGENT_ROLE_NAMES=["scribe","coder","reviewer","planner"];var EXECUTION_CAPABILITY_AXES=["fsRead","fsWrite","networkEgress","processSpawn","externalMutationApproval"],SESSION_CAPABILITY_AXES=["resumeById","sessionDir","persistentStdin","structuredOutput"],AGENT_RUN_CAPABILITY_AXES=[...EXECUTION_CAPABILITY_AXES,...SESSION_CAPABILITY_AXES],EXECUTION_CAPABILITY_STATES=["enforced","available","unavailable","unknown"],EXECUTION_CAPABILITY_PROVENANCES=["native-known","operator-configured","unattested"],ExecutionCapabilityAttestationSchema=exports_external.object({state:exports_external.enum(EXECUTION_CAPABILITY_STATES),provenance:exports_external.enum(EXECUTION_CAPABILITY_PROVENANCES)}),ExecutionCapabilitiesSchema=exports_external.object({version:exports_external.literal(1),axes:exports_external.partialRecord(exports_external.enum(EXECUTION_CAPABILITY_AXES),ExecutionCapabilityAttestationSchema)}),EXECUTION_CAPABILITY_REQUIREMENTS=["available","enforced"],RequiresCapabilitiesSchema=exports_external.partialRecord(exports_external.enum(AGENT_RUN_CAPABILITY_AXES),exports_external.enum(EXECUTION_CAPABILITY_REQUIREMENTS)),executorAvailabilityOwnerSchema=exports_external.enum(["operator","quota","probe"]),executorDisabledObjectSchema=exports_external.object({owner:executorAvailabilityOwnerSchema,since:exports_external.string().refine(isRfc3339Timestamp,{message:"since must be an RFC 3339 timestamp"}),reason:exports_external.string().min(1)}),AgentExecutorConfigSchema=exports_external.object({name:exports_external.string().min(1),agent:exports_external.string().min(1),model:exports_external.string().min(1).optional(),tier:executorCapabilityTierSchema.optional(),executionCapabilities:ExecutionCapabilitiesSchema.optional(),disabled:exports_external.union([exports_external.boolean(),executorDisabledObjectSchema]).default(!1)});var AgentRoleConfigSchema=exports_external.object({tier:exports_external.enum(EXECUTOR_CAPABILITY_TIERS).optional(),stages:exports_external.array(exports_external.string().min(1)).min(1).optional()});var FleetMemberSchema=exports_external.object({id:exports_external.string().min(1).optional(),role:exports_external.enum(AGENT_ROLE_NAMES,{error:(issue2)=>Error(`Unknown role "${issue2.input}" — expected one of: ${AGENT_ROLE_NAMES.join(", ")}`)}).optional(),executor:exports_external.string().min(1).optional(),purpose:exports_external.string().optional(),enabled:exports_external.boolean().optional()}),FLEET_STRATEGIES=["rest","gtd"],FleetMemberEntrySchema=FleetMemberSchema.superRefine((member,ctx)=>{if(member.role===void 0&&member.executor===void 0)ctx.addIssue({code:exports_external.ZodIssueCode.custom,message:"must declare a role or an executor — at least one is required"})}),AgentFleetSchema=exports_external.object({enabled:exports_external.boolean().default(!1),strategy:exports_external.enum(FLEET_STRATEGIES).default("rest"),orchestrator:exports_external.string().min(1).optional(),members:exports_external.array(FleetMemberEntrySchema).default([])});var AgentOutputConfigSchema=exports_external.object({"max-bytes":exports_external.number().int().positive().optional(),"max-lines":exports_external.number().int().positive().optional()}),AgentConfigSchema=exports_external.object({default:exports_external.string().optional(),executors:exports_external.array(AgentExecutorConfigSchema).optional(),roles:exports_external.record(exports_external.string(),AgentRoleConfigSchema).optional(),output:AgentOutputConfigSchema.optional(),sessionAffinity:exports_external.boolean().optional(),fleet:AgentFleetSchema.optional()}).superRefine((value,ctx)=>{for(let key of Object.keys(value.roles??{}))if(!AGENT_ROLE_NAMES.includes(key))ctx.addIssue({code:exports_external.ZodIssueCode.custom,path:["roles",key],message:`Unknown role "${key}" — expected one of: ${AGENT_ROLE_NAMES.join(", ")}`});let executors=value.executors,executorNames=new Set;if(executors!==void 0){let seen=new Set;for(let[index2,executor]of executors.entries()){if(seen.has(executor.name))ctx.addIssue({code:exports_external.ZodIssueCode.custom,message:`Duplicate executor name: ${executor.name}`,path:["executors",index2,"name"]});if(executor.name==="inline"||executor.name==="auto")ctx.addIssue({code:exports_external.ZodIssueCode.custom,message:`Executor name "${executor.name}" is reserved (the --agent selector value '${executor.name}' has fixed semantics); rename executor at index ${index2}.`,path:["executors",index2,"name"]});if(AGENT_ROLE_NAMES.includes(executor.name))ctx.addIssue({code:exports_external.ZodIssueCode.custom,message:`Executor name "${executor.name}" collides with the role selector namespace ("${executor.name}"); rename executor at index ${index2}.`,path:["executors",index2,"name"]});seen.add(executor.name),executorNames.add(executor.name)}}}),RulesConfigSchema=exports_external.object({paths:exports_external.array(exports_external.string()).optional()}),WorkflowsConfigSchema=exports_external.object({paths:exports_external.array(exports_external.string()).optional()}),WorkflowConfigSchema=exports_external.object({hitlDecisionMaker:exports_external.boolean().optional(),decideDecisionMaker:exports_external.boolean().optional(),logRetentionDays:exports_external.number().int().positive().default(30)}),RedactionConfigSchema=exports_external.object({enabled:exports_external.boolean().optional()}),HistoryRefreshConfigSchema=exports_external.object({on_completion:exports_external.boolean().default(!1),debounce_ms:exports_external.number().int().min(1000).default(600000)}),HistoryConfigSchema=exports_external.object({refresh:HistoryRefreshConfigSchema.optional()}),VersionCarrierEntrySchema=exports_external.looseObject({type:exports_external.string().min(1)}),BuilderBumpVerConfigSchema=exports_external.object({tagVersionSeparator:exports_external.string().min(1).default("-v"),aggregatePackage:exports_external.string().min(1).optional(),publishWorkflow:exports_external.string().min(1).default("publish.yml"),releaseCommitType:exports_external.string().min(1).default("chore"),releaseCommitScope:exports_external.string().min(1).default("release"),ghRunListLimit:exports_external.number().int().positive().default(5),versionCarriers:exports_external.array(VersionCarrierEntrySchema).default([])}),BuilderConfigSchema=exports_external.object({"bump-ver":BuilderBumpVerConfigSchema.optional()});var bootstrapOptionsSchema=exports_external.object({options:exports_external.record(exports_external.string(),exports_external.unknown()).optional()}),bootstrapSectionSchema=bootstrapOptionsSchema.extend({modules:boardModuleDeclarationsSchema.optional()}),spurConfigSchema=exports_external.object({version:exports_external.string().optional(),name:exports_external.string().optional(),bootstrap:bootstrapSectionSchema.optional(),agent:AgentConfigSchema.optional(),rules:RulesConfigSchema.optional(),workflows:WorkflowsConfigSchema.optional(),workflow:WorkflowConfigSchema.optional(),redaction:RedactionConfigSchema.optional(),history:HistoryConfigSchema.optional(),builder:BuilderConfigSchema.optional(),tasks:tasksConfigSchema.optional(),features:featuresConfigSchema.optional()});var configSchema3=exports_external.object({database:exports_external.object({url:exports_external.string().default(DEFAULT_DATABASE_URL)}).default({url:DEFAULT_DATABASE_URL}),server:exports_external.object({port:exports_external.coerce.number().int().positive().default(3000),host:exports_external.string().default("localhost"),openBrowser:exports_external.boolean().default(!0),webDistPath:exports_external.string().nullable().default(null)}).default({port:3000,host:"localhost",openBrowser:!0,webDistPath:null}),telemetry:exports_external.object({enabled:exports_external.boolean().default(!1),endpoint:exports_external.string().optional()}).default({enabled:!1}),logging:exports_external.object({level:exports_external.enum(SPUR_LOG_LEVELS).default("info")}).default({level:"info"})});import{existsSync as existsSync2,readdirSync as readdirSync2,statSync as statSync3}from"node:fs";import{dirname as dirname2,join as join2}from"node:path";var BUNDLED_CONFIG_DIRS=["config","spur-cli/config"],cachedRoot;function bundledConfigRoot(){if(cachedRoot!==void 0)return cachedRoot;let dir=import.meta.dirname;while(!0){for(let name of BUNDLED_CONFIG_DIRS){let candidate=join2(dir,name);if(isBundledConfigDir(candidate))return cachedRoot=candidate,cachedRoot}let parent=dirname2(dir);if(parent===dir)break;dir=parent}return cachedRoot=null,cachedRoot}function isBundledConfigDir(candidate){return existsSync2(candidate)&&statSync3(candidate).isDirectory()&&existsSync2(join2(candidate,"rules"))&&existsSync2(join2(candidate,"workflows"))}init_dist2();var SPUR_CONFIG_DIR=".spur",SPUR_CONFIG_FILE="config.yaml",GLOBAL_CONFIG_FILE=join3(homedir(),".config","spur","config.yaml"),LOADER_DIR=dirname3(fileURLToPath3(import.meta.url)),nextEmbeddedSchemasId=1,embeddedSchemasIds=new WeakMap,spurConfigCache=new Map;function embeddedSchemasId(embeddedSchemas){if(embeddedSchemas===void 0)return"disk";let id=embeddedSchemasIds.get(embeddedSchemas);if(id===void 0)id=nextEmbeddedSchemasId,nextEmbeddedSchemasId+=1,embeddedSchemasIds.set(embeddedSchemas,id);return`embedded:${id}`}function cacheKey(configPath,opts,validateJsonSchema2){return[configPath,validateJsonSchema2?"schema":"zod",opts?.schemaManifestSpecifier??"@gobing-ai/spur/package.json",embeddedSchemasId(opts?.embeddedSchemas)].join("\x00")}function resolveSchemaSpecifier(specifier,manifestSpecifier){if(specifier===manifestSpecifier){let workspaceManifest=join3(LOADER_DIR,"..","..","..","apps","cli","package.json");if(existsSync3(workspaceManifest))return workspaceManifest}try{let resolved=import.meta.resolve(specifier);return resolved.startsWith("file:")?fileURLToPath3(resolved):resolved}catch{return specifier}}function resolveConfigLayers(cwd){let layers={};if(!(cwd===void 0&&getEnvVar("SPUR_SKIP_PROJECT_CONFIG")==="true")){let projectConfig=join3(cwd??process.cwd(),SPUR_CONFIG_DIR,SPUR_CONFIG_FILE);if(existsSync3(projectConfig))layers.project=projectConfig}if(getEnvVar("SPUR_SKIP_GLOBAL_CONFIG")!=="true"&&existsSync3(GLOBAL_CONFIG_FILE))layers.global=GLOBAL_CONFIG_FILE;return layers}var EMBEDDED_PREFIX="\x00embedded-spur";function makeEmbeddedReader(embeddedSchemas){return async function(path8){if(path8.startsWith(EMBEDDED_PREFIX)){let subpath=path8.slice(EMBEDDED_PREFIX.length+1),embedded=embeddedSchemas.get(subpath);if(embedded===void 0)throw Error(`No embedded schema registered for "${subpath}".`);return embedded}return createNodeFileSystem2().readFile(path8)}}async function loadSpurConfig(cwd,opts){let layers=resolveConfigLayers(cwd),projectRoot=resolve(cwd??process.cwd());if(assertNoLegacyFleetFile(projectRoot,layers.project),layers.global===void 0&&layers.project===void 0)return spurConfigSchema.parse({});let validateJsonSchema2=opts?.validateJsonSchema??getEnvVar("NODE_ENV")!=="test",mtimeOf=(path8)=>path8!==void 0?String(statSync4(path8).mtimeMs):"-",key=[cacheKey(layers.project??layers.global??"",opts,validateJsonSchema2),layers.global??"-",mtimeOf(layers.project),mtimeOf(layers.global)].join("\x00"),cached2=spurConfigCache.get(key);if(cached2!==void 0)return cached2;let promise2=loadMergedConfig(layers,opts,validateJsonSchema2);return spurConfigCache.set(key,promise2),promise2.catch(()=>spurConfigCache.delete(key)),promise2}async function resolveDecideDecisionMakerEnabled(cwd,opts){return(await loadSpurConfig(cwd,opts)).workflow?.decideDecisionMaker===!0}function assertNoRetiredTeamKey(parsed,layerPath,replacementFile){let agent=parsed.agent;if(!isPlainObject5(agent)||!("team"in agent))return;throw Error(`agent.team is no longer supported (${layerPath??"the merged config"}). Declare the project fleet under agent.fleet in ${replacementFile}.`)}function assertNoGlobalFleetSection(globalRaw,layerPath,projectFile){let agent=globalRaw.agent;if(!isPlainObject5(agent)||!("fleet"in agent))return;throw Error(`agent.fleet is not supported in the global config (${layerPath??SPUR_CONFIG_FILE}). Declare the project fleet under agent.fleet in ${projectFile} — the flock belongs to a project, not to the machine.`)}function assertNoLegacyFleetFile(projectRoot,projectConfigPath){let candidates=new Set([join3(projectRoot,SPUR_CONFIG_DIR,"fleet.json")]);if(projectConfigPath!==void 0)candidates.add(join3(dirname3(projectConfigPath),"fleet.json"));for(let legacyFile of candidates){if(!existsSync3(legacyFile))continue;throw Error(`The retired fleet declaration ${legacyFile} still exists. Move its members and orchestrator under agent.fleet in the project config, then delete the file.`)}}function projectConfigReplacement(layers){return layers.project??join3(SPUR_CONFIG_DIR,SPUR_CONFIG_FILE)}function schemaValidationContext(opts){let embeddedSchemas=opts?.embeddedSchemas,manifestSpecifier=opts?.schemaManifestSpecifier??"@gobing-ai/spur/package.json",resolve2=(specifier)=>{if(embeddedSchemas!==void 0&&specifier===manifestSpecifier)return`${EMBEDDED_PREFIX}/package.json`;return resolveSchemaSpecifier(specifier,manifestSpecifier)},fileSystem=embeddedSchemas?{readFile:makeEmbeddedReader(embeddedSchemas)}:void 0;return{resolve:resolve2,...fileSystem!==void 0?{fileSystem}:{}}}async function readRawYamlLayer(configPath,kind){let nodeFs=createNodeFileSystem2(),text3;try{text3=await nodeFs.readFile(nodeFs.resolve(configPath))}catch(error51){throw Error(`Failed to read ${kind} config ${configPath}: ${error51.message}`)}try{return $parse(text3)??{}}catch(error51){throw Error(`Failed to parse ${kind} config ${configPath}: ${error51.message}`)}}function isPlainObject5(value){return typeof value==="object"&&value!==null&&!Array.isArray(value)}function executorNameOf(item){return isPlainObject5(item)&&typeof item.name==="string"?item.name:void 0}function isConcatPath(segments){return segments.length===2&&segments[0]==="rules"&&segments[1]==="paths"||segments.length===2&&segments[0]==="workflows"&&segments[1]==="paths"}function byKeyIdentityFor(segments){if(segments.length===2&&segments[0]==="agent"&&segments[1]==="executors")return executorNameOf;return}function concatUnique(globalItems,projectItems){let out=[...globalItems];for(let item of projectItems)if(!out.includes(item))out.push(item);return out}function mergeByKeyIdentity(globalItems,projectItems,identityOf,segments){let merged=[],indexByIdentity=new Map;for(let item of globalItems){let identity5=identityOf(item);if(identity5!==void 0&&!indexByIdentity.has(identity5))indexByIdentity.set(identity5,merged.length);merged.push(item)}let matchedProjectIdentities=new Set;for(let item of projectItems){let identity5=identityOf(item),existing=identity5===void 0||matchedProjectIdentities.has(identity5)?void 0:indexByIdentity.get(identity5);if(existing===void 0){merged.push(item);continue}if(identity5!==void 0)matchedProjectIdentities.add(identity5);let base2=merged[existing];merged[existing]=isPlainObject5(base2)&&isPlainObject5(item)?mergeDeep(base2,item,[...segments,existing]):item}return merged}function mergeDeep(globalValue,projectValue,segments){if(isPlainObject5(globalValue)&&isPlainObject5(projectValue)){let out={...globalValue};for(let[key,projectItem]of Object.entries(projectValue))out[key]=key in out?mergeDeep(out[key],projectItem,[...segments,key]):projectItem;return out}if(Array.isArray(globalValue)&&Array.isArray(projectValue)){if(isConcatPath(segments))return concatUnique(globalValue,projectValue);let identityOf=byKeyIdentityFor(segments);if(identityOf!==void 0)return mergeByKeyIdentity(globalValue,projectValue,identityOf,segments);return projectValue}return projectValue}function mergeSpurConfigLayers(globalRaw,projectRaw){return mergeDeep(globalRaw,projectRaw,[])}function formatZodPath(path8){return path8.map((segment,index2)=>typeof segment==="number"?`[${segment}]`:index2===0?segment:`.${segment}`).join("")}function parseViolationPath(path8){let segments=[];for(let part of path8.split(".")){let bracket=part.indexOf("["),key=bracket===-1?part:part.slice(0,bracket);if(key!=="")segments.push(key);if(bracket!==-1)for(let match of part.slice(bracket).matchAll(/\[(\d+)\]/g))segments.push(Number(match[1]))}return segments}function findItemByIdentity(node,identityOf,identity5){return Array.isArray(node)?node.find((entry)=>identityOf(entry)===identity5):void 0}function describeIssueProvenance(issuePath,merged,globalRaw,projectRaw){let g2=globalRaw,p=projectRaw,m=merged,segments=[],parentG=globalRaw,parentP=projectRaw,identityPrefix="";for(let segment of issuePath){if(parentG=g2,parentP=p,segments=[...segments,segment],typeof segment==="number"){let mergedItem=Array.isArray(m)?m[segment]:void 0,identityOf=byKeyIdentityFor(segments.slice(0,-1));if(identityOf!==void 0&&mergedItem!==void 0){let identity5=identityOf(mergedItem);if(identity5!==void 0)identityPrefix=`executor "${identity5}" `,g2=findItemByIdentity(g2,identityOf,identity5),p=findItemByIdentity(p,identityOf,identity5)}else g2=Array.isArray(g2)&&segment<g2.length?g2[segment]:void 0,p=Array.isArray(p)&&segment<p.length?p[segment]:void 0;m=mergedItem;continue}g2=isPlainObject5(g2)?g2[segment]:void 0,p=isPlainObject5(p)?p[segment]:void 0,m=isPlainObject5(m)?m[segment]:void 0}let label;if(g2!==void 0&&p!==void 0)label="set in both layers (project value wins)";else if(g2!==void 0)label="from global layer";else if(p!==void 0)label="from project layer";else if(parentP!==void 0&&parentG===void 0)label="from project layer (key absent there)";else if(parentG!==void 0&&parentP===void 0)label="from global layer (key absent there)";else label="missing in both layers";return`${identityPrefix}${label}`}function parseMergedWithProvenance(merged,globalRaw,projectRaw,layers){try{return spurConfigSchema.parse(merged)}catch(error51){if(!(error51 instanceof ZodError))throw error51;let details=error51.issues.map((issue2)=>{let path8=issue2.path.filter((segment)=>typeof segment!=="symbol");return` ${formatZodPath(path8)}: ${issue2.message} (${describeIssueProvenance(path8,merged,globalRaw,projectRaw)})`}).join(`
|
|
1484
1484
|
`);throw Error(`Spur config validation failed after merging global ${layers.global??"(absent)"} with project ${layers.project??"(absent)"}:
|
|
1485
1485
|
${details}`)}}function enrichSchemaViolationError(error51,merged,globalRaw,projectRaw,layers){let violations=error51.violations;if(!Array.isArray(violations))return error51;let details=violations.map((violation)=>{let v=violation,path8=typeof v.path==="string"?v.path:"(root)",message=typeof v.message==="string"?v.message:"schema violation",label=describeIssueProvenance(parseViolationPath(path8),merged,globalRaw,projectRaw);return` ${path8}: ${message} (${label})`}).join(`
|
|
1486
1486
|
`);return Error(`Merged Spur config failed JSON Schema validation (global ${layers.global??"(absent)"} + project ${layers.project??"(absent)"}):
|
|
1487
|
-
${details}`)}async function loadMergedConfig(layers,opts,validateJsonSchema2){let globalRaw=layers.global!==void 0?await readRawYamlLayer(layers.global,"global"):{},projectRaw=layers.project!==void 0?await readRawYamlLayer(layers.project,"project"):{},replacementFile=projectConfigReplacement(layers);if(layers.global!==void 0)assertNoRetiredTeamKey(globalRaw,layers.global,replacementFile),assertNoGlobalFleetSection(globalRaw,layers.global,replacementFile);if(layers.project!==void 0)assertNoRetiredTeamKey(projectRaw,layers.project,replacementFile);let merged=mergeSpurConfigLayers(globalRaw,projectRaw);if(validateJsonSchema2){let source=layers.project??layers.global??"";try{await validateDeclaredJsonSchema(merged,source,schemaValidationContext(opts))}catch(error51){throw enrichSchemaViolationError(error51,merged,globalRaw,projectRaw,layers)}}return parseMergedWithProvenance(merged,globalRaw,projectRaw,layers)}init_dist6();init_dist2();var EMBEDDED_SCHEMA_PREFIX="\x00embedded-spur",SPUR_SCHEMA_MANIFEST="@gobing-ai/spur/package.json";function normalizeLayerPath(cwd,path8){return resolve2(cwd,path8)}function workflowLayers(opts){let sharedRoot=opts.sharedRoot!==void 0?opts.sharedRoot:bundledConfigRoot(),sharedPath=sharedRoot!==null?normalizeLayerPath(opts.cwd,join4(sharedRoot,"workflows")):null,layers=[],seen=new Set,add=(id,path8)=>{if(seen.has(path8))return;seen.add(path8),layers.push({id,path:path8})};add("project",normalizeLayerPath(opts.cwd,join4(opts.cwd,".spur","workflows")));for(let entry of opts.registered){if(sharedPath!==null&&normalizeLayerPath(opts.cwd,entry)===sharedPath)continue;add("registered",normalizeLayerPath(opts.cwd,entry))}if(sharedPath!==null)add("shared",sharedPath);return layers}function createEmbeddedSchemaOptions(embedded){if(embedded===void 0||embedded.size===0)return;let nodeFs=createNodeFileSystem2();return{resolve:(specifier)=>specifier===SPUR_SCHEMA_MANIFEST?`${EMBEDDED_SCHEMA_PREFIX}/package.json`:specifier,fileSystem:{readFile:async(path8)=>{if(!path8.startsWith(EMBEDDED_SCHEMA_PREFIX))return nodeFs.readFile(path8);let subpath=path8.slice(EMBEDDED_SCHEMA_PREFIX.length+1),text3=embedded.get(subpath);if(text3===void 0)throw Error(`No embedded schema registered for "${subpath}".`);return text3}}}}async function readWorkflowNameFast(fs2,filePath){try{let text3=await fs2.readFile(filePath),parsed=$parse(text3);return typeof parsed?.name==="string"?parsed.name:null}catch{return null}}async function scanWorkflowByName(cwd,name,registered){let fs2=createNodeFileSystem2();for(let layer of workflowLayers({cwd,registered}))try{let files=(await fs2.readDir(layer.path)).filter((f)=>f.endsWith(".yaml")||f.endsWith(".yml"));for(let f of files){let abs=join4(layer.path,f);if(await readWorkflowNameFast(fs2,abs)===name)return{path:abs,source:layer.id}}}catch{}return null}function resolveWorkflowFile(cwd,file2){let fs2=createNodeFileSystem2(),projectPath=resolve2(cwd,file2);if(fs2.exists(projectPath))return{path:projectPath,source:"project"};let isYaml=file2.endsWith(".yaml")||file2.endsWith(".yml"),base2=basename(file2);if(!isAbsolute(file2)){let withYaml=isYaml?file2:`${file2}.yaml`,projectSpur=resolve2(cwd,".spur","workflows",withYaml);if(fs2.exists(projectSpur))return{path:projectSpur,source:"project"};if(!isYaml){let projectDirect=resolve2(cwd,`${file2}.yaml`);if(fs2.exists(projectDirect))return{path:projectDirect,source:"project"};let projectSpurPipeline=resolve2(cwd,".spur","workflows",`${file2}-pipeline.yaml`);if(fs2.exists(projectSpurPipeline))return{path:projectSpurPipeline,source:"project"};let projectDirectPipeline=resolve2(cwd,`${file2}-pipeline.yaml`);if(fs2.exists(projectDirectPipeline))return{path:projectDirectPipeline,source:"project"}}}let bundledRoot=bundledConfigRoot();if(bundledRoot!==null){let sharedName=isYaml?base2:`${base2}.yaml`,sharedPath=join4(bundledRoot,"workflows",sharedName);if(fs2.exists(sharedPath))return{path:sharedPath,source:"shared"};if(!isYaml){let sharedPipeline=join4(bundledRoot,"workflows",`${base2}-pipeline.yaml`);if(fs2.exists(sharedPipeline))return{path:sharedPipeline,source:"shared"};let sharedLiteral=join4(bundledRoot,"workflows",base2);if(fs2.exists(sharedLiteral))return{path:sharedLiteral,source:"shared"}}return{path:null,probed:[projectPath,sharedPath]}}return{path:null,probed:[projectPath,null]}}async function resolveWorkflowDefinition(cwd,fileOrName,options={}){let registered=options.registered??[],resolved=(basename(fileOrName)===fileOrName&&!/\.ya?ml$/.test(fileOrName)&&!createNodeFileSystem2().exists(resolve2(cwd,fileOrName))?await scanWorkflowByName(cwd,fileOrName,registered):null)??resolveWorkflowFile(cwd,fileOrName);if(resolved.path===null){let scanned=await scanWorkflowByName(cwd,fileOrName,registered);if(scanned!==null)resolved=scanned;else{let[probedProject,probedShared]=resolved.probed;throw Error(`Workflow not found: ${probedProject}${probedShared!==null?` (shared: ${probedShared})`:""}`)}}let embedded=createEmbeddedSchemaOptions(options.embeddedSchemas),workflow=await loadWorkflowDef(resolved.path,{validateSchema:options.validateSchema!==!1,...embedded!==void 0?embedded:{}});if(workflow.version==="")throw Error(`Invalid workflow definition ${resolved.path}: root "version" is an empty string. Omit the field for an unversioned definition, or give it a non-empty literal.`);let digest=computeDefinitionDigest(workflow);return{path:resolved.path,workflow,digest,layer:resolved.source}}var TERMINAL_REASONS=["done","paused-operator","failed-check","failed-agent","failed-timeout","failed-guard","cancelled","interrupted","retry-exhausted"];function isTerminalReason(value){return TERMINAL_REASONS.includes(value)}function classifyTerminalReason({status,engineReason,actionKind,errorText}){if(engineReason!==void 0&&engineReason!==null&&isTerminalReason(engineReason))return engineReason;if(status==="interrupted")return"interrupted";if(status==="paused")return"paused-operator";if(status==="done")return"done";if(engineReason==="no-passing-transition"||engineReason==="no-passing-edge")return"failed-guard";if(engineReason==="iteration-bound-exceeded")return"retry-exhausted";if(errorText!==void 0&&errorText!==null&&/timeout/i.test(errorText))return"failed-timeout";if(actionKind==="agent.run")return"failed-agent";return"failed-check"}var UNPERSISTED_PREFIX="trace-unpersisted:";class RunRowNotFoundError extends Error{runId;constructor(runId){super(`run row not found: ${runId}`);this.name="RunRowNotFoundError",this.runId=runId}}class WorkflowActionTraceWriter{inner;recordFailure;db;boundaries=new Map;constructor(inner,recordFailure,db2){this.inner=inner;this.recordFailure=recordFailure;this.db=db2}async saveActionStart(runId,node,kind,options){let outcome=await this.guard("action.start",{runId,node,kind},()=>this.inner.saveActionStart(runId,node,kind,options));if(!outcome.ok){let syntheticId=`${UNPERSISTED_PREFIX}${crypto.randomUUID()}`;return this.boundaries.set(syntheticId,{runId,node,kind}),this.lastStart={runId,node,kind},syntheticId}return this.boundaries.set(outcome.value,{runId,node,kind}),this.lastStart={runId,node,kind},outcome.value}lastStart;async saveActionFinalize(actionId,status,durationMs,ok,kind,result,redactor){let origin2=this.boundaries.get(actionId)??this.lastStart;await this.guard("action.finish",{runId:origin2?.runId??"",node:origin2?.node,kind},()=>this.inner.saveActionFinalize(actionId,status,durationMs,ok,kind,result,redactor)),this.boundaries.delete(actionId)}async finalizeRun(runId,status,completedAt,fence,reason){await this.inner.finalizeRun(runId,status,completedAt,fence,reason===void 0?void 0:classifyTerminalReason({status,engineReason:reason,errorText:reason}))}async claimRunOwnership(runId,owner,expectedStatuses){return this.inner.claimRunOwnership(runId,owner,expectedStatuses)}async interruptRun(runId,reason){return this.inner.interruptRun(runId,reason)}async recordAction(boundary2){let start=await this.guard("action.start",{runId:boundary2.runId,node:boundary2.node,kind:boundary2.kind},()=>this.inner.saveActionStart(boundary2.runId,boundary2.node,boundary2.kind));if(!start.ok)return start;let finish=await this.guard("action.finish",{runId:boundary2.runId,node:boundary2.node,kind:boundary2.kind},()=>this.inner.saveActionFinalize(start.value,boundary2.status,boundary2.durationMs,boundary2.ok,boundary2.kind,boundary2.result,boundary2.redactor));if(!finish.ok)return finish;return await this.backdateStart(start.value,boundary2),{ok:!0,actionId:start.value}}async backdateStart(actionId,boundary2){let db2=this.db;if(db2===void 0||boundary2.durationMs<=0)return;await this.guard("action.backdate",{runId:boundary2.runId,node:boundary2.node,kind:boundary2.kind},async()=>{let dao2=new ActionRunDao(db2),completedAt=await dao2.completedAtById(actionId);if(completedAt===null)return;let startedAt=new Date(new Date(completedAt).getTime()-boundary2.durationMs).toISOString();await dao2.setStartedAt(actionId,startedAt)})}async closeRun(runId,status,completedAt,reason){if(await this.inner.loadRun(runId)===void 0)throw new RunRowNotFoundError(runId);if(await this.inner.finalizeRun(runId,status,completedAt??new Date().toISOString(),void 0,reason===void 0?void 0:classifyTerminalReason({status,engineReason:reason,errorText:reason})),this.db===void 0)return{ok:!0};return{ok:!0,actionRows:(await new ActionRunDao(this.db).actionRowsByRunId(runId)).length}}async guard(operation,context4,emit){try{return{ok:!0,value:await emit()}}catch(error51){let failure={operation,runId:context4.runId,...context4.node!==void 0?{node:context4.node}:{},...context4.kind!==void 0?{kind:context4.kind}:{},error:error51 instanceof Error?error51.message:String(error51),at:new Date().toISOString()};try{this.recordFailure?.(failure)}catch{}return{ok:!1,failure}}}createRun(record3){return this.inner.createRun(record3)}savePhase(runId,phase,status){return this.inner.savePhase(runId,phase,status)}saveTransition(runId,from,to,trigger){return this.inner.saveTransition(runId,from,to,trigger)}saveWorkflowState(runId,state,data){return this.inner.saveWorkflowState(runId,state,data)}commitTransition(runId,from,to,trigger,state,data,phase){return this.inner.commitTransition(runId,from,to,trigger,state,data,phase)}loadRun(runId){return this.inner.loadRun(runId)}listRuns(){return this.inner.listRuns()}findRunByKey(workflowName,externalKey){return this.inner.findRunByKey(workflowName,externalKey)}createOrAttachRun(record3){return this.inner.createOrAttachRun(record3)}reseedRun(runId,newState){return this.inner.reseedRun(runId,newState)}loadCurrentState(runId){return this.inner.loadCurrentState(runId)}loadLatestStateSnapshot(runId){return this.inner.loadLatestStateSnapshot(runId)}listPausedRuns(options){return this.inner.listPausedRuns(options)}}function createWorkflowActionTraceWriter(db2,recordFailure){return new WorkflowActionTraceWriter(new DbWorkflowPersistenceAdapter(db2),recordFailure,db2)}var TRIPWIRE_CATALOG=Object.freeze({"retry-exhausted":{id:"retry-exhausted",version:1,response:"fail",nextDecision:"Retries are exhausted; an operator must decide to escalate, extend the retry policy, or fail the stage. No further automatic retry is permitted."},"hard-budget":{id:"hard-budget",version:1,response:"fail",nextDecision:"An operator must raise the declared budget or trim the stage scope, then re-run the action; the run stays failed until then."},"capability-denied":{id:"capability-denied",version:1,response:"fail",nextDecision:"An operator must attest the executor capabilities in agent config or lower the stage requiresCapabilities, then re-run the action."},"proof-invalidated":{id:"proof-invalidated",version:1,response:"fail",nextDecision:"An operator must restore the proof inputs or re-establish the verdict (re-verify) before record; recording against a changed tree is blocked."},"output-drop":{id:"output-drop",version:1,response:"continue",nextDecision:"The dispatch completed but its captured evidence is incomplete (bounded relay dropped chunks). Inspect the session/trace for full output if the result is contested."}});var SHELL_METACHARACTERS=/[;&|<>$`(){}[\]!*?~#\n\r"']/;function splitLaunchCommand(value,label){if(SHELL_METACHARACTERS.test(value))return{error:`${label} must not contain shell metacharacters (got ${value})`};let tokens=value.trim().split(/\s+/).filter((t)=>t.length>0),command=tokens[0];if(command===void 0)return{error:`Action option ${label.slice(label.indexOf('"'))} must be a non-empty string`};return{command,leadingArgs:tokens.slice(1)}}import crypto4 from"node:crypto";import{tmpdir}from"node:os";import{dirname as dirname4,join as join5,resolve as resolve3,sep}from"node:path";init_dist6();class ProofCaptureError extends Error{stderr;constructor(message,stderr){super(message);this.stderr=stderr;this.name="ProofCaptureError"}}var TASK_SPEC_SECTIONS=["Background","Requirements","Acceptance Criteria","Design","Plan"],CANONICAL_TASK_HEADING_RE=/^##[ \t]+(\d+)\.[ \t]+(\S.*)$/m;function taskDocumentShapeError(content){let doc2=MarkdownDocument.parse(content,"task"),heading=CANONICAL_TASK_HEADING_RE.exec(doc2.bodyWithoutFrontmatter);if(heading===null)return"no canonical task heading (`## <WBS>. <title>`) was found";if((heading[2]??"").trim()==="")return`the canonical task heading for WBS ${heading[1]} has an empty title`;if(TASK_SPEC_SECTIONS.filter((section)=>doc2.hasSection(section)).length===0)return`no task specification section (${TASK_SPEC_SECTIONS.join(", ")}) was found`;return null}async function readProofInputContents(fileSystem=createNodeFileSystem2(),workdir,options){for(let name of["taskFile","featureFile"]){let value=options[name];if(value!==void 0&&typeof value!=="string")return{ok:!1,error:`${name} must be a string when supplied (got ${typeof value})`}}let readOne=async(name)=>{let raw=name==="taskFile"?options.taskFile:options.featureFile;if(raw===void 0||raw==="")return{};let workdirAbs=resolve3(workdir),resolved=resolve3(workdirAbs,raw);if(!(resolved===workdirAbs||resolved.startsWith(`${workdirAbs}${sep}`)))return{error:`${name} must resolve under the workflow workdir (${workdirAbs}): ${raw}`};let stat;try{stat=await fileSystem.stat(resolved)}catch(error51){return{error:`${name} could not be inspected: ${error51.message}`}}if(stat===null)return{error:`${name} does not exist: ${raw} (resolved ${resolved}) — an explicitly supplied spec must be readable, not silently omitted`};if(!stat.isFile())return{error:`${name} is not a regular file: ${resolved}`};let content;try{content=await fileSystem.readFile(resolved)}catch(error51){return{error:`${name} is not readable: ${error51.message}`}}if(name==="taskFile"){let shapeError=taskDocumentShapeError(content);if(shapeError!==null)return{error:`taskFile is not a task document: ${raw} (resolved ${resolved}) — ${shapeError}. Supply the task specification markdown itself: a \`## <WBS>. <title>\` heading plus at least one of ${TASK_SPEC_SECTIONS.join(", ")}. A file containing only a path is not dereferenced.`}}return{content}},task=await readOne("taskFile");if(task.error!==void 0)return{ok:!1,error:task.error};let feature=await readOne("featureFile");if(feature.error!==void 0)return{ok:!1,error:feature.error};return{ok:!0,...task.content!==void 0?{taskContent:task.content}:{},...feature.content!==void 0?{featureContent:feature.content}:{}}}var DEFAULT_EXCLUDE_GLOBS=["docs/tasks*","docs/features*"];async function createGitAlternateTree(cwd,excludeGlobs=DEFAULT_EXCLUDE_GLOBS,executor=new NodeProcessExecutor2,fs2=createNodeFileSystem2()){let indexFile=join5(tmpdir(),`spur-proof-fingerprint-${crypto4.randomUUID()}.index`);try{await fs2.ensureDir(dirname4(indexFile));let env2=Object.fromEntries(Object.entries(getEnvVars()).filter((entry)=>entry[1]!==void 0));env2.GIT_INDEX_FILE=indexFile;let common4={cwd,env:env2,forceBuffered:!0,rejectOnError:!1},read=await executor.run({command:"git",args:["read-tree","HEAD"],...common4});if(read.exitCode!==0)throw new ProofCaptureError(`git read-tree HEAD failed with exit code ${read.exitCode}`,read.stderr);let excludes=excludeGlobs.map((glob)=>`:(exclude)${glob}`),add=await executor.run({command:"git",args:["add","-A","--",".",...excludes],...common4});if(add.exitCode!==0)throw new ProofCaptureError(`git add -A failed with exit code ${add.exitCode}`,add.stderr);let tree=await executor.run({command:"git",args:["write-tree"],...common4});if(tree.exitCode!==0)throw new ProofCaptureError(`git write-tree failed with exit code ${tree.exitCode}`,tree.stderr);return tree.stdout.trim()}catch(error51){if(error51 instanceof ProofCaptureError)throw error51;throw new ProofCaptureError(`git alternate-tree capture threw: ${error51.message}`)}finally{if(await fs2.exists(indexFile))try{await fs2.deleteFile(indexFile)}catch{}}}function extractTaskProofData(content){let doc2=MarkdownDocument.parse(content,"task"),fm=doc2.frontmatterData??{},wbs=typeof fm.wbs==="string"?fm.wbs:void 0,name=typeof fm.name==="string"?fm.name:void 0,feature_id=typeof fm.feature_id==="string"?fm.feature_id:void 0,depends_on;if(Array.isArray(fm.depends_on))depends_on=fm.depends_on.filter((d)=>typeof d==="string");else if(Array.isArray(fm.dependencies))depends_on=fm.dependencies.filter((d)=>typeof d==="string");let sections={},taskSections=["Background","Requirements","Acceptance Criteria","Design","Plan"];for(let sec of taskSections)if(doc2.hasSection(sec)){let body=doc2.getSection(sec);if(body!==null)sections[sec]=body.trim()}return{...wbs!==void 0?{wbs}:{},...name!==void 0?{name}:{},...feature_id!==void 0?{feature_id}:{},...depends_on!==void 0?{depends_on}:{},sections}}function extractFeatureProofData(content){let doc2=MarkdownDocument.parse(content,"feature"),fm=doc2.frontmatterData??{},id=typeof fm.id==="string"?fm.id:void 0,name=typeof fm.name==="string"?fm.name:void 0,sections={},featureSections=["Goal","Scope","Acceptance Criteria"];for(let sec of featureSections)if(doc2.hasSection(sec)){let body=doc2.getSection(sec);if(body!==null)sections[sec]=body.trim()}return{...id!==void 0?{id}:{},...name!==void 0?{name}:{},sections}}async function computeProofInputFingerprint(options={}){let cwd=options.cwd??process.cwd(),gitTree=await createGitAlternateTree(cwd,options.excludeGlobs??DEFAULT_EXCLUDE_GLOBS,options.processExecutor,options.fileSystem),task;if(options.taskContent!==void 0)task=extractTaskProofData(options.taskContent);let feature;if(options.featureContent!==void 0)feature=extractFeatureProofData(options.featureContent);let canonical=canonicalJsonStringify({gitTree,...task!==void 0?{task}:{},...feature!==void 0?{feature}:{},...options.learningsContent!==void 0?{learnings:options.learningsContent}:{}});return`sha256:${crypto4.createHash("sha256").update(canonical,"utf8").digest("hex")}`}var ProofInputFingerprint={compute:computeProofInputFingerprint};init_zod();var VERDICT_AGGREGATES=["PASS","PARTIAL","FAIL","UNKNOWN"],ROW_STATUSES=["MET","PARTIAL","UNMET","N/A"],CHECK_SEVERITIES=["blocker","major","minor","advisory"],verdictSchema=exports_external.string().transform((v,ctx)=>{let up=v.toUpperCase();if(!VERDICT_AGGREGATES.includes(up))return ctx.addIssue({code:"custom",message:`invalid verdict "${v}" (expected PASS|PARTIAL|FAIL|UNKNOWN)`}),"UNKNOWN";return up}),coverageRowSchema=exports_external.object({id:exports_external.string().optional(),scenario:exports_external.string().optional(),status:exports_external.string(),evidenceType:exports_external.string().optional(),evidence:exports_external.string().optional()}).superRefine((r,ctx)=>{if(r.id!==void 0&&r.scenario!==void 0&&r.id!==r.scenario)ctx.addIssue({code:"custom",message:`id/scenario conflict ("${r.id}" vs "${r.scenario}")`,path:["scenario"]});if(!ROW_STATUSES.includes(r.status.toUpperCase()))ctx.addIssue({code:"custom",message:`invalid row status "${r.status}"`,path:["status"]})}).transform((r)=>({id:r.id??r.scenario??"",status:r.status.toUpperCase(),evidenceType:r.evidenceType??"",evidence:r.evidence??""})),checkSchema=exports_external.object({name:exports_external.string().optional(),check:exports_external.string().optional(),id:exports_external.string().optional(),status:exports_external.string(),evidence:exports_external.string().optional().default(""),severity:exports_external.enum(CHECK_SEVERITIES).optional()}).superRefine((c3,ctx)=>{if(c3.name===void 0&&c3.check===void 0&&c3.id===void 0)ctx.addIssue({code:"custom",message:"check row needs one of name/check/id",path:["name"]})}).transform((c3)=>({name:c3.name??c3.check??c3.id??"",status:c3.status,evidence:c3.evidence,severity:c3.severity})),verifyVerdictSchema=exports_external.object({wbs:exports_external.string().optional().default(""),verdict:verdictSchema,requirements:exports_external.array(coverageRowSchema).optional().default([]),acceptanceCriteria:exports_external.array(coverageRowSchema).optional().default([]),checks:exports_external.array(checkSchema).optional().default([]),source:exports_external.string().optional(),pipelineRunId:exports_external.string().optional(),recordedAt:exports_external.string().optional()});var field=(path8,label)=>({path:path8,label}),SOURCE_PROFILES={planning:{producerPackage:"spur",subsystem:"planning",remediationKind:"prefix-filter"},queue:{producerPackage:"@gobing-ai/ts-infra",subsystem:"job-queue",remediationKind:"prefix-filter"},scheduler:{producerPackage:"@gobing-ai/ts-infra",subsystem:"scheduler",remediationKind:"prefix-filter"},message:{producerPackage:"spur",subsystem:"coordination-messaging",remediationKind:"prefix-filter"},process:{producerPackage:"@gobing-ai/ts-runtime",subsystem:"process-executor",remediationKind:"prefix-filter"},workflow:{producerPackage:"@gobing-ai/ts-dual-workflow-engine",subsystem:"workflow",remediationKind:"workflow-trace"},rule:{producerPackage:"@gobing-ai/ts-rule-engine",subsystem:"rule-engine",remediationKind:"rule-trace"},agent:{producerPackage:"@gobing-ai/ts-ai-runner",subsystem:"agent-runner",remediationKind:"prefix-filter"},history:{producerPackage:"spur",subsystem:"history",remediationKind:"prefix-filter"},bus:{producerPackage:"@gobing-ai/ts-infra",subsystem:"event-bus",remediationKind:"prefix-filter"},api:{producerPackage:"spur",subsystem:"http-api",remediationKind:"prefix-filter"}};function at(data,path8){if(data===null)return;let current=data;for(let segment of path8.split(".")){if(current===null||typeof current!=="object"||Array.isArray(current))return;current=current[segment]}return current}function s2(data,...paths){for(let path8 of paths){let value=at(data,path8);if(typeof value==="string"&&value.length>0)return value}return}function n2(data,...paths){for(let path8 of paths){let value=at(data,path8);if(typeof value==="number"&&Number.isFinite(value))return String(value);if(typeof value==="boolean")return String(value)}return}function entityId(input){return s2(input.data,"entity.id")??input.correlation.entityId??""}function looksLikeOpaqueId(value){if(typeof value!=="string")return!1;let v=value.trim();if(v==="")return!1;if(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v))return!0;if(/^live[-_][a-z0-9._-]+$/i.test(v))return!0;if(/^(?:eventId|rowId|runId|executionId|actionId)$/i.test(v))return!0;return!1}function humanWorkflowTitle(input){let raw=s2(input.data,"workflowName")??s2(input.data,"workflow");if(raw!==void 0&&!looksLikeOpaqueId(raw))return(raw.split("/").pop()?.replace(/\.(?:ya?ml|json)$/i,"")??raw).replace(/[._-]+$/,"");return""}function humanStepLabel(data){let label=s2(data,"nodeLabel")??s2(data,"stepName")??s2(data,"step");if(label!==void 0&&!looksLikeOpaqueId(label))return label;let node=s2(data,"node");if(node!==void 0&&!looksLikeOpaqueId(node))return node;return}function derivedFrom(...paths){return{support:"derived",derive:({data})=>s2(data,...paths)}}function derivedFromValue(...paths){return{support:"derived",derive:({data})=>n2(data,...paths)??s2(data,...paths)}}var unsupported={support:"unsupported"};function baseEvent(name,source,renderer,payloadPolicy="metadata-only",tier="default",producer){return{name,source,tier,payloadPolicy,renderer,...producer!==void 0?{producer}:{}}}var BASE_CATALOG=[baseEvent("task.created","planning","planning"),baseEvent("task.updated","planning","planning"),baseEvent("task.transitioned","planning","planning"),baseEvent("feature.created","planning","planning"),baseEvent("feature.updated","planning","planning"),baseEvent("feature.transitioned","planning","planning"),baseEvent("queue.consumer.started","queue","queue"),baseEvent("queue.consumer.stopped","queue","queue"),baseEvent("queue.job.enqueued","queue","queue"),baseEvent("queue.job.started","queue","queue"),baseEvent("queue.job.completed","queue","queue"),baseEvent("queue.job.failed","queue","queue"),baseEvent("queue.job.retrying","queue","queue"),baseEvent("queue.stats","queue","queue"),baseEvent("scheduler.job.executed","scheduler","scheduler"),baseEvent("message.sent","message","message"),baseEvent("message.replied","message","message"),baseEvent("process.spawned","process","process"),baseEvent("process.exited","process","process"),baseEvent("process.stopped","process","process"),baseEvent("process.started","process","process"),baseEvent("agent.invoke.start","agent","agent"),baseEvent("agent.invoke.exit","agent","agent"),baseEvent("agent.invoke.escalated","agent","agent","metadata-only","default",{package:"spur",subsystem:"agent-runner"}),baseEvent("agent.invoke.exhausted","agent","agent","metadata-only","default",{package:"spur",subsystem:"agent-runner"}),baseEvent("agent.started","agent","agent"),baseEvent("agent.stopped","agent","agent"),baseEvent("agent.message.sent","agent","agent"),baseEvent("strategy.changed","agent","agent","metadata-only","default",{package:"spur",subsystem:"fleet-strategy"}),baseEvent("fleet.capacity.changed","agent","agent","metadata-only","default",{package:"spur",subsystem:"write-slot"}),baseEvent("task.assigned","planning","planning"),baseEvent("history.import.completed","history","history-import"),baseEvent("history.analyze.completed","history","history-analyze"),baseEvent("history.daily.failed","history","history-daily"),baseEvent("history.refresh.enqueued","history","history-refresh"),baseEvent("rule.run.start","rule","rule"),baseEvent("rule.eval.start","rule","rule"),baseEvent("rule.eval.done","rule","rule"),baseEvent("rule.eval.error","rule","rule"),baseEvent("rule.run.done","rule","rule"),baseEvent("workflow.run.started","workflow","workflow-run"),baseEvent("workflow.run.done","workflow","workflow-run"),baseEvent("workflow.run.failed","workflow","workflow-run"),baseEvent("workflow.run.finalized","workflow","workflow-run"),baseEvent("workflow.escalation.created","workflow","workflow-run","redacted"),baseEvent("workflow.escalation.projection_failed","workflow","workflow-run","metadata-only"),baseEvent("workflow.run.paused","workflow","workflow-run"),baseEvent("workflow.run.resumed","workflow","workflow-run"),baseEvent("workflow.run.reseeded","workflow","workflow-run"),baseEvent("workflow.node.enter","workflow","workflow-phase"),baseEvent("workflow.phase","workflow","workflow-phase"),baseEvent("workflow.node.transition","workflow","workflow-transition"),baseEvent("workflow.transition","workflow","workflow-transition"),baseEvent("workflow.transition.requested","workflow","workflow-transition","metadata-only","diagnostic"),baseEvent("workflow.transition.denied","workflow","workflow-transition","metadata-only","diagnostic"),baseEvent("workflow.action.started","workflow","workflow-action"),baseEvent("workflow.action.finished","workflow","workflow-action"),baseEvent("workflow.action.failed_continue","workflow","workflow-action"),baseEvent("workflow.guard.evaluated","workflow","workflow-guard","metadata-only","diagnostic"),baseEvent("workflow.hitl.ask","workflow","workflow-hitl","redacted"),baseEvent("workflow.hitl.response","workflow","workflow-hitl","redacted"),baseEvent("workflow.hitl.note","workflow","workflow-hitl","redacted"),baseEvent("workflow.custom","workflow","workflow-custom"),baseEvent("workflow.agent","workflow","workflow-agent","redacted","diagnostic"),baseEvent("workflow.steering","workflow","workflow-steering","redacted"),baseEvent("api.request.error","api","api"),baseEvent("bus.emit.done","bus","bus","metadata-only","diagnostic"),baseEvent("bus.emit.noop","bus","bus","metadata-only","diagnostic"),baseEvent("bus.handler.error","bus","bus","metadata-only","diagnostic"),baseEvent("bus.handler.async.enqueued","bus","bus","metadata-only","diagnostic")],SYSTEM_EVENT_PRESENTERS={"task.created":{description:"A task file was created with a new WBS id.",fields:[field("entity.kind","Entity kind"),field("entity.id","Entity")],summary:({data,correlation})=>`[task] ${entityId({data,correlation})} created`,outcome:unsupported},"task.updated":{description:"An existing task file was updated in place, naming the section that changed.",fields:[field("entity.kind","Entity kind"),field("entity.id","Entity"),field("field","Field"),field("data.mutation.name","Section"),field("data.after","After"),field("data.diff","Diff")],summary:({data,correlation})=>{let section=s2(data,"data.mutation.name"),id=entityId({data,correlation});return section!==void 0?`[task] ${section}`:`[task] ${id||"updated"}`},outcome:unsupported},"task.transitioned":{description:"A task moved between lifecycle states, naming both the previous and new status.",fields:[field("entity.kind","Entity kind"),field("entity.id","Entity"),field("from","From"),field("to","To")],summary:({data,correlation})=>{let id=entityId({data,correlation}),from=s2(data,"from"),to=s2(data,"to");return from!==void 0&&to!==void 0?`[task] ${id} : ${from} -> ${to}`:`[task] ${id} transitioned`},outcome:{support:"derived",derive:({data})=>s2(data,"to")}},"feature.created":{description:"A feature file was created with a new feature id.",fields:[field("entity.kind","Entity kind"),field("entity.id","Entity")],summary:({data,correlation})=>`[feature] ${entityId({data,correlation})} created`,outcome:unsupported},"feature.updated":{description:"An existing feature file was updated in place, naming the section that changed.",fields:[field("entity.kind","Entity kind"),field("entity.id","Entity"),field("field","Field"),field("data.mutation.name","Section"),field("data.after","After"),field("data.diff","Diff")],summary:({data,correlation})=>{let section=s2(data,"data.mutation.name"),id=entityId({data,correlation});return section!==void 0?`[feature] ${section}`:`[feature] ${id||"updated"}`},outcome:unsupported},"feature.transitioned":{description:"A feature moved between lifecycle states, naming both the previous and new status.",fields:[field("entity.kind","Entity kind"),field("entity.id","Entity"),field("from","From"),field("to","To")],summary:({data,correlation})=>{let id=entityId({data,correlation}),from=s2(data,"from"),to=s2(data,"to");return from!==void 0&&to!==void 0?`[feature] ${id} : ${from} -> ${to}`:`[feature] ${id} transitioned`},outcome:{support:"derived",derive:({data})=>s2(data,"to")}},"queue.consumer.started":{description:"The configured queue consumer began polling its named queue.",fields:[field("queueName","Queue"),field("startedAt","Started"),field("pollInterval","Poll interval"),field("batchSize","Batch size"),field("maxConcurrency","Max concurrency"),field("visibilityTimeout","Visibility timeout")],summary:({data})=>{let name=s2(data,"queueName");return name!==void 0?`[queue] ${name} : consumer started`:"[queue] consumer started"},outcome:{support:"derived",derive:({data})=>at(data,"startedAt")!==void 0?"running":void 0}},"queue.consumer.stopped":{description:"The queue consumer stopped, reporting whether it drained in-flight work.",fields:[field("queueName","Queue"),field("stoppedAt","Stopped"),field("drainTimeoutMs","Drain timeout"),field("inFlightAtStop","In flight"),field("drained","Drained")],summary:({data})=>{let name=s2(data,"queueName");return name!==void 0?`[queue] ${name} : consumer stopped`:"[queue] consumer stopped"},outcome:{support:"derived",derive:({data})=>{let drained=at(data,"drained");if(drained===!0)return"drained";if(drained===!1)return"timeout";return}}},"queue.job.enqueued":{description:"A job was enqueued onto the job queue for later processing.",fields:[field("jobId","Job"),field("type","Type"),field("nextRetryAt","Next retry")],summary:({data})=>{let type=s2(data,"type"),jobId=s2(data,"jobId");return type!==void 0&&jobId!==void 0?`[queue] ${type} · job ${jobId} enqueued`:"[queue] job enqueued"},outcome:unsupported},"queue.job.started":{description:"A queued job handler began executing (job identity and phase anchor).",fields:[field("jobId","Job"),field("type","Type"),field("name","Name")],summary:({data})=>{let type=s2(data,"type"),jobId=s2(data,"jobId");return type!==void 0&&jobId!==void 0?`[queue] ${type} · job ${jobId} started`:"[queue] job started"},outcome:unsupported},"queue.job.completed":{description:"A queued job finished successfully with its attempt and duration.",fields:[field("jobId","Job"),field("type","Type"),field("attempt","Attempt"),field("durationMs","Duration (ms)")],summary:({data})=>{let type=s2(data,"type"),jobId=s2(data,"jobId");return type!==void 0&&jobId!==void 0?`[queue] ${type} · job ${jobId} completed`:"[queue] job completed"},outcome:unsupported},"queue.job.failed":{description:"A queued job exhausted its attempts and failed with an error.",fields:[field("jobId","Job"),field("type","Type"),field("attempt","Attempt"),field("maxRetries","Max retries"),field("durationMs","Duration (ms)"),field("error","Error")],summary:({data})=>{let type=s2(data,"type"),jobId=s2(data,"jobId");return type!==void 0&&jobId!==void 0?`[queue] ${type} · job ${jobId} failed`:"[queue] job failed"},outcome:derivedFrom("error")},"queue.job.retrying":{description:"A queued job failed once and is scheduled for another attempt.",fields:[field("jobId","Job"),field("type","Type"),field("attempt","Attempt"),field("maxRetries","Max retries"),field("nextRetryAt","Next retry"),field("error","Error")],summary:({data})=>{let type=s2(data,"type"),jobId=s2(data,"jobId");return type!==void 0&&jobId!==void 0?`[queue] ${type} · job ${jobId} retrying`:"[queue] job retrying"},outcome:{support:"derived",derive:({data})=>{let attempt=at(data,"attempt"),max=at(data,"maxRetries");if(typeof attempt==="number"&&typeof max==="number"&&Number.isFinite(attempt)&&Number.isFinite(max))return`retrying ${attempt}/${max}`;return s2(data,"error")}}},"queue.stats":{description:"Periodic job-queue statistics across ready, running, completed, and failed counts.",fields:[field("ready","Ready"),field("running","Running"),field("completed","Completed"),field("failed","Failed")],summary:()=>"[queue] stats",outcome:unsupported},"scheduler.job.executed":{description:"A scheduler job ran to completion or failed, with its duration.",fields:[field("name","Job"),field("action","Action"),field("durationMs","Duration (ms)"),field("error","Error")],summary:({data})=>{let name=s2(data,"name");return name!==void 0?`[scheduler] ${name}`:"[scheduler] job executed"},outcome:{support:"derived",derive:({data})=>s2(data,"error")??(at(data,"error")===null?"completed":void 0)}},"message.sent":{description:"A team message was sent from one member to another.",fields:[field("msgId","Message"),field("fromId","From"),field("toId","To"),field("threadId","Thread")],summary:({data})=>{let from=s2(data,"fromId"),to=s2(data,"toId");return from!==void 0&&to!==void 0?`[message] ${from} -> ${to}`:"[message] sent"},outcome:unsupported},"message.replied":{description:"A member replied to an existing message thread.",fields:[field("msgId","Message"),field("fromId","From"),field("toId","To"),field("threadId","Thread")],summary:({data})=>{let from=s2(data,"fromId"),thread=s2(data,"threadId");return from!==void 0&&thread!==void 0?`[message] ${from} replied in ${thread}`:"[message] replied"},outcome:unsupported},"process.spawned":{description:"A supervised process was spawned with a new pid.",fields:[field("label","Label"),field("pid","PID"),field("agentId","Agent")],summary:({data})=>{let label=s2(data,"label")??n2(data,"pid");return label!==void 0?`[process] ${label} spawned`:"[process] spawned"},outcome:unsupported},"process.exited":{description:"A supervised process exited, carrying its exit code, signal, or failure reason.",fields:[field("label","Label"),field("pid","PID"),field("exitCode","Exit code"),field("signal","Signal"),field("durationMs","Duration (ms)"),field("reason","Reason")],summary:({data})=>{let label=s2(data,"label")??n2(data,"pid");return label!==void 0?`[process] ${label} exited`:"[process] exited"},outcome:{support:"derived",derive:({data})=>{let reason=s2(data,"reason");if(reason!==void 0)return reason;let signal=s2(data,"signal");if(signal!==void 0)return`signal ${signal}`;let code=at(data,"exitCode");if(typeof code==="number"&&Number.isFinite(code))return code===0?"ok":`exit ${code}`;return}}},"process.stopped":{description:"A supervised process was stopped, naming the stopping reason.",fields:[field("label","Label"),field("pid","PID"),field("signal","Signal"),field("reason","Reason")],summary:({data})=>{let label=s2(data,"label")??n2(data,"pid");return label!==void 0?`[process] ${label} stopped`:"[process] stopped"},outcome:derivedFrom("reason")},"process.started":{description:"A process executor started a process with a new pid.",fields:[field("label","Label"),field("pid","PID")],summary:({data})=>{let label=s2(data,"label")??n2(data,"pid");return label!==void 0?`[process] ${label} started`:"[process] started"},outcome:unsupported},"agent.invoke.start":{description:"An agent invocation began, naming the agent and its operation.",fields:[field("agent","Agent"),field("operation","Operation"),field("routing.role","Role"),field("routing.tier","Tier"),field("routing.executor","Executor"),field("routing.source","Selection source")],summary:({data})=>{let agent=s2(data,"agent"),operation=s2(data,"operation");return agent!==void 0&&operation!==void 0?`[agent] ${agent} · ${operation}`:"[agent] invocation started"},outcome:unsupported},"agent.invoke.exit":{description:"An agent invocation exited, reporting its exit code or signal.",fields:[field("agent","Agent"),field("operation","Operation"),field("exitCode","Exit code"),field("signal","Signal"),field("routing.role","Role"),field("routing.tier","Tier"),field("routing.executor","Executor"),field("routing.source","Selection source")],summary:({data})=>{let agent=s2(data,"agent"),operation=s2(data,"operation");return agent!==void 0&&operation!==void 0?`[agent] ${agent} · ${operation} exited`:"[agent] invocation exited"},outcome:{support:"derived",derive:({data})=>{let signal=s2(data,"signal");if(signal!==void 0)return`signal ${signal}`;let code=at(data,"exitCode");if(typeof code==="number"&&Number.isFinite(code))return code===0?"ok":`exit ${code}`;return}}},"agent.invoke.escalated":{description:"An agent invocation escalated from one executor tier to another.",fields:[field("fromExecutor","From executor"),field("fromTier","From tier"),field("toExecutor","To executor"),field("toTier","To tier"),field("trigger","Trigger")],summary:({data})=>{let from=s2(data,"fromExecutor"),to=s2(data,"toExecutor");return from!==void 0&&to!==void 0?`[agent] ${from} -> ${to}`:"[agent] escalation"},outcome:{support:"derived",derive:({data})=>s2(data,"toTier")??s2(data,"trigger")}},"agent.invoke.exhausted":{description:"An agent invocation exhausted every eligible executor tier without success.",fields:[field("stage","Stage"),field("attempts","Attempts"),field("fromTier","From tier"),field("toTier","To tier"),field("fromExecutor","From executor"),field("toExecutor","To executor")],summary:({data})=>{let stage=s2(data,"stage");return stage!==void 0?`[agent] ${stage} escalation exhausted`:"[agent] escalation exhausted"},outcome:derivedFromValue("attempts")},"agent.started":{description:"An agent started, carrying its id and type.",fields:[field("agentId","Agent"),field("agentType","Agent type"),field("pid","PID")],summary:({data})=>{let id=s2(data,"agentId");return id!==void 0?`[agent] ${id} started`:"[agent] started"},outcome:unsupported},"agent.stopped":{description:"An agent stopped, reporting its exit code.",fields:[field("agentId","Agent"),field("exitCode","Exit code")],summary:({data})=>{let id=s2(data,"agentId");return id!==void 0?`[agent] ${id} stopped`:"[agent] stopped"},outcome:derivedFromValue("exitCode")},"strategy.changed":{description:"A project strategy changed (0838), minting a new strategy version for dispatch fencing.",fields:[field("data.projectPath","Project"),field("data.strategy","Strategy"),field("data.version","Version")],summary:({data})=>{let strategy=s2(data,"data.strategy"),version3=s2(data,"data.version");return strategy!==void 0?`[strategy] ${strategy}${version3!==void 0?` (v${version3})`:""}`:"[strategy] changed"},outcome:unsupported},"fleet.capacity.changed":{description:"The project write slot was claimed or released (0837), changing dispatch capacity.",fields:[field("data.projectPath","Project"),field("data.change","Change"),field("data.holderId","Holder")],summary:({data})=>{let change=s2(data,"data.change"),holder=s2(data,"data.holderId");return`[fleet] write slot ${change??"changed"}${holder!==void 0?` — ${holder}`:""}`},outcome:unsupported},"agent.message.sent":{description:"A message was sent to an agent, reporting delivery success.",fields:[field("agentId","Agent"),field("ok","Delivered")],summary:({data})=>{let id=s2(data,"agentId");return id!==void 0?`[agent] message -> ${id}`:"[agent] message sent"},outcome:derivedFromValue("ok")},"task.assigned":{description:"A task was assigned to an agent, naming the agent when resolved.",fields:[field("memberId","Member"),field("agentType","Agent type"),field("taskId","Task"),field("outcome","Outcome")],summary:({data})=>{let member=s2(data,"memberId"),task=s2(data,"taskId");return task!==void 0&&member!==void 0?`[task] ${task} assigned to ${member}`:"[task] assignment recorded"},outcome:derivedFrom("outcome")},"history.import.completed":{description:"A history import finished, reporting files, messages, and exit code.",fields:[field("source","Source"),field("sources","Sources"),field("files","Files"),field("messages","Messages"),field("durationMs","Duration (ms)"),field("exitCode","Exit code"),field("artifactPath","Artifact"),field("cwd","Project root")],retain:[field("trigger","Refresh trigger"),field("windowStart","Refresh window start"),field("windowEnd","Refresh window end"),field("importMode","Import mode"),field("coverage","Refresh coverage")],summary:({data})=>{let source=s2(data,"source")??s2(data,"sources");return source!==void 0?`[history] import · ${source}`:"[history] import completed"},outcome:derivedFromValue("exitCode")},"history.analyze.completed":{description:"A history analyze pass finished, reporting sources, duration, and exit code.",fields:[field("source","Source"),field("sources","Sources"),field("durationMs","Duration (ms)"),field("exitCode","Exit code"),field("artifactPath","Artifact")],retain:[field("trigger","Refresh trigger"),field("windowStart","Refresh window start"),field("windowEnd","Refresh window end"),field("importMode","Import mode")],summary:({data})=>{let source=s2(data,"source")??s2(data,"sources");return source!==void 0?`[history] analyze · ${source}`:"[history] analyze completed"},outcome:derivedFromValue("exitCode")},"history.daily.failed":{description:"The daily history refresh failed, carrying the detail, reason, and exit code.",fields:[field("source","Source"),field("sources","Sources"),field("detail","Detail"),field("reason","Reason"),field("exitCode","Exit code")],retain:[field("trigger","Refresh trigger"),field("windowStart","Refresh window start"),field("windowEnd","Refresh window end"),field("importMode","Import mode")],summary:()=>"[history] daily failed",outcome:{support:"derived",derive:({data})=>s2(data,"reason")??s2(data,"detail")??n2(data,"exitCode")}},"history.refresh.enqueued":{description:"A completion-triggered history refresh was enqueued, naming its window.",fields:[field("trigger","Trigger"),field("triggerId","Trigger id"),field("jobId","Queue job"),field("windowStart","Window start"),field("windowEnd","Window end"),field("coalesced","Coalesced"),field("outcome","Outcome")],summary:({data})=>{let start=s2(data,"windowStart"),end=s2(data,"windowEnd");return start!==void 0&&end!==void 0?`[history] refresh · ${start} -> ${end}`:"[history] refresh enqueued"},outcome:{support:"derived",derive:({data})=>{let status=s2(data,"outcome");return status!==void 0&&status!=="enqueued"?status:void 0}}},"rule.run.start":{description:"A rule run began with the rule count it will evaluate.",fields:[field("runId","Run"),field("ruleCount","Rules"),field("evaluator","Evaluator")],summary:({data,correlation})=>{let run=s2(data,"runId")??correlation.runId;return run!==void 0?`[rule] run ${run} started`:"[rule] run started"},outcome:unsupported},"rule.eval.start":{description:"A single rule began evaluating.",fields:[field("runId","Run"),field("ruleId","Rule"),field("evaluator","Evaluator"),field("index","Index"),field("total","Total")],summary:({data})=>{let id=s2(data,"ruleId");return id!==void 0?`[rule] ${id} evaluating`:"[rule] evaluating"},outcome:unsupported},"rule.eval.done":{description:"A rule finished evaluating, reporting its findings count and severity.",fields:[field("runId","Run"),field("ruleId","Rule"),field("evaluator","Evaluator"),field("findings","Findings"),field("durationMs","Duration (ms)"),field("severity","Severity")],summary:({data})=>{let id=s2(data,"ruleId");return id!==void 0?`[rule] ${id} evaluated`:"[rule] evaluated"},outcome:derivedFromValue("findings")},"rule.eval.error":{description:"A rule evaluation failed with an error.",fields:[field("runId","Run"),field("ruleId","Rule"),field("evaluator","Evaluator"),field("error","Error")],summary:({data})=>{let id=s2(data,"ruleId");return id!==void 0?`[rule] ${id} error`:"[rule] error"},outcome:derivedFrom("error")},"rule.run.done":{description:"A rule run finished, reporting findings and whether it stopped early.",fields:[field("runId","Run"),field("findings","Findings"),field("durationMs","Duration (ms)"),field("stoppedEarly","Stopped early"),field("severity","Severity")],summary:({data,correlation})=>{let run=s2(data,"runId")??correlation.runId;return run!==void 0?`[rule] run ${run} done`:"[rule] run done"},outcome:{support:"derived",derive:({data})=>n2(data,"findings")??s2(data,"stoppedEarly")}},"workflow.run.started":{description:"A workflow run started, naming the workflow definition.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("mode","Mode"),field("dryRun","Dry run")],summary:(input)=>{let name=humanWorkflowTitle(input);return name!==""?`[workflow] ${name} started`:"[workflow] started"},outcome:unsupported},"workflow.run.done":{description:"A workflow run reached a done terminal state.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("finalState","Final state"),field("transitionsTaken","Transitions")],summary:(input)=>{let name=humanWorkflowTitle(input);return name!==""?`[workflow] ${name} done`:"[workflow] done"},outcome:derivedFrom("finalState")},"workflow.run.failed":{description:"A workflow run failed with a terminal failure reason.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("finalState","Final state"),field("reason","Reason")],summary:(input)=>{let name=humanWorkflowTitle(input);return name!==""?`[workflow] ${name} failed`:"[workflow] failed"},outcome:derivedFrom("reason")},"workflow.run.finalized":{description:"A workflow run settled on a terminal status.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("status","Status")],summary:(input)=>{let name=humanWorkflowTitle(input);return name!==""?`[workflow] ${name} finalized`:"[workflow] finalized"},outcome:derivedFrom("status")},"workflow.escalation.created":{description:"A canonical escalation packet was projected from existing run evidence.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("fingerprint","Fingerprint"),field("artifactPath","Artifact"),field("decision","Decision")],summary:(input)=>{let name=humanWorkflowTitle(input),decision=typeof at(input.data,"decision")==="string"?` — ${String(at(input.data,"decision"))}`:"";return name!==""?`[workflow] escalation packet created (${name}${decision})`:`[workflow] escalation packet created${decision}`},outcome:derivedFrom("decision")},"workflow.escalation.projection_failed":{description:"Escalation packet projection failed; the original failure is preserved untouched.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("error","Error")],summary:()=>"[workflow] escalation packet projection failed",outcome:derivedFrom("error")},"workflow.run.paused":{description:"A workflow run paused at a step, naming the step when available.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("nodeLabel","Step"),field("node","Node"),field("transitionsTaken","Transitions")],summary:(input)=>{let name=humanWorkflowTitle(input),step=humanStepLabel(input.data),parts=[name,step].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")} paused`:"[workflow] paused"},outcome:unsupported},"workflow.run.resumed":{description:"A paused workflow run resumed at a step, naming the step when available.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("nodeLabel","Step"),field("node","Node")],summary:(input)=>{let name=humanWorkflowTitle(input),step=humanStepLabel(input.data),parts=[name,step].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")} resumed`:"[workflow] resumed"},outcome:unsupported},"workflow.run.reseeded":{description:"A workflow run was reseeded to a new state, naming the transition.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("fromState","From"),field("toState","To")],summary:(input)=>{let name=humanWorkflowTitle(input),from=s2(input.data,"fromState"),to=s2(input.data,"toState");if(from!==void 0&&to!==void 0)return name!==""?`[workflow] ${name} : ${from} -> ${to}`:`[workflow] : ${from} -> ${to}`;return name!==""?`[workflow] ${name} reseeded`:"[workflow] reseeded"},outcome:derivedFrom("toState")},"workflow.node.enter":{description:"The engine entered a workflow node, naming the step when available.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("nodeLabel","Step"),field("node","Node"),field("transitionsTaken","Transitions")],summary:(input)=>{let name=humanWorkflowTitle(input),step=humanStepLabel(input.data),parts=[name,step].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")}`:"[workflow] node entered"},outcome:unsupported},"workflow.phase":{description:"A workflow phase changed status, naming the phase.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("phase","Phase"),field("status","Status")],summary:(input)=>{let name=humanWorkflowTitle(input),phase=s2(input.data,"phase"),parts=[name,phase].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")}`:"[workflow] phase"},outcome:derivedFrom("status")},"workflow.node.transition":{description:"A workflow transitioned between nodes, naming the from and to states.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("from","From"),field("to","To"),field("trigger","Trigger")],summary:(input)=>{let name=humanWorkflowTitle(input),from=s2(input.data,"from"),to=s2(input.data,"to");if(from!==void 0&&to!==void 0)return name!==""?`[workflow] ${name} : ${from} -> ${to}`:`[workflow] : ${from} -> ${to}`;return name!==""?`[workflow] ${name} transitioned`:"[workflow] transitioned"},outcome:derivedFrom("to")},"workflow.transition":{description:"A workflow state transition was committed.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("from","From"),field("to","To"),field("trigger","Trigger")],summary:(input)=>{let name=humanWorkflowTitle(input),from=s2(input.data,"from"),to=s2(input.data,"to");if(from!==void 0&&to!==void 0)return name!==""?`[workflow] ${name} : ${from} -> ${to}`:`[workflow] : ${from} -> ${to}`;return name!==""?`[workflow] ${name} transitioned`:"[workflow] transitioned"},outcome:derivedFrom("to")},"workflow.transition.requested":{description:"A workflow transition was requested and accepted for evaluation.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("from","From"),field("to","To"),field("trigger","Trigger")],summary:(input)=>{let name=humanWorkflowTitle(input),from=s2(input.data,"from"),to=s2(input.data,"to");if(from!==void 0&&to!==void 0)return name!==""?`[workflow] ${name} requested ${from} -> ${to}`:`[workflow] requested ${from} -> ${to}`;return name!==""?`[workflow] ${name} transition requested`:"[workflow] transition requested"},outcome:unsupported},"workflow.transition.denied":{description:"A workflow transition was denied with a reason.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("from","From"),field("to","To"),field("reason","Reason")],summary:(input)=>{let name=humanWorkflowTitle(input),from=s2(input.data,"from"),to=s2(input.data,"to");if(from!==void 0&&to!==void 0)return name!==""?`[workflow] ${name} denied ${from} -> ${to}`:`[workflow] denied ${from} -> ${to}`;return name!==""?`[workflow] ${name} transition denied`:"[workflow] transition denied"},outcome:derivedFrom("reason")},"workflow.action.started":{description:"A workflow action began executing, naming the step and kind.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("nodeLabel","Step"),field("node","Node"),field("actionId","Action"),field("kind","Kind")],retain:[field("metadata.agent","Agent"),field("metadata.role","Role"),field("routing.executor","Executor")],summary:(input)=>{let name=humanWorkflowTitle(input),step=humanStepLabel(input.data),parts=[name,step].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")} started`:"[workflow] action started"},outcome:unsupported},"workflow.action.finished":{description:"A workflow action finished, reporting its status and success.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("nodeLabel","Step"),field("node","Node"),field("actionId","Action"),field("kind","Kind"),field("durationMs","Duration (ms)"),field("status","Status")],retain:[field("metadata.agent","Agent"),field("metadata.role","Role"),field("routing.executor","Executor")],summary:(input)=>{let name=humanWorkflowTitle(input),step=humanStepLabel(input.data),parts=[name,step].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")} finished`:"[workflow] action finished"},outcome:{support:"derived",derive:({data})=>s2(data,"status")??n2(data,"ok")}},"workflow.action.failed_continue":{description:"A workflow action failed but the workflow continued, carrying the error.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("nodeLabel","Step"),field("node","Node"),field("transitionsTaken","Transitions"),field("error","Error")],retain:[field("metadata.agent","Agent"),field("metadata.role","Role"),field("routing.executor","Executor")],summary:(input)=>{let name=humanWorkflowTitle(input),step=humanStepLabel(input.data),parts=[name,step].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")} failed; continuing`:"[workflow] action failed; continuing"},outcome:derivedFrom("error")},"workflow.guard.evaluated":{description:"A workflow guard was evaluated for a transition, reporting whether it passed.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("from","From"),field("to","To"),field("kind","Kind"),field("passed","Passed")],summary:(input)=>{let name=humanWorkflowTitle(input),from=s2(input.data,"from"),to=s2(input.data,"to");if(from!==void 0&&to!==void 0)return name!==""?`[workflow] ${name} guard ${from} -> ${to}`:`[workflow] guard ${from} -> ${to}`;return name!==""?`[workflow] ${name} guard evaluated`:"[workflow] guard evaluated"},outcome:derivedFromValue("passed")},"workflow.hitl.ask":{description:"A workflow paused for human input, naming the step and kind.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("nodeLabel","Step"),field("node","Node"),field("kind","Kind")],summary:(input)=>{let name=humanWorkflowTitle(input),step=humanStepLabel(input.data),parts=[name,step].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")} awaiting input`:"[workflow] awaiting input"},outcome:unsupported},"workflow.hitl.response":{description:"Human input was received for a paused workflow step.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("nodeLabel","Step"),field("node","Node"),field("ok","Accepted")],summary:(input)=>{let name=humanWorkflowTitle(input),step=humanStepLabel(input.data),parts=[name,step].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")} input received`:"[workflow] input received"},outcome:derivedFromValue("ok")},"workflow.hitl.note":{description:"A note was recorded on a paused workflow step.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("nodeLabel","Step"),field("node","Node")],summary:(input)=>{let name=humanWorkflowTitle(input),step=humanStepLabel(input.data),parts=[name,step].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")} note`:"[workflow] note"},outcome:unsupported},"workflow.custom":{description:"A custom workflow event was emitted, naming the custom event.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("name","Event")],summary:(input)=>{let name=humanWorkflowTitle(input),custom3=s2(input.data,"name"),parts=[name,custom3].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")}`:"[workflow] custom"},outcome:unsupported},"workflow.agent":{description:"A workflow-dispatched agent execution lifecycle event, discriminated by kind.",fields:[field("runId","Run"),field("executionId","Execution"),field("actionId","Action"),field("kind","Kind"),field("agent","Agent"),field("model","Model")],retain:[field("metadata.agent","Agent"),field("metadata.role","Role"),field("routing.executor","Executor")],summary:(input)=>{let name=humanWorkflowTitle(input),kind=s2(input.data,"kind"),parts=[name,kind!==void 0?`agent ${kind}`:"agent"].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")}`:"[workflow] agent"},outcome:{support:"derived",derive:({data})=>s2(data,"kind")==="finished"?s2(data,"outcome"):void 0}},"workflow.steering":{description:"A steering command was acknowledged for a workflow action boundary.",fields:[field("runId","Run"),field("actionId","Action"),field("operation","Operation"),field("actor","Actor"),field("accepted","Accepted"),field("state","State"),field("reason","Reason")],summary:(input)=>{let name=humanWorkflowTitle(input),operation=s2(input.data,"operation"),parts=[name,operation!==void 0?`steering ${operation}`:"steering"].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")}`:"[workflow] steering"},outcome:{support:"derived",derive:({data})=>{let reason=s2(data,"reason");if(reason!==void 0)return reason;let accepted=at(data,"accepted");if(accepted===!0)return"accepted";if(accepted===!1)return"rejected";return s2(data,"state")}}},"api.request.error":{description:"An API request failed, naming the method, path, and status or error code.",fields:[field("method","Method"),field("path","Path"),field("status","Status"),field("code","Code"),field("requestId","Request"),field("error","Error")],summary:({data})=>{let method=s2(data,"method"),path8=s2(data,"path");return method!==void 0&&path8!==void 0?`[api] ${method} ${path8}`:"[api] request error"},outcome:{support:"derived",derive:({data})=>s2(data,"error")??s2(data,"code")??n2(data,"status")}},"bus.emit.done":{description:"An event was emitted to its handlers on the event bus.",fields:[field("event","Event"),field("handlers","Handlers"),field("durationMs","Duration (ms)")],summary:({data})=>{let event=s2(data,"event");return event!==void 0?`[bus] ${event} emitted`:"[bus] event emitted"},outcome:derivedFromValue("handlers")},"bus.emit.noop":{description:"An event was emitted but had no registered handlers.",fields:[field("event","Event"),field("handlers","Handlers"),field("durationMs","Duration (ms)")],summary:({data})=>{let event=s2(data,"event");return event!==void 0?`[bus] ${event} had no handlers`:"[bus] event had no handlers"},outcome:derivedFromValue("handlers")},"bus.handler.error":{description:"An event-bus handler threw an error while processing an event.",fields:[field("event","Event"),field("handlers","Handlers"),field("durationMs","Duration (ms)"),field("error","Error")],summary:({data})=>{let event=s2(data,"event");return event!==void 0?`[bus] ${event} handler error`:"[bus] handler error"},outcome:derivedFrom("error")},"bus.handler.async.enqueued":{description:"An event-bus handler was enqueued for asynchronous processing.",fields:[field("event","Event"),field("handlers","Handlers")],summary:({data})=>{let event=s2(data,"event");return event!==void 0?`[bus] ${event} handlers enqueued`:"[bus] handlers enqueued"},outcome:derivedFromValue("handlers")}};function inferSeverity(name){if(/(?:failed|error|denied)$/.test(name))return"error";if(/(?:retrying|paused|dropped)$/.test(name))return"warning";return"info"}function resolveCatalogEntry(base2){let profile=SOURCE_PROFILES[base2.source],presenter=SYSTEM_EVENT_PRESENTERS[base2.name];return{name:base2.name,prefix:base2.name.split(".")[0]??base2.name,source:base2.source,tier:base2.tier,persisted:!0,streamed:!0,payloadPolicy:base2.payloadPolicy,renderer:base2.renderer,...profile,...base2.producer!==void 0?{producerPackage:base2.producer.package,subsystem:base2.producer.subsystem}:{},severity:inferSeverity(base2.name),description:presenter.description,metadataFields:presenter.retain?[...presenter.fields,...presenter.retain.filter((r)=>!presenter.fields.some((f)=>f.path===r.path))]:presenter.fields,remediationKind:profile.remediationKind}}var SYSTEM_EVENT_CATALOG=BASE_CATALOG.map(resolveCatalogEntry),SYSTEM_EVENT_NAMES=SYSTEM_EVENT_CATALOG.map((entry)=>entry.name),SYSTEM_EVENT_PERSISTED_NAMES=SYSTEM_EVENT_CATALOG.filter((entry)=>entry.tier==="default").map((entry)=>entry.name),SYSTEM_EVENT_STREAMED_NAMES=SYSTEM_EVENT_CATALOG.filter((entry)=>entry.tier==="default").map((entry)=>entry.name),SYSTEM_EVENT_PREFIXES=Array.from(new Set(SYSTEM_EVENT_CATALOG.map((entry)=>entry.prefix))),SYSTEM_EVENT_DEFAULT_NAMES=SYSTEM_EVENT_CATALOG.filter((entry)=>entry.tier==="default").map((entry)=>entry.name),SYSTEM_EVENT_DIAGNOSTIC_NAMES=SYSTEM_EVENT_CATALOG.filter((entry)=>entry.tier==="diagnostic").map((entry)=>entry.name);var SYSTEM_EVENT_CATALOG_METADATA=SYSTEM_EVENT_CATALOG.map(({name,prefix,source,tier,renderer,producerPackage,subsystem,severity,description,metadataFields,remediationKind})=>({name,prefix,source,tier,renderer,producerPackage,subsystem,severity,description,metadataFields,remediationKind}));function workflowVersionLiteral(workflow){return typeof workflow.version==="string"&&workflow.version!==""?workflow.version:null}var{mkdirSync:mkdirSync2,writeFileSync:writeFileSync3}=await import("node:fs"),{readFile}=await import("node:fs/promises");function parseIdentityMetadata(raw){if(raw.trim()==="")return{};try{let parsed=JSON.parse(raw);if(parsed===null||typeof parsed!=="object"||Array.isArray(parsed))return null;return parsed}catch{return null}}async function openInlineRunProjectDb(workdir){let url2=join6(resolve4(workdir),".spur","spur.db");mkdirSync2(join6(url2,".."),{recursive:!0});let adapter=await createMigratedDb({url:url2});return{adapter,close:()=>adapter.close()}}var SAFE_RUN_ID_RE=/^[A-Za-z0-9][A-Za-z0-9._-]*$/;async function persistWorktreeRuns(input){let fromDir=resolve4(input.fromWorkdir),toDir=resolve4(input.toWorkdir),source=await openInlineRunProjectDb(fromDir);try{for(let id of await listRunIds(source.adapter))if(!SAFE_RUN_ID_RE.test(id))throw new InvalidWorkflowRunIdError(id);let target=await openInlineRunProjectDb(toDir);try{let{persistedIds,skipped}=await transferRunTables(source.adapter,target.adapter),recordSkips=[];if(persistedIds.length>0){let fromRunDir=join6(fromDir,".spur","run"),toRunDir=join6(toDir,".spur","run");mkdirSync2(toRunDir,{recursive:!0});for(let id of persistedIds)for(let fileName of[`${id}.md`,`${id}.state.json`]){let sourceBytes=await readFile(join6(fromRunDir,fileName)),targetPath=join6(toRunDir,fileName),existing;try{existing=await readFile(targetPath)}catch{existing=void 0}if(existing!==void 0){if(existing.equals(sourceBytes))continue;recordSkips.push({id,reason:`record-conflict:${fileName}`});continue}writeFileSync3(targetPath,sourceBytes)}}return{ok:!0,persisted:persistedIds.length,skipped:[...skipped,...recordSkips]}}finally{target.close()}}finally{source.close()}}async function createOrAttachInlineRun(input){let runId=input.runId.trim();if(runId==="")return{ok:!1,error:"inline run setup requires a non-empty runId (driver Run setup step 2)"};let workdir=resolve4(input.workdir),resolved;try{let projection=input.inventory===void 0?void 0:parseWorkflowInventory(input.inventory);if(projection&&!projection.ok)return projection;let inventory=projection?.ok?projection.inventory:void 0;if(inventory&&(!inventory.source||inventory.kind!=="state-machine"))return{ok:!1,error:"inline run setup requires a state-machine inventory with definition source"};if(resolved=await resolveWorkflowDefinition(workdir,inventory?.source?.path??input.file,{validateSchema:!0,...input.embeddedSchemas!==void 0?{embeddedSchemas:input.embeddedSchemas}:{},...!inventory?{registered:input.registered}:{}}),(resolved.workflow.kind??"state-machine")!=="state-machine")return{ok:!1,error:"inline run setup requires a state-machine definition"};if(inventory?.source){let identity5=assertInventoryIdentity(inventory,resolved.digest);if(!identity5.ok)return identity5;if(inventory.name!==resolved.workflow.name)return{ok:!1,error:"inline run setup: inventory workflow name does not match its definition"};resolved={...resolved,layer:inventory.source.layer}}}catch(error51){return{ok:!1,error:`inline run setup could not resolve the workflow definition: ${error51.message}`}}let digest=resolved.digest,version3=workflowVersionLiteral(resolved.workflow),source={path:resolved.path,layer:resolved.layer,workdir},db2=await input.getDb(),existing=await new RunDao(db2).traceRowById(runId);if(existing!==void 0){let metadata=parseIdentityMetadata(existing.metadata_json);if(metadata===null)return{ok:!1,error:`inline run setup refuses run ${runId}: its existing row has malformed metadata_json, `+"so its identity cannot be verified — delete the stale run row or allocate a new run id"};let resumeDigest=typeof metadata.resumeDefinitionDigest==="string"?metadata.resumeDefinitionDigest:void 0,launchDigest=typeof metadata.definitionDigest==="string"?metadata.definitionDigest:void 0,effectiveDigest=resumeDigest??launchDigest;if(effectiveDigest===void 0)return{ok:!1,error:`inline run setup refuses run ${runId}: its existing row carries no definition digest `+"(pre-identity legacy row) — allocate a new run id instead of attaching an unverifiable identity"};if(effectiveDigest!==digest)return{ok:!1,error:`inline run setup refuses run ${runId}: the resolved definition digest (${digest}) does not match the run's recorded ${resumeDigest!==void 0?"resume":""} digest (${effectiveDigest}) — `+"a changed definition must resume through the explicit resume rules, not silently re-attach"};if(existing.workflow_name!==resolved.workflow.name)return{ok:!1,error:`inline run setup refuses run ${runId}: the run row records workflow "${existing.workflow_name}" but the resolved definition is "${resolved.workflow.name}" — conflicting run identity`};if(typeof metadata.definitionSource!=="object"||metadata.definitionSource===null||Array.isArray(metadata.definitionSource))return{ok:!1,error:`inline run setup refuses run ${runId}: its existing row carries no definition source `+"(path/layer/workdir) — allocate a new run id instead of attaching an unverifiable launch source"};let existingSource=metadata.definitionSource;if(!(typeof existingSource.path==="string"&&resolve4(existingSource.path)===resolved.path&&normalizePersistedWorkflowLayer(existingSource.layer)===resolved.layer&&typeof existingSource.workdir==="string"&&resolve4(existingSource.workdir)===workdir))return{ok:!1,error:`inline run setup refuses run ${runId}: the recorded definition source (${JSON.stringify(existingSource)}) does not match the resolved launch source (${JSON.stringify(source)}) — conflicting project/workdir identity`};return{ok:!0,attached:!0,runId,workflowName:resolved.workflow.name,definitionDigest:digest,workflowVersion:version3,resolvedPath:resolved.path,layer:resolved.layer,workdir,status:existing.status}}return await new WorkflowService(createDefaultWorkflowEngineHost(),new DbWorkflowPersistenceAdapter(db2)).createOrAttachRun({id:runId,workflow_name:resolved.workflow.name,mode:"state-machine",status:"running",started_at:new Date().toISOString(),completed_at:null,metadata_json:JSON.stringify({definitionDigest:digest,workflowVersion:version3,definitionSource:source})}),{ok:!0,attached:!1,runId,workflowName:resolved.workflow.name,definitionDigest:digest,workflowVersion:version3,resolvedPath:resolved.path,layer:resolved.layer,workdir,status:"running"}}async function runDecideForInlineRun(input){let optionsFile=join6(resolve4(input.workdir),input.optionsFile),raw;try{raw=JSON.parse(await readFile(optionsFile,"utf8"))}catch(error51){return{ok:!1,error:`decide: unreadable options file ${input.optionsFile}: ${String(error51)}`}}let parsed=DecideOptionsSchema.safeParse(raw);if(!parsed.success)return{ok:!1,error:`decide: invalid options — ${parsed.error.issues.map((i2)=>i2.message).join("; ")}`};let result=await new DecideActionRunner(createNodeFileSystem2(),{enabled:input.enabled}).execute(raw,{runId:"inline-decide",stateOrNodeId:"decide",workdir:resolve4(input.workdir),vars:{},env:{}});if(!result.ok||result.data===void 0)return{ok:!1,error:result.error??"decide: action failed without an error message"};let decision=result.data.decision;return{ok:!0,value:decision.value,degraded:decision.degraded,reason:decision.reason,source:decision.source,backend:decision.backend,confidence:decision.confidence,resultFile:join6(resolve4(input.workdir),parsed.data.resultFile),durationMs:decision.durationMs}}import{basename as basename2,join as join7}from"node:path";var FEATURE_RECEIPT_SCHEMA_VERSION=1,DEFAULT_FEATURE_VERIFICATION_CMD="bun run spur-check-feature",RECEIPT_ID_PATTERN=/^[A-Za-z0-9][A-Za-z0-9._-]*$/;function assertReceiptId(kind,id){if(!RECEIPT_ID_PATTERN.test(id)||id.includes(".."))throw Error(`invalid ${kind} for receipt path: ${JSON.stringify(id)}`)}function featureReceiptPaths(runDir,featureId2,runId){return assertReceiptId("featureId",featureId2),assertReceiptId("runId",runId),{runScoped:join7(runDir,`${runId}-feature-verification.json`),featureScoped:join7(runDir,`${featureId2}-feature-verification.json`),log:join7(runDir,`${runId}-feature-verification.log`),status:join7(runDir,`${runId}-feature-verification.status`)}}async function atomicWriteReceipt(fs2,path8,receipt){let body=`${JSON.stringify(receipt,null,4)}
|
|
1487
|
+
${details}`)}async function loadMergedConfig(layers,opts,validateJsonSchema2){let globalRaw=layers.global!==void 0?await readRawYamlLayer(layers.global,"global"):{},projectRaw=layers.project!==void 0?await readRawYamlLayer(layers.project,"project"):{},replacementFile=projectConfigReplacement(layers);if(layers.global!==void 0)assertNoRetiredTeamKey(globalRaw,layers.global,replacementFile),assertNoGlobalFleetSection(globalRaw,layers.global,replacementFile);if(layers.project!==void 0)assertNoRetiredTeamKey(projectRaw,layers.project,replacementFile);let merged=mergeSpurConfigLayers(globalRaw,projectRaw);if(validateJsonSchema2){let source=layers.project??layers.global??"";try{await validateDeclaredJsonSchema(merged,source,schemaValidationContext(opts))}catch(error51){throw enrichSchemaViolationError(error51,merged,globalRaw,projectRaw,layers)}}return parseMergedWithProvenance(merged,globalRaw,projectRaw,layers)}init_dist6();init_dist2();var EMBEDDED_SCHEMA_PREFIX="\x00embedded-spur",SPUR_SCHEMA_MANIFEST="@gobing-ai/spur/package.json";function normalizeLayerPath(cwd,path8){return resolve2(cwd,path8)}function workflowLayers(opts){let sharedRoot=opts.sharedRoot!==void 0?opts.sharedRoot:bundledConfigRoot(),sharedPath=sharedRoot!==null?normalizeLayerPath(opts.cwd,join4(sharedRoot,"workflows")):null,layers=[],seen=new Set,add=(id,path8)=>{if(seen.has(path8))return;seen.add(path8),layers.push({id,path:path8})};add("project",normalizeLayerPath(opts.cwd,join4(opts.cwd,".spur","workflows")));for(let entry of opts.registered){if(sharedPath!==null&&normalizeLayerPath(opts.cwd,entry)===sharedPath)continue;add("registered",normalizeLayerPath(opts.cwd,entry))}if(sharedPath!==null)add("shared",sharedPath);return layers}function createEmbeddedSchemaOptions(embedded){if(embedded===void 0||embedded.size===0)return;let nodeFs=createNodeFileSystem2();return{resolve:(specifier)=>specifier===SPUR_SCHEMA_MANIFEST?`${EMBEDDED_SCHEMA_PREFIX}/package.json`:specifier,fileSystem:{readFile:async(path8)=>{if(!path8.startsWith(EMBEDDED_SCHEMA_PREFIX))return nodeFs.readFile(path8);let subpath=path8.slice(EMBEDDED_SCHEMA_PREFIX.length+1),text3=embedded.get(subpath);if(text3===void 0)throw Error(`No embedded schema registered for "${subpath}".`);return text3}}}}async function readWorkflowNameFast(fs2,filePath){try{let text3=await fs2.readFile(filePath),parsed=$parse(text3);return typeof parsed?.name==="string"?parsed.name:null}catch{return null}}async function scanWorkflowByName(cwd,name,registered){let fs2=createNodeFileSystem2();for(let layer of workflowLayers({cwd,registered}))try{let files=(await fs2.readDir(layer.path)).filter((f)=>f.endsWith(".yaml")||f.endsWith(".yml"));for(let f of files){let abs=join4(layer.path,f);if(await readWorkflowNameFast(fs2,abs)===name)return{path:abs,source:layer.id}}}catch{}return null}function resolveWorkflowFile(cwd,file2){let fs2=createNodeFileSystem2(),projectPath=resolve2(cwd,file2);if(fs2.exists(projectPath))return{path:projectPath,source:"project"};let isYaml=file2.endsWith(".yaml")||file2.endsWith(".yml"),base2=basename(file2);if(!isAbsolute(file2)){let withYaml=isYaml?file2:`${file2}.yaml`,projectSpur=resolve2(cwd,".spur","workflows",withYaml);if(fs2.exists(projectSpur))return{path:projectSpur,source:"project"};if(!isYaml){let projectDirect=resolve2(cwd,`${file2}.yaml`);if(fs2.exists(projectDirect))return{path:projectDirect,source:"project"};let projectSpurPipeline=resolve2(cwd,".spur","workflows",`${file2}-pipeline.yaml`);if(fs2.exists(projectSpurPipeline))return{path:projectSpurPipeline,source:"project"};let projectDirectPipeline=resolve2(cwd,`${file2}-pipeline.yaml`);if(fs2.exists(projectDirectPipeline))return{path:projectDirectPipeline,source:"project"}}}let bundledRoot=bundledConfigRoot();if(bundledRoot!==null){let sharedName=isYaml?base2:`${base2}.yaml`,sharedPath=join4(bundledRoot,"workflows",sharedName);if(fs2.exists(sharedPath))return{path:sharedPath,source:"shared"};if(!isYaml){let sharedPipeline=join4(bundledRoot,"workflows",`${base2}-pipeline.yaml`);if(fs2.exists(sharedPipeline))return{path:sharedPipeline,source:"shared"};let sharedLiteral=join4(bundledRoot,"workflows",base2);if(fs2.exists(sharedLiteral))return{path:sharedLiteral,source:"shared"}}return{path:null,probed:[projectPath,sharedPath]}}return{path:null,probed:[projectPath,null]}}async function resolveWorkflowDefinition(cwd,fileOrName,options={}){let registered=options.registered??[],resolved=(basename(fileOrName)===fileOrName&&!/\.ya?ml$/.test(fileOrName)&&!createNodeFileSystem2().exists(resolve2(cwd,fileOrName))?await scanWorkflowByName(cwd,fileOrName,registered):null)??resolveWorkflowFile(cwd,fileOrName);if(resolved.path===null){let scanned=await scanWorkflowByName(cwd,fileOrName,registered);if(scanned!==null)resolved=scanned;else{let[probedProject,probedShared]=resolved.probed;throw Error(`Workflow not found: ${probedProject}${probedShared!==null?` (shared: ${probedShared})`:""}`)}}let embedded=createEmbeddedSchemaOptions(options.embeddedSchemas),workflow=await loadWorkflowDef(resolved.path,{validateSchema:options.validateSchema!==!1,...embedded!==void 0?embedded:{}});if(workflow.version==="")throw Error(`Invalid workflow definition ${resolved.path}: root "version" is an empty string. Omit the field for an unversioned definition, or give it a non-empty literal.`);let digest=computeDefinitionDigest(workflow);return{path:resolved.path,workflow,digest,layer:resolved.source}}var UNPERSISTED_PREFIX="trace-unpersisted:";class RunRowNotFoundError extends Error{runId;constructor(runId){super(`run row not found: ${runId}`);this.name="RunRowNotFoundError",this.runId=runId}}class WorkflowActionTraceWriter{inner;recordFailure;db;boundaries=new Map;constructor(inner,recordFailure,db2){this.inner=inner;this.recordFailure=recordFailure;this.db=db2}async saveActionStart(runId,node,kind,options){let outcome=await this.guard("action.start",{runId,node,kind},()=>this.inner.saveActionStart(runId,node,kind,options));if(!outcome.ok){let syntheticId=`${UNPERSISTED_PREFIX}${crypto.randomUUID()}`;return this.boundaries.set(syntheticId,{runId,node,kind}),this.lastStart={runId,node,kind},syntheticId}return this.boundaries.set(outcome.value,{runId,node,kind}),this.lastStart={runId,node,kind},outcome.value}lastStart;async saveActionFinalize(actionId,status,durationMs,ok,kind,result,redactor){let origin2=this.boundaries.get(actionId)??this.lastStart;await this.guard("action.finish",{runId:origin2?.runId??"",node:origin2?.node,kind},()=>this.inner.saveActionFinalize(actionId,status,durationMs,ok,kind,result,redactor)),this.boundaries.delete(actionId)}async finalizeRun(runId,status,completedAt,fence,reason){await this.inner.finalizeRun(runId,status,completedAt,fence,reason===void 0?void 0:classifyTerminalReason({status,engineReason:reason,errorText:reason}))}async claimRunOwnership(runId,owner,expectedStatuses){return this.inner.claimRunOwnership(runId,owner,expectedStatuses)}async interruptRun(runId,reason){return this.inner.interruptRun(runId,reason)}async recordAction(boundary2){let start=await this.guard("action.start",{runId:boundary2.runId,node:boundary2.node,kind:boundary2.kind},()=>this.inner.saveActionStart(boundary2.runId,boundary2.node,boundary2.kind));if(!start.ok)return start;let finish=await this.guard("action.finish",{runId:boundary2.runId,node:boundary2.node,kind:boundary2.kind},()=>this.inner.saveActionFinalize(start.value,boundary2.status,boundary2.durationMs,boundary2.ok,boundary2.kind,boundary2.result,boundary2.redactor));if(!finish.ok)return finish;return await this.backdateStart(start.value,boundary2),{ok:!0,actionId:start.value}}async backdateStart(actionId,boundary2){let db2=this.db;if(db2===void 0||boundary2.durationMs<=0)return;await this.guard("action.backdate",{runId:boundary2.runId,node:boundary2.node,kind:boundary2.kind},async()=>{let dao2=new ActionRunDao(db2),completedAt=await dao2.completedAtById(actionId);if(completedAt===null)return;let startedAt=new Date(new Date(completedAt).getTime()-boundary2.durationMs).toISOString();await dao2.setStartedAt(actionId,startedAt)})}async closeRun(runId,status,completedAt,reason){if(await this.inner.loadRun(runId)===void 0)throw new RunRowNotFoundError(runId);if(await this.inner.finalizeRun(runId,status,completedAt??new Date().toISOString(),void 0,reason===void 0?void 0:classifyTerminalReason({status,engineReason:reason,errorText:reason})),this.db===void 0)return{ok:!0};return{ok:!0,actionRows:(await new ActionRunDao(this.db).actionRowsByRunId(runId)).length}}async guard(operation,context4,emit){try{return{ok:!0,value:await emit()}}catch(error51){let failure={operation,runId:context4.runId,...context4.node!==void 0?{node:context4.node}:{},...context4.kind!==void 0?{kind:context4.kind}:{},error:error51 instanceof Error?error51.message:String(error51),at:new Date().toISOString()};try{this.recordFailure?.(failure)}catch{}return{ok:!1,failure}}}createRun(record3){return this.inner.createRun(record3)}savePhase(runId,phase,status){return this.inner.savePhase(runId,phase,status)}saveTransition(runId,from,to,trigger){return this.inner.saveTransition(runId,from,to,trigger)}saveWorkflowState(runId,state,data){return this.inner.saveWorkflowState(runId,state,data)}commitTransition(runId,from,to,trigger,state,data,phase){return this.inner.commitTransition(runId,from,to,trigger,state,data,phase)}loadRun(runId){return this.inner.loadRun(runId)}listRuns(){return this.inner.listRuns()}findRunByKey(workflowName,externalKey){return this.inner.findRunByKey(workflowName,externalKey)}createOrAttachRun(record3){return this.inner.createOrAttachRun(record3)}reseedRun(runId,newState){return this.inner.reseedRun(runId,newState)}loadCurrentState(runId){return this.inner.loadCurrentState(runId)}loadLatestStateSnapshot(runId){return this.inner.loadLatestStateSnapshot(runId)}listPausedRuns(options){return this.inner.listPausedRuns(options)}}function createWorkflowActionTraceWriter(db2,recordFailure){return new WorkflowActionTraceWriter(new DbWorkflowPersistenceAdapter(db2),recordFailure,db2)}var TRIPWIRE_CATALOG=Object.freeze({"retry-exhausted":{id:"retry-exhausted",version:1,response:"fail",nextDecision:"Retries are exhausted; an operator must decide to escalate, extend the retry policy, or fail the stage. No further automatic retry is permitted."},"hard-budget":{id:"hard-budget",version:1,response:"fail",nextDecision:"An operator must raise the declared budget or trim the stage scope, then re-run the action; the run stays failed until then."},"capability-denied":{id:"capability-denied",version:1,response:"fail",nextDecision:"An operator must attest the executor capabilities in agent config or lower the stage requiresCapabilities, then re-run the action."},"proof-invalidated":{id:"proof-invalidated",version:1,response:"fail",nextDecision:"An operator must restore the proof inputs or re-establish the verdict (re-verify) before record; recording against a changed tree is blocked."},"output-drop":{id:"output-drop",version:1,response:"continue",nextDecision:"The dispatch completed but its captured evidence is incomplete (bounded relay dropped chunks). Inspect the session/trace for full output if the result is contested."}});var SHELL_METACHARACTERS=/[;&|<>$`(){}[\]!*?~#\n\r"']/;function splitLaunchCommand(value,label){if(SHELL_METACHARACTERS.test(value))return{error:`${label} must not contain shell metacharacters (got ${value})`};let tokens=value.trim().split(/\s+/).filter((t)=>t.length>0),command=tokens[0];if(command===void 0)return{error:`Action option ${label.slice(label.indexOf('"'))} must be a non-empty string`};return{command,leadingArgs:tokens.slice(1)}}import crypto4 from"node:crypto";import{tmpdir}from"node:os";import{dirname as dirname4,join as join5,resolve as resolve3,sep}from"node:path";init_dist6();class ProofCaptureError extends Error{stderr;constructor(message,stderr){super(message);this.stderr=stderr;this.name="ProofCaptureError"}}var TASK_SPEC_SECTIONS=["Background","Requirements","Acceptance Criteria","Design","Plan"],CANONICAL_TASK_HEADING_RE=/^##[ \t]+(\d+)\.[ \t]+(\S.*)$/m;function taskDocumentShapeError(content){let doc2=MarkdownDocument.parse(content,"task"),heading=CANONICAL_TASK_HEADING_RE.exec(doc2.bodyWithoutFrontmatter);if(heading===null)return"no canonical task heading (`## <WBS>. <title>`) was found";if((heading[2]??"").trim()==="")return`the canonical task heading for WBS ${heading[1]} has an empty title`;if(TASK_SPEC_SECTIONS.filter((section)=>doc2.hasSection(section)).length===0)return`no task specification section (${TASK_SPEC_SECTIONS.join(", ")}) was found`;return null}async function readProofInputContents(fileSystem=createNodeFileSystem2(),workdir,options){for(let name of["taskFile","featureFile"]){let value=options[name];if(value!==void 0&&typeof value!=="string")return{ok:!1,error:`${name} must be a string when supplied (got ${typeof value})`}}let readOne=async(name)=>{let raw=name==="taskFile"?options.taskFile:options.featureFile;if(raw===void 0||raw==="")return{};let workdirAbs=resolve3(workdir),resolved=resolve3(workdirAbs,raw);if(!(resolved===workdirAbs||resolved.startsWith(`${workdirAbs}${sep}`)))return{error:`${name} must resolve under the workflow workdir (${workdirAbs}): ${raw}`};let stat;try{stat=await fileSystem.stat(resolved)}catch(error51){return{error:`${name} could not be inspected: ${error51.message}`}}if(stat===null)return{error:`${name} does not exist: ${raw} (resolved ${resolved}) — an explicitly supplied spec must be readable, not silently omitted`};if(!stat.isFile())return{error:`${name} is not a regular file: ${resolved}`};let content;try{content=await fileSystem.readFile(resolved)}catch(error51){return{error:`${name} is not readable: ${error51.message}`}}if(name==="taskFile"){let shapeError=taskDocumentShapeError(content);if(shapeError!==null)return{error:`taskFile is not a task document: ${raw} (resolved ${resolved}) — ${shapeError}. Supply the task specification markdown itself: a \`## <WBS>. <title>\` heading plus at least one of ${TASK_SPEC_SECTIONS.join(", ")}. A file containing only a path is not dereferenced.`}}return{content}},task=await readOne("taskFile");if(task.error!==void 0)return{ok:!1,error:task.error};let feature=await readOne("featureFile");if(feature.error!==void 0)return{ok:!1,error:feature.error};return{ok:!0,...task.content!==void 0?{taskContent:task.content}:{},...feature.content!==void 0?{featureContent:feature.content}:{}}}var DEFAULT_EXCLUDE_GLOBS=["docs/tasks*","docs/features*"];async function createGitAlternateTree(cwd,excludeGlobs=DEFAULT_EXCLUDE_GLOBS,executor=new NodeProcessExecutor2,fs2=createNodeFileSystem2()){let indexFile=join5(tmpdir(),`spur-proof-fingerprint-${crypto4.randomUUID()}.index`);try{await fs2.ensureDir(dirname4(indexFile));let env2=Object.fromEntries(Object.entries(getEnvVars()).filter((entry)=>entry[1]!==void 0));env2.GIT_INDEX_FILE=indexFile;let common4={cwd,env:env2,forceBuffered:!0,rejectOnError:!1},read=await executor.run({command:"git",args:["read-tree","HEAD"],...common4});if(read.exitCode!==0)throw new ProofCaptureError(`git read-tree HEAD failed with exit code ${read.exitCode}`,read.stderr);let excludes=excludeGlobs.map((glob)=>`:(exclude)${glob}`),add=await executor.run({command:"git",args:["add","-A","--",".",...excludes],...common4});if(add.exitCode!==0)throw new ProofCaptureError(`git add -A failed with exit code ${add.exitCode}`,add.stderr);let tree=await executor.run({command:"git",args:["write-tree"],...common4});if(tree.exitCode!==0)throw new ProofCaptureError(`git write-tree failed with exit code ${tree.exitCode}`,tree.stderr);return tree.stdout.trim()}catch(error51){if(error51 instanceof ProofCaptureError)throw error51;throw new ProofCaptureError(`git alternate-tree capture threw: ${error51.message}`)}finally{if(await fs2.exists(indexFile))try{await fs2.deleteFile(indexFile)}catch{}}}function canonicalizeCheckboxMarkers(body){return body.replace(/^([ \t]*)[-*+][ \t]+\[[ xX]\]/gm,"$1- [x]")}function extractTaskProofData(content){let doc2=MarkdownDocument.parse(content,"task"),fm=doc2.frontmatterData??{},wbs=typeof fm.wbs==="string"?fm.wbs:void 0,name=typeof fm.name==="string"?fm.name:void 0,feature_id=typeof fm.feature_id==="string"?fm.feature_id:void 0,depends_on;if(Array.isArray(fm.depends_on))depends_on=fm.depends_on.filter((d)=>typeof d==="string");else if(Array.isArray(fm.dependencies))depends_on=fm.dependencies.filter((d)=>typeof d==="string");let sections={},taskSections=["Background","Requirements","Acceptance Criteria","Design","Plan"];for(let sec of taskSections)if(doc2.hasSection(sec)){let body=doc2.getSection(sec);if(body!==null)sections[sec]=canonicalizeCheckboxMarkers(body.trim())}return{...wbs!==void 0?{wbs}:{},...name!==void 0?{name}:{},...feature_id!==void 0?{feature_id}:{},...depends_on!==void 0?{depends_on}:{},sections}}function extractFeatureProofData(content){let doc2=MarkdownDocument.parse(content,"feature"),fm=doc2.frontmatterData??{},id=typeof fm.id==="string"?fm.id:void 0,name=typeof fm.name==="string"?fm.name:void 0,sections={},featureSections=["Goal","Scope","Acceptance Criteria"];for(let sec of featureSections)if(doc2.hasSection(sec)){let body=doc2.getSection(sec);if(body!==null)sections[sec]=canonicalizeCheckboxMarkers(body.trim())}return{...id!==void 0?{id}:{},...name!==void 0?{name}:{},sections}}async function computeProofInputFingerprint(options={}){let cwd=options.cwd??process.cwd(),gitTree=await createGitAlternateTree(cwd,options.excludeGlobs??DEFAULT_EXCLUDE_GLOBS,options.processExecutor,options.fileSystem),task;if(options.taskContent!==void 0)task=extractTaskProofData(options.taskContent);let feature;if(options.featureContent!==void 0)feature=extractFeatureProofData(options.featureContent);let canonical=canonicalJsonStringify({gitTree,...task!==void 0?{task}:{},...feature!==void 0?{feature}:{},...options.learningsContent!==void 0?{learnings:options.learningsContent}:{}});return`sha256:${crypto4.createHash("sha256").update(canonical,"utf8").digest("hex")}`}var ProofInputFingerprint={compute:computeProofInputFingerprint};init_zod();var VERDICT_AGGREGATES=["PASS","PARTIAL","FAIL","UNKNOWN"],ROW_STATUSES=["MET","PARTIAL","UNMET","N/A"],CHECK_SEVERITIES=["blocker","major","minor","advisory"],verdictSchema=exports_external.string().transform((v,ctx)=>{let up=v.toUpperCase();if(!VERDICT_AGGREGATES.includes(up))return ctx.addIssue({code:"custom",message:`invalid verdict "${v}" (expected PASS|PARTIAL|FAIL|UNKNOWN)`}),"UNKNOWN";return up}),coverageRowSchema=exports_external.object({id:exports_external.string().optional(),scenario:exports_external.string().optional(),status:exports_external.string(),evidenceType:exports_external.string().optional(),evidence:exports_external.string().optional()}).superRefine((r,ctx)=>{if(r.id!==void 0&&r.scenario!==void 0&&r.id!==r.scenario)ctx.addIssue({code:"custom",message:`id/scenario conflict ("${r.id}" vs "${r.scenario}")`,path:["scenario"]});if(!ROW_STATUSES.includes(r.status.toUpperCase()))ctx.addIssue({code:"custom",message:`invalid row status "${r.status}"`,path:["status"]})}).transform((r)=>({id:r.id??r.scenario??"",status:r.status.toUpperCase(),evidenceType:r.evidenceType??"",evidence:r.evidence??""})),checkSchema=exports_external.object({name:exports_external.string().optional(),check:exports_external.string().optional(),id:exports_external.string().optional(),status:exports_external.string(),evidence:exports_external.string().optional().default(""),severity:exports_external.enum(CHECK_SEVERITIES).optional()}).superRefine((c3,ctx)=>{if(c3.name===void 0&&c3.check===void 0&&c3.id===void 0)ctx.addIssue({code:"custom",message:"check row needs one of name/check/id",path:["name"]})}).transform((c3)=>({name:c3.name??c3.check??c3.id??"",status:c3.status,evidence:c3.evidence,severity:c3.severity})),verifyVerdictSchema=exports_external.object({wbs:exports_external.string().optional().default(""),verdict:verdictSchema,requirements:exports_external.array(coverageRowSchema).optional().default([]),acceptanceCriteria:exports_external.array(coverageRowSchema).optional().default([]),checks:exports_external.array(checkSchema).optional().default([]),source:exports_external.string().optional(),pipelineRunId:exports_external.string().optional(),recordedAt:exports_external.string().optional()});var field=(path8,label)=>({path:path8,label}),SOURCE_PROFILES={planning:{producerPackage:"spur",subsystem:"planning",remediationKind:"prefix-filter"},queue:{producerPackage:"@gobing-ai/ts-infra",subsystem:"job-queue",remediationKind:"prefix-filter"},scheduler:{producerPackage:"@gobing-ai/ts-infra",subsystem:"scheduler",remediationKind:"prefix-filter"},message:{producerPackage:"spur",subsystem:"coordination-messaging",remediationKind:"prefix-filter"},process:{producerPackage:"@gobing-ai/ts-runtime",subsystem:"process-executor",remediationKind:"prefix-filter"},workflow:{producerPackage:"@gobing-ai/ts-dual-workflow-engine",subsystem:"workflow",remediationKind:"workflow-trace"},rule:{producerPackage:"@gobing-ai/ts-rule-engine",subsystem:"rule-engine",remediationKind:"rule-trace"},agent:{producerPackage:"@gobing-ai/ts-ai-runner",subsystem:"agent-runner",remediationKind:"prefix-filter"},history:{producerPackage:"spur",subsystem:"history",remediationKind:"prefix-filter"},bus:{producerPackage:"@gobing-ai/ts-infra",subsystem:"event-bus",remediationKind:"prefix-filter"},api:{producerPackage:"spur",subsystem:"http-api",remediationKind:"prefix-filter"}};function at(data,path8){if(data===null)return;let current=data;for(let segment of path8.split(".")){if(current===null||typeof current!=="object"||Array.isArray(current))return;current=current[segment]}return current}function s2(data,...paths){for(let path8 of paths){let value=at(data,path8);if(typeof value==="string"&&value.length>0)return value}return}function n2(data,...paths){for(let path8 of paths){let value=at(data,path8);if(typeof value==="number"&&Number.isFinite(value))return String(value);if(typeof value==="boolean")return String(value)}return}function entityId(input){return s2(input.data,"entity.id")??input.correlation.entityId??""}function looksLikeOpaqueId(value){if(typeof value!=="string")return!1;let v=value.trim();if(v==="")return!1;if(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v))return!0;if(/^live[-_][a-z0-9._-]+$/i.test(v))return!0;if(/^(?:eventId|rowId|runId|executionId|actionId)$/i.test(v))return!0;return!1}function humanWorkflowTitle(input){let raw=s2(input.data,"workflowName")??s2(input.data,"workflow");if(raw!==void 0&&!looksLikeOpaqueId(raw))return(raw.split("/").pop()?.replace(/\.(?:ya?ml|json)$/i,"")??raw).replace(/[._-]+$/,"");return""}function humanStepLabel(data){let label=s2(data,"nodeLabel")??s2(data,"stepName")??s2(data,"step");if(label!==void 0&&!looksLikeOpaqueId(label))return label;let node=s2(data,"node");if(node!==void 0&&!looksLikeOpaqueId(node))return node;return}function derivedFrom(...paths){return{support:"derived",derive:({data})=>s2(data,...paths)}}function derivedFromValue(...paths){return{support:"derived",derive:({data})=>n2(data,...paths)??s2(data,...paths)}}var unsupported={support:"unsupported"};function baseEvent(name,source,renderer,payloadPolicy="metadata-only",tier="default",producer){return{name,source,tier,payloadPolicy,renderer,...producer!==void 0?{producer}:{}}}var BASE_CATALOG=[baseEvent("task.created","planning","planning"),baseEvent("task.updated","planning","planning"),baseEvent("task.transitioned","planning","planning"),baseEvent("feature.created","planning","planning"),baseEvent("feature.updated","planning","planning"),baseEvent("feature.transitioned","planning","planning"),baseEvent("queue.consumer.started","queue","queue"),baseEvent("queue.consumer.stopped","queue","queue"),baseEvent("queue.job.enqueued","queue","queue"),baseEvent("queue.job.started","queue","queue"),baseEvent("queue.job.completed","queue","queue"),baseEvent("queue.job.failed","queue","queue"),baseEvent("queue.job.retrying","queue","queue"),baseEvent("queue.stats","queue","queue"),baseEvent("scheduler.job.executed","scheduler","scheduler"),baseEvent("message.sent","message","message"),baseEvent("message.replied","message","message"),baseEvent("process.spawned","process","process"),baseEvent("process.exited","process","process"),baseEvent("process.stopped","process","process"),baseEvent("process.started","process","process"),baseEvent("agent.invoke.start","agent","agent"),baseEvent("agent.invoke.exit","agent","agent"),baseEvent("agent.invoke.escalated","agent","agent","metadata-only","default",{package:"spur",subsystem:"agent-runner"}),baseEvent("agent.invoke.exhausted","agent","agent","metadata-only","default",{package:"spur",subsystem:"agent-runner"}),baseEvent("agent.started","agent","agent"),baseEvent("agent.stopped","agent","agent"),baseEvent("agent.message.sent","agent","agent"),baseEvent("strategy.changed","agent","agent","metadata-only","default",{package:"spur",subsystem:"fleet-strategy"}),baseEvent("fleet.capacity.changed","agent","agent","metadata-only","default",{package:"spur",subsystem:"write-slot"}),baseEvent("task.assigned","planning","planning"),baseEvent("history.import.completed","history","history-import"),baseEvent("history.analyze.completed","history","history-analyze"),baseEvent("history.daily.failed","history","history-daily"),baseEvent("history.refresh.enqueued","history","history-refresh"),baseEvent("rule.run.start","rule","rule"),baseEvent("rule.eval.start","rule","rule"),baseEvent("rule.eval.done","rule","rule"),baseEvent("rule.eval.error","rule","rule"),baseEvent("rule.run.done","rule","rule"),baseEvent("workflow.run.started","workflow","workflow-run"),baseEvent("workflow.run.done","workflow","workflow-run"),baseEvent("workflow.run.failed","workflow","workflow-run"),baseEvent("workflow.run.finalized","workflow","workflow-run"),baseEvent("workflow.escalation.created","workflow","workflow-run","redacted"),baseEvent("workflow.escalation.projection_failed","workflow","workflow-run","metadata-only"),baseEvent("workflow.run.paused","workflow","workflow-run"),baseEvent("workflow.run.resumed","workflow","workflow-run"),baseEvent("workflow.run.reseeded","workflow","workflow-run"),baseEvent("workflow.node.enter","workflow","workflow-phase"),baseEvent("workflow.phase","workflow","workflow-phase"),baseEvent("workflow.node.transition","workflow","workflow-transition"),baseEvent("workflow.transition","workflow","workflow-transition"),baseEvent("workflow.transition.requested","workflow","workflow-transition","metadata-only","diagnostic"),baseEvent("workflow.transition.denied","workflow","workflow-transition","metadata-only","diagnostic"),baseEvent("workflow.action.started","workflow","workflow-action"),baseEvent("workflow.action.finished","workflow","workflow-action"),baseEvent("workflow.action.failed_continue","workflow","workflow-action"),baseEvent("workflow.guard.evaluated","workflow","workflow-guard","metadata-only","diagnostic"),baseEvent("workflow.hitl.ask","workflow","workflow-hitl","redacted"),baseEvent("workflow.hitl.response","workflow","workflow-hitl","redacted"),baseEvent("workflow.hitl.note","workflow","workflow-hitl","redacted"),baseEvent("workflow.custom","workflow","workflow-custom"),baseEvent("workflow.agent","workflow","workflow-agent","redacted","diagnostic"),baseEvent("workflow.steering","workflow","workflow-steering","redacted"),baseEvent("api.request.error","api","api"),baseEvent("bus.emit.done","bus","bus","metadata-only","diagnostic"),baseEvent("bus.emit.noop","bus","bus","metadata-only","diagnostic"),baseEvent("bus.handler.error","bus","bus","metadata-only","diagnostic"),baseEvent("bus.handler.async.enqueued","bus","bus","metadata-only","diagnostic")],SYSTEM_EVENT_PRESENTERS={"task.created":{description:"A task file was created with a new WBS id.",fields:[field("entity.kind","Entity kind"),field("entity.id","Entity")],summary:({data,correlation})=>`[task] ${entityId({data,correlation})} created`,outcome:unsupported},"task.updated":{description:"An existing task file was updated in place, naming the section that changed.",fields:[field("entity.kind","Entity kind"),field("entity.id","Entity"),field("field","Field"),field("data.mutation.name","Section"),field("data.after","After"),field("data.diff","Diff")],summary:({data,correlation})=>{let section=s2(data,"data.mutation.name"),id=entityId({data,correlation});return section!==void 0?`[task] ${section}`:`[task] ${id||"updated"}`},outcome:unsupported},"task.transitioned":{description:"A task moved between lifecycle states, naming both the previous and new status.",fields:[field("entity.kind","Entity kind"),field("entity.id","Entity"),field("from","From"),field("to","To")],summary:({data,correlation})=>{let id=entityId({data,correlation}),from=s2(data,"from"),to=s2(data,"to");return from!==void 0&&to!==void 0?`[task] ${id} : ${from} -> ${to}`:`[task] ${id} transitioned`},outcome:{support:"derived",derive:({data})=>s2(data,"to")}},"feature.created":{description:"A feature file was created with a new feature id.",fields:[field("entity.kind","Entity kind"),field("entity.id","Entity")],summary:({data,correlation})=>`[feature] ${entityId({data,correlation})} created`,outcome:unsupported},"feature.updated":{description:"An existing feature file was updated in place, naming the section that changed.",fields:[field("entity.kind","Entity kind"),field("entity.id","Entity"),field("field","Field"),field("data.mutation.name","Section"),field("data.after","After"),field("data.diff","Diff")],summary:({data,correlation})=>{let section=s2(data,"data.mutation.name"),id=entityId({data,correlation});return section!==void 0?`[feature] ${section}`:`[feature] ${id||"updated"}`},outcome:unsupported},"feature.transitioned":{description:"A feature moved between lifecycle states, naming both the previous and new status.",fields:[field("entity.kind","Entity kind"),field("entity.id","Entity"),field("from","From"),field("to","To")],summary:({data,correlation})=>{let id=entityId({data,correlation}),from=s2(data,"from"),to=s2(data,"to");return from!==void 0&&to!==void 0?`[feature] ${id} : ${from} -> ${to}`:`[feature] ${id} transitioned`},outcome:{support:"derived",derive:({data})=>s2(data,"to")}},"queue.consumer.started":{description:"The configured queue consumer began polling its named queue.",fields:[field("queueName","Queue"),field("startedAt","Started"),field("pollInterval","Poll interval"),field("batchSize","Batch size"),field("maxConcurrency","Max concurrency"),field("visibilityTimeout","Visibility timeout")],summary:({data})=>{let name=s2(data,"queueName");return name!==void 0?`[queue] ${name} : consumer started`:"[queue] consumer started"},outcome:{support:"derived",derive:({data})=>at(data,"startedAt")!==void 0?"running":void 0}},"queue.consumer.stopped":{description:"The queue consumer stopped, reporting whether it drained in-flight work.",fields:[field("queueName","Queue"),field("stoppedAt","Stopped"),field("drainTimeoutMs","Drain timeout"),field("inFlightAtStop","In flight"),field("drained","Drained")],summary:({data})=>{let name=s2(data,"queueName");return name!==void 0?`[queue] ${name} : consumer stopped`:"[queue] consumer stopped"},outcome:{support:"derived",derive:({data})=>{let drained=at(data,"drained");if(drained===!0)return"drained";if(drained===!1)return"timeout";return}}},"queue.job.enqueued":{description:"A job was enqueued onto the job queue for later processing.",fields:[field("jobId","Job"),field("type","Type"),field("nextRetryAt","Next retry")],summary:({data})=>{let type=s2(data,"type"),jobId=s2(data,"jobId");return type!==void 0&&jobId!==void 0?`[queue] ${type} · job ${jobId} enqueued`:"[queue] job enqueued"},outcome:unsupported},"queue.job.started":{description:"A queued job handler began executing (job identity and phase anchor).",fields:[field("jobId","Job"),field("type","Type"),field("name","Name")],summary:({data})=>{let type=s2(data,"type"),jobId=s2(data,"jobId");return type!==void 0&&jobId!==void 0?`[queue] ${type} · job ${jobId} started`:"[queue] job started"},outcome:unsupported},"queue.job.completed":{description:"A queued job finished successfully with its attempt and duration.",fields:[field("jobId","Job"),field("type","Type"),field("attempt","Attempt"),field("durationMs","Duration (ms)")],summary:({data})=>{let type=s2(data,"type"),jobId=s2(data,"jobId");return type!==void 0&&jobId!==void 0?`[queue] ${type} · job ${jobId} completed`:"[queue] job completed"},outcome:unsupported},"queue.job.failed":{description:"A queued job exhausted its attempts and failed with an error.",fields:[field("jobId","Job"),field("type","Type"),field("attempt","Attempt"),field("maxRetries","Max retries"),field("durationMs","Duration (ms)"),field("error","Error")],summary:({data})=>{let type=s2(data,"type"),jobId=s2(data,"jobId");return type!==void 0&&jobId!==void 0?`[queue] ${type} · job ${jobId} failed`:"[queue] job failed"},outcome:derivedFrom("error")},"queue.job.retrying":{description:"A queued job failed once and is scheduled for another attempt.",fields:[field("jobId","Job"),field("type","Type"),field("attempt","Attempt"),field("maxRetries","Max retries"),field("nextRetryAt","Next retry"),field("error","Error")],summary:({data})=>{let type=s2(data,"type"),jobId=s2(data,"jobId");return type!==void 0&&jobId!==void 0?`[queue] ${type} · job ${jobId} retrying`:"[queue] job retrying"},outcome:{support:"derived",derive:({data})=>{let attempt=at(data,"attempt"),max=at(data,"maxRetries");if(typeof attempt==="number"&&typeof max==="number"&&Number.isFinite(attempt)&&Number.isFinite(max))return`retrying ${attempt}/${max}`;return s2(data,"error")}}},"queue.stats":{description:"Periodic job-queue statistics across ready, running, completed, and failed counts.",fields:[field("ready","Ready"),field("running","Running"),field("completed","Completed"),field("failed","Failed")],summary:()=>"[queue] stats",outcome:unsupported},"scheduler.job.executed":{description:"A scheduler job ran to completion or failed, with its duration.",fields:[field("name","Job"),field("action","Action"),field("durationMs","Duration (ms)"),field("error","Error")],summary:({data})=>{let name=s2(data,"name");return name!==void 0?`[scheduler] ${name}`:"[scheduler] job executed"},outcome:{support:"derived",derive:({data})=>s2(data,"error")??(at(data,"error")===null?"completed":void 0)}},"message.sent":{description:"A team message was sent from one member to another.",fields:[field("msgId","Message"),field("fromId","From"),field("toId","To"),field("threadId","Thread")],summary:({data})=>{let from=s2(data,"fromId"),to=s2(data,"toId");return from!==void 0&&to!==void 0?`[message] ${from} -> ${to}`:"[message] sent"},outcome:unsupported},"message.replied":{description:"A member replied to an existing message thread.",fields:[field("msgId","Message"),field("fromId","From"),field("toId","To"),field("threadId","Thread")],summary:({data})=>{let from=s2(data,"fromId"),thread=s2(data,"threadId");return from!==void 0&&thread!==void 0?`[message] ${from} replied in ${thread}`:"[message] replied"},outcome:unsupported},"process.spawned":{description:"A supervised process was spawned with a new pid.",fields:[field("label","Label"),field("pid","PID"),field("agentId","Agent")],summary:({data})=>{let label=s2(data,"label")??n2(data,"pid");return label!==void 0?`[process] ${label} spawned`:"[process] spawned"},outcome:unsupported},"process.exited":{description:"A supervised process exited, carrying its exit code, signal, or failure reason.",fields:[field("label","Label"),field("pid","PID"),field("exitCode","Exit code"),field("signal","Signal"),field("durationMs","Duration (ms)"),field("reason","Reason")],summary:({data})=>{let label=s2(data,"label")??n2(data,"pid");return label!==void 0?`[process] ${label} exited`:"[process] exited"},outcome:{support:"derived",derive:({data})=>{let reason=s2(data,"reason");if(reason!==void 0)return reason;let signal=s2(data,"signal");if(signal!==void 0)return`signal ${signal}`;let code=at(data,"exitCode");if(typeof code==="number"&&Number.isFinite(code))return code===0?"ok":`exit ${code}`;return}}},"process.stopped":{description:"A supervised process was stopped, naming the stopping reason.",fields:[field("label","Label"),field("pid","PID"),field("signal","Signal"),field("reason","Reason")],summary:({data})=>{let label=s2(data,"label")??n2(data,"pid");return label!==void 0?`[process] ${label} stopped`:"[process] stopped"},outcome:derivedFrom("reason")},"process.started":{description:"A process executor started a process with a new pid.",fields:[field("label","Label"),field("pid","PID")],summary:({data})=>{let label=s2(data,"label")??n2(data,"pid");return label!==void 0?`[process] ${label} started`:"[process] started"},outcome:unsupported},"agent.invoke.start":{description:"An agent invocation began, naming the agent and its operation.",fields:[field("agent","Agent"),field("operation","Operation"),field("routing.role","Role"),field("routing.tier","Tier"),field("routing.executor","Executor"),field("routing.source","Selection source")],summary:({data})=>{let agent=s2(data,"agent"),operation=s2(data,"operation");return agent!==void 0&&operation!==void 0?`[agent] ${agent} · ${operation}`:"[agent] invocation started"},outcome:unsupported},"agent.invoke.exit":{description:"An agent invocation exited, reporting its exit code or signal.",fields:[field("agent","Agent"),field("operation","Operation"),field("exitCode","Exit code"),field("signal","Signal"),field("routing.role","Role"),field("routing.tier","Tier"),field("routing.executor","Executor"),field("routing.source","Selection source")],summary:({data})=>{let agent=s2(data,"agent"),operation=s2(data,"operation");return agent!==void 0&&operation!==void 0?`[agent] ${agent} · ${operation} exited`:"[agent] invocation exited"},outcome:{support:"derived",derive:({data})=>{let signal=s2(data,"signal");if(signal!==void 0)return`signal ${signal}`;let code=at(data,"exitCode");if(typeof code==="number"&&Number.isFinite(code))return code===0?"ok":`exit ${code}`;return}}},"agent.invoke.escalated":{description:"An agent invocation escalated from one executor tier to another.",fields:[field("fromExecutor","From executor"),field("fromTier","From tier"),field("toExecutor","To executor"),field("toTier","To tier"),field("trigger","Trigger")],summary:({data})=>{let from=s2(data,"fromExecutor"),to=s2(data,"toExecutor");return from!==void 0&&to!==void 0?`[agent] ${from} -> ${to}`:"[agent] escalation"},outcome:{support:"derived",derive:({data})=>s2(data,"toTier")??s2(data,"trigger")}},"agent.invoke.exhausted":{description:"An agent invocation exhausted every eligible executor tier without success.",fields:[field("stage","Stage"),field("attempts","Attempts"),field("fromTier","From tier"),field("toTier","To tier"),field("fromExecutor","From executor"),field("toExecutor","To executor")],summary:({data})=>{let stage=s2(data,"stage");return stage!==void 0?`[agent] ${stage} escalation exhausted`:"[agent] escalation exhausted"},outcome:derivedFromValue("attempts")},"agent.started":{description:"An agent started, carrying its id and type.",fields:[field("agentId","Agent"),field("agentType","Agent type"),field("pid","PID")],summary:({data})=>{let id=s2(data,"agentId");return id!==void 0?`[agent] ${id} started`:"[agent] started"},outcome:unsupported},"agent.stopped":{description:"An agent stopped, reporting its exit code.",fields:[field("agentId","Agent"),field("exitCode","Exit code")],summary:({data})=>{let id=s2(data,"agentId");return id!==void 0?`[agent] ${id} stopped`:"[agent] stopped"},outcome:derivedFromValue("exitCode")},"strategy.changed":{description:"A project strategy changed (0838), minting a new strategy version for dispatch fencing.",fields:[field("data.projectPath","Project"),field("data.strategy","Strategy"),field("data.version","Version")],summary:({data})=>{let strategy=s2(data,"data.strategy"),version3=s2(data,"data.version");return strategy!==void 0?`[strategy] ${strategy}${version3!==void 0?` (v${version3})`:""}`:"[strategy] changed"},outcome:unsupported},"fleet.capacity.changed":{description:"The project write slot was claimed or released (0837), changing dispatch capacity.",fields:[field("data.projectPath","Project"),field("data.change","Change"),field("data.holderId","Holder")],summary:({data})=>{let change=s2(data,"data.change"),holder=s2(data,"data.holderId");return`[fleet] write slot ${change??"changed"}${holder!==void 0?` — ${holder}`:""}`},outcome:unsupported},"agent.message.sent":{description:"A message was sent to an agent, reporting delivery success.",fields:[field("agentId","Agent"),field("ok","Delivered")],summary:({data})=>{let id=s2(data,"agentId");return id!==void 0?`[agent] message -> ${id}`:"[agent] message sent"},outcome:derivedFromValue("ok")},"task.assigned":{description:"A task was assigned to an agent, naming the agent when resolved.",fields:[field("memberId","Member"),field("agentType","Agent type"),field("taskId","Task"),field("outcome","Outcome")],summary:({data})=>{let member=s2(data,"memberId"),task=s2(data,"taskId");return task!==void 0&&member!==void 0?`[task] ${task} assigned to ${member}`:"[task] assignment recorded"},outcome:derivedFrom("outcome")},"history.import.completed":{description:"A history import finished, reporting files, messages, and exit code.",fields:[field("source","Source"),field("sources","Sources"),field("files","Files"),field("messages","Messages"),field("durationMs","Duration (ms)"),field("exitCode","Exit code"),field("artifactPath","Artifact"),field("cwd","Project root")],retain:[field("trigger","Refresh trigger"),field("windowStart","Refresh window start"),field("windowEnd","Refresh window end"),field("importMode","Import mode"),field("coverage","Refresh coverage")],summary:({data})=>{let source=s2(data,"source")??s2(data,"sources");return source!==void 0?`[history] import · ${source}`:"[history] import completed"},outcome:derivedFromValue("exitCode")},"history.analyze.completed":{description:"A history analyze pass finished, reporting sources, duration, and exit code.",fields:[field("source","Source"),field("sources","Sources"),field("durationMs","Duration (ms)"),field("exitCode","Exit code"),field("artifactPath","Artifact")],retain:[field("trigger","Refresh trigger"),field("windowStart","Refresh window start"),field("windowEnd","Refresh window end"),field("importMode","Import mode")],summary:({data})=>{let source=s2(data,"source")??s2(data,"sources");return source!==void 0?`[history] analyze · ${source}`:"[history] analyze completed"},outcome:derivedFromValue("exitCode")},"history.daily.failed":{description:"The daily history refresh failed, carrying the detail, reason, and exit code.",fields:[field("source","Source"),field("sources","Sources"),field("detail","Detail"),field("reason","Reason"),field("exitCode","Exit code")],retain:[field("trigger","Refresh trigger"),field("windowStart","Refresh window start"),field("windowEnd","Refresh window end"),field("importMode","Import mode")],summary:()=>"[history] daily failed",outcome:{support:"derived",derive:({data})=>s2(data,"reason")??s2(data,"detail")??n2(data,"exitCode")}},"history.refresh.enqueued":{description:"A completion-triggered history refresh was enqueued, naming its window.",fields:[field("trigger","Trigger"),field("triggerId","Trigger id"),field("jobId","Queue job"),field("windowStart","Window start"),field("windowEnd","Window end"),field("coalesced","Coalesced"),field("outcome","Outcome")],summary:({data})=>{let start=s2(data,"windowStart"),end=s2(data,"windowEnd");return start!==void 0&&end!==void 0?`[history] refresh · ${start} -> ${end}`:"[history] refresh enqueued"},outcome:{support:"derived",derive:({data})=>{let status=s2(data,"outcome");return status!==void 0&&status!=="enqueued"?status:void 0}}},"rule.run.start":{description:"A rule run began with the rule count it will evaluate.",fields:[field("runId","Run"),field("ruleCount","Rules"),field("evaluator","Evaluator")],summary:({data,correlation})=>{let run=s2(data,"runId")??correlation.runId;return run!==void 0?`[rule] run ${run} started`:"[rule] run started"},outcome:unsupported},"rule.eval.start":{description:"A single rule began evaluating.",fields:[field("runId","Run"),field("ruleId","Rule"),field("evaluator","Evaluator"),field("index","Index"),field("total","Total")],summary:({data})=>{let id=s2(data,"ruleId");return id!==void 0?`[rule] ${id} evaluating`:"[rule] evaluating"},outcome:unsupported},"rule.eval.done":{description:"A rule finished evaluating, reporting its findings count and severity.",fields:[field("runId","Run"),field("ruleId","Rule"),field("evaluator","Evaluator"),field("findings","Findings"),field("durationMs","Duration (ms)"),field("severity","Severity")],summary:({data})=>{let id=s2(data,"ruleId");return id!==void 0?`[rule] ${id} evaluated`:"[rule] evaluated"},outcome:derivedFromValue("findings")},"rule.eval.error":{description:"A rule evaluation failed with an error.",fields:[field("runId","Run"),field("ruleId","Rule"),field("evaluator","Evaluator"),field("error","Error")],summary:({data})=>{let id=s2(data,"ruleId");return id!==void 0?`[rule] ${id} error`:"[rule] error"},outcome:derivedFrom("error")},"rule.run.done":{description:"A rule run finished, reporting findings and whether it stopped early.",fields:[field("runId","Run"),field("findings","Findings"),field("durationMs","Duration (ms)"),field("stoppedEarly","Stopped early"),field("severity","Severity")],summary:({data,correlation})=>{let run=s2(data,"runId")??correlation.runId;return run!==void 0?`[rule] run ${run} done`:"[rule] run done"},outcome:{support:"derived",derive:({data})=>n2(data,"findings")??s2(data,"stoppedEarly")}},"workflow.run.started":{description:"A workflow run started, naming the workflow definition.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("mode","Mode"),field("dryRun","Dry run")],summary:(input)=>{let name=humanWorkflowTitle(input);return name!==""?`[workflow] ${name} started`:"[workflow] started"},outcome:unsupported},"workflow.run.done":{description:"A workflow run reached a done terminal state.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("finalState","Final state"),field("transitionsTaken","Transitions")],summary:(input)=>{let name=humanWorkflowTitle(input);return name!==""?`[workflow] ${name} done`:"[workflow] done"},outcome:derivedFrom("finalState")},"workflow.run.failed":{description:"A workflow run failed with a terminal failure reason.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("finalState","Final state"),field("reason","Reason")],summary:(input)=>{let name=humanWorkflowTitle(input);return name!==""?`[workflow] ${name} failed`:"[workflow] failed"},outcome:derivedFrom("reason")},"workflow.run.finalized":{description:"A workflow run settled on a terminal status.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("status","Status")],summary:(input)=>{let name=humanWorkflowTitle(input);return name!==""?`[workflow] ${name} finalized`:"[workflow] finalized"},outcome:derivedFrom("status")},"workflow.escalation.created":{description:"A canonical escalation packet was projected from existing run evidence.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("fingerprint","Fingerprint"),field("artifactPath","Artifact"),field("decision","Decision")],summary:(input)=>{let name=humanWorkflowTitle(input),decision=typeof at(input.data,"decision")==="string"?` — ${String(at(input.data,"decision"))}`:"";return name!==""?`[workflow] escalation packet created (${name}${decision})`:`[workflow] escalation packet created${decision}`},outcome:derivedFrom("decision")},"workflow.escalation.projection_failed":{description:"Escalation packet projection failed; the original failure is preserved untouched.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("error","Error")],summary:()=>"[workflow] escalation packet projection failed",outcome:derivedFrom("error")},"workflow.run.paused":{description:"A workflow run paused at a step, naming the step when available.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("nodeLabel","Step"),field("node","Node"),field("transitionsTaken","Transitions")],summary:(input)=>{let name=humanWorkflowTitle(input),step=humanStepLabel(input.data),parts=[name,step].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")} paused`:"[workflow] paused"},outcome:unsupported},"workflow.run.resumed":{description:"A paused workflow run resumed at a step, naming the step when available.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("nodeLabel","Step"),field("node","Node")],summary:(input)=>{let name=humanWorkflowTitle(input),step=humanStepLabel(input.data),parts=[name,step].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")} resumed`:"[workflow] resumed"},outcome:unsupported},"workflow.run.reseeded":{description:"A workflow run was reseeded to a new state, naming the transition.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("fromState","From"),field("toState","To")],summary:(input)=>{let name=humanWorkflowTitle(input),from=s2(input.data,"fromState"),to=s2(input.data,"toState");if(from!==void 0&&to!==void 0)return name!==""?`[workflow] ${name} : ${from} -> ${to}`:`[workflow] : ${from} -> ${to}`;return name!==""?`[workflow] ${name} reseeded`:"[workflow] reseeded"},outcome:derivedFrom("toState")},"workflow.node.enter":{description:"The engine entered a workflow node, naming the step when available.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("nodeLabel","Step"),field("node","Node"),field("transitionsTaken","Transitions")],summary:(input)=>{let name=humanWorkflowTitle(input),step=humanStepLabel(input.data),parts=[name,step].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")}`:"[workflow] node entered"},outcome:unsupported},"workflow.phase":{description:"A workflow phase changed status, naming the phase.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("phase","Phase"),field("status","Status")],summary:(input)=>{let name=humanWorkflowTitle(input),phase=s2(input.data,"phase"),parts=[name,phase].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")}`:"[workflow] phase"},outcome:derivedFrom("status")},"workflow.node.transition":{description:"A workflow transitioned between nodes, naming the from and to states.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("from","From"),field("to","To"),field("trigger","Trigger")],summary:(input)=>{let name=humanWorkflowTitle(input),from=s2(input.data,"from"),to=s2(input.data,"to");if(from!==void 0&&to!==void 0)return name!==""?`[workflow] ${name} : ${from} -> ${to}`:`[workflow] : ${from} -> ${to}`;return name!==""?`[workflow] ${name} transitioned`:"[workflow] transitioned"},outcome:derivedFrom("to")},"workflow.transition":{description:"A workflow state transition was committed.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("from","From"),field("to","To"),field("trigger","Trigger")],summary:(input)=>{let name=humanWorkflowTitle(input),from=s2(input.data,"from"),to=s2(input.data,"to");if(from!==void 0&&to!==void 0)return name!==""?`[workflow] ${name} : ${from} -> ${to}`:`[workflow] : ${from} -> ${to}`;return name!==""?`[workflow] ${name} transitioned`:"[workflow] transitioned"},outcome:derivedFrom("to")},"workflow.transition.requested":{description:"A workflow transition was requested and accepted for evaluation.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("from","From"),field("to","To"),field("trigger","Trigger")],summary:(input)=>{let name=humanWorkflowTitle(input),from=s2(input.data,"from"),to=s2(input.data,"to");if(from!==void 0&&to!==void 0)return name!==""?`[workflow] ${name} requested ${from} -> ${to}`:`[workflow] requested ${from} -> ${to}`;return name!==""?`[workflow] ${name} transition requested`:"[workflow] transition requested"},outcome:unsupported},"workflow.transition.denied":{description:"A workflow transition was denied with a reason.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("from","From"),field("to","To"),field("reason","Reason")],summary:(input)=>{let name=humanWorkflowTitle(input),from=s2(input.data,"from"),to=s2(input.data,"to");if(from!==void 0&&to!==void 0)return name!==""?`[workflow] ${name} denied ${from} -> ${to}`:`[workflow] denied ${from} -> ${to}`;return name!==""?`[workflow] ${name} transition denied`:"[workflow] transition denied"},outcome:derivedFrom("reason")},"workflow.action.started":{description:"A workflow action began executing, naming the step and kind.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("nodeLabel","Step"),field("node","Node"),field("actionId","Action"),field("kind","Kind")],retain:[field("metadata.agent","Agent"),field("metadata.role","Role"),field("routing.executor","Executor")],summary:(input)=>{let name=humanWorkflowTitle(input),step=humanStepLabel(input.data),parts=[name,step].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")} started`:"[workflow] action started"},outcome:unsupported},"workflow.action.finished":{description:"A workflow action finished, reporting its status and success.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("nodeLabel","Step"),field("node","Node"),field("actionId","Action"),field("kind","Kind"),field("durationMs","Duration (ms)"),field("status","Status")],retain:[field("metadata.agent","Agent"),field("metadata.role","Role"),field("routing.executor","Executor")],summary:(input)=>{let name=humanWorkflowTitle(input),step=humanStepLabel(input.data),parts=[name,step].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")} finished`:"[workflow] action finished"},outcome:{support:"derived",derive:({data})=>s2(data,"status")??n2(data,"ok")}},"workflow.action.failed_continue":{description:"A workflow action failed but the workflow continued, carrying the error.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("nodeLabel","Step"),field("node","Node"),field("transitionsTaken","Transitions"),field("error","Error")],retain:[field("metadata.agent","Agent"),field("metadata.role","Role"),field("routing.executor","Executor")],summary:(input)=>{let name=humanWorkflowTitle(input),step=humanStepLabel(input.data),parts=[name,step].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")} failed; continuing`:"[workflow] action failed; continuing"},outcome:derivedFrom("error")},"workflow.guard.evaluated":{description:"A workflow guard was evaluated for a transition, reporting whether it passed.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("from","From"),field("to","To"),field("kind","Kind"),field("passed","Passed")],summary:(input)=>{let name=humanWorkflowTitle(input),from=s2(input.data,"from"),to=s2(input.data,"to");if(from!==void 0&&to!==void 0)return name!==""?`[workflow] ${name} guard ${from} -> ${to}`:`[workflow] guard ${from} -> ${to}`;return name!==""?`[workflow] ${name} guard evaluated`:"[workflow] guard evaluated"},outcome:derivedFromValue("passed")},"workflow.hitl.ask":{description:"A workflow paused for human input, naming the step and kind.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("nodeLabel","Step"),field("node","Node"),field("kind","Kind")],summary:(input)=>{let name=humanWorkflowTitle(input),step=humanStepLabel(input.data),parts=[name,step].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")} awaiting input`:"[workflow] awaiting input"},outcome:unsupported},"workflow.hitl.response":{description:"Human input was received for a paused workflow step.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("nodeLabel","Step"),field("node","Node"),field("ok","Accepted")],summary:(input)=>{let name=humanWorkflowTitle(input),step=humanStepLabel(input.data),parts=[name,step].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")} input received`:"[workflow] input received"},outcome:derivedFromValue("ok")},"workflow.hitl.note":{description:"A note was recorded on a paused workflow step.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("nodeLabel","Step"),field("node","Node")],summary:(input)=>{let name=humanWorkflowTitle(input),step=humanStepLabel(input.data),parts=[name,step].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")} note`:"[workflow] note"},outcome:unsupported},"workflow.custom":{description:"A custom workflow event was emitted, naming the custom event.",fields:[field("runId","Run"),field("workflowName","Workflow"),field("name","Event")],summary:(input)=>{let name=humanWorkflowTitle(input),custom3=s2(input.data,"name"),parts=[name,custom3].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")}`:"[workflow] custom"},outcome:unsupported},"workflow.agent":{description:"A workflow-dispatched agent execution lifecycle event, discriminated by kind.",fields:[field("runId","Run"),field("executionId","Execution"),field("actionId","Action"),field("kind","Kind"),field("agent","Agent"),field("model","Model")],retain:[field("metadata.agent","Agent"),field("metadata.role","Role"),field("routing.executor","Executor")],summary:(input)=>{let name=humanWorkflowTitle(input),kind=s2(input.data,"kind"),parts=[name,kind!==void 0?`agent ${kind}`:"agent"].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")}`:"[workflow] agent"},outcome:{support:"derived",derive:({data})=>s2(data,"kind")==="finished"?s2(data,"outcome"):void 0}},"workflow.steering":{description:"A steering command was acknowledged for a workflow action boundary.",fields:[field("runId","Run"),field("actionId","Action"),field("operation","Operation"),field("actor","Actor"),field("accepted","Accepted"),field("state","State"),field("reason","Reason")],summary:(input)=>{let name=humanWorkflowTitle(input),operation=s2(input.data,"operation"),parts=[name,operation!==void 0?`steering ${operation}`:"steering"].filter((part)=>typeof part==="string"&&part!=="");return parts.length>0?`[workflow] ${parts.join(" · ")}`:"[workflow] steering"},outcome:{support:"derived",derive:({data})=>{let reason=s2(data,"reason");if(reason!==void 0)return reason;let accepted=at(data,"accepted");if(accepted===!0)return"accepted";if(accepted===!1)return"rejected";return s2(data,"state")}}},"api.request.error":{description:"An API request failed, naming the method, path, and status or error code.",fields:[field("method","Method"),field("path","Path"),field("status","Status"),field("code","Code"),field("requestId","Request"),field("error","Error")],summary:({data})=>{let method=s2(data,"method"),path8=s2(data,"path");return method!==void 0&&path8!==void 0?`[api] ${method} ${path8}`:"[api] request error"},outcome:{support:"derived",derive:({data})=>s2(data,"error")??s2(data,"code")??n2(data,"status")}},"bus.emit.done":{description:"An event was emitted to its handlers on the event bus.",fields:[field("event","Event"),field("handlers","Handlers"),field("durationMs","Duration (ms)")],summary:({data})=>{let event=s2(data,"event");return event!==void 0?`[bus] ${event} emitted`:"[bus] event emitted"},outcome:derivedFromValue("handlers")},"bus.emit.noop":{description:"An event was emitted but had no registered handlers.",fields:[field("event","Event"),field("handlers","Handlers"),field("durationMs","Duration (ms)")],summary:({data})=>{let event=s2(data,"event");return event!==void 0?`[bus] ${event} had no handlers`:"[bus] event had no handlers"},outcome:derivedFromValue("handlers")},"bus.handler.error":{description:"An event-bus handler threw an error while processing an event.",fields:[field("event","Event"),field("handlers","Handlers"),field("durationMs","Duration (ms)"),field("error","Error")],summary:({data})=>{let event=s2(data,"event");return event!==void 0?`[bus] ${event} handler error`:"[bus] handler error"},outcome:derivedFrom("error")},"bus.handler.async.enqueued":{description:"An event-bus handler was enqueued for asynchronous processing.",fields:[field("event","Event"),field("handlers","Handlers")],summary:({data})=>{let event=s2(data,"event");return event!==void 0?`[bus] ${event} handlers enqueued`:"[bus] handlers enqueued"},outcome:derivedFromValue("handlers")}};function inferSeverity(name){if(/(?:failed|error|denied)$/.test(name))return"error";if(/(?:retrying|paused|dropped)$/.test(name))return"warning";return"info"}function resolveCatalogEntry(base2){let profile=SOURCE_PROFILES[base2.source],presenter=SYSTEM_EVENT_PRESENTERS[base2.name];return{name:base2.name,prefix:base2.name.split(".")[0]??base2.name,source:base2.source,tier:base2.tier,persisted:!0,streamed:!0,payloadPolicy:base2.payloadPolicy,renderer:base2.renderer,...profile,...base2.producer!==void 0?{producerPackage:base2.producer.package,subsystem:base2.producer.subsystem}:{},severity:inferSeverity(base2.name),description:presenter.description,metadataFields:presenter.retain?[...presenter.fields,...presenter.retain.filter((r)=>!presenter.fields.some((f)=>f.path===r.path))]:presenter.fields,remediationKind:profile.remediationKind}}var SYSTEM_EVENT_CATALOG=BASE_CATALOG.map(resolveCatalogEntry),SYSTEM_EVENT_NAMES=SYSTEM_EVENT_CATALOG.map((entry)=>entry.name),SYSTEM_EVENT_PERSISTED_NAMES=SYSTEM_EVENT_CATALOG.filter((entry)=>entry.tier==="default").map((entry)=>entry.name),SYSTEM_EVENT_STREAMED_NAMES=SYSTEM_EVENT_CATALOG.filter((entry)=>entry.tier==="default").map((entry)=>entry.name),SYSTEM_EVENT_PREFIXES=Array.from(new Set(SYSTEM_EVENT_CATALOG.map((entry)=>entry.prefix))),SYSTEM_EVENT_DEFAULT_NAMES=SYSTEM_EVENT_CATALOG.filter((entry)=>entry.tier==="default").map((entry)=>entry.name),SYSTEM_EVENT_DIAGNOSTIC_NAMES=SYSTEM_EVENT_CATALOG.filter((entry)=>entry.tier==="diagnostic").map((entry)=>entry.name);var SYSTEM_EVENT_CATALOG_METADATA=SYSTEM_EVENT_CATALOG.map(({name,prefix,source,tier,renderer,producerPackage,subsystem,severity,description,metadataFields,remediationKind})=>({name,prefix,source,tier,renderer,producerPackage,subsystem,severity,description,metadataFields,remediationKind}));function workflowVersionLiteral(workflow){return typeof workflow.version==="string"&&workflow.version!==""?workflow.version:null}var{mkdirSync:mkdirSync2,writeFileSync:writeFileSync3}=await import("node:fs"),{lstat,readFile}=await import("node:fs/promises");function parseIdentityMetadata(raw){if(raw.trim()==="")return{};try{let parsed=JSON.parse(raw);if(parsed===null||typeof parsed!=="object"||Array.isArray(parsed))return null;return parsed}catch{return null}}async function openInlineRunProjectDb(workdir){let url2=join6(resolve4(workdir),".spur","spur.db");mkdirSync2(join6(url2,".."),{recursive:!0});let adapter=await createMigratedDb({url:url2});return{adapter,close:()=>adapter.close()}}var SAFE_RUN_ID_RE=/^[A-Za-z0-9][A-Za-z0-9._-]*$/,MAX_CITED_RUN_FILES=64,RUN_CITATION_RE=/(?<![\w~:-]|[\w~:-]\/)\.spur\/run\/([A-Za-z0-9][A-Za-z0-9._*?<>{}|,\u2026-]*)/g;function asLiteralRunFileName(citation){let name=citation.replace(/[.,]+$/,"");if(!SAFE_RUN_ID_RE.test(name)||name.includes(".."))return;return name}async function persistWorktreeRuns(input){let fromDir=resolve4(input.fromWorkdir),toDir=resolve4(input.toWorkdir),fromRunDir=join6(fromDir,".spur","run"),toRunDir=join6(toDir,".spur","run"),citedNames=new Set;for(let taskFile of input.taskFiles??[]){let content;try{content=await readFile(resolve4(toDir,taskFile),"utf8")}catch(error51){throw Error(`persist-out: merged task file ${taskFile} is unreadable: ${String(error51)}`)}for(let match of content.matchAll(RUN_CITATION_RE)){let name=asLiteralRunFileName(match[1]??"");if(name===void 0||citedNames.has(name))continue;if(citedNames.size>=MAX_CITED_RUN_FILES)throw Error(`persist-out: merged task files cite more than ${MAX_CITED_RUN_FILES} distinct `+".spur/run/ files — over the fixed citation cap (0984 R3); split the batch or prune the citations");citedNames.add(name)}}let citedCopies=[],citedSkips=[];for(let name of citedNames){let sourcePath=join6(fromRunDir,name),targetPath=join6(toRunDir,name),sourceStat=await lstat(sourcePath).catch(()=>{return}),targetBytes=await readFile(targetPath).catch(()=>{return});if(sourceStat===void 0){if(targetBytes===void 0)throw Error(`persist-out: cited run evidence .spur/run/${name} is missing in both the worktree and `+"the invoking tree — resolve or drop the citation before teardown (0984 R1)");continue}if(!sourceStat.isFile()){let kind=sourceStat.isDirectory()?"directory":sourceStat.isSymbolicLink()?"symlink":"non-file";citedSkips.push({id:name,reason:`cited-${kind}:${name}`});continue}if(targetBytes!==void 0){let sourceBytes=await readFile(sourcePath);if(!targetBytes.equals(sourceBytes))throw Error(`persist-out: cited run evidence .spur/run/${name} diverges from the invoking tree's `+"existing file — refusing to overwrite; reconcile the two copies by hand (0984 R4)");continue}citedCopies.push({name,sourcePath,targetPath})}let source=await openInlineRunProjectDb(fromDir);try{let runRows=await listRunIdRows(source.adapter);for(let row of runRows)if(!SAFE_RUN_ID_RE.test(row.id))throw new InvalidWorkflowRunIdError(row.id);let target=await openInlineRunProjectDb(toDir);try{let{persistedIds,skipped}=await transferRunTables(source.adapter,target.adapter),workflowNameById=new Map(runRows.map((row)=>[row.id,row.workflowName])),recordSkips=[];if(persistedIds.length>0||citedCopies.length>0){mkdirSync2(toRunDir,{recursive:!0});for(let id of persistedIds){let workflowName=workflowNameById.get(id);for(let fileName of[`${id}.md`,`${id}.state.json`]){let sourceBytes;try{sourceBytes=await readFile(join6(fromRunDir,fileName))}catch(error51){if(workflowName!==null&&workflowName!==void 0&&isBookkeepingWorkflow(workflowName)&&error51.code==="ENOENT"){recordSkips.push({id,reason:`record-missing:${fileName}`});continue}throw error51}let targetPath=join6(toRunDir,fileName),existing;try{existing=await readFile(targetPath)}catch{existing=void 0}if(existing!==void 0){if(existing.equals(sourceBytes))continue;recordSkips.push({id,reason:`record-conflict:${fileName}`});continue}writeFileSync3(targetPath,sourceBytes)}}for(let cited of citedCopies){let sourceBytes=await readFile(cited.sourcePath),existing;try{existing=await readFile(cited.targetPath)}catch{existing=void 0}if(existing!==void 0){if(!existing.equals(sourceBytes))throw Error(`persist-out: cited run evidence .spur/run/${cited.name} diverges from the invoking `+"tree's existing file — refusing to overwrite; reconcile the two copies by hand (0984 R4)");continue}writeFileSync3(cited.targetPath,sourceBytes)}}return{ok:!0,persisted:persistedIds.length,skipped:[...skipped,...recordSkips,...citedSkips]}}finally{target.close()}}finally{source.close()}}async function createOrAttachInlineRun(input){let runId=input.runId.trim();if(runId==="")return{ok:!1,error:"inline run setup requires a non-empty runId (driver Run setup step 2)"};let workdir=resolve4(input.workdir),resolved;try{let projection=input.inventory===void 0?void 0:parseWorkflowInventory(input.inventory);if(projection&&!projection.ok)return projection;let inventory=projection?.ok?projection.inventory:void 0;if(inventory&&(!inventory.source||inventory.kind!=="state-machine"))return{ok:!1,error:"inline run setup requires a state-machine inventory with definition source"};if(resolved=await resolveWorkflowDefinition(workdir,inventory?.source?.path??input.file,{validateSchema:!0,...input.embeddedSchemas!==void 0?{embeddedSchemas:input.embeddedSchemas}:{},...!inventory?{registered:input.registered}:{}}),(resolved.workflow.kind??"state-machine")!=="state-machine")return{ok:!1,error:"inline run setup requires a state-machine definition"};if(inventory?.source){let identity5=assertInventoryIdentity(inventory,resolved.digest);if(!identity5.ok)return identity5;if(inventory.name!==resolved.workflow.name)return{ok:!1,error:"inline run setup: inventory workflow name does not match its definition"};resolved={...resolved,layer:inventory.source.layer}}}catch(error51){return{ok:!1,error:`inline run setup could not resolve the workflow definition: ${error51.message}`}}let digest=resolved.digest,version3=workflowVersionLiteral(resolved.workflow),source={path:resolved.path,layer:resolved.layer,workdir},db2=await input.getDb(),existing=await new RunDao(db2).traceRowById(runId);if(existing!==void 0){let metadata=parseIdentityMetadata(existing.metadata_json);if(metadata===null)return{ok:!1,error:`inline run setup refuses run ${runId}: its existing row has malformed metadata_json, `+"so its identity cannot be verified — delete the stale run row or allocate a new run id"};let resumeDigest=typeof metadata.resumeDefinitionDigest==="string"?metadata.resumeDefinitionDigest:void 0,launchDigest=typeof metadata.definitionDigest==="string"?metadata.definitionDigest:void 0,effectiveDigest=resumeDigest??launchDigest;if(effectiveDigest===void 0)return{ok:!1,error:`inline run setup refuses run ${runId}: its existing row carries no definition digest `+"(pre-identity legacy row) — allocate a new run id instead of attaching an unverifiable identity"};if(effectiveDigest!==digest)return{ok:!1,error:`inline run setup refuses run ${runId}: the resolved definition digest (${digest}) does not match the run's recorded ${resumeDigest!==void 0?"resume":""} digest (${effectiveDigest}) — `+"a changed definition must resume through the explicit resume rules, not silently re-attach"};if(existing.workflow_name!==resolved.workflow.name)return{ok:!1,error:`inline run setup refuses run ${runId}: the run row records workflow "${existing.workflow_name}" but the resolved definition is "${resolved.workflow.name}" — conflicting run identity`};if(typeof metadata.definitionSource!=="object"||metadata.definitionSource===null||Array.isArray(metadata.definitionSource))return{ok:!1,error:`inline run setup refuses run ${runId}: its existing row carries no definition source `+"(path/layer/workdir) — allocate a new run id instead of attaching an unverifiable launch source"};let existingSource=metadata.definitionSource;if(!(typeof existingSource.path==="string"&&resolve4(existingSource.path)===resolved.path&&normalizePersistedWorkflowLayer(existingSource.layer)===resolved.layer&&typeof existingSource.workdir==="string"&&resolve4(existingSource.workdir)===workdir))return{ok:!1,error:`inline run setup refuses run ${runId}: the recorded definition source (${JSON.stringify(existingSource)}) does not match the resolved launch source (${JSON.stringify(source)}) — conflicting project/workdir identity`};return{ok:!0,attached:!0,runId,workflowName:resolved.workflow.name,definitionDigest:digest,workflowVersion:version3,resolvedPath:resolved.path,layer:resolved.layer,workdir,status:existing.status}}return await new WorkflowService(createDefaultWorkflowEngineHost(),new DbWorkflowPersistenceAdapter(db2)).createOrAttachRun({id:runId,workflow_name:resolved.workflow.name,mode:"state-machine",status:"running",started_at:new Date().toISOString(),completed_at:null,metadata_json:JSON.stringify({definitionDigest:digest,workflowVersion:version3,definitionSource:source})}),{ok:!0,attached:!1,runId,workflowName:resolved.workflow.name,definitionDigest:digest,workflowVersion:version3,resolvedPath:resolved.path,layer:resolved.layer,workdir,status:"running"}}async function runDecideForInlineRun(input){let optionsFile=join6(resolve4(input.workdir),input.optionsFile),raw;try{raw=JSON.parse(await readFile(optionsFile,"utf8"))}catch(error51){return{ok:!1,error:`decide: unreadable options file ${input.optionsFile}: ${String(error51)}`}}let parsed=DecideOptionsSchema.safeParse(raw);if(!parsed.success)return{ok:!1,error:`decide: invalid options — ${parsed.error.issues.map((i2)=>i2.message).join("; ")}`};let result=await new DecideActionRunner(createNodeFileSystem2(),{enabled:input.enabled}).execute(raw,{runId:"inline-decide",stateOrNodeId:"decide",workdir:resolve4(input.workdir),vars:{},env:{}});if(!result.ok||result.data===void 0)return{ok:!1,error:result.error??"decide: action failed without an error message"};let decision=result.data.decision;return{ok:!0,value:decision.value,degraded:decision.degraded,reason:decision.reason,source:decision.source,backend:decision.backend,confidence:decision.confidence,resultFile:join6(resolve4(input.workdir),parsed.data.resultFile),durationMs:decision.durationMs}}import{basename as basename2,join as join7}from"node:path";var FEATURE_RECEIPT_SCHEMA_VERSION=1,DEFAULT_FEATURE_VERIFICATION_CMD="bun run spur-check-feature",RECEIPT_ID_PATTERN=/^[A-Za-z0-9][A-Za-z0-9._-]*$/;function assertReceiptId(kind,id){if(!RECEIPT_ID_PATTERN.test(id)||id.includes(".."))throw Error(`invalid ${kind} for receipt path: ${JSON.stringify(id)}`)}function featureReceiptPaths(runDir,featureId2,runId){return assertReceiptId("featureId",featureId2),assertReceiptId("runId",runId),{runScoped:join7(runDir,`${runId}-feature-verification.json`),featureScoped:join7(runDir,`${featureId2}-feature-verification.json`),log:join7(runDir,`${runId}-feature-verification.log`),status:join7(runDir,`${runId}-feature-verification.status`)}}async function atomicWriteReceipt(fs2,path8,receipt){let body=`${JSON.stringify(receipt,null,4)}
|
|
1488
1488
|
`,tmp=`${path8}.tmp`;await fs2.writeFile(tmp,body),await fs2.rename(tmp,path8)}async function startFeatureVerificationReceipt(fs2,runDir,options){let receipt={schemaVersion:FEATURE_RECEIPT_SCHEMA_VERSION,featureId:options.featureId,runId:options.runId,workdir:options.workdir,verifier:options.verifier,verificationCmd:options.verificationCmd,inputDigest:options.inputDigest,status:"RUNNING",startedAt:options.startedAt??new Date().toISOString().replace(/\.\d{3}Z$/,"Z"),completedAt:null},paths=featureReceiptPaths(runDir,options.featureId,options.runId);return await fs2.ensureDir(runDir),await atomicWriteReceipt(fs2,paths.runScoped,receipt),await atomicWriteReceipt(fs2,paths.featureScoped,receipt),receipt}async function completeFeatureVerificationReceipt(fs2,runDir,running,options){if(running.status!=="RUNNING")throw Error(`receipt for run ${running.runId} is already ${running.status}`);let receipt={...running,status:options.status,inputDigest:options.inputDigest??running.inputDigest,completedAt:options.completedAt??new Date().toISOString().replace(/\.\d{3}Z$/,"Z")},paths=featureReceiptPaths(runDir,receipt.featureId,receipt.runId);return await fs2.ensureDir(runDir),await atomicWriteReceipt(fs2,paths.runScoped,receipt),await atomicWriteReceipt(fs2,paths.featureScoped,receipt),await fs2.writeFile(paths.status,`${receipt.status}
|
|
1489
1489
|
`),receipt}function parseReceipt(raw){let parsed;try{parsed=JSON.parse(raw)}catch(err){throw Error(`not JSON (${String(err)})`)}if(parsed===null||typeof parsed!=="object")throw Error("not an object");let r=parsed;if(r.schemaVersion!==FEATURE_RECEIPT_SCHEMA_VERSION)throw Error(`schemaVersion must be ${FEATURE_RECEIPT_SCHEMA_VERSION}`);let v=r.verifier;if(typeof r.featureId!=="string"||typeof r.runId!=="string"||typeof r.workdir!=="string"||typeof v?.name!=="string"||typeof v?.sourcePath!=="string"||typeof v?.layer!=="string"||typeof v?.definitionDigest!=="string"||typeof r.verificationCmd!=="string"||typeof r.inputDigest!=="string"||r.status!=="RUNNING"&&r.status!=="PASS"&&r.status!=="FAIL"||typeof r.startedAt!=="string"||r.completedAt!==null&&typeof r.completedAt!=="string")throw Error("required fields missing or mistyped");return parsed}async function readReceiptCopy(fs2,path8,label){let raw;try{raw=await fs2.readFile(path8)}catch{throw Error(`no ${label} receipt at ${path8}; run the feature-scoped verification pass`)}try{return parseReceipt(raw)}catch(err){throw Error(`${label} receipt at ${basename2(path8)} is not a valid schema-v1 artifact (${String(err)})`)}}async function validateFeatureVerificationReceipt(fs2,options){let latest;try{latest=await readReceiptCopy(fs2,join7(options.runDir,`${options.featureId}-feature-verification.json`),"feature-latest")}catch(err){let message=String(err);return{ok:!1,reason:message.includes("not a valid")?"malformed":"missing",detail:message}}let paths=featureReceiptPaths(options.runDir,options.featureId,latest.runId);try{let runScoped=await readReceiptCopy(fs2,paths.runScoped,"run-scoped");if(JSON.stringify(runScoped)!==JSON.stringify(latest))return{ok:!1,reason:"divergent",detail:`run-scoped ${paths.runScoped} and feature-latest receipts disagree — a newer attempt started or the evidence was tampered with`}}catch(err){let message=String(err);return{ok:!1,reason:message.includes("not a valid")?"malformed":"missing",detail:message}}if(latest.featureId!==options.featureId)return{ok:!1,reason:"cross-feature",detail:`receipt belongs to feature "${latest.featureId}", not "${options.featureId}"`};if(latest.status==="FAIL")return{ok:!1,reason:"failed",detail:`verification pass recorded FAIL (started ${latest.startedAt}, ended ${latest.completedAt})`};if(latest.status==="RUNNING")return{ok:!1,reason:"run",detail:`verification pass is still RUNNING (started ${latest.startedAt}); no completion evidence exists`};if(options.runPort?.readRunRow){let row=await options.runPort.readRunRow(latest.runId);if(!row)return{ok:!1,reason:"run",detail:`run ${latest.runId} that recorded the receipt does not exist in the run store`};if(row.status!=="done")return{ok:!1,reason:"run",detail:`run ${latest.runId} is "${row.status}", not terminal done — the recording run never finished`};if(row.definitionDigest&&row.definitionDigest!==latest.verifier.definitionDigest)return{ok:!1,reason:"run",detail:`run ${latest.runId} attached with definition digest ${row.definitionDigest}, receipt records ${latest.verifier.definitionDigest}`};let recordedCmd;try{let vars=row.varsJson?JSON.parse(row.varsJson):void 0;if(vars&&typeof vars==="object"&&typeof vars.verificationCmd==="string")recordedCmd=vars.verificationCmd}catch{recordedCmd=void 0}if(recordedCmd!==void 0&&recordedCmd!==latest.verificationCmd)return{ok:!1,reason:"run",detail:`run ${latest.runId} recorded effective command "${recordedCmd}", receipt records "${latest.verificationCmd}"`};if(options.runPort.hasArtifact&&!await options.runPort.hasArtifact(latest.runId,paths.runScoped))return{ok:!1,reason:"run",detail:`receipt ${basename2(paths.runScoped)} is not registered as an artifact of run ${latest.runId}`}}let verifier=latest.verifier,current=options.currentVerifier,drifted=["name","layer","definitionDigest"].filter((k)=>verifier[k]!==current[k]);if(drifted.length>0)return{ok:!1,reason:"contract-mismatch",detail:`receipt recorded verifier ${verifier.name}@${verifier.layer} (${verifier.definitionDigest}), completion evaluates ${current.name}@${current.layer} (${current.definitionDigest}) — the selected definition changed after the pass (${drifted.join(", ")})`};if(latest.verificationCmd!==options.currentVerificationCmd)return{ok:!1,reason:"contract-mismatch",detail:`receipt recorded with verifier "${latest.verificationCmd}", completion evaluates the configured command "${options.currentVerificationCmd}"`};if(latest.inputDigest!==options.currentDigest)return{ok:!1,reason:"stale",detail:`receipt digest ${latest.inputDigest} ≠ current inputs ${options.currentDigest} — tree, spec, learnings or check contract changed after the pass`};return{ok:!0,receipt:latest}}async function captureFeatureReceiptDigest(repoRoot,featureContent,learningsContent){return ProofInputFingerprint.compute({cwd:repoRoot,featureContent,learningsContent})}var section_matrix_schema_default={$schema:"http://json-schema.org/draft-07/schema#",$id:"https://gobing.ai/spur/schemas/section-matrix.schema.json",title:"Section-Status-Matrix Schema",description:"Validates the shipped section-matrix.yaml — which sections are required/optional/forbidden per task status. Design §3.2. Authored for ts-runtime's loadStructuredConfig validator (supports properties/required/additionalProperties + $defs/$ref/enum; NOT patternProperties/uniqueItems).",type:"object",required:["variants"],additionalProperties:!1,properties:{$schema:{type:"string",description:"JSON Schema ref this file validates against (loadStructuredConfig reads it)."},variants:{type:"object",description:"Map of template variant → per-status matrix. Variant names are extensible (user-defined variants allowed); each value is a variant.",additionalProperties:{$ref:"#/$defs/variant"}}},$defs:{section:{enum:["Background","Requirements","Acceptance Criteria","Q&A","Design","Plan","Solution","Root Cause","Testing","Review","References","Notes","History"],description:"Canonical task section vocabulary (DD-08). Any other value is a typo."},sectionList:{type:"array",items:{$ref:"#/$defs/section"}},entry:{type:"object",additionalProperties:!1,properties:{required:{$ref:"#/$defs/sectionList"},optional:{$ref:"#/$defs/sectionList"},forbidden:{$ref:"#/$defs/sectionList"},gate:{type:"boolean"}}},variant:{type:"object",additionalProperties:!1,description:"A variant may declare any subset of the 7 canonical statuses (enumerated below); an unknown status key is rejected.",properties:{backlog:{$ref:"#/$defs/entry"},todo:{$ref:"#/$defs/entry"},wip:{$ref:"#/$defs/entry"},testing:{$ref:"#/$defs/entry"},blocked:{$ref:"#/$defs/entry"},done:{$ref:"#/$defs/entry"},cancelled:{$ref:"#/$defs/entry"}}}}};var spur_config_schema_default={$schema:"https://json-schema.org/draft/2020-12/schema",$id:"https://github.com/gobing-ai/spur/schemas/spur-config.schema.json",title:"Spur Project Configuration",description:"Schema for .spur/config.yaml — the single project configuration surface consumed by spur and (future) spur-server.",type:"object",properties:{$schema:{type:"string",description:"Reference to this schema for IDE validation. spur resolves this at runtime via loadStructuredConfig."},version:{type:"string",description:"Config schema version (string, not integer). Current recommended: '1.2' (config-1.2 layered global/project merge, ADR-033 executor tiers + planning blocks). '1' remains accepted for backward compatibility."},name:{type:"string",description:"Project name written by spur init."},bootstrap:{type:"object",description:"Portable bootstrap block consumed by @gobing-ai/ts-infra runNodeApplication. Shared across spur and spur-server.",properties:{logging:{type:"object",properties:{enabled:{type:"boolean",description:"Enable structured logging via LogTape."},level:{type:"string",enum:["trace","debug","info","warn","error","fatal"],description:"Minimum log level."},console:{type:"boolean",description:"Emit log records to console (stderr)."},json:{type:"boolean",description:"Format log records as JSON Lines. false = text format."},file:{type:"boolean",description:"Write log records to a file sink. Uses filePath when set, otherwise disabled."},filePath:{type:"string",description:"Path to the log file. Relative to project root. Default: .spur/logs/spur.log."}}},telemetry:{type:"object",properties:{enabled:{type:"boolean",description:"Enable OpenTelemetry tracing/metrics export."},serviceName:{type:"string",description:"Service name reported to OTel collectors."},environment:{type:"string",description:"Deployment environment label."}}},database:{type:"object",properties:{enabled:{type:"boolean",description:"Enable the SQLite database adapter."},driver:{type:"string",enum:["bun-sqlite"],description:"Database driver. Currently only bun-sqlite."},url:{type:"string",description:"Database file path. Supports ${DATABASE_URL} interpolation. Default: .spur/spur.db."}}},scheduler:{type:"object",properties:{enabled:{type:"boolean",description:"Enable the scheduled-task runner. OFF by default for CLI (run-once)."},jobs:{type:"array",description:"Declarative scheduled commands (task 0734). Each entry registers one scheduler tick that enqueues a `scheduler.custom` queue job running `command` through `/bin/sh -c`. Normalized and validated by @gobing-ai/ts-infra runNodeApplication before the server starts.",items:{type:"object",required:["name","command"],properties:{name:{type:"string",minLength:1,description:"Job name, unique across the list after trimming. Reported as the `scheduler.custom:<name>` display name on scheduler.job.executed."},command:{type:"string",minLength:1,description:"Shell command run by `/bin/sh -c` with the project root as cwd. Trusted operator input — never logged."},intervalMinutes:{type:"integer",minimum:1,maximum:35791,description:"Fixed interval in minutes. Mutually exclusive with `cron`. The upper bound is the Node timer ceiling (2147483647 ms)."},cron:{type:"string",minLength:1,description:"Five-field cron expression (minute hour day-of-month month day-of-week) evaluated in local time. Mutually exclusive with `intervalMinutes`."}},oneOf:[{required:["intervalMinutes"],not:{required:["cron"]}},{required:["cron"],not:{required:["intervalMinutes"]}}]}}}}}},agent:{type:"object",properties:{default:{type:"string",description:"Default role for `--agent auto` when nothing is declared (0542 R2). A role id (scribe, coder, reviewer, planner) selects its tier's cheapest eligible executor; a configured executor name still resolves during the transition with a one-time warning; any other value is rejected naming both accepted sets."},executors:{type:"array",description:"Named executor profiles: each pairs a canonical agent with an optional model override. Referenced by name from `agent.default` and stage model_policy (default-by-phase removed 0452).",items:{type:"object",required:["name","agent"],properties:{name:{type:"string",minLength:1,description:"Executor selector name (unique across the list)."},agent:{type:"string",minLength:1,description:"Canonical coding agent (claude, codex, gemini, pi, opencode, antigravity-cli, openclaw, hermes, omp)."},model:{type:"string",minLength:1,description:"Opaque model override passed straight to the agent (e.g. zai//glm-5.2). Applied only when the user passes no explicit --model."},tier:{type:"string",enum:["cheap","standard","capable-1","capable-2","capable-3"],description:"Capability tier for stage-registry adaptive model routing (ADR-033, 0343). Live values: cheap | standard | capable-1 | capable-2 | capable-3 (1=low output quality, 3=high within the capable band). A stage starts on the cheapest eligible executor meeting its model_policy min_tier. Bare legacy `capable` is accepted at runtime (zod preprocess → capable-1) during the deprecation window but is not part of this editor enum."},disabled:{description:"Routing kill-switch (111; ownership widened 0890): a disabled profile never serves a role, team, stage, or explicit selection, and doctor inventories it without probing. Omitted = enabled. Bare `true` is operator-owned (only humans write booleans); automatic writers emit the object form carrying owner (operator|quota|probe), since (RFC 3339) and reason.",anyOf:[{type:"boolean"},{type:"object",additionalProperties:!1,required:["owner","since","reason"],properties:{owner:{enum:["operator","quota","probe"]},since:{type:"string",format:"date-time",minLength:1},reason:{type:"string",minLength:1}}}]}}}},fleet:{type:"object",description:"The project's agent fleet (G65 / 0858): the single declaration of composition, the on/off switch, and the dispatch strategy. PROJECT LAYER ONLY — a global-layer agent.fleet fails the load. Replaces the retired .spur/fleet.json (0835) and agent.team (0857). Mirrors @gobing-ai/spur-config AgentFleetSchema (Zod is SSOT).",properties:{enabled:{type:"boolean",default:!1,description:"The single fleet switch. `spur serve` materializes and autostarts the roster only when true; an absent or disabled fleet starts nothing."},strategy:{type:"string",enum:["rest","gtd"],default:"rest",description:"Dispatch strategy, reconciled into project_strategy at serve start (0859). One name is added by a typed code change, not by config."},orchestrator:{type:"string",minLength:1,description:"memberLocalId of the one planner-role member carrying purpose: orchestrator. Absent = no orchestrator declared (never inferred)."},members:{type:"array",default:[],description:"The roster. Each member declares a role or an executor. `enabled: false` keeps the member's derived <role>-<n> id index but does not materialize it.",items:{type:"object",properties:{id:{type:"string",minLength:1,description:"Explicit stable id; wins over the derived <role>-<n> form."},role:{type:"string",enum:["scribe","coder","reviewer","planner"],description:"Layer-1 role id (closed vocabulary)."},executor:{type:"string",minLength:1,description:"Executor profile name or a raw canonical agent type."},purpose:{type:"string",description:"Free-form member purpose; `orchestrator` is the value the orchestrator pointer binds to."},enabled:{type:"boolean",description:"Default true. False preserves the member's derived id index without materializing it."}},anyOf:[{required:["role"]},{required:["executor"]}]}}}},roles:{type:"object",description:"Per-role tier/stage overrides over DEFAULT_AGENT_ROLES (0572 / ADR-061). Keys are the closed role vocabulary (scribe, coder, reviewer, planner); a present field replaces the default for that role, an omitted field keeps it. Mirrors @gobing-ai/spur-config AgentRoleConfigSchema (Zod is SSOT).",additionalProperties:{type:"object",properties:{tier:{type:"string",enum:["cheap","standard","capable-1","capable-2","capable-3"],description:"Replacement capability tier for the role. Must not sit below the highest min_tier among the role's folded stages (enforced at the CLI boundary)."},stages:{type:"array",minItems:1,items:{type:"string",minLength:1},description:"Replacement folded-stage list for the role. Ids must come from the canonical stage registry (validated at the CLI boundary). Omit the field to keep the default — an empty array is rejected."}}}}}},rules:{type:"object",properties:{paths:{type:"array",items:{type:"string"},description:"Glob paths to rule files."}}},workflows:{type:"object",properties:{paths:{type:"array",items:{type:"string"},description:"Glob paths to workflow directories."}}},redaction:{type:"object",properties:{enabled:{type:"boolean",description:"Enable sensitive-data redaction in CLI output."}}},history:{type:"object",description:"History import/analyze configuration (feature E3). Opt-in operation-triggered refresh.",properties:{refresh:{type:"object",properties:{on_completion:{type:"boolean",description:"Enqueue a coalesced history refresh when a task or pipeline run completes. Default false (opt-in; hidden automation is out of contract)."},debounce_ms:{type:"integer",minimum:0,description:"Coalescing window in milliseconds. Completions inside the window join one pending refresh. Default 60000."}}}}},builder:{type:"object",description:"Builder noun configuration. Currently hosts the release plumbing knobs for `spur builder bump-ver` / `drop-tags`; every field defaults to the built-in release convention, so an absent builder section keeps default behavior.",properties:{"bump-ver":{type:"object",description:"Release knobs for bump-ver/drop-tags. Defaults: -v separator, publish.yml workflow, chore(release) commit, gh run list limit 5.",properties:{aggregatePackage:{type:"string",minLength:1,description:'Package whose own release tag is the publish trigger for the aggregate (--all) path, as an unscoped package id (e.g. "spur" for @gobing-ai/spur). Default: the package whose full name equals the workspace root manifest name.'},tagVersionSeparator:{type:"string",minLength:1,description:'Release tag format: <package><separator><version>. Default "-v".'},publishWorkflow:{type:"string",minLength:1,description:'GitHub Actions workflow file the pushed release tag triggers. Default "publish.yml".'},releaseCommitType:{type:"string",minLength:1,description:'Conventional commit type for the release commit. Default "chore".'},releaseCommitScope:{type:"string",minLength:1,description:'Conventional commit scope for the release commit. Default "release".'},ghRunListLimit:{type:"integer",minimum:1,description:"gh run list --limit used to point at the triggered publish run. Default 5."},versionCarriers:{type:"array",description:"Extra version carriers beyond workspace package.json files. Default: none. Types are registered in apps/cli/src/version-carriers.ts (registerCarrierType), which validates instances at release time; registering a new type extends this description in the same commit.",items:{type:"object",description:"One carrier instance. Required field: type (string). Built-ins: plugin-manifest { paths: [..] } — repo-wide manifests synced to the release version (e.g. per-platform plugin.json mirrors); ts-literal { file?, identifier? } — version constant in a package source file (defaults src/config.ts / binaryVersion).",properties:{type:{type:"string",minLength:1}},required:["type"]}}}}}},tasks:{type:"object",description:"Task-folder registration (design §9). Absorbs the legacy docs/.tasks/config.json folders + baseCounter concepts. Mirrors @gobing-ai/spur-config tasksConfigSchema (Zod is SSOT).",properties:{folders:{type:"object",description:"Map of task-folder path → folder config.",additionalProperties:{type:"object",properties:{baseCounter:{type:"integer",minimum:0,description:"WBS base counter for new tasks in this folder. Default 0."},label:{type:"string",description:"Human-readable folder label."}}}},active:{type:"string",description:"Default folder for `spur task create`. Default: docs/tasks."},severity:{type:"object",description:"Rule severity overrides map by code (error | warning | off).",additionalProperties:{type:"string",enum:["error","warning","off"]}}}},features:{type:"object",description:"Feature directory location (design §9). Mirrors @gobing-ai/spur-config featuresConfigSchema (Zod is SSOT).",properties:{dir:{type:"string",description:"Feature files directory. Default: docs/features."}}}}};var state_machine_workflow_schema_default={$schema:"https://json-schema.org/draft/2020-12/schema",$id:"https://github.com/gobing-ai/spur/schemas/state-machine-workflow.schema.json",title:"@gobing-ai/ts-dual-workflow-engine State-machine Workflow",type:"object",additionalProperties:!1,required:["name","initialState","states","transitions"],properties:{$schema:{type:"string"},kind:{const:"state-machine"},name:{type:"string",minLength:1},version:{type:"string",minLength:1,description:"Optional behavior-neutral identity tag (0756). Absent = unversioned; present = a non-empty opaque literal surfaced as explicit(<literal>). Not parsed, ordered, or compatibility-checked; no registry."},description:{type:"string"},initialState:{type:"string",minLength:1},terminalStates:{type:"array",items:{type:"string",minLength:1}},failureStates:{type:"array",items:{type:"string",minLength:1},description:"Subset of terminalStates whose reach finalizes the run as failed. Absent ⇒ every terminal is a success."},iterationBound:{type:"integer",exclusiveMinimum:0},vars:{type:"object",propertyNames:{pattern:"^[A-Za-z_][A-Za-z0-9_]*$"},additionalProperties:{type:"string"}},env:{type:"object",additionalProperties:!1,properties:{allow:{type:"array",items:{type:"string",pattern:"^[A-Za-z_][A-Za-z0-9_]*$"}}}},extensions:{type:"object",additionalProperties:!1,properties:{actions:{type:"array",items:{$ref:"#/$defs/relativeExtensionPath"}},guards:{type:"array",items:{$ref:"#/$defs/relativeExtensionPath"}}}},states:{type:"array",items:{type:"object",additionalProperties:!1,required:["id"],properties:{id:{type:"string",minLength:1},description:{type:"string"},pause:{type:"boolean",description:"When true, the engine pauses the run at this state for HITL (E3); resume with `spur workflow continue`."},onEnter:{type:"array",items:{$ref:"#/$defs/action"}},onExit:{type:"array",items:{$ref:"#/$defs/action"}}}}},transitions:{type:"array",items:{type:"object",additionalProperties:!1,required:["from","to"],properties:{from:{type:"string",minLength:1},to:{type:"string",minLength:1},terminalReason:{type:"string",description:"Closed terminal-reason enum declared when this edge finalizes the run (0937 R3; required for edges into failureStates)."},description:{type:"string"},trigger:{type:"string"},guard:{$ref:"#/$defs/guard"}}}}},$defs:{action:{type:"object",additionalProperties:!1,required:["kind"],properties:{kind:{type:"string",minLength:1},options:{type:"object",additionalProperties:!0},onError:{type:"string",enum:["fail","continue"],description:"Per-action error handling policy: 'fail' halts the run; 'continue' logs the failure and proceeds so transition guards can route the outcome."}}},guard:{type:"object",additionalProperties:!1,required:["kind"],properties:{kind:{type:"string",minLength:1},options:{type:"object",additionalProperties:!0}}},relativeExtensionPath:{type:"string",minLength:1,description:"Relative module path; absolute paths and '..' traversal are forbidden.",not:{anyOf:[{pattern:"^[/\\\\]"},{pattern:"^[A-Za-z]:[/\\\\]"},{pattern:"(^|[/\\\\])\\.\\.([/\\\\]|$)"}]}}}};var transition_flow_workflow_schema_default={$schema:"https://json-schema.org/draft/2020-12/schema",$id:"https://github.com/gobing-ai/spur/schemas/transition-flow-workflow.schema.json",title:"@gobing-ai/ts-dual-workflow-engine Transition-flow Workflow",type:"object",additionalProperties:!1,required:["kind","name","initialNode","nodes","edges"],properties:{$schema:{type:"string"},kind:{const:"transition-flow"},name:{type:"string",minLength:1},version:{type:"string",minLength:1,description:"Optional behavior-neutral identity tag (0756). Absent = unversioned; present = a non-empty opaque literal surfaced as explicit(<literal>). Not parsed, ordered, or compatibility-checked; no registry."},description:{type:"string"},initialNode:{type:"string",minLength:1},terminalNodes:{type:"array",items:{type:"string",minLength:1}},iterationBound:{type:"integer",exclusiveMinimum:0},vars:{type:"object",propertyNames:{pattern:"^[A-Za-z_][A-Za-z0-9_]*$"},additionalProperties:{type:"string"}},env:{type:"object",additionalProperties:!1,properties:{allow:{type:"array",items:{type:"string",pattern:"^[A-Za-z_][A-Za-z0-9_]*$"}}}},extensions:{type:"object",additionalProperties:!1,properties:{actions:{type:"array",items:{$ref:"#/$defs/relativeExtensionPath"}},guards:{type:"array",items:{$ref:"#/$defs/relativeExtensionPath"}}}},nodes:{type:"array",items:{type:"object",additionalProperties:!1,required:["id"],properties:{id:{type:"string",minLength:1},description:{type:"string"},type:{enum:["action","gate","parallel","decision"]},action:{$ref:"#/$defs/action"}}}},edges:{type:"array",items:{type:"object",additionalProperties:!1,required:["from","to"],properties:{from:{type:"string",minLength:1},to:{type:"string",minLength:1},description:{type:"string"},condition:{$ref:"#/$defs/guard"}}}}},$defs:{action:{type:"object",additionalProperties:!1,required:["kind"],properties:{kind:{type:"string",minLength:1},options:{type:"object",additionalProperties:!0},onError:{type:"string",enum:["fail","continue"],description:"Per-action error handling policy: 'fail' halts the run; 'continue' logs the failure and proceeds so edge conditions can route the outcome."}}},guard:{type:"object",additionalProperties:!1,required:["kind"],properties:{kind:{type:"string",minLength:1},options:{type:"object",additionalProperties:!0}}},relativeExtensionPath:{type:"string",minLength:1,description:"Relative module path; absolute paths and '..' traversal are forbidden.",not:{anyOf:[{pattern:"^[/\\\\]"},{pattern:"^[A-Za-z]:[/\\\\]"},{pattern:"(^|[/\\\\])\\.\\.([/\\\\]|$)"}]}}}};var EMBEDDED_SPUR_SCHEMAS=new Map([["schemas/spur-config.schema.json",JSON.stringify(spur_config_schema_default)],["schemas/section-matrix.schema.json",JSON.stringify(section_matrix_schema_default)],["schemas/state-machine-workflow.schema.json",JSON.stringify(state_machine_workflow_schema_default)],["schemas/transition-flow-workflow.schema.json",JSON.stringify(transition_flow_workflow_schema_default)]]);export{validateFeatureVerificationReceipt,startFeatureVerificationReceipt,splitLaunchCommand,runDecideForInlineRun,resolveWorkflowDefinition,resolveDecideDecisionMakerEnabled,readProofInputContents,persistWorktreeRuns,openInlineRunProjectDb,featureReceiptPaths,createWorkflowActionTraceWriter,createOrAttachInlineRun,computeProofInputFingerprint,completeFeatureVerificationReceipt,captureFeatureReceiptDigest,RunDao,EMBEDDED_SPUR_SCHEMAS,DEFAULT_FEATURE_VERIFICATION_CMD,ArtifactDao};
|