@ornexus/neocortex 4.59.3 → 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.js +13 -13
- 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/scheduler.js +7 -7
- 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
package/dist/sbom.cdx.json
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
"bomFormat": "CycloneDX",
|
|
4
4
|
"specVersion": "1.5",
|
|
5
5
|
"version": 1,
|
|
6
|
-
"serialNumber": "urn:uuid:
|
|
6
|
+
"serialNumber": "urn:uuid:6fc05a3f-c761-4fca-bbb4-d8ad50c4f3e7",
|
|
7
7
|
"metadata": {
|
|
8
|
-
"timestamp": "2026-06-
|
|
8
|
+
"timestamp": "2026-06-24T05:21:07.061Z",
|
|
9
9
|
"tools": {
|
|
10
10
|
"components": [
|
|
11
11
|
{
|
|
@@ -83,10 +83,10 @@
|
|
|
83
83
|
"type": "application",
|
|
84
84
|
"name": "neocortex",
|
|
85
85
|
"group": "@ornexus",
|
|
86
|
-
"version": "4.59.
|
|
87
|
-
"bom-ref": "@ornexus/neocortex@4.59.
|
|
86
|
+
"version": "4.59.4",
|
|
87
|
+
"bom-ref": "@ornexus/neocortex@4.59.4",
|
|
88
88
|
"author": "OrNexus Team",
|
|
89
|
-
"description": "Neocortex v4.59.
|
|
89
|
+
"description": "Neocortex v4.59.4 - Orquestrador de Desenvolvimento de Epics & Stories para Claude Code",
|
|
90
90
|
"licenses": [
|
|
91
91
|
{
|
|
92
92
|
"license": {
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
],
|
|
97
|
-
"purl": "pkg:npm/%40ornexus/neocortex@4.59.
|
|
97
|
+
"purl": "pkg:npm/%40ornexus/neocortex@4.59.4?vcs_url=git%2Bhttps%3A%2F%2Fgithub.com%2FOrNexus-AI%2Fneocortex.git",
|
|
98
98
|
"externalReferences": [
|
|
99
99
|
{
|
|
100
100
|
"url": "git+https://github.com/OrNexus-AI/neocortex.git",
|
|
@@ -3819,9 +3819,9 @@
|
|
|
3819
3819
|
"type": "library",
|
|
3820
3820
|
"name": "client",
|
|
3821
3821
|
"group": "@neocortex",
|
|
3822
|
-
"version": "4.59.
|
|
3823
|
-
"bom-ref": "@neocortex/client@4.59.
|
|
3824
|
-
"purl": "pkg:npm/%40neocortex/client@4.59.
|
|
3822
|
+
"version": "4.59.4",
|
|
3823
|
+
"bom-ref": "@neocortex/client@4.59.4",
|
|
3824
|
+
"purl": "pkg:npm/%40neocortex/client@4.59.4",
|
|
3825
3825
|
"properties": [
|
|
3826
3826
|
{
|
|
3827
3827
|
"name": "cdx:npm:package:path",
|
|
@@ -3837,9 +3837,9 @@
|
|
|
3837
3837
|
"type": "library",
|
|
3838
3838
|
"name": "shared",
|
|
3839
3839
|
"group": "@neocortex",
|
|
3840
|
-
"version": "4.59.
|
|
3841
|
-
"bom-ref": "@neocortex/shared@4.59.
|
|
3842
|
-
"purl": "pkg:npm/%40neocortex/shared@4.59.
|
|
3840
|
+
"version": "4.59.4",
|
|
3841
|
+
"bom-ref": "@neocortex/shared@4.59.4",
|
|
3842
|
+
"purl": "pkg:npm/%40neocortex/shared@4.59.4",
|
|
3843
3843
|
"properties": [
|
|
3844
3844
|
{
|
|
3845
3845
|
"name": "cdx:npm:package:path",
|
|
@@ -6222,13 +6222,13 @@
|
|
|
6222
6222
|
],
|
|
6223
6223
|
"dependencies": [
|
|
6224
6224
|
{
|
|
6225
|
-
"ref": "@ornexus/neocortex@4.59.
|
|
6225
|
+
"ref": "@ornexus/neocortex@4.59.4",
|
|
6226
6226
|
"dependsOn": [
|
|
6227
6227
|
"@clack/prompts@1.0.1",
|
|
6228
6228
|
"@modelcontextprotocol/sdk@1.26.0",
|
|
6229
|
-
"@neocortex/client@4.59.
|
|
6229
|
+
"@neocortex/client@4.59.4",
|
|
6230
6230
|
"@neocortex/core@0.1.0",
|
|
6231
|
-
"@neocortex/shared@4.59.
|
|
6231
|
+
"@neocortex/shared@4.59.4",
|
|
6232
6232
|
"better-sqlite3@12.11.1",
|
|
6233
6233
|
"execa@9.6.1",
|
|
6234
6234
|
"node-cache@5.1.2",
|
|
@@ -6765,16 +6765,16 @@
|
|
|
6765
6765
|
"ref": "zod@4.3.6"
|
|
6766
6766
|
},
|
|
6767
6767
|
{
|
|
6768
|
-
"ref": "@neocortex/client@4.59.
|
|
6768
|
+
"ref": "@neocortex/client@4.59.4",
|
|
6769
6769
|
"dependsOn": [
|
|
6770
|
-
"@neocortex/shared@4.59.
|
|
6770
|
+
"@neocortex/shared@4.59.4",
|
|
6771
6771
|
"better-sqlite3@12.11.1",
|
|
6772
6772
|
"jose@6.2.2",
|
|
6773
6773
|
"keytar@7.9.0"
|
|
6774
6774
|
]
|
|
6775
6775
|
},
|
|
6776
6776
|
{
|
|
6777
|
-
"ref": "@neocortex/shared@4.59.
|
|
6777
|
+
"ref": "@neocortex/shared@4.59.4"
|
|
6778
6778
|
},
|
|
6779
6779
|
{
|
|
6780
6780
|
"ref": "better-sqlite3@12.11.1",
|
|
@@ -6813,7 +6813,7 @@
|
|
|
6813
6813
|
{
|
|
6814
6814
|
"ref": "@neocortex/core@0.1.0",
|
|
6815
6815
|
"dependsOn": [
|
|
6816
|
-
"@neocortex/shared@4.59.
|
|
6816
|
+
"@neocortex/shared@4.59.4"
|
|
6817
6817
|
]
|
|
6818
6818
|
},
|
|
6819
6819
|
{
|
package/install.ps1
CHANGED
package/install.sh
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ornexus/neocortex",
|
|
3
|
-
"version": "4.59.
|
|
4
|
-
"description": "Neocortex v4.59.
|
|
3
|
+
"version": "4.59.4",
|
|
4
|
+
"description": "Neocortex v4.59.4 - Orquestrador de Desenvolvimento de Epics & Stories para Claude Code",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
|
7
7
|
"claude-code",
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import{createHash as
|
|
1
|
+
import{createHash as $}from"node:crypto";import{existsSync as C,readFileSync as N,unlinkSync as se,writeFileSync as ie,mkdirSync as ae,statSync as ce}from"node:fs";import{join as E}from"node:path";import{homedir as k}from"node:os";import{LicenseClient as ue}from"../license/license-client.js";import{EncryptedCache as U}from"../cache/encrypted-cache.js";import{NoOpCache as de}from"../types/index.js";import{resolveClientPreFlightTrigger as le,TierAwareClient as pe}from"../tier/tier-aware-client.js";import{loadSecureConfig as fe}from"../config/secure-config.js";import{DEFAULT_SERVER_URL as me}from"../constants.js";import{detectFirstRunLocale as ge,renderFirstRunMessage as he}from"../i18n/first-run.js";import{humanizeError as F,formatHumanizedError as M,detectErrorLocale as j}from"../errors/error-messages.js";import{projectStateSnapshotForInvoke as _e}from"../state/project-state-snapshot.js";import{maybeRepairStateJsonBeforeInvoke as ye,StateRepairHardStopError as Ee}from"../state/state-json-repair.js";import{bootstrapArchitectureMemory as Se}from"../memory/project-memory-writer.js";import{RUNNER_BOOTSTRAP_POLICY_REASON_CODES as we,classifyRunnerBootstrapPolicyFromArgs as Re}from"../continuity/runner-bootstrap-policy.js";import{RUNNER_SCHEDULER_BOOTSTRAP_REASON_CODES as Ce,ensureRunnerSchedulerBootstrap as Te}from"../runner/scheduler.js";const I=E(k(),".neocortex"),B=E(I,"cache"),Y=E(B,"menu-cache.json"),K=1440*60*1e3,z=3e4,S="3.9.62",V=256*1024,Ae=.8,R="[REDACTED]",Ne=1e5,O=2e3,Ie=200,Oe=200,be=12,ke=/(?:promptBody|workflow|workflowGraph|stepBody|privateUrl|rawLog|secret|credential|licenseKey|apiKey|internalRouting|serverOnly|proprietary|protected)/i,xe=/(?:PRIVATE|PROTECTED|SERVER_ONLY)[-_\s]*(?:PROMPT|PROMPT_BODY|WORKFLOW|WORKFLOW_GRAPH|STEP_BODY|STEP|ROUTING)\s*[:=][^\n\r]*/gi,H=Math.floor(V*Ae),G=E(I,".first-run-shown"),Pe="<!-- NEOCORTEX-MEMORY-START -->";function De(e){return/^\s*\*?init(?:\s|$)/i.test(e)}function ve(e){const t=E(e,"NEOCORTEX.md"),r=C(t)?N(t,"utf8"):void 0,o=r===void 0?["missing_canonical_memory"]:[r.includes(Pe)?void 0:"missing_managed_memory_block",r.length>18e3?"canonical_memory_over_budget":void 0,/api[-_ ]?key|license[-_ ]?key|password\s*[:=]|secret\s*[:=]/i.test(r)?"possible_secret_shape_detected":void 0].filter(u=>!!u),a=["AGENTS.md","CLAUDE.md","GEMINI.md",".opencode/AGENTS.md",".cursor/rules/neocortex.mdc",".github/copilot-instructions.md"].filter(u=>C(E(e,u))),c=o.includes("possible_secret_shape_detected")?"low":o.length===0?"high":a.length>0?"medium":"low",l=Se(e);return{canonical:{path:"NEOCORTEX.md",exists:r!==void 0,incompleteReasons:o,confidence:c},permittedSources:{packageBuildFiles:l.repositoryMap?.find(u=>u.startsWith("Package/build files:"))?.split(",").length??0,architectureReadmeDocs:l.architectureReferences?.length??0,runtimeConfigTemplates:l.environmentPractices?.[0]?.startsWith("Runtime/config templates:")?l.environmentPractices[0].split(",").length:0,platformWrappers:a.length},wrapperFiles:a,recommendedPreviewCommand:'neocortex-client refresh-memory --dry-run --project-root "$PROJECT_ROOT"',recommendedRefreshCommand:'neocortex-client refresh-memory --project-root "$PROJECT_ROOT"',guardrails:["Use only permitted bootstrap sources; never read real .env files or credentials into memory.","Preserve human-authored wrapper content outside Neocortex managed blocks.","Do not reset .neocortex/state.json or depend on legacy planning.current during init bootstrap."]}}function Le(){try{if(C(G))return;const e=ge(),t=he(e);process.stderr.write(t);try{ae(I,{recursive:!0}),ie(G,new Date().toISOString(),"utf-8")}catch{}}catch{}}function $e(e,t=process.cwd()){return e&&e.trim().length>0?e:t}function Ue(e){return e.replace(/[\w.+-]+@[\w-]+\.[\w.-]+/g,R).replace(/(?:sk|pk|whsec|nxk)[-_](?:test|live|ant|proj|pro|free|enterprise)?[-_]?[A-Za-z0-9_-]{16,}/g,R).replace(/NX-[FPE]-[a-f0-9]{24}-[a-f0-9]{4}/g,R).replace(/eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g,R).replace(xe,R)}function T(e,t){const r=Ue(e);return r.length<=t?r:`${r.slice(0,t)}\u2026[TRUNCATED:${r.length-t}]`}function x(e,t=0,r=new WeakSet){if(t>be)return"[MAX_DEPTH]";if(e==null)return e;if(typeof e=="string")return T(e,O);if(typeof e=="number")return Number.isFinite(e)?e:null;if(typeof e=="boolean")return e;if(typeof e=="bigint")return String(e);if(typeof e=="function"||typeof e=="symbol"||typeof e!="object")return;if(r.has(e))return"[CIRCULAR]";if(r.add(e),Array.isArray(e))return e.slice(0,Ie).map(i=>x(i,t+1,r));const o={};for(const[i,a]of Object.entries(e).slice(0,Oe)){if(ke.test(i)){o[i]=R;continue}const c=x(a,t+1,r);c!==void 0&&(o[i]=c)}return o}function P(e,t){return{instructions:T(e??"",Ne),metadata:t?x(t):void 0}}class y extends Error{code;constructor(t,r){super(r),this.name="InvokeCliInputError",this.code=t}}let D=!1;function Fe(e){const t=[];if(!e||typeof e!="object")return t;const r=e,o=r.planning;if(o&&(o.current!==void 0||Array.isArray(o.history))&&t.push({code:"PLANNING_LEGACY",message:"legacy `planning.current`/`planning.history` detected (not read by v1 orchestrator)"}),Array.isArray(r.stories)&&t.push({code:"STORIES_AS_ARRAY",message:"`stories` is an Array (expected Object keyed by story ID)"}),r.epics&&typeof r.epics=="object"&&!Array.isArray(r.epics))for(const[a,c]of Object.entries(r.epics)){const l=c;if(l&&l.stories!==void 0&&!Array.isArray(l.stories)){t.push({code:"EPIC_STORIES_NOT_ARRAY",message:`epic "${a}" has non-array \`stories\` field (expected string[] of story IDs)`});break}}const i=r.epics&&typeof r.epics=="object"&&Object.keys(r.epics).length>0||r.stories&&typeof r.stories=="object"&&!Array.isArray(r.stories)&&Object.keys(r.stories).length>0||Array.isArray(r.stories)||o&&o.current!==void 0;return r.schema_version===void 0?i&&t.push({code:"SCHEMA_VERSION_MISSING",message:"`schema_version` field missing (expected: `schema_version: 1`)"}):r.schema_version!==1&&t.push({code:"SCHEMA_VERSION_OUTDATED",message:`schema_version=${String(r.schema_version)} (expected: 1)`}),t}function Me(e){if(!(D||e.length===0)){D=!0;try{const t=e.map(r=>` - ${r.message}`).join(`
|
|
2
2
|
`);process.stderr.write(`[Neocortex] state.json schema drift detected:
|
|
3
3
|
${t}
|
|
4
4
|
Run \`neocortex *migrate-state --preview\` to inspect or \`neocortex *migrate-state --apply\` to migrate.
|
|
5
5
|
See docs/arquitetura-software/STATE-JSON-SCHEMA.md for the schema contract.
|
|
6
|
-
`)}catch{}}}function At(){
|
|
7
|
-
`),r=new de;const o=new ue({serverUrl:e,licenseKey:t??"",cacheProvider:r}),i=await o.getToken();if(!i)return null;const a=new pe({cacheProvider:r,licenseClient:o});return{token:i,client:o,tierClient:a}}catch{return null}}let W=!1;function X(e){return
|
|
8
|
-
`),t}async function tt(e){const t=
|
|
6
|
+
`)}catch{}}}function At(){D=!1}function q(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"&&t.length>0):[]}function je(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"&&t.length>0):[]}function Be(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function b(e){return typeof e=="number"&&Number.isFinite(e)&&e>0?e:void 0}function w(e){if(typeof e!="string")return;const t=e.trim();if(t)return t.replace(/[^a-z0-9_.:-]+/gi,"_").slice(0,120)}function v(e,t){if(!Be(e))return;const r={};for(const o of t){const i=e[o];if(typeof i=="boolean")r[o]=i;else if(typeof i=="number"&&Number.isFinite(i))r[o]=i;else if(typeof i=="string"){const a=w(i);a&&(r[o]=a)}}return Object.keys(r).length>0?r:void 0}function Ye(e){const t=v(e.completionEvidence??e.completion_evidence,["prNumber","pr_number","prState","pr_state","pullRequestState","merged","mergedAt","issueNumber","issue_number","issueState","issue_state","closedAt"]),r=v(e.issueCloseAudit??e.issue_close_audit,["schema_version","event","storyId","epicId","issueNumber","closedAt","publicSafe","rawLogStorage"]),o=v(e.scopedCiEvidence??e.scoped_ci_evidence,["schema_version","storyId","epicId","prNumber","finalState","publicSafe","rawLogStorage"]);return{...typeof e.merged=="boolean"?{merged:e.merged}:{},...typeof e.safeToContinueYoloop=="boolean"?{safeToContinueYoloop:e.safeToContinueYoloop}:{},...typeof e.mergeBlockedRemotely=="boolean"?{mergeBlockedRemotely:e.mergeBlockedRemotely}:{},...w(e.physicalMergeStatus)?{physicalMergeStatus:w(e.physicalMergeStatus)}:{},...w(e.pr_state??e.prState??e.pull_request_state??e.pullRequestState)?{pr_state:w(e.pr_state??e.prState??e.pull_request_state??e.pullRequestState)}:{},...w(e.issue_state??e.issueState??e.workflow_issue_state)?{issue_state:w(e.issue_state??e.issueState??e.workflow_issue_state)}:{},...b(e.issue_number??e.issueNumber)?{issue_number:b(e.issue_number??e.issueNumber)}:{},...t?{completionEvidence:t}:{},...r?{issueCloseAudit:r}:{},...o?{scopedCiEvidence:o}:{}}}function Ke(e){const t=E(e,".neocortex","state.json");if(!C(t))return{config:{project_name:"unknown",default_branch:"main",language:"pt-BR"},stories:{},epics:{}};let r;try{const u=N(t,"utf-8");r=JSON.parse(u)}catch{return{config:{project_name:"unknown",default_branch:"main",language:"pt-BR"},stories:{},epics:{}}}try{const u=Fe(r);u.length>0&&Me(u)}catch{}const o=r.config??r.project??{},i=r.stories??{},a={};for(const[u,d]of Object.entries(i))a[u]={id:d.id??u,title:d.title,epic_id:d.epic_id,status:d.status??"backlog",steps_completed:d.steps_completed??[],last_step:d.last_step??null,branch_name:d.branch_name??null,pr_number:d.pr_number,...b(d.workflow_issue)?{workflow_issue:b(d.workflow_issue)}:{},...Ye(d),depends_on:q(d.depends_on),files_to_modify:je(d.files_to_modify),risk:typeof d.risk=="string"?d.risk:void 0,blast_radius:typeof d.blast_radius=="number"?d.blast_radius:void 0};const c=r.epics??{},l={};for(const[u,d]of Object.entries(c))l[u]={id:d.id??u,title:d.title,status:d.status,stories:d.stories,total_stories:d.total_stories,completed_stories:d.completed_stories,depends_on:q(d.depends_on)};return{schema_version:typeof r.schema_version=="number"?r.schema_version:void 0,config:{project_name:o.project_name??o.name??"unknown",default_branch:o.default_branch??"main",language:o.language??"pt-BR",yolo_mode:o.yolo_mode,user_name:o.user_name,worktree_base:o.worktree_base,max_parallel_stories:o.max_parallel_stories},stories:a,epics:l}}function Nt(e,t){return{kind:"full",trigger:e,targetEpicId:null,targetStoryId:null,includedStoryCount:Object.keys(t.stories).length,omittedStoryCount:0,omittedEpicCount:0,reason:"full-state"}}const J="neocortex:menu:cache";async function ze(e){try{const t=await e.get(J);if(!t)return null;const r=JSON.parse(t);return r.version!==S||Date.now()-r.cachedAt>K?null:r}catch{return null}}async function Ve(e,t,r){try{const o={instructions:t,metadata:r,cachedAt:Date.now(),version:S};await e.set(J,JSON.stringify(o),K),He()}catch{}}function He(){try{C(Y)&&se(Y)}catch{}}function Ge(){return fe()}async function qe(e,t){try{let r;if(t){const c=E(I,"cache");r=new U({cacheDir:c,passphrase:t})}else process.stderr.write(`[neocortex] Warning: No license key in config. Run "neocortex activate" to re-authenticate.
|
|
7
|
+
`),r=new de;const o=new ue({serverUrl:e,licenseKey:t??"",cacheProvider:r}),i=await o.getToken();if(!i)return null;const a=new pe({cacheProvider:r,licenseClient:o});return{token:i,client:o,tierClient:a}}catch{return null}}let W=!1;function X(e){return $("sha256").update(e).digest("hex")}function Je(){const e=Number(process.env.NEOCORTEX_INVOKE_CHUNK_BYTES??"49152");return Number.isFinite(e)&&e>=1024&&e<=98304?Math.floor(e):49152}function We(e,t,r){return`args-${$("sha256").update("invoke-materialization:v1").update(e).update(String(t)).update(JSON.stringify(r)).digest("hex")}`}async function Q(e,t,r,o){const i=await fetch(`${e}${t}`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o}`,"X-Client-Version":S},body:JSON.stringify(r)}),a=await i.text().catch(()=>""),c=(()=>{try{return a?JSON.parse(a):{}}catch{return{}}})();if(!i.ok){const l=typeof c.error_code=="string"?c.error_code:`HTTP_${i.status}`,u=typeof c.message=="string"?c.message:"materialization upload failed";throw new Error(`${l}: ${u}`)}return c}async function Xe(e,t,r){const o=Buffer.from(t,"utf8"),i=Je(),a=[];for(let f=0,h=0;f<o.byteLength;f+=i,h++){const _=o.subarray(f,Math.min(f+i,o.byteLength));a.push({index:h,sha256:X(_),byteLength:_.byteLength})}const c=X(o),l=We(c,o.byteLength,a),u=Number(process.env.NEOCORTEX_INVOKE_CHUNK_TTL_SECONDS??"900");for(const f of a){const h=f.index*i,_=o.subarray(h,h+f.byteLength);await Q(e,"/api/v1/invoke/materialization/chunks",{manifestId:l,index:f.index,sha256:f.sha256,byteLength:f.byteLength,contentBase64:_.toString("base64"),ttlSeconds:u,idempotencyKey:`${l}:${f.index}:${f.sha256}`},r)}const m=(await Q(e,"/api/v1/invoke/materialization/manifests",{manifestId:l,sha256:c,byteLength:o.byteLength,chunkCount:a.length,chunks:a,ttlSeconds:u,retry:{attempt:1,budget:3,idempotencyKey:l}},r)).argsRef;if(!m?.manifestId)throw new Error("MATERIALIZATION_RESPONSE_INVALID: missing argsRef");return{argsRef:m,chunks:a}}function Qe(e){return Buffer.byteLength(JSON.stringify(e),"utf8")}function Ze(e){return re(e)??e.trim().split(/\s+/,1)[0]?.slice(0,80)??"(empty)"}function et(e){return e.args!==void 0?Ze(e.args):`argsRef:${e.argsRef.manifestId.slice(0,80)}`}function Z(e){const t=Qe(e);if(t<H)return t;const r=e.stateSnapshot.scope,o=Object.keys(e.stateSnapshot.stories).length,i=r?.kind??"full",a=r?.includedStoryCount??o,c=r?.omittedStoryCount??0;return process.stderr.write(`[Neocortex] invoke payload near server limit: trigger=${et(e)} scope=${i} bytes=${t} limit=${V} includedStories=${a} omittedStories=${c}
|
|
8
|
+
`),t}async function tt(e){const t=Re(e.args,{platformTarget:e.platformTarget,environment:e.environment??process.env});if(t.action==="skipped")return{shouldContinue:!0,attachToRequest:rt(t),metadata:ee(t)};const r=e.bootstrapper??Te;let o;try{o=await r({projectRoot:e.projectRoot,env:e.environment??process.env})}catch{o={ok:!1,attempted:!0,installed:!1,started:!1,cached:!1,projectKey:"unknown",reasonCodes:[Ce.UNEXPECTED_ERROR],publicSummary:"runner scheduler bootstrap stopped unexpectedly.",publicSafe:!0}}const i=ee(t,o);if(o.ok)return{shouldContinue:!0,attachToRequest:!0,metadata:i};const a=i.reasonCodes.slice(0,5).join(",");return t.failurePolicy==="fail-open"?{shouldContinue:!0,attachToRequest:!0,metadata:{...i,failOpenWarning:!0},warning:`Runner auto-bootstrap warning (${a}); continuing fail-open for operator command.`}:{shouldContinue:!1,attachToRequest:!1,metadata:i,errorCode:"RUNNER_BOOTSTRAP_REQUIRED_FAILED",error:`Runner auto-bootstrap required but failed (${a}). Run neocortex-runner doctor or retry after resolving scheduler setup.`,exitCode:1}}function rt(e){return!e.reasonCodes.includes(we.SKIPPED_NON_CONTINUITY_COMMAND)}function ee(e,t){return{schemaVersion:1,action:e.action,failurePolicy:e.failurePolicy,command:e.command,operation:e.operation,attempted:t?.attempted??!1,ok:t?.ok??!0,cached:t?.cached??!1,installed:t?.installed??!1,started:t?.started??!1,...t?.projectKey?{projectKey:t.projectKey}:{},reasonCodes:nt([...e.reasonCodes,...t?.reasonCodes??[]]),publicSummary:t?.publicSummary??e.publicSummary,publicSafe:!0}}function nt(e){return Array.from(new Set(e.map(t=>t.slice(0,120))))}async function te(e,t,r){const o=`${e}/api/v1/invoke`,i=new AbortController,a=setTimeout(()=>i.abort(),z);try{const c=await fetch(o,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${r}`,"X-Client-Version":S},body:JSON.stringify(t),signal:i.signal});if(clearTimeout(a),!c.ok){const d=await c.text().catch(()=>"Unknown error");let m;try{m=JSON.parse(d)}catch{}return{ok:!1,status:c.status,error:m?`${m.error_code??"ERROR"}: ${m.message??d}`:`HTTP ${c.status}: ${d}`,errorBody:m}}const l=await c.json(),u=c.headers.get("X-Client-Version-Warning");return u&&!W&&(W=!0,process.stderr.write(`
|
|
9
9
|
[Neocortex] ${u}
|
|
10
10
|
|
|
11
|
-
`)),{ok:!0,status:c.status,data:l}}catch(c){clearTimeout(a);const l=c instanceof Error?c.message:String(c);return{ok:!1,status:0,error:l.includes("abort")?`Request timeout after ${
|
|
11
|
+
`)),{ok:!0,status:c.status,data:l}}catch(c){clearTimeout(a);const l=c instanceof Error?c.message:String(c);return{ok:!1,status:0,error:l.includes("abort")?`Request timeout after ${z/1e3}s`:`Network error: ${l}`}}}async function ot(e){const t=$e(e.projectRoot),r=e.platformTarget??"claude-code";Le();const o=Ge(),i=(e.serverUrl??o?.serverUrl??me).replace(/\/+$/,"");try{ye(t)}catch(n){if(n instanceof Ee)return process.stderr.write(`${n.message}
|
|
12
12
|
`),{success:!1,error:n.message,exitCode:1};const s=n instanceof Error?n.message:String(n);return process.stderr.write(`[Neocortex] state.json repair stopped unexpectedly: ${s}. No request was sent; inspect .neocortex/state.json and rerun.
|
|
13
13
|
`),{success:!1,error:s,exitCode:1}}const a=Ke(t);try{const{maybeAutoResolveYoloopArgs:n}=await import("../yoloop/invoke-hooks.js"),s={args:e.args,projectRoot:t,logger:{info:g=>process.stderr.write(`${g}
|
|
14
14
|
`),warn:g=>process.stderr.write(`${g}
|
|
@@ -18,11 +18,11 @@ ${t}
|
|
|
18
18
|
`)}try{const{readArchitecturePolicy:n}=await import("../policy/architecture-policy.js"),s=await n(t);s&&(a.architecture_policy=s)}catch(n){const s=n instanceof Error?n.message:String(n);console.warn(`[Neocortex] architecture-policy hook failed: ${s}. Proceeding without policy.`)}try{const n=/^(1|true|on|yes)$/i.test(process.env.NEOCORTEX_GRAPH_RETRIEVAL??""),{maybeRunGraphRetrievalHook:s}=await import("../yoloop/invoke-hooks.js"),g=await s({args:e.args,projectRoot:t,featureFlag:n,logger:{warn:A=>process.stderr.write(`${A}
|
|
19
19
|
`)}});g.applied&&g.metadata&&(a.graphRetrieval=g.metadata)}catch(n){const s=n instanceof Error?n.message:String(n);process.stderr.write(`[Neocortex] graph retrieval hook failed: ${s}. Proceeding without enrichment.
|
|
20
20
|
`)}try{const{readAndConsumeCheckpoint:n}=await import("../checkpoint/index.js"),s=await n(t);s&&(a.implementCheckpoint=s)}catch(n){const s=n instanceof Error?n.message:String(n);process.stderr.write(`[Neocortex] checkpoint hook failed: ${s}. Proceeding without checkpoint.
|
|
21
|
-
`)}const c=o?.licenseKey?new
|
|
22
|
-
`)}if(!l&&c){const n=await ze(c);if(n)return{success:!0,instructions:n.instructions,metadata:n.metadata,exitCode:0}}const u=await qe(i,o?.licenseKey);if(!u){const n=o&&!o.licenseKey?" This may be caused by a machine fingerprint change (e.g., hardware or hostname change).":"";try{const s=
|
|
21
|
+
`)}const c=o?.licenseKey?new U({cacheDir:B,passphrase:o.licenseKey}):null,l=e.args.trim();if(De(l))try{a.projectMemoryBootstrap=ve(t)}catch(n){const s=n instanceof Error?n.message:String(n);process.stderr.write(`[Neocortex] project-memory bootstrap diagnosis failed: ${s}. Proceeding without local memory snapshot.
|
|
22
|
+
`)}if(!l&&c){const n=await ze(c);if(n)return{success:!0,instructions:n.instructions,metadata:n.metadata,exitCode:0}}const u=await qe(i,o?.licenseKey);if(!u){const n=o&&!o.licenseKey?" This may be caused by a machine fingerprint change (e.g., hardware or hostname change).":"";try{const s=j(),g=F("NOT_CONFIGURED",s);g&&process.stderr.write(M(g,s))}catch{}return{success:!1,error:`Not authenticated.${n} Visit https://neocortex.sh/portal/login to get your license key, then run: neocortex activate YOUR-LICENSE-KEY`,exitCode:2}}const d=re(l);if(d)try{const n=await u.tierClient.preFlightCheck(d);if(!n.allowed)return process.stderr.write(`[neocortex] ${n.message}
|
|
23
23
|
`),{success:!1,error:n.message??"Trigger not available on your plan",exitCode:1}}catch{}const m=await tt({args:l,projectRoot:t,platformTarget:r,environment:e.environment??process.env,bootstrapper:e.runnerBootstrapper});if(m.attachToRequest&&(a.runnerBootstrap=m.metadata),m.warning&&process.stderr.write(`[Neocortex] ${m.warning}
|
|
24
24
|
`),!m.shouldContinue)return m.error&&process.stderr.write(`[Neocortex] ${m.error}
|
|
25
|
-
`),{success:!1,error:m.error??"Runner auto-bootstrap required but failed.",errorCode:m.errorCode,exitCode:m.exitCode??1};const f=_e(l,a);let h={args:l,projectRoot:t.replace(
|
|
25
|
+
`),{success:!1,error:m.error??"Runner auto-bootstrap required but failed.",errorCode:m.errorCode,exitCode:m.exitCode??1};const f=_e(l,a);let h={args:l,projectRoot:t.replace(k(),"~"),stateSnapshot:f,platformTarget:r};const _=Z(h);if(e.inputSource&&e.inputSource!=="args"&&_>=H)try{h={argsRef:(await Xe(i,l,u.token)).argsRef,projectRoot:t.replace(k(),"~"),stateSnapshot:f,platformTarget:r},Z(h)}catch(n){return{success:!1,error:`INVOKE_MATERIALIZATION_FAILED: ${n instanceof Error?n.message:String(n)}`,errorCode:"INVOKE_MATERIALIZATION_FAILED",exitCode:1}}let p=await te(i,h,u.token);if(!p.ok&&p.status===401){const n=p.errorBody?.fallback_action;if(n==="refresh_token"||n==="re_authenticate"){const s=await u.client.forceRefresh();s&&(p=await te(i,h,s))}}if(!p.ok&&p.status===426){const n=p.errorBody,s=n?.upgrade_command??"npm install -g @ornexus/neocortex@latest",g=n?.min_version??"unknown";return process.stderr.write(`
|
|
26
26
|
`),process.stderr.write(`==================================================
|
|
27
27
|
`),process.stderr.write(` UPGRADE REQUIRED
|
|
28
28
|
`),process.stderr.write(`==================================================
|
|
@@ -37,7 +37,7 @@ ${t}
|
|
|
37
37
|
`),process.stderr.write(` After updating, re-run your command.
|
|
38
38
|
`),process.stderr.write(`==================================================
|
|
39
39
|
|
|
40
|
-
`),{success:!1,error:`UPGRADE_REQUIRED: Client version ${S} is below minimum ${g}. Run: ${s}`,exitCode:3}}if(!p.ok||!p.data){const n=p.status===401?2:(p.status===429||p.status>=500,1);try{const s=p.errorBody?.error_code??(p.status===429?"RATE_LIMITED":p.status>=500?"SERVER_ERROR":void 0);if(s){const g=
|
|
40
|
+
`),{success:!1,error:`UPGRADE_REQUIRED: Client version ${S} is below minimum ${g}. Run: ${s}`,exitCode:3}}if(!p.ok||!p.data){const n=p.status===401?2:(p.status===429||p.status>=500,1);try{const s=p.errorBody?.error_code??(p.status===429?"RATE_LIMITED":p.status>=500?"SERVER_ERROR":void 0);if(s){const g=j(),A=F(s,g);A&&process.stderr.write(M(A,g))}}catch{}return{success:!1,error:T(p.error??"Unknown error from server",O),exitCode:n}}if(!l&&p.data.metadata?.mode==="menu"&&c&&Ve(c,p.data.instructions,p.data.metadata).catch(()=>{}),p.data.metadata&&u.tierClient.updateQuotaFromResponse(p.data.metadata).catch(()=>{}),p.data.metadata?.mode==="error"&&p.data.metadata?.errorCode==="CLIENT_UPGRADE_REQUIRED")return process.stderr.write(`
|
|
41
41
|
`),process.stderr.write(`==================================================
|
|
42
42
|
`),process.stderr.write(` YOLOOP CLIENT UPGRADE REQUIRED
|
|
43
43
|
`),process.stderr.write(`==================================================
|
|
@@ -57,9 +57,9 @@ ${t}
|
|
|
57
57
|
`),{success:!1,error:`CONTINUITY_PERSISTENCE_FAILED: ${T(s,O)}`,errorCode:"CONTINUITY_PERSISTENCE_FAILED",exitCode:1}}if(p.data.metadata?.stateMutated===!0)try{const{persistMigratedStateFromResponse:n}=await import("../yoloop/invoke-hooks.js");await n(p.data.metadata,t)}catch{}if(p.data.metadata?.tier_changed){const n=p.data.metadata.current_tier;try{await u.client.forceRefresh()?(await u.tierClient.invalidateTierCache(),process.stderr.write(`[Neocortex] Token atualizado automaticamente para tier ${n}
|
|
58
58
|
`)):process.stderr.write(`[Neocortex] Seu tier foi atualizado para ${n}! Execute "neocortex activate" para obter um token atualizado.
|
|
59
59
|
`)}catch{process.stderr.write(`[Neocortex] Seu tier foi atualizado para ${n}! Execute "neocortex activate" para obter um token atualizado.
|
|
60
|
-
`)}}const
|
|
60
|
+
`)}}const L=P(p.data.instructions,p.data.metadata);return{success:!0,instructions:L.instructions,metadata:L.metadata,exitCode:0}}function re(e){const[t]=e.trim().split(/\s+/,1);return t?/^@?epic-[a-z0-9][a-z0-9._-]*$/i.test(t)?"epic":le(t):null}const ne="Provide exactly one invoke input source: --args <string>, --stdin, or --args-file <path>.";function oe(e){return new y("INVOKE_INPUT_VALUE_MISSING",`${e} requires a value. ${ne}`)}function st(e){try{if(!ce(e).isFile())throw new y("INVOKE_ARGS_FILE_NOT_FILE","--args-file must point to a readable UTF-8 text file.");return N(e,"utf8")}catch(t){throw t instanceof y?t:new y("INVOKE_ARGS_FILE_READ_FAILED","--args-file could not be read as UTF-8 text. Check the path and permissions.")}}function it(){try{if(process.stdin.isTTY)throw new y("INVOKE_STDIN_EMPTY","--stdin requires piped UTF-8 text, for example: neocortex-client invoke --stdin < synthetic.story.md");return N(0,"utf8")}catch(e){throw e instanceof y?e:new y("INVOKE_STDIN_READ_FAILED","--stdin could not be read as UTF-8 text. Pipe command text into stdin and retry.")}}function at(e,t={}){let r,o=!1,i,a,c="plain",l;for(let f=0;f<e.length;f++)switch(e[f]){case"--args":{const _=e[++f];if(_===void 0)throw oe("--args");r=_;break}case"--stdin":o=!0;break;case"--args-file":{const _=e[++f];if(_===void 0)throw oe("--args-file");i=_;break}case"--project-root":a=e[++f];break;case"--format":c=e[++f]??"plain";break;case"--server-url":l=e[++f];break}const u=[r!==void 0?"args":void 0,o?"stdin":void 0,i!==void 0?"args-file":void 0].filter(f=>f!==void 0);if(u.length===0)throw new y("INVOKE_INPUT_SOURCE_MISSING",ne);if(u.length>1)throw new y("INVOKE_INPUT_SOURCE_CONFLICT",`Choose only one invoke input source; received ${u.join(", ")}.`);const d=u[0];return{args:d==="args"?r:d==="stdin"?(t.readStdin??it)():(t.readArgsFile??st)(i),inputSource:d,projectRoot:a,format:c,serverUrl:l}}async function It(e){let t;try{t=at(e)}catch(o){if(o instanceof y)return process.stderr.write(JSON.stringify({error_code:o.code,message:o.message})+`
|
|
61
61
|
`),1;throw o}const r=await ot({args:t.args,inputSource:t.inputSource,projectRoot:t.projectRoot,format:t.format,serverUrl:t.serverUrl});if(!r.success)return process.stderr.write(JSON.stringify({error_code:r.errorCode??(r.exitCode===2?"NOT_CONFIGURED":"INVOKE_ERROR"),message:T(r.error??"",O)})+`
|
|
62
|
-
`),r.exitCode;if(t.format==="json"){const o=
|
|
63
|
-
`)}else{const o=
|
|
62
|
+
`),r.exitCode;if(t.format==="json"){const o=P(r.instructions,r.metadata);process.stdout.write(JSON.stringify({instructions:o.instructions,metadata:o.metadata})+`
|
|
63
|
+
`)}else{const o=P(r.instructions,r.metadata);process.stdout.write(o.instructions+`
|
|
64
64
|
`),o.metadata&&process.stderr.write(JSON.stringify(o.metadata)+`
|
|
65
|
-
`)}return 0}export{
|
|
65
|
+
`)}return 0}export{H as INVOKE_PAYLOAD_WARNING_THRESHOLD_BYTES,y as InvokeCliInputError,At as __resetSchemaDriftWarnedForTests,ve as collectInitProjectMemoryBootstrapSnapshot,Ke as collectStateSnapshot,Qe as computeInvokeRequestBodySizeBytes,Nt as createFullStateSnapshotScope,Fe as detectStateSchemaDrift,re as extractPreFlightTrigger,ot as invoke,It as invokeCliHandler,De as isInitTrigger,Z as maybeEmitInvokePayloadSizeWarning,tt as maybeRunInvokeRunnerAutoBootstrap,at as parseInvokeCliOptions,$e as resolveInvokeProjectRoot,P as sanitizeInvokeCliOutput};
|
|
@@ -9,7 +9,7 @@ export declare const CONTINUITY_SQLITE_FILENAME: "continuity.sqlite";
|
|
|
9
9
|
export declare const CONTINUITY_SQLITE_SCHEMA_VERSION: 1;
|
|
10
10
|
export declare const DEFAULT_CONTINUITY_SQLITE_BUSY_TIMEOUT_MS = 5000;
|
|
11
11
|
export declare const SQLITE_ADAPTER_INSTALL_GUIDANCE = "Install the optional Enterprise continuity SQLite adapter with `npm install --workspace packages/client better-sqlite3 --include=optional` or reinstall Neocortex with optional dependencies enabled.";
|
|
12
|
-
export type ContinuitySqliteStoreErrorCode = 'sqlite-adapter-unavailable' | 'sqlite-integrity-failed' | 'sqlite-migration-failed' | 'sqlite-migration-conflict' | 'sqlite-foreign-key-failed' | 'sqlite-public-safety-rejected' | 'sqlite-mutation-blocked';
|
|
12
|
+
export type ContinuitySqliteStoreErrorCode = 'sqlite-adapter-unavailable' | 'sqlite-integrity-failed' | 'sqlite-migration-failed' | 'sqlite-migration-conflict' | 'sqlite-mutation-failed' | 'sqlite-foreign-key-failed' | 'sqlite-public-safety-rejected' | 'sqlite-mutation-blocked';
|
|
13
13
|
export declare class ContinuitySqliteStoreError extends Error {
|
|
14
14
|
readonly code: ContinuitySqliteStoreErrorCode;
|
|
15
15
|
readonly reasonCode: ContinuitySqliteStoreErrorCode;
|
|
@@ -31,13 +31,16 @@ export interface ContinuitySqliteStatement {
|
|
|
31
31
|
get(...params: readonly unknown[]): unknown;
|
|
32
32
|
all(...params: readonly unknown[]): readonly unknown[];
|
|
33
33
|
}
|
|
34
|
+
export type ContinuitySqliteTransaction<T extends (...args: never[]) => unknown> = T & {
|
|
35
|
+
readonly immediate?: T;
|
|
36
|
+
};
|
|
34
37
|
export interface ContinuitySqliteDatabase {
|
|
35
38
|
pragma(source: string, options?: {
|
|
36
39
|
readonly simple?: boolean;
|
|
37
40
|
}): unknown;
|
|
38
41
|
exec(source: string): void;
|
|
39
42
|
prepare(source: string): ContinuitySqliteStatement;
|
|
40
|
-
transaction<T extends (...args: never[]) => unknown>(fn: T): T
|
|
43
|
+
transaction<T extends (...args: never[]) => unknown>(fn: T): ContinuitySqliteTransaction<T>;
|
|
41
44
|
close(): void;
|
|
42
45
|
}
|
|
43
46
|
export interface ContinuitySqliteAdapter {
|
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
import{createHash as T}from"node:crypto";import{chmodSync as
|
|
1
|
+
import{createHash as T}from"node:crypto";import{chmodSync as y,existsSync as C,mkdirSync as N}from"node:fs";import{join as g}from"node:path";import{INITIAL_CONTINUITY_SQLITE_MIGRATION as O}from"./migrations/001-initial-schema.js";const f=".neocortex/continuity",A="continuity.sqlite",K=1,j=5e3,I="Install the optional Enterprise continuity SQLite adapter with `npm install --workspace packages/client better-sqlite3 --include=optional` or reinstall Neocortex with optional dependencies enabled.";class i extends Error{code;reasonCode;guidance;mutationBlocked;cause;constructor(e,t,a={}){super(t),this.name="ContinuitySqliteStoreError",this.code=e,this.reasonCode=e,this.guidance=a.guidance,this.cause=a.cause,this.mutationBlocked=a.mutationBlocked??e==="sqlite-integrity-failed"}}const R=[O],L=Object.freeze(["continuity_migrations","jobs","job_leases","job_events","job_receipts","goal_campaigns","goal_ledger_items","goal_verifiers","goal_review_gates","loop_jobs","artifacts","state_snapshots","runner_config","outbox"]),w=/(raw[_-]?logs?|prompt(?:[_-]?(?:body|text))?|private[_-]?urls?|secret|token|password|protected(?:[_-]?(?:field|body|internals))?|workflow(?:[_-]?body)?|step(?:[_-]?body)?|customer(?:[_-]?(?:pii|data))?|authorization|api[_-]?key|license[_-]?key)/i,S=/(https?:\/\/\S+|ghp_[A-Za-z0-9_]+|sk-[A-Za-z0-9_-]+|-----BEGIN [A-Z ]*PRIVATE KEY-----|authorization\s*:|password\s*=|token\s*=|api[_-]?key\s*=|license[_-]?key\s*=|raw[_-]?log|transcript|stack trace|stderr:|stdout:|system prompt|workflow body|step body|PROTECTED_|PRIVATE_INTERNALS|CUSTOMER_PII|VENDOR_CORPUS|P180[_-]?SYNTHETIC[_-]?CONTINUITY)/i,k=/(corrupt|malformed|not a database|file is not a database|database disk image is malformed)/i,x=/(foreign key constraint failed|SQLITE_CONSTRAINT_FOREIGNKEY)/i;function M(r){return new Function("specifier","return import(specifier)")(r)}function v(r){return`sha256:${T("sha256").update(r).digest("hex")}`}function _(r){return typeof r=="object"&&r!==null&&!Array.isArray(r)}function U(r){return r instanceof Error?r.message:String(r)}function q(r){return _(r)&&typeof r.code=="string"?r.code:void 0}function n(r,e){if(r instanceof i)return r;const t=U(r),a=q(r);return a==="SQLITE_CORRUPT"||a==="SQLITE_NOTADB"||k.test(t)?new i("sqlite-integrity-failed","Continuity SQLite integrity check failed; durable mutation is blocked until the store is repaired or rebuilt.",{cause:r,mutationBlocked:!0}):a==="SQLITE_CONSTRAINT_FOREIGNKEY"||x.test(t)?new i("sqlite-foreign-key-failed","Continuity SQLite foreign-key validation failed; mutation was rejected.",{cause:r}):new i(e,t,{cause:r})}function b(r,e){if(typeof r=="string"){if(S.test(r))throw new i("sqlite-public-safety-rejected",`Continuity SQLite metadata rejected unsafe value at ${e}.`);return}if(!(r===null||typeof r=="number"||typeof r=="boolean")){if(Array.isArray(r)){r.forEach((t,a)=>b(t,`${e}[${a}]`));return}if(_(r)){for(const[t,a]of Object.entries(r)){if(w.test(t))throw new i("sqlite-public-safety-rejected",`Continuity SQLite metadata rejected unsafe key at ${e}.${t}.`);b(a,`${e}.${t}`)}return}throw new i("sqlite-public-safety-rejected",`Continuity SQLite metadata rejected unsupported value at ${e}.`)}}function c(r,e){if(r!==void 0&&S.test(r))throw new i("sqlite-public-safety-rejected",`Continuity SQLite text rejected unsafe value at ${e}.`)}function l(r){return r?(b(r,"metadata"),JSON.stringify(r)):null}function p(r){if(Array.isArray(r)){const e=r[0];return _(e)?Object.values(e)[0]:e}return _(r)?Object.values(r)[0]:r}function D(r){return L.includes(r)}function F(r){return Array.from(new Set(r))}function W(r){const e=_(r)&&"default"in r?r.default:r;if(typeof e!="function")throw new i("sqlite-adapter-unavailable","Optional better-sqlite3 adapter did not export a database constructor.",{guidance:I});const t=e;return{adapterName:"better-sqlite3",open(a,s){return new t(a,s)}}}async function P(r=M){try{const e=await r("better-sqlite3");return{ok:!0,adapter:W(e)}}catch(e){return e instanceof i?{ok:!1,error:e}:{ok:!1,error:new i("sqlite-adapter-unavailable","Optional Enterprise continuity SQLite adapter better-sqlite3 is unavailable.",{cause:e,guidance:I})}}}function H(r){return g(r,f,A)}function B(r){const e=g(r,f);N(e,{recursive:!0,mode:448});try{y(e,448)}catch{}return e}async function z(r){const e=r.adapter??await J(r.adapterLoader);B(r.projectRoot);const t=H(r.projectRoot);let a;try{a=e.open(t)}catch(o){throw n(o,"sqlite-integrity-failed")}const s=new Q({db:a,filePath:t,adapterName:e.adapterName,busyTimeoutMs:r.busyTimeoutMs??j,integrityCheck:r.integrityCheck??!0,now:r.now??(()=>new Date().toISOString())});try{if(s.initialize(),C(t))try{y(t,384)}catch{}return s}catch(o){try{a.close()}catch{}throw o}}async function J(r){const e=r?await r():await P();if(!e.ok)throw e.error;return e.adapter}class Q{filePath;adapterName;db;busyTimeoutMs;integrityCheck;now;mutationBlocked=!1;constructor(e){this.db=e.db,this.filePath=e.filePath,this.adapterName=e.adapterName,this.busyTimeoutMs=e.busyTimeoutMs,this.integrityCheck=e.integrityCheck,this.now=e.now}initialize(){try{this.configureConnection(),this.integrityCheck&&this.runIntegrityCheck(),this.ensureMigrationTable(),this.applyMigrations(),this.integrityCheck&&this.runIntegrityCheck()}catch(e){throw n(e,"sqlite-migration-failed")}}close(){this.db.close()}pragmaValue(e){return p(this.db.pragma(e,{simple:!0}))}runIntegrityCheck(){try{if(String(p(this.db.pragma("integrity_check",{simple:!0}))??"").toLowerCase()!=="ok")throw this.mutationBlocked=!0,new i("sqlite-integrity-failed","Continuity SQLite integrity check failed; durable mutation is blocked until the store is repaired or rebuilt.",{mutationBlocked:!0})}catch(e){throw this.mutationBlocked=!0,n(e,"sqlite-integrity-failed")}}getSchemaVersion(){const e=this.db.prepare("SELECT COALESCE(MAX(version), 0) AS version FROM continuity_migrations").get();return _(e)&&typeof e.version=="number"?e.version:0}countRows(e){if(!D(e))throw new i("sqlite-public-safety-rejected","Unknown continuity table name.");const t=this.db.prepare(`SELECT COUNT(*) AS count FROM ${e}`).get();return _(t)&&typeof t.count=="number"?t.count:0}recordJob(e){this.assertCanMutate(),c(e.summary,"jobs.summary");const t=l(e.metadata);try{const a=this.db.prepare(`
|
|
2
2
|
INSERT OR IGNORE INTO jobs (
|
|
3
3
|
job_id, kind, status, summary, reason_code, created_at, updated_at,
|
|
4
4
|
next_run_at, goal_id, loop_id, campaign_id, operation_id,
|
|
5
5
|
idempotency_key, metadata_json
|
|
6
6
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
7
|
-
`).run(e.jobId,e.kind,e.status,e.summary??null,e.reasonCode??null,e.createdAt,e.updatedAt,e.nextRunAt??null,e.goalId??null,e.loopId??null,e.campaignId??null,e.operationId??null,e.idempotencyKey??null,t);return this.toWriteResult(a)}catch(a){throw n(a,"sqlite-
|
|
7
|
+
`).run(e.jobId,e.kind,e.status,e.summary??null,e.reasonCode??null,e.createdAt,e.updatedAt,e.nextRunAt??null,e.goalId??null,e.loopId??null,e.campaignId??null,e.operationId??null,e.idempotencyKey??null,t);return this.toWriteResult(a)}catch(a){throw n(a,"sqlite-mutation-failed")}}appendEvent(e){this.assertCanMutate(),c(e.summary,"job_events.summary");const t=l(e.metadata);try{const a=this.db.prepare(`
|
|
8
8
|
INSERT OR IGNORE INTO job_events (
|
|
9
9
|
event_id, job_id, operation_id, idempotency_key, event_sequence,
|
|
10
10
|
type, summary, reason_code, created_at, metadata_json
|
|
11
11
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
12
|
-
`).run(e.eventId,e.jobId,e.operationId,e.idempotencyKey??null,e.sequence??null,e.type,e.summary,e.reasonCode??null,e.createdAt,t);return this.toWriteResult(a)}catch(a){throw n(a,"sqlite-
|
|
12
|
+
`).run(e.eventId,e.jobId,e.operationId,e.idempotencyKey??null,e.sequence??null,e.type,e.summary,e.reasonCode??null,e.createdAt,t);return this.toWriteResult(a)}catch(a){throw n(a,"sqlite-mutation-failed")}}appendReceipt(e){this.assertCanMutate();const t=l(e.metadata);try{const a=this.db.prepare(`
|
|
13
13
|
INSERT OR IGNORE INTO job_receipts (
|
|
14
14
|
receipt_id, job_id, operation_id, idempotency_key, status, reason_code,
|
|
15
15
|
applied_operation_ids_json, ignored_operation_ids_json, created_at, metadata_json
|
|
16
16
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
17
|
-
`).run(e.receiptId,e.jobId,e.operationId??null,e.idempotencyKey??null,e.status,e.reasonCode??null,e.appliedOperationIds?JSON.stringify(e.appliedOperationIds):null,e.ignoredOperationIds?JSON.stringify(e.ignoredOperationIds):null,e.createdAt,t);return this.toWriteResult(a)}catch(a){throw n(a,"sqlite-
|
|
17
|
+
`).run(e.receiptId,e.jobId,e.operationId??null,e.idempotencyKey??null,e.status,e.reasonCode??null,e.appliedOperationIds?JSON.stringify(e.appliedOperationIds):null,e.ignoredOperationIds?JSON.stringify(e.ignoredOperationIds):null,e.createdAt,t);return this.toWriteResult(a)}catch(a){throw n(a,"sqlite-mutation-failed")}}updateJobStatus(e){this.assertCanMutate();try{const t=this.db.prepare(`
|
|
18
18
|
UPDATE jobs
|
|
19
19
|
SET status = ?,
|
|
20
20
|
reason_code = COALESCE(?, reason_code),
|
|
21
21
|
updated_at = ?,
|
|
22
22
|
next_run_at = COALESCE(?, next_run_at)
|
|
23
23
|
WHERE job_id = ?
|
|
24
|
-
`).run(e.status,e.reasonCode??null,e.updatedAt,e.nextRunAt??null,e.jobId);if(t.changes===0)throw new i("sqlite-foreign-key-failed",`Continuity SQLite job ${e.jobId} was not found for status update.`);return this.toWriteResult(t)}catch(t){throw n(t,"sqlite-
|
|
24
|
+
`).run(e.status,e.reasonCode??null,e.updatedAt,e.nextRunAt??null,e.jobId);if(t.changes===0)throw new i("sqlite-foreign-key-failed",`Continuity SQLite job ${e.jobId} was not found for status update.`);return this.toWriteResult(t)}catch(t){throw n(t,"sqlite-mutation-failed")}}scheduleNextTick(e){return this.updateJobStatus({jobId:e.jobId,status:"active",updatedAt:e.updatedAt,reasonCode:e.reasonCode,nextRunAt:e.scheduledAt})}acquireLease(e){this.assertCanMutate();const t=l(e.metadata);try{const a=this.db.prepare(`
|
|
25
25
|
INSERT OR IGNORE INTO job_leases (
|
|
26
26
|
lease_id, job_id, runner_id, status, acquired_at, expires_at,
|
|
27
27
|
operation_id, idempotency_key, metadata_json
|
|
28
28
|
) VALUES (?, ?, ?, 'acquired', ?, ?, ?, ?, ?)
|
|
29
|
-
`).run(e.leaseId,e.jobId,e.runnerId,e.acquiredAt,e.expiresAt,e.operationId??null,e.idempotencyKey??null,t);return this.toWriteResult(a)}catch(a){throw n(a,"sqlite-
|
|
29
|
+
`).run(e.leaseId,e.jobId,e.runnerId,e.acquiredAt,e.expiresAt,e.operationId??null,e.idempotencyKey??null,t);return this.toWriteResult(a)}catch(a){throw n(a,"sqlite-mutation-failed")}}releaseLease(e){this.assertCanMutate();try{const t=this.db.prepare(`
|
|
30
30
|
UPDATE job_leases
|
|
31
31
|
SET status = 'released', released_at = ?
|
|
32
32
|
WHERE lease_id = ? AND released_at IS NULL
|
|
33
|
-
`).run(e.releasedAt,e.leaseId);if(t.changes===0)throw new i("sqlite-foreign-key-failed",`Continuity SQLite lease ${e.leaseId} was not found for release.`);return this.toWriteResult(t)}catch(t){throw n(t,"sqlite-
|
|
33
|
+
`).run(e.releasedAt,e.leaseId);if(t.changes===0)throw new i("sqlite-foreign-key-failed",`Continuity SQLite lease ${e.leaseId} was not found for release.`);return this.toWriteResult(t)}catch(t){throw n(t,"sqlite-mutation-failed")}}recordStateSnapshot(e){this.assertCanMutate(),c(e.summary,"state_snapshots.summary"),c(e.relativePath,"state_snapshots.relative_path");const t=l(e.metadata);try{const a=this.db.prepare(`
|
|
34
34
|
INSERT OR IGNORE INTO state_snapshots (
|
|
35
35
|
snapshot_id, job_id, kind, relative_path, sha256, summary, captured_at,
|
|
36
36
|
operation_id, idempotency_key, metadata_json
|
|
37
37
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
38
|
-
`).run(e.snapshotId,e.jobId??null,e.kind,e.relativePath??null,e.sha256??null,e.summary??null,e.capturedAt,e.operationId??null,e.idempotencyKey??null,t);return this.toWriteResult(a)}catch(a){throw n(a,"sqlite-
|
|
38
|
+
`).run(e.snapshotId,e.jobId??null,e.kind,e.relativePath??null,e.sha256??null,e.summary??null,e.capturedAt,e.operationId??null,e.idempotencyKey??null,t);return this.toWriteResult(a)}catch(a){throw n(a,"sqlite-mutation-failed")}}recordArtifact(e){this.assertCanMutate(),c(e.kind,"artifacts.kind"),c(e.relativePath,"artifacts.relative_path"),c(e.summary,"artifacts.summary");const t=l(e.metadata);try{const a=this.db.prepare(`
|
|
39
39
|
INSERT OR IGNORE INTO artifacts (
|
|
40
40
|
artifact_id, job_id, kind, relative_path, sha256, summary,
|
|
41
41
|
operation_id, idempotency_key, created_at, metadata_json
|
|
42
42
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
43
|
-
`).run(e.artifactId,e.jobId??null,e.kind,e.relativePath,e.sha256??null,e.summary??null,e.operationId??null,e.idempotencyKey??null,e.createdAt,t);return this.toWriteResult(a)}catch(a){throw n(a,"sqlite-
|
|
43
|
+
`).run(e.artifactId,e.jobId??null,e.kind,e.relativePath,e.sha256??null,e.summary??null,e.operationId??null,e.idempotencyKey??null,e.createdAt,t);return this.toWriteResult(a)}catch(a){throw n(a,"sqlite-mutation-failed")}}enqueueOutbox(e){this.assertCanMutate();const t=l(e.payload);try{const a=this.db.prepare(`
|
|
44
44
|
INSERT OR IGNORE INTO outbox (
|
|
45
45
|
outbox_id, job_id, operation_id, idempotency_key, type, status,
|
|
46
46
|
payload_json, retry_count, next_attempt_at, last_error_code,
|
|
47
47
|
created_at, updated_at
|
|
48
48
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
49
|
-
`).run(e.outboxId,e.jobId??null,e.operationId,e.idempotencyKey??null,e.type,e.status??"pending",t??"{}",e.retryCount??0,e.nextAttemptAt??null,e.lastErrorCode??null,e.createdAt,e.updatedAt);return this.toWriteResult(a)}catch(a){throw n(a,"sqlite-
|
|
49
|
+
`).run(e.outboxId,e.jobId??null,e.operationId,e.idempotencyKey??null,e.type,e.status??"pending",t??"{}",e.retryCount??0,e.nextAttemptAt??null,e.lastErrorCode??null,e.createdAt,e.updatedAt);return this.toWriteResult(a)}catch(a){throw n(a,"sqlite-mutation-failed")}}retryOutboxEntries(e){this.assertCanMutate();const t=Math.max(1,Math.min(100,Math.floor(e.limit))),a=F(e.statuses?.length?e.statuses:["failed","dead_letter"]),s=e.reasonCode??"backoff-scheduled";c(s,"outbox.last_error_code"),c(e.nextAttemptAt,"outbox.next_attempt_at");try{return this.runInTransaction(()=>{const o=a.map(()=>"?").join(", "),d=this.db.prepare(`
|
|
50
50
|
SELECT outbox_id
|
|
51
51
|
FROM outbox
|
|
52
52
|
WHERE status IN (${o})
|
|
@@ -60,7 +60,7 @@ import{createHash as T}from"node:crypto";import{chmodSync as b,existsSync as C,m
|
|
|
60
60
|
last_error_code = ?,
|
|
61
61
|
updated_at = ?
|
|
62
62
|
WHERE outbox_id IN (${h})
|
|
63
|
-
`).run(e.nextAttemptAt??e.nowIso,s,e.nowIso,...d);return{retriedOutboxIds:d,changes:E.changes,reasonCode:s,publicSafe:!0}})}catch(o){throw n(o,"sqlite-
|
|
63
|
+
`).run(e.nextAttemptAt??e.nowIso,s,e.nowIso,...d);return{retriedOutboxIds:d,changes:E.changes,reasonCode:s,publicSafe:!0}})}catch(o){throw n(o,"sqlite-mutation-failed")}}upsertGoalCampaign(e){this.assertCanMutate(),c(e.title,"goal_campaigns.title"),c(e.publicSummary,"goal_campaigns.public_summary");const t=l(e.metadata);try{const a=this.db.prepare(`
|
|
64
64
|
INSERT INTO goal_campaigns (
|
|
65
65
|
campaign_id, job_id, status, title, public_summary, reason_code,
|
|
66
66
|
created_at, updated_at, operation_id, idempotency_key, metadata_json
|
|
@@ -74,7 +74,7 @@ import{createHash as T}from"node:crypto";import{chmodSync as b,existsSync as C,m
|
|
|
74
74
|
operation_id = excluded.operation_id,
|
|
75
75
|
idempotency_key = excluded.idempotency_key,
|
|
76
76
|
metadata_json = excluded.metadata_json
|
|
77
|
-
`).run(e.campaignId,e.jobId,e.status,e.title??null,e.publicSummary??null,e.reasonCode??null,e.createdAt,e.updatedAt,e.operationId??null,e.idempotencyKey??null,t);return this.toWriteResult(a)}catch(a){throw n(a,"sqlite-
|
|
77
|
+
`).run(e.campaignId,e.jobId,e.status,e.title??null,e.publicSummary??null,e.reasonCode??null,e.createdAt,e.updatedAt,e.operationId??null,e.idempotencyKey??null,t);return this.toWriteResult(a)}catch(a){throw n(a,"sqlite-mutation-failed")}}upsertGoalLedgerItem(e){this.assertCanMutate(),c(e.summary,"goal_ledger_items.summary");const t=l(e.metadata);try{this.ensureGoalCampaign(e.campaignId,e.jobId,e.createdAt,e.updatedAt);const a=this.db.prepare(`
|
|
78
78
|
INSERT INTO goal_ledger_items (
|
|
79
79
|
item_id, campaign_id, operation_id, idempotency_key, item_type, status,
|
|
80
80
|
summary, reason_code, created_at, updated_at, metadata_json
|
|
@@ -85,7 +85,7 @@ import{createHash as T}from"node:crypto";import{chmodSync as b,existsSync as C,m
|
|
|
85
85
|
reason_code = excluded.reason_code,
|
|
86
86
|
updated_at = excluded.updated_at,
|
|
87
87
|
metadata_json = excluded.metadata_json
|
|
88
|
-
`).run(e.itemId,e.campaignId,e.operationId??null,e.idempotencyKey??null,e.itemType,e.status,e.summary,e.reasonCode??null,e.createdAt,e.updatedAt,t);return this.toWriteResult(a)}catch(a){throw n(a,"sqlite-
|
|
88
|
+
`).run(e.itemId,e.campaignId,e.operationId??null,e.idempotencyKey??null,e.itemType,e.status,e.summary,e.reasonCode??null,e.createdAt,e.updatedAt,t);return this.toWriteResult(a)}catch(a){throw n(a,"sqlite-mutation-failed")}}upsertGoalVerifier(e){this.assertCanMutate(),c(e.summary,"goal_verifiers.summary");const t=l(e.metadata);try{const a=e.lastCheckedAt??this.now();this.ensureGoalCampaign(e.campaignId,e.jobId,a,a);const s=this.db.prepare(`
|
|
89
89
|
INSERT INTO goal_verifiers (
|
|
90
90
|
verifier_id, campaign_id, kind, status, summary, reason_code,
|
|
91
91
|
last_checked_at, operation_id, idempotency_key, metadata_json
|
|
@@ -96,7 +96,7 @@ import{createHash as T}from"node:crypto";import{chmodSync as b,existsSync as C,m
|
|
|
96
96
|
reason_code = excluded.reason_code,
|
|
97
97
|
last_checked_at = excluded.last_checked_at,
|
|
98
98
|
metadata_json = excluded.metadata_json
|
|
99
|
-
`).run(e.verifierId,e.campaignId,e.kind,e.status,e.summary??null,e.reasonCode??null,e.lastCheckedAt??null,e.operationId??null,e.idempotencyKey??null,t);return this.toWriteResult(s)}catch(a){throw n(a,"sqlite-
|
|
99
|
+
`).run(e.verifierId,e.campaignId,e.kind,e.status,e.summary??null,e.reasonCode??null,e.lastCheckedAt??null,e.operationId??null,e.idempotencyKey??null,t);return this.toWriteResult(s)}catch(a){throw n(a,"sqlite-mutation-failed")}}upsertGoalReviewGate(e){this.assertCanMutate(),c(e.summary,"goal_review_gates.summary");const t=l(e.metadata);try{const a=this.now();this.ensureGoalCampaign(e.campaignId,e.jobId,a,a);const s=this.db.prepare(`
|
|
100
100
|
INSERT INTO goal_review_gates (
|
|
101
101
|
gate_id, campaign_id, status, summary, required, reason_code,
|
|
102
102
|
operation_id, idempotency_key, metadata_json
|
|
@@ -107,7 +107,7 @@ import{createHash as T}from"node:crypto";import{chmodSync as b,existsSync as C,m
|
|
|
107
107
|
required = excluded.required,
|
|
108
108
|
reason_code = excluded.reason_code,
|
|
109
109
|
metadata_json = excluded.metadata_json
|
|
110
|
-
`).run(e.gateId,e.campaignId,e.status,e.summary??null,e.required?1:0,e.reasonCode??null,e.operationId??null,e.idempotencyKey??null,t);return this.toWriteResult(s)}catch(a){throw n(a,"sqlite-
|
|
110
|
+
`).run(e.gateId,e.campaignId,e.status,e.summary??null,e.required?1:0,e.reasonCode??null,e.operationId??null,e.idempotencyKey??null,t);return this.toWriteResult(s)}catch(a){throw n(a,"sqlite-mutation-failed")}}recordOperationAudit(e){return this.appendReceipt(e)}hasOperationRef(e,t){this.assertCanMutate();const a=["jobs","job_leases","job_events","job_receipts","goal_campaigns","goal_ledger_items","goal_verifiers","goal_review_gates","loop_jobs","artifacts","state_snapshots","runner_config","outbox"],s=a.map(d=>`SELECT 1 AS found FROM ${d} WHERE operation_id = ?${t?" OR idempotency_key = ?":""}`),o=a.flatMap(()=>t?[e,t]:[e]);return!!this.db.prepare(`${s.join(" UNION ALL ")} LIMIT 1`).get(...o)}jobExists(e){return!!this.db.prepare("SELECT 1 AS found FROM jobs WHERE job_id = ? LIMIT 1").get(e)}runInTransaction(e){this.assertCanMutate();const t=this.db.transaction(e);try{return typeof t.immediate=="function"?t.immediate():t()}catch(a){throw n(a,"sqlite-mutation-failed")}}collectSnapshotRows(e){const t=(o,...m)=>{const d=this.db.prepare(o).get(...m);return _(d)&&typeof d.count=="number"?d.count:0},a=this.db.prepare(`
|
|
111
111
|
SELECT status, COUNT(*) AS count FROM outbox GROUP BY status
|
|
112
112
|
`).all(),s={};for(const o of a)typeof o.status=="string"&&typeof o.count=="number"&&(s[o.status]=o.count);return{schemaVersion:this.getSchemaVersion(),jobs:this.db.prepare(`
|
|
113
113
|
SELECT job_id, kind, status, summary, reason_code, created_at, updated_at,
|
|
@@ -212,7 +212,7 @@ import{createHash as T}from"node:crypto";import{chmodSync as b,existsSync as C,m
|
|
|
212
212
|
SET status = 'expired', released_at = ?
|
|
213
213
|
WHERE released_at IS NULL
|
|
214
214
|
AND lease_id IN (${h})
|
|
215
|
-
`).run(e.nowIso,...d);return{recoveredLeaseIds:d,safeExpiredAtOrBefore:o,changes:E.changes}})}catch(m){throw n(m,"sqlite-
|
|
215
|
+
`).run(e.nowIso,...d);return{recoveredLeaseIds:d,safeExpiredAtOrBefore:o,changes:E.changes}})}catch(m){throw n(m,"sqlite-mutation-failed")}}ensureGoalCampaign(e,t,a,s){this.db.prepare(`
|
|
216
216
|
INSERT OR IGNORE INTO goal_campaigns (
|
|
217
217
|
campaign_id, job_id, status, public_summary, created_at, updated_at
|
|
218
218
|
) VALUES (?, ?, 'active', 'Public goal campaign summary unavailable', ?, ?)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{spawnSync as ce}from"node:child_process";import{createHash as le}from"node:crypto";import{existsSync as j,mkdirSync as ue,readFileSync as ie,writeFileSync as de}from"node:fs";import{delimiter as me,dirname as pe,isAbsolute as F,join as c,resolve as Q}from"node:path";import{checkRunnerBinaryTrust as fe,resolveTrustedRunnerBinary as J}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"}),A=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"}),$="neocortex-runner",he=`${$}.service`,N=`${$}.timer`,B="com.ornexus.neocortex.runner",ye=`${B}.plist`,M="NeocortexRunner",Ee="neocortex-runner-task.xml",ge="runner.cron",Se=12,Ce=24,Le=60,H=new Map;function K(e){const r=g(e)??Q(e||"."),t=We(r),n=le("sha256").update(t).digest("hex").slice(0,Se),s=Qe(ze(t)),o=`${s}-${n}`,a=`${$}-${o}`,d=`com.ornexus.neocortex.runner.${o}`;return{projectKey:o,projectBasename:s,systemdServiceName:`${a}.service`,systemdTimerName:`${a}.timer`,systemdServiceFile:`${a}.service`,systemdTimerFile:`${a}.timer`,launchdLabel:d,launchdFile:`${d}.plist`,windowsTaskName:`NeocortexRunner-${o}`,windowsXmlFile:`${a}-task.xml`,cronFile:`runner-${o}.cron`,cronMarkerStart:`# BEGIN neocortex-runner:${o}`,cronMarkerEnd:`# END neocortex-runner:${o}`,publicSafe:!0}}function or(){H.clear()}async function ar(e={}){const r=e.platform??process.platform,t=g(e.projectRoot??process.cwd())??process.cwd(),n=K(t),s=`${r}:${n.projectKey}`,o=H.get(s);if(o?.ok)return{...o,attempted:!1,installed:!1,started:!1,cached:!0,reasonCodes:S([...o.reasonCodes,A.ALREADY_ACTIVE]),publicSummary:"runner scheduler bootstrap already active for project key.",publicSafe:!0};try{const a=e.binaryResolver??J,d=g(e.executablePath??process.argv[1])??process.argv[1],y=a({from:d,platform:r});if(!y.ok)return w({projectKey:n.projectKey,reasonCodes:[A.BINARY_UNAVAILABLE,...y.reasonCodes],publicSummary:"runner scheduler bootstrap could not resolve a trusted runner binary."});const u=Re(e.env??process.env),E={...e,projectRoot:t,executablePath:y.executablePath,platform:r,env:u,binaryResolver:()=>y},p=await q({...E,command:"install"});if(!p.ok)return w({projectKey:n.projectKey,strategy:p.strategy,reasonCodes:[A.INSTALL_FAILED,...p.reasonCodes],publicSummary:"runner scheduler bootstrap install failed.",attempted:!0});const f=await q({...E,command:"start"});if(!f.ok)return w({projectKey:n.projectKey,strategy:f.strategy??p.strategy,reasonCodes:[A.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([A.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:[A.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 Re(e){return{...e,NEOCORTEX_RUNNER_BOOTSTRAP_IN_PROGRESS:"1",NEOCORTEX_BOOTSTRAP_IN_PROGRESS:"1"}}async function q(e){const r=e.env??process.env,t=e.platform??process.platform,n=e.dryRun===!0,s=g(e.projectRoot??process.cwd()),o=g(e.executablePath??process.argv[1]),a=Xe(e,o,t),d=a.runnerCommand,y=d?.executablePath??o,u=K(s??process.cwd()),E=e.commandAvailable??(h=>ne(h,r)),p=qe(e.intervalSeconds??Le,10,1440*60),f=ke({platform:t,env:r,strategy:e.strategy,allowCronFallback:e.allowCronFallback,commandAvailable:E,uid:e.uid}),L=Ve(e,y,a.resolution),R=[...f.blockers];if((!s||!d)&&R.push(i.SCHEDULER_INSTALL_UNSAFE),!L.trusted){const h=L.reasonCodes&&L.reasonCodes.length>0?L.reasonCodes:[L.reasonCode??i.RUNNER_BINARY_UNTRUSTED];R.push(i.SCHEDULER_INSTALL_UNSAFE,i.RUNNER_BINARY_UNTRUSTED,...h)}const m=f.selectedStrategy;m||R.push(i.SCHEDULER_UNAVAILABLE);const k=m?be(m,r,u):void 0,b=m&&s&&Be(e.command)?Me({strategy:m,env:r,projectRoot:s}):[],ae=b.flatMap(h=>h.reasonCodes),v=(e.command==="install"||e.command==="start"||e.command==="stop")&&R.length>0,X=S([...f.reasonCodes,...R,...ae,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:u,legacyEntries:b,controlCommands:[],uninstallGuidance:m&&k?ee(m,k,u):[],capability:se(f,R),reasonCodes:X,applied:!1,publicSafe:!0};const T=e.command==="install"?Ae({strategy:m,paths:k,projectRoot:s,executablePath:d.command,runnerCommand:d,intervalSeconds:p,identity:u}):[],U=_e(e.command,m,k,u,b,r);let I=!1,x=!0;const V=[];if(e.command==="install"&&!n){for(const h of T)ue(pe(h.path),{recursive:!0}),de(h.path,h.content,"utf8");I=T.length>0}if(!n&&U.length>0){const h=e.commandRunner??Je;for(const W of U){if(W.manualOnly)continue;const z=h(W);z.ok?I=!0:(x=!1,V.push(z.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:u,legacyEntries:b,controlCommands:U,uninstallGuidance:[...ee(m,k,u),...Ue(m,b)],capability:se(f,R),reasonCodes:S([...X,...V,x?i.OK:i.SCHEDULER_COMMAND_FAILED]),applied:I,publicSafe:!0}}function ke(e={}){const r=e.env??process.env,t=e.platform??process.platform,n=e.commandAvailable??(p=>ne(p,r)),s=Ye(t,r,e.uid),o=Ge(t),a=o?re(o,n):!1,d=t!=="win32"&&n("crontab"),y=e.allowCronFallback!==!1;let u=e.strategy;const E=[];return u||(o&&a?u=o:y&&d&&(u="cron-fallback",E.push(i.PRIMARY_USER_SCHEDULER_UNAVAILABLE,i.CRON_FALLBACK_SELECTED))),u==="cron-fallback"&&a&&(u=void 0,E.push(i.CRON_FALLBACK_NOT_ALLOWED)),u&&!re(u,n)&&(u!=="cron-fallback"||!d)&&(u=void 0),u||E.push(i.SCHEDULER_UNAVAILABLE),s.length>0&&E.push(...s),E.length===0&&E.push(i.OK),{platform:t,primaryStrategy:o,selectedStrategy:u,fallbackStrategy:d?"cron-fallback":void 0,primaryAvailable:a,cronFallbackAvailable:d,safeToInstall:s.length===0,blockers:s,reasonCodes:S(E),publicSafe:!0}}function Ae(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:Ie(t,e.projectRoot,r),publicSafe:!0},{kind:"systemd-timer",path:e.paths.systemdTimerPath,content:xe(e.intervalSeconds,r),publicSafe:!0}];case"launchd-user":return[{kind:"launchd-plist",path:e.paths.launchdPlistPath,content:je(t,e.projectRoot,e.intervalSeconds,r),publicSafe:!0}];case"windows-task-scheduler":return[{kind:"windows-task-xml",path:e.paths.windowsTaskXmlPath,content:Fe(t,e.projectRoot,e.intervalSeconds,r),publicSafe:!0}];case"cron-fallback":return[{kind:"cron-snippet",path:e.paths.cronSnippetPath,content:$e(t,e.projectRoot,r),publicSafe:!0}]}}function be(e,r,t){const n=te(r),s=g(r.XDG_CONFIG_HOME)??c(n,".config"),o=c(s,"systemd","user"),a=c(n,"Library","LaunchAgents"),d=g(r.APPDATA)??c(g(r.USERPROFILE)??n,"AppData","Roaming"),y=c(d,"Neocortex","Runner"),u=c(s,"neocortex");return{systemdServicePath:c(o,t.systemdServiceFile),systemdTimerPath:c(o,t.systemdTimerFile),launchdPlistPath:c(a,t.launchdFile),windowsTaskXmlPath:c(y,t.windowsXmlFile),cronSnippetPath:c(u,t.cronFile)}}function Z(e,r){const t=te(r),n=g(r.XDG_CONFIG_HOME)??c(t,".config"),s=c(n,"systemd","user"),o=c(t,"Library","LaunchAgents"),a=g(r.APPDATA)??c(g(r.USERPROFILE)??t,"AppData","Roaming"),d=c(a,"Neocortex","Runner"),y=c(n,"neocortex");return{systemdServicePath:c(s,he),systemdTimerPath:c(s,N),launchdPlistPath:c(o,ye),windowsTaskXmlPath:c(d,Ee),cronSnippetPath:c(y,ge)}}function _e(e,r,t,n,s,o){return e==="doctor"?[]:[...e==="install"?Te(r,t,n):e==="start"?Ne(r,t,n):e==="stop"?we(r,t,n):De(r,t,n),...Pe(e,r,s,o)]}function Te(e,r,t){switch(e){case"systemd-user":return[l("systemctl",["--user","daemon-reload"]),l("systemctl",["--user","enable","--now",t.systemdTimerName])];case"launchd-user":return[l("launchctl",["load","-w",r.launchdPlistPath])];case"windows-task-scheduler":return[l("schtasks",["/Create","/TN",t.windowsTaskName,"/XML",r.windowsTaskXmlPath,"/F"])];case"cron-fallback":return[l("crontab",["-l","# append snippet from",r.cronSnippetPath],!0)]}}function Ne(e,r,t){switch(e){case"systemd-user":return[l("systemctl",["--user","start",t.systemdTimerName])];case"launchd-user":return[l("launchctl",["load","-w",r.launchdPlistPath])];case"windows-task-scheduler":return[l("schtasks",["/Run","/TN",t.windowsTaskName])];case"cron-fallback":return[l("crontab",["-l","# ensure snippet from",r.cronSnippetPath,"is installed"],!0)]}}function we(e,r,t){switch(e){case"systemd-user":return[l("systemctl",["--user","stop",t.systemdTimerName])];case"launchd-user":return[l("launchctl",["unload","-w",r.launchdPlistPath])];case"windows-task-scheduler":return[l("schtasks",["/End","/TN",t.windowsTaskName])];case"cron-fallback":return[l("crontab",["-l","# remove scoped neocortex-runner snippet"],!0)]}}function De(e,r,t){switch(e){case"systemd-user":return[l("systemctl",["--user","status",t.systemdTimerName,"--no-pager"])];case"launchd-user":return[l("launchctl",["list",t.launchdLabel])];case"windows-task-scheduler":return[l("schtasks",["/Query","/TN",t.windowsTaskName,"/FO","LIST"])];case"cron-fallback":return[l("crontab",["-l","# look for neocortex-runner snippet from",r.cronSnippetPath],!0)]}}function ee(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 Pe(e,r,t,n){if(!t.some(a=>a.relation==="current-project")||e!=="status"&&e!=="stop")return[];const o=Z(r,n);return e==="status"?Oe(r,o):ve(r,o)}function Oe(e,r){switch(e){case"systemd-user":return[l("systemctl",["--user","status",N,"--no-pager"])];case"launchd-user":return[l("launchctl",["list",B])];case"windows-task-scheduler":return[l("schtasks",["/Query","/TN",M,"/FO","LIST"])];case"cron-fallback":return[l("crontab",["-l","# look for legacy neocortex-runner snippet from",r.cronSnippetPath],!0)]}}function ve(e,r){switch(e){case"systemd-user":return[l("systemctl",["--user","stop",N])];case"launchd-user":return[l("launchctl",["unload","-w",r.launchdPlistPath])];case"windows-task-scheduler":return[l("schtasks",["/End","/TN",M])];case"cron-fallback":return[l("crontab",["-l","# remove legacy neocortex-runner snippet"],!0)]}}function Ue(e,r){if(r.length===0)return[];const t=r.filter(a=>a.relation==="current-project"),n=r.filter(a=>a.relation==="ambiguous"),s=r.filter(a=>a.relation==="other-project"),o=[];return t.length>0&&o.push(`Legacy global ${e} scheduler matches this project; stop it before relying on project-scoped runner scheduling.`),n.length>0&&o.push(`Legacy global ${e} scheduler ownership is ambiguous; inspect it manually before removal.`),s.length>0&&o.push(`Legacy global ${e} scheduler appears to belong to another project; leave it unchanged.`),o}function Ie(e,r,t){const n=[e.command,...e.args,"tick","--project-root",r].map(G).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=${G(r)}`,`ExecStart=${n}`,"","[Install]","WantedBy=default.target",""].join(`
|
|
2
|
-
`)}function
|
|
3
|
-
`)}function
|
|
4
|
-
`)}function
|
|
5
|
-
`)}function
|
|
6
|
-
`)}function
|
|
7
|
-
`),e.projectRoot,s);return[D(e.strategy,"systemd-timer",N,
|
|
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 │
|