@clawos-dev/clawd 0.2.622 → 0.2.624
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 +495 -267
- package/dist/cli.cjs +20818 -19773
- package/dist/cloud-persona-conversations.html +73 -73
- package/dist/dispatch/mcp-server.cjs +233 -101
- package/dist/persona-defaults/persona-app-builder/mcp/clawd-app-builder/mcp-server.cjs +495 -267
- package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/mcp-server.cjs +495 -267
- package/dist/share-ui/assets/{guest-nVklLeTD.js → guest-DBwcqbLb.js} +141 -141
- package/dist/share-ui/guest.html +1 -1
- package/package.json +1 -1
|
@@ -21593,6 +21593,46 @@ var EnvEvidenceSchema = external_exports.object({
|
|
|
21593
21593
|
quote: external_exports.string().min(1)
|
|
21594
21594
|
});
|
|
21595
21595
|
|
|
21596
|
+
// ../protocol/src/release-schemas.ts
|
|
21597
|
+
var DEPLOY_ENVIRONMENTS = ["integration", "production"];
|
|
21598
|
+
var DeployEnvironmentSchema = external_exports.enum(DEPLOY_ENVIRONMENTS);
|
|
21599
|
+
var ImageDigestSchema = external_exports.string().regex(/^[a-z0-9.-]+(?::[0-9]+)?\/[a-z0-9._/-]+@sha256:[a-f0-9]{64}$/);
|
|
21600
|
+
var SourceCommitSchema = external_exports.string().regex(/^[a-f0-9]{40}$/);
|
|
21601
|
+
var IntegrationEndpointSchema = external_exports.string().refine((value) => {
|
|
21602
|
+
try {
|
|
21603
|
+
const url = new URL(value);
|
|
21604
|
+
return url.protocol === "https:" && !url.username && !url.password && !url.search && !url.hash && url.pathname === "/" && /(^|[.-])int([.-]|$)/.test(url.hostname);
|
|
21605
|
+
} catch {
|
|
21606
|
+
return false;
|
|
21607
|
+
}
|
|
21608
|
+
}, "\u6D4B\u8BD5\u9A8C\u8BC1\u5730\u5740\u5FC5\u987B\u660E\u786E\u6307\u5411 int HTTPS \u73AF\u5883");
|
|
21609
|
+
var VerificationSchema = external_exports.object({
|
|
21610
|
+
status: external_exports.literal("passed"),
|
|
21611
|
+
fingerprint: external_exports.string().regex(/^[a-f0-9]{64}$/),
|
|
21612
|
+
checks: external_exports.array(external_exports.string().regex(/^[a-z0-9-]+$/)),
|
|
21613
|
+
endpoint: IntegrationEndpointSchema,
|
|
21614
|
+
verifiedAt: external_exports.string().refine((s) => Number.isFinite(Date.parse(s)))
|
|
21615
|
+
}).strict();
|
|
21616
|
+
var VerifiedPersonaReleaseSchema = external_exports.object({
|
|
21617
|
+
version: external_exports.literal(1),
|
|
21618
|
+
environment: external_exports.literal("integration"),
|
|
21619
|
+
component: external_exports.literal("persona"),
|
|
21620
|
+
image: ImageDigestSchema,
|
|
21621
|
+
commit: SourceCommitSchema,
|
|
21622
|
+
baseImage: ImageDigestSchema,
|
|
21623
|
+
pipelineCommit: SourceCommitSchema,
|
|
21624
|
+
repository: external_exports.string().regex(/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/),
|
|
21625
|
+
verification: VerificationSchema.refine((v) => v.checks.includes("persona-smoke"))
|
|
21626
|
+
}).strict();
|
|
21627
|
+
var VerifiedBaseReleaseSchema = external_exports.object({
|
|
21628
|
+
version: external_exports.literal(1),
|
|
21629
|
+
environment: external_exports.literal("integration"),
|
|
21630
|
+
component: external_exports.literal("base"),
|
|
21631
|
+
image: ImageDigestSchema,
|
|
21632
|
+
commit: SourceCommitSchema,
|
|
21633
|
+
verification: VerificationSchema.refine((v) => v.checks.includes("base-smoke"))
|
|
21634
|
+
}).strict();
|
|
21635
|
+
|
|
21596
21636
|
// ../protocol/src/deploy-schemas.ts
|
|
21597
21637
|
var DeployFileSchema = external_exports.object({
|
|
21598
21638
|
version: external_exports.literal(1),
|
|
@@ -21621,15 +21661,44 @@ var DeployScanSchema = external_exports.object({
|
|
|
21621
21661
|
error: external_exports.string().optional()
|
|
21622
21662
|
}).strict();
|
|
21623
21663
|
var DeployReleasedSchema = external_exports.object({
|
|
21664
|
+
/** Legacy wire records can omit these; file migration always materializes them. */
|
|
21665
|
+
id: external_exports.string().min(1).optional(),
|
|
21666
|
+
environment: DeployEnvironmentSchema.optional(),
|
|
21667
|
+
legacy: external_exports.boolean().optional(),
|
|
21624
21668
|
head: external_exports.string().min(1),
|
|
21625
21669
|
contentHead: external_exports.string().min(1),
|
|
21626
21670
|
scanId: external_exports.string().min(1),
|
|
21627
|
-
at: external_exports.number()
|
|
21671
|
+
at: external_exports.number(),
|
|
21672
|
+
pushed: external_exports.boolean().optional(),
|
|
21673
|
+
runId: external_exports.number().int().positive().optional(),
|
|
21674
|
+
runAttempt: external_exports.number().int().positive().optional(),
|
|
21675
|
+
artifactId: external_exports.number().int().positive().optional(),
|
|
21676
|
+
verified: VerifiedPersonaReleaseSchema.optional(),
|
|
21677
|
+
confirmation: external_exports.object({
|
|
21678
|
+
fingerprint: external_exports.string().regex(/^[a-f0-9]{64}$/),
|
|
21679
|
+
runId: external_exports.number().int().positive(),
|
|
21680
|
+
runAttempt: external_exports.number().int().positive(),
|
|
21681
|
+
at: external_exports.number()
|
|
21682
|
+
}).strict().optional()
|
|
21683
|
+
}).strict();
|
|
21684
|
+
var DEPLOY_PROMOTION_PHASES = ["prepared", "main-pushed", "dispatching", "dispatched", "completed", "failed"];
|
|
21685
|
+
var DeployPromotionSchema = external_exports.object({
|
|
21686
|
+
id: external_exports.string().min(1),
|
|
21687
|
+
releaseId: external_exports.string().min(1),
|
|
21688
|
+
at: external_exports.number(),
|
|
21689
|
+
/** Artifact fixed when the user authorizes this action; int reruns cannot replace it. */
|
|
21690
|
+
verified: VerifiedPersonaReleaseSchema.optional(),
|
|
21691
|
+
phase: external_exports.enum(DEPLOY_PROMOTION_PHASES),
|
|
21692
|
+
expectedMain: external_exports.string().optional(),
|
|
21693
|
+
runId: external_exports.number().int().positive().optional(),
|
|
21694
|
+
runAttempt: external_exports.number().int().positive().optional(),
|
|
21695
|
+
error: external_exports.string().optional()
|
|
21628
21696
|
}).strict();
|
|
21629
21697
|
var DeployScanFileSchema = external_exports.object({
|
|
21630
|
-
version: external_exports.literal(
|
|
21698
|
+
version: external_exports.literal(4),
|
|
21631
21699
|
scans: external_exports.array(DeployScanSchema),
|
|
21632
|
-
releases: external_exports.array(DeployReleasedSchema)
|
|
21700
|
+
releases: external_exports.array(DeployReleasedSchema),
|
|
21701
|
+
promotions: external_exports.array(DeployPromotionSchema).default([])
|
|
21633
21702
|
}).strict();
|
|
21634
21703
|
var DeployRepoSchema = external_exports.object({
|
|
21635
21704
|
url: external_exports.string().min(1),
|
|
@@ -21663,7 +21732,13 @@ var DeployRunSchema = external_exports.object({
|
|
|
21663
21732
|
status: external_exports.enum(["queued", "running", "completed"]),
|
|
21664
21733
|
htmlUrl: external_exports.string().min(1),
|
|
21665
21734
|
/** run 刚入队时可能一条都还没有 */
|
|
21666
|
-
jobs: external_exports.array(DeployJobSchema)
|
|
21735
|
+
jobs: external_exports.array(DeployJobSchema),
|
|
21736
|
+
environment: DeployEnvironmentSchema.optional(),
|
|
21737
|
+
branch: external_exports.string().optional(),
|
|
21738
|
+
event: external_exports.string().optional(),
|
|
21739
|
+
runAttempt: external_exports.number().int().positive().optional(),
|
|
21740
|
+
conclusion: external_exports.enum(["success", "failure"]).optional(),
|
|
21741
|
+
promotionId: external_exports.string().optional()
|
|
21667
21742
|
}).strict();
|
|
21668
21743
|
var DeployUnpublishRunSchema = external_exports.object({
|
|
21669
21744
|
runId: external_exports.number(),
|
|
@@ -21678,6 +21753,23 @@ var DeployStateSchema = external_exports.object({
|
|
|
21678
21753
|
repo: DeployRepoSchema.optional(),
|
|
21679
21754
|
scans: external_exports.array(DeployScanSchema).default([]),
|
|
21680
21755
|
releases: external_exports.array(DeployReleasedSchema).default([]),
|
|
21756
|
+
promotions: external_exports.array(DeployPromotionSchema).optional(),
|
|
21757
|
+
targets: external_exports.object({
|
|
21758
|
+
integration: external_exports.object({
|
|
21759
|
+
run: DeployRunSchema.optional(),
|
|
21760
|
+
secrets: external_exports.array(DeploySecretPresenceSchema).optional(),
|
|
21761
|
+
online: external_exports.boolean().optional(),
|
|
21762
|
+
image: ImageDigestSchema.optional(),
|
|
21763
|
+
unpublish: DeployUnpublishRunSchema.optional()
|
|
21764
|
+
}).strict().optional(),
|
|
21765
|
+
production: external_exports.object({
|
|
21766
|
+
run: DeployRunSchema.optional(),
|
|
21767
|
+
secrets: external_exports.array(DeploySecretPresenceSchema).optional(),
|
|
21768
|
+
online: external_exports.boolean().optional(),
|
|
21769
|
+
image: ImageDigestSchema.optional(),
|
|
21770
|
+
unpublish: DeployUnpublishRunSchema.optional()
|
|
21771
|
+
}).strict().optional()
|
|
21772
|
+
}).strict().optional(),
|
|
21681
21773
|
/** 没仓库时缺席(查不了) */
|
|
21682
21774
|
secrets: external_exports.array(DeploySecretPresenceSchema).optional(),
|
|
21683
21775
|
/**
|
|
@@ -21704,13 +21796,16 @@ var DeployUnpublishResultSchema = external_exports.object({
|
|
|
21704
21796
|
var DeployPatchResultSchema = DeployStateSchema.pick({ scans: true });
|
|
21705
21797
|
var DeployReleaseResultSchema = external_exports.object({
|
|
21706
21798
|
sha: external_exports.string().min(1),
|
|
21707
|
-
actionsUrl: external_exports.string().min(1)
|
|
21799
|
+
actionsUrl: external_exports.string().min(1),
|
|
21800
|
+
releaseId: external_exports.string().optional()
|
|
21708
21801
|
}).strict();
|
|
21709
21802
|
var DeployPersonaArgsSchema = external_exports.object({
|
|
21710
21803
|
personaId: external_exports.string().min(1)
|
|
21711
21804
|
}).strict();
|
|
21712
21805
|
var DeployGetArgsSchema = DeployPersonaArgsSchema.extend({
|
|
21713
|
-
releaseHead: external_exports.string().min(1).optional()
|
|
21806
|
+
releaseHead: external_exports.string().min(1).optional(),
|
|
21807
|
+
releaseId: external_exports.string().min(1).optional(),
|
|
21808
|
+
environment: DeployEnvironmentSchema.optional()
|
|
21714
21809
|
}).strict();
|
|
21715
21810
|
var DeployScanArgsSchema = DeployPersonaArgsSchema.extend({
|
|
21716
21811
|
scanBase: ScanBaseKindSchema.optional()
|
|
@@ -21718,6 +21813,13 @@ var DeployScanArgsSchema = DeployPersonaArgsSchema.extend({
|
|
|
21718
21813
|
var DeployReleaseArgsSchema = DeployPersonaArgsSchema.extend({
|
|
21719
21814
|
scanId: external_exports.string().min(1)
|
|
21720
21815
|
}).strict();
|
|
21816
|
+
var DeployConfirmTestArgsSchema = DeployPersonaArgsSchema.extend({ releaseId: external_exports.string().min(1) }).strict();
|
|
21817
|
+
var DeployPromoteArgsSchema = DeployConfirmTestArgsSchema;
|
|
21818
|
+
var DeployOpenTestArgsSchema = DeployConfirmTestArgsSchema;
|
|
21819
|
+
var DeployEnvironmentArgsSchema = DeployPersonaArgsSchema.extend({ environment: DeployEnvironmentSchema.default("production") }).strict();
|
|
21820
|
+
var DeployConfirmTestResultSchema = external_exports.object({ confirmation: DeployReleasedSchema.shape.confirmation.unwrap() }).strict();
|
|
21821
|
+
var DeployPromoteResultSchema = external_exports.object({ promotion: DeployPromotionSchema }).strict();
|
|
21822
|
+
var DeployOpenTestResultSchema = external_exports.object({ personaId: external_exports.string().min(1), expectedImage: ImageDigestSchema }).strict();
|
|
21721
21823
|
var DeployPatchArgsSchema = external_exports.object({
|
|
21722
21824
|
personaId: external_exports.string().min(1),
|
|
21723
21825
|
scanId: external_exports.string().min(1),
|
|
@@ -21733,6 +21835,7 @@ var DeployPatchArgsSchema = external_exports.object({
|
|
|
21733
21835
|
}).strict();
|
|
21734
21836
|
var DeployPutSecretArgsSchema = external_exports.object({
|
|
21735
21837
|
personaId: external_exports.string().min(1),
|
|
21838
|
+
environment: DeployEnvironmentSchema.default("production"),
|
|
21736
21839
|
/** 按哪次扫描的清单校验凭据名 / env 名。值本身是仓库级的(GitHub Secrets),跟扫描无关 */
|
|
21737
21840
|
scanId: external_exports.string().min(1),
|
|
21738
21841
|
name: external_exports.string().min(1),
|
|
@@ -21741,6 +21844,7 @@ var DeployPutSecretArgsSchema = external_exports.object({
|
|
|
21741
21844
|
}).strict();
|
|
21742
21845
|
var DeploySetEngineAuthArgsSchema = external_exports.object({
|
|
21743
21846
|
personaId: external_exports.string().min(1),
|
|
21847
|
+
environment: DeployEnvironmentSchema.default("production"),
|
|
21744
21848
|
channelId: external_exports.string().min(1).optional(),
|
|
21745
21849
|
auth: external_exports.object({ baseUrl: external_exports.string(), apiKey: external_exports.string() }).strict().nullable().optional()
|
|
21746
21850
|
}).strict().refine((data) => data.channelId !== void 0 || data.auth !== void 0, {
|
|
@@ -21748,6 +21852,8 @@ var DeploySetEngineAuthArgsSchema = external_exports.object({
|
|
|
21748
21852
|
});
|
|
21749
21853
|
var DeployRerunJobArgsSchema = external_exports.object({
|
|
21750
21854
|
personaId: external_exports.string().min(1),
|
|
21855
|
+
environment: DeployEnvironmentSchema.default("production"),
|
|
21856
|
+
releaseId: external_exports.string().optional(),
|
|
21751
21857
|
jobId: external_exports.number()
|
|
21752
21858
|
}).strict();
|
|
21753
21859
|
var DeployReportFindingArgsSchema = external_exports.object({
|
|
@@ -21769,6 +21875,99 @@ var DeployFinishScanArgsSchema = external_exports.object({
|
|
|
21769
21875
|
notes: external_exports.array(external_exports.string()).default([])
|
|
21770
21876
|
}).strict();
|
|
21771
21877
|
|
|
21878
|
+
// ../protocol/src/feishu-auth.ts
|
|
21879
|
+
var AuthEnvironmentArgsSchema = external_exports.object({ environment: DeployEnvironmentSchema.default("production") }).strict();
|
|
21880
|
+
var DeviceEntrySchema = external_exports.object({
|
|
21881
|
+
/**
|
|
21882
|
+
* 设备标识(决策 #15:daemon 本地生成的 dev-<uuid>,与人的身份 unionId 无关)。
|
|
21883
|
+
* 中心 server clawd_devices 注册表仅作服务发现(url 下发 + 目录),不在安全路径上。
|
|
21884
|
+
*/
|
|
21885
|
+
deviceId: external_exports.string().min(1),
|
|
21886
|
+
name: external_exports.string().min(1),
|
|
21887
|
+
url: external_exports.string().min(1)
|
|
21888
|
+
});
|
|
21889
|
+
var DeviceListResponseSchema = external_exports.object({
|
|
21890
|
+
type: external_exports.literal("device:list:ok"),
|
|
21891
|
+
devices: external_exports.array(DeviceEntrySchema)
|
|
21892
|
+
});
|
|
21893
|
+
var DeviceConnectArgsSchema = external_exports.object({
|
|
21894
|
+
deviceId: external_exports.string().min(1),
|
|
21895
|
+
/**
|
|
21896
|
+
* 目标设备的 ws/tunnel 地址(可选):
|
|
21897
|
+
* - 公开目录点击:带 url(device:list 已下发,省一次 server 查询)
|
|
21898
|
+
* - 凭 deviceId 连接:缺省 url → daemon exchange 时由中心 server 下发该设备上报的 url
|
|
21899
|
+
* - 注册表不在安全路径上:知道对方 url 时显式传入即可连接(不依赖中心 server 服务发现)
|
|
21900
|
+
*/
|
|
21901
|
+
url: external_exports.string().min(1).optional(),
|
|
21902
|
+
/** Optional display name; otherwise populate it from the handshake acknowledgement. */
|
|
21903
|
+
name: external_exports.string().optional()
|
|
21904
|
+
});
|
|
21905
|
+
var DeviceConnectResponseSchema = external_exports.object({
|
|
21906
|
+
type: external_exports.literal("device:connect:ok"),
|
|
21907
|
+
deviceId: external_exports.string(),
|
|
21908
|
+
name: external_exports.string(),
|
|
21909
|
+
url: external_exports.string()
|
|
21910
|
+
});
|
|
21911
|
+
var FeishuIdentitySchema = external_exports.object({
|
|
21912
|
+
/** 归属人 id(决策 #16:TTC unique_id,取代飞书 union_id;跨登录方式稳定) */
|
|
21913
|
+
ownerId: external_exports.string().min(1),
|
|
21914
|
+
/** 身份来源:'ttc'(飞书/手机/邮箱登入 TTC)| 'google' | ...(决策 #16,拓展用) */
|
|
21915
|
+
provider: external_exports.string().min(1),
|
|
21916
|
+
displayName: external_exports.string().min(1),
|
|
21917
|
+
/** TTC user_info 接口 data.avatar_url,可缺省 */
|
|
21918
|
+
avatarUrl: external_exports.string().optional(),
|
|
21919
|
+
/** TTC user_info 接口 data.union_id(飞书 union_id;dataclaw 可信入口 X-User-UnionId 用),可缺省 */
|
|
21920
|
+
unionId: external_exports.string().optional()
|
|
21921
|
+
});
|
|
21922
|
+
var AuthLoginStartResponseSchema = external_exports.object({
|
|
21923
|
+
type: external_exports.literal("auth:login:start:ok"),
|
|
21924
|
+
environment: DeployEnvironmentSchema.optional(),
|
|
21925
|
+
authUrl: external_exports.string().min(1),
|
|
21926
|
+
/** 防 CSRF 的一次性 nonce;回调时 daemon 校验 */
|
|
21927
|
+
state: external_exports.string().min(1)
|
|
21928
|
+
});
|
|
21929
|
+
var AuthGetIdentityResponseSchema = external_exports.object({
|
|
21930
|
+
type: external_exports.literal("auth:getIdentity:ok"),
|
|
21931
|
+
/** null = 未登录 */
|
|
21932
|
+
identity: FeishuIdentitySchema.nullable(),
|
|
21933
|
+
/** Stable device identifier independent of login, used for the shareable device link. */
|
|
21934
|
+
deviceId: external_exports.string().min(1)
|
|
21935
|
+
});
|
|
21936
|
+
var AuthLogoutResponseSchema = external_exports.object({
|
|
21937
|
+
type: external_exports.literal("auth:logout:ok")
|
|
21938
|
+
});
|
|
21939
|
+
var GatewayUrl = external_exports.string().nullable();
|
|
21940
|
+
var AuthApiKeyGetResponseSchema = external_exports.object({
|
|
21941
|
+
type: external_exports.literal("auth:apiKey:get:ok"),
|
|
21942
|
+
/** null = 还没发过。**发过就能一直看到** —— 中心存的是明文,设置页据此展示 */
|
|
21943
|
+
apiKey: external_exports.string().nullable(),
|
|
21944
|
+
/** ISO 时间;apiKey 为 null 时同为 null */
|
|
21945
|
+
createdAt: external_exports.string().nullable(),
|
|
21946
|
+
gatewayUrl: GatewayUrl
|
|
21947
|
+
});
|
|
21948
|
+
var AuthApiKeyRegenerateResponseSchema = external_exports.object({
|
|
21949
|
+
type: external_exports.literal("auth:apiKey:regenerate:ok"),
|
|
21950
|
+
/** 新发的那把。**旧的当场失效** —— 一人一把,按 union_id 覆盖 */
|
|
21951
|
+
apiKey: external_exports.string().min(1),
|
|
21952
|
+
createdAt: external_exports.string().min(1),
|
|
21953
|
+
gatewayUrl: GatewayUrl
|
|
21954
|
+
});
|
|
21955
|
+
var AuthApiKeyRevokeResponseSchema = external_exports.object({
|
|
21956
|
+
type: external_exports.literal("auth:apiKey:revoke:ok"),
|
|
21957
|
+
/** 之前有没有那把——没发过也算成功(幂等) */
|
|
21958
|
+
revoked: external_exports.boolean()
|
|
21959
|
+
});
|
|
21960
|
+
var AuthLoginDoneEventSchema = external_exports.object({
|
|
21961
|
+
type: external_exports.literal("auth:login:done"),
|
|
21962
|
+
environment: DeployEnvironmentSchema.optional(),
|
|
21963
|
+
identity: FeishuIdentitySchema
|
|
21964
|
+
});
|
|
21965
|
+
var AuthLoginFailedEventSchema = external_exports.object({
|
|
21966
|
+
type: external_exports.literal("auth:login:failed"),
|
|
21967
|
+
environment: DeployEnvironmentSchema.optional(),
|
|
21968
|
+
reason: external_exports.string()
|
|
21969
|
+
});
|
|
21970
|
+
|
|
21772
21971
|
// ../protocol/src/contact-remote-access.ts
|
|
21773
21972
|
var ContactSetRemoteAccessArgsSchema = external_exports.object({
|
|
21774
21973
|
deviceId: external_exports.string().min(1),
|
|
@@ -21886,95 +22085,6 @@ var ContactPinnedFrameSchema = external_exports.object({
|
|
|
21886
22085
|
pinnedAt: external_exports.number().int().nullable()
|
|
21887
22086
|
}).strict();
|
|
21888
22087
|
|
|
21889
|
-
// ../protocol/src/feishu-auth.ts
|
|
21890
|
-
var DeviceEntrySchema = external_exports.object({
|
|
21891
|
-
/**
|
|
21892
|
-
* 设备标识(决策 #15:daemon 本地生成的 dev-<uuid>,与人的身份 unionId 无关)。
|
|
21893
|
-
* 中心 server clawd_devices 注册表仅作服务发现(url 下发 + 目录),不在安全路径上。
|
|
21894
|
-
*/
|
|
21895
|
-
deviceId: external_exports.string().min(1),
|
|
21896
|
-
name: external_exports.string().min(1),
|
|
21897
|
-
url: external_exports.string().min(1)
|
|
21898
|
-
});
|
|
21899
|
-
var DeviceListResponseSchema = external_exports.object({
|
|
21900
|
-
type: external_exports.literal("device:list:ok"),
|
|
21901
|
-
devices: external_exports.array(DeviceEntrySchema)
|
|
21902
|
-
});
|
|
21903
|
-
var DeviceConnectArgsSchema = external_exports.object({
|
|
21904
|
-
deviceId: external_exports.string().min(1),
|
|
21905
|
-
/**
|
|
21906
|
-
* 目标设备的 ws/tunnel 地址(可选):
|
|
21907
|
-
* - 公开目录点击:带 url(device:list 已下发,省一次 server 查询)
|
|
21908
|
-
* - 凭 deviceId 连接:缺省 url → daemon exchange 时由中心 server 下发该设备上报的 url
|
|
21909
|
-
* - 注册表不在安全路径上:知道对方 url 时显式传入即可连接(不依赖中心 server 服务发现)
|
|
21910
|
-
*/
|
|
21911
|
-
url: external_exports.string().min(1).optional(),
|
|
21912
|
-
/** Optional display name; otherwise populate it from the handshake acknowledgement. */
|
|
21913
|
-
name: external_exports.string().optional()
|
|
21914
|
-
});
|
|
21915
|
-
var DeviceConnectResponseSchema = external_exports.object({
|
|
21916
|
-
type: external_exports.literal("device:connect:ok"),
|
|
21917
|
-
deviceId: external_exports.string(),
|
|
21918
|
-
name: external_exports.string(),
|
|
21919
|
-
url: external_exports.string()
|
|
21920
|
-
});
|
|
21921
|
-
var FeishuIdentitySchema = external_exports.object({
|
|
21922
|
-
/** 归属人 id(决策 #16:TTC unique_id,取代飞书 union_id;跨登录方式稳定) */
|
|
21923
|
-
ownerId: external_exports.string().min(1),
|
|
21924
|
-
/** 身份来源:'ttc'(飞书/手机/邮箱登入 TTC)| 'google' | ...(决策 #16,拓展用) */
|
|
21925
|
-
provider: external_exports.string().min(1),
|
|
21926
|
-
displayName: external_exports.string().min(1),
|
|
21927
|
-
/** TTC user_info 接口 data.avatar_url,可缺省 */
|
|
21928
|
-
avatarUrl: external_exports.string().optional(),
|
|
21929
|
-
/** TTC user_info 接口 data.union_id(飞书 union_id;dataclaw 可信入口 X-User-UnionId 用),可缺省 */
|
|
21930
|
-
unionId: external_exports.string().optional()
|
|
21931
|
-
});
|
|
21932
|
-
var AuthLoginStartResponseSchema = external_exports.object({
|
|
21933
|
-
type: external_exports.literal("auth:login:start:ok"),
|
|
21934
|
-
authUrl: external_exports.string().min(1),
|
|
21935
|
-
/** 防 CSRF 的一次性 nonce;回调时 daemon 校验 */
|
|
21936
|
-
state: external_exports.string().min(1)
|
|
21937
|
-
});
|
|
21938
|
-
var AuthGetIdentityResponseSchema = external_exports.object({
|
|
21939
|
-
type: external_exports.literal("auth:getIdentity:ok"),
|
|
21940
|
-
/** null = 未登录 */
|
|
21941
|
-
identity: FeishuIdentitySchema.nullable(),
|
|
21942
|
-
/** Stable device identifier independent of login, used for the shareable device link. */
|
|
21943
|
-
deviceId: external_exports.string().min(1)
|
|
21944
|
-
});
|
|
21945
|
-
var AuthLogoutResponseSchema = external_exports.object({
|
|
21946
|
-
type: external_exports.literal("auth:logout:ok")
|
|
21947
|
-
});
|
|
21948
|
-
var GatewayUrl = external_exports.string().nullable();
|
|
21949
|
-
var AuthApiKeyGetResponseSchema = external_exports.object({
|
|
21950
|
-
type: external_exports.literal("auth:apiKey:get:ok"),
|
|
21951
|
-
/** null = 还没发过。**发过就能一直看到** —— 中心存的是明文,设置页据此展示 */
|
|
21952
|
-
apiKey: external_exports.string().nullable(),
|
|
21953
|
-
/** ISO 时间;apiKey 为 null 时同为 null */
|
|
21954
|
-
createdAt: external_exports.string().nullable(),
|
|
21955
|
-
gatewayUrl: GatewayUrl
|
|
21956
|
-
});
|
|
21957
|
-
var AuthApiKeyRegenerateResponseSchema = external_exports.object({
|
|
21958
|
-
type: external_exports.literal("auth:apiKey:regenerate:ok"),
|
|
21959
|
-
/** 新发的那把。**旧的当场失效** —— 一人一把,按 union_id 覆盖 */
|
|
21960
|
-
apiKey: external_exports.string().min(1),
|
|
21961
|
-
createdAt: external_exports.string().min(1),
|
|
21962
|
-
gatewayUrl: GatewayUrl
|
|
21963
|
-
});
|
|
21964
|
-
var AuthApiKeyRevokeResponseSchema = external_exports.object({
|
|
21965
|
-
type: external_exports.literal("auth:apiKey:revoke:ok"),
|
|
21966
|
-
/** 之前有没有那把——没发过也算成功(幂等) */
|
|
21967
|
-
revoked: external_exports.boolean()
|
|
21968
|
-
});
|
|
21969
|
-
var AuthLoginDoneEventSchema = external_exports.object({
|
|
21970
|
-
type: external_exports.literal("auth:login:done"),
|
|
21971
|
-
identity: FeishuIdentitySchema
|
|
21972
|
-
});
|
|
21973
|
-
var AuthLoginFailedEventSchema = external_exports.object({
|
|
21974
|
-
type: external_exports.literal("auth:login:failed"),
|
|
21975
|
-
reason: external_exports.string()
|
|
21976
|
-
});
|
|
21977
|
-
|
|
21978
22088
|
// ../protocol/src/dispatch.ts
|
|
21979
22089
|
var DispatchOutcomeSchema = external_exports.discriminatedUnion("kind", [
|
|
21980
22090
|
external_exports.object({
|
|
@@ -22778,7 +22888,14 @@ var PersonaFileSchema = external_exports.object({
|
|
|
22778
22888
|
createdAt: external_exports.number(),
|
|
22779
22889
|
updatedAt: external_exports.number(),
|
|
22780
22890
|
/** 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. */
|
|
22781
|
-
cloud: external_exports.object({
|
|
22891
|
+
cloud: external_exports.object({
|
|
22892
|
+
gatewayUrl: external_exports.string().min(1),
|
|
22893
|
+
personaId: external_exports.string().min(1),
|
|
22894
|
+
publishedByMe: external_exports.boolean().optional(),
|
|
22895
|
+
environment: DeployEnvironmentSchema.optional(),
|
|
22896
|
+
expectedImage: ImageDigestSchema.optional(),
|
|
22897
|
+
testReleaseId: external_exports.string().optional()
|
|
22898
|
+
}).strict().optional()
|
|
22782
22899
|
}).strict();
|
|
22783
22900
|
var PersonaSkillSummarySchema = external_exports.object({
|
|
22784
22901
|
// 目录名作为 skill name(对齐 CC:frontmatter `name:` 仅作 displayName 用)
|
|
@@ -23012,6 +23129,9 @@ var AllowRuleSchema = external_exports.object({
|
|
|
23012
23129
|
createdAt: external_exports.string().min(1).optional()
|
|
23013
23130
|
});
|
|
23014
23131
|
var SessionFileSchema = external_exports.object({
|
|
23132
|
+
cloudEnvironment: DeployEnvironmentSchema.optional(),
|
|
23133
|
+
cloudExpectedImage: ImageDigestSchema.optional(),
|
|
23134
|
+
testReleaseId: external_exports.string().optional(),
|
|
23015
23135
|
sessionId: external_exports.string().min(1),
|
|
23016
23136
|
/** New gateway execution identity after session:new; defaults to sessionId for the first execution. */
|
|
23017
23137
|
cloudExecutionId: external_exports.string().min(1).optional(),
|
|
@@ -23888,9 +24008,21 @@ var METHOD_DOCS = {
|
|
|
23888
24008
|
summary: "\u539F\u6837\u91CD\u8DD1\u6700\u65B0\u90A3\u6761\u6D41\u6C34\u7EBF\u91CC\u5931\u8D25\u7684\u67D0\u4E00\u6BB5\uFF08GitHub REST rerun job\uFF09\u3002**\u540C\u4E00\u4E2A commit\u3001\u540C\u4E00\u4EFD\u8F93\u5165**\uFF0C\u4E0D\u4EA7\u751F\u65B0\u63D0\u4EA4\u2014\u2014\u6539\u4E86 persona \u5185\u5BB9\u8981 deploy:scan \u518D deploy:release\u3002jobId \u5FC5\u987B\u5C5E\u4E8E\u6700\u65B0\u90A3\u6761 run\uFF1Bowner-only",
|
|
23889
24009
|
args: DeployRerunJobArgsSchema
|
|
23890
24010
|
},
|
|
24011
|
+
"deploy:confirmTest": {
|
|
24012
|
+
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",
|
|
24013
|
+
args: DeployConfirmTestArgsSchema
|
|
24014
|
+
},
|
|
24015
|
+
"deploy:promote": {
|
|
24016
|
+
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",
|
|
24017
|
+
args: DeployPromoteArgsSchema
|
|
24018
|
+
},
|
|
24019
|
+
"deploy:openTest": {
|
|
24020
|
+
summary: "\u51C6\u5907\u5F53\u524D\u6D4B\u8BD5\u7248\u7684\u4E91 Persona \u4F1A\u8BDD\u5165\u53E3\uFF0C\u9501\u5B9A\u73AF\u5883\u548C\u5DF2\u6D4B\u955C\u50CF\uFF0Cowner-only\u3001human-only",
|
|
24021
|
+
args: DeployOpenTestArgsSchema
|
|
24022
|
+
},
|
|
23891
24023
|
"deploy:unpublish": {
|
|
23892
24024
|
summary: "\u4E0B\u7EBF\uFF1A\u89E6\u53D1 persona \u4ED3\u5E93\u91CC\u7684 clawd-unpublish.yml\uFF08workflow_dispatch\uFF09\uFF0C\u7531\u6D41\u6C34\u7EBF\u5728 gateway \u64A4\u6389\u6B63\u5F0F\u767B\u8BB0\u2014\u2014\u522B\u4EBA\u770B\u4E0D\u5230\u3001\u7528\u4E0D\u4E86\uFF1B\u4ED3\u5E93 / \u955C\u50CF / \u672C\u673A\u4E0A\u4E91\u8BB0\u5F55\u90FD\u4E0D\u52A8\uFF0C\u91CD\u65B0\u53D1\u5E03\u5C31\u56DE\u6765\u3002\u6700\u540E\u4E00\u6B21\u53D1\u5E03\u7684 commit \u91CC\u6CA1\u6709\u8FD9\u4EFD workflow\uFF08\u65E7\u6A21\u677F\uFF09\u65F6\u62D2\uFF0C\u8981\u5148\u91CD\u65B0\u53D1\u5E03\u4E00\u6B21\u3002\u56DE { before }\uFF1A\u89E6\u53D1\u4E4B\u524D\u73B0\u67E5\u7684\u6700\u65B0\u4E0B\u7EBF run id\uFF08\u6CA1\u4E0B\u7EBF\u8FC7 = null\uFF09\uFF0C\u9875\u9762\u62FF\u5B83\u8BA4\u65B0 run\uFF1Bowner-only\u3001human-only",
|
|
23893
|
-
args:
|
|
24025
|
+
args: DeployEnvironmentArgsSchema
|
|
23894
24026
|
},
|
|
23895
24027
|
"githubAuth:get": {
|
|
23896
24028
|
summary: "\u672C\u673A\u7684 GitHub \u8EAB\u4EFD\uFF1Aauthorized\uFF08@login\uFF0C\u6765\u81EA git \u51ED\u636E\u5B58\u50A8 / \u672C\u673A\u51ED\u636E\u8868\uFF09/ missing / invalid\uFF08GitHub \u4E0D\u8BA4\uFF09/ pending\uFF08\u7B49 GitHub \u8DF3\u56DE\u4E2D\u5FC3\uFF09\u3002\u8BBE\u7F6E\u9875\u300C\u8D26\u53F7\u300D\u3001\u4E0A\u4E91\u9875\u9876\u4E0A\u90A3\u5F20\u5361\u3001PR \u6536\u4EF6\u7BB1\u90FD\u770B\u5B83\uFF1Bpending \u671F\u9875\u9762\u6BCF 2 \u79D2\u8F6E\u8BE2\uFF0Cdaemon \u987A\u624B\u5411\u4E2D\u5FC3\u9886 token\u3002\u65E0\u53C2\u6570",
|
|
@@ -24312,7 +24444,7 @@ var METHOD_DOCS = {
|
|
|
24312
24444
|
},
|
|
24313
24445
|
"auth:login:start": {
|
|
24314
24446
|
summary: "\u8D77\u98DE\u4E66\u767B\u5F55\u6D41\u7A0B\uFF1A\u751F\u6210 state \u5E76\u8FD4\u56DE\u6388\u6743 URL\uFF0C\u56DE\u8C03\u8D70 HTTP /auth/callback \u843D\u76D8\u3002owner-only",
|
|
24315
|
-
args:
|
|
24447
|
+
args: AuthEnvironmentArgsSchema
|
|
24316
24448
|
},
|
|
24317
24449
|
"auth:getIdentity": {
|
|
24318
24450
|
summary: "\u53D6\u672C\u673A owner \u7684\u98DE\u4E66\u8EAB\u4EFD\uFF08ownerId / provider / displayName / unionId\uFF09+ **\u672C\u673A deviceId**\uFF08\u8BBE\u5907\u5C5E\u6027\uFF0C\u4E0E\u767B\u5F55\u6001\u65E0\u5173\uFF1Bdevice:connect / contact:* / inbox:* \u7684\u4E3B\u952E\u90FD\u662F\u5B83\uFF09\uFF1B\u7EDD\u4E0D\u8FD4\u56DE\u767B\u5F55\u7968",
|
|
@@ -24324,15 +24456,15 @@ var METHOD_DOCS = {
|
|
|
24324
24456
|
},
|
|
24325
24457
|
"auth:apiKey:get": {
|
|
24326
24458
|
summary: "\u8BFB\u56DE\u81EA\u5DF1\u90A3\u628A\u4E91 persona \u8C03\u7528 key\uFF08\u6CA1\u53D1\u8FC7 \u2192 apiKey:null\uFF09\u3002daemon \u62FF\u672C\u673A\u767B\u5F55\u51ED\u8BC1\u5411\u4E2D\u5FC3\u4EE3\u53D6\uFF0C\u51ED\u8BC1\u4E0D\u51FA ws\u3002owner-only",
|
|
24327
|
-
args:
|
|
24459
|
+
args: AuthEnvironmentArgsSchema
|
|
24328
24460
|
},
|
|
24329
24461
|
"auth:apiKey:regenerate": {
|
|
24330
24462
|
summary: "\u6362\u4E00\u628A\u65B0\u7684\u4E91 persona \u8C03\u7528 key\uFF0C**\u65E7\u7684\u5F53\u573A\u5931\u6548**\uFF08\u4E00\u4EBA\u4E00\u628A\uFF0C\u4E2D\u5FC3\u6309 union_id \u8986\u76D6\uFF09\u3002owner-only",
|
|
24331
|
-
args:
|
|
24463
|
+
args: AuthEnvironmentArgsSchema
|
|
24332
24464
|
},
|
|
24333
24465
|
"auth:apiKey:revoke": {
|
|
24334
24466
|
summary: "\u64A4\u9500\u81EA\u5DF1\u7684\u4E91 persona \u8C03\u7528 key\uFF1A\u4E2D\u5FC3\u5220\u6389\u90A3\u4E00\u884C\u3001**\u4E0D\u53D1\u65B0\u7684**\u3002gateway \u53EA\u5728\u5F00\u4F1A\u8BDD\u548C\u6BCF\u6B21\u4E0A\u884C\u65F6\u9A8C key\uFF0C\u6240\u4EE5\u5F00\u7740\u7684\u4E91\u4F1A\u8BDD\u4E0B\u4E00\u6761\u6D88\u606F\u624D\u53D1\u4E0D\u51FA\u53BB\u3001\u6B63\u5728\u8DD1\u7684\u90A3\u4E00\u8F6E\u4F1A\u8DD1\u5B8C\u3002\u6CA1\u53D1\u8FC7\u4E5F\u56DE ok\uFF08revoked:false\uFF09\u3002owner-only",
|
|
24335
|
-
args:
|
|
24467
|
+
args: AuthEnvironmentArgsSchema
|
|
24336
24468
|
},
|
|
24337
24469
|
"device:list": {
|
|
24338
24470
|
summary: "\u5217\u51FA\u516C\u5171\u8BBE\u5907\u76EE\u5F55\u91CC\u53EF\u8FDE\u63A5\u7684\u8BBE\u5907\uFF08daemon \u4EE3\u7406\u4E2D\u5FC3 server\uFF09\u3002owner-only",
|
|
@@ -24467,10 +24599,242 @@ var DEPLOY_FILE = import_node_path3.default.join(".clawd", "deploy.json");
|
|
|
24467
24599
|
var SCAN_FILE = import_node_path3.default.join(".clawd", "deploy-scan.json");
|
|
24468
24600
|
var z1 = DeployScanSchema.omit({ id: true, manifest: true }).extend({ releasedHead: DeployScanSchema.shape.head }).strict();
|
|
24469
24601
|
var z2 = external_exports.object({ version: external_exports.literal(2), scans: external_exports.array(DeployScanSchema), released: DeployReleasedSchema.optional() }).strict();
|
|
24602
|
+
var z3 = external_exports.object({ version: external_exports.literal(3), scans: external_exports.array(DeployScanSchema), releases: external_exports.array(DeployReleasedSchema) }).strict();
|
|
24470
24603
|
var PackageFindingSchema = EnvPackageSchema.omit({ localVersion: true, artifact: true, aptMissing: true, aptVersion: true }).extend({
|
|
24471
24604
|
artifact: external_exports.object({ url: external_exports.string().url(), bin: external_exports.string() }).strict().optional()
|
|
24472
24605
|
});
|
|
24473
24606
|
|
|
24607
|
+
// src/deploy/release-workflow.ts
|
|
24608
|
+
function renderDeployWorkflow(config2) {
|
|
24609
|
+
const identity = [
|
|
24610
|
+
" - name: Select pinned source identities",
|
|
24611
|
+
" env:",
|
|
24612
|
+
" RELEASE_JSON: ${{ inputs.release_json }}",
|
|
24613
|
+
" run: |",
|
|
24614
|
+
" node --input-type=module <<'NODE'",
|
|
24615
|
+
' import fs from "node:fs"',
|
|
24616
|
+
' const file = "candidate-release.json"',
|
|
24617
|
+
' const r = fs.existsSync(file) ? JSON.parse(fs.readFileSync(file, "utf8")) : process.env.RELEASE_JSON ? JSON.parse(process.env.RELEASE_JSON) : undefined',
|
|
24618
|
+
' 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")',
|
|
24619
|
+
' 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")',
|
|
24620
|
+
' fs.appendFileSync(process.env.GITHUB_ENV, "SOURCE_COMMIT=" + (r?.commit ?? process.env.GITHUB_SHA) + "\\nPIPELINE_COMMIT=" + (r?.pipelineCommit ?? process.env.CLAWOS_REF) + "\\n")',
|
|
24621
|
+
" NODE",
|
|
24622
|
+
""
|
|
24623
|
+
];
|
|
24624
|
+
const contract = [
|
|
24625
|
+
...identity,
|
|
24626
|
+
" - name: Checkout persona",
|
|
24627
|
+
" uses: actions/checkout@v4",
|
|
24628
|
+
" with:",
|
|
24629
|
+
" path: persona",
|
|
24630
|
+
" ref: ${{ env.SOURCE_COMMIT }}",
|
|
24631
|
+
" sparse-checkout: .clawd",
|
|
24632
|
+
"",
|
|
24633
|
+
" - name: Checkout pinned pipeline",
|
|
24634
|
+
" uses: actions/checkout@v4",
|
|
24635
|
+
" with:",
|
|
24636
|
+
" repository: ${{ env.CLAWOS_REPO }}",
|
|
24637
|
+
" ref: ${{ env.PIPELINE_COMMIT }}",
|
|
24638
|
+
" token: ${{ secrets.CLAWOS_READ_TOKEN }}",
|
|
24639
|
+
" path: clawos",
|
|
24640
|
+
" sparse-checkout: |",
|
|
24641
|
+
" cloud-host/pipeline",
|
|
24642
|
+
" cloud-host/k8s",
|
|
24643
|
+
"",
|
|
24644
|
+
" - name: \u8BFB\u90E8\u7F72\u6587\u4EF6",
|
|
24645
|
+
" id: plan",
|
|
24646
|
+
" run: |",
|
|
24647
|
+
" node clawos/cloud-host/pipeline/deploy-file.mjs \\",
|
|
24648
|
+
" --persona-dir persona \\",
|
|
24649
|
+
" --repo-name '${{ github.event.repository.name }}' \\",
|
|
24650
|
+
' --sha "$SOURCE_COMMIT" >> "$GITHUB_OUTPUT"',
|
|
24651
|
+
"",
|
|
24652
|
+
" - name: Bind pipeline source",
|
|
24653
|
+
' run: echo "PIPELINE_COMMIT=$(git -C clawos rev-parse HEAD)" >> "$GITHUB_ENV"',
|
|
24654
|
+
"",
|
|
24655
|
+
" - name: Select integration credentials",
|
|
24656
|
+
" if: inputs.environment != 'production'",
|
|
24657
|
+
" env:",
|
|
24658
|
+
" CLAWD_INT_GATEWAY_URL: ${{ vars.CLAWD_INT_GATEWAY_URL }}",
|
|
24659
|
+
" CLAWD_INT_GATEWAY_ADMIN_KEY: ${{ secrets.CLAWD_INT_GATEWAY_ADMIN_KEY }}",
|
|
24660
|
+
" CLAWD_INT_PERSONA_SECRETS_JSON: ${{ toJSON(secrets) }}",
|
|
24661
|
+
" CLAWD_ENV_NAMES: ${{ steps.plan.outputs.env_names }}",
|
|
24662
|
+
" run: node clawos/cloud-host/pipeline/persona-candidate.mjs env",
|
|
24663
|
+
"",
|
|
24664
|
+
" - name: Select production credentials",
|
|
24665
|
+
" if: inputs.environment == 'production'",
|
|
24666
|
+
" env:",
|
|
24667
|
+
" CLAWD_GATEWAY_URL: ${{ vars.CLAWD_GATEWAY_URL }}",
|
|
24668
|
+
" CLAWD_GATEWAY_ADMIN_KEY: ${{ secrets.CLAWD_GATEWAY_ADMIN_KEY }}",
|
|
24669
|
+
" CLAWD_SECRETS_JSON: ${{ toJSON(secrets) }}",
|
|
24670
|
+
" run: node clawos/cloud-host/pipeline/persona-candidate.mjs env",
|
|
24671
|
+
"",
|
|
24672
|
+
" - name: Check required credentials",
|
|
24673
|
+
" env:",
|
|
24674
|
+
" CLAWD_ENV_NAMES: ${{ steps.plan.outputs.env_names }}",
|
|
24675
|
+
" run: node clawos/cloud-host/pipeline/check-secrets.mjs",
|
|
24676
|
+
""
|
|
24677
|
+
];
|
|
24678
|
+
const download = (name) => [
|
|
24679
|
+
" - uses: actions/download-artifact@v4",
|
|
24680
|
+
" with:",
|
|
24681
|
+
` name: ${name}`,
|
|
24682
|
+
""
|
|
24683
|
+
];
|
|
24684
|
+
const upload = (name) => [
|
|
24685
|
+
" - uses: actions/upload-artifact@v4",
|
|
24686
|
+
...name.startsWith("persona-verified") ? [" if: inputs.environment != 'production'"] : [],
|
|
24687
|
+
" with:",
|
|
24688
|
+
` name: ${name}`,
|
|
24689
|
+
" path: candidate-release.json",
|
|
24690
|
+
" overwrite: true",
|
|
24691
|
+
""
|
|
24692
|
+
];
|
|
24693
|
+
const runtime = (script) => [
|
|
24694
|
+
` - name: ${script === "smoke" ? "Run real int smoke" : "Register the verified image"}`,
|
|
24695
|
+
" env:",
|
|
24696
|
+
" CLAWD_ENV_NAMES: ${{ steps.plan.outputs.env_names }}",
|
|
24697
|
+
" run: |",
|
|
24698
|
+
` IMAGE_REF=$(node clawos/cloud-host/pipeline/release.mjs validate --file candidate-release.json --component persona${script === "register" ? " --production" : ""})`,
|
|
24699
|
+
...script === "register" ? [" node clawos/cloud-host/pipeline/persona-candidate.mjs check-source"] : [],
|
|
24700
|
+
` node clawos/cloud-host/pipeline/${script}.mjs \\`,
|
|
24701
|
+
' --image "$IMAGE_REF" \\',
|
|
24702
|
+
" --persona-id '${{ steps.plan.outputs.persona_id }}' \\",
|
|
24703
|
+
" --model '${{ steps.plan.outputs.model }}' \\",
|
|
24704
|
+
" --effort '${{ steps.plan.outputs.effort }}' \\",
|
|
24705
|
+
" --size '${{ steps.plan.outputs.size }}' \\",
|
|
24706
|
+
" --task-concurrency '${{ steps.plan.outputs.task_concurrency }}' \\",
|
|
24707
|
+
" --engine '${{ steps.plan.outputs.engine }}' \\",
|
|
24708
|
+
" --connectors '${{ steps.plan.outputs.connectors }}' \\",
|
|
24709
|
+
" --run-number '${{ github.run_number }}'",
|
|
24710
|
+
""
|
|
24711
|
+
];
|
|
24712
|
+
const job = (name) => [
|
|
24713
|
+
` ${name}:`,
|
|
24714
|
+
` name: ${name}`,
|
|
24715
|
+
" runs-on: ubuntu-latest",
|
|
24716
|
+
" environment: ${{ inputs.environment || 'integration' }}",
|
|
24717
|
+
" timeout-minutes: 40"
|
|
24718
|
+
];
|
|
24719
|
+
return [
|
|
24720
|
+
"name: clawd deploy",
|
|
24721
|
+
"run-name: ${{ inputs.environment == 'production' && format('persona-production-{0}', inputs.promotion_id) || 'persona-integration' }}",
|
|
24722
|
+
"# \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",
|
|
24723
|
+
"on:",
|
|
24724
|
+
" push:",
|
|
24725
|
+
" branches: [integration]",
|
|
24726
|
+
" workflow_dispatch:",
|
|
24727
|
+
" inputs:",
|
|
24728
|
+
" environment:",
|
|
24729
|
+
" type: choice",
|
|
24730
|
+
" options: [integration, production]",
|
|
24731
|
+
" default: integration",
|
|
24732
|
+
" promotion_id:",
|
|
24733
|
+
" type: string",
|
|
24734
|
+
" required: false",
|
|
24735
|
+
" release_json:",
|
|
24736
|
+
" description: Verified Persona release JSON for production promotion",
|
|
24737
|
+
" type: string",
|
|
24738
|
+
" required: false",
|
|
24739
|
+
"",
|
|
24740
|
+
"concurrency:",
|
|
24741
|
+
" group: persona-cloud-${{ github.repository }}",
|
|
24742
|
+
" queue: max",
|
|
24743
|
+
" cancel-in-progress: false",
|
|
24744
|
+
"",
|
|
24745
|
+
"env:",
|
|
24746
|
+
` REGISTRY: ${config2.registry}`,
|
|
24747
|
+
` VPC_REGISTRY: ${config2.vpcRegistry}`,
|
|
24748
|
+
` ACR_NAMESPACE: ${config2.namespace}`,
|
|
24749
|
+
` CLAWOS_REPO: ${config2.repository}`,
|
|
24750
|
+
" CLAWOS_REF: ${{ vars.CLAWD_PIPELINE_REF || '" + config2.ref + "' }}",
|
|
24751
|
+
" DEPLOY_ENVIRONMENT: ${{ inputs.environment || 'integration' }}",
|
|
24752
|
+
"",
|
|
24753
|
+
"permissions:",
|
|
24754
|
+
" contents: read",
|
|
24755
|
+
"",
|
|
24756
|
+
"jobs:",
|
|
24757
|
+
...job("build"),
|
|
24758
|
+
" steps:",
|
|
24759
|
+
...contract,
|
|
24760
|
+
" - name: Dockerfile matches Persona directory",
|
|
24761
|
+
" if: inputs.environment != 'production'",
|
|
24762
|
+
" run: |",
|
|
24763
|
+
" test -f persona/Dockerfile",
|
|
24764
|
+
" grep -qF '/clawd/personas/${{ steps.plan.outputs.persona_id }}/' persona/Dockerfile",
|
|
24765
|
+
"",
|
|
24766
|
+
" - name: Install aliyun CLI",
|
|
24767
|
+
" if: inputs.environment != 'production'",
|
|
24768
|
+
" env:",
|
|
24769
|
+
" GH_TOKEN: ${{ github.token }}",
|
|
24770
|
+
" run: |",
|
|
24771
|
+
" TAGNAME=$(gh release view --repo aliyun/aliyun-cli --json tagName -q .tagName)",
|
|
24772
|
+
' VER=$(printf %s "$TAGNAME" | sed s/^v//)',
|
|
24773
|
+
' curl -fsSL -o /tmp/aliyun-cli.tgz "https://github.com/aliyun/aliyun-cli/releases/download/$TAGNAME/aliyun-cli-linux-$VER-amd64.tgz"',
|
|
24774
|
+
" sudo tar -xzf /tmp/aliyun-cli.tgz -C /usr/local/bin",
|
|
24775
|
+
"",
|
|
24776
|
+
" - name: Login to ACR",
|
|
24777
|
+
" if: inputs.environment != 'production'",
|
|
24778
|
+
" uses: aliyun/acr-login@v1",
|
|
24779
|
+
" with:",
|
|
24780
|
+
" login-server: ${{ env.REGISTRY }}",
|
|
24781
|
+
" username: ${{ secrets.ALI_DOCKER_USERNAME }}",
|
|
24782
|
+
" password: ${{ secrets.ALI_DOCKER_PASSWORD }}",
|
|
24783
|
+
"",
|
|
24784
|
+
" - name: Select candidate or promote without rebuilding",
|
|
24785
|
+
" env:",
|
|
24786
|
+
" ALIBABA_CLOUD_ACCESS_KEY_ID: ${{ secrets.ALI_ACS_ACCESS_KEY_ID }}",
|
|
24787
|
+
" ALIBABA_CLOUD_ACCESS_KEY_SECRET: ${{ secrets.ALI_ACS_ACCESS_KEY_SECRET }}",
|
|
24788
|
+
" RELEASE_JSON: ${{ inputs.release_json }}",
|
|
24789
|
+
" run: node clawos/cloud-host/pipeline/persona-candidate.mjs",
|
|
24790
|
+
"",
|
|
24791
|
+
...upload("persona-candidate"),
|
|
24792
|
+
...job("smoke"),
|
|
24793
|
+
" needs: build",
|
|
24794
|
+
" if: inputs.environment != 'production'",
|
|
24795
|
+
" steps:",
|
|
24796
|
+
...download("persona-candidate"),
|
|
24797
|
+
...contract,
|
|
24798
|
+
...runtime("smoke"),
|
|
24799
|
+
" - name: Attest successful int runtime smoke",
|
|
24800
|
+
' run: node clawos/cloud-host/pipeline/release.mjs attest --file candidate-release.json --endpoint "$CLAWD_GATEWAY_URL" --checks persona-smoke --out candidate-release.json',
|
|
24801
|
+
"",
|
|
24802
|
+
...upload("persona-smoked"),
|
|
24803
|
+
...job("deploy"),
|
|
24804
|
+
" needs: [build, smoke]",
|
|
24805
|
+
" if: always() && needs.build.result == 'success' && (needs.smoke.result == 'success' || needs.smoke.result == 'skipped')",
|
|
24806
|
+
" steps:",
|
|
24807
|
+
...download("${{ inputs.environment == 'production' && 'persona-candidate' || 'persona-smoked' }}"),
|
|
24808
|
+
...contract,
|
|
24809
|
+
...runtime("register"),
|
|
24810
|
+
...upload("persona-verified-${{ github.run_attempt }}")
|
|
24811
|
+
].join("\n");
|
|
24812
|
+
}
|
|
24813
|
+
|
|
24814
|
+
// src/deploy/templates.ts
|
|
24815
|
+
var import_node_crypto2 = require("crypto");
|
|
24816
|
+
|
|
24817
|
+
// src/deploy/default-base-release.json
|
|
24818
|
+
var default_base_release_default = {
|
|
24819
|
+
version: 1,
|
|
24820
|
+
environment: "integration",
|
|
24821
|
+
component: "base",
|
|
24822
|
+
image: "registry-vpc.cn-hangzhou.aliyuncs.com/ttc-prod/clawd-persona-base@sha256:9a0952c6bc94a6595374da7db125b5089b476d0bd88f280bd981757d9f572c22",
|
|
24823
|
+
commit: "8dfab2c57781e9f9600e3f99a79adcfbef455f2e",
|
|
24824
|
+
verification: {
|
|
24825
|
+
status: "passed",
|
|
24826
|
+
fingerprint: "d7b03abb9d2bf3a4d7f6f88ac43a2d33d6ec7a7c94ae816f7dae11d67d338194",
|
|
24827
|
+
checks: [
|
|
24828
|
+
"base-smoke",
|
|
24829
|
+
"codex-smoke",
|
|
24830
|
+
"pi-smoke",
|
|
24831
|
+
"workspace-persistence"
|
|
24832
|
+
],
|
|
24833
|
+
endpoint: "https://persona-int.clawos.chat",
|
|
24834
|
+
verifiedAt: "2026-10-08T09:34:53.131Z"
|
|
24835
|
+
}
|
|
24836
|
+
};
|
|
24837
|
+
|
|
24474
24838
|
// src/deploy/templates.ts
|
|
24475
24839
|
var CLAWOS_REPO = "ottin4ttc/clawos";
|
|
24476
24840
|
var CLAWOS_REF = "release";
|
|
@@ -24481,7 +24845,17 @@ var UNPUBLISH_WORKFLOW_PATH = `.github/workflows/${UNPUBLISH_WORKFLOW_FILE}`;
|
|
|
24481
24845
|
var ACR_REGISTRY = "registry.cn-hangzhou.aliyuncs.com";
|
|
24482
24846
|
var ACR_VPC_REGISTRY = "registry-vpc.cn-hangzhou.aliyuncs.com";
|
|
24483
24847
|
var ACR_NAMESPACE = "ttc-prod";
|
|
24484
|
-
var
|
|
24848
|
+
var acceptedBase = VerifiedBaseReleaseSchema.parse(default_base_release_default);
|
|
24849
|
+
var baseFingerprint = (0, import_node_crypto2.createHash)("sha256").update(JSON.stringify({
|
|
24850
|
+
component: acceptedBase.component,
|
|
24851
|
+
image: acceptedBase.image,
|
|
24852
|
+
commit: acceptedBase.commit,
|
|
24853
|
+
baseImage: null,
|
|
24854
|
+
pipelineCommit: null,
|
|
24855
|
+
repository: null
|
|
24856
|
+
})).digest("hex");
|
|
24857
|
+
if (baseFingerprint !== acceptedBase.verification.fingerprint) throw new Error("\u5E73\u53F0\u9ED8\u8BA4\u5E95\u5EA7\u4E0E\u5DF2\u9A8C\u6536\u5236\u54C1\u4E0D\u4E00\u81F4");
|
|
24858
|
+
var BASE_IMAGE = acceptedBase.image.replace(`${ACR_VPC_REGISTRY}/`, `${ACR_REGISTRY}/`);
|
|
24485
24859
|
var DOCKERIGNORE_TEMPLATE = [
|
|
24486
24860
|
"# \u7531 clawd \u751F\u6210\u3001\u7531 clawd \u7EF4\u62A4\uFF08\u540C Dockerfile\uFF09\u3002",
|
|
24487
24861
|
".git",
|
|
@@ -24520,170 +24894,8 @@ var CONTRACT_STEPS = [
|
|
|
24520
24894
|
"",
|
|
24521
24895
|
...PLAN_STEP
|
|
24522
24896
|
];
|
|
24523
|
-
var ACR_LOGIN_STEPS = [
|
|
24524
|
-
" - name: Login to ACR\uFF08\u89E3\u6790\u955C\u50CF digest \u8981 docker \u51ED\u636E\uFF09",
|
|
24525
|
-
" uses: aliyun/acr-login@v1",
|
|
24526
|
-
" with:",
|
|
24527
|
-
" login-server: ${{ env.REGISTRY }}",
|
|
24528
|
-
' username: "${{ secrets.ALI_DOCKER_USERNAME }}"',
|
|
24529
|
-
' password: "${{ secrets.ALI_DOCKER_PASSWORD }}"',
|
|
24530
|
-
""
|
|
24531
|
-
];
|
|
24532
|
-
var IMAGE_LATEST = '"$REGISTRY/$ACR_NAMESPACE/${{ steps.plan.outputs.persona_id }}:latest"';
|
|
24533
|
-
var RESOLVE_LINE = ` IMAGE_REF=$(node clawos/cloud-host/pipeline/acr.mjs resolve --image ${IMAGE_LATEST} --vpc-registry "$VPC_REGISTRY")`;
|
|
24534
24897
|
var CONCURRENCY_GROUP = " group: persona-cloud-${{ github.repository }}";
|
|
24535
|
-
var
|
|
24536
|
-
"name: clawd deploy",
|
|
24537
|
-
"",
|
|
24538
|
-
"# \u7531 clawd \u751F\u6210\u3001\u7531 clawd \u7EF4\u62A4\uFF1A\u6BCF\u6B21\u300C\u53D1\u5E03\u300D\u90FD\u4F1A\u7528\u5F53\u524D\u6A21\u677F\u91CD\u5199\u8FD9\u4EFD\u6587\u4EF6\u518D\u63D0\u4EA4\uFF0C\u624B\u6539\u4F1A\u88AB\u76D6\u6389\u3002",
|
|
24539
|
-
"# \u4E09\u6BB5\uFF1Abuild \u8BA9 ACR \u4ECE\u8FD9\u4E2A\u4ED3\u5E93\u6784 persona \u955C\u50CF\uFF08Dockerfile \u4E5F\u662F clawd \u5199\u7684\uFF09\u2192 smoke \u5728\u96C6\u7FA4\u4E0A\u771F\u8D77\u4E00\u6B21 \u2192 deploy \u5728 gateway \u767B\u8BB0\u6210\u6B63\u5F0F\u3002",
|
|
24540
|
-
"# \u955C\u50CF\u4E0D\u5728 runner \u4E0A\u6784\u3001\u4E5F\u4E0D\u4ECE runner \u63A8\uFF1AACR \u4E2A\u4EBA\u7248\u4ED3\u5E93 ttc-prod/<persona_id> \u6302\u7740\u8FD9\u4E2A GitHub \u4ED3\u5E93\u5F53\u4EE3\u7801\u6E90\uFF08\u9996\u6B21\u53D1\u5E03\u65F6\u81EA\u5EFA\uFF09\uFF0C",
|
|
24541
|
-
"# build \u6BB5\u53EA\u662F\u300C\u89E6\u53D1 \u2192 \u7B49\u5B83\u6784\u51FA\u672C\u6B21 commit\u300D\uFF1Bsmoke / deploy \u5404\u81EA\u628A :latest \u89E3\u6790\u6210 digest \u518D\u7528\u3002\u6D41\u6C34\u7EBF\u811A\u672C\u5728 ottin4ttc/clawos \u4ED3\u5E93\u91CC\u3002",
|
|
24542
|
-
"#",
|
|
24543
|
-
"# \u8981\u7684\u7EC4\u7EC7\u7EA7 Secrets\uFF1AALI_ACS_ACCESS_KEY_ID / ALI_ACS_ACCESS_KEY_SECRET\uFF08ACR OpenAPI\uFF1A\u5EFA\u4ED3\u5E93 / \u89E6\u53D1 / \u67E5\u6784\u5EFA\u8BB0\u5F55\uFF09\u3001",
|
|
24544
|
-
"# ALI_DOCKER_USERNAME / ALI_DOCKER_PASSWORD\uFF08\u89E3\u6790\u955C\u50CF digest\uFF09\u3001CLAWOS_READ_TOKEN\uFF08\u8BFB clawos \u4ED3\u5E93\uFF09\u3001CLAWD_GATEWAY_ADMIN_KEY\uFF1B",
|
|
24545
|
-
"# \u7EC4\u7EC7\u7EA7 Variable\uFF1ACLAWD_GATEWAY_URL\u3002",
|
|
24546
|
-
"# \u4ED3\u5E93\u7EA7\u540C\u540D\u914D\u7F6E\u4F1A\u76D6\u8FC7\u7EC4\u7EC7\u7EA7\u2014\u2014\u67D0\u4E2A persona \u8981\u6307\u5230\u53E6\u4E00\u53F0 gateway\uFF0C\u5728\u81EA\u5DF1\u4ED3\u5E93\u91CC\u914D\u5373\u53EF\u3002",
|
|
24547
|
-
"",
|
|
24548
|
-
"on:",
|
|
24549
|
-
" push:",
|
|
24550
|
-
" branches: [main]",
|
|
24551
|
-
" workflow_dispatch:",
|
|
24552
|
-
"",
|
|
24553
|
-
"concurrency:",
|
|
24554
|
-
" # \u540C\u4E00\u4E2A\u4ED3\u5E93\u7684\u53D1\u5E03\u6392\u961F\u8DD1\uFF0C\u4E0D\u53D6\u6D88\uFF1A\u4E0A\u4E00\u6B21\u53EF\u80FD\u5DF2\u7ECF\u5728\u767B\u8BB0\u6B63\u5F0F\u4E86",
|
|
24555
|
-
CONCURRENCY_GROUP,
|
|
24556
|
-
"",
|
|
24557
|
-
"env:",
|
|
24558
|
-
` REGISTRY: ${ACR_REGISTRY}`,
|
|
24559
|
-
` VPC_REGISTRY: ${ACR_VPC_REGISTRY}`,
|
|
24560
|
-
` ACR_NAMESPACE: ${ACR_NAMESPACE}`,
|
|
24561
|
-
` CLAWOS_REPO: ${CLAWOS_REPO}`,
|
|
24562
|
-
` CLAWOS_REF: ${CLAWOS_REF}`,
|
|
24563
|
-
"",
|
|
24564
|
-
"permissions:",
|
|
24565
|
-
" contents: read",
|
|
24566
|
-
"",
|
|
24567
|
-
"jobs:",
|
|
24568
|
-
" build:",
|
|
24569
|
-
// jobs API 只返 name 不返 key,故 name 必须用段 key。
|
|
24570
|
-
" name: build",
|
|
24571
|
-
" runs-on: ubuntu-latest",
|
|
24572
|
-
// ACR 账号内串行构建,需给其他镜像排队留时间。
|
|
24573
|
-
" timeout-minutes: 40",
|
|
24574
|
-
" steps:",
|
|
24575
|
-
...CONTRACT_STEPS,
|
|
24576
|
-
" - name: \u51ED\u636E\u9F50\u4E0D\u9F50\uFF08\u7F3A\u54EA\u51E0\u4E2A\u540D\u5B57\u4E00\u6B21\u5217\u5168\uFF09",
|
|
24577
|
-
" env:",
|
|
24578
|
-
" CLAWD_SECRETS_JSON: ${{ toJSON(secrets) }}",
|
|
24579
|
-
" CLAWD_ENV_NAMES: ${{ steps.plan.outputs.env_names }}",
|
|
24580
|
-
" run: node clawos/cloud-host/pipeline/check-secrets.mjs",
|
|
24581
|
-
"",
|
|
24582
|
-
" - name: Dockerfile \u5728\u3001\u4E14\u62F7\u5230\u7684\u662F\u8FD9\u4E2A persona \u7684\u76EE\u5F55",
|
|
24583
|
-
" # Dockerfile \u7531 clawd \u53D1\u5E03\u65F6\u5199\uFF08\u540C\u8FD9\u4EFD workflow\uFF09\uFF0CACR \u6309\u5B83\u6784\u3002\u76EE\u5F55\u540D\u90A3\u4E00\u6BB5\u8981\u4E0E deploy-file \u7B97\u51FA\u7684 persona_id \u4E00\u81F4\uFF1A",
|
|
24584
|
-
" # \u4E24\u8FB9\u5404\u6709\u4E00\u4EFD\u540C\u6837\u7684\u540D\u5B57\u6E05\u6D17\uFF0C\u8FD9\u91CC\u662F\u5B83\u4EEC\u552F\u4E00\u7684\u4EA4\u6C47\u70B9\u3002",
|
|
24585
|
-
" run: |",
|
|
24586
|
-
" test -f persona/Dockerfile \\",
|
|
24587
|
-
' || { echo "\u2717 \u4ED3\u5E93\u91CC\u6CA1\u6709 Dockerfile\uFF1A\u8FD9\u6B21\u63A8\u9001\u4E0D\u662F clawd \u53D1\u5E03\u7684\uFF08\u6216 clawd \u592A\u65E7\uFF09\uFF1B\u56DE clawd \u7684\u4E0A\u4E91\u9875\u9762\u91CD\u65B0\u53D1\u5E03" >&2; exit 1; }',
|
|
24588
|
-
" grep -qF '/clawd/personas/${{ steps.plan.outputs.persona_id }}/' persona/Dockerfile \\",
|
|
24589
|
-
' || { echo "\u2717 Dockerfile \u62F7\u5230\u7684\u76EE\u5F55\u4E0D\u662F /clawd/personas/${{ steps.plan.outputs.persona_id }}/" >&2; exit 1; }',
|
|
24590
|
-
"",
|
|
24591
|
-
" - name: \u88C5 aliyun CLI\uFF08ACR OpenAPI\uFF1A\u5EFA\u4ED3\u5E93 / \u89E6\u53D1 / \u67E5\u6784\u5EFA\u8BB0\u5F55\uFF09",
|
|
24592
|
-
" env:",
|
|
24593
|
-
" GH_TOKEN: ${{ github.token }}",
|
|
24594
|
-
" run: |",
|
|
24595
|
-
" TAGNAME=$(gh release view --repo aliyun/aliyun-cli --json tagName -q .tagName)",
|
|
24596
|
-
// 不用 ${TAGNAME#v} 这种带花括号的展开:这份模板里 `${` 只许出现在 GitHub 表达式里(spec 守着)
|
|
24597
|
-
' VER=$(printf %s "$TAGNAME" | sed s/^v//)',
|
|
24598
|
-
' curl -fsSL -o /tmp/aliyun-cli.tgz "https://github.com/aliyun/aliyun-cli/releases/download/$TAGNAME/aliyun-cli-linux-$VER-amd64.tgz"',
|
|
24599
|
-
" sudo tar -xzf /tmp/aliyun-cli.tgz -C /usr/local/bin",
|
|
24600
|
-
" aliyun version",
|
|
24601
|
-
"",
|
|
24602
|
-
" - name: \u8BA9 ACR \u4ECE\u672C\u4ED3\u5E93\u6784\uFF08\u9996\u6B21\u53D1\u5E03\u5148\u5EFA ACR \u4ED3\u5E93\u4E0E\u89C4\u5219\uFF1B\u7B49\u5B83\u6784\u51FA\u672C\u6B21 commit\uFF09",
|
|
24603
|
-
" # ACR \u6784\u7684\u662F main \u5F53\u524D\u7684 tip\u3001\u4E0D\u662F github.sha\uFF1Atip \u5DF2\u7ECF\u4E0D\u662F\u672C\u6B21 commit \u65F6\u76F4\u63A5\u7EA2\uFF0C\u8BA9\u66F4\u65B0\u7684\u90A3\u6B21 run \u53BB\u6784\u3001\u53BB\u767B\u8BB0\u3002",
|
|
24604
|
-
" # \u81EA\u52A8\u6784\u5EFA\u5173\u7740\uFF1A\u53EA\u6709\u8FD9\u91CC\u89E6\u53D1\u3001webhook \u4E0D\u6784\uFF0C\u300C\u6784 \u2192 \u5192\u70DF \u2192 \u767B\u8BB0\u300D\u624D\u662F\u4E00\u6761\u6709\u5E8F\u7684\u94FE\u3002",
|
|
24605
|
-
" # \u6784\u51FA\u7684\u662F\u54EA\u4E2A commit \u7531 acr.mjs wait \u6309\u6784\u5EFA\u8BB0\u5F55 + \u65E5\u5FD7\u91CC\u7684 commit \u6838\uFF0C\u4E0D\u770B\u955C\u50CF\u7684\u65F6\u95F4\uFF08\u7F13\u5B58\u547D\u4E2D\u65F6\u90A3\u662F\u8001\u7684\uFF09\u3002",
|
|
24606
|
-
" env:",
|
|
24607
|
-
" ALIBABA_CLOUD_ACCESS_KEY_ID: ${{ secrets.ALI_ACS_ACCESS_KEY_ID }}",
|
|
24608
|
-
" ALIBABA_CLOUD_ACCESS_KEY_SECRET: ${{ secrets.ALI_ACS_ACCESS_KEY_SECRET }}",
|
|
24609
|
-
" run: |",
|
|
24610
|
-
// pipefail 让 ls-remote 失败正确传播,避免被 cut 的成功状态掩盖。
|
|
24611
|
-
" set -eo pipefail",
|
|
24612
|
-
' REPO="$ACR_NAMESPACE/${{ steps.plan.outputs.persona_id }}"',
|
|
24613
|
-
' node clawos/cloud-host/pipeline/acr.mjs ensure-repo --repo "$REPO" \\',
|
|
24614
|
-
" --source '${{ github.repository }}' --location / --dockerfile Dockerfile --branch main --tag latest \\",
|
|
24615
|
-
" --summary 'clawd persona ${{ github.event.repository.name }}'",
|
|
24616
|
-
" TIP=$(git -C persona ls-remote origin refs/heads/main | cut -f1)",
|
|
24617
|
-
` [ "$TIP" = '\${{ github.sha }}' ] \\`,
|
|
24618
|
-
' || { echo "\u2717 main \u5DF2\u7ECF\u63A8\u8FDB\u5230 $TIP\uFF0C\u672C\u6B21 ${{ github.sha }} \u4E0D\u518D\u6784\uFF1B\u7B49\u65B0\u7684\u90A3\u6B21 run" >&2; exit 1; }',
|
|
24619
|
-
' node clawos/cloud-host/pipeline/acr.mjs trigger --repo "$REPO" --tag latest',
|
|
24620
|
-
` node clawos/cloud-host/pipeline/acr.mjs wait --repo "$REPO" --tag latest --commit '\${{ github.sha }}' --timeout-sec 1800`,
|
|
24621
|
-
"",
|
|
24622
|
-
...ACR_LOGIN_STEPS,
|
|
24623
|
-
" - name: \u955C\u50CF = \u672C\u6B21 commit \u6784\u51FA\u7684\u90A3\u4EFD\uFF08digest\uFF1B\u53EA\u6253\u65E5\u5FD7\uFF0Csmoke / deploy \u5404\u81EA\u518D\u89E3\u6790\u4E00\u6B21\uFF09",
|
|
24624
|
-
` run: node clawos/cloud-host/pipeline/acr.mjs resolve --image ${IMAGE_LATEST} --vpc-registry "$VPC_REGISTRY"`,
|
|
24625
|
-
"",
|
|
24626
|
-
" smoke:",
|
|
24627
|
-
" name: smoke",
|
|
24628
|
-
" needs: build",
|
|
24629
|
-
" runs-on: ubuntu-latest",
|
|
24630
|
-
" timeout-minutes: 20",
|
|
24631
|
-
" steps:",
|
|
24632
|
-
...CONTRACT_STEPS,
|
|
24633
|
-
...ACR_LOGIN_STEPS,
|
|
24634
|
-
" - name: \u4E34\u65F6\u767B\u8BB0 \u2192 \u8D77\u4E00\u6B21 Pod \u2192 \u64A4\u9500",
|
|
24635
|
-
" # \u767B\u8BB0\u6B63\u5F0F\u53EA\u662F\u5F80 gateway \u5199\u4E00\u884C\uFF0Cgateway \u4E0D\u78B0\u955C\u50CF\uFF1B\u96C6\u7FA4\u62C9\u955C\u50CF\u53D1\u751F\u5728\u7B2C\u4E00\u4E2A\u4EFB\u52A1\u5230\u6765\u65F6\u3002",
|
|
24636
|
-
" # \u6CA1\u6709\u8FD9\u4E00\u6B65\uFF0C\u6D41\u6C34\u7EBF\u7EFF\u4E86\u53EA\u4EE3\u8868\u300C\u767B\u8BB0\u4E86\u300D\u3002\u955C\u50CF\u7528 digest\uFF08\u96C6\u7FA4 Job \u662F IfNotPresent\uFF0C\u79FB\u52A8 tag \u4F1A\u4E00\u76F4\u8DD1\u65E7\u7684\uFF09\u3002",
|
|
24637
|
-
// smoke 与正式发布用同份模型/档位/连接器;deploy-file.mjs 拒绝单引号/换行等危险值,方可单引号拼参。
|
|
24638
|
-
" env:",
|
|
24639
|
-
" CLAWD_GATEWAY_URL: ${{ vars.CLAWD_GATEWAY_URL }}",
|
|
24640
|
-
" CLAWD_GATEWAY_ADMIN_KEY: ${{ secrets.CLAWD_GATEWAY_ADMIN_KEY }}",
|
|
24641
|
-
" CLAWD_SECRETS_JSON: ${{ toJSON(secrets) }}",
|
|
24642
|
-
" CLAWD_ENV_NAMES: ${{ steps.plan.outputs.env_names }}",
|
|
24643
|
-
" run: |",
|
|
24644
|
-
" set -e",
|
|
24645
|
-
RESOLVE_LINE,
|
|
24646
|
-
" node clawos/cloud-host/pipeline/smoke.mjs \\",
|
|
24647
|
-
' --image "$IMAGE_REF" \\',
|
|
24648
|
-
" --persona-id '${{ steps.plan.outputs.persona_id }}' \\",
|
|
24649
|
-
" --model '${{ steps.plan.outputs.model }}' \\",
|
|
24650
|
-
" --effort '${{ steps.plan.outputs.effort }}' \\",
|
|
24651
|
-
" --size '${{ steps.plan.outputs.size }}' \\",
|
|
24652
|
-
" --task-concurrency '${{ steps.plan.outputs.task_concurrency }}' \\",
|
|
24653
|
-
" --engine '${{ steps.plan.outputs.engine }}' \\",
|
|
24654
|
-
" --connectors '${{ steps.plan.outputs.connectors }}' \\",
|
|
24655
|
-
" --run-number '${{ github.run_number }}'",
|
|
24656
|
-
"",
|
|
24657
|
-
" deploy:",
|
|
24658
|
-
" name: deploy",
|
|
24659
|
-
" needs: [build, smoke]",
|
|
24660
|
-
" runs-on: ubuntu-latest",
|
|
24661
|
-
" # \u4ED3\u5E93\u914D\u4E86 production \u73AF\u5883\u7684\u300C\u987B\u5BA1\u6838\u4EBA\u6279\u51C6\u300D\uFF0Cjob \u5C31\u505C\u5728\u8FD9\u91CC\u7B49\u4EBA\u70B9\uFF1B\u6CA1\u914D\u5C31\u76F4\u63A5\u8FC7\u3002",
|
|
24662
|
-
" environment: production",
|
|
24663
|
-
" steps:",
|
|
24664
|
-
...CONTRACT_STEPS,
|
|
24665
|
-
...ACR_LOGIN_STEPS,
|
|
24666
|
-
" - name: \u767B\u8BB0\u6B63\u5F0F",
|
|
24667
|
-
" env:",
|
|
24668
|
-
" CLAWD_GATEWAY_URL: ${{ vars.CLAWD_GATEWAY_URL }}",
|
|
24669
|
-
" CLAWD_GATEWAY_ADMIN_KEY: ${{ secrets.CLAWD_GATEWAY_ADMIN_KEY }}",
|
|
24670
|
-
" CLAWD_SECRETS_JSON: ${{ toJSON(secrets) }}",
|
|
24671
|
-
" CLAWD_ENV_NAMES: ${{ steps.plan.outputs.env_names }}",
|
|
24672
|
-
" run: |",
|
|
24673
|
-
" set -e",
|
|
24674
|
-
RESOLVE_LINE,
|
|
24675
|
-
" node clawos/cloud-host/pipeline/register.mjs \\",
|
|
24676
|
-
' --image "$IMAGE_REF" \\',
|
|
24677
|
-
" --persona-id '${{ steps.plan.outputs.persona_id }}' \\",
|
|
24678
|
-
" --model '${{ steps.plan.outputs.model }}' \\",
|
|
24679
|
-
" --effort '${{ steps.plan.outputs.effort }}' \\",
|
|
24680
|
-
" --size '${{ steps.plan.outputs.size }}' \\",
|
|
24681
|
-
" --task-concurrency '${{ steps.plan.outputs.task_concurrency }}' \\",
|
|
24682
|
-
" --engine '${{ steps.plan.outputs.engine }}' \\",
|
|
24683
|
-
" --connectors '${{ steps.plan.outputs.connectors }}'",
|
|
24684
|
-
""
|
|
24685
|
-
];
|
|
24686
|
-
var WORKFLOW_TEMPLATE = L.join("\n");
|
|
24898
|
+
var WORKFLOW_TEMPLATE = renderDeployWorkflow({ registry: ACR_REGISTRY, vpcRegistry: ACR_VPC_REGISTRY, namespace: ACR_NAMESPACE, repository: CLAWOS_REPO, ref: CLAWOS_REF });
|
|
24687
24899
|
var U = [
|
|
24688
24900
|
"name: clawd unpublish",
|
|
24689
24901
|
"",
|
|
@@ -24695,10 +24907,17 @@ var U = [
|
|
|
24695
24907
|
"",
|
|
24696
24908
|
"on:",
|
|
24697
24909
|
" workflow_dispatch:",
|
|
24910
|
+
" inputs:",
|
|
24911
|
+
" environment:",
|
|
24912
|
+
" type: choice",
|
|
24913
|
+
" options: [integration, production]",
|
|
24914
|
+
" default: production",
|
|
24698
24915
|
"",
|
|
24699
24916
|
"concurrency:",
|
|
24700
|
-
" # \u4E0E\u53D1\u5E03\u540C\u4E00\u7EC4\
|
|
24917
|
+
" # \u4E0E\u53D1\u5E03\u540C\u4E00\u7EC4\u4E32\u884C\u7B49\u5F85\uFF0C\u65B0\u7684\u4EFB\u52A1\u4E0D\u4F1A\u66FF\u6362\u7B49\u5F85\u4E2D\u7684\u4EFB\u52A1",
|
|
24701
24918
|
CONCURRENCY_GROUP,
|
|
24919
|
+
" queue: max",
|
|
24920
|
+
" cancel-in-progress: false",
|
|
24702
24921
|
"",
|
|
24703
24922
|
"env:",
|
|
24704
24923
|
` CLAWOS_REPO: ${CLAWOS_REPO}`,
|
|
@@ -24711,14 +24930,23 @@ var U = [
|
|
|
24711
24930
|
" unpublish:",
|
|
24712
24931
|
" name: unpublish",
|
|
24713
24932
|
" runs-on: ubuntu-latest",
|
|
24933
|
+
" environment: ${{ inputs.environment || 'integration' }}",
|
|
24714
24934
|
" timeout-minutes: 10",
|
|
24715
24935
|
" steps:",
|
|
24716
24936
|
...CONTRACT_STEPS,
|
|
24717
|
-
" - name: \u64A4\u767B\u8BB0",
|
|
24937
|
+
" - name: \u64A4 production \u767B\u8BB0",
|
|
24938
|
+
" if: inputs.environment == 'production'",
|
|
24718
24939
|
" env:",
|
|
24719
24940
|
" CLAWD_GATEWAY_URL: ${{ vars.CLAWD_GATEWAY_URL }}",
|
|
24720
24941
|
" CLAWD_GATEWAY_ADMIN_KEY: ${{ secrets.CLAWD_GATEWAY_ADMIN_KEY }}",
|
|
24721
24942
|
" run: node clawos/cloud-host/pipeline/unregister.mjs --persona-id '${{ steps.plan.outputs.persona_id }}'",
|
|
24943
|
+
" - name: \u64A4 int \u767B\u8BB0",
|
|
24944
|
+
" if: inputs.environment != 'production'",
|
|
24945
|
+
" env:",
|
|
24946
|
+
" CLAWD_GATEWAY_URL: ${{ vars.CLAWD_INT_GATEWAY_URL }}",
|
|
24947
|
+
" CLAWD_GATEWAY_ADMIN_KEY: ${{ secrets.CLAWD_INT_GATEWAY_ADMIN_KEY }}",
|
|
24948
|
+
" run: node clawos/cloud-host/pipeline/unregister.mjs --persona-id '${{ steps.plan.outputs.persona_id }}'",
|
|
24949
|
+
"",
|
|
24722
24950
|
""
|
|
24723
24951
|
];
|
|
24724
24952
|
var UNPUBLISH_WORKFLOW_TEMPLATE = U.join("\n");
|