@ornexus/neocortex 4.59.1 → 4.59.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/sbom.cdx.json +19 -19
- package/install.ps1 +1 -1
- package/install.sh +1 -1
- package/package.json +2 -2
- package/packages/client/dist/commands/invoke.d.ts +47 -0
- package/packages/client/dist/commands/invoke.js +30 -28
- package/packages/client/dist/continuity/invoke-hooks.d.ts +1 -0
- package/packages/client/dist/continuity/invoke-hooks.js +1 -1
- package/packages/client/dist/continuity/runner-bootstrap-policy.d.ts +50 -0
- package/packages/client/dist/continuity/runner-bootstrap-policy.js +1 -0
- package/packages/client/dist/continuity/sqlite-store.d.ts +5 -2
- package/packages/client/dist/continuity/sqlite-store.js +16 -16
- package/packages/client/dist/runner/binary.d.ts +68 -0
- package/packages/client/dist/runner/binary.js +1 -0
- package/packages/client/dist/runner/cli.d.ts +2 -13
- package/packages/client/dist/runner/cli.js +10 -10
- package/packages/client/dist/runner/scheduler.d.ts +70 -0
- package/packages/client/dist/runner/scheduler.js +7 -6
- package/packages/client/dist/state/state-json-repair.js +3 -3
- package/targets-stubs/antigravity/gemini.md +1 -1
- package/targets-stubs/antigravity/skill/SKILL.md +1 -1
- package/targets-stubs/claude-code/neocortex-root.agent.yaml +1 -1
- package/targets-stubs/claude-code/neocortex-root.md +2 -2
- package/targets-stubs/claude-code/neocortex.agent.yaml +1 -1
- package/targets-stubs/claude-code/neocortex.md +2 -2
- package/targets-stubs/codex/AGENTS.md +1 -1
- package/targets-stubs/cursor/agent.md +2 -2
- package/targets-stubs/gemini-cli/agent.md +2 -2
- package/targets-stubs/opencode/neocortex-root.md +1 -1
- package/targets-stubs/vscode/neocortex.agent.md +2 -2
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import{spawnSync as W}from"node:child_process";import{existsSync as w,mkdirSync as K,writeFileSync as X}from"node:fs";import{delimiter as V,dirname as Y,isAbsolute as _,join as u,resolve as G}from"node:path";const s=Object.freeze({OK:"continuity-ok",SCHEDULER_INSTALL_UNSAFE:"scheduler-install-unsafe",PRIMARY_USER_SCHEDULER_UNAVAILABLE:"primary-user-scheduler-unavailable",CRON_FALLBACK_SELECTED:"cron-fallback-selected",CRON_FALLBACK_NOT_ALLOWED:"cron-fallback-primary-scheduler-available",SCHEDULER_UNAVAILABLE:"scheduler-unavailable",SCHEDULER_COMMAND_FAILED:"scheduler-command-failed",RUNNER_BINARY_UNTRUSTED:"runner-binary-untrusted"}),F="neocortex-runner",$=`${F}.service`,E=`${F}.timer`,T="com.ornexus.neocortex.runner",Q=`${T}.plist`,k="NeocortexRunner",q="neocortex-runner-task.xml",z="runner.cron",Z=60;async function ge(e){const t=e.env??process.env,r=e.platform??process.platform,a=e.dryRun===!0,c=y(e.projectRoot??process.cwd()),n=y(e.executablePath??process.argv[1]),m=e.commandAvailable??(p=>H(p,t)),f=Ee(e.intervalSeconds??Z,10,1440*60),h=J({platform:r,env:t,strategy:e.strategy,allowCronFallback:e.allowCronFallback,commandAvailable:m,uid:e.uid}),d=me(e,n),i=[...h.blockers];(!c||!n)&&i.push(s.SCHEDULER_INSTALL_UNSAFE),d.trusted||i.push(s.SCHEDULER_INSTALL_UNSAFE,s.RUNNER_BINARY_UNTRUSTED);const l=h.selectedStrategy;l||i.push(s.SCHEDULER_UNAVAILABLE);const g=(e.command==="install"||e.command==="start"||e.command==="stop")&&i.length>0,U=A([...h.reasonCodes,...i,g?s.SCHEDULER_INSTALL_UNSAFE:s.OK]);if(g||!l||!c||!n)return{ok:!g&&!!l,command:e.command,platform:r,strategy:l,dryRun:a,manifestPaths:[],manifests:[],controlCommands:[],uninstallGuidance:l?v(l,M(l,t)):[],capability:j(h,i),reasonCodes:U,applied:!1,publicSafe:!0};const C=M(l,t),L=e.command==="install"?ee({strategy:l,paths:C,projectRoot:c,executablePath:n,intervalSeconds:f}):[],R=te(e.command,l,C);let b=!1,D=!0;const I=[];if(e.command==="install"&&!a){for(const p of L)K(Y(p.path),{recursive:!0}),X(p.path,p.content,"utf8");b=L.length>0}if(!a&&R.length>0){const p=e.commandRunner??pe;for(const O of R){if(O.manualOnly)continue;const x=p(O);x.ok?b=!0:(D=!1,I.push(x.reasonCode??s.SCHEDULER_COMMAND_FAILED))}}return{ok:D,command:e.command,platform:r,strategy:l,dryRun:a,manifestPaths:L.map(p=>p.path),manifests:L,controlCommands:R,uninstallGuidance:v(l,C),capability:j(h,i),reasonCodes:A([...U,...I,D?s.OK:s.SCHEDULER_COMMAND_FAILED]),applied:b,publicSafe:!0}}function J(e={}){const t=e.env??process.env,r=e.platform??process.platform,a=e.commandAvailable??(l=>H(l,t)),c=fe(r,t,e.uid),n=de(r),m=n?B(n,a):!1,f=r!=="win32"&&a("crontab"),h=e.allowCronFallback!==!1;let d=e.strategy;const i=[];return d||(n&&m?d=n:h&&f&&(d="cron-fallback",i.push(s.PRIMARY_USER_SCHEDULER_UNAVAILABLE,s.CRON_FALLBACK_SELECTED))),d==="cron-fallback"&&m&&(d=void 0,i.push(s.CRON_FALLBACK_NOT_ALLOWED)),d&&!B(d,a)&&(d!=="cron-fallback"||!f)&&(d=void 0),d||i.push(s.SCHEDULER_UNAVAILABLE),c.length>0&&i.push(...c),i.length===0&&i.push(s.OK),{platform:r,primaryStrategy:n,selectedStrategy:d,fallbackStrategy:f?"cron-fallback":void 0,primaryAvailable:m,cronFallbackAvailable:f,safeToInstall:c.length===0,blockers:c,reasonCodes:A(i),publicSafe:!0}}function ee(e){switch(e.strategy){case"systemd-user":return[{kind:"systemd-service",path:e.paths.systemdServicePath,content:oe(e.executablePath,e.projectRoot),publicSafe:!0},{kind:"systemd-timer",path:e.paths.systemdTimerPath,content:ce(e.intervalSeconds),publicSafe:!0}];case"launchd-user":return[{kind:"launchd-plist",path:e.paths.launchdPlistPath,content:ie(e.executablePath,e.projectRoot,e.intervalSeconds),publicSafe:!0}];case"windows-task-scheduler":return[{kind:"windows-task-xml",path:e.paths.windowsTaskXmlPath,content:le(e.executablePath,e.projectRoot,e.intervalSeconds),publicSafe:!0}];case"cron-fallback":return[{kind:"cron-snippet",path:e.paths.cronSnippetPath,content:ue(e.executablePath,e.projectRoot),publicSafe:!0}]}}function M(e,t){const r=he(t),a=y(t.XDG_CONFIG_HOME)??u(r,".config"),c=u(a,"systemd","user"),n=u(r,"Library","LaunchAgents"),m=y(t.APPDATA)??u(y(t.USERPROFILE)??r,"AppData","Roaming"),f=u(m,"Neocortex","Runner"),h=u(a,"neocortex");return{systemdServicePath:u(c,$),systemdTimerPath:u(c,E),launchdPlistPath:u(n,Q),windowsTaskXmlPath:u(f,q),cronSnippetPath:u(h,z)}}function te(e,t,r){return e==="doctor"?[]:e==="install"?re(t,r):e==="start"?ne(t,r):e==="stop"?se(t,r):ae(t,r)}function re(e,t){switch(e){case"systemd-user":return[o("systemctl",["--user","daemon-reload"]),o("systemctl",["--user","enable","--now",E])];case"launchd-user":return[o("launchctl",["load","-w",t.launchdPlistPath])];case"windows-task-scheduler":return[o("schtasks",["/Create","/TN",k,"/XML",t.windowsTaskXmlPath,"/F"])];case"cron-fallback":return[o("crontab",["-l","# append snippet from",t.cronSnippetPath],!0)]}}function ne(e,t){switch(e){case"systemd-user":return[o("systemctl",["--user","start",E])];case"launchd-user":return[o("launchctl",["load","-w",t.launchdPlistPath])];case"windows-task-scheduler":return[o("schtasks",["/Run","/TN",k])];case"cron-fallback":return[o("crontab",["-l","# ensure snippet from",t.cronSnippetPath,"is installed"],!0)]}}function se(e,t){switch(e){case"systemd-user":return[o("systemctl",["--user","stop",E])];case"launchd-user":return[o("launchctl",["unload","-w",t.launchdPlistPath])];case"windows-task-scheduler":return[o("schtasks",["/End","/TN",k])];case"cron-fallback":return[o("crontab",["-l","# remove neocortex-runner snippet"],!0)]}}function ae(e,t){switch(e){case"systemd-user":return[o("systemctl",["--user","status",E,"--no-pager"])];case"launchd-user":return[o("launchctl",["list",T])];case"windows-task-scheduler":return[o("schtasks",["/Query","/TN",k,"/FO","LIST"])];case"cron-fallback":return[o("crontab",["-l","# look for neocortex-runner snippet from",t.cronSnippetPath],!0)]}}function v(e,t){switch(e){case"systemd-user":return[`systemctl --user disable --now ${E}`,`rm ${t.systemdServicePath}`,`rm ${t.systemdTimerPath}`];case"launchd-user":return[`launchctl unload -w ${t.launchdPlistPath}`,`rm ${t.launchdPlistPath}`];case"windows-task-scheduler":return[`schtasks /Delete /TN ${k} /F`,`Remove-Item ${t.windowsTaskXmlPath}`];case"cron-fallback":return["Remove the # neocortex-runner snippet from the user crontab.",`rm ${t.cronSnippetPath}`]}}function oe(e,t){return["[Unit]","Description=Neocortex Enterprise Continuity Runner (user scope)","After=network-online.target","","[Service]","Type=oneshot",`WorkingDirectory=${N(t)}`,`ExecStart=${N(e)} tick --project-root ${N(t)}`,"","[Install]","WantedBy=default.target",""].join(`
|
|
2
|
-
`)}function
|
|
3
|
-
`)}function
|
|
4
|
-
`)}function
|
|
5
|
-
`)}function
|
|
6
|
-
`)}function
|
|
1
|
+
import{Buffer as le}from"node:buffer";import{spawnSync as ie}from"node:child_process";import{createHash as de}from"node:crypto";import{existsSync as j,mkdirSync as me,readFileSync as pe,writeFileSync as fe}from"node:fs";import{delimiter as he,dirname as ye,isAbsolute as $,join as c,resolve as z}from"node:path";import{checkRunnerBinaryTrust as Ee,resolveTrustedRunnerBinary as Q}from"./binary.js";const i=Object.freeze({OK:"continuity-ok",SCHEDULER_INSTALL_UNSAFE:"scheduler-install-unsafe",PRIMARY_USER_SCHEDULER_UNAVAILABLE:"primary-user-scheduler-unavailable",CRON_FALLBACK_SELECTED:"cron-fallback-selected",CRON_FALLBACK_NOT_ALLOWED:"cron-fallback-primary-scheduler-available",SCHEDULER_UNAVAILABLE:"scheduler-unavailable",SCHEDULER_COMMAND_FAILED:"scheduler-command-failed",RUNNER_BINARY_UNTRUSTED:"runner-binary-untrusted",LEGACY_GLOBAL_SCHEDULER_DETECTED:"legacy-global-scheduler-detected",LEGACY_GLOBAL_SCHEDULER_AMBIGUOUS:"legacy-global-scheduler-ambiguous",LEGACY_GLOBAL_SCHEDULER_OTHER_PROJECT:"legacy-global-scheduler-other-project"}),R=Object.freeze({OK:"runner-bootstrap-ok",ALREADY_ACTIVE:"runner-bootstrap-already-active",BINARY_UNAVAILABLE:"runner-bootstrap-binary-unavailable",INSTALL_FAILED:"runner-bootstrap-install-failed",START_FAILED:"runner-bootstrap-start-failed",UNEXPECTED_ERROR:"runner-bootstrap-unexpected-error"}),F="neocortex-runner",ge=`${F}.service`,N=`${F}.timer`,B="com.ornexus.neocortex.runner",Se=`${B}.plist`,M="NeocortexRunner",Ce="neocortex-runner-task.xml",Le="runner.cron",Ae=12,ke=24,Re=60,H=new Map;function K(e){const r=g(e)??z(e||"."),t=Je(r),n=de("sha256").update(t).digest("hex").slice(0,Ae),s=Ze(qe(t)),a=`${s}-${n}`,o=`${F}-${a}`,d=`com.ornexus.neocortex.runner.${a}`;return{projectKey:a,projectBasename:s,systemdServiceName:`${o}.service`,systemdTimerName:`${o}.timer`,systemdServiceFile:`${o}.service`,systemdTimerFile:`${o}.timer`,launchdLabel:d,launchdFile:`${d}.plist`,windowsTaskName:`NeocortexRunner-${a}`,windowsXmlFile:`${o}-task.xml`,cronFile:`runner-${a}.cron`,cronMarkerStart:`# BEGIN neocortex-runner:${a}`,cronMarkerEnd:`# END neocortex-runner:${a}`,publicSafe:!0}}function ir(){H.clear()}async function dr(e={}){const r=e.platform??process.platform,t=g(e.projectRoot??process.cwd())??process.cwd(),n=K(t),s=`${r}:${n.projectKey}`,a=H.get(s);if(a?.ok)return{...a,attempted:!1,installed:!1,started:!1,cached:!0,reasonCodes:S([...a.reasonCodes,R.ALREADY_ACTIVE]),publicSummary:"runner scheduler bootstrap already active for project key.",publicSafe:!0};try{const o=e.binaryResolver??Q,d=g(e.executablePath??process.argv[1])??process.argv[1],y=o({from:d,platform:r});if(!y.ok)return w({projectKey:n.projectKey,reasonCodes:[R.BINARY_UNAVAILABLE,...y.reasonCodes],publicSummary:"runner scheduler bootstrap could not resolve a trusted runner binary."});const l=be(e.env??process.env),E={...e,projectRoot:t,executablePath:y.executablePath,platform:r,env:l,binaryResolver:()=>y},p=await J({...E,command:"install"});if(!p.ok)return w({projectKey:n.projectKey,strategy:p.strategy,reasonCodes:[R.INSTALL_FAILED,...p.reasonCodes],publicSummary:"runner scheduler bootstrap install failed.",attempted:!0});const f=await J({...E,command:"start"});if(!f.ok)return w({projectKey:n.projectKey,strategy:f.strategy??p.strategy,reasonCodes:[R.START_FAILED,...f.reasonCodes],publicSummary:"runner scheduler bootstrap start failed.",attempted:!0,installed:p.applied||p.ok});const L={ok:!0,attempted:!0,installed:p.applied||p.ok,started:f.applied||f.ok,cached:!1,projectKey:n.projectKey,strategy:f.strategy??p.strategy,reasonCodes:S([R.OK,...p.reasonCodes,...f.reasonCodes]),publicSummary:"runner scheduler bootstrap completed for project key.",publicSafe:!0};return H.set(s,L),L}catch{return w({projectKey:n.projectKey,reasonCodes:[R.UNEXPECTED_ERROR],publicSummary:"runner scheduler bootstrap stopped unexpectedly."})}}function w(e){return{ok:!1,attempted:e.attempted??!1,installed:e.installed??!1,started:!1,cached:!1,projectKey:e.projectKey,strategy:e.strategy,reasonCodes:S(e.reasonCodes),publicSummary:e.publicSummary,publicSafe:!0}}function be(e){return{...e,NEOCORTEX_RUNNER_BOOTSTRAP_IN_PROGRESS:"1",NEOCORTEX_BOOTSTRAP_IN_PROGRESS:"1"}}async function J(e){const r=e.env??process.env,t=e.platform??process.platform,n=e.dryRun===!0,s=g(e.projectRoot??process.cwd()),a=g(e.executablePath??process.argv[1]),o=ze(e,a,t),d=o.runnerCommand,y=d?.executablePath??a,l=K(s??process.cwd()),E=e.commandAvailable??(h=>te(h,r)),p=tr(e.intervalSeconds??Re,10,1440*60),f=_e({platform:t,env:r,strategy:e.strategy,allowCronFallback:e.allowCronFallback,commandAvailable:E,uid:e.uid}),L=Qe(e,y,o.resolution),A=[...f.blockers];if((!s||!d)&&A.push(i.SCHEDULER_INSTALL_UNSAFE),!L.trusted){const h=L.reasonCodes&&L.reasonCodes.length>0?L.reasonCodes:[L.reasonCode??i.RUNNER_BINARY_UNTRUSTED];A.push(i.SCHEDULER_INSTALL_UNSAFE,i.RUNNER_BINARY_UNTRUSTED,...h)}const m=f.selectedStrategy;m||A.push(i.SCHEDULER_UNAVAILABLE);const k=m?Ne(m,r,l):void 0,b=m&&s&&Ke(e.command)?Ge({strategy:m,env:r,projectRoot:s}):[],ue=b.flatMap(h=>h.reasonCodes),v=(e.command==="install"||e.command==="start"||e.command==="stop")&&A.length>0,Y=S([...f.reasonCodes,...A,...ue,v?i.SCHEDULER_INSTALL_UNSAFE:i.OK]);if(v||!m||!k||!s||!d)return{ok:!v&&!!m,command:e.command,platform:t,strategy:m,dryRun:n,manifestPaths:[],manifests:[],identity:l,legacyEntries:b,controlCommands:[],uninstallGuidance:m&&k?Z(m,k,l):[],capability:ne(f,A),reasonCodes:Y,applied:!1,publicSafe:!0};const T=e.command==="install"?Te({strategy:m,paths:k,projectRoot:s,executablePath:d.command,runnerCommand:d,intervalSeconds:p,identity:l}):[],U=we(e.command,m,k,l,b,r);let I=!1,x=!0;const X=[];if(e.command==="install"&&!n){for(const h of T)me(ye(h.path),{recursive:!0}),fe(h.path,h.content,"utf8");I=T.length>0}if(!n&&U.length>0){const h=e.commandRunner??er;for(const V of U){if(V.manualOnly)continue;const W=h(V);W.ok?I=!0:(x=!1,X.push(W.reasonCode??i.SCHEDULER_COMMAND_FAILED))}}return{ok:x,command:e.command,platform:t,strategy:m,dryRun:n,manifestPaths:T.map(h=>h.path),manifests:T,identity:l,legacyEntries:b,controlCommands:U,uninstallGuidance:[...Z(m,k,l),...je(m,b)],capability:ne(f,A),reasonCodes:S([...Y,...X,x?i.OK:i.SCHEDULER_COMMAND_FAILED]),applied:I,publicSafe:!0}}function _e(e={}){const r=e.env??process.env,t=e.platform??process.platform,n=e.commandAvailable??(p=>te(p,r)),s=We(t,r,e.uid),a=Ve(t),o=a?ee(a,n):!1,d=t!=="win32"&&n("crontab"),y=e.allowCronFallback!==!1;let l=e.strategy;const E=[];return l||(a&&o?l=a:y&&d&&(l="cron-fallback",E.push(i.PRIMARY_USER_SCHEDULER_UNAVAILABLE,i.CRON_FALLBACK_SELECTED))),l==="cron-fallback"&&o&&(l=void 0,E.push(i.CRON_FALLBACK_NOT_ALLOWED)),l&&!ee(l,n)&&(l!=="cron-fallback"||!d)&&(l=void 0),l||E.push(i.SCHEDULER_UNAVAILABLE),s.length>0&&E.push(...s),E.length===0&&E.push(i.OK),{platform:t,primaryStrategy:a,selectedStrategy:l,fallbackStrategy:d?"cron-fallback":void 0,primaryAvailable:o,cronFallbackAvailable:d,safeToInstall:s.length===0,blockers:s,reasonCodes:S(E),publicSafe:!0}}function Te(e){const r=e.identity??K(e.projectRoot),t=e.runnerCommand??{command:e.executablePath,args:[],executablePath:e.executablePath,publicSafe:!0};switch(e.strategy){case"systemd-user":return[{kind:"systemd-service",path:e.paths.systemdServicePath,content:$e(t,e.projectRoot,r),publicSafe:!0},{kind:"systemd-timer",path:e.paths.systemdTimerPath,content:Fe(e.intervalSeconds,r),publicSafe:!0}];case"launchd-user":return[{kind:"launchd-plist",path:e.paths.launchdPlistPath,content:Be(t,e.projectRoot,e.intervalSeconds,r),publicSafe:!0}];case"windows-task-scheduler":return[{kind:"windows-task-xml",path:e.paths.windowsTaskXmlPath,content:Me(t,e.projectRoot,e.intervalSeconds,r),publicSafe:!0}];case"cron-fallback":return[{kind:"cron-snippet",path:e.paths.cronSnippetPath,content:He(t,e.projectRoot,r),publicSafe:!0}]}}function Ne(e,r,t){const n=re(r),s=g(r.XDG_CONFIG_HOME)??c(n,".config"),a=c(s,"systemd","user"),o=c(n,"Library","LaunchAgents"),d=g(r.APPDATA)??c(g(r.USERPROFILE)??n,"AppData","Roaming"),y=c(d,"Neocortex","Runner"),l=c(s,"neocortex");return{systemdServicePath:c(a,t.systemdServiceFile),systemdTimerPath:c(a,t.systemdTimerFile),launchdPlistPath:c(o,t.launchdFile),windowsTaskXmlPath:c(y,t.windowsXmlFile),cronSnippetPath:c(l,t.cronFile)}}function q(e,r){const t=re(r),n=g(r.XDG_CONFIG_HOME)??c(t,".config"),s=c(n,"systemd","user"),a=c(t,"Library","LaunchAgents"),o=g(r.APPDATA)??c(g(r.USERPROFILE)??t,"AppData","Roaming"),d=c(o,"Neocortex","Runner"),y=c(n,"neocortex");return{systemdServicePath:c(s,ge),systemdTimerPath:c(s,N),launchdPlistPath:c(a,Se),windowsTaskXmlPath:c(d,Ce),cronSnippetPath:c(y,Le)}}function we(e,r,t,n,s,a){return e==="doctor"?[]:[...e==="install"?De(r,t,n):e==="start"?Pe(r,t,n):e==="stop"?Oe(r,t,n):ve(r,t,n),...Ue(e,r,s,a)]}function De(e,r,t){switch(e){case"systemd-user":return[u("systemctl",["--user","daemon-reload"]),u("systemctl",["--user","enable","--now",t.systemdTimerName])];case"launchd-user":return[u("launchctl",["load","-w",r.launchdPlistPath])];case"windows-task-scheduler":return[u("schtasks",["/Create","/TN",t.windowsTaskName,"/XML",r.windowsTaskXmlPath,"/F"])];case"cron-fallback":return[u("crontab",["-l","# append snippet from",r.cronSnippetPath],!0)]}}function Pe(e,r,t){switch(e){case"systemd-user":return[u("systemctl",["--user","start",t.systemdTimerName])];case"launchd-user":return[u("launchctl",["load","-w",r.launchdPlistPath])];case"windows-task-scheduler":return[u("schtasks",["/Run","/TN",t.windowsTaskName])];case"cron-fallback":return[u("crontab",["-l","# ensure snippet from",r.cronSnippetPath,"is installed"],!0)]}}function Oe(e,r,t){switch(e){case"systemd-user":return[u("systemctl",["--user","stop",t.systemdTimerName])];case"launchd-user":return[u("launchctl",["unload","-w",r.launchdPlistPath])];case"windows-task-scheduler":return[u("schtasks",["/End","/TN",t.windowsTaskName])];case"cron-fallback":return[u("crontab",["-l","# remove scoped neocortex-runner snippet"],!0)]}}function ve(e,r,t){switch(e){case"systemd-user":return[u("systemctl",["--user","status",t.systemdTimerName,"--no-pager"])];case"launchd-user":return[u("launchctl",["list",t.launchdLabel])];case"windows-task-scheduler":return[u("schtasks",["/Query","/TN",t.windowsTaskName,"/FO","LIST"])];case"cron-fallback":return[u("crontab",["-l","# look for neocortex-runner snippet from",r.cronSnippetPath],!0)]}}function Z(e,r,t){switch(e){case"systemd-user":return[`systemctl --user disable --now ${t.systemdTimerName}`,`rm ${r.systemdServicePath}`,`rm ${r.systemdTimerPath}`];case"launchd-user":return[`launchctl unload -w ${r.launchdPlistPath}`,`rm ${r.launchdPlistPath}`];case"windows-task-scheduler":return[`schtasks /Delete /TN ${t.windowsTaskName} /F`,`Remove-Item ${r.windowsTaskXmlPath}`];case"cron-fallback":return[`Remove the ${t.cronMarkerStart} block from the user crontab.`,`rm ${r.cronSnippetPath}`]}}function Ue(e,r,t,n){if(!t.some(o=>o.relation==="current-project")||e!=="status"&&e!=="stop")return[];const a=q(r,n);return e==="status"?Ie(r,a):xe(r,a)}function Ie(e,r){switch(e){case"systemd-user":return[u("systemctl",["--user","status",N,"--no-pager"])];case"launchd-user":return[u("launchctl",["list",B])];case"windows-task-scheduler":return[u("schtasks",["/Query","/TN",M,"/FO","LIST"])];case"cron-fallback":return[u("crontab",["-l","# look for legacy neocortex-runner snippet from",r.cronSnippetPath],!0)]}}function xe(e,r){switch(e){case"systemd-user":return[u("systemctl",["--user","stop",N])];case"launchd-user":return[u("launchctl",["unload","-w",r.launchdPlistPath])];case"windows-task-scheduler":return[u("schtasks",["/End","/TN",M])];case"cron-fallback":return[u("crontab",["-l","# remove legacy neocortex-runner snippet"],!0)]}}function je(e,r){if(r.length===0)return[];const t=r.filter(o=>o.relation==="current-project"),n=r.filter(o=>o.relation==="ambiguous"),s=r.filter(o=>o.relation==="other-project"),a=[];return t.length>0&&a.push(`Legacy global ${e} scheduler matches this project; stop it before relying on project-scoped runner scheduling.`),n.length>0&&a.push(`Legacy global ${e} scheduler ownership is ambiguous; inspect it manually before removal.`),s.length>0&&a.push(`Legacy global ${e} scheduler appears to belong to another project; leave it unchanged.`),a}function $e(e,r,t){const n=[e.command,...e.args,"tick","--project-root",r].map(se).join(" ");return["[Unit]",`Description=Neocortex Enterprise Continuity Runner (${t.projectKey}, user scope)`,`# Managed by Neocortex runner for project ${t.projectKey}`,"After=network-online.target","","[Service]","Type=oneshot",`WorkingDirectory=${oe(r)}`,`ExecStart=${n}`,"","[Install]","WantedBy=default.target",""].join(`
|
|
2
|
+
`)}function Fe(e,r){return["[Unit]",`Description=Run Neocortex Enterprise Continuity Runner periodically (${r.projectKey}, user scope)`,`# Managed by Neocortex runner for project ${r.projectKey}`,"","[Timer]","OnBootSec=60s",`OnUnitActiveSec=${e}s`,`Unit=${r.systemdServiceName}`,"","[Install]","WantedBy=timers.target",""].join(`
|
|
3
|
+
`)}function Be(e,r,t,n){const s=[e.command,...e.args,"tick","--project-root",r];return['<?xml version="1.0" encoding="UTF-8"?>','<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">','<plist version="1.0">',"<dict>",` <!-- Managed by Neocortex runner for project ${C(n.projectKey)} -->`," <key>Label</key>",` <string>${C(n.launchdLabel)}</string>`," <key>ProgramArguments</key>"," <array>",...s.map(a=>` <string>${C(a)}</string>`)," </array>"," <key>WorkingDirectory</key>",` <string>${C(r)}</string>`," <key>StartInterval</key>",` <integer>${t}</integer>`," <key>RunAtLoad</key>"," <true/>","</dict>","</plist>",""].join(`
|
|
4
|
+
`)}function Me(e,r,t,n){const s=[...e.args,"tick","--project-root",r].map(ce).join(" ");return['<?xml version="1.0" encoding="UTF-16"?>','<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">'," <RegistrationInfo>",` <Description>Neocortex Enterprise Continuity Runner (${C(n.projectKey)}, user scope)</Description>`," </RegistrationInfo>"," <Triggers>"," <TimeTrigger>"," <Repetition>",` <Interval>PT${t}S</Interval>`," <StopAtDurationEnd>false</StopAtDurationEnd>"," </Repetition>"," <Enabled>true</Enabled>"," </TimeTrigger>"," </Triggers>"," <Principals>",' <Principal id="Author">'," <LogonType>InteractiveToken</LogonType>"," <RunLevel>LeastPrivilege</RunLevel>"," </Principal>"," </Principals>"," <Settings>"," <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>"," <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>"," <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>"," <Enabled>true</Enabled>"," </Settings>",' <Actions Context="Author">'," <Exec>",` <Command>${C(e.command)}</Command>`,` <Arguments>${C(s)}</Arguments>`,` <WorkingDirectory>${C(r)}</WorkingDirectory>`," </Exec>"," </Actions>","</Task>",""].join(`
|
|
5
|
+
`)}function He(e,r,t){const n=[e.command,...e.args,"tick","--project-root",r].map(G).join(" ");return[t.cronMarkerStart,`# neocortex-runner user-scope cron fallback for project ${t.projectKey}`,"# Reason: primary-user-scheduler-unavailable",`* * * * * ${n} # neocortex-runner:${t.projectKey}`,t.cronMarkerEnd,""].join(`
|
|
6
|
+
`)}function Ke(e){return e==="status"||e==="stop"||e==="doctor"}function Ge(e){const r=q(e.strategy,e.env);switch(e.strategy){case"systemd-user":{const t=_(r.systemdServicePath),n=_(r.systemdTimerPath),s=t?O(t):!1,a=n?Xe(n):!1;if(!s&&!a)return[];const o=P([t,n].filter(Boolean).join(`
|
|
7
|
+
`),e.projectRoot,s);return[D(e.strategy,"systemd-timer",N,o)]}case"launchd-user":{const t=_(r.launchdPlistPath);return!t||!O(t)?[]:[D(e.strategy,"launchd-plist",B,P(t,e.projectRoot,!0))]}case"windows-task-scheduler":{const t=_(r.windowsTaskXmlPath);return!t||!O(t)?[]:[D(e.strategy,"windows-task-xml",M,P(t,e.projectRoot,!0))]}case"cron-fallback":{const t=_(r.cronSnippetPath);return!t||!O(t)?[]:[D(e.strategy,"cron-snippet","# neocortex-runner",P(t,e.projectRoot,!0))]}}}function D(e,r,t,n){const s=n==="current-project"?i.LEGACY_GLOBAL_SCHEDULER_DETECTED:n==="ambiguous"?i.LEGACY_GLOBAL_SCHEDULER_AMBIGUOUS:i.LEGACY_GLOBAL_SCHEDULER_OTHER_PROJECT;return{strategy:e,kind:r,name:t,relation:n,reasonCodes:[s],remediation:n==="current-project"?"stop-safe":n==="ambiguous"?"manual-review-only":"report-only",publicSafe:!0}}function P(e,r,t){return Ye(e,r)?"current-project":t&&/--project-root|WorkingDirectory=|<key>WorkingDirectory<\/key>|<Arguments>[^<]*--project-root/i.test(e)?"other-project":"ambiguous"}function Ye(e,r){return S([r,se(r),rr(r),oe(r),G(r),ce(r),C(r)].filter(Boolean)).some(n=>e.includes(n))}function O(e){return/neocortex-runner|com\.ornexus\.neocortex\.runner|NeocortexRunner|Neocortex Enterprise Continuity Runner/i.test(e)&&/tick|--project-root|StartInterval|OnUnitActiveSec|InteractiveToken|primary-user-scheduler-unavailable/i.test(e)}function Xe(e){return/neocortex-runner\.service|Neocortex Enterprise Continuity Runner|OnUnitActiveSec/i.test(e)}function _(e){try{return pe(e,"utf8")}catch{return null}}function Ve(e){if(e==="linux")return"systemd-user";if(e==="darwin")return"launchd-user";if(e==="win32")return"windows-task-scheduler"}function ee(e,r){switch(e){case"systemd-user":return r("systemctl");case"launchd-user":return r("launchctl");case"windows-task-scheduler":return r("schtasks")||r("schtasks.exe");case"cron-fallback":return r("crontab")}}function We(e,r,t){const n=[],s=t??(typeof process.getuid=="function"?process.getuid():null);e!=="win32"&&s===0&&n.push(i.SCHEDULER_INSTALL_UNSAFE),e!=="win32"&&(r.SUDO_USER||r.SUDO_UID||r.SUDO_COMMAND)&&n.push(i.SCHEDULER_INSTALL_UNSAFE);const a=r.HOME??r.USERPROFILE;return(!a||!$(a)||!g(a))&&n.push(i.SCHEDULER_INSTALL_UNSAFE),S(n)}function ze(e,r,t){if(e.trustCheck===!1||e.trustChecker)return{runnerCommand:r?{command:r,args:[],executablePath:r,publicSafe:!0}:void 0};const s=(e.binaryResolver??Q)({from:r??process.argv[1],platform:t});return s.ok?{runnerCommand:{command:s.command,args:s.args,executablePath:s.executablePath,provenance:s.provenance,publicSafe:!0},resolution:s}:{runnerCommand:r?{command:r,args:[],executablePath:r,provenance:s.provenance,publicSafe:!0}:void 0,resolution:s}}function Qe(e,r,t){return e.trustCheck===!1?{trusted:!0,executablePath:r??void 0,publicSafe:!0}:e.trustChecker?e.trustChecker(r??void 0):t?t.ok?{trusted:!0,packageName:t.packageName,packageVersion:t.packageVersion,packageRoot:t.packageRoot,executablePath:t.executablePath,expectedRelativePath:t.expectedRelativePath,provenance:t.provenance,reasonCodes:t.reasonCodes,publicSafe:!0}:{trusted:!1,reasonCode:t.reasonCode,reasonCodes:t.reasonCodes,packageName:t.packageName,packageVersion:t.packageVersion,packageRoot:t.packageRoot,executablePath:t.executablePath??r??void 0,expectedRelativePath:t.expectedRelativePath,provenance:t.provenance,publicSafe:!0}:Ee(r??void 0)}function re(e){return e.HOME??e.USERPROFILE??process.env.HOME??process.cwd()}function Je(e){let r=e.replace(/\\/g,"/").replace(/\/+$/g,"");return r||(r="/"),r=r.replace(/^([A-Z]):\//,(t,n)=>`${n.toLowerCase()}:/`),r}function qe(e){const r=e.split("/").filter(Boolean);return r[r.length-1]??"project"}function Ze(e){return e.normalize("NFKD").replace(/[\u0300-\u036f]/g,"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,ke).replace(/-+$/g,"")||"project"}function g(e){if(!e||/[\r\n\0]/.test(e))return null;const r=$(e)?e:z(e);return $(r)?r:null}function u(e,r,t=!1){return{command:e,args:r,preview:[e,...r.map(G)].join(" "),safeUserScope:!0,...t?{manualOnly:!0}:{}}}function er(e){const r=ie(e.command,[...e.args],{stdio:"ignore",shell:!1});return{ok:r.status===0,code:r.status,signal:r.signal,reasonCode:r.status===0?i.OK:i.SCHEDULER_COMMAND_FAILED}}function te(e,r){const t=r.PATH??process.env.PATH??"",n=(r.PATHEXT??".EXE;.CMD;.BAT;.COM").split(";").filter(Boolean),s=t.split(he).filter(Boolean);for(const a of s){const o=c(a,e);if(j(o))return!0;for(const d of n)if(j(c(a,`${e}${d.toLowerCase()}`))||j(c(a,`${e}${d.toUpperCase()}`)))return!0}return!1}function ne(e,r){const t=S([...e.blockers,...r]);return{...e,safeToInstall:t.length===0,blockers:t,reasonCodes:S([...e.reasonCodes,...t])}}function se(e){return ae(e,!0)}function rr(e){return ae(e,!1)}function ae(e,r){const t=e.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/%/g,r?"%%":"%");return/[\s"'\\]/.test(e)?`"${t}"`:t}function oe(e){return Array.from(e,r=>/^[A-Za-z0-9_./:@+=,-]$/.test(r)?r:r==="%"?"%%":Array.from(le.from(r,"utf8"),t=>`\\x${t.toString(16).padStart(2,"0")}`).join("")).join("")}function G(e){return/^[A-Za-z0-9_./:=@%+-]+$/.test(e)?e:`'${e.replace(/'/g,"'\\''")}'`}function ce(e){return/[\s"]/.test(e)?`"${e.replace(/"/g,'\\"')}"`:e}function C(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function tr(e,r,t){return Number.isFinite(e)?Math.max(r,Math.min(t,Math.floor(e))):r}function S(e){return Array.from(new Set(e))}export{R as RUNNER_SCHEDULER_BOOTSTRAP_REASON_CODES,i as SCHEDULER_REASON_CODES,ir as __resetRunnerSchedulerBootstrapCacheForTests,K as createRunnerSchedulerIdentity,_e as detectSchedulerCapability,dr as ensureRunnerSchedulerBootstrap,Te as renderSchedulerManifests,J as runRunnerSchedulerCommand};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{existsSync as C,mkdirSync as A,readFileSync as N,renameSync as $,writeFileSync as O,copyFileSync as I}from"node:fs";import{join as b}from"node:path";import{randomBytes as R}from"node:crypto";class g extends Error{reasonCode;constructor(t,s){super(t),this.reasonCode=s,this.name="StateRepairHardStopError"}}function u(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function h(){return new Date().toISOString()}function E(){return h().replace(/[:.]/g,"-")}function w(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"&&t.length>0):[]}const x="pr_merged_issue_closed_reconciled";function m(e){return typeof e=="string"?e.trim().toLowerCase().replace(/[_\s]+/g,"-"):""}function _(e,t){const s=e[t];return u(s)?s:null}function P(e){const t=_(e,"issueCloseAudit")??_(e,"issue_close_audit");if(t){const o=m(t.event).replace(/-/g,"_"),d=t.publicSafe===!0||t.public_safe===!0,p=t.rawLogStorage==="forbidden"||t.raw_log_storage==="forbidden";if(o==="story_issue_closed"&&d&&p)return!0}const s=_(e,"completionEvidence")??_(e,"completion_evidence"),n=m(s?.issueState??s?.issue_state??s?.state);return e.issue_closed===!0||m(e.issue_state??e.issueState??e.workflow_issue_state)==="closed"||n==="closed"}function k(e){const t=_(e,"completionEvidence")??_(e,"completion_evidence"),s=_(e,"scopedCiEvidence")??_(e,"scoped_ci_evidence"),n=[e.physicalMergeStatus,e.pr_state,e.prState,e.pull_request_state,e.pullRequestState,t?.prState,t?.pr_state,t?.pullRequestState,s?.prState].map(m);return e.merged===!0||n.includes("merged")||m(s?.finalState)==="can-merge"&&e.merged===!0}function M(e){const t=_(e,"completionEvidence")??_(e,"completion_evidence"),s=[e.pr_state,e.prState,e.pull_request_state,e.pullRequestState,t?.prState,t?.pr_state,t?.pullRequestState].map(m),n=k(e),o=["denied-external-gate","denied-local-or-repo","not-attempted"].includes(m(e.physicalMergeStatus)),d=s.includes("closed")||s.includes("closed-unmerged");return n&&(e.merged===!1||o||d)||e.merged===!0&&o}function z(e,t,s){const n=`state-completion-reconciliation:${j(t)}`,o=e.filter(u).map(r=>({...r})),d={id:n,status:"open",reason:"stale_state_completion_evidence_observed",reason_codes:[x],category:"state/completion-reconciliation",story_id:j(t),public_safe:!0,raw_log_storage:"forbidden",created_at:s,last_seen_at:s,occurrences:1},p=o.findIndex(r=>r.id===n);if(p<0)return[...o,d];const i=o[p];return o[p]={...i,...d,created_at:typeof i.created_at=="string"?i.created_at:s,occurrences:Math.max(1,typeof i.occurrences=="number"?i.occurrences:1)+1},o}function J(e,t,s){const n=u(e.stories)?e.stories:null;if(!n)return;const o=[],d=h();for(const[p,i]of Object.entries(n)){if(!u(i))continue;const r=m(i.status);if(M(i))throw new g(`[Neocortex] state.json repair stopped: story "${p}" has conflicting PR merge completion evidence. Resolve .neocortex/state.json manually before invoking Neocortex.`,"conflicting_completion_evidence");if(r!=="pr-reviewed"||!k(i)||!P(i))continue;const a=typeof i.status=="string"?i.status:r,l=w(i.steps_completed);i.status="done",i.last_step="step-c-12-merge-pr",i.steps_completed=Array.from(new Set([...l,"step-c-12-merge-pr"])),i.merged=!0,i.physicalMergeStatus="merged",i.completion_reconciled_at=d,t.push(`reconciled completion evidence for story ${p}`),s.push(x),o.push({schemaVersion:1,publicSafe:!0,rawLogStorage:"forbidden",storyId:j(p),previousStatus:a,nextStatus:"done",reasonCodes:[x],reconciledAt:d}),e.state_repair_debt=z(Array.isArray(e.state_repair_debt)?e.state_repair_debt:[],p,d)}o.length>0&&(e.state_completion_reconciliations=[...Array.isArray(e.state_completion_reconciliations)?e.state_completion_reconciliations.filter(u):[],...o])}function L(e,t,s){const n=s[e];if(!u(n))return;const o=n.epic_id;if(typeof o=="string"&&o!==t)throw new g(`[Neocortex] state.json repair stopped: story "${e}" belongs to epic "${o}" but legacy planning maps it to "${t}". Resolve the conflicting IDs in .neocortex/state.json, then rerun the command.`,"conflicting_story_epic_id")}function q(e){if(Array.isArray(e.stories))throw new g("[Neocortex] state.json repair stopped: `stories` is an Array. Convert it to an object keyed by story ID or run `*migrate-state --preview` for guidance.","stories_array_ambiguous");if(u(e.epics)){for(const[r,a]of Object.entries(e.epics))if(u(a)&&a.stories!==void 0&&!Array.isArray(a.stories))throw new g(`[Neocortex] state.json repair stopped: epic "${r}" has non-array \`stories\`. Repair this ambiguous shape manually before invoking Neocortex.`,"epic_stories_not_array")}if(e.schema_version!==void 0&&e.schema_version!==1)throw new g(`[Neocortex] state.json repair stopped: schema_version=${String(e.schema_version)} is not a safe automatic downgrade target. Run \`*migrate-state --preview\` or repair the schema version manually.`,"unsupported_schema_version");const t=JSON.parse(JSON.stringify(e)),s=[],n=[];u(t.epics)||(t.epics={},s.push("initialized epics{}"),n.push("initialized_epics_object")),u(t.stories)||(t.stories={},s.push("initialized stories{}"),n.push("initialized_stories_object"));const o=t.epics,d=t.stories,p=u(t.planning)?t.planning:null;if(p&&u(p.current)){const r=p.current,a=typeof r.epic_id=="string"?r.epic_id:null;if(!a)throw new g("[Neocortex] state.json repair stopped: legacy planning.current has no epic_id. Add the missing epic_id or run `*migrate-state --preview`.","planning_current_missing_epic_id");const l=Array.isArray(r.stories)?r.stories:[],y=l.map(c=>u(c)&&typeof c.id=="string"?c.id:typeof c=="string"?c:null).filter(c=>!!c);for(const c of y)L(c,a,d);u(o[a])||(o[a]={id:a,title:typeof r.title=="string"?r.title:`Epic ${a}`,status:r.status==="done"?"done":"in-progress",stories:y,created_at:typeof r.created_at=="string"?r.created_at:h(),completed_at:typeof r.completed_at=="string"?r.completed_at:null,completed_stories:typeof r.completed_stories=="number"?r.completed_stories:0,total_stories:typeof r.total_stories=="number"?r.total_stories:y.length,source:"client-auto-repair-P156.05"},s.push(`migrated planning.current to epics["${a}"]`),n.push("legacy_planning_current_migrated"));for(const c of l)!u(c)||typeof c.id!="string"||u(d[c.id])||(d[c.id]={...c,id:c.id,epic_id:a,title:typeof c.title=="string"?c.title:c.id,status:typeof c.status=="string"?c.status:"backlog",depends_on:w(c.depends_on),created_at:typeof c.created_at=="string"?c.created_at:h()},s.push(`migrated embedded story ${c.id}`),n.push("legacy_planning_story_migrated"));const f=typeof r.status=="string"?r.status.trim().toLowerCase().replace(/[_\s]+/g,"-"):"",S=new Set(["epic_id","title","status","created_at","updated_at","completed_at","completed_stories","total_stories","stories"]),v=Object.keys(r).filter(c=>!S.has(c));f==="generated"&&v.length===0?(delete p.current,s.push("removed safe legacy planning.current generated container"),n.push("legacy_planning_current_generated_removed")):v.length>0&&(s.push(`preserved planning.current unknown keys: ${v.sort().join(", ")}`),n.push("unknown_planning_current_keys_preserved"))}if(p&&Array.isArray(p.history)){let r=!0;const a=new Set(["epic_id","title","status","created_at","completed_at","completed_stories","total_stories","stories"]);for(const l of p.history){if(!u(l)){r=!1;continue}Object.keys(l).filter(S=>!a.has(S)).length>0&&(r=!1);const f=typeof l.epic_id=="string"?l.epic_id:null;if(!f){r=!1;continue}u(o[f])||(o[f]={id:f,title:typeof l.title=="string"?l.title:`Epic ${f}`,status:"done",stories:w(l.stories),created_at:typeof l.created_at=="string"?l.created_at:h(),completed_at:typeof l.completed_at=="string"?l.completed_at:h(),completed_stories:typeof l.completed_stories=="number"?l.completed_stories:0,total_stories:typeof l.total_stories=="number"?l.total_stories:0,source:"client-auto-repair-P156.05"},s.push(`migrated planning.history to epics["${f}"]`),n.push("legacy_planning_history_migrated"))}r?(delete p.history,s.push("removed safe legacy planning.history container"),n.push("legacy_planning_history_removed")):(s.push("preserved planning.history because one or more entries were not safely removable"),n.push("legacy_planning_history_preserved"))}p&&Object.keys(p).length===0&&(delete t.planning,s.push("removed empty planning container"),n.push("empty_planning_removed")),t.schema_version!==1&&(t.schema_version=1,s.push("set schema_version=1"),n.push("schema_version_added")),J(t,s,n);const i=JSON.stringify(t)!==JSON.stringify(e);if(i){const r=h(),a=Array.from(new Set(n));t.last_updated=r,t.state_migration_repairs=[...Array.isArray(t.state_migration_repairs)?t.state_migration_repairs:[],{schemaVersion:1,action:"client_auto_repair",reasonCodes:a,repairedAt:r}],t.state_repair_debt=D(Array.isArray(t.state_repair_debt)?t.state_repair_debt:[],a,r)}return{mutated:i,state:t,reasonCodes:Array.from(new Set(n)),changes:s}}function D(e,t,s){const n=Array.from(new Set(t.map(K).filter(Boolean))).sort(),o=`state-drift-repair:${n.join("+")||"unknown"}`,d=e.filter(u).map(a=>({...a})),p={id:o,status:"open",reason:"state_json_drift_repaired",reason_codes:n,category:"state/drift-repair",created_at:s,last_seen_at:s,occurrences:1},i=d.findIndex(a=>a.id===o);if(i<0)return[...d,p];const r=d[i];return d[i]={...r,...p,created_at:typeof r.created_at=="string"?r.created_at:s,occurrences:Math.max(1,typeof r.occurrences=="number"?r.occurrences:1)+1},d}function K(e){return e.replace(/\b(sk|ghp|gho|github_pat|xoxb|AKIA)[A-Za-z0-9_-]{8,}\b/g,"[redacted]").replace(/(password|passwd|secret|token|api[_-]?key)\s*[:=]\s*[^,\s)]+/gi,"$1=[redacted]").replace(/https?:\/\/[^\s)]+/gi,"[url-redacted]").replace(/[^a-z0-9_+-]+/gi,"_").replace(/^_+|_+$/g,"").slice(0,120)}function j(e){return e.replace(/[^a-z0-9_.:-]+/gi,"_").replace(/^_+|_+$/g,"").slice(0,120)||"unknown"}function T(e){const t=b(e,".neocortex"),s=b(t,"state.json");if(!C(s))return{repaired:!1,reasonCodes:[],changes:[]};let n;try{n=JSON.parse(N(s,"utf8"))}catch(a){const l=a instanceof Error?a.message:String(a);throw new g(`[Neocortex] state.json repair stopped: invalid JSON in .neocortex/state.json (${l}). No files were overwritten. Fix the JSON or restore a backup, then rerun.`,"invalid_json")}if(!u(n))throw new g("[Neocortex] state.json repair stopped: top-level state must be a JSON object. Restore a valid .neocortex/state.json before invoking Neocortex.","state_not_object");const o=q(n);if(!o.mutated)return{repaired:!1,reasonCodes:[],changes:[]};A(t,{recursive:!0});const d=E(),p=b(t,`state.json.backup-${d}`),i=b(t,`state.json.tmp.${R(6).toString("hex")}`);I(s,p),O(i,`${JSON.stringify(o.state,null,2)}
|
|
2
|
-
`,"utf8")
|
|
3
|
-
`),{repaired:!0,reasonCodes:o.reasonCodes,backupPath:r,changes:o.changes}}export{g as StateRepairHardStopError,
|
|
1
|
+
import{existsSync as A,mkdirSync as C,readFileSync as N,renameSync as O,writeFileSync as $,copyFileSync as I}from"node:fs";import{join as b}from"node:path";import{randomBytes as R}from"node:crypto";class g extends Error{reasonCode;constructor(t,s){super(t),this.reasonCode=s,this.name="StateRepairHardStopError"}}function u(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function h(){return new Date().toISOString()}function E(){return h().replace(/[:.]/g,"-")}function k(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"&&t.length>0):[]}const j="pr_merged_issue_closed_reconciled",P="invalid_workflow_issue_removed";function m(e){return typeof e=="string"?e.trim().toLowerCase().replace(/[_\s]+/g,"-"):""}function _(e,t){const s=e[t];return u(s)?s:null}function M(e){const t=_(e,"issueCloseAudit")??_(e,"issue_close_audit");if(t){const o=m(t.event).replace(/-/g,"_"),a=t.publicSafe===!0||t.public_safe===!0,l=t.rawLogStorage==="forbidden"||t.raw_log_storage==="forbidden";if(o==="story_issue_closed"&&a&&l)return!0}const s=_(e,"completionEvidence")??_(e,"completion_evidence"),n=m(s?.issueState??s?.issue_state??s?.state);return e.issue_closed===!0||m(e.issue_state??e.issueState??e.workflow_issue_state)==="closed"||n==="closed"}function x(e){const t=_(e,"completionEvidence")??_(e,"completion_evidence"),s=_(e,"scopedCiEvidence")??_(e,"scoped_ci_evidence"),n=[e.physicalMergeStatus,e.pr_state,e.prState,e.pull_request_state,e.pullRequestState,t?.prState,t?.pr_state,t?.pullRequestState,s?.prState].map(m);return e.merged===!0||n.includes("merged")||m(s?.finalState)==="can-merge"&&e.merged===!0}function z(e){const t=_(e,"completionEvidence")??_(e,"completion_evidence"),s=[e.pr_state,e.prState,e.pull_request_state,e.pullRequestState,t?.prState,t?.pr_state,t?.pullRequestState].map(m),n=x(e),o=["denied-external-gate","denied-local-or-repo","not-attempted"].includes(m(e.physicalMergeStatus)),a=s.includes("closed")||s.includes("closed-unmerged");return n&&(e.merged===!1||o||a)||e.merged===!0&&o}function J(e,t,s){const n=`state-completion-reconciliation:${w(t)}`,o=e.filter(u).map(r=>({...r})),a={id:n,status:"open",reason:"stale_state_completion_evidence_observed",reason_codes:[j],category:"state/completion-reconciliation",story_id:w(t),public_safe:!0,raw_log_storage:"forbidden",created_at:s,last_seen_at:s,occurrences:1},l=o.findIndex(r=>r.id===n);if(l<0)return[...o,a];const i=o[l];return o[l]={...i,...a,created_at:typeof i.created_at=="string"?i.created_at:s,occurrences:Math.max(1,typeof i.occurrences=="number"?i.occurrences:1)+1},o}function L(e,t,s){const n=u(e.stories)?e.stories:null;if(!n)return;const o=[],a=h();for(const[l,i]of Object.entries(n)){if(!u(i))continue;const r=m(i.status);if(z(i))throw new g(`[Neocortex] state.json repair stopped: story "${l}" has conflicting PR merge completion evidence. Resolve .neocortex/state.json manually before invoking Neocortex.`,"conflicting_completion_evidence");if(r!=="pr-reviewed"||!x(i)||!M(i))continue;const c=typeof i.status=="string"?i.status:r,d=k(i.steps_completed);i.status="done",i.last_step="step-c-12-merge-pr",i.steps_completed=Array.from(new Set([...d,"step-c-12-merge-pr"])),i.merged=!0,i.physicalMergeStatus="merged",i.completion_reconciled_at=a,t.push(`reconciled completion evidence for story ${l}`),s.push(j),o.push({schemaVersion:1,publicSafe:!0,rawLogStorage:"forbidden",storyId:w(l),previousStatus:c,nextStatus:"done",reasonCodes:[j],reconciledAt:a}),e.state_repair_debt=J(Array.isArray(e.state_repair_debt)?e.state_repair_debt:[],l,a)}o.length>0&&(e.state_completion_reconciliations=[...Array.isArray(e.state_completion_reconciliations)?e.state_completion_reconciliations.filter(u):[],...o])}function q(e,t,s){const n=u(e.stories)?e.stories:null;if(n)for(const[o,a]of Object.entries(n))!u(a)||!Object.prototype.hasOwnProperty.call(a,"workflow_issue")||typeof a.workflow_issue=="number"&&Number.isFinite(a.workflow_issue)||(delete a.workflow_issue,t.push(`removed invalid workflow_issue from story ${w(o)}`),s.push(P))}function D(e,t,s){const n=s[e];if(!u(n))return;const o=n.epic_id;if(typeof o=="string"&&o!==t)throw new g(`[Neocortex] state.json repair stopped: story "${e}" belongs to epic "${o}" but legacy planning maps it to "${t}". Resolve the conflicting IDs in .neocortex/state.json, then rerun the command.`,"conflicting_story_epic_id")}function F(e){if(Array.isArray(e.stories))throw new g("[Neocortex] state.json repair stopped: `stories` is an Array. Convert it to an object keyed by story ID or run `*migrate-state --preview` for guidance.","stories_array_ambiguous");if(u(e.epics)){for(const[r,c]of Object.entries(e.epics))if(u(c)&&c.stories!==void 0&&!Array.isArray(c.stories))throw new g(`[Neocortex] state.json repair stopped: epic "${r}" has non-array \`stories\`. Repair this ambiguous shape manually before invoking Neocortex.`,"epic_stories_not_array")}if(e.schema_version!==void 0&&e.schema_version!==1)throw new g(`[Neocortex] state.json repair stopped: schema_version=${String(e.schema_version)} is not a safe automatic downgrade target. Run \`*migrate-state --preview\` or repair the schema version manually.`,"unsupported_schema_version");const t=JSON.parse(JSON.stringify(e)),s=[],n=[];u(t.epics)||(t.epics={},s.push("initialized epics{}"),n.push("initialized_epics_object")),u(t.stories)||(t.stories={},s.push("initialized stories{}"),n.push("initialized_stories_object"));const o=t.epics,a=t.stories,l=u(t.planning)?t.planning:null;if(l&&u(l.current)){const r=l.current,c=typeof r.epic_id=="string"?r.epic_id:null;if(!c)throw new g("[Neocortex] state.json repair stopped: legacy planning.current has no epic_id. Add the missing epic_id or run `*migrate-state --preview`.","planning_current_missing_epic_id");const d=Array.isArray(r.stories)?r.stories:[],y=d.map(p=>u(p)&&typeof p.id=="string"?p.id:typeof p=="string"?p:null).filter(p=>!!p);for(const p of y)D(p,c,a);u(o[c])||(o[c]={id:c,title:typeof r.title=="string"?r.title:`Epic ${c}`,status:r.status==="done"?"done":"in-progress",stories:y,created_at:typeof r.created_at=="string"?r.created_at:h(),completed_at:typeof r.completed_at=="string"?r.completed_at:null,completed_stories:typeof r.completed_stories=="number"?r.completed_stories:0,total_stories:typeof r.total_stories=="number"?r.total_stories:y.length,source:"client-auto-repair-P156.05"},s.push(`migrated planning.current to epics["${c}"]`),n.push("legacy_planning_current_migrated"));for(const p of d)!u(p)||typeof p.id!="string"||u(a[p.id])||(a[p.id]={...p,id:p.id,epic_id:c,title:typeof p.title=="string"?p.title:p.id,status:typeof p.status=="string"?p.status:"backlog",depends_on:k(p.depends_on),created_at:typeof p.created_at=="string"?p.created_at:h()},s.push(`migrated embedded story ${p.id}`),n.push("legacy_planning_story_migrated"));const f=typeof r.status=="string"?r.status.trim().toLowerCase().replace(/[_\s]+/g,"-"):"",S=new Set(["epic_id","title","status","created_at","updated_at","completed_at","completed_stories","total_stories","stories"]),v=Object.keys(r).filter(p=>!S.has(p));f==="generated"&&v.length===0?(delete l.current,s.push("removed safe legacy planning.current generated container"),n.push("legacy_planning_current_generated_removed")):v.length>0&&(s.push(`preserved planning.current unknown keys: ${v.sort().join(", ")}`),n.push("unknown_planning_current_keys_preserved"))}if(l&&Array.isArray(l.history)){let r=!0;const c=new Set(["epic_id","title","status","created_at","completed_at","completed_stories","total_stories","stories"]);for(const d of l.history){if(!u(d)){r=!1;continue}Object.keys(d).filter(S=>!c.has(S)).length>0&&(r=!1);const f=typeof d.epic_id=="string"?d.epic_id:null;if(!f){r=!1;continue}u(o[f])||(o[f]={id:f,title:typeof d.title=="string"?d.title:`Epic ${f}`,status:"done",stories:k(d.stories),created_at:typeof d.created_at=="string"?d.created_at:h(),completed_at:typeof d.completed_at=="string"?d.completed_at:h(),completed_stories:typeof d.completed_stories=="number"?d.completed_stories:0,total_stories:typeof d.total_stories=="number"?d.total_stories:0,source:"client-auto-repair-P156.05"},s.push(`migrated planning.history to epics["${f}"]`),n.push("legacy_planning_history_migrated"))}r?(delete l.history,s.push("removed safe legacy planning.history container"),n.push("legacy_planning_history_removed")):(s.push("preserved planning.history because one or more entries were not safely removable"),n.push("legacy_planning_history_preserved"))}l&&Object.keys(l).length===0&&(delete t.planning,s.push("removed empty planning container"),n.push("empty_planning_removed")),t.schema_version!==1&&(t.schema_version=1,s.push("set schema_version=1"),n.push("schema_version_added")),q(t,s,n),L(t,s,n);const i=JSON.stringify(t)!==JSON.stringify(e);if(i){const r=h(),c=Array.from(new Set(n));t.last_updated=r,t.state_migration_repairs=[...Array.isArray(t.state_migration_repairs)?t.state_migration_repairs:[],{schemaVersion:1,action:"client_auto_repair",reasonCodes:c,repairedAt:r}],t.state_repair_debt=K(Array.isArray(t.state_repair_debt)?t.state_repair_debt:[],c,r)}return{mutated:i,state:t,reasonCodes:Array.from(new Set(n)),changes:s}}function K(e,t,s){const n=Array.from(new Set(t.map(B).filter(Boolean))).sort(),o=`state-drift-repair:${n.join("+")||"unknown"}`,a=e.filter(u).map(c=>({...c})),l={id:o,status:"open",reason:"state_json_drift_repaired",reason_codes:n,category:"state/drift-repair",created_at:s,last_seen_at:s,occurrences:1},i=a.findIndex(c=>c.id===o);if(i<0)return[...a,l];const r=a[i];return a[i]={...r,...l,created_at:typeof r.created_at=="string"?r.created_at:s,occurrences:Math.max(1,typeof r.occurrences=="number"?r.occurrences:1)+1},a}function B(e){return e.replace(/\b(sk|ghp|gho|github_pat|xoxb|AKIA)[A-Za-z0-9_-]{8,}\b/g,"[redacted]").replace(/(password|passwd|secret|token|api[_-]?key)\s*[:=]\s*[^,\s)]+/gi,"$1=[redacted]").replace(/https?:\/\/[^\s)]+/gi,"[url-redacted]").replace(/[^a-z0-9_+-]+/gi,"_").replace(/^_+|_+$/g,"").slice(0,120)}function w(e){return e.replace(/[^a-z0-9_.:-]+/gi,"_").replace(/^_+|_+$/g,"").slice(0,120)||"unknown"}function V(e){const t=b(e,".neocortex"),s=b(t,"state.json");if(!A(s))return{repaired:!1,reasonCodes:[],changes:[]};let n;try{n=JSON.parse(N(s,"utf8"))}catch(c){const d=c instanceof Error?c.message:String(c);throw new g(`[Neocortex] state.json repair stopped: invalid JSON in .neocortex/state.json (${d}). No files were overwritten. Fix the JSON or restore a backup, then rerun.`,"invalid_json")}if(!u(n))throw new g("[Neocortex] state.json repair stopped: top-level state must be a JSON object. Restore a valid .neocortex/state.json before invoking Neocortex.","state_not_object");const o=F(n);if(!o.mutated)return{repaired:!1,reasonCodes:[],changes:[]};C(t,{recursive:!0});const a=E(),l=b(t,`state.json.backup-${a}`),i=b(t,`state.json.tmp.${R(6).toString("hex")}`);I(s,l),$(i,`${JSON.stringify(o.state,null,2)}
|
|
2
|
+
`,"utf8"),O(i,s);const r=`.neocortex/state.json.backup-${a}`;return process.stderr.write(`[Neocortex P156.05] state.json auto-repaired before invoke; backup=${r}; reasonCodes=${o.reasonCodes.join(",")}; changes=${o.changes.join("; ")}
|
|
3
|
+
`),{repaired:!0,reasonCodes:o.reasonCodes,backupPath:r,changes:o.changes}}export{g as StateRepairHardStopError,V as maybeRepairStateJsonBeforeInvoke};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: neocortex-root
|
|
3
|
-
description: "🧠 Neocortex Root Agent v4.59.
|
|
3
|
+
description: "🧠 Neocortex Root Agent v4.59.4 | OrNexus Team"
|
|
4
4
|
model: opus
|
|
5
5
|
color: blue
|
|
6
6
|
tools:
|
|
@@ -103,7 +103,7 @@ SEMPRE que este agente for invocado, imprima o banner abaixo como PRIMEIRO outpu
|
|
|
103
103
|
┌────────────────────────────────────────────────────────────┐
|
|
104
104
|
│ │
|
|
105
105
|
│ ####### N E O C O R T E X │
|
|
106
|
-
│ ### ######## v4.59.
|
|
106
|
+
│ ### ######## v4.59.4 │
|
|
107
107
|
│ ######### ##### │
|
|
108
108
|
│ ## ############## Development Orchestrator │
|
|
109
109
|
│ ## ### ###### ## OrNexus Team │
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: neocortex
|
|
3
|
-
description: "🧠 Neocortex v4.59.
|
|
3
|
+
description: "🧠 Neocortex v4.59.4 | OrNexus Team"
|
|
4
4
|
model: opus
|
|
5
5
|
color: blue
|
|
6
6
|
tools:
|
|
@@ -97,7 +97,7 @@ SEMPRE que este agente for invocado, imprima o banner abaixo como PRIMEIRO outpu
|
|
|
97
97
|
┌────────────────────────────────────────────────────────────┐
|
|
98
98
|
│ │
|
|
99
99
|
│ ####### N E O C O R T E X │
|
|
100
|
-
│ ### ######## v4.59.
|
|
100
|
+
│ ### ######## v4.59.4 │
|
|
101
101
|
│ ######### ##### │
|
|
102
102
|
│ ## ############## Development Orchestrator │
|
|
103
103
|
│ ## ### ###### ## OrNexus Team │
|
|
@@ -23,7 +23,7 @@ Codex built-in commands or actions.
|
|
|
23
23
|
|
|
24
24
|
<!-- END: Plugin Conflict Prevention -->
|
|
25
25
|
|
|
26
|
-
# Neocortex v4.59.
|
|
26
|
+
# Neocortex v4.59.4 | OrNexus Team
|
|
27
27
|
|
|
28
28
|
You are a Development Orchestrator. All orchestration logic is delivered by the remote Neocortex server.
|
|
29
29
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: neocortex
|
|
3
|
-
description: "🧠 Neocortex v4.59.
|
|
3
|
+
description: "🧠 Neocortex v4.59.4 | OrNexus Team"
|
|
4
4
|
model: fast
|
|
5
5
|
readonly: false
|
|
6
6
|
is_background: false
|
|
@@ -43,7 +43,7 @@ SEMPRE que este agente for invocado, imprima o banner abaixo como PRIMEIRO outpu
|
|
|
43
43
|
┌────────────────────────────────────────────────────────────┐
|
|
44
44
|
│ │
|
|
45
45
|
│ ####### N E O C O R T E X │
|
|
46
|
-
│ ### ######## v4.59.
|
|
46
|
+
│ ### ######## v4.59.4 │
|
|
47
47
|
│ ######### ##### │
|
|
48
48
|
│ ## ############## Development Orchestrator │
|
|
49
49
|
│ ## ### ###### ## OrNexus Team │
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: neocortex
|
|
3
|
-
description: "🧠 Neocortex v4.59.
|
|
3
|
+
description: "🧠 Neocortex v4.59.4 | OrNexus Team"
|
|
4
4
|
kind: local
|
|
5
5
|
tools:
|
|
6
6
|
# File operations (Gemini CLI built-ins)
|
|
@@ -60,7 +60,7 @@ SEMPRE que este agente for invocado, imprima o banner abaixo como PRIMEIRO outpu
|
|
|
60
60
|
┌────────────────────────────────────────────────────────────┐
|
|
61
61
|
│ │
|
|
62
62
|
│ ####### N E O C O R T E X │
|
|
63
|
-
│ ### ######## v4.59.
|
|
63
|
+
│ ### ######## v4.59.4 │
|
|
64
64
|
│ ######### ##### │
|
|
65
65
|
│ ## ############## Development Orchestrator │
|
|
66
66
|
│ ## ### ###### ## OrNexus Team │
|
|
@@ -47,7 +47,7 @@ explicit server opt-in rather than a local assumption.
|
|
|
47
47
|
┌────────────────────────────────────────────────────────────┐
|
|
48
48
|
│ │
|
|
49
49
|
│ ####### N E O C O R T E X │
|
|
50
|
-
│ ### ######## v4.59.
|
|
50
|
+
│ ### ######## v4.59.4 │
|
|
51
51
|
│ ######### ##### │
|
|
52
52
|
│ ## ############## Development Orchestrator │
|
|
53
53
|
│ ## ### ###### ## OrNexus Team │
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: "neocortex"
|
|
3
|
-
description: "Neocortex v4.59.
|
|
3
|
+
description: "Neocortex v4.59.4 | OrNexus Team"
|
|
4
4
|
tools:
|
|
5
5
|
# Read / Edit (built-in tool sets)
|
|
6
6
|
- read
|
|
@@ -61,7 +61,7 @@ SEMPRE que este agente for invocado, imprima o banner abaixo como PRIMEIRO outpu
|
|
|
61
61
|
┌────────────────────────────────────────────────────────────┐
|
|
62
62
|
│ │
|
|
63
63
|
│ ####### N E O C O R T E X │
|
|
64
|
-
│ ### ######## v4.59.
|
|
64
|
+
│ ### ######## v4.59.4 │
|
|
65
65
|
│ ######### ##### │
|
|
66
66
|
│ ## ############## Development Orchestrator │
|
|
67
67
|
│ ## ### ###### ## OrNexus Team │
|