@clawos-dev/clawd 0.2.667 → 0.2.670
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 +192 -157
- package/dist/cli.cjs +328 -197
- package/dist/cloud-persona-conversations.html +71 -71
- package/dist/dispatch/mcp-server.cjs +174 -154
- package/dist/persona-defaults/persona-app-builder/mcp/clawd-app-builder/mcp-server.cjs +192 -157
- package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/mcp-server.cjs +192 -157
- package/dist/share-ui/assets/{guest-ep-uzh2e.js → guest-DrCklp9W.js} +135 -135
- package/dist/share-ui/guest.html +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -6209,7 +6209,7 @@ var init_environment_schemas = __esm({
|
|
|
6209
6209
|
});
|
|
6210
6210
|
|
|
6211
6211
|
// ../protocol/src/release-schemas.ts
|
|
6212
|
-
var DEPLOY_ENVIRONMENTS, DeployEnvironmentSchema, ImageDigestSchema, SourceCommitSchema, IntegrationEndpointSchema, PublisherTestReceiptSchema, VerificationSchema, VerifiedPersonaReleaseSchema, VerifiedBaseReleaseSchema;
|
|
6212
|
+
var DEPLOY_ENVIRONMENTS, DeployEnvironmentSchema, ImageDigestSchema, SourceCommitSchema, IntegrationEndpointSchema, PublisherTestReceiptSchema, VerificationSchema, DeployConfigSchema, VerifiedPersonaReleaseSchema, VerifiedBaseReleaseSchema;
|
|
6213
6213
|
var init_release_schemas = __esm({
|
|
6214
6214
|
"../protocol/src/release-schemas.ts"() {
|
|
6215
6215
|
"use strict";
|
|
@@ -6247,6 +6247,14 @@ var init_release_schemas = __esm({
|
|
|
6247
6247
|
verifiedAt: external_exports.string().refine((s2) => Number.isFinite(Date.parse(s2))),
|
|
6248
6248
|
test: PublisherTestReceiptSchema.optional()
|
|
6249
6249
|
}).strict();
|
|
6250
|
+
DeployConfigSchema = external_exports.object({
|
|
6251
|
+
engine: external_exports.string().min(1),
|
|
6252
|
+
model: external_exports.string(),
|
|
6253
|
+
effort: external_exports.string(),
|
|
6254
|
+
size: external_exports.string().min(1),
|
|
6255
|
+
cpu: external_exports.number().positive(),
|
|
6256
|
+
taskConcurrency: external_exports.number().int().positive()
|
|
6257
|
+
}).strict();
|
|
6250
6258
|
VerifiedPersonaReleaseSchema = external_exports.object({
|
|
6251
6259
|
version: external_exports.literal(1),
|
|
6252
6260
|
environment: external_exports.literal("integration"),
|
|
@@ -6256,6 +6264,7 @@ var init_release_schemas = __esm({
|
|
|
6256
6264
|
baseImage: ImageDigestSchema,
|
|
6257
6265
|
pipelineCommit: SourceCommitSchema,
|
|
6258
6266
|
repository: external_exports.string().regex(/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/),
|
|
6267
|
+
config: DeployConfigSchema.optional(),
|
|
6259
6268
|
verification: VerificationSchema.refine((v3) => v3.checks.includes("persona-smoke")),
|
|
6260
6269
|
test: PublisherTestSchema.optional()
|
|
6261
6270
|
}).strict().refine((record4) => {
|
|
@@ -6274,6 +6283,189 @@ var init_release_schemas = __esm({
|
|
|
6274
6283
|
}
|
|
6275
6284
|
});
|
|
6276
6285
|
|
|
6286
|
+
// ../protocol/src/tool-family.ts
|
|
6287
|
+
function isCodexFamily(tool) {
|
|
6288
|
+
return tool === "codex" || tool === CODEX_CLOUD_TOOL_ID;
|
|
6289
|
+
}
|
|
6290
|
+
function isPiFamily(tool) {
|
|
6291
|
+
return tool === PI_TOOL_ID || tool === PI_CLOUD_TOOL_ID;
|
|
6292
|
+
}
|
|
6293
|
+
function isCloudTool(tool) {
|
|
6294
|
+
return typeof tool === "string" && tool.length > CLOUD_TOOL_SUFFIX.length && tool.endsWith(CLOUD_TOOL_SUFFIX);
|
|
6295
|
+
}
|
|
6296
|
+
function isRpcAgentTool(tool) {
|
|
6297
|
+
return isCodexFamily(tool) || isPiFamily(tool);
|
|
6298
|
+
}
|
|
6299
|
+
var CLOUD_TOOL_SUFFIX, CODEX_CLOUD_TOOL_ID, CODEX_SERVICE_TIERS, CLAUDE_CLOUD_TOOL_ID, PI_TOOL_ID, PI_CLOUD_TOOL_ID;
|
|
6300
|
+
var init_tool_family = __esm({
|
|
6301
|
+
"../protocol/src/tool-family.ts"() {
|
|
6302
|
+
"use strict";
|
|
6303
|
+
CLOUD_TOOL_SUFFIX = "-cloud";
|
|
6304
|
+
CODEX_CLOUD_TOOL_ID = `codex${CLOUD_TOOL_SUFFIX}`;
|
|
6305
|
+
CODEX_SERVICE_TIERS = { standard: "default", fast: "priority" };
|
|
6306
|
+
CLAUDE_CLOUD_TOOL_ID = `claude${CLOUD_TOOL_SUFFIX}`;
|
|
6307
|
+
PI_TOOL_ID = "pi";
|
|
6308
|
+
PI_CLOUD_TOOL_ID = `${PI_TOOL_ID}${CLOUD_TOOL_SUFFIX}`;
|
|
6309
|
+
}
|
|
6310
|
+
});
|
|
6311
|
+
|
|
6312
|
+
// ../protocol/src/persona-schemas.ts
|
|
6313
|
+
var CodexServiceTierSchema, PERSONA_SIZES, PersonaSizeSchema, DEFAULT_PERSONA_SIZE, PERSONA_CPUS, PersonaCpuSchema, PERSONA_CPU_DEFAULTS, PersonaCloudEngineSchema, PersonaFileSchema, PersonaSkillSummarySchema, PersonaPluginSummarySchema, CodexSandboxSettingsSchema, PersonaSandboxSettingsSchema, PersonaInfoResponseSchema, PersonaCreateArgsSchema, PersonaIdArgsSchema, PersonaUpdateArgsSchema;
|
|
6314
|
+
var init_persona_schemas = __esm({
|
|
6315
|
+
"../protocol/src/persona-schemas.ts"() {
|
|
6316
|
+
"use strict";
|
|
6317
|
+
init_zod();
|
|
6318
|
+
init_release_schemas();
|
|
6319
|
+
init_tool_family();
|
|
6320
|
+
CodexServiceTierSchema = external_exports.enum([CODEX_SERVICE_TIERS.standard, CODEX_SERVICE_TIERS.fast]);
|
|
6321
|
+
PERSONA_SIZES = ["tiny", "small", "medium", "large", "xlarge"];
|
|
6322
|
+
PersonaSizeSchema = external_exports.enum(PERSONA_SIZES);
|
|
6323
|
+
DEFAULT_PERSONA_SIZE = "medium";
|
|
6324
|
+
PERSONA_CPUS = [0.5, 1, 2];
|
|
6325
|
+
PersonaCpuSchema = external_exports.number().refine((cpu) => PERSONA_CPUS.includes(cpu), "Unsupported CPU");
|
|
6326
|
+
PERSONA_CPU_DEFAULTS = { tiny: 0.5, small: 1, medium: 2, large: 2, xlarge: 2 };
|
|
6327
|
+
PersonaCloudEngineSchema = external_exports.object({
|
|
6328
|
+
model: external_exports.string().optional(),
|
|
6329
|
+
effort: external_exports.string().optional()
|
|
6330
|
+
}).strict();
|
|
6331
|
+
PersonaFileSchema = external_exports.object({
|
|
6332
|
+
personaId: external_exports.string(),
|
|
6333
|
+
label: external_exports.string(),
|
|
6334
|
+
model: external_exports.string().optional(),
|
|
6335
|
+
// 与 model 平行的第二个 session 默认值:reasoning effort。值域跟着 tool 走
|
|
6336
|
+
// (claude 是 '' | low | medium | high | xhigh | max,codex 是 per-model 档位),
|
|
6337
|
+
// 协议层保持 string,由消费侧按 capabilities 收窄。
|
|
6338
|
+
effort: external_exports.string().optional(),
|
|
6339
|
+
serviceTier: CodexServiceTierSchema.optional(),
|
|
6340
|
+
public: external_exports.boolean(),
|
|
6341
|
+
// 8-key set defined UI-side in `lib/session-icons.ts`; protocol stays plain string
|
|
6342
|
+
// for forward compatibility, consumer fallbacks to default when key not found.
|
|
6343
|
+
iconKey: external_exports.string().optional(),
|
|
6344
|
+
// Default engine binding for new sessions; missing values are consumed as claude.
|
|
6345
|
+
tool: external_exports.string().optional(),
|
|
6346
|
+
/** Cloud resource size is string-compatible in stored files and narrowed at update/deploy boundaries; local execution ignores it. */
|
|
6347
|
+
size: external_exports.string().optional(),
|
|
6348
|
+
cpu: external_exports.number().finite().optional(),
|
|
6349
|
+
/** Cloud task-Pod concurrency, validated at release. Local execution ignores it; changes apply on the next publication. */
|
|
6350
|
+
taskConcurrency: external_exports.number().int().positive().optional(),
|
|
6351
|
+
cloudEngine: PersonaCloudEngineSchema.optional(),
|
|
6352
|
+
createdAt: external_exports.number(),
|
|
6353
|
+
updatedAt: external_exports.number(),
|
|
6354
|
+
/** Registry-only cloud entry, with no local persona directory. Local key adds -cloud; gateway paths use cloud.personaId and the registered engine determines the cloud tool id. */
|
|
6355
|
+
cloud: external_exports.object({
|
|
6356
|
+
gatewayUrl: external_exports.string().min(1),
|
|
6357
|
+
personaId: external_exports.string().min(1),
|
|
6358
|
+
publishedByMe: external_exports.boolean().optional(),
|
|
6359
|
+
environment: DeployEnvironmentSchema.optional(),
|
|
6360
|
+
expectedImage: ImageDigestSchema.optional(),
|
|
6361
|
+
testReleaseId: external_exports.string().optional()
|
|
6362
|
+
}).strict().optional()
|
|
6363
|
+
}).strict();
|
|
6364
|
+
PersonaSkillSummarySchema = external_exports.object({
|
|
6365
|
+
// 目录名作为 skill name(对齐 CC:frontmatter `name:` 仅作 displayName 用)
|
|
6366
|
+
name: external_exports.string().min(1),
|
|
6367
|
+
description: external_exports.string().optional()
|
|
6368
|
+
});
|
|
6369
|
+
PersonaPluginSummarySchema = external_exports.object({
|
|
6370
|
+
id: external_exports.string().min(1)
|
|
6371
|
+
});
|
|
6372
|
+
CodexSandboxSettingsSchema = external_exports.object({
|
|
6373
|
+
// 额外可写的绝对路径或 ~ 路径(pnpm 工具链等);workspace(cwd) 和 userWorkDir 由 daemon 自动加,不用列。
|
|
6374
|
+
writableRoots: external_exports.array(external_exports.string()).optional(),
|
|
6375
|
+
// 禁读 glob(相对 workspace root 或绝对),如 ".secrets/**"、"**/*.env"。
|
|
6376
|
+
denyRead: external_exports.array(external_exports.string()).optional(),
|
|
6377
|
+
// true → 网络全放(*);false / 缺省 → 断网(fail-closed)。**「新建默认联网」不靠这里的缺省**,
|
|
6378
|
+
// 靠 persona 创建时就把 CODEX_SANDBOX_DEFAULT 物化进文件(见 PersonaManager.create)——
|
|
6379
|
+
// 缺省只在文件损坏这种异常路径上出现,那时断网是更安全的一侧。
|
|
6380
|
+
network: external_exports.boolean().optional()
|
|
6381
|
+
}).strict();
|
|
6382
|
+
PersonaSandboxSettingsSchema = external_exports.object({
|
|
6383
|
+
permissions: external_exports.object({
|
|
6384
|
+
defaultMode: external_exports.string().optional(),
|
|
6385
|
+
allow: external_exports.array(external_exports.string()).optional(),
|
|
6386
|
+
// deny 优先级最高;强制底座(persona 私密区)由 daemon compose 强制 union,owner 删不掉。
|
|
6387
|
+
deny: external_exports.array(external_exports.string()).optional()
|
|
6388
|
+
}).optional(),
|
|
6389
|
+
sandbox: external_exports.object({
|
|
6390
|
+
enabled: external_exports.boolean().optional(),
|
|
6391
|
+
autoAllowBashIfSandboxed: external_exports.boolean().optional(),
|
|
6392
|
+
allowUnsandboxedCommands: external_exports.boolean().optional(),
|
|
6393
|
+
// 命令前缀白名单(CC `sandbox.excludedCommands`):匹配的命令在沙箱外运行,
|
|
6394
|
+
// 用于需逃出沙箱的工具(如 'docker *' / 'aliyun *' 要访问宿主 socket / 凭证)。
|
|
6395
|
+
excludedCommands: external_exports.array(external_exports.string()).optional(),
|
|
6396
|
+
filesystem: external_exports.object({
|
|
6397
|
+
denyRead: external_exports.array(external_exports.string()).optional(),
|
|
6398
|
+
allowRead: external_exports.array(external_exports.string()).optional(),
|
|
6399
|
+
denyWrite: external_exports.array(external_exports.string()).optional(),
|
|
6400
|
+
allowWrite: external_exports.array(external_exports.string()).optional()
|
|
6401
|
+
}).optional(),
|
|
6402
|
+
network: external_exports.object({
|
|
6403
|
+
allowedDomains: external_exports.array(external_exports.string()).optional(),
|
|
6404
|
+
allowLocalBinding: external_exports.boolean().optional()
|
|
6405
|
+
}).optional()
|
|
6406
|
+
}).optional()
|
|
6407
|
+
});
|
|
6408
|
+
PersonaInfoResponseSchema = PersonaFileSchema.extend({
|
|
6409
|
+
// 人格 builtin 层:`<personaDir>/CLAUDE.md`(= AGENTS.md 镜像)。预装 persona 的这份是
|
|
6410
|
+
// daemon ship 的产品规格,每次 daemon 启动被覆盖回 bundle 版(personalityManaged 标记它)。
|
|
6411
|
+
personality: external_exports.string().optional(),
|
|
6412
|
+
// Owner-managed personality overlay survives daemon resource refreshes and is injected for owner and guest sessions. Empty text clears it.
|
|
6413
|
+
personalityLocal: external_exports.string().optional(),
|
|
6414
|
+
// Managed builtin personality is refreshed by daemon and shown read-only; user edits belong to the overlay. User-created persona files remain editable.
|
|
6415
|
+
personalityManaged: external_exports.boolean().optional(),
|
|
6416
|
+
// 仅 'persona:get' 携带;null = 文件不存在 / parse 失败;undefined = 不在该响应类型上
|
|
6417
|
+
skills: external_exports.array(PersonaSkillSummarySchema).optional(),
|
|
6418
|
+
// 仅 'persona:get' 携带;空数组 = 没启用任何插件 / settings.json 不存在;undefined = 不在该响应类型上
|
|
6419
|
+
plugins: external_exports.array(PersonaPluginSummarySchema).optional(),
|
|
6420
|
+
sandboxSettings: PersonaSandboxSettingsSchema.nullable().optional(),
|
|
6421
|
+
// 仅 'persona:get' 携带;null = codex-sandbox.json 不存在 / parse 失败。
|
|
6422
|
+
// UI 的「访客联网」开关读它(见 PersonaCardSettings)。
|
|
6423
|
+
codexSandbox: CodexSandboxSettingsSchema.nullable().optional()
|
|
6424
|
+
});
|
|
6425
|
+
PersonaCreateArgsSchema = external_exports.object({
|
|
6426
|
+
// Caller provides a safe slug, daemon adds persona-. Keep identity separate from the freely editable display label.
|
|
6427
|
+
slug: external_exports.string().regex(/^[a-z0-9]+(-[a-z0-9]+)*$/).max(32),
|
|
6428
|
+
label: external_exports.string().min(1),
|
|
6429
|
+
personality: external_exports.string(),
|
|
6430
|
+
model: external_exports.string().optional(),
|
|
6431
|
+
effort: external_exports.string().optional(),
|
|
6432
|
+
serviceTier: PersonaFileSchema.shape.serviceTier,
|
|
6433
|
+
tool: external_exports.string().optional(),
|
|
6434
|
+
public: external_exports.boolean().optional(),
|
|
6435
|
+
iconKey: external_exports.string().optional()
|
|
6436
|
+
}).strict();
|
|
6437
|
+
PersonaIdArgsSchema = external_exports.object({
|
|
6438
|
+
personaId: external_exports.string().min(1)
|
|
6439
|
+
});
|
|
6440
|
+
PersonaUpdateArgsSchema = external_exports.object({
|
|
6441
|
+
personaId: external_exports.string().min(1),
|
|
6442
|
+
patch: external_exports.object({
|
|
6443
|
+
label: external_exports.string().min(1).optional(),
|
|
6444
|
+
model: external_exports.string().optional(),
|
|
6445
|
+
effort: external_exports.string().optional(),
|
|
6446
|
+
serviceTier: PersonaFileSchema.shape.serviceTier,
|
|
6447
|
+
tool: external_exports.string().optional(),
|
|
6448
|
+
size: PersonaSizeSchema.optional(),
|
|
6449
|
+
cpu: PersonaCpuSchema.optional(),
|
|
6450
|
+
taskConcurrency: PersonaFileSchema.shape.taskConcurrency,
|
|
6451
|
+
// 整体替换(上云页每次交完整的 { model, effort });切 tool 不清它
|
|
6452
|
+
cloudEngine: PersonaCloudEngineSchema.optional(),
|
|
6453
|
+
personality: external_exports.string().optional(),
|
|
6454
|
+
// 人格补充层正文(见 PersonaInfoResponseSchema.personalityLocal)。与 personality 各写
|
|
6455
|
+
// 各层、互不影响;'' = 清空补充层。预装 persona 的编辑入口写的就是这个字段。
|
|
6456
|
+
personalityLocal: external_exports.string().optional(),
|
|
6457
|
+
public: external_exports.boolean().optional(),
|
|
6458
|
+
// pass `null` to clear; daemon strips the field from PersonaFile on null
|
|
6459
|
+
iconKey: external_exports.string().nullable().optional(),
|
|
6460
|
+
// codex guest 沙箱(落盘 .clawd/codex-sandbox.json,不在 PersonaFile 里)。与 personality
|
|
6461
|
+
// 同款分层写:handler 剥出来单独落盘,且**局部合并**——只带 network 的 patch 不能抹掉
|
|
6462
|
+
// owner 手配的 writableRoots / denyRead。
|
|
6463
|
+
codexSandbox: CodexSandboxSettingsSchema.optional()
|
|
6464
|
+
}).strict()
|
|
6465
|
+
}).strict();
|
|
6466
|
+
}
|
|
6467
|
+
});
|
|
6468
|
+
|
|
6277
6469
|
// ../protocol/src/deploy-schemas.ts
|
|
6278
6470
|
function latestProductionRelease(releases) {
|
|
6279
6471
|
return [...releases].reverse().find((r2) => (r2.environment ?? "production") === "production");
|
|
@@ -6314,10 +6506,20 @@ function cloudEngineSettings(p3) {
|
|
|
6314
6506
|
const src = tool === "claude" ? p3.cloudEngine ?? {} : p3;
|
|
6315
6507
|
return { tool, model: src.model ?? "", effort: src.effort ?? "" };
|
|
6316
6508
|
}
|
|
6509
|
+
function configOfPersona(p3) {
|
|
6510
|
+
const { tool, model, effort } = cloudEngineSettings(p3);
|
|
6511
|
+
const size = (p3.size ?? "").trim() || DEFAULT_PERSONA_SIZE;
|
|
6512
|
+
const cpu = p3.cpu ?? PERSONA_CPU_DEFAULTS[size] ?? PERSONA_CPU_DEFAULTS[DEFAULT_PERSONA_SIZE];
|
|
6513
|
+
return { engine: tool, model: model.trim(), effort: effort.trim(), size, cpu, taskConcurrency: p3.taskConcurrency ?? DEFAULT_TASK_CONCURRENCY };
|
|
6514
|
+
}
|
|
6515
|
+
function changedConfigKeys(a2, b3) {
|
|
6516
|
+
if (!a2 || !b3) return null;
|
|
6517
|
+
return CONFIG_KEYS.filter((key) => a2[key] !== b3[key]);
|
|
6518
|
+
}
|
|
6317
6519
|
function repoSlug(url) {
|
|
6318
6520
|
return url.trim().replace(/^git@[^:]+:/, "").replace(/^https?:\/\/[^/]+\//, "").replace(/\.git$/, "");
|
|
6319
6521
|
}
|
|
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, DeployLocalStateSchema, DeployPatchResultSchema, DeploySecretsResultSchema, DeployReleaseResultSchema, DeployPersonaArgsSchema, DeployGetArgsSchema, DeployScanArgsSchema, DeployReleaseArgsSchema, DeployConfirmTestArgsSchema, DeployPromoteArgsSchema, DeployOpenTestArgsSchema, DeployEnvironmentArgsSchema, DeployConfirmTestResultSchema, DeployPromoteResultSchema, DeployOpenTestResultSchema, DeployPatchArgsSchema, DeployPutSecretArgsSchema, DeploySetEngineAuthArgsSchema, DeployRerunJobArgsSchema, DeployReportFindingArgsSchema, DeployFinishScanArgsSchema, PERSONA_REPO_ORG;
|
|
6522
|
+
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, DeployLocalStateSchema, DeployPatchResultSchema, DeploySecretsResultSchema, DEPLOY_WORKFLOW_VERSION, DEFAULT_TASK_CONCURRENCY, CONFIG_KEYS, DeployReleaseResultSchema, DeployPersonaArgsSchema, DeployGetArgsSchema, DeployScanArgsSchema, DeployReleaseArgsSchema, DeployConfirmTestArgsSchema, DeployPromoteArgsSchema, DeployApplyConfigArgsSchema, DeployOpenTestArgsSchema, DeployEnvironmentArgsSchema, DeployConfirmTestResultSchema, DeployPromoteResultSchema, DeployOpenTestResultSchema, DeployPatchArgsSchema, DeployPutSecretArgsSchema, DeploySetEngineAuthArgsSchema, DeployRerunJobArgsSchema, DeployReportFindingArgsSchema, DeployFinishScanArgsSchema, PERSONA_REPO_ORG;
|
|
6321
6523
|
var init_deploy_schemas = __esm({
|
|
6322
6524
|
"../protocol/src/deploy-schemas.ts"() {
|
|
6323
6525
|
"use strict";
|
|
@@ -6325,6 +6527,7 @@ var init_deploy_schemas = __esm({
|
|
|
6325
6527
|
init_github_auth_schemas();
|
|
6326
6528
|
init_environment_schemas();
|
|
6327
6529
|
init_release_schemas();
|
|
6530
|
+
init_persona_schemas();
|
|
6328
6531
|
DeployFileSchema = external_exports.object({
|
|
6329
6532
|
version: external_exports.literal(1),
|
|
6330
6533
|
manifest: EnvironmentManifestSchema
|
|
@@ -6365,6 +6568,12 @@ var init_deploy_schemas = __esm({
|
|
|
6365
6568
|
runAttempt: external_exports.number().int().positive().optional(),
|
|
6366
6569
|
artifactId: external_exports.number().int().positive().optional(),
|
|
6367
6570
|
verified: VerifiedPersonaReleaseSchema.optional(),
|
|
6571
|
+
/** 这一轮测试用的配置(design 2026-10-14-deploy-config-decouple §3.1);老记录没有,按「发布时 commit 里的 persona.json」算 */
|
|
6572
|
+
config: DeployConfigSchema.optional(),
|
|
6573
|
+
/** 「应用配置」产生的记录:复用的是哪条测试发布的镜像(它的 id)。首次构建的记录没有 */
|
|
6574
|
+
reconfigOf: external_exports.string().min(1).optional(),
|
|
6575
|
+
/** 发布时写进仓库的 workflow 模板版本;缺 = 老模板(不认 config_json 输入,要先完整重发一次) */
|
|
6576
|
+
workflowVersion: external_exports.number().int().positive().optional(),
|
|
6368
6577
|
confirmation: external_exports.object({
|
|
6369
6578
|
fingerprint: external_exports.string().regex(/^[a-f0-9]{64}$/),
|
|
6370
6579
|
runId: external_exports.number().int().positive(),
|
|
@@ -6516,6 +6725,9 @@ var init_deploy_schemas = __esm({
|
|
|
6516
6725
|
secrets: external_exports.array(DeploySecretPresenceSchema).optional(),
|
|
6517
6726
|
engineChannels: DeployEngineChannelsSchema.optional()
|
|
6518
6727
|
}).strict();
|
|
6728
|
+
DEPLOY_WORKFLOW_VERSION = 2;
|
|
6729
|
+
DEFAULT_TASK_CONCURRENCY = 4;
|
|
6730
|
+
CONFIG_KEYS = ["engine", "model", "effort", "size", "cpu", "taskConcurrency"];
|
|
6519
6731
|
DeployReleaseResultSchema = external_exports.object({
|
|
6520
6732
|
sha: external_exports.string().min(1),
|
|
6521
6733
|
actionsUrl: external_exports.string().min(1),
|
|
@@ -6537,6 +6749,7 @@ var init_deploy_schemas = __esm({
|
|
|
6537
6749
|
}).strict();
|
|
6538
6750
|
DeployConfirmTestArgsSchema = DeployPersonaArgsSchema.extend({ releaseId: external_exports.string().min(1) }).strict();
|
|
6539
6751
|
DeployPromoteArgsSchema = DeployConfirmTestArgsSchema;
|
|
6752
|
+
DeployApplyConfigArgsSchema = DeployConfirmTestArgsSchema;
|
|
6540
6753
|
DeployOpenTestArgsSchema = DeployConfirmTestArgsSchema;
|
|
6541
6754
|
DeployEnvironmentArgsSchema = DeployPersonaArgsSchema.extend({ environment: DeployEnvironmentSchema.default("production") }).strict();
|
|
6542
6755
|
DeployConfirmTestResultSchema = external_exports.object({ confirmation: DeployReleasedSchema.shape.confirmation.unwrap() }).strict();
|
|
@@ -7773,187 +7986,6 @@ var init_dashboard_schemas = __esm({
|
|
|
7773
7986
|
}
|
|
7774
7987
|
});
|
|
7775
7988
|
|
|
7776
|
-
// ../protocol/src/tool-family.ts
|
|
7777
|
-
function isCodexFamily(tool) {
|
|
7778
|
-
return tool === "codex" || tool === CODEX_CLOUD_TOOL_ID;
|
|
7779
|
-
}
|
|
7780
|
-
function isPiFamily(tool) {
|
|
7781
|
-
return tool === PI_TOOL_ID || tool === PI_CLOUD_TOOL_ID;
|
|
7782
|
-
}
|
|
7783
|
-
function isCloudTool(tool) {
|
|
7784
|
-
return typeof tool === "string" && tool.length > CLOUD_TOOL_SUFFIX.length && tool.endsWith(CLOUD_TOOL_SUFFIX);
|
|
7785
|
-
}
|
|
7786
|
-
function isRpcAgentTool(tool) {
|
|
7787
|
-
return isCodexFamily(tool) || isPiFamily(tool);
|
|
7788
|
-
}
|
|
7789
|
-
var CLOUD_TOOL_SUFFIX, CODEX_CLOUD_TOOL_ID, CODEX_SERVICE_TIERS, CLAUDE_CLOUD_TOOL_ID, PI_TOOL_ID, PI_CLOUD_TOOL_ID;
|
|
7790
|
-
var init_tool_family = __esm({
|
|
7791
|
-
"../protocol/src/tool-family.ts"() {
|
|
7792
|
-
"use strict";
|
|
7793
|
-
CLOUD_TOOL_SUFFIX = "-cloud";
|
|
7794
|
-
CODEX_CLOUD_TOOL_ID = `codex${CLOUD_TOOL_SUFFIX}`;
|
|
7795
|
-
CODEX_SERVICE_TIERS = { standard: "default", fast: "priority" };
|
|
7796
|
-
CLAUDE_CLOUD_TOOL_ID = `claude${CLOUD_TOOL_SUFFIX}`;
|
|
7797
|
-
PI_TOOL_ID = "pi";
|
|
7798
|
-
PI_CLOUD_TOOL_ID = `${PI_TOOL_ID}${CLOUD_TOOL_SUFFIX}`;
|
|
7799
|
-
}
|
|
7800
|
-
});
|
|
7801
|
-
|
|
7802
|
-
// ../protocol/src/persona-schemas.ts
|
|
7803
|
-
var CodexServiceTierSchema, PERSONA_SIZES, PersonaSizeSchema, PERSONA_CPUS, PersonaCpuSchema, PersonaCloudEngineSchema, PersonaFileSchema, PersonaSkillSummarySchema, PersonaPluginSummarySchema, CodexSandboxSettingsSchema, PersonaSandboxSettingsSchema, PersonaInfoResponseSchema, PersonaCreateArgsSchema, PersonaIdArgsSchema, PersonaUpdateArgsSchema;
|
|
7804
|
-
var init_persona_schemas = __esm({
|
|
7805
|
-
"../protocol/src/persona-schemas.ts"() {
|
|
7806
|
-
"use strict";
|
|
7807
|
-
init_zod();
|
|
7808
|
-
init_release_schemas();
|
|
7809
|
-
init_tool_family();
|
|
7810
|
-
CodexServiceTierSchema = external_exports.enum([CODEX_SERVICE_TIERS.standard, CODEX_SERVICE_TIERS.fast]);
|
|
7811
|
-
PERSONA_SIZES = ["tiny", "small", "medium", "large", "xlarge"];
|
|
7812
|
-
PersonaSizeSchema = external_exports.enum(PERSONA_SIZES);
|
|
7813
|
-
PERSONA_CPUS = [0.5, 1, 2];
|
|
7814
|
-
PersonaCpuSchema = external_exports.number().refine((cpu) => PERSONA_CPUS.includes(cpu), "Unsupported CPU");
|
|
7815
|
-
PersonaCloudEngineSchema = external_exports.object({
|
|
7816
|
-
model: external_exports.string().optional(),
|
|
7817
|
-
effort: external_exports.string().optional()
|
|
7818
|
-
}).strict();
|
|
7819
|
-
PersonaFileSchema = external_exports.object({
|
|
7820
|
-
personaId: external_exports.string(),
|
|
7821
|
-
label: external_exports.string(),
|
|
7822
|
-
model: external_exports.string().optional(),
|
|
7823
|
-
// 与 model 平行的第二个 session 默认值:reasoning effort。值域跟着 tool 走
|
|
7824
|
-
// (claude 是 '' | low | medium | high | xhigh | max,codex 是 per-model 档位),
|
|
7825
|
-
// 协议层保持 string,由消费侧按 capabilities 收窄。
|
|
7826
|
-
effort: external_exports.string().optional(),
|
|
7827
|
-
serviceTier: CodexServiceTierSchema.optional(),
|
|
7828
|
-
public: external_exports.boolean(),
|
|
7829
|
-
// 8-key set defined UI-side in `lib/session-icons.ts`; protocol stays plain string
|
|
7830
|
-
// for forward compatibility, consumer fallbacks to default when key not found.
|
|
7831
|
-
iconKey: external_exports.string().optional(),
|
|
7832
|
-
// Default engine binding for new sessions; missing values are consumed as claude.
|
|
7833
|
-
tool: external_exports.string().optional(),
|
|
7834
|
-
/** Cloud resource size is string-compatible in stored files and narrowed at update/deploy boundaries; local execution ignores it. */
|
|
7835
|
-
size: external_exports.string().optional(),
|
|
7836
|
-
cpu: external_exports.number().finite().optional(),
|
|
7837
|
-
/** Cloud task-Pod concurrency, validated at release. Local execution ignores it; changes apply on the next publication. */
|
|
7838
|
-
taskConcurrency: external_exports.number().int().positive().optional(),
|
|
7839
|
-
cloudEngine: PersonaCloudEngineSchema.optional(),
|
|
7840
|
-
createdAt: external_exports.number(),
|
|
7841
|
-
updatedAt: external_exports.number(),
|
|
7842
|
-
/** Registry-only cloud entry, with no local persona directory. Local key adds -cloud; gateway paths use cloud.personaId and the registered engine determines the cloud tool id. */
|
|
7843
|
-
cloud: external_exports.object({
|
|
7844
|
-
gatewayUrl: external_exports.string().min(1),
|
|
7845
|
-
personaId: external_exports.string().min(1),
|
|
7846
|
-
publishedByMe: external_exports.boolean().optional(),
|
|
7847
|
-
environment: DeployEnvironmentSchema.optional(),
|
|
7848
|
-
expectedImage: ImageDigestSchema.optional(),
|
|
7849
|
-
testReleaseId: external_exports.string().optional()
|
|
7850
|
-
}).strict().optional()
|
|
7851
|
-
}).strict();
|
|
7852
|
-
PersonaSkillSummarySchema = external_exports.object({
|
|
7853
|
-
// 目录名作为 skill name(对齐 CC:frontmatter `name:` 仅作 displayName 用)
|
|
7854
|
-
name: external_exports.string().min(1),
|
|
7855
|
-
description: external_exports.string().optional()
|
|
7856
|
-
});
|
|
7857
|
-
PersonaPluginSummarySchema = external_exports.object({
|
|
7858
|
-
id: external_exports.string().min(1)
|
|
7859
|
-
});
|
|
7860
|
-
CodexSandboxSettingsSchema = external_exports.object({
|
|
7861
|
-
// 额外可写的绝对路径或 ~ 路径(pnpm 工具链等);workspace(cwd) 和 userWorkDir 由 daemon 自动加,不用列。
|
|
7862
|
-
writableRoots: external_exports.array(external_exports.string()).optional(),
|
|
7863
|
-
// 禁读 glob(相对 workspace root 或绝对),如 ".secrets/**"、"**/*.env"。
|
|
7864
|
-
denyRead: external_exports.array(external_exports.string()).optional(),
|
|
7865
|
-
// true → 网络全放(*);false / 缺省 → 断网(fail-closed)。**「新建默认联网」不靠这里的缺省**,
|
|
7866
|
-
// 靠 persona 创建时就把 CODEX_SANDBOX_DEFAULT 物化进文件(见 PersonaManager.create)——
|
|
7867
|
-
// 缺省只在文件损坏这种异常路径上出现,那时断网是更安全的一侧。
|
|
7868
|
-
network: external_exports.boolean().optional()
|
|
7869
|
-
}).strict();
|
|
7870
|
-
PersonaSandboxSettingsSchema = external_exports.object({
|
|
7871
|
-
permissions: external_exports.object({
|
|
7872
|
-
defaultMode: external_exports.string().optional(),
|
|
7873
|
-
allow: external_exports.array(external_exports.string()).optional(),
|
|
7874
|
-
// deny 优先级最高;强制底座(persona 私密区)由 daemon compose 强制 union,owner 删不掉。
|
|
7875
|
-
deny: external_exports.array(external_exports.string()).optional()
|
|
7876
|
-
}).optional(),
|
|
7877
|
-
sandbox: external_exports.object({
|
|
7878
|
-
enabled: external_exports.boolean().optional(),
|
|
7879
|
-
autoAllowBashIfSandboxed: external_exports.boolean().optional(),
|
|
7880
|
-
allowUnsandboxedCommands: external_exports.boolean().optional(),
|
|
7881
|
-
// 命令前缀白名单(CC `sandbox.excludedCommands`):匹配的命令在沙箱外运行,
|
|
7882
|
-
// 用于需逃出沙箱的工具(如 'docker *' / 'aliyun *' 要访问宿主 socket / 凭证)。
|
|
7883
|
-
excludedCommands: external_exports.array(external_exports.string()).optional(),
|
|
7884
|
-
filesystem: external_exports.object({
|
|
7885
|
-
denyRead: external_exports.array(external_exports.string()).optional(),
|
|
7886
|
-
allowRead: external_exports.array(external_exports.string()).optional(),
|
|
7887
|
-
denyWrite: external_exports.array(external_exports.string()).optional(),
|
|
7888
|
-
allowWrite: external_exports.array(external_exports.string()).optional()
|
|
7889
|
-
}).optional(),
|
|
7890
|
-
network: external_exports.object({
|
|
7891
|
-
allowedDomains: external_exports.array(external_exports.string()).optional(),
|
|
7892
|
-
allowLocalBinding: external_exports.boolean().optional()
|
|
7893
|
-
}).optional()
|
|
7894
|
-
}).optional()
|
|
7895
|
-
});
|
|
7896
|
-
PersonaInfoResponseSchema = PersonaFileSchema.extend({
|
|
7897
|
-
// 人格 builtin 层:`<personaDir>/CLAUDE.md`(= AGENTS.md 镜像)。预装 persona 的这份是
|
|
7898
|
-
// daemon ship 的产品规格,每次 daemon 启动被覆盖回 bundle 版(personalityManaged 标记它)。
|
|
7899
|
-
personality: external_exports.string().optional(),
|
|
7900
|
-
// Owner-managed personality overlay survives daemon resource refreshes and is injected for owner and guest sessions. Empty text clears it.
|
|
7901
|
-
personalityLocal: external_exports.string().optional(),
|
|
7902
|
-
// Managed builtin personality is refreshed by daemon and shown read-only; user edits belong to the overlay. User-created persona files remain editable.
|
|
7903
|
-
personalityManaged: external_exports.boolean().optional(),
|
|
7904
|
-
// 仅 'persona:get' 携带;null = 文件不存在 / parse 失败;undefined = 不在该响应类型上
|
|
7905
|
-
skills: external_exports.array(PersonaSkillSummarySchema).optional(),
|
|
7906
|
-
// 仅 'persona:get' 携带;空数组 = 没启用任何插件 / settings.json 不存在;undefined = 不在该响应类型上
|
|
7907
|
-
plugins: external_exports.array(PersonaPluginSummarySchema).optional(),
|
|
7908
|
-
sandboxSettings: PersonaSandboxSettingsSchema.nullable().optional(),
|
|
7909
|
-
// 仅 'persona:get' 携带;null = codex-sandbox.json 不存在 / parse 失败。
|
|
7910
|
-
// UI 的「访客联网」开关读它(见 PersonaCardSettings)。
|
|
7911
|
-
codexSandbox: CodexSandboxSettingsSchema.nullable().optional()
|
|
7912
|
-
});
|
|
7913
|
-
PersonaCreateArgsSchema = external_exports.object({
|
|
7914
|
-
// Caller provides a safe slug, daemon adds persona-. Keep identity separate from the freely editable display label.
|
|
7915
|
-
slug: external_exports.string().regex(/^[a-z0-9]+(-[a-z0-9]+)*$/).max(32),
|
|
7916
|
-
label: external_exports.string().min(1),
|
|
7917
|
-
personality: external_exports.string(),
|
|
7918
|
-
model: external_exports.string().optional(),
|
|
7919
|
-
effort: external_exports.string().optional(),
|
|
7920
|
-
serviceTier: PersonaFileSchema.shape.serviceTier,
|
|
7921
|
-
tool: external_exports.string().optional(),
|
|
7922
|
-
public: external_exports.boolean().optional(),
|
|
7923
|
-
iconKey: external_exports.string().optional()
|
|
7924
|
-
}).strict();
|
|
7925
|
-
PersonaIdArgsSchema = external_exports.object({
|
|
7926
|
-
personaId: external_exports.string().min(1)
|
|
7927
|
-
});
|
|
7928
|
-
PersonaUpdateArgsSchema = external_exports.object({
|
|
7929
|
-
personaId: external_exports.string().min(1),
|
|
7930
|
-
patch: external_exports.object({
|
|
7931
|
-
label: external_exports.string().min(1).optional(),
|
|
7932
|
-
model: external_exports.string().optional(),
|
|
7933
|
-
effort: external_exports.string().optional(),
|
|
7934
|
-
serviceTier: PersonaFileSchema.shape.serviceTier,
|
|
7935
|
-
tool: external_exports.string().optional(),
|
|
7936
|
-
size: PersonaSizeSchema.optional(),
|
|
7937
|
-
cpu: PersonaCpuSchema.optional(),
|
|
7938
|
-
taskConcurrency: PersonaFileSchema.shape.taskConcurrency,
|
|
7939
|
-
// 整体替换(上云页每次交完整的 { model, effort });切 tool 不清它
|
|
7940
|
-
cloudEngine: PersonaCloudEngineSchema.optional(),
|
|
7941
|
-
personality: external_exports.string().optional(),
|
|
7942
|
-
// 人格补充层正文(见 PersonaInfoResponseSchema.personalityLocal)。与 personality 各写
|
|
7943
|
-
// 各层、互不影响;'' = 清空补充层。预装 persona 的编辑入口写的就是这个字段。
|
|
7944
|
-
personalityLocal: external_exports.string().optional(),
|
|
7945
|
-
public: external_exports.boolean().optional(),
|
|
7946
|
-
// pass `null` to clear; daemon strips the field from PersonaFile on null
|
|
7947
|
-
iconKey: external_exports.string().nullable().optional(),
|
|
7948
|
-
// codex guest 沙箱(落盘 .clawd/codex-sandbox.json,不在 PersonaFile 里)。与 personality
|
|
7949
|
-
// 同款分层写:handler 剥出来单独落盘,且**局部合并**——只带 network 的 patch 不能抹掉
|
|
7950
|
-
// owner 手配的 writableRoots / denyRead。
|
|
7951
|
-
codexSandbox: CodexSandboxSettingsSchema.optional()
|
|
7952
|
-
}).strict()
|
|
7953
|
-
}).strict();
|
|
7954
|
-
}
|
|
7955
|
-
});
|
|
7956
|
-
|
|
7957
7989
|
// ../protocol/src/events.ts
|
|
7958
7990
|
var DAEMON_MODE_VALUES, CLOUD_HISTORY_REFRESH_KIND, SESSION_STATUS_VALUES, HISTORY_USER_META_VALUES, SKILL_SOURCE_VALUES, AGENT_SOURCE_VALUES, ASK_USER_QUESTION_TOOL_NAME;
|
|
7959
7991
|
var init_events = __esm({
|
|
@@ -9112,6 +9144,10 @@ var init_methods = __esm({
|
|
|
9112
9144
|
summary: "\u786E\u8BA4\u6240\u9009\u6D4B\u8BD5\u7248\u901A\u8FC7\u5B9E\u9645\u8BD5\u7528\uFF1B\u6309\u5DF2\u4FDD\u5B58\u5236\u54C1\u548C\u6D4B\u8BD5\u767B\u8BB0\u6821\u9A8C\uFF0Cowner-only\u3001human-only",
|
|
9113
9145
|
args: DeployConfirmTestArgsSchema
|
|
9114
9146
|
},
|
|
9147
|
+
"deploy:applyConfig": {
|
|
9148
|
+
summary: "\u628A releaseId \u90A3\u6761\u6D4B\u8BD5\u53D1\u5E03\u7684**\u955C\u50CF**\u6362\u4E0A persona \u5F53\u524D\u7684\u5F15\u64CE / \u6A21\u578B / \u8D44\u6E90\u914D\u7F6E\uFF0C\u5728\u6D4B\u8BD5\u73AF\u5883\u91CD\u6D4B\u4E00\u904D\uFF1A\u4E0D\u626B\u63CF\u3001\u4E0D\u6784\u5EFA\uFF0C\u6D41\u6C34\u7EBF\u8D70 smoke \u2192 \u767B\u8BB0 \u2192 \u9A8C\u8BC1\u3002\u524D\u7F6E\uFF1A\u90A3\u6761\u53D1\u5E03\u5DF2\u63A8\u9001\u5E76\u901A\u8FC7\u9A8C\u8BC1\uFF0C\u4E14\u4ED3\u5E93\u91CC\u7684 workflow \u6A21\u677F\u591F\u65B0\uFF08\u7F3A config_json \u8F93\u5165\u7684\u8981\u5148\u300C\u53D1\u5E03\u5230\u6D4B\u8BD5\u300D\u5B8C\u6574\u91CD\u53D1\u4E00\u6B21\uFF09\uFF1B\u8FC7\u4E0E\u53D1\u5E03\u540C\u4E00\u5957\u95F8\uFF08\u9009\u4E86\u6A21\u578B\u3001\u8BA2\u9605\u51ED\u636E\u6210\u5BF9\u7B49\uFF09\u3002\u56DE\u65B0\u6D4B\u8BD5\u53D1\u5E03\u7684 commit \u4E0E Actions \u5730\u5740\uFF1B\u4E4B\u540E\u8D70\u5E38\u89C4\u7684\u6D4B\u8BD5\u786E\u8BA4 / \u664B\u7EA7\uFF1Bowner-only\u3001human-only",
|
|
9149
|
+
args: DeployApplyConfigArgsSchema
|
|
9150
|
+
},
|
|
9115
9151
|
"deploy:promote": {
|
|
9116
9152
|
summary: "\u5C06\u5DF2\u786E\u8BA4\u6D4B\u8BD5\u7248\u7684\u63D0\u4EA4\u63A8\u8FDB main \u5E76\u4E0A\u7EBF\u76F8\u540C\u955C\u50CF\uFF1B\u6062\u590D\u4E2D\u65AD\u7684\u540C\u4E00\u6B21\u664B\u7EA7\uFF0Cowner-only\u3001human-only",
|
|
9117
9153
|
args: DeployPromoteArgsSchema
|
|
@@ -45606,10 +45642,14 @@ var import_node_crypto = require("crypto");
|
|
|
45606
45642
|
|
|
45607
45643
|
// src/tools/codex-app-server-client.ts
|
|
45608
45644
|
var import_node_readline = require("readline");
|
|
45609
|
-
function stdioLineStream(proc) {
|
|
45645
|
+
function stdioLineStream(proc, opts = {}) {
|
|
45610
45646
|
const rl = (0, import_node_readline.createInterface)({ input: proc.stdout, crlfDelay: Infinity });
|
|
45611
45647
|
const lineCbs = [];
|
|
45612
45648
|
const closeCbs = [];
|
|
45649
|
+
proc.stdin?.on(
|
|
45650
|
+
"error",
|
|
45651
|
+
(err) => opts.logger?.warn("codex stdin error (write dropped)", { code: err.code, message: err.message })
|
|
45652
|
+
);
|
|
45613
45653
|
rl.on("line", (l2) => {
|
|
45614
45654
|
for (const cb of lineCbs) cb(l2);
|
|
45615
45655
|
});
|
|
@@ -54765,7 +54805,7 @@ function createCodexSession(ctx, sink, deps = {}) {
|
|
|
54765
54805
|
ctx,
|
|
54766
54806
|
sink,
|
|
54767
54807
|
logger: deps.logger,
|
|
54768
|
-
stream: stdioLineStream(proc),
|
|
54808
|
+
stream: stdioLineStream(proc, { logger: deps.logger }),
|
|
54769
54809
|
threadParams: threadStartParams(ctx),
|
|
54770
54810
|
// persona 惯例装在 <cwd>/.claude/skills/,经 extraRoots 注入 discovery
|
|
54771
54811
|
// (skills:list RPC 侧 codex-skills.ts 同款注入,两处保持一致)。
|
|
@@ -62157,6 +62197,7 @@ function renderDeployWorkflow(config) {
|
|
|
62157
62197
|
" - name: Select pinned source identities",
|
|
62158
62198
|
" env:",
|
|
62159
62199
|
" RELEASE_JSON: ${{ inputs.release_json }}",
|
|
62200
|
+
" CONFIG_JSON: ${{ inputs.config_json }}",
|
|
62160
62201
|
" run: |",
|
|
62161
62202
|
" node --input-type=module <<'NODE'",
|
|
62162
62203
|
' import fs from "node:fs"',
|
|
@@ -62164,7 +62205,9 @@ function renderDeployWorkflow(config) {
|
|
|
62164
62205
|
' const r = fs.existsSync(file) ? JSON.parse(fs.readFileSync(file, "utf8")) : process.env.RELEASE_JSON ? JSON.parse(process.env.RELEASE_JSON) : undefined',
|
|
62165
62206
|
' if (r && (!/^[a-f0-9]{40}$/.test(r.commit) || !/^[a-f0-9]{40}$/.test(r.pipelineCommit) || r.repository !== process.env.GITHUB_REPOSITORY)) throw new Error("invalid Persona release identity")',
|
|
62166
62207
|
' if (process.env.DEPLOY_ENVIRONMENT === "production" && (!r || process.env.GITHUB_REF_NAME !== "main" || process.env.GITHUB_SHA !== r.commit)) throw new Error("production main must equal tested commit")',
|
|
62167
|
-
|
|
62208
|
+
" // \u5E94\u7528\u914D\u7F6E\uFF08integration + config_json + release_json\uFF0C\u4E14\u8FD8\u6CA1\u6709\u5019\u9009\u6587\u4EF6\uFF09\u8981\u6362\u4E0A\u5F53\u524D\u6D41\u6C34\u7EBF\uFF1A\u8BB0\u5F55\u91CC\u9489\u7684\u65E7\u811A\u672C\u4E0D\u8BA4\u8BC6 config_json",
|
|
62209
|
+
' const reconfigure = process.env.DEPLOY_ENVIRONMENT === "integration" && process.env.CONFIG_JSON && !fs.existsSync(file)',
|
|
62210
|
+
' fs.appendFileSync(process.env.GITHUB_ENV, "SOURCE_COMMIT=" + (r?.commit ?? process.env.GITHUB_SHA) + "\\nPIPELINE_COMMIT=" + (reconfigure ? process.env.CLAWOS_REF : r?.pipelineCommit ?? process.env.CLAWOS_REF) + "\\n")',
|
|
62168
62211
|
" NODE",
|
|
62169
62212
|
""
|
|
62170
62213
|
];
|
|
@@ -62191,6 +62234,8 @@ function renderDeployWorkflow(config) {
|
|
|
62191
62234
|
"",
|
|
62192
62235
|
" - name: \u8BFB\u90E8\u7F72\u6587\u4EF6",
|
|
62193
62236
|
" id: plan",
|
|
62237
|
+
" env:",
|
|
62238
|
+
" CLAWD_CONFIG_JSON: ${{ inputs.config_json }}",
|
|
62194
62239
|
" run: |",
|
|
62195
62240
|
" node clawos/cloud-host/pipeline/deploy-file.mjs \\",
|
|
62196
62241
|
" --persona-dir persona \\",
|
|
@@ -62255,6 +62300,7 @@ function renderDeployWorkflow(config) {
|
|
|
62255
62300
|
" --effort '${{ steps.plan.outputs.effort }}' \\",
|
|
62256
62301
|
" --size '${{ steps.plan.outputs.size }}' \\",
|
|
62257
62302
|
" --cpu '${{ steps.plan.outputs.cpu }}' \\",
|
|
62303
|
+
" --config-source '${{ steps.plan.outputs.config_source }}' \\",
|
|
62258
62304
|
" --task-concurrency '${{ steps.plan.outputs.task_concurrency }}' \\",
|
|
62259
62305
|
" --engine '${{ steps.plan.outputs.engine }}' \\",
|
|
62260
62306
|
" --connectors '${{ steps.plan.outputs.connectors }}' \\",
|
|
@@ -62270,7 +62316,7 @@ function renderDeployWorkflow(config) {
|
|
|
62270
62316
|
];
|
|
62271
62317
|
return [
|
|
62272
62318
|
"name: clawd deploy",
|
|
62273
|
-
"run-name: ${{ inputs.environment == 'production' && format('persona-production-{0}', inputs.promotion_id) || 'persona-integration' }}",
|
|
62319
|
+
"run-name: ${{ inputs.environment == 'production' && format('persona-production-{0}', inputs.promotion_id) || inputs.config_id && format('persona-integration-config-{0}', inputs.config_id) || 'persona-integration' }}",
|
|
62274
62320
|
"# \u7531 clawd \u751F\u6210\u3001\u7531 clawd \u7EF4\u62A4\u3002push \u6784\u5EFA int \u5019\u9009\uFF1Bproduction \u624B\u52A8\u664B\u7EA7\u5DF2\u9A8C\u6536\u5236\u54C1\u3002",
|
|
62275
62321
|
"on:",
|
|
62276
62322
|
" push:",
|
|
@@ -62285,7 +62331,15 @@ function renderDeployWorkflow(config) {
|
|
|
62285
62331
|
" type: string",
|
|
62286
62332
|
" required: false",
|
|
62287
62333
|
" release_json:",
|
|
62288
|
-
" description: Verified Persona release JSON for production promotion",
|
|
62334
|
+
" description: Verified Persona release JSON for production promotion or config re-test",
|
|
62335
|
+
" type: string",
|
|
62336
|
+
" required: false",
|
|
62337
|
+
" config_json:",
|
|
62338
|
+
" description: Engine/model/resource config (canonical JSON); replaces .clawd/persona.json for this run",
|
|
62339
|
+
" type: string",
|
|
62340
|
+
" required: false",
|
|
62341
|
+
" config_id:",
|
|
62342
|
+
" description: Identifies an integration config re-test run (run-name)",
|
|
62289
62343
|
" type: string",
|
|
62290
62344
|
" required: false",
|
|
62291
62345
|
"",
|
|
@@ -62338,6 +62392,7 @@ function renderDeployWorkflow(config) {
|
|
|
62338
62392
|
" ALIBABA_CLOUD_ACCESS_KEY_ID: ${{ secrets.ALI_ACS_ACCESS_KEY_ID }}",
|
|
62339
62393
|
" ALIBABA_CLOUD_ACCESS_KEY_SECRET: ${{ secrets.ALI_ACS_ACCESS_KEY_SECRET }}",
|
|
62340
62394
|
" RELEASE_JSON: ${{ inputs.release_json }}",
|
|
62395
|
+
" CLAWD_CONFIG_JSON: ${{ steps.plan.outputs.config_json }}",
|
|
62341
62396
|
" CLAWD_PUBLISHER_TEST: ${{ steps.plan.outputs.test }}",
|
|
62342
62397
|
" run: node clawos/cloud-host/pipeline/persona-candidate.mjs",
|
|
62343
62398
|
"",
|
|
@@ -62799,6 +62854,10 @@ async function fileInCommit(exec, dir, sha, rel) {
|
|
|
62799
62854
|
const r2 = await git(exec, dir, ["cat-file", "-e", `${sha}:${rel}`]);
|
|
62800
62855
|
return !r2.spawnError && r2.code === 0;
|
|
62801
62856
|
}
|
|
62857
|
+
async function readFileAtCommit(exec, dir, sha, rel) {
|
|
62858
|
+
const r2 = await git(exec, dir, ["show", `${sha}:${rel}`]);
|
|
62859
|
+
return !r2.spawnError && r2.code === 0 ? r2.stdout : void 0;
|
|
62860
|
+
}
|
|
62802
62861
|
async function commitAll(exec, args) {
|
|
62803
62862
|
await mustGit(exec, args.dir, ["add", "-A"], "\u6682\u5B58\u6587\u4EF6");
|
|
62804
62863
|
const staged = await git(exec, args.dir, ["diff", "--cached", "--quiet"]);
|
|
@@ -62849,7 +62908,9 @@ function validatePersonaRelease(raw, expected) {
|
|
|
62849
62908
|
baseImage: record4.baseImage,
|
|
62850
62909
|
pipelineCommit: record4.pipelineCommit,
|
|
62851
62910
|
repository: record4.repository,
|
|
62852
|
-
...record4.test ? { test: record4.test } : {}
|
|
62911
|
+
...record4.test ? { test: record4.test } : {},
|
|
62912
|
+
// 与 cloud-host/pipeline/release.mjs 的 fingerprint 同序;老记录没有 config,哈希不变
|
|
62913
|
+
...record4.config ? { config: Object.fromEntries(CONFIG_KEYS.map((k3) => [k3, record4.config[k3]])) } : {}
|
|
62853
62914
|
})).digest("hex");
|
|
62854
62915
|
if (record4.verification.fingerprint !== fingerprint) throw new Error("\u5236\u54C1\u5DF2\u504F\u79BB\u6D4B\u8BD5\u65F6\u7684\u7248\u672C\uFF0C\u8BF7\u91CD\u65B0\u6D4B\u8BD5");
|
|
62855
62916
|
return record4;
|
|
@@ -63137,6 +63198,7 @@ var SCAN_BASE_LABEL = {
|
|
|
63137
63198
|
|
|
63138
63199
|
// src/deploy/run-status.ts
|
|
63139
63200
|
init_protocol();
|
|
63201
|
+
var INTEGRATION_CONFIG_RUN_PREFIX = "persona-integration-config-";
|
|
63140
63202
|
var runsOf = (slug, file, query) => `/repos/${slug}/actions/workflows/${encodeURIComponent(file)}/runs?${query}`;
|
|
63141
63203
|
var pipelineJobKey = (name) => DEPLOY_STAGE_KEYS.find((k3) => name === k3 || name.startsWith(`${k3} `));
|
|
63142
63204
|
function stageStatusOf(status, conclusion) {
|
|
@@ -63190,7 +63252,7 @@ async function findReleaseRun(api, slug, target, jobsCache) {
|
|
|
63190
63252
|
`${target.environment === "integration" ? `head_sha=${encodeURIComponent(target.head)}&` : ""}branch=${branch}&per_page=100&page=${page}`
|
|
63191
63253
|
));
|
|
63192
63254
|
if (!Array.isArray(listed?.workflow_runs)) return void 0;
|
|
63193
|
-
const raw = listed.workflow_runs.find((r2) => r2.head_branch === branch && (target.environment === "production" ? r2.event === "workflow_dispatch" && r2.display_title === `persona-production-${target.promotionId}` : r2.head_sha === target.head && (r2.event === "push" || r2.event === "workflow_dispatch")));
|
|
63255
|
+
const raw = listed.workflow_runs.find((r2) => r2.head_branch === branch && (target.environment === "production" ? r2.event === "workflow_dispatch" && r2.display_title === `persona-production-${target.promotionId}` : target.configId ? r2.head_sha === target.head && r2.event === "workflow_dispatch" && r2.display_title === `${INTEGRATION_CONFIG_RUN_PREFIX}${target.configId}` : r2.head_sha === target.head && (r2.event === "push" || r2.event === "workflow_dispatch") && !(typeof r2.display_title === "string" && r2.display_title.startsWith(INTEGRATION_CONFIG_RUN_PREFIX))));
|
|
63194
63256
|
if (raw) return readPinnedRun(api, slug, raw, target.environment, target.promotionId, jobsCache);
|
|
63195
63257
|
if (listed.workflow_runs.length < 100 && (listed.total_count === void 0 || page * 100 >= listed.total_count)) return null;
|
|
63196
63258
|
}
|
|
@@ -63513,6 +63575,12 @@ function buildDeployHandlers(deps) {
|
|
|
63513
63575
|
...historyError ? { historyError } : {}
|
|
63514
63576
|
};
|
|
63515
63577
|
}
|
|
63578
|
+
async function withLegacyConfig(dir, releases) {
|
|
63579
|
+
const latestIntegration = [...releases].reverse().find((r2) => r2.environment === "integration" && !r2.legacy);
|
|
63580
|
+
if (!latestIntegration || latestIntegration.config || latestIntegration.verified?.config) return releases;
|
|
63581
|
+
const config = await testedConfigOf(dir, latestIntegration);
|
|
63582
|
+
return config ? releases.map((r2) => r2 === latestIntegration ? { ...r2, config } : r2) : releases;
|
|
63583
|
+
}
|
|
63516
63584
|
async function stateOf(personaId2, selection = {}, measure = directRead) {
|
|
63517
63585
|
const { releaseHead, releaseId, environment } = selection;
|
|
63518
63586
|
const historical = releaseHead !== void 0 || releaseId !== void 0;
|
|
@@ -63571,7 +63639,7 @@ function buildDeployHandlers(deps) {
|
|
|
63571
63639
|
const integration = historical ? selected?.environment === "integration" ? selected : void 0 : [...file.releases].reverse().find((r2) => r2.environment === "integration");
|
|
63572
63640
|
const intRunRead = (async () => {
|
|
63573
63641
|
if (!integration) return void 0;
|
|
63574
|
-
const intRun2 = await measure("run", async () => integration.runId ? runById(api, slug, integration.runId, "integration", void 0, completedJobs) : await findReleaseRun(api, slug, { environment: "integration", head: integration.head }, completedJobs) ?? void 0, { environment: "integration" });
|
|
63642
|
+
const intRun2 = await measure("run", async () => integration.runId ? runById(api, slug, integration.runId, "integration", void 0, completedJobs) : await findReleaseRun(api, slug, { environment: "integration", head: integration.head, ...configIdOf(integration) }, completedJobs) ?? void 0, { environment: "integration" });
|
|
63575
63643
|
if (intRun2 && intRun2.headSha === integration.head) {
|
|
63576
63644
|
let updated = { ...integration, runId: intRun2.runId, runAttempt: intRun2.runAttempt };
|
|
63577
63645
|
if (integration.runAttempt !== intRun2.runAttempt) updated = { ...updated, verified: void 0, artifactId: void 0, confirmation: void 0 };
|
|
@@ -63660,7 +63728,7 @@ function buildDeployHandlers(deps) {
|
|
|
63660
63728
|
...file.engineChannels ? { engineChannels: file.engineChannels } : {},
|
|
63661
63729
|
...repo2 ? { repo: repo2 } : {},
|
|
63662
63730
|
scans,
|
|
63663
|
-
releases: file.releases,
|
|
63731
|
+
releases: await withLegacyConfig(dir, file.releases),
|
|
63664
63732
|
...secrets ? { secrets } : {},
|
|
63665
63733
|
...run ? { run } : {},
|
|
63666
63734
|
...online !== void 0 ? { online } : {},
|
|
@@ -63970,6 +64038,23 @@ function buildDeployHandlers(deps) {
|
|
|
63970
64038
|
await requireIntegrationPublishingConfig(api, slug);
|
|
63971
64039
|
await api.putSecret(slug, "CLAWD_INT_TEST_LOGIN_PASS", await deps.testLoginPass(), "integration");
|
|
63972
64040
|
};
|
|
64041
|
+
const configIdOf = (r2) => r2.reconfigOf && r2.id ? { configId: r2.id } : {};
|
|
64042
|
+
const testedConfigOf = async (dir, record4) => {
|
|
64043
|
+
if (record4.verified?.config) return record4.verified.config;
|
|
64044
|
+
if (record4.config) return record4.config;
|
|
64045
|
+
const raw = await readFileAtCommit(deps.exec, dir, record4.head, PERSONA_FILE_REL);
|
|
64046
|
+
if (raw === void 0) return void 0;
|
|
64047
|
+
try {
|
|
64048
|
+
return configOfPersona(JSON.parse(raw));
|
|
64049
|
+
} catch {
|
|
64050
|
+
return void 0;
|
|
64051
|
+
}
|
|
64052
|
+
};
|
|
64053
|
+
const CONFIG_KEY_LABEL = { engine: "\u5F15\u64CE", model: "\u6A21\u578B", effort: "\u63A8\u7406\u6863\u4F4D", size: "\u89C4\u683C", cpu: "CPU", taskConcurrency: "\u4EFB\u52A1\u5E76\u53D1" };
|
|
64054
|
+
const assertConfigTested = async (personaId2, record4) => {
|
|
64055
|
+
const changed = changedConfigKeys(configOfPersona(deps.personaEngine(personaId2) ?? {}), await testedConfigOf(mustPersona(personaId2), record4));
|
|
64056
|
+
if (changed?.length) throw invalid(`\u914D\u7F6E\u6539\u8FC7\u4E86\uFF08${changed.map((k3) => CONFIG_KEY_LABEL[k3]).join("\u3001")}\uFF09\uFF0C\u5148\u300C\u5E94\u7528\u5230\u6D4B\u8BD5\u73AF\u5883\u300D\u5E76\u786E\u8BA4\uFF0C\u518D\u4E0A\u7EBF`);
|
|
64057
|
+
};
|
|
63973
64058
|
const releaseHandler = async (frame, _client, ctx) => {
|
|
63974
64059
|
ensureOwner(ctx);
|
|
63975
64060
|
const { personaId: personaId2, scanId } = parseArgs2(DeployReleaseArgsSchema, frame, "deploy:release");
|
|
@@ -64043,7 +64128,7 @@ function buildDeployHandlers(deps) {
|
|
|
64043
64128
|
try {
|
|
64044
64129
|
const result = await release(deps.exec, api, { dir, now: deps.now, auth, manifest, onPrepared: async (head) => {
|
|
64045
64130
|
const latest2 = await readHistory(dir);
|
|
64046
|
-
await writeScanFile(dir, { ...latest2, releases: [...latest2.releases, { id: releaseId, environment: "integration", head, contentHead: entry.head, scanId: entry.id, at: deps.now(), pushed: false }] });
|
|
64131
|
+
await writeScanFile(dir, { ...latest2, releases: [...latest2.releases, { id: releaseId, environment: "integration", head, contentHead: entry.head, scanId: entry.id, at: deps.now(), pushed: false, config: configOfPersona(deps.personaEngine(personaId2) ?? {}), workflowVersion: DEPLOY_WORKFLOW_VERSION }] });
|
|
64047
64132
|
} });
|
|
64048
64133
|
runCache.delete(runCacheKey(personaId2));
|
|
64049
64134
|
const latest = await readHistory(dir);
|
|
@@ -64119,7 +64204,7 @@ function buildDeployHandlers(deps) {
|
|
|
64119
64204
|
const repo2 = await repoInfo(deps.exec, dir);
|
|
64120
64205
|
if (!repo2) throw invalid("\u4ED3\u5E93\u4E0D\u5B58\u5728");
|
|
64121
64206
|
const { api } = await requireGithub();
|
|
64122
|
-
const run = record4.runId ? await runById(api, repoSlug(repo2.url), record4.runId, "integration") : await findReleaseRun(api, repoSlug(repo2.url), { environment: "integration", head: record4.head });
|
|
64207
|
+
const run = record4.runId ? await runById(api, repoSlug(repo2.url), record4.runId, "integration") : await findReleaseRun(api, repoSlug(repo2.url), { environment: "integration", head: record4.head, ...configIdOf(record4) });
|
|
64123
64208
|
if (!run || run.headSha !== record4.head) throw invalid("\u6682\u65F6\u67E5\u4E0D\u5230\u672C\u6B21\u6D4B\u8BD5\u6D41\u6C34\u7EBF\uFF0C\u8BF7\u5237\u65B0");
|
|
64124
64209
|
const { artifactId, release: verified } = await readVerifiedRelease(api, repoSlug(repo2.url), run);
|
|
64125
64210
|
if (requireDialogue) {
|
|
@@ -64146,7 +64231,7 @@ function buildDeployHandlers(deps) {
|
|
|
64146
64231
|
verified,
|
|
64147
64232
|
advanceMain: (head) => advanceMain(deps.exec, dir, auth, head),
|
|
64148
64233
|
findRun: (id) => findReleaseRun(observedApi ?? api, slug, { environment: "production", head: record4.head, promotionId: id }),
|
|
64149
|
-
dispatch: (id, verified2) => api.dispatchWorkflow(slug, DEPLOY_WORKFLOW_FILE, "main", { environment: "production", promotion_id: id, release_json: JSON.stringify(verified2) }),
|
|
64234
|
+
dispatch: (id, verified2) => api.dispatchWorkflow(slug, DEPLOY_WORKFLOW_FILE, "main", { environment: "production", promotion_id: id, release_json: JSON.stringify(verified2), ...verified2.config ? { config_json: JSON.stringify(verified2.config) } : {} }),
|
|
64150
64235
|
actualImage: observedImage ?? (async () => (await deps.cloudState(cloudName, "production")).image),
|
|
64151
64236
|
now: deps.now,
|
|
64152
64237
|
persist: async (next) => {
|
|
@@ -64162,6 +64247,7 @@ function buildDeployHandlers(deps) {
|
|
|
64162
64247
|
ensureOwner(ctx);
|
|
64163
64248
|
const { personaId: personaId2, releaseId } = releaseArgs(frame, DeployConfirmTestArgsSchema);
|
|
64164
64249
|
const record4 = await testedRelease(personaId2, releaseId, true, true);
|
|
64250
|
+
await assertConfigTested(personaId2, record4);
|
|
64165
64251
|
const confirmation = record4.confirmation ?? { fingerprint: record4.verified.verification.fingerprint, runId: record4.runId, runAttempt: record4.runAttempt, at: deps.now() };
|
|
64166
64252
|
const dir = mustPersona(personaId2), file = await readHistory(dir);
|
|
64167
64253
|
await writeScanFile(dir, { ...file, releases: file.releases.map((r2) => r2.id === releaseId ? { ...r2, confirmation } : r2) });
|
|
@@ -64178,6 +64264,7 @@ function buildDeployHandlers(deps) {
|
|
|
64178
64264
|
const snapshot = old?.verified ?? (stored?.confirmation?.fingerprint === stored?.verified?.verification.fingerprint ? stored?.verified : void 0);
|
|
64179
64265
|
if (recovering && (!snapshot || !stored)) throw invalid("\u539F\u4E0A\u7EBF\u4EFB\u52A1\u7684\u5DF2\u6D4B\u5236\u54C1\u8BB0\u5F55\u4E0D\u5B8C\u6574\uFF0C\u8BF7\u5148\u6838\u5B9E\u539F\u6D41\u6C34\u7EBF\uFF1B\u4E0D\u4F1A\u6539\u7528\u65B0\u7684\u6D4B\u8BD5\u7248\u672C");
|
|
64180
64266
|
const record4 = recovering ? { ...stored, verified: snapshot } : await testedRelease(personaId2, releaseId, true, true);
|
|
64267
|
+
if (!recovering) await assertConfigTested(personaId2, record4);
|
|
64181
64268
|
const repo2 = await repoInfo(deps.exec, mustPersona(personaId2));
|
|
64182
64269
|
if (!repo2) throw invalid("\u4ED3\u5E93\u4E0D\u5B58\u5728");
|
|
64183
64270
|
if (await deps.claimPublisher(cloudPersonaIdOf(repo2.url), "production") === "taken") throw invalid("\u7EBF\u4E0A\u73AF\u5883\u91CC\u7684\u8FD9\u4E2A\u540D\u5B57\u5DF2\u7531\u522B\u4EBA\u53D1\u5E03");
|
|
@@ -64196,6 +64283,47 @@ function buildDeployHandlers(deps) {
|
|
|
64196
64283
|
const promotion = await continuePromotion(personaId2, record4, reuse ? { ...old, verified: snapshot ?? record4.verified } : { id: (0, import_node_crypto14.randomUUID)(), releaseId, at: deps.now(), phase: "prepared", verified: record4.verified }, true);
|
|
64197
64284
|
return { response: { type: "deploy:promote", promotion } };
|
|
64198
64285
|
};
|
|
64286
|
+
const applyConfig = async (frame, _client, ctx) => {
|
|
64287
|
+
ensureOwner(ctx);
|
|
64288
|
+
const { personaId: personaId2, releaseId } = releaseArgs(frame, DeployApplyConfigArgsSchema);
|
|
64289
|
+
const dir = mustPersona(personaId2);
|
|
64290
|
+
const wrong = wrongEngine(deps.personaEngine(personaId2)?.tool);
|
|
64291
|
+
if (wrong) throw invalid(wrong);
|
|
64292
|
+
const file = await readHistory(dir);
|
|
64293
|
+
const latest = [...file.releases].reverse().find((r2) => r2.environment === "integration");
|
|
64294
|
+
if (!latest || latest.id !== releaseId) throw invalid("\u53EA\u80FD\u5BF9\u6700\u65B0\u4E00\u6B21\u6D4B\u8BD5\u53D1\u5E03\u5E94\u7528\u914D\u7F6E\uFF0C\u5237\u65B0\u9875\u9762\u540E\u518D\u8BD5");
|
|
64295
|
+
if (!latest.workflowVersion || latest.workflowVersion < DEPLOY_WORKFLOW_VERSION) throw invalid("\u8FD9\u4E2A\u4ED3\u5E93\u7684\u53D1\u5E03\u6D41\u6C34\u7EBF\u662F\u65E7\u7248\u672C\uFF0C\u4E0D\u8BA4\u65B0\u914D\u7F6E\u2014\u2014\u8BF7\u5148\u5B8C\u6574\u91CD\u65B0\u53D1\u5E03\u4E00\u6B21\uFF08\u4F1A\u91CD\u65B0\u6784\u5EFA\uFF09");
|
|
64296
|
+
const repo2 = await repoInfo(deps.exec, dir);
|
|
64297
|
+
if (!repo2) throw invalid("\u4ED3\u5E93\u4E0D\u5B58\u5728");
|
|
64298
|
+
const { api } = await requireGithub();
|
|
64299
|
+
const slug = repoSlug(repo2.url);
|
|
64300
|
+
let base = latest;
|
|
64301
|
+
let retryAfterFailure = false;
|
|
64302
|
+
if (latest.reconfigOf) {
|
|
64303
|
+
const prior = await findReleaseRun(api, slug, { environment: "integration", head: latest.head, configId: latest.id });
|
|
64304
|
+
if (prior === void 0) throw invalid("\u6682\u65F6\u67E5\u4E0D\u5230\u4E0A\u4E00\u6B21\u5E94\u7528\u914D\u7F6E\u7684\u6D41\u6C34\u7EBF\uFF0C\u8BF7\u5237\u65B0");
|
|
64305
|
+
if (prior && prior.status !== "completed") throw invalid("\u4E0A\u4E00\u6B21\u5E94\u7528\u914D\u7F6E\u8FD8\u5728\u8DD1\uFF0C\u7B49\u5B83\u7ED3\u675F\u518D\u6539");
|
|
64306
|
+
if (prior && prior.conclusion === "failure") {
|
|
64307
|
+
base = file.releases.find((r2) => r2.id === latest.reconfigOf) ?? latest;
|
|
64308
|
+
retryAfterFailure = true;
|
|
64309
|
+
}
|
|
64310
|
+
}
|
|
64311
|
+
const source = await testedRelease(personaId2, base.id, false);
|
|
64312
|
+
const config = configOfPersona(deps.personaEngine(personaId2) ?? {});
|
|
64313
|
+
if (!config.model) throw invalid("\u8FD8\u6CA1\u9009\u6A21\u578B\u2014\u2014\u5728\u4E0A\u4E91\u9875\u300C\u5F15\u64CE\u4E0E\u6A21\u578B\u300D\u91CC\u9009\u4E00\u4E2A");
|
|
64314
|
+
if (!retryAfterFailure && !(changedConfigKeys(config, await testedConfigOf(dir, source)) ?? ["engine"]).length) throw invalid("\u914D\u7F6E\u548C\u6D4B\u8BD5\u73AF\u5883\u91CC\u7684\u4E00\u81F4\uFF0C\u6CA1\u6709\u9700\u8981\u5E94\u7528\u7684");
|
|
64315
|
+
const id = (0, import_node_crypto14.randomUUID)();
|
|
64316
|
+
try {
|
|
64317
|
+
await api.dispatchWorkflow(slug, DEPLOY_WORKFLOW_FILE, "integration", { environment: "integration", release_json: JSON.stringify(source.verified), config_json: JSON.stringify(config), config_id: id });
|
|
64318
|
+
} catch (err) {
|
|
64319
|
+
throw new ClawdError(ERROR_CODES.INTERNAL, err instanceof Error ? err.message : String(err));
|
|
64320
|
+
}
|
|
64321
|
+
const { verified: _v, artifactId: _a2, runId: _r2, runAttempt: _ra, confirmation: _c, ...kept } = source;
|
|
64322
|
+
const fresh = await readHistory(dir);
|
|
64323
|
+
await writeScanFile(dir, { ...fresh, releases: [...fresh.releases, { ...kept, id, at: deps.now(), pushed: true, config, reconfigOf: source.id }] });
|
|
64324
|
+
runCache.delete(runCacheKey(personaId2));
|
|
64325
|
+
return { response: { type: "deploy:applyConfig", sha: source.head, actionsUrl: "https://github.com/" + slug + "/actions", releaseId: id } };
|
|
64326
|
+
};
|
|
64199
64327
|
const openTest = async (frame, _client, ctx) => {
|
|
64200
64328
|
ensureOwner(ctx);
|
|
64201
64329
|
const { personaId: personaId2, releaseId } = releaseArgs(frame, DeployOpenTestArgsSchema);
|
|
@@ -64282,6 +64410,7 @@ function buildDeployHandlers(deps) {
|
|
|
64282
64410
|
"deploy:confirmTest": serial(confirmTest),
|
|
64283
64411
|
"deploy:promote": serial(promote),
|
|
64284
64412
|
"deploy:openTest": serial(openTest),
|
|
64413
|
+
"deploy:applyConfig": serial(applyConfig),
|
|
64285
64414
|
"deploy:scan": serial(scanHandler),
|
|
64286
64415
|
"deploy:patch": serial(patch),
|
|
64287
64416
|
"deploy:putSecret": serial(putSecret),
|
|
@@ -74595,6 +74724,7 @@ var METHOD_GRANT_MAP = {
|
|
|
74595
74724
|
"deploy:finishScan": ADMIN_ANY,
|
|
74596
74725
|
"deploy:release": ADMIN_ANY,
|
|
74597
74726
|
"deploy:confirmTest": ADMIN_ANY,
|
|
74727
|
+
"deploy:applyConfig": ADMIN_ANY,
|
|
74598
74728
|
"deploy:promote": ADMIN_ANY,
|
|
74599
74729
|
"deploy:openTest": ADMIN_ANY,
|
|
74600
74730
|
"deploy:rerunJob": ADMIN_ANY,
|
|
@@ -74767,6 +74897,7 @@ var HUMAN_ONLY_METHODS = [
|
|
|
74767
74897
|
"deploy:scan",
|
|
74768
74898
|
"deploy:release",
|
|
74769
74899
|
"deploy:confirmTest",
|
|
74900
|
+
"deploy:applyConfig",
|
|
74770
74901
|
"deploy:promote",
|
|
74771
74902
|
"deploy:openTest",
|
|
74772
74903
|
"deploy:putSecret",
|
|
@@ -74817,7 +74948,7 @@ function computeMethodAccess(args) {
|
|
|
74817
74948
|
}
|
|
74818
74949
|
|
|
74819
74950
|
// src/version.ts
|
|
74820
|
-
var version = "0.2.
|
|
74951
|
+
var version = "0.2.670".length > 0 ? "0.2.670" : "dev";
|
|
74821
74952
|
|
|
74822
74953
|
// src/cli-probe/probe.ts
|
|
74823
74954
|
var fs86 = __toESM(require("fs"), 1);
|
|
@@ -78444,7 +78575,7 @@ async function startDaemon(config) {
|
|
|
78444
78575
|
personaDir: (personaId2) => personaStore.personaDirPath(personaId2),
|
|
78445
78576
|
personaEngine: (personaId2) => {
|
|
78446
78577
|
const p3 = personaRegistry.get(personaId2);
|
|
78447
|
-
return p3 ? { ...p3.tool ? { tool: p3.tool } : {}, ...p3.model ? { model: p3.model } : {}, ...p3.cloudEngine ? { cloudEngine: p3.cloudEngine } : {} } : void 0;
|
|
78578
|
+
return p3 ? { ...p3.tool ? { tool: p3.tool } : {}, ...p3.model ? { model: p3.model } : {}, ...p3.effort ? { effort: p3.effort } : {}, ...p3.cloudEngine ? { cloudEngine: p3.cloudEngine } : {}, ...p3.size ? { size: p3.size } : {}, ...p3.cpu !== void 0 ? { cpu: p3.cpu } : {}, ...p3.taskConcurrency !== void 0 ? { taskConcurrency: p3.taskConcurrency } : {} } : void 0;
|
|
78448
78579
|
},
|
|
78449
78580
|
exec: runCommand,
|
|
78450
78581
|
// 探本机前刷一次登录 shell 的 PATH:daemon 继承的是 app 启动时的快照,之后装的 CLI(~/.local/bin)看不见。
|