@clawos-dev/clawd 0.2.583 → 0.2.585
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 +9 -1
- package/dist/cli.cjs +124 -14
- package/dist/cloud-persona-conversations.html +1 -1
- package/dist/cloud-persona-metrics.html +19 -19
- package/dist/dispatch/mcp-server.cjs +9 -1
- package/dist/persona-defaults/persona-app-builder/mcp/clawd-app-builder/mcp-server.cjs +9 -1
- package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/mcp-server.cjs +9 -1
- package/dist/share-ui/assets/{guest-DVxTImMk.js → guest-D9kUdzSm.js} +2 -2
- package/dist/share-ui/guest.html +1 -1
- package/package.json +1 -1
|
@@ -21787,6 +21787,10 @@ var DeployPutSecretArgsSchema = external_exports.object({
|
|
|
21787
21787
|
// 环境变量名 → 值。key 必须是该 secret 声明过的 env 之一,handler 校验。
|
|
21788
21788
|
values: external_exports.record(external_exports.string(), external_exports.string())
|
|
21789
21789
|
}).strict();
|
|
21790
|
+
var DeploySetEngineAuthArgsSchema = external_exports.object({
|
|
21791
|
+
personaId: external_exports.string().min(1),
|
|
21792
|
+
auth: external_exports.object({ baseUrl: external_exports.string(), apiKey: external_exports.string() }).strict().nullable()
|
|
21793
|
+
}).strict();
|
|
21790
21794
|
var DeployRerunJobArgsSchema = external_exports.object({
|
|
21791
21795
|
personaId: external_exports.string().min(1),
|
|
21792
21796
|
/** GitHub 的 job databaseId。**是数字**——字符串会在拼命令时静默出错 */
|
|
@@ -24273,9 +24277,13 @@ var METHOD_DOCS = {
|
|
|
24273
24277
|
args: DeployPatchArgsSchema
|
|
24274
24278
|
},
|
|
24275
24279
|
"deploy:putSecret": {
|
|
24276
|
-
summary: "\u628A\u4E00\u6761\u51ED\u636E\u7684\u503C\u5199\u8FDB\u4ED3\u5E93\u7684 GitHub Secrets\uFF08GitHub REST\uFF0C\u503C\u7528\u4ED3\u5E93\u516C\u94A5\u5C01\u7BB1\u540E\u4E0A\u4F20\uFF09\u3002**\u8FD9\u662F\u503C\u552F\u4E00\u7684\u5165\u53E3**\uFF1A\u5165\u53C2\u4E0D\u8FDB\u65E5\u5FD7\u3001\u54CD\u5E94\u4E0D\u56DE\u663E\u503C\u3001\u672C\u673A\u4E0D\u843D\u76D8\u3002env \u540D\u5FC5\u987B\u662F scanId \u90A3\u6B21\u6E05\u5355\u91CC\u8BE5\u51ED\u636E\u58F0\u660E\u8FC7\u7684\uFF1Bowner-only",
|
|
24280
|
+
summary: "\u628A\u4E00\u6761\u51ED\u636E\u7684\u503C\u5199\u8FDB\u4ED3\u5E93\u7684 GitHub Secrets\uFF08GitHub REST\uFF0C\u503C\u7528\u4ED3\u5E93\u516C\u94A5\u5C01\u7BB1\u540E\u4E0A\u4F20\uFF09\u3002**\u8FD9\u662F\u6E05\u5355\u51ED\u636E\u503C\u552F\u4E00\u7684\u5165\u53E3**\uFF08\u6A21\u578B\u8BA2\u9605\u8D70 deploy:setEngineAuth\uFF09\uFF1A\u5165\u53C2\u4E0D\u8FDB\u65E5\u5FD7\u3001\u54CD\u5E94\u4E0D\u56DE\u663E\u503C\u3001\u672C\u673A\u4E0D\u843D\u76D8\u3002env \u540D\u5FC5\u987B\u662F scanId \u90A3\u6B21\u6E05\u5355\u91CC\u8BE5\u51ED\u636E\u58F0\u660E\u8FC7\u7684\uFF1Bowner-only",
|
|
24277
24281
|
args: DeployPutSecretArgsSchema
|
|
24278
24282
|
},
|
|
24283
|
+
"deploy:setEngineAuth": {
|
|
24284
|
+
summary: "\u6A21\u578B\u8BA2\u9605\uFF08\u4E91\u4E0A\u8DD1\u8FD9\u4E2A persona \u82B1\u8C01\u7684\u6A21\u578B\u989D\u5EA6\uFF09\uFF1Aauth = { baseUrl, apiKey } \u5199\u8FDB\u4ED3\u5E93 GitHub Secrets \u7684 CLAWD_ENGINE_BASE_URL / CLAWD_ENGINE_API_KEY\uFF08\u5730\u5740\u89C4\u8303\u6210 \u2026/v1\uFF09\uFF0Cnull = \u5220\u8FD9\u4E24\u6761\u3001\u6539\u56DE\u5E73\u53F0\u9ED8\u8BA4\u3002\u4E0B\u6B21\u53D1\u5E03\u751F\u6548\u3002\u540C putSecret \u7684\u7EAA\u5F8B\uFF1A\u5165\u53C2\u4E0D\u8FDB\u65E5\u5FD7\u3001\u54CD\u5E94\u4E0D\u56DE\u663E\u503C\u3001\u672C\u673A\u4E0D\u843D\u76D8\uFF1B\u56DE deploy:get \u540C\u5F62\u7684\u72B6\u6001\uFF1Bowner-only\u3001human-only",
|
|
24285
|
+
args: DeploySetEngineAuthArgsSchema
|
|
24286
|
+
},
|
|
24279
24287
|
"deploy:reportFinding": {
|
|
24280
24288
|
summary: "\u626B\u63CF\u4E2D\u7684 butler \u9010\u6761\u4E0A\u62A5\u4E00\u4E2A\u53D1\u73B0\uFF08cli / secret / asset\uFF09\u3002**\u8FB9\u626B\u8FB9\u62A5**\uFF0C\u9875\u9762\u968F\u4E4B\u4E00\u70B9\u70B9\u586B\u5145\uFF1B\u540C (kind,name) \u91CD\u590D\u4E0A\u62A5\u5373\u8986\u76D6\u3002owner-only\u2014\u2014butler \u4F1A\u8BDD\u672C\u8EAB\u8DD1\u5728 owner \u6A21\u5F0F",
|
|
24281
24289
|
args: DeployReportFindingArgsSchema
|
package/dist/cli.cjs
CHANGED
|
@@ -6154,6 +6154,26 @@ var init_environment_schemas = __esm({
|
|
|
6154
6154
|
});
|
|
6155
6155
|
|
|
6156
6156
|
// ../protocol/src/deploy-schemas.ts
|
|
6157
|
+
function engineAuthState(secrets) {
|
|
6158
|
+
if (!secrets) return void 0;
|
|
6159
|
+
const has = (env) => secrets.some((p3) => p3.env === env && p3.setAt !== void 0);
|
|
6160
|
+
const n2 = [ENGINE_AUTH_SECRETS.baseUrl, ENGINE_AUTH_SECRETS.apiKey].filter(has).length;
|
|
6161
|
+
return n2 === 2 ? "own" : n2 === 0 ? "platform" : "partial";
|
|
6162
|
+
}
|
|
6163
|
+
function normalizeEngineBaseUrl(raw) {
|
|
6164
|
+
const s2 = raw.trim();
|
|
6165
|
+
let url;
|
|
6166
|
+
try {
|
|
6167
|
+
url = new URL(s2);
|
|
6168
|
+
} catch {
|
|
6169
|
+
throw new Error("\u8BA2\u9605\u5730\u5740\u8981\u4EE5 http:// \u6216 https:// \u5F00\u5934\uFF0C\u5F62\u5982 https://cpa.example.com");
|
|
6170
|
+
}
|
|
6171
|
+
if (url.protocol !== "http:" && url.protocol !== "https:" || !url.hostname) {
|
|
6172
|
+
throw new Error("\u8BA2\u9605\u5730\u5740\u8981\u4EE5 http:// \u6216 https:// \u5F00\u5934\uFF0C\u5F62\u5982 https://cpa.example.com");
|
|
6173
|
+
}
|
|
6174
|
+
const base = `${url.origin}${url.pathname}`.replace(/\/+$/, "");
|
|
6175
|
+
return base.endsWith("/v1") ? base : `${base}/v1`;
|
|
6176
|
+
}
|
|
6157
6177
|
function contentHeadOf(repo2, released) {
|
|
6158
6178
|
return released && repo2.head === released.head ? released.contentHead : repo2.head;
|
|
6159
6179
|
}
|
|
@@ -6168,7 +6188,7 @@ function cloudEngineOk(tool) {
|
|
|
6168
6188
|
function repoSlug(url) {
|
|
6169
6189
|
return url.trim().replace(/^git@[^:]+:/, "").replace(/^https?:\/\/[^/]+\//, "").replace(/\.git$/, "");
|
|
6170
6190
|
}
|
|
6171
|
-
var DeployFileSchema, SCAN_BASE_KINDS, ScanBaseKindSchema, DeployScanStatusSchema, DeployScanSchema, DeployReleasedSchema, DeployScanFileSchema, DeployRepoSchema, DeploySecretPresenceSchema, DEPLOY_STAGE_STATUSES, DeployStageStatusSchema, DEPLOY_STAGE_KEYS, DeployStageKeySchema, DeployJobSchema, DeployRunSchema, CLOUD_ENGINES, DeployUnpublishRunSchema, DeployStateSchema, DeployUnpublishResultSchema, DeployReleaseResultSchema, DeployPersonaArgsSchema, DeployGetArgsSchema, DeployScanArgsSchema, DeployReleaseArgsSchema, DeployPatchArgsSchema, DeployPutSecretArgsSchema, DeployRerunJobArgsSchema, DeployReportFindingArgsSchema, DeployFinishScanArgsSchema, PERSONA_REPO_ORG;
|
|
6191
|
+
var DeployFileSchema, SCAN_BASE_KINDS, ScanBaseKindSchema, DeployScanStatusSchema, DeployScanSchema, DeployReleasedSchema, DeployScanFileSchema, DeployRepoSchema, DeploySecretPresenceSchema, ENGINE_AUTH_SECRETS, ENGINE_AUTH_PARTIAL_BLOCKER, DEPLOY_STAGE_STATUSES, DeployStageStatusSchema, DEPLOY_STAGE_KEYS, DeployStageKeySchema, DeployJobSchema, DeployRunSchema, CLOUD_ENGINES, DeployUnpublishRunSchema, DeployStateSchema, DeployUnpublishResultSchema, DeployReleaseResultSchema, DeployPersonaArgsSchema, DeployGetArgsSchema, DeployScanArgsSchema, DeployReleaseArgsSchema, DeployPatchArgsSchema, DeployPutSecretArgsSchema, DeploySetEngineAuthArgsSchema, DeployRerunJobArgsSchema, DeployReportFindingArgsSchema, DeployFinishScanArgsSchema, PERSONA_REPO_ORG;
|
|
6172
6192
|
var init_deploy_schemas = __esm({
|
|
6173
6193
|
"../protocol/src/deploy-schemas.ts"() {
|
|
6174
6194
|
"use strict";
|
|
@@ -6253,6 +6273,8 @@ var init_deploy_schemas = __esm({
|
|
|
6253
6273
|
env: external_exports.string().min(1),
|
|
6254
6274
|
setAt: external_exports.number().optional()
|
|
6255
6275
|
}).strict();
|
|
6276
|
+
ENGINE_AUTH_SECRETS = { baseUrl: "CLAWD_ENGINE_BASE_URL", apiKey: "CLAWD_ENGINE_API_KEY" };
|
|
6277
|
+
ENGINE_AUTH_PARTIAL_BLOCKER = "\u6A21\u578B\u8BA2\u9605\u53EA\u5199\u8FDB\u53BB\u4E00\u534A\u2014\u2014\u91CD\u586B\u6216\u6539\u56DE\u5E73\u53F0\u9ED8\u8BA4";
|
|
6256
6278
|
DEPLOY_STAGE_STATUSES = ["pending", "running", "done", "failed", "waiting", "skipped"];
|
|
6257
6279
|
DeployStageStatusSchema = external_exports.enum(DEPLOY_STAGE_STATUSES);
|
|
6258
6280
|
DEPLOY_STAGE_KEYS = ["build", "smoke", "deploy"];
|
|
@@ -6358,6 +6380,10 @@ var init_deploy_schemas = __esm({
|
|
|
6358
6380
|
// 环境变量名 → 值。key 必须是该 secret 声明过的 env 之一,handler 校验。
|
|
6359
6381
|
values: external_exports.record(external_exports.string(), external_exports.string())
|
|
6360
6382
|
}).strict();
|
|
6383
|
+
DeploySetEngineAuthArgsSchema = external_exports.object({
|
|
6384
|
+
personaId: external_exports.string().min(1),
|
|
6385
|
+
auth: external_exports.object({ baseUrl: external_exports.string(), apiKey: external_exports.string() }).strict().nullable()
|
|
6386
|
+
}).strict();
|
|
6361
6387
|
DeployRerunJobArgsSchema = external_exports.object({
|
|
6362
6388
|
personaId: external_exports.string().min(1),
|
|
6363
6389
|
/** GitHub 的 job databaseId。**是数字**——字符串会在拼命令时静默出错 */
|
|
@@ -9137,9 +9163,13 @@ var init_methods = __esm({
|
|
|
9137
9163
|
args: DeployPatchArgsSchema
|
|
9138
9164
|
},
|
|
9139
9165
|
"deploy:putSecret": {
|
|
9140
|
-
summary: "\u628A\u4E00\u6761\u51ED\u636E\u7684\u503C\u5199\u8FDB\u4ED3\u5E93\u7684 GitHub Secrets\uFF08GitHub REST\uFF0C\u503C\u7528\u4ED3\u5E93\u516C\u94A5\u5C01\u7BB1\u540E\u4E0A\u4F20\uFF09\u3002**\u8FD9\u662F\u503C\u552F\u4E00\u7684\u5165\u53E3**\uFF1A\u5165\u53C2\u4E0D\u8FDB\u65E5\u5FD7\u3001\u54CD\u5E94\u4E0D\u56DE\u663E\u503C\u3001\u672C\u673A\u4E0D\u843D\u76D8\u3002env \u540D\u5FC5\u987B\u662F scanId \u90A3\u6B21\u6E05\u5355\u91CC\u8BE5\u51ED\u636E\u58F0\u660E\u8FC7\u7684\uFF1Bowner-only",
|
|
9166
|
+
summary: "\u628A\u4E00\u6761\u51ED\u636E\u7684\u503C\u5199\u8FDB\u4ED3\u5E93\u7684 GitHub Secrets\uFF08GitHub REST\uFF0C\u503C\u7528\u4ED3\u5E93\u516C\u94A5\u5C01\u7BB1\u540E\u4E0A\u4F20\uFF09\u3002**\u8FD9\u662F\u6E05\u5355\u51ED\u636E\u503C\u552F\u4E00\u7684\u5165\u53E3**\uFF08\u6A21\u578B\u8BA2\u9605\u8D70 deploy:setEngineAuth\uFF09\uFF1A\u5165\u53C2\u4E0D\u8FDB\u65E5\u5FD7\u3001\u54CD\u5E94\u4E0D\u56DE\u663E\u503C\u3001\u672C\u673A\u4E0D\u843D\u76D8\u3002env \u540D\u5FC5\u987B\u662F scanId \u90A3\u6B21\u6E05\u5355\u91CC\u8BE5\u51ED\u636E\u58F0\u660E\u8FC7\u7684\uFF1Bowner-only",
|
|
9141
9167
|
args: DeployPutSecretArgsSchema
|
|
9142
9168
|
},
|
|
9169
|
+
"deploy:setEngineAuth": {
|
|
9170
|
+
summary: "\u6A21\u578B\u8BA2\u9605\uFF08\u4E91\u4E0A\u8DD1\u8FD9\u4E2A persona \u82B1\u8C01\u7684\u6A21\u578B\u989D\u5EA6\uFF09\uFF1Aauth = { baseUrl, apiKey } \u5199\u8FDB\u4ED3\u5E93 GitHub Secrets \u7684 CLAWD_ENGINE_BASE_URL / CLAWD_ENGINE_API_KEY\uFF08\u5730\u5740\u89C4\u8303\u6210 \u2026/v1\uFF09\uFF0Cnull = \u5220\u8FD9\u4E24\u6761\u3001\u6539\u56DE\u5E73\u53F0\u9ED8\u8BA4\u3002\u4E0B\u6B21\u53D1\u5E03\u751F\u6548\u3002\u540C putSecret \u7684\u7EAA\u5F8B\uFF1A\u5165\u53C2\u4E0D\u8FDB\u65E5\u5FD7\u3001\u54CD\u5E94\u4E0D\u56DE\u663E\u503C\u3001\u672C\u673A\u4E0D\u843D\u76D8\uFF1B\u56DE deploy:get \u540C\u5F62\u7684\u72B6\u6001\uFF1Bowner-only\u3001human-only",
|
|
9171
|
+
args: DeploySetEngineAuthArgsSchema
|
|
9172
|
+
},
|
|
9143
9173
|
"deploy:reportFinding": {
|
|
9144
9174
|
summary: "\u626B\u63CF\u4E2D\u7684 butler \u9010\u6761\u4E0A\u62A5\u4E00\u4E2A\u53D1\u73B0\uFF08cli / secret / asset\uFF09\u3002**\u8FB9\u626B\u8FB9\u62A5**\uFF0C\u9875\u9762\u968F\u4E4B\u4E00\u70B9\u70B9\u586B\u5145\uFF1B\u540C (kind,name) \u91CD\u590D\u4E0A\u62A5\u5373\u8986\u76D6\u3002owner-only\u2014\u2014butler \u4F1A\u8BDD\u672C\u8EAB\u8DD1\u5728 owner \u6A21\u5F0F",
|
|
9145
9175
|
args: DeployReportFindingArgsSchema
|
|
@@ -53313,6 +53343,23 @@ function stringValue(value) {
|
|
|
53313
53343
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
53314
53344
|
}
|
|
53315
53345
|
|
|
53346
|
+
// src/tools/first-byte.ts
|
|
53347
|
+
var VISIBLE = /* @__PURE__ */ new Set(["thinking", "tool_call", "text"]);
|
|
53348
|
+
function createFirstByteClock(now = Date.now) {
|
|
53349
|
+
let at3 = null;
|
|
53350
|
+
return {
|
|
53351
|
+
reset() {
|
|
53352
|
+
at3 = null;
|
|
53353
|
+
},
|
|
53354
|
+
see(events) {
|
|
53355
|
+
if (at3 === null && events.some((e) => VISIBLE.has(e.kind))) at3 = now();
|
|
53356
|
+
},
|
|
53357
|
+
afterFirstByteMs() {
|
|
53358
|
+
return at3 === null ? void 0 : Math.max(0, Math.round(now() - at3));
|
|
53359
|
+
}
|
|
53360
|
+
};
|
|
53361
|
+
}
|
|
53362
|
+
|
|
53316
53363
|
// src/tools/codex-app-server-params.ts
|
|
53317
53364
|
function resolveApprovalPolicy(ctx) {
|
|
53318
53365
|
if (ctx.personaMode === "owner" || ctx.personaMode === "guest") return "never";
|
|
@@ -53448,6 +53495,7 @@ function driveCodexThread(opts) {
|
|
|
53448
53495
|
let threadId = ctx.toolSessionId;
|
|
53449
53496
|
let turnId;
|
|
53450
53497
|
let turnOpen = false;
|
|
53498
|
+
const firstByte = createFirstByteClock(opts.now);
|
|
53451
53499
|
const approvalIds = /* @__PURE__ */ new Map();
|
|
53452
53500
|
const subagents = new CodexSubagentTracker();
|
|
53453
53501
|
const effort = ctx.effort;
|
|
@@ -53479,10 +53527,13 @@ function driveCodexThread(opts) {
|
|
|
53479
53527
|
...subagents.handleParentNotification(method, params),
|
|
53480
53528
|
...translateNotification(method, params)
|
|
53481
53529
|
] : [];
|
|
53482
|
-
if (events.length)
|
|
53530
|
+
if (events.length) {
|
|
53531
|
+
if (turnOpen) firstByte.see(events);
|
|
53532
|
+
sink.pushEvents(events);
|
|
53533
|
+
}
|
|
53483
53534
|
if (route === "foreground" && method === "turn/completed") {
|
|
53484
53535
|
turnOpen = false;
|
|
53485
|
-
opts.onTurnCompleted?.(turnOutcomeOf(params));
|
|
53536
|
+
opts.onTurnCompleted?.(turnOutcomeOf(params), firstByte.afterFirstByteMs());
|
|
53486
53537
|
}
|
|
53487
53538
|
},
|
|
53488
53539
|
onServerRequest: (id, method, params) => {
|
|
@@ -53531,6 +53582,7 @@ function driveCodexThread(opts) {
|
|
|
53531
53582
|
const opened = !turnOpen;
|
|
53532
53583
|
if (opened) {
|
|
53533
53584
|
turnOpen = true;
|
|
53585
|
+
firstByte.reset();
|
|
53534
53586
|
opts.onTurnStarting?.();
|
|
53535
53587
|
}
|
|
53536
53588
|
void client.request("turn/start", {
|
|
@@ -53547,7 +53599,7 @@ function driveCodexThread(opts) {
|
|
|
53547
53599
|
]);
|
|
53548
53600
|
if (!opened) return;
|
|
53549
53601
|
turnOpen = false;
|
|
53550
|
-
opts.onTurnCompleted?.("failure");
|
|
53602
|
+
opts.onTurnCompleted?.("failure", firstByte.afterFirstByteMs());
|
|
53551
53603
|
});
|
|
53552
53604
|
}
|
|
53553
53605
|
});
|
|
@@ -60843,6 +60895,11 @@ function createGithubApi(args) {
|
|
|
60843
60895
|
const encrypted_value = await seal(pk.key, value);
|
|
60844
60896
|
await must("PUT", `/repos/${slug}/actions/secrets/${encodeURIComponent(name)}`, `\u5199 ${name}`, { encrypted_value, key_id: pk.key_id });
|
|
60845
60897
|
},
|
|
60898
|
+
async deleteSecret(slug, name) {
|
|
60899
|
+
const r2 = await request("DELETE", `/repos/${slug}/actions/secrets/${encodeURIComponent(name)}`);
|
|
60900
|
+
if (r2.status === 404) return;
|
|
60901
|
+
if (r2.status < 200 || r2.status >= 300) throw new GithubApiError(r2.status, explain(r2.status, `\u5220 ${name}`, r2.json));
|
|
60902
|
+
},
|
|
60846
60903
|
async listSecrets(slug) {
|
|
60847
60904
|
const j2 = await must("GET", `/repos/${slug}/actions/secrets?per_page=100`, "\u67E5\u4ED3\u5E93 Secrets");
|
|
60848
60905
|
const rows = Array.isArray(j2?.secrets) ? j2.secrets : [];
|
|
@@ -61408,6 +61465,15 @@ async function setSecret(exec, api, args) {
|
|
|
61408
61465
|
throw new RepoError(err instanceof Error ? err.message : String(err));
|
|
61409
61466
|
}
|
|
61410
61467
|
}
|
|
61468
|
+
async function deleteSecret(exec, api, args) {
|
|
61469
|
+
const info = await repoInfo(exec, args.dir);
|
|
61470
|
+
if (!info) throw new RepoError("\u8FD8\u6CA1\u6709\u4ED3\u5E93\uFF0CSecrets \u6CA1\u5730\u65B9\u5220");
|
|
61471
|
+
try {
|
|
61472
|
+
await api.deleteSecret(repoSlug(info.url), args.env);
|
|
61473
|
+
} catch (err) {
|
|
61474
|
+
throw new RepoError(err instanceof Error ? err.message : String(err));
|
|
61475
|
+
}
|
|
61476
|
+
}
|
|
61411
61477
|
async function listSecrets(exec, api, dir) {
|
|
61412
61478
|
const info = await repoInfo(exec, dir);
|
|
61413
61479
|
if (!info) return [];
|
|
@@ -61827,6 +61893,36 @@ function buildDeployHandlers(deps) {
|
|
|
61827
61893
|
secretsCache.delete(args.personaId);
|
|
61828
61894
|
return view(args.personaId);
|
|
61829
61895
|
};
|
|
61896
|
+
const setEngineAuth = async (frame, _client, ctx) => {
|
|
61897
|
+
ensureOwner(ctx);
|
|
61898
|
+
const args = parseArgs2(DeploySetEngineAuthArgsSchema, frame, "deploy:setEngineAuth");
|
|
61899
|
+
const dir = mustPersona(args.personaId);
|
|
61900
|
+
let writes;
|
|
61901
|
+
if (args.auth) {
|
|
61902
|
+
let baseUrl;
|
|
61903
|
+
try {
|
|
61904
|
+
baseUrl = normalizeEngineBaseUrl(args.auth.baseUrl);
|
|
61905
|
+
} catch (err) {
|
|
61906
|
+
throw invalid(err instanceof Error ? err.message : String(err));
|
|
61907
|
+
}
|
|
61908
|
+
const apiKey = args.auth.apiKey.trim();
|
|
61909
|
+
if (!apiKey) throw invalid("key \u4E0D\u80FD\u662F\u7A7A\u7684");
|
|
61910
|
+
if (/[\s\p{Cc}]/u.test(apiKey)) throw invalid("key \u91CC\u4E0D\u80FD\u6709\u7A7A\u767D\u6216\u63A7\u5236\u5B57\u7B26\uFF08\u591A\u534A\u662F\u7C98\u8D34\u65F6\u5E26\u8FDB\u4E86\u6362\u884C\u6216\u7A7A\u683C\uFF09");
|
|
61911
|
+
writes = [[ENGINE_AUTH_SECRETS.apiKey, apiKey], [ENGINE_AUTH_SECRETS.baseUrl, baseUrl]];
|
|
61912
|
+
}
|
|
61913
|
+
const { api } = await requireGithub();
|
|
61914
|
+
try {
|
|
61915
|
+
if (writes) {
|
|
61916
|
+
await deleteSecret(deps.exec, api, { dir, env: ENGINE_AUTH_SECRETS.baseUrl });
|
|
61917
|
+
for (const [env, value] of writes) await setSecret(deps.exec, api, { dir, env, value });
|
|
61918
|
+
} else for (const env of [ENGINE_AUTH_SECRETS.apiKey, ENGINE_AUTH_SECRETS.baseUrl]) await deleteSecret(deps.exec, api, { dir, env });
|
|
61919
|
+
} catch (err) {
|
|
61920
|
+
throw toClawdError(err);
|
|
61921
|
+
} finally {
|
|
61922
|
+
secretsCache.delete(args.personaId);
|
|
61923
|
+
}
|
|
61924
|
+
return view(args.personaId);
|
|
61925
|
+
};
|
|
61830
61926
|
async function settlePackage(pkg) {
|
|
61831
61927
|
const localVersion = await deps.probeLocalVersion(pkg);
|
|
61832
61928
|
const { artifact: reported, ...rest } = pkg;
|
|
@@ -61970,14 +62066,16 @@ function buildDeployHandlers(deps) {
|
|
|
61970
62066
|
throw invalid(repo2.dirty ? "\u6709\u672A\u63D0\u4EA4\u7684\u6539\u52A8\uFF0C\u6E05\u5355\u662F\u6539\u52A8\u524D\u626B\u7684\u2014\u2014\u91CD\u65B0\u626B\u63CF" : "\u8FD9\u6B21\u626B\u63CF\u5BF9\u5E94\u7684\u4E0D\u662F\u5F53\u524D\u8FD9\u4E00\u7248 persona\u2014\u2014\u91CD\u65B0\u626B\u63CF");
|
|
61971
62067
|
}
|
|
61972
62068
|
const blockers = [];
|
|
61973
|
-
let
|
|
62069
|
+
let secrets;
|
|
61974
62070
|
try {
|
|
61975
|
-
|
|
62071
|
+
secrets = await cachedSecrets(personaId2, dir, api, true);
|
|
61976
62072
|
} catch (err) {
|
|
61977
62073
|
throw toClawdError(err);
|
|
61978
62074
|
}
|
|
62075
|
+
const present = new Set(secrets.filter((p3) => p3.setAt).map((p3) => p3.env));
|
|
61979
62076
|
const missing = requiredEnvNames(entry.manifest).filter((e) => !present.has(e));
|
|
61980
62077
|
if (missing.length > 0) blockers.push(`${missing.join(" / ")} \u8FD8\u6CA1\u586B`);
|
|
62078
|
+
if (engineAuthState(secrets) === "partial") blockers.push(ENGINE_AUTH_PARTIAL_BLOCKER);
|
|
61981
62079
|
for (const c2 of entry.manifest.connectors) blockers.push(...connectorBlockers(c2));
|
|
61982
62080
|
for (const p3 of entry.manifest.packages) blockers.push(...packageBlockers(p3));
|
|
61983
62081
|
if (!deps.personaEngine(personaId2)?.model) {
|
|
@@ -62053,6 +62151,7 @@ function buildDeployHandlers(deps) {
|
|
|
62053
62151
|
"deploy:scan": scanHandler,
|
|
62054
62152
|
"deploy:patch": patch,
|
|
62055
62153
|
"deploy:putSecret": putSecret,
|
|
62154
|
+
"deploy:setEngineAuth": setEngineAuth,
|
|
62056
62155
|
"deploy:reportFinding": reportFinding,
|
|
62057
62156
|
"deploy:finishScan": finishScan,
|
|
62058
62157
|
"deploy:release": releaseHandler,
|
|
@@ -64007,7 +64106,7 @@ function openHttpLineStream(opts) {
|
|
|
64007
64106
|
if (closed || !sessionId) return;
|
|
64008
64107
|
const url = gatewayUrl + GATEWAY_ROUTES.sessionMirror(personaId2, sessionId);
|
|
64009
64108
|
try {
|
|
64010
|
-
const res = await fetchImpl(url, { method: "POST", headers, body: turn ? JSON.stringify({ turn: { outcome: turn.outcome } }) : "" });
|
|
64109
|
+
const res = await fetchImpl(url, { method: "POST", headers, body: turn ? JSON.stringify({ turn: { outcome: turn.outcome, ...turn.afterFirstByteMs !== void 0 ? { afterFirstByteMs: turn.afterFirstByteMs } : {} } }) : "" });
|
|
64011
64110
|
if (!res.ok) logger?.warn("cloud session mirror failed", { status: res.status });
|
|
64012
64111
|
} catch (e) {
|
|
64013
64112
|
if (!closed) logger?.warn("cloud session mirror error", { message: e.message });
|
|
@@ -64226,7 +64325,9 @@ function createCloudCodexSession(ctx, sink, deps) {
|
|
|
64226
64325
|
kill: () => stream.close(),
|
|
64227
64326
|
// 云 persona 运行看板(design 2026-09-23-cloud-persona-metrics §3.7):提问那一行带「一轮开始」头,轮末镜像顺带报这一轮的结果
|
|
64228
64327
|
onTurnStarting: () => channel?.markNextLineTurnStart(),
|
|
64229
|
-
|
|
64328
|
+
// 轮末镜像带上这一轮的结果与首字节(design 2026-09-23-cloud-persona-metrics §3.7)
|
|
64329
|
+
onTurnCompleted: (outcome, afterFirstByteMs) => void channel?.mirror({ outcome, ...afterFirstByteMs !== void 0 ? { afterFirstByteMs } : {} }),
|
|
64330
|
+
now: deps.now
|
|
64230
64331
|
});
|
|
64231
64332
|
if (!personaId2) {
|
|
64232
64333
|
queueMicrotask(() => {
|
|
@@ -64563,6 +64664,7 @@ function drivePiSession(opts) {
|
|
|
64563
64664
|
let turnErrored = false;
|
|
64564
64665
|
let turnInterrupted = false;
|
|
64565
64666
|
let turnOpen = false;
|
|
64667
|
+
const firstByte = createFirstByteClock(opts.now);
|
|
64566
64668
|
let handshakeFailed = false;
|
|
64567
64669
|
let exited = false;
|
|
64568
64670
|
const finish = (code) => {
|
|
@@ -64574,7 +64676,7 @@ function drivePiSession(opts) {
|
|
|
64574
64676
|
sink.pushEvents([{ kind: "error", message }, { kind: "turn_end", reason: "completed" }]);
|
|
64575
64677
|
if (!opened) return;
|
|
64576
64678
|
turnOpen = false;
|
|
64577
|
-
opts.onTurnCompleted?.("failure");
|
|
64679
|
+
opts.onTurnCompleted?.("failure", firstByte.afterFirstByteMs());
|
|
64578
64680
|
};
|
|
64579
64681
|
const handleUiRequest = (ev) => {
|
|
64580
64682
|
const method = str2(ev.method);
|
|
@@ -64601,14 +64703,17 @@ function drivePiSession(opts) {
|
|
|
64601
64703
|
return;
|
|
64602
64704
|
}
|
|
64603
64705
|
const events = translatePiEvent(ev, st2);
|
|
64604
|
-
if (events.length)
|
|
64706
|
+
if (events.length) {
|
|
64707
|
+
if (turnOpen) firstByte.see(events);
|
|
64708
|
+
sink.pushEvents(events);
|
|
64709
|
+
}
|
|
64605
64710
|
for (const e of events) {
|
|
64606
64711
|
if (e.kind === "error") turnErrored = true;
|
|
64607
64712
|
if (e.kind === "turn_end" && e.reason === "interrupted") turnInterrupted = true;
|
|
64608
64713
|
}
|
|
64609
64714
|
if (ev.type === "agent_settled") {
|
|
64610
64715
|
turnOpen = false;
|
|
64611
|
-
opts.onTurnCompleted?.(turnInterrupted ? "interrupted" : turnErrored ? "failure" : "success");
|
|
64716
|
+
opts.onTurnCompleted?.(turnInterrupted ? "interrupted" : turnErrored ? "failure" : "success", firstByte.afterFirstByteMs());
|
|
64612
64717
|
}
|
|
64613
64718
|
},
|
|
64614
64719
|
onClose: () => finish(opts.exitCodeOnClose?.() ?? null)
|
|
@@ -64644,6 +64749,7 @@ function drivePiSession(opts) {
|
|
|
64644
64749
|
opened = !turnOpen;
|
|
64645
64750
|
if (opened) {
|
|
64646
64751
|
turnOpen = true;
|
|
64752
|
+
firstByte.reset();
|
|
64647
64753
|
opts.onTurnStarting?.();
|
|
64648
64754
|
}
|
|
64649
64755
|
const r2 = await client.request({
|
|
@@ -64949,7 +65055,9 @@ function createCloudPiSession(ctx, sink, deps) {
|
|
|
64949
65055
|
kill: () => stream.close(),
|
|
64950
65056
|
// 云 persona 运行看板(design 2026-09-23-cloud-persona-metrics §3.7):提问那一行带「一轮开始」头,轮末镜像顺带报这一轮的结果
|
|
64951
65057
|
onTurnStarting: () => channel?.markNextLineTurnStart(),
|
|
64952
|
-
|
|
65058
|
+
// 轮末镜像带上这一轮的结果与首字节(design 2026-09-23-cloud-persona-metrics §3.7)
|
|
65059
|
+
onTurnCompleted: (outcome, afterFirstByteMs) => void channel?.mirror({ outcome, ...afterFirstByteMs !== void 0 ? { afterFirstByteMs } : {} }),
|
|
65060
|
+
now: deps.now
|
|
64953
65061
|
});
|
|
64954
65062
|
if (!personaId2) {
|
|
64955
65063
|
queueMicrotask(() => {
|
|
@@ -71990,6 +72098,7 @@ var METHOD_GRANT_MAP = {
|
|
|
71990
72098
|
"deploy:scan": ADMIN_ANY,
|
|
71991
72099
|
"deploy:patch": ADMIN_ANY,
|
|
71992
72100
|
"deploy:putSecret": ADMIN_ANY,
|
|
72101
|
+
"deploy:setEngineAuth": ADMIN_ANY,
|
|
71993
72102
|
"deploy:reportFinding": ADMIN_ANY,
|
|
71994
72103
|
"deploy:finishScan": ADMIN_ANY,
|
|
71995
72104
|
"deploy:release": ADMIN_ANY,
|
|
@@ -72207,6 +72316,7 @@ var HUMAN_ONLY_METHODS = [
|
|
|
72207
72316
|
"deploy:scan",
|
|
72208
72317
|
"deploy:release",
|
|
72209
72318
|
"deploy:putSecret",
|
|
72319
|
+
"deploy:setEngineAuth",
|
|
72210
72320
|
"deploy:rerunJob",
|
|
72211
72321
|
"deploy:unpublish",
|
|
72212
72322
|
"githubAuth:oauthStart",
|
|
@@ -72253,7 +72363,7 @@ function computeMethodAccess(args) {
|
|
|
72253
72363
|
}
|
|
72254
72364
|
|
|
72255
72365
|
// src/version.ts
|
|
72256
|
-
var version = "0.2.
|
|
72366
|
+
var version = "0.2.585".length > 0 ? "0.2.585" : "dev";
|
|
72257
72367
|
|
|
72258
72368
|
// src/cli-probe/probe.ts
|
|
72259
72369
|
var fs80 = __toESM(require("fs"), 1);
|