agentix-cli 0.68.1 → 0.69.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agent-32KAOR6W.js → agent-VQIC7O5T.js} +2 -2
- package/dist/{board-dashboard-DJXGWM4G.js → board-dashboard-ZPJHXX3U.js} +186 -186
- package/dist/board-dashboard-ZPJHXX3U.js.map +1 -0
- package/dist/{chunk-NRSXMPFM.js → chunk-4NXIJEYU.js} +205 -205
- package/dist/chunk-4NXIJEYU.js.map +1 -0
- package/dist/chunk-5AMQFDLE.js +649 -0
- package/dist/chunk-5AMQFDLE.js.map +1 -0
- package/dist/{chunk-RX5VVHT4.js → chunk-ART666G6.js} +2 -2
- package/dist/chunk-AU6FFC4I.js +5 -0
- package/dist/chunk-AU6FFC4I.js.map +1 -0
- package/dist/{chunk-REFLUAXH.js → chunk-B65FS265.js} +2 -2
- package/dist/{chunk-HMW5CVOT.js → chunk-BYKF3UTL.js} +2 -2
- package/dist/{chunk-FZSEHYYU.js → chunk-CUZWGTXT.js} +2 -2
- package/dist/{chunk-G5JUY265.js → chunk-F2DEKA2Q.js} +2 -2
- package/dist/chunk-GQ76J72O.js +3 -0
- package/dist/chunk-GQ76J72O.js.map +1 -0
- package/dist/{chunk-DXOLLHVZ.js → chunk-HEJOWP7O.js} +2 -2
- package/dist/{chunk-7R334NQ5.js → chunk-KSDVKLHN.js} +2 -2
- package/dist/chunk-NMFXY3QU.js +2 -0
- package/dist/chunk-NMFXY3QU.js.map +1 -0
- package/dist/{chunk-LP4DLIZ5.js → chunk-NVJHA63C.js} +19 -18
- package/dist/chunk-NVJHA63C.js.map +1 -0
- package/dist/{chunk-FGRD3JAX.js → chunk-Q2WW2HF4.js} +2 -2
- package/dist/{chunk-XFI63BEM.js → chunk-QDRAKJSY.js} +7 -7
- package/dist/chunk-QDRAKJSY.js.map +1 -0
- package/dist/chunk-S4ASFOJU.js +2 -0
- package/dist/chunk-S4ASFOJU.js.map +1 -0
- package/dist/chunk-ST6KPQOY.js +3 -0
- package/dist/chunk-ST6KPQOY.js.map +1 -0
- package/dist/{chunk-TX7MWUC4.js → chunk-VOS2IW4V.js} +2 -2
- package/dist/chunk-ZXR6GNEK.js +3 -0
- package/dist/chunk-ZXR6GNEK.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/fact-proposals-ERRQXV2J.js +2 -0
- package/dist/{facts-72AFTTDG.js → facts-X44PF73W.js} +2 -2
- package/dist/index.d.ts +40 -12
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/ledger-DHYRP4TN.js +2 -0
- package/dist/memory-migrate-ED37IBEL.js +2 -0
- package/dist/memory-migrate-ED37IBEL.js.map +1 -0
- package/dist/program-6PFRDQFT.js +2 -0
- package/dist/{promote-FDEKCVAE.js → promote-XRKH73IB.js} +2 -2
- package/dist/query-6272PJPD.js +2 -0
- package/dist/questions-QGITDLJY.js +2 -0
- package/dist/registry-KP3C4EZ4.js +2 -0
- package/dist/{request-planner-KQLWWR3U.js → request-planner-73Y5GI3D.js} +2 -2
- package/dist/{review-candidates-A6CLXAFS.js → review-candidates-VF5IWP5P.js} +2 -2
- package/dist/rotation-memo-store-X63HYIMV.js +2 -0
- package/dist/rotation-memo-store-X63HYIMV.js.map +1 -0
- package/dist/routing-T24BMMLM.js +2 -0
- package/dist/routing-T24BMMLM.js.map +1 -0
- package/dist/{seat-W3ZTOJUT.js → seat-XNA2O6EO.js} +2 -2
- package/dist/seat-XNA2O6EO.js.map +1 -0
- package/dist/{select-VPOWFRSN.js → select-WOUZIR3Y.js} +2 -2
- package/dist/web/activity-graph.global.js +75 -11
- package/dist/web/activity-graph.global.js.map +1 -1
- package/dist/wiki-W6WI6HL3.js +2 -0
- package/dist/wiki-W6WI6HL3.js.map +1 -0
- package/package.json +1 -1
- package/dist/board-dashboard-DJXGWM4G.js.map +0 -1
- package/dist/chunk-5V6HNNFY.js +0 -2
- package/dist/chunk-5V6HNNFY.js.map +0 -1
- package/dist/chunk-HNR6GLNV.js +0 -648
- package/dist/chunk-HNR6GLNV.js.map +0 -1
- package/dist/chunk-L52X3YGH.js +0 -2
- package/dist/chunk-L52X3YGH.js.map +0 -1
- package/dist/chunk-LP4DLIZ5.js.map +0 -1
- package/dist/chunk-NRSXMPFM.js.map +0 -1
- package/dist/chunk-XFI63BEM.js.map +0 -1
- package/dist/program-7QBU5CYO.js +0 -2
- package/dist/query-PJG52OHP.js +0 -2
- package/dist/questions-2V2VGIT4.js +0 -3
- package/dist/questions-2V2VGIT4.js.map +0 -1
- package/dist/registry-BVOLZUYL.js +0 -2
- package/dist/routing-5G22WTPR.js +0 -2
- package/dist/wiki-ZM6BEOFX.js +0 -2
- /package/dist/{agent-32KAOR6W.js.map → agent-VQIC7O5T.js.map} +0 -0
- /package/dist/{chunk-RX5VVHT4.js.map → chunk-ART666G6.js.map} +0 -0
- /package/dist/{chunk-REFLUAXH.js.map → chunk-B65FS265.js.map} +0 -0
- /package/dist/{chunk-HMW5CVOT.js.map → chunk-BYKF3UTL.js.map} +0 -0
- /package/dist/{chunk-FZSEHYYU.js.map → chunk-CUZWGTXT.js.map} +0 -0
- /package/dist/{chunk-G5JUY265.js.map → chunk-F2DEKA2Q.js.map} +0 -0
- /package/dist/{chunk-DXOLLHVZ.js.map → chunk-HEJOWP7O.js.map} +0 -0
- /package/dist/{chunk-7R334NQ5.js.map → chunk-KSDVKLHN.js.map} +0 -0
- /package/dist/{chunk-FGRD3JAX.js.map → chunk-Q2WW2HF4.js.map} +0 -0
- /package/dist/{chunk-TX7MWUC4.js.map → chunk-VOS2IW4V.js.map} +0 -0
- /package/dist/{program-7QBU5CYO.js.map → fact-proposals-ERRQXV2J.js.map} +0 -0
- /package/dist/{facts-72AFTTDG.js.map → facts-X44PF73W.js.map} +0 -0
- /package/dist/{promote-FDEKCVAE.js.map → ledger-DHYRP4TN.js.map} +0 -0
- /package/dist/{query-PJG52OHP.js.map → program-6PFRDQFT.js.map} +0 -0
- /package/dist/{registry-BVOLZUYL.js.map → promote-XRKH73IB.js.map} +0 -0
- /package/dist/{routing-5G22WTPR.js.map → query-6272PJPD.js.map} +0 -0
- /package/dist/{seat-W3ZTOJUT.js.map → questions-QGITDLJY.js.map} +0 -0
- /package/dist/{wiki-ZM6BEOFX.js.map → registry-KP3C4EZ4.js.map} +0 -0
- /package/dist/{request-planner-KQLWWR3U.js.map → request-planner-73Y5GI3D.js.map} +0 -0
- /package/dist/{review-candidates-A6CLXAFS.js.map → review-candidates-VF5IWP5P.js.map} +0 -0
- /package/dist/{select-VPOWFRSN.js.map → select-WOUZIR3Y.js.map} +0 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{e as o}from"./chunk-CUZWGTXT.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-S4ASFOJU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{b,c as k,d as F,f as A}from"./chunk-GQ76J72O.js";import{a as B,b as v}from"./chunk-ZXR6GNEK.js";import{createHash as P}from"crypto";import{existsSync as _,statSync as q}from"fs";import{resolve as J}from"path";import{closeSync as L,existsSync as M,mkdirSync as S,openSync as C,readFileSync as E,renameSync as T,statSync as O,unlinkSync as $,writeFileSync as R}from"fs";import{dirname as x}from"path";var y=class extends Error{constructor(e,s){super(`fact ledger ${e} is unreadable (${s}). Nothing was written to it. Repair the JSON, or move the file aside to start an empty ledger.`);this.file=e;this.name="LedgerCorruptError"}};function j(r){if(!M(r))return null;let t;try{t=JSON.parse(E(r,"utf-8"))}catch(e){throw new y(r,String(e?.message??e))}if(!t||typeof t!="object"||!Array.isArray(t.facts)||t.proposals!==void 0&&!Array.isArray(t.proposals))throw new y(r,"not a ledger: expected { facts: [], proposals: [] }");return{facts:t.facts,proposals:t.proposals??[]}}function W(r,t){S(x(r),{recursive:!0});let e=`${r}.${process.pid}.tmp`;R(e,JSON.stringify(t,null,2)+`
|
|
2
|
+
`),T(e,r)}var N=r=>Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,r);function I(r,t,e={}){let s=`${r}.lock`,i=e.timeoutMs??3e3,l=e.staleMs??15e3;S(x(s),{recursive:!0});let o=Date.now()+i,c;for(;c===void 0;)try{c=C(s,"wx")}catch(d){if(d?.code!=="EEXIST")throw d;try{if(Date.now()-O(s).mtimeMs>l){$(s);continue}}catch{continue}if(Date.now()>o)throw new Error(`fact ledger is busy (${s}); try again`);N(25)}try{return t()}finally{L(c);try{$(s)}catch{}}}var n=r=>r.toLowerCase().replace(/\s+/g," ").trim();function H(r,t){return"f-"+P("sha1").update(`${n(r)}\0${n(t)}`).digest("hex").slice(0,10)}var D=class{constructor(t){this.wikiDir=t;this.file=J(t,"_facts.json")}file;cache;reported;load(){if(!_(this.file))return{version:1,facts:[],proposals:[]};let t=q(this.file).mtimeMs;if(this.cache?.mtimeMs===t)return structuredClone(this.cache.data);let e;try{e=j(this.file)}catch(i){throw this.reported!==t&&(this.reported=t,console.error(`[wiki-facts] ${i.message}`)),i}let s={version:1,facts:e?.facts??[],proposals:e?.proposals??[]};return this.cache={mtimeMs:t,data:s},structuredClone(s)}update(t){return I(this.file,()=>{this.cache=void 0;let e=this.load(),{save:s,result:i}=t(e);return s&&(W(this.file,e),this.cache=void 0),i})}list(){return this.load().facts}get(t){return this.list().find(e=>e.id===t||t.length>=6&&e.id.startsWith(t))??null}write(t,e={}){let s=e.now??Date.now(),i=new Date(s).toISOString();if(!t.source?.trim())throw new Error('a fact needs a source: a system, URL, command or "owner said"');if(!t.subject?.trim()||!t.attribute?.trim()||!t.value?.trim())throw new Error("a fact needs a subject, an attribute and a value");let l=t.verifiedAt==="now"?s:Date.parse(t.verifiedAt??""),o=Number.isFinite(l),c=o?new Date(Math.min(l,s)).toISOString():i,d=b(t.volatility)?t.volatility:F(t.attribute,`${t.subject} ${t.attribute} is ${t.value}`),g={source:t.source.trim(),verifiedAt:c,verifiedBy:t.verifiedBy||"unknown",volatility:d,...typeof t.ttlDays=="number"?{ttlDays:t.ttlDays}:{}},h=H(t.subject,t.attribute),u=this.update(f=>{let a=f.facts.find(m=>m.id===h);if(!a){let m={id:h,subject:t.subject.trim(),attribute:t.attribute.trim(),value:t.value.trim(),...g,createdAt:i,updatedAt:i,...e.confirmedBy?{confirmedBy:e.confirmedBy}:{}};return f.facts.push(m),{save:!0,result:{status:"created",fact:m}}}let p=Date.parse(a.verifiedAt),w=o&&(!Number.isFinite(p)||Date.parse(c)>p);return n(a.value)===n(t.value)?!w&&!e.confirmedBy?{save:!1,result:{status:"unchanged",fact:a}}:(Object.assign(a,g,{updatedAt:i},e.confirmedBy?{confirmedBy:e.confirmedBy}:{}),{save:!0,result:{status:"verified",fact:a}}):!e.confirmedBy&&(!w||a.confirmedBy)?{save:!1,result:{contradiction:a}}:(a.history=[...a.history??[],{value:a.value,source:a.source,verifiedAt:a.verifiedAt,verifiedBy:a.verifiedBy,replacedAt:i}].slice(-10),a.value=t.value.trim(),Object.assign(a,g,{updatedAt:i}),e.confirmedBy?a.confirmedBy=e.confirmedBy:delete a.confirmedBy,{save:!0,result:{status:"updated",fact:a}})});if("contradiction"in u){let f=Q(this.wikiDir,u.contradiction,{...t,verifiedAt:o?c:"undated"});return{status:"contradiction",fact:u.contradiction,questionId:f}}return u}};function Q(r,t,e){let s=new v(r),i={kind:"contradiction",agentId:e.verifiedBy||"unknown",path:"_facts.json",subject:t.subject,field:`${t.attribute}=${n(e.value)}`,tier:"pillar",factId:t.id,proposed:{value:e.value.trim(),source:e.source.trim(),verifiedAt:e.verifiedAt,verifiedBy:e.verifiedBy},question:`${t.subject} \xB7 ${t.attribute}: the wiki says "${t.value}" (${t.source}, checked ${t.verifiedAt.slice(0,10)}), but ${e.verifiedBy} reports "${e.value.trim()}" (${e.source.trim()}, checked ${e.verifiedAt.slice(0,10)}). Which is true?`};return s.add([i]),B(i.kind,i.agentId,i.subject,i.field)}function et(r){return new v(r).list("open").filter(t=>t.kind==="contradiction").map(t=>({type:"contradiction",articles:[`_facts.json#${t.factId??"?"}`],message:`[${t.id}] ${t.question}`,confidence:"high"}))}function rt(r,t=Date.now()){return A(r,t)}function it(r,t){let e=n(r),s=null;for(let i of t){let l=n(i.subject);if(l.length<3||!e.includes(l))continue;let o=n(i.attribute).split(" ").filter(d=>d.length>2);(e.includes(n(i.value))||i.volatility!=="stable"&&k(r)===i.volatility||o.length>0&&o.every(d=>e.includes(d)))&&(!s||i.subject.length>s.subject.length)&&(s=i)}return s}export{H as a,D as b,et as c,rt as d,it as e};
|
|
3
|
+
//# sourceMappingURL=chunk-ST6KPQOY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/wiki/facts/ledger.ts","../src/wiki/facts/ledger-file.ts"],"sourcesContent":["import { createHash } from \"crypto\"\nimport { existsSync, statSync } from \"fs\"\nimport { resolve } from \"path\"\nimport { readLedger, withLock, writeLedger } from \"./ledger-file\"\nimport { classifyAttribute, classifyFact, isFactClass, isPastTtl, type FactClass, type Provenance } from \"@/agents/fact-freshness\"\nimport type { ContradictionIssue } from \"../lint-contradictions\"\nimport { QuestionStore, questionId } from \"../questions\"\n\n// --- The wiki fact ledger: durable facts with provenance (#273) ---\n//\n// Articles are prose. A fact an agent states to a person (\"the vendor\n// account is past due\") needs more than prose: where it came from, when\n// it was last checked, by whom, and how long it stays true. This is that\n// record — one small JSON sidecar beside `_questions.json`, skipped by the\n// article index like every `_` file.\n//\n// Every other store references it: memory lines that restate a ledger\n// fact are replaced by a reference at injection (agents/memory-context),\n// and memo claims wait here as proposals (fact-proposals.ts) instead of\n// becoming memory.\n//\n// Overwrite safety: a write that disagrees with the current value needs a\n// check newer than the current one, or a person's confirmation. Otherwise\n// the old value stays and a contradiction question joins the wiki's\n// question queue (`agentx wiki questions`), where the answer is written\n// back through here.\n\nexport interface WikiFact extends Provenance {\n id: string\n subject: string\n attribute: string\n value: string\n createdAt: string\n updatedAt: string\n /** Set when a person confirmed the value over a newer-dated one. */\n confirmedBy?: string\n /** Earlier values, newest last. Nothing is replaced silently. */\n history?: Array<{ value: string; source: string; verifiedAt: string; verifiedBy: string; replacedAt: string }>\n}\n\nexport interface FactInput {\n subject: string\n attribute: string\n value: string\n source: string\n verifiedBy: string\n /** When the source was checked (ISO date, or \"now\"). Without it the\n * write is undated and never counts as newer than an existing fact. */\n verifiedAt?: string\n volatility?: FactClass\n ttlDays?: number\n}\n\nexport type WriteStatus = \"created\" | \"verified\" | \"unchanged\" | \"updated\" | \"contradiction\"\n\nexport interface WriteResult {\n status: WriteStatus\n fact: WikiFact\n /** The queued question, for a contradiction. */\n questionId?: string\n}\n\nexport interface LedgerFile {\n version: 1\n facts: WikiFact[]\n proposals: import(\"./fact-proposals\").FactProposal[]\n}\n\nconst norm = (s: string) => s.toLowerCase().replace(/\\s+/g, \" \").trim()\n\n/** Stable per subject and attribute, so a re-check lands on the same fact. */\nexport function factId(subject: string, attribute: string): string {\n return \"f-\" + createHash(\"sha1\").update(`${norm(subject)}\\u0000${norm(attribute)}`).digest(\"hex\").slice(0, 10)\n}\n\nexport class FactLedger {\n readonly file: string\n private cache?: { mtimeMs: number; data: LedgerFile }\n private reported?: number\n\n constructor(readonly wikiDir: string) {\n this.file = resolve(wikiDir, \"_facts.json\")\n }\n\n /** The ledger as stored. Throws LedgerCorruptError on a file that does\n * not parse: it is never read as empty, so it is never overwritten. */\n load(): LedgerFile {\n if (!existsSync(this.file)) return { version: 1, facts: [], proposals: [] }\n const mtimeMs = statSync(this.file).mtimeMs\n if (this.cache?.mtimeMs === mtimeMs) return structuredClone(this.cache.data)\n let raw\n try {\n raw = readLedger(this.file)\n } catch (e) {\n // Once per version of the bad file, not once per prompt.\n if (this.reported !== mtimeMs) {\n this.reported = mtimeMs\n console.error(`[wiki-facts] ${(e as Error).message}`)\n }\n throw e\n }\n const data: LedgerFile = { version: 1, facts: (raw?.facts ?? []) as WikiFact[], proposals: (raw?.proposals ?? []) as LedgerFile[\"proposals\"] }\n this.cache = { mtimeMs, data }\n return structuredClone(data)\n }\n\n /**\n * Load, change and save under the ledger's lock, so concurrent writers\n * (a daemon proposing memo claims, a CLI `set`) can't drop each other's\n * change. `fn` returns whether to save, and a result.\n */\n update<T>(fn: (data: LedgerFile) => { save: boolean; result: T }): T {\n return withLock(this.file, () => {\n this.cache = undefined\n const data = this.load()\n const { save, result } = fn(data)\n if (save) {\n writeLedger(this.file, data)\n this.cache = undefined\n }\n return result\n })\n }\n\n list(): WikiFact[] { return this.load().facts }\n\n get(id: string): WikiFact | null {\n return this.list().find((f) => f.id === id || (id.length >= 6 && f.id.startsWith(id))) ?? null\n }\n\n /**\n * Record a checked fact. Refuses a fact with no source. A different value\n * replaces the current one only with a dated check newer than the current\n * one, or `confirmedBy`. A value a person confirmed is replaced only by\n * another confirmation. Otherwise the current value stays and a\n * contradiction question is raised.\n *\n * A write with no `verifiedAt` is undated: it can create a fact, but it\n * never counts as newer than a fact already there.\n */\n write(input: FactInput, opts: { confirmedBy?: string; now?: number } = {}): WriteResult {\n const now = opts.now ?? Date.now()\n const nowIso = new Date(now).toISOString()\n if (!input.source?.trim()) throw new Error(\"a fact needs a source: a system, URL, command or \\\"owner said\\\"\")\n if (!input.subject?.trim() || !input.attribute?.trim() || !input.value?.trim()) {\n throw new Error(\"a fact needs a subject, an attribute and a value\")\n }\n const checked = input.verifiedAt === \"now\" ? now : Date.parse(input.verifiedAt ?? \"\")\n const dated = Number.isFinite(checked)\n // A check can't be dated after it happened.\n const verifiedAt = dated ? new Date(Math.min(checked, now)).toISOString() : nowIso\n const volatility = isFactClass(input.volatility)\n ? input.volatility\n : classifyAttribute(input.attribute, `${input.subject} ${input.attribute} is ${input.value}`)\n const provenance: Provenance = {\n source: input.source.trim(), verifiedAt, verifiedBy: input.verifiedBy || \"unknown\", volatility,\n ...(typeof input.ttlDays === \"number\" ? { ttlDays: input.ttlDays } : {}),\n }\n const id = factId(input.subject, input.attribute)\n\n const out = this.update<WriteResult | { contradiction: WikiFact }>((data) => {\n const existing = data.facts.find((f) => f.id === id)\n if (!existing) {\n const fact: WikiFact = {\n id, subject: input.subject.trim(), attribute: input.attribute.trim(), value: input.value.trim(),\n ...provenance, createdAt: nowIso, updatedAt: nowIso,\n ...(opts.confirmedBy ? { confirmedBy: opts.confirmedBy } : {}),\n }\n data.facts.push(fact)\n return { save: true, result: { status: \"created\", fact } }\n }\n\n const prior = Date.parse(existing.verifiedAt)\n const newer = dated && (!Number.isFinite(prior) || Date.parse(verifiedAt) > prior)\n if (norm(existing.value) === norm(input.value)) {\n if (!newer && !opts.confirmedBy) return { save: false, result: { status: \"unchanged\", fact: existing } }\n Object.assign(existing, provenance, { updatedAt: nowIso }, opts.confirmedBy ? { confirmedBy: opts.confirmedBy } : {})\n return { save: true, result: { status: \"verified\", fact: existing } }\n }\n\n // A person's confirmation outranks any agent's date.\n if (!opts.confirmedBy && (!newer || existing.confirmedBy)) {\n return { save: false, result: { contradiction: existing } }\n }\n\n existing.history = [...(existing.history ?? []), {\n value: existing.value, source: existing.source, verifiedAt: existing.verifiedAt,\n verifiedBy: existing.verifiedBy, replacedAt: nowIso,\n }].slice(-10)\n existing.value = input.value.trim()\n Object.assign(existing, provenance, { updatedAt: nowIso })\n if (opts.confirmedBy) existing.confirmedBy = opts.confirmedBy\n else delete existing.confirmedBy\n return { save: true, result: { status: \"updated\", fact: existing } }\n })\n\n if (\"contradiction\" in out) {\n const questionId = raiseContradiction(this.wikiDir, out.contradiction, { ...input, verifiedAt: dated ? verifiedAt : \"undated\" })\n return { status: \"contradiction\", fact: out.contradiction, questionId }\n }\n return out\n }\n}\n\nfunction raiseContradiction(wikiDir: string, current: WikiFact, input: FactInput & { verifiedAt: string }): string {\n const store = new QuestionStore(wikiDir)\n const item = {\n kind: \"contradiction\" as const,\n agentId: input.verifiedBy || \"unknown\",\n path: \"_facts.json\",\n subject: current.subject,\n // One question per refused value: a second, different claim is a new\n // question, while repeating the same claim does not ask twice.\n field: `${current.attribute}=${norm(input.value)}`,\n tier: \"pillar\",\n factId: current.id,\n proposed: { value: input.value.trim(), source: input.source.trim(), verifiedAt: input.verifiedAt, verifiedBy: input.verifiedBy },\n question:\n `${current.subject} · ${current.attribute}: the wiki says \"${current.value}\" ` +\n `(${current.source}, checked ${current.verifiedAt.slice(0, 10)}), but ${input.verifiedBy} reports ` +\n `\"${input.value.trim()}\" (${input.source.trim()}, checked ${input.verifiedAt.slice(0, 10)}). Which is true?`,\n }\n store.add([item])\n return questionId(item.kind, item.agentId, item.subject, item.field)\n}\n\n/** Open fact contradictions, in the shape `wiki lint` reports. */\nexport function factContradictions(wikiDir: string): ContradictionIssue[] {\n return new QuestionStore(wikiDir).list(\"open\")\n .filter((q) => q.kind === \"contradiction\")\n .map((q) => ({\n type: \"contradiction\" as const,\n articles: [`_facts.json#${q.factId ?? \"?\"}`],\n message: `[${q.id}] ${q.question}`,\n confidence: \"high\" as const,\n }))\n}\n\n/** A fact is stale when it is past its class TTL. */\nexport function isStaleFact(f: WikiFact, now = Date.now()): boolean {\n return isPastTtl(f, now)\n}\n\n/**\n * The ledger fact a memory line restates, if any. The line must name the\n * fact's subject, and either repeat its value, share its volatility class,\n * or name its attribute.\n */\nexport function matchFact(content: string, facts: WikiFact[]): WikiFact | null {\n const text = norm(content)\n let best: WikiFact | null = null\n for (const f of facts) {\n const subject = norm(f.subject)\n if (subject.length < 3 || !text.includes(subject)) continue\n const attrWords = norm(f.attribute).split(\" \").filter((w) => w.length > 2)\n const hit = text.includes(norm(f.value))\n || (f.volatility !== \"stable\" && classifyFact(content) === f.volatility)\n || (attrWords.length > 0 && attrWords.every((w) => text.includes(w)))\n if (hit && (!best || f.subject.length > best.subject.length)) best = f\n }\n return best\n}\n","import { closeSync, existsSync, mkdirSync, openSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync } from \"fs\"\nimport { dirname } from \"path\"\n\n// --- The fact ledger's file: strict reads, locked writes (#273) ---\n//\n// Two rules keep the ledger from losing facts with nobody watching:\n// 1. A file that does not parse is never treated as empty. Reading it\n// throws LedgerCorruptError, so no write can replace it; the file is\n// left exactly as it is for a person to repair.\n// 2. load → modify → save runs under a lockfile, so a daemon proposing\n// memo claims and a CLI `set` or `approve` can't drop each other's\n// write.\n\nexport class LedgerCorruptError extends Error {\n constructor(readonly file: string, cause: string) {\n super(\n `fact ledger ${file} is unreadable (${cause}). Nothing was written to it. ` +\n `Repair the JSON, or move the file aside to start an empty ledger.`,\n )\n this.name = \"LedgerCorruptError\"\n }\n}\n\nexport interface RawLedger {\n facts: unknown[]\n proposals: unknown[]\n}\n\n/** Null when the file does not exist; throws when it exists but is not a ledger. */\nexport function readLedger(file: string): RawLedger | null {\n if (!existsSync(file)) return null\n let raw: any\n try {\n raw = JSON.parse(readFileSync(file, \"utf-8\"))\n } catch (e) {\n throw new LedgerCorruptError(file, String((e as Error)?.message ?? e))\n }\n if (!raw || typeof raw !== \"object\" || !Array.isArray(raw.facts) || (raw.proposals !== undefined && !Array.isArray(raw.proposals))) {\n throw new LedgerCorruptError(file, \"not a ledger: expected { facts: [], proposals: [] }\")\n }\n return { facts: raw.facts, proposals: raw.proposals ?? [] }\n}\n\nexport function writeLedger(file: string, data: unknown): void {\n mkdirSync(dirname(file), { recursive: true })\n const tmp = `${file}.${process.pid}.tmp`\n writeFileSync(tmp, JSON.stringify(data, null, 2) + \"\\n\")\n renameSync(tmp, file)\n}\n\nconst sleep = (ms: number) => Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms)\n\n/**\n * Run `fn` holding `<file>.lock`. Waits up to `timeoutMs` for another\n * holder; a lock older than `staleMs` is a crashed holder and is taken over.\n */\nexport function withLock<T>(file: string, fn: () => T, opts: { timeoutMs?: number; staleMs?: number } = {}): T {\n const lock = `${file}.lock`\n const timeoutMs = opts.timeoutMs ?? 3000\n const staleMs = opts.staleMs ?? 15_000\n mkdirSync(dirname(lock), { recursive: true })\n const deadline = Date.now() + timeoutMs\n let fd: number | undefined\n while (fd === undefined) {\n try {\n fd = openSync(lock, \"wx\")\n } catch (e: any) {\n if (e?.code !== \"EEXIST\") throw e\n try {\n if (Date.now() - statSync(lock).mtimeMs > staleMs) { unlinkSync(lock); continue }\n } catch { continue }\n if (Date.now() > deadline) throw new Error(`fact ledger is busy (${lock}); try again`)\n sleep(25)\n }\n }\n try {\n return fn()\n } finally {\n closeSync(fd)\n try { unlinkSync(lock) } catch { /* already gone */ }\n }\n}\n"],"mappings":"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","names":["createHash","existsSync","statSync","resolve","closeSync","existsSync","mkdirSync","openSync","readFileSync","renameSync","statSync","unlinkSync","writeFileSync","dirname","LedgerCorruptError","file","cause","readLedger","raw","writeLedger","data","tmp","sleep","ms","withLock","fn","opts","lock","timeoutMs","staleMs","deadline","fd","e","norm","s","factId","subject","attribute","createHash","FactLedger","wikiDir","resolve","existsSync","mtimeMs","statSync","raw","readLedger","e","data","fn","withLock","save","result","writeLedger","id","f","input","opts","now","nowIso","checked","dated","verifiedAt","volatility","isFactClass","classifyAttribute","provenance","out","existing","fact","prior","newer","questionId","raiseContradiction","current","store","QuestionStore","item","factContradictions","q","isStaleFact","isPastTtl","matchFact","content","facts","text","best","attrWords","w","classifyFact"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as et,b as tt,c as nt,d as S,e as A,f as N}from"./chunk-72SZI2UW.js";import{a as ne,b as He}from"./chunk-FCPTN6NF.js";import{
|
|
1
|
+
import{a as Te,b as ft}from"./chunk-FX3D7YON.js";import{a as et,b as tt,c as nt,d as S,e as A,f as N}from"./chunk-72SZI2UW.js";import{a as ne,b as He}from"./chunk-FCPTN6NF.js";import{o as we,p as Ke}from"./chunk-SZJMS7K4.js";import{y as We,z as Ze}from"./chunk-N5NPJ6DJ.js";import{a as rt,b as ot,c as st,d as it,e as at,f as ct,g as ut,h as lt,i as dt,j as pt,k as mt,l as bt}from"./chunk-RGDKHYY2.js";import{a as E,b as Ye,c as he}from"./chunk-QIJLFPWE.js";function R(e,t){$.set(e,t),X.delete(e)}function D(e){let t=X.get(e);if(t)return t;let r=$.get(e);if(!r){let o=Ee();throw new Error(`unknown decision backend "${e}"`+(o.length>0?` \u2014 registered: ${o.join(", ")}`:" \u2014 none registered"))}let n=r();return X.set(e,n),n}function Ee(){return[...$.keys()].sort()}function gt(){$.clear(),X.clear()}var $,X,C=E(()=>{"use strict";$=new Map,X=new Map});import yt from"better-sqlite3";import{createHash as ht}from"crypto";import{mkdirSync as wt}from"fs";import{dirname as Tt,resolve as Et}from"path";function Q(e){if(e.type==="noul"){let r=e.noul,n={yes:r,no:1-r},o=r>=.5?"yes":"no",s=Math.abs(r-.5)*2;return{predicted:o,confidence:s,probabilities:n,topLabel:o,topProb:Math.max(r,1-r),expectedScore:null,pMax:Math.max(r,1-r),negEntropy:s}}if(e.type==="choice")return{predicted:e.choice,confidence:e.confidence,probabilities:{...e.probabilities},topLabel:e.choice,topProb:e.probabilities[e.choice]??0,expectedScore:null,pMax:e.pMax,negEntropy:e.negEntropy};let t=String(Math.round(e.score));return{predicted:t,confidence:e.confidence,probabilities:{...e.probabilities},topLabel:t,topProb:e.probabilities[t]??0,expectedScore:e.score,pMax:e.pMax,negEntropy:e.negEntropy}}function kt(e){if(typeof e!="string"||e.length===0)return{};try{let t=JSON.parse(e);return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}catch{return{}}}function xt(e){e.exec("CREATE TABLE IF NOT EXISTS schema_version (v INTEGER PRIMARY KEY);");let t=e.prepare("SELECT MAX(v) AS v FROM schema_version").get().v??0;t<1&&Rt(e),t<2&&At(e),t<3&&St(e)}function St(e){e.exec(`
|
|
2
2
|
ALTER TABLE decision_calls ADD COLUMN features_json TEXT;
|
|
3
3
|
INSERT INTO schema_version (v) VALUES (3);
|
|
4
4
|
`)}function At(e){e.exec(`
|
|
@@ -111,4 +111,4 @@ import{a as et,b as tt,c as nt,d as S,e as A,f as N}from"./chunk-72SZI2UW.js";im
|
|
|
111
111
|
`)}if(!m)throw new Error(`local decision backend could not get a valid answer after ${f+1} attempt(s): ${h}`);let M={},L=!1;for(let[k,q]of Object.entries(s.questions)){let x=_(q,m[k],{normalize:e.normalizeProbabilities??!0});M[k]=x.answer,x.repaired&&(L=!0)}return{model:a,answers:M,usage:g,meta:{backend:"local",structureMode:c,answerMode:"probabilities",repaired:L,retries:f,stateTruncated:l.truncated,latencyMs:Date.now()-i}}}finally{b()}}}}async function $t(e,t,r,n,o){if(!e.generateRaw)throw new Error(`provider "${e.name}" has no generateRaw(); use structureMode "text"`);let s=[{role:"user",content:r},...n?[{role:"user",content:n}]:[]],i=await e.generateRaw(s,J,[{name:B,description:"Report a probability distribution for every question.",input_schema:se(t)}],{...o,toolChoice:{type:"tool",name:B}}),a=i.content.find(c=>c.type==="tool_use"&&c.name===B),u=a&&a.type==="tool_use"?a.input:null;return{answers:Pe(u),usage:{inputTokens:i.usage.input_tokens,outputTokens:i.usage.output_tokens}}}async function Vt(e,t,r,n,o){let s=[r,ae(t)].join(`
|
|
112
112
|
`),i=[{role:"system",content:J},{role:"user",content:s},...n?[{role:"user",content:n}]:[]],a=await e.generate(i,o);return{answers:Pe(Te(a.content??"")),usage:{inputTokens:0,outputTokens:a.tokensUsed??0}}}function Pe(e){if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e;if(t.answers&&typeof t.answers=="object")return t.answers}return e}function zt(e,t){return e!=="auto"?e:t.generateRaw&&me[t.name]?.structuredOutput?"tool":"text"}function Jt(e,t){let r=new AbortController,n=setTimeout(()=>r.abort(new Error(`decision timed out after ${t}ms`)),t),o=()=>r.abort(e?.reason);return e&&(e.aborted?o():e.addEventListener("abort",o,{once:!0})),{signal:r.signal,dispose:()=>{clearTimeout(n),e?.removeEventListener("abort",o)}}}var Bt,Pt,qt,Be,Xt,be=E(()=>{"use strict";Ke();Ue();ft();j();Y();N();z();Bt="claude-code",Pt="claude-haiku-4-5-20251001",qt=24e3,Be=2e3,Xt=3e4});import{readFileSync as Gt}from"fs";import{homedir as Yt}from"os";import{join as Kt}from"path";function v(e={}){let t=(e.baseUrl??Ht).replace(/\/+$/,""),r=e.path??"/classifier",n=e.name??"simple-jev",o=e.maxStateChars??Zt,s=e.maxChoiceOptions??en,i={probabilitySource:e.probabilitySource??"logits",calibratedProbabilities:!1,maxChoiceOptions:s,maxStateChars:o,parallelQuestions:!0,images:!1};return{name:n,capabilities:i,async decide(a){A(a.questions),on(a.questions,s);let u=Date.now(),c=a.model??e.model;if(!c)throw new Error("simple-jev backend needs a model id");let l=G(a.state,o),p=e.fetchImpl??fetch,{signal:y,dispose:d}=sn(a.abortSignal,a.timeoutMs??e.timeoutMs??Wt);try{let b={"Content-Type":"application/json"},g=rn(e.apiKeyEnv,e.apiKeyFile);g&&(b.Authorization=`Bearer ${g}`);let w=await p(`${t}${r}`,{method:"POST",headers:b,body:JSON.stringify({model:c,state:l.text,questions:nn(a.questions)}),signal:y});if(!w.ok){let k=await w.text().catch(()=>"");throw new Error(`${n} ${w.status}: ${k.slice(0,300)}`)}let f=await w.json(),m=F(a.questions).safeParse(f.answers);if(!m.success)throw new Error(`${n} returned a response that does not match the requested questions (contract drift, not a model slip \u2014 retrying will not help):
|
|
113
113
|
${U(m.error)}`);let h=m.data,M={},L=!1;for(let[k,q]of Object.entries(a.questions)){let x=_(q,h[k]);M[k]=x.answer,x.repaired&&(L=!0)}return{model:f.model??c,answers:M,usage:{inputTokens:f.usage?.input_tokens??0,outputTokens:f.usage?.output_tokens??0},meta:{backend:n,structureMode:i.probabilitySource==="native"?"native":"logprobs",answerMode:"probabilities",repaired:L,retries:0,stateTruncated:l.truncated,latencyMs:Date.now()-u}}}finally{d()}}}}function nn(e){let t={};for(let[r,n]of Object.entries(e))t[r]=n.instructions?n:{...n,instructions:tn[n.type]};return t}function rn(e,t){let r=e?process.env[e]:void 0;if(r)return r;if(!t)return;let n=t.startsWith("~/")?Kt(Yt(),t.slice(2)):t;if(!Z.has(n))try{let o=Gt(n,"utf-8").trim();Z.set(n,o.length>0?o:null)}catch{Z.set(n,null)}return Z.get(n)??void 0}function on(e,t){for(let[r,n]of Object.entries(e))if(n.type==="choice"){let o=Object.keys(n.criteria).length;if(o>t)throw new Error(`question "${r}": accepts at most ${t} choice options, got ${o}`)}else if(n.type==="score"&&n.criteria.length>t)throw new Error(`question "${r}": accepts at most ${t} score levels, got ${n.criteria.length}`)}function sn(e,t){let r=new AbortController,n=setTimeout(()=>r.abort(new Error(`decision timed out after ${t}ms`)),t),o=()=>r.abort(e?.reason);return e&&(e.aborted?o():e.addEventListener("abort",o,{once:!0})),{signal:r.signal,dispose:()=>{clearTimeout(n),e?.removeEventListener("abort",o)}}}var Ht,Wt,Zt,en,tn,Z,fe=E(()=>{"use strict";j();N();z();Y();Ht="http://127.0.0.1:8000/v1",Wt=3e4,Zt=6e3,en=50;tn={choice:"Which option best fits?",score:"Which level best fits?",noul:"Is this true of the state?"};Z=new Map});var qe={};Ye(qe,{DecisionStore:()=>I,MAX_CHOICE_OPTIONS:()=>MAX_CHOICE_OPTIONS,SYSTEM_PROMPT:()=>J,TOOL_NAME:()=>B,UNCERTAINTY_HIGH:()=>Ce,UNCERTAINTY_LOW:()=>De,_resetDecisionBackendsForTesting:()=>gt,agreement:()=>rt,answerView:()=>Q,applyRecalibrator:()=>ue,applyTemperature:()=>lt,askSeat:()=>pn,band:()=>Ie,bootstrapInterval:()=>pt,brier:()=>at,buildDesign:()=>Ne,calibrationReport:()=>mt,choice:()=>tt,compareCalibrators:()=>Lt,confidenceFor:()=>re,configureDecisions:()=>cn,coverageCurve:()=>ut,createLocalDecisionBackend:()=>W,createMockDecisionBackend:()=>H,createSimpleJevBackend:()=>v,decisionsRuntime:()=>ln,describeIssues:()=>U,ece:()=>st,expectedScore:()=>Ae,finalizeAnswer:()=>_,fitLogistic:()=>ve,fitRecalibrator:()=>P,fitTemperature:()=>dt,getDecisionBackend:()=>D,getSeatMode:()=>Ve,labelsOf:()=>S,listDecisionBackends:()=>Ee,logLoss:()=>ct,logit:()=>le,mce:()=>it,measureConsistency:()=>Qt,normalizeDistribution:()=>xe,normalizedNegEntropy:()=>oe,noul:()=>et,pMax:()=>Se,parseSeatMode:()=>ge,rawAnswerSchema:()=>Re,rawAnswersSchema:()=>F,recordSeatOutcome:()=>dn,registerBuiltinDecisionBackends:()=>an,registerDecisionBackend:()=>R,reliabilityBins:()=>ot,renderQuestions:()=>_e,renderShapeInstructions:()=>ae,renderState:()=>G,renderUserPrompt:()=>ie,resetDecisionsRuntime:()=>un,score:()=>nt,seatEnvVar:()=>$e,sigmoid:()=>de,toolInputSchema:()=>se,validateQuestions:()=>A,withUid:()=>Qe});function an(e={},t={},r={},n={}){R("mock",()=>H()),R("local",()=>W(e)),R("simple-jev",()=>v(t)),R("jev",()=>v({name:"jev",baseUrl:"https://openrouter.ai/api/alpha",path:"/decisions",model:"jev-latest",apiKeyEnv:"OPENROUTER_API_KEY",apiKeyFile:"~/.agentx/openrouter-key.txt",probabilitySource:"native",maxChoiceOptions:255,maxStateChars:9e4,...r})),R("typesafe",()=>v({name:"typesafe",baseUrl:"https://api.typesafe.ai/v1",path:"/systemone",model:"jev-latest",apiKeyEnv:"TYPESAFE_API_KEY",apiKeyFile:"~/.agentx/typesafe-key.txt",probabilitySource:"native",maxChoiceOptions:255,maxStateChars:9e4,...n}))}var Xe=E(()=>{"use strict";ke();N();j();z();C();Y();V();bt();Me();je();ze();pe();be();fe();C();pe();be();fe()});function cn(e){T={...ye,...T,...e},ee=!0}function un(){T={...ye,seats:{}},ee=!1}function mn(){if(!ee){ee=!0;try{let{loadDaemonConfig:e}=(Ze(),he(We)),t=e()?.decisions;if(!t?.enabled)return;let{registerBuiltinDecisionBackends:r}=(Xe(),he(qe)),n=t.backends??{};r(n.local,n.simpleJev,n.jev,n.typesafe);let o=null;try{o=new I({path:t.dbPath})}catch{}T={enabled:!0,defaultBackend:t.defaultBackend,store:o,seats:Object.fromEntries(Object.entries(t.seats??{}).map(([s,i])=>[s,{...i,redactState:t.redactState,keepStateRows:t.keepStateRows}]))}}catch{}}}function ln(){return T}function ge(e){if(typeof e!="string")return null;let t=e.trim().toLowerCase();return bn.includes(t)?t:null}function $e(e){return`AGENTX_DECISION_SEAT_${e.toUpperCase().replace(/[^A-Z0-9]+/g,"_")}`}function Ve(e,t=process.env){mn();let r=ge(t[$e(e)]);return r||(T.enabled?ge(T.seats[e]?.mode)??"off":"off")}function dn(e,t,r=!1){if(!(!e||!T.store))try{T.store.recordOutcome(e,t,r)}catch{}}async function pn(e,t,r,n={}){let o=Ve(e);if(o==="off")return null;let s=T.seats[e]??{mode:o},i=n.backend??s.backend??T.defaultBackend,a=Date.now();try{let c=await D(i).decide({state:t,questions:r,model:n.model??s.model,abortSignal:n.signal,timeoutMs:n.timeoutMs??s.timeoutMs}),l=fn(e,o,t,r,c,n,s);return{answers:c.answers,callId:l,mode:o}}catch(u){return gn(e,o,t,r,i,n,s,a,u),yn(e,i,u),null}}function fn(e,t,r,n,o,s,i){if(!T.store)return null;try{return T.store.recordCall({seat:e,mode:t,backend:o.meta.backend,model:o.model,meta:o.meta,state:r,questions:n,answers:o.answers,usage:o.usage,incumbent:Ge(s.incumbent),links:s.links,features:s.features,keepState:!i.redactState})}catch{return null}}function gn(e,t,r,n,o,s,i,a,u){if(T.store)try{T.store.recordCall({seat:e,mode:t,backend:o,model:s.model??i.model??"unknown",meta:{structureMode:"text",answerMode:"probabilities",retries:0,stateTruncated:!1,latencyMs:Date.now()-a},state:r,questions:n,answers:{},incumbent:Ge(s.incumbent),links:s.links,features:s.features,error:String(u?.message??u).slice(0,500),keepState:!i.redactState})}catch{}}function Ge(e){if(!e)return;let t={};for(let[r,n]of Object.entries(e))n!==void 0&&(t[r]={value:n});return t}function yn(e,t,r){let n=Date.now();n-Je<6e4||(Je=n,console.warn(`[decisions] seat "${e}" on backend "${t}" failed: ${r?.message??r}`))}var ye,T,ee,bn,Je,ze=E(()=>{C();V();ye={enabled:!1,defaultBackend:"local",seats:{},store:null},T={...ye},ee=!1;bn=["off","shadow","active"];Je=0});export{D as a,Ee as b,C as c,I as d,V as e,Lt as f,Me as g,Qt as h,je as i,me as j,Un as k,Ue as l,an as m,Xe as n,cn as o,un as p,ln as q,ge as r,$e as s,Ve as t,dn as u,pn as v,ze as w};
|
|
114
|
-
//# sourceMappingURL=chunk-
|
|
114
|
+
//# sourceMappingURL=chunk-VOS2IW4V.js.map
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{createHash as l}from"crypto";import{existsSync as f,mkdirSync as c,readFileSync as g,writeFileSync as p}from"fs";import{dirname as h,resolve as v}from"path";function m(u,i,s,t){return l("sha1").update([u,i,s.toLowerCase().trim(),t??""].join("\0")).digest("hex").slice(0,12)}var d=class{file;constructor(i){this.file=v(i,"_questions.json")}get path(){return this.file}load(){if(!f(this.file))return{version:1,questions:[]};try{let i=JSON.parse(g(this.file,"utf-8"));return Array.isArray(i?.questions)?{version:1,questions:i.questions}:{version:1,questions:[]}}catch{return{version:1,questions:[]}}}save(i){c(h(this.file),{recursive:!0}),p(this.file,`${JSON.stringify(i,null,2)}
|
|
2
|
+
`)}list(i){let s=this.load().questions;return i?s.filter(t=>t.status===i):s}add(i){let s=this.load(),t=new Set(s.questions.map(n=>n.id)),r=0,e=0,o=new Date().toISOString();for(let n of i){let a=m(n.kind,n.agentId,n.subject,n.field);if(t.has(a)){e++;continue}t.add(a),s.questions.push({...n,id:a,status:"open",asked:o}),r++}return r>0&&this.save(s),{added:r,skipped:e}}resolve(i,s,t){let r=this.load(),e=r.questions.find(o=>o.id===i||o.id.startsWith(i));return e?(e.status=s,e.answered=new Date().toISOString(),t!==void 0&&(e.answer=t),this.save(r),e):null}};export{m as a,d as b};
|
|
3
|
+
//# sourceMappingURL=chunk-ZXR6GNEK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/wiki/questions.ts"],"sourcesContent":["import { createHash } from \"crypto\"\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\"\nimport { dirname, resolve } from \"path\"\n\n// The gaps a lookup cannot close.\n//\n// Two things were producing gap signal and throwing it away. Absorb has\n// always emitted a `gaps` array — entities it referenced but has no\n// article for — and the command printed it and moved on, so the signal\n// lived in a cron log nobody reads. And the field grader can now name a\n// missing `role` or `ourOwner` that no system of record holds.\n//\n// Both are the same thing: a question only a person can answer. They\n// get one queue rather than two, because a second parallel store is\n// precisely what the wiki-as-source-of-truth decision rules out.\n//\n// Stored as JSON beside the other wiki sidecars (_index.json,\n// _backlinks.json), because this is derived state that is rebuilt and\n// rewritten, not knowledge. The knowledge is what lands in the article\n// once the question is answered.\n\nexport type QuestionStatus = \"open\" | \"answered\" | \"dismissed\"\n\nexport interface WikiQuestion {\n id: string\n /** \"field\" — a named gap in an existing article.\n * \"article\" — absorb referenced something with no article at all.\n * \"contradiction\" — a write disagreed with a wiki fact and could not\n * replace it (facts/ledger.ts); the answer is the true value. */\n kind: \"field\" | \"article\" | \"contradiction\"\n agentId: string\n /** Article path for a field question; empty for a missing article. */\n path: string\n /** Article title, or the referenced name for a missing article. */\n subject: string\n /** Required-field key, for `kind: \"field\"`. */\n field?: string\n /** What tier of the build this gap sits at, so asking can be ordered. */\n tier?: string\n question: string\n /** For a contradiction: the wiki fact and the value that was refused. */\n factId?: string\n proposed?: { value: string; source: string; verifiedAt: string; verifiedBy: string }\n status: QuestionStatus\n asked: string\n answered?: string\n answer?: string\n}\n\nexport interface QuestionsFile {\n version: 1\n questions: WikiQuestion[]\n}\n\n/**\n * Stable across runs, so re-grading the same article does not ask the\n * same question twice and cannot resurrect one already dismissed.\n */\nexport function questionId(kind: string, agentId: string, subject: string, field?: string): string {\n return createHash(\"sha1\")\n .update([kind, agentId, subject.toLowerCase().trim(), field ?? \"\"].join(\"\\u0000\"))\n .digest(\"hex\")\n .slice(0, 12)\n}\n\nexport class QuestionStore {\n private readonly file: string\n\n constructor(wikiDir: string) {\n this.file = resolve(wikiDir, \"_questions.json\")\n }\n\n get path(): string { return this.file }\n\n load(): QuestionsFile {\n if (!existsSync(this.file)) return { version: 1, questions: [] }\n try {\n const parsed = JSON.parse(readFileSync(this.file, \"utf-8\")) as Partial<QuestionsFile>\n if (!Array.isArray(parsed?.questions)) return { version: 1, questions: [] }\n return { version: 1, questions: parsed.questions as WikiQuestion[] }\n } catch {\n // A corrupt queue must not stop an absorb. Worst case the\n // questions are asked again; they are idempotent by id.\n return { version: 1, questions: [] }\n }\n }\n\n private save(f: QuestionsFile): void {\n mkdirSync(dirname(this.file), { recursive: true })\n writeFileSync(this.file, `${JSON.stringify(f, null, 2)}\\n`)\n }\n\n list(status?: QuestionStatus): WikiQuestion[] {\n const all = this.load().questions\n return status ? all.filter((q) => q.status === status) : all\n }\n\n /**\n * Add questions that are not already on the queue.\n *\n * An existing id is left completely alone — including an answered or\n * dismissed one. Re-asking something a person has already dealt with\n * is how a queue becomes noise and then becomes ignored.\n */\n add(items: Array<Omit<WikiQuestion, \"id\" | \"status\" | \"asked\">>): { added: number; skipped: number } {\n const f = this.load()\n const seen = new Set(f.questions.map((q) => q.id))\n let added = 0, skipped = 0\n const now = new Date().toISOString()\n\n for (const item of items) {\n const id = questionId(item.kind, item.agentId, item.subject, item.field)\n if (seen.has(id)) { skipped++; continue }\n seen.add(id)\n f.questions.push({ ...item, id, status: \"open\", asked: now })\n added++\n }\n if (added > 0) this.save(f)\n return { added, skipped }\n }\n\n /** Returns the question so the caller can act on its subject/field. */\n resolve(id: string, status: \"answered\" | \"dismissed\", answer?: string): WikiQuestion | null {\n const f = this.load()\n const q = f.questions.find((x) => x.id === id || x.id.startsWith(id))\n if (!q) return null\n q.status = status\n q.answered = new Date().toISOString()\n if (answer !== undefined) q.answer = answer\n this.save(f)\n return q\n }\n}\n"],"mappings":"AAAA,OAAS,cAAAA,MAAkB,SAC3B,OAAS,cAAAC,EAAY,aAAAC,EAAW,gBAAAC,EAAc,iBAAAC,MAAqB,KACnE,OAAS,WAAAC,EAAS,WAAAC,MAAe,OAwD1B,SAASC,EAAWC,EAAcC,EAAiBC,EAAiBC,EAAwB,CACjG,OAAOX,EAAW,MAAM,EACrB,OAAO,CAACQ,EAAMC,EAASC,EAAQ,YAAY,EAAE,KAAK,EAAGC,GAAS,EAAE,EAAE,KAAK,IAAQ,CAAC,EAChF,OAAO,KAAK,EACZ,MAAM,EAAG,EAAE,CAChB,CAEO,IAAMC,EAAN,KAAoB,CACR,KAEjB,YAAYC,EAAiB,CAC3B,KAAK,KAAOP,EAAQO,EAAS,iBAAiB,CAChD,CAEA,IAAI,MAAe,CAAE,OAAO,KAAK,IAAK,CAEtC,MAAsB,CACpB,GAAI,CAACZ,EAAW,KAAK,IAAI,EAAG,MAAO,CAAE,QAAS,EAAG,UAAW,CAAC,CAAE,EAC/D,GAAI,CACF,IAAMa,EAAS,KAAK,MAAMX,EAAa,KAAK,KAAM,OAAO,CAAC,EAC1D,OAAK,MAAM,QAAQW,GAAQ,SAAS,EAC7B,CAAE,QAAS,EAAG,UAAWA,EAAO,SAA4B,EADrB,CAAE,QAAS,EAAG,UAAW,CAAC,CAAE,CAE5E,MAAE,CAGA,MAAO,CAAE,QAAS,EAAG,UAAW,CAAC,CAAE,CACrC,CACF,CAEQ,KAAKC,EAAwB,CACnCb,EAAUG,EAAQ,KAAK,IAAI,EAAG,CAAE,UAAW,EAAK,CAAC,EACjDD,EAAc,KAAK,KAAM,GAAG,KAAK,UAAUW,EAAG,KAAM,CAAC;AAAA,CAAK,CAC5D,CAEA,KAAKC,EAAyC,CAC5C,IAAMC,EAAM,KAAK,KAAK,EAAE,UACxB,OAAOD,EAASC,EAAI,OAAQC,GAAMA,EAAE,SAAWF,CAAM,EAAIC,CAC3D,CASA,IAAIE,EAAiG,CACnG,IAAMJ,EAAI,KAAK,KAAK,EACdK,EAAO,IAAI,IAAIL,EAAE,UAAU,IAAKG,GAAMA,EAAE,EAAE,CAAC,EAC7CG,EAAQ,EAAGC,EAAU,EACnBC,EAAM,IAAI,KAAK,EAAE,YAAY,EAEnC,QAAWC,KAAQL,EAAO,CACxB,IAAMM,EAAKlB,EAAWiB,EAAK,KAAMA,EAAK,QAASA,EAAK,QAASA,EAAK,KAAK,EACvE,GAAIJ,EAAK,IAAIK,CAAE,EAAG,CAAEH,IAAW,SAC/BF,EAAK,IAAIK,CAAE,EACXV,EAAE,UAAU,KAAK,CAAE,GAAGS,EAAM,GAAAC,EAAI,OAAQ,OAAQ,MAAOF,CAAI,CAAC,EAC5DF,IAEF,OAAIA,EAAQ,GAAG,KAAK,KAAKN,CAAC,EACnB,CAAE,MAAAM,EAAO,QAAAC,CAAQ,CAC1B,CAGA,QAAQG,EAAYT,EAAkCU,EAAsC,CAC1F,IAAMX,EAAI,KAAK,KAAK,EACdG,EAAIH,EAAE,UAAU,KAAMY,GAAMA,EAAE,KAAOF,GAAME,EAAE,GAAG,WAAWF,CAAE,CAAC,EACpE,OAAKP,GACLA,EAAE,OAASF,EACXE,EAAE,SAAW,IAAI,KAAK,EAAE,YAAY,EAChCQ,IAAW,SAAWR,EAAE,OAASQ,GACrC,KAAK,KAAKX,CAAC,EACJG,GALQ,IAMjB,CACF","names":["createHash","existsSync","mkdirSync","readFileSync","writeFileSync","dirname","resolve","questionId","kind","agentId","subject","field","QuestionStore","wikiDir","parsed","f","status","all","q","items","seen","added","skipped","now","item","id","answer","x"]}
|
package/dist/cli.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{a as n}from"./chunk-
|
|
2
|
+
import{a as n}from"./chunk-5AMQFDLE.js";import"./chunk-G3SOCQII.js";import"./chunk-APKKQGTG.js";import"./chunk-HEJOWP7O.js";import"./chunk-Z3IP66SL.js";import"./chunk-C4CDVE2E.js";import"./chunk-RKPAVWXF.js";import"./chunk-GV7S5BAX.js";import"./chunk-GSX4NK2N.js";import"./chunk-SZDACK6O.js";import"./chunk-4NXIJEYU.js";import"./chunk-B65FS265.js";import"./chunk-BYJ3A55Y.js";import"./chunk-NMFXY3QU.js";import"./chunk-F2DEKA2Q.js";import"./chunk-LQRBGQIR.js";import"./chunk-ZVP6GB4G.js";import"./chunk-ART666G6.js";import"./chunk-2D3RYIDU.js";import"./chunk-L53FTKEP.js";import"./chunk-QDRAKJSY.js";import"./chunk-NVJHA63C.js";import"./chunk-N6EWZGIX.js";import"./chunk-WP6KLXTP.js";import"./chunk-DP7RTNDM.js";import"./chunk-BYKF3UTL.js";import"./chunk-SFQUP3BP.js";import"./chunk-NEC4RXFT.js";import"./chunk-2AXFYDWF.js";import"./chunk-AQASR6KR.js";import"./chunk-76Z4VHDX.js";import"./chunk-W4YR2RO2.js";import"./chunk-AFRHKA7B.js";import"./chunk-JHWBCDD2.js";import"./chunk-APKAW7LU.js";import"./chunk-ST6KPQOY.js";import"./chunk-GQ76J72O.js";import"./chunk-ZXR6GNEK.js";import"./chunk-J3SOEFRE.js";import"./chunk-SIU6STB2.js";import"./chunk-X5C5W3E4.js";import"./chunk-Q2WW2HF4.js";import"./chunk-DWADWDMU.js";import"./chunk-NO2HOK4B.js";import"./chunk-QD6IICK7.js";import"./chunk-VWTBHLMX.js";import"./chunk-S4ASFOJU.js";import"./chunk-CUZWGTXT.js";import"./chunk-PNWNVOEZ.js";import"./chunk-64P4QHSZ.js";import"./chunk-KSDVKLHN.js";import"./chunk-TFVUOC2C.js";import"./chunk-2GIDVZ4H.js";import"./chunk-VOS2IW4V.js";import"./chunk-FX3D7YON.js";import"./chunk-72SZI2UW.js";import"./chunk-FCPTN6NF.js";import"./chunk-QOYAX2FT.js";import"./chunk-SZJMS7K4.js";import"./chunk-7I7IEX4S.js";import"./chunk-VDMYBPYB.js";import"./chunk-DSYKYZMT.js";import"./chunk-N5NPJ6DJ.js";import"./chunk-RGDKHYY2.js";import"./chunk-QIJLFPWE.js";var r=["SIGINT","SIGTERM"];function o(t=process){for(let i of r)t.on(i,()=>{t.listenerCount(i)<=1&&t.exit(0)})}o();async function s(){let t=await n();if(process.argv.slice(2).length===0){t.outputHelp();return}t.parse()}s();
|
|
3
3
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/signal-exit.ts","../src/cli.ts"],"sourcesContent":["// --- Ctrl-C / SIGTERM for CLI commands ---\n//\n// Short commands should exit at once when stopped. Long-running ones (the\n// daemon above all) install their own handler to finish in-flight work first.\n// The CLI's quick exit used to be registered unconditionally, before the\n// daemon's, and Node runs listeners in registration order — so every stop\n// exited the process before the daemon's drain began and killed in-flight\n// agent tasks mid-turn (#103). Now the quick exit only fires when nobody\n// else handles the signal.\n\ntype SignalTarget = Pick<NodeJS.Process, \"on\" | \"listenerCount\" | \"exit\">\n\nexport const CLI_EXIT_SIGNALS = [\"SIGINT\", \"SIGTERM\"] as const\n\nexport function installCliSignalExit(proc: SignalTarget = process): void {\n for (const sig of CLI_EXIT_SIGNALS) {\n proc.on(sig, () => {\n // This listener is always one of them; anything more means a command\n // is handling the stop itself.\n if (proc.listenerCount(sig) <= 1) proc.exit(0)\n })\n }\n}\n","#!/usr/bin/env node\nimport { buildProgram } from \"@/program\"\nimport { installCliSignalExit } from \"@/utils/signal-exit\"\n\ninstallCliSignalExit()\n\nasync function main() {\n const program = await buildProgram()\n\n const args = process.argv.slice(2)\n if (args.length === 0) {\n program.outputHelp()\n return\n }\n\n program.parse()\n}\n\nmain()\n"],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../src/utils/signal-exit.ts","../src/cli.ts"],"sourcesContent":["// --- Ctrl-C / SIGTERM for CLI commands ---\n//\n// Short commands should exit at once when stopped. Long-running ones (the\n// daemon above all) install their own handler to finish in-flight work first.\n// The CLI's quick exit used to be registered unconditionally, before the\n// daemon's, and Node runs listeners in registration order — so every stop\n// exited the process before the daemon's drain began and killed in-flight\n// agent tasks mid-turn (#103). Now the quick exit only fires when nobody\n// else handles the signal.\n\ntype SignalTarget = Pick<NodeJS.Process, \"on\" | \"listenerCount\" | \"exit\">\n\nexport const CLI_EXIT_SIGNALS = [\"SIGINT\", \"SIGTERM\"] as const\n\nexport function installCliSignalExit(proc: SignalTarget = process): void {\n for (const sig of CLI_EXIT_SIGNALS) {\n proc.on(sig, () => {\n // This listener is always one of them; anything more means a command\n // is handling the stop itself.\n if (proc.listenerCount(sig) <= 1) proc.exit(0)\n })\n }\n}\n","#!/usr/bin/env node\nimport { buildProgram } from \"@/program\"\nimport { installCliSignalExit } from \"@/utils/signal-exit\"\n\ninstallCliSignalExit()\n\nasync function main() {\n const program = await buildProgram()\n\n const args = process.argv.slice(2)\n if (args.length === 0) {\n program.outputHelp()\n return\n }\n\n program.parse()\n}\n\nmain()\n"],"mappings":";wyDAYO,IAAMA,EAAmB,CAAC,SAAU,SAAS,EAE7C,SAASC,EAAqBC,EAAqB,QAAe,CACvE,QAAWC,KAAOH,EAChBE,EAAK,GAAGC,EAAK,IAAM,CAGbD,EAAK,cAAcC,CAAG,GAAK,GAAGD,EAAK,KAAK,CAAC,CAC/C,CAAC,CAEL,CClBAE,EAAqB,EAErB,eAAeC,GAAO,CACpB,IAAMC,EAAU,MAAMC,EAAa,EAGnC,GADa,QAAQ,KAAK,MAAM,CAAC,EACxB,SAAW,EAAG,CACrBD,EAAQ,WAAW,EACnB,OAGFA,EAAQ,MAAM,CAChB,CAEAD,EAAK","names":["CLI_EXIT_SIGNALS","installCliSignalExit","proc","sig","installCliSignalExit","main","program","buildProgram"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a,b,c,d,e,f}from"./chunk-AU6FFC4I.js";import"./chunk-ST6KPQOY.js";import"./chunk-GQ76J72O.js";import"./chunk-ZXR6GNEK.js";import"./chunk-QIJLFPWE.js";export{d as approveFactProposal,c as listFactProposals,a as parseClaim,b as proposeFacts,e as rejectFactProposal,f as routeMemo};
|
|
2
|
+
//# sourceMappingURL=fact-proposals-ERRQXV2J.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{b as A}from"./chunk-NMFXY3QU.js";import"./chunk-QIJLFPWE.js";import{existsSync as C,readFileSync as j}from"fs";import{resolve as M}from"path";import{execFile as G}from"child_process";function p(n,t,o={}){return new Promise(e=>{G(n,t,{timeout:o.timeoutMs??15e3,signal:o.signal,maxBuffer:4*1024*1024,env:{...process.env,PATH:[process.env.PATH??"","/opt/homebrew/bin","/usr/local/bin",`${process.env.HOME??""}/.local/bin`].filter(Boolean).join(":")}},(r,a,i)=>{let s=r&&typeof r.code=="number"?r.code:r?1:0;e({stdout:String(a??""),stderr:String(i??""),code:s})})})}async function y(n){let{code:t}=await p("command",["-v",n],{timeoutMs:3e3}).catch(()=>({code:1}));if(t===0)return!0;let{code:o}=await p("/usr/bin/which",[n],{timeoutMs:3e3});return o===0}var I=[["216","Tunisia"],["966","Saudi Arabia"],["971","UAE"],["974","Qatar"],["965","Kuwait"],["973","Bahrain"],["968","Oman"],["962","Jordan"],["961","Lebanon"],["212","Morocco"],["213","Algeria"],["218","Libya"],["249","Sudan"],["20","Egypt"],["90","Turkey"],["33","France"],["49","Germany"],["39","Italy"],["34","Spain"],["44","United Kingdom"],["31","Netherlands"],["32","Belgium"],["41","Switzerland"],["1","US/Canada"]];function m(n){let t=n.replace(/\D/g,""),o,e=0;for(let[r,a]of I)t.startsWith(r)&&r.length>e&&(o=a,e=r.length);return o}function F(n){let t=[];for(let o of n.split(`
|
|
2
2
|
`)){let e=o.trim();if(!e||e.startsWith("ALIAS"))continue;let r=e.split(/\s{2,}/).filter(Boolean);if(r.length<2)continue;let a=r[r.length-1];if(!a.includes("@"))continue;let i=r[r.length-2],s=r.length>=3?r[r.length-3]:"";if(!s||!/\d/.test(i))continue;let l=m(i);t.push({name:s,source:"wacli",fields:{phone:`+${i.replace(/\D/g,"")}`,whatsapp:a,...l?{country:l}:{}}})}return t}function w(){return{name:"wacli",provides:["contact value","country"],async available(){if(!await y("wacli"))return{kind:"not-installed",hint:"brew install wacli \u2014 see https://wacli.sh"};let{stdout:n,stderr:t,code:o}=await p("wacli",["contacts","search","__agentx_probe__"],{timeoutMs:1e4});return o!==0&&/auth|not logged in|no session|login/i.test(n+t)?{kind:"not-configured",hint:"wacli auth \u2014 scan the QR to link the account"}:null},async lookup(n,t){let o=[],e=new Set;for(let r of n)for(let a of T(r.name)){let{stdout:i,code:s}=await p("wacli",["contacts","search",a],{signal:t,timeoutMs:15e3});if(s!==0)continue;let l=F(i).filter(u=>E(u.name,r.name));if(l.length!==0){for(let u of l){let c=u.fields.whatsapp;e.has(c)||(e.add(c),o.push({...u,fuzzy:!P(u.name,r.name)}))}break}}return o}}}var h=n=>n.toLowerCase().normalize("NFD").replace(/[̀-ͯ]/g,"").replace(/[^a-z0-9 ]/g,"").trim(),P=(n,t)=>h(n)===h(t);function T(n){let t=h(n).split(/\s+/).filter(o=>o.length>2);return t.length>1?[n,t[t.length-1]]:[n]}function E(n,t){let o=h(n).split(/\s+/).filter(Boolean),e=h(t).split(/\s+/).filter(Boolean);if(o.length===0||e.length===0)return!1;let[r,a]=o.length<=e.length?[o,e]:[e,o];return r.every(i=>a.includes(i))}var D={whatsapp:"whatsapp",telegram:"telegram",gitlab:"gitlab",github:"github",email:"email",phone:"phone",slack:"slack",discord:"discord"};function z(n=".agentx"){return M(process.cwd(),n,"contacts.json")}function S(n){if(!C(n))return[];try{let t=JSON.parse(j(n,"utf-8"));return Array.isArray(t?.contacts)?t.contacts:[]}catch{return[]}}var b=n=>n.toLowerCase().normalize("NFD").replace(/[̀-ͯ]/g,"").replace(/[^a-z0-9 ]/g,"").trim();function _(n){return[n.name,n.id,...n.aliases??[]].filter(t=>!!(t&&t.trim())).map(b)}function L(n){let t={};for(let[o,e]of Object.entries(n.channels??{})){let r=String(e??"").trim();if(!r)continue;let a=D[o.toLowerCase()]??o.toLowerCase();if(a==="whatsapp"){let i=r.split("@")[0].replace(/\D/g,"");if(t.whatsapp=r.includes("@")?r:`${i}@s.whatsapp.net`,i){t.phone??=`+${i}`;let s=m(i);s&&(t.country??=s)}continue}if(a==="phone"){let i=r.replace(/\D/g,"");t.phone=r.startsWith("+")?r:`+${i}`;let s=m(i);s&&(t.country??=s);continue}if(a==="telegram"&&/^\d+$/.test(r)){t.telegramId=r;continue}t[a]=a==="gitlab"||a==="github"?r.startsWith("@")?r:`@${r}`:r}return t}function k(n={}){let t=n.path??z();return{name:"contacts",provides:["contact value","handles","country"],async available(){return C(t)?S(t).length>0?null:{kind:"not-configured",hint:`${t} has no contacts`}:{kind:"not-configured",hint:`no ${t} \u2014 add {"contacts":[{"name":"\u2026","aliases":[],"channels":{"whatsapp":"\u2026"}}]}`}},async lookup(o){let e=S(t);if(e.length===0)return[];let r=new Map;for(let s of e)for(let l of _(s))l&&r.set(l,s);let a=[],i=new Set;for(let s of o){let l=r.get(b(s.name));if(!l||i.has(l))continue;i.add(l);let u=L(l);Object.keys(u).length!==0&&a.push({name:l.name??s.name,source:"contacts",fields:u,fuzzy:b(l.name??"")!==b(s.name)})}return a}}}function v(n={}){let t=(n.baseUrl??process.env.GITLAB_URL??"").replace(/\/+$/,""),o=n.token??process.env.GITLAB_ADMIN_TOKEN??process.env.GITLAB_TOKEN;return{name:"gitlab",provides:["email","handle","profile URL"],async available(){if(!t)return{kind:"not-configured",hint:"export GITLAB_URL=https://<your-gitlab-host>"};if(!o)return{kind:"not-configured",hint:"export GITLAB_ADMIN_TOKEN=<PAT> (read_api scope is enough)"};try{let e=await fetch(`${t}/api/v4/user`,{headers:{"PRIVATE-TOKEN":o}});if(e.status===401||e.status===403)return{kind:"not-configured",hint:`GitLab rejected the token (${e.status}) \u2014 set a valid GITLAB_ADMIN_TOKEN`};if(!e.ok)return{kind:"failed",hint:`GitLab returned ${e.status} for the auth probe`}}catch(e){return{kind:"failed",hint:`cannot reach ${t}: ${String(e?.message??e)}`}}return null},async lookup(e,r){if(!o||!t)return[];let a=[],i=new Set;for(let s of e){let l=`${t}/api/v4/users?search=${encodeURIComponent(s.name)}&per_page=5`,u;try{let c=await fetch(l,{headers:{"PRIVATE-TOKEN":o},signal:r});if(!c.ok)continue;u=await c.json()}catch{continue}if(Array.isArray(u))for(let c of u){let d=c.username??c.web_url??"";if(!d||i.has(d))continue;i.add(d);let f={},g=c.email||c.public_email;g&&(f.email=g),c.username&&(f.gitlab=`@${c.username}`),c.web_url&&(f.profile=c.web_url),c.organization&&(f.organisation=c.organization),c.job_title&&(f.role=c.job_title),c.state&&c.state!=="active"&&(f.accountState=c.state),Object.keys(f).length!==0&&a.push({name:c.name??s.name,source:"gitlab",fields:f,fuzzy:(c.name??"").toLowerCase()!==s.name.toLowerCase()})}}return a}}}function x(){return{name:"gog",provides:["contact value","email","organisation","role","country"],async available(){if(!await y("gog"))return{kind:"not-installed",hint:"brew install gog \u2014 Google CLI"};let{stdout:n,stderr:t}=await p("gog",["contacts","list","-j"],{timeoutMs:2e4}),o=n+t;return/unknown flag|Run with --help/i.test(o)?{kind:"failed",hint:`gog rejected the probe: ${o.split(`
|
|
3
3
|
`)[0]}`}:/accessNotConfigured|has not been used in project/i.test(o)?{kind:"not-configured",hint:"enable the People API on the gog OAuth project, then retry (console.developers.google.com \u2192 APIs \u2192 People API)"}:/invalid_grant|PERMISSION_DENIED|unauthenticated/i.test(o)?{kind:"not-configured",hint:"gog auth login \u2014 the stored token is expired or lacks contacts scope"}:null},async lookup(n,t){let o=[];for(let e of n){let{stdout:r,code:a}=await p("gog",["contacts","search",e.name,"-j","--results-only"],{signal:t,timeoutMs:2e4});if(a!==0)continue;let i;try{i=JSON.parse(r)}catch{continue}let s=Array.isArray(i)?i:i?.results??i?.people??[];for(let l of s){let u={},c=l.phoneNumbers?.[0]?.value,d=l.emailAddresses?.[0]?.value,f=l.organizations?.[0];c&&(u.phone=c),d&&(u.email=d),f?.name&&(u.organisation=f.name),f?.title&&(u.role=f.title);let g=l.addresses?.[0]?.country;g&&(u.country=g),Object.keys(u).length!==0&&o.push({name:l.names?.[0]?.displayName??e.name,source:"gog",fields:u})}}return o}}}var R=n=>typeof n=="string"&&n.trim()?n.trim():void 0;function $(n){return String(n??"").split("@")[0].split(":")[0].toLowerCase()}function H(n){let t=new Map;for(let o of n){let e=R(o.meta?.sender);if(!e||A(e))continue;let r=R(o.meta?.senderId),a=R(o.meta?.senderUsername),i=$(o.source),s={};if(r&&/@s\.whatsapp\.net$/.test(r)){let c=r.split("@")[0].replace(/\D/g,"");if(c){s.phone=`+${c}`,s.whatsapp=r;let d=m(c);d&&(s.country=d)}}else if(i==="whatsapp"&&r&&/^\d{6,}$/.test(r)){s.phone=`+${r}`,s.whatsapp=`${r}@s.whatsapp.net`;let c=m(r);c&&(s.country=c)}if(a){let c=a.startsWith("@")?a:`@${a}`;i==="gitlab"?s.gitlab=c:i==="github"?s.github=c:i==="telegram"?s.telegram=c:s.handle=c}if(r&&!s.phone&&!a&&(s[`${i||"platform"}Id`]=r),Object.keys(s).length===0)continue;let l=e.toLowerCase(),u=t.get(l);if(!u){t.set(l,{name:e,source:"entries",fields:s});continue}for(let[c,d]of Object.entries(s))u.fields[c]??=d}return Array.from(t.values())}function U(n){let t;return{...n,available:()=>t??=n.available(),lookup:(o,e)=>n.lookup(o,e)}}function N(){return[k(),w(),v(),x()].map(U)}function ut(n,t={}){let o=t.max??25,e=new Map;for(let a of n){let i=(a.sender??"").trim();i&&O(i)&&e.set(i.toLowerCase(),{name:i,origin:"sender",type:"person"})}for(let a of n){let i=(a.context??"").trim();if(!O(i))continue;let s=i.toLowerCase();e.has(s)||e.set(s,{name:i,origin:"context"})}let r=(t.known??[]).filter(a=>a.trim().length>2);if(r.length>0){let a=n.map(i=>i.content??"").join(`
|
|
4
4
|
`).toLowerCase();for(let i of r){let s=i.toLowerCase().trim();e.has(s)||a.includes(s)&&e.set(s,{name:i,origin:"body",type:"person"})}}return Array.from(e.values()).slice(0,o)}var B=new Set(["me","user","system","cron","unknown","anonymous","bot","agent","self","test","admin","none","null","n/a"]),W=new Set(["group","team","chat","channel","squad","crew","room","family","project","board","committee","club","staff","office","dept","department","support","sales","ops","admins","everyone","all"]);function O(n){let t=n.trim();if(!t||t.length>48||B.has(t.toLowerCase())||/[\d@/\\#:|_]/.test(t))return!1;let o=t.split(/\s+/);return o.length<2||o.length>4||o.some(e=>W.has(e.toLowerCase()))?!1:o.every(e=>/^[\p{Lu}][\p{L}'’.-]*$/u.test(e))}async function ft(n,t={}){let o=t.sources??N(),e=n.slice(0,t.maxEntities??25);if(e.length===0)return{records:[],results:[]};let r=new AbortController,a=setTimeout(()=>r.abort(),t.timeoutMs??12e4);try{let i=await Promise.all(o.map(async s=>{let l=Date.now();try{let u=await s.available();if(u)return{source:s.name,records:[],unavailable:u,ms:Date.now()-l};let c=await s.lookup(e,r.signal);return{source:s.name,records:c,ms:Date.now()-l}}catch(u){return{source:s.name,records:[],unavailable:{kind:"failed",hint:String(u?.message??u)},ms:Date.now()-l}}}));for(let s of i)t.onResult?.(s);return{records:i.flatMap(s=>s.records),results:i}}finally{clearTimeout(a)}}function dt(n,t=N()){let o=new Map(t.map(e=>[e.name,e.provides]));return n.filter(e=>e.unavailable&&e.unavailable.kind!=="failed").map(e=>({source:e.source,kind:e.unavailable.kind,hint:e.unavailable.hint,provides:o.get(e.source)??[]}))}function pt(n){let t=new Map;for(let o of n){let e=o.name.toLowerCase().trim(),r=t.get(e);r||(r={name:o.name,fields:{}},t.set(e,r));for(let[a,i]of Object.entries(o.fields)){if(!i?.trim())continue;let s=r.fields[a];if(!s){r.fields[a]={value:i,source:o.source};continue}s.value!==i&&(r.fields[`${a} (${o.source})`]??={value:i,source:o.source})}}return Array.from(t.values())}function mt(n){if(n.length===0)return"";let t=n.filter(o=>Object.keys(o.fields).length>0).map(o=>{let e=Object.entries(o.fields).map(([r,a])=>` - ${r}: \`${a.value}\` _(${a.source})_`).join(`
|
|
@@ -19,4 +19,4 @@ contradicts the entries, this wins and the entry is stale.
|
|
|
19
19
|
${t.join(`
|
|
20
20
|
`)}
|
|
21
21
|
`}export{m as countryFromPhone,k as createContactsSource,v as createGitlabSource,x as createGogSource,w as createWacliSource,N as defaultSources,ut as extractHints,L as factsFrom,dt as installPrompts,O as isPersonName,S as loadContacts,U as memoizeAvailability,pt as mergeRecords,_ as namesOf,F as parseContactsTable,$ as platformOf,E as plausible,H as recordsFromEntries,mt as renderFactsBlock,ft as resolveFacts};
|
|
22
|
-
//# sourceMappingURL=facts-
|
|
22
|
+
//# sourceMappingURL=facts-X44PF73W.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -8623,6 +8623,19 @@ interface DriftReport {
|
|
|
8623
8623
|
missingTools: string[];
|
|
8624
8624
|
}
|
|
8625
8625
|
|
|
8626
|
+
type FactClass = "billing" | "account" | "outage" | "deploy" | "work-state" | "stable";
|
|
8627
|
+
/** Where a fact came from and when it was last checked. */
|
|
8628
|
+
interface Provenance {
|
|
8629
|
+
/** A system, URL or command, or "owner said". */
|
|
8630
|
+
source: string;
|
|
8631
|
+
verifiedAt: string;
|
|
8632
|
+
/** The agent or person who checked it. */
|
|
8633
|
+
verifiedBy: string;
|
|
8634
|
+
volatility: FactClass;
|
|
8635
|
+
/** Overrides the class TTL. */
|
|
8636
|
+
ttlDays?: number;
|
|
8637
|
+
}
|
|
8638
|
+
|
|
8626
8639
|
type SourceTrust =
|
|
8627
8640
|
/** Only the operator can reach it: CLI, dashboard, local voice, TUI and Raycast. */
|
|
8628
8641
|
"operator"
|
|
@@ -8653,6 +8666,13 @@ interface MemoryFact {
|
|
|
8653
8666
|
reviewedAt?: string;
|
|
8654
8667
|
createdAt: string;
|
|
8655
8668
|
expiresAt?: string;
|
|
8669
|
+
/** Where the fact was checked (#273). Absent on facts nobody checked. */
|
|
8670
|
+
provenance?: Partial<Provenance>;
|
|
8671
|
+
/** Flagged by `agentx memory facts flag-unsourced`: volatile, no source. */
|
|
8672
|
+
unverified?: {
|
|
8673
|
+
since: string;
|
|
8674
|
+
reason: string;
|
|
8675
|
+
};
|
|
8656
8676
|
accessCount?: number;
|
|
8657
8677
|
lastAccessed?: string;
|
|
8658
8678
|
nextReview?: string;
|
|
@@ -8661,6 +8681,9 @@ interface MemoryFact {
|
|
|
8661
8681
|
}
|
|
8662
8682
|
declare class MemoryStore {
|
|
8663
8683
|
private memoryDir;
|
|
8684
|
+
/** The wiki's fact ledger: memory lines that restate one of its facts
|
|
8685
|
+
* are rendered as references to it (memory-context.ts). */
|
|
8686
|
+
private ledger;
|
|
8664
8687
|
constructor(baseDir?: string);
|
|
8665
8688
|
private filePath;
|
|
8666
8689
|
/** Store a fact. Refuses secrets (returns false). Stamps the source's
|
|
@@ -8698,7 +8721,10 @@ declare class MemoryStore {
|
|
|
8698
8721
|
scrubSecrets(agentId: string, apply?: boolean): number;
|
|
8699
8722
|
/** Trust and review counts, for the CLI. */
|
|
8700
8723
|
trustSummary(agentId: string): Record<string, number>;
|
|
8701
|
-
|
|
8724
|
+
/** The agent's facts file, for backups. */
|
|
8725
|
+
fileFor(agentId: string): string;
|
|
8726
|
+
/** Replace every fact of an agent. Callers back the file up first. */
|
|
8727
|
+
rewrite(agentId: string, memories: MemoryFact[]): void;
|
|
8702
8728
|
/**
|
|
8703
8729
|
* Check if a substantially similar memory already exists.
|
|
8704
8730
|
*/
|
|
@@ -9315,6 +9341,8 @@ declare class WikiHub {
|
|
|
9315
9341
|
* graph: agents/<id>/graph/
|
|
9316
9342
|
*/
|
|
9317
9343
|
getAgentWiki(agentId: string): WikiStore;
|
|
9344
|
+
/** The wiki root: shared sidecars (_facts.json, _questions.json) live here. */
|
|
9345
|
+
getBaseDir(): string;
|
|
9318
9346
|
getSharedStore(): WikiStore;
|
|
9319
9347
|
listAgents(): string[];
|
|
9320
9348
|
getAgentEntries(agentId: string): WikiEntry[];
|
|
@@ -9612,17 +9640,17 @@ declare const graphNodeSchema: z.ZodObject<{
|
|
|
9612
9640
|
createdBy: z.ZodOptional<z.ZodString>;
|
|
9613
9641
|
}, "strip", z.ZodTypeAny, {
|
|
9614
9642
|
id: string;
|
|
9615
|
-
createdAt: string;
|
|
9616
9643
|
axes: Record<string, string>;
|
|
9617
9644
|
level: string;
|
|
9618
9645
|
parentId: string | null;
|
|
9646
|
+
createdAt: string;
|
|
9619
9647
|
createdBy?: string | undefined;
|
|
9620
9648
|
}, {
|
|
9621
9649
|
id: string;
|
|
9622
|
-
createdAt: string;
|
|
9623
9650
|
axes: Record<string, string>;
|
|
9624
9651
|
level: string;
|
|
9625
9652
|
parentId: string | null;
|
|
9653
|
+
createdAt: string;
|
|
9626
9654
|
createdBy?: string | undefined;
|
|
9627
9655
|
}>;
|
|
9628
9656
|
type GraphNode = z.infer<typeof graphNodeSchema>;
|
|
@@ -9660,7 +9688,7 @@ declare const classificationSchema: z.ZodObject<{
|
|
|
9660
9688
|
preview: z.ZodOptional<z.ZodString>;
|
|
9661
9689
|
}, "strip", z.ZodTypeAny, {
|
|
9662
9690
|
path: string[];
|
|
9663
|
-
status: "
|
|
9691
|
+
status: "pending" | "approved" | "rejected";
|
|
9664
9692
|
source: "user" | "llm" | "cache";
|
|
9665
9693
|
ts: string;
|
|
9666
9694
|
msgHash: string;
|
|
@@ -9676,7 +9704,7 @@ declare const classificationSchema: z.ZodObject<{
|
|
|
9676
9704
|
sender?: string | undefined;
|
|
9677
9705
|
}, {
|
|
9678
9706
|
path: string[];
|
|
9679
|
-
status: "
|
|
9707
|
+
status: "pending" | "approved" | "rejected";
|
|
9680
9708
|
source: "user" | "llm" | "cache";
|
|
9681
9709
|
ts: string;
|
|
9682
9710
|
msgHash: string;
|
|
@@ -9710,11 +9738,11 @@ declare const fingerprintEntrySchema: z.ZodObject<{
|
|
|
9710
9738
|
}, "strip", z.ZodTypeAny, {
|
|
9711
9739
|
path: string[];
|
|
9712
9740
|
fingerprint: string;
|
|
9713
|
-
updatedAt: string;
|
|
9714
9741
|
leaf: {
|
|
9715
9742
|
output?: string | undefined;
|
|
9716
9743
|
input?: string | undefined;
|
|
9717
9744
|
};
|
|
9745
|
+
updatedAt: string;
|
|
9718
9746
|
}, {
|
|
9719
9747
|
path: string[];
|
|
9720
9748
|
fingerprint: string;
|
|
@@ -9742,37 +9770,37 @@ declare const nodesFileSchema: z.ZodObject<{
|
|
|
9742
9770
|
createdBy: z.ZodOptional<z.ZodString>;
|
|
9743
9771
|
}, "strip", z.ZodTypeAny, {
|
|
9744
9772
|
id: string;
|
|
9745
|
-
createdAt: string;
|
|
9746
9773
|
axes: Record<string, string>;
|
|
9747
9774
|
level: string;
|
|
9748
9775
|
parentId: string | null;
|
|
9776
|
+
createdAt: string;
|
|
9749
9777
|
createdBy?: string | undefined;
|
|
9750
9778
|
}, {
|
|
9751
9779
|
id: string;
|
|
9752
|
-
createdAt: string;
|
|
9753
9780
|
axes: Record<string, string>;
|
|
9754
9781
|
level: string;
|
|
9755
9782
|
parentId: string | null;
|
|
9783
|
+
createdAt: string;
|
|
9756
9784
|
createdBy?: string | undefined;
|
|
9757
9785
|
}>, "many">>;
|
|
9758
9786
|
}, "strip", z.ZodTypeAny, {
|
|
9759
9787
|
version: number;
|
|
9760
9788
|
nodes: {
|
|
9761
9789
|
id: string;
|
|
9762
|
-
createdAt: string;
|
|
9763
9790
|
axes: Record<string, string>;
|
|
9764
9791
|
level: string;
|
|
9765
9792
|
parentId: string | null;
|
|
9793
|
+
createdAt: string;
|
|
9766
9794
|
createdBy?: string | undefined;
|
|
9767
9795
|
}[];
|
|
9768
9796
|
}, {
|
|
9769
9797
|
version?: number | undefined;
|
|
9770
9798
|
nodes?: {
|
|
9771
9799
|
id: string;
|
|
9772
|
-
createdAt: string;
|
|
9773
9800
|
axes: Record<string, string>;
|
|
9774
9801
|
level: string;
|
|
9775
9802
|
parentId: string | null;
|
|
9803
|
+
createdAt: string;
|
|
9776
9804
|
createdBy?: string | undefined;
|
|
9777
9805
|
}[] | undefined;
|
|
9778
9806
|
}>;
|
|
@@ -9797,11 +9825,11 @@ declare const indexFileSchema: z.ZodObject<{
|
|
|
9797
9825
|
}, "strip", z.ZodTypeAny, {
|
|
9798
9826
|
path: string[];
|
|
9799
9827
|
fingerprint: string;
|
|
9800
|
-
updatedAt: string;
|
|
9801
9828
|
leaf: {
|
|
9802
9829
|
output?: string | undefined;
|
|
9803
9830
|
input?: string | undefined;
|
|
9804
9831
|
};
|
|
9832
|
+
updatedAt: string;
|
|
9805
9833
|
}, {
|
|
9806
9834
|
path: string[];
|
|
9807
9835
|
fingerprint: string;
|
|
@@ -9815,11 +9843,11 @@ declare const indexFileSchema: z.ZodObject<{
|
|
|
9815
9843
|
entries: Record<string, {
|
|
9816
9844
|
path: string[];
|
|
9817
9845
|
fingerprint: string;
|
|
9818
|
-
updatedAt: string;
|
|
9819
9846
|
leaf: {
|
|
9820
9847
|
output?: string | undefined;
|
|
9821
9848
|
input?: string | undefined;
|
|
9822
9849
|
};
|
|
9850
|
+
updatedAt: string;
|
|
9823
9851
|
}>;
|
|
9824
9852
|
version: number;
|
|
9825
9853
|
}, {
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as L}from"./chunk-Y57CULGE.js";import{a as St,b as kt,c as vt,d as xt,da as Tt,e as $t,ea as Mt,f as Ct,g as Pt,h as bt}from"./chunk-
|
|
1
|
+
import{a as L}from"./chunk-Y57CULGE.js";import{a as St,b as kt,c as vt,d as xt,da as Tt,e as $t,ea as Mt,f as Ct,g as Pt,h as bt}from"./chunk-4NXIJEYU.js";import"./chunk-B65FS265.js";import"./chunk-BYJ3A55Y.js";import"./chunk-NMFXY3QU.js";import"./chunk-F2DEKA2Q.js";import"./chunk-LQRBGQIR.js";import"./chunk-ZVP6GB4G.js";import"./chunk-ART666G6.js";import"./chunk-2D3RYIDU.js";import"./chunk-L53FTKEP.js";import{S as yt,l as lt,m as ct,n as dt,o as mt,p as pt}from"./chunk-QDRAKJSY.js";import"./chunk-NVJHA63C.js";import"./chunk-N6EWZGIX.js";import"./chunk-WP6KLXTP.js";import"./chunk-DP7RTNDM.js";import{A as D,B as z,C as V,a as ye,b as we,c as Se,d as Ae,e as Ie,f as Oe,g as Ne,h as He,i as je,j as Ue,k as _e,l as I,m as q,n as Be,o as qe,p as Ye,q as O,r as ze,s as Ve,t as Xe,u as x,v as Y,w as Qe,x as Ze,y as et,z as wt}from"./chunk-BYKF3UTL.js";import{a as B,b as M,c as F}from"./chunk-SFQUP3BP.js";import"./chunk-NEC4RXFT.js";import"./chunk-2AXFYDWF.js";import"./chunk-AQASR6KR.js";import"./chunk-76Z4VHDX.js";import"./chunk-W4YR2RO2.js";import"./chunk-AFRHKA7B.js";import{s as ut}from"./chunk-JHWBCDD2.js";import"./chunk-APKAW7LU.js";import"./chunk-ST6KPQOY.js";import"./chunk-GQ76J72O.js";import"./chunk-ZXR6GNEK.js";import"./chunk-J3SOEFRE.js";import"./chunk-SIU6STB2.js";import"./chunk-X5C5W3E4.js";import"./chunk-Q2WW2HF4.js";import"./chunk-DWADWDMU.js";import"./chunk-NO2HOK4B.js";import"./chunk-QD6IICK7.js";import"./chunk-VWTBHLMX.js";import"./chunk-S4ASFOJU.js";import{a as gt,b as ft,e as ht}from"./chunk-CUZWGTXT.js";import"./chunk-PNWNVOEZ.js";import"./chunk-64P4QHSZ.js";import"./chunk-KSDVKLHN.js";import"./chunk-TFVUOC2C.js";import"./chunk-2GIDVZ4H.js";import{j as it,k as rt,l as at}from"./chunk-VOS2IW4V.js";import"./chunk-FX3D7YON.js";import"./chunk-72SZI2UW.js";import"./chunk-FCPTN6NF.js";import"./chunk-QOYAX2FT.js";import{a as ke,b as ve,c as xe,d as $e,e as Ce,f as Pe,g as be,h as Te,i as Me,j as Re,l as Ee,m as Ge,o as T,p as W}from"./chunk-SZJMS7K4.js";import{a as m,b as G}from"./chunk-7I7IEX4S.js";import{a as Fe,b as Le,c as A,d as De}from"./chunk-VDMYBPYB.js";import{a as Ke,b as Je,e as We}from"./chunk-DSYKYZMT.js";import{u as tt,w as st,x as ot,z as nt}from"./chunk-N5NPJ6DJ.js";import"./chunk-RGDKHYY2.js";import"./chunk-QIJLFPWE.js";W();G();import{execa as Rt}from"execa";import{existsSync as se,promises as X}from"fs";import S from"path";import ie from"node-fetch";async function Et(o,e){let t=o.split("/");if(t.length<2)throw new Error(`Invalid skill package ID: ${o}. Expected format: owner/repo`);let s=t[0],i=t[1],n=t[2];try{let a=n?`${s}/${i}/${n}`:`${s}/${i}`;await Rt("npx",["-y","skills","add",a],{cwd:e,stdio:"pipe"}),m.success(`Installed skill package: ${o}`);let r=S.resolve(e,".skills",`${s}_${i}`);if(se(r))return await ne(r,o);let d=S.resolve(e,".skills");return se(d)?await ne(d,o):[]}catch{return m.info(`Fetching skills directly from GitHub: ${s}/${i}`),await Gt(s,i,n,e)}}async function Gt(o,e,t,s){let i=[];try{let n=`https://api.github.com/repos/${o}/${e}/git/trees/main?recursive=1`,a=await ie(n);if(!a.ok)throw new Error(`GitHub API error: ${a.status}`);let d=(await a.json()).tree.filter(p=>p.type==="blob"&&p.path.endsWith("SKILL.md"));if(t){let p=d.find(f=>f.path.includes(`/${t}/`)||f.path===`${t}/SKILL.md`);if(p){let f=await oe(o,e,p.path,s);f&&i.push(f)}}else for(let p of d){let f=await oe(o,e,p.path,s);f&&i.push(f)}}catch(n){m.error(`Failed to fetch skills from GitHub: ${n.message}`)}return i}async function oe(o,e,t,s){try{let i=`https://raw.githubusercontent.com/${o}/${e}/main/${t}`,n=await ie(i);if(!n.ok)return null;let a=await n.text(),r=A(a);if(r){r.source="remote",r.packageId=`${o}/${e}`;let d=S.dirname(t),p=S.resolve(s,".skills",`${o}_${e}`,d);await X.mkdir(p,{recursive:!0}),await X.writeFile(S.resolve(p,"SKILL.md"),a),r.path=S.resolve(p,"SKILL.md")}return r}catch{return null}}async function ne(o,e){let t=[],{default:s}=await import("fast-glob"),i=await s.glob("**/SKILL.md",{cwd:o,deep:5});for(let n of i)try{let a=S.resolve(o,n),r=await X.readFile(a,"utf8"),d=A(r);d&&(d.source="remote",d.path=a,d.packageId=e,t.push(d))}catch{}return t}async function At(o,e,t,s,i){let n=["---",`name: ${o}`,`description: ${e}`];if(s?.length){n.push("tags:");for(let a of s)n.push(` - ${a}`)}if(i?.length){n.push("globs:");for(let a of i)n.push(` - ${a}`)}return n.push("---"),`${n.join(`
|
|
2
2
|
`)}
|
|
3
3
|
|
|
4
4
|
${t}`}async function It(o){let{loadLocalSkills:e}=await import("./loader-EVHZ2R73.js");return e(o)}async function Ot(o,e,t,s,i){let a=[{role:"system",content:`You are a skill author for the Agent Skills ecosystem (skills.sh).
|