agent-afk 3.80.3 → 3.80.4
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/bundled-plugins/awa-bundled/.claude-plugin/plugin.json +5 -0
- package/dist/bundled-plugins/awa-bundled/bundled.test.ts +403 -0
- package/dist/bundled-plugins/awa-bundled/skills/contract/SKILL.md +34 -0
- package/dist/bundled-plugins/awa-bundled/skills/devils-advocate/SKILL.md +46 -0
- package/dist/bundled-plugins/awa-bundled/skills/gather/SKILL.md +42 -0
- package/dist/bundled-plugins/awa-bundled/skills/ground-claim/SKILL.md +54 -0
- package/dist/bundled-plugins/awa-bundled/skills/ground-state/SKILL.md +51 -0
- package/dist/bundled-plugins/awa-bundled/skills/intent-lock/SKILL.md +99 -0
- package/dist/bundled-plugins/awa-bundled/skills/parallelize/SKILL.md +9 -0
- package/dist/bundled-plugins/awa-bundled/skills/refactor/SKILL.md +154 -0
- package/dist/bundled-plugins/awa-bundled/skills/research/SKILL.md +33 -0
- package/dist/bundled-plugins/awa-bundled/skills/review/SKILL.md +104 -0
- package/dist/bundled-plugins/awa-bundled/skills/shadow-verify/SKILL.md +38 -0
- package/dist/bundled-plugins/awa-bundled/skills/ship/SKILL.md +128 -0
- package/dist/bundled-plugins/awa-bundled/skills/simplify/SKILL.md +123 -0
- package/dist/bundled-plugins/awa-bundled/skills/spec/SKILL.md +29 -0
- package/dist/cli.mjs +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: simplify
|
|
3
|
+
description: "Discovers incidental complexity, duplication, and dead code in a codebase and produces a ranked, behavior-preserving reduction plan — optionally applying safe changes. Dispatches four parallel read-only discovery lenses (clone detection, dead code, complexity hotspots, wrong abstraction), synthesizes into a prioritized reduction plan, and gates apply mode behind /refactor and a hard test check."
|
|
4
|
+
argument-hint: "[target] [--apply] [--all]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Sub-agent contract
|
|
8
|
+
/contract
|
|
9
|
+
|
|
10
|
+
### Overview
|
|
11
|
+
|
|
12
|
+
`/simplify` is a discovery-and-prioritization skill, not a correctness auditor (that is `/review`'s job) and not a blind executor (that is `/refactor`'s job). It answers: *what incidental complexity, duplication, and dead weight exists in this code, and what is safe to remove?* Default mode is **read-only**: a ranked reduction plan is emitted but nothing is changed. Writes only happen when `--apply` is explicitly passed.
|
|
13
|
+
|
|
14
|
+
Scope is **diff-bounded by default** (`git diff origin/main`, or working-tree/HEAD if no remote). Pass `--all` for a whole-repo sweep (where duplication and dead-code analysis pay off most). Pass an explicit `[target]` path or PR reference to override both. Code with no test coverage is safe to *analyze* but must never be *auto-applied* — the skill surfaces that gap and recommends `/simplify [target] --all` after adding tests, or produces the plan and stops.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Argument parsing
|
|
19
|
+
|
|
20
|
+
| Argument | Effect |
|
|
21
|
+
|---|---|
|
|
22
|
+
| *(none)* | Scope = `git diff origin/main` (working-tree fallback) |
|
|
23
|
+
| `[target]` | Explicit path, glob, or PR ref |
|
|
24
|
+
| `--all` | Whole-repo sweep; excludes `node_modules/`, `dist/`, generated files |
|
|
25
|
+
| `--apply` | Opt-in write mode; default is read-only plan |
|
|
26
|
+
|
|
27
|
+
Parse arguments before dispatching Wave 1. Resolve scope to a concrete file list or diff stat and attach it to every sub-agent prompt.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Wave 1 — Parallel discovery (read-only)
|
|
32
|
+
|
|
33
|
+
Dispatch all four lenses simultaneously as `research-agent` sub-agents. All are strictly read-only — no writes, no installs that modify `package.json`. Optional tooling (`jscpd`, `knip`) is an **accelerant only**; degrade to grep/structural reasoning when absent or network-gated.
|
|
34
|
+
|
|
35
|
+
### (a) Duplication / clone detection
|
|
36
|
+
Find exact and near-duplicate logic blocks across modules within scope. Optionally seed with:
|
|
37
|
+
```
|
|
38
|
+
npx jscpd <scope> --reporters json --silent
|
|
39
|
+
```
|
|
40
|
+
If `jscpd` is absent, use grep for literal repetition and structural reasoning for semantic clones. Output: **clone clusters** with `file:line` ranges, estimated token overlap, and a suggested extraction site.
|
|
41
|
+
|
|
42
|
+
### (b) Dead code / unused exports
|
|
43
|
+
Find module-graph-dead exports, unreachable branches, and obsolete feature flags — beyond what `tsc --noEmit --noUnusedLocals` already catches. Optionally seed with:
|
|
44
|
+
```
|
|
45
|
+
npx knip --reporter json
|
|
46
|
+
```
|
|
47
|
+
**MANDATORY GROUNDING**: every "X is unused/dead" claim MUST carry:
|
|
48
|
+
1. A `file:line` citation for the symbol.
|
|
49
|
+
2. A structural evidence path — *who would import it, and why nothing does*.
|
|
50
|
+
|
|
51
|
+
Dynamic imports, reflection, string-keyed access, and barrel re-exports are common false-positive vectors. Never assert dead code without grounding. Flag uncertain cases as **POSSIBLE-DEAD** rather than **DEAD**.
|
|
52
|
+
|
|
53
|
+
### (c) Complexity hotspots
|
|
54
|
+
Identify over-long functions (>40 lines), deep nesting (>3 levels), boolean-flag parameters, primitive obsession, and sprawling switch/if chains. **The target repo has NO ESLint** — this lens is pure agent reasoning over the code, not lint output. Rank by cyclomatic complexity estimate × call-site frequency. Output: hotspot list with `file:line`, smell label, and a plain-language refactor suggestion.
|
|
55
|
+
|
|
56
|
+
### (d) Reuse / wrong-abstraction-level
|
|
57
|
+
Find code that reimplements an existing helper, sits at the wrong layer (leaky abstraction, unnecessary wrapper), or is a thin pass-through with no added value. Cross-reference the project's existing utilities before flagging. Output: reuse candidates with `file:line`, what existing construct could replace them, and estimated call-site count.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Synthesis — inline, after Wave 1
|
|
62
|
+
|
|
63
|
+
1. **Dedup**: one site often trips multiple lenses. Merge duplicate entries; annotate each with the lens(es) that flagged it.
|
|
64
|
+
2. **SANDI-METZ WRONG-ABSTRACTION GUARD**: flag but **do NOT propose collapsing** two code paths if unifying them requires introducing a new boolean/flag parameter. Record these as *"defer — duplication is cheaper than the wrong abstraction"* with an explanation.
|
|
65
|
+
3. **Rank by impact × safety**:
|
|
66
|
+
- **HIGH IMPACT**: multi-site duplication, provably dead exports, complexity hotspots at high call frequency.
|
|
67
|
+
- **LOW RISK**: purely local changes, full test coverage, no public API surface.
|
|
68
|
+
- Deprioritize: single-use private helpers, style preferences, anything touching uncovered code.
|
|
69
|
+
4. **Emit the reduction plan** — one row per finding:
|
|
70
|
+
|
|
71
|
+
| # | Location (`file:line`) | Smell | Proposed simplification | Risk note | Behavior-preservation note |
|
|
72
|
+
|---|---|---|---|---|---|
|
|
73
|
+
|
|
74
|
+
5. Append a **Coverage gate summary**: list files in scope with no test coverage where apply was requested — recommend tests first.
|
|
75
|
+
|
|
76
|
+
**In default (read-only) mode: STOP here.** Print the plan and exit.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Wave 2 — Gated apply (only when `--apply` is passed)
|
|
81
|
+
|
|
82
|
+
Before any write, verify the test suite is green:
|
|
83
|
+
```
|
|
84
|
+
pnpm lint && pnpm test
|
|
85
|
+
```
|
|
86
|
+
If the gate is red before any change, **abort apply and report**. Do not attempt to fix pre-existing failures.
|
|
87
|
+
|
|
88
|
+
**Delegation decision** (per ranked item, high-to-low):
|
|
89
|
+
|
|
90
|
+
- **Multi-site mechanical changes** (extract duplicated block into a shared helper used at N≥2 sites): delegate to `/refactor` if available. `/refactor` handles DAG-layered, worktree-isolated parallel application with a hard test gate at each layer boundary and a behavioral diff. Pass the reduction plan item as the refactor spec.
|
|
91
|
+
- **`/refactor` NOT available, OR single-site local simplifications**: apply directly inside a git worktree. One change at a time; run `pnpm lint && pnpm test` after each. On regression → route to `/diagnose`; revert the change; continue with remaining items.
|
|
92
|
+
- **Items touching uncovered code**: skip apply, preserve in plan output as *"plan-only — no test coverage"*.
|
|
93
|
+
|
|
94
|
+
On full success, chain to `/ship` for commit + PR.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Guardrails
|
|
99
|
+
|
|
100
|
+
- **Behavior-preserving only** — never change observable behavior under the guise of cleanup.
|
|
101
|
+
- Exclude `node_modules/`, `dist/`, vendored code, and auto-generated files from all analysis.
|
|
102
|
+
- Optional tooling (`jscpd`, `knip`) must not modify `package.json` or lock files — use `npx` with no persistent side effects.
|
|
103
|
+
- Diff-scoped by default; whole-repo only on `--all` — avoids signal-drowning noise on large codebases.
|
|
104
|
+
- Max 3 apply-layer retries per item before skipping and continuing.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Failure modes to surface explicitly
|
|
109
|
+
|
|
110
|
+
| Failure mode | Mitigation |
|
|
111
|
+
|---|---|
|
|
112
|
+
| Over-DRYing / wrong abstraction | Sandi-Metz guard (see Synthesis step 2) |
|
|
113
|
+
| False dead-code positives | Mandatory grounding rule on lens (b) |
|
|
114
|
+
| Behavior change disguised as cleanup | Pre/post test gate; worktree isolation |
|
|
115
|
+
| Scope creep on large repos | Diff-scope default; `--all` is explicit opt-in |
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Chains to
|
|
120
|
+
|
|
121
|
+
- `/refactor` — multi-site mechanical apply
|
|
122
|
+
- `/ship` — commit + PR after successful apply
|
|
123
|
+
- `/diagnose` — when an applied simplification breaks a test
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spec
|
|
3
|
+
description: "Takes a loose idea and transforms it into a structured, actionable spec ready for implementation. Use when the user passes an idea, feature request, or problem description that needs scoping before building."
|
|
4
|
+
argument-hint: "<idea or feature request>"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Triage: bugs route to /diagnose
|
|
8
|
+
|
|
9
|
+
Before speccing, detect bug-shaped inputs: crashes, error stacks, regression reports ("worked yesterday", "used to work"), platform-specific failures ("broken on X", "doesn't work when…"), or user-report framing that implies root-cause-first (not design-first). If detected, stop and redirect: *"This is a debugging task, not a spec task. Route to /diagnose instead — it will isolate the root cause, then /spec can scope the fix."* Do not emit a spec.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
Dispatch two sub-agents in parallel. One researches the web for prior art, comparable approaches, and patterns relevant to $ARGUMENT. The other inspects the local working directory for conventions, existing artifacts, and integration points relevant to the domain. When both return, synthesize a concise spec using the domain-appropriate schema below. Present to the user for confirmation before proceeding.
|
|
14
|
+
|
|
15
|
+
**Output schema by domain:**
|
|
16
|
+
|
|
17
|
+
| Domain | Spec fields |
|
|
18
|
+
|--------|-------------|
|
|
19
|
+
| `software` | problem, goals, non-goals, approach, key decisions, interface, file plan, test plan, open questions |
|
|
20
|
+
| `research` | problem, hypothesis, methodology, prior art positioning, expected results, publication plan, open questions |
|
|
21
|
+
| `design` | problem, user needs, constraints, solution space, prototype plan, success metrics, open questions |
|
|
22
|
+
| `business` | opportunity, risk analysis, competitive landscape, go/no-go criteria, resource plan, open questions |
|
|
23
|
+
| *(other)* | problem, goals, non-goals, approach, key decisions, deliverables, validation plan, open questions |
|
|
24
|
+
|
|
25
|
+
When domain is unspecified, infer from $ARGUMENT and the working directory. If ambiguous, use the generic *(other)* schema.
|
|
26
|
+
|
|
27
|
+
## Epistemic confidence
|
|
28
|
+
|
|
29
|
+
Include an **Epistemic confidence** section at the end of every spec: summarize coverage gaps from research, flag claims that will be hard to verify, and note where human judgment will be needed.
|
package/dist/cli.mjs
CHANGED
|
@@ -2247,7 +2247,7 @@ ${E}`})}return{fileBlocks:a,warnings:l}}async function UE(e,t,n,r,o="summary",s,
|
|
|
2247
2247
|
`))!==-1;){let u=n.slice(0,c);n=n.slice(c+1),this.opts.writeLine(u)}},s={command:t,mode:"foreground",onChunk:c=>{r||(n+=c.toString("utf8"),o())}},i=this.opts.getCwd();i!==void 0&&(s.cwd=i);let{job:a,handle:l}=this.registry.start(s);this.activeFgJobId=a.id;try{let c=await l.promise;r=!0,n.length>0&&(this.opts.writeLine(n),n=""),this.opts.writeLine(uG(a,c)),this.queueInjection({command:t,mode:"foreground",result:c})}finally{this.activeFgJobId=null}}startBackground(t){let n={command:t,mode:"background"},r=this.opts.getCwd();r!==void 0&&(n.cwd=r);let{job:o}=this.registry.start(n);this.opts.writeLine(m.dim(` [${o.id}] background: `)+t)}queueInjection(t){this.pendingInjections.push(t),this.pendingInjections.length>e.MAX_PENDING_INJECTIONS&&this.pendingInjections.shift()}};function pG(e,t){if(e!==void 0){let n=e.toLowerCase();return!(n==="0"||n==="false"||n==="off"||n==="no")}return typeof t=="boolean"?t:!0}async function mG(e,t){if(e.firstTurnHook&&e.stats.totalTurns===0){let n=e.firstTurnHook;e.firstTurnHook=void 0;try{await n(t)}catch(r){e.completionWriter.fn(m.warning("\u26A0 ")+"first-turn hook failed: "+(r instanceof Error?r.message:String(r)))}}}function zc(e,t){let n=m.brand("afk")+m.dim(` (${e})`),r=t?m.warning(" \u25CF plan"):"";return n+r+m.dim(" \u203A ")}async function VE(e,t,n,r){let o=null,s=[];e.session.current.waitForInitialization().then(async S=>{He()&&(o=El(S)),await bc(e.session.current),He()&&(s=Bx())}).catch(()=>{});let i=await CE(),a=new Wc({rl:e.rl,history:i,statusLine:e.statusLine}),l,c,u,d,p,f,g,h=!1,b=!1,y=Vv({onError:S=>V("[afk suggest] Tier-2 completion failed:",S)}),w=pG(T.AFK_SUGGEST_GHOST,e.suggestGhostConfig);try{await a.armCompositor({promptFn:()=>zc(e.stats.model,e.stats.planMode),onCancel:r,onShiftTab:()=>{let _=e.slashCtx;_.stats.planMode&&_.stats.pendingPlanExit?(_.stats.pendingPlanExit=!1,Pt(_,!1,{closureSummarySkipped:!0}).catch(()=>{})):Pt(_).catch(()=>{}),e.statusLine.rearm()},scrollRegion:e.statusLine,...e.preArmAnchorRow!==void 0?{anchorRow:e.preArmAnchorRow}:{},...w?{suggest:{engine:y,getContext:()=>({model:e.stats.model,apiKey:e.suggestApiKey,baseUrl:e.suggestBaseUrl,cwd:e.stats.cwd??process.cwd(),getHistory:()=>{let _=a.history;return _.getEntries?[..._.getEntries()]:[]},getDropdownTopCandidate:_=>{let $=a.autocompleteState.candidates[0];return $&&$.value.startsWith(_)&&$.value.length>_.length?$.value:null},getTranscriptTail:()=>"",getRecentCommands:()=>[],llmEnabled:()=>/^(1|true|yes|on)$/i.test(T.AFK_SUGGEST_ENABLED??"")})}}:{}});let S=a.getCompositor();Wt.install(kl({readLine:_=>a.readLine({promptFn:()=>_}).then(D=>D.text),writer:{line:(_="")=>{let D=a.getCompositor();D?D.commitAbove(_):process.stdout.write(_+`
|
|
2248
2248
|
`)}},pendingCount:()=>Wt.pendingCount(),...S?{pickFromList:_=>$E(S,_),readTextOverlay:_=>DE(S,_)}:{}})),e.replRenderer.setCompositor(a.getCompositor()),e.slashCtx.getCompositor=()=>a.getCompositor();let E=a.getCompositor();if(E){let _=D=>E.commitAbove(D);e.completionWriter.fn=_,e.completionWriter.idleFn=_}e.slashCtx.setSoftStopHandler=_=>a.setSoftStopHandler(_),e.inputSurfaceRef&&(e.inputSurfaceRef.current=a),c=HE(),g=WE(),e.clearVerdictLedger=()=>g?.reset(),u=new Ml,uv(u),wv(u),vv(u),Sv(e.backgroundRegistry);let k=0,R=0,I=1,A=()=>e.statusLine.setExtraRows(I+k+R);g.setRowCountChangeHandler(_=>{R=_,A(),d?.redraw(),p?.redraw()}),d=new Kc(u,e.backgroundRegistry,{getAdjacentRows:()=>R}),d.setRowCountChangeHandler(_=>{k=_,A()}),p=new tc({getExtraRows:()=>e.statusLine.getExtraRows()}),p.setRowCountChangeHandler(_=>{A()}),e.statusLine.setAfterScrollRestore(()=>{g?.repaint(),d?.redraw(),p?.redraw()}),d.start(),p.start(),g.start({stream:process.stdout});let C=50,P=[];for(u.on("complete",_=>{P.length>=C&&P.shift(),P.push(_)}),f=new Gc({writeLine:_=>e.replRenderer.writeLine(_),getCwd:()=>e.stats.cwd}),yv(f),n.tryAbortShellForeground=()=>f.abortActiveForeground();;){if(o&&(e.replRenderer.writeLine(o),e.replRenderer.writeLine(""),o=null),s.length>0){for(let x of s)e.replRenderer.writeLine(x);e.replRenderer.writeLine(""),s=[]}for(;P.length>0;){let x=P.shift(),O=x.status==="succeeded"?"\u2713":"\u2717",B=[];if(x.resultText){let K=x.resultText.trim().split(`
|
|
2249
2249
|
`)[0]?.slice(0,80)??"";K&&B.push(K)}x.error&&B.push(x.error.message);let q=[x.stats.toolUses>0?`${x.stats.toolUses} tools`:"",x.stats.tokens>0?`${Math.round(x.stats.tokens/1e3)}k tok`:"",x.stats.durationMs>0?`${Math.round(x.stats.durationMs/1e3)}s`:""].filter(Boolean).join(" \xB7 ");q&&B.push(q),e.replRenderer.writeLine(Mn({kind:x.status==="succeeded"?"checkpoint":"diagnosis",title:`${O} ${x.id} ${x.label}`,body:B})),e.replRenderer.writeLine("")}let _=f.drainNotifications();for(let{job:x,result:O}of _){let B=O.errorReason===void 0?"\u2713":"\u2717",q=O.errorReason==="abort"?"killed":O.errorReason==="timeout"?"timed out":O.errorReason==="signal-killed"?"killed by signal":`exit ${O.exitCode??0}`,K=Math.max(0,Math.round(O.durationMs/100)/10);e.replRenderer.writeLine(m.dim(` ${B} [${x.id}] ${q} \xB7 ${K}s \xB7 `)+x.command)}let D=c.renderIfChanged(e.stats.sessionId);if(D.length>0){for(let x of D)e.replRenderer.writeLine(x);e.replRenderer.writeLine("")}let $,j;if(l!==void 0){let x=l;l=void 0;let O=zc(e.stats.model,e.stats.planMode),B=Rr({buffer:x.text,promptText:O,isTTY:!!process.stdout.isTTY,attachmentSummary:zo([...x.attachments])});e.replRenderer.writeLine(B),$=x.text.trim(),j=x.attachments}else{let x=await a.readLine({promptFn:()=>zc(e.stats.model,e.stats.planMode),onSigint:r,onShiftTab:()=>{let O=e.slashCtx;O.stats.planMode&&O.stats.pendingPlanExit?(O.stats.pendingPlanExit=!1,Pt(O,!1,{closureSummarySkipped:!0}).catch(()=>{})):Pt(O).catch(()=>{}),e.statusLine.rearm()}});$=x.text.trim(),j=x.attachments}if(!$&&j.length===0)continue;if($.startsWith("!")){let x=/^(0|false|off|no)$/i.test(T.AFK_SHELL_PASSTHROUGH??"");if(e.options.shellPassthrough!==!1&&!x&&(h||(h=!0,e.replRenderer.writeLine(m.dim(" \u2139 ! prefix shells out. Pass --no-shell-passthrough (or set AFK_SHELL_PASSTHROUGH=0) to send ! text to the model instead."))),await f.dispatch($))){e.statusLine.rearm();continue}}let N=!1;if($.startsWith("/")){let x=await Ek($,e.slashCtx,j);if(x.handled){if(x.result==="exit"){e.rl.close();return}if(($==="/clear"||$.startsWith("/clear "))&&(await t.rotateOnClear(),e.replRenderer.writeLine(m.dim(` transcript: ${t.path()}`)),g.reset()),x.result!==null&&typeof x.result=="object"&&"kind"in x.result&&x.result.kind==="submit"){l={text:x.result.message,attachments:j??[]},e.statusLine.rearm();continue}e.statusLine.rearm();continue}N=!0}i.push($),await mG(e,$);let H=$;if(N){let x=Ip($);if(x){let O=x.name.replace(/^\//,"").split(":").pop()??"";if(O&&Mm(O)){let B={skillName:O,rawArgs:x.args,source:"plugin",capabilities:{compose:!0,subagents:!0}},q=e.session.current.sessionId,K=Lr(q),F=Date.now();V(`[afk trace] preflight.start commandName=${O}`);let Y=!1,be=await Dr(B,{cwd:e.stats.cwd??process.cwd(),artifactDir:K},je=>{He()&&e.replRenderer.writeLine(m.warning(`\u26A0 preflight(${O}) failed: `)+(je instanceof Error?je.message:String(je)))});Y=be!==null,V(`[afk trace] preflight.end commandName=${O} durationMs=${Date.now()-F} success=${Y}`),H=Dm(be?.manifestBlock,$)}}}let M=f.drainInjections();M.length>0&&(H=M+H),await UE({text:H,attachments:j},e.session.current,e.stats,{setInFlight(x){n.turnInFlight=x},async onTurnComplete(x,O){if(await t.appendTurn(x,O),e.stats.sessionId)try{Jt(e.stats)}catch(B){b||(b=!0,e.replRenderer.writeLine(m.warning("\u26A0 ")+"session autosave failed \u2014 this conversation may not be resumable: "+(B instanceof Error?B.message:String(B))))}},async onAfterTurn(){await e.contextSampler.onTurn(e.stats.totalTurns),await Bk(e.slashCtx),e.statusLine.rearm(),p?.repaint("observing")},rearmStatus:()=>e.statusLine.rearm(),onTerminalState:x=>g?.push(x),setActiveCompositor:x=>{n.activeCompositor=x},setInterruptNotifier:x=>{n.notifyInterrupting=x},scrollRegion:e.statusLine,getCompositor:()=>a.getCompositor(),setBackgroundHandler:x=>a.setBackgroundHandler(x),setSoftStopHandler:x=>a.setSoftStopHandler(x),async onContextProgress(){await e.contextSampler.refresh(),e.statusLine.repaint(Er(e.stats,e.contextSampler))},...p?{onStageChange:x=>p.repaint(x)}:{}},e.options.thinkingUi,e.completionWriter,u,a.toRunTurnRefs(zc(e.stats.model,e.stats.planMode)))}}finally{if(u!==void 0)for(let E of u.running())u.cancel(E.id);n.tryAbortShellForeground=null,f?.drainOnExit(),p?.stop(),d?.stop(),g?.stop(),c?.dispose();let S=E=>console.log(E);e.completionWriter.fn=S,e.completionWriter.idleFn=S,await a.dispose(),e.inputSurfaceRef&&(e.inputSurfaceRef.current=null)}}import{execFile as fG}from"node:child_process";import{dirname as gG,isAbsolute as hG,resolve as yG}from"node:path";import{promisify as bG}from"node:util";var YE=bG(fG),wG=3e3,SG=new Set(["empty","orphaned-dir","orphaned-registration","dead-owner"]);async function kG(){let t=(await YE("git",["rev-parse","--git-common-dir"])).stdout.trim();if(!t)throw new Error("Not in a git repository.");let n=hG(t)?t:yG(process.cwd(),t);return gG(n)}async function XE(e){if(e?.disabled)return{ran:!1,removedCount:0,skippedReason:"disabled"};let t;try{t=await kG()}catch{return{ran:!1,removedCount:0,skippedReason:"not-in-repo"}}let n,r=new Promise(o=>{n=setTimeout(()=>o("timeout"),wG)});try{let o=Zt({execFile:YE,repoRoot:t,dryRun:!1,scope:"interactive",bypassSoftLaunch:!0}),s=await Promise.race([o,r]);if(s==="timeout")return{ran:!1,removedCount:0,skippedReason:"timeout"};let i=s;return i.warnings.some(c=>c.toLowerCase().includes("contested"))?{ran:!1,removedCount:0,skippedReason:"lock-contested"}:{ran:!0,removedCount:i.candidates.filter(c=>SG.has(c.verdict)&&i.removed.includes(c.path)).length}}catch{return{ran:!1,removedCount:0,skippedReason:"error"}}finally{n&&clearTimeout(n)}}import{promises as vG}from"node:fs";import{dirname as TG,join as eR}from"node:path";import{randomBytes as xG}from"node:crypto";var EG=["Generate a 2-4 word kebab-case slug describing this work request.","Rules:","- ASCII lowercase letters and digits only, separated by single hyphens","- 2 to 4 hyphen-separated words","- Maximum 30 characters total","- No prefix, no quotes, no punctuation other than hyphens","- Output ONLY the slug \u2014 no explanation, no preamble","Examples: fix-cleanup-race, add-telegram-allowlist, refactor-prompt-loader, debug-flaky-test"].join(`
|
|
2250
|
-
`),ZE=/^[a-z0-9]+(-[a-z0-9]+){1,3}$/,af=30,RG=1024,AG=8e3,_G="haiku";async function CG(e,t){let n=e.trim();if(n.length===0)return t.onSkip?.("empty-message"),null;if(n.startsWith("/"))return t.onSkip?.("slash-command"),null;let r=OG(n,RG),o=new AbortController,s=setTimeout(()=>o.abort(),t.timeoutMs??AG),i=t.signal?$G([t.signal,o.signal]):o.signal,a;try{t.slugGenerator?a=await t.slugGenerator(r,i):a=await so({token:t.token,model:t.model??_G,system:EG,user:r,maxTokens:32,signal:i})}catch(d){let p=d instanceof Error?d.message:String(d);return t.onSkip?.("slug-generator-error",p.slice(0,200)),null}finally{clearTimeout(s)}let l=IG(a);if(l===null)return t.onSkip?.("invalid-slug-output",a.slice(0,60)),null;let c=TG(t.worktreePath);return await PG(l,c)}function IG(e){let t=e.trim().toLowerCase();if(t.length===0)return null;if(ZE.test(t)&&t.length<=af)return t;let n=t.replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");if(n.length===0)return null;let r=n.split("-").filter(s=>s.length>0).slice(0,4);if(r.length<2)return null;let o=r[0];for(let s=1;s<r.length;s++){let i=`${o}-${r[s]}`;if(i.length>af)break;o=i}return ZE.test(o)?o:null}async function PG(e,t){if(!await MG(eR(t,e)))return e;let n=xG(2).toString("hex");return`${e.split("-").slice(0,3).join("-").slice(0,af-5)}-${n}`}async function MG(e){try{return await vG.access(e),!0}catch{return!1}}function OG(e,t){let n=Buffer.from(e,"utf8");if(n.length<=t)return e;let r=t;for(;r>0&&n[r]!==void 0&&(n[r]&192)===128;)r--;return n.slice(0,r).toString("utf8")}function $G(e){let t=AbortSignal.any;if(typeof t=="function")return t.call(AbortSignal,e);let n=new AbortController;for(let r of e){if(r.aborted)return n.abort(r.reason),n.signal;r.addEventListener("abort",()=>n.abort(r.reason),{once:!0})}return n.signal}async function tR(e){let t,n,r=eR(e.deferred.repoRoot,".afk-worktrees","unnamed"),o=await CG(e.message,{token:e.token,...e.model!==void 0?{model:e.model}:{},...e.timeoutMs!==void 0?{timeoutMs:e.timeoutMs}:{},worktreePath:r,...e.signal!==void 0?{signal:e.signal}:{},...e.slugGenerator!==void 0?{slugGenerator:e.slugGenerator}:{},onSkip:(a,l)=>{t=a,n=l}}),s=t??"unknown",i=n;if(o!==null){let l=`${Va(e.branchPrefix)}${o}`;try{let c=await e.deferred.create(l);return QE(e.session,c.path),{status:"created",path:c.path,branch:c.branch,slug:o}}catch(c){s="create-failed",i=(c instanceof Error?c.message:String(c)).slice(0,200)}}try{let a=await e.deferred.create(!0);return QE(e.session,a.path),{status:"created-fallback",path:a.path,branch:a.branch,reason:s,...i!==void 0?{detail:i}:{}}}catch(a){return{status:"failed",reason:a instanceof Error?a.message:String(a)}}}function QE(e,t){e&&e.setCwd(t),DG(t)}function DG(e){try{process.chdir(e)}catch{}}W();import{spawn as nR}from"child_process";import{existsSync as jG,mkdirSync as UG,readFileSync as rR,unlinkSync as HG,writeFileSync as WG}from"fs";import{get as KG}from"https";import{join as oR}from"path";import{readFileSync as LG}from"fs";import{dirname as FG,join as NG}from"path";import{fileURLToPath as BG}from"url";function xn(){try{return"3.80.
|
|
2250
|
+
`),ZE=/^[a-z0-9]+(-[a-z0-9]+){1,3}$/,af=30,RG=1024,AG=8e3,_G="haiku";async function CG(e,t){let n=e.trim();if(n.length===0)return t.onSkip?.("empty-message"),null;if(n.startsWith("/"))return t.onSkip?.("slash-command"),null;let r=OG(n,RG),o=new AbortController,s=setTimeout(()=>o.abort(),t.timeoutMs??AG),i=t.signal?$G([t.signal,o.signal]):o.signal,a;try{t.slugGenerator?a=await t.slugGenerator(r,i):a=await so({token:t.token,model:t.model??_G,system:EG,user:r,maxTokens:32,signal:i})}catch(d){let p=d instanceof Error?d.message:String(d);return t.onSkip?.("slug-generator-error",p.slice(0,200)),null}finally{clearTimeout(s)}let l=IG(a);if(l===null)return t.onSkip?.("invalid-slug-output",a.slice(0,60)),null;let c=TG(t.worktreePath);return await PG(l,c)}function IG(e){let t=e.trim().toLowerCase();if(t.length===0)return null;if(ZE.test(t)&&t.length<=af)return t;let n=t.replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");if(n.length===0)return null;let r=n.split("-").filter(s=>s.length>0).slice(0,4);if(r.length<2)return null;let o=r[0];for(let s=1;s<r.length;s++){let i=`${o}-${r[s]}`;if(i.length>af)break;o=i}return ZE.test(o)?o:null}async function PG(e,t){if(!await MG(eR(t,e)))return e;let n=xG(2).toString("hex");return`${e.split("-").slice(0,3).join("-").slice(0,af-5)}-${n}`}async function MG(e){try{return await vG.access(e),!0}catch{return!1}}function OG(e,t){let n=Buffer.from(e,"utf8");if(n.length<=t)return e;let r=t;for(;r>0&&n[r]!==void 0&&(n[r]&192)===128;)r--;return n.slice(0,r).toString("utf8")}function $G(e){let t=AbortSignal.any;if(typeof t=="function")return t.call(AbortSignal,e);let n=new AbortController;for(let r of e){if(r.aborted)return n.abort(r.reason),n.signal;r.addEventListener("abort",()=>n.abort(r.reason),{once:!0})}return n.signal}async function tR(e){let t,n,r=eR(e.deferred.repoRoot,".afk-worktrees","unnamed"),o=await CG(e.message,{token:e.token,...e.model!==void 0?{model:e.model}:{},...e.timeoutMs!==void 0?{timeoutMs:e.timeoutMs}:{},worktreePath:r,...e.signal!==void 0?{signal:e.signal}:{},...e.slugGenerator!==void 0?{slugGenerator:e.slugGenerator}:{},onSkip:(a,l)=>{t=a,n=l}}),s=t??"unknown",i=n;if(o!==null){let l=`${Va(e.branchPrefix)}${o}`;try{let c=await e.deferred.create(l);return QE(e.session,c.path),{status:"created",path:c.path,branch:c.branch,slug:o}}catch(c){s="create-failed",i=(c instanceof Error?c.message:String(c)).slice(0,200)}}try{let a=await e.deferred.create(!0);return QE(e.session,a.path),{status:"created-fallback",path:a.path,branch:a.branch,reason:s,...i!==void 0?{detail:i}:{}}}catch(a){return{status:"failed",reason:a instanceof Error?a.message:String(a)}}}function QE(e,t){e&&e.setCwd(t),DG(t)}function DG(e){try{process.chdir(e)}catch{}}W();import{spawn as nR}from"child_process";import{existsSync as jG,mkdirSync as UG,readFileSync as rR,unlinkSync as HG,writeFileSync as WG}from"fs";import{get as KG}from"https";import{join as oR}from"path";import{readFileSync as LG}from"fs";import{dirname as FG,join as NG}from"path";import{fileURLToPath as BG}from"url";function xn(){try{return"3.80.4"}catch{}try{let e=FG(BG(import.meta.url));for(let t of["../../package.json","../package.json"])try{let n=JSON.parse(LG(NG(e,t),"utf-8"));if(typeof n.version=="string")return n.version}catch{}}catch{}return"0.0.0-unknown"}G();var GG=64*1024,zG=1440*60*1e3,qG="update-check.json",JG="pending-update.json";function sR(){return oR(Xi(),qG)}function lf(){return oR(Xi(),JG)}function iR(){let e=Xi();jG(e)||UG(e,{recursive:!0})}function VG(e,t){let n=e.split(".").map(Number),r=t.split(".").map(Number),o=Math.max(n.length,r.length);for(let s=0;s<o;s++){let i=n[s]??0,a=r[s]??0;if(a>i)return!0;if(a<i)return!1}return!1}function YG(){try{let e=rR(sR(),"utf-8"),t=JSON.parse(e);if(typeof t.latestVersion=="string"&&typeof t.checkedAt=="number")return t}catch{}return null}function XG(){try{iR();let e=`
|
|
2251
2251
|
const https = require('https');
|
|
2252
2252
|
const fs = require('fs');
|
|
2253
2253
|
const url = 'https://registry.npmjs.org/agent-afk/latest';
|