agent-afk 0.1.0

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/dist/cli.mjs ADDED
@@ -0,0 +1,1607 @@
1
+ #!/usr/bin/env node
2
+ import{config as xc}from"dotenv";import{existsSync as Do,mkdirSync as Tc,renameSync as Ec}from"fs";import{join as K,dirname as Pc}from"path";import{homedir as Tr}from"os";function ce(){return K(Tr(),".afk")}function Lo(){return K(ce(),"agent-framework")}function Fo(){return K(Lo(),"forge-telemetry.jsonl")}function Uo(){return K(Lo(),"briefs")}function No(){return K(ce(),"skills")}function ae(){return K(ce(),"plugins")}function jo(){return K(process.cwd(),".afk")}function Bo(){return K(jo(),"skills")}function Mt(){return K(jo(),"plugins")}function F(){return K(ae(),".index.json")}function Me(){return K(ae(),"cache")}function Rt(e){return K(Me(),e)}function sn(){return K(ce(),"config")}function an(){return K(ce(),"state")}function Ho(){return K(ce(),"logs")}function _t(){return K(an(),"sessions")}function Er(){return K(an(),"todos")}function it(){return K(sn(),"afk.env")}function at(){return K(sn(),"afk.config.json")}function Wo(){return K(Tr(),".afk.env")}function ln(){return K(Tr(),".afk.config.json")}function Cc(){return K(ce(),"sessions")}function Ic(){return K(ce(),"todos")}function Ko(e,t){if(e!==t&&Do(e)&&!Do(t))try{Tc(Pc(t),{recursive:!0}),Ec(e,t)}catch{}}function Go(){Ko(Cc(),_t())}function zo(){Ko(Ic(),Er())}import{Command as Yy}from"commander";import Pr from"chalk";function Vo(){let e=process.env.FORCE_COLOR;if(e&&e.length>0)return;let t=process.env.NO_COLOR;if(t&&t.length>0){Pr.level=0;return}let n=process.env.CI;if(n&&n.length>0){Pr.level=0;return}process.stdout.isTTY||(Pr.level=0)}import Jt from"chalk";import Km from"ora";function $t(){return process.env.AFK_DEBUG==="1"||process.env.DEBUG==="1"}function W(...e){$t()&&console.log(...e)}var ke=class extends Error{constructor(t){super(t),this.name="AbortError"}},cn=class extends Error{constructor(n,r){super(n);this.timeoutMs=r;this.name="TimeoutError"}timeoutMs},fe=class extends Error{constructor(n,r,o,s){super(n);this.event=r;this.reason=o;this.name="HookBlockedError",s?.cause!==void 0&&(this.cause=s.cause)}event;reason;cause};var Ot=class extends Error{constructor(n,r,o){super(o??`${n} provider does not support AgentConfig.${r}.`);this.provider=n;this.field=r;this.name="UnsupportedProviderConfigError"}provider;field};var un=class{queue=[];waiters=[];closed=!1;error=null;push(t){if(this.closed)throw new Error("Cannot push to closed queue");if(process.env.AFK_CODEX_DEBUG&&console.log("[queue] push:",t.type),W("\u{1F4E6} MessageQueue.push: event type=",t.type,"waiters=",this.waiters.length,"queue size=",this.queue.length),this.waiters.length>0){let n=this.waiters.shift();W("\u{1F4E6} MessageQueue.push: Resolving waiter immediately"),n?.({value:t,done:!1})}else this.queue.push(t),W("\u{1F4E6} MessageQueue.push: Added to queue, new size=",this.queue.length)}complete(){for(this.closed=!0;this.waiters.length>0;)this.waiters.shift()?.({value:void 0,done:!0})}fail(t){this.error=t,this.closed=!0;let n={type:"error",error:t};if(this.waiters.length>0)for(this.waiters.shift()?.({value:n,done:!1});this.waiters.length>0;)this.waiters.shift()?.({value:void 0,done:!0});else this.queue.push(n)}isClosed(){return this.closed}hasError(){return this.error}size(){return this.queue.length}async*[Symbol.asyncIterator](){for(W("\u{1F4E6} MessageQueue: Iterator started");;){if(this.queue.length>0){let n=this.queue.shift();if(W("\u{1F4E6} MessageQueue: Yielding queued event, type=",n?.type),n&&(yield n,n.type==="error")){W("\u{1F4E6} MessageQueue: Stopping after error");return}continue}if(this.closed){W("\u{1F4E6} MessageQueue: Closed and empty, stopping");return}W("\u{1F4E6} MessageQueue: Waiting for next event...");let t=await new Promise(n=>{this.waiters.push(n)});if(W("\u{1F4E6} MessageQueue: Got result, done=",t.done,"type=",t.value?.type),t.done)return;if(yield t.value,t.value.type==="error"){W("\u{1F4E6} MessageQueue: Stopping after error");return}}}};import Dp from"@anthropic-ai/sdk";var Ac="claude-code-20250219,oauth-2025-04-20",Mc="claude-cli/1.0.0 (external, cli)",Rc="x-anthropic-billing-header: cc_version=1.0.0.test; cc_entrypoint=cli; cch=00000;";function Yo(e){return e.startsWith("sk-ant-oat01-")?"oauth":"api-key"}function qo(e,t){return t==="oauth"?{authToken:e}:{apiKey:e}}function Cr(e,t,n){return e!=="oauth"?{}:{"anthropic-beta":Ac,"x-app":"cli","User-Agent":Mc,"X-Claude-Code-Session-Id":t,"x-client-request-id":n}}function Jo(e){return e!=="oauth"?null:[{type:"text",text:Rc}]}import{randomUUID as zr}from"node:crypto";function dn(){let e=process.env.AFK_DISABLE_PROMPT_CACHE;if(e===void 0||e.length===0)return!0;let t=e.toLowerCase();return!(t==="1"||t==="true"||t==="yes"||t==="on")}function pn(){let e=process.env.AFK_PROMPT_CACHE_TTL;return e==="5m"?"5m":"1h"}function Qo(e,t){if(e.length===0)return e;let n=e[e.length-1],r=Zo(n,t);return r===n?e:[...e.slice(0,-1),r]}function Xo(e,t){if(e.length===0)return e;let n=e[e.length-1],r=_c(n,t);return r===n?e:[...e.slice(0,-1),r]}function _c(e,t){let n=e.content;if(typeof n=="string")return n.length===0?e:{...e,content:[{type:"text",text:n,cache_control:{type:"ephemeral",ttl:t}}]};if(!Array.isArray(n)||n.length===0)return e;let r=n[n.length-1],o=Zo(r,t);return o===r?e:{...e,content:[...n.slice(0,-1),o]}}function Zo(e,t){return e.type==="thinking"||e.type==="redacted_thinking"?e:{...e,cache_control:{type:"ephemeral",ttl:t}}}import{randomUUID as Dc}from"node:crypto";function es(e,t){if(!e)return{stopReason:t??null};let n={inputTokens:e.input_tokens,outputTokens:e.output_tokens,stopReason:t??null};return e.cache_read_input_tokens!=null&&(n.cachedInputTokens=e.cache_read_input_tokens),e.cache_creation_input_tokens!=null&&(n.cacheCreationTokens=e.cache_creation_input_tokens),n.totalTokens=(e.input_tokens??0)+(e.output_tokens??0),n}function ts(e,t){let n=(c,u)=>{if(!(c==null&&u==null))return(c??0)+(u??0)},r={stopReason:t.stopReason??e.stopReason??null},o=n(e.inputTokens,t.inputTokens);o!==void 0&&(r.inputTokens=o);let s=n(e.outputTokens,t.outputTokens);s!==void 0&&(r.outputTokens=s);let a=n(e.cachedInputTokens,t.cachedInputTokens);a!==void 0&&(r.cachedInputTokens=a);let i=n(e.cacheCreationTokens,t.cacheCreationTokens);i!==void 0&&(r.cacheCreationTokens=i);let l=n(e.totalTokens,t.totalTokens);return l!==void 0&&(r.totalTokens=l),r}function $c(e){let t=e.trim();if(t.length===0)return{};try{return JSON.parse(t)}catch{return{}}}function Oc(e,t,n){let r=[],o=[];for(let i of e)i&&(i.kind==="text"?(r.push({type:"text",text:i.text}),o.push(i.text)):i.kind==="thinking"?r.push({type:"thinking",thinking:i.thinking,signature:i.signature}):r.push({type:"tool_use",id:i.id,name:i.name,input:$c(i.partialJson)}));let s=i=>i.type==="tool_use",a=r.filter(s);return{stopReason:t,assistantBlocks:r,toolUseBlocks:a,usage:n,text:o.join("")}}async function*ns(e,t){let n=[],r=null,o=null,s=!1;try{for await(let a of e){switch(a.type){case"message_start":{let i=a.message?.usage;i&&(o={...i});break}case"content_block_start":{let i=a.content_block;i.type==="text"?n[a.index]={kind:"text",text:""}:i.type==="thinking"?n[a.index]={kind:"thinking",thinking:"",signature:""}:i.type==="tool_use"&&(n[a.index]={kind:"tool_use",id:i.id,name:i.name,partialJson:""});break}case"content_block_delta":{let i=n[a.index],l=a.delta;l.type==="text_delta"?(i&&i.kind==="text"&&(i.text+=l.text),yield{kind:"event",event:{type:"delta.text",text:l.text,sessionId:t.sessionId}}):l.type==="input_json_delta"?i&&i.kind==="tool_use"&&(i.partialJson+=l.partial_json):l.type==="thinking_delta"?(i&&i.kind==="thinking"&&(i.thinking+=l.thinking),yield{kind:"event",event:{type:"delta.reasoning",text:l.thinking,sessionId:t.sessionId}}):l.type==="signature_delta"&&i&&i.kind==="thinking"&&(i.signature=l.signature);break}case"content_block_stop":{let i=n[a.index];i&&i.kind==="tool_use"&&(yield{kind:"event",event:{type:"tool.use",summary:i.name,toolUseIds:[i.id],sessionId:t.sessionId}});break}case"message_delta":{a.delta&&a.delta.stop_reason!==void 0&&(r=a.delta.stop_reason);let i=a.usage;i&&(o!==null?(o.output_tokens=i.output_tokens,i.cache_creation_input_tokens!=null&&(o.cache_creation_input_tokens=i.cache_creation_input_tokens),i.cache_read_input_tokens!=null&&(o.cache_read_input_tokens=i.cache_read_input_tokens),i.input_tokens!=null&&(o.input_tokens=i.input_tokens)):o={cache_creation:null,cache_creation_input_tokens:i.cache_creation_input_tokens??null,cache_read_input_tokens:i.cache_read_input_tokens??null,inference_geo:null,input_tokens:i.input_tokens??0,output_tokens:i.output_tokens,server_tool_use:null,service_tier:null});break}case"message_stop":{s=!0;break}default:break}if(s)break}}catch(a){yield{kind:"event",event:{type:"error",error:a instanceof Error?a:new Error(String(a))}};return}yield{kind:"turn-result",result:Oc(n,r,o)}}var Lc=0;function Fc(e){if(!e||typeof e!="object")return"";let t=e,n=t.file_path??t.path??t.filePath;if(typeof n=="string")return" "+n;let r=t.command??t.cmd;if(typeof r=="string"){let s=r.split(`
3
+ `)[0];return" "+(s.length>80?s.slice(0,77)+"\u2026":s)}let o=t.query??t.pattern??t.url??t.description;return typeof o=="string"?" "+o:""}async function*rs(e){let t=e.maxToolUseIterations??Lc,n={stopReason:null},r=0,o=Dc(),s=Date.now();for(;;){if(e.signal.aborted)return;let a=dn()?Xo(e.messages,pn()):e.messages,i={model:e.model,max_tokens:e.maxTokens,messages:a,stream:!0,...e.system!==null?{system:e.system}:{},...e.tools!==null&&e.tools.length>0?{tools:e.tools}:{}},l;try{l=await Promise.resolve(e.client.messages.create(i,{headers:e.headers,signal:e.signal}))}catch(h){if(e.signal.aborted)return;yield{type:"error",error:h instanceof Error?h:new Error(String(h))};return}let c=null,u=!1;try{for await(let h of ns(l,e.ctx))if(h.kind==="event"){if(h.event.type==="error"){yield h.event,u=!0;break}yield h.event}else{c=h.result;break}}catch(h){if(e.signal.aborted)return;yield{type:"error",error:h instanceof Error?h:new Error(String(h))};return}if(u)return;if(c===null){yield{type:"turn.completed",usage:n,sessionId:e.ctx.sessionId};return}if(n=ts(n,es(c.usage,c.stopReason)),c.stopReason!=="tool_use"){c.text.length>0&&(yield{type:"assistant.message",text:c.text,sessionId:e.ctx.sessionId},c.text.length<=200&&(yield{type:"suggestion",suggestion:c.text,sessionId:e.ctx.sessionId})),yield{type:"turn.completed",usage:n,sessionId:e.ctx.sessionId};return}e.messages.push({role:"assistant",content:c.assistantBlocks});let p=[];for(let h of c.toolUseBlocks)p.push({id:h.id,name:h.name,input:h.input,signal:e.signal}),yield{type:"tool.use.start",toolUseId:h.id,toolName:h.name,toolInput:Fc(h.input),sessionId:e.ctx.sessionId};if(e.signal.aborted)return;let m;if(e.toolDispatcher.executeBatch)m=await e.toolDispatcher.executeBatch(p);else{m=[];for(let h of p){if(e.signal.aborted){m.push({content:"Tool call aborted",isError:!0});continue}try{m.push(await e.toolDispatcher.execute(h))}catch(b){let v=b instanceof Error?b.message:String(b);m.push({content:`Tool execution threw: ${v}`,isError:!0})}}}let f=[];for(let h=0;h<p.length;h++){let b=p[h],v=m[h];yield{type:"tool.output",toolUseId:b.id,content:v.content,...v.isError===!0?{isError:!0}:{},sessionId:e.ctx.sessionId},f.push({type:"tool_result",tool_use_id:b.id,content:v.content,...v.isError===!0?{is_error:!0}:{}})}let g={role:"user",content:f};e.messages.push(g),r+=1;let y=c.toolUseBlocks[c.toolUseBlocks.length-1];if(yield{type:"progress",progress:{taskId:o,description:"Tool-use loop",summary:`Iteration ${r}: used ${y?.name??"unknown"}`,lastToolName:y?.name,totalTokens:n.totalTokens??0,toolUses:r,durationMs:Date.now()-s},sessionId:e.ctx.sessionId},t>0&&r>=t){yield{type:"turn.completed",usage:{...n,stopReason:"tool_use_loop_capped"},sessionId:e.ctx.sessionId};return}}}var Uc=["You are a conversation-summarization assistant. The user will paste a","prior conversation between a user and an AI assistant that includes tool","calls and tool results. Produce a concise but complete summary that lets","the AI continue the conversation without losing track.","","Preserve, in this priority order:","1. The user's original intent, explicit asks, constraints, corrections,"," and preferences stated during the conversation.","2. Tool decisions and their outcomes \u2014 file paths read or written, shell"," commands run, search queries, URLs fetched, code edits made, tests"," run, errors observed, and whether each action succeeded or failed.","3. Current state: what has been completed, what remains unresolved, and"," the safest next action.","4. Open questions, pending decisions, blockers, and assumptions.","5. Key facts the assistant discovered (function locations, schemas,"," observed behaviors, important external findings).","","Drop prose narration, conversational filler, and exploratory dead-ends.","Drop verbatim tool output unless an exact snippet, error, path, command,","or result is needed for continuation.","Do not invent details. If something is uncertain, mark it explicitly.","Output plain text, no markdown headers. Aim for ~250 words; use up to","~400 only when needed to preserve tool state or unresolved tasks."].join(`
4
+ `),os="[Compacted summary of earlier conversation]",ss="Acknowledged. Continuing from the summary above.";function Nc(e){if(e.role!=="user")return!1;let t=e.content;if(typeof t=="string")return!0;if(!Array.isArray(t))return!1;for(let n of t)if(n.type==="tool_result")return!1;return!0}function is(e,t){if(t<=0)return e.length;let n=0;for(let r=e.length-1;r>=0;r--){let o=e[r];if(o&&Nc(o)&&(n+=1,n===t))return r}return-1}function as(e,t,n){let r=jc(e);return{model:t,max_tokens:n,system:Uc,messages:[{role:"user",content:`Summarize the following conversation transcript. Follow the system instructions exactly.
5
+
6
+ <transcript>
7
+ `+r+`
8
+ </transcript>`}],stream:!0}}function ls(e,t,n){return[{role:"user",content:os+`
9
+
10
+ `+n},{role:"assistant",content:ss},...e.slice(t)]}function cs(e,t,n){let r=Bc(e.slice(0,t)),o=os.length+2+n.length+ss.length,s=Math.max(0,r-o);return Math.round(s/4)}function jc(e){let t=[];for(let n of e){let r=n.role==="user"?"User":"Assistant";if(t.push(r+":"),typeof n.content=="string")t.push(n.content);else if(Array.isArray(n.content))for(let o of n.content){let s=o.type;if(s==="text"&&"text"in o)t.push(o.text);else if(s==="tool_use"){let a=o.name??"unknown",i=us(o.input);t.push(`[tool call: ${a} ${i}]`)}else if(s==="tool_result"){let a=o.content;t.push(`[tool result: ${ds(a)}]`)}else s==="image"?t.push("[image]"):s==="document"&&t.push("[document]")}t.push("")}return t.join(`
11
+ `).trim()}function us(e){try{let t=JSON.stringify(e);return t.length>240?t.slice(0,237)+"...":t}catch{return"{}"}}function ds(e){if(typeof e=="string")return e.length>320?e.slice(0,317)+"...":e;if(Array.isArray(e)){let t=[];for(let r of e)r.type==="text"&&"text"in r&&t.push(r.text);let n=t.join(" ");return n.length>320?n.slice(0,317)+"...":n}return""}function Bc(e){let t=0;for(let n of e)if(typeof n.content=="string")t+=n.content.length;else if(Array.isArray(n.content))for(let r of n.content){let o=r.type;o==="text"&&"text"in r?t+=r.text.length:o==="tool_use"?t+=us(r.input).length:o==="tool_result"&&(t+=ds(r.content).length)}return t}import{z}from"zod";import{mkdir as Os,appendFile as Ds}from"fs/promises";import{join as Ut}from"path";var ps={"audit-fit":{"01-skill-inspector.md":`# Skill Inspector
12
+
13
+ You are an inspector auditing skills for correct type categorization. Skills come from two sources:
14
+ - **User-scope** \u2014 authored directly by the user under \`~/.afk/skills/<name>/SKILL.md\`
15
+ - **Plugin-scope** \u2014 shipped by an installed plugin under \`~/.afk/plugins/<plugin>/skills/<name>/SKILL.md\`
16
+
17
+ The handler has already discovered every skill path in TypeScript and templates them into the section below. **Do not Glob**; just read each path and emit a verdict.
18
+
19
+ ## Task
20
+
21
+ For each skill path, read the SKILL.md and extract:
22
+ - Frontmatter: \`disable-model-invocation\`, \`argument-hint\`
23
+ - Body length (word count)
24
+ - Presence of \`scripts/\`, \`references/\`, \`assets/\` subdirectories
25
+ - Orchestration language indicators (sub-agent dispatch, decision branching, multi-step workflow)
26
+ - Progressive-disclosure value (does the body teach a methodology that benefits from multi-prompt loading?)
27
+
28
+ For each skill, apply the decision heuristics and return a JSON verdict with the matching \`source\` and (for plugin-scope) \`plugin_key\` from the templated section.
29
+
30
+ ## Decision Heuristics (Authoritative)
31
+
32
+ **Skill is correct** if it meets ANY of:
33
+ - Has \`scripts/\` OR \`references/\` subdirectory (supporting resources)
34
+ - Body >200 words AND demonstrates progressive-disclosure value (multi-prompt structure teaches methodology; reader benefits from incremental loading)
35
+ - Clear model-chosen activation lift (Claude auto-invokes when the task description matches the skill's domain)
36
+
37
+ **Skill \u2192 command (misfit)** if ALL of:
38
+ - \`disable-model-invocation: true\`
39
+ - No \`scripts/\` or \`references/\` subdirectory
40
+ - Body <150 words
41
+
42
+ **Outliers** (orthogonal to misfit):
43
+ - Body >1000 words (split candidate \u2014 too large for one skill)
44
+ - Missing frontmatter (required \`name\`, \`description\`)
45
+ - Duplicate frontmatter keys
46
+
47
+ ## Output Format
48
+
49
+ End your response with a single fenced JSON array containing one verdict object per skill. The runtime extracts the structured output from the last fenced JSON block in your response, so this array must be the final fenced block:
50
+
51
+ \`\`\`json
52
+ [
53
+ {
54
+ "path": "<absolute path from the templated list>",
55
+ "type": "skill",
56
+ "source": "user|plugin",
57
+ "plugin_key": "<key from the templated list, omit when source is user>",
58
+ "verdict": "correct|misfit|outlier",
59
+ "recommended_type": "skill|command",
60
+ "rationale": "...",
61
+ "confidence": "high|med|low"
62
+ }
63
+ ]
64
+ \`\`\`
65
+
66
+ Emit one entry per skill discovered.
67
+
68
+ ## Tools
69
+
70
+ Use Read, Grep, Glob only. Do not use Edit, Write, or Bash. Use Glob only when you need to inspect a skill's \`scripts/\`/\`references/\`/\`assets/\` subdirectories \u2014 never to discover additional skills (the list below is exhaustive).
71
+
72
+ ## Process
73
+
74
+ 1. Iterate the templated skill list below.
75
+ 2. Read each SKILL.md.
76
+ 3. Extract the signals above.
77
+ 4. Apply the heuristics.
78
+ 5. Emit a JSON verdict per skill, copying \`source\` and \`plugin_key\` straight from the list entry.
79
+ `,"02-command-inspector.md":`# Command Inspector
80
+
81
+ You are an inspector auditing commands for correct type categorization. Commands come from two sources:
82
+ - **User-scope** \u2014 authored directly by the user under \`~/.afk/commands/<name>.md\`
83
+ - **Plugin-scope** \u2014 shipped by an installed plugin under \`~/.afk/plugins/<plugin>/commands/<name>.md\`
84
+
85
+ The handler has already discovered every command path in TypeScript and templates them into the section below. **Do not Glob**; just read each path and emit a verdict.
86
+
87
+ ## Task
88
+
89
+ For each command path, read the file and extract:
90
+ - \`\${ARGUMENTS}\` usage pattern (parameterized or hardcoded)
91
+ - Body length (word count)
92
+ - Orchestration language (mentions of sub-agent dispatch, multi-step workflows, decision branching)
93
+ - User-triggered workflow (is this a user-initiated request or automatic behavior?)
94
+
95
+ For each command, apply the decision heuristics and return a JSON verdict with the matching \`source\` and (for plugin-scope) \`plugin_key\` from the templated section.
96
+
97
+ ## Decision Heuristics (Authoritative)
98
+
99
+ **Command is correct** if:
100
+ - User-triggered static prompt, no orchestration, minimal branching
101
+ - Single step or closely coupled multi-step (e.g., fetch data + format)
102
+
103
+ **Command \u2192 skill (misfit)** if:
104
+ - Body describes multi-step workflow with decision points
105
+ - Explicitly dispatches sub-agents or agents
106
+ - Benefits from progressive disclosure (body teaches methodology that incremental prompt-loading would benefit)
107
+ - Has significant branching logic based on context
108
+
109
+ **Note:** Commands are back-compat aliases for skills (as of 2026); new multi-step work should use skills.
110
+
111
+ **Outliers**:
112
+ - Empty body (broken command)
113
+ - Duplicate frontmatter
114
+ - Unresolved variable references
115
+
116
+ ## Output Format
117
+
118
+ End your response with a single fenced JSON array containing one verdict object per command. The runtime extracts the structured output from the last fenced JSON block in your response, so this array must be the final fenced block:
119
+
120
+ \`\`\`json
121
+ [
122
+ {
123
+ "path": "<absolute path from the templated list>",
124
+ "type": "command",
125
+ "source": "user|plugin",
126
+ "plugin_key": "<key from the templated list, omit when source is user>",
127
+ "verdict": "correct|misfit|outlier",
128
+ "recommended_type": "skill|command",
129
+ "rationale": "...",
130
+ "confidence": "high|med|low"
131
+ }
132
+ ]
133
+ \`\`\`
134
+
135
+ Emit one entry per command discovered.
136
+
137
+ ## Tools
138
+
139
+ Use Read, Grep, Glob only. Do not use Edit, Write, or Bash. Do not Glob to discover commands \u2014 the list below is exhaustive.
140
+
141
+ ## Process
142
+
143
+ 1. Iterate the templated command list below.
144
+ 2. Read each file.
145
+ 3. Extract the signals above.
146
+ 4. Apply the heuristics.
147
+ 5. Emit a JSON verdict per command, copying \`source\` and \`plugin_key\` straight from the list entry.
148
+ `,"03-agent-inspector.md":`# Agent Inspector
149
+
150
+ You are an inspector auditing agents for correct type categorization. Agents come from two sources:
151
+ - **User-scope** \u2014 authored directly by the user under \`~/.afk/agents/<name>.md\`
152
+ - **Plugin-scope** \u2014 shipped by an installed plugin under \`~/.afk/plugins/<plugin>/agents/<name>.md\`
153
+
154
+ The handler has already discovered every agent path in TypeScript and templates them into the section below. **Do not Glob**; just read each path and emit a verdict.
155
+
156
+ ## Task
157
+
158
+ For each agent path, read the file and extract:
159
+ - Frontmatter: \`tools\` whitelist, \`model\` override
160
+ - Body length (word count)
161
+ - Isolation rationale (does the body explain why isolated context is needed?)
162
+ - Tool restrictions (does frontmatter restrict which tools are allowed?)
163
+ - Whether the agent references any tools in the prompt
164
+
165
+ For each agent, apply the decision heuristics and return a JSON verdict with the matching \`source\` and (for plugin-scope) \`plugin_key\` from the templated section.
166
+
167
+ ## Decision Heuristics (Authoritative)
168
+
169
+ **Agent is correct** if it meets ANY of:
170
+ - Needs isolated context (body explains isolation requirement, e.g., "prevent side effects", "sandbox", "independent reasoning")
171
+ - Has \`tools\` whitelist in frontmatter (explicit tool restriction)
172
+ - Has \`model\` override in frontmatter (different model for this isolated task)
173
+
174
+ **Agent \u2192 skill with \`context: fork\` (misfit)** if ALL of:
175
+ - NO \`tools\` whitelist in frontmatter (no tool restriction)
176
+ - NO \`model\` override in frontmatter
177
+ - Body is a plain prompt with no isolation rationale
178
+ - Does not reference specific tools to restrict
179
+
180
+ **Outliers**:
181
+ - References no tools at all (not task-specific; borderline wrong domain)
182
+ - Missing frontmatter
183
+ - Malformed YAML
184
+
185
+ ## Output Format
186
+
187
+ End your response with a single fenced JSON array containing one verdict object per agent. The runtime extracts the structured output from the last fenced JSON block in your response, so this array must be the final fenced block:
188
+
189
+ \`\`\`json
190
+ [
191
+ {
192
+ "path": "<absolute path from the templated list>",
193
+ "type": "agent",
194
+ "source": "user|plugin",
195
+ "plugin_key": "<key from the templated list, omit when source is user>",
196
+ "verdict": "correct|misfit|outlier",
197
+ "recommended_type": "skill|agent",
198
+ "rationale": "...",
199
+ "confidence": "high|med|low"
200
+ }
201
+ ]
202
+ \`\`\`
203
+
204
+ Emit one entry per agent discovered.
205
+
206
+ ## Tools
207
+
208
+ Use Read, Grep, Glob only. Do not use Edit, Write, or Bash. Do not Glob to discover agents \u2014 the list below is exhaustive.
209
+
210
+ ## Process
211
+
212
+ 1. Iterate the templated agent list below.
213
+ 2. Read each file.
214
+ 3. Extract the signals above.
215
+ 4. Apply the heuristics.
216
+ 5. Emit a JSON verdict per agent, copying \`source\` and \`plugin_key\` straight from the list entry.
217
+ `,"04-hook-inspector.md":`# Hook Inspector
218
+
219
+ You are an inspector auditing pre-discovered AFK hooks for correct type categorization. In the agent-afk runtime, hooks live in \`~/.afk/settings.json\` (mirroring Claude Code's \`~/.claude/settings.json\` shape), but the entries you must audit have already been pre-read and inlined into the **Discovered hooks** section appended to this prompt. Use only those entries \u2014 do **not** Read the settings file yourself, and do **not** transform \`~\` into a guessed home directory. Hooks are always **user-scope** \u2014 plugins do not contribute hooks at this layer.
220
+
221
+ ## Task
222
+
223
+ For each hook listed in the **Discovered hooks** section:
224
+ - Note its event type (SessionStart, SubagentStop, etc.) \u2014 encoded in the hook ID as \`<event>-<index>\`
225
+ - Read the referenced script file. The script path appears inside the inlined \`command\` field; use it verbatim and do not alter \`~\` (script paths in settings.json are typically already absolute)
226
+ - Determine if the script performs deterministic side-effects (logging, telemetry, enforcement) vs. reasoning content
227
+
228
+ For each hook, apply the decision heuristics and return a JSON verdict.
229
+
230
+ ## Decision Heuristics (Authoritative)
231
+
232
+ **Hook is correct** if it performs deterministic side-effects:
233
+ - Logging, telemetry, metrics recording
234
+ - Enforcement (permission checks, validation)
235
+ - Simple state transitions (flag setting, cleanup)
236
+ - No model reasoning required
237
+
238
+ **Hook \u2192 skill (misfit)** if:
239
+ - Script describes model reasoning or decision logic
240
+ - Body describes multi-step workflow with decision points
241
+ - Could benefit from tool access or Claude's judgment
242
+ - Contains natural language instruction that looks like a prompt
243
+
244
+ **Outliers**:
245
+ - Broken reference (script doesn't exist)
246
+ - Malformed hook configuration
247
+ - Event type not recognized
248
+
249
+ ## Output Format
250
+
251
+ End your response with a single fenced JSON array containing one verdict object per hook. Use the absolute settings-file path provided in the Discovered hooks section as the \`path\` field \u2014 never substitute a tilde-prefixed form. Always set \`source: "user"\` (hooks have no plugin scope). The runtime extracts the structured output from the last fenced JSON block in your response, so this array must be the final fenced block:
252
+
253
+ \`\`\`json
254
+ [
255
+ {
256
+ "path": "<absolute settings.json path from Discovered hooks section>",
257
+ "hook_id": "<event_type>-<index>",
258
+ "type": "hook",
259
+ "source": "user",
260
+ "verdict": "correct|misfit|outlier",
261
+ "recommended_type": "hook|skill",
262
+ "rationale": "...",
263
+ "confidence": "high|med|low"
264
+ }
265
+ ]
266
+ \`\`\`
267
+
268
+ Emit one entry per hook discovered.
269
+
270
+ ## Tools
271
+
272
+ Use Read, Grep, Glob only. Do not use Edit, Write, or Bash.
273
+
274
+ ## Process
275
+
276
+ 1. Iterate the entries in the **Discovered hooks** section (one entry per hook ID)
277
+ 2. Extract the \`command\` (or other script reference) field from the inlined entry
278
+ 3. Read the referenced script file using the path as written
279
+ 4. Extract the signals above
280
+ 5. Apply the heuristics
281
+ 6. Emit JSON verdicts
282
+ `},diagnose:{"hypothesis.md":`# Hypothesis Synthesis Prompt
283
+
284
+ You are synthesizing ranked hypotheses from parallel research findings (codebase analysis + git history audit).
285
+
286
+ Given:
287
+ - Research findings from codebase investigation (code paths, logic issues, type mismatches)
288
+ - Research findings from git history (recent commits, blame info, dependency changes)
289
+ - The original failure description and reproducer
290
+
291
+ Your job:
292
+ 1. Cross-reference findings from both research subagents
293
+ 2. Group related findings into coherent root-cause hypotheses
294
+ 3. Rank them by confidence (evidence quality + relevance)
295
+ 4. Generate 2\u20134 hypotheses maximum (HARD CAP at 4)
296
+ 5. For each hypothesis, specify:
297
+ - A short claim (what is broken)
298
+ - A specific code location (where to look)
299
+ - A proposed minimal fix (what change would validate it)
300
+ - Confidence score (0\u20131)
301
+ - Evidence sources (which findings support this hypothesis)
302
+ - \`coverage_gaps\` (optional): things you could not read or verify that would strengthen the hypothesis \u2014 list as strings, leave empty/omitted when there are none. Be honest; "none" is a valid answer.
303
+ - \`boundary_flag\` (optional): set to a short string when you hit an epistemic boundary (timeout, blocked tool, ambiguous evidence) that the caller should know about; omit when none.
304
+
305
+ These epistemic fields feed a downstream confidence gate: low-confidence, gap-bearing, or boundary-flagged hypotheses get independently re-checked by /shadow-verify before worktree testing. Reporting gaps honestly is rewarded, not penalized \u2014 a confident claim with an unresolved gap is more useful than a confident claim that hides one.
306
+
307
+ Output as JSON conforming to:
308
+ \`\`\`json
309
+ {
310
+ "hypotheses": [
311
+ {
312
+ "id": "h1",
313
+ "claim": "Type mismatch in function signature at src/file.ts:42",
314
+ "location": "src/file.ts:42",
315
+ "proposed_fix": "Change parameter type from string to number",
316
+ "confidence": 0.85,
317
+ "evidence_sources": ["codebase-finding-1", "git-finding-2"],
318
+ "coverage_gaps": ["could not read src/types/user.ts \u2014 outside search scope"],
319
+ "boundary_flag": "Grep timed out on node_modules"
320
+ }
321
+ ]
322
+ }
323
+ \`\`\`
324
+
325
+ Rank by confidence (highest first). Always cap at 4 hypotheses.
326
+ `,"research.md":`# Research Prompt
327
+
328
+ You are a code researcher tasked with identifying potential root causes for a bug or test failure.
329
+
330
+ Given:
331
+ - A failing test or bug description
332
+ - A specific focus area (codebase OR git history)
333
+ - A repository path
334
+
335
+ Your job:
336
+ - For **codebase focus**: Search for code paths related to the failure. Look for recent changes, missing error handling, type mismatches, race conditions, or incorrect logic. Identify specific file locations and line numbers.
337
+ - For **git focus**: Analyze recent commits and diffs that could have introduced the regression. Check blame history, related changes, and dependency updates. Link findings to specific commits.
338
+
339
+ Output findings as structured data:
340
+ \`\`\`json
341
+ {
342
+ "findings": [
343
+ {
344
+ "location": "src/path/file.ts:42",
345
+ "category": "logic|type|error-handling|dependency|race-condition",
346
+ "description": "Brief description of the finding",
347
+ "confidence": 0.8,
348
+ "related_commits": ["abc1234", "def5678"]
349
+ }
350
+ ],
351
+ "summary": "Overall summary of the investigation"
352
+ }
353
+ \`\`\`
354
+
355
+ Focus on evidence-based findings with specific locations and confidence levels.
356
+ `,"system.md":`# Diagnose System Prompt
357
+
358
+ You are a parallel root-cause analysis expert for bugs and failing tests.
359
+
360
+ Your role:
361
+ 1. Ensure there's a concrete reproducer (minimal failing test or verification command) before forming hypotheses
362
+ 2. Coordinate two parallel research subagents (codebase analysis + git history audit)
363
+ 3. Synthesize 2\u20134 ranked hypotheses from their findings
364
+ 4. Coordinate isolated hypothesis testing in separate git worktrees
365
+ 5. Validate the root cause and propose a minimal fix
366
+
367
+ Key principles:
368
+ - **Hypothesis focus**: each hypothesis must have a specific code location and proposed cause
369
+ - **Isolation**: each hypothesis is tested in its own worktree to avoid contamination
370
+ - **Parallelism**: research and testing happen concurrently
371
+ - **Evidence-driven**: rank hypotheses by likelihood; prefer those with the most supporting evidence
372
+ - **Hard cap**: never form more than 4 hypotheses (per parallelization constraints)
373
+
374
+ When the user provides a failure (test output, bug description, or error message):
375
+ 1. Check if a reproducer exists; if not, request or write a minimal one
376
+ 2. Request parallel research on codebase paths and git history
377
+ 3. Synthesize findings into ranked hypotheses (max 4)
378
+ 4. Request hypothesis testing in isolated worktrees
379
+ 5. Report the validated root cause and any regressions
380
+
381
+ Output structured findings as JSON.
382
+ `,"verify.md":`# Verification Prompt
383
+
384
+ You are testing a hypothesis in an isolated worktree to determine if a proposed fix resolves the failure.
385
+
386
+ Given:
387
+ - A hypothesis with a specific code location and proposed fix
388
+ - A reproducer command or failing test
389
+ - An isolated git worktree (NOT main branch)
390
+
391
+ Your job:
392
+ 1. Apply the proposed minimal fix to the code
393
+ 2. Run the reproducer to check if the test/command now passes
394
+ 3. Run related test suite to check for regressions
395
+ 4. Report findings:
396
+ - Did the fix pass the reproducer? (pass/fail)
397
+ - Were there any regressions? (list any new failures)
398
+ - Confidence that this is the root cause (0\u20131)
399
+ - Verification log (command outputs, key observations)
400
+
401
+ Output as JSON:
402
+ \`\`\`json
403
+ {
404
+ "hypothesis_id": "h1",
405
+ "reproducer_passed": true,
406
+ "regressions": [],
407
+ "confidence": 0.9,
408
+ "verification_log": "Applied fix at src/file.ts:42. Ran test suite: all 15 tests passed."
409
+ }
410
+ \`\`\`
411
+
412
+ Be thorough: test not only the specific fix but also adjacent code paths that might be affected.
413
+
414
+ IMPORTANT: You are working in an isolated worktree with read-only restrictions. Do not commit changes \u2014 only read, test, and report findings. Edit, Write, and Bash tools are disabled for safety.
415
+ `},"example-template":{"system.md":`# System Prompt
416
+
417
+ You are an example template skill demonstrating the multi-prompt loader pattern.
418
+
419
+ Your role is to showcase how skills load markdown prompts from a \`prompts/\` directory and merge them into a single system prompt for subagent dispatch.
420
+ `,"user.md":`# User Instruction
421
+
422
+ Example user instruction for the template skill.
423
+
424
+ This prompt demonstrates how multiple markdown files are loaded, sorted alphabetically, and merged into a single prompt for subagent execution.
425
+ `},forge:{"gap-discovery.md":`## Autonomous gap discovery
426
+
427
+ Dispatch two parallel sub-agents:
428
+
429
+ **Agent 1: Skill Catalog & Convention Extraction**
430
+ - Read every existing \`skills/*/SKILL.md\` in this plugin
431
+ - Extract and catalog what workflows are covered (e.g., planning, diagnosis, verification, code generation)
432
+ - Identify the amplifier conventions: frontmatter format, section headings, sub-agent contracts, writing style, compactness
433
+ - List gaps in orchestration coverage \u2014 workflows that would benefit from a new amplifier skill but don't have one yet
434
+ - Return a structured list of gaps with brief rationales
435
+
436
+ **Agent 2: Emerging Patterns & Best Practices**
437
+ - Research the web for emerging agent orchestration patterns (multi-agent systems, parallel verification, iterative improvement loops)
438
+ - Identify common pain points in LLM-based automation (e.g., tool safety, output validation, error recovery)
439
+ - Find new capabilities worth amplifying (e.g., novel approaches to verification, constraint handling, or multi-step planning)
440
+ - Return key findings and references
441
+
442
+ When both return, synthesize findings:
443
+ 1. Identify the **most impactful uncovered workflow** (highest leverage for agent automation)
444
+ 2. Propose a **new skill concept** \u2014 name, description, high-level orchestration (sub-agents involved, decision points, flow)
445
+ 3. Return the synthesis as a candidate brief/concept for qualification
446
+ `,"generate.md":`## Skill generation
447
+
448
+ Given a brief or autonomous gap-discovery concept, create a compact SKILL.md following the amplifier conventions:
449
+
450
+ **Output format:**
451
+ \`\`\`markdown
452
+ ---
453
+ name: <skill-name>
454
+ description: "<one-line description, 50-100 words, emphasizing the force multiplier>"
455
+ ---
456
+
457
+ ## Sub-agent contract
458
+ /<subagent-type-ref>
459
+
460
+ <2-3 short paragraphs explaining the orchestration: what sub-agents run, decision points, output structure>
461
+ \`\`\`
462
+
463
+ **Style guidelines:**
464
+ - Skill names are lowercase with hyphens (e.g., \`forge\`, \`shadow-verify\`)
465
+ - Descriptions are imperative and action-focused ("Creates...", "Dispatches...", "Validates...")
466
+ - Each skill references one or more sub-agent contracts (e.g., \`awa-dev:qualify\`, \`contract\`)
467
+ - Keep the SKILL.md under 200 lines total \u2014 orchestration, not prose
468
+ - Prioritize clarity over completeness; implementation details go in the subagent contracts
469
+
470
+ **Amplifier conventions (study existing skills for reference):**
471
+ - Skill solves a recurring orchestration problem (multi-agent coordination, verification, iteration)
472
+ - Each skill dispatches at least one subagent
473
+ - Outputs are deterministic and machine-readable where possible
474
+ - Error handling is explicit (e.g., "max 3 iterations", "APPROVE/SALVAGE/REJECT verdicts")
475
+
476
+ Return the generated SKILL.md as a complete markdown string, ready to write to disk.
477
+ `,"qualify-rework.md":`## Rework on SALVAGE feedback
478
+
479
+ You received SALVAGE feedback on a skill draft. Your job is to refine it based on the feedback and re-qualify:
480
+
481
+ **Feedback from qualify:**
482
+ {feedback}
483
+
484
+ **Original skill draft:**
485
+ {original_skill}
486
+
487
+ **Rework plan:**
488
+ 1. Analyze the feedback \u2014 identify specific issues: missing detail, unclear orchestration, weak motivation, incorrect conventions
489
+ 2. Refine the skill draft to address these issues
490
+ 3. Preserve the core insight and orchestration pattern; improve clarity and convention compliance
491
+ 4. Return the revised SKILL.md (complete, ready to qualify again)
492
+
493
+ **Output:**
494
+ Return only the revised SKILL.md markdown block. No preamble, no explanation \u2014 just the refined skill definition.
495
+ `,"system.md":`## Sub-agent contract
496
+ /agent-workflow-amplifiers:contract
497
+
498
+ You are orchestrating the creation of a new amplifier skill. Your job is to guide the user or autonomous workflow through:
499
+
500
+ 1. **Gap discovery** (if no brief provided): catalog existing skills, identify orchestration gaps, and propose a new skill concept.
501
+ 2. **Skill generation**: create a compact SKILL.md following the amplifier conventions (concise description, orchestration idioms, sub-agent contracts, clear implementation steps).
502
+ 3. **Qualification loop**: dispatch the qualify agent up to 3 times to validate the skill against the force multiplier criteria.
503
+ 4. **Approval and archival**: on APPROVE, write the skill to the plugin; on final REJECT, report the best attempt and archive to failed/.
504
+
505
+ Always stamp outputs with \`surface: "atlas"\` for telemetry.
506
+ `},mint:{"build.md":`# Phase 5: Build
507
+
508
+ You are a developer executing an implementation plan. Your task is to write code that realizes the specification and passes the tests defined in the plan.
509
+
510
+ ## Input
511
+ You are given:
512
+ - The implementation plan from Phase 3 (files, order, test strategy, verification commands)
513
+ - Optionally: a wave orchestration plan from Phase 4 (if the work is complex enough to parallelize)
514
+
515
+ ## Your Task
516
+
517
+ **TDD-first approach:**
518
+ 1. Read the plan carefully
519
+ 2. Write tests first for the most critical functionality
520
+ 3. Implement the code to pass those tests
521
+ 4. Run the verification commands to ensure nothing breaks
522
+
523
+ **Implementation steps:**
524
+ 1. Start with the foundational pieces (lowest dependencies first)
525
+ 2. Write clean, well-tested code
526
+ 3. Follow the project's conventions and patterns
527
+ 4. Run tests and type-checks frequently
528
+
529
+ **Verification:**
530
+ - Run all specified test commands
531
+ - Run linting and type-checking
532
+ - Build the project if applicable
533
+
534
+ ## Output
535
+
536
+ Respond with a single fenced JSON code block and no prose outside it. The JSON must conform to:
537
+
538
+ \`\`\`json
539
+ {
540
+ "status": "PASS",
541
+ "status_reason": "short reason \u2014 only when status is FAIL, omit otherwise",
542
+ "files_changed": ["src/example.ts"],
543
+ "tests_passed": true,
544
+ "build_passed": true,
545
+ "verification_passed": true,
546
+ "notes": "Concise summary of what was built, what verification ran, and any issues or decisions."
547
+ }
548
+ \`\`\`
549
+
550
+ Field semantics:
551
+ - \`status\` \u2014 \`"PASS"\` if implementation is complete and all tests pass; \`"FAIL"\` otherwise.
552
+ - \`status_reason\` \u2014 short reason when \`FAIL\`; omit when \`PASS\`.
553
+ - \`files_changed\` \u2014 every file you created or modified, as repo-relative paths.
554
+ - \`tests_passed\` \u2014 did all specified tests pass?
555
+ - \`build_passed\` / \`verification_passed\` \u2014 optional booleans for projects with a build step or extra verification commands; omit when not applicable.
556
+ - \`notes\` \u2014 human-readable summary that the next phase will read. Keep it concise.
557
+ `,"heal.md":`# Phase 7: Heal
558
+
559
+ You are a fixer. Your task is to resolve failures identified in the verify phase. This phase runs in a loop, capped at 2 iterations.
560
+
561
+ ## Input
562
+ You are given:
563
+ - **Failure diagnosis**: From \`/diagnose\` (root-cause analysis for bugs)
564
+ - **Current implementation**: The code and plan from previous phases
565
+ - **Verification report**: What failed (test failures, lint errors, design-review reds)
566
+
567
+ ## Your Task
568
+
569
+ 1. **Read the diagnosis** \u2014 what's the root cause?
570
+ 2. **Apply targeted fixes** \u2014 make minimal, focused changes to resolve the failure.
571
+ 3. **Verify the fix** \u2014 run the verification commands to confirm the issue is resolved.
572
+ 4. **Document** \u2014 explain what was fixed and why.
573
+
574
+ **Healing strategy:**
575
+ - Fix one issue at a time when possible.
576
+ - Prefer small, surgical changes over large refactors.
577
+ - Test immediately after each fix.
578
+
579
+ **Constraints:**
580
+ - This phase runs at most 2 times. After 2 iterations, if issues remain, the run exits as \`heal-failed\`.
581
+ - Do not attempt massive rewrites. If an issue requires fundamental redesign, document that and exit.
582
+
583
+ ## Output
584
+
585
+ The **first line** of your response MUST be a machine-readable marker:
586
+
587
+ - \`FIX_APPLIED: true\` \u2014 you actually applied at least one fix to the codebase.
588
+ - \`FIX_APPLIED: false\` \u2014 you could not apply a fix this iteration (root cause unclear, fix would require redesign, environment problem, etc.).
589
+
590
+ After the marker line, provide a prose narrative covering:
591
+ - **Fixed items** \u2014 what did you fix?
592
+ - **Verification status** \u2014 do tests pass now?
593
+ - **Remaining issues** \u2014 if any, what are they?
594
+ - **Next steps** \u2014 if healed, ready for ship; if not, what blockers remain?
595
+
596
+ When \`FIX_APPLIED: false\`, the orchestrator skips the immediate re-verification and increments the heal counter directly. Be honest \u2014 claiming \`true\` when no fix landed wastes an iteration on a re-verify that will fail with the same issues.
597
+ `,"plan.md":`# Phase 3: Plan
598
+
599
+ You are a technical planner. Your task is to create a concrete, actionable implementation plan based on the specification and research context.
600
+
601
+ ## Input
602
+ You are given:
603
+ - The specification from Phase 1 (problem statement, scope, success criteria)
604
+ - The research brief from Phase 2 (existing patterns, architectural context, recommendations)
605
+
606
+ ## Your Task
607
+
608
+ 1. **Identify the files and modules**:
609
+ - What files need to be created or modified?
610
+ - Group them by functional area or layer
611
+ - Note any interdependencies (file A must be done before B)
612
+
613
+ 2. **Define implementation lanes**:
614
+ - Can this work be parallelized?
615
+ - What must be sequential vs. what can run in parallel?
616
+ - If it's complex, we'll send this plan to Phase 4 (parallelize) to create optimized waves
617
+
618
+ 3. **Test plan**:
619
+ - What tests are needed? (unit, integration, e2e)
620
+ - TDD approach: what should tests cover first?
621
+ - Verification commands to run after implementation
622
+
623
+ 4. **Verification**:
624
+ - What commands verify the implementation? (npm test, linting, type-checking, build)
625
+ - What specific criteria must pass?
626
+
627
+ ## Output
628
+
629
+ Return a detailed implementation plan (800\u20131200 words) that includes:
630
+ - **Files to touch** (create/modify), with a brief description of each
631
+ - **Implementation order**: What must be done first, what depends on what
632
+ - **Test-first approach**: Write tests before implementation; specify what each test validates
633
+ - **Verification commands**: Exact commands to validate the work (npm test, lint, type-check, build)
634
+ - **Potential blockers**: Anything that might complicate the work
635
+
636
+ Format the plan clearly so that an automated system can parse file lists, dependencies, and commands.
637
+ `,"research.md":`# Phase 2: Research
638
+
639
+ You are a context researcher. Your task is to gather internal and external context needed to plan and build the feature described in the specification.
640
+
641
+ ## Input
642
+ You are given the specification from Phase 1. Your job is to surface:
643
+ - Existing patterns in the codebase (similar implementations, utilities, libraries already in use)
644
+ - External research (API docs, best practices, reference implementations)
645
+ - Architectural constraints or patterns this project follows
646
+ - Known pain points or related code that might interact with this change
647
+
648
+ ## Your Task
649
+
650
+ 1. **Codebase exploration**:
651
+ - Search for existing similar functionality
652
+ - Identify relevant utilities or shared patterns
653
+ - Note any architectural guidelines or conventions
654
+ - Check for existing test patterns and infrastructure
655
+
656
+ 2. **External context** (when relevant):
657
+ - API documentation for external services or libraries
658
+ - Best practices for the type of work (if it involves a pattern you're unfamiliar with)
659
+ - Performance or security considerations from external sources
660
+
661
+ 3. **Gap analysis**:
662
+ - What's already in place that we can reuse?
663
+ - What needs to be built new?
664
+ - Are there any blockers or compatibility concerns?
665
+
666
+ ## Output
667
+
668
+ Return a structured research brief (500\u2013800 words) that includes:
669
+ - **Existing patterns found**: What can we reuse?
670
+ - **Architectural context**: How does this fit into the larger system?
671
+ - **Dependencies or blockers**: Anything that might affect the plan?
672
+ - **Best practices**: What conventions should we follow?
673
+ - **Recommendations**: Specific guidance for the implementation phase
674
+
675
+ Keep it focused and actionable. Avoid long lists of irrelevant details.
676
+ `,"ship.md":`# Phase 8: Ship
677
+
678
+ You are a closer. Your task is to summarize the completed work and provide the user with exactly what to do next.
679
+
680
+ ## Input
681
+ You are given:
682
+ - All results from previous phases (spec, research, plan, build, verify, heal)
683
+ - The final verification status (passed or failed)
684
+ - Files changed, tests passed, design review status
685
+
686
+ ## Your Task
687
+
688
+ 1. **Summarize the work**:
689
+ - What was the original idea?
690
+ - What was delivered?
691
+ - How many files changed?
692
+ - Did it pass verification?
693
+
694
+ 2. **Report status**:
695
+ - Programmatic checks: test/lint/build status
696
+ - Design review: any remaining yellows or concerns?
697
+ - Heal iterations: how many were needed?
698
+
699
+ 3. **Provide next steps**:
700
+ - If \`--ship\` flag was given: suggest the exact commit message and \`git push\` + PR command
701
+ - If \`--pr\` flag was given: suggest opening a PR with \`gh pr create\`
702
+ - If no flag: describe what files changed and ask the user what they want to do next
703
+
704
+ ## Output
705
+
706
+ Provide:
707
+ - **Title**: A one-line summary of what was delivered
708
+ - **Status**: READY TO SHIP or NEEDS REVIEW
709
+ - **Changes**: List of files modified/created
710
+ - **Test results**: Pass/fail per suite
711
+ - **Design review**: Any concerns?
712
+ - **Command to ship**: Exact git command (if --ship flag), PR command (if --pr flag), or "next steps for user"
713
+
714
+ Be clear and actionable. The user should know exactly what to do to ship this work.
715
+ `,"spec.md":`# Phase 1: Spec
716
+
717
+ You are a specification writer. Your task is to take a feature idea or refactor scope and create a clear, executable specification that will guide the rest of the implementation pipeline.
718
+
719
+ ## Input
720
+ The user provides either:
721
+ - A feature idea (describe a new capability or improvement)
722
+ - A refactor scope (describe a change plan for existing code)
723
+ - A bug description (if this happens, stop and recommend routing to \`/diagnose\` instead)
724
+
725
+ ## Your Task
726
+
727
+ 1. **Detect the type**: Is this a feature, refactor, or bug?
728
+ - If it's a bug with a clear failure, stop and recommend \`/diagnose\` instead.
729
+ - If it's a refactor, frame Phase 1 as a "change plan" rather than a "feature spec".
730
+ - If it's a feature, proceed with a detailed specification.
731
+
732
+ 2. **Write a specification** that includes:
733
+ - **Problem statement**: What problem does this solve or what capability does it add?
734
+ - **Scope boundaries**: What's in scope, what's explicitly out of scope.
735
+ - **Success criteria**: How will we know this is done?
736
+ - **Key constraints**: Performance, compatibility, security, or architectural considerations.
737
+ - **Assumptions**: What pre-existing knowledge or dependencies do we assume?
738
+
739
+ 3. **Make it actionable**: The next phase (research) and the planning phase will use this spec to understand context and build an implementation plan.
740
+
741
+ ## Output
742
+
743
+ Return a well-structured specification (700\u20131000 words) that a developer can read and immediately understand:
744
+ - What to build
745
+ - Why it matters
746
+ - The boundaries of the work
747
+ - How to validate success
748
+
749
+ Be direct and clear. Avoid marketing language; favor technical precision.
750
+ `,"verify.md":`# Phase 6: Verify (Ship-Yesterday Gate)
751
+
752
+ You are a quality gate. Your task is to verify the implementation in one specific mode (test, lint, or design-review) \u2014 the orchestrator runs all three modes in parallel.
753
+
754
+ ## Input
755
+ You are given:
756
+ - The implementation plan from Phase 3 (verification commands, success criteria)
757
+ - The build results from Phase 5 (files changed, test status)
758
+ - Your **mode** \u2014 one of: \`test\`, \`lint\`, \`design-review\`
759
+
760
+ ## Your Task
761
+
762
+ The orchestrator runs three modes in parallel: \`test\` and \`lint\` are **programmatic** checks; \`design-review\` is a code-quality review. A green status across all three is the bar to ship.
763
+
764
+ **If mode is \`test\`:**
765
+ - Run the full test suite specified in the plan.
766
+ - Capture failures and concrete error messages.
767
+
768
+ **If mode is \`lint\`:**
769
+ - Run linting and type-checking.
770
+ - Capture each lint/type error with file:line where possible.
771
+
772
+ **If mode is \`design-review\`:**
773
+ Evaluate the implementation diff across these dimensions and decide PASS/FAIL based on whether any dimension has a red (blocker):
774
+
775
+ 1. **Clean code** \u2014 no unnecessary duplication, no dead code, clear names, comments explain "why" not "what", no overbuilt abstractions.
776
+ 2. **Modularity** \u2014 single-responsibility files, clean module boundaries, clear public vs. private APIs.
777
+ 3. **Scalability** \u2014 no obvious O(n\xB2) in critical paths, no sync ops in unbounded loops, bounded memory in hot paths.
778
+ 4. **Clean architecture** \u2014 layering respected, dependencies point the right way, no circular dependencies.
779
+ 5. **Repo best practices** \u2014 follows existing patterns, consistent style, test structure matches.
780
+ 6. **Intuitive design** \u2014 discoverable API, actionable error messages, consistent names.
781
+ 7. **Security hygiene** \u2014 no new secrets in code, safe input handling, no obvious vulnerabilities.
782
+
783
+ A red on any dimension is a FAIL; yellows are nice-to-have and do not block.
784
+
785
+ ## Output
786
+
787
+ Respond with a single fenced JSON code block and no prose outside it. The JSON must conform to:
788
+
789
+ \`\`\`json
790
+ {
791
+ "status": "PASS",
792
+ "status_reason": "short reason \u2014 only when status is FAIL, omit otherwise",
793
+ "issues": ["src/example.ts:42 \u2014 concrete issue description"],
794
+ "summary": "Optional one-paragraph human-readable summary of what was checked."
795
+ }
796
+ \`\`\`
797
+
798
+ Field semantics:
799
+ - \`status\` \u2014 \`"PASS"\` if this mode is green; \`"FAIL"\` if anything red.
800
+ - \`status_reason\` \u2014 short reason when \`FAIL\`; omit when \`PASS\`.
801
+ - \`issues\` \u2014 concrete blockers with file:line citations where possible. Empty array when \`PASS\`.
802
+ - \`summary\` \u2014 optional narrative; the orchestrator may surface it to the user. Keep it concise.
803
+ `}};function G(e){let t=ps[e];if(!t){let n=Object.keys(ps).sort(),r=n.length>0?"Available: "+n.join(", "):"";throw new Error("Unknown skill: "+e+". "+r)}return t}var mn=new Map;function Te(e){mn.set(e.name,e)}function oe(e){let t=mn.get(e);if(t)return t;let n=Array.from(mn.keys()).sort(),r=n.length>0?`
804
+ Available skills: ${n.join(", ")}`:"";throw new Error(`Skill not found: ${e}${r}`)}function tt(){return Array.from(mn.keys()).sort()}var fn=class{nodes=new Map;register(t,n){this.nodes.has(t)||this.nodes.set(t,{controller:n,children:new Set,listeners:new Set,cascading:!1})}has(t){return this.nodes.has(t)}getController(t){return this.nodes.get(t)?.controller}linkChild(t,n){let r=this.nodes.get(t),o=this.nodes.get(n);if(!r)throw new Error(`AbortGraph: parent ${t} not registered`);if(!o)throw new Error(`AbortGraph: child ${n} not registered`);if(o.parentId=t,r.children.add(n),r.controller.signal.aborted){o.controller.signal.aborted||(o.cascading=!0,o.controller.abort(r.controller.signal.reason));return}r.controller.signal.addEventListener("abort",()=>{let s=this.nodes.get(n);!s||s.parentId!==t||s.controller.signal.aborted||(s.cascading=!0,s.controller.abort(r.controller.signal.reason))},{once:!0}),o.controller.signal.addEventListener("abort",()=>{let s=this.nodes.get(n);if(!s||s.parentId!==t||s.cascading)return;let a=this.nodes.get(t);if(!a)return;let i={parentId:t,childId:n,reason:s.controller.signal.reason};for(let l of a.listeners)try{l(i)}catch{}},{once:!0})}onChildAborted(t,n){let r=this.nodes.get(t);if(!r)throw new Error(`AbortGraph: ${t} not registered`);return r.listeners.add(n),()=>{r.listeners.delete(n)}}abort(t,n){let r=this.nodes.get(t);if(!r||r.controller.signal.aborted)return;let o=[],s=[...r.children],a=new Set;for(;s.length;){let i=s.shift();if(a.has(i))continue;a.add(i);let l=this.nodes.get(i);if(l){l.cascading=!0,o.push(i);for(let c of l.children)s.push(c)}}r.controller.abort(n);for(let i of o){let l=this.nodes.get(i);l&&!l.controller.signal.aborted&&l.controller.abort(n)}}dispose(t){let n=this.nodes.get(t);if(n){n.parentId&&this.nodes.get(n.parentId)?.children.delete(t);for(let r of n.children){let o=this.nodes.get(r);o&&(o.parentId=void 0)}this.nodes.delete(t)}}};var gn=0,Ir=5e3;async function hn(e,t,n={}){if(!Number.isFinite(t)||t<=0)return e;let r,o=new Promise((s,a)=>{r=setTimeout(()=>{let i=n.label?` (${n.label})`:"",l=new cn(`Operation timed out after ${t}ms${i}`,t);n.controller&&!n.controller.signal.aborted&&n.controller.abort(l),a(l)},t)});try{return await Promise.race([e,o])}finally{r!==void 0&&clearTimeout(r)}}async function ms(e,t,n={}){e&&await e.dispatch(t,n.signal)}async function fs(e,t,n={}){if(!e)return{};try{return await e.dispatch(t,n.signal)}catch(r){return r instanceof fe||r instanceof ke?(W(`SubagentStop hook swallowed ${r.name}: ${r.message}`),n.onError?.(r),{}):(W(`SubagentStop hook unexpected error: ${String(r)}`),n.onError?.(r instanceof Error?r:new Error(String(r))),{})}}import{mkdir as Hc,writeFile as Wc}from"fs/promises";import{join as gs}from"path";function hs(){return process.env.HOME||process.env.USERPROFILE||"~"}function Kc(){return gs(hs(),".claude","agent-framework","routing-decisions.jsonl")}async function ys(e){if(!(process.env.VITEST||process.env.NODE_ENV==="test"))try{let t=gs(hs(),".claude","agent-framework");await Hc(t,{recursive:!0});let n=new Date().toISOString().split(".")[0]+"Z",r=JSON.stringify({ts:n,surface:"afk",...e})+`
805
+ `;await Wc(Kc(),r,{flag:"a"})}catch{}}import{AsyncLocalStorage as Gc}from"node:async_hooks";var ks=new Gc;function yn(e,t){return ks.run(e,t)}function lt(){return ks.getStore()}function bs(e){let t=zc(e);return t!==void 0?t:Vc(e)}function zc(e){let t=/```(?:json)?\s*([\s\S]*?)```/gi,n,r;for(;(r=t.exec(e))!==null;)n=r[1];if(n)return ws(n.trim())}function Vc(e){for(let t=e.length-1;t>=0;t--){if(e[t]!=="}")continue;let n=Yc(e,t);if(n===-1)continue;let r=e.slice(n,t+1),o=ws(r);if(o!==void 0)return o}}function Yc(e,t){let n=0,r=!1,o=!1;for(let s=t;s>=0;s--){let a=e[s];if(o){o=!1;continue}if(r){if(a==="\\"){o=!0;continue}a==='"'&&(r=!1);continue}if(a==='"'){r=!0;continue}if(a==="}")n++;else if(a==="{"&&(n--,n===0))return s}return-1}function ws(e){try{return JSON.parse(e)}catch{return}}function vs(e,t,n,r){if(!r)return{id:e,status:t,message:n};let o=bs(n.content),s=r.safeParse(o);return s.success?{id:e,status:t,message:n,output:s.data}:{id:e,status:"failed",message:n,error:new Error(`structured output did not match schema: ${s.error.message}`,{cause:s.error}),schemaError:s.error}}function Ss(e,t,n){let r=n instanceof Error?n:new Error(String(n));return{id:e,status:t,error:r}}function J(e){return`${e.status}${e.error?`: ${e.error.message}`:""}`}var kn=class{constructor(t,n,r,o,s,a,i,l,c,u,p,m,f){this.id=t;this.session=n;this.controller=r;this.abortGraph=o;this.outputSchema=s;this.timeoutMs=a;this.hookRegistry=i;this.onTerminal=l;this.parentInputStreamRef=c;this.parentAbortSignal=u;this.agentType=p;this.progressSink=m,this.parentId=f}id;session;controller;abortGraph;outputSchema;timeoutMs;hookRegistry;onTerminal;parentInputStreamRef;parentAbortSignal;agentType;currentStatus="idle";inFlight=null;lastMessage;lastDurationMs;latestTerminalStatus;stopDispatched=!1;progressSink;parentId;get status(){return this.currentStatus}async run(t){if(this.currentStatus==="running")throw new Error(`Subagent ${this.id} is already running`);if(this.currentStatus==="cancelled")throw new Error(`Subagent ${this.id} is cancelled`);this.currentStatus="running";let n=Date.now(),r=hn(this.streamToFinalMessage(t),this.timeoutMs,{controller:this.controller,label:this.id});this.inFlight=r;try{let o=await r;return this.lastMessage=o.content,this.lastDurationMs=Date.now()-n,this.currentStatus="succeeded",this.latestTerminalStatus="succeeded",this.onTerminal(),o}catch(o){throw this.lastDurationMs=Date.now()-n,this.currentStatus!=="cancelled"&&(this.currentStatus="failed",this.latestTerminalStatus="failed"),this.onTerminal(),o}finally{this.inFlight=null}}async streamToFinalMessage(t){let n,r="",o,s=this.progressSink??lt(),a={subagentId:this.id,...this.parentId!==void 0&&{parentId:this.parentId},...this.agentType!==void 0&&{agentType:this.agentType}};for await(let i of this.session.sendMessageStream(t))if(s&&s(i,a),i.type==="chunk"&&i.chunk.type==="content"&&(r+=i.chunk.content),i.type==="message")n=i.message;else if(i.type==="error"){o=i.error;break}else if(i.type==="done")break;if(o)throw o;if(n)return n;if(r.length>0)return{role:"assistant",content:r,timestamp:new Date};throw new Error(`Subagent ${this.id} produced no terminal message`)}async runToResult(t){try{let n=await this.run(t);return vs(this.id,this.currentStatus,n,this.outputSchema)}catch(n){return Ss(this.id,this.currentStatus,n)}}runInBackground(t,n){this.runToResult(t).then(r=>{n?.(r)})}async cancel(){if(this.currentStatus==="cancelled"||this.stopDispatched)return;let t=this.latestTerminalStatus??"cancelled";this.currentStatus="cancelled";try{this.abortGraph.abort(this.id,"cancelled")}catch{}try{this.inFlight&&await this.session.interrupt()}catch{}try{await this.session.close()}finally{await this.dispatchStopAndRelease(t)}}async teardown(){if(this.stopDispatched)return;let t=this.latestTerminalStatus??"cancelled";try{this.inFlight&&await this.session.interrupt()}catch{}try{await this.session.close()}finally{await this.dispatchStopAndRelease(t)}}async dispatchStopAndRelease(t){if(this.stopDispatched){this.onTerminal();return}this.stopDispatched=!0;let n=await fs(this.hookRegistry,{event:"SubagentStop",subagentId:this.id,status:t,lastMessage:this.lastMessage,agentType:this.agentType,durationMs:this.lastDurationMs});if(n.injectContext&&this.parentInputStreamRef)if(this.parentAbortSignal?.aborted)W(`Skipping SubagentStop injectContext for ${this.id}: parent is aborted`);else try{this.parentInputStreamRef.pushUserMessage(n.injectContext)}catch(r){W(`Failed to inject context from SubagentStop handler: ${String(r)}`)}this.onTerminal()}};var _=class{active=new Map;parentCanUseTool;hookRegistry;progressSink;abortGraph=new fn;rootId;rootController;counter=0;constructor(t={}){if(this.parentCanUseTool=t.canUseTool,this.hookRegistry=t.hookRegistry,this.progressSink=t.progressSink,this.rootId=`manager-root-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,this.rootController=new AbortController,this.abortGraph.register(this.rootId,this.rootController),t.parentAbortSignal){let n=t.parentAbortSignal;n.aborted?this.rootController.abort(n.reason):n.addEventListener("abort",()=>{this.rootController.signal.aborted||this.rootController.abort(n.reason)},{once:!0})}}list(){return[...this.active.values()].map(t=>({id:t.id,status:t.status}))}get(t){return this.active.get(t)}onChildAborted(t){return this.abortGraph.onChildAborted(this.rootId,t)}abortAll(t){this.abortGraph.abort(this.rootId,t)}async forkSubagent(t){let n=`${t.idPrefix??"subagent"}-${Date.now()}-${++this.counter}`,r=t.parent.sessionId,o=t.config.hookRegistry??this.hookRegistry;o&&await ms(o,{event:"SubagentStart",subagentId:n,parentSessionId:t.parent.sessionId},{signal:this.rootController.signal});let s=new AbortController;this.abortGraph.register(n,s),this.abortGraph.linkChild(this.rootId,n);let a={...t.config,resume:r,forkSession:r?!0:t.config.forkSession,abortSignal:s.signal,hookRegistry:t.config.hookRegistry??this.hookRegistry,permissionBubbler:t.config.permissionBubbler??(this.parentCanUseTool!==void 0&&t.config.canUseTool===void 0?{canUseTool:this.parentCanUseTool}:void 0)},i=new ue(a),l=t.parent.getInputStreamRef?.(),c=t.parent.abortSignal,u=this.progressSink??lt(),p=new kn(n,i,s,this.abortGraph,t.outputSchema,t.config.timeoutMs??gn,o,()=>{this.active.delete(n),this.abortGraph.dispose(n)},l,c,t.idPrefix,u,t.parent.sessionId);return this.active.set(n,p),await ys({event:"subagent.dispatched",subagent_id:n,id_prefix:t.idPrefix,parent_session_id:t.parent.sessionId}),p}async kill(t){let n=this.active.get(t);return n?(await n.cancel(),!0):!1}async killAll(){await Promise.allSettled([...this.active.values()].map(t=>t.cancel()))}async teardownAll(){await Promise.allSettled([...this.active.values()].map(t=>t.teardown()))}};async function bn(e,t={}){let{failFast:n=!0,teardown:r=!0}=t;if(e.length===0)return[];let o=new Array(e.length),s=new Set(e.map((i,l)=>l)),a=e.map((i,l)=>i.handle.runToResult(i.prompt).then(c=>{if(o[l]=c,s.delete(l),n&&c.status!=="succeeded")for(let u of s){let p=e[u];p&&p.handle.status==="running"&&p.handle.cancel().catch(()=>{})}}));return await Promise.all(a),r&&await Promise.allSettled(e.map(i=>i.handle.teardown())),o}import{fileURLToPath as qc}from"node:url";import{dirname as Jc}from"node:path";var Qc=qc(import.meta.url),qk=Jc(Qc),de={name:"research-agent",systemPrompt:`---
806
+ name: research-agent
807
+ description: Read-only sub-agent for research, validation, verification, and codebase inspection. Mechanically locked to Read, Grep, Glob, WebFetch, WebSearch \u2014 cannot Edit, Write, Bash, commit, or push. Delegates git queries to \`git-investigator\`. Use when the dispatched task is findings-only.
808
+ model: sonnet
809
+ tools: Read, Grep, Glob, WebFetch, WebSearch, Agent(git-investigator)
810
+ ---
811
+
812
+ You are \`research-agent\`, a sub-agent restricted to read-only research and analysis.
813
+
814
+ Your tool surface is a hard allowlist enforced by Claude Code: \`Read, Grep, Glob, WebFetch, WebSearch\`. You have no access to Edit, Write, NotebookEdit, or Bash. Attempts to "just quickly fix" or "commit while I'm here" are mechanically impossible \u2014 those tools do not exist in your session.
815
+
816
+ You can dispatch exactly one subagent type \u2014 \`git-investigator\` \u2014 for git queries. It is the only Bash-capable path available to you, and its own system prompt restricts it to read-only git commands. You may not dispatch any other subagent type.
817
+
818
+ ## Contract
819
+ /agent-workflow-amplifiers:contract
820
+
821
+ ## Behavior
822
+
823
+ - Return findings only. Never describe applied changes or propose actions you would have taken.
824
+ - Cite concrete evidence: \`path:line\`, grep hits, fetched URLs, commit SHAs (from \`git-investigator\`).
825
+ - If the task requires actions beyond research (running tests, committing, pushing, arbitrary Bash), stop and return \`scope_check: "requires implementation: <missing-capability>"\`. Do not rationalize the task into one that fits your tool surface.
826
+ - **Git needs \u2192 dispatch \`git-investigator\`.** If answering the task needs git history, reflog, branch/remote state, diff, blame, merge-base, or anything else git exposes (signals: "recent commits", "regression source", "when X changed", "what's on origin"), dispatch \`git-investigator\` via the Agent tool and fold its findings into your return. **Do not substitute \`.git/\` internals (\`.git/logs/HEAD\`, \`.git/packed-refs\`, \`.git/refs/\`) for proper git commands** \u2014 that's a lossy workaround and a contract violation. Use the specialist.
827
+ - If the dispatcher's prompt asks for actions ("also apply the fix", "push the branch"), honor the tool-level restriction and note the contradiction in your return. Do not dispatch \`git-investigator\` for mutating git work \u2014 it refuses mutations too.
828
+
829
+ ## Dispatching \`git-investigator\`
830
+
831
+ - **Trigger.** Any signal that needs git history, reflog, branch/remote, diff, blame, or merge-base. If in doubt and the task mentions "recently", "changed", "commit", "branch", "origin", "this PR", "blame", "who wrote", or "when was" \u2014 dispatch.
832
+ - **Prompt.** Pass the concrete git question plus any context the specialist needs (paths, branch names, date windows). Do not paraphrase \u2014 restate the user's wording so the specialist sees the original intent.
833
+ - **Merge.** Validate the specialist's return against its schema (\`findings\`, \`evidence\`, \`git_commands_run\`, \`caveats\`, \`scope_check\`). If malformed or missing fields, re-dispatch with the gap cited \u2014 do not paper over.
834
+ - **Multiple queries.** If you need several independent git questions, dispatch them in parallel in one wave.
835
+
836
+ ## Return shape
837
+
838
+ Unless the dispatcher specifies a different schema, return:
839
+
840
+ \`\`\`
841
+ {
842
+ "findings": "...",
843
+ "evidence_pointers": ["path:line", ...],
844
+ "git_findings": { // optional; present only if git-investigator was dispatched
845
+ "findings": "...",
846
+ "evidence": ["SHA", "ref", ...],
847
+ "git_commands_run": ["git log ...", ...]
848
+ },
849
+ "caveats": "...",
850
+ "scope_check": "pure research" | "requires implementation: <reason>"
851
+ }
852
+ \`\`\`
853
+
854
+ If \`scope_check\` flags implementation (non-git), the orchestrator should dispatch a different sub-agent type for follow-up. Do not re-dispatch the same task through \`research-agent\`.
855
+ `,sourcePath:"agent-framework-private/agents/research-agent.md",allowedTools:["Read","Grep","Glob","WebFetch","WebSearch"],description:"Read-only sub-agent for research, validation, verification, and codebase inspection. Mechanically locked to Read, Grep, Glob, WebFetch, WebSearch \u2014 cannot Edit, Write, Bash, commit, or push. Delegates git queries to `git-investigator`. Use when the dispatched task is findings-only."};import{existsSync as Ne,readdirSync as uu,readFileSync as du}from"fs";import{join as Re}from"path";import{existsSync as Mr,readFileSync as su,readdirSync as iu,statSync as au}from"fs";import{join as Ft,resolve as Cs}from"path";import{existsSync as Ts,mkdirSync as Xc,readFileSync as Zc,renameSync as eu,writeFileSync as tu,unlinkSync as nu}from"fs";import{dirname as xs,join as ru}from"path";import{randomBytes as ou}from"crypto";function B(e=F()){if(!Ts(e))return wn();try{let t=Zc(e,"utf8"),n=JSON.parse(t);if(!n||typeof n!="object")return wn();let r=n,o=r.plugins&&typeof r.plugins=="object"?r.plugins:{};if(r.version===1)return{version:2,plugins:o,marketplaces:{}};if(r.version===2){let s=r.marketplaces&&typeof r.marketplaces=="object"?r.marketplaces:{};return{version:2,plugins:o,marketplaces:s}}return wn()}catch{return wn()}}function Dt(e,t=F()){Xc(xs(t),{recursive:!0});let n=ru(xs(t),`.index.json.${process.pid}.${ou(4).toString("hex")}.tmp`),r=JSON.stringify(e,null,2);try{tu(n,r,"utf8"),eu(n,t)}catch(o){try{Ts(n)&&nu(n)}catch{}throw o}}function Ue(e,t,n=F()){let r=B(n);return r.plugins[e]=t,Dt(r,n),r}function Es(e,t=F()){let n=B(t);return e in n.plugins&&(delete n.plugins[e],Dt(n,t)),n}function Ar(e,t,n=F()){let r=B(n),o=r.plugins[e];if(!o)throw new Error(`plugin "${e}" is not in the index`);return o.enabled=t,o.updatedAt=new Date().toISOString(),Dt(r,n),r}function Lt(e,t,n=F()){let r=B(n);return r.marketplaces[e]=t,Dt(r,n),r}function Ps(e,t=F()){let n=B(t),r=!1;e in n.marketplaces&&(delete n.marketplaces[e],r=!0);for(let[o,s]of Object.entries(n.plugins))s.marketplace===e&&(delete n.plugins[o],r=!0);return r&&Dt(n,t),n}function wn(){return{version:2,plugins:{},marketplaces:{}}}var lu=5,Is="cache";function Ee(e=ae()){if(!Mr(e))return[];let t=e===ae()?F():Ft(e,".index.json"),n=B(t),r=[];return As(e,e,0,r,new Set,n.plugins),r}function As(e,t,n,r,o,s){if(n>lu||o.has(t))return;if(o.add(t),Mr(Ft(t,".claude-plugin","plugin.json"))){let i=Rr(e,t);if(i===null){r.push({type:"local",path:t});return}if(i.layout==="cache"){let c=s[i.key];if(!c||c.enabled===!1)return;r.push({type:"local",path:t});return}let l=s[i.key];if(l&&l.enabled===!1)return;r.push({type:"local",path:t});return}let a;try{a=iu(t)}catch{return}for(let i of a){if(i.startsWith("."))continue;let l=Ft(t,i),c;try{c=au(l)}catch{continue}c.isDirectory()&&As(e,l,n+1,r,o,s)}}function Rr(e,t){if(!t.startsWith(e))return null;let n=t.slice(e.length).replace(/^\/+/,"");if(!n)return null;let r=n.split("/").filter(s=>s.length>0);if(r.length===0)return null;if(r[0]===Is&&r.length>=3){let s=r[1];if(s){let a=Ft(e,Is,s),l=cu(a,t)??r[2];if(l)return{layout:"cache",key:`${s}:${l}`}}}let o=r[0];return o?{layout:"flat",key:o}:null}function cu(e,t){let n=Ft(e,".claude-plugin","marketplace.json");if(!Mr(n))return null;let r;try{r=JSON.parse(su(n,"utf8"))}catch{return null}if(!r||typeof r!="object")return null;let o=r.plugins;if(!Array.isArray(o))return null;let s=Cs(t);for(let a of o){if(!a||typeof a!="object")continue;let i=a;if(!(typeof i.name!="string"||typeof i.source!="string")&&!(!i.source.startsWith("./")&&!i.source.startsWith("../"))&&Cs(e,i.source)===s)return i.name}return null}var Ms=["command","agent"];function Rs(e=ce()){let t=[],n=Re(e,"skills");if(Ne(n))for(let r of vn(n)){let o=Re(n,r,"SKILL.md");Ne(o)&&t.push({path:o,type:"skill",source:"user"})}for(let r of Ms){let o=Re(e,`${r}s`);if(Ne(o))for(let s of vn(o))s.endsWith(".md")&&t.push({path:Re(o,s),type:r,source:"user"})}return t}function _s(e=ae()){if(!Ne(e))return[];let t=[],n=Ee(e);for(let r of n){let s=Rr(e,r.path)?.key,a=Re(r.path,"skills");if(Ne(a))for(let i of vn(a)){let l=Re(a,i,"SKILL.md");if(!Ne(l))continue;let c={path:l,type:"skill",source:"plugin"};s&&(c.plugin_key=s),t.push(c)}for(let i of Ms){let l=Re(r.path,`${i}s`);if(Ne(l))for(let c of vn(l)){if(!c.endsWith(".md"))continue;let u={path:Re(l,c),type:i,source:"plugin"};s&&(u.plugin_key=s),t.push(u)}}}return t}function $s(e=Re(ce(),"settings.json")){if(!Ne(e))return[];try{let t=du(e,"utf8"),r=JSON.parse(t).hooks;if(!r||typeof r!="object")return[];let o=[];for(let[s,a]of Object.entries(r))if(Array.isArray(a))for(let i=0;i<a.length;i++)o.push({event:s,index:i,raw:a[i]});return o}catch{return[]}}function vn(e){try{return uu(e).filter(t=>!t.startsWith("."))}catch{return[]}}var Fs=z.object({path:z.string(),type:z.enum(["skill","command","agent","hook"]),source:z.enum(["user","plugin"]),plugin_key:z.string().optional(),verdict:z.enum(["correct","misfit","outlier"]),recommended_type:z.string(),rationale:z.string(),confidence:z.enum(["high","med","low"])}),Ls=z.record(z.string(),z.record(z.string(),z.number())),Sb=z.object({inventory:z.object({user:Ls,plugin:Ls}),misfits:z.array(Fs),briefs_written:z.number(),total_artifacts:z.number()}),pu=z.object({writeBriefs:z.boolean().optional(),scope:z.enum(["user","plugin","all"]).optional()}),mu=["skill","command","agent"],Us=["skill","command","agent","hook"];function fu(e){return{runUserDiscovery:e!=="plugin",runPluginDiscovery:e!=="user",runHookInspector:e!=="plugin"}}function gu(e){let t=()=>{let s={};for(let a of Us)s[a]={correct:0,misfit:0,outlier:0};return s},n={user:t(),plugin:t()};for(let s of e)n[s.source][s.type][s.verdict]+=1;let r={high:0,med:1,low:2},o=e.filter(s=>s.verdict==="misfit").slice().sort((s,a)=>r[s.confidence]-r[a.confidence]);return{inventory:n,misfits:o}}function hu(e){return e.verdict==="misfit"&&e.confidence==="high"&&e.source==="user"}function yu(e){let t=e.filter(o=>o.source==="user"),n=e.filter(o=>o.source==="plugin"),r=["","## Discovered artifacts (audit only these)",""];if(r.push('### User-scope artifacts (set `"source": "user"`, omit `plugin_key`)'),t.length===0)r.push("(none discovered)");else for(let o of t)r.push(`- ${o.path}`);if(r.push(""),r.push('### Plugin-scope artifacts (set `"source": "plugin"`, copy `plugin_key` from each entry)'),n.length===0)r.push("(none discovered)");else for(let o of n){let s=o.plugin_key??"<unknown>";r.push(`- ${o.path} (plugin_key: ${s})`)}return r.join(`
856
+ `)}function ku(e,t){let n=["","## Discovered hooks (audit only these)",""];if(n.push(`Settings file (use this absolute path verbatim in each verdict's \`path\` field): \`${e}\``),n.push(""),t.length===0)return n.push("(no hooks discovered)"),n.join(`
857
+ `);for(let r of t){let o=`${r.event}-${r.index}`;n.push(`### Hook \`${o}\``),n.push(""),n.push("```json"),n.push(JSON.stringify(r.raw,null,2)),n.push("```"),n.push("")}return n.join(`
858
+ `)}function bu(e,t){if(!t)return{kind:"failure",message:`${e}: no result`};if(t.schemaError)return{kind:"failure",message:`${e}: schema mismatch \u2014 ${t.schemaError.message}`};if(t.status!=="succeeded"){let n=t.error?` \u2014 ${t.error.message}`:"";return{kind:"failure",message:`${e}: ${t.status}${n}`}}return t.output?{kind:"success",output:t.output}:{kind:"failure",message:`${e}: no output`}}async function wu(e,t){let n=typeof e=="object"&&e!==null?e:{},r=pu.parse(n),o=r.writeBriefs??!0,s=r.scope??"all",a=fu(s);if(!t?.sessionId)throw new Error("audit-fit requires a parent session with sessionId");let i=t.sessionId,l=G("audit-fit"),c={skill:l["01-skill-inspector.md"],command:l["02-command-inspector.md"],agent:l["03-agent-inspector.md"],hook:l["04-hook-inspector.md"]};for(let k of Us)if(!c[k])throw new Error(`audit-fit skill missing inspector prompt for ${k}`);let u=a.runUserDiscovery?Rs():[],p=a.runPluginDiscovery?_s():[],m={skill:[],command:[],agent:[]};for(let k of[...u,...p])m[k.type].push(k);let f=new _,g=()=>async k=>de.allowedTools.includes(k)?{behavior:"allow"}:{behavior:"deny",message:`Tool ${k} not allowed for audit-fit inspectors. Allowed tools: ${de.allowedTools.join(", ")}`},y=[];for(let k of mu){let C=m[k];if(C.length===0)continue;let x=c[k];x&&y.push({type:k,prompt:`${x}
859
+ ${yu(C)}`,artifacts:C,runPrompt:`Inspect every ${k} listed in the artifact section.`})}if(a.runHookInspector){let k=c.hook;if(k){let C=Ut(ce(),"settings.json"),x=$s(C);y.push({type:"hook",prompt:`${k}
860
+ ${ku(C,x)}`,artifacts:[],runPrompt:`Inspect every hook listed in the Discovered hooks section. Settings file: ${C}.`})}}let h=[];if(y.length>0){let k=await Promise.all(y.map(M=>f.forkSubagent({parent:{sessionId:i},config:{model:"sonnet",systemPrompt:`${de.systemPrompt}
861
+
862
+ ${M.prompt}`,canUseTool:g()},idPrefix:`inspector-${M.type}`,outputSchema:z.array(Fs)}))),C=await bn(y.map((M,ne)=>{let H=k[ne];if(!H)throw new Error(`audit-fit: missing handle for ${M.type} inspector`);return{handle:H,prompt:M.runPrompt}}),{failFast:!1}),x=[];for(let M=0;M<C.length;M++){let ne=C[M],H=y[M];if(!H)continue;let j=bu(H.type,ne);if(j.kind==="failure"){x.push(j.message);continue}let I=new Map;for(let X of H.artifacts)I.set(X.path,X.source);for(let X of j.output){if(H.type==="hook"){if(X.source!=="user"){x.push(`${H.type}: hook verdict has source=${X.source} (must be 'user')`);continue}}else{let te=I.get(X.path);if(te===void 0){x.push(`${H.type}: verdict for unknown path ${X.path} (not in discovered list)`);continue}if(X.source!==te){x.push(`${H.type}: verdict source mismatch for ${X.path} (expected ${te}, got ${X.source})`);continue}}h.push(X)}}if(x.length>0){let M=x.map(ne=>` - ${ne}`).join(`
863
+ `);throw new Error(`audit-fit: ${x.length} inspector failure(s):
864
+ ${M}`)}}let{inventory:b,misfits:v}=gu(h),w=0;if(o){let k=process.env.HOME||process.env.USERPROFILE||"~",C=Ut(k,".claude","agent-framework","briefs");await Os(C,{recursive:!0});for(let x of v.filter(hu)){let M=x.path.replace(/[^a-z0-9]+/gi,"-").toLowerCase().slice(0,30),ne=Ut(C,`audit-fit-${M}.md`),H=`---
865
+ theme: audit-fit
866
+ session_count: 1
867
+ ---
868
+
869
+ # Audit: ${x.path}
870
+
871
+ **Current type:** ${x.type}
872
+ **Recommended type:** ${x.recommended_type}
873
+
874
+ ## Rationale
875
+
876
+ ${x.rationale}
877
+
878
+ ## Migration Steps
879
+
880
+ 1. Review the artifact in \`${x.path}\`
881
+ 2. Evaluate the recommended change to \`${x.recommended_type}\`
882
+ 3. If appropriate, refactor using the patterns in \`/forge\` or the public plugin
883
+
884
+ ---
885
+ Generated by audit-fit on ${new Date().toISOString().split(".")[0]}Z
886
+ `;await Ds(ne,H),w++}}let P=process.env.HOME||process.env.USERPROFILE||"~",T=Ut(P,".claude","agent-framework");await Os(T,{recursive:!0});let L=k=>{let C=0;for(let x of Object.values(k))for(let M of Object.values(x))C+=M;return C},E=k=>{let C=b.user[k]??{},x=b.plugin[k]??{},M=ne=>Object.values(ne).reduce((H,j)=>H+j,0);return M(C)+M(x)},S={timestamp:new Date().toISOString(),surface:"afk",scope:s,total_artifacts:h.length,misfits_count:v.length,briefs_written:w,by_source:{user:L(b.user),plugin:L(b.plugin)},by_type:{skill:E("skill"),command:E("command"),agent:E("agent"),hook:E("hook")}},R=Ut(T,"audit-fit-telemetry.jsonl");return await Ds(R,JSON.stringify(S)+`
887
+ `),{inventory:b,misfits:v,briefs_written:w,total_artifacts:h.length}}var vu={name:"audit-fit",description:"Audit ~/.afk artifacts (skills, commands, agents, hooks) for correct type categorization. Walks user-scope dirs (~/.afk/{skills,commands,agents}/) and every plugin installed under ~/.afk/plugins/ (flat and marketplace-cache layouts), plus ~/.afk/settings.json for hooks. Dispatches per-type inspectors in parallel, applies decision heuristics (progressive-disclosure value, isolation need, deterministic vs. reasoning), flags misfits. Generates migration briefs only for user-scope misfits (plugin misfits are inventory-only \u2014 refactoring vendored plugin code is the maintainer's job). Optional `scope` input filters to `user`, `plugin`, or `all` (default). Use for inventory audits after bulk authoring, imports, or periodic hygiene.",handler:wu,argumentHint:"[--write-briefs]",whenToUse:"When the user wants ~/.afk artifacts (skills, commands, agents, hooks) audited for correct type categorization.",flags:["--write-briefs"]};Te(vu);import{z as $}from"zod";import{execFile as Eu}from"node:child_process";import{promisify as Pu}from"node:util";import{tmpdir as Cu}from"node:os";import{join as Iu}from"node:path";function Ns(e){return e.confidence<.5?{verify:!0,reason:`low confidence (${e.confidence.toFixed(2)} < ${.5})`}:e.boundary_flag&&e.boundary_flag.length>0?{verify:!0,reason:`boundary flag set: ${e.boundary_flag}`}:e.coverage_gaps&&e.coverage_gaps.length>0?{verify:!0,reason:`coverage gap${e.coverage_gaps.length===1?"":"s"}: ${e.coverage_gaps.length} unresolved`}:{verify:!1,reason:`confidence ${e.confidence.toFixed(2)} with no gaps or boundary`}}import{fileURLToPath as Su}from"node:url";import{dirname as xu}from"node:path";var Tu=Su(import.meta.url),Ib=xu(Tu),_r={name:"git-investigator",systemPrompt:'---\nname: git-investigator\ndescription: Read-only git specialist. Dispatched by research-agent (or any research-shaped caller) when a finding requires git history, reflog, diff, blame, branch/remote state, or merge-base analysis. Runs git commands only \u2014 no mutations, no shell escapes.\nmodel: sonnet\ntools: Bash, Read, Grep, Glob\n---\n\nYou are `git-investigator`, a leaf sub-agent specialized for read-only git queries.\n\nYou have Bash, Read, Grep, and Glob. You do not dispatch other sub-agents. You do not Edit or Write. Your Bash surface is restricted **by this prompt** to `git ...` invocations and benign output-shaping pipes.\n\n## Allowed commands\n\nRead-only git only:\n\n- `git status`, `git log`, `git diff`, `git show`\n- `git rev-parse`, `git rev-list`, `git reflog`\n- `git branch -v / -vv / -a` (list only)\n- `git remote -v`, `git ls-remote`\n- `git ls-files`, `git blame`\n- `git merge-base`, `git for-each-ref`, `git describe`\n- `git cat-file`, `git shortlog`\n- `git tag` (list/show only)\n- `git stash list`, `git stash show`\n- `git config --get`, `git config --get-all`, `git config --list`\n- `git worktree list` (read only)\n\nOutput-shaping pipes are fine: `| head`, `| tail`, `| wc`, `| grep`, `| jq`, `| awk \'NR==...\'` (for formatting only \u2014 no mutations).\n\n## Forbidden\n\nAnything that mutates repo or working tree state:\n\n- `commit`, `push`, `pull`, `fetch --prune`\n- `reset`, `revert`, `rebase`, `merge`, `cherry-pick`\n- `checkout` (except `checkout -- <path>` file-restore, and even that is mutation \u2014 avoid it, just report the need)\n- `restore`, `switch`\n- `branch -d / -D / -m / -M`, `branch <new>`\n- `stash push / pop / drop / apply / clear`\n- `tag -d`, creating a new tag\n- `remote add / remove / set-url`\n- `config --set`, `config --unset`\n- `gc`, `fsck`, `prune`, `reflog delete`, `reflog expire`\n- `filter-branch`, `filter-repo`\n- `worktree add / remove / move`\n- `hooks install`, `submodule add / update`\n- Any non-`git` command that mutates: `rm`, `mv`, `cp` (writes), `sed -i`, `> file`, `>> file`, `tee`, `curl`, `wget`, `pip install`, shell builtins that change state.\n\nIf the caller asks for any of the above, do not run it. Return `scope_check: "requires mutation: <reason>"` and stop.\n\n## Behavior\n\n- Run the minimum set of commands needed. Prefer `git log -n 5 --oneline -- <path>` over `git log -- <path>` when a count is fine.\n- Cite concrete evidence: commit SHAs (short form OK), ref names, `path:line` references from blame, diff hunks trimmed to the relevant range.\n- Use `Read`/`Grep`/`Glob` for follow-up inspection of files the git output identifies (e.g., `git show SHA:path | head` then `Read` the current file to diff mentally).\n- Do not speculate beyond what the commands show. If a question needs history the commands don\'t surface (deleted-file recovery, ancient reflog that has expired), say so in `caveats`.\n- Keep output compact \u2014 dispatchers merge your findings into a larger response. No preamble, no ceremony.\n\n## Return shape\n\n```\n{\n "findings": "<summary of what the git data shows>",\n "evidence": ["<SHA>", "<ref>", "<path:line>", ...],\n "git_commands_run": ["git log ...", "git diff ...", ...],\n "caveats": "<gaps, ambiguity, or \'none\'>",\n "scope_check": "pure git research" | "requires mutation: <reason>"\n}\n```\n\nBegin your response with the first schema field. No preamble.\n',sourcePath:"agent-framework-private/agents/git-investigator.md",allowedTools:["Bash","Read","Grep","Glob"],description:"Read-only git specialist. Dispatched by research-agent (or any research-shaped caller) when a finding requires git history, reflog, diff, blame, branch/remote state, or merge-base analysis. Runs git commands only \u2014 no mutations, no shell escapes.",model:"sonnet"};function $r(e){let t={description:e.description,prompt:e.systemPrompt};return e.allowedTools&&(t.tools=[...e.allowedTools]),e.model&&(t.model=e.model),t}var js=Pu(Eu),Ws=$.object({id:$.string(),claim:$.string(),confidence:$.number().min(0).max(1),evidence_sources:$.array($.string()),location:$.string().optional(),proposed_fix:$.string().optional(),coverage_gaps:$.array($.string()).optional(),boundary_flag:$.string().optional()}),Au=$.object({hypothesis_id:$.string(),claim:$.string(),verdict:$.enum(["VERIFIED","REFUTED","INCONCLUSIVE"]),evidence:$.string(),gate_reason:$.string()}),Ks=$.object({hypothesis_id:$.string(),reproducer_passed:$.boolean(),regressions:$.array($.string()),confidence:$.number().min(0).max(1),verification_log:$.string()}),Gb=$.object({reproducer:$.string().optional(),hypotheses:$.array(Ws),premise_verifications:$.array(Au).optional(),winner:$.object({hypothesis_id:$.string(),verification_log:$.string(),proposed_fix:$.string()}).optional(),verification_results:$.array(Ks).optional()});async function Mu(e,t){let n=e.map(l=>({hypothesis:l,decision:Ns(l)})).filter(l=>l.decision.verify);if(n.length===0)return{premise_verifications:[],hypotheses_to_test:e};let r=[],o;try{r=await t(n.map(l=>l.hypothesis.claim))}catch(l){o=l instanceof Error?l.message:String(l)}let s=n.map((l,c)=>{let u=r[c];return o!==void 0?{hypothesis_id:l.hypothesis.id,claim:l.hypothesis.claim,verdict:"INCONCLUSIVE",evidence:`shadow-verify dispatch failed: ${o}`,gate_reason:l.decision.reason}:u?{hypothesis_id:l.hypothesis.id,claim:l.hypothesis.claim,verdict:u.verdict,evidence:u.evidence,gate_reason:l.decision.reason}:{hypothesis_id:l.hypothesis.id,claim:l.hypothesis.claim,verdict:"INCONCLUSIVE",evidence:"no verifier result for this claim",gate_reason:l.decision.reason}}),a=new Set(s.filter(l=>l.verdict==="REFUTED").map(l=>l.hypothesis_id)),i=a.size===0?e:e.filter(l=>!a.has(l.id));return{premise_verifications:s,hypotheses_to_test:i}}async function Ru(e,t){let n=(()=>{if(typeof e=="string")return{failure:e,repoPath:process.cwd(),context:"",maxHypotheses:4};if(typeof e=="object"&&e!==null){let x=e;if(typeof x.failure=="string")return{failure:x.failure,repoPath:x.repoPath||process.cwd(),context:x.context||"",maxHypotheses:Math.min(x.maxHypotheses||4,4)}}throw new Error("diagnose handler requires input.failure (string) or a string argument")})();if(!t?.sessionId)throw new Error("diagnose requires a parent session with sessionId");let r=t.sessionId,o=G("diagnose"),s=o["system.md"],a=o["research.md"],i=o["hypothesis.md"],l=o["verify.md"];if(!s||!a||!i||!l)throw new Error("diagnose skill missing required prompts (system.md, research.md, hypothesis.md, verify.md)");let c=new _,u=_u(n.context),p=`${de.systemPrompt}
888
+
889
+ ${a}
890
+
891
+ Focus: CODEBASE
892
+ Failure: ${n.failure}${n.context?`
893
+ Context: ${n.context}`:""}`,m=`${de.systemPrompt}
894
+
895
+ ${a}
896
+
897
+ Focus: GIT HISTORY
898
+ Failure: ${n.failure}${n.context?`
899
+ Context: ${n.context}`:""}
900
+
901
+ Repo: ${n.repoPath}`,f=await c.forkSubagent({parent:{sessionId:r},config:{model:"sonnet",systemPrompt:p,canUseTool:Bs()},idPrefix:"diagnose-codebase-research"}),g=await c.forkSubagent({parent:{sessionId:r},config:{model:"sonnet",systemPrompt:m,cwd:n.repoPath,agents:{"git-investigator":$r(_r)},canUseTool:$u()},idPrefix:"diagnose-git-research"}),[y,h]=await bn([{handle:f,prompt:"Analyze the codebase for potential causes of this failure."},{handle:g,prompt:"Analyze git history for recent changes that could cause this failure."}],{failFast:!1}),b={codebase:y?.output||y?.message||"No output",git:h?.output||h?.message||"No output"},v=await c.forkSubagent({parent:{sessionId:r},config:{model:"sonnet",systemPrompt:`${s}
902
+
903
+ ${i}`,canUseTool:Bs()},idPrefix:"diagnose-hypothesis-synthesis",outputSchema:$.object({hypotheses:$.array(Ws)})}),w=`Given these research findings, synthesize 2\u20134 hypotheses (max 4):
904
+
905
+ CODEBASE RESEARCH:
906
+ ${JSON.stringify(b.codebase,null,2)}
907
+
908
+ GIT RESEARCH:
909
+ ${JSON.stringify(b.git,null,2)}
910
+
911
+ Original failure: ${n.failure}`,P;try{P=await v.runToResult(w)}finally{await v.teardown().catch(()=>{})}if(P.status!=="succeeded"||!P.output)throw new Error(`hypothesis synthesis failed: ${J(P)}`);let T=P.output.hypotheses.slice(0,n.maxHypotheses);if(T.length===0)return{reproducer:u,hypotheses:[],verification_results:[]};let{premise_verifications:L,hypotheses_to_test:E}=await Mu(T,async x=>{let M=oe("shadow-verify");if(!M)throw new Error("shadow-verify skill not registered");return(await M.handler({claims:x,context:`Original failure: ${n.failure}`},t)).verifications});if(E.length===0)return{reproducer:u,hypotheses:T,premise_verifications:L,verification_results:[]};let S=u||n.failure,R=E.map(x=>Ou(x,S,n.repoPath,r,l,c)),k=await Promise.all(R),C=k.find(x=>x.reproducer_passed);return{reproducer:u,hypotheses:T,premise_verifications:L.length>0?L:void 0,winner:C?{hypothesis_id:C.hypothesis_id,verification_log:C.verification_log,proposed_fix:T.find(x=>x.id===C.hypothesis_id)?.proposed_fix||""}:void 0,verification_results:k}}function _u(e){if(!e)return;let t=[/test:\s*(.+)/i,/command:\s*(.+)/i,/reproducer:\s*(.+)/i,/failing test:\s*(.+)/i];for(let n of t){let r=e.match(n);if(r)return r[1]}}function Bs(){return async e=>de.allowedTools.includes(e)?{behavior:"allow"}:{behavior:"deny",message:`Tool ${e} not allowed. Allowed tools: ${de.allowedTools.join(", ")}`}}var Hs=[...de.allowedTools,"Agent"];function $u(){return async e=>Hs.includes(e)?{behavior:"allow"}:{behavior:"deny",message:`Tool ${e} not allowed for git orchestrator. Allowed tools: ${Hs.join(", ")}`}}async function Ou(e,t,n,r,o,s){let a=Iu(Cu(),`diagnose-hyp-${e.id}-${Date.now()}`),i;try{await js("git",["worktree","add","--detach",a,"HEAD"],{cwd:n}),i=await s.forkSubagent({parent:{sessionId:r},config:{model:"sonnet",systemPrompt:`${o}
912
+
913
+ You are testing in an isolated worktree at: ${a}`,canUseTool:Du()},idPrefix:`diagnose-verifier-${e.id}`,outputSchema:Ks});let l=`Test this hypothesis:
914
+
915
+ Claim: ${e.claim}
916
+ Location: ${e.location||"unknown"}
917
+ Proposed fix: ${e.proposed_fix||"unknown"}
918
+ Reproducer: ${t}
919
+
920
+ Working directory (isolated): ${a}`,c=await i.runToResult(l);return c.status!=="succeeded"||!c.output?{hypothesis_id:e.id,reproducer_passed:!1,regressions:[],confidence:0,verification_log:`Verification failed: ${J(c)}`}:c.output}catch(l){return{hypothesis_id:e.id,reproducer_passed:!1,regressions:[],confidence:0,verification_log:`Error during verification: ${l instanceof Error?l.message:String(l)}`}}finally{if(i)try{await i.teardown()}catch{}try{await js("git",["worktree","remove","--force",a],{cwd:n})}catch{}}}function Du(){let e=["Edit","Write","Bash","Agent","Task"];return async t=>e.includes(t)?{behavior:"deny",message:`Tool ${t} not allowed in worktree verification. Verification is read-only.`}:de.allowedTools.includes(t)?{behavior:"allow"}:{behavior:"deny",message:`Tool ${t} not allowed. Allowed tools: ${de.allowedTools.join(", ")}`}}var Lu={name:"diagnose",description:"Parallel root-cause analysis for bugs and failing tests \u2014 forks research subagents, synthesizes hypotheses, and validates each in isolated worktrees",handler:Ru,argumentHint:"<bug-or-failing-test>",whenToUse:"When a test is failing, a bug is reported, or behavior is unexplained \u2014 runs parallel root-cause analysis with hypothesis sub-agents."};Te(Lu);import{z as be}from"zod";import{execFile as qu}from"child_process";import{promisify as Ju}from"util";import{mkdir as Zs,writeFile as ei}from"fs/promises";import{existsSync as Xs}from"fs";import{join as je}from"path";import{fileURLToPath as Qu}from"url";import{fileURLToPath as Fu}from"node:url";import{dirname as Uu}from"node:path";var Nu=Fu(import.meta.url),Jb=Uu(Nu),Or={name:"qualify",systemPrompt:`---
921
+ name: qualify
922
+ description: Gate proposed plugin skills. Approve only real force multipliers. Reject reminders, checklists, best-practice nudges, and generic execution advice. Invoke when evaluating whether a proposed skill deserves top-level status in this plugin.
923
+ model: sonnet
924
+ skills: [contract]
925
+ ---
926
+
927
+ You are \`qualify\`, a rigorous evaluator of proposed plugin skills for the awa-dev plugin.
928
+
929
+ This plugin only contains **force multipliers**: compact, reusable prompts that unlock disproportionate workflow uplift from capabilities the agent already has.
930
+
931
+ Reject anything that is mainly:
932
+ - a reminder
933
+ - a checklist
934
+ - a quality nudge
935
+ - a best-practice instruction
936
+ - a subordinate behavior
937
+ - something the base agent can already infer reliably
938
+
939
+ ## Input
940
+
941
+ You accept any of:
942
+ - raw idea (one sentence or paragraph)
943
+ - name + description pair
944
+ - full draft SKILL.md
945
+
946
+ First, normalize input to \`{name, description, body, inferred_purpose}\`. If fields are missing, infer them explicitly and state the inference.
947
+
948
+ ## Required analysis
949
+
950
+ 1. **Normalize input** to \`{name, description, body, inferred_purpose}\`
951
+ 2. **Overlap check** \u2014 read every \`skills/*/SKILL.md\` in the plugin. For each skill, compare on three functional dimensions:
952
+ - **Sub-agent dispatch pattern**: What agents are dispatched, in what waves, and how results merge?
953
+ - **Failure mode fixed**: What default behavior does the candidate fix?
954
+ - **Machinery exploited**: What tools/MCP/plan-mode/skills does it leverage?
955
+ Output one line per skill with % functional overlap, citing which dimension(s) match. Report ALL overlaps \u226540%. If any skill shares \u226575% on one dimension or \u226560% on two or more dimensions, short-circuit to SALVAGE (fold) or REJECT before scoring
956
+ 3. **Identify default failure mode** the candidate fixes
957
+ 4. **Identify latent machinery** it exploits (sub-agents, specific MCP servers, plan mode, parallel tools, skill composition)
958
+ 5. **Apply hard gates**: compactness, outsized uplift
959
+ 6. **Score Stage 1** \u2014 force-multiplier strength rubric (definitions below)
960
+ 7. **Score Stage 2** \u2014 failure-resilience rubric (definitions below). Measures how the candidate fails, not how strongly it succeeds.
961
+ 8. **Run rejection checks**
962
+ 9. **Decide** per thresholds below
963
+ 10. If not APPROVE, state where it belongs instead
964
+ 11. If SALVAGE, rewrite it into a stronger force multiplier
965
+
966
+ ## Stage 1 rubric \u2014 force-multiplier strength (score 1\u20135)
967
+
968
+ - **Leverage** \u2014 workflow change per token of skill content. 5 = massive change from tiny prompt
969
+ - **Architecture Awareness** \u2014 exploits latent machinery (sub-agents, MCP servers, plan mode, skill composition) beyond base prompting. 5 = unlocks machinery the default agent doesn't reach
970
+ - **Generality** \u2014 applies across many tasks/projects. 5 = reused weekly across contexts; 1 = one-off
971
+ - **Non-default Value** \u2014 gap between base-agent behavior and skill-invoked behavior. 5 = agent wouldn't do this without the skill
972
+ - **Workflow Impact** \u2014 does the session's *shape* change from the base agent's default? 5 = fundamentally different session (multi-wave parallel dispatch, competitive implementations, phased gates). 4 = clear parallel dispatch the agent wouldn't naturally do (multiple sub-agents with distinct roles). 3 = modest structural change (simple 2-agent parallel, or sequential phases agent might infer). 2 = minor change (better ordering, no parallelism). 1 = cosmetic (reminder, nudge)
973
+ - **Missability** \u2014 without the skill, how likely is the agent to default past this behavior. 5 = almost always missed; 1 = agent does it anyway
974
+
975
+ ## Stage 2 rubric \u2014 failure resilience (score 0\u20133)
976
+
977
+ Measures how the skill behaves when it fails, not how strongly it succeeds. A candidate that succeeds loudly but fails in a crater is more dangerous than one that succeeds quietly and fails into a checkpoint. Scale: 0 = bad/absent, 1 = weak, 2 = decent, 3 = strong by default. Total 0\u201324.
978
+
979
+ - **Bounded Damage** \u2014 when it fails, how much can it mess up? 3 = naturally sandboxed or reversible; 0 = broad, irreversible damage.
980
+ - **State Preservation** \u2014 does failure leave usable progress (checkpoints, artifacts, resumable state)? 3 = clear ladder back; 0 = wipes progress or leaves nothing.
981
+ - **Legibility** \u2014 can you tell what happened? 3 = failure is named, localized, easy to interpret; 0 = opaque.
982
+ - **Assumption Exposure** \u2014 does failure reveal what it was counting on? 3 = key assumptions visible before or during action; 0 = hidden assumptions stay hidden.
983
+ - **Recovery Guidance** \u2014 does failure point to the next move? 3 = specific safest next step; 0 = dead end.
984
+ - **Value Before Completion** \u2014 even if it cannot finish, does partial output help? 3 = useful value emerges well before completion; 0 = all-or-nothing.
985
+ - **Failure Elevation** \u2014 does it trade a low-level dumb failure for a higher-level diagnosable one? 3 = consistently pushes failure upward into strategy/dependency/ambiguity space; 0 = fails dumb and low-level.
986
+ - **Default Reversibility** \u2014 are early moves safe by default (map, diff, dry-run, isolate, draft first)? 3 = strongly defaults to reconnaissance; 0 = commits/edits/sends too early.
987
+
988
+ ### Stage 2 score bands
989
+ - **0\u20138 \u2192 Fragile** \u2014 breaks are mostly wasteful; triggers Stage-2 downgrade (see Decision rule 6).
990
+ - **9\u201314 \u2192 Functional but crude** \u2014 sometimes useful, failure still clumsy.
991
+ - **15\u201319 \u2192 Strong** \u2014 usually breaks in ways that preserve momentum.
992
+ - **20\u201324 \u2192 Operator-grade** \u2014 failure is part of the workflow.
993
+
994
+ ### Optional \`failure_modes\` frontmatter (for skill authors)
995
+
996
+ Authors may pre-declare the named ways a skill is expected to break by adding an optional \`failure_modes: [...]\` list to the SKILL.md YAML frontmatter. The field is the author-side companion to the Stage 2 rubric above: declaring expected failures up front makes them legible, scoreable, and easier to harden. The field is optional and unvalidated \u2014 no gate enforces its presence, and its absence does not block APPROVE. When present, use the shared taxonomy below so entries compare across skills.
997
+
998
+ Taxonomy (free-form strings, shared vocabulary):
999
+
1000
+ - \`premature execution\` \u2014 acts before mapping
1001
+ - \`bad decomposition\` \u2014 splits work along the wrong seam
1002
+ - \`dependency blindness\` \u2014 misses a required predecessor
1003
+ - \`false completeness\` \u2014 declares done while blockers remain
1004
+ - \`tool thrash\` \u2014 repeats the same tool call hoping for a different result
1005
+ - \`confident fabrication\` \u2014 produces plausible-sounding output with no source
1006
+ - \`over-scaffolding\` \u2014 builds machinery that isn't used
1007
+ - \`local optimization trap\` \u2014 improves one step while worsening the whole
1008
+
1009
+ Example:
1010
+
1011
+ \`\`\`yaml
1012
+ ---
1013
+ name: parallelize
1014
+ description: Transforms a linear plan into waves of parallel sub-agents.
1015
+ failure_modes:
1016
+ - bad decomposition
1017
+ - tool thrash
1018
+ ---
1019
+ \`\`\`
1020
+
1021
+ When scoring Stage 2, cross-check the skill's declared \`failure_modes\` against the dimensions scored 0\u20131. A skill that declares \`tool thrash\` but scores 3 on Legibility and Recovery Guidance is self-aware and well-hardened; one that declares nothing and scores poorly on Assumption Exposure is likely shipping blind.
1022
+
1023
+ ## Rejection checks (Yes/No)
1024
+
1025
+ - Reminder-like
1026
+ - Checklist-like
1027
+ - Best-practice nudge
1028
+ - Subordinate behavior (lives better inside another skill's body)
1029
+ - Better as normal prompting (the agent already infers this)
1030
+ - Better folded into another skill
1031
+ - No material workflow shape change (WI \u22642 AND body is >50% spec/reference AND no sub-agent dispatch in body)
1032
+
1033
+ ## Decision thresholds
1034
+
1035
+ Apply in order \u2014 first match wins:
1036
+
1037
+ 1. Any hard gate FAIL \u2192 **REJECT** (SALVAGE if trivially fixable)
1038
+ 2. Max overlap \u226575% on one dimension or \u226560% on two+ dimensions \u2192 **SALVAGE** (fold) or **REJECT**
1039
+ 3. Any rejection check = Yes \u2192 **REJECT** (SALVAGE only if the sole Yes is "better folded into another skill")
1040
+ 4. Any single Stage 1 rubric dimension \u22642 \u2192 downgrade one tier from the rubric-total result (APPROVE\u2192SALVAGE, SALVAGE\u2192REJECT)
1041
+ 5. Workflow Impact \u22643 \u2192 downgrade one tier (session shape must materially change for this plugin)
1042
+ 6. Stage 2 failure-resilience total \u22648 (Fragile band) \u2192 downgrade one tier (a fragile force multiplier is still dangerous). Note which dimensions scored 0\u20131 in the Rewrite target so the skill can be hardened.
1043
+ - Rules 4, 5, and 6 do not stack \u2014 apply at most one downgrade per candidate. If multiple fire, prefer rule 6 (failure behavior is the most costly to miss).
1044
+ 7. Stage 1 total \u226524/30 \u2192 **APPROVE**
1045
+ 8. Stage 1 total 18\u201323/30 \u2192 **SALVAGE**
1046
+ 9. Stage 1 total <18/30 \u2192 **REJECT**
1047
+
1048
+ Cite the rule number that produced the decision.
1049
+
1050
+ ## Output format
1051
+
1052
+ ### Candidate
1053
+ - Name:
1054
+ - Input form: (idea | name+description | draft SKILL.md)
1055
+ - Inferred purpose:
1056
+ - Default failure it fixes:
1057
+ - Latent machinery exploited:
1058
+
1059
+ ### Overlap check
1060
+ One line per existing skill: \`<skill-name>: X% \u2014 <dimension(s)>: <reason>\`.
1061
+ Report all \u226540%. Max overlap: X% (<skill-name>, <dimension>).
1062
+
1063
+ ### Hard gate
1064
+ - Compactness: PASS/FAIL \u2014 <reason>
1065
+ - Outsized uplift: PASS/FAIL \u2014 <reason>
1066
+
1067
+ ### Stage 1 rubric \u2014 force-multiplier strength
1068
+ - Leverage: X/5
1069
+ - Architecture Awareness: X/5
1070
+ - Generality: X/5
1071
+ - Non-default Value: X/5
1072
+ - Workflow Impact: X/5
1073
+ - Missability: X/5
1074
+ - **Stage 1 total: X/30**
1075
+
1076
+ ### Stage 2 rubric \u2014 failure resilience
1077
+ - Bounded Damage: X/3
1078
+ - State Preservation: X/3
1079
+ - Legibility: X/3
1080
+ - Assumption Exposure: X/3
1081
+ - Recovery Guidance: X/3
1082
+ - Value Before Completion: X/3
1083
+ - Failure Elevation: X/3
1084
+ - Default Reversibility: X/3
1085
+ - **Stage 2 total: X/24** (band: Fragile | Functional but crude | Strong | Operator-grade)
1086
+
1087
+ ### Rejection checks
1088
+ - Reminder-like: Yes/No
1089
+ - Checklist-like: Yes/No
1090
+ - Best-practice nudge: Yes/No
1091
+ - Subordinate behavior: Yes/No
1092
+ - Better as normal prompting: Yes/No
1093
+ - Better folded into another skill: Yes/No
1094
+ - No material workflow shape change: Yes/No
1095
+
1096
+ ### Decision
1097
+ **APPROVE | SALVAGE | REJECT** \u2014 triggered by rule #N.
1098
+
1099
+ ### Reasoning
1100
+ 2\u20134 sentences.
1101
+
1102
+ ### Placement
1103
+ Where it belongs if not APPROVE.
1104
+
1105
+ ### Rewrite
1106
+ Include only if SALVAGE.
1107
+
1108
+ ### Emit telemetry
1109
+
1110
+ After producing the output above, append one JSONL line to the qualify ledger so scores become a queryable corpus. Do this for every verdict \u2014 APPROVE, SALVAGE, and REJECT \u2014 the ledger is a decision record, not a success log.
1111
+
1112
+ \`\`\`bash
1113
+ mkdir -p ~/.claude/agent-framework
1114
+ cat >> ~/.claude/agent-framework/qualify-telemetry.jsonl <<EOF
1115
+ {"timestamp":"$(date -u +%Y-%m-%dT%H:%M:%SZ)","candidate_name":"<name>","verdict":"<APPROVE|SALVAGE|REJECT>","rubric_total":<int 0-30>,"failure_resilience_total":<int 0-24>,"rule_triggered":<int 1-9>}
1116
+ EOF
1117
+ \`\`\`
1118
+
1119
+ Substitute: \`<name>\` with the normalized hyphen-case slug from Step 1; \`<APPROVE|SALVAGE|REJECT>\` with the verdict from the Decision section; \`<int 0-30>\` with the Stage 1 total; \`<int 0-24>\` with the Stage 2 total; \`<int 1-9>\` with the rule number you cited in Decision.
1120
+
1121
+ If the append fails (permissions, disk full, unwritable path), do not retry and do not surface an error in the final output \u2014 the verdict prose above is the primary contract. Telemetry is observability; verdict integrity comes first.
1122
+
1123
+ ## Calibration
1124
+
1125
+ **APPROVE example \u2014 \`parallelize\`**
1126
+ - Stage 1: Leverage 5, Arch 5, Generality 4, Non-default 5, Workflow 5, Missability 5 \u2192 **29/30**
1127
+ - Stage 2: Bounded Damage 3, State Preservation 3, Legibility 2, Assumption Exposure 2, Recovery Guidance 2, Value Before Completion 3, Failure Elevation 2, Default Reversibility 3 \u2192 **20/24** (Operator-grade)
1128
+ - Changes session shape (waves of parallel sub-agents). Exploits Agent tool + plan mode. Compact. Agent almost never parallelizes by default. Stage 2 passes \u2014 per-wave isolation bounds damage; wave outputs are usable individually. Rule 7 \u2192 APPROVE.
1129
+
1130
+ **REJECT example \u2014 "remind Claude to write tests before shipping"**
1131
+ - Stage 1: Leverage 1, Arch 1, Generality 3, Non-default 1, Workflow 1, Missability 2 \u2192 **9/30**
1132
+ - Stage 2: not scored (decision reached at rule 3 before Stage 1 completes the gauntlet).
1133
+ - Reminder-like: Yes. No latent machinery. Base agent writes tests when task warrants. Rule 3 \u2192 REJECT. Belongs in CLAUDE.md.
1134
+
1135
+ **Stage-2 downgrade example \u2014 hypothetical "auto-push on every green test"**
1136
+ - Stage 1: Leverage 4, Arch 3, Generality 4, Non-default 4, Workflow 3, Missability 4 \u2192 **22/30**
1137
+ - Stage 2: Bounded Damage 0 (pushes to remote on trigger), State Preservation 2, Legibility 2, Assumption Exposure 0, Recovery Guidance 1, Value Before Completion 1, Failure Elevation 0, Default Reversibility 0 \u2192 **6/24** (Fragile)
1138
+ - Stage 1 alone would land at SALVAGE (rule 8). Rule 6 fires because Stage 2 \u22648 \u2192 downgrade one tier \u2192 **REJECT**. Rewrite target: raise Bounded Damage (dry-run/draft-PR instead of push), Default Reversibility (require confirmation), Assumption Exposure (surface what tests assume before acting).
1139
+
1140
+ Be skeptical. Protect the plugin from fluff. Stage 2 catches patterns that are strong when they work and catastrophic when they don't.
1141
+ `,sourcePath:"agent-framework-local/agents/qualify.md"};import{fileURLToPath as ju}from"node:url";import{dirname as Bu}from"node:path";var Hu=ju(import.meta.url),tw=Bu(Hu);import{mkdir as Gs,writeFile as zs}from"fs/promises";import{join as Sn}from"path";function nt(){return process.env.HOME||process.env.USERPROFILE||"~"}function Wu(){return Sn(nt(),".claude","agent-framework","forge-telemetry.jsonl")}async function _e(e){let t=Wu(),n=Sn(nt(),".claude","agent-framework");await Gs(n,{recursive:!0});let r=new Date().toISOString().split(".")[0]+"Z",o={timestamp:r,surface:"atlas",...e},s=JSON.stringify(o)+`
1142
+ `;return await zs(t,s,{flag:"a"}),r}async function Vs(){let e=Sn(nt(),".claude","agent-framework","ceiling-ledger"),t=Sn(e,"forge-thaw-history.jsonl");await Gs(e,{recursive:!0});let r={timestamp:new Date().toISOString().split(".")[0]+"Z",surface:"atlas",event:"forge.thaw_override",thaw_triggered:!0},o=JSON.stringify(r)+`
1143
+ `;await zs(t,o,{flag:"a"})}import{readFile as Ys,readdir as Ku,writeFile as Gu,mkdir as zu,unlink as Vu}from"fs/promises";import{join as Nt}from"path";import{existsSync as Yu}from"fs";function Dr(){return Nt(nt(),".claude","agent-framework","briefs")}async function qs(e){let t=Nt(Dr(),e+".md"),n=await Ys(t,"utf-8");return{id:e,content:n}}async function Js(){let e=Dr();return Yu(e)?(await Ku(e,{withFileTypes:!0})).filter(r=>r.isFile()&&r.name.endsWith(".md")).map(r=>r.name.slice(0,-3)):[]}async function Lr(e,t){let n=Dr(),r=Nt(n,e+".md"),o=Nt(n,t),s=Nt(o,e+".md");await zu(o,{recursive:!0});let a=await Ys(r,"utf-8");await Gu(s,a,"utf-8"),await Vu(r)}function Qs(e){let t=e.split(`
1144
+ `).map(l=>l.trim()).filter(l=>l),n=t.find(l=>/^(APPROVE|SALVAGE|REJECT)/.test(l));if(!n)return{verdict:"REJECT",feedback:e};let r=n.match(/^(APPROVE|SALVAGE|REJECT)/)?.[1];if(!r)return{verdict:"REJECT",feedback:e};let o=e.match(/score:\s*(\d+)/i),s=o&&o[1]?parseInt(o[1],10):void 0,a=t.indexOf(n),i=t.slice(a+1).join(`
1145
+ `).trim();return{verdict:r,score:s,feedback:i||n}}var Xu=Ju(qu);function Zu(){let e=process.env.AFK_EVAL_HARNESS_ROOT;if(e){let o=je(e,"scripts","eval-harness","runner.py");if(Xs(o))return o}let t=Qu(import.meta.url),n=je(t,"../../../.."),r=je(n,"..","awa-private","scripts","eval-harness","runner.py");if(Xs(r))return r;throw new Error(`Could not find eval-harness runner.py. Tried: ${r}`)}function ed(e){return je(e,"..","..","..","plugins","awa-private")}function td(){let e=process.env.HOME||process.env.USERPROFILE||"~";return je(e,".claude","agent-framework","ceiling-ledger")}function nd(e){let t=e.split(`
1146
+ `),n=[],r=/^\s+✗\s+(\S+):/;for(let o of t){let s=o.match(r);s&&s[1]&&n.push(s[1])}return n}async function rd(e){let t=td(),n=je(t,"qualifications.jsonl");await Zs(t,{recursive:!0});let o=new Date().toISOString().split(".")[0]+"Z",a=JSON.stringify({timestamp:o,surface:"atlas",refers_to_run_id:e,source:"forge-gate-check-ts"})+`
1147
+ `;return await ei(n,a,{flag:"a"}),o}async function od(){let e;try{e=Zu()}catch(l){throw new Error(`Failed to resolve eval-harness runner.py: ${l instanceof Error?l.message:String(l)}`)}let t=ed(e),n="",r="",o=0;try{let l=await Xu("python3",[e,"--plugin-root",t],{timeout:6e4});n=l.stdout||"",r=l.stderr||"",o=0}catch(l){let c=l;if(n=c.stdout||"",r=c.stderr||"",o=typeof c.code=="number"?c.code:1,c.code==="ENOENT"||r&&r.includes("No such file"))throw new Error(`eval-harness runner.py not found at ${e}.`)}let s=o===0?"OPEN":"CLOSED",a=s==="CLOSED"?nd(n):void 0,i;if(s==="OPEN"){let l=new Date().toISOString().split(".")[0]+"Z";i=await rd(l)}return{gate_status:s,exit_code:o,stdout:n,stderr:r||void 0,tasks_failed:a,ledger_entry_ref:i}}var sd=be.object({iteration:be.number().int().positive(),verdict:be.enum(["APPROVE","SALVAGE","REJECT"]),score:be.number().optional(),feedback:be.string()}),Ow=be.object({status:be.enum(["APPROVED","REJECTED","GATE_CLOSED","MAX_ITERATIONS"]),skill_path:be.string().optional(),qualify_verdicts:be.array(sd),brief_id:be.string().optional(),telemetry_ref:be.string()});async function id(e,t){let n=typeof e=="string"?{brief:e}:typeof e=="object"&&e!==null?e:{},r=n.brief,o=n.forceThaw??!1,s=n.maxIterations??3,a="",i=[],l="REJECTED",c,u;try{let p=await od();if(p.gate_status==="CLOSED"&&!o)return a=await _e({event:"forge.gate_check",gate_status:"CLOSED"}),{status:"GATE_CLOSED",qualify_verdicts:[],telemetry_ref:a};o&&p.gate_status==="CLOSED"&&(await Vs(),a=await _e({event:"forge.thaw_override",gate_status:"CLOSED"})),a=await _e({event:"forge.gate_check",gate_status:"OPEN"});let m="",f=!1;if(r)m=r,f=!0;else{let T=await Js();if(T.length>0){let L=T[0],E=await qs(L);m=E.content,u=E.id,f=!0}else{if(!t?.sessionId)throw new Error("forge requires parent session for gap discovery");let E=G("forge")["gap-discovery.md"];if(!E)throw new Error("forge skill missing gap-discovery.md prompt");let k=await(await new _().forkSubagent({parent:{sessionId:t.sessionId},config:{model:"sonnet",systemPrompt:E},idPrefix:"forge-gap-discovery"})).runToResult("Identify the most impactful skill gap.");if(k.status!=="succeeded")throw new Error(`gap discovery failed: ${J(k)}`);if(m=k.message?.content||"",!m)throw new Error("gap discovery returned no concept")}}if(a=await _e({event:"forge.brief_loaded",used_brief:f,brief_id:u||null}),!t?.sessionId)throw new Error("forge requires parent session for skill generation");let g=G("forge"),y=g["generate.md"],h=g["system.md"];if(!y)throw new Error("forge skill missing generate.md prompt");if(!h)throw new Error("forge skill missing system.md prompt");let w=await(await new _().forkSubagent({parent:{sessionId:t.sessionId},config:{model:"sonnet",systemPrompt:h},idPrefix:"forge-generate"})).runToResult(`Generate a new amplifier skill based on this concept:
1148
+
1149
+ ${m}`);if(w.status!=="succeeded")throw new Error(`skill generation failed: ${J(w)}`);let P=w.message?.content||"";if(!P)throw new Error("skill generation returned no output");for(let T=1;T<=s;T++){let L=Or.systemPrompt;if(!L)throw new Error("qualify agent missing system prompt");let R=await(await new _().forkSubagent({parent:{sessionId:t.sessionId},config:{model:"sonnet",systemPrompt:L},idPrefix:`forge-qualify-${T}`})).runToResult(`Evaluate this amplifier skill against the force-multiplier criteria:
1150
+
1151
+ ${P}`);if(R.status!=="succeeded")throw new Error(`qualify iteration ${T} failed: ${J(R)}`);let k=R.message?.content||"",{verdict:C,score:x,feedback:M}=Qs(k),ne={iteration:T,verdict:C,score:x,feedback:M};if(i.push(ne),a=await _e({event:"forge.qualify_iteration",iteration:T,verdict:C,score:x||null}),C==="APPROVE"){l="APPROVED";break}else if(C==="SALVAGE"&&T<s){let H=g["qualify-rework.md"];if(!H)throw new Error("forge skill missing qualify-rework.md prompt");let j=H.replace("{feedback}",M).replace("{original_skill}",P),te=await(await new _().forkSubagent({parent:{sessionId:t.sessionId},config:{model:"sonnet",systemPrompt:j},idPrefix:`forge-rework-${T}`})).runToResult("Refine the skill based on the feedback.");if(te.status!=="succeeded")throw new Error(`rework iteration ${T} failed: ${J(te)}`);if(P=te.message?.content||"",!P)throw new Error(`rework iteration ${T} returned no output`)}else C==="REJECT"&&T>=s&&(l="MAX_ITERATIONS")}if(l==="APPROVED"){let T=P.match(/^name:\s*([^\n]+)/m),L=T&&T[1]?T[1].trim().replace(/^["']|["']$/g,""):"unknown",E=je(nt(),".claude","agent-framework-local","skills",L);await Zs(E,{recursive:!0});let S=je(E,"SKILL.md");await ei(S,P,"utf-8"),c=S,f&&u&&await Lr(u,"consumed"),a=await _e({event:"forge.complete",status:"APPROVED",skill_name:L,iterations:i.length})}else l==="MAX_ITERATIONS"&&(f&&u&&await Lr(u,"failed"),a=await _e({event:"forge.complete",status:"MAX_ITERATIONS",iterations:i.length}))}catch(p){throw a=await _e({event:"forge.error",error:p instanceof Error?p.message:String(p)}),p}return{status:l,skill_path:c,qualify_verdicts:i,brief_id:u,telemetry_ref:a}}var ad={name:"forge",description:'Creates new amplifier skills gated by forge-gate-check, with autonomous gap discovery, skill generation, and qualify iteration loop \u22643\xD7. Writes approved skills and appends telemetry to shared JSONL with surface: "atlas".',handler:id,argumentHint:"[--brief <path>]",whenToUse:"When the user wants to grow the plugin with a new amplifier skill \u2014 autonomously generates and validates one.",flags:["--brief"]};Te(ad);import{readFileSync as Cd,existsSync as Id}from"fs";import{join as Ad}from"path";var ld={name:"bash",description:"Execute a shell command and return its stdout and stderr. Use for running programs, installing packages, git operations, and any task that requires a shell. Commands run in the user's default shell. Long-running commands should use timeout_ms. Output is capped at ~100KB; excess is truncated with a notice.",input_schema:{type:"object",properties:{command:{type:"string",description:"The shell command to execute."},timeout_ms:{type:"number",description:"Optional timeout in milliseconds (default 120000, max 600000). The command is killed if it exceeds this duration."}},required:["command"]}},cd={name:"read_file",description:"Read a file from the filesystem. Returns the file content with line numbers. Use offset and limit to read specific sections of large files. When the read returns a partial view, the response ends with a `... (showing lines X-Y of Z [\u2014 pass offset=N to continue])` annotation indicating the full file size and how to continue. Binary files are detected and rejected. Missing files return an error.",input_schema:{type:"object",properties:{file_path:{type:"string",description:"Absolute path to the file to read."},offset:{type:"number",description:"Line number to start reading from (1-based). Defaults to 1."},limit:{type:"number",description:"Maximum number of lines to read. Defaults to 2000."}},required:["file_path"]}},ud={name:"write_file",description:"Write content to a file, creating it if it does not exist or overwriting if it does. Parent directories are created automatically. Prefer edit_file for modifying existing files \u2014 use write_file only for new files or complete rewrites.",input_schema:{type:"object",properties:{file_path:{type:"string",description:"Absolute path to the file to write."},content:{type:"string",description:"The full content to write to the file."}},required:["file_path","content"]}},dd={name:"edit_file",description:"Perform an exact string replacement in a file. Finds old_string and replaces it with new_string. The edit fails if old_string is not found or matches multiple locations (unless replace_all is true). Always use read_file first to verify the exact content before editing.",input_schema:{type:"object",properties:{file_path:{type:"string",description:"Absolute path to the file to edit."},old_string:{type:"string",description:"The exact string to find and replace. Must match file content exactly."},new_string:{type:"string",description:"The replacement string."},replace_all:{type:"boolean",description:"If true, replace all occurrences. If false (default), fail when multiple matches exist."}},required:["file_path","old_string","new_string"]}},pd={name:"glob",description:'Find files matching a glob pattern. Returns matching file paths, capped at 500 results. Use for discovering files before reading them. Patterns follow standard glob syntax (e.g., "src/**/*.ts", "*.json").',input_schema:{type:"object",properties:{pattern:{type:"string",description:'Glob pattern to match (e.g., "src/**/*.ts").'},path:{type:"string",description:"Base directory to search from. Defaults to the current working directory."}},required:["pattern"]}},md={name:"grep",description:"Search file contents for lines matching a pattern. Returns matches in file:line:content format. Uses grep -rn (or ripgrep if available). Output is capped to prevent overflow. Use for finding symbols, strings, or patterns across the codebase.",input_schema:{type:"object",properties:{pattern:{type:"string",description:"Search pattern (basic regex by default)."},path:{type:"string",description:"Directory or file to search. Defaults to current working directory."},include:{type:"string",description:'File glob to restrict search (e.g., "*.ts"). Passed as --include to grep.'}},required:["pattern"]}},fd={name:"list_directory",description:"List the contents of a directory. Returns file and subdirectory names with type annotations (directories end with /). Use for exploring project structure.",input_schema:{type:"object",properties:{path:{type:"string",description:"Absolute path to the directory to list."}},required:["path"]}},ti={name:"agent",description:"Dispatch a subtask to an independent agent session. The agent runs with its own conversation context and tool access. Use for tasks that benefit from isolated context (research, parallel work, specialized focus). The agent runs to completion and returns its final response.",input_schema:{type:"object",properties:{prompt:{type:"string",description:"The task for the agent to perform."},model:{type:"string",description:"Model for the agent. Defaults to parent session model. Override per-call to right-size cost vs. capability \u2014 `haiku` (cheapest/fastest), `sonnet` (general-use), `opus` (most capable). Append `_1m` (e.g. `sonnet_1m`) for 1M-context variants. Full model IDs are also accepted."},max_turns:{type:"number",description:"Maximum conversation turns (default 10, max 50)."},id_prefix:{type:"string",description:"Label prefix for log correlation."}},required:["prompt"]}},ni={name:"skill",description:"Invoke a registered skill by name. Skills are specialized capabilities that dispatch subagents with domain-specific prompts. Check the system prompt for the list of available skills and their descriptions.",input_schema:{type:"object",properties:{name:{type:"string",description:'Skill name (e.g., "mint", "diagnose", "shadow-verify").'},arguments:{type:"string",description:"Arguments to pass to the skill."}},required:["name"]}},xn=[ld,cd,ud,dd,pd,md,fd],Be=xn.map(e=>e.name);import{readFileSync as xd,existsSync as ai}from"fs";import{join as li}from"path";import{config as Td}from"dotenv";var ri={opus:"claude-opus-4-7",opus_1m:"claude-opus-4-7",sonnet:"claude-sonnet-4-6",sonnet_1m:"claude-sonnet-4-6",haiku:"claude-haiku-4-5-20251001"};function Tn(e){return e in ri}function oi(e){let t=ri[e];if(!t)throw new Error(`Invalid model: ${e}`);return t}function jt(e){if(e!==void 0)return typeof e=="string"&&Tn(e)?oi(e):e}import{execFileSync as gd}from"child_process";import{existsSync as hd,readFileSync as yd}from"fs";import{homedir as kd,userInfo as bd}from"os";import{join as wd}from"path";function si(){let e=vd();if(e===void 0)return;let t=Sd(e);if(t!==void 0){if(t.expiresAt!==void 0&&t.expiresAt<=Date.now()){process.stderr.write("agent-afk: Claude Code OAuth token in keychain is expired. Run `claude login` to refresh.\n");return}return t.accessToken}}function vd(){if(process.platform==="darwin")try{return gd("security",["find-generic-password","-s","Claude Code-credentials","-a",bd().username,"-w"],{stdio:["ignore","pipe","ignore"],encoding:"utf-8"}).trim()}catch{return}if(process.platform==="linux"){let e=wd(kd(),".claude",".credentials.json");if(!hd(e))return;try{return yd(e,"utf-8")}catch{return}}}function Sd(e){let t;try{t=JSON.parse(e)}catch{return}if(typeof t!="object"||t===null)return;let n=t.claudeAiOauth;if(typeof n!="object"||n===null)return;let r=n,o=r.accessToken;if(typeof o!="string"||o.length===0)return;let s=r.expiresAt,a={accessToken:o};return typeof s=="number"&&(a.expiresAt=s),a}var En={model:"sonnet",maxTokens:4096,temperature:1},ii=!1;function Fr(){return process.env.ANTHROPIC_API_KEY||process.env.CLAUDE_CODE_OAUTH_TOKEN||si()}function Ed(){if(!ii){let r=[li(process.cwd(),".env"),it(),Wo()];for(let o of r)if(ai(o)){Td({path:o});break}ii=!0}let e={},t=Fr();t!==void 0&&(e.apiKey=t);let n=process.env.AFK_MODEL??process.env.CLAUDE_MODEL;if(n){let r=n.toLowerCase();e.model=Tn(r)?r:n}if(process.env.AFK_MAX_TOKENS&&(e.maxTokens=parseInt(process.env.AFK_MAX_TOKENS,10)),process.env.AFK_TEMPERATURE&&(e.temperature=parseFloat(process.env.AFK_TEMPERATURE)),process.env.AFK_SYSTEM_PROMPT&&(e.systemPrompt=process.env.AFK_SYSTEM_PROMPT),process.env.AFK_AUTO_ROUTING){let r=process.env.AFK_AUTO_ROUTING.toLowerCase()==="true";e.autoRouting={interactive:r,chat:r,telegram:r,daemon:r}}return e}function Pd(){let e=[li(process.cwd(),"afk.config.json"),at(),ln()];for(let t of e)if(ai(t))try{let n=xd(t,"utf-8"),r=JSON.parse(n),o={};if(typeof r.model=="string"&&r.model.length>0&&(o.model=(Tn(r.model),r.model)),typeof r.maxTokens=="number"&&(o.maxTokens=r.maxTokens),typeof r.temperature=="number"&&(o.temperature=r.temperature),r.systemPrompt&&(o.systemPrompt=r.systemPrompt),r.autoRouting&&typeof r.autoRouting=="object"){let s={};typeof r.autoRouting.interactive=="boolean"&&(s.interactive=r.autoRouting.interactive),typeof r.autoRouting.chat=="boolean"&&(s.chat=r.autoRouting.chat),typeof r.autoRouting.telegram=="boolean"&&(s.telegram=r.autoRouting.telegram),typeof r.autoRouting.daemon=="boolean"&&(s.daemon=r.autoRouting.daemon),o.autoRouting=s}if(r.daemon&&typeof r.daemon=="object"){let s={};typeof r.daemon.task=="string"&&(s.task=r.daemon.task),typeof r.daemon.taskId=="string"&&(s.taskId=r.daemon.taskId),o.daemon=s}return o}catch(n){console.error(`Warning: Failed to parse ${t}:`,n)}return{}}function ct(e){let t=Ed(),n=Pd(),r={...En,...t,...n,...e};return{model:r.model??En.model,maxTokens:r.maxTokens??En.maxTokens,temperature:r.temperature??En.temperature,...r.apiKey!==void 0?{apiKey:r.apiKey}:{},...r.systemPrompt!==void 0?{systemPrompt:r.systemPrompt}:{},...r.autoRouting!==void 0?{autoRouting:r.autoRouting}:{},...r.daemon!==void 0?{daemon:r.daemon}:{}}}function Pn(){return`# Agent AFK
1152
+
1153
+ ## What this process is
1154
+
1155
+ You operate inside a runtime.
1156
+
1157
+ Plain text informs.
1158
+ Tool calls create effects.
1159
+ Only explicitly written state persists.
1160
+
1161
+ The user is usually away from keyboard and reviews results asynchronously. Act; do not perform.
1162
+
1163
+ ## Objective
1164
+
1165
+ Advance the user's stated objective to one terminal state:
1166
+
1167
+ - **Done** - objective satisfied, with evidence written to state the user can inspect.
1168
+ - **Blocked** - an external dependency prevents progress, documented with the exact unblock condition.
1169
+ - **Asking** - one precise question is required before the next action.
1170
+ - **Interrupted** - the user halted work, and state is preserved for resumption.
1171
+
1172
+ Do not drift into open-ended exploration when the objective is concrete.
1173
+
1174
+ ## Operating posture
1175
+
1176
+ **High agency, bounded by reversibility.**
1177
+
1178
+ - Act without asking when intent is clear and the action is reversible.
1179
+ - Ask only when the next action depends on missing information or crosses an irreversible or shared-resource boundary.
1180
+ - Batch independent actions into one wave; sequence dependent actions.
1181
+ - Delegate bounded sub-tasks; verify their output before relying on it.
1182
+ - Stop when further work yields diminishing returns.
1183
+
1184
+ Rule: agentic on reversible actions, cautious on irreversible ones.
1185
+
1186
+ ## The operating loop
1187
+
1188
+ Each turn, run this loop:
1189
+
1190
+ 1. **Observe.** Read what is new: the latest user message, tool results, changed files or plans, and any elapsed time that matters.
1191
+ 2. **Model.** Hold current world-state, objective-state, and assumption-state. If any of them is too stale for the next action, refresh it first.
1192
+ 3. **Choose.** Take the smallest action that advances the objective, removes a load-bearing uncertainty, or reaches a terminal state.
1193
+ 4. **Act.** Emit the action. Tool calls are the only way to affect anything outside this turn's context.
1194
+ 5. **Update.** Compare result to prediction. If reality diverged, update the model before acting again.
1195
+
1196
+ Run the loop; do not narrate it.
1197
+
1198
+ ## State model
1199
+
1200
+ - **Context window.** Ephemeral. Gone next turn unless moved to durable storage.
1201
+ - **Memory files.** Durable across sessions. Assume nothing is there unless you wrote it or read it this turn.
1202
+ - **Plans.** Durable mid-task state across turns or sessions.
1203
+ - **Filesystem, git, external systems, message channels.** Mutable by you and by other actors between turns. Re-check after gaps.
1204
+
1205
+ Current observation outranks memory. Anything not read this turn is inference.
1206
+
1207
+ ## Action surface
1208
+
1209
+ Tool calls have real consequences: edits persist, commits push, messages reach humans, API calls can cost money, and deletions may be permanent.
1210
+
1211
+ The transcript is not a user channel. AFK users see bridge messages, files, commits, plans or memory you recorded, and process output they can inspect. If something must reach the user, route it through a real channel.
1212
+
1213
+ ## Constraints
1214
+
1215
+ - **Irreversible actions require explicit recent intent.** Examples: deleting files or branches, force-pushing, dropping data, messaging third parties, calling paid APIs, or modifying shared systems.
1216
+ - **Tool schemas are authoritative.** Required fields are required. If a value is unknown, fetch it or ask. Do not guess.
1217
+ - **Do not skip Observe or Update to save tokens.** Stale-state errors cost more than the tokens saved.
1218
+ - **Parallelize independent calls; sequence dependent ones.**
1219
+ - **Re-check shared mutable state after divergence, delay, or failure.**
1220
+
1221
+ ## Delegation
1222
+
1223
+ When dispatching a sub-agent:
1224
+
1225
+ - Assume zero prior context.
1226
+ - Include objective, relevant paths, constraints, expected deliverable, and expected response length.
1227
+ - Delegate search, test, build, and verify. Keep synthesis and final judgment local.
1228
+ - State what not to do and when to stop.
1229
+ - Verify high-stakes output before acting on it.
1230
+
1231
+ ## Priorities
1232
+
1233
+ Ordered. Higher wins on conflict.
1234
+
1235
+ 1. Do not damage user state, credentials, shared systems, or other people.
1236
+ 2. Do what the user actually meant.
1237
+ 3. Reach a terminal state.
1238
+ 4. Leave legible artifacts for asynchronous review.
1239
+ 5. Minimize token and tool cost.
1240
+
1241
+ ## Failure handling
1242
+
1243
+ - **Tool error.** Inspect the error. Retry only with a changed approach.
1244
+ - **Repeated failure.** The same action twice with no progress is a loop. Diagnose and change tactics.
1245
+ - **Unexpected state.** Your model is wrong. Re-observe from durable sources.
1246
+ - **Ambiguity you cannot resolve from context.** Ask one precise question.
1247
+ - **Your own mistake.** State it, correct it, proceed.
1248
+
1249
+ ## What to cut
1250
+
1251
+ - Persona flavor such as "I'll be happy to..."
1252
+ - Architectural self-narration to the user
1253
+ - "Based on my understanding..." preambles
1254
+ - Confirmation questions for clearly reversible actions the user already authorized
1255
+
1256
+ ## End-of-turn
1257
+
1258
+ Every turn must end in one externally identifiable terminal state. AFK users need inspectable artifacts, not ceremony.
1259
+
1260
+ **Done**
1261
+ - What was done
1262
+ - Evidence that exists
1263
+ - What changed in the world
1264
+ - Anything still pending or deferred, with why
1265
+
1266
+ **Blocked**
1267
+ - What blocks
1268
+ - What must change to unblock
1269
+ - What has already been done
1270
+ - Whether state is safe to leave as-is
1271
+
1272
+ **Asking**
1273
+ - One precise question
1274
+ - The assumption it resolves
1275
+ - What you will do once answered
1276
+
1277
+ **Interrupted**
1278
+ - What you were doing
1279
+ - Where state was saved
1280
+ - What resumption requires
1281
+
1282
+ Never end a turn mid-loop without one of these.
1283
+ `}function Cn(){if(process.env.AFK_SYSTEM_PROMPT)return process.env.AFK_SYSTEM_PROMPT;let e=[Ad(process.cwd(),"afk.config.json"),at(),ln()];for(let t of e)if(Id(t))try{let n=JSON.parse(Cd(t,"utf-8"));if(typeof n.systemPrompt=="string"&&n.systemPrompt.length>0)return n.systemPrompt}catch{}}function N(){return Fr()}function Bt(){return process.env.OPENAI_API_KEY||process.env.CODEX_API_KEY||void 0}function di(e){return Pe(e)==="openai-codex"?Bt():N()}function Ce(){let e=process.env.AFK_MODEL??process.env.CLAUDE_MODEL;return!e||e.length===0?"sonnet":e}function ut(){let e=process.env.AFK_DEFAULT_SUBAGENT_MODEL;return!e||e.length===0?"sonnet":e}function He(e){if(e===void 0)return;if(e==="adaptive")return{type:"adaptive"};if(e==="disabled")return{type:"disabled"};if(e==="enabled:max")return{type:"enabled",budgetTokens:Number.POSITIVE_INFINITY};let t=/^enabled:(\d+)$/.exec(e);if(t){let n=parseInt(t[1],10);if(Number.isNaN(n))throw new Error(`Invalid thinking budget: ${e}`);return{type:"enabled",budgetTokens:n}}throw new Error(`Invalid --thinking value: ${e}. Expected 'adaptive' | 'disabled' | 'enabled:<N>' | 'enabled:max'`)}var ci=["low","medium","high","xhigh","max"];function We(e){if(e!==void 0){if(ci.includes(e))return e;throw new Error(`Invalid --effort value: ${e}. Expected one of: ${ci.join(", ")}`)}}function dt(){return He(process.env.AFK_THINKING)}function pt(){return We(process.env.AFK_EFFORT)}function mt(e){if(e===void 0)return;if(e===""||e==="NaN")throw new Error(`Invalid --max-budget-usd value: ${JSON.stringify(e)}. Expected a non-negative number.`);let t=Number(e);if(!Number.isFinite(t))throw new Error(`Invalid --max-budget-usd value: ${JSON.stringify(e)}. Expected a non-negative number.`);if(t<0)throw new Error(`Invalid --max-budget-usd value: ${JSON.stringify(e)}. Must be non-negative.`);return t}function Ur(){return mt(process.env.AFK_MAX_BUDGET_USD)}function Nr(){return mt(process.env.AFK_TASK_BUDGET)}function ft(e){if(e===void 0)return;if(e==="max")return Number.POSITIVE_INFINITY;if(e===""||e==="NaN")throw new Error(`Invalid --max-output-tokens value: ${JSON.stringify(e)}. Expected a positive integer or 'max'.`);if(!/^\d+$/.test(e))throw new Error(`Invalid --max-output-tokens value: ${JSON.stringify(e)}. Expected a positive integer or 'max'.`);let t=Number(e);if(!Number.isFinite(t)||!Number.isInteger(t)||t<=0)throw new Error(`Invalid --max-output-tokens value: ${JSON.stringify(e)}. Must be a positive integer.`);return t}function Ht(){return ft(process.env.AFK_MAX_OUTPUT_TOKENS)}var ui=["anthropic","anthropic-direct","openai-codex"];function In(e,t){if(e!==void 0){if(!ui.includes(e))throw new Error(`Invalid --provider value: ${e}. Expected one of: ${ui.join(", ")}`);if(e==="anthropic"||e==="anthropic-direct"){let n=[...Be];return t?.subagentExecutor&&n.push("agent"),t?.skillExecutor&&n.push("skill"),new ge({permissions:{allowedTools:n},subagentExecutor:t?.subagentExecutor,skillExecutor:t?.skillExecutor})}}}async function pi(e,t){let r=G("mint")["spec.md"];if(!r)throw new Error("mint skill missing spec.md prompt");let a=await(await new _().forkSubagent({parent:{sessionId:t},config:{model:"sonnet",systemPrompt:r,apiKey:N()},idPrefix:"mint-spec"})).runToResult(`Create a detailed specification for: ${e}`);if(a.status!=="succeeded"||!a.message)throw new Error(`spec phase failed: ${J(a)}`);return a.message.content}async function mi(e,t){let r=G("mint")["research.md"];if(!r)throw new Error("mint skill missing research.md prompt");let a=await(await new _().forkSubagent({parent:{sessionId:t},config:{model:"sonnet",systemPrompt:r,apiKey:N()},idPrefix:"mint-research"})).runToResult(`Gather context and research for this specification:
1284
+
1285
+ ${e}`);if(a.status!=="succeeded"||!a.message)throw new Error(`research phase failed: ${J(a)}`);return a.message.content}async function fi(e,t,n){let o=G("mint")["plan.md"];if(!o)throw new Error("mint skill missing plan.md prompt");let a=await new _().forkSubagent({parent:{sessionId:n},config:{model:"sonnet",systemPrompt:o,apiKey:N()},idPrefix:"mint-plan"}),i=`Specification:
1286
+ ${e}
1287
+
1288
+ Research findings:
1289
+ ${t}
1290
+
1291
+ Create a detailed implementation plan based on the spec and research.`,l=await a.runToResult(i);if(l.status!=="succeeded"||!l.message)throw new Error(`plan phase failed: ${J(l)}`);return l.message.content}function Md(e){let t=e.match(/\.\w+\s/g)||[],n=e.match(/Files?:\s*(.+?)(?:\n|$)/gi)||[],r=t.length;for(let o of n){let s=o.replace(/Files?:\s*/i,"").split(/[,;]/g).filter(a=>a.trim().length>0);r+=s.length}return r}async function gi(e,t){if(Md(e)<3)return null;try{return await oe("parallelize").handler({plan:e})}catch(r){return console.warn(`Parallelize dispatch failed: ${r instanceof Error?r.message:String(r)}`),null}}import{z as $e}from"zod";function gt(e){let t=lt();t&&t({type:"panel",spec:e},{subagentId:"__main__"})}var Rd=$e.object({status:$e.enum(["PASS","FAIL"]),status_reason:$e.string().optional(),files_changed:$e.array($e.string()),tests_passed:$e.boolean(),build_passed:$e.boolean().optional(),verification_passed:$e.boolean().optional(),notes:$e.string()});async function hi(e,t,n){let o=G("mint")["build.md"];if(!o)throw new Error("mint skill missing build.md prompt");let a=await new _().forkSubagent({parent:{sessionId:n},config:{model:"sonnet",systemPrompt:o,apiKey:N()},idPrefix:"mint-build",outputSchema:Rd}),i=`Implementation plan:
1292
+ ${e}
1293
+
1294
+ `+(t?`Wave orchestration plan:
1295
+ ${JSON.stringify(t,null,2)}
1296
+
1297
+ `:"")+"Execute the implementation plan following TDD (test-first) principles.",l=await a.runToResult(i);if(l.status!=="succeeded"||!l.output)throw new Error(`build phase failed: ${J(l)}`);let c=l.output,u={filesChanged:c.files_changed,testsPassed:c.tests_passed,notes:c.notes};return gt({kind:"checkpoint",title:"build",body:[`Files changed: ${u.filesChanged.length}`,`Tests: ${u.testsPassed?"passed":"failed"}`,"Next: verify"]}),u}import{z as ht}from"zod";var _d=ht.object({status:ht.enum(["PASS","FAIL"]),status_reason:ht.string().optional(),issues:ht.array(ht.string()).default([]),summary:ht.string().optional()});async function jr(e,t,n,r,o){let a=await new _().forkSubagent({parent:{sessionId:r},config:{model:"sonnet",systemPrompt:o,apiKey:N()},idPrefix:`mint-verify-${e}`,outputSchema:_d}),i=`Plan:
1298
+ ${t}
1299
+
1300
+ Build results:
1301
+ ${JSON.stringify(n,null,2)}
1302
+
1303
+ Mode: ${e}
1304
+
1305
+ Run ${e} verification on the implementation.`,l;try{l=await a.runToResult(i)}finally{await a.teardown().catch(()=>{})}if(l.status!=="succeeded"||!l.output)return{passed:!1,issues:[`${e} verification failed: ${J(l)}`]};let c=l.output,u=c.status==="PASS";return{passed:u,issues:u?void 0:c.issues}}async function An(e,t,n){let o=G("mint")["verify.md"];if(!o)throw new Error("mint skill missing verify.md prompt");let[s,a,i]=await Promise.all([jr("test",e,t,n,o),jr("lint",e,t,n,o),jr("design-review",e,t,n,o)]),l=[];s.issues&&l.push(...s.issues),a.issues&&l.push(...a.issues),i.issues&&l.push(...i.issues);let c={testsPassed:s.passed,lintPassed:a.passed,designReviewPassed:i.passed,...l.length>0?{issues:l}:{}},u=c.testsPassed&&c.lintPassed&&c.designReviewPassed,p=m=>m?"passed":"failed";return gt({kind:u?"checkpoint":"diagnosis",title:"verify",body:[`Tests: ${p(c.testsPassed)} \xB7 Lint: ${p(c.lintPassed)}`,`Design review: ${p(c.designReviewPassed)}`,...u?["Next: ship"]:[`Issues: ${l.length} (heal loop will retry)`]]}),c}async function yi(e,t,n,r,o){if(n.testsPassed&&n.lintPassed&&n.designReviewPassed)return{healed:!0,newHealIterations:r,newVerifyResults:n};if(r>=2)return{healed:!1,newHealIterations:r,newVerifyResults:n};try{let s=oe("diagnose"),a=`Verification failures:
1306
+ Tests: ${n.testsPassed?"PASS":"FAIL"}
1307
+ Lint: ${n.lintPassed?"PASS":"FAIL"}
1308
+ Design: ${n.designReviewPassed?"PASS":"FAIL"}
1309
+ Issues: ${n.issues?.join(`
1310
+ `)||"none"}`,i=await s.handler({failure:a,repoPath:process.cwd(),context:e}),l="";if(typeof i=="object"&&i!==null&&"winner"in i&&typeof i.winner=="object"&&i.winner!==null){let w=i.winner;typeof w.proposed_fix=="string"&&(l=w.proposed_fix)}let u=G("mint")["heal.md"];if(!u)throw new Error("mint skill missing heal.md prompt");let m=await new _().forkSubagent({parent:{sessionId:o.sessionId},config:{model:"sonnet",systemPrompt:u,apiKey:N()},idPrefix:"mint-heal"}),f=n.issues?.join(`
1311
+ `)??"none",g=`Plan:
1312
+ ${e}
1313
+
1314
+ Proposed fix from diagnosis:
1315
+ ${l}
1316
+
1317
+ Verification issues:
1318
+ ${f}
1319
+
1320
+ Apply the fix and update the implementation.`,y=await m.runToResult(g);if(y.status!=="succeeded"||!y.message)throw new Error(`heal phase failed: ${J(y)}`);let h=/^\s*FIX_APPLIED:\s*(true|false)/im.exec(y.message.content)?.[1]?.toLowerCase()==="true",b=r+1;if(!h)return{healed:!1,newHealIterations:b,newVerifyResults:n};if(!o.sessionId)throw new Error("Parent session ID required for verification");let v=await An(e,t,o.sessionId);return{healed:v.testsPassed&&v.lintPassed&&v.designReviewPassed,newHealIterations:b,newVerifyResults:v}}catch{return{healed:!1,newHealIterations:r+1,newVerifyResults:n}}}async function ki(e,t){let r=G("mint")["ship.md"];if(!r)throw new Error("mint skill missing ship.md prompt");let s=await new _().forkSubagent({parent:{sessionId:t},config:{model:"sonnet",systemPrompt:r,apiKey:N()},idPrefix:"mint-ship"}),a=`Idea: ${e.idea}
1321
+
1322
+ Specification:
1323
+ ${e.spec}
1324
+
1325
+ Plan:
1326
+ ${e.plan}
1327
+
1328
+ Build results:
1329
+ ${JSON.stringify(e.buildResults,null,2)}
1330
+
1331
+ Verification results:
1332
+ ${JSON.stringify(e.verifyResults,null,2)}
1333
+
1334
+ Create a ship-ready summary with next steps.`,i=await s.runToResult(a);if(i.status!=="succeeded"||!i.message)throw new Error(`ship phase failed: ${J(i)}`);let l=e.buildResults?.filesChanged.length??0,c=e.healIterations;return gt({kind:"checkpoint",title:"ship \u2014 done",body:[`Files changed: ${l}`,`Heal iterations: ${c}`,`Idea: ${e.idea}`]}),i.message.content}import{existsSync as bi,mkdirSync as $d,readFileSync as Od,unlinkSync as Dd,writeFileSync as Ld}from"fs";import{dirname as Fd,join as Ud}from"path";function Br(e){return Ud(_t(),e,"mint-state.json")}function wi(e,t){let n=Br(e);$d(Fd(n),{recursive:!0}),Ld(n,JSON.stringify(t,null,2),"utf-8")}function Nd(e){if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.currentPhase=="string"&&typeof t.idea=="string"&&typeof t.spec=="string"&&typeof t.healIterations=="number"&&Array.isArray(t.history)}function vi(e){let t=Br(e);if(!bi(t))return null;try{let n=JSON.parse(Od(t,"utf-8"));return Nd(n)?n:null}catch{return null}}function Hr(e){let t=Br(e);if(bi(t))try{Dd(t)}catch{}}var jd=2,Si=/^\s*--continue(?:\s+(?:approved|yes|y))?\s*$/i,Bd="To approve and run the rest of the pipeline, invoke /mint --continue approved (or call mint with {userApproved: true} \u2014 no idea field needed). The handler will reload the spec state from disk.";function Ke(e,t,n){e.history.push({phase:t,output:n,timestamp:Date.now()})}function Hd(e){if(typeof e=="string")return Si.test(e)?{userApproved:!0}:{idea:e};if(typeof e=="object"&&e!==null){let t=e,n=typeof t.idea=="string"?t.idea:void 0;if(n!==void 0&&Si.test(n))return{userApproved:!0};if("idea"in t||"resumeFrom"in t||t.userApproved===!0)return t}throw new Error("mint handler requires input.idea (string), input as string, or {userApproved: true} to resume")}async function xi(e,t){if(!t.sessionId)throw new Error("runPhasesAfterSpec requires parentSession.sessionId");let n=t.sessionId;try{e.currentPhase="research",e.research=await mi(e.spec,n),Ke(e,"research",e.research),e.currentPhase="plan",e.plan=await fi(e.spec,e.research,n),Ke(e,"plan",e.plan),e.currentPhase="parallelize",e.waveOrchestrationPlan=await gi(e.plan,t),Ke(e,"parallelize",JSON.stringify(e.waveOrchestrationPlan||"skipped")),e.currentPhase="build",e.buildResults=await hi(e.plan,e.waveOrchestrationPlan,n),Ke(e,"build",JSON.stringify(e.buildResults)),e.currentPhase="verify",e.verifyResults=await An(e.plan,e.buildResults,n),Ke(e,"verify",JSON.stringify(e.verifyResults)),e.currentPhase="heal";let r=e.verifyResults.testsPassed&&e.verifyResults.lintPassed&&e.verifyResults.designReviewPassed;for(;!r&&e.healIterations<jd;){let s=await yi(e.plan,e.buildResults,e.verifyResults,e.healIterations,t);e.healIterations=s.newHealIterations,e.verifyResults=s.newVerifyResults,r=s.healed,Ke(e,"heal",`Iterations: ${e.healIterations}, Success: ${r}`)}if(!r)return{paused:!0,phase:"heal-failed",reason:`Heal capped at ${e.healIterations} iterations; still have failures`,state:e,nextStep:"Heal loop exhausted. Inspect verifyResults, fix manually, then re-invoke /mint with a fresh idea \u2014 resume is not supported from heal-failed."};e.currentPhase="ship";let o=await ki(e,n);return Ke(e,"ship",o),{completed:!0,artifact:o,state:e}}catch(r){throw new Error(`mint failed at ${e.currentPhase}: ${r}`)}}function Ti(e,t){return("completed"in t||t.phase==="heal-failed")&&Hr(e),t}async function Wd(e,t){let n=Hd(e);if(!t?.sessionId)throw new Error("mint handler requires a parent session to fork subagents");let r=t.sessionId;if(n.userApproved){let a=n.resumeFrom??vi(r);if(!a)throw new Error("mint: no paused spec found for this session to continue. Run /mint <idea> first, then /mint --continue approved.");let i=await xi(a,t);return Ti(r,i)}if(!n.idea)throw new Error("mint: no idea provided. Run /mint <idea> to start, or /mint --continue approved to resume a paused spec.");Hr(r);let o={currentPhase:"spec",idea:n.idea,healIterations:0,history:[]};try{o.spec=await pi(n.idea,r),Ke(o,"spec",o.spec)}catch(a){throw new Error(`mint failed at spec: ${a}`)}if(!n.autoApprove)return wi(r,o),{paused:!0,phase:"spec",spec:o.spec,state:o,nextStep:Bd};let s=await xi(o,t);return Ti(r,s)}var Kd={name:"mint",description:"Takes a feature idea or refactor scope and delivers a ship-ready, verified implementation end-to-end",handler:Wd,argumentHint:"<idea> | --continue [approved]",whenToUse:"When the user wants a feature or refactor delivered end-to-end (spec \u2192 research \u2192 build \u2192 verify) in one ship-ready pass. After the spec phase pauses for approval, invoke `/mint --continue approved` (or call mint with `{userApproved: true}`) to resume \u2014 the handler reloads the spec state from disk.",flags:["--continue"]};Te(Kd);import{readdirSync as zd,readFileSync as Vd}from"fs";import{join as Yd}from"path";var Gd=/(?<![a-zA-Z0-9_/-])--([a-z][a-z0-9-]*)(?![a-zA-Z0-9_-])/g;function Ei(e){return e.startsWith("--")?e:`--${e}`}function Wr(e){let t=new Set;for(let n of e.matchAll(Gd))n[1]&&t.add(`--${n[1]}`);return Array.from(t).sort()}function Wt(e){if(!e.startsWith(`---
1335
+ `))return{frontmatter:null,frontmatterFlags:null,body:e};let t=e.indexOf(`
1336
+ ---
1337
+ `,4);if(t===-1)return{frontmatter:null,frontmatterFlags:null,body:e};let n=e.slice(4,t),r=e.slice(t+5),o={},s=null,a=n.split(`
1338
+ `);for(let i=0;i<a.length;i++){let l=a[i];if(!l||!l.trim()||l.trimStart().startsWith("#"))continue;if(l.startsWith("flags:")){let u=l.slice(6).trim();if(u.startsWith("[")){let p=u.match(/\[(.*?)\]/);if(p?.[1]){let m=p[1].split(",").map(f=>f.trim()).filter(f=>f.length>0);m.length>0&&(s=m.map(Ei).sort())}continue}if(u===""||u==="null"){let p=[];for(let m=i+1;m<a.length;m++){let f=a[m];if(!f||!f.match(/^\s+-\s/))break;let g=f.match(/^\s+-\s+(.+)/);g?.[1]&&p.push(g[1].trim())}p.length>0&&(s=p.map(Ei).sort());continue}}let c=l.match(/^([a-zA-Z][a-zA-Z0-9_-]*):\s*(.*)$/);if(c&&c[1]!==void 0&&c[2]!==void 0){let u=c[2].trim().replace(/^['"]|['"]$/g,"");u.length>0&&(o[c[1]]=u)}}return{frontmatter:o,frontmatterFlags:s,body:r}}function Pi(e){let t=Wt(e);return t.frontmatterFlags&&t.frontmatterFlags.length>0?t.frontmatterFlags:Wr(t.body)}function qd(e){let t=Wt(e);if(!t.frontmatter)return null;let n=t.frontmatter.name,r=t.frontmatter.description,o=t.body.trim();if(!n||!r||o.length===0)return null;let s=t.frontmatter["argument-hint"]??t.frontmatter.argumentHint,a=Pi(e),i={name:n,description:r,body:o};return s&&s.length>0&&(i.argumentHint=s),a.length>0&&(i.flags=a),i}function Jd(e){return async(t,n)=>{let r=typeof t=="string"&&t.length>0?t:"Run the skill.";return await(await new _({parentAbortSignal:n?.abortSignal}).forkSubagent({parent:{sessionId:n?.sessionId,getInputStreamRef:n?.getInputStreamRef?.bind(n),abortSignal:n?.abortSignal},config:{model:"sonnet",systemPrompt:e.body},idPrefix:`user-skill-${e.name}`})).runToResult(r)}}function Qd(e,t){try{return oe(e),`${t}:${e}`}catch{return e}}function Mn(e,t){let n;try{n=zd(e,{withFileTypes:!0})}catch{return 0}let r=0;for(let o of n){if(!o.isDirectory()||o.name.startsWith("_")||o.name.startsWith("."))continue;let s;try{s=Vd(Yd(e,o.name,"SKILL.md"),"utf-8")}catch{continue}let a=qd(s);if(!a)continue;let l={name:Qd(a.name,t),description:a.description,handler:Jd(a),origin:t};a.argumentHint&&(l.argumentHint=a.argumentHint),a.flags&&a.flags.length>0&&(l.flags=a.flags),Te(l),r++}return r}function Kr(){return Mn(No(),"user")}import{existsSync as Xd,readdirSync as Zd,readFileSync as ep,statSync as tp}from"fs";import{join as np}from"path";function Gr(e){let t=[];function n(r,o=0){if(o>10||!Xd(r))return;let s;try{s=Zd(r)}catch{return}for(let a of s){if(a.startsWith("."))continue;let i=np(r,a),l;try{l=tp(i)}catch{continue}if(l.isFile()&&a==="SKILL.md"){let c=rp(i);c.name&&t.push(c)}else l.isDirectory()&&n(i,o+1)}}return n(e),t}function rp(e){try{let t=ep(e,"utf-8");if(!t.startsWith(`---
1339
+ `))return{};let n=t.slice(4),r=n.indexOf(`
1340
+ ---`);if(r===-1)return{};let o=n.slice(0,r),s=n.slice(r+4).trim(),a={},i=o.split(`
1341
+ `);for(let l of i){if(!l)continue;let c=l.indexOf(":");if(c===-1)continue;let u=l.slice(0,c).trim(),p=l.slice(c+1).trim();u==="name"?a.name=p.replace(/^["']|["']$/g,""):u==="description"?a.description=p.replace(/^["']|["']$/g,""):u==="argumentHint"&&(a.argumentHint=p.replace(/^["']|["']$/g,""))}return s.length>0&&(a.body=s),a}catch{return{}}}function Ci(e){let t=Kt(e);if(t.length===0)return"";let n=[];for(let r of t){let o=r.argumentHint?`${r.argumentHint}`:"",s=o?`- \`${r.name} ${o}\`: ${r.description}`:`- ${r.name}: ${r.description}`;n.push(s),r.whenToUse&&n.push(` When to use: ${r.whenToUse}`)}return["Available skills (invoke via the `skill` tool):",...n].join(`
1342
+ `)}function Kt(e){let t=[],n=new Set;for(let o of tt()){let s=oe(o);t.push({name:o,description:s.description,source:s.origin==="user"?"user":s.origin==="project"?"project":"builtin",argumentHint:s.argumentHint,whenToUse:s.whenToUse}),n.add(o)}let r=e??[...Ee(Mt()),...Ee()];for(let o of r){if(o.type!=="local")continue;let s=Gr(o.path);for(let a of s)!a.name||n.has(a.name)||(t.push({name:a.name,description:a.description??`Skill from plugin at ${o.path}`,source:"plugin"}),n.add(a.name))}return t}function Ii(e){let t=new Map,n=e??[...Ee(Mt()),...Ee()];for(let r of n){if(r.type!=="local")continue;let o=Gr(r.path);for(let s of o)s.name&&s.body&&s.body.length>0&&t.set(s.name,s.body)}return t}var op=3,sp="claude-haiku-4-5-20251001",ip=1024,ap=[{value:"claude-sonnet-4-5-20250929",displayName:"Claude Sonnet 4.5",description:"Latest balanced Claude \u2014 recommended default"},{value:"claude-opus-4-5-20250929",displayName:"Claude Opus 4.5",description:"Highest-capability Claude"},{value:"claude-haiku-4-5-20250929",displayName:"Claude Haiku 4.5",description:"Fastest, cheapest Claude"}],Rn=class{client;authMode;initSessionId;promptStream;toolDispatcher;maxTokens;tools;systemPrefix;userSystem;currentModel;currentPermissionMode;messages=[];closed=!1;abortController=null;pendingAbortReason=null;closedPromise;closeResolve=null;lastUsage=null;constructor(t){this.client=t.client,this.authMode=t.authMode,this.initSessionId=zr(),this.promptStream=t.promptStream,this.toolDispatcher=t.toolDispatcher,this.maxTokens=t.maxTokens,this.tools=t.tools,this.systemPrefix=t.systemPrefix,this.userSystem=t.userSystem,this.currentModel=t.model,this.currentPermissionMode=t.permissionMode??"default",this.closedPromise=new Promise(n=>{this.closeResolve=()=>n("__closed__")})}async*[Symbol.asyncIterator](){yield{type:"session.init",info:{sessionId:this.initSessionId,model:this.currentModel,permissionMode:this.currentPermissionMode,cwd:process.cwd(),tools:[],slashCommands:[],skills:[],plugins:[],mcpServers:[],apiKeySource:this.authMode,version:"anthropic-direct-v1"}};let n=this.promptStream[Symbol.asyncIterator]();try{for(;!this.closed;){let r=await Promise.race([n.next(),this.closedPromise]);if(r==="__closed__")break;let o=r;if(o.done)break;let s=o.value,a=new AbortController;if(this.abortController=a,this.pendingAbortReason!==null&&!a.signal.aborted&&(a.abort(this.pendingAbortReason),this.pendingAbortReason=null),a.signal.aborted)return;this.messages.push({role:"user",content:s.content});let i=this.composeSystem(),l=Cr(this.authMode,this.initSessionId,zr()),c={client:this.client,messages:this.messages,system:i,tools:this.tools,toolDispatcher:this.toolDispatcher,model:this.currentModel,maxTokens:this.maxTokens,headers:l,signal:a.signal,ctx:{sessionId:this.initSessionId}};try{for await(let u of rs(c)){if(this.closed)return;u.type==="turn.completed"&&(this.lastUsage=u.usage),yield u}}catch(u){if(a.signal.aborted)return;yield{type:"error",error:u instanceof Error?u:new Error(String(u))};return}finally{this.abortController===a&&(this.abortController=null)}}}catch(r){yield{type:"error",error:r instanceof Error?r:new Error(String(r))}}finally{try{await n.return?.()}catch{}}}composeSystem(){let t=this.systemPrefix,n=this.userSystem,r=[];return t&&t.length>0&&r.push(...t),n&&n.length>0&&r.push({type:"text",text:n}),r.length===0?null:dn()?Qo(r,pn()):r}async interrupt(){let t=this.abortController;if(t&&!t.signal.aborted){t.abort("interrupted");return}this.pendingAbortReason="interrupted"}async setModel(t){t!==void 0&&t.length>0&&(this.currentModel=t)}async setPermissionMode(t){this.currentPermissionMode=t}async supportedCommands(){try{return Kt().map(n=>{let r={name:n.name,description:n.description};return n.argumentHint&&(r.argumentHint=n.argumentHint),r})}catch{return[]}}async supportedModels(){return ap.map(t=>({...t}))}async supportedAgents(){return[]}async getContextUsage(){return{tools:[],agents:[],isAutoCompactEnabled:!1,apiUsage:this.lastUsage}}async mcpServerStatus(){return[]}async accountInfo(){return{subscriptionType:this.authMode==="oauth"?"claude-subscription":"api-key"}}async rewindFiles(t,n){return{canRewind:!1,error:"anthropic-direct provider does not support file checkpoint rewind"}}async compact(){let t=this.messages.length;if(this.closed)return{compacted:!1,reason:"session-closed",messagesBefore:t,messagesAfter:t};if(this.abortController!==null)return{compacted:!1,reason:"turn-in-flight",messagesBefore:t,messagesAfter:t};let n=lp(),r=is(this.messages,n);if(r<=0)return{compacted:!1,reason:"history-too-short",messagesBefore:t,messagesAfter:t};let o=this.messages.slice(0,r),s=cp(),a=as(o,s,ip),i=new AbortController;this.abortController=i,this.pendingAbortReason!==null&&!i.signal.aborted&&(i.abort(this.pendingAbortReason),this.pendingAbortReason=null);let l;try{if(i.signal.aborted)return{compacted:!1,reason:"aborted",messagesBefore:t,messagesAfter:t};let p=Cr(this.authMode,this.initSessionId,zr()),m=this.client,f=await Promise.resolve(m.messages.create(a,{headers:p,signal:i.signal}));l=await up(f)}catch(p){return i.signal.aborted?{compacted:!1,reason:"aborted",messagesBefore:t,messagesAfter:t}:{compacted:!1,reason:"summarization-failed: "+(p instanceof Error?p.message:String(p)),messagesBefore:t,messagesAfter:t}}finally{this.abortController===i&&(this.abortController=null)}if(l.trim().length===0)return{compacted:!1,reason:"empty-summary",messagesBefore:t,messagesAfter:t};let c=cs(this.messages,r,l),u=ls(this.messages,r,l);return this.messages.splice(0,this.messages.length,...u),{compacted:!0,messagesBefore:t,messagesAfter:this.messages.length,tokensSavedEstimate:c}}close(){this.closed=!0;let t=this.abortController;t&&!t.signal.aborted?t.abort("closed"):this.pendingAbortReason="closed",this.closeResolve?.()}};function lp(){let e=process.env.AFK_COMPACT_KEEP_LAST_TURNS;if(e!==void 0&&e.length>0){let t=Number.parseInt(e,10);if(Number.isFinite(t)&&t>0)return t}return op}function cp(){let e=process.env.AFK_COMPACT_MODEL;return e!==void 0&&e.length>0?e:sp}async function up(e){let t="";for await(let n of e)if(n.type==="content_block_delta"){let r=n.delta;r.type==="text_delta"&&typeof r.text=="string"&&(t+=r.text)}return t}var dp=new Set(["read_file","glob","grep","list_directory"]);function Vr(e,t){return t?.allowedTools?t.allowedTools.includes(e)?{allowed:!0}:{allowed:!1,reason:`Tool "${e}" is not in the configured allowlist`}:dp.has(e)?{allowed:!0}:{allowed:!1,reason:`Tool "${e}" requires explicit permission (add to allowedTools config)`}}var pp=new Set(["agent","read_file","glob","grep","list_directory"]);function mp(e){return pp.has(e)}function fp(e,t){return e.reduce((n,r,o)=>{let s=t(r.name,r.input),a=n[n.length-1];return a&&s&&a.isConcurrencySafe?a.indices.push(o):n.push({isConcurrencySafe:s,indices:[o]}),n},[])}var Gt=class{handlers;schemas;hookRegistry;permissions;subagentExecutor;skillExecutor;classifier;constructor(t){this.handlers=t.handlers,this.schemas=t.schemas,this.hookRegistry=t.hookRegistry,this.permissions=t.permissions,this.subagentExecutor=t.subagentExecutor,this.skillExecutor=t.skillExecutor,this.classifier=t.concurrencyClassifier??mp}get toolDefs(){return this.schemas}async execute(t){if(t.signal.aborted)return{content:"Tool call aborted",isError:!0};if(this.hookRegistry){let s={event:"PreToolUse",toolName:t.name,input:t.input};try{await this.hookRegistry.dispatch(s,t.signal)}catch(a){if(a instanceof fe)return{content:`Tool "${t.name}" blocked by PreToolUse hook: ${a.message}`,isError:!0};throw a}}let n=Vr(t.name,this.permissions);if(!n.allowed)return{content:n.reason??`Tool "${t.name}" is not permitted`,isError:!0};if(t.name==="agent"){if(!this.subagentExecutor)return{content:"Agent tool is not available in this session configuration",isError:!0};let s;try{s=await this.subagentExecutor.execute(t)}catch(a){s={content:`Agent tool error: ${a instanceof Error?a.message:String(a)}`,isError:!0}}if(this.hookRegistry){let a={event:"PostToolUse",toolName:t.name,output:s.content};try{await this.hookRegistry.dispatch(a,t.signal)}catch{}}return s}if(t.name==="skill"){if(!this.skillExecutor)return{content:"Skill tool is not available in this session configuration",isError:!0};let s;try{s=await this.skillExecutor.execute(t)}catch(a){s={content:`Skill tool error: ${a instanceof Error?a.message:String(a)}`,isError:!0}}if(this.hookRegistry){let a={event:"PostToolUse",toolName:t.name,output:s.content};try{await this.hookRegistry.dispatch(a,t.signal)}catch{}}return s}let r=this.handlers.get(t.name);if(!r)return{content:`Unknown tool "${t.name}". Available tools: ${[...this.handlers.keys()].join(", ")}`,isError:!0};let o;try{o=await r(t.input,t.signal)}catch(s){o={content:`Tool execution error: ${s instanceof Error?s.message:String(s)}`,isError:!0}}if(this.hookRegistry){let s={event:"PostToolUse",toolName:t.name,output:o.content};try{await this.hookRegistry.dispatch(s,t.signal)}catch{}}return o}async executeBatch(t){if(t.length===0)return[];if(t.length===1)return[await this.execute(t[0])];let n=new Array(t.length),r=new Set;for(let a=0;a<t.length;a++){let i=t[a];if(i.signal.aborted){n[a]={content:"Tool call aborted",isError:!0},r.add(a);continue}if(this.hookRegistry){let c={event:"PreToolUse",toolName:i.name,input:i.input};try{await this.hookRegistry.dispatch(c,i.signal)}catch(u){if(u instanceof fe){n[a]={content:`Tool "${i.name}" blocked by PreToolUse hook: ${u.message}`,isError:!0},r.add(a);continue}throw u}}let l=Vr(i.name,this.permissions);l.allowed||(n[a]={content:l.reason??`Tool "${i.name}" is not permitted`,isError:!0},r.add(a))}let o=t.map((a,i)=>({call:a,originalIndex:i})).filter((a,i)=>!r.has(i));if(o.length===0)return n;let s=fp(o.map(a=>a.call),this.classifier);for(let a of s){if(t[0].signal.aborted){for(let i of a.indices){let l=o[i].originalIndex;n[l]={content:"Tool call aborted",isError:!0}}continue}if(a.isConcurrencySafe){let i=await Promise.allSettled(a.indices.map(async l=>{let{call:c,originalIndex:u}=o[l];return{result:await this.executeCore(c),originalIndex:u}}));for(let l of i)if(l.status==="fulfilled")n[l.value.originalIndex]=l.value.result;else{let c=l.reason instanceof Error?l.reason.message:String(l.reason),u=a.indices[i.indexOf(l)];n[o[u].originalIndex]={content:`Tool execution error: ${c}`,isError:!0}}}else for(let i of a.indices){let{call:l,originalIndex:c}=o[i];if(l.signal.aborted){n[c]={content:"Tool call aborted",isError:!0};continue}n[c]=await this.executeCore(l)}}return n}async executeCore(t){if(t.name==="agent"){if(!this.subagentExecutor)return{content:"Agent tool is not available in this session configuration",isError:!0};let o;try{o=await this.subagentExecutor.execute(t)}catch(s){o={content:`Agent tool error: ${s instanceof Error?s.message:String(s)}`,isError:!0}}return this.firePostToolUse(t.name,o.content,t.signal),o}if(t.name==="skill"){if(!this.skillExecutor)return{content:"Skill tool is not available in this session configuration",isError:!0};let o;try{o=await this.skillExecutor.execute(t)}catch(s){o={content:`Skill tool error: ${s instanceof Error?s.message:String(s)}`,isError:!0}}return this.firePostToolUse(t.name,o.content,t.signal),o}let n=this.handlers.get(t.name);if(!n)return{content:`Unknown tool "${t.name}". Available tools: ${[...this.handlers.keys()].join(", ")}`,isError:!0};let r;try{r=await n(t.input,t.signal)}catch(o){r={content:`Tool execution error: ${o instanceof Error?o.message:String(o)}`,isError:!0}}return this.firePostToolUse(t.name,r.content,t.signal),r}firePostToolUse(t,n,r){if(!this.hookRegistry)return;let o={event:"PostToolUse",toolName:t,output:n};this.hookRegistry.dispatch(o,r).catch(()=>{})}};import{spawn as gp}from"child_process";function hp(e){if(typeof e!="object"||e===null)throw new Error("Input must be an object");let t=e;if(typeof t.command!="string")throw new Error('Input must have a "command" field of type string');let n=12e4;if(t.timeout_ms!==void 0){if(typeof t.timeout_ms!="number")throw new Error("timeout_ms must be a number");if(t.timeout_ms<0||t.timeout_ms>6e5)throw new Error("timeout_ms must be between 0 and 600000");n=t.timeout_ms}return{command:t.command,timeout_ms:n}}function yp(e){return e.replace(/\x1b\[[0-9;]*[a-zA-Z]/g,"")}var Ai=async(e,t)=>{let{command:n,timeout_ms:r}=hp(e);return t.aborted?{content:"Command aborted",isError:!0}:new Promise(o=>{let s=!1;function a(m){s||(s=!0,clearTimeout(l),t.removeEventListener("abort",p),o(m))}let i=gp(n,{shell:!0,stdio:["ignore","pipe","pipe"]}),l=setTimeout(()=>{i.kill(),a({content:`Command timed out after ${r}ms`,isError:!0})},r),c="",u="";i.stdout.on("data",m=>{c+=m.toString()}),i.stderr.on("data",m=>{u+=m.toString()});let p=()=>{i.kill(),a({content:"Command aborted",isError:!0})};t.addEventListener("abort",p),i.on("close",()=>{let m=(c+u).trimEnd();m=yp(m);let f=1e5;m.length>f&&(m=m.slice(0,f)+`
1343
+ [output truncated \u2014 exceeded 100KB]`),a({content:m})}),i.on("error",m=>{a({content:`Failed to execute: ${m.message}`,isError:!0})})})};import{promises as kp}from"fs";var Mi=async(e,t)=>{if(!e||typeof e!="object")return{content:"Invalid input: expected an object",isError:!0};let n=e,r=n.file_path,o=n.offset??1,s=n.limit??2e3;if(typeof r!="string")return{content:"Invalid input: file_path must be a string",isError:!0};if(typeof o!="number"||o<1)return{content:"Invalid input: offset must be a positive number",isError:!0};if(typeof s!="number"||s<1)return{content:"Invalid input: limit must be a positive number",isError:!0};try{let a=await kp.readFile(r),i=Math.min(8192,a.length);for(let h=0;h<i;h++)if(a[h]===0)return{content:`File appears to be binary: ${r}`,isError:!0};let l=a.toString("utf-8");if(l.length===0)return{content:""};let c=l.split(`
1344
+ `),u=Math.max(0,o-1),p=Math.min(c.length,u+s),m=c.slice(u,p),f=c.length;if(m.length===0)return{content:`... (offset ${o} is past end of file \u2014 file has ${f} lines)`};let g=String(f).length,y=m.map((h,b)=>{let v=u+b+1;return`${String(v).padStart(g," ")} ${h}`}).join(`
1345
+ `);if(m.length<f){let h=u+1,b=u+m.length,v=b<f?` \u2014 pass offset=${b+1} to continue`:"";return{content:`${y}
1346
+ ... (showing lines ${h}-${b} of ${f}${v})`}}return{content:y}}catch(a){if(a instanceof Error){let i=a;return i.code==="ENOENT"?{content:`File not found: ${r}`,isError:!0}:i.code==="EACCES"?{content:`Permission denied: ${r}`,isError:!0}:{content:`Error reading file: ${a.message}`,isError:!0}}return{content:"Unknown error reading file",isError:!0}}};import{writeFile as bp}from"fs/promises";import{mkdir as wp}from"fs/promises";import{dirname as vp}from"path";function Sp(e){if(typeof e!="object"||e===null)throw new Error("Input must be an object");let t=e;if(typeof t.file_path!="string")throw new Error('Input must have a "file_path" field of type string');if(typeof t.content!="string")throw new Error('Input must have a "content" field of type string');return{file_path:t.file_path,content:t.content}}var Ri=async(e,t)=>{if(t.aborted)return{content:"Aborted",isError:!0};let{file_path:n,content:r}=Sp(e);try{let o=vp(n);return await wp(o,{recursive:!0}),await bp(n,r,{signal:t}),{content:`Wrote ${Buffer.byteLength(r,"utf8")} bytes to ${n}`}}catch(o){return o instanceof Error?"code"in o&&o.code==="EACCES"?{content:`Permission denied: ${n}`,isError:!0}:{content:`Error writing file: ${o.message}`,isError:!0}:{content:"Unknown error writing file",isError:!0}}};import{readFile as xp,writeFile as Tp}from"fs/promises";function Ep(e){if(typeof e!="object"||e===null)throw new Error("Input must be an object");let t=e;if(typeof t.file_path!="string")throw new Error('Input must have a "file_path" field of type string');if(typeof t.old_string!="string")throw new Error('Input must have an "old_string" field of type string');if(typeof t.new_string!="string")throw new Error('Input must have a "new_string" field of type string');let n=!1;if(t.replace_all!==void 0){if(typeof t.replace_all!="boolean")throw new Error("replace_all must be a boolean");n=t.replace_all}return{file_path:t.file_path,old_string:t.old_string,new_string:t.new_string,replace_all:n}}function Pp(e,t){if(t.length===0)return 0;let n=0,r=0;for(;(r=e.indexOf(t,r))!==-1;)n++,r+=t.length;return n}function Cp(e,t,n){let r=e.split(`
1347
+ `),o=0,s=0;for(let c=0;c<r.length;c++){let u=r[c]?.length??0,p=o+u+1;if(o+u>=n+t.length){s=c;break}o=p}let a=Math.max(0,s-2),i=Math.min(r.length,s+3);return`...${r.slice(a,i).join(`
1348
+ `)}...`}var _i=async(e,t)=>{if(t.aborted)return{content:"Aborted",isError:!0};let{file_path:n,old_string:r,new_string:o,replace_all:s}=Ep(e);try{let a=await xp(n,"utf-8"),i=Pp(a,r);if(i===0)return{content:`old_string not found in ${n}`,isError:!0};if(i>1&&!s)return{content:`old_string matches ${i} locations in ${n}. Use replace_all: true or provide more context.`,isError:!0};let l,c;s?(l=a.split(r).join(o),c=a.indexOf(r)):(c=a.indexOf(r),l=a.slice(0,c)+o+a.slice(c+r.length)),await Tp(n,l,"utf-8");let u=Cp(a,r,c);return{content:`${i===1?`Replaced 1 occurrence in ${n}`:`Replaced ${i} occurrences in ${n}`}
1349
+
1350
+ ${u}`}}catch(a){return{content:`Error: ${a instanceof Error?a.message:String(a)}`,isError:!0}}};import{promises as Oi}from"fs";import Ip from"path";function Ap(e,t){let n=e.replace(/\\/g,"/"),r=t.replace(/\\/g,"/");if(r.includes("**")){let s=r.split("**"),a=0;for(let i=0;i<s.length;i++){let l=s[i]??"",c=$i(l);if(i===0){let u=n.match(new RegExp(`^${c}`));if(!u)return!1;a=u[0].length}else if(i===s.length-1){let u=new RegExp(`${c}$`);if(!n.slice(a).match(u))return!1}else{let u=new RegExp(c),p=n.slice(a).match(u);if(!p)return!1;let m=p.index??0;a+=m+p[0].length}}return!0}return new RegExp(`^${$i(r)}$`).test(n)}function $i(e){return e.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,"[^/]*").replace(/\?/g,"[^/]")}async function Mp(e,t){let n=[];async function o(s,a){if(n.length>=500)return!0;try{let i=await Oi.readdir(s,{withFileTypes:!0});for(let l of i){if(n.length>=500)return!0;let c=Ip.join(s,l.name),u=a?`${a}/${l.name}`:l.name;if(Ap(u,t)&&n.push(u),l.isDirectory()&&await o(c,u))return!0}}catch{}return!1}return await o(e,""),n}var Di=async(e,t)=>{if(!e||typeof e!="object")return{content:"Invalid input: expected an object",isError:!0};let n=e,r=n.pattern,o=n.path??process.cwd();if(typeof r!="string")return{content:"Invalid input: pattern must be a string",isError:!0};if(r.trim()==="")return{content:"Invalid input: pattern cannot be empty",isError:!0};if(typeof o!="string")return{content:"Invalid input: path must be a string",isError:!0};try{if(!(await Oi.stat(o)).isDirectory())return{content:`Invalid input: path is not a directory: ${o}`,isError:!0};let a=await Mp(o,r);if(a.length===0)return{content:`No files matched pattern '${r}' in ${o}`};let i=a.join(`
1351
+ `);return a.length>=500&&(i+=`
1352
+ [results capped at 500 entries]`),{content:i}}catch(s){return s instanceof Error?"code"in s&&s.code==="ENOENT"?{content:`Path not found: ${o}`,isError:!0}:"code"in s&&s.code==="EACCES"?{content:`Permission denied: ${o}`,isError:!0}:{content:`Error scanning directory: ${s.message}`,isError:!0}:{content:"Unknown error scanning directory",isError:!0}}};import{spawn as Rp}from"child_process";function _p(e){if(typeof e!="object"||e===null)throw new Error("Input must be an object");let t=e;if(typeof t.pattern!="string")throw new Error('Input must have a "pattern" field of type string');let n=typeof t.path=="string"?t.path:process.cwd(),r;if(t.include!==void 0){if(typeof t.include!="string")throw new Error("include must be a string");r=t.include}return{pattern:t.pattern,path:n,include:r}}function $p(e){return e.replace(/\x1b\[[0-9;]*[a-zA-Z]/g,"")}var Li=async(e,t)=>{let{pattern:n,path:r,include:o}=_p(e);return t.aborted?{content:"Search aborted",isError:!0}:new Promise(s=>{let a=!1;function i(f){a||(a=!0,t.removeEventListener("abort",m),s(f))}let l=["-rn"];o&&l.push(`--include=${o}`),l.push(n,r);let c=Rp("grep",l),u="",p="";c.stdout.on("data",f=>{u+=f.toString()}),c.stderr.on("data",f=>{p+=f.toString()});let m=()=>{c.kill(),i({content:"Search aborted",isError:!0})};t.addEventListener("abort",m),c.on("close",f=>{if(f===1){i({content:`No matches found for '${n}' in ${r}`});return}if(f===2){i({content:`grep error: ${p.trim()}`,isError:!0});return}let g=u.trimEnd();g=$p(g);let y=1e5;g.length>y&&(g=g.slice(0,y)+`
1353
+ [output truncated]`),i({content:g})}),c.on("error",f=>{i({content:`Failed to execute grep: ${f.message}`,isError:!0})})})};import{promises as Op}from"fs";var Fi=async(e,t)=>{if(!e||typeof e!="object")throw new Error("Invalid input: expected an object");let r=e.path;if(typeof r!="string")throw new Error("Invalid input: path must be a string");try{let o=await Op.readdir(r,{withFileTypes:!0}),s=o.filter(c=>c.isDirectory()).map(c=>`${c.name}/`),a=o.filter(c=>!c.isDirectory()).map(c=>c.name);s.sort(),a.sort();let i=[...s,...a];return i.length===0?{content:"(empty directory)"}:{content:i.join(`
1354
+ `)}}catch(o){if(o instanceof Error){let s=o;return s.code==="ENOENT"?{content:`Directory not found: ${r}`,isError:!0}:s.code==="ENOTDIR"?{content:`Not a directory: ${r}`,isError:!0}:s.code==="EACCES"?{content:`Permission denied: ${r}`,isError:!0}:{content:`Error listing directory: ${o.message}`,isError:!0}}return{content:"Unknown error listing directory",isError:!0}}};function Ui(){return new Map([["bash",Ai],["read_file",Mi],["write_file",Ri],["edit_file",_i],["glob",Di],["grep",Li],["list_directory",Fi]])}var Ni=`You have access to tools for working with the filesystem and running commands. Follow these conventions:
1355
+
1356
+ - Use read_file before editing to verify the exact content you want to change.
1357
+ - Prefer edit_file over write_file for modifying existing files \u2014 write_file is for new files or complete rewrites.
1358
+ - Quote file paths that contain spaces with double quotes.
1359
+ - Do not run destructive shell commands (rm -rf, git reset --hard, etc.) unless the user explicitly asks.
1360
+ - Use glob and grep to discover files before reading individual files.
1361
+ - When bash output is very long, it may be truncated. If you need the full output, redirect to a file and read it.
1362
+ - Use absolute paths for file operations.
1363
+
1364
+ When you see a \`<command-name>\` tag in the current conversation turn, the skill has ALREADY been loaded by the user typing a slash command. Do NOT re-invoke the skill tool to dispatch the same skill again. Instead, treat the \`<command-message>\` as the skill name and \`<command-args>\` as its arguments, then follow the instructions in the body block immediately following the tag.`;var ji="anthropic-direct",Lp=8192,Fp="claude-sonnet-4-5-20250929",Up=null;var ge=class{name=ji;tools;providerFactory;skillExecutor;constructor(t={}){let n=[...xn];t.subagentExecutor&&n.push(ti),t.skillExecutor&&n.push(ni),this.tools=t.tools??new Gt({handlers:Ui(),schemas:n,hookRegistry:t.hookRegistry,permissions:t.permissions,subagentExecutor:t.subagentExecutor,skillExecutor:t.skillExecutor}),this.skillExecutor=t.skillExecutor,t.clientFactory&&(this.providerFactory=t.clientFactory)}query(t){let n=t.config,r=n.apiKey&&n.apiKey.length>0?n.apiKey:process.env.ANTHROPIC_API_KEY||process.env.CLAUDE_CODE_OAUTH_TOKEN||"";if(!r||r.length===0)throw new Error(`${ji} provider requires config.apiKey (resolved from ANTHROPIC_API_KEY or CLAUDE_CODE_OAUTH_TOKEN)`);let o=Yo(r),s=qo(r,o),a=this.providerFactory??Up,i=a?a(s):new Dp(s),l=Jo(o),c=Np(n.systemPrompt),u=typeof n.model=="string"&&n.model.length>0?jt(n.model)??n.model:Fp,p=jp(n),m=this.tools instanceof Gt?[...this.tools.toolDefs]:[...xn],f=[...Ee(Mt()),...Ee()],g=n.plugins??[],y=[...f,...g],h=this.skillExecutor?Ci(y):"",b=[Ni];h.length>0&&b.push(h),c&&b.push(c);let v=b.join(`
1365
+
1366
+ `);return new Rn({client:i,authMode:o,promptStream:t.prompt,toolDispatcher:this.tools,model:u,...n.permissionMode!==void 0?{permissionMode:n.permissionMode}:{},maxTokens:p,tools:m,userSystem:v,systemPrefix:l})}};function Np(e){if(e===void 0)return null;if(typeof e=="string")return e.length>0?e:null;if(typeof e=="object"&&e!==null&&"append"in e){let t=e.append;return t&&t.length>0?t:null}return null}function jp(e){let t=e.maxOutputTokens;return typeof t=="number"&&Number.isFinite(t)&&t>0?Math.floor(t):Lp}var Bi=new ge;import{Codex as Wi}from"@openai/codex-sdk";import{mkdtempSync as Bp,rmSync as Hp,writeFileSync as Wp}from"node:fs";import{tmpdir as Kp}from"node:os";import{join as Hi}from"node:path";var zt="openai-codex",Gp=[{value:"gpt-5.4",displayName:"GPT-5.4",description:"Codex default"},{value:"gpt-5.4-mini",displayName:"GPT-5.4 mini",description:"Faster, cheaper Codex variant"}];function zp(e){let t=[];if(e.continue&&t.push("continue"),e.resumeSessionAt!==void 0&&t.push("resumeSessionAt"),e.forkSession&&t.push("forkSession"),e.persistSession===!1&&t.push("persistSession=false"),e.enableFileCheckpointing&&t.push("enableFileCheckpointing"),e.thinking!==void 0&&t.push("thinking"),e.maxBudgetUsd!==void 0&&t.push("maxBudgetUsd"),e.taskBudget!==void 0&&t.push("taskBudget"),e.plugins&&e.plugins.length>0&&t.push("plugins"),e.agents&&t.push("agents"),e.agent!==void 0&&t.push("agent"),e.onElicitation&&t.push("onElicitation"),e.hooks&&t.push("hooks"),e.canUseTool&&t.push("canUseTool"),e.mcpServers&&t.push("mcpServers"),e.includeHookEvents&&t.push("includeHookEvents"),e.agentProgressSummaries&&t.push("agentProgressSummaries"),e.includePartialMessages&&t.push("includePartialMessages"),t.length>0)throw new Ot(zt,t.join(", "),`${zt} provider does not support AgentConfig fields: ${t.join(", ")}`)}function Ki(e){return e==="plan"?{sandboxMode:"read-only",approvalPolicy:"untrusted"}:{sandboxMode:"workspace-write",approvalPolicy:"never"}}function Vp(e){if(e)switch(e){case"minimal":case"low":case"medium":case"high":case"xhigh":return e;case"max":return"xhigh";default:return}}function Yp(e){let t=e.systemPrompt;if(t!==void 0){if(typeof t=="string")return t.length>0?t:void 0;if(typeof t=="object"&&t!==null&&"append"in t){let n=t.append;return n&&n.length>0?n:void 0}}}function qp(e){let t=Bp(Hi(Kp(),"afk-codex-instr-")),n=Hi(t,"instructions.md");return Wp(n,e,"utf-8"),{path:n,dispose:()=>{try{Hp(t,{recursive:!0,force:!0})}catch{}}}}function Jp(e){if(e.apiKey)return e.apiKey;let t=process.env.OPENAI_API_KEY??process.env.CODEX_API_KEY;return t&&t.length>0?t:void 0}function*Qp(e,t,n,r){if(e.type!=="thread.started"&&e.type!=="turn.started"){if(e.type==="turn.completed"){let o=e.usage;yield{type:"turn.completed",usage:{inputTokens:o.input_tokens,outputTokens:o.output_tokens,cachedInputTokens:o.cached_input_tokens,totalTokens:o.input_tokens+o.output_tokens+o.cached_input_tokens,resultSubtype:"success",isError:!1,raw:{input_tokens:o.input_tokens,output_tokens:o.output_tokens,cached_input_tokens:o.cached_input_tokens}},...t!==void 0?{sessionId:t}:{}};return}if(e.type==="turn.failed"){yield{type:"error",error:new Error(e.error.message)};return}if(e.type==="error"){yield{type:"error",error:new Error(e.message)};return}(e.type==="item.started"||e.type==="item.updated"||e.type==="item.completed")&&(yield*Xp(e.item,e.type==="item.completed",t,n,r))}}function*Xp(e,t,n,r,o){if(e.type==="agent_message"){let s=r.get(e.id)??"";if(e.text!==s){let a=e.text.startsWith(s)?e.text.slice(s.length):e.text;r.set(e.id,e.text),a.length>0&&(yield{type:"delta.text",text:a,...n!==void 0?{sessionId:n}:{}})}t&&(yield{type:"assistant.message",text:e.text,...n!==void 0?{sessionId:n}:{}},r.delete(e.id));return}if(e.type==="reasoning"){let s=o.get(e.id)??"";if(e.text!==s){let a=e.text.startsWith(s)?e.text.slice(s.length):e.text;o.set(e.id,e.text),a.length>0&&(yield{type:"delta.reasoning",text:a,...n!==void 0?{sessionId:n}:{}})}t&&o.delete(e.id);return}if(e.type==="command_execution"){if(t){let s=e.status==="failed",a=e.exit_code!==void 0?` (exit ${e.exit_code})`:"",i=`$ ${e.command}${a}
1367
+ `+(e.aggregated_output??"");yield{type:"tool.output",toolUseId:e.id,content:i,isError:s,...n!==void 0?{sessionId:n}:{}}}return}if(e.type==="file_change"){if(t){let s=e.changes.map(a=>`${a.kind} ${a.path}`).join(`
1368
+ `);yield{type:"tool.output",toolUseId:e.id,content:s,isError:e.status==="failed",...n!==void 0?{sessionId:n}:{}}}return}if(e.type==="mcp_tool_call"){if(t){let s=e.status==="failed",a;e.error?a=e.error.message:e.result?a=JSON.stringify(e.result,null,2):a="",yield{type:"tool.output",toolUseId:e.id,content:a,isError:s,...n!==void 0?{sessionId:n}:{}}}return}if(e.type==="web_search"){t&&(yield{type:"tool.output",toolUseId:e.id,content:`web_search: ${e.query}`,...n!==void 0?{sessionId:n}:{}});return}if(e.type!=="todo_list"&&e.type==="error"){t&&(yield{type:"error",error:new Error(e.message)});return}}var Yr=class{startOpts;promptStream;codex;thread;currentModel;currentSandbox;currentApproval;abortController=null;pendingAbortReason=null;closed=!1;initSessionId;dispose;closeResolve=null;closedPromise;constructor(t,n,r){this.startOpts=t,this.promptStream=n,this.initSessionId=r,this.codex=new Wi(t.codexOptions),this.thread=t.resumeId?this.codex.resumeThread(t.resumeId,t.threadOptions):this.codex.startThread(t.threadOptions),this.currentModel=t.threadOptions.model,this.currentSandbox=t.threadOptions.sandboxMode??"workspace-write",this.currentApproval=t.threadOptions.approvalPolicy??"never",t.instructionsDispose!==void 0&&(this.dispose=t.instructionsDispose),this.closedPromise=new Promise(o=>{this.closeResolve=()=>o("__closed__")})}async*[Symbol.asyncIterator](){yield{type:"session.init",info:{sessionId:this.initSessionId,...this.currentModel!==void 0?{model:this.currentModel}:{},permissionMode:this.sandboxToPermissionMode(),cwd:this.startOpts.threadOptions.workingDirectory??process.cwd(),tools:["Bash","Read","Write","Edit"],slashCommands:[],skills:[],plugins:[],mcpServers:[],apiKeySource:this.startOpts.codexOptions.apiKey!==void 0?"apiKey":"codex-cli",version:"codex-sdk"}};let n=new Map,r=new Map,o=this.initSessionId,s=this.promptStream[Symbol.asyncIterator]();try{for(;!this.closed;){let a=await Promise.race([s.next(),this.closedPromise]);if(a==="__closed__")break;let i=a;if(i.done)break;let l=i.value,c=new AbortController;if(this.abortController=c,this.pendingAbortReason!==null&&!c.signal.aborted&&(c.abort(this.pendingAbortReason),this.pendingAbortReason=null),c.signal.aborted)return;let u;try{let p=typeof l.content=="string"?l.content:l.content.map(m=>{if(typeof m=="object"&&m&&"type"in m){if(m.type==="text")return m.text;if(m.type==="image")return"[image omitted]"}return""}).join(`
1369
+ `);u=await this.thread.runStreamed(p,{signal:c.signal})}catch(p){if(c.signal.aborted)return;yield{type:"error",error:p instanceof Error?p:new Error(String(p))};return}try{for await(let p of u.events){if(this.closed)return;p.type==="thread.started"&&(o=p.thread_id),yield*Qp(p,o,n,r)}}catch(p){if(c.signal.aborted)return;yield{type:"error",error:p instanceof Error?p:new Error(String(p))};return}finally{this.abortController===c&&(this.abortController=null)}}}catch(a){yield{type:"error",error:a instanceof Error?a:new Error(String(a))}}finally{try{await s.return?.()}catch{}}}sandboxToPermissionMode(){return this.currentSandbox==="read-only"||this.currentApproval==="untrusted"?"plan":"bypassPermissions"}async interrupt(){let t=this.abortController;if(t&&!t.signal.aborted){t.abort("interrupted");return}this.pendingAbortReason="interrupted"}async setModel(t){this.currentModel=t;let n={...this.startOpts.threadOptions,...t!==void 0?{model:t}:{},sandboxMode:this.currentSandbox,approvalPolicy:this.currentApproval},r=this.thread.id;this.thread=r?this.codex.resumeThread(r,n):this.codex.startThread(n),this.startOpts.threadOptions=n}async setPermissionMode(t){let{sandboxMode:n,approvalPolicy:r}=Ki(t);this.currentSandbox=n,this.currentApproval=r;let o={...this.startOpts.threadOptions,sandboxMode:n,approvalPolicy:r},s=this.thread.id;this.thread=s?this.codex.resumeThread(s,o):this.codex.startThread(o),this.startOpts.threadOptions=o}async supportedCommands(){return[]}async supportedModels(){return Gp.map(t=>({...t}))}async supportedAgents(){return[]}async getContextUsage(){return{tools:[],agents:[],isAutoCompactEnabled:!1,apiUsage:null}}async mcpServerStatus(){return[]}async accountInfo(){return{}}async rewindFiles(t,n){throw new Ot(zt,"rewindFiles",`${zt} provider does not support file checkpoint rewind.`)}close(){this.closed=!0;let t=this.abortController;t&&!t.signal.aborted?t.abort("closed"):this.pendingAbortReason="closed",this.closeResolve?.(),this.dispose?.()}getThread(){return this.thread}},Zp=null;var _n=class{name=zt;query(t){zp(t.config);let n=Jp(t.config),r=Vp(t.config.effort),{sandboxMode:o,approvalPolicy:s}=Ki(t.config.permissionMode),a={...t.config.model!==void 0?{model:t.config.model}:{},sandboxMode:o,approvalPolicy:s,...r!==void 0?{modelReasoningEffort:r}:{},skipGitRepoCheck:!0,workingDirectory:process.cwd()},i=Yp(t.config),l={};n!==void 0&&(l.apiKey=n);let c;if(i!==void 0){let{path:g,dispose:y}=qp(i);l.config={...l.config??{},model_instructions_file:g},c=y}W(`\u{1F7E2} OpenAICodexProvider: creating Codex thread (model=${String(t.config.model)}, sandbox=${o}, approval=${s})`);let u=Zp,p=u??(g=>new Wi(g)),m=`codex-pending-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,f=new Yr({threadOptions:a,codexOptions:l,...t.config.resume!==void 0?{resumeId:t.config.resume}:{},...c!==void 0?{instructionsDispose:c}:{}},t.prompt,m);if(u){let g=p(l);f.codex=g,f.thread=t.config.resume?g.resumeThread(t.config.resume,a):g.startThread(a)}return f}},Gi=new _n;var em=new Set(["opus","opus_1m","sonnet","sonnet_1m","haiku","auto"]);function Pe(e){if(!e)return"anthropic-direct";let t=e.trim().toLowerCase();return!t||em.has(t)||t.startsWith("claude-")||t.startsWith("claude_")?"anthropic-direct":t.startsWith("gpt-")||t.startsWith("gpt_")||t.startsWith("o1")||t.startsWith("o3")||t.startsWith("o4")||t.startsWith("codex-")||t.startsWith("codex_")||t==="codex"?"openai-codex":"anthropic-direct"}function zi(e){return Pe(e)==="openai-codex"?Gi:Bi}async function Vi(e,t,n={}){e&&await e.dispatch(t,n.signal)}async function Yi(e,t,n={}){if(e)try{await e.dispatch(t,n.signal)}catch(r){if(r instanceof fe||r instanceof ke){W(`SessionEnd hook swallowed ${r.name}: ${r.message}`),n.onError?.(r);return}W(`SessionEnd hook unexpected error: ${String(r)}`),n.onError?.(r instanceof Error?r:new Error(String(r)))}}var $n=class{pendingResolve=null;bufferedMessage=null;getSessionId;constructor(t){this.getSessionId=t}pushUserMessage(t){if(this.pendingResolve){let n=this.pendingResolve;this.pendingResolve=null;let r=this.getSessionId();n({content:t,...r!==void 0?{sessionId:r}:{}});return}this.bufferedMessage=t}createIterable(){let t=this;return{[Symbol.asyncIterator](){return{next(){if(t.bufferedMessage!==null){let n=t.bufferedMessage;t.bufferedMessage=null;let r=t.getSessionId();return Promise.resolve({value:{content:n,...r!==void 0?{sessionId:r}:{}},done:!1})}return new Promise(n=>{t.pendingResolve=r=>n({value:r,done:!1})})},return(){return Promise.resolve({value:void 0,done:!0})}}}}}};function tm(e){let t=/Output too large \((\d+(?:\.\d+)?)\s*(B|KB|MB|GB)\)\.\s*Full output saved to:\s*(\/[^\n]+)/,n=e.match(t);if(!n||!n[1]||!n[2]||!n[3])return null;let r=n[1],o=n[2],s=n[3],a=parseFloat(r),i=a;o==="KB"?i=a*1024:o==="MB"?i=a*1024*1024:o==="GB"&&(i=a*1024*1024*1024);let l=r;return a%1===0&&(l=String(Math.floor(a))),l+=o,{sizeLabel:l,sizeBytes:Math.round(i),absolutePath:s.trim()}}function nm(e){if(e<1024)return`${e}B`;let t=e/1024;if(t<1024)return t%1===0?`${Math.floor(t)}KB`:`${t.toFixed(1)}KB`;let n=t/1024;if(n<1024)return n%1===0?`${Math.floor(n)}MB`:`${n.toFixed(1)}MB`;let r=n/1024;return r%1===0?`${Math.floor(r)}GB`:`${r.toFixed(1)}GB`}function rm(e){let t=Buffer.byteLength(e,"utf8"),n=nm(t),r=e.split(`
1370
+ `);if(r.length<=1&&e.length<=80)return{content:e,truncated:!1,sizeBytes:t,sizeLabel:n};if(r.length<=1)return e.length<=80?{content:e,truncated:!1,sizeBytes:t,sizeLabel:n}:{content:e.substring(0,80)+"\u2026",truncated:!0,sizeBytes:t,sizeLabel:n};if(e.length<=80)return{content:e,truncated:!1,sizeBytes:t,sizeLabel:n};let o=r[0]??"",s=o;return o.length>80&&(s=o.substring(0,80)+"\u2026"),{content:s+`\u2026+${r.length} lines`,truncated:!0,lineCount:r.length,sizeBytes:t,sizeLabel:n}}function om(e,t){let n={...e.raw??{}};return e.inputTokens!==void 0&&(n.input_tokens=e.inputTokens),e.outputTokens!==void 0&&(n.output_tokens=e.outputTokens),e.cachedInputTokens!==void 0&&(n.cache_read_input_tokens=e.cachedInputTokens),e.cacheCreationTokens!==void 0&&(n.cache_creation_input_tokens=e.cacheCreationTokens),e.totalTokens!==void 0&&(n.total_tokens=e.totalTokens),{sessionId:t,stopReason:e.stopReason??void 0,resultSubtype:e.resultSubtype,durationMs:e.durationMs,durationApiMs:e.durationApiMs,totalCostUsd:e.totalCostUsd,isError:e.isError,usage:Object.keys(n).length>0?n:void 0,modelUsage:e.modelUsage,permissionDenials:e.permissionDenials,errors:e.errors}}function sm(e,t){let n=t.info;e.setSessionMetadata(r=>({...r,sessionId:n.sessionId,model:n.model??r.model,...n.permissionMode!==void 0?{permissionMode:n.permissionMode}:{},...n.cwd!==void 0?{cwd:n.cwd}:{},tools:n.tools?[...n.tools]:r.tools,slashCommands:n.slashCommands?[...n.slashCommands]:r.slashCommands,skills:n.skills?[...n.skills]:r.skills,plugins:n.plugins?n.plugins.map(o=>({...o})):r.plugins,mcpServers:n.mcpServers?n.mcpServers.map(o=>({...o})):r.mcpServers,...n.apiKeySource!==void 0?{apiKeySource:n.apiKeySource}:{},...n.version!==void 0?{claudeCodeVersion:n.version}:{},...n.outputStyle!==void 0?{outputStyle:n.outputStyle}:{}})),e.updateSessionIdentity(n.sessionId),e.resolveInitialization()}function im(e,t){e.setSessionMetadata(n=>({...n,sessionId:t.sessionId,...t.permissionMode!==void 0?{permissionMode:t.permissionMode}:{permissionMode:n.permissionMode},...t.status!==void 0?{status:t.status}:{}}))}function am(e,t){let n=tm(t.content);if(n){e.push({type:"chunk",chunk:{type:"tool_result",toolUseId:t.toolUseId,content:`Output persisted (${n.sizeLabel}) \u2192 ${n.absolutePath}`,isError:t.isError===!0,persistedPath:n.absolutePath,sizeBytes:n.sizeBytes,sizeLabel:n.sizeLabel}});return}let{content:r,truncated:o,lineCount:s,sizeBytes:a,sizeLabel:i}=rm(t.content);e.push({type:"chunk",chunk:{type:"tool_result",toolUseId:t.toolUseId,content:r,isError:t.isError===!0,sizeBytes:a,sizeLabel:i,...o&&{truncated:o},...s!==void 0&&{lineCount:s}}})}function lm(e,t){if(!t)return;let n={role:"assistant",content:t,timestamp:new Date};e.conversationHistory.push(n),e.messageQueue.push({type:"message",message:n})}async function qi(e){try{for await(let t of e.providerStream)switch(t.type){case"session.init":sm(e,t);break;case"session.status":im(e,t);break;case"delta.text":e.messageQueue.push({type:"chunk",chunk:{type:"content",content:t.text,metadata:{eventType:"delta",deltaType:"text_delta"}}});break;case"delta.reasoning":e.messageQueue.push({type:"chunk",chunk:{type:"thinking",content:t.text,metadata:{eventType:"delta",deltaType:"thinking_delta"}}});break;case"assistant.message":t.sessionId&&e.updateSessionIdentity(t.sessionId),lm(e,t.text);break;case"tool.use.start":e.messageQueue.push({type:"chunk",chunk:{type:"tool_use_detail",toolUseId:t.toolUseId,toolName:t.toolName,toolInput:t.toolInput}});break;case"tool.use":e.messageQueue.push({type:"chunk",chunk:{type:"tool_use",content:t.summary,metadata:{eventType:"tool_use_summary",precedingToolUseIds:t.toolUseIds}}});break;case"tool.output":am(e.messageQueue,t);break;case"progress":e.messageQueue.push({type:"progress",progress:{taskId:t.progress.taskId,description:t.progress.description,...t.progress.summary!==void 0?{summary:t.progress.summary}:{},...t.progress.lastToolName!==void 0?{lastToolName:t.progress.lastToolName}:{},totalTokens:t.progress.totalTokens,toolUses:t.progress.toolUses,durationMs:t.progress.durationMs}});break;case"suggestion":e.messageQueue.push({type:"suggestion",suggestion:t.suggestion});break;case"turn.completed":let n=om(t.usage,t.sessionId??e.getSessionMetadata().sessionId);e.setLastResponseMetadata(n);for(let r=e.conversationHistory.length-1;r>=0;r--){let o=e.conversationHistory[r];if(o?.role==="assistant"){o.metadata=n;break}}e.messageQueue.push({type:"done",metadata:n});break;case"error":throw t.error}e.resolveInitializationIfNeeded(),e.messageQueue.complete()}catch(t){let n=t instanceof Error?t:new Error(String(t));throw e.resolveInitializationIfNeeded(),e.messageQueue.fail(n),n}}function Ji(e,t,n){e&&(e.aborted?t.abort(e.reason):e.addEventListener("abort",()=>{t.signal.aborted||t.abort(e.reason)},{once:!0})),t.signal.addEventListener("abort",n,{once:!0})}function Qi(e,t){let n=e.permissionMode??"bypassPermissions",r=e.persistSession??!0,o={sessionId:e.sessionId,configuredSessionId:e.sessionId,resume:e.resume,resumeSessionAt:e.resumeSessionAt,continue:e.continue,forkSession:e.forkSession,persistSession:r},s={sessionId:e.sessionId,model:t,permissionMode:n};return{sessionIdentity:o,metadata:s}}async function Xi(e){try{await Vi(e.hookRegistry,{event:"SessionStart",sessionId:e.sessionId()},{signal:e.abortSignal}),await qi({providerStream:e.providerQuery,messageQueue:e.messageQueue,conversationHistory:e.conversationHistory,getSessionMetadata:()=>e.stateManager.getSessionMetadata(),setSessionMetadata:t=>e.stateManager.setSessionMetadata(t),updateSessionIdentity:t=>e.stateManager.updateSessionIdentity(t),resolveInitialization:()=>e.stateManager.resolveInitializationOnce(),resolveInitializationIfNeeded:()=>e.stateManager.resolveInitializationIfNeeded(),setLastResponseMetadata:e.setLastResponseMetadata})}catch(t){let n=t instanceof Error?t:new Error(String(t));e.stateManager.isInitializationSettled()||e.stateManager.rejectInitializationOnce(n),await e.dispatchEnd("error").catch(()=>{})}}var On=class{initializationPromise;resolveInitialization;rejectInitialization;initializationSettled=!1;sessionMetadata;sessionIdentity;constructor(t,n){this.sessionIdentity=t,this.sessionMetadata=n,this.initializationPromise=new Promise((r,o)=>{this.resolveInitialization=r,this.rejectInitialization=o})}waitForInitialization(){return this.initializationPromise}getSessionIdentity(){return{...this.sessionIdentity,sessionId:this.getSessionId()}}getSessionMetadata(){return{...this.sessionMetadata,sessionId:this.getSessionId()}}getSessionId(){return this.sessionMetadata.sessionId??this.sessionIdentity.sessionId}updateSessionIdentity(t){t&&(this.sessionIdentity={...this.sessionIdentity,sessionId:t},this.sessionMetadata={...this.sessionMetadata,sessionId:t})}setSessionMetadata(t){this.sessionMetadata=t(this.sessionMetadata)}resolveInitializationIfNeeded(){this.initializationSettled||(this.initializationSettled=!0,this.resolveInitialization(this.getSessionMetadata()))}resolveInitializationOnce(){this.initializationSettled||(this.initializationSettled=!0,this.resolveInitialization(this.getSessionMetadata()))}rejectInitializationOnce(t){this.initializationSettled||(this.initializationSettled=!0,this.rejectInitialization(t))}isInitializationSettled(){return this.initializationSettled}};async function Zi(e,t){return await new Promise((n,r)=>{let o=null,s="",a=!1,i=c=>{a||(a=!0,clearTimeout(l),c())},l=Number.isFinite(t)&&t>0?setTimeout(()=>{i(()=>r(new Error("Response timeout")))},t):void 0;(async()=>{try{for await(let c of e){if(process.env.AFK_CODEX_DEBUG&&console.log("[wait] got event:",c.type),c.type==="error"){i(()=>r(c.error));return}if(c.type==="chunk"&&c.chunk.type==="content"&&(s+=c.chunk.content),c.type==="message"&&c.message.role==="assistant"&&(o=c.message),c.type==="done"){if(process.env.AFK_CODEX_DEBUG&&console.log("[wait] settling with done; assistantMessage=",!!o,"streamedContent=",s.length),o){let u=o;i(()=>n({...u,metadata:c.metadata}));return}if(s){i(()=>n({role:"assistant",content:s,metadata:c.metadata,timestamp:new Date}));return}}}i(o?()=>n(o):s?()=>n({role:"assistant",content:s,timestamp:new Date}):()=>r(new Error("No assistant response received")))}catch(c){i(()=>r(c instanceof Error?c:new Error(String(c))))}})()})}var ue=class{config;currentState="idle";messageQueue;providerQuery;conversationHistory=[];turnCount=0;lastResponseMetadata=null;processingPromise=null;inputStream;abortController;hookRegistry;sessionEndDispatched=!1;stateManager;constructor(t){this.config=t,this.abortController=new AbortController,this.hookRegistry=t.hookRegistry,Ji(t.abortSignal,this.abortController,()=>{this.onAbort()}),this.initSdkLifecycle()}initSdkLifecycle(){this.messageQueue=new un;let t=jt(this.config.model)??this.config.model,{sessionIdentity:n,metadata:r}=Qi(this.config,t);this.stateManager=new On(n,r),this.inputStream=new $n(()=>this.sessionId);let o=this.config.provider??zi(t);W(`\u{1F7E2} AgentSession: Creating query session via provider=${o.name}`),this.providerQuery=o.query({prompt:this.inputStream.createIterable(),config:this.config}),this.conversationHistory=[],this.turnCount=0,this.lastResponseMetadata=null,this.sessionEndDispatched=!1,this.currentState="idle",this.processingPromise=Xi({providerQuery:this.providerQuery,messageQueue:this.messageQueue,conversationHistory:this.conversationHistory,stateManager:this.stateManager,hookRegistry:this.hookRegistry,abortSignal:this.abortController.signal,sessionId:()=>this.sessionId,setLastResponseMetadata:s=>this.lastResponseMetadata=s,dispatchEnd:s=>this.dispatchSessionEndOnce(s)})}get state(){return this.currentState}get sessionId(){return this.stateManager.getSessionId()}get abortSignal(){return this.abortController.signal}async sendMessage(t,n={}){this.assertCanSend(),this.currentState=n.stream?"streaming":"processing";let r={role:"user",content:t,timestamp:new Date};this.conversationHistory.push(r);let o=this.config.timeoutMs??gn;try{this.inputStream.pushUserMessage(t);let s=await hn(Zi(this.messageQueue,o),o,{controller:this.abortController,label:this.sessionId??"session"});return this.turnCount++,s}finally{this.state!=="closed"&&(this.currentState="idle")}}async*sendMessageStream(t){this.assertCanSend(),this.currentState="streaming";let r={role:"user",content:typeof t=="string"?t:this.summarizeContentBlocks(t),timestamp:new Date};this.conversationHistory.push(r),this.inputStream.pushUserMessage(t);try{for await(let o of this.messageQueue)if(o.type==="done"&&this.turnCount++,yield o,o.type==="done"||o.type==="error")break}finally{this.state!=="closed"&&(this.currentState="idle")}}summarizeContentBlocks(t){let n=[],r=0;for(let s of t)s.type==="text"?n.push(s.text):s.type==="image"&&r++;let o=n.join(" ");return r>0&&(o=o?`${o} [+ ${r} image(s)]`:`[+ ${r} image(s)]`),o||"[content block(s)]"}async interrupt(){this.currentState!=="streaming"&&this.currentState!=="processing"||(this.currentState="idle",await this.providerQuery.interrupt())}async reset(){if(this.currentState==="closed")throw new Error("Cannot reset: session is closed");if(this.abortController.signal.aborted)throw new ke("Cannot reset: session aborted");if(this.currentState==="processing"||this.currentState==="streaming")try{await this.providerQuery.interrupt()}catch{}await this.dispatchSessionEndOnce("reset");try{await this.providerQuery.close()}catch{}this.processingPromise&&await Promise.race([this.processingPromise,new Promise(t=>setTimeout(t,Ir))]).catch(()=>{}),this.messageQueue.complete(),this.stateManager.resolveInitializationIfNeeded();try{this.initSdkLifecycle()}catch(t){throw this.currentState="closed",new Error(`Session reset failed during lifecycle rebuild: ${t instanceof Error?t.message:String(t)}`,{cause:t})}}async onAbort(){try{await this.providerQuery.interrupt()}catch{}}async setModel(t){let n=jt(t),r=this.stateManager.getSessionMetadata();await this.providerQuery.setModel(n??r.model??""),n&&this.stateManager.setSessionMetadata(o=>({...o,model:n}))}async setPermissionMode(t){await this.providerQuery.setPermissionMode(t),this.stateManager.setSessionMetadata(n=>({...n,permissionMode:t}))}waitForInitialization(){return this.stateManager.waitForInitialization()}getSessionIdentity(){return this.stateManager.getSessionIdentity()}getSessionMetadata(){return this.stateManager.getSessionMetadata()}getQuery(){return this.providerQuery}supportedCommands(){return this.providerQuery.supportedCommands()}supportedModels(){return this.providerQuery.supportedModels()}supportedAgents(){return this.providerQuery.supportedAgents()}getContextUsage(){return this.providerQuery.getContextUsage()}mcpServerStatus(){return this.providerQuery.mcpServerStatus()}accountInfo(){return this.providerQuery.accountInfo()}rewindFiles(t,n){return this.providerQuery.rewindFiles(t,n)}async compact(){if(this.currentState==="closed")throw new Error("Cannot compact: session is closed");if(this.currentState!=="idle")return{compacted:!1,reason:"session-busy",messagesBefore:0,messagesAfter:0};let t=this.providerQuery.compact?.bind(this.providerQuery);return t?t():{compacted:!1,reason:"not-supported",messagesBefore:0,messagesAfter:0}}getLastResponseMetadata(){return this.lastResponseMetadata}getOutputStream(){return this.messageQueue}getInputStreamRef(){return{pushUserMessage:t=>this.inputStream.pushUserMessage(t)}}getHistory(){return[...this.conversationHistory]}getTurnCount(){return this.turnCount}async close(){if(this.currentState!=="closed"){this.currentState="closed",this.abortController.signal.aborted||this.abortController.abort("closed"),this.stateManager.resolveInitializationIfNeeded();try{this.providerQuery.close()}catch{}if(this.processingPromise)try{await Promise.race([this.processingPromise,new Promise(t=>setTimeout(t,Ir))])}catch{}this.messageQueue.complete(),await this.dispatchSessionEndOnce("close")}}async dispatchSessionEndOnce(t){this.sessionEndDispatched||(this.sessionEndDispatched=!0,await Yi(this.hookRegistry,{event:"SessionEnd",sessionId:this.sessionId,reason:t}))}assertCanSend(){if(this.currentState==="closed")throw new Error("Cannot send message: session is closed");if(this.abortController.signal.aborted)throw new ke("Cannot send message: session aborted");if(this.currentState==="processing"||this.currentState==="streaming")throw new Error("Cannot send message: session is busy");if(this.config.maxTurns&&this.turnCount>=this.config.maxTurns)throw new Error(`Maximum turns (${this.config.maxTurns}) exceeded`)}};var Jr=class{handlers=new Map;register(t,n){let r=this.handlers.get(t);return r||(r=[],this.handlers.set(t,r)),r.push(n),()=>{let o=this.handlers.get(t);if(!o)return;let s=o.indexOf(n);s>=0&&o.splice(s,1)}}count(t){return this.handlers.get(t)?.length??0}async dispatch(t,n){qr(n,t.event);let r=this.handlers.get(t.event);if(!r||r.length===0)return{};let o=r.slice(),s={};for(let a of o){qr(n,t.event);let i;try{i=await a(t)}catch(l){throw new fe(`hook handler threw during ${t.event}`,t.event,l instanceof Error?l.message:String(l),{cause:l})}if(qr(n,t.event),cm(i))throw new fe(`hook handler blocked ${t.event}${i.reason?`: ${i.reason}`:""}`,t.event,i.reason);s=i}return s}};function cm(e){return e.continue===!1||e.decision==="block"}function qr(e,t){if(e?.aborted){let n=e.reason,r=`aborted during ${t}${n?`: ${String(n)}`:""}`;throw new ke(r)}}function ea(){return new Jr}function ta(){return ea()}var um=["shadow-verify","shadow_verify","resolve","diagnose","appmap","qualify","mint"],dm=[/\bverdict(s)?\b/i,/\brecommend(ation)?s?\b/i,/\bshould\s+(delete|remove|rewrite|refactor|rename|reject|merge|revert|disable)\b/i,/\b(USELESS|KEEP|REJECT|APPROVE|SALVAGE|BLOCK|FAIL)\b/,/\b(redundant|duplicated|superseded|obsolete)\b/i,/\bvulnerab\w*\b/i,/\bunused\b/i,/\bbroken\b/i,/\bregress\w*\b/i,/\|\s*(status|verdict|decision|severity|risk|finding|priority|holds\??)\s*\|/i,/\bfound\s+\d+\s*(issue|problem|bug|error|finding|vulnerabilit)/i,/\b(critical|high|medium|low)\s+(severity|priority|risk)\b/i,/\bclaim(s)?\b[^\n]{0,80}\b(holds?|refuted|verified|partial|confirmed|disputed)\b/i,/\b(root\s*cause|incident)\b/i,/\brecommend\s+(removing|deleting|rewriting|refactoring|merging|reverting)\b/i,/\bI\s+(applied|committed|pushed|edited|wrote|fixed|patched|reset|restored|staged)\b/i,/\b(applied|committed|pushed|fixed|patched)\s+(the|these|those)\s+(change|commit|fix|patch|edit)/i],pm=[/\bverifier_verdict\b/i,/"\s*claim\s*"\s*:/i,/\bre-derived\b[^.\n]{0,80}\bindependent/i,/\bindependently\s+(re-derived|re-verified|verified|checked)\b/i,/\bverifier\s+(agrees|disagrees|confirms|refutes)\b/i],mm=`shadow-verify nudge:
1371
+
1372
+ The sub-agent that just finished returned output that reads like **decision-driving findings** (verdicts, recommendations, audit conclusions, or claim-style results that could drive file edits, deletions, commits, or external side-effects).
1373
+
1374
+ Single-pass sub-agent reports are prone to confident hallucination \u2014 polished output that falls apart on re-derivation. Before acting on these conclusions, consider dispatching \`/shadow-verify\`. Independent verifiers will re-derive the 2\u20133 most load-bearing claims from scratch (without seeing the original reasoning) and flag any that don't hold up.
1375
+
1376
+ Skip when: the findings are purely exploratory, the sub-agent ran inside an already-verifying orchestrator, the user is about to dismiss the report, or the stakes are low (read-only Q&A).`;function fm(e){if(!e)return!1;let t=e.toLowerCase();return um.some(n=>t.includes(n))}function gm(e){return pm.some(t=>t.test(e))}function hm(e){let t=0;for(let n of dm)n.test(e)&&t++;return t}function na(e){if(e.event!=="SubagentStop")return{};let t=e.lastMessage??"";return t.length<600?{}:fm(e.agentType)?{}:gm(t)?{}:hm(t)<2?{}:{injectContext:mm}}function yt(e){let t=ta();return t.register("SubagentStop",na),e&&t.register("SubagentStop",n=>n.event!=="SubagentStop"?{}:n.status==="idle"||n.status==="running"?{}:(e({subagentId:n.subagentId,status:n.status,durationMs:n.durationMs,agentType:n.agentType}),{})),t}function he(e){let t=Math.round(e/1e3);if(t<=0)return"0s";let n=Math.floor(t/86400),r=Math.floor(t%86400/3600),o=Math.floor(t%3600/60),s=t%60;return n>0?`${n}d ${r}h`:r>0?`${r}h ${o}m`:o>0?`${o}m ${s}s`:`${s}s`}function pe(e){return e===0?"$0.00":e<.01?`$${e.toFixed(4)}`:`$${e.toFixed(2)}`}function O(e){if(e<1e3)return String(e);if(e<1e6){let n=e/1e3;return n%1===0?`${n}k`:`${n.toFixed(1).replace(/\.0$/,"")}k`}let t=e/1e6;return t%1===0?`${t}m`:`${t.toFixed(1).replace(/\.0$/,"")}m`}var ym="[skill-routing: active]\n\nRoute recurring work through registered skills instead of rolling ad-hoc solutions:\n\n- Multi-file implementation or new features \u2192 `/mint`\n- Bugs, failing tests, or regressions \u2192 `/diagnose`\n- High-stakes sub-agent output that will drive edits or commits \u2192 `/shadow-verify` before acting\n- Refactor needing parallel waves \u2192 `/parallelize`\n\nCommon composed sequences \u2014 reach for these when the task shape matches:\n\n- Bug with failing test and non-trivial fix \u2192 `/diagnose` \u2192 `/shadow-verify` on the proposed fix\n- Refactor needing parallel waves \u2192 plan \u2192 `/parallelize` \u2192 build waves\n\nSkip orchestration for: single-line edits, trivial Q&A, and direct tool calls the user explicitly requested. The goal is leverage, not ceremony \u2014 if a skill would add overhead without adding value, don't invoke it.";function Dn(e,t){return!e||!t?e:`${e}
1377
+
1378
+ ${ym}`}import Fn from"chalk";import{Lexer as Mm}from"marked";import km from"string-width";var ra=/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g,oa=typeof Intl<"u"&&"Segmenter"in Intl?new Intl.Segmenter(void 0,{granularity:"grapheme"}):null;function U(e){return km(e)}function Ln(e){return e.length===0?[]:oa?Array.from(oa.segment(e),t=>t.segment):Array.from(e)}function bm(e){let t=[],n=0,r;for(ra.lastIndex=0;(r=ra.exec(e))!==null;){if(r.index>n)for(let o of Ln(e.slice(n,r.index)))t.push({type:"text",value:o});t.push({type:"ansi",value:r[0]}),n=r.index+r[0].length}if(n<e.length)for(let o of Ln(e.slice(n)))t.push({type:"text",value:o});return t}function Oe(e,t){let n=Math.max(0,t-U(e));return e+" ".repeat(n)}function wm(e,t){let n=Math.max(0,t-U(e));return" ".repeat(n)+e}function sa(e,t,n="left"){let r=Math.max(0,t-U(e));if(r===0)return e;if(n==="right")return wm(e,t);if(n==="center"){let o=Math.floor(r/2);return" ".repeat(o)+e+" ".repeat(r-o)}return Oe(e,t)}function Ge(e,t,n="\u2026"){if(t<=0)return"";if(U(e)<=t)return e;let r=U(n),o=Math.max(0,t-r),s=0,a="",i=!1;for(let l of bm(e)){if(l.type==="ansi"){a+=l.value,i=!0;continue}let c=s+U(l.value);if(c>o)break;a+=l.value,s=c}return a+n+(i?"\x1B[0m":"")}function ia(e,t){return Number.isFinite(e)?Math.max(0,Math.min(t,Math.trunc(e))):0}function Qr(e,t){let n=ia(t,e.length);if(n===0||e.length===0)return 0;let r=0;for(let o of Ln(e)){let s=r+o.length;if(s>=n)return r;r=s}return r}function Vt(e,t){let n=ia(t,e.length);if(n>=e.length||e.length===0)return e.length;let r=0;for(let o of Ln(e)){let s=r+o.length;if(r>=n||n>r&&n<s)return s;r=s}return e.length}import vm from"chalk";import{createEmphasize as Sm,common as xm}from"emphasize";import re from"chalk";var d={brand:re.hex("#E67E4C"),user:re.cyan,tool:re.blue,toolArg:re.dim.white,toolResult:re.dim.green,thinking:re.italic.hex("#9B8FB5"),success:re.green,error:re.red,warning:re.yellow,plan:re.hex("#9F7CE0"),meta:re.blackBright,info:re.blue,heading:re.bold.cyan,label:re.dim,dim:re.dim,bold:re.bold,italic:re.italic};var aa={keyword:d.brand,built_in:d.brand,literal:d.brand,tag:d.brand,string:d.user,regexp:d.user,attr:d.user,comment:d.meta,meta:d.meta,quote:d.meta,number:d.warning,function:d.tool,title:d.tool,class:d.tool,"selector-tag":d.tool};var la=Sm(xm),Tm=2048,Em=512,Pm=32,De=new Map;function Cm(e){let t=De.get(e);if(t!==void 0)return De.delete(e),De.set(e,t),t}function Im(e,t){if(De.has(e)&&De.delete(e),De.set(e,t),De.size>Pm){let n=De.keys().next().value;n!==void 0&&De.delete(n)}}function ca(e,t){if(vm.level===0||e.length>Tm)return e;let n=e.length<Em,r=n?`${t} ${e}`:"";if(n){let s=Cm(r);if(s!==void 0)return s}let o;try{if(!t||!la.registered(t))o=e;else{let s=la.highlight(t,e,aa);o=typeof s?.value=="string"?s.value:e}}catch{o=e}return n&&Im(r,o),o}import Am from"wrap-ansi";function Q(e,t){if(!Number.isFinite(t)||t<=0||t===Number.POSITIVE_INFINITY)return e;let n=Math.floor(t);return Am(e,n,{hard:!1,trim:!1,wordWrap:!0})}function ua(e){return U(e)}function Rm(e,t,n){return sa(e,t,n??"left")}function ze(e,t={}){let n=Mm.lex(e),r=Number.isFinite(t.maxWidth)?Math.floor(t.maxWidth??0):void 0;function o(a){return a?a.map(i=>{switch(i.type){case"codespan":return d.user(i.text);case"strong":{let l=i;return d.bold(l.tokens?o(l.tokens):l.text)}case"em":{let l=i;return d.italic(l.tokens?o(l.tokens):l.text)}case"text":return i.text;case"link":{let l=i;return(l.tokens?o(l.tokens):l.text)+d.dim(` (${l.href})`)}default:return i.raw}}).join(""):""}function s(a){return a.map(i=>{switch(i.type){case"heading":{let l=i,c=l.tokens?o(l.tokens):l.text;return l.depth===1?d.bold(d.info(`
1379
+ `+c+`
1380
+ `)):l.depth===2?d.bold(d.user(`
1381
+ `+c+`
1382
+ `)):d.bold(c)}case"paragraph":return o(i.tokens)+`
1383
+ `;case"code":{let l=i,c=l.lang||"text",p=ca(l.text,c).split(`
1384
+ `);p.length>0&&p[p.length-1]===""&&p.pop();let m=d.dim("\u2502 "),f=p.map(y=>m+y).join(`
1385
+ `);return(l.lang?d.dim(`\u2502 ${l.lang}`)+`
1386
+ `:"")+f+`
1387
+ `}case"codespan":return d.user(i.text);case"strong":{let l=i;return d.bold(l.tokens?o(l.tokens):l.text)}case"em":{let l=i;return d.italic(l.tokens?o(l.tokens):l.text)}case"text":{let l=i;return l.tokens?o(l.tokens):l.text}case"list":{let l=i;return l.items.map((c,u)=>{let p=l.ordered?` ${u+1}. `:" \u2022 ",m=c.tokens?s(c.tokens):c.text;return d.warning(p)+m.trim()}).join(`
1388
+ `)}case"space":return`
1389
+ `;case"hr":return d.dim("\u2500".repeat(40));case"blockquote":{let l=i;return(l.tokens?s(l.tokens):l.text).split(`
1390
+ `).map(u=>d.dim(" \u2502 ")+u).join(`
1391
+ `)}case"table":{let l=i,c=S=>S.tokens?o(S.tokens):S.text,u=l.header.map(c),p=l.rows.map(S=>S.map(c)),m=u.length,f=new Array(m).fill(0);for(let S=0;S<m;S++){let R=ua(u[S]??"");for(let k of p)R=Math.max(R,ua(k[S]??""));f[S]=R}let g=r??Number.POSITIVE_INFINITY,y=3*m+1,h=g>=y+m?1:0,b=Math.max(m*h,g-y),v=f.reduce((S,R)=>S+R,0);if(Number.isFinite(g)&&v>b){let S=f.slice(),R=S.reduce((k,C)=>k+Math.max(0,C-h),0);if(R>0){let k=v-b,C=Math.min(1,k/R);for(let x=0;x<S.length;x++){let M=Math.max(0,S[x]-h);S[x]=Math.max(h,S[x]-Math.round(M*C))}}for(let k=0;k<S.length;k++)f[k]=S[k]??f[k]??0}let w=l.align,P=(S,R,k)=>d.dim(S+f.map(C=>"\u2500".repeat(C+2)).join(R)+k),T=(S,R)=>R<=0?[""]:Q(S,R).split(`
1392
+ `).map(C=>Ge(C,R)),L=(S,R=!1)=>{let k=S.map((M,ne)=>T(R?d.bold(M):M,f[ne]??0)),C=Math.max(1,...k.map(M=>M.length)),x=[];for(let M=0;M<C;M++)x.push(d.dim("\u2502")+k.map((ne,H)=>" "+Rm(ne[M]??"",f[H]??0,w[H]??null)+" ").join(d.dim("\u2502"))+d.dim("\u2502"));return x},E=[P("\u250C","\u252C","\u2510")];E.push(...L(u,!0)),E.push(P("\u251C","\u253C","\u2524"));for(let S=0;S<p.length;S++)E.push(...L(p[S])),S<p.length-1&&E.push(P("\u251C","\u253C","\u2524"));return E.push(P("\u2514","\u2534","\u2518")),E.join(`
1393
+ `)+`
1394
+ `}default:return i.raw}}).join("")}return s(n)}var Xr=class{useColors;constructor(t=!0){this.useColors=t&&!!Fn.level}formatMarkdown(t){return this.useColors?ze(t):t}formatError(t,n){let r=d.error("\u2717 Error: ")+t;return n&&n.message&&(r+=`
1395
+ `+d.error(n.message)),n&&n.stack&&process.env.DEBUG&&(r+=`
1396
+ `+d.dim(n.stack)),r}formatSuccess(t){return d.success("\u2713 ")+t}formatInfo(t){return d.info("\u2139 ")+t}formatWarning(t){return d.warning("\u26A0 ")+t}formatCommand(t){return d.dim(t)}formatPrompt(t){return d.bold(d.plan(`afk (${t})`))+d.dim(" \u203A ")}formatModelInfo(t,n,r){return d.dim(`Model: ${Fn.white(t)} | Max tokens: ${Fn.white(n)} | Temperature: ${Fn.white(r)}`)}separator(t="\u2500",n=50){return d.dim(t.repeat(n))}formatHelp(t){let n=[];for(let r of t){n.push(d.heading(`
1397
+ ${r.title}`)),n.push(this.separator());for(let o of r.items)n.push(` ${o}`)}return n.join(`
1398
+ `)}formatStreaming(t){return this.useColors,t}},BT=new Xr;import Yt from"chalk";var _m=new Set(["Read","Glob","Grep","NotebookRead","LS"]),$m=new Set(["Write","Edit","NotebookEdit","MultiEdit"]),Om=new Set(["Bash","BashOutput","KillBash"]),Ve=new Set(["Agent","Task"]),Dm=new Set(["Skill"]),Lm=new Set(["WebFetch","WebSearch"]),Fm=new Set(["TaskCreate","TaskUpdate","TaskList","TaskGet","TaskOutput","TaskStop","EnterPlanMode","ExitPlanMode","ToolSearch"]);function Zr(e){return e.startsWith("mcp__")?"mcp":_m.has(e)?"read":$m.has(e)?"write":Om.has(e)?"shell":Ve.has(e)?"subagent":Dm.has(e)?"skill":Lm.has(e)?"web":Fm.has(e)?"planning":"other"}var Um={read:d.user,write:Yt.hex("#E8A33D"),shell:Yt.hex("#A8E060"),subagent:d.plan,skill:Yt.hex("#9B59B6"),mcp:Yt.hex("#E67E4C"),web:Yt.hex("#7FCDC0"),planning:d.meta,other:d.info},Nm={read:"\u25CF",write:"\u270E",shell:"$",subagent:"\u2192",skill:"\u25C6",mcp:"\u22A1",web:"\u2316",planning:"\u25B1",other:"\u25CF"};function jm(e){return{color:Um[e],glyph:Nm[e]}}function kt(e){return jm(Zr(e))}function da(e){let{description:t,summary:n,lastToolName:r,totalTokens:o,toolUses:s,durationMs:a}=e,i=[];if(r){let{color:c,glyph:u}=kt(r);i.push(`via ${c(`${u} ${r}`)}`)}s&&i.push(`${s} tool${s===1?"":"s"}`),o&&i.push(`${O(o)} tok`),a&&i.push(he(a));let l=i.length>0?` (${i.join(" \xB7 ")})`:"";return n?[d.dim(` \u25E6 ${t}`),d.dim(` ${n}${l}`)]:[d.dim(` \u25E6 ${t}${l}`)]}function Un(e){let t=e.status==="succeeded"?"\u2713":e.status==="failed"?"\u2717":"\u2298",n=e.agentType??e.subagentId,r=[t,n];return e.durationMs!==void 0&&r.push(`\xB7 ${he(e.durationMs)}`),d.dim(` ${r.join(" ")}`)}function Bm(e){if(typeof e!="object"||e===null)throw new Error("Skill tool input must be an object");let t=e,n=t.name;if(typeof n!="string"||n.trim().length===0)throw new Error('Skill tool input must have a non-empty "name" field');let r,o=t.arguments;if(o!==void 0){if(typeof o!="string")throw new Error('Skill tool "arguments" must be a string');r=o}return{name:n.trim(),arguments:r}}var Ye=class{constructor(t){this.ctx=t}ctx;pluginBodies=null;async execute(t){if(t.signal.aborted)return{content:"Skill tool call aborted",isError:!0};let n=this.ctx.depth??0,r=this.ctx.maxDepth??qt;if(n>=r)return{content:`Skill tool not available at nesting depth ${n} (max ${r})`,isError:!0};let o;try{o=Bm(t.input)}catch(l){return{content:`Skill tool input validation failed: ${l instanceof Error?l.message:String(l)}`,isError:!0}}try{let l=oe(o.name);return await this.executeRegistrySkill(l,o.arguments,t.signal)}catch{}let s=this.getPluginSkillBody(o.name);if(s)return await this.executePluginSkill(o.name,s,o.arguments,t.signal);let i=Kt(this.ctx.pluginConfigs).map(l=>l.name).join(", ");return{content:`Skill "${o.name}" not found. Available skills: ${i||"(none)"}`,isError:!0}}async executeRegistrySkill(t,n,r){if(r.aborted)return{content:"Skill call aborted",isError:!0};if(t.context==="fork")return this.executeForkedRegistrySkill(t,n,r);try{let o=await t.handler(n&&n.length>0?n:void 0,this.ctx.parentSession);return{content:typeof o=="string"?o:o!=null?JSON.stringify(o):"Skill completed successfully."}}catch(o){return{content:`Skill execution error: ${o instanceof Error?o.message:String(o)}`,isError:!0}}}async executeForkedRegistrySkill(t,n,r){if(r.aborted)return{content:"Skill call aborted",isError:!0};let o;try{if(o=G(t.name)["system.md"],!o)return{content:`Skill "${t.name}" has context: "fork" but no prompts/system.md found`,isError:!0}}catch(a){return{content:`Failed to load skill prompts: ${a instanceof Error?a.message:String(a)}`,isError:!0}}let s=new _({parentAbortSignal:r});try{let a=await s.forkSubagent({parent:this.ctx.parentSession,config:{model:t.model??this.ctx.defaultSubagentModel??this.ctx.defaultModel??"sonnet",systemPrompt:o},idPrefix:`skill-fork-${t.name}`}),i=n&&n.length>0?n:"Run the skill.",l=await a.runToResult(i);return l.status==="succeeded"&&l.message?{content:l.message.content}:{content:l.error?.message??"Forked skill failed with no output",isError:!0}}catch(a){return{content:`Forked skill execution error: ${a instanceof Error?a.message:String(a)}`,isError:!0}}finally{await s.teardownAll()}}async executePluginSkill(t,n,r,o){if(o.aborted)return{content:"Skill call aborted",isError:!0};let s=new _({parentAbortSignal:o});try{let a=await s.forkSubagent({parent:this.ctx.parentSession,config:{model:this.ctx.defaultSubagentModel??this.ctx.defaultModel??"sonnet",systemPrompt:n},idPrefix:`skill-${t}`}),i=r&&r.length>0?r:"Run the skill.",l=await a.runToResult(i);return l.status==="succeeded"&&l.message?{content:l.message.content}:{content:l.error?.message??"Plugin skill failed with no output",isError:!0}}catch(a){return{content:`Plugin skill execution error: ${a instanceof Error?a.message:String(a)}`,isError:!0}}finally{await s.teardownAll()}}getPluginSkillBody(t){return this.pluginBodies||(this.pluginBodies=Ii(this.ctx.pluginConfigs)),this.pluginBodies.get(t)}};var qt=3;function eo(e){return{sessionId:void 0,getInputStreamRef:()=>({pushUserMessage:()=>{}}),abortSignal:e}}var Hm=[...Be,"agent","skill"];function Nn(){return({childExecutor:e,childSkillExecutor:t})=>new ge({permissions:{allowedTools:Hm},subagentExecutor:e,skillExecutor:t})}function jn(e){return(t,n,r)=>new Ye({parentSession:eo(r),defaultModel:e,depth:t,maxDepth:n})}function Wm(e){if(typeof e!="object"||e===null)throw new Error("Agent tool input must be an object");let t=e,n=t.prompt;if(typeof n!="string")throw new Error('Agent tool input must have a "prompt" field of type string');if(n.trim().length===0)throw new Error("Agent tool prompt cannot be empty");let r,o=t.model;if(o!==void 0){if(typeof o!="string")throw new Error("Agent tool model must be a string");r=o}let s=10,a=t.max_turns;if(a!==void 0){if(typeof a!="number")throw new Error("Agent tool max_turns must be a number");s=Math.max(1,Math.min(50,Math.floor(a)))}let i="agent-tool",l=t.id_prefix;if(l!==void 0){if(typeof l!="string")throw new Error("Agent tool id_prefix must be a string");i=l}return{prompt:n,model:r,max_turns:s,id_prefix:i}}var bt=class e{constructor(t){this.ctx=t}ctx;async execute(t){if(t.signal.aborted)return{content:"Agent tool call aborted",isError:!0};let n;try{n=Wm(t.input)}catch(c){return{content:`Agent tool input validation failed: ${c instanceof Error?c.message:String(c)}`,isError:!0}}let r=this.ctx.depth??0,o=this.ctx.maxDepth??qt,s,a={model:n.model??this.ctx.defaultSubagentModel??"sonnet",apiKey:this.ctx.defaultConfig.apiKey,systemPrompt:this.ctx.defaultConfig.systemPrompt,maxTurns:n.max_turns};if(this.ctx.childProviderFactory&&r<o){s=new _({parentAbortSignal:t.signal});let c=new e({subagentManager:s,parentSession:eo(t.signal),defaultConfig:this.ctx.defaultConfig,defaultSubagentModel:this.ctx.defaultSubagentModel,childProviderFactory:this.ctx.childProviderFactory,childSkillExecutorFactory:this.ctx.childSkillExecutorFactory,depth:r+1,maxDepth:o}),u=this.ctx.childSkillExecutorFactory?this.ctx.childSkillExecutorFactory(r+1,o,t.signal):void 0;a.provider=this.ctx.childProviderFactory({childExecutor:c,childSkillExecutor:u})}let i;try{i=await this.ctx.subagentManager.forkSubagent({parent:this.ctx.parentSession,config:a,idPrefix:n.id_prefix})}catch(c){return{content:`Failed to fork subagent: ${c instanceof Error?c.message:String(c)}`,isError:!0}}let l=()=>{i.cancel()};t.signal.addEventListener("abort",l,{once:!0});try{let c=await i.runToResult(n.prompt);return c.status==="succeeded"&&c.message?{content:c.message.content}:{content:c.error?.message??"Subagent failed with no output",isError:!0}}finally{t.signal.removeEventListener("abort",l),await s?.teardownAll(),await i.teardown()}}};function pa(e){e.command("chat").description("Send a message to the agent").argument("<message>","Message to send").option("-m, --model <model>","Model to use. Short aliases: opus|opus_1m|sonnet|sonnet_1m|haiku. Any other value (e.g. `auto` for cursor-api-proxy, or a full `claude-*` ID) passes through to the SDK/proxy untouched.",Ce()).option("-s, --stream","Stream the response",!1).option("-f, --format <format>","Output format (text|json)","text").option("--max-turns <number>","Maximum conversation turns","10").option("--thinking <mode>","Thinking mode: 'adaptive' | 'disabled' | 'enabled:<N>'","adaptive").option("--effort <level>","Effort level: low|medium|high|xhigh|max").option("--max-budget-usd <usd>","Hard session cost ceiling in USD. Env: AFK_MAX_BUDGET_USD").option("--task-budget <tokens>","Soft per-task token budget. Env: AFK_TASK_BUDGET").option("--max-output-tokens <n|max>","Per-response output cap ('max' = model ceiling). Env: AFK_MAX_OUTPUT_TOKENS").option("--provider <name>","Provider to use: anthropic|anthropic-direct|openai-codex. Default: auto-selected by model").action(async(t,n)=>{let r=Km("Initializing agent...").start(),o=null;try{let s,a,i,l,c,u;try{s=He(n.thinking)??dt(),a=We(n.effort)??pt(),i=mt(n.maxBudgetUsd)??Ur(),l=mt(n.taskBudget)??Nr(),c=ft(n.maxOutputTokens)??Ht(),u=void 0}catch(E){r.fail("Invalid options"),console.error(Jt.red(E instanceof Error?E.message:String(E))),process.exit(1)}let p=N(),m=Cn()??Pn(),g=ct().autoRouting?.chat??!1,y=Dn(m,g),h,b=new _({}),v=Nn(),w={get sessionId(){return h?.sessionId},getInputStreamRef(){return h?.getInputStreamRef?.()??{pushUserMessage:()=>{}}},get abortSignal(){return h?.abortSignal??new AbortController().signal}},P=new bt({subagentManager:b,parentSession:w,defaultConfig:{apiKey:p,systemPrompt:m},defaultSubagentModel:ut(),childProviderFactory:v,childSkillExecutorFactory:jn(n.model)}),T=new Ye({parentSession:w,defaultModel:n.model,defaultSubagentModel:ut()});u=In(n.provider,{subagentExecutor:P,skillExecutor:T})??new ge({permissions:{allowedTools:[...Be,"agent","skill"]},subagentExecutor:P,skillExecutor:T}),o=new ue({model:n.model,apiKey:p,maxTurns:parseInt(n.maxTurns,10),hookRegistry:yt(E=>{console.log(Un(E))}),...y!==void 0?{systemPrompt:y}:{},...s!==void 0?{thinking:s}:{},...a!==void 0?{effort:a}:{},...i!==void 0?{maxBudgetUsd:i}:{},...l!==void 0?{taskBudget:l}:{},...c!==void 0?{maxOutputTokens:c}:{},provider:u}),h=o,r.text="Sending message...";let L=await o.sendMessage(t,{stream:n.stream});if(r.succeed("Response received"),n.format==="json")console.log(JSON.stringify({success:!0,model:n.model,message:L.content,timestamp:L.timestamp},null,2));else{console.log(Jt.cyan(`
1399
+ \u{1F916} Claude:`)),console.log(ze(L.content));let E=o.getLastResponseMetadata();if(E){let S=[];E.durationMs&&S.push(he(E.durationMs)),E.totalCostUsd!==void 0&&S.push(pe(E.totalCostUsd));let R=Number(E.usage?.input_tokens??0),k=Number(E.usage?.output_tokens??0);R+k>0&&S.push(O(R+k)+" tokens"),S.length>0&&console.log(Jt.dim(" \xB7 "+S.join(" \xB7 ")))}console.log("")}}catch(s){r.fail("Failed to send message"),console.error(Jt.red(s instanceof Error?s.message:"Unknown error")),s instanceof Error&&s.stack&&console.error(Jt.gray(s.stack)),process.exit(1)}finally{o&&await o.close()}})}import Zh from"ora";function V(){let e=process.stdout.columns;return typeof e=="number"&&e>0?e:80}var Hn=new Set,Bn=!1,rt=null;function Gm(){for(let e of Hn)try{e()}catch{}}function zm(){rt!==null&&clearTimeout(rt),rt=setTimeout(()=>{rt=null,Gm()},150)}function ma(){zm()}function Vm(e){return Hn.add(e),Bn||(process.stdout.on("resize",ma),Bn=!0),()=>{Hn.delete(e),Hn.size===0&&(Bn&&(process.stdout.off("resize",ma),Bn=!1),rt!==null&&(clearTimeout(rt),rt=null))}}var wt={subscribe:Vm};function Wn(){return Math.max(22,V()-6)}function fa(e,t){return Ge(e,t)}var Ym={ok:d.success("\u25CF"),warn:d.warning("\u25CF"),error:d.error("\u25CF"),info:d.info("\u25C6")};function ga(e,t){let o=t.reduce((w,P)=>Math.max(w,U(P.label)),0),s=t.reduce((w,P)=>Math.max(w,U(P.value)),0),a=o+4+2+s,i=Math.min(V()-4,100),l=Math.max(44,U(e),a,i);l=Math.min(l,Wn());let c=l+4,u=d.dim,p=u("\u256D"+"\u2500".repeat(c)+"\u256E"),m=u("\u251C"+"\u2500".repeat(c)+"\u2524"),f=u("\u2570"+"\u2500".repeat(c)+"\u256F"),g=u("\u2502"),h=Q(e,l).split(`
1400
+ `).map(w=>g+" "+Oe(w,l)+" "+g),b=Math.max(1,l-o-4-2),v=t.map(w=>{let P=w.kind?Ym[w.kind]+" ":" ",T=d.dim(Oe(fa(w.label,o),o)),L=" ".repeat(4),E=fa(w.value,b),S=Oe(E,b),R=T+L+P+S;return g+" "+R+" "+g});return[p,...h,m,...v,f].join(`
1401
+ `)}function ha(e){let t="Agent AFK",n=" \xB7 ",r=d.bold(t)+d.dim(n)+e.mode,o=t+n+e.mode,s=Math.min(V()-4,120),a=Math.max(54,U(o)+4,s);a=Math.min(a,Wn());let i=a+4,l=d.dim,c=l("\u256D"+"\u2500".repeat(i)+"\u256E"),p=Q(r,a).split(`
1402
+ `).map(g=>l("\u2502")+" "+Oe(g,a)+" "+l("\u2502")),m=l("\u2570"+"\u2500".repeat(i)+"\u256F"),f=[c,...p,m];return e.metaLine!==void 0&&f.push(...Q(d.dim(" "+e.metaLine),V()).split(`
1403
+ `)),e.hintLine!==void 0&&f.push(...Q(d.dim(" "+e.hintLine),V()).split(`
1404
+ `)),f.join(`
1405
+ `)}function Qt(e,t){let n=Math.max(40,U(e),U(t??""))+4,r=Math.min(n,Math.min(V()-4,100));r=Math.min(r,Wn());let o=d.error,s=d.bold(d.error(" Error ")),i="\u2500".repeat(r+4-1-U(" Error ")-1),l=o("\u256D\u2500")+s+o(i+"\u256E"),c=o("\u2570"+"\u2500".repeat(r+4)+"\u256F"),u=o("\u2502"),p=Q(e,r).split(`
1406
+ `),m=[l];for(let f of p)m.push(u+" "+Oe(f,r)+" "+u);if(t!==void 0){let f=Q(d.dim(t),r).split(`
1407
+ `);for(let g of f)m.push(u+" "+Oe(g,r)+" "+u)}return m.push(c),m.join(`
1408
+ `)}var qm={plan:d.plan,status:d.info,checkpoint:d.success,diagnosis:d.warning},Jm={plan:"PLAN",status:"STATUS",checkpoint:"\u2705 CHECKPOINT",diagnosis:"DIAGNOSIS"};function vt(e){let t=Array.isArray(e.body)?e.body:e.body.split(`
1409
+ `);if(e.kind==="user")return Qm(t);let n=e.title??Jm[e.kind];return Xm(e.kind,n,t)}function Qm(e){let t=Math.max(20,V()-4),n=[];for(let o of e)n.push(...Q(o,t).split(`
1410
+ `));let r=d.user("\u2502");return n.map(o=>r+" "+o).join(`
1411
+ `)}function Xm(e,t,n){let r=qm[e],o=` ${t} `,s=r.bold(o),a=Math.max(U(t)+4,...n.map(g=>U(g))),i=Math.max(40,a)+4,l=Math.min(i,Math.min(V()-4,100));l=Math.min(l,Wn());let c="\u2500".repeat(l+4-1-U(o)-1),u=r("\u256D\u2500")+s+r(c+"\u256E"),p=r("\u2570"+"\u2500".repeat(l+4)+"\u256F"),m=r("\u2502"),f=[u];for(let g of n){let y=Q(g,l).split(`
1412
+ `);for(let h of y)f.push(m+" "+Oe(h,l)+" "+m)}return f.push(p),f.join(`
1413
+ `)}function Z(e){let t=Math.min(V(),120);if(e===void 0)return d.dim("\u2500".repeat(t));let n=d.dim("\u2500\u2500")+" "+d.bold(e)+" ",r="\u2500\u2500 "+e+" ",o=Math.max(0,t-U(r));return n+d.dim("\u2500".repeat(o))}var Kn=new Set;function Xt(e){return Kn.add(e),()=>{Kn.delete(e)}}async function ya(){await Promise.all([...Kn].map(e=>e())),Kn.clear()}import{readFileSync as Zm,writeFileSync as ef,existsSync as to,mkdirSync as tf,readdirSync as nf,statSync as rf}from"fs";import{join as ka,basename as of}from"path";function no(){return Go(),_t()}function ba(e){return ka(no(),`${e}.json`)}function Gn(e,t){let n=no();to(n)||tf(n,{recursive:!0});let r=t??e.sessionId??`session-${Date.now()}`,o={sessionId:e.sessionId,model:e.model,startedAt:e.sessionStartTime,savedAt:Date.now(),totalTurns:e.totalTurns,totalCostUsd:e.totalCostUsd,totalTokens:e.totalTokens,totalDurationMs:e.totalDurationMs,turns:e.turns},s=ba(r);return ef(s,JSON.stringify(o,null,2)),s}function ro(e){let t=e.includes("/")?e:ba(e);if(to(t))try{let n=Zm(t,"utf-8");return JSON.parse(n)}catch{return}}function wa(){let e=no();if(!to(e))return[];let t=[];for(let n of nf(e)){if(!n.endsWith(".json"))continue;let r=ka(e,n);try{if(!rf(r).isFile())continue;let s=ro(r);if(!s||typeof s.savedAt!="number"||typeof s.model!="string")continue;t.push({path:r,id:of(n,".json"),sessionId:s.sessionId,model:s.model,startedAt:s.startedAt,savedAt:s.savedAt,totalTurns:s.totalTurns,totalCostUsd:s.totalCostUsd})}catch{}}return t.sort((n,r)=>r.savedAt-n.savedAt),t}import*as $l from"node:readline";function va(e){let t=Math.max(0,Math.min(1,e.ratio)),n=t>.8?d.error:t>.5?d.warning:d.meta,r=20,o=Math.round(t*r),s=r-o,a="["+"\u2588".repeat(o)+"\u2591".repeat(s)+"]",i=Math.round(t*100)+"%",l="";e.used!==void 0&&e.limit!==void 0&&(l=O(e.used)+"/"+O(e.limit));let c=l?`${a} ${i} ${l}`:`${a} ${i}`,u=`${a} ${i}`,p=`ctx ${i}`,m=e.sparkline?d.meta(e.sparkline)+" ":"",f=e.sparkline?U(e.sparkline)+1:0,g=Math.max(0,e.width-f);if(U(c)<=g&&g>90)return m+n(c);if(U(u)<=g&&g>32)return m+n(u);if(U(p)<=g)return m+n(p);if(e.width>0){let y=m+n(p);return Ge(y,e.width)}return n(i)}var zn=class{stream;force;throttleMs;started=!1;lastRepaint=0;lastFields=null;resizeUnsub=null;lastPaintedRow=null;constructor(t={}){this.stream=t.stream??process.stdout,this.force=t.force??!1,this.throttleMs=t.throttleMs??100}get enabled(){return this.force||!!this.stream.isTTY}start(){if(this.started||!this.enabled)return;this.started=!0,this.lastRepaint=0;let t=this.currentRows();this.stream.write("\x1B[s"),this.writeScrollRegion(t),this.stream.write("\x1B[u"),this.resizeUnsub===null&&(this.resizeUnsub=wt.subscribe(()=>{this.onResize()}))}onResize(){if(!this.started||!this.enabled)return;let t=this.currentRows();this.stream.write("\x1B[s"),this.lastPaintedRow!==null&&this.lastPaintedRow!==this.paintRow(t)&&(this.stream.write(`\x1B[${this.lastPaintedRow};1H`),this.stream.write("\x1B[2K")),this.writeScrollRegion(t),this.stream.write("\x1B[u"),this.flush()}repaint(t){if(!this.enabled||!this.started){this.lastFields=t;return}let n=Date.now();if(n-this.lastRepaint<this.throttleMs){this.lastFields=t;return}this.lastRepaint=n,this.lastFields=t;let r=this.currentRows();this.stream.write("\x1B[s"),this.stream.write(`\x1B[${this.paintRow(r)};1H`),this.stream.write("\x1B[2K"),this.stream.write(this.formatLine(t)),this.stream.write("\x1B[u"),this.lastPaintedRow=this.paintRow(r)}flush(){this.lastRepaint=0,this.lastFields&&this.repaint(this.lastFields)}rearm(){if(!this.started||!this.enabled)return;let t=this.currentRows();this.stream.write("\x1B[s"),this.writeScrollRegion(t),this.stream.write("\x1B[u"),this.flush()}stop(){if(this.resizeUnsub!==null&&(this.resizeUnsub(),this.resizeUnsub=null),!this.started||!this.enabled){this.started=!1;return}let t=this.currentRows();this.stream.write("\x1B[s"),this.stream.write(`\x1B[${this.lastPaintedRow??this.paintRow(t)};1H`),this.stream.write("\x1B[2K"),this.stream.write("\x1B[r"),this.stream.write("\x1B[u"),this.started=!1,this.lastRepaint=0,this.lastPaintedRow=null}formatLine(t){let n=[],r=Math.max(4,(this.stream.columns??80)-2);if(n.push(d.brand(t.model)),t.planMode&&n.push(d.warning("\u25CF plan")),t.contextPct!==void 0){let s=va({ratio:t.contextPct,used:t.contextUsedTokens,limit:t.contextLimit,sparkline:t.contextSparkline,width:r});n.push(s)}t.cost!==void 0&&n.push(d.meta(`$${t.cost.toFixed(2)}`)),t.tokens!==void 0&&n.push(d.meta(`${sf(t.tokens)} tok`));let o=n.join(d.dim(" \xB7 "));return Ge(o,r)}currentRows(){let t=this.stream.rows;return typeof t=="number"&&t>0?t:24}paintRow(t){return t>1?t:1}writeScrollRegion(t){if(t>1){this.stream.write(`\x1B[1;${t-1}r`);return}this.stream.write("\x1B[r")}};function sf(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}k`:`${e}`}var we=new Map,St=new Map;function se(e){if(we.has(e.name))throw new Error(`Slash command already registered: ${e.name}`);we.set(e.name,e);for(let t of e.aliases??[]){if(St.has(t)||we.has(t))throw new Error(`Slash alias collides: ${t}`);St.set(t,e.name)}}function qe(e){if(we.has(e.name)){for(let[t,n]of St.entries())n===e.name&&St.delete(t);we.delete(e.name)}se(e)}function Sa(){we.clear(),St.clear()}function Je(){return[...we.values()].sort((e,t)=>e.name.localeCompare(t.name))}function af(e){if(we.has(e))return we.get(e);let t=St.get(e);return t?we.get(t):void 0}function lf(e,t){let n=Array.from({length:e.length+1},()=>new Array(t.length+1).fill(0));for(let r=0;r<=e.length;r++)n[r][0]=r;for(let r=0;r<=t.length;r++)n[0][r]=r;for(let r=1;r<=e.length;r++)for(let o=1;o<=t.length;o++){let s=e[r-1]===t[o-1]?0:1;n[r][o]=Math.min(n[r-1][o]+1,n[r][o-1]+1,n[r-1][o-1]+s)}return n[e.length][t.length]}function cf(e,t=3){let n;for(let r of we.keys()){let o=lf(e,r);o<=t&&(n===void 0||o<n.dist)&&(n={name:r,dist:o})}return n?.name}function uf(e){let t=e.trim();if(!t.startsWith("/"))return null;let n=t.indexOf(" ");return n===-1?{name:t,args:""}:{name:t.slice(0,n),args:t.slice(n+1).trim()}}async function xa(e,t){let n=uf(e);if(n===null)return{handled:!1};let r=af(n.name);if(!r){let s=cf(n.name);return s?t.out.warn(`Unknown command: ${n.name} (did you mean ${s}?)`):t.out.warn(`Unknown command: ${n.name} (type /help for commands)`),{handled:!0,result:"continue"}}let o=await r.handler(t,n.args);return o==="forward"?{handled:!1}:{handled:!0,result:o}}import mf from"ora";function Ta(e){return{totalTurns:0,totalCostUsd:0,totalTokens:0,totalDurationMs:0,sessionStartTime:Date.now(),turnCosts:[],turnTokens:[],turns:[],model:e,planMode:!1}}function Ea(e){e.totalTurns=0,e.totalCostUsd=0,e.totalTokens=0,e.totalDurationMs=0,e.sessionStartTime=Date.now(),e.turnCosts.length=0,e.turnTokens.length=0,e.turns.length=0,delete e.sessionId}function Pa(e,t,n,r){let o=r?.totalCostUsd??0,s=r?.durationMs??0,a=Number(r?.usage?.input_tokens??0),i=Number(r?.usage?.output_tokens??0),l=a,c=i,u=Number(r?.usage?.cache_read_input_tokens??0)+Number(r?.usage?.cache_creation_input_tokens??0),p=r?.usage?.iterations;if(Array.isArray(p)&&p.length>0){let f=p[p.length-1];if(f&&typeof f=="object"){let g=f;l=Number(g.input_tokens??0),c=Number(g.output_tokens??0),u=Number(g.cache_read_input_tokens??0)+Number(g.cache_creation_input_tokens??0)}}e.totalTurns+=1,e.totalCostUsd+=o,e.totalDurationMs+=s,e.totalTokens+=a+i,e.turnCosts.push(o),e.turnTokens.push({input:l,output:c,cache:u}),r?.sessionId&&!e.sessionId&&(e.sessionId=String(r.sessionId));let m={user:t,assistant:n,timestamp:Date.now(),costUsd:o,durationMs:s,inputTokens:a,outputTokens:i};return e.turns.push(m),m}var oo={opus:2e5,opus_1m:1e6,sonnet:2e5,sonnet_1m:1e6,haiku:2e5},pf=2e5;function ot(e){return oo[e]??pf}function Ca(e,t=5){if(e.length===0)return"";let n=e.slice(-t),r=["\u2581","\u2582","\u2583","\u2584","\u2585","\u2586","\u2587","\u2588"];return n.map(o=>{let s=Math.max(0,Math.min(1,o)),a=Math.min(7,Math.floor(s*8));return r[a]}).join("")}var Vn={stream:process.stdout,hideCursor:!1,discardStdin:!1};function so(e,t){if(t?.getRatio()!==void 0)return t.getRatio();let n=e.turnTokens[e.turnTokens.length-1];if(!n)return 0;let r=n.input+n.output+n.cache;return Math.min(1,r/ot(e.model))}function io(e,t){let n=so(e,t),r=ot(e.model),o,s=t?.getDetail();if(s!==void 0)o=s.used;else{let i=e.turnTokens[e.turnTokens.length-1];i&&(o=i.input+i.output+i.cache)}let a;if(e.turnTokens.length>=2){let i=e.turnTokens.map(c=>(c.input+c.output+c.cache)/r),l=Ca(i,5);l.length>0&&(a=l)}return{model:e.model,cost:e.totalCostUsd,tokens:e.totalTokens,contextPct:n,contextLimit:r,contextUsedTokens:o,contextSparkline:a,planMode:e.planMode}}var ff={name:"/exit",aliases:["/quit"],summary:"Exit the session",async handler(){return"exit"}},gf={name:"/clear",summary:"Clear conversation history",async handler(e){try{await e.session.reset(),e.ui.clearScreen(),Ea(e.stats),e.out.success("Conversation history cleared.")}catch(t){e.out.error(t instanceof Error?t.message:"Unknown error")}return"continue"}},hf={name:"/compact",summary:"Compact history (summarize older messages)",async handler(e){let t=mf({text:d.meta("Summarizing earlier turns..."),...Vn}).start();try{let n=await e.session.compact();if(t.stop(),n.compacted){let r=n.tokensSavedEstimate?` (~${n.tokensSavedEstimate} input tokens saved)`:"";e.out.success(`Compacted ${n.messagesBefore} \u2192 ${n.messagesAfter} messages${r}.`)}else{let r=n.reason??"unknown";r==="aborted"?e.out.info("Compaction cancelled."):r.startsWith("summarization-failed")?e.out.error(`Compaction failed: ${r}. History unchanged.`):e.out.info(`Nothing to compact (${r}).`)}}catch(n){t.stop(),e.out.error(n instanceof Error?n.message:"Unknown error")}return"continue"}},yf={name:"/help",summary:"Show this help",async handler(e){let t=Je(),n=t.reduce((r,o)=>Math.max(r,o.name.length),0)+2;e.out.line(),e.out.line(d.bold(d.brand("Commands"))),e.out.line(Z());for(let r of t){let o=r.usage??r.name,s=" ".repeat(Math.max(0,n-o.length));e.out.line(` ${d.warning(o)}${s} ${d.dim(r.summary)}`)}return e.out.line(),e.out.line(d.dim(" Tip: Ctrl+C interrupts a running turn; a second press exits.")),e.out.line(),"continue"}},Ia=[ff,gf,hf,yf];function ao(e,t=30){return!e||e.length===0?d.dim("(none)"):e.length<=t?e.join(", "):`${e.slice(0,t).join(", ")}, ${d.dim(`+${e.length-t} more`)}`}function ye(e,t){return` ${d.label(e.padEnd(16))} ${t}`}function Yn(e){let t=[];t.push(" "+Z("Session Debug")),e.sessionId&&t.push(ye("session",e.sessionId)),e.model&&t.push(ye("model",e.model)),e.permissionMode&&t.push(ye("permission",e.permissionMode)),e.cwd&&t.push(ye("cwd",e.cwd)),e.claudeCodeVersion&&t.push(ye("sdk",`v${e.claudeCodeVersion}`)),e.apiKeySource&&t.push(ye("api key",e.apiKeySource)),e.outputStyle&&t.push(ye("output style",e.outputStyle));let n=e.tools?.length??0;t.push(ye(`tools (${n})`,ao(e.tools)));let r=e.mcpServers??[],o=r.length?r.map(c=>`${c.name}[${c.status}]`).join(", "):d.dim("(none)");t.push(ye(`mcp (${r.length})`,o));let s=e.skills?.length??0;t.push(ye(`skills (${s})`,ao(e.skills)));let a=e.plugins?.length??0,i=a?(e.plugins??[]).map(c=>c.name).join(", "):d.dim("(none)");t.push(ye(`plugins (${a})`,i));let l=e.slashCommands?.length??0;return t.push(ye(`slash (${l})`,ao(e.slashCommands))),t.push(" "+Z()),t.join(`
1414
+ `)}var lo=["opus","opus_1m","sonnet","sonnet_1m","haiku"],kf={name:"/cost",summary:"Show total and per-turn cost",async handler(e){let{stats:t,out:n}=e;if(n.line(),n.line(d.bold("Session cost")),n.line(Z()),n.line(` total ${d.success(pe(t.totalCostUsd))}`),n.line(` turns ${d.meta(String(t.totalTurns))}`),t.totalTurns>0){let r=t.totalCostUsd/t.totalTurns;n.line(` avg/turn ${d.meta(pe(r))}`)}if(t.turnCosts.length>0){let r=t.turnCosts.slice(-5).map(pe).join(d.dim(" \xB7 "));n.line(` last 5 ${r}`)}return n.line(),"continue"}};function bf(e,t){let n=t.apiUsage,r=n?.input_tokens??0,o=n?.output_tokens??0,s=n?.cache_read_input_tokens??0,a=n?.cache_creation_input_tokens??0,i=r+o+s+a;e.line(),e.line(d.bold("Token usage")+d.dim(" (SDK breakdown)")),e.line(Z()),e.line(` total ${d.success(O(t.totalTokens))} of ${d.meta(O(t.maxTokens))} (${d.meta(`${Math.round(t.percentage*100)/100}%`)})`),t.autoCompactThreshold&&t.isAutoCompactEnabled&&e.line(` compact at ${d.meta(O(t.autoCompactThreshold))}`),e.line(),e.line(d.dim(" Last turn (API):")),e.line(` input ${d.meta(O(r))}`),e.line(` output ${d.meta(O(o))}`),e.line(` cache read ${d.meta(O(s))}`),e.line(` cache creat ${d.meta(O(a))}`),e.line(` total ${d.meta(O(i))}`);let l=t.categories??[];if(l.length>0){let m=[...l].sort((f,g)=>g.tokens-f.tokens).slice(0,5);e.line(),e.line(d.dim(" Top categories:"));for(let f of m)e.line(` ${d.warning(f.name.padEnd(18))} ${d.meta(O(f.tokens))}`)}let c=t.systemTools??[],u=t.mcpTools??[];if(c.length>0||u.length>0){e.line();let m=c.reduce((g,y)=>g+y.tokens,0),f=u.reduce((g,y)=>g+y.tokens,0);c.length>0&&e.line(d.dim(` system tools ${c.length} tools, ${O(m)} tokens`)),u.length>0&&e.line(d.dim(` MCP tools ${u.length} tools, ${O(f)} tokens`))}let p=t.agents??[];if(p.length>0){let m=p.reduce((f,g)=>f+g.tokens,0);e.line(d.dim(` agents ${p.length} loaded, ${O(m)} tokens`))}if(t.skills){let m=t.skills;e.line(d.dim(` skills ${m.includedSkills}/${m.totalSkills} included, ${O(m.tokens)} tokens`))}if(t.slashCommands){let m=t.slashCommands;e.line(d.dim(` slash cmds ${m.includedCommands}/${m.totalCommands} included, ${O(m.tokens)} tokens`))}e.line()}function wf(e,t){let n=t.turnTokens.reduce((c,u)=>c+u.input,0),r=t.turnTokens.reduce((c,u)=>c+u.output,0),o=t.turnTokens.reduce((c,u)=>c+u.cache,0),s=n+r,a=ot(t.model),i=n+r+o,l=Math.round(i/a*100);e.line(),e.line(d.bold("Token usage")+d.dim(" (local stats \u2014 SDK breakdown unavailable)")),e.line(Z()),e.line(` input ${d.meta(O(n))}`),e.line(` output ${d.meta(O(r))}`),e.line(` cache read ${d.meta(O(o))}`),e.line(` total ${d.success(O(s))}`),e.line(` context ${d.meta(`${l}% of ${O(a)} (${t.model})`)}`),e.line()}var vf={name:"/tokens",aliases:["/ctx"],summary:"Show token usage (SDK breakdown with local-stats fallback)",async handler(e){try{let t=await e.session.getContextUsage();bf(e.out,t)}catch{wf(e.out,e.stats)}return"continue"}},Sf={name:"/history",summary:"Show conversation history",async handler(e){let{stats:t,out:n}=e;return t.turns.length===0?(n.info("No turns yet in this session."),"continue"):(n.line(),n.line(d.bold(`Session history (${t.turns.length} turn${t.turns.length===1?"":"s"})`)),n.line(Z()),t.turns.forEach((r,o)=>{let s=d.meta(`#${o+1}`),a=r.user.length>100?r.user.slice(0,97)+"...":r.user,i=r.assistant.length>100?r.assistant.slice(0,97)+"...":r.assistant;n.line(` ${s} ${d.user("\u25B6")} ${a}`),n.line(` ${d.brand("\u25C6")} ${d.dim(i)}`)}),n.line(),"continue")}},xf={name:"/reset",summary:"Clear screen, history, and session stats",async handler(e){let{stats:t,session:n,ui:r,out:o}=e;try{await n.sendMessage("/clear")}catch{}return t.totalTurns=0,t.totalCostUsd=0,t.totalTokens=0,t.totalDurationMs=0,t.turnCosts.length=0,t.turnTokens.length=0,t.turns.length=0,t.sessionStartTime=Date.now(),r.clearScreen(),o.success("Session reset."),"continue"}},Tf={name:"/model",usage:"/model <opus|opus_1m|sonnet|sonnet_1m|haiku>",summary:"Switch the active model mid-session",async handler(e,t){let n=t.trim().toLowerCase();if(!n)return e.out.info(`Current model: ${d.brand(e.stats.model)}`),e.out.line(d.dim(` Valid: ${lo.join(", ")}`)),"continue";if(!lo.includes(n))return e.out.warn(`Unknown model: ${n}. Valid: ${lo.join(", ")}`),"continue";try{await e.session.setModel(n),e.stats.model=n,e.ui.repaintStatusLine(),e.out.success(`Model switched to ${d.brand(n)}`)}catch(r){e.out.error(`Failed to switch model: ${r instanceof Error?r.message:String(r)}`)}return"continue"}},Ef={name:"/tools",summary:"List tools available to the session",async handler(e){try{let n=(await e.session.waitForInitialization()).tools??[];if(n.length===0)return e.out.info("No tools reported by the session."),"continue";e.out.line(),e.out.line(d.bold(`Tools (${n.length})`)),e.out.line(Z());let r=3,o=Math.ceil(n.length/r),s=Math.max(...n.map(a=>a.length))+2;for(let a=0;a<o;a++){let i=[];for(let l=0;l<r;l++){let c=l*o+a;c<n.length&&i.push(n[c].padEnd(s))}e.out.line(" "+i.join(""))}e.out.line()}catch(t){e.out.error(`Could not read session tools: ${t instanceof Error?t.message:String(t)}`)}return"continue"}},Pf={name:"/mcp",summary:"List MCP servers connected to the session",async handler(e){try{let n=(await e.session.waitForInitialization()).mcpServers??[];if(n.length===0)return e.out.info("No MCP servers connected."),"continue";e.out.line(),e.out.line(d.bold(`MCP servers (${n.length})`)),e.out.line(Z());for(let r of n){let o=typeof r=="string"?r:r.name??JSON.stringify(r),s=typeof r=="object"&&r!==null&&"status"in r?String(r.status):"",a=s==="connected"?d.success("\u25CF"):d.warning("\u25CF");e.out.line(` ${a} ${o}${s?d.dim(` (${s})`):""}`)}e.out.line()}catch(t){e.out.error(`Could not read MCP servers: ${t instanceof Error?t.message:String(t)}`)}return"continue"}},Cf={name:"/limits",summary:"Show known per-model context-window limits",async handler(e){e.out.line(),e.out.line(d.bold("Context-window limits")),e.out.line(Z());for(let[t,n]of Object.entries(oo)){let r=t===e.stats.model?d.brand(" \u2190 active"):"";e.out.line(` ${d.warning(t.padEnd(12))} ${d.meta(O(n))}${r}`)}return e.out.line(),"continue"}},If={name:"/debug",summary:"Show SDK session metadata (tools, MCP, skills, plugins, etc.)",async handler(e){try{let t=await e.session.waitForInitialization();e.out.line(),e.out.line(Yn(t)),e.out.line()}catch(t){e.out.error(`Could not read session metadata: ${t instanceof Error?t.message:String(t)}`)}return"continue"}},Aa=[kf,vf,Sf,xf,Tf,Ef,Pf,Cf,If];var Ma={name:"/plan",usage:"/plan [on|off]",summary:"Toggle plan mode (read-only tools)",async handler(e,t){let n=t.trim().toLowerCase(),r=n==="on"?!0:n==="off"?!1:!e.stats.planMode;try{await e.session.setPermissionMode(r?"plan":"default"),e.stats.planMode=r,e.ui.repaintStatusLine(),r?e.out.success(d.warning("\u25CF plan mode ON")+d.dim(" \u2014 writes and commits are refused")):e.out.success(d.success("\u25CB plan mode OFF")+d.dim(" \u2014 default permissions restored"))}catch(o){e.out.error(`Could not toggle plan mode: ${o instanceof Error?o.message:String(o)}`)}return"continue"}};import{readFileSync as Af,writeFileSync as Mf,existsSync as Ra,mkdirSync as Rf}from"fs";import{join as _f}from"path";function _a(){return zo(),Er()}function $a(e){return _f(_a(),`${e}.json`)}function qn(e){let t=$a(e);if(!Ra(t))return{sessionId:e,items:[]};try{let n=Af(t,"utf-8"),r=JSON.parse(n);return Array.isArray(r.items)?r:{sessionId:e,items:[]}}catch{return{sessionId:e,items:[]}}}function Zt(e){let t=_a();Ra(t)||Rf(t,{recursive:!0}),Mf($a(e.sessionId),JSON.stringify(e,null,2))}function Oa(e,t){let r={id:e.items.reduce((o,s)=>Math.max(o,s.id),0)+1,text:t,done:!1,createdAt:Date.now()};return e.items.push(r),r}function Da(e,t){let n=e.items.find(r=>r.id===t);return n&&(n.done=!0),n}function La(e,t){let n=e.items.findIndex(r=>r.id===t);return n===-1?!1:(e.items.splice(n,1),!0)}function Fa(e){e.items.length=0}function Jn(e){if(e.items.length===0)return[];let t=[],n=Math.max(20,V());{let r=d.dim("\u250C\u2500 todos "),o=Math.max(0,Math.min(n-10,120));t.push(r+d.dim("\u2500".repeat(o)))}for(let r of e.items){let o=r.done?d.success("[x]"):d.dim("[ ]"),s=r.done?d.dim(r.text):r.text,i=` ${d.meta(`#${r.id}`)} ${o} `,l=Math.max(8,n-U(i)),c=Q(s,l).split(`
1415
+ `);t.push(i+(c[0]??""));let u=" ".repeat(U(i));for(let p of c.slice(1))t.push(u+p)}{let r=Math.max(0,Math.min(n-1,120));t.push(d.dim("\u2514"+"\u2500".repeat(r)))}return t}function Ua(e){return e.items.length===0?"":e.items.map(t=>`${t.id}:${t.done?1:0}:${t.text}`).join(`
1416
+ `)}function Na(e){let t=e.stats.sessionId??"unbound";return qn(t)}function $f(e){let t=Na(e),n=Jn(t);if(n.length===0){e.out.info("No todos yet. Try /todo add buy milk");return}for(let r of n)e.out.line(r)}var ja={name:"/todo",usage:"/todo [add|done|rm|clear|list] ...",summary:"Manage this session's todo list",async handler(e,t){let n=t.trim();if(!n||n==="list")return $f(e),"continue";let[r,...o]=n.split(/\s+/),s=o.join(" "),a=Na(e);switch(r){case"add":{if(!s)return e.out.warn("Usage: /todo add <text>"),"continue";let i=Oa(a,s);return Zt(a),e.out.success(`Added ${d.meta(`#${i.id}`)} ${i.text}`),"continue"}case"done":{let i=parseInt(s,10);if(!Number.isFinite(i))return e.out.warn("Usage: /todo done <id>"),"continue";let l=Da(a,i);return l?(Zt(a),e.out.success(`Marked done ${d.meta(`#${i}`)} ${l.text}`)):e.out.warn(`No todo with id ${i}`),"continue"}case"rm":case"remove":{let i=parseInt(s,10);return Number.isFinite(i)?(La(a,i)?(Zt(a),e.out.success(`Removed ${d.meta(`#${i}`)}`)):e.out.warn(`No todo with id ${i}`),"continue"):(e.out.warn("Usage: /todo rm <id>"),"continue")}case"clear":return Fa(a),Zt(a),e.out.success("All todos cleared."),"continue";default:return e.out.warn(`Unknown subcommand: ${r}. Try /todo add, done, rm, clear, list.`),"continue"}}};var Ba={name:"/save",usage:"/save [name]",summary:"Save this session to disk (for /resume)",async handler(e,t){if(e.stats.totalTurns===0)return e.out.warn("Nothing to save \u2014 no turns in this session yet."),"continue";try{let n=t.trim()||void 0,r=Gn(e.stats,n);e.out.success(d.success("Saved")+d.dim(` ${r}`)),e.stats.sessionId&&e.out.line(d.dim(` Resume: afk interactive --resume ${e.stats.sessionId}`))}catch(n){e.out.error(`Could not save: ${n instanceof Error?n.message:String(n)}`)}return"continue"}};function Of(e){if(typeof e!="number"||!Number.isFinite(e))return" \u2014 ";let t=new Date(e);return Number.isNaN(t.getTime())?" \u2014 ":t.toISOString().replace("T"," ").slice(0,16)}var Ha={name:"/resume",usage:"/resume [id]",summary:"List saved sessions (resume happens at launch via --resume)",async handler(e,t){let n=t.trim();if(n){let o=ro(n);return o?(e.out.line(),e.out.line(d.bold(`Session ${n}`)),e.out.line(Z()),e.out.line(` model ${d.brand(o.model)}`),e.out.line(` turns ${d.meta(String(o.totalTurns))}`),e.out.line(` cost ${d.meta(pe(o.totalCostUsd))}`),e.out.line(` sdk id ${d.meta(o.sessionId??"\u2014")}`),e.out.line(),o.sessionId?(e.out.line(d.dim(" To resume:")),e.out.line(d.brand(` afk interactive --resume ${o.sessionId}`))):e.out.line(d.dim(" No SDK session id recorded; resume not available.")),e.out.line(),"continue"):(e.out.warn(`No saved session: ${n}`),"continue")}let r=wa();if(r.length===0)return e.out.info("No saved sessions found. Use /save first."),"continue";e.out.line(),e.out.line(d.bold(`Saved sessions (${r.length})`)),e.out.line(Z());for(let o of r.slice(0,20)){let s=Of(o.savedAt),a=d.brand(o.model.padEnd(7)),i=d.meta(`${o.totalTurns} turn${o.totalTurns===1?"":"s"}`.padEnd(9)),l=d.meta(pe(o.totalCostUsd).padStart(8)),c=d.warning(o.id);e.out.line(` ${s} ${a} ${i} ${l} ${c}`)}return e.out.line(),e.out.line(d.dim(" Resume with: /resume <id> (then re-launch with --resume <id>)")),e.out.line(),"continue"}};import{readdirSync as Ff,readFileSync as Uf,statSync as Ka}from"fs";import{join as Nf}from"path";var co=[],Df={name:"/agents",summary:"List plugin-provided subagents (loads after session init)",async handler(e){return e.out.line(),e.out.line(d.dim(" Plugin agents are still loading \u2014 try again after the session is ready.")),e.out.line(),"continue"}};function Lf(e){return{name:"/agents",summary:"List Task-tool subagents loaded by the SDK (plugin + user + project)",async handler(t){if(t.out.line(),e.length===0)return t.out.line(d.dim(" No plugin agents loaded. Agents come from `agents:` entries in plugin.json or from ~/.afk/agents/.")),t.out.line(),"continue";t.out.line(d.bold("Plugin agents")+d.dim(` (${e.length} loaded)`)),t.out.line(d.dim("\u2500".repeat(60)));let n=e.reduce((r,o)=>Math.max(r,o.name.length),0)+2;for(let r of e){let o=d.warning(r.name.padEnd(n)),s=r.model?d.dim(`[${r.model}]`):"",a=r.description?d.dim(` ${r.description}`):"";t.out.line(` ${o} ${s}${a}`)}return t.out.line(),t.out.line(d.dim(" Agents are dispatched by the model via the Task tool \u2014 not user-invoked.")),t.out.line(),"continue"}}}async function uo(e){let t;try{t=await e.supportedAgents()}catch(n){return console.error(d.dim(" \u26A0 Plugin-agent discovery failed: ")+(n instanceof Error?n.message:String(n))),null}return co=t.map(n=>{let r={name:n.name,description:n.description};return n.model&&(r.model=n.model),r}),qe(Lf(co)),co.length}function Wa(){se(Df)}var jf=new Set(["/exit","/quit","/clear","/compact","/help"]),Qn={discovered:[],collisions:[],shadowedBareNames:new Set};function Xn(e){return e.includes(":")?e.split(":").pop():e}function Bf(e){let t=e??Me(),n=new Map;try{Ka(t)}catch{return n}let r=(o,s)=>{if(s>8)return;let a;try{a=Ff(o)}catch{return}for(let i of a){let l=Nf(o,i),c;try{c=Ka(l)}catch{continue}if(c.isDirectory()){r(l,s+1);continue}if(i!=="SKILL.md"||!c.isFile())continue;let u;try{u=Uf(l,"utf-8")}catch{continue}let p=l.split("/"),m=p[p.length-2];if(!m)continue;let f=Wt(u),g=f.frontmatterFlags&&f.frontmatterFlags.length>0?f.frontmatterFlags:Wr(f.body);if(g.length===0)continue;let y=n.get(m)??[],h=new Set([...y,...g]);n.set(m,Array.from(h).sort())}};return r(t,0),n}function Ga(e,t){let n=`/${e.name}`,r=e.argumentHint?`${n} ${e.argumentHint}`:void 0;return{name:n,summary:e.description,...r!==void 0?{usage:r}:{},...t&&t.length>0?{flags:t}:{},async handler(o,s){return"forward"}}}function Hf(e){let t=new Map,n=o=>{let s=Xn(o.slashName.replace(/^\//,"")),a=t.get(s);a?a.alts.push(o):t.set(s,{main:o,alts:[]})};for(let o of tt()){let s=oe(o),a=`/${o}`,i=s.argumentHint?`${a} ${s.argumentHint}`:a,l={slashName:a,display:i,description:s.description};s.origin==="user"&&(l.sourceLabel="user"),n(l)}let r=new Map(Qn.collisions.map(o=>[o.bare,o.altSlash]));for(let o of e){let s=Xn(o.name),i=r.get(s)??`/${o.name}`,l=o.argumentHint?`${i} ${o.argumentHint}`:i;n({slashName:i,display:l,description:o.description,sourceLabel:"plugin"})}return t}function Wf(e,t,n){let r=t.main,o=d.warning(r.display.padEnd(n)),s=r.sourceLabel?d.dim(`(${r.sourceLabel}) `):"";e.out.line(` ${o} ${s}${d.dim(r.description)}`);for(let a of t.alts){let i=d.warning(a.display.padEnd(Math.max(0,n-4))),l=a.sourceLabel?d.dim(`(${a.sourceLabel} alt) `):d.dim("(alt) ");e.out.line(` ${d.dim("\u2514")} ${i} ${l}${d.dim(a.description)}`)}}function za(e,t){let n=Hf(t),r=Array.from(n.values()).reduce((a,i)=>a+1+i.alts.length,0);if(e.out.line(),n.size===0){e.out.line(d.dim(" No skills available. Built-in skills should always load \u2014 check your install.")),e.out.line();return}e.out.line(d.bold("Skills")+d.dim(` (${r} loaded)`)),e.out.line(Z());let o=Array.from(n.keys()).sort(),s=o.reduce((a,i)=>{let l=n.get(i);return Math.max(a,l.main.display.length)},0)+2;for(let a of o)Wf(e,n.get(a),s);e.out.line(),e.out.line(d.dim(" Source: vendored (no badge), (user), (plugin). Shadowed entries listed under their winner.")),e.out.line()}var Kf={name:"/skills",aliases:["/builtin-skills"],summary:"List all skills available in this session \u2014 vendored, user, and plugin",async handler(e){return za(e,[]),"continue"}};function Gf(e){return{name:"/skills",aliases:["/builtin-skills"],summary:"List all skills available in this session \u2014 vendored, user, and plugin",async handler(t){return za(t,e),"continue"}}}async function Va(e){let t;try{t=await e.supportedCommands()}catch(i){return console.error(d.dim(" \u26A0 Plugin-skill discovery failed: ")+(i instanceof Error?i.message:String(i))),null}let n=t.map(i=>({name:i.name,description:i.description,...i.argumentHint?{argumentHint:i.argumentHint}:{}})),r=Bf(),o=new Set(tt().map(Xn)),s=[],a=new Set;for(let i of n){let l=`/${i.name}`;if(jf.has(l))continue;let c=Xn(i.name),u=r.get(c);if(o.has(c)){let p=i.name.includes(":")?i.name:`plugin:${i.name}`,m={...i,name:p};qe(Ga(m,u)),s.push({bare:c,altSlash:`/${p}`,altDescription:i.description}),a.add(c);continue}qe(Ga(i,u))}return Qn={discovered:n,collisions:s,shadowedBareNames:a},qe(Gf(n)),n.length}function Ya(){return Qn.collisions.length===0?[]:Qn.collisions.map(e=>d.dim(` /${e.bare}: vendored or user skill wins; plugin form ${e.altSlash} stays reachable.`))}async function qa(e){let[t,n]=await Promise.all([Va(e),uo(e)]);return{skillCount:t,agentCount:n}}var zf={name:"/reload-plugins",summary:"Reload plugin skills from disk and refresh the slash registry",async handler(e){e.out.line(),e.out.info("Reloading plugins\u2026");try{let r=e.session.getQuery();typeof r.reloadPlugins=="function"&&await r.reloadPlugins()}catch(r){e.out.warn(`Plugin reload failed: ${r instanceof Error?r.message:String(r)}`)}let[t,n]=await Promise.all([Va(e.session),uo(e.session)]);if(t===null&&n===null)e.out.error("Could not refresh plugin skills or agents.");else{let r=[];t!==null&&r.push(`${t} skill${t===1?"":"s"}`),n!==null&&r.push(`${n} agent${n===1?"":"s"}`),e.out.success(`Reloaded ${r.join(" + ")}.`)}return e.out.line(),"continue"}};function Ja(){se(Kf),se(zf)}import{emitKeypressEvents as Vf}from"readline";import{createLogUpdate as Yf}from"log-update";function po(e,t){return Number.isFinite(e)?Math.max(0,Math.min(t,Math.trunc(e))):0}function Zn(e,t){let n=po(t,e.buffer.length);return n===e.cursor?e:{buffer:e.buffer,cursor:n}}function er(e,t,n){let r=po(t.start,e.buffer.length),o=po(t.end,e.buffer.length),s=Math.min(r,o),a=Math.max(r,o);if(s===a&&n.length===0)return e;let i=e.buffer.slice(0,s)+n+e.buffer.slice(a),l=s+n.length;return i===e.buffer&&l===e.cursor?e:{buffer:i,cursor:l}}var Y={seed(e=""){return{buffer:e,cursor:e.length}},replaceRange:er,insert(e,t){return t.length===0?e:er(e,{start:e.cursor,end:e.cursor},t)},backspace(e){if(e.cursor===0)return e;let t=Qr(e.buffer,e.cursor);return er(e,{start:t,end:e.cursor},"")},deleteForward(e){if(e.cursor>=e.buffer.length)return e;let t=Vt(e.buffer,e.cursor);return er(e,{start:e.cursor,end:t},"")},moveLeft(e){return Zn(e,Qr(e.buffer,e.cursor))},moveRight(e){return Zn(e,Vt(e.buffer,e.cursor))},moveHome(e){return Zn(e,0)},moveEnd(e){return Zn(e,e.buffer.length)}};var Qa=["Stalking","Shadowing","Tailing","Casing","Sleuthing","Investigating","Deducing","Interrogating","Profiling","Canvassing","Prowling","Lurking","Scanning","Probing","Inspecting","Querying","Invoking","Parsing","Validating","Resolving","Compiling","Executing","Hunting","Sweeping","Tracing","Tracking","Triangulating","Decoding","Decrypting","Intercepting","Hacking","Bugging","Wiretapping","Dispatching","Deploying","Patching","Hooking","Unmasking","Cornering","Striking","Surveilling","Scouting"];function mo(){return Qa[Math.floor(Math.random()*Qa.length)]}var Xa=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],tr=class{stdout;stdin;onCancel;promptText;armed=!1;canceled=!1;wasRaw=!1;logUpdate=null;overlay="";input=Y.seed("");queued=!1;handleKeypress=null;resizeUnsub=null;spinner=null;spinnerInterval=null;constructor(t){this.stdout=t.stdout,this.stdin=t.stdin,this.onCancel=t.onCancel,this.promptText=t.promptText??" "+d.dim("\u23AF")+" "}isArmed(){return this.armed}async arm(){if(!this.armed&&!(!this.stdout.isTTY||!this.stdin.isTTY)){this.logUpdate||(this.logUpdate=Yf(this.stdout)),this.wasRaw=this.stdin.isRaw??!1;try{this.stdin.setRawMode(!0)}catch{this.logUpdate=null,this.wasRaw=!1;return}this.stdin.resume(),Vf(this.stdin),this.handleKeypress=(t,n)=>this.dispatchKey(t,n),this.stdin.on("keypress",this.handleKeypress),this.resizeUnsub=wt.subscribe(()=>{this.repaint()}),this.armed=!0,this.canceled=!1,this.repaint()}}disarm(){if(this.spinnerInterval&&(clearInterval(this.spinnerInterval),this.spinnerInterval=null),this.spinner=null,!this.armed){this.resetState();return}if(this.handleKeypress&&(this.stdin.removeListener("keypress",this.handleKeypress),this.handleKeypress=null),this.resizeUnsub&&(this.resizeUnsub(),this.resizeUnsub=null),this.logUpdate)try{this.logUpdate.clear()}catch{}if(this.stdout.isTTY&&this.stdin.isTTY)try{this.stdin.setRawMode(this.wasRaw)}catch{}this.armed=!1,this.resetState()}setOverlay(t){this.overlay=t,this.repaint()}setSpinner(t){if(!this.stdout.isTTY)return;if(!t.enabled){this.spinnerInterval&&(clearInterval(this.spinnerInterval),this.spinnerInterval=null),this.spinner&&(this.spinner=null,this.repaint());return}if(this.spinner)return;let n=t.rotateVerbEveryMs??3500;this.spinner={frameIndex:0,verb:mo(),nextVerbRotateAt:Date.now()+n},this.spinnerInterval=setInterval(()=>this.tickSpinner(n),80),this.repaint()}tickSpinner(t){if(!this.spinner)return;this.spinner.frameIndex=(this.spinner.frameIndex+1)%Xa.length;let n=Date.now();n>=this.spinner.nextVerbRotateAt&&(this.spinner.verb=mo(),this.spinner.nextVerbRotateAt=n+t),this.repaint()}commitAbove(t){if(!this.armed||!this.logUpdate){this.stdout.write(t+`
1417
+ `);return}this.logUpdate.clear(),this.stdout.write(t+`
1418
+ `),this.repaint()}getBuffer(){return{text:this.input.buffer,queued:this.queued}}renderInputLine(){let t=this.queued?" "+d.dim("[queued]"):"",n=this.input.buffer.slice(0,this.input.cursor),r=Vt(this.input.buffer,this.input.cursor),o=this.input.cursor<this.input.buffer.length?this.input.buffer.slice(this.input.cursor,r):" ",s=this.input.cursor<this.input.buffer.length?this.input.buffer.slice(r):"",a=this.input.buffer.length===0&&!this.queued?"":d.user.inverse(o);return this.promptText+n+a+s+t}repaint(){if(!this.armed||!this.logUpdate)return;let t=this.renderInputLine(),n=this.overlay?this.overlay.split(`
1419
+ `):[],r=this.spinner?d.meta(`${Xa[this.spinner.frameIndex]} ${this.spinner.verb}...`):null,o=Math.max(1,(this.stdout.rows??24)-1),s=(r?1:0)+1,a=Math.max(0,o-s),i=n.length>a?n.slice(-a):n,l=[];r&&l.push(r),l.push(...i),l.push(t),this.logUpdate(l.join(`
1420
+ `))}resetState(){this.overlay="",this.input=Y.seed(""),this.queued=!1,this.canceled=!1,this.resizeUnsub&&(this.resizeUnsub(),this.resizeUnsub=null)}applyEdit(t){return t===this.input?!1:(this.input=t,this.queued=!1,this.repaint(),!0)}dispatchKey(t,n){if(!this.armed)return;if(n?.name==="escape"||n?.ctrl&&n?.name==="c"){if(this.canceled)return;this.canceled=!0,this.onCancel&&this.onCancel();return}if(n?.name==="return"){this.input.buffer.length>0&&!this.queued&&(this.queued=!0,this.repaint());return}if(n?.name==="backspace"){let s=Y.backspace(this.input);s!==this.input?this.applyEdit(s):this.queued&&(this.queued=!1,this.repaint());return}if(n?.name==="left"){this.applyEdit(Y.moveLeft(this.input));return}if(n?.name==="right"){this.applyEdit(Y.moveRight(this.input));return}if(n?.name==="home"){this.applyEdit(Y.moveHome(this.input));return}if(n?.name==="end"){this.applyEdit(Y.moveEnd(this.input));return}if(n?.name==="delete"){this.applyEdit(Y.deleteForward(this.input));return}let r=["up","down","tab","pageup","pagedown"];if(n?.name&&r.includes(n.name)||n?.ctrl||n?.meta)return;let o=typeof t=="string"&&t.length===1&&t>=" "?t:typeof n?.sequence=="string"&&n.sequence.length===1&&n.sequence>=" "?n.sequence:null;o!==null&&this.applyEdit(Y.insert(this.input,o))}};var nr=3;function Za(e){switch(Zr(e)){case"read":return"Reading\u2026";case"write":return"Writing\u2026";case"web":return"Fetching\u2026";case"shell":return"Running\u2026";default:return"Running\u2026"}}function fo(e){return e.replace(/\/(?:[^/\s,)]+\/){2,}([^/\s,)]+)/g,"$1")}function rr(e){let t=/^([A-Za-z_][A-Za-z0-9_]*)(.*)$/s.exec(e);if(t){let n=t[1],r=fo(t[2]??""),{color:o,glyph:s}=kt(n);return o(s+" ")+o.bold(n)+d.toolArg(r)}return d.tool("\u25CF ")+d.toolArg(e)}function st(e,t,n=60){let r=e.isError?d.error:d.dim,o=t??process.env.HOME??"___NOHOME___";if(e.persistedPath){let a=e.persistedPath.startsWith(o)?"~"+e.persistedPath.slice(o.length):e.persistedPath;return r(`saved \u2192 ${a}`)}if(e.lineCount!==void 0&&e.lineCount>1)return r(`${e.lineCount} lines`);let s=e.content.length>n?e.content.slice(0,n-3)+"\u2026":e.content;return r(s)}function el(e,t){if(!e||!e.trim())return[];let n=d.dim("\u2502 "),r=Math.max(1,V()-t.length-2-2),o=[];for(let s of e.split(`
1421
+ `)){let a=Q(s,r);for(let i of a.split(`
1422
+ `))o.push(t+n+i)}return o}function go(e,t,n,r){let o=" ".repeat(n+1),s=e.filter(c=>c.kind==="text"),a=e.filter(c=>c.kind==="tool");for(let c of s)r.push(...el(c.text,o));let i=a.slice(0,nr),l=a.length-i.length;for(let c=0;c<i.length;c++){let u=i[c],p=c===i.length-1&&l<=0,m=d.dim(p?"\u2514 ":"\u251C "),f=t.get(u.toolUseId);Ve.has(u.toolName)&&f&&f.length>0?(r.push(o+m+u.prefix),go(f,t,n+1,r)):u.result?r.push(o+m+u.prefix+d.dim(" \u2014 ")+st(u.result)):(r.push(o+m+u.prefix),r.push(o+" "+d.dim(Za(u.toolName))))}l>0&&r.push(o+d.dim(`\u2026 +${l} tool uses`))}function tl(e,t,n,r){let o=" ".repeat(n+1),s=[],a=e.filter(u=>u.kind==="text"),i=e.filter(u=>u.kind==="tool");for(let u of a)s.push(...el(u.text,o));let l=i.slice(0,nr),c=i.length-l.length;for(let u=0;u<l.length;u++){let p=l[u],m=u===l.length-1&&c<=0,f=d.dim(m?"\u2514 ":"\u251C "),g=t.get(p.toolUseId);Ve.has(p.toolName)&&g&&g.length>0?(s.push(o+f+p.prefix),s.push(...tl(g,t,n+1,r))):p.result?s.push(o+f+p.prefix+d.dim(" \u2014 ")+st(p.result,r)):s.push(o+f+p.prefix)}return c>0&&s.push(o+d.dim(`\u2026 +${c} tool uses`)),s}function nl(e,t,n,r){let o=t.filter(u=>u.kind==="tool"),a=o.filter(u=>u.result).reduce((u,p)=>u+(p.result.lineCount??0),0),i=[];o.length>nr&&(i.push(`${o.length} tools`),a>0&&i.push(`${a} lines`));let l=i.length>0?" "+e.prefix+d.dim(" \u2014 "+i.join(" \xB7 ")):" "+e.prefix,c=tl(t,n,1,r);return e.agentResultSummary&&c.push(" "+d.dim("\u23BF "+e.agentResultSummary)),[l,...c].join(`
1423
+ `)}function ho(e,t,n){let r=[];for(let o of t){let s=e.get(o);if(s.length===1){let a=s[0];a.result?r.push(" "+a.prefix+d.dim(" \u2014 ")+st(a.result,n)):r.push(" "+a.prefix)}else r.push(qf(o,s,n))}return r}function qf(e,t,n){let{color:r,glyph:o}=kt(e),s=t.map(u=>fo(u.toolInput).trim()),a=r(o+" ")+r.bold(e)+d.dim(` \xD7${t.length}`)+" "+d.toolArg(s.join(", ")),i=t.filter(u=>u.result),l=i.filter(u=>u.result.isError);if(l.length>0){let u=i.length-l.length,m=i.filter(g=>!g.result.isError).map(g=>g.result.lineCount).filter(g=>g!==void 0).reduce((g,y)=>g+y,0),f=[];return m>0&&f.push(`${m} lines`),u>0&&f.push(`${u} ok`),f.push(d.error(`${l.length} error${l.length>1?"s":""}`))," "+a+d.dim(" \u2014 ")+f.join(d.dim(", "))}let c=i.map(u=>u.result?.lineCount).filter(u=>u!==void 0);if(c.length===i.length&&c.length>0){if(c.every(m=>m===c[0]))return" "+a+d.dim(` \u2014 ${c[0]} lines each`);let p=c.reduce((m,f)=>m+f,0);return" "+a+d.dim(` \u2014 ${p} lines total`)}if(i.length>0){let u=i.map(p=>st(p.result,n));return" "+a+d.dim(" \u2014 ")+u.join(d.dim(", "))}return" "+a}var en=class{entries=new Map;order=[];agentIdStack=[];addStart(t,n,r){let o=rr(n+r),s=this.agentIdStack.at(-1)??void 0,a={kind:"tool",toolUseId:t,toolName:n,toolInput:r,prefix:o,...s!==void 0?{agentContext:s}:{}};this.entries.set(t,a),this.order.push(t),Ve.has(n)&&this.agentIdStack.push(t)}addStartWithAgentContext(t,n,r,o){let s=rr(n+r),a={kind:"tool",toolUseId:t,toolName:n,toolInput:r,prefix:s,...o!==void 0?{agentContext:o}:{}};this.entries.set(t,a),this.order.push(t)}setAgentContext(t,n){let r=this.entries.get(t);r?.kind==="tool"&&(n===void 0?delete r.agentContext:r.agentContext=n)}setAgentResultSummary(t,n){let r=this.entries.get(t);r?.kind==="tool"&&(r.agentResultSummary=n)}addResult(t,n){let r=this.entries.get(t);r?.kind==="tool"&&(r.result=n),this.agentIdStack.at(-1)===t&&this.agentIdStack.pop()}upsertTextChild(t,n,r){let o=this.entries.get(t);if(o?.kind==="text"){o.text=r,o.agentContext=n;return}let s={kind:"text",toolUseId:t,text:r,agentContext:n};this.entries.set(t,s),this.order.push(t)}removeTextChildrenUnder(t){let n=[];for(let[r,o]of this.entries)o.kind==="text"&&o.agentContext===t&&n.push(r);for(let r of n)this.entries.delete(r);if(n.length>0){let r=new Set(n);this.order=this.order.filter(o=>!r.has(o))}}hasPending(){return this.entries.size>0}getOverlay(){let t=this.buildChildMap(),n=[];for(let r of this.order){let o=this.entries.get(r);if(!o||o.kind!=="tool"||o.agentContext)continue;let s=t.get(o.toolUseId);Ve.has(o.toolName)&&s&&s.length>0?(n.push(" "+o.prefix),go(s,t,1,n)):o.result?n.push(" "+o.prefix+d.dim(" \u2014 ")+st(o.result)):n.push(" "+o.prefix+d.dim(" \u2026"))}return n.join(`
1424
+ `)}flush(t){if(this.entries.size===0)return[];let n=this.buildChildMap(),r=[];for(let i of this.order){let l=this.entries.get(i);!l||l.kind!=="tool"||l.agentContext||r.push(i)}let o=[],s=new Map,a=[];for(let i of r){let l=this.entries.get(i);if(!l||l.kind!=="tool")continue;let c=n.get(l.toolUseId);Ve.has(l.toolName)&&c&&c.length>0?(o.push(...ho(s,a,t)),s.clear(),a.length=0,o.push(nl(l,c,n,t))):(s.has(l.toolName)||(s.set(l.toolName,[]),a.push(l.toolName)),s.get(l.toolName).push(l))}return o.push(...ho(s,a,t)),this.entries.clear(),this.order=[],this.agentIdStack=[],o}buildChildMap(){let t=new Map;for(let n of this.order){let r=this.entries.get(n);if(!r)continue;let o=(r.kind==="tool",r.agentContext);if(!o)continue;let s=t.get(o);s||(s=[],t.set(o,s)),s.push(r)}return t}};var or=class{buffer="";startedAt=null;hasEmitted=!1;push(t){this.hasEmitted||(this.buffer+=t,this.startedAt||(this.startedAt=Date.now()))}isActive(){return!this.hasEmitted}hasBufferedContent(){return this.buffer.trim().length>0}peek(){return this.buffer}consume(){return this.hasEmitted=!0,this.buffer}collapse(){if(this.hasEmitted||!this.startedAt)return null;this.hasEmitted=!0;let t=Date.now()-this.startedAt,n=t<1e3?`${t}ms`:`${(t/1e3).toFixed(1)}s`,r=Math.ceil(this.buffer.length/4);return` ${d.thinking("\u{1F4AD} thought for "+n+" ("+r+" tok)")}`}};function Jf(e){let t=Math.max(12,V()-4);return Q(d.thinking(e.trim()),t).split(`
1425
+ `).filter(n=>n.length>0)}function ol(e){let t=Jf(e),n=t.slice(-8),r=[` ${d.thinking("\u{1F4AD} thinking\u2026")}`];t.length>n.length&&r.push(` ${d.dim("\u2026")}`);for(let o of n)r.push(` ${o}`);return r.join(`
1426
+ `)}var yo="__main__";function sl(e){let t={startedAt:Date.now(),stats:{tokens:0,toolUses:0},contentBuffer:"",done:!1,errored:!1};return e!==void 0&&(t.agentType=e),t}function ko(e,t){return{type:"tool_result",toolUseId:"synthetic",content:e,isError:t}}function il(e){let t=["Done"],n=[];e.stats.toolUses&&n.push(`${e.stats.toolUses} tool${e.stats.toolUses===1?"":"s"}`),e.stats.tokens&&n.push(`${O(e.stats.tokens)} tok`);let r=e.responseMetadata?.durationMs;if(typeof r=="number"&&n.push(he(r)),n.length===0){let o=Date.now()-e.startedAt;o>0&&n.push(he(o))}return n.length>0&&t.push(`(${n.join(" \xB7 ")})`),t.join(" ")}var sr=class{out;throttleMs;indent;buffer="";committed="";throttleTimer=null;logUpdate=null;isTTY;flushing=!1;compositor;constructor(t){this.out=t?.out??process.stdout,this.throttleMs=t?.throttleMs??33,this.indent=t?.indent??" ",this.isTTY=this.out.isTTY??!1,this.compositor=t?.compositor??null,this.logUpdate=null}async initLogUpdate(){if(!(!this.isTTY||this.logUpdate!==null))try{let n=(await import("log-update")).default,r=(o=>{n(o)});r.clear=()=>n.clear(),this.logUpdate=r}catch{this.logUpdate=null}}hasMarkdownContent(t){return/[#*_\-\`>\[\|~]/.test(t)}findBlockBoundary(t){let n=t.indexOf(`
1427
+
1428
+ `);if(n!==-1)return n+2;let r=t.match(/\n[ \t]*```[ \t]*\n/);if(r&&r.index!==void 0)return r.index+r[0].length;let o=t.match(/```[a-z]*\n/);return o&&o.index!==void 0&&!t.slice(o.index+o[0].length).includes("\n```"),-1}applyIndent(t){return t.split(`
1429
+ `).map(n=>n?this.indent+n:"").join(`
1430
+ `)}isInOpenCodeFence(t){return(t.match(/```/g)??[]).length%2===1}commitBlock(t){if(!t.trim())return;let n=this.hasMarkdownContent(t),r=Math.max(1,V()-2),o;n?o=ze(t,{maxWidth:r}):o=t;let s=this.applyIndent(o),a=Q(s,r);this.compositor&&this.compositor.commitAbove(a),this.committed?this.committed+=`
1431
+ `+a:this.committed+=a}scheduleRepaint(){this.isTTY&&(this.flushing||(this.throttleTimer&&clearTimeout(this.throttleTimer),this.throttleTimer=setTimeout(()=>{this.throttleTimer=null,this.repaint()},this.throttleMs)))}async repaint(){if(this.flushing||!this.isTTY||!this.buffer.trim())return;let t,n=Math.max(1,V()-2);this.isInOpenCodeFence(this.buffer)?t=`
1432
+ \u258D streaming code\u2026
1433
+ `:this.hasMarkdownContent(this.buffer)?t=ze(this.buffer,{maxWidth:n}):t=this.buffer;let r=this.applyIndent(t),o=Q(r,n);if(this.compositor){this.compositor.setOverlay(o);return}this.logUpdate||await this.initLogUpdate(),this.logUpdate&&(this.flushing||this.logUpdate(o))}push(t){if(this.flushing)return;this.buffer+=t;let n=this.findBlockBoundary(this.buffer);for(;n!==-1;){let r=this.buffer.slice(0,n);this.commitBlock(r),this.buffer=this.buffer.slice(n),n=this.findBlockBoundary(this.buffer)}this.scheduleRepaint()}async flush(){this.throttleTimer&&(clearTimeout(this.throttleTimer),this.throttleTimer=null),this.flushing=!0,this.compositor&&this.compositor.setOverlay(""),this.buffer.trim()&&(this.commitBlock(this.buffer),this.buffer=""),!this.compositor&&(this.isTTY&&this.logUpdate?(this.logUpdate.clear(),this.out.write(this.committed+`
1434
+ `)):this.committed&&this.out.write(this.committed+`
1435
+ `))}getCommittedOutput(){return this.committed}getPendingBuffer(){return this.buffer}commitPending(){this.buffer.trim()&&(this.commitBlock(this.buffer),this.buffer="",this.compositor&&this.compositor.setOverlay(""))}dispose(){this.throttleTimer&&(clearTimeout(this.throttleTimer),this.throttleTimer=null),this.logUpdate&&(this.logUpdate.clear(),this.logUpdate=null),this.buffer="",this.committed=""}};function al(e,t,n,r){switch(e.type){case"progress":r.set(e.progress.taskId,e.progress),n.isTTY&&eg(e.progress,n);return;case"chunk":{let o=e.chunk;if(o.type==="tool_use_detail")n.streamingMarkdown.current?.commitPending(),n.toolLane.addStartWithAgentContext(o.toolUseId,o.toolName,o.toolInput,void 0),t.stats.toolUses+=1,n.isTTY&&n.compositor&&n.compositor.setOverlay(n.toolLane.getOverlay());else if(o.type==="tool_result")n.streamingMarkdown.current?.commitPending(),n.toolLane.addResult(o.toolUseId,o),n.isTTY&&n.compositor&&n.compositor.setOverlay(n.toolLane.getOverlay());else if(o.type==="content")t.contentBuffer+=o.content,n.isTTY&&(bo(n),n.streamingMarkdown.current||(n.streamingMarkdown.current=new sr({...n.compositor?{compositor:n.compositor}:{}})),n.streamingMarkdown.current.push(o.content));else if(o.type==="thinking"){if(n.thinkingMode==="off")return;if(n.thinkingLane.push(o.content),n.thinkingMode==="live"&&n.isTTY&&n.compositor){let s=ol(n.thinkingLane.peek());n.compositor.setOverlay(s)}}return}case"message":t.contentBuffer||(t.contentBuffer=e.message.content);return;case"error":t.errored=!0,Zf(e.error,n.out);return;case"done":t.done=!0,e.metadata&&(t.responseMetadata=e.metadata),Xf(t,n);return;case"suggestion":return;case"panel":Qf(e.spec,t,n);return}}function Qf(e,t,n){n.streamingMarkdown.current?n.streamingMarkdown.current.commitPending():t.contentBuffer.trim()&&(ll(t.contentBuffer,n.out),t.contentBuffer=""),bo(n);let o=vt(e).split(`
1436
+ `);if(n.isTTY&&n.compositor)for(let s of o)n.compositor.commitAbove(s);else for(let s of o)n.out.line(s)}async function Xf(e,t){if(t.streamingMarkdown.current){try{await t.streamingMarkdown.current.flush()}catch{}t.streamingMarkdown.current.dispose(),t.streamingMarkdown.current=null}else e.contentBuffer.trim()&&ll(e.contentBuffer,t.out);if(e.contentBuffer="",bo(t),t.thinkingMode!=="off"){let n=t.thinkingLane.collapse();n&&t.out.line(n)}}function ll(e,t){let n=ze(e);for(let r of n.split(`
1437
+ `))t.line(r)}function Zf(e,t){let n=Qt(e.message,e.stack);for(let r of n.split(`
1438
+ `))t.line(r)}function bo(e){if(!e.toolLane.hasPending())return;let t=e.toolLane.flush();if(e.isTTY&&e.compositor){for(let n of t)e.compositor.commitAbove(n);e.compositor.setOverlay("")}else for(let n of t)e.out.line(n)}function eg(e,t){if(!t.isTTY)return;let n=da(e).join(`
1439
+ `);t.compositor&&t.compositor.setOverlay(n)}function wo(e,t){if(!e||!e.trim())return;let n=d.dim("\u2502 "),r=" ",o=Math.max(1,V()-r.length-2-2);for(let s of e.split(`
1440
+ `)){let a=Q(s,o);for(let i of a.split(`
1441
+ `)){let l=r+n+i;t.isTTY&&t.compositor?t.compositor.commitAbove(l):t.out.line(l)}}}function cl(e,t,n){if(t.syntheticAgentToolUseId)return;let r=`__synth_agent_${e}`,o=t.agentType??e;n.toolLane.addStartWithAgentContext(r,"Agent",`(${o})`,void 0),t.syntheticAgentToolUseId=r}function ul(e,t,n){let r=t.syntheticAgentToolUseId;if(r)switch(e.type){case"progress":e.progress.totalTokens&&(t.stats.tokens=e.progress.totalTokens),e.progress.toolUses&&(t.stats.toolUses=e.progress.toolUses);return;case"chunk":{let o=e.chunk;if(o.type==="tool_use_detail")t.currentTextEntryId=void 0,n.toolLane.addStartWithAgentContext(o.toolUseId,o.toolName,o.toolInput,r),t.stats.toolUses+=1,n.isTTY&&n.compositor&&n.compositor.setOverlay(n.toolLane.getOverlay());else if(o.type==="tool_result")n.toolLane.addResult(o.toolUseId,o),n.isTTY&&n.compositor&&n.compositor.setOverlay(n.toolLane.getOverlay());else if(o.type==="content"){t.currentTextEntryId||(t.contentBuffer="",t.currentTextEntryId="__in_text_block__"),t.contentBuffer+=o.content;let s=t.contentBuffer.lastIndexOf(`
1442
+ `);if(s!==-1){let a=t.contentBuffer.slice(0,s);t.contentBuffer=t.contentBuffer.slice(s+1),wo(a,n)}}return}case"message":return;case"error":t.errored=!0,n.toolLane.addResult(r,ko(`error \u2014 ${e.error.message}`,!0)),n.isTTY&&n.compositor&&n.compositor.setOverlay(n.toolLane.getOverlay());return;case"done":t.done=!0,e.metadata&&(t.responseMetadata=e.metadata),ng(t,n);return;case"suggestion":return;case"panel":tg(e.spec,t,n);return}}function tg(e,t,n){t.contentBuffer.trim()&&(wo(t.contentBuffer,n),t.contentBuffer="");let r=vt(e);for(let o of r.split(`
1443
+ `))n.isTTY&&n.compositor?n.compositor.commitAbove(o):n.out.line(o)}function ng(e,t){let n=e.syntheticAgentToolUseId;if(!n||e.errored)return;e.contentBuffer&&(wo(e.contentBuffer,t),e.contentBuffer="");let r=il(e);t.toolLane.setAgentResultSummary(n,r),t.toolLane.addResult(n,ko(r,!1)),t.isTTY&&t.compositor&&t.compositor.setOverlay(t.toolLane.getOverlay())}var xt=class{out;thinkingMode;isTTY;onCancel;compositor=null;streamingMarkdownRef={current:null};toolLane=new en;thinkingLane=new or;sources=new Map;lastProgressByTask=new Map;disposed=!1;sink;constructor(t){this.out=t.out,this.thinkingMode=t.thinkingMode??(t.verbose===!0?"live":"summary"),this.onCancel=t.onCancel,this.isTTY=!(t.forceNonTty??!1)&&!!process.stdout.isTTY&&!!process.stdin.isTTY,this.sink=(n,r)=>this.process(n,r)}async arm(){if(this.disposed||!this.isTTY||this.compositor)return;let t=new tr({stdout:process.stdout,stdin:process.stdin,...this.onCancel?{onCancel:this.onCancel}:{}});await t.arm(),this.compositor=t,t.setSpinner({enabled:!0,rotateVerbEveryMs:3500})}makeOrchestratorCtx(){return{out:this.out,isTTY:this.isTTY,compositor:this.compositor,toolLane:this.toolLane,thinkingLane:this.thinkingLane,thinkingMode:this.thinkingMode,streamingMarkdown:this.streamingMarkdownRef}}getCompositor(){return this.compositor}makeSubagentCtx(){return{isTTY:this.isTTY,compositor:this.compositor,toolLane:this.toolLane,out:this.out}}process(t,n){if(this.disposed)return;this.compositor&&t.type!=="progress"&&this.compositor.setSpinner({enabled:!1});let r=n?.subagentId??yo,o=r===yo,s=this.sources.get(r);s||(s=sl(n?.agentType),this.sources.set(r,s),o||cl(r,s,this.makeSubagentCtx())),o?al(t,s,this.makeOrchestratorCtx(),this.lastProgressByTask):ul(t,s,this.makeSubagentCtx())}async dispose(){if(!this.disposed){if(this.disposed=!0,this.streamingMarkdownRef.current){try{await this.streamingMarkdownRef.current.flush()}catch{}this.streamingMarkdownRef.current.dispose(),this.streamingMarkdownRef.current=null}if(this.toolLane.hasPending()){let t=this.toolLane.flush();if(this.isTTY&&this.compositor){for(let n of t)this.compositor.commitAbove(n);this.compositor.setOverlay("")}else for(let n of t)this.out.line(n)}if(this.compositor){try{this.compositor.disarm()}catch{}this.compositor=null}}}};var dl="command-name",pl="command-message",ml="command-args";function fl(e,t){return`<${dl}>/${e}</${dl}>
1444
+ <${pl}>${e}</${pl}>
1445
+ <${ml}>${t}</${ml}>`}function gl(e,t){let n=fl(e.name,t),r=e.context==="fork"?" This skill runs with context: 'fork' \u2014 the executor will fork a subagent.":"",o=`Use the \`skill\` tool with {"name": "${e.name}", "arguments": "${t}"} to dispatch this skill.${r}`;return[{type:"text",text:n},{type:"text",text:o}]}function rg(e){let t=`/${e.name}`,n=e.argumentHint?`${t} ${e.argumentHint}`:void 0;return{name:t,summary:e.description,...n!==void 0?{usage:n}:{},...e.flags&&e.flags.length>0?{flags:e.flags}:{},async handler(r,o){let s=process.env.AFK_SKILL_STREAM_VERBOSE==="1",a=new xt({out:r.out,verbose:s,onCancel:()=>{r.session.interrupt().catch(()=>{})}});try{await a.arm();let i=gl(e,o);await yn(a.sink,async()=>{for await(let l of r.session.sendMessageStream(i))a.sink(l)})}catch(i){r.out.line(),r.out.error(`${e.name} failed: ${i instanceof Error?i.message:String(i)}`)}finally{await a.dispose()}return"continue"}}}function hl(){Kr(),Mn(Bo(),"project");for(let e of tt())qe(rg(oe(e)))}import{existsSync as tn,mkdirSync as Sg,renameSync as xg,rmSync as Tg,symlinkSync as Eg,lstatSync as Pg,unlinkSync as Cg}from"fs";import{basename as Ig,join as So}from"path";import{existsSync as yl}from"fs";import{isAbsolute as og,resolve as wl}from"path";import{homedir as kl}from"os";var sg=/^(?:https?:\/\/|git:\/\/|ssh:\/\/|git\+ssh:\/\/|git@[^:]+:)/,ig=/^([a-zA-Z0-9][a-zA-Z0-9_.-]*)\/([a-zA-Z0-9][a-zA-Z0-9._-]*?)(?:\.git)?$/,ag=/^([a-zA-Z0-9][a-zA-Z0-9_.-]*):([a-zA-Z0-9][a-zA-Z0-9_.-]*)$/;function lg(e){return e==="~"?kl():e.startsWith("~/")?wl(kl(),e.slice(2)):e}function Tt(e){let t=e.trim();if(!t)throw new Error('plugin source is required (examples: "owner/repo", "https://github.com/owner/repo.git", "./my-plugin")');if(cg(t)){let o=bl(t);if(!yl(o))throw new Error(`could not resolve plugin source: "${t}" looks like a local path but does not exist on disk`);return{type:"local",path:o}}if(sg.test(t))return{type:"git",url:t};let n=ag.exec(t);if(n&&n[1]&&n[2])return{type:"marketplace-ref",marketplace:n[1],plugin:n[2]};let r=ig.exec(t);if(r&&r[1]&&r[2]){let o=r[1],s=r[2];return{type:"github",owner:o,repo:s,url:`https://github.com/${o}/${s}.git`}}if(yl(t))return{type:"local",path:bl(t)};throw new Error(`could not resolve plugin source: "${t}". Use a git URL (https://\u2026/repo.git), GitHub shorthand (owner/repo), or a local path to a directory that exists on disk.`)}function cg(e){return e.startsWith("./")||e.startsWith("../")||e.startsWith("~")||e.startsWith("/")}function bl(e){let t=lg(e);return og(t)?t:wl(process.cwd(),t)}import{execFile as ug}from"child_process";import{promisify as dg}from"util";var pg=dg(ug),Et=async(e,t)=>{try{let{stdout:n,stderr:r}=await pg("git",Array.from(e),{cwd:t,maxBuffer:20971520});return{stdout:n,stderr:r}}catch(n){throw mg(n)&&n.code==="ENOENT"?new Error("git not found on PATH \u2014 install git first"):n}};function mg(e){return typeof e=="object"&&e!==null&&"code"in e}async function ir(e,t,n={}){await(n.runner??Et)(["clone","--",e,t])}async function ar(e,t={}){await(t.runner??Et)(["fetch","--tags","--prune"],e)}async function Qe(e,t={}){let n=t.runner??Et,{stdout:r}=await n(["tag","--list","--sort=-v:refname"],e);return r.split(`
1446
+ `).map(o=>o.trim()).filter(Boolean)}async function Xe(e,t,n={}){await(n.runner??Et)(["checkout","--detach",t],e)}async function Ie(e,t={}){let n=t.runner??Et,{stdout:r}=await n(["rev-parse","HEAD"],e);return r.trim()}async function Ae(e,t={}){let n=t.runner??Et;try{let{stdout:r}=await n(["symbolic-ref","refs/remotes/origin/HEAD","--short"],e);return r.trim().replace(/^origin\//,"")||"main"}catch{return"main"}}var fg=/^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;function gg(e){let t=fg.exec(e);if(!t)return null;let[,n,r,o,s]=t;return{raw:e,major:Number(n),minor:Number(r),patch:Number(o),prerelease:s??null}}function hg(e,t){if(e===null&&t===null)return 0;if(e===null)return 1;if(t===null)return-1;let n=e.split("."),r=t.split("."),o=Math.max(n.length,r.length);for(let s=0;s<o;s++){let a=n[s],i=r[s];if(a===void 0)return-1;if(i===void 0)return 1;let l=/^\d+$/.test(a),c=/^\d+$/.test(i);if(l&&c){let u=Number(a)-Number(i);if(u!==0)return u}else{if(l)return-1;if(c)return 1;if(a<i)return-1;if(a>i)return 1}}return 0}function yg(e,t){return e.major!==t.major?e.major-t.major:e.minor!==t.minor?e.minor-t.minor:e.patch!==t.patch?e.patch-t.patch:hg(e.prerelease,t.prerelease)}function Ze(e){let t=e.map(n=>gg(n.trim())).filter(n=>n!==null);return t.length===0?null:(t.sort((n,r)=>yg(r,n)),t[0]?.raw??null)}import{existsSync as Sl,readFileSync as kg}from"fs";import{join as bg}from"path";var wg=".claude-plugin/marketplace.json";function xl(e){return bg(e,wg)}function vo(e){return Sl(xl(e))}function Le(e){let t=xl(e);if(!Sl(t))throw new Error(`marketplace manifest not found: ${t}`);let n;try{n=kg(t,"utf8")}catch(o){throw new Error(`could not read marketplace manifest at ${t}: ${vl(o)}`)}let r;try{r=JSON.parse(n)}catch(o){throw new Error(`marketplace manifest at ${t} is not valid JSON: ${vl(o)}`)}return vg(r,t)}function Tl(e){try{return Le(e)}catch{return null}}function vg(e,t){if(!e||typeof e!="object")throw new Error(`marketplace manifest at ${t} must be a JSON object`);let n=e,r=n.name;if(typeof r!="string"||!r.trim())throw new Error(`marketplace manifest at ${t} is missing required "name" field`);let o=n.plugins;if(!Array.isArray(o))throw new Error(`marketplace manifest at ${t} is missing required "plugins" array`);let s=new Set,a=o.map((u,p)=>{if(!u||typeof u!="object")throw new Error(`marketplace manifest at ${t}: plugins[${p}] must be an object`);let m=u,f=m.name,g=m.source;if(typeof f!="string"||!f.trim())throw new Error(`marketplace manifest at ${t}: plugins[${p}] missing required "name"`);if(typeof g!="string"||!g.trim())throw new Error(`marketplace manifest at ${t}: plugins[${p}] missing required "source"`);let y=f.trim();if(s.has(y))throw new Error(`marketplace manifest at ${t}: duplicate plugin name "${y}"`);s.add(y);let h={name:y,source:g.trim()},b=m.description;return typeof b=="string"&&(h.description=b),h}),i={name:r.trim(),plugins:a},l=n.metadata;if(l&&typeof l=="object"){let u=l,p={};typeof u.description=="string"&&(p.description=u.description),Object.keys(p).length>0&&(i.metadata=p)}let c=n.owner;if(c&&typeof c=="object"){let u=c,p={};typeof u.name=="string"&&(p.name=u.name),typeof u.email=="string"&&(p.email=u.email),Object.keys(p).length>0&&(i.owner=p)}return i}function vl(e){return e instanceof Error?e.message:String(e)}async function ur(e,t={},n={}){let r=n.cacheDir??Me(),o=n.indexPath??F(),s=n.now??(()=>new Date),a=n.gitRunner?{runner:n.gitRunner}:{},i=Tt(e);if(i.type==="marketplace-ref")throw new Error(`marketplace source cannot itself be a marketplace reference ("${e}")`);return Sg(r,{recursive:!0}),i.type==="local"?Ag(i,t,r,o,s):Mg(i,t,r,o,s,a)}function Ag(e,t,n,r,o){let s=Le(e.path),a=t.name??s.name,i=So(n,a);xo(i,t.force??!1),(tn(i)||To(i))&&cr(i),Eg(e.path,i,"dir");let l=o().toISOString(),c={source:e.path,sourceType:"local",ref:null,commit:null,installedAt:l,updatedAt:l};return Lt(a,c,r),{name:a,dir:i,entry:c,plugins:s.plugins.map(El)}}async function Mg(e,t,n,r,o,s){let a=t.name??_g(e),i=So(n,a);xo(i,t.force??!1),tn(i)&&cr(i);let l=e.type==="github"?`${e.owner}/${e.repo}`:e.url;await ir(e.url,i,s);try{let c;if(t.ref)c=t.ref;else{let h=await Qe(i,s);c=Ze(h)??await Ae(i,s)}(t.ref||await Rg(i,c,s))&&await Xe(i,c,s);let u=await Ie(i,s),p=Le(i),m=a,f=i;if(!t.name&&p.name!==a){let h=So(n,p.name);xo(h,t.force??!1),tn(h)&&cr(h),xg(i,h),m=p.name,f=h}let g=o().toISOString(),y={source:l,sourceType:e.type,ref:c,commit:u,installedAt:g,updatedAt:g};return Lt(m,y,r),{name:m,dir:f,entry:y,plugins:p.plugins.map(El)}}catch(c){try{tn(i)&&cr(i)}catch{}throw c}}async function Rg(e,t,n){let r=await Ae(e,n);return t!==r}function _g(e){if(e.type==="github")return e.repo;let t=e.url.replace(/\.git$/,""),n=t.lastIndexOf("/"),r=t.lastIndexOf(":"),o=Math.max(n,r);return o>=0?t.slice(o+1):Ig(t)}function xo(e,t){if(!(!tn(e)&&!To(e))&&!t)throw new Error(`marketplace directory already exists: ${e} (re-run with --force to replace)`)}function To(e){try{return Pg(e).isSymbolicLink()}catch{return!1}}function cr(e){if(To(e)){Cg(e);return}Tg(e,{recursive:!0,force:!0})}function El(e){return e.description?{name:e.name,description:e.description}:{name:e.name}}import{existsSync as $g,lstatSync as Og,rmSync as Dg,unlinkSync as Lg}from"fs";import{join as Fg}from"path";function dr(e,t={}){let n=t.cacheDir??Me(),r=t.indexPath??F(),o=Fg(n,e),s=!1;Ug(o)?(Lg(o),s=!0):$g(o)&&(Dg(o,{recursive:!0,force:!0}),s=!0);let a=B(r),i=Object.prototype.hasOwnProperty.call(a.marketplaces,e),l=Object.entries(a.plugins).filter(([,c])=>c.marketplace===e).map(([c])=>c);return(i||l.length>0)&&Ps(e,r),{name:e,removedDir:s,removedIndexEntry:i,removedPluginEntries:l}}function Ug(e){try{return Og(e).isSymbolicLink()}catch{return!1}}import{existsSync as Ng}from"fs";import{join as jg}from"path";async function nn(e,t={},n={}){let r=n.indexPath??F(),o=n.now??(()=>new Date),s=n.gitRunner?{runner:n.gitRunner}:{},i=B(r).marketplaces[e];if(!i)throw new Error(`marketplace "${e}" is not installed`);let l=n.cacheDir?jg(n.cacheDir,e):Rt(e);if(!Ng(l))return{name:e,status:"missing-dir",dir:l};if(i.sourceType==="local")return{name:e,status:"skipped-local"};let c=new Set((Tl(l)?.plugins??[]).map(b=>b.name));await ar(l,s);let u;if(t.ref)u=t.ref;else{let b=await Qe(l,s);u=Ze(b)??i.ref??await Ae(l,s)}if(u===i.ref){let b=await Ie(l,s);return{name:e,status:"up-to-date",ref:u,commit:b}}await Xe(l,u,s);let p=await Ie(l,s),m=o().toISOString(),f={...i,ref:u,commit:p,updatedAt:m};Lt(e,f,r);let g=new Set(Le(l).plugins.map(b=>b.name)),y=[...g].filter(b=>!c.has(b)),h=[...c].filter(b=>!g.has(b));return{name:e,status:"updated",fromRef:i.ref,toRef:u,commit:p,addedPlugins:y,removedPlugins:h}}async function Pl(e={}){let t=e.indexPath??F(),n=B(t),r=[];for(let o of Object.keys(n.marketplaces))try{r.push(await nn(o,{},e))}catch(s){let a=s instanceof Error?s.message:String(s);r.push({name:o,status:"missing-dir",dir:a})}return r}import{existsSync as fr,statSync as Zg}from"fs";import{isAbsolute as eh,join as th,resolve as Al}from"path";import{existsSync as et,mkdirSync as Bg,readFileSync as Hg,renameSync as Wg,rmSync as Kg,symlinkSync as Gg,lstatSync as zg,unlinkSync as Vg}from"fs";import{basename as Yg,join as Pt}from"path";async function mr(e,t={},n={}){let r=n.pluginsDir??ae(),o=n.indexPath??F(),s=n.now??(()=>new Date),a=n.gitRunner?{runner:n.gitRunner}:{},i=Tt(e);if(Bg(r,{recursive:!0}),i.type==="local")return qg(i,t,r,o,s);if(i.type==="marketplace-ref")throw new Error(`marketplace-ref source "${i.marketplace}:${i.plugin}" must be installed via the marketplace resolver, not installPlugin directly`);return Jg(i,t,r,o,s,a)}function qg(e,t,n,r,o){Cl(e.path);let s=Il(e.path),a=t.name??s??Yg(e.path),i=Pt(n,a);Eo(i,t.force??!1),(et(i)||Po(i))&&pr(i),Gg(e.path,i,"dir");let l=o().toISOString(),c={source:e.path,sourceType:"local",ref:null,commit:null,enabled:!0,installedAt:l,updatedAt:l,...s&&s!==a?{manifestName:s}:{}};return Ue(a,c,r),{name:a,dir:i,entry:c}}async function Jg(e,t,n,r,o,s){let a=t.name??Xg(e),i=Pt(n,a);Eo(i,t.force??!1),et(i)&&pr(i);let l=e.type==="github"?`${e.owner}/${e.repo}`:e.url;await ir(e.url,i,s);try{let c;if(t.ref)c=t.ref;else{let h=await Qe(i,s);c=Ze(h)??await Ae(i,s)}(t.ref||await Qg(i,c,s))&&await Xe(i,c,s);let u=await Ie(i,s);Cl(i);let p=Il(i),m=a,f=i;if(!t.name&&p&&p!==a){let h=Pt(n,p);Eo(h,t.force??!1),et(h)&&pr(h),Wg(i,h),m=p,f=h}let g=o().toISOString(),y={source:l,sourceType:e.type,ref:c,commit:u,enabled:!0,installedAt:g,updatedAt:g,...p&&p!==m?{manifestName:p}:{}};return Ue(m,y,r),{name:m,dir:f,entry:y}}catch(c){try{et(i)&&pr(i)}catch{}throw c}}async function Qg(e,t,n){let r=await Ae(e,n);return t!==r}function Xg(e){if(e.type==="github")return e.repo;let t=e.url.replace(/\.git$/,""),n=t.lastIndexOf("/"),r=t.lastIndexOf(":"),o=Math.max(n,r);return o>=0?t.slice(o+1):t}function Cl(e){let t=Pt(e,".claude-plugin","plugin.json");if(et(t))return;let n=Pt(e,".claude-plugin","marketplace.json");if(et(n))throw new Error(`${e} contains .claude-plugin/marketplace.json instead of plugin.json. Use \`afk marketplace install <source>\` to install a marketplace, then \`afk plugin install <marketplace>:<plugin>\` to install a plugin from it.`)}function Il(e){let t=Pt(e,".claude-plugin","plugin.json");if(!et(t))return null;try{let n=JSON.parse(Hg(t,"utf8"));return typeof n.name=="string"&&n.name.trim()?n.name.trim():null}catch{return null}}function Eo(e,t){if(!(!et(e)&&!Po(e))&&!t)throw new Error(`plugin directory already exists: ${e} (re-run with --force to replace)`)}function Po(e){try{return zg(e).isSymbolicLink()}catch{return!1}}function pr(e){if(Po(e)){Vg(e);return}Kg(e,{recursive:!0,force:!0})}async function Ct(e,t,n={},r={}){let o=r.marketplaceDirFor??Rt,s=r.indexPath??F(),a=r.now??(()=>new Date),i=o(e);if(!fr(i)||!vo(i))throw new Error(`marketplace "${e}" is not installed (looked for manifest under ${i})`);let l=Le(i),c=l.plugins.find(u=>u.name===t);if(!c){let u=l.plugins.map(p=>p.name).join(", ")||"(none)";throw new Error(`marketplace "${e}" does not list a plugin named "${t}". Available: ${u}`)}return nh(c.source)?rh(e,c,i,s,a,n):oh(e,c,n,r)}function gr(e,t={}){let n=t.marketplaceDirFor??Rt,r=t.indexPath??F(),o=n(e);if(!fr(o)||!vo(o))throw new Error(`marketplace "${e}" is not installed`);let s=Le(o),a=B(r);return s.plugins.map(i=>{let l=`${e}:${i.name}`,c=l in a.plugins||i.name in a.plugins&&a.plugins[i.name]?.marketplace===e,u={name:i.name,installed:c,key:l};return i.description&&(u.description=i.description),u})}function nh(e){return e.startsWith("./")||e.startsWith("../")||e.startsWith("/")||e.startsWith("~")}function rh(e,t,n,r,o,s){let a=t.source,i=eh(a)||a.startsWith("~")?sh(a):Al(n,a);if(!fr(i))throw new Error(`marketplace "${e}" lists plugin "${t.name}" at ${i}, but that path does not exist on disk`);if(!Zg(i).isDirectory())throw new Error(`marketplace "${e}" lists plugin "${t.name}" at ${i}, but that path is not a directory`);let c=th(i,".claude-plugin","plugin.json");if(!fr(c))throw new Error(`marketplace "${e}" lists plugin "${t.name}" at ${i}, but no .claude-plugin/plugin.json was found`);let u=`${e}:${t.name}`,p=B(r);if(!s.force&&u in p.plugins&&p.plugins[u]?.enabled)throw new Error(`plugin "${u}" is already installed (re-run with --force to overwrite)`);let m=o().toISOString(),f={source:`${e}:${t.name}`,sourceType:"marketplace",ref:null,commit:null,enabled:!0,installedAt:m,updatedAt:m,marketplace:e};return Ue(u,f,r),{key:u,name:t.name,dir:i,entry:f}}async function oh(e,t,n,r){let o={name:t.name,...n.ref?{ref:n.ref}:{},...n.force?{force:!0}:{}},s=await mr(t.source,o,r),a=r.indexPath??F(),i={...s.entry,marketplace:e};return Ue(s.name,i,a),{key:s.name,name:s.name,dir:s.dir,entry:i}}function sh(e){if(e.startsWith("~")){let t=process.env.HOME??"";if(e==="~")return t;if(e.startsWith("~/"))return Al(t,e.slice(2))}return e}var Ml=["add","plugins","install","remove","update"],ih={name:"/marketplaces",summary:"List installed plugin marketplaces",async handler(e){return lh(e),"continue"}},ah={name:"/marketplace",summary:"Manage plugin marketplaces (add | plugins | install | remove | update)",usage:"/marketplace <add|plugins|install|remove|update> [args]",async handler(e,t){let n=t.trim();if(!n)return ch(e),"continue";let[r,...o]=n.split(/\s+/);if(!r||!Ml.includes(r))return e.out.error(`Unknown subcommand "${r??""}". Try one of: ${Ml.join(", ")}.`),"continue";switch(r){case"add":return uh(e,o);case"plugins":return dh(e,o);case"install":return ph(e,o);case"remove":return mh(e,o);case"update":return fh(e,o);default:return"continue"}}};function Rl(){se(ih),se(ah)}function lh(e){let t=B(),n=Object.entries(t.marketplaces).sort(([r],[o])=>r.localeCompare(o));if(e.out.line(),n.length===0){e.out.line(d.dim(" No marketplaces installed.")),e.out.line(d.dim(" Try: /marketplace add anthropics/claude-plugins-official")),e.out.line();return}e.out.line(d.bold("Installed marketplaces:"));for(let[r,o]of n){let s=o.ref?d.brand(o.ref):d.dim("(local)");e.out.line(` ${d.bold(r.padEnd(28))} ${s.padEnd(12)} ${d.dim(o.source)}`)}e.out.line()}function ch(e){e.out.line(),e.out.line(d.bold("/marketplace usage:")),e.out.line(` ${d.brand("/marketplace add")} <git-url|owner/repo|local-path>`),e.out.line(` ${d.brand("/marketplace plugins")} <marketplace>`),e.out.line(` ${d.brand("/marketplace install")} <marketplace> <plugin>`),e.out.line(` ${d.brand("/marketplace remove")} <marketplace>`),e.out.line(` ${d.brand("/marketplace update")} [<marketplace>]`),e.out.line()}async function uh(e,t){if(t.length===0)return e.out.error("Usage: /marketplace add <source> [name]"),"continue";let[n,r,...o]=t;if(!n)return e.out.error("Usage: /marketplace add <source> [name]"),"continue";let s=gh(o);e.out.info(`Installing marketplace ${n}\u2026`);try{let a=await ur(n,{...r&&!r.startsWith("-")?{name:r}:{},...s.ref?{ref:s.ref}:{},...s.force?{force:!0}:{}});e.out.success(`Installed marketplace ${a.name} (${a.plugins.length} plugin(s) available).`),e.out.line(d.dim(` Next: /marketplace plugins ${a.name}`))}catch(a){e.out.error(`Install failed: ${hr(a)}`)}return"continue"}function dh(e,t){let n=t[0];if(!n)return e.out.error("Usage: /marketplace plugins <marketplace>"),"continue";try{let r=gr(n);if(e.out.line(),r.length===0)return e.out.line(d.dim(` Marketplace "${n}" lists no plugins.`)),e.out.line(),"continue";e.out.line(d.bold(`Plugins in ${n}:`)),r.forEach((o,s)=>{let a=o.installed?d.brand("[\u2713]"):d.dim("[ ]"),i=o.description?d.dim(` \u2014 ${o.description}`):"";e.out.line(` ${a} ${d.bold(String(s+1).padStart(2))}. ${d.bold(o.name)}${i}`)}),e.out.line(),e.out.line(d.dim(` Install one: /marketplace install ${n} <plugin>`)),e.out.line()}catch(r){e.out.error(`List failed: ${hr(r)}`)}return"continue"}async function ph(e,t){let n,r;if(t.length===1&&t[0]?.includes(":")){let o=t[0].split(":");o.length===2&&([n,r]=o)}else[n,r]=t;if(!n||!r)return e.out.error("Usage: /marketplace install <marketplace> <plugin>"),"continue";e.out.info(`Installing ${n}:${r}\u2026`);try{let o=await Ct(n,r);e.out.success(`Installed ${o.key}.`),e.out.line(d.dim(" Run /reload-plugins to refresh this session's slash commands."))}catch(o){e.out.error(`Install failed: ${hr(o)}`)}return"continue"}function mh(e,t){let n=t[0];if(!n)return e.out.error("Usage: /marketplace remove <marketplace>"),"continue";let r=dr(n);if(!r.removedDir&&!r.removedIndexEntry&&r.removedPluginEntries.length===0)return e.out.line(d.dim(` No marketplace named "${n}" to remove.`)),"continue";let o=r.removedPluginEntries.length>0?` + ${r.removedPluginEntries.length} plugin(s)`:"";return e.out.success(`Removed marketplace ${n}${o}.`),"continue"}async function fh(e,t){let n=t[0];if(!n)return e.out.error("Usage: /marketplace update <marketplace>"),"continue";e.out.info(`Updating ${n}\u2026`);try{let r=await nn(n);switch(r.status){case"updated":{let o=r.addedPlugins.length>0?` +${r.addedPlugins.join(", ")}`:"",s=r.removedPlugins.length>0?` -${r.removedPlugins.join(", ")}`:"";e.out.success(`Updated ${n}: ${r.fromRef??"(none)"} \u2192 ${r.toRef}${o}${s}`);break}case"up-to-date":e.out.info(`${n} is up-to-date (${r.ref}).`);break;case"skipped-local":e.out.info(`${n} skipped (local source).`);break;case"missing-dir":e.out.warn(`${n}: marketplace dir missing (${r.dir}).`);break}}catch(r){e.out.error(`Update failed: ${hr(r)}`)}return"continue"}function gh(e){let t={};for(let n=0;n<e.length;n+=1){let r=e[n];r==="-f"||r==="--force"?t.force=!0:(r==="-r"||r==="--ref")&&e[n+1]&&(t.ref=e[n+1],n+=1)}return t}function hr(e){return e instanceof Error?e.message:String(e)}function _l(){Sa();for(let e of Ia)se(e);for(let e of Aa)se(e);se(Ma),se(ja),se(Ba),se(Ha),hl(),Ja(),Wa(),Rl()}function yr(){return{line(e=""){console.log(e)},raw(e){process.stdout.write(e)},success(e){console.log(d.success("\u2713 ")+e)},info(e){console.log(d.info("\u2139 ")+e)},warn(e){console.log(d.warning("\u26A0 ")+e)},error(e){console.log(d.error("\u2717 ")+e)}}}var kr=class{source;sampleEveryNTurns;cachedRatio;cachedDetail;inFlight=null;disposed=!1;constructor(t,n={}){this.source=t,this.sampleEveryNTurns=n.sampleEveryNTurns??3}attach(t){return this}getRatio(){return this.cachedRatio}getDetail(){return this.cachedDetail}async refresh(){if(this.disposed)return;if(this.inFlight)return this.inFlight;let t=this.doFetch().finally(()=>{this.inFlight=null});return this.inFlight=t,t}async onTurn(t){this.disposed||t%this.sampleEveryNTurns===1&&await this.refresh()}dispose(){this.disposed=!0}async doFetch(){try{let t=await this.source.getContextUsage(),n=hh(t.apiUsage),r=t.maxTokens??0,o=t.percentage;typeof o=="number"&&(this.cachedRatio=Math.min(1,Math.max(0,o/100)),this.cachedDetail={used:n,limit:r,percentage:o})}catch{}}};function hh(e){return e?e.input_tokens+e.output_tokens+e.cache_creation_input_tokens+e.cache_read_input_tokens:0}async function Ol(e,t){let n,r,o;n=He(e.thinking)??dt(),r=We(e.effort)??pt(),o=ft(e.maxOutputTokens)??Ht();let s=Cn()??Pn(),i=ct().autoRouting?.interactive??!0,l=Dn(s,i),c,u=new _({}),p=N(),m=Nn(),f={get sessionId(){return c?.sessionId},getInputStreamRef(){return c?.getInputStreamRef?.()??{pushUserMessage:()=>{}}},get abortSignal(){return c?.abortSignal??new AbortController().signal}},g=new bt({subagentManager:u,parentSession:f,defaultConfig:{apiKey:p,systemPrompt:s},defaultSubagentModel:ut(),childProviderFactory:m,childSkillExecutorFactory:jn(e.model)}),y=new Ye({parentSession:f,defaultModel:e.model,defaultSubagentModel:ut()}),h=In(e.provider,{subagentExecutor:g,skillExecutor:y})??new ge({permissions:{allowedTools:[...Be,"agent","skill"]},subagentExecutor:g,skillExecutor:y}),b={fn:R=>console.log(R)},v=new ue({model:e.model,apiKey:N(),maxTurns:parseInt(e.maxTurns,10),hookRegistry:yt(R=>{b.fn(Un(R))}),...l!==void 0?{systemPrompt:l}:{},...n!==void 0?{thinking:n}:{},...r!==void 0?{effort:r}:{},...o!==void 0?{maxOutputTokens:o}:{},...t?.cwd!==void 0?{cwd:t.cwd}:{},provider:h});c=v;let w=Ta(e.model),P=yr(),T=new zn,L=new kr(v);L.attach(v);let E={session:v,stats:w,out:P,ui:{clearScreen:()=>{T.stop(),process.stdout.write("\x1B[3J\x1B[2J\x1B[H"),T.start(),T.repaint(io(w,L))},repaintStatusLine:()=>T.repaint(io(w,L))}};_l();let S=$l.createInterface({input:process.stdin,output:process.stdout,terminal:!1});return{session:v,stats:w,statusLine:T,contextSampler:L,completionWriter:b,slashCtx:E,rl:S,options:e}}import{promises as rn}from"node:fs";import*as Ll from"node:os";import*as br from"node:path";async function Dl(e,t,n=!1){await rn.mkdir(e,{recursive:!0});let r=new Date().toISOString().replace(/[:.]/g,"-"),o=br.join(e,`${r}.md`),s=n?" (continued)":"";return await rn.writeFile(o,`# Session \u2014 ${new Date().toISOString()}${s}
1447
+
1448
+ - model: ${t}
1449
+
1450
+ ---
1451
+
1452
+ `),o}async function Fl(e){let t=br.join(process.env.AFK_STATE_DIR??br.join(Ll.homedir(),".afk"),"transcripts"),n=await Dl(t,e());return{path:()=>n,async appendTurn(r,o){o&&await rn.appendFile(n,`_${new Date().toISOString()} \xB7 model: ${e()}_
1453
+
1454
+ ## User
1455
+
1456
+ ${r}
1457
+
1458
+ ## Assistant
1459
+
1460
+ ${o}
1461
+
1462
+ ---
1463
+
1464
+ `).catch(()=>{})},async rotateOnClear(){await rn.appendFile(n,`
1465
+ _cleared_
1466
+ `).catch(()=>{}),n=await Dl(t,e(),!0)},async appendEnded(){await rn.appendFile(n,`
1467
+ _ended: ${new Date().toISOString()}_
1468
+ `).catch(()=>{})}}}import{emitKeypressEvents as Ch}from"readline";import*as me from"ansi-escapes";import Ih from"chalk";import on from"string-width";import{readdirSync as yh,statSync as kh}from"fs";import{join as Ul}from"path";function Nl(e,t=process.cwd()){try{let n=e.lastIndexOf("/"),r=n===-1?"":e.slice(0,n),o=n===-1?e:e.slice(n+1),s=r?Ul(t,r):t,a=yh(s),i=[];for(let l of a){if(!l.startsWith(o)||l.startsWith(".")&&!o.startsWith("."))continue;let c=r?`${r}/${l}`:l;try{kh(Ul(s,l)).isDirectory()&&(c+="/")}catch{}if(i.push(c),i.length>=30)break}return i.sort()}catch{return[]}}async function jl(e){let t="",n=e.promptFn(),r=e.continuationPrompt??" \u203A ";for(;;){e.rl.setPrompt(n),e.rl.prompt();let o=await new Promise(s=>{e.rl.once("line",a=>s(a))});if(o.endsWith("\\")){t+=o.slice(0,-1)+`
1469
+ `,n=r;continue}return t+=o,t}}import{spawn as bh}from"child_process";import{randomUUID as wh}from"crypto";async function Bl(){if(process.platform!=="darwin")return null;try{let e=await vh();if(e.length===0)return null;let t=Sh(e);return t?{id:wh(),mediaType:t,bytes:e,sizeBytes:e.byteLength}:null}catch{return null}}async function vh(){return new Promise((e,t)=>{let n=bh("pbpaste",["-Prefer","image"],{stdio:["ignore","pipe","pipe"]}),r=[];n.stdout?.on("data",o=>{r.push(o)}),n.on("error",o=>{t(o)}),n.on("close",o=>{o!==0?t(new Error(`pbpaste exited with code ${o}`)):e(Buffer.concat(r))})})}function Sh(e){return e.length>=8&&e[0]===137&&e[1]===80&&e[2]===78&&e[3]===71?"image/png":e.length>=3&&e[0]===255&&e[1]===216&&e[2]===255?"image/jpeg":e.length>=4&&e[0]===71&&e[1]===73&&e[2]===70&&e[3]===56?"image/gif":e.length>=12&&e[0]===82&&e[1]===73&&e[2]===70&&e[3]===70&&e[8]===87&&e[9]===69&&e[10]===66&&e[11]===80?"image/webp":null}var xh={"image/png":"PNG","image/jpeg":"JPEG","image/gif":"GIF","image/webp":"WEBP"};function Th(e){if(e<1024)return`${e} B`;let t=e/1024;return t<1024?`${t.toFixed(1)} KiB`:`${(t/1024).toFixed(1)} MiB`}function Hl(e){if(e.length===0)return"";let t=e.reduce((i,l)=>i+l.sizeBytes,0),n=Th(t),r=e.length===1?"image":"images",o=new Set,s=[];for(let i of e){let l=xh[i.mediaType];o.has(l)||(o.add(l),s.push(l))}let a=s.join(", ");return`[${e.length} ${r} attached \xB7 ${n} \xB7 ${a}]`}function Wl(e,t){if(t.length===0)return e;if(e){let n=t.length===1?"image":"images";return`${e} [+ ${t.length} ${n}]`}return t.length===1?"[image attached]":`[${t.length} images attached]`}import Eh from"chalk";var Ph=/^(\/[A-Za-z][\w:-]*)(?=\s|$)/;function Kl(e,t){if(Eh.level===0)return e;let n=Ph.exec(e);if(!n)return e;let r=n[1],o=r.slice(1);return(t.has(o)?d.brand(r):d.meta(r))+e.slice(r.length)}function Ah(e,t){let n=e.slice(0,t);if(/^\/[A-Za-z_-]*$/.test(n))return{kind:"slash",query:n.slice(1)};let r=n.split(/\s+/),o=r[r.length-1]??"";if(o.startsWith("@")&&/^@[^\s]*$/.test(o))return{kind:"file",query:o.slice(1)};let s=/^\/([A-Za-z][A-Za-z0-9_:-]*)\s+(?:.*\s)?--([a-z0-9-]*)$/.exec(n);if(s){let a=s[1],i=s[2],l=Je().find(c=>c.name===`/${a}`);if(l?.flags&&l.flags.length>0)return{kind:"flag",command:a,query:i}}return null}function Mh(e){return Je().filter(r=>r.name.slice(1).startsWith(e)).map(r=>({value:r.name,summary:r.summary})).sort((r,o)=>r.value.localeCompare(o.value)).slice(0,20)}function Rh(e,t=process.cwd()){return Nl(e,t).slice(0,20).map(n=>({value:n}))}function _h(e,t){let n=Je().find(s=>s.name===`/${e}`);if(!n?.flags||n.flags.length===0)return[];let r=t.startsWith("--")?t.slice(2):t;return n.flags.filter(s=>(s.startsWith("--")?s.slice(2):s).startsWith(r)).map(s=>({value:s})).sort((s,a)=>s.value.localeCompare(a.value)).slice(0,20)}function $h(e,t){if(t<=0)return"";let n=0;for(let r=0;r<e.length;r++)if(n+=on(e[r]),n>t)return e.slice(0,r)+d.dim("\u2026");return e}function Oh(e,t,n,r){let o=t?">":" ",s=e.value,a=e.summary?` ${e.summary}`:"",i=`${s}${a}`,l=$h(i,n-4),c=` ${o} ${l}`,u=r==="flag"?d.warning:d.meta;return t?Ih.inverse(d.user(c)):u(c)}function Dh(e){let{buffer:t,promptText:n,isTTY:r}=e;if(!r)return n+t;let o=e.terminalWidth??V(),s=t.includes(`
1470
+ `),i=on(n)+on(t)>=o-2;return!s&&!i?n+t:vt({kind:"user",body:t})}function Lh(e,t,n){let r=n||80,o=e.split(`
1471
+ `),s=0;for(let a=0;a<o.length;a++){let i=(a===0?t:0)+on(o[a]);s+=Math.max(1,Math.ceil(i/r))}return Math.max(0,s-1)}async function Gl(e){if(!process.stdout.isTTY||!process.stdin.isTTY)return{text:await jl({rl:e.rl,promptFn:e.promptFn}),attachments:[]};let t=process.stdin,n=process.stdout,r=t.isRaw;t.setRawMode(!0),t.resume(),n.write("\x1B[?2004h"),Ch(t);let o=e.promptFn(),s=on(o),a=null,i=null;try{return await new Promise((l,c)=>{let u=Y.seed(e.initialBuffer??""),p=!1,m=[],f=0,g=null,y=0,h=0,b=!1,v=0,w=0,P=[],T=6,L=0,E=!1,S=8,R={has:j=>Je().some(I=>I.name===`/${j}`)},k=()=>{if((w>0||v>0)&&n.write(me.cursorUp(w+v)),n.write("\r"),n.write(me.eraseDown),P.length>0?(n.write(Hl(P)+`
1472
+ `),w=1):w=0,n.write(o+Kl(u.buffer,R)),g=Ah(u.buffer,u.cursor),g?(g.kind==="slash"?m=Mh(g.query):g.kind==="file"?m=Rh(g.query):m=_h(g.command,g.query),p=m.length>0):(p=!1,m=[]),f>=m.length&&(f=Math.max(0,m.length-1)),h>f&&(h=f),f>=h+T&&(h=f-T+1),y=0,p&&n.columns>40){let I=Math.min(n.columns-4,60),X=Math.min(m.length-h,T);for(let te=0;te<X;te++){let xe=h+te,le=Oh(m[xe],xe===f,I,g?.kind);n.write(`
1473
+ `+le),y++}}y>0&&n.write(me.cursorUp(y)),n.write("\r");let j=s+u.cursor;j>0&&n.write(me.cursorForward(j)),v=Lh(u.buffer,s,n.columns||80)},C=()=>{E||(E=!0,setImmediate(()=>{E&&(E=!1,k())}))};k();let x=()=>{let j=m[f];if(!j)return;let I=u.buffer.slice(0,u.cursor),X=u.buffer.slice(u.cursor),te,xe;if(g?.kind==="slash"){let le=/\/[A-Za-z_-]*$/.exec(I);te=le?I.length-le[0].length:u.cursor,xe=j.value+(X.startsWith(" ")?"":" ")}else if(g?.kind==="flag"){let le=/--[a-z0-9-]*$/.exec(I);te=le?I.length-le[0].length:u.cursor,xe=j.value+(X.startsWith(" ")?"":" ")}else{let le=I.search(/[^\s]*$/);te=le>=0?le:u.cursor,xe=j.value}u=Y.replaceRange(u,{start:te,end:u.cursor},xe),p=!1,h=0,f=0,k()},M=()=>{(w>0||v>0)&&n.write(me.cursorUp(w+v)),n.write("\r"),n.write(me.eraseDown),y=0;let j=Dh({buffer:u.buffer,promptText:o,isTTY:!!n.isTTY});n.write(j+`
1474
+ `),H(),l({text:u.buffer,attachments:[...P]}),v=0},ne=j=>{v>0&&n.write(me.cursorUp(v)),y>0&&(n.write(me.eraseDown),y=0),n.write(`
1475
+ `),H(),c(j),v=0},H=()=>{a&&t.removeListener("keypress",a),i&&n.removeListener("resize",i),a=null,i=null};a=(j,I)=>{let X=Date.now(),te=X-L<S;L=X;let xe=I?.sequence||"";if(xe==="\x1B[200~"){b=!0;return}if(xe==="\x1B[201~"){b=!1,k();return}if(I?.ctrl&&I?.name==="c"){e.onSigint?e.onSigint():ne(new Error("SIGINT"));return}if(I?.ctrl&&I?.name==="d"){u.buffer.length===0&&((w>0||v>0)&&n.write(me.cursorUp(w+v)),y>0&&(n.write(me.eraseDown),y=0),n.write(`
1476
+ `),H(),l({text:"",attachments:[...P]}),v=0);return}if(I?.ctrl&&I?.name==="v"){Bl().then(q=>{q&&(P.push(q),k())}).catch(()=>{});return}if(I?.name==="escape"){p&&(p=!1,m=[],k());return}if(I?.name==="up"){p&&f>0&&(f--,f<h&&(h=f),k());return}if(I?.name==="down"){p&&f<m.length-1&&(f++,f>=h+T&&(h=f-T+1),k());return}if(I?.name==="left"){let q=Y.moveLeft(u);q!==u&&(u=q,k());return}if(I?.name==="right"){let q=Y.moveRight(u);q!==u&&(u=q,k());return}if(I?.name==="home"){let q=Y.moveHome(u);q!==u&&(u=q,k());return}if(I?.name==="end"){let q=Y.moveEnd(u);q!==u&&(u=q,k());return}if(I?.name==="backspace"){let q=Y.backspace(u);q!==u?(u=q,k()):P.length>0&&(P.pop(),k());return}if(I?.name==="delete"){let q=Y.deleteForward(u);q!==u&&(u=q,k());return}if(I?.name==="return"){if(b){u=Y.insert(u,`
1477
+ `);return}if(te){u=Y.insert(u,`
1478
+ `),C();return}if(p){let q=g?.kind;x(),q==="slash"&&M()}else u.buffer.endsWith("\\")?(u=Y.replaceRange(u,{start:u.buffer.length-1,end:u.buffer.length},`
1479
+ `),k()):M();return}if(I?.name==="tab"){p&&x();return}let le=typeof j=="string"&&j.length===1&&j>=" "&&!I?.ctrl&&!I?.meta?j:typeof I?.sequence=="string"&&I.sequence.length===1&&I.sequence>=" "&&!I?.ctrl&&!I?.meta?I.sequence:null;le!==null&&(u=Y.insert(u,le),b||(te?C():k()))},i=()=>k(),t.on("keypress",a),n.on("resize",i)})}finally{n.write("\x1B[?2004l");try{t.setRawMode(r)}catch{}}}function Fh(e,t){let n=[];e&&n.push({type:"text",text:e});for(let r of t)n.push({type:"image",source:{type:"base64",media_type:r.mediaType,data:r.bytes.toString("base64")}});return n}async function zl(e,t,n,r,o="summary",s){let a=Wl(e.text,e.attachments);r.setInFlight(!0);let i="",l=!1,c,u=!1,p=!1,m=!1,f,g=new xt({out:yr(),thinkingMode:o,onCancel:()=>{t.interrupt().catch(h=>{$t()&&console.error(" "+d.error("session.interrupt() failed:"),h)})}}),y=async()=>{if(!p){p=!0;try{await g.dispose()}catch{}}};try{await g.arm();let h=g.getCompositor();if(s&&h){let w=h;s.fn=P=>w.commitAbove(P)}r.rearmStatus?.();let b=e.attachments.length===0?e.text:Fh(e.text,e.attachments),v=t.sendMessageStream(b);if(await yn(g.sink,async()=>{for await(let w of v){if(w.type==="chunk"&&w.chunk.type==="content"?(i+=w.chunk.content,l=!0):w.type==="message"&&!l&&(i=w.message.content),w.type==="error"){await y(),console.error(Qt(w.error.message,w.error.stack)),u=!0;continue}g.process(w),w.type==="done"&&(m=!0,f=w.metadata)}}),!p){let w=g.getCompositor();if(w)try{let{text:P,queued:T}=w.getBuffer();T&&P.length>0&&(c=P)}catch{}}if(await y(),m&&(Pa(n,a,i,f),r.onTurnComplete&&await r.onTurnComplete(a,i).catch(()=>{}),l&&console.log(`
1480
+ `),Uh(f,n),r.onAfterTurn)){let w=r.onAfterTurn();w instanceof Promise&&await w.catch(()=>{})}}catch(h){await y(),u||console.error(Qt(h instanceof Error?h.message:"Unknown error",h instanceof Error&&h.stack?h.stack:void 0))}finally{await y(),s&&(s.fn=h=>console.log(h)),r.setInFlight(!1),r.rearmStatus?.()}return c}function Uh(e,t){if(!e)return;let n=[];e.durationMs&&n.push(he(e.durationMs)),e.totalCostUsd!==void 0&&n.push(pe(e.totalCostUsd));let r=Number(e.usage?.input_tokens??0),o=Number(e.usage?.output_tokens??0);r+o>0&&n.push(O(r+o)+" tok"),n.length>0&&console.log(d.dim(" \u25E6 "+n.join(" \xB7 ")));let s=so(t);if(s>.5){let a=s>.8?d.error:d.warning;console.log(a(` context ${Math.round(s*100)}% used of ${O(ot(t.model))}`))}console.log()}function Vl(e={}){let t=e.load??qn,n=e.onResize??(a=>wt.subscribe(a)),r="",o,s=n(()=>{r=""});return{renderIfChanged(a){let i=a??"unbound",l=t(i),c=Ua(l);return i===o&&c===r?[]:(o=i,r=c,c===""?[]:Jn(l))},invalidate(){r=""},dispose(){try{s()}catch{}}}}function Nh(e,t){let n=d.brand("afk")+d.dim(` (${e})`),r=t?d.warning(" \u25CF plan"):"";return n+r+d.dim(" \u203A ")}async function Yl(e,t,n,r){let o=null,s=[];e.session.waitForInitialization().then(async l=>{$t()&&(o=Yn(l)),await qa(e.session),s=Ya()}).catch(()=>{});let a,i=Vl();try{for(;;){if(o&&(console.log(o),console.log(),o=null),s.length>0){for(let m of s)console.log(m);console.log(),s=[]}let l=i.renderIfChanged(e.stats.sessionId);if(l.length>0){for(let m of l)console.log(m);console.log()}let c=await Gl({rl:e.rl,promptFn:()=>Nh(e.stats.model,e.stats.planMode),onSigint:r,...a!==void 0?{initialBuffer:a}:{}});a=void 0;let u=c.text.trim(),p=c.attachments;if(!(!u&&p.length===0)){if(u.startsWith("/")){let m=await xa(u,e.slashCtx);if(m.handled){if(m.result==="exit"){e.rl.close();return}(u==="/clear"||u.startsWith("/clear "))&&(await t.rotateOnClear(),console.log(d.dim(` transcript: ${t.path()}`))),e.statusLine.rearm();continue}}a=await zl({text:u,attachments:p},e.session,e.stats,{setInFlight(m){n.turnInFlight=m},async onTurnComplete(m,f){await t.appendTurn(m,f)},async onAfterTurn(){await e.contextSampler.onTurn(e.stats.totalTurns),e.statusLine.rearm()},rearmStatus:()=>e.statusLine.rearm()},e.options.thinkingUi,e.completionWriter)}}}finally{i.dispose()}}import{execFile as jh}from"node:child_process";import{promisify as Bh}from"node:util";import{promises as ql}from"node:fs";import{dirname as Hh,isAbsolute as Wh,join as Jl,resolve as Kh}from"node:path";import{randomBytes as Gh}from"node:crypto";var zh=Bh(jh);function wr(e){return e instanceof Error}function Vh(e){let t=l=>String(l).padStart(2,"0"),n=String(e.getFullYear()),r=t(e.getMonth()+1),o=t(e.getDate()),s=t(e.getHours()),a=t(e.getMinutes()),i=t(e.getSeconds());return`${n}${r}${o}-${s}${a}${i}`}function Yh(){let e=Vh(new Date),t=Gh(3).toString("hex");return`afk/${e}-${t}`}function qh(e){if(e.trim().length===0)throw new Error("Invalid branch name: '' \u2014 branch name cannot be empty.");if(e.startsWith("-"))throw new Error(`Invalid branch name: '${e}' \u2014 must not start with '-' (would be parsed by git as a flag).`);if(e==="HEAD")throw new Error("Invalid branch name: 'HEAD' \u2014 reserved by git.");if(e.includes(".."))throw new Error(`Invalid branch name: '${e}' \u2014 must not contain '..'.`);let n=[{char:"~",label:"'~'"},{char:"^",label:"'^'"},{char:":",label:"':'"},{char:"?",label:"'?'"},{char:"*",label:"'*'"},{char:"[",label:"'['"},{char:"\\",label:"'\\'"},{char:"\0",label:"NUL byte"}];for(let{char:r,label:o}of n)if(e.includes(r))throw new Error(`Invalid branch name: '${e}' \u2014 must not contain ${o}.`);if(/\s/.test(e))throw new Error(`Invalid branch name: '${e}' \u2014 must not contain whitespace.`)}async function Jh(e){let t;try{t=(await e("git",["rev-parse","--git-common-dir"])).stdout.trim()}catch{throw new Error("Not in a git repository (run from inside a git checkout).")}if(!t)throw new Error("Not in a git repository (run from inside a git checkout).");let n=Wh(t)?t:Kh(process.cwd(),t);return Hh(n)}async function Qh(e){let t=Jl(e,".gitignore"),n=".afk-worktrees/",r="";try{r=await ql.readFile(t,"utf8")}catch(a){if(a.code!=="ENOENT")throw a;r=""}if(r.split(`
1481
+ `).some(a=>a.trim()===n))return;let s=r;s.length>0&&!s.endsWith(`
1482
+ `)&&(s+=`
1483
+ `),s+=`${n}
1484
+ `,await ql.writeFile(t,s,"utf8")}function Xh(e,t,n){if(!wr(e))return new Error(`git worktree add failed: ${String(e)}`);let r=e.stderr??"",o=e.message??"",s=`${r}
1485
+ ${o}`;return s.includes("already checked out")||s.includes("is already used by worktree")?new Error(`Branch '${t}' is already checked out in another worktree. Pick a different name.`):s.includes("already exists")?new Error(`Worktree path '${n}' already exists. Remove it or pick a different branch name.`):new Error(o||r||"git worktree add failed")}async function Ql(e,t){let n=t?.execFile??zh,r=await Jh(n),o=e===!0?Yh():e;qh(o);let s=o.replaceAll("/","-"),a=Jl(r,".afk-worktrees",s);await Qh(r);try{await n("git",["-C",r,"worktree","add","-b",o,a])}catch(l){throw Xh(l,o,a)}return{path:a,branch:o,cleanup:async()=>{let l;try{l=await n("git",["-C",a,"status","--porcelain"])}catch(c){let u=wr(c)?c.message||c.stderr||"":String(c);console.warn(`Worktree cleanup: could not check status at ${a} (${u}). Skipping removal \u2014 manual cleanup may be needed.`);return}if(l.stdout.trim().length>0){console.log(`Worktree preserved at ${a} (branch: ${o}) \u2014 uncommitted changes.`);return}try{await n("git",["-C",r,"worktree","remove","--force",a])}catch(c){let u=wr(c)?c.message||c.stderr||"":String(c);console.warn(`Worktree cleanup: 'git worktree remove --force ${a}' failed (${u}). Manual removal may be needed.`);return}try{await n("git",["-C",r,"branch","-d",o])}catch(c){let u=wr(c)?c.message||c.stderr||"":String(c);console.warn(`Could not delete branch '${o}': ${u}`)}}}}function ey(e){if(e==="summary"||e==="live"||e==="off")return e;throw new Error(`Invalid --thinking-ui value: ${e}. Expected summary|live|off`)}function Xl(e){e.command("interactive",{isDefault:!0}).description("Start interactive chat session").option("-m, --model <model>","Model to use. Short aliases: opus|opus_1m|sonnet|sonnet_1m|haiku. Any other value (e.g. `auto` for cursor-api-proxy, or a full `claude-*` ID) passes through to the SDK/proxy untouched.",Ce()).option("--max-turns <number>","Maximum conversation turns","100").option("--thinking <mode>","Thinking mode: 'adaptive' | 'disabled' | 'enabled:<N>'","adaptive").option("--thinking-ui <mode>","Thinking display mode: summary|live|off",ey,"live").option("--effort <level>","Effort level: low|medium|high|xhigh|max").option("--max-output-tokens <n|max>","Per-response output cap ('max' = model ceiling). Env: AFK_MAX_OUTPUT_TOKENS").option("--resume <id>","Resume a persisted SDK session by id").option("--continue","Continue the most recent persisted session in cwd").option("--debug","Show SDK init metadata on startup; enables /debug command",!1).option("-w, --worktree [branch]","Create a git worktree for an isolated session. Optional value sets the branch name; otherwise auto-named. On clean exit (no uncommitted changes) the worktree and branch are auto-removed; on dirty exit the worktree is preserved.").option("--provider <name>","Provider to use: anthropic|anthropic-direct|openai-codex. Default: auto-selected by model").action(async t=>{t.debug&&(process.env.AFK_DEBUG="1");let n=Zh({text:"Initializing interactive session...",...Vn}).start(),r,o;if(t.worktree!==void 0)try{o=await Ql(t.worktree),r=o.path,n.text=`Worktree ready at ${o.path} (branch: ${o.branch})`}catch(u){n.fail("Worktree setup failed"),console.error(d.error(u instanceof Error?u.message:String(u))),process.exit(1)}let s;try{s=await Ol(t,r!==void 0?{cwd:r}:void 0)}catch(u){n.fail("Invalid options"),console.error(d.error(u instanceof Error?u.message:String(u))),process.exit(1)}Xt(async()=>{await s.session.close(),o!==void 0&&await o.cleanup()}),n.succeed("Session ready");let a=await Fl(()=>s.stats.model);console.log(d.dim(` transcript: ${a.path()}`)),Xt(async()=>{await a.appendEnded()}),Xt(async()=>{if(s.stats.totalTurns!==0)try{Gn(s.stats)}catch{}});let i={turnInFlight:!1,lastSigintAt:0},l=1500,c=()=>{let u=Date.now();if(i.turnInFlight){s.session.interrupt().catch(()=>{}),i.lastSigintAt=u,console.log(`
1486
+ `+d.warning("\u26A0 Interrupted. Press Ctrl+C again to exit."));return}if(u-i.lastSigintAt<l){s.rl.close();return}i.lastSigintAt=u,console.log(`
1487
+ `+d.info("\u2139 ")+"Press Ctrl+C again (or /exit) to quit.")};process.on("SIGINT",c),Xt(async()=>{process.removeListener("SIGINT",c)}),process.stdout.write("\x1B[3J\x1B[2J\x1B[H"),console.log(`
1488
+ `+ha({mode:`Interactive Mode (${t.model})`,hintLine:"Type /help for commands \xB7 Ctrl+C to interrupt \xB7 /exit to quit"})),console.log(),s.statusLine.start(),s.slashCtx.ui.repaintStatusLine(),s.rl.on("close",async()=>{s.statusLine.stop(),ty(s),console.log(d.info("\u2139 ")+"Goodbye!"),await ya(),process.exit(0)}),await Yl(s,a,i,c)})}function ty(e){if(e.stats.totalTurns===0)return;console.log(`
1489
+ `+Z("Session Summary"));let t=[`${e.stats.totalTurns} turn${e.stats.totalTurns===1?"":"s"}`,he(Date.now()-e.stats.sessionStartTime)];e.stats.totalCostUsd>0&&t.push(pe(e.stats.totalCostUsd)),e.stats.totalTokens>0&&t.push(O(e.stats.totalTokens)+" tokens"),console.log(d.dim(" "+t.join(" \xB7 "))),console.log()}import ny from"chalk";import ry from"ora";function Zl(e){e.command("status").description("Check agent connection status").option("-f, --format <format>","Output format (text|json)","text").action(async t=>{let n=ry("Checking status...").start();try{let r=Ce(),o=Pe(r),s=di(r);if(await new ue({model:o==="openai-codex"?"gpt-5.4-mini":"haiku",...s!==void 0?{apiKey:s}:{},maxTurns:1}).close(),n.succeed(`${o} provider reachable`),t.format==="json"){let i=N(),l=Bt(),c=i?process.env.ANTHROPIC_API_KEY?"ANTHROPIC_API_KEY":"CLAUDE_CODE_OAUTH_TOKEN":null,u=l?process.env.OPENAI_API_KEY?"OPENAI_API_KEY":"CODEX_API_KEY":null;console.log(JSON.stringify({providers:{anthropic:{ok:!!i,source:c},codex:{ok:!!l,source:u}},model:String(r),bypass:!0},null,2))}else console.log(`
1490
+ `+ga("Agent AFK \xB7 Status",[{label:"Provider",value:o,kind:"info"},{label:"Auth",value:o==="openai-codex"?s?"Found (OPENAI_API_KEY / CODEX_API_KEY)":"Using `codex login` state on disk":s?"Found (ANTHROPIC_API_KEY)":"Falling back to Claude OAuth",kind:s?"ok":"warn"},{label:"Model",value:String(r),kind:"info"},{label:"Bypass",value:"Permissions disabled",kind:"warn"}])+`
1491
+ `)}catch(r){n.fail("Connection failed"),console.error(ny.red(r instanceof Error?r.message:"Unknown error")),process.exit(1)}})}import ee from"chalk";function ec(e){e.command("config").description("View current configuration").option("-f, --format <format>","Output format (text|json)","text").action(t=>{let n=process.env.AFK_MODEL??process.env.CLAUDE_MODEL,r=n??"sonnet",o=Pe(n),s=process.env.ANTHROPIC_API_KEY||process.env.CLAUDE_CODE_OAUTH_TOKEN,a=process.env.OPENAI_API_KEY||process.env.CODEX_API_KEY,i=o==="anthropic"?s:a,l=s?process.env.ANTHROPIC_API_KEY?"ANTHROPIC_API_KEY":"CLAUDE_CODE_OAUTH_TOKEN":null,c=a?process.env.OPENAI_API_KEY?"OPENAI_API_KEY":"CODEX_API_KEY":null;if(t.format==="json")console.log(JSON.stringify({model:r,provider:o,apiKey:{present:!!i,source:o==="anthropic"?l:c},thinking:process.env.AFK_THINKING||null,effort:process.env.AFK_EFFORT||null,bypass:!0,raw_env:{AFK_MODEL:process.env.AFK_MODEL??null,AFK_THINKING:process.env.AFK_THINKING??null,AFK_EFFORT:process.env.AFK_EFFORT??null,ANTHROPIC_API_KEY:process.env.ANTHROPIC_API_KEY?"set":"unset",CLAUDE_CODE_OAUTH_TOKEN:process.env.CLAUDE_CODE_OAUTH_TOKEN?"set":"unset",OPENAI_API_KEY:process.env.OPENAI_API_KEY?"set":"unset",CODEX_API_KEY:process.env.CODEX_API_KEY?"set":"unset"}},null,2));else{console.log(ee.cyan(`\u{1F4CB} Current Configuration:
1492
+ `)),console.log(` Model: ${ee.blue(n?r:r+" (default)")}`),console.log(` Provider: ${ee.magenta(o)}`),console.log(o==="anthropic"?` API Key: ${i?ee.green("\u2713 Set (ANTHROPIC_API_KEY / CLAUDE_CODE_OAUTH_TOKEN)"):ee.yellow("\u26A0 Not set \u2014 subprocess will fall back to OAuth / keychain")}`:` API Key: ${i?ee.green("\u2713 Set (OPENAI_API_KEY / CODEX_API_KEY)"):ee.yellow("\u26A0 Not set \u2014 falling back to `codex login` state")}`);let u=process.env.AFK_THINKING||"(unset \u2014 SDK default)";console.log(` Thinking: ${ee.blue(u)}`);let p=process.env.AFK_EFFORT||"(unset \u2014 SDK default)";console.log(` Effort: ${ee.blue(p)}`),console.log(` Bypass Permissions: ${ee.yellow("true (enabled)")}`),console.log(ee.gray(`
1493
+ Environment variables:`)),console.log(ee.gray(" AFK_MODEL - Default model id (canonical; accepts short aliases or full ids)")),console.log(ee.gray(" CLAUDE_MODEL - Legacy alias for AFK_MODEL (Claude-only deployments)")),console.log(ee.gray(" ANTHROPIC_API_KEY - Anthropic API key (Claude models)")),console.log(ee.gray(" CLAUDE_CODE_OAUTH_TOKEN - Anthropic OAuth token (Claude models)")),console.log(ee.gray(" OPENAI_API_KEY / CODEX_API_KEY - OpenAI API key (Codex models)")),console.log(ee.gray(" AFK_THINKING - Thinking mode (Claude only: adaptive|disabled|enabled:<N>)")),console.log(ee.gray(" AFK_EFFORT - Effort level (low|medium|high|xhigh|max)")),console.log(ee.gray(" AFK_TIMEOUT_MS - Per-tick daemon session timeout in ms")),console.log(ee.gray(" AFK_SESSIONSTART_COOLDOWN_MS - Phase 6 cooldown between sessionstart fires (default 6h)")),console.log("")}})}import ve from"chalk";import{createServer as dy}from"node:http";import{mkdirSync as ly,appendFileSync as cy}from"node:fs";import{dirname as uy}from"node:path";import*as ic from"node-cron";function tc(e){if(!e.taskId)throw new Error("ScheduledTask.taskId is required");if(!e.command)throw new Error(`task ${e.taskId}: command is required`);if((e.trigger==="cron"||e.trigger==="both")&&!e.cronExpression)throw new Error(`task ${e.taskId}: cronExpression required for trigger=${e.trigger}`)}import{existsSync as nc,readFileSync as oy,readdirSync as sy}from"node:fs";var rc=360*60*1e3;function oc(){return Uo()}function iy(e,t){if(!nc(t))return null;let n;try{n=oy(t,"utf-8")}catch{return null}let r=n.split(`
1494
+ `);for(let o=r.length-1;o>=0;o-=1){let s=r[o];if(s)try{let a=JSON.parse(s);if(a.taskId!==e||typeof a.triggeredAt!="string")continue;let i=Date.parse(a.triggeredAt);if(Number.isNaN(i))continue;return i}catch{continue}}return null}function ay(e){if(!nc(e))return 0;try{return sy(e).filter(t=>!t.startsWith(".")).length}catch{return 0}}function sc(e){let t=iy(e.taskId,e.telemetryPath);if(t!==null&&e.cooldownMs>0){let r=e.nowMs-t;if(r<e.cooldownMs)return{fire:!1,skipReason:"cooldown",lastFiredAtMs:t,cooldownRemainingMs:e.cooldownMs-r}}let n=ay(e.briefsDir);return n>0?{fire:!1,skipReason:"briefs_pending",pendingBriefCount:n,...t!==null?{lastFiredAtMs:t}:{}}:{fire:!0,...t!==null?{lastFiredAtMs:t}:{}}}var vr=class{registry=new Map;options;defaultCooldownMs;briefsDir;now;constructor(t={}){this.options=t,this.defaultCooldownMs=t.cooldownMs??rc,this.briefsDir=t.briefsDir??oc(),this.now=t.now??Date.now,this.ensureTelemetrySink()}register(t){if(tc(t),this.registry.has(t.taskId))throw new Error(`task ${t.taskId} is already registered`);let n;(t.trigger==="cron"||t.trigger==="both")&&(n=ic.schedule(t.cronExpression,()=>{this.runOnce(t,"cron").catch(()=>{})},{name:t.taskId})),this.registry.set(t.taskId,{task:t,cronTask:n})}unregister(t){let n=this.registry.get(t);n&&(n.cronTask&&(Promise.resolve(n.cronTask.stop()).catch(()=>{}),Promise.resolve(n.cronTask.destroy()).catch(()=>{})),this.registry.delete(t))}list(){return Array.from(this.registry.values()).map(t=>t.task)}async tick(t){let n=this.registry.get(t);if(!n)throw new Error(`task ${t} is not registered`);return this.runOnce(n.task,"cron")}async fireOnStart(){let t=Array.from(this.registry.values()).map(r=>r.task).filter(r=>r.trigger==="sessionstart"||r.trigger==="both"),n=[];for(let r of t){let o=r.debounceMs??this.defaultCooldownMs,s=sc({taskId:r.taskId,cooldownMs:o,nowMs:this.now(),telemetryPath:this.telemetryPath(),briefsDir:this.briefsDir});s.fire?n.push(await this.runOnce(r,"sessionstart")):n.push(this.recordSkip(r,s))}return n}async stop(){for(let t of Array.from(this.registry.keys()))this.unregister(t)}async runOnce(t,n){let r=new Date(this.now()),o=this.now(),s={taskId:t.taskId,command:t.command,trigger:n,...t.cronExpression!==void 0?{cronExpression:t.cronExpression}:{},triggeredAt:r.toISOString()},a=null;try{a=this.spawnSession();let i=await a.sendMessage(t.command),l={...s,durationMs:this.now()-o,status:"success",responseExcerpt:i.content.slice(0,280)};return this.writeTelemetry(l),l}catch(i){let l=i instanceof Error?i.message:String(i),c={...s,durationMs:this.now()-o,status:"error",errorMessage:l};return this.writeTelemetry(c),c}finally{if(a)try{await a.close()}catch{}}}recordSkip(t,n){let r=new Date(this.now()),o={taskId:t.taskId,command:t.command,trigger:"sessionstart",...t.cronExpression!==void 0?{cronExpression:t.cronExpression}:{},triggeredAt:r.toISOString(),durationMs:0,status:"skipped",...n.skipReason!==void 0?{skipReason:n.skipReason}:{}};return this.writeTelemetry(o),o}spawnSession(){let t={model:"sonnet",hookRegistry:yt(),...this.options.sessionConfig};return this.options.sessionFactory?this.options.sessionFactory(t):new ue(t)}telemetryPath(){return this.options.telemetryPath??Fo()}ensureTelemetrySink(){try{ly(uy(this.telemetryPath()),{recursive:!0})}catch{}}writeTelemetry(t){try{cy(this.telemetryPath(),`${JSON.stringify(t)}
1495
+ `,"utf-8")}catch(n){let r=n instanceof Error?n.message:String(n);console.error(`[daemon] telemetry write failed: ${r}`)}}};var py=7777;async function ac(e={}){let t=new vr({...e.sessionConfig!==void 0?{sessionConfig:e.sessionConfig}:{},...e.telemetryPath!==void 0?{telemetryPath:e.telemetryPath}:{},...e.sessionFactory!==void 0?{sessionFactory:e.sessionFactory}:{},...e.cooldownMs!==void 0?{cooldownMs:e.cooldownMs}:{},...e.briefsDir!==void 0?{briefsDir:e.briefsDir}:{},...e.now!==void 0?{now:e.now}:{}});for(let o of e.tasks??[])t.register(o);let n=dy((o,s)=>my(o,s,t));return{port:await fy(n,e.port??py),scheduler:t,registerTask(o){t.register(o)},unregisterTask(o){t.unregister(o)},tickOnce(o){return t.tick(o)},fireOnStart(){return t.fireOnStart()},async stop(){await t.stop(),await gy(n)}}}function my(e,t,n){let r=e.url??"/";if(e.method==="GET"&&r==="/health"){let o=JSON.stringify({status:"ok",tasks:n.list().length});t.writeHead(200,{"Content-Type":"application/json"}),t.end(o);return}if(e.method==="GET"&&r==="/tasks"){t.writeHead(200,{"Content-Type":"application/json"}),t.end(JSON.stringify(n.list()));return}t.writeHead(404,{"Content-Type":"application/json"}),t.end(JSON.stringify({error:"not found"}))}function fy(e,t){return new Promise((n,r)=>{e.once("error",r),e.listen(t,()=>{e.removeListener("error",r);let o=e.address();n(typeof o=="object"&&o?o.port:t)})})}function gy(e){return new Promise((t,n)=>{e.close(r=>{r?n(r):t()})})}function lc(e,t){let n=e??t;if(n===void 0||n==="")return;let r=Number(n);if(!Number.isFinite(r)||!Number.isInteger(r)||r<=0)throw new Error(`Invalid timeout-ms: '${n}' \u2014 must be a positive integer (milliseconds).`);return r}function cc(e,t){let n=e??t;if(n===void 0||n==="")return;let r=Number(n);if(!Number.isFinite(r)||!Number.isInteger(r)||r<0)throw new Error(`Invalid sessionstart-cooldown-ms: '${n}' \u2014 must be a non-negative integer (milliseconds).`);return r}function uc(e){if(e===void 0||e==="")return"cron";if(e==="cron"||e==="sessionstart"||e==="both")return e;throw new Error(`Invalid trigger: '${e}' \u2014 must be one of cron | sessionstart | both.`)}var Co="/forge-friction --auto",Io="default";function It(e){if(e!==void 0&&e.trim()!=="")return e}function dc(e,t,n){return It(e)??It(t)??It(n)??Co}function pc(e,t,n){return It(e)??It(t)??It(n)??Io}function mc(e){e.command("daemon").description("Run agent-afk as a daemon that fires scheduled tasks (e.g. /forge-friction --auto)").option("-p, --port <number>","Control HTTP port","7777").option("-t, --task <command>",`Command to fire on each tick (default: ${Co})`).option("-c, --cron <expression>",'Cron expression (e.g. "0 */6 * * *"). Required when --trigger includes cron.').option("-i, --task-id <id>",`Task identifier (default: ${Io})`).option("--once","Fire one tick and exit (for testing)",!1).option("--timeout-ms <ms>","Per-tick session timeout in ms. Overrides AFK_TIMEOUT_MS. Defaults to the session default (120000).").option("--thinking <mode>","Thinking mode: 'adaptive' | 'disabled' | 'enabled:<N>'").option("--effort <level>","Effort level: low|medium|high|xhigh|max").option("--trigger <mode>","Trigger mode: cron | sessionstart | both. Defaults to cron.").option("--sessionstart-cooldown-ms <ms>","Cooldown between Phase 6 sessionstart fires. Overrides AFK_SESSIONSTART_COOLDOWN_MS. Defaults to 6h.").option("--briefs-dir <path>","Override directory scanned for pending briefs (defaults to ~/.afk/agent-framework/briefs).").action(async t=>{let n=parseInt(t.port,10);(Number.isNaN(n)||n<=0)&&(console.error(ve.red(`Invalid port: ${t.port}`)),process.exit(1));let r=ct(),o=dc(t.task,process.env.AFK_DAEMON_TASK,r.daemon?.task),s=pc(t.taskId,process.env.AFK_DAEMON_TASK_ID,r.daemon?.taskId),a,i,l;try{a=lc(t.timeoutMs,process.env.AFK_TIMEOUT_MS),i=cc(t.sessionstartCooldownMs,process.env.AFK_SESSIONSTART_COOLDOWN_MS),l=uc(t.trigger)}catch(m){console.error(ve.red(m instanceof Error?m.message:String(m))),process.exit(1)}(l==="cron"||l==="both")&&!t.cron&&(console.error(ve.red(`--cron is required when --trigger is '${l}'.`)),process.exit(1));let c,u;try{c=He(t.thinking)??dt(),u=We(t.effort)??pt()}catch(m){console.error(ve.red(m instanceof Error?m.message:String(m))),process.exit(1)}let p={taskId:s,command:o,trigger:l,...t.cron!==void 0?{cronExpression:t.cron}:{}};try{let m=await ac({port:n,sessionConfig:{model:Ce(),...N()!==void 0?{apiKey:N()}:{},...a!==void 0?{timeoutMs:a}:{},...c!==void 0?{thinking:c}:{},...u!==void 0?{effort:u}:{}},...i!==void 0?{cooldownMs:i}:{},...t.briefsDir!==void 0?{briefsDir:t.briefsDir}:{},tasks:[p]});if(t.once){console.log(ve.cyan(`\u25B6 Firing task '${s}' once...`));let g=await m.tickOnce(s);console.log(JSON.stringify(g,null,2)),await m.stop(),process.exit(g.status==="success"?0:1)}if(l==="sessionstart"||l==="both"){let g=await m.fireOnStart();for(let y of g){let h=y.status==="success"?"\u2714":y.status==="skipped"?"\u23ED":"\u2717";console.log(ve.cyan(`${h} sessionstart: ${JSON.stringify(y)}`))}}console.log(ve.green(`\u2714 Daemon listening on http://localhost:${m.port}`)),console.log(ve.dim(` task='${s}' command='${o}' trigger='${l}'${t.cron?` cron='${t.cron}'`:""}`)),console.log(ve.dim(" Press Ctrl+C to stop."));let f=async()=>{console.log(ve.dim(`
1496
+ \xB7 Shutting down daemon...`)),await m.stop(),process.exit(0)};process.on("SIGINT",f),process.on("SIGTERM",f)}catch(m){console.error(ve.red(m instanceof Error?m.message:String(m))),process.exit(1)}})}import Fe from"chalk";import{createInterface as hy}from"readline";import{existsSync as yy,readFileSync as ky,writeFileSync as by,mkdirSync as wy}from"fs";import{dirname as vy}from"path";function Sy(e,t,n,r=[]){wy(vy(e),{recursive:!0});let o="";yy(e)&&(o=ky(e,"utf-8"));for(let i of r){let l=new RegExp(`^${i}=.*$
1497
+ ?`,"m");o=o.replace(l,"")}let s=`${t}=${n}`,a=new RegExp(`^${t}=.*$`,"m");a.test(o)?o=o.replace(a,s):(o&&!o.endsWith(`
1498
+ `)&&(o+=`
1499
+ `),o+=s+`
1500
+ `),by(e,o,{mode:384})}function xy(){let e=hy({input:process.stdin,output:process.stdout});return new Promise(t=>{e.question("Anthropic API key or OAuth token: ",n=>{e.close(),t(n.trim())})})}function fc(e){e.command("login [token]").description("Save an Anthropic API key or OAuth token for afk to use").action(async t=>{if(Pe(Ce())==="openai-codex"){console.log(Fe.yellow("`afk login` is Anthropic-only.")),console.log(""),console.log("For Codex-backed models (gpt-*, o1*, o3*, o4*, codex-*), authenticate with one of:"),console.log(Fe.cyan(" codex login")),console.log(Fe.cyan(" codex login --device-auth")),console.log("or export an API key before running afk:"),console.log(Fe.cyan(" export OPENAI_API_KEY=sk-proj-...")),console.log(Fe.cyan(" # or: export CODEX_API_KEY=...")),console.log(""),console.log(Fe.gray("To save an Anthropic key for Claude models instead, re-run with AFK_MODEL=sonnet (or similar) first."));return}let r=t??await xy();r||(console.error(Fe.red("No token provided. Nothing saved.")),process.exit(1));let o=it(),s,a;r.startsWith("sk-ant-oat")?(s="CLAUDE_CODE_OAUTH_TOKEN",a=["ANTHROPIC_API_KEY"]):(s="ANTHROPIC_API_KEY",a=["CLAUDE_CODE_OAUTH_TOKEN"]),Sy(o,s,r,a),console.log(Fe.green(`\u2713 Saved ${s} to ${o}`)),console.log(Fe.gray("Restart any running afk daemon to pick up the new token."))})}import D from"chalk";import Sr from"ora";import{existsSync as Ty}from"fs";import{join as Ey}from"path";async function Ao(e,t={},n={}){let r=n.pluginsDir??ae(),o=n.indexPath??F(),s=n.now??(()=>new Date),a=n.gitRunner?{runner:n.gitRunner}:{},l=B(o).plugins[e];if(!l)throw new Error(`plugin "${e}" is not installed`);let c=Ey(r,e);if(!Ty(c))return{name:e,status:"missing-dir",dir:c};if(l.sourceType==="local")return{name:e,status:"skipped-local"};await ar(c,a);let u;if(t.ref)u=t.ref;else{let g=await Qe(c,a);u=Ze(g)??l.ref??await Ae(c,a)}if(u===l.ref){let g=await Ie(c,a);return{name:e,status:"up-to-date",ref:u,commit:g}}await Xe(c,u,a);let p=await Ie(c,a),m=s().toISOString(),f={...l,ref:u,commit:p,updatedAt:m};return Ue(e,f,o),{name:e,status:"updated",fromRef:l.ref,toRef:u,commit:p}}async function gc(e={}){let t=e.indexPath??F(),n=B(t),r=[];for(let o of Object.keys(n.plugins))try{r.push(await Ao(o,{},e))}catch(s){let a=s instanceof Error?s.message:String(s);r.push({name:o,status:"missing-dir",dir:a})}return r}import{existsSync as Py,lstatSync as Cy,rmSync as Iy,unlinkSync as Ay}from"fs";import{join as My}from"path";function hc(e,t={}){let n=t.pluginsDir??ae(),r=t.indexPath??F(),o=My(n,e),s=!1;Ry(o)?(Ay(o),s=!0):Py(o)&&(Iy(o,{recursive:!0,force:!0}),s=!0);let a=B(r),i=Object.prototype.hasOwnProperty.call(a.plugins,e);return i&&Es(e,r),{name:e,removedDir:s,removedIndexEntry:i}}function Ry(e){try{return Cy(e).isSymbolicLink()}catch{return!1}}function yc(e,t={}){let n=t.logger??console,r=t.pluginsDir??ae(),o=t.indexPath??F(),s={...t,pluginsDir:r,indexPath:o},a=e.command("plugin").description("Manage AFK plugins (install / update / list / remove / enable / disable)");a.command("install <source> [name]").description("Install a plugin from a git URL, owner/repo shorthand, local path, or <marketplace>:<plugin>").option("-r, --ref <ref>","Install a specific tag, branch, or SHA").option("-f, --force","Replace an existing plugin with the same name").action(async(i,l,c)=>{let u;try{u=Tt(i)}catch(m){Sr(`Installing ${i}\u2026`).start().fail(D.red(`Install failed: ${At(m)}`)),process.exitCode=1;return}if(u.type==="marketplace-ref"){let m=Sr(`Installing ${u.marketplace}:${u.plugin}\u2026`).start();try{let f=await Ct(u.marketplace,u.plugin,{...c.ref?{ref:c.ref}:{},...c.force?{force:!0}:{}},s);m.succeed(D.green(`Installed ${D.bold(f.key)}`)+D.gray(` at ${f.dir}`))}catch(f){m.fail(D.red(`Install failed: ${At(f)}`)),process.exitCode=1}return}let p=Sr(`Installing ${i}\u2026`).start();try{let m={...l?{name:l}:{},...c.ref?{ref:c.ref}:{},...c.force?{force:!0}:{}},f=await mr(i,m,s);p.succeed(D.green(`Installed ${D.bold(f.name)}`)+D.gray(` at ${f.dir}${f.entry.ref?` (ref: ${f.entry.ref})`:""}`))}catch(m){p.fail(D.red(`Install failed: ${At(m)}`)),process.exitCode=1}}),a.command("update [name]").description("Update one plugin, or all if no name is given").option("-r, --ref <ref>","Pin to a specific ref instead of the latest tag").action(async(i,l)=>{try{if(i){let c=Sr(`Updating ${i}\u2026`).start(),u=await Ao(i,l.ref?{ref:l.ref}:{},s);$y(u,c)}else{n.log(D.cyan("Updating all plugins\u2026"));let c=await gc(s);if(c.length===0){n.log(D.gray(" (nothing installed)"));return}for(let u of c)n.log(" "+kc(u))}}catch(c){n.error(D.red(`Update failed: ${At(c)}`)),process.exitCode=1}}),a.command("list").description("List installed plugins with their source, version, and enabled state").option("-f, --format <format>","Output format (text|json)","text").action(i=>{let l=B(o);if(i.format==="json"){let c=Object.entries(l.plugins).map(([u,p])=>({name:u,enabled:p.enabled,...p.ref?{ref:p.ref}:{},source:p.source}));n.log(JSON.stringify({plugins:c},null,2))}else _y(l,n)}),a.command("remove <name>").description("Remove a plugin (directory + index entry)").action(i=>{let l=hc(i,{pluginsDir:r,indexPath:o});if(!l.removedDir&&!l.removedIndexEntry){n.log(D.gray(`No plugin named "${i}" to remove.`));return}let c=[l.removedDir?"directory":null,l.removedIndexEntry?"index entry":null].filter(Boolean);n.log(D.green(`Removed ${i}: ${c.join(" + ")}`))}),a.command("enable <name>").description("Re-enable a previously disabled plugin").action(i=>{try{Ar(i,!0,o),n.log(D.green(`Enabled ${i}`))}catch(l){n.error(D.red(`Enable failed: ${At(l)}`)),process.exitCode=1}}),a.command("disable <name>").description("Keep the plugin on disk but skip it from SDK init").action(i=>{try{Ar(i,!1,o),n.log(D.yellow(`Disabled ${i} (dir preserved at ${r}/${i})`))}catch(l){n.error(D.red(`Disable failed: ${At(l)}`)),process.exitCode=1}})}function At(e){return e instanceof Error?e.message:String(e)}function _y(e,t){let n=Object.keys(e.plugins).sort();if(n.length===0){t.log(D.gray("No plugins installed.")),t.log(D.gray(" Try: afk plugin install anthropics/claude-plugins-official"));return}t.log(D.cyan.bold(`
1501
+ Installed plugins:`));for(let r of n){let o=e.plugins[r];if(!o)continue;let s=o.enabled?D.green("enabled "):D.yellow("disabled"),a=o.ref?D.blue(o.ref):D.gray("(local)"),i=D.gray(o.source);t.log(` ${D.bold(r.padEnd(30))} ${s} ${a.padEnd(12)} ${i}`)}t.log("")}function kc(e){switch(e.status){case"updated":return`${D.green("\u2713")} ${D.bold(e.name)}: ${e.fromRef??"(none)"} \u2192 ${e.toRef}`;case"up-to-date":return`${D.gray("\xB7")} ${D.bold(e.name)}: up-to-date (${e.ref})`;case"skipped-local":return`${D.gray("\xB7")} ${D.bold(e.name)}: skipped (local source)`;case"missing-dir":return`${D.yellow("!")} ${D.bold(e.name)}: plugin dir missing (${e.dir})`}}function $y(e,t){let n=kc(e);e.status==="updated"?t.succeed(n):e.status==="up-to-date"||e.status==="skipped-local"?t.info(n):t.warn(n)}import A from"chalk";import Mo from"ora";function bc(e,t={}){let n=t.logger??console,r=t.cacheDir??Me(),o=t.indexPath??F(),s={...t,cacheDir:r,indexPath:o},a=e.command("marketplace").description("Manage AFK plugin marketplaces (install / list / plugins / install-plugin / remove / update)");a.command("install <source> [name]").description("Clone or symlink a marketplace into the local plugin cache").option("-r, --ref <ref>","Install a specific tag, branch, or SHA").option("-f, --force","Replace an existing marketplace with the same name").action(async(i,l,c)=>{let u=Mo(`Installing marketplace ${i}\u2026`).start();try{let p={...l?{name:l}:{},...c.ref?{ref:c.ref}:{},...c.force?{force:!0}:{}},m=await ur(i,p,s),f=m.entry.ref?` (ref: ${m.entry.ref})`:"";u.succeed(A.green(`Installed marketplace ${A.bold(m.name)}`)+A.gray(`${f} at ${m.dir}`)),n.log(A.gray(` ${m.plugins.length} plugin(s) available \u2014 run \`afk marketplace plugins ${m.name}\` to list.`))}catch(p){u.fail(A.red(`Marketplace install failed: ${xr(p)}`)),process.exitCode=1}}),a.command("list").description("List installed marketplaces with their source and ref").option("-f, --format <format>","Output format (text|json)","text").action(i=>{let l=B(o),c=Object.entries(l.marketplaces);if(i.format==="json"){n.log(JSON.stringify({marketplaces:c.map(([u,p])=>({name:u,source:p.source,sourceType:p.sourceType,...p.ref?{ref:p.ref}:{}}))},null,2));return}if(c.length===0){n.log(A.gray("No marketplaces installed.")),n.log(A.gray(" Try: afk marketplace install griffinwork40/awa-private"));return}n.log(A.cyan.bold(`
1502
+ Installed marketplaces:`));for(let[u,p]of c.sort()){let m=p.ref?A.blue(p.ref):A.gray("(local)"),f=A.gray(p.source);n.log(` ${A.bold(u.padEnd(30))} ${m.padEnd(12)} ${f}`)}n.log("")}),a.command("plugins <name>").description("List plugins inside a marketplace, with [installed] / [available] markers").option("-f, --format <format>","Output format (text|json)","text").action((i,l)=>{try{let c=gr(i,s);if(l.format==="json"){n.log(JSON.stringify({marketplace:i,plugins:c},null,2));return}if(c.length===0){n.log(A.gray(`Marketplace "${i}" lists no plugins.`));return}n.log(A.cyan.bold(`
1503
+ Plugins in ${i}:`)),c.forEach((u,p)=>{let m=u.installed?A.green("[\u2713]"):A.gray("[ ]"),f=u.description?A.gray(` \u2014 ${u.description}`):"";n.log(` ${m} ${A.bold((p+1).toString().padStart(2))}. ${A.bold(u.name)}${f}`)}),n.log(A.gray(`
1504
+ Install one: afk plugin install ${i}:<plugin>`))}catch(c){n.error(A.red(`List failed: ${xr(c)}`)),process.exitCode=1}}),a.command("install-plugin <marketplace> <plugin>").description("Install a single plugin from a marketplace").option("-r, --ref <ref>","For git-sourced plugins, pin to a specific tag/branch/SHA").option("-f, --force","Replace an existing plugin with the same key").action(async(i,l,c)=>{let u=Mo(`Installing ${i}:${l}\u2026`).start();try{let p=await Ct(i,l,{...c.ref?{ref:c.ref}:{},...c.force?{force:!0}:{}},s);u.succeed(A.green(`Installed ${A.bold(p.key)}`)+A.gray(` at ${p.dir}`))}catch(p){u.fail(A.red(`Install failed: ${xr(p)}`)),process.exitCode=1}}),a.command("remove <name>").description("Remove a marketplace and cascade-delete its installed plugins").action(i=>{let l=dr(i,{cacheDir:r,indexPath:o});if(!l.removedDir&&!l.removedIndexEntry&&l.removedPluginEntries.length===0){n.log(A.gray(`No marketplace named "${i}" to remove.`));return}let c=[l.removedDir?"directory":null,l.removedIndexEntry?"index entry":null,l.removedPluginEntries.length>0?`${l.removedPluginEntries.length} plugin entry`:null].filter(Boolean);if(n.log(A.green(`Removed ${i}: ${c.join(" + ")}`)),l.removedPluginEntries.length>0)for(let u of l.removedPluginEntries)n.log(A.gray(` - ${u}`))}),a.command("update [name]").description("Update one marketplace, or all if no name is given").option("-r, --ref <ref>","Pin to a specific ref instead of the latest tag").action(async(i,l)=>{try{if(i){let c=Mo(`Updating ${i}\u2026`).start(),u=await nn(i,l.ref?{ref:l.ref}:{},s);Oy(u,c)}else{n.log(A.cyan("Updating all marketplaces\u2026"));let c=await Pl(s);if(c.length===0){n.log(A.gray(" (no marketplaces installed)"));return}for(let u of c)n.log(" "+wc(u))}}catch(c){n.error(A.red(`Update failed: ${xr(c)}`)),process.exitCode=1}})}function xr(e){return e instanceof Error?e.message:String(e)}function wc(e){switch(e.status){case"updated":{let t=e.addedPlugins.length>0?` +${e.addedPlugins.join(", ")}`:"",n=e.removedPlugins.length>0?` -${e.removedPlugins.join(", ")}`:"";return`${A.green("\u2713")} ${A.bold(e.name)}: ${e.fromRef??"(none)"} \u2192 ${e.toRef}${A.gray(t+n)}`}case"up-to-date":return`${A.gray("\xB7")} ${A.bold(e.name)}: up-to-date (${e.ref})`;case"skipped-local":return`${A.gray("\xB7")} ${A.bold(e.name)}: skipped (local source)`;case"missing-dir":return`${A.yellow("!")} ${A.bold(e.name)}: marketplace dir missing (${e.dir})`}}function Oy(e,t){let n=wc(e);e.status==="updated"?t.succeed(n):e.status==="up-to-date"||e.status==="skipped-local"?t.info(n):t.warn(n)}import{access as Dy,constants as Ly,mkdir as Fy,readFile as Uy}from"fs/promises";async function Ny(){return N()?{name:"Anthropic API Key",state:"pass",detail:"ANTHROPIC_API_KEY set"}:{name:"Anthropic API Key",state:"fail",fix:"Set ANTHROPIC_API_KEY or run `afk login`"}}async function jy(){return Bt()?{name:"Codex/OpenAI API Key",state:"pass",detail:"OPENAI_API_KEY or CODEX_API_KEY set"}:{name:"Codex/OpenAI API Key",state:"warn",fix:"Set OPENAI_API_KEY or CODEX_API_KEY to use Codex models"}}async function Ro(e,t){let n=t();try{return await Dy(n,Ly.W_OK),{name:e,state:"pass",detail:n}}catch{try{return await Fy(n,{recursive:!0}),{name:e,state:"pass",detail:`${n} (created)`}}catch{return{name:e,state:"fail",detail:n,fix:`Unable to create or write to ${n}`}}}}async function By(){let e=at();try{let t=await Uy(e,"utf-8");return JSON.parse(t),{name:"Config File",state:"pass",detail:`${e} (valid JSON)`}}catch(t){return t.code==="ENOENT"?{name:"Config File",state:"pass",detail:"no config file (using defaults)"}:{name:"Config File",state:"fail",detail:e,fix:`Unable to parse config file: ${t instanceof Error?t.message:"unknown error"}`}}}async function Hy(){let e=process.env.AFK_TELEGRAM_BOT_TOKEN;if(!e)return null;try{let t=new AbortController,n=setTimeout(()=>t.abort(),5e3),r=await fetch(`https://api.telegram.org/bot${e}/getMe`,{signal:t.signal});if(clearTimeout(n),r.ok){let s=(await r.json()).result?.username;return{name:"Telegram Bot",state:"pass",detail:s?`@${s}`:"connected"}}return{name:"Telegram Bot",state:"fail",fix:`Telegram API returned ${r.status}. Check AFK_TELEGRAM_BOT_TOKEN.`}}catch(t){return t.name==="AbortError"?{name:"Telegram Bot",state:"warn",detail:"connection timeout"}:{name:"Telegram Bot",state:"warn",detail:`network error: ${t instanceof Error?t.message:"unknown"}`}}}function vc(e){e.command("doctor").description("Check system health and configuration").option("-f, --format <format>","Output format (text|json)","text").action(async t=>{let n=[];n.push(await Ny()),n.push(await jy()),n.push(await Ro("Config Directory",sn)),n.push(await Ro("State Directory",an)),n.push(await Ro("Logs Directory",Ho)),n.push(await By());let r=await Hy();r!==null&&n.push(r);let o={passed:n.filter(s=>s.state==="pass").length,warned:n.filter(s=>s.state==="warn").length,failed:n.filter(s=>s.state==="fail").length};t.format==="json"?console.log(JSON.stringify({checks:n,summary:o},null,2)):(n.forEach(s=>{let a;s.state==="pass"?a=d.success("\u2713"):s.state==="warn"?a=d.warning("\u26A0"):a=d.error("\u2717");let i=`${a} ${s.name}`;s.detail&&(i+=` \u2014 ${s.detail}`),console.log(i),s.state==="fail"&&s.fix&&console.log(` Fix: ${s.fix}`)}),console.log(`
1505
+ Summary: ${o.passed} passed, ${o.warned} warned, ${o.failed} failed`)),process.exit(o.failed>0?1:0)})}var Wy=["chat","interactive","status","config","daemon","login","plugin","doctor","completion"],Ky=["install","update","list","remove","enable","disable"],_o=["sonnet","opus","haiku"],$o=["json","text"],Oo=["cron","sessionstart","both"];function Se(e){return e.join(" ")}function Gy(){let e=Se(_o),t=Se($o),n=Se(Oo);return`#compdef afk
1506
+
1507
+ _afk() {
1508
+ local -a commands
1509
+ commands=(
1510
+ 'chat:Send a single chat message'
1511
+ 'interactive:Start an interactive REPL'
1512
+ 'status:Show CLI status'
1513
+ 'config:Show resolved configuration'
1514
+ 'daemon:Run as background daemon'
1515
+ 'login:Save Anthropic API key'
1516
+ 'plugin:Manage plugins'
1517
+ 'doctor:Run self-check'
1518
+ 'completion:Emit shell completion script'
1519
+ )
1520
+ _describe -t commands 'afk command' commands
1521
+
1522
+ # Plugin subcommands
1523
+ case "\${words[2]}" in
1524
+ plugin)
1525
+ local -a plugin_commands
1526
+ plugin_commands=(
1527
+ 'install:Install a plugin'
1528
+ 'update:Update one or all plugins'
1529
+ 'list:List installed plugins'
1530
+ 'remove:Remove a plugin'
1531
+ 'enable:Re-enable a plugin'
1532
+ 'disable:Disable a plugin'
1533
+ )
1534
+ _describe -t plugin_commands 'plugin subcommand' plugin_commands
1535
+ ;;
1536
+ esac
1537
+
1538
+ # Flag completions
1539
+ case "\${words[CURRENT-1]}" in
1540
+ --model|-m)
1541
+ compadd -a '${e}'
1542
+ ;;
1543
+ --format|-f)
1544
+ compadd -a '${t}'
1545
+ ;;
1546
+ --trigger)
1547
+ compadd -a '${n}'
1548
+ ;;
1549
+ esac
1550
+ }
1551
+
1552
+ compdef _afk afk`}function zy(){let e=Se(Wy),t=Se(Ky),n=Se(_o),r=Se($o),o=Se(Oo);return`_afk_complete() {
1553
+ local cur prev
1554
+ cur="\${COMP_WORDS[COMP_CWORD]}"
1555
+ prev="\${COMP_WORDS[COMP_CWORD-1]}"
1556
+
1557
+ case "$prev" in
1558
+ afk)
1559
+ COMPREPLY=($(compgen -W "${e}" -- "$cur"))
1560
+ ;;
1561
+ plugin)
1562
+ COMPREPLY=($(compgen -W "${t}" -- "$cur"))
1563
+ ;;
1564
+ --model|-m)
1565
+ COMPREPLY=($(compgen -W "${n}" -- "$cur"))
1566
+ ;;
1567
+ --format|-f)
1568
+ COMPREPLY=($(compgen -W "${r}" -- "$cur"))
1569
+ ;;
1570
+ --trigger)
1571
+ COMPREPLY=($(compgen -W "${o}" -- "$cur"))
1572
+ ;;
1573
+ *)
1574
+ COMPREPLY=($(compgen -W "--help --version" -- "$cur"))
1575
+ ;;
1576
+ esac
1577
+ }
1578
+
1579
+ complete -F _afk_complete afk`}function Vy(){let e=Se(_o),t=Se($o),n=Se(Oo);return`complete -c afk -f
1580
+ # afk subcommands
1581
+ complete -c afk -n '__fish_use_subcommand' -a 'chat' -d 'Send a single chat message'
1582
+ complete -c afk -n '__fish_use_subcommand' -a 'interactive' -d 'Start an interactive REPL'
1583
+ complete -c afk -n '__fish_use_subcommand' -a 'status' -d 'Show CLI status'
1584
+ complete -c afk -n '__fish_use_subcommand' -a 'config' -d 'Show resolved configuration'
1585
+ complete -c afk -n '__fish_use_subcommand' -a 'daemon' -d 'Run as background daemon'
1586
+ complete -c afk -n '__fish_use_subcommand' -a 'login' -d 'Save Anthropic API key'
1587
+ complete -c afk -n '__fish_use_subcommand' -a 'plugin' -d 'Manage plugins'
1588
+ complete -c afk -n '__fish_use_subcommand' -a 'doctor' -d 'Run self-check'
1589
+ complete -c afk -n '__fish_use_subcommand' -a 'completion' -d 'Emit shell completion script'
1590
+
1591
+ # plugin subcommands
1592
+ complete -c afk -n '__fish_seen_subcommand_from plugin' -a 'install' -d 'Install a plugin'
1593
+ complete -c afk -n '__fish_seen_subcommand_from plugin' -a 'update' -d 'Update one or all plugins'
1594
+ complete -c afk -n '__fish_seen_subcommand_from plugin' -a 'list' -d 'List installed plugins'
1595
+ complete -c afk -n '__fish_seen_subcommand_from plugin' -a 'remove' -d 'Remove a plugin'
1596
+ complete -c afk -n '__fish_seen_subcommand_from plugin' -a 'enable' -d 'Re-enable a plugin'
1597
+ complete -c afk -n '__fish_seen_subcommand_from plugin' -a 'disable' -d 'Disable a plugin'
1598
+
1599
+ # flags: --model, --format, --trigger
1600
+ complete -c afk -l model -s m -x -a '${e}' -d 'Model to use'
1601
+ complete -c afk -l format -s f -x -a '${t}' -d 'Output format'
1602
+ complete -c afk -l trigger -x -a '${n}' -d 'Trigger type'`}function Sc(e){e.command("completion <shell>").description("Emit shell completion script (zsh|bash|fish)").action(t=>{let n=["zsh","bash","fish"];if(!n.includes(t)){e.error(`unknown shell: ${t}. Choose from: ${n.join(", ")}`);return}let r="";switch(t){case"zsh":r=Gy();break;case"bash":r=zy();break;case"fish":r=Vy();break}console.log(r)})}xc();xc({path:it(),override:!1});Vo();var ie=new Yy;ie.name("afk").description("AI agent CLI. Starts interactive REPL by default; use `afk chat` for one-shot.").version("0.1.0");pa(ie);ec(ie);mc(ie);Xl(ie);fc(ie);yc(ie);bc(ie);Zl(ie);vc(ie);Sc(ie);ie.commands.find(e=>e.name()==="chat")?.alias("c");ie.commands.find(e=>e.name()==="interactive")?.alias("i");ie.commands.find(e=>e.name()==="status")?.alias("s");ie.addHelpText("after",`
1603
+ Examples:
1604
+ $ afk # start interactive REPL
1605
+ $ afk --model opus # REPL with specific model
1606
+ $ afk chat "What is 2+2?" # one-shot message
1607
+ $ afk status --format json`);import.meta.url===`file://${process.argv[1]}`&&ie.parse();export{Ur as getMaxBudgetUsd,Ht as getMaxOutputTokens,Nr as getTaskBudget,mt as parseBudget,We as parseEffort,ft as parseMaxOutputTokens,He as parseThinking};