dsh-vscode-mode 0.1.17 → 0.1.19
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/lib/client.js +359 -17
- package/lib/client.js.map +1 -1
- package/lib/index.js +82 -23
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/client/addToConversation.ts +211 -0
- package/src/client/index.ts +16 -2
- package/src/client/styles/editor.css +6 -0
- package/src/client/ui/EditorView.ts +168 -16
- package/src/rpc.ts +63 -18
- package/src/shared/rpc.ts +19 -1
- package/src/store.ts +6 -2
package/lib/index.js
CHANGED
|
@@ -1243,15 +1243,18 @@ async function appendArchiveEntries(ctx, cwd, entries, session) {
|
|
|
1243
1243
|
console.error("edrv appendArchiveEntries failed", error);
|
|
1244
1244
|
}
|
|
1245
1245
|
}
|
|
1246
|
-
/**
|
|
1247
|
-
|
|
1246
|
+
/**
|
|
1247
|
+
* 归档记录:标记 archived、按批次写入归档、落盘工作区桶。
|
|
1248
|
+
* @param opts.deferSave 为 true 时只写归档、不落盘桶(由批量调用方统一 saveBucket 一次)
|
|
1249
|
+
*/
|
|
1250
|
+
async function archiveRecords(ctx, session, cwd, bucket, recs, reason, opts) {
|
|
1248
1251
|
if (!recs.length) return;
|
|
1249
1252
|
const fresh = recs.filter((r) => !r.archived);
|
|
1250
1253
|
for (const r of recs) r.archived = true;
|
|
1251
1254
|
const entries = [];
|
|
1252
1255
|
for (const list of groupByBatch(recs).values()) entries.push(archiveEntryFor(list, cwd, reason));
|
|
1253
1256
|
await appendArchiveEntries(ctx, cwd, entries, session);
|
|
1254
|
-
if (fresh.length) await saveBucket(ctx, cwd, bucket, session);
|
|
1257
|
+
if (fresh.length && !opts?.deferSave) await saveBucket(ctx, cwd, bucket, session);
|
|
1255
1258
|
}
|
|
1256
1259
|
//#endregion
|
|
1257
1260
|
//#region src/registry.ts
|
|
@@ -2437,6 +2440,53 @@ async function requireSession(ctx, sessionId) {
|
|
|
2437
2440
|
cwd
|
|
2438
2441
|
};
|
|
2439
2442
|
}
|
|
2443
|
+
/**
|
|
2444
|
+
* 批量决策核心:一次会话/桶解析 + 逐项处理 + 统一落盘(accept/reject 单条与 decideBatch 共用)。
|
|
2445
|
+
* rejected 项先做回滚,失败记入该项 error 且不改决策;本批次新增"已解决"记录一次性归档,
|
|
2446
|
+
* 有任何成功项则整桶只写盘一次,避免逐条读写整个 sidecar。
|
|
2447
|
+
* @author ddj 2026年08月25号
|
|
2448
|
+
* @param items 决策项(按数组顺序处理,rejected 的先后即回滚顺序)
|
|
2449
|
+
* @returns 逐项结果(ok 项含更新后的记录视图)
|
|
2450
|
+
*/
|
|
2451
|
+
async function applyDecisions(ctx, session, cwd, bucket, items) {
|
|
2452
|
+
const results = [];
|
|
2453
|
+
const resolved = [];
|
|
2454
|
+
let changed = false;
|
|
2455
|
+
for (const item of items) {
|
|
2456
|
+
const record = bucket.get(item.callId);
|
|
2457
|
+
if (!record) {
|
|
2458
|
+
results.push({
|
|
2459
|
+
callId: item.callId,
|
|
2460
|
+
ok: false,
|
|
2461
|
+
error: "记录不存在"
|
|
2462
|
+
});
|
|
2463
|
+
continue;
|
|
2464
|
+
}
|
|
2465
|
+
if (item.decision === "rejected") {
|
|
2466
|
+
const outcome = (item.scope ?? "call") === "hunk" ? await revertHunk(ctx, session, record, item.hunkIndex ?? -1) : await revertCall(ctx, session, record);
|
|
2467
|
+
if (!outcome.ok) {
|
|
2468
|
+
results.push({
|
|
2469
|
+
callId: item.callId,
|
|
2470
|
+
ok: false,
|
|
2471
|
+
error: outcome.error
|
|
2472
|
+
});
|
|
2473
|
+
continue;
|
|
2474
|
+
}
|
|
2475
|
+
}
|
|
2476
|
+
const wasResolved = recordResolved(record);
|
|
2477
|
+
markDecision(record, item.scope ?? "call", item.hunkIndex, item.decision);
|
|
2478
|
+
changed = true;
|
|
2479
|
+
if (!wasResolved && recordResolved(record)) resolved.push(record);
|
|
2480
|
+
results.push({
|
|
2481
|
+
callId: item.callId,
|
|
2482
|
+
ok: true,
|
|
2483
|
+
record: recView(record)
|
|
2484
|
+
});
|
|
2485
|
+
}
|
|
2486
|
+
if (resolved.length) await archiveRecords(ctx, session, cwd, bucket, resolved, items.some((item) => item.decision === "rejected") ? "已处理(回滚)" : "已处理", { deferSave: true });
|
|
2487
|
+
if (changed) await saveBucket(ctx, cwd, bucket, session);
|
|
2488
|
+
return results;
|
|
2489
|
+
}
|
|
2440
2490
|
/** 各方法 handler 表(类型由 shared/rpc 的 RpcHandlerMap 约束)。 */
|
|
2441
2491
|
function buildHandlers(ctx, registry, searcher = newSearcher(ctx)) {
|
|
2442
2492
|
return {
|
|
@@ -2448,7 +2498,7 @@ function buildHandlers(ctx, registry, searcher = newSearcher(ctx)) {
|
|
|
2448
2498
|
};
|
|
2449
2499
|
const bucket = await bucketOf(registry, ctx, sc.cwd);
|
|
2450
2500
|
const want = Array.isArray(args.callIds) ? new Set(args.callIds) : null;
|
|
2451
|
-
if (!want) await autoArchiveStale(ctx, sc.session, sc.cwd, bucket);
|
|
2501
|
+
if (!want && args.skipStale !== true) await autoArchiveStale(ctx, sc.session, sc.cwd, bucket);
|
|
2452
2502
|
const out = [];
|
|
2453
2503
|
for (const rec of bucket.values()) {
|
|
2454
2504
|
if (!want && rec.archived) continue;
|
|
@@ -2468,17 +2518,19 @@ function buildHandlers(ctx, registry, searcher = newSearcher(ctx)) {
|
|
|
2468
2518
|
error: sc.err
|
|
2469
2519
|
};
|
|
2470
2520
|
const bucket = await bucketOf(registry, ctx, sc.cwd);
|
|
2471
|
-
const
|
|
2472
|
-
|
|
2521
|
+
const item = (await applyDecisions(ctx, sc.session, sc.cwd, bucket, [{
|
|
2522
|
+
callId: args.callId,
|
|
2523
|
+
scope: args.scope,
|
|
2524
|
+
hunkIndex: args.hunkIndex,
|
|
2525
|
+
decision: "accepted"
|
|
2526
|
+
}]))[0];
|
|
2527
|
+
if (!item?.ok) return {
|
|
2473
2528
|
ok: false,
|
|
2474
|
-
error: "
|
|
2529
|
+
error: item?.error ?? "操作失败"
|
|
2475
2530
|
};
|
|
2476
|
-
markDecision(record, args.scope ?? "call", args.hunkIndex, "accepted");
|
|
2477
|
-
if (recordResolved(record)) await archiveRecords(ctx, sc.session, sc.cwd, bucket, [record], "已处理");
|
|
2478
|
-
else await saveBucket(ctx, sc.cwd, bucket, sc.session);
|
|
2479
2531
|
return {
|
|
2480
2532
|
ok: true,
|
|
2481
|
-
record:
|
|
2533
|
+
record: item.record
|
|
2482
2534
|
};
|
|
2483
2535
|
},
|
|
2484
2536
|
"edrv.reject": async (args) => {
|
|
@@ -2488,24 +2540,31 @@ function buildHandlers(ctx, registry, searcher = newSearcher(ctx)) {
|
|
|
2488
2540
|
error: sc.err
|
|
2489
2541
|
};
|
|
2490
2542
|
const bucket = await bucketOf(registry, ctx, sc.cwd);
|
|
2491
|
-
const
|
|
2492
|
-
|
|
2543
|
+
const item = (await applyDecisions(ctx, sc.session, sc.cwd, bucket, [{
|
|
2544
|
+
callId: args.callId,
|
|
2545
|
+
scope: args.scope,
|
|
2546
|
+
hunkIndex: args.hunkIndex,
|
|
2547
|
+
decision: "rejected"
|
|
2548
|
+
}]))[0];
|
|
2549
|
+
if (!item?.ok) return {
|
|
2493
2550
|
ok: false,
|
|
2494
|
-
error: "
|
|
2551
|
+
error: item?.error ?? "操作失败"
|
|
2552
|
+
};
|
|
2553
|
+
return {
|
|
2554
|
+
ok: true,
|
|
2555
|
+
record: item.record
|
|
2495
2556
|
};
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2557
|
+
},
|
|
2558
|
+
"edrv.decideBatch": async (args) => {
|
|
2559
|
+
const sc = await requireSession(ctx, args.sessionId);
|
|
2560
|
+
if ("err" in sc) return {
|
|
2499
2561
|
ok: false,
|
|
2500
|
-
error:
|
|
2562
|
+
error: sc.err
|
|
2501
2563
|
};
|
|
2502
|
-
|
|
2503
|
-
record.at = (/* @__PURE__ */ new Date()).toISOString();
|
|
2504
|
-
if (recordResolved(record)) await archiveRecords(ctx, sc.session, sc.cwd, bucket, [record], "已处理(回滚)");
|
|
2505
|
-
else await saveBucket(ctx, sc.cwd, bucket, sc.session);
|
|
2564
|
+
const bucket = await bucketOf(registry, ctx, sc.cwd);
|
|
2506
2565
|
return {
|
|
2507
2566
|
ok: true,
|
|
2508
|
-
|
|
2567
|
+
results: await applyDecisions(ctx, sc.session, sc.cwd, bucket, Array.isArray(args.items) ? args.items : [])
|
|
2509
2568
|
};
|
|
2510
2569
|
},
|
|
2511
2570
|
"edrv.read": async (args) => {
|