dsh-packycode-api 1.3.2 → 1.3.4
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/AGENTS.md +17 -4
- package/CHANGELOG.md +19 -0
- package/README.en.md +35 -21
- package/README.md +35 -21
- package/SECURITY.md +14 -5
- package/compatibility.json +6 -4
- package/lib/client.js +349 -0
- package/lib/index.js +2386 -207
- package/package.json +22 -15
package/lib/client.js
CHANGED
|
@@ -122,6 +122,45 @@ window.__ModuleLoader__.load({
|
|
|
122
122
|
groupsMiss: "不可用",
|
|
123
123
|
groupsPartial: "部分",
|
|
124
124
|
groupsStale: "分组为上次读取的结果",
|
|
125
|
+
keyClaudeCli: "Claude 经官方 CLI",
|
|
126
|
+
keyClaudeHttp: "Claude 经 HTTP",
|
|
127
|
+
keyClaudeCliHint: "分组 {groups} 只接受官方 Claude Code 客户端,这个 Key 的 Claude 请求由本机 Claude Code CLI 发出。",
|
|
128
|
+
keyClaudeHttpHint: "这个 Key 的 Claude 请求走插件内置的 HTTP 通道。",
|
|
129
|
+
keyClaudePinned: "(已在 Claude Code CLI 卡片中固定)",
|
|
130
|
+
cliTitle: "Claude Code CLI",
|
|
131
|
+
cliIntro: "cc 分组只接受官方 Claude Code 客户端,这些 Key 的 Claude 请求由本机的 Claude Code CLI 发出;cc-sale、cc-expensive、claude-officially 等分组继续走插件内置的 HTTP 通道。两种通道都由 DSH 执行工具、审批权限、计划模式、附件和历史,体验一致,CLI 只负责把请求发给 PackyCode。",
|
|
132
|
+
cliTransportTitle: "Claude 通道",
|
|
133
|
+
cliTransportAuto: "按分组自动",
|
|
134
|
+
cliTransportCli: "始终用 CLI",
|
|
135
|
+
cliTransportHttp: "始终用 HTTP",
|
|
136
|
+
cliTransportAutoHint: "推荐。Key 在 cc 分组时走 CLI,其它分组走 HTTP。",
|
|
137
|
+
cliTransportCliHint: "所有 Claude 请求都由 Claude Code CLI 发出,需要本机已安装 CLI。",
|
|
138
|
+
cliTransportHttpHint: "所有 Claude 请求都走 HTTP;cc 分组可能被网关识别为第三方客户端而拒绝。",
|
|
139
|
+
cliTransportNotWritable: "当前 profile 不允许写入设置,通道选择无法保存。",
|
|
140
|
+
cliTransportFailed: "保存 Claude 通道失败",
|
|
141
|
+
cliProcesses: "运行中的 CLI 会话 {live} 个 · 已启动 {opened} 次 · 续接 {continued} 次",
|
|
142
|
+
cliChecking: "正在检测本机的 Claude Code CLI…",
|
|
143
|
+
cliInstalled: "已安装",
|
|
144
|
+
cliVersion: "版本",
|
|
145
|
+
cliPath: "位置",
|
|
146
|
+
cliRecheck: "重新检测",
|
|
147
|
+
cliMissing: "未检测到 Claude Code CLI",
|
|
148
|
+
cliMissingHint: "cc 分组的 Key 需要它才能使用 Claude 模型(claude-opus-5-5、claude-sonnet-5-5、claude-haiku-5-5)。其它分组和其它模型不受影响。",
|
|
149
|
+
cliConfiguredMissing: "设置里指定的 CLI 路径不存在:{path}",
|
|
150
|
+
cliBroken: "找到了 CLI,但无法运行",
|
|
151
|
+
cliInstall: "安装 Claude Code CLI",
|
|
152
|
+
cliReinstall: "重新安装",
|
|
153
|
+
cliInstalling: "正在安装…(通常需要一两分钟,请勿关闭 DSH)",
|
|
154
|
+
cliInstallCommand: "将在本机执行:{command}(需要 Node.js 18 或更高版本)",
|
|
155
|
+
cliInstallSucceeded: "安装完成。",
|
|
156
|
+
cliInstallFailed: "安装失败",
|
|
157
|
+
cliNpmMissing: "没有找到 npm。请先从 https://nodejs.org 安装 Node.js(18 或更高版本),然后再点安装。",
|
|
158
|
+
cliPermission: "npm 没有权限写入全局目录。请在终端执行 sudo {command},或把 npm 的全局目录改到用户目录后重试。",
|
|
159
|
+
cliPermissionWindows: "npm 没有权限写入全局目录。请以管理员身份打开终端执行 {command},然后点「重新检测」。",
|
|
160
|
+
cliNetwork: "下载失败,请检查网络或 npm 镜像设置后重试。",
|
|
161
|
+
cliTimeout: "安装超时,请检查网络后重试。",
|
|
162
|
+
cliNotFoundAfterInstall: "npm 显示安装完成,但仍找不到 claude 命令。请在终端执行 claude --version 确认,然后点「重新检测」。",
|
|
163
|
+
cliWindowsNote: "Windows 上 Claude Code 还需要 Git for Windows(https://git-scm.com/downloads/win)。",
|
|
125
164
|
modelsTitle: "显示的模型",
|
|
126
165
|
modelsIntro: "切换模型时只显示已勾选的 PackyCode 模型,默认全选。修改后立即生效;已有会话仍可继续使用原模型。",
|
|
127
166
|
modelsChecking: "正在读取模型设置…",
|
|
@@ -152,6 +191,8 @@ window.__ModuleLoader__.load({
|
|
|
152
191
|
versionUpdate: "更新插件",
|
|
153
192
|
versionUpdating: "正在更新…",
|
|
154
193
|
versionUpdateFailed: "更新失败,请重试,或在插件页重新安装。",
|
|
194
|
+
versionCooling: "v{version} 发布不久,DSH 的 pnpm 要等新版本过了发布冷却期才会安装,请稍后再更新。",
|
|
195
|
+
versionCoolingUntil: "v{version} 发布不久,DSH 的 pnpm 要等新版本过了发布冷却期才会安装,{time} 之后可以更新。",
|
|
155
196
|
versionUpdated: "已更新到 v{version}。",
|
|
156
197
|
versionUpdatedHint: "新版本需要完全退出并重新打开桌面应用才会生效;只刷新页面不会重载 Host 里的插件。",
|
|
157
198
|
versionRestart: "如何重启",
|
|
@@ -293,6 +334,45 @@ window.__ModuleLoader__.load({
|
|
|
293
334
|
groupsMiss: "Not",
|
|
294
335
|
groupsPartial: "partly",
|
|
295
336
|
groupsStale: "groups from the last read",
|
|
337
|
+
keyClaudeCli: "Claude via official CLI",
|
|
338
|
+
keyClaudeHttp: "Claude via HTTP",
|
|
339
|
+
keyClaudeCliHint: "Group {groups} only serves the official Claude Code client, so this key's Claude requests are sent by this device's Claude Code CLI.",
|
|
340
|
+
keyClaudeHttpHint: "This key's Claude requests use the plugin's built-in HTTP route.",
|
|
341
|
+
keyClaudePinned: " (pinned in the Claude Code CLI card)",
|
|
342
|
+
cliTitle: "Claude Code CLI",
|
|
343
|
+
cliIntro: "The cc group only serves the official Claude Code client, so Claude requests on cc keys go through this device's Claude Code CLI; cc-sale, cc-expensive, claude-officially and other groups keep the built-in HTTP route. Either way DSH runs the tools, permissions, plan mode, attachments and history the same; the CLI only carries the request to PackyCode.",
|
|
344
|
+
cliTransportTitle: "Claude route",
|
|
345
|
+
cliTransportAuto: "By group",
|
|
346
|
+
cliTransportCli: "Always CLI",
|
|
347
|
+
cliTransportHttp: "Always HTTP",
|
|
348
|
+
cliTransportAutoHint: "Recommended. Keys in cc use the CLI; other groups use HTTP.",
|
|
349
|
+
cliTransportCliHint: "Every Claude request is sent by the Claude Code CLI, which must be installed.",
|
|
350
|
+
cliTransportHttpHint: "Every Claude request uses HTTP; the cc group may refuse it as a third-party client.",
|
|
351
|
+
cliTransportNotWritable: "This profile does not allow writing settings, so the route cannot be saved.",
|
|
352
|
+
cliTransportFailed: "Could not save the Claude route",
|
|
353
|
+
cliProcesses: "{live} CLI session(s) running · started {opened} · continued {continued}",
|
|
354
|
+
cliChecking: "Checking this device for the Claude Code CLI…",
|
|
355
|
+
cliInstalled: "Installed",
|
|
356
|
+
cliVersion: "Version",
|
|
357
|
+
cliPath: "Location",
|
|
358
|
+
cliRecheck: "Check again",
|
|
359
|
+
cliMissing: "Claude Code CLI not found",
|
|
360
|
+
cliMissingHint: "Keys in the cc group need it to use the Claude models (claude-opus-5-5, claude-sonnet-5-5, claude-haiku-5-5). Other groups and models are unaffected.",
|
|
361
|
+
cliConfiguredMissing: "The CLI path set in settings does not exist: {path}",
|
|
362
|
+
cliBroken: "The CLI was found but could not run",
|
|
363
|
+
cliInstall: "Install Claude Code CLI",
|
|
364
|
+
cliReinstall: "Reinstall",
|
|
365
|
+
cliInstalling: "Installing… (usually a minute or two; keep DSH open)",
|
|
366
|
+
cliInstallCommand: "Runs on this device: {command} (requires Node.js 18 or later)",
|
|
367
|
+
cliInstallSucceeded: "Installed.",
|
|
368
|
+
cliInstallFailed: "Install failed",
|
|
369
|
+
cliNpmMissing: "npm was not found. Install Node.js 18 or later from https://nodejs.org, then click Install again.",
|
|
370
|
+
cliPermission: "npm cannot write its global directory. Run sudo {command} in a terminal, or point npm’s global prefix at a folder you own, then retry.",
|
|
371
|
+
cliPermissionWindows: "npm cannot write its global directory. Open a terminal as administrator, run {command}, then click Check again.",
|
|
372
|
+
cliNetwork: "The download failed. Check your network or npm registry settings and retry.",
|
|
373
|
+
cliTimeout: "The install timed out. Check your network and retry.",
|
|
374
|
+
cliNotFoundAfterInstall: "npm reported success, but the claude command still cannot be found. Run claude --version in a terminal, then click Check again.",
|
|
375
|
+
cliWindowsNote: "On Windows, Claude Code also needs Git for Windows (https://git-scm.com/downloads/win).",
|
|
296
376
|
advanced: "Advanced: endpoints",
|
|
297
377
|
apiHost: "Model endpoint",
|
|
298
378
|
statusHost: "Balance endpoint",
|
|
@@ -315,6 +395,8 @@ window.__ModuleLoader__.load({
|
|
|
315
395
|
versionUpdate: "Update plugin",
|
|
316
396
|
versionUpdating: "Updating…",
|
|
317
397
|
versionUpdateFailed: "The update failed. Try again, or reinstall from the Plugins page.",
|
|
398
|
+
versionCooling: "v{version} was published recently. DSH’s pnpm installs a new version only after its release cooldown; update again later.",
|
|
399
|
+
versionCoolingUntil: "v{version} was published recently. DSH’s pnpm installs a new version only after its release cooldown; update after {time}.",
|
|
318
400
|
versionUpdated: "Updated to v{version}.",
|
|
319
401
|
versionUpdatedHint: "Quit and reopen the desktop application. Refreshing the page does not reload the plugin inside the Host.",
|
|
320
402
|
versionRestart: "How to restart",
|
|
@@ -1792,6 +1874,13 @@ window.__ModuleLoader__.load({
|
|
|
1792
1874
|
const INVITE_URL = "https://www.packyapi.ai/register?aff=Im3l";
|
|
1793
1875
|
/** How long after a search change the panel re-reads what DSH applied (the patch hot-reloads). */
|
|
1794
1876
|
const SEARCH_SETTLE_MS = 1500;
|
|
1877
|
+
/** While the CLI installs, the panel polls its status this often. */
|
|
1878
|
+
const INSTALL_POLL_MS = 2e3;
|
|
1879
|
+
const CLAUDE_MODELS = [
|
|
1880
|
+
"claude-opus-5-5",
|
|
1881
|
+
"claude-sonnet-5-5",
|
|
1882
|
+
"claude-haiku-5-5"
|
|
1883
|
+
];
|
|
1795
1884
|
const OWN_SEARCH_IDS = {
|
|
1796
1885
|
auto: "packycode-api-auto",
|
|
1797
1886
|
packycode: "packycode-api"
|
|
@@ -1928,12 +2017,32 @@ window.__ModuleLoader__.load({
|
|
|
1928
2017
|
]
|
|
1929
2018
|
}, family.name))
|
|
1930
2019
|
}),
|
|
2020
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ClaudeRoute, {
|
|
2021
|
+
group,
|
|
2022
|
+
t
|
|
2023
|
+
}),
|
|
1931
2024
|
group.stale !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1932
2025
|
className: "pkc-meta",
|
|
1933
2026
|
children: t("groupsStale")
|
|
1934
2027
|
})
|
|
1935
2028
|
] });
|
|
1936
2029
|
}
|
|
2030
|
+
/** Which transport this key's Claude requests take, when the key reaches Claude. */
|
|
2031
|
+
function ClaudeRoute({ group, t }) {
|
|
2032
|
+
const route = group.claudeTransport;
|
|
2033
|
+
if (route === void 0 || !CLAUDE_MODELS.some((id) => group.coverage?.[id] === true)) return null;
|
|
2034
|
+
const pinned = route.reason === "preference" ? t("keyClaudePinned") : "";
|
|
2035
|
+
const hint = route.transport === "cli" ? `${fill(t("keyClaudeCliHint"), { groups: (route.groups ?? []).join(" / ") || "cc" })}${pinned}` : `${t("keyClaudeHttpHint")}${pinned}`;
|
|
2036
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2037
|
+
className: "pkc-groups",
|
|
2038
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2039
|
+
className: "pkc-chip",
|
|
2040
|
+
"data-tone": route.transport === "cli" ? "info" : "neutral",
|
|
2041
|
+
title: hint,
|
|
2042
|
+
children: route.transport === "cli" ? t("keyClaudeCli") : t("keyClaudeHttp")
|
|
2043
|
+
})
|
|
2044
|
+
});
|
|
2045
|
+
}
|
|
1937
2046
|
function KeyRow({ entry, row, group, descriptions, groupsLoading, busy, rename, onAction, t }) {
|
|
1938
2047
|
const editing = rename.renaming?.id === entry.id;
|
|
1939
2048
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -2475,12 +2584,235 @@ window.__ModuleLoader__.load({
|
|
|
2475
2584
|
]
|
|
2476
2585
|
});
|
|
2477
2586
|
}
|
|
2587
|
+
const INSTALL_FAILURES = {
|
|
2588
|
+
"npm-missing": () => "cliNpmMissing",
|
|
2589
|
+
permission: (cli) => cli.platform === "win32" ? "cliPermissionWindows" : "cliPermission",
|
|
2590
|
+
network: () => "cliNetwork",
|
|
2591
|
+
timeout: () => "cliTimeout",
|
|
2592
|
+
"not-found-after-install": () => "cliNotFoundAfterInstall"
|
|
2593
|
+
};
|
|
2594
|
+
/** The sentence explaining a failed install, by the code the host classified. */
|
|
2595
|
+
function installFailure(cli, t) {
|
|
2596
|
+
const key = INSTALL_FAILURES[cli.install?.code]?.(cli);
|
|
2597
|
+
return key === void 0 ? void 0 : fill(t(key), { command: cli.command ?? "" });
|
|
2598
|
+
}
|
|
2599
|
+
/**
|
|
2600
|
+
* Which route Claude requests take, whether this device has the Claude Code
|
|
2601
|
+
* CLI those on cc keys need, and — without one — an installer.
|
|
2602
|
+
*/
|
|
2603
|
+
function ClaudeCliCard({ call, t }) {
|
|
2604
|
+
const [cli, setCli] = react.useState();
|
|
2605
|
+
const [checking, setChecking] = react.useState(false);
|
|
2606
|
+
const [saving, setSaving] = react.useState(false);
|
|
2607
|
+
const [error, setError] = react.useState();
|
|
2608
|
+
const check = react.useCallback((force = false) => {
|
|
2609
|
+
setChecking(true);
|
|
2610
|
+
setError(void 0);
|
|
2611
|
+
return call("claude-cli/status", { force }).then(setCli).catch((failure) => setError(clearMessage(failure))).finally(() => setChecking(false));
|
|
2612
|
+
}, [call]);
|
|
2613
|
+
react.useEffect(() => {
|
|
2614
|
+
check(false);
|
|
2615
|
+
}, [check]);
|
|
2616
|
+
const running = cli?.install?.state === "running";
|
|
2617
|
+
react.useEffect(() => {
|
|
2618
|
+
if (!running) return void 0;
|
|
2619
|
+
let live = true;
|
|
2620
|
+
const timer = window.setInterval(() => {
|
|
2621
|
+
call("claude-cli/status").then((value) => {
|
|
2622
|
+
if (live) setCli(value);
|
|
2623
|
+
}).catch(() => void 0);
|
|
2624
|
+
}, INSTALL_POLL_MS);
|
|
2625
|
+
return () => {
|
|
2626
|
+
live = false;
|
|
2627
|
+
window.clearInterval(timer);
|
|
2628
|
+
};
|
|
2629
|
+
}, [call, running]);
|
|
2630
|
+
const install = () => {
|
|
2631
|
+
setError(void 0);
|
|
2632
|
+
call("claude-cli/install").then(setCli).catch((failure) => setError(clearMessage(failure)));
|
|
2633
|
+
};
|
|
2634
|
+
const choose = (transport) => {
|
|
2635
|
+
setSaving(true);
|
|
2636
|
+
setError(void 0);
|
|
2637
|
+
call("claude-cli/update", { transport }).then(setCli).catch((failure) => setError(`${t("cliTransportFailed")}: ${clearMessage(failure)}`)).finally(() => setSaving(false));
|
|
2638
|
+
};
|
|
2639
|
+
const usable = cli?.installed === true && cli.version !== void 0;
|
|
2640
|
+
const failed = cli?.install?.state === "failed";
|
|
2641
|
+
const failure = cli === void 0 ? void 0 : installFailure(cli, t);
|
|
2642
|
+
const transport = cli?.transport ?? "auto";
|
|
2643
|
+
const processes = cli?.processes;
|
|
2644
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Card, {
|
|
2645
|
+
title: t("cliTitle"),
|
|
2646
|
+
aside: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
|
|
2647
|
+
disabled: checking || running,
|
|
2648
|
+
onClick: () => check(true),
|
|
2649
|
+
children: checking ? t("refreshing") : t("cliRecheck")
|
|
2650
|
+
}),
|
|
2651
|
+
children: [
|
|
2652
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2653
|
+
className: "pkc-note",
|
|
2654
|
+
children: t("cliIntro")
|
|
2655
|
+
}),
|
|
2656
|
+
cli !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2657
|
+
className: "pkc-setting",
|
|
2658
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2659
|
+
className: "pkc-label",
|
|
2660
|
+
children: t("cliTransportTitle")
|
|
2661
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [
|
|
2662
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Segmented, {
|
|
2663
|
+
label: t("cliTransportTitle"),
|
|
2664
|
+
value: transport,
|
|
2665
|
+
disabled: saving || cli.writable !== true,
|
|
2666
|
+
onChange: choose,
|
|
2667
|
+
options: [
|
|
2668
|
+
{
|
|
2669
|
+
value: "auto",
|
|
2670
|
+
label: t("cliTransportAuto")
|
|
2671
|
+
},
|
|
2672
|
+
{
|
|
2673
|
+
value: "cli",
|
|
2674
|
+
label: t("cliTransportCli")
|
|
2675
|
+
},
|
|
2676
|
+
{
|
|
2677
|
+
value: "http",
|
|
2678
|
+
label: t("cliTransportHttp")
|
|
2679
|
+
}
|
|
2680
|
+
]
|
|
2681
|
+
}),
|
|
2682
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2683
|
+
className: "pkc-note",
|
|
2684
|
+
children: t({
|
|
2685
|
+
auto: "cliTransportAutoHint",
|
|
2686
|
+
cli: "cliTransportCliHint",
|
|
2687
|
+
http: "cliTransportHttpHint"
|
|
2688
|
+
}[transport] ?? "cliTransportAutoHint")
|
|
2689
|
+
}),
|
|
2690
|
+
cli.writable !== true && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2691
|
+
className: "pkc-note",
|
|
2692
|
+
children: t("cliTransportNotWritable")
|
|
2693
|
+
})
|
|
2694
|
+
] })]
|
|
2695
|
+
}),
|
|
2696
|
+
cli === void 0 && error === void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2697
|
+
className: "pkc-note",
|
|
2698
|
+
children: t("cliChecking")
|
|
2699
|
+
}),
|
|
2700
|
+
usable && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
2701
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2702
|
+
className: "pkc-status",
|
|
2703
|
+
children: [
|
|
2704
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2705
|
+
className: "pkc-dot",
|
|
2706
|
+
"data-tone": "success"
|
|
2707
|
+
}),
|
|
2708
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("cliInstalled") }),
|
|
2709
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: `${t("cliVersion")} ${cli.version}` })
|
|
2710
|
+
]
|
|
2711
|
+
}),
|
|
2712
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2713
|
+
className: "pkc-meta",
|
|
2714
|
+
children: [
|
|
2715
|
+
t("cliPath"),
|
|
2716
|
+
" ",
|
|
2717
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2718
|
+
className: "pkc-mono",
|
|
2719
|
+
children: cli.path
|
|
2720
|
+
})
|
|
2721
|
+
]
|
|
2722
|
+
}),
|
|
2723
|
+
processes !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2724
|
+
className: "pkc-meta",
|
|
2725
|
+
children: fill(t("cliProcesses"), processes)
|
|
2726
|
+
}),
|
|
2727
|
+
cli.install?.state === "succeeded" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2728
|
+
className: "pkc-note",
|
|
2729
|
+
children: t("cliInstallSucceeded")
|
|
2730
|
+
})
|
|
2731
|
+
] }),
|
|
2732
|
+
cli !== void 0 && !usable && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2733
|
+
className: "pkc-callout",
|
|
2734
|
+
children: [
|
|
2735
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2736
|
+
className: "pkc-status",
|
|
2737
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2738
|
+
className: "pkc-dot",
|
|
2739
|
+
"data-tone": cli.installed ? "danger" : "warn"
|
|
2740
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: cli.installed ? t("cliBroken") : t("cliMissing") })]
|
|
2741
|
+
}),
|
|
2742
|
+
cli.installed && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2743
|
+
className: "pkc-meta",
|
|
2744
|
+
children: [
|
|
2745
|
+
t("cliPath"),
|
|
2746
|
+
" ",
|
|
2747
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2748
|
+
className: "pkc-mono",
|
|
2749
|
+
children: cli.path
|
|
2750
|
+
})
|
|
2751
|
+
]
|
|
2752
|
+
}), cli.error !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
|
|
2753
|
+
className: "pkc-detail",
|
|
2754
|
+
children: cli.error
|
|
2755
|
+
})] }),
|
|
2756
|
+
cli.configuredPath !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2757
|
+
className: "pkc-note",
|
|
2758
|
+
children: fill(t("cliConfiguredMissing"), { path: cli.configuredPath })
|
|
2759
|
+
}),
|
|
2760
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2761
|
+
className: "pkc-note",
|
|
2762
|
+
children: t("cliMissingHint")
|
|
2763
|
+
}),
|
|
2764
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2765
|
+
className: "pkc-split",
|
|
2766
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
|
|
2767
|
+
variant: "primary",
|
|
2768
|
+
size: "md",
|
|
2769
|
+
disabled: running || checking,
|
|
2770
|
+
onClick: install,
|
|
2771
|
+
children: running ? t("cliInstalling") : cli.installed ? t("cliReinstall") : t("cliInstall")
|
|
2772
|
+
})
|
|
2773
|
+
}),
|
|
2774
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
2775
|
+
className: "pkc-note",
|
|
2776
|
+
children: [fill(t("cliInstallCommand"), { command: cli.command ?? "" }), cli.platform === "win32" && ` ${t("cliWindowsNote")}`]
|
|
2777
|
+
})
|
|
2778
|
+
]
|
|
2779
|
+
}),
|
|
2780
|
+
failed && !usable && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2781
|
+
className: "pkc-error",
|
|
2782
|
+
children: failure === void 0 ? t("cliInstallFailed") : `${t("cliInstallFailed")} · ${failure}`
|
|
2783
|
+
}), cli.install.detail !== void 0 && cli.install.detail !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
|
|
2784
|
+
className: "pkc-detail",
|
|
2785
|
+
children: cli.install.detail
|
|
2786
|
+
})] }),
|
|
2787
|
+
error !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2788
|
+
className: "pkc-error",
|
|
2789
|
+
role: "alert",
|
|
2790
|
+
children: `${t("error")}: ${error}`
|
|
2791
|
+
})
|
|
2792
|
+
]
|
|
2793
|
+
});
|
|
2794
|
+
}
|
|
2795
|
+
/** A release-age wait can end tomorrow, so the date is part of the time. */
|
|
2796
|
+
function readDateTime(ms) {
|
|
2797
|
+
try {
|
|
2798
|
+
return new Date(ms).toLocaleString(void 0, {
|
|
2799
|
+
month: "numeric",
|
|
2800
|
+
day: "numeric",
|
|
2801
|
+
hour: "2-digit",
|
|
2802
|
+
minute: "2-digit"
|
|
2803
|
+
});
|
|
2804
|
+
} catch {
|
|
2805
|
+
return new Date(ms).toISOString().slice(0, 16).replace("T", " ");
|
|
2806
|
+
}
|
|
2807
|
+
}
|
|
2478
2808
|
function VersionCard({ call, t }) {
|
|
2479
2809
|
const [info, setInfo] = react.useState();
|
|
2480
2810
|
const [loading, setLoading] = react.useState(true);
|
|
2481
2811
|
const [error, setError] = react.useState(false);
|
|
2482
2812
|
const [updating, setUpdating] = react.useState(false);
|
|
2483
2813
|
const [updateFailed, setUpdateFailed] = react.useState(false);
|
|
2814
|
+
/** A version pnpm still holds back under the profile's release-age policy. */
|
|
2815
|
+
const [pending, setPending] = react.useState();
|
|
2484
2816
|
const [updated, setUpdated] = react.useState();
|
|
2485
2817
|
const [restartHint, setRestartHint] = react.useState(false);
|
|
2486
2818
|
const generation = react.useRef(0);
|
|
@@ -2505,7 +2837,12 @@ window.__ModuleLoader__.load({
|
|
|
2505
2837
|
const update = () => {
|
|
2506
2838
|
setUpdating(true);
|
|
2507
2839
|
setUpdateFailed(false);
|
|
2840
|
+
setPending(void 0);
|
|
2508
2841
|
call("plugin/update").then((value) => {
|
|
2842
|
+
if (value?.pending === true) {
|
|
2843
|
+
setPending(value);
|
|
2844
|
+
return;
|
|
2845
|
+
}
|
|
2509
2846
|
setUpdated(value);
|
|
2510
2847
|
setRestartHint(false);
|
|
2511
2848
|
}).catch(() => setUpdateFailed(true)).finally(() => setUpdating(false));
|
|
@@ -2567,6 +2904,14 @@ window.__ModuleLoader__.load({
|
|
|
2567
2904
|
role: "alert",
|
|
2568
2905
|
children: t("versionUpdateFailed")
|
|
2569
2906
|
}),
|
|
2907
|
+
pending !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2908
|
+
className: "pkc-note",
|
|
2909
|
+
role: "status",
|
|
2910
|
+
children: typeof pending.availableAt === "number" ? fill(t("versionCoolingUntil"), {
|
|
2911
|
+
version: pending.version,
|
|
2912
|
+
time: readDateTime(pending.availableAt)
|
|
2913
|
+
}) : fill(t("versionCooling"), { version: pending.version })
|
|
2914
|
+
}),
|
|
2570
2915
|
updated !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2571
2916
|
className: "pkc-callout",
|
|
2572
2917
|
"data-tone": "info",
|
|
@@ -2625,6 +2970,10 @@ window.__ModuleLoader__.load({
|
|
|
2625
2970
|
call,
|
|
2626
2971
|
t
|
|
2627
2972
|
}),
|
|
2973
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ClaudeCliCard, {
|
|
2974
|
+
call,
|
|
2975
|
+
t
|
|
2976
|
+
}),
|
|
2628
2977
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelsCard, {
|
|
2629
2978
|
call,
|
|
2630
2979
|
t
|