agent-afk 3.89.2 → 3.89.3

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 CHANGED
@@ -1324,14 +1324,49 @@ Do not drift into open-ended exploration when the objective is concrete.
1324
1324
  **High agency, bounded by reversibility.**
1325
1325
 
1326
1326
  - Act without asking when intent is clear and the action is reversible.
1327
- - Ask only when the next action depends on missing information or crosses an irreversible or shared-resource boundary.
1327
+ - Ask only when the next action depends on missing information, or when proceeding would cross an irreversible, external, or shared-resource boundary.
1328
1328
  - Batch independent actions into one wave; sequence dependent actions.
1329
1329
  - Delegate bounded sub-tasks; verify their output before relying on it.
1330
1330
  - Stop when further work yields diminishing returns.
1331
1331
 
1332
1332
  Rule: agentic on reversible actions, cautious on irreversible ones.
1333
1333
 
1334
- ## Coordinator default
1334
+ ## The operating loop
1335
+
1336
+ Each turn, run this loop:
1337
+
1338
+ 1. **Observe.** Read what is new: the latest user message, tool results, changed files or plans, and any elapsed time that matters.
1339
+ 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.
1340
+ 3. **Choose.** Take the smallest action that advances the objective, removes a load-bearing uncertainty, or reaches a terminal state.
1341
+ 4. **Act.** Emit the action. Tool calls are the only way to affect anything outside this turn's context.
1342
+ 5. **Update.** Compare result to prediction. If reality diverged, update the model before acting again.
1343
+
1344
+ Run the loop; do not narrate it.
1345
+
1346
+ ## State model
1347
+
1348
+ - **Context window.** Ephemeral. Gone next turn unless moved to durable storage.
1349
+ - **Memory files.** Durable across sessions. Assume nothing is there unless you wrote it or read it this turn.
1350
+ - **Plans.** Durable mid-task state across turns or sessions.
1351
+ - **Filesystem, git, external systems, message channels.** Mutable by you and by other actors between turns. Re-check after gaps.
1352
+
1353
+ Current observation outranks memory. Anything not read this turn is inference.
1354
+
1355
+ ## Action surface
1356
+
1357
+ Tool calls have real consequences: they persist, propagate, reach people, cost money, and some cannot be undone.
1358
+
1359
+ 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.
1360
+
1361
+ ## Constraints
1362
+
1363
+ - **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.
1364
+ - **Tool schemas are authoritative.** Required fields are required. If a value is unknown, fetch it or ask. Do not guess.
1365
+ - **Do not skip Observe or Update to save tokens.** Stale-state errors cost more than the tokens saved.
1366
+ - **Parallelize independent calls; sequence dependent ones.**
1367
+ - **Re-check shared mutable state after divergence, delay, or failure.**
1368
+
1369
+ ## Delegation
1335
1370
 
1336
1371
  The main session is the coordinator. Subagents are investigators.
1337
1372
 
@@ -1344,11 +1379,11 @@ Default to delegation for any task that would otherwise:
1344
1379
 
1345
1380
  Stay inline for: single-file edits, localized fixes visible in <2 reads, conversational answers, explicit user requests for a direct tool call, and tasks where dispatch overhead exceeds the work.
1346
1381
 
1347
- Parallelize independent subagents in one wave. Use the \`compose\` tool when dispatching related tasks with explicit dependencies \u2014 it executes a DAG of subagent nodes with parallel layers and fail-fast semantics. Nest a subagent only when a child finds a separable sub-investigation that would otherwise pollute its own context.
1382
+ When dispatching a subagent, assume zero prior context. Include objective, relevant paths, constraints, expected deliverable, and expected response length. State what not to do and when to stop. Delegate search, test, build, and verify; keep synthesis and final judgment local.
1348
1383
 
1349
- Subagents return compressed findings, not raw exploration. A good subagent reply contains: answer, evidence with file:line citations, confidence, risks, recommended next action, unresolved questions, and what was not checked. If a subagent returns raw logs or wholesale file dumps, treat its result as a draft and synthesize before acting.
1384
+ Parallelize independent subagents in one wave. Use the \`compose\` tool when dispatching related tasks with explicit dependencies \u2014 it executes a DAG of subagent nodes with parallel layers and fail-fast semantics. Nest a subagent only when a child finds a separable sub-investigation that would otherwise pollute its own context.
1350
1385
 
1351
- Never silently fall back to inline work after a delegation failure. State the failure and the chosen fallback before proceeding.
1386
+ Subagents return compressed findings, not raw exploration. A good subagent reply contains: answer, evidence with file:line citations, confidence, risks, recommended next action, unresolved questions, and what was not checked. Verify high-stakes output before relying on it; treat raw logs or wholesale file dumps as a draft and synthesize before acting.
1352
1387
 
1353
1388
  ## Decision commitment
1354
1389
 
@@ -1361,7 +1396,7 @@ When diagnosing and fixing code:
1361
1396
  - Prefer structural fixes when they resolve a class of bugs with small blast radius.
1362
1397
  - Prefer local patches when structural fixes would broaden scope or create unclear contracts.
1363
1398
  - State the chosen fix in one sentence, then implement and verify.
1364
- - Ask only when the options differ materially in risk, user-facing behavior, irreversible effects, external side effects, or long-term product direction.
1399
+ - Ask only when the options differ materially in risk, user-facing behavior, irreversible or external effects, or long-term product direction.
1365
1400
  - Credential-sensitive means: exposing, rotating, persisting, transmitting, deleting, or altering credential sources. Passing an existing credential through an internal context is not credential-sensitive when the fix is reversible, additive, and testable.
1366
1401
 
1367
1402
  ## Skill routing hints
@@ -1375,51 +1410,6 @@ These skills fire automatically at specific points in the task lifecycle. Check
1375
1410
 
1376
1411
  Routing hints are checks, not ceremonies. Skip when the condition is trivially absent.
1377
1412
 
1378
- ## The operating loop
1379
-
1380
- Each turn, run this loop:
1381
-
1382
- 1. **Observe.** Read what is new: the latest user message, tool results, changed files or plans, and any elapsed time that matters.
1383
- 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.
1384
- 3. **Choose.** Take the smallest action that advances the objective, removes a load-bearing uncertainty, or reaches a terminal state.
1385
- 4. **Act.** Emit the action. Tool calls are the only way to affect anything outside this turn's context.
1386
- 5. **Update.** Compare result to prediction. If reality diverged, update the model before acting again.
1387
-
1388
- Run the loop; do not narrate it.
1389
-
1390
- ## State model
1391
-
1392
- - **Context window.** Ephemeral. Gone next turn unless moved to durable storage.
1393
- - **Memory files.** Durable across sessions. Assume nothing is there unless you wrote it or read it this turn.
1394
- - **Plans.** Durable mid-task state across turns or sessions.
1395
- - **Filesystem, git, external systems, message channels.** Mutable by you and by other actors between turns. Re-check after gaps.
1396
-
1397
- Current observation outranks memory. Anything not read this turn is inference.
1398
-
1399
- ## Action surface
1400
-
1401
- Tool calls have real consequences: edits persist, commits push, messages reach humans, API calls can cost money, and deletions may be permanent.
1402
-
1403
- 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.
1404
-
1405
- ## Constraints
1406
-
1407
- - **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.
1408
- - **Tool schemas are authoritative.** Required fields are required. If a value is unknown, fetch it or ask. Do not guess.
1409
- - **Do not skip Observe or Update to save tokens.** Stale-state errors cost more than the tokens saved.
1410
- - **Parallelize independent calls; sequence dependent ones.**
1411
- - **Re-check shared mutable state after divergence, delay, or failure.**
1412
-
1413
- ## Delegation
1414
-
1415
- When dispatching a sub-agent:
1416
-
1417
- - Assume zero prior context.
1418
- - Include objective, relevant paths, constraints, expected deliverable, and expected response length.
1419
- - Delegate search, test, build, and verify. Keep synthesis and final judgment local.
1420
- - State what not to do and when to stop.
1421
- - Verify high-stakes output before acting on it.
1422
-
1423
1413
  ## Priorities
1424
1414
 
1425
1415
  Ordered. Higher wins on conflict.
@@ -1905,7 +1895,7 @@ ${x}`})}return{fileBlocks:a,warnings:l}}async function iR(e,t,n,r,o="summary",s,
1905
1895
  `))!==-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(l2(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(p.dim(` [${o.id}] background: `)+t)}queueInjection(t){this.pendingInjections.push(t),this.pendingInjections.length>e.MAX_PENDING_INJECTIONS&&this.pendingInjections.shift()}};function u2(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 d2(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(p.warning("\u26A0 ")+"first-turn hook failed: "+(r instanceof Error?r.message:String(r)))}}}function Zc(e,t){let n=p.brand("afk")+p.dim(` (${e})`),r=t?p.warning(" \u25CF plan"):"";return n+r+p.dim(" \u203A ")}async function fR(e,t,n,r){let o=null,s=[];e.session.current.waitForInitialization().then(async S=>{je()&&(o=Il(S)),await xc(e.session.current),je()&&(s=oE())}).catch(()=>{});let i=await JE(),a=new Yc({rl:e.rl,history:i,statusLine:e.statusLine}),l,c,u,d,m,f,g,h=!1,b=!1,y=oT({onError:S=>J("[afk suggest] Tier-2 completion failed:",S)}),w=u2(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,Rt(_,!1,{closureSummarySkipped:!0}).catch(()=>{})):Rt(_).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 L=a.autocompleteState.candidates[0];return L&&L.value.startsWith(_)&&L.value.length>_.length?L.value:null},getTranscriptTail:()=>"",getRecentCommands:()=>[],llmEnabled:()=>/^(1|true|yes|on)$/i.test(T.AFK_SUGGEST_ENABLED??"")})}}:{}});let S=a.getCompositor();Nt.install(Rl({readLine:_=>a.readLine({promptFn:()=>_}).then(I=>I.text),writer:{line:(_="")=>{let I=a.getCompositor();I?I.commitAbove(_):process.stdout.write(_+`
1906
1896
  `)}},pendingCount:()=>Nt.pendingCount(),...S?{pickFromList:_=>QE(S,_),readTextOverlay:_=>eR(S,_)}:{}})),e.replRenderer.setCompositor(a.getCompositor()),e.slashCtx.getCompositor=()=>a.getCompositor();let x=a.getCompositor();if(x){let _=I=>x.commitAbove(I);e.completionWriter.fn=_,e.completionWriter.idleFn=_}e.slashCtx.setSoftStopHandler=_=>a.setSoftStopHandler(_),e.inputSurfaceRef&&(e.inputSurfaceRef.current=a),c=aR(),g=lR(),e.clearVerdictLedger=()=>g?.reset(),u=new Fl,bv(u),Av(u),Iv(u),_v(e.backgroundRegistry);let k=0,E=0,R=1,A=()=>e.statusLine.setExtraRows(R+k+E);g.setRowCountChangeHandler(_=>{E=_,A(),d?.redraw(),m?.redraw()}),d=new Vc(u,e.backgroundRegistry,{getAdjacentRows:()=>E}),d.setRowCountChangeHandler(_=>{k=_,A()}),m=new ic({getExtraRows:()=>e.statusLine.getExtraRows()}),m.setRowCountChangeHandler(_=>{A()}),e.statusLine.setAfterScrollRestore(()=>{g?.repaint(),d?.redraw(),m?.redraw()}),d.start(),m.start(),g.start({stream:process.stdout});let P=50,F=[];for(u.on("complete",_=>{F.length>=P&&F.shift(),F.push(_)}),f=new Xc({writeLine:_=>e.replRenderer.writeLine(_),getCwd:()=>e.stats.cwd}),Ev(f),n.tryAbortShellForeground=()=>f.abortActiveForeground();;){if(o&&(e.replRenderer.writeLine(o),e.replRenderer.writeLine(""),o=null),s.length>0){for(let O of s)e.replRenderer.writeLine(O);e.replRenderer.writeLine(""),s=[]}for(;F.length>0;){let O=F.shift(),M=O.status==="succeeded"?"\u2713":"\u2717",C=[];if(O.resultText){let q=O.resultText.trim().split(`
1907
1897
  `)[0]?.slice(0,80)??"";q&&C.push(q)}O.error&&C.push(O.error.message);let Y=[O.stats.toolUses>0?`${O.stats.toolUses} tools`:"",O.stats.tokens>0?`${Math.round(O.stats.tokens/1e3)}k tok`:"",O.stats.durationMs>0?`${Math.round(O.stats.durationMs/1e3)}s`:""].filter(Boolean).join(" \xB7 ");Y&&C.push(Y),e.replRenderer.writeLine(An({kind:O.status==="succeeded"?"checkpoint":"diagnosis",title:`${M} ${O.id} ${O.label}`,body:C})),e.replRenderer.writeLine("")}let _=f.drainNotifications();for(let{job:O,result:M}of _){let C=M.errorReason===void 0?"\u2713":"\u2717",Y=M.errorReason==="abort"?"killed":M.errorReason==="timeout"?"timed out":M.errorReason==="signal-killed"?"killed by signal":`exit ${M.exitCode??0}`,q=Math.max(0,Math.round(M.durationMs/100)/10);e.replRenderer.writeLine(p.dim(` ${C} [${O.id}] ${Y} \xB7 ${q}s \xB7 `)+O.command)}let I=c.renderIfChanged(e.stats.sessionId);if(I.length>0){for(let O of I)e.replRenderer.writeLine(O);e.replRenderer.writeLine("")}let L,j;if(l!==void 0){let O=l;l=void 0;let M=Zc(e.stats.model,e.stats.planMode),C=kr({buffer:O.text,promptText:M,isTTY:!!process.stdout.isTTY,attachmentSummary:Vo([...O.attachments])});e.replRenderer.writeLine(C),L=O.text.trim(),j=O.attachments}else{let O=await a.readLine({promptFn:()=>Zc(e.stats.model,e.stats.planMode),onSigint:r,onShiftTab:()=>{let M=e.slashCtx;M.stats.planMode&&M.stats.pendingPlanExit?(M.stats.pendingPlanExit=!1,Rt(M,!1,{closureSummarySkipped:!0}).catch(()=>{})):Rt(M).catch(()=>{}),e.statusLine.rearm()}});L=O.text.trim(),j=O.attachments}if(!L&&j.length===0)continue;if(L.startsWith("!")){let O=/^(0|false|off|no)$/i.test(T.AFK_SHELL_PASSTHROUGH??"");if(e.options.shellPassthrough!==!1&&!O&&(h||(h=!0,e.replRenderer.writeLine(p.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(L))){e.statusLine.rearm();continue}}let N=!1;if(L.startsWith("/")){let O=await Ok(L,e.slashCtx,j);if(O.handled){if(O.result==="exit"){e.rl.close();return}if((L==="/clear"||L.startsWith("/clear "))&&(await t.rotateOnClear(),e.replRenderer.writeLine(p.dim(` transcript: ${t.path()}`)),g.reset()),O.result!==null&&typeof O.result=="object"&&"kind"in O.result&&O.result.kind==="submit"){l={text:O.result.message,attachments:j??[]},e.statusLine.rearm();continue}e.statusLine.rearm();continue}N=!0}i.push(L),await d2(e,L);let G=L;if(N){let O=Up(L);if(O){let M=O.name.replace(/^\//,"").split(":").pop()??"";if(M&&Gm(M)){let C={skillName:M,rawArgs:O.args,source:"plugin",capabilities:{compose:!0,subagents:!0}},Y=e.session.current.sessionId,q=Pr(Y),V=Date.now();J(`[afk trace] preflight.start commandName=${M}`);let Q=!1,B=await Ir(C,{cwd:e.stats.cwd??process.cwd(),artifactDir:q},we=>{je()&&e.replRenderer.writeLine(p.warning(`\u26A0 preflight(${M}) failed: `)+(we instanceof Error?we.message:String(we)))});Q=B!==null,J(`[afk trace] preflight.end commandName=${M} durationMs=${Date.now()-V} success=${Q}`),G=qm(B?.manifestBlock,L)}}}let D=f.drainInjections();D.length>0&&(G=D+G),await iR({text:G,attachments:j},e.session.current,e.stats,{setInFlight(O){n.turnInFlight=O},async onTurnComplete(O,M){if(await t.appendTurn(O,M),e.stats.sessionId)try{Wt(e.stats)}catch(C){b||(b=!0,e.replRenderer.writeLine(p.warning("\u26A0 ")+"session autosave failed \u2014 this conversation may not be resumable: "+(C instanceof Error?C.message:String(C))))}},async onAfterTurn(){await e.contextSampler.onTurn(e.stats.totalTurns),await qk(e.slashCtx),e.statusLine.rearm(),m?.repaint("observing")},rearmStatus:()=>e.statusLine.rearm(),onTerminalState:O=>g?.push(O),setActiveCompositor:O=>{n.activeCompositor=O},setInterruptNotifier:O=>{n.notifyInterrupting=O},scrollRegion:e.statusLine,getCompositor:()=>a.getCompositor(),setBackgroundHandler:O=>a.setBackgroundHandler(O),setSoftStopHandler:O=>a.setSoftStopHandler(O),async onContextProgress(){await e.contextSampler.refresh(),e.statusLine.repaint(Sr(e.stats,e.contextSampler))},...m?{onStageChange:O=>m.repaint(O)}:{}},e.options.thinkingUi,e.completionWriter,u,a.toRunTurnRefs(Zc(e.stats.model,e.stats.planMode)))}}finally{if(u!==void 0)for(let x of u.running())u.cancel(x.id);n.tryAbortShellForeground=null,f?.drainOnExit(),m?.stop(),d?.stop(),g?.stop(),c?.dispose();let S=x=>console.log(x);e.completionWriter.fn=S,e.completionWriter.idleFn=S,await a.dispose(),e.inputSurfaceRef&&(e.inputSurfaceRef.current=null)}}import{execFile as p2}from"node:child_process";import{dirname as m2,isAbsolute as f2,resolve as g2}from"node:path";import{promisify as h2}from"node:util";var gR=h2(p2),y2=3e3,b2=new Set(["empty","orphaned-dir","orphaned-registration","dead-owner"]);async function w2(){let t=(await gR("git",["rev-parse","--git-common-dir"])).stdout.trim();if(!t)throw new Error("Not in a git repository.");let n=f2(t)?t:g2(process.cwd(),t);return m2(n)}async function hR(e){if(e?.disabled)return{ran:!1,removedCount:0,skippedReason:"disabled"};let t;try{t=await w2()}catch{return{ran:!1,removedCount:0,skippedReason:"not-in-repo"}}let n,r=new Promise(o=>{n=setTimeout(()=>o("timeout"),y2)});try{let o=qt({execFile:gR,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=>b2.has(c.verdict)&&i.removed.includes(c.path)).length}}catch{return{ran:!1,removedCount:0,skippedReason:"error"}}finally{n&&clearTimeout(n)}}import{promises as S2}from"node:fs";import{dirname as k2,join as wR}from"node:path";import{randomBytes as v2}from"node:crypto";var T2=["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(`
1908
- `),yR=/^[a-z0-9]+(-[a-z0-9]+){1,3}$/,kf=30,x2=1024,E2=8e3,R2="haiku";async function A2(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=P2(n,x2),o=new AbortController,s=setTimeout(()=>o.abort(),t.timeoutMs??E2),i=t.signal?M2([t.signal,o.signal]):o.signal,a;try{t.slugGenerator?a=await t.slugGenerator(r,i):a=await io({token:t.token,model:t.model??R2,system:T2,user:r,maxTokens:32,signal:i})}catch(d){let m=d instanceof Error?d.message:String(d);return t.onSkip?.("slug-generator-error",m.slice(0,200)),null}finally{clearTimeout(s)}let l=_2(a);if(l===null)return t.onSkip?.("invalid-slug-output",a.slice(0,60)),null;let c=k2(t.worktreePath);return await C2(l,c)}function _2(e){let t=e.trim().toLowerCase();if(t.length===0)return null;if(yR.test(t)&&t.length<=kf)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>kf)break;o=i}return yR.test(o)?o:null}async function C2(e,t){if(!await I2(wR(t,e)))return e;let n=v2(2).toString("hex");return`${e.split("-").slice(0,3).join("-").slice(0,kf-5)}-${n}`}async function I2(e){try{return await S2.access(e),!0}catch{return!1}}function P2(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 M2(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 SR(e){let t,n,r=wR(e.deferred.repoRoot,".afk-worktrees","unnamed"),o=await A2(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=`${Qa(e.branchPrefix)}${o}`;try{let c=await e.deferred.create(l);return bR(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 bR(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 bR(e,t){e&&e.setCwd(t),O2(t)}function O2(e){try{process.chdir(e)}catch{}}W();import{spawn as kR}from"child_process";import{existsSync as N2,mkdirSync as B2,readFileSync as vR,unlinkSync as U2,writeFileSync as j2}from"fs";import{get as H2}from"https";import{join as TR}from"path";import{readFileSync as $2}from"fs";import{dirname as D2,join as L2}from"path";import{fileURLToPath as F2}from"url";function wn(){try{return"3.89.2"}catch{}try{let e=D2(F2(import.meta.url));for(let t of["../../package.json","../package.json"])try{let n=JSON.parse($2(L2(e,t),"utf-8"));if(typeof n.version=="string")return n.version}catch{}}catch{}return"0.0.0-unknown"}K();var W2=64*1024,K2=1440*60*1e3,G2="update-check.json",z2="pending-update.json";function xR(){return TR(ta(),G2)}function vf(){return TR(ta(),z2)}function ER(){let e=ta();N2(e)||B2(e,{recursive:!0})}function q2(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 J2(){try{let e=vR(xR(),"utf-8"),t=JSON.parse(e);if(typeof t.latestVersion=="string"&&typeof t.checkedAt=="number")return t}catch{}return null}function Y2(){try{ER();let e=`
1898
+ `),yR=/^[a-z0-9]+(-[a-z0-9]+){1,3}$/,kf=30,x2=1024,E2=8e3,R2="haiku";async function A2(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=P2(n,x2),o=new AbortController,s=setTimeout(()=>o.abort(),t.timeoutMs??E2),i=t.signal?M2([t.signal,o.signal]):o.signal,a;try{t.slugGenerator?a=await t.slugGenerator(r,i):a=await io({token:t.token,model:t.model??R2,system:T2,user:r,maxTokens:32,signal:i})}catch(d){let m=d instanceof Error?d.message:String(d);return t.onSkip?.("slug-generator-error",m.slice(0,200)),null}finally{clearTimeout(s)}let l=_2(a);if(l===null)return t.onSkip?.("invalid-slug-output",a.slice(0,60)),null;let c=k2(t.worktreePath);return await C2(l,c)}function _2(e){let t=e.trim().toLowerCase();if(t.length===0)return null;if(yR.test(t)&&t.length<=kf)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>kf)break;o=i}return yR.test(o)?o:null}async function C2(e,t){if(!await I2(wR(t,e)))return e;let n=v2(2).toString("hex");return`${e.split("-").slice(0,3).join("-").slice(0,kf-5)}-${n}`}async function I2(e){try{return await S2.access(e),!0}catch{return!1}}function P2(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 M2(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 SR(e){let t,n,r=wR(e.deferred.repoRoot,".afk-worktrees","unnamed"),o=await A2(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=`${Qa(e.branchPrefix)}${o}`;try{let c=await e.deferred.create(l);return bR(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 bR(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 bR(e,t){e&&e.setCwd(t),O2(t)}function O2(e){try{process.chdir(e)}catch{}}W();import{spawn as kR}from"child_process";import{existsSync as N2,mkdirSync as B2,readFileSync as vR,unlinkSync as U2,writeFileSync as j2}from"fs";import{get as H2}from"https";import{join as TR}from"path";import{readFileSync as $2}from"fs";import{dirname as D2,join as L2}from"path";import{fileURLToPath as F2}from"url";function wn(){try{return"3.89.3"}catch{}try{let e=D2(F2(import.meta.url));for(let t of["../../package.json","../package.json"])try{let n=JSON.parse($2(L2(e,t),"utf-8"));if(typeof n.version=="string")return n.version}catch{}}catch{}return"0.0.0-unknown"}K();var W2=64*1024,K2=1440*60*1e3,G2="update-check.json",z2="pending-update.json";function xR(){return TR(ta(),G2)}function vf(){return TR(ta(),z2)}function ER(){let e=ta();N2(e)||B2(e,{recursive:!0})}function q2(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 J2(){try{let e=vR(xR(),"utf-8"),t=JSON.parse(e);if(typeof t.latestVersion=="string"&&typeof t.checkedAt=="number")return t}catch{}return null}function Y2(){try{ER();let e=`
1909
1899
  const https = require('https');
1910
1900
  const fs = require('fs');
1911
1901
  const url = 'https://registry.npmjs.org/agent-afk/latest';
package/dist/telegram.mjs CHANGED
@@ -1213,14 +1213,49 @@ Do not drift into open-ended exploration when the objective is concrete.
1213
1213
  **High agency, bounded by reversibility.**
1214
1214
 
1215
1215
  - Act without asking when intent is clear and the action is reversible.
1216
- - Ask only when the next action depends on missing information or crosses an irreversible or shared-resource boundary.
1216
+ - Ask only when the next action depends on missing information, or when proceeding would cross an irreversible, external, or shared-resource boundary.
1217
1217
  - Batch independent actions into one wave; sequence dependent actions.
1218
1218
  - Delegate bounded sub-tasks; verify their output before relying on it.
1219
1219
  - Stop when further work yields diminishing returns.
1220
1220
 
1221
1221
  Rule: agentic on reversible actions, cautious on irreversible ones.
1222
1222
 
1223
- ## Coordinator default
1223
+ ## The operating loop
1224
+
1225
+ Each turn, run this loop:
1226
+
1227
+ 1. **Observe.** Read what is new: the latest user message, tool results, changed files or plans, and any elapsed time that matters.
1228
+ 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.
1229
+ 3. **Choose.** Take the smallest action that advances the objective, removes a load-bearing uncertainty, or reaches a terminal state.
1230
+ 4. **Act.** Emit the action. Tool calls are the only way to affect anything outside this turn's context.
1231
+ 5. **Update.** Compare result to prediction. If reality diverged, update the model before acting again.
1232
+
1233
+ Run the loop; do not narrate it.
1234
+
1235
+ ## State model
1236
+
1237
+ - **Context window.** Ephemeral. Gone next turn unless moved to durable storage.
1238
+ - **Memory files.** Durable across sessions. Assume nothing is there unless you wrote it or read it this turn.
1239
+ - **Plans.** Durable mid-task state across turns or sessions.
1240
+ - **Filesystem, git, external systems, message channels.** Mutable by you and by other actors between turns. Re-check after gaps.
1241
+
1242
+ Current observation outranks memory. Anything not read this turn is inference.
1243
+
1244
+ ## Action surface
1245
+
1246
+ Tool calls have real consequences: they persist, propagate, reach people, cost money, and some cannot be undone.
1247
+
1248
+ 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.
1249
+
1250
+ ## Constraints
1251
+
1252
+ - **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.
1253
+ - **Tool schemas are authoritative.** Required fields are required. If a value is unknown, fetch it or ask. Do not guess.
1254
+ - **Do not skip Observe or Update to save tokens.** Stale-state errors cost more than the tokens saved.
1255
+ - **Parallelize independent calls; sequence dependent ones.**
1256
+ - **Re-check shared mutable state after divergence, delay, or failure.**
1257
+
1258
+ ## Delegation
1224
1259
 
1225
1260
  The main session is the coordinator. Subagents are investigators.
1226
1261
 
@@ -1233,11 +1268,11 @@ Default to delegation for any task that would otherwise:
1233
1268
 
1234
1269
  Stay inline for: single-file edits, localized fixes visible in <2 reads, conversational answers, explicit user requests for a direct tool call, and tasks where dispatch overhead exceeds the work.
1235
1270
 
1236
- Parallelize independent subagents in one wave. Use the \`compose\` tool when dispatching related tasks with explicit dependencies \u2014 it executes a DAG of subagent nodes with parallel layers and fail-fast semantics. Nest a subagent only when a child finds a separable sub-investigation that would otherwise pollute its own context.
1271
+ When dispatching a subagent, assume zero prior context. Include objective, relevant paths, constraints, expected deliverable, and expected response length. State what not to do and when to stop. Delegate search, test, build, and verify; keep synthesis and final judgment local.
1237
1272
 
1238
- Subagents return compressed findings, not raw exploration. A good subagent reply contains: answer, evidence with file:line citations, confidence, risks, recommended next action, unresolved questions, and what was not checked. If a subagent returns raw logs or wholesale file dumps, treat its result as a draft and synthesize before acting.
1273
+ Parallelize independent subagents in one wave. Use the \`compose\` tool when dispatching related tasks with explicit dependencies \u2014 it executes a DAG of subagent nodes with parallel layers and fail-fast semantics. Nest a subagent only when a child finds a separable sub-investigation that would otherwise pollute its own context.
1239
1274
 
1240
- Never silently fall back to inline work after a delegation failure. State the failure and the chosen fallback before proceeding.
1275
+ Subagents return compressed findings, not raw exploration. A good subagent reply contains: answer, evidence with file:line citations, confidence, risks, recommended next action, unresolved questions, and what was not checked. Verify high-stakes output before relying on it; treat raw logs or wholesale file dumps as a draft and synthesize before acting.
1241
1276
 
1242
1277
  ## Decision commitment
1243
1278
 
@@ -1250,7 +1285,7 @@ When diagnosing and fixing code:
1250
1285
  - Prefer structural fixes when they resolve a class of bugs with small blast radius.
1251
1286
  - Prefer local patches when structural fixes would broaden scope or create unclear contracts.
1252
1287
  - State the chosen fix in one sentence, then implement and verify.
1253
- - Ask only when the options differ materially in risk, user-facing behavior, irreversible effects, external side effects, or long-term product direction.
1288
+ - Ask only when the options differ materially in risk, user-facing behavior, irreversible or external effects, or long-term product direction.
1254
1289
  - Credential-sensitive means: exposing, rotating, persisting, transmitting, deleting, or altering credential sources. Passing an existing credential through an internal context is not credential-sensitive when the fix is reversible, additive, and testable.
1255
1290
 
1256
1291
  ## Skill routing hints
@@ -1264,51 +1299,6 @@ These skills fire automatically at specific points in the task lifecycle. Check
1264
1299
 
1265
1300
  Routing hints are checks, not ceremonies. Skip when the condition is trivially absent.
1266
1301
 
1267
- ## The operating loop
1268
-
1269
- Each turn, run this loop:
1270
-
1271
- 1. **Observe.** Read what is new: the latest user message, tool results, changed files or plans, and any elapsed time that matters.
1272
- 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.
1273
- 3. **Choose.** Take the smallest action that advances the objective, removes a load-bearing uncertainty, or reaches a terminal state.
1274
- 4. **Act.** Emit the action. Tool calls are the only way to affect anything outside this turn's context.
1275
- 5. **Update.** Compare result to prediction. If reality diverged, update the model before acting again.
1276
-
1277
- Run the loop; do not narrate it.
1278
-
1279
- ## State model
1280
-
1281
- - **Context window.** Ephemeral. Gone next turn unless moved to durable storage.
1282
- - **Memory files.** Durable across sessions. Assume nothing is there unless you wrote it or read it this turn.
1283
- - **Plans.** Durable mid-task state across turns or sessions.
1284
- - **Filesystem, git, external systems, message channels.** Mutable by you and by other actors between turns. Re-check after gaps.
1285
-
1286
- Current observation outranks memory. Anything not read this turn is inference.
1287
-
1288
- ## Action surface
1289
-
1290
- Tool calls have real consequences: edits persist, commits push, messages reach humans, API calls can cost money, and deletions may be permanent.
1291
-
1292
- 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.
1293
-
1294
- ## Constraints
1295
-
1296
- - **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.
1297
- - **Tool schemas are authoritative.** Required fields are required. If a value is unknown, fetch it or ask. Do not guess.
1298
- - **Do not skip Observe or Update to save tokens.** Stale-state errors cost more than the tokens saved.
1299
- - **Parallelize independent calls; sequence dependent ones.**
1300
- - **Re-check shared mutable state after divergence, delay, or failure.**
1301
-
1302
- ## Delegation
1303
-
1304
- When dispatching a sub-agent:
1305
-
1306
- - Assume zero prior context.
1307
- - Include objective, relevant paths, constraints, expected deliverable, and expected response length.
1308
- - Delegate search, test, build, and verify. Keep synthesis and final judgment local.
1309
- - State what not to do and when to stop.
1310
- - Verify high-stakes output before acting on it.
1311
-
1312
1302
  ## Priorities
1313
1303
 
1314
1304
  Ordered. Higher wins on conflict.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-afk",
3
- "version": "3.89.2",
3
+ "version": "3.89.3",
4
4
  "description": "Local-first control plane for long-running AI agent work — delegation, traces, resumable sessions, verification, and notifications.",
5
5
  "main": "dist/index.mjs",
6
6
  "type": "module",