toolnet-memory 0.3.9 → 0.3.11

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/bundle/init.js CHANGED
@@ -1,11 +1,11 @@
1
- import{existsSync as ct,statSync as fo}from"node:fs";import{resolve as yo,join as ho}from"node:path";import{existsSync as lt,readFileSync as ut}from"node:fs";import{homedir as dt}from"node:os";import{join as mt}from"node:path";function pt(e){let n=e.trim();return n.length>=2&&n.startsWith('"')&&n.endsWith('"')?(n=n.slice(1,-1),n.replace(/\\n/g,`
2
- `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):n.length>=2&&n.startsWith("'")&&n.endsWith("'")?n.slice(1,-1):n}function gt(){let e=process.env.TOOLNET_GLOBAL_ENV??mt(dt(),".config","toolnet-memory",".env");if(!lt(e))return;let n=ut(e,"utf8");for(let t of n.split(/\r?\n/)){let o=t.trim();if(!o||o.startsWith("#"))continue;o.startsWith("export ")&&(o=o.slice(7));let s=o.indexOf("=");if(s<=0)continue;let i=o.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(i)&&process.env[i]===void 0&&(process.env[i]=pt(o.slice(s+1)))}}gt();import{createHash as ft}from"node:crypto";import{existsSync as _,mkdirSync as yt,readFileSync as ht,renameSync as vt,writeFileSync as bt}from"node:fs";import{basename as St,dirname as M,join as A,parse as X,resolve as v}from"node:path";var Z=".toolnet",Ot="project.json";function xt(e){return ft("sha256").update(e).digest("hex").slice(0,16)}function P(e){return A(e,Z,Ot)}function wt(e){return _(P(e))}function Ct(e,n){let t=v(e),o=X(t).root;for(;;){if(wt(t))return t;if(t===o||n&&t===v(n))break;let s=M(t);if(s===t)break;t=s}return null}function kt(e){let n=v(e),t=X(n).root,o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(o.some(i=>_(A(n,i))))return n;if(n===t)break;let s=M(n);if(s===n)break;n=s}return v(e)}function It(e){let n;try{n=JSON.parse(ht(e,"utf8"))}catch(s){throw new Error(`Invalid ToolNet project manifest: ${e}: ${s instanceof Error?s.message:String(s)}`)}if(!n||typeof n!="object")throw new Error(`Invalid ToolNet project manifest: ${e}`);let t=n;if(typeof t.id!="string"||!t.id.trim())throw new Error(`ToolNet project manifest is missing id: ${e}`);if(typeof t.name!="string"||!t.name.trim())throw new Error(`ToolNet project manifest is missing name: ${e}`);let o=new Date().toISOString();return{version:1,id:t.id,name:t.name,remote:typeof t.remote=="string"&&t.remote.trim()?t.remote:t.name,rootPath:typeof t.rootPath=="string"?t.rootPath:M(M(e)),createdAt:typeof t.createdAt=="string"?t.createdAt:o,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:o,graphVersion:typeof t.graphVersion=="number"?t.graphVersion:0,memoryVersion:typeof t.memoryVersion=="number"?t.memoryVersion:0,metadata:t.metadata&&typeof t.metadata=="object"?t.metadata:void 0}}function q(e,n){let t=A(e,Z);yt(t,{recursive:!0});let o=P(e),s=`${o}.tmp-${process.pid}`;bt(s,JSON.stringify(n,null,2)+`
3
- `,{encoding:"utf8",mode:384}),vt(s,o)}function Q(e,n){return{id:e.id,name:e.name,remote:e.remote,rootPath:n,createdAt:e.createdAt,updatedAt:e.updatedAt,graphVersion:e.graphVersion,memoryVersion:e.memoryVersion,metadata:e.metadata}}var E=class{detect(n=process.cwd()){let t=v(n),o=kt(t),i=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(u=>_(A(o,u))),r=Ct(t,i?o:void 0);if(r){let u=P(r),p=It(u);return p.rootPath!==r&&(p.rootPath=r,p.updatedAt=new Date().toISOString(),q(r,p)),Q(p,r)}let a=new Date().toISOString(),l=St(o),c={version:1,id:xt(o),name:l,remote:l,rootPath:o,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return q(o,c),Q(c,o)}};var ee=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],m={clear:"\r\x1B[2K",cyan:"\x1B[36m",green:"\x1B[32m",red:"\x1B[31m",yellow:"\x1B[33m",amber:"\x1B[38;5;214m",dim:"\x1B[2m",reset:"\x1B[0m"};function te(e,n=16){let o=Math.max(1,n-4+1),s=e%o;return"\u2500".repeat(s)+"\u2501".repeat(4)+"\u2500".repeat(Math.max(0,n-s-4))}function ne(e){let n=Date.now()-e;return n<1e3?`${n}ms`:n<1e4?`${(n/1e3).toFixed(1)}s`:`${Math.round(n/1e3)}s`}var F=class{stream;enabled;interactive;color;intervalMs;display;label;frame=0;startedAt=0;timer;active=!1;constructor(n,t={}){this.label=n,this.stream=t.stream??process.stderr,this.enabled=t.enabled??!0,this.interactive=t.interactive??this.stream.isTTY===!0,this.color=t.color??(this.interactive&&process.env.NO_COLOR===void 0),this.intervalMs=Math.max(40,t.intervalMs??80),this.display=t.display??"spinner"}start(){return!this.enabled||this.active?this:(this.active=!0,this.startedAt=Date.now(),this.interactive?(this.render(),this.timer=setInterval(()=>{this.frame=(this.frame+1)%1e4,this.render()},this.intervalMs),this.timer.unref?.(),this):(this.stream.write(`\u2192 ${this.label}
4
- `),this))}update(n){return this.label=n,this.enabled&&this.active&&this.interactive&&this.render(),this}succeed(n){this.finish("\u2713",n??this.label,m.green)}fail(n){this.finish("\u2717",n??this.label,m.red)}warn(n){this.finish("!",n??this.label,m.yellow)}stop(){this.active&&(this.timer&&(clearInterval(this.timer),this.timer=void 0),this.enabled&&this.interactive&&this.stream.write(m.clear),this.active=!1)}render(){if(!this.enabled||!this.active||!this.interactive)return;let n=ee[this.frame%ee.length],t=this.display==="bar"?this.color?`${m.amber}${te(this.frame)}${m.reset}`:te(this.frame):this.color?`${m.cyan}${n}${m.reset}`:n,o=ne(this.startedAt),s=this.color?`${m.dim}${o}${m.reset}`:o;this.stream.write(`${m.clear}${t} ${this.label} ${s}`)}finish(n,t,o){if(!this.enabled){this.active=!1;return}this.startedAt||(this.startedAt=Date.now()),this.timer&&(clearInterval(this.timer),this.timer=void 0);let s=ne(this.startedAt),i=this.color?`${o}${n}${m.reset}`:n,r=this.color?`${m.dim}${s}${m.reset}`:s;this.interactive?this.stream.write(`${m.clear}${i} ${t} ${r}
5
- `):this.stream.write(`${i} ${t} (${s})
6
- `),this.active=!1}};async function $(e,n,t={}){let o=new F(e,t).start();try{let s=await n();return o.succeed(),s}catch(s){throw o.fail(),s}}import{existsSync as Rt}from"node:fs";import{homedir as Nt}from"node:os";import{join as _t}from"node:path";import{spawnSync as Pt}from"node:child_process";import{homedir as Mt}from"node:os";import{join as f}from"node:path";function oe(e={}){return f(e.home??Mt(),".gemini")}function D(e={}){return f(oe(e),"config")}function T(e={}){return f(D(e),"mcp_config.json")}function j(e={}){return f(D(e),"hooks.json")}function re(e={}){return f(oe(e),"antigravity-cli")}function se(e="toolnet-memory",n={}){return f(re(n),"plugins",e)}function ie(e={}){return[re(e),D(e)]}import{homedir as Et}from"node:os";import{join as b}from"node:path";function g(e={}){let n=e.xdgConfigHome??process.env.XDG_CONFIG_HOME?.trim();return n?b(n,"opencode"):b(e.home??Et(),".config","opencode")}function ae(e={}){return b(g(e),"opencode.json")}function ce(e={}){return b(g(e),"plugins")}function le(e={}){return b(g(e),"AGENTS.md")}import{homedir as ue}from"node:os";import{join as L}from"node:path";function J(e={}){return L(e.home??ue(),".claude")}function de(e={}){return L(J(e),"settings.json")}function me(e={}){return L(e.home??ue(),".claude.json")}import{homedir as At}from"node:os";import{join as S}from"node:path";function K(e={}){return e.kiroHome??process.env.KIRO_HOME??S(e.home??At(),".kiro")}function Tt(e={}){return S(K(e),"settings")}function pe(e={}){return S(Tt(e),"mcp.json")}function jt(e={}){return S(K(e),"hooks")}function ge(e={}){return S(jt(e),"toolnet-memory.json")}function fe(e={}){return[K(e)]}function Ft(e){return Pt("sh",["-lc",`command -v ${JSON.stringify(e)} >/dev/null 2>&1`],{stdio:"ignore"}).status===0}function O(e){let n=e.commandExists(e.command),t=e.configPaths.filter(i=>Rt(i)),o=t.length>0,s=[];n&&s.push(`command:${e.command}`);for(let i of t)s.push(`config:${i}`);return{agent:e.agent,detected:n||o,commandDetected:n,configDetected:o,evidence:s}}function ye(e={}){let n=e.home??Nt(),t=e.commandExists??Ft,o=e.codexHome??process.env.CODEX_HOME??_t(n,".codex");return[O({agent:"agy",command:"agy",commandExists:t,configPaths:ie({home:n})}),O({agent:"opencode",command:"opencode",commandExists:t,configPaths:[g({home:n,xdgConfigHome:e.xdgConfigHome})]}),O({agent:"claude",command:"claude",commandExists:t,configPaths:[J({home:n})]}),O({agent:"kiro",command:"kiro-cli",commandExists:t,configPaths:fe({home:n,kiroHome:e.kiroHome})}),O({agent:"codex",command:"codex",commandExists:t,configPaths:[o]})]}import{existsSync as N,mkdirSync as xe,readFileSync as we,renameSync as Xt,writeFileSync as Zt}from"node:fs";import{dirname as en,join as R}from"node:path";import{existsSync as $t,mkdirSync as Dt,readFileSync as Lt,renameSync as Jt,rmSync as Kt,writeFileSync as Ht}from"node:fs";import{dirname as Bt}from"node:path";function Yt(e){return`'${e.replace(/'/g,"'\\''")}'`}function he(e={}){let n=e.hooksFile??j();Dt(Bt(n),{recursive:!0,mode:448});let t={};if($t(n)){let r;try{r=JSON.parse(Lt(n,"utf8"))}catch(a){throw new Error(`Invalid existing Agy hooks.json: ${a instanceof Error?a.message:String(a)}`)}if(typeof r!="object"||r===null||Array.isArray(r))throw new Error("Invalid existing Agy hooks.json: root must be a JSON object.");t=r}let o=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",s=`${Yt(o)} session:agy-hook`;t["toolnet-memory"]={enabled:!0,PreToolUse:[{matcher:"view_file|list_dir|find_by_name|grep_search|run_command",hooks:[{type:"command",command:`${s} pre-tool`,timeout:5}]}],PreInvocation:[{type:"command",command:`${s} pre`,timeout:15}],PostInvocation:[{type:"command",command:`${s} post`,timeout:15}],Stop:[{type:"command",command:`${s} stop`,timeout:30}]};let i=`${n}.tmp-${process.pid}-${Date.now()}`;try{Ht(i,JSON.stringify(t,null,2)+`
7
- `,{encoding:"utf8",mode:384}),Jt(i,n)}finally{Kt(i,{force:!0})}return n}import{existsSync as Ut,mkdirSync as zt,readFileSync as Wt,renameSync as Gt,writeFileSync as Vt}from"node:fs";import{dirname as qt}from"node:path";function x(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Qt(e,n){zt(qt(e),{recursive:!0,mode:448});let t=`${e}.tmp-${process.pid}-${Date.now()}`;Vt(t,`${JSON.stringify(n,null,2)}
8
- `,{encoding:"utf8",mode:384}),Gt(t,e)}function ve(e){if(!Ut(e))return{};let n=Wt(e,"utf8").trim();if(!n)return{};let t;try{t=JSON.parse(n)}catch(o){throw new Error(`Invalid existing Agy MCP config: ${o instanceof Error?o.message:String(o)}`)}if(!x(t))throw new Error("Invalid existing Agy MCP config: root must be a JSON object.");return t}function be(e,n){return x(e)?e.command===n&&Array.isArray(e.args)&&e.args.length===1&&e.args[0]==="mcp":!1}function Se(e={}){let n=e.configFile??T(),t=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",o=e.serverName??"toolnet-memory",s=ve(n),i=s.mcpServers;if(i!==void 0&&!x(i))throw new Error("Invalid existing Agy MCP config: mcpServers must be an object.");let r=x(i)?{...i}:{},a=r[o];if(be(a,t))return{installed:!0,changed:!1,configFile:n,serverName:o,command:t,args:["mcp"]};r[o]={command:t,args:["mcp"]};let l={...s,mcpServers:r};Qt(n,l);let u=ve(n).mcpServers;if(!x(u)||!be(u[o],t))throw new Error("Agy MCP configuration was written but verification failed.");return{installed:!0,changed:!0,configFile:n,serverName:o,command:t,args:["mcp"]}}var tn=`# ToolNet Memory Continuity
1
+ import{existsSync as Do,statSync as ds}from"node:fs";import{resolve as gs,join as fs}from"node:path";import{existsSync as Ho,readFileSync as Jo}from"node:fs";import{homedir as Lo}from"node:os";import{join as Go}from"node:path";function Ko(e){let t=e.trim();return t.length>=2&&t.startsWith('"')&&t.endsWith('"')?(t=t.slice(1,-1),t.replace(/\\n/g,`
2
+ `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):t.length>=2&&t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1):t}function Bo(){let e=process.env.TOOLNET_GLOBAL_ENV??Go(Lo(),".config","toolnet-memory",".env");if(!Ho(e))return;let t=Jo(e,"utf8");for(let o of t.split(/\r?\n/)){let r=o.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let n=r.indexOf("=");if(n<=0)continue;let s=r.slice(0,n).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(s)&&process.env[s]===void 0&&(process.env[s]=Ko(r.slice(n+1)))}}Bo();import{createHash as Uo}from"node:crypto";import{existsSync as ae,mkdirSync as Yo,readFileSync as Wo,renameSync as zo,writeFileSync as qo}from"node:fs";import{basename as Vo,dirname as K,join as U,parse as Ke,resolve as A}from"node:path";var Be=".toolnet",Xo="project.json";function Qo(e){return Uo("sha256").update(e).digest("hex").slice(0,16)}function le(e){return U(e,Be,Xo)}function Zo(e){return ae(le(e))}function er(e,t){let o=A(e),r=Ke(o).root;for(;;){if(Zo(o))return o;if(o===r||t&&o===A(t))break;let n=K(o);if(n===o)break;o=n}return null}function tr(e){let t=A(e),o=Ke(t).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(s=>ae(U(t,s))))return t;if(t===o)break;let n=K(t);if(n===t)break;t=n}return A(e)}function or(e){let t;try{t=JSON.parse(Wo(e,"utf8"))}catch(n){throw new Error(`Invalid ToolNet project manifest: ${e}: ${n instanceof Error?n.message:String(n)}`)}if(!t||typeof t!="object")throw new Error(`Invalid ToolNet project manifest: ${e}`);let o=t;if(typeof o.id!="string"||!o.id.trim())throw new Error(`ToolNet project manifest is missing id: ${e}`);if(typeof o.name!="string"||!o.name.trim())throw new Error(`ToolNet project manifest is missing name: ${e}`);let r=new Date().toISOString();return{version:1,id:o.id,name:o.name,remote:typeof o.remote=="string"&&o.remote.trim()?o.remote:o.name,rootPath:typeof o.rootPath=="string"?o.rootPath:K(K(e)),createdAt:typeof o.createdAt=="string"?o.createdAt:r,updatedAt:typeof o.updatedAt=="string"?o.updatedAt:r,graphVersion:typeof o.graphVersion=="number"?o.graphVersion:0,memoryVersion:typeof o.memoryVersion=="number"?o.memoryVersion:0,metadata:o.metadata&&typeof o.metadata=="object"?o.metadata:void 0}}function Le(e,t){let o=U(e,Be);Yo(o,{recursive:!0});let r=le(e),n=`${r}.tmp-${process.pid}`;qo(n,JSON.stringify(t,null,2)+`
3
+ `,{encoding:"utf8",mode:384}),zo(n,r)}function Ge(e,t){return{id:e.id,name:e.name,remote:e.remote,rootPath:t,createdAt:e.createdAt,updatedAt:e.updatedAt,graphVersion:e.graphVersion,memoryVersion:e.memoryVersion,metadata:e.metadata}}var B=class{detect(t=process.cwd()){let o=A(t),r=tr(o),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(u=>ae(U(r,u))),i=er(o,s?r:void 0);if(i){let u=le(i),p=or(u);return p.rootPath!==i&&(p.rootPath=i,p.updatedAt=new Date().toISOString(),Le(i,p)),Ge(p,i)}let c=new Date().toISOString(),a=Vo(r),l={version:1,id:Qo(r),name:a,remote:a,rootPath:r,createdAt:c,updatedAt:c,graphVersion:0,memoryVersion:0};return Le(r,l),Ge(l,r)}};var Ue=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],f={clear:"\r\x1B[2K",cyan:"\x1B[36m",green:"\x1B[32m",red:"\x1B[31m",yellow:"\x1B[33m",amber:"\x1B[38;5;214m",dim:"\x1B[2m",reset:"\x1B[0m"};function Ye(e,t=16){let r=Math.max(1,t-4+1),n=e%r;return"\u2500".repeat(n)+"\u2501".repeat(4)+"\u2500".repeat(Math.max(0,t-n-4))}function We(e){let t=Date.now()-e;return t<1e3?`${t}ms`:t<1e4?`${(t/1e3).toFixed(1)}s`:`${Math.round(t/1e3)}s`}var ue=class{stream;enabled;interactive;color;intervalMs;display;label;frame=0;startedAt=0;timer;active=!1;constructor(t,o={}){this.label=t,this.stream=o.stream??process.stderr,this.enabled=o.enabled??!0,this.interactive=o.interactive??this.stream.isTTY===!0,this.color=o.color??(this.interactive&&process.env.NO_COLOR===void 0),this.intervalMs=Math.max(40,o.intervalMs??80),this.display=o.display??"spinner"}start(){return!this.enabled||this.active?this:(this.active=!0,this.startedAt=Date.now(),this.interactive?(this.render(),this.timer=setInterval(()=>{this.frame=(this.frame+1)%1e4,this.render()},this.intervalMs),this.timer.unref?.(),this):(this.stream.write(`\u2192 ${this.label}
4
+ `),this))}update(t){return this.label=t,this.enabled&&this.active&&this.interactive&&this.render(),this}succeed(t){this.finish("\u2713",t??this.label,f.green)}fail(t){this.finish("\u2717",t??this.label,f.red)}warn(t){this.finish("!",t??this.label,f.yellow)}stop(){this.active&&(this.timer&&(clearInterval(this.timer),this.timer=void 0),this.enabled&&this.interactive&&this.stream.write(f.clear),this.active=!1)}render(){if(!this.enabled||!this.active||!this.interactive)return;let t=Ue[this.frame%Ue.length],o=this.display==="bar"?this.color?`${f.amber}${Ye(this.frame)}${f.reset}`:Ye(this.frame):this.color?`${f.cyan}${t}${f.reset}`:t,r=We(this.startedAt),n=this.color?`${f.dim}${r}${f.reset}`:r;this.stream.write(`${f.clear}${o} ${this.label} ${n}`)}finish(t,o,r){if(!this.enabled){this.active=!1;return}this.startedAt||(this.startedAt=Date.now()),this.timer&&(clearInterval(this.timer),this.timer=void 0);let n=We(this.startedAt),s=this.color?`${r}${t}${f.reset}`:t,i=this.color?`${f.dim}${n}${f.reset}`:n;this.interactive?this.stream.write(`${f.clear}${s} ${o} ${i}
5
+ `):this.stream.write(`${s} ${o} (${n})
6
+ `),this.active=!1}};async function pe(e,t,o={}){let r=new ue(e,o).start();try{let n=await t();return r.succeed(),n}catch(n){throw r.fail(),n}}import{existsSync as bt}from"node:fs";import{homedir as Ir}from"node:os";import{join as Or}from"node:path";import{spawnSync as xr}from"node:child_process";import{homedir as rr}from"node:os";import{join as I}from"node:path";function ze(e={}){return I(e.home??rr(),".gemini")}function de(e={}){return I(ze(e),"config")}function Y(e={}){return I(de(e),"mcp_config.json")}function W(e={}){return I(de(e),"hooks.json")}function qe(e={}){return I(ze(e),"antigravity-cli")}function Ve(e="toolnet-memory",t={}){return I(qe(t),"plugins",e)}function Xe(e={}){return[qe(e),de(e)]}import{homedir as nr}from"node:os";import{join as P}from"node:path";function w(e={}){let t=e.xdgConfigHome??process.env.XDG_CONFIG_HOME?.trim();return t?P(t,"opencode"):P(e.home??nr(),".config","opencode")}function Qe(e={}){return P(w(e),"opencode.json")}function Ze(e={}){return P(w(e),"plugins")}function et(e={}){return P(w(e),"AGENTS.md")}import{homedir as tt}from"node:os";import{join as ge}from"node:path";function fe(e={}){return ge(e.home??tt(),".claude")}function ot(e={}){return ge(fe(e),"settings.json")}function rt(e={}){return ge(e.home??tt(),".claude.json")}import{homedir as ir}from"node:os";import{join as F}from"node:path";function me(e={}){return e.kiroHome??process.env.KIRO_HOME??F(e.home??ir(),".kiro")}function sr(e={}){return F(me(e),"settings")}function nt(e={}){return F(sr(e),"mcp.json")}function cr(e={}){return F(me(e),"hooks")}function it(e={}){return F(cr(e),"toolnet-memory.json")}function st(e={}){return[me(e)]}import{homedir as ar}from"node:os";import{join as k,resolve as lr}from"node:path";function z(e={}){return e.cursorHome??k(e.home??ar(),".cursor")}function ur(e={}){return e.cursorConfigDir??process.env.CURSOR_CONFIG_DIR??(e.xdgConfigHome??process.env.XDG_CONFIG_HOME?k(e.xdgConfigHome??process.env.XDG_CONFIG_HOME,"cursor"):void 0)??z(e)}function q(e={}){return k(z(e),"mcp.json")}function V(e={}){return k(z(e),"hooks.json")}function ye(e){return k(lr(e),".cursor")}function ct(e){return k(ye(e),"mcp.json")}function at(e){return k(ye(e),"hooks.json")}function pr(e){return k(ye(e),"rules")}function lt(e){return k(pr(e),"toolnet-memory.mdc")}function ut(e={}){return Array.from(new Set([z(e),ur(e)]))}import{homedir as dr}from"node:os";import{join as h,resolve as gr}from"node:path";function he(e={}){return e.copilotHome??process.env.COPILOT_HOME??h(e.home??dr(),".copilot")}function X(e={}){return h(he(e),"mcp-config.json")}function fr(e={}){return h(he(e),"hooks")}function Q(e={}){return h(fr(e),"toolnet-memory.json")}function ke(e){return h(gr(e),".github")}function pt(e){return h(ke(e),"mcp.json")}function mr(e){return h(ke(e),"hooks")}function dt(e){return h(mr(e),"toolnet-memory.json")}function yr(e){return h(ke(e),"instructions")}function gt(e){return h(yr(e),"toolnet-memory.instructions.md")}function ft(e={}){return[he(e)]}import{homedir as hr}from"node:os";import{join as m,resolve as kr}from"node:path";function Z(e={}){return e.grokHome??process.env.GROK_HOME??m(e.home??hr(),".grok")}function ee(e={}){return m(Z(e),"config.toml")}function br(e={}){return m(Z(e),"hooks")}function te(e={}){return m(br(e),"toolnet-memory.json")}function vr(e={}){return m(Z(e),"skills")}function Sr(e={}){return m(vr(e),"toolnet-continuity")}function oe(e={}){return m(Sr(e),"SKILL.md")}function be(e){return m(kr(e),".grok")}function mt(e){return m(be(e),"config.toml")}function Cr(e){return m(be(e),"hooks")}function yt(e){return m(Cr(e),"toolnet-memory.json")}function wr(e){return m(be(e),"skills")}function jr(e){return m(wr(e),"toolnet-continuity")}function ht(e){return m(jr(e),"SKILL.md")}function kt(e={}){return[Z(e)]}function Rr(e){return xr("sh",["-lc",`command -v ${JSON.stringify(e)} >/dev/null 2>&1`],{stdio:"ignore"}).status===0}function j(e){let t=e.commandExists(e.command),o=e.configPaths.filter(s=>bt(s)),r=o.length>0,n=[];t&&n.push(`command:${e.command}`);for(let s of o)n.push(`config:${s}`);return{agent:e.agent,detected:t||r,commandDetected:t,configDetected:r,evidence:n}}function Er(e){let t=e.commands.filter(i=>e.commandExists(i)),o=e.configPaths.filter(i=>bt(i)),r=t.length>0,n=o.length>0,s=[...t.map(i=>`command:${i}`),...o.map(i=>`config:${i}`)];return{agent:e.agent,detected:r||n,commandDetected:r,configDetected:n,evidence:s}}function vt(e={}){let t=e.home??Ir(),o=e.commandExists??Rr,r=e.codexHome??process.env.CODEX_HOME??Or(t,".codex");return[j({agent:"agy",command:"agy",commandExists:o,configPaths:Xe({home:t})}),j({agent:"opencode",command:"opencode",commandExists:o,configPaths:[w({home:t,xdgConfigHome:e.xdgConfigHome})]}),j({agent:"claude",command:"claude",commandExists:o,configPaths:[fe({home:t})]}),j({agent:"kiro",command:"kiro-cli",commandExists:o,configPaths:st({home:t,kiroHome:e.kiroHome})}),Er({agent:"cursor",commands:["agent","cursor-agent"],commandExists:o,configPaths:ut({home:t,cursorHome:e.cursorHome,cursorConfigDir:e.cursorConfigDir,xdgConfigHome:e.xdgConfigHome})}),j({agent:"copilot",command:"copilot",commandExists:o,configPaths:ft({home:t,copilotHome:e.copilotHome})}),j({agent:"grok",command:"grok",commandExists:o,configPaths:kt({home:t,grokHome:e.grokHome})}),j({agent:"codex",command:"codex",commandExists:o,configPaths:[r]})]}import{existsSync as ne,mkdirSync as Ot,readFileSync as xt,renameSync as Ur,writeFileSync as Yr}from"node:fs";import{dirname as Wr,join as re}from"node:path";import{existsSync as Mr,mkdirSync as Tr,readFileSync as Ar,renameSync as Pr,rmSync as Fr,writeFileSync as Nr}from"node:fs";import{dirname as _r}from"node:path";function $r(e){return`'${e.replace(/'/g,"'\\''")}'`}function St(e={}){let t=e.hooksFile??W();Tr(_r(t),{recursive:!0,mode:448});let o={};if(Mr(t)){let i;try{i=JSON.parse(Ar(t,"utf8"))}catch(c){throw new Error(`Invalid existing Agy hooks.json: ${c instanceof Error?c.message:String(c)}`)}if(typeof i!="object"||i===null||Array.isArray(i))throw new Error("Invalid existing Agy hooks.json: root must be a JSON object.");o=i}let r=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",n=`${$r(r)} session:agy-hook`;o["toolnet-memory"]={enabled:!0,PreToolUse:[{matcher:"view_file|list_dir|find_by_name|grep_search|run_command",hooks:[{type:"command",command:`${n} pre-tool`,timeout:5}]}],PreInvocation:[{type:"command",command:`${n} pre`,timeout:15}],PostInvocation:[{type:"command",command:`${n} post`,timeout:15}],Stop:[{type:"command",command:`${n} stop`,timeout:30}]};let s=`${t}.tmp-${process.pid}-${Date.now()}`;try{Nr(s,JSON.stringify(o,null,2)+`
7
+ `,{encoding:"utf8",mode:384}),Pr(s,t)}finally{Fr(s,{force:!0})}return t}import{existsSync as Dr,mkdirSync as Hr,readFileSync as Jr,renameSync as Lr,writeFileSync as Gr}from"node:fs";import{dirname as Kr}from"node:path";function N(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Br(e,t){Hr(Kr(e),{recursive:!0,mode:448});let o=`${e}.tmp-${process.pid}-${Date.now()}`;Gr(o,`${JSON.stringify(t,null,2)}
8
+ `,{encoding:"utf8",mode:384}),Lr(o,e)}function Ct(e){if(!Dr(e))return{};let t=Jr(e,"utf8").trim();if(!t)return{};let o;try{o=JSON.parse(t)}catch(r){throw new Error(`Invalid existing Agy MCP config: ${r instanceof Error?r.message:String(r)}`)}if(!N(o))throw new Error("Invalid existing Agy MCP config: root must be a JSON object.");return o}function wt(e,t){return N(e)?e.command===t&&Array.isArray(e.args)&&e.args.length===1&&e.args[0]==="mcp":!1}function jt(e={}){let t=e.configFile??Y(),o=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",r=e.serverName??"toolnet-memory",n=Ct(t),s=n.mcpServers;if(s!==void 0&&!N(s))throw new Error("Invalid existing Agy MCP config: mcpServers must be an object.");let i=N(s)?{...s}:{},c=i[r];if(wt(c,o))return{installed:!0,changed:!1,configFile:t,serverName:r,command:o,args:["mcp"]};i[r]={command:o,args:["mcp"]};let a={...n,mcpServers:i};Br(t,a);let u=Ct(t).mcpServers;if(!N(u)||!wt(u[r],o))throw new Error("Agy MCP configuration was written but verification failed.");return{installed:!0,changed:!0,configFile:t,serverName:r,command:o,args:["mcp"]}}var zr=`# ToolNet Memory Continuity
9
9
 
10
10
  ToolNet Memory is the authoritative continuity layer for previous project work.
11
11
 
@@ -46,15 +46,15 @@ Use \`mode="ai"\` only when continuity is ambiguous or requires synthesis.
46
46
  Current repository evidence overrides stale memory after ToolNet has restored the working context.
47
47
 
48
48
  Do not ask the user to repeat context already available through ToolNet Memory.
49
- `;function Ce(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function H(e,n){xe(en(e),{recursive:!0});let t=`${e}.tmp-${process.pid}-${Date.now()}`;Zt(t,n,{encoding:"utf8",mode:384}),Xt(t,e)}function Oe(e,n){N(e)&&we(e,"utf8")===n||H(e,n)}function ke(e){if(!N(e))return{};let n=we(e,"utf8").trim();if(!n)return{};let t;try{t=JSON.parse(n)}catch(o){throw new Error(`Invalid legacy Antigravity config ${e}: ${o instanceof Error?o.message:String(o)}`)}if(!Ce(t))throw new Error(`Invalid legacy Antigravity config ${e}: root must be object`);return t}function nn(e,n){if(!N(e))return!1;let t=ke(e);if(!Ce(t.mcpServers)||!Object.prototype.hasOwnProperty.call(t.mcpServers,n))return!1;let o={...t.mcpServers};return delete o[n],H(e,`${JSON.stringify({...t,mcpServers:o},null,2)}
50
- `),!0}function on(e){if(!N(e))return!1;let n=ke(e);if(!Object.prototype.hasOwnProperty.call(n,"toolnet-memory"))return!1;let t={...n};return delete t["toolnet-memory"],H(e,`${JSON.stringify(t,null,2)}
51
- `),!0}function Ie(e={}){let n=e.pluginName??"toolnet-memory",t=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",o=e.pluginRoot??se(n),s=R(o,"plugin.json"),i=R(o,"mcp_config.json"),r=R(o,"hooks.json"),a=R(o,"rules","toolnet-memory-continuity.md");xe(o,{recursive:!0,mode:448}),Oe(s,`${JSON.stringify({$schema:"https://antigravity.google/schemas/v1/plugin.json",name:n,description:"Persistent project continuity and memory for Antigravity coding sessions."},null,2)}
52
- `),Se({configFile:i,binary:t,serverName:"toolnet-memory"}),he({hooksFile:r,binary:t}),Oe(a,`${tn.trim()}
53
- `);let l=e.legacyMcpFile??T(),c=e.legacyHooksFile??j(),u=[];return l!==i&&nn(l,"toolnet-memory")&&u.push(l),c!==r&&on(c)&&u.push(c),{installed:!0,pluginRoot:o,files:[s,i,r,a],migratedLegacy:u}}import{existsSync as sn,mkdirSync as Ae,readFileSync as an,writeFileSync as Te}from"node:fs";import{join as cn}from"node:path";var rn="memory_agent_ask";function Me(){return`
49
+ `;function Rt(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function ve(e,t){Ot(Wr(e),{recursive:!0});let o=`${e}.tmp-${process.pid}-${Date.now()}`;Yr(o,t,{encoding:"utf8",mode:384}),Ur(o,e)}function It(e,t){ne(e)&&xt(e,"utf8")===t||ve(e,t)}function Et(e){if(!ne(e))return{};let t=xt(e,"utf8").trim();if(!t)return{};let o;try{o=JSON.parse(t)}catch(r){throw new Error(`Invalid legacy Antigravity config ${e}: ${r instanceof Error?r.message:String(r)}`)}if(!Rt(o))throw new Error(`Invalid legacy Antigravity config ${e}: root must be object`);return o}function qr(e,t){if(!ne(e))return!1;let o=Et(e);if(!Rt(o.mcpServers)||!Object.prototype.hasOwnProperty.call(o.mcpServers,t))return!1;let r={...o.mcpServers};return delete r[t],ve(e,`${JSON.stringify({...o,mcpServers:r},null,2)}
50
+ `),!0}function Vr(e){if(!ne(e))return!1;let t=Et(e);if(!Object.prototype.hasOwnProperty.call(t,"toolnet-memory"))return!1;let o={...t};return delete o["toolnet-memory"],ve(e,`${JSON.stringify(o,null,2)}
51
+ `),!0}function Mt(e={}){let t=e.pluginName??"toolnet-memory",o=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",r=e.pluginRoot??Ve(t),n=re(r,"plugin.json"),s=re(r,"mcp_config.json"),i=re(r,"hooks.json"),c=re(r,"rules","toolnet-memory-continuity.md");Ot(r,{recursive:!0,mode:448}),It(n,`${JSON.stringify({$schema:"https://antigravity.google/schemas/v1/plugin.json",name:t,description:"Persistent project continuity and memory for Antigravity coding sessions."},null,2)}
52
+ `),jt({configFile:s,binary:o,serverName:"toolnet-memory"}),St({hooksFile:i,binary:o}),It(c,`${zr.trim()}
53
+ `);let a=e.legacyMcpFile??Y(),l=e.legacyHooksFile??W(),u=[];return a!==s&&qr(a,"toolnet-memory")&&u.push(a),l!==i&&Vr(l)&&u.push(l),{installed:!0,pluginRoot:r,files:[n,s,i,c],migratedLegacy:u}}import{existsSync as Qr,mkdirSync as Pt,readFileSync as Zr,writeFileSync as Ft}from"node:fs";import{join as en}from"node:path";var Xr="memory_agent_ask";function Tt(){return`
54
54
  [TOOLNET MEMORY AGENT]
55
55
 
56
56
  Tool available:
57
- - ${rn}
57
+ - ${Xr}
58
58
 
59
59
  Use it automatically BEFORE guessing when:
60
60
 
@@ -101,7 +101,7 @@ Rules:
101
101
  - After receiving the ToolNet answer, continue the task
102
102
  instead of asking the user to repeat known context.
103
103
  - If ToolNet says information is not recorded, say so.
104
- `.trim()}var Ee="<!-- TOOLNET_MEMORY_BOOTSTRAP_START -->",B="<!-- TOOLNET_MEMORY_BOOTSTRAP_END -->";function ln(){let e=le();Ae(g(),{recursive:!0});let n=`${Ee}
104
+ `.trim()}var At="<!-- TOOLNET_MEMORY_BOOTSTRAP_START -->",Se="<!-- TOOLNET_MEMORY_BOOTSTRAP_END -->";function tn(){let e=et();Pt(w(),{recursive:!0});let t=`${At}
105
105
  ## ToolNet Memory
106
106
 
107
107
  ToolNet Memory is available for projects that already contain a valid \`.toolnet/project.json\`.
@@ -117,12 +117,12 @@ Rules:
117
117
  7. Current repository evidence has priority over stale memory when they conflict.
118
118
 
119
119
 
120
- ${Me()}
120
+ ${Tt()}
121
121
 
122
- ${B}`,t=sn(e)?an(e,"utf8"):"",o=t.indexOf(Ee),s=t.indexOf(B);return o>=0&&s>=o?t=t.slice(0,o)+n+t.slice(s+B.length):(t=t.trimEnd(),t&&(t+=`
122
+ ${Se}`,o=Qr(e)?Zr(e,"utf8"):"",r=o.indexOf(At),n=o.indexOf(Se);return r>=0&&n>=r?o=o.slice(0,r)+t+o.slice(n+Se.length):(o=o.trimEnd(),o&&(o+=`
123
123
 
124
- `),t+=n),Te(e,t.trimEnd()+`
125
- `,{encoding:"utf8",mode:384}),e}function je(e={}){let n=e.directory??ce();Ae(n,{recursive:!0}),ln();let t=cn(n,"toolnet-memory.js"),o=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",s=`
124
+ `),o+=t),Ft(e,o.trimEnd()+`
125
+ `,{encoding:"utf8",mode:384}),e}function Nt(e={}){let t=e.directory??Ze();Pt(t,{recursive:!0}),tn();let o=en(t,"toolnet-memory.js"),r=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",n=`
126
126
  // Generated by ToolNet Memory.
127
127
  // OpenCode integration:
128
128
  // - project gated
@@ -136,7 +136,7 @@ import path from "node:path"
136
136
  import os from "node:os"
137
137
 
138
138
  const TOOLNET_BINARY =
139
- ${JSON.stringify(o)}
139
+ ${JSON.stringify(r)}
140
140
 
141
141
  const CONTEXT_MAX_TOKENS = 700
142
142
 
@@ -1056,16 +1056,101 @@ export const ToolNetMemoryPlugin =
1056
1056
  },
1057
1057
  }
1058
1058
  }
1059
- `;return Te(t,s.trimStart(),{encoding:"utf8",mode:384}),t}import{existsSync as _e,mkdirSync as un,readFileSync as dn,renameSync as mn,writeFileSync as pn}from"node:fs";import{dirname as Pe,join as gn}from"node:path";function y(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function fn(e,n){un(Pe(e),{recursive:!0});let t=`${e}.tmp-${process.pid}-${Date.now()}`;pn(t,`${JSON.stringify(n,null,2)}
1060
- `,{encoding:"utf8",mode:384}),mn(t,e)}function Re(e){if(!_e(e))return{};let n=dn(e,"utf8").trim();if(!n)return{};let t;try{t=JSON.parse(n)}catch(o){throw new Error(`Invalid existing OpenCode opencode.json: ${o instanceof Error?o.message:String(o)}`)}if(!y(t))throw new Error("Invalid existing OpenCode opencode.json: root must be a JSON object.");return t}function Ne(e,n){if(!y(e))return!1;let t=e.command;return e.type==="local"&&e.enabled!==!1&&Array.isArray(t)&&t.length===2&&t[0]===n&&t[1]==="mcp"}function yn(e,n){let t=e.mcpServers;if(!y(t)||!Object.prototype.hasOwnProperty.call(t,n))return{root:e,changed:!1};let o={...t};return delete o[n],{root:{...e,mcpServers:o},changed:!0}}function Fe(e={}){let n=e.configFile??ae(),t=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",o=e.serverName??"toolnet-memory",s=gn(Pe(n),"opencode.jsonc"),i=_e(s)?s:void 0,r=Re(n),a=yn(r,o),l=a.root,c=l.mcp;if(c!==void 0&&!y(c))throw new Error("Invalid existing OpenCode config: mcp must be an object.");let u=y(c)?{...c}:{},p=u[o];if(Ne(p,t)&&!a.changed)return{installed:!0,changed:!1,configFile:n,serverName:o,command:[t,"mcp"],preservedJsonc:i};u[o]={type:"local",command:[t,"mcp"],enabled:!0};let d={...l,mcp:u};fn(n,d);let V=Re(n);if(!y(V.mcp)||!Ne(V.mcp[o],t))throw new Error("OpenCode MCP configuration was written but verification failed.");return{installed:!0,changed:!0,configFile:n,serverName:o,command:[t,"mcp"],preservedJsonc:i}}import{existsSync as hn,mkdirSync as $e,readFileSync as vn,writeFileSync as De}from"node:fs";import{homedir as Le}from"node:os";import{dirname as Je,join as Y}from"node:path";function bn(e){let n=[],t=/"((?:\\.|[^"\\])*)"|'([^']*)'/g,o;for(;o=t.exec(e);){let s=o[1]??o[2]??"";try{n.push(o[1]!==void 0?JSON.parse(`"${s}"`):s)}catch{n.push(s)}}return n}function Ke(e={}){let n=e.configFile??Y(process.env.CODEX_HOME??Y(Le(),".codex"),"config.toml"),t=e.previousFile??Y(Le(),".config","toolnet-memory","codex-notify-previous.json");$e(Je(n),{recursive:!0}),$e(Je(t),{recursive:!0});let o=hn(n)?vn(n,"utf8"):"",s=e.binary??"toolnet-memory",i=`notify = [${JSON.stringify(s)}, "session:codex-notify"]`,r=o.split(`
1061
- `),a=r.findIndex(d=>/^\s*\[/.test(d));a<0&&(a=r.length);let l=-1,c=-1;for(let d=0;d<a;d+=1)if(/^\s*notify\s*=/.test(r[d])){if(l=d,c=d,r[d].includes("[")&&!r[d].includes("]"))for(;c+1<a&&(c+=1,!r[c].includes("]")););break}let u=[];if(l>=0){let d=r.slice(l,c+1).join(`
1062
- `);u=bn(d),r.splice(l,c-l+1,i)}else a=r.findIndex(d=>/^\s*\[/.test(d)),a<0&&(a=r.length),r.splice(a,0,i);let p=u.length>=2&&u[u.length-1]==="session:codex-notify";return u.length>0&&!p&&De(t,JSON.stringify(u,null,2)+`
1063
- `,{encoding:"utf8",mode:384}),o=r.join(`
1064
- `),o.endsWith(`
1065
- `)||(o+=`
1066
- `),De(n,o,{encoding:"utf8",mode:384}),{configFile:n,previousFile:t,preservedPrevious:u.length>0&&!p}}import{existsSync as Sn,mkdirSync as On,readFileSync as xn,writeFileSync as wn}from"node:fs";import{homedir as Cn}from"node:os";import{dirname as kn,join as He}from"node:path";function In(e){return`'${e.replace(/'/g,"'\\''")}'`}function Be(e={}){let n=e.hooksFile??He(process.env.CODEX_HOME??He(Cn(),".codex"),"hooks.json");On(kn(n),{recursive:!0});let t={};if(Sn(n))try{t=JSON.parse(xn(n,"utf8"))}catch(a){throw new Error(`Invalid existing Codex hooks.json: ${a instanceof Error?a.message:String(a)}`)}let o=t.hooks&&typeof t.hooks=="object"&&!Array.isArray(t.hooks)?t.hooks:{};t.hooks=o;let i=(Array.isArray(o.SessionStart)?o.SessionStart:[]).filter(a=>{try{return!JSON.stringify(a).includes("session:codex-context")}catch{return!0}}),r=e.binary??"toolnet-memory";return i.push({matcher:"startup|resume|clear|compact",hooks:[{type:"command",command:`${In(r)} session:codex-context`,timeout:15,additionalContextLimit:1e3,statusMessage:"Loading ToolNet project continuity"}]}),o.SessionStart=i,wn(n,JSON.stringify(t,null,2)+`
1067
- `,{encoding:"utf8",mode:384}),n}import{spawnSync as Mn}from"node:child_process";function U(e,n){return Mn(e,n,{encoding:"utf8",stdio:["ignore","pipe","pipe"]})}function Ye(e,n){let t=U(e,["mcp","get",n,"--json"]);if(t.status!==0||!t.stdout)return null;try{return JSON.parse(t.stdout)}catch{return null}}function Ue(e,n){return e.enabled!==!1&&e.transport?.type==="stdio"&&e.transport?.command===n&&Array.isArray(e.transport?.args)&&e.transport?.args.length===1&&e.transport.args[0]==="mcp"}function ze(e={}){let n=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",t=e.codexBinary??"codex",o=e.serverName??"toolnet-memory",s=Ye(t,o);if(s&&Ue(s,n))return{installed:!0,changed:!1,serverName:o,command:n,args:["mcp"]};if(s){let a=U(t,["mcp","remove",o]);if(a.status!==0)return{installed:!1,changed:!1,serverName:o,command:n,args:["mcp"],error:(a.stderr||a.stdout||"Unable to remove old ToolNet MCP configuration.").trim()}}let i=U(t,["mcp","add",o,"--",n,"mcp"]);if(i.status!==0)return{installed:!1,changed:!1,serverName:o,command:n,args:["mcp"],error:(i.stderr||i.stdout||"Unable to register ToolNet MCP.").trim()};let r=Ye(t,o);return!r||!Ue(r,n)?{installed:!1,changed:!0,serverName:o,command:n,args:["mcp"],error:"Codex accepted MCP registration but verification did not match expected ToolNet command."}:{installed:!0,changed:!0,serverName:o,command:n,args:["mcp"]}}import{existsSync as En,mkdirSync as An,readFileSync as Tn,renameSync as jn,rmSync as Rn,writeFileSync as Nn}from"node:fs";import{dirname as _n}from"node:path";function w(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Pn(e){return/^[A-Za-z0-9_./:-]+$/u.test(e)?e:`'${e.replace(/'/gu,"'\\''")}'`}function Fn(e){if(!En(e))return{};let n;try{n=JSON.parse(Tn(e,"utf8"))}catch(t){throw new Error(`Invalid existing Claude settings.json: ${t instanceof Error?t.message:String(t)}`)}if(!w(n))throw new Error("Invalid existing Claude settings.json: root must be a JSON object.");return n}function z(e){if(e===void 0)return[];if(!Array.isArray(e))throw new Error("Invalid existing Claude settings.json: hook event must be an array.");let n=[];for(let t of e){if(!w(t)){n.push(t);continue}let o=t.hooks;if(!Array.isArray(o)){n.push(t);continue}let s=o.filter(i=>{if(!w(i))return!0;let r=i.command;return!(typeof r=="string"&&r.includes("session:claude-hook"))});s.length!==0&&n.push({...t,hooks:s})}return n}function W(e){return{type:"command",command:e,timeout:10}}function $n(e,n){An(_n(e),{recursive:!0,mode:448});let t=`${e}.toolnet-${process.pid}-${Date.now()}.tmp`;try{Nn(t,JSON.stringify(n,null,2)+`
1068
- `,{encoding:"utf8",mode:384}),jn(t,e)}finally{Rn(t,{force:!0})}}function We(e={}){let n=e.settingsFile??de(),t=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",o=Fn(n),s=o.hooks;if(s!==void 0&&!w(s))throw new Error("Invalid existing Claude settings.json: hooks must be an object.");let i=w(s)?{...s}:{},r=`${Pn(t)} session:claude-hook`,a=z(i.SessionStart);a.push({matcher:"startup|resume|clear|compact",hooks:[W(r)]}),i.SessionStart=a;let l=z(i.PostToolUse);l.push({matcher:"Edit|Write",hooks:[W(r)]}),i.PostToolUse=l;let c=z(i.Stop);c.push({hooks:[W(r)]}),i.Stop=c;let u={...o,hooks:i},p=JSON.stringify(o),d=JSON.stringify(u);return p===d?{settingsFile:n,changed:!1}:($n(n,u),{settingsFile:n,changed:!0})}import{existsSync as Dn,mkdirSync as Ln,readFileSync as Jn,renameSync as Kn,rmSync as Hn,writeFileSync as Bn}from"node:fs";import{dirname as Yn}from"node:path";function C(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Ge(e){if(!Dn(e))return{};let n;try{n=JSON.parse(Jn(e,"utf8"))}catch(t){throw new Error(`Invalid existing Claude Code config: ${t instanceof Error?t.message:String(t)}`)}if(!C(n))throw new Error("Invalid existing Claude Code config: root must be a JSON object.");return n}function Ve(e,n){if(!C(e))return!1;let t=e.args;return e.type==="stdio"&&e.command===n&&Array.isArray(t)&&t.length===1&&t[0]==="mcp"}function Un(e,n){Ln(Yn(e),{recursive:!0});let t=`${e}.toolnet-${process.pid}-${Date.now()}.tmp`;try{Bn(t,JSON.stringify(n,null,2)+`
1069
- `,{encoding:"utf8",mode:384}),Kn(t,e)}finally{Hn(t,{force:!0})}}function qe(e={}){let n=e.stateFile??me(),t=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",o=e.serverName??"toolnet-memory",s=Ge(n),i=s.mcpServers;if(i!==void 0&&!C(i))throw new Error("Invalid existing Claude Code config: mcpServers must be an object.");let r=C(i)?{...i}:{},a=r[o];if(Ve(a,t))return{installed:!0,changed:!1,configFile:n,serverName:o,command:[t,"mcp"],repaired:!1};let l=a!==void 0;r[o]={type:"stdio",command:t,args:["mcp"]},Un(n,{...s,mcpServers:r});let u=Ge(n).mcpServers;if(!C(u)||!Ve(u[o],t))throw new Error("Claude Code MCP configuration was written but verification failed.");return{installed:!0,changed:!0,configFile:n,serverName:o,command:[t,"mcp"],repaired:l}}function Qe(e={}){let n=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",t=We({binary:n,settingsFile:e.settingsFile}),o=qe({binary:n,stateFile:e.stateFile});return{hooks:t,mcp:o,files:[t.settingsFile,o.configFile]}}import{existsSync as zn,mkdirSync as Wn,readFileSync as Gn,renameSync as Vn,rmSync as qn,writeFileSync as Qn}from"node:fs";import{dirname as Xn}from"node:path";var h="ToolNet Memory - ";function et(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Zn(e){return/^[A-Za-z0-9_./:-]+$/u.test(e)?e:`'${e.replace(/'/gu,"'\\''")}'`}function Xe(e){if(!zn(e))return{};let n=Gn(e,"utf8").trim();if(!n)return{};let t;try{t=JSON.parse(n)}catch(o){throw new Error(`Invalid existing Kiro hooks file: ${o instanceof Error?o.message:String(o)}`)}if(!et(t))throw new Error("Invalid existing Kiro hooks file: root must be a JSON object.");return t}function Ze(e){return et(e)?typeof e.name=="string"&&e.name.startsWith(h):!1}function k(e){return{type:"command",command:e}}function eo(e){return[{name:`${h}Session Start`,description:"Inject compact local ToolNet continuity and capture Kiro session activation.",trigger:"SessionStart",action:k(e),timeout:10,enabled:!0},{name:`${h}Prompt Continuity`,description:"Capture prompts and refresh ToolNet guidance only for resume/continue requests.",trigger:"UserPromptSubmit",action:k(e),timeout:10,enabled:!0},{name:`${h}Raw History Guard`,description:"Prevent Kiro from reconstructing continuity from raw ToolNet/agent session history.",trigger:"PreToolUse",matcher:"*",action:k(e),timeout:10,enabled:!0},{name:`${h}Tool Capture`,description:"Capture durable tool activity while filtering noisy read-only events.",trigger:"PostToolUse",matcher:"*",action:k(e),timeout:15,enabled:!0},{name:`${h}Final Flush`,description:"Flush pending Kiro WAL events when the assistant finishes a turn.",trigger:"Stop",action:k(e),timeout:30,enabled:!0}]}function to(e,n){Wn(Xn(e),{recursive:!0,mode:448});let t=`${e}.toolnet-${process.pid}-${Date.now()}.tmp`;try{Qn(t,JSON.stringify(n,null,2)+`
1070
- `,{encoding:"utf8",mode:384}),Vn(t,e)}finally{qn(t,{force:!0})}}function tt(e={}){let n=e.hooksFile??ge(),t=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",o=Xe(n);if(o.version!==void 0&&o.version!=="v1")throw new Error(`Unsupported existing Kiro hooks version: ${String(o.version)}`);let s=o.hooks;if(s!==void 0&&!Array.isArray(s))throw new Error("Invalid existing Kiro hooks file: hooks must be an array.");let i=Array.isArray(s)?s.filter(u=>!Ze(u)):[],r=`${Zn(t)} session:kiro-hook`,a=eo(r),l={...o,version:"v1",hooks:[...i,...a]};if(JSON.stringify(o)===JSON.stringify(l))return{hooksFile:n,changed:!1,hookCount:a.length};to(n,l);let c=Xe(n);if(c.version!=="v1"||!Array.isArray(c.hooks)||c.hooks.filter(Ze).length!==a.length)throw new Error("Kiro hooks were written but verification failed.");return{hooksFile:n,changed:!0,hookCount:a.length}}import{existsSync as no,mkdirSync as oo,readFileSync as ro,renameSync as so,rmSync as io,writeFileSync as ao}from"node:fs";import{dirname as co}from"node:path";function I(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function nt(e){if(!no(e))return{};let n=ro(e,"utf8").trim();if(!n)return{};let t;try{t=JSON.parse(n)}catch(o){throw new Error(`Invalid existing Kiro MCP config: ${o instanceof Error?o.message:String(o)}`)}if(!I(t))throw new Error("Invalid existing Kiro MCP config: root must be a JSON object.");return t}function ot(e,n){return I(e)?e.command===n&&Array.isArray(e.args)&&e.args.length===1&&e.args[0]==="mcp"&&e.disabled===!1:!1}function lo(e,n){oo(co(e),{recursive:!0,mode:448});let t=`${e}.tmp-${process.pid}-${Date.now()}`;try{ao(t,`${JSON.stringify(n,null,2)}
1071
- `,{encoding:"utf8",mode:384}),so(t,e)}finally{io(t,{force:!0})}}function rt(e={}){let n=e.configFile??pe(),t=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",o=e.serverName??"toolnet-memory",s=nt(n),i=s.mcpServers;if(i!==void 0&&!I(i))throw new Error("Invalid existing Kiro MCP config: mcpServers must be an object.");let r=I(i)?{...i}:{},a=r[o];if(ot(a,t))return{installed:!0,changed:!1,configFile:n,serverName:o,command:t,args:["mcp"]};r[o]={command:t,args:["mcp"],disabled:!1};let l={...s,mcpServers:r};lo(n,l);let u=nt(n).mcpServers;if(!I(u)||!ot(u[o],t))throw new Error("Kiro MCP configuration was written but verification failed.");return{installed:!0,changed:!0,configFile:n,serverName:o,command:t,args:["mcp"]}}function st(e={}){let n=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",t=rt({binary:n,configFile:e.configFile}),o=tt({binary:n,hooksFile:e.hooksFile});return{installed:t.installed,changed:t.changed||o.changed,mcp:t,hooks:o,files:[t.configFile,o.hooksFile]}}function it(){return ye()}function G(e={}){let n=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",t=[],o=e.detections??it(),s=new Map(o.map(i=>[i.agent,i.detected]));if(!(e.force===!0||s.get("agy")===!0))t.push({agent:"agy",detected:!1,installed:!1,targets:[]});else try{let r=Ie({binary:n});t.push({agent:"agy",detected:!0,installed:!0,targets:r.files})}catch(r){t.push({agent:"agy",detected:!0,installed:!1,targets:[],error:r instanceof Error?r.message:String(r)})}if(!(e.force===!0||s.get("opencode")===!0))t.push({agent:"opencode",detected:!1,installed:!1,targets:[]});else try{let r=je({binary:n}),a=Fe({binary:n});t.push({agent:"opencode",detected:!0,installed:!0,targets:[r,a.configFile,`mcp:${a.serverName}`]})}catch(r){t.push({agent:"opencode",detected:!0,installed:!1,targets:[],error:r instanceof Error?r.message:String(r)})}if(!(e.force===!0||s.get("claude")===!0))t.push({agent:"claude",detected:!1,installed:!1,targets:[]});else try{let r=Qe({binary:n});t.push({agent:"claude",detected:!0,installed:!0,targets:[r.hooks.settingsFile,r.mcp.configFile,`mcp:${r.mcp.serverName}`]})}catch(r){t.push({agent:"claude",detected:!0,installed:!1,targets:[],error:r instanceof Error?r.message:String(r)})}if(!(e.force===!0||s.get("kiro")===!0))t.push({agent:"kiro",detected:!1,installed:!1,targets:[]});else try{let r=st({...e.kiro??{},binary:n});t.push({agent:"kiro",detected:!0,installed:!0,targets:[r.mcp.configFile,`mcp:${r.mcp.serverName}`,r.hooks.hooksFile]})}catch(r){t.push({agent:"kiro",detected:!0,installed:!1,targets:[],error:r instanceof Error?r.message:String(r)})}if(!(e.force===!0||s.get("codex")===!0))t.push({agent:"codex",detected:!1,installed:!1,targets:[]});else try{let r=Ke({binary:n}),a=Be({binary:n}),l=ze({binary:n});if(!l.installed)throw new Error(l.error??"Codex MCP registration failed");let c=[r.configFile,a,`mcp:${l.serverName}`];r.preservedPrevious&&c.push(r.previousFile),t.push({agent:"codex",detected:!0,installed:!0,targets:c})}catch(r){t.push({agent:"codex",detected:!0,installed:!1,targets:[],error:r instanceof Error?r.message:String(r)})}return t}function at(e){switch(e){case"agy":return"Agy / Antigravity";case"opencode":return"OpenCode";case"claude":return"Claude Code";case"kiro":return"Kiro CLI";case"codex":return"Codex"}}function uo(e){console.log(""),console.log("ToolNet Memory Integration Detection"),console.log("===================================="),console.log("");for(let n of e){let t=at(n.agent);if(!n.detected){console.log(`\u25CB ${t}: not detected`);continue}console.log(`\u2713 ${t}: detected`);for(let o of n.evidence)console.log(` ${o}`)}console.log("")}function mo(e){console.log(""),console.log("ToolNet Memory AI Integrations"),console.log("=============================="),console.log("");for(let n of e){let t=at(n.agent);if(!n.detected){console.log(`- ${t}: not detected`);continue}if(n.installed){console.log(`\u2713 ${t}: automatic memory enabled`);continue}console.log(`\u2717 ${t}: integration failed`),n.error&&console.log(` ${n.error}`)}console.log("")}async function po(){let e=process.argv.slice(2),n=e.includes("--all"),t=e.includes("--json");if(e.includes("--detect-only")){let i=it();if(t){console.log(JSON.stringify(i,null,2));return}uo(i);return}let s=G({force:n});if(t){console.log(JSON.stringify(s,null,2));return}mo(s)}var go=process.argv[1]&&(process.argv[1].endsWith("auto-integrate.js")||process.argv[1].endsWith("auto-integrate.ts"));go&&po().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exitCode=1});function vo(e=process.cwd()){let n=yo(e);if(!ct(n))throw new Error(`Project path does not exist: ${n}`);if(!fo(n).isDirectory())throw new Error(`Project path is not a directory: ${n}`);let t=new E().detect(n),o=ho(t.rootPath,".toolnet","project.json");if(!ct(o))throw new Error(`ToolNet project initialization failed: ${o} was not created`);return{initialized:!0,project:{id:t.id,name:t.name,remote:t.remote,rootPath:t.rootPath},manifestFile:o}}function bo(e,n){let t=e.indexOf(n);return t>=0?e[t+1]:void 0}async function So(){let e=process.argv.slice(2),n=e.includes("--json"),t=!e.includes("--no-integrate"),o=bo(e,"--project"),s=e.find((l,c)=>!l.startsWith("-")&&(c===0||e[c-1]!=="--project")),i=o??s??process.cwd(),r=await $("Initializing ToolNet project",()=>vo(i),{enabled:!n}),a=[];if(t&&(a=await $("Detecting AI coding agents",()=>G(),{enabled:!n})),n){console.log(JSON.stringify({...r,integrations:a},null,2));return}if(console.log(""),console.log("ToolNet Memory"),console.log("=============="),console.log(""),console.log("\u2713 Project initialized"),console.log(""),console.log(`Project: ${r.project.name}`),console.log(`ID: ${r.project.id}`),console.log(`Root: ${r.project.rootPath}`),console.log(`Manifest: ${r.manifestFile}`),console.log(""),t){console.log("AI integrations:");let l=a.filter(c=>c.detected&&c.installed);if(!l.length)console.log(" \u25CB No supported coding agent detected");else for(let c of l){let u=c.agent==="agy"?"Agy / Antigravity":c.agent==="opencode"?"OpenCode":"Codex";console.log(` \u2713 ${u}`)}console.log("")}console.log("Next: toolnet-memory doctor"),console.log("")}var Oo=process.argv[1]?.endsWith("/init.js")||process.argv[1]?.endsWith("/init.ts");Oo&&So().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exitCode=1});export{vo as initializeToolNetProject};
1059
+ `;return Ft(o,n.trimStart(),{encoding:"utf8",mode:384}),o}import{existsSync as Dt,mkdirSync as on,readFileSync as rn,renameSync as nn,writeFileSync as sn}from"node:fs";import{dirname as Ht,join as cn}from"node:path";function O(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function an(e,t){on(Ht(e),{recursive:!0});let o=`${e}.tmp-${process.pid}-${Date.now()}`;sn(o,`${JSON.stringify(t,null,2)}
1060
+ `,{encoding:"utf8",mode:384}),nn(o,e)}function _t(e){if(!Dt(e))return{};let t=rn(e,"utf8").trim();if(!t)return{};let o;try{o=JSON.parse(t)}catch(r){throw new Error(`Invalid existing OpenCode opencode.json: ${r instanceof Error?r.message:String(r)}`)}if(!O(o))throw new Error("Invalid existing OpenCode opencode.json: root must be a JSON object.");return o}function $t(e,t){if(!O(e))return!1;let o=e.command;return e.type==="local"&&e.enabled!==!1&&Array.isArray(o)&&o.length===2&&o[0]===t&&o[1]==="mcp"}function ln(e,t){let o=e.mcpServers;if(!O(o)||!Object.prototype.hasOwnProperty.call(o,t))return{root:e,changed:!1};let r={...o};return delete r[t],{root:{...e,mcpServers:r},changed:!0}}function Jt(e={}){let t=e.configFile??Qe(),o=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",r=e.serverName??"toolnet-memory",n=cn(Ht(t),"opencode.jsonc"),s=Dt(n)?n:void 0,i=_t(t),c=ln(i,r),a=c.root,l=a.mcp;if(l!==void 0&&!O(l))throw new Error("Invalid existing OpenCode config: mcp must be an object.");let u=O(l)?{...l}:{},p=u[r];if($t(p,o)&&!c.changed)return{installed:!0,changed:!1,configFile:t,serverName:r,command:[o,"mcp"],preservedJsonc:s};u[r]={type:"local",command:[o,"mcp"],enabled:!0};let d={...a,mcp:u};an(t,d);let C=_t(t);if(!O(C.mcp)||!$t(C.mcp[r],o))throw new Error("OpenCode MCP configuration was written but verification failed.");return{installed:!0,changed:!0,configFile:t,serverName:r,command:[o,"mcp"],preservedJsonc:s}}import{existsSync as un,mkdirSync as Lt,readFileSync as pn,writeFileSync as Gt}from"node:fs";import{homedir as Kt}from"node:os";import{dirname as Bt,join as Ce}from"node:path";function dn(e){let t=[],o=/"((?:\\.|[^"\\])*)"|'([^']*)'/g,r;for(;r=o.exec(e);){let n=r[1]??r[2]??"";try{t.push(r[1]!==void 0?JSON.parse(`"${n}"`):n)}catch{t.push(n)}}return t}function Ut(e={}){let t=e.configFile??Ce(process.env.CODEX_HOME??Ce(Kt(),".codex"),"config.toml"),o=e.previousFile??Ce(Kt(),".config","toolnet-memory","codex-notify-previous.json");Lt(Bt(t),{recursive:!0}),Lt(Bt(o),{recursive:!0});let r=un(t)?pn(t,"utf8"):"",n=e.binary??"toolnet-memory",s=`notify = [${JSON.stringify(n)}, "session:codex-notify"]`,i=r.split(`
1061
+ `),c=i.findIndex(d=>/^\s*\[/.test(d));c<0&&(c=i.length);let a=-1,l=-1;for(let d=0;d<c;d+=1)if(/^\s*notify\s*=/.test(i[d])){if(a=d,l=d,i[d].includes("[")&&!i[d].includes("]"))for(;l+1<c&&(l+=1,!i[l].includes("]")););break}let u=[];if(a>=0){let d=i.slice(a,l+1).join(`
1062
+ `);u=dn(d),i.splice(a,l-a+1,s)}else c=i.findIndex(d=>/^\s*\[/.test(d)),c<0&&(c=i.length),i.splice(c,0,s);let p=u.length>=2&&u[u.length-1]==="session:codex-notify";return u.length>0&&!p&&Gt(o,JSON.stringify(u,null,2)+`
1063
+ `,{encoding:"utf8",mode:384}),r=i.join(`
1064
+ `),r.endsWith(`
1065
+ `)||(r+=`
1066
+ `),Gt(t,r,{encoding:"utf8",mode:384}),{configFile:t,previousFile:o,preservedPrevious:u.length>0&&!p}}import{existsSync as gn,mkdirSync as fn,readFileSync as mn,writeFileSync as yn}from"node:fs";import{homedir as hn}from"node:os";import{dirname as kn,join as Yt}from"node:path";function bn(e){return`'${e.replace(/'/g,"'\\''")}'`}function Wt(e={}){let t=e.hooksFile??Yt(process.env.CODEX_HOME??Yt(hn(),".codex"),"hooks.json");fn(kn(t),{recursive:!0});let o={};if(gn(t))try{o=JSON.parse(mn(t,"utf8"))}catch(c){throw new Error(`Invalid existing Codex hooks.json: ${c instanceof Error?c.message:String(c)}`)}let r=o.hooks&&typeof o.hooks=="object"&&!Array.isArray(o.hooks)?o.hooks:{};o.hooks=r;let s=(Array.isArray(r.SessionStart)?r.SessionStart:[]).filter(c=>{try{return!JSON.stringify(c).includes("session:codex-context")}catch{return!0}}),i=e.binary??"toolnet-memory";return s.push({matcher:"startup|resume|clear|compact",hooks:[{type:"command",command:`${bn(i)} session:codex-context`,timeout:15,additionalContextLimit:1e3,statusMessage:"Loading ToolNet project continuity"}]}),r.SessionStart=s,yn(t,JSON.stringify(o,null,2)+`
1067
+ `,{encoding:"utf8",mode:384}),t}import{spawnSync as vn}from"node:child_process";function we(e,t){return vn(e,t,{encoding:"utf8",stdio:["ignore","pipe","pipe"]})}function zt(e,t){let o=we(e,["mcp","get",t,"--json"]);if(o.status!==0||!o.stdout)return null;try{return JSON.parse(o.stdout)}catch{return null}}function qt(e,t){return e.enabled!==!1&&e.transport?.type==="stdio"&&e.transport?.command===t&&Array.isArray(e.transport?.args)&&e.transport?.args.length===1&&e.transport.args[0]==="mcp"}function Vt(e={}){let t=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",o=e.codexBinary??"codex",r=e.serverName??"toolnet-memory",n=zt(o,r);if(n&&qt(n,t))return{installed:!0,changed:!1,serverName:r,command:t,args:["mcp"]};if(n){let c=we(o,["mcp","remove",r]);if(c.status!==0)return{installed:!1,changed:!1,serverName:r,command:t,args:["mcp"],error:(c.stderr||c.stdout||"Unable to remove old ToolNet MCP configuration.").trim()}}let s=we(o,["mcp","add",r,"--",t,"mcp"]);if(s.status!==0)return{installed:!1,changed:!1,serverName:r,command:t,args:["mcp"],error:(s.stderr||s.stdout||"Unable to register ToolNet MCP.").trim()};let i=zt(o,r);return!i||!qt(i,t)?{installed:!1,changed:!0,serverName:r,command:t,args:["mcp"],error:"Codex accepted MCP registration but verification did not match expected ToolNet command."}:{installed:!0,changed:!0,serverName:r,command:t,args:["mcp"]}}import{existsSync as Sn,mkdirSync as Cn,readFileSync as wn,renameSync as jn,rmSync as In,writeFileSync as On}from"node:fs";import{dirname as xn}from"node:path";function _(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Rn(e){return/^[A-Za-z0-9_./:-]+$/u.test(e)?e:`'${e.replace(/'/gu,"'\\''")}'`}function En(e){if(!Sn(e))return{};let t;try{t=JSON.parse(wn(e,"utf8"))}catch(o){throw new Error(`Invalid existing Claude settings.json: ${o instanceof Error?o.message:String(o)}`)}if(!_(t))throw new Error("Invalid existing Claude settings.json: root must be a JSON object.");return t}function je(e){if(e===void 0)return[];if(!Array.isArray(e))throw new Error("Invalid existing Claude settings.json: hook event must be an array.");let t=[];for(let o of e){if(!_(o)){t.push(o);continue}let r=o.hooks;if(!Array.isArray(r)){t.push(o);continue}let n=r.filter(s=>{if(!_(s))return!0;let i=s.command;return!(typeof i=="string"&&i.includes("session:claude-hook"))});n.length!==0&&t.push({...o,hooks:n})}return t}function Ie(e){return{type:"command",command:e,timeout:10}}function Mn(e,t){Cn(xn(e),{recursive:!0,mode:448});let o=`${e}.toolnet-${process.pid}-${Date.now()}.tmp`;try{On(o,JSON.stringify(t,null,2)+`
1068
+ `,{encoding:"utf8",mode:384}),jn(o,e)}finally{In(o,{force:!0})}}function Xt(e={}){let t=e.settingsFile??ot(),o=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",r=En(t),n=r.hooks;if(n!==void 0&&!_(n))throw new Error("Invalid existing Claude settings.json: hooks must be an object.");let s=_(n)?{...n}:{},i=`${Rn(o)} session:claude-hook`,c=je(s.SessionStart);c.push({matcher:"startup|resume|clear|compact",hooks:[Ie(i)]}),s.SessionStart=c;let a=je(s.PostToolUse);a.push({matcher:"Edit|Write",hooks:[Ie(i)]}),s.PostToolUse=a;let l=je(s.Stop);l.push({hooks:[Ie(i)]}),s.Stop=l;let u={...r,hooks:s},p=JSON.stringify(r),d=JSON.stringify(u);return p===d?{settingsFile:t,changed:!1}:(Mn(t,u),{settingsFile:t,changed:!0})}import{existsSync as Tn,mkdirSync as An,readFileSync as Pn,renameSync as Fn,rmSync as Nn,writeFileSync as _n}from"node:fs";import{dirname as $n}from"node:path";function $(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Qt(e){if(!Tn(e))return{};let t;try{t=JSON.parse(Pn(e,"utf8"))}catch(o){throw new Error(`Invalid existing Claude Code config: ${o instanceof Error?o.message:String(o)}`)}if(!$(t))throw new Error("Invalid existing Claude Code config: root must be a JSON object.");return t}function Zt(e,t){if(!$(e))return!1;let o=e.args;return e.type==="stdio"&&e.command===t&&Array.isArray(o)&&o.length===1&&o[0]==="mcp"}function Dn(e,t){An($n(e),{recursive:!0});let o=`${e}.toolnet-${process.pid}-${Date.now()}.tmp`;try{_n(o,JSON.stringify(t,null,2)+`
1069
+ `,{encoding:"utf8",mode:384}),Fn(o,e)}finally{Nn(o,{force:!0})}}function eo(e={}){let t=e.stateFile??rt(),o=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",r=e.serverName??"toolnet-memory",n=Qt(t),s=n.mcpServers;if(s!==void 0&&!$(s))throw new Error("Invalid existing Claude Code config: mcpServers must be an object.");let i=$(s)?{...s}:{},c=i[r];if(Zt(c,o))return{installed:!0,changed:!1,configFile:t,serverName:r,command:[o,"mcp"],repaired:!1};let a=c!==void 0;i[r]={type:"stdio",command:o,args:["mcp"]},Dn(t,{...n,mcpServers:i});let u=Qt(t).mcpServers;if(!$(u)||!Zt(u[r],o))throw new Error("Claude Code MCP configuration was written but verification failed.");return{installed:!0,changed:!0,configFile:t,serverName:r,command:[o,"mcp"],repaired:a}}function to(e={}){let t=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",o=Xt({binary:t,settingsFile:e.settingsFile}),r=eo({binary:t,stateFile:e.stateFile});return{hooks:o,mcp:r,files:[o.settingsFile,r.configFile]}}import{existsSync as Hn,mkdirSync as Jn,readFileSync as Ln,renameSync as Gn,rmSync as Kn,writeFileSync as Bn}from"node:fs";import{dirname as Un}from"node:path";var x="ToolNet Memory - ";function no(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Yn(e){return/^[A-Za-z0-9_./:-]+$/u.test(e)?e:`'${e.replace(/'/gu,"'\\''")}'`}function oo(e){if(!Hn(e))return{};let t=Ln(e,"utf8").trim();if(!t)return{};let o;try{o=JSON.parse(t)}catch(r){throw new Error(`Invalid existing Kiro hooks file: ${r instanceof Error?r.message:String(r)}`)}if(!no(o))throw new Error("Invalid existing Kiro hooks file: root must be a JSON object.");return o}function ro(e){return no(e)?typeof e.name=="string"&&e.name.startsWith(x):!1}function D(e){return{type:"command",command:e}}function Wn(e){return[{name:`${x}Session Start`,description:"Inject compact local ToolNet continuity and capture Kiro session activation.",trigger:"SessionStart",action:D(e),timeout:10,enabled:!0},{name:`${x}Prompt Continuity`,description:"Capture prompts and refresh ToolNet guidance only for resume/continue requests.",trigger:"UserPromptSubmit",action:D(e),timeout:10,enabled:!0},{name:`${x}Raw History Guard`,description:"Prevent Kiro from reconstructing continuity from raw ToolNet/agent session history.",trigger:"PreToolUse",matcher:"*",action:D(e),timeout:10,enabled:!0},{name:`${x}Tool Capture`,description:"Capture durable tool activity while filtering noisy read-only events.",trigger:"PostToolUse",matcher:"*",action:D(e),timeout:15,enabled:!0},{name:`${x}Final Flush`,description:"Flush pending Kiro WAL events when the assistant finishes a turn.",trigger:"Stop",action:D(e),timeout:30,enabled:!0}]}function zn(e,t){Jn(Un(e),{recursive:!0,mode:448});let o=`${e}.toolnet-${process.pid}-${Date.now()}.tmp`;try{Bn(o,JSON.stringify(t,null,2)+`
1070
+ `,{encoding:"utf8",mode:384}),Gn(o,e)}finally{Kn(o,{force:!0})}}function io(e={}){let t=e.hooksFile??it(),o=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",r=oo(t);if(r.version!==void 0&&r.version!=="v1")throw new Error(`Unsupported existing Kiro hooks version: ${String(r.version)}`);let n=r.hooks;if(n!==void 0&&!Array.isArray(n))throw new Error("Invalid existing Kiro hooks file: hooks must be an array.");let s=Array.isArray(n)?n.filter(u=>!ro(u)):[],i=`${Yn(o)} session:kiro-hook`,c=Wn(i),a={...r,version:"v1",hooks:[...s,...c]};if(JSON.stringify(r)===JSON.stringify(a))return{hooksFile:t,changed:!1,hookCount:c.length};zn(t,a);let l=oo(t);if(l.version!=="v1"||!Array.isArray(l.hooks)||l.hooks.filter(ro).length!==c.length)throw new Error("Kiro hooks were written but verification failed.");return{hooksFile:t,changed:!0,hookCount:c.length}}import{existsSync as qn,mkdirSync as Vn,readFileSync as Xn,renameSync as Qn,rmSync as Zn,writeFileSync as ei}from"node:fs";import{dirname as ti}from"node:path";function H(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function so(e){if(!qn(e))return{};let t=Xn(e,"utf8").trim();if(!t)return{};let o;try{o=JSON.parse(t)}catch(r){throw new Error(`Invalid existing Kiro MCP config: ${r instanceof Error?r.message:String(r)}`)}if(!H(o))throw new Error("Invalid existing Kiro MCP config: root must be a JSON object.");return o}function co(e,t){return H(e)?e.command===t&&Array.isArray(e.args)&&e.args.length===1&&e.args[0]==="mcp"&&e.disabled===!1:!1}function oi(e,t){Vn(ti(e),{recursive:!0,mode:448});let o=`${e}.tmp-${process.pid}-${Date.now()}`;try{ei(o,`${JSON.stringify(t,null,2)}
1071
+ `,{encoding:"utf8",mode:384}),Qn(o,e)}finally{Zn(o,{force:!0})}}function ao(e={}){let t=e.configFile??nt(),o=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",r=e.serverName??"toolnet-memory",n=so(t),s=n.mcpServers;if(s!==void 0&&!H(s))throw new Error("Invalid existing Kiro MCP config: mcpServers must be an object.");let i=H(s)?{...s}:{},c=i[r];if(co(c,o))return{installed:!0,changed:!1,configFile:t,serverName:r,command:o,args:["mcp"]};i[r]={command:o,args:["mcp"],disabled:!1};let a={...n,mcpServers:i};oi(t,a);let u=so(t).mcpServers;if(!H(u)||!co(u[r],o))throw new Error("Kiro MCP configuration was written but verification failed.");return{installed:!0,changed:!0,configFile:t,serverName:r,command:o,args:["mcp"]}}function lo(e={}){let t=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",o=ao({binary:t,configFile:e.configFile}),r=io({binary:t,hooksFile:e.hooksFile});return{installed:o.installed,changed:o.changed||r.changed,mcp:o,hooks:r,files:[o.configFile,r.hooksFile]}}import{existsSync as ri,mkdirSync as ni,readFileSync as ii,renameSync as si,rmSync as ci,writeFileSync as ai}from"node:fs";import{dirname as li}from"node:path";function g(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function b(e,t){if(!ri(e))return{};let o=ii(e,"utf8").trim();if(!o)return{};let r;try{r=JSON.parse(o)}catch(n){throw new Error(`Invalid existing ${t} hooks file: ${n instanceof Error?n.message:String(n)}`)}if(!g(r))throw new Error(`Invalid existing ${t} hooks file: root must be a JSON object.`);return r}function R(e,t){ni(li(e),{recursive:!0,mode:448});let o=`${e}.toolnet-${process.pid}-${Date.now()}.tmp`;try{ai(o,`${JSON.stringify(t,null,2)}
1072
+ `,{encoding:"utf8",mode:384}),si(o,e)}finally{ci(o,{force:!0})}}function Oe(e){return/^[A-Za-z0-9_./:-]+$/u.test(e)?e:`'${e.replace(/'/gu,"'\\''")}'`}var J=[["sessionStart",10],["beforeSubmitPrompt",10],["preToolUse",10],["postToolUse",15],["afterAgentResponse",15],["stop",30]];function uo(e){return g(e)&&typeof e.command=="string"&&e.command.includes("session:cursor-hook")}function ui(e,t,o){let n={type:"command",command:`TOOLNET_HOOK_EVENT=${Oe(e)} ${Oe(t)} session:cursor-hook`,timeout:o};return e==="preToolUse"&&(n.matcher=".*"),n}function xe(e={}){let t=e.hooksFile??V(),o=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",r=b(t,"Cursor");if(r.version!==void 0&&r.version!==1)throw new Error(`Unsupported existing Cursor hooks version: ${String(r.version)}`);let n=r.hooks;if(n!==void 0&&!g(n))throw new Error("Invalid existing Cursor hooks file: hooks must be an object.");let s=g(n)?{...n}:{};for(let[l,u]of J){let p=s[l];if(p!==void 0&&!Array.isArray(p))throw new Error(`Invalid existing Cursor hooks file: hooks.${l} must be an array.`);let d=Array.isArray(p)?p.filter(C=>!uo(C)):[];s[l]=[...d,ui(l,o,u)]}let i={...r,version:1,hooks:s};if(JSON.stringify(r)===JSON.stringify(i))return{hooksFile:t,changed:!1,hookCount:J.length};R(t,i);let c=b(t,"Cursor");if(c.version!==1||!g(c.hooks))throw new Error("Cursor hooks were written but verification failed.");let a=0;for(let[l]of J){let u=c.hooks[l];if(!Array.isArray(u))throw new Error("Cursor hooks were written but verification failed.");a+=u.filter(uo).length}if(a!==J.length)throw new Error("Cursor hooks were written but verification failed.");return{hooksFile:t,changed:!0,hookCount:J.length}}import{existsSync as pi,mkdirSync as di,readFileSync as gi,renameSync as fi,rmSync as mi,writeFileSync as yi}from"node:fs";import{dirname as hi}from"node:path";function y(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function E(e,t){if(!pi(e))return{};let o=gi(e,"utf8").trim();if(!o)return{};let r;try{r=JSON.parse(o)}catch(n){throw new Error(`Invalid existing ${t} MCP config: ${n instanceof Error?n.message:String(n)}`)}if(!y(r))throw new Error(`Invalid existing ${t} MCP config: root must be a JSON object.`);return r}function ie(e,t){di(hi(e),{recursive:!0,mode:448});let o=`${e}.tmp-${process.pid}-${Date.now()}`;try{yi(o,`${JSON.stringify(t,null,2)}
1073
+ `,{encoding:"utf8",mode:384}),fi(o,e)}finally{mi(o,{force:!0})}}function po(e,t){return y(e)?(e.type===void 0||e.type==="stdio")&&e.command===t&&Array.isArray(e.args)&&e.args.length===1&&e.args[0]==="mcp":!1}function Re(e={}){let t=e.configFile??q(),o=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",r=e.serverName??"toolnet-memory",n=E(t,"Cursor"),s=n.mcpServers;if(s!==void 0&&!y(s))throw new Error("Invalid existing Cursor MCP config: mcpServers must be an object.");let i=y(s)?{...s}:{};if(po(i[r],o))return{installed:!0,changed:!1,configFile:t,serverName:r,command:o,args:["mcp"]};i[r]={type:"stdio",command:o,args:["mcp"]},ie(t,{...n,mcpServers:i});let a=E(t,"Cursor").mcpServers;if(!y(a)||!po(a[r],o))throw new Error("Cursor MCP configuration was written but verification failed.");return{installed:!0,changed:!0,configFile:t,serverName:r,command:o,args:["mcp"]}}import{mkdirSync as ki,readFileSync as go,renameSync as bi,rmSync as vi,writeFileSync as Si}from"node:fs";import{dirname as Ci}from"node:path";var Ee=`---
1074
+ description: ToolNet Memory project continuity and safety rules
1075
+ alwaysApply: true
1076
+ ---
1077
+
1078
+ # ToolNet Memory
1079
+
1080
+ Use ToolNet Memory as the continuity source for this project.
1081
+
1082
+ - When the user asks to continue, resume, pick up, finish unfinished work,
1083
+ or asks where work stopped, use ToolNet continuity before reconstructing
1084
+ context from old chat/session history.
1085
+ - Use the ToolNet MCP server and \`memory_agent_ask\` when fast project context
1086
+ is missing, stale, or ambiguous.
1087
+ - Prefer \`mode="local"\` for current task, current file, blockers, TODOs,
1088
+ completed work, and next action.
1089
+ - Use \`mode="ai"\` only when synthesis is actually required.
1090
+ - Do not reconstruct continuity by reading:
1091
+ - \`.toolnet/sessions/**\`
1092
+ - ToolNet raw \`events.jsonl\`
1093
+ - ToolNet raw \`state.json\`
1094
+ - another coding agent's private transcript/history files.
1095
+ - After continuity is recovered, verify current repository source and git
1096
+ state before changing code.
1097
+ - Do not ask the user to repeat project context that ToolNet already provides.
1098
+
1099
+ Current repository evidence overrides stale memory.
1100
+ `;function wi(e,t){ki(Ci(e),{recursive:!0,mode:448});let o=`${e}.toolnet-${process.pid}-${Date.now()}.tmp`;try{Si(o,t,{encoding:"utf8",mode:384}),bi(o,e)}finally{vi(o,{force:!0})}}function fo(e){let t=e.ruleFile??lt(e.projectRoot);try{if(go(t,"utf8")===Ee)return{ruleFile:t,changed:!1}}catch{}if(wi(t,Ee),go(t,"utf8")!==Ee)throw new Error("Cursor ToolNet project rule was written but verification failed.");return{ruleFile:t,changed:!0}}import{spawnSync as ji}from"node:child_process";import{existsSync as M,statSync as Ii}from"node:fs";import{dirname as Oi,join as xi,parse as Ri,resolve as Te}from"node:path";function mo(e){let t=Te(e);if(!M(t))throw new Error(`Project path does not exist: ${t}`);if(!Ii(t).isDirectory())throw new Error(`Project path is not a directory: ${t}`);return t}function se(e){return xi(e,".toolnet","project.json")}function Ei(e){let t=Te(e),o=Ri(t).root;for(;;){if(M(se(t)))return t;if(t===o)return;let r=Oi(t);if(r===t)return;t=r}}function Me(e){let t=ji("git",["rev-parse","--show-toplevel"],{cwd:e,encoding:"utf8",timeout:5e3});if(t.status!==0)return;let o=t.stdout.trim();return o?Te(o):void 0}function v(e={}){let t=mo(e.cwd??process.cwd());if(e.project){let n=mo(e.project),s=se(n),i=Me(n);return{root:n,source:"explicit",eligible:!0,toolnetProject:M(s),manifestFile:M(s)?s:void 0,gitRoot:i}}let o=Ei(t);if(o){let n=se(o);return{root:o,source:"toolnet",eligible:!0,toolnetProject:!0,manifestFile:n,gitRoot:Me(o)}}let r=Me(t);if(r){let n=se(r);return{root:r,source:"git",eligible:!0,toolnetProject:M(n),manifestFile:M(n)?n:void 0,gitRoot:r}}return{root:t,source:"cwd",eligible:!1,toolnetProject:!1}}function bo(e,t={}){let o=[],r=e.indexOf("--scope");if(r>=0){let s=e[r+1];if(s!=="global"&&s!=="project"&&s!=="both")throw new Error(`Invalid --scope value: ${String(s)}`);o.push(s)}e.includes("--global")&&o.push("global"),e.includes("--both")&&o.push("both");let n=Array.from(new Set(o));if(n.length>1)throw new Error(`Conflicting integration scopes: ${n.join(", ")}`);return n[0]??t.defaultScope??"global"}function yo(e,t){return{install:e,effective:t}}function S(e,t){return{surface:e,global:yo(t.globalInstall,t.effective==="global"||t.effective==="both"),project:yo(t.projectInstall,t.effective==="project"||t.effective==="both"),effective:t.effective,risk:t.risk??"none",dedupeRequired:t.dedupeRequired??!1,trustRequired:t.trustRequired??t.projectInstall,note:t.note}}function Mi(e){return{mcp:S("mcp",{globalInstall:!0,projectInstall:!1,effective:"global"}),hooks:S("hooks",{globalInstall:!0,projectInstall:!1,effective:"global"}),work:S("work",{globalInstall:e==="grok",projectInstall:!1,effective:e==="grok"?"global":"none",note:e==="grok"?"Grok supports a global ToolNet continuity skill.":"Cursor/Copilot work instructions remain project-scoped."})}}function ho(e){return{mcp:S("mcp",{globalInstall:!1,projectInstall:!0,effective:"project",trustRequired:!0}),hooks:S("hooks",{globalInstall:!1,projectInstall:!0,effective:"project",trustRequired:!0}),work:S("work",{globalInstall:!1,projectInstall:!0,effective:"project",trustRequired:!1,note:e==="cursor"?"Use .cursor/rules/toolnet-memory.mdc.":e==="copilot"?"Use .github/instructions/toolnet-memory.instructions.md.":"Use .grok/skills/toolnet-continuity/SKILL.md."})}}function ko(e){return{mcp:S("mcp",{globalInstall:!0,projectInstall:!0,effective:"project",risk:e==="cursor"?"precedence-unverified":"shadowed-global",trustRequired:!0,note:e==="cursor"?"Project ToolNet MCP is the intended effective definition; native same-name precedence must be E2E certified before release.":"Global remains useful outside the project; same-name project definition wins inside the project."}),hooks:S("hooks",{globalInstall:!0,projectInstall:!0,effective:"both",risk:"additive-duplicate",dedupeRequired:!0,trustRequired:!0,note:"Global and project hook sources can both execute for the same native event."}),work:S("work",{globalInstall:e==="grok",projectInstall:!0,effective:"project",risk:e==="grok"?"shadowed-global":"none",trustRequired:!1,note:e==="cursor"?"Project rule is authoritative.":e==="copilot"?"Project instruction is authoritative.":"Project skill shadows the same-name global skill inside the project."})}}function T(e){let{agent:t,scope:o,project:r}=e;return(o==="project"||o==="both")&&(!r||!r.eligible)?{agent:t,requestedScope:o,project:r,surfaces:o==="both"?ko(t):ho(t),canInstall:!1,reason:"Project scope requires an explicit project, existing ToolNet project, or Git repository root."}:{agent:t,requestedScope:o,project:r,surfaces:o==="global"?Mi(t):o==="project"?ho(t):ko(t),canInstall:!0}}function vo(e){return!!(e?.mcp?.changed||e?.hooks?.changed||e?.rule?.changed)}function So(e={}){let t=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",o=e.scope??"global",r=o==="global"?void 0:v({project:e.projectRoot}),n=T({agent:"cursor",scope:o,project:r});if(!n.canInstall)throw new Error(n.reason??"Cursor project integration scope cannot be resolved.");let s,i;if((n.surfaces.mcp.global.install||n.surfaces.hooks.global.install||n.surfaces.work.global.install)&&(s={},n.surfaces.mcp.global.install&&(s.mcp=Re({binary:t,configFile:e.configFile??q()})),n.surfaces.hooks.global.install&&(s.hooks=xe({binary:t,hooksFile:e.hooksFile??V()}))),n.surfaces.mcp.project.install||n.surfaces.hooks.project.install||n.surfaces.work.project.install){if(!r?.eligible)throw new Error("Cursor project integration requires an eligible project root.");i={},n.surfaces.mcp.project.install&&(i.mcp=Re({binary:t,configFile:e.projectConfigFile??ct(r.root)})),n.surfaces.hooks.project.install&&(i.hooks=xe({binary:t,hooksFile:e.projectHooksFile??at(r.root)})),n.surfaces.work.project.install&&(i.rule=fo({projectRoot:r.root,ruleFile:e.projectRuleFile}))}let c=i?.mcp??s?.mcp,a=i?.hooks??s?.hooks;if(!c||!a)throw new Error("Cursor integration did not produce an effective MCP/hooks installation.");let l=Array.from(new Set([s?.mcp?.configFile,s?.hooks?.hooksFile,s?.rule?.ruleFile,i?.mcp?.configFile,i?.hooks?.hooksFile,i?.rule?.ruleFile].filter(u=>typeof u=="string")));return{installed:!0,changed:vo(s)||vo(i),scope:o,plan:n,project:r,global:s,projectScope:i,mcp:c,hooks:a,rule:i?.rule,files:l}}var L=[["sessionStart",10],["userPromptSubmitted",10],["userPromptTransformed",10],["preToolUse",10],["postToolUse",15],["agentStop",30]];function Ti(e){if(typeof e.command=="string")return e.command;if(typeof e.bash=="string")return e.bash}function Co(e){return g(e)&&Ti(e)?.includes("session:copilot-hook")===!0}function Ai(e,t,o){let r={type:"command",command:`${t} session:copilot-hook`,env:{TOOLNET_HOOK_EVENT:e},timeoutSec:o};return e==="preToolUse"&&(r.matcher=".*"),r}function Ae(e={}){let t=e.hooksFile??Q(),o=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",r=b(t,"GitHub Copilot CLI");if(r.version!==void 0&&r.version!==1)throw new Error(`Unsupported existing GitHub Copilot CLI hooks version: ${String(r.version)}`);let n=r.hooks;if(n!==void 0&&!g(n))throw new Error("Invalid existing GitHub Copilot CLI hooks file: hooks must be an object.");let s=g(n)?{...n}:{};for(let[l,u]of L){let p=s[l];if(p!==void 0&&!Array.isArray(p))throw new Error(`Invalid existing GitHub Copilot CLI hooks file: hooks.${l} must be an array.`);let d=Array.isArray(p)?p.filter(C=>!Co(C)):[];s[l]=[...d,Ai(l,o,u)]}let i={...r,version:1,hooks:s};if(JSON.stringify(r)===JSON.stringify(i))return{hooksFile:t,changed:!1,hookCount:L.length};R(t,i);let c=b(t,"GitHub Copilot CLI");if(c.version!==1||!g(c.hooks))throw new Error("GitHub Copilot CLI hooks were written but verification failed.");let a=0;for(let[l]of L){let u=c.hooks[l];if(!Array.isArray(u))throw new Error("GitHub Copilot CLI hooks were written but verification failed.");a+=u.filter(Co).length}if(a!==L.length)throw new Error("GitHub Copilot CLI hooks were written but verification failed.");return{hooksFile:t,changed:!0,hookCount:L.length}}function wo(e,t){return y(e)?(e.type===void 0||e.type==="local"||e.type==="stdio")&&e.command===t&&Array.isArray(e.args)&&e.args.length===1&&e.args[0]==="mcp"&&Array.isArray(e.tools)&&e.tools.length===1&&e.tools[0]==="*":!1}function Pe(e={}){let t=e.configFile??X(),o=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",r=e.serverName??"toolnet-memory",n=E(t,"GitHub Copilot CLI"),s=n.mcpServers;if(s!==void 0&&!y(s))throw new Error("Invalid existing GitHub Copilot CLI MCP config: mcpServers must be an object.");let i=y(s)?{...s}:{};if(wo(i[r],o))return{installed:!0,changed:!1,configFile:t,serverName:r,command:o,args:["mcp"]};i[r]={type:"stdio",command:o,args:["mcp"],tools:["*"]},ie(t,{...n,mcpServers:i});let a=E(t,"GitHub Copilot CLI").mcpServers;if(!y(a)||!wo(a[r],o))throw new Error("GitHub Copilot CLI MCP configuration was written but verification failed.");return{installed:!0,changed:!0,configFile:t,serverName:r,command:o,args:["mcp"]}}import{mkdirSync as Pi,readFileSync as jo,renameSync as Fi,rmSync as Ni,writeFileSync as _i}from"node:fs";import{dirname as $i}from"node:path";var Fe=`---
1101
+ applyTo: "**"
1102
+ ---
1103
+
1104
+ # ToolNet Memory project continuity
1105
+
1106
+ Use ToolNet Memory as the continuity source for this repository.
1107
+
1108
+ - When the user asks to continue, resume, pick up, finish unfinished work,
1109
+ or asks where work stopped, recover ToolNet continuity before reconstructing
1110
+ state from chat/session history.
1111
+ - Use the ToolNet MCP server and \`memory_agent_ask\` when fast project context
1112
+ is missing, stale, or ambiguous.
1113
+ - Prefer \`mode="local"\` for current task, current file, blockers, TODOs,
1114
+ completed work, and next action.
1115
+ - Use \`mode="ai"\` only when continuity needs synthesis.
1116
+ - Do not reconstruct continuity by reading:
1117
+ - \`.toolnet/sessions/**\`
1118
+ - ToolNet raw \`events.jsonl\`
1119
+ - ToolNet raw \`state.json\`
1120
+ - another coding agent's private transcript/history files.
1121
+ - After continuity is recovered, verify current repository source and git
1122
+ state before changing code.
1123
+ - Do not ask the user to repeat context ToolNet already provides.
1124
+
1125
+ Current repository evidence overrides stale memory.
1126
+ `;function Di(e,t){Pi($i(e),{recursive:!0,mode:448});let o=`${e}.toolnet-${process.pid}-${Date.now()}.tmp`;try{_i(o,t,{encoding:"utf8",mode:384}),Fi(o,e)}finally{Ni(o,{force:!0})}}function Io(e){let t=e.instructionFile??gt(e.projectRoot);try{if(jo(t,"utf8")===Fe)return{instructionFile:t,changed:!1}}catch{}if(Di(t,Fe),jo(t,"utf8")!==Fe)throw new Error("Copilot ToolNet project instruction verification failed.");return{instructionFile:t,changed:!0}}function Oo(e){return!!(e?.mcp?.changed||e?.hooks?.changed||e?.instruction?.changed)}function xo(e={}){let t=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",o=e.scope??"global",r=o==="global"?void 0:v({project:e.projectRoot}),n=T({agent:"copilot",scope:o,project:r});if(!n.canInstall)throw new Error(n.reason??"Copilot project integration scope cannot be resolved.");let s,i;if((n.surfaces.mcp.global.install||n.surfaces.hooks.global.install||n.surfaces.work.global.install)&&(s={},n.surfaces.mcp.global.install&&(s.mcp=Pe({binary:t,configFile:e.configFile??X()})),n.surfaces.hooks.global.install&&(s.hooks=Ae({binary:t,hooksFile:e.hooksFile??Q()}))),n.surfaces.mcp.project.install||n.surfaces.hooks.project.install||n.surfaces.work.project.install){if(!r?.eligible)throw new Error("Copilot project integration requires an eligible project root.");i={},n.surfaces.mcp.project.install&&(i.mcp=Pe({binary:t,configFile:e.projectConfigFile??pt(r.root)})),n.surfaces.hooks.project.install&&(i.hooks=Ae({binary:t,hooksFile:e.projectHooksFile??dt(r.root)})),n.surfaces.work.project.install&&(i.instruction=Io({projectRoot:r.root,instructionFile:e.projectInstructionFile}))}let c=i?.mcp??s?.mcp,a=i?.hooks??s?.hooks;if(!c||!a)throw new Error("Copilot integration did not produce effective MCP/hooks.");let l=Array.from(new Set([s?.mcp?.configFile,s?.hooks?.hooksFile,s?.instruction?.instructionFile,i?.mcp?.configFile,i?.hooks?.hooksFile,i?.instruction?.instructionFile].filter(u=>typeof u=="string")));return{installed:!0,changed:Oo(s)||Oo(i),scope:o,plan:n,project:r,global:s,projectScope:i,mcp:c,hooks:a,instruction:i?.instruction,files:l}}import{existsSync as Hi,mkdirSync as Ji,readFileSync as Ro,renameSync as Li,rmSync as Gi,writeFileSync as Ki}from"node:fs";import{dirname as Bi}from"node:path";var Ne=`---
1127
+ name: toolnet-continuity
1128
+ description: Restore previous ToolNet project work when the user asks to continue, resume, pick up, finish unfinished work, or asks where work stopped.
1129
+ when-to-use: continue, resume, pick up, carry on, ti\u1EBFp t\u1EE5c, l\xE0m ti\u1EBFp, l\xE0m n\u1ED1t, \u0111ang l\xE0m \u0111\u1EBFn \u0111\xE2u, d\u1EEBng \u1EDF \u0111\xE2u
1130
+ ---
1131
+
1132
+ # ToolNet Continuity
1133
+
1134
+ When the user asks to continue or resume previous work:
1135
+
1136
+ 1. Use the ToolNet Memory MCP server as the continuity source.
1137
+ 2. Invoke \`memory_agent_ask\` before exploring old history if the current
1138
+ ToolNet handoff is missing, stale, or ambiguous.
1139
+ 3. Prefer \`mode="local"\` for current task, last file, blocker, completed
1140
+ work, TODOs, and next action.
1141
+ 4. Use \`mode="ai"\` only when continuity requires synthesis.
1142
+ 5. Do not reconstruct previous work from:
1143
+ - \`.toolnet/sessions/**\`
1144
+ - ToolNet \`events.jsonl\` or \`state.json\`
1145
+ - raw transcripts
1146
+ - another coding agent's private session/history files
1147
+ 6. After ToolNet continuity is known, verify current git and repository
1148
+ source truth before changing code.
1149
+ 7. Do not ask the user to repeat context ToolNet already provides.
1150
+
1151
+ Current repository evidence overrides stale memory.
1152
+ `;function Ui(e,t){Ji(Bi(e),{recursive:!0,mode:448});let o=`${e}.toolnet-${process.pid}-${Date.now()}.tmp`;try{Ki(o,t,{encoding:"utf8",mode:384}),Li(o,e)}finally{Gi(o,{force:!0})}}function _e(e={}){let t=e.skillFile??oe();if(Hi(t)&&Ro(t,"utf8")===Ne)return{skillFile:t,changed:!1};if(Ui(t,Ne),Ro(t,"utf8")!==Ne)throw new Error("Grok ToolNet continuity skill was written but verification failed.");return{skillFile:t,changed:!0}}var G=[["SessionStart",10],["UserPromptSubmit",10],["PreToolUse",10],["PostToolUse",15],["Stop",30]];function Eo(e){return!g(e)||!Array.isArray(e.hooks)?!1:e.hooks.some(t=>g(t)&&typeof t.command=="string"&&t.command.includes("session:grok-hook"))}function Yi(e,t,o){let r={hooks:[{type:"command",command:`${t} session:grok-hook`,timeout:o,env:{TOOLNET_HOOK_EVENT:e}}]};return e==="PreToolUse"&&(r.matcher=".*"),r}function $e(e={}){let t=e.hooksFile??te(),o=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",r=b(t,"Grok Build"),n=r.hooks;if(n!==void 0&&!g(n))throw new Error("Invalid existing Grok Build hooks file: hooks must be an object.");let s=g(n)?{...n}:{};for(let[l,u]of G){let p=s[l];if(p!==void 0&&!Array.isArray(p))throw new Error(`Invalid existing Grok Build hooks file: hooks.${l} must be an array.`);let d=Array.isArray(p)?p.filter(C=>!Eo(C)):[];s[l]=[...d,Yi(l,o,u)]}let i={...r,hooks:s};if(JSON.stringify(r)===JSON.stringify(i))return{hooksFile:t,changed:!1,hookCount:G.length};R(t,i);let c=b(t,"Grok Build");if(!g(c.hooks))throw new Error("Grok Build hooks were written but verification failed.");let a=0;for(let[l]of G){let u=c.hooks[l];if(!Array.isArray(u))throw new Error("Grok Build hooks were written but verification failed.");a+=u.filter(Eo).length}if(a!==G.length)throw new Error("Grok Build hooks were written but verification failed.");return{hooksFile:t,changed:!0,hookCount:G.length}}import{existsSync as Wi,mkdirSync as zi,readFileSync as qi,renameSync as Vi,rmSync as Xi,writeFileSync as Qi}from"node:fs";import{dirname as Zi}from"node:path";function Mo(e){return Wi(e)?qi(e,"utf8"):""}function es(e,t){zi(Zi(e),{recursive:!0,mode:448});let o=`${e}.tmp-${process.pid}-${Date.now()}`;try{Qi(o,t,{encoding:"utf8",mode:384}),Vi(o,e)}finally{Xi(o,{force:!0})}}function De(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t")}function ts(e){return`[mcp_servers."${De(e)}"]`}function os(e,t){return[ts(e),`command = "${De(t)}"`,'args = ["mcp"]',"enabled = true"].join(`
1153
+ `)}function rs(e){let t=e.trim();return t.startsWith("[")&&t.includes("]")}function ce(e){return e.trim().replace(/\s+/g,"")}function ns(e){return new Set([ce(`[mcp_servers.${e}]`),ce(`[mcp_servers."${e}"]`),ce(`[mcp_servers.'${e}']`)])}function Ao(e,t){let o=e.split(/\r?\n/),r=ns(t),n=-1;for(let u=0;u<o.length;u+=1){let p=ce(o[u].replace(/\s+#.*$/,""));if(r.has(p)){n=u;break}}if(n<0)return null;let s=o.length;for(let u=n+1;u<o.length;u+=1)if(rs(o[u])){s=u;break}let i=[],c=0;for(let u of o)i.push(c),c+=u.length+1;let a=i[n]??0,l=s>=o.length?e.length:i[s]??e.length;return{start:a,end:l}}function is(e,t,o){let r=`${os(t,o)}
1154
+ `,n=Ao(e,t);if(n){let s=e.slice(0,n.start),i=e.slice(n.end);return`${s}${r}${i.replace(/^\n+/,"")}`}return e.trim()?`${e.replace(/\s*$/,"")}
1155
+
1156
+ ${r}`:r}function To(e,t,o){let r=Ao(e,t);if(!r)return!1;let n=e.slice(r.start,r.end);return n.includes(`command = "${De(o)}"`)&&/args\s*=\s*\[\s*"mcp"\s*\]/.test(n)&&/enabled\s*=\s*true/.test(n)}function He(e={}){let t=e.configFile??ee(),o=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",r=e.serverName??"toolnet-memory",n=Mo(t);if(To(n,r,o))return{installed:!0,changed:!1,configFile:t,serverName:r,command:o,args:["mcp"]};let s=is(n,r,o);es(t,s);let i=Mo(t);if(!To(i,r,o))throw new Error("Grok Build MCP configuration was written but verification failed.");return{installed:!0,changed:!0,configFile:t,serverName:r,command:o,args:["mcp"]}}function Po(e){return!!(e?.mcp?.changed||e?.hooks?.changed||e?.skill?.changed)}function Fo(e={}){let t=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",o=e.scope??"global",r=o==="global"?void 0:v({project:e.projectRoot}),n=T({agent:"grok",scope:o,project:r});if(!n.canInstall)throw new Error(n.reason??"Grok project integration scope cannot be resolved.");let s,i;if((n.surfaces.mcp.global.install||n.surfaces.hooks.global.install||n.surfaces.work.global.install)&&(s={},n.surfaces.mcp.global.install&&(s.mcp=He({binary:t,configFile:e.configFile??ee()})),n.surfaces.hooks.global.install&&(s.hooks=$e({binary:t,hooksFile:e.hooksFile??te()})),n.surfaces.work.global.install&&(s.skill=_e({skillFile:e.skillFile??oe()}))),n.surfaces.mcp.project.install||n.surfaces.hooks.project.install||n.surfaces.work.project.install){if(!r?.eligible)throw new Error("Grok project integration requires an eligible project root.");i={},n.surfaces.mcp.project.install&&(i.mcp=He({binary:t,configFile:e.projectConfigFile??mt(r.root)})),n.surfaces.hooks.project.install&&(i.hooks=$e({binary:t,hooksFile:e.projectHooksFile??yt(r.root)})),n.surfaces.work.project.install&&(i.skill=_e({skillFile:e.projectSkillFile??ht(r.root)}))}let c=i?.mcp??s?.mcp,a=i?.hooks??s?.hooks,l=i?.skill??s?.skill;if(!c||!a||!l)throw new Error("Grok integration did not produce effective MCP/hooks/skill.");let u=Array.from(new Set([s?.mcp?.configFile,s?.hooks?.hooksFile,s?.skill?.skillFile,i?.mcp?.configFile,i?.hooks?.hooksFile,i?.skill?.skillFile].filter(p=>typeof p=="string")));return{installed:!0,changed:Po(s)||Po(i),scope:o,plan:n,project:r,global:s,projectScope:i,mcp:c,hooks:a,skill:l,files:u}}function No(e={}){if(e.scope==="global")return{scope:"global",automatic:!1,reason:"explicit-global"};if(e.scope==="project"||e.scope==="both"){let o=v({cwd:e.cwd,project:e.projectRoot});if(!o.eligible)throw new Error(`Explicit ${e.scope} integration requires an explicit project, ToolNet project, or Git repository root.`);return{scope:e.scope,automatic:!1,project:o,reason:e.scope==="project"?"explicit-project":"explicit-both"}}let t=v({cwd:e.cwd,project:e.projectRoot});return t.toolnetProject?{scope:"both",automatic:!0,project:t,reason:"toolnet-project"}:{scope:"global",automatic:!0,reason:"no-toolnet-project"}}function _o(){return vt()}function Je(e={}){let t=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",o=[],r=e.detections??_o(),n=new Map(r.map(i=>[i.agent,i.detected])),s=No({scope:e.scope,projectRoot:e.projectRoot,cwd:e.cwd});if(!(e.force===!0||n.get("agy")===!0))o.push({agent:"agy",detected:!1,installed:!1,targets:[]});else try{let c=Mt({binary:t});o.push({agent:"agy",detected:!0,installed:!0,targets:c.files})}catch(c){o.push({agent:"agy",detected:!0,installed:!1,targets:[],error:c instanceof Error?c.message:String(c)})}if(!(e.force===!0||n.get("opencode")===!0))o.push({agent:"opencode",detected:!1,installed:!1,targets:[]});else try{let c=Nt({binary:t}),a=Jt({binary:t});o.push({agent:"opencode",detected:!0,installed:!0,targets:[c,a.configFile,`mcp:${a.serverName}`]})}catch(c){o.push({agent:"opencode",detected:!0,installed:!1,targets:[],error:c instanceof Error?c.message:String(c)})}if(!(e.force===!0||n.get("claude")===!0))o.push({agent:"claude",detected:!1,installed:!1,targets:[]});else try{let c=to({binary:t});o.push({agent:"claude",detected:!0,installed:!0,targets:[c.hooks.settingsFile,c.mcp.configFile,`mcp:${c.mcp.serverName}`]})}catch(c){o.push({agent:"claude",detected:!0,installed:!1,targets:[],error:c instanceof Error?c.message:String(c)})}if(!(e.force===!0||n.get("kiro")===!0))o.push({agent:"kiro",detected:!1,installed:!1,targets:[]});else try{let c=lo({...e.kiro??{},binary:t});o.push({agent:"kiro",detected:!0,installed:!0,targets:[c.mcp.configFile,`mcp:${c.mcp.serverName}`,c.hooks.hooksFile]})}catch(c){o.push({agent:"kiro",detected:!0,installed:!1,targets:[],error:c instanceof Error?c.message:String(c)})}if(!(e.force===!0||n.get("cursor")===!0))o.push({agent:"cursor",detected:!1,installed:!1,targets:[]});else try{let c=e.cursor??{},a=So({...c,binary:t,scope:c.scope??s.scope,projectRoot:c.projectRoot??s.project?.root});o.push({agent:"cursor",detected:!0,installed:!0,scope:a.scope,projectRoot:a.project?.root,targets:[...a.files,`mcp:${a.mcp.serverName}`]})}catch(c){o.push({agent:"cursor",detected:!0,installed:!1,targets:[],error:c instanceof Error?c.message:String(c)})}if(!(e.force===!0||n.get("copilot")===!0))o.push({agent:"copilot",detected:!1,installed:!1,targets:[]});else try{let c=e.copilot??{},a=xo({...c,binary:t,scope:c.scope??s.scope,projectRoot:c.projectRoot??s.project?.root});o.push({agent:"copilot",detected:!0,installed:!0,scope:a.scope,projectRoot:a.project?.root,targets:[...a.files,`mcp:${a.mcp.serverName}`]})}catch(c){o.push({agent:"copilot",detected:!0,installed:!1,targets:[],error:c instanceof Error?c.message:String(c)})}if(!(e.force===!0||n.get("grok")===!0))o.push({agent:"grok",detected:!1,installed:!1,targets:[]});else try{let c=e.grok??{},a=Fo({...c,binary:t,scope:c.scope??s.scope,projectRoot:c.projectRoot??s.project?.root});o.push({agent:"grok",detected:!0,installed:!0,scope:a.scope,projectRoot:a.project?.root,targets:[...a.files,`mcp:${a.mcp.serverName}`]})}catch(c){o.push({agent:"grok",detected:!0,installed:!1,targets:[],error:c instanceof Error?c.message:String(c)})}if(!(e.force===!0||n.get("codex")===!0))o.push({agent:"codex",detected:!1,installed:!1,targets:[]});else try{let c=Ut({binary:t}),a=Wt({binary:t}),l=Vt({binary:t});if(!l.installed)throw new Error(l.error??"Codex MCP registration failed");let u=[c.configFile,a,`mcp:${l.serverName}`];c.preservedPrevious&&u.push(c.previousFile),o.push({agent:"codex",detected:!0,installed:!0,targets:u})}catch(c){o.push({agent:"codex",detected:!0,installed:!1,targets:[],error:c instanceof Error?c.message:String(c)})}return o}function $o(e){switch(e){case"agy":return"Agy / Antigravity";case"opencode":return"OpenCode";case"claude":return"Claude Code";case"kiro":return"Kiro CLI";case"cursor":return"Cursor CLI";case"copilot":return"GitHub Copilot CLI";case"grok":return"Grok Build";case"codex":return"Codex"}}function ss(e){console.log(""),console.log("ToolNet Memory Integration Detection"),console.log("===================================="),console.log("");for(let t of e){let o=$o(t.agent);if(!t.detected){console.log(`\u25CB ${o}: not detected`);continue}console.log(`\u2713 ${o}: detected`);for(let r of t.evidence)console.log(` ${r}`)}console.log("")}function cs(e){console.log(""),console.log("ToolNet Memory AI Integrations"),console.log("=============================="),console.log("");for(let t of e){let o=$o(t.agent);if(!t.detected){console.log(`- ${o}: not detected`);continue}if(t.installed){let r=t.scope?` [scope=${t.scope}]`:"";console.log(`\u2713 ${o}: automatic memory enabled${r}`),t.projectRoot&&console.log(` project: ${t.projectRoot}`);continue}console.log(`\u2717 ${o}: integration failed`),t.error&&console.log(` ${t.error}`)}console.log("")}function as(e,t){let o=e.indexOf(t);return o>=0?e[o+1]:void 0}function ls(e){return e.includes("--scope")||e.includes("--global")||e.includes("--both")?bo(e):void 0}async function us(){let e=process.argv.slice(2),t=e.includes("--all"),o=e.includes("--json"),r=e.includes("--detect-only"),n=ls(e),s=as(e,"--project");if(r){let c=_o();if(o){console.log(JSON.stringify(c,null,2));return}ss(c);return}let i=Je({force:t,scope:n,projectRoot:s});if(o){console.log(JSON.stringify(i,null,2));return}cs(i)}var ps=process.argv[1]&&(process.argv[1].endsWith("auto-integrate.js")||process.argv[1].endsWith("auto-integrate.ts"));ps&&us().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exitCode=1});function ms(e=process.cwd()){let t=gs(e);if(!Do(t))throw new Error(`Project path does not exist: ${t}`);if(!ds(t).isDirectory())throw new Error(`Project path is not a directory: ${t}`);let o=new B().detect(t),r=fs(o.rootPath,".toolnet","project.json");if(!Do(r))throw new Error(`ToolNet project initialization failed: ${r} was not created`);return{initialized:!0,project:{id:o.id,name:o.name,remote:o.remote,rootPath:o.rootPath},manifestFile:r}}function ys(e,t){let o=e.indexOf(t);return o>=0?e[o+1]:void 0}async function hs(){let e=process.argv.slice(2),t=e.includes("--json"),o=!e.includes("--no-integrate"),r=ys(e,"--project"),n=e.find((a,l)=>!a.startsWith("-")&&(l===0||e[l-1]!=="--project")),s=r??n??process.cwd(),i=await pe("Initializing ToolNet project",()=>ms(s),{enabled:!t}),c=[];if(o&&(c=await pe("Detecting AI coding agents",()=>Je({projectRoot:i.project.rootPath}),{enabled:!t})),t){console.log(JSON.stringify({...i,integrations:c},null,2));return}if(console.log(""),console.log("ToolNet Memory"),console.log("=============="),console.log(""),console.log("\u2713 Project initialized"),console.log(""),console.log(`Project: ${i.project.name}`),console.log(`ID: ${i.project.id}`),console.log(`Root: ${i.project.rootPath}`),console.log(`Manifest: ${i.manifestFile}`),console.log(""),o){console.log("AI integrations:");let a=c.filter(l=>l.detected&&l.installed);if(!a.length)console.log(" \u25CB No supported coding agent detected");else for(let l of a){let u=l.agent==="agy"?"Agy / Antigravity":l.agent==="opencode"?"OpenCode":"Codex";console.log(` \u2713 ${u}`)}console.log("")}console.log("Next: toolnet-memory doctor"),console.log("")}var ks=process.argv[1]?.endsWith("/init.js")||process.argv[1]?.endsWith("/init.ts");ks&&hs().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exitCode=1});export{ms as initializeToolNetProject};
@@ -0,0 +1,55 @@
1
+ import{existsSync as K,readFileSync as Xe}from"node:fs";import{homedir as Re}from"node:os";import{join as m,resolve as Pe}from"node:path";function V(e={}){return e.cursorHome??m(e.home??Re(),".cursor")}function F(e={}){return m(V(e),"mcp.json")}function w(e={}){return m(V(e),"hooks.json")}function H(e){return m(Pe(e),".cursor")}function Y(e){return m(H(e),"mcp.json")}function Z(e){return m(H(e),"hooks.json")}function Fe(e){return m(H(e),"rules")}function D(e){return m(Fe(e),"toolnet-memory.mdc")}var ee=`---
2
+ description: ToolNet Memory project continuity and safety rules
3
+ alwaysApply: true
4
+ ---
5
+
6
+ # ToolNet Memory
7
+
8
+ Use ToolNet Memory as the continuity source for this project.
9
+
10
+ - When the user asks to continue, resume, pick up, finish unfinished work,
11
+ or asks where work stopped, use ToolNet continuity before reconstructing
12
+ context from old chat/session history.
13
+ - Use the ToolNet MCP server and \`memory_agent_ask\` when fast project context
14
+ is missing, stale, or ambiguous.
15
+ - Prefer \`mode="local"\` for current task, current file, blockers, TODOs,
16
+ completed work, and next action.
17
+ - Use \`mode="ai"\` only when synthesis is actually required.
18
+ - Do not reconstruct continuity by reading:
19
+ - \`.toolnet/sessions/**\`
20
+ - ToolNet raw \`events.jsonl\`
21
+ - ToolNet raw \`state.json\`
22
+ - another coding agent's private transcript/history files.
23
+ - After continuity is recovered, verify current repository source and git
24
+ state before changing code.
25
+ - Do not ask the user to repeat project context that ToolNet already provides.
26
+
27
+ Current repository evidence overrides stale memory.
28
+ `;import{spawnSync as we}from"node:child_process";import{existsSync as b,statSync as xe}from"node:fs";import{dirname as Oe,join as Ae,parse as Te,resolve as $}from"node:path";function oe(e){let o=$(e);if(!b(o))throw new Error(`Project path does not exist: ${o}`);if(!xe(o).isDirectory())throw new Error(`Project path is not a directory: ${o}`);return o}function x(e){return Ae(e,".toolnet","project.json")}function Ue(e){let o=$(e),t=Te(o).root;for(;;){if(b(x(o)))return o;if(o===t)return;let r=Oe(o);if(r===o)return;o=r}}function M(e){let o=we("git",["rev-parse","--show-toplevel"],{cwd:e,encoding:"utf8",timeout:5e3});if(o.status!==0)return;let t=o.stdout.trim();return t?$(t):void 0}function S(e={}){let o=oe(e.cwd??process.cwd());if(e.project){let n=oe(e.project),i=x(n),s=M(n);return{root:n,source:"explicit",eligible:!0,toolnetProject:b(i),manifestFile:b(i)?i:void 0,gitRoot:s}}let t=Ue(o);if(t){let n=x(t);return{root:t,source:"toolnet",eligible:!0,toolnetProject:!0,manifestFile:n,gitRoot:M(t)}}let r=M(o);if(r){let n=x(r);return{root:r,source:"git",eligible:!0,toolnetProject:b(n),manifestFile:b(n)?n:void 0,gitRoot:r}}return{root:o,source:"cwd",eligible:!1,toolnetProject:!1}}function ie(e,o={}){let t=[],r=e.indexOf("--scope");if(r>=0){let i=e[r+1];if(i!=="global"&&i!=="project"&&i!=="both")throw new Error(`Invalid --scope value: ${String(i)}`);t.push(i)}e.includes("--global")&&t.push("global"),e.includes("--both")&&t.push("both");let n=Array.from(new Set(t));if(n.length>1)throw new Error(`Conflicting integration scopes: ${n.join(", ")}`);return n[0]??o.defaultScope??"global"}function te(e,o){return{install:e,effective:o}}function d(e,o){return{surface:e,global:te(o.globalInstall,o.effective==="global"||o.effective==="both"),project:te(o.projectInstall,o.effective==="project"||o.effective==="both"),effective:o.effective,risk:o.risk??"none",dedupeRequired:o.dedupeRequired??!1,trustRequired:o.trustRequired??o.projectInstall,note:o.note}}function qe(e){return{mcp:d("mcp",{globalInstall:!0,projectInstall:!1,effective:"global"}),hooks:d("hooks",{globalInstall:!0,projectInstall:!1,effective:"global"}),work:d("work",{globalInstall:e==="grok",projectInstall:!1,effective:e==="grok"?"global":"none",note:e==="grok"?"Grok supports a global ToolNet continuity skill.":"Cursor/Copilot work instructions remain project-scoped."})}}function re(e){return{mcp:d("mcp",{globalInstall:!1,projectInstall:!0,effective:"project",trustRequired:!0}),hooks:d("hooks",{globalInstall:!1,projectInstall:!0,effective:"project",trustRequired:!0}),work:d("work",{globalInstall:!1,projectInstall:!0,effective:"project",trustRequired:!1,note:e==="cursor"?"Use .cursor/rules/toolnet-memory.mdc.":e==="copilot"?"Use .github/instructions/toolnet-memory.instructions.md.":"Use .grok/skills/toolnet-continuity/SKILL.md."})}}function ne(e){return{mcp:d("mcp",{globalInstall:!0,projectInstall:!0,effective:"project",risk:e==="cursor"?"precedence-unverified":"shadowed-global",trustRequired:!0,note:e==="cursor"?"Project ToolNet MCP is the intended effective definition; native same-name precedence must be E2E certified before release.":"Global remains useful outside the project; same-name project definition wins inside the project."}),hooks:d("hooks",{globalInstall:!0,projectInstall:!0,effective:"both",risk:"additive-duplicate",dedupeRequired:!0,trustRequired:!0,note:"Global and project hook sources can both execute for the same native event."}),work:d("work",{globalInstall:e==="grok",projectInstall:!0,effective:"project",risk:e==="grok"?"shadowed-global":"none",trustRequired:!1,note:e==="cursor"?"Project rule is authoritative.":e==="copilot"?"Project instruction is authoritative.":"Project skill shadows the same-name global skill inside the project."})}}function I(e){let{agent:o,scope:t,project:r}=e;return(t==="project"||t==="both")&&(!r||!r.eligible)?{agent:o,requestedScope:t,project:r,surfaces:t==="both"?ne(o):re(o),canInstall:!1,reason:"Project scope requires an explicit project, existing ToolNet project, or Git repository root."}:{agent:o,requestedScope:t,project:r,surfaces:t==="global"?qe(o):t==="project"?re(o):ne(o),canInstall:!0}}import{existsSync as v,readFileSync as B}from"node:fs";import{homedir as Ee}from"node:os";import{join as p,resolve as se}from"node:path";function ce(e={}){return e.copilotHome??process.env.COPILOT_HOME??p(e.home??Ee(),".copilot")}function O(e={}){return p(ce(e),"mcp-config.json")}function Ne(e={}){return p(ce(e),"hooks")}function A(e={}){return p(Ne(e),"toolnet-memory.json")}function G(e){return p(se(e),".github")}function le(e){return p(G(e),"mcp.json")}function ae(e){return p(se(e),".mcp.json")}function He(e){return p(G(e),"hooks")}function ue(e){return p(He(e),"toolnet-memory.json")}function De(e){return p(G(e),"instructions")}function _(e){return p(De(e),"toolnet-memory.instructions.md")}import{homedir as Me}from"node:os";import{join as l,resolve as $e}from"node:path";function L(e={}){return e.grokHome??process.env.GROK_HOME??l(e.home??Me(),".grok")}function T(e={}){return l(L(e),"config.toml")}function Ge(e={}){return l(L(e),"hooks")}function U(e={}){return l(Ge(e),"toolnet-memory.json")}function _e(e={}){return l(L(e),"skills")}function Le(e={}){return l(_e(e),"toolnet-continuity")}function q(e={}){return l(Le(e),"SKILL.md")}function J(e){return l($e(e),".grok")}function pe(e){return l(J(e),"config.toml")}function Je(e){return l(J(e),"hooks")}function fe(e){return l(Je(e),"toolnet-memory.json")}function We(e){return l(J(e),"skills")}function Be(e){return l(We(e),"toolnet-continuity")}function de(e){return l(Be(e),"SKILL.md")}function k(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function P(e){if(!v(e))return{};try{let o=JSON.parse(B(e,"utf8"));return k(o)?{value:o}:{error:"root must be a JSON object"}}catch(o){return{error:o instanceof Error?o.message:String(o)}}}function ge(e,o){if(!e||!k(e.mcpServers))return!1;let t=e.mcpServers["toolnet-memory"];return!k(t)||typeof t.command!="string"||!t.command.trim()||!Array.isArray(t.args)||t.args.length!==1||t.args[0]!=="mcp"?!1:!o||Array.isArray(t.tools)&&t.tools.includes("*")}function me(e,o,t){if(!e||!k(e.hooks))return[];let r=e.hooks;return o.filter(n=>{let i=r[n];return Array.isArray(i)&&i.some(s=>k(s)&&(typeof s.command=="string"&&s.command.includes(t)||typeof s.bash=="string"&&s.bash.includes(t)))})}function Ke(e,o){if(!e||!k(e.hooks))return[];let t=e.hooks;return o.filter(r=>{let n=t[r];return Array.isArray(n)&&n.some(i=>!k(i)||!Array.isArray(i.hooks)?!1:i.hooks.some(s=>k(s)&&typeof s.command=="string"&&s.command.includes("session:grok-hook")))})}function ze(e){if(!v(e))return!1;let o=B(e,"utf8"),t=/\[mcp_servers\.(?:"toolnet-memory"|'toolnet-memory'|toolnet-memory)\]/,r=o.search(t);if(r<0)return!1;let n=o.slice(r),i=n.slice(1).search(/\n\s*\[[^\]]+\]/),s=i>=0?n.slice(0,i+1):n;return/command\s*=\s*"[^"]+"/.test(s)&&/args\s*=\s*\[\s*"mcp"\s*\]/.test(s)&&!/enabled\s*=\s*false/.test(s)}function W(e){let o=[];e.mcpError&&o.push(`MCP config: ${e.mcpError}`),e.hookError&&o.push(`Hooks config: ${e.hookError}`);let t=e.mcpConfigured&&e.hooksConfigured&&(e.skill?.configured??!0),r=v(e.configFile)||v(e.hooksFile)||(e.skill?v(e.skill.skillFile):!1),n=o.length>0?"invalid":t?"ready":r?"partial":"not-installed";return{installed:t,state:n,mcp:{configured:e.mcpConfigured,configFile:e.configFile,error:e.mcpError},hooks:{configured:e.hooksConfigured,hooksFile:e.hooksFile,events:e.events,error:e.hookError},skill:e.skill,errors:o}}function g(e,o={}){if(e==="cursor"){let c=["sessionStart","beforeSubmitPrompt","preToolUse","postToolUse","afterAgentResponse","stop"],a=o.configFile??F(),j=o.hooksFile??w(),h=P(a),y=P(j),R=y.error?[]:me(y.value,c,"session:cursor-hook");return W({mcpConfigured:!h.error&&ge(h.value,!1),configFile:a,mcpError:h.error,hooksConfigured:c.every(N=>R.includes(N)),hooksFile:j,events:R,hookError:y.error})}if(e==="copilot"){let c=["sessionStart","userPromptSubmitted","userPromptTransformed","preToolUse","postToolUse","agentStop"],a=o.configFile??O(),j=o.hooksFile??A(),h=P(a),y=P(j),R=y.error?[]:me(y.value,c,"session:copilot-hook");return W({mcpConfigured:!h.error&&ge(h.value,!0),configFile:a,mcpError:h.error,hooksConfigured:c.every(N=>R.includes(N)),hooksFile:j,events:R,hookError:y.error})}let t=["SessionStart","UserPromptSubmit","PreToolUse","PostToolUse","Stop"],r=o.configFile??T(),n=o.hooksFile??U(),i=o.skillFile??q(),s=P(n),u=s.error?[]:Ke(s.value,t),f=v(i)&&B(i,"utf8").includes("memory_agent_ask");return W({mcpConfigured:ze(r),configFile:r,hooksConfigured:t.every(c=>u.includes(c)),hooksFile:n,events:u,hookError:s.error,skill:{configured:f,skillFile:i}})}function Qe(e){let o=!1;try{o=Xe(e,"utf8")===ee}catch{o=!1}return{configured:o,ruleFile:e}}function Ve(e,o,t){return o.some(n=>n?.state==="invalid")?"invalid":e?"ready":o.some(n=>n&&(n.state==="partial"||n.state==="ready"||K(n.mcp.configFile)||K(n.hooks.hooksFile)))||!!(t&&K(t.ruleFile))?"partial":"not-installed"}function Se(e={}){let o=e.scope??"global",t=o==="global"?void 0:S({project:e.projectRoot}),r=I({agent:"cursor",scope:o,project:t}),n=o==="global"||o==="both"?g("cursor",{configFile:e.globalConfigFile??F(),hooksFile:e.globalHooksFile??w()}):void 0,i;if((o==="project"||o==="both")&&t?.eligible){let a=Qe(e.projectRuleFile??D(t.root));i={...g("cursor",{configFile:e.projectConfigFile??Y(t.root),hooksFile:e.projectHooksFile??Z(t.root)}),rule:a}}let s=o==="project"?!0:n?.installed===!0,u=o==="global"?!0:i?.installed===!0&&i.rule.configured===!0,f=r.canInstall&&s&&u,c=[];return!r.canInstall&&r.reason&&c.push(r.reason),o==="both"&&(c.push("Global + project Cursor hooks are additive; ToolNet runtime dedupe is required and enabled."),c.push("Cursor same-name global/project MCP precedence remains marked for native E2E certification.")),{installed:f,state:Ve(f,[n,i],i?.rule),requestedScope:o,plan:r,project:t,global:n,projectScope:i,dedupeReady:!0,trustRequired:o==="project"||o==="both",warnings:c}}import{existsSync as E,readFileSync as je}from"node:fs";var ke=`---
29
+ applyTo: "**"
30
+ ---
31
+
32
+ # ToolNet Memory project continuity
33
+
34
+ Use ToolNet Memory as the continuity source for this repository.
35
+
36
+ - When the user asks to continue, resume, pick up, finish unfinished work,
37
+ or asks where work stopped, recover ToolNet continuity before reconstructing
38
+ state from chat/session history.
39
+ - Use the ToolNet MCP server and \`memory_agent_ask\` when fast project context
40
+ is missing, stale, or ambiguous.
41
+ - Prefer \`mode="local"\` for current task, current file, blockers, TODOs,
42
+ completed work, and next action.
43
+ - Use \`mode="ai"\` only when continuity needs synthesis.
44
+ - Do not reconstruct continuity by reading:
45
+ - \`.toolnet/sessions/**\`
46
+ - ToolNet raw \`events.jsonl\`
47
+ - ToolNet raw \`state.json\`
48
+ - another coding agent's private transcript/history files.
49
+ - After continuity is recovered, verify current repository source and git
50
+ state before changing code.
51
+ - Do not ask the user to repeat context ToolNet already provides.
52
+
53
+ Current repository evidence overrides stale memory.
54
+ `;function Ye(e){let o=!1;try{o=je(e,"utf8")===ke}catch{o=!1}return{configured:o,instructionFile:e}}function Ze(e){let o=ae(e);if(!E(o))return{file:o,toolnetDefined:!1};try{let t=JSON.parse(je(o,"utf8")),r=t.mcpServers&&typeof t.mcpServers=="object"&&!Array.isArray(t.mcpServers)?t.mcpServers:{};return{file:o,toolnetDefined:r["toolnet-memory"]!==void 0||r.toolnet!==void 0}}catch{return{file:o,toolnetDefined:!1}}}function eo(e,o,t){return o.some(n=>n?.state==="invalid")?"invalid":e?"ready":o.some(n=>n&&(n.state==="partial"||n.state==="ready"||E(n.mcp.configFile)||E(n.hooks.hooksFile)))||!!(t&&E(t.instructionFile))?"partial":"not-installed"}function he(e={}){let o=e.scope??"global",t=o==="global"?void 0:S({project:e.projectRoot}),r=I({agent:"copilot",scope:o,project:t}),n=o==="global"||o==="both"?g("copilot",{configFile:e.globalConfigFile??O(),hooksFile:e.globalHooksFile??A()}):void 0,i;if((o==="project"||o==="both")&&t?.eligible){let j=Ye(e.projectInstructionFile??_(t.root));i={...g("copilot",{configFile:e.projectConfigFile??le(t.root),hooksFile:e.projectHooksFile??ue(t.root)}),instruction:j}}let s=o==="project"?!0:n?.installed===!0,u=o==="global"?!0:i?.installed===!0&&i.instruction.configured===!0,f=r.canInstall&&s&&u,c=t?.eligible?Ze(t.root):null,a=[];return!r.canInstall&&r.reason&&a.push(r.reason),o==="both"&&(a.push("Global + project Copilot hooks are additive; ToolNet cross-process dedupe is enabled."),a.push("Project toolnet-memory MCP shadows the same-name global definition inside this repository.")),c?.toolnetDefined&&a.push(`Alternate repository MCP file also defines ToolNet: ${c.file}`),{installed:f,state:eo(f,[n,i],i?.instruction),requestedScope:o,plan:r,project:t,global:n,projectScope:i,dedupeReady:!0,trustRequired:o==="project"||o==="both",alternateProjectMcp:c,warnings:a}}import{existsSync as z}from"node:fs";function oo(e,o){return o.some(r=>r?.state==="invalid")?"invalid":e?"ready":o.some(r=>r&&(r.state==="partial"||r.state==="ready"||z(r.mcp.configFile)||z(r.hooks.hooksFile)||!!(r.skill&&z(r.skill.skillFile))))?"partial":"not-installed"}function ye(e={}){let o=e.scope??"global",t=o==="global"?void 0:S({project:e.projectRoot}),r=I({agent:"grok",scope:o,project:t}),n=o==="global"||o==="both"?g("grok",{configFile:e.globalConfigFile??T(),hooksFile:e.globalHooksFile??U(),skillFile:e.globalSkillFile??q()}):void 0,i=(o==="project"||o==="both")&&t?.eligible?g("grok",{configFile:e.projectConfigFile??pe(t.root),hooksFile:e.projectHooksFile??fe(t.root),skillFile:e.projectSkillFile??de(t.root)}):void 0,s=o==="project"?!0:n?.installed===!0,u=o==="global"?!0:i?.installed===!0,f=r.canInstall&&s&&u,c=[];return!r.canInstall&&r.reason&&c.push(r.reason),o==="both"&&(c.push("Global + project Grok hooks are layered; ToolNet cross-process dedupe is enabled."),c.push('Project [mcp_servers."toolnet-memory"] fully replaces the same-name global server inside this project.'),c.push("Project toolnet-continuity skill shadows the same-name global skill inside this project.")),{installed:f,state:oo(f,[n,i]),requestedScope:o,plan:r,project:t,global:n,projectScope:i,effective:{mcp:r.surfaces.mcp.effective==="project"?"project":r.surfaces.mcp.effective==="global"?"global":"none",hooks:r.surfaces.hooks.effective==="both"?"both":r.surfaces.hooks.effective==="project"?"project":r.surfaces.hooks.effective==="global"?"global":"none",skill:r.surfaces.work.effective==="project"?"project":r.surfaces.work.effective==="global"?"global":"none"},dedupeReady:!0,trustRequired:o==="project"||o==="both",warnings:c}}var to={cursor:Se,copilot:he,grok:ye},X={cursor:"Cursor CLI",copilot:"GitHub Copilot CLI",grok:"Grok Build"};function C(e,o){if(e)return{configured:e.installed&&(o?.configured??!0),mcp:{configured:e.mcp.configured,file:e.mcp.configFile},hooks:{configured:e.hooks.configured,file:e.hooks.hooksFile,events:e.hooks.events},work:o}}function ro(e){let o=e.projectScope?{kind:"rule",configured:e.projectScope.rule.configured,file:e.projectScope.rule.ruleFile}:void 0;return{agent:"cursor",label:X.cursor,installed:e.installed,state:e.state,requestedScope:e.requestedScope,projectRoot:e.project?.root,global:C(e.global),project:C(e.projectScope,o),effective:{mcp:e.plan.surfaces.mcp.effective,hooks:e.plan.surfaces.hooks.effective,work:e.plan.surfaces.work.effective},risk:{mcp:e.plan.surfaces.mcp.risk,hooks:e.plan.surfaces.hooks.risk,work:e.plan.surfaces.work.risk},trust:{required:e.trustRequired,state:e.trustRequired?"required-unverified":"not-required"},dedupe:{required:e.plan.surfaces.hooks.dedupeRequired,ready:e.dedupeReady},warnings:[...e.warnings]}}function no(e){let o=e.projectScope?{kind:"instruction",configured:e.projectScope.instruction.configured,file:e.projectScope.instruction.instructionFile}:void 0;return{agent:"copilot",label:X.copilot,installed:e.installed,state:e.state,requestedScope:e.requestedScope,projectRoot:e.project?.root,global:C(e.global),project:C(e.projectScope,o),effective:{mcp:e.plan.surfaces.mcp.effective,hooks:e.plan.surfaces.hooks.effective,work:e.plan.surfaces.work.effective},risk:{mcp:e.plan.surfaces.mcp.risk,hooks:e.plan.surfaces.hooks.risk,work:e.plan.surfaces.work.risk},trust:{required:e.trustRequired,state:e.trustRequired?"required-unverified":"not-required"},dedupe:{required:e.plan.surfaces.hooks.dedupeRequired,ready:e.dedupeReady},warnings:[...e.warnings]}}function io(e){let o=e.global?.skill?{kind:"skill",configured:e.global.skill.configured,file:e.global.skill.skillFile}:void 0,t=e.projectScope?.skill?{kind:"skill",configured:e.projectScope.skill.configured,file:e.projectScope.skill.skillFile}:void 0;return{agent:"grok",label:X.grok,installed:e.installed,state:e.state,requestedScope:e.requestedScope,projectRoot:e.project?.root,global:C(e.global,o),project:C(e.projectScope,t),effective:{mcp:e.plan.surfaces.mcp.effective,hooks:e.plan.surfaces.hooks.effective,work:e.plan.surfaces.work.effective},risk:{mcp:e.plan.surfaces.mcp.risk,hooks:e.plan.surfaces.hooks.risk,work:e.plan.surfaces.work.risk},trust:{required:e.trustRequired,state:e.trustRequired?"required-unverified":"not-required"},dedupe:{required:e.plan.surfaces.hooks.dedupeRequired,ready:e.dedupeReady},warnings:[...e.warnings]}}function so(e){return e.some(o=>o.state==="invalid")?"invalid":e.length>0&&e.every(o=>o.installed)?"ready":e.every(o=>o.state==="not-installed")?"not-installed":"partial"}function be(e={},o=to){let t=e.scope??"global",n=(e.agents??["cursor","copilot","grok"]).map(s=>s==="cursor"?ro(o.cursor({scope:t,projectRoot:e.projectRoot})):s==="copilot"?no(o.copilot({scope:t,projectRoot:e.projectRoot})):io(o.grok({scope:t,projectRoot:e.projectRoot}))),i=so(n);return{installed:n.length>0&&n.every(s=>s.installed),state:i,requestedScope:t,projectRoot:e.projectRoot??n.find(s=>s.projectRoot)?.projectRoot,agents:n,summary:{total:n.length,ready:n.filter(s=>s.state==="ready").length,partial:n.filter(s=>s.state==="partial").length,invalid:n.filter(s=>s.state==="invalid").length,missing:n.filter(s=>s.state==="not-installed").length}}}function Q(e){return e?"ready":"missing"}function co(e){return e.work?`${e.work.kind} ${Q(e.work.configured)} \u2014 ${e.work.file}`:"n/a"}function Ie(e,o){return o?[` ${e}`,` MCP ${Q(o.mcp.configured)} \u2014 ${o.mcp.file}`,` Hooks ${Q(o.hooks.configured)} \u2014 ${o.hooks.file}`,` Work ${co(o)}`]:[` ${e.padEnd(8)} not selected`]}function lo(e){let o=[];o.push(`${e.label} \u2014 ${e.state.toUpperCase()}`),o.push(...Ie("Global",e.global)),o.push(...Ie("Project",e.project)),o.push(` Effective MCP=${e.effective.mcp} Hooks=${e.effective.hooks} Work=${e.effective.work}`),o.push(` Dedupe ${e.dedupe.ready?"ready":"missing"}${e.dedupe.required?" (required)":" (not required)"}`),o.push(` Trust ${e.trust.state==="required-unverified"?"required / native trust unverified":"not required"}`),o.push(` Risk MCP=${e.risk.mcp} Hooks=${e.risk.hooks} Work=${e.risk.work}`);for(let t of e.warnings)o.push(` Note ${t}`);return o}function ve(e){let o=[];return o.push("ToolNet Scoped Integrations"),o.push("==========================="),o.push(""),o.push(`State : ${e.state}`),o.push(`Scope : ${e.requestedScope}`),e.projectRoot&&o.push(`Project : ${e.projectRoot}`),o.push(""),e.agents.forEach((t,r)=>{o.push(...lo(t)),r<e.agents.length-1&&o.push("")}),o.push(""),o.push(`Summary : ${e.summary.ready}/${e.summary.total} ready | ${e.summary.partial} partial | ${e.summary.invalid} invalid | ${e.summary.missing} missing`),o.push(""),o.join(`
55
+ `)}function Ce(e,o){let t=e.indexOf(o);return t>=0?e[t+1]:void 0}function ao(e){let o=Ce(e,"--agent");if(o){if(o!=="cursor"&&o!=="copilot"&&o!=="grok")throw new Error(`Invalid --agent value: ${o}`);return[o]}}function uo(){let e=process.argv.slice(2),o=e.includes("--json"),t=ie(e),r=Ce(e,"--project"),n=ao(e),i=t==="global"?void 0:S({project:r}),s={scope:t,projectRoot:i?.root,agents:n},u=be(s);console.log(o?JSON.stringify(u,null,2):ve(u)),u.installed||(process.exitCode=1)}try{uo()}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exitCode=1}