toolnet-memory 0.3.10 → 0.3.12

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/copilot.js CHANGED
@@ -1,33 +1,29 @@
1
- import{homedir as yo}from"node:os";import{join as _}from"node:path";function V(o={}){return o.cursorHome??_(o.home??yo(),".cursor")}function I(o={}){return _(V(o),"mcp.json")}function E(o={}){return _(V(o),"hooks.json")}import{existsSync as Co,mkdirSync as bo,readFileSync as Oo,renameSync as wo,rmSync as Fo,writeFileSync as So}from"node:fs";import{dirname as vo}from"node:path";function f(o){return typeof o=="object"&&o!==null&&!Array.isArray(o)}function k(o,r){if(!Co(o))return{};let n=Oo(o,"utf8").trim();if(!n)return{};let t;try{t=JSON.parse(n)}catch(e){throw new Error(`Invalid existing ${r} hooks file: ${e instanceof Error?e.message:String(e)}`)}if(!f(t))throw new Error(`Invalid existing ${r} hooks file: root must be a JSON object.`);return t}function C(o,r){bo(vo(o),{recursive:!0,mode:448});let n=`${o}.toolnet-${process.pid}-${Date.now()}.tmp`;try{So(n,`${JSON.stringify(r,null,2)}
2
- `,{encoding:"utf8",mode:384}),wo(n,o)}finally{Fo(n,{force:!0})}}function R(o){return/^[A-Za-z0-9_./:-]+$/u.test(o)?o:`'${o.replace(/'/gu,"'\\''")}'`}var F=[["sessionStart",10],["beforeSubmitPrompt",10],["preToolUse",10],["postToolUse",15],["afterAgentResponse",15],["stop",30]];function K(o){return f(o)&&typeof o.command=="string"&&o.command.includes("session:cursor-hook")}function xo(o,r,n){let e={type:"command",command:`TOOLNET_HOOK_EVENT=${R(o)} ${R(r)} session:cursor-hook`,timeout:n};return o==="preToolUse"&&(e.matcher=".*"),e}function q(o={}){let r=o.hooksFile??E(),n=o.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",t=k(r,"Cursor");if(t.version!==void 0&&t.version!==1)throw new Error(`Unsupported existing Cursor hooks version: ${String(t.version)}`);let e=t.hooks;if(e!==void 0&&!f(e))throw new Error("Invalid existing Cursor hooks file: hooks must be an object.");let s=f(e)?{...e}:{};for(let[l,c]of F){let a=s[l];if(a!==void 0&&!Array.isArray(a))throw new Error(`Invalid existing Cursor hooks file: hooks.${l} must be an array.`);let m=Array.isArray(a)?a.filter(p=>!K(p)):[];s[l]=[...m,xo(l,n,c)]}let i={...t,version:1,hooks:s};if(JSON.stringify(t)===JSON.stringify(i))return{hooksFile:r,changed:!1,hookCount:F.length};C(r,i);let g=k(r,"Cursor");if(g.version!==1||!f(g.hooks))throw new Error("Cursor hooks were written but verification failed.");let u=0;for(let[l]of F){let c=g.hooks[l];if(!Array.isArray(c))throw new Error("Cursor hooks were written but verification failed.");u+=c.filter(K).length}if(u!==F.length)throw new Error("Cursor hooks were written but verification failed.");return{hooksFile:r,changed:!0,hookCount:F.length}}import{existsSync as Io,mkdirSync as Eo,readFileSync as Ho,renameSync as No,rmSync as jo,writeFileSync as To}from"node:fs";import{dirname as $o}from"node:path";function d(o){return typeof o=="object"&&o!==null&&!Array.isArray(o)}function b(o,r){if(!Io(o))return{};let n=Ho(o,"utf8").trim();if(!n)return{};let t;try{t=JSON.parse(n)}catch(e){throw new Error(`Invalid existing ${r} MCP config: ${e instanceof Error?e.message:String(e)}`)}if(!d(t))throw new Error(`Invalid existing ${r} MCP config: root must be a JSON object.`);return t}function H(o,r){Eo($o(o),{recursive:!0,mode:448});let n=`${o}.tmp-${process.pid}-${Date.now()}`;try{To(n,`${JSON.stringify(r,null,2)}
3
- `,{encoding:"utf8",mode:384}),No(n,o)}finally{jo(n,{force:!0})}}function z(o,r){return d(o)?(o.type===void 0||o.type==="stdio")&&o.command===r&&Array.isArray(o.args)&&o.args.length===1&&o.args[0]==="mcp":!1}function Q(o={}){let r=o.configFile??I(),n=o.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",t=o.serverName??"toolnet-memory",e=b(r,"Cursor"),s=e.mcpServers;if(s!==void 0&&!d(s))throw new Error("Invalid existing Cursor MCP config: mcpServers must be an object.");let i=d(s)?{...s}:{};if(z(i[t],n))return{installed:!0,changed:!1,configFile:r,serverName:t,command:n,args:["mcp"]};i[t]={type:"stdio",command:n,args:["mcp"]},H(r,{...e,mcpServers:i});let u=b(r,"Cursor").mcpServers;if(!d(u)||!z(u[t],n))throw new Error("Cursor MCP configuration was written but verification failed.");return{installed:!0,changed:!0,configFile:r,serverName:t,command:n,args:["mcp"]}}function X(o={}){let r=o.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",n=Q({binary:r,configFile:o.configFile}),t=q({binary:r,hooksFile:o.hooksFile});return{installed:n.installed,changed:n.changed||t.changed,mcp:n,hooks:t,files:[n.configFile,t.hooksFile]}}import{homedir as Jo}from"node:os";import{join as N}from"node:path";function Z(o={}){return o.copilotHome??process.env.COPILOT_HOME??N(o.home??Jo(),".copilot")}function j(o={}){return N(Z(o),"mcp-config.json")}function Mo(o={}){return N(Z(o),"hooks")}function T(o={}){return N(Mo(o),"toolnet-memory.json")}var S=[["sessionStart",10],["userPromptSubmitted",10],["userPromptTransformed",10],["preToolUse",10],["postToolUse",15],["agentStop",30]];function Go(o){if(typeof o.command=="string")return o.command;if(typeof o.bash=="string")return o.bash}function oo(o){return f(o)&&Go(o)?.includes("session:copilot-hook")===!0}function Ao(o,r,n){let t={type:"command",command:`${r} session:copilot-hook`,env:{TOOLNET_HOOK_EVENT:o},timeoutSec:n};return o==="preToolUse"&&(t.matcher=".*"),t}function ro(o={}){let r=o.hooksFile??T(),n=o.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",t=k(r,"GitHub Copilot CLI");if(t.version!==void 0&&t.version!==1)throw new Error(`Unsupported existing GitHub Copilot CLI hooks version: ${String(t.version)}`);let e=t.hooks;if(e!==void 0&&!f(e))throw new Error("Invalid existing GitHub Copilot CLI hooks file: hooks must be an object.");let s=f(e)?{...e}:{};for(let[l,c]of S){let a=s[l];if(a!==void 0&&!Array.isArray(a))throw new Error(`Invalid existing GitHub Copilot CLI hooks file: hooks.${l} must be an array.`);let m=Array.isArray(a)?a.filter(p=>!oo(p)):[];s[l]=[...m,Ao(l,n,c)]}let i={...t,version:1,hooks:s};if(JSON.stringify(t)===JSON.stringify(i))return{hooksFile:r,changed:!1,hookCount:S.length};C(r,i);let g=k(r,"GitHub Copilot CLI");if(g.version!==1||!f(g.hooks))throw new Error("GitHub Copilot CLI hooks were written but verification failed.");let u=0;for(let[l]of S){let c=g.hooks[l];if(!Array.isArray(c))throw new Error("GitHub Copilot CLI hooks were written but verification failed.");u+=c.filter(oo).length}if(u!==S.length)throw new Error("GitHub Copilot CLI hooks were written but verification failed.");return{hooksFile:r,changed:!0,hookCount:S.length}}function no(o,r){return d(o)?(o.type===void 0||o.type==="local"||o.type==="stdio")&&o.command===r&&Array.isArray(o.args)&&o.args.length===1&&o.args[0]==="mcp"&&Array.isArray(o.tools)&&o.tools.length===1&&o.tools[0]==="*":!1}function to(o={}){let r=o.configFile??j(),n=o.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",t=o.serverName??"toolnet-memory",e=b(r,"GitHub Copilot CLI"),s=e.mcpServers;if(s!==void 0&&!d(s))throw new Error("Invalid existing GitHub Copilot CLI MCP config: mcpServers must be an object.");let i=d(s)?{...s}:{};if(no(i[t],n))return{installed:!0,changed:!1,configFile:r,serverName:t,command:n,args:["mcp"]};i[t]={type:"stdio",command:n,args:["mcp"],tools:["*"]},H(r,{...e,mcpServers:i});let u=b(r,"GitHub Copilot CLI").mcpServers;if(!d(u)||!no(u[t],n))throw new Error("GitHub Copilot CLI MCP configuration was written but verification failed.");return{installed:!0,changed:!0,configFile:r,serverName:t,command:n,args:["mcp"]}}function eo(o={}){let r=o.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",n=to({binary:r,configFile:o.configFile}),t=ro({binary:r,hooksFile:o.hooksFile});return{installed:n.installed,changed:n.changed||t.changed,mcp:n,hooks:t,files:[n.configFile,t.hooksFile]}}import{existsSync as Do,mkdirSync as Uo,readFileSync as io,renameSync as Bo,rmSync as Wo,writeFileSync as Yo}from"node:fs";import{dirname as Vo}from"node:path";import{homedir as Po}from"node:os";import{join as y}from"node:path";function L(o={}){return o.grokHome??process.env.GROK_HOME??y(o.home??Po(),".grok")}function $(o={}){return y(L(o),"config.toml")}function _o(o={}){return y(L(o),"hooks")}function J(o={}){return y(_o(o),"toolnet-memory.json")}function Ro(o={}){return y(L(o),"skills")}function Lo(o={}){return y(Ro(o),"toolnet-continuity")}function M(o={}){return y(Lo(o),"SKILL.md")}var D=`---
4
- name: toolnet-continuity
5
- description: Restore previous ToolNet project work when the user asks to continue, resume, pick up, finish unfinished work, or asks where work stopped.
6
- 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
1
+ import{homedir as So}from"node:os";import{join as f,resolve as Y}from"node:path";function z(o={}){return o.copilotHome??process.env.COPILOT_HOME??f(o.home??So(),".copilot")}function k(o={}){return f(z(o),"mcp-config.json")}function Co(o={}){return f(z(o),"hooks")}function h(o={}){return f(Co(o),"toolnet-memory.json")}function J(o){return f(Y(o),".github")}function x(o){return f(J(o),"mcp.json")}function V(o){return f(Y(o),".mcp.json")}function Io(o){return f(J(o),"hooks")}function R(o){return f(Io(o),"toolnet-memory.json")}function Po(o){return f(J(o),"instructions")}function H(o){return f(Po(o),"toolnet-memory.instructions.md")}import{existsSync as Fo,mkdirSync as Oo,readFileSync as vo,renameSync as wo,rmSync as xo,writeFileSync as Ro}from"node:fs";import{dirname as Ho}from"node:path";function b(o){return typeof o=="object"&&o!==null&&!Array.isArray(o)}function $(o,t){if(!Fo(o))return{};let e=vo(o,"utf8").trim();if(!e)return{};let r;try{r=JSON.parse(e)}catch(n){throw new Error(`Invalid existing ${t} hooks file: ${n instanceof Error?n.message:String(n)}`)}if(!b(r))throw new Error(`Invalid existing ${t} hooks file: root must be a JSON object.`);return r}function Q(o,t){Oo(Ho(o),{recursive:!0,mode:448});let e=`${o}.toolnet-${process.pid}-${Date.now()}.tmp`;try{Ro(e,`${JSON.stringify(t,null,2)}
2
+ `,{encoding:"utf8",mode:384}),wo(e,o)}finally{xo(e,{force:!0})}}var O=[["sessionStart",10],["userPromptSubmitted",10],["userPromptTransformed",10],["preToolUse",10],["postToolUse",15],["agentStop",30]];function Ao(o){if(typeof o.command=="string")return o.command;if(typeof o.bash=="string")return o.bash}function Z(o){return b(o)&&Ao(o)?.includes("session:copilot-hook")===!0}function Eo(o,t,e){let r={type:"command",command:`${t} session:copilot-hook`,env:{TOOLNET_HOOK_EVENT:o},timeoutSec:e};return o==="preToolUse"&&(r.matcher=".*"),r}function D(o={}){let t=o.hooksFile??h(),e=o.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",r=$(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&&!b(n))throw new Error("Invalid existing GitHub Copilot CLI hooks file: hooks must be an object.");let i=b(n)?{...n}:{};for(let[c,a]of O){let p=i[c];if(p!==void 0&&!Array.isArray(p))throw new Error(`Invalid existing GitHub Copilot CLI hooks file: hooks.${c} must be an array.`);let g=Array.isArray(p)?p.filter(d=>!Z(d)):[];i[c]=[...g,Eo(c,e,a)]}let s={...r,version:1,hooks:i};if(JSON.stringify(r)===JSON.stringify(s))return{hooksFile:t,changed:!1,hookCount:O.length};Q(t,s);let u=$(t,"GitHub Copilot CLI");if(u.version!==1||!b(u.hooks))throw new Error("GitHub Copilot CLI hooks were written but verification failed.");let l=0;for(let[c]of O){let a=u.hooks[c];if(!Array.isArray(a))throw new Error("GitHub Copilot CLI hooks were written but verification failed.");l+=a.filter(Z).length}if(l!==O.length)throw new Error("GitHub Copilot CLI hooks were written but verification failed.");return{hooksFile:t,changed:!0,hookCount:O.length}}import{existsSync as To,mkdirSync as Mo,readFileSync as No,renameSync as Jo,rmSync as $o,writeFileSync as Do}from"node:fs";import{dirname as _o}from"node:path";function S(o){return typeof o=="object"&&o!==null&&!Array.isArray(o)}function _(o,t){if(!To(o))return{};let e=No(o,"utf8").trim();if(!e)return{};let r;try{r=JSON.parse(e)}catch(n){throw new Error(`Invalid existing ${t} MCP config: ${n instanceof Error?n.message:String(n)}`)}if(!S(r))throw new Error(`Invalid existing ${t} MCP config: root must be a JSON object.`);return r}function oo(o,t){Mo(_o(o),{recursive:!0,mode:448});let e=`${o}.tmp-${process.pid}-${Date.now()}`;try{Do(e,`${JSON.stringify(t,null,2)}
3
+ `,{encoding:"utf8",mode:384}),Jo(e,o)}finally{$o(e,{force:!0})}}function to(o,t){return S(o)?(o.type===void 0||o.type==="local"||o.type==="stdio")&&o.command===t&&Array.isArray(o.args)&&o.args.length===1&&o.args[0]==="mcp"&&Array.isArray(o.tools)&&o.tools.length===1&&o.tools[0]==="*":!1}function G(o={}){let t=o.configFile??k(),e=o.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",r=o.serverName??"toolnet-memory",n=_(t,"GitHub Copilot CLI"),i=n.mcpServers;if(i!==void 0&&!S(i))throw new Error("Invalid existing GitHub Copilot CLI MCP config: mcpServers must be an object.");let s=S(i)?{...i}:{};if(to(s[r],e))return{installed:!0,changed:!1,configFile:t,serverName:r,command:e,args:["mcp"]};s[r]={type:"stdio",command:e,args:["mcp"],tools:["*"]},oo(t,{...n,mcpServers:s});let l=_(t,"GitHub Copilot CLI").mcpServers;if(!S(l)||!to(l[r],e))throw new Error("GitHub Copilot CLI MCP configuration was written but verification failed.");return{installed:!0,changed:!0,configFile:t,serverName:r,command:e,args:["mcp"]}}import{mkdirSync as Go,readFileSync as eo,renameSync as Lo,rmSync as qo,writeFileSync as Uo}from"node:fs";import{dirname as Bo}from"node:path";var v=`---
4
+ applyTo: "**"
7
5
  ---
8
6
 
9
- # ToolNet Continuity
7
+ # ToolNet Memory project continuity
10
8
 
11
- When the user asks to continue or resume previous work:
9
+ Use ToolNet Memory as the continuity source for this repository.
12
10
 
13
- 1. Use the ToolNet Memory MCP server as the continuity source.
14
- 2. Invoke \`memory_agent_ask\` before exploring old history if the current
15
- ToolNet handoff is missing, stale, or ambiguous.
16
- 3. Prefer \`mode="local"\` for current task, last file, blocker, completed
17
- work, TODOs, and next action.
18
- 4. Use \`mode="ai"\` only when continuity requires synthesis.
19
- 5. Do not reconstruct previous work from:
20
- - \`.toolnet/sessions/**\`
21
- - ToolNet \`events.jsonl\` or \`state.json\`
22
- - raw transcripts
23
- - another coding agent's private session/history files
24
- 6. After ToolNet continuity is known, verify current git and repository
25
- source truth before changing code.
26
- 7. Do not ask the user to repeat context ToolNet already provides.
11
+ - When the user asks to continue, resume, pick up, finish unfinished work,
12
+ or asks where work stopped, recover ToolNet continuity before reconstructing
13
+ state from chat/session history.
14
+ - Use the ToolNet MCP server and \`memory_agent_ask\` when fast project context
15
+ is missing, stale, or ambiguous.
16
+ - Prefer \`mode="local"\` for current task, current file, blockers, TODOs,
17
+ completed work, and next action.
18
+ - Use \`mode="ai"\` only when continuity needs synthesis.
19
+ - Do not reconstruct continuity by reading:
20
+ - \`.toolnet/sessions/**\`
21
+ - ToolNet raw \`events.jsonl\`
22
+ - ToolNet raw \`state.json\`
23
+ - another coding agent's private transcript/history files.
24
+ - After continuity is recovered, verify current repository source and git
25
+ state before changing code.
26
+ - Do not ask the user to repeat context ToolNet already provides.
27
27
 
28
28
  Current repository evidence overrides stale memory.
29
- `;function Ko(o,r){Uo(Vo(o),{recursive:!0,mode:448});let n=`${o}.toolnet-${process.pid}-${Date.now()}.tmp`;try{Yo(n,r,{encoding:"utf8",mode:384}),Bo(n,o)}finally{Wo(n,{force:!0})}}function so(o={}){let r=o.skillFile??M();if(Do(r)&&io(r,"utf8")===D)return{skillFile:r,changed:!1};if(Ko(r,D),io(r,"utf8")!==D)throw new Error("Grok ToolNet continuity skill was written but verification failed.");return{skillFile:r,changed:!0}}var v=[["SessionStart",10],["UserPromptSubmit",10],["PreToolUse",10],["PostToolUse",15],["Stop",30]];function co(o){return!f(o)||!Array.isArray(o.hooks)?!1:o.hooks.some(r=>f(r)&&typeof r.command=="string"&&r.command.includes("session:grok-hook"))}function qo(o,r,n){let t={hooks:[{type:"command",command:`${r} session:grok-hook`,timeout:n,env:{TOOLNET_HOOK_EVENT:o}}]};return o==="PreToolUse"&&(t.matcher=".*"),t}function lo(o={}){let r=o.hooksFile??J(),n=o.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",t=k(r,"Grok Build"),e=t.hooks;if(e!==void 0&&!f(e))throw new Error("Invalid existing Grok Build hooks file: hooks must be an object.");let s=f(e)?{...e}:{};for(let[l,c]of v){let a=s[l];if(a!==void 0&&!Array.isArray(a))throw new Error(`Invalid existing Grok Build hooks file: hooks.${l} must be an array.`);let m=Array.isArray(a)?a.filter(p=>!co(p)):[];s[l]=[...m,qo(l,n,c)]}let i={...t,hooks:s};if(JSON.stringify(t)===JSON.stringify(i))return{hooksFile:r,changed:!1,hookCount:v.length};C(r,i);let g=k(r,"Grok Build");if(!f(g.hooks))throw new Error("Grok Build hooks were written but verification failed.");let u=0;for(let[l]of v){let c=g.hooks[l];if(!Array.isArray(c))throw new Error("Grok Build hooks were written but verification failed.");u+=c.filter(co).length}if(u!==v.length)throw new Error("Grok Build hooks were written but verification failed.");return{hooksFile:r,changed:!0,hookCount:v.length}}import{existsSync as zo,mkdirSync as Qo,readFileSync as Xo,renameSync as Zo,rmSync as or,writeFileSync as rr}from"node:fs";import{dirname as nr}from"node:path";function ao(o){return zo(o)?Xo(o,"utf8"):""}function tr(o,r){Qo(nr(o),{recursive:!0,mode:448});let n=`${o}.tmp-${process.pid}-${Date.now()}`;try{rr(n,r,{encoding:"utf8",mode:384}),Zo(n,o)}finally{or(n,{force:!0})}}function U(o){return o.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t")}function er(o){return`[mcp_servers."${U(o)}"]`}function ir(o,r){return[er(o),`command = "${U(r)}"`,'args = ["mcp"]',"enabled = true"].join(`
30
- `)}function sr(o){let r=o.trim();return r.startsWith("[")&&r.includes("]")}function G(o){return o.trim().replace(/\s+/g,"")}function cr(o){return new Set([G(`[mcp_servers.${o}]`),G(`[mcp_servers."${o}"]`),G(`[mcp_servers.'${o}']`)])}function uo(o,r){let n=o.split(/\r?\n/),t=cr(r),e=-1;for(let c=0;c<n.length;c+=1){let a=G(n[c].replace(/\s+#.*$/,""));if(t.has(a)){e=c;break}}if(e<0)return null;let s=n.length;for(let c=e+1;c<n.length;c+=1)if(sr(n[c])){s=c;break}let i=[],g=0;for(let c of n)i.push(g),g+=c.length+1;let u=i[e]??0,l=s>=n.length?o.length:i[s]??o.length;return{start:u,end:l}}function lr(o,r,n){let t=`${ir(r,n)}
31
- `,e=uo(o,r);if(e){let s=o.slice(0,e.start),i=o.slice(e.end);return`${s}${t}${i.replace(/^\n+/,"")}`}return o.trim()?`${o.replace(/\s*$/,"")}
32
-
33
- ${t}`:t}function go(o,r,n){let t=uo(o,r);if(!t)return!1;let e=o.slice(t.start,t.end);return e.includes(`command = "${U(n)}"`)&&/args\s*=\s*\[\s*"mcp"\s*\]/.test(e)&&/enabled\s*=\s*true/.test(e)}function fo(o={}){let r=o.configFile??$(),n=o.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",t=o.serverName??"toolnet-memory",e=ao(r);if(go(e,t,n))return{installed:!0,changed:!1,configFile:r,serverName:t,command:n,args:["mcp"]};let s=lr(e,t,n);tr(r,s);let i=ao(r);if(!go(i,t,n))throw new Error("Grok Build MCP configuration was written but verification failed.");return{installed:!0,changed:!0,configFile:r,serverName:t,command:n,args:["mcp"]}}function mo(o={}){let r=o.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",n=fo({binary:r,configFile:o.configFile}),t=lo({binary:r,hooksFile:o.hooksFile}),e=so({skillFile:o.skillFile});return{installed:n.installed,changed:n.changed||t.changed||e.changed,mcp:n,hooks:t,skill:e,files:[n.configFile,t.hooksFile,e.skillFile]}}import{existsSync as O,readFileSync as W}from"node:fs";function h(o){return typeof o=="object"&&o!==null&&!Array.isArray(o)}function x(o){if(!O(o))return{};try{let r=JSON.parse(W(o,"utf8"));return h(r)?{value:r}:{error:"root must be a JSON object"}}catch(r){return{error:r instanceof Error?r.message:String(r)}}}function po(o,r){if(!o||!h(o.mcpServers))return!1;let n=o.mcpServers["toolnet-memory"];return!h(n)||typeof n.command!="string"||!n.command.trim()||!Array.isArray(n.args)||n.args.length!==1||n.args[0]!=="mcp"?!1:!r||Array.isArray(n.tools)&&n.tools.includes("*")}function ko(o,r,n){if(!o||!h(o.hooks))return[];let t=o.hooks;return r.filter(e=>{let s=t[e];return Array.isArray(s)&&s.some(i=>h(i)&&(typeof i.command=="string"&&i.command.includes(n)||typeof i.bash=="string"&&i.bash.includes(n)))})}function ar(o,r){if(!o||!h(o.hooks))return[];let n=o.hooks;return r.filter(t=>{let e=n[t];return Array.isArray(e)&&e.some(s=>!h(s)||!Array.isArray(s.hooks)?!1:s.hooks.some(i=>h(i)&&typeof i.command=="string"&&i.command.includes("session:grok-hook")))})}function gr(o){if(!O(o))return!1;let r=W(o,"utf8"),n=/\[mcp_servers\.(?:"toolnet-memory"|'toolnet-memory'|toolnet-memory)\]/,t=r.search(n);if(t<0)return!1;let e=r.slice(t),s=e.slice(1).search(/\n\s*\[[^\]]+\]/),i=s>=0?e.slice(0,s+1):e;return/command\s*=\s*"[^"]+"/.test(i)&&/args\s*=\s*\[\s*"mcp"\s*\]/.test(i)&&!/enabled\s*=\s*false/.test(i)}function B(o){let r=[];o.mcpError&&r.push(`MCP config: ${o.mcpError}`),o.hookError&&r.push(`Hooks config: ${o.hookError}`);let n=o.mcpConfigured&&o.hooksConfigured&&(o.skill?.configured??!0),t=O(o.configFile)||O(o.hooksFile)||(o.skill?O(o.skill.skillFile):!1),e=r.length>0?"invalid":n?"ready":t?"partial":"not-installed";return{installed:n,state:e,mcp:{configured:o.mcpConfigured,configFile:o.configFile,error:o.mcpError},hooks:{configured:o.hooksConfigured,hooksFile:o.hooksFile,events:o.events,error:o.hookError},skill:o.skill,errors:r}}function Y(o,r={}){if(o==="cursor"){let l=["sessionStart","beforeSubmitPrompt","preToolUse","postToolUse","afterAgentResponse","stop"],c=r.configFile??I(),a=r.hooksFile??E(),m=x(c),p=x(a),w=p.error?[]:ko(p.value,l,"session:cursor-hook");return B({mcpConfigured:!m.error&&po(m.value,!1),configFile:c,mcpError:m.error,hooksConfigured:l.every(P=>w.includes(P)),hooksFile:a,events:w,hookError:p.error})}if(o==="copilot"){let l=["sessionStart","userPromptSubmitted","userPromptTransformed","preToolUse","postToolUse","agentStop"],c=r.configFile??j(),a=r.hooksFile??T(),m=x(c),p=x(a),w=p.error?[]:ko(p.value,l,"session:copilot-hook");return B({mcpConfigured:!m.error&&po(m.value,!0),configFile:c,mcpError:m.error,hooksConfigured:l.every(P=>w.includes(P)),hooksFile:a,events:w,hookError:p.error})}let n=["SessionStart","UserPromptSubmit","PreToolUse","PostToolUse","Stop"],t=r.configFile??$(),e=r.hooksFile??J(),s=r.skillFile??M(),i=x(e),g=i.error?[]:ar(i.value,n),u=O(s)&&W(s,"utf8").includes("memory_agent_ask");return B({mcpConfigured:gr(t),configFile:t,hooksConfigured:n.every(l=>g.includes(l)),hooksFile:e,events:g,hookError:i.error,skill:{configured:u,skillFile:s}})}var A={cursor:"Cursor CLI",copilot:"GitHub Copilot CLI",grok:"Grok Build"};function ho(o){let r=process.argv.slice(2),n=r.includes("--json");if(r.includes("--status")||r[0]==="status"){let i=Y(o);if(n)console.log(JSON.stringify(i,null,2));else{console.log(`${A[o]} Integration`),console.log("=".repeat(`${A[o]} Integration`.length)),console.log(""),console.log(`State : ${i.state}`),console.log(`MCP : ${i.mcp.configured?"ready":"missing"} \u2014 ${i.mcp.configFile}`),console.log(`Hooks : ${i.hooks.configured?"ready":"missing"} \u2014 ${i.hooks.hooksFile}`),i.skill&&console.log(`Skill : ${i.skill.configured?"ready":"missing"} \u2014 ${i.skill.skillFile}`),i.hooks.events.length>0&&console.log(`Events: ${i.hooks.events.join(", ")}`);for(let g of i.errors)console.log(`Error : ${g}`);console.log("")}i.installed||(process.exitCode=1);return}let e=o==="cursor"?X():o==="copilot"?eo():mo(),s=Y(o);if(!s.installed)throw new Error(`${A[o]} integration installation did not verify successfully (state=${s.state}).`);if(n){console.log(JSON.stringify({installed:!0,changed:e.changed,files:e.files,status:s},null,2));return}console.log(`\u2705 ${A[o]} integration installed`),console.log(`MCP: ${e.mcp.configFile}`),console.log(`Hooks: ${e.hooks.hooksFile}`),s.skill&&console.log(`Skill: ${s.skill.skillFile}`),console.log("Server: toolnet-memory")}try{ho("copilot")}catch(o){console.error(o instanceof Error?o.message:String(o)),process.exitCode=1}
29
+ `;function Ko(o,t){Go(Bo(o),{recursive:!0,mode:448});let e=`${o}.toolnet-${process.pid}-${Date.now()}.tmp`;try{Uo(e,t,{encoding:"utf8",mode:384}),Lo(e,o)}finally{qo(e,{force:!0})}}function ro(o){let t=o.instructionFile??H(o.projectRoot);try{if(eo(t,"utf8")===v)return{instructionFile:t,changed:!1}}catch{}if(Ko(t,v),eo(t,"utf8")!==v)throw new Error("Copilot ToolNet project instruction verification failed.");return{instructionFile:t,changed:!0}}import{spawnSync as Wo}from"node:child_process";import{existsSync as C,statSync as Xo}from"node:fs";import{dirname as Yo,join as zo,parse as Vo,resolve as q}from"node:path";function no(o){let t=q(o);if(!C(t))throw new Error(`Project path does not exist: ${t}`);if(!Xo(t).isDirectory())throw new Error(`Project path is not a directory: ${t}`);return t}function A(o){return zo(o,".toolnet","project.json")}function Qo(o){let t=q(o),e=Vo(t).root;for(;;){if(C(A(t)))return t;if(t===e)return;let r=Yo(t);if(r===t)return;t=r}}function L(o){let t=Wo("git",["rev-parse","--show-toplevel"],{cwd:o,encoding:"utf8",timeout:5e3});if(t.status!==0)return;let e=t.stdout.trim();return e?q(e):void 0}function I(o={}){let t=no(o.cwd??process.cwd());if(o.project){let n=no(o.project),i=A(n),s=L(n);return{root:n,source:"explicit",eligible:!0,toolnetProject:C(i),manifestFile:C(i)?i:void 0,gitRoot:s}}let e=Qo(t);if(e){let n=A(e);return{root:e,source:"toolnet",eligible:!0,toolnetProject:!0,manifestFile:n,gitRoot:L(e)}}let r=L(t);if(r){let n=A(r);return{root:r,source:"git",eligible:!0,toolnetProject:C(n),manifestFile:C(n)?n:void 0,gitRoot:r}}return{root:t,source:"cwd",eligible:!1,toolnetProject:!1}}function lo(o,t={}){let e=[],r=o.indexOf("--scope");if(r>=0){let i=o[r+1];if(i!=="global"&&i!=="project"&&i!=="both")throw new Error(`Invalid --scope value: ${String(i)}`);e.push(i)}o.includes("--global")&&e.push("global"),o.includes("--both")&&e.push("both");let n=Array.from(new Set(e));if(n.length>1)throw new Error(`Conflicting integration scopes: ${n.join(", ")}`);return n[0]??t.defaultScope??"global"}function io(o,t){return{install:o,effective:t}}function m(o,t){return{surface:o,global:io(t.globalInstall,t.effective==="global"||t.effective==="both"),project:io(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 Zo(o){return{mcp:m("mcp",{globalInstall:!0,projectInstall:!1,effective:"global"}),hooks:m("hooks",{globalInstall:!0,projectInstall:!1,effective:"global"}),work:m("work",{globalInstall:o==="grok",projectInstall:!1,effective:o==="grok"?"global":"none",note:o==="grok"?"Grok supports a global ToolNet continuity skill.":"Cursor/Copilot work instructions remain project-scoped."})}}function so(o){return{mcp:m("mcp",{globalInstall:!1,projectInstall:!0,effective:"project",trustRequired:!0}),hooks:m("hooks",{globalInstall:!1,projectInstall:!0,effective:"project",trustRequired:!0}),work:m("work",{globalInstall:!1,projectInstall:!0,effective:"project",trustRequired:!1,note:o==="cursor"?"Use .cursor/rules/toolnet-memory.mdc.":o==="copilot"?"Use .github/instructions/toolnet-memory.instructions.md.":"Use .grok/skills/toolnet-continuity/SKILL.md."})}}function co(o){return{mcp:m("mcp",{globalInstall:!0,projectInstall:!0,effective:"project",risk:o==="cursor"?"precedence-unverified":"shadowed-global",trustRequired:!0,note:o==="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:m("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:m("work",{globalInstall:o==="grok",projectInstall:!0,effective:"project",risk:o==="grok"?"shadowed-global":"none",trustRequired:!1,note:o==="cursor"?"Project rule is authoritative.":o==="copilot"?"Project instruction is authoritative.":"Project skill shadows the same-name global skill inside the project."})}}function E(o){let{agent:t,scope:e,project:r}=o;return(e==="project"||e==="both")&&(!r||!r.eligible)?{agent:t,requestedScope:e,project:r,surfaces:e==="both"?co(t):so(t),canInstall:!1,reason:"Project scope requires an explicit project, existing ToolNet project, or Git repository root."}:{agent:t,requestedScope:e,project:r,surfaces:e==="global"?Zo(t):e==="project"?so(t):co(t),canInstall:!0}}function ao(o){return!!(o?.mcp?.changed||o?.hooks?.changed||o?.instruction?.changed)}function uo(o={}){let t=o.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",e=o.scope??"global",r=e==="global"?void 0:I({project:o.projectRoot}),n=E({agent:"copilot",scope:e,project:r});if(!n.canInstall)throw new Error(n.reason??"Copilot project integration scope cannot be resolved.");let i,s;if((n.surfaces.mcp.global.install||n.surfaces.hooks.global.install||n.surfaces.work.global.install)&&(i={},n.surfaces.mcp.global.install&&(i.mcp=G({binary:t,configFile:o.configFile??k()})),n.surfaces.hooks.global.install&&(i.hooks=D({binary:t,hooksFile:o.hooksFile??h()}))),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.");s={},n.surfaces.mcp.project.install&&(s.mcp=G({binary:t,configFile:o.projectConfigFile??x(r.root)})),n.surfaces.hooks.project.install&&(s.hooks=D({binary:t,hooksFile:o.projectHooksFile??R(r.root)})),n.surfaces.work.project.install&&(s.instruction=ro({projectRoot:r.root,instructionFile:o.projectInstructionFile}))}let u=s?.mcp??i?.mcp,l=s?.hooks??i?.hooks;if(!u||!l)throw new Error("Copilot integration did not produce effective MCP/hooks.");let c=Array.from(new Set([i?.mcp?.configFile,i?.hooks?.hooksFile,i?.instruction?.instructionFile,s?.mcp?.configFile,s?.hooks?.hooksFile,s?.instruction?.instructionFile].filter(a=>typeof a=="string")));return{installed:!0,changed:ao(i)||ao(s),scope:e,plan:n,project:r,global:i,projectScope:s,mcp:u,hooks:l,instruction:s?.instruction,files:c}}import{existsSync as T,readFileSync as bo}from"node:fs";import{existsSync as P,readFileSync as W}from"node:fs";import{homedir as ot}from"node:os";import{join as U,resolve as Qt}from"node:path";function po(o={}){return o.cursorHome??U(o.home??ot(),".cursor")}function fo(o={}){return U(po(o),"mcp.json")}function go(o={}){return U(po(o),"hooks.json")}import{homedir as tt}from"node:os";import{join as j,resolve as ee}from"node:path";function B(o={}){return o.grokHome??process.env.GROK_HOME??j(o.home??tt(),".grok")}function mo(o={}){return j(B(o),"config.toml")}function et(o={}){return j(B(o),"hooks")}function ko(o={}){return j(et(o),"toolnet-memory.json")}function rt(o={}){return j(B(o),"skills")}function nt(o={}){return j(rt(o),"toolnet-continuity")}function ho(o={}){return j(nt(o),"SKILL.md")}function y(o){return typeof o=="object"&&o!==null&&!Array.isArray(o)}function w(o){if(!P(o))return{};try{let t=JSON.parse(W(o,"utf8"));return y(t)?{value:t}:{error:"root must be a JSON object"}}catch(t){return{error:t instanceof Error?t.message:String(t)}}}function yo(o,t){if(!o||!y(o.mcpServers))return!1;let e=o.mcpServers["toolnet-memory"];return!y(e)||typeof e.command!="string"||!e.command.trim()||!Array.isArray(e.args)||e.args.length!==1||e.args[0]!=="mcp"?!1:!t||Array.isArray(e.tools)&&e.tools.includes("*")}function jo(o,t,e){if(!o||!y(o.hooks))return[];let r=o.hooks;return t.filter(n=>{let i=r[n];return Array.isArray(i)&&i.some(s=>y(s)&&(typeof s.command=="string"&&s.command.includes(e)||typeof s.bash=="string"&&s.bash.includes(e)))})}function it(o,t){if(!o||!y(o.hooks))return[];let e=o.hooks;return t.filter(r=>{let n=e[r];return Array.isArray(n)&&n.some(i=>!y(i)||!Array.isArray(i.hooks)?!1:i.hooks.some(s=>y(s)&&typeof s.command=="string"&&s.command.includes("session:grok-hook")))})}function st(o){if(!P(o))return!1;let t=W(o,"utf8"),e=/\[mcp_servers\.(?:"toolnet-memory"|'toolnet-memory'|toolnet-memory)\]/,r=t.search(e);if(r<0)return!1;let n=t.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 K(o){let t=[];o.mcpError&&t.push(`MCP config: ${o.mcpError}`),o.hookError&&t.push(`Hooks config: ${o.hookError}`);let e=o.mcpConfigured&&o.hooksConfigured&&(o.skill?.configured??!0),r=P(o.configFile)||P(o.hooksFile)||(o.skill?P(o.skill.skillFile):!1),n=t.length>0?"invalid":e?"ready":r?"partial":"not-installed";return{installed:e,state:n,mcp:{configured:o.mcpConfigured,configFile:o.configFile,error:o.mcpError},hooks:{configured:o.hooksConfigured,hooksFile:o.hooksFile,events:o.events,error:o.hookError},skill:o.skill,errors:t}}function X(o,t={}){if(o==="cursor"){let c=["sessionStart","beforeSubmitPrompt","preToolUse","postToolUse","afterAgentResponse","stop"],a=t.configFile??fo(),p=t.hooksFile??go(),g=w(a),d=w(p),F=d.error?[]:jo(d.value,c,"session:cursor-hook");return K({mcpConfigured:!g.error&&yo(g.value,!1),configFile:a,mcpError:g.error,hooksConfigured:c.every(N=>F.includes(N)),hooksFile:p,events:F,hookError:d.error})}if(o==="copilot"){let c=["sessionStart","userPromptSubmitted","userPromptTransformed","preToolUse","postToolUse","agentStop"],a=t.configFile??k(),p=t.hooksFile??h(),g=w(a),d=w(p),F=d.error?[]:jo(d.value,c,"session:copilot-hook");return K({mcpConfigured:!g.error&&yo(g.value,!0),configFile:a,mcpError:g.error,hooksConfigured:c.every(N=>F.includes(N)),hooksFile:p,events:F,hookError:d.error})}let e=["SessionStart","UserPromptSubmit","PreToolUse","PostToolUse","Stop"],r=t.configFile??mo(),n=t.hooksFile??ko(),i=t.skillFile??ho(),s=w(n),u=s.error?[]:it(s.value,e),l=P(i)&&W(i,"utf8").includes("memory_agent_ask");return K({mcpConfigured:st(r),configFile:r,hooksConfigured:e.every(c=>u.includes(c)),hooksFile:n,events:u,hookError:s.error,skill:{configured:l,skillFile:i}})}function ct(o){let t=!1;try{t=bo(o,"utf8")===v}catch{t=!1}return{configured:t,instructionFile:o}}function lt(o){let t=V(o);if(!T(t))return{file:t,toolnetDefined:!1};try{let e=JSON.parse(bo(t,"utf8")),r=e.mcpServers&&typeof e.mcpServers=="object"&&!Array.isArray(e.mcpServers)?e.mcpServers:{};return{file:t,toolnetDefined:r["toolnet-memory"]!==void 0||r.toolnet!==void 0}}catch{return{file:t,toolnetDefined:!1}}}function at(o,t,e){return t.some(n=>n?.state==="invalid")?"invalid":o?"ready":t.some(n=>n&&(n.state==="partial"||n.state==="ready"||T(n.mcp.configFile)||T(n.hooks.hooksFile)))||!!(e&&T(e.instructionFile))?"partial":"not-installed"}function M(o={}){let t=o.scope??"global",e=t==="global"?void 0:I({project:o.projectRoot}),r=E({agent:"copilot",scope:t,project:e}),n=t==="global"||t==="both"?X("copilot",{configFile:o.globalConfigFile??k(),hooksFile:o.globalHooksFile??h()}):void 0,i;if((t==="project"||t==="both")&&e?.eligible){let p=ct(o.projectInstructionFile??H(e.root));i={...X("copilot",{configFile:o.projectConfigFile??x(e.root),hooksFile:o.projectHooksFile??R(e.root)}),instruction:p}}let s=t==="project"?!0:n?.installed===!0,u=t==="global"?!0:i?.installed===!0&&i.instruction.configured===!0,l=r.canInstall&&s&&u,c=e?.eligible?lt(e.root):null,a=[];return!r.canInstall&&r.reason&&a.push(r.reason),t==="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:l,state:at(l,[n,i],i?.instruction),requestedScope:t,plan:r,project:e,global:n,projectScope:i,dedupeReady:!0,trustRequired:t==="project"||t==="both",alternateProjectMcp:c,warnings:a}}function ut(o,t){let e=o.indexOf(t);return e>=0?o[e+1]:void 0}function pt(){let o=process.argv.slice(2);return o[0]==="install"?o.slice(1):o}function ft(o,t){let e=M({scope:o,projectRoot:t});console.log("GitHub Copilot CLI Integration"),console.log("=============================="),console.log(""),console.log(`State : ${e.state}`),console.log(`Scope : ${e.requestedScope}`),e.global&&(console.log(""),console.log("Global"),console.log(` MCP : ${e.global.mcp.configured?"ready":"missing"} \u2014 ${e.global.mcp.configFile}`),console.log(` Hooks : ${e.global.hooks.configured?"ready":"missing"} \u2014 ${e.global.hooks.hooksFile}`)),e.projectScope&&(console.log(""),console.log("Project"),console.log(` Root : ${e.project?.root??"-"}`),console.log(` MCP : ${e.projectScope.mcp.configured?"ready":"missing"} \u2014 ${e.projectScope.mcp.configFile}`),console.log(` Hooks : ${e.projectScope.hooks.configured?"ready":"missing"} \u2014 ${e.projectScope.hooks.hooksFile}`),console.log(` Instruction : ${e.projectScope.instruction.configured?"ready":"missing"} \u2014 ${e.projectScope.instruction.instructionFile}`),console.log(` Trust : ${e.trustRequired?"required":"n/a"}`)),console.log(""),console.log(`Dedupe: ${e.dedupeReady?"ready":"missing"}`);for(let r of e.warnings)console.log(`Note : ${r}`);console.log(""),e.installed||(process.exitCode=1)}function gt(){let o=pt(),t=o.includes("--json"),e=o.includes("--status")||o[0]==="status",r=lo(o),n=ut(o,"--project"),i=r==="global"?void 0:I({project:n});if(e){let l=M({scope:r,projectRoot:i?.root});if(t){console.log(JSON.stringify(l,null,2)),l.installed||(process.exitCode=1);return}ft(r,i?.root);return}let s=uo({scope:r,projectRoot:i?.root}),u=M({scope:r,projectRoot:i?.root});if(!u.installed)throw new Error(`GitHub Copilot CLI integration installation did not verify successfully (state=${u.state}).`);if(t){console.log(JSON.stringify({installed:!0,changed:s.changed,scope:s.scope,files:s.files,status:u},null,2));return}console.log("\u2705 GitHub Copilot CLI integration installed"),console.log(`Scope: ${r}`);for(let l of s.files)console.log(`File: ${l}`);r==="both"&&(console.log("Hook dedupe: enabled"),console.log("Project MCP precedence: project > global"),console.log("Project trust: required by Copilot CLI")),console.log("Server: toolnet-memory")}try{gt()}catch(o){console.error(o instanceof Error?o.message:String(o)),process.exitCode=1}