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 +17 -4
- package/dist/agents/adapters/mcp/definitions.js +3 -2
- package/dist/agents/adapters/mcp/dispatch.js +9 -1
- package/dist/agents/adapters/mcp/envelope.js +2 -0
- package/dist/agents/adapters/mcp/handlers/orchestration.js +60 -18
- package/dist/agents/adapters/mcp/helpers.js +2 -2
- package/dist/agents/adapters/mcp/types.d.ts +1 -1
- package/dist/cli.js +29 -0
- package/dist/dashboard/app/views/trust.js +41 -0
- package/dist/dashboard/selectors/trust-selector.js +20 -0
- package/dist/dashboard/types.d.ts +1 -0
- package/dist/engines/github-bridge.d.ts +6 -1
- package/dist/engines/github-bridge.js +91 -7
- package/dist/engines/nexus-proof.d.ts +26 -0
- package/dist/engines/nexus-proof.js +118 -0
- package/dist/engines/nexus-signature.d.ts +33 -0
- package/dist/engines/nexus-signature.js +127 -0
- package/dist/engines/telemetry-remote.d.ts +15 -1
- package/dist/engines/telemetry-remote.js +93 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +5 -1
- package/dist/licensing/enforcement.js +18 -1
- package/dist/phantom/runtime.d.ts +1 -1
- package/package.json +1 -1
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
|
-
> **
|
|
41
|
+
> **Stop restarting your coding agents from zero.**
|
|
42
42
|
>
|
|
43
|
-
>
|
|
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
|
|
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/
|
|
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)
|
|
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
|
|
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
|
-
...(
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
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
|
-
...(
|
|
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
|
-
|
|
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,
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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, '&')
|
|
124
|
+
.replace(/"/g, '"')
|
|
125
|
+
.replace(/</g, '<')
|
|
126
|
+
.replace(/>/g, '>');
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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",
|