engineering-memory 0.2.5 → 0.2.6
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "engineering-memory",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "Installs the Engineering Memory skill and its local MCP bridge. Sign in after installing; your organization and project are resolved from your account.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -25,8 +25,26 @@ export const validationIds = [
|
|
|
25
25
|
export class BridgeService {
|
|
26
26
|
dependencies;
|
|
27
27
|
taskQueues = new Map();
|
|
28
|
+
deferDeliveries;
|
|
29
|
+
backgroundDelivery = Promise.resolve();
|
|
28
30
|
constructor(dependencies) {
|
|
29
31
|
this.dependencies = dependencies;
|
|
32
|
+
this.deferDeliveries = dependencies.deferDeliveries ?? true;
|
|
33
|
+
}
|
|
34
|
+
deliverInBackground() {
|
|
35
|
+
if (!this.deferDeliveries)
|
|
36
|
+
return;
|
|
37
|
+
this.backgroundDelivery = this.backgroundDelivery.then(async () => {
|
|
38
|
+
try {
|
|
39
|
+
await this.flushOutbox();
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
async settleDeliveries() {
|
|
47
|
+
await this.backgroundDelivery;
|
|
30
48
|
}
|
|
31
49
|
async sessionBootstrap(input) {
|
|
32
50
|
return await this.execute(async () => {
|
|
@@ -676,15 +694,31 @@ export class BridgeService {
|
|
|
676
694
|
}));
|
|
677
695
|
assertSafeToPersist(cleanJson({ entries }));
|
|
678
696
|
const snapshot = await this.activeTaskSnapshot(input.taskId, undefined, input.repoRoot);
|
|
697
|
+
const body = cleanJson({
|
|
698
|
+
taskId: input.taskId,
|
|
699
|
+
entries,
|
|
700
|
+
expectedTaskVersion: snapshot.taskVersion,
|
|
701
|
+
});
|
|
702
|
+
await this.dependencies.gate.invalidateTask(input.taskId);
|
|
703
|
+
if (this.deferDeliveries) {
|
|
704
|
+
const queued = await this.dependencies.outbox.enqueue({
|
|
705
|
+
operation: 'task.reconcile',
|
|
706
|
+
method: 'POST',
|
|
707
|
+
path: endpoints.taskReconcile,
|
|
708
|
+
body,
|
|
709
|
+
});
|
|
710
|
+
this.deliverInBackground();
|
|
711
|
+
return asJsonValue({
|
|
712
|
+
reconciled: entries.map((entry) => entry.resourceId),
|
|
713
|
+
queued: true,
|
|
714
|
+
outboxId: queued.id,
|
|
715
|
+
deliveryStatus: 'pending',
|
|
716
|
+
});
|
|
717
|
+
}
|
|
679
718
|
const response = await this.dependencies.client.request(endpoints.taskReconcile, {
|
|
680
719
|
method: 'POST',
|
|
681
|
-
body
|
|
682
|
-
taskId: input.taskId,
|
|
683
|
-
entries,
|
|
684
|
-
expectedTaskVersion: snapshot.taskVersion,
|
|
685
|
-
}),
|
|
720
|
+
body,
|
|
686
721
|
});
|
|
687
|
-
await this.dependencies.gate.invalidateTask(input.taskId);
|
|
688
722
|
return asJsonValue({ reconciliations: response.data });
|
|
689
723
|
});
|
|
690
724
|
}
|
|
@@ -1363,7 +1397,10 @@ export class BridgeService {
|
|
|
1363
1397
|
assertSafeToPersist(cleanJson(safeInput));
|
|
1364
1398
|
return await this.taskExclusive(input.taskId, async () => {
|
|
1365
1399
|
await this.recoverJournalOutbox(input.projectId, input.taskSlug);
|
|
1366
|
-
|
|
1400
|
+
if (this.deferDeliveries)
|
|
1401
|
+
this.deliverInBackground();
|
|
1402
|
+
else
|
|
1403
|
+
await this.flushOutbox();
|
|
1367
1404
|
const journalInput = {
|
|
1368
1405
|
eventId: idempotencyKey,
|
|
1369
1406
|
taskId: input.taskId,
|
|
@@ -1426,7 +1463,8 @@ export class BridgeService {
|
|
|
1426
1463
|
await this.dependencies.activeContexts.updateTaskSnapshot(input.taskId, expectedTaskVersion + 1, pointer.lastSequence + 1);
|
|
1427
1464
|
}
|
|
1428
1465
|
const predecessorEntries = taskEntries.filter((entry) => entry.id !== queued.id);
|
|
1429
|
-
if (predecessorEntries.length > 0) {
|
|
1466
|
+
if (predecessorEntries.length > 0 || this.deferDeliveries) {
|
|
1467
|
+
this.deliverInBackground();
|
|
1430
1468
|
return asJsonValue({
|
|
1431
1469
|
local: { directory: staged.directory, applied: staged.applied },
|
|
1432
1470
|
queued: true,
|
|
@@ -45,7 +45,9 @@ answer in the design; do not spend the read there.
|
|
|
45
45
|
|
|
46
46
|
Do not pull history for everything. Pull it for the records the task actually touches, and for anything the header shows a surprising number of corrections on. Record `task.checkpoint` with type `discovery` and update STATE, DECISIONS, DISCOVERY, and HANDOFF projections through the bridge.
|
|
47
47
|
|
|
48
|
-
Send calls that do not feed each other in one batch rather than one at a time: reads of any kind, and proposals for different records. Reconcile every record the task touched in a single `task.reconcile` call with `entries`, not one call per record.
|
|
48
|
+
Send calls that do not feed each other in one batch rather than one at a time: reads of any kind, and proposals for different records. Reconcile every record the task touched in a single `task.reconcile` call with `entries`, not one call per record.
|
|
49
|
+
|
|
50
|
+
Checkpoints, recorded corrections and reconciliations return before the backend has them, reporting `deliveryStatus: 'pending'` with the task version they will occupy. That is a completed call, not a pending one: the journal is already durable, delivery is already under way, and `task.verify` refuses while anything remains undelivered. Do not wait for it, poll it, or send it again. Wait only for what the next step uses — a proposal's identifiers, an approval's revision, a prepared lease, and verification itself.
|
|
49
51
|
|
|
50
52
|
Temporary code written to reach or force a path — a pinned state, a fixed service response, a jump straight to the screen — is allowed and expected, carries the marker `ENGINEERING-MEMORY-TEMPORARY` with its reason, and is removed before verification. `task.verify` refuses while any marker is in the tree and names every line, and the commit gate refuses while one is staged.
|
|
51
53
|
|