@ycodium-ai/agent-claude 0.2.3681 → 0.2.3766
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/dist/index.js +98 -19
- package/locales/en.json +13 -2
- package/locales/zh-CN.json +13 -2
- package/package.json +5 -3
package/dist/index.js
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
+
import * as NodePath20 from "node:path";
|
|
2
3
|
import { definePlugin } from "@ycodium-ai/plugin-api";
|
|
4
|
+
import {
|
|
5
|
+
EXECUTOR_EFFECTIVE_PAYLOAD_SCHEMA,
|
|
6
|
+
executorEnvironmentValue,
|
|
7
|
+
executorHomeEffectiveValue,
|
|
8
|
+
readExecutorEffectiveRequest
|
|
9
|
+
} from "@ycodium-ai/plugin-api/executor";
|
|
3
10
|
|
|
4
11
|
// src/card.ts
|
|
5
12
|
var CLAUDE_DRIVER_KIND = "claudeAgent";
|
|
@@ -13,6 +20,8 @@ var CLAUDE_CARD = {
|
|
|
13
20
|
launchArgs: "",
|
|
14
21
|
// Claude 的隔离走 CLAUDE_CONFIG_DIR,不注入 HOME(钥匙串查找跟着 HOME)。
|
|
15
22
|
homeEnvVar: "",
|
|
23
|
+
// 设置表单里留空的格子此刻会用什么,见 index.ts 的同名命令。
|
|
24
|
+
effectiveCommand: "effectiveConfig",
|
|
16
25
|
// 写的是凭据目录(`credentialsPath`),不是共用工作目录:写错字段等于把两个账号的会话历史
|
|
17
26
|
// 也分开,同一 thread 里就换不了账号了。
|
|
18
27
|
accountDirectory: {
|
|
@@ -279,8 +288,8 @@ var waitForJsonlHistory = (input) => {
|
|
|
279
288
|
signal.throwIfAborted();
|
|
280
289
|
if (error !== void 0) throw error;
|
|
281
290
|
if (!dirty)
|
|
282
|
-
await new Promise((
|
|
283
|
-
wake =
|
|
291
|
+
await new Promise((resolve6) => {
|
|
292
|
+
wake = resolve6;
|
|
284
293
|
});
|
|
285
294
|
signal.throwIfAborted();
|
|
286
295
|
dirty = false;
|
|
@@ -1349,8 +1358,8 @@ async function openJsonlHistory(path, layout, signal) {
|
|
|
1349
1358
|
readSignal.throwIfAborted();
|
|
1350
1359
|
if (failure !== void 0) throw failure;
|
|
1351
1360
|
if (!dirty)
|
|
1352
|
-
await new Promise((
|
|
1353
|
-
wake =
|
|
1361
|
+
await new Promise((resolve6) => {
|
|
1362
|
+
wake = resolve6;
|
|
1354
1363
|
});
|
|
1355
1364
|
readSignal.throwIfAborted();
|
|
1356
1365
|
dirty = false;
|
|
@@ -23252,9 +23261,9 @@ var PromptQueue = class {
|
|
|
23252
23261
|
const queued = this.#queued.shift();
|
|
23253
23262
|
if (queued !== void 0) return Promise.resolve(queued);
|
|
23254
23263
|
if (this.#closed) return Promise.resolve(void 0);
|
|
23255
|
-
return new Promise((
|
|
23264
|
+
return new Promise((resolve6) => {
|
|
23256
23265
|
this.#waiters.push((result) => {
|
|
23257
|
-
|
|
23266
|
+
resolve6(result.done ? void 0 : result.value);
|
|
23258
23267
|
});
|
|
23259
23268
|
});
|
|
23260
23269
|
}
|
|
@@ -24352,12 +24361,12 @@ function makeClaudeProcessSpawner(host, stderr, config = {}) {
|
|
|
24352
24361
|
// src/sdkRead.ts
|
|
24353
24362
|
var silentPrompt = (signal) => ({
|
|
24354
24363
|
[Symbol.asyncIterator]: () => ({
|
|
24355
|
-
next: () => new Promise((
|
|
24364
|
+
next: () => new Promise((resolve6) => {
|
|
24356
24365
|
if (signal.aborted) {
|
|
24357
|
-
|
|
24366
|
+
resolve6({ done: true, value: void 0 });
|
|
24358
24367
|
return;
|
|
24359
24368
|
}
|
|
24360
|
-
signal.addEventListener("abort", () =>
|
|
24369
|
+
signal.addEventListener("abort", () => resolve6({ done: true, value: void 0 }), {
|
|
24361
24370
|
once: true
|
|
24362
24371
|
});
|
|
24363
24372
|
}),
|
|
@@ -25808,7 +25817,7 @@ var makeSessionControls = (deps) => {
|
|
|
25808
25817
|
context.query.interrupt().then(() => settled.promise).then(() => {
|
|
25809
25818
|
acknowledged = true;
|
|
25810
25819
|
}),
|
|
25811
|
-
new Promise((
|
|
25820
|
+
new Promise((resolve6) => setTimeout(resolve6, CLAUDE_INTERRUPT_GRACE_MS))
|
|
25812
25821
|
]);
|
|
25813
25822
|
} catch (cause) {
|
|
25814
25823
|
throw toRequestError(threadId, "turn/interrupt", cause);
|
|
@@ -25940,8 +25949,8 @@ var makeSessionLifecycle = (deps) => {
|
|
|
25940
25949
|
const claim = context.turnState?.resultClaim;
|
|
25941
25950
|
if (claim === void 0) return;
|
|
25942
25951
|
let timer;
|
|
25943
|
-
const timeout = new Promise((
|
|
25944
|
-
timer = setTimeout(() =>
|
|
25952
|
+
const timeout = new Promise((resolve6) => {
|
|
25953
|
+
timer = setTimeout(() => resolve6("timeout"), RESULT_CLAIM_WAIT_MS);
|
|
25945
25954
|
});
|
|
25946
25955
|
try {
|
|
25947
25956
|
const outcome = await Promise.race([claim.then(() => "settled"), timeout]);
|
|
@@ -26020,7 +26029,7 @@ var makeSessionLifecycle = (deps) => {
|
|
|
26020
26029
|
if (streamFiber) {
|
|
26021
26030
|
await Promise.race([
|
|
26022
26031
|
streamFiber.catch(() => void 0),
|
|
26023
|
-
new Promise((
|
|
26032
|
+
new Promise((resolve6) => setTimeout(resolve6, 1e3))
|
|
26024
26033
|
]);
|
|
26025
26034
|
}
|
|
26026
26035
|
const updatedAt = nowIso();
|
|
@@ -26316,8 +26325,8 @@ var makeStartSession = (deps) => {
|
|
|
26316
26325
|
try {
|
|
26317
26326
|
return await Promise.race([
|
|
26318
26327
|
contextDeferred.promise,
|
|
26319
|
-
new Promise((
|
|
26320
|
-
timer = setTimeout(() =>
|
|
26328
|
+
new Promise((resolve6) => {
|
|
26329
|
+
timer = setTimeout(() => resolve6(void 0), CLAUDE_SESSION_CONTEXT_WAIT_MS);
|
|
26321
26330
|
})
|
|
26322
26331
|
]);
|
|
26323
26332
|
} catch {
|
|
@@ -26916,10 +26925,35 @@ var claudeSlashCommandsFromSdk = (commands) => Array.isArray(commands) ? command
|
|
|
26916
26925
|
];
|
|
26917
26926
|
}) : [];
|
|
26918
26927
|
|
|
26928
|
+
// src/adapter/reportedModel.ts
|
|
26929
|
+
var makeReportedModelEmitter = (emitter) => {
|
|
26930
|
+
const { eventHeader, offerRuntimeEvent } = emitter;
|
|
26931
|
+
return (context, model) => {
|
|
26932
|
+
const turn = context.turnState;
|
|
26933
|
+
if (turn === void 0 || typeof model !== "string") return;
|
|
26934
|
+
const reported = model.replace(/\[[^\]]*\]\s*$/, "").trim();
|
|
26935
|
+
if (reported.length === 0) return;
|
|
26936
|
+
const key = `${turn.turnId}|${reported}`;
|
|
26937
|
+
if ((context.reportedModelKeys ??= /* @__PURE__ */ new Set()).has(key)) return;
|
|
26938
|
+
context.reportedModelKeys.add(key);
|
|
26939
|
+
offerRuntimeEvent(context, {
|
|
26940
|
+
type: "thread.metadata.updated",
|
|
26941
|
+
...eventHeader(context, {
|
|
26942
|
+
eventId: `${turn.turnId}:model:${reported}`,
|
|
26943
|
+
createdAt: turn.startedAt
|
|
26944
|
+
}),
|
|
26945
|
+
turnId: asCanonicalTurnId(turn.turnId),
|
|
26946
|
+
payload: { model: reported, modelSource: "reported" },
|
|
26947
|
+
providerRefs: {}
|
|
26948
|
+
});
|
|
26949
|
+
};
|
|
26950
|
+
};
|
|
26951
|
+
|
|
26919
26952
|
// src/adapter/systemMessages.ts
|
|
26920
26953
|
var makeSystemMessageHandler = (deps) => {
|
|
26921
26954
|
const { emitter, host, emitRuntimeError, emitRuntimeWarning, emitThreadTokenUsage } = deps;
|
|
26922
26955
|
const { randomUUIDv4, makeEventStamp, eventHeader, offerRuntimeEvent } = emitter;
|
|
26956
|
+
const emitReportedModel = makeReportedModelEmitter(emitter);
|
|
26923
26957
|
const emitWorkflowMemberProgress = async (context, base, message) => {
|
|
26924
26958
|
const progress = parseWorkflowProgress(
|
|
26925
26959
|
message.workflow_progress
|
|
@@ -27030,6 +27064,7 @@ var makeSystemMessageHandler = (deps) => {
|
|
|
27030
27064
|
config: message
|
|
27031
27065
|
}
|
|
27032
27066
|
});
|
|
27067
|
+
emitReportedModel(context, message.model);
|
|
27033
27068
|
const threadId = context.session.threadId;
|
|
27034
27069
|
const names = claudeSlashCommandsFromNames(message.slash_commands);
|
|
27035
27070
|
if (names.length > 0) host.reportSessionInventory?.({ threadId, slashCommands: names });
|
|
@@ -27675,6 +27710,7 @@ var makeTurnMessageHandlers = (deps) => {
|
|
|
27675
27710
|
backfillAssistantTextBlocksFromSnapshot
|
|
27676
27711
|
} = deps;
|
|
27677
27712
|
const { makeEventStamp, eventHeader, offerRuntimeEvent } = emitter;
|
|
27713
|
+
const emitReportedModel = makeReportedModelEmitter(emitter);
|
|
27678
27714
|
const handleUserMessage = async (context, message) => {
|
|
27679
27715
|
if (message.type !== "user") {
|
|
27680
27716
|
return;
|
|
@@ -27869,6 +27905,7 @@ var makeTurnMessageHandlers = (deps) => {
|
|
|
27869
27905
|
return;
|
|
27870
27906
|
}
|
|
27871
27907
|
await ensureSyntheticTurn(context);
|
|
27908
|
+
emitReportedModel(context, message.message?.model);
|
|
27872
27909
|
const content = message.message?.content;
|
|
27873
27910
|
if (Array.isArray(content)) {
|
|
27874
27911
|
for (const block of content) {
|
|
@@ -28000,8 +28037,8 @@ var EventBus = class {
|
|
|
28000
28037
|
const queued = this.#queued.shift();
|
|
28001
28038
|
if (queued !== void 0) return Promise.resolve({ done: false, value: queued });
|
|
28002
28039
|
if (this.#closed) return Promise.resolve({ done: true, value: void 0 });
|
|
28003
|
-
return new Promise((
|
|
28004
|
-
this.#waiters.push(
|
|
28040
|
+
return new Promise((resolve6) => {
|
|
28041
|
+
this.#waiters.push(resolve6);
|
|
28005
28042
|
});
|
|
28006
28043
|
}
|
|
28007
28044
|
};
|
|
@@ -29628,14 +29665,56 @@ var executors = [
|
|
|
29628
29665
|
createInstance: async (config, host) => {
|
|
29629
29666
|
host.log.info("createInstance");
|
|
29630
29667
|
return createClaudeInstance(config, host, capturedAttachments, void 0, capturedCache);
|
|
29631
|
-
}
|
|
29668
|
+
},
|
|
29669
|
+
// 厂商脚本装,宿主卸不了;登录要在那台机器的终端里跑 `claude auth login`,宿主只回这条命令。
|
|
29670
|
+
lifecycle: [
|
|
29671
|
+
{ kind: "install", reversible: false },
|
|
29672
|
+
{ kind: "detect", reversible: true },
|
|
29673
|
+
{ kind: "sign-in", reversible: false },
|
|
29674
|
+
{ kind: "update", reversible: false }
|
|
29675
|
+
]
|
|
29632
29676
|
}
|
|
29633
29677
|
];
|
|
29634
29678
|
var index_default = definePlugin({
|
|
29635
29679
|
id: "agent-claude",
|
|
29636
|
-
apiVersion:
|
|
29680
|
+
apiVersion: 56,
|
|
29637
29681
|
executors,
|
|
29638
29682
|
activate(ctx) {
|
|
29683
|
+
ctx.command({
|
|
29684
|
+
name: "effectiveConfig",
|
|
29685
|
+
description: "Settings form: the config and credentials directories empty fields resolve to.",
|
|
29686
|
+
scope: "read",
|
|
29687
|
+
payloadSchema: EXECUTOR_EFFECTIVE_PAYLOAD_SCHEMA,
|
|
29688
|
+
handle: async (payload) => {
|
|
29689
|
+
const request = readExecutorEffectiveRequest(payload);
|
|
29690
|
+
const home = executorHomeEffectiveValue(
|
|
29691
|
+
"CLAUDE_CONFIG_DIR",
|
|
29692
|
+
request,
|
|
29693
|
+
process.env,
|
|
29694
|
+
(value) => resolveClaudeConfigDirPath("", value === void 0 ? {} : { CLAUDE_CONFIG_DIR: value })
|
|
29695
|
+
);
|
|
29696
|
+
const credentialsVariable = "CLAUDE_SECURESTORAGE_CONFIG_DIR";
|
|
29697
|
+
const configuredHome = typeof request.config["homePath"] === "string" ? request.config["homePath"] : "";
|
|
29698
|
+
const configVariable = executorEnvironmentValue("CLAUDE_CONFIG_DIR", request, process.env);
|
|
29699
|
+
const configDirectory = resolveClaudeConfigDirPath(
|
|
29700
|
+
configuredHome,
|
|
29701
|
+
configVariable === null ? {} : { CLAUDE_CONFIG_DIR: configVariable.value }
|
|
29702
|
+
);
|
|
29703
|
+
const keychain = (
|
|
29704
|
+
// eslint-disable-next-line ycodium/no-global-process-runtime -- 钥匙串只在 macOS 上用。
|
|
29705
|
+
process.platform === "darwin" && configuredHome.trim() === "" && configVariable === null
|
|
29706
|
+
);
|
|
29707
|
+
return {
|
|
29708
|
+
homePath: home,
|
|
29709
|
+
credentialsPath: executorEnvironmentValue(credentialsVariable, request, process.env) !== null ? executorHomeEffectiveValue(
|
|
29710
|
+
credentialsVariable,
|
|
29711
|
+
request,
|
|
29712
|
+
process.env,
|
|
29713
|
+
(value) => NodePath20.resolve(value ?? "")
|
|
29714
|
+
) : keychain ? { detailKey: "form.credentialsPath.keychain" } : { value: configDirectory, detailKey: "form.credentialsPath.sameAsHome" }
|
|
29715
|
+
};
|
|
29716
|
+
}
|
|
29717
|
+
});
|
|
29639
29718
|
capturedAttachments = ctx.attachments;
|
|
29640
29719
|
capturedCache = ctx.cache;
|
|
29641
29720
|
ctx.log.info("claude executor ready");
|
package/locales/en.json
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
+
"presentation": {
|
|
3
|
+
"name": "Claude Code",
|
|
4
|
+
"description": "Use Claude Code in Ycodium, switching models mid-session."
|
|
5
|
+
},
|
|
2
6
|
"form": {
|
|
3
7
|
"binaryPath": {
|
|
4
8
|
"title": "Program path",
|
|
@@ -13,17 +17,24 @@
|
|
|
13
17
|
"credentialsPath": {
|
|
14
18
|
"title": "Credentials directory",
|
|
15
19
|
"description": "Account-specific login directory. Keeps credentials separate while sharing the config directory.",
|
|
16
|
-
"placeholder": "~/.claude-personal"
|
|
20
|
+
"placeholder": "~/.claude-personal",
|
|
21
|
+
"sameAsHome": "same as the config directory",
|
|
22
|
+
"keychain": "macOS Keychain"
|
|
17
23
|
},
|
|
18
24
|
"autoCompactWindow": {
|
|
19
25
|
"title": "Auto-compact after",
|
|
20
26
|
"description": "Compact after 100,000 to 1,000,000 tokens. Leave empty to use Claude's default.",
|
|
21
|
-
"placeholder": "
|
|
27
|
+
"placeholder": "Claude's default"
|
|
22
28
|
},
|
|
23
29
|
"launchArgs": {
|
|
24
30
|
"title": "Launch arguments",
|
|
25
31
|
"description": "Additional CLI arguments passed on session start. --permission-mode and --dangerously-skip-permissions are ignored here; choose the permission mode in the chat input.",
|
|
26
32
|
"placeholder": "e.g. --chrome"
|
|
33
|
+
},
|
|
34
|
+
"effective": {
|
|
35
|
+
"provider": "{{name}} in this provider",
|
|
36
|
+
"machine": "{{name}} on this machine",
|
|
37
|
+
"default": "default"
|
|
27
38
|
}
|
|
28
39
|
},
|
|
29
40
|
"probe": {
|
package/locales/zh-CN.json
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
+
"presentation": {
|
|
3
|
+
"name": "Claude Code",
|
|
4
|
+
"description": "在 Ycodium 里使用 Claude Code,会话中途也能换模型。"
|
|
5
|
+
},
|
|
2
6
|
"form": {
|
|
3
7
|
"binaryPath": {
|
|
4
8
|
"title": "程序路径",
|
|
@@ -13,17 +17,24 @@
|
|
|
13
17
|
"credentialsPath": {
|
|
14
18
|
"title": "凭据目录",
|
|
15
19
|
"description": "账号专用的登录目录。凭据单独保存,配置目录仍可共用。",
|
|
16
|
-
"placeholder": "~/.claude-personal"
|
|
20
|
+
"placeholder": "~/.claude-personal",
|
|
21
|
+
"sameAsHome": "与配置目录相同",
|
|
22
|
+
"keychain": "macOS 钥匙串"
|
|
17
23
|
},
|
|
18
24
|
"autoCompactWindow": {
|
|
19
25
|
"title": "自动压缩阈值",
|
|
20
26
|
"description": "在 100,000 到 1,000,000 个 token 后压缩。留空则使用 Claude 的默认值。",
|
|
21
|
-
"placeholder": "
|
|
27
|
+
"placeholder": "Claude 的默认值"
|
|
22
28
|
},
|
|
23
29
|
"launchArgs": {
|
|
24
30
|
"title": "启动参数",
|
|
25
31
|
"description": "会话启动时传入的额外命令行参数。其中的 --permission-mode 与 --dangerously-skip-permissions 会被忽略,权限模式请在输入区选择。",
|
|
26
32
|
"placeholder": "例如 --chrome"
|
|
33
|
+
},
|
|
34
|
+
"effective": {
|
|
35
|
+
"provider": "本 provider 的 {{name}}",
|
|
36
|
+
"machine": "本机的 {{name}}",
|
|
37
|
+
"default": "默认"
|
|
27
38
|
}
|
|
28
39
|
},
|
|
29
40
|
"probe": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ycodium-ai/agent-claude",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3766",
|
|
4
4
|
"description": "Claude executor: Claude Code CLI via @anthropic-ai/claude-agent-sdk.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ycodium",
|
|
@@ -24,15 +24,17 @@
|
|
|
24
24
|
"@types/node": "24.12.4",
|
|
25
25
|
"esbuild": "0.28.1",
|
|
26
26
|
"vite-plus": "0.2.2",
|
|
27
|
-
"@ycodium-ai/plugin-api": "0.2.3681",
|
|
28
27
|
"ycodium-composer-tokens": "0.0.0",
|
|
29
28
|
"ycodium-executor-testing": "0.0.0",
|
|
29
|
+
"@ycodium-ai/plugin-api": "0.2.3766",
|
|
30
30
|
"ycodium-jsonl-stream": "0.0.0"
|
|
31
31
|
},
|
|
32
32
|
"ycodium": {
|
|
33
33
|
"plugin": "./dist/index.js",
|
|
34
34
|
"displayName": "Claude Code",
|
|
35
|
-
"
|
|
35
|
+
"displayNameKey": "presentation.name",
|
|
36
|
+
"description": "Use Claude Code in Ycodium, switching models mid-session.",
|
|
37
|
+
"descriptionKey": "presentation.description",
|
|
36
38
|
"icon": "./assets/icon.svg",
|
|
37
39
|
"permissions": [
|
|
38
40
|
{
|