@ycodium-ai/agent-claude 0.2.2169 → 0.2.2488
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 +18 -13
- package/dist/index.js +484 -826
- package/locales/en.json +29 -0
- package/locales/zh-CN.json +29 -0
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -1,12 +1,53 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import { definePlugin } from "@ycodium-ai/plugin-api";
|
|
3
3
|
|
|
4
|
+
// src/accountUsage.ts
|
|
5
|
+
var METRICS = [
|
|
6
|
+
{
|
|
7
|
+
id: "five_hour",
|
|
8
|
+
optional: true,
|
|
9
|
+
kind: "quota-window",
|
|
10
|
+
scope: "account",
|
|
11
|
+
unit: { kind: "percent", direction: "used" },
|
|
12
|
+
usedAt: "/five_hour/utilization",
|
|
13
|
+
resetsAt: { path: "/five_hour/resets_at", format: "iso" },
|
|
14
|
+
label: "session",
|
|
15
|
+
windowSeconds: 5 * 60 * 60
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: "seven_day",
|
|
19
|
+
optional: true,
|
|
20
|
+
kind: "quota-window",
|
|
21
|
+
scope: "account",
|
|
22
|
+
unit: { kind: "percent", direction: "used" },
|
|
23
|
+
usedAt: "/seven_day/utilization",
|
|
24
|
+
resetsAt: { path: "/seven_day/resets_at", format: "iso" },
|
|
25
|
+
label: "weekly",
|
|
26
|
+
windowSeconds: 7 * 24 * 60 * 60
|
|
27
|
+
}
|
|
28
|
+
];
|
|
29
|
+
var CLAUDE_ACCOUNT_USAGE = {
|
|
30
|
+
id: "agent-claude:account-usage",
|
|
31
|
+
credentialKind: "claude-oauth",
|
|
32
|
+
request: {
|
|
33
|
+
url: "https://api.anthropic.com/api/oauth/usage",
|
|
34
|
+
headers: {
|
|
35
|
+
Accept: "application/json",
|
|
36
|
+
"anthropic-beta": "oauth-2025-04-20",
|
|
37
|
+
Authorization: { credential: "accessToken", prefix: "Bearer " }
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
ttlMs: 6e4,
|
|
41
|
+
cooldownMs: 5e3,
|
|
42
|
+
metrics: METRICS
|
|
43
|
+
};
|
|
44
|
+
|
|
4
45
|
// src/card.ts
|
|
5
46
|
var CLAUDE_DRIVER_KIND = "claudeAgent";
|
|
6
47
|
var CLAUDE_CARD = {
|
|
7
48
|
driverKind: CLAUDE_DRIVER_KIND,
|
|
8
|
-
// 手叫 Claude Code,不叫 Claude——「Claude
|
|
9
|
-
//
|
|
49
|
+
// 手叫 Claude Code,不叫 Claude——「Claude」会和模型(Anthropic · Claude Opus 5)混。
|
|
50
|
+
// 已有实例存的显示名不动,这里只影响新建实例的默认名。
|
|
10
51
|
displayName: "Claude Code",
|
|
11
52
|
iconUrl: "./assets/icon.svg",
|
|
12
53
|
commandName: "claude",
|
|
@@ -20,6 +61,7 @@ var CLAUDE_CARD = {
|
|
|
20
61
|
windowsCommand: "irm https://claude.ai/install.ps1 | iex",
|
|
21
62
|
installedPathSegment: "/.local/"
|
|
22
63
|
},
|
|
64
|
+
// `claude auth login` 没有无头选项,只能在有浏览器的机器上跑。
|
|
23
65
|
signIn: [{ kind: "command", command: "claude auth login" }],
|
|
24
66
|
deviceCodeSignInArgs: [],
|
|
25
67
|
npmPackage: "@anthropic-ai/claude-code",
|
|
@@ -30,33 +72,8 @@ var CLAUDE_CARD = {
|
|
|
30
72
|
defaultModel: "claude-sonnet-5",
|
|
31
73
|
defaultTextGenerationModel: "claude-haiku-4-5",
|
|
32
74
|
customModelIdExample: "claude-sonnet-5",
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"opus-5": "claude-opus-5",
|
|
36
|
-
"claude-opus-5.0": "claude-opus-5",
|
|
37
|
-
"claude-opus-5-0": "claude-opus-5",
|
|
38
|
-
"opus-4.8": "claude-opus-4-8",
|
|
39
|
-
"claude-opus-4.8": "claude-opus-4-8",
|
|
40
|
-
"opus-4.7": "claude-opus-4-7",
|
|
41
|
-
"claude-opus-4.7": "claude-opus-4-7",
|
|
42
|
-
"opus-4.6": "claude-opus-4-6",
|
|
43
|
-
"claude-opus-4.6": "claude-opus-4-6",
|
|
44
|
-
"claude-opus-4-6-20251117": "claude-opus-4-6",
|
|
45
|
-
sonnet: "claude-sonnet-5",
|
|
46
|
-
"sonnet-5": "claude-sonnet-5",
|
|
47
|
-
"claude-sonnet-5.0": "claude-sonnet-5",
|
|
48
|
-
"claude-sonnet-5-0": "claude-sonnet-5",
|
|
49
|
-
"sonnet-4.6": "claude-sonnet-4-6",
|
|
50
|
-
"claude-sonnet-4.6": "claude-sonnet-4-6",
|
|
51
|
-
"claude-sonnet-4-6-20251117": "claude-sonnet-4-6",
|
|
52
|
-
haiku: "claude-haiku-4-5",
|
|
53
|
-
"haiku-4.5": "claude-haiku-4-5",
|
|
54
|
-
"claude-haiku-4.5": "claude-haiku-4-5",
|
|
55
|
-
"claude-haiku-4-5-20251001": "claude-haiku-4-5"
|
|
56
|
-
},
|
|
57
|
-
modelsDevProviderIds: ["anthropic"],
|
|
58
|
-
modelsDevSlugPrefixed: false,
|
|
59
|
-
modelSlugPrefix: "",
|
|
75
|
+
// 不改写用户的选择:`opus` / `sonnet` 这类简称的含义随 CLI 版本变,由 Claude 自己解析。
|
|
76
|
+
modelSlugAliases: null,
|
|
60
77
|
mcpTransports: ["stdio", "http", "sse"],
|
|
61
78
|
pluginManaged: true,
|
|
62
79
|
verifiedSkills: true,
|
|
@@ -90,14 +107,62 @@ var CLAUDE_CARD = {
|
|
|
90
107
|
}
|
|
91
108
|
],
|
|
92
109
|
diagnostics: [],
|
|
110
|
+
accountUsage: CLAUDE_ACCOUNT_USAGE,
|
|
111
|
+
// 设置表单照这份画:带 x-ycodium-form 的属性才进表单(enabled、customModels 等另有入口,不在此列),
|
|
112
|
+
// 顺序看 x-ycodium-form-order;文案键在本插件 locales/<locale>.json 里解析,宿主不兜底。
|
|
93
113
|
configSchema: {
|
|
94
114
|
type: "object",
|
|
115
|
+
"x-ycodium-form-order": [
|
|
116
|
+
"binaryPath",
|
|
117
|
+
"homePath",
|
|
118
|
+
"credentialsPath",
|
|
119
|
+
"autoCompactWindow",
|
|
120
|
+
"launchArgs"
|
|
121
|
+
],
|
|
95
122
|
properties: {
|
|
96
|
-
binaryPath: {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
123
|
+
binaryPath: {
|
|
124
|
+
type: "string",
|
|
125
|
+
"x-ycodium-form": {
|
|
126
|
+
titleKey: "form.binaryPath.title",
|
|
127
|
+
descriptionKey: "form.binaryPath.description",
|
|
128
|
+
placeholderKey: "form.binaryPath.placeholder",
|
|
129
|
+
control: "executable-path"
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
homePath: {
|
|
133
|
+
type: "string",
|
|
134
|
+
"x-ycodium-form": {
|
|
135
|
+
titleKey: "form.homePath.title",
|
|
136
|
+
descriptionKey: "form.homePath.description",
|
|
137
|
+
placeholderKey: "form.homePath.placeholder"
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
credentialsPath: {
|
|
141
|
+
type: "string",
|
|
142
|
+
"x-ycodium-form": {
|
|
143
|
+
titleKey: "form.credentialsPath.title",
|
|
144
|
+
descriptionKey: "form.credentialsPath.description",
|
|
145
|
+
placeholderKey: "form.credentialsPath.placeholder"
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
launchArgs: {
|
|
149
|
+
type: "string",
|
|
150
|
+
"x-ycodium-form": {
|
|
151
|
+
titleKey: "form.launchArgs.title",
|
|
152
|
+
descriptionKey: "form.launchArgs.description",
|
|
153
|
+
placeholderKey: "form.launchArgs.placeholder"
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
autoCompactWindow: {
|
|
157
|
+
type: "string",
|
|
158
|
+
// 空,或 100000 到 1000000 的整数(与服务端设置校验同一条规则)。
|
|
159
|
+
pattern: "^(?:|[1-9]\\d{5}|1000000)$",
|
|
160
|
+
"x-ycodium-form": {
|
|
161
|
+
titleKey: "form.autoCompactWindow.title",
|
|
162
|
+
descriptionKey: "form.autoCompactWindow.description",
|
|
163
|
+
placeholderKey: "form.autoCompactWindow.placeholder"
|
|
164
|
+
}
|
|
165
|
+
},
|
|
101
166
|
customModels: { type: "array" },
|
|
102
167
|
enabled: { type: "boolean" },
|
|
103
168
|
driver: { type: "string" },
|
|
@@ -109,19 +174,29 @@ var CLAUDE_CARD = {
|
|
|
109
174
|
modelConnectivity: {
|
|
110
175
|
dialects: ["anthropic-messages"],
|
|
111
176
|
acceptsExternalEndpoints: true,
|
|
112
|
-
// claude 认 origin:CLI
|
|
113
|
-
//
|
|
177
|
+
// claude 认 origin:CLI 自己在 `ANTHROPIC_BASE_URL` 后追加 `/v1/messages`,所以实例上
|
|
178
|
+
// 填的是纯 origin。
|
|
114
179
|
nativePathSuffix: "/v1/messages",
|
|
115
|
-
//
|
|
116
|
-
//
|
|
180
|
+
// 用户在实例上填这几个变量接模型服务(ADR-0032)。CLI 两个凭据变量都认:
|
|
181
|
+
// `ANTHROPIC_AUTH_TOKEN` 走 bearer,`ANTHROPIC_API_KEY` 走 x-api-key。
|
|
117
182
|
baseUrlEnvKey: "ANTHROPIC_BASE_URL",
|
|
118
183
|
credentialEnvKey: "ANTHROPIC_AUTH_TOKEN",
|
|
119
184
|
alternateCredentialEnvKeys: ["ANTHROPIC_API_KEY"],
|
|
185
|
+
// 设成真值就改连云厂商托管的 Claude,不再用订阅登录。名单取自 claude-agent-sdk
|
|
186
|
+
// 0.3.170 的 `sdk.mjs`:它按 1/true/yes/on 判这五个开关。设置页据此给这样的实例
|
|
187
|
+
// 单独的凭据目录,不让它顶着这台机器上登录的订阅。
|
|
188
|
+
backendSwitchEnvKeys: [
|
|
189
|
+
"CLAUDE_CODE_USE_BEDROCK",
|
|
190
|
+
"CLAUDE_CODE_USE_VERTEX",
|
|
191
|
+
"CLAUDE_CODE_USE_FOUNDRY",
|
|
192
|
+
"CLAUDE_CODE_USE_ANTHROPIC_AWS",
|
|
193
|
+
"CLAUDE_CODE_USE_MANTLE"
|
|
194
|
+
],
|
|
120
195
|
supportsNativeSubscription: true,
|
|
121
|
-
//
|
|
122
|
-
//
|
|
123
|
-
//
|
|
124
|
-
//
|
|
196
|
+
// 七个档位变量:claude 的 opus / sonnet / haiku / fable 档与子代理、小快模型各读一个,
|
|
197
|
+
// 只设 `ANTHROPIC_MODEL` 的话子代理会跑回默认档。名单与旧 `CLAUDE_SETTINGS_MODEL_ENV_KEYS`
|
|
198
|
+
// 逐字相同(含 2026-09-09 从 2.1.265 二进制核实出来的 fable 那一条)。宿主不再替换
|
|
199
|
+
// `$model`,这一栏只是记录。
|
|
125
200
|
extraEnv: [
|
|
126
201
|
{ name: "ANTHROPIC_MODEL", value: "$model" },
|
|
127
202
|
{ name: "ANTHROPIC_DEFAULT_OPUS_MODEL", value: "$model" },
|
|
@@ -135,8 +210,8 @@ var CLAUDE_CARD = {
|
|
|
135
210
|
};
|
|
136
211
|
|
|
137
212
|
// src/claudeInstance.ts
|
|
138
|
-
import * as
|
|
139
|
-
import * as
|
|
213
|
+
import * as NodeOS8 from "node:os";
|
|
214
|
+
import * as NodePath8 from "node:path";
|
|
140
215
|
|
|
141
216
|
// ../../node_modules/.pnpm/@anthropic-ai+claude-agent-sdk@0.3.170_@anthropic-ai+sdk@0.93.0_zod@4.6.5__@modelcontex_64204813d4dba2ebc464c3aa751485a4/node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs
|
|
142
217
|
import { createRequire as xz } from "node:module";
|
|
@@ -19569,11 +19644,7 @@ function HU(e, t) {
|
|
|
19569
19644
|
}
|
|
19570
19645
|
|
|
19571
19646
|
// src/claudeInstance.ts
|
|
19572
|
-
import {
|
|
19573
|
-
mergeLaunchEnv as mergeLaunchEnv2,
|
|
19574
|
-
withoutBrainSlots,
|
|
19575
|
-
brainSlotEnvKeys as brainSlotEnvKeys3
|
|
19576
|
-
} from "@ycodium-ai/plugin-api/executor";
|
|
19647
|
+
import { mergeLaunchEnv as mergeLaunchEnv2 } from "@ycodium-ai/plugin-api/executor";
|
|
19577
19648
|
|
|
19578
19649
|
// src/claudeAccount.ts
|
|
19579
19650
|
import * as NodeFS from "node:fs";
|
|
@@ -19731,10 +19802,6 @@ function expandHomePath(value) {
|
|
|
19731
19802
|
|
|
19732
19803
|
// src/claudeHome.ts
|
|
19733
19804
|
var CLAUDE_CREDENTIALS_DIR_ENVIRONMENT_VARIABLE = "CLAUDE_SECURESTORAGE_CONFIG_DIR";
|
|
19734
|
-
var CLAUDE_ROUTED_HOME_DIR_NAME = "claude-home";
|
|
19735
|
-
function claudeRoutedHomePath(pluginDataDirPath) {
|
|
19736
|
-
return NodePath4.join(pluginDataDirPath, CLAUDE_ROUTED_HOME_DIR_NAME);
|
|
19737
|
-
}
|
|
19738
19805
|
function resolveClaudeHomePath(homePath) {
|
|
19739
19806
|
const trimmed = homePath.trim();
|
|
19740
19807
|
return NodePath4.resolve(trimmed.length > 0 ? expandHomePath(trimmed) : NodeOS4.homedir());
|
|
@@ -19759,26 +19826,9 @@ function resolveClaudeCredentialsDirPath(credentialsPath) {
|
|
|
19759
19826
|
return NodePath4.resolve(expandHomePath(trimmed));
|
|
19760
19827
|
}
|
|
19761
19828
|
function resolveClaudeHomeLayout(input) {
|
|
19762
|
-
const userConfigDirPath = resolveClaudeConfigDirPath(input.homePath, input.environment ?? {});
|
|
19763
|
-
const instanceConfigDirPath = input.homePath.trim().length > 0 ? resolveClaudeHomePath(input.homePath) : void 0;
|
|
19764
|
-
const instanceCredentialsDirPath = resolveClaudeCredentialsDirPath(input.credentialsPath);
|
|
19765
|
-
const routedHomePath = input.routedHomePath?.trim() ?? "";
|
|
19766
|
-
if (routedHomePath.length === 0 || instanceConfigDirPath !== void 0 || instanceCredentialsDirPath !== null) {
|
|
19767
|
-
return {
|
|
19768
|
-
mode: "instance",
|
|
19769
|
-
userConfigDirPath,
|
|
19770
|
-
configDirPath: instanceConfigDirPath,
|
|
19771
|
-
credentialsDirPath: instanceCredentialsDirPath ?? void 0
|
|
19772
|
-
};
|
|
19773
|
-
}
|
|
19774
|
-
const resolvedRoutedHomePath = NodePath4.resolve(expandHomePath(routedHomePath));
|
|
19775
19829
|
return {
|
|
19776
|
-
|
|
19777
|
-
|
|
19778
|
-
configDirPath: resolvedRoutedHomePath,
|
|
19779
|
-
// 登录目录显式钉成影子目录本身。不设这个变量时 CLI 本来就把凭据放配置目录,但
|
|
19780
|
-
// 「登录去哪」正是这次要修的东西,不靠默认值。
|
|
19781
|
-
credentialsDirPath: resolvedRoutedHomePath
|
|
19830
|
+
configDirPath: input.homePath.trim().length > 0 ? resolveClaudeHomePath(input.homePath) : void 0,
|
|
19831
|
+
credentialsDirPath: resolveClaudeCredentialsDirPath(input.credentialsPath) ?? void 0
|
|
19782
19832
|
};
|
|
19783
19833
|
}
|
|
19784
19834
|
function claudeHomeVariables(layout) {
|
|
@@ -19792,8 +19842,7 @@ function makeClaudeEnvironment(config, baseEnv) {
|
|
|
19792
19842
|
const variables = claudeHomeVariables(
|
|
19793
19843
|
resolveClaudeHomeLayout({
|
|
19794
19844
|
homePath: config.homePath,
|
|
19795
|
-
credentialsPath: config.credentialsPath
|
|
19796
|
-
environment: resolvedBaseEnv
|
|
19845
|
+
credentialsPath: config.credentialsPath
|
|
19797
19846
|
})
|
|
19798
19847
|
);
|
|
19799
19848
|
if (Object.keys(variables).length === 0) return resolvedBaseEnv;
|
|
@@ -19820,6 +19869,60 @@ function claudeSignInCommand(credentialsPath, platform) {
|
|
|
19820
19869
|
return withClaudeCredentialsDir({ command, credentialsDirPath, platform });
|
|
19821
19870
|
}
|
|
19822
19871
|
|
|
19872
|
+
// src/claudeSkills.ts
|
|
19873
|
+
import * as NodeFSP from "node:fs/promises";
|
|
19874
|
+
import * as NodePath5 from "node:path";
|
|
19875
|
+
var FRONT_MATTER_KEY = /^(name|description):[ \t]*(.*)$/;
|
|
19876
|
+
var BLOCK_SCALAR = /^[|>][+-]?$/;
|
|
19877
|
+
function parseSkillFrontMatter(contents) {
|
|
19878
|
+
const lines = contents.split(/\r?\n/);
|
|
19879
|
+
if (lines[0]?.trim() !== "---") return {};
|
|
19880
|
+
const values = {};
|
|
19881
|
+
for (let index = 1; index < lines.length; index += 1) {
|
|
19882
|
+
const line = lines[index] ?? "";
|
|
19883
|
+
if (line.trim() === "---") break;
|
|
19884
|
+
const match = FRONT_MATTER_KEY.exec(line);
|
|
19885
|
+
if (match === null) continue;
|
|
19886
|
+
const key = match[1];
|
|
19887
|
+
let value = (match[2] ?? "").trim();
|
|
19888
|
+
if (BLOCK_SCALAR.test(value)) {
|
|
19889
|
+
const block = [];
|
|
19890
|
+
while (index + 1 < lines.length) {
|
|
19891
|
+
const next = lines[index + 1] ?? "";
|
|
19892
|
+
if (next.trim() === "---" || next.trim().length > 0 && !/^[ \t]/.test(next)) break;
|
|
19893
|
+
index += 1;
|
|
19894
|
+
if (next.trim().length > 0) block.push(next.trim());
|
|
19895
|
+
}
|
|
19896
|
+
value = block.join(value.startsWith("|") ? "\n" : " ");
|
|
19897
|
+
} else {
|
|
19898
|
+
value = value.replace(/^(["'])(.*)\1$/, "$2").trim();
|
|
19899
|
+
}
|
|
19900
|
+
if (value.length > 0 && values[key] === void 0) values[key] = value;
|
|
19901
|
+
}
|
|
19902
|
+
return values;
|
|
19903
|
+
}
|
|
19904
|
+
async function discoverClaudeSkills(configDirPath) {
|
|
19905
|
+
const root = NodePath5.join(configDirPath, "skills");
|
|
19906
|
+
const entries = await NodeFSP.readdir(root).catch(() => []);
|
|
19907
|
+
const skills = /* @__PURE__ */ new Map();
|
|
19908
|
+
for (const entry of entries.toSorted()) {
|
|
19909
|
+
const skillPath = NodePath5.join(root, entry, "SKILL.md");
|
|
19910
|
+
const contents = await NodeFSP.readFile(skillPath, "utf8").catch(() => void 0);
|
|
19911
|
+
if (contents === void 0) continue;
|
|
19912
|
+
const frontMatter = parseSkillFrontMatter(contents);
|
|
19913
|
+
const name = frontMatter.name ?? entry.trim();
|
|
19914
|
+
if (name.length === 0) continue;
|
|
19915
|
+
skills.set(name, {
|
|
19916
|
+
name,
|
|
19917
|
+
path: skillPath,
|
|
19918
|
+
enabled: true,
|
|
19919
|
+
scope: "user",
|
|
19920
|
+
...frontMatter.description === void 0 ? {} : { description: frontMatter.description }
|
|
19921
|
+
});
|
|
19922
|
+
}
|
|
19923
|
+
return [...skills.values()].toSorted((left, right) => left.name.localeCompare(right.name));
|
|
19924
|
+
}
|
|
19925
|
+
|
|
19823
19926
|
// src/config.ts
|
|
19824
19927
|
var CLAUDE_AUTO_COMPACT_WINDOW_PATTERN = /^(?:|[1-9]\d{5}|1000000)$/;
|
|
19825
19928
|
function isRecord2(value) {
|
|
@@ -20026,8 +20129,8 @@ var EventBus = class {
|
|
|
20026
20129
|
const queued = this.#queued.shift();
|
|
20027
20130
|
if (queued !== void 0) return Promise.resolve({ done: false, value: queued });
|
|
20028
20131
|
if (this.#closed) return Promise.resolve({ done: true, value: void 0 });
|
|
20029
|
-
return new Promise((
|
|
20030
|
-
this.#waiters.push(
|
|
20132
|
+
return new Promise((resolve2) => {
|
|
20133
|
+
this.#waiters.push(resolve2);
|
|
20031
20134
|
});
|
|
20032
20135
|
}
|
|
20033
20136
|
};
|
|
@@ -20043,290 +20146,17 @@ var CLAUDE_CUSTOM_MODEL_THINKING_SELECT = {
|
|
|
20043
20146
|
id: "effort",
|
|
20044
20147
|
label: "Reasoning"
|
|
20045
20148
|
};
|
|
20046
|
-
var MINIMUM_CLAUDE_OPUS_5_VERSION = "2.1.219";
|
|
20047
|
-
var MINIMUM_CLAUDE_FABLE_5_VERSION = "2.1.169";
|
|
20048
|
-
var MINIMUM_CLAUDE_OPUS_4_8_VERSION = "2.1.154";
|
|
20049
|
-
var MINIMUM_CLAUDE_OPUS_4_7_VERSION = "2.1.111";
|
|
20050
|
-
var CURRENT_CLAUDE_MODELS = /* @__PURE__ */ new Set(["claude-fable-5", "claude-opus-5", "claude-sonnet-5"]);
|
|
20051
|
-
function isLegacyClaudeModel(model) {
|
|
20052
|
-
return !CURRENT_CLAUDE_MODELS.has(model);
|
|
20053
|
-
}
|
|
20054
|
-
function select(id2, label, options, promptInjectedValues) {
|
|
20055
|
-
return {
|
|
20056
|
-
type: "select",
|
|
20057
|
-
id: id2,
|
|
20058
|
-
label,
|
|
20059
|
-
options: options.map((option) => ({
|
|
20060
|
-
id: option.value,
|
|
20061
|
-
label: option.label,
|
|
20062
|
-
...option.isDefault ? { isDefault: true } : {},
|
|
20063
|
-
...option.description ? { description: option.description } : {}
|
|
20064
|
-
})),
|
|
20065
|
-
...promptInjectedValues ? { promptInjectedValues } : {}
|
|
20066
|
-
};
|
|
20067
|
-
}
|
|
20068
|
-
function booleanOption(id2, label) {
|
|
20069
|
-
return { type: "boolean", id: id2, label };
|
|
20070
|
-
}
|
|
20071
|
-
var ULTRACODE = {
|
|
20072
|
-
value: "ultracode",
|
|
20073
|
-
label: "Ultracode",
|
|
20074
|
-
description: "xhigh effort plus multi-agent workflow orchestration"
|
|
20075
|
-
};
|
|
20076
|
-
var CLAUDE_MODEL_CATALOG = [
|
|
20077
|
-
{
|
|
20078
|
-
slug: "claude-fable-5",
|
|
20079
|
-
name: "Claude Fable 5",
|
|
20080
|
-
isCustom: false,
|
|
20081
|
-
capabilities: {
|
|
20082
|
-
optionDescriptors: [
|
|
20083
|
-
select(
|
|
20084
|
-
"effort",
|
|
20085
|
-
"Reasoning",
|
|
20086
|
-
[
|
|
20087
|
-
{ value: "low", label: "Low" },
|
|
20088
|
-
{ value: "medium", label: "Medium" },
|
|
20089
|
-
{ value: "high", label: "High", isDefault: true },
|
|
20090
|
-
{ value: "xhigh", label: "Extra High" },
|
|
20091
|
-
{ value: "max", label: "Max" },
|
|
20092
|
-
ULTRACODE,
|
|
20093
|
-
{ value: "ultrathink", label: "Ultrathink" }
|
|
20094
|
-
],
|
|
20095
|
-
["ultrathink"]
|
|
20096
|
-
),
|
|
20097
|
-
select("contextWindow", "Context Window", [
|
|
20098
|
-
{ value: "200k", label: "200k" },
|
|
20099
|
-
{ value: "1m", label: "1M", isDefault: true }
|
|
20100
|
-
])
|
|
20101
|
-
]
|
|
20102
|
-
}
|
|
20103
|
-
},
|
|
20104
|
-
{
|
|
20105
|
-
slug: "claude-opus-5",
|
|
20106
|
-
name: "Claude Opus 5",
|
|
20107
|
-
isCustom: false,
|
|
20108
|
-
capabilities: {
|
|
20109
|
-
optionDescriptors: [
|
|
20110
|
-
select(
|
|
20111
|
-
"effort",
|
|
20112
|
-
"Reasoning",
|
|
20113
|
-
[
|
|
20114
|
-
{ value: "low", label: "Low" },
|
|
20115
|
-
{ value: "medium", label: "Medium" },
|
|
20116
|
-
{ value: "high", label: "High", isDefault: true },
|
|
20117
|
-
{ value: "xhigh", label: "Extra High" },
|
|
20118
|
-
{ value: "max", label: "Max" },
|
|
20119
|
-
ULTRACODE,
|
|
20120
|
-
{ value: "ultrathink", label: "Ultrathink" }
|
|
20121
|
-
],
|
|
20122
|
-
["ultrathink"]
|
|
20123
|
-
),
|
|
20124
|
-
booleanOption("fastMode", "Fast Mode"),
|
|
20125
|
-
select("contextWindow", "Context Window", [
|
|
20126
|
-
{ value: "200k", label: "200k" },
|
|
20127
|
-
{ value: "1m", label: "1M", isDefault: true }
|
|
20128
|
-
])
|
|
20129
|
-
]
|
|
20130
|
-
}
|
|
20131
|
-
},
|
|
20132
|
-
{
|
|
20133
|
-
slug: "claude-opus-4-8",
|
|
20134
|
-
name: "Claude Opus 4.8",
|
|
20135
|
-
isCustom: false,
|
|
20136
|
-
capabilities: {
|
|
20137
|
-
optionDescriptors: [
|
|
20138
|
-
select(
|
|
20139
|
-
"effort",
|
|
20140
|
-
"Reasoning",
|
|
20141
|
-
[
|
|
20142
|
-
{ value: "low", label: "Low" },
|
|
20143
|
-
{ value: "medium", label: "Medium" },
|
|
20144
|
-
{ value: "high", label: "High", isDefault: true },
|
|
20145
|
-
{ value: "xhigh", label: "Extra High" },
|
|
20146
|
-
{ value: "max", label: "Max" },
|
|
20147
|
-
ULTRACODE,
|
|
20148
|
-
{ value: "ultrathink", label: "Ultrathink" }
|
|
20149
|
-
],
|
|
20150
|
-
["ultrathink"]
|
|
20151
|
-
),
|
|
20152
|
-
booleanOption("fastMode", "Fast Mode")
|
|
20153
|
-
]
|
|
20154
|
-
}
|
|
20155
|
-
},
|
|
20156
|
-
{
|
|
20157
|
-
slug: "claude-opus-4-7",
|
|
20158
|
-
name: "Claude Opus 4.7",
|
|
20159
|
-
isCustom: false,
|
|
20160
|
-
capabilities: {
|
|
20161
|
-
optionDescriptors: [
|
|
20162
|
-
select(
|
|
20163
|
-
"effort",
|
|
20164
|
-
"Reasoning",
|
|
20165
|
-
[
|
|
20166
|
-
{ value: "low", label: "Low" },
|
|
20167
|
-
{ value: "medium", label: "Medium" },
|
|
20168
|
-
{ value: "high", label: "High" },
|
|
20169
|
-
{ value: "xhigh", label: "Extra High", isDefault: true },
|
|
20170
|
-
{ value: "max", label: "Max" },
|
|
20171
|
-
{ value: "ultrathink", label: "Ultrathink" }
|
|
20172
|
-
],
|
|
20173
|
-
["ultrathink"]
|
|
20174
|
-
),
|
|
20175
|
-
booleanOption("fastMode", "Fast Mode")
|
|
20176
|
-
]
|
|
20177
|
-
}
|
|
20178
|
-
},
|
|
20179
|
-
{
|
|
20180
|
-
slug: "claude-opus-4-6",
|
|
20181
|
-
name: "Claude Opus 4.6",
|
|
20182
|
-
isCustom: false,
|
|
20183
|
-
capabilities: {
|
|
20184
|
-
optionDescriptors: [
|
|
20185
|
-
select(
|
|
20186
|
-
"effort",
|
|
20187
|
-
"Reasoning",
|
|
20188
|
-
[
|
|
20189
|
-
{ value: "low", label: "Low" },
|
|
20190
|
-
{ value: "medium", label: "Medium" },
|
|
20191
|
-
{ value: "high", label: "High", isDefault: true },
|
|
20192
|
-
{ value: "max", label: "Max" },
|
|
20193
|
-
{ value: "ultrathink", label: "Ultrathink" }
|
|
20194
|
-
],
|
|
20195
|
-
["ultrathink"]
|
|
20196
|
-
),
|
|
20197
|
-
booleanOption("fastMode", "Fast Mode"),
|
|
20198
|
-
select("contextWindow", "Context Window", [
|
|
20199
|
-
{ value: "200k", label: "200k" },
|
|
20200
|
-
{ value: "1m", label: "1M", isDefault: true }
|
|
20201
|
-
])
|
|
20202
|
-
]
|
|
20203
|
-
}
|
|
20204
|
-
},
|
|
20205
|
-
{
|
|
20206
|
-
slug: "claude-opus-4-5",
|
|
20207
|
-
name: "Claude Opus 4.5",
|
|
20208
|
-
isCustom: false,
|
|
20209
|
-
capabilities: {
|
|
20210
|
-
optionDescriptors: [
|
|
20211
|
-
select("effort", "Reasoning", [
|
|
20212
|
-
{ value: "low", label: "Low" },
|
|
20213
|
-
{ value: "medium", label: "Medium" },
|
|
20214
|
-
{ value: "high", label: "High", isDefault: true },
|
|
20215
|
-
{ value: "max", label: "Max" }
|
|
20216
|
-
]),
|
|
20217
|
-
booleanOption("fastMode", "Fast Mode")
|
|
20218
|
-
]
|
|
20219
|
-
}
|
|
20220
|
-
},
|
|
20221
|
-
{
|
|
20222
|
-
slug: "claude-sonnet-5",
|
|
20223
|
-
name: "Claude Sonnet 5",
|
|
20224
|
-
isCustom: false,
|
|
20225
|
-
capabilities: {
|
|
20226
|
-
optionDescriptors: [
|
|
20227
|
-
select(
|
|
20228
|
-
"effort",
|
|
20229
|
-
"Reasoning",
|
|
20230
|
-
[
|
|
20231
|
-
{ value: "low", label: "Low" },
|
|
20232
|
-
{ value: "medium", label: "Medium" },
|
|
20233
|
-
{ value: "high", label: "High", isDefault: true },
|
|
20234
|
-
{ value: "xhigh", label: "Extra High" },
|
|
20235
|
-
{ value: "max", label: "Max" },
|
|
20236
|
-
{ value: "ultrathink", label: "Ultrathink" }
|
|
20237
|
-
],
|
|
20238
|
-
["ultrathink"]
|
|
20239
|
-
),
|
|
20240
|
-
select("contextWindow", "Context Window", [
|
|
20241
|
-
{ value: "200k", label: "200k", isDefault: true },
|
|
20242
|
-
{ value: "1m", label: "1M" }
|
|
20243
|
-
])
|
|
20244
|
-
]
|
|
20245
|
-
}
|
|
20246
|
-
},
|
|
20247
|
-
{
|
|
20248
|
-
slug: "claude-sonnet-4-6",
|
|
20249
|
-
name: "Claude Sonnet 4.6",
|
|
20250
|
-
isCustom: false,
|
|
20251
|
-
capabilities: {
|
|
20252
|
-
optionDescriptors: [
|
|
20253
|
-
select(
|
|
20254
|
-
"effort",
|
|
20255
|
-
"Reasoning",
|
|
20256
|
-
[
|
|
20257
|
-
{ value: "low", label: "Low" },
|
|
20258
|
-
{ value: "medium", label: "Medium" },
|
|
20259
|
-
{ value: "high", label: "High", isDefault: true },
|
|
20260
|
-
{ value: "max", label: "Max" },
|
|
20261
|
-
{ value: "ultrathink", label: "Ultrathink" }
|
|
20262
|
-
],
|
|
20263
|
-
["ultrathink"]
|
|
20264
|
-
),
|
|
20265
|
-
select("contextWindow", "Context Window", [
|
|
20266
|
-
{ value: "200k", label: "200k", isDefault: true },
|
|
20267
|
-
{ value: "1m", label: "1M" }
|
|
20268
|
-
])
|
|
20269
|
-
]
|
|
20270
|
-
}
|
|
20271
|
-
},
|
|
20272
|
-
{
|
|
20273
|
-
slug: "claude-haiku-4-5",
|
|
20274
|
-
name: "Claude Haiku 4.5",
|
|
20275
|
-
isCustom: false,
|
|
20276
|
-
capabilities: {
|
|
20277
|
-
optionDescriptors: [booleanOption("thinking", "Thinking")]
|
|
20278
|
-
}
|
|
20279
|
-
}
|
|
20280
|
-
];
|
|
20281
|
-
var BUILT_IN_MODELS = CLAUDE_MODEL_CATALOG.map(
|
|
20282
|
-
(model) => isLegacyClaudeModel(model.slug) ? { ...model, isLegacy: true } : model
|
|
20283
|
-
);
|
|
20284
|
-
var CLAUDE_XHIGH_SLUGS = /* @__PURE__ */ new Set([
|
|
20285
|
-
"claude-fable-5",
|
|
20286
|
-
"claude-opus-5",
|
|
20287
|
-
"claude-opus-4-8",
|
|
20288
|
-
"claude-sonnet-5"
|
|
20289
|
-
]);
|
|
20290
|
-
function compareSemverVersions(left, right) {
|
|
20291
|
-
const parse = (value) => {
|
|
20292
|
-
const match = value.trim().replace(/^v/, "").match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
20293
|
-
if (!match) return null;
|
|
20294
|
-
return [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
20295
|
-
};
|
|
20296
|
-
const a = parse(left);
|
|
20297
|
-
const b3 = parse(right);
|
|
20298
|
-
if (!a || !b3) return left.localeCompare(right);
|
|
20299
|
-
if (a[0] !== b3[0]) return a[0] - b3[0];
|
|
20300
|
-
if (a[1] !== b3[1]) return a[1] - b3[1];
|
|
20301
|
-
return a[2] - b3[2];
|
|
20302
|
-
}
|
|
20303
|
-
function supportsVersion(version, minimum) {
|
|
20304
|
-
return version ? compareSemverVersions(version, minimum) >= 0 : false;
|
|
20305
|
-
}
|
|
20306
|
-
function getBuiltInClaudeModelsForVersion(version) {
|
|
20307
|
-
return BUILT_IN_MODELS.filter((model) => {
|
|
20308
|
-
if (model.slug === "claude-opus-5")
|
|
20309
|
-
return supportsVersion(version, MINIMUM_CLAUDE_OPUS_5_VERSION);
|
|
20310
|
-
if (model.slug === "claude-fable-5")
|
|
20311
|
-
return supportsVersion(version, MINIMUM_CLAUDE_FABLE_5_VERSION);
|
|
20312
|
-
if (model.slug === "claude-opus-4-8")
|
|
20313
|
-
return supportsVersion(version, MINIMUM_CLAUDE_OPUS_4_8_VERSION);
|
|
20314
|
-
if (model.slug === "claude-opus-4-7")
|
|
20315
|
-
return supportsVersion(version, MINIMUM_CLAUDE_OPUS_4_7_VERSION);
|
|
20316
|
-
return true;
|
|
20317
|
-
});
|
|
20318
|
-
}
|
|
20319
20149
|
function parseGenericCliVersion(output) {
|
|
20320
|
-
const match = output.match(/\
|
|
20150
|
+
const match = output.match(/\bv?(\d+\.\d+\.\d+)\b/);
|
|
20321
20151
|
return match?.[1] ?? null;
|
|
20322
20152
|
}
|
|
20323
20153
|
function normalizeCustomModelSlug(slug) {
|
|
20324
20154
|
return slug.trim();
|
|
20325
20155
|
}
|
|
20326
|
-
function knownClaudeModelCapabilities(model, customModels) {
|
|
20156
|
+
function knownClaudeModelCapabilities(model, catalog, customModels) {
|
|
20327
20157
|
const slug = model?.trim();
|
|
20328
|
-
const
|
|
20329
|
-
if (
|
|
20158
|
+
const fromCatalog = catalog.find((candidate) => candidate.slug === slug)?.capabilities;
|
|
20159
|
+
if (fromCatalog) return fromCatalog;
|
|
20330
20160
|
const custom = customModels?.find(
|
|
20331
20161
|
(candidate) => normalizeCustomModelSlug(candidate.slug) === slug
|
|
20332
20162
|
);
|
|
@@ -20346,8 +20176,8 @@ function knownClaudeModelCapabilities(model, customModels) {
|
|
|
20346
20176
|
}
|
|
20347
20177
|
return void 0;
|
|
20348
20178
|
}
|
|
20349
|
-
function claudeModelCapabilities(model, customModels) {
|
|
20350
|
-
return knownClaudeModelCapabilities(model, customModels) ?? DEFAULT_CLAUDE_MODEL_CAPABILITIES;
|
|
20179
|
+
function claudeModelCapabilities(model, catalog, customModels) {
|
|
20180
|
+
return knownClaudeModelCapabilities(model, catalog, customModels) ?? DEFAULT_CLAUDE_MODEL_CAPABILITIES;
|
|
20351
20181
|
}
|
|
20352
20182
|
function isRecord3(value) {
|
|
20353
20183
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -20384,59 +20214,34 @@ function modelIdFromSelection(selection) {
|
|
|
20384
20214
|
}
|
|
20385
20215
|
function currentSelectValue(descriptor, raw) {
|
|
20386
20216
|
if (raw && descriptor.options.some((option) => option.id === raw)) return raw;
|
|
20387
|
-
return descriptor.options.find((option) => option.isDefault)?.id
|
|
20217
|
+
return descriptor.options.find((option) => option.isDefault)?.id;
|
|
20388
20218
|
}
|
|
20389
20219
|
function resolveClaudeEffort(caps, raw) {
|
|
20390
20220
|
const descriptor = caps.optionDescriptors.find((entry) => entry.id === "effort");
|
|
20391
20221
|
if (!descriptor || descriptor.type !== "select") return void 0;
|
|
20392
20222
|
return currentSelectValue(descriptor, raw);
|
|
20393
20223
|
}
|
|
20394
|
-
function
|
|
20395
|
-
const slug = model?.trim();
|
|
20396
|
-
if (slug !== void 0 && CLAUDE_XHIGH_SLUGS.has(slug)) return true;
|
|
20397
|
-
if (knownClaudeModelCapabilities(slug)) return false;
|
|
20398
|
-
if (!caps) return false;
|
|
20399
|
-
const descriptor = caps.optionDescriptors.find((candidate) => candidate.id === "effort");
|
|
20400
|
-
return descriptor?.type === "select" ? descriptor.options.some((option) => option.id === "xhigh") : false;
|
|
20401
|
-
}
|
|
20402
|
-
function normalizeClaudeCliEffort(effort, model, caps) {
|
|
20224
|
+
function normalizeClaudeCliEffort(effort) {
|
|
20403
20225
|
if (!effort || effort === "ultrathink") {
|
|
20404
20226
|
return void 0;
|
|
20405
20227
|
}
|
|
20406
20228
|
if (effort === "ultracode") {
|
|
20407
20229
|
return "xhigh";
|
|
20408
20230
|
}
|
|
20409
|
-
if (effort === "xhigh" && !acceptsClaudeXhigh(model, caps)) {
|
|
20410
|
-
return "max";
|
|
20411
|
-
}
|
|
20412
|
-
if (effort === "max" && model === "claude-sonnet-4-6") {
|
|
20413
|
-
return "high";
|
|
20414
|
-
}
|
|
20415
20231
|
return effort;
|
|
20416
20232
|
}
|
|
20417
20233
|
function isClaudeUltracodeEffort(effort) {
|
|
20418
20234
|
return effort === "ultracode";
|
|
20419
20235
|
}
|
|
20420
|
-
function resolveClaudeContextWindow(caps, modelSelection) {
|
|
20421
|
-
const raw = getModelSelectionStringOptionValue(modelSelection, "contextWindow");
|
|
20422
|
-
const descriptor = caps.optionDescriptors.find((entry) => entry.id === "contextWindow");
|
|
20423
|
-
if (!descriptor || descriptor.type !== "select") return void 0;
|
|
20424
|
-
return currentSelectValue(descriptor, raw);
|
|
20425
|
-
}
|
|
20426
20236
|
function claudeCliModelId(input) {
|
|
20427
|
-
const
|
|
20428
|
-
|
|
20237
|
+
const requested = input.requestedModelId.trim();
|
|
20238
|
+
if (requested.length > 0 && (input.catalog ?? []).length === 0) return requested;
|
|
20239
|
+
const known = [
|
|
20240
|
+
...(input.catalog ?? []).map((model) => model.slug),
|
|
20241
|
+
...input.declared ?? [],
|
|
20429
20242
|
...(input.customModels ?? []).map((model) => normalizeCustomModelSlug(model.slug))
|
|
20430
20243
|
];
|
|
20431
|
-
return matchCatalogModel(input.
|
|
20432
|
-
}
|
|
20433
|
-
function resolveClaudeApiModelId(caps, modelSelection) {
|
|
20434
|
-
switch (resolveClaudeContextWindow(caps, modelSelection)) {
|
|
20435
|
-
case "1m":
|
|
20436
|
-
return `${modelSelection.model}[1m]`;
|
|
20437
|
-
default:
|
|
20438
|
-
return modelSelection.model;
|
|
20439
|
-
}
|
|
20244
|
+
return matchCatalogModel(input.requestedModelId, known) ?? input.placeholder;
|
|
20440
20245
|
}
|
|
20441
20246
|
function resolvePromptInjectedEffort(caps, rawEffort) {
|
|
20442
20247
|
const trimmed = rawEffort?.trim();
|
|
@@ -20460,26 +20265,106 @@ function applyClaudePromptEffortPrefix(text, effort) {
|
|
|
20460
20265
|
return `Ultrathink:
|
|
20461
20266
|
${trimmed}`;
|
|
20462
20267
|
}
|
|
20463
|
-
function
|
|
20464
|
-
|
|
20465
|
-
case "claude-opus-4-8":
|
|
20466
|
-
case "claude-opus-4-7":
|
|
20467
|
-
return 1e6;
|
|
20468
|
-
}
|
|
20469
|
-
switch (resolveClaudeContextWindow(caps, modelSelection)) {
|
|
20470
|
-
case "1m":
|
|
20471
|
-
return 1e6;
|
|
20472
|
-
case "200k":
|
|
20473
|
-
return 2e5;
|
|
20474
|
-
default:
|
|
20475
|
-
return void 0;
|
|
20476
|
-
}
|
|
20477
|
-
}
|
|
20478
|
-
function getEffectiveClaudeAgentEffort(effort, model, caps) {
|
|
20479
|
-
const normalized = normalizeClaudeCliEffort(effort, model, caps);
|
|
20268
|
+
function getEffectiveClaudeAgentEffort(effort) {
|
|
20269
|
+
const normalized = normalizeClaudeCliEffort(effort);
|
|
20480
20270
|
return normalized ? normalized : null;
|
|
20481
20271
|
}
|
|
20482
20272
|
|
|
20273
|
+
// src/sdkModels.ts
|
|
20274
|
+
import * as NodeOS5 from "node:os";
|
|
20275
|
+
var CLAUDE_SDK_MODELS_TIMEOUT_MS = 2e4;
|
|
20276
|
+
var CLAUDE_SDK_MODELS_TTL_MS = 30 * 6e4;
|
|
20277
|
+
var CLAUDE_SDK_MODELS_RETRY_MS = 2 * 6e4;
|
|
20278
|
+
var EFFORT_LABELS = {
|
|
20279
|
+
low: "Low",
|
|
20280
|
+
medium: "Medium",
|
|
20281
|
+
high: "High",
|
|
20282
|
+
xhigh: "Extra High",
|
|
20283
|
+
max: "Max"
|
|
20284
|
+
};
|
|
20285
|
+
var effortLabel = (level) => EFFORT_LABELS[level] ?? `${level.slice(0, 1).toUpperCase()}${level.slice(1)}`;
|
|
20286
|
+
var claudeCatalogModelFromSdk = (info) => {
|
|
20287
|
+
const descriptors = [];
|
|
20288
|
+
const levels = info.supportsEffort === false ? [] : info.supportedEffortLevels ?? [];
|
|
20289
|
+
if (levels.length > 0) {
|
|
20290
|
+
descriptors.push({
|
|
20291
|
+
type: "select",
|
|
20292
|
+
id: "effort",
|
|
20293
|
+
label: "Reasoning",
|
|
20294
|
+
options: levels.map((level) => ({ id: level, label: effortLabel(level) }))
|
|
20295
|
+
});
|
|
20296
|
+
}
|
|
20297
|
+
if (info.supportsFastMode === true) {
|
|
20298
|
+
descriptors.push({ type: "boolean", id: "fastMode", label: "Fast Mode" });
|
|
20299
|
+
}
|
|
20300
|
+
return {
|
|
20301
|
+
slug: info.value,
|
|
20302
|
+
name: info.displayName.trim().length > 0 ? info.displayName : info.value,
|
|
20303
|
+
isCustom: false,
|
|
20304
|
+
capabilities: { optionDescriptors: descriptors }
|
|
20305
|
+
};
|
|
20306
|
+
};
|
|
20307
|
+
var claudeCatalogFromSdk = (models) => {
|
|
20308
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20309
|
+
const out = [];
|
|
20310
|
+
for (const info of models) {
|
|
20311
|
+
if (typeof info.value !== "string" || info.value.trim().length === 0) continue;
|
|
20312
|
+
if (seen.has(info.value)) continue;
|
|
20313
|
+
seen.add(info.value);
|
|
20314
|
+
out.push(claudeCatalogModelFromSdk(info));
|
|
20315
|
+
}
|
|
20316
|
+
return out;
|
|
20317
|
+
};
|
|
20318
|
+
var silentPrompt = (signal) => ({
|
|
20319
|
+
[Symbol.asyncIterator]: () => ({
|
|
20320
|
+
next: () => new Promise((resolve2) => {
|
|
20321
|
+
if (signal.aborted) resolve2({ done: true, value: void 0 });
|
|
20322
|
+
signal.addEventListener("abort", () => resolve2({ done: true, value: void 0 }), {
|
|
20323
|
+
once: true
|
|
20324
|
+
});
|
|
20325
|
+
}),
|
|
20326
|
+
return: async () => ({ done: true, value: void 0 })
|
|
20327
|
+
})
|
|
20328
|
+
});
|
|
20329
|
+
var readClaudeSdkModels = async (input) => {
|
|
20330
|
+
const abort = new AbortController();
|
|
20331
|
+
const forwardAbort = () => abort.abort();
|
|
20332
|
+
input.signal?.addEventListener("abort", forwardAbort, { once: true });
|
|
20333
|
+
if (input.signal?.aborted) abort.abort();
|
|
20334
|
+
let runtime;
|
|
20335
|
+
let timer;
|
|
20336
|
+
try {
|
|
20337
|
+
runtime = input.createQuery({
|
|
20338
|
+
prompt: silentPrompt(abort.signal),
|
|
20339
|
+
options: { ...input.options, abortController: abort }
|
|
20340
|
+
});
|
|
20341
|
+
if (runtime.supportedModels === void 0) return void 0;
|
|
20342
|
+
const timeout = new Promise((_3, reject) => {
|
|
20343
|
+
timer = setTimeout(
|
|
20344
|
+
() => reject(new Error("supportedModels timed out")),
|
|
20345
|
+
input.timeoutMs ?? CLAUDE_SDK_MODELS_TIMEOUT_MS
|
|
20346
|
+
);
|
|
20347
|
+
});
|
|
20348
|
+
const cancelled = new Promise((_3, reject) => {
|
|
20349
|
+
abort.signal.addEventListener("abort", () => reject(new Error("aborted")), { once: true });
|
|
20350
|
+
});
|
|
20351
|
+
cancelled.catch(() => {
|
|
20352
|
+
});
|
|
20353
|
+
return await Promise.race([runtime.supportedModels(), timeout, cancelled]);
|
|
20354
|
+
} catch {
|
|
20355
|
+
return void 0;
|
|
20356
|
+
} finally {
|
|
20357
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
20358
|
+
input.signal?.removeEventListener("abort", forwardAbort);
|
|
20359
|
+
abort.abort();
|
|
20360
|
+
try {
|
|
20361
|
+
runtime?.close();
|
|
20362
|
+
} catch {
|
|
20363
|
+
}
|
|
20364
|
+
}
|
|
20365
|
+
};
|
|
20366
|
+
var claudeSdkModelsCwd = () => NodeOS5.tmpdir();
|
|
20367
|
+
|
|
20483
20368
|
// src/util.ts
|
|
20484
20369
|
function encodeJsonStringForDiagnostics(input) {
|
|
20485
20370
|
try {
|
|
@@ -20656,10 +20541,10 @@ function inputDiffStat(input) {
|
|
|
20656
20541
|
let deletions = 0;
|
|
20657
20542
|
for (const edit of input.edits) {
|
|
20658
20543
|
if (edit === null || typeof edit !== "object" || Array.isArray(edit)) return void 0;
|
|
20659
|
-
const
|
|
20660
|
-
if (!
|
|
20661
|
-
additions +=
|
|
20662
|
-
deletions +=
|
|
20544
|
+
const stat = replacementDiffStat(edit, budget);
|
|
20545
|
+
if (!stat) return void 0;
|
|
20546
|
+
additions += stat.additions;
|
|
20547
|
+
deletions += stat.deletions;
|
|
20663
20548
|
}
|
|
20664
20549
|
return { additions, deletions };
|
|
20665
20550
|
}
|
|
@@ -21236,8 +21121,8 @@ var CLAUDE_SETTING_SOURCES = [
|
|
|
21236
21121
|
|
|
21237
21122
|
// src/sessions.ts
|
|
21238
21123
|
import * as NodeFS3 from "node:fs";
|
|
21239
|
-
import * as
|
|
21240
|
-
import * as
|
|
21124
|
+
import * as NodeOS6 from "node:os";
|
|
21125
|
+
import * as NodePath6 from "node:path";
|
|
21241
21126
|
import * as NodeProcess from "node:process";
|
|
21242
21127
|
|
|
21243
21128
|
// src/sessionScope.ts
|
|
@@ -21357,7 +21242,7 @@ function listTranscriptFiles(transcriptDir, directory) {
|
|
|
21357
21242
|
const scanned = matched.length > 0 ? matched : dirs;
|
|
21358
21243
|
const found = [];
|
|
21359
21244
|
for (const dir of scanned) {
|
|
21360
|
-
const projectDir =
|
|
21245
|
+
const projectDir = NodePath6.join(transcriptDir, dir);
|
|
21361
21246
|
let names;
|
|
21362
21247
|
try {
|
|
21363
21248
|
names = NodeFS3.readdirSync(projectDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(TRANSCRIPT_SUFFIX)).map((entry) => entry.name);
|
|
@@ -21365,17 +21250,17 @@ function listTranscriptFiles(transcriptDir, directory) {
|
|
|
21365
21250
|
continue;
|
|
21366
21251
|
}
|
|
21367
21252
|
for (const name of names) {
|
|
21368
|
-
let
|
|
21253
|
+
let stat;
|
|
21369
21254
|
try {
|
|
21370
|
-
|
|
21255
|
+
stat = NodeFS3.statSync(NodePath6.join(projectDir, name));
|
|
21371
21256
|
} catch {
|
|
21372
21257
|
continue;
|
|
21373
21258
|
}
|
|
21374
21259
|
found.push({
|
|
21375
|
-
path:
|
|
21260
|
+
path: NodePath6.join(projectDir, name),
|
|
21376
21261
|
sessionId: name.slice(0, -TRANSCRIPT_SUFFIX.length),
|
|
21377
|
-
size:
|
|
21378
|
-
mtimeMs: Number.isFinite(
|
|
21262
|
+
size: stat.size,
|
|
21263
|
+
mtimeMs: Number.isFinite(stat.mtimeMs) ? stat.mtimeMs : 0
|
|
21379
21264
|
});
|
|
21380
21265
|
}
|
|
21381
21266
|
}
|
|
@@ -21383,7 +21268,7 @@ function listTranscriptFiles(transcriptDir, directory) {
|
|
|
21383
21268
|
}
|
|
21384
21269
|
function readClaudeLiveSessionIds(configDir) {
|
|
21385
21270
|
const live = /* @__PURE__ */ new Set();
|
|
21386
|
-
const markerDir =
|
|
21271
|
+
const markerDir = NodePath6.join(configDir, "sessions");
|
|
21387
21272
|
let entries;
|
|
21388
21273
|
try {
|
|
21389
21274
|
entries = NodeFS3.readdirSync(markerDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name);
|
|
@@ -21393,7 +21278,7 @@ function readClaudeLiveSessionIds(configDir) {
|
|
|
21393
21278
|
for (const entry of entries) {
|
|
21394
21279
|
let marker;
|
|
21395
21280
|
try {
|
|
21396
|
-
marker = JSON.parse(NodeFS3.readFileSync(
|
|
21281
|
+
marker = JSON.parse(NodeFS3.readFileSync(NodePath6.join(markerDir, entry), "utf8"));
|
|
21397
21282
|
} catch {
|
|
21398
21283
|
continue;
|
|
21399
21284
|
}
|
|
@@ -21423,7 +21308,7 @@ function scanClaudeSessions(input) {
|
|
|
21423
21308
|
}
|
|
21424
21309
|
const files = [...listTranscriptFiles(input.transcriptDir, input.directory)].sort((left, right) => right.mtimeMs - left.mtimeMs).slice(0, MAX_SCANNED_FILES);
|
|
21425
21310
|
const live = readClaudeLiveSessionIds(input.configDir);
|
|
21426
|
-
const caseInsensitive = input.caseInsensitive ??
|
|
21311
|
+
const caseInsensitive = input.caseInsensitive ?? NodeOS6.type() === "Windows_NT";
|
|
21427
21312
|
const rows = [];
|
|
21428
21313
|
for (const file of files) {
|
|
21429
21314
|
if (rows.length >= MAX_ROWS) break;
|
|
@@ -21447,7 +21332,7 @@ function scanClaudeSessions(input) {
|
|
|
21447
21332
|
function resolveTranscriptPath(input) {
|
|
21448
21333
|
const fileName = `${input.sessionId}${TRANSCRIPT_SUFFIX}`;
|
|
21449
21334
|
if (input.cwd !== void 0 && input.cwd.length > 0) {
|
|
21450
|
-
const direct =
|
|
21335
|
+
const direct = NodePath6.join(
|
|
21451
21336
|
input.transcriptDir,
|
|
21452
21337
|
encodeClaudeProjectDirName(input.cwd),
|
|
21453
21338
|
fileName
|
|
@@ -21464,7 +21349,7 @@ function resolveTranscriptPath(input) {
|
|
|
21464
21349
|
return null;
|
|
21465
21350
|
}
|
|
21466
21351
|
for (const dir of dirs) {
|
|
21467
|
-
const candidate =
|
|
21352
|
+
const candidate = NodePath6.join(input.transcriptDir, dir, fileName);
|
|
21468
21353
|
try {
|
|
21469
21354
|
if (NodeFS3.statSync(candidate).isFile()) return candidate;
|
|
21470
21355
|
} catch {
|
|
@@ -21541,18 +21426,8 @@ function readClaudeSessionRecord(input) {
|
|
|
21541
21426
|
|
|
21542
21427
|
// src/spawnEnvironment.ts
|
|
21543
21428
|
function changedSpawnEnvironmentKeys(previous, next) {
|
|
21544
|
-
const
|
|
21545
|
-
return [
|
|
21546
|
-
...changedKeys(previous.processEnv, next.processEnv),
|
|
21547
|
-
...settingsPresenceChanged ? ["settings.env"] : [],
|
|
21548
|
-
...changedKeys(previous.settingsEnv ?? {}, next.settingsEnv ?? {}).map(
|
|
21549
|
-
(key) => `settings.env.${key}`
|
|
21550
|
-
)
|
|
21551
|
-
];
|
|
21552
|
-
}
|
|
21553
|
-
function changedKeys(previous, next) {
|
|
21554
|
-
const keys = /* @__PURE__ */ new Set([...Object.keys(previous), ...Object.keys(next)]);
|
|
21555
|
-
return [...keys].filter((key) => previous[key] !== next[key]).sort();
|
|
21429
|
+
const keys = /* @__PURE__ */ new Set([...Object.keys(previous.processEnv), ...Object.keys(next.processEnv)]);
|
|
21430
|
+
return [...keys].filter((key) => previous.processEnv[key] !== next.processEnv[key]).sort();
|
|
21556
21431
|
}
|
|
21557
21432
|
|
|
21558
21433
|
// src/usage.ts
|
|
@@ -21962,18 +21837,6 @@ function normalizeClaudeTaskProgressTokenUsage(value, memory) {
|
|
|
21962
21837
|
}
|
|
21963
21838
|
|
|
21964
21839
|
// src/probeModels.ts
|
|
21965
|
-
var CONTEXT_WINDOW_TOKENS = {
|
|
21966
|
-
"200k": 2e5,
|
|
21967
|
-
"1m": 1e6
|
|
21968
|
-
};
|
|
21969
|
-
var defaultContextWindowOf = (caps) => {
|
|
21970
|
-
const descriptor = caps.optionDescriptors.find(
|
|
21971
|
-
(entry) => entry.type === "select" && entry.id === "contextWindow"
|
|
21972
|
-
);
|
|
21973
|
-
if (descriptor === void 0) return void 0;
|
|
21974
|
-
const chosen = descriptor.options.find((option) => option.isDefault === true);
|
|
21975
|
-
return chosen === void 0 ? void 0 : CONTEXT_WINDOW_TOKENS[chosen.id];
|
|
21976
|
-
};
|
|
21977
21840
|
var toProbeCapabilities = (caps) => ({
|
|
21978
21841
|
optionDescriptors: caps.optionDescriptors.map(
|
|
21979
21842
|
(descriptor) => descriptor.type === "select" ? {
|
|
@@ -21996,17 +21859,14 @@ var toProbeCapabilities = (caps) => ({
|
|
|
21996
21859
|
var claudeProbeModels = (input) => {
|
|
21997
21860
|
const seen = /* @__PURE__ */ new Set();
|
|
21998
21861
|
const out = [];
|
|
21999
|
-
for (const model of input.
|
|
21862
|
+
for (const model of input.catalog) {
|
|
22000
21863
|
if (seen.has(model.slug)) continue;
|
|
22001
21864
|
seen.add(model.slug);
|
|
22002
21865
|
const userLabel = input.customModels.find((entry) => entry.slug === model.slug)?.label;
|
|
22003
|
-
const contextWindow = defaultContextWindowOf(model.capabilities);
|
|
22004
21866
|
out.push({
|
|
22005
21867
|
slug: model.slug,
|
|
22006
21868
|
name: userLabel?.trim() || model.name,
|
|
22007
|
-
|
|
22008
|
-
capabilities: toProbeCapabilities(model.capabilities),
|
|
22009
|
-
...contextWindow === void 0 ? {} : { contextWindow }
|
|
21869
|
+
capabilities: toProbeCapabilities(model.capabilities)
|
|
22010
21870
|
});
|
|
22011
21871
|
}
|
|
22012
21872
|
for (const model of input.customModels) {
|
|
@@ -22014,251 +21874,14 @@ var claudeProbeModels = (input) => {
|
|
|
22014
21874
|
seen.add(model.slug);
|
|
22015
21875
|
out.push({ slug: model.slug, name: model.label?.trim() || model.slug });
|
|
22016
21876
|
}
|
|
22017
|
-
for (const model of input.discovered ?? []) {
|
|
22018
|
-
if (seen.has(model.slug)) continue;
|
|
22019
|
-
seen.add(model.slug);
|
|
22020
|
-
out.push(model);
|
|
22021
|
-
}
|
|
22022
21877
|
return out;
|
|
22023
21878
|
};
|
|
22024
21879
|
|
|
22025
|
-
// src/routedHome.ts
|
|
22026
|
-
import * as NodeFSP from "node:fs/promises";
|
|
22027
|
-
import * as NodePath6 from "node:path";
|
|
22028
|
-
|
|
22029
|
-
// src/routedSettings.ts
|
|
22030
|
-
import { brainSlotEnvKeys } from "@ycodium-ai/plugin-api";
|
|
22031
|
-
var PROXY_ENV_KEYS = [
|
|
22032
|
-
"HTTP_PROXY",
|
|
22033
|
-
"HTTPS_PROXY",
|
|
22034
|
-
"NO_PROXY",
|
|
22035
|
-
"ALL_PROXY",
|
|
22036
|
-
"http_proxy",
|
|
22037
|
-
"https_proxy",
|
|
22038
|
-
"no_proxy",
|
|
22039
|
-
"all_proxy"
|
|
22040
|
-
];
|
|
22041
|
-
function isRoutedLaunch(launchProcessEnv) {
|
|
22042
|
-
const baseUrlKey = CLAUDE_CARD.modelConnectivity.baseUrlEnvKey;
|
|
22043
|
-
if (baseUrlKey === void 0) return false;
|
|
22044
|
-
return (launchProcessEnv?.[baseUrlKey] ?? "").trim().length > 0;
|
|
22045
|
-
}
|
|
22046
|
-
function routedEnvOverride(input) {
|
|
22047
|
-
if (!isRoutedLaunch(input.launchProcessEnv)) return void 0;
|
|
22048
|
-
const valueOf = (key) => input.mergedEnv[key] ?? "";
|
|
22049
|
-
const override = {};
|
|
22050
|
-
for (const key of brainSlotEnvKeys(CLAUDE_CARD)) override[key] = valueOf(key);
|
|
22051
|
-
for (const { name } of CLAUDE_CARD.modelConnectivity.extraEnv ?? []) {
|
|
22052
|
-
const bound = valueOf(name);
|
|
22053
|
-
override[name] = bound.length === 0 ? "" : claudeCliModelId({
|
|
22054
|
-
boundModelId: bound,
|
|
22055
|
-
placeholder: CLAUDE_CARD.defaultModel,
|
|
22056
|
-
...input.customModels === void 0 ? {} : { customModels: input.customModels }
|
|
22057
|
-
});
|
|
22058
|
-
}
|
|
22059
|
-
for (const key of PROXY_ENV_KEYS) override[key] = valueOf(key);
|
|
22060
|
-
return override;
|
|
22061
|
-
}
|
|
22062
|
-
|
|
22063
|
-
// src/routedHome.ts
|
|
22064
|
-
var BORROWED_ENTRY_NAMES = [
|
|
22065
|
-
"projects",
|
|
22066
|
-
"plugins",
|
|
22067
|
-
"skills",
|
|
22068
|
-
"agents",
|
|
22069
|
-
"commands",
|
|
22070
|
-
"CLAUDE.md"
|
|
22071
|
-
];
|
|
22072
|
-
var GLOBAL_CONFIG_FILE_NAME = ".claude.json";
|
|
22073
|
-
var USER_SETTINGS_FILE_NAME = "settings.json";
|
|
22074
|
-
var ROUTING_AND_IDENTITY_SETTING_KEYS = [
|
|
22075
|
-
"env",
|
|
22076
|
-
"apiKeyHelper",
|
|
22077
|
-
"awsAuthRefresh",
|
|
22078
|
-
"awsCredentialExport"
|
|
22079
|
-
];
|
|
22080
|
-
var FIRST_RUN_FLAG_KEYS = ["hasCompletedOnboarding", "bypassPermissionsModeAccepted"];
|
|
22081
|
-
function isRecord5(value) {
|
|
22082
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22083
|
-
}
|
|
22084
|
-
async function readTextFile(filePath) {
|
|
22085
|
-
try {
|
|
22086
|
-
return await NodeFSP.readFile(filePath, "utf8");
|
|
22087
|
-
} catch {
|
|
22088
|
-
return null;
|
|
22089
|
-
}
|
|
22090
|
-
}
|
|
22091
|
-
function parseJsonObject(raw) {
|
|
22092
|
-
try {
|
|
22093
|
-
const parsed = JSON.parse(raw);
|
|
22094
|
-
return isRecord5(parsed) ? parsed : null;
|
|
22095
|
-
} catch {
|
|
22096
|
-
return null;
|
|
22097
|
-
}
|
|
22098
|
-
}
|
|
22099
|
-
async function writeFileAtomic(filePath, contents) {
|
|
22100
|
-
const tempPath = `${filePath}.${crypto.randomUUID()}.tmp`;
|
|
22101
|
-
await NodeFSP.writeFile(tempPath, contents, { encoding: "utf8", mode: 384 });
|
|
22102
|
-
await NodeFSP.rename(tempPath, filePath);
|
|
22103
|
-
}
|
|
22104
|
-
async function readLinkState(linkPath) {
|
|
22105
|
-
try {
|
|
22106
|
-
return { _tag: "Symlink", target: await NodeFSP.readlink(linkPath) };
|
|
22107
|
-
} catch (error) {
|
|
22108
|
-
const code = typeof error === "object" && error !== null && "code" in error ? String(error.code) : "";
|
|
22109
|
-
if (code === "ENOENT") return { _tag: "Missing" };
|
|
22110
|
-
return { _tag: "NotSymlink" };
|
|
22111
|
-
}
|
|
22112
|
-
}
|
|
22113
|
-
async function isEmptyDirectory(path) {
|
|
22114
|
-
try {
|
|
22115
|
-
return (await NodeFSP.readdir(path)).length === 0;
|
|
22116
|
-
} catch {
|
|
22117
|
-
return false;
|
|
22118
|
-
}
|
|
22119
|
-
}
|
|
22120
|
-
async function borrowEntry(input) {
|
|
22121
|
-
const target = NodePath6.join(input.userConfigDirPath, input.entryName);
|
|
22122
|
-
const targetInfo = await NodeFSP.stat(target).then(
|
|
22123
|
-
(info) => info,
|
|
22124
|
-
() => null
|
|
22125
|
-
);
|
|
22126
|
-
if (targetInfo === null) return;
|
|
22127
|
-
const link = NodePath6.join(input.configDirPath, input.entryName);
|
|
22128
|
-
const state = await readLinkState(link);
|
|
22129
|
-
if (state._tag === "NotSymlink") {
|
|
22130
|
-
if (!await isEmptyDirectory(link)) {
|
|
22131
|
-
input.log?.warn("Claude routed home entry left unlinked: a real entry is already there.", {
|
|
22132
|
-
entryName: input.entryName,
|
|
22133
|
-
link
|
|
22134
|
-
});
|
|
22135
|
-
return;
|
|
22136
|
-
}
|
|
22137
|
-
await NodeFSP.rm(link, { recursive: true, force: true });
|
|
22138
|
-
await NodeFSP.symlink(target, link, targetInfo.isDirectory() ? "junction" : "file");
|
|
22139
|
-
return;
|
|
22140
|
-
}
|
|
22141
|
-
if (state._tag === "Symlink") {
|
|
22142
|
-
if (NodePath6.resolve(NodePath6.dirname(link), state.target) === target) return;
|
|
22143
|
-
await NodeFSP.rm(link, { force: true });
|
|
22144
|
-
}
|
|
22145
|
-
await NodeFSP.symlink(target, link, targetInfo.isDirectory() ? "junction" : "file");
|
|
22146
|
-
}
|
|
22147
|
-
async function mirrorUserSettings(input) {
|
|
22148
|
-
const sourcePath = NodePath6.join(input.userConfigDirPath, USER_SETTINGS_FILE_NAME);
|
|
22149
|
-
const raw = await readTextFile(sourcePath);
|
|
22150
|
-
if (raw === null) return;
|
|
22151
|
-
const parsed = parseJsonObject(raw);
|
|
22152
|
-
if (parsed === null) {
|
|
22153
|
-
input.log?.warn(
|
|
22154
|
-
"Claude routed home settings mirror skipped: the source is not a JSON object.",
|
|
22155
|
-
{
|
|
22156
|
-
sourcePath
|
|
22157
|
-
}
|
|
22158
|
-
);
|
|
22159
|
-
return;
|
|
22160
|
-
}
|
|
22161
|
-
const mirrored = { ...parsed };
|
|
22162
|
-
for (const key of ROUTING_AND_IDENTITY_SETTING_KEYS) delete mirrored[key];
|
|
22163
|
-
const targetPath = NodePath6.join(input.configDirPath, USER_SETTINGS_FILE_NAME);
|
|
22164
|
-
const desired = `${JSON.stringify(mirrored, null, 2)}
|
|
22165
|
-
`;
|
|
22166
|
-
if (await readTextFile(targetPath) === desired) return;
|
|
22167
|
-
await writeFileAtomic(targetPath, desired);
|
|
22168
|
-
}
|
|
22169
|
-
async function seedFirstRun(input) {
|
|
22170
|
-
const filePath = NodePath6.join(input.configDirPath, GLOBAL_CONFIG_FILE_NAME);
|
|
22171
|
-
const raw = await readTextFile(filePath);
|
|
22172
|
-
const parsed = raw === null ? {} : parseJsonObject(raw);
|
|
22173
|
-
if (parsed === null) {
|
|
22174
|
-
input.log?.warn("Claude routed home first-run seed skipped: the config file is not readable.", {
|
|
22175
|
-
filePath
|
|
22176
|
-
});
|
|
22177
|
-
return;
|
|
22178
|
-
}
|
|
22179
|
-
const next = { ...parsed };
|
|
22180
|
-
let changed = false;
|
|
22181
|
-
if (raw === null) {
|
|
22182
|
-
for (const key of FIRST_RUN_FLAG_KEYS) next[key] = true;
|
|
22183
|
-
changed = true;
|
|
22184
|
-
}
|
|
22185
|
-
const existingProjects = next["projects"];
|
|
22186
|
-
const projects = isRecord5(existingProjects) ? { ...existingProjects } : {};
|
|
22187
|
-
for (const trustedPath of input.trustedPaths) {
|
|
22188
|
-
const resolved = NodePath6.resolve(trustedPath);
|
|
22189
|
-
const entry = projects[resolved];
|
|
22190
|
-
const project = isRecord5(entry) ? { ...entry } : {};
|
|
22191
|
-
if (project["hasTrustDialogAccepted"] === true) continue;
|
|
22192
|
-
project["hasTrustDialogAccepted"] = true;
|
|
22193
|
-
projects[resolved] = project;
|
|
22194
|
-
changed = true;
|
|
22195
|
-
}
|
|
22196
|
-
if (Object.keys(projects).length > 0) next["projects"] = projects;
|
|
22197
|
-
if (!changed) return;
|
|
22198
|
-
await writeFileAtomic(filePath, `${JSON.stringify(next, null, 2)}
|
|
22199
|
-
`);
|
|
22200
|
-
}
|
|
22201
|
-
function resolveClaudeLaunchHome(input) {
|
|
22202
|
-
const routed = isRoutedLaunch(input.launchProcessEnv);
|
|
22203
|
-
const dataDirPath = input.pluginDataDirPath?.trim() ?? "";
|
|
22204
|
-
if (routed && dataDirPath.length === 0) {
|
|
22205
|
-
input.log?.warn(
|
|
22206
|
-
"Ycodium is routing this turn but has no directory of its own to hand the CLI; it will read the user's."
|
|
22207
|
-
);
|
|
22208
|
-
}
|
|
22209
|
-
return resolveClaudeHomeLayout({
|
|
22210
|
-
homePath: input.homePath,
|
|
22211
|
-
credentialsPath: input.credentialsPath,
|
|
22212
|
-
...routed && dataDirPath.length > 0 ? { routedHomePath: claudeRoutedHomePath(dataDirPath) } : {},
|
|
22213
|
-
...input.environment === void 0 ? {} : { environment: input.environment }
|
|
22214
|
-
});
|
|
22215
|
-
}
|
|
22216
|
-
async function materializeClaudeRoutedHome(layout, options) {
|
|
22217
|
-
if (layout.mode !== "routed") return;
|
|
22218
|
-
const configDirPath = layout.configDirPath;
|
|
22219
|
-
if (configDirPath === void 0) return;
|
|
22220
|
-
if (configDirPath === layout.userConfigDirPath) {
|
|
22221
|
-
throw new Error(
|
|
22222
|
-
`Ycodium's Claude configuration directory '${configDirPath}' must differ from the user's.`
|
|
22223
|
-
);
|
|
22224
|
-
}
|
|
22225
|
-
await NodeFSP.mkdir(configDirPath, { recursive: true });
|
|
22226
|
-
await NodeFSP.chmod(configDirPath, 448);
|
|
22227
|
-
const credentialsDirPath = layout.credentialsDirPath;
|
|
22228
|
-
if (credentialsDirPath !== void 0 && credentialsDirPath !== configDirPath) {
|
|
22229
|
-
await NodeFSP.mkdir(credentialsDirPath, { recursive: true });
|
|
22230
|
-
await NodeFSP.chmod(credentialsDirPath, 448);
|
|
22231
|
-
}
|
|
22232
|
-
const log = options?.log;
|
|
22233
|
-
for (const entryName of BORROWED_ENTRY_NAMES) {
|
|
22234
|
-
try {
|
|
22235
|
-
await borrowEntry({
|
|
22236
|
-
userConfigDirPath: layout.userConfigDirPath,
|
|
22237
|
-
configDirPath,
|
|
22238
|
-
entryName,
|
|
22239
|
-
log
|
|
22240
|
-
});
|
|
22241
|
-
} catch (error) {
|
|
22242
|
-
log?.warn("Claude routed home entry left unlinked.", {
|
|
22243
|
-
entryName,
|
|
22244
|
-
reason: error instanceof Error ? error.message : String(error)
|
|
22245
|
-
});
|
|
22246
|
-
}
|
|
22247
|
-
}
|
|
22248
|
-
await mirrorUserSettings({
|
|
22249
|
-
userConfigDirPath: layout.userConfigDirPath,
|
|
22250
|
-
configDirPath,
|
|
22251
|
-
log
|
|
22252
|
-
});
|
|
22253
|
-
await seedFirstRun({
|
|
22254
|
-
configDirPath,
|
|
22255
|
-
trustedPaths: options?.trustedPaths ?? [],
|
|
22256
|
-
log
|
|
22257
|
-
});
|
|
22258
|
-
}
|
|
22259
|
-
|
|
22260
21880
|
// src/textGeneration.ts
|
|
22261
|
-
import
|
|
21881
|
+
import * as NodeFSP2 from "node:fs/promises";
|
|
21882
|
+
import * as NodeOS7 from "node:os";
|
|
21883
|
+
import * as NodePath7 from "node:path";
|
|
21884
|
+
import { mergeLaunchEnv } from "@ycodium-ai/plugin-api/executor";
|
|
22262
21885
|
|
|
22263
21886
|
// src/textGenerationUtils.ts
|
|
22264
21887
|
function limitSection(value, maxChars) {
|
|
@@ -22607,7 +22230,7 @@ function buildHandoverSummaryPrompt(input) {
|
|
|
22607
22230
|
|
|
22608
22231
|
// src/textGeneration.ts
|
|
22609
22232
|
var CLAUDE_TIMEOUT_MS = 18e4;
|
|
22610
|
-
function
|
|
22233
|
+
function isRecord5(value) {
|
|
22611
22234
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22612
22235
|
}
|
|
22613
22236
|
function readString3(value) {
|
|
@@ -22629,46 +22252,36 @@ function decodeStructuredOutput(stdout, operation) {
|
|
|
22629
22252
|
cause: error
|
|
22630
22253
|
});
|
|
22631
22254
|
}
|
|
22632
|
-
|
|
22255
|
+
const envelope = Array.isArray(parsed) ? parsed.findLast((message) => isRecord5(message) && message["type"] === "result") : parsed;
|
|
22256
|
+
if (!isRecord5(envelope) || !("structured_output" in envelope)) {
|
|
22633
22257
|
throw new Error(`${operation}: Claude CLI returned unexpected output format.`);
|
|
22634
22258
|
}
|
|
22635
|
-
return
|
|
22259
|
+
return envelope["structured_output"];
|
|
22636
22260
|
}
|
|
22637
|
-
function createClaudeTextGeneration(recipe, host,
|
|
22261
|
+
function createClaudeTextGeneration(recipe, host, modelCatalog) {
|
|
22638
22262
|
const runClaudeJson = async (input) => {
|
|
22639
|
-
const homeLayout = resolveClaudeLaunchHome({
|
|
22640
|
-
homePath: recipe.homePath,
|
|
22641
|
-
credentialsPath: recipe.credentialsPath,
|
|
22642
|
-
launchProcessEnv: input.launch?.processEnv,
|
|
22643
|
-
pluginDataDirPath,
|
|
22644
|
-
log: host.log
|
|
22645
|
-
});
|
|
22646
|
-
await materializeClaudeRoutedHome(homeLayout, {
|
|
22647
|
-
trustedPaths: [input.cwd],
|
|
22648
|
-
log: host.log
|
|
22649
|
-
});
|
|
22650
22263
|
const processEnv = mergeLaunchEnv({
|
|
22651
|
-
brainSlots: brainSlotEnvKeys2(CLAUDE_CARD),
|
|
22652
22264
|
instanceTable: recipe.environment,
|
|
22653
|
-
handOverrides: claudeHomeVariables(
|
|
22654
|
-
launch: input.launch?.processEnv
|
|
22265
|
+
handOverrides: claudeHomeVariables(resolveClaudeHomeLayout(recipe))
|
|
22655
22266
|
});
|
|
22656
|
-
const modelSelection =
|
|
22657
|
-
const requestedModel =
|
|
22658
|
-
const caps = claudeModelCapabilities(requestedModel, recipe.customModels);
|
|
22267
|
+
const modelSelection = isRecord5(input.modelSelection) ? input.modelSelection : {};
|
|
22268
|
+
const requestedModel = modelIdFromSelection(modelSelection) ?? "claude-haiku-4-5";
|
|
22269
|
+
const caps = claudeModelCapabilities(requestedModel, modelCatalog(), recipe.customModels);
|
|
22659
22270
|
const rawEffort = getModelSelectionStringOptionValue(modelSelection, "effort");
|
|
22660
22271
|
const resolvedEffort = resolveClaudeEffort(caps, rawEffort);
|
|
22661
|
-
const cliEffort = normalizeClaudeCliEffort(resolvedEffort
|
|
22272
|
+
const cliEffort = normalizeClaudeCliEffort(resolvedEffort);
|
|
22662
22273
|
const ultracode = isClaudeUltracodeEffort(resolvedEffort);
|
|
22663
22274
|
const thinking = getModelSelectionBooleanOptionValue(modelSelection, "thinking");
|
|
22664
22275
|
const fastMode = getModelSelectionBooleanOptionValue(modelSelection, "fastMode");
|
|
22665
22276
|
const settings = {
|
|
22277
|
+
// 元数据生成只需要传进去的 prompt:不跑用户配的 hook。
|
|
22278
|
+
disableAllHooks: true,
|
|
22666
22279
|
...typeof thinking === "boolean" ? { alwaysThinkingEnabled: thinking } : {},
|
|
22667
22280
|
...fastMode ? { fastMode: true } : {},
|
|
22668
22281
|
...ultracode ? { ultracode: true } : {}
|
|
22669
22282
|
};
|
|
22670
|
-
const settingsJson =
|
|
22671
|
-
const apiModelId =
|
|
22283
|
+
const settingsJson = JSON.stringify(settings);
|
|
22284
|
+
const apiModelId = typeof modelSelection["model"] === "string" ? modelSelection["model"] : requestedModel;
|
|
22672
22285
|
const args = [
|
|
22673
22286
|
"-p",
|
|
22674
22287
|
"--output-format",
|
|
@@ -22678,44 +22291,60 @@ function createClaudeTextGeneration(recipe, host, pluginDataDirPath) {
|
|
|
22678
22291
|
"--model",
|
|
22679
22292
|
apiModelId,
|
|
22680
22293
|
...cliEffort ? ["--effort", cliEffort] : [],
|
|
22681
|
-
|
|
22682
|
-
|
|
22294
|
+
"--settings",
|
|
22295
|
+
settingsJson,
|
|
22296
|
+
// 标题、提交信息这类只要文本:即使 prompt 里出现技能名,也不给任何可执行能力。
|
|
22297
|
+
"--tools",
|
|
22298
|
+
"",
|
|
22299
|
+
"--disable-slash-commands",
|
|
22300
|
+
"--strict-mcp-config"
|
|
22683
22301
|
];
|
|
22684
22302
|
const program = recipe.binaryPath.trim() || "claude";
|
|
22685
|
-
const
|
|
22686
|
-
|
|
22687
|
-
|
|
22688
|
-
|
|
22689
|
-
|
|
22690
|
-
|
|
22691
|
-
|
|
22692
|
-
|
|
22693
|
-
|
|
22694
|
-
|
|
22695
|
-
|
|
22303
|
+
const runIn = async (cwd) => {
|
|
22304
|
+
const spawned = await host.process.spawn({
|
|
22305
|
+
program,
|
|
22306
|
+
args,
|
|
22307
|
+
cwd,
|
|
22308
|
+
env: processEnv,
|
|
22309
|
+
owner: { bindingId: host.bindingId }
|
|
22310
|
+
});
|
|
22311
|
+
const timeout = AbortSignal.timeout(CLAUDE_TIMEOUT_MS);
|
|
22312
|
+
const signal = input.signal ? AbortSignal.any([input.signal, timeout]) : timeout;
|
|
22313
|
+
const abort = () => {
|
|
22314
|
+
void spawned.kill("SIGTERM");
|
|
22315
|
+
};
|
|
22316
|
+
if (signal.aborted) abort();
|
|
22317
|
+
else signal.addEventListener("abort", abort, { once: true });
|
|
22318
|
+
await spawned.writeStdin(input.prompt);
|
|
22319
|
+
await spawned.closeStdin();
|
|
22320
|
+
const [stdout, stderr, exitCode] = await Promise.all([
|
|
22321
|
+
collectText(spawned.stdout),
|
|
22322
|
+
collectText(spawned.stderr),
|
|
22323
|
+
spawned.exited
|
|
22324
|
+
]);
|
|
22325
|
+
if (signal.aborted && !input.signal?.aborted) {
|
|
22326
|
+
throw new Error(`${input.operation}: Claude CLI request timed out.`);
|
|
22327
|
+
}
|
|
22328
|
+
if (exitCode !== 0) {
|
|
22329
|
+
const detail = stderr.trim() || stdout.trim();
|
|
22330
|
+
throw new Error(
|
|
22331
|
+
detail.length > 0 ? `Claude CLI command failed: ${detail}` : `Claude CLI command failed with code ${exitCode}.`
|
|
22332
|
+
);
|
|
22333
|
+
}
|
|
22334
|
+
return decodeStructuredOutput(stdout, input.operation);
|
|
22696
22335
|
};
|
|
22697
|
-
if (
|
|
22698
|
-
|
|
22699
|
-
|
|
22700
|
-
|
|
22701
|
-
|
|
22702
|
-
|
|
22703
|
-
|
|
22704
|
-
|
|
22705
|
-
]);
|
|
22706
|
-
if (signal.aborted && !input.signal?.aborted) {
|
|
22707
|
-
throw new Error(`${input.operation}: Claude CLI request timed out.`);
|
|
22708
|
-
}
|
|
22709
|
-
if (exitCode !== 0) {
|
|
22710
|
-
const detail = stderr.trim() || stdout.trim();
|
|
22711
|
-
throw new Error(
|
|
22712
|
-
detail.length > 0 ? `Claude CLI command failed: ${detail}` : `Claude CLI command failed with code ${exitCode}.`
|
|
22713
|
-
);
|
|
22336
|
+
if (input.operation !== "generateThreadTitle") return runIn(input.cwd);
|
|
22337
|
+
const scratchDirectory = await NodeFSP2.mkdtemp(
|
|
22338
|
+
NodePath7.join(NodeOS7.tmpdir(), "ycodium-claude-title-")
|
|
22339
|
+
);
|
|
22340
|
+
try {
|
|
22341
|
+
return await runIn(scratchDirectory);
|
|
22342
|
+
} finally {
|
|
22343
|
+
await NodeFSP2.rm(scratchDirectory, { recursive: true, force: true }).catch(() => void 0);
|
|
22714
22344
|
}
|
|
22715
|
-
return decodeStructuredOutput(stdout, input.operation);
|
|
22716
22345
|
};
|
|
22717
22346
|
const asRecord = (value, operation) => {
|
|
22718
|
-
if (!
|
|
22347
|
+
if (!isRecord5(value))
|
|
22719
22348
|
throw new Error(`${operation}: Claude returned invalid structured output.`);
|
|
22720
22349
|
return value;
|
|
22721
22350
|
};
|
|
@@ -22729,7 +22358,7 @@ function createClaudeTextGeneration(recipe, host, pluginDataDirPath) {
|
|
|
22729
22358
|
stagedSummary: readString3(input["stagedSummary"]),
|
|
22730
22359
|
stagedPatch: readString3(input["stagedPatch"]),
|
|
22731
22360
|
includeBranch,
|
|
22732
|
-
...
|
|
22361
|
+
...isRecord5(input["policy"]) ? { policy: input["policy"] } : {}
|
|
22733
22362
|
});
|
|
22734
22363
|
const generated = asRecord(
|
|
22735
22364
|
await runClaudeJson({
|
|
@@ -22738,7 +22367,6 @@ function createClaudeTextGeneration(recipe, host, pluginDataDirPath) {
|
|
|
22738
22367
|
prompt,
|
|
22739
22368
|
outputSchema,
|
|
22740
22369
|
modelSelection: input["modelSelection"],
|
|
22741
|
-
...isRecord6(input["launch"]) ? { launch: input["launch"] } : {},
|
|
22742
22370
|
...signal === void 0 ? {} : { signal }
|
|
22743
22371
|
}),
|
|
22744
22372
|
"generateCommitMessage"
|
|
@@ -22762,7 +22390,7 @@ function createClaudeTextGeneration(recipe, host, pluginDataDirPath) {
|
|
|
22762
22390
|
diffSummary: readString3(input["diffSummary"]),
|
|
22763
22391
|
diffPatch: readString3(input["diffPatch"]),
|
|
22764
22392
|
...typeof input["changeRequestTemplate"] === "string" ? { changeRequestTemplate: input["changeRequestTemplate"] } : {},
|
|
22765
|
-
...
|
|
22393
|
+
...isRecord5(input["policy"]) ? { policy: input["policy"] } : {}
|
|
22766
22394
|
});
|
|
22767
22395
|
const generated = asRecord(
|
|
22768
22396
|
await runClaudeJson({
|
|
@@ -22771,7 +22399,6 @@ function createClaudeTextGeneration(recipe, host, pluginDataDirPath) {
|
|
|
22771
22399
|
prompt,
|
|
22772
22400
|
outputSchema,
|
|
22773
22401
|
modelSelection: input["modelSelection"],
|
|
22774
|
-
...isRecord6(input["launch"]) ? { launch: input["launch"] } : {},
|
|
22775
22402
|
...signal === void 0 ? {} : { signal }
|
|
22776
22403
|
}),
|
|
22777
22404
|
"generatePrContent"
|
|
@@ -22790,7 +22417,7 @@ function createClaudeTextGeneration(recipe, host, pluginDataDirPath) {
|
|
|
22790
22417
|
const { prompt, outputSchema } = buildBranchNamePrompt({
|
|
22791
22418
|
message: readString3(input["message"]),
|
|
22792
22419
|
...Array.isArray(input["attachments"]) ? { attachments: input["attachments"] } : {},
|
|
22793
|
-
...
|
|
22420
|
+
...isRecord5(input["policy"]) ? { policy: input["policy"] } : {}
|
|
22794
22421
|
});
|
|
22795
22422
|
const generated = asRecord(
|
|
22796
22423
|
await runClaudeJson({
|
|
@@ -22799,7 +22426,6 @@ function createClaudeTextGeneration(recipe, host, pluginDataDirPath) {
|
|
|
22799
22426
|
prompt,
|
|
22800
22427
|
outputSchema,
|
|
22801
22428
|
modelSelection: input["modelSelection"],
|
|
22802
|
-
...isRecord6(input["launch"]) ? { launch: input["launch"] } : {},
|
|
22803
22429
|
...signal === void 0 ? {} : { signal }
|
|
22804
22430
|
}),
|
|
22805
22431
|
"generateBranchName"
|
|
@@ -22816,7 +22442,7 @@ function createClaudeTextGeneration(recipe, host, pluginDataDirPath) {
|
|
|
22816
22442
|
message: readString3(input["message"]),
|
|
22817
22443
|
...typeof input["previousTitle"] === "string" ? { previousTitle: input["previousTitle"] } : {},
|
|
22818
22444
|
...Array.isArray(input["attachments"]) ? { attachments: input["attachments"] } : {},
|
|
22819
|
-
...
|
|
22445
|
+
...isRecord5(input["policy"]) ? { policy: input["policy"] } : {}
|
|
22820
22446
|
});
|
|
22821
22447
|
const generated = asRecord(
|
|
22822
22448
|
await runClaudeJson({
|
|
@@ -22825,7 +22451,6 @@ function createClaudeTextGeneration(recipe, host, pluginDataDirPath) {
|
|
|
22825
22451
|
prompt,
|
|
22826
22452
|
outputSchema,
|
|
22827
22453
|
modelSelection: input["modelSelection"],
|
|
22828
|
-
...isRecord6(input["launch"]) ? { launch: input["launch"] } : {},
|
|
22829
22454
|
...signal === void 0 ? {} : { signal }
|
|
22830
22455
|
}),
|
|
22831
22456
|
"generateThreadTitle"
|
|
@@ -22848,7 +22473,6 @@ function createClaudeTextGeneration(recipe, host, pluginDataDirPath) {
|
|
|
22848
22473
|
prompt,
|
|
22849
22474
|
outputSchema,
|
|
22850
22475
|
modelSelection: input["modelSelection"],
|
|
22851
|
-
...isRecord6(input["launch"]) ? { launch: input["launch"] } : {},
|
|
22852
22476
|
...signal === void 0 ? {} : { signal }
|
|
22853
22477
|
}),
|
|
22854
22478
|
"summarizeHandover"
|
|
@@ -22941,9 +22565,9 @@ var PromptQueue = class {
|
|
|
22941
22565
|
const queued = this.#queued.shift();
|
|
22942
22566
|
if (queued !== void 0) return Promise.resolve(queued);
|
|
22943
22567
|
if (this.#closed) return Promise.resolve(void 0);
|
|
22944
|
-
return new Promise((
|
|
22568
|
+
return new Promise((resolve2) => {
|
|
22945
22569
|
this.#waiters.push((result) => {
|
|
22946
|
-
|
|
22570
|
+
resolve2(result.done ? void 0 : result.value);
|
|
22947
22571
|
});
|
|
22948
22572
|
});
|
|
22949
22573
|
}
|
|
@@ -23098,6 +22722,48 @@ function createClaudeAdapter(recipe, host, options) {
|
|
|
23098
22722
|
prompt: input.prompt,
|
|
23099
22723
|
options: input.options
|
|
23100
22724
|
}));
|
|
22725
|
+
const buildLaunchEnvironment = () => mergeLaunchEnv2({
|
|
22726
|
+
inherited: { ...process.env, ...options?.environment },
|
|
22727
|
+
instanceTable: recipe.environment,
|
|
22728
|
+
handOverrides: claudeHomeVariables(resolveClaudeHomeLayout(recipe))
|
|
22729
|
+
});
|
|
22730
|
+
let modelCatalog;
|
|
22731
|
+
let modelCatalogRead;
|
|
22732
|
+
let modelCatalogFailedAt;
|
|
22733
|
+
const currentModelCatalog = () => modelCatalog?.models ?? [];
|
|
22734
|
+
const refreshModelCatalog = (input) => {
|
|
22735
|
+
const fresh = modelCatalog !== void 0 && Date.now() - modelCatalog.readAt < CLAUDE_SDK_MODELS_TTL_MS;
|
|
22736
|
+
if (fresh && input?.force !== true) return Promise.resolve();
|
|
22737
|
+
if (input?.force !== true && modelCatalogFailedAt !== void 0 && Date.now() - modelCatalogFailedAt < CLAUDE_SDK_MODELS_RETRY_MS) {
|
|
22738
|
+
return Promise.resolve();
|
|
22739
|
+
}
|
|
22740
|
+
if (modelCatalogRead !== void 0) return modelCatalogRead;
|
|
22741
|
+
const read = (async () => {
|
|
22742
|
+
const extraArgs = parseCliArgs(recipe.launchArgs).flags;
|
|
22743
|
+
const models = await readClaudeSdkModels({
|
|
22744
|
+
createQuery,
|
|
22745
|
+
signal: input?.signal,
|
|
22746
|
+
options: {
|
|
22747
|
+
cwd: claudeSdkModelsCwd(),
|
|
22748
|
+
pathToClaudeCodeExecutable: claudeSdkExecutablePath,
|
|
22749
|
+
settingSources: [...CLAUDE_SETTING_SOURCES],
|
|
22750
|
+
env: compactEnv(buildLaunchEnvironment()),
|
|
22751
|
+
...Object.keys(extraArgs).length > 0 ? { extraArgs } : {}
|
|
22752
|
+
}
|
|
22753
|
+
});
|
|
22754
|
+
if (models === void 0) {
|
|
22755
|
+
modelCatalogFailedAt = Date.now();
|
|
22756
|
+
} else {
|
|
22757
|
+
modelCatalogFailedAt = void 0;
|
|
22758
|
+
modelCatalog = { models: claudeCatalogFromSdk(models), readAt: Date.now() };
|
|
22759
|
+
}
|
|
22760
|
+
})().finally(() => {
|
|
22761
|
+
modelCatalogRead = void 0;
|
|
22762
|
+
});
|
|
22763
|
+
modelCatalogRead = read;
|
|
22764
|
+
return read;
|
|
22765
|
+
};
|
|
22766
|
+
const declaredModels = [CLAUDE_CARD.defaultModel, CLAUDE_CARD.defaultTextGenerationModel];
|
|
23101
22767
|
const sessions = /* @__PURE__ */ new Map();
|
|
23102
22768
|
const runtimeEventQueue = new EventBus();
|
|
23103
22769
|
const nowIso = () => (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -23381,8 +23047,8 @@ function createClaudeAdapter(recipe, host, options) {
|
|
|
23381
23047
|
try {
|
|
23382
23048
|
usage = await Promise.race([
|
|
23383
23049
|
context.query.getContextUsage(),
|
|
23384
|
-
new Promise((
|
|
23385
|
-
setTimeout(() =>
|
|
23050
|
+
new Promise((resolve2) => {
|
|
23051
|
+
setTimeout(() => resolve2(void 0), 1e3);
|
|
23386
23052
|
})
|
|
23387
23053
|
]);
|
|
23388
23054
|
} catch {
|
|
@@ -24762,7 +24428,7 @@ function createClaudeAdapter(recipe, host, options) {
|
|
|
24762
24428
|
if (streamFiber) {
|
|
24763
24429
|
await Promise.race([
|
|
24764
24430
|
streamFiber.catch(() => void 0),
|
|
24765
|
-
new Promise((
|
|
24431
|
+
new Promise((resolve2) => setTimeout(resolve2, 1e3))
|
|
24766
24432
|
]);
|
|
24767
24433
|
}
|
|
24768
24434
|
const updatedAt = nowIso();
|
|
@@ -24845,9 +24511,6 @@ function createClaudeAdapter(recipe, host, options) {
|
|
|
24845
24511
|
}
|
|
24846
24512
|
context.currentSettings = desired.settings;
|
|
24847
24513
|
}
|
|
24848
|
-
if (desired.contextWindow !== void 0) {
|
|
24849
|
-
context.lastKnownContextWindow = desired.contextWindow;
|
|
24850
|
-
}
|
|
24851
24514
|
const updatedAt = nowIso();
|
|
24852
24515
|
context.session = {
|
|
24853
24516
|
...context.session,
|
|
@@ -24877,16 +24540,20 @@ function createClaudeAdapter(recipe, host, options) {
|
|
|
24877
24540
|
const startSession = async (input) => {
|
|
24878
24541
|
const extraArgs = parseCliArgs(recipe.launchArgs).flags;
|
|
24879
24542
|
const modelSelection = boundModelSelection(input.modelSelection, boundInstanceId);
|
|
24880
|
-
|
|
24543
|
+
await modelCatalogRead;
|
|
24544
|
+
const caps = claudeModelCapabilities(
|
|
24545
|
+
modelSelection?.model,
|
|
24546
|
+
currentModelCatalog(),
|
|
24547
|
+
recipe.customModels
|
|
24548
|
+
);
|
|
24881
24549
|
const descriptors = caps.optionDescriptors;
|
|
24882
|
-
const apiModelId = modelSelection?.model ?
|
|
24883
|
-
|
|
24884
|
-
|
|
24885
|
-
|
|
24886
|
-
|
|
24887
|
-
|
|
24550
|
+
const apiModelId = modelSelection?.model ? claudeCliModelId({
|
|
24551
|
+
requestedModelId: modelSelection.model,
|
|
24552
|
+
placeholder: CLAUDE_CARD.defaultModel,
|
|
24553
|
+
catalog: currentModelCatalog(),
|
|
24554
|
+
declared: declaredModels,
|
|
24555
|
+
customModels: recipe.customModels
|
|
24888
24556
|
}) : void 0;
|
|
24889
|
-
const initialContextWindow = selectedClaudeContextWindow(caps, modelSelection);
|
|
24890
24557
|
const rawEffort = getModelSelectionStringOptionValue(modelSelection, "effort");
|
|
24891
24558
|
const effort = resolveClaudeEffort(caps, rawEffort) ?? null;
|
|
24892
24559
|
const fastModeSupported = descriptors.some(
|
|
@@ -24898,7 +24565,7 @@ function createClaudeAdapter(recipe, host, options) {
|
|
|
24898
24565
|
const fastMode = getModelSelectionBooleanOptionValue(modelSelection, "fastMode") === true && fastModeSupported;
|
|
24899
24566
|
const thinking = thinkingSupported ? getModelSelectionBooleanOptionValue(modelSelection, "thinking") : void 0;
|
|
24900
24567
|
const ultracode = isClaudeUltracodeEffort(effort);
|
|
24901
|
-
const effectiveEffort = getEffectiveClaudeAgentEffort(effort
|
|
24568
|
+
const effectiveEffort = getEffectiveClaudeAgentEffort(effort);
|
|
24902
24569
|
const permissionMode = claudePermissionModeFor(input.runtimeMode, input.nativeModeId);
|
|
24903
24570
|
const settings = buildClaudeSessionSettings({
|
|
24904
24571
|
thinking,
|
|
@@ -24906,28 +24573,8 @@ function createClaudeAdapter(recipe, host, options) {
|
|
|
24906
24573
|
ultracode,
|
|
24907
24574
|
autoCompactWindow: recipe.autoCompactWindow
|
|
24908
24575
|
});
|
|
24909
|
-
const homeLayout = resolveClaudeLaunchHome({
|
|
24910
|
-
homePath: recipe.homePath,
|
|
24911
|
-
credentialsPath: recipe.credentialsPath,
|
|
24912
|
-
launchProcessEnv: input.launch.processEnv,
|
|
24913
|
-
pluginDataDirPath: options?.pluginDataDirPath,
|
|
24914
|
-
environment: claudeHomeEnvironment,
|
|
24915
|
-
...options?.log === void 0 ? {} : { log: options.log }
|
|
24916
|
-
});
|
|
24917
|
-
const launchEnvironment = mergeLaunchEnv2({
|
|
24918
|
-
brainSlots: brainSlotEnvKeys3(CLAUDE_CARD),
|
|
24919
|
-
inherited: { ...process.env, ...options?.environment },
|
|
24920
|
-
instanceTable: recipe.environment,
|
|
24921
|
-
handOverrides: claudeHomeVariables(homeLayout),
|
|
24922
|
-
launch: input.launch.processEnv
|
|
24923
|
-
});
|
|
24924
24576
|
const spawnEnvironment = {
|
|
24925
|
-
processEnv: compactEnv(
|
|
24926
|
-
settingsEnv: routedEnvOverride({
|
|
24927
|
-
launchProcessEnv: input.launch.processEnv,
|
|
24928
|
-
mergedEnv: launchEnvironment,
|
|
24929
|
-
...recipe.customModels === void 0 ? {} : { customModels: recipe.customModels }
|
|
24930
|
-
})
|
|
24577
|
+
processEnv: compactEnv(buildLaunchEnvironment())
|
|
24931
24578
|
};
|
|
24932
24579
|
const existingContext = sessions.get(input.threadId);
|
|
24933
24580
|
if (existingContext) {
|
|
@@ -24935,7 +24582,6 @@ function createClaudeAdapter(recipe, host, options) {
|
|
|
24935
24582
|
permissionMode,
|
|
24936
24583
|
...apiModelId ? { apiModelId } : {},
|
|
24937
24584
|
...effectiveEffort ? { effectiveEffort } : {},
|
|
24938
|
-
...initialContextWindow !== void 0 ? { contextWindow: initialContextWindow } : {},
|
|
24939
24585
|
...modelSelection?.model ? { model: modelSelection.model } : {},
|
|
24940
24586
|
settings,
|
|
24941
24587
|
spawnEnvironment
|
|
@@ -24971,7 +24617,7 @@ function createClaudeAdapter(recipe, host, options) {
|
|
|
24971
24617
|
return await Promise.race([
|
|
24972
24618
|
contextDeferred.promise,
|
|
24973
24619
|
new Promise(
|
|
24974
|
-
(
|
|
24620
|
+
(resolve2) => setTimeout(() => resolve2(void 0), CLAUDE_SESSION_CONTEXT_WAIT_MS)
|
|
24975
24621
|
)
|
|
24976
24622
|
]);
|
|
24977
24623
|
} catch {
|
|
@@ -25255,11 +24901,7 @@ function createClaudeAdapter(recipe, host, options) {
|
|
|
25255
24901
|
const onUserDialog = (request, callbackOptions) => handleResumeDialog(request, callbackOptions);
|
|
25256
24902
|
const additionalDirectories = input.cwd ? [input.cwd] : [];
|
|
25257
24903
|
const mcpServers = toClaudeMcpServers(input.mcpServers);
|
|
25258
|
-
|
|
25259
|
-
...input.cwd ? { trustedPaths: [input.cwd] } : {},
|
|
25260
|
-
...options?.log === void 0 ? {} : { log: options.log }
|
|
25261
|
-
});
|
|
25262
|
-
const querySettings = spawnEnvironment.settingsEnv === void 0 ? { ...settings } : { ...settings, env: { ...spawnEnvironment.settingsEnv } };
|
|
24904
|
+
const querySettings = { ...settings };
|
|
25263
24905
|
const stderrTail = createOutputTail(CLAUDE_STDERR_TAIL_CHARS);
|
|
25264
24906
|
const queryOptions = {
|
|
25265
24907
|
...input.cwd ? { cwd: input.cwd } : {},
|
|
@@ -25340,6 +24982,8 @@ function createClaudeAdapter(recipe, host, options) {
|
|
|
25340
24982
|
basePermissionMode: permissionMode,
|
|
25341
24983
|
currentPermissionMode: permissionMode,
|
|
25342
24984
|
currentApiModelId: apiModelId,
|
|
24985
|
+
// 上下文长度只信 SDK 结果里报的那个数,起步时不猜。
|
|
24986
|
+
lastKnownContextWindow: void 0,
|
|
25343
24987
|
currentEffort: effectiveEffort ?? void 0,
|
|
25344
24988
|
launchEffort: effectiveEffort ?? void 0,
|
|
25345
24989
|
spawnEnvironment,
|
|
@@ -25360,7 +25004,6 @@ function createClaudeAdapter(recipe, host, options) {
|
|
|
25360
25004
|
compaction: void 0,
|
|
25361
25005
|
compactionInProgress: false,
|
|
25362
25006
|
pendingManualCompaction: false,
|
|
25363
|
-
lastKnownContextWindow: initialContextWindow,
|
|
25364
25007
|
lastKnownTokenUsage: void 0,
|
|
25365
25008
|
lastKnownTotalProcessedTokens: void 0,
|
|
25366
25009
|
lastAssistantUuid: resumeState?.resumeSessionAt,
|
|
@@ -25443,13 +25086,17 @@ function createClaudeAdapter(recipe, host, options) {
|
|
|
25443
25086
|
await completeTurn(context, "completed");
|
|
25444
25087
|
}
|
|
25445
25088
|
if (modelSelection?.model) {
|
|
25446
|
-
const turnCaps = claudeModelCapabilities(
|
|
25447
|
-
|
|
25448
|
-
|
|
25449
|
-
|
|
25450
|
-
|
|
25451
|
-
|
|
25452
|
-
|
|
25089
|
+
const turnCaps = claudeModelCapabilities(
|
|
25090
|
+
modelSelection.model,
|
|
25091
|
+
currentModelCatalog(),
|
|
25092
|
+
recipe.customModels
|
|
25093
|
+
);
|
|
25094
|
+
const apiModelId = claudeCliModelId({
|
|
25095
|
+
requestedModelId: modelSelection.model,
|
|
25096
|
+
placeholder: CLAUDE_CARD.defaultModel,
|
|
25097
|
+
catalog: currentModelCatalog(),
|
|
25098
|
+
declared: declaredModels,
|
|
25099
|
+
customModels: recipe.customModels
|
|
25453
25100
|
});
|
|
25454
25101
|
if (context.currentApiModelId !== apiModelId) {
|
|
25455
25102
|
try {
|
|
@@ -25467,7 +25114,7 @@ function createClaudeAdapter(recipe, host, options) {
|
|
|
25467
25114
|
turnCaps,
|
|
25468
25115
|
getModelSelectionStringOptionValue(modelSelection, "effort")
|
|
25469
25116
|
);
|
|
25470
|
-
context.currentEffort = getEffectiveClaudeAgentEffort(turnEffort ?? null
|
|
25117
|
+
context.currentEffort = getEffectiveClaudeAgentEffort(turnEffort ?? null) ?? void 0;
|
|
25471
25118
|
}
|
|
25472
25119
|
if (input.interactionMode === "plan") {
|
|
25473
25120
|
try {
|
|
@@ -25484,7 +25131,11 @@ function createClaudeAdapter(recipe, host, options) {
|
|
|
25484
25131
|
}
|
|
25485
25132
|
context.currentPermissionMode = context.basePermissionMode;
|
|
25486
25133
|
}
|
|
25487
|
-
const turnCapsForPrompt = claudeModelCapabilities(
|
|
25134
|
+
const turnCapsForPrompt = claudeModelCapabilities(
|
|
25135
|
+
modelSelection?.model,
|
|
25136
|
+
currentModelCatalog(),
|
|
25137
|
+
recipe.customModels
|
|
25138
|
+
);
|
|
25488
25139
|
const turnId = steeringTurnState?.turnId ?? randomUUIDv4();
|
|
25489
25140
|
if (steeringTurnState === null) {
|
|
25490
25141
|
const turnState = {
|
|
@@ -25548,7 +25199,7 @@ function createClaudeAdapter(recipe, host, options) {
|
|
|
25548
25199
|
context.query.interrupt().then(() => settled.promise).then(() => {
|
|
25549
25200
|
acknowledged = true;
|
|
25550
25201
|
}),
|
|
25551
|
-
new Promise((
|
|
25202
|
+
new Promise((resolve2) => setTimeout(resolve2, CLAUDE_INTERRUPT_GRACE_MS))
|
|
25552
25203
|
]);
|
|
25553
25204
|
} catch (cause) {
|
|
25554
25205
|
throw toRequestError(threadId, "turn/interrupt", cause);
|
|
@@ -25648,6 +25299,8 @@ function createClaudeAdapter(recipe, host, options) {
|
|
|
25648
25299
|
await stopSessionInternal(context, { emitExitEvent: true });
|
|
25649
25300
|
};
|
|
25650
25301
|
return {
|
|
25302
|
+
/** 型号目录:探测用它读并拿当前这份;会话内部自己走同一份。 */
|
|
25303
|
+
modelCatalog: { refresh: refreshModelCatalog, current: currentModelCatalog },
|
|
25651
25304
|
startSession,
|
|
25652
25305
|
sendTurn,
|
|
25653
25306
|
interruptTurn,
|
|
@@ -25674,17 +25327,14 @@ function createClaudeAdapter(recipe, host, options) {
|
|
|
25674
25327
|
};
|
|
25675
25328
|
}
|
|
25676
25329
|
function claudeAdapterBaseEnvironment(recipe) {
|
|
25677
|
-
return {
|
|
25678
|
-
...process.env,
|
|
25679
|
-
...withoutBrainSlots(recipe.environment, brainSlotEnvKeys3(CLAUDE_CARD))
|
|
25680
|
-
};
|
|
25330
|
+
return { ...process.env, ...recipe.environment };
|
|
25681
25331
|
}
|
|
25682
|
-
function createClaudeInstance(config, host, attachments,
|
|
25332
|
+
function createClaudeInstance(config, host, attachments, overrides) {
|
|
25683
25333
|
const recipe = parseClaudeInstanceConfig(config);
|
|
25684
25334
|
const adapter = createClaudeAdapter(recipe, host, {
|
|
25685
25335
|
instanceId: host.instanceId,
|
|
25686
25336
|
...attachments === void 0 ? {} : { attachments },
|
|
25687
|
-
...
|
|
25337
|
+
...overrides?.createQuery === void 0 ? {} : { createQuery: overrides.createQuery },
|
|
25688
25338
|
environment: claudeAdapterBaseEnvironment(recipe),
|
|
25689
25339
|
log: host.log
|
|
25690
25340
|
});
|
|
@@ -25716,6 +25366,7 @@ function createClaudeInstance(config, host, attachments, pluginDataDirPath) {
|
|
|
25716
25366
|
return { status: "unknown" };
|
|
25717
25367
|
}
|
|
25718
25368
|
};
|
|
25369
|
+
let lastProbedVersion;
|
|
25719
25370
|
const probe = async (signal) => {
|
|
25720
25371
|
if (recipe.binaryPath.length === 0) {
|
|
25721
25372
|
return {
|
|
@@ -25741,11 +25392,18 @@ function createClaudeInstance(config, host, attachments, pluginDataDirPath) {
|
|
|
25741
25392
|
]);
|
|
25742
25393
|
const version = parseGenericCliVersion(`${stdout}
|
|
25743
25394
|
${stderr}`);
|
|
25395
|
+
if (version !== null || exitCode === 0) {
|
|
25396
|
+
await adapter.modelCatalog.refresh({ signal, force: version !== lastProbedVersion });
|
|
25397
|
+
lastProbedVersion = version;
|
|
25398
|
+
}
|
|
25744
25399
|
const models = claudeProbeModels({
|
|
25745
|
-
|
|
25400
|
+
catalog: adapter.modelCatalog.current(),
|
|
25746
25401
|
customModels: recipe.customModels
|
|
25747
25402
|
});
|
|
25748
25403
|
const auth = probeAuth();
|
|
25404
|
+
const skills = await discoverClaudeSkills(
|
|
25405
|
+
resolveClaudeConfigDirPath(recipe.homePath, { ...process.env, ...recipe.environment })
|
|
25406
|
+
);
|
|
25749
25407
|
if (exitCode !== 0 && version === null) {
|
|
25750
25408
|
const detail = (stderr || stdout || "claude --version failed").trim();
|
|
25751
25409
|
return {
|
|
@@ -25763,6 +25421,7 @@ ${stderr}`);
|
|
|
25763
25421
|
readiness: "error",
|
|
25764
25422
|
auth,
|
|
25765
25423
|
models,
|
|
25424
|
+
skills,
|
|
25766
25425
|
detail: "Claude is signed out",
|
|
25767
25426
|
// 退出登录了档位照样是那五档。不报就退回宿主四档,而那份映射少了 `plan`。
|
|
25768
25427
|
...CLAUDE_NATIVE_MODE_REPORT
|
|
@@ -25774,6 +25433,7 @@ ${stderr}`);
|
|
|
25774
25433
|
readiness: "ready",
|
|
25775
25434
|
auth,
|
|
25776
25435
|
models,
|
|
25436
|
+
skills,
|
|
25777
25437
|
...CLAUDE_NATIVE_MODE_REPORT
|
|
25778
25438
|
};
|
|
25779
25439
|
};
|
|
@@ -25785,7 +25445,7 @@ ${stderr}`);
|
|
|
25785
25445
|
);
|
|
25786
25446
|
return {
|
|
25787
25447
|
configDir,
|
|
25788
|
-
transcriptDir:
|
|
25448
|
+
transcriptDir: NodePath8.join(configDir, "projects")
|
|
25789
25449
|
};
|
|
25790
25450
|
};
|
|
25791
25451
|
return {
|
|
@@ -25802,7 +25462,7 @@ ${stderr}`);
|
|
|
25802
25462
|
readThread: adapter.readThread,
|
|
25803
25463
|
events: adapter.events,
|
|
25804
25464
|
dispose: adapter.dispose,
|
|
25805
|
-
textGeneration: createClaudeTextGeneration(recipe, host,
|
|
25465
|
+
textGeneration: createClaudeTextGeneration(recipe, host, adapter.modelCatalog.current),
|
|
25806
25466
|
continuationKey: claudeContinuationKey(recipe.homePath),
|
|
25807
25467
|
sessions: {
|
|
25808
25468
|
scan: async (input) => {
|
|
@@ -25828,7 +25488,7 @@ ${stderr}`);
|
|
|
25828
25488
|
start: async () => {
|
|
25829
25489
|
const command = claudeSignInCommand(
|
|
25830
25490
|
recipe.credentialsPath,
|
|
25831
|
-
|
|
25491
|
+
NodeOS8.type() === "Windows_NT" ? "win32" : "linux"
|
|
25832
25492
|
);
|
|
25833
25493
|
return {
|
|
25834
25494
|
operationId: `claude-sign-in-${crypto.randomUUID()}`,
|
|
@@ -25844,13 +25504,12 @@ ${stderr}`);
|
|
|
25844
25504
|
|
|
25845
25505
|
// src/index.ts
|
|
25846
25506
|
var capturedAttachments;
|
|
25847
|
-
var capturedDataDirPath;
|
|
25848
25507
|
var executors = [
|
|
25849
25508
|
{
|
|
25850
25509
|
card: CLAUDE_CARD,
|
|
25851
25510
|
createInstance: async (config, host) => {
|
|
25852
25511
|
host.log.info("createInstance");
|
|
25853
|
-
return createClaudeInstance(config, host, capturedAttachments
|
|
25512
|
+
return createClaudeInstance(config, host, capturedAttachments);
|
|
25854
25513
|
}
|
|
25855
25514
|
}
|
|
25856
25515
|
];
|
|
@@ -25860,7 +25519,6 @@ var index_default = definePlugin({
|
|
|
25860
25519
|
executors,
|
|
25861
25520
|
activate(ctx) {
|
|
25862
25521
|
capturedAttachments = ctx.attachments;
|
|
25863
|
-
capturedDataDirPath = ctx.paths.dataDir;
|
|
25864
25522
|
ctx.log.info("claude executor ready");
|
|
25865
25523
|
}
|
|
25866
25524
|
});
|