@devflow-tools/database 0.17.0 → 0.17.2

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,79 @@
1
+ export interface TaskIdentityRecord {
2
+ projectRoot: string;
3
+ projectId: string;
4
+ hostId: string;
5
+ sessionId: string;
6
+ turnId: string;
7
+ requestId: string;
8
+ executionId?: string;
9
+ }
10
+ export interface TaskIntentArtifactRecord extends TaskIdentityRecord {
11
+ version: number;
12
+ supersedesHash?: string;
13
+ rawPrompt: string;
14
+ normalizedPrompt: string;
15
+ command?: string;
16
+ slashArgs: string[];
17
+ activeSkill?: string;
18
+ intent: string;
19
+ action: string;
20
+ entities: string[];
21
+ targetAnchors: string[];
22
+ policyConstraints: string[];
23
+ classificationEvidence: Array<Record<string, unknown>>;
24
+ sourceEventIds: string[];
25
+ sourceHash: string;
26
+ artifactHash: string;
27
+ createdAt: number;
28
+ }
29
+ export interface ChannelQueryPlanRecord extends TaskIdentityRecord {
30
+ sourceIntentHash: string;
31
+ planHash: string;
32
+ code: Array<Record<string, unknown>>;
33
+ memory: Array<Record<string, unknown>>;
34
+ knowledge: Array<Record<string, unknown>>;
35
+ generatedBy: 'deterministic' | 'host_semantic' | 'hybrid';
36
+ degradation?: Record<string, unknown>;
37
+ createdAt: number;
38
+ }
39
+ export type ToolNameResolutionStatus = 'canonical' | 'alias' | 'unsupported';
40
+ export interface ToolNameResolutionRecord extends TaskIdentityRecord {
41
+ id: string;
42
+ sourceHash: string;
43
+ requestedName: string;
44
+ canonicalName?: string;
45
+ projectedName?: string;
46
+ status: ToolNameResolutionStatus;
47
+ attempt: number;
48
+ capabilityMechanism?: string;
49
+ reason?: string;
50
+ createdAt: number;
51
+ }
52
+ export interface TerminalTransitionRecord extends TaskIdentityRecord {
53
+ sequence: number;
54
+ fromState?: string;
55
+ toState: string;
56
+ receiptId: string;
57
+ sourceReceiptId?: string;
58
+ reason: string;
59
+ payload: Record<string, unknown>;
60
+ createdAt: number;
61
+ }
62
+ export interface TranscriptCheckpointRecord {
63
+ id: string;
64
+ projectRoot: string;
65
+ hostId: string;
66
+ sessionId: string;
67
+ sourcePath: string;
68
+ sourceHash: string;
69
+ byteOffset: number;
70
+ eventCount: number;
71
+ createdAt: number;
72
+ }
73
+ export declare function stableSemanticJson(value: unknown): string;
74
+ export declare function mapTaskIntentArtifactRow(row: Record<string, unknown>): TaskIntentArtifactRecord;
75
+ export declare function mapChannelQueryPlanRow(row: Record<string, unknown>): ChannelQueryPlanRecord;
76
+ export declare function mapToolNameResolutionRow(row: Record<string, unknown>): ToolNameResolutionRecord;
77
+ export declare function mapTerminalTransitionRow(row: Record<string, unknown>): TerminalTransitionRecord;
78
+ export declare function mapTranscriptCheckpointRow(row: Record<string, unknown>): TranscriptCheckpointRecord;
79
+ export declare function assertTaskIdentity(record: TaskIdentityRecord): void;
@@ -0,0 +1,196 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.stableSemanticJson = stableSemanticJson;
4
+ exports.mapTaskIntentArtifactRow = mapTaskIntentArtifactRow;
5
+ exports.mapChannelQueryPlanRow = mapChannelQueryPlanRow;
6
+ exports.mapToolNameResolutionRow = mapToolNameResolutionRow;
7
+ exports.mapTerminalTransitionRow = mapTerminalTransitionRow;
8
+ exports.mapTranscriptCheckpointRow = mapTranscriptCheckpointRow;
9
+ exports.assertTaskIdentity = assertTaskIdentity;
10
+ function stableSemanticJson(value) {
11
+ return JSON.stringify(canonicalize(value));
12
+ }
13
+ function mapTaskIntentArtifactRow(row) {
14
+ return {
15
+ ...mapTaskIdentityRow(row),
16
+ version: requiredPositiveInteger(row.version, 'version'),
17
+ supersedesHash: optionalString(row.supersedes_hash),
18
+ rawPrompt: requiredString(row.raw_prompt, 'raw_prompt'),
19
+ normalizedPrompt: requiredString(row.normalized_prompt, 'normalized_prompt'),
20
+ command: optionalString(row.command),
21
+ slashArgs: parseStringArray(row.slash_args_json, 'slash_args_json'),
22
+ activeSkill: optionalString(row.active_skill),
23
+ intent: requiredString(row.intent, 'intent'),
24
+ action: requiredString(row.action, 'action'),
25
+ entities: parseStringArray(row.entities_json, 'entities_json'),
26
+ targetAnchors: parseStringArray(row.target_anchors_json, 'target_anchors_json'),
27
+ policyConstraints: parseStringArray(row.policy_constraints_json, 'policy_constraints_json'),
28
+ classificationEvidence: parseObjectArray(row.classification_evidence_json, 'classification_evidence_json'),
29
+ sourceEventIds: parseStringArray(row.source_event_ids_json, 'source_event_ids_json'),
30
+ sourceHash: requiredString(row.source_hash, 'source_hash'),
31
+ artifactHash: requiredString(row.artifact_hash, 'artifact_hash'),
32
+ createdAt: requiredNonNegativeInteger(row.created_at, 'created_at'),
33
+ };
34
+ }
35
+ function mapChannelQueryPlanRow(row) {
36
+ const generatedBy = requiredString(row.generated_by, 'generated_by');
37
+ if (generatedBy !== 'deterministic' && generatedBy !== 'host_semantic' && generatedBy !== 'hybrid') {
38
+ throw new Error(`Invalid persisted generated_by: ${generatedBy}`);
39
+ }
40
+ return {
41
+ ...mapTaskIdentityRow(row),
42
+ sourceIntentHash: requiredString(row.source_intent_hash, 'source_intent_hash'),
43
+ planHash: requiredString(row.plan_hash, 'plan_hash'),
44
+ code: parseObjectArray(row.code_queries_json, 'code_queries_json'),
45
+ memory: parseObjectArray(row.memory_queries_json, 'memory_queries_json'),
46
+ knowledge: parseObjectArray(row.knowledge_queries_json, 'knowledge_queries_json'),
47
+ generatedBy,
48
+ degradation: parseOptionalObject(row.degradation_json, 'degradation_json'),
49
+ createdAt: requiredNonNegativeInteger(row.created_at, 'created_at'),
50
+ };
51
+ }
52
+ function mapToolNameResolutionRow(row) {
53
+ const status = requiredString(row.status, 'status');
54
+ if (status !== 'canonical' && status !== 'alias' && status !== 'unsupported') {
55
+ throw new Error(`Invalid persisted tool resolution status: ${status}`);
56
+ }
57
+ return {
58
+ ...mapTaskIdentityRow(row),
59
+ id: requiredString(row.id, 'id'),
60
+ sourceHash: requiredString(row.source_hash, 'source_hash'),
61
+ requestedName: requiredString(row.requested_name, 'requested_name'),
62
+ canonicalName: optionalString(row.canonical_name),
63
+ projectedName: optionalString(row.projected_name),
64
+ status,
65
+ attempt: requiredNonNegativeInteger(row.attempt, 'attempt'),
66
+ capabilityMechanism: optionalString(row.capability_mechanism),
67
+ reason: optionalString(row.reason),
68
+ createdAt: requiredNonNegativeInteger(row.created_at, 'created_at'),
69
+ };
70
+ }
71
+ function mapTerminalTransitionRow(row) {
72
+ return {
73
+ ...mapTaskIdentityRow(row),
74
+ sequence: requiredPositiveInteger(row.sequence, 'sequence'),
75
+ fromState: optionalString(row.from_state),
76
+ toState: requiredString(row.to_state, 'to_state'),
77
+ receiptId: requiredString(row.receipt_id, 'receipt_id'),
78
+ sourceReceiptId: optionalString(row.source_receipt_id),
79
+ reason: requiredString(row.reason, 'reason'),
80
+ payload: parseObject(row.payload_json, 'payload_json'),
81
+ createdAt: requiredNonNegativeInteger(row.created_at, 'created_at'),
82
+ };
83
+ }
84
+ function mapTranscriptCheckpointRow(row) {
85
+ return {
86
+ id: requiredString(row.id, 'id'),
87
+ projectRoot: requiredString(row.project_root, 'project_root'),
88
+ hostId: requiredString(row.host_id, 'host_id'),
89
+ sessionId: requiredString(row.session_id, 'session_id'),
90
+ sourcePath: requiredString(row.source_path, 'source_path'),
91
+ sourceHash: requiredString(row.source_hash, 'source_hash'),
92
+ byteOffset: requiredNonNegativeInteger(row.byte_offset, 'byte_offset'),
93
+ eventCount: requiredNonNegativeInteger(row.event_count, 'event_count'),
94
+ createdAt: requiredNonNegativeInteger(row.created_at, 'created_at'),
95
+ };
96
+ }
97
+ function assertTaskIdentity(record) {
98
+ for (const [field, value] of Object.entries({
99
+ projectRoot: record.projectRoot,
100
+ projectId: record.projectId,
101
+ hostId: record.hostId,
102
+ sessionId: record.sessionId,
103
+ turnId: record.turnId,
104
+ requestId: record.requestId,
105
+ })) {
106
+ if (typeof value !== 'string' || value.trim().length === 0) {
107
+ throw new Error(`TASK_IDENTITY_INVALID:${field}`);
108
+ }
109
+ }
110
+ if (record.executionId !== undefined && record.executionId.trim().length === 0) {
111
+ throw new Error('TASK_IDENTITY_INVALID:executionId');
112
+ }
113
+ }
114
+ function mapTaskIdentityRow(row) {
115
+ return {
116
+ projectRoot: requiredString(row.project_root, 'project_root'),
117
+ projectId: requiredString(row.project_id, 'project_id'),
118
+ hostId: requiredString(row.host_id, 'host_id'),
119
+ sessionId: requiredString(row.session_id, 'session_id'),
120
+ turnId: requiredString(row.turn_id, 'turn_id'),
121
+ requestId: requiredString(row.request_id, 'request_id'),
122
+ executionId: optionalString(row.execution_id),
123
+ };
124
+ }
125
+ function canonicalize(value) {
126
+ if (value === null || typeof value === 'string' || typeof value === 'boolean')
127
+ return value;
128
+ if (typeof value === 'number') {
129
+ if (!Number.isFinite(value) || Object.is(value, -0))
130
+ throw new Error('Semantic control evidence must be lossless JSON');
131
+ return value;
132
+ }
133
+ if (Array.isArray(value))
134
+ return value.map(canonicalize);
135
+ if (!value || typeof value !== 'object' || Object.getPrototypeOf(value) !== Object.prototype) {
136
+ throw new Error('Semantic control evidence must be plain JSON');
137
+ }
138
+ const record = value;
139
+ return Object.fromEntries(Object.keys(record).sort().map(key => [key, canonicalize(record[key])]));
140
+ }
141
+ function parseJson(value, field) {
142
+ if (typeof value !== 'string')
143
+ throw new Error(`Invalid persisted ${field}: expected JSON text`);
144
+ try {
145
+ return JSON.parse(value);
146
+ }
147
+ catch {
148
+ throw new Error(`Invalid persisted ${field}: malformed JSON`);
149
+ }
150
+ }
151
+ function parseStringArray(value, field) {
152
+ const parsed = parseJson(value, field);
153
+ if (!Array.isArray(parsed) || parsed.some(item => typeof item !== 'string')) {
154
+ throw new Error(`Invalid persisted ${field}: expected string array`);
155
+ }
156
+ return parsed;
157
+ }
158
+ function parseObjectArray(value, field) {
159
+ const parsed = parseJson(value, field);
160
+ if (!Array.isArray(parsed) || parsed.some(item => !item || typeof item !== 'object' || Array.isArray(item))) {
161
+ throw new Error(`Invalid persisted ${field}: expected object array`);
162
+ }
163
+ return parsed;
164
+ }
165
+ function parseObject(value, field) {
166
+ const parsed = parseJson(value, field);
167
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
168
+ throw new Error(`Invalid persisted ${field}: expected object`);
169
+ }
170
+ return parsed;
171
+ }
172
+ function parseOptionalObject(value, field) {
173
+ if (value === null || value === undefined)
174
+ return undefined;
175
+ return parseObject(value, field);
176
+ }
177
+ function requiredString(value, field) {
178
+ if (typeof value !== 'string' || value.length === 0)
179
+ throw new Error(`Invalid persisted ${field}`);
180
+ return value;
181
+ }
182
+ function optionalString(value) {
183
+ return typeof value === 'string' && value.length > 0 ? value : undefined;
184
+ }
185
+ function requiredNonNegativeInteger(value, field) {
186
+ const result = Number(value);
187
+ if (!Number.isSafeInteger(result) || result < 0)
188
+ throw new Error(`Invalid persisted ${field}`);
189
+ return result;
190
+ }
191
+ function requiredPositiveInteger(value, field) {
192
+ const result = requiredNonNegativeInteger(value, field);
193
+ if (result === 0)
194
+ throw new Error(`Invalid persisted ${field}`);
195
+ return result;
196
+ }
@@ -38,6 +38,7 @@ export interface LeaseWorkInput {
38
38
  projectRoot: string;
39
39
  owner: string;
40
40
  kinds?: WorkKind[];
41
+ workItemIds?: string[];
41
42
  limit: number;
42
43
  leaseMs: number;
43
44
  now?: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devflow-tools/database",
3
- "version": "0.17.0",
3
+ "version": "0.17.2",
4
4
  "description": "DevFlow SQLite database package",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",