ds4-context-engine 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,872 @@
1
+ import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
2
+ import {
3
+ isPrivacyClassification,
4
+ type PrivacyClassification,
5
+ } from "ds4-context-core/privacy/privacy-policy";
6
+ import type {
7
+ Ds4ContextRuntime,
8
+ RuntimeDiagnostics,
9
+ SummaryGraphDiagnostics,
10
+ } from "./runtime.ts";
11
+
12
+ const NUMBER_FORMAT = new Intl.NumberFormat("en-US");
13
+ const SUBCOMMANDS = [
14
+ "status",
15
+ "tokens",
16
+ "manifest",
17
+ "explain",
18
+ "included",
19
+ "excluded",
20
+ "summaries",
21
+ "retrieved",
22
+ "project",
23
+ "pins",
24
+ "pin",
25
+ "unpin",
26
+ "memory",
27
+ "privacy",
28
+ "model",
29
+ "continuation",
30
+ "artifacts",
31
+ "compaction",
32
+ "compact-preview",
33
+ "health",
34
+ "rebuild-index",
35
+ ] as const;
36
+
37
+ function classificationOption(value: string | undefined): PrivacyClassification | undefined {
38
+ if (value === undefined) return undefined;
39
+ const normalized = value.trim().toLowerCase();
40
+ if (!isPrivacyClassification(normalized)) {
41
+ throw new Error("Classification must be normal, internal, sensitive, or local-only");
42
+ }
43
+ return normalized;
44
+ }
45
+
46
+ function count(value: number | undefined): string {
47
+ return value === undefined ? "n/a" : NUMBER_FORMAT.format(value);
48
+ }
49
+
50
+ function present(ctx: ExtensionCommandContext, message: string, level: "info" | "warning" | "error" = "info"): void {
51
+ if (ctx.hasUI) ctx.ui.notify(message, level);
52
+ else console.log(message);
53
+ }
54
+
55
+ interface ParsedCommandArgs {
56
+ positionals: string[];
57
+ options: Map<string, string>;
58
+ }
59
+
60
+ function commandTokens(value: string): string[] {
61
+ const tokens: string[] = [];
62
+ let current = "";
63
+ let quote: "\"" | "'" | undefined;
64
+ let escaped = false;
65
+ for (const character of value.trim()) {
66
+ if (escaped) {
67
+ current += character;
68
+ escaped = false;
69
+ continue;
70
+ }
71
+ if (character === "\\") {
72
+ escaped = true;
73
+ continue;
74
+ }
75
+ if (quote) {
76
+ if (character === quote) quote = undefined;
77
+ else current += character;
78
+ continue;
79
+ }
80
+ if (character === "\"" || character === "'") {
81
+ quote = character;
82
+ continue;
83
+ }
84
+ if (/\s/u.test(character)) {
85
+ if (current) tokens.push(current);
86
+ current = "";
87
+ continue;
88
+ }
89
+ current += character;
90
+ }
91
+ if (escaped) current += "\\";
92
+ if (quote) throw new Error("Unterminated quote in /context arguments");
93
+ if (current) tokens.push(current);
94
+ return tokens;
95
+ }
96
+
97
+ function parseCommandArgs(value: string): ParsedCommandArgs {
98
+ const tokens = commandTokens(value);
99
+ const positionals: string[] = [];
100
+ const options = new Map<string, string>();
101
+ for (let index = 0; index < tokens.length; index++) {
102
+ const token = tokens[index] ?? "";
103
+ if (token === "--") {
104
+ positionals.push(...tokens.slice(index + 1));
105
+ break;
106
+ }
107
+ if (!token.startsWith("--")) {
108
+ positionals.push(token);
109
+ continue;
110
+ }
111
+ const equals = token.indexOf("=");
112
+ if (equals > 2) {
113
+ options.set(token.slice(2, equals).toLowerCase(), token.slice(equals + 1));
114
+ continue;
115
+ }
116
+ const name = token.slice(2).toLowerCase();
117
+ const next = tokens[index + 1];
118
+ if (!next || next.startsWith("--")) throw new Error(`Option --${name} requires a value`);
119
+ options.set(name, next);
120
+ index++;
121
+ }
122
+ return { positionals, options };
123
+ }
124
+
125
+ function sourceIds(value: string | undefined): string[] {
126
+ return value ? [...new Set(value.split(",").map((item) => item.trim()).filter(Boolean))] : [];
127
+ }
128
+
129
+ function splitCommand(value: string, fallback = ""): { command: string; args: string } {
130
+ const match = value.trim().match(/^(\S+)(?:\s+([\s\S]*))?$/u);
131
+ return match
132
+ ? { command: (match[1] ?? fallback).toLowerCase(), args: match[2] ?? "" }
133
+ : { command: fallback, args: "" };
134
+ }
135
+
136
+ function assertOptions(options: ReadonlyMap<string, string>, allowed: readonly string[]): void {
137
+ const allowedSet = new Set(allowed);
138
+ const unknown = [...options.keys()].filter((name) => !allowedSet.has(name));
139
+ if (unknown.length > 0) throw new Error(`Unknown option(s): ${unknown.map((name) => `--${name}`).join(", ")}`);
140
+ }
141
+
142
+ function formatStatus(diagnostics: RuntimeDiagnostics): string {
143
+ const session = diagnostics.session;
144
+ const observation = diagnostics.observation;
145
+ const budget = observation?.budget;
146
+ const model = diagnostics.model ? `${diagnostics.model.provider}/${diagnostics.model.id}` : "not selected";
147
+ const indexStatus = diagnostics.lastIndexResult
148
+ ? `${diagnostics.lastIndexResult.mode} (${diagnostics.lastIndexResult.reason})`
149
+ : "not run";
150
+
151
+ return [
152
+ "DS4 Context Engine",
153
+ "",
154
+ `State: ${diagnostics.phase}`,
155
+ `Planner: ${diagnostics.plannerVersion} (${diagnostics.lastManifest?.planning?.mode ?? diagnostics.contextMode})`,
156
+ `Extension / Pi target: ${diagnostics.extensionVersion} / ${diagnostics.supportedPiVersion}`,
157
+ `Session: ${session?.sessionId ?? "unavailable"}`,
158
+ `Session entries: ${count(session?.totalEntries)}`,
159
+ `Current branch entries: ${count(session?.branchEntries)}`,
160
+ `Model: ${model}`,
161
+ `Original messages: ${count(observation?.originalMessageCount)}`,
162
+ `Selected messages: ${count(observation?.messageCount)}`,
163
+ `Original message tokens: ${count(observation?.originalEstimatedMessageTokens)} estimated`,
164
+ `Selected message tokens: ${count(observation?.estimatedMessageTokens)} estimated`,
165
+ `Planning duration: ${observation?.planningDurationMs === undefined ? "n/a" : `${observation.planningDurationMs.toFixed(1)} ms`}`,
166
+ `Active input budget: ${count(budget?.activeInputBudget ?? diagnostics.lastManifest?.targetInputTokens)}`,
167
+ `Latest manifest: ${diagnostics.lastManifest?.id ?? "not built"}`,
168
+ `Compaction: ${diagnostics.compaction.phase}`,
169
+ `Proactive compaction: ${diagnostics.compaction.proactiveEligible ? "eligible" : "not eligible"}`,
170
+ `Retrieved evidence: ${count(diagnostics.retrieval.selected.length)} item(s), ${count(diagnostics.retrieval.selectedTokens)} tokens`,
171
+ `Retrieval duration: ${diagnostics.retrieval.durationMs.toFixed(1)} ms`,
172
+ `Project knowledge: ${diagnostics.project.status}`,
173
+ `Project snippets: ${count(diagnostics.project.selected.length)} item(s), ${count(diagnostics.project.selectedTokens)} tokens`,
174
+ `Project index files: ${count(diagnostics.project.stats?.files)}`,
175
+ `Stale project snippets: ${count(diagnostics.project.stats?.staleSnippets)}`,
176
+ `Pins active / selected: ${count(diagnostics.memory.activePins)} / ${count(diagnostics.memory.selectedPins.length)}`,
177
+ `Memory active / selected: ${count(diagnostics.memory.activeMemories)} / ${count(diagnostics.memory.selectedMemories.length)}`,
178
+ `Memory tokens: ${count(diagnostics.memory.selectedPinTokens + diagnostics.memory.selectedMemoryTokens)}`,
179
+ `Privacy enforcement: ${diagnostics.privacy.enforcement}`,
180
+ `Privacy blocked/redacted: ${count(diagnostics.privacy.blockedBlocks)} / ${count(diagnostics.privacy.secretRedactions)}`,
181
+ `Estimator calibration: ${diagnostics.modelAwareness?.calibration.calibrated ? `x${diagnostics.modelAwareness.calibration.appliedRatio.toFixed(3)}` : "collecting/neutral"}`,
182
+ `Calibration samples: ${count(diagnostics.modelAwareness?.calibration.acceptedSamples)} accepted`,
183
+ `Native continuation: ${diagnostics.nativeContinuation.status} (${diagnostics.nativeContinuation.last?.mode ?? "no request"})`,
184
+ `Continuation saved items: ${count(diagnostics.nativeContinuation.last?.omittedInputItems)}`,
185
+ `Artifact offload: ${count(diagnostics.artifacts.offloadedCount)} result(s), ${count(diagnostics.artifacts.offloadedBytes)} bytes`,
186
+ `Artifact tokens saved: ${count(diagnostics.artifacts.estimatedTokensSaved)} estimated`,
187
+ `Artifact objects / refs: ${count(diagnostics.artifacts.stats.objects)} / ${count(diagnostics.artifacts.stats.references)}`,
188
+ `Indexed entries: ${count(diagnostics.indexed?.entries)}`,
189
+ `Last index sync: ${indexStatus}`,
190
+ `Malformed JSONL lines: ${count(diagnostics.lastIndexResult?.malformedLines)}`,
191
+ `Database schema: ${diagnostics.databaseSchemaVersion ?? "unavailable"}`,
192
+ `Database: ${diagnostics.databasePath ?? "unavailable"}`,
193
+ ...(diagnostics.configWarnings.length > 0
194
+ ? [`Configuration warnings: ${diagnostics.configWarnings.length}`]
195
+ : []),
196
+ ...(diagnostics.lastIndexError ? [`Index warning: ${diagnostics.lastIndexError}`] : []),
197
+ ...(observation?.fallbackReason ? [`Planner fallback: ${observation.fallbackReason}`] : []),
198
+ ...(diagnostics.lastError ? [`Runtime fallback: ${diagnostics.lastError}`] : []),
199
+ ].join("\n");
200
+ }
201
+
202
+ function formatTokens(diagnostics: RuntimeDiagnostics): string {
203
+ const observation = diagnostics.observation;
204
+ const budget = observation?.budget;
205
+ const manifest = diagnostics.lastManifest;
206
+ const tokensFor = (kind: string) => manifest?.included
207
+ .filter((item) => item.kind === kind)
208
+ .reduce((total, item) => total + item.tokens, 0);
209
+ return [
210
+ `DS4 Context Tokens (${manifest?.planning?.mode ?? diagnostics.contextMode} mode)`,
211
+ "",
212
+ `System prompt: ${count(manifest?.composition.systemTokens)}`,
213
+ `Tool definitions: ${count(manifest?.composition.toolTokens)}`,
214
+ `AgentMessage[]: ${count(manifest?.composition.messageTokens)}`,
215
+ ` Recent verbatim: ${count(tokensFor("recent"))}`,
216
+ ` Pinned context: ${count(tokensFor("pin"))}`,
217
+ ` Durable memory: ${count(tokensFor("memory"))}`,
218
+ ` Historical retrieval: ${count(tokensFor("retrieval"))}`,
219
+ ` Project snippets: ${count(tokensFor("project"))}`,
220
+ ` Artifactized results*: ${count(manifest?.artifacts?.reduce((total, artifact) => total + artifact.condensedTokens, 0))}`,
221
+ ` Active summaries: ${count(tokensFor("summary"))}`,
222
+ ` Current request: ${count(tokensFor("current"))}`,
223
+ `Estimated provider input: ${count(manifest?.estimatedInputTokens)}`,
224
+ `Actual provider input: ${count(manifest?.actualInputTokens)}`,
225
+ ` Uncached input: ${count(manifest?.providerUsage?.inputTokens)}`,
226
+ ` Cache read / write: ${count(manifest?.providerUsage?.cacheReadTokens)} / ${count(manifest?.providerUsage?.cacheWriteTokens)}`,
227
+ `Pi reported context: ${count(manifest?.piReportedContextTokens ?? observation?.reportedTokens)}`,
228
+ `Model context window: ${count(budget?.contextWindow ?? manifest?.contextWindow)}`,
229
+ `Output reserve: ${count(budget?.outputReserve ?? manifest?.outputReserve)}`,
230
+ `Safety margin: ${count(budget?.safetyMargin)}`,
231
+ `Estimator calibration: ${budget?.calibrationRatio === undefined ? "n/a" : `x${budget.calibrationRatio.toFixed(3)} (${count(budget.calibrationSamples)} samples)`}`,
232
+ `Nominal soft / hard: ${count(budget?.nominalSoftInputLimit)} / ${count(budget?.nominalHardInputLimit)}`,
233
+ `Soft input limit: ${count(budget?.softInputLimit)}`,
234
+ `Hard input limit: ${count(budget?.hardInputLimit ?? manifest?.hardInputLimit)}`,
235
+ `Preferred input target: ${count(budget?.preferredInputTarget ?? manifest?.targetInputTokens)}`,
236
+ `Active input budget: ${count(budget?.activeInputBudget ?? manifest?.targetInputTokens)}`,
237
+ "",
238
+ "Estimates cover Pi's effective system prompt, active tool schemas, and AgentMessage[] before provider rendering.",
239
+ "* Artifactized result tokens are already included in AgentMessage[] and the recent/current categories.",
240
+ ].join("\n");
241
+ }
242
+
243
+ function formatManifest(diagnostics: RuntimeDiagnostics): string {
244
+ const manifest = diagnostics.lastManifest;
245
+ if (!manifest) return "No Context Manifest has been built for this session yet.";
246
+
247
+ const kinds = new Map<string, { items: number; tokens: number }>();
248
+ for (const item of manifest.included) {
249
+ const aggregate = kinds.get(item.kind) ?? { items: 0, tokens: 0 };
250
+ aggregate.items++;
251
+ aggregate.tokens += item.tokens;
252
+ kinds.set(item.kind, aggregate);
253
+ }
254
+ const composition = [...kinds.entries()]
255
+ .map(([kind, value]) => ` ${kind.padEnd(10)} ${String(value.items).padStart(4)} item(s) ${count(value.tokens).padStart(10)} tokens`);
256
+
257
+ return [
258
+ "DS4 Context Manifest",
259
+ "",
260
+ `ID: ${manifest.id}`,
261
+ `Session / leaf: ${manifest.sessionId} / ${manifest.branchLeafId ?? "root"}`,
262
+ `Provider / model: ${manifest.provider} / ${manifest.model}`,
263
+ `Prompt hash: ${manifest.promptHash}`,
264
+ `Planner / policy: ${manifest.plannerVersion} / ${manifest.policyVersion}`,
265
+ `Estimated input: ${count(manifest.estimatedInputTokens)}`,
266
+ `Actual input: ${count(manifest.actualInputTokens)}`,
267
+ `Usage input/cache: ${count(manifest.providerUsage?.inputTokens)} / ${count(manifest.providerUsage?.cacheReadTokens)} read / ${count(manifest.providerUsage?.cacheWriteTokens)} write`,
268
+ `Target / hard: ${count(manifest.targetInputTokens)} / ${count(manifest.hardInputLimit)}`,
269
+ `Included / excluded:${count(manifest.included.length)} / ${count(manifest.excluded.length)}`,
270
+ `Planning mode: ${manifest.planning?.mode ?? "observer"}`,
271
+ `Original messages: ${count(manifest.planning?.originalMessageCount ?? manifest.composition.messageCount)}`,
272
+ `Selected messages: ${count(manifest.composition.messageCount)}`,
273
+ `Recent-tail limit: ${count(manifest.planning?.recentTailTokenLimit)}`,
274
+ `Planning duration: ${manifest.planning?.durationMs === undefined ? "n/a" : `${manifest.planning.durationMs.toFixed(1)} ms`}`,
275
+ ...(manifest.planning?.fallbackReason ? [`Fallback: ${manifest.planning.fallbackReason}`] : []),
276
+ `Summary sources: ${manifest.summaryIds.length > 0 ? manifest.summaryIds.join(", ") : "none"}`,
277
+ `Project snippets: ${count(manifest.projectSnippets.length)}`,
278
+ `Project revision: ${manifest.projectRevision?.head ?? "non-git/unavailable"}${manifest.projectRevision?.dirty ? " (dirty)" : ""}`,
279
+ `Pins / memories: ${count(manifest.pins?.length ?? 0)} / ${count(manifest.memories?.length ?? 0)}`,
280
+ `Artifacts: ${count(manifest.artifacts?.length ?? 0)}`,
281
+ `Privacy: ${manifest.privacy?.enforcement ?? "disabled"}${manifest.privacy ? ` (${manifest.privacy.destination})` : ""}`,
282
+ `Model calibration: ${manifest.modelAwareness?.calibration.calibrated ? `x${manifest.modelAwareness.calibration.appliedRatio.toFixed(3)}` : "neutral/collecting"}`,
283
+ `Adaptive tail/hist/project: ${count(manifest.modelAwareness?.adaptive.recentTailTokens)} / ${count(manifest.modelAwareness?.adaptive.maxRetrievedHistoryTokens)} / ${count(manifest.modelAwareness?.adaptive.maxProjectTokens)}`,
284
+ `Continuation: ${manifest.nativeContinuation?.mode ?? "disabled"}; sent/full ${count(manifest.nativeContinuation?.sentInputItems)} / ${count(manifest.nativeContinuation?.fullInputItems)}`,
285
+ "",
286
+ "Composition",
287
+ ...composition,
288
+ ].join("\n");
289
+ }
290
+
291
+ function formatManifestItems(diagnostics: RuntimeDiagnostics, type: "included" | "excluded"): string {
292
+ const manifest = diagnostics.lastManifest;
293
+ if (!manifest) return "No Context Manifest has been built for this session yet.";
294
+ const items = manifest[type];
295
+ return [
296
+ `DS4 Context ${type === "included" ? "Included" : "Excluded"} Items`,
297
+ "",
298
+ ...(items.length === 0
299
+ ? ["none"]
300
+ : items.map((item, index) => {
301
+ const score = item.score === undefined ? "-" : item.score.toFixed(3);
302
+ const source = item.sourceId ?? "transient";
303
+ const group = item.groupId ? ` group=${item.groupId}` : "";
304
+ const classification = item.classification ? ` class=${item.classification}` : "";
305
+ return `${String(index + 1).padStart(3)}. ${item.kind.padEnd(8)} ${count(item.tokens).padStart(8)} tok score=${score} source=${source}${group}${classification}\n ${item.reason}`;
306
+ })),
307
+ ].join("\n");
308
+ }
309
+
310
+ function formatExplain(diagnostics: RuntimeDiagnostics): string {
311
+ const planning = diagnostics.lastManifest?.planning;
312
+ if (!planning) {
313
+ return "Latest context used observer mode; no managed-context selection was applied.";
314
+ }
315
+ return [
316
+ "DS4 Context Plan",
317
+ "",
318
+ `Mode: ${planning.mode}`,
319
+ `Original messages: ${count(planning.originalMessageCount)}`,
320
+ `Original tokens: ${count(planning.originalMessageTokens)}`,
321
+ `Fixed system/tools: ${count(planning.fixedTokens)}`,
322
+ `Message target: ${count(planning.messageTargetTokens)}`,
323
+ `Message hard limit: ${count(planning.messageHardLimitTokens)}`,
324
+ `Recent-tail limit: ${count(planning.recentTailTokenLimit)}`,
325
+ `Selected groups: ${count(planning.selectedGroupCount)}`,
326
+ `Excluded groups: ${count(planning.excludedGroupCount)}`,
327
+ `Duration: ${planning.durationMs === undefined ? "n/a" : `${planning.durationMs.toFixed(1)} ms`}`,
328
+ ...(planning.fallbackReason ? [`Fallback reason: ${planning.fallbackReason}`] : []),
329
+ "",
330
+ "Use /context included or /context excluded for item-level provenance.",
331
+ "Label an active Pi entry with 'ds4:pin' to make its atomic turn mandatory.",
332
+ ].join("\n");
333
+ }
334
+
335
+ function formatSummaryGraph(graph: SummaryGraphDiagnostics): string {
336
+ const recentNodes = graph.nodes.slice(0, 24);
337
+ return [
338
+ "DS4 Hierarchical Summary Graph",
339
+ "",
340
+ `Nodes: ${count(graph.totalNodes)}`,
341
+ `Committed/prepared/failed: ${count(graph.committedNodes)} / ${count(graph.preparedNodes)} / ${count(graph.failedNodes)}`,
342
+ `Segment/aggregate/branch: ${count(graph.segmentNodes)} / ${count(graph.aggregateNodes)} / ${count(graph.branchNodes)}`,
343
+ `Maximum graph level: ${count(graph.maxGraphLevel)}`,
344
+ `Active summary: ${graph.activeSummaryId ?? "none on current branch"}`,
345
+ `Active path nodes: ${count(graph.activePathIds.length)}`,
346
+ `Committed roots: ${graph.rootSummaryIds.length > 0 ? graph.rootSummaryIds.join(", ") : "none"}`,
347
+ "",
348
+ "Recent nodes (* = current branch active path)",
349
+ ...(recentNodes.length === 0
350
+ ? ["none"]
351
+ : recentNodes.map((node) => {
352
+ const marker = node.activePath ? "*" : " ";
353
+ const children = node.children.length > 0 ? node.children.join(",") : "-";
354
+ return `${marker} ${node.id} ${node.kind} L${node.graphLevel} ${node.lifecycleStatus}/${node.validationStatus} sources=${node.sourceEntries} children=${children}`;
355
+ })),
356
+ ...(graph.nodes.length > recentNodes.length ? [`... ${graph.nodes.length - recentNodes.length} older node(s) omitted`] : []),
357
+ ].join("\n");
358
+ }
359
+
360
+ function formatRetrieved(diagnostics: RuntimeDiagnostics): string {
361
+ const retrieval = diagnostics.retrieval;
362
+ return [
363
+ "DS4 Retrieved Historical Evidence",
364
+ "",
365
+ `Status: ${retrieval.status}`,
366
+ `Query terms: ${retrieval.queryTerms.length > 0 ? retrieval.queryTerms.join(", ") : "none"}`,
367
+ `Candidates: ${count(retrieval.candidateCount)}`,
368
+ `Alternate-branch blocked:${count(retrieval.alternateBranchCandidates).padStart(9)}`,
369
+ `Duplicate candidates: ${count(retrieval.duplicateCandidates)}`,
370
+ `Planner exclusions: ${count(retrieval.plannerExcludedCount)}`,
371
+ `Selected: ${count(retrieval.selected.length)}`,
372
+ `Selected / maximum tokens:${count(retrieval.selectedTokens).padStart(9)} / ${count(retrieval.maxTokens)}`,
373
+ `Duration: ${retrieval.durationMs.toFixed(3)} ms`,
374
+ ...(retrieval.fallbackReason ? [`Fallback: ${retrieval.fallbackReason}`] : []),
375
+ ...retrieval.warnings.map((warning) => `Warning: ${warning}`),
376
+ "",
377
+ ...(retrieval.selected.length === 0
378
+ ? ["No historical evidence was injected into the latest managed context."]
379
+ : retrieval.selected.flatMap((evidence, index) => [
380
+ `${index + 1}. ${evidence.entryId} score=${evidence.score.toFixed(3)} tokens=${count(evidence.estimatedTokens)} role=${evidence.role ?? "unknown"}`,
381
+ ` ${evidence.reason}`,
382
+ ` ${evidence.excerpt.replace(/\s+/gu, " ").slice(0, 500)}${evidence.excerpt.length > 500 ? "…" : ""}`,
383
+ ])),
384
+ ].join("\n");
385
+ }
386
+
387
+ function formatProject(diagnostics: RuntimeDiagnostics): string {
388
+ const project = diagnostics.project;
389
+ const revision = project.revision;
390
+ const sync = project.lastSync;
391
+ return [
392
+ "DS4 Project Knowledge",
393
+ "",
394
+ `Status / trusted: ${project.status} / ${project.trusted ? "yes" : "no"}`,
395
+ `Project: ${project.projectPath ?? "not indexed"}`,
396
+ `Git branch / HEAD: ${revision?.branch ?? "n/a"} / ${revision?.head ?? "n/a"}`,
397
+ `Working tree: ${revision?.dirty ? "dirty" : "clean or non-git"}`,
398
+ `Changed files: ${count(revision?.changedFiles.length)}`,
399
+ `Current / deleted files: ${count(project.stats?.files)} / ${count(project.stats?.deletedFiles)}`,
400
+ `Current / stale snippets: ${count(project.stats?.currentSnippets)} / ${count(project.stats?.staleSnippets)}`,
401
+ `Indexed snippet tokens: ${count(project.stats?.indexedTokens)}`,
402
+ `Last sync mode: ${sync?.mode ?? "not run"}`,
403
+ `Indexed / unchanged files: ${count(sync?.indexedFiles)} / ${count(sync?.unchangedFiles)}`,
404
+ `Skipped large/binary/secret:${count(sync?.skippedLarge).padStart(7)} / ${count(sync?.skippedBinary)} / ${count(sync?.skippedSensitive)}`,
405
+ `Query terms: ${project.queryTerms.length > 0 ? project.queryTerms.join(", ") : "none"}`,
406
+ `Candidates / duplicates: ${count(project.candidateCount)} / ${count(project.duplicateCandidates)}`,
407
+ `Invalidated / reindexed: ${count(project.invalidatedSnippets)} / ${count(project.reindexedFiles)}`,
408
+ `Planner exclusions: ${count(project.plannerExcludedCount)}`,
409
+ `Selected / maximum tokens: ${count(project.selectedTokens)} / ${count(project.maxTokens)}`,
410
+ `Index/retrieval duration: ${sync?.durationMs.toFixed(3) ?? "n/a"} / ${project.durationMs.toFixed(3)} ms`,
411
+ ...(project.fallbackReason ? [`Fallback: ${project.fallbackReason}`] : []),
412
+ ...project.warnings.map((warning) => `Warning: ${warning}`),
413
+ "",
414
+ ...(project.selected.length === 0
415
+ ? ["No project snippets were injected into the latest managed context."]
416
+ : project.selected.flatMap((evidence, index) => [
417
+ `${index + 1}. ${evidence.path}:${evidence.startLine}-${evidence.endLine} score=${evidence.score.toFixed(3)} tokens=${count(evidence.estimatedTokens)}${evidence.modified ? " modified" : ""}`,
418
+ ` ${evidence.reason}`,
419
+ ` ${evidence.excerpt.replace(/\s+/gu, " ").slice(0, 500)}${evidence.excerpt.length > 500 ? "…" : ""}`,
420
+ ])),
421
+ ].join("\n");
422
+ }
423
+
424
+ function formatPins(runtime: Ds4ContextRuntime): string {
425
+ const pins = runtime.listPins(false);
426
+ return [
427
+ "DS4 Persistent Pins",
428
+ "",
429
+ ...(pins.length === 0
430
+ ? ["No pins are available for this session/project."]
431
+ : pins.map((pin, index) => [
432
+ `${index + 1}. ${pin.id} ${pin.scope} ${pin.status} class=${pin.classification ?? "default"}${pin.supersededBy ? ` -> ${pin.supersededBy}` : ""}`,
433
+ ` created=${new Date(pin.createdAt).toISOString()}${pin.branchLeafId ? ` branch=${pin.branchLeafId}` : ""}`,
434
+ ` ${pin.content.slice(0, 500)}${pin.content.length > 500 ? "…" : ""}`,
435
+ ...(pin.statusReason ? [` reason: ${pin.statusReason}`] : []),
436
+ ].join("\n"))),
437
+ "",
438
+ "Create: /context pin [--scope session|branch|project] [--classification LEVEL] [--source ENTRY] [--file PATH] <content>",
439
+ "Replace: add --supersedes PIN_ID. Remove: /context unpin PIN_ID [reason]",
440
+ ].join("\n");
441
+ }
442
+
443
+ function formatMemory(runtime: Ds4ContextRuntime, diagnostics: RuntimeDiagnostics): string {
444
+ const memories = runtime.listMemories(false);
445
+ return [
446
+ "DS4 Durable Memory",
447
+ "",
448
+ `Status: ${diagnostics.memory.status}`,
449
+ `Active / inactive: ${count(diagnostics.memory.activeMemories)} / ${count(diagnostics.memory.inactiveMemories)}`,
450
+ `Selected / excluded: ${count(diagnostics.memory.selectedMemories.length)} / ${count(diagnostics.memory.excludedMemories)}`,
451
+ `Selected tokens: ${count(diagnostics.memory.selectedMemoryTokens)}`,
452
+ ...diagnostics.memory.warnings.map((warning) => `Warning: ${warning}`),
453
+ "",
454
+ ...(memories.length === 0
455
+ ? ["No memory items are available for this session/project."]
456
+ : memories.map((memory, index) => [
457
+ `${index + 1}. ${memory.id} ${memory.scope} ${memory.status} class=${memory.classification ?? "default"}${memory.key ? ` key=${memory.key}` : ""}${memory.supersededBy ? ` -> ${memory.supersededBy}` : ""}`,
458
+ ` sources=${memory.sourceEntryIds.join(",") || "mutation"}`,
459
+ ` ${memory.claim.slice(0, 500)}${memory.claim.length > 500 ? "…" : ""}`,
460
+ ...(memory.statusReason ? [` reason: ${memory.statusReason}`] : []),
461
+ ].join("\n"))),
462
+ "",
463
+ "Add: /context memory add [--scope session|project] [--classification LEVEL] [--key KEY] [--source ID,ID] <claim>",
464
+ "Replace: /context memory supersede MEMORY_ID [--classification LEVEL] [--source ID,ID] <new claim>",
465
+ "Invalidate/expire: /context memory invalidate|expire MEMORY_ID [reason]",
466
+ ].join("\n");
467
+ }
468
+
469
+ function formatPrivacy(diagnostics: RuntimeDiagnostics): string {
470
+ const privacy = diagnostics.privacy;
471
+ const selected = Object.entries(privacy.selectedClassifications)
472
+ .map(([classification, value]) => `${classification}=${count(value)}`)
473
+ .join(", ");
474
+ return [
475
+ "DS4 Privacy and Provider Policy",
476
+ "",
477
+ `Enabled: ${privacy.enabled ? "yes" : "no"}`,
478
+ `Provider / destination: ${privacy.provider ?? "n/a"} / ${privacy.destination ?? "n/a"}`,
479
+ `Allowed classifications: ${privacy.allowedClassifications.join(", ") || "none"}`,
480
+ `Selected classifications: ${selected}`,
481
+ `Inspected messages: ${count(privacy.inspectedMessages)}`,
482
+ `Blocked classified blocks: ${count(privacy.blockedBlocks)}`,
483
+ `Excluded source slices: ${count(privacy.excludedSources)}`,
484
+ `Credential redactions: ${count(privacy.secretRedactions)}`,
485
+ `Provider final checks: ${count(privacy.providerChecks)}`,
486
+ `Provider payload redactions:${count(privacy.providerPayloadRedactions).padStart(8)}`,
487
+ `Enforcement: ${privacy.enforcement}`,
488
+ ...privacy.warnings.map((warning) => `Warning: ${warning}`),
489
+ "",
490
+ "Classification markers: [ds4:local-only]...[/ds4:local-only] (also normal, internal, sensitive).",
491
+ "Pin/memory commands accept --classification. Local-only is never permitted by a remote allow rule.",
492
+ ].join("\n");
493
+ }
494
+
495
+ function formatModelAwareness(diagnostics: RuntimeDiagnostics): string {
496
+ const awareness = diagnostics.modelAwareness;
497
+ if (!awareness) return "No active model profile has been resolved for this session yet.";
498
+ const calibration = awareness.calibration;
499
+ const cache = calibration.cache;
500
+ const usage = diagnostics.lastManifest?.providerUsage;
501
+ const modelSwitch = awareness.switch;
502
+ return [
503
+ "DS4 Advanced Model Awareness",
504
+ "",
505
+ `Enabled: ${awareness.enabled ? "yes" : "no"}`,
506
+ `Profile: ${awareness.profileKey}`,
507
+ `Overrides: ${awareness.overrideKeys.join(", ") || "none"}`,
508
+ `Context / max output: ${count(awareness.contextWindow)} / ${count(awareness.maxOutputTokens)}`,
509
+ `Safety margin: ${count(awareness.safetyMarginTokens)}`,
510
+ `Estimator: ${calibration.estimator}`,
511
+ `Calibration ratio: ${calibration.calibrated ? `x${calibration.appliedRatio.toFixed(6)}` : "x1.000000 (neutral)"}`,
512
+ `Samples observed/accepted: ${count(calibration.observedSamples)} / ${count(calibration.acceptedSamples)}`,
513
+ `Samples rejected/outliers: ${count(calibration.rejectedSamples)} / ${count(calibration.outlierSamples)}`,
514
+ `Calibration bounds/window: ${calibration.lowerRatioBound.toFixed(2)}-${calibration.upperRatioBound.toFixed(2)} / ${count(calibration.windowSize)}`,
515
+ `Adaptive recent tail: ${count(awareness.adaptive.recentTailTokens)} (nominal ${count(awareness.adaptive.nominalRecentTailTokens)})`,
516
+ `Adaptive history retrieval: ${count(awareness.adaptive.maxRetrievedHistoryTokens)} (nominal ${count(awareness.adaptive.nominalRetrievedHistoryTokens)})`,
517
+ `Adaptive project retrieval: ${count(awareness.adaptive.maxProjectTokens)} (nominal ${count(awareness.adaptive.nominalProjectTokens)})`,
518
+ `Cache window read/write: ${count(cache.cacheReadTokens)} / ${count(cache.cacheWriteTokens)}`,
519
+ `Cache window shares: ${(cache.cacheReadShare * 100).toFixed(2)}% read / ${(cache.cacheWriteShare * 100).toFixed(2)}% write`,
520
+ `Latest input/cache read/write:${count(usage?.inputTokens).padStart(8)} / ${count(usage?.cacheReadTokens)} / ${count(usage?.cacheWriteTokens)}`,
521
+ `Model switch: ${modelSwitch ? `${modelSwitch.source}; ${modelSwitch.switched ? "cold model switch" : modelSwitch.cacheDisposition}; profile ${modelSwitch.profileReused ? "reused" : "new"}` : "n/a"}`,
522
+ ...(modelSwitch?.previousProvider && modelSwitch.previousModel
523
+ ? [`Previous profile: ${modelSwitch.previousProvider}/${modelSwitch.previousModel}`]
524
+ : []),
525
+ "",
526
+ "Calibration is isolated by exact provider/model and uses bounded median/MAD outlier rejection.",
527
+ "Provider cache state is an optimization; Pi JSONL and DS4 provenance remain canonical.",
528
+ ].join("\n");
529
+ }
530
+
531
+ function formatNativeContinuation(diagnostics: RuntimeDiagnostics): string {
532
+ const continuation = diagnostics.nativeContinuation;
533
+ const latest = continuation.last;
534
+ return [
535
+ "DS4 Optional Native Continuation",
536
+ "",
537
+ `Enabled / storage consent: ${continuation.enabled ? "yes" : "no"} / ${continuation.allowProviderStorage ? "yes" : "no"}`,
538
+ `Strategy: ${continuation.strategy}`,
539
+ `Status / state: ${continuation.status} / ${continuation.stateAvailable ? "ready" : "cold"}`,
540
+ `Profiles: ${continuation.profiles.join(", ") || "none"}`,
541
+ `Provider wrappers: ${continuation.registeredProviders.join(", ") || "none"}`,
542
+ `Requests full/native: ${count(continuation.fullReplayRequests)} / ${count(continuation.continuationRequests)}`,
543
+ `Native successes: ${count(continuation.continuationSuccesses)}`,
544
+ `Invalidations: ${count(continuation.invalidations)}`,
545
+ `Retry attempts/success/fail:${count(continuation.retryAttempts).padStart(7)} / ${count(continuation.retrySuccesses)} / ${count(continuation.retryFailures)}`,
546
+ `Latest provider/model: ${continuation.lastProvider && continuation.lastModel ? `${continuation.lastProvider}/${continuation.lastModel}` : "n/a"}`,
547
+ `Latest mode: ${latest?.mode ?? "n/a"}`,
548
+ `Latest full/sent/omitted: ${count(latest?.fullInputItems)} / ${count(latest?.sentInputItems)} / ${count(latest?.omittedInputItems)}`,
549
+ `Latest retry: ${latest?.retry ?? "n/a"}`,
550
+ ...(latest?.stateAgeMs !== undefined ? [`Latest state age: ${count(latest.stateAgeMs)} ms`] : []),
551
+ ...(latest?.fallbackReason ? [`Latest fallback: ${latest.fallbackReason}`] : []),
552
+ ...(latest?.invalidationReason ? [`Latest invalidation: ${latest.invalidationReason}`] : []),
553
+ ...continuation.warnings.map((warning) => `Warning: ${warning}`),
554
+ "",
555
+ "Provider response IDs and payload content are never included in these diagnostics or Context Manifests.",
556
+ "Eligible OpenAI Responses calls use store=true only after explicit configuration consent.",
557
+ ].join("\n");
558
+ }
559
+
560
+ function formatArtifacts(diagnostics: RuntimeDiagnostics): string {
561
+ const artifacts = diagnostics.artifacts;
562
+ return [
563
+ "DS4 Artifact Store",
564
+ "",
565
+ `Enabled: ${artifacts.enabled ? "yes" : "no"}`,
566
+ `Store: ${artifacts.storePath ?? "unavailable"}`,
567
+ `Objects / references: ${count(artifacts.stats.objects)} / ${count(artifacts.stats.references)}`,
568
+ `Stored bytes: ${count(artifacts.stats.bytes)}`,
569
+ `Missing / corrupt: ${count(artifacts.stats.missing)} / ${count(artifacts.stats.corrupt)}`,
570
+ `Current branch references:${count(artifacts.currentBranchReferences).padStart(8)}`,
571
+ `Latest offloaded: ${count(artifacts.offloadedCount)}`,
572
+ `Latest bytes offloaded: ${count(artifacts.offloadedBytes)}`,
573
+ `Estimated tokens saved: ${count(artifacts.estimatedTokensSaved)}`,
574
+ `Latest failures: ${count(artifacts.failedCount)}`,
575
+ ...artifacts.warnings.map((warning) => `Warning: ${warning}`),
576
+ "",
577
+ ...(artifacts.references.length === 0
578
+ ? ["No artifacts are referenced by the active branch."]
579
+ : artifacts.references.slice(0, 50).map((artifact, index) =>
580
+ `${index + 1}. ${artifact.artifactId} ${JSON.stringify(artifact.toolName)}/${JSON.stringify(artifact.toolCallId)} ${count(artifact.sizeBytes)} bytes ${artifact.originalTokens}->${artifact.condensedTokens} tokens ${artifact.mimeType}${artifact.isError ? " error" : ""}`
581
+ )),
582
+ ...(artifacts.references.length > 50 ? [`... ${artifacts.references.length - 50} older reference(s) omitted`] : []),
583
+ "",
584
+ "Use context_artifact_search with an Artifact ID and a narrow literal query.",
585
+ ].join("\n");
586
+ }
587
+
588
+ function formatCompaction(diagnostics: RuntimeDiagnostics, preview: boolean): string {
589
+ const compaction = diagnostics.compaction;
590
+ return [
591
+ preview ? "DS4 Compaction Preview" : "DS4 Compaction",
592
+ "",
593
+ `Custom compaction: ${compaction.enabled ? "enabled" : "disabled"}`,
594
+ `Deterministic validator: ${compaction.validate ? "enabled" : "disabled"}`,
595
+ `Preserve recent tail: ${compaction.preserveRecentVerbatim ? "yes" : "no"}`,
596
+ `Segment target: ${count(compaction.segmentTargetTokens)}`,
597
+ `Current context tokens: ${count(compaction.contextTokens)}`,
598
+ `Model soft limit: ${count(compaction.softLimitTokens)}`,
599
+ `Proactive threshold: ${count(compaction.proactiveThresholdTokens)}`,
600
+ `Would compact now: ${compaction.proactiveEligible ? "yes" : "no"}`,
601
+ `Last phase: ${compaction.phase}`,
602
+ `Last trigger: ${compaction.trigger ?? "n/a"}`,
603
+ `Summary ID: ${compaction.summaryId ?? "n/a"}`,
604
+ `Source entries: ${count(compaction.sourceEntries)}`,
605
+ `Validation: ${compaction.validationStatus ?? "n/a"}`,
606
+ `First kept entry: ${compaction.firstKeptEntryId ?? "n/a"}`,
607
+ `Tokens before: ${count(compaction.tokensBefore)}`,
608
+ ...(compaction.lastError ? [`Last error: ${compaction.lastError}`] : []),
609
+ ...(preview
610
+ ? ["", "Pi determines the exact cut point; DS4 preserves Pi's firstKeptEntryId and validates the generated summary before replacing history."]
611
+ : []),
612
+ ].join("\n");
613
+ }
614
+
615
+ export function registerContextCommand(pi: ExtensionAPI, runtime: Ds4ContextRuntime): void {
616
+ pi.registerCommand("context", {
617
+ description: "Inspect DS4 managed context, provenance, tokens, or storage health",
618
+ getArgumentCompletions: (prefix) => {
619
+ const matches = SUBCOMMANDS.filter((command) => command.startsWith(prefix.trim()));
620
+ return matches.length > 0 ? matches.map((command) => ({ value: command, label: command })) : null;
621
+ },
622
+ handler: async (args, ctx) => {
623
+ const parsedCommand = splitCommand(args, "status");
624
+ const subcommand = parsedCommand.command;
625
+ const subcommandArgs = parsedCommand.args;
626
+
627
+ try {
628
+ if (subcommand === "status") {
629
+ const diagnostics = runtime.diagnostics(ctx);
630
+ const level = diagnostics.phase === "degraded" ? "warning" : "info";
631
+ present(ctx, formatStatus(diagnostics), level);
632
+ return;
633
+ }
634
+
635
+ if (subcommand === "tokens") {
636
+ present(ctx, formatTokens(runtime.diagnostics(ctx)));
637
+ return;
638
+ }
639
+
640
+ if (subcommand === "manifest") {
641
+ present(ctx, formatManifest(runtime.diagnostics(ctx)));
642
+ return;
643
+ }
644
+
645
+ if (subcommand === "explain") {
646
+ present(ctx, formatExplain(runtime.diagnostics(ctx)));
647
+ return;
648
+ }
649
+
650
+ if (subcommand === "included" || subcommand === "excluded") {
651
+ present(ctx, formatManifestItems(runtime.diagnostics(ctx), subcommand));
652
+ return;
653
+ }
654
+
655
+ if (subcommand === "summaries") {
656
+ present(ctx, formatSummaryGraph(runtime.summaryGraph(ctx)));
657
+ return;
658
+ }
659
+
660
+ if (subcommand === "retrieved") {
661
+ present(ctx, formatRetrieved(runtime.diagnostics(ctx)));
662
+ return;
663
+ }
664
+
665
+ if (subcommand === "project") {
666
+ present(ctx, formatProject(runtime.diagnostics(ctx)));
667
+ return;
668
+ }
669
+
670
+ if (subcommand === "pins") {
671
+ present(ctx, formatPins(runtime));
672
+ return;
673
+ }
674
+
675
+ if (subcommand === "pin") {
676
+ const parsed = parseCommandArgs(subcommandArgs);
677
+ assertOptions(parsed.options, ["scope", "source", "file", "supersedes", "classification"]);
678
+ const scope = (parsed.options.get("scope") ?? "session").toLowerCase();
679
+ const classification = classificationOption(parsed.options.get("classification"));
680
+ if (scope !== "session" && scope !== "branch" && scope !== "project") {
681
+ throw new Error("Pin scope must be session, branch, or project");
682
+ }
683
+ const result = runtime.createPin({
684
+ content: parsed.positionals.join(" "),
685
+ scope,
686
+ ...(parsed.options.get("source") ? { sourceEntryId: parsed.options.get("source") } : {}),
687
+ ...(parsed.options.get("file") ? { sourceFile: parsed.options.get("file") } : {}),
688
+ ...(parsed.options.get("supersedes") ? { supersedes: parsed.options.get("supersedes") } : {}),
689
+ ...(classification ? { classification } : {}),
690
+ }, ctx, (customType, data) => pi.appendEntry(customType, data));
691
+ present(
692
+ ctx,
693
+ `${result.duplicate ? "Existing" : "Created"} ${result.pin.scope} pin ${result.pin.id}`,
694
+ );
695
+ return;
696
+ }
697
+
698
+ if (subcommand === "unpin") {
699
+ const parsed = parseCommandArgs(subcommandArgs);
700
+ assertOptions(parsed.options, []);
701
+ const pinId = parsed.positionals[0];
702
+ if (!pinId) throw new Error("Usage: /context unpin PIN_ID [reason]");
703
+ const pin = runtime.unpin(
704
+ pinId,
705
+ parsed.positionals.slice(1).join(" ") || undefined,
706
+ ctx,
707
+ (customType, data) => pi.appendEntry(customType, data),
708
+ );
709
+ present(ctx, `Pin ${pin.id} is ${pin.status}`);
710
+ return;
711
+ }
712
+
713
+ if (subcommand === "memory") {
714
+ const nested = splitCommand(subcommandArgs, "list");
715
+ if (nested.command === "list") {
716
+ present(ctx, formatMemory(runtime, runtime.diagnostics(ctx)));
717
+ return;
718
+ }
719
+ const parsed = parseCommandArgs(nested.args);
720
+ if (nested.command === "add") {
721
+ assertOptions(parsed.options, ["scope", "key", "source", "classification"]);
722
+ const scope = (parsed.options.get("scope") ?? "session").toLowerCase();
723
+ const classification = classificationOption(parsed.options.get("classification"));
724
+ if (scope !== "session" && scope !== "project") {
725
+ throw new Error("Memory scope must be session or project");
726
+ }
727
+ const result = runtime.createMemory({
728
+ claim: parsed.positionals.join(" "),
729
+ scope,
730
+ ...(parsed.options.get("key") ? { key: parsed.options.get("key") } : {}),
731
+ ...(classification ? { classification } : {}),
732
+ sourceEntryIds: sourceIds(parsed.options.get("source")),
733
+ }, ctx, (customType, data) => pi.appendEntry(customType, data));
734
+ present(
735
+ ctx,
736
+ `${result.duplicate ? "Existing" : "Created"} ${result.memory.scope} memory ${result.memory.id}`,
737
+ );
738
+ return;
739
+ }
740
+ if (nested.command === "supersede") {
741
+ assertOptions(parsed.options, ["source", "classification"]);
742
+ const previousId = parsed.positionals[0];
743
+ const claim = parsed.positionals.slice(1).join(" ");
744
+ if (!previousId || !claim) {
745
+ throw new Error("Usage: /context memory supersede MEMORY_ID [--source ID,ID] <new claim>");
746
+ }
747
+ const memory = runtime.supersedeMemory(
748
+ previousId,
749
+ claim,
750
+ sourceIds(parsed.options.get("source")),
751
+ classificationOption(parsed.options.get("classification")),
752
+ ctx,
753
+ (customType, data) => pi.appendEntry(customType, data),
754
+ );
755
+ present(ctx, `Memory ${previousId} superseded by ${memory.id}`);
756
+ return;
757
+ }
758
+ if (nested.command === "invalidate" || nested.command === "expire") {
759
+ assertOptions(parsed.options, []);
760
+ const memoryId = parsed.positionals[0];
761
+ if (!memoryId) throw new Error(`Usage: /context memory ${nested.command} MEMORY_ID [reason]`);
762
+ const memory = runtime.setMemoryStatus(
763
+ memoryId,
764
+ nested.command === "invalidate" ? "invalid" : "expired",
765
+ parsed.positionals.slice(1).join(" ") || undefined,
766
+ ctx,
767
+ (customType, data) => pi.appendEntry(customType, data),
768
+ );
769
+ present(ctx, `Memory ${memory.id} is ${memory.status}`);
770
+ return;
771
+ }
772
+ throw new Error("Usage: /context memory [list|add|supersede|invalidate|expire]");
773
+ }
774
+
775
+ if (subcommand === "privacy") {
776
+ present(ctx, formatPrivacy(runtime.diagnostics(ctx)));
777
+ return;
778
+ }
779
+
780
+ if (subcommand === "model") {
781
+ present(ctx, formatModelAwareness(runtime.diagnostics(ctx)));
782
+ return;
783
+ }
784
+
785
+ if (subcommand === "continuation") {
786
+ present(ctx, formatNativeContinuation(runtime.diagnostics(ctx)));
787
+ return;
788
+ }
789
+
790
+ if (subcommand === "artifacts") {
791
+ present(ctx, formatArtifacts(runtime.diagnostics(ctx)));
792
+ return;
793
+ }
794
+
795
+ if (subcommand === "compaction" || subcommand === "compact-preview") {
796
+ present(ctx, formatCompaction(runtime.diagnostics(ctx), subcommand === "compact-preview"));
797
+ return;
798
+ }
799
+
800
+ if (subcommand === "rebuild-index") {
801
+ await ctx.waitForIdle();
802
+ const result = runtime.rebuildIndex(ctx);
803
+ present(
804
+ ctx,
805
+ [
806
+ "DS4 Context Index Rebuilt",
807
+ "",
808
+ `Reason: ${result.reason}`,
809
+ `Processed entries: ${count(result.processedEntries)}`,
810
+ `Indexed entries: ${count(result.totalEntries)}`,
811
+ `Malformed lines: ${count(result.malformedLines)}`,
812
+ `Duration: ${result.durationMs.toFixed(1)} ms`,
813
+ `Project files: ${count(runtime.diagnostics(ctx).project.stats?.files)}`,
814
+ `Project snippets: ${count(runtime.diagnostics(ctx).project.stats?.currentSnippets)}`,
815
+ `Pins / memories: ${count(runtime.diagnostics(ctx).memory.activePins)} / ${count(runtime.diagnostics(ctx).memory.activeMemories)}`,
816
+ `Artifact references: ${count(runtime.diagnostics(ctx).artifacts.stats.references)}`,
817
+ ].join("\n"),
818
+ );
819
+ return;
820
+ }
821
+
822
+ if (subcommand === "health") {
823
+ const health = runtime.health();
824
+ if (!health) {
825
+ present(ctx, "DS4 Context Engine database is unavailable; Pi fallback remains active.", "warning");
826
+ return;
827
+ }
828
+ runtime.verifyArtifactHealth(ctx);
829
+ const diagnostics = runtime.diagnostics(ctx);
830
+ const staleProjectSnippets = diagnostics.project.stats?.staleSnippets ?? 0;
831
+ const artifactIntegrityIssues = diagnostics.artifacts.stats.missing + diagnostics.artifacts.stats.corrupt;
832
+ const healthy = health.ok
833
+ && staleProjectSnippets === 0
834
+ && diagnostics.project.status !== "failed"
835
+ && diagnostics.memory.status !== "failed"
836
+ && diagnostics.memory.warnings.length === 0
837
+ && diagnostics.privacy.warnings.length === 0
838
+ && diagnostics.nativeContinuation.warnings.length === 0
839
+ && artifactIntegrityIssues === 0
840
+ && diagnostics.artifacts.warnings.length === 0;
841
+ present(
842
+ ctx,
843
+ [
844
+ "DS4 Context Engine Health",
845
+ "",
846
+ `Status: ${healthy ? "OK" : "WARN"}`,
847
+ `SQLite quick_check: ${health.quickCheck}`,
848
+ `Journal mode: ${health.journalMode}`,
849
+ `Foreign keys: ${health.foreignKeys ? "enabled" : "disabled"}`,
850
+ `Schema version: ${health.schemaVersion}`,
851
+ `Applied migrations: ${health.appliedMigrations}`,
852
+ `Project stale snippets: ${count(staleProjectSnippets)}`,
853
+ `Memory/pin warnings: ${count(diagnostics.memory.warnings.length)}`,
854
+ `Privacy enforcement: ${diagnostics.privacy.enforcement}`,
855
+ `Privacy warnings: ${count(diagnostics.privacy.warnings.length)}`,
856
+ `Continuation warnings: ${count(diagnostics.nativeContinuation.warnings.length)}`,
857
+ `Artifact missing/corrupt: ${count(diagnostics.artifacts.stats.missing)} / ${count(diagnostics.artifacts.stats.corrupt)}`,
858
+ `Artifact warnings: ${count(diagnostics.artifacts.warnings.length)}`,
859
+ ].join("\n"),
860
+ healthy ? "info" : "warning",
861
+ );
862
+ return;
863
+ }
864
+
865
+ present(ctx, `Unknown /context command: ${subcommand}\nUsage: /context [${SUBCOMMANDS.join("|")}]`, "warning");
866
+ } catch (error) {
867
+ const message = error instanceof Error ? error.message : String(error);
868
+ present(ctx, `DS4 Context Engine diagnostics failed: ${message}`, "warning");
869
+ }
870
+ },
871
+ });
872
+ }