@devflow-tools/database 0.17.2 → 0.17.4
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/CHANGELOG.md +30 -0
- package/__tests__/database.retrieval-ledger.test.ts +15 -0
- package/__tests__/database.semantic-resolution.test.ts +87 -0
- package/__tests__/database.task-runtime.test.ts +73 -0
- package/__tests__/database.work-queue.test.ts +34 -0
- package/dist/database.d.ts +39 -0
- package/dist/database.js +395 -12
- package/dist/index.d.ts +5 -1
- package/dist/index.js +10 -1
- package/dist/retrieval-ledger.d.ts +8 -1
- package/dist/semantic-resolution.d.ts +30 -0
- package/dist/semantic-resolution.js +156 -0
- package/dist/task-runtime.d.ts +64 -0
- package/dist/task-runtime.js +106 -0
- package/dist/work-queue.d.ts +18 -2
- package/package.json +2 -2
- package/src/database.ts +423 -9
- package/src/index.ts +27 -0
- package/src/retrieval-ledger.ts +9 -2
- package/src/semantic-resolution.ts +181 -0
- package/src/task-runtime.ts +169 -0
- package/src/work-queue.ts +20 -1
- package/tsconfig.tsbuildinfo +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,36 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [0.17.4](https://github.com/shilongfeicool/dev-flow/compare/v0.17.3...v0.17.4) (2026-08-04)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **semantic:** persist resolution revisions ([cffa6ca](https://github.com/shilongfeicool/dev-flow/commit/cffa6ca24fb08b54bdd8e516167895e660c6eacc))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## [0.17.3](https://github.com/shilongfeicool/dev-flow/compare/v0.17.2...v0.17.3) (2026-08-03)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* **runtime:** enforce evidence-driven task truth ([6a8f84a](https://github.com/shilongfeicool/dev-flow/commit/6a8f84abf62666dfb7b8643fa88a5e9489940fce))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Features
|
|
26
|
+
|
|
27
|
+
* **evidence:** attribute consumed and verified retrieval ([65e5828](https://github.com/shilongfeicool/dev-flow/commit/65e5828de6d8455a2712ff78ea411aa2bf8be829))
|
|
28
|
+
* **runtime:** persist and reduce task events ([f1966c5](https://github.com/shilongfeicool/dev-flow/commit/f1966c5eaa6c023b88c4c52b3109657b7ad8cca1))
|
|
29
|
+
* **runtime:** shadow online task reduction ([c15088c](https://github.com/shilongfeicool/dev-flow/commit/c15088c9fc9434bba86bcbceeb107da36f2d9606))
|
|
30
|
+
* **semantic:** harden durable memory and knowledge work ([69eab16](https://github.com/shilongfeicool/dev-flow/commit/69eab16012ad7b3cb6a7a38ddcb1c7c1fc30054a))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
6
36
|
## [0.17.2](https://github.com/shilongfeicool/dev-flow/compare/v0.17.1...v0.17.2) (2026-08-01)
|
|
7
37
|
|
|
8
38
|
|
|
@@ -35,6 +35,21 @@ describe('retrieval ledger', () => {
|
|
|
35
35
|
database.close();
|
|
36
36
|
});
|
|
37
37
|
|
|
38
|
+
it('persists v1 provenance and reads legacy adopted rows as consumed', () => {
|
|
39
|
+
const database = createDatabase();
|
|
40
|
+
database.appendRetrievalLedgerEvent(event({
|
|
41
|
+
id: 'legacy-adopted', stage: 'adopted', taskSpecHash: 'spec:1', actor: 'tool:read',
|
|
42
|
+
sourceVersion: 'v1', sourceContentHash: 'sha256:1', evidenceIds: ['memory-a'],
|
|
43
|
+
reasonCode: 'structural_evidence_ref',
|
|
44
|
+
}));
|
|
45
|
+
expect(database.listRetrievalLedgerEvents({ projectRoot: '/project' })[0]).toMatchObject({
|
|
46
|
+
schemaVersion: 'retrieval-ledger-event.v1', stage: 'consumed', taskSpecHash: 'spec:1',
|
|
47
|
+
actor: 'tool:read', sourceVersion: 'v1', sourceContentHash: 'sha256:1',
|
|
48
|
+
evidenceIds: ['memory-a'], reasonCode: 'structural_evidence_ref',
|
|
49
|
+
});
|
|
50
|
+
database.close();
|
|
51
|
+
});
|
|
52
|
+
|
|
38
53
|
function createDatabase(): DevFlowDatabase {
|
|
39
54
|
const directory = mkdtempSync(join(tmpdir(), 'devflow-retrieval-ledger-'));
|
|
40
55
|
directories.push(directory);
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { mkdtempSync, rmSync } from 'node:fs';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
5
|
+
import { DevFlowDatabase } from '../src/database';
|
|
6
|
+
import type { SemanticResolutionRecord } from '../src/semantic-resolution';
|
|
7
|
+
|
|
8
|
+
describe('DevFlowDatabase semantic resolution persistence', () => {
|
|
9
|
+
let directory: string;
|
|
10
|
+
let database: DevFlowDatabase;
|
|
11
|
+
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
directory = mkdtempSync(join(tmpdir(), 'devflow-semantic-resolution-'));
|
|
14
|
+
database = new DevFlowDatabase(directory);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
afterEach(() => {
|
|
18
|
+
database.close();
|
|
19
|
+
rmSync(directory, { recursive: true, force: true });
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('appends, lists, and returns the latest immutable revision', () => {
|
|
23
|
+
const provisional = resolution();
|
|
24
|
+
const resolved = resolution({
|
|
25
|
+
frameHash: 'b'.repeat(64),
|
|
26
|
+
artifactHash: 'artifact:2',
|
|
27
|
+
artifactRevision: 2,
|
|
28
|
+
supersedesFrameHash: provisional.frameHash,
|
|
29
|
+
state: 'resolved',
|
|
30
|
+
frame: { frameHash: 'b'.repeat(64), state: 'resolved' },
|
|
31
|
+
createdAt: 2,
|
|
32
|
+
});
|
|
33
|
+
expect(database.appendSemanticResolution(provisional)).toBe(true);
|
|
34
|
+
expect(database.appendSemanticResolution(resolved)).toBe(true);
|
|
35
|
+
expect(database.listSemanticResolutions('/project', 'session:1', 'turn:1'))
|
|
36
|
+
.toEqual([provisional, resolved]);
|
|
37
|
+
expect(database.getLatestSemanticResolution('/project', 'session:1', 'turn:1'))
|
|
38
|
+
.toEqual(resolved);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('makes identical replay idempotent and rejects hash conflicts', () => {
|
|
42
|
+
const record = resolution();
|
|
43
|
+
expect(database.appendSemanticResolution(record)).toBe(true);
|
|
44
|
+
expect(database.appendSemanticResolution(record)).toBe(false);
|
|
45
|
+
expect(() => database.appendSemanticResolution({
|
|
46
|
+
...record,
|
|
47
|
+
durationMs: 9,
|
|
48
|
+
})).toThrow(`SEMANTIC_RESOLUTION_HASH_CONFLICT:${record.frameHash}`);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('rejects another frame at the same artifact revision', () => {
|
|
52
|
+
const record = resolution();
|
|
53
|
+
database.appendSemanticResolution(record);
|
|
54
|
+
expect(() => database.appendSemanticResolution({
|
|
55
|
+
...record,
|
|
56
|
+
frameHash: 'c'.repeat(64),
|
|
57
|
+
frame: { frameHash: 'c'.repeat(64), state: 'provisional' },
|
|
58
|
+
})).toThrow('SEMANTIC_RESOLUTION_REVISION_CONFLICT:turn:1:1');
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
function resolution(overrides: Partial<SemanticResolutionRecord> = {}): SemanticResolutionRecord {
|
|
63
|
+
const frameHash = overrides.frameHash ?? 'a'.repeat(64);
|
|
64
|
+
return {
|
|
65
|
+
frameHash,
|
|
66
|
+
projectRoot: '/project',
|
|
67
|
+
projectId: 'project:1',
|
|
68
|
+
hostId: 'claude-code',
|
|
69
|
+
sessionId: 'session:1',
|
|
70
|
+
turnId: 'turn:1',
|
|
71
|
+
requestId: 'request:1',
|
|
72
|
+
sourceHash: 'source:1',
|
|
73
|
+
artifactHash: 'artifact:1',
|
|
74
|
+
artifactRevision: 1,
|
|
75
|
+
state: 'provisional',
|
|
76
|
+
generatedBy: 'deterministic',
|
|
77
|
+
routeCatalogVersion: 'catalog.v1',
|
|
78
|
+
thresholdVersion: 'threshold.v1',
|
|
79
|
+
route: { status: 'unavailable' },
|
|
80
|
+
sampling: { attempted: false, status: 'not_needed' },
|
|
81
|
+
conflicts: [],
|
|
82
|
+
frame: { frameHash, state: 'provisional' },
|
|
83
|
+
durationMs: 0,
|
|
84
|
+
createdAt: 1,
|
|
85
|
+
...overrides,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { mkdtempSync, rmSync } from 'node:fs';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
5
|
+
import { DevFlowDatabase } from '../src/database';
|
|
6
|
+
import { stableTaskRuntimeHash, type TaskRuntimeEventRecord, type TaskRuntimeSnapshotRecord } from '../src/task-runtime';
|
|
7
|
+
|
|
8
|
+
const identity = {
|
|
9
|
+
projectRoot: '/project', projectId: 'project:1', hostId: 'claude-code',
|
|
10
|
+
sessionId: 'session:1', turnId: 'turn:1', requestId: 'request:1',
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
function event(overrides: Partial<TaskRuntimeEventRecord> = {}): TaskRuntimeEventRecord {
|
|
14
|
+
return {
|
|
15
|
+
schemaVersion: 'task-runtime-event.v1', producer: 'test', producerVersion: '1.0.0',
|
|
16
|
+
eventId: 'event:1', sequence: 1, identity, taskSpecHash: 'spec:1',
|
|
17
|
+
kind: 'task.spec.bound', payload: {}, createdAt: 1, ...overrides,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function snapshot(lastEventSequence = 1): TaskRuntimeSnapshotRecord {
|
|
22
|
+
const body = {
|
|
23
|
+
schemaVersion: 'task-runtime-snapshot.v1' as const,
|
|
24
|
+
producer: 'test', producerVersion: '1.0.0', identity, taskSpecHash: 'spec:1',
|
|
25
|
+
lastEventSequence,
|
|
26
|
+
artifacts: { requiredIdentityIds: [], resolvedIdentityIds: [], ambiguousIdentityIds: [] },
|
|
27
|
+
channels: {},
|
|
28
|
+
action: { requirement: 'not_required' as const, state: 'satisfied' as const },
|
|
29
|
+
verification: { requirement: 'not_required' as const, state: 'satisfied' as const },
|
|
30
|
+
memory: { requirement: 'required' as const, state: 'satisfied' as const },
|
|
31
|
+
durableWorkIds: [], terminal: 'completed' as const, runtimeHealth: 'healthy' as const,
|
|
32
|
+
updatedAt: lastEventSequence,
|
|
33
|
+
};
|
|
34
|
+
return { ...body, snapshotHash: stableTaskRuntimeHash(body) };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
describe('DevFlowDatabase task runtime persistence', () => {
|
|
38
|
+
let directory: string;
|
|
39
|
+
let database: DevFlowDatabase;
|
|
40
|
+
|
|
41
|
+
beforeEach(() => {
|
|
42
|
+
directory = mkdtempSync(join(tmpdir(), 'devflow-task-runtime-'));
|
|
43
|
+
database = new DevFlowDatabase(directory);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
afterEach(() => {
|
|
47
|
+
database.close();
|
|
48
|
+
rmSync(directory, { recursive: true, force: true });
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('makes identical event replay idempotent and rejects conflicting IDs or sequences', () => {
|
|
52
|
+
const first = database.appendTaskRuntimeEvent(event());
|
|
53
|
+
expect(database.appendTaskRuntimeEvent(event())).toEqual(first);
|
|
54
|
+
expect(database.listTaskRuntimeEvents('/project', 'session:1', 'turn:1')).toEqual([first]);
|
|
55
|
+
|
|
56
|
+
expect(() => database.appendTaskRuntimeEvent(event({ payload: { changed: true } })))
|
|
57
|
+
.toThrow('TASK_RUNTIME_EVENT_CONFLICT:event:1');
|
|
58
|
+
expect(() => database.appendTaskRuntimeEvent(event({ eventId: 'event:2' })))
|
|
59
|
+
.toThrow('TASK_RUNTIME_SEQUENCE_CONFLICT:1');
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('round-trips snapshots, rejects regression, and supports deterministic rebuild deletion', () => {
|
|
63
|
+
database.appendTaskRuntimeEvent(event());
|
|
64
|
+
const current = database.putTaskRuntimeSnapshot(snapshot(1));
|
|
65
|
+
expect(database.getTaskRuntimeSnapshot('/project', 'session:1', 'turn:1')).toEqual(current);
|
|
66
|
+
expect(() => database.putTaskRuntimeSnapshot(snapshot(0))).toThrow('TASK_RUNTIME_SNAPSHOT_REGRESSION');
|
|
67
|
+
|
|
68
|
+
expect(database.deleteTaskRuntimeSnapshot('/project', 'session:1', 'turn:1')).toBe(true);
|
|
69
|
+
expect(database.getTaskRuntimeSnapshot('/project', 'session:1', 'turn:1')).toBeNull();
|
|
70
|
+
expect(database.listTaskRuntimeEvents('/project', 'session:1', 'turn:1')).toEqual([event()]);
|
|
71
|
+
expect(database.putTaskRuntimeSnapshot(snapshot(1))).toEqual(current);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
@@ -166,6 +166,40 @@ describe('DevFlowDatabase durable work queue', () => {
|
|
|
166
166
|
});
|
|
167
167
|
});
|
|
168
168
|
|
|
169
|
+
it('serializes project mutations, cancels stale work, and preserves dead-letter replay lineage', () => {
|
|
170
|
+
expect(database.acquireProjectMutationLease({
|
|
171
|
+
projectRoot, mutationKind: 'knowledge_publish', owner: 'worker-a', leaseMs: 100, now: 10,
|
|
172
|
+
})).toBe(true);
|
|
173
|
+
expect(database.acquireProjectMutationLease({
|
|
174
|
+
projectRoot, mutationKind: 'knowledge_publish', owner: 'worker-b', leaseMs: 100, now: 50,
|
|
175
|
+
})).toBe(false);
|
|
176
|
+
expect(database.acquireProjectMutationLease({
|
|
177
|
+
projectRoot, mutationKind: 'knowledge_publish', owner: 'worker-b', leaseMs: 100, now: 111,
|
|
178
|
+
})).toBe(true);
|
|
179
|
+
|
|
180
|
+
const stale = database.enqueueWork({
|
|
181
|
+
idempotencyKey: 'knowledge:stale', kind: 'knowledge.ingest', projectRoot,
|
|
182
|
+
sourceHash: 'source:v1', taskSpecHash: 'spec:v1', payload: {}, nextAttemptAt: 200,
|
|
183
|
+
});
|
|
184
|
+
expect(stale.maxAttempts).toBe(3);
|
|
185
|
+
database.leaseWork({ projectRoot, owner: 'worker-b', workItemIds: [stale.id], limit: 1, leaseMs: 100, now: 200 });
|
|
186
|
+
expect(database.cancelStaleWork({
|
|
187
|
+
id: stale.id, owner: 'worker-b', sourceHash: 'source:v2', taskSpecHash: 'spec:v1', now: 210,
|
|
188
|
+
})).toBe(true);
|
|
189
|
+
expect(database.getWorkById(stale.id)).toMatchObject({ state: 'cancelled', sourceHash: 'source:v1' });
|
|
190
|
+
|
|
191
|
+
const failed = database.enqueueWork({
|
|
192
|
+
idempotencyKey: 'knowledge:dead', kind: 'knowledge.ingest', projectRoot,
|
|
193
|
+
sourceHash: 'source:dead', payload: {}, maxAttempts: 1, nextAttemptAt: 300,
|
|
194
|
+
});
|
|
195
|
+
database.leaseWork({ projectRoot, owner: 'worker-b', workItemIds: [failed.id], limit: 1, leaseMs: 100, now: 300 });
|
|
196
|
+
database.retryWork(failed.id, 'worker-b', { category: 'semantic_invalid', message: 'empty' }, 310);
|
|
197
|
+
const replay = database.replayDeadLetterWork(failed.id, {
|
|
198
|
+
idempotencyKey: 'knowledge:dead:replay:1', sourceHash: 'source:fixed', now: 320,
|
|
199
|
+
});
|
|
200
|
+
expect(replay).toMatchObject({ state: 'pending', replayOfId: failed.id, replayCount: 1, sourceHash: 'source:fixed' });
|
|
201
|
+
});
|
|
202
|
+
|
|
169
203
|
it('recovers expired leases and dead-letters exhausted work', () => {
|
|
170
204
|
database.enqueueWork({
|
|
171
205
|
idempotencyKey: 'memory:distill:retryable',
|
package/dist/database.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ import { type AddLearningCandidateEvidenceInput, type LearningCandidateEvidenceR
|
|
|
6
6
|
import { type CreateWorkflowWorkerInput, type EnqueueWorkflowMergeInput, type TransitionWorkflowWorkerInput, type WorkflowMergeRecord, type WorkflowMergeState, type WorkflowWorkerEventRecord, type WorkflowWorkerRecord } from './workflow-workers';
|
|
7
7
|
import type { RetrievalLedgerEventRecord } from './retrieval-ledger';
|
|
8
8
|
import { type ChannelQueryPlanRecord, type TaskIntentArtifactRecord, type TerminalTransitionRecord, type ToolNameResolutionRecord, type TranscriptCheckpointRecord } from './task-semantic-control';
|
|
9
|
+
import { type TaskRuntimeEventRecord, type TaskRuntimeSnapshotRecord } from './task-runtime';
|
|
10
|
+
import { type SemanticResolutionRecord } from './semantic-resolution';
|
|
9
11
|
export interface BenchmarkReportRecord {
|
|
10
12
|
runId: string;
|
|
11
13
|
suiteId: string;
|
|
@@ -389,6 +391,30 @@ export declare class DevFlowDatabase {
|
|
|
389
391
|
private insertLearningActivation;
|
|
390
392
|
enqueueWork(input: EnqueueWorkInput): WorkItemRecord;
|
|
391
393
|
getWorkByIdempotencyKey(idempotencyKey: string): WorkItemRecord | null;
|
|
394
|
+
getWorkById(id: string): WorkItemRecord | null;
|
|
395
|
+
acquireProjectMutationLease(input: {
|
|
396
|
+
projectRoot: string;
|
|
397
|
+
mutationKind: string;
|
|
398
|
+
owner: string;
|
|
399
|
+
leaseMs: number;
|
|
400
|
+
sourceHash?: string;
|
|
401
|
+
now?: number;
|
|
402
|
+
}): boolean;
|
|
403
|
+
releaseProjectMutationLease(projectRoot: string, mutationKind: string, owner: string): boolean;
|
|
404
|
+
cancelStaleWork(input: {
|
|
405
|
+
id: string;
|
|
406
|
+
owner: string;
|
|
407
|
+
sourceHash?: string;
|
|
408
|
+
taskSpecHash?: string;
|
|
409
|
+
reason?: string;
|
|
410
|
+
now?: number;
|
|
411
|
+
}): boolean;
|
|
412
|
+
replayDeadLetterWork(id: string, input: {
|
|
413
|
+
idempotencyKey: string;
|
|
414
|
+
sourceHash?: string;
|
|
415
|
+
taskSpecHash?: string;
|
|
416
|
+
now?: number;
|
|
417
|
+
}): WorkItemRecord | null;
|
|
392
418
|
requestSessionClosure(input: RequestSessionClosureInput): SessionClosureRecord;
|
|
393
419
|
getSessionClosure(projectRoot: string, sessionId: string): SessionClosureRecord | null;
|
|
394
420
|
completeSessionClosure(projectRoot: string, sessionId: string, excludingWorkItemId?: string, closedAt?: number): SessionClosureRecord;
|
|
@@ -426,6 +452,7 @@ export declare class DevFlowDatabase {
|
|
|
426
452
|
upsertContextReceipt(receipt: ContextReceiptRecord): void;
|
|
427
453
|
getContextReceipt(projectRoot: string, sessionId: string, executionId: string): ContextReceiptRecord | null;
|
|
428
454
|
getActiveContextReceipt(projectRoot: string, sessionId: string, executionId?: string, now?: number): ContextReceiptRecord | null;
|
|
455
|
+
getContextReceiptForRequest(projectRoot: string, sessionId: string, requestId: string): ContextReceiptRecord | null;
|
|
429
456
|
recordContextSelectionEvent(event: ContextSelectionEventRecord): boolean;
|
|
430
457
|
appendRetrievalLedgerEvent(event: RetrievalLedgerEventRecord): boolean;
|
|
431
458
|
appendTaskIntentArtifact(record: TaskIntentArtifactRecord): TaskIntentArtifactRecord;
|
|
@@ -441,6 +468,10 @@ export declare class DevFlowDatabase {
|
|
|
441
468
|
sessionId: string;
|
|
442
469
|
sourceHash: string;
|
|
443
470
|
}): TaskIntentArtifactRecord | null;
|
|
471
|
+
appendSemanticResolution(record: SemanticResolutionRecord): boolean;
|
|
472
|
+
getSemanticResolution(frameHash: string): SemanticResolutionRecord | null;
|
|
473
|
+
getLatestSemanticResolution(projectRoot: string, sessionId: string, turnId: string): SemanticResolutionRecord | null;
|
|
474
|
+
listSemanticResolutions(projectRoot: string, sessionId: string, turnId: string): SemanticResolutionRecord[];
|
|
444
475
|
listLatestTaskIntentArtifacts(projectRoot: string, sessionId: string): TaskIntentArtifactRecord[];
|
|
445
476
|
appendChannelQueryPlan(record: ChannelQueryPlanRecord): ChannelQueryPlanRecord;
|
|
446
477
|
getChannelQueryPlan(planHash: string): ChannelQueryPlanRecord | null;
|
|
@@ -457,6 +488,13 @@ export declare class DevFlowDatabase {
|
|
|
457
488
|
requestId?: string;
|
|
458
489
|
}): ToolNameResolutionRecord[];
|
|
459
490
|
appendTerminalTransition(record: TerminalTransitionRecord): TerminalTransitionRecord;
|
|
491
|
+
appendTaskRuntimeEvent(event: TaskRuntimeEventRecord): TaskRuntimeEventRecord;
|
|
492
|
+
getTaskRuntimeEvent(eventId: string): TaskRuntimeEventRecord | null;
|
|
493
|
+
listTaskRuntimeEvents(projectRoot: string, sessionId: string, turnId: string): TaskRuntimeEventRecord[];
|
|
494
|
+
putTaskRuntimeSnapshot(snapshot: TaskRuntimeSnapshotRecord): TaskRuntimeSnapshotRecord;
|
|
495
|
+
appendTaskRuntimeEventAndSnapshot(event: TaskRuntimeEventRecord, snapshot: TaskRuntimeSnapshotRecord): TaskRuntimeSnapshotRecord;
|
|
496
|
+
getTaskRuntimeSnapshot(projectRoot: string, sessionId: string, turnId: string): TaskRuntimeSnapshotRecord | null;
|
|
497
|
+
deleteTaskRuntimeSnapshot(projectRoot: string, sessionId: string, turnId: string): boolean;
|
|
460
498
|
getTerminalTransition(receiptId: string): TerminalTransitionRecord | null;
|
|
461
499
|
getLatestTerminalTransition(projectRoot: string, sessionId: string, turnId: string): TerminalTransitionRecord | null;
|
|
462
500
|
appendTranscriptCheckpoint(record: TranscriptCheckpointRecord): boolean;
|
|
@@ -515,6 +553,7 @@ export declare class DevFlowDatabase {
|
|
|
515
553
|
turnId: string;
|
|
516
554
|
receiptId: string;
|
|
517
555
|
reason: string;
|
|
556
|
+
source?: string;
|
|
518
557
|
decidedAt?: number;
|
|
519
558
|
}): MemoryTurnRecord;
|
|
520
559
|
markMemoryTurnStopPrompted(turnId: string, promptedAt?: number): boolean;
|