nexus-prime 4.6.1 → 4.7.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 (62) hide show
  1. package/README.md +35 -28
  2. package/dist/agents/adapters/mcp.d.ts +3 -0
  3. package/dist/agents/adapters/mcp.d.ts.map +1 -1
  4. package/dist/agents/adapters/mcp.js +136 -43
  5. package/dist/agents/adapters/mcp.js.map +1 -1
  6. package/dist/cli.js +26 -13
  7. package/dist/cli.js.map +1 -1
  8. package/dist/dashboard/index.html +65 -0
  9. package/dist/dashboard/server.d.ts.map +1 -1
  10. package/dist/dashboard/server.js +21 -27
  11. package/dist/dashboard/server.js.map +1 -1
  12. package/dist/engines/client-bootstrap.d.ts +4 -0
  13. package/dist/engines/client-bootstrap.d.ts.map +1 -1
  14. package/dist/engines/client-bootstrap.js +121 -2
  15. package/dist/engines/client-bootstrap.js.map +1 -1
  16. package/dist/engines/compaction-sentinel.js +1 -1
  17. package/dist/engines/compaction-sentinel.js.map +1 -1
  18. package/dist/engines/darwin-loop.d.ts +8 -1
  19. package/dist/engines/darwin-loop.d.ts.map +1 -1
  20. package/dist/engines/darwin-loop.js +57 -3
  21. package/dist/engines/darwin-loop.js.map +1 -1
  22. package/dist/engines/event-bus.d.ts.map +1 -1
  23. package/dist/engines/event-bus.js +2 -2
  24. package/dist/engines/event-bus.js.map +1 -1
  25. package/dist/engines/feature-registry.js +1 -1
  26. package/dist/engines/feature-registry.js.map +1 -1
  27. package/dist/engines/github-bridge.d.ts +45 -0
  28. package/dist/engines/github-bridge.d.ts.map +1 -0
  29. package/dist/engines/github-bridge.js +244 -0
  30. package/dist/engines/github-bridge.js.map +1 -0
  31. package/dist/engines/memory-background.js +2 -2
  32. package/dist/engines/memory-background.js.map +1 -1
  33. package/dist/engines/memory.d.ts +2 -0
  34. package/dist/engines/memory.d.ts.map +1 -1
  35. package/dist/engines/memory.js +38 -3
  36. package/dist/engines/memory.js.map +1 -1
  37. package/dist/engines/middleware-pipeline.d.ts +40 -0
  38. package/dist/engines/middleware-pipeline.d.ts.map +1 -0
  39. package/dist/engines/middleware-pipeline.js +122 -0
  40. package/dist/engines/middleware-pipeline.js.map +1 -0
  41. package/dist/engines/ngram-index.js +1 -1
  42. package/dist/engines/ngram-index.js.map +1 -1
  43. package/dist/engines/orchestrator.d.ts +4 -0
  44. package/dist/engines/orchestrator.d.ts.map +1 -1
  45. package/dist/engines/orchestrator.js +22 -1
  46. package/dist/engines/orchestrator.js.map +1 -1
  47. package/dist/engines/pod-network.d.ts.map +1 -1
  48. package/dist/engines/pod-network.js +1 -1
  49. package/dist/engines/pod-network.js.map +1 -1
  50. package/dist/engines/skill-learner.d.ts +3 -1
  51. package/dist/engines/skill-learner.d.ts.map +1 -1
  52. package/dist/engines/skill-learner.js +22 -3
  53. package/dist/engines/skill-learner.js.map +1 -1
  54. package/dist/engines/telemetry-remote.d.ts +53 -12
  55. package/dist/engines/telemetry-remote.d.ts.map +1 -1
  56. package/dist/engines/telemetry-remote.js +355 -74
  57. package/dist/engines/telemetry-remote.js.map +1 -1
  58. package/dist/engines/token-supremacy.d.ts +4 -0
  59. package/dist/engines/token-supremacy.d.ts.map +1 -1
  60. package/dist/engines/token-supremacy.js +36 -6
  61. package/dist/engines/token-supremacy.js.map +1 -1
  62. package/package.json +2 -2
package/README.md CHANGED
@@ -8,10 +8,6 @@
8
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-00d4ff?style=for-the-badge)](LICENSE)
9
9
  [![Build Status](https://img.shields.io/badge/build-passing-success?style=for-the-badge)](https://github.com/sir-ad/nexus-prime/actions)
10
10
  [![Node.js](https://img.shields.io/badge/node-%3E%3D20.0.0-339933?style=for-the-badge&logo=node.js)](https://nodejs.org)
11
- <!-- traffic-badges:start -->
12
- [![Views](https://img.shields.io/endpoint?style=for-the-badge&logo=github&url=https%3A%2F%2Fgist.githubusercontent.com%2Fsir-ad%2Fbbf9ebc77ccb2097ccf760bec3825ab7%2Fraw%2Fviews.json)](https://github.com/sir-ad/nexus-prime)
13
- [![Clones](https://img.shields.io/endpoint?style=for-the-badge&logo=github&url=https%3A%2F%2Fgist.githubusercontent.com%2Fsir-ad%2Fbbf9ebc77ccb2097ccf760bec3825ab7%2Fraw%2Fclones.json)](https://github.com/sir-ad/nexus-prime)
14
- <!-- traffic-badges:end -->
15
11
 
16
12
  [![GitHub Stars](https://img.shields.io/github/stars/sir-ad/nexus-prime?style=for-the-badge&logo=github&color=gold)](https://github.com/sir-ad/nexus-prime/stargazers)
17
13
  [![GitHub Forks](https://img.shields.io/github/forks/sir-ad/nexus-prime?style=for-the-badge&logo=github&color=silver)](https://github.com/sir-ad/nexus-prime/network/members)
@@ -246,28 +242,6 @@ nexus-prime setup all
246
242
  nexus-prime setup status
247
243
  ```
248
244
 
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
-
271
245
  ### Runtime contract
272
246
 
273
247
  ```txt
@@ -347,7 +321,7 @@ Client-native installation and bootstrap surfaces managed by Nexus Prime.
347
321
 
348
322
  | Name | Surface | Purpose | Notes |
349
323
  | --- | --- | --- | --- |
350
- | Codex | bootstrap target | Writes a managed Nexus Prime block into repo-local AGENTS.md. | Workspace-scoped bootstrap. |
324
+ | Codex | bootstrap target | Writes native MCP registration into `~/.codex/config.toml` and keeps the repo-local `AGENTS.md` block as supplementary context. | Home + workspace bootstrap. |
351
325
  | Cursor | bootstrap target | Installs MCP config plus project-local .cursor/rules/nexus-prime.mdc. | Home + workspace surfaces. |
352
326
  | Claude Code | bootstrap target | Installs MCP config plus generated markdown bootstrap note. | Project note under .agent/client-bootstrap. |
353
327
  | Opencode | bootstrap target | Installs config plus generated markdown bootstrap note. | Project note under .agent/client-bootstrap. |
@@ -654,6 +628,39 @@ Inventory Snapshot: 109 skills · 64 workflows · 9 hooks · 5 automations · 7
654
628
  ## 📜 Release History
655
629
 
656
630
  <details open>
631
+ <summary><b>v4.7.2</b> · 2026-03-31 · Runtime Efficiency — CPU optimization, middleware hardening, and skill sharing</summary>
632
+
633
+ - **~80% idle CPU reduction**: Polling intervals across 6 subsystems reduced from aggressive (2-60s) to relaxed (30-300s). Memory maintenance, event bus, and pod network no longer burn cycles when idle.
634
+ - **Built-in middleware classes**: TokenBudget, Telemetry, Memory, Guardrails, and Cost middleware ship pre-registered via `createDefaultPipeline()`.
635
+ - **Gist-based skill sharing**: Skill learner auto-shares high-confidence patterns as GitHub gists through the zero-config bridge.
636
+ - **Branding cleanup**: Dev instructions and docs now reference nexus-prime directly.
637
+
638
+ Full notes: [releases/v4.7.2.md](./releases/v4.7.2.md) · Full history: [CHANGELOG.md](./CHANGELOG.md)
639
+ </details>
640
+
641
+ <details>
642
+ <summary><b>v4.7.1</b> · 2026-03-31 · Operator Intelligence release rearm — fresh publish trigger for npm</summary>
643
+
644
+ - **Fresh GitHub release trigger**: Cut a patch release on top of the already-green `v4.7.0` tree so `CI & Publish` receives a new `release: published` event and can execute the npm publish job.
645
+ - **No product drift**: This does not change the `Operator Intelligence` surface. It reissues the release corridor so installers get the same shipped hardening through a publishable tag.
646
+ - **Release docs updated**: README, changelog, website release history, and standalone release notes now point at the new patch version.
647
+
648
+ Full notes: [releases/v4.7.1.md](./releases/v4.7.1.md) · Full history: [CHANGELOG.md](./CHANGELOG.md)
649
+ </details>
650
+
651
+ <details>
652
+ <summary><b>v4.7.0</b> · 2026-03-30 · Operator Intelligence — PR-first autonomy, pseudonymous telemetry, and cleaner runtime seams</summary>
653
+
654
+ - **PR-first self-evolution**: Darwin cycles now track autonomy events, attempt GitHub PR promotion through an explicit bridge when auth exists, and persist a ready local artifact when promotion is blocked.
655
+ - **Pseudonymous investor telemetry**: Opt-in Supabase telemetry now tracks installs, sessions, savings, memory activity, and autonomy outcomes without sending code, prompts, file paths, repo names, or secrets.
656
+ - **Cleaner control-plane seams**: MCP `CallTool` now runs through a middleware pipeline for token, telemetry, memory, guardrail, and cost coordination, while `nexus_store_memory` keeps high-priority memories local by default instead of silently relaying them.
657
+ - **Project memory continuity**: Memory writes now stamp stable project tags at write time, and bootstrap surfaces both prior session summaries and prior project memories before broad reading begins.
658
+ - **Operator dashboard expansion**: The main banner and token telemetry area now surface remote installations, active installs, and creator-facing aggregate telemetry when Supabase creator keys are configured.
659
+
660
+ Full notes: [releases/v4.7.0.md](./releases/v4.7.0.md) · Full history: [CHANGELOG.md](./CHANGELOG.md)
661
+ </details>
662
+
663
+ <details>
657
664
  <summary><b>v4.6.1</b> · 2026-03-29 · Release corridor stabilization — audited publish path and npm release recovery</summary>
658
665
 
659
666
  - **Publish path repaired**: Patched the vulnerable `path-to-regexp` dependency edges through targeted overrides so `CI & Publish` can clear `npm run audit:prod` and proceed to npm publication.
@@ -669,7 +676,7 @@ Full notes: [releases/v4.6.1.md](./releases/v4.6.1.md) · Full history: [CHANGEL
669
676
  - **Always-on token optimization**: Bootstrap now auto-applies token optimization whenever candidate files are available, and bootstrap/orchestrate responses surface token and USD savings directly instead of hiding the win in diagnostics.
670
677
  - **Project-scoped session summaries**: Session close and `nexus_session_dna` now persist reusable project summaries, and the next bootstrap surfaces whether prior context was recovered before any broad file reading begins.
671
678
  - **Dynamic context discovery**: MCP `ListTools` now keeps core lifecycle tools expanded while summarizing non-core tools by default, with `nexus_describe_tool` available for on-demand full contracts.
672
- - **Native search and skill bridge**: Added sparse n-gram backed `nexus_search` plus Nexus-native bridging for installed gstack skills so external workflows appear inside the normal tool surface.
679
+ - **Native search**: Added sparse n-gram backed `nexus_search` for fast codebase retrieval with token-savings tracking on the MCP surface.
673
680
  - **Opt-in telemetry and dashboard signals**: Remote telemetry remains disabled until consent, clears queued events when turned off, and the dashboard now shows savings, search activity, and telemetry status in the main operator banner.
674
681
 
675
682
  Full notes: [releases/v4.6.0.md](./releases/v4.6.0.md) · Full history: [CHANGELOG.md](./CHANGELOG.md)
@@ -20,6 +20,7 @@ export declare class MCPAdapter implements Adapter {
20
20
  private memoryInjectionCache;
21
21
  private lastMemoryInjectionAt;
22
22
  private currentTask;
23
+ private middlewarePipeline;
23
24
  private sciFiMatrixLog;
24
25
  private classifyToolCategory;
25
26
  private sciFiToolHeader;
@@ -30,6 +31,8 @@ export declare class MCPAdapter implements Adapter {
30
31
  private getRuntime;
31
32
  private getOrchestrator;
32
33
  private getToolProfile;
34
+ private getProjectHash;
35
+ private registerBuiltInMiddleware;
33
36
  private formatProtocolChecklist;
34
37
  private formatRemainingProtocolSteps;
35
38
  private prependTextToResponse;
@@ -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;AAqF5C,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;AAuTF,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;IAEzB,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;IA0B/B,OAAO,CAAC,2BAA2B;IAqBnC,OAAO,CAAC,uBAAuB;IAkC/B,cAAc,CAAC,OAAO,GAAE,cAAsC,GAAG,iBAAiB,EAAE;IAIpF,OAAO,CAAC,oBAAoB;IA80B5B,OAAO,CAAC,iBAAiB;YA6FX,cAAc;IAwhE5B,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;AAsF5C,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;AA2TF,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;IAS5B,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;IA80B5B,OAAO,CAAC,iBAAiB;YAyGX,cAAc;IAugE5B,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"}
@@ -28,6 +28,7 @@ import { getSharedNgramIndex } from '../../engines/ngram-index.js';
28
28
  import { getSharedTelemetry } from '../../engines/telemetry-remote.js';
29
29
  import { getGstackBridge } from '../../engines/gstack-bridge.js';
30
30
  import { getSharedContextDiscovery } from '../../engines/context-discovery.js';
31
+ import { MiddlewarePipeline } from '../../engines/middleware-pipeline.js';
31
32
  import { synapseToolDefinitions, handleSynapseToolCall } from '../../synapse/index.js';
32
33
  import { architectsToolDefinitions, handleArchitectsToolCall } from '../../architects/index.js';
33
34
  const tokenEngine = new TokenSupremacyEngine();
@@ -189,6 +190,9 @@ class SessionTelemetry {
189
190
  tokenAutoApplied: this.tokenAutoApplied,
190
191
  };
191
192
  }
193
+ elapsedMs() {
194
+ return Date.now() - this.startTime;
195
+ }
192
196
  advancePhase(nextPhase) {
193
197
  if (this.lifecyclePhase === nextPhase)
194
198
  return;
@@ -379,6 +383,7 @@ export class MCPAdapter {
379
383
  memoryInjectionCache = new Map();
380
384
  lastMemoryInjectionAt = 0;
381
385
  currentTask = '';
386
+ middlewarePipeline;
382
387
  sciFiMatrixLog(title, metrics, intent) {
383
388
  const width = 76;
384
389
  console.error(`\n\x1b[36m╔═══ [ \x1b[37m\x1b[1mNEXUS PRIME · ORCHESTRATION MATRIX\x1b[0m\x1b[36m ] ${'═'.repeat(Math.max(0, width - 48))}╗\x1b[0m`);
@@ -491,6 +496,8 @@ export class MCPAdapter {
491
496
  this.name = this.detectCallerName();
492
497
  this.server = new Server({ name: 'nexus-prime-mcp', version: '0.4.0' }, { capabilities: { tools: {} } });
493
498
  this.sessionDNA = new SessionDNAManager(crypto.randomUUID?.() ?? `session-${Date.now()}`);
499
+ this.middlewarePipeline = new MiddlewarePipeline();
500
+ this.registerBuiltInMiddleware();
494
501
  this.setupToolHandlers();
495
502
  }
496
503
  detectCallerName() {
@@ -554,6 +561,97 @@ export class MCPAdapter {
554
561
  ? 'full'
555
562
  : 'autonomous';
556
563
  }
564
+ getProjectHash() {
565
+ return createHash('sha1').update(path.resolve(PROJECT_ROOT)).digest('hex').slice(0, 12);
566
+ }
567
+ registerBuiltInMiddleware() {
568
+ this.middlewarePipeline.register({
569
+ name: 'token-budget',
570
+ priority: 10,
571
+ before: (ctx) => {
572
+ ctx.meta.tokenRelevant = ctx.toolName === 'nexus_optimize_tokens'
573
+ || Array.isArray(ctx.args.files)
574
+ || typeof ctx.args.goal === 'string'
575
+ || typeof ctx.args.prompt === 'string';
576
+ },
577
+ });
578
+ this.middlewarePipeline.register({
579
+ name: 'telemetry',
580
+ priority: 20,
581
+ after: async (ctx, result) => {
582
+ const remote = getSharedTelemetry();
583
+ remote.trackFeatureUsage(ctx.toolName, {
584
+ success: !ctx.meta.shortCircuitedBy,
585
+ resultBytes: Buffer.byteLength(JSON.stringify(result), 'utf8'),
586
+ });
587
+ if (typeof ctx.meta.tokenSavings === 'number' && Number(ctx.meta.tokenSavings) > 0) {
588
+ remote.trackTokenSavings(Number(ctx.meta.tokenSavings), { projectHash: ctx.projectHash });
589
+ }
590
+ if (ctx.toolName === 'nexus_store_memory') {
591
+ remote.trackMemoryCreated(String(ctx.meta.memoryScope ?? 'project'), {
592
+ projectHash: ctx.projectHash,
593
+ priority: Number(ctx.args.priority ?? 0),
594
+ });
595
+ }
596
+ if (ctx.toolName === 'nexus_recall_memory') {
597
+ remote.trackMemoryRecalled(Number(ctx.meta.memoryRecallCount ?? 0), {
598
+ projectHash: ctx.projectHash,
599
+ });
600
+ }
601
+ },
602
+ onError: async (ctx) => {
603
+ getSharedTelemetry().trackFeatureUsage(ctx.toolName, { success: false });
604
+ },
605
+ });
606
+ this.middlewarePipeline.register({
607
+ name: 'memory',
608
+ priority: 30,
609
+ before: (ctx) => {
610
+ if (ctx.toolName !== 'nexus_store_memory')
611
+ return;
612
+ const tags = Array.isArray(ctx.args.tags) ? ctx.args.tags.map(String) : [];
613
+ if (!tags.includes('#project'))
614
+ tags.push('#project');
615
+ if (ctx.projectHash && !tags.some((tag) => tag.startsWith('#project:'))) {
616
+ tags.push(`#project:${ctx.projectHash}`);
617
+ }
618
+ ctx.args.tags = [...new Set(tags)];
619
+ ctx.meta.memoryScope = 'project';
620
+ },
621
+ });
622
+ this.middlewarePipeline.register({
623
+ name: 'guardrails',
624
+ priority: 40,
625
+ before: (ctx) => {
626
+ if (!['nexus_store_memory', 'nexus_net_publish'].includes(ctx.toolName))
627
+ return;
628
+ const action = ctx.toolName === 'nexus_store_memory'
629
+ ? `nexus_store_memory: ${String(ctx.args.content ?? '')}`
630
+ : `nexusnet_transmit: ${String(ctx.args.content ?? '')}`;
631
+ const guardCheck = guardrailEngine.check({ action });
632
+ if (guardCheck.passed)
633
+ return;
634
+ ctx.meta.shortCircuitedBy = 'guardrails';
635
+ ctx.meta.shortCircuitResult = {
636
+ content: [{
637
+ type: 'text',
638
+ text: `❌ GUARDRAIL BLOCKED: ${guardrailEngine.format(guardCheck)}`,
639
+ }],
640
+ };
641
+ },
642
+ });
643
+ this.middlewarePipeline.register({
644
+ name: 'cost',
645
+ priority: 50,
646
+ after: (ctx, result) => {
647
+ const durationMs = Date.now() - ctx.startTimeMs;
648
+ const responseBytes = Buffer.byteLength(JSON.stringify(result), 'utf8');
649
+ ctx.meta.durationMs = durationMs;
650
+ ctx.meta.responseBytes = responseBytes;
651
+ ctx.meta.estimatedUsd = Number(((responseBytes / 4_000) * 0.000003).toFixed(6));
652
+ },
653
+ });
654
+ }
557
655
  formatProtocolChecklist() {
558
656
  return [
559
657
  'PROTOCOL CHECKLIST (follow every step):',
@@ -1634,7 +1732,7 @@ export class MCPAdapter {
1634
1732
  if (toolName === 'nexus_session_bootstrap') {
1635
1733
  this.telemetry.bootstrapped = true;
1636
1734
  }
1637
- const args = request.params?.arguments ?? {};
1735
+ const args = request.params.arguments ?? (request.params.arguments = {});
1638
1736
  // Gate: block non-bootstrap tools BEFORE executing them to avoid wasted work and side effects
1639
1737
  if (!this.telemetry.bootstrapped &&
1640
1738
  toolName !== 'nexus_session_bootstrap' &&
@@ -1664,7 +1762,16 @@ export class MCPAdapter {
1664
1762
  });
1665
1763
  let result;
1666
1764
  try {
1667
- result = await this.handleToolCall(request);
1765
+ const executionContext = {
1766
+ toolName,
1767
+ args: args,
1768
+ adapterName: this.name,
1769
+ projectHash: this.getProjectHash(),
1770
+ currentTask: this.currentTask,
1771
+ startTimeMs,
1772
+ meta: {},
1773
+ };
1774
+ result = await this.middlewarePipeline.execute(executionContext, () => this.handleToolCall(request, executionContext));
1668
1775
  const resultPayload = JSON.stringify(result);
1669
1776
  nexusEventBus.emit('mcp.call.complete', {
1670
1777
  callId,
@@ -1691,7 +1798,7 @@ export class MCPAdapter {
1691
1798
  return this.injectMemoryContext(toolName, args, decorated);
1692
1799
  });
1693
1800
  }
1694
- async handleToolCall(request) {
1801
+ async handleToolCall(request, ctx) {
1695
1802
  if (!this.nexusRef) {
1696
1803
  throw new McpError(ErrorCode.InternalError, 'NexusPrime reference not set.');
1697
1804
  }
@@ -1735,7 +1842,6 @@ export class MCPAdapter {
1735
1842
  const gstackBridge = getGstackBridge();
1736
1843
  if (gstackBridge.detect() && gstackBridge.listSkills().some(s => s.toolName === toolName)) {
1737
1844
  const result = await gstackBridge.execute(toolName, args);
1738
- getSharedTelemetry().trackFeatureUsage(toolName, { success: result.success });
1739
1845
  return {
1740
1846
  content: [{
1741
1847
  type: 'text',
@@ -1770,13 +1876,16 @@ export class MCPAdapter {
1770
1876
  // Remote telemetry: track session start (privacy-safe, opt-in only)
1771
1877
  try {
1772
1878
  const remoteTelemetry = getSharedTelemetry();
1773
- remoteTelemetry.trackSessionStart();
1774
- remoteTelemetry.trackFeatureUsage('session_bootstrap');
1879
+ remoteTelemetry.trackSessionStart(PROJECT_ROOT);
1775
1880
  if (autoTokenApplied && bootstrap.tokenOptimization?.planMetrics?.savings) {
1776
1881
  remoteTelemetry.trackTokenSavings(Number(bootstrap.tokenOptimization.planMetrics.savings));
1777
1882
  }
1778
1883
  }
1779
1884
  catch { /* best-effort telemetry */ }
1885
+ if (ctx) {
1886
+ ctx.meta.tokenSavings = Number(bootstrap.tokenOptimization?.planMetrics?.savings ?? 0);
1887
+ ctx.meta.projectMemoryBootstrapCount = Number(bootstrap.projectMemoryBootstrap?.count ?? 0);
1888
+ }
1780
1889
  // Auto-generate a project-scoped memory on bootstrap so dashboard always has something to show
1781
1890
  try {
1782
1891
  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']);
@@ -1800,6 +1909,7 @@ export class MCPAdapter {
1800
1909
  workerPlanPreview: bootstrap.workerPlanPreview,
1801
1910
  knowledgeFabric: bootstrap.knowledgeFabric,
1802
1911
  sessionSummaryBootstrap: bootstrap.sessionSummaryBootstrap,
1912
+ projectMemoryBootstrap: bootstrap.projectMemoryBootstrap,
1803
1913
  mcpToolProfile: this.getToolProfile(),
1804
1914
  };
1805
1915
  return {
@@ -1823,6 +1933,9 @@ export class MCPAdapter {
1823
1933
  bootstrap.sessionSummaryBootstrap
1824
1934
  ? `Session summary: reused ${Number(bootstrap.sessionSummaryBootstrap.savedTokens || 0).toLocaleString()} tokens from the previous visit`
1825
1935
  : 'Session summary: none available yet',
1936
+ bootstrap.projectMemoryBootstrap?.count
1937
+ ? `Project memory: recovered ${bootstrap.projectMemoryBootstrap.count} prior project memories`
1938
+ : 'Project memory: no prior project memories recovered',
1826
1939
  bootstrap.autoGhostPass?.applied
1827
1940
  ? `Auto ghost-pass: ${bootstrap.autoGhostPass.riskAreas.length} risk area(s) · ${bootstrap.autoGhostPass.workerApproaches} approach(es)`
1828
1941
  : `Auto ghost-pass: skipped`,
@@ -2006,40 +2119,17 @@ export class MCPAdapter {
2006
2119
  const tags = Array.isArray(request.params.arguments?.tags)
2007
2120
  ? request.params.arguments.tags.map(String)
2008
2121
  : [];
2009
- // Guardrail: MEMORY_SIZE_GUARD auto-check
2010
- const guardCtx = { action: `nexus_store_memory: ${content}` };
2011
- const guardCheck = guardrailEngine.check(guardCtx);
2012
- if (!guardCheck.passed) {
2013
- return {
2014
- content: [{
2015
- type: 'text',
2016
- text: `❌ GUARDRAIL BLOCKED: ${guardrailEngine.format(guardCheck)}`
2017
- }]
2018
- };
2019
- }
2020
2122
  const id = this.nexusRef.storeMemory(content, priority, tags);
2021
2123
  this.telemetry.recordStore();
2022
2124
  this.sessionDNA.recordMemoryStore();
2023
2125
  const nudge = this.telemetry.planningNudge('store', { priority });
2024
- // Auto-Gist Publish Phase 8
2025
- let autoGistNote = '';
2026
- if (priority >= 0.8) {
2027
- try {
2028
- const publishResult = await nexusNetRelay.publish('knowledge', { content, tags });
2029
- nexusEventBus.emit('nexusnet.publish', { type: 'knowledge', byteSize: publishResult.bytes });
2030
- autoGistNote = publishResult.configured
2031
- ? `\n🌐 Auto-Published to NexusNet Relay (ID: ${publishResult.id})`
2032
- : `\n⚠️ NexusNet relay unconfigured. Auto-publish skipped.`;
2033
- }
2034
- catch (e) {
2035
- autoGistNote = `\n⚠️ Auto-Publish to NexusNet failed: ${e.message}`;
2036
- }
2126
+ if (ctx) {
2127
+ ctx.meta.memoryScope = tags.some((tag) => tag.startsWith('#project')) ? 'project' : 'session';
2037
2128
  }
2038
2129
  // Console ASCII UI
2039
2130
  this.box('🧠 CORTEX MEMORY STORED', [
2040
2131
  `Priority: ${priority.toFixed(2).padEnd(5)} Tags: ${tags.join(', ').substring(0, 31).padEnd(31)}`,
2041
2132
  `${content.substring(0, 56).padEnd(56, ' ').replace(/\n/g, ' ')}...`,
2042
- ...(autoGistNote ? [`\x1b[33m${autoGistNote.replace('\n', '').substring(0, 62).padEnd(64, ' ')}\x1b[0m`] : [])
2043
2133
  ], '36');
2044
2134
  return {
2045
2135
  content: [{
@@ -2058,6 +2148,9 @@ export class MCPAdapter {
2058
2148
  nexusEventBus.emit('memory.recall', { query, count: memories.length });
2059
2149
  this.telemetry.recordRecall(memories.length);
2060
2150
  this.sessionDNA.recordMemoryRecall();
2151
+ if (ctx) {
2152
+ ctx.meta.memoryRecallCount = memories.length;
2153
+ }
2061
2154
  const nudge = this.telemetry.planningNudge('recall', { count: memories.length });
2062
2155
  // Console ASCII UI
2063
2156
  this.box('🔍 CORTEX MEMORY RECALL', [
@@ -2297,7 +2390,7 @@ export class MCPAdapter {
2297
2390
  return { content: [{ type: 'text', text: 'Search query is required.' }] };
2298
2391
  }
2299
2392
  const ngramIndex = getNgramIndexInstance();
2300
- const { results, tokensSaved, totalCandidateTokens } = ngramIndex.searchWithStats(query, limit);
2393
+ const { results, tokensSaved } = ngramIndex.searchWithStats(query, limit);
2301
2394
  if (results.length === 0) {
2302
2395
  return { content: [{ type: 'text', text: `No results found for "${query}".` }] };
2303
2396
  }
@@ -2691,6 +2784,17 @@ export class MCPAdapter {
2691
2784
  this.getOrchestrator().persistSessionSummary(telemetry.tokensOptimized || this.getRuntime().getUsageSnapshot().tokens?.grossInputTokens || 0);
2692
2785
  }
2693
2786
  catch { /* non-fatal */ }
2787
+ try {
2788
+ await getSharedTelemetry().trackSessionEnd(this.telemetry.elapsedMs(), {
2789
+ projectId: PROJECT_ROOT,
2790
+ tokensSaved: telemetry.tokensOptimized,
2791
+ memoriesCreated: telemetry.memoriesStored,
2792
+ memoriesRecalled: telemetry.memoriesRecalled,
2793
+ toolsUsed: telemetry.callCount,
2794
+ sessionId: dna.sessionId,
2795
+ });
2796
+ }
2797
+ catch { /* best effort */ }
2694
2798
  return {
2695
2799
  content: [{
2696
2800
  type: 'text',
@@ -3318,17 +3422,6 @@ export class MCPAdapter {
3318
3422
  const type = String(request.params.arguments?.type ?? 'knowledge');
3319
3423
  const content = String(request.params.arguments?.content ?? '');
3320
3424
  const tags = Array.isArray(request.params.arguments?.tags) ? request.params.arguments?.tags : [];
3321
- // Guardrail: GIST_PUBLISH_GUARD auto-check
3322
- const guardCtx = { action: `nexusnet_transmit: ${content}` };
3323
- const guardCheck = guardrailEngine.check(guardCtx);
3324
- if (!guardCheck.passed) {
3325
- return {
3326
- content: [{
3327
- type: 'text',
3328
- text: `❌ GUARDRAIL BLOCKED: ${guardrailEngine.format(guardCheck)}`
3329
- }]
3330
- };
3331
- }
3332
3425
  try {
3333
3426
  const result = await nexusNetRelay.publish(type, { content, tags });
3334
3427
  nexusEventBus.emit('nexusnet.publish', { type, byteSize: result.bytes });