nexus-prime 7.9.26 → 7.9.28

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 CHANGED
@@ -38,9 +38,9 @@
38
38
  <a href="https://www.producthunt.com/products/nexus-prime?embed=true&utm_source=badge-featured&utm_medium=badge&utm_campaign=badge-nexus-prime" target="_blank" rel="noopener noreferrer"><img alt="Nexus-Prime — Product Hunt" width="250" height="54" src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=1096831&theme=dark&t=1773345508816"></a>
39
39
  </div>
40
40
 
41
- > **Coding agents were never built to remember. Nexus Prime gives them a memory.**
41
+ > **Stop restarting your coding agents from zero.**
42
42
  >
43
- > Install once. Every coding agent on your machine gets smarter together.
43
+ > Nexus Prime gives Claude Code, Codex, Cursor, Windsurf, OpenCode, Aider, and the rest of your local agent stack one shared memory, one proof trail, and one dashboard for what actually happened.
44
44
 
45
45
  ---
46
46
 
@@ -74,6 +74,18 @@ Agents should start with `nexus_session_bootstrap`, then route the raw request t
74
74
 
75
75
  ---
76
76
 
77
+ ## Why teams install it
78
+
79
+ Nexus Prime is the local-first control plane for serious AI-assisted coding.
80
+
81
+ - **Shared memory for every agent.** Your tools stop acting like strangers and start carrying useful context across sessions.
82
+ - **Lower token waste.** Nexus routes agents toward the files and facts that matter instead of rereading the repo every turn.
83
+ - **Runtime truth you can inspect.** The dashboard shows runs, memory, token savings, and agent activity instead of hiding the messy parts.
84
+ - **Safer multi-file work.** Planning, verification, and handoff state stay attached to the repo, so interrupted work is easier to resume and review.
85
+ - **Local by default.** Your code and agent memory stay on your machine unless you explicitly opt into something else.
86
+
87
+ ---
88
+
77
89
  ## The problem
78
90
 
79
91
  Every coding agent you use starts every session cold.
@@ -84,7 +96,7 @@ One tracked session was measured at **100,000,000 tokens**. Ninety-nine point fo
84
96
 
85
97
  This is **agent amnesia** — and it's the quiet tax on every hour you spend with AI-assisted coding.
86
98
 
87
- **Nexus Prime ends it.**
99
+ **Nexus Prime turns that cold start into a remembered workspace.**
88
100
 
89
101
  ---
90
102
 
@@ -447,7 +459,8 @@ Nexus Prime was designed privacy-first, because the code on your machine is your
447
459
  |---------|-------------------|
448
460
  | 💬 [**Discord**](https://discord.gg/tByGZgk5gS) | Real-time help, show-and-tell, feature ideas |
449
461
  | 🔴 [**Reddit — r/Nexus_Prime**](https://www.reddit.com/r/Nexus_Prime/) | Long-form posts, releases, community wins |
450
- | 🐦 [**X / Twitter**](https://x.com/nexusprime_ai) | Launch announcements, tips, updates |
462
+ | 🐦 [**X / Twitter**](https://x.com/getnexusprime) | Launch announcements, tips, updates |
463
+ | 📸 [**Instagram**](https://www.instagram.com/nexus_prime.cfd/) | Product clips, launch updates, behind-the-scenes |
451
464
  | 📧 [**adarsh@nexus-prime.cfd**](mailto:adarsh@nexus-prime.cfd) | License requests, upgrades, pilots, enterprise |
452
465
  | 📧 [**hello@nexus-prime.cfd**](mailto:hello@nexus-prime.cfd) | General support, press, community |
453
466
  | 🌐 [**nexus-prime.cfd**](https://nexus-prime.cfd) | Product site, demos, pricing, setup guides |
@@ -238,7 +238,7 @@ export function buildMcpToolDefinitions() {
238
238
  properties: {
239
239
  goal: { type: 'string', description: 'Raw goal or task description for this session' },
240
240
  files: { type: 'array', items: { type: 'string' }, description: 'Optional candidate file constraints' },
241
- detailLevel: { type: 'string', enum: ['compact', 'standard', 'debug'], description: 'Response verbosity; defaults to compact for MCP callers' },
241
+ detailLevel: { type: 'string', enum: ['compact', 'standard', 'debug', 'full'], description: 'Response verbosity; defaults to compact for MCP callers' },
242
242
  depth: { type: 'string', enum: ['fast', 'deep'], description: 'Optional bootstrap depth override; defaults to fast unless debug mode is requested' },
243
243
  include: { type: 'array', items: { type: 'string' }, description: 'Optional rich payload sections to include for advanced clients' },
244
244
  intent: { type: 'string', enum: ['inspect', 'plan', 'mutate'], description: 'Requested orchestration stance for the bootstrap summary' },
@@ -268,7 +268,7 @@ export function buildMcpToolDefinitions() {
268
268
  properties: {
269
269
  prompt: { type: 'string', description: 'Raw prompt or objective to orchestrate end-to-end' },
270
270
  files: { type: 'array', items: { type: 'string' }, description: 'Optional hard constraints for candidate files' },
271
- detailLevel: { type: 'string', enum: ['compact', 'standard', 'debug'], description: 'Response verbosity; defaults to compact for MCP callers' },
271
+ detailLevel: { type: 'string', enum: ['compact', 'standard', 'debug', 'full'], description: 'Response verbosity; defaults to compact for MCP callers' },
272
272
  intent: { type: 'string', enum: ['inspect', 'plan', 'mutate'], description: 'Requested orchestration stance; inspect/plan should stay read-only' },
273
273
  topology: { type: 'string', enum: ['auto', 'manager-tools', 'handoff', 'dag-pool', 'worktree-swarm'], description: 'Requested orchestration topology hint' },
274
274
  workers: { type: 'number', description: 'Optional worker override' },
@@ -282,6 +282,7 @@ export function buildMcpToolDefinitions() {
282
282
  executionPreset: { type: 'string', enum: ['fast', 'balanced', 'deep', 'release'], description: 'Optional execution preset that maps orchestration depth, verification strictness, and backend routing' },
283
283
  background: { type: 'boolean', description: 'Compatibility flag; nexus_orchestrate already returns a queued hiring preflight by default and continues in the async gate.' },
284
284
  async: { type: 'boolean', description: 'Alias for background; useful for clients that prefer explicit async orchestration.' },
285
+ wait: { type: 'boolean', description: 'Alias for inline/sync execution. Waits up to the MCP-safe bounded window and returns the final result when it completes in time.' },
285
286
  waitMs: { type: 'number', description: 'Advanced/debug bounded wait for inline execution. Clamped to 45 seconds; normal orchestrate calls return a queued preflight immediately.' },
286
287
  inline: { type: 'boolean', description: 'Advanced/debug only: wait for inline orchestrate output instead of the default fast queued preflight.' }
287
288
  },
@@ -101,7 +101,10 @@ function shouldReturnQueuedReceipt(toolName, args) {
101
101
  if (!SLOW_TOOLS.has(toolName))
102
102
  return false;
103
103
  if (toolName === 'nexus_orchestrate') {
104
- return !isTruthyFlag(args.inline) && !isTruthyFlag(args.sync) && !isTruthyFlag(args.blocking);
104
+ return !isTruthyFlag(args.inline)
105
+ && !isTruthyFlag(args.sync)
106
+ && !isTruthyFlag(args.blocking)
107
+ && !isTruthyFlag(args.wait);
105
108
  }
106
109
  return isTruthyFlag(args.background)
107
110
  || isTruthyFlag(args.async)
@@ -109,8 +112,13 @@ function shouldReturnQueuedReceipt(toolName, args) {
109
112
  || isTruthyFlag(args.detach);
110
113
  }
111
114
  function resolveMaxSyncMs(toolName, args) {
115
+ const explicitWait = isTruthyFlag(args.wait)
116
+ || isTruthyFlag(args.inline)
117
+ || isTruthyFlag(args.sync)
118
+ || isTruthyFlag(args.blocking);
112
119
  return coerceBoundedWaitMs(args.waitMs)
113
120
  ?? coerceBoundedWaitMs(args.maxSyncMs)
121
+ ?? (toolName === 'nexus_orchestrate' && explicitWait ? MAX_CLIENT_SYNC_WAIT_MS : undefined)
114
122
  ?? (toolName === 'nexus_orchestrate' ? ORCHESTRATE_DEFAULT_MAX_SYNC_MS : DEFAULT_MAX_SYNC_MS);
115
123
  }
116
124
  function asStringList(value) {
@@ -22,6 +22,8 @@ function renderTable(rows, maxRows = 20) {
22
22
  }
23
23
  /** Build a compact timing + savings footer line for tool responses. */
24
24
  function buildMcpFooter(meta) {
25
+ if (process.env.NEXUS_MCP_RESPONSE_FOOTER !== '1')
26
+ return '';
25
27
  const ms = meta.durationMs;
26
28
  const timing = ms < 1000 ? `${ms}ms` : `${(ms / 1000).toFixed(1)}s`;
27
29
  return `\n\n─── nexus-prime · ${meta.toolName} · ${timing} · dashboard: http://localhost:${DASH_PORT}/#runtime ───`;
@@ -275,7 +275,8 @@ export async function handleOrchestrationGroup(toolName, hctx, request, args, ct
275
275
  const timings = {
276
276
  totalMs: Date.now() - callStartedAt,
277
277
  };
278
- const payload = detailLevel === 'debug'
278
+ const fullBootstrapDetails = detailLevel === 'debug' || detailLevel === 'full';
279
+ const payload = fullBootstrapDetails
279
280
  ? {
280
281
  depth: bootstrap.depth,
281
282
  workspace,
@@ -390,7 +391,7 @@ export async function handleOrchestrationGroup(toolName, hctx, request, args, ct
390
391
  return '';
391
392
  }
392
393
  })(),
393
- ...(detailLevel === 'debug' ? [
394
+ ...(fullBootstrapDetails ? [
394
395
  `Bootstrap depth: ${bootstrap.depth || bootstrapDepth}`,
395
396
  `Execution mode: ${bootstrap.recommendedExecutionMode || 'autonomous'}`,
396
397
  `Shortlist: ${bootstrap.shortlist?.skills?.slice(0, 3).join(', ') || 'none'} (skills), ${bootstrap.shortlist?.specialists?.slice(0, 3).join(', ') || 'none'} (specialists)`,
@@ -410,7 +411,7 @@ export async function handleOrchestrationGroup(toolName, hctx, request, args, ct
410
411
  `Bootstrap status: ${bootstrap.clientBootstrapStatus?.clients?.length || 0} client manifests tracked`,
411
412
  ] : []),
412
413
  ]),
413
- detailLevel === 'debug' && bootstrap.tokenOptimization?.autoApplied && bootstrap.tokenOptimization?.plan
414
+ fullBootstrapDetails && bootstrap.tokenOptimization?.autoApplied && bootstrap.tokenOptimization?.plan
414
415
  ? `Auto token plan\n\`\`\`txt\n${bootstrap.tokenOptimization.plan}\n\`\`\``
415
416
  : '',
416
417
  formatJsonDetails('Structured details', payload),
@@ -547,7 +548,36 @@ export async function handleOrchestrationGroup(toolName, hctx, request, args, ct
547
548
  intent: requestedIntent,
548
549
  topology: requestedTopology,
549
550
  };
551
+ const verboseDetails = detailLevel === 'debug' || detailLevel === 'full';
550
552
  const compactPayload = {
553
+ workspace,
554
+ runId: execution.runId,
555
+ state: execution.state,
556
+ summary: summarizeExecution(execution),
557
+ resultPreview: truncateText(execution.result || summarizeExecution(execution), 700),
558
+ artifactsPath: execution.artifactsPath,
559
+ planner: execution.plannerState
560
+ ? {
561
+ selectedCrew: execution.plannerState.selectedCrew?.name,
562
+ selectedSpecialists: execution.plannerState.selectedSpecialists.slice(0, 4).map((specialist) => specialist.name),
563
+ selectedWorkflows: execution.plannerState.selectedWorkflows.slice(0, 4),
564
+ }
565
+ : undefined,
566
+ worktreeHealth: runtimeUsage.worktreeHealth
567
+ ? {
568
+ repoRoot: runtimeUsage.worktreeHealth.repoRoot,
569
+ overall: runtimeUsage.worktreeHealth.overall,
570
+ brokenEntries: runtimeUsage.worktreeHealth.brokenEntries,
571
+ repairedEntries: runtimeUsage.worktreeHealth.repairedEntries,
572
+ issues: runtimeUsage.worktreeHealth.issues,
573
+ }
574
+ : undefined,
575
+ modelRoute: selectionSummary.modelRoute,
576
+ verifiedWorkers,
577
+ continuationChildren: execution.continuationChildren.length,
578
+ timings,
579
+ };
580
+ const standardPayload = {
551
581
  workspace,
552
582
  runId: execution.runId,
553
583
  state: execution.state,
@@ -616,31 +646,43 @@ export async function handleOrchestrationGroup(toolName, hctx, request, args, ct
616
646
  timings,
617
647
  payloadRef,
618
648
  };
619
- const payload = detailLevel === 'debug' ? debugPayload : compactPayload;
649
+ const payload = verboseDetails
650
+ ? debugPayload
651
+ : detailLevel === 'standard'
652
+ ? standardPayload
653
+ : compactPayload;
654
+ const verboseResponse = detailLevel !== 'compact';
655
+ const stateLine = execution.state === 'inspected'
656
+ ? 'Orchestrated run inspected (read-only advisory; no diff expected).'
657
+ : `Orchestrated run ${execution.state}.`;
620
658
  return {
621
659
  content: [{
622
660
  type: 'text',
623
661
  text: [
624
662
  upfrontTokenNote ? `[Token plan] ${upfrontTokenNote}` : '',
625
- `Orchestrated run ${execution.state}.`,
663
+ stateLine,
626
664
  formatBullets([
627
665
  `Workspace: ${workspace.repoName} (${workspace.workspaceSource})`,
628
666
  `Run ID: ${execution.runId}`,
629
667
  `Summary: ${summarizeExecution(execution)}`,
630
668
  `Crew: ${execution.plannerState?.selectedCrew?.name || 'baseline path'}`,
631
- `Decomposition: ${selectionSummary.phaseCount} phase(s), ${selectionSummary.workerLaneCount} worker lane(s), ${selectionSummary.mode}`,
632
669
  `Hired/selected: crew ${selectionSummary.crew}; specialists ${formatSelectionList(selectionSummary.specialists)}; workflows ${formatSelectionList(selectionSummary.workflows)}; skills ${formatSelectionList(selectionSummary.skills)}`,
633
- `Model route: ${formatModelRoute(selectionSummary.modelRoute)}`,
634
- `Budget route: ${selectionSummary.budgetRoute || 'budget pending'}`,
635
- selectionSummary.agentFlow?.stages?.length
636
- ? `AgentFlow gates: ${selectionSummary.agentFlow.stages.map((stage) => `${stage.stage}:${stage.ownerRole}`).join(' -> ')}`
637
- : null,
638
- `Selection audit: ${selectionSummary.auditSelected} selected, ${selectionSummary.auditRejected} rejected`,
670
+ ...(verboseResponse ? [
671
+ `Decomposition: ${selectionSummary.phaseCount} phase(s), ${selectionSummary.workerLaneCount} worker lane(s), ${selectionSummary.mode}`,
672
+ `Model route: ${formatModelRoute(selectionSummary.modelRoute)}`,
673
+ `Budget route: ${selectionSummary.budgetRoute || 'budget pending'}`,
674
+ selectionSummary.agentFlow?.stages?.length
675
+ ? `AgentFlow gates: ${selectionSummary.agentFlow.stages.map((stage) => `${stage.stage}:${stage.ownerRole}`).join(' -> ')}`
676
+ : null,
677
+ `Selection audit: ${selectionSummary.auditSelected} selected, ${selectionSummary.auditRejected} rejected`,
678
+ ] : [
679
+ `Model route: ${formatModelRoute(selectionSummary.modelRoute)}`,
680
+ ]),
639
681
  `Verification: ${verifiedWorkers}/${execution.workerResults.length} worker(s) verified`,
640
- `Tokens: saved ${Number(execution.tokenTelemetry?.savedTokens || 0).toLocaleString()} · compression ${Number(execution.tokenTelemetry?.compressionPct || 0)}%`,
682
+ verboseResponse ? `Tokens: saved ${Number(execution.tokenTelemetry?.savedTokens || 0).toLocaleString()} · compression ${Number(execution.tokenTelemetry?.compressionPct || 0)}%` : null,
641
683
  autoTokenApplyNote || null,
642
- `Payload ref: ${workspace.stateKey} · ${detailLevel}`,
643
- ...(detailLevel === 'debug' ? [
684
+ verboseResponse ? `Payload ref: ${workspace.stateKey} · ${detailLevel}` : null,
685
+ ...(verboseDetails ? [
644
686
  `Specialists: ${execution.plannerState?.selectedSpecialists.map((specialist) => specialist.name).slice(0, 4).join(', ') || 'none selected'}`,
645
687
  `Assets: ${(execution.activeSkills || []).length} skills · ${(execution.activeWorkflows || []).length} workflows · ${(runtimeUsage.artifactSelectionAudit?.selected?.length || 0)} audited selections`,
646
688
  `Task graph: ${runtimeUsage.taskGraph?.phases?.length || execution.taskGraph?.phases?.length || 0} phases · ${runtimeUsage.workerPlan?.totalWorkers || execution.workerPlan?.totalWorkers || 0} workers`,
@@ -652,9 +694,9 @@ export async function handleOrchestrationGroup(toolName, hctx, request, args, ct
652
694
  `Payload ref: ${workspace.stateKey} · ${detailLevel}`,
653
695
  ] : []),
654
696
  ]),
655
- detailLevel === 'debug' && execution.result ? `Result\n\`\`\`\n${execution.result}\n\`\`\`` : `Result preview\n\`\`\`\n${truncateText(execution.result || summarizeExecution(execution), 900)}\n\`\`\``,
697
+ verboseDetails && execution.result ? `Result\n\`\`\`\n${execution.result}\n\`\`\`` : `Result preview\n\`\`\`\n${truncateText(execution.result || summarizeExecution(execution), 900)}\n\`\`\``,
656
698
  formatJsonDetails('Structured details', payload),
657
- hctx.formatRemainingProtocolSteps(),
699
+ verboseResponse ? hctx.formatRemainingProtocolSteps() : '',
658
700
  ].filter(Boolean).join('\n\n'),
659
701
  }],
660
702
  };
@@ -684,7 +726,7 @@ export async function handleOrchestrationGroup(toolName, hctx, request, args, ct
684
726
  runtimeUsage?.skipReasons?.length ? `Skipped stages: ${runtimeUsage.skipReasons.join(' · ')}` : 'Skipped stages: not recorded',
685
727
  ]),
686
728
  formatJsonDetails('Structured details', payload),
687
- hctx.formatRemainingProtocolSteps(),
729
+ detailLevel !== 'compact' ? hctx.formatRemainingProtocolSteps() : '',
688
730
  ].join('\n\n'),
689
731
  }],
690
732
  };
@@ -90,7 +90,7 @@ export function formatJsonDetails(label, value) {
90
90
  }
91
91
  export function normalizeDetailLevel(value) {
92
92
  const normalized = String(value ?? 'compact').toLowerCase();
93
- if (normalized === 'standard' || normalized === 'debug')
93
+ if (normalized === 'standard' || normalized === 'debug' || normalized === 'full')
94
94
  return normalized;
95
95
  return 'compact';
96
96
  }
@@ -100,7 +100,7 @@ export function normalizeBootstrapDepth(value, detailLevel) {
100
100
  return 'deep';
101
101
  if (normalized === 'fast')
102
102
  return 'fast';
103
- return detailLevel === 'debug' ? 'deep' : 'fast';
103
+ return detailLevel === 'debug' || detailLevel === 'full' ? 'deep' : 'fast';
104
104
  }
105
105
  export function normalizeResponseIntent(value) {
106
106
  const normalized = String(value ?? 'inspect').toLowerCase();
@@ -14,7 +14,7 @@ import type { SessionDNAManager } from '../../../engines/session-dna.js';
14
14
  import type { NgramIndex } from '../../../engines/ngram-index.js';
15
15
  export type McpToolProfile = 'autonomous' | 'full';
16
16
  export type LifecyclePhase = 'pre-bootstrap' | 'bootstrapped' | 'orchestrated' | 'working' | 'closing';
17
- export type ResponseDetailLevel = 'compact' | 'standard' | 'debug';
17
+ export type ResponseDetailLevel = 'compact' | 'standard' | 'debug' | 'full';
18
18
  export type ResponseIntent = 'inspect' | 'plan' | 'mutate';
19
19
  export type ResponseTopology = 'auto' | 'manager-tools' | 'handoff' | 'dag-pool' | 'worktree-swarm';
20
20
  /** Session-level telemetry tracker. Moved to types.ts so handler files can
package/dist/cli.js CHANGED
@@ -40,6 +40,7 @@ import { runReset } from './cli/reset.js';
40
40
  import { runUninstall } from './cli/uninstall.js';
41
41
  import { runCleanup } from './cli/cleanup.js';
42
42
  import { runDoctorStorage } from './cli/doctor-storage.js';
43
+ import { formatNexusProofReport, verifyNexusProof } from './engines/nexus-proof.js';
43
44
  const tokenEngine = new TokenSupremacyEngine();
44
45
  import { getNexusHookSpec, writeNexusClaudeCodeHooks, } from './install/claude-code-hooks.js';
45
46
  /**
@@ -1886,6 +1887,34 @@ program
1886
1887
  nexus = null;
1887
1888
  }
1888
1889
  });
1890
+ program
1891
+ .command('proof')
1892
+ .description('Inspect Nexus Prime provenance, signatures, and opt-in proof telemetry')
1893
+ .addCommand(new Command('verify')
1894
+ .description('Verify Nexus Prime PR presence, generated commit trailers, artifact signatures, and telemetry redaction')
1895
+ .option('--repo-root <path>', 'Repo root to verify (default: cwd)')
1896
+ .option('--pr-body <path>', 'Generated pull request body markdown to verify')
1897
+ .option('--commit-message <path>', 'Generated commit message file to verify')
1898
+ .option('--artifact <path...>', 'Generated artifact/document files to verify')
1899
+ .option('--strict', 'Treat warnings as failures')
1900
+ .option('--json', 'Output raw JSON')
1901
+ .action(async (options) => {
1902
+ const summary = await verifyNexusProof({
1903
+ repoRoot: options.repoRoot ? path.resolve(options.repoRoot) : getWorkspaceRoot(),
1904
+ prBodyPath: options.prBody ? path.resolve(options.prBody) : undefined,
1905
+ commitMessagePath: options.commitMessage ? path.resolve(options.commitMessage) : undefined,
1906
+ artifactPaths: (options.artifact ?? []).map((artifactPath) => path.resolve(artifactPath)),
1907
+ });
1908
+ if (options.json) {
1909
+ console.log(JSON.stringify(summary, null, 2));
1910
+ }
1911
+ else {
1912
+ console.log(formatNexusProofReport(summary));
1913
+ }
1914
+ if (summary.failed > 0 || (options.strict && summary.warnings > 0)) {
1915
+ process.exitCode = 1;
1916
+ }
1917
+ }));
1889
1918
  program
1890
1919
  .command('memory-hygiene')
1891
1920
  .description('Inspect or apply memory hygiene to reduce duplicate and low-signal memories')
@@ -57,10 +57,20 @@ export function render(data) {
57
57
  const synapseHealth = Array.isArray(data.synapseHealth) ? data.synapseHealth : [];
58
58
  const approvals = Array.isArray(data.synapseApprovals) ? data.synapseApprovals : [];
59
59
  const escalations = Array.isArray(data.architectsEscalations) ? data.architectsEscalations : [];
60
+ const nexusProof = data.nexusProof ?? {};
60
61
 
61
62
  container.innerHTML = `
62
63
  <div class="trust-grid">
63
64
 
65
+ <!-- Nexus Prime proof card -->
66
+ <div class="card trust-card trust-card-wide">
67
+ <div class="trust-card-hd">
68
+ <span class="trust-card-title">Nexus Prime proof</span>
69
+ <span class="chip ${nexusProof.status === 'verified' ? 'chip-ok' : nexusProof.status === 'failed' ? 'chip-bad' : 'chip-warn'}">${esc(nexusProof.status ?? 'unknown')}</span>
70
+ </div>
71
+ ${_nexusProofSection(nexusProof)}
72
+ </div>
73
+
64
74
  <!-- Security posture card -->
65
75
  <div class="card trust-card">
66
76
  <div class="trust-card-hd">
@@ -188,6 +198,37 @@ function _postureRows(gov) {
188
198
  ).join('');
189
199
  }
190
200
 
201
+ function _nexusProofSection(proof) {
202
+ const telemetry = proof.telemetry ?? {};
203
+ const totals = telemetry.localTotals ?? {};
204
+ const checks = Array.isArray(proof.checks) ? proof.checks : [];
205
+ const events = Array.isArray(proof.proofEvents) ? proof.proofEvents : [];
206
+ return `
207
+ <div class="trust-posture-body">
208
+ <div class="trust-row"><span class="trust-row-k">Website</span><span class="trust-row-v">${esc(proof.website ?? 'https://nexus-prime.cfd/')}</span></div>
209
+ <div class="trust-row"><span class="trust-row-k">Checks</span><span class="trust-row-v">${esc(`${proof.passed ?? 0} passed · ${proof.warnings ?? 0} warning(s) · ${proof.failed ?? 0} failed`)}</span></div>
210
+ <div class="trust-row"><span class="trust-row-k">Telemetry</span><span class="trust-row-v">${telemetry.optedIn ? 'opted in' : 'off'} · ${telemetry.endpointConfigured ? 'endpoint ready' : 'local only'}</span></div>
211
+ <div class="trust-row"><span class="trust-row-k">Proof events</span><span class="trust-row-v">${esc(`${totals.prPresence ?? 0} PR · ${totals.commitAttributions ?? 0} commit · ${totals.documentsSigned ?? 0} doc · ${totals.releasesVerified ?? 0} release`)}</span></div>
212
+ </div>
213
+ <div class="trust-event-list" style="margin-top:10px">
214
+ ${checks.slice(0, 6).map(check => _proofCheckRow(check)).join('')}
215
+ </div>
216
+ <div class="empty-sub" style="margin-top:8px">${esc(events.slice(0, 6).join(' · '))}</div>
217
+ `;
218
+ }
219
+
220
+ function _proofCheckRow(check) {
221
+ const chip = check.status === 'pass' ? 'chip-ok' : check.status === 'fail' ? 'chip-bad' : 'chip-warn';
222
+ return `
223
+ <div class="trust-event-row">
224
+ <div class="trust-event-main">
225
+ <span class="chip ${chip}">${esc(check.status ?? 'unknown')}</span>
226
+ <span class="trust-event-type">${esc(check.label ?? check.id ?? 'proof check')}</span>
227
+ ${check.detail ? `<span style="color:var(--text-muted);font-size:var(--text-sm)">${esc(String(check.detail).slice(0, 110))}</span>` : ''}
228
+ </div>
229
+ </div>`;
230
+ }
231
+
191
232
  function _auditRow(e, idx) {
192
233
  return `
193
234
  <div class="trust-event-row">
@@ -1,4 +1,6 @@
1
1
  import { getSharedGovernor } from '../../engines/machine-efficiency/index.js';
2
+ import { verifyNexusProof } from '../../engines/nexus-proof.js';
3
+ import { getSharedTelemetry } from '../../engines/telemetry-remote.js';
2
4
  import { serializeMemoryAudit, serializeMemoryQuarantine } from '../serializers/memory-serializer.js';
3
5
  import { collectDashboardBaseState } from './summary-selector.js';
4
6
  export async function buildTrustSurface(ctx, url) {
@@ -7,6 +9,8 @@ export async function buildTrustSurface(ctx, url) {
7
9
  const governorState = governor.getState();
8
10
  const synapseTeams = ctx.getSynapse()?.getStrikeTeamStatus?.();
9
11
  const synapseHealth = ctx.getSynapse()?.getOperativeHealth?.();
12
+ const telemetryStats = getSharedTelemetry().getStats();
13
+ const proofSummary = await verifyNexusProof({ repoRoot: ctx.repoRoot });
10
14
  return {
11
15
  repoIdentity: state.snapshot?.repoIdentity ?? ctx.getSelectedRepoIdentity(url),
12
16
  usage: state.usage,
@@ -29,6 +33,22 @@ export async function buildTrustSurface(ctx, url) {
29
33
  : ctx.getClientRegistry()?.listClients(ctx.getAdapters()) ?? [],
30
34
  primaryClient: state.snapshot?.clients?.primary ?? ctx.getClientRegistry()?.getPrimaryClient(ctx.getAdapters()) ?? null,
31
35
  nexusLayer: state.layer?.getSummary(state.snapshot?.orchestration?.sessionId) ?? null,
36
+ nexusProof: {
37
+ ...proofSummary,
38
+ telemetry: {
39
+ optedIn: telemetryStats.optedIn,
40
+ queuedEvents: telemetryStats.queuedEvents,
41
+ endpointConfigured: telemetryStats.endpointConfigured,
42
+ remoteStatsConfigured: telemetryStats.remoteStatsConfigured,
43
+ localTotals: {
44
+ prPresence: telemetryStats.totalPrPresence,
45
+ commitAttributions: telemetryStats.totalCommitAttributions,
46
+ documentsSigned: telemetryStats.totalDocumentsSigned,
47
+ releasesVerified: telemetryStats.totalReleasesVerified,
48
+ proofBadgeViews: telemetryStats.totalProofBadgeViews,
49
+ },
50
+ },
51
+ },
32
52
  machinePressure: governorState.pressureLevel,
33
53
  activeWorktrees: governorState.activeWorktrees,
34
54
  governor: governorState,
@@ -268,6 +268,7 @@ export interface TrustSurfaceDTO {
268
268
  clients: unknown[];
269
269
  primaryClient: unknown;
270
270
  nexusLayer: unknown;
271
+ nexusProof: unknown;
271
272
  machinePressure: PressureLevel;
272
273
  activeWorktrees: number;
273
274
  governor: GovernorState;
@@ -1,3 +1,4 @@
1
+ import { type RemoteTelemetry } from './telemetry-remote.js';
1
2
  export interface GithubBridgeDetection {
2
3
  available: boolean;
3
4
  method: 'gh-cli' | 'token' | 'none';
@@ -21,7 +22,8 @@ export interface GithubPromotionResult {
21
22
  }
22
23
  export declare class GithubBridge {
23
24
  private readonly defaultCwd;
24
- constructor(defaultCwd?: string);
25
+ private readonly telemetry?;
26
+ constructor(defaultCwd?: string, telemetry?: Pick<RemoteTelemetry, 'trackProductEvent'>);
25
27
  detect(cwd?: string): GithubBridgeDetection;
26
28
  promoteToPR(input: GithubPromotionInput): Promise<GithubPromotionResult>;
27
29
  private createPullRequestViaApi;
@@ -29,6 +31,7 @@ export declare class GithubBridge {
29
31
  private resolveRepo;
30
32
  private detectBaseBranch;
31
33
  private buildBranchName;
34
+ private renderCommitBody;
32
35
  private renderPrBody;
33
36
  private safeExec;
34
37
  shareAsGist(pattern: {
@@ -40,5 +43,7 @@ export declare class GithubBridge {
40
43
  localPath?: string;
41
44
  }>;
42
45
  private shellQuote;
46
+ private telemetryConsentLabel;
47
+ private trackProductEvent;
43
48
  }
44
49
  export declare function getSharedGithubBridge(cwd?: string): GithubBridge;
@@ -3,10 +3,14 @@ import * as path from 'path';
3
3
  import { execSync } from 'child_process';
4
4
  import { createHash } from 'crypto';
5
5
  import { resolveNexusStateDir } from './runtime-registry.js';
6
+ import { appendOrReplaceNexusPrPresenceBlock, buildNexusProofMetadata, ensureNexusCoauthorTrailer, NEXUS_PRIME_COAUTHOR_TRAILER, NEXUS_PRIME_WEBSITE, renderNexusDocumentSignature, renderNexusPrPresenceBlock, } from './nexus-signature.js';
7
+ import { getSharedTelemetry } from './telemetry-remote.js';
6
8
  export class GithubBridge {
7
9
  defaultCwd;
8
- constructor(defaultCwd = process.cwd()) {
10
+ telemetry;
11
+ constructor(defaultCwd = process.cwd(), telemetry) {
9
12
  this.defaultCwd = defaultCwd;
13
+ this.telemetry = telemetry;
10
14
  }
11
15
  detect(cwd = this.defaultCwd) {
12
16
  try {
@@ -42,20 +46,34 @@ export class GithubBridge {
42
46
  this.safeExec(`git checkout -b ${this.shellQuote(branch)}`, cwd, true);
43
47
  this.safeExec('git add -A', cwd, true);
44
48
  const subject = `[NOVA] Promote Darwin cycle ${input.cycleId ?? 'candidate'} to the fleet`;
45
- const body = [
46
- 'The autonomous engine marked this bounded improvement worthy of review.',
47
- `Hypothesis: ${input.hypothesis}`,
48
- ...(input.learnings?.length ? [`Learnings: ${input.learnings.join('; ')}`] : []),
49
- ].join('\n\n');
49
+ const body = ensureNexusCoauthorTrailer(this.renderCommitBody(input), true);
50
50
  this.safeExec(`git commit -m ${this.shellQuote(subject)} -m ${this.shellQuote(body)}`, cwd, true);
51
+ this.trackProductEvent('commit_attributed', {
52
+ surface: 'git_commit',
53
+ role: 'published',
54
+ method: detection.method,
55
+ attribution: 'coauthor_trailer',
56
+ });
51
57
  this.safeExec(`git push -u origin ${this.shellQuote(branch)}`, cwd, true);
52
58
  if (detection.method === 'gh-cli') {
53
59
  const title = `Darwin: ${input.hypothesis}`.slice(0, 72);
54
60
  const prBody = this.renderPrBody(input, diffSummary, baseBranch);
55
61
  const url = this.safeExec(`gh pr create --base ${this.shellQuote(baseBranch)} --head ${this.shellQuote(branch)} --title ${this.shellQuote(title)} --body ${this.shellQuote(prBody)}`, cwd, true).trim();
62
+ this.trackProductEvent('pr_presence_added', {
63
+ surface: 'pull_request',
64
+ role: 'published',
65
+ method: detection.method,
66
+ verification: 'local_diff_captured',
67
+ });
56
68
  return { status: 'pr_created', method: detection.method, branch, url };
57
69
  }
58
70
  const url = await this.createPullRequestViaApi(repo.owner, repo.name, branch, baseBranch, input, diffSummary);
71
+ this.trackProductEvent('pr_presence_added', {
72
+ surface: 'pull_request',
73
+ role: 'published',
74
+ method: detection.method,
75
+ verification: 'local_diff_captured',
76
+ });
59
77
  return { status: 'pr_created', method: detection.method, branch, url };
60
78
  }
61
79
  catch (error) {
@@ -100,6 +118,21 @@ export class GithubBridge {
100
118
  .slice(0, 10);
101
119
  const patchPath = path.join(stateDir, `darwin-${slug}.patch`);
102
120
  const artifactPath = path.join(stateDir, `darwin-${slug}.json`);
121
+ const signatureInput = {
122
+ source: 'github-bridge',
123
+ role: 'observed',
124
+ runId: input.cycleId,
125
+ cycleId: input.cycleId,
126
+ verificationState: diffPatch.trim() ? 'advisory' : 'not-run',
127
+ hooksState: 'not-applicable',
128
+ telemetryConsent: this.telemetryConsentLabel(),
129
+ humanReviewState: 'required',
130
+ coauthorState: 'Not claimed because no GitHub PR was created.',
131
+ };
132
+ const documentSignature = renderNexusDocumentSignature({
133
+ ...signatureInput,
134
+ artifactKind: 'GitHub promotion artifact',
135
+ });
103
136
  fs.writeFileSync(patchPath, diffPatch, 'utf8');
104
137
  fs.writeFileSync(artifactPath, JSON.stringify({
105
138
  createdAt: new Date().toISOString(),
@@ -111,7 +144,20 @@ export class GithubBridge {
111
144
  learnings: input.learnings ?? [],
112
145
  diffSummary,
113
146
  patchPath,
147
+ nexusPrime: {
148
+ website: NEXUS_PRIME_WEBSITE,
149
+ coauthorTrailer: NEXUS_PRIME_COAUTHOR_TRAILER,
150
+ prPresence: renderNexusPrPresenceBlock(signatureInput),
151
+ documentSignature,
152
+ metadata: buildNexusProofMetadata(signatureInput),
153
+ },
114
154
  }, null, 2), 'utf8');
155
+ this.trackProductEvent('document_signed', {
156
+ surface: 'github_promotion_artifact',
157
+ role: 'observed',
158
+ method,
159
+ status: 'artifact_saved',
160
+ });
115
161
  return {
116
162
  status: 'artifact_saved',
117
163
  method,
@@ -140,8 +186,15 @@ export class GithubBridge {
140
186
  .slice(0, 48);
141
187
  return `ad/${seed || 'darwin-candidate'}`;
142
188
  }
143
- renderPrBody(input, diffSummary, baseBranch) {
189
+ renderCommitBody(input) {
144
190
  return [
191
+ 'The autonomous engine marked this bounded improvement worthy of review.',
192
+ `Hypothesis: ${input.hypothesis}`,
193
+ ...(input.learnings?.length ? [`Learnings: ${input.learnings.join('; ')}`] : []),
194
+ ].join('\n\n');
195
+ }
196
+ renderPrBody(input, diffSummary, baseBranch) {
197
+ const body = [
145
198
  '### Mission Briefing',
146
199
  'A bounded Darwin candidate completed local validation and now seeks human review through the standard GitHub path.',
147
200
  '',
@@ -159,6 +212,17 @@ export class GithubBridge {
159
212
  diffSummary.trim() || 'No diff summary available.',
160
213
  '```',
161
214
  ].join('\n');
215
+ return appendOrReplaceNexusPrPresenceBlock(body, {
216
+ source: 'github-bridge',
217
+ role: 'published',
218
+ runId: input.cycleId,
219
+ cycleId: input.cycleId,
220
+ verificationState: diffSummary.trim() ? 'advisory' : 'unknown',
221
+ hooksState: 'unknown',
222
+ telemetryConsent: this.telemetryConsentLabel(),
223
+ humanReviewState: 'required',
224
+ coauthorState: 'Required on the Nexus-generated promotion commit.',
225
+ });
162
226
  }
163
227
  safeExec(command, cwd, throwOnError = false) {
164
228
  try {
@@ -233,6 +297,26 @@ export class GithubBridge {
233
297
  shellQuote(value) {
234
298
  return `'${value.replace(/'/g, `'\\''`)}'`;
235
299
  }
300
+ telemetryConsentLabel() {
301
+ try {
302
+ const telemetry = this.telemetry ?? getSharedTelemetry();
303
+ return telemetry instanceof Object && 'isOptedIn' in telemetry && typeof telemetry.isOptedIn === 'function'
304
+ ? (telemetry.isOptedIn() ? 'opted-in' : 'disabled')
305
+ : 'unknown';
306
+ }
307
+ catch {
308
+ return 'unknown';
309
+ }
310
+ }
311
+ trackProductEvent(type, metadata) {
312
+ try {
313
+ const telemetry = this.telemetry ?? getSharedTelemetry();
314
+ telemetry.trackProductEvent(type, metadata);
315
+ }
316
+ catch {
317
+ // Telemetry must never block promotion or artifact persistence.
318
+ }
319
+ }
236
320
  }
237
321
  let _sharedGithubBridge = null;
238
322
  export function getSharedGithubBridge(cwd) {
@@ -0,0 +1,26 @@
1
+ export type NexusProofCheckStatus = 'pass' | 'warn' | 'fail';
2
+ export interface NexusProofCheck {
3
+ id: string;
4
+ label: string;
5
+ status: NexusProofCheckStatus;
6
+ detail: string;
7
+ evidence?: string;
8
+ }
9
+ export interface NexusProofVerifyOptions {
10
+ repoRoot?: string;
11
+ prBodyPath?: string;
12
+ commitMessagePath?: string;
13
+ artifactPaths?: string[];
14
+ }
15
+ export interface NexusProofSummary {
16
+ generatedAt: number;
17
+ website: string;
18
+ status: 'verified' | 'attention' | 'failed';
19
+ passed: number;
20
+ warnings: number;
21
+ failed: number;
22
+ checks: NexusProofCheck[];
23
+ proofEvents: readonly string[];
24
+ }
25
+ export declare function verifyNexusProof(options?: NexusProofVerifyOptions): Promise<NexusProofSummary>;
26
+ export declare function formatNexusProofReport(summary: NexusProofSummary): string;
@@ -0,0 +1,118 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ import { NEXUS_PLG_EVENT_TYPES, NEXUS_PRIME_COAUTHOR_TRAILER, NEXUS_PRIME_PRESENCE_END, NEXUS_PRIME_PRESENCE_START, NEXUS_PRIME_WEBSITE, } from './nexus-signature.js';
4
+ async function readOptional(filePath) {
5
+ if (!filePath)
6
+ return null;
7
+ try {
8
+ return await fs.readFile(filePath, 'utf8');
9
+ }
10
+ catch {
11
+ return null;
12
+ }
13
+ }
14
+ function addCheck(checks, id, label, status, detail, evidence) {
15
+ checks.push({ id, label, status, detail, evidence });
16
+ }
17
+ function hasPresenceBlock(value) {
18
+ return value.includes(NEXUS_PRIME_PRESENCE_START) && value.includes(NEXUS_PRIME_PRESENCE_END);
19
+ }
20
+ export async function verifyNexusProof(options = {}) {
21
+ const repoRoot = options.repoRoot ?? process.cwd();
22
+ const checks = [];
23
+ const prTemplatePath = path.join(repoRoot, '.github', 'pull_request_template.md');
24
+ const readmePath = path.join(repoRoot, 'README.md');
25
+ const telemetryPath = path.join(repoRoot, 'src', 'engines', 'telemetry-remote.ts');
26
+ addCheck(checks, 'website.identity', 'Website identity', NEXUS_PRIME_WEBSITE === 'https://nexus-prime.cfd/' ? 'pass' : 'fail', `Expected canonical website https://nexus-prime.cfd/, got ${NEXUS_PRIME_WEBSITE}`, NEXUS_PRIME_WEBSITE);
27
+ const prTemplate = await readOptional(prTemplatePath);
28
+ if (!prTemplate) {
29
+ addCheck(checks, 'pr.template', 'PR template presence', 'warn', 'No .github/pull_request_template.md found.');
30
+ }
31
+ else {
32
+ const ok = hasPresenceBlock(prTemplate) && prTemplate.includes(NEXUS_PRIME_WEBSITE);
33
+ addCheck(checks, 'pr.template', 'PR template presence', ok ? 'pass' : 'fail', ok
34
+ ? 'Pull request template contains Nexus Prime Presence and website identity.'
35
+ : 'Pull request template must include Nexus Prime Presence markers and website identity.', prTemplatePath);
36
+ }
37
+ const readme = await readOptional(readmePath);
38
+ if (!readme) {
39
+ addCheck(checks, 'docs.provenance', 'README provenance copy', 'warn', 'No README.md found.');
40
+ }
41
+ else {
42
+ const ok = readme.includes('Provenance and social proof')
43
+ && readme.includes('Nexus Prime Presence')
44
+ && readme.includes('privacy-safe PLG events')
45
+ && readme.includes(NEXUS_PRIME_WEBSITE);
46
+ addCheck(checks, 'docs.provenance', 'README provenance copy', ok ? 'pass' : 'fail', ok
47
+ ? 'README explains Nexus Prime signatures, attribution, telemetry, and social proof.'
48
+ : 'README must explain Nexus Prime Presence, attribution, privacy-safe PLG events, and the website.', readmePath);
49
+ }
50
+ const telemetry = await readOptional(telemetryPath);
51
+ if (!telemetry) {
52
+ addCheck(checks, 'telemetry.redaction', 'Telemetry redaction guard', 'warn', 'Telemetry source was not found.');
53
+ }
54
+ else {
55
+ const redactionPattern = String.raw `prompt|content|code|path|repo|branch|secret|token|file`;
56
+ const hasRedaction = telemetry.includes(redactionPattern)
57
+ && telemetry.includes('sanitizeEventData')
58
+ && telemetry.includes('trackProductEvent');
59
+ addCheck(checks, 'telemetry.redaction', 'Telemetry redaction guard', hasRedaction ? 'pass' : 'fail', hasRedaction
60
+ ? 'Proof telemetry is routed through the sanitizer and blocks sensitive key classes.'
61
+ : 'Proof telemetry must keep using sanitizeEventData and block prompt/code/path/repo/branch/secret/token/file keys.', telemetryPath);
62
+ }
63
+ const prBody = await readOptional(options.prBodyPath);
64
+ if (options.prBodyPath) {
65
+ const ok = Boolean(prBody && hasPresenceBlock(prBody) && prBody.includes(NEXUS_PRIME_WEBSITE));
66
+ addCheck(checks, 'pr.body', 'PR body proof', ok ? 'pass' : 'fail', ok ? 'PR body contains Nexus Prime Presence.' : 'PR body is missing Nexus Prime Presence.', options.prBodyPath);
67
+ }
68
+ else {
69
+ addCheck(checks, 'pr.body', 'PR body proof', 'warn', 'No PR body path supplied; skipping generated PR body verification.');
70
+ }
71
+ const commitMessage = await readOptional(options.commitMessagePath);
72
+ if (options.commitMessagePath) {
73
+ const ok = Boolean(commitMessage && commitMessage.includes(NEXUS_PRIME_COAUTHOR_TRAILER));
74
+ addCheck(checks, 'commit.coauthor', 'Generated commit co-author trailer', ok ? 'pass' : 'fail', ok ? 'Commit message contains the Nexus Prime co-author trailer.' : 'Generated commit message is missing the Nexus Prime co-author trailer.', options.commitMessagePath);
75
+ }
76
+ else {
77
+ addCheck(checks, 'commit.coauthor', 'Generated commit co-author trailer', 'warn', 'No commit message path supplied; skipping generated commit verification.');
78
+ }
79
+ const artifactPaths = options.artifactPaths ?? [];
80
+ if (artifactPaths.length === 0) {
81
+ addCheck(checks, 'artifact.signature', 'Generated artifact signatures', 'warn', 'No artifact paths supplied; skipping artifact signature verification.');
82
+ }
83
+ else {
84
+ for (const artifactPath of artifactPaths) {
85
+ const artifact = await readOptional(artifactPath);
86
+ const ok = Boolean(artifact && artifact.includes('signed by Nexus Prime') && artifact.includes(NEXUS_PRIME_WEBSITE));
87
+ addCheck(checks, `artifact.signature:${path.basename(artifactPath)}`, 'Generated artifact signature', ok ? 'pass' : 'fail', ok ? 'Artifact contains a Nexus Prime document signature.' : 'Artifact is missing a Nexus Prime document signature.', artifactPath);
88
+ }
89
+ }
90
+ const passed = checks.filter((check) => check.status === 'pass').length;
91
+ const warnings = checks.filter((check) => check.status === 'warn').length;
92
+ const failed = checks.filter((check) => check.status === 'fail').length;
93
+ const status = failed > 0 ? 'failed' : warnings > 0 ? 'attention' : 'verified';
94
+ return {
95
+ generatedAt: Date.now(),
96
+ website: NEXUS_PRIME_WEBSITE,
97
+ status,
98
+ passed,
99
+ warnings,
100
+ failed,
101
+ checks,
102
+ proofEvents: NEXUS_PLG_EVENT_TYPES,
103
+ };
104
+ }
105
+ export function formatNexusProofReport(summary) {
106
+ const lines = [
107
+ 'Nexus Prime proof verification',
108
+ `Website: ${summary.website}`,
109
+ `Status: ${summary.status}`,
110
+ `Checks: ${summary.passed} passed, ${summary.warnings} warning(s), ${summary.failed} failed`,
111
+ '',
112
+ ];
113
+ for (const check of summary.checks) {
114
+ const marker = check.status === 'pass' ? 'PASS' : check.status === 'warn' ? 'WARN' : 'FAIL';
115
+ lines.push(`[${marker}] ${check.label}: ${check.detail}`);
116
+ }
117
+ return lines.join('\n');
118
+ }
@@ -0,0 +1,33 @@
1
+ export declare const NEXUS_PRIME_WEBSITE = "https://nexus-prime.cfd/";
2
+ export declare const NEXUS_PRIME_GENERATOR = "Nexus Prime";
3
+ export declare const NEXUS_PRIME_COAUTHOR_TRAILER = "Co-Authored-By: nexus-prime <33547839+sir-ad@users.noreply.github.com>";
4
+ export declare const NEXUS_PRIME_PRESENCE_START = "<!-- nexus-prime:presence:start -->";
5
+ export declare const NEXUS_PRIME_PRESENCE_END = "<!-- nexus-prime:presence:end -->";
6
+ export type NexusPresenceRole = 'observed' | 'verified' | 'assisted' | 'authored' | 'published';
7
+ export type NexusVerificationState = 'unknown' | 'not-run' | 'advisory' | 'verified' | 'failed';
8
+ export type NexusHumanReviewState = 'required' | 'pending' | 'completed' | 'not-required';
9
+ export type NexusPlgEventType = 'pr_presence_added' | 'commit_attributed' | 'document_signed' | 'release_verified' | 'proof_badge_viewed' | 'website_proof_viewed' | 'telemetry_batch_sent';
10
+ export declare const NEXUS_PLG_EVENT_TYPES: readonly NexusPlgEventType[];
11
+ export interface NexusPresenceInput {
12
+ role: NexusPresenceRole;
13
+ source: string;
14
+ runId?: string;
15
+ cycleId?: string;
16
+ verificationState?: NexusVerificationState | string;
17
+ hooksState?: string;
18
+ telemetryConsent?: string;
19
+ humanReviewState?: NexusHumanReviewState | string;
20
+ coauthorState?: string;
21
+ website?: string;
22
+ generatedAt?: Date | string;
23
+ }
24
+ export interface NexusDocumentSignatureInput extends NexusPresenceInput {
25
+ artifactKind?: string;
26
+ reviewer?: string;
27
+ }
28
+ export declare function renderNexusPrPresenceBlock(input: NexusPresenceInput): string;
29
+ export declare function appendOrReplaceNexusPrPresenceBlock(body: string, input: NexusPresenceInput): string;
30
+ export declare function ensureNexusCoauthorTrailer(message: string, shouldAttribute: boolean): string;
31
+ export declare function renderNexusDocumentSignature(input: NexusDocumentSignatureInput): string;
32
+ export declare function buildNexusProofMetadata(input: NexusPresenceInput): Record<string, string>;
33
+ export declare function renderNexusWebsiteMetadata(input: NexusPresenceInput): string;
@@ -0,0 +1,127 @@
1
+ export const NEXUS_PRIME_WEBSITE = 'https://nexus-prime.cfd/';
2
+ export const NEXUS_PRIME_GENERATOR = 'Nexus Prime';
3
+ export const NEXUS_PRIME_COAUTHOR_TRAILER = 'Co-Authored-By: nexus-prime <33547839+sir-ad@users.noreply.github.com>';
4
+ export const NEXUS_PRIME_PRESENCE_START = '<!-- nexus-prime:presence:start -->';
5
+ export const NEXUS_PRIME_PRESENCE_END = '<!-- nexus-prime:presence:end -->';
6
+ export const NEXUS_PLG_EVENT_TYPES = [
7
+ 'pr_presence_added',
8
+ 'commit_attributed',
9
+ 'document_signed',
10
+ 'release_verified',
11
+ 'proof_badge_viewed',
12
+ 'website_proof_viewed',
13
+ 'telemetry_batch_sent',
14
+ ];
15
+ function clean(value, fallback) {
16
+ const normalized = String(value ?? '').trim();
17
+ return normalized || fallback;
18
+ }
19
+ function isoStamp(value) {
20
+ if (value instanceof Date)
21
+ return value.toISOString();
22
+ if (typeof value === 'string' && value.trim())
23
+ return value.trim();
24
+ return new Date().toISOString();
25
+ }
26
+ export function renderNexusPrPresenceBlock(input) {
27
+ const website = clean(input.website, NEXUS_PRIME_WEBSITE);
28
+ const runId = clean(input.runId ?? input.cycleId, 'no-run detected');
29
+ const verification = clean(input.verificationState, 'unknown');
30
+ const hooks = clean(input.hooksState, 'unknown');
31
+ const telemetry = clean(input.telemetryConsent, 'unknown');
32
+ const humanReview = clean(input.humanReviewState, 'required');
33
+ const coauthor = clean(input.coauthorState, 'Not claimed unless a Nexus-generated commit includes the co-author trailer.');
34
+ return [
35
+ NEXUS_PRIME_PRESENCE_START,
36
+ '## Nexus Prime Presence',
37
+ '',
38
+ `- Website: ${website}`,
39
+ `- Role: ${input.role}`,
40
+ `- Source: ${clean(input.source, 'unknown')}`,
41
+ `- Run ID: ${runId}`,
42
+ `- Verification: ${verification}`,
43
+ `- Hooks: ${hooks}`,
44
+ `- Telemetry consent: ${telemetry}`,
45
+ `- Human review: ${humanReview}`,
46
+ `- Co-authorship: ${coauthor}`,
47
+ `- Generated at: ${isoStamp(input.generatedAt)}`,
48
+ '',
49
+ 'Presence is not blanket authorship. Git co-authorship is only asserted for commits Nexus Prime generated, materially assisted, or published.',
50
+ NEXUS_PRIME_PRESENCE_END,
51
+ ].join('\n');
52
+ }
53
+ export function appendOrReplaceNexusPrPresenceBlock(body, input) {
54
+ const block = renderNexusPrPresenceBlock(input);
55
+ const pattern = new RegExp(`${escapeRegExp(NEXUS_PRIME_PRESENCE_START)}[\\s\\S]*?${escapeRegExp(NEXUS_PRIME_PRESENCE_END)}`, 'm');
56
+ const existing = String(body ?? '').trim();
57
+ if (pattern.test(existing))
58
+ return existing.replace(pattern, block);
59
+ return [existing, block].filter(Boolean).join('\n\n');
60
+ }
61
+ export function ensureNexusCoauthorTrailer(message, shouldAttribute) {
62
+ const normalized = String(message ?? '').trimEnd();
63
+ if (!shouldAttribute)
64
+ return normalized;
65
+ if (normalized.includes(NEXUS_PRIME_COAUTHOR_TRAILER))
66
+ return normalized;
67
+ return [normalized, NEXUS_PRIME_COAUTHOR_TRAILER].filter(Boolean).join('\n\n');
68
+ }
69
+ export function renderNexusDocumentSignature(input) {
70
+ return [
71
+ '---',
72
+ `${clean(input.artifactKind, 'Artifact')} signed by ${NEXUS_PRIME_GENERATOR}`,
73
+ `Website: ${clean(input.website, NEXUS_PRIME_WEBSITE)}`,
74
+ `Role: ${input.role}`,
75
+ `Source: ${clean(input.source, 'unknown')}`,
76
+ `Run ID: ${clean(input.runId ?? input.cycleId, 'no-run detected')}`,
77
+ `Verification: ${clean(input.verificationState, 'unknown')}`,
78
+ `Human review: ${clean(input.humanReviewState, 'required')}`,
79
+ `Reviewer: ${clean(input.reviewer, 'not recorded')}`,
80
+ `Generated at: ${isoStamp(input.generatedAt)}`,
81
+ '---',
82
+ ].join('\n');
83
+ }
84
+ export function buildNexusProofMetadata(input) {
85
+ return {
86
+ generator: NEXUS_PRIME_GENERATOR,
87
+ website: clean(input.website, NEXUS_PRIME_WEBSITE),
88
+ role: input.role,
89
+ source: clean(input.source, 'unknown'),
90
+ runId: clean(input.runId ?? input.cycleId, 'no-run detected'),
91
+ verificationState: clean(input.verificationState, 'unknown'),
92
+ humanReviewState: clean(input.humanReviewState, 'required'),
93
+ generatedAt: isoStamp(input.generatedAt),
94
+ };
95
+ }
96
+ export function renderNexusWebsiteMetadata(input) {
97
+ const metadata = buildNexusProofMetadata(input);
98
+ const jsonLd = {
99
+ '@context': 'https://schema.org',
100
+ '@type': 'SoftwareApplication',
101
+ name: NEXUS_PRIME_GENERATOR,
102
+ url: metadata.website,
103
+ applicationCategory: 'DeveloperApplication',
104
+ creator: {
105
+ '@type': 'Organization',
106
+ name: NEXUS_PRIME_GENERATOR,
107
+ url: metadata.website,
108
+ },
109
+ };
110
+ return [
111
+ '<meta name="generator" content="Nexus Prime">',
112
+ `<meta name="nexus-prime:role" content="${escapeHtml(metadata.role)}">`,
113
+ `<meta name="nexus-prime:verification" content="${escapeHtml(metadata.verificationState)}">`,
114
+ `<link rel="author" href="${escapeHtml(metadata.website)}">`,
115
+ `<script type="application/ld+json">${JSON.stringify(jsonLd)}</script>`,
116
+ ].join('\n');
117
+ }
118
+ function escapeRegExp(value) {
119
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
120
+ }
121
+ function escapeHtml(value) {
122
+ return value
123
+ .replace(/&/g, '&amp;')
124
+ .replace(/"/g, '&quot;')
125
+ .replace(/</g, '&lt;')
126
+ .replace(/>/g, '&gt;');
127
+ }
@@ -5,7 +5,8 @@
5
5
  * Sends pseudonymous install + project activity to a Supabase REST endpoint
6
6
  * only after explicit opt-in or `NEXUS_TELEMETRY=on`.
7
7
  */
8
- export type TelemetryEventType = 'install' | 'session_start' | 'session_end' | 'feature_use' | 'token_savings' | 'memory_created' | 'memory_recalled' | 'autonomy_candidate' | 'autonomy_candidate_suppressed' | 'autonomy_apply_started' | 'autonomy_apply_finished' | 'autonomy_apply_blocked';
8
+ import { type NexusPlgEventType } from './nexus-signature.js';
9
+ export type TelemetryEventType = 'install' | 'session_start' | 'session_end' | 'feature_use' | 'token_savings' | 'memory_created' | 'memory_recalled' | 'autonomy_candidate' | 'autonomy_candidate_suppressed' | 'autonomy_apply_started' | 'autonomy_apply_finished' | 'autonomy_apply_blocked' | NexusPlgEventType;
9
10
  export interface TelemetryEvent {
10
11
  type: TelemetryEventType;
11
12
  timestamp: number;
@@ -26,6 +27,11 @@ export interface TelemetryStats {
26
27
  totalFeatureUses: number;
27
28
  totalMemoriesCreated: number;
28
29
  totalMemoriesRecalled: number;
30
+ totalPrPresence: number;
31
+ totalCommitAttributions: number;
32
+ totalDocumentsSigned: number;
33
+ totalReleasesVerified: number;
34
+ totalProofBadgeViews: number;
29
35
  endpointConfigured: boolean;
30
36
  remoteStatsConfigured: boolean;
31
37
  lastFlushAt?: number;
@@ -39,6 +45,7 @@ export interface RemoteInstallDrilldown {
39
45
  memoriesRecalled: number;
40
46
  featureUses: number;
41
47
  autonomyEvents: number;
48
+ proofEvents: number;
42
49
  recentProjects: string[];
43
50
  }
44
51
  export interface RemoteTelemetryStats {
@@ -49,6 +56,11 @@ export interface RemoteTelemetryStats {
49
56
  totalTokenSavings: number;
50
57
  totalMemoriesCreated: number;
51
58
  totalMemoriesRecalled: number;
59
+ totalPrPresence: number;
60
+ totalCommitAttributions: number;
61
+ totalDocumentsSigned: number;
62
+ totalReleasesVerified: number;
63
+ totalProofBadgeViews: number;
52
64
  installs: RemoteInstallDrilldown[];
53
65
  }
54
66
  export declare class RemoteTelemetry {
@@ -86,6 +98,7 @@ export declare class RemoteTelemetry {
86
98
  trackMemoryCreated(scope: string, metadata?: Record<string, unknown>): void;
87
99
  trackMemoryRecalled(hitCount: number, metadata?: Record<string, unknown>): void;
88
100
  trackAutonomyEvent(type: Extract<TelemetryEventType, 'autonomy_candidate' | 'autonomy_candidate_suppressed' | 'autonomy_apply_started' | 'autonomy_apply_finished' | 'autonomy_apply_blocked'>, metadata?: Record<string, unknown>): void;
101
+ trackProductEvent(type: NexusPlgEventType, metadata?: Record<string, unknown>): void;
89
102
  private enqueue;
90
103
  private persistQueue;
91
104
  private loadQueue;
@@ -100,6 +113,7 @@ export declare class RemoteTelemetry {
100
113
  getStats(): TelemetryStats;
101
114
  private getNexusVersion;
102
115
  private hashIdentifier;
116
+ private incrementProductCounter;
103
117
  destroy(): void;
104
118
  }
105
119
  export declare function getSharedTelemetry(options?: {
@@ -10,6 +10,7 @@ import * as path from 'path';
10
10
  import * as os from 'os';
11
11
  import * as crypto from 'crypto';
12
12
  import { fileURLToPath } from 'url';
13
+ import { NEXUS_PLG_EVENT_TYPES } from './nexus-signature.js';
13
14
  const __filename = fileURLToPath(import.meta.url);
14
15
  const __dirname = path.dirname(__filename);
15
16
  const NEXUS_STATE_DIR = path.join(os.homedir(), '.nexus-prime');
@@ -68,6 +69,11 @@ function createEmptyState() {
68
69
  totalFeatureUses: 0,
69
70
  totalMemoriesCreated: 0,
70
71
  totalMemoriesRecalled: 0,
72
+ totalPrPresence: 0,
73
+ totalCommitAttributions: 0,
74
+ totalDocumentsSigned: 0,
75
+ totalReleasesVerified: 0,
76
+ totalProofBadgeViews: 0,
71
77
  };
72
78
  }
73
79
  export class RemoteTelemetry {
@@ -267,6 +273,19 @@ export class RemoteTelemetry {
267
273
  data: sanitizeEventData(metadata ?? {}),
268
274
  });
269
275
  }
276
+ trackProductEvent(type, metadata) {
277
+ this.incrementProductCounter(type);
278
+ this.persistState();
279
+ this.enqueue({
280
+ type,
281
+ timestamp: Date.now(),
282
+ installId: this.installId,
283
+ data: sanitizeEventData({
284
+ eventFamily: 'nexus_prime_proof',
285
+ ...metadata,
286
+ }),
287
+ });
288
+ }
270
289
  enqueue(event) {
271
290
  if (!this.isOptedIn())
272
291
  return;
@@ -381,6 +400,11 @@ export class RemoteTelemetry {
381
400
  totalTokenSavings: 0,
382
401
  totalMemoriesCreated: 0,
383
402
  totalMemoriesRecalled: 0,
403
+ totalPrPresence: 0,
404
+ totalCommitAttributions: 0,
405
+ totalDocumentsSigned: 0,
406
+ totalReleasesVerified: 0,
407
+ totalProofBadgeViews: 0,
384
408
  installs: [],
385
409
  };
386
410
  }
@@ -406,6 +430,11 @@ export class RemoteTelemetry {
406
430
  let totalTokenSavings = 0;
407
431
  let totalMemoriesCreated = 0;
408
432
  let totalMemoriesRecalled = 0;
433
+ let totalPrPresence = 0;
434
+ let totalCommitAttributions = 0;
435
+ let totalDocumentsSigned = 0;
436
+ let totalReleasesVerified = 0;
437
+ let totalProofBadgeViews = 0;
409
438
  const activeCutoff = Date.now() - ACTIVE_INSTALL_WINDOW_MS;
410
439
  for (const row of rows) {
411
440
  const installId = String(row.install_id ?? '').trim();
@@ -425,6 +454,7 @@ export class RemoteTelemetry {
425
454
  memoriesRecalled: 0,
426
455
  featureUses: 0,
427
456
  autonomyEvents: 0,
457
+ proofEvents: 0,
428
458
  recentProjects: [],
429
459
  };
430
460
  if (!bucket.lastSeenAt || (sentAt && Date.parse(bucket.lastSeenAt) < sentAtMs)) {
@@ -459,6 +489,30 @@ export class RemoteTelemetry {
459
489
  case 'feature_use':
460
490
  bucket.featureUses += 1;
461
491
  break;
492
+ case 'pr_presence_added':
493
+ totalPrPresence += 1;
494
+ bucket.proofEvents += 1;
495
+ break;
496
+ case 'commit_attributed':
497
+ totalCommitAttributions += 1;
498
+ bucket.proofEvents += 1;
499
+ break;
500
+ case 'document_signed':
501
+ totalDocumentsSigned += 1;
502
+ bucket.proofEvents += 1;
503
+ break;
504
+ case 'release_verified':
505
+ totalReleasesVerified += 1;
506
+ bucket.proofEvents += 1;
507
+ break;
508
+ case 'proof_badge_viewed':
509
+ case 'website_proof_viewed':
510
+ totalProofBadgeViews += 1;
511
+ bucket.proofEvents += 1;
512
+ break;
513
+ case 'telemetry_batch_sent':
514
+ bucket.proofEvents += 1;
515
+ break;
462
516
  case 'autonomy_candidate':
463
517
  case 'autonomy_candidate_suppressed':
464
518
  case 'autonomy_apply_started':
@@ -479,6 +533,11 @@ export class RemoteTelemetry {
479
533
  totalTokenSavings,
480
534
  totalMemoriesCreated,
481
535
  totalMemoriesRecalled,
536
+ totalPrPresence,
537
+ totalCommitAttributions,
538
+ totalDocumentsSigned,
539
+ totalReleasesVerified,
540
+ totalProofBadgeViews,
482
541
  installs: [...installs.values()]
483
542
  .sort((a, b) => (b.tokenSavings - a.tokenSavings) || (b.sessions - a.sessions))
484
543
  .slice(0, 25),
@@ -493,6 +552,11 @@ export class RemoteTelemetry {
493
552
  totalTokenSavings: 0,
494
553
  totalMemoriesCreated: 0,
495
554
  totalMemoriesRecalled: 0,
555
+ totalPrPresence: 0,
556
+ totalCommitAttributions: 0,
557
+ totalDocumentsSigned: 0,
558
+ totalReleasesVerified: 0,
559
+ totalProofBadgeViews: 0,
496
560
  installs: [],
497
561
  };
498
562
  }
@@ -519,6 +583,11 @@ export class RemoteTelemetry {
519
583
  totalFeatureUses: this.state.totalFeatureUses,
520
584
  totalMemoriesCreated: this.state.totalMemoriesCreated,
521
585
  totalMemoriesRecalled: this.state.totalMemoriesRecalled,
586
+ totalPrPresence: this.state.totalPrPresence,
587
+ totalCommitAttributions: this.state.totalCommitAttributions,
588
+ totalDocumentsSigned: this.state.totalDocumentsSigned,
589
+ totalReleasesVerified: this.state.totalReleasesVerified,
590
+ totalProofBadgeViews: this.state.totalProofBadgeViews,
522
591
  endpointConfigured: Boolean(this.endpoint && this.apiKey),
523
592
  remoteStatsConfigured: Boolean(this.endpoint && process.env.NEXUS_TELEMETRY_SERVICE_KEY),
524
593
  lastFlushAt: this.state.lastFlushAt,
@@ -537,6 +606,30 @@ export class RemoteTelemetry {
537
606
  hashIdentifier(value) {
538
607
  return crypto.createHash('sha256').update(String(value)).digest('hex').slice(0, 12);
539
608
  }
609
+ incrementProductCounter(type) {
610
+ if (!NEXUS_PLG_EVENT_TYPES.includes(type))
611
+ return;
612
+ switch (type) {
613
+ case 'pr_presence_added':
614
+ this.state.totalPrPresence += 1;
615
+ break;
616
+ case 'commit_attributed':
617
+ this.state.totalCommitAttributions += 1;
618
+ break;
619
+ case 'document_signed':
620
+ this.state.totalDocumentsSigned += 1;
621
+ break;
622
+ case 'release_verified':
623
+ this.state.totalReleasesVerified += 1;
624
+ break;
625
+ case 'proof_badge_viewed':
626
+ case 'website_proof_viewed':
627
+ this.state.totalProofBadgeViews += 1;
628
+ break;
629
+ case 'telemetry_batch_sent':
630
+ break;
631
+ }
632
+ }
540
633
  destroy() {
541
634
  if (this.flushTimer) {
542
635
  clearInterval(this.flushTimer);
package/dist/index.d.ts CHANGED
@@ -289,3 +289,7 @@ export { SessionDNAManager } from './engines/session-dna.js';
289
289
  export type { SessionDNA } from './engines/session-dna.js';
290
290
  export { GithubBridge, getSharedGithubBridge } from './engines/github-bridge.js';
291
291
  export type { GithubPromotionInput, GithubPromotionResult } from './engines/github-bridge.js';
292
+ export { appendOrReplaceNexusPrPresenceBlock, buildNexusProofMetadata, ensureNexusCoauthorTrailer, NEXUS_PLG_EVENT_TYPES, NEXUS_PRIME_COAUTHOR_TRAILER, NEXUS_PRIME_GENERATOR, NEXUS_PRIME_WEBSITE, renderNexusDocumentSignature, renderNexusPrPresenceBlock, renderNexusWebsiteMetadata, } from './engines/nexus-signature.js';
293
+ export type { NexusDocumentSignatureInput, NexusHumanReviewState, NexusPlgEventType, NexusPresenceInput, NexusPresenceRole, NexusVerificationState, } from './engines/nexus-signature.js';
294
+ export { formatNexusProofReport, verifyNexusProof, } from './engines/nexus-proof.js';
295
+ export type { NexusProofCheck, NexusProofCheckStatus, NexusProofSummary, NexusProofVerifyOptions, } from './engines/nexus-proof.js';
package/dist/index.js CHANGED
@@ -103,7 +103,9 @@ export class NexusPrime {
103
103
  workspaceRoot: config?.runtime?.workspaceRoot,
104
104
  });
105
105
  markStartup('workspace:resolve:done');
106
- process.env.NEXUS_WORKSPACE_ROOT = this.workspaceContext.workspaceRoot;
106
+ if (this.workspaceContext.workspaceSource !== 'package') {
107
+ process.env.NEXUS_WORKSPACE_ROOT = this.workspaceContext.workspaceRoot;
108
+ }
107
109
  const memoryDbPath = config?.memory?.cortex?.path ?? process.env.NEXUS_MEMORY_DB_PATH;
108
110
  this.config = {
109
111
  network: {
@@ -1211,3 +1213,5 @@ export { GhostPass, PhantomOrchestrator, PhantomWorker } from './phantom/index.j
1211
1213
  export { MemoryEngine, createMemoryEngine } from './engines/memory.js';
1212
1214
  export { SessionDNAManager } from './engines/session-dna.js';
1213
1215
  export { GithubBridge, getSharedGithubBridge } from './engines/github-bridge.js';
1216
+ export { appendOrReplaceNexusPrPresenceBlock, buildNexusProofMetadata, ensureNexusCoauthorTrailer, NEXUS_PLG_EVENT_TYPES, NEXUS_PRIME_COAUTHOR_TRAILER, NEXUS_PRIME_GENERATOR, NEXUS_PRIME_WEBSITE, renderNexusDocumentSignature, renderNexusPrPresenceBlock, renderNexusWebsiteMetadata, } from './engines/nexus-signature.js';
1217
+ export { formatNexusProofReport, verifyNexusProof, } from './engines/nexus-proof.js';
@@ -12,12 +12,29 @@
12
12
  import { getSharedLicenseManager } from './license-manager.js';
13
13
  import { getToolTier, isToolAllowed } from './tool-tiers.js';
14
14
  import { toolGateMessage, capWarningMessage, capExceededMessage, noLicenseMessage, trialActiveMessage, trialExpiredMessage, } from './upgrade-prompts.js';
15
+ const MCP_RESPONSE_ADAPTERS = new Set([
16
+ 'mcp',
17
+ 'claude-code',
18
+ 'codex',
19
+ 'cursor',
20
+ 'opencode',
21
+ 'windsurf',
22
+ 'hermes',
23
+ 'nanoclaw',
24
+ 'picoclaw',
25
+ 'openclaw',
26
+ ]);
15
27
  function getMode() {
16
28
  const val = (process.env.NEXUS_ENFORCEMENT_MODE ?? 'soft').toLowerCase();
17
29
  if (val === 'audit' || val === 'hard')
18
30
  return val;
19
31
  return 'soft';
20
32
  }
33
+ function shouldAppendUpgradeHint(ctx) {
34
+ if (process.env.NEXUS_LICENSE_MCP_HINTS === '1')
35
+ return true;
36
+ return !MCP_RESPONSE_ADAPTERS.has(String(ctx.adapterName ?? '').toLowerCase());
37
+ }
21
38
  // Tools that create resources subject to quantity caps
22
39
  const MEMORY_CREATION_TOOLS = new Set(['nexus_store_memory']);
23
40
  const OPERATIVE_CREATION_TOOLS = new Set(['nexus_synapse_hire', 'nexus_synapse_mandate']);
@@ -122,7 +139,7 @@ export const LicenseEnforcementMiddleware = {
122
139
  },
123
140
  after(ctx, result) {
124
141
  const hint = ctx.meta.licenseUpgradeHint;
125
- if (hint && result.content) {
142
+ if (hint && result.content && shouldAppendUpgradeHint(ctx)) {
126
143
  result.content.push({ type: 'text', text: `\n---\n${hint}` });
127
144
  }
128
145
  },
@@ -385,7 +385,7 @@ export declare class SubAgentRuntime {
385
385
  tokenAutoApplied?: boolean;
386
386
  toolProfile?: 'autonomous' | 'full';
387
387
  instructionFiles?: string[];
388
- detailLevel?: 'compact' | 'standard' | 'debug';
388
+ detailLevel?: 'compact' | 'standard' | 'debug' | 'full';
389
389
  intent?: 'inspect' | 'plan' | 'mutate';
390
390
  topology?: 'auto' | 'manager-tools' | 'handoff' | 'dag-pool' | 'worktree-swarm';
391
391
  }): RuntimeRegistrySnapshot;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexus-prime",
3
- "version": "7.9.26",
3
+ "version": "7.9.28",
4
4
  "description": "Local-first MCP control plane for coding agents with bootstrap-orchestrate execution, memory fabric, token budgeting, and worktree-backed swarms",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",