@dzhechkov/harness-core 0.3.140 → 0.3.141
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/.dz-manifest.json +45 -17
- package/dist/agentdb-index.d.ts +36 -0
- package/dist/agentdb-index.d.ts.map +1 -1
- package/dist/agentdb-index.js +146 -2
- package/dist/agentdb-index.js.map +1 -1
- package/dist/backlog.d.ts +310 -0
- package/dist/backlog.d.ts.map +1 -0
- package/dist/backlog.js +755 -0
- package/dist/backlog.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/vector-tier.d.ts +9 -0
- package/dist/vector-tier.d.ts.map +1 -1
- package/dist/vector-tier.js +38 -6
- package/dist/vector-tier.js.map +1 -1
- package/package.json +5 -5
- package/sbom.json +86 -16
- package/src/agentdb-index.ts +145 -2
- package/src/backlog.ts +978 -0
- package/src/index.ts +6 -1
- package/src/vector-tier.ts +47 -4
package/sbom.json
CHANGED
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
"hashes": [
|
|
96
96
|
{
|
|
97
97
|
"alg": "SHA-256",
|
|
98
|
-
"content": "
|
|
98
|
+
"content": "894c24f39960080ec16a422915bd51b83b8143dd1eee656aa7df94f06014aedb"
|
|
99
99
|
}
|
|
100
100
|
]
|
|
101
101
|
},
|
|
@@ -105,7 +105,7 @@
|
|
|
105
105
|
"hashes": [
|
|
106
106
|
{
|
|
107
107
|
"alg": "SHA-256",
|
|
108
|
-
"content": "
|
|
108
|
+
"content": "da6079c043c3dc3c25b33fd435da0fdef122143ee3c8a3c46e51bd51e6252883"
|
|
109
109
|
}
|
|
110
110
|
]
|
|
111
111
|
},
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
"hashes": [
|
|
116
116
|
{
|
|
117
117
|
"alg": "SHA-256",
|
|
118
|
-
"content": "
|
|
118
|
+
"content": "57cd32c3f28ee55c776dc4be7eefd5bc1acc4d3d4d8e96917e633cfc5ea7f9cc"
|
|
119
119
|
}
|
|
120
120
|
]
|
|
121
121
|
},
|
|
@@ -125,7 +125,7 @@
|
|
|
125
125
|
"hashes": [
|
|
126
126
|
{
|
|
127
127
|
"alg": "SHA-256",
|
|
128
|
-
"content": "
|
|
128
|
+
"content": "901f14b27b2fc410a66167f9b63f6263b68b516061e71d3cf3c98b207093cf51"
|
|
129
129
|
}
|
|
130
130
|
]
|
|
131
131
|
},
|
|
@@ -209,6 +209,46 @@
|
|
|
209
209
|
}
|
|
210
210
|
]
|
|
211
211
|
},
|
|
212
|
+
{
|
|
213
|
+
"type": "file",
|
|
214
|
+
"name": "dist/backlog.d.ts",
|
|
215
|
+
"hashes": [
|
|
216
|
+
{
|
|
217
|
+
"alg": "SHA-256",
|
|
218
|
+
"content": "0e6b229ff5dfe8026018173f8bbc13398fe2a88411d9cedc0c4c679d6a1c2fc8"
|
|
219
|
+
}
|
|
220
|
+
]
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
"type": "file",
|
|
224
|
+
"name": "dist/backlog.d.ts.map",
|
|
225
|
+
"hashes": [
|
|
226
|
+
{
|
|
227
|
+
"alg": "SHA-256",
|
|
228
|
+
"content": "99520bcd3dc3045df2e678a2be16f925b7f0f858f88ca4cc60526290c8e7c1aa"
|
|
229
|
+
}
|
|
230
|
+
]
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
"type": "file",
|
|
234
|
+
"name": "dist/backlog.js",
|
|
235
|
+
"hashes": [
|
|
236
|
+
{
|
|
237
|
+
"alg": "SHA-256",
|
|
238
|
+
"content": "f6c541c38343a7d7ac6e07e5bca60bb0910d83d1fe3c22089b2dae9ba41eadc9"
|
|
239
|
+
}
|
|
240
|
+
]
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
"type": "file",
|
|
244
|
+
"name": "dist/backlog.js.map",
|
|
245
|
+
"hashes": [
|
|
246
|
+
{
|
|
247
|
+
"alg": "SHA-256",
|
|
248
|
+
"content": "d211992f2a33bd28a164b19f3e2a9da798ccf679c29e92748742de14d8f009ff"
|
|
249
|
+
}
|
|
250
|
+
]
|
|
251
|
+
},
|
|
212
252
|
{
|
|
213
253
|
"type": "file",
|
|
214
254
|
"name": "dist/benchmark.d.ts",
|
|
@@ -1055,7 +1095,7 @@
|
|
|
1055
1095
|
"hashes": [
|
|
1056
1096
|
{
|
|
1057
1097
|
"alg": "SHA-256",
|
|
1058
|
-
"content": "
|
|
1098
|
+
"content": "13e762f63d29519f51214c202498f25171781daaaa5e872bf93504590da14102"
|
|
1059
1099
|
}
|
|
1060
1100
|
]
|
|
1061
1101
|
},
|
|
@@ -1065,7 +1105,7 @@
|
|
|
1065
1105
|
"hashes": [
|
|
1066
1106
|
{
|
|
1067
1107
|
"alg": "SHA-256",
|
|
1068
|
-
"content": "
|
|
1108
|
+
"content": "7145736e767324ee5cc10ad8ffe0b58bc80bd8c186e91fd4693c9bfb350ae4a0"
|
|
1069
1109
|
}
|
|
1070
1110
|
]
|
|
1071
1111
|
},
|
|
@@ -1075,7 +1115,7 @@
|
|
|
1075
1115
|
"hashes": [
|
|
1076
1116
|
{
|
|
1077
1117
|
"alg": "SHA-256",
|
|
1078
|
-
"content": "
|
|
1118
|
+
"content": "875624dd956dd81671adc24d896798b5b162f7a1af468a58944e29f0f6ad8347"
|
|
1079
1119
|
}
|
|
1080
1120
|
]
|
|
1081
1121
|
},
|
|
@@ -1085,7 +1125,7 @@
|
|
|
1085
1125
|
"hashes": [
|
|
1086
1126
|
{
|
|
1087
1127
|
"alg": "SHA-256",
|
|
1088
|
-
"content": "
|
|
1128
|
+
"content": "5a8b40115c9b4d9dd815a4b15d61d4fc5da502a1b8a71104743c3ed9e204ce2c"
|
|
1089
1129
|
}
|
|
1090
1130
|
]
|
|
1091
1131
|
},
|
|
@@ -2455,7 +2495,7 @@
|
|
|
2455
2495
|
"hashes": [
|
|
2456
2496
|
{
|
|
2457
2497
|
"alg": "SHA-256",
|
|
2458
|
-
"content": "
|
|
2498
|
+
"content": "77d99aef6714a8fbc0246be15425f96c4d9da95c9545de551ee069fc89eb4de2"
|
|
2459
2499
|
}
|
|
2460
2500
|
]
|
|
2461
2501
|
},
|
|
@@ -2465,7 +2505,7 @@
|
|
|
2465
2505
|
"hashes": [
|
|
2466
2506
|
{
|
|
2467
2507
|
"alg": "SHA-256",
|
|
2468
|
-
"content": "
|
|
2508
|
+
"content": "d34550cb15c7b10f2fd7a8009e4517d4e466a4d54e8e81d00ca34dc32a742e7b"
|
|
2469
2509
|
}
|
|
2470
2510
|
]
|
|
2471
2511
|
},
|
|
@@ -2475,7 +2515,7 @@
|
|
|
2475
2515
|
"hashes": [
|
|
2476
2516
|
{
|
|
2477
2517
|
"alg": "SHA-256",
|
|
2478
|
-
"content": "
|
|
2518
|
+
"content": "e45ce822673cb271d8e264f471d7ef6644ed5f689cedaf6e58d1aab3f2ebad6c"
|
|
2479
2519
|
}
|
|
2480
2520
|
]
|
|
2481
2521
|
},
|
|
@@ -2485,7 +2525,7 @@
|
|
|
2485
2525
|
"hashes": [
|
|
2486
2526
|
{
|
|
2487
2527
|
"alg": "SHA-256",
|
|
2488
|
-
"content": "
|
|
2528
|
+
"content": "716f08b502d77bb2be012982c09902207e75c083706a9fa7816b1306d1c0f03b"
|
|
2489
2529
|
}
|
|
2490
2530
|
]
|
|
2491
2531
|
},
|
|
@@ -2535,7 +2575,7 @@
|
|
|
2535
2575
|
"hashes": [
|
|
2536
2576
|
{
|
|
2537
2577
|
"alg": "SHA-256",
|
|
2538
|
-
"content": "
|
|
2578
|
+
"content": "c1bcc12b49b2181ad41b2bdb9b8869f95c5c34222038bbb1cd34b7c5e997a4f3"
|
|
2539
2579
|
}
|
|
2540
2580
|
]
|
|
2541
2581
|
},
|
|
@@ -2555,7 +2595,7 @@
|
|
|
2555
2595
|
"hashes": [
|
|
2556
2596
|
{
|
|
2557
2597
|
"alg": "SHA-256",
|
|
2558
|
-
"content": "
|
|
2598
|
+
"content": "c4585a8bd01f0aaf1c8a0719f4b1a18464ab0a20b305d0c69b07ab21a5e2673c"
|
|
2559
2599
|
}
|
|
2560
2600
|
]
|
|
2561
2601
|
},
|
|
@@ -2579,6 +2619,16 @@
|
|
|
2579
2619
|
}
|
|
2580
2620
|
]
|
|
2581
2621
|
},
|
|
2622
|
+
{
|
|
2623
|
+
"type": "file",
|
|
2624
|
+
"name": "src/backlog.ts",
|
|
2625
|
+
"hashes": [
|
|
2626
|
+
{
|
|
2627
|
+
"alg": "SHA-256",
|
|
2628
|
+
"content": "e5173f2eafa803a5aaf0be03e238b5bc567f876fcb3caed4bae2148173baa998"
|
|
2629
|
+
}
|
|
2630
|
+
]
|
|
2631
|
+
},
|
|
2582
2632
|
{
|
|
2583
2633
|
"type": "file",
|
|
2584
2634
|
"name": "src/benchmark.ts",
|
|
@@ -2795,7 +2845,7 @@
|
|
|
2795
2845
|
"hashes": [
|
|
2796
2846
|
{
|
|
2797
2847
|
"alg": "SHA-256",
|
|
2798
|
-
"content": "
|
|
2848
|
+
"content": "bf307ef27bca0ac2ad6dbb6e8c7301507b042469cacee3a9a183ef1be3e69df7"
|
|
2799
2849
|
}
|
|
2800
2850
|
]
|
|
2801
2851
|
},
|
|
@@ -3135,7 +3185,7 @@
|
|
|
3135
3185
|
"hashes": [
|
|
3136
3186
|
{
|
|
3137
3187
|
"alg": "SHA-256",
|
|
3138
|
-
"content": "
|
|
3188
|
+
"content": "db2d2510d5a9297ed212f117307ad15d0900005797d1ad81aee2b3802114b473"
|
|
3139
3189
|
}
|
|
3140
3190
|
]
|
|
3141
3191
|
},
|
|
@@ -3199,6 +3249,26 @@
|
|
|
3199
3249
|
}
|
|
3200
3250
|
]
|
|
3201
3251
|
},
|
|
3252
|
+
{
|
|
3253
|
+
"type": "file",
|
|
3254
|
+
"name": "test/backlog-live.test.ts",
|
|
3255
|
+
"hashes": [
|
|
3256
|
+
{
|
|
3257
|
+
"alg": "SHA-256",
|
|
3258
|
+
"content": "a10cb51a8e58564c31a8bbe828e4426b388e014b074a9b419c2cbfc1ef08987d"
|
|
3259
|
+
}
|
|
3260
|
+
]
|
|
3261
|
+
},
|
|
3262
|
+
{
|
|
3263
|
+
"type": "file",
|
|
3264
|
+
"name": "test/backlog.test.ts",
|
|
3265
|
+
"hashes": [
|
|
3266
|
+
{
|
|
3267
|
+
"alg": "SHA-256",
|
|
3268
|
+
"content": "551e107380c9be270770266ebb258495825d942150c12c305345970de7f666b5"
|
|
3269
|
+
}
|
|
3270
|
+
]
|
|
3271
|
+
},
|
|
3202
3272
|
{
|
|
3203
3273
|
"type": "file",
|
|
3204
3274
|
"name": "test/benchmark-s15.test.ts",
|
package/src/agentdb-index.ts
CHANGED
|
@@ -160,9 +160,21 @@ export async function indexPatternsToAgentdb(
|
|
|
160
160
|
/* READ half (dz-rvf-vector-bridge FR-3): semantic search + id scan */
|
|
161
161
|
/* ------------------------------------------------------------------ */
|
|
162
162
|
|
|
163
|
-
/**
|
|
163
|
+
/**
|
|
164
|
+
* The RECALL/search default task_types. Deliberately EXCLUDES `dz-backlog`: `dz recall` (and
|
|
165
|
+
* feature-adr Step-0) must never surface raw backlog ideas as if they were earned lessons (ADR-005).
|
|
166
|
+
*/
|
|
164
167
|
const DZ_TASK_TYPES = ['dz-teach', 'dz-learning'] as const;
|
|
165
168
|
|
|
169
|
+
/**
|
|
170
|
+
* The dz-owned task_types for LIFECYCLE scans (id enumeration + reindex ownership) — a SUPERSET of
|
|
171
|
+
* the recall default that ALSO owns `dz-backlog` (smart-backlog, ADR-001/005). Reindex must re-embed
|
|
172
|
+
* these on a model bump (else backlog rows rot in a stale embedding space), and id-scans must see them
|
|
173
|
+
* (mirror idempotency). Kept SEPARATE from {@link DZ_TASK_TYPES} so ownership never leaks ideas into
|
|
174
|
+
* lesson recall: search defaults to DZ_TASK_TYPES, lifecycle to DZ_OWNED_TASK_TYPES.
|
|
175
|
+
*/
|
|
176
|
+
export const DZ_OWNED_TASK_TYPES = ['dz-teach', 'dz-learning', 'dz-backlog'] as const;
|
|
177
|
+
|
|
166
178
|
/** Minimal READONLY better-sqlite3 surface used by the read half. */
|
|
167
179
|
interface ReadonlyDb {
|
|
168
180
|
pragma: (s: string) => void;
|
|
@@ -362,7 +374,9 @@ export async function listAgentdbDzIds(
|
|
|
362
374
|
const { db } = opened;
|
|
363
375
|
try {
|
|
364
376
|
if (!hasDzTables(db)) return { ids: [] };
|
|
365
|
-
|
|
377
|
+
// LIFECYCLE scan ⇒ the OWNED superset (incl. dz-backlog) so idea ids are visible for mirror
|
|
378
|
+
// idempotency + `dz vector status`. Recall/search still defaults to the narrower DZ_TASK_TYPES.
|
|
379
|
+
const taskTypes = opts.taskTypes ?? DZ_OWNED_TASK_TYPES;
|
|
366
380
|
const placeholders = taskTypes.map(() => '?').join(', ');
|
|
367
381
|
const rows = db
|
|
368
382
|
.prepare(`SELECT metadata FROM reasoning_patterns WHERE task_type IN (${placeholders})`)
|
|
@@ -380,6 +394,65 @@ export async function listAgentdbDzIds(
|
|
|
380
394
|
}
|
|
381
395
|
}
|
|
382
396
|
|
|
397
|
+
/**
|
|
398
|
+
* Read the rows that ACTUALLY EXIST IN THE STORE for a task_type, as re-indexable {@link AgentdbRow}s
|
|
399
|
+
* (their stored `approach` text + score/uses/reward/tags/metadata, dzId preserved). This is the correct
|
|
400
|
+
* source for a REINDEX: a reindex re-embeds what is physically in the store to the new model — reading it
|
|
401
|
+
* back from the store (not reconstructing from a sidecar file like ideas.jsonl) means an empty/unreadable
|
|
402
|
+
* sidecar can never leave real store rows un-re-embedded and stale under an advanced manifest (HIGH-G).
|
|
403
|
+
* Readonly, best-effort ({rows:[]} on absent/unavailable), never throws.
|
|
404
|
+
*/
|
|
405
|
+
export function readAgentdbRowsByTaskType(
|
|
406
|
+
projectRoot: string,
|
|
407
|
+
taskType: string,
|
|
408
|
+
opts: { dbPath?: string } = {},
|
|
409
|
+
): { rows: AgentdbRow[]; error?: string } {
|
|
410
|
+
const opened = openReadonly(projectRoot, opts.dbPath);
|
|
411
|
+
if ('absent' in opened) return { rows: [] };
|
|
412
|
+
if ('error' in opened) return { rows: [], error: opened.error };
|
|
413
|
+
const { db } = opened;
|
|
414
|
+
try {
|
|
415
|
+
if (!hasDzTables(db)) return { rows: [] };
|
|
416
|
+
const raw = db
|
|
417
|
+
.prepare('SELECT approach, success_rate, uses, avg_reward, tags, metadata FROM reasoning_patterns WHERE task_type = ?')
|
|
418
|
+
.all(taskType) as Array<{ approach: string; success_rate: number; uses: number; avg_reward: number; tags: string | null; metadata: string | null }>;
|
|
419
|
+
const rows: AgentdbRow[] = raw.map((r) => {
|
|
420
|
+
let metadata: Record<string, unknown> | undefined;
|
|
421
|
+
if (typeof r.metadata === 'string' && r.metadata !== '') {
|
|
422
|
+
try {
|
|
423
|
+
const m = JSON.parse(r.metadata) as unknown;
|
|
424
|
+
if (m !== null && typeof m === 'object') metadata = m as Record<string, unknown>;
|
|
425
|
+
} catch {
|
|
426
|
+
/* drop unparseable metadata */
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
let tags: string[] | undefined;
|
|
430
|
+
if (typeof r.tags === 'string' && r.tags !== '') {
|
|
431
|
+
try {
|
|
432
|
+
const t = JSON.parse(r.tags) as unknown;
|
|
433
|
+
if (Array.isArray(t)) tags = t.filter((x): x is string => typeof x === 'string');
|
|
434
|
+
} catch {
|
|
435
|
+
/* drop unparseable tags */
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
return {
|
|
439
|
+
taskType,
|
|
440
|
+
text: r.approach,
|
|
441
|
+
score: r.success_rate,
|
|
442
|
+
uses: r.uses,
|
|
443
|
+
avgReward: r.avg_reward,
|
|
444
|
+
...(tags !== undefined ? { tags } : {}),
|
|
445
|
+
...(metadata !== undefined ? { metadata } : {}),
|
|
446
|
+
};
|
|
447
|
+
});
|
|
448
|
+
return { rows };
|
|
449
|
+
} catch (err) {
|
|
450
|
+
return { rows: [], error: `row scan failed: ${err instanceof Error ? err.message : String(err)}` };
|
|
451
|
+
} finally {
|
|
452
|
+
db.close();
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
383
456
|
/* ------------------------------------------------------------------ */
|
|
384
457
|
/* IMPORT half (dz-vector-harmonize-import M0.4): upsert-by-dzId */
|
|
385
458
|
/* ------------------------------------------------------------------ */
|
|
@@ -437,6 +510,20 @@ export async function importVectorsToAgentdb(
|
|
|
437
510
|
const { default: Database } = (await import(sqliteUrl)) as { default: new (p: string) => UpsertDb };
|
|
438
511
|
const model = resolveEmbedModel(projectRoot);
|
|
439
512
|
if ('error' in model) return { imported: 0, error: model.error };
|
|
513
|
+
// MED-C: the store manifest guards the MODEL, but a per-vector guard was missing — a malformed or
|
|
514
|
+
// TOCTOU vector (wrong length / NaN / ±Infinity) would be stamped compatible. Fail CLOSED and LOUD:
|
|
515
|
+
// reject the whole batch if any vector's dimensionality ≠ the store dim or any component is non-finite,
|
|
516
|
+
// so a vector can only enter the store bound to the model+dim the manifest names.
|
|
517
|
+
for (const row of rows) {
|
|
518
|
+
if (!(row.vector instanceof Float32Array) || row.vector.length !== model.dim) {
|
|
519
|
+
return { imported: 0, error: `vector validation failed for ${row.dzId}: length ${row.vector?.length} != store dim ${model.dim}` };
|
|
520
|
+
}
|
|
521
|
+
for (let i = 0; i < row.vector.length; i += 1) {
|
|
522
|
+
if (!Number.isFinite(row.vector[i])) {
|
|
523
|
+
return { imported: 0, error: `vector validation failed for ${row.dzId}: non-finite component at index ${i}` };
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
440
527
|
const dbFile = resolveAgentdbPath(projectRoot, opts.dbPath);
|
|
441
528
|
mkdirSync(dirname(dbFile), { recursive: true }); // better-sqlite3 won't create the parent dir
|
|
442
529
|
const db = new Database(dbFile);
|
|
@@ -530,6 +617,62 @@ export function clearAgentdbQuarantine(
|
|
|
530
617
|
}
|
|
531
618
|
}
|
|
532
619
|
|
|
620
|
+
/**
|
|
621
|
+
* DELETE mirrored rows by `metadata.dzId` (pattern + its embedding), optionally scoped to a task_type
|
|
622
|
+
* set. The write-half of a structured-store removal: when `harmonize --apply` drops ideas from
|
|
623
|
+
* `ideas.jsonl`, their `dz-backlog` vectors must be pruned too, or a later semantic search matches an
|
|
624
|
+
* ORPHAN dzId that no longer has a structured record (smart-backlog HIGH-A). Best-effort, same custody
|
|
625
|
+
* model as {@link clearAgentdbQuarantine} (missing db/deps ⇒ no-op). Never throws.
|
|
626
|
+
*/
|
|
627
|
+
export function deleteAgentdbByDzIds(
|
|
628
|
+
projectRoot: string,
|
|
629
|
+
dzIds: readonly string[],
|
|
630
|
+
opts: { dbPath?: string; taskTypes?: readonly string[] } = {},
|
|
631
|
+
): { deleted: number; error?: string } {
|
|
632
|
+
if (dzIds.length === 0) return { deleted: 0 };
|
|
633
|
+
const dbFile = resolveAgentdbPath(projectRoot, opts.dbPath);
|
|
634
|
+
if (!existsSync(dbFile)) return { deleted: 0 };
|
|
635
|
+
let Database: new (p: string) => UpsertDb;
|
|
636
|
+
try {
|
|
637
|
+
const req = createRequire(join(projectRoot, 'package.json'));
|
|
638
|
+
Database = req('better-sqlite3') as new (p: string) => UpsertDb;
|
|
639
|
+
} catch {
|
|
640
|
+
return { deleted: 0, error: DEPS_MISSING };
|
|
641
|
+
}
|
|
642
|
+
try {
|
|
643
|
+
const db = new Database(dbFile);
|
|
644
|
+
try {
|
|
645
|
+
db.pragma('journal_mode = WAL');
|
|
646
|
+
db.pragma('busy_timeout = 5000');
|
|
647
|
+
db.exec(REASONING_BANK_SCHEMA);
|
|
648
|
+
const scope = opts.taskTypes !== undefined && opts.taskTypes.length > 0;
|
|
649
|
+
const scopeSql = scope ? ` AND task_type IN (${opts.taskTypes!.map(() => '?').join(', ')})` : '';
|
|
650
|
+
const findIds = db.prepare(`SELECT id FROM reasoning_patterns WHERE json_extract(metadata, '$.dzId') = ?${scopeSql}`) as unknown as {
|
|
651
|
+
all: (...a: unknown[]) => { id: number }[];
|
|
652
|
+
};
|
|
653
|
+
const delEmb = db.prepare('DELETE FROM pattern_embeddings WHERE pattern_id = ?');
|
|
654
|
+
const delPat = db.prepare('DELETE FROM reasoning_patterns WHERE id = ?');
|
|
655
|
+
const tx = db.transaction(() => {
|
|
656
|
+
let deleted = 0;
|
|
657
|
+
for (const dzId of dzIds) {
|
|
658
|
+
const rows = scope ? findIds.all(dzId, ...opts.taskTypes!) : findIds.all(dzId);
|
|
659
|
+
for (const { id } of rows) {
|
|
660
|
+
delEmb.run(id);
|
|
661
|
+
delPat.run(id);
|
|
662
|
+
deleted += 1;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
return deleted;
|
|
666
|
+
});
|
|
667
|
+
return { deleted: tx() };
|
|
668
|
+
} finally {
|
|
669
|
+
db.close();
|
|
670
|
+
}
|
|
671
|
+
} catch (err) {
|
|
672
|
+
return { deleted: 0, error: `delete by dzId failed: ${err instanceof Error ? err.message : String(err)}` };
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
|
|
533
676
|
export function bumpAgentdbUses(
|
|
534
677
|
projectRoot: string,
|
|
535
678
|
dzIds: readonly string[],
|