@norman-else/dsh-claude 0.1.53 → 0.1.54
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/INSTALL.md +120 -120
- package/LICENSE +21 -21
- package/README.md +1 -0
- package/cordis.patch.yml +12 -12
- package/legacy-preset/agent.cordis.yml +11 -11
- package/legacy-preset/preset.yml +4 -4
- package/lib/bin.mjs +1 -1
- package/lib/bin.mjs.map +1 -1
- package/lib/client.d.ts +30 -0
- package/lib/client.js +460 -46
- package/lib/client.js.map +1 -1
- package/lib/{events-B498uofA.mjs → events-QGz0a_LH.mjs} +3 -2
- package/lib/events-QGz0a_LH.mjs.map +1 -0
- package/lib/index.d.mts +26 -0
- package/lib/index.mjs +497 -180
- package/lib/index.mjs.map +1 -1
- package/lib/{presenters-CRFcjLSC.mjs → presenters-BaZaq9rR.mjs} +2 -2
- package/lib/presenters-BaZaq9rR.mjs.map +1 -0
- package/lib/{preset-installer-Cj637ucf.mjs → preset-installer-3CuT5Lrc.mjs} +2 -2
- package/lib/preset-installer-3CuT5Lrc.mjs.map +1 -0
- package/lib/preset-route.mjs +2 -2
- package/lib/preset-route.mjs.map +1 -1
- package/package.json +222 -222
- package/preset/claude/agent.cordis.yml +11 -11
- package/preset/claude/preset.yml +4 -4
- package/lib/events-B498uofA.mjs.map +0 -1
- package/lib/presenters-CRFcjLSC.mjs.map +0 -1
- package/lib/preset-installer-Cj637ucf.mjs.map +0 -1
package/lib/client.js
CHANGED
|
@@ -4,7 +4,7 @@ window.__ModuleLoader__.load({
|
|
|
4
4
|
var module = { exports: {} };
|
|
5
5
|
module.exports;
|
|
6
6
|
var { Fragment, useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } = require("react");
|
|
7
|
-
var { Button, DiffBlock, DisclosureRow, HoverCard, IconAgentPresetOutline16, IconApiOutline14, IconBranchOutline16, IconCheckOutline14, IconCheckOutline16, IconChevronDownOutline14, IconChevronRightOutline14, IconChevronUpOutline14, IconCloseOutline16, IconEditOutline16, IconListPenOutline16, IconLoadingOutline16, IconQueueOutline14, IconRefreshOutline14, IconRefreshOutline16, IconRightUpOutline14, IconSearchOutline16, IconSendOutline14, IconSparkle16, IconThinkOutline14, IconTrashOutline16, MarkdownText, Menu, Modal, StateDot, Toast, Tooltip, useDismissOnOutsidePointer } = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
7
|
+
var { Button, DiffBlock, DisclosureRow, HoverCard, IconAgentPresetOutline16, IconApiOutline14, IconBranchOutline16, IconCheckOutline14, IconCheckOutline16, IconChevronDownOutline14, IconChevronRightOutline14, IconChevronUpOutline14, IconCloseOutline16, IconEditOutline16, IconListPenOutline16, IconLoadingOutline16, IconQueueOutline14, IconRefreshOutline14, IconRefreshOutline16, IconRightUpOutline14, IconSearchOutline16, IconSendOutline14, IconSparkle16, IconThinkOutline14, IconTrashOutline16, MarkdownText, Menu, Modal, RiskConfirmation, StateDot, Toast, Tooltip, useDismissOnOutsidePointer } = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
8
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
|
|
@@ -26,6 +26,7 @@ window.__ModuleLoader__.load({
|
|
|
26
26
|
const CLAUDE_JIRA_PATH = "/plugins/dsh-claude/jira";
|
|
27
27
|
const CLAUDE_ASK_PATH = "/plugins/dsh-claude/ask";
|
|
28
28
|
const CLAUDE_REWIND_PATH = "/plugins/dsh-claude/rewind";
|
|
29
|
+
const CLAUDE_PERMISSION_MODE_PATH = "/plugins/dsh-claude/permission-mode";
|
|
29
30
|
const CLAUDE_PLAN_FEEDBACK_PATH = "/plugins/dsh-claude/plan/feedback";
|
|
30
31
|
const CLAUDE_PROMPTS_PATH = "/plugins/dsh-claude/prompts";
|
|
31
32
|
const CLAUDE_PROMPT_NAME_PATH = "/plugins/dsh-claude/prompts/name";
|
|
@@ -3888,6 +3889,53 @@ window.__ModuleLoader__.load({
|
|
|
3888
3889
|
fontSize: 13,
|
|
3889
3890
|
lineHeight: "20px"
|
|
3890
3891
|
};
|
|
3892
|
+
const permissionSelectClass = "dshClaudePermissionSelect";
|
|
3893
|
+
const permissionSelectTriggerClass = "dshClaudePermissionSelectTrigger";
|
|
3894
|
+
const permissionSelectIconClass = "dshClaudePermissionSelectIcon";
|
|
3895
|
+
const permissionSelectLabelClass = "dshClaudePermissionSelectLabel";
|
|
3896
|
+
const permissionSelectChevronClass = "dshClaudePermissionSelectChevron";
|
|
3897
|
+
/** The Host's PermissionSelect trigger (PermissionSelect.module.css
|
|
3898
|
+
* `.trigger`): a 28px capsule of 13px/500 secondary text with a 4px gap,
|
|
3899
|
+
* hover fill, no border. Matched here so the plugin's selector sits where the
|
|
3900
|
+
* Host's did without the row noticing the swap. */
|
|
3901
|
+
const permissionSelectCss = `
|
|
3902
|
+
.${permissionSelectClass} { display: inline-flex; align-items: center; min-width: 0; }
|
|
3903
|
+
.${permissionSelectTriggerClass} {
|
|
3904
|
+
min-width: 0;
|
|
3905
|
+
max-width: 220px;
|
|
3906
|
+
height: 28px;
|
|
3907
|
+
display: inline-flex;
|
|
3908
|
+
align-items: center;
|
|
3909
|
+
gap: 4px;
|
|
3910
|
+
padding: 0 4px 0 8px;
|
|
3911
|
+
border: none;
|
|
3912
|
+
border-radius: 24px;
|
|
3913
|
+
background: transparent;
|
|
3914
|
+
color: var(--dsw-alias-label-secondary);
|
|
3915
|
+
font-size: 13px;
|
|
3916
|
+
font-weight: 500;
|
|
3917
|
+
line-height: 20px;
|
|
3918
|
+
cursor: pointer;
|
|
3919
|
+
outline: none;
|
|
3920
|
+
}
|
|
3921
|
+
.${permissionSelectTriggerClass}:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }
|
|
3922
|
+
.${permissionSelectTriggerClass}:disabled { cursor: default; opacity: 0.5; }
|
|
3923
|
+
.${permissionSelectTriggerClass}:focus-visible { outline: none; }
|
|
3924
|
+
.${permissionSelectIconClass} { display: inline-flex; flex: none; }
|
|
3925
|
+
.${permissionSelectLabelClass} { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
3926
|
+
.${permissionSelectChevronClass} { flex: none; transition: transform 120ms ease; }
|
|
3927
|
+
.${permissionSelectChevronClass}[data-open] { transform: rotate(180deg); }
|
|
3928
|
+
`;
|
|
3929
|
+
const permissionSelectRowClass = "dshClaudePermissionSelectRow";
|
|
3930
|
+
const permissionSelectRowNameClass = "dshClaudePermissionSelectRowName";
|
|
3931
|
+
const permissionSelectRowHintClass = "dshClaudePermissionSelectRowHint";
|
|
3932
|
+
/** A mode row: its name, and under it the one line that says what the mode
|
|
3933
|
+
* does. In the row rather than a native title, which the Host never draws. */
|
|
3934
|
+
const permissionSelectRowCss = `
|
|
3935
|
+
.${permissionSelectRowClass} { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
|
|
3936
|
+
.${permissionSelectRowNameClass} { white-space: nowrap; }
|
|
3937
|
+
.${permissionSelectRowHintClass} { font-size: 12px; line-height: 16px; font-weight: 400; color: var(--dsw-alias-label-tertiary); white-space: normal; max-width: 260px; }
|
|
3938
|
+
`;
|
|
3891
3939
|
//#endregion
|
|
3892
3940
|
//#region src/client/markdown-theme.ts
|
|
3893
3941
|
/** Claude Code's code presentation over the Host's Markdown renderer.
|
|
@@ -4239,6 +4287,26 @@ window.__ModuleLoader__.load({
|
|
|
4239
4287
|
return ranges.some((range) => seq >= range.start && seq <= range.end);
|
|
4240
4288
|
}
|
|
4241
4289
|
//#endregion
|
|
4290
|
+
//#region src/permission-mode.ts
|
|
4291
|
+
/** Every mode the selector offers, in the order it lists them: tightest
|
|
4292
|
+
* first. `auto` hands each ask to Claude Code's own classifier and is a
|
|
4293
|
+
* per-model capability, so the selector greys it out where the catalog says
|
|
4294
|
+
* the session's model lacks it. */
|
|
4295
|
+
const CLAUDE_PERMISSION_MODES = [
|
|
4296
|
+
"plan",
|
|
4297
|
+
"default",
|
|
4298
|
+
"acceptEdits",
|
|
4299
|
+
"dontAsk",
|
|
4300
|
+
"auto",
|
|
4301
|
+
"bypassPermissions"
|
|
4302
|
+
];
|
|
4303
|
+
function isClaudePermissionMode(value) {
|
|
4304
|
+
return typeof value === "string" && CLAUDE_PERMISSION_MODES.includes(value);
|
|
4305
|
+
}
|
|
4306
|
+
function isClaudePermissionSelector(value) {
|
|
4307
|
+
return value === "plugin" || value === "native";
|
|
4308
|
+
}
|
|
4309
|
+
//#endregion
|
|
4242
4310
|
//#region src/client/plugin-transport.ts
|
|
4243
4311
|
/**
|
|
4244
4312
|
* The plugin's only door to the network.
|
|
@@ -4547,7 +4615,7 @@ window.__ModuleLoader__.load({
|
|
|
4547
4615
|
const MAX_REPOSITORIES = 8;
|
|
4548
4616
|
const MAX_REVIEW_COMMENT_CHARS = 2e3;
|
|
4549
4617
|
const MAX_TRANSCRIPT_CHARS = 64e3;
|
|
4550
|
-
function record$
|
|
4618
|
+
function record$8(value) {
|
|
4551
4619
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
4552
4620
|
}
|
|
4553
4621
|
function nonNegativeInteger(value) {
|
|
@@ -4557,7 +4625,7 @@ window.__ModuleLoader__.load({
|
|
|
4557
4625
|
return value === void 0 || typeof value === "string" && value.length <= MAX_REPOSITORY_TEXT_CHARS;
|
|
4558
4626
|
}
|
|
4559
4627
|
function validateRepository(value) {
|
|
4560
|
-
const repository = record$
|
|
4628
|
+
const repository = record$8(value);
|
|
4561
4629
|
if (repository === void 0 || ![
|
|
4562
4630
|
"ready",
|
|
4563
4631
|
"not-repository",
|
|
@@ -4569,11 +4637,11 @@ window.__ModuleLoader__.load({
|
|
|
4569
4637
|
"revert"
|
|
4570
4638
|
].includes(String(repository.operation)) || repository.pullRequestOnly !== void 0 && typeof repository.pullRequestOnly !== "boolean" || repository.conflicts !== void 0 && (!Array.isArray(repository.conflicts) || repository.conflicts.length > MAX_CONFLICT_PATHS || repository.conflicts.some((path) => typeof path !== "string" || path.length > MAX_REPOSITORY_TEXT_CHARS))) return false;
|
|
4571
4639
|
if (repository.diff !== void 0) {
|
|
4572
|
-
const diff = record$
|
|
4640
|
+
const diff = record$8(repository.diff);
|
|
4573
4641
|
if (diff === void 0 || !nonNegativeInteger(diff.additions) || !nonNegativeInteger(diff.deletions) || !nonNegativeInteger(diff.files) || typeof diff.truncated !== "boolean" || diff.elided !== void 0 && !(Array.isArray(diff.elided) && diff.elided.length <= 1e3 && diff.elided.every((item) => typeof item === "string")) || diff.patch !== void 0 && (typeof diff.patch !== "string" || diff.patch.length > MAX_DIFF_CHARS)) return false;
|
|
4574
4642
|
}
|
|
4575
4643
|
if (repository.pullRequest === void 0) return true;
|
|
4576
|
-
const pullRequest = record$
|
|
4644
|
+
const pullRequest = record$8(repository.pullRequest);
|
|
4577
4645
|
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 || ![
|
|
4578
4646
|
"open",
|
|
4579
4647
|
"closed",
|
|
@@ -4598,33 +4666,38 @@ window.__ModuleLoader__.load({
|
|
|
4598
4666
|
}
|
|
4599
4667
|
/** Validate the public route envelope before publishing it to UI components. */
|
|
4600
4668
|
function parseClaudeClientProjection(value) {
|
|
4601
|
-
const input = record$
|
|
4669
|
+
const input = record$8(value);
|
|
4602
4670
|
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");
|
|
4603
4671
|
for (const item of input.commands) {
|
|
4604
|
-
const command = record$
|
|
4672
|
+
const command = record$8(item);
|
|
4605
4673
|
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");
|
|
4606
4674
|
}
|
|
4607
4675
|
for (const item of input.activities) {
|
|
4608
|
-
const activity = record$
|
|
4676
|
+
const activity = record$8(item);
|
|
4609
4677
|
if (activity === void 0 || !nonNegativeInteger(activity.turn) || !nonNegativeInteger(activity.step) || !nonNegativeInteger(activity.ordinal) || typeof activity.kind !== "string") throw new Error("invalid Claude sidecar activity");
|
|
4610
4678
|
}
|
|
4611
|
-
if (input.contextUsage !== void 0 && record$
|
|
4612
|
-
const tasks = input.tasks === void 0 ? void 0 : record$
|
|
4679
|
+
if (input.contextUsage !== void 0 && record$8(input.contextUsage) === void 0) throw new Error("invalid Claude context projection");
|
|
4680
|
+
const tasks = input.tasks === void 0 ? void 0 : record$8(input.tasks);
|
|
4613
4681
|
if (tasks !== void 0 && !Array.isArray(tasks.tasks)) throw new Error("invalid Claude tasks projection");
|
|
4614
4682
|
if (input.repository !== void 0 && !validateRepository(input.repository)) throw new Error("invalid Claude repository projection");
|
|
4615
4683
|
if (input.repositories !== void 0 && (!Array.isArray(input.repositories) || input.repositories.length > MAX_REPOSITORIES || !input.repositories.every(validateRepository))) throw new Error("invalid Claude repositories projection");
|
|
4616
4684
|
if (input.reviewComments !== void 0) {
|
|
4617
4685
|
if (!Array.isArray(input.reviewComments) || input.reviewComments.length > MAX_REVIEW_COMMENTS) throw new Error("invalid Claude review comment projection");
|
|
4618
4686
|
for (const item of input.reviewComments) {
|
|
4619
|
-
const comment = record$
|
|
4687
|
+
const comment = record$8(item);
|
|
4620
4688
|
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");
|
|
4621
4689
|
}
|
|
4622
4690
|
}
|
|
4691
|
+
if (input.permissionSelector !== void 0 && !isClaudePermissionSelector(input.permissionSelector)) throw new Error("invalid Claude permission selector projection");
|
|
4692
|
+
if (input.permissionMode !== void 0) {
|
|
4693
|
+
const view = record$8(input.permissionMode);
|
|
4694
|
+
if (view === void 0 || !isClaudePermissionMode(view.mode) || typeof view.locked !== "boolean" || view.autoSupported !== void 0 && typeof view.autoSupported !== "boolean") throw new Error("invalid Claude permission mode projection");
|
|
4695
|
+
}
|
|
4623
4696
|
if (input.rewind !== void 0) {
|
|
4624
|
-
const ranges = record$
|
|
4697
|
+
const ranges = record$8(input.rewind)?.ranges;
|
|
4625
4698
|
if (!Array.isArray(ranges) || ranges.length > 200) throw new Error("invalid Claude rewind projection");
|
|
4626
4699
|
for (const item of ranges) {
|
|
4627
|
-
const range = record$
|
|
4700
|
+
const range = record$8(item);
|
|
4628
4701
|
if (range === void 0 || !nonNegativeInteger(range.start) || !nonNegativeInteger(range.end)) throw new Error("invalid Claude rewind projection");
|
|
4629
4702
|
}
|
|
4630
4703
|
}
|
|
@@ -4682,6 +4755,8 @@ window.__ModuleLoader__.load({
|
|
|
4682
4755
|
let repositories;
|
|
4683
4756
|
let reviewComments;
|
|
4684
4757
|
let rewind;
|
|
4758
|
+
let permissionMode;
|
|
4759
|
+
let permissionSelector;
|
|
4685
4760
|
const byStep = /* @__PURE__ */ new Map();
|
|
4686
4761
|
const stepOrder = [];
|
|
4687
4762
|
/** Streaming prose still being revealed: full arrived text plus shown chars. */
|
|
@@ -4763,6 +4838,8 @@ window.__ModuleLoader__.load({
|
|
|
4763
4838
|
...repositories === void 0 ? {} : { repositories },
|
|
4764
4839
|
...reviewComments === void 0 ? {} : { reviewComments },
|
|
4765
4840
|
...rewind === void 0 ? {} : { rewind },
|
|
4841
|
+
...permissionMode === void 0 ? {} : { permissionMode },
|
|
4842
|
+
...permissionSelector === void 0 ? {} : { permissionSelector },
|
|
4766
4843
|
byStep: new Map(byStep)
|
|
4767
4844
|
};
|
|
4768
4845
|
for (const listener of [...listeners]) listener();
|
|
@@ -4844,7 +4921,7 @@ window.__ModuleLoader__.load({
|
|
|
4844
4921
|
} catch {
|
|
4845
4922
|
return;
|
|
4846
4923
|
}
|
|
4847
|
-
const event = record$
|
|
4924
|
+
const event = record$8(value);
|
|
4848
4925
|
if (event === void 0 || typeof event.type !== "string") return;
|
|
4849
4926
|
if (event.type === "checkpoint") {
|
|
4850
4927
|
if (nonNegativeInteger(event.seq) && seq !== void 0 && event.seq !== seq) desync("projection-gap", `checkpoint at ${event.seq}, applied ${seq}`);
|
|
@@ -4865,6 +4942,8 @@ window.__ModuleLoader__.load({
|
|
|
4865
4942
|
repositories = next.repositories;
|
|
4866
4943
|
reviewComments = next.reviewComments;
|
|
4867
4944
|
rewind = next.rewind;
|
|
4945
|
+
permissionMode = next.permissionMode;
|
|
4946
|
+
permissionSelector = next.permissionSelector;
|
|
4868
4947
|
reset(next.activities);
|
|
4869
4948
|
break;
|
|
4870
4949
|
}
|
|
@@ -4896,13 +4975,17 @@ window.__ModuleLoader__.load({
|
|
|
4896
4975
|
commands: event.commands,
|
|
4897
4976
|
...event.repository === void 0 ? {} : { repository: event.repository },
|
|
4898
4977
|
...event.repositories === void 0 ? {} : { repositories: event.repositories },
|
|
4899
|
-
...event.reviewComments === void 0 ? {} : { reviewComments: event.reviewComments }
|
|
4978
|
+
...event.reviewComments === void 0 ? {} : { reviewComments: event.reviewComments },
|
|
4979
|
+
...event.permissionMode === void 0 ? {} : { permissionMode: event.permissionMode },
|
|
4980
|
+
...event.permissionSelector === void 0 ? {} : { permissionSelector: event.permissionSelector }
|
|
4900
4981
|
});
|
|
4901
4982
|
owned = event.owned;
|
|
4902
4983
|
commands = event.commands;
|
|
4903
4984
|
repository = event.repository;
|
|
4904
4985
|
repositories = event.repositories;
|
|
4905
4986
|
reviewComments = event.reviewComments;
|
|
4987
|
+
if (event.permissionMode !== void 0) permissionMode = event.permissionMode;
|
|
4988
|
+
permissionSelector = event.permissionSelector;
|
|
4906
4989
|
revision += 1;
|
|
4907
4990
|
break;
|
|
4908
4991
|
default: return;
|
|
@@ -5264,7 +5347,7 @@ window.__ModuleLoader__.load({
|
|
|
5264
5347
|
return value;
|
|
5265
5348
|
}
|
|
5266
5349
|
}
|
|
5267
|
-
function record$
|
|
5350
|
+
function record$7(value) {
|
|
5268
5351
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
5269
5352
|
}
|
|
5270
5353
|
function text$1(value) {
|
|
@@ -5278,7 +5361,7 @@ window.__ModuleLoader__.load({
|
|
|
5278
5361
|
if (typeof value === "string") return value;
|
|
5279
5362
|
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
5280
5363
|
if (Array.isArray(value)) return value.map(displayValue).join(", ");
|
|
5281
|
-
return record$
|
|
5364
|
+
return record$7(value) === void 0 ? String(value) : Object.entries(value).map(([key, item]) => `${key}: ${displayValue(item)}`).join("\n");
|
|
5282
5365
|
}
|
|
5283
5366
|
function Section({ title, children }) {
|
|
5284
5367
|
return /* @__PURE__ */ jsxs("section", {
|
|
@@ -5383,8 +5466,8 @@ window.__ModuleLoader__.load({
|
|
|
5383
5466
|
function ToolPresentation({ tool, t }) {
|
|
5384
5467
|
const inputValue = parsedValue(tool.input);
|
|
5385
5468
|
const outputValue = parsedValue(tool.output);
|
|
5386
|
-
const input = record$
|
|
5387
|
-
const output = record$
|
|
5469
|
+
const input = record$7(inputValue);
|
|
5470
|
+
const output = record$7(outputValue);
|
|
5388
5471
|
const outputTitle = tool.isError === true ? t("toolError") : t("toolOutput");
|
|
5389
5472
|
if (tool.diffs !== void 0) return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(DiffBlock, {
|
|
5390
5473
|
diffs: [...tool.diffs],
|
|
@@ -5394,7 +5477,7 @@ window.__ModuleLoader__.load({
|
|
|
5394
5477
|
value: typeof outputValue === "string" ? outputValue : void 0
|
|
5395
5478
|
})] });
|
|
5396
5479
|
if (tool.toolName === "Read") {
|
|
5397
|
-
const file = record$
|
|
5480
|
+
const file = record$7(output?.file);
|
|
5398
5481
|
const path = text$1(file?.filePath) ?? text$1(input?.file_path);
|
|
5399
5482
|
const content = text$1(file?.content) ?? (typeof outputValue === "string" ? outputValue : void 0);
|
|
5400
5483
|
const offset = numberValue(input?.offset) ?? 1;
|
|
@@ -6097,7 +6180,7 @@ window.__ModuleLoader__.load({
|
|
|
6097
6180
|
}
|
|
6098
6181
|
//#endregion
|
|
6099
6182
|
//#region src/client/pr-feedback-api.ts
|
|
6100
|
-
function record$
|
|
6183
|
+
function record$6(value) {
|
|
6101
6184
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
6102
6185
|
}
|
|
6103
6186
|
/** `root` names another checkout the session wrote into; absent, the
|
|
@@ -6111,7 +6194,7 @@ window.__ModuleLoader__.load({
|
|
|
6111
6194
|
};
|
|
6112
6195
|
}
|
|
6113
6196
|
function answer(value) {
|
|
6114
|
-
const body = record$
|
|
6197
|
+
const body = record$6(value);
|
|
6115
6198
|
if (body === void 0) throw new Error("Invalid pull request feedback response.");
|
|
6116
6199
|
return body;
|
|
6117
6200
|
}
|
|
@@ -6127,7 +6210,7 @@ window.__ModuleLoader__.load({
|
|
|
6127
6210
|
}));
|
|
6128
6211
|
}
|
|
6129
6212
|
function reviewComment(value) {
|
|
6130
|
-
const input = record$
|
|
6213
|
+
const input = record$6(value);
|
|
6131
6214
|
if (input === void 0 || typeof input.id !== "number" || typeof input.path !== "string" || typeof input.author !== "string" || typeof input.body !== "string" || typeof input.url !== "string" || input.avatarUrl !== void 0 && githubAvatarUrl(input.avatarUrl) === void 0 || input.side !== "new" && input.side !== "old" || input.line !== void 0 && typeof input.line !== "number" || input.createdAt !== void 0 && typeof input.createdAt !== "string" || input.bot !== void 0 && typeof input.bot !== "boolean") return void 0;
|
|
6132
6215
|
return input;
|
|
6133
6216
|
}
|
|
@@ -6136,7 +6219,7 @@ window.__ModuleLoader__.load({
|
|
|
6136
6219
|
if (!Array.isArray(body.threads)) throw new Error("Invalid pull request comments response.");
|
|
6137
6220
|
const threads = [];
|
|
6138
6221
|
for (const item of body.threads) {
|
|
6139
|
-
const input = record$
|
|
6222
|
+
const input = record$6(item);
|
|
6140
6223
|
if (input === void 0 || typeof input.id !== "string" || typeof input.path !== "string" || input.side !== "new" && input.side !== "old" || input.line !== void 0 && typeof input.line !== "number" || !Array.isArray(input.comments)) continue;
|
|
6141
6224
|
const comments = input.comments.map(reviewComment).filter((value) => value !== void 0);
|
|
6142
6225
|
if (comments.length === 0) continue;
|
|
@@ -6176,7 +6259,7 @@ window.__ModuleLoader__.load({
|
|
|
6176
6259
|
if (!Array.isArray(body.users)) return [];
|
|
6177
6260
|
const users = [];
|
|
6178
6261
|
for (const item of body.users) {
|
|
6179
|
-
const input = record$
|
|
6262
|
+
const input = record$6(item);
|
|
6180
6263
|
if (input === void 0 || typeof input.login !== "string" || input.login.length === 0) continue;
|
|
6181
6264
|
const avatarUrl = githubAvatarUrl(input.avatarUrl);
|
|
6182
6265
|
users.push({
|
|
@@ -6191,7 +6274,7 @@ window.__ModuleLoader__.load({
|
|
|
6191
6274
|
if (!Array.isArray(body.checks)) throw new Error("Invalid pull request checks response.");
|
|
6192
6275
|
const checks = [];
|
|
6193
6276
|
for (const item of body.checks) {
|
|
6194
|
-
const input = record$
|
|
6277
|
+
const input = record$6(item);
|
|
6195
6278
|
if (input === void 0 || typeof input.name !== "string" || input.link !== void 0 && typeof input.link !== "string" || input.description !== void 0 && typeof input.description !== "string" || input.log !== void 0 && typeof input.log !== "string") continue;
|
|
6196
6279
|
checks.push(input);
|
|
6197
6280
|
}
|
|
@@ -6666,7 +6749,7 @@ window.__ModuleLoader__.load({
|
|
|
6666
6749
|
if (code !== void 0) this.code = code;
|
|
6667
6750
|
}
|
|
6668
6751
|
};
|
|
6669
|
-
function record$
|
|
6752
|
+
function record$5(value) {
|
|
6670
6753
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
6671
6754
|
}
|
|
6672
6755
|
/**
|
|
@@ -6687,7 +6770,7 @@ window.__ModuleLoader__.load({
|
|
|
6687
6770
|
return new JiraClientError(cause.message === cause.code ? "Jira is unavailable." : cause.message, cause.code);
|
|
6688
6771
|
}
|
|
6689
6772
|
function payload(value) {
|
|
6690
|
-
const body = record$
|
|
6773
|
+
const body = record$5(value);
|
|
6691
6774
|
if (body === void 0) throw new JiraClientError("Invalid Jira response.");
|
|
6692
6775
|
return body;
|
|
6693
6776
|
}
|
|
@@ -6723,7 +6806,7 @@ window.__ModuleLoader__.load({
|
|
|
6723
6806
|
if (!Array.isArray(body.tickets)) throw new JiraClientError("Invalid Jira search response.");
|
|
6724
6807
|
const tickets = [];
|
|
6725
6808
|
for (const item of body.tickets) {
|
|
6726
|
-
const ticket = record$
|
|
6809
|
+
const ticket = record$5(item);
|
|
6727
6810
|
if (ticket === void 0 || typeof ticket.key !== "string" || typeof ticket.summary !== "string" || typeof ticket.url !== "string") continue;
|
|
6728
6811
|
tickets.push(ticket);
|
|
6729
6812
|
}
|
|
@@ -6984,8 +7067,9 @@ window.__ModuleLoader__.load({
|
|
|
6984
7067
|
* so an older Host cannot make a setting unreachable. */
|
|
6985
7068
|
function visibleGlobalSettings(settings) {
|
|
6986
7069
|
const renderer = settings.find((setting) => setting.key === "renderer");
|
|
6987
|
-
|
|
6988
|
-
|
|
7070
|
+
const withProse = renderer === void 0 || renderer.value !== "native" ? settings : settings.filter((setting) => setting.key !== "prose");
|
|
7071
|
+
const selector = settings.find((setting) => setting.key === "permissionSelector");
|
|
7072
|
+
return selector === void 0 || selector.value !== "native" ? withProse : withProse.filter((setting) => setting.key !== "permissionMode");
|
|
6989
7073
|
}
|
|
6990
7074
|
/** Per-setting label and the effect note that used to sit as a standalone
|
|
6991
7075
|
* paragraph under the card; it now hangs off the label as a hover hint. */
|
|
@@ -6994,6 +7078,14 @@ window.__ModuleLoader__.load({
|
|
|
6994
7078
|
label: "outputStyle",
|
|
6995
7079
|
hint: "globalSettingsNewSession"
|
|
6996
7080
|
},
|
|
7081
|
+
permissionSelector: {
|
|
7082
|
+
label: "permissionSelector",
|
|
7083
|
+
hint: "permissionSelectorEffect"
|
|
7084
|
+
},
|
|
7085
|
+
permissionMode: {
|
|
7086
|
+
label: "defaultPermissionMode",
|
|
7087
|
+
hint: "defaultPermissionModeEffect"
|
|
7088
|
+
},
|
|
6997
7089
|
renderer: {
|
|
6998
7090
|
label: "renderer",
|
|
6999
7091
|
hint: "rendererEffect"
|
|
@@ -7023,6 +7115,14 @@ window.__ModuleLoader__.load({
|
|
|
7023
7115
|
* keyed `<setting>:<option>`. Options discovered on the machine (output style
|
|
7024
7116
|
* names) carry no entry and keep the label the route reported. */
|
|
7025
7117
|
const SETTING_OPTION_COPY = {
|
|
7118
|
+
"permissionSelector:plugin": "permissionSelectorPlugin",
|
|
7119
|
+
"permissionSelector:native": "permissionSelectorNative",
|
|
7120
|
+
"permissionMode:plan": "permissionModePlan",
|
|
7121
|
+
"permissionMode:default": "permissionModeDefault",
|
|
7122
|
+
"permissionMode:acceptEdits": "permissionModeAcceptEdits",
|
|
7123
|
+
"permissionMode:dontAsk": "permissionModeDontAsk",
|
|
7124
|
+
"permissionMode:auto": "permissionModeAuto",
|
|
7125
|
+
"permissionMode:bypassPermissions": "permissionModeBypass",
|
|
7026
7126
|
"renderer:plugin": "rendererPlugin",
|
|
7027
7127
|
"renderer:native": "rendererNative",
|
|
7028
7128
|
"prose:plain": "prosePlain",
|
|
@@ -8131,7 +8231,7 @@ window.__ModuleLoader__.load({
|
|
|
8131
8231
|
if (commit !== void 0) this.commit = commit;
|
|
8132
8232
|
}
|
|
8133
8233
|
};
|
|
8134
|
-
function record$
|
|
8234
|
+
function record$4(value) {
|
|
8135
8235
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
8136
8236
|
}
|
|
8137
8237
|
/** The dialog branches on `code`, so a route refusal keeps arriving as this
|
|
@@ -8144,20 +8244,20 @@ window.__ModuleLoader__.load({
|
|
|
8144
8244
|
return error instanceof PluginRequestError ? new RepositoryActionClientError(error.message, error.code) : error;
|
|
8145
8245
|
}
|
|
8146
8246
|
function preview(value) {
|
|
8147
|
-
const input = record$
|
|
8247
|
+
const input = record$4(value);
|
|
8148
8248
|
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.");
|
|
8149
8249
|
for (const file of input.files) {
|
|
8150
|
-
const item = record$
|
|
8250
|
+
const item = record$4(file);
|
|
8151
8251
|
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.");
|
|
8152
8252
|
}
|
|
8153
8253
|
for (const commit of input.unpushedCommits) {
|
|
8154
|
-
const item = record$
|
|
8254
|
+
const item = record$4(commit);
|
|
8155
8255
|
if (item === void 0 || typeof item.hash !== "string" || typeof item.subject !== "string") throw new Error("Invalid repository action commit.");
|
|
8156
8256
|
}
|
|
8157
8257
|
return input;
|
|
8158
8258
|
}
|
|
8159
8259
|
function result(value) {
|
|
8160
|
-
const input = record$
|
|
8260
|
+
const input = record$4(value);
|
|
8161
8261
|
if (input === void 0 || typeof input.commit !== "string" || typeof input.pushed !== "boolean" || input.pullRequestUrl !== void 0 && typeof input.pullRequestUrl !== "string" || input.conflicts !== void 0 && (!Array.isArray(input.conflicts) || input.conflicts.some((item) => typeof item !== "string"))) throw new Error("Invalid repository action result.");
|
|
8162
8262
|
return input;
|
|
8163
8263
|
}
|
|
@@ -8179,7 +8279,7 @@ window.__ModuleLoader__.load({
|
|
|
8179
8279
|
}
|
|
8180
8280
|
async function generateCommitMessage(sessionId, fingerprint, signal, root) {
|
|
8181
8281
|
try {
|
|
8182
|
-
const value = record$
|
|
8282
|
+
const value = record$4(await pluginWrite(`${CLAUDE_REPOSITORY_ACTION_PATH}/message`, "remote", signal, {
|
|
8183
8283
|
query: sessionQuery(sessionId, root),
|
|
8184
8284
|
json: { fingerprint }
|
|
8185
8285
|
}));
|
|
@@ -8193,7 +8293,7 @@ window.__ModuleLoader__.load({
|
|
|
8193
8293
|
* `baseBranch` empty means origin's default branch. */
|
|
8194
8294
|
async function generatePullRequestText(sessionId, fingerprint, baseBranch, signal, root) {
|
|
8195
8295
|
try {
|
|
8196
|
-
const value = record$
|
|
8296
|
+
const value = record$4(await pluginWrite(`${CLAUDE_REPOSITORY_ACTION_PATH}/pull-request`, "remote", signal, {
|
|
8197
8297
|
query: sessionQuery(sessionId, root),
|
|
8198
8298
|
json: {
|
|
8199
8299
|
fingerprint,
|
|
@@ -8262,16 +8362,16 @@ window.__ModuleLoader__.load({
|
|
|
8262
8362
|
/** The draft only has to describe the work; the host truncates it again before
|
|
8263
8363
|
* summarizing, and the setup route caps the whole body at 16 KiB. */
|
|
8264
8364
|
const MAX_INTENT_CHARS = 2e3;
|
|
8265
|
-
function record$
|
|
8365
|
+
function record$3(value) {
|
|
8266
8366
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
8267
8367
|
}
|
|
8268
8368
|
function setupResult(value) {
|
|
8269
|
-
const item = record$
|
|
8369
|
+
const item = record$3(value);
|
|
8270
8370
|
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;
|
|
8271
8371
|
return item;
|
|
8272
8372
|
}
|
|
8273
8373
|
function parseRepositorySetupEvent(line, onProgress) {
|
|
8274
|
-
const event = record$
|
|
8374
|
+
const event = record$3(JSON.parse(line));
|
|
8275
8375
|
if (event?.type === "progress" && typeof event.stage === "string" && HOST_STAGES.has(event.stage)) {
|
|
8276
8376
|
onProgress(event.stage);
|
|
8277
8377
|
return;
|
|
@@ -9845,7 +9945,7 @@ window.__ModuleLoader__.load({
|
|
|
9845
9945
|
}
|
|
9846
9946
|
//#endregion
|
|
9847
9947
|
//#region src/client/review-comment-api.ts
|
|
9848
|
-
function record$
|
|
9948
|
+
function record$2(value) {
|
|
9849
9949
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
9850
9950
|
}
|
|
9851
9951
|
async function post(path, sessionId, body) {
|
|
@@ -9855,7 +9955,7 @@ window.__ModuleLoader__.load({
|
|
|
9855
9955
|
});
|
|
9856
9956
|
}
|
|
9857
9957
|
async function addReviewComment(sessionId, comment) {
|
|
9858
|
-
const created = record$
|
|
9958
|
+
const created = record$2(record$2(await post("", sessionId, comment))?.comment);
|
|
9859
9959
|
if (created === void 0 || typeof created.id !== "string") throw new Error("Invalid review comment response.");
|
|
9860
9960
|
return created;
|
|
9861
9961
|
}
|
|
@@ -16250,11 +16350,11 @@ window.__ModuleLoader__.load({
|
|
|
16250
16350
|
}
|
|
16251
16351
|
//#endregion
|
|
16252
16352
|
//#region src/client/ask-api.ts
|
|
16253
|
-
function record(value) {
|
|
16353
|
+
function record$1(value) {
|
|
16254
16354
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
16255
16355
|
}
|
|
16256
16356
|
function parseAskEvent(line) {
|
|
16257
|
-
const event = record(JSON.parse(line));
|
|
16357
|
+
const event = record$1(JSON.parse(line));
|
|
16258
16358
|
if (event?.type === "delta" && typeof event.text === "string") return {
|
|
16259
16359
|
type: "delta",
|
|
16260
16360
|
text: event.text
|
|
@@ -18823,6 +18923,244 @@ window.__ModuleLoader__.load({
|
|
|
18823
18923
|
});
|
|
18824
18924
|
}
|
|
18825
18925
|
//#endregion
|
|
18926
|
+
//#region src/client/ClaudePermissionSelect.tsx
|
|
18927
|
+
const NAME_KEY = {
|
|
18928
|
+
plan: "permissionModePlan",
|
|
18929
|
+
default: "permissionModeDefault",
|
|
18930
|
+
acceptEdits: "permissionModeAcceptEdits",
|
|
18931
|
+
dontAsk: "permissionModeDontAsk",
|
|
18932
|
+
auto: "permissionModeAuto",
|
|
18933
|
+
bypassPermissions: "permissionModeBypass"
|
|
18934
|
+
};
|
|
18935
|
+
const HINT_KEY = {
|
|
18936
|
+
plan: "permissionModePlanHint",
|
|
18937
|
+
default: "permissionModeDefaultHint",
|
|
18938
|
+
acceptEdits: "permissionModeAcceptEditsHint",
|
|
18939
|
+
dontAsk: "permissionModeDontAskHint",
|
|
18940
|
+
auto: "permissionModeAutoHint",
|
|
18941
|
+
bypassPermissions: "permissionModeBypassHint"
|
|
18942
|
+
};
|
|
18943
|
+
/** One 16px outline glyph per mode, drawn to the Host's own icon grammar
|
|
18944
|
+
* (1.5px round strokes on currentColor) so the row reads as one set with
|
|
18945
|
+
* the attach and plan controls beside it. */
|
|
18946
|
+
function ClaudePermissionModeGlyph({ mode }) {
|
|
18947
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
18948
|
+
width: "16",
|
|
18949
|
+
height: "16",
|
|
18950
|
+
viewBox: "0 0 16 16",
|
|
18951
|
+
fill: "none",
|
|
18952
|
+
"aria-hidden": "true",
|
|
18953
|
+
children: {
|
|
18954
|
+
plan: [
|
|
18955
|
+
"M6 2.75h4",
|
|
18956
|
+
"M4.5 3.75h7a1 1 0 0 1 1 1v8.5a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1v-8.5a1 1 0 0 1 1-1z",
|
|
18957
|
+
"M6 8h4",
|
|
18958
|
+
"M6 10.5h2.5"
|
|
18959
|
+
],
|
|
18960
|
+
default: [
|
|
18961
|
+
"M8 2.25l5 1.9v3.6c0 3.05-2.15 5.15-5 6.25-2.85-1.1-5-3.2-5-6.25v-3.6l5-1.9z",
|
|
18962
|
+
"M8 6v3",
|
|
18963
|
+
"M8 11h.01"
|
|
18964
|
+
],
|
|
18965
|
+
acceptEdits: [
|
|
18966
|
+
"M10.4 3.1l2.5 2.5L6.5 12H4v-2.5l6.4-6.4z",
|
|
18967
|
+
"M9 4.5l2.5 2.5",
|
|
18968
|
+
"M9.5 13.25l1.5 1.5 3-3"
|
|
18969
|
+
],
|
|
18970
|
+
dontAsk: [
|
|
18971
|
+
"M5.25 9.5V7.25a2.75 2.75 0 0 1 5.5 0V9.5l1 1.75h-7.5l1-1.75z",
|
|
18972
|
+
"M6.75 12.75a1.25 1.25 0 0 0 2.5 0",
|
|
18973
|
+
"M3 3l10 10"
|
|
18974
|
+
],
|
|
18975
|
+
auto: ["M8 2.5l1.4 3.6 3.6 1.4-3.6 1.4L8 12.5 6.6 8.9 3 7.5l3.6-1.4L8 2.5z", "M12.5 11.5l.5 1.25 1.25.5-1.25.5-.5 1.25-.5-1.25-1.25-.5 1.25-.5.5-1.25z"],
|
|
18976
|
+
bypassPermissions: [
|
|
18977
|
+
"M5 8V6.25a3 3 0 0 1 5.85-.95",
|
|
18978
|
+
"M4.25 8h7.5v5.5h-7.5z",
|
|
18979
|
+
"M8 10.25v1.5"
|
|
18980
|
+
]
|
|
18981
|
+
}[mode].map((d) => /* @__PURE__ */ jsx("path", {
|
|
18982
|
+
d,
|
|
18983
|
+
stroke: "currentColor",
|
|
18984
|
+
strokeWidth: "1.5",
|
|
18985
|
+
strokeLinecap: "round",
|
|
18986
|
+
strokeLinejoin: "round"
|
|
18987
|
+
}, d))
|
|
18988
|
+
});
|
|
18989
|
+
}
|
|
18990
|
+
/**
|
|
18991
|
+
* Claude Code's own permission modes as the session's access control, in the
|
|
18992
|
+
* composer's tool row where the Host's three-mode selector sits for other
|
|
18993
|
+
* agent presets. That selector is hidden for Claude sessions (host-chrome.ts)
|
|
18994
|
+
* rather than replaced: it is not a slot. This one drives the same Host
|
|
18995
|
+
* knobs through the plugin's route, so approvals and the sandbox follow.
|
|
18996
|
+
*
|
|
18997
|
+
* The pick is shown the moment it is made and held until the projection
|
|
18998
|
+
* confirms it; a refused pick drops back to what the projection says.
|
|
18999
|
+
*/
|
|
19000
|
+
function ClaudePermissionSelect({ t, setMode, notify, useClaudeProjection, useSession }) {
|
|
19001
|
+
const owned = useClaudeProjection((projection) => projection.owned);
|
|
19002
|
+
const selector = useClaudeProjection((projection) => projection.permissionSelector);
|
|
19003
|
+
const view = useClaudeProjection((projection) => projection.permissionMode);
|
|
19004
|
+
const running = useSession === void 0 ? false : useSession((session) => session.running);
|
|
19005
|
+
const [pick, setPick] = useState(null);
|
|
19006
|
+
const [open, setOpen] = useState(false);
|
|
19007
|
+
const [confirming, setConfirming] = useState(null);
|
|
19008
|
+
const [acknowledged, setAcknowledged] = useState(false);
|
|
19009
|
+
const [busy, setBusy] = useState(false);
|
|
19010
|
+
const reported = view?.mode;
|
|
19011
|
+
useEffect(() => {
|
|
19012
|
+
if (pick !== null && reported === pick) setPick(null);
|
|
19013
|
+
}, [pick, reported]);
|
|
19014
|
+
if (!owned || selector !== "plugin") return null;
|
|
19015
|
+
const current = pick ?? reported;
|
|
19016
|
+
const locked = running || view?.locked === true;
|
|
19017
|
+
const label = current === void 0 ? t("permissionMode") : t(NAME_KEY[current]);
|
|
19018
|
+
const hint = locked ? t("permissionModeLocked") : current === void 0 ? t("permissionMode") : t(HINT_KEY[current]);
|
|
19019
|
+
const autoUnsupported = view?.autoSupported === false;
|
|
19020
|
+
const hintOf = (mode) => mode === "auto" && autoUnsupported ? t("permissionModeAutoUnsupported") : t(HINT_KEY[mode]);
|
|
19021
|
+
const submit = (mode) => {
|
|
19022
|
+
setPick(mode);
|
|
19023
|
+
setBusy(true);
|
|
19024
|
+
setMode(mode).then((outcome) => {
|
|
19025
|
+
if (!outcome.hostSynced) notify?.("info", t("permissionModeHostKept"));
|
|
19026
|
+
}, (error) => {
|
|
19027
|
+
setPick(null);
|
|
19028
|
+
notify?.("error", t("permissionModeFailed", { message: error instanceof Error ? error.message : String(error) }));
|
|
19029
|
+
}).finally(() => {
|
|
19030
|
+
setBusy(false);
|
|
19031
|
+
});
|
|
19032
|
+
};
|
|
19033
|
+
const choose = (id) => {
|
|
19034
|
+
setOpen(false);
|
|
19035
|
+
if (id === current || !CLAUDE_PERMISSION_MODES.includes(id)) return;
|
|
19036
|
+
const mode = id;
|
|
19037
|
+
if (mode === "bypassPermissions") {
|
|
19038
|
+
setAcknowledged(false);
|
|
19039
|
+
setConfirming(mode);
|
|
19040
|
+
return;
|
|
19041
|
+
}
|
|
19042
|
+
submit(mode);
|
|
19043
|
+
};
|
|
19044
|
+
const closeConfirmation = () => {
|
|
19045
|
+
setAcknowledged(false);
|
|
19046
|
+
setConfirming(null);
|
|
19047
|
+
};
|
|
19048
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
19049
|
+
className: permissionSelectClass,
|
|
19050
|
+
children: [
|
|
19051
|
+
/* @__PURE__ */ jsxs("style", {
|
|
19052
|
+
"data-dsh-claude-permission-select-styles": true,
|
|
19053
|
+
children: [permissionSelectCss, permissionSelectRowCss]
|
|
19054
|
+
}),
|
|
19055
|
+
/* @__PURE__ */ jsx(Menu, {
|
|
19056
|
+
open,
|
|
19057
|
+
items: CLAUDE_PERMISSION_MODES.map((mode) => ({
|
|
19058
|
+
id: mode,
|
|
19059
|
+
label: /* @__PURE__ */ jsxs("span", {
|
|
19060
|
+
className: permissionSelectRowClass,
|
|
19061
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
19062
|
+
className: permissionSelectRowNameClass,
|
|
19063
|
+
children: t(NAME_KEY[mode])
|
|
19064
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
19065
|
+
className: permissionSelectRowHintClass,
|
|
19066
|
+
children: hintOf(mode)
|
|
19067
|
+
})]
|
|
19068
|
+
}),
|
|
19069
|
+
icon: /* @__PURE__ */ jsx(ClaudePermissionModeGlyph, { mode }),
|
|
19070
|
+
...mode === "auto" && autoUnsupported ? { disabled: true } : {},
|
|
19071
|
+
...mode === "bypassPermissions" ? { danger: true } : {}
|
|
19072
|
+
})),
|
|
19073
|
+
selectedId: current,
|
|
19074
|
+
onSelect: choose,
|
|
19075
|
+
onClose: () => {
|
|
19076
|
+
setOpen(false);
|
|
19077
|
+
},
|
|
19078
|
+
side: "top",
|
|
19079
|
+
anchor: /* @__PURE__ */ jsx(Tooltip, {
|
|
19080
|
+
label: hint,
|
|
19081
|
+
side: "top",
|
|
19082
|
+
delayMs: 250,
|
|
19083
|
+
disabled: open,
|
|
19084
|
+
children: /* @__PURE__ */ jsxs("button", {
|
|
19085
|
+
type: "button",
|
|
19086
|
+
className: permissionSelectTriggerClass,
|
|
19087
|
+
"aria-label": t("permissionModeAria", { name: label }),
|
|
19088
|
+
"aria-haspopup": "menu",
|
|
19089
|
+
"aria-expanded": open,
|
|
19090
|
+
disabled: locked || busy,
|
|
19091
|
+
onClick: () => {
|
|
19092
|
+
setOpen(!open);
|
|
19093
|
+
},
|
|
19094
|
+
children: [
|
|
19095
|
+
current === void 0 ? null : /* @__PURE__ */ jsx("span", {
|
|
19096
|
+
className: permissionSelectIconClass,
|
|
19097
|
+
children: /* @__PURE__ */ jsx(ClaudePermissionModeGlyph, { mode: current })
|
|
19098
|
+
}),
|
|
19099
|
+
/* @__PURE__ */ jsx("span", {
|
|
19100
|
+
className: permissionSelectLabelClass,
|
|
19101
|
+
children: label
|
|
19102
|
+
}),
|
|
19103
|
+
/* @__PURE__ */ jsx("svg", {
|
|
19104
|
+
className: permissionSelectChevronClass,
|
|
19105
|
+
width: "12",
|
|
19106
|
+
height: "12",
|
|
19107
|
+
viewBox: "0 0 12 12",
|
|
19108
|
+
fill: "none",
|
|
19109
|
+
"aria-hidden": "true",
|
|
19110
|
+
"data-open": open ? "" : void 0,
|
|
19111
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
19112
|
+
d: "M3 4.5L6 7.5L9 4.5",
|
|
19113
|
+
stroke: "currentColor",
|
|
19114
|
+
strokeWidth: "1.5",
|
|
19115
|
+
strokeLinecap: "round",
|
|
19116
|
+
strokeLinejoin: "round"
|
|
19117
|
+
})
|
|
19118
|
+
})
|
|
19119
|
+
]
|
|
19120
|
+
})
|
|
19121
|
+
})
|
|
19122
|
+
}),
|
|
19123
|
+
/* @__PURE__ */ jsx(RiskConfirmation, {
|
|
19124
|
+
open: confirming !== null,
|
|
19125
|
+
title: t("permissionBypassTitle"),
|
|
19126
|
+
description: t("permissionBypassDescription"),
|
|
19127
|
+
acknowledgeLabel: t("permissionBypassAcknowledge"),
|
|
19128
|
+
cancelLabel: t("permissionBypassCancel"),
|
|
19129
|
+
closeLabel: t("permissionBypassClose"),
|
|
19130
|
+
confirmLabel: t("permissionBypassConfirm"),
|
|
19131
|
+
acknowledged,
|
|
19132
|
+
disabled: locked,
|
|
19133
|
+
onAcknowledgedChange: setAcknowledged,
|
|
19134
|
+
onCancel: closeConfirmation,
|
|
19135
|
+
onConfirm: () => {
|
|
19136
|
+
if (locked || !acknowledged || confirming === null) return;
|
|
19137
|
+
const mode = confirming;
|
|
19138
|
+
closeConfirmation();
|
|
19139
|
+
submit(mode);
|
|
19140
|
+
}
|
|
19141
|
+
})
|
|
19142
|
+
]
|
|
19143
|
+
});
|
|
19144
|
+
}
|
|
19145
|
+
//#endregion
|
|
19146
|
+
//#region src/client/permission-mode-api.ts
|
|
19147
|
+
function record(value) {
|
|
19148
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
19149
|
+
}
|
|
19150
|
+
/** Make `mode` the session's Claude permission mode from its next turn. */
|
|
19151
|
+
async function setClaudePermissionMode(sessionId, mode, signal) {
|
|
19152
|
+
const value = record(await pluginWrite(CLAUDE_PERMISSION_MODE_PATH, "fast", signal, { json: {
|
|
19153
|
+
sessionId,
|
|
19154
|
+
mode
|
|
19155
|
+
} }));
|
|
19156
|
+
if (value === void 0 || !isClaudePermissionMode(value.mode) || typeof value.sandbox !== "string" || typeof value.hostSynced !== "boolean") throw new Error("Invalid permission mode result.");
|
|
19157
|
+
return {
|
|
19158
|
+
mode: value.mode,
|
|
19159
|
+
sandbox: value.sandbox,
|
|
19160
|
+
hostSynced: value.hostSynced
|
|
19161
|
+
};
|
|
19162
|
+
}
|
|
19163
|
+
//#endregion
|
|
18826
19164
|
//#region src/client/ClaudePromptRefineAction.tsx
|
|
18827
19165
|
/**
|
|
18828
19166
|
* Rewrite the draft in place, from the composer's own tool row.
|
|
@@ -18986,7 +19324,7 @@ window.__ModuleLoader__.load({
|
|
|
18986
19324
|
`button[${CLAUDE_SEAT_ATTRIBUTE}]>[class*="seatIcon"]{display:none}`,
|
|
18987
19325
|
`button[${CLAUDE_SEAT_ATTRIBUTE}]::before{content:"";flex:none;width:16px;height:16px;`,
|
|
18988
19326
|
`background:${claudeMarkUrl()} center/contain no-repeat}`
|
|
18989
|
-
].join("")}`;
|
|
19327
|
+
].join("")}${`[class*="_tools"]:has(.${permissionSelectClass}) [class*="_modes"]>*:has(span[class*="_triggerLabel"]){display:none}`}`;
|
|
18990
19328
|
/** Install the stylesheet and the one DOM flag it depends on.
|
|
18991
19329
|
* @returns a disposer that removes both again. */
|
|
18992
19330
|
function restyleHostChrome() {
|
|
@@ -19049,6 +19387,12 @@ window.__ModuleLoader__.load({
|
|
|
19049
19387
|
globalSettingsNewSession: "修改仅对新建 Claude 会话生效。",
|
|
19050
19388
|
globalSettingsError: "全局设置保存失败",
|
|
19051
19389
|
outputStyle: "Output Style",
|
|
19390
|
+
permissionSelector: "权限选择器",
|
|
19391
|
+
permissionSelectorPlugin: "插件(Claude Code 权限模式)",
|
|
19392
|
+
permissionSelectorNative: "DSH 原生(三档访问模式)",
|
|
19393
|
+
permissionSelectorEffect: "插件:composer 里显示本插件的选择器,提供 Claude Code 的全部权限模式,并按下面的\"默认权限模式\"初始化新会话。DSH 原生:保留 DSH 自带的只读 / 工作区写入 / 完全权限三档下拉,权限只按沙箱映射(只读对应计划,工作区写入对应自动接受编辑,完全权限对应跳过权限),会话里的选择和默认权限模式都不再参与。立即生效;正在运行的回合保持原模式。",
|
|
19394
|
+
defaultPermissionMode: "默认权限模式",
|
|
19395
|
+
defaultPermissionModeEffect: "新建 Claude 会话时采用的 Claude Code 权限模式,DSH 的访问预设会随之切到这个模式对应的沙箱;之后在 composer 里的权限选择器改过的会话按自己的选择运行。用 /permission 之类原生方式改过沙箱的会话,以沙箱对应的模式为准;当前模型不支持自动模式时退回默认模式。修改只对之后新建的会话生效。",
|
|
19052
19396
|
renderer: "AI 输出渲染器",
|
|
19053
19397
|
rendererPlugin: "插件渲染器",
|
|
19054
19398
|
rendererNative: "DSH 原生渲染器",
|
|
@@ -19229,6 +19573,30 @@ window.__ModuleLoader__.load({
|
|
|
19229
19573
|
promptSaved: "已存为「{name}」",
|
|
19230
19574
|
promptSaveExists: "已有同名提示词,换个名字。",
|
|
19231
19575
|
promptSaveFailed: "保存失败:{message}",
|
|
19576
|
+
permissionMode: "权限模式",
|
|
19577
|
+
permissionModeAria: "权限模式:{name}",
|
|
19578
|
+
permissionModePlan: "计划",
|
|
19579
|
+
permissionModePlanHint: "只读探索并写出计划,经你批准后才执行",
|
|
19580
|
+
permissionModeDefault: "默认",
|
|
19581
|
+
permissionModeDefaultHint: "每次文件改动和命令都先询问",
|
|
19582
|
+
permissionModeAcceptEdits: "自动接受编辑",
|
|
19583
|
+
permissionModeAcceptEditsHint: "文件改动自动放行,命令仍会询问",
|
|
19584
|
+
permissionModeDontAsk: "不询问",
|
|
19585
|
+
permissionModeDontAskHint: "没有预先放行的操作直接拒绝,不弹出审批",
|
|
19586
|
+
permissionModeAuto: "自动",
|
|
19587
|
+
permissionModeAutoHint: "由 Claude Code 的分类器代为批准,拿不准的才问你",
|
|
19588
|
+
permissionModeAutoUnsupported: "当前模型不支持自动模式",
|
|
19589
|
+
permissionModeBypass: "跳过权限",
|
|
19590
|
+
permissionModeBypassHint: "跳过所有权限检查",
|
|
19591
|
+
permissionModeLocked: "回合进行中无法切换权限模式",
|
|
19592
|
+
permissionModeFailed: "切换权限模式失败:{message}",
|
|
19593
|
+
permissionModeHostKept: "DSH 未同步访问模式,Claude 仍按所选模式运行",
|
|
19594
|
+
permissionBypassTitle: "跳过所有权限检查?",
|
|
19595
|
+
permissionBypassDescription: "Claude Code 将不再请求审批,直接执行文件改动和命令。",
|
|
19596
|
+
permissionBypassAcknowledge: "我了解风险",
|
|
19597
|
+
permissionBypassCancel: "取消",
|
|
19598
|
+
permissionBypassClose: "关闭",
|
|
19599
|
+
permissionBypassConfirm: "启用",
|
|
19232
19600
|
presetHeaderHint: "当前会话运行的 Agent 预设",
|
|
19233
19601
|
diffRepository: "仓库",
|
|
19234
19602
|
repositoryLinked: "关联仓库:本会话改动过",
|
|
@@ -19493,6 +19861,12 @@ window.__ModuleLoader__.load({
|
|
|
19493
19861
|
globalSettingsNewSession: "Changes apply only to new Claude sessions.",
|
|
19494
19862
|
globalSettingsError: "Global settings save failed",
|
|
19495
19863
|
outputStyle: "Output Style",
|
|
19864
|
+
permissionSelector: "Permission selector",
|
|
19865
|
+
permissionSelectorPlugin: "Plugin (Claude Code permission modes)",
|
|
19866
|
+
permissionSelectorNative: "DSH native (three access modes)",
|
|
19867
|
+
permissionSelectorEffect: "Plugin: the composer shows this plugin's selector with every Claude Code permission mode, and new sessions start in the default mode below. DSH native: the Host's own read-only / workspace-write / full-access selector stays, and the mode follows the sandbox alone (read-only is Plan, workspace-write is Accept edits, full access is Bypass); per-session choices and the default mode are not consulted. Takes effect immediately; a running turn keeps its mode.",
|
|
19868
|
+
defaultPermissionMode: "Default permission mode",
|
|
19869
|
+
defaultPermissionModeEffect: "The Claude Code permission mode a new Claude session starts in; DSH's access preset is moved onto the sandbox that mode needs as the session is created. A session you have since changed with the composer's own selector runs its own choice. A sandbox switched natively (/permission) wins over the mode, and auto yields to Default on a model that cannot run it. Changes apply to sessions created from then on.",
|
|
19496
19870
|
renderer: "AI output renderer",
|
|
19497
19871
|
rendererPlugin: "Plugin renderer",
|
|
19498
19872
|
rendererNative: "DSH native renderer",
|
|
@@ -19673,6 +20047,30 @@ window.__ModuleLoader__.load({
|
|
|
19673
20047
|
promptSaved: "Saved as \"{name}\"",
|
|
19674
20048
|
promptSaveExists: "A prompt with that name already exists. Try another.",
|
|
19675
20049
|
promptSaveFailed: "Could not save: {message}",
|
|
20050
|
+
permissionMode: "Permission mode",
|
|
20051
|
+
permissionModeAria: "Permission mode: {name}",
|
|
20052
|
+
permissionModePlan: "Plan",
|
|
20053
|
+
permissionModePlanHint: "Read-only exploration; the plan comes back for your approval before anything runs",
|
|
20054
|
+
permissionModeDefault: "Default",
|
|
20055
|
+
permissionModeDefaultHint: "Every file edit and command asks first",
|
|
20056
|
+
permissionModeAcceptEdits: "Accept edits",
|
|
20057
|
+
permissionModeAcceptEditsHint: "File edits go through on their own; commands still ask",
|
|
20058
|
+
permissionModeDontAsk: "Don't ask",
|
|
20059
|
+
permissionModeDontAskHint: "Anything not pre-approved is refused instead of asked about",
|
|
20060
|
+
permissionModeAuto: "Auto",
|
|
20061
|
+
permissionModeAutoHint: "Claude Code's classifier approves on your behalf and asks you only when unsure",
|
|
20062
|
+
permissionModeAutoUnsupported: "The current model does not support auto mode",
|
|
20063
|
+
permissionModeBypass: "Bypass permissions",
|
|
20064
|
+
permissionModeBypassHint: "Skip every permission check",
|
|
20065
|
+
permissionModeLocked: "The permission mode cannot change while a turn is running",
|
|
20066
|
+
permissionModeFailed: "Could not switch the permission mode: {message}",
|
|
20067
|
+
permissionModeHostKept: "DSH kept its own access preset; Claude still runs the chosen mode",
|
|
20068
|
+
permissionBypassTitle: "Skip every permission check?",
|
|
20069
|
+
permissionBypassDescription: "Claude Code will run file edits and commands without asking for approval.",
|
|
20070
|
+
permissionBypassAcknowledge: "I understand the risk",
|
|
20071
|
+
permissionBypassCancel: "Cancel",
|
|
20072
|
+
permissionBypassClose: "Close",
|
|
20073
|
+
permissionBypassConfirm: "Enable",
|
|
19676
20074
|
presetHeaderHint: "The agent preset this session runs",
|
|
19677
20075
|
diffRepository: "Repository",
|
|
19678
20076
|
repositoryLinked: "Linked repository: changed by this session",
|
|
@@ -20100,6 +20498,22 @@ window.__ModuleLoader__.load({
|
|
|
20100
20498
|
diffOpen: sidebarTabs.sourceFor(CLAUDE_TAB_KINDS.diff, sessionId)
|
|
20101
20499
|
})
|
|
20102
20500
|
}, ClaudeDiffHeaderAction));
|
|
20501
|
+
ctx.slots.inject("conversation.input.left", () => ctx.slots.register({
|
|
20502
|
+
name: "conversation.input.left",
|
|
20503
|
+
id: "claude-permission-mode",
|
|
20504
|
+
order: 30,
|
|
20505
|
+
locale: namespace,
|
|
20506
|
+
inject: (sessionId) => {
|
|
20507
|
+
const scope = sessions?.scope(sessionId);
|
|
20508
|
+
return {
|
|
20509
|
+
t,
|
|
20510
|
+
setMode: (mode) => setClaudePermissionMode(sessionId, mode),
|
|
20511
|
+
...scope === void 0 || conversation === void 0 ? {} : { notify: (level, text) => {
|
|
20512
|
+
sessionInput(conversation, scope).notify(level, text);
|
|
20513
|
+
} }
|
|
20514
|
+
};
|
|
20515
|
+
}
|
|
20516
|
+
}, ClaudePermissionSelect));
|
|
20103
20517
|
ctx.slots.inject("conversation.input.left", () => ctx.slots.register({
|
|
20104
20518
|
name: "conversation.input.left",
|
|
20105
20519
|
id: "claude-prompt-save",
|