nexus-prime 4.10.0 → 4.10.2

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 (83) hide show
  1. package/README.md +22 -0
  2. package/dist/agents/adapters/mcp.d.ts +9 -1
  3. package/dist/agents/adapters/mcp.d.ts.map +1 -1
  4. package/dist/agents/adapters/mcp.js +100 -39
  5. package/dist/agents/adapters/mcp.js.map +1 -1
  6. package/dist/architects/bootstrap.js +1 -1
  7. package/dist/architects/bootstrap.js.map +1 -1
  8. package/dist/cli.d.ts +0 -1
  9. package/dist/cli.d.ts.map +1 -1
  10. package/dist/cli.js +1 -2
  11. package/dist/cli.js.map +1 -1
  12. package/dist/core/types.d.ts +1 -0
  13. package/dist/core/types.d.ts.map +1 -1
  14. package/dist/dashboard/index.html +52 -17
  15. package/dist/dashboard/server.d.ts +2 -0
  16. package/dist/dashboard/server.d.ts.map +1 -1
  17. package/dist/dashboard/server.js +96 -17
  18. package/dist/dashboard/server.js.map +1 -1
  19. package/dist/engines/client-bootstrap.d.ts.map +1 -1
  20. package/dist/engines/client-bootstrap.js +27 -7
  21. package/dist/engines/client-bootstrap.js.map +1 -1
  22. package/dist/engines/knowledge-fabric.d.ts.map +1 -1
  23. package/dist/engines/knowledge-fabric.js +49 -0
  24. package/dist/engines/knowledge-fabric.js.map +1 -1
  25. package/dist/engines/memory-control-plane.d.ts +1 -1
  26. package/dist/engines/memory-control-plane.d.ts.map +1 -1
  27. package/dist/engines/memory.d.ts +1 -1
  28. package/dist/engines/memory.d.ts.map +1 -1
  29. package/dist/engines/ngram-index.d.ts.map +1 -1
  30. package/dist/engines/ngram-index.js +7 -4
  31. package/dist/engines/ngram-index.js.map +1 -1
  32. package/dist/engines/orchestrator.d.ts +12 -0
  33. package/dist/engines/orchestrator.d.ts.map +1 -1
  34. package/dist/engines/orchestrator.js +222 -19
  35. package/dist/engines/orchestrator.js.map +1 -1
  36. package/dist/engines/runtime-registry.d.ts +10 -1
  37. package/dist/engines/runtime-registry.d.ts.map +1 -1
  38. package/dist/engines/runtime-registry.js.map +1 -1
  39. package/dist/engines/skill-runtime.d.ts +1 -1
  40. package/dist/engines/skill-runtime.d.ts.map +1 -1
  41. package/dist/engines/skill-runtime.js +21 -2
  42. package/dist/engines/skill-runtime.js.map +1 -1
  43. package/dist/engines/workspace-resolver.d.ts +1 -1
  44. package/dist/engines/workspace-resolver.d.ts.map +1 -1
  45. package/dist/engines/workspace-resolver.js +109 -20
  46. package/dist/engines/workspace-resolver.js.map +1 -1
  47. package/dist/index.d.ts +4 -0
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +84 -10
  50. package/dist/index.js.map +1 -1
  51. package/dist/phantom/runtime.d.ts +1 -0
  52. package/dist/phantom/runtime.d.ts.map +1 -1
  53. package/dist/phantom/runtime.js +16 -0
  54. package/dist/phantom/runtime.js.map +1 -1
  55. package/dist/synapse/approvals/gate.d.ts +1 -0
  56. package/dist/synapse/approvals/gate.d.ts.map +1 -1
  57. package/dist/synapse/approvals/gate.js +15 -3
  58. package/dist/synapse/approvals/gate.js.map +1 -1
  59. package/dist/synapse/bootstrap.d.ts.map +1 -1
  60. package/dist/synapse/bootstrap.js +168 -5
  61. package/dist/synapse/bootstrap.js.map +1 -1
  62. package/dist/synapse/db/schema.d.ts +1 -1
  63. package/dist/synapse/db/schema.d.ts.map +1 -1
  64. package/dist/synapse/db/schema.js +13 -1
  65. package/dist/synapse/db/schema.js.map +1 -1
  66. package/dist/synapse/mandate/pipeline.d.ts.map +1 -1
  67. package/dist/synapse/mandate/pipeline.js +2 -0
  68. package/dist/synapse/mandate/pipeline.js.map +1 -1
  69. package/dist/synapse/mcp-tools.d.ts +254 -20
  70. package/dist/synapse/mcp-tools.d.ts.map +1 -1
  71. package/dist/synapse/mcp-tools.js +99 -2
  72. package/dist/synapse/mcp-tools.js.map +1 -1
  73. package/dist/synapse/operatives/crud.d.ts +2 -0
  74. package/dist/synapse/operatives/crud.d.ts.map +1 -1
  75. package/dist/synapse/operatives/crud.js +24 -3
  76. package/dist/synapse/operatives/crud.js.map +1 -1
  77. package/dist/synapse/types.d.ts +36 -0
  78. package/dist/synapse/types.d.ts.map +1 -1
  79. package/package.json +1 -1
  80. package/dist/utils/env-defaults.d.ts +0 -2
  81. package/dist/utils/env-defaults.d.ts.map +0 -1
  82. package/dist/utils/env-defaults.js +0 -13
  83. package/dist/utils/env-defaults.js.map +0 -1
package/README.md CHANGED
@@ -630,6 +630,28 @@ Inventory Snapshot: 109 skills · 64 workflows · 9 hooks · 5 automations · 7
630
630
  ## 📜 Release History
631
631
 
632
632
  <details open>
633
+ <summary><b>v4.10.2</b> · 2026-04-02 · Company Control Plane — runtime-scoped hiring, repo-truth MCP, and dashboard alignment</summary>
634
+
635
+ - **Real employee control plane**: Synapse now supports direct and approval-backed hires, operative lifecycle updates, and heartbeat triggers instead of keeping hiring behind internal-only mandate plumbing.
636
+ - **Repo-truth MCP fallback**: MCP fallback runtimes, token planning, search, and telemetry now stay scoped to the active workspace state key instead of leaking package-root identity.
637
+ - **Aligned dashboard surfaces**: Summary, trust, Synapse, and Architects views now carry selected-runtime repo identity, operative lineage, and the relevant worklist by default.
638
+ - **Shared operational memory**: Synapse control-plane events now persist operative, team, worklist, and work-item lineage into shared memory for later coordination and inspection.
639
+
640
+ Full notes: [releases/v4.10.2.md](./releases/v4.10.2.md) · Full history: [CHANGELOG.md](./CHANGELOG.md)
641
+ </details>
642
+
643
+ <details>
644
+ <summary><b>v4.10.1</b> · 2026-04-02 · Workspace Truth — repo-first binding, real skill selection, and grounded knowledge state</summary>
645
+
646
+ - **Repo-first workspace binding**: Nexus now prefers the active repo over stale installed-package hints, which stops Codex and MCP sessions from snapping to Homebrew-style package roots.
647
+ - **Real skill handoff**: Repo-local skills are registered per workspace state root, runtime selection participates in packet assembly, and id-based selections no longer disappear before execution.
648
+ - **Grounded knowledge state**: First-run workspace profile seeding and dashboard RAG hydration now reflect the selected runtime instead of generic bootstrap noise or stale usage state.
649
+ - **Cleaner inactive mode**: Synapse and Architects stay initialized but explicitly inactive until configured, without telling normal operators to set operative IDs.
650
+
651
+ Full notes: [releases/v4.10.1.md](./releases/v4.10.1.md) · Full history: [CHANGELOG.md](./CHANGELOG.md)
652
+ </details>
653
+
654
+ <details>
633
655
  <summary><b>v4.10.0</b> · 2026-04-01 · Control Plane Recovery — truthful catalogs, bounded memory repair, and fast MCP startup</summary>
634
656
 
635
657
  - **Truthful catalog health**: `.agents/*` is now canonical, `.agent/*` is treated as legacy fallback, and runtime health only degrades when selected assets actually fail to resolve.
@@ -16,6 +16,8 @@ export declare class MCPAdapter implements Adapter {
16
16
  private telemetry;
17
17
  private sessionDNA;
18
18
  private runtime?;
19
+ private fallbackRuntimeStateKey?;
20
+ private darwinLoops;
19
21
  private lifecyclePolicy;
20
22
  private memoryInjectionCache;
21
23
  private lastMemoryInjectionAt;
@@ -28,10 +30,16 @@ export declare class MCPAdapter implements Adapter {
28
30
  constructor();
29
31
  private detectCallerName;
30
32
  setNexusRef(nexus: NexusPrime): void;
33
+ private isPackageLikeWorkspace;
34
+ private resolveWorkspaceHintFromArgs;
35
+ private getWorkspaceContextForArgs;
36
+ private resolveToolPath;
37
+ private getToolProjectHash;
38
+ private getRepoNgramIndex;
39
+ private getDarwinLoop;
31
40
  private getRuntime;
32
41
  private getOrchestrator;
33
42
  private getToolProfile;
34
- private getProjectHash;
35
43
  private registerBuiltInMiddleware;
36
44
  private formatProtocolChecklist;
37
45
  private formatRemainingProtocolSteps;
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../../src/agents/adapters/mcp.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AA+F5C,KAAK,cAAc,GAAG,YAAY,GAAG,MAAM,CAAC;AAK5C,KAAK,iBAAiB,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC,CAAC;AAkYF,qBAAa,UAAW,YAAW,OAAO;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAG,KAAK,CAAU;IACtB,SAAS,UAAS;IAClB,MAAM,EAAE,MAAM,EAAE,CAAM;IAEtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAC,CAAa;IAC9B,OAAO,CAAC,SAAS,CAA4C;IAC7D,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,OAAO,CAAC,CAAkB;IAClC,OAAO,CAAC,eAAe,CAAyB;IAChD,OAAO,CAAC,oBAAoB,CAAgG;IAC5H,OAAO,CAAC,qBAAqB,CAAK;IAClC,OAAO,CAAC,WAAW,CAAM;IACzB,OAAO,CAAC,kBAAkB,CAAqB;IAE/C,OAAO,CAAC,cAAc;IA6BtB,OAAO,CAAC,oBAAoB;IAsB5B,OAAO,CAAC,eAAe;IAqEvB,OAAO,CAAC,GAAG;;IAqBX,OAAO,CAAC,gBAAgB;IA4BxB,WAAW,CAAC,KAAK,EAAE,UAAU;IAI7B,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,yBAAyB;IAqFjC,OAAO,CAAC,uBAAuB;IAY/B,OAAO,CAAC,4BAA4B;IAWpC,OAAO,CAAC,qBAAqB;IAiB7B,OAAO,CAAC,yBAAyB;IA2CjC,OAAO,CAAC,mBAAmB;IAO3B,OAAO,CAAC,YAAY;YAON,mBAAmB;IA0DjC,OAAO,CAAC,+BAA+B;IAMvC,OAAO,CAAC,uBAAuB;IA0B/B,OAAO,CAAC,2BAA2B;IAqBnC,OAAO,CAAC,uBAAuB;IAkC/B,cAAc,CAAC,OAAO,GAAE,cAAsC,GAAG,iBAAiB,EAAE;IAIpF,OAAO,CAAC,oBAAoB;IAg/B5B,OAAO,CAAC,iBAAiB;YAuGX,cAAc;IAq/E5B,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE;IAItC,OAAO,CAAC,IAAI;IAmBN,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAOxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB3B,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAYlD,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;CAOzC"}
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../../src/agents/adapters/mcp.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAkG5C,KAAK,cAAc,GAAG,YAAY,GAAG,MAAM,CAAC;AAK5C,KAAK,iBAAiB,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC,CAAC;AAkYF,qBAAa,UAAW,YAAW,OAAO;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAG,KAAK,CAAU;IACtB,SAAS,UAAS;IAClB,MAAM,EAAE,MAAM,EAAE,CAAM;IAEtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAC,CAAa;IAC9B,OAAO,CAAC,SAAS,CAA4C;IAC7D,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,OAAO,CAAC,CAAkB;IAClC,OAAO,CAAC,uBAAuB,CAAC,CAAS;IACzC,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,eAAe,CAAyB;IAChD,OAAO,CAAC,oBAAoB,CAAgG;IAC5H,OAAO,CAAC,qBAAqB,CAAK;IAClC,OAAO,CAAC,WAAW,CAAM;IACzB,OAAO,CAAC,kBAAkB,CAAqB;IAE/C,OAAO,CAAC,cAAc;IA6BtB,OAAO,CAAC,oBAAoB;IAsB5B,OAAO,CAAC,eAAe;IAqEvB,OAAO,CAAC,GAAG;;IAqBX,OAAO,CAAC,gBAAgB;IA4BxB,WAAW,CAAC,KAAK,EAAE,UAAU;IAI7B,OAAO,CAAC,sBAAsB;IAK9B,OAAO,CAAC,4BAA4B;IAepC,OAAO,CAAC,0BAA0B;IAkBlC,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,yBAAyB;IAqFjC,OAAO,CAAC,uBAAuB;IAY/B,OAAO,CAAC,4BAA4B;IAWpC,OAAO,CAAC,qBAAqB;IAiB7B,OAAO,CAAC,yBAAyB;IA2CjC,OAAO,CAAC,mBAAmB;IAO3B,OAAO,CAAC,YAAY;YAON,mBAAmB;IA0DjC,OAAO,CAAC,+BAA+B;IAMvC,OAAO,CAAC,uBAAuB;IA0B/B,OAAO,CAAC,2BAA2B;IAqBnC,OAAO,CAAC,uBAAuB;IAkC/B,cAAc,CAAC,OAAO,GAAE,cAAsC,GAAG,iBAAiB,EAAE;IAIpF,OAAO,CAAC,oBAAoB;IAg/B5B,OAAO,CAAC,iBAAiB;YAuGX,cAAc;IAo/E5B,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE;IAItC,OAAO,CAAC,IAAI;IAmBN,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAOxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB3B,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAYlD,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;CAOzC"}
@@ -31,27 +31,37 @@ import { getSharedContextDiscovery } from '../../engines/context-discovery.js';
31
31
  import { MiddlewarePipeline } from '../../engines/middleware-pipeline.js';
32
32
  import { applyExecutionPreset, listExecutionPresets, resolveExecutionPreset } from '../../engines/execution-presets.js';
33
33
  import { ensureBootstrap } from '../../engines/client-bootstrap.js';
34
- import { resolveWorkspaceContext } from '../../engines/workspace-resolver.js';
34
+ import { resolveWorkspaceContext, resolveWorkspaceStateRoot } from '../../engines/workspace-resolver.js';
35
35
  import { synapseToolDefinitions, handleSynapseToolCall } from '../../synapse/index.js';
36
36
  import { architectsToolDefinitions, handleArchitectsToolCall } from '../../architects/index.js';
37
37
  const tokenEngine = new TokenSupremacyEngine();
38
38
  const guardrailEngine = new GuardrailEngine();
39
39
  const casEngine = new ContinuousAttentionStream();
40
40
  const kvBridge = createKVBridge({ agents: 3 });
41
- const orchestrator = new OrchestratorEngine();
42
- const darwinLoop = new DarwinLoop(orchestrator.getMemoryEngine());
43
41
  const federation = new FederationEngine();
44
- // Lazy-initialized fallback runtime to avoid leaking a phantom runtime at module load
45
- let _fallbackRuntime = null;
46
- function getFallbackRuntime() {
47
- if (!_fallbackRuntime) {
48
- const workspace = resolveWorkspaceContext();
49
- _fallbackRuntime = createSubAgentRuntime({
42
+ const fallbackRuntimes = new Map();
43
+ const fallbackOrchestrators = new Map();
44
+ function getFallbackRuntime(workspace) {
45
+ let runtime = fallbackRuntimes.get(workspace.stateKey);
46
+ if (!runtime) {
47
+ runtime = createSubAgentRuntime({
50
48
  repoRoot: workspace.repoRoot,
51
49
  artifactsRoot: path.join(workspace.stateRoot, 'runs'),
52
50
  });
51
+ fallbackRuntimes.set(workspace.stateKey, runtime);
53
52
  }
54
- return _fallbackRuntime;
53
+ return runtime;
54
+ }
55
+ function getFallbackOrchestrator(workspace) {
56
+ let instance = fallbackOrchestrators.get(workspace.stateKey);
57
+ if (!instance) {
58
+ instance = new OrchestratorEngine({
59
+ repoRoot: workspace.repoRoot,
60
+ runtime: getFallbackRuntime(workspace),
61
+ });
62
+ fallbackOrchestrators.set(workspace.stateKey, instance);
63
+ }
64
+ return instance;
55
65
  }
56
66
  // Lazy-initialized Graph Engine (separate DB from core memory)
57
67
  let _graphEngine = null;
@@ -72,13 +82,6 @@ function getHybridRetriever() {
72
82
  _hybridRetriever = new HybridRetriever(getGraphEngine());
73
83
  return _hybridRetriever;
74
84
  }
75
- // Lazy-initialized N-gram index for fast search
76
- let _ngramIndex = null;
77
- function getNgramIndexInstance() {
78
- if (!_ngramIndex)
79
- _ngramIndex = getSharedNgramIndex();
80
- return _ngramIndex;
81
- }
82
85
  // Derive project root from this file's location (dist/agents/adapters/mcp.js → project root)
83
86
  const __filename = fileURLToPath(import.meta.url);
84
87
  const PROJECT_ROOT = path.resolve(path.dirname(__filename), '..', '..', '..');
@@ -455,6 +458,8 @@ export class MCPAdapter {
455
458
  telemetry = new SessionTelemetry();
456
459
  sessionDNA;
457
460
  runtime;
461
+ fallbackRuntimeStateKey;
462
+ darwinLoops = new Map();
458
463
  lifecyclePolicy = new LifecyclePolicy();
459
464
  memoryInjectionCache = new Map();
460
465
  lastMemoryInjectionAt = 0;
@@ -630,29 +635,86 @@ export class MCPAdapter {
630
635
  setNexusRef(nexus) {
631
636
  this.nexusRef = nexus;
632
637
  }
633
- getRuntime() {
638
+ isPackageLikeWorkspace(target) {
639
+ const relative = path.relative(path.resolve(PROJECT_ROOT), path.resolve(target));
640
+ return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));
641
+ }
642
+ resolveWorkspaceHintFromArgs(args = {}) {
643
+ const rawFiles = [
644
+ ...(Array.isArray(args.files) ? args.files : []),
645
+ ...(Array.isArray(args.filesToModify) ? args.filesToModify : []),
646
+ ].map((value) => String(value ?? '').trim()).filter(Boolean);
647
+ const preferredCwd = process.env.INIT_CWD || process.env.PWD || process.cwd();
648
+ for (const rawFile of rawFiles) {
649
+ const absolute = path.isAbsolute(rawFile) ? rawFile : path.resolve(preferredCwd, rawFile);
650
+ const candidate = statSync(absolute, { throwIfNoEntry: false });
651
+ if (!candidate)
652
+ continue;
653
+ return candidate.isDirectory() ? absolute : path.dirname(absolute);
654
+ }
655
+ return undefined;
656
+ }
657
+ getWorkspaceContextForArgs(args = {}) {
658
+ const current = this.nexusRef?.getWorkspaceContext?.();
659
+ const preferredCwd = process.env.INIT_CWD || process.env.PWD || process.cwd();
660
+ const hintedRoot = this.resolveWorkspaceHintFromArgs(args);
661
+ const hinted = hintedRoot
662
+ ? resolveWorkspaceContext({ workspaceRoot: hintedRoot, cwd: preferredCwd, env: process.env })
663
+ : null;
664
+ if (hinted && (!current || current.stateKey !== hinted.stateKey)) {
665
+ return hinted;
666
+ }
667
+ const envResolved = resolveWorkspaceContext({ cwd: preferredCwd, env: process.env });
668
+ if (!current)
669
+ return envResolved;
670
+ if (this.isPackageLikeWorkspace(current.repoRoot) && !this.isPackageLikeWorkspace(envResolved.repoRoot)) {
671
+ return envResolved;
672
+ }
673
+ return current;
674
+ }
675
+ resolveToolPath(candidatePath, args = {}) {
676
+ return path.isAbsolute(candidatePath)
677
+ ? candidatePath
678
+ : path.join(this.getWorkspaceContextForArgs(args).repoRoot, candidatePath);
679
+ }
680
+ getToolProjectHash(args = {}) {
681
+ return createHash('sha1').update(path.resolve(this.getWorkspaceContextForArgs(args).repoRoot)).digest('hex').slice(0, 12);
682
+ }
683
+ getRepoNgramIndex(args = {}) {
684
+ const workspace = this.getWorkspaceContextForArgs(args);
685
+ return getSharedNgramIndex(path.join(resolveWorkspaceStateRoot(workspace.repoRoot), 'repo-search.ngram.db'));
686
+ }
687
+ getDarwinLoop(args = {}) {
688
+ const workspace = this.getWorkspaceContextForArgs(args);
689
+ let loop = this.darwinLoops.get(workspace.stateKey);
690
+ if (!loop) {
691
+ loop = new DarwinLoop(this.getOrchestrator(args).getMemoryEngine());
692
+ this.darwinLoops.set(workspace.stateKey, loop);
693
+ }
694
+ return loop;
695
+ }
696
+ getRuntime(args = {}) {
634
697
  if (this.nexusRef && typeof this.nexusRef.getRuntime === 'function') {
635
698
  return this.nexusRef.getRuntime();
636
699
  }
637
- if (!this.runtime) {
638
- this.runtime = getFallbackRuntime();
700
+ const workspace = this.getWorkspaceContextForArgs(args);
701
+ if (!this.runtime || this.fallbackRuntimeStateKey !== workspace.stateKey) {
702
+ this.runtime = getFallbackRuntime(workspace);
703
+ this.fallbackRuntimeStateKey = workspace.stateKey;
639
704
  }
640
705
  return this.runtime;
641
706
  }
642
- getOrchestrator() {
707
+ getOrchestrator(args = {}) {
643
708
  if (this.nexusRef && typeof this.nexusRef.getOrchestrator === 'function') {
644
709
  return this.nexusRef.getOrchestrator();
645
710
  }
646
- return orchestrator;
711
+ return getFallbackOrchestrator(this.getWorkspaceContextForArgs(args));
647
712
  }
648
713
  getToolProfile() {
649
714
  return String(process.env.NEXUS_MCP_TOOL_PROFILE ?? 'autonomous').toLowerCase() === 'full'
650
715
  ? 'full'
651
716
  : 'autonomous';
652
717
  }
653
- getProjectHash() {
654
- return createHash('sha1').update(path.resolve(PROJECT_ROOT)).digest('hex').slice(0, 12);
655
- }
656
718
  registerBuiltInMiddleware() {
657
719
  this.middlewarePipeline.register({
658
720
  name: 'token-budget',
@@ -2014,7 +2076,7 @@ export class MCPAdapter {
2014
2076
  toolName,
2015
2077
  args: args,
2016
2078
  adapterName: this.name,
2017
- projectHash: this.getProjectHash(),
2079
+ projectHash: this.getToolProjectHash(args),
2018
2080
  currentTask: this.currentTask,
2019
2081
  startTimeMs,
2020
2082
  meta: {},
@@ -2136,7 +2198,7 @@ export class MCPAdapter {
2136
2198
  // Remote telemetry: track session start (privacy-safe, opt-in only)
2137
2199
  try {
2138
2200
  const remoteTelemetry = getSharedTelemetry();
2139
- remoteTelemetry.trackSessionStart(PROJECT_ROOT);
2201
+ remoteTelemetry.trackSessionStart(this.getWorkspaceContextForArgs(request.params.arguments ?? {}).repoRoot);
2140
2202
  if (autoTokenApplied && bootstrap.tokenOptimization?.planMetrics?.savings) {
2141
2203
  remoteTelemetry.trackTokenSavings(Number(bootstrap.tokenOptimization.planMetrics.savings));
2142
2204
  }
@@ -2997,7 +3059,7 @@ export class MCPAdapter {
2997
3059
  if (!query.trim()) {
2998
3060
  return { content: [{ type: 'text', text: 'Search query is required.' }] };
2999
3061
  }
3000
- const ngramIndex = getNgramIndexInstance();
3062
+ const ngramIndex = this.getRepoNgramIndex(request.params.arguments ?? {});
3001
3063
  const { results, tokensSaved } = ngramIndex.searchWithStats(query, limit);
3002
3064
  if (results.length === 0) {
3003
3065
  return { content: [{ type: 'text', text: `No results found for "${query}".` }] };
@@ -3026,10 +3088,9 @@ export class MCPAdapter {
3026
3088
  const rawFiles = Array.isArray(request.params.arguments?.files)
3027
3089
  ? request.params.arguments.files.map(String)
3028
3090
  : null;
3029
- const filePaths = rawFiles ?? this.scanSourceFiles(PROJECT_ROOT);
3091
+ const filePaths = rawFiles ?? this.scanSourceFiles(this.getWorkspaceContextForArgs(request.params.arguments ?? {}).repoRoot);
3030
3092
  const files = filePaths.map(p => {
3031
- // Resolve relative paths to absolute using project root
3032
- const resolved = path.isAbsolute(p) ? p : path.join(PROJECT_ROOT, p);
3093
+ const resolved = this.resolveToolPath(p, request.params.arguments ?? {});
3033
3094
  try {
3034
3095
  const stat = statSync(resolved);
3035
3096
  return { path: resolved, sizeBytes: stat.size, lastModified: stat.mtimeMs };
@@ -3087,7 +3148,7 @@ export class MCPAdapter {
3087
3148
  ? request.params.arguments.files.map(String)
3088
3149
  : [];
3089
3150
  const files = rawFiles.map(p => {
3090
- const resolved = path.isAbsolute(p) ? p : path.join(PROJECT_ROOT, p);
3151
+ const resolved = this.resolveToolPath(p, request.params.arguments ?? {});
3091
3152
  try {
3092
3153
  const stat = statSync(resolved);
3093
3154
  return { path: resolved, sizeBytes: stat.size, lastModified: stat.mtimeMs };
@@ -3096,7 +3157,7 @@ export class MCPAdapter {
3096
3157
  return { path: resolved, sizeBytes: 0 };
3097
3158
  }
3098
3159
  });
3099
- const ghost = new GhostPass(process.cwd());
3160
+ const ghost = new GhostPass(this.getWorkspaceContextForArgs(request.params.arguments ?? {}).repoRoot);
3100
3161
  const report = await ghost.analyze(goal, files);
3101
3162
  this.nexusRef.storeMemory(`Ghost pass for "${goal.slice(0, 80)}": ${report.riskAreas.length} risks identified.`, 0.6, ['#ghost-pass']);
3102
3163
  nexusEventBus.emit('ghost.pass', { task: goal, risks: report.riskAreas.length, workers: report.workerAssignments.length });
@@ -3322,9 +3383,9 @@ export class MCPAdapter {
3322
3383
  const rawFiles = Array.isArray(request.params.arguments?.files)
3323
3384
  ? request.params.arguments.files.map(String)
3324
3385
  : null;
3325
- const filePaths = rawFiles ?? this.scanSourceFiles(PROJECT_ROOT);
3386
+ const filePaths = rawFiles ?? this.scanSourceFiles(this.getWorkspaceContextForArgs(request.params.arguments ?? {}).repoRoot);
3326
3387
  const files = filePaths.map(p => {
3327
- const resolved = path.isAbsolute(p) ? p : path.join(PROJECT_ROOT, p);
3388
+ const resolved = this.resolveToolPath(p, request.params.arguments ?? {});
3328
3389
  try {
3329
3390
  const stat = statSync(resolved);
3330
3391
  return { path: resolved, sizeBytes: stat.size, lastModified: stat.mtimeMs };
@@ -3395,12 +3456,12 @@ export class MCPAdapter {
3395
3456
  const formatted = SessionDNAManager.format(dna);
3396
3457
  // Trigger self-summarization at session end
3397
3458
  try {
3398
- this.getOrchestrator().persistSessionSummary(telemetry.tokensOptimized || this.getRuntime().getUsageSnapshot().tokens?.grossInputTokens || 0);
3459
+ this.getOrchestrator(request.params.arguments ?? {}).persistSessionSummary(telemetry.tokensOptimized || this.getRuntime(request.params.arguments ?? {}).getUsageSnapshot().tokens?.grossInputTokens || 0);
3399
3460
  }
3400
3461
  catch { /* non-fatal */ }
3401
3462
  try {
3402
3463
  await getSharedTelemetry().trackSessionEnd(this.telemetry.elapsedMs(), {
3403
- projectId: PROJECT_ROOT,
3464
+ projectId: this.getWorkspaceContextForArgs(request.params.arguments ?? {}).repoRoot,
3404
3465
  tokensSaved: telemetry.tokensOptimized,
3405
3466
  memoriesCreated: telemetry.memoriesStored,
3406
3467
  memoriesRecalled: telemetry.memoriesRecalled,
@@ -4110,7 +4171,7 @@ export class MCPAdapter {
4110
4171
  const targetFile = String(request.params.arguments?.targetFile ?? '');
4111
4172
  const approach = String(request.params.arguments?.approach ?? '');
4112
4173
  try {
4113
- const cycle = darwinLoop.propose(hypothesis, targetFile, approach);
4174
+ const cycle = this.getDarwinLoop(request.params.arguments ?? {}).propose(hypothesis, targetFile, approach);
4114
4175
  nexusEventBus.emit('darwin.cycle', { hypothesis: cycle.hypothesis, outcome: 'proposed' });
4115
4176
  return {
4116
4177
  content: [{
@@ -4135,7 +4196,7 @@ export class MCPAdapter {
4135
4196
  ? request.params.arguments?.learnings
4136
4197
  : [];
4137
4198
  try {
4138
- const updated = await darwinLoop.review(cycleId, action, learnings);
4199
+ const updated = await this.getDarwinLoop(request.params.arguments ?? {}).review(cycleId, action, learnings);
4139
4200
  nexusEventBus.emit('darwin.cycle', { hypothesis: updated.hypothesis, outcome: updated.outcome });
4140
4201
  return {
4141
4202
  content: [{