nexus-prime 7.9.21 → 7.9.23

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 (59) hide show
  1. package/dist/agents/adapters/ide-compat.d.ts +3 -3
  2. package/dist/agents/adapters/ide-compat.js +51 -1
  3. package/dist/agents/adapters/mcp/definitions.js +4 -1
  4. package/dist/agents/adapters/mcp/dispatch.js +66 -4
  5. package/dist/agents/adapters/mcp/handlers/memory.js +44 -5
  6. package/dist/agents/adapters/mcp/handlers/orchestration.js +91 -0
  7. package/dist/agents/adapters/mcp/runHandler.js +3 -0
  8. package/dist/agents/adapters/mcp/util/detect-caller.js +21 -0
  9. package/dist/agents/adapters/mcp.js +1 -1
  10. package/dist/agents/adapters.d.ts +10 -1
  11. package/dist/agents/adapters.js +21 -0
  12. package/dist/agents/core/types.d.ts +1 -1
  13. package/dist/cli/hook.d.ts +4 -6
  14. package/dist/cli/hook.js +6 -8
  15. package/dist/cli/install-wizard.js +5 -1
  16. package/dist/cli.js +181 -15
  17. package/dist/core/types.d.ts +1 -1
  18. package/dist/dashboard/app/styles/board.css +85 -1
  19. package/dist/dashboard/app/styles/runtime.css +148 -0
  20. package/dist/dashboard/app/styles/workforce.css +28 -0
  21. package/dist/dashboard/app/views/board.js +56 -0
  22. package/dist/dashboard/app/views/memory.js +71 -10
  23. package/dist/dashboard/app/views/runtime.js +138 -4
  24. package/dist/dashboard/app/views/workforce.js +11 -4
  25. package/dist/dashboard/routes/events.js +3 -0
  26. package/dist/dashboard/selectors/operate-selector.js +5 -0
  27. package/dist/dashboard/selectors/runs-selector.js +5 -0
  28. package/dist/dashboard/server.js +6 -0
  29. package/dist/dashboard/types.d.ts +4 -0
  30. package/dist/engines/client-bootstrap.d.ts +5 -1
  31. package/dist/engines/client-bootstrap.js +105 -10
  32. package/dist/engines/client-registry.js +51 -0
  33. package/dist/engines/event-bus.d.ts +20 -2
  34. package/dist/engines/feature-registry.js +1 -0
  35. package/dist/engines/instruction-gateway.d.ts +9 -0
  36. package/dist/engines/instruction-gateway.js +113 -4
  37. package/dist/engines/memory/types.d.ts +28 -0
  38. package/dist/engines/memory-bridge.d.ts +1 -1
  39. package/dist/engines/memory-bridge.js +1 -1
  40. package/dist/engines/memory.d.ts +5 -0
  41. package/dist/engines/memory.js +144 -12
  42. package/dist/engines/orchestrator/decision-spine.d.ts +26 -0
  43. package/dist/engines/orchestrator/decision-spine.js +145 -6
  44. package/dist/engines/orchestrator/funnel.js +8 -1
  45. package/dist/engines/orchestrator/scoring.d.ts +1 -1
  46. package/dist/engines/orchestrator/scoring.js +24 -2
  47. package/dist/engines/orchestrator.d.ts +3 -0
  48. package/dist/engines/orchestrator.js +73 -13
  49. package/dist/engines/peer-connectors.d.ts +1 -1
  50. package/dist/engines/peer-connectors.js +9 -2
  51. package/dist/engines/runtime-registry.d.ts +9 -0
  52. package/dist/index.js +9 -0
  53. package/dist/install/state-locator.d.ts +1 -1
  54. package/dist/install/state-locator.js +3 -0
  55. package/dist/synapse/bootstrap.js +3 -0
  56. package/dist/synapse/mandate/pipeline.js +52 -5
  57. package/dist/synapse/sorties/runner.js +32 -0
  58. package/dist/synapse/types.d.ts +27 -0
  59. package/package.json +1 -1
@@ -19,7 +19,14 @@ function buildWelcomeMemoryTags(workspaceStateKey) {
19
19
  }
20
20
  const CODEX_MANAGED_START = '<!-- nexus-prime:codex-bootstrap:start -->';
21
21
  const CODEX_MANAGED_END = '<!-- nexus-prime:codex-bootstrap:end -->';
22
- const SUPPORTED_CLIENTS = ['codex', 'cursor', 'claude', 'claude-code', 'claude-desktop', 'opencode', 'windsurf', 'antigravity', 'openclaw', 'aider', 'continue', 'cline'];
22
+ const SUPPORTED_CLIENTS = ['codex', 'cursor', 'claude', 'claude-code', 'claude-desktop', 'opencode', 'windsurf', 'antigravity', 'openclaw', 'hermes', 'nanoclaw', 'picoclaw', 'aider', 'continue', 'cline'];
23
+ const HOME_SKILL_BUNDLE_DIRS = {
24
+ antigravity: join(homedir(), '.antigravity', 'skills', 'nexus-prime'),
25
+ openclaw: join(homedir(), '.openclaw', 'skills', 'nexus-prime'),
26
+ hermes: join(homedir(), '.hermes', 'skills', 'nexus-prime'),
27
+ nanoclaw: join(homedir(), '.nanoclaw', 'skills', 'nexus-prime'),
28
+ picoclaw: join(homedir(), '.picoclaw', 'skills', 'nexus-prime'),
29
+ };
23
30
  const WORKSPACE_SEED_FILES = [
24
31
  {
25
32
  relativePath: '.agents/README.md',
@@ -499,16 +506,10 @@ function buildInstructionFiles(clientId, packageRoot, workspaceRoot) {
499
506
  scope: 'workspace',
500
507
  }));
501
508
  }
502
- if (clientId === 'antigravity') {
509
+ const homeSkillDir = HOME_SKILL_BUNDLE_DIRS[clientId];
510
+ if (homeSkillDir) {
503
511
  return bundle.artifacts.map((artifact) => ({
504
- path: join(homedir(), '.antigravity', 'skills', 'nexus-prime', artifact.fileName),
505
- content: artifact.content,
506
- scope: 'home',
507
- }));
508
- }
509
- if (clientId === 'openclaw') {
510
- return bundle.artifacts.map((artifact) => ({
511
- path: join(homedir(), '.openclaw', 'skills', 'nexus-prime', artifact.fileName),
512
+ path: join(homeSkillDir, artifact.fileName),
512
513
  content: artifact.content,
513
514
  scope: 'home',
514
515
  }));
@@ -640,6 +641,33 @@ export function getSetupDefinition(clientId, options) {
640
641
  instructionFiles,
641
642
  };
642
643
  }
644
+ if (clientId === 'hermes') {
645
+ return {
646
+ id: clientId,
647
+ label: 'Hermes',
648
+ workspaceRoot,
649
+ configPath: join(homedir(), '.hermes', 'mcp.json'),
650
+ instructionFiles,
651
+ };
652
+ }
653
+ if (clientId === 'nanoclaw') {
654
+ return {
655
+ id: clientId,
656
+ label: 'NanoClaw',
657
+ workspaceRoot,
658
+ configPath: join(homedir(), '.nanoclaw', 'mcp.json'),
659
+ instructionFiles,
660
+ };
661
+ }
662
+ if (clientId === 'picoclaw') {
663
+ return {
664
+ id: clientId,
665
+ label: 'PicoClaw',
666
+ workspaceRoot,
667
+ configPath: join(homedir(), '.picoclaw', 'mcp.json'),
668
+ instructionFiles,
669
+ };
670
+ }
643
671
  return {
644
672
  id: clientId,
645
673
  label: 'Antigravity',
@@ -746,12 +774,71 @@ function instructionState(definition, scope) {
746
774
  ? 'installed'
747
775
  : 'missing';
748
776
  }
777
+ const MEMORY_HOOK_CLIENTS = new Set(['codex', 'cursor', 'claude', 'claude-code', 'claude-desktop']);
778
+ function instructionMentionsMemoryHook(content) {
779
+ return content.includes('nexus_store_memory') && /memory hooks?/i.test(content);
780
+ }
781
+ function hasInstructionMemoryHook(definition) {
782
+ return definition.instructionFiles.some((file) => {
783
+ if (!existsSync(file.path))
784
+ return false;
785
+ try {
786
+ return instructionMentionsMemoryHook(readFileSync(file.path, 'utf8'));
787
+ }
788
+ catch {
789
+ return false;
790
+ }
791
+ });
792
+ }
793
+ function hasRepoMemoryHookSeed(workspaceRoot) {
794
+ return ['.agents/hooks/memory-stored-review.md', '.agent/hooks/memory-stored-review.md']
795
+ .some((relativePath) => existsSync(join(workspaceRoot, relativePath)));
796
+ }
797
+ function hasClaudeCodeMemoryHook() {
798
+ const settingsPath = join(homedir(), '.claude', 'settings.json');
799
+ if (!existsSync(settingsPath))
800
+ return false;
801
+ try {
802
+ const parsed = JSON.parse(readFileSync(settingsPath, 'utf8'));
803
+ return Boolean(parsed?.hooks?.PostToolUse?.some((entry) => (entry?.hooks?.some((hook) => hook?.command === 'nexus-prime hook memory'))));
804
+ }
805
+ catch {
806
+ return false;
807
+ }
808
+ }
809
+ function memoryHookStatus(definition) {
810
+ if (!MEMORY_HOOK_CLIENTS.has(definition.id)) {
811
+ return {
812
+ memoryHookReady: false,
813
+ memoryHookSummary: 'Memory hook readiness is not tracked for this client',
814
+ };
815
+ }
816
+ const instructionReady = hasInstructionMemoryHook(definition);
817
+ const repoHookReady = hasRepoMemoryHookSeed(definition.workspaceRoot);
818
+ const nativeHookRequired = definition.id === 'claude' || definition.id === 'claude-code';
819
+ const nativeHookReady = nativeHookRequired ? hasClaudeCodeMemoryHook() : true;
820
+ const memoryHookReady = instructionReady && repoHookReady && nativeHookReady;
821
+ const missing = [
822
+ instructionReady ? null : 'client instruction wording',
823
+ repoHookReady ? null : 'repo memory.stored hook seed',
824
+ nativeHookReady ? null : 'Claude Code PostToolUse hook',
825
+ ].filter(Boolean);
826
+ return {
827
+ memoryHookReady,
828
+ memoryHookSummary: memoryHookReady
829
+ ? nativeHookRequired
830
+ ? 'Memory hooks ready via Claude Code PostToolUse plus Nexus lifecycle memory storage'
831
+ : 'Memory hooks ready via Nexus lifecycle memory storage and repo memory.stored hook'
832
+ : `Memory hooks incomplete: ${missing.join(', ')}`,
833
+ };
834
+ }
749
835
  export function statusForDefinition(definition) {
750
836
  const configOk = definition.configPath ? hasExpectedConfig(definition) : true;
751
837
  const workspaceState = instructionState(definition, 'workspace');
752
838
  const homeState = instructionState(definition, 'home');
753
839
  const homeReady = configOk && homeState !== 'drifted';
754
840
  const workspaceReady = workspaceState === 'installed' || definition.instructionFiles.every((file) => file.scope !== 'workspace');
841
+ const memoryHook = memoryHookStatus(definition);
755
842
  if (configOk && workspaceState !== 'drifted' && homeState !== 'drifted' && workspaceReady) {
756
843
  return {
757
844
  state: 'installed',
@@ -760,6 +847,7 @@ export function statusForDefinition(definition) {
760
847
  : 'Managed client instructions are current',
761
848
  homeReady,
762
849
  workspaceReady,
850
+ ...memoryHook,
763
851
  };
764
852
  }
765
853
  if ((definition.configPath && existsSync(definition.configPath)) || workspaceState !== 'missing' || homeState !== 'missing') {
@@ -770,6 +858,7 @@ export function statusForDefinition(definition) {
770
858
  : 'A client instruction file exists, but the managed Nexus Prime bootstrap block is missing or outdated',
771
859
  homeReady,
772
860
  workspaceReady,
861
+ ...memoryHook,
773
862
  };
774
863
  }
775
864
  return {
@@ -777,6 +866,7 @@ export function statusForDefinition(definition) {
777
866
  summary: definition.configPath ? 'Setup not installed yet' : 'No managed client instruction file installed yet',
778
867
  homeReady: false,
779
868
  workspaceReady: false,
869
+ ...memoryHook,
780
870
  };
781
871
  }
782
872
  export function supportedSetupClients() {
@@ -817,6 +907,9 @@ function isClientPresent(clientId) {
817
907
  'cline': () => existsSync(join(home, '.vscode')),
818
908
  'antigravity': () => hasBinary('antigravity') || existsSync(join(home, '.antigravity')),
819
909
  'openclaw': () => hasBinary('openclaw') || existsSync(join(home, '.openclaw')),
910
+ 'hermes': () => hasBinary('hermes') || existsSync(join(home, '.hermes')),
911
+ 'nanoclaw': () => hasBinary('nanoclaw') || existsSync(join(home, '.nanoclaw')),
912
+ 'picoclaw': () => hasBinary('picoclaw') || existsSync(join(home, '.picoclaw')),
820
913
  };
821
914
  try {
822
915
  return checks[clientId]?.() ?? false;
@@ -914,6 +1007,8 @@ export function collectBootstrapManifest(options) {
914
1007
  instructionFiles: definition.instructionFiles.map((file) => file.path),
915
1008
  homeReady: status.homeReady,
916
1009
  workspaceReady: status.workspaceReady,
1010
+ memoryHookReady: status.memoryHookReady,
1011
+ memoryHookSummary: status.memoryHookSummary,
917
1012
  summary: status.summary,
918
1013
  updatedAt: Date.now(),
919
1014
  };
@@ -37,6 +37,30 @@ const KNOWN_CLIENTS = [
37
37
  recentPaths: [path.join(HOME, '.antigravity', 'sessions'), path.join(HOME, '.openclaw', 'sessions')],
38
38
  adapterNames: ['openclaw'],
39
39
  },
40
+ {
41
+ clientId: 'hermes',
42
+ displayName: 'Hermes',
43
+ aliases: ['hermes'],
44
+ configPaths: [path.join(HOME, '.hermes')],
45
+ recentPaths: [path.join(HOME, '.hermes', 'sessions')],
46
+ adapterNames: ['hermes'],
47
+ },
48
+ {
49
+ clientId: 'nanoclaw',
50
+ displayName: 'NanoClaw',
51
+ aliases: ['nanoclaw', 'nano-claw'],
52
+ configPaths: [path.join(HOME, '.nanoclaw')],
53
+ recentPaths: [path.join(HOME, '.nanoclaw', 'sessions')],
54
+ adapterNames: ['nanoclaw'],
55
+ },
56
+ {
57
+ clientId: 'picoclaw',
58
+ displayName: 'PicoClaw',
59
+ aliases: ['picoclaw', 'pico-claw'],
60
+ configPaths: [path.join(HOME, '.picoclaw')],
61
+ recentPaths: [path.join(HOME, '.picoclaw', 'sessions')],
62
+ adapterNames: ['picoclaw'],
63
+ },
40
64
  {
41
65
  clientId: 'opencode',
42
66
  displayName: 'Opencode',
@@ -412,6 +436,12 @@ export class ClientRegistry {
412
436
  return 'opencode';
413
437
  if (process.env.OPENCLAW_HOME || process.env.ANTIGRAVITY_HOME)
414
438
  return 'antigravity';
439
+ if (process.env.HERMES_HOME || process.env.HERMES_SESSION)
440
+ return 'hermes';
441
+ if (process.env.NANOCLAW_HOME || process.env.NANOCLAW_SESSION)
442
+ return 'nanoclaw';
443
+ if (process.env.PICOCLAW_HOME || process.env.PICOCLAW_SESSION)
444
+ return 'picoclaw';
415
445
  if (process.env.WINDSURF_HOME || process.env.WINDSURF_SESSION)
416
446
  return 'windsurf';
417
447
  if (process.env.MCP_CLIENT_NAME) {
@@ -438,6 +468,12 @@ export class ClientRegistry {
438
468
  return 'windsurf';
439
469
  if (ps.includes('antigravity') || ps.includes('openclaw'))
440
470
  return 'antigravity';
471
+ if (ps.includes('hermes'))
472
+ return 'hermes';
473
+ if (ps.includes('nanoclaw') || ps.includes('nano-claw'))
474
+ return 'nanoclaw';
475
+ if (ps.includes('picoclaw') || ps.includes('pico-claw'))
476
+ return 'picoclaw';
441
477
  }
442
478
  catch (error) {
443
479
  this.disableProcessScanIfUnavailable(error);
@@ -461,6 +497,15 @@ export class ClientRegistry {
461
497
  if (clientId === 'antigravity' && (process.env.OPENCLAW_HOME || process.env.ANTIGRAVITY_HOME)) {
462
498
  return 'env:ANTIGRAVITY detected';
463
499
  }
500
+ if (clientId === 'hermes' && (process.env.HERMES_HOME || process.env.HERMES_SESSION)) {
501
+ return 'env:HERMES detected';
502
+ }
503
+ if (clientId === 'nanoclaw' && (process.env.NANOCLAW_HOME || process.env.NANOCLAW_SESSION)) {
504
+ return 'env:NANOCLAW detected';
505
+ }
506
+ if (clientId === 'picoclaw' && (process.env.PICOCLAW_HOME || process.env.PICOCLAW_SESSION)) {
507
+ return 'env:PICOCLAW detected';
508
+ }
464
509
  if (clientId === 'windsurf' && (process.env.WINDSURF_HOME || process.env.WINDSURF_SESSION)) {
465
510
  return 'env:WINDSURF detected';
466
511
  }
@@ -562,6 +607,12 @@ export class ClientRegistry {
562
607
  function normalizeDisplayName(value) {
563
608
  if (value === 'openclaw')
564
609
  return 'Antigravity';
610
+ if (value === 'hermes')
611
+ return 'Hermes';
612
+ if (value === 'nanoclaw' || value === 'nano-claw')
613
+ return 'NanoClaw';
614
+ if (value === 'picoclaw' || value === 'pico-claw')
615
+ return 'PicoClaw';
565
616
  if (value === 'claude-code')
566
617
  return 'Claude Code';
567
618
  if (value === 'cursor')
@@ -1,4 +1,4 @@
1
- export type NexusEventType = 'system.boot' | 'planner.stage' | 'memory.store' | 'memory.dedup' | 'memory.recall' | 'memory.flushed' | 'memory.snapshot' | 'memory.health.tick' | 'memory.sqlite.retry' | 'pod.signal' | 'tokens.optimized' | 'tokens.searchSaved' | 'orchestration.decomposed' | 'orchestration.completed' | 'session.summaryBootstrap' | 'phantom.worker.start' | 'phantom.worker.complete' | 'phantom.merge.complete' | 'phantom.merge' | 'guardrail.check' | 'ghost.pass' | 'graph.query' | 'graph.sync.failed' | 'graph.coverage.low' | 'graph.cr.build.start' | 'graph.cr.build.complete' | 'graph.cr.build.failed' | 'darwin.cycle' | 'darwin.cycle.complete' | 'session.dna' | 'skill.register' | 'skill.deploy' | 'skill.revoke' | 'hook.deploy' | 'hook.revoke' | 'hook.fire' | 'hook.error' | 'workflow.deploy' | 'workflow.run' | 'automation.deploy' | 'automation.revoke' | 'automation.run' | 'shield.decision' | 'memory.audit' | 'federation.heartbeat' | 'client.heartbeat' | 'client.inferred' | 'client.status' | 'dashboard.action' | 'workspace.changed' | 'nexus.shutdown' | 'nexus.daemon.error' | 'orchestrator.disposed' | 'orchestrator.funnel.stage' | 'orchestrator.warn' | 'nexusnet.publish' | 'nexusnet.sync' | 'mcp.call.start' | 'mcp.call.stream' | 'mcp.call.complete' | 'mcp.handler.complete' | 'mcp.handler.failed' | 'mcp.handler.retry' | 'mcp.handler.best-effort-failed' | 'tool.invocation' | 'nexus.deprecation.used' | 'memory.tier.promoted' | 'memory.tier.promoted.failed' | 'memory.pre-compaction' | 'memory.flush-requested' | 'entanglement.create' | 'entanglement.collapse' | 'entanglement.correlate' | 'cas.encode' | 'cas.decode' | 'cas.pattern_learned' | 'kv.merge' | 'kv.adapt' | 'kv.consensus' | 'byzantine.vote.started' | 'byzantine.vote.result' | 'synapse.ready' | 'synapse.operative.hired' | 'synapse.operative.retired' | 'synapse.operative.health.changed' | 'synapse.striketeam.deployed' | 'synapse.striketeam.completed' | 'synapse.striketeam.finished' | 'synapse.mission.assigned' | 'synapse.mission.completed' | 'synapse.sortie.started' | 'synapse.sortie.completed' | 'synapse.sortie.failed' | 'synapse.fieldreport.submitted' | 'synapse.echo.fired' | 'synapse.budget.warning' | 'synapse.budget.exceeded' | 'synapse.approval.requested' | 'synapse.approval.resolved' | 'synapse.compaction.standdown' | 'synapse.compaction.resumed' | 'synapse.coordination.publish.failed' | 'synapse.watchdog.stall' | 'synapse.watchdog.zombie' | 'architects.ready' | 'architects.blueprint.instantiated' | 'architects.worklist.created' | 'architects.workitem.claimed' | 'architects.workitem.completed' | 'architects.workitem.blocked' | 'architects.constructionlock.acquired' | 'architects.constructionlock.renewed' | 'architects.constructionlock.released' | 'architects.constructionlock.contested' | 'architects.relay.sent' | 'architects.relay.read' | 'architects.sentinel.patrol' | 'architects.sentinel.stall' | 'architects.sentinel.zombie' | 'architects.ward.patrol' | 'architects.ward.escalation' | 'architects.convergence.started' | 'architects.convergence.merged' | 'architects.convergence.failed' | 'architects.dispatch.go' | 'architects.dispatch.queued' | 'architects.relay.failed' | 'architects.event.failed' | 'ledger.duplicate-prevented' | 'nexus.circuit-open' | 'nexus.circuit-tripped' | 'license.activated' | 'license.deactivated' | 'license.expired' | 'license.cap.warning' | 'license.cap.reached' | 'dispatch.started' | 'dispatch.event' | 'dispatch.token-usage' | 'dispatch.complete' | 'dispatch.failed' | 'dispatch.cancelled' | 'dispatch.budget-exceeded' | 'mcp.auto-memory.failed' | 'daemon.self-heal.db-corrupt' | 'feature.time_to_first_bootstrap' | 'feature.time_to_first_memory' | 'feature.time_to_first_interaction' | 'feature.time_to_first_mission_complete' | 'async_gate.completed' | 'async_gate.failed' | 'install.step' | 'license.tierChanged' | 'license.upgradeNudge' | 'orchestrator.run.start' | 'orchestrator.run.complete';
1
+ export type NexusEventType = 'system.boot' | 'planner.stage' | 'memory.store' | 'memory.dedup' | 'memory.recall' | 'memory.flushed' | 'memory.snapshot' | 'memory.health.tick' | 'memory.sqlite.retry' | 'pod.signal' | 'tokens.optimized' | 'tokens.searchSaved' | 'orchestration.decomposed' | 'orchestration.completed' | 'session.summaryBootstrap' | 'phantom.worker.start' | 'phantom.worker.complete' | 'phantom.merge.complete' | 'phantom.merge' | 'guardrail.check' | 'ghost.pass' | 'graph.query' | 'graph.sync.failed' | 'graph.coverage.low' | 'graph.cr.build.start' | 'graph.cr.build.complete' | 'graph.cr.build.failed' | 'darwin.cycle' | 'darwin.cycle.complete' | 'session.dna' | 'skill.register' | 'skill.deploy' | 'skill.revoke' | 'hook.deploy' | 'hook.revoke' | 'hook.fire' | 'hook.error' | 'workflow.deploy' | 'workflow.run' | 'automation.deploy' | 'automation.revoke' | 'automation.run' | 'shield.decision' | 'memory.audit' | 'federation.heartbeat' | 'client.heartbeat' | 'client.inferred' | 'client.status' | 'dashboard.action' | 'workspace.changed' | 'nexus.shutdown' | 'nexus.daemon.error' | 'orchestrator.disposed' | 'orchestrator.funnel.stage' | 'orchestrator.warn' | 'nexusnet.publish' | 'nexusnet.sync' | 'mcp.call.start' | 'mcp.call.stream' | 'mcp.call.complete' | 'mcp.handler.complete' | 'mcp.handler.failed' | 'mcp.handler.retry' | 'mcp.handler.best-effort-failed' | 'tool.invocation' | 'nexus.deprecation.used' | 'memory.tier.promoted' | 'memory.tier.promoted.failed' | 'memory.pre-compaction' | 'memory.flush-requested' | 'entanglement.create' | 'entanglement.collapse' | 'entanglement.correlate' | 'cas.encode' | 'cas.decode' | 'cas.pattern_learned' | 'kv.merge' | 'kv.adapt' | 'kv.consensus' | 'byzantine.vote.started' | 'byzantine.vote.result' | 'synapse.ready' | 'synapse.operative.hired' | 'synapse.operative.retired' | 'synapse.operative.health.changed' | 'synapse.striketeam.deployed' | 'synapse.striketeam.completed' | 'synapse.striketeam.finished' | 'synapse.mission.assigned' | 'synapse.mission.completed' | 'synapse.sortie.started' | 'synapse.sortie.selection' | 'synapse.sortie.completed' | 'synapse.sortie.failed' | 'synapse.fieldreport.submitted' | 'synapse.echo.fired' | 'synapse.budget.warning' | 'synapse.budget.exceeded' | 'synapse.approval.requested' | 'synapse.approval.resolved' | 'synapse.compaction.standdown' | 'synapse.compaction.resumed' | 'synapse.coordination.publish.failed' | 'synapse.watchdog.stall' | 'synapse.watchdog.zombie' | 'architects.ready' | 'architects.blueprint.instantiated' | 'architects.worklist.created' | 'architects.workitem.claimed' | 'architects.workitem.completed' | 'architects.workitem.blocked' | 'architects.constructionlock.acquired' | 'architects.constructionlock.renewed' | 'architects.constructionlock.released' | 'architects.constructionlock.contested' | 'architects.relay.sent' | 'architects.relay.read' | 'architects.sentinel.patrol' | 'architects.sentinel.stall' | 'architects.sentinel.zombie' | 'architects.ward.patrol' | 'architects.ward.escalation' | 'architects.convergence.started' | 'architects.convergence.merged' | 'architects.convergence.failed' | 'architects.dispatch.go' | 'architects.dispatch.queued' | 'architects.relay.failed' | 'architects.event.failed' | 'ledger.duplicate-prevented' | 'nexus.circuit-open' | 'nexus.circuit-tripped' | 'license.activated' | 'license.deactivated' | 'license.expired' | 'license.cap.warning' | 'license.cap.reached' | 'dispatch.started' | 'dispatch.event' | 'dispatch.token-usage' | 'dispatch.complete' | 'dispatch.failed' | 'dispatch.cancelled' | 'dispatch.budget-exceeded' | 'mcp.auto-memory.failed' | 'daemon.self-heal.db-corrupt' | 'feature.time_to_first_bootstrap' | 'feature.time_to_first_memory' | 'feature.time_to_first_interaction' | 'feature.time_to_first_mission_complete' | 'async_gate.completed' | 'async_gate.failed' | 'install.step' | 'license.tierChanged' | 'license.upgradeNudge' | 'orchestrator.run.start' | 'orchestrator.run.complete';
2
2
  export interface NexusEventPayloads {
3
3
  'system.boot': {
4
4
  version: string;
@@ -24,6 +24,10 @@ export interface NexusEventPayloads {
24
24
  'memory.recall': {
25
25
  query: string;
26
26
  count: number;
27
+ k?: number;
28
+ crossClient?: boolean;
29
+ format?: string;
30
+ preview?: string[];
27
31
  };
28
32
  'memory.flushed': {
29
33
  count: number;
@@ -442,7 +446,10 @@ export interface NexusEventPayloads {
442
446
  operativeId: string;
443
447
  name: string;
444
448
  skillId: string | null;
445
- strikeTeamId: string;
449
+ specialistId?: string | null;
450
+ roleTitle?: string | null;
451
+ reportsToOperativeId?: string | null;
452
+ strikeTeamId: string | null;
446
453
  };
447
454
  'synapse.operative.retired': {
448
455
  operativeId: string;
@@ -455,6 +462,7 @@ export interface NexusEventPayloads {
455
462
  strikeTeamId: string;
456
463
  operativeCount: number;
457
464
  missionCount: number;
465
+ selectionSummary?: unknown;
458
466
  worklistId?: string | null;
459
467
  correlationId?: string | null;
460
468
  };
@@ -489,6 +497,16 @@ export interface NexusEventPayloads {
489
497
  worklistId?: string | null;
490
498
  correlationId?: string | null;
491
499
  };
500
+ 'synapse.sortie.selection': {
501
+ sortieId: string;
502
+ operativeId: string;
503
+ missionId: string | null;
504
+ strikeTeamId?: string | null;
505
+ skillId?: string | null;
506
+ specialistId?: string | null;
507
+ workflowSelectors: string[];
508
+ workerCount: number;
509
+ };
492
510
  'synapse.sortie.completed': {
493
511
  sortieId: string;
494
512
  operativeId: string;
@@ -24,6 +24,7 @@ const CLIENT_BOOTSTRAP_TARGETS = [
24
24
  { name: 'Opencode', surface: 'bootstrap target', purpose: 'Installs config plus generated markdown bootstrap note.', notes: 'Project note under .agent/client-bootstrap.' },
25
25
  { name: 'Windsurf', surface: 'bootstrap target', purpose: 'Installs MCP config plus .windsurfrules.', notes: 'Workspace-scoped rule surface.' },
26
26
  { name: 'Antigravity / OpenClaw', surface: 'bootstrap target', purpose: 'Installs MCP config plus split SKILL.md bundles sized to client limits.', notes: 'Home-scoped skill bundle.' },
27
+ { name: 'Hermes / NanoClaw / PicoClaw', surface: 'bootstrap target', purpose: 'Installs MCP config plus split SKILL.md bundles for peer agent clients.', notes: 'Memory, skills, token budgeting, and workforce tools are exposed through the same MCP surface.' },
27
28
  ];
28
29
  const DASHBOARD_CAPABILITIES = [
29
30
  { name: 'Overview', surface: 'dashboard', purpose: 'Runtime truth, lifetime token telemetry, graph-centered memory view, and system signals.', notes: 'Default operator cockpit.' },
@@ -43,6 +43,8 @@ export interface TokenPolicySnapshot {
43
43
  selectedFiles: string[];
44
44
  estimatedSavings: number;
45
45
  estimatedCompressionPct: number;
46
+ codeBlockTemplates?: string[];
47
+ codeBlockReservedTokens?: number;
46
48
  }
47
49
  export interface GovernanceSnapshot {
48
50
  passed: boolean;
@@ -87,6 +89,13 @@ export interface InstructionPacket {
87
89
  relayLastError?: string;
88
90
  };
89
91
  tokenPolicy: TokenPolicySnapshot;
92
+ codeQualityBlocks: Array<{
93
+ id: string;
94
+ title: string;
95
+ language: string;
96
+ purpose: string;
97
+ content: string;
98
+ }>;
90
99
  memoryContext: {
91
100
  matches: string[];
92
101
  stats?: Pick<MemoryStats, 'prefrontal' | 'hippocampus' | 'cortex' | 'totalLinks'>;
@@ -5,6 +5,9 @@ import { resolveWorkspaceContext } from './workspace-resolver.js';
5
5
  export const PACKET_TOKEN_LIMIT = 3500;
6
6
  export const CLIENT_BOOTSTRAP_TOKEN_LIMITS = {
7
7
  antigravity: 1200,
8
+ hermes: 1600,
9
+ nanoclaw: 1200,
10
+ picoclaw: 1200,
8
11
  cursor: 1800,
9
12
  windsurf: 1800,
10
13
  'claude-code': 2000,
@@ -29,8 +32,11 @@ export const DEFAULT_REQUIRED_SEQUENCE = [
29
32
  export const CLIENT_BOOTSTRAP_SEQUENCE = [
30
33
  'MUST call `nexus_session_bootstrap(goal, files?)` then `nexus_orchestrate(prompt)` before any non-trivial task.',
31
34
  'MUST call `nexus_mindkit_check(action, files)` before mutations; `nexus_ghost_pass(goal, files)` before 3+ file refactors.',
32
- 'MUST call `nexus_store_memory(content, priority, tags)` after findings and `nexus_session_dna("generate")` at session end.',
35
+ 'Memory hooks are supported: MUST call `nexus_store_memory(content, priority, tags)` after significant findings, user preferences, decisions, pivots, and verification results; never store secrets; call `nexus_session_dna("generate")` at session end.',
36
+ 'Use fenced code blocks for work packets, implementation notes, verification output, and memory write-back so downstream agents can parse the handoff cleanly.',
33
37
  'Use `nexus_describe_tool(id)` to load skill/workflow details on demand. Let Nexus select assets by default.',
38
+ 'Use `nexus_list_skills`, `nexus_list_specialists`, and `nexus_work_hire`/`nexus_work_enqueue` when a client needs skills, specialists, Synapse-style hiring, or workforce delegation.',
39
+ 'When workers are selected, state exactly what is being hired: crew, specialists, workflow, model tier, budget guardrail, and verification gate.',
34
40
  'If a tool returns `{ "queued": true, "runId": "..." }`, call `nexus_run_status(runId)` every ~5 seconds until status is `completed` or `failed`, then inspect the `result` field.',
35
41
  'Repo graph is internal to Nexus. Do not expose or call a separate `code-review-graph` MCP server from client configs.',
36
42
  'The n-gram index is active as a bounded lexical fallback for memory, skills, repo search, and graph-unavailable routing.',
@@ -56,6 +62,7 @@ const PROTOCOL_SOURCES = [
56
62
  { source: '.agent/rules/quality-gates.md', relativePath: path.join('.agent', 'rules', 'quality-gates.md') },
57
63
  { source: '.agent/rules/agent-guardrails.md', relativePath: path.join('.agent', 'rules', 'agent-guardrails.md') },
58
64
  ];
65
+ const SKILL_BUNDLE_CLIENT_FAMILIES = new Set(['antigravity', 'hermes', 'nanoclaw', 'picoclaw']);
59
66
  export function estimateInstructionTokens(value) {
60
67
  return Math.max(1, Math.ceil(String(value || '').length / 4));
61
68
  }
@@ -128,6 +135,74 @@ function normalizeHeading(value) {
128
135
  function hashValue(value) {
129
136
  return createHash('sha1').update(value).digest('hex');
130
137
  }
138
+ function renderList(values, fallback = 'none') {
139
+ return values.length ? values.join(', ') : fallback;
140
+ }
141
+ function buildCodeQualityBlocks(input) {
142
+ const selectedFiles = dedupeStrings(input.tokenPolicy?.selectedFiles ?? []);
143
+ const verifyCommands = dedupeStrings([
144
+ ...(input.manualOverrides ?? []).filter((entry) => /npm|pnpm|yarn|test|lint|build|cargo|pytest/i.test(entry)),
145
+ ]);
146
+ const crewName = input.selectedCrew?.name ?? 'baseline';
147
+ const specialists = (input.selectedSpecialists ?? []).map((specialist) => specialist.name).filter(Boolean);
148
+ return [
149
+ {
150
+ id: 'work-packet',
151
+ title: 'Work Packet',
152
+ language: 'yaml',
153
+ purpose: 'Stable handoff for a hired worker or sub-agent.',
154
+ content: [
155
+ `goal: ${JSON.stringify(input.goal)}`,
156
+ `crew: ${JSON.stringify(crewName)}`,
157
+ `specialists: [${specialists.map((item) => JSON.stringify(item)).join(', ')}]`,
158
+ `owned_files: [${selectedFiles.map((item) => JSON.stringify(item)).join(', ')}]`,
159
+ `non_goals: ["unrelated refactors", "secret reads", "destructive git changes"]`,
160
+ `done_when: ["diff is scoped", "verification recorded", "memory write-back prepared"]`,
161
+ ].join('\n'),
162
+ },
163
+ {
164
+ id: 'implementation-notes',
165
+ title: 'Implementation Notes',
166
+ language: 'markdown',
167
+ purpose: 'Keep coding quality explicit before patching.',
168
+ content: [
169
+ '### Why',
170
+ '<one paragraph explaining the product/runtime reason>',
171
+ '',
172
+ '### What Changed',
173
+ '<short list of files and behavior changed>',
174
+ '',
175
+ '### Risk',
176
+ '<blast radius, rollback path, and compatibility notes>',
177
+ ].join('\n'),
178
+ },
179
+ {
180
+ id: 'verification-output',
181
+ title: 'Verification Output',
182
+ language: 'text',
183
+ purpose: 'Separate real command proof from assumptions.',
184
+ content: [
185
+ `commands: ${renderList(verifyCommands, 'project-specific targeted tests, then build/lint when feasible')}`,
186
+ 'passed: <true|false>',
187
+ 'known_failures: <pre-existing or new failure with file/test name>',
188
+ 'not_run: <commands skipped and why>',
189
+ ].join('\n'),
190
+ },
191
+ {
192
+ id: 'memory-writeback',
193
+ title: 'Memory Write-Back',
194
+ language: 'markdown',
195
+ purpose: 'Reusable project learning without raw secrets or noisy logs.',
196
+ content: [
197
+ 'Session YYYY-MM-DD: <what changed, why, and what remains>.',
198
+ '',
199
+ 'Tags: #session-summary #token-budget #orchestration',
200
+ 'Priority: 0.85',
201
+ 'Do not store secrets, raw credentials, or full logs.',
202
+ ].join('\n'),
203
+ },
204
+ ];
205
+ }
131
206
  function sectionPriority(source, heading) {
132
207
  const normalized = normalizeHeading(`${source} ${heading}`);
133
208
  if (normalized.includes('default operating rule'))
@@ -254,7 +329,15 @@ export class InstructionGateway {
254
329
  selectedFiles: (input.tokenPolicy?.selectedFiles ?? []).slice(0, 16),
255
330
  estimatedSavings: Number(input.tokenPolicy?.estimatedSavings ?? 0),
256
331
  estimatedCompressionPct: Number(input.tokenPolicy?.estimatedCompressionPct ?? 0),
332
+ codeBlockTemplates: (input.tokenPolicy?.codeBlockTemplates ?? [
333
+ 'work-packet',
334
+ 'implementation-notes',
335
+ 'verification-output',
336
+ 'memory-writeback',
337
+ ]).slice(0, 8),
338
+ codeBlockReservedTokens: Number(input.tokenPolicy?.codeBlockReservedTokens ?? 0),
257
339
  },
340
+ codeQualityBlocks: buildCodeQualityBlocks(input),
258
341
  memoryContext: {
259
342
  matches: (input.memoryMatches ?? []).slice(0, 3),
260
343
  stats: input.memoryStats ? {
@@ -351,7 +434,7 @@ export class InstructionGateway {
351
434
  renderEnvelope(packet, clientId) {
352
435
  const family = this.toClientFamily(clientId ?? packet.client?.clientId);
353
436
  const markdown = renderInstructionPacketMarkdown(packet);
354
- if (family === 'antigravity') {
437
+ if (SKILL_BUNDLE_CLIENT_FAMILIES.has(family)) {
355
438
  return {
356
439
  clientFamily: family,
357
440
  format: 'skill-md',
@@ -489,6 +572,12 @@ export class InstructionGateway {
489
572
  const normalized = String(clientId ?? 'codex').toLowerCase();
490
573
  if (normalized === 'openclaw' || normalized === 'antigravity')
491
574
  return 'antigravity';
575
+ if (normalized === 'hermes')
576
+ return 'hermes';
577
+ if (normalized === 'nanoclaw')
578
+ return 'nanoclaw';
579
+ if (normalized === 'picoclaw')
580
+ return 'picoclaw';
492
581
  if (normalized === 'claude-code')
493
582
  return 'claude-code';
494
583
  if (normalized === 'opencode')
@@ -505,6 +594,12 @@ export class InstructionGateway {
505
594
  const family = this.toClientFamily(clientId);
506
595
  if (family === 'antigravity')
507
596
  return 'Antigravity / OpenClaw';
597
+ if (family === 'hermes')
598
+ return 'Hermes';
599
+ if (family === 'nanoclaw')
600
+ return 'NanoClaw';
601
+ if (family === 'picoclaw')
602
+ return 'PicoClaw';
508
603
  if (family === 'claude-code')
509
604
  return 'Claude Code';
510
605
  if (family === 'opencode')
@@ -518,7 +613,7 @@ export class InstructionGateway {
518
613
  return family.charAt(0).toUpperCase() + family.slice(1);
519
614
  }
520
615
  renderBootstrapArtifacts(family, envelope, tokenLimit) {
521
- if (family === 'antigravity') {
616
+ if (SKILL_BUNDLE_CLIENT_FAMILIES.has(family)) {
522
617
  const chunks = this.chunkContent(envelope.content, tokenLimit);
523
618
  return chunks.map((chunk, index) => ({
524
619
  fileName: index === 0 ? 'SKILL.md' : `SKILL-${String(index + 1).padStart(2, '0')}.md`,
@@ -596,7 +691,9 @@ export class InstructionGateway {
596
691
  '- REQUIRED before broad reading when bootstrap did not auto-apply: call `nexus_optimize_tokens(goal, files)`.',
597
692
  '- REQUIRED before file modification or destructive work: call `nexus_mindkit_check(action, filesToModify)`.',
598
693
  '- REQUIRED before refactoring 3+ files: call `nexus_ghost_pass(goal, files)`.',
599
- '- REQUIRED after significant findings and at session end: call `nexus_store_memory(content, priority, tags)`.',
694
+ '- Memory hooks are supported: REQUIRED after significant findings, user preferences, decisions, pivots, and verification results: call `nexus_store_memory(content, priority, tags)` without secrets.',
695
+ '- Use fenced code blocks for work packets, implementation notes, verification output, and memory write-back.',
696
+ '- When Nexus selects workers, tell the user exactly what is being hired: crew, specialists, workflow, model tier, budget guardrail, and verification gate.',
600
697
  '- REQUIRED before ending the session: call `nexus_session_dna(action="generate")`.',
601
698
  '- Repo graph is internal to Nexus; do not expose a separate `code-review-graph` MCP server.',
602
699
  '- The n-gram index is active as a bounded lexical fallback for memory, skills, repo search, and graph-unavailable routing.',
@@ -639,6 +736,18 @@ export function renderInstructionPacketMarkdown(packet) {
639
736
  `- Selected Files: ${packet.tokenPolicy.selectedFiles.join(', ') || 'none'}`,
640
737
  `- Estimated Savings: ${packet.tokenPolicy.estimatedSavings}`,
641
738
  `- Estimated Compression: ${packet.tokenPolicy.estimatedCompressionPct}%`,
739
+ `- Code Block Templates: ${packet.tokenPolicy.codeBlockTemplates?.join(', ') || 'none'}`,
740
+ `- Code Block Reserve: ${packet.tokenPolicy.codeBlockReservedTokens ?? 0}`,
741
+ ``,
742
+ `## Coding Quality Blocks`,
743
+ ...packet.codeQualityBlocks.flatMap((block) => [
744
+ `### ${block.title}`,
745
+ block.purpose,
746
+ '```' + block.language,
747
+ block.content,
748
+ '```',
749
+ ``,
750
+ ]),
642
751
  ``,
643
752
  `## Governance`,
644
753
  `- Passed: ${packet.governance.passed}`,
@@ -133,6 +133,8 @@ export interface MemoryFeedbackResult {
133
133
  item?: MemorySnapshot;
134
134
  trust?: number;
135
135
  priority?: number;
136
+ decay?: MemoryDecayProfile;
137
+ reinforcement?: MemoryReinforcementProfile;
136
138
  }
137
139
  export interface MemoryRecallMatch {
138
140
  content: string;
@@ -176,6 +178,30 @@ export interface MemoryEntityReference {
176
178
  type: 'session' | 'run' | 'skill' | 'workflow';
177
179
  id: string;
178
180
  }
181
+ export type MemoryDecayState = 'fresh' | 'fading' | 'stale' | 'retiring';
182
+ export type MemoryDecayNextAction = 'keep' | 'reinforce' | 'review' | 'archive';
183
+ export interface MemoryDecayProfile {
184
+ score: number;
185
+ state: MemoryDecayState;
186
+ ageDays: number;
187
+ halfLifeDays: number;
188
+ retentionHint: MemoryRetentionHint | 'default';
189
+ nextAction: MemoryDecayNextAction;
190
+ reasons: string[];
191
+ }
192
+ export interface MemoryReinforcementProfile {
193
+ score: number;
194
+ accessCount: number;
195
+ trust: number;
196
+ feedbackCount: number;
197
+ lastFeedbackAt?: number;
198
+ qmd: {
199
+ recency: number;
200
+ frequency: number;
201
+ relevance: number;
202
+ };
203
+ reasons: string[];
204
+ }
179
205
  export interface MemorySnapshot {
180
206
  id: string;
181
207
  tier: MemoryItem['tier'];
@@ -196,6 +222,8 @@ export interface MemorySnapshot {
196
222
  freshnessScore: number;
197
223
  trustScore: number;
198
224
  entropyScore: number;
225
+ decay: MemoryDecayProfile;
226
+ reinforcement: MemoryReinforcementProfile;
199
227
  provenance: MemoryProvenance;
200
228
  expiresAt?: number;
201
229
  purgeAt?: number;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Memory Bridge — OpenClaw/Antigravity Memory Synchronization
2
+ * Memory Bridge — external agent memory synchronization
3
3
  *
4
4
  * Provides bidirectional memory sync between Nexus Prime and external agent instances.
5
5
  * Uses chunked manifest exports by default while remaining backward compatible with
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Memory Bridge — OpenClaw/Antigravity Memory Synchronization
2
+ * Memory Bridge — external agent memory synchronization
3
3
  *
4
4
  * Provides bidirectional memory sync between Nexus Prime and external agent instances.
5
5
  * Uses chunked manifest exports by default while remaining backward compatible with
@@ -267,7 +267,12 @@ export declare class MemoryEngine {
267
267
  private listVaultIndexItems;
268
268
  private listContentCheckCandidates;
269
269
  private listReconciliationCandidates;
270
+ private clamp01;
271
+ private qmdComponents;
270
272
  private computeQmdScore;
273
+ private getFeedbackStats;
274
+ private buildDecayProfile;
275
+ private buildReinforcementProfile;
271
276
  private applyRecallRerankerHint;
272
277
  private getAllItems;
273
278
  private getItemsByIds;