@danielblomma/cortex-mcp 2.4.0 → 2.4.1

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.
Files changed (173) hide show
  1. package/CHANGELOG.md +201 -0
  2. package/README.md +19 -3
  3. package/bin/cortex.mjs +308 -75
  4. package/bin/daemon-control.mjs +162 -0
  5. package/package.json +7 -3
  6. package/scaffold/mcp/dist/.cortex-build-hash +1 -0
  7. package/scaffold/mcp/dist/cli/enterprise-setup.js +134 -0
  8. package/scaffold/mcp/dist/cli/govern.js +937 -0
  9. package/scaffold/mcp/dist/cli/query.js +409 -0
  10. package/scaffold/mcp/dist/cli/run.js +295 -0
  11. package/scaffold/mcp/dist/cli/stage.js +308 -0
  12. package/scaffold/mcp/dist/cli/telemetry-test.js +141 -0
  13. package/scaffold/mcp/dist/cli/ungoverned-detector.js +133 -0
  14. package/scaffold/mcp/dist/contextEntities.js +282 -0
  15. package/scaffold/mcp/dist/core/audit/query.js +72 -0
  16. package/scaffold/mcp/dist/core/audit/writer.js +28 -0
  17. package/scaffold/mcp/dist/core/config.js +235 -0
  18. package/scaffold/mcp/dist/core/enterprise-host-identity.js +193 -0
  19. package/scaffold/mcp/dist/core/enterprise-identity.js +18 -0
  20. package/scaffold/mcp/dist/core/enterprise-rotation.js +158 -0
  21. package/scaffold/mcp/dist/core/govern-paths.js +21 -0
  22. package/scaffold/mcp/dist/core/index.js +14 -0
  23. package/scaffold/mcp/dist/core/license.js +278 -0
  24. package/scaffold/mcp/dist/core/policy/enforce.js +66 -0
  25. package/scaffold/mcp/dist/core/policy/injection.js +172 -0
  26. package/scaffold/mcp/dist/core/policy/store.js +179 -0
  27. package/scaffold/mcp/dist/core/rbac/check.js +30 -0
  28. package/scaffold/mcp/dist/core/secure-endpoint.js +25 -0
  29. package/scaffold/mcp/dist/core/telemetry/collector.js +285 -0
  30. package/scaffold/mcp/dist/core/telemetry/state-dir.js +31 -0
  31. package/scaffold/mcp/dist/core/validators/builtins.js +632 -0
  32. package/scaffold/mcp/dist/core/validators/config.js +44 -0
  33. package/scaffold/mcp/dist/core/validators/engine.js +120 -0
  34. package/scaffold/mcp/dist/core/validators/evaluators/code_comments.js +236 -0
  35. package/scaffold/mcp/dist/core/validators/evaluators/regex.js +116 -0
  36. package/scaffold/mcp/dist/core/workflow/artifact-io.js +103 -0
  37. package/scaffold/mcp/dist/core/workflow/capabilities.js +88 -0
  38. package/scaffold/mcp/dist/core/workflow/default-workflows.js +102 -0
  39. package/scaffold/mcp/dist/core/workflow/enforcement.js +164 -0
  40. package/scaffold/mcp/dist/core/workflow/envelope.js +132 -0
  41. package/scaffold/mcp/dist/core/workflow/index.js +11 -0
  42. package/scaffold/mcp/dist/core/workflow/mcp-tools.js +175 -0
  43. package/scaffold/mcp/dist/core/workflow/resolution.js +69 -0
  44. package/scaffold/mcp/dist/core/workflow/run-lifecycle.js +123 -0
  45. package/scaffold/mcp/dist/core/workflow/schemas.js +141 -0
  46. package/scaffold/mcp/dist/core/workflow/synced-capability-registry.js +60 -0
  47. package/scaffold/mcp/dist/core/workflow/synced-registry.js +60 -0
  48. package/scaffold/mcp/dist/daemon/capability-sync-checker.js +242 -0
  49. package/scaffold/mcp/dist/daemon/client.js +130 -0
  50. package/scaffold/mcp/dist/daemon/egress-proxy.js +288 -0
  51. package/scaffold/mcp/dist/daemon/global-host-events.js +222 -0
  52. package/scaffold/mcp/dist/daemon/heartbeat-pusher.js +116 -0
  53. package/scaffold/mcp/dist/daemon/heartbeat-tracker.js +165 -0
  54. package/scaffold/mcp/dist/daemon/host-events-pusher.js +249 -0
  55. package/scaffold/mcp/dist/daemon/main.js +449 -0
  56. package/scaffold/mcp/dist/daemon/paths.js +36 -0
  57. package/scaffold/mcp/dist/daemon/project-service-registry.js +78 -0
  58. package/scaffold/mcp/dist/daemon/protocol.js +8 -0
  59. package/scaffold/mcp/dist/daemon/server.js +180 -0
  60. package/scaffold/mcp/dist/daemon/skill-sync-checker.js +557 -0
  61. package/scaffold/mcp/dist/daemon/sync-checker.js +165 -0
  62. package/scaffold/mcp/dist/daemon/ungoverned-scanner.js +136 -0
  63. package/scaffold/mcp/dist/daemon/workflow-sync-checker.js +249 -0
  64. package/scaffold/mcp/dist/defaults.js +6 -0
  65. package/scaffold/mcp/dist/embed.js +627 -0
  66. package/scaffold/mcp/dist/embedScheduler.js +479 -0
  67. package/scaffold/mcp/dist/embeddings.js +167 -0
  68. package/scaffold/mcp/dist/enterprise/audit/push.js +66 -0
  69. package/scaffold/mcp/dist/enterprise/index.js +327 -0
  70. package/scaffold/mcp/dist/enterprise/model/deploy.js +27 -0
  71. package/scaffold/mcp/dist/enterprise/policy/sync.js +129 -0
  72. package/scaffold/mcp/dist/enterprise/privacy/boundary.js +184 -0
  73. package/scaffold/mcp/dist/enterprise/reviews/changed-files.js +33 -0
  74. package/scaffold/mcp/dist/enterprise/reviews/pattern-context.js +202 -0
  75. package/scaffold/mcp/dist/enterprise/reviews/policy-selection.js +46 -0
  76. package/scaffold/mcp/dist/enterprise/reviews/push.js +102 -0
  77. package/scaffold/mcp/dist/enterprise/reviews/trust-state.js +186 -0
  78. package/scaffold/mcp/dist/enterprise/telemetry/sync.js +57 -0
  79. package/scaffold/mcp/dist/enterprise/tools/enterprise.js +826 -0
  80. package/scaffold/mcp/dist/enterprise/tools/harness.js +40 -0
  81. package/scaffold/mcp/dist/enterprise/tools/walk.js +73 -0
  82. package/scaffold/mcp/dist/enterprise/violations/push.js +77 -0
  83. package/scaffold/mcp/dist/enterprise/workflow/push.js +44 -0
  84. package/scaffold/mcp/dist/enterprise/workflow/state.js +329 -0
  85. package/scaffold/mcp/dist/frontmatter.js +33 -0
  86. package/scaffold/mcp/dist/graph.js +769 -0
  87. package/scaffold/mcp/dist/graphCsv.js +55 -0
  88. package/scaffold/mcp/dist/graphMetrics.js +8 -0
  89. package/scaffold/mcp/dist/hooks/permission-request.js +89 -0
  90. package/scaffold/mcp/dist/hooks/post-tool-use.js +105 -0
  91. package/scaffold/mcp/dist/hooks/pre-compact.js +29 -0
  92. package/scaffold/mcp/dist/hooks/pre-tool-use.js +78 -0
  93. package/scaffold/mcp/dist/hooks/session-end.js +43 -0
  94. package/scaffold/mcp/dist/hooks/session-start.js +41 -0
  95. package/scaffold/mcp/dist/hooks/shared.js +194 -0
  96. package/scaffold/mcp/dist/hooks/stop.js +28 -0
  97. package/scaffold/mcp/dist/hooks/user-prompt-submit.js +33 -0
  98. package/scaffold/mcp/dist/impactPresentation.js +137 -0
  99. package/scaffold/mcp/dist/impactRanking.js +191 -0
  100. package/scaffold/mcp/dist/impactResponse.js +30 -0
  101. package/scaffold/mcp/dist/impactResults.js +105 -0
  102. package/scaffold/mcp/dist/impactSeed.js +20 -0
  103. package/scaffold/mcp/dist/impactTraversal.js +64 -0
  104. package/scaffold/mcp/dist/jsonl.js +77 -0
  105. package/scaffold/mcp/dist/loadGraph.js +759 -0
  106. package/scaffold/mcp/dist/lruCache.js +38 -0
  107. package/scaffold/mcp/dist/paths.js +97 -0
  108. package/scaffold/mcp/dist/patternEvidence.js +272 -0
  109. package/scaffold/mcp/dist/plugin.js +81 -0
  110. package/scaffold/mcp/dist/presets.js +78 -0
  111. package/scaffold/mcp/dist/relatedResponse.js +18 -0
  112. package/scaffold/mcp/dist/relatedTraversal.js +78 -0
  113. package/scaffold/mcp/dist/rules.js +23 -0
  114. package/scaffold/mcp/dist/search.js +212 -0
  115. package/scaffold/mcp/dist/searchCore.js +457 -0
  116. package/scaffold/mcp/dist/searchResults.js +230 -0
  117. package/scaffold/mcp/dist/server.js +317 -0
  118. package/scaffold/mcp/dist/types.js +1 -0
  119. package/scaffold/mcp/package-lock.json +321 -200
  120. package/scaffold/mcp/package.json +15 -6
  121. package/scaffold/mcp/src/cli/enterprise-setup.ts +82 -8
  122. package/scaffold/mcp/src/cli/govern.ts +137 -52
  123. package/scaffold/mcp/src/cli/run.ts +53 -19
  124. package/scaffold/mcp/src/cli/stage.ts +8 -3
  125. package/scaffold/mcp/src/core/config.ts +9 -2
  126. package/scaffold/mcp/src/core/enterprise-host-identity.ts +259 -0
  127. package/scaffold/mcp/src/core/enterprise-identity.ts +20 -0
  128. package/scaffold/mcp/src/core/enterprise-rotation.ts +185 -0
  129. package/scaffold/mcp/src/core/govern-paths.ts +30 -0
  130. package/scaffold/mcp/src/core/license.ts +186 -17
  131. package/scaffold/mcp/src/core/secure-endpoint.ts +23 -0
  132. package/scaffold/mcp/src/core/workflow/enforcement.ts +8 -1
  133. package/scaffold/mcp/src/core/workflow/mcp-tools.ts +3 -0
  134. package/scaffold/mcp/src/core/workflow/resolution.ts +9 -1
  135. package/scaffold/mcp/src/core/workflow/synced-capability-registry.ts +15 -0
  136. package/scaffold/mcp/src/core/workflow/synced-registry.ts +15 -0
  137. package/scaffold/mcp/src/daemon/capability-sync-checker.ts +38 -2
  138. package/scaffold/mcp/src/daemon/egress-proxy.ts +14 -8
  139. package/scaffold/mcp/src/daemon/global-host-events.ts +288 -0
  140. package/scaffold/mcp/src/daemon/heartbeat-pusher.ts +4 -0
  141. package/scaffold/mcp/src/daemon/heartbeat-tracker.ts +2 -0
  142. package/scaffold/mcp/src/daemon/host-events-pusher.ts +5 -0
  143. package/scaffold/mcp/src/daemon/main.ts +99 -25
  144. package/scaffold/mcp/src/daemon/project-service-registry.ts +107 -0
  145. package/scaffold/mcp/src/daemon/skill-sync-checker.ts +368 -31
  146. package/scaffold/mcp/src/daemon/sync-checker.ts +4 -0
  147. package/scaffold/mcp/src/daemon/ungoverned-scanner.ts +57 -25
  148. package/scaffold/mcp/src/daemon/workflow-sync-checker.ts +41 -2
  149. package/scaffold/mcp/src/enterprise/audit/push.ts +8 -0
  150. package/scaffold/mcp/src/enterprise/policy/sync.ts +12 -0
  151. package/scaffold/mcp/src/enterprise/reviews/push.ts +9 -0
  152. package/scaffold/mcp/src/enterprise/reviews/trust-state.ts +3 -1
  153. package/scaffold/mcp/src/enterprise/telemetry/sync.ts +9 -0
  154. package/scaffold/mcp/src/enterprise/violations/push.ts +9 -0
  155. package/scaffold/mcp/src/enterprise/workflow/push.ts +7 -0
  156. package/scaffold/mcp/src/plugin.ts +20 -0
  157. package/scaffold/mcp/tests/copilot-shim.test.mjs +19 -1
  158. package/scaffold/mcp/tests/egress-proxy.test.mjs +37 -0
  159. package/scaffold/mcp/tests/enterprise-identity-sync.test.mjs +401 -0
  160. package/scaffold/mcp/tests/enterprise-setup.test.mjs +189 -0
  161. package/scaffold/mcp/tests/global-host-events.test.mjs +81 -0
  162. package/scaffold/mcp/tests/govern-install.test.mjs +95 -2
  163. package/scaffold/mcp/tests/govern-repair.test.mjs +20 -3
  164. package/scaffold/mcp/tests/heartbeat-tracker.test.mjs +26 -0
  165. package/scaffold/mcp/tests/license.test.mjs +367 -0
  166. package/scaffold/mcp/tests/project-service-registry.test.mjs +172 -0
  167. package/scaffold/mcp/tests/review-trust-contract.test.mjs +18 -0
  168. package/scaffold/mcp/tests/secure-enterprise-endpoint.test.mjs +46 -0
  169. package/scaffold/mcp/tests/skill-sync-checker.test.mjs +446 -2
  170. package/scaffold/mcp/tests/ungoverned-scanner.test.mjs +104 -22
  171. package/scaffold/mcp/tests/workflow-cli.test.mjs +14 -1
  172. package/scaffold/mcp/tests/workflow-synced-capabilities.test.mjs +37 -0
  173. package/scaffold/mcp/tests/workflow-synced-registry.test.mjs +40 -1
@@ -10,6 +10,7 @@ import {
10
10
  } from "../dist/core/workflow/synced-capability-registry.js";
11
11
  import { evaluateToolCall } from "../dist/core/workflow/enforcement.js";
12
12
  import { createRun } from "../dist/core/workflow/run-lifecycle.js";
13
+ import { enterpriseCredentialId } from "../dist/core/license.js";
13
14
 
14
15
  function makeWorkspace() {
15
16
  return fs.mkdtempSync(path.join(os.tmpdir(), "cortex-synced-caps-"));
@@ -49,6 +50,23 @@ function writeCache(dir, payload) {
49
50
  );
50
51
  }
51
52
 
53
+ function configureEnterprise(cwd) {
54
+ const endpoint = "https://licenses.example.com";
55
+ const apiKey = "ent_capability_12345678";
56
+ fs.mkdirSync(path.join(cwd, ".context"), { recursive: true });
57
+ fs.writeFileSync(
58
+ path.join(cwd, ".context", "enterprise.yml"),
59
+ [
60
+ "enterprise:",
61
+ ` api_key: ${apiKey}`,
62
+ ` endpoint: ${endpoint}`,
63
+ "",
64
+ ].join("\n"),
65
+ "utf8",
66
+ );
67
+ return enterpriseCredentialId(endpoint, apiKey);
68
+ }
69
+
52
70
  test("syncedCapabilitiesCachePath: defaults to ~/.cortex/capabilities.local.json", () => {
53
71
  const expected = path.join(os.homedir(), ".cortex", "capabilities.local.json");
54
72
  assert.equal(syncedCapabilitiesCachePath(), expected);
@@ -107,16 +125,33 @@ test("loadSyncedCapabilities: returns valid capability definitions", () => {
107
125
  assert.deepEqual(loaded["frontend-builder"].write_globs, ["src/components/**"]);
108
126
  });
109
127
 
128
+ test("loadSyncedCapabilities: rejects a cache bound to another Enterprise identity", () => {
129
+ const dir = makeWorkspace();
130
+ writeCache(dir, {
131
+ credential_id: "identity-a",
132
+ capabilities: {
133
+ "frontend-builder": {
134
+ capability_name: "frontend-builder",
135
+ updated_at: "2026-05-07T12:00:00.000Z",
136
+ definition: FRONTEND_BUILDER,
137
+ },
138
+ },
139
+ });
140
+ assert.deepEqual(loadSyncedCapabilities(dir, "identity-b"), {});
141
+ });
142
+
110
143
  test("evaluateToolCall integration: synced capability is consulted via merged registry", () => {
111
144
  const cwd = makeWorkspace();
112
145
  // Sandbox the home-dir-based loader.
113
146
  const fakeHome = makeWorkspace();
114
147
  process.env.HOME = fakeHome;
115
148
  try {
149
+ const credentialId = configureEnterprise(cwd);
116
150
  fs.mkdirSync(path.join(fakeHome, ".cortex"), { recursive: true });
117
151
  fs.writeFileSync(
118
152
  path.join(fakeHome, ".cortex", "capabilities.local.json"),
119
153
  JSON.stringify({
154
+ credential_id: credentialId,
120
155
  capabilities: {
121
156
  "frontend-builder": {
122
157
  capability_name: "frontend-builder",
@@ -163,6 +198,7 @@ test("evaluateToolCall integration: synced capability with same name as bundled
163
198
  const fakeHome = makeWorkspace();
164
199
  process.env.HOME = fakeHome;
165
200
  try {
201
+ const credentialId = configureEnterprise(cwd);
166
202
  // Override the bundled "builder" capability with a much stricter version
167
203
  // — only test files writable.
168
204
  const stricterBuilder = {
@@ -176,6 +212,7 @@ test("evaluateToolCall integration: synced capability with same name as bundled
176
212
  fs.writeFileSync(
177
213
  path.join(fakeHome, ".cortex", "capabilities.local.json"),
178
214
  JSON.stringify({
215
+ credential_id: credentialId,
179
216
  capabilities: {
180
217
  builder: {
181
218
  capability_name: "builder",
@@ -11,6 +11,7 @@ import {
11
11
  import { resolveWorkflowDefinition } from "../dist/core/workflow/resolution.js";
12
12
  import { runWorkflowStart } from "../dist/core/workflow/mcp-tools.js";
13
13
  import { SECURE_BUILD_WORKFLOW } from "../dist/core/workflow/default-workflows.js";
14
+ import { enterpriseCredentialId } from "../dist/core/license.js";
14
15
 
15
16
  function makeWorkspace() {
16
17
  return fs.mkdtempSync(path.join(os.tmpdir(), "cortex-synced-registry-"));
@@ -49,6 +50,23 @@ function writeCache(dir, payload) {
49
50
  );
50
51
  }
51
52
 
53
+ function configureEnterprise(cwd) {
54
+ const endpoint = "https://licenses.example.com";
55
+ const apiKey = "ent_workflow_12345678";
56
+ fs.mkdirSync(path.join(cwd, ".context"), { recursive: true });
57
+ fs.writeFileSync(
58
+ path.join(cwd, ".context", "enterprise.yml"),
59
+ [
60
+ "enterprise:",
61
+ ` api_key: ${apiKey}`,
62
+ ` endpoint: ${endpoint}`,
63
+ "",
64
+ ].join("\n"),
65
+ "utf8",
66
+ );
67
+ return enterpriseCredentialId(endpoint, apiKey);
68
+ }
69
+
52
70
  test("syncedWorkflowsCachePath: defaults to ~/.cortex/workflows.local.json", () => {
53
71
  const expected = path.join(os.homedir(), ".cortex", "workflows.local.json");
54
72
  assert.equal(syncedWorkflowsCachePath(), expected);
@@ -110,6 +128,22 @@ test("loadSyncedWorkflows: returns valid workflow definitions keyed by workflow_
110
128
  assert.equal(loaded.tiny.stages.length, 2);
111
129
  });
112
130
 
131
+ test("loadSyncedWorkflows: rejects a cache bound to another Enterprise identity", () => {
132
+ const dir = makeWorkspace();
133
+ writeCache(dir, {
134
+ credential_id: "identity-a",
135
+ workflows: {
136
+ tiny: {
137
+ workflow_id: "tiny",
138
+ version: 1,
139
+ updated_at: "2026-05-06T12:00:00.000Z",
140
+ definition: TINY_WORKFLOW,
141
+ },
142
+ },
143
+ });
144
+ assert.deepEqual(loadSyncedWorkflows(dir, "identity-b"), {});
145
+ });
146
+
113
147
  test("resolveWorkflow integration: synced workflow takes precedence over bundled default", () => {
114
148
  // We can't easily intercept loadSyncedWorkflows() from inside
115
149
  // mcp-tools.ts (it reads from a fixed home-dir path). Instead, exercise
@@ -148,10 +182,12 @@ test("resolveWorkflow integration: synced cache adds new workflow_ids beyond def
148
182
  const fakeHome = makeWorkspace();
149
183
  process.env.HOME = fakeHome;
150
184
  try {
185
+ const credentialId = configureEnterprise(cwd);
151
186
  fs.mkdirSync(path.join(fakeHome, ".cortex"), { recursive: true });
152
187
  fs.writeFileSync(
153
188
  path.join(fakeHome, ".cortex", "workflows.local.json"),
154
189
  JSON.stringify({
190
+ credential_id: credentialId,
155
191
  workflows: {
156
192
  tiny: {
157
193
  workflow_id: "tiny",
@@ -215,7 +251,10 @@ test("resolveWorkflowDefinition: unknown workflow errors list bundled and synced
215
251
  const fakeHome = makeWorkspace();
216
252
  process.env.HOME = fakeHome;
217
253
  try {
254
+ const cwd = makeWorkspace();
255
+ const credentialId = configureEnterprise(cwd);
218
256
  writeCache(path.join(fakeHome, ".cortex"), {
257
+ credential_id: credentialId,
219
258
  workflows: {
220
259
  tiny: {
221
260
  workflow_id: "tiny",
@@ -226,7 +265,7 @@ test("resolveWorkflowDefinition: unknown workflow errors list bundled and synced
226
265
  },
227
266
  });
228
267
  assert.throws(
229
- () => resolveWorkflowDefinition("missing-workflow"),
268
+ () => resolveWorkflowDefinition("missing-workflow", { cwd }),
230
269
  /Available bundled: secure-build\. Available synced: tiny\./,
231
270
  );
232
271
  } finally {