@danielblomma/cortex-mcp 2.0.16 → 2.0.19
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/README.md +6 -4
- package/bin/cortex.mjs +75 -10
- package/package.json +2 -1
- package/scaffold/.context/config.yaml +2 -3
- package/scaffold/.githooks/_cortex-update-runner.sh +2 -2
- package/scaffold/mcp/package-lock.json +59 -60
- package/scaffold/mcp/package.json +2 -2
- package/scaffold/mcp/src/cli/stage.ts +15 -18
- package/scaffold/mcp/src/core/validators/builtins.ts +24 -4
- package/scaffold/mcp/src/core/workflow/index.ts +1 -0
- package/scaffold/mcp/src/core/workflow/mcp-tools.ts +15 -25
- package/scaffold/mcp/src/core/workflow/resolution.ts +113 -0
- package/scaffold/mcp/src/embeddings.ts +1 -1
- package/scaffold/mcp/src/enterprise/index.ts +16 -1
- package/scaffold/mcp/src/enterprise/reviews/policy-selection.ts +65 -0
- package/scaffold/mcp/src/enterprise/reviews/push.ts +55 -4
- package/scaffold/mcp/src/enterprise/reviews/trust-state.ts +305 -0
- package/scaffold/mcp/src/enterprise/tools/enterprise.ts +40 -47
- package/scaffold/mcp/src/enterprise/tools/harness.ts +2 -0
- package/scaffold/mcp/src/enterprise/workflow/state.ts +21 -0
- package/scaffold/mcp/src/graph.ts +3 -3
- package/scaffold/mcp/tests/enterprise-review-trust.test.mjs +318 -0
- package/scaffold/mcp/tests/fixtures/org-skillz-contract.json +59 -0
- package/scaffold/mcp/tests/fixtures/review-trust-contract.json +111 -0
- package/scaffold/mcp/tests/review-policy-selection.test.mjs +85 -0
- package/scaffold/mcp/tests/review-trust-contract.test.mjs +167 -0
- package/scaffold/mcp/tests/review-validator-source.test.mjs +52 -0
- package/scaffold/mcp/tests/skill-sync-checker.test.mjs +277 -0
- package/scaffold/mcp/tests/workflow-cli.test.mjs +102 -1
- package/scaffold/mcp/tests/workflow-mcp-tools.test.mjs +22 -0
- package/scaffold/mcp/tests/workflow-synced-registry.test.mjs +56 -0
- package/scaffold/scripts/bootstrap.sh +9 -8
- package/scaffold/scripts/context.sh +1 -1
- package/scaffold/scripts/dashboard.mjs +3 -1
- package/scaffold/scripts/dashboard.sh +1 -1
- package/scaffold/scripts/doctor.sh +2 -1
- package/scaffold/scripts/embed.sh +2 -1
- package/scaffold/scripts/ingest.mjs +3 -1
- package/scaffold/scripts/ingest.sh +3 -2
- package/scaffold/scripts/install-git-hooks.sh +2 -1
- package/scaffold/scripts/load-kuzu.sh +2 -2
- package/scaffold/scripts/load-ryu.sh +2 -1
- package/scaffold/scripts/memory-compile.mjs +2 -2
- package/scaffold/scripts/memory-compile.sh +3 -2
- package/scaffold/scripts/memory-lint.mjs +2 -2
- package/scaffold/scripts/memory-lint.sh +3 -2
- package/scaffold/scripts/parsers/node_modules/.package-lock.json +0 -1
- package/scaffold/scripts/parsers/package-lock.json +0 -1
- package/scaffold/scripts/refresh.sh +2 -2
- package/scaffold/scripts/status.sh +6 -5
- package/scaffold/scripts/update-context.sh +5 -5
- package/scaffold/scripts/watch.sh +7 -8
package/README.md
CHANGED
|
@@ -97,7 +97,7 @@ cortex init --bootstrap
|
|
|
97
97
|
|
|
98
98
|
This will:
|
|
99
99
|
|
|
100
|
-
- scaffold `.context/`,
|
|
100
|
+
- scaffold `.context/`, `.context/scripts/`, `.context/mcp/`, `.githooks/`, and docs files
|
|
101
101
|
- activate git hooks for checkout, pull/merge, commit, and rewrite events
|
|
102
102
|
- build and prepare the local MCP server
|
|
103
103
|
- try to auto-register MCP connections for Claude/Codex (if installed)
|
|
@@ -346,11 +346,13 @@ This repository includes two GitHub Actions workflows:
|
|
|
346
346
|
- Triggers on tag push `v*.*.*`
|
|
347
347
|
- Verifies tag/version sync
|
|
348
348
|
- Runs root tests + MCP build/tests
|
|
349
|
-
- Publishes `@danielblomma/cortex-mcp` to npm
|
|
349
|
+
- Publishes `@danielblomma/cortex-mcp` to npm via npm trusted publishing (GitHub OIDC)
|
|
350
350
|
|
|
351
|
-
Required
|
|
351
|
+
Required npm configuration:
|
|
352
352
|
|
|
353
|
-
-
|
|
353
|
+
- Configure a trusted publisher for `@danielblomma/cortex-mcp` on npmjs.com
|
|
354
|
+
- Use GitHub Actions publisher `DanielBlomma/cortex`
|
|
355
|
+
- Workflow filename must match `release-publish.yml`
|
|
354
356
|
|
|
355
357
|
## Limitations
|
|
356
358
|
|
package/bin/cortex.mjs
CHANGED
|
@@ -27,11 +27,14 @@ const PACKAGE_JSON_PATH = path.join(PACKAGE_ROOT, "package.json");
|
|
|
27
27
|
// only the three editable config files". Generated artifacts (db,
|
|
28
28
|
// embeddings, cache, hooks, mcp/, govern.local.json) never land in git.
|
|
29
29
|
const MCP_PROJECT_REL = path.join(".context", "mcp");
|
|
30
|
+
const CONTEXT_SCRIPTS_REL = path.join(".context", "scripts");
|
|
30
31
|
|
|
32
|
+
// `.context/*` (not `.context/`) so the !-negations below actually re-include
|
|
33
|
+
// the config files — git can't re-include children of an excluded directory.
|
|
31
34
|
const GITIGNORE_LINES = [
|
|
32
35
|
"",
|
|
33
36
|
"# Cortex local storage",
|
|
34
|
-
".context
|
|
37
|
+
".context/*",
|
|
35
38
|
"!.context/config.yaml",
|
|
36
39
|
"!.context/rules.yaml",
|
|
37
40
|
"!.context/ontology.cypher",
|
|
@@ -461,12 +464,73 @@ function migrateLegacyMcpLocation(targetDir) {
|
|
|
461
464
|
);
|
|
462
465
|
}
|
|
463
466
|
|
|
467
|
+
const LEGACY_SCRIPT_ENTRIES = [
|
|
468
|
+
"bootstrap.sh",
|
|
469
|
+
"context.sh",
|
|
470
|
+
"dashboard.mjs",
|
|
471
|
+
"dashboard.sh",
|
|
472
|
+
"doctor.sh",
|
|
473
|
+
"embed.sh",
|
|
474
|
+
"ingest.mjs",
|
|
475
|
+
"ingest.sh",
|
|
476
|
+
"install-git-hooks.sh",
|
|
477
|
+
"load-kuzu.sh",
|
|
478
|
+
"load-ryu.sh",
|
|
479
|
+
"memory-compile.mjs",
|
|
480
|
+
"memory-compile.sh",
|
|
481
|
+
"memory-lint.mjs",
|
|
482
|
+
"memory-lint.sh",
|
|
483
|
+
"refresh.sh",
|
|
484
|
+
"status.sh",
|
|
485
|
+
"update-context.sh",
|
|
486
|
+
"watch.sh",
|
|
487
|
+
"lib",
|
|
488
|
+
"parsers"
|
|
489
|
+
];
|
|
490
|
+
|
|
491
|
+
function looksLikeLegacyCortexScriptsDir(scriptsDir) {
|
|
492
|
+
const contextScript = path.join(scriptsDir, "context.sh");
|
|
493
|
+
if (!fs.existsSync(contextScript)) {
|
|
494
|
+
return false;
|
|
495
|
+
}
|
|
496
|
+
try {
|
|
497
|
+
const contents = fs.readFileSync(contextScript, "utf8");
|
|
498
|
+
return contents.includes("bootstrap)") && contents.includes("graph-load)") && contents.includes("memory-lint)");
|
|
499
|
+
} catch {
|
|
500
|
+
return false;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
function removeLegacyCortexScripts(targetDir) {
|
|
505
|
+
if (path.resolve(targetDir) === PACKAGE_ROOT) {
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
const scriptsDir = path.join(targetDir, "scripts");
|
|
510
|
+
if (!looksLikeLegacyCortexScriptsDir(scriptsDir)) {
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
for (const entry of LEGACY_SCRIPT_ENTRIES) {
|
|
515
|
+
fs.rmSync(path.join(scriptsDir, entry), { recursive: true, force: true });
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
try {
|
|
519
|
+
if (fs.existsSync(scriptsDir) && fs.readdirSync(scriptsDir).length === 0) {
|
|
520
|
+
fs.rmdirSync(scriptsDir);
|
|
521
|
+
}
|
|
522
|
+
} catch {
|
|
523
|
+
// Best effort. A user's own files in scripts/ must remain untouched.
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
464
527
|
function installScaffold(targetDir, force) {
|
|
465
528
|
migrateLegacyMcpLocation(targetDir);
|
|
529
|
+
removeLegacyCortexScripts(targetDir);
|
|
466
530
|
|
|
467
531
|
const copyMap = [
|
|
468
532
|
[path.join(SCAFFOLD_ROOT, ".context"), path.join(targetDir, ".context")],
|
|
469
|
-
[path.join(SCAFFOLD_ROOT, "scripts"), path.join(targetDir,
|
|
533
|
+
[path.join(SCAFFOLD_ROOT, "scripts"), path.join(targetDir, CONTEXT_SCRIPTS_REL)],
|
|
470
534
|
[path.join(SCAFFOLD_ROOT, "mcp"), path.join(targetDir, MCP_PROJECT_REL)],
|
|
471
535
|
[path.join(SCAFFOLD_ROOT, ".githooks"), path.join(targetDir, ".githooks")]
|
|
472
536
|
];
|
|
@@ -720,7 +784,7 @@ async function connectMcpClients(targetDir, options = {}) {
|
|
|
720
784
|
}
|
|
721
785
|
|
|
722
786
|
async function maybeInstallGitHooks(targetDir) {
|
|
723
|
-
const installScript = path.join(targetDir,
|
|
787
|
+
const installScript = path.join(targetDir, CONTEXT_SCRIPTS_REL, "install-git-hooks.sh");
|
|
724
788
|
if (!fs.existsSync(installScript)) {
|
|
725
789
|
return false;
|
|
726
790
|
}
|
|
@@ -758,16 +822,17 @@ function isTruthyEnv(value) {
|
|
|
758
822
|
function canAutoInitialize(targetDir) {
|
|
759
823
|
// Legacy mcp/ at root no longer counted — pre-v2.0.5 projects are migrated
|
|
760
824
|
// by installScaffold rather than blocking auto-init.
|
|
761
|
-
const scaffoldPaths = [".context", "
|
|
825
|
+
const scaffoldPaths = [".context", ".githooks"].map((entry) => path.join(targetDir, entry));
|
|
762
826
|
return scaffoldPaths.every((entryPath) => !fs.existsSync(entryPath));
|
|
763
827
|
}
|
|
764
828
|
|
|
765
829
|
function isScaffoldOutOfDate(targetDir) {
|
|
766
|
-
const contextScript = path.join(targetDir,
|
|
830
|
+
const contextScript = path.join(targetDir, CONTEXT_SCRIPTS_REL, "context.sh");
|
|
831
|
+
const legacyContextScript = path.join(targetDir, "scripts", "context.sh");
|
|
767
832
|
if (!fs.existsSync(contextScript)) {
|
|
768
|
-
return
|
|
833
|
+
return fs.existsSync(legacyContextScript);
|
|
769
834
|
}
|
|
770
|
-
const doctorScript = path.join(targetDir,
|
|
835
|
+
const doctorScript = path.join(targetDir, CONTEXT_SCRIPTS_REL, "doctor.sh");
|
|
771
836
|
if (!fs.existsSync(doctorScript)) {
|
|
772
837
|
return true;
|
|
773
838
|
}
|
|
@@ -812,7 +877,7 @@ async function maybeMigrateScaffold(targetDir, command) {
|
|
|
812
877
|
|
|
813
878
|
console.error(
|
|
814
879
|
`[cortex] scaffold in ${targetDir} is out of date ` +
|
|
815
|
-
`(missing scripts/doctor.sh, .context/mcp/package.json, doctor subcommand in context.sh, ` +
|
|
880
|
+
`(missing .context/scripts/doctor.sh, .context/mcp/package.json, doctor subcommand in context.sh, ` +
|
|
816
881
|
`or carries a legacy mcp/ directory at the project root).`
|
|
817
882
|
);
|
|
818
883
|
|
|
@@ -881,7 +946,7 @@ async function ensureProjectInitializedForMcp(targetDir) {
|
|
|
881
946
|
}
|
|
882
947
|
|
|
883
948
|
async function runContextCommand(cwd, contextArgs) {
|
|
884
|
-
const contextScript = path.join(cwd,
|
|
949
|
+
const contextScript = path.join(cwd, CONTEXT_SCRIPTS_REL, "context.sh");
|
|
885
950
|
if (!fs.existsSync(contextScript)) {
|
|
886
951
|
throw new Error(`Missing ${contextScript}. Run 'cortex init' first.`);
|
|
887
952
|
}
|
|
@@ -915,7 +980,7 @@ async function run() {
|
|
|
915
980
|
await maybeInstallGitHooks(target);
|
|
916
981
|
|
|
917
982
|
console.log(`[cortex] initialized in ${target}`);
|
|
918
|
-
console.log("[cortex] scaffold copied: .context/, scripts/, mcp/, .githooks/, docs/");
|
|
983
|
+
console.log("[cortex] scaffold copied: .context/, .context/scripts/, .context/mcp/, .githooks/, docs/");
|
|
919
984
|
console.log(`[cortex] Claude commands ready: /context-update (${helpers.claude.total} files)`);
|
|
920
985
|
if (helpers.codex.changed) {
|
|
921
986
|
console.log("[cortex] Codex workflow instructions added to AGENTS.md");
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@danielblomma/cortex-mcp",
|
|
3
3
|
"mcpName": "io.github.DanielBlomma/cortex",
|
|
4
|
-
"version": "2.0.
|
|
4
|
+
"version": "2.0.19",
|
|
5
5
|
"description": "Local, repo-scoped context platform for coding assistants. Semantic search, graph relationships, and architectural rule context.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"author": "Daniel Blomma",
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
"docs/MCP_MARKETPLACE.md"
|
|
50
50
|
],
|
|
51
51
|
"scripts": {
|
|
52
|
+
"pretest": "test -d scaffold/scripts/parsers/node_modules || npm --prefix scaffold/scripts/parsers install --no-fund --no-update-notifier --silent",
|
|
52
53
|
"test": "node tests/context-regressions.test.mjs && node --test tests/ingest-units.test.mjs tests/javascript-parser.test.mjs tests/sql-parser.test.mjs tests/config-parser.test.mjs tests/resources-parser.test.mjs tests/vbnet-parser.test.mjs tests/cpp-parser.test.mjs tests/dashboard.test.mjs tests/init-config.test.mjs tests/init-agents.test.mjs tests/multi-level.test.mjs tests/no-legacy-paths.test.mjs tests/tree-sitter-error-reporting.test.mjs tests/tree-sitter-body-cap.test.mjs tests/tree-sitter-exported.test.mjs tests/tree-sitter-robustness.test.mjs",
|
|
53
54
|
"release:sync-version": "node scripts/sync-release-version.mjs",
|
|
54
55
|
"release:check-version-sync": "node scripts/sync-release-version.mjs --check",
|
|
@@ -6,12 +6,12 @@ if [[ -z "$REPO_ROOT" ]]; then
|
|
|
6
6
|
exit 0
|
|
7
7
|
fi
|
|
8
8
|
|
|
9
|
-
CONTEXT_SCRIPT="$REPO_ROOT/scripts/context.sh"
|
|
9
|
+
CONTEXT_SCRIPT="$REPO_ROOT/.context/scripts/context.sh"
|
|
10
10
|
if [[ ! -x "$CONTEXT_SCRIPT" ]]; then
|
|
11
11
|
exit 0
|
|
12
12
|
fi
|
|
13
13
|
|
|
14
|
-
PARSER_MODULES_DIR="$REPO_ROOT/scripts/parsers/node_modules"
|
|
14
|
+
PARSER_MODULES_DIR="$REPO_ROOT/.context/scripts/parsers/node_modules"
|
|
15
15
|
|
|
16
16
|
HOOK_DIR="$REPO_ROOT/.context/hooks"
|
|
17
17
|
LOCK_DIR="$HOOK_DIR/update.lock"
|
|
@@ -91,12 +91,6 @@
|
|
|
91
91
|
"integrity": "sha512-MI1qs7Lo4Syw0EOzUl0xjs2lsoeqFku44KpngfIduHBYvzm8h2+7K8YMQh1JtVVVrUvhLpNwqVi4DERegUJhPQ==",
|
|
92
92
|
"license": "Apache-2.0"
|
|
93
93
|
},
|
|
94
|
-
"node_modules/@huggingface/transformers/node_modules/long": {
|
|
95
|
-
"version": "5.3.2",
|
|
96
|
-
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
|
|
97
|
-
"integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
|
|
98
|
-
"license": "Apache-2.0"
|
|
99
|
-
},
|
|
100
94
|
"node_modules/@huggingface/transformers/node_modules/onnxruntime-common": {
|
|
101
95
|
"version": "1.24.3",
|
|
102
96
|
"resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.24.3.tgz",
|
|
@@ -140,30 +134,6 @@
|
|
|
140
134
|
"integrity": "sha512-BOoomdHYmNRL5r4iQ4bMvsl2t0/hzVQ3OM3PHD0gxeXu1PmggqBv3puZicEUVOA3AtHHYmqZtjMj9FOfGrATTw==",
|
|
141
135
|
"license": "MIT"
|
|
142
136
|
},
|
|
143
|
-
"node_modules/@huggingface/transformers/node_modules/protobufjs": {
|
|
144
|
-
"version": "7.5.5",
|
|
145
|
-
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.5.tgz",
|
|
146
|
-
"integrity": "sha512-3wY1AxV+VBNW8Yypfd1yQY9pXnqTAN+KwQxL8iYm3/BjKYMNg4i0owhEe26PWDOMaIrzeeF98Lqd5NGz4omiIg==",
|
|
147
|
-
"hasInstallScript": true,
|
|
148
|
-
"license": "BSD-3-Clause",
|
|
149
|
-
"dependencies": {
|
|
150
|
-
"@protobufjs/aspromise": "^1.1.2",
|
|
151
|
-
"@protobufjs/base64": "^1.1.2",
|
|
152
|
-
"@protobufjs/codegen": "^2.0.4",
|
|
153
|
-
"@protobufjs/eventemitter": "^1.1.0",
|
|
154
|
-
"@protobufjs/fetch": "^1.1.0",
|
|
155
|
-
"@protobufjs/float": "^1.0.2",
|
|
156
|
-
"@protobufjs/inquire": "^1.1.0",
|
|
157
|
-
"@protobufjs/path": "^1.1.2",
|
|
158
|
-
"@protobufjs/pool": "^1.1.0",
|
|
159
|
-
"@protobufjs/utf8": "^1.1.0",
|
|
160
|
-
"@types/node": ">=13.7.0",
|
|
161
|
-
"long": "^5.0.0"
|
|
162
|
-
},
|
|
163
|
-
"engines": {
|
|
164
|
-
"node": ">=12.0.0"
|
|
165
|
-
}
|
|
166
|
-
},
|
|
167
137
|
"node_modules/@huggingface/transformers/node_modules/sharp": {
|
|
168
138
|
"version": "0.34.5",
|
|
169
139
|
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz",
|
|
@@ -766,9 +736,9 @@
|
|
|
766
736
|
"license": "BSD-3-Clause"
|
|
767
737
|
},
|
|
768
738
|
"node_modules/@protobufjs/codegen": {
|
|
769
|
-
"version": "2.0.
|
|
770
|
-
"resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.
|
|
771
|
-
"integrity": "sha512-
|
|
739
|
+
"version": "2.0.5",
|
|
740
|
+
"resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz",
|
|
741
|
+
"integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==",
|
|
772
742
|
"license": "BSD-3-Clause"
|
|
773
743
|
},
|
|
774
744
|
"node_modules/@protobufjs/eventemitter": {
|
|
@@ -778,13 +748,12 @@
|
|
|
778
748
|
"license": "BSD-3-Clause"
|
|
779
749
|
},
|
|
780
750
|
"node_modules/@protobufjs/fetch": {
|
|
781
|
-
"version": "1.1.
|
|
782
|
-
"resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.
|
|
783
|
-
"integrity": "sha512-
|
|
751
|
+
"version": "1.1.1",
|
|
752
|
+
"resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz",
|
|
753
|
+
"integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==",
|
|
784
754
|
"license": "BSD-3-Clause",
|
|
785
755
|
"dependencies": {
|
|
786
|
-
"@protobufjs/aspromise": "^1.1.1"
|
|
787
|
-
"@protobufjs/inquire": "^1.1.0"
|
|
756
|
+
"@protobufjs/aspromise": "^1.1.1"
|
|
788
757
|
}
|
|
789
758
|
},
|
|
790
759
|
"node_modules/@protobufjs/float": {
|
|
@@ -794,9 +763,9 @@
|
|
|
794
763
|
"license": "BSD-3-Clause"
|
|
795
764
|
},
|
|
796
765
|
"node_modules/@protobufjs/inquire": {
|
|
797
|
-
"version": "1.1.
|
|
798
|
-
"resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.
|
|
799
|
-
"integrity": "sha512-
|
|
766
|
+
"version": "1.1.2",
|
|
767
|
+
"resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.2.tgz",
|
|
768
|
+
"integrity": "sha512-pa0vFRuws4wkvaXKK1uXZMAwAX4/t8ANaJo45iw/oQHNQ9q5xUzwgFmVJGXiga2BeN+zpX7Vf9vmsiIa2J+MUw==",
|
|
800
769
|
"license": "BSD-3-Clause"
|
|
801
770
|
},
|
|
802
771
|
"node_modules/@protobufjs/path": {
|
|
@@ -812,9 +781,9 @@
|
|
|
812
781
|
"license": "BSD-3-Clause"
|
|
813
782
|
},
|
|
814
783
|
"node_modules/@protobufjs/utf8": {
|
|
815
|
-
"version": "1.1.
|
|
816
|
-
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.
|
|
817
|
-
"integrity": "sha512-
|
|
784
|
+
"version": "1.1.1",
|
|
785
|
+
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.1.tgz",
|
|
786
|
+
"integrity": "sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==",
|
|
818
787
|
"license": "BSD-3-Clause"
|
|
819
788
|
},
|
|
820
789
|
"node_modules/@tsconfig/node10": {
|
|
@@ -1044,9 +1013,9 @@
|
|
|
1044
1013
|
"license": "MIT"
|
|
1045
1014
|
},
|
|
1046
1015
|
"node_modules/brace-expansion": {
|
|
1047
|
-
"version": "5.0.
|
|
1048
|
-
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.
|
|
1049
|
-
"integrity": "sha512-
|
|
1016
|
+
"version": "5.0.6",
|
|
1017
|
+
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz",
|
|
1018
|
+
"integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==",
|
|
1050
1019
|
"license": "MIT",
|
|
1051
1020
|
"dependencies": {
|
|
1052
1021
|
"balanced-match": "^4.0.2"
|
|
@@ -1525,12 +1494,12 @@
|
|
|
1525
1494
|
}
|
|
1526
1495
|
},
|
|
1527
1496
|
"node_modules/express-rate-limit": {
|
|
1528
|
-
"version": "8.
|
|
1529
|
-
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.
|
|
1530
|
-
"integrity": "sha512-
|
|
1497
|
+
"version": "8.5.1",
|
|
1498
|
+
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.5.1.tgz",
|
|
1499
|
+
"integrity": "sha512-5O6KYmyJEpuPJV5hNTXKbAHWRqrzyu+OI3vUnSd2kXFubIVpG7ezpgxQy76Zo5GQZtrQBg86hF+CM/NX+cioiQ==",
|
|
1531
1500
|
"license": "MIT",
|
|
1532
1501
|
"dependencies": {
|
|
1533
|
-
"ip-address": "10.
|
|
1502
|
+
"ip-address": "^10.2.0"
|
|
1534
1503
|
},
|
|
1535
1504
|
"engines": {
|
|
1536
1505
|
"node": ">= 16"
|
|
@@ -1574,9 +1543,9 @@
|
|
|
1574
1543
|
"license": "MIT"
|
|
1575
1544
|
},
|
|
1576
1545
|
"node_modules/fast-uri": {
|
|
1577
|
-
"version": "3.1.
|
|
1578
|
-
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.
|
|
1579
|
-
"integrity": "sha512-
|
|
1546
|
+
"version": "3.1.2",
|
|
1547
|
+
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz",
|
|
1548
|
+
"integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==",
|
|
1580
1549
|
"funding": [
|
|
1581
1550
|
{
|
|
1582
1551
|
"type": "github",
|
|
@@ -1791,9 +1760,9 @@
|
|
|
1791
1760
|
}
|
|
1792
1761
|
},
|
|
1793
1762
|
"node_modules/hono": {
|
|
1794
|
-
"version": "4.12.
|
|
1795
|
-
"resolved": "https://registry.npmjs.org/hono/-/hono-4.12.
|
|
1796
|
-
"integrity": "sha512-
|
|
1763
|
+
"version": "4.12.18",
|
|
1764
|
+
"resolved": "https://registry.npmjs.org/hono/-/hono-4.12.18.tgz",
|
|
1765
|
+
"integrity": "sha512-RWzP96k/yv0PQfyXnWjs6zot20TqfpfsNXhOnev8d1InAxubW93L11/oNUc3tQqn2G0bSdAOBpX+2uDFHV7kdQ==",
|
|
1797
1766
|
"license": "MIT",
|
|
1798
1767
|
"engines": {
|
|
1799
1768
|
"node": ">=16.9.0"
|
|
@@ -1848,9 +1817,9 @@
|
|
|
1848
1817
|
"license": "ISC"
|
|
1849
1818
|
},
|
|
1850
1819
|
"node_modules/ip-address": {
|
|
1851
|
-
"version": "10.
|
|
1852
|
-
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.
|
|
1853
|
-
"integrity": "sha512
|
|
1820
|
+
"version": "10.2.0",
|
|
1821
|
+
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz",
|
|
1822
|
+
"integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==",
|
|
1854
1823
|
"license": "MIT",
|
|
1855
1824
|
"engines": {
|
|
1856
1825
|
"node": ">= 12"
|
|
@@ -1937,6 +1906,12 @@
|
|
|
1937
1906
|
"graceful-fs": "^4.1.6"
|
|
1938
1907
|
}
|
|
1939
1908
|
},
|
|
1909
|
+
"node_modules/long": {
|
|
1910
|
+
"version": "5.3.2",
|
|
1911
|
+
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
|
|
1912
|
+
"integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
|
|
1913
|
+
"license": "Apache-2.0"
|
|
1914
|
+
},
|
|
1940
1915
|
"node_modules/make-error": {
|
|
1941
1916
|
"version": "1.3.6",
|
|
1942
1917
|
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
|
@@ -2152,6 +2127,30 @@
|
|
|
2152
2127
|
"integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==",
|
|
2153
2128
|
"license": "MIT"
|
|
2154
2129
|
},
|
|
2130
|
+
"node_modules/protobufjs": {
|
|
2131
|
+
"version": "7.5.9",
|
|
2132
|
+
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.9.tgz",
|
|
2133
|
+
"integrity": "sha512-Od4muIm3HW1AouyHF5lONOf1FWo3hY1NbFDoy191X9GzhpgW1clCoaFjfVs2rKJNFYpTNJbje4cbAIDBZJ63ZA==",
|
|
2134
|
+
"hasInstallScript": true,
|
|
2135
|
+
"license": "BSD-3-Clause",
|
|
2136
|
+
"dependencies": {
|
|
2137
|
+
"@protobufjs/aspromise": "^1.1.2",
|
|
2138
|
+
"@protobufjs/base64": "^1.1.2",
|
|
2139
|
+
"@protobufjs/codegen": "^2.0.5",
|
|
2140
|
+
"@protobufjs/eventemitter": "^1.1.0",
|
|
2141
|
+
"@protobufjs/fetch": "^1.1.1",
|
|
2142
|
+
"@protobufjs/float": "^1.0.2",
|
|
2143
|
+
"@protobufjs/inquire": "^1.1.2",
|
|
2144
|
+
"@protobufjs/path": "^1.1.2",
|
|
2145
|
+
"@protobufjs/pool": "^1.1.0",
|
|
2146
|
+
"@protobufjs/utf8": "^1.1.1",
|
|
2147
|
+
"@types/node": ">=13.7.0",
|
|
2148
|
+
"long": "^5.0.0"
|
|
2149
|
+
},
|
|
2150
|
+
"engines": {
|
|
2151
|
+
"node": ">=12.0.0"
|
|
2152
|
+
}
|
|
2153
|
+
},
|
|
2155
2154
|
"node_modules/proxy-addr": {
|
|
2156
2155
|
"version": "2.0.7",
|
|
2157
2156
|
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
|
@@ -8,8 +8,8 @@ import {
|
|
|
8
8
|
type StageStatus,
|
|
9
9
|
type WorkflowDefinition,
|
|
10
10
|
} from "../core/workflow/index.js";
|
|
11
|
-
import {
|
|
12
|
-
import { isEnterpriseProject } from "../hooks/shared.js";
|
|
11
|
+
import { resolveWorkflowDefinition } from "../core/workflow/resolution.js";
|
|
12
|
+
import { isEnforcedMode, isEnterpriseProject } from "../hooks/shared.js";
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* `cortex stage` CLI surface. Each subcommand is a thin shell wrapper
|
|
@@ -93,18 +93,6 @@ function projectRoot(): string {
|
|
|
93
93
|
return process.env.CORTEX_PROJECT_ROOT?.trim() || process.cwd();
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
function resolveWorkflow(workflowId: string): WorkflowDefinition {
|
|
97
|
-
const wf = DEFAULT_WORKFLOWS[workflowId];
|
|
98
|
-
if (!wf) {
|
|
99
|
-
throw new Error(
|
|
100
|
-
`Unknown workflow_id: ${workflowId}. Available: ${
|
|
101
|
-
Object.keys(DEFAULT_WORKFLOWS).join(", ") || "<none>"
|
|
102
|
-
}`,
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
return wf;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
96
|
type Flags = Record<string, string | boolean>;
|
|
109
97
|
|
|
110
98
|
function parseFlags(args: string[]): { flags: Flags; rest: string[] } {
|
|
@@ -153,7 +141,11 @@ async function runStart(args: string[]): Promise<void> {
|
|
|
153
141
|
const workflowId =
|
|
154
142
|
typeof flags.workflow === "string" ? flags.workflow : "secure-build";
|
|
155
143
|
|
|
156
|
-
const
|
|
144
|
+
const resolved = resolveWorkflowDefinition(workflowId, {
|
|
145
|
+
emitBundledFallbackWarning: true,
|
|
146
|
+
bundledFallbackPolicy: isEnforcedMode(projectRoot()) ? "block" : "warn",
|
|
147
|
+
});
|
|
148
|
+
const workflow = resolved.workflow;
|
|
157
149
|
const state = createRun({
|
|
158
150
|
cwd: projectRoot(),
|
|
159
151
|
taskId,
|
|
@@ -165,7 +157,12 @@ async function runStart(args: string[]): Promise<void> {
|
|
|
165
157
|
taskId,
|
|
166
158
|
workflow,
|
|
167
159
|
});
|
|
168
|
-
emitJson({
|
|
160
|
+
emitJson({
|
|
161
|
+
state,
|
|
162
|
+
envelope,
|
|
163
|
+
workflow_source: resolved.source,
|
|
164
|
+
warnings: resolved.warnings,
|
|
165
|
+
});
|
|
169
166
|
}
|
|
170
167
|
|
|
171
168
|
async function runStatus(args: string[]): Promise<void> {
|
|
@@ -186,7 +183,7 @@ async function runEnvelope(args: string[]): Promise<void> {
|
|
|
186
183
|
`No run state for task ${taskId}. Start one with 'cortex stage start'.`,
|
|
187
184
|
);
|
|
188
185
|
}
|
|
189
|
-
const workflow =
|
|
186
|
+
const workflow = resolveWorkflowDefinition(state.workflow_id).workflow;
|
|
190
187
|
const envelope = composeStageEnvelope({
|
|
191
188
|
cwd: projectRoot(),
|
|
192
189
|
taskId,
|
|
@@ -246,7 +243,7 @@ async function runAdvance(args: string[]): Promise<void> {
|
|
|
246
243
|
`No run state for task ${taskId}. Start one with 'cortex stage start'.`,
|
|
247
244
|
);
|
|
248
245
|
}
|
|
249
|
-
const workflow =
|
|
246
|
+
const workflow = resolveWorkflowDefinition(state.workflow_id).workflow;
|
|
250
247
|
const stage = workflow.stages.find((s) => s.name === stageName);
|
|
251
248
|
if (!stage) {
|
|
252
249
|
throw new Error(
|
|
@@ -100,6 +100,21 @@ type ReviewStatusPayload = {
|
|
|
100
100
|
reviewedFiles: ReviewedFileSnapshot[] | null;
|
|
101
101
|
};
|
|
102
102
|
|
|
103
|
+
function formatReviewEvidenceSource(
|
|
104
|
+
source: ReviewStatusPayload["source"] | "none",
|
|
105
|
+
): string {
|
|
106
|
+
switch (source) {
|
|
107
|
+
case "workflow-state":
|
|
108
|
+
return "workflow state";
|
|
109
|
+
case "workflow-artifact":
|
|
110
|
+
return "workflow artifact";
|
|
111
|
+
case "legacy-review-status":
|
|
112
|
+
return "legacy file";
|
|
113
|
+
default:
|
|
114
|
+
return "none";
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
103
118
|
type ReviewedFileSnapshot = {
|
|
104
119
|
path: string;
|
|
105
120
|
exists: boolean;
|
|
@@ -474,7 +489,9 @@ registerValidator({
|
|
|
474
489
|
pass: false,
|
|
475
490
|
severity: "warning",
|
|
476
491
|
message: `${sourceLabel} at ${reviewStatus.timestamp} is stale for current changes`,
|
|
477
|
-
detail:
|
|
492
|
+
detail:
|
|
493
|
+
`Source: ${formatReviewEvidenceSource(reviewStatus.source)}. ` +
|
|
494
|
+
`${freshness.detail ?? "Current changes no longer match the reviewed code."}`,
|
|
478
495
|
};
|
|
479
496
|
}
|
|
480
497
|
|
|
@@ -485,7 +502,7 @@ registerValidator({
|
|
|
485
502
|
message: reviewStatus.reviewed
|
|
486
503
|
? `Enterprise review completed by ${reviewStatus.reviewer} at ${reviewStatus.timestamp}`
|
|
487
504
|
: `Enterprise review recorded at ${reviewStatus.timestamp} but did not pass`,
|
|
488
|
-
detail: `Source: ${reviewStatus.source}`,
|
|
505
|
+
detail: `Source: ${formatReviewEvidenceSource(reviewStatus.source)}`,
|
|
489
506
|
};
|
|
490
507
|
}
|
|
491
508
|
|
|
@@ -496,7 +513,9 @@ registerValidator({
|
|
|
496
513
|
message: reviewStatus.reviewed
|
|
497
514
|
? `Code review completed by ${reviewStatus.reviewer} at ${reviewStatus.timestamp}`
|
|
498
515
|
: "Code review recorded but not approved",
|
|
499
|
-
detail: reviewStatus.reviewed
|
|
516
|
+
detail: reviewStatus.reviewed
|
|
517
|
+
? undefined
|
|
518
|
+
: `Source: ${formatReviewEvidenceSource(reviewStatus.source)}`,
|
|
500
519
|
};
|
|
501
520
|
}
|
|
502
521
|
|
|
@@ -504,7 +523,8 @@ registerValidator({
|
|
|
504
523
|
pass: false,
|
|
505
524
|
severity: "warning",
|
|
506
525
|
message: "No code review recorded for current changes",
|
|
507
|
-
detail:
|
|
526
|
+
detail:
|
|
527
|
+
"Source: none. Run /review or context.review, or ensure your CI writes .context/review-status.json.",
|
|
508
528
|
};
|
|
509
529
|
},
|
|
510
530
|
});
|