agent-afk 3.72.0 → 3.73.1

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/threads.mjs CHANGED
@@ -122,7 +122,7 @@ You are an inspector auditing skills for correct type categorization. Skills com
122
122
  - **User-scope** \u2014 authored directly by the user under \`~/.afk/skills/<name>/SKILL.md\`
123
123
  - **Plugin-scope** \u2014 shipped by an installed plugin under \`~/.afk/plugins/<plugin>/skills/<name>/SKILL.md\`
124
124
 
125
- 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.
125
+ The handler has already discovered every skill path in TypeScript and templates them into the section below. **Do not Glob to discover additional skills** (the list below is exhaustive); just read each path and emit a verdict. Targeted Glob of a known skill's own \`scripts/\`/\`references/\`/\`assets/\` subdirectories is allowed when needed \u2014 see Tools.
126
126
 
127
127
  ## Task
128
128
 
@@ -190,7 +190,7 @@ You are an inspector auditing commands for correct type categorization. Commands
190
190
  - **User-scope** \u2014 authored directly by the user under \`~/.afk/commands/<name>.md\`
191
191
  - **Plugin-scope** \u2014 shipped by an installed plugin under \`~/.afk/plugins/<plugin>/commands/<name>.md\`
192
192
 
193
- 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.
193
+ The handler has already discovered every command path in TypeScript and templates them into the section below. **Do not Glob to discover additional commands** (the list below is exhaustive); just read each path and emit a verdict.
194
194
 
195
195
  ## Task
196
196
 
@@ -259,7 +259,7 @@ You are an inspector auditing agents for correct type categorization. Agents com
259
259
  - **User-scope** \u2014 authored directly by the user under \`~/.afk/agents/<name>.md\`
260
260
  - **Plugin-scope** \u2014 shipped by an installed plugin under \`~/.afk/plugins/<plugin>/agents/<name>.md\`
261
261
 
262
- 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.
262
+ The handler has already discovered every agent path in TypeScript and templates them into the section below. **Do not Glob to discover additional agents** (the list below is exhaustive); just read each path and emit a verdict.
263
263
 
264
264
  ## Task
265
265
 
@@ -1580,6 +1580,8 @@ ${JSON.stringify(t.buildResults,null,2)}
1580
1580
  Verification results:
1581
1581
  ${JSON.stringify(t.verifyResults,null,2)}
1582
1582
 
1583
+ Heal iterations used: ${t.healIterations}
1584
+
1583
1585
  Create a ship-ready summary with next steps.`,l=await a.runToResult(c);if(l.status!=="succeeded"||!l.message)throw new Error(`ship phase failed: ${G(l)}`);let d=t.buildResults?.filesChanged.length??0,u=t.healIterations;return gt({kind:"checkpoint",title:"ship \u2014 done",body:[`Files changed: ${d}`,`Heal iterations: ${u}`,`Idea: ${t.idea}`]}),l.message.content}$();import{existsSync as Tc,mkdirSync as ly,readFileSync as dy,unlinkSync as uy,writeFileSync as py}from"fs";import{dirname as fy,join as my}from"path";function so(t){return my(wt(),t,"mint-state.json")}function Rc(t,e){let n=so(t);ly(fy(n),{recursive:!0}),py(n,JSON.stringify(e,null,2),"utf-8")}function gy(t){if(typeof t!="object"||t===null)return!1;let e=t;return typeof e.currentPhase=="string"&&typeof e.idea=="string"&&typeof e.spec=="string"&&typeof e.healIterations=="number"&&Array.isArray(e.history)}function Ic(t){let e=so(t);if(!Tc(e))return null;try{let n=JSON.parse(dy(e,"utf-8"));return gy(n)?n:null}catch{return null}}function io(t){let e=so(t);if(Tc(e))try{uy(e)}catch{}}var hy=2,Pc=/^\s*(?:--continue(?:\s+(?:approved|yes|y))?|approved?|yes|y|lgtm|sure)\s*$/i,yy='To approve and run the rest of the pipeline, say "approve", "yes", "sure", or "lgtm" \u2014 or invoke /mint --continue approved. The handler will reload the spec state from disk.';function Se(t,e,n){t.history.push({phase:e,output:n,timestamp:Date.now()})}function Dc(t){if("completed"in t&&"paused"in t)throw new Error("mint: invariant violation \u2014 MintResult carries both completed and paused keys simultaneously")}var Cc=240;function by(t){return t.length<=Cc?t:t.slice(0,Cc)+"\u2026"}function Lc(t){if(typeof t=="string"){if(Pc.test(t))return{userApproved:!0};if(t.length>1&&t.trimStart().startsWith("{"))try{let e=JSON.parse(t);if(typeof e=="object"&&e!==null)return Lc(e)}catch{}return{idea:t}}if(typeof t=="object"&&t!==null){let e=t,n=typeof e.idea=="string"?e.idea:void 0;if(n!==void 0&&Pc.test(n))return{userApproved:!0};if("idea"in e||"resumeFrom"in e||e.userApproved===!0)return e}throw new Error("mint handler requires input.idea (string), input as string, or {userApproved: true} to resume")}async function Oc(t,e,n){if(!e.sessionId)throw new Error("runPhasesAfterSpec requires parentSession.sessionId");let r=e.sessionId,o=e.cwd;try{t.currentPhase="research",t.research=await Sc(t.spec,r,o,n),Se(t,"research",t.research),t.currentPhase="plan",t.plan=await vc(t.spec,t.research,r,o,n),Se(t,"plan",t.plan),t.currentPhase="parallelize";let s=await _c(t.plan,e,n);if(s.kind==="plan")t.waveOrchestrationPlan=s.plan,Se(t,"parallelize",JSON.stringify(s.plan));else if(s.kind==="skipped")t.waveOrchestrationPlan=void 0,Se(t,"parallelize",`skipped: ${s.reason}`);else if(s.kind==="failed"){t.waveOrchestrationPlan=void 0;let c=by(s.error);Se(t,"parallelize",`failed: ${c}`),J({event:"fallback.inline",parent_session_id:r,reason:"parallelize-dispatch-failed",error_message:c}),console.warn(`[mint] parallelize dispatch failed (single-lane fallback): ${c}`)}else{let c=s}t.currentPhase="build",t.buildResults=await Ec(t.plan,t.waveOrchestrationPlan,r,o,n),Se(t,"build",JSON.stringify(t.buildResults)),t.currentPhase="verify",t.verifyResults=await Un(t.plan,t.buildResults,r,o,n),Se(t,"verify",JSON.stringify(t.verifyResults)),t.currentPhase="heal";let i=t.verifyResults.testsPassed&&t.verifyResults.lintPassed&&t.verifyResults.designReviewPassed;for(;!i&&t.healIterations<hy;){let c=await Ac(t.plan,t.buildResults,t.verifyResults,t.healIterations,e,n);t.healIterations=c.newHealIterations,t.verifyResults=c.newVerifyResults,i=c.healed,Se(t,"heal",`Iterations: ${t.healIterations}, Success: ${i}`)}if(!i)return{paused:!0,phase:"heal-failed",reason:`Heal capped at ${t.healIterations} iterations; still have failures`,state:t,nextStep:"Heal loop exhausted. Inspect verifyResults, fix manually, then re-invoke /mint with a fresh idea \u2014 resume is not supported from heal-failed."};t.currentPhase="ship";let a=await xc(t,r,o,n);return Se(t,"ship",a),{completed:!0,artifact:a,state:t}}catch(s){throw new Error(`mint failed at ${t.currentPhase}: ${s}`)}}function Mc(t,e){return Dc(e),("completed"in e||e.phase==="heal-failed")&&io(t),e}async function wy(t,e,n){let r=Lc(t);if(!e?.sessionId)throw new Error("mint handler requires a parent session to fork subagents");let o=e.sessionId,s=n?.callId;if(r.userApproved){let c=r.resumeFrom??Ic(o);if(!c)throw new Error("mint: no paused spec found for this session to continue. Run /mint <idea> first, then /mint --continue approved.");let l=await Oc(c,e,s);return Mc(o,l)}if(!r.idea)throw new Error("mint: no idea provided. Run /mint <idea> to start, or /mint --continue approved to resume a paused spec.");io(o);let i={currentPhase:"spec",idea:r.idea,healIterations:0,history:[]};try{i.spec=await kc(r.idea,o,e.cwd,s),Se(i,"spec",i.spec)}catch(c){throw new Error(`mint failed at spec: ${c}`)}if(!r.autoApprove){Rc(o,i);let c={paused:!0,phase:"spec",spec:i.spec,state:i,nextStep:yy};return Dc(c),c}let a=await Oc(i,e,s);return Mc(o,a)}var ky={name:"mint",description:"Takes a feature idea or refactor scope and delivers a ship-ready, verified implementation end-to-end",handler:wy,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, resume by invoking mint again with the literal string `"approved"` (or `"yes"`, `"lgtm"`, `"--continue approved"`) as the arguments. Equivalent JSON forms `{"userApproved": true}` and `{"idea": "approved"}` are also accepted. The handler reloads the spec state from disk and runs phases 2\u20138.',flags:["--continue"]};Q(ky);async function Sy(){throw new Error("service-setup is a fork skill; its handler should never be called directly. Invoke via the `skill` tool or `/service-setup` slash command.")}var vy={name:"service-setup",description:"Install an AFK background process (telegram bot or daemon) as a macOS LaunchAgent so it auto-starts on login and relaunches on crash. Runs pre-flight checks (e.g., refuses to install the telegram service with an invalid token, which would otherwise crash-loop under KeepAlive), invokes `afk service install`, verifies with `afk service status`, and surfaces the management cheatsheet. macOS-only \u2014 gracefully refuses on other platforms.",handler:Sy,context:"fork",whenToUse:"When the user wants to make `afk telegram start` or `afk daemon` always-on \u2014 i.e., survive reboot, crash, OOM. Triggers on phrasings like 'install as a service', 'auto-start on login', 'keep the bot running', 'launchd', 'always-on telegram', or right after a successful `/telegram-setup` when the user asks how to make it persistent."};Q(vy);async function _y(){throw new Error("telegram-setup is a fork skill; its handler should never be called directly. Invoke via the `skill` tool or `/telegram-setup` slash command.")}var Ey={name:"telegram-setup",description:"Guide the user through first-time Telegram bot onboarding without leaking the bearer token. Walks the user to run `afk telegram setup` in a terminal for token entry, then uses the sanctioned `afk telegram check-token`/`discover-chat`/`set-allowed-chat` subcommands to validate and finish allowlist setup \u2014 the token never enters the model context. Works in REPL or Telegram. Use when the user wants to set up Telegram push notifications for the first time, or to debug a partially-configured install.",handler:_y,context:"fork",whenToUse:`When the user wants to set up Telegram bot notifications for the first time, or when they say something like "set up telegram", "connect telegram", "enable push", or you detect that TELEGRAM_BOT_TOKEN is unset and they're asking for notifications.`};Q(Ey);$();import{readdirSync as Ty,readFileSync as Ry}from"fs";import{join as $c}from"path";var Ay=/(?<![a-zA-Z0-9_/-])--([a-z][a-z0-9-]*)(?![a-zA-Z0-9_-])/g;function Fc(t){return t.startsWith("--")?t:`--${t}`}function xy(t){let e=new Set;for(let n of t.matchAll(Ay))n[1]&&e.add(`--${n[1]}`);return Array.from(e).sort()}function ao(t){if(!t.startsWith(`---
1584
1586
  `))return{frontmatter:null,frontmatterFlags:null,body:t};let e=t.indexOf(`
1585
1587
  ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-afk",
3
- "version": "3.72.0",
3
+ "version": "3.73.1",
4
4
  "description": "CLI tool for interacting with AI agents via multiple interfaces",
5
5
  "main": "dist/index.mjs",
6
6
  "type": "module",