nexus-prime 4.4.0 → 4.5.0
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 +48 -0
- package/dist/agents/adapters/mcp.d.ts +8 -0
- package/dist/agents/adapters/mcp.d.ts.map +1 -1
- package/dist/agents/adapters/mcp.js +267 -41
- package/dist/agents/adapters/mcp.js.map +1 -1
- package/dist/cli.js +3 -0
- package/dist/cli.js.map +1 -1
- package/dist/dashboard/index.html +429 -20
- package/dist/dashboard/server.d.ts +7 -0
- package/dist/dashboard/server.d.ts.map +1 -1
- package/dist/dashboard/server.js +226 -4
- package/dist/dashboard/server.js.map +1 -1
- package/dist/engines/index.d.ts +2 -0
- package/dist/engines/index.d.ts.map +1 -1
- package/dist/engines/index.js +1 -0
- package/dist/engines/index.js.map +1 -1
- package/dist/engines/lifecycle-policy.d.ts +38 -0
- package/dist/engines/lifecycle-policy.d.ts.map +1 -0
- package/dist/engines/lifecycle-policy.js +83 -0
- package/dist/engines/lifecycle-policy.js.map +1 -0
- package/dist/engines/memory.d.ts +25 -0
- package/dist/engines/memory.d.ts.map +1 -1
- package/dist/engines/memory.js +119 -5
- package/dist/engines/memory.js.map +1 -1
- package/dist/engines/orchestrator.d.ts +30 -0
- package/dist/engines/orchestrator.d.ts.map +1 -1
- package/dist/engines/orchestrator.js +115 -8
- package/dist/engines/orchestrator.js.map +1 -1
- package/dist/engines/rag-collections.d.ts +2 -0
- package/dist/engines/rag-collections.d.ts.map +1 -1
- package/dist/engines/rag-collections.js +56 -1
- package/dist/engines/rag-collections.js.map +1 -1
- package/dist/engines/runtime-registry.d.ts +2 -0
- package/dist/engines/runtime-registry.d.ts.map +1 -1
- package/dist/engines/runtime-registry.js +18 -2
- package/dist/engines/runtime-registry.js.map +1 -1
- package/dist/engines/token-supremacy.d.ts +7 -1
- package/dist/engines/token-supremacy.d.ts.map +1 -1
- package/dist/engines/token-supremacy.js +61 -8
- package/dist/engines/token-supremacy.js.map +1 -1
- package/dist/phantom/runtime.d.ts +3 -0
- package/dist/phantom/runtime.d.ts.map +1 -1
- package/dist/phantom/runtime.js +3 -1
- package/dist/phantom/runtime.js.map +1 -1
- package/dist/postinstall-bootstrap.js +68 -6
- package/dist/postinstall-bootstrap.js.map +1 -1
- package/dist/utils/ascii-art.d.ts +24 -0
- package/dist/utils/ascii-art.d.ts.map +1 -0
- package/dist/utils/ascii-art.js +109 -0
- package/dist/utils/ascii-art.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -246,6 +246,28 @@ nexus-prime setup all
|
|
|
246
246
|
nexus-prime setup status
|
|
247
247
|
```
|
|
248
248
|
|
|
249
|
+
### GStack Workspace Coordination
|
|
250
|
+
|
|
251
|
+
[GStack](https://github.com/garrytan/gstack) is a workspace coordination and deployment tool that complements Nexus Prime for web browsing, deployment workflows, planning, and team coordination. If you have GStack installed globally at `~/gstack`, Nexus Prime will auto-detect and enable it:
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
# Check GStack configuration for this project
|
|
255
|
+
cat .gstackrc
|
|
256
|
+
|
|
257
|
+
# Available GStack skills (when enabled)
|
|
258
|
+
/browse # Web browsing & navigation (preferred over MCP Chrome)
|
|
259
|
+
/ship # Prepare & execute deployments
|
|
260
|
+
/land-and-deploy # Landing page & feature deployment
|
|
261
|
+
/canary # Canary deployment testing
|
|
262
|
+
/qa # Full QA & testing workflows
|
|
263
|
+
/review # Code review (integrates with Git)
|
|
264
|
+
/plan-eng-review # Engineering review planning
|
|
265
|
+
/retro # Sprint retrospectives
|
|
266
|
+
/document-release # Release notes & documentation
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
For full GStack integration docs, see [`GSTACK.md`](./GSTACK.md).
|
|
270
|
+
|
|
249
271
|
### Runtime contract
|
|
250
272
|
|
|
251
273
|
```txt
|
|
@@ -632,6 +654,32 @@ Inventory Snapshot: 109 skills · 64 workflows · 9 hooks · 5 automations · 7
|
|
|
632
654
|
## 📜 Release History
|
|
633
655
|
|
|
634
656
|
<details open>
|
|
657
|
+
<summary><b>v4.5.0</b> · 2026-03-27 · Neural Ascension — Auto-optimization, memory injection, and sci-fi command center</summary>
|
|
658
|
+
|
|
659
|
+
- **Auto token optimization**: Bootstrap auto-applies token planning when 5+ candidate files detected. Quality floor (0.7) ensures task-referenced and recently modified files never get skipped. Zero manual `nexus_optimize_tokens` calls needed.
|
|
660
|
+
- **Seamless memory injection**: Every MCP tool response auto-recalls top 3 relevant memories (30s rate limit, 0.4 score floor, SHA1-cached). Recursion-safe — skips memory tools.
|
|
661
|
+
- **Auto ghost-pass**: Refactoring tasks with 3+ files or 3+ phases auto-detect risk areas before execution begins.
|
|
662
|
+
- **MCP category visuals**: 5 distinct sci-fi themes (memory/orchestration/execution/intelligence/system) with per-category ANSI borders, colors, and thematic labels.
|
|
663
|
+
- **Dashboard noise reduction**: Server-side rate limiting for 5 event types (2-10s windows), noise suppression for auto/empty signals, System filter button, client-side type+summary dedup.
|
|
664
|
+
- **Cross-project memory**: New APIs for cross-project browsing and project index. Dashboard project selector, tag-based search with fuzzy toggle, cross-project memory lane.
|
|
665
|
+
- **Animated installation**: 10-frame braille spinner, compact logo for narrow terminals, progress bars, phase headers, build metadata in success message.
|
|
666
|
+
- **Lifecycle policy substrate**: Feature flags with env overrides for all new auto-behaviors. Fail-open defaults with decision metrics.
|
|
667
|
+
|
|
668
|
+
Full history: [CHANGELOG.md](./CHANGELOG.md)
|
|
669
|
+
</details>
|
|
670
|
+
|
|
671
|
+
<details>
|
|
672
|
+
<summary><b>v4.4.0</b> · 2026-03-27 · Lifecycle policy automation, cross-project memory APIs, and signal-aware dashboard UX</summary>
|
|
673
|
+
|
|
674
|
+
- **Lifecycle policy substrate**: Added policy-gated auto behaviors with fail-open decisions, feature kill switches, and decision metrics for bootstrap token planning, memory-context injection, MCP visuals, and ghost-pass automation.
|
|
675
|
+
- **Memory platform expansion**: Added `/api/memory/cross-project` and `/api/memory/projects`, shared-only governance defaults, and tag+content+fuzzy cross-project query support.
|
|
676
|
+
- **Dashboard signal quality**: Added server-side event throttles/noise suppression, explicit `mcp` + `system` taxonomy alignment, a `System` event filter chip, and dual-key dedup (`id` + `type/summary` in 2s, severity bypass).
|
|
677
|
+
- **CLI/install visual layer**: Expanded ASCII toolkit (compact logo, richer loaders, phase/sub-brand helpers), added TTY-aware install spinner, and surfaced phase/sub-brand rendering in CLI summaries/help.
|
|
678
|
+
|
|
679
|
+
Full history: [CHANGELOG.md](./CHANGELOG.md)
|
|
680
|
+
</details>
|
|
681
|
+
|
|
682
|
+
<details>
|
|
635
683
|
<summary><b>v4.3.4</b> · 2026-03-26 · Semantic retrieval hardening, truthful worker budgets, and canonical promoted assets</summary>
|
|
636
684
|
|
|
637
685
|
- **Semantic retrieval and matching**: RAG chunks now carry embeddings with semantic-first retrieval, Context Assembler relevance uses Embedder-backed scoring, and Synapse asset matching blends semantic and lexical signals instead of pure Jaccard hot paths.
|
|
@@ -16,7 +16,12 @@ export declare class MCPAdapter implements Adapter {
|
|
|
16
16
|
private telemetry;
|
|
17
17
|
private sessionDNA;
|
|
18
18
|
private runtime?;
|
|
19
|
+
private lifecyclePolicy;
|
|
20
|
+
private memoryInjectionCache;
|
|
21
|
+
private lastMemoryInjectionAt;
|
|
19
22
|
private sciFiMatrixLog;
|
|
23
|
+
private classifyToolCategory;
|
|
24
|
+
private sciFiToolHeader;
|
|
20
25
|
private box;
|
|
21
26
|
constructor();
|
|
22
27
|
private detectCallerName;
|
|
@@ -28,6 +33,9 @@ export declare class MCPAdapter implements Adapter {
|
|
|
28
33
|
private formatRemainingProtocolSteps;
|
|
29
34
|
private prependTextToResponse;
|
|
30
35
|
private decorateLifecycleResponse;
|
|
36
|
+
private extractGoalLikeText;
|
|
37
|
+
private isMemoryTool;
|
|
38
|
+
private injectMemoryContext;
|
|
31
39
|
private describeClientInstructionStatus;
|
|
32
40
|
private finalizeToolDefinitions;
|
|
33
41
|
private decorateToolDescription;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../../src/agents/adapters/mcp.ts"],"names":[],"mappings":"
|
|
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;AA0E5C,KAAK,cAAc,GAAG,YAAY,GAAG,MAAM,CAAC;AAE5C,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;AAqTF,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;IAElC,OAAO,CAAC,cAAc;IA6BtB,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,eAAe;IAqEvB,OAAO,CAAC,GAAG;;IAmBX,OAAO,CAAC,gBAAgB;IA4BxB,WAAW,CAAC,KAAK,EAAE,UAAU;IAI7B,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,cAAc;IAMtB,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;IAqB/B,OAAO,CAAC,uBAAuB;IAkC/B,cAAc,CAAC,OAAO,GAAE,cAAsC,GAAG,iBAAiB,EAAE;IAIpF,OAAO,CAAC,oBAAoB;IAkzB5B,OAAO,CAAC,iBAAiB;YA6FX,cAAc;IAk7D5B,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"}
|
|
@@ -5,6 +5,7 @@ import { statSync, readdirSync } from 'fs';
|
|
|
5
5
|
import * as path from 'path';
|
|
6
6
|
import { fileURLToPath } from 'url';
|
|
7
7
|
import { execSync } from 'child_process';
|
|
8
|
+
import { createHash } from 'crypto';
|
|
8
9
|
import { TokenSupremacyEngine, formatReadingPlan } from '../../engines/token-supremacy.js';
|
|
9
10
|
import { GhostPass, createSubAgentRuntime, summarizeExecution, } from '../../phantom/index.js';
|
|
10
11
|
import { GuardrailEngine } from '../../engines/guardrails-bridge.js';
|
|
@@ -12,12 +13,14 @@ import { SessionDNAManager } from '../../engines/session-dna.js';
|
|
|
12
13
|
import { ContextAssembler } from '../../engines/context-assembler.js';
|
|
13
14
|
import { GraphMemoryEngine } from '../../engines/graph-memory.js';
|
|
14
15
|
import { GraphTraversalEngine } from '../../engines/graph-traversal.js';
|
|
16
|
+
import { ASCII_ART } from '../../utils/ascii-art.js';
|
|
15
17
|
import { HybridRetriever } from '../../engines/hybrid-retriever.js';
|
|
16
18
|
import { nexusEventBus } from '../../engines/event-bus.js';
|
|
17
19
|
import { AttentionScorer } from '../../engines/attention-stream.js';
|
|
18
20
|
import { SkillCardRegistry } from '../../engines/skill-card.js';
|
|
19
21
|
import { DarwinLoop } from '../../engines/darwin-loop.js';
|
|
20
22
|
import { nexusNetRelay } from '../../engines/nexusnet-relay.js';
|
|
23
|
+
import { LifecyclePolicy } from '../../engines/lifecycle-policy.js';
|
|
21
24
|
import { entanglementEngine, ContinuousAttentionStream, createKVBridge, nxl, OrchestratorEngine } from '../../engines/index.js';
|
|
22
25
|
import { FederationEngine } from '../../engines/federation.js';
|
|
23
26
|
import { TokenAnalyticsEngine } from '../../engines/token-analytics.js';
|
|
@@ -30,7 +33,13 @@ const kvBridge = createKVBridge({ agents: 3 });
|
|
|
30
33
|
const orchestrator = new OrchestratorEngine();
|
|
31
34
|
const darwinLoop = new DarwinLoop(orchestrator.getMemoryEngine());
|
|
32
35
|
const federation = new FederationEngine();
|
|
33
|
-
|
|
36
|
+
// Lazy-initialized fallback runtime to avoid leaking a phantom runtime at module load
|
|
37
|
+
let _fallbackRuntime = null;
|
|
38
|
+
function getFallbackRuntime() {
|
|
39
|
+
if (!_fallbackRuntime)
|
|
40
|
+
_fallbackRuntime = createSubAgentRuntime({ repoRoot: process.cwd() });
|
|
41
|
+
return _fallbackRuntime;
|
|
42
|
+
}
|
|
34
43
|
// Lazy-initialized Graph Engine (separate DB from core memory)
|
|
35
44
|
let _graphEngine = null;
|
|
36
45
|
let _traversalEngine = null;
|
|
@@ -140,6 +149,7 @@ class SessionTelemetry {
|
|
|
140
149
|
fileReadIntentCount = 0;
|
|
141
150
|
callsSinceOrchestrate = 0;
|
|
142
151
|
fileIntentPaths = new Set();
|
|
152
|
+
tokenAutoApplied = false;
|
|
143
153
|
bootstrapped = false;
|
|
144
154
|
recordCall() {
|
|
145
155
|
this.callCount++;
|
|
@@ -163,6 +173,7 @@ class SessionTelemetry {
|
|
|
163
173
|
sessionDnaCalled: this.sessionDnaCalled,
|
|
164
174
|
fileReadIntentCount: this.fileReadIntentCount,
|
|
165
175
|
callsSinceOrchestrate: this.callsSinceOrchestrate,
|
|
176
|
+
tokenAutoApplied: this.tokenAutoApplied,
|
|
166
177
|
};
|
|
167
178
|
}
|
|
168
179
|
advancePhase(nextPhase) {
|
|
@@ -172,6 +183,7 @@ class SessionTelemetry {
|
|
|
172
183
|
if (nextPhase === 'bootstrapped' || nextPhase === 'orchestrated') {
|
|
173
184
|
this.resetFileIntentTracking();
|
|
174
185
|
this.optimizeTokensCalled = false;
|
|
186
|
+
this.tokenAutoApplied = false;
|
|
175
187
|
}
|
|
176
188
|
if (nextPhase === 'orchestrated') {
|
|
177
189
|
this.mindkitCheckCalled = false;
|
|
@@ -234,8 +246,14 @@ class SessionTelemetry {
|
|
|
234
246
|
return false;
|
|
235
247
|
if (this.lifecyclePhase === 'pre-bootstrap')
|
|
236
248
|
return false;
|
|
249
|
+
if (this.tokenAutoApplied)
|
|
250
|
+
return false;
|
|
237
251
|
return this.fileReadIntentCount >= 3 && !this.optimizeTokensCalled;
|
|
238
252
|
}
|
|
253
|
+
markTokenAutoApplied() {
|
|
254
|
+
this.tokenAutoApplied = true;
|
|
255
|
+
this.optimizeTokensCalled = true;
|
|
256
|
+
}
|
|
239
257
|
needsStoreMemory(currentToolName) {
|
|
240
258
|
if (currentToolName === 'nexus_store_memory')
|
|
241
259
|
return false;
|
|
@@ -344,6 +362,9 @@ export class MCPAdapter {
|
|
|
344
362
|
telemetry = new SessionTelemetry();
|
|
345
363
|
sessionDNA;
|
|
346
364
|
runtime;
|
|
365
|
+
lifecyclePolicy = new LifecyclePolicy();
|
|
366
|
+
memoryInjectionCache = new Map();
|
|
367
|
+
lastMemoryInjectionAt = 0;
|
|
347
368
|
sciFiMatrixLog(title, metrics, intent) {
|
|
348
369
|
const width = 76;
|
|
349
370
|
console.error(`\n\x1b[36m╔═══ [ \x1b[37m\x1b[1mNEXUS PRIME · ORCHESTRATION MATRIX\x1b[0m\x1b[36m ] ${'═'.repeat(Math.max(0, width - 48))}╗\x1b[0m`);
|
|
@@ -369,6 +390,81 @@ export class MCPAdapter {
|
|
|
369
390
|
}
|
|
370
391
|
console.error(`\x1b[36m╚${'═'.repeat(width - 2)}╝\x1b[0m\n`);
|
|
371
392
|
}
|
|
393
|
+
classifyToolCategory(toolName) {
|
|
394
|
+
if (['nexus_store_memory', 'nexus_recall_memory', 'nexus_memory_stats'].includes(toolName))
|
|
395
|
+
return 'memory';
|
|
396
|
+
if (['nexus_orchestrate', 'nexus_plan_execution', 'nexus_spawn_workers'].includes(toolName))
|
|
397
|
+
return 'orchestration';
|
|
398
|
+
if (['nexus_ghost_pass', 'nexus_mindkit_check', 'nexus_optimize_tokens'].includes(toolName))
|
|
399
|
+
return 'execution';
|
|
400
|
+
if (['nexus_session_bootstrap', 'nexus_session_dna', 'nexus_token_report'].includes(toolName))
|
|
401
|
+
return 'intelligence';
|
|
402
|
+
if (toolName === 'nexus_run_status' || toolName === 'nexus_federation_status' || toolName.startsWith('nexus_list_'))
|
|
403
|
+
return 'system';
|
|
404
|
+
return 'system';
|
|
405
|
+
}
|
|
406
|
+
sciFiToolHeader(category, toolName, goal) {
|
|
407
|
+
if (!this.lifecyclePolicy.isEnabled('mcpCategoryVisuals')) {
|
|
408
|
+
console.error(`\x1b[90m[NEXUS] ◈ ${toolName} ◈\x1b[0m`);
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
const rawPreview = goal || 'No goal payload provided.';
|
|
412
|
+
const preview = rawPreview.length > 54 ? `${rawPreview.slice(0, 53)}…` : rawPreview;
|
|
413
|
+
if (category === 'orchestration') {
|
|
414
|
+
this.sciFiMatrixLog('ORCHESTRATION MATRIX', {
|
|
415
|
+
'Category': 'orchestration',
|
|
416
|
+
'Label': 'ORCHESTRATION MATRIX',
|
|
417
|
+
'Tool': toolName,
|
|
418
|
+
'Execution': 'autonomous',
|
|
419
|
+
'Policy': 'enabled',
|
|
420
|
+
'Status': 'dispatching',
|
|
421
|
+
}, preview);
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
const themed = {
|
|
425
|
+
memory: {
|
|
426
|
+
color: '32',
|
|
427
|
+
title: '🧠 MEMORY LATTICE QUERY',
|
|
428
|
+
lines: [
|
|
429
|
+
`Glyph: ⬢ MEMORY NODE`,
|
|
430
|
+
`Tool: ${toolName}`,
|
|
431
|
+
`Intent: ${preview}`,
|
|
432
|
+
'Border: single-line lattice',
|
|
433
|
+
],
|
|
434
|
+
},
|
|
435
|
+
execution: {
|
|
436
|
+
color: '33',
|
|
437
|
+
title: '⚙ EXECUTION PIPELINE',
|
|
438
|
+
lines: [
|
|
439
|
+
`Glyph: ▶ PIPE STAGE`,
|
|
440
|
+
`Tool: ${toolName}`,
|
|
441
|
+
`Intent: ${preview}`,
|
|
442
|
+
'Border: high-visibility single line',
|
|
443
|
+
],
|
|
444
|
+
},
|
|
445
|
+
intelligence: {
|
|
446
|
+
color: '34',
|
|
447
|
+
title: '📡 INTELLIGENCE RELAY',
|
|
448
|
+
lines: [
|
|
449
|
+
`Glyph: ⟡ RELAY NODE`,
|
|
450
|
+
`Tool: ${toolName}`,
|
|
451
|
+
`Intent: ${preview}`,
|
|
452
|
+
'Border: relay channel single line',
|
|
453
|
+
],
|
|
454
|
+
},
|
|
455
|
+
system: {
|
|
456
|
+
color: '90',
|
|
457
|
+
title: '⋯ SYSTEM BUS ⋯',
|
|
458
|
+
lines: [
|
|
459
|
+
`Glyph: ◌ BUS TRACE`,
|
|
460
|
+
`Tool: ${toolName}`,
|
|
461
|
+
`Intent: ${preview}`,
|
|
462
|
+
'Border: dotted diagnostics',
|
|
463
|
+
],
|
|
464
|
+
},
|
|
465
|
+
}[category];
|
|
466
|
+
this.box(themed.title, themed.lines, themed.color);
|
|
467
|
+
}
|
|
372
468
|
box(title, content, color = '34') {
|
|
373
469
|
const width = 68;
|
|
374
470
|
console.error(`\n\x1b[${color}m┌─ ${title} ${'─'.repeat(Math.max(0, width - title.length - 4))}┐\x1b[0m`);
|
|
@@ -429,7 +525,7 @@ export class MCPAdapter {
|
|
|
429
525
|
return this.nexusRef.getRuntime();
|
|
430
526
|
}
|
|
431
527
|
if (!this.runtime) {
|
|
432
|
-
this.runtime =
|
|
528
|
+
this.runtime = getFallbackRuntime();
|
|
433
529
|
}
|
|
434
530
|
return this.runtime;
|
|
435
531
|
}
|
|
@@ -490,10 +586,88 @@ export class MCPAdapter {
|
|
|
490
586
|
}
|
|
491
587
|
if (warnings.length === 0)
|
|
492
588
|
return result;
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
589
|
+
// Make warnings highly visible: prepend as plain text AND inject as structured first content block
|
|
590
|
+
const warningBlock = {
|
|
591
|
+
type: 'text',
|
|
592
|
+
text: JSON.stringify({
|
|
593
|
+
WARNING: 'NEXUS LIFECYCLE VIOLATION',
|
|
594
|
+
issues: warnings,
|
|
595
|
+
requiredActions: warnings.map((w) => w.includes('nexus_optimize_tokens') ? 'Call nexus_optimize_tokens(goal, files) NOW before reading more files'
|
|
596
|
+
: w.includes('nexus_store_memory') ? 'Call nexus_store_memory(content, priority, tags) to persist findings'
|
|
597
|
+
: w),
|
|
598
|
+
}, null, 2),
|
|
599
|
+
};
|
|
600
|
+
return {
|
|
601
|
+
content: [
|
|
602
|
+
warningBlock,
|
|
603
|
+
...result.content,
|
|
604
|
+
],
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
extractGoalLikeText(args) {
|
|
608
|
+
const candidates = [args.goal, args.task, args.prompt, args.query, args.action, args.content]
|
|
609
|
+
.map((value) => String(value ?? '').trim())
|
|
610
|
+
.filter(Boolean);
|
|
611
|
+
return candidates[0] ?? '';
|
|
612
|
+
}
|
|
613
|
+
isMemoryTool(toolName) {
|
|
614
|
+
return toolName === 'nexus_store_memory'
|
|
615
|
+
|| toolName === 'nexus_recall_memory'
|
|
616
|
+
|| toolName === 'nexus_memory_stats'
|
|
617
|
+
|| toolName.startsWith('nexus_memory_');
|
|
618
|
+
}
|
|
619
|
+
async injectMemoryContext(toolName, args, result) {
|
|
620
|
+
const policy = this.lifecyclePolicy.evaluate('memoryInjection', {
|
|
621
|
+
toolName,
|
|
622
|
+
hasArgs: Object.keys(args ?? {}).length,
|
|
623
|
+
});
|
|
624
|
+
if (!policy.enabled || this.isMemoryTool(toolName))
|
|
625
|
+
return result;
|
|
626
|
+
const query = this.extractGoalLikeText(args);
|
|
627
|
+
if (query.length < 10)
|
|
628
|
+
return result;
|
|
629
|
+
const now = Date.now();
|
|
630
|
+
if (now - this.lastMemoryInjectionAt < 30_000)
|
|
631
|
+
return result;
|
|
632
|
+
const cacheWindowMs = Number(process.env.NEXUS_MEMORY_INJECTION_CACHE_MS ?? 30_000);
|
|
633
|
+
const minScore = Number(process.env.NEXUS_MEMORY_INJECTION_MIN_SCORE ?? 0.4);
|
|
634
|
+
const cacheKey = createHash('sha1').update(query.toLowerCase()).digest('hex').slice(0, 16);
|
|
635
|
+
const cached = this.memoryInjectionCache.get(cacheKey);
|
|
636
|
+
let matches = [];
|
|
637
|
+
if (cached && cached.expiresAt > now) {
|
|
638
|
+
matches = cached.matches;
|
|
639
|
+
}
|
|
640
|
+
else {
|
|
641
|
+
try {
|
|
642
|
+
const memory = this.getOrchestrator().getMemoryEngine();
|
|
643
|
+
const recalled = await memory.recallWithMetadata(query, 3, { minScore });
|
|
644
|
+
matches = recalled
|
|
645
|
+
.filter((entry) => Number(entry.score) >= minScore)
|
|
646
|
+
.map((entry) => ({ content: entry.content, score: entry.score }));
|
|
647
|
+
this.memoryInjectionCache.set(cacheKey, {
|
|
648
|
+
expiresAt: now + cacheWindowMs,
|
|
649
|
+
matches,
|
|
650
|
+
});
|
|
651
|
+
}
|
|
652
|
+
catch (error) {
|
|
653
|
+
console.warn('[MCP] Memory context injection skipped:', error?.message ?? error);
|
|
654
|
+
return result;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
if (matches.length === 0)
|
|
658
|
+
return result;
|
|
659
|
+
this.lastMemoryInjectionAt = now;
|
|
660
|
+
const contextBlock = {
|
|
661
|
+
type: 'text',
|
|
662
|
+
text: [
|
|
663
|
+
'[Memory Context]',
|
|
664
|
+
...matches.map((entry, index) => `${index + 1}. ${entry.content.slice(0, 220)}${entry.content.length > 220 ? '…' : ''} (score ${entry.score.toFixed(2)})`),
|
|
665
|
+
].join('\n'),
|
|
666
|
+
};
|
|
667
|
+
return {
|
|
668
|
+
...result,
|
|
669
|
+
content: [...result.content, contextBlock],
|
|
670
|
+
};
|
|
497
671
|
}
|
|
498
672
|
describeClientInstructionStatus(profile) {
|
|
499
673
|
return profile === 'autonomous'
|
|
@@ -1106,7 +1280,7 @@ export class MCPAdapter {
|
|
|
1106
1280
|
},
|
|
1107
1281
|
{
|
|
1108
1282
|
name: 'nexus_rag_ingest_collection',
|
|
1109
|
-
description: 'Expert surface: ingest local files, URLs, or raw text into a RAG collection.',
|
|
1283
|
+
description: 'Expert surface: ingest local files, folders, URLs, or raw text into a RAG collection. Use folderPath to ingest an entire directory recursively.',
|
|
1110
1284
|
inputSchema: {
|
|
1111
1285
|
type: 'object',
|
|
1112
1286
|
properties: {
|
|
@@ -1116,14 +1290,16 @@ export class MCPAdapter {
|
|
|
1116
1290
|
items: {
|
|
1117
1291
|
type: 'object',
|
|
1118
1292
|
properties: {
|
|
1119
|
-
filePath: { type: 'string' },
|
|
1293
|
+
filePath: { type: 'string', description: 'Single file path' },
|
|
1294
|
+
folderPath: { type: 'string', description: 'Directory path to recursively ingest all supported files' },
|
|
1295
|
+
folderGlob: { type: 'string', description: 'Optional extension filter for folder ingestion (e.g. "*.ts")' },
|
|
1120
1296
|
url: { type: 'string' },
|
|
1121
1297
|
text: { type: 'string' },
|
|
1122
1298
|
label: { type: 'string' },
|
|
1123
1299
|
tags: { type: 'array', items: { type: 'string' } },
|
|
1124
1300
|
},
|
|
1125
1301
|
},
|
|
1126
|
-
description: 'Collection sources',
|
|
1302
|
+
description: 'Collection sources (supports file, folder, url, or text)',
|
|
1127
1303
|
},
|
|
1128
1304
|
},
|
|
1129
1305
|
required: ['collectionId', 'inputs'],
|
|
@@ -1394,6 +1570,25 @@ export class MCPAdapter {
|
|
|
1394
1570
|
this.telemetry.bootstrapped = true;
|
|
1395
1571
|
}
|
|
1396
1572
|
const args = request.params?.arguments ?? {};
|
|
1573
|
+
// Gate: block non-bootstrap tools BEFORE executing them to avoid wasted work and side effects
|
|
1574
|
+
if (!this.telemetry.bootstrapped &&
|
|
1575
|
+
toolName !== 'nexus_session_bootstrap' &&
|
|
1576
|
+
toolName !== 'nexus_memory_stats' &&
|
|
1577
|
+
!toolName.startsWith('nexus_list_') &&
|
|
1578
|
+
toolName !== 'nexus_federation_status' &&
|
|
1579
|
+
toolName !== 'nexus_status') {
|
|
1580
|
+
return {
|
|
1581
|
+
content: [{
|
|
1582
|
+
type: 'text',
|
|
1583
|
+
text: JSON.stringify({
|
|
1584
|
+
status: 'blocked',
|
|
1585
|
+
reason: 'nexus_session_bootstrap has not been called yet',
|
|
1586
|
+
action: 'Call nexus_session_bootstrap(goal="<your task>") first, then retry this tool',
|
|
1587
|
+
hint: 'Bootstrap recovers memory and context — skipping it means working blind'
|
|
1588
|
+
}, null, 2)
|
|
1589
|
+
}]
|
|
1590
|
+
};
|
|
1591
|
+
}
|
|
1397
1592
|
const callId = `mcp_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
1398
1593
|
const startTimeMs = Date.now();
|
|
1399
1594
|
nexusEventBus.emit('mcp.call.start', {
|
|
@@ -1427,25 +1622,8 @@ export class MCPAdapter {
|
|
|
1427
1622
|
throw error;
|
|
1428
1623
|
}
|
|
1429
1624
|
this.telemetry.observeSuccessfulToolCall(toolName, args);
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
toolName !== 'nexus_memory_stats' &&
|
|
1433
|
-
!toolName.startsWith('nexus_list_') &&
|
|
1434
|
-
toolName !== 'nexus_federation_status' &&
|
|
1435
|
-
toolName !== 'nexus_status') {
|
|
1436
|
-
return {
|
|
1437
|
-
content: [{
|
|
1438
|
-
type: 'text',
|
|
1439
|
-
text: JSON.stringify({
|
|
1440
|
-
status: 'blocked',
|
|
1441
|
-
reason: 'nexus_session_bootstrap has not been called yet',
|
|
1442
|
-
action: 'Call nexus_session_bootstrap(goal="<your task>") first, then retry this tool',
|
|
1443
|
-
hint: 'Bootstrap recovers memory and context — skipping it means working blind'
|
|
1444
|
-
}, null, 2)
|
|
1445
|
-
}]
|
|
1446
|
-
};
|
|
1447
|
-
}
|
|
1448
|
-
return this.decorateLifecycleResponse(toolName, result);
|
|
1625
|
+
const decorated = this.decorateLifecycleResponse(toolName, result);
|
|
1626
|
+
return this.injectMemoryContext(toolName, args, decorated);
|
|
1449
1627
|
});
|
|
1450
1628
|
}
|
|
1451
1629
|
async handleToolCall(request) {
|
|
@@ -1462,20 +1640,19 @@ export class MCPAdapter {
|
|
|
1462
1640
|
tokenOptimizationApplied: toolName === 'nexus_optimize_tokens',
|
|
1463
1641
|
toolProfile: this.getToolProfile(),
|
|
1464
1642
|
});
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1643
|
+
const toolCategory = this.classifyToolCategory(toolName);
|
|
1644
|
+
const showRichHeader = goal
|
|
1645
|
+
&& goal.length > 20
|
|
1646
|
+
&& !['nexus_execute_nxl', 'nexus_session_bootstrap', 'nexus_plan_execution', 'nexus_memory_stats'].includes(request.params.name);
|
|
1647
|
+
if (showRichHeader) {
|
|
1648
|
+
const frameCount = Math.max(4, Math.min(8, Number(ASCII_ART.sciFiLoaderFrames?.length ?? 8)));
|
|
1649
|
+
for (let i = 0; i < frameCount; i++) {
|
|
1650
|
+
console.error(`\x1b[35m${ASCII_ART.sciFiLoader(i)}\x1b[0m`);
|
|
1651
|
+
}
|
|
1652
|
+
this.sciFiToolHeader(toolCategory, toolName, goal);
|
|
1475
1653
|
}
|
|
1476
1654
|
else if (toolName) {
|
|
1477
|
-
|
|
1478
|
-
console.error(`\x1b[90m[NEXUS] Executing Tool: ${toolName}\x1b[0m`);
|
|
1655
|
+
console.error(`\x1b[90m[NEXUS:${toolCategory.toUpperCase()}] ◈ ${toolName} ◈\x1b[0m`);
|
|
1479
1656
|
}
|
|
1480
1657
|
if (goal && goal.length > 50 && !['nexus_execute_nxl', 'nexus_session_bootstrap', 'nexus_plan_execution'].includes(request.params.name)) {
|
|
1481
1658
|
const swarm = await this.getOrchestrator().induce(goal);
|
|
@@ -1496,6 +1673,25 @@ export class MCPAdapter {
|
|
|
1496
1673
|
? request.params.arguments.files.map(String)
|
|
1497
1674
|
: undefined;
|
|
1498
1675
|
const bootstrap = await this.getOrchestrator().bootstrapSession(bootstrapGoal, { files });
|
|
1676
|
+
const autoTokenApplied = Boolean(bootstrap.tokenOptimization?.autoApplied);
|
|
1677
|
+
if (autoTokenApplied) {
|
|
1678
|
+
this.telemetry.markTokenAutoApplied();
|
|
1679
|
+
if (bootstrap.tokenOptimization?.planMetrics?.savings) {
|
|
1680
|
+
this.telemetry.recordTokens(Number(bootstrap.tokenOptimization.planMetrics.savings));
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
this.getRuntime().recordClientToolCall('nexus_session_bootstrap', {
|
|
1684
|
+
bootstrapCalled: true,
|
|
1685
|
+
plannerCalled: true,
|
|
1686
|
+
tokenOptimizationApplied: autoTokenApplied,
|
|
1687
|
+
tokenAutoApplied: autoTokenApplied,
|
|
1688
|
+
toolProfile: this.getToolProfile(),
|
|
1689
|
+
});
|
|
1690
|
+
// Auto-generate a project-scoped memory on bootstrap so dashboard always has something to show
|
|
1691
|
+
try {
|
|
1692
|
+
this.nexusRef.storeMemory(`Session bootstrap: ${bootstrapGoal || 'interactive session'}. Memory: prefrontal=${bootstrap.memoryStats?.prefrontal ?? 0}, hippocampus=${bootstrap.memoryStats?.hippocampus ?? 0}, cortex=${bootstrap.memoryStats?.cortex ?? 0}.`, 0.5, ['#session-start', '#auto', '#project']);
|
|
1693
|
+
}
|
|
1694
|
+
catch { /* best-effort */ }
|
|
1499
1695
|
const payload = {
|
|
1500
1696
|
client: bootstrap.client,
|
|
1501
1697
|
memoryRecall: bootstrap.memoryRecall,
|
|
@@ -1526,15 +1722,21 @@ export class MCPAdapter {
|
|
|
1526
1722
|
`Memory stats: prefrontal ${bootstrap.memoryStats?.prefrontal ?? 0} · hippocampus ${bootstrap.memoryStats?.hippocampus ?? 0} · cortex ${bootstrap.memoryStats?.cortex ?? 0}`,
|
|
1527
1723
|
`Recommended next step: ${bootstrap.recommendedNextStep || 'nexus_orchestrate'}`,
|
|
1528
1724
|
`Execution mode: ${bootstrap.recommendedExecutionMode || 'autonomous'}`,
|
|
1529
|
-
`Token optimization: ${bootstrap.tokenOptimization?.required ? 'required before broad reading' : 'not required yet'}`,
|
|
1725
|
+
`Token optimization: ${bootstrap.tokenOptimization?.autoApplied ? 'auto-applied during bootstrap' : (bootstrap.tokenOptimization?.required ? 'required before broad reading' : 'not required yet')}`,
|
|
1530
1726
|
`Catalog health: ${bootstrap.catalogHealth?.overall || 'unknown'} · selected ${bootstrap.artifactSelectionAudit?.selected?.length || 0}`,
|
|
1531
1727
|
`Shortlist: ${bootstrap.shortlist?.skills?.slice(0, 3).join(', ') || 'none'} (skills), ${bootstrap.shortlist?.specialists?.slice(0, 3).join(', ') || 'none'} (specialists)`,
|
|
1532
1728
|
`Knowledge fabric: ${bootstrap.sourceMixRecommendation?.dominantSource || bootstrap.knowledgeFabric?.dominantSource || 'awaiting source mix'}`,
|
|
1533
1729
|
`RAG: ${bootstrap.ragCandidateStatus?.attachedCollections || 0} attached · ${bootstrap.ragCandidateStatus?.retrievedChunks || 0} retrieved`,
|
|
1534
1730
|
`Task graph: ${bootstrap.taskGraphPreview?.phases?.length || 0} phases · ${bootstrap.taskGraphPreview?.independentBranches || 0} branches`,
|
|
1535
1731
|
`Worker plan: ${bootstrap.workerPlanPreview?.totalWorkers || 0} lanes planned`,
|
|
1732
|
+
bootstrap.autoGhostPass?.applied
|
|
1733
|
+
? `Auto ghost-pass: ${bootstrap.autoGhostPass.riskAreas.length} risk area(s) · ${bootstrap.autoGhostPass.workerApproaches} approach(es)`
|
|
1734
|
+
: `Auto ghost-pass: skipped`,
|
|
1536
1735
|
`Bootstrap status: ${bootstrap.clientBootstrapStatus?.clients?.length || 0} client manifests tracked`,
|
|
1537
1736
|
]),
|
|
1737
|
+
bootstrap.tokenOptimization?.autoApplied && bootstrap.tokenOptimization?.plan
|
|
1738
|
+
? `Auto token plan\n\`\`\`txt\n${bootstrap.tokenOptimization.plan}\n\`\`\``
|
|
1739
|
+
: '',
|
|
1538
1740
|
formatJsonDetails('Structured details', payload),
|
|
1539
1741
|
this.formatProtocolChecklist(),
|
|
1540
1742
|
].join('\n\n'),
|
|
@@ -1583,6 +1785,28 @@ export class MCPAdapter {
|
|
|
1583
1785
|
optimizationProfile,
|
|
1584
1786
|
});
|
|
1585
1787
|
const verifiedWorkers = execution.workerResults.filter((worker) => worker.verified).length;
|
|
1788
|
+
const tokenPlan = execution?.knowledgeFabric?.repo?.readingPlan;
|
|
1789
|
+
const canAutoApplyTokenPlan = Boolean(tokenPlan
|
|
1790
|
+
&& Number(tokenPlan.savings || 0) > 5000
|
|
1791
|
+
&& !this.getRuntime().getUsageSnapshot()?.tokenOptimizationApplied);
|
|
1792
|
+
let autoTokenApplyNote = '';
|
|
1793
|
+
if (canAutoApplyTokenPlan) {
|
|
1794
|
+
const savings = Number(tokenPlan.savings || 0);
|
|
1795
|
+
this.telemetry.recordTokens(savings);
|
|
1796
|
+
this.getRuntime().recordClientToolCall('nexus_orchestrate', {
|
|
1797
|
+
orchestrateCalled: true,
|
|
1798
|
+
plannerCalled: true,
|
|
1799
|
+
tokenOptimizationApplied: true,
|
|
1800
|
+
toolProfile: this.getToolProfile(),
|
|
1801
|
+
});
|
|
1802
|
+
autoTokenApplyNote = `Auto-applied token optimization (${savings.toLocaleString()} estimated token savings).`;
|
|
1803
|
+
}
|
|
1804
|
+
// Auto-store run summary memory so dashboard and future sessions can see what happened
|
|
1805
|
+
try {
|
|
1806
|
+
const modifiedFiles = execution.workerResults.flatMap((w) => w.modifiedFiles);
|
|
1807
|
+
this.nexusRef.storeMemory(`Run ${execution.runId} ${execution.state}: ${summarizeExecution(execution)}. Workers: ${verifiedWorkers}/${execution.workerResults.length} verified. Files modified: ${modifiedFiles.slice(0, 5).join(', ') || 'none'}.`, 0.7, ['#run-summary', '#auto', '#project']);
|
|
1808
|
+
}
|
|
1809
|
+
catch { /* best-effort */ }
|
|
1586
1810
|
execution.activeSkills.forEach((skill) => this.sessionDNA.recordSkill(skill.name));
|
|
1587
1811
|
execution.workerResults.forEach((result) => {
|
|
1588
1812
|
result.modifiedFiles.forEach((file) => this.sessionDNA.recordFileModified(file));
|
|
@@ -1618,6 +1842,7 @@ export class MCPAdapter {
|
|
|
1618
1842
|
tokens: execution.tokenTelemetry,
|
|
1619
1843
|
verifiedWorkers,
|
|
1620
1844
|
continuationChildren: execution.continuationChildren,
|
|
1845
|
+
autoTokenApplyNote,
|
|
1621
1846
|
};
|
|
1622
1847
|
return {
|
|
1623
1848
|
content: [{
|
|
@@ -1635,6 +1860,7 @@ export class MCPAdapter {
|
|
|
1635
1860
|
`Verification: ${verifiedWorkers}/${execution.workerResults.length} worker(s) verified`,
|
|
1636
1861
|
`Worktrees: ${runtimeUsage.worktreeHealth?.overall || 'unknown'} · repaired ${runtimeUsage.worktreeHealth?.repairedEntries || 0} · broken ${runtimeUsage.worktreeHealth?.brokenEntries || 0}`,
|
|
1637
1862
|
`Tokens: saved ${Number(execution.tokenTelemetry?.savedTokens || 0).toLocaleString()} · compression ${Number(execution.tokenTelemetry?.compressionPct || 0)}% · dominant ${runtimeUsage.sourceAwareTokenBudget?.dominantSource || execution.knowledgeFabric?.sourceMix?.dominantSource || 'repo'}`,
|
|
1863
|
+
autoTokenApplyNote || null,
|
|
1638
1864
|
`RAG: ${(runtimeUsage.ragUsageSummary?.attachedCollections || execution.knowledgeFabric?.rag.attachedCollections.length || 0)} attached · ${(runtimeUsage.ragUsageSummary?.retrievedChunks || execution.knowledgeFabric?.rag.hits.length || 0)} retrieved`,
|
|
1639
1865
|
`Memory scopes: ${Object.entries(runtimeUsage.memoryScopeUsage?.byScope || execution.memoryScopeUsage?.byScope || {}).map(([scope, count]) => `${scope}:${count}`).join(' · ') || 'awaiting shared/session reads'}`,
|
|
1640
1866
|
]),
|