@remnic/core 9.3.691 → 9.3.693
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/dist/access-boundary.d.ts +6 -5
- package/dist/access-boundary.js +12 -12
- package/dist/access-cli.js +71 -18
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +5 -4
- package/dist/access-http.js +16 -16
- package/dist/access-mcp.d.ts +7 -4
- package/dist/access-mcp.js +15 -15
- package/dist/access-operations.d.ts +12 -6
- package/dist/access-operations.js +16 -14
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-CKnFdxH-.d.ts → access-service-DxCpgyVW.d.ts} +96 -2
- package/dist/access-service.d.ts +5 -4
- package/dist/access-service.js +11 -11
- package/dist/access-surface-catalog.d.ts +5 -4
- package/dist/access-surface-catalog.js +2 -0
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/bootstrap.d.ts +4 -3
- package/dist/{chunk-QNG35H27.js → chunk-4IQNAOP3.js} +5 -141
- package/dist/chunk-4IQNAOP3.js.map +1 -0
- package/dist/{chunk-VH2DHBHG.js → chunk-5HGPDRQZ.js} +2 -2
- package/dist/chunk-5HGPDRQZ.js.map +1 -0
- package/dist/chunk-6C2BMUZA.js +444 -0
- package/dist/chunk-6C2BMUZA.js.map +1 -0
- package/dist/{chunk-UUMYB3FR.js → chunk-6ZNIUGXB.js} +10 -10
- package/dist/{chunk-IPJD7WJH.js → chunk-E6BOD3UJ.js} +2 -2
- package/dist/{chunk-TJ5IIQIR.js → chunk-F7BVJ3IE.js} +40 -369
- package/dist/chunk-F7BVJ3IE.js.map +1 -0
- package/dist/{chunk-D3DNGQNQ.js → chunk-FM7KLRKN.js} +2 -2
- package/dist/{chunk-7MOTEVAA.js → chunk-HRUULBBV.js} +3 -1
- package/dist/chunk-HRUULBBV.js.map +1 -0
- package/dist/chunk-HXNMDPHN.js +149 -0
- package/dist/chunk-HXNMDPHN.js.map +1 -0
- package/dist/{chunk-7UVDIWLL.js → chunk-JNKH2XWQ.js} +36 -6
- package/dist/chunk-JNKH2XWQ.js.map +1 -0
- package/dist/{chunk-IPLYGWQF.js → chunk-KQAFEZQX.js} +5 -5
- package/dist/{chunk-OOO7ZKOD.js → chunk-KYH53EFD.js} +3 -3
- package/dist/{chunk-LQ6JI4VH.js → chunk-LD53WPMU.js} +4 -4
- package/dist/{chunk-KO6OL4I7.js → chunk-MQTPUPLP.js} +297 -17
- package/dist/chunk-MQTPUPLP.js.map +1 -0
- package/dist/{chunk-TSGREOYY.js → chunk-RHWFMBO5.js} +33 -6
- package/dist/chunk-RHWFMBO5.js.map +1 -0
- package/dist/{chunk-5CEJH5ZN.js → chunk-TAPSNIMA.js} +4 -4
- package/dist/{chunk-K7I24ZO2.js → chunk-THKNO6OX.js} +22 -21
- package/dist/{chunk-K7I24ZO2.js.map → chunk-THKNO6OX.js.map} +1 -1
- package/dist/{chunk-QLRYXOAD.js → chunk-UDJLF3BO.js} +2 -2
- package/dist/{chunk-NCRDCTEJ.js → chunk-WYB44HHV.js} +21 -7
- package/dist/chunk-WYB44HHV.js.map +1 -0
- package/dist/{chunk-WRFKZEO6.js → chunk-YQGHW5ML.js} +4 -4
- package/dist/{cli-CrSW_KRq.d.ts → cli-DoQsv4ut.d.ts} +2 -2
- package/dist/cli.d.ts +6 -5
- package/dist/cli.js +26 -25
- package/dist/contradiction/index.js +4 -4
- package/dist/explicit-capture.d.ts +4 -3
- package/dist/index.d.ts +6 -5
- package/dist/index.js +33 -31
- package/dist/index.js.map +1 -1
- package/dist/mcp-memory-inspector-app.d.ts +5 -4
- package/dist/namespaces/migrate.js +8 -8
- package/dist/namespaces/search.js +7 -7
- package/dist/operator-toolkit.js +11 -10
- package/dist/orchestration/maintenance.d.ts +112 -0
- package/dist/orchestration/maintenance.js +39 -0
- package/dist/orchestration/maintenance.js.map +1 -0
- package/dist/{orchestrator-DvswGK76.d.ts → orchestrator-CNJCYjZ1.d.ts} +9 -33
- package/dist/orchestrator.d.ts +2 -1
- package/dist/orchestrator.js +13 -11
- package/dist/schemas.d.ts +28 -28
- package/dist/search/factory.js +6 -6
- package/dist/search/index.js +11 -11
- package/dist/search/lancedb-backend.js +2 -2
- package/dist/search/meilisearch-backend.js +2 -2
- package/dist/search/orama-backend.js +2 -2
- package/dist/transfer/autodetect.js +1 -1
- package/dist/transfer/backup.js +1 -1
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/types.d.ts +12 -12
- package/package.json +12 -2
- package/src/access-boundary.ts +2 -1
- package/src/access-cli.ts +65 -2
- package/src/access-http.ts +20 -0
- package/src/access-mcp.ts +29 -0
- package/src/access-operations.ts +46 -0
- package/src/access-service.ts +55 -0
- package/src/access-surface-catalog.test.ts +1 -1
- package/src/access-surface-catalog.ts +2 -0
- package/src/cli.ts +1 -0
- package/src/coding/coding-namespace.ts +1 -1
- package/src/coding/session-delta-surfaces.test.ts +383 -0
- package/src/coding/session-delta-surfaces.ts +325 -0
- package/src/coding/session-delta.test.ts +411 -0
- package/src/coding/session-delta.ts +442 -0
- package/src/orchestration/maintenance.test.ts +738 -0
- package/src/orchestration/maintenance.ts +557 -0
- package/src/orchestrator-flush.test.ts +0 -599
- package/src/orchestrator.ts +33 -419
- package/dist/chunk-7MOTEVAA.js.map +0 -1
- package/dist/chunk-7UVDIWLL.js.map +0 -1
- package/dist/chunk-KO6OL4I7.js.map +0 -1
- package/dist/chunk-NCRDCTEJ.js.map +0 -1
- package/dist/chunk-QNG35H27.js.map +0 -1
- package/dist/chunk-TJ5IIQIR.js.map +0 -1
- package/dist/chunk-TSGREOYY.js.map +0 -1
- package/dist/chunk-VH2DHBHG.js.map +0 -1
- /package/dist/{chunk-UUMYB3FR.js.map → chunk-6ZNIUGXB.js.map} +0 -0
- /package/dist/{chunk-IPJD7WJH.js.map → chunk-E6BOD3UJ.js.map} +0 -0
- /package/dist/{chunk-D3DNGQNQ.js.map → chunk-FM7KLRKN.js.map} +0 -0
- /package/dist/{chunk-IPLYGWQF.js.map → chunk-KQAFEZQX.js.map} +0 -0
- /package/dist/{chunk-OOO7ZKOD.js.map → chunk-KYH53EFD.js.map} +0 -0
- /package/dist/{chunk-LQ6JI4VH.js.map → chunk-LD53WPMU.js.map} +0 -0
- /package/dist/{chunk-5CEJH5ZN.js.map → chunk-TAPSNIMA.js.map} +0 -0
- /package/dist/{chunk-QLRYXOAD.js.map → chunk-UDJLF3BO.js.map} +0 -0
- /package/dist/{chunk-WRFKZEO6.js.map → chunk-YQGHW5ML.js.map} +0 -0
package/src/access-cli.ts
CHANGED
|
@@ -15,7 +15,7 @@ import { projectTagProjectId } from "./coding/coding-namespace.js";
|
|
|
15
15
|
|
|
16
16
|
const OPENCLAW_REMNIC_PLUGIN_IDS = ["openclaw-remnic", "openclaw-engram"] as const;
|
|
17
17
|
|
|
18
|
-
type CommandName = "browse" | "store" | "decision" | "architecture";
|
|
18
|
+
type CommandName = "browse" | "store" | "decision" | "architecture" | "delta";
|
|
19
19
|
|
|
20
20
|
type ParsedArgs = {
|
|
21
21
|
command: CommandName;
|
|
@@ -138,6 +138,7 @@ function usage(): string {
|
|
|
138
138
|
" engram-access store [options]",
|
|
139
139
|
" engram-access decision [options]",
|
|
140
140
|
" engram-access architecture [options]",
|
|
141
|
+
" engram-access delta [options]",
|
|
141
142
|
"",
|
|
142
143
|
"Browse options:",
|
|
143
144
|
" --namespace <name>",
|
|
@@ -248,6 +249,17 @@ const COMMAND_SPECS: Record<CommandName, CommandSpec> = {
|
|
|
248
249
|
]),
|
|
249
250
|
flagOptions: new Set(),
|
|
250
251
|
},
|
|
252
|
+
delta: {
|
|
253
|
+
valueOptions: new Set([
|
|
254
|
+
"subcommand",
|
|
255
|
+
"namespace",
|
|
256
|
+
"session-key",
|
|
257
|
+
"principal",
|
|
258
|
+
"project-tag",
|
|
259
|
+
"repo-root",
|
|
260
|
+
]),
|
|
261
|
+
flagOptions: new Set(),
|
|
262
|
+
},
|
|
251
263
|
};
|
|
252
264
|
const BROWSE_SORT_VALUES = Object.freeze([
|
|
253
265
|
"updated_desc",
|
|
@@ -265,7 +277,7 @@ type BrowseSort = (typeof BROWSE_SORT_VALUES)[number];
|
|
|
265
277
|
* `command: commandRaw` assignment below (codex review P2).
|
|
266
278
|
*/
|
|
267
279
|
function isCommandName(value: string): value is CommandName {
|
|
268
|
-
return value === "browse" || value === "store" || value === "decision" || value === "architecture";
|
|
280
|
+
return value === "browse" || value === "store" || value === "decision" || value === "architecture" || value === "delta";
|
|
269
281
|
}
|
|
270
282
|
|
|
271
283
|
function parseArgs(argv: string[]): ParsedArgs {
|
|
@@ -636,6 +648,53 @@ async function runArchitecture(args: ParsedArgs, preferredId?: string): Promise<
|
|
|
636
648
|
console.log(JSON.stringify(output.result, null, 2));
|
|
637
649
|
}
|
|
638
650
|
|
|
651
|
+
/**
|
|
652
|
+
* Session-delta surface (issue #1548 Track A PR 4). Dispatches through the
|
|
653
|
+
* same `coding_delta` operation as the MCP tool and HTTP route — one
|
|
654
|
+
* validation boundary, three transports.
|
|
655
|
+
*/
|
|
656
|
+
async function runDelta(args: ParsedArgs, preferredId?: string): Promise<void> {
|
|
657
|
+
const subcommand = requireOption(args, "subcommand");
|
|
658
|
+
const { config, service } = buildRuntime(preferredId);
|
|
659
|
+
// Same coding-context attachment as runArchitecture/runDecision: the CLI's
|
|
660
|
+
// fresh Orchestrator has an empty session coding-context map, so attach a
|
|
661
|
+
// context BEFORE dispatching so the gate passes.
|
|
662
|
+
const projectTag = getLastOption(args, "project-tag");
|
|
663
|
+
const sessionKey = getLastOption(args, "session-key");
|
|
664
|
+
if (sessionKey && sessionKey.trim().length > 0) {
|
|
665
|
+
const repoRoot = expandOptionalPath(getLastOption(args, "repo-root")) ?? process.cwd();
|
|
666
|
+
const projectId =
|
|
667
|
+
projectTag && projectTag.trim().length > 0
|
|
668
|
+
? projectTagProjectId(projectTag.trim())
|
|
669
|
+
: projectTagProjectId(path.basename(repoRoot));
|
|
670
|
+
service.setCodingContext({
|
|
671
|
+
sessionKey,
|
|
672
|
+
codingContext: {
|
|
673
|
+
projectId,
|
|
674
|
+
branch: null,
|
|
675
|
+
rootPath: repoRoot,
|
|
676
|
+
defaultBranch: null,
|
|
677
|
+
},
|
|
678
|
+
});
|
|
679
|
+
}
|
|
680
|
+
const op = getOperation("coding_delta");
|
|
681
|
+
if (!op) {
|
|
682
|
+
throw new Error("access-boundary: operation not registered: coding_delta");
|
|
683
|
+
}
|
|
684
|
+
const output = (await op.run(
|
|
685
|
+
{
|
|
686
|
+
subcommand,
|
|
687
|
+
namespace: getLastOption(args, "namespace"),
|
|
688
|
+
sessionKey,
|
|
689
|
+
},
|
|
690
|
+
{
|
|
691
|
+
service,
|
|
692
|
+
authenticatedPrincipal: getLastOption(args, "principal") ?? config.agentAccessHttp.principal,
|
|
693
|
+
},
|
|
694
|
+
)) as { result: unknown };
|
|
695
|
+
console.log(JSON.stringify(output.result, null, 2));
|
|
696
|
+
}
|
|
697
|
+
|
|
639
698
|
export async function main(
|
|
640
699
|
argv: string[] = process.argv.slice(2),
|
|
641
700
|
options: AccessCliOptions = {},
|
|
@@ -653,6 +712,10 @@ export async function main(
|
|
|
653
712
|
await runArchitecture(args, options.preferredId);
|
|
654
713
|
return;
|
|
655
714
|
}
|
|
715
|
+
if (args.command === "delta") {
|
|
716
|
+
await runDelta(args, options.preferredId);
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
656
719
|
await runStore(args, options.preferredId);
|
|
657
720
|
}
|
|
658
721
|
|
package/src/access-http.ts
CHANGED
|
@@ -317,6 +317,7 @@ export class EngramAccessHttpServer {
|
|
|
317
317
|
emitLegacyTools: options.emitLegacyTools,
|
|
318
318
|
codingDecisionVisible: this.service.decisionRecordSurfaceVisible,
|
|
319
319
|
architectureCardVisible: this.service.architectureCardSurfaceVisible,
|
|
320
|
+
sessionDeltaVisible: this.service.sessionDeltaSurfaceVisible,
|
|
320
321
|
});
|
|
321
322
|
}
|
|
322
323
|
|
|
@@ -1386,6 +1387,25 @@ export class EngramAccessHttpServer {
|
|
|
1386
1387
|
return;
|
|
1387
1388
|
}
|
|
1388
1389
|
|
|
1390
|
+
if (req.method === "POST" && pathname === "/engram/v1/coding/delta") {
|
|
1391
|
+
// Migrated through the access boundary (issue #1525/#1548 PR4):
|
|
1392
|
+
// get is read-only with respect to user memory content. It DOES write
|
|
1393
|
+
// the operator-side state file (last-seen-head marker), but that is
|
|
1394
|
+
// bookkeeping — the same way calibration.ts writes are uncounted. No
|
|
1395
|
+
// write-quota enforcement.
|
|
1396
|
+
const body = await this.readJsonBody(req);
|
|
1397
|
+
const op = getOperation("coding_delta");
|
|
1398
|
+
if (!op) {
|
|
1399
|
+
throw new EngramAccessInputError("access-boundary: operation not registered: coding_delta");
|
|
1400
|
+
}
|
|
1401
|
+
const output = (await op.run(body, {
|
|
1402
|
+
service: this.service,
|
|
1403
|
+
authenticatedPrincipal: this.resolveRequestPrincipal(req),
|
|
1404
|
+
})) as { result: unknown };
|
|
1405
|
+
this.respondJson(res, 200, output.result);
|
|
1406
|
+
return;
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1389
1409
|
if (req.method === "POST" && pathname === "/engram/v1/suggestions") {
|
|
1390
1410
|
const body = await this.readValidatedBody(req, "suggestionSubmit");
|
|
1391
1411
|
const request = {
|
package/src/access-mcp.ts
CHANGED
|
@@ -111,6 +111,7 @@ const MCP_MIGRATED_OPERATIONS: Readonly<Record<string, OperationName>> = {
|
|
|
111
111
|
"engram.memory_store": "memory_store",
|
|
112
112
|
"engram.coding_decision": "coding_decision",
|
|
113
113
|
"engram.coding_architecture": "coding_architecture",
|
|
114
|
+
"engram.coding_delta": "coding_delta",
|
|
114
115
|
};
|
|
115
116
|
|
|
116
117
|
function resolveChatGptInspectorRecallSessionKey(
|
|
@@ -331,6 +332,7 @@ export class EngramMcpServer {
|
|
|
331
332
|
* (issue #1548 Track A PR 3, rule 39).
|
|
332
333
|
*/
|
|
333
334
|
private readonly architectureCardVisible: boolean;
|
|
335
|
+
private readonly sessionDeltaVisible: boolean;
|
|
334
336
|
|
|
335
337
|
constructor(
|
|
336
338
|
private readonly service: EngramAccessService,
|
|
@@ -341,6 +343,7 @@ export class EngramMcpServer {
|
|
|
341
343
|
emitLegacyTools?: boolean;
|
|
342
344
|
codingDecisionVisible?: boolean;
|
|
343
345
|
architectureCardVisible?: boolean;
|
|
346
|
+
sessionDeltaVisible?: boolean;
|
|
344
347
|
} = {},
|
|
345
348
|
) {
|
|
346
349
|
this.citationsEnabled = options.citationsEnabled === true;
|
|
@@ -348,6 +351,7 @@ export class EngramMcpServer {
|
|
|
348
351
|
this.emitLegacyTools = options.emitLegacyTools !== false;
|
|
349
352
|
this.codingDecisionVisible = options.codingDecisionVisible === true;
|
|
350
353
|
this.architectureCardVisible = options.architectureCardVisible === true;
|
|
354
|
+
this.sessionDeltaVisible = options.sessionDeltaVisible === true;
|
|
351
355
|
this.authenticatedPrincipal =
|
|
352
356
|
options.principal?.trim() ||
|
|
353
357
|
readEnvVar("OPENCLAW_ENGRAM_ACCESS_PRINCIPAL")?.trim() ||
|
|
@@ -2033,6 +2037,31 @@ export class EngramMcpServer {
|
|
|
2033
2037
|
);
|
|
2034
2038
|
this.tools = [...this.tools, ...architectureTools];
|
|
2035
2039
|
}
|
|
2040
|
+
if (this.sessionDeltaVisible) {
|
|
2041
|
+
const deltaTools = withToolAliases(
|
|
2042
|
+
{
|
|
2043
|
+
name: "engram.coding_delta",
|
|
2044
|
+
description:
|
|
2045
|
+
"Get the session delta (commits + touched files since last seen) for the session's coding namespace (issue #1548 Track A PR 4). Subcommand: get.",
|
|
2046
|
+
inputSchema: {
|
|
2047
|
+
type: "object",
|
|
2048
|
+
properties: {
|
|
2049
|
+
subcommand: {
|
|
2050
|
+
type: "string",
|
|
2051
|
+
enum: ["get"],
|
|
2052
|
+
description: "Which delta operation to run.",
|
|
2053
|
+
},
|
|
2054
|
+
sessionKey: { type: "string", description: "Session identifier whose coding context scopes the operation." },
|
|
2055
|
+
namespace: { type: "string", description: "Optional explicit namespace (overrides coding-context overlay)." },
|
|
2056
|
+
},
|
|
2057
|
+
required: ["subcommand"],
|
|
2058
|
+
additionalProperties: false,
|
|
2059
|
+
},
|
|
2060
|
+
},
|
|
2061
|
+
this.emitLegacyTools,
|
|
2062
|
+
);
|
|
2063
|
+
this.tools = [...this.tools, ...deltaTools];
|
|
2064
|
+
}
|
|
2036
2065
|
}
|
|
2037
2066
|
|
|
2038
2067
|
/** Get clientInfo for a specific MCP session. Returns undefined for non-MCP requests. */
|
package/src/access-operations.ts
CHANGED
|
@@ -29,6 +29,11 @@ import {
|
|
|
29
29
|
type ArchitectureSurfaceRequest,
|
|
30
30
|
type ArchitectureSurfaceResponse,
|
|
31
31
|
} from "./coding/architecture-surfaces.js";
|
|
32
|
+
import {
|
|
33
|
+
DELTA_SUBCOMMANDS,
|
|
34
|
+
type DeltaSurfaceRequest,
|
|
35
|
+
type DeltaSurfaceResponse,
|
|
36
|
+
} from "./coding/session-delta-surfaces.js";
|
|
32
37
|
|
|
33
38
|
// ---------------------------------------------------------------------------
|
|
34
39
|
// memory_get — fetch one memory by id
|
|
@@ -250,6 +255,46 @@ export const codingArchitectureOperation = defineOperation<
|
|
|
250
255
|
},
|
|
251
256
|
});
|
|
252
257
|
|
|
258
|
+
// ---------------------------------------------------------------------------
|
|
259
|
+
// coding_delta — session-delta surface (issue #1548 Track A PR 4)
|
|
260
|
+
// ---------------------------------------------------------------------------
|
|
261
|
+
|
|
262
|
+
const codingDeltaSchema = z.preprocess(
|
|
263
|
+
(data) => {
|
|
264
|
+
if (data !== null && typeof data === "object" && !Array.isArray(data)) {
|
|
265
|
+
const obj = data as Record<string, unknown>;
|
|
266
|
+
const cleaned: Record<string, unknown> = {};
|
|
267
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
268
|
+
if (value !== null) cleaned[key] = value;
|
|
269
|
+
}
|
|
270
|
+
return cleaned;
|
|
271
|
+
}
|
|
272
|
+
return data;
|
|
273
|
+
},
|
|
274
|
+
z.object({
|
|
275
|
+
subcommand: z.enum(DELTA_SUBCOMMANDS),
|
|
276
|
+
sessionKey: z.string().trim().max(512).optional(),
|
|
277
|
+
namespace: z.string().trim().max(256).optional(),
|
|
278
|
+
}),
|
|
279
|
+
);
|
|
280
|
+
|
|
281
|
+
export type CodingDeltaInput = DeltaSurfaceRequest;
|
|
282
|
+
export type CodingDeltaOutput = { result: DeltaSurfaceResponse };
|
|
283
|
+
|
|
284
|
+
export const codingDeltaOperation = defineOperation<
|
|
285
|
+
CodingDeltaInput,
|
|
286
|
+
CodingDeltaOutput
|
|
287
|
+
>({
|
|
288
|
+
name: "coding_delta",
|
|
289
|
+
description:
|
|
290
|
+
"Get the session delta (commits + touched files since last seen) for the session's coding namespace (issue #1548 Track A PR 4).",
|
|
291
|
+
schema: codingDeltaSchema as z.ZodType<CodingDeltaInput>,
|
|
292
|
+
handler: async (input, ctx) => {
|
|
293
|
+
const result = await ctx.service.codingDelta(input, ctx.authenticatedPrincipal);
|
|
294
|
+
return { result };
|
|
295
|
+
},
|
|
296
|
+
});
|
|
297
|
+
|
|
253
298
|
// ---------------------------------------------------------------------------
|
|
254
299
|
// Surface registration map — what each transport calls the pilot ops
|
|
255
300
|
// ---------------------------------------------------------------------------
|
|
@@ -265,4 +310,5 @@ export const REGISTERED_OPERATIONS = [
|
|
|
265
310
|
memoryStoreOperation.spec.name,
|
|
266
311
|
codingDecisionOperation.spec.name,
|
|
267
312
|
codingArchitectureOperation.spec.name,
|
|
313
|
+
codingDeltaOperation.spec.name,
|
|
268
314
|
] as const;
|
package/src/access-service.ts
CHANGED
|
@@ -28,6 +28,13 @@ import {
|
|
|
28
28
|
ARCHITECTURE_CARD_TAG,
|
|
29
29
|
} from "./coding/architecture-surfaces.js";
|
|
30
30
|
import { buildArchitectureCard, createArchitectureCardSummariser } from "./coding/architecture-card.js";
|
|
31
|
+
import {
|
|
32
|
+
handleCodingDelta,
|
|
33
|
+
type DeltaSurfaceRequest,
|
|
34
|
+
type DeltaSurfaceResponse,
|
|
35
|
+
type DeltaSurfaceStorage,
|
|
36
|
+
} from "./coding/session-delta-surfaces.js";
|
|
37
|
+
import { defaultGitInvoker } from "./coding/git-context.js";
|
|
31
38
|
import { createVersion } from "./page-versioning.js";
|
|
32
39
|
import { WorkStorage } from "./work/storage.js";
|
|
33
40
|
import {
|
|
@@ -4545,6 +4552,54 @@ export class EngramAccessService {
|
|
|
4545
4552
|
});
|
|
4546
4553
|
}
|
|
4547
4554
|
|
|
4555
|
+
/** Whether the coding_delta tool should appear in tools/list (rule 39). */
|
|
4556
|
+
get sessionDeltaSurfaceVisible(): boolean {
|
|
4557
|
+
return this.orchestrator.config.codingKnowledge?.enabled === true
|
|
4558
|
+
&& this.orchestrator.config.codingKnowledge?.sessionDelta === true;
|
|
4559
|
+
}
|
|
4560
|
+
/**
|
|
4561
|
+
* Thin delegate — handler logic in coding/session-delta-surfaces.ts (#1548 PR4).
|
|
4562
|
+
* All three surfaces (MCP/HTTP/CLI) arrive here via the boundary operation.
|
|
4563
|
+
* Namespace resolution uses the SAME coding-scoped read path as the other
|
|
4564
|
+
* coding surfaces; the delta state file lives under
|
|
4565
|
+
* `<memoryDir>/state/coding-knowledge/<namespace>.json`.
|
|
4566
|
+
*/
|
|
4567
|
+
async codingDelta(
|
|
4568
|
+
request: DeltaSurfaceRequest,
|
|
4569
|
+
authenticatedPrincipal?: string,
|
|
4570
|
+
): Promise<DeltaSurfaceResponse> {
|
|
4571
|
+
return handleCodingDelta(request, {
|
|
4572
|
+
codingKnowledge: this.orchestrator.config.codingKnowledge,
|
|
4573
|
+
getCodingContext: (sk) => this.orchestrator.getCodingContextForSession(sk),
|
|
4574
|
+
resolveStorage: async (req) => {
|
|
4575
|
+
const ns = await this.resolveCodingScopedReadableNamespace({
|
|
4576
|
+
namespace: req.namespace,
|
|
4577
|
+
sessionKey: req.sessionKey,
|
|
4578
|
+
authenticatedPrincipal,
|
|
4579
|
+
});
|
|
4580
|
+
const storage = await this.orchestrator.getStorage(ns);
|
|
4581
|
+
// Delta only needs memoryDir + namespace (no readAllMemories). Use the
|
|
4582
|
+
// namespace-ROUTED root (storage.dir), not the global config.memoryDir:
|
|
4583
|
+
// non-default namespaces route to memoryDir/namespaces/<token>, so
|
|
4584
|
+
// session-delta markers must read/write from the routed tree, mirroring
|
|
4585
|
+
// the decision/architecture siblings (cursor review).
|
|
4586
|
+
return {
|
|
4587
|
+
memoryDir: storage.dir,
|
|
4588
|
+
namespace: ns,
|
|
4589
|
+
} satisfies DeltaSurfaceStorage;
|
|
4590
|
+
},
|
|
4591
|
+
gitInvoker: (cwd, args) => {
|
|
4592
|
+
// Reuse the existing defaultGitInvoker (2s timeout, never throws —
|
|
4593
|
+
// the discipline git-context.ts already established). It returns
|
|
4594
|
+
// { stdout, exitCode } so the handler can recover from non-zero
|
|
4595
|
+
// exits without a try/catch.
|
|
4596
|
+
const invoker = defaultGitInvoker();
|
|
4597
|
+
return invoker(cwd, args);
|
|
4598
|
+
},
|
|
4599
|
+
throwInputError: (msg) => { throw new EngramAccessInputError(msg); },
|
|
4600
|
+
});
|
|
4601
|
+
}
|
|
4602
|
+
|
|
4548
4603
|
async memoryBrowse(
|
|
4549
4604
|
request: EngramAccessMemoryBrowseRequest = {},
|
|
4550
4605
|
): Promise<EngramAccessMemoryBrowseResponse> {
|
|
@@ -67,7 +67,7 @@ function shortToolName(advertised: string): string {
|
|
|
67
67
|
/** Spin up a server with emitLegacyTools=true and read the deduped short names. */
|
|
68
68
|
async function liveMcpToolShortNames(): Promise<ReadonlySet<string>> {
|
|
69
69
|
const stub = { briefingEnabled: true } as unknown as EngramAccessService;
|
|
70
|
-
const server = new EngramMcpServer(stub, { emitLegacyTools: true, codingDecisionVisible: true, architectureCardVisible: true });
|
|
70
|
+
const server = new EngramMcpServer(stub, { emitLegacyTools: true, codingDecisionVisible: true, architectureCardVisible: true, sessionDeltaVisible: true });
|
|
71
71
|
const response = await server.handleRequest({ jsonrpc: "2.0", id: 1, method: "tools/list" });
|
|
72
72
|
const result = (response as { result?: { tools?: Array<{ name: string }> } }).result;
|
|
73
73
|
const names = new Set<string>();
|
|
@@ -74,6 +74,7 @@ export const MCP_TOOLS: readonly McpToolEntry[] = [
|
|
|
74
74
|
{ tool: "memory_store", operation: "memory_store" },
|
|
75
75
|
{ tool: "coding_decision", operation: "coding_decision" },
|
|
76
76
|
{ tool: "coding_architecture", operation: "coding_architecture" },
|
|
77
|
+
{ tool: "coding_delta", operation: "coding_delta" },
|
|
77
78
|
{ tool: "suggestion_submit", operation: null },
|
|
78
79
|
{ tool: "entity_get", operation: null },
|
|
79
80
|
{ tool: "review_queue_list", operation: null },
|
|
@@ -172,6 +173,7 @@ export const HTTP_ROUTES: readonly HttpRouteEntry[] = [
|
|
|
172
173
|
{ method: "POST", pathname: "/engram/v1/memories", operation: "memory_store" },
|
|
173
174
|
{ method: "POST", pathname: "/engram/v1/coding/decisions", operation: "coding_decision" },
|
|
174
175
|
{ method: "POST", pathname: "/engram/v1/coding/architecture", operation: "coding_architecture" },
|
|
176
|
+
{ method: "POST", pathname: "/engram/v1/coding/delta", operation: "coding_delta" },
|
|
175
177
|
{ method: "POST", pathname: "/engram/v1/suggestions", operation: null },
|
|
176
178
|
{ method: "GET", pathname: "/engram/v1/memories", operation: null },
|
|
177
179
|
{ method: "GET", pathname: "/engram/v1/memories/:id", operation: "memory_get" },
|
package/src/cli.ts
CHANGED
|
@@ -2803,6 +2803,7 @@ export async function runAccessMcpServeCliCommand(
|
|
|
2803
2803
|
emitLegacyTools: options.emitLegacyTools,
|
|
2804
2804
|
codingDecisionVisible: service.decisionRecordSurfaceVisible,
|
|
2805
2805
|
architectureCardVisible: service.architectureCardSurfaceVisible,
|
|
2806
|
+
sessionDeltaVisible: service.sessionDeltaSurfaceVisible,
|
|
2806
2807
|
});
|
|
2807
2808
|
await server.runStdio(options.stdin ?? process.stdin, options.stdout ?? process.stdout);
|
|
2808
2809
|
return { ok: true };
|
|
@@ -66,7 +66,7 @@ export interface CodingNamespaceOverlay {
|
|
|
66
66
|
* greedy quantifiers) closes the polynomial-backtracking surface that
|
|
67
67
|
* CodeQL flagged on patterns like `-+` and `^-+|-+$`.
|
|
68
68
|
*/
|
|
69
|
-
function sanitizeFragment(input: string): string {
|
|
69
|
+
export function sanitizeFragment(input: string): string {
|
|
70
70
|
if (typeof input !== "string") return "";
|
|
71
71
|
const trimmed = input.trim().toLowerCase();
|
|
72
72
|
let out = "";
|