@norman-else/dsh-claude 0.1.19 → 0.1.21
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/README.md +38 -147
- package/lib/bin.mjs +1 -1
- package/lib/client.d.ts +232 -188
- package/lib/client.js +3060 -442
- package/lib/client.js.map +1 -1
- package/lib/command-bridge-C10-lz6A.mjs +71 -0
- package/lib/command-bridge-C10-lz6A.mjs.map +1 -0
- package/lib/{events-DPJaBReT.mjs → events-BdDs9ebF.mjs} +6 -2
- package/lib/events-BdDs9ebF.mjs.map +1 -0
- package/lib/index.d.mts +36 -1
- package/lib/index.mjs +1221 -262
- package/lib/index.mjs.map +1 -1
- package/lib/{preset-installer-DnoSEKGm.mjs → preset-installer-DMANIjwu.mjs} +2 -2
- package/lib/{preset-installer-DnoSEKGm.mjs.map → preset-installer-DMANIjwu.mjs.map} +1 -1
- package/lib/preset-route.mjs +172 -2
- package/lib/preset-route.mjs.map +1 -1
- package/package.json +1 -1
- package/lib/events-DPJaBReT.mjs.map +0 -1
- package/lib/presenters-DBRIOgJs.mjs +0 -257
- package/lib/presenters-DBRIOgJs.mjs.map +0 -1
package/lib/client.js
CHANGED
|
@@ -3,9 +3,9 @@ window.__ModuleLoader__.load({
|
|
|
3
3
|
factory: (require) => {
|
|
4
4
|
var module = { exports: {} };
|
|
5
5
|
module.exports;
|
|
6
|
-
var { useCallback, useEffect, useId, useMemo, useRef, useState } = require("react");
|
|
7
|
-
var {
|
|
8
|
-
var {
|
|
6
|
+
var { Fragment, useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } = require("react");
|
|
7
|
+
var { DiffBlock, DisclosureRow, HoverCard, IconApiOutline14, IconBranchOutline16, IconCheckOutline14, IconChevronDownOutline14, IconCloseOutline16, IconFullscreenOutline16, IconSearchOutline16, IconThinkOutline14, MarkdownText, Menu, Modal, StateDot } = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
8
|
+
var { Fragment: Fragment$1, jsx, jsxs } = require("react/jsx-runtime");
|
|
9
9
|
var { createPortal } = require("react-dom");
|
|
10
10
|
/** Claude's subagent dispatch tools; rendered as plugin-owned group cards
|
|
11
11
|
* gathering subagent activity instead of native tool cards. */
|
|
@@ -16,6 +16,21 @@ window.__ModuleLoader__.load({
|
|
|
16
16
|
const CLAUDE_PROJECTION_PATH = "/plugins/dsh-claude/projection";
|
|
17
17
|
const CLAUDE_GLOBAL_SETTINGS_PATH = "/plugins/dsh-claude/settings/global";
|
|
18
18
|
const CLAUDE_REPOSITORY_SETUP_PATH = "/plugins/dsh-claude/repository/setup";
|
|
19
|
+
const CLAUDE_REPOSITORY_ACTION_PATH = "/plugins/dsh-claude/repository/action";
|
|
20
|
+
const CLAUDE_REVIEW_COMMENT_PATH = "/plugins/dsh-claude/review-comments";
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/client/task-projection.ts
|
|
23
|
+
/** Tasks UI is reserved for detached work and genuine Claude subagents. */
|
|
24
|
+
function isProjectedTask(task) {
|
|
25
|
+
if (task.backgrounded === true) return true;
|
|
26
|
+
return task.subagentType !== void 0 && task.subagentType.trim().length > 0;
|
|
27
|
+
}
|
|
28
|
+
function isProjectedTaskActivity(activity, tasks) {
|
|
29
|
+
if (activity.kind !== "subagent" || activity.parentToolUseId !== void 0) return true;
|
|
30
|
+
if (activity.taskId === void 0) return false;
|
|
31
|
+
const task = tasks.find((candidate) => candidate.taskId === activity.taskId);
|
|
32
|
+
return task !== void 0 && isProjectedTask(task);
|
|
33
|
+
}
|
|
19
34
|
//#endregion
|
|
20
35
|
//#region src/client/conversation-sidecar.ts
|
|
21
36
|
function isTaskActivity(value) {
|
|
@@ -53,7 +68,7 @@ window.__ModuleLoader__.load({
|
|
|
53
68
|
const rows = [];
|
|
54
69
|
const byId = /* @__PURE__ */ new Map();
|
|
55
70
|
for (const value of activities) {
|
|
56
|
-
if (!accepts(value)) continue;
|
|
71
|
+
if (!accepts(value) || !isProjectedTaskActivity(value, tasks)) continue;
|
|
57
72
|
const existingTaskId = value.toolUseId === void 0 ? void 0 : `task-${value.toolUseId}`;
|
|
58
73
|
const updatesExistingTask = value.kind === "tool-result" && existingTaskId !== void 0 && byId.has(existingTaskId);
|
|
59
74
|
if (!presentable(value) && !updatesExistingTask) continue;
|
|
@@ -117,10 +132,232 @@ window.__ModuleLoader__.load({
|
|
|
117
132
|
};
|
|
118
133
|
});
|
|
119
134
|
}
|
|
120
|
-
function
|
|
121
|
-
|
|
135
|
+
function inputRecord(detail) {
|
|
136
|
+
if (detail === void 0) return void 0;
|
|
137
|
+
try {
|
|
138
|
+
const value = JSON.parse(detail);
|
|
139
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
140
|
+
} catch {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function inputString(input, key) {
|
|
145
|
+
const value = input?.[key];
|
|
146
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
147
|
+
}
|
|
148
|
+
function lineCount(text) {
|
|
149
|
+
return text.length === 0 ? 0 : text.split(/\r?\n/u).length;
|
|
150
|
+
}
|
|
151
|
+
function editDiffs(toolName, input) {
|
|
152
|
+
const path = inputString(input, "file_path");
|
|
153
|
+
if (path === void 0) return void 0;
|
|
154
|
+
if (toolName === "MultiEdit" && Array.isArray(input?.edits)) {
|
|
155
|
+
const diffs = input.edits.flatMap((edit) => {
|
|
156
|
+
if (edit === null || typeof edit !== "object" || Array.isArray(edit)) return [];
|
|
157
|
+
const item = edit;
|
|
158
|
+
const newText = inputString(item, "new_string");
|
|
159
|
+
if (newText === void 0) return [];
|
|
160
|
+
return [{
|
|
161
|
+
path,
|
|
162
|
+
oldText: inputString(item, "old_string") ?? null,
|
|
163
|
+
newText
|
|
164
|
+
}];
|
|
165
|
+
});
|
|
166
|
+
return diffs.length === 0 ? void 0 : diffs;
|
|
167
|
+
}
|
|
168
|
+
if (toolName === "Edit") {
|
|
169
|
+
const newText = inputString(input, "new_string");
|
|
170
|
+
return newText === void 0 ? void 0 : [{
|
|
171
|
+
path,
|
|
172
|
+
oldText: inputString(input, "old_string") ?? null,
|
|
173
|
+
newText
|
|
174
|
+
}];
|
|
175
|
+
}
|
|
176
|
+
if (toolName === "Write") {
|
|
177
|
+
const content = inputString(input, "content");
|
|
178
|
+
return content === void 0 ? void 0 : [{
|
|
179
|
+
path,
|
|
180
|
+
oldText: null,
|
|
181
|
+
newText: content
|
|
182
|
+
}];
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function toolDescription(toolName, input, failed = false) {
|
|
186
|
+
const path = inputString(input, "file_path") ?? inputString(input, "path");
|
|
187
|
+
const pattern = inputString(input, "pattern") ?? inputString(input, "query");
|
|
188
|
+
const description = inputString(input, "description");
|
|
189
|
+
const target = path ?? pattern;
|
|
190
|
+
let completed;
|
|
191
|
+
let failedAction;
|
|
192
|
+
switch (toolName) {
|
|
193
|
+
case "Grep":
|
|
194
|
+
completed = path === void 0 ? `Searched for ${pattern ?? "matches"}` : `Searched ${path} for ${pattern ?? "matches"}`;
|
|
195
|
+
failedAction = path === void 0 ? `search for ${pattern ?? "matches"}` : `search ${path} for ${pattern ?? "matches"}`;
|
|
196
|
+
break;
|
|
197
|
+
case "Glob":
|
|
198
|
+
completed = `Searched for ${pattern ?? "files"}`;
|
|
199
|
+
failedAction = `search for ${pattern ?? "files"}`;
|
|
200
|
+
break;
|
|
201
|
+
case "Read":
|
|
202
|
+
completed = `Read ${path ?? "a file"}`;
|
|
203
|
+
failedAction = `read ${path ?? "a file"}`;
|
|
204
|
+
break;
|
|
205
|
+
case "WebFetch": {
|
|
206
|
+
const url = inputString(input, "url") ?? "a web page";
|
|
207
|
+
completed = `Fetched ${url}`;
|
|
208
|
+
failedAction = `fetch ${url}`;
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
case "WebSearch":
|
|
212
|
+
completed = `Searched the web for ${pattern ?? "results"}`;
|
|
213
|
+
failedAction = `search the web for ${pattern ?? "results"}`;
|
|
214
|
+
break;
|
|
215
|
+
case "Edit":
|
|
216
|
+
case "MultiEdit":
|
|
217
|
+
completed = `Edited ${path ?? "a file"}`;
|
|
218
|
+
failedAction = `edit ${path ?? "a file"}`;
|
|
219
|
+
break;
|
|
220
|
+
case "Write":
|
|
221
|
+
completed = `Wrote ${path ?? "a file"}`;
|
|
222
|
+
failedAction = `write ${path ?? "a file"}`;
|
|
223
|
+
break;
|
|
224
|
+
case "Bash": {
|
|
225
|
+
const command = inputString(input, "command") ?? "a command";
|
|
226
|
+
completed = description ?? `Ran ${command}`;
|
|
227
|
+
failedAction = description === void 0 ? `run ${command}` : description;
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
230
|
+
default:
|
|
231
|
+
completed = description ?? `${toolName}${target === void 0 ? "" : ` ${target}`}`;
|
|
232
|
+
failedAction = completed.charAt(0).toLowerCase() + completed.slice(1);
|
|
233
|
+
}
|
|
234
|
+
return failed ? `Failed to ${failedAction}` : completed;
|
|
235
|
+
}
|
|
236
|
+
/** Fold one step's shared ordinal stream into Claude Code-style prose and tool groups. */
|
|
237
|
+
function transcriptItemsForStep(activities, turn, step, tasks = []) {
|
|
238
|
+
const ordered = activities.filter((activity) => activity.turn === turn && activity.step === step).slice().sort((left, right) => left.ordinal - right.ordinal);
|
|
239
|
+
const items = [];
|
|
240
|
+
let group;
|
|
241
|
+
const flushGroup = () => {
|
|
242
|
+
if (group === void 0 || group.tools.length === 0) return;
|
|
243
|
+
const current = group;
|
|
244
|
+
const diffs = current.tools.flatMap((tool) => tool.diffs ?? []);
|
|
245
|
+
const additions = diffs.reduce((total, diff) => total + lineCount(diff.newText), 0);
|
|
246
|
+
const deletions = diffs.reduce((total, diff) => total + (diff.oldText === null ? 0 : lineCount(diff.oldText)), 0);
|
|
247
|
+
const files = new Set(diffs.map((diff) => diff.path)).size;
|
|
248
|
+
items.push({
|
|
249
|
+
kind: "tools",
|
|
250
|
+
ordinal: current.ordinal,
|
|
251
|
+
tools: current.tools,
|
|
252
|
+
...diffs.length === 0 ? {} : {
|
|
253
|
+
additions,
|
|
254
|
+
deletions,
|
|
255
|
+
files
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
group = void 0;
|
|
259
|
+
for (const activity of current.trailingActivities) {
|
|
260
|
+
const row = activityRows([activity], () => true, tasks)[0];
|
|
261
|
+
if (row !== void 0) items.push({
|
|
262
|
+
kind: "activity",
|
|
263
|
+
ordinal: activity.ordinal,
|
|
264
|
+
row
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
for (const activity of ordered) {
|
|
269
|
+
if (!isProjectedTaskActivity(activity, tasks)) continue;
|
|
270
|
+
if (activity.kind === "text") {
|
|
271
|
+
flushGroup();
|
|
272
|
+
if (activity.text !== void 0 && activity.text.length > 0) items.push({
|
|
273
|
+
kind: "text",
|
|
274
|
+
ordinal: activity.ordinal,
|
|
275
|
+
text: activity.text
|
|
276
|
+
});
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
if (activity.kind === "tool-call" && activity.toolUseId !== void 0 && activity.toolName !== void 0) {
|
|
280
|
+
group ??= {
|
|
281
|
+
ordinal: activity.ordinal,
|
|
282
|
+
tools: [],
|
|
283
|
+
byId: /* @__PURE__ */ new Map(),
|
|
284
|
+
trailingActivities: []
|
|
285
|
+
};
|
|
286
|
+
group.byId.set(activity.toolUseId, group.tools.length);
|
|
287
|
+
const input = inputRecord(activity.detail);
|
|
288
|
+
group.tools.push({
|
|
289
|
+
toolUseId: activity.toolUseId,
|
|
290
|
+
toolName: activity.toolName,
|
|
291
|
+
description: toolDescription(activity.toolName, input),
|
|
292
|
+
...activity.summary === void 0 ? {} : { summary: activity.summary },
|
|
293
|
+
...activity.detail === void 0 ? {} : { input: activity.detail },
|
|
294
|
+
...activity.phase === void 0 ? {} : { phase: activity.phase },
|
|
295
|
+
...activity.isError === void 0 ? {} : { isError: activity.isError },
|
|
296
|
+
subcalls: []
|
|
297
|
+
});
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
if ((activity.kind === "tool-result" || activity.kind === "permission") && activity.toolUseId !== void 0 && group !== void 0) {
|
|
301
|
+
const index = group.byId.get(activity.toolUseId);
|
|
302
|
+
const previous = index === void 0 ? void 0 : group.tools[index];
|
|
303
|
+
if (index !== void 0 && previous !== void 0) {
|
|
304
|
+
const failed = activity.isError === true || activity.phase === "failed" || activity.kind === "permission";
|
|
305
|
+
const diffs = failed ? void 0 : editDiffs(previous.toolName, inputRecord(previous.input));
|
|
306
|
+
const additions = diffs?.reduce((total, diff) => total + lineCount(diff.newText), 0);
|
|
307
|
+
const deletions = diffs?.reduce((total, diff) => total + (diff.oldText === null ? 0 : lineCount(diff.oldText)), 0);
|
|
308
|
+
group.tools[index] = {
|
|
309
|
+
...previous,
|
|
310
|
+
description: toolDescription(previous.toolName, inputRecord(previous.input), failed),
|
|
311
|
+
...activity.detail === void 0 ? {} : { output: activity.detail },
|
|
312
|
+
...activity.phase === void 0 ? {} : { phase: activity.phase },
|
|
313
|
+
...activity.isError === void 0 ? {} : { isError: activity.isError },
|
|
314
|
+
...diffs === void 0 ? {} : {
|
|
315
|
+
diffs,
|
|
316
|
+
additions: additions ?? 0,
|
|
317
|
+
deletions: deletions ?? 0
|
|
318
|
+
},
|
|
319
|
+
...activity.kind === "permission" ? {
|
|
320
|
+
output: activity.summary,
|
|
321
|
+
isError: true
|
|
322
|
+
} : {}
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
if (activity.kind === "subagent" && activity.parentToolUseId !== void 0 && group !== void 0) {
|
|
328
|
+
const index = group.byId.get(activity.parentToolUseId);
|
|
329
|
+
const previous = index === void 0 ? void 0 : group.tools[index];
|
|
330
|
+
const nested = subcallOf(activity);
|
|
331
|
+
if (index !== void 0 && previous !== void 0 && nested !== void 0) {
|
|
332
|
+
const nestedIndex = previous.subcalls.findIndex((item) => item.toolUseId === nested.toolUseId);
|
|
333
|
+
const subcalls = nestedIndex === -1 ? [...previous.subcalls, nested] : previous.subcalls.map((item, position) => position === nestedIndex ? {
|
|
334
|
+
...item,
|
|
335
|
+
...nested
|
|
336
|
+
} : item);
|
|
337
|
+
group.tools[index] = {
|
|
338
|
+
...previous,
|
|
339
|
+
subcalls
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
if (!presentable(activity)) continue;
|
|
345
|
+
if (group !== void 0) {
|
|
346
|
+
group.trailingActivities.push(activity);
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
const row = activityRows([activity], () => true, tasks)[0];
|
|
350
|
+
if (row !== void 0) items.push({
|
|
351
|
+
kind: "activity",
|
|
352
|
+
ordinal: activity.ordinal,
|
|
353
|
+
row
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
flushGroup();
|
|
357
|
+
return items;
|
|
122
358
|
}
|
|
123
|
-
/**
|
|
359
|
+
/** Keep one sidecar-backed activity group at the live chat tail, then anchor it
|
|
360
|
+
* before the native assistant message or at step settlement when none appears. */
|
|
124
361
|
const claudeActivityStepDefinition = {
|
|
125
362
|
kind: "claude-activity-step",
|
|
126
363
|
target: "chat",
|
|
@@ -129,6 +366,10 @@ window.__ModuleLoader__.load({
|
|
|
129
366
|
id: `${event.data.turn}:${event.data.step}`,
|
|
130
367
|
role: "start"
|
|
131
368
|
};
|
|
369
|
+
if (event.type === "step/end") return {
|
|
370
|
+
id: `${event.data.turn}:${event.data.step}`,
|
|
371
|
+
role: "update"
|
|
372
|
+
};
|
|
132
373
|
if (event.type !== "assistant/message" || event.data.message.source.provider !== "claude") return null;
|
|
133
374
|
return {
|
|
134
375
|
id: `${event.data.turn}:${event.data.step}`,
|
|
@@ -139,25 +380,31 @@ window.__ModuleLoader__.load({
|
|
|
139
380
|
if (match.event.type !== "step/start") throw new Error("Claude activity step requires step/start");
|
|
140
381
|
return {
|
|
141
382
|
turn: match.event.data.turn,
|
|
142
|
-
step: match.event.data.step
|
|
383
|
+
step: match.event.data.step,
|
|
384
|
+
anchorSeq: Number.MAX_SAFE_INTEGER - 1
|
|
143
385
|
};
|
|
144
386
|
},
|
|
145
387
|
update(context, match) {
|
|
146
|
-
if (match.event.type
|
|
147
|
-
return {
|
|
388
|
+
if (match.event.type === "assistant/message") return {
|
|
148
389
|
...context.state,
|
|
149
|
-
assistantSeq: match.event.seq
|
|
390
|
+
assistantSeq: match.event.seq,
|
|
391
|
+
anchorSeq: match.event.seq - .1
|
|
150
392
|
};
|
|
393
|
+
if (match.event.type === "step/end") return context.state.assistantSeq === void 0 ? {
|
|
394
|
+
...context.state,
|
|
395
|
+
anchorSeq: match.event.seq - .1
|
|
396
|
+
} : context.state;
|
|
397
|
+
throw new Error("Claude activity step update requires assistant/message or step/end");
|
|
151
398
|
},
|
|
152
399
|
buildViewNode(context) {
|
|
153
400
|
const state = context.state;
|
|
154
|
-
if (state
|
|
401
|
+
if (state === void 0) return null;
|
|
155
402
|
return {
|
|
156
403
|
key: context.key,
|
|
157
404
|
kind: "claude-activity-step",
|
|
158
405
|
id: context.id,
|
|
159
406
|
target: "chat",
|
|
160
|
-
anchorSeq: state.
|
|
407
|
+
anchorSeq: state.anchorSeq,
|
|
161
408
|
location: context.start?.location ?? { kind: "unresolved" },
|
|
162
409
|
visibility: "visible",
|
|
163
410
|
data: {
|
|
@@ -535,19 +782,35 @@ window.__ModuleLoader__.load({
|
|
|
535
782
|
fontSize: 12,
|
|
536
783
|
lineHeight: "17px"
|
|
537
784
|
};
|
|
538
|
-
const
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
785
|
+
const panelIconButtonClass = "dshClaudePanelIconButton";
|
|
786
|
+
const panelIconButtonCss = `
|
|
787
|
+
.${panelIconButtonClass} {
|
|
788
|
+
width: 26px;
|
|
789
|
+
height: 26px;
|
|
790
|
+
display: grid;
|
|
791
|
+
place-items: center;
|
|
792
|
+
padding: 0;
|
|
793
|
+
border: none;
|
|
794
|
+
border-radius: 7px;
|
|
795
|
+
background: transparent;
|
|
796
|
+
color: var(--dsw-alias-label-tertiary);
|
|
797
|
+
font: inherit;
|
|
798
|
+
line-height: 1;
|
|
799
|
+
cursor: pointer;
|
|
800
|
+
transition: background-color 120ms ease, color 120ms ease;
|
|
801
|
+
}
|
|
802
|
+
.${panelIconButtonClass}:hover {
|
|
803
|
+
background: color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent);
|
|
804
|
+
color: var(--dsw-alias-label-primary);
|
|
805
|
+
}
|
|
806
|
+
.${panelIconButtonClass}:active {
|
|
807
|
+
background: color-mix(in srgb, var(--dsw-alias-label-primary) 14%, transparent);
|
|
808
|
+
}
|
|
809
|
+
.${panelIconButtonClass}:focus-visible {
|
|
810
|
+
outline: 2px solid var(--dsw-static-blue-450);
|
|
811
|
+
outline-offset: 1px;
|
|
812
|
+
}
|
|
813
|
+
`;
|
|
551
814
|
const tasksBody = {
|
|
552
815
|
flex: 1,
|
|
553
816
|
minHeight: 0,
|
|
@@ -729,26 +992,105 @@ window.__ModuleLoader__.load({
|
|
|
729
992
|
lineHeight: "16px",
|
|
730
993
|
cursor: "pointer"
|
|
731
994
|
};
|
|
732
|
-
const
|
|
995
|
+
const tasksBadgeWrap = {
|
|
996
|
+
display: "flex",
|
|
997
|
+
justifyContent: "flex-end",
|
|
998
|
+
margin: "8px 0 4px"
|
|
999
|
+
};
|
|
1000
|
+
const tasksBadgeSeat = {
|
|
1001
|
+
position: "relative",
|
|
1002
|
+
display: "inline-flex"
|
|
1003
|
+
};
|
|
1004
|
+
const tasksTurnBadge = {
|
|
733
1005
|
display: "inline-flex",
|
|
734
1006
|
alignItems: "center",
|
|
735
|
-
gap:
|
|
736
|
-
|
|
737
|
-
padding: "5px 8px",
|
|
1007
|
+
gap: 5,
|
|
1008
|
+
padding: "2px 4px",
|
|
738
1009
|
border: "none",
|
|
739
|
-
borderRadius:
|
|
1010
|
+
borderRadius: 6,
|
|
740
1011
|
background: "transparent",
|
|
741
|
-
color: "var(--dsw-alias-label-
|
|
1012
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
742
1013
|
font: "inherit",
|
|
1014
|
+
fontSize: 11,
|
|
1015
|
+
lineHeight: "16px",
|
|
1016
|
+
fontVariantNumeric: "tabular-nums",
|
|
1017
|
+
cursor: "pointer",
|
|
1018
|
+
transition: "color 120ms ease, opacity 120ms ease"
|
|
1019
|
+
};
|
|
1020
|
+
const tasksBadgeHovered = { color: "var(--dsw-alias-label-secondary)" };
|
|
1021
|
+
const tasksBadgeDone = { opacity: .7 };
|
|
1022
|
+
const tasksBadgeDot = {
|
|
1023
|
+
width: 8,
|
|
1024
|
+
height: 8,
|
|
1025
|
+
flex: "none",
|
|
1026
|
+
borderRadius: 999,
|
|
1027
|
+
background: "var(--dsw-static-blue-450)"
|
|
1028
|
+
};
|
|
1029
|
+
const tasksBadgeDotError = { background: "var(--dsw-alias-state-error-primary)" };
|
|
1030
|
+
const tasksBadgeDotDone = { background: "var(--dsw-alias-state-success-primary, var(--dsw-static-green-500))" };
|
|
1031
|
+
const tasksBadgeCount = { fontWeight: 600 };
|
|
1032
|
+
const tasksHoverCard = {
|
|
1033
|
+
position: "absolute",
|
|
1034
|
+
right: 0,
|
|
1035
|
+
bottom: "calc(100% + 8px)",
|
|
1036
|
+
zIndex: 40,
|
|
1037
|
+
minWidth: 240,
|
|
1038
|
+
maxWidth: 340,
|
|
1039
|
+
boxSizing: "border-box",
|
|
1040
|
+
display: "flex",
|
|
1041
|
+
flexDirection: "column",
|
|
1042
|
+
gap: 6,
|
|
1043
|
+
padding: "10px 12px",
|
|
1044
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
1045
|
+
borderRadius: 12,
|
|
1046
|
+
background: "var(--dsw-alias-bg-layer-2)",
|
|
1047
|
+
boxShadow: "0 8px 24px color-mix(in srgb, #000 24%, transparent)",
|
|
743
1048
|
fontSize: 12,
|
|
744
1049
|
lineHeight: "18px",
|
|
745
|
-
|
|
1050
|
+
pointerEvents: "auto"
|
|
746
1051
|
};
|
|
747
|
-
const
|
|
748
|
-
color: "var(--dsw-
|
|
749
|
-
|
|
1052
|
+
const tasksHoverHeader = {
|
|
1053
|
+
color: "var(--dsw-alias-label-primary)",
|
|
1054
|
+
fontWeight: 600
|
|
1055
|
+
};
|
|
1056
|
+
const tasksHoverRow = {
|
|
1057
|
+
minWidth: 0,
|
|
1058
|
+
display: "flex",
|
|
1059
|
+
alignItems: "center",
|
|
1060
|
+
gap: 7
|
|
1061
|
+
};
|
|
1062
|
+
const tasksHoverGlyph = {
|
|
1063
|
+
width: 12,
|
|
1064
|
+
flex: "none",
|
|
1065
|
+
textAlign: "center",
|
|
1066
|
+
fontSize: 10,
|
|
1067
|
+
lineHeight: 1,
|
|
1068
|
+
fontWeight: 700
|
|
1069
|
+
};
|
|
1070
|
+
const tasksHoverGlyphRunning = { color: "var(--dsw-static-blue-450)" };
|
|
1071
|
+
const tasksHoverGlyphError = { color: "var(--dsw-alias-state-error-primary)" };
|
|
1072
|
+
const tasksHoverGlyphDone = { color: "var(--dsw-alias-state-success-primary, var(--dsw-static-green-500))" };
|
|
1073
|
+
const tasksHoverDesc = {
|
|
1074
|
+
minWidth: 0,
|
|
1075
|
+
flex: 1,
|
|
1076
|
+
overflow: "hidden",
|
|
1077
|
+
textOverflow: "ellipsis",
|
|
1078
|
+
whiteSpace: "nowrap",
|
|
1079
|
+
color: "var(--dsw-alias-label-secondary)"
|
|
1080
|
+
};
|
|
1081
|
+
const tasksHoverType = {
|
|
1082
|
+
flex: "none",
|
|
1083
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
1084
|
+
fontSize: 10
|
|
1085
|
+
};
|
|
1086
|
+
const tasksHoverMore = { color: "var(--dsw-alias-label-tertiary)" };
|
|
1087
|
+
const tasksHoverHint = {
|
|
1088
|
+
marginTop: 2,
|
|
1089
|
+
paddingTop: 6,
|
|
1090
|
+
borderTop: "1px solid var(--dsw-alias-border-l1)",
|
|
1091
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
1092
|
+
fontSize: 11
|
|
750
1093
|
};
|
|
751
|
-
const tasksTurnLauncherDone = { color: "var(--dsw-alias-state-success-primary, var(--dsw-alias-label-tertiary))" };
|
|
752
1094
|
const heroRepositoryControls = {
|
|
753
1095
|
position: "relative",
|
|
754
1096
|
display: "inline-flex",
|
|
@@ -1069,6 +1411,10 @@ window.__ModuleLoader__.load({
|
|
|
1069
1411
|
lineHeight: "20px",
|
|
1070
1412
|
textAlign: "left"
|
|
1071
1413
|
};
|
|
1414
|
+
const repositoryBarMerged = {
|
|
1415
|
+
borderColor: "color-mix(in srgb, #a78bfa 30%, var(--dsw-alias-border-l2))",
|
|
1416
|
+
background: "color-mix(in srgb, #a78bfa 5%, var(--dsw-alias-bg-layer-1))"
|
|
1417
|
+
};
|
|
1072
1418
|
const repositoryPrIcon = {
|
|
1073
1419
|
width: 20,
|
|
1074
1420
|
height: 20,
|
|
@@ -1078,6 +1424,7 @@ window.__ModuleLoader__.load({
|
|
|
1078
1424
|
borderRadius: 6,
|
|
1079
1425
|
color: "var(--dsw-alias-state-success-primary, var(--dsw-static-blue-450))"
|
|
1080
1426
|
};
|
|
1427
|
+
const repositoryPrIconMerged = { color: "#a78bfa" };
|
|
1081
1428
|
const repositoryPrimary = {
|
|
1082
1429
|
minWidth: 0,
|
|
1083
1430
|
flex: 1,
|
|
@@ -1099,6 +1446,7 @@ window.__ModuleLoader__.load({
|
|
|
1099
1446
|
textDecoration: "none",
|
|
1100
1447
|
cursor: "pointer"
|
|
1101
1448
|
};
|
|
1449
|
+
const repositoryPrLinkMerged = { color: "#a78bfa" };
|
|
1102
1450
|
const repositoryPrHoverCard = {
|
|
1103
1451
|
position: "absolute",
|
|
1104
1452
|
zIndex: 30,
|
|
@@ -1134,6 +1482,10 @@ window.__ModuleLoader__.load({
|
|
|
1134
1482
|
fontSize: 11,
|
|
1135
1483
|
fontWeight: 650
|
|
1136
1484
|
};
|
|
1485
|
+
const repositoryPrStateBadgeMerged = {
|
|
1486
|
+
background: "color-mix(in srgb, #a78bfa 18%, transparent)",
|
|
1487
|
+
color: "#a78bfa"
|
|
1488
|
+
};
|
|
1137
1489
|
const repositoryPrHoverRepo = {
|
|
1138
1490
|
minWidth: 0,
|
|
1139
1491
|
flex: 1,
|
|
@@ -1248,6 +1600,31 @@ window.__ModuleLoader__.load({
|
|
|
1248
1600
|
const repositoryItemSuccess = { color: "var(--dsw-alias-state-success-primary)" };
|
|
1249
1601
|
const repositoryItemWarning = { color: "var(--dsw-alias-state-warning-primary, #d69e2e)" };
|
|
1250
1602
|
const repositoryItemError = { color: "var(--dsw-alias-state-error-primary)" };
|
|
1603
|
+
const repositoryMergedStatus = {
|
|
1604
|
+
minWidth: 0,
|
|
1605
|
+
display: "inline-flex",
|
|
1606
|
+
alignItems: "center",
|
|
1607
|
+
gap: 6,
|
|
1608
|
+
overflow: "hidden",
|
|
1609
|
+
color: "#a78bfa",
|
|
1610
|
+
fontSize: 12,
|
|
1611
|
+
fontWeight: 600,
|
|
1612
|
+
whiteSpace: "nowrap",
|
|
1613
|
+
textOverflow: "ellipsis"
|
|
1614
|
+
};
|
|
1615
|
+
const repositoryMergedDot = {
|
|
1616
|
+
width: 6,
|
|
1617
|
+
height: 6,
|
|
1618
|
+
flex: "none",
|
|
1619
|
+
borderRadius: 999,
|
|
1620
|
+
background: "currentColor"
|
|
1621
|
+
};
|
|
1622
|
+
const repositoryMergedAge = {
|
|
1623
|
+
overflow: "hidden",
|
|
1624
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
1625
|
+
fontWeight: 500,
|
|
1626
|
+
textOverflow: "ellipsis"
|
|
1627
|
+
};
|
|
1251
1628
|
const diffTrigger = {
|
|
1252
1629
|
flex: "none",
|
|
1253
1630
|
display: "inline-flex",
|
|
@@ -1264,85 +1641,334 @@ window.__ModuleLoader__.load({
|
|
|
1264
1641
|
fontWeight: 650,
|
|
1265
1642
|
cursor: "pointer"
|
|
1266
1643
|
};
|
|
1644
|
+
const diffTriggerMuted = {
|
|
1645
|
+
background: "transparent",
|
|
1646
|
+
color: "var(--dsw-alias-label-tertiary)"
|
|
1647
|
+
};
|
|
1267
1648
|
const diffAdd = { color: "var(--dsw-alias-state-success-primary)" };
|
|
1268
1649
|
const diffDelete = { color: "var(--dsw-alias-state-error-primary)" };
|
|
1269
|
-
const
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1650
|
+
const diffCommentButtonClass = "dshClaudeDiffCommentButton";
|
|
1651
|
+
const diffLineRowClass = "dshClaudeDiffLineRow";
|
|
1652
|
+
const diffCommentTextareaClass = "dshClaudeDiffCommentTextarea";
|
|
1653
|
+
const diffCommentCss = `
|
|
1654
|
+
.${diffCommentButtonClass} {
|
|
1655
|
+
width: 18px;
|
|
1656
|
+
height: 18px;
|
|
1657
|
+
flex: none;
|
|
1658
|
+
display: grid;
|
|
1659
|
+
place-items: center;
|
|
1660
|
+
align-self: center;
|
|
1661
|
+
margin: 0 2px;
|
|
1662
|
+
padding: 0;
|
|
1663
|
+
border: none;
|
|
1664
|
+
border-radius: 4px;
|
|
1665
|
+
background: var(--dsw-static-blue-450);
|
|
1666
|
+
color: var(--dsw-alias-label-on-accent, #fff);
|
|
1667
|
+
font: inherit;
|
|
1668
|
+
font-size: 13px;
|
|
1669
|
+
line-height: 1;
|
|
1670
|
+
cursor: pointer;
|
|
1671
|
+
opacity: 0;
|
|
1672
|
+
transition: opacity 100ms ease;
|
|
1673
|
+
}
|
|
1674
|
+
.${diffLineRowClass}:hover .${diffCommentButtonClass},
|
|
1675
|
+
.${diffCommentButtonClass}:focus-visible {
|
|
1676
|
+
opacity: 1;
|
|
1677
|
+
}
|
|
1678
|
+
.${diffCommentButtonClass}[disabled] {
|
|
1679
|
+
visibility: hidden;
|
|
1680
|
+
}
|
|
1681
|
+
.${diffCommentTextareaClass}:focus {
|
|
1682
|
+
outline: none;
|
|
1683
|
+
box-shadow: inset 0 0 0 1px var(--dsw-static-blue-450);
|
|
1684
|
+
}
|
|
1685
|
+
`;
|
|
1686
|
+
const diffCommentBlock = {
|
|
1687
|
+
boxSizing: "border-box",
|
|
1688
|
+
width: "min(640px, calc(var(--dsh-claude-diff-viewport, 520px) - 72px))",
|
|
1689
|
+
position: "sticky",
|
|
1690
|
+
left: 62,
|
|
1691
|
+
margin: "4px 8px 8px 62px",
|
|
1692
|
+
padding: "8px 10px",
|
|
1277
1693
|
border: "1px solid var(--dsw-alias-border-l2)",
|
|
1278
|
-
borderRadius:
|
|
1694
|
+
borderRadius: 8,
|
|
1279
1695
|
background: "var(--dsw-alias-bg-layer-1)",
|
|
1280
|
-
|
|
1696
|
+
fontFamily: "var(--dsw-font-family, system-ui)",
|
|
1697
|
+
fontSize: 12,
|
|
1698
|
+
lineHeight: "18px",
|
|
1699
|
+
whiteSpace: "normal"
|
|
1281
1700
|
};
|
|
1282
|
-
const
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1701
|
+
const diffCommentCardText = {
|
|
1702
|
+
margin: 0,
|
|
1703
|
+
color: "var(--dsw-alias-label-primary)",
|
|
1704
|
+
overflowWrap: "anywhere"
|
|
1705
|
+
};
|
|
1706
|
+
const diffCommentCardMeta = {
|
|
1286
1707
|
display: "flex",
|
|
1287
1708
|
alignItems: "center",
|
|
1288
1709
|
justifyContent: "space-between",
|
|
1289
|
-
gap:
|
|
1290
|
-
|
|
1291
|
-
|
|
1710
|
+
gap: 8,
|
|
1711
|
+
marginBottom: 4,
|
|
1712
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
1713
|
+
fontSize: 11
|
|
1292
1714
|
};
|
|
1293
|
-
const
|
|
1294
|
-
|
|
1715
|
+
const diffCommentTextarea = {
|
|
1716
|
+
width: "100%",
|
|
1717
|
+
minHeight: 56,
|
|
1718
|
+
boxSizing: "border-box",
|
|
1719
|
+
padding: "6px 8px",
|
|
1720
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
1721
|
+
borderRadius: 6,
|
|
1722
|
+
background: "var(--dsw-alias-bg-base)",
|
|
1723
|
+
color: "var(--dsw-alias-label-primary)",
|
|
1724
|
+
font: "inherit",
|
|
1725
|
+
resize: "vertical"
|
|
1726
|
+
};
|
|
1727
|
+
const diffCommentActions = {
|
|
1295
1728
|
display: "flex",
|
|
1296
|
-
|
|
1729
|
+
justifyContent: "flex-end",
|
|
1297
1730
|
gap: 8,
|
|
1298
|
-
|
|
1299
|
-
fontSize: 15,
|
|
1300
|
-
fontWeight: 650
|
|
1731
|
+
marginTop: 6
|
|
1301
1732
|
};
|
|
1302
|
-
const
|
|
1303
|
-
|
|
1304
|
-
|
|
1733
|
+
const diffCommentActionButton = {
|
|
1734
|
+
minHeight: 24,
|
|
1735
|
+
padding: "2px 10px",
|
|
1736
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
1737
|
+
borderRadius: 6,
|
|
1738
|
+
background: "transparent",
|
|
1739
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
1740
|
+
font: "inherit",
|
|
1305
1741
|
fontSize: 12,
|
|
1306
|
-
|
|
1307
|
-
textOverflow: "ellipsis",
|
|
1308
|
-
whiteSpace: "nowrap"
|
|
1742
|
+
cursor: "pointer"
|
|
1309
1743
|
};
|
|
1310
|
-
const
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
padding: "6px 12px",
|
|
1316
|
-
borderBottom: "1px solid var(--dsw-alias-border-l2)",
|
|
1317
|
-
color: "var(--dsw-alias-label-tertiary)",
|
|
1318
|
-
fontSize: 12
|
|
1744
|
+
const diffCommentSubmitButton = {
|
|
1745
|
+
border: "none",
|
|
1746
|
+
background: "var(--dsw-static-blue-450)",
|
|
1747
|
+
color: "var(--dsw-alias-label-on-accent, #fff)",
|
|
1748
|
+
fontWeight: 600
|
|
1319
1749
|
};
|
|
1320
|
-
const
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
background: "var(--dsw-alias-bg-base)"
|
|
1750
|
+
const diffCommentError = {
|
|
1751
|
+
margin: "4px 0 0",
|
|
1752
|
+
color: "var(--dsw-alias-state-error-primary)",
|
|
1753
|
+
fontSize: 11
|
|
1325
1754
|
};
|
|
1326
|
-
const
|
|
1327
|
-
|
|
1755
|
+
const reviewCommentBarFrame = {
|
|
1756
|
+
width: "calc(100% - 64px)",
|
|
1757
|
+
maxWidth: "var(--dsh-conversation-composer-max-width, 782px)",
|
|
1758
|
+
margin: "0 auto",
|
|
1759
|
+
boxSizing: "border-box"
|
|
1760
|
+
};
|
|
1761
|
+
const reviewCommentBar = {
|
|
1328
1762
|
width: "100%",
|
|
1329
|
-
|
|
1763
|
+
minWidth: 0,
|
|
1764
|
+
minHeight: 42,
|
|
1765
|
+
boxSizing: "border-box",
|
|
1330
1766
|
display: "flex",
|
|
1767
|
+
flexWrap: "wrap",
|
|
1331
1768
|
alignItems: "center",
|
|
1332
|
-
gap:
|
|
1333
|
-
padding: "7px
|
|
1334
|
-
border: "
|
|
1769
|
+
gap: 8,
|
|
1770
|
+
padding: "7px 11px",
|
|
1771
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
1772
|
+
borderRadius: 11,
|
|
1335
1773
|
background: "var(--dsw-alias-bg-layer-1)",
|
|
1774
|
+
boxShadow: "0 1px 2px color-mix(in srgb, var(--dsw-alias-label-primary) 4%, transparent)",
|
|
1336
1775
|
color: "var(--dsw-alias-label-primary)",
|
|
1337
|
-
font: "inherit",
|
|
1338
1776
|
fontSize: 12,
|
|
1339
|
-
|
|
1340
|
-
cursor: "pointer"
|
|
1777
|
+
lineHeight: "20px"
|
|
1341
1778
|
};
|
|
1342
|
-
const
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1779
|
+
const reviewCommentIcon = {
|
|
1780
|
+
width: 20,
|
|
1781
|
+
height: 20,
|
|
1782
|
+
display: "grid",
|
|
1783
|
+
placeItems: "center",
|
|
1784
|
+
flex: "none",
|
|
1785
|
+
color: "var(--dsw-static-blue-450)"
|
|
1786
|
+
};
|
|
1787
|
+
const reviewCommentClearSeat = {
|
|
1788
|
+
marginLeft: "auto",
|
|
1789
|
+
alignSelf: "flex-start",
|
|
1790
|
+
flex: "none",
|
|
1791
|
+
display: "inline-flex"
|
|
1792
|
+
};
|
|
1793
|
+
const reviewCommentChip = {
|
|
1794
|
+
display: "inline-flex",
|
|
1795
|
+
alignItems: "center",
|
|
1796
|
+
gap: 3,
|
|
1797
|
+
maxWidth: 240,
|
|
1798
|
+
padding: "1px 4px 1px 9px",
|
|
1799
|
+
border: "1px solid color-mix(in srgb, var(--dsw-static-blue-450) 32%, transparent)",
|
|
1800
|
+
borderRadius: 999,
|
|
1801
|
+
background: "color-mix(in srgb, var(--dsw-static-blue-450) 10%, transparent)",
|
|
1802
|
+
color: "var(--dsw-alias-label-primary)",
|
|
1803
|
+
fontSize: 12,
|
|
1804
|
+
lineHeight: "20px"
|
|
1805
|
+
};
|
|
1806
|
+
const reviewCommentChipLabel$1 = {
|
|
1807
|
+
overflow: "hidden",
|
|
1808
|
+
textOverflow: "ellipsis",
|
|
1809
|
+
whiteSpace: "nowrap"
|
|
1810
|
+
};
|
|
1811
|
+
const reviewCommentChipRemove = {
|
|
1812
|
+
width: 16,
|
|
1813
|
+
height: 16,
|
|
1814
|
+
flex: "none",
|
|
1815
|
+
display: "grid",
|
|
1816
|
+
placeItems: "center",
|
|
1817
|
+
padding: 0,
|
|
1818
|
+
border: "none",
|
|
1819
|
+
borderRadius: 999,
|
|
1820
|
+
background: "transparent",
|
|
1821
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
1822
|
+
font: "inherit",
|
|
1823
|
+
fontSize: 12,
|
|
1824
|
+
lineHeight: 1,
|
|
1825
|
+
cursor: "pointer"
|
|
1826
|
+
};
|
|
1827
|
+
const reviewCommentHoverCard = {
|
|
1828
|
+
display: "block",
|
|
1829
|
+
maxWidth: 360,
|
|
1830
|
+
padding: "8px 10px",
|
|
1831
|
+
fontSize: 12,
|
|
1832
|
+
lineHeight: "18px"
|
|
1833
|
+
};
|
|
1834
|
+
const reviewCommentHoverPath = {
|
|
1835
|
+
display: "block",
|
|
1836
|
+
marginBottom: 4,
|
|
1837
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
1838
|
+
fontSize: 11,
|
|
1839
|
+
overflowWrap: "anywhere"
|
|
1840
|
+
};
|
|
1841
|
+
const reviewCommentHoverText = {
|
|
1842
|
+
margin: 0,
|
|
1843
|
+
color: "var(--dsw-alias-label-primary)",
|
|
1844
|
+
whiteSpace: "pre-wrap",
|
|
1845
|
+
overflowWrap: "anywhere"
|
|
1846
|
+
};
|
|
1847
|
+
const diffAhead = { color: "var(--dsw-static-blue-450)" };
|
|
1848
|
+
const diffAheadMuted = { color: "color-mix(in srgb, var(--dsw-static-blue-450) 62%, var(--dsw-alias-label-tertiary))" };
|
|
1849
|
+
const diffAddMuted = { color: "color-mix(in srgb, var(--dsw-alias-state-success-primary) 62%, var(--dsw-alias-label-tertiary))" };
|
|
1850
|
+
const diffDeleteMuted = { color: "color-mix(in srgb, var(--dsw-alias-state-error-primary) 62%, var(--dsw-alias-label-tertiary))" };
|
|
1851
|
+
const diffPanel = {
|
|
1852
|
+
display: "flex",
|
|
1853
|
+
flexDirection: "column",
|
|
1854
|
+
width: "calc(100% - 16px)",
|
|
1855
|
+
height: "calc(100% - 16px)",
|
|
1856
|
+
minWidth: 0,
|
|
1857
|
+
margin: 8,
|
|
1858
|
+
overflow: "hidden",
|
|
1859
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
1860
|
+
borderRadius: 12,
|
|
1861
|
+
background: "var(--dsw-alias-bg-layer-1)",
|
|
1862
|
+
boxShadow: "0 4px 16px color-mix(in srgb, #000 12%, transparent)"
|
|
1863
|
+
};
|
|
1864
|
+
const diffPanelMaximized = {
|
|
1865
|
+
width: "100%",
|
|
1866
|
+
height: "100%",
|
|
1867
|
+
margin: 0
|
|
1868
|
+
};
|
|
1869
|
+
const diffHeader = {
|
|
1870
|
+
boxSizing: "border-box",
|
|
1871
|
+
height: 49,
|
|
1872
|
+
flex: "none",
|
|
1873
|
+
display: "flex",
|
|
1874
|
+
alignItems: "center",
|
|
1875
|
+
justifyContent: "space-between",
|
|
1876
|
+
gap: 10,
|
|
1877
|
+
padding: "9px 12px",
|
|
1878
|
+
borderBottom: "1px solid var(--dsw-alias-border-l2)"
|
|
1879
|
+
};
|
|
1880
|
+
const diffHeaderTitle = {
|
|
1881
|
+
minWidth: 0,
|
|
1882
|
+
display: "flex",
|
|
1883
|
+
alignItems: "center",
|
|
1884
|
+
gap: 8,
|
|
1885
|
+
color: "var(--dsw-alias-label-primary)",
|
|
1886
|
+
fontSize: 15,
|
|
1887
|
+
fontWeight: 650
|
|
1888
|
+
};
|
|
1889
|
+
const diffHeaderActions = {
|
|
1890
|
+
display: "flex",
|
|
1891
|
+
alignItems: "center",
|
|
1892
|
+
gap: 5
|
|
1893
|
+
};
|
|
1894
|
+
const diffSplitButton = {
|
|
1895
|
+
display: "inline-flex",
|
|
1896
|
+
alignItems: "stretch"
|
|
1897
|
+
};
|
|
1898
|
+
const diffCommitButton = {
|
|
1899
|
+
minHeight: 28,
|
|
1900
|
+
padding: "4px 10px",
|
|
1901
|
+
border: "none",
|
|
1902
|
+
borderRadius: "7px 0 0 7px",
|
|
1903
|
+
background: "var(--dsw-static-blue-450)",
|
|
1904
|
+
color: "var(--dsw-alias-label-on-accent, #fff)",
|
|
1905
|
+
font: "inherit",
|
|
1906
|
+
fontSize: 12,
|
|
1907
|
+
fontWeight: 650,
|
|
1908
|
+
cursor: "pointer"
|
|
1909
|
+
};
|
|
1910
|
+
const diffActionDisabled = {
|
|
1911
|
+
opacity: .45,
|
|
1912
|
+
cursor: "default"
|
|
1913
|
+
};
|
|
1914
|
+
const diffCommitMenuButton = {
|
|
1915
|
+
width: 28,
|
|
1916
|
+
minHeight: 28,
|
|
1917
|
+
display: "grid",
|
|
1918
|
+
placeItems: "center",
|
|
1919
|
+
padding: 0,
|
|
1920
|
+
border: "none",
|
|
1921
|
+
borderLeft: "1px solid color-mix(in srgb, #fff 32%, transparent)",
|
|
1922
|
+
borderRadius: "0 7px 7px 0",
|
|
1923
|
+
background: "var(--dsw-static-blue-450)",
|
|
1924
|
+
color: "var(--dsw-alias-label-on-accent, #fff)",
|
|
1925
|
+
font: "inherit",
|
|
1926
|
+
cursor: "pointer"
|
|
1927
|
+
};
|
|
1928
|
+
const diffHeaderBranch = {
|
|
1929
|
+
overflow: "hidden",
|
|
1930
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
1931
|
+
fontSize: 12,
|
|
1932
|
+
fontWeight: 500,
|
|
1933
|
+
textOverflow: "ellipsis",
|
|
1934
|
+
whiteSpace: "nowrap"
|
|
1935
|
+
};
|
|
1936
|
+
const diffSummary = {
|
|
1937
|
+
minHeight: 34,
|
|
1938
|
+
display: "flex",
|
|
1939
|
+
alignItems: "center",
|
|
1940
|
+
gap: 7,
|
|
1941
|
+
padding: "6px 12px",
|
|
1942
|
+
borderBottom: "1px solid var(--dsw-alias-border-l2)",
|
|
1943
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
1944
|
+
fontSize: 12
|
|
1945
|
+
};
|
|
1946
|
+
const diffBody = {
|
|
1947
|
+
flex: 1,
|
|
1948
|
+
minHeight: 0,
|
|
1949
|
+
overflow: "auto",
|
|
1950
|
+
background: "var(--dsw-alias-bg-base)"
|
|
1951
|
+
};
|
|
1952
|
+
const diffFile = { borderBottom: "1px solid var(--dsw-alias-border-l2)" };
|
|
1953
|
+
const diffFileHeader = {
|
|
1954
|
+
width: "100%",
|
|
1955
|
+
minHeight: 38,
|
|
1956
|
+
display: "flex",
|
|
1957
|
+
alignItems: "center",
|
|
1958
|
+
gap: 7,
|
|
1959
|
+
padding: "7px 10px",
|
|
1960
|
+
border: "none",
|
|
1961
|
+
background: "var(--dsw-alias-bg-layer-1)",
|
|
1962
|
+
color: "var(--dsw-alias-label-primary)",
|
|
1963
|
+
font: "inherit",
|
|
1964
|
+
fontSize: 12,
|
|
1965
|
+
textAlign: "left",
|
|
1966
|
+
cursor: "pointer"
|
|
1967
|
+
};
|
|
1968
|
+
const diffFilePath = {
|
|
1969
|
+
minWidth: 0,
|
|
1970
|
+
flex: 1,
|
|
1971
|
+
overflow: "hidden",
|
|
1346
1972
|
textOverflow: "ellipsis",
|
|
1347
1973
|
whiteSpace: "nowrap"
|
|
1348
1974
|
};
|
|
@@ -1409,6 +2035,152 @@ window.__ModuleLoader__.load({
|
|
|
1409
2035
|
color: "var(--dsw-alias-label-tertiary)",
|
|
1410
2036
|
fontSize: 11
|
|
1411
2037
|
};
|
|
2038
|
+
const diffModalCss = `
|
|
2039
|
+
.dshClaudeRepositoryActionModal {
|
|
2040
|
+
box-sizing: border-box;
|
|
2041
|
+
width: min(760px, calc(100vw - 48px));
|
|
2042
|
+
max-width: calc(100vw - 48px);
|
|
2043
|
+
max-height: min(680px, calc(100vh - 48px));
|
|
2044
|
+
}
|
|
2045
|
+
.dshClaudeRepositoryActionModalContent {
|
|
2046
|
+
flex: 1;
|
|
2047
|
+
min-height: 0;
|
|
2048
|
+
overflow-y: auto;
|
|
2049
|
+
}
|
|
2050
|
+
.dshClaudeRepositoryActionModalContent > div:first-child {
|
|
2051
|
+
position: sticky;
|
|
2052
|
+
top: 0;
|
|
2053
|
+
z-index: 2;
|
|
2054
|
+
background: var(--dsw-alias-bg-layer-2);
|
|
2055
|
+
}
|
|
2056
|
+
.dshClaudeRepositoryActionModalContent h2 {
|
|
2057
|
+
font-size: 24px;
|
|
2058
|
+
line-height: 32px;
|
|
2059
|
+
}
|
|
2060
|
+
.dshClaudeRepositoryActionModalContent > p {
|
|
2061
|
+
font-size: 18px;
|
|
2062
|
+
line-height: 28px;
|
|
2063
|
+
}
|
|
2064
|
+
.dshClaudeRepositoryActionModal input[type='checkbox'] {
|
|
2065
|
+
width: 18px;
|
|
2066
|
+
height: 18px;
|
|
2067
|
+
}
|
|
2068
|
+
.dshClaudeRepositoryActionModal textarea:focus,
|
|
2069
|
+
.dshClaudeRepositoryActionModal input:not([type='checkbox']):focus {
|
|
2070
|
+
outline: none;
|
|
2071
|
+
box-shadow: inset 0 0 0 1px var(--dsw-static-blue-450);
|
|
2072
|
+
}
|
|
2073
|
+
`;
|
|
2074
|
+
const diffModalBody = {
|
|
2075
|
+
display: "flex",
|
|
2076
|
+
flexDirection: "column",
|
|
2077
|
+
gap: 16,
|
|
2078
|
+
width: "100%",
|
|
2079
|
+
minWidth: 0,
|
|
2080
|
+
boxSizing: "border-box"
|
|
2081
|
+
};
|
|
2082
|
+
const diffModalMeta = {
|
|
2083
|
+
display: "flex",
|
|
2084
|
+
justifyContent: "space-between",
|
|
2085
|
+
gap: 16,
|
|
2086
|
+
minWidth: 0,
|
|
2087
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
2088
|
+
fontSize: 16,
|
|
2089
|
+
lineHeight: "24px"
|
|
2090
|
+
};
|
|
2091
|
+
const diffModalMetaText = {
|
|
2092
|
+
minWidth: 0,
|
|
2093
|
+
overflow: "hidden",
|
|
2094
|
+
textOverflow: "ellipsis",
|
|
2095
|
+
whiteSpace: "nowrap"
|
|
2096
|
+
};
|
|
2097
|
+
const diffModalFiles = {
|
|
2098
|
+
minWidth: 0,
|
|
2099
|
+
maxHeight: 300,
|
|
2100
|
+
overflowX: "hidden",
|
|
2101
|
+
overflowY: "auto",
|
|
2102
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
2103
|
+
borderRadius: 8
|
|
2104
|
+
};
|
|
2105
|
+
const diffModalFile = {
|
|
2106
|
+
display: "flex",
|
|
2107
|
+
justifyContent: "space-between",
|
|
2108
|
+
gap: 12,
|
|
2109
|
+
minWidth: 0,
|
|
2110
|
+
padding: "10px 14px",
|
|
2111
|
+
borderBottom: "1px solid var(--dsw-alias-border-l2)",
|
|
2112
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
2113
|
+
fontSize: 15,
|
|
2114
|
+
lineHeight: "22px"
|
|
2115
|
+
};
|
|
2116
|
+
const diffModalFilePath = {
|
|
2117
|
+
minWidth: 0,
|
|
2118
|
+
overflow: "hidden",
|
|
2119
|
+
textOverflow: "ellipsis",
|
|
2120
|
+
whiteSpace: "nowrap"
|
|
2121
|
+
};
|
|
2122
|
+
const diffModalFileState = { flex: "none" };
|
|
2123
|
+
const diffModalField = {
|
|
2124
|
+
display: "flex",
|
|
2125
|
+
flexDirection: "column",
|
|
2126
|
+
gap: 8,
|
|
2127
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
2128
|
+
fontSize: 16,
|
|
2129
|
+
lineHeight: "24px",
|
|
2130
|
+
fontWeight: 550
|
|
2131
|
+
};
|
|
2132
|
+
const diffModalTextarea = {
|
|
2133
|
+
...settingTextInput,
|
|
2134
|
+
minHeight: 140,
|
|
2135
|
+
padding: "10px 14px",
|
|
2136
|
+
fontSize: 16,
|
|
2137
|
+
lineHeight: "24px",
|
|
2138
|
+
resize: "vertical"
|
|
2139
|
+
};
|
|
2140
|
+
const diffModalTextInput = {
|
|
2141
|
+
...settingTextInput,
|
|
2142
|
+
minHeight: 44,
|
|
2143
|
+
padding: "9px 14px",
|
|
2144
|
+
fontSize: 16,
|
|
2145
|
+
lineHeight: "24px"
|
|
2146
|
+
};
|
|
2147
|
+
const diffModalCheckbox = {
|
|
2148
|
+
display: "flex",
|
|
2149
|
+
alignItems: "center",
|
|
2150
|
+
gap: 10,
|
|
2151
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
2152
|
+
fontSize: 16,
|
|
2153
|
+
lineHeight: "24px"
|
|
2154
|
+
};
|
|
2155
|
+
const diffModalFooter = {
|
|
2156
|
+
display: "flex",
|
|
2157
|
+
justifyContent: "flex-end",
|
|
2158
|
+
gap: 12
|
|
2159
|
+
};
|
|
2160
|
+
const diffModalButton = {
|
|
2161
|
+
minHeight: 42,
|
|
2162
|
+
padding: "8px 18px",
|
|
2163
|
+
fontSize: 16,
|
|
2164
|
+
lineHeight: "24px"
|
|
2165
|
+
};
|
|
2166
|
+
const diffModalStatus = {
|
|
2167
|
+
margin: 0,
|
|
2168
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
2169
|
+
fontSize: 16,
|
|
2170
|
+
lineHeight: "24px"
|
|
2171
|
+
};
|
|
2172
|
+
const diffModalError = {
|
|
2173
|
+
margin: "10px 0 0",
|
|
2174
|
+
color: "var(--dsw-alias-state-error-primary)",
|
|
2175
|
+
fontSize: 16,
|
|
2176
|
+
lineHeight: "24px"
|
|
2177
|
+
};
|
|
2178
|
+
const diffModalSuccess = {
|
|
2179
|
+
margin: 0,
|
|
2180
|
+
color: "var(--dsw-alias-state-success-primary)",
|
|
2181
|
+
fontSize: 16,
|
|
2182
|
+
lineHeight: "24px"
|
|
2183
|
+
};
|
|
1412
2184
|
//#endregion
|
|
1413
2185
|
//#region src/client/token-format.ts
|
|
1414
2186
|
function formatTokenCount(tokens) {
|
|
@@ -1426,16 +2198,17 @@ window.__ModuleLoader__.load({
|
|
|
1426
2198
|
killed: "tasksKilled"
|
|
1427
2199
|
};
|
|
1428
2200
|
function visibleTaskGroups(tasks, dismissedSettledIds) {
|
|
2201
|
+
const projected = tasks.filter(isProjectedTask);
|
|
1429
2202
|
return {
|
|
1430
|
-
running:
|
|
1431
|
-
finished:
|
|
2203
|
+
running: projected.filter((task) => task.status === "running"),
|
|
2204
|
+
finished: projected.filter((task) => task.status !== "running" && !dismissedSettledIds.has(task.taskId))
|
|
1432
2205
|
};
|
|
1433
2206
|
}
|
|
1434
2207
|
function activitiesForTask(activities, taskId) {
|
|
1435
2208
|
return activities.filter((activity) => activity.taskId === taskId);
|
|
1436
2209
|
}
|
|
1437
2210
|
function tasksForTurn(tasks, turn) {
|
|
1438
|
-
return tasks.filter((task) => task.originTurn === turn);
|
|
2211
|
+
return tasks.filter((task) => task.originTurn === turn && isProjectedTask(task));
|
|
1439
2212
|
}
|
|
1440
2213
|
function summarizeTurnTasks(tasks) {
|
|
1441
2214
|
if (tasks.length === 0) return void 0;
|
|
@@ -1538,7 +2311,7 @@ window.__ModuleLoader__.load({
|
|
|
1538
2311
|
children: task.description
|
|
1539
2312
|
}), /* @__PURE__ */ jsxs("p", {
|
|
1540
2313
|
style: taskStatusLine,
|
|
1541
|
-
children: [/* @__PURE__ */ jsx("span", { children: t(STATUS_LABEL[task.status] ?? "tasksRunning") }), task.backgrounded === true ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
2314
|
+
children: [/* @__PURE__ */ jsx("span", { children: t(STATUS_LABEL[task.status] ?? "tasksRunning") }), task.backgrounded === true ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
|
|
1542
2315
|
"aria-hidden": "true",
|
|
1543
2316
|
children: " · "
|
|
1544
2317
|
}), /* @__PURE__ */ jsx("span", { children: t("tasksBackground") })] }) : null]
|
|
@@ -1574,7 +2347,7 @@ window.__ModuleLoader__.load({
|
|
|
1574
2347
|
}
|
|
1575
2348
|
function GroupHeading(props) {
|
|
1576
2349
|
const { label, count, collapsed, onToggle, action } = props;
|
|
1577
|
-
const content = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", { children: label }), /* @__PURE__ */ jsx("span", {
|
|
2350
|
+
const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", { children: label }), /* @__PURE__ */ jsx("span", {
|
|
1578
2351
|
style: tasksGroupCount,
|
|
1579
2352
|
children: count
|
|
1580
2353
|
})] });
|
|
@@ -1621,96 +2394,192 @@ window.__ModuleLoader__.load({
|
|
|
1621
2394
|
if (!projection.owned) return null;
|
|
1622
2395
|
return /* @__PURE__ */ jsxs("div", {
|
|
1623
2396
|
style: tasksPanel,
|
|
1624
|
-
children: [
|
|
1625
|
-
style
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
style:
|
|
1631
|
-
children:
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
children: [/* @__PURE__ */ jsx(GroupHeading, {
|
|
1644
|
-
label: t("tasksRunning"),
|
|
1645
|
-
count: groups.running.length
|
|
1646
|
-
}), groups.running.length === 0 ? /* @__PURE__ */ jsx("p", {
|
|
1647
|
-
style: tasksGroupEmpty,
|
|
1648
|
-
children: t("tasksNoneRunning")
|
|
1649
|
-
}) : /* @__PURE__ */ jsx("div", {
|
|
1650
|
-
style: taskCardList,
|
|
1651
|
-
children: groups.running.map((task) => /* @__PURE__ */ jsx(TaskCard, {
|
|
1652
|
-
task,
|
|
1653
|
-
activities: taskActivities.get(task.taskId) ?? [],
|
|
1654
|
-
t
|
|
1655
|
-
}, task.taskId))
|
|
2397
|
+
children: [
|
|
2398
|
+
/* @__PURE__ */ jsx("style", {
|
|
2399
|
+
"data-dsh-claude-panel-icon-styles": true,
|
|
2400
|
+
children: panelIconButtonCss
|
|
2401
|
+
}),
|
|
2402
|
+
/* @__PURE__ */ jsxs("div", {
|
|
2403
|
+
style: tasksHeader,
|
|
2404
|
+
children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("span", {
|
|
2405
|
+
style: tasksHeading,
|
|
2406
|
+
children: t("tasksPanelTurn")
|
|
2407
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
2408
|
+
style: tasksTurnMeta,
|
|
2409
|
+
children: t("tasksTurnNumber", { turn })
|
|
2410
|
+
})] }), /* @__PURE__ */ jsx("button", {
|
|
2411
|
+
type: "button",
|
|
2412
|
+
className: panelIconButtonClass,
|
|
2413
|
+
"aria-label": t("tasksClose"),
|
|
2414
|
+
onClick: closeDetails,
|
|
2415
|
+
children: /* @__PURE__ */ jsx(IconCloseOutline16, {})
|
|
1656
2416
|
})]
|
|
1657
|
-
}),
|
|
1658
|
-
|
|
1659
|
-
style:
|
|
1660
|
-
children: [/* @__PURE__ */
|
|
1661
|
-
label: t("
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
}
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
}
|
|
2417
|
+
}),
|
|
2418
|
+
/* @__PURE__ */ jsxs("div", {
|
|
2419
|
+
style: tasksBody,
|
|
2420
|
+
children: [/* @__PURE__ */ jsxs("section", {
|
|
2421
|
+
"aria-label": t("tasksRunning"),
|
|
2422
|
+
children: [/* @__PURE__ */ jsx(GroupHeading, {
|
|
2423
|
+
label: t("tasksRunning"),
|
|
2424
|
+
count: groups.running.length
|
|
2425
|
+
}), groups.running.length === 0 ? /* @__PURE__ */ jsx("p", {
|
|
2426
|
+
style: tasksGroupEmpty,
|
|
2427
|
+
children: t("tasksNoneRunning")
|
|
2428
|
+
}) : /* @__PURE__ */ jsx("div", {
|
|
2429
|
+
style: taskCardList,
|
|
2430
|
+
children: groups.running.map((task) => /* @__PURE__ */ jsx(TaskCard, {
|
|
2431
|
+
task,
|
|
2432
|
+
activities: taskActivities.get(task.taskId) ?? [],
|
|
2433
|
+
t
|
|
2434
|
+
}, task.taskId))
|
|
2435
|
+
})]
|
|
2436
|
+
}), /* @__PURE__ */ jsxs("section", {
|
|
2437
|
+
"aria-label": t("tasksSettled"),
|
|
2438
|
+
style: tasksFinishedSection,
|
|
2439
|
+
children: [/* @__PURE__ */ jsx(GroupHeading, {
|
|
2440
|
+
label: t("tasksSettled"),
|
|
2441
|
+
count: groups.finished.length,
|
|
2442
|
+
collapsed: finishedCollapsed,
|
|
2443
|
+
onToggle: () => setFinishedCollapsed((value) => !value),
|
|
2444
|
+
...groups.finished.length === 0 ? {} : { action: {
|
|
2445
|
+
label: t("tasksClear"),
|
|
2446
|
+
onClick: clearFinished
|
|
2447
|
+
} }
|
|
2448
|
+
}), finishedCollapsed || groups.finished.length === 0 ? null : /* @__PURE__ */ jsx("div", {
|
|
2449
|
+
style: taskCardList,
|
|
2450
|
+
children: groups.finished.map((task) => /* @__PURE__ */ jsx(TaskCard, {
|
|
2451
|
+
task,
|
|
2452
|
+
activities: taskActivities.get(task.taskId) ?? [],
|
|
2453
|
+
t
|
|
2454
|
+
}, task.taskId))
|
|
2455
|
+
})]
|
|
1676
2456
|
})]
|
|
1677
|
-
})
|
|
1678
|
-
|
|
2457
|
+
})
|
|
2458
|
+
]
|
|
1679
2459
|
});
|
|
1680
2460
|
}
|
|
1681
2461
|
//#endregion
|
|
1682
2462
|
//#region src/client/ClaudeActivityTail.tsx
|
|
2463
|
+
const MAX_HOVER_TASKS = 6;
|
|
2464
|
+
function taskGlyph(status) {
|
|
2465
|
+
if (status === "failed") return {
|
|
2466
|
+
glyph: "×",
|
|
2467
|
+
style: tasksHoverGlyphError
|
|
2468
|
+
};
|
|
2469
|
+
if (status === "completed") return {
|
|
2470
|
+
glyph: "✓",
|
|
2471
|
+
style: tasksHoverGlyphDone
|
|
2472
|
+
};
|
|
2473
|
+
return {
|
|
2474
|
+
glyph: "●",
|
|
2475
|
+
style: tasksHoverGlyphRunning
|
|
2476
|
+
};
|
|
2477
|
+
}
|
|
1683
2478
|
function ClaudeTaskLauncher({ turn, tasks, t, openTasks }) {
|
|
1684
|
-
const
|
|
2479
|
+
const [hovered, setHovered] = useState(false);
|
|
2480
|
+
const closeTimer = useRef();
|
|
2481
|
+
const turnTasks = useMemo(() => tasksForTurn(tasks, turn), [tasks, turn]);
|
|
2482
|
+
const summary = useMemo(() => summarizeTurnTasks(turnTasks), [turnTasks]);
|
|
2483
|
+
const open = () => {
|
|
2484
|
+
if (closeTimer.current !== void 0) clearTimeout(closeTimer.current);
|
|
2485
|
+
closeTimer.current = void 0;
|
|
2486
|
+
setHovered(true);
|
|
2487
|
+
};
|
|
2488
|
+
const scheduleClose = () => {
|
|
2489
|
+
if (closeTimer.current !== void 0) clearTimeout(closeTimer.current);
|
|
2490
|
+
closeTimer.current = setTimeout(() => {
|
|
2491
|
+
closeTimer.current = void 0;
|
|
2492
|
+
setHovered(false);
|
|
2493
|
+
}, 350);
|
|
2494
|
+
};
|
|
2495
|
+
useEffect(() => () => {
|
|
2496
|
+
if (closeTimer.current !== void 0) clearTimeout(closeTimer.current);
|
|
2497
|
+
}, []);
|
|
1685
2498
|
if (summary === void 0) return null;
|
|
1686
2499
|
const label = summary.state === "running" ? t("tasksTurnRunning", { count: summary.running }) : summary.state === "failed" ? t("tasksTurnFailed", {
|
|
1687
2500
|
failed: summary.failed,
|
|
1688
2501
|
completed: summary.completed
|
|
1689
2502
|
}) : t("tasksTurnCompleted", { count: summary.completed });
|
|
1690
|
-
const
|
|
2503
|
+
const stateStyle = summary.state === "completed" ? tasksBadgeDone : {};
|
|
2504
|
+
const dotStyle = summary.state === "failed" ? tasksBadgeDotError : summary.state === "completed" ? tasksBadgeDotDone : {};
|
|
1691
2505
|
return /* @__PURE__ */ jsx("div", {
|
|
1692
2506
|
"data-claude-task-launcher": turn,
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
style:
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
2507
|
+
style: tasksBadgeWrap,
|
|
2508
|
+
children: /* @__PURE__ */ jsxs("span", {
|
|
2509
|
+
style: tasksBadgeSeat,
|
|
2510
|
+
onMouseEnter: open,
|
|
2511
|
+
onMouseLeave: scheduleClose,
|
|
2512
|
+
onFocus: open,
|
|
2513
|
+
onBlur: (event) => {
|
|
2514
|
+
if (!event.currentTarget.contains(event.relatedTarget)) scheduleClose();
|
|
2515
|
+
},
|
|
2516
|
+
children: [hovered ? /* @__PURE__ */ jsxs("span", {
|
|
2517
|
+
role: "tooltip",
|
|
2518
|
+
style: tasksHoverCard,
|
|
2519
|
+
onMouseEnter: open,
|
|
2520
|
+
onMouseLeave: scheduleClose,
|
|
2521
|
+
children: [
|
|
2522
|
+
/* @__PURE__ */ jsx("span", {
|
|
2523
|
+
style: tasksHoverHeader,
|
|
2524
|
+
children: label
|
|
2525
|
+
}),
|
|
2526
|
+
turnTasks.slice(0, MAX_HOVER_TASKS).map((task) => {
|
|
2527
|
+
const { glyph, style } = taskGlyph(task.status);
|
|
2528
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
2529
|
+
style: tasksHoverRow,
|
|
2530
|
+
children: [
|
|
2531
|
+
/* @__PURE__ */ jsx("span", {
|
|
2532
|
+
className: task.status === "running" ? "dsh-claude-act-running" : void 0,
|
|
2533
|
+
style: {
|
|
2534
|
+
...tasksHoverGlyph,
|
|
2535
|
+
...style
|
|
2536
|
+
},
|
|
2537
|
+
"aria-hidden": "true",
|
|
2538
|
+
children: glyph
|
|
2539
|
+
}),
|
|
2540
|
+
/* @__PURE__ */ jsx("span", {
|
|
2541
|
+
style: tasksHoverDesc,
|
|
2542
|
+
title: task.description,
|
|
2543
|
+
children: task.description
|
|
2544
|
+
}),
|
|
2545
|
+
task.subagentType === void 0 ? null : /* @__PURE__ */ jsx("span", {
|
|
2546
|
+
style: tasksHoverType,
|
|
2547
|
+
children: task.subagentType
|
|
2548
|
+
})
|
|
2549
|
+
]
|
|
2550
|
+
}, task.taskId);
|
|
2551
|
+
}),
|
|
2552
|
+
turnTasks.length > MAX_HOVER_TASKS ? /* @__PURE__ */ jsxs("span", {
|
|
2553
|
+
style: tasksHoverMore,
|
|
2554
|
+
children: ["+", turnTasks.length - MAX_HOVER_TASKS]
|
|
2555
|
+
}) : null,
|
|
2556
|
+
/* @__PURE__ */ jsx("span", {
|
|
2557
|
+
style: tasksHoverHint,
|
|
2558
|
+
children: t("tasksOpen")
|
|
2559
|
+
})
|
|
2560
|
+
]
|
|
2561
|
+
}) : null, /* @__PURE__ */ jsxs("button", {
|
|
2562
|
+
type: "button",
|
|
2563
|
+
className: "dsh-claude-task-launcher",
|
|
2564
|
+
style: {
|
|
2565
|
+
...tasksTurnBadge,
|
|
2566
|
+
...stateStyle,
|
|
2567
|
+
...hovered ? tasksBadgeHovered : {}
|
|
2568
|
+
},
|
|
2569
|
+
"aria-label": `${label} — ${t("tasksOpen")}`,
|
|
2570
|
+
onClick: () => openTasks(turn),
|
|
2571
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
1699
2572
|
className: summary.state === "running" ? "dsh-claude-act-running" : void 0,
|
|
1700
2573
|
style: {
|
|
1701
|
-
...
|
|
1702
|
-
...
|
|
1703
|
-
...summary.state === "completed" ? tasksTurnLauncherDone : {}
|
|
2574
|
+
...tasksBadgeDot,
|
|
2575
|
+
...dotStyle
|
|
1704
2576
|
},
|
|
1705
|
-
"aria-hidden": "true"
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
children: "›"
|
|
1712
|
-
})
|
|
1713
|
-
]
|
|
2577
|
+
"aria-hidden": "true"
|
|
2578
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
2579
|
+
style: tasksBadgeCount,
|
|
2580
|
+
children: turnTasks.length
|
|
2581
|
+
})]
|
|
2582
|
+
})]
|
|
1714
2583
|
})
|
|
1715
2584
|
});
|
|
1716
2585
|
}
|
|
@@ -1737,10 +2606,461 @@ window.__ModuleLoader__.load({
|
|
|
1737
2606
|
});
|
|
1738
2607
|
}
|
|
1739
2608
|
//#endregion
|
|
2609
|
+
//#region src/client/projection.ts
|
|
2610
|
+
const EMPTY_CLAUDE_PROJECTION = {
|
|
2611
|
+
schemaVersion: 1,
|
|
2612
|
+
revision: 0,
|
|
2613
|
+
owned: false,
|
|
2614
|
+
commands: [],
|
|
2615
|
+
activities: []
|
|
2616
|
+
};
|
|
2617
|
+
const RETRY_DELAY_MS = 2e3;
|
|
2618
|
+
/** Coalesce stream deltas into at most one React notification per frame. */
|
|
2619
|
+
const FRAME_MS = 16;
|
|
2620
|
+
/** Typewriter smoothing: drain newly arrived prose over roughly this window,
|
|
2621
|
+
* so the CLI's paragraph-sized deltas read as a continuous character flow. */
|
|
2622
|
+
const REVEAL_WINDOW_MS = 1200;
|
|
2623
|
+
/** A burst larger than this (redaction rewrite, reconnect catch-up) shows
|
|
2624
|
+
* instantly instead of animating for a long stretch. */
|
|
2625
|
+
const MAX_INSTANT_REVEAL = 4e3;
|
|
2626
|
+
const MAX_ACTIVITIES = 1e4;
|
|
2627
|
+
const MAX_COMMANDS = 2e3;
|
|
2628
|
+
const MAX_REPOSITORY_TEXT_CHARS = 1024;
|
|
2629
|
+
const MAX_DIFF_CHARS = 262144;
|
|
2630
|
+
const MAX_REVIEW_COMMENTS = 50;
|
|
2631
|
+
const MAX_REVIEW_COMMENT_CHARS = 2e3;
|
|
2632
|
+
const MAX_TRANSCRIPT_CHARS = 64e3;
|
|
2633
|
+
function record$4(value) {
|
|
2634
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
2635
|
+
}
|
|
2636
|
+
function nonNegativeInteger(value) {
|
|
2637
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
2638
|
+
}
|
|
2639
|
+
function optionalBoundedString(value) {
|
|
2640
|
+
return value === void 0 || typeof value === "string" && value.length <= MAX_REPOSITORY_TEXT_CHARS;
|
|
2641
|
+
}
|
|
2642
|
+
function validateRepository(value) {
|
|
2643
|
+
const repository = record$4(value);
|
|
2644
|
+
if (repository === void 0 || ![
|
|
2645
|
+
"ready",
|
|
2646
|
+
"not-repository",
|
|
2647
|
+
"unavailable"
|
|
2648
|
+
].includes(String(repository.status)) || typeof repository.cwd !== "string" || repository.cwd.length > MAX_REPOSITORY_TEXT_CHARS || !optionalBoundedString(repository.root) || !optionalBoundedString(repository.branch) || !optionalBoundedString(repository.remote) || repository.detached !== void 0 && typeof repository.detached !== "boolean" || repository.worktree !== void 0 && typeof repository.worktree !== "boolean" || repository.dirty !== void 0 && typeof repository.dirty !== "boolean" || repository.upstream !== void 0 && typeof repository.upstream !== "boolean" || repository.ahead !== void 0 && !nonNegativeInteger(repository.ahead) || repository.behind !== void 0 && !nonNegativeInteger(repository.behind)) return false;
|
|
2649
|
+
if (repository.diff !== void 0) {
|
|
2650
|
+
const diff = record$4(repository.diff);
|
|
2651
|
+
if (diff === void 0 || !nonNegativeInteger(diff.additions) || !nonNegativeInteger(diff.deletions) || !nonNegativeInteger(diff.files) || typeof diff.truncated !== "boolean" || diff.patch !== void 0 && (typeof diff.patch !== "string" || diff.patch.length > MAX_DIFF_CHARS)) return false;
|
|
2652
|
+
}
|
|
2653
|
+
if (repository.pullRequest === void 0) return true;
|
|
2654
|
+
const pullRequest = record$4(repository.pullRequest);
|
|
2655
|
+
if (pullRequest === void 0 || !Number.isSafeInteger(pullRequest.number) || Number(pullRequest.number) <= 0 || typeof pullRequest.title !== "string" || pullRequest.title.length > MAX_REPOSITORY_TEXT_CHARS || typeof pullRequest.url !== "string" || pullRequest.url.length > MAX_REPOSITORY_TEXT_CHARS || ![
|
|
2656
|
+
"open",
|
|
2657
|
+
"closed",
|
|
2658
|
+
"merged"
|
|
2659
|
+
].includes(String(pullRequest.state)) || typeof pullRequest.draft !== "boolean" || ![
|
|
2660
|
+
"approved",
|
|
2661
|
+
"changes-requested",
|
|
2662
|
+
"review-required",
|
|
2663
|
+
"none"
|
|
2664
|
+
].includes(String(pullRequest.review)) || ![
|
|
2665
|
+
"passing",
|
|
2666
|
+
"pending",
|
|
2667
|
+
"failing",
|
|
2668
|
+
"none"
|
|
2669
|
+
].includes(String(pullRequest.checks)) || !optionalBoundedString(pullRequest.mergeState) || !optionalBoundedString(pullRequest.author) || !optionalBoundedString(pullRequest.baseBranch) || pullRequest.createdAt !== void 0 && (typeof pullRequest.createdAt !== "string" || !Number.isFinite(Date.parse(pullRequest.createdAt))) || pullRequest.mergedAt !== void 0 && (typeof pullRequest.mergedAt !== "string" || !Number.isFinite(Date.parse(pullRequest.mergedAt)))) return false;
|
|
2670
|
+
try {
|
|
2671
|
+
const url = new URL(pullRequest.url);
|
|
2672
|
+
return url.protocol === "https:" && url.hostname === "github.com";
|
|
2673
|
+
} catch {
|
|
2674
|
+
return false;
|
|
2675
|
+
}
|
|
2676
|
+
}
|
|
2677
|
+
/** Validate the public route envelope before publishing it to UI components. */
|
|
2678
|
+
function parseClaudeClientProjection(value) {
|
|
2679
|
+
const input = record$4(value);
|
|
2680
|
+
if (input === void 0 || input.schemaVersion !== 1 || !nonNegativeInteger(input.revision) || typeof input.owned !== "boolean" || !Array.isArray(input.commands) || input.commands.length > MAX_COMMANDS || !Array.isArray(input.activities) || input.activities.length > MAX_ACTIVITIES) throw new Error("invalid Claude sidecar projection");
|
|
2681
|
+
for (const item of input.commands) {
|
|
2682
|
+
const command = record$4(item);
|
|
2683
|
+
if (command === void 0 || typeof command.publicName !== "string" || typeof command.claudeName !== "string" || typeof command.description !== "string" || command.hint !== void 0 && typeof command.hint !== "string" || typeof command.prefixed !== "boolean") throw new Error("invalid Claude command projection");
|
|
2684
|
+
}
|
|
2685
|
+
for (const item of input.activities) {
|
|
2686
|
+
const activity = record$4(item);
|
|
2687
|
+
if (activity === void 0 || !nonNegativeInteger(activity.turn) || !nonNegativeInteger(activity.step) || !nonNegativeInteger(activity.ordinal) || typeof activity.kind !== "string") throw new Error("invalid Claude sidecar activity");
|
|
2688
|
+
}
|
|
2689
|
+
if (input.contextUsage !== void 0 && record$4(input.contextUsage) === void 0) throw new Error("invalid Claude context projection");
|
|
2690
|
+
const tasks = input.tasks === void 0 ? void 0 : record$4(input.tasks);
|
|
2691
|
+
if (tasks !== void 0 && !Array.isArray(tasks.tasks)) throw new Error("invalid Claude tasks projection");
|
|
2692
|
+
if (input.repository !== void 0 && !validateRepository(input.repository)) throw new Error("invalid Claude repository projection");
|
|
2693
|
+
if (input.reviewComments !== void 0) {
|
|
2694
|
+
if (!Array.isArray(input.reviewComments) || input.reviewComments.length > MAX_REVIEW_COMMENTS) throw new Error("invalid Claude review comment projection");
|
|
2695
|
+
for (const item of input.reviewComments) {
|
|
2696
|
+
const comment = record$4(item);
|
|
2697
|
+
if (comment === void 0 || typeof comment.id !== "string" || comment.id.length === 0 || comment.id.length > 128 || typeof comment.path !== "string" || comment.path.length === 0 || comment.path.length > MAX_REPOSITORY_TEXT_CHARS || !nonNegativeInteger(comment.line) || comment.side !== "old" && comment.side !== "new" || typeof comment.text !== "string" || comment.text.length > MAX_REVIEW_COMMENT_CHARS) throw new Error("invalid Claude review comment projection");
|
|
2698
|
+
}
|
|
2699
|
+
}
|
|
2700
|
+
return input;
|
|
2701
|
+
}
|
|
2702
|
+
/** Validate one incremental delta payload with the same rules as a snapshot. */
|
|
2703
|
+
function validateEnvelopeFragment(fragment) {
|
|
2704
|
+
parseClaudeClientProjection({
|
|
2705
|
+
schemaVersion: 1,
|
|
2706
|
+
revision: 0,
|
|
2707
|
+
owned: false,
|
|
2708
|
+
commands: [],
|
|
2709
|
+
activities: [],
|
|
2710
|
+
...fragment
|
|
2711
|
+
});
|
|
2712
|
+
}
|
|
2713
|
+
function stepKeyOf(turn, step) {
|
|
2714
|
+
return `${turn}:${step}`;
|
|
2715
|
+
}
|
|
2716
|
+
const EMPTY_ACTIVITIES = [];
|
|
2717
|
+
/** Identity-stable per-step slice; untouched steps never re-render while
|
|
2718
|
+
* another step streams. Falls back to filtering for snapshot-only hooks. */
|
|
2719
|
+
function selectStepActivities(value, turn, step) {
|
|
2720
|
+
const sliced = value.byStep?.get(stepKeyOf(turn, step));
|
|
2721
|
+
if (sliced !== void 0) return sliced;
|
|
2722
|
+
const filtered = value.activities.filter((activity) => activity.turn === turn && activity.step === step);
|
|
2723
|
+
return filtered.length === 0 ? EMPTY_ACTIVITIES : filtered;
|
|
2724
|
+
}
|
|
2725
|
+
function isAbort(error) {
|
|
2726
|
+
return error?.name === "AbortError";
|
|
2727
|
+
}
|
|
2728
|
+
function delay(ms) {
|
|
2729
|
+
return new Promise((resolve) => {
|
|
2730
|
+
setTimeout(resolve, ms).unref?.();
|
|
2731
|
+
});
|
|
2732
|
+
}
|
|
2733
|
+
/** Create one lazy source: active subscribers open the Host NDJSON stream, and
|
|
2734
|
+
* a dropped stream reconnects with a fresh snapshot after a bounded delay. */
|
|
2735
|
+
function createClaudeProjectionSource(sessionId, fetchProjection = fetch, retryDelayMs = RETRY_DELAY_MS) {
|
|
2736
|
+
let snapshot = EMPTY_CLAUDE_PROJECTION;
|
|
2737
|
+
let revision = 0;
|
|
2738
|
+
let owned = false;
|
|
2739
|
+
let commands = [];
|
|
2740
|
+
let contextUsage;
|
|
2741
|
+
let tasks;
|
|
2742
|
+
let repository;
|
|
2743
|
+
let reviewComments;
|
|
2744
|
+
const byStep = /* @__PURE__ */ new Map();
|
|
2745
|
+
const stepOrder = [];
|
|
2746
|
+
/** Streaming prose still being revealed: full arrived text plus shown chars. */
|
|
2747
|
+
const reveal = /* @__PURE__ */ new Map();
|
|
2748
|
+
let disposed = false;
|
|
2749
|
+
let running = false;
|
|
2750
|
+
let controller;
|
|
2751
|
+
let frame;
|
|
2752
|
+
let usedAnimationFrame = false;
|
|
2753
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
2754
|
+
const ensureStep = (turn, step) => {
|
|
2755
|
+
const key = stepKeyOf(turn, step);
|
|
2756
|
+
const existing = byStep.get(key);
|
|
2757
|
+
if (existing !== void 0) return existing;
|
|
2758
|
+
const created = [];
|
|
2759
|
+
byStep.set(key, created);
|
|
2760
|
+
const at = stepOrder.findIndex((entry) => entry.turn > turn || entry.turn === turn && entry.step > step);
|
|
2761
|
+
stepOrder.splice(at === -1 ? stepOrder.length : at, 0, {
|
|
2762
|
+
turn,
|
|
2763
|
+
step,
|
|
2764
|
+
key
|
|
2765
|
+
});
|
|
2766
|
+
return created;
|
|
2767
|
+
};
|
|
2768
|
+
const upsertActivity = (activity) => {
|
|
2769
|
+
const key = stepKeyOf(activity.turn, activity.step);
|
|
2770
|
+
const next = ensureStep(activity.turn, activity.step).slice();
|
|
2771
|
+
const index = next.findIndex((item) => item.ordinal === activity.ordinal);
|
|
2772
|
+
if (index === -1) {
|
|
2773
|
+
const at = next.findIndex((item) => item.ordinal > activity.ordinal);
|
|
2774
|
+
next.splice(at === -1 ? next.length : at, 0, activity);
|
|
2775
|
+
} else next[index] = activity;
|
|
2776
|
+
byStep.set(key, next);
|
|
2777
|
+
};
|
|
2778
|
+
const reset = (activities) => {
|
|
2779
|
+
byStep.clear();
|
|
2780
|
+
stepOrder.length = 0;
|
|
2781
|
+
reveal.clear();
|
|
2782
|
+
for (const activity of activities) ensureStep(activity.turn, activity.step).push(activity);
|
|
2783
|
+
};
|
|
2784
|
+
/** Advance every pending typewriter reveal by one frame's worth of characters.
|
|
2785
|
+
* The per-frame step scales with the backlog so any burst drains in roughly
|
|
2786
|
+
* REVEAL_WINDOW_MS. Returns whether another frame is still needed. */
|
|
2787
|
+
const advanceReveals = () => {
|
|
2788
|
+
let remaining = false;
|
|
2789
|
+
for (const [key, entry] of reveal) {
|
|
2790
|
+
const total = entry.full.text?.length ?? 0;
|
|
2791
|
+
if (entry.shown >= total) {
|
|
2792
|
+
reveal.delete(key);
|
|
2793
|
+
continue;
|
|
2794
|
+
}
|
|
2795
|
+
const step = Math.max(1, Math.ceil((total - entry.shown) * FRAME_MS / REVEAL_WINDOW_MS));
|
|
2796
|
+
entry.shown = Math.min(total, entry.shown + step);
|
|
2797
|
+
upsertActivity({
|
|
2798
|
+
...entry.full,
|
|
2799
|
+
text: (entry.full.text ?? "").slice(0, entry.shown)
|
|
2800
|
+
});
|
|
2801
|
+
if (entry.shown >= total) reveal.delete(key);
|
|
2802
|
+
else remaining = true;
|
|
2803
|
+
}
|
|
2804
|
+
return remaining;
|
|
2805
|
+
};
|
|
2806
|
+
const publish = () => {
|
|
2807
|
+
frame = void 0;
|
|
2808
|
+
if (disposed) return;
|
|
2809
|
+
const revealing = advanceReveals();
|
|
2810
|
+
const activities = [];
|
|
2811
|
+
for (const entry of stepOrder) {
|
|
2812
|
+
const slice = byStep.get(entry.key);
|
|
2813
|
+
if (slice !== void 0) for (const item of slice) activities.push(item);
|
|
2814
|
+
}
|
|
2815
|
+
snapshot = {
|
|
2816
|
+
schemaVersion: 1,
|
|
2817
|
+
revision,
|
|
2818
|
+
owned,
|
|
2819
|
+
commands,
|
|
2820
|
+
activities,
|
|
2821
|
+
...contextUsage === void 0 ? {} : { contextUsage },
|
|
2822
|
+
...tasks === void 0 ? {} : { tasks },
|
|
2823
|
+
...repository === void 0 ? {} : { repository },
|
|
2824
|
+
...reviewComments === void 0 ? {} : { reviewComments },
|
|
2825
|
+
byStep: new Map(byStep)
|
|
2826
|
+
};
|
|
2827
|
+
for (const listener of [...listeners]) listener();
|
|
2828
|
+
if (revealing) schedulePublish();
|
|
2829
|
+
};
|
|
2830
|
+
const cancelFrame = () => {
|
|
2831
|
+
if (frame === void 0) return;
|
|
2832
|
+
if (usedAnimationFrame) globalThis.cancelAnimationFrame?.(frame);
|
|
2833
|
+
else clearTimeout(frame);
|
|
2834
|
+
frame = void 0;
|
|
2835
|
+
};
|
|
2836
|
+
const schedulePublish = () => {
|
|
2837
|
+
if (disposed || frame !== void 0 || listeners.size === 0) return;
|
|
2838
|
+
const raf = globalThis.requestAnimationFrame;
|
|
2839
|
+
if (typeof raf === "function") {
|
|
2840
|
+
usedAnimationFrame = true;
|
|
2841
|
+
frame = raf(publish);
|
|
2842
|
+
} else {
|
|
2843
|
+
usedAnimationFrame = false;
|
|
2844
|
+
frame = setTimeout(publish, FRAME_MS);
|
|
2845
|
+
}
|
|
2846
|
+
};
|
|
2847
|
+
const applyText = (event) => {
|
|
2848
|
+
const { turn, step, ordinal, append, text } = event;
|
|
2849
|
+
if (!nonNegativeInteger(turn) || !nonNegativeInteger(step) || !nonNegativeInteger(ordinal)) return false;
|
|
2850
|
+
if (append !== void 0 && (typeof append !== "string" || append.length > MAX_TRANSCRIPT_CHARS)) return false;
|
|
2851
|
+
if (text !== void 0 && (typeof text !== "string" || text.length > MAX_TRANSCRIPT_CHARS)) return false;
|
|
2852
|
+
if (append === void 0 && text === void 0) return false;
|
|
2853
|
+
const revealKey = `${turn}:${step}:${ordinal}`;
|
|
2854
|
+
const existing = byStep.get(stepKeyOf(turn, step))?.find((item) => item.ordinal === ordinal);
|
|
2855
|
+
const pending = reveal.get(revealKey);
|
|
2856
|
+
if (existing === void 0 && pending === void 0 && typeof text !== "string") return false;
|
|
2857
|
+
const baseText = pending?.full.text ?? existing?.text ?? "";
|
|
2858
|
+
const fullText = (typeof text === "string" ? text : `${baseText}${append}`).slice(0, MAX_TRANSCRIPT_CHARS);
|
|
2859
|
+
const full = {
|
|
2860
|
+
...pending?.full ?? existing ?? {
|
|
2861
|
+
turn,
|
|
2862
|
+
step,
|
|
2863
|
+
ordinal,
|
|
2864
|
+
kind: "text",
|
|
2865
|
+
phase: "updated"
|
|
2866
|
+
},
|
|
2867
|
+
text: fullText
|
|
2868
|
+
};
|
|
2869
|
+
const shown = Math.min(pending?.shown ?? existing?.text?.length ?? 0, fullText.length);
|
|
2870
|
+
if (fullText.length - shown > MAX_INSTANT_REVEAL) {
|
|
2871
|
+
reveal.delete(revealKey);
|
|
2872
|
+
upsertActivity(full);
|
|
2873
|
+
return true;
|
|
2874
|
+
}
|
|
2875
|
+
reveal.set(revealKey, {
|
|
2876
|
+
full,
|
|
2877
|
+
shown
|
|
2878
|
+
});
|
|
2879
|
+
upsertActivity({
|
|
2880
|
+
...full,
|
|
2881
|
+
text: fullText.slice(0, shown)
|
|
2882
|
+
});
|
|
2883
|
+
return true;
|
|
2884
|
+
};
|
|
2885
|
+
const applyLine = (line) => {
|
|
2886
|
+
const trimmed = line.trim();
|
|
2887
|
+
if (trimmed.length === 0) return;
|
|
2888
|
+
let value;
|
|
2889
|
+
try {
|
|
2890
|
+
value = JSON.parse(trimmed);
|
|
2891
|
+
} catch {
|
|
2892
|
+
return;
|
|
2893
|
+
}
|
|
2894
|
+
const event = record$4(value);
|
|
2895
|
+
if (event === void 0 || typeof event.type !== "string") return;
|
|
2896
|
+
try {
|
|
2897
|
+
switch (event.type) {
|
|
2898
|
+
case "snapshot": {
|
|
2899
|
+
const next = parseClaudeClientProjection(event);
|
|
2900
|
+
revision = next.revision;
|
|
2901
|
+
owned = next.owned;
|
|
2902
|
+
commands = next.commands;
|
|
2903
|
+
contextUsage = next.contextUsage;
|
|
2904
|
+
tasks = next.tasks;
|
|
2905
|
+
repository = next.repository;
|
|
2906
|
+
reviewComments = next.reviewComments;
|
|
2907
|
+
reset(next.activities);
|
|
2908
|
+
break;
|
|
2909
|
+
}
|
|
2910
|
+
case "text":
|
|
2911
|
+
if (!applyText(event)) return;
|
|
2912
|
+
revision += 1;
|
|
2913
|
+
break;
|
|
2914
|
+
case "activity":
|
|
2915
|
+
validateEnvelopeFragment({ activities: [event.activity] });
|
|
2916
|
+
upsertActivity(event.activity);
|
|
2917
|
+
revision += 1;
|
|
2918
|
+
break;
|
|
2919
|
+
case "contextUsage":
|
|
2920
|
+
validateEnvelopeFragment({ contextUsage: event.value });
|
|
2921
|
+
contextUsage = event.value;
|
|
2922
|
+
revision += 1;
|
|
2923
|
+
break;
|
|
2924
|
+
case "tasks":
|
|
2925
|
+
validateEnvelopeFragment({ tasks: event.value });
|
|
2926
|
+
tasks = event.value;
|
|
2927
|
+
revision += 1;
|
|
2928
|
+
break;
|
|
2929
|
+
case "meta":
|
|
2930
|
+
validateEnvelopeFragment({
|
|
2931
|
+
owned: event.owned,
|
|
2932
|
+
commands: event.commands,
|
|
2933
|
+
...event.repository === void 0 ? {} : { repository: event.repository },
|
|
2934
|
+
...event.reviewComments === void 0 ? {} : { reviewComments: event.reviewComments }
|
|
2935
|
+
});
|
|
2936
|
+
owned = event.owned;
|
|
2937
|
+
commands = event.commands;
|
|
2938
|
+
repository = event.repository;
|
|
2939
|
+
reviewComments = event.reviewComments;
|
|
2940
|
+
revision += 1;
|
|
2941
|
+
break;
|
|
2942
|
+
default: return;
|
|
2943
|
+
}
|
|
2944
|
+
} catch {
|
|
2945
|
+
return;
|
|
2946
|
+
}
|
|
2947
|
+
schedulePublish();
|
|
2948
|
+
};
|
|
2949
|
+
const run = async () => {
|
|
2950
|
+
if (running) return;
|
|
2951
|
+
running = true;
|
|
2952
|
+
try {
|
|
2953
|
+
while (!disposed && listeners.size > 0) {
|
|
2954
|
+
controller = new AbortController();
|
|
2955
|
+
try {
|
|
2956
|
+
const response = await fetchProjection(`${CLAUDE_PROJECTION_PATH}/${encodeURIComponent(sessionId)}/stream`, {
|
|
2957
|
+
headers: { accept: "application/x-ndjson" },
|
|
2958
|
+
signal: controller.signal
|
|
2959
|
+
});
|
|
2960
|
+
if (!response.ok) throw new Error(`Claude projection stream failed (${response.status})`);
|
|
2961
|
+
if (response.body === null) throw new Error("Claude projection stream is unavailable");
|
|
2962
|
+
const reader = response.body.getReader();
|
|
2963
|
+
const decoder = new TextDecoder();
|
|
2964
|
+
let buffer = "";
|
|
2965
|
+
while (true) {
|
|
2966
|
+
if (disposed || listeners.size === 0) {
|
|
2967
|
+
await reader.cancel().catch(() => void 0);
|
|
2968
|
+
break;
|
|
2969
|
+
}
|
|
2970
|
+
const chunk = await reader.read();
|
|
2971
|
+
buffer += decoder.decode(chunk.value, { stream: !chunk.done });
|
|
2972
|
+
const lines = buffer.split("\n");
|
|
2973
|
+
buffer = lines.pop() ?? "";
|
|
2974
|
+
for (const line of lines) applyLine(line);
|
|
2975
|
+
if (chunk.done) break;
|
|
2976
|
+
}
|
|
2977
|
+
} catch (error) {
|
|
2978
|
+
if (isAbort(error)) return;
|
|
2979
|
+
} finally {
|
|
2980
|
+
controller = void 0;
|
|
2981
|
+
}
|
|
2982
|
+
if (disposed || listeners.size === 0) return;
|
|
2983
|
+
await delay(retryDelayMs);
|
|
2984
|
+
}
|
|
2985
|
+
} finally {
|
|
2986
|
+
running = false;
|
|
2987
|
+
}
|
|
2988
|
+
};
|
|
2989
|
+
return {
|
|
2990
|
+
getSnapshot: () => snapshot,
|
|
2991
|
+
subscribe(listener) {
|
|
2992
|
+
if (disposed) return () => {};
|
|
2993
|
+
const wasIdle = listeners.size === 0;
|
|
2994
|
+
listeners.add(listener);
|
|
2995
|
+
if (wasIdle) run();
|
|
2996
|
+
return () => {
|
|
2997
|
+
listeners.delete(listener);
|
|
2998
|
+
if (listeners.size !== 0) return;
|
|
2999
|
+
controller?.abort();
|
|
3000
|
+
controller = void 0;
|
|
3001
|
+
cancelFrame();
|
|
3002
|
+
};
|
|
3003
|
+
},
|
|
3004
|
+
dispose() {
|
|
3005
|
+
disposed = true;
|
|
3006
|
+
listeners.clear();
|
|
3007
|
+
controller?.abort();
|
|
3008
|
+
controller = void 0;
|
|
3009
|
+
cancelFrame();
|
|
3010
|
+
}
|
|
3011
|
+
};
|
|
3012
|
+
}
|
|
3013
|
+
var ClaudeProjectionStore = class {
|
|
3014
|
+
#sources = /* @__PURE__ */ new Map();
|
|
3015
|
+
source(sessionId) {
|
|
3016
|
+
let source = this.#sources.get(sessionId);
|
|
3017
|
+
if (source === void 0) {
|
|
3018
|
+
source = createClaudeProjectionSource(sessionId);
|
|
3019
|
+
this.#sources.set(sessionId, source);
|
|
3020
|
+
}
|
|
3021
|
+
return source;
|
|
3022
|
+
}
|
|
3023
|
+
dispose() {
|
|
3024
|
+
for (const source of this.#sources.values()) source.dispose();
|
|
3025
|
+
this.#sources.clear();
|
|
3026
|
+
}
|
|
3027
|
+
};
|
|
3028
|
+
//#endregion
|
|
1740
3029
|
//#region src/client/ClaudeActivityNode.tsx
|
|
1741
3030
|
const EMPTY_TASKS = [];
|
|
1742
3031
|
const ACTIVITY_CSS = [
|
|
1743
|
-
".dsh-claude-flow{display:flex;flex-direction:column;gap:
|
|
3032
|
+
".dsh-claude-flow{display:flex;flex-direction:column;gap:10px}",
|
|
3033
|
+
".dsh-claude-transcript-text{color:var(--dsw-alias-label-primary);font-size:15px;line-height:24px;overflow-wrap:anywhere}",
|
|
3034
|
+
".dsh-claude-tool-group-native{overflow:visible}",
|
|
3035
|
+
".dsh-claude-tool-group-native>.dsh-claude-flow-row{padding:0}",
|
|
3036
|
+
".dsh-claude-tool-list{max-height:min(420px,calc(100vh - 320px));overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;margin-top:4px;border:1px solid var(--dsw-alias-border-l1);border-radius:10px;scrollbar-gutter:stable}",
|
|
3037
|
+
".dsh-claude-tool-item{border-top:1px solid var(--dsw-alias-border-l1)}",
|
|
3038
|
+
".dsh-claude-tool-item:first-child{border-top:0}",
|
|
3039
|
+
".dsh-claude-tool-summary-row{display:flex;align-items:center;min-height:34px;gap:8px;padding:0 10px;cursor:pointer;list-style:none}",
|
|
3040
|
+
".dsh-claude-tool-summary-row::-webkit-details-marker{display:none}",
|
|
3041
|
+
".dsh-claude-tool-summary-row::after{content:\"›\";margin-left:2px;flex:none;align-self:center;color:var(--dsw-alias-label-secondary);font-size:22px;line-height:1;transform-origin:center;transition:transform .15s ease}",
|
|
3042
|
+
".dsh-claude-tool-item[open]>.dsh-claude-tool-summary-row::after{transform:rotate(90deg)}",
|
|
3043
|
+
".dsh-claude-tool-content{min-width:0;padding:0 10px 8px}",
|
|
3044
|
+
".dsh-claude-tool-content>*{max-width:100%;box-sizing:border-box}",
|
|
3045
|
+
".dsh-claude-tool-section{margin-top:8px}",
|
|
3046
|
+
".dsh-claude-tool-section-title{margin-bottom:4px;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;text-transform:uppercase;letter-spacing:.04em}",
|
|
3047
|
+
".dsh-claude-tool-fields{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:3px 12px;font-size:13px;line-height:20px}",
|
|
3048
|
+
".dsh-claude-tool-field-key{color:var(--dsw-alias-label-tertiary)}",
|
|
3049
|
+
".dsh-claude-tool-field-value{min-width:0;color:var(--dsw-alias-label-primary);white-space:pre-wrap;overflow-wrap:anywhere}",
|
|
3050
|
+
".dsh-claude-tool-paths{display:flex;flex-direction:column;gap:2px;margin:0;padding:0;list-style:none;font:var(--dsw-font-markdown-code-block-small)}",
|
|
3051
|
+
".dsh-claude-tool-path{overflow-wrap:anywhere;color:var(--dsw-alias-label-primary)}",
|
|
3052
|
+
".dsh-claude-tool-code{max-height:260px;overflow:auto;margin:0;padding:8px 0;border-radius:8px;background:var(--dsw-alias-markdown-code-block);font:var(--dsw-font-markdown-code-block-small)}",
|
|
3053
|
+
".dsh-claude-tool-code-line{display:grid;grid-template-columns:44px minmax(max-content,1fr);min-height:18px}",
|
|
3054
|
+
".dsh-claude-tool-line-number{padding-right:10px;text-align:right;user-select:none;color:var(--dsw-alias-label-caption);border-right:1px solid var(--dsw-alias-border-l1)}",
|
|
3055
|
+
".dsh-claude-tool-line-text{padding:0 10px;white-space:pre}",
|
|
3056
|
+
".dsh-claude-tool-label{width:72px;flex:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;line-height:20px;color:var(--dsw-alias-label-tertiary)}",
|
|
3057
|
+
".dsh-claude-tool-description{min-width:0;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:14px;line-height:20px;color:var(--dsw-alias-label-primary)}",
|
|
3058
|
+
".dsh-claude-tool-stats{display:inline-flex;gap:4px;flex:none;font-size:13px;line-height:20px}",
|
|
3059
|
+
".dsh-claude-diff-add{color:var(--dsw-alias-state-success-primary,#21c55d)}",
|
|
3060
|
+
".dsh-claude-diff-delete{color:var(--dsw-alias-state-error-primary)}",
|
|
3061
|
+
".dsh-claude-tool-name{font-size:14px;line-height:22px;color:var(--dsw-alias-label-primary)}",
|
|
3062
|
+
".dsh-claude-tool-summary{margin-left:8px;color:var(--dsw-alias-label-tertiary)}",
|
|
3063
|
+
".dsh-claude-tool-detail{margin:6px 0 0;padding:8px 10px;max-height:220px;overflow:auto;border-radius:8px;background:var(--dsw-alias-markdown-code-block);font:var(--dsw-font-markdown-code-block-small);white-space:pre-wrap;overflow-wrap:anywhere}",
|
|
1744
3064
|
".dsh-claude-flow-row{position:relative;overflow:hidden}",
|
|
1745
3065
|
".dsh-claude-flow-leading{flex-shrink:0}",
|
|
1746
3066
|
".dsh-claude-flow-title{font-weight:400}",
|
|
@@ -1797,7 +3117,7 @@ window.__ModuleLoader__.load({
|
|
|
1797
3117
|
expandOnRowClick: true,
|
|
1798
3118
|
keepContentWhenOpen: true,
|
|
1799
3119
|
onToggle: () => setOpen((value) => !value),
|
|
1800
|
-
collapsedContent: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
3120
|
+
collapsedContent: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
|
|
1801
3121
|
className: "dsh-claude-flow-separator",
|
|
1802
3122
|
"aria-hidden": "true"
|
|
1803
3123
|
}), /* @__PURE__ */ jsx("span", {
|
|
@@ -1822,24 +3142,292 @@ window.__ModuleLoader__.load({
|
|
|
1822
3142
|
})]
|
|
1823
3143
|
});
|
|
1824
3144
|
}
|
|
3145
|
+
function parsedValue(value) {
|
|
3146
|
+
if (value === void 0 || value.length === 0) return void 0;
|
|
3147
|
+
try {
|
|
3148
|
+
return JSON.parse(value);
|
|
3149
|
+
} catch {
|
|
3150
|
+
return value;
|
|
3151
|
+
}
|
|
3152
|
+
}
|
|
3153
|
+
function record$3(value) {
|
|
3154
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
3155
|
+
}
|
|
3156
|
+
function text(value) {
|
|
3157
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
3158
|
+
}
|
|
3159
|
+
function numberValue(value) {
|
|
3160
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
3161
|
+
}
|
|
3162
|
+
function displayValue(value) {
|
|
3163
|
+
if (value === null) return "null";
|
|
3164
|
+
if (typeof value === "string") return value;
|
|
3165
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
3166
|
+
if (Array.isArray(value)) return value.map(displayValue).join(", ");
|
|
3167
|
+
return record$3(value) === void 0 ? String(value) : Object.entries(value).map(([key, item]) => `${key}: ${displayValue(item)}`).join("\n");
|
|
3168
|
+
}
|
|
3169
|
+
function Section({ title, children }) {
|
|
3170
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
3171
|
+
className: "dsh-claude-tool-section",
|
|
3172
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
3173
|
+
className: "dsh-claude-tool-section-title",
|
|
3174
|
+
children: title
|
|
3175
|
+
}), children]
|
|
3176
|
+
});
|
|
3177
|
+
}
|
|
3178
|
+
function Fields({ value, omit = [] }) {
|
|
3179
|
+
const entries = Object.entries(value).filter(([key, item]) => !omit.includes(key) && item !== void 0 && item !== "");
|
|
3180
|
+
if (entries.length === 0) return null;
|
|
3181
|
+
return /* @__PURE__ */ jsx("div", {
|
|
3182
|
+
className: "dsh-claude-tool-fields",
|
|
3183
|
+
children: entries.map(([key, item]) => /* @__PURE__ */ jsxs("div", {
|
|
3184
|
+
style: { display: "contents" },
|
|
3185
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
3186
|
+
className: "dsh-claude-tool-field-key",
|
|
3187
|
+
children: key.replaceAll("_", " ")
|
|
3188
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
3189
|
+
className: "dsh-claude-tool-field-value",
|
|
3190
|
+
children: displayValue(item)
|
|
3191
|
+
})]
|
|
3192
|
+
}, key))
|
|
3193
|
+
});
|
|
3194
|
+
}
|
|
3195
|
+
function Paths({ paths }) {
|
|
3196
|
+
if (paths.length === 0) return null;
|
|
3197
|
+
return /* @__PURE__ */ jsx("ul", {
|
|
3198
|
+
className: "dsh-claude-tool-paths",
|
|
3199
|
+
children: paths.map((path, index) => /* @__PURE__ */ jsx("li", {
|
|
3200
|
+
className: "dsh-claude-tool-path",
|
|
3201
|
+
children: path
|
|
3202
|
+
}, `${path}:${index}`))
|
|
3203
|
+
});
|
|
3204
|
+
}
|
|
3205
|
+
function Source({ content, start = 1 }) {
|
|
3206
|
+
return /* @__PURE__ */ jsx("div", {
|
|
3207
|
+
className: "dsh-claude-tool-code",
|
|
3208
|
+
children: content.split(/\r?\n/u).map((line, index) => /* @__PURE__ */ jsxs("div", {
|
|
3209
|
+
className: "dsh-claude-tool-code-line",
|
|
3210
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
3211
|
+
className: "dsh-claude-tool-line-number",
|
|
3212
|
+
children: start + index
|
|
3213
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
3214
|
+
className: "dsh-claude-tool-line-text",
|
|
3215
|
+
children: line || " "
|
|
3216
|
+
})]
|
|
3217
|
+
}, index))
|
|
3218
|
+
});
|
|
3219
|
+
}
|
|
3220
|
+
function TextDetail({ title, value }) {
|
|
3221
|
+
if (value === void 0 || value.length === 0) return null;
|
|
3222
|
+
return /* @__PURE__ */ jsx(Section, {
|
|
3223
|
+
title,
|
|
3224
|
+
children: /* @__PURE__ */ jsx("pre", {
|
|
3225
|
+
className: "dsh-claude-tool-detail",
|
|
3226
|
+
children: value
|
|
3227
|
+
})
|
|
3228
|
+
});
|
|
3229
|
+
}
|
|
3230
|
+
function filenameList(value) {
|
|
3231
|
+
if (!Array.isArray(value)) return [];
|
|
3232
|
+
return value.filter((item) => typeof item === "string");
|
|
3233
|
+
}
|
|
3234
|
+
function ToolPresentation({ tool, t }) {
|
|
3235
|
+
const inputValue = parsedValue(tool.input);
|
|
3236
|
+
const outputValue = parsedValue(tool.output);
|
|
3237
|
+
const input = record$3(inputValue);
|
|
3238
|
+
const output = record$3(outputValue);
|
|
3239
|
+
const outputTitle = tool.isError === true ? t("toolError") : t("toolOutput");
|
|
3240
|
+
if (tool.diffs !== void 0) return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(DiffBlock, { diffs: [...tool.diffs] }), /* @__PURE__ */ jsx(TextDetail, {
|
|
3241
|
+
title: outputTitle,
|
|
3242
|
+
value: typeof outputValue === "string" ? outputValue : void 0
|
|
3243
|
+
})] });
|
|
3244
|
+
if (tool.toolName === "Read") {
|
|
3245
|
+
const file = record$3(output?.file);
|
|
3246
|
+
const path = text(file?.filePath) ?? text(input?.file_path);
|
|
3247
|
+
const content = text(file?.content) ?? (typeof outputValue === "string" ? outputValue : void 0);
|
|
3248
|
+
const offset = numberValue(input?.offset) ?? 1;
|
|
3249
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
3250
|
+
path === void 0 ? null : /* @__PURE__ */ jsx(Section, {
|
|
3251
|
+
title: "File",
|
|
3252
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
3253
|
+
className: "dsh-claude-tool-path",
|
|
3254
|
+
children: path
|
|
3255
|
+
})
|
|
3256
|
+
}),
|
|
3257
|
+
input === void 0 ? null : /* @__PURE__ */ jsx(Section, {
|
|
3258
|
+
title: t("toolInput"),
|
|
3259
|
+
children: /* @__PURE__ */ jsx(Fields, {
|
|
3260
|
+
value: input,
|
|
3261
|
+
omit: ["file_path"]
|
|
3262
|
+
})
|
|
3263
|
+
}),
|
|
3264
|
+
content === void 0 ? null : /* @__PURE__ */ jsx(Section, {
|
|
3265
|
+
title: outputTitle,
|
|
3266
|
+
children: /* @__PURE__ */ jsx(Source, {
|
|
3267
|
+
content,
|
|
3268
|
+
start: offset
|
|
3269
|
+
})
|
|
3270
|
+
})
|
|
3271
|
+
] });
|
|
3272
|
+
}
|
|
3273
|
+
if (tool.toolName === "Grep" || tool.toolName === "Glob") {
|
|
3274
|
+
const filenames = filenameList(output?.filenames);
|
|
3275
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [input === void 0 ? /* @__PURE__ */ jsx(TextDetail, {
|
|
3276
|
+
title: t("toolInput"),
|
|
3277
|
+
value: typeof inputValue === "string" ? inputValue : void 0
|
|
3278
|
+
}) : /* @__PURE__ */ jsx(Section, {
|
|
3279
|
+
title: t("toolInput"),
|
|
3280
|
+
children: /* @__PURE__ */ jsx(Fields, { value: input })
|
|
3281
|
+
}), filenames.length === 0 ? /* @__PURE__ */ jsx(TextDetail, {
|
|
3282
|
+
title: outputTitle,
|
|
3283
|
+
value: typeof outputValue === "string" ? outputValue : output === void 0 ? void 0 : displayValue(output)
|
|
3284
|
+
}) : /* @__PURE__ */ jsx(Section, {
|
|
3285
|
+
title: outputTitle,
|
|
3286
|
+
children: /* @__PURE__ */ jsx(Paths, { paths: filenames })
|
|
3287
|
+
})] });
|
|
3288
|
+
}
|
|
3289
|
+
if (tool.toolName === "Bash" || tool.toolName === "PowerShell") {
|
|
3290
|
+
const command = text(input?.command);
|
|
3291
|
+
const terminal = [text(output?.stdout), text(output?.stderr)].filter((value) => value !== void 0).join("\n");
|
|
3292
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
3293
|
+
/* @__PURE__ */ jsx(TextDetail, {
|
|
3294
|
+
title: "Command",
|
|
3295
|
+
value: command ?? (typeof inputValue === "string" ? inputValue : void 0)
|
|
3296
|
+
}),
|
|
3297
|
+
input === void 0 ? null : /* @__PURE__ */ jsx(Section, {
|
|
3298
|
+
title: t("toolInput"),
|
|
3299
|
+
children: /* @__PURE__ */ jsx(Fields, {
|
|
3300
|
+
value: input,
|
|
3301
|
+
omit: ["command"]
|
|
3302
|
+
})
|
|
3303
|
+
}),
|
|
3304
|
+
/* @__PURE__ */ jsx(TextDetail, {
|
|
3305
|
+
title: outputTitle,
|
|
3306
|
+
value: terminal || (typeof outputValue === "string" ? outputValue : void 0)
|
|
3307
|
+
})
|
|
3308
|
+
] });
|
|
3309
|
+
}
|
|
3310
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [input === void 0 ? /* @__PURE__ */ jsx(TextDetail, {
|
|
3311
|
+
title: t("toolInput"),
|
|
3312
|
+
value: typeof inputValue === "string" ? inputValue : void 0
|
|
3313
|
+
}) : /* @__PURE__ */ jsx(Section, {
|
|
3314
|
+
title: t("toolInput"),
|
|
3315
|
+
children: /* @__PURE__ */ jsx(Fields, { value: input })
|
|
3316
|
+
}), output === void 0 ? /* @__PURE__ */ jsx(TextDetail, {
|
|
3317
|
+
title: outputTitle,
|
|
3318
|
+
value: typeof outputValue === "string" ? outputValue : void 0
|
|
3319
|
+
}) : /* @__PURE__ */ jsx(Section, {
|
|
3320
|
+
title: outputTitle,
|
|
3321
|
+
children: /* @__PURE__ */ jsx(Fields, { value: output })
|
|
3322
|
+
})] });
|
|
3323
|
+
}
|
|
3324
|
+
function ClaudeTranscriptToolItem({ tool, t }) {
|
|
3325
|
+
return /* @__PURE__ */ jsxs("details", {
|
|
3326
|
+
className: "dsh-claude-tool-item",
|
|
3327
|
+
children: [/* @__PURE__ */ jsxs("summary", {
|
|
3328
|
+
className: "dsh-claude-tool-summary-row",
|
|
3329
|
+
children: [
|
|
3330
|
+
/* @__PURE__ */ jsx("span", {
|
|
3331
|
+
className: "dsh-claude-tool-label",
|
|
3332
|
+
children: tool.toolName
|
|
3333
|
+
}),
|
|
3334
|
+
/* @__PURE__ */ jsx("span", {
|
|
3335
|
+
className: "dsh-claude-tool-description",
|
|
3336
|
+
children: tool.description
|
|
3337
|
+
}),
|
|
3338
|
+
tool.additions === void 0 && tool.deletions === void 0 ? null : /* @__PURE__ */ jsxs("span", {
|
|
3339
|
+
className: "dsh-claude-tool-stats",
|
|
3340
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
3341
|
+
className: "dsh-claude-diff-add",
|
|
3342
|
+
children: ["+", tool.additions ?? 0]
|
|
3343
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
3344
|
+
className: "dsh-claude-diff-delete",
|
|
3345
|
+
children: ["−", tool.deletions ?? 0]
|
|
3346
|
+
})]
|
|
3347
|
+
})
|
|
3348
|
+
]
|
|
3349
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
3350
|
+
className: "dsh-claude-tool-content",
|
|
3351
|
+
children: [tool.subcalls.length === 0 ? null : /* @__PURE__ */ jsx("div", {
|
|
3352
|
+
className: "dsh-claude-flow-subcalls",
|
|
3353
|
+
children: tool.subcalls.map((subcall) => /* @__PURE__ */ jsxs("div", { children: [
|
|
3354
|
+
subcallGlyph(subcall),
|
|
3355
|
+
" ",
|
|
3356
|
+
subcall.toolName ?? t("subagent"),
|
|
3357
|
+
subcall.summary === void 0 ? "" : ` · ${subcall.summary}`
|
|
3358
|
+
] }, subcall.toolUseId))
|
|
3359
|
+
}), /* @__PURE__ */ jsx(ToolPresentation, {
|
|
3360
|
+
tool,
|
|
3361
|
+
t
|
|
3362
|
+
})]
|
|
3363
|
+
})]
|
|
3364
|
+
});
|
|
3365
|
+
}
|
|
3366
|
+
function ClaudeTranscriptToolGroup({ tools, additions, deletions, files: _files, t }) {
|
|
3367
|
+
const [open, setOpen] = useState(false);
|
|
3368
|
+
const failed = tools.some((tool) => tool.isError === true || tool.phase === "failed");
|
|
3369
|
+
const running = tools.some((tool) => tool.phase === "started" || tool.phase === "updated");
|
|
3370
|
+
const summary = tools.length === 1 ? t("usedTool") : t("usedTools", { count: tools.length });
|
|
3371
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
3372
|
+
className: "dsh-claude-tool-group-native",
|
|
3373
|
+
children: [/* @__PURE__ */ jsx(DisclosureRow, {
|
|
3374
|
+
rowClassName: "dsh-claude-flow-row",
|
|
3375
|
+
leadingClassName: "dsh-claude-flow-leading",
|
|
3376
|
+
titleClassName: "dsh-claude-flow-title",
|
|
3377
|
+
chevronClassName: "dsh-claude-flow-chevron",
|
|
3378
|
+
icon: failed ? /* @__PURE__ */ jsx(StateDot, { state: "error" }) : running ? /* @__PURE__ */ jsx(StateDot, { state: "ongoing" }) : /* @__PURE__ */ jsx(IconApiOutline14, { size: 14 }),
|
|
3379
|
+
title: summary,
|
|
3380
|
+
open,
|
|
3381
|
+
expandable: true,
|
|
3382
|
+
expandOnRowClick: true,
|
|
3383
|
+
keepContentWhenOpen: true,
|
|
3384
|
+
onToggle: () => setOpen((value) => !value),
|
|
3385
|
+
collapsedContent: additions !== void 0 || deletions !== void 0 ? /* @__PURE__ */ jsxs("span", {
|
|
3386
|
+
className: "dsh-claude-tool-stats",
|
|
3387
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
3388
|
+
className: "dsh-claude-diff-add",
|
|
3389
|
+
children: ["+", additions ?? 0]
|
|
3390
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
3391
|
+
className: "dsh-claude-diff-delete",
|
|
3392
|
+
children: ["−", deletions ?? 0]
|
|
3393
|
+
})]
|
|
3394
|
+
}) : void 0
|
|
3395
|
+
}), open ? /* @__PURE__ */ jsx("div", {
|
|
3396
|
+
className: "dsh-claude-tool-list",
|
|
3397
|
+
children: tools.map((tool) => /* @__PURE__ */ jsx(ClaudeTranscriptToolItem, {
|
|
3398
|
+
tool,
|
|
3399
|
+
t
|
|
3400
|
+
}, tool.toolUseId))
|
|
3401
|
+
}) : null]
|
|
3402
|
+
});
|
|
3403
|
+
}
|
|
1825
3404
|
function ClaudeActivityNode({ node, useClaudeProjection, t }) {
|
|
1826
3405
|
ensureCss();
|
|
1827
3406
|
const marker = node.data;
|
|
1828
|
-
const activities = useClaudeProjection((value) => value.
|
|
3407
|
+
const activities = useClaudeProjection((value) => selectStepActivities(value, marker.turn, marker.step));
|
|
1829
3408
|
const tasks = useClaudeProjection((value) => value.tasks?.tasks ?? EMPTY_TASKS);
|
|
1830
|
-
const
|
|
3409
|
+
const items = useMemo(() => transcriptItemsForStep(activities, marker.turn, marker.step, tasks), [
|
|
1831
3410
|
activities,
|
|
1832
3411
|
marker.step,
|
|
1833
3412
|
marker.turn,
|
|
1834
3413
|
tasks
|
|
1835
3414
|
]);
|
|
1836
|
-
if (
|
|
3415
|
+
if (items.length === 0) return null;
|
|
1837
3416
|
return /* @__PURE__ */ jsx("div", {
|
|
1838
3417
|
className: "dsh-claude-flow",
|
|
1839
|
-
children:
|
|
1840
|
-
|
|
3418
|
+
children: items.map((item) => item.kind === "text" ? /* @__PURE__ */ jsx("div", {
|
|
3419
|
+
className: "dsh-claude-transcript-text",
|
|
3420
|
+
children: /* @__PURE__ */ jsx(MarkdownText, { text: item.text })
|
|
3421
|
+
}, `text:${item.ordinal}`) : item.kind === "tools" ? /* @__PURE__ */ jsx(ClaudeTranscriptToolGroup, {
|
|
3422
|
+
tools: item.tools,
|
|
3423
|
+
...item.additions === void 0 ? {} : { additions: item.additions },
|
|
3424
|
+
...item.deletions === void 0 ? {} : { deletions: item.deletions },
|
|
3425
|
+
...item.files === void 0 ? {} : { files: item.files },
|
|
3426
|
+
t
|
|
3427
|
+
}, `tools:${item.ordinal}`) : /* @__PURE__ */ jsx(ActivityRow, {
|
|
3428
|
+
row: item.row,
|
|
1841
3429
|
t
|
|
1842
|
-
},
|
|
3430
|
+
}, `activity:${item.ordinal}`))
|
|
1843
3431
|
});
|
|
1844
3432
|
}
|
|
1845
3433
|
//#endregion
|
|
@@ -2282,7 +3870,7 @@ window.__ModuleLoader__.load({
|
|
|
2282
3870
|
style: diagnosticValue,
|
|
2283
3871
|
children: t(`updateState_${updateStatus.state}`)
|
|
2284
3872
|
}),
|
|
2285
|
-
updateStatus.latestVersion === void 0 ? null : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
3873
|
+
updateStatus.latestVersion === void 0 ? null : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
|
|
2286
3874
|
style: diagnosticLabel,
|
|
2287
3875
|
children: t("latestVersion")
|
|
2288
3876
|
}), /* @__PURE__ */ jsx("span", {
|
|
@@ -2348,6 +3936,16 @@ window.__ModuleLoader__.load({
|
|
|
2348
3936
|
}
|
|
2349
3937
|
//#endregion
|
|
2350
3938
|
//#region src/client/ClaudeRepositoryStatus.tsx
|
|
3939
|
+
const RATE_LIMIT_TITLE_PREFIX = "Claude rate limit";
|
|
3940
|
+
const RATE_LIMIT_BLOCKING_TITLE = "Claude rate limit is blocking requests";
|
|
3941
|
+
/** Whether the newest quota update in the activity feed reports a blocked state. */
|
|
3942
|
+
function rateLimitBlocked(activities) {
|
|
3943
|
+
for (let index = activities.length - 1; index >= 0; index -= 1) {
|
|
3944
|
+
const title = activities[index]?.title;
|
|
3945
|
+
if (title?.startsWith(RATE_LIMIT_TITLE_PREFIX) === true) return title === RATE_LIMIT_BLOCKING_TITLE;
|
|
3946
|
+
}
|
|
3947
|
+
return false;
|
|
3948
|
+
}
|
|
2351
3949
|
function StatusItem({ label, tone = "neutral" }) {
|
|
2352
3950
|
const toneStyle = tone === "success" ? repositoryItemSuccess : tone === "warning" ? repositoryItemWarning : tone === "error" ? repositoryItemError : {};
|
|
2353
3951
|
return /* @__PURE__ */ jsxs("span", {
|
|
@@ -2361,7 +3959,37 @@ window.__ModuleLoader__.load({
|
|
|
2361
3959
|
}), label]
|
|
2362
3960
|
});
|
|
2363
3961
|
}
|
|
2364
|
-
function PullRequestIcon({ size = 16 }) {
|
|
3962
|
+
function PullRequestIcon({ size = 16, merged = false }) {
|
|
3963
|
+
if (merged) return /* @__PURE__ */ jsxs("svg", {
|
|
3964
|
+
width: size,
|
|
3965
|
+
height: size,
|
|
3966
|
+
viewBox: "0 0 16 16",
|
|
3967
|
+
fill: "none",
|
|
3968
|
+
stroke: "currentColor",
|
|
3969
|
+
strokeWidth: "1.8",
|
|
3970
|
+
strokeLinecap: "round",
|
|
3971
|
+
strokeLinejoin: "round",
|
|
3972
|
+
"aria-hidden": "true",
|
|
3973
|
+
children: [
|
|
3974
|
+
/* @__PURE__ */ jsx("circle", {
|
|
3975
|
+
cx: "4",
|
|
3976
|
+
cy: "3",
|
|
3977
|
+
r: "1.6"
|
|
3978
|
+
}),
|
|
3979
|
+
/* @__PURE__ */ jsx("circle", {
|
|
3980
|
+
cx: "4",
|
|
3981
|
+
cy: "13",
|
|
3982
|
+
r: "1.6"
|
|
3983
|
+
}),
|
|
3984
|
+
/* @__PURE__ */ jsx("circle", {
|
|
3985
|
+
cx: "12",
|
|
3986
|
+
cy: "8",
|
|
3987
|
+
r: "1.6"
|
|
3988
|
+
}),
|
|
3989
|
+
/* @__PURE__ */ jsx("path", { d: "M4 4.6v6.8" }),
|
|
3990
|
+
/* @__PURE__ */ jsx("path", { d: "M5.6 3H7a5 5 0 0 1 5 3.4" })
|
|
3991
|
+
]
|
|
3992
|
+
});
|
|
2365
3993
|
return /* @__PURE__ */ jsxs("svg", {
|
|
2366
3994
|
width: size,
|
|
2367
3995
|
height: size,
|
|
@@ -2408,7 +4036,8 @@ window.__ModuleLoader__.load({
|
|
|
2408
4036
|
function PullRequestHoverCard({ repository, t }) {
|
|
2409
4037
|
const pullRequest = repository.pullRequest;
|
|
2410
4038
|
if (pullRequest === void 0) return null;
|
|
2411
|
-
const
|
|
4039
|
+
const merged = pullRequest.state === "merged";
|
|
4040
|
+
const age = relativeAge(merged ? pullRequest.mergedAt : pullRequest.createdAt);
|
|
2412
4041
|
return /* @__PURE__ */ jsxs("span", {
|
|
2413
4042
|
role: "tooltip",
|
|
2414
4043
|
style: repositoryPrHoverCard,
|
|
@@ -2417,8 +4046,14 @@ window.__ModuleLoader__.load({
|
|
|
2417
4046
|
style: repositoryPrHoverTop,
|
|
2418
4047
|
children: [
|
|
2419
4048
|
/* @__PURE__ */ jsxs("span", {
|
|
2420
|
-
style:
|
|
2421
|
-
|
|
4049
|
+
style: {
|
|
4050
|
+
...repositoryPrStateBadge,
|
|
4051
|
+
...merged ? repositoryPrStateBadgeMerged : {}
|
|
4052
|
+
},
|
|
4053
|
+
children: [/* @__PURE__ */ jsx(PullRequestIcon, {
|
|
4054
|
+
size: 13,
|
|
4055
|
+
merged
|
|
4056
|
+
}), t(`repositoryState_${pullRequest.state}`)]
|
|
2422
4057
|
}),
|
|
2423
4058
|
/* @__PURE__ */ jsxs("span", {
|
|
2424
4059
|
style: repositoryPrHoverRepo,
|
|
@@ -2509,7 +4144,10 @@ window.__ModuleLoader__.load({
|
|
|
2509
4144
|
href: pullRequest.url,
|
|
2510
4145
|
target: "_blank",
|
|
2511
4146
|
rel: "noopener noreferrer",
|
|
2512
|
-
style:
|
|
4147
|
+
style: {
|
|
4148
|
+
...repositoryPrLink,
|
|
4149
|
+
...pullRequest.state === "merged" ? repositoryPrLinkMerged : {}
|
|
4150
|
+
},
|
|
2513
4151
|
"aria-label": t("repositoryOpenPr", { number: pullRequest.number }),
|
|
2514
4152
|
children: ["#", pullRequest.number]
|
|
2515
4153
|
})]
|
|
@@ -2522,27 +4160,46 @@ window.__ModuleLoader__.load({
|
|
|
2522
4160
|
if (blank || !projection.owned || repository === void 0) return null;
|
|
2523
4161
|
const branch = repository.detached === true ? t("repositoryDetached") : repository.branch ?? t("repositoryUnknownBranch");
|
|
2524
4162
|
const pullRequest = repository.pullRequest;
|
|
4163
|
+
const merged = pullRequest?.state === "merged";
|
|
4164
|
+
const mergedAge = merged ? relativeAge(pullRequest.mergedAt) : void 0;
|
|
4165
|
+
const aheadCount = repository.ahead ?? 0;
|
|
4166
|
+
const pushable = repository.remote !== void 0 && repository.detached !== true && (aheadCount > 0 || repository.upstream === false);
|
|
4167
|
+
const hasDiff = repository.diff !== void 0 && (repository.diff.additions > 0 || repository.diff.deletions > 0);
|
|
4168
|
+
const rateLimited = rateLimitBlocked(projection.activities);
|
|
2525
4169
|
if (repository.status !== "ready") return /* @__PURE__ */ jsx("div", {
|
|
2526
4170
|
style: repositoryBarFrame,
|
|
2527
4171
|
children: /* @__PURE__ */ jsxs("div", {
|
|
2528
4172
|
style: repositoryBar,
|
|
2529
|
-
children: [
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
4173
|
+
children: [
|
|
4174
|
+
/* @__PURE__ */ jsx("span", {
|
|
4175
|
+
style: repositoryPrIcon,
|
|
4176
|
+
children: /* @__PURE__ */ jsx(PullRequestIcon, {})
|
|
4177
|
+
}),
|
|
4178
|
+
/* @__PURE__ */ jsx("span", {
|
|
4179
|
+
style: repositoryPrimary,
|
|
4180
|
+
children: repository.status === "not-repository" ? t("repositoryNotGit") : t("repositoryUnavailable")
|
|
4181
|
+
}),
|
|
4182
|
+
rateLimited ? /* @__PURE__ */ jsx(StatusItem, {
|
|
4183
|
+
label: t("repositoryRateLimited"),
|
|
4184
|
+
tone: "warning"
|
|
4185
|
+
}) : null
|
|
4186
|
+
]
|
|
2536
4187
|
})
|
|
2537
4188
|
});
|
|
2538
4189
|
return /* @__PURE__ */ jsx("div", {
|
|
2539
4190
|
style: repositoryBarFrame,
|
|
2540
4191
|
children: /* @__PURE__ */ jsxs("div", {
|
|
2541
|
-
style:
|
|
4192
|
+
style: {
|
|
4193
|
+
...repositoryBar,
|
|
4194
|
+
...merged ? repositoryBarMerged : {}
|
|
4195
|
+
},
|
|
2542
4196
|
children: [
|
|
2543
4197
|
/* @__PURE__ */ jsx("span", {
|
|
2544
|
-
style:
|
|
2545
|
-
|
|
4198
|
+
style: {
|
|
4199
|
+
...repositoryPrIcon,
|
|
4200
|
+
...merged ? repositoryPrIconMerged : {}
|
|
4201
|
+
},
|
|
4202
|
+
children: /* @__PURE__ */ jsx(PullRequestIcon, { merged })
|
|
2546
4203
|
}),
|
|
2547
4204
|
/* @__PURE__ */ jsx(PullRequestLink, {
|
|
2548
4205
|
repository,
|
|
@@ -2562,31 +4219,311 @@ window.__ModuleLoader__.load({
|
|
|
2562
4219
|
}) : null,
|
|
2563
4220
|
/* @__PURE__ */ jsxs("span", {
|
|
2564
4221
|
style: repositoryStatusItems,
|
|
2565
|
-
children: [
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
4222
|
+
children: [
|
|
4223
|
+
rateLimited ? /* @__PURE__ */ jsx(StatusItem, {
|
|
4224
|
+
label: t("repositoryRateLimited"),
|
|
4225
|
+
tone: "warning"
|
|
4226
|
+
}) : null,
|
|
4227
|
+
hasDiff || pushable ? /* @__PURE__ */ jsxs("button", {
|
|
4228
|
+
type: "button",
|
|
4229
|
+
style: {
|
|
4230
|
+
...diffTrigger,
|
|
4231
|
+
...merged ? diffTriggerMuted : {}
|
|
4232
|
+
},
|
|
4233
|
+
onClick: openDiff,
|
|
4234
|
+
"aria-label": t("diffOpen"),
|
|
4235
|
+
children: [hasDiff && repository.diff !== void 0 ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("span", {
|
|
4236
|
+
style: merged ? diffAddMuted : diffAdd,
|
|
4237
|
+
children: ["+", repository.diff.additions]
|
|
4238
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
4239
|
+
style: merged ? diffDeleteMuted : diffDelete,
|
|
4240
|
+
children: ["−", repository.diff.deletions]
|
|
4241
|
+
})] }) : null, pushable ? /* @__PURE__ */ jsxs("span", {
|
|
4242
|
+
style: merged ? diffAheadMuted : diffAhead,
|
|
4243
|
+
children: ["↑", aheadCount > 0 ? aheadCount : ""]
|
|
4244
|
+
}) : null]
|
|
4245
|
+
}) : null,
|
|
4246
|
+
pullRequest === void 0 ? null : merged ? /* @__PURE__ */ jsxs("span", {
|
|
4247
|
+
style: repositoryMergedStatus,
|
|
4248
|
+
children: [
|
|
4249
|
+
/* @__PURE__ */ jsx("span", {
|
|
4250
|
+
style: repositoryMergedDot,
|
|
4251
|
+
"aria-hidden": "true"
|
|
4252
|
+
}),
|
|
4253
|
+
t("repositoryMergedInto", { branch: pullRequest.baseBranch ?? t("repositoryUnknownBranch") }),
|
|
4254
|
+
mergedAge === void 0 ? null : /* @__PURE__ */ jsxs("span", {
|
|
4255
|
+
style: repositoryMergedAge,
|
|
4256
|
+
children: ["· ", t("repositoryMergedAgo", { age: mergedAge })]
|
|
4257
|
+
})
|
|
4258
|
+
]
|
|
4259
|
+
}) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(StatusItem, {
|
|
4260
|
+
label: t(`repositoryChecks_${pullRequest.checks}`),
|
|
4261
|
+
tone: pullRequest.checks === "passing" ? "success" : pullRequest.checks === "failing" ? "error" : pullRequest.checks === "pending" ? "warning" : "neutral"
|
|
4262
|
+
}), /* @__PURE__ */ jsx(StatusItem, {
|
|
4263
|
+
label: t(`repositoryReview_${pullRequest.review}`),
|
|
4264
|
+
tone: pullRequest.review === "approved" ? "success" : pullRequest.review === "changes-requested" ? "error" : "neutral"
|
|
4265
|
+
})] })
|
|
4266
|
+
]
|
|
2584
4267
|
})
|
|
2585
4268
|
]
|
|
2586
4269
|
})
|
|
2587
4270
|
});
|
|
2588
4271
|
}
|
|
2589
4272
|
//#endregion
|
|
4273
|
+
//#region src/client/review-comment-api.ts
|
|
4274
|
+
function record$2(value) {
|
|
4275
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
4276
|
+
}
|
|
4277
|
+
async function post(path, sessionId, body) {
|
|
4278
|
+
const response = await fetch(`${CLAUDE_REVIEW_COMMENT_PATH}${path}?sessionId=${encodeURIComponent(sessionId)}`, {
|
|
4279
|
+
method: "POST",
|
|
4280
|
+
credentials: "same-origin",
|
|
4281
|
+
headers: {
|
|
4282
|
+
accept: "application/json",
|
|
4283
|
+
"content-type": "application/json"
|
|
4284
|
+
},
|
|
4285
|
+
body: JSON.stringify(body)
|
|
4286
|
+
});
|
|
4287
|
+
const value = await response.json();
|
|
4288
|
+
if (!response.ok) {
|
|
4289
|
+
const error = record$2(value);
|
|
4290
|
+
throw new Error(typeof error?.message === "string" ? error.message : "Review comment request failed.");
|
|
4291
|
+
}
|
|
4292
|
+
return value;
|
|
4293
|
+
}
|
|
4294
|
+
async function addReviewComment(sessionId, comment) {
|
|
4295
|
+
const created = record$2(record$2(await post("", sessionId, comment))?.comment);
|
|
4296
|
+
if (created === void 0 || typeof created.id !== "string") throw new Error("Invalid review comment response.");
|
|
4297
|
+
return created;
|
|
4298
|
+
}
|
|
4299
|
+
async function removeReviewComment(sessionId, id) {
|
|
4300
|
+
await post("/remove", sessionId, { id });
|
|
4301
|
+
}
|
|
4302
|
+
async function clearReviewComments(sessionId) {
|
|
4303
|
+
await post("/clear", sessionId, {});
|
|
4304
|
+
}
|
|
4305
|
+
//#endregion
|
|
4306
|
+
//#region src/client/ClaudeReviewComments.tsx
|
|
4307
|
+
function reviewCommentChipLabel(comment) {
|
|
4308
|
+
return `${comment.path.split("/").at(-1) ?? comment.path}:${comment.line}`;
|
|
4309
|
+
}
|
|
4310
|
+
function CommentIcon() {
|
|
4311
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
4312
|
+
width: "16",
|
|
4313
|
+
height: "16",
|
|
4314
|
+
viewBox: "0 0 16 16",
|
|
4315
|
+
fill: "none",
|
|
4316
|
+
stroke: "currentColor",
|
|
4317
|
+
strokeWidth: "1.5",
|
|
4318
|
+
strokeLinecap: "round",
|
|
4319
|
+
strokeLinejoin: "round",
|
|
4320
|
+
"aria-hidden": "true",
|
|
4321
|
+
children: /* @__PURE__ */ jsx("path", { d: "M2.75 2.75h10.5a1 1 0 0 1 1 1v6.5a1 1 0 0 1-1 1H8.2l-3.2 2.9v-2.9H2.75a1 1 0 0 1-1-1v-6.5a1 1 0 0 1 1-1Z" })
|
|
4322
|
+
});
|
|
4323
|
+
}
|
|
4324
|
+
function SendIcon() {
|
|
4325
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
4326
|
+
width: "14",
|
|
4327
|
+
height: "14",
|
|
4328
|
+
viewBox: "0 0 16 16",
|
|
4329
|
+
fill: "none",
|
|
4330
|
+
stroke: "currentColor",
|
|
4331
|
+
strokeWidth: "1.5",
|
|
4332
|
+
strokeLinecap: "round",
|
|
4333
|
+
strokeLinejoin: "round",
|
|
4334
|
+
"aria-hidden": "true",
|
|
4335
|
+
children: /* @__PURE__ */ jsx("path", { d: "M14 2 7.3 8.7M14 2 9.7 14l-2.4-5.3L2 6.3 14 2Z" })
|
|
4336
|
+
});
|
|
4337
|
+
}
|
|
4338
|
+
function TrashIcon() {
|
|
4339
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
4340
|
+
width: "14",
|
|
4341
|
+
height: "14",
|
|
4342
|
+
viewBox: "0 0 16 16",
|
|
4343
|
+
fill: "none",
|
|
4344
|
+
stroke: "currentColor",
|
|
4345
|
+
strokeWidth: "1.5",
|
|
4346
|
+
strokeLinecap: "round",
|
|
4347
|
+
strokeLinejoin: "round",
|
|
4348
|
+
"aria-hidden": "true",
|
|
4349
|
+
children: /* @__PURE__ */ jsx("path", { d: "M2.5 4h11M6.3 2.5h3.4M4.2 4l.65 9.3a1 1 0 0 0 1 .93h4.3a1 1 0 0 0 1-.93L11.8 4M6.7 6.8v4.6M9.3 6.8v4.6" })
|
|
4350
|
+
});
|
|
4351
|
+
}
|
|
4352
|
+
function CommentChip({ comment, t, onRemove }) {
|
|
4353
|
+
return /* @__PURE__ */ jsx(HoverCard, {
|
|
4354
|
+
anchor: /* @__PURE__ */ jsxs("span", {
|
|
4355
|
+
style: reviewCommentChip,
|
|
4356
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
4357
|
+
style: reviewCommentChipLabel$1,
|
|
4358
|
+
children: reviewCommentChipLabel(comment)
|
|
4359
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
4360
|
+
type: "button",
|
|
4361
|
+
style: reviewCommentChipRemove,
|
|
4362
|
+
"aria-label": t("reviewCommentRemove"),
|
|
4363
|
+
onClick: () => onRemove(comment.id),
|
|
4364
|
+
children: "×"
|
|
4365
|
+
})]
|
|
4366
|
+
}),
|
|
4367
|
+
content: /* @__PURE__ */ jsxs("span", {
|
|
4368
|
+
style: reviewCommentHoverCard,
|
|
4369
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
4370
|
+
style: reviewCommentHoverPath,
|
|
4371
|
+
children: [
|
|
4372
|
+
comment.path,
|
|
4373
|
+
" · ",
|
|
4374
|
+
comment.side === "old" ? t("reviewCommentOldSide", { line: comment.line }) : t("reviewCommentNewSide", { line: comment.line })
|
|
4375
|
+
]
|
|
4376
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
4377
|
+
style: reviewCommentHoverText,
|
|
4378
|
+
children: comment.text
|
|
4379
|
+
})]
|
|
4380
|
+
}),
|
|
4381
|
+
openDelayMs: 250
|
|
4382
|
+
});
|
|
4383
|
+
}
|
|
4384
|
+
/** Pending review comments docked above the composer; drained by the next user turn. */
|
|
4385
|
+
function ClaudeReviewComments({ useClaudeProjection, t, sessionId, submitWith }) {
|
|
4386
|
+
const projection = useClaudeProjection((value) => value);
|
|
4387
|
+
const [removedIds, setRemovedIds] = useState(() => /* @__PURE__ */ new Set());
|
|
4388
|
+
const comments = (projection.reviewComments ?? []).filter((comment) => !removedIds.has(comment.id));
|
|
4389
|
+
if (!projection.owned || comments.length === 0) return null;
|
|
4390
|
+
const remove = (id) => {
|
|
4391
|
+
setRemovedIds((previous) => /* @__PURE__ */ new Set([...previous, id]));
|
|
4392
|
+
removeReviewComment(sessionId, id).catch(() => {
|
|
4393
|
+
setRemovedIds((previous) => {
|
|
4394
|
+
const next = new Set(previous);
|
|
4395
|
+
next.delete(id);
|
|
4396
|
+
return next;
|
|
4397
|
+
});
|
|
4398
|
+
});
|
|
4399
|
+
};
|
|
4400
|
+
const clearAll = () => {
|
|
4401
|
+
const ids = comments.map((comment) => comment.id);
|
|
4402
|
+
setRemovedIds((previous) => /* @__PURE__ */ new Set([...previous, ...ids]));
|
|
4403
|
+
clearReviewComments(sessionId).catch(() => {
|
|
4404
|
+
setRemovedIds((previous) => {
|
|
4405
|
+
const next = new Set(previous);
|
|
4406
|
+
for (const id of ids) next.delete(id);
|
|
4407
|
+
return next;
|
|
4408
|
+
});
|
|
4409
|
+
});
|
|
4410
|
+
};
|
|
4411
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
4412
|
+
style: reviewCommentBarFrame,
|
|
4413
|
+
children: [/* @__PURE__ */ jsx("style", {
|
|
4414
|
+
"data-dsh-claude-review-comment-styles": true,
|
|
4415
|
+
children: panelIconButtonCss
|
|
4416
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
4417
|
+
style: reviewCommentBar,
|
|
4418
|
+
children: [
|
|
4419
|
+
/* @__PURE__ */ jsx("span", {
|
|
4420
|
+
style: reviewCommentIcon,
|
|
4421
|
+
children: /* @__PURE__ */ jsx(CommentIcon, {})
|
|
4422
|
+
}),
|
|
4423
|
+
comments.map((comment) => /* @__PURE__ */ jsx(CommentChip, {
|
|
4424
|
+
comment,
|
|
4425
|
+
t,
|
|
4426
|
+
onRemove: remove
|
|
4427
|
+
}, comment.id)),
|
|
4428
|
+
/* @__PURE__ */ jsxs("span", {
|
|
4429
|
+
style: reviewCommentClearSeat,
|
|
4430
|
+
children: [submitWith === void 0 ? null : /* @__PURE__ */ jsx("button", {
|
|
4431
|
+
type: "button",
|
|
4432
|
+
className: panelIconButtonClass,
|
|
4433
|
+
"aria-label": t("reviewCommentsSend"),
|
|
4434
|
+
onClick: () => submitWith(t("reviewCommentsSendDraft")),
|
|
4435
|
+
children: /* @__PURE__ */ jsx(SendIcon, {})
|
|
4436
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
4437
|
+
type: "button",
|
|
4438
|
+
className: panelIconButtonClass,
|
|
4439
|
+
"aria-label": t("reviewCommentsClear"),
|
|
4440
|
+
onClick: clearAll,
|
|
4441
|
+
children: /* @__PURE__ */ jsx(TrashIcon, {})
|
|
4442
|
+
})]
|
|
4443
|
+
})
|
|
4444
|
+
]
|
|
4445
|
+
})]
|
|
4446
|
+
});
|
|
4447
|
+
}
|
|
4448
|
+
//#endregion
|
|
4449
|
+
//#region src/client/repository-action-api.ts
|
|
4450
|
+
var RepositoryActionClientError = class extends Error {
|
|
4451
|
+
code;
|
|
4452
|
+
commit;
|
|
4453
|
+
constructor(message, code, commit) {
|
|
4454
|
+
super(message);
|
|
4455
|
+
this.name = "RepositoryActionClientError";
|
|
4456
|
+
if (code !== void 0) this.code = code;
|
|
4457
|
+
if (commit !== void 0) this.commit = commit;
|
|
4458
|
+
}
|
|
4459
|
+
};
|
|
4460
|
+
function record$1(value) {
|
|
4461
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
4462
|
+
}
|
|
4463
|
+
async function response$1(pending) {
|
|
4464
|
+
const result = await pending;
|
|
4465
|
+
const body = await result.json();
|
|
4466
|
+
if (!result.ok) {
|
|
4467
|
+
const error = record$1(body);
|
|
4468
|
+
throw new RepositoryActionClientError(typeof error?.message === "string" ? error.message : "Repository action failed.", typeof error?.error === "string" ? error.error : void 0, typeof error?.commit === "string" ? error.commit : void 0);
|
|
4469
|
+
}
|
|
4470
|
+
return body;
|
|
4471
|
+
}
|
|
4472
|
+
function preview(value) {
|
|
4473
|
+
const input = record$1(value);
|
|
4474
|
+
if (input === void 0 || typeof input.root !== "string" || typeof input.branch !== "string" || typeof input.head !== "string" || typeof input.fingerprint !== "string" || !Array.isArray(input.files) || typeof input.patch !== "string" || typeof input.truncated !== "boolean" || typeof input.hasStaged !== "boolean" || typeof input.hasUnstaged !== "boolean" || typeof input.hasUntracked !== "boolean" || input.upstream !== void 0 && typeof input.upstream !== "string" || !Array.isArray(input.unpushedCommits) || typeof input.unpushedTruncated !== "boolean") throw new Error("Invalid repository action preview.");
|
|
4475
|
+
for (const file of input.files) {
|
|
4476
|
+
const item = record$1(file);
|
|
4477
|
+
if (item === void 0 || typeof item.path !== "string" || typeof item.staged !== "boolean" || typeof item.unstaged !== "boolean" || typeof item.untracked !== "boolean") throw new Error("Invalid repository action file.");
|
|
4478
|
+
}
|
|
4479
|
+
for (const commit of input.unpushedCommits) {
|
|
4480
|
+
const item = record$1(commit);
|
|
4481
|
+
if (item === void 0 || typeof item.hash !== "string" || typeof item.subject !== "string") throw new Error("Invalid repository action commit.");
|
|
4482
|
+
}
|
|
4483
|
+
return input;
|
|
4484
|
+
}
|
|
4485
|
+
function result(value) {
|
|
4486
|
+
const input = record$1(value);
|
|
4487
|
+
if (input === void 0 || typeof input.commit !== "string" || typeof input.pushed !== "boolean" || input.pullRequestUrl !== void 0 && typeof input.pullRequestUrl !== "string") throw new Error("Invalid repository action result.");
|
|
4488
|
+
return input;
|
|
4489
|
+
}
|
|
4490
|
+
function endpoint(path, sessionId) {
|
|
4491
|
+
return `${CLAUDE_REPOSITORY_ACTION_PATH}${path}?sessionId=${encodeURIComponent(sessionId)}`;
|
|
4492
|
+
}
|
|
4493
|
+
async function loadRepositoryActionPreview(sessionId, signal) {
|
|
4494
|
+
return preview(await response$1(fetch(endpoint("/preview", sessionId), {
|
|
4495
|
+
method: "GET",
|
|
4496
|
+
credentials: "same-origin",
|
|
4497
|
+
headers: { accept: "application/json" },
|
|
4498
|
+
...signal === void 0 ? {} : { signal }
|
|
4499
|
+
})));
|
|
4500
|
+
}
|
|
4501
|
+
async function generateCommitMessage(sessionId, fingerprint, signal) {
|
|
4502
|
+
const value = record$1(await response$1(fetch(endpoint("/message", sessionId), {
|
|
4503
|
+
method: "POST",
|
|
4504
|
+
credentials: "same-origin",
|
|
4505
|
+
headers: {
|
|
4506
|
+
accept: "application/json",
|
|
4507
|
+
"content-type": "application/json"
|
|
4508
|
+
},
|
|
4509
|
+
body: JSON.stringify({ fingerprint }),
|
|
4510
|
+
...signal === void 0 ? {} : { signal }
|
|
4511
|
+
})));
|
|
4512
|
+
if (typeof value?.message !== "string") throw new Error("Invalid generated commit message.");
|
|
4513
|
+
return value.message;
|
|
4514
|
+
}
|
|
4515
|
+
function executeRepositoryAction(sessionId, request) {
|
|
4516
|
+
return response$1(fetch(endpoint("", sessionId), {
|
|
4517
|
+
method: "POST",
|
|
4518
|
+
credentials: "same-origin",
|
|
4519
|
+
headers: {
|
|
4520
|
+
accept: "application/json",
|
|
4521
|
+
"content-type": "application/json"
|
|
4522
|
+
},
|
|
4523
|
+
body: JSON.stringify(request)
|
|
4524
|
+
})).then(result);
|
|
4525
|
+
}
|
|
4526
|
+
//#endregion
|
|
2590
4527
|
//#region src/client/ClaudeDiffPanel.tsx
|
|
2591
4528
|
function pathFromHeader(line) {
|
|
2592
4529
|
return /^diff --git a\/(.+) b\/(.+)$/u.exec(line)?.[2];
|
|
@@ -2665,15 +4602,35 @@ window.__ModuleLoader__.load({
|
|
|
2665
4602
|
}
|
|
2666
4603
|
return numbered;
|
|
2667
4604
|
}
|
|
2668
|
-
|
|
4605
|
+
/** Which working-tree line a comment on this rendered diff row refers to. */
|
|
4606
|
+
function commentAnchorForLine(entry) {
|
|
4607
|
+
if (entry.kind === "add" || entry.kind === "context") return entry.newLine === void 0 ? void 0 : {
|
|
4608
|
+
line: entry.newLine,
|
|
4609
|
+
side: "new"
|
|
4610
|
+
};
|
|
4611
|
+
if (entry.kind === "delete") return entry.oldLine === void 0 ? void 0 : {
|
|
4612
|
+
line: entry.oldLine,
|
|
4613
|
+
side: "old"
|
|
4614
|
+
};
|
|
4615
|
+
}
|
|
4616
|
+
function DiffLine({ entry, addLabel, onComment }) {
|
|
2669
4617
|
const style = entry.kind === "add" ? diffLineAdd : entry.kind === "delete" ? diffLineDelete : entry.kind === "hunk" || entry.kind === "collapsed" ? diffLineHunk : diffLineContext;
|
|
2670
4618
|
const lineNumber = entry.oldLine === void 0 && entry.newLine === void 0 ? "" : entry.oldLine === void 0 ? String(entry.newLine) : entry.newLine === void 0 ? String(entry.oldLine) : String(entry.newLine);
|
|
2671
4619
|
return /* @__PURE__ */ jsxs("div", {
|
|
4620
|
+
className: diffLineRowClass,
|
|
2672
4621
|
style: {
|
|
2673
4622
|
...diffLine,
|
|
2674
4623
|
...style
|
|
2675
4624
|
},
|
|
2676
4625
|
children: [
|
|
4626
|
+
/* @__PURE__ */ jsx("button", {
|
|
4627
|
+
type: "button",
|
|
4628
|
+
className: diffCommentButtonClass,
|
|
4629
|
+
disabled: onComment === void 0,
|
|
4630
|
+
"aria-label": addLabel,
|
|
4631
|
+
onClick: onComment,
|
|
4632
|
+
children: "+"
|
|
4633
|
+
}),
|
|
2677
4634
|
/* @__PURE__ */ jsx("span", {
|
|
2678
4635
|
style: diffLineNumber,
|
|
2679
4636
|
children: lineNumber
|
|
@@ -2686,7 +4643,7 @@ window.__ModuleLoader__.load({
|
|
|
2686
4643
|
]
|
|
2687
4644
|
});
|
|
2688
4645
|
}
|
|
2689
|
-
function DiffFileSection({ file, initiallyOpen }) {
|
|
4646
|
+
function DiffFileSection({ file, initiallyOpen, t, comments, editorAnchor, editorNode, onOpenEditor, onRemoveComment }) {
|
|
2690
4647
|
const [open, setOpen] = useState(initiallyOpen);
|
|
2691
4648
|
return /* @__PURE__ */ jsxs("section", {
|
|
2692
4649
|
style: diffFile,
|
|
@@ -2720,15 +4677,278 @@ window.__ModuleLoader__.load({
|
|
|
2720
4677
|
]
|
|
2721
4678
|
}), open ? /* @__PURE__ */ jsx("div", {
|
|
2722
4679
|
style: diffCode,
|
|
2723
|
-
children: numberDiffLines(file.lines).map((entry, index) =>
|
|
4680
|
+
children: numberDiffLines(file.lines).map((entry, index) => {
|
|
4681
|
+
const anchor = commentAnchorForLine(entry);
|
|
4682
|
+
const lineComments = anchor === void 0 ? [] : comments.filter((comment) => comment.line === anchor.line && comment.side === anchor.side);
|
|
4683
|
+
const editorOpen = anchor !== void 0 && editorAnchor !== void 0 && editorAnchor.line === anchor.line && editorAnchor.side === anchor.side;
|
|
4684
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4685
|
+
/* @__PURE__ */ jsx(DiffLine, {
|
|
4686
|
+
entry,
|
|
4687
|
+
addLabel: t("reviewCommentAdd"),
|
|
4688
|
+
onComment: anchor === void 0 ? void 0 : () => onOpenEditor(anchor)
|
|
4689
|
+
}),
|
|
4690
|
+
lineComments.map((comment) => /* @__PURE__ */ jsxs("div", {
|
|
4691
|
+
style: diffCommentBlock,
|
|
4692
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
4693
|
+
style: diffCommentCardMeta,
|
|
4694
|
+
children: [/* @__PURE__ */ jsx("span", { children: comment.side === "old" ? t("reviewCommentOldSide", { line: comment.line }) : t("reviewCommentNewSide", { line: comment.line }) }), /* @__PURE__ */ jsx("button", {
|
|
4695
|
+
type: "button",
|
|
4696
|
+
style: reviewCommentChipRemove,
|
|
4697
|
+
"aria-label": t("reviewCommentRemove"),
|
|
4698
|
+
onClick: () => onRemoveComment(comment.id),
|
|
4699
|
+
children: "×"
|
|
4700
|
+
})]
|
|
4701
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
4702
|
+
style: diffCommentCardText,
|
|
4703
|
+
children: comment.text
|
|
4704
|
+
})]
|
|
4705
|
+
}, comment.id)),
|
|
4706
|
+
editorOpen ? editorNode : null
|
|
4707
|
+
] }, `${index}:${entry.line}`);
|
|
4708
|
+
})
|
|
2724
4709
|
}) : null]
|
|
2725
4710
|
});
|
|
2726
4711
|
}
|
|
2727
|
-
function
|
|
4712
|
+
function actionLabel(action, t) {
|
|
4713
|
+
return (action === "commit" ? t("diffCommit") : action === "commit-push" ? t("diffCommitPush") : action === "push" ? t("diffPush") : t("diffCreatePr")).replace(/[….]+$/u, "");
|
|
4714
|
+
}
|
|
4715
|
+
function repositoryActionAvailability(repository) {
|
|
4716
|
+
const ready = repository?.status === "ready" && repository.detached !== true;
|
|
4717
|
+
const committable = ready && repository.dirty === true;
|
|
4718
|
+
const hasRemote = repository?.remote !== void 0;
|
|
4719
|
+
const hasOpenPullRequest = repository?.pullRequest?.state === "open";
|
|
4720
|
+
const pushable = ready && hasRemote && (repository.upstream === false || (repository.ahead ?? 0) > 0);
|
|
4721
|
+
return {
|
|
4722
|
+
"commit": committable,
|
|
4723
|
+
"commit-push": committable && hasRemote,
|
|
4724
|
+
"push": pushable,
|
|
4725
|
+
"create-pr": (committable || pushable) && hasRemote && !hasOpenPullRequest
|
|
4726
|
+
};
|
|
4727
|
+
}
|
|
4728
|
+
function RestorePanelIcon() {
|
|
4729
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
4730
|
+
width: "16",
|
|
4731
|
+
height: "16",
|
|
4732
|
+
viewBox: "0 0 16 16",
|
|
4733
|
+
fill: "currentColor",
|
|
4734
|
+
"aria-hidden": "true",
|
|
4735
|
+
children: /* @__PURE__ */ jsx("path", { d: "M1.5 5h3V2h1.4v4.4H1.5V5Zm9.9-3h1.4v3h3v1.4h-4.4V2ZM1.5 9.6h4.4V14H4.5v-3h-3V9.6Zm9.9 0h4.4V11h-3v3h-1.4V9.6Z" })
|
|
4736
|
+
});
|
|
4737
|
+
}
|
|
4738
|
+
function ClaudeDiffPanel({ useClaudeProjection, t, sessionId, maximized, closeDetails, toggleMaximized }) {
|
|
2728
4739
|
const projection = useClaudeProjection((value) => value);
|
|
2729
4740
|
const repository = projection.repository;
|
|
2730
4741
|
const diff = repository?.diff;
|
|
2731
4742
|
const files = useMemo(() => parseUnifiedDiff(diff?.patch ?? ""), [diff?.patch]);
|
|
4743
|
+
const [menuOpen, setMenuOpen] = useState(false);
|
|
4744
|
+
const [dialog, setDialog] = useState();
|
|
4745
|
+
const [message, setMessage] = useState("");
|
|
4746
|
+
const [includeUnstaged, setIncludeUnstaged] = useState(true);
|
|
4747
|
+
const [prTitle, setPrTitle] = useState("");
|
|
4748
|
+
const [prBody, setPrBody] = useState("");
|
|
4749
|
+
const [baseBranch, setBaseBranch] = useState("");
|
|
4750
|
+
const [draft, setDraft] = useState(true);
|
|
4751
|
+
const [commentEditor, setCommentEditor] = useState();
|
|
4752
|
+
const [commentDraft, setCommentDraft] = useState("");
|
|
4753
|
+
const [commentBusy, setCommentBusy] = useState(false);
|
|
4754
|
+
const [commentError, setCommentError] = useState();
|
|
4755
|
+
const [localComments, setLocalComments] = useState([]);
|
|
4756
|
+
const [removedCommentIds, setRemovedCommentIds] = useState(() => /* @__PURE__ */ new Set());
|
|
4757
|
+
const actionController = useRef();
|
|
4758
|
+
const diffViewportObserver = useRef();
|
|
4759
|
+
const diffBodyRef = useCallback((element) => {
|
|
4760
|
+
diffViewportObserver.current?.disconnect();
|
|
4761
|
+
diffViewportObserver.current = void 0;
|
|
4762
|
+
if (element === null || typeof ResizeObserver === "undefined") return;
|
|
4763
|
+
const update = () => element.style.setProperty("--dsh-claude-diff-viewport", `${element.clientWidth}px`);
|
|
4764
|
+
update();
|
|
4765
|
+
const observer = new ResizeObserver(update);
|
|
4766
|
+
observer.observe(element);
|
|
4767
|
+
diffViewportObserver.current = observer;
|
|
4768
|
+
}, []);
|
|
4769
|
+
useEffect(() => () => diffViewportObserver.current?.disconnect(), []);
|
|
4770
|
+
const closeDialog = useCallback(() => {
|
|
4771
|
+
if (dialog?.submitting === true) return;
|
|
4772
|
+
actionController.current?.abort();
|
|
4773
|
+
actionController.current = void 0;
|
|
4774
|
+
setDialog(void 0);
|
|
4775
|
+
}, [dialog?.submitting]);
|
|
4776
|
+
useEffect(() => {
|
|
4777
|
+
if (dialog?.commit === void 0 || dialog.error !== void 0 || dialog.pullRequestUrl !== void 0) return;
|
|
4778
|
+
const timer = setTimeout(closeDialog, 1200);
|
|
4779
|
+
return () => clearTimeout(timer);
|
|
4780
|
+
}, [
|
|
4781
|
+
closeDialog,
|
|
4782
|
+
dialog?.commit,
|
|
4783
|
+
dialog?.error,
|
|
4784
|
+
dialog?.pullRequestUrl
|
|
4785
|
+
]);
|
|
4786
|
+
const openAction = useCallback((action) => {
|
|
4787
|
+
actionController.current?.abort();
|
|
4788
|
+
setMenuOpen(false);
|
|
4789
|
+
setDialog({
|
|
4790
|
+
action,
|
|
4791
|
+
loading: true,
|
|
4792
|
+
submitting: false
|
|
4793
|
+
});
|
|
4794
|
+
setMessage("");
|
|
4795
|
+
setPrTitle("");
|
|
4796
|
+
setPrBody("");
|
|
4797
|
+
setBaseBranch("");
|
|
4798
|
+
setDraft(true);
|
|
4799
|
+
const controller = new AbortController();
|
|
4800
|
+
actionController.current = controller;
|
|
4801
|
+
loadRepositoryActionPreview(sessionId, controller.signal).then(async (preview) => {
|
|
4802
|
+
setIncludeUnstaged(preview.hasUnstaged || preview.hasUntracked);
|
|
4803
|
+
if (action === "push") {
|
|
4804
|
+
setDialog({
|
|
4805
|
+
action,
|
|
4806
|
+
preview,
|
|
4807
|
+
loading: false,
|
|
4808
|
+
submitting: false
|
|
4809
|
+
});
|
|
4810
|
+
return;
|
|
4811
|
+
}
|
|
4812
|
+
setDialog({
|
|
4813
|
+
action,
|
|
4814
|
+
preview,
|
|
4815
|
+
loading: true,
|
|
4816
|
+
submitting: false
|
|
4817
|
+
});
|
|
4818
|
+
const generated = await generateCommitMessage(sessionId, preview.fingerprint, controller.signal);
|
|
4819
|
+
setMessage(generated);
|
|
4820
|
+
setPrTitle(generated);
|
|
4821
|
+
setPrBody(`Summary: ${generated}\n\nChanges:\n- ${generated}`);
|
|
4822
|
+
setDialog({
|
|
4823
|
+
action,
|
|
4824
|
+
preview,
|
|
4825
|
+
loading: false,
|
|
4826
|
+
submitting: false
|
|
4827
|
+
});
|
|
4828
|
+
}).catch((error) => {
|
|
4829
|
+
if (!controller.signal.aborted) setDialog({
|
|
4830
|
+
action,
|
|
4831
|
+
loading: false,
|
|
4832
|
+
submitting: false,
|
|
4833
|
+
error: error instanceof Error ? error.message : t("diffActionFailed")
|
|
4834
|
+
});
|
|
4835
|
+
});
|
|
4836
|
+
}, [sessionId, t]);
|
|
4837
|
+
const confirm = useCallback(async () => {
|
|
4838
|
+
if (dialog?.preview === void 0 || dialog.action !== "push" && message.trim().length === 0) return;
|
|
4839
|
+
const { error: _error, ...pending } = dialog;
|
|
4840
|
+
setDialog({
|
|
4841
|
+
...pending,
|
|
4842
|
+
submitting: true
|
|
4843
|
+
});
|
|
4844
|
+
try {
|
|
4845
|
+
const result = await executeRepositoryAction(sessionId, {
|
|
4846
|
+
action: dialog.action,
|
|
4847
|
+
fingerprint: dialog.preview.fingerprint,
|
|
4848
|
+
message,
|
|
4849
|
+
includeUnstaged,
|
|
4850
|
+
...dialog.action === "create-pr" ? {
|
|
4851
|
+
prTitle,
|
|
4852
|
+
prBody,
|
|
4853
|
+
...baseBranch.trim() === "" ? {} : { baseBranch },
|
|
4854
|
+
draft
|
|
4855
|
+
} : {}
|
|
4856
|
+
});
|
|
4857
|
+
setDialog({
|
|
4858
|
+
...dialog,
|
|
4859
|
+
submitting: false,
|
|
4860
|
+
commit: result.commit,
|
|
4861
|
+
...result.pullRequestUrl === void 0 ? {} : { pullRequestUrl: result.pullRequestUrl }
|
|
4862
|
+
});
|
|
4863
|
+
} catch (error) {
|
|
4864
|
+
const completedCommit = typeof error === "object" && error !== null && "commit" in error && typeof error.commit === "string" ? error.commit : void 0;
|
|
4865
|
+
setDialog({
|
|
4866
|
+
...dialog,
|
|
4867
|
+
submitting: false,
|
|
4868
|
+
error: error instanceof Error ? error.message : t("diffActionFailed"),
|
|
4869
|
+
...completedCommit === void 0 ? {} : { commit: completedCommit }
|
|
4870
|
+
});
|
|
4871
|
+
}
|
|
4872
|
+
}, [
|
|
4873
|
+
baseBranch,
|
|
4874
|
+
dialog,
|
|
4875
|
+
draft,
|
|
4876
|
+
includeUnstaged,
|
|
4877
|
+
message,
|
|
4878
|
+
prBody,
|
|
4879
|
+
prTitle,
|
|
4880
|
+
sessionId,
|
|
4881
|
+
t
|
|
4882
|
+
]);
|
|
4883
|
+
const openCommentEditor = useCallback((path, anchor) => {
|
|
4884
|
+
setCommentEditor({
|
|
4885
|
+
path,
|
|
4886
|
+
...anchor
|
|
4887
|
+
});
|
|
4888
|
+
setCommentDraft("");
|
|
4889
|
+
setCommentError(void 0);
|
|
4890
|
+
}, []);
|
|
4891
|
+
const closeCommentEditor = useCallback(() => {
|
|
4892
|
+
setCommentEditor(void 0);
|
|
4893
|
+
setCommentDraft("");
|
|
4894
|
+
setCommentError(void 0);
|
|
4895
|
+
}, []);
|
|
4896
|
+
const submitComment = useCallback(async () => {
|
|
4897
|
+
if (commentEditor === void 0 || commentDraft.trim().length === 0 || commentBusy) return;
|
|
4898
|
+
setCommentBusy(true);
|
|
4899
|
+
setCommentError(void 0);
|
|
4900
|
+
try {
|
|
4901
|
+
const created = await addReviewComment(sessionId, {
|
|
4902
|
+
path: commentEditor.path,
|
|
4903
|
+
line: commentEditor.line,
|
|
4904
|
+
side: commentEditor.side,
|
|
4905
|
+
text: commentDraft.trim()
|
|
4906
|
+
});
|
|
4907
|
+
setLocalComments((list) => [...list, created]);
|
|
4908
|
+
closeCommentEditor();
|
|
4909
|
+
} catch (error) {
|
|
4910
|
+
setCommentError(error instanceof Error ? error.message : t("reviewCommentFailed"));
|
|
4911
|
+
} finally {
|
|
4912
|
+
setCommentBusy(false);
|
|
4913
|
+
}
|
|
4914
|
+
}, [
|
|
4915
|
+
closeCommentEditor,
|
|
4916
|
+
commentBusy,
|
|
4917
|
+
commentDraft,
|
|
4918
|
+
commentEditor,
|
|
4919
|
+
sessionId,
|
|
4920
|
+
t
|
|
4921
|
+
]);
|
|
4922
|
+
const removeComment = useCallback((id) => {
|
|
4923
|
+
setRemovedCommentIds((previous) => /* @__PURE__ */ new Set([...previous, id]));
|
|
4924
|
+
removeReviewComment(sessionId, id).catch(() => {
|
|
4925
|
+
setRemovedCommentIds((previous) => {
|
|
4926
|
+
const next = new Set(previous);
|
|
4927
|
+
next.delete(id);
|
|
4928
|
+
return next;
|
|
4929
|
+
});
|
|
4930
|
+
});
|
|
4931
|
+
}, [sessionId]);
|
|
4932
|
+
useEffect(() => {
|
|
4933
|
+
const projected = new Set((projection.reviewComments ?? []).map((comment) => comment.id));
|
|
4934
|
+
setLocalComments((list) => list.some((comment) => projected.has(comment.id)) ? list.filter((comment) => !projected.has(comment.id)) : list);
|
|
4935
|
+
setRemovedCommentIds((previous) => {
|
|
4936
|
+
const kept = [...previous].filter((id) => projected.has(id));
|
|
4937
|
+
return kept.length === previous.size ? previous : new Set(kept);
|
|
4938
|
+
});
|
|
4939
|
+
}, [projection.reviewComments]);
|
|
4940
|
+
const reviewComments = useMemo(() => {
|
|
4941
|
+
const merged = /* @__PURE__ */ new Map();
|
|
4942
|
+
for (const comment of projection.reviewComments ?? []) merged.set(comment.id, comment);
|
|
4943
|
+
for (const comment of localComments) merged.set(comment.id, comment);
|
|
4944
|
+
for (const id of removedCommentIds) merged.delete(id);
|
|
4945
|
+
return [...merged.values()];
|
|
4946
|
+
}, [
|
|
4947
|
+
localComments,
|
|
4948
|
+
projection.reviewComments,
|
|
4949
|
+
removedCommentIds
|
|
4950
|
+
]);
|
|
4951
|
+
useEffect(() => () => actionController.current?.abort(), []);
|
|
2732
4952
|
useEffect(() => {
|
|
2733
4953
|
if (!projection.owned || repository?.status !== "ready" || diff === void 0) closeDetails();
|
|
2734
4954
|
}, [
|
|
@@ -2739,61 +4959,431 @@ window.__ModuleLoader__.load({
|
|
|
2739
4959
|
]);
|
|
2740
4960
|
if (!projection.owned || repository?.status !== "ready" || diff === void 0) return null;
|
|
2741
4961
|
const branch = repository.detached === true ? t("repositoryDetached") : repository.branch ?? t("repositoryUnknownBranch");
|
|
2742
|
-
|
|
2743
|
-
|
|
4962
|
+
const availability = repositoryActionAvailability(repository);
|
|
4963
|
+
const anyActionAvailable = availability["commit"] || availability["commit-push"] || availability["push"] || availability["create-pr"];
|
|
4964
|
+
const menuItems = [
|
|
4965
|
+
{
|
|
4966
|
+
id: "commit",
|
|
4967
|
+
label: t("diffCommit"),
|
|
4968
|
+
disabled: !availability["commit"]
|
|
4969
|
+
},
|
|
4970
|
+
{
|
|
4971
|
+
id: "commit-push",
|
|
4972
|
+
label: t("diffCommitPush"),
|
|
4973
|
+
disabled: !availability["commit-push"]
|
|
4974
|
+
},
|
|
4975
|
+
{
|
|
4976
|
+
id: "push",
|
|
4977
|
+
label: t("diffPush"),
|
|
4978
|
+
disabled: !availability["push"]
|
|
4979
|
+
},
|
|
4980
|
+
{
|
|
4981
|
+
id: "create-pr",
|
|
4982
|
+
label: t("diffCreatePr"),
|
|
4983
|
+
disabled: !availability["create-pr"]
|
|
4984
|
+
}
|
|
4985
|
+
];
|
|
4986
|
+
const completed = dialog?.commit !== void 0 && dialog.error === void 0;
|
|
4987
|
+
const commentEditorNode = commentEditor === void 0 ? null : /* @__PURE__ */ jsxs("div", {
|
|
4988
|
+
style: diffCommentBlock,
|
|
2744
4989
|
children: [
|
|
2745
|
-
/* @__PURE__ */
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
4990
|
+
/* @__PURE__ */ jsx("textarea", {
|
|
4991
|
+
className: diffCommentTextareaClass,
|
|
4992
|
+
style: diffCommentTextarea,
|
|
4993
|
+
value: commentDraft,
|
|
4994
|
+
maxLength: 2e3,
|
|
4995
|
+
placeholder: t("reviewCommentPlaceholder"),
|
|
4996
|
+
autoFocus: true,
|
|
4997
|
+
onChange: (event) => setCommentDraft(event.currentTarget.value)
|
|
4998
|
+
}),
|
|
4999
|
+
commentError !== void 0 ? /* @__PURE__ */ jsx("p", {
|
|
5000
|
+
style: diffCommentError,
|
|
5001
|
+
children: commentError
|
|
5002
|
+
}) : null,
|
|
5003
|
+
/* @__PURE__ */ jsxs("div", {
|
|
5004
|
+
style: diffCommentActions,
|
|
5005
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
5006
|
+
type: "button",
|
|
5007
|
+
style: diffCommentActionButton,
|
|
5008
|
+
onClick: closeCommentEditor,
|
|
5009
|
+
children: t("reviewCommentCancel")
|
|
2760
5010
|
}), /* @__PURE__ */ jsx("button", {
|
|
2761
5011
|
type: "button",
|
|
2762
|
-
style:
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
5012
|
+
style: {
|
|
5013
|
+
...diffCommentActionButton,
|
|
5014
|
+
...diffCommentSubmitButton
|
|
5015
|
+
},
|
|
5016
|
+
disabled: commentBusy || commentDraft.trim().length === 0,
|
|
5017
|
+
onClick: () => void submitComment(),
|
|
5018
|
+
children: t("reviewCommentSubmit")
|
|
2766
5019
|
})]
|
|
2767
|
-
}),
|
|
2768
|
-
/* @__PURE__ */ jsxs("div", {
|
|
2769
|
-
style: diffSummary,
|
|
2770
|
-
children: [
|
|
2771
|
-
/* @__PURE__ */ jsx("span", { children: t("diffFiles", { count: diff.files }) }),
|
|
2772
|
-
/* @__PURE__ */ jsxs("span", {
|
|
2773
|
-
style: diffAdd,
|
|
2774
|
-
children: ["+", diff.additions]
|
|
2775
|
-
}),
|
|
2776
|
-
/* @__PURE__ */ jsxs("span", {
|
|
2777
|
-
style: diffDelete,
|
|
2778
|
-
children: ["−", diff.deletions]
|
|
2779
|
-
})
|
|
2780
|
-
]
|
|
2781
|
-
}),
|
|
2782
|
-
/* @__PURE__ */ jsxs("div", {
|
|
2783
|
-
style: diffBody,
|
|
2784
|
-
children: [diff.truncated ? /* @__PURE__ */ jsx("p", {
|
|
2785
|
-
style: diffNotice,
|
|
2786
|
-
children: t("diffTruncated")
|
|
2787
|
-
}) : null, files.length === 0 ? /* @__PURE__ */ jsx("p", {
|
|
2788
|
-
style: diffEmpty,
|
|
2789
|
-
children: t("diffEmpty")
|
|
2790
|
-
}) : files.map((file, index) => /* @__PURE__ */ jsx(DiffFileSection, {
|
|
2791
|
-
file,
|
|
2792
|
-
initiallyOpen: index === 0
|
|
2793
|
-
}, file.path))]
|
|
2794
5020
|
})
|
|
2795
5021
|
]
|
|
2796
5022
|
});
|
|
5023
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
5024
|
+
/* @__PURE__ */ jsxs("style", {
|
|
5025
|
+
"data-dsh-claude-repository-modal-styles": true,
|
|
5026
|
+
children: [
|
|
5027
|
+
diffModalCss,
|
|
5028
|
+
panelIconButtonCss,
|
|
5029
|
+
diffCommentCss
|
|
5030
|
+
]
|
|
5031
|
+
}),
|
|
5032
|
+
/* @__PURE__ */ jsxs("div", {
|
|
5033
|
+
style: {
|
|
5034
|
+
...diffPanel,
|
|
5035
|
+
...maximized ? diffPanelMaximized : {}
|
|
5036
|
+
},
|
|
5037
|
+
children: [
|
|
5038
|
+
/* @__PURE__ */ jsxs("header", {
|
|
5039
|
+
style: diffHeader,
|
|
5040
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
5041
|
+
style: diffHeaderTitle,
|
|
5042
|
+
children: [
|
|
5043
|
+
/* @__PURE__ */ jsx("span", {
|
|
5044
|
+
style: diffHeaderBranch,
|
|
5045
|
+
children: branch
|
|
5046
|
+
}),
|
|
5047
|
+
/* @__PURE__ */ jsx("span", {
|
|
5048
|
+
"aria-hidden": "true",
|
|
5049
|
+
children: "›"
|
|
5050
|
+
}),
|
|
5051
|
+
/* @__PURE__ */ jsx("span", { children: t("diffWorkingTree") })
|
|
5052
|
+
]
|
|
5053
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
5054
|
+
style: diffHeaderActions,
|
|
5055
|
+
children: [
|
|
5056
|
+
/* @__PURE__ */ jsxs("div", {
|
|
5057
|
+
style: diffSplitButton,
|
|
5058
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
5059
|
+
type: "button",
|
|
5060
|
+
style: {
|
|
5061
|
+
...diffCommitButton,
|
|
5062
|
+
...availability["commit"] ? {} : diffActionDisabled
|
|
5063
|
+
},
|
|
5064
|
+
disabled: !availability["commit"],
|
|
5065
|
+
onClick: () => openAction("commit"),
|
|
5066
|
+
children: t("diffCommit")
|
|
5067
|
+
}), /* @__PURE__ */ jsx(Menu, {
|
|
5068
|
+
open: menuOpen,
|
|
5069
|
+
items: menuItems,
|
|
5070
|
+
onSelect: (id) => {
|
|
5071
|
+
if (availability[id]) openAction(id);
|
|
5072
|
+
},
|
|
5073
|
+
onClose: () => setMenuOpen(false),
|
|
5074
|
+
align: "end",
|
|
5075
|
+
portal: true,
|
|
5076
|
+
anchor: /* @__PURE__ */ jsx("button", {
|
|
5077
|
+
type: "button",
|
|
5078
|
+
style: {
|
|
5079
|
+
...diffCommitMenuButton,
|
|
5080
|
+
...anyActionAvailable ? {} : diffActionDisabled
|
|
5081
|
+
},
|
|
5082
|
+
disabled: !anyActionAvailable,
|
|
5083
|
+
"aria-label": t("diffCommitMenu"),
|
|
5084
|
+
"aria-expanded": menuOpen,
|
|
5085
|
+
onClick: () => setMenuOpen((value) => !value),
|
|
5086
|
+
children: /* @__PURE__ */ jsx(IconChevronDownOutline14, {})
|
|
5087
|
+
})
|
|
5088
|
+
})]
|
|
5089
|
+
}),
|
|
5090
|
+
/* @__PURE__ */ jsx("button", {
|
|
5091
|
+
type: "button",
|
|
5092
|
+
className: panelIconButtonClass,
|
|
5093
|
+
"aria-label": maximized ? t("diffRestore") : t("diffMaximize"),
|
|
5094
|
+
onClick: toggleMaximized,
|
|
5095
|
+
children: maximized ? /* @__PURE__ */ jsx(RestorePanelIcon, {}) : /* @__PURE__ */ jsx(IconFullscreenOutline16, {})
|
|
5096
|
+
}),
|
|
5097
|
+
/* @__PURE__ */ jsx("button", {
|
|
5098
|
+
type: "button",
|
|
5099
|
+
className: panelIconButtonClass,
|
|
5100
|
+
"aria-label": t("diffClose"),
|
|
5101
|
+
onClick: closeDetails,
|
|
5102
|
+
children: /* @__PURE__ */ jsx(IconCloseOutline16, {})
|
|
5103
|
+
})
|
|
5104
|
+
]
|
|
5105
|
+
})]
|
|
5106
|
+
}),
|
|
5107
|
+
/* @__PURE__ */ jsxs("div", {
|
|
5108
|
+
style: diffSummary,
|
|
5109
|
+
children: [
|
|
5110
|
+
/* @__PURE__ */ jsx("span", { children: t("diffFiles", { count: diff.files }) }),
|
|
5111
|
+
/* @__PURE__ */ jsxs("span", {
|
|
5112
|
+
style: diffAdd,
|
|
5113
|
+
children: ["+", diff.additions]
|
|
5114
|
+
}),
|
|
5115
|
+
/* @__PURE__ */ jsxs("span", {
|
|
5116
|
+
style: diffDelete,
|
|
5117
|
+
children: ["−", diff.deletions]
|
|
5118
|
+
})
|
|
5119
|
+
]
|
|
5120
|
+
}),
|
|
5121
|
+
/* @__PURE__ */ jsxs("div", {
|
|
5122
|
+
ref: diffBodyRef,
|
|
5123
|
+
style: diffBody,
|
|
5124
|
+
children: [diff.truncated ? /* @__PURE__ */ jsx("p", {
|
|
5125
|
+
style: diffNotice,
|
|
5126
|
+
children: t("diffTruncated")
|
|
5127
|
+
}) : null, files.length === 0 ? /* @__PURE__ */ jsx("p", {
|
|
5128
|
+
style: diffEmpty,
|
|
5129
|
+
children: t("diffEmpty")
|
|
5130
|
+
}) : files.map((file, index) => /* @__PURE__ */ jsx(DiffFileSection, {
|
|
5131
|
+
file,
|
|
5132
|
+
initiallyOpen: index === 0,
|
|
5133
|
+
t,
|
|
5134
|
+
comments: reviewComments.filter((comment) => comment.path === file.path),
|
|
5135
|
+
editorAnchor: commentEditor !== void 0 && commentEditor.path === file.path ? commentEditor : void 0,
|
|
5136
|
+
editorNode: commentEditorNode,
|
|
5137
|
+
onOpenEditor: (anchor) => openCommentEditor(file.path, anchor),
|
|
5138
|
+
onRemoveComment: removeComment
|
|
5139
|
+
}, file.path))]
|
|
5140
|
+
})
|
|
5141
|
+
]
|
|
5142
|
+
}),
|
|
5143
|
+
/* @__PURE__ */ jsxs(Modal, {
|
|
5144
|
+
className: "dshClaudeRepositoryActionModal",
|
|
5145
|
+
contentClassName: "dshClaudeRepositoryActionModalContent",
|
|
5146
|
+
open: dialog !== void 0,
|
|
5147
|
+
onClose: closeDialog,
|
|
5148
|
+
title: dialog === void 0 ? t("diffCommit") : actionLabel(dialog.action, t),
|
|
5149
|
+
closeLabel: t("diffCancel"),
|
|
5150
|
+
description: t("diffConfirmDescription"),
|
|
5151
|
+
footer: /* @__PURE__ */ jsxs("div", {
|
|
5152
|
+
style: diffModalFooter,
|
|
5153
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
5154
|
+
type: "button",
|
|
5155
|
+
style: {
|
|
5156
|
+
...button,
|
|
5157
|
+
...diffModalButton
|
|
5158
|
+
},
|
|
5159
|
+
disabled: dialog?.submitting === true,
|
|
5160
|
+
onClick: closeDialog,
|
|
5161
|
+
children: completed ? t("diffDone") : t("diffCancel")
|
|
5162
|
+
}), !completed ? /* @__PURE__ */ jsx("button", {
|
|
5163
|
+
type: "button",
|
|
5164
|
+
style: {
|
|
5165
|
+
...primaryButton,
|
|
5166
|
+
...diffModalButton
|
|
5167
|
+
},
|
|
5168
|
+
disabled: dialog?.loading === true || dialog?.submitting === true || dialog?.preview === void 0 || dialog.action !== "push" && message.trim() === "",
|
|
5169
|
+
onClick: () => void confirm(),
|
|
5170
|
+
children: dialog?.submitting === true ? t("diffSubmitting") : t("diffConfirm")
|
|
5171
|
+
}) : null]
|
|
5172
|
+
}),
|
|
5173
|
+
children: [
|
|
5174
|
+
dialog?.loading === true ? /* @__PURE__ */ jsx("p", {
|
|
5175
|
+
style: diffModalStatus,
|
|
5176
|
+
children: t("diffGeneratingMessage")
|
|
5177
|
+
}) : null,
|
|
5178
|
+
dialog?.preview !== void 0 ? /* @__PURE__ */ jsxs("div", {
|
|
5179
|
+
style: diffModalBody,
|
|
5180
|
+
children: [
|
|
5181
|
+
/* @__PURE__ */ jsxs("div", {
|
|
5182
|
+
style: diffModalMeta,
|
|
5183
|
+
children: [/* @__PURE__ */ jsx("strong", {
|
|
5184
|
+
style: diffModalMetaText,
|
|
5185
|
+
title: dialog.preview.branch,
|
|
5186
|
+
children: dialog.action === "push" ? `${dialog.preview.branch} → ${dialog.preview.upstream ?? `origin/${dialog.preview.branch}`}` : dialog.preview.branch
|
|
5187
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
5188
|
+
style: diffModalFileState,
|
|
5189
|
+
children: dialog.action === "push" ? t("diffPushAhead", { count: dialog.preview.unpushedTruncated ? `${dialog.preview.unpushedCommits.length}+` : dialog.preview.unpushedCommits.length }) : t("diffFiles", { count: dialog.preview.files.length })
|
|
5190
|
+
})]
|
|
5191
|
+
}),
|
|
5192
|
+
dialog.action === "push" ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
|
|
5193
|
+
style: diffModalFiles,
|
|
5194
|
+
children: dialog.preview.unpushedCommits.map((commit) => /* @__PURE__ */ jsxs("div", {
|
|
5195
|
+
style: diffModalFile,
|
|
5196
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
5197
|
+
style: diffModalFilePath,
|
|
5198
|
+
title: commit.subject,
|
|
5199
|
+
children: commit.subject
|
|
5200
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
5201
|
+
style: diffModalFileState,
|
|
5202
|
+
children: commit.hash.slice(0, 8)
|
|
5203
|
+
})]
|
|
5204
|
+
}, commit.hash))
|
|
5205
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
5206
|
+
style: diffModalStatus,
|
|
5207
|
+
children: t("diffPushDescription")
|
|
5208
|
+
})] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
5209
|
+
/* @__PURE__ */ jsx("div", {
|
|
5210
|
+
style: diffModalFiles,
|
|
5211
|
+
children: dialog.preview.files.map((file) => /* @__PURE__ */ jsxs("div", {
|
|
5212
|
+
style: diffModalFile,
|
|
5213
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
5214
|
+
style: diffModalFilePath,
|
|
5215
|
+
title: file.path,
|
|
5216
|
+
children: file.path
|
|
5217
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
5218
|
+
style: diffModalFileState,
|
|
5219
|
+
children: file.untracked ? t("diffUntracked") : file.staged && file.unstaged ? t("diffStagedUnstaged") : file.staged ? t("diffStaged") : t("diffUnstaged")
|
|
5220
|
+
})]
|
|
5221
|
+
}, file.path))
|
|
5222
|
+
}),
|
|
5223
|
+
/* @__PURE__ */ jsxs("label", {
|
|
5224
|
+
style: diffModalCheckbox,
|
|
5225
|
+
children: [/* @__PURE__ */ jsx("input", {
|
|
5226
|
+
type: "checkbox",
|
|
5227
|
+
checked: includeUnstaged,
|
|
5228
|
+
disabled: !dialog.preview.hasUnstaged && !dialog.preview.hasUntracked,
|
|
5229
|
+
onChange: (event) => setIncludeUnstaged(event.currentTarget.checked)
|
|
5230
|
+
}), t("diffIncludeUnstaged")]
|
|
5231
|
+
}),
|
|
5232
|
+
/* @__PURE__ */ jsxs("label", {
|
|
5233
|
+
style: diffModalField,
|
|
5234
|
+
children: [t("diffCommitMessage"), /* @__PURE__ */ jsx("textarea", {
|
|
5235
|
+
style: diffModalTextarea,
|
|
5236
|
+
value: message,
|
|
5237
|
+
maxLength: 512,
|
|
5238
|
+
onChange: (event) => setMessage(event.currentTarget.value)
|
|
5239
|
+
})]
|
|
5240
|
+
})
|
|
5241
|
+
] }),
|
|
5242
|
+
dialog.action === "create-pr" ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
5243
|
+
/* @__PURE__ */ jsxs("label", {
|
|
5244
|
+
style: diffModalField,
|
|
5245
|
+
children: [t("diffPrTitle"), /* @__PURE__ */ jsx("input", {
|
|
5246
|
+
style: diffModalTextInput,
|
|
5247
|
+
value: prTitle,
|
|
5248
|
+
maxLength: 256,
|
|
5249
|
+
onChange: (event) => setPrTitle(event.currentTarget.value)
|
|
5250
|
+
})]
|
|
5251
|
+
}),
|
|
5252
|
+
/* @__PURE__ */ jsxs("label", {
|
|
5253
|
+
style: diffModalField,
|
|
5254
|
+
children: [t("diffPrBase"), /* @__PURE__ */ jsx("input", {
|
|
5255
|
+
style: diffModalTextInput,
|
|
5256
|
+
value: baseBranch,
|
|
5257
|
+
maxLength: 512,
|
|
5258
|
+
placeholder: t("diffPrBaseDefault"),
|
|
5259
|
+
onChange: (event) => setBaseBranch(event.currentTarget.value)
|
|
5260
|
+
})]
|
|
5261
|
+
}),
|
|
5262
|
+
/* @__PURE__ */ jsxs("label", {
|
|
5263
|
+
style: diffModalField,
|
|
5264
|
+
children: [t("diffPrDescription"), /* @__PURE__ */ jsx("textarea", {
|
|
5265
|
+
style: {
|
|
5266
|
+
...diffModalTextarea,
|
|
5267
|
+
minHeight: 240
|
|
5268
|
+
},
|
|
5269
|
+
value: prBody,
|
|
5270
|
+
maxLength: 8192,
|
|
5271
|
+
onChange: (event) => setPrBody(event.currentTarget.value)
|
|
5272
|
+
})]
|
|
5273
|
+
}),
|
|
5274
|
+
/* @__PURE__ */ jsxs("label", {
|
|
5275
|
+
style: diffModalCheckbox,
|
|
5276
|
+
children: [/* @__PURE__ */ jsx("input", {
|
|
5277
|
+
type: "checkbox",
|
|
5278
|
+
checked: draft,
|
|
5279
|
+
onChange: (event) => setDraft(event.currentTarget.checked)
|
|
5280
|
+
}), t("diffPrDraft")]
|
|
5281
|
+
})
|
|
5282
|
+
] }) : null,
|
|
5283
|
+
dialog.commit !== void 0 ? /* @__PURE__ */ jsx("p", {
|
|
5284
|
+
style: diffModalSuccess,
|
|
5285
|
+
children: dialog.action === "push" ? t("diffPushCompleted", { commit: dialog.commit.slice(0, 8) }) : t("diffCommitCompleted", { commit: dialog.commit.slice(0, 8) })
|
|
5286
|
+
}) : null,
|
|
5287
|
+
dialog.pullRequestUrl !== void 0 ? /* @__PURE__ */ jsx("a", {
|
|
5288
|
+
href: dialog.pullRequestUrl,
|
|
5289
|
+
target: "_blank",
|
|
5290
|
+
rel: "noopener noreferrer",
|
|
5291
|
+
children: t("diffOpenPr")
|
|
5292
|
+
}) : null
|
|
5293
|
+
]
|
|
5294
|
+
}) : null,
|
|
5295
|
+
dialog?.error !== void 0 ? /* @__PURE__ */ jsxs("p", {
|
|
5296
|
+
role: "alert",
|
|
5297
|
+
style: diffModalError,
|
|
5298
|
+
children: [dialog.error, dialog.commit === void 0 ? "" : ` ${t("diffCommitPreserved", { commit: dialog.commit.slice(0, 8) })}`]
|
|
5299
|
+
}) : null
|
|
5300
|
+
]
|
|
5301
|
+
})
|
|
5302
|
+
] });
|
|
5303
|
+
}
|
|
5304
|
+
//#endregion
|
|
5305
|
+
//#region src/client/ClaudeDiffOverlay.tsx
|
|
5306
|
+
const useClientLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
|
|
5307
|
+
function shouldRestoreFromEscape(event, root = document) {
|
|
5308
|
+
return event.key === "Escape" && root.querySelector("[role=\"dialog\"][aria-modal=\"true\"]") === null;
|
|
5309
|
+
}
|
|
5310
|
+
function workspaceBounds(overlay) {
|
|
5311
|
+
const frame = overlay.parentElement;
|
|
5312
|
+
if (frame === null) return void 0;
|
|
5313
|
+
const overlayRect = overlay.getBoundingClientRect();
|
|
5314
|
+
const candidates = Array.from(frame.children).filter((element) => element !== overlay).map((element) => element.getBoundingClientRect()).filter((rect) => rect.width > 0 && rect.height > 0);
|
|
5315
|
+
const insetCandidates = candidates.filter((rect) => rect.left > overlayRect.left);
|
|
5316
|
+
const workspace = (insetCandidates.length > 0 ? insetCandidates : candidates).reduce((largest, rect) => {
|
|
5317
|
+
if (largest === void 0 || rect.width * rect.height > largest.width * largest.height) return rect;
|
|
5318
|
+
return largest;
|
|
5319
|
+
}, void 0);
|
|
5320
|
+
if (workspace === void 0) return void 0;
|
|
5321
|
+
const left = Math.max(0, workspace.left - overlayRect.left);
|
|
5322
|
+
const top = Math.max(0, workspace.top - overlayRect.top);
|
|
5323
|
+
return {
|
|
5324
|
+
left,
|
|
5325
|
+
top,
|
|
5326
|
+
width: Math.max(0, Math.min(workspace.width, overlayRect.width - left)),
|
|
5327
|
+
height: Math.max(0, Math.min(workspace.height, overlayRect.height - top))
|
|
5328
|
+
};
|
|
5329
|
+
}
|
|
5330
|
+
function observeWorkspaceBounds(overlay, listener) {
|
|
5331
|
+
const frame = overlay.parentElement;
|
|
5332
|
+
if (frame === null) return () => {};
|
|
5333
|
+
const update = () => {
|
|
5334
|
+
const next = workspaceBounds(overlay);
|
|
5335
|
+
if (next !== void 0) listener(next);
|
|
5336
|
+
};
|
|
5337
|
+
update();
|
|
5338
|
+
const observer = typeof ResizeObserver === "undefined" ? void 0 : new ResizeObserver(update);
|
|
5339
|
+
observer?.observe(frame);
|
|
5340
|
+
for (const element of Array.from(frame.children)) observer?.observe(element);
|
|
5341
|
+
const mutation = typeof MutationObserver === "undefined" ? void 0 : new MutationObserver(update);
|
|
5342
|
+
mutation?.observe(frame, {
|
|
5343
|
+
attributes: true,
|
|
5344
|
+
childList: true
|
|
5345
|
+
});
|
|
5346
|
+
window.addEventListener("resize", update);
|
|
5347
|
+
return () => {
|
|
5348
|
+
observer?.disconnect();
|
|
5349
|
+
mutation?.disconnect();
|
|
5350
|
+
window.removeEventListener("resize", update);
|
|
5351
|
+
};
|
|
5352
|
+
}
|
|
5353
|
+
function ClaudeDiffOverlay({ children, onRestore }) {
|
|
5354
|
+
const ref = useRef(null);
|
|
5355
|
+
const [bounds, setBounds] = useState();
|
|
5356
|
+
useClientLayoutEffect(() => {
|
|
5357
|
+
const overlay = ref.current?.closest("[data-shell-overlay]");
|
|
5358
|
+
if (overlay === void 0 || overlay === null) return;
|
|
5359
|
+
return observeWorkspaceBounds(overlay, (next) => {
|
|
5360
|
+
setBounds((current) => current?.left === next.left && current.top === next.top && current.width === next.width && current.height === next.height ? current : next);
|
|
5361
|
+
});
|
|
5362
|
+
}, []);
|
|
5363
|
+
useEffect(() => {
|
|
5364
|
+
const escape = (event) => {
|
|
5365
|
+
if (shouldRestoreFromEscape(event)) onRestore();
|
|
5366
|
+
};
|
|
5367
|
+
window.addEventListener("keydown", escape);
|
|
5368
|
+
return () => window.removeEventListener("keydown", escape);
|
|
5369
|
+
}, [onRestore]);
|
|
5370
|
+
return /* @__PURE__ */ jsx("div", {
|
|
5371
|
+
ref,
|
|
5372
|
+
"data-dsh-claude-diff-overlay": true,
|
|
5373
|
+
style: {
|
|
5374
|
+
position: "absolute",
|
|
5375
|
+
left: bounds?.left ?? 0,
|
|
5376
|
+
top: bounds?.top ?? 0,
|
|
5377
|
+
width: bounds?.width ?? 0,
|
|
5378
|
+
height: bounds?.height ?? 0,
|
|
5379
|
+
visibility: bounds === void 0 ? "hidden" : "visible",
|
|
5380
|
+
padding: 8,
|
|
5381
|
+
boxSizing: "border-box",
|
|
5382
|
+
background: "var(--dsw-alias-bg-base)",
|
|
5383
|
+
pointerEvents: bounds === void 0 ? "none" : "auto"
|
|
5384
|
+
},
|
|
5385
|
+
children
|
|
5386
|
+
});
|
|
2797
5387
|
}
|
|
2798
5388
|
//#endregion
|
|
2799
5389
|
//#region src/client/hero-dom-bridge.ts
|
|
@@ -2849,16 +5439,16 @@ window.__ModuleLoader__.load({
|
|
|
2849
5439
|
"saving-worktree",
|
|
2850
5440
|
"switching-branch"
|
|
2851
5441
|
]);
|
|
2852
|
-
function record
|
|
5442
|
+
function record(value) {
|
|
2853
5443
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
2854
5444
|
}
|
|
2855
5445
|
function setupResult(value) {
|
|
2856
|
-
const item = record
|
|
5446
|
+
const item = record(value);
|
|
2857
5447
|
if (item === void 0 || item.mode !== "checkout" && item.mode !== "worktree" || typeof item.root !== "string" || typeof item.path !== "string" || typeof item.branch !== "string" || item.leaseId !== void 0 && typeof item.leaseId !== "string") return void 0;
|
|
2858
5448
|
return item;
|
|
2859
5449
|
}
|
|
2860
5450
|
function parseRepositorySetupEvent(line, onProgress) {
|
|
2861
|
-
const event = record
|
|
5451
|
+
const event = record(JSON.parse(line));
|
|
2862
5452
|
if (event?.type === "progress" && typeof event.stage === "string" && HOST_STAGES.has(event.stage)) {
|
|
2863
5453
|
onProgress(event.stage);
|
|
2864
5454
|
return;
|
|
@@ -3367,7 +5957,7 @@ window.__ModuleLoader__.load({
|
|
|
3367
5957
|
children: [branches === void 0 ? /* @__PURE__ */ jsx("span", {
|
|
3368
5958
|
style: heroRepositoryStatus,
|
|
3369
5959
|
children: error ?? t("repositoryBranchesLoading")
|
|
3370
|
-
}) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(ClaudeHeroRepositoryCapsule, {
|
|
5960
|
+
}) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(ClaudeHeroRepositoryCapsule, {
|
|
3371
5961
|
branches: availableBranches,
|
|
3372
5962
|
selected,
|
|
3373
5963
|
worktree,
|
|
@@ -3402,160 +5992,6 @@ window.__ModuleLoader__.load({
|
|
|
3402
5992
|
}), portal);
|
|
3403
5993
|
}
|
|
3404
5994
|
//#endregion
|
|
3405
|
-
//#region src/client/projection.ts
|
|
3406
|
-
const EMPTY_CLAUDE_PROJECTION = {
|
|
3407
|
-
schemaVersion: 1,
|
|
3408
|
-
revision: 0,
|
|
3409
|
-
owned: false,
|
|
3410
|
-
commands: [],
|
|
3411
|
-
activities: []
|
|
3412
|
-
};
|
|
3413
|
-
const POLL_INTERVAL_MS = 2e3;
|
|
3414
|
-
const MAX_ACTIVITIES = 1e4;
|
|
3415
|
-
const MAX_COMMANDS = 2e3;
|
|
3416
|
-
const MAX_REPOSITORY_TEXT_CHARS = 1024;
|
|
3417
|
-
const MAX_DIFF_CHARS = 262144;
|
|
3418
|
-
function record(value) {
|
|
3419
|
-
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
3420
|
-
}
|
|
3421
|
-
function nonNegativeInteger(value) {
|
|
3422
|
-
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
3423
|
-
}
|
|
3424
|
-
function optionalBoundedString(value) {
|
|
3425
|
-
return value === void 0 || typeof value === "string" && value.length <= MAX_REPOSITORY_TEXT_CHARS;
|
|
3426
|
-
}
|
|
3427
|
-
function validateRepository(value) {
|
|
3428
|
-
const repository = record(value);
|
|
3429
|
-
if (repository === void 0 || ![
|
|
3430
|
-
"ready",
|
|
3431
|
-
"not-repository",
|
|
3432
|
-
"unavailable"
|
|
3433
|
-
].includes(String(repository.status)) || typeof repository.cwd !== "string" || repository.cwd.length > MAX_REPOSITORY_TEXT_CHARS || !optionalBoundedString(repository.root) || !optionalBoundedString(repository.branch) || !optionalBoundedString(repository.remote) || repository.detached !== void 0 && typeof repository.detached !== "boolean" || repository.worktree !== void 0 && typeof repository.worktree !== "boolean" || repository.dirty !== void 0 && typeof repository.dirty !== "boolean") return false;
|
|
3434
|
-
if (repository.diff !== void 0) {
|
|
3435
|
-
const diff = record(repository.diff);
|
|
3436
|
-
if (diff === void 0 || !nonNegativeInteger(diff.additions) || !nonNegativeInteger(diff.deletions) || !nonNegativeInteger(diff.files) || typeof diff.truncated !== "boolean" || diff.patch !== void 0 && (typeof diff.patch !== "string" || diff.patch.length > MAX_DIFF_CHARS)) return false;
|
|
3437
|
-
}
|
|
3438
|
-
if (repository.pullRequest === void 0) return true;
|
|
3439
|
-
const pullRequest = record(repository.pullRequest);
|
|
3440
|
-
if (pullRequest === void 0 || !Number.isSafeInteger(pullRequest.number) || Number(pullRequest.number) <= 0 || typeof pullRequest.title !== "string" || pullRequest.title.length > MAX_REPOSITORY_TEXT_CHARS || typeof pullRequest.url !== "string" || pullRequest.url.length > MAX_REPOSITORY_TEXT_CHARS || ![
|
|
3441
|
-
"open",
|
|
3442
|
-
"closed",
|
|
3443
|
-
"merged"
|
|
3444
|
-
].includes(String(pullRequest.state)) || typeof pullRequest.draft !== "boolean" || ![
|
|
3445
|
-
"approved",
|
|
3446
|
-
"changes-requested",
|
|
3447
|
-
"review-required",
|
|
3448
|
-
"none"
|
|
3449
|
-
].includes(String(pullRequest.review)) || ![
|
|
3450
|
-
"passing",
|
|
3451
|
-
"pending",
|
|
3452
|
-
"failing",
|
|
3453
|
-
"none"
|
|
3454
|
-
].includes(String(pullRequest.checks)) || !optionalBoundedString(pullRequest.mergeState) || !optionalBoundedString(pullRequest.author) || !optionalBoundedString(pullRequest.baseBranch) || pullRequest.createdAt !== void 0 && (typeof pullRequest.createdAt !== "string" || !Number.isFinite(Date.parse(pullRequest.createdAt)))) return false;
|
|
3455
|
-
try {
|
|
3456
|
-
const url = new URL(pullRequest.url);
|
|
3457
|
-
return url.protocol === "https:" && url.hostname === "github.com";
|
|
3458
|
-
} catch {
|
|
3459
|
-
return false;
|
|
3460
|
-
}
|
|
3461
|
-
}
|
|
3462
|
-
/** Validate the public route envelope before publishing it to UI components. */
|
|
3463
|
-
function parseClaudeClientProjection(value) {
|
|
3464
|
-
const input = record(value);
|
|
3465
|
-
if (input === void 0 || input.schemaVersion !== 1 || !nonNegativeInteger(input.revision) || typeof input.owned !== "boolean" || !Array.isArray(input.commands) || input.commands.length > MAX_COMMANDS || !Array.isArray(input.activities) || input.activities.length > MAX_ACTIVITIES) throw new Error("invalid Claude sidecar projection");
|
|
3466
|
-
for (const item of input.commands) {
|
|
3467
|
-
const command = record(item);
|
|
3468
|
-
if (command === void 0 || typeof command.publicName !== "string" || typeof command.claudeName !== "string" || typeof command.description !== "string" || command.hint !== void 0 && typeof command.hint !== "string" || typeof command.prefixed !== "boolean") throw new Error("invalid Claude command projection");
|
|
3469
|
-
}
|
|
3470
|
-
for (const item of input.activities) {
|
|
3471
|
-
const activity = record(item);
|
|
3472
|
-
if (activity === void 0 || !nonNegativeInteger(activity.turn) || !nonNegativeInteger(activity.step) || !nonNegativeInteger(activity.ordinal) || typeof activity.kind !== "string") throw new Error("invalid Claude sidecar activity");
|
|
3473
|
-
}
|
|
3474
|
-
if (input.contextUsage !== void 0 && record(input.contextUsage) === void 0) throw new Error("invalid Claude context projection");
|
|
3475
|
-
const tasks = input.tasks === void 0 ? void 0 : record(input.tasks);
|
|
3476
|
-
if (tasks !== void 0 && !Array.isArray(tasks.tasks)) throw new Error("invalid Claude tasks projection");
|
|
3477
|
-
if (input.repository !== void 0 && !validateRepository(input.repository)) throw new Error("invalid Claude repository projection");
|
|
3478
|
-
return input;
|
|
3479
|
-
}
|
|
3480
|
-
/** Create one lazy source: active subscribers trigger an immediate load and bounded polling. */
|
|
3481
|
-
function createClaudeProjectionSource(sessionId, fetchProjection = fetch, pollIntervalMs = POLL_INTERVAL_MS) {
|
|
3482
|
-
let snapshot = EMPTY_CLAUDE_PROJECTION;
|
|
3483
|
-
let timer;
|
|
3484
|
-
let controller;
|
|
3485
|
-
let disposed = false;
|
|
3486
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
3487
|
-
const schedule = () => {
|
|
3488
|
-
if (disposed || listeners.size === 0) return;
|
|
3489
|
-
timer = setTimeout(() => {
|
|
3490
|
-
refresh();
|
|
3491
|
-
}, pollIntervalMs);
|
|
3492
|
-
};
|
|
3493
|
-
const refresh = async () => {
|
|
3494
|
-
if (disposed || listeners.size === 0) return;
|
|
3495
|
-
controller?.abort();
|
|
3496
|
-
controller = new AbortController();
|
|
3497
|
-
try {
|
|
3498
|
-
const response = await fetchProjection(`${CLAUDE_PROJECTION_PATH}/${encodeURIComponent(sessionId)}`, {
|
|
3499
|
-
headers: { accept: "application/json" },
|
|
3500
|
-
signal: controller.signal
|
|
3501
|
-
});
|
|
3502
|
-
if (!response.ok) throw new Error(`Claude projection request failed (${response.status})`);
|
|
3503
|
-
const next = parseClaudeClientProjection(await response.json());
|
|
3504
|
-
const commandCatalogChanged = JSON.stringify(next.commands) !== JSON.stringify(snapshot.commands);
|
|
3505
|
-
const repositoryChanged = JSON.stringify(next.repository) !== JSON.stringify(snapshot.repository);
|
|
3506
|
-
if (next.revision !== snapshot.revision || next.owned !== snapshot.owned || commandCatalogChanged || repositoryChanged) {
|
|
3507
|
-
snapshot = next;
|
|
3508
|
-
for (const listener of [...listeners]) listener();
|
|
3509
|
-
}
|
|
3510
|
-
} catch (error) {
|
|
3511
|
-
if (error instanceof DOMException && error.name === "AbortError") return;
|
|
3512
|
-
} finally {
|
|
3513
|
-
controller = void 0;
|
|
3514
|
-
schedule();
|
|
3515
|
-
}
|
|
3516
|
-
};
|
|
3517
|
-
return {
|
|
3518
|
-
getSnapshot: () => snapshot,
|
|
3519
|
-
subscribe(listener) {
|
|
3520
|
-
if (disposed) return () => {};
|
|
3521
|
-
const wasIdle = listeners.size === 0;
|
|
3522
|
-
listeners.add(listener);
|
|
3523
|
-
if (wasIdle) refresh();
|
|
3524
|
-
return () => {
|
|
3525
|
-
listeners.delete(listener);
|
|
3526
|
-
if (listeners.size !== 0) return;
|
|
3527
|
-
if (timer !== void 0) clearTimeout(timer);
|
|
3528
|
-
timer = void 0;
|
|
3529
|
-
controller?.abort();
|
|
3530
|
-
controller = void 0;
|
|
3531
|
-
};
|
|
3532
|
-
},
|
|
3533
|
-
dispose() {
|
|
3534
|
-
disposed = true;
|
|
3535
|
-
listeners.clear();
|
|
3536
|
-
if (timer !== void 0) clearTimeout(timer);
|
|
3537
|
-
timer = void 0;
|
|
3538
|
-
controller?.abort();
|
|
3539
|
-
controller = void 0;
|
|
3540
|
-
}
|
|
3541
|
-
};
|
|
3542
|
-
}
|
|
3543
|
-
var ClaudeProjectionStore = class {
|
|
3544
|
-
#sources = /* @__PURE__ */ new Map();
|
|
3545
|
-
source(sessionId) {
|
|
3546
|
-
let source = this.#sources.get(sessionId);
|
|
3547
|
-
if (source === void 0) {
|
|
3548
|
-
source = createClaudeProjectionSource(sessionId);
|
|
3549
|
-
this.#sources.set(sessionId, source);
|
|
3550
|
-
}
|
|
3551
|
-
return source;
|
|
3552
|
-
}
|
|
3553
|
-
dispose() {
|
|
3554
|
-
for (const source of this.#sources.values()) source.dispose();
|
|
3555
|
-
this.#sources.clear();
|
|
3556
|
-
}
|
|
3557
|
-
};
|
|
3558
|
-
//#endregion
|
|
3559
5995
|
//#region src/client/claude-command-source.ts
|
|
3560
5996
|
const SOURCE_NAME = "Claude Code";
|
|
3561
5997
|
function commandsFor(store, session) {
|
|
@@ -3814,6 +6250,11 @@ window.__ModuleLoader__.load({
|
|
|
3814
6250
|
failed: "失败",
|
|
3815
6251
|
done: "完成",
|
|
3816
6252
|
subagent: "子代理",
|
|
6253
|
+
usedTool: "使用了 1 个工具",
|
|
6254
|
+
usedTools: "使用了 {count} 个工具",
|
|
6255
|
+
toolInput: "输入",
|
|
6256
|
+
toolOutput: "输出",
|
|
6257
|
+
toolError: "错误",
|
|
3817
6258
|
tokens: "{count} 个 token",
|
|
3818
6259
|
doctor: "运行诊断",
|
|
3819
6260
|
refreshing: "诊断中…",
|
|
@@ -3878,6 +6319,7 @@ window.__ModuleLoader__.load({
|
|
|
3878
6319
|
tasksViewActivity: "查看活动",
|
|
3879
6320
|
tasksHideActivity: "收起活动",
|
|
3880
6321
|
tasksRunningCount: "{count} 个运行中任务",
|
|
6322
|
+
repositoryRateLimited: "Claude 额度限流中",
|
|
3881
6323
|
tasksTurnRunning: "{count} 个任务执行中",
|
|
3882
6324
|
tasksTurnCompleted: "{count} 个任务已完成",
|
|
3883
6325
|
tasksTurnFailed: "{failed} 个任务失败,{completed} 个已完成",
|
|
@@ -3933,6 +6375,8 @@ window.__ModuleLoader__.load({
|
|
|
3933
6375
|
repositoryState_open: "开放",
|
|
3934
6376
|
repositoryState_closed: "已关闭",
|
|
3935
6377
|
repositoryState_merged: "已合并",
|
|
6378
|
+
repositoryMergedInto: "已合并到 {branch}",
|
|
6379
|
+
repositoryMergedAgo: "{age}前",
|
|
3936
6380
|
repositoryChecks: "检查",
|
|
3937
6381
|
repositoryChecks_passing: "检查通过",
|
|
3938
6382
|
repositoryChecks_pending: "检查进行中",
|
|
@@ -3953,7 +6397,49 @@ window.__ModuleLoader__.load({
|
|
|
3953
6397
|
diffFiles: "{count} 个已修改文件",
|
|
3954
6398
|
diffFilesShort: "{count} 个文件",
|
|
3955
6399
|
diffTruncated: "Diff 超出安全显示上限。请在终端中查看完整内容。",
|
|
3956
|
-
diffEmpty: "没有可显示的 tracked 文件改动"
|
|
6400
|
+
diffEmpty: "没有可显示的 tracked 文件改动",
|
|
6401
|
+
diffMaximize: "最大化 Diff 面板",
|
|
6402
|
+
diffRestore: "还原 Diff 面板",
|
|
6403
|
+
diffCommit: "Commit",
|
|
6404
|
+
diffCommitMenu: "打开提交操作菜单",
|
|
6405
|
+
diffCommitPush: "Commit & Push…",
|
|
6406
|
+
diffPush: "Push",
|
|
6407
|
+
diffCreatePr: "Create PR…",
|
|
6408
|
+
diffConfirmDescription: "确认仓库快照和将要执行的 Git 操作。",
|
|
6409
|
+
diffPushDescription: "将本地未推送的 commit 推送到远端分支。",
|
|
6410
|
+
diffPushAhead: "{count} 个未推送的 commit",
|
|
6411
|
+
diffPushCompleted: "已推送 commit {commit}",
|
|
6412
|
+
diffGeneratingMessage: "正在读取仓库并生成 commit message…",
|
|
6413
|
+
diffActionFailed: "仓库操作失败。",
|
|
6414
|
+
diffIncludeUnstaged: "包含 unstaged 和 untracked 改动",
|
|
6415
|
+
diffCommitMessage: "Commit message",
|
|
6416
|
+
diffStaged: "Staged",
|
|
6417
|
+
diffUnstaged: "Unstaged",
|
|
6418
|
+
diffStagedUnstaged: "Staged + unstaged",
|
|
6419
|
+
diffUntracked: "Untracked",
|
|
6420
|
+
diffPrTitle: "PR title",
|
|
6421
|
+
diffPrBase: "Base branch",
|
|
6422
|
+
diffPrBaseDefault: "使用远端默认分支",
|
|
6423
|
+
diffPrDescription: "PR description(仅 Summary 与 Changes)",
|
|
6424
|
+
diffPrDraft: "创建为 Draft PR",
|
|
6425
|
+
diffCancel: "取消",
|
|
6426
|
+
diffConfirm: "确认",
|
|
6427
|
+
diffSubmitting: "执行中…",
|
|
6428
|
+
diffDone: "完成",
|
|
6429
|
+
diffCommitCompleted: "已创建 commit {commit}",
|
|
6430
|
+
diffCommitPreserved: "本地 commit {commit} 已保留。",
|
|
6431
|
+
diffOpenPr: "打开 Pull Request",
|
|
6432
|
+
reviewCommentAdd: "添加行评论",
|
|
6433
|
+
reviewCommentPlaceholder: "请求更改",
|
|
6434
|
+
reviewCommentSubmit: "注释",
|
|
6435
|
+
reviewCommentCancel: "取消",
|
|
6436
|
+
reviewCommentRemove: "删除评论",
|
|
6437
|
+
reviewCommentFailed: "评论操作失败。",
|
|
6438
|
+
reviewCommentsClear: "清除全部评论",
|
|
6439
|
+
reviewCommentsSend: "发送评论",
|
|
6440
|
+
reviewCommentsSendDraft: "请处理以上代码评论。",
|
|
6441
|
+
reviewCommentOldSide: "旧代码第 {line} 行",
|
|
6442
|
+
reviewCommentNewSide: "第 {line} 行"
|
|
3957
6443
|
};
|
|
3958
6444
|
const en = {
|
|
3959
6445
|
nav: "Claude Code",
|
|
@@ -3966,6 +6452,11 @@ window.__ModuleLoader__.load({
|
|
|
3966
6452
|
failed: "Failed",
|
|
3967
6453
|
done: "Done",
|
|
3968
6454
|
subagent: "Subagent",
|
|
6455
|
+
usedTool: "Used 1 tool",
|
|
6456
|
+
usedTools: "Used {count} tools",
|
|
6457
|
+
toolInput: "Input",
|
|
6458
|
+
toolOutput: "Output",
|
|
6459
|
+
toolError: "Error",
|
|
3969
6460
|
tokens: "{count} tokens",
|
|
3970
6461
|
doctor: "Run Doctor",
|
|
3971
6462
|
refreshing: "Running Doctor…",
|
|
@@ -4030,6 +6521,7 @@ window.__ModuleLoader__.load({
|
|
|
4030
6521
|
tasksViewActivity: "View activity",
|
|
4031
6522
|
tasksHideActivity: "Hide activity",
|
|
4032
6523
|
tasksRunningCount: "{count} running task(s)",
|
|
6524
|
+
repositoryRateLimited: "Rate limited",
|
|
4033
6525
|
tasksTurnRunning: "{count} task(s) running",
|
|
4034
6526
|
tasksTurnCompleted: "{count} task(s) completed",
|
|
4035
6527
|
tasksTurnFailed: "{failed} failed, {completed} completed",
|
|
@@ -4085,6 +6577,8 @@ window.__ModuleLoader__.load({
|
|
|
4085
6577
|
repositoryState_open: "Open",
|
|
4086
6578
|
repositoryState_closed: "Closed",
|
|
4087
6579
|
repositoryState_merged: "Merged",
|
|
6580
|
+
repositoryMergedInto: "Merged into {branch}",
|
|
6581
|
+
repositoryMergedAgo: "{age} ago",
|
|
4088
6582
|
repositoryChecks: "Checks",
|
|
4089
6583
|
repositoryChecks_passing: "Checks passing",
|
|
4090
6584
|
repositoryChecks_pending: "Checks pending",
|
|
@@ -4105,10 +6599,67 @@ window.__ModuleLoader__.load({
|
|
|
4105
6599
|
diffFiles: "{count} modified file(s)",
|
|
4106
6600
|
diffFilesShort: "{count} files",
|
|
4107
6601
|
diffTruncated: "The diff exceeds the safe display limit. Use the terminal to inspect the complete content.",
|
|
4108
|
-
diffEmpty: "No tracked file changes to display"
|
|
6602
|
+
diffEmpty: "No tracked file changes to display",
|
|
6603
|
+
diffMaximize: "Maximize diff panel",
|
|
6604
|
+
diffRestore: "Restore diff panel",
|
|
6605
|
+
diffCommit: "Commit",
|
|
6606
|
+
diffCommitMenu: "Open commit actions",
|
|
6607
|
+
diffCommitPush: "Commit & Push…",
|
|
6608
|
+
diffPush: "Push",
|
|
6609
|
+
diffCreatePr: "Create PR…",
|
|
6610
|
+
diffConfirmDescription: "Confirm the repository snapshot and Git operation.",
|
|
6611
|
+
diffPushDescription: "Push local commits to the remote branch.",
|
|
6612
|
+
diffPushAhead: "{count} unpushed commit(s)",
|
|
6613
|
+
diffPushCompleted: "Pushed commit {commit}",
|
|
6614
|
+
diffGeneratingMessage: "Reading the repository and generating a commit message…",
|
|
6615
|
+
diffActionFailed: "Repository action failed.",
|
|
6616
|
+
diffIncludeUnstaged: "Include unstaged and untracked changes",
|
|
6617
|
+
diffCommitMessage: "Commit message",
|
|
6618
|
+
diffStaged: "Staged",
|
|
6619
|
+
diffUnstaged: "Unstaged",
|
|
6620
|
+
diffStagedUnstaged: "Staged + unstaged",
|
|
6621
|
+
diffUntracked: "Untracked",
|
|
6622
|
+
diffPrTitle: "PR title",
|
|
6623
|
+
diffPrBase: "Base branch",
|
|
6624
|
+
diffPrBaseDefault: "Use the remote default branch",
|
|
6625
|
+
diffPrDescription: "PR description (Summary and Changes only)",
|
|
6626
|
+
diffPrDraft: "Create as a Draft PR",
|
|
6627
|
+
diffCancel: "Cancel",
|
|
6628
|
+
diffConfirm: "Confirm",
|
|
6629
|
+
diffSubmitting: "Working…",
|
|
6630
|
+
diffDone: "Done",
|
|
6631
|
+
diffCommitCompleted: "Created commit {commit}",
|
|
6632
|
+
diffCommitPreserved: "Local commit {commit} was preserved.",
|
|
6633
|
+
diffOpenPr: "Open pull request",
|
|
6634
|
+
reviewCommentAdd: "Add line comment",
|
|
6635
|
+
reviewCommentPlaceholder: "Request changes",
|
|
6636
|
+
reviewCommentSubmit: "Comment",
|
|
6637
|
+
reviewCommentCancel: "Cancel",
|
|
6638
|
+
reviewCommentRemove: "Remove comment",
|
|
6639
|
+
reviewCommentFailed: "The comment could not be saved.",
|
|
6640
|
+
reviewCommentsClear: "Clear all comments",
|
|
6641
|
+
reviewCommentsSend: "Send comments",
|
|
6642
|
+
reviewCommentsSendDraft: "Please address the attached review comments.",
|
|
6643
|
+
reviewCommentOldSide: "Old line {line}",
|
|
6644
|
+
reviewCommentNewSide: "Line {line}"
|
|
4109
6645
|
};
|
|
4110
6646
|
//#endregion
|
|
4111
6647
|
//#region src/client/index.tsx
|
|
6648
|
+
function MaximizedDiff({ source, t, sessionId, closeDetails, restore }) {
|
|
6649
|
+
const snapshot = useSyncExternalStore(source.subscribe, source.getSnapshot, source.getSnapshot);
|
|
6650
|
+
const useClaudeProjection = (selector) => selector(snapshot);
|
|
6651
|
+
return /* @__PURE__ */ jsx(ClaudeDiffOverlay, {
|
|
6652
|
+
onRestore: restore,
|
|
6653
|
+
children: /* @__PURE__ */ jsx(ClaudeDiffPanel, {
|
|
6654
|
+
useClaudeProjection,
|
|
6655
|
+
t,
|
|
6656
|
+
sessionId,
|
|
6657
|
+
maximized: true,
|
|
6658
|
+
closeDetails,
|
|
6659
|
+
toggleMaximized: restore
|
|
6660
|
+
})
|
|
6661
|
+
});
|
|
6662
|
+
}
|
|
4112
6663
|
const name = "dsh-claude-client";
|
|
4113
6664
|
const inject = [
|
|
4114
6665
|
"slots",
|
|
@@ -4148,17 +6699,30 @@ window.__ModuleLoader__.load({
|
|
|
4148
6699
|
}, ClaudeActivityNode));
|
|
4149
6700
|
const layout = ctx.get("layout");
|
|
4150
6701
|
let disposePluginDetails;
|
|
6702
|
+
let disposeDiffOverlay;
|
|
4151
6703
|
let disposeExpandedDetailsResize;
|
|
4152
6704
|
let detailsSessionId;
|
|
6705
|
+
const restoreDiff = () => {
|
|
6706
|
+
if (disposeDiffOverlay === void 0) return;
|
|
6707
|
+
disposeDiffOverlay();
|
|
6708
|
+
disposeDiffOverlay = void 0;
|
|
6709
|
+
layout?.openDetails();
|
|
6710
|
+
disposeExpandedDetailsResize = enableExpandedDetailsResize();
|
|
6711
|
+
};
|
|
4153
6712
|
const closePluginDetails = () => {
|
|
4154
|
-
if (disposePluginDetails === void 0) return;
|
|
6713
|
+
if (disposePluginDetails === void 0 && disposeDiffOverlay === void 0 && disposeExpandedDetailsResize === void 0 && detailsSessionId === void 0) return;
|
|
6714
|
+
disposeDiffOverlay?.();
|
|
6715
|
+
disposeDiffOverlay = void 0;
|
|
4155
6716
|
disposeExpandedDetailsResize?.();
|
|
4156
6717
|
disposeExpandedDetailsResize = void 0;
|
|
4157
|
-
disposePluginDetails();
|
|
6718
|
+
disposePluginDetails?.();
|
|
4158
6719
|
disposePluginDetails = void 0;
|
|
4159
6720
|
detailsSessionId = void 0;
|
|
4160
6721
|
layout?.closeDetails();
|
|
4161
6722
|
};
|
|
6723
|
+
ctx.effect(() => ctx.slots.onEntryError((key, entry) => {
|
|
6724
|
+
if (key === "shell.overlay" && entry.options.id === "claude-diff-overlay") restoreDiff();
|
|
6725
|
+
}), "dsh-claude: diff overlay recovery");
|
|
4162
6726
|
const openTasksPanel = (sessionId, turn) => {
|
|
4163
6727
|
closePluginDetails();
|
|
4164
6728
|
try {
|
|
@@ -4181,27 +6745,64 @@ window.__ModuleLoader__.load({
|
|
|
4181
6745
|
};
|
|
4182
6746
|
const openDiffPanel = (sessionId) => {
|
|
4183
6747
|
closePluginDetails();
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
6748
|
+
detailsSessionId = sessionId;
|
|
6749
|
+
const registerDetails = () => {
|
|
6750
|
+
try {
|
|
6751
|
+
disposePluginDetails = ctx.slots.register({
|
|
6752
|
+
name: "details",
|
|
6753
|
+
priority: -10,
|
|
6754
|
+
locale: namespace,
|
|
6755
|
+
inject: () => ({
|
|
6756
|
+
t,
|
|
6757
|
+
sessionId,
|
|
6758
|
+
maximized: false,
|
|
6759
|
+
closeDetails: closePluginDetails,
|
|
6760
|
+
toggleMaximized: maximizeDiff
|
|
6761
|
+
})
|
|
6762
|
+
}, ClaudeDiffPanel);
|
|
6763
|
+
} catch {
|
|
6764
|
+
disposePluginDetails = void 0;
|
|
6765
|
+
return false;
|
|
6766
|
+
}
|
|
6767
|
+
layout?.openDetails();
|
|
6768
|
+
return true;
|
|
6769
|
+
};
|
|
6770
|
+
const maximizeDiff = () => {
|
|
6771
|
+
if (disposeDiffOverlay !== void 0) {
|
|
6772
|
+
restoreDiff();
|
|
6773
|
+
return;
|
|
6774
|
+
}
|
|
6775
|
+
disposeExpandedDetailsResize?.();
|
|
6776
|
+
disposeExpandedDetailsResize = void 0;
|
|
6777
|
+
layout?.closeDetails();
|
|
6778
|
+
try {
|
|
6779
|
+
disposeDiffOverlay = ctx.slots.register({
|
|
6780
|
+
name: "shell.overlay",
|
|
6781
|
+
id: "claude-diff-overlay",
|
|
6782
|
+
locale: namespace
|
|
6783
|
+
}, () => /* @__PURE__ */ jsx(MaximizedDiff, {
|
|
6784
|
+
source: projections.source(sessionId),
|
|
4190
6785
|
t,
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
6786
|
+
sessionId,
|
|
6787
|
+
closeDetails: closePluginDetails,
|
|
6788
|
+
restore: restoreDiff
|
|
6789
|
+
}));
|
|
6790
|
+
} catch {
|
|
6791
|
+
disposeDiffOverlay = void 0;
|
|
6792
|
+
layout?.openDetails();
|
|
6793
|
+
disposeExpandedDetailsResize = enableExpandedDetailsResize();
|
|
6794
|
+
}
|
|
6795
|
+
};
|
|
6796
|
+
if (!registerDetails()) {
|
|
6797
|
+
detailsSessionId = void 0;
|
|
4195
6798
|
return;
|
|
4196
6799
|
}
|
|
4197
|
-
detailsSessionId = sessionId;
|
|
4198
|
-
layout?.openDetails();
|
|
4199
6800
|
disposeExpandedDetailsResize = enableExpandedDetailsResize();
|
|
4200
6801
|
};
|
|
4201
6802
|
ctx.effect(() => {
|
|
4202
6803
|
if (typeof document === "undefined" || typeof MutationObserver === "undefined") return () => closePluginDetails();
|
|
4203
6804
|
const observer = new MutationObserver(() => {
|
|
4204
|
-
if (detailsSessionId !== void 0 && document.querySelector("[data-details-collapsed]") !== null) closePluginDetails();
|
|
6805
|
+
if (detailsSessionId !== void 0 && disposeDiffOverlay === void 0 && document.querySelector("[data-details-collapsed]") !== null) closePluginDetails();
|
|
4205
6806
|
});
|
|
4206
6807
|
observer.observe(document.body, {
|
|
4207
6808
|
attributes: true,
|
|
@@ -4227,10 +6828,27 @@ window.__ModuleLoader__.load({
|
|
|
4227
6828
|
openTasks: (turn) => openTasksPanel(sessionId, turn)
|
|
4228
6829
|
})
|
|
4229
6830
|
}, ClaudeActivityTail));
|
|
6831
|
+
ctx.slots.inject("conversation.input.dock", () => ctx.slots.register({
|
|
6832
|
+
name: "conversation.input.dock",
|
|
6833
|
+
id: "claude-review-comments",
|
|
6834
|
+
order: 18,
|
|
6835
|
+
locale: namespace,
|
|
6836
|
+
inject: (sessionId) => ({
|
|
6837
|
+
t,
|
|
6838
|
+
sessionId,
|
|
6839
|
+
...sessions === void 0 || conversation === void 0 ? {} : { submitWith: (fallbackDraft) => {
|
|
6840
|
+
const scope = sessions.scope(sessionId);
|
|
6841
|
+
if (scope === void 0) return;
|
|
6842
|
+
const input = conversation.input.for(scope);
|
|
6843
|
+
if (input.state.getSnapshot().draft.trim() === "") input.setDraft(fallbackDraft);
|
|
6844
|
+
input.submit();
|
|
6845
|
+
} }
|
|
6846
|
+
})
|
|
6847
|
+
}, ClaudeReviewComments));
|
|
4230
6848
|
ctx.slots.inject("conversation.input.dock", () => ctx.slots.register({
|
|
4231
6849
|
name: "conversation.input.dock",
|
|
4232
6850
|
id: "claude-repository-status",
|
|
4233
|
-
order: 20,
|
|
6851
|
+
order: 20.5,
|
|
4234
6852
|
locale: namespace,
|
|
4235
6853
|
inject: (sessionId) => ({
|
|
4236
6854
|
t,
|