@clawos-dev/clawd 0.2.656 → 0.2.658
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/app-builder-plugin/mcp-server.cjs +15 -3
- package/dist/cli.cjs +727 -567
- package/dist/cloud-persona-conversations.html +72 -72
- package/dist/dispatch/mcp-server.cjs +54 -29
- package/dist/persona-defaults/persona-app-builder/mcp/clawd-app-builder/mcp-server.cjs +15 -3
- package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/mcp-server.cjs +15 -3
- package/dist/share-ui/assets/{guest-3JOCTfo2.js → guest-CeIO68-h.js} +136 -136
- package/dist/share-ui/guest.html +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -5830,7 +5830,11 @@ var init_subscription_channel = __esm({
|
|
|
5830
5830
|
SubscriptionChannelActivateArgsSchema = external_exports.object({
|
|
5831
5831
|
id: external_exports.string().min(1).nullable()
|
|
5832
5832
|
}).strict();
|
|
5833
|
-
SubscriptionChannelModelsArgsSchema = external_exports.object({
|
|
5833
|
+
SubscriptionChannelModelsArgsSchema = external_exports.object({
|
|
5834
|
+
channelId: external_exports.string().min(1).optional(),
|
|
5835
|
+
/** Reject discovery when the saved cloud credential source has since been edited. */
|
|
5836
|
+
updatedAt: external_exports.number().optional()
|
|
5837
|
+
}).strict().refine((args) => args.updatedAt === void 0 || args.channelId !== void 0, { message: "updatedAt requires channelId" });
|
|
5834
5838
|
SubscriptionChannelModelsResultSchema = external_exports.object({
|
|
5835
5839
|
/** 没有激活通道 = null(models 为空) */
|
|
5836
5840
|
channelId: external_exports.string().nullable(),
|
|
@@ -6313,7 +6317,7 @@ function cloudEngineSettings(p3) {
|
|
|
6313
6317
|
function repoSlug(url) {
|
|
6314
6318
|
return url.trim().replace(/^git@[^:]+:/, "").replace(/^https?:\/\/[^/]+\//, "").replace(/\.git$/, "");
|
|
6315
6319
|
}
|
|
6316
|
-
var DeployFileSchema, SCAN_BASE_KINDS, ScanBaseKindSchema, DeployScanStatusSchema, DeployScanSchema, DeployReleasedSchema, DEPLOY_PROMOTION_PHASES, DeployPromotionSchema, DeployScanFileSchema, DeployRepoSchema, DeploySecretPresenceSchema, ENGINE_AUTH_SECRETS, ENGINE_AUTH_PARTIAL_BLOCKER, DEPLOY_STAGE_STATUSES, DeployStageStatusSchema, DEPLOY_VERIFY_STAGE, DEPLOY_STAGE_KEYS, DeployStageKeySchema, DeployJobSchema, DeployRunSchema, CLOUD_ENGINES, DeployUnpublishRunSchema, DeployStateSchema, DeployUnpublishResultSchema, DeployPatchResultSchema, DeployReleaseResultSchema, DeployPersonaArgsSchema, DeployGetArgsSchema, DeployScanArgsSchema, DeployReleaseArgsSchema, DeployConfirmTestArgsSchema, DeployPromoteArgsSchema, DeployOpenTestArgsSchema, DeployEnvironmentArgsSchema, DeployConfirmTestResultSchema, DeployPromoteResultSchema, DeployOpenTestResultSchema, DeployPatchArgsSchema, DeployPutSecretArgsSchema, DeploySetEngineAuthArgsSchema, DeployRerunJobArgsSchema, DeployReportFindingArgsSchema, DeployFinishScanArgsSchema, PERSONA_REPO_ORG;
|
|
6320
|
+
var DeployFileSchema, SCAN_BASE_KINDS, ScanBaseKindSchema, DeployScanStatusSchema, DeployScanSchema, DeployReleasedSchema, DEPLOY_PROMOTION_PHASES, DeployPromotionSchema, DeployEngineChannelSchema, DeployEngineChannelsSchema, DeployScanFileSchema, DeployRepoSchema, DeploySecretPresenceSchema, ENGINE_AUTH_SECRETS, ENGINE_AUTH_PARTIAL_BLOCKER, DEPLOY_STAGE_STATUSES, DeployStageStatusSchema, DEPLOY_VERIFY_STAGE, DEPLOY_STAGE_KEYS, DeployStageKeySchema, DeployJobSchema, DeployRunSchema, CLOUD_ENGINES, DeployUnpublishRunSchema, DeployStateSchema, DeployUnpublishResultSchema, DeployPatchResultSchema, DeployReleaseResultSchema, DeployPersonaArgsSchema, DeployGetArgsSchema, DeployScanArgsSchema, DeployReleaseArgsSchema, DeployConfirmTestArgsSchema, DeployPromoteArgsSchema, DeployOpenTestArgsSchema, DeployEnvironmentArgsSchema, DeployConfirmTestResultSchema, DeployPromoteResultSchema, DeployOpenTestResultSchema, DeployPatchArgsSchema, DeployPutSecretArgsSchema, DeploySetEngineAuthArgsSchema, DeployRerunJobArgsSchema, DeployReportFindingArgsSchema, DeployFinishScanArgsSchema, PERSONA_REPO_ORG;
|
|
6317
6321
|
var init_deploy_schemas = __esm({
|
|
6318
6322
|
"../protocol/src/deploy-schemas.ts"() {
|
|
6319
6323
|
"use strict";
|
|
@@ -6381,8 +6385,14 @@ var init_deploy_schemas = __esm({
|
|
|
6381
6385
|
runAttempt: external_exports.number().int().positive().optional(),
|
|
6382
6386
|
error: external_exports.string().optional()
|
|
6383
6387
|
}).strict();
|
|
6388
|
+
DeployEngineChannelSchema = external_exports.object({ channelId: external_exports.string().min(1), updatedAt: external_exports.number() }).strict();
|
|
6389
|
+
DeployEngineChannelsSchema = external_exports.object({
|
|
6390
|
+
integration: DeployEngineChannelSchema.nullable().optional(),
|
|
6391
|
+
production: DeployEngineChannelSchema.nullable().optional()
|
|
6392
|
+
}).strict();
|
|
6384
6393
|
DeployScanFileSchema = external_exports.object({
|
|
6385
6394
|
version: external_exports.literal(4),
|
|
6395
|
+
engineChannels: DeployEngineChannelsSchema.optional(),
|
|
6386
6396
|
scans: external_exports.array(DeployScanSchema),
|
|
6387
6397
|
releases: external_exports.array(DeployReleasedSchema),
|
|
6388
6398
|
promotions: external_exports.array(DeployPromotionSchema).default([])
|
|
@@ -6439,6 +6449,7 @@ var init_deploy_schemas = __esm({
|
|
|
6439
6449
|
}).strict();
|
|
6440
6450
|
DeployStateSchema = external_exports.object({
|
|
6441
6451
|
personaId: external_exports.string().min(1),
|
|
6452
|
+
engineChannels: DeployEngineChannelsSchema.optional(),
|
|
6442
6453
|
/** 本机 GitHub 身份(机器级,githubAuth:* 的同一份;上云页顶上那张卡用)。老 daemon 不给(可选只为兼容),UI 缺席时按未知处理 */
|
|
6443
6454
|
github: GithubAuthStatusSchema.optional(),
|
|
6444
6455
|
/** Current publisher's Feishu tool grant, including authorization links before first release. */
|
|
@@ -9332,8 +9343,9 @@ var init_methods = __esm({
|
|
|
9332
9343
|
args: SubscriptionChannelActivateArgsSchema
|
|
9333
9344
|
},
|
|
9334
9345
|
"subscriptionChannel:models": {
|
|
9335
|
-
summary: "\u5217\u51FA\
|
|
9336
|
-
args: SubscriptionChannelModelsArgsSchema
|
|
9346
|
+
summary: "\u5217\u51FA\u6307\u5B9A\u8BA2\u9605\u901A\u9053\u7684\u6A21\u578B ID\uFF0C\u4E0D\u6FC0\u6D3B\u672C\u673A\u901A\u9053\uFF1B\u7701\u7565 channelId \u65F6\u67E5\u672C\u673A\u6FC0\u6D3B\u901A\u9053\u3002updatedAt \u6821\u9A8C\u4E91\u7AEF\u4FDD\u5B58\u540E\u901A\u9053\u662F\u5426\u53D8\u66F4\u3002\u6CA1\u6709\u672C\u673A\u6FC0\u6D3B\u901A\u9053\u56DE\u7A7A\u8868\uFF1B\u6307\u5B9A\u901A\u9053\u4E0D\u5B58\u5728\u3001\u5DF2\u53D8\u66F4\u6216\u8BF7\u6C42\u5931\u8D25 reject\u3002owner-only",
|
|
9347
|
+
args: SubscriptionChannelModelsArgsSchema,
|
|
9348
|
+
argsConstraints: { dependentRequired: { updatedAt: ["channelId"] } }
|
|
9337
9349
|
},
|
|
9338
9350
|
"engine:connectPool": {
|
|
9339
9351
|
summary: "\u63A5\u5165\u53F7\u6C60\uFF1A\u62FF\u81EA\u52A9\u53F0\u53D1\u7684\u4E2A\u4EBA key\uFF0C\u62C9\u53F7\u6C60 setup.sh \u8DD1\u4E00\u904D\uFF08\u5199 ~/.codex/config.toml \u6307\u5411 CLIProxyAPI \u4EE3\u7406\uFF09\uFF0C\u518D\u5237 codex \u6A21\u578B\u8868\u9A8C\u8BC1\u3002\u6210\u529F\u56DE { ok:true }\uFF1B\u62FF\u4E0D\u5230\u811A\u672C / \u811A\u672C\u62A5\u9519 / \u8D85\u65F6 / 401 \u4E00\u5F8B reject \u5E26\u4EBA\u8BDD\u3002\u53EA\u7BA1 codex\uFF1B\u672C\u673A\u6CA1\u88C5 codex \u62A5 INVALID_PARAM\u3002owner-only",
|
|
@@ -15876,17 +15888,504 @@ var init_permission_stdio = __esm({
|
|
|
15876
15888
|
}
|
|
15877
15889
|
});
|
|
15878
15890
|
|
|
15891
|
+
// src/tools/codex-provider-models.ts
|
|
15892
|
+
function asRecord2(v3) {
|
|
15893
|
+
return v3 && typeof v3 === "object" && !Array.isArray(v3) ? v3 : null;
|
|
15894
|
+
}
|
|
15895
|
+
function readAuthKey(codexHome) {
|
|
15896
|
+
try {
|
|
15897
|
+
const raw = JSON.parse(import_node_fs21.default.readFileSync(import_node_path21.default.join(codexHome, "auth.json"), "utf8"));
|
|
15898
|
+
const key = asRecord2(raw)?.OPENAI_API_KEY;
|
|
15899
|
+
return typeof key === "string" && key ? key : void 0;
|
|
15900
|
+
} catch {
|
|
15901
|
+
return void 0;
|
|
15902
|
+
}
|
|
15903
|
+
}
|
|
15904
|
+
async function runAuthCommand(name, auth, deps) {
|
|
15905
|
+
const command = typeof auth.command === "string" && auth.command ? auth.command : void 0;
|
|
15906
|
+
if (!command) return void 0;
|
|
15907
|
+
const args = Array.isArray(auth.args) ? auth.args.filter((a2) => typeof a2 === "string") : [];
|
|
15908
|
+
const timeout = typeof auth.timeout_ms === "number" && auth.timeout_ms > 0 ? Math.min(auth.timeout_ms, AUTH_COMMAND_TIMEOUT_MS) : AUTH_COMMAND_TIMEOUT_MS;
|
|
15909
|
+
const cwd = typeof auth.cwd === "string" && auth.cwd ? auth.cwd : void 0;
|
|
15910
|
+
try {
|
|
15911
|
+
const { stdout } = await deps.execFileImpl(command, args, { ...cwd ? { cwd } : {}, timeout });
|
|
15912
|
+
const token = String(stdout).trim();
|
|
15913
|
+
if (token) return token;
|
|
15914
|
+
deps.logger?.warn?.(`provider "${name}": auth command \`${command}\` produced an empty token, sending unauthenticated`);
|
|
15915
|
+
} catch (err) {
|
|
15916
|
+
const e = err;
|
|
15917
|
+
const why = e.killed ? `killed by ${e.signal ?? "signal"} (timeout ${timeout}ms)` : e.code !== void 0 ? `exit/code ${e.code}` : "failed";
|
|
15918
|
+
deps.logger?.warn?.(`provider "${name}": auth command \`${command}\` ${why}, sending unauthenticated`);
|
|
15919
|
+
}
|
|
15920
|
+
return void 0;
|
|
15921
|
+
}
|
|
15922
|
+
async function resolveProviderEndpoint(rawConfig, deps = {}) {
|
|
15923
|
+
const config = asRecord2(asRecord2(rawConfig)?.config);
|
|
15924
|
+
if (!config) return null;
|
|
15925
|
+
const name = config.model_provider;
|
|
15926
|
+
if (typeof name !== "string" || !name) return null;
|
|
15927
|
+
const entry = asRecord2(asRecord2(config.model_providers)?.[name]);
|
|
15928
|
+
if (!entry) return null;
|
|
15929
|
+
const baseUrl = entry.base_url;
|
|
15930
|
+
if (typeof baseUrl !== "string" || !baseUrl) return null;
|
|
15931
|
+
const env = deps.env ?? process.env;
|
|
15932
|
+
const codexHome = deps.codexHome ?? env.CODEX_HOME ?? import_node_path21.default.join(import_node_os10.default.homedir(), ".codex");
|
|
15933
|
+
const envKey = typeof entry.env_key === "string" && entry.env_key ? entry.env_key : null;
|
|
15934
|
+
const inlineToken = typeof entry.experimental_bearer_token === "string" && entry.experimental_bearer_token ? entry.experimental_bearer_token : void 0;
|
|
15935
|
+
const auth = asRecord2(entry.auth);
|
|
15936
|
+
let token;
|
|
15937
|
+
if (envKey) token = env[envKey];
|
|
15938
|
+
else if (inlineToken) token = inlineToken;
|
|
15939
|
+
else if (auth && typeof auth.command === "string" && auth.command) {
|
|
15940
|
+
token = await runAuthCommand(name, auth, { execFileImpl: deps.execFileImpl ?? defaultExecFile, ...deps.logger ? { logger: deps.logger } : {} });
|
|
15941
|
+
} else token = readAuthKey(codexHome);
|
|
15942
|
+
if (!token && !(auth && typeof auth.command === "string" && auth.command)) {
|
|
15943
|
+
deps.logger?.warn?.(
|
|
15944
|
+
envKey ? `provider "${name}": env_key ${envKey} is not set in the daemon process, sending unauthenticated` : `provider "${name}": no OPENAI_API_KEY in ${codexHome}/auth.json, sending unauthenticated`
|
|
15945
|
+
);
|
|
15946
|
+
}
|
|
15947
|
+
return {
|
|
15948
|
+
baseUrl,
|
|
15949
|
+
headers: {
|
|
15950
|
+
Accept: "application/json",
|
|
15951
|
+
...token ? { Authorization: `Bearer ${token}` } : {}
|
|
15952
|
+
}
|
|
15953
|
+
};
|
|
15954
|
+
}
|
|
15955
|
+
async function fetchProviderModels(endpoint, deps = {}) {
|
|
15956
|
+
const fetchImpl = deps.fetchImpl ?? fetch;
|
|
15957
|
+
const controller = new AbortController();
|
|
15958
|
+
const timer = setTimeout(() => controller.abort(), deps.timeoutMs ?? PROVIDER_FETCH_TIMEOUT_MS);
|
|
15959
|
+
const url = `${endpoint.baseUrl.replace(/\/$/, "")}/models`;
|
|
15960
|
+
try {
|
|
15961
|
+
const res = await fetchImpl(url, { headers: endpoint.headers, signal: controller.signal });
|
|
15962
|
+
if (!res.ok) throw new Error(`provider model list failed: HTTP ${res.status} from ${url}`);
|
|
15963
|
+
const data = asRecord2(await res.json())?.data;
|
|
15964
|
+
if (!Array.isArray(data)) throw new Error(`provider model list: \`data\` is not an array (${url})`);
|
|
15965
|
+
const out = [];
|
|
15966
|
+
for (const item of data) {
|
|
15967
|
+
const e = asRecord2(item);
|
|
15968
|
+
if (!e || typeof e.id !== "string" || !e.id) continue;
|
|
15969
|
+
out.push({ id: e.id, ...typeof e.owned_by === "string" ? { ownedBy: e.owned_by } : {} });
|
|
15970
|
+
}
|
|
15971
|
+
return out;
|
|
15972
|
+
} catch (err) {
|
|
15973
|
+
if (deps.throwOnFailure) throw err;
|
|
15974
|
+
deps.logger?.warn?.(`provider model list failed: ${err.message}`);
|
|
15975
|
+
return [];
|
|
15976
|
+
} finally {
|
|
15977
|
+
clearTimeout(timer);
|
|
15978
|
+
}
|
|
15979
|
+
}
|
|
15980
|
+
var import_node_child_process2, import_node_fs21, import_node_os10, import_node_path21, import_node_util, PROVIDER_FETCH_TIMEOUT_MS, defaultExecFile, AUTH_COMMAND_TIMEOUT_MS;
|
|
15981
|
+
var init_codex_provider_models = __esm({
|
|
15982
|
+
"src/tools/codex-provider-models.ts"() {
|
|
15983
|
+
"use strict";
|
|
15984
|
+
import_node_child_process2 = require("child_process");
|
|
15985
|
+
import_node_fs21 = __toESM(require("fs"), 1);
|
|
15986
|
+
import_node_os10 = __toESM(require("os"), 1);
|
|
15987
|
+
import_node_path21 = __toESM(require("path"), 1);
|
|
15988
|
+
import_node_util = require("util");
|
|
15989
|
+
PROVIDER_FETCH_TIMEOUT_MS = 3e3;
|
|
15990
|
+
defaultExecFile = (0, import_node_util.promisify)(import_node_child_process2.execFile);
|
|
15991
|
+
AUTH_COMMAND_TIMEOUT_MS = 5e3;
|
|
15992
|
+
}
|
|
15993
|
+
});
|
|
15994
|
+
|
|
15995
|
+
// src/tools/codex-config-toml.ts
|
|
15996
|
+
function parseKey(src, start) {
|
|
15997
|
+
const parts = [];
|
|
15998
|
+
let i2 = start;
|
|
15999
|
+
for (; ; ) {
|
|
16000
|
+
while (src[i2] === " " || src[i2] === " ") i2++;
|
|
16001
|
+
let part;
|
|
16002
|
+
if (src[i2] === '"') {
|
|
16003
|
+
let j2 = i2 + 1;
|
|
16004
|
+
while (j2 < src.length && src[j2] !== '"') j2 += src[j2] === "\\" ? 2 : 1;
|
|
16005
|
+
if (j2 >= src.length) return null;
|
|
16006
|
+
try {
|
|
16007
|
+
part = JSON.parse(src.slice(i2, j2 + 1));
|
|
16008
|
+
} catch {
|
|
16009
|
+
part = src.slice(i2 + 1, j2);
|
|
16010
|
+
}
|
|
16011
|
+
i2 = j2 + 1;
|
|
16012
|
+
} else if (src[i2] === "'") {
|
|
16013
|
+
const j2 = src.indexOf("'", i2 + 1);
|
|
16014
|
+
if (j2 < 0) return null;
|
|
16015
|
+
part = src.slice(i2 + 1, j2);
|
|
16016
|
+
i2 = j2 + 1;
|
|
16017
|
+
} else {
|
|
16018
|
+
const bare = /^[A-Za-z0-9_-]+/.exec(src.slice(i2));
|
|
16019
|
+
if (!bare) return null;
|
|
16020
|
+
part = bare[0];
|
|
16021
|
+
i2 += part.length;
|
|
16022
|
+
}
|
|
16023
|
+
parts.push(part);
|
|
16024
|
+
while (src[i2] === " " || src[i2] === " ") i2++;
|
|
16025
|
+
if (src[i2] !== ".") return { parts, end: i2 };
|
|
16026
|
+
i2++;
|
|
16027
|
+
}
|
|
16028
|
+
}
|
|
16029
|
+
function tableHeader(line) {
|
|
16030
|
+
const open = /^\s*(\[\[?)/.exec(line);
|
|
16031
|
+
if (!open) return null;
|
|
16032
|
+
const key = parseKey(line, open[0].length);
|
|
16033
|
+
if (!key) return null;
|
|
16034
|
+
const close = open[1] === "[[" ? "]]" : "]";
|
|
16035
|
+
if (!line.startsWith(close, key.end)) return null;
|
|
16036
|
+
return /^\s*(?:#.*)?$/.test(line.slice(key.end + close.length)) ? key.parts : null;
|
|
16037
|
+
}
|
|
16038
|
+
function keyLine(line) {
|
|
16039
|
+
const lead = /^\s*/.exec(line)[0].length;
|
|
16040
|
+
if (line[lead] === "[" || line[lead] === "#") return null;
|
|
16041
|
+
const key = parseKey(line, lead);
|
|
16042
|
+
return key && line[key.end] === "=" ? { parts: key.parts, valueStart: key.end + 1 } : null;
|
|
16043
|
+
}
|
|
16044
|
+
function scanValue(s2, start, st2) {
|
|
16045
|
+
let i2 = start;
|
|
16046
|
+
while (i2 < s2.length) {
|
|
16047
|
+
if (st2.ml) {
|
|
16048
|
+
if (st2.ml === '"""' && s2[i2] === "\\") {
|
|
16049
|
+
i2 += 2;
|
|
16050
|
+
continue;
|
|
16051
|
+
}
|
|
16052
|
+
if (s2.startsWith(st2.ml, i2)) {
|
|
16053
|
+
let j2 = i2 + 3;
|
|
16054
|
+
while (j2 < s2.length && j2 < i2 + 5 && s2[j2] === st2.ml[0]) j2++;
|
|
16055
|
+
st2.ml = null;
|
|
16056
|
+
i2 = j2;
|
|
16057
|
+
continue;
|
|
16058
|
+
}
|
|
16059
|
+
i2++;
|
|
16060
|
+
continue;
|
|
16061
|
+
}
|
|
16062
|
+
const c2 = s2[i2];
|
|
16063
|
+
if (c2 === "#") return;
|
|
16064
|
+
if (s2.startsWith('"""', i2) || s2.startsWith("'''", i2)) {
|
|
16065
|
+
st2.ml = s2.slice(i2, i2 + 3);
|
|
16066
|
+
i2 += 3;
|
|
16067
|
+
continue;
|
|
16068
|
+
}
|
|
16069
|
+
if (c2 === '"') {
|
|
16070
|
+
i2++;
|
|
16071
|
+
while (i2 < s2.length && s2[i2] !== '"') i2 += s2[i2] === "\\" ? 2 : 1;
|
|
16072
|
+
i2++;
|
|
16073
|
+
continue;
|
|
16074
|
+
}
|
|
16075
|
+
if (c2 === "'") {
|
|
16076
|
+
const j2 = s2.indexOf("'", i2 + 1);
|
|
16077
|
+
i2 = j2 < 0 ? s2.length : j2 + 1;
|
|
16078
|
+
continue;
|
|
16079
|
+
}
|
|
16080
|
+
if (c2 === "[" || c2 === "{") st2.depth++;
|
|
16081
|
+
else if ((c2 === "]" || c2 === "}") && st2.depth > 0) st2.depth--;
|
|
16082
|
+
i2++;
|
|
16083
|
+
}
|
|
16084
|
+
}
|
|
16085
|
+
function scanToml(text) {
|
|
16086
|
+
const out = [];
|
|
16087
|
+
const st2 = { ml: null, depth: 0 };
|
|
16088
|
+
let table = [];
|
|
16089
|
+
for (const line of text.split("\n")) {
|
|
16090
|
+
if (st2.ml || st2.depth > 0) {
|
|
16091
|
+
scanValue(line, 0, st2);
|
|
16092
|
+
out.push({ text: line, kind: "continuation", table });
|
|
16093
|
+
continue;
|
|
16094
|
+
}
|
|
16095
|
+
const header = tableHeader(line);
|
|
16096
|
+
if (header) {
|
|
16097
|
+
table = header;
|
|
16098
|
+
out.push({ text: line, kind: "header", table, key: header });
|
|
16099
|
+
continue;
|
|
16100
|
+
}
|
|
16101
|
+
const key = keyLine(line);
|
|
16102
|
+
if (key) {
|
|
16103
|
+
scanValue(line, key.valueStart, st2);
|
|
16104
|
+
out.push({ text: line, kind: "key", table, key: key.parts, value: line.slice(key.valueStart) });
|
|
16105
|
+
continue;
|
|
16106
|
+
}
|
|
16107
|
+
out.push({ text: line, kind: "other", table });
|
|
16108
|
+
}
|
|
16109
|
+
return out;
|
|
16110
|
+
}
|
|
16111
|
+
function parseTomlValue(raw) {
|
|
16112
|
+
const parsed = parseValueAt(raw, 0);
|
|
16113
|
+
if (!parsed) return void 0;
|
|
16114
|
+
return /^\s*(?:#[^\n]*)?\s*$/.test(raw.slice(parsed.end)) ? parsed.value : void 0;
|
|
16115
|
+
}
|
|
16116
|
+
function skipSeparators(s2, start) {
|
|
16117
|
+
let i2 = start;
|
|
16118
|
+
for (; ; ) {
|
|
16119
|
+
while (i2 < s2.length && " \r\n,".includes(s2[i2])) i2++;
|
|
16120
|
+
if (s2[i2] !== "#") return i2;
|
|
16121
|
+
const newline = s2.indexOf("\n", i2);
|
|
16122
|
+
i2 = newline < 0 ? s2.length : newline;
|
|
16123
|
+
}
|
|
16124
|
+
}
|
|
16125
|
+
function parseValueAt(s2, start) {
|
|
16126
|
+
let i2 = start;
|
|
16127
|
+
while (s2[i2] === " " || s2[i2] === " ") i2++;
|
|
16128
|
+
const c2 = s2[i2];
|
|
16129
|
+
if (c2 === '"') {
|
|
16130
|
+
if (s2.startsWith('"""', i2)) return null;
|
|
16131
|
+
let j2 = i2 + 1;
|
|
16132
|
+
while (j2 < s2.length && s2[j2] !== '"') j2 += s2[j2] === "\\" ? 2 : 1;
|
|
16133
|
+
if (j2 >= s2.length) return null;
|
|
16134
|
+
try {
|
|
16135
|
+
return { value: JSON.parse(s2.slice(i2, j2 + 1)), end: j2 + 1 };
|
|
16136
|
+
} catch {
|
|
16137
|
+
return null;
|
|
16138
|
+
}
|
|
16139
|
+
}
|
|
16140
|
+
if (c2 === "'") {
|
|
16141
|
+
if (s2.startsWith("'''", i2)) return null;
|
|
16142
|
+
const j2 = s2.indexOf("'", i2 + 1);
|
|
16143
|
+
return j2 < 0 ? null : { value: s2.slice(i2 + 1, j2), end: j2 + 1 };
|
|
16144
|
+
}
|
|
16145
|
+
if (c2 === "[") {
|
|
16146
|
+
const items = [];
|
|
16147
|
+
i2++;
|
|
16148
|
+
for (; ; ) {
|
|
16149
|
+
i2 = skipSeparators(s2, i2);
|
|
16150
|
+
if (s2[i2] === "]") return { value: items, end: i2 + 1 };
|
|
16151
|
+
const item = parseValueAt(s2, i2);
|
|
16152
|
+
if (!item) return null;
|
|
16153
|
+
items.push(item.value);
|
|
16154
|
+
i2 = item.end;
|
|
16155
|
+
}
|
|
16156
|
+
}
|
|
16157
|
+
if (c2 === "{") {
|
|
16158
|
+
const table = {};
|
|
16159
|
+
i2++;
|
|
16160
|
+
for (; ; ) {
|
|
16161
|
+
i2 = skipSeparators(s2, i2);
|
|
16162
|
+
if (s2[i2] === "}") return { value: table, end: i2 + 1 };
|
|
16163
|
+
const key = parseKey(s2, i2);
|
|
16164
|
+
if (!key || s2[key.end] !== "=") return null;
|
|
16165
|
+
const item = parseValueAt(s2, key.end + 1);
|
|
16166
|
+
if (!item) return null;
|
|
16167
|
+
setPath(table, key.parts, item.value);
|
|
16168
|
+
i2 = item.end;
|
|
16169
|
+
}
|
|
16170
|
+
}
|
|
16171
|
+
const bare = /^[^\s,\]}#]+/.exec(s2.slice(i2));
|
|
16172
|
+
return bare ? { value: bare[0], end: i2 + bare[0].length } : null;
|
|
16173
|
+
}
|
|
16174
|
+
function setPath(target, path110, value) {
|
|
16175
|
+
let node = target;
|
|
16176
|
+
for (const part of path110.slice(0, -1)) {
|
|
16177
|
+
const next = node[part];
|
|
16178
|
+
if (!next || typeof next !== "object" || Array.isArray(next)) node[part] = {};
|
|
16179
|
+
node = node[part];
|
|
16180
|
+
}
|
|
16181
|
+
const last = path110[path110.length - 1];
|
|
16182
|
+
const existing = node[last];
|
|
16183
|
+
if (existing && typeof existing === "object" && !Array.isArray(existing) && value && typeof value === "object" && !Array.isArray(value)) {
|
|
16184
|
+
Object.assign(existing, value);
|
|
16185
|
+
} else node[last] = value;
|
|
16186
|
+
}
|
|
16187
|
+
function readTomlTable(text, path110) {
|
|
16188
|
+
const result = {};
|
|
16189
|
+
let found = false;
|
|
16190
|
+
const within = (full) => full.length >= path110.length && path110.every((part, i2) => full[i2] === part);
|
|
16191
|
+
const lines = scanToml(text);
|
|
16192
|
+
for (let index = 0; index < lines.length; index++) {
|
|
16193
|
+
const line = lines[index];
|
|
16194
|
+
if (line.kind === "header" && within(line.key)) {
|
|
16195
|
+
found = true;
|
|
16196
|
+
if (line.key.length > path110.length) setPath(result, line.key.slice(path110.length), {});
|
|
16197
|
+
continue;
|
|
16198
|
+
}
|
|
16199
|
+
if (line.kind !== "key") continue;
|
|
16200
|
+
const full = [...line.table, ...line.key];
|
|
16201
|
+
if (!within(full)) continue;
|
|
16202
|
+
let raw = line.value;
|
|
16203
|
+
while (lines[index + 1]?.kind === "continuation") raw += `
|
|
16204
|
+
${lines[++index].text}`;
|
|
16205
|
+
const parsed = parseTomlValue(raw);
|
|
16206
|
+
const value = parsed === void 0 ? UNREADABLE : parsed;
|
|
16207
|
+
found = true;
|
|
16208
|
+
if (full.length === path110.length) {
|
|
16209
|
+
if (value && typeof value === "object" && !Array.isArray(value)) Object.assign(result, value);
|
|
16210
|
+
} else setPath(result, full.slice(path110.length), value);
|
|
16211
|
+
}
|
|
16212
|
+
return found ? result : null;
|
|
16213
|
+
}
|
|
16214
|
+
var UNREADABLE;
|
|
16215
|
+
var init_codex_config_toml = __esm({
|
|
16216
|
+
"src/tools/codex-config-toml.ts"() {
|
|
16217
|
+
"use strict";
|
|
16218
|
+
UNREADABLE = /* @__PURE__ */ Symbol("unreadable TOML value");
|
|
16219
|
+
}
|
|
16220
|
+
});
|
|
16221
|
+
|
|
16222
|
+
// src/tools/subscription-channels-apply.ts
|
|
16223
|
+
function stripCodexProvider(text) {
|
|
16224
|
+
const out = [];
|
|
16225
|
+
let dropping = false;
|
|
16226
|
+
let droppingValue = false;
|
|
16227
|
+
for (const line of scanToml(text)) {
|
|
16228
|
+
if (line.kind === "header") {
|
|
16229
|
+
dropping = isOwnProvider(line.key);
|
|
16230
|
+
droppingValue = false;
|
|
16231
|
+
if (!dropping) out.push(line.text);
|
|
16232
|
+
continue;
|
|
16233
|
+
}
|
|
16234
|
+
if (line.kind === "continuation") {
|
|
16235
|
+
if (!dropping && !droppingValue) out.push(line.text);
|
|
16236
|
+
continue;
|
|
16237
|
+
}
|
|
16238
|
+
if (dropping) continue;
|
|
16239
|
+
if (line.kind === "key") {
|
|
16240
|
+
const full = [...line.table, ...line.key];
|
|
16241
|
+
droppingValue = full.length === 1 && full[0] === "model_provider" || isOwnProvider(full);
|
|
16242
|
+
if (!droppingValue) out.push(line.text);
|
|
16243
|
+
continue;
|
|
16244
|
+
}
|
|
16245
|
+
out.push(line.text);
|
|
16246
|
+
}
|
|
16247
|
+
return out.join("\n").trim();
|
|
16248
|
+
}
|
|
16249
|
+
function writeFileAtomic(file, data) {
|
|
16250
|
+
const target = import_node_fs22.default.existsSync(file) && import_node_fs22.default.lstatSync(file).isSymbolicLink() ? import_node_fs22.default.realpathSync(file) : file;
|
|
16251
|
+
const tmp = `${target}.tmp.${process.pid}.${Date.now()}`;
|
|
16252
|
+
import_node_fs22.default.writeFileSync(tmp, data, { mode: 384 });
|
|
16253
|
+
import_node_fs22.default.renameSync(tmp, target);
|
|
16254
|
+
}
|
|
16255
|
+
function snapshotFile(file) {
|
|
16256
|
+
const original = import_node_fs22.default.existsSync(file) ? import_node_fs22.default.readFileSync(file) : null;
|
|
16257
|
+
return () => {
|
|
16258
|
+
const current = import_node_fs22.default.existsSync(file) ? import_node_fs22.default.readFileSync(file) : null;
|
|
16259
|
+
if (original === null) {
|
|
16260
|
+
if (current !== null) import_node_fs22.default.rmSync(file, { force: true });
|
|
16261
|
+
return;
|
|
16262
|
+
}
|
|
16263
|
+
if (current !== null && current.equals(original)) return;
|
|
16264
|
+
writeFileAtomic(file, original);
|
|
16265
|
+
};
|
|
16266
|
+
}
|
|
16267
|
+
function applyCodexSubscriptionChannel(opts) {
|
|
16268
|
+
const codexHome = resolveCodexHome2(opts.codexHome);
|
|
16269
|
+
import_node_fs22.default.mkdirSync(codexHome, { recursive: true });
|
|
16270
|
+
const configFile = import_node_path22.default.join(codexHome, "config.toml");
|
|
16271
|
+
const original = import_node_fs22.default.existsSync(configFile) ? import_node_fs22.default.readFileSync(configFile, "utf8") : "";
|
|
16272
|
+
const rest = stripCodexProvider(original);
|
|
16273
|
+
let content;
|
|
16274
|
+
if (opts.channel) {
|
|
16275
|
+
const ch = opts.channel;
|
|
16276
|
+
content = [
|
|
16277
|
+
`model_provider = "${PROVIDER_ID}"`,
|
|
16278
|
+
...rest ? ["", rest] : [],
|
|
16279
|
+
"",
|
|
16280
|
+
`[model_providers.${PROVIDER_ID}]`,
|
|
16281
|
+
`name = "${PROVIDER_ID}"`,
|
|
16282
|
+
`base_url = ${JSON.stringify(ch.baseUrl)}`,
|
|
16283
|
+
'wire_api = "responses"',
|
|
16284
|
+
`auth = { command = "echo", args = [${JSON.stringify(ch.apiKey)}] }`,
|
|
16285
|
+
""
|
|
16286
|
+
].join("\n");
|
|
16287
|
+
} else {
|
|
16288
|
+
content = [
|
|
16289
|
+
'model_provider = "openai"',
|
|
16290
|
+
...rest ? ["", rest] : [],
|
|
16291
|
+
""
|
|
16292
|
+
].join("\n");
|
|
16293
|
+
}
|
|
16294
|
+
writeFileAtomic(configFile, content);
|
|
16295
|
+
}
|
|
16296
|
+
function applyPiSubscriptionChannel(opts) {
|
|
16297
|
+
const agentDir = resolvePiAgentDir(opts.agentDir);
|
|
16298
|
+
if (!import_node_fs22.default.existsSync(agentDir)) return false;
|
|
16299
|
+
const configFile = import_node_path22.default.join(agentDir, PI_SUBSCRIPTION_FILE);
|
|
16300
|
+
if (opts.channel) {
|
|
16301
|
+
const data = { baseUrl: opts.channel.baseUrl, apiKey: opts.channel.apiKey };
|
|
16302
|
+
writeFileAtomic(configFile, JSON.stringify(data, null, 2) + "\n");
|
|
16303
|
+
return true;
|
|
16304
|
+
}
|
|
16305
|
+
return false;
|
|
16306
|
+
}
|
|
16307
|
+
function claudeSubscriptionEnv(channel) {
|
|
16308
|
+
return {
|
|
16309
|
+
ANTHROPIC_BASE_URL: channel.baseUrl.replace(/\/+$/, "").replace(/\/v1$/, ""),
|
|
16310
|
+
ANTHROPIC_AUTH_TOKEN: channel.apiKey,
|
|
16311
|
+
ANTHROPIC_API_KEY: "",
|
|
16312
|
+
CLAUDE_CODE_USE_BEDROCK: "0",
|
|
16313
|
+
CLAUDE_CODE_USE_VERTEX: "0",
|
|
16314
|
+
CLAUDE_CODE_USE_FOUNDRY: "0"
|
|
16315
|
+
};
|
|
16316
|
+
}
|
|
16317
|
+
function readSettings(file) {
|
|
16318
|
+
if (!import_node_fs22.default.existsSync(file)) return {};
|
|
16319
|
+
const value = JSON.parse(import_node_fs22.default.readFileSync(file, "utf8"));
|
|
16320
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("Claude settings must be a JSON object");
|
|
16321
|
+
return value;
|
|
16322
|
+
}
|
|
16323
|
+
function applyClaudeSubscriptionChannel(opts) {
|
|
16324
|
+
const dir = resolveClaudeConfigDir(opts.configDir);
|
|
16325
|
+
const file = import_node_path22.default.join(dir, "settings.json");
|
|
16326
|
+
const backupFile = import_node_path22.default.join(dir, CLAUDE_SUBSCRIPTION_BACKUP);
|
|
16327
|
+
if (!opts.channel && !import_node_fs22.default.existsSync(backupFile)) return;
|
|
16328
|
+
const settings = readSettings(file);
|
|
16329
|
+
if (settings.env !== void 0 && (!settings.env || typeof settings.env !== "object" || Array.isArray(settings.env))) {
|
|
16330
|
+
throw new Error("Claude settings.env must be a JSON object");
|
|
16331
|
+
}
|
|
16332
|
+
const env = { ...settings.env };
|
|
16333
|
+
if (opts.channel) {
|
|
16334
|
+
const connection = claudeSubscriptionEnv(opts.channel);
|
|
16335
|
+
import_node_fs22.default.mkdirSync(dir, { recursive: true });
|
|
16336
|
+
if (!import_node_fs22.default.existsSync(backupFile)) {
|
|
16337
|
+
writeFileAtomic(backupFile, JSON.stringify({
|
|
16338
|
+
hadSettings: import_node_fs22.default.existsSync(file),
|
|
16339
|
+
hadEnv: settings.env !== void 0,
|
|
16340
|
+
env: Object.fromEntries(Object.keys(connection).filter((key) => key in env).map((key) => [key, env[key]]))
|
|
16341
|
+
}) + "\n");
|
|
16342
|
+
}
|
|
16343
|
+
settings.env = { ...env, ...connection };
|
|
16344
|
+
writeFileAtomic(file, JSON.stringify(settings, null, 2) + "\n");
|
|
16345
|
+
return;
|
|
16346
|
+
}
|
|
16347
|
+
const backup = readSettings(backupFile);
|
|
16348
|
+
if (typeof backup.hadSettings !== "boolean" || typeof backup.hadEnv !== "boolean" || !backup.env || typeof backup.env !== "object" || Array.isArray(backup.env)) {
|
|
16349
|
+
throw new Error("Claude subscription backup is invalid; native configuration was not changed");
|
|
16350
|
+
}
|
|
16351
|
+
for (const key of CLAUDE_CONNECTION_KEYS) delete env[key];
|
|
16352
|
+
Object.assign(env, backup.env);
|
|
16353
|
+
if (Object.keys(env).length || backup.hadEnv) settings.env = env;
|
|
16354
|
+
else delete settings.env;
|
|
16355
|
+
if (!backup.hadSettings && !Object.keys(settings).length) import_node_fs22.default.rmSync(file, { force: true });
|
|
16356
|
+
else writeFileAtomic(file, JSON.stringify(settings, null, 2) + "\n");
|
|
16357
|
+
import_node_fs22.default.unlinkSync(backupFile);
|
|
16358
|
+
}
|
|
16359
|
+
var import_node_fs22, import_node_os11, import_node_path22, PROVIDER_ID, isOwnProvider, resolveCodexHome2, resolvePiAgentDir, PI_SUBSCRIPTION_FILE, resolveClaudeConfigDir, CLAUDE_SUBSCRIPTION_BACKUP, CLAUDE_CONNECTION_KEYS;
|
|
16360
|
+
var init_subscription_channels_apply = __esm({
|
|
16361
|
+
"src/tools/subscription-channels-apply.ts"() {
|
|
16362
|
+
"use strict";
|
|
16363
|
+
import_node_fs22 = __toESM(require("fs"), 1);
|
|
16364
|
+
import_node_os11 = __toESM(require("os"), 1);
|
|
16365
|
+
import_node_path22 = __toESM(require("path"), 1);
|
|
16366
|
+
init_codex_config_toml();
|
|
16367
|
+
PROVIDER_ID = "cliproxyapi";
|
|
16368
|
+
isOwnProvider = (path110) => path110[0] === "model_providers" && path110[1] === PROVIDER_ID;
|
|
16369
|
+
resolveCodexHome2 = (codexHome) => codexHome || process.env.CODEX_HOME || import_node_path22.default.join(import_node_os11.default.homedir(), ".codex");
|
|
16370
|
+
resolvePiAgentDir = (agentDir) => agentDir || process.env.PI_CODING_AGENT_DIR || import_node_path22.default.join(import_node_os11.default.homedir(), ".pi", "agent");
|
|
16371
|
+
PI_SUBSCRIPTION_FILE = "cliproxyapi.json";
|
|
16372
|
+
resolveClaudeConfigDir = (configDir) => configDir || process.env.CLAUDE_CONFIG_DIR || import_node_path22.default.join(import_node_os11.default.homedir(), ".claude");
|
|
16373
|
+
CLAUDE_SUBSCRIPTION_BACKUP = "clawd-subscription-backup.json";
|
|
16374
|
+
CLAUDE_CONNECTION_KEYS = ["ANTHROPIC_BASE_URL", "ANTHROPIC_AUTH_TOKEN", "ANTHROPIC_API_KEY", "CLAUDE_CODE_USE_BEDROCK", "CLAUDE_CODE_USE_VERTEX", "CLAUDE_CODE_USE_FOUNDRY"];
|
|
16375
|
+
}
|
|
16376
|
+
});
|
|
16377
|
+
|
|
15879
16378
|
// src/tools/claude.ts
|
|
15880
16379
|
function probeViaWhich() {
|
|
15881
16380
|
try {
|
|
15882
|
-
const out = (0,
|
|
15883
|
-
if (out &&
|
|
16381
|
+
const out = (0, import_node_child_process4.execFileSync)("which", ["claude"], { encoding: "utf8" }).trim();
|
|
16382
|
+
if (out && import_node_fs23.default.existsSync(out)) return out;
|
|
15884
16383
|
} catch {
|
|
15885
16384
|
}
|
|
15886
16385
|
return null;
|
|
15887
16386
|
}
|
|
15888
16387
|
async function probeClaude(env = process.env) {
|
|
15889
|
-
if (env.CLAUDE_BIN &&
|
|
16388
|
+
if (env.CLAUDE_BIN && import_node_fs23.default.existsSync(env.CLAUDE_BIN)) {
|
|
15890
16389
|
return { available: true, path: env.CLAUDE_BIN };
|
|
15891
16390
|
}
|
|
15892
16391
|
const w3 = probeViaWhich();
|
|
@@ -16366,14 +16865,16 @@ function resolveClaudeContextWindow(modelId) {
|
|
|
16366
16865
|
if (/\[1m\]/i.test(modelId)) return 1e6;
|
|
16367
16866
|
return void 0;
|
|
16368
16867
|
}
|
|
16369
|
-
var
|
|
16868
|
+
var import_node_child_process3, import_node_child_process4, import_node_fs23, ATTACHMENT_SILENT_SUBTYPES2, unknownTypeHandler, ATTACHMENT_RE, IMAGE_EXT_MIME, CLAUDE_MODEL_IDS, CLAUDE_MODELS, _assertModelIdsAligned, CLAUDE_PERMISSION_MODES, CLAUDE_CAPABILITIES, ClaudeAdapter;
|
|
16370
16869
|
var init_claude = __esm({
|
|
16371
16870
|
"src/tools/claude.ts"() {
|
|
16372
16871
|
"use strict";
|
|
16373
|
-
import_node_child_process2 = require("child_process");
|
|
16374
16872
|
import_node_child_process3 = require("child_process");
|
|
16375
|
-
|
|
16873
|
+
import_node_child_process4 = require("child_process");
|
|
16874
|
+
import_node_fs23 = __toESM(require("fs"), 1);
|
|
16376
16875
|
init_protocol();
|
|
16876
|
+
init_codex_provider_models();
|
|
16877
|
+
init_subscription_channels_apply();
|
|
16377
16878
|
init_claude_history();
|
|
16378
16879
|
init_tool_result_extra();
|
|
16379
16880
|
ATTACHMENT_SILENT_SUBTYPES2 = /* @__PURE__ */ new Set([
|
|
@@ -16454,7 +16955,11 @@ var init_claude = __esm({
|
|
|
16454
16955
|
logger;
|
|
16455
16956
|
historyReader;
|
|
16456
16957
|
probeOverride;
|
|
16958
|
+
getSubscriptionChannel;
|
|
16959
|
+
fetchImpl;
|
|
16457
16960
|
constructor(opts = {}) {
|
|
16961
|
+
this.getSubscriptionChannel = opts.getSubscriptionChannel;
|
|
16962
|
+
this.fetchImpl = opts.fetchImpl;
|
|
16458
16963
|
this.logger = opts.logger;
|
|
16459
16964
|
this.historyReader = opts.historyReader;
|
|
16460
16965
|
this.probeOverride = opts.probeOverride;
|
|
@@ -16477,8 +16982,38 @@ var init_claude = __esm({
|
|
|
16477
16982
|
appendTurnDurationRow(args) {
|
|
16478
16983
|
appendTurnDurationRowToJsonl(args);
|
|
16479
16984
|
}
|
|
16480
|
-
async capabilities() {
|
|
16481
|
-
|
|
16985
|
+
async capabilities(opts) {
|
|
16986
|
+
const channel = this.getSubscriptionChannel?.();
|
|
16987
|
+
if (!channel) return CLAUDE_CAPABILITIES;
|
|
16988
|
+
const provider = await fetchProviderModels(
|
|
16989
|
+
{ baseUrl: channel.baseUrl, headers: { Accept: "application/json", Authorization: "Bearer " + channel.apiKey } },
|
|
16990
|
+
{ fetchImpl: this.fetchImpl, logger: this.logger, throwOnFailure: opts?.refresh }
|
|
16991
|
+
);
|
|
16992
|
+
const known = /* @__PURE__ */ new Set();
|
|
16993
|
+
const merged = [];
|
|
16994
|
+
for (const model of provider) {
|
|
16995
|
+
if (known.has(model.id)) continue;
|
|
16996
|
+
known.add(model.id);
|
|
16997
|
+
const native = CLAUDE_MODELS.find((entry) => entry.id === model.id);
|
|
16998
|
+
merged.push(native ?? { id: model.id, label: model.id, contextWindowSize: resolveClaudeContextWindow(model.id) ?? 2e5 });
|
|
16999
|
+
}
|
|
17000
|
+
merged.sort((a2, b3) => a2.id.localeCompare(b3.id));
|
|
17001
|
+
return {
|
|
17002
|
+
...CLAUDE_CAPABILITIES,
|
|
17003
|
+
models: merged,
|
|
17004
|
+
configSchema: CLAUDE_CAPABILITIES.configSchema.map((field) => field.name === "model" ? { ...field, default: merged[0]?.id ?? "", options: merged.map((m3) => ({ value: m3.id, label: m3.label, description: m3.description })) } : field)
|
|
17005
|
+
};
|
|
17006
|
+
}
|
|
17007
|
+
/** Global settings serve terminal CLI; inject the same connection for guest sessions that exclude user settings. */
|
|
17008
|
+
spawnEnv(ctx) {
|
|
17009
|
+
const channel = this.getSubscriptionChannel?.();
|
|
17010
|
+
if (!channel) return buildSpawnEnv(ctx.env);
|
|
17011
|
+
const env = { ...ctx.env, ...claudeSubscriptionEnv(channel) };
|
|
17012
|
+
if (ctx.model && !CLAUDE_MODEL_IDS.includes(ctx.model)) {
|
|
17013
|
+
for (const alias of CLAUDE_MODEL_IDS) env["ANTHROPIC_DEFAULT_" + alias.toUpperCase() + "_MODEL"] = ctx.model;
|
|
17014
|
+
env.CLAUDE_CODE_SUBAGENT_MODEL = ctx.model;
|
|
17015
|
+
}
|
|
17016
|
+
return buildSpawnEnv(env);
|
|
16482
17017
|
}
|
|
16483
17018
|
resolveContextWindow(modelId) {
|
|
16484
17019
|
return resolveClaudeContextWindow(modelId);
|
|
@@ -16486,9 +17021,9 @@ var init_claude = __esm({
|
|
|
16486
17021
|
spawn(ctx) {
|
|
16487
17022
|
const args = buildSpawnArgs(ctx);
|
|
16488
17023
|
const cmd = process.env.CLAUDE_BIN ?? "claude";
|
|
16489
|
-
const child = (0,
|
|
17024
|
+
const child = (0, import_node_child_process3.spawn)(cmd, args, {
|
|
16490
17025
|
cwd: ctx.cwd,
|
|
16491
|
-
env:
|
|
17026
|
+
env: this.spawnEnv(ctx),
|
|
16492
17027
|
stdio: ["pipe", "pipe", "pipe"]
|
|
16493
17028
|
});
|
|
16494
17029
|
this.logger?.info("claude spawn", { cmd, args, cwd: ctx.cwd });
|
|
@@ -49138,9 +49673,8 @@ var SessionManager = class {
|
|
|
49138
49673
|
const adapter = this.deps.getAdapter(tool);
|
|
49139
49674
|
const revision = this.capabilitiesRevision.get(tool);
|
|
49140
49675
|
const caps = await adapter.capabilities(opts);
|
|
49141
|
-
if (revision
|
|
49142
|
-
|
|
49143
|
-
}
|
|
49676
|
+
if (revision !== this.capabilitiesRevision.get(tool)) return this.getCapabilities(tool, opts);
|
|
49677
|
+
this.capabilitiesCache.set(tool, { caps, loadedAt: Date.now() });
|
|
49144
49678
|
return caps;
|
|
49145
49679
|
}
|
|
49146
49680
|
invalidateCapabilities(tool) {
|
|
@@ -53273,8 +53807,8 @@ function createVisitorStore(opts) {
|
|
|
53273
53807
|
init_claude();
|
|
53274
53808
|
|
|
53275
53809
|
// src/tools/codex-session.ts
|
|
53276
|
-
var
|
|
53277
|
-
var
|
|
53810
|
+
var import_node_child_process6 = require("child_process");
|
|
53811
|
+
var import_node_path26 = __toESM(require("path"), 1);
|
|
53278
53812
|
|
|
53279
53813
|
// src/tools/codex-app-server-events.ts
|
|
53280
53814
|
function translateNotification(method, params) {
|
|
@@ -53897,17 +54431,17 @@ function stringValue2(value) {
|
|
|
53897
54431
|
}
|
|
53898
54432
|
|
|
53899
54433
|
// src/tools/mcp-server-defs.ts
|
|
53900
|
-
var
|
|
53901
|
-
var
|
|
54434
|
+
var import_node_fs24 = __toESM(require("fs"), 1);
|
|
54435
|
+
var import_node_path23 = __toESM(require("path"), 1);
|
|
53902
54436
|
var HTTP_TYPES = /* @__PURE__ */ new Set(["http", "sse", "streamable_http", "streamable-http"]);
|
|
53903
54437
|
function loadMcpServerDefs(args) {
|
|
53904
54438
|
const out = [];
|
|
53905
54439
|
const seen = /* @__PURE__ */ new Set();
|
|
53906
|
-
const sources = [...args.mcpConfigPaths,
|
|
54440
|
+
const sources = [...args.mcpConfigPaths, import_node_path23.default.join(args.cwd, ".mcp.json")];
|
|
53907
54441
|
for (const file of sources) {
|
|
53908
54442
|
let parsed;
|
|
53909
54443
|
try {
|
|
53910
|
-
parsed = JSON.parse(
|
|
54444
|
+
parsed = JSON.parse(import_node_fs24.default.readFileSync(file, "utf8"));
|
|
53911
54445
|
} catch (e) {
|
|
53912
54446
|
const code = e.code;
|
|
53913
54447
|
if (code !== "ENOENT") {
|
|
@@ -53971,18 +54505,18 @@ function loadMcpServerDefs(args) {
|
|
|
53971
54505
|
}
|
|
53972
54506
|
|
|
53973
54507
|
// src/tools/codex-agents-config.ts
|
|
53974
|
-
var
|
|
53975
|
-
var
|
|
54508
|
+
var import_node_fs25 = __toESM(require("fs"), 1);
|
|
54509
|
+
var import_node_path24 = __toESM(require("path"), 1);
|
|
53976
54510
|
var AGENTS_SECTION = /^\[agents\][^\n]*\n([\s\S]*?)(?=^\[|$(?![\s\S]))/m;
|
|
53977
54511
|
function readKey(section, key) {
|
|
53978
54512
|
const m3 = new RegExp(`^[ \\t]*${key}[ \\t]*=[ \\t]*(["'])(.*?)\\1`, "m").exec(section);
|
|
53979
54513
|
return m3?.[2].trim() || void 0;
|
|
53980
54514
|
}
|
|
53981
54515
|
function loadCodexAgentsConfig(args) {
|
|
53982
|
-
const file =
|
|
54516
|
+
const file = import_node_path24.default.join(args.cwd, ".codex", "config.toml");
|
|
53983
54517
|
let text;
|
|
53984
54518
|
try {
|
|
53985
|
-
text =
|
|
54519
|
+
text = import_node_fs25.default.readFileSync(file, "utf8");
|
|
53986
54520
|
} catch (e) {
|
|
53987
54521
|
const code = e.code;
|
|
53988
54522
|
if (code !== "ENOENT") {
|
|
@@ -54000,13 +54534,13 @@ function loadCodexAgentsConfig(args) {
|
|
|
54000
54534
|
}
|
|
54001
54535
|
|
|
54002
54536
|
// src/tools/codex-features.ts
|
|
54003
|
-
var
|
|
54537
|
+
var import_node_child_process5 = require("child_process");
|
|
54004
54538
|
var cachedNetworkProxy;
|
|
54005
54539
|
function hasNetworkProxyFeature(deps = {}) {
|
|
54006
54540
|
if (cachedNetworkProxy !== void 0) return cachedNetworkProxy;
|
|
54007
54541
|
try {
|
|
54008
54542
|
const cmd = codexCommand();
|
|
54009
|
-
const out = deps.execOverride ? deps.execOverride() : (0,
|
|
54543
|
+
const out = deps.execOverride ? deps.execOverride() : (0, import_node_child_process5.execFileSync)(cmd, ["features", "list"], {
|
|
54010
54544
|
env: codexEnvironment(cmd),
|
|
54011
54545
|
encoding: "utf8",
|
|
54012
54546
|
timeout: 3e3
|
|
@@ -54023,7 +54557,7 @@ function warmCodexFeatureCache() {
|
|
|
54023
54557
|
if (cachedNetworkProxy !== void 0 || warming) return;
|
|
54024
54558
|
warming = true;
|
|
54025
54559
|
const cmd = codexCommand();
|
|
54026
|
-
(0,
|
|
54560
|
+
(0, import_node_child_process5.execFile)(
|
|
54027
54561
|
cmd,
|
|
54028
54562
|
["features", "list"],
|
|
54029
54563
|
{ encoding: "utf8", timeout: 3e3, env: codexEnvironment(cmd) },
|
|
@@ -54041,7 +54575,7 @@ function warmCodexFeatureCache() {
|
|
|
54041
54575
|
}
|
|
54042
54576
|
|
|
54043
54577
|
// src/attachment/mime.ts
|
|
54044
|
-
var
|
|
54578
|
+
var import_node_path25 = __toESM(require("path"), 1);
|
|
54045
54579
|
var TEXT_PLAIN = "text/plain; charset=utf-8";
|
|
54046
54580
|
var EXT_TO_NATIVE_MIME = {
|
|
54047
54581
|
".png": "image/png",
|
|
@@ -54140,7 +54674,7 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
54140
54674
|
".mk"
|
|
54141
54675
|
]);
|
|
54142
54676
|
function lookupMime(filePathOrName) {
|
|
54143
|
-
const ext =
|
|
54677
|
+
const ext = import_node_path25.default.extname(filePathOrName).toLowerCase();
|
|
54144
54678
|
if (EXT_TO_NATIVE_MIME[ext]) return EXT_TO_NATIVE_MIME[ext];
|
|
54145
54679
|
if (TEXT_EXTENSIONS.has(ext)) return TEXT_PLAIN;
|
|
54146
54680
|
return "application/octet-stream";
|
|
@@ -54177,7 +54711,7 @@ function createCodexSession(ctx, sink, deps = {}) {
|
|
|
54177
54711
|
...resolvedCodexHome ? { CODEX_HOME: resolvedCodexHome } : {},
|
|
54178
54712
|
...ctx.env
|
|
54179
54713
|
});
|
|
54180
|
-
const proc = deps.spawnOverride ? deps.spawnOverride(cmd, args, ctx.cwd, env) : (0,
|
|
54714
|
+
const proc = deps.spawnOverride ? deps.spawnOverride(cmd, args, ctx.cwd, env) : (0, import_node_child_process6.spawn)(cmd, args, { cwd: ctx.cwd, env, stdio: ["pipe", "pipe", "pipe"] });
|
|
54181
54715
|
const alive = () => proc.exitCode === null && proc.signalCode === null;
|
|
54182
54716
|
const driver = driveCodexThread({
|
|
54183
54717
|
ctx,
|
|
@@ -54187,7 +54721,7 @@ function createCodexSession(ctx, sink, deps = {}) {
|
|
|
54187
54721
|
threadParams: threadStartParams(ctx),
|
|
54188
54722
|
// persona 惯例装在 <cwd>/.claude/skills/,经 extraRoots 注入 discovery
|
|
54189
54723
|
// (skills:list RPC 侧 codex-skills.ts 同款注入,两处保持一致)。
|
|
54190
|
-
skillsExtraRoots: [
|
|
54724
|
+
skillsExtraRoots: [import_node_path26.default.join(ctx.cwd, ".claude", "skills")],
|
|
54191
54725
|
// 附件图片:验签认出本机 absPath → localImage,codex 自己读文件(TUI 拖图 / SDK local_image 同一条路)。
|
|
54192
54726
|
// 0.145 起 http(s) URL 在 turn/start 入口被拒,不能再按 url 传(codex-app-server-params.ts 头注释)。
|
|
54193
54727
|
// 与云上 cloudImageInput 同一道 mime 门:非图片(签过的 .md 之类)留文本,别让 codex 读到一半才炸。
|
|
@@ -54216,12 +54750,12 @@ function createCodexSession(ctx, sink, deps = {}) {
|
|
|
54216
54750
|
}
|
|
54217
54751
|
|
|
54218
54752
|
// src/tools/codex-app-server-query.ts
|
|
54219
|
-
var
|
|
54753
|
+
var import_node_child_process7 = require("child_process");
|
|
54220
54754
|
var DEFAULT_CODEX_QUERY_TIMEOUT_MS = 8e3;
|
|
54221
54755
|
async function withCodexAppServerClient(cwd, operation, run, deps = {}) {
|
|
54222
54756
|
const cmd = codexCommand();
|
|
54223
54757
|
const args = ["app-server", "--listen", "stdio://"];
|
|
54224
|
-
const proc = deps.spawnOverride ? deps.spawnOverride(cmd, args, cwd) : (0,
|
|
54758
|
+
const proc = deps.spawnOverride ? deps.spawnOverride(cmd, args, cwd) : (0, import_node_child_process7.spawn)(cmd, args, { cwd, env: codexEnvironment(cmd), stdio: ["pipe", "pipe", "pipe"] });
|
|
54225
54759
|
const client = new CodexAppServerClient(stdioLineStream(proc), {});
|
|
54226
54760
|
const timeoutMs = deps.timeoutMs ?? DEFAULT_CODEX_QUERY_TIMEOUT_MS;
|
|
54227
54761
|
let timer;
|
|
@@ -54336,105 +54870,8 @@ function mergeProviderModels(native, provider) {
|
|
|
54336
54870
|
return sorted.map((m3) => ({ ...m3, group: modelFamily(m3.id) }));
|
|
54337
54871
|
}
|
|
54338
54872
|
|
|
54339
|
-
// src/tools/codex-provider-models.ts
|
|
54340
|
-
var import_node_child_process7 = require("child_process");
|
|
54341
|
-
var import_node_fs24 = __toESM(require("fs"), 1);
|
|
54342
|
-
var import_node_os10 = __toESM(require("os"), 1);
|
|
54343
|
-
var import_node_path25 = __toESM(require("path"), 1);
|
|
54344
|
-
var import_node_util = require("util");
|
|
54345
|
-
var PROVIDER_FETCH_TIMEOUT_MS = 3e3;
|
|
54346
|
-
function asRecord2(v3) {
|
|
54347
|
-
return v3 && typeof v3 === "object" && !Array.isArray(v3) ? v3 : null;
|
|
54348
|
-
}
|
|
54349
|
-
function readAuthKey(codexHome) {
|
|
54350
|
-
try {
|
|
54351
|
-
const raw = JSON.parse(import_node_fs24.default.readFileSync(import_node_path25.default.join(codexHome, "auth.json"), "utf8"));
|
|
54352
|
-
const key = asRecord2(raw)?.OPENAI_API_KEY;
|
|
54353
|
-
return typeof key === "string" && key ? key : void 0;
|
|
54354
|
-
} catch {
|
|
54355
|
-
return void 0;
|
|
54356
|
-
}
|
|
54357
|
-
}
|
|
54358
|
-
var defaultExecFile = (0, import_node_util.promisify)(import_node_child_process7.execFile);
|
|
54359
|
-
var AUTH_COMMAND_TIMEOUT_MS = 5e3;
|
|
54360
|
-
async function runAuthCommand(name, auth, deps) {
|
|
54361
|
-
const command = typeof auth.command === "string" && auth.command ? auth.command : void 0;
|
|
54362
|
-
if (!command) return void 0;
|
|
54363
|
-
const args = Array.isArray(auth.args) ? auth.args.filter((a2) => typeof a2 === "string") : [];
|
|
54364
|
-
const timeout = typeof auth.timeout_ms === "number" && auth.timeout_ms > 0 ? Math.min(auth.timeout_ms, AUTH_COMMAND_TIMEOUT_MS) : AUTH_COMMAND_TIMEOUT_MS;
|
|
54365
|
-
const cwd = typeof auth.cwd === "string" && auth.cwd ? auth.cwd : void 0;
|
|
54366
|
-
try {
|
|
54367
|
-
const { stdout } = await deps.execFileImpl(command, args, { ...cwd ? { cwd } : {}, timeout });
|
|
54368
|
-
const token = String(stdout).trim();
|
|
54369
|
-
if (token) return token;
|
|
54370
|
-
deps.logger?.warn?.(`provider "${name}": auth command \`${command}\` produced an empty token, sending unauthenticated`);
|
|
54371
|
-
} catch (err) {
|
|
54372
|
-
const e = err;
|
|
54373
|
-
const why = e.killed ? `killed by ${e.signal ?? "signal"} (timeout ${timeout}ms)` : e.code !== void 0 ? `exit/code ${e.code}` : "failed";
|
|
54374
|
-
deps.logger?.warn?.(`provider "${name}": auth command \`${command}\` ${why}, sending unauthenticated`);
|
|
54375
|
-
}
|
|
54376
|
-
return void 0;
|
|
54377
|
-
}
|
|
54378
|
-
async function resolveProviderEndpoint(rawConfig, deps = {}) {
|
|
54379
|
-
const config = asRecord2(asRecord2(rawConfig)?.config);
|
|
54380
|
-
if (!config) return null;
|
|
54381
|
-
const name = config.model_provider;
|
|
54382
|
-
if (typeof name !== "string" || !name) return null;
|
|
54383
|
-
const entry = asRecord2(asRecord2(config.model_providers)?.[name]);
|
|
54384
|
-
if (!entry) return null;
|
|
54385
|
-
const baseUrl = entry.base_url;
|
|
54386
|
-
if (typeof baseUrl !== "string" || !baseUrl) return null;
|
|
54387
|
-
const env = deps.env ?? process.env;
|
|
54388
|
-
const codexHome = deps.codexHome ?? env.CODEX_HOME ?? import_node_path25.default.join(import_node_os10.default.homedir(), ".codex");
|
|
54389
|
-
const envKey = typeof entry.env_key === "string" && entry.env_key ? entry.env_key : null;
|
|
54390
|
-
const inlineToken = typeof entry.experimental_bearer_token === "string" && entry.experimental_bearer_token ? entry.experimental_bearer_token : void 0;
|
|
54391
|
-
const auth = asRecord2(entry.auth);
|
|
54392
|
-
let token;
|
|
54393
|
-
if (envKey) token = env[envKey];
|
|
54394
|
-
else if (inlineToken) token = inlineToken;
|
|
54395
|
-
else if (auth && typeof auth.command === "string" && auth.command) {
|
|
54396
|
-
token = await runAuthCommand(name, auth, { execFileImpl: deps.execFileImpl ?? defaultExecFile, ...deps.logger ? { logger: deps.logger } : {} });
|
|
54397
|
-
} else token = readAuthKey(codexHome);
|
|
54398
|
-
if (!token && !(auth && typeof auth.command === "string" && auth.command)) {
|
|
54399
|
-
deps.logger?.warn?.(
|
|
54400
|
-
envKey ? `provider "${name}": env_key ${envKey} is not set in the daemon process, sending unauthenticated` : `provider "${name}": no OPENAI_API_KEY in ${codexHome}/auth.json, sending unauthenticated`
|
|
54401
|
-
);
|
|
54402
|
-
}
|
|
54403
|
-
return {
|
|
54404
|
-
baseUrl,
|
|
54405
|
-
headers: {
|
|
54406
|
-
Accept: "application/json",
|
|
54407
|
-
...token ? { Authorization: `Bearer ${token}` } : {}
|
|
54408
|
-
}
|
|
54409
|
-
};
|
|
54410
|
-
}
|
|
54411
|
-
async function fetchProviderModels(endpoint, deps = {}) {
|
|
54412
|
-
const fetchImpl = deps.fetchImpl ?? fetch;
|
|
54413
|
-
const controller = new AbortController();
|
|
54414
|
-
const timer = setTimeout(() => controller.abort(), deps.timeoutMs ?? PROVIDER_FETCH_TIMEOUT_MS);
|
|
54415
|
-
const url = `${endpoint.baseUrl.replace(/\/$/, "")}/models`;
|
|
54416
|
-
try {
|
|
54417
|
-
const res = await fetchImpl(url, { headers: endpoint.headers, signal: controller.signal });
|
|
54418
|
-
if (!res.ok) throw new Error(`provider model list failed: HTTP ${res.status} from ${url}`);
|
|
54419
|
-
const data = asRecord2(await res.json())?.data;
|
|
54420
|
-
if (!Array.isArray(data)) throw new Error(`provider model list: \`data\` is not an array (${url})`);
|
|
54421
|
-
const out = [];
|
|
54422
|
-
for (const item of data) {
|
|
54423
|
-
const e = asRecord2(item);
|
|
54424
|
-
if (!e || typeof e.id !== "string" || !e.id) continue;
|
|
54425
|
-
out.push({ id: e.id, ...typeof e.owned_by === "string" ? { ownedBy: e.owned_by } : {} });
|
|
54426
|
-
}
|
|
54427
|
-
return out;
|
|
54428
|
-
} catch (err) {
|
|
54429
|
-
if (deps.throwOnFailure) throw err;
|
|
54430
|
-
deps.logger?.warn?.(`provider model list failed: ${err.message}`);
|
|
54431
|
-
return [];
|
|
54432
|
-
} finally {
|
|
54433
|
-
clearTimeout(timer);
|
|
54434
|
-
}
|
|
54435
|
-
}
|
|
54436
|
-
|
|
54437
54873
|
// src/tools/codex.ts
|
|
54874
|
+
init_codex_provider_models();
|
|
54438
54875
|
init_claude();
|
|
54439
54876
|
var CODEX_EFFORTS = [
|
|
54440
54877
|
{ value: "low", label: "Low", description: "Fast responses with lighter reasoning" },
|
|
@@ -54620,9 +55057,9 @@ var CodexAdapter = class {
|
|
|
54620
55057
|
|
|
54621
55058
|
// src/tools/claude-tui.ts
|
|
54622
55059
|
var import_node_crypto9 = require("crypto");
|
|
54623
|
-
var
|
|
54624
|
-
var
|
|
54625
|
-
var
|
|
55060
|
+
var import_node_fs26 = __toESM(require("fs"), 1);
|
|
55061
|
+
var import_node_os12 = __toESM(require("os"), 1);
|
|
55062
|
+
var import_node_path27 = __toESM(require("path"), 1);
|
|
54626
55063
|
var import_headless = __toESM(require_xterm_headless(), 1);
|
|
54627
55064
|
|
|
54628
55065
|
// ../node_modules/.pnpm/@xterm+addon-serialize@0.14.0/node_modules/@xterm/addon-serialize/lib/addon-serialize.mjs
|
|
@@ -55645,7 +56082,7 @@ var ClaudeTuiAdapter = class extends ClaudeAdapter {
|
|
|
55645
56082
|
command: cmd,
|
|
55646
56083
|
args,
|
|
55647
56084
|
cwd: ctx.cwd,
|
|
55648
|
-
env:
|
|
56085
|
+
env: this.spawnEnv(ctx)
|
|
55649
56086
|
});
|
|
55650
56087
|
if (ctx.toolSessionId && this.tuiOpts.onPtyRegister) {
|
|
55651
56088
|
this.tuiOpts.onPtyRegister(ctx.toolSessionId, pty);
|
|
@@ -55830,10 +56267,10 @@ function buildTuiSpawnArgs(ctx, isResume = false) {
|
|
|
55830
56267
|
}
|
|
55831
56268
|
function jsonlExistsForCtx(ctx) {
|
|
55832
56269
|
if (!ctx.toolSessionId) return false;
|
|
55833
|
-
const home =
|
|
55834
|
-
const file =
|
|
56270
|
+
const home = import_node_os12.default.homedir();
|
|
56271
|
+
const file = import_node_path27.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
|
|
55835
56272
|
try {
|
|
55836
|
-
return
|
|
56273
|
+
return import_node_fs26.default.statSync(file).isFile();
|
|
55837
56274
|
} catch {
|
|
55838
56275
|
return false;
|
|
55839
56276
|
}
|
|
@@ -55916,7 +56353,7 @@ var PersonaDispatchManager = class {
|
|
|
55916
56353
|
|
|
55917
56354
|
// src/dispatch/store.ts
|
|
55918
56355
|
var import_promises = __toESM(require("fs/promises"), 1);
|
|
55919
|
-
var
|
|
56356
|
+
var import_node_path28 = __toESM(require("path"), 1);
|
|
55920
56357
|
|
|
55921
56358
|
// src/shift/constants.ts
|
|
55922
56359
|
var MAX_RUNS_PER_SHIFT = 30;
|
|
@@ -55954,7 +56391,7 @@ function createDispatchStore(deps) {
|
|
|
55954
56391
|
flushTimer = null;
|
|
55955
56392
|
}
|
|
55956
56393
|
const content = { version: 1, records };
|
|
55957
|
-
await import_promises.default.mkdir(
|
|
56394
|
+
await import_promises.default.mkdir(import_node_path28.default.dirname(deps.filePath), { recursive: true });
|
|
55958
56395
|
const tmp = `${deps.filePath}.tmp-${deps.now()}-${Math.floor(Math.random() * 1e6)}`;
|
|
55959
56396
|
await import_promises.default.writeFile(tmp, JSON.stringify(content, null, 2), "utf8");
|
|
55960
56397
|
await import_promises.default.rename(tmp, deps.filePath);
|
|
@@ -56023,7 +56460,7 @@ function createDispatchStore(deps) {
|
|
|
56023
56460
|
|
|
56024
56461
|
// src/channel/json-store.ts
|
|
56025
56462
|
var import_promises2 = __toESM(require("fs/promises"), 1);
|
|
56026
|
-
var
|
|
56463
|
+
var import_node_path29 = __toESM(require("path"), 1);
|
|
56027
56464
|
function createJsonStore(deps) {
|
|
56028
56465
|
let items = [];
|
|
56029
56466
|
let flushTimer = null;
|
|
@@ -56034,7 +56471,7 @@ function createJsonStore(deps) {
|
|
|
56034
56471
|
flushTimer = null;
|
|
56035
56472
|
}
|
|
56036
56473
|
const content = { version: version2, [deps.key]: items };
|
|
56037
|
-
await import_promises2.default.mkdir(
|
|
56474
|
+
await import_promises2.default.mkdir(import_node_path29.default.dirname(deps.filePath), { recursive: true });
|
|
56038
56475
|
const tmp = `${deps.filePath}.tmp-${deps.now()}-${Math.floor(Math.random() * 1e6)}`;
|
|
56039
56476
|
await import_promises2.default.writeFile(tmp, JSON.stringify(content, null, 2), "utf8");
|
|
56040
56477
|
await import_promises2.default.rename(tmp, deps.filePath);
|
|
@@ -56305,10 +56742,10 @@ function createTopicStore(deps) {
|
|
|
56305
56742
|
}
|
|
56306
56743
|
|
|
56307
56744
|
// src/dispatch/mcp-config.ts
|
|
56308
|
-
var
|
|
56309
|
-
var
|
|
56745
|
+
var import_node_fs27 = __toESM(require("fs"), 1);
|
|
56746
|
+
var import_node_path30 = __toESM(require("path"), 1);
|
|
56310
56747
|
function dispatchMcpConfigPath(dataDir) {
|
|
56311
|
-
return
|
|
56748
|
+
return import_node_path30.default.join(dataDir, "dispatch.mcp.json");
|
|
56312
56749
|
}
|
|
56313
56750
|
function writeDispatchMcpConfig(args) {
|
|
56314
56751
|
const cfgPath = dispatchMcpConfigPath(args.dataDir);
|
|
@@ -56327,16 +56764,16 @@ function writeDispatchMcpConfig(args) {
|
|
|
56327
56764
|
}
|
|
56328
56765
|
}
|
|
56329
56766
|
};
|
|
56330
|
-
|
|
56331
|
-
|
|
56767
|
+
import_node_fs27.default.mkdirSync(args.dataDir, { recursive: true });
|
|
56768
|
+
import_node_fs27.default.writeFileSync(cfgPath, JSON.stringify(content, null, 2), "utf8");
|
|
56332
56769
|
return cfgPath;
|
|
56333
56770
|
}
|
|
56334
56771
|
|
|
56335
56772
|
// src/ticket/mcp-config.ts
|
|
56336
|
-
var
|
|
56337
|
-
var
|
|
56773
|
+
var import_node_fs28 = __toESM(require("fs"), 1);
|
|
56774
|
+
var import_node_path31 = __toESM(require("path"), 1);
|
|
56338
56775
|
function ticketMcpConfigPath(dataDir) {
|
|
56339
|
-
return
|
|
56776
|
+
return import_node_path31.default.join(dataDir, "ticket.mcp.json");
|
|
56340
56777
|
}
|
|
56341
56778
|
function writeTicketMcpConfig(args) {
|
|
56342
56779
|
const cfgPath = ticketMcpConfigPath(args.dataDir);
|
|
@@ -56358,16 +56795,16 @@ function writeTicketMcpConfig(args) {
|
|
|
56358
56795
|
}
|
|
56359
56796
|
}
|
|
56360
56797
|
};
|
|
56361
|
-
|
|
56362
|
-
|
|
56798
|
+
import_node_fs28.default.mkdirSync(args.dataDir, { recursive: true });
|
|
56799
|
+
import_node_fs28.default.writeFileSync(cfgPath, JSON.stringify(content, null, 2), "utf8");
|
|
56363
56800
|
return cfgPath;
|
|
56364
56801
|
}
|
|
56365
56802
|
|
|
56366
56803
|
// src/shift/mcp-config.ts
|
|
56367
|
-
var
|
|
56368
|
-
var
|
|
56804
|
+
var import_node_fs29 = __toESM(require("fs"), 1);
|
|
56805
|
+
var import_node_path32 = __toESM(require("path"), 1);
|
|
56369
56806
|
function shiftMcpConfigPath(dataDir) {
|
|
56370
|
-
return
|
|
56807
|
+
return import_node_path32.default.join(dataDir, "shift.mcp.json");
|
|
56371
56808
|
}
|
|
56372
56809
|
async function writeShiftMcpConfig(args) {
|
|
56373
56810
|
const cfgPath = shiftMcpConfigPath(args.dataDir);
|
|
@@ -56386,16 +56823,16 @@ async function writeShiftMcpConfig(args) {
|
|
|
56386
56823
|
}
|
|
56387
56824
|
}
|
|
56388
56825
|
};
|
|
56389
|
-
await
|
|
56390
|
-
await
|
|
56826
|
+
await import_node_fs29.default.promises.mkdir(args.dataDir, { recursive: true });
|
|
56827
|
+
await import_node_fs29.default.promises.writeFile(cfgPath, JSON.stringify(content, null, 2), "utf8");
|
|
56391
56828
|
return cfgPath;
|
|
56392
56829
|
}
|
|
56393
56830
|
|
|
56394
56831
|
// src/inbox/mcp-config.ts
|
|
56395
|
-
var
|
|
56396
|
-
var
|
|
56832
|
+
var import_node_fs30 = __toESM(require("fs"), 1);
|
|
56833
|
+
var import_node_path33 = __toESM(require("path"), 1);
|
|
56397
56834
|
function inboxMcpConfigPath(dataDir) {
|
|
56398
|
-
return
|
|
56835
|
+
return import_node_path33.default.join(dataDir, "inbox.mcp.json");
|
|
56399
56836
|
}
|
|
56400
56837
|
async function writeInboxMcpConfig(args) {
|
|
56401
56838
|
const cfgPath = inboxMcpConfigPath(args.dataDir);
|
|
@@ -56414,16 +56851,16 @@ async function writeInboxMcpConfig(args) {
|
|
|
56414
56851
|
}
|
|
56415
56852
|
}
|
|
56416
56853
|
};
|
|
56417
|
-
await
|
|
56418
|
-
await
|
|
56854
|
+
await import_node_fs30.default.promises.mkdir(args.dataDir, { recursive: true });
|
|
56855
|
+
await import_node_fs30.default.promises.writeFile(cfgPath, JSON.stringify(content, null, 2), "utf8");
|
|
56419
56856
|
return cfgPath;
|
|
56420
56857
|
}
|
|
56421
56858
|
|
|
56422
56859
|
// src/peer-ops/mcp-config.ts
|
|
56423
|
-
var
|
|
56424
|
-
var
|
|
56860
|
+
var import_node_fs31 = __toESM(require("fs"), 1);
|
|
56861
|
+
var import_node_path34 = __toESM(require("path"), 1);
|
|
56425
56862
|
function peerOpsMcpConfigPath(dataDir) {
|
|
56426
|
-
return
|
|
56863
|
+
return import_node_path34.default.join(dataDir, "peer-ops.mcp.json");
|
|
56427
56864
|
}
|
|
56428
56865
|
function writePeerOpsMcpConfig(args) {
|
|
56429
56866
|
const cfgPath = peerOpsMcpConfigPath(args.dataDir);
|
|
@@ -56440,16 +56877,16 @@ function writePeerOpsMcpConfig(args) {
|
|
|
56440
56877
|
}
|
|
56441
56878
|
}
|
|
56442
56879
|
};
|
|
56443
|
-
|
|
56444
|
-
|
|
56880
|
+
import_node_fs31.default.mkdirSync(args.dataDir, { recursive: true });
|
|
56881
|
+
import_node_fs31.default.writeFileSync(cfgPath, JSON.stringify(cfg, null, 2));
|
|
56445
56882
|
return cfgPath;
|
|
56446
56883
|
}
|
|
56447
56884
|
|
|
56448
56885
|
// src/rpc-tool/mcp-config.ts
|
|
56449
|
-
var
|
|
56450
|
-
var
|
|
56886
|
+
var import_node_fs32 = __toESM(require("fs"), 1);
|
|
56887
|
+
var import_node_path35 = __toESM(require("path"), 1);
|
|
56451
56888
|
function rpcToolMcpConfigPath(dataDir) {
|
|
56452
|
-
return
|
|
56889
|
+
return import_node_path35.default.join(dataDir, "rpc-tool.mcp.json");
|
|
56453
56890
|
}
|
|
56454
56891
|
function writeRpcToolMcpConfig(args) {
|
|
56455
56892
|
const cfgPath = rpcToolMcpConfigPath(args.dataDir);
|
|
@@ -56468,29 +56905,29 @@ function writeRpcToolMcpConfig(args) {
|
|
|
56468
56905
|
}
|
|
56469
56906
|
}
|
|
56470
56907
|
};
|
|
56471
|
-
|
|
56472
|
-
|
|
56908
|
+
import_node_fs32.default.mkdirSync(args.dataDir, { recursive: true });
|
|
56909
|
+
import_node_fs32.default.writeFileSync(cfgPath, JSON.stringify(content, null, 2), "utf8");
|
|
56473
56910
|
return cfgPath;
|
|
56474
56911
|
}
|
|
56475
56912
|
|
|
56476
56913
|
// src/deploy/secret-table.ts
|
|
56477
|
-
var
|
|
56478
|
-
var
|
|
56914
|
+
var import_node_fs33 = __toESM(require("fs"), 1);
|
|
56915
|
+
var import_node_path36 = __toESM(require("path"), 1);
|
|
56479
56916
|
var import_node_url5 = require("url");
|
|
56480
56917
|
var import_meta5 = {};
|
|
56481
56918
|
var LOCAL_SECRETS_DIRNAME = "secrets";
|
|
56482
56919
|
function findSecretsBundleRoot(logger) {
|
|
56483
56920
|
const candidates = [];
|
|
56484
56921
|
try {
|
|
56485
|
-
const here =
|
|
56486
|
-
candidates.push(
|
|
56922
|
+
const here = import_node_path36.default.dirname((0, import_node_url5.fileURLToPath)(import_meta5.url));
|
|
56923
|
+
candidates.push(import_node_path36.default.resolve(here, "..", "secrets"));
|
|
56487
56924
|
} catch {
|
|
56488
56925
|
}
|
|
56489
56926
|
const fromArgv = bundleSiblingFromArgv(process.argv[1], "secrets");
|
|
56490
56927
|
if (fromArgv) candidates.push(fromArgv);
|
|
56491
56928
|
for (const c2 of candidates) {
|
|
56492
56929
|
try {
|
|
56493
|
-
if (
|
|
56930
|
+
if (import_node_fs33.default.statSync(c2).isDirectory()) return c2;
|
|
56494
56931
|
} catch {
|
|
56495
56932
|
}
|
|
56496
56933
|
}
|
|
@@ -56516,7 +56953,7 @@ function readDir(dir, logger) {
|
|
|
56516
56953
|
const out = {};
|
|
56517
56954
|
let files;
|
|
56518
56955
|
try {
|
|
56519
|
-
files =
|
|
56956
|
+
files = import_node_fs33.default.readdirSync(dir).filter((f2) => f2.endsWith(".env")).sort();
|
|
56520
56957
|
} catch (e) {
|
|
56521
56958
|
const code = e.code;
|
|
56522
56959
|
if (code !== "ENOENT") logger?.warn("secrets.dir-unreadable", { dir, code: code ?? "unknown" });
|
|
@@ -56524,19 +56961,19 @@ function readDir(dir, logger) {
|
|
|
56524
56961
|
}
|
|
56525
56962
|
for (const f2 of files) {
|
|
56526
56963
|
try {
|
|
56527
|
-
Object.assign(out, parseEnvFile(
|
|
56964
|
+
Object.assign(out, parseEnvFile(import_node_fs33.default.readFileSync(import_node_path36.default.join(dir, f2), "utf8")));
|
|
56528
56965
|
} catch (e) {
|
|
56529
|
-
logger?.warn("secrets.file-unreadable", { file:
|
|
56966
|
+
logger?.warn("secrets.file-unreadable", { file: import_node_path36.default.join(dir, f2), error: e.message });
|
|
56530
56967
|
}
|
|
56531
56968
|
}
|
|
56532
56969
|
return out;
|
|
56533
56970
|
}
|
|
56534
56971
|
function upsertEnvFileVar(file, key, value) {
|
|
56535
56972
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) throw new Error(`invalid env name: ${key}`);
|
|
56536
|
-
|
|
56973
|
+
import_node_fs33.default.mkdirSync(import_node_path36.default.dirname(file), { recursive: true, mode: 448 });
|
|
56537
56974
|
let lines = [];
|
|
56538
56975
|
try {
|
|
56539
|
-
lines =
|
|
56976
|
+
lines = import_node_fs33.default.readFileSync(file, "utf8").split("\n");
|
|
56540
56977
|
if (lines[lines.length - 1] === "") lines.pop();
|
|
56541
56978
|
} catch {
|
|
56542
56979
|
}
|
|
@@ -56544,12 +56981,12 @@ function upsertEnvFileVar(file, key, value) {
|
|
|
56544
56981
|
let replaced = false;
|
|
56545
56982
|
const out = lines.map((l2) => re2.test(l2) ? (replaced = true, `${key}=${value}`) : l2);
|
|
56546
56983
|
if (!replaced) out.push(`${key}=${value}`);
|
|
56547
|
-
|
|
56984
|
+
import_node_fs33.default.writeFileSync(file, `${out.join("\n")}
|
|
56548
56985
|
`, { encoding: "utf8", mode: 384 });
|
|
56549
56986
|
}
|
|
56550
56987
|
function readEnvFileVar(file, key) {
|
|
56551
56988
|
try {
|
|
56552
|
-
return parseEnvFile(
|
|
56989
|
+
return parseEnvFile(import_node_fs33.default.readFileSync(file, "utf8"))[key];
|
|
56553
56990
|
} catch {
|
|
56554
56991
|
return void 0;
|
|
56555
56992
|
}
|
|
@@ -56558,7 +56995,7 @@ function removeEnvFileVar(file, key) {
|
|
|
56558
56995
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) throw new Error(`invalid env name: ${key}`);
|
|
56559
56996
|
let lines;
|
|
56560
56997
|
try {
|
|
56561
|
-
lines =
|
|
56998
|
+
lines = import_node_fs33.default.readFileSync(file, "utf8").split("\n");
|
|
56562
56999
|
} catch {
|
|
56563
57000
|
return;
|
|
56564
57001
|
}
|
|
@@ -56567,10 +57004,10 @@ function removeEnvFileVar(file, key) {
|
|
|
56567
57004
|
const out = lines.filter((l2) => !re2.test(l2));
|
|
56568
57005
|
if (out.length === lines.length) return;
|
|
56569
57006
|
if (out.every((l2) => l2.trim() === "" || l2.trim().startsWith("#"))) {
|
|
56570
|
-
|
|
57007
|
+
import_node_fs33.default.rmSync(file, { force: true });
|
|
56571
57008
|
return;
|
|
56572
57009
|
}
|
|
56573
|
-
|
|
57010
|
+
import_node_fs33.default.writeFileSync(file, `${out.join("\n")}
|
|
56574
57011
|
`, { encoding: "utf8", mode: 384 });
|
|
56575
57012
|
}
|
|
56576
57013
|
function readSecretTable(args) {
|
|
@@ -56581,12 +57018,12 @@ function readSecretTable(args) {
|
|
|
56581
57018
|
}
|
|
56582
57019
|
|
|
56583
57020
|
// src/dispatch/source-transcript.ts
|
|
56584
|
-
var
|
|
57021
|
+
var import_node_path37 = __toESM(require("path"), 1);
|
|
56585
57022
|
init_claude_history();
|
|
56586
57023
|
var NO_SOURCE_TRANSCRIPT = "(no transcript yet \u2014 operate from the task description alone)";
|
|
56587
57024
|
function resolveSourceJsonlPath(sourceFile, home) {
|
|
56588
57025
|
if (!sourceFile?.toolSessionId) return NO_SOURCE_TRANSCRIPT;
|
|
56589
|
-
return
|
|
57026
|
+
return import_node_path37.default.join(
|
|
56590
57027
|
home,
|
|
56591
57028
|
".claude",
|
|
56592
57029
|
"projects",
|
|
@@ -56597,7 +57034,7 @@ function resolveSourceJsonlPath(sourceFile, home) {
|
|
|
56597
57034
|
|
|
56598
57035
|
// src/shift/store.ts
|
|
56599
57036
|
var import_promises3 = __toESM(require("fs/promises"), 1);
|
|
56600
|
-
var
|
|
57037
|
+
var import_node_path38 = __toESM(require("path"), 1);
|
|
56601
57038
|
var import_node_crypto10 = require("crypto");
|
|
56602
57039
|
|
|
56603
57040
|
// src/shift/schedule.ts
|
|
@@ -56672,7 +57109,7 @@ function createShiftStore(deps) {
|
|
|
56672
57109
|
flushTimer = null;
|
|
56673
57110
|
}
|
|
56674
57111
|
const content = { version: 1, shifts };
|
|
56675
|
-
await import_promises3.default.mkdir(
|
|
57112
|
+
await import_promises3.default.mkdir(import_node_path38.default.dirname(deps.filePath), { recursive: true });
|
|
56676
57113
|
const tmp = `${deps.filePath}.tmp-${deps.now()}-${Math.floor(Math.random() * 1e6)}`;
|
|
56677
57114
|
await import_promises3.default.writeFile(tmp, JSON.stringify(content, null, 2), "utf8");
|
|
56678
57115
|
await import_promises3.default.rename(tmp, deps.filePath);
|
|
@@ -57096,40 +57533,40 @@ var import_node_crypto14 = require("crypto");
|
|
|
57096
57533
|
var import_node_perf_hooks = require("perf_hooks");
|
|
57097
57534
|
|
|
57098
57535
|
// src/deploy/persona-test.ts
|
|
57099
|
-
var
|
|
57100
|
-
var
|
|
57536
|
+
var import_node_fs34 = __toESM(require("fs"), 1);
|
|
57537
|
+
var import_node_path39 = __toESM(require("path"), 1);
|
|
57101
57538
|
init_protocol();
|
|
57102
57539
|
var TEST_SCAN_NOTE_PREFIX = PUBLISHER_TEST_NOTE_PREFIX;
|
|
57103
57540
|
function regularFile(root, relative5) {
|
|
57104
57541
|
let current = root;
|
|
57105
57542
|
for (const segment of relative5.split("/")) {
|
|
57106
|
-
current =
|
|
57107
|
-
if (
|
|
57543
|
+
current = import_node_path39.default.join(current, segment);
|
|
57544
|
+
if (import_node_fs34.default.lstatSync(current).isSymbolicLink()) throw new Error("symlink");
|
|
57108
57545
|
}
|
|
57109
|
-
if (!
|
|
57110
|
-
const resolved =
|
|
57111
|
-
if (!resolved.startsWith(root +
|
|
57546
|
+
if (!import_node_fs34.default.statSync(current).isFile()) throw new Error("not a file");
|
|
57547
|
+
const resolved = import_node_fs34.default.realpathSync(current);
|
|
57548
|
+
if (!resolved.startsWith(root + import_node_path39.default.sep)) throw new Error("outside root");
|
|
57112
57549
|
return resolved;
|
|
57113
57550
|
}
|
|
57114
57551
|
function discoverPublisherTest(dir) {
|
|
57115
57552
|
try {
|
|
57116
|
-
const root =
|
|
57553
|
+
const root = import_node_fs34.default.realpathSync(dir);
|
|
57117
57554
|
try {
|
|
57118
|
-
|
|
57555
|
+
import_node_fs34.default.lstatSync(import_node_path39.default.join(root, ".clawd"));
|
|
57119
57556
|
} catch (error) {
|
|
57120
57557
|
if (error.code === "ENOENT") return { problems: [] };
|
|
57121
57558
|
throw error;
|
|
57122
57559
|
}
|
|
57123
|
-
if (
|
|
57560
|
+
if (import_node_fs34.default.lstatSync(import_node_path39.default.join(root, ".clawd")).isSymbolicLink()) throw new Error("symlink");
|
|
57124
57561
|
try {
|
|
57125
|
-
|
|
57562
|
+
import_node_fs34.default.lstatSync(import_node_path39.default.join(root, ".clawd/test.json"));
|
|
57126
57563
|
} catch (error) {
|
|
57127
57564
|
if (error.code === "ENOENT") return { problems: [] };
|
|
57128
57565
|
throw error;
|
|
57129
57566
|
}
|
|
57130
57567
|
const file = regularFile(root, ".clawd/test.json");
|
|
57131
|
-
if (
|
|
57132
|
-
const test = PublisherTestSchema.parse(JSON.parse(
|
|
57568
|
+
if (import_node_fs34.default.statSync(file).size > 64 * 1024) throw new Error("oversized");
|
|
57569
|
+
const test = PublisherTestSchema.parse(JSON.parse(import_node_fs34.default.readFileSync(file, "utf8")));
|
|
57133
57570
|
regularFile(root, test.entry);
|
|
57134
57571
|
return { test, problems: [] };
|
|
57135
57572
|
} catch {
|
|
@@ -57530,19 +57967,19 @@ function openHttpTurn(opts) {
|
|
|
57530
57967
|
|
|
57531
57968
|
// src/deploy/repo.ts
|
|
57532
57969
|
var import_promises5 = __toESM(require("fs/promises"), 1);
|
|
57533
|
-
var
|
|
57970
|
+
var import_node_path42 = __toESM(require("path"), 1);
|
|
57534
57971
|
init_protocol();
|
|
57535
57972
|
|
|
57536
57973
|
// src/deploy/deploy-file.ts
|
|
57537
57974
|
var import_promises4 = __toESM(require("fs/promises"), 1);
|
|
57538
|
-
var
|
|
57975
|
+
var import_node_path41 = __toESM(require("path"), 1);
|
|
57539
57976
|
var import_node_crypto11 = require("crypto");
|
|
57540
57977
|
init_zod();
|
|
57541
57978
|
init_protocol();
|
|
57542
57979
|
|
|
57543
57980
|
// src/deploy/connectors.ts
|
|
57544
|
-
var
|
|
57545
|
-
var
|
|
57981
|
+
var import_node_fs35 = __toESM(require("fs"), 1);
|
|
57982
|
+
var import_node_path40 = __toESM(require("path"), 1);
|
|
57546
57983
|
init_zod();
|
|
57547
57984
|
init_protocol();
|
|
57548
57985
|
|
|
@@ -57630,11 +58067,11 @@ var PACKAGE_RUNNERS = /* @__PURE__ */ new Set(["npx", "uvx", "pnpx", "bunx"]);
|
|
|
57630
58067
|
var SCRIPT_RUNNERS = /* @__PURE__ */ new Set(["node", "bun", "deno", "python", "python3"]);
|
|
57631
58068
|
var HOST_ARG_PLACEHOLDER = "CLAWD_PERSONA_DIR";
|
|
57632
58069
|
function scanMcpConnectors(personaDir) {
|
|
57633
|
-
const file =
|
|
58070
|
+
const file = import_node_path40.default.join(personaDir, ".mcp.json");
|
|
57634
58071
|
const out = { readable: true, connectors: [], evidence: [], warnings: [] };
|
|
57635
58072
|
let parsed;
|
|
57636
58073
|
try {
|
|
57637
|
-
parsed = JSON.parse(
|
|
58074
|
+
parsed = JSON.parse(import_node_fs35.default.readFileSync(file, "utf8"));
|
|
57638
58075
|
} catch (e) {
|
|
57639
58076
|
if (e.code === "ENOENT") return out;
|
|
57640
58077
|
out.readable = false;
|
|
@@ -57730,8 +58167,8 @@ function mergeScannedConnectors(existing, scanned) {
|
|
|
57730
58167
|
}
|
|
57731
58168
|
|
|
57732
58169
|
// src/deploy/deploy-file.ts
|
|
57733
|
-
var DEPLOY_FILE =
|
|
57734
|
-
var SCAN_FILE =
|
|
58170
|
+
var DEPLOY_FILE = import_node_path41.default.join(".clawd", "deploy.json");
|
|
58171
|
+
var SCAN_FILE = import_node_path41.default.join(".clawd", "deploy-scan.json");
|
|
57735
58172
|
async function readJson(file) {
|
|
57736
58173
|
let raw;
|
|
57737
58174
|
try {
|
|
@@ -57747,14 +58184,14 @@ async function readJson(file) {
|
|
|
57747
58184
|
}
|
|
57748
58185
|
}
|
|
57749
58186
|
async function writeJson(file, value) {
|
|
57750
|
-
await import_promises4.default.mkdir(
|
|
58187
|
+
await import_promises4.default.mkdir(import_node_path41.default.dirname(file), { recursive: true });
|
|
57751
58188
|
const tmp = `${file}.tmp-${process.pid}`;
|
|
57752
58189
|
await import_promises4.default.writeFile(tmp, `${JSON.stringify(value, null, 2)}
|
|
57753
58190
|
`);
|
|
57754
58191
|
await import_promises4.default.rename(tmp, file);
|
|
57755
58192
|
}
|
|
57756
58193
|
async function readDeployFile(dir) {
|
|
57757
|
-
const raw = await readJson(
|
|
58194
|
+
const raw = await readJson(import_node_path41.default.join(dir, DEPLOY_FILE));
|
|
57758
58195
|
if (raw === void 0) return void 0;
|
|
57759
58196
|
const parsed = DeployFileSchema.safeParse(raw);
|
|
57760
58197
|
if (!parsed.success) {
|
|
@@ -57764,18 +58201,18 @@ async function readDeployFile(dir) {
|
|
|
57764
58201
|
return parsed.data;
|
|
57765
58202
|
}
|
|
57766
58203
|
async function writeDeployFile(dir, file) {
|
|
57767
|
-
await writeJson(
|
|
58204
|
+
await writeJson(import_node_path41.default.join(dir, DEPLOY_FILE), DeployFileSchema.parse(file));
|
|
57768
58205
|
}
|
|
57769
58206
|
async function readDeployFileRaw(dir) {
|
|
57770
58207
|
try {
|
|
57771
|
-
return await import_promises4.default.readFile(
|
|
58208
|
+
return await import_promises4.default.readFile(import_node_path41.default.join(dir, DEPLOY_FILE), "utf8");
|
|
57772
58209
|
} catch (err) {
|
|
57773
58210
|
if (err.code === "ENOENT") return void 0;
|
|
57774
58211
|
throw err;
|
|
57775
58212
|
}
|
|
57776
58213
|
}
|
|
57777
58214
|
async function restoreDeployFileRaw(dir, raw) {
|
|
57778
|
-
const file =
|
|
58215
|
+
const file = import_node_path41.default.join(dir, DEPLOY_FILE);
|
|
57779
58216
|
if (raw === void 0) await import_promises4.default.rm(file, { force: true });
|
|
57780
58217
|
else await import_promises4.default.writeFile(file, raw);
|
|
57781
58218
|
}
|
|
@@ -57826,7 +58263,7 @@ function normalizeLegacyScan(raw) {
|
|
|
57826
58263
|
return fix(raw);
|
|
57827
58264
|
}
|
|
57828
58265
|
async function readScanFile(dir) {
|
|
57829
|
-
const raw = normalizeLegacyScan(await readJson(
|
|
58266
|
+
const raw = normalizeLegacyScan(await readJson(import_node_path41.default.join(dir, SCAN_FILE)));
|
|
57830
58267
|
if (raw === void 0) return void 0;
|
|
57831
58268
|
const badShape = (issues) => {
|
|
57832
58269
|
const first = issues[0];
|
|
@@ -57852,7 +58289,7 @@ async function readScanFile(dir) {
|
|
|
57852
58289
|
return parsed.data;
|
|
57853
58290
|
}
|
|
57854
58291
|
async function writeScanFile(dir, file) {
|
|
57855
|
-
await writeJson(
|
|
58292
|
+
await writeJson(import_node_path41.default.join(dir, SCAN_FILE), DeployScanFileSchema.parse(file));
|
|
57856
58293
|
}
|
|
57857
58294
|
function replaceScan(file, entry) {
|
|
57858
58295
|
const idx = file.scans.findIndex((s2) => s2.id === entry.id);
|
|
@@ -62117,7 +62554,7 @@ var runCommand = (cmd, args, opts = {}) => new Promise((resolve9) => {
|
|
|
62117
62554
|
});
|
|
62118
62555
|
|
|
62119
62556
|
// src/deploy/repo.ts
|
|
62120
|
-
var DEPLOY_FILE_REL = DEPLOY_FILE.split(
|
|
62557
|
+
var DEPLOY_FILE_REL = DEPLOY_FILE.split(import_node_path42.default.sep).join("/");
|
|
62121
62558
|
var PERSONA_FILE_REL = ".clawd/persona.json";
|
|
62122
62559
|
var DIRTY_IGNORED = [DEPLOY_FILE_REL, PERSONA_FILE_REL];
|
|
62123
62560
|
var RepoError = class extends Error {
|
|
@@ -62150,7 +62587,7 @@ async function prepareIntegration(exec, dir, auth) {
|
|
|
62150
62587
|
for (const name of ["MERGE_HEAD", "CHERRY_PICK_HEAD", "REVERT_HEAD", "rebase-merge", "rebase-apply"]) {
|
|
62151
62588
|
const rel = await mustGit(exec, dir, ["rev-parse", "--git-path", name], "\u68C0\u67E5 Git \u64CD\u4F5C");
|
|
62152
62589
|
try {
|
|
62153
|
-
await import_promises5.default.stat(
|
|
62590
|
+
await import_promises5.default.stat(import_node_path42.default.resolve(dir, rel));
|
|
62154
62591
|
throw new RepoError("Git \u5408\u5E76\u6216\u53D8\u57FA\u8FD8\u672A\u5B8C\u6210\uFF0C\u5148\u5904\u7406\u518D\u53D1\u5E03");
|
|
62155
62592
|
} catch (err) {
|
|
62156
62593
|
if (err.code !== "ENOENT") throw err;
|
|
@@ -62211,7 +62648,7 @@ async function samePath(a2, b3) {
|
|
|
62211
62648
|
try {
|
|
62212
62649
|
return await import_promises5.default.realpath(x2);
|
|
62213
62650
|
} catch {
|
|
62214
|
-
return
|
|
62651
|
+
return import_node_path42.default.resolve(x2);
|
|
62215
62652
|
}
|
|
62216
62653
|
};
|
|
62217
62654
|
return await real(a2) === await real(b3);
|
|
@@ -62237,7 +62674,7 @@ async function identityArgs(exec, dir) {
|
|
|
62237
62674
|
return ["-c", "user.name=clawd", "-c", "user.email=clawd@clawos.local"];
|
|
62238
62675
|
}
|
|
62239
62676
|
async function writeGitignore(dir) {
|
|
62240
|
-
const gi =
|
|
62677
|
+
const gi = import_node_path42.default.join(dir, ".gitignore");
|
|
62241
62678
|
let existing;
|
|
62242
62679
|
try {
|
|
62243
62680
|
existing = await import_promises5.default.readFile(gi, "utf8");
|
|
@@ -62248,18 +62685,18 @@ async function writeGitignore(dir) {
|
|
|
62248
62685
|
}
|
|
62249
62686
|
async function writeWorkflow(dir) {
|
|
62250
62687
|
for (const [rel, body] of [[WORKFLOW_PATH, WORKFLOW_TEMPLATE], [UNPUBLISH_WORKFLOW_PATH, UNPUBLISH_WORKFLOW_TEMPLATE]]) {
|
|
62251
|
-
const wf =
|
|
62252
|
-
await import_promises5.default.mkdir(
|
|
62688
|
+
const wf = import_node_path42.default.join(dir, rel);
|
|
62689
|
+
await import_promises5.default.mkdir(import_node_path42.default.dirname(wf), { recursive: true });
|
|
62253
62690
|
await import_promises5.default.writeFile(wf, body);
|
|
62254
62691
|
}
|
|
62255
62692
|
}
|
|
62256
62693
|
async function writeDockerfile(dir, personaId2, image) {
|
|
62257
62694
|
const baseImage = image.replace("registry-vpc.cn-hangzhou.aliyuncs.com/", "registry.cn-hangzhou.aliyuncs.com/");
|
|
62258
|
-
await import_promises5.default.mkdir(
|
|
62259
|
-
await import_promises5.default.writeFile(
|
|
62695
|
+
await import_promises5.default.mkdir(import_node_path42.default.join(dir, ".clawd"), { recursive: true });
|
|
62696
|
+
await import_promises5.default.writeFile(import_node_path42.default.join(dir, ".clawd", "base-image.txt"), `${baseImage}
|
|
62260
62697
|
`);
|
|
62261
|
-
await import_promises5.default.writeFile(
|
|
62262
|
-
await import_promises5.default.writeFile(
|
|
62698
|
+
await import_promises5.default.writeFile(import_node_path42.default.join(dir, DOCKERFILE_PATH), renderDockerfile(personaId2, baseImage));
|
|
62699
|
+
await import_promises5.default.writeFile(import_node_path42.default.join(dir, DOCKERIGNORE_PATH), DOCKERIGNORE_TEMPLATE);
|
|
62263
62700
|
}
|
|
62264
62701
|
var RepoAlreadyExistsError = class extends RepoError {
|
|
62265
62702
|
constructor(slug) {
|
|
@@ -62298,7 +62735,7 @@ async function ensureRepo(exec, api, args) {
|
|
|
62298
62735
|
const existing = await repoInfo(exec, dir);
|
|
62299
62736
|
if (existing) return { created: false, url: existing.url };
|
|
62300
62737
|
await writeGitignore(dir);
|
|
62301
|
-
await import_promises5.default.rm(
|
|
62738
|
+
await import_promises5.default.rm(import_node_path42.default.join(dir, WORKFLOW_PATH), { force: true });
|
|
62302
62739
|
let created;
|
|
62303
62740
|
try {
|
|
62304
62741
|
created = await createOrgRepo(exec, api, { dir, org, repoName: personaId2, message: "clawd: \u4E0A\u4E91", auth: args.auth });
|
|
@@ -62516,9 +62953,9 @@ init_protocol();
|
|
|
62516
62953
|
|
|
62517
62954
|
// src/deploy/artifact.ts
|
|
62518
62955
|
var import_node_crypto13 = require("crypto");
|
|
62519
|
-
var
|
|
62520
|
-
var
|
|
62521
|
-
var
|
|
62956
|
+
var import_node_fs36 = __toESM(require("fs"), 1);
|
|
62957
|
+
var import_node_os13 = __toESM(require("os"), 1);
|
|
62958
|
+
var import_node_path43 = __toESM(require("path"), 1);
|
|
62522
62959
|
var import_node_stream3 = require("stream");
|
|
62523
62960
|
var import_promises6 = require("stream/promises");
|
|
62524
62961
|
var ARTIFACT_MAX_BYTES = 200 * 1024 * 1024;
|
|
@@ -62552,8 +62989,8 @@ function downloadArtifact(exec) {
|
|
|
62552
62989
|
if (!res.ok || !res.body) throw new Error(`\u4E0B\u8F7D\u5931\u8D25 HTTP ${res.status}\uFF1A${url}`);
|
|
62553
62990
|
const declared = Number(res.headers.get("content-length") ?? 0);
|
|
62554
62991
|
if (declared > ARTIFACT_MAX_BYTES) throw new Error(`\u8D44\u4EA7 ${declared} \u5B57\u8282\uFF0C\u8D85\u8FC7\u4E0A\u9650 ${ARTIFACT_MAX_BYTES}\uFF1A${url}`);
|
|
62555
|
-
const dir = await
|
|
62556
|
-
const file =
|
|
62992
|
+
const dir = await import_node_fs36.default.promises.mkdtemp(import_node_path43.default.join(import_node_os13.default.tmpdir(), "clawd-artifact-"));
|
|
62993
|
+
const file = import_node_path43.default.join(dir, "pkg");
|
|
62557
62994
|
const hash = (0, import_node_crypto13.createHash)("sha256");
|
|
62558
62995
|
let size = 0;
|
|
62559
62996
|
const meter = new import_node_stream3.Transform({
|
|
@@ -62565,7 +63002,7 @@ function downloadArtifact(exec) {
|
|
|
62565
63002
|
}
|
|
62566
63003
|
});
|
|
62567
63004
|
try {
|
|
62568
|
-
await (0, import_promises6.pipeline)(import_node_stream3.Readable.fromWeb(res.body), meter,
|
|
63005
|
+
await (0, import_promises6.pipeline)(import_node_stream3.Readable.fromWeb(res.body), meter, import_node_fs36.default.createWriteStream(file));
|
|
62569
63006
|
let entries;
|
|
62570
63007
|
if (listEntries) {
|
|
62571
63008
|
const r2 = await exec("tar", ["-tzf", file], { timeoutMs: 3e4 });
|
|
@@ -62574,7 +63011,7 @@ function downloadArtifact(exec) {
|
|
|
62574
63011
|
}
|
|
62575
63012
|
return { sha256: hash.digest("hex"), size, ...entries ? { entries } : {} };
|
|
62576
63013
|
} finally {
|
|
62577
|
-
await
|
|
63014
|
+
await import_node_fs36.default.promises.rm(dir, { recursive: true, force: true });
|
|
62578
63015
|
}
|
|
62579
63016
|
};
|
|
62580
63017
|
}
|
|
@@ -63136,6 +63573,7 @@ function buildDeployHandlers(deps) {
|
|
|
63136
63573
|
...publisherFeishuAuth ? { publisherFeishuAuth } : {},
|
|
63137
63574
|
targets,
|
|
63138
63575
|
promotions: file.promotions,
|
|
63576
|
+
...file.engineChannels ? { engineChannels: file.engineChannels } : {},
|
|
63139
63577
|
...repo2 ? { repo: repo2 } : {},
|
|
63140
63578
|
scans,
|
|
63141
63579
|
releases: file.releases,
|
|
@@ -63257,10 +63695,12 @@ function buildDeployHandlers(deps) {
|
|
|
63257
63695
|
const args = parseArgs2(DeploySetEngineAuthArgsSchema, frame, "deploy:setEngineAuth");
|
|
63258
63696
|
const dir = mustPersona(args.personaId);
|
|
63259
63697
|
let auth = args.auth;
|
|
63698
|
+
let channelSource = null;
|
|
63260
63699
|
if (args.channelId) {
|
|
63261
63700
|
const channel = deps.channelStore?.get(args.channelId);
|
|
63262
63701
|
if (!channel) throw invalid(`\u672A\u627E\u5230 ID \u4E3A ${args.channelId} \u7684\u8BA2\u9605\u901A\u9053`);
|
|
63263
63702
|
auth = { baseUrl: channel.baseUrl, apiKey: channel.apiKey };
|
|
63703
|
+
channelSource = { channelId: channel.id, updatedAt: channel.updatedAt };
|
|
63264
63704
|
}
|
|
63265
63705
|
let writes;
|
|
63266
63706
|
if (auth) {
|
|
@@ -63276,6 +63716,8 @@ function buildDeployHandlers(deps) {
|
|
|
63276
63716
|
writes = [[ENGINE_AUTH_SECRETS.apiKey, apiKey], [ENGINE_AUTH_SECRETS.baseUrl, baseUrl]];
|
|
63277
63717
|
}
|
|
63278
63718
|
const { api } = await requireGithub();
|
|
63719
|
+
const before = await readHistory(dir);
|
|
63720
|
+
await writeScanFile(dir, { ...before, engineChannels: { ...before.engineChannels, [args.environment]: null } });
|
|
63279
63721
|
try {
|
|
63280
63722
|
if (args.environment === "production") {
|
|
63281
63723
|
for (const env of [ENGINE_AUTH_SECRETS.baseUrl, ENGINE_AUTH_SECRETS.apiKey]) {
|
|
@@ -63286,6 +63728,8 @@ function buildDeployHandlers(deps) {
|
|
|
63286
63728
|
await deleteSecret(deps.exec, api, { dir, env: args.environment === "integration" ? "CLAWD_INT_" + ENGINE_AUTH_SECRETS.baseUrl : ENGINE_AUTH_SECRETS.baseUrl, environment: args.environment });
|
|
63287
63729
|
for (const [env, value] of writes) await setSecret(deps.exec, api, { dir, env: args.environment === "integration" ? "CLAWD_INT_" + env : env, value, environment: args.environment });
|
|
63288
63730
|
} else for (const env of [ENGINE_AUTH_SECRETS.apiKey, ENGINE_AUTH_SECRETS.baseUrl]) await deleteSecret(deps.exec, api, { dir, env: args.environment === "integration" ? "CLAWD_INT_" + env : env, environment: args.environment });
|
|
63731
|
+
const latest = await readHistory(dir);
|
|
63732
|
+
await writeScanFile(dir, { ...latest, engineChannels: { ...latest.engineChannels, [args.environment]: channelSource } });
|
|
63289
63733
|
} catch (err) {
|
|
63290
63734
|
throw toClawdError(err);
|
|
63291
63735
|
} finally {
|
|
@@ -63724,325 +64168,8 @@ function buildDeployHandlers(deps) {
|
|
|
63724
64168
|
var import_node_fs37 = __toESM(require("fs"), 1);
|
|
63725
64169
|
var import_node_os14 = __toESM(require("os"), 1);
|
|
63726
64170
|
var import_node_path44 = __toESM(require("path"), 1);
|
|
63727
|
-
|
|
63728
|
-
|
|
63729
|
-
var import_node_fs36 = __toESM(require("fs"), 1);
|
|
63730
|
-
var import_node_os13 = __toESM(require("os"), 1);
|
|
63731
|
-
var import_node_path43 = __toESM(require("path"), 1);
|
|
63732
|
-
|
|
63733
|
-
// src/tools/codex-config-toml.ts
|
|
63734
|
-
function parseKey(src, start) {
|
|
63735
|
-
const parts = [];
|
|
63736
|
-
let i2 = start;
|
|
63737
|
-
for (; ; ) {
|
|
63738
|
-
while (src[i2] === " " || src[i2] === " ") i2++;
|
|
63739
|
-
let part;
|
|
63740
|
-
if (src[i2] === '"') {
|
|
63741
|
-
let j2 = i2 + 1;
|
|
63742
|
-
while (j2 < src.length && src[j2] !== '"') j2 += src[j2] === "\\" ? 2 : 1;
|
|
63743
|
-
if (j2 >= src.length) return null;
|
|
63744
|
-
try {
|
|
63745
|
-
part = JSON.parse(src.slice(i2, j2 + 1));
|
|
63746
|
-
} catch {
|
|
63747
|
-
part = src.slice(i2 + 1, j2);
|
|
63748
|
-
}
|
|
63749
|
-
i2 = j2 + 1;
|
|
63750
|
-
} else if (src[i2] === "'") {
|
|
63751
|
-
const j2 = src.indexOf("'", i2 + 1);
|
|
63752
|
-
if (j2 < 0) return null;
|
|
63753
|
-
part = src.slice(i2 + 1, j2);
|
|
63754
|
-
i2 = j2 + 1;
|
|
63755
|
-
} else {
|
|
63756
|
-
const bare = /^[A-Za-z0-9_-]+/.exec(src.slice(i2));
|
|
63757
|
-
if (!bare) return null;
|
|
63758
|
-
part = bare[0];
|
|
63759
|
-
i2 += part.length;
|
|
63760
|
-
}
|
|
63761
|
-
parts.push(part);
|
|
63762
|
-
while (src[i2] === " " || src[i2] === " ") i2++;
|
|
63763
|
-
if (src[i2] !== ".") return { parts, end: i2 };
|
|
63764
|
-
i2++;
|
|
63765
|
-
}
|
|
63766
|
-
}
|
|
63767
|
-
function tableHeader(line) {
|
|
63768
|
-
const open = /^\s*(\[\[?)/.exec(line);
|
|
63769
|
-
if (!open) return null;
|
|
63770
|
-
const key = parseKey(line, open[0].length);
|
|
63771
|
-
if (!key) return null;
|
|
63772
|
-
const close = open[1] === "[[" ? "]]" : "]";
|
|
63773
|
-
if (!line.startsWith(close, key.end)) return null;
|
|
63774
|
-
return /^\s*(?:#.*)?$/.test(line.slice(key.end + close.length)) ? key.parts : null;
|
|
63775
|
-
}
|
|
63776
|
-
function keyLine(line) {
|
|
63777
|
-
const lead = /^\s*/.exec(line)[0].length;
|
|
63778
|
-
if (line[lead] === "[" || line[lead] === "#") return null;
|
|
63779
|
-
const key = parseKey(line, lead);
|
|
63780
|
-
return key && line[key.end] === "=" ? { parts: key.parts, valueStart: key.end + 1 } : null;
|
|
63781
|
-
}
|
|
63782
|
-
function scanValue(s2, start, st2) {
|
|
63783
|
-
let i2 = start;
|
|
63784
|
-
while (i2 < s2.length) {
|
|
63785
|
-
if (st2.ml) {
|
|
63786
|
-
if (st2.ml === '"""' && s2[i2] === "\\") {
|
|
63787
|
-
i2 += 2;
|
|
63788
|
-
continue;
|
|
63789
|
-
}
|
|
63790
|
-
if (s2.startsWith(st2.ml, i2)) {
|
|
63791
|
-
let j2 = i2 + 3;
|
|
63792
|
-
while (j2 < s2.length && j2 < i2 + 5 && s2[j2] === st2.ml[0]) j2++;
|
|
63793
|
-
st2.ml = null;
|
|
63794
|
-
i2 = j2;
|
|
63795
|
-
continue;
|
|
63796
|
-
}
|
|
63797
|
-
i2++;
|
|
63798
|
-
continue;
|
|
63799
|
-
}
|
|
63800
|
-
const c2 = s2[i2];
|
|
63801
|
-
if (c2 === "#") return;
|
|
63802
|
-
if (s2.startsWith('"""', i2) || s2.startsWith("'''", i2)) {
|
|
63803
|
-
st2.ml = s2.slice(i2, i2 + 3);
|
|
63804
|
-
i2 += 3;
|
|
63805
|
-
continue;
|
|
63806
|
-
}
|
|
63807
|
-
if (c2 === '"') {
|
|
63808
|
-
i2++;
|
|
63809
|
-
while (i2 < s2.length && s2[i2] !== '"') i2 += s2[i2] === "\\" ? 2 : 1;
|
|
63810
|
-
i2++;
|
|
63811
|
-
continue;
|
|
63812
|
-
}
|
|
63813
|
-
if (c2 === "'") {
|
|
63814
|
-
const j2 = s2.indexOf("'", i2 + 1);
|
|
63815
|
-
i2 = j2 < 0 ? s2.length : j2 + 1;
|
|
63816
|
-
continue;
|
|
63817
|
-
}
|
|
63818
|
-
if (c2 === "[" || c2 === "{") st2.depth++;
|
|
63819
|
-
else if ((c2 === "]" || c2 === "}") && st2.depth > 0) st2.depth--;
|
|
63820
|
-
i2++;
|
|
63821
|
-
}
|
|
63822
|
-
}
|
|
63823
|
-
function scanToml(text) {
|
|
63824
|
-
const out = [];
|
|
63825
|
-
const st2 = { ml: null, depth: 0 };
|
|
63826
|
-
let table = [];
|
|
63827
|
-
for (const line of text.split("\n")) {
|
|
63828
|
-
if (st2.ml || st2.depth > 0) {
|
|
63829
|
-
scanValue(line, 0, st2);
|
|
63830
|
-
out.push({ text: line, kind: "continuation", table });
|
|
63831
|
-
continue;
|
|
63832
|
-
}
|
|
63833
|
-
const header = tableHeader(line);
|
|
63834
|
-
if (header) {
|
|
63835
|
-
table = header;
|
|
63836
|
-
out.push({ text: line, kind: "header", table, key: header });
|
|
63837
|
-
continue;
|
|
63838
|
-
}
|
|
63839
|
-
const key = keyLine(line);
|
|
63840
|
-
if (key) {
|
|
63841
|
-
scanValue(line, key.valueStart, st2);
|
|
63842
|
-
out.push({ text: line, kind: "key", table, key: key.parts, value: line.slice(key.valueStart) });
|
|
63843
|
-
continue;
|
|
63844
|
-
}
|
|
63845
|
-
out.push({ text: line, kind: "other", table });
|
|
63846
|
-
}
|
|
63847
|
-
return out;
|
|
63848
|
-
}
|
|
63849
|
-
var UNREADABLE = /* @__PURE__ */ Symbol("unreadable TOML value");
|
|
63850
|
-
function parseTomlValue(raw) {
|
|
63851
|
-
const parsed = parseValueAt(raw, 0);
|
|
63852
|
-
if (!parsed) return void 0;
|
|
63853
|
-
return /^\s*(?:#[^\n]*)?\s*$/.test(raw.slice(parsed.end)) ? parsed.value : void 0;
|
|
63854
|
-
}
|
|
63855
|
-
function skipSeparators(s2, start) {
|
|
63856
|
-
let i2 = start;
|
|
63857
|
-
for (; ; ) {
|
|
63858
|
-
while (i2 < s2.length && " \r\n,".includes(s2[i2])) i2++;
|
|
63859
|
-
if (s2[i2] !== "#") return i2;
|
|
63860
|
-
const newline = s2.indexOf("\n", i2);
|
|
63861
|
-
i2 = newline < 0 ? s2.length : newline;
|
|
63862
|
-
}
|
|
63863
|
-
}
|
|
63864
|
-
function parseValueAt(s2, start) {
|
|
63865
|
-
let i2 = start;
|
|
63866
|
-
while (s2[i2] === " " || s2[i2] === " ") i2++;
|
|
63867
|
-
const c2 = s2[i2];
|
|
63868
|
-
if (c2 === '"') {
|
|
63869
|
-
if (s2.startsWith('"""', i2)) return null;
|
|
63870
|
-
let j2 = i2 + 1;
|
|
63871
|
-
while (j2 < s2.length && s2[j2] !== '"') j2 += s2[j2] === "\\" ? 2 : 1;
|
|
63872
|
-
if (j2 >= s2.length) return null;
|
|
63873
|
-
try {
|
|
63874
|
-
return { value: JSON.parse(s2.slice(i2, j2 + 1)), end: j2 + 1 };
|
|
63875
|
-
} catch {
|
|
63876
|
-
return null;
|
|
63877
|
-
}
|
|
63878
|
-
}
|
|
63879
|
-
if (c2 === "'") {
|
|
63880
|
-
if (s2.startsWith("'''", i2)) return null;
|
|
63881
|
-
const j2 = s2.indexOf("'", i2 + 1);
|
|
63882
|
-
return j2 < 0 ? null : { value: s2.slice(i2 + 1, j2), end: j2 + 1 };
|
|
63883
|
-
}
|
|
63884
|
-
if (c2 === "[") {
|
|
63885
|
-
const items = [];
|
|
63886
|
-
i2++;
|
|
63887
|
-
for (; ; ) {
|
|
63888
|
-
i2 = skipSeparators(s2, i2);
|
|
63889
|
-
if (s2[i2] === "]") return { value: items, end: i2 + 1 };
|
|
63890
|
-
const item = parseValueAt(s2, i2);
|
|
63891
|
-
if (!item) return null;
|
|
63892
|
-
items.push(item.value);
|
|
63893
|
-
i2 = item.end;
|
|
63894
|
-
}
|
|
63895
|
-
}
|
|
63896
|
-
if (c2 === "{") {
|
|
63897
|
-
const table = {};
|
|
63898
|
-
i2++;
|
|
63899
|
-
for (; ; ) {
|
|
63900
|
-
i2 = skipSeparators(s2, i2);
|
|
63901
|
-
if (s2[i2] === "}") return { value: table, end: i2 + 1 };
|
|
63902
|
-
const key = parseKey(s2, i2);
|
|
63903
|
-
if (!key || s2[key.end] !== "=") return null;
|
|
63904
|
-
const item = parseValueAt(s2, key.end + 1);
|
|
63905
|
-
if (!item) return null;
|
|
63906
|
-
setPath(table, key.parts, item.value);
|
|
63907
|
-
i2 = item.end;
|
|
63908
|
-
}
|
|
63909
|
-
}
|
|
63910
|
-
const bare = /^[^\s,\]}#]+/.exec(s2.slice(i2));
|
|
63911
|
-
return bare ? { value: bare[0], end: i2 + bare[0].length } : null;
|
|
63912
|
-
}
|
|
63913
|
-
function setPath(target, path110, value) {
|
|
63914
|
-
let node = target;
|
|
63915
|
-
for (const part of path110.slice(0, -1)) {
|
|
63916
|
-
const next = node[part];
|
|
63917
|
-
if (!next || typeof next !== "object" || Array.isArray(next)) node[part] = {};
|
|
63918
|
-
node = node[part];
|
|
63919
|
-
}
|
|
63920
|
-
const last = path110[path110.length - 1];
|
|
63921
|
-
const existing = node[last];
|
|
63922
|
-
if (existing && typeof existing === "object" && !Array.isArray(existing) && value && typeof value === "object" && !Array.isArray(value)) {
|
|
63923
|
-
Object.assign(existing, value);
|
|
63924
|
-
} else node[last] = value;
|
|
63925
|
-
}
|
|
63926
|
-
function readTomlTable(text, path110) {
|
|
63927
|
-
const result = {};
|
|
63928
|
-
let found = false;
|
|
63929
|
-
const within = (full) => full.length >= path110.length && path110.every((part, i2) => full[i2] === part);
|
|
63930
|
-
const lines = scanToml(text);
|
|
63931
|
-
for (let index = 0; index < lines.length; index++) {
|
|
63932
|
-
const line = lines[index];
|
|
63933
|
-
if (line.kind === "header" && within(line.key)) {
|
|
63934
|
-
found = true;
|
|
63935
|
-
if (line.key.length > path110.length) setPath(result, line.key.slice(path110.length), {});
|
|
63936
|
-
continue;
|
|
63937
|
-
}
|
|
63938
|
-
if (line.kind !== "key") continue;
|
|
63939
|
-
const full = [...line.table, ...line.key];
|
|
63940
|
-
if (!within(full)) continue;
|
|
63941
|
-
let raw = line.value;
|
|
63942
|
-
while (lines[index + 1]?.kind === "continuation") raw += `
|
|
63943
|
-
${lines[++index].text}`;
|
|
63944
|
-
const parsed = parseTomlValue(raw);
|
|
63945
|
-
const value = parsed === void 0 ? UNREADABLE : parsed;
|
|
63946
|
-
found = true;
|
|
63947
|
-
if (full.length === path110.length) {
|
|
63948
|
-
if (value && typeof value === "object" && !Array.isArray(value)) Object.assign(result, value);
|
|
63949
|
-
} else setPath(result, full.slice(path110.length), value);
|
|
63950
|
-
}
|
|
63951
|
-
return found ? result : null;
|
|
63952
|
-
}
|
|
63953
|
-
|
|
63954
|
-
// src/tools/subscription-channels-apply.ts
|
|
63955
|
-
var PROVIDER_ID = "cliproxyapi";
|
|
63956
|
-
var isOwnProvider = (path110) => path110[0] === "model_providers" && path110[1] === PROVIDER_ID;
|
|
63957
|
-
function stripCodexProvider(text) {
|
|
63958
|
-
const out = [];
|
|
63959
|
-
let dropping = false;
|
|
63960
|
-
let droppingValue = false;
|
|
63961
|
-
for (const line of scanToml(text)) {
|
|
63962
|
-
if (line.kind === "header") {
|
|
63963
|
-
dropping = isOwnProvider(line.key);
|
|
63964
|
-
droppingValue = false;
|
|
63965
|
-
if (!dropping) out.push(line.text);
|
|
63966
|
-
continue;
|
|
63967
|
-
}
|
|
63968
|
-
if (line.kind === "continuation") {
|
|
63969
|
-
if (!dropping && !droppingValue) out.push(line.text);
|
|
63970
|
-
continue;
|
|
63971
|
-
}
|
|
63972
|
-
if (dropping) continue;
|
|
63973
|
-
if (line.kind === "key") {
|
|
63974
|
-
const full = [...line.table, ...line.key];
|
|
63975
|
-
droppingValue = full.length === 1 && full[0] === "model_provider" || isOwnProvider(full);
|
|
63976
|
-
if (!droppingValue) out.push(line.text);
|
|
63977
|
-
continue;
|
|
63978
|
-
}
|
|
63979
|
-
out.push(line.text);
|
|
63980
|
-
}
|
|
63981
|
-
return out.join("\n").trim();
|
|
63982
|
-
}
|
|
63983
|
-
function writeFileAtomic(file, data) {
|
|
63984
|
-
const target = import_node_fs36.default.existsSync(file) && import_node_fs36.default.lstatSync(file).isSymbolicLink() ? import_node_fs36.default.realpathSync(file) : file;
|
|
63985
|
-
const tmp = `${target}.tmp.${process.pid}.${Date.now()}`;
|
|
63986
|
-
import_node_fs36.default.writeFileSync(tmp, data, { mode: 384 });
|
|
63987
|
-
import_node_fs36.default.renameSync(tmp, target);
|
|
63988
|
-
}
|
|
63989
|
-
function snapshotFile(file) {
|
|
63990
|
-
const original = import_node_fs36.default.existsSync(file) ? import_node_fs36.default.readFileSync(file) : null;
|
|
63991
|
-
return () => {
|
|
63992
|
-
const current = import_node_fs36.default.existsSync(file) ? import_node_fs36.default.readFileSync(file) : null;
|
|
63993
|
-
if (original === null) {
|
|
63994
|
-
if (current !== null) import_node_fs36.default.rmSync(file, { force: true });
|
|
63995
|
-
return;
|
|
63996
|
-
}
|
|
63997
|
-
if (current !== null && current.equals(original)) return;
|
|
63998
|
-
writeFileAtomic(file, original);
|
|
63999
|
-
};
|
|
64000
|
-
}
|
|
64001
|
-
var resolveCodexHome2 = (codexHome) => codexHome || process.env.CODEX_HOME || import_node_path43.default.join(import_node_os13.default.homedir(), ".codex");
|
|
64002
|
-
var resolvePiAgentDir = (agentDir) => agentDir || process.env.PI_CODING_AGENT_DIR || import_node_path43.default.join(import_node_os13.default.homedir(), ".pi", "agent");
|
|
64003
|
-
var PI_SUBSCRIPTION_FILE = "cliproxyapi.json";
|
|
64004
|
-
function applyCodexSubscriptionChannel(opts) {
|
|
64005
|
-
const codexHome = resolveCodexHome2(opts.codexHome);
|
|
64006
|
-
import_node_fs36.default.mkdirSync(codexHome, { recursive: true });
|
|
64007
|
-
const configFile = import_node_path43.default.join(codexHome, "config.toml");
|
|
64008
|
-
const original = import_node_fs36.default.existsSync(configFile) ? import_node_fs36.default.readFileSync(configFile, "utf8") : "";
|
|
64009
|
-
const rest = stripCodexProvider(original);
|
|
64010
|
-
let content;
|
|
64011
|
-
if (opts.channel) {
|
|
64012
|
-
const ch = opts.channel;
|
|
64013
|
-
content = [
|
|
64014
|
-
`model_provider = "${PROVIDER_ID}"`,
|
|
64015
|
-
...rest ? ["", rest] : [],
|
|
64016
|
-
"",
|
|
64017
|
-
`[model_providers.${PROVIDER_ID}]`,
|
|
64018
|
-
`name = "${PROVIDER_ID}"`,
|
|
64019
|
-
`base_url = ${JSON.stringify(ch.baseUrl)}`,
|
|
64020
|
-
'wire_api = "responses"',
|
|
64021
|
-
`auth = { command = "echo", args = [${JSON.stringify(ch.apiKey)}] }`,
|
|
64022
|
-
""
|
|
64023
|
-
].join("\n");
|
|
64024
|
-
} else {
|
|
64025
|
-
content = [
|
|
64026
|
-
'model_provider = "openai"',
|
|
64027
|
-
...rest ? ["", rest] : [],
|
|
64028
|
-
""
|
|
64029
|
-
].join("\n");
|
|
64030
|
-
}
|
|
64031
|
-
writeFileAtomic(configFile, content);
|
|
64032
|
-
}
|
|
64033
|
-
function applyPiSubscriptionChannel(opts) {
|
|
64034
|
-
const agentDir = resolvePiAgentDir(opts.agentDir);
|
|
64035
|
-
if (!import_node_fs36.default.existsSync(agentDir)) return false;
|
|
64036
|
-
const configFile = import_node_path43.default.join(agentDir, PI_SUBSCRIPTION_FILE);
|
|
64037
|
-
if (opts.channel) {
|
|
64038
|
-
const data = { baseUrl: opts.channel.baseUrl, apiKey: opts.channel.apiKey };
|
|
64039
|
-
writeFileAtomic(configFile, JSON.stringify(data, null, 2) + "\n");
|
|
64040
|
-
return true;
|
|
64041
|
-
}
|
|
64042
|
-
return false;
|
|
64043
|
-
}
|
|
64044
|
-
|
|
64045
|
-
// src/tools/subscription-channels-store.ts
|
|
64171
|
+
init_subscription_channels_apply();
|
|
64172
|
+
init_codex_config_toml();
|
|
64046
64173
|
var CHANNELS_FILE_NAME = "subscription-channels.json";
|
|
64047
64174
|
function providerKey(provider, codexHome) {
|
|
64048
64175
|
if ([provider.env_key, provider.experimental_bearer_token, provider.auth].includes(UNREADABLE)) return null;
|
|
@@ -64227,6 +64354,9 @@ var SubscriptionChannelStore = class {
|
|
|
64227
64354
|
}
|
|
64228
64355
|
};
|
|
64229
64356
|
|
|
64357
|
+
// src/index.ts
|
|
64358
|
+
init_subscription_channels_apply();
|
|
64359
|
+
|
|
64230
64360
|
// src/deploy/local-probe.ts
|
|
64231
64361
|
function pickVersion(s2) {
|
|
64232
64362
|
return /(\d+)\.(\d+)(?:\.(\d+))?/.exec(s2)?.[0];
|
|
@@ -65698,7 +65828,8 @@ function buildPersonaDispatchHandlers(deps) {
|
|
|
65698
65828
|
await deps.getCapabilities(args.tool);
|
|
65699
65829
|
}
|
|
65700
65830
|
if (args.model !== void 0) {
|
|
65701
|
-
const
|
|
65831
|
+
const caps = await deps.getCapabilities?.(effectiveTool);
|
|
65832
|
+
const allowed = caps ? caps.models.map((m3) => m3.id).filter((id) => id !== "") : effectiveTool === "claude" ? CLAUDE_MODEL_IDS : [];
|
|
65702
65833
|
if (!allowed.includes(args.model)) {
|
|
65703
65834
|
throw new ClawdError(
|
|
65704
65835
|
ERROR_CODES.INVALID_PARAM,
|
|
@@ -66918,16 +67049,22 @@ var PiAdapter = class {
|
|
|
66918
67049
|
probeCache = null;
|
|
66919
67050
|
// 进程级 memo,**回落结果同样缓存**(pi 没装时别每次开弹窗都 spawn 一次必然失败的子进程;同 codex)
|
|
66920
67051
|
capsPromise;
|
|
67052
|
+
capsRevision = 0;
|
|
66921
67053
|
windows = /* @__PURE__ */ new Map();
|
|
66922
67054
|
async probe() {
|
|
66923
67055
|
if (this.probeCache) return this.probeCache;
|
|
66924
67056
|
this.probeCache = this.opts.probeOverride ? await this.opts.probeOverride() : await probePi();
|
|
66925
67057
|
return this.probeCache;
|
|
66926
67058
|
}
|
|
67059
|
+
invalidateCapabilities() {
|
|
67060
|
+
this.capsRevision++;
|
|
67061
|
+
this.capsPromise = void 0;
|
|
67062
|
+
}
|
|
66927
67063
|
async capabilities(opts) {
|
|
66928
67064
|
if (opts?.refresh) {
|
|
67065
|
+
const revision = this.capsRevision;
|
|
66929
67066
|
const fresh = await this.loadCapabilities({ strict: true, refresh: true });
|
|
66930
|
-
this.capsPromise = Promise.resolve(fresh);
|
|
67067
|
+
if (revision === this.capsRevision) this.capsPromise = Promise.resolve(fresh);
|
|
66931
67068
|
return fresh;
|
|
66932
67069
|
}
|
|
66933
67070
|
if (!this.capsPromise) this.capsPromise = this.loadCapabilities({ strict: false, refresh: false });
|
|
@@ -73528,6 +73665,8 @@ function buildEngineHandlers(deps, overrides = {}) {
|
|
|
73528
73665
|
// src/handlers/channels.ts
|
|
73529
73666
|
var import_node_fs66 = __toESM(require("fs"), 1);
|
|
73530
73667
|
var import_node_path75 = __toESM(require("path"), 1);
|
|
73668
|
+
init_subscription_channels_apply();
|
|
73669
|
+
init_codex_provider_models();
|
|
73531
73670
|
function buildChannelsHandlers(deps) {
|
|
73532
73671
|
let queue = Promise.resolve();
|
|
73533
73672
|
const serialized = (fn) => (frame, context) => {
|
|
@@ -73540,6 +73679,12 @@ function buildChannelsHandlers(deps) {
|
|
|
73540
73679
|
async function transact(mutate) {
|
|
73541
73680
|
const codexHome = resolveCodexHome2(deps.codexHome);
|
|
73542
73681
|
const agentDir = resolvePiAgentDir(deps.agentDir);
|
|
73682
|
+
const claudeDir = resolveClaudeConfigDir(deps.claudeConfigDir);
|
|
73683
|
+
let restoreClaude;
|
|
73684
|
+
let restoreClaudeBackup;
|
|
73685
|
+
const invalidateModels = () => {
|
|
73686
|
+
for (const tool of ["codex", "claude", "pi"]) deps.manager.invalidateCapabilities(tool);
|
|
73687
|
+
};
|
|
73543
73688
|
const restoreStore = deps.store.snapshot();
|
|
73544
73689
|
const restoreCodex = snapshotFile(import_node_path75.default.join(codexHome, "config.toml"));
|
|
73545
73690
|
const restorePi = import_node_fs66.default.existsSync(agentDir) ? snapshotFile(import_node_path75.default.join(agentDir, PI_SUBSCRIPTION_FILE)) : null;
|
|
@@ -73548,6 +73693,8 @@ function buildChannelsHandlers(deps) {
|
|
|
73548
73693
|
next = mutate();
|
|
73549
73694
|
if (next === void 0) return;
|
|
73550
73695
|
if (next) {
|
|
73696
|
+
const commitStore = deps.store.snapshot();
|
|
73697
|
+
restoreStore();
|
|
73551
73698
|
try {
|
|
73552
73699
|
await fetchProviderModels({ baseUrl: next.baseUrl, headers: {
|
|
73553
73700
|
Accept: "application/json",
|
|
@@ -73558,14 +73705,21 @@ function buildChannelsHandlers(deps) {
|
|
|
73558
73705
|
const authFailed = /HTTP (401|403)\b/.test(message);
|
|
73559
73706
|
throw new Error(`${authFailed ? "\u8BA2\u9605 API \u9274\u6743\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5 API Key" : "\u8BA2\u9605 API \u9A8C\u8BC1\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u5730\u5740\u4E0E\u7F51\u7EDC"}\uFF1A${message}`);
|
|
73560
73707
|
}
|
|
73708
|
+
commitStore();
|
|
73561
73709
|
}
|
|
73710
|
+
restoreClaude = snapshotFile(import_node_path75.default.join(claudeDir, "settings.json"));
|
|
73711
|
+
restoreClaudeBackup = snapshotFile(import_node_path75.default.join(claudeDir, CLAUDE_SUBSCRIPTION_BACKUP));
|
|
73562
73712
|
applyCodexSubscriptionChannel({ codexHome, channel: next });
|
|
73563
73713
|
applyPiSubscriptionChannel({ agentDir, channel: next });
|
|
73564
|
-
|
|
73714
|
+
applyClaudeSubscriptionChannel({ configDir: claudeDir, channel: next });
|
|
73715
|
+
invalidateModels();
|
|
73565
73716
|
} catch (err) {
|
|
73566
73717
|
restoreStore();
|
|
73567
73718
|
restoreCodex();
|
|
73568
73719
|
restorePi?.();
|
|
73720
|
+
restoreClaude?.();
|
|
73721
|
+
restoreClaudeBackup?.();
|
|
73722
|
+
invalidateModels();
|
|
73569
73723
|
if (next?.id === "default-pool" && err instanceof Error && /HTTP 401/.test(err.message)) {
|
|
73570
73724
|
throw new Error("\u9ED8\u8BA4\u53F7\u6C60\u8BA4\u8BC1\u5931\u8D25\uFF08HTTP 401\uFF09\uFF1A\u8BF7\u7F16\u8F91\u300C\u9ED8\u8BA4\u56E2\u961F\u53F7\u6C60\u300D\u5E76\u91CD\u65B0\u586B\u5199\u53F7\u6C60 API Key\uFF0C\u518D\u8BBE\u4E3A\u5F53\u524D\u3002");
|
|
73571
73725
|
}
|
|
@@ -73598,8 +73752,10 @@ function buildChannelsHandlers(deps) {
|
|
|
73598
73752
|
return { response: { ok: true } };
|
|
73599
73753
|
});
|
|
73600
73754
|
const models = async (frame) => {
|
|
73601
|
-
parseArgs2(SubscriptionChannelModelsArgsSchema, frame, "subscriptionChannel:models");
|
|
73602
|
-
const active = deps.store.getActive();
|
|
73755
|
+
const args = parseArgs2(SubscriptionChannelModelsArgsSchema, frame, "subscriptionChannel:models");
|
|
73756
|
+
const active = args.channelId ? deps.store.get(args.channelId) : deps.store.getActive();
|
|
73757
|
+
if (args.channelId && !active) throw new Error("\u672A\u627E\u5230\u4E91\u7AEF\u9009\u7528\u7684\u8BA2\u9605\u901A\u9053\uFF0C\u8BF7\u5728\u53D1\u5E03\u9875\u91CD\u65B0\u9009\u62E9");
|
|
73758
|
+
if (active && args.updatedAt !== void 0 && args.updatedAt !== active.updatedAt) throw new Error("\u8BA2\u9605\u901A\u9053\u5DF2\u53D8\u66F4\uFF0C\u8BF7\u5728\u53D1\u5E03\u9875\u91CD\u65B0\u4FDD\u5B58\u4E91\u7AEF\u8BA2\u9605");
|
|
73603
73759
|
if (!active) return { response: { channelId: null, models: [] } };
|
|
73604
73760
|
const list = await fetchProviderModels(
|
|
73605
73761
|
{ baseUrl: active.baseUrl, headers: { Accept: "application/json", Authorization: `Bearer ${active.apiKey}` } },
|
|
@@ -74529,7 +74685,7 @@ function computeMethodAccess(args) {
|
|
|
74529
74685
|
}
|
|
74530
74686
|
|
|
74531
74687
|
// src/version.ts
|
|
74532
|
-
var version = "0.2.
|
|
74688
|
+
var version = "0.2.658".length > 0 ? "0.2.658" : "dev";
|
|
74533
74689
|
|
|
74534
74690
|
// src/cli-probe/probe.ts
|
|
74535
74691
|
var fs85 = __toESM(require("fs"), 1);
|
|
@@ -77142,7 +77298,10 @@ async function startDaemon(config) {
|
|
|
77142
77298
|
const personaStore = new PersonaStore(import_node_path88.default.join(config.dataDir, "personas"));
|
|
77143
77299
|
const subscriptionChannelStore = new SubscriptionChannelStore({ dataDir: config.dataDir });
|
|
77144
77300
|
const activeSubscriptionChannel = subscriptionChannelStore.getActive();
|
|
77145
|
-
if (activeSubscriptionChannel)
|
|
77301
|
+
if (activeSubscriptionChannel) {
|
|
77302
|
+
applyPiSubscriptionChannel({ channel: activeSubscriptionChannel });
|
|
77303
|
+
applyClaudeSubscriptionChannel({ channel: activeSubscriptionChannel });
|
|
77304
|
+
}
|
|
77146
77305
|
const usersRoot = import_node_path88.default.join(config.dataDir, "users");
|
|
77147
77306
|
const defaultsRoot = findDefaultsRoot(logger);
|
|
77148
77307
|
if (defaultsRoot) {
|
|
@@ -77551,6 +77710,7 @@ async function startDaemon(config) {
|
|
|
77551
77710
|
manager.attachObserver(observer);
|
|
77552
77711
|
deliverPendingRef = (sid) => manager.deliverPending(sid);
|
|
77553
77712
|
const claudeAdapter = config.mode === "tui" ? new ClaudeTuiAdapter({
|
|
77713
|
+
getSubscriptionChannel: () => subscriptionChannelStore.getActive(),
|
|
77554
77714
|
logger,
|
|
77555
77715
|
historyReader: new ClaudeHistoryReader(),
|
|
77556
77716
|
onPtyRegister: (tsid, pty) => manager.registerPty(tsid, pty),
|
|
@@ -77563,7 +77723,7 @@ async function startDaemon(config) {
|
|
|
77563
77723
|
onReady: (tsid) => manager.dispatchReadyDetected(tsid),
|
|
77564
77724
|
onScreenIdle: (tsid) => manager.notifyScreenIdle(tsid),
|
|
77565
77725
|
screenIdleProbeLogger
|
|
77566
|
-
}) : new ClaudeAdapter({ logger, historyReader: new ClaudeHistoryReader() });
|
|
77726
|
+
}) : new ClaudeAdapter({ logger, historyReader: new ClaudeHistoryReader(), getSubscriptionChannel: () => subscriptionChannelStore.getActive() });
|
|
77567
77727
|
const cloudGateway = new CloudGatewayClient({
|
|
77568
77728
|
getLoginPass: () => ownerIdentityStore.read()?.loginPass ?? null,
|
|
77569
77729
|
centralApi: config.clawosApi ?? DEFAULT_CLAWOS_API,
|