@clawos-dev/clawd 0.2.666 → 0.2.668
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 +322 -195
- 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-B7AqtMdc.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
|
|
@@ -62157,6 +62193,7 @@ function renderDeployWorkflow(config) {
|
|
|
62157
62193
|
" - name: Select pinned source identities",
|
|
62158
62194
|
" env:",
|
|
62159
62195
|
" RELEASE_JSON: ${{ inputs.release_json }}",
|
|
62196
|
+
" CONFIG_JSON: ${{ inputs.config_json }}",
|
|
62160
62197
|
" run: |",
|
|
62161
62198
|
" node --input-type=module <<'NODE'",
|
|
62162
62199
|
' import fs from "node:fs"',
|
|
@@ -62164,7 +62201,9 @@ function renderDeployWorkflow(config) {
|
|
|
62164
62201
|
' const r = fs.existsSync(file) ? JSON.parse(fs.readFileSync(file, "utf8")) : process.env.RELEASE_JSON ? JSON.parse(process.env.RELEASE_JSON) : undefined',
|
|
62165
62202
|
' 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
62203
|
' 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
|
-
|
|
62204
|
+
" // \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",
|
|
62205
|
+
' const reconfigure = process.env.DEPLOY_ENVIRONMENT === "integration" && process.env.CONFIG_JSON && !fs.existsSync(file)',
|
|
62206
|
+
' 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
62207
|
" NODE",
|
|
62169
62208
|
""
|
|
62170
62209
|
];
|
|
@@ -62191,6 +62230,8 @@ function renderDeployWorkflow(config) {
|
|
|
62191
62230
|
"",
|
|
62192
62231
|
" - name: \u8BFB\u90E8\u7F72\u6587\u4EF6",
|
|
62193
62232
|
" id: plan",
|
|
62233
|
+
" env:",
|
|
62234
|
+
" CLAWD_CONFIG_JSON: ${{ inputs.config_json }}",
|
|
62194
62235
|
" run: |",
|
|
62195
62236
|
" node clawos/cloud-host/pipeline/deploy-file.mjs \\",
|
|
62196
62237
|
" --persona-dir persona \\",
|
|
@@ -62255,6 +62296,7 @@ function renderDeployWorkflow(config) {
|
|
|
62255
62296
|
" --effort '${{ steps.plan.outputs.effort }}' \\",
|
|
62256
62297
|
" --size '${{ steps.plan.outputs.size }}' \\",
|
|
62257
62298
|
" --cpu '${{ steps.plan.outputs.cpu }}' \\",
|
|
62299
|
+
" --config-source '${{ steps.plan.outputs.config_source }}' \\",
|
|
62258
62300
|
" --task-concurrency '${{ steps.plan.outputs.task_concurrency }}' \\",
|
|
62259
62301
|
" --engine '${{ steps.plan.outputs.engine }}' \\",
|
|
62260
62302
|
" --connectors '${{ steps.plan.outputs.connectors }}' \\",
|
|
@@ -62270,7 +62312,7 @@ function renderDeployWorkflow(config) {
|
|
|
62270
62312
|
];
|
|
62271
62313
|
return [
|
|
62272
62314
|
"name: clawd deploy",
|
|
62273
|
-
"run-name: ${{ inputs.environment == 'production' && format('persona-production-{0}', inputs.promotion_id) || 'persona-integration' }}",
|
|
62315
|
+
"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
62316
|
"# \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
62317
|
"on:",
|
|
62276
62318
|
" push:",
|
|
@@ -62285,7 +62327,15 @@ function renderDeployWorkflow(config) {
|
|
|
62285
62327
|
" type: string",
|
|
62286
62328
|
" required: false",
|
|
62287
62329
|
" release_json:",
|
|
62288
|
-
" description: Verified Persona release JSON for production promotion",
|
|
62330
|
+
" description: Verified Persona release JSON for production promotion or config re-test",
|
|
62331
|
+
" type: string",
|
|
62332
|
+
" required: false",
|
|
62333
|
+
" config_json:",
|
|
62334
|
+
" description: Engine/model/resource config (canonical JSON); replaces .clawd/persona.json for this run",
|
|
62335
|
+
" type: string",
|
|
62336
|
+
" required: false",
|
|
62337
|
+
" config_id:",
|
|
62338
|
+
" description: Identifies an integration config re-test run (run-name)",
|
|
62289
62339
|
" type: string",
|
|
62290
62340
|
" required: false",
|
|
62291
62341
|
"",
|
|
@@ -62338,6 +62388,7 @@ function renderDeployWorkflow(config) {
|
|
|
62338
62388
|
" ALIBABA_CLOUD_ACCESS_KEY_ID: ${{ secrets.ALI_ACS_ACCESS_KEY_ID }}",
|
|
62339
62389
|
" ALIBABA_CLOUD_ACCESS_KEY_SECRET: ${{ secrets.ALI_ACS_ACCESS_KEY_SECRET }}",
|
|
62340
62390
|
" RELEASE_JSON: ${{ inputs.release_json }}",
|
|
62391
|
+
" CLAWD_CONFIG_JSON: ${{ steps.plan.outputs.config_json }}",
|
|
62341
62392
|
" CLAWD_PUBLISHER_TEST: ${{ steps.plan.outputs.test }}",
|
|
62342
62393
|
" run: node clawos/cloud-host/pipeline/persona-candidate.mjs",
|
|
62343
62394
|
"",
|
|
@@ -62799,6 +62850,10 @@ async function fileInCommit(exec, dir, sha, rel) {
|
|
|
62799
62850
|
const r2 = await git(exec, dir, ["cat-file", "-e", `${sha}:${rel}`]);
|
|
62800
62851
|
return !r2.spawnError && r2.code === 0;
|
|
62801
62852
|
}
|
|
62853
|
+
async function readFileAtCommit(exec, dir, sha, rel) {
|
|
62854
|
+
const r2 = await git(exec, dir, ["show", `${sha}:${rel}`]);
|
|
62855
|
+
return !r2.spawnError && r2.code === 0 ? r2.stdout : void 0;
|
|
62856
|
+
}
|
|
62802
62857
|
async function commitAll(exec, args) {
|
|
62803
62858
|
await mustGit(exec, args.dir, ["add", "-A"], "\u6682\u5B58\u6587\u4EF6");
|
|
62804
62859
|
const staged = await git(exec, args.dir, ["diff", "--cached", "--quiet"]);
|
|
@@ -62849,7 +62904,9 @@ function validatePersonaRelease(raw, expected) {
|
|
|
62849
62904
|
baseImage: record4.baseImage,
|
|
62850
62905
|
pipelineCommit: record4.pipelineCommit,
|
|
62851
62906
|
repository: record4.repository,
|
|
62852
|
-
...record4.test ? { test: record4.test } : {}
|
|
62907
|
+
...record4.test ? { test: record4.test } : {},
|
|
62908
|
+
// 与 cloud-host/pipeline/release.mjs 的 fingerprint 同序;老记录没有 config,哈希不变
|
|
62909
|
+
...record4.config ? { config: Object.fromEntries(CONFIG_KEYS.map((k3) => [k3, record4.config[k3]])) } : {}
|
|
62853
62910
|
})).digest("hex");
|
|
62854
62911
|
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
62912
|
return record4;
|
|
@@ -63137,6 +63194,7 @@ var SCAN_BASE_LABEL = {
|
|
|
63137
63194
|
|
|
63138
63195
|
// src/deploy/run-status.ts
|
|
63139
63196
|
init_protocol();
|
|
63197
|
+
var INTEGRATION_CONFIG_RUN_PREFIX = "persona-integration-config-";
|
|
63140
63198
|
var runsOf = (slug, file, query) => `/repos/${slug}/actions/workflows/${encodeURIComponent(file)}/runs?${query}`;
|
|
63141
63199
|
var pipelineJobKey = (name) => DEPLOY_STAGE_KEYS.find((k3) => name === k3 || name.startsWith(`${k3} `));
|
|
63142
63200
|
function stageStatusOf(status, conclusion) {
|
|
@@ -63190,7 +63248,7 @@ async function findReleaseRun(api, slug, target, jobsCache) {
|
|
|
63190
63248
|
`${target.environment === "integration" ? `head_sha=${encodeURIComponent(target.head)}&` : ""}branch=${branch}&per_page=100&page=${page}`
|
|
63191
63249
|
));
|
|
63192
63250
|
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")));
|
|
63251
|
+
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
63252
|
if (raw) return readPinnedRun(api, slug, raw, target.environment, target.promotionId, jobsCache);
|
|
63195
63253
|
if (listed.workflow_runs.length < 100 && (listed.total_count === void 0 || page * 100 >= listed.total_count)) return null;
|
|
63196
63254
|
}
|
|
@@ -63513,6 +63571,12 @@ function buildDeployHandlers(deps) {
|
|
|
63513
63571
|
...historyError ? { historyError } : {}
|
|
63514
63572
|
};
|
|
63515
63573
|
}
|
|
63574
|
+
async function withLegacyConfig(dir, releases) {
|
|
63575
|
+
const latestIntegration = [...releases].reverse().find((r2) => r2.environment === "integration" && !r2.legacy);
|
|
63576
|
+
if (!latestIntegration || latestIntegration.config || latestIntegration.verified?.config) return releases;
|
|
63577
|
+
const config = await testedConfigOf(dir, latestIntegration);
|
|
63578
|
+
return config ? releases.map((r2) => r2 === latestIntegration ? { ...r2, config } : r2) : releases;
|
|
63579
|
+
}
|
|
63516
63580
|
async function stateOf(personaId2, selection = {}, measure = directRead) {
|
|
63517
63581
|
const { releaseHead, releaseId, environment } = selection;
|
|
63518
63582
|
const historical = releaseHead !== void 0 || releaseId !== void 0;
|
|
@@ -63571,7 +63635,7 @@ function buildDeployHandlers(deps) {
|
|
|
63571
63635
|
const integration = historical ? selected?.environment === "integration" ? selected : void 0 : [...file.releases].reverse().find((r2) => r2.environment === "integration");
|
|
63572
63636
|
const intRunRead = (async () => {
|
|
63573
63637
|
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" });
|
|
63638
|
+
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
63639
|
if (intRun2 && intRun2.headSha === integration.head) {
|
|
63576
63640
|
let updated = { ...integration, runId: intRun2.runId, runAttempt: intRun2.runAttempt };
|
|
63577
63641
|
if (integration.runAttempt !== intRun2.runAttempt) updated = { ...updated, verified: void 0, artifactId: void 0, confirmation: void 0 };
|
|
@@ -63660,7 +63724,7 @@ function buildDeployHandlers(deps) {
|
|
|
63660
63724
|
...file.engineChannels ? { engineChannels: file.engineChannels } : {},
|
|
63661
63725
|
...repo2 ? { repo: repo2 } : {},
|
|
63662
63726
|
scans,
|
|
63663
|
-
releases: file.releases,
|
|
63727
|
+
releases: await withLegacyConfig(dir, file.releases),
|
|
63664
63728
|
...secrets ? { secrets } : {},
|
|
63665
63729
|
...run ? { run } : {},
|
|
63666
63730
|
...online !== void 0 ? { online } : {},
|
|
@@ -63970,6 +64034,23 @@ function buildDeployHandlers(deps) {
|
|
|
63970
64034
|
await requireIntegrationPublishingConfig(api, slug);
|
|
63971
64035
|
await api.putSecret(slug, "CLAWD_INT_TEST_LOGIN_PASS", await deps.testLoginPass(), "integration");
|
|
63972
64036
|
};
|
|
64037
|
+
const configIdOf = (r2) => r2.reconfigOf && r2.id ? { configId: r2.id } : {};
|
|
64038
|
+
const testedConfigOf = async (dir, record4) => {
|
|
64039
|
+
if (record4.verified?.config) return record4.verified.config;
|
|
64040
|
+
if (record4.config) return record4.config;
|
|
64041
|
+
const raw = await readFileAtCommit(deps.exec, dir, record4.head, PERSONA_FILE_REL);
|
|
64042
|
+
if (raw === void 0) return void 0;
|
|
64043
|
+
try {
|
|
64044
|
+
return configOfPersona(JSON.parse(raw));
|
|
64045
|
+
} catch {
|
|
64046
|
+
return void 0;
|
|
64047
|
+
}
|
|
64048
|
+
};
|
|
64049
|
+
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" };
|
|
64050
|
+
const assertConfigTested = async (personaId2, record4) => {
|
|
64051
|
+
const changed = changedConfigKeys(configOfPersona(deps.personaEngine(personaId2) ?? {}), await testedConfigOf(mustPersona(personaId2), record4));
|
|
64052
|
+
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`);
|
|
64053
|
+
};
|
|
63973
64054
|
const releaseHandler = async (frame, _client, ctx) => {
|
|
63974
64055
|
ensureOwner(ctx);
|
|
63975
64056
|
const { personaId: personaId2, scanId } = parseArgs2(DeployReleaseArgsSchema, frame, "deploy:release");
|
|
@@ -64043,7 +64124,7 @@ function buildDeployHandlers(deps) {
|
|
|
64043
64124
|
try {
|
|
64044
64125
|
const result = await release(deps.exec, api, { dir, now: deps.now, auth, manifest, onPrepared: async (head) => {
|
|
64045
64126
|
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 }] });
|
|
64127
|
+
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
64128
|
} });
|
|
64048
64129
|
runCache.delete(runCacheKey(personaId2));
|
|
64049
64130
|
const latest = await readHistory(dir);
|
|
@@ -64119,7 +64200,7 @@ function buildDeployHandlers(deps) {
|
|
|
64119
64200
|
const repo2 = await repoInfo(deps.exec, dir);
|
|
64120
64201
|
if (!repo2) throw invalid("\u4ED3\u5E93\u4E0D\u5B58\u5728");
|
|
64121
64202
|
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 });
|
|
64203
|
+
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
64204
|
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
64205
|
const { artifactId, release: verified } = await readVerifiedRelease(api, repoSlug(repo2.url), run);
|
|
64125
64206
|
if (requireDialogue) {
|
|
@@ -64146,7 +64227,7 @@ function buildDeployHandlers(deps) {
|
|
|
64146
64227
|
verified,
|
|
64147
64228
|
advanceMain: (head) => advanceMain(deps.exec, dir, auth, head),
|
|
64148
64229
|
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) }),
|
|
64230
|
+
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
64231
|
actualImage: observedImage ?? (async () => (await deps.cloudState(cloudName, "production")).image),
|
|
64151
64232
|
now: deps.now,
|
|
64152
64233
|
persist: async (next) => {
|
|
@@ -64162,6 +64243,7 @@ function buildDeployHandlers(deps) {
|
|
|
64162
64243
|
ensureOwner(ctx);
|
|
64163
64244
|
const { personaId: personaId2, releaseId } = releaseArgs(frame, DeployConfirmTestArgsSchema);
|
|
64164
64245
|
const record4 = await testedRelease(personaId2, releaseId, true, true);
|
|
64246
|
+
await assertConfigTested(personaId2, record4);
|
|
64165
64247
|
const confirmation = record4.confirmation ?? { fingerprint: record4.verified.verification.fingerprint, runId: record4.runId, runAttempt: record4.runAttempt, at: deps.now() };
|
|
64166
64248
|
const dir = mustPersona(personaId2), file = await readHistory(dir);
|
|
64167
64249
|
await writeScanFile(dir, { ...file, releases: file.releases.map((r2) => r2.id === releaseId ? { ...r2, confirmation } : r2) });
|
|
@@ -64178,6 +64260,7 @@ function buildDeployHandlers(deps) {
|
|
|
64178
64260
|
const snapshot = old?.verified ?? (stored?.confirmation?.fingerprint === stored?.verified?.verification.fingerprint ? stored?.verified : void 0);
|
|
64179
64261
|
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
64262
|
const record4 = recovering ? { ...stored, verified: snapshot } : await testedRelease(personaId2, releaseId, true, true);
|
|
64263
|
+
if (!recovering) await assertConfigTested(personaId2, record4);
|
|
64181
64264
|
const repo2 = await repoInfo(deps.exec, mustPersona(personaId2));
|
|
64182
64265
|
if (!repo2) throw invalid("\u4ED3\u5E93\u4E0D\u5B58\u5728");
|
|
64183
64266
|
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 +64279,47 @@ function buildDeployHandlers(deps) {
|
|
|
64196
64279
|
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
64280
|
return { response: { type: "deploy:promote", promotion } };
|
|
64198
64281
|
};
|
|
64282
|
+
const applyConfig = async (frame, _client, ctx) => {
|
|
64283
|
+
ensureOwner(ctx);
|
|
64284
|
+
const { personaId: personaId2, releaseId } = releaseArgs(frame, DeployApplyConfigArgsSchema);
|
|
64285
|
+
const dir = mustPersona(personaId2);
|
|
64286
|
+
const wrong = wrongEngine(deps.personaEngine(personaId2)?.tool);
|
|
64287
|
+
if (wrong) throw invalid(wrong);
|
|
64288
|
+
const file = await readHistory(dir);
|
|
64289
|
+
const latest = [...file.releases].reverse().find((r2) => r2.environment === "integration");
|
|
64290
|
+
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");
|
|
64291
|
+
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");
|
|
64292
|
+
const repo2 = await repoInfo(deps.exec, dir);
|
|
64293
|
+
if (!repo2) throw invalid("\u4ED3\u5E93\u4E0D\u5B58\u5728");
|
|
64294
|
+
const { api } = await requireGithub();
|
|
64295
|
+
const slug = repoSlug(repo2.url);
|
|
64296
|
+
let base = latest;
|
|
64297
|
+
let retryAfterFailure = false;
|
|
64298
|
+
if (latest.reconfigOf) {
|
|
64299
|
+
const prior = await findReleaseRun(api, slug, { environment: "integration", head: latest.head, configId: latest.id });
|
|
64300
|
+
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");
|
|
64301
|
+
if (prior && prior.status !== "completed") throw invalid("\u4E0A\u4E00\u6B21\u5E94\u7528\u914D\u7F6E\u8FD8\u5728\u8DD1\uFF0C\u7B49\u5B83\u7ED3\u675F\u518D\u6539");
|
|
64302
|
+
if (prior && prior.conclusion === "failure") {
|
|
64303
|
+
base = file.releases.find((r2) => r2.id === latest.reconfigOf) ?? latest;
|
|
64304
|
+
retryAfterFailure = true;
|
|
64305
|
+
}
|
|
64306
|
+
}
|
|
64307
|
+
const source = await testedRelease(personaId2, base.id, false);
|
|
64308
|
+
const config = configOfPersona(deps.personaEngine(personaId2) ?? {});
|
|
64309
|
+
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");
|
|
64310
|
+
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");
|
|
64311
|
+
const id = (0, import_node_crypto14.randomUUID)();
|
|
64312
|
+
try {
|
|
64313
|
+
await api.dispatchWorkflow(slug, DEPLOY_WORKFLOW_FILE, "integration", { environment: "integration", release_json: JSON.stringify(source.verified), config_json: JSON.stringify(config), config_id: id });
|
|
64314
|
+
} catch (err) {
|
|
64315
|
+
throw new ClawdError(ERROR_CODES.INTERNAL, err instanceof Error ? err.message : String(err));
|
|
64316
|
+
}
|
|
64317
|
+
const { verified: _v, artifactId: _a2, runId: _r2, runAttempt: _ra, confirmation: _c, ...kept } = source;
|
|
64318
|
+
const fresh = await readHistory(dir);
|
|
64319
|
+
await writeScanFile(dir, { ...fresh, releases: [...fresh.releases, { ...kept, id, at: deps.now(), pushed: true, config, reconfigOf: source.id }] });
|
|
64320
|
+
runCache.delete(runCacheKey(personaId2));
|
|
64321
|
+
return { response: { type: "deploy:applyConfig", sha: source.head, actionsUrl: "https://github.com/" + slug + "/actions", releaseId: id } };
|
|
64322
|
+
};
|
|
64199
64323
|
const openTest = async (frame, _client, ctx) => {
|
|
64200
64324
|
ensureOwner(ctx);
|
|
64201
64325
|
const { personaId: personaId2, releaseId } = releaseArgs(frame, DeployOpenTestArgsSchema);
|
|
@@ -64282,6 +64406,7 @@ function buildDeployHandlers(deps) {
|
|
|
64282
64406
|
"deploy:confirmTest": serial(confirmTest),
|
|
64283
64407
|
"deploy:promote": serial(promote),
|
|
64284
64408
|
"deploy:openTest": serial(openTest),
|
|
64409
|
+
"deploy:applyConfig": serial(applyConfig),
|
|
64285
64410
|
"deploy:scan": serial(scanHandler),
|
|
64286
64411
|
"deploy:patch": serial(patch),
|
|
64287
64412
|
"deploy:putSecret": serial(putSecret),
|
|
@@ -74595,6 +74720,7 @@ var METHOD_GRANT_MAP = {
|
|
|
74595
74720
|
"deploy:finishScan": ADMIN_ANY,
|
|
74596
74721
|
"deploy:release": ADMIN_ANY,
|
|
74597
74722
|
"deploy:confirmTest": ADMIN_ANY,
|
|
74723
|
+
"deploy:applyConfig": ADMIN_ANY,
|
|
74598
74724
|
"deploy:promote": ADMIN_ANY,
|
|
74599
74725
|
"deploy:openTest": ADMIN_ANY,
|
|
74600
74726
|
"deploy:rerunJob": ADMIN_ANY,
|
|
@@ -74767,6 +74893,7 @@ var HUMAN_ONLY_METHODS = [
|
|
|
74767
74893
|
"deploy:scan",
|
|
74768
74894
|
"deploy:release",
|
|
74769
74895
|
"deploy:confirmTest",
|
|
74896
|
+
"deploy:applyConfig",
|
|
74770
74897
|
"deploy:promote",
|
|
74771
74898
|
"deploy:openTest",
|
|
74772
74899
|
"deploy:putSecret",
|
|
@@ -74817,7 +74944,7 @@ function computeMethodAccess(args) {
|
|
|
74817
74944
|
}
|
|
74818
74945
|
|
|
74819
74946
|
// src/version.ts
|
|
74820
|
-
var version = "0.2.
|
|
74947
|
+
var version = "0.2.668".length > 0 ? "0.2.668" : "dev";
|
|
74821
74948
|
|
|
74822
74949
|
// src/cli-probe/probe.ts
|
|
74823
74950
|
var fs86 = __toESM(require("fs"), 1);
|
|
@@ -78444,7 +78571,7 @@ async function startDaemon(config) {
|
|
|
78444
78571
|
personaDir: (personaId2) => personaStore.personaDirPath(personaId2),
|
|
78445
78572
|
personaEngine: (personaId2) => {
|
|
78446
78573
|
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;
|
|
78574
|
+
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
78575
|
},
|
|
78449
78576
|
exec: runCommand,
|
|
78450
78577
|
// 探本机前刷一次登录 shell 的 PATH:daemon 继承的是 app 启动时的快照,之后装的 CLI(~/.local/bin)看不见。
|