agentix-cli 0.117.0 → 0.118.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/README.md +5 -5
- package/dist/{App-UQP7UQYV.js → App-XMSNIAU6.js} +2 -2
- package/dist/{ChatApp-VGSP5O6N.js → ChatApp-BFYTIQF3.js} +2 -2
- package/dist/{agent-MO27U4Y7.js → agent-E6W5VBYH.js} +2 -2
- package/dist/{board-dashboard-CSS7XMIZ.js → board-dashboard-D5FQZKO4.js} +215 -101
- package/dist/board-dashboard-D5FQZKO4.js.map +1 -0
- package/dist/chunk-23SQSUBI.js +3 -0
- package/dist/chunk-23SQSUBI.js.map +1 -0
- package/dist/{chunk-VRXJW6JJ.js → chunk-2G227TF3.js} +2 -2
- package/dist/{chunk-HVZVFCJX.js → chunk-4PQREYBU.js} +2 -2
- package/dist/{chunk-4FU4BFCH.js → chunk-5NTWGUSJ.js} +3 -3
- package/dist/chunk-5NTWGUSJ.js.map +1 -0
- package/dist/{chunk-2WK5A3UV.js → chunk-5PR6DZYW.js} +3 -3
- package/dist/chunk-5PR6DZYW.js.map +1 -0
- package/dist/{chunk-4ELAUGOP.js → chunk-5UFIHT66.js} +2 -2
- package/dist/{chunk-CUZTLQH2.js → chunk-6PC4EZ4P.js} +2 -2
- package/dist/chunk-AD4QZZVN.js +8 -0
- package/dist/{failure-candidates-PBPF45GN.js.map → chunk-AD4QZZVN.js.map} +1 -1
- package/dist/chunk-B6OXEIOF.js +126 -0
- package/dist/chunk-B6OXEIOF.js.map +1 -0
- package/dist/chunk-BDJWN3PL.js +4 -0
- package/dist/chunk-BDJWN3PL.js.map +1 -0
- package/dist/{chunk-OJ7KM2UO.js → chunk-FSXWNVGL.js} +2 -2
- package/dist/{chunk-746KHKT4.js → chunk-FTZCNID3.js} +2 -2
- package/dist/{chunk-PFK3QO6S.js → chunk-GJKYOEDE.js} +2 -2
- package/dist/{chunk-BQ2HJ7TS.js → chunk-HK7TU5NX.js} +2 -2
- package/dist/{chunk-FJI5GRBH.js → chunk-IMLLHT7U.js} +3 -3
- package/dist/chunk-IMLLHT7U.js.map +1 -0
- package/dist/chunk-IOYRRGK7.js +2 -0
- package/dist/chunk-IOYRRGK7.js.map +1 -0
- package/dist/{chunk-T2VDHVYW.js → chunk-IVCFXLAR.js} +2 -2
- package/dist/{chunk-W7WNRPNQ.js → chunk-NDPU6AX2.js} +2 -2
- package/dist/{chunk-45GOH6F7.js → chunk-NG677JHW.js} +8 -8
- package/dist/chunk-NG677JHW.js.map +1 -0
- package/dist/{chunk-MSP25HE5.js → chunk-PVQPXZHE.js} +5 -5
- package/dist/{chunk-5PPMPCHG.js → chunk-RJBRYUKU.js} +2 -2
- package/dist/{chunk-QLWGLRT5.js → chunk-TJ7IUHC7.js} +2 -2
- package/dist/{chunk-J2YLOGNN.js → chunk-U46G24CD.js} +2 -2
- package/dist/{chunk-IZMXAXW3.js → chunk-V4PVGEWI.js} +196 -197
- package/dist/chunk-V4PVGEWI.js.map +1 -0
- package/dist/chunk-WCXXXAHV.js +3 -0
- package/dist/{chunk-DMHQIACQ.js.map → chunk-WCXXXAHV.js.map} +1 -1
- package/dist/{chunk-45YETJY4.js → chunk-XGOBZCYC.js} +2 -2
- package/dist/{chunk-CKQ2YDFP.js → chunk-ZDWE47LM.js} +8 -8
- package/dist/chunk-ZDWE47LM.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/{client-5UMNDY7Z.js → client-TSYZXEH7.js} +2 -2
- package/dist/{config-O44DOHFW.js → config-QAE3LNFQ.js} +2 -2
- package/dist/config-mutator-WRQ7MFQL.js +2 -0
- package/dist/{doctor-NKPH74F7.js → doctor-PVLVKLRA.js} +2 -2
- package/dist/failure-candidates-JNGUVBDG.js +2 -0
- package/dist/{grants-BRAVOGBP.js → grants-V2ZNLWSJ.js} +2 -2
- package/dist/index.d.ts +69 -2
- package/dist/index.js +1 -1
- package/dist/program-ZYG3YPH2.js +721 -0
- package/dist/program-ZYG3YPH2.js.map +1 -0
- package/dist/{promote-ZRNVPWTD.js → promote-IRBBEXGG.js} +2 -2
- package/dist/{push-bridge-VPTQNM43.js → push-bridge-325SXDGN.js} +2 -2
- package/dist/{query-HURONGKA.js → query-NAU7J34H.js} +2 -2
- package/dist/{registry-AYGFAKTC.js → registry-I5PXGCO6.js} +2 -2
- package/dist/{request-planner-ZZRSOBQZ.js → request-planner-CRG3OGGG.js} +2 -2
- package/dist/{review-candidates-KHH47PK7.js → review-candidates-HAP7P6SH.js} +2 -2
- package/dist/{routing-GUBKKWPT.js → routing-G33LLOTF.js} +2 -2
- package/dist/schedule-tool-IP7ZCQKI.js +2 -0
- package/dist/scheduler-QXLPYSNJ.js +2 -0
- package/dist/{seat-CVTTTE5V.js → seat-IJN7NETF.js} +2 -2
- package/dist/{select-OUTM6OBC.js → select-D7AZ2XZF.js} +2 -2
- package/dist/{set-enabled-2QKQRVUN.js → set-enabled-5YSDIQXU.js} +2 -2
- package/dist/{surface-usage-HCJTUS6Z.js → surface-usage-WSY4SHHL.js} +2 -2
- package/dist/{tool-XY7QGHLV.js → tool-GQIQWHWB.js} +2 -2
- package/dist/{tool-OFXHMLE5.js → tool-XADSW6NL.js} +2 -2
- package/dist/wiki-PPX3HYXW.js +2 -0
- package/dist/wiki-PPX3HYXW.js.map +1 -0
- package/package.json +1 -1
- package/dist/board-dashboard-CSS7XMIZ.js.map +0 -1
- package/dist/chunk-2WK5A3UV.js.map +0 -1
- package/dist/chunk-45GOH6F7.js.map +0 -1
- package/dist/chunk-4FU4BFCH.js.map +0 -1
- package/dist/chunk-CKQ2YDFP.js.map +0 -1
- package/dist/chunk-DMHQIACQ.js +0 -3
- package/dist/chunk-FJI5GRBH.js.map +0 -1
- package/dist/chunk-HYGMWCUU.js +0 -126
- package/dist/chunk-HYGMWCUU.js.map +0 -1
- package/dist/chunk-IZMXAXW3.js.map +0 -1
- package/dist/chunk-JIT5GPTX.js +0 -4
- package/dist/chunk-JIT5GPTX.js.map +0 -1
- package/dist/chunk-PMQ47IPT.js +0 -2
- package/dist/chunk-PMQ47IPT.js.map +0 -1
- package/dist/chunk-VEHTVYP6.js +0 -2
- package/dist/chunk-VEHTVYP6.js.map +0 -1
- package/dist/config-mutator-PRLY2TCE.js +0 -2
- package/dist/failure-candidates-PBPF45GN.js +0 -8
- package/dist/program-RHIJYCEJ.js +0 -703
- package/dist/program-RHIJYCEJ.js.map +0 -1
- package/dist/schedule-tool-VH77T3N3.js +0 -2
- package/dist/scheduler-SZ4YYXJE.js +0 -2
- package/dist/wiki-46GMWX34.js +0 -2
- /package/dist/{App-UQP7UQYV.js.map → App-XMSNIAU6.js.map} +0 -0
- /package/dist/{ChatApp-VGSP5O6N.js.map → ChatApp-BFYTIQF3.js.map} +0 -0
- /package/dist/{agent-MO27U4Y7.js.map → agent-E6W5VBYH.js.map} +0 -0
- /package/dist/{chunk-VRXJW6JJ.js.map → chunk-2G227TF3.js.map} +0 -0
- /package/dist/{chunk-HVZVFCJX.js.map → chunk-4PQREYBU.js.map} +0 -0
- /package/dist/{chunk-4ELAUGOP.js.map → chunk-5UFIHT66.js.map} +0 -0
- /package/dist/{chunk-CUZTLQH2.js.map → chunk-6PC4EZ4P.js.map} +0 -0
- /package/dist/{chunk-OJ7KM2UO.js.map → chunk-FSXWNVGL.js.map} +0 -0
- /package/dist/{chunk-746KHKT4.js.map → chunk-FTZCNID3.js.map} +0 -0
- /package/dist/{chunk-PFK3QO6S.js.map → chunk-GJKYOEDE.js.map} +0 -0
- /package/dist/{chunk-BQ2HJ7TS.js.map → chunk-HK7TU5NX.js.map} +0 -0
- /package/dist/{chunk-T2VDHVYW.js.map → chunk-IVCFXLAR.js.map} +0 -0
- /package/dist/{chunk-W7WNRPNQ.js.map → chunk-NDPU6AX2.js.map} +0 -0
- /package/dist/{chunk-MSP25HE5.js.map → chunk-PVQPXZHE.js.map} +0 -0
- /package/dist/{chunk-5PPMPCHG.js.map → chunk-RJBRYUKU.js.map} +0 -0
- /package/dist/{chunk-QLWGLRT5.js.map → chunk-TJ7IUHC7.js.map} +0 -0
- /package/dist/{chunk-J2YLOGNN.js.map → chunk-U46G24CD.js.map} +0 -0
- /package/dist/{chunk-45YETJY4.js.map → chunk-XGOBZCYC.js.map} +0 -0
- /package/dist/{client-5UMNDY7Z.js.map → client-TSYZXEH7.js.map} +0 -0
- /package/dist/{config-O44DOHFW.js.map → config-QAE3LNFQ.js.map} +0 -0
- /package/dist/{config-mutator-PRLY2TCE.js.map → config-mutator-WRQ7MFQL.js.map} +0 -0
- /package/dist/{doctor-NKPH74F7.js.map → doctor-PVLVKLRA.js.map} +0 -0
- /package/dist/{grants-BRAVOGBP.js.map → failure-candidates-JNGUVBDG.js.map} +0 -0
- /package/dist/{promote-ZRNVPWTD.js.map → grants-V2ZNLWSJ.js.map} +0 -0
- /package/dist/{push-bridge-VPTQNM43.js.map → promote-IRBBEXGG.js.map} +0 -0
- /package/dist/{query-HURONGKA.js.map → push-bridge-325SXDGN.js.map} +0 -0
- /package/dist/{registry-AYGFAKTC.js.map → query-NAU7J34H.js.map} +0 -0
- /package/dist/{routing-GUBKKWPT.js.map → registry-I5PXGCO6.js.map} +0 -0
- /package/dist/{request-planner-ZZRSOBQZ.js.map → request-planner-CRG3OGGG.js.map} +0 -0
- /package/dist/{review-candidates-KHH47PK7.js.map → review-candidates-HAP7P6SH.js.map} +0 -0
- /package/dist/{schedule-tool-VH77T3N3.js.map → routing-G33LLOTF.js.map} +0 -0
- /package/dist/{scheduler-SZ4YYXJE.js.map → schedule-tool-IP7ZCQKI.js.map} +0 -0
- /package/dist/{seat-CVTTTE5V.js.map → scheduler-QXLPYSNJ.js.map} +0 -0
- /package/dist/{surface-usage-HCJTUS6Z.js.map → seat-IJN7NETF.js.map} +0 -0
- /package/dist/{select-OUTM6OBC.js.map → select-D7AZ2XZF.js.map} +0 -0
- /package/dist/{set-enabled-2QKQRVUN.js.map → set-enabled-5YSDIQXU.js.map} +0 -0
- /package/dist/{wiki-46GMWX34.js.map → surface-usage-WSY4SHHL.js.map} +0 -0
- /package/dist/{tool-XY7QGHLV.js.map → tool-GQIQWHWB.js.map} +0 -0
- /package/dist/{tool-OFXHMLE5.js.map → tool-XADSW6NL.js.map} +0 -0
package/dist/chunk-JIT5GPTX.js
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import{c as C,e as w,f as _}from"./chunk-Y4CYQV7G.js";import{existsSync as O,mkdirSync as v,readdirSync as E,readFileSync as A,renameSync as R,writeFileSync as L}from"fs";import{resolve as b}from"path";function S(e,r){let t=e.list?` in the "${e.list}" list`:"",n=[`This card came from the operator's reminder "${e.title}"${t} (id ${e.id}).`];return n.push(r?`Do what the operator chose, then tick the reminder off: remindctl complete ${e.id}`:"Leave the reminder open; it will come back at a later check-in."),n}var D=["discard","keep","pause","approve"],d={title:120,ask:300,recommend:300,source:500,note:500,pendingPerAgent:25},N={defaultExpiryDays:3,maxExpiryDays:30};function m(e){return b(e,".agentx","approvals")}var T=/^[a-z0-9][a-z0-9-]{0,80}$/;function $(e){return T.test(e)}function I(e,r){if(!$(r))throw new Error(`invalid card id: ${r}`);return b(m(e),`${r}.json`)}function q(e,r){let t=new Date(e).toISOString().slice(0,10),n=r.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,40);return`${t}-${n||"card"}-${Math.random().toString(36).slice(2,6)}`}function f(e,r){v(m(e),{recursive:!0});let t=I(e,r.id),n=`${t}.${process.pid}.tmp`;L(n,JSON.stringify(r,null,2)+`
|
|
2
|
-
`),R(n,t)}function y(e,r){if(!$(r))return null;try{return JSON.parse(A(I(e,r),"utf-8"))}catch{return null}}function k(e,r){let t=m(e);if(!O(t))return[];let n=[];for(let i of E(t).filter(s=>s.endsWith(".json")&&!s.startsWith("_")).sort()){let s=y(e,i.slice(0,-5));s&&(!r||s.status===r)&&n.push(s)}return n}function o(e){return typeof e=="string"?e.replace(/\s+/g," ").trim():""}function j(e,r,t){let n=r+t.maxExpiryDays*864e5,i,s=o(e);if(!s)i=r+t.defaultExpiryDays*864e5;else{let a=/^(\d+)\s*([hd])$/i.exec(s);if(a)i=r+Number(a[1])*(a[2].toLowerCase()==="d"?864e5:36e5);else if(i=Date.parse(s),Number.isNaN(i))return{ok:!1,error:`expires must be an ISO date or time, or like "12h" / "3d" (got "${s}")`}}return i<=r?{ok:!1,error:"expires must be in the future"}:{ok:!0,at:new Date(Math.min(i,n)).toISOString()}}function z(e,r={}){let t=r.now??Date.now(),n=r.settings??N,i=o(e.title),s=o(e.ask),a=o(e.recommend),l=o(e.raised_by);if(!i)return{ok:!1,error:"title is required"};if(!s)return{ok:!1,error:"ask is required: the yes/no question"};if(!a)return{ok:!1,error:"recommend is required: your advice and why, in one line"};if(!l)return{ok:!1,error:"raised_by is required: the agent id"};if(i.length>d.title)return{ok:!1,error:`title is longer than ${d.title} characters`};if(s.length>d.ask)return{ok:!1,error:`ask is longer than ${d.ask} characters`};if(a.length>d.recommend)return{ok:!1,error:`recommend is longer than ${d.recommend} characters`};let x=o(e.if_silent).toLowerCase();if(!D.includes(x))return{ok:!1,error:`if_silent must be one of ${D.join(", ")}`};let g=j(e.expires,t,n);if(!g.ok)return g;let u=o(e.source);if(u.length>d.source)return{ok:!1,error:`source is longer than ${d.source} characters`};if(u&&/^[a-z][a-z0-9+.-]*:/i.test(u)&&!/^https?:\/\//i.test(u))return{ok:!1,error:"source must be an http(s) link or a plain reference"};let p=C(e);if(!p.ok)return p;let h,c=e.reply;return c&&typeof c=="object"&&o(c.channel)&&o(c.chatId)&&(h={channel:o(c.channel),chatId:o(c.chatId),...o(c.accountId)?{accountId:o(c.accountId)}:{}}),{ok:!0,card:{id:q(t,i),title:i,ask:s,recommend:a,if_silent:x,expires:g.at,...u?{source:u}:{},raised_by:l,...r.node?{node:r.node}:{},created_at:new Date(t).toISOString(),...h?{reply:h}:{},...p.value,...r.origin?{origin:r.origin}:{},status:"pending"}}}function J(e,r,t={}){let n=z(r,t);if(!n.ok)return n;let i=k(e,"pending").filter(s=>s.raised_by===n.card.raised_by).length;return i>=d.pendingPerAgent?{ok:!1,error:`${n.card.raised_by} already has ${i} cards waiting; wait for decisions before raising more`}:(f(e,n.card),n)}function P(e,r,t,n={}){let i=y(e,r);if(!i)return{ok:!1,error:`no card "${r}"`};if(i.status!=="pending")return{ok:!1,error:`card "${r}" is already ${i.status}`};let s=w(i,t,n);if(!s.ok)return s;let a=o(n.note).slice(0,d.note),l={...i,status:"decided",verdict:t,decided_by:n.by??"operator",decided_at:new Date(n.now??Date.now()).toISOString(),...a?{note:a}:{},...s.choice?{choice:s.choice}:{},...s.text?{text:s.text}:{}};return f(e,l),{ok:!0,card:l}}function U(e,r=Date.now()){let t=[];for(let n of k(e,"pending")){if(Date.parse(n.expires)>r)continue;let i={...n,status:"expired",outcome:n.if_silent,decided_by:"expiry",decided_at:new Date(r).toISOString()};f(e,i),t.push(i)}return t}function W(e){return k(e).filter(r=>r.status!=="pending"&&!r.agent_notified_at)}function G(e,r,t=Date.now()){let n=y(e,r);!n||n.agent_notified_at||f(e,{...n,agent_notified_at:new Date(t).toISOString()})}function Q(e){let r=e.status==="decided"?e.verdict==="yes"?"The operator said YES.":"The operator said NO.":`Nobody answered before it expired, so the default applied: ${e.outcome??e.if_silent}.`,t=[`[Approval result] Your decision card "${e.title}" (${e.id}) is closed.`,`Question: ${e.ask}`,r];return e.status==="decided"&&e.verdict==="yes"&&t.push(..._(e)),e.note&&t.push(`Operator note: ${e.note}`),e.source&&t.push(`Source: ${e.source}`),e.origin?.kind==="reminder"&&t.push(...S(e.origin,e.status==="decided"&&e.verdict==="yes")),e.reply&&t.push(`You raised it from ${e.reply.channel} chat ${e.reply.chatId}; reply there if the requester should know.`),e.node&&t.push(`The operator answered it on another machine; the card was forwarded from ${e.node}.`),t.push("Act on this result now. Do not raise the same card again."),t.join(`
|
|
3
|
-
`)}export{D as a,d as b,m as c,$ as d,y as e,k as f,J as g,P as h,U as i,W as j,G as k,Q as l};
|
|
4
|
-
//# sourceMappingURL=chunk-JIT5GPTX.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/approvals/cards.ts","../src/approvals/origin.ts"],"sourcesContent":["import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, writeFileSync } from \"fs\"\nimport { resolve } from \"path\"\nimport { answerLines, buildChoices, resolveAnswer, type CardChoices } from \"./choices\"\nimport { originLines, type CardOrigin } from \"./origin\"\n\n// --- Decision cards: what an agent asks the operator ---\n//\n// An agent that needs a yes/no from the operator writes a card instead of\n// asking in chat. A card says what it is, the question, what the agent\n// recommends, and what happens if nobody answers by `expires`. Nothing\n// waits forever: past `expires` the daemon applies `if_silent` (sweep.ts).\n//\n// Storage: one JSON file per card under `.agentx/approvals/`, written\n// atomically, like wiki proposals. The CLI, the dashboard and the daemon\n// are separate processes and all read the same files.\n//\n// Field names match the API (`if_silent`, `raised_by`), so a stored card is\n// exactly what `POST /approvals` accepted.\n\nexport type IfSilent = \"discard\" | \"keep\" | \"pause\" | \"approve\"\nexport const IF_SILENT_VALUES: readonly IfSilent[] = [\"discard\", \"keep\", \"pause\", \"approve\"]\n\nexport type CardStatus = \"pending\" | \"decided\" | \"expired\"\nexport type Verdict = \"yes\" | \"no\"\n\n/** Where the agent was asked, so the verdict can be taken back there. */\nexport interface ReplyTarget {\n channel: string\n chatId: string\n accountId?: string\n}\n\nexport interface DecisionCard extends CardChoices {\n id: string\n title: string\n ask: string\n recommend: string\n if_silent: IfSilent\n /** ISO time the default applies. Always set. */\n expires: string\n /** Link to the draft, PR or issue. */\n source?: string\n raised_by: string\n /** The mesh node the raising agent is on, when the card was forwarded\n * here from there (forward.ts, #668). Unset: this node. */\n node?: string\n created_at: string\n reply?: ReplyTarget\n status: CardStatus\n /** The operator's answer (status \"decided\"). */\n verdict?: Verdict\n /** What applied on expiry (status \"expired\"). */\n outcome?: IfSilent\n decided_by?: string\n decided_at?: string\n note?: string\n /** The option the operator picked, when the card offered choices. */\n choice?: string\n /** The message the operator approved, after any edit. */\n text?: string\n /** Set once the raising agent has been told the result. */\n agent_notified_at?: string\n /** What the card is about, when the daemon raised it (origin.ts). */\n origin?: CardOrigin\n}\n\nexport const CARD_LIMITS = {\n title: 120,\n ask: 300,\n recommend: 300,\n source: 500,\n note: 500,\n /** Pending cards one agent may have open at a time. */\n pendingPerAgent: 25,\n} as const\n\nexport interface CardSettings {\n defaultExpiryDays: number\n maxExpiryDays: number\n}\n\nexport const DEFAULT_CARD_SETTINGS: CardSettings = { defaultExpiryDays: 3, maxExpiryDays: 30 }\n\nexport function approvalsDir(root: string): string {\n return resolve(root, \".agentx\", \"approvals\")\n}\n\nconst CARD_ID_RE = /^[a-z0-9][a-z0-9-]{0,80}$/\n\nexport function isValidCardId(id: string): boolean {\n return CARD_ID_RE.test(id)\n}\n\nfunction fileFor(root: string, id: string): string {\n if (!isValidCardId(id)) throw new Error(`invalid card id: ${id}`)\n return resolve(approvalsDir(root), `${id}.json`)\n}\n\nexport function newCardId(now: number, title: string): string {\n const day = new Date(now).toISOString().slice(0, 10)\n const slug = title.toLowerCase().replace(/[^a-z0-9]+/g, \"-\").replace(/^-+|-+$/g, \"\").slice(0, 40)\n return `${day}-${slug || \"card\"}-${Math.random().toString(36).slice(2, 6)}`\n}\n\nexport function saveCard(root: string, card: DecisionCard): void {\n mkdirSync(approvalsDir(root), { recursive: true })\n const path = fileFor(root, card.id)\n const tmp = `${path}.${process.pid}.tmp`\n writeFileSync(tmp, JSON.stringify(card, null, 2) + \"\\n\")\n renameSync(tmp, path)\n}\n\nexport function readCard(root: string, id: string): DecisionCard | null {\n if (!isValidCardId(id)) return null\n try {\n return JSON.parse(readFileSync(fileFor(root, id), \"utf-8\")) as DecisionCard\n } catch {\n return null\n }\n}\n\n/** Cards, oldest first; only `status` ones when given. */\nexport function listCards(root: string, status?: CardStatus): DecisionCard[] {\n const dir = approvalsDir(root)\n if (!existsSync(dir)) return []\n const out: DecisionCard[] = []\n for (const f of readdirSync(dir).filter((f) => f.endsWith(\".json\") && !f.startsWith(\"_\")).sort()) {\n const c = readCard(root, f.slice(0, -5))\n if (c && (!status || c.status === status)) out.push(c)\n }\n return out\n}\n\nfunction oneLine(v: unknown): string {\n return typeof v === \"string\" ? v.replace(/\\s+/g, \" \").trim() : \"\"\n}\n\n/**\n * `expires` as given by an agent: an ISO date or time, or a relative\n * \"12h\" / \"3d\". Unset: the default. Always capped at maxExpiryDays, so a\n * card can't be parked for a year.\n */\nexport function resolveExpiry(input: unknown, now: number, settings: CardSettings): { ok: true; at: string } | { ok: false; error: string } {\n const max = now + settings.maxExpiryDays * 86_400_000\n let at: number\n const raw = oneLine(input)\n if (!raw) {\n at = now + settings.defaultExpiryDays * 86_400_000\n } else {\n const rel = /^(\\d+)\\s*([hd])$/i.exec(raw)\n if (rel) {\n at = now + Number(rel[1]) * (rel[2].toLowerCase() === \"d\" ? 86_400_000 : 3_600_000)\n } else {\n at = Date.parse(raw)\n if (Number.isNaN(at)) return { ok: false, error: `expires must be an ISO date or time, or like \"12h\" / \"3d\" (got \"${raw}\")` }\n }\n }\n if (at <= now) return { ok: false, error: \"expires must be in the future\" }\n return { ok: true, at: new Date(Math.min(at, max)).toISOString() }\n}\n\nexport interface CardInput {\n title?: unknown\n ask?: unknown\n recommend?: unknown\n if_silent?: unknown\n expires?: unknown\n source?: unknown\n raised_by?: unknown\n reply?: unknown\n choices?: unknown\n draft?: unknown\n say?: unknown\n context?: unknown\n}\n\n/** Validate what an agent sent and build a pending card. Never saves. */\nexport interface BuildCardOptions {\n now?: number\n settings?: CardSettings\n origin?: CardOrigin\n /** The peer the card was forwarded from. The daemon sets it after\n * checking the name against its mesh peers; never taken as sent. */\n node?: string\n}\n\nexport function buildCard(\n input: CardInput,\n opts: BuildCardOptions = {},\n): { ok: true; card: DecisionCard } | { ok: false; error: string } {\n const now = opts.now ?? Date.now()\n const settings = opts.settings ?? DEFAULT_CARD_SETTINGS\n const title = oneLine(input.title)\n const ask = oneLine(input.ask)\n const recommend = oneLine(input.recommend)\n const raisedBy = oneLine(input.raised_by)\n if (!title) return { ok: false, error: \"title is required\" }\n if (!ask) return { ok: false, error: \"ask is required: the yes/no question\" }\n if (!recommend) return { ok: false, error: \"recommend is required: your advice and why, in one line\" }\n if (!raisedBy) return { ok: false, error: \"raised_by is required: the agent id\" }\n if (title.length > CARD_LIMITS.title) return { ok: false, error: `title is longer than ${CARD_LIMITS.title} characters` }\n if (ask.length > CARD_LIMITS.ask) return { ok: false, error: `ask is longer than ${CARD_LIMITS.ask} characters` }\n if (recommend.length > CARD_LIMITS.recommend) return { ok: false, error: `recommend is longer than ${CARD_LIMITS.recommend} characters` }\n const ifSilent = oneLine(input.if_silent).toLowerCase()\n if (!IF_SILENT_VALUES.includes(ifSilent as IfSilent)) {\n return { ok: false, error: `if_silent must be one of ${IF_SILENT_VALUES.join(\", \")}` }\n }\n const expiry = resolveExpiry(input.expires, now, settings)\n if (!expiry.ok) return expiry\n const source = oneLine(input.source)\n if (source.length > CARD_LIMITS.source) return { ok: false, error: `source is longer than ${CARD_LIMITS.source} characters` }\n if (source && /^[a-z][a-z0-9+.-]*:/i.test(source) && !/^https?:\\/\\//i.test(source)) {\n return { ok: false, error: \"source must be an http(s) link or a plain reference\" }\n }\n const extras = buildChoices(input)\n if (!extras.ok) return extras\n let reply: ReplyTarget | undefined\n const r = input.reply as Record<string, unknown> | undefined\n if (r && typeof r === \"object\" && oneLine(r.channel) && oneLine(r.chatId)) {\n reply = { channel: oneLine(r.channel), chatId: oneLine(r.chatId), ...(oneLine(r.accountId) ? { accountId: oneLine(r.accountId) } : {}) }\n }\n return {\n ok: true,\n card: {\n id: newCardId(now, title),\n title,\n ask,\n recommend,\n if_silent: ifSilent as IfSilent,\n expires: expiry.at,\n ...(source ? { source } : {}),\n raised_by: raisedBy,\n ...(opts.node ? { node: opts.node } : {}),\n created_at: new Date(now).toISOString(),\n ...(reply ? { reply } : {}),\n ...extras.value,\n // Set by the daemon only (check-ins), never from what an agent sent.\n ...(opts.origin ? { origin: opts.origin } : {}),\n status: \"pending\",\n },\n }\n}\n\n/** Validate, enforce the per-agent cap, and save. */\nexport function createCard(\n root: string,\n input: CardInput,\n opts: BuildCardOptions = {},\n): { ok: true; card: DecisionCard } | { ok: false; error: string } {\n const built = buildCard(input, opts)\n if (!built.ok) return built\n const open = listCards(root, \"pending\").filter((c) => c.raised_by === built.card.raised_by).length\n if (open >= CARD_LIMITS.pendingPerAgent) {\n return { ok: false, error: `${built.card.raised_by} already has ${open} cards waiting; wait for decisions before raising more` }\n }\n saveCard(root, built.card)\n return built\n}\n\n/** Record the operator's answer. Refuses anything no longer pending. */\nexport function decideCard(\n root: string,\n id: string,\n verdict: Verdict,\n opts: { by?: string; note?: string; now?: number; choice?: string | number; text?: string } = {},\n): { ok: true; card: DecisionCard } | { ok: false; error: string } {\n const card = readCard(root, id)\n if (!card) return { ok: false, error: `no card \"${id}\"` }\n if (card.status !== \"pending\") return { ok: false, error: `card \"${id}\" is already ${card.status}` }\n const answer = resolveAnswer(card, verdict, opts)\n if (!answer.ok) return answer\n const note = oneLine(opts.note).slice(0, CARD_LIMITS.note)\n const decided: DecisionCard = {\n ...card,\n status: \"decided\",\n verdict,\n decided_by: opts.by ?? \"operator\",\n decided_at: new Date(opts.now ?? Date.now()).toISOString(),\n ...(note ? { note } : {}),\n ...(answer.choice ? { choice: answer.choice } : {}),\n ...(answer.text ? { text: answer.text } : {}),\n }\n saveCard(root, decided)\n return { ok: true, card: decided }\n}\n\n/** Apply `if_silent` to every pending card past its expiry. */\nexport function expireCards(root: string, now: number = Date.now()): DecisionCard[] {\n const out: DecisionCard[] = []\n for (const card of listCards(root, \"pending\")) {\n if (Date.parse(card.expires) > now) continue\n const expired: DecisionCard = {\n ...card,\n status: \"expired\",\n outcome: card.if_silent,\n decided_by: \"expiry\",\n decided_at: new Date(now).toISOString(),\n }\n saveCard(root, expired)\n out.push(expired)\n }\n return out\n}\n\n/** Decided or expired cards whose agent hasn't been told yet. */\nexport function cardsAwaitingAgentNotice(root: string): DecisionCard[] {\n return listCards(root).filter((c) => c.status !== \"pending\" && !c.agent_notified_at)\n}\n\nexport function markAgentNotified(root: string, id: string, now: number = Date.now()): void {\n const card = readCard(root, id)\n if (!card || card.agent_notified_at) return\n saveCard(root, { ...card, agent_notified_at: new Date(now).toISOString() })\n}\n\n/** What the raising agent is told. Plain text, one short message. */\nexport function verdictMessage(card: DecisionCard): string {\n const result = card.status === \"decided\"\n ? (card.verdict === \"yes\" ? \"The operator said YES.\" : \"The operator said NO.\")\n : `Nobody answered before it expired, so the default applied: ${card.outcome ?? card.if_silent}.`\n const lines = [\n `[Approval result] Your decision card \"${card.title}\" (${card.id}) is closed.`,\n `Question: ${card.ask}`,\n result,\n ]\n if (card.status === \"decided\" && card.verdict === \"yes\") lines.push(...answerLines(card))\n if (card.note) lines.push(`Operator note: ${card.note}`)\n if (card.source) lines.push(`Source: ${card.source}`)\n if (card.origin?.kind === \"reminder\") lines.push(...originLines(card.origin, card.status === \"decided\" && card.verdict === \"yes\"))\n if (card.reply) lines.push(`You raised it from ${card.reply.channel} chat ${card.reply.chatId}; reply there if the requester should know.`)\n if (card.node) lines.push(`The operator answered it on another machine; the card was forwarded from ${card.node}.`)\n lines.push(\"Act on this result now. Do not raise the same card again.\")\n return lines.join(\"\\n\")\n}\n","// --- Where a card came from, when the daemon raised it ---\n//\n// Agents raise most cards themselves. A check-in (checkin.ts) raises one on\n// an agent's behalf for an open Apple Reminder, and records the reminder\n// here so the agent that gets the answer knows what to act on and what to\n// tick off. Only the daemon sets it: POST /approvals and the agent tool\n// never pass it through.\n\nexport interface ReminderOrigin {\n kind: \"reminder\"\n /** The reminder's full id, as remindctl prints it. */\n id: string\n title: string\n list?: string\n}\n\n/** An open request that needs attention, shown as a card on the Mac\n * (popup-runner.ts). Never stored: the request is the record. */\nexport interface RequestOrigin {\n kind: \"request\"\n id: string\n}\n\nexport type CardOrigin = ReminderOrigin | RequestOrigin\n\n/** Lines for the owning agent's result message. */\nexport function originLines(origin: ReminderOrigin, approved: boolean): string[] {\n const where = origin.list ? ` in the \"${origin.list}\" list` : \"\"\n const lines = [`This card came from the operator's reminder \"${origin.title}\"${where} (id ${origin.id}).`]\n lines.push(approved\n ? `Do what the operator chose, then tick the reminder off: remindctl complete ${origin.id}`\n : \"Leave the reminder open; it will come back at a later check-in.\")\n return lines\n}\n"],"mappings":"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","names":["existsSync","mkdirSync","readdirSync","readFileSync","renameSync","writeFileSync","resolve","originLines","origin","approved","where","lines","IF_SILENT_VALUES","CARD_LIMITS","DEFAULT_CARD_SETTINGS","approvalsDir","root","resolve","CARD_ID_RE","isValidCardId","id","fileFor","newCardId","now","title","day","slug","saveCard","card","mkdirSync","path","tmp","writeFileSync","renameSync","readCard","readFileSync","listCards","status","dir","existsSync","out","f","readdirSync","c","oneLine","v","resolveExpiry","input","settings","max","at","raw","rel","buildCard","opts","ask","recommend","raisedBy","ifSilent","expiry","source","extras","buildChoices","reply","r","createCard","built","open","decideCard","verdict","answer","resolveAnswer","note","decided","expireCards","expired","cardsAwaitingAgentNotice","markAgentNotified","verdictMessage","result","lines","answerLines","originLines"]}
|
package/dist/chunk-PMQ47IPT.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as o}from"./chunk-BQ2HJ7TS.js";import{resolve as a}from"path";import{existsSync as d,readdirSync as c,mkdirSync as l}from"fs";var g=class{baseDir;agentsDir;mode;sharedStore;agentStores=new Map;log;constructor(t=a(process.cwd(),".agentx/wiki"),e=console.error.bind(console,"[wiki-hub]"),r="graph"){this.baseDir=t,this.agentsDir=a(t,"agents"),this.mode=r,this.log=e,l(this.agentsDir,{recursive:!0}),this.sharedStore=new o(t,e)}getMode(){return this.mode}getAgentWiki(t){let e=`${t}:${this.mode}`;if(this.agentStores.has(e))return this.agentStores.get(e);let r=a(this.agentsDir,t,this.mode),i=new o(r,this.log);return this.agentStores.set(e,i),i}getBaseDir(){return this.baseDir}getSharedStore(){return this.sharedStore}listAgents(){let t=new Set,e=this.sharedStore.listEntries();for(let r of e)t.add(r.agentId);if(d(this.agentsDir))for(let r of c(this.agentsDir))!r.startsWith("_")&&!r.startsWith(".")&&t.add(r);return[...t].sort()}getAgentEntries(t){return this.sharedStore.listEntries({agentId:t})}getUnabsorbedEntries(t){let e=this.getAgentWiki(t),r=this.getAgentEntries(t),i=new Set,n=e.rebuildIndex();for(let s of n.articles)if(s.sources)for(let h of s.sources)i.add(h);return r.filter(s=>!i.has(s.id))}summary(){return this.listAgents().map(e=>{let r=this.getAgentEntries(e),n=this.getAgentWiki(e).rebuildIndex(),s=this.getUnabsorbedEntries(e);return{agentId:e,totalEntries:r.length,totalArticles:n.articles.length,unabsorbed:s.length,articles:n.articles}})}};export{g as a};
|
|
2
|
-
//# sourceMappingURL=chunk-PMQ47IPT.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/wiki/hub.ts"],"sourcesContent":["import { WikiStore } from \"./store\"\nimport { resolve } from \"path\"\nimport { existsSync, readdirSync, mkdirSync } from \"fs\"\nimport type { WikiEntry } from \"./types\"\n\nexport type WikiMode = \"flat\" | \"graph\" | \"unified\"\n\n/**\n * WikiHub: manages per-agent wikis with a shared raw entry pool.\n * Supports two compilation modes:\n * - flat: Karpathy pattern — tags, LLM-chosen paths, worldview, gap detection\n * - graph: Knowledge graph — kind, parent, hierarchy, events, entities\n *\n * Both modes share the same raw entries. Articles stored separately:\n * agents/<id>/flat/ ← Karpathy compilation\n * agents/<id>/graph/ ← Knowledge graph compilation\n */\nexport class WikiHub {\n private baseDir: string\n private agentsDir: string\n private mode: WikiMode\n private sharedStore: WikiStore\n private agentStores: Map<string, WikiStore> = new Map()\n private log: (...args: unknown[]) => void\n\n constructor(\n baseDir: string = resolve(process.cwd(), \".agentx/wiki\"),\n log: (...args: unknown[]) => void = console.error.bind(console, \"[wiki-hub]\"),\n mode: WikiMode = \"graph\",\n ) {\n this.baseDir = baseDir\n this.agentsDir = resolve(baseDir, \"agents\")\n this.mode = mode\n this.log = log\n\n mkdirSync(this.agentsDir, { recursive: true })\n this.sharedStore = new WikiStore(baseDir, log)\n }\n\n getMode(): WikiMode { return this.mode }\n\n /**\n * Get or create the wiki store for a specific agent (mode-aware).\n * flat: agents/<id>/flat/\n * graph: agents/<id>/graph/\n */\n getAgentWiki(agentId: string): WikiStore {\n const key = `${agentId}:${this.mode}`\n if (this.agentStores.has(key)) return this.agentStores.get(key)!\n\n const agentDir = resolve(this.agentsDir, agentId, this.mode)\n const store = new WikiStore(agentDir, this.log)\n this.agentStores.set(key, store)\n return store\n }\n\n /** The wiki root: shared sidecars (_facts.json, _questions.json) live here. */\n getBaseDir(): string {\n return this.baseDir\n }\n\n getSharedStore(): WikiStore {\n return this.sharedStore\n }\n\n listAgents(): string[] {\n const agents = new Set<string>()\n\n const entries = this.sharedStore.listEntries()\n for (const e of entries) agents.add(e.agentId)\n\n if (existsSync(this.agentsDir)) {\n for (const dir of readdirSync(this.agentsDir)) {\n if (!dir.startsWith(\"_\") && !dir.startsWith(\".\")) {\n agents.add(dir)\n }\n }\n }\n\n return [...agents].sort()\n }\n\n getAgentEntries(agentId: string): WikiEntry[] {\n return this.sharedStore.listEntries({ agentId })\n }\n\n getUnabsorbedEntries(agentId: string): WikiEntry[] {\n const agentWiki = this.getAgentWiki(agentId)\n const agentEntries = this.getAgentEntries(agentId)\n\n const absorbedIds = new Set<string>()\n const index = agentWiki.rebuildIndex()\n for (const article of index.articles) {\n if (article.sources) {\n for (const s of article.sources) absorbedIds.add(s)\n }\n }\n\n return agentEntries.filter(e => !absorbedIds.has(e.id))\n }\n\n summary(): AgentWikiSummary[] {\n const agents = this.listAgents()\n return agents.map(agentId => {\n const entries = this.getAgentEntries(agentId)\n const wiki = this.getAgentWiki(agentId)\n const index = wiki.rebuildIndex()\n const unabsorbed = this.getUnabsorbedEntries(agentId)\n\n return {\n agentId,\n totalEntries: entries.length,\n totalArticles: index.articles.length,\n unabsorbed: unabsorbed.length,\n articles: index.articles,\n }\n })\n }\n}\n\nexport interface AgentWikiSummary {\n agentId: string\n totalEntries: number\n totalArticles: number\n unabsorbed: number\n articles: Array<{ title: string; path: string; tags?: string[] }>\n}\n"],"mappings":"wCACA,OAAS,WAAAA,MAAe,OACxB,OAAS,cAAAC,EAAY,eAAAC,EAAa,aAAAC,MAAiB,KAe5C,IAAMC,EAAN,KAAc,CACX,QACA,UACA,KACA,YACA,YAAsC,IAAI,IAC1C,IAER,YACEC,EAAkBL,EAAQ,QAAQ,IAAI,EAAG,cAAc,EACvDM,EAAoC,QAAQ,MAAM,KAAK,QAAS,YAAY,EAC5EC,EAAiB,QACjB,CACA,KAAK,QAAUF,EACf,KAAK,UAAYL,EAAQK,EAAS,QAAQ,EAC1C,KAAK,KAAOE,EACZ,KAAK,IAAMD,EAEXH,EAAU,KAAK,UAAW,CAAE,UAAW,EAAK,CAAC,EAC7C,KAAK,YAAc,IAAIK,EAAUH,EAASC,CAAG,CAC/C,CAEA,SAAoB,CAAE,OAAO,KAAK,IAAK,CAOvC,aAAaG,EAA4B,CACvC,IAAMC,EAAM,GAAGD,KAAW,KAAK,OAC/B,GAAI,KAAK,YAAY,IAAIC,CAAG,EAAG,OAAO,KAAK,YAAY,IAAIA,CAAG,EAE9D,IAAMC,EAAWX,EAAQ,KAAK,UAAWS,EAAS,KAAK,IAAI,EACrDG,EAAQ,IAAIJ,EAAUG,EAAU,KAAK,GAAG,EAC9C,YAAK,YAAY,IAAID,EAAKE,CAAK,EACxBA,CACT,CAGA,YAAqB,CACnB,OAAO,KAAK,OACd,CAEA,gBAA4B,CAC1B,OAAO,KAAK,WACd,CAEA,YAAuB,CACrB,IAAMC,EAAS,IAAI,IAEbC,EAAU,KAAK,YAAY,YAAY,EAC7C,QAAWC,KAAKD,EAASD,EAAO,IAAIE,EAAE,OAAO,EAE7C,GAAId,EAAW,KAAK,SAAS,EAC3B,QAAWe,KAAOd,EAAY,KAAK,SAAS,EACtC,CAACc,EAAI,WAAW,GAAG,GAAK,CAACA,EAAI,WAAW,GAAG,GAC7CH,EAAO,IAAIG,CAAG,EAKpB,MAAO,CAAC,GAAGH,CAAM,EAAE,KAAK,CAC1B,CAEA,gBAAgBJ,EAA8B,CAC5C,OAAO,KAAK,YAAY,YAAY,CAAE,QAAAA,CAAQ,CAAC,CACjD,CAEA,qBAAqBA,EAA8B,CACjD,IAAMQ,EAAY,KAAK,aAAaR,CAAO,EACrCS,EAAe,KAAK,gBAAgBT,CAAO,EAE3CU,EAAc,IAAI,IAClBC,EAAQH,EAAU,aAAa,EACrC,QAAWI,KAAWD,EAAM,SAC1B,GAAIC,EAAQ,QACV,QAAWC,KAAKD,EAAQ,QAASF,EAAY,IAAIG,CAAC,EAItD,OAAOJ,EAAa,OAAOH,GAAK,CAACI,EAAY,IAAIJ,EAAE,EAAE,CAAC,CACxD,CAEA,SAA8B,CAE5B,OADe,KAAK,WAAW,EACjB,IAAIN,GAAW,CAC3B,IAAMK,EAAU,KAAK,gBAAgBL,CAAO,EAEtCW,EADO,KAAK,aAAaX,CAAO,EACnB,aAAa,EAC1Bc,EAAa,KAAK,qBAAqBd,CAAO,EAEpD,MAAO,CACL,QAAAA,EACA,aAAcK,EAAQ,OACtB,cAAeM,EAAM,SAAS,OAC9B,WAAYG,EAAW,OACvB,SAAUH,EAAM,QAClB,CACF,CAAC,CACH,CACF","names":["resolve","existsSync","readdirSync","mkdirSync","WikiHub","baseDir","log","mode","WikiStore","agentId","key","agentDir","store","agents","entries","e","dir","agentWiki","agentEntries","absorbedIds","index","article","s","unabsorbed"]}
|
package/dist/chunk-VEHTVYP6.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{q as p}from"./chunk-HYGMWCUU.js";import{b as i,c as u,d as l,e as c}from"./chunk-HVZVFCJX.js";import d from"cronstrue";var f=Intl.DateTimeFormat().resolvedOptions().timeZone,m=600,E='Try: "every morning at 9", "weekdays at 6pm", "every 15 minutes", "every monday at 10am", "1st of every month at noon", "daily at 9:30am", "every hour"',g=/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/;function w(e){return g.test(e)}function x(e){try{return new Intl.DateTimeFormat("en-US",{timeZone:e}),!0}catch{return!1}}function $(e){return e?e.split(",").map(r=>r.trim().toLowerCase()).filter(r=>r==="log"||r==="notify"||r==="disable"):["log"]}function S(e){let r=[...e.onError??["log"]];e.notify&&!r.includes("notify")&&r.push("notify");let t={enabled:e.enabled??!0,schedule:e.parsed.cron,timezone:e.timezone||f,agent:e.agent,prompt:e.prompt,timeout:e.timeout??m,onError:r};return e.model&&(t.model=e.model),e.notify&&(t.notify=e.notify),e.createdBy&&(t.createdBy=e.createdBy),e.approval&&(t.approval=e.approval),t}function P(e){try{return d.toString(e,{use24HourTimeFormat:!1})}catch{return e}}function T(e,r,t=new Date){try{return p(e,t,r)}catch{return null}}function A(e,r){if(!e)return"unknown (no match within a year)";try{return`${new Intl.DateTimeFormat("en-GB",{timeZone:r,weekday:"short",day:"2-digit",month:"short",year:"numeric",hour:"2-digit",minute:"2-digit",hour12:!1}).format(e)} (${r})`}catch{return e.toISOString()}}function h(e){return e?.approval?.action==="create"}async function D(e,r={}){let t="",o=await i(n=>{let a=l(n,`crons.${e}`);if(!a)throw new Error(`cron "${e}" not found`);let s=a.approval;if(!s)throw new Error(`cron "${e}" has no pending request`);s.action==="create"?(delete a.approval,a.enabled=!0,t=`${e} approved and enabled (requested by ${s.requestedBy})`):(c(n,`crons.${e}`),t=`${e} deletion approved; job removed (requested by ${s.requestedBy})`)},{configPath:r.configPath,reload:r.reload});return o.success?{success:!0,message:t,result:o}:{success:!1,message:o.error||"failed",result:o}}async function I(e,r={}){let t="",o=await i(n=>{let a=l(n,`crons.${e}`);if(!a)throw new Error(`cron "${e}" not found`);let s=a.approval;if(!s)throw new Error(`cron "${e}" has no pending request`);s.action==="create"?(c(n,`crons.${e}`),t=`${e} rejected; pending job removed`):(delete a.approval,t=`${e} deletion rejected; job kept`)},{configPath:r.configPath,reload:r.reload});return o.success?{success:!0,message:t,result:o}:{success:!1,message:o.error||"failed",result:o}}async function O(e,r,t={}){return i(o=>{let n=l(o,`crons.${e}`);if(!n)throw new Error(`cron "${e}" not found`);if(r&&h(n))throw new Error(`cron "${e}" is awaiting approval; run \`agentx schedule approve ${e}\``);u(o,`crons.${e}.enabled`,r)},{configPath:t.configPath,reload:t.reload})}export{f as a,E as b,w as c,x as d,$ as e,S as f,P as g,T as h,A as i,h as j,D as k,I as l,O as m};
|
|
2
|
-
//# sourceMappingURL=chunk-VEHTVYP6.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/crons/schedule-ops.ts"],"sourcesContent":["import cronstrue from \"cronstrue\"\nimport { applyConfigMutation, getAtPath, setAtPath, unsetAtPath, type MutationResult } from \"@/daemon/config-mutator\"\nimport type { NlCronResult } from \"@/utils/nl-cron\"\nimport { getNextCronDate } from \"./scheduler\"\n\n// --- Shared schedule operations ---\n//\n// One code path for everything that writes a `crons.<id>` entry from a\n// natural-language schedule: the `agentx schedule` CLI and the agent-facing\n// `agentx_schedule` MCP tool both build jobs here, so the two can never\n// drift into writing different shapes.\n//\n// Also owns the operator side of the approval flow (approve / reject), which\n// only the CLI exposes. Agents can request; they cannot approve.\n\nexport type OnErrorValue = \"log\" | \"notify\" | \"disable\"\n\nexport interface NotifyTarget {\n channel: string\n chatId: string\n accountId?: string\n}\n\nexport interface ScheduleApproval {\n action: \"create\" | \"delete\"\n requestedBy: string\n requestedAt: string\n}\n\n/** Default timezone for schedules created without one: this machine's, the\n * same as the CLI's `--timezone` default. */\nexport const DEFAULT_SCHEDULE_TIMEZONE = Intl.DateTimeFormat().resolvedOptions().timeZone\nexport const DEFAULT_SCHEDULE_TIMEOUT = 600\n\nexport const SUPPORTED_PHRASES_HINT =\n 'Try: \"every morning at 9\", \"weekdays at 6pm\", \"every 15 minutes\", \"every monday at 10am\", ' +\n '\"1st of every month at noon\", \"daily at 9:30am\", \"every hour\"'\n\n/** Cron ids become a dot-path segment (`crons.<id>`), so dots and other\n * separators are refused rather than silently nesting the config. */\nconst SCHEDULE_ID_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/\n\nexport function isValidScheduleId(id: string): boolean {\n return SCHEDULE_ID_RE.test(id)\n}\n\nexport function isValidTimezone(tz: string): boolean {\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: tz })\n return true\n } catch {\n return false\n }\n}\n\nexport function parseOnError(flag: string | undefined): OnErrorValue[] {\n if (!flag) return [\"log\"]\n return flag\n .split(\",\")\n .map((s) => s.trim().toLowerCase())\n .filter((s): s is OnErrorValue => s === \"log\" || s === \"notify\" || s === \"disable\")\n}\n\nexport interface ScheduleJobInput {\n parsed: NlCronResult\n agent: string\n prompt: string\n timezone?: string\n timeout?: number\n model?: string\n notify?: NotifyTarget\n onError?: OnErrorValue[]\n enabled?: boolean\n createdBy?: string\n approval?: ScheduleApproval\n}\n\n/** Build the `crons.<id>` object. A notify target implies the \"notify\"\n * error mode, exactly as the CLI always did. */\nexport function buildScheduleJob(input: ScheduleJobInput): Record<string, unknown> {\n const onError = [...(input.onError ?? [\"log\"])]\n if (input.notify && !onError.includes(\"notify\")) onError.push(\"notify\")\n\n const job: Record<string, unknown> = {\n enabled: input.enabled ?? true,\n schedule: input.parsed.cron,\n timezone: input.timezone || DEFAULT_SCHEDULE_TIMEZONE,\n agent: input.agent,\n prompt: input.prompt,\n timeout: input.timeout ?? DEFAULT_SCHEDULE_TIMEOUT,\n onError,\n }\n if (input.model) job.model = input.model\n if (input.notify) job.notify = input.notify\n if (input.createdBy) job.createdBy = input.createdBy\n if (input.approval) job.approval = input.approval\n return job\n}\n\nexport function humanizeCron(cron: string): string {\n try {\n return cronstrue.toString(cron, { use24HourTimeFormat: false })\n } catch {\n return cron\n }\n}\n\nexport function nextFireTime(cron: string, timezone: string, now: Date = new Date()): Date | null {\n try {\n return getNextCronDate(cron, now, timezone)\n } catch {\n return null\n }\n}\n\n/** \"Mon, 28 Sep 2026, 10:00 (<tz>)\" — the wall-clock time where the job\n * runs, which is what an operator reading an approval request cares about. */\nexport function formatFireTime(d: Date | null, timezone: string): string {\n if (!d) return \"unknown (no match within a year)\"\n try {\n const local = new Intl.DateTimeFormat(\"en-GB\", {\n timeZone: timezone,\n weekday: \"short\",\n day: \"2-digit\",\n month: \"short\",\n year: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false,\n }).format(d)\n return `${local} (${timezone})`\n } catch {\n return d.toISOString()\n }\n}\n\nexport function isPendingCreate(job: any): boolean {\n return job?.approval?.action === \"create\"\n}\n\n// ── Operator approval ────────────────────────────────────────────────\n\nexport interface ApprovalOutcome {\n success: boolean\n /** What happened, for the CLI to print. */\n message: string\n result?: MutationResult\n}\n\n/**\n * Apply a pending agent request. `create` → enable and clear the marker;\n * `delete` → remove the job. Hot-reloads the daemon through the same\n * mutator the CLI uses.\n */\nexport async function approveSchedule(\n id: string,\n opts: { configPath?: string; reload?: boolean } = {},\n): Promise<ApprovalOutcome> {\n let message = \"\"\n const result = await applyConfigMutation((cfg) => {\n const job: any = getAtPath(cfg, `crons.${id}`)\n if (!job) throw new Error(`cron \"${id}\" not found`)\n const approval = job.approval as ScheduleApproval | undefined\n if (!approval) throw new Error(`cron \"${id}\" has no pending request`)\n if (approval.action === \"create\") {\n delete job.approval\n job.enabled = true\n message = `${id} approved and enabled (requested by ${approval.requestedBy})`\n } else {\n unsetAtPath(cfg, `crons.${id}`)\n message = `${id} deletion approved; job removed (requested by ${approval.requestedBy})`\n }\n }, { configPath: opts.configPath, reload: opts.reload })\n if (!result.success) return { success: false, message: result.error || \"failed\", result }\n return { success: true, message, result }\n}\n\n/** Refuse a pending request. `create` → drop the never-run job; `delete` →\n * keep the job exactly as it was and clear the marker. */\nexport async function rejectSchedule(\n id: string,\n opts: { configPath?: string; reload?: boolean } = {},\n): Promise<ApprovalOutcome> {\n let message = \"\"\n const result = await applyConfigMutation((cfg) => {\n const job: any = getAtPath(cfg, `crons.${id}`)\n if (!job) throw new Error(`cron \"${id}\" not found`)\n const approval = job.approval as ScheduleApproval | undefined\n if (!approval) throw new Error(`cron \"${id}\" has no pending request`)\n if (approval.action === \"create\") {\n unsetAtPath(cfg, `crons.${id}`)\n message = `${id} rejected; pending job removed`\n } else {\n delete job.approval\n message = `${id} deletion rejected; job kept`\n }\n }, { configPath: opts.configPath, reload: opts.reload })\n if (!result.success) return { success: false, message: result.error || \"failed\", result }\n return { success: true, message, result }\n}\n\n/** Enable/disable, refusing to enable a job still awaiting approval. */\nexport async function setScheduleEnabled(\n id: string,\n enabled: boolean,\n opts: { configPath?: string; reload?: boolean } = {},\n): Promise<MutationResult> {\n return applyConfigMutation((cfg) => {\n const job: any = getAtPath(cfg, `crons.${id}`)\n if (!job) throw new Error(`cron \"${id}\" not found`)\n if (enabled && isPendingCreate(job)) {\n throw new Error(`cron \"${id}\" is awaiting approval; run \\`agentx schedule approve ${id}\\``)\n }\n setAtPath(cfg, `crons.${id}.enabled`, enabled)\n }, { configPath: opts.configPath, reload: opts.reload })\n}\n"],"mappings":"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","names":["cronstrue","DEFAULT_SCHEDULE_TIMEZONE","DEFAULT_SCHEDULE_TIMEOUT","SUPPORTED_PHRASES_HINT","SCHEDULE_ID_RE","isValidScheduleId","id","isValidTimezone","tz","parseOnError","flag","s","buildScheduleJob","input","onError","job","humanizeCron","cron","cronstrue","nextFireTime","timezone","now","getNextCronDate","formatFireTime","d","isPendingCreate","approveSchedule","opts","message","result","applyConfigMutation","cfg","getAtPath","approval","unsetAtPath","rejectSchedule","setScheduleEnabled","enabled","setAtPath"]}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a,b,c,d,e}from"./chunk-HVZVFCJX.js";import"./chunk-FJI5GRBH.js";import"./chunk-BRK6M6LA.js";import"./chunk-UIBUZ2N3.js";import"./chunk-2QNT5JDS.js";import"./chunk-QIJLFPWE.js";export{b as applyConfigMutation,a as findConfigPath,d as getAtPath,c as setAtPath,e as unsetAtPath};
|
|
2
|
-
//# sourceMappingURL=config-mutator-PRLY2TCE.js.map
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import{f,k as I}from"./chunk-GLQLCBJS.js";import"./chunk-FCPTN6NF.js";import"./chunk-QIJLFPWE.js";import{createHash as $}from"crypto";var k="failure:",x=3,p=5,A=["error","timeout"],T=["memory-promote","procedure-miner"];function h(t,s){return(s??"").toLowerCase().replace(/https?:\/\/\S+/g,"<url>").replace(/(["'`]).*?\1/g,"<v>").replace(/(?:~|\.{0,2})?\/[\w.@-]+(?:\/[\w.@-]+)*/g,"<path>").replace(/\b[0-9a-z]*\d[0-9a-z]*\b/g,"<n>").replace(/[^a-z<>\s]+/g," ").replace(/\s+/g," ").trim().split(" ").filter(Boolean).slice(0,8).join(" ")||t}function y(t){return`${t.agentId}|${t.tool??"no-tool"}|${t.status}|${h(t.status,t.error)}`}function S(t){return $("sha1").update(t).digest("hex").slice(0,10)}function w(t,s){return`${k}${S(t)}@${Math.floor(Math.log2(Math.max(1,s)))}`}function F(t){return t.finalSessionId??t.resumeSessionId??t.taskId}function _(t,s={}){return A.flatMap(e=>I(t,{status:e,since:s.since,limit:1e3})).filter(e=>!T.some(i=>(e.chatId??"").startsWith(i))).map(e=>{let{tool:i,error:n}=b(f(t,e.taskId)?.steps??[]);return{taskId:e.taskId,agentId:e.agentId,chatId:e.chatId,sessionId:F(e),status:e.status,startedAt:e.startedAt,error:n??e.error,messagePreview:e.messagePreview,tool:i}})}function b(t){let s=null,a=null;for(let e of t)e.name==="tool_use"&&e.action?(s=e.action,e.status==="error"&&(a={tool:e.action,error:e.error??e.outputSummary})):e.name==="tool_result"&&e.status==="error"&&(a={tool:e.action??s,error:e.error??e.outputSummary});return a??{tool:s,error:null}}function C(t,s={}){let a=Math.max(2,s.minSessions??x),e=new Map;for(let n of t){let r=y(n);e.set(r,[...e.get(r)??[],n])}let i=[];for(let[n,r]of e){let l=[...new Set([...r].sort((c,g)=>g.startedAt-c.startedAt).map(c=>c.sessionId))];if(l.length<a)continue;r.sort((c,g)=>g.startedAt-c.startedAt);let o=r[0],u=o.tool??"no tool",d=h(o.status,o.error),m=`failure-${S(n)}`;i.push({occurrences:l.length,sessions:l.slice(0,p),tasks:r.slice(0,p).map(c=>c.taskId),failure:{tool:u,errorClass:d,runs:r.length},agentId:o.agentId,key:`${o.agentId}/feedback_${m}`,stamp:w(n,l.length),memory:{name:m,type:"feedback",description:`${o.agentId}: ${u} keeps failing (${d}) in ${l.length} sessions`.slice(0,200),body:E(o.agentId,u,d,l.length,r),createdAt:new Date(r[r.length-1].startedAt).toISOString(),updatedAt:new Date(o.startedAt).toISOString()}})}return i.sort((n,r)=>r.occurrences-n.occurrences)}function E(t,s,a,e,i){let n=i.slice(0,p).map(r=>{let l=(r.messagePreview??"").replace(/\s+/g," ").trim().slice(0,120),o=(r.error??r.status).replace(/\s+/g," ").trim().slice(0,160);return`- ${new Date(r.startedAt).toISOString().slice(0,10)} \`${r.taskId}\` (${r.status})${l?` \u2014 task: ${l}`:""}
|
|
2
|
-
error: ${o}`});return[`**${t}** hit the same failure in ${e} separate sessions (${i.length} runs).`,`- Tool: \`${s}\`
|
|
3
|
-
- Error class: \`${a}\``,"Recurrence across sessions is the finding: any one of these runs is session state. Propose the fix that stops it recurring \u2014 what fails, the likely cause, and what to do instead (a missing fact, a better approach, or a tool or configuration change to make) \u2014 or skip it if the examples do not share a cause.",`**Examples (newest first):**
|
|
4
|
-
${n.join(`
|
|
5
|
-
`)}`].join(`
|
|
6
|
-
|
|
7
|
-
`)}export{x as DEFAULT_MIN_SESSIONS,k as FAILURE_STAMP_PREFIX,p as MAX_FAILURE_EXAMPLES,h as errorClass,b as failingTool,y as failureSignature,w as failureStamp,C as failuresToCandidates,_ as loadFailedTraces,F as sessionOf};
|
|
8
|
-
//# sourceMappingURL=failure-candidates-PBPF45GN.js.map
|