toolnet-memory 0.3.14 → 0.3.16
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/.env.example +0 -1
- package/.release-target +1 -1
- package/README.md +182 -6
- package/bin/toolnet-memory +5 -0
- package/bundle/agy-hook.js +71 -71
- package/bundle/agy.js +65 -65
- package/bundle/api.js +15 -15
- package/bundle/auto-integrate.js +28 -28
- package/bundle/background-refresh.js +7 -7
- package/bundle/claude-hook.js +51 -50
- package/bundle/codex-context.js +29 -28
- package/bundle/codex.js +77 -77
- package/bundle/context-runtime.js +44 -43
- package/bundle/context.js +15 -15
- package/bundle/continuity-certify.js +13 -13
- package/bundle/copilot-hook.js +88 -86
- package/bundle/copilot.js +4 -4
- package/bundle/cursor-hook.js +88 -86
- package/bundle/cursor.js +4 -4
- package/bundle/doctor.js +4 -4
- package/bundle/full-index.js +21 -21
- package/bundle/gc.js +3 -0
- package/bundle/graph-index.js +4 -4
- package/bundle/graph-ui.js +3 -3
- package/bundle/grok-hook.js +64 -63
- package/bundle/grok.js +5 -5
- package/bundle/handoff-refresh.js +10 -10
- package/bundle/help-cli.js +3 -3
- package/bundle/impact.js +4 -4
- package/bundle/incremental.js +5 -4
- package/bundle/init.js +38 -37
- package/bundle/integration-status.js +4 -4
- package/bundle/kiro-hook.js +93 -92
- package/bundle/learner.js +6 -6
- package/bundle/mcp.js +17 -17
- package/bundle/memory-agent.js +7 -7
- package/bundle/memory-query.js +7 -7
- package/bundle/opencode.js +84 -84
- package/bundle/project-manual.js +7 -7
- package/bundle/recovery-certify.js +15 -15
- package/bundle/runtime.js +13 -12
- package/bundle/semantic.js +5 -5
- package/bundle/snapshot.js +4 -4
- package/bundle/status-cli.js +4 -4
- package/bundle/toolnet-cli.js +60 -60
- package/bundle/work-continuity.js +7 -7
- package/package.json +21 -3
- package/release-manifest.json +104 -3
package/bundle/copilot.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{homedir as
|
|
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
|
|
3
|
-
`,{encoding:"utf8",mode:384}),Jo(e,o)}finally{
|
|
1
|
+
import{homedir as Io}from"node:os";import{join as f,resolve as z}from"node:path";function Y(o={}){return o.copilotHome??process.env.COPILOT_HOME??f(o.home??Io(),".copilot")}function y(o={}){return f(Y(o),"mcp-config.json")}function So(o={}){return f(Y(o),"hooks")}function j(o={}){return f(So(o),"toolnet-memory.json")}function J(o){return f(z(o),".github")}function x(o){return f(J(o),"mcp.json")}function X(o){return f(z(o),".mcp.json")}function Co(o){return f(J(o),"hooks")}function R(o){return f(Co(o),"toolnet-memory.json")}function Po(o){return f(J(o),"instructions")}function A(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 Ao}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(Ao(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 Eo(o){if(typeof o.command=="string")return o.command;if(typeof o.bash=="string")return o.bash}function Z(o){return b(o)&&Eo(o)?.includes("session:copilot-hook")===!0}function Ho(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??j(),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,Ho(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 I(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(!I(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 I(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??y(),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&&!I(i))throw new Error("Invalid existing GitHub Copilot CLI MCP config: mcpServers must be an object.");let s=I(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(!I(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 Ko}from"node:path";var v=`---
|
|
4
4
|
applyTo: "**"
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -26,4 +26,4 @@ Use ToolNet Memory as the continuity source for this repository.
|
|
|
26
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,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}
|
|
29
|
+
`;function Wo(o,t){Go(Ko(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??A(o.projectRoot);try{if(eo(t,"utf8")===v)return{instructionFile:t,changed:!1}}catch{}if(Wo(t,v),eo(t,"utf8")!==v)throw new Error("Copilot ToolNet project instruction verification failed.");return{instructionFile:t,changed:!0}}import{spawnSync as Bo}from"node:child_process";import{existsSync as S,statSync as Vo}from"node:fs";import{dirname as zo,join as Yo,parse as Xo,resolve as q}from"node:path";function no(o){let t=q(o);if(!S(t))throw new Error(`Project path does not exist: ${t}`);if(!Vo(t).isDirectory())throw new Error(`Project path is not a directory: ${t}`);return t}function E(o){return Yo(o,".toolnet","project.json")}function Qo(o){let t=q(o),e=Xo(t).root;for(;;){if(S(E(t)))return t;if(t===e)return;let r=zo(t);if(r===t)return;t=r}}function L(o){let t=Bo("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 C(o={}){let t=no(o.cwd??process.cwd());if(o.project){let n=no(o.project),i=E(n),s=L(n);return{root:n,source:"explicit",eligible:!0,toolnetProject:S(i),manifestFile:S(i)?i:void 0,gitRoot:s}}let e=Qo(t);if(e){let n=E(e);return{root:e,source:"toolnet",eligible:!0,toolnetProject:!0,manifestFile:n,gitRoot:L(e)}}let r=L(t);if(r){let n=E(r);return{root:r,source:"git",eligible:!0,toolnetProject:S(n),manifestFile:S(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 H(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:C({project:o.projectRoot}),n=H({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??y()})),n.surfaces.hooks.global.install&&(i.hooks=D({binary:t,hooksFile:o.hooksFile??j()}))),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 B}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 h,resolve as ee}from"node:path";function K(o={}){return o.grokHome??process.env.GROK_HOME??h(o.home??tt(),".grok")}function mo(o={}){return h(K(o),"config.toml")}function et(o={}){return h(K(o),"hooks")}function yo(o={}){return h(et(o),"toolnet-memory.json")}function rt(o={}){return h(K(o),"skills")}function nt(o={}){return h(rt(o),"toolnet-continuity")}function jo(o={}){return h(nt(o),"SKILL.md")}function k(o){return typeof o=="object"&&o!==null&&!Array.isArray(o)}function w(o){if(!P(o))return{};try{let t=JSON.parse(B(o,"utf8"));return k(t)?{value:t}:{error:"root must be a JSON object"}}catch(t){return{error:t instanceof Error?t.message:String(t)}}}function ko(o,t){if(!o||!k(o.mcpServers))return!1;let e=o.mcpServers["toolnet-memory"];return!k(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 ho(o,t,e){if(!o||!k(o.hooks))return[];let r=o.hooks;return t.filter(n=>{let i=r[n];return Array.isArray(i)&&i.some(s=>k(s)&&(typeof s.command=="string"&&s.command.includes(e)||typeof s.bash=="string"&&s.bash.includes(e)))})}function it(o,t){if(!o||!k(o.hooks))return[];let e=o.hooks;return t.filter(r=>{let n=e[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 st(o){if(!P(o))return!1;let t=B(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 W(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 V(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?[]:ho(d.value,c,"session:cursor-hook");return W({mcpConfigured:!g.error&&ko(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??y(),p=t.hooksFile??j(),g=w(a),d=w(p),F=d.error?[]:ho(d.value,c,"session:copilot-hook");return W({mcpConfigured:!g.error&&ko(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??yo(),i=t.skillFile??jo(),s=w(n),u=s.error?[]:it(s.value,e),l=P(i)&&B(i,"utf8").includes("memory_agent_ask");return W({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=X(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:C({project:o.projectRoot}),r=H({agent:"copilot",scope:t,project:e}),n=t==="global"||t==="both"?V("copilot",{configFile:o.globalConfigFile??y(),hooksFile:o.globalHooksFile??j()}):void 0,i;if((t==="project"||t==="both")&&e?.eligible){let p=ct(o.projectInstructionFile??A(e.root));i={...V("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:C({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}
|