arcrun 1.1.0 → 1.3.0
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/commands/config.d.ts +4 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +39 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/init.d.ts +5 -2
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +147 -19
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/install-harness.d.ts +2 -0
- package/dist/commands/install-harness.d.ts.map +1 -0
- package/dist/commands/install-harness.js +122 -0
- package/dist/commands/install-harness.js.map +1 -0
- package/dist/commands/mcp-setup.d.ts +12 -0
- package/dist/commands/mcp-setup.d.ts.map +1 -0
- package/dist/commands/mcp-setup.js +42 -0
- package/dist/commands/mcp-setup.js.map +1 -0
- package/dist/commands/push.d.ts.map +1 -1
- package/dist/commands/push.js +13 -0
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/recipe.d.ts.map +1 -1
- package/dist/commands/recipe.js +63 -1
- package/dist/commands/recipe.js.map +1 -1
- package/dist/commands/update.d.ts +13 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +89 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/validate.js +2 -2
- package/dist/commands/validate.js.map +1 -1
- package/dist/index.js +43 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/api-recipe-seeds.d.ts +32 -0
- package/dist/lib/api-recipe-seeds.d.ts.map +1 -0
- package/dist/lib/api-recipe-seeds.js +108 -0
- package/dist/lib/api-recipe-seeds.js.map +1 -0
- package/dist/lib/cf-api.d.ts +22 -0
- package/dist/lib/cf-api.d.ts.map +1 -1
- package/dist/lib/cf-api.js +58 -0
- package/dist/lib/cf-api.js.map +1 -1
- package/dist/lib/config.d.ts +34 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +123 -8
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/deploy.d.ts +56 -0
- package/dist/lib/deploy.d.ts.map +1 -0
- package/dist/lib/deploy.js +239 -0
- package/dist/lib/deploy.js.map +1 -0
- package/dist/lib/exposure-warning.d.ts +25 -0
- package/dist/lib/exposure-warning.d.ts.map +1 -0
- package/dist/lib/exposure-warning.js +92 -0
- package/dist/lib/exposure-warning.js.map +1 -0
- package/dist/lib/yaml-parser.d.ts.map +1 -1
- package/dist/lib/yaml-parser.js +7 -1
- package/dist/lib/yaml-parser.js.map +1 -1
- package/harness/CLAUDE.block.md +15 -0
- package/harness/commands/arcrun.md +29 -0
- package/harness/hooks/arcrun-guard.sh +54 -0
- package/harness/settings.fragment.json +16 -0
- package/harness/skills/arcrun-mindset/SKILL.md +78 -0
- package/package.json +5 -4
package/dist/lib/cf-api.js
CHANGED
|
@@ -60,6 +60,64 @@ export class CfKvClient {
|
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Cloudflare Account-level API wrapper(self-hosted installer 用)。
|
|
65
|
+
*
|
|
66
|
+
* 負責 acr init --self-hosted 的資源建立:驗 token、建/列 KV namespace、查 workers.dev subdomain。
|
|
67
|
+
* (不建 R2:R2 是 dead storage 且綁卡違背開源免費;見 init.ts step 2 + registry-canon Phase 1.5。)
|
|
68
|
+
* 與 CfKvClient(綁單一 namespace 的 KV 操作)職責不同——這個是帳號層級的資源管理。
|
|
69
|
+
* 對應 SDD:.agents/specs/arcrun/sdk-and-website/self-hosted-init.md §3 step 1-2
|
|
70
|
+
*/
|
|
71
|
+
export class CfAccountClient {
|
|
72
|
+
accountBase;
|
|
73
|
+
headers;
|
|
74
|
+
constructor(accountId, apiToken) {
|
|
75
|
+
this.accountBase = `${CF_API_BASE}/accounts/${accountId}`;
|
|
76
|
+
this.headers = {
|
|
77
|
+
'Authorization': `Bearer ${apiToken}`,
|
|
78
|
+
'Content-Type': 'application/json',
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
async cf(path, init) {
|
|
82
|
+
const res = await fetch(`${this.accountBase}${path}`, {
|
|
83
|
+
...init,
|
|
84
|
+
headers: { ...this.headers, ...(init?.headers ?? {}) },
|
|
85
|
+
});
|
|
86
|
+
const data = await res.json().catch(() => null);
|
|
87
|
+
if (!res.ok || !data?.success) {
|
|
88
|
+
const msg = data?.errors?.map(e => e.message).join('; ') ?? `HTTP ${res.status}`;
|
|
89
|
+
throw new Error(`CF API ${path} 失敗:${msg}`);
|
|
90
|
+
}
|
|
91
|
+
return data.result;
|
|
92
|
+
}
|
|
93
|
+
/** 驗證 token 能存取此 account(權限不足會在後續建立操作報錯,這裡先確認 account 可達)。*/
|
|
94
|
+
async verifyAccess() {
|
|
95
|
+
// GET /accounts/{id} 能通 = token 有此 account 的基本讀權限
|
|
96
|
+
await this.cf('');
|
|
97
|
+
}
|
|
98
|
+
/** 列出現有 KV namespace(冪等用:已存在就重用,不重建)。回傳 title → id 對照。*/
|
|
99
|
+
async listKvNamespaces() {
|
|
100
|
+
const result = await this.cf('/storage/kv/namespaces?per_page=100');
|
|
101
|
+
const map = new Map();
|
|
102
|
+
for (const ns of result)
|
|
103
|
+
map.set(ns.title, ns.id);
|
|
104
|
+
return map;
|
|
105
|
+
}
|
|
106
|
+
/** 建立 KV namespace(若同名已存在則回傳既有 id,冪等)。*/
|
|
107
|
+
async ensureKvNamespace(title, existing) {
|
|
108
|
+
const known = existing ?? (await this.listKvNamespaces());
|
|
109
|
+
const found = known.get(title);
|
|
110
|
+
if (found)
|
|
111
|
+
return found;
|
|
112
|
+
const result = await this.cf('/storage/kv/namespaces', { method: 'POST', body: JSON.stringify({ title }) });
|
|
113
|
+
return result.id;
|
|
114
|
+
}
|
|
115
|
+
/** 查 workers.dev subdomain(cypher-executor WORKER_SUBDOMAIN 用,組對內 component URL)。*/
|
|
116
|
+
async getWorkersSubdomain() {
|
|
117
|
+
const result = await this.cf('/workers/subdomain');
|
|
118
|
+
return result.subdomain;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
63
121
|
/** AES-GCM 加密 credential(與 cypher-executor credential-injector 解密邏輯對應)*/
|
|
64
122
|
export async function encryptCredential(value, encryptionKey) {
|
|
65
123
|
if (!encryptionKey || encryptionKey.length < 64) {
|
package/dist/lib/cf-api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cf-api.js","sourceRoot":"","sources":["../../src/lib/cf-api.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cf-api.js","sourceRoot":"","sources":["../../src/lib/cf-api.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -8,11 +8,44 @@ export interface ArcrunConfig {
|
|
|
8
8
|
cypher_executor_url?: string;
|
|
9
9
|
credentials_kv_namespace_id?: string;
|
|
10
10
|
webhooks_kv_namespace_id?: string;
|
|
11
|
-
|
|
11
|
+
mcp_url?: string;
|
|
12
12
|
multi_tenant?: boolean;
|
|
13
|
+
exposure_consented?: Record<string, {
|
|
14
|
+
confirmed_at: string;
|
|
15
|
+
suppress_future?: boolean;
|
|
16
|
+
}>;
|
|
13
17
|
}
|
|
18
|
+
/** 專案層設定檔名(就近往上找)。含憑證 → 必須 gitignore(見 createCredentialsYamlIfMissing)。*/
|
|
19
|
+
export declare const PROJECT_CONFIG_NAME = ".arcrun.yaml";
|
|
20
|
+
/** 設定來源層級(acr config --where 用,讓使用者知道每個值來自哪一層,避免用錯帳號)。*/
|
|
21
|
+
export type ConfigSource = 'env' | 'project' | 'global' | 'default';
|
|
22
|
+
/**
|
|
23
|
+
* 平台預設 MCP URL(mcp_url 未設時的 fallback,SaaS 用戶用)。
|
|
24
|
+
* MCP 搬進 arcrun 主庫後改用 arcrun.dev zone(mcp/wrangler.toml route = mcp.arcrun.dev)。
|
|
25
|
+
*/
|
|
26
|
+
export declare const DEFAULT_MCP_URL = "https://mcp.arcrun.dev";
|
|
14
27
|
export declare function configExists(): boolean;
|
|
28
|
+
/** 從 startDir 就近往上逐層找專案層 .arcrun.yaml,回傳第一個命中的路徑(停在檔案系統根)。*/
|
|
29
|
+
export declare function findProjectConfig(startDir?: string): string | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* 三層分層解析:全域 → 疊專案層 → 疊 env(欄位級 merge,高層只覆蓋它提供的欄位)。
|
|
32
|
+
* 任一層都沒有 mode 時 fallback 'local',讓 validate --offline 等在無設定下可運作。
|
|
33
|
+
*/
|
|
15
34
|
export declare function loadConfig(): ArcrunConfig;
|
|
35
|
+
/** 解析每個關鍵欄位的最終值與來源層(acr config --where 用)。*/
|
|
36
|
+
export declare function resolveConfigSources(): Array<{
|
|
37
|
+
field: keyof ArcrunConfig;
|
|
38
|
+
value: string;
|
|
39
|
+
source: ConfigSource;
|
|
40
|
+
}>;
|
|
41
|
+
/** 回傳本次解析實際採用的專案層設定檔路徑(無則 undefined)。acr config --where 顯示用。*/
|
|
42
|
+
export declare function activeProjectConfigPath(): string | undefined;
|
|
16
43
|
export declare function saveConfig(config: ArcrunConfig): void;
|
|
17
44
|
export declare function getCypherExecutorUrl(config: ArcrunConfig): string;
|
|
45
|
+
/**
|
|
46
|
+
* 取得 MCP server URL(薄殼原則:與 cypher_url 同一份 config 解析)。
|
|
47
|
+
* config 有 mcp_url(env/專案/全域 任一層)→ 用它;否則 fallback 平台預設。
|
|
48
|
+
* acr mcp-setup 用此決定要寫進專案 .mcp.json 的 URL → 切資料夾自動切 MCP。
|
|
49
|
+
*/
|
|
50
|
+
export declare function getMcpUrl(config: ArcrunConfig): string;
|
|
18
51
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/lib/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,aAAa,CAAC;IAE3C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAOlC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;IAIvB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAC1F;AAKD,0EAA0E;AAC1E,eAAO,MAAM,mBAAmB,iBAAiB,CAAC;AAElD,yDAAyD;AACzD,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAapE;;;GAGG;AACH,eAAO,MAAM,eAAe,2BAA2B,CAAC;AAExD,wBAAgB,YAAY,IAAI,OAAO,CAEtC;AAED,6DAA6D;AAC7D,wBAAgB,iBAAiB,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,GAAG,SAAS,CAatF;AA4BD;;;GAGG;AACH,wBAAgB,UAAU,IAAI,YAAY,CAQzC;AAED,6CAA6C;AAC7C,wBAAgB,oBAAoB,IAAI,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,YAAY,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,YAAY,CAAA;CAAE,CAAC,CAoBhH;AAED,+DAA+D;AAC/D,wBAAgB,uBAAuB,IAAI,MAAM,GAAG,SAAS,CAE5D;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAGrD;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAKjE;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAEtD"}
|
package/dist/lib/config.js
CHANGED
|
@@ -1,22 +1,129 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CLI
|
|
2
|
+
* CLI 設定檔管理 — 三層分層解析(SDD: sdk-and-website/config-layering.md)
|
|
3
|
+
* 優先序:env 變數 > 專案層 .arcrun.yaml(就近往上找)> 全域 ~/.arcrun/config.yaml
|
|
4
|
+
* 解壓測 #7(AI/CI 非互動)+ #8(接案多帳號),仿 git config / Claude Code MCP 模式。
|
|
3
5
|
*/
|
|
4
6
|
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
5
7
|
import { homedir } from 'node:os';
|
|
6
|
-
import { join } from 'node:path';
|
|
8
|
+
import { join, dirname, parse as parsePath } from 'node:path';
|
|
7
9
|
import yaml from 'js-yaml';
|
|
8
10
|
const CONFIG_DIR = join(homedir(), '.arcrun');
|
|
9
11
|
const CONFIG_PATH = join(CONFIG_DIR, 'config.yaml');
|
|
12
|
+
/** 專案層設定檔名(就近往上找)。含憑證 → 必須 gitignore(見 createCredentialsYamlIfMissing)。*/
|
|
13
|
+
export const PROJECT_CONFIG_NAME = '.arcrun.yaml';
|
|
14
|
+
/** env 變數 → config 欄位映射(最高層覆蓋)。CF 兩個沿用 wrangler 慣用名,CI 設一次兩邊通用。*/
|
|
15
|
+
const ENV_MAP = {
|
|
16
|
+
ARCRUN_MODE: 'mode',
|
|
17
|
+
ARCRUN_API_KEY: 'api_key',
|
|
18
|
+
ARCRUN_ENCRYPTION_KEY: 'encryption_key',
|
|
19
|
+
ARCRUN_CYPHER_EXECUTOR_URL: 'cypher_executor_url',
|
|
20
|
+
ARCRUN_MCP_URL: 'mcp_url',
|
|
21
|
+
CLOUDFLARE_ACCOUNT_ID: 'cloudflare_account_id',
|
|
22
|
+
CLOUDFLARE_API_TOKEN: 'cf_api_token',
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* 平台預設 MCP URL(mcp_url 未設時的 fallback,SaaS 用戶用)。
|
|
26
|
+
* MCP 搬進 arcrun 主庫後改用 arcrun.dev zone(mcp/wrangler.toml route = mcp.arcrun.dev)。
|
|
27
|
+
*/
|
|
28
|
+
export const DEFAULT_MCP_URL = 'https://mcp.arcrun.dev';
|
|
10
29
|
export function configExists() {
|
|
11
|
-
return existsSync(CONFIG_PATH);
|
|
30
|
+
return existsSync(CONFIG_PATH) || findProjectConfig() !== undefined;
|
|
31
|
+
}
|
|
32
|
+
/** 從 startDir 就近往上逐層找專案層 .arcrun.yaml,回傳第一個命中的路徑(停在檔案系統根)。*/
|
|
33
|
+
export function findProjectConfig(startDir = process.cwd()) {
|
|
34
|
+
let dir = startDir;
|
|
35
|
+
const root = parsePath(dir).root;
|
|
36
|
+
// 防呆上界:層數不會無限(root 一定到得了),但仍加保險避免異常路徑死迴圈。
|
|
37
|
+
for (let i = 0; i < 256; i++) {
|
|
38
|
+
const candidate = join(dir, PROJECT_CONFIG_NAME);
|
|
39
|
+
if (existsSync(candidate))
|
|
40
|
+
return candidate;
|
|
41
|
+
if (dir === root)
|
|
42
|
+
break;
|
|
43
|
+
const parent = dirname(dir);
|
|
44
|
+
if (parent === dir)
|
|
45
|
+
break;
|
|
46
|
+
dir = parent;
|
|
47
|
+
}
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
/** 讀全域設定(不分層)。無檔回 undefined。*/
|
|
51
|
+
function readGlobalConfig() {
|
|
52
|
+
if (!existsSync(CONFIG_PATH))
|
|
53
|
+
return undefined;
|
|
54
|
+
return yaml.load(readFileSync(CONFIG_PATH, 'utf8')) ?? undefined;
|
|
55
|
+
}
|
|
56
|
+
/** 讀專案層設定(不分層)。無檔回 undefined。*/
|
|
57
|
+
function readProjectConfig() {
|
|
58
|
+
const path = findProjectConfig();
|
|
59
|
+
if (!path)
|
|
60
|
+
return undefined;
|
|
61
|
+
return yaml.load(readFileSync(path, 'utf8')) ?? undefined;
|
|
62
|
+
}
|
|
63
|
+
/** 蒐集 env 覆蓋(只取有設值的 env,欄位級)。*/
|
|
64
|
+
function readEnvOverrides() {
|
|
65
|
+
const out = {};
|
|
66
|
+
for (const [envName, field] of Object.entries(ENV_MAP)) {
|
|
67
|
+
const v = process.env[envName];
|
|
68
|
+
if (v !== undefined && v !== '') {
|
|
69
|
+
// mode 需窄型別;其餘皆 string 欄位。
|
|
70
|
+
out[field] = v;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return out;
|
|
12
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* 三層分層解析:全域 → 疊專案層 → 疊 env(欄位級 merge,高層只覆蓋它提供的欄位)。
|
|
77
|
+
* 任一層都沒有 mode 時 fallback 'local',讓 validate --offline 等在無設定下可運作。
|
|
78
|
+
*/
|
|
13
79
|
export function loadConfig() {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
80
|
+
const merged = {
|
|
81
|
+
...(readGlobalConfig() ?? {}),
|
|
82
|
+
...(readProjectConfig() ?? {}),
|
|
83
|
+
...readEnvOverrides(),
|
|
84
|
+
};
|
|
85
|
+
if (!merged.mode)
|
|
86
|
+
merged.mode = 'local';
|
|
87
|
+
return merged;
|
|
88
|
+
}
|
|
89
|
+
/** 解析每個關鍵欄位的最終值與來源層(acr config --where 用)。*/
|
|
90
|
+
export function resolveConfigSources() {
|
|
91
|
+
const global = readGlobalConfig() ?? {};
|
|
92
|
+
const project = readProjectConfig() ?? {};
|
|
93
|
+
const env = readEnvOverrides();
|
|
94
|
+
const fields = [
|
|
95
|
+
'mode', 'api_key', 'encryption_key', 'cloudflare_account_id',
|
|
96
|
+
'cf_api_token', 'cypher_executor_url', 'mcp_url',
|
|
97
|
+
];
|
|
98
|
+
const rows = [];
|
|
99
|
+
for (const f of fields) {
|
|
100
|
+
let value;
|
|
101
|
+
let source = 'default';
|
|
102
|
+
if (f in env) {
|
|
103
|
+
value = env[f];
|
|
104
|
+
source = 'env';
|
|
105
|
+
}
|
|
106
|
+
else if (f in project) {
|
|
107
|
+
value = project[f];
|
|
108
|
+
source = 'project';
|
|
109
|
+
}
|
|
110
|
+
else if (f in global) {
|
|
111
|
+
value = global[f];
|
|
112
|
+
source = 'global';
|
|
113
|
+
}
|
|
114
|
+
else if (f === 'mode') {
|
|
115
|
+
value = 'local';
|
|
116
|
+
source = 'default';
|
|
117
|
+
}
|
|
118
|
+
else
|
|
119
|
+
continue;
|
|
120
|
+
rows.push({ field: f, value: String(value), source });
|
|
17
121
|
}
|
|
18
|
-
|
|
19
|
-
|
|
122
|
+
return rows;
|
|
123
|
+
}
|
|
124
|
+
/** 回傳本次解析實際採用的專案層設定檔路徑(無則 undefined)。acr config --where 顯示用。*/
|
|
125
|
+
export function activeProjectConfigPath() {
|
|
126
|
+
return findProjectConfig();
|
|
20
127
|
}
|
|
21
128
|
export function saveConfig(config) {
|
|
22
129
|
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
@@ -28,4 +135,12 @@ export function getCypherExecutorUrl(config) {
|
|
|
28
135
|
}
|
|
29
136
|
return 'https://cypher.arcrun.dev';
|
|
30
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* 取得 MCP server URL(薄殼原則:與 cypher_url 同一份 config 解析)。
|
|
140
|
+
* config 有 mcp_url(env/專案/全域 任一層)→ 用它;否則 fallback 平台預設。
|
|
141
|
+
* acr mcp-setup 用此決定要寫進專案 .mcp.json 的 URL → 切資料夾自動切 MCP。
|
|
142
|
+
*/
|
|
143
|
+
export function getMcpUrl(config) {
|
|
144
|
+
return config.mcp_url && config.mcp_url.trim() !== '' ? config.mcp_url : DEFAULT_MCP_URL;
|
|
145
|
+
}
|
|
31
146
|
//# sourceMappingURL=config.js.map
|
package/dist/lib/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,IAAI,MAAM,SAAS,CAAC;AA4B3B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AAC9C,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEpD,0EAA0E;AAC1E,MAAM,CAAC,MAAM,mBAAmB,GAAG,cAAc,CAAC;AAKlD,kEAAkE;AAClE,MAAM,OAAO,GAAuC;IAClD,WAAW,EAAE,MAAM;IACnB,cAAc,EAAE,SAAS;IACzB,qBAAqB,EAAE,gBAAgB;IACvC,0BAA0B,EAAE,qBAAqB;IACjD,cAAc,EAAE,SAAS;IACzB,qBAAqB,EAAE,uBAAuB;IAC9C,oBAAoB,EAAE,cAAc;CACrC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,wBAAwB,CAAC;AAExD,MAAM,UAAU,YAAY;IAC1B,OAAO,UAAU,CAAC,WAAW,CAAC,IAAI,iBAAiB,EAAE,KAAK,SAAS,CAAC;AACtE,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,iBAAiB,CAAC,WAAmB,OAAO,CAAC,GAAG,EAAE;IAChE,IAAI,GAAG,GAAG,QAAQ,CAAC;IACnB,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;IACjC,0CAA0C;IAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC;QACjD,IAAI,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;QAC5C,IAAI,GAAG,KAAK,IAAI;YAAE,MAAM;QACxB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QAC1B,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,+BAA+B;AAC/B,SAAS,gBAAgB;IACvB,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,SAAS,CAAC;IAC/C,OAAQ,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAA2B,IAAI,SAAS,CAAC;AAC9F,CAAC;AAED,gCAAgC;AAChC,SAAS,iBAAiB;IACxB,MAAM,IAAI,GAAG,iBAAiB,EAAE,CAAC;IACjC,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,OAAQ,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAA2B,IAAI,SAAS,CAAC;AACvF,CAAC;AAED,gCAAgC;AAChC,SAAS,gBAAgB;IACvB,MAAM,GAAG,GAA0B,EAAE,CAAC;IACtC,KAAK,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACvD,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC/B,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;YAChC,2BAA2B;YAC1B,GAA+B,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,MAAM,GAA0B;QACpC,GAAG,CAAC,gBAAgB,EAAE,IAAI,EAAE,CAAC;QAC7B,GAAG,CAAC,iBAAiB,EAAE,IAAI,EAAE,CAAC;QAC9B,GAAG,gBAAgB,EAAE;KACtB,CAAC;IACF,IAAI,CAAC,MAAM,CAAC,IAAI;QAAE,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC;IACxC,OAAO,MAAsB,CAAC;AAChC,CAAC;AAED,6CAA6C;AAC7C,MAAM,UAAU,oBAAoB;IAClC,MAAM,MAAM,GAAG,gBAAgB,EAAE,IAAI,EAAE,CAAC;IACxC,MAAM,OAAO,GAAG,iBAAiB,EAAE,IAAI,EAAE,CAAC;IAC1C,MAAM,GAAG,GAAG,gBAAgB,EAAE,CAAC;IAC/B,MAAM,MAAM,GAA2B;QACrC,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,uBAAuB;QAC5D,cAAc,EAAE,qBAAqB,EAAE,SAAS;KACjD,CAAC;IACF,MAAM,IAAI,GAA8E,EAAE,CAAC;IAC3F,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,KAAc,CAAC;QACnB,IAAI,MAAM,GAAiB,SAAS,CAAC;QACrC,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;YAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;YAAC,MAAM,GAAG,KAAK,CAAC;QAAC,CAAC;aAC5C,IAAI,CAAC,IAAI,OAAO,EAAE,CAAC;YAAC,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAAC,MAAM,GAAG,SAAS,CAAC;QAAC,CAAC;aAC7D,IAAI,CAAC,IAAI,MAAM,EAAE,CAAC;YAAC,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YAAC,MAAM,GAAG,QAAQ,CAAC;QAAC,CAAC;aAC1D,IAAI,CAAC,KAAK,MAAM,EAAE,CAAC;YAAC,KAAK,GAAG,OAAO,CAAC;YAAC,MAAM,GAAG,SAAS,CAAC;QAAC,CAAC;;YAC1D,SAAS;QACd,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,uBAAuB;IACrC,OAAO,iBAAiB,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAoB;IAC7C,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAoB;IACvD,IAAI,MAAM,CAAC,IAAI,KAAK,aAAa,IAAI,MAAM,CAAC,mBAAmB,EAAE,CAAC;QAChE,OAAO,MAAM,CAAC,mBAAmB,CAAC;IACpC,CAAC;IACD,OAAO,2BAA2B,CAAC;AACrC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,MAAoB;IAC5C,OAAO,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;AAC3F,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* deploy.ts — self-hosted Worker 部署(installer 的「下載 repo tarball + wrangler deploy」段)
|
|
3
|
+
*
|
|
4
|
+
* 對應 SDD:.agents/specs/arcrun/sdk-and-website/self-hosted-init.md §6(commit wasm + codeload)
|
|
5
|
+
*
|
|
6
|
+
* 策略(richblack 2026-06-02):repo 自帶預編譯 wasm(.component-builds 下各 component.wasm,
|
|
7
|
+
* 見 rule 05 慣例變更)→ CLI 從 GitHub codeload tarball 拿完整部署物 → 注入用戶的 KV id
|
|
8
|
+
* → 用用戶自己的 CF token wrangler deploy。用戶不需 git / tinygo,只需 wrangler。
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* init 要建立的 KV namespace(title)。
|
|
12
|
+
* 前 7 個權威來源:.claude/rules/01-tech-stack.md 資料儲存表(cypher-executor 用)。
|
|
13
|
+
* SUBMISSIONS_KV:registry worker 用(component 投稿)。漏建會讓 registry deploy 失敗 →
|
|
14
|
+
* 壓測 §2.6/#11「20/21」根因(registry/wrangler.toml 綁 SUBMISSIONS_KV,但注入清單沒有它,
|
|
15
|
+
* 殘留官方舊 id → wrangler deploy 因 KV 不存在而失敗)。補進來後回到 21/21。
|
|
16
|
+
*/
|
|
17
|
+
export declare const REQUIRED_KV_NAMESPACES: readonly ["WEBHOOKS", "CREDENTIALS_KV", "RECIPES", "USERS_KV", "SESSIONS_KV", "ANALYTICS_KV", "EXEC_CONTEXT", "SUBMISSIONS_KV"];
|
|
18
|
+
/** 部署後要提示用戶手動 `wrangler secret put ENCRYPTION_KEY` 的 Worker。*/
|
|
19
|
+
export declare const SECRET_TARGET_WORKERS: readonly ["arcrun-cypher-executor", "arcrun-auth-static-key", "arcrun-auth-service-account"];
|
|
20
|
+
export interface DeployContext {
|
|
21
|
+
accountId: string;
|
|
22
|
+
apiToken: string;
|
|
23
|
+
workerSubdomain: string;
|
|
24
|
+
kvNamespaceIds: Record<string, string>;
|
|
25
|
+
}
|
|
26
|
+
export interface DeployResult {
|
|
27
|
+
implemented: boolean;
|
|
28
|
+
cypherExecutorUrl?: string;
|
|
29
|
+
message: string;
|
|
30
|
+
}
|
|
31
|
+
/** 偵測 wrangler 是否已安裝(用戶前置:裝 CF CLI)。*/
|
|
32
|
+
export declare function wranglerAvailable(): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* 下載 repo codeload tarball(含預編譯 wasm)→ 注入用戶 KV id → wrangler deploy 全部 Worker。
|
|
35
|
+
*
|
|
36
|
+
* SDD self-hosted-init.md §6.4:
|
|
37
|
+
* 1. 下載 codeload tarball(ref 預設 main)→ 解壓到暫存目錄
|
|
38
|
+
* 2. 各 wrangler.toml 注入 ctx.kvNamespaceIds + cypher-executor WORKER_SUBDOMAIN
|
|
39
|
+
* 3. tier1=.component-builds/* 先 → tier2=cypher-executor/registry 後,逐一 wrangler deploy
|
|
40
|
+
* 4. 回 cypherExecutorUrl = https://arcrun-cypher-executor.<subdomain>.workers.dev
|
|
41
|
+
*
|
|
42
|
+
* 誠實(mindset §7):任一 worker deploy 失敗會收集進 message 回報,不假裝全綠。
|
|
43
|
+
*
|
|
44
|
+
* @param ctx 部署上下文
|
|
45
|
+
* @param ref git ref(branch / tag),預設 main;acr update 可帶 tag
|
|
46
|
+
*/
|
|
47
|
+
export declare function downloadAndDeploy(ctx: DeployContext, ref?: string): Promise<DeployResult>;
|
|
48
|
+
/**
|
|
49
|
+
* 移除 self-hosted fork 帳號沒有、會導致 wrangler deploy 失敗的官方專屬 TOML 區塊:
|
|
50
|
+
* - `[[routes]]`(含 pattern/zone_name):fork 沒有 arcrun.dev zone
|
|
51
|
+
* - `[[r2_buckets]]`:dead storage + 綁卡違背開源免費(registry-canon 1.5)
|
|
52
|
+
* - `[ai]`(Workers AI binding):免費帳號未必啟用,且自架預設不需要
|
|
53
|
+
* 純文字行級移除(TOML table 以空行 / 下一個 `[` 區塊結束)。worker 仍靠 `workers_dev = true` 對外。
|
|
54
|
+
*/
|
|
55
|
+
export declare function stripOfficialOnlyBindings(toml: string): string;
|
|
56
|
+
//# sourceMappingURL=deploy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/lib/deploy.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAWH;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,iIASzB,CAAC;AAEX,+DAA+D;AAC/D,eAAO,MAAM,qBAAqB,8FAIxB,CAAC;AAEX,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,OAAO,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,uCAAuC;AACvC,wBAAgB,iBAAiB,IAAI,OAAO,CAO3C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,CAmD/F;AAuFD;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA2B9D"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* deploy.ts — self-hosted Worker 部署(installer 的「下載 repo tarball + wrangler deploy」段)
|
|
3
|
+
*
|
|
4
|
+
* 對應 SDD:.agents/specs/arcrun/sdk-and-website/self-hosted-init.md §6(commit wasm + codeload)
|
|
5
|
+
*
|
|
6
|
+
* 策略(richblack 2026-06-02):repo 自帶預編譯 wasm(.component-builds 下各 component.wasm,
|
|
7
|
+
* 見 rule 05 慣例變更)→ CLI 從 GitHub codeload tarball 拿完整部署物 → 注入用戶的 KV id
|
|
8
|
+
* → 用用戶自己的 CF token wrangler deploy。用戶不需 git / tinygo,只需 wrangler。
|
|
9
|
+
*/
|
|
10
|
+
import { execFileSync } from 'node:child_process';
|
|
11
|
+
import { mkdtempSync, readFileSync, writeFileSync, existsSync, readdirSync, statSync } from 'node:fs';
|
|
12
|
+
import { tmpdir } from 'node:os';
|
|
13
|
+
import { join } from 'node:path';
|
|
14
|
+
/** GitHub repo(codeload tarball 來源)。fork 者改這裡或用 ARCRUN_REPO env。
|
|
15
|
+
* 注意:repo 名大小寫敏感(codeload 路徑需完全一致)。*/
|
|
16
|
+
const ARCRUN_REPO = process.env.ARCRUN_REPO ?? 'uncle6me-web/Arcrun';
|
|
17
|
+
/**
|
|
18
|
+
* init 要建立的 KV namespace(title)。
|
|
19
|
+
* 前 7 個權威來源:.claude/rules/01-tech-stack.md 資料儲存表(cypher-executor 用)。
|
|
20
|
+
* SUBMISSIONS_KV:registry worker 用(component 投稿)。漏建會讓 registry deploy 失敗 →
|
|
21
|
+
* 壓測 §2.6/#11「20/21」根因(registry/wrangler.toml 綁 SUBMISSIONS_KV,但注入清單沒有它,
|
|
22
|
+
* 殘留官方舊 id → wrangler deploy 因 KV 不存在而失敗)。補進來後回到 21/21。
|
|
23
|
+
*/
|
|
24
|
+
export const REQUIRED_KV_NAMESPACES = [
|
|
25
|
+
'WEBHOOKS',
|
|
26
|
+
'CREDENTIALS_KV',
|
|
27
|
+
'RECIPES',
|
|
28
|
+
'USERS_KV',
|
|
29
|
+
'SESSIONS_KV',
|
|
30
|
+
'ANALYTICS_KV',
|
|
31
|
+
'EXEC_CONTEXT',
|
|
32
|
+
'SUBMISSIONS_KV',
|
|
33
|
+
];
|
|
34
|
+
/** 部署後要提示用戶手動 `wrangler secret put ENCRYPTION_KEY` 的 Worker。*/
|
|
35
|
+
export const SECRET_TARGET_WORKERS = [
|
|
36
|
+
'arcrun-cypher-executor',
|
|
37
|
+
'arcrun-auth-static-key',
|
|
38
|
+
'arcrun-auth-service-account',
|
|
39
|
+
];
|
|
40
|
+
/** 偵測 wrangler 是否已安裝(用戶前置:裝 CF CLI)。*/
|
|
41
|
+
export function wranglerAvailable() {
|
|
42
|
+
try {
|
|
43
|
+
execFileSync('wrangler', ['--version'], { stdio: 'ignore' });
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 下載 repo codeload tarball(含預編譯 wasm)→ 注入用戶 KV id → wrangler deploy 全部 Worker。
|
|
52
|
+
*
|
|
53
|
+
* SDD self-hosted-init.md §6.4:
|
|
54
|
+
* 1. 下載 codeload tarball(ref 預設 main)→ 解壓到暫存目錄
|
|
55
|
+
* 2. 各 wrangler.toml 注入 ctx.kvNamespaceIds + cypher-executor WORKER_SUBDOMAIN
|
|
56
|
+
* 3. tier1=.component-builds/* 先 → tier2=cypher-executor/registry 後,逐一 wrangler deploy
|
|
57
|
+
* 4. 回 cypherExecutorUrl = https://arcrun-cypher-executor.<subdomain>.workers.dev
|
|
58
|
+
*
|
|
59
|
+
* 誠實(mindset §7):任一 worker deploy 失敗會收集進 message 回報,不假裝全綠。
|
|
60
|
+
*
|
|
61
|
+
* @param ctx 部署上下文
|
|
62
|
+
* @param ref git ref(branch / tag),預設 main;acr update 可帶 tag
|
|
63
|
+
*/
|
|
64
|
+
export async function downloadAndDeploy(ctx, ref = 'main') {
|
|
65
|
+
// 1. 下載 + 解壓 codeload tarball
|
|
66
|
+
let root;
|
|
67
|
+
try {
|
|
68
|
+
root = await downloadRepoTarball(ref);
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
return {
|
|
72
|
+
implemented: true,
|
|
73
|
+
message: `下載部署物失敗(${e instanceof Error ? e.message : e})。確認網路 + ARCRUN_REPO=${ARCRUN_REPO} 可達。`,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
// 2. 列出要部署的 worker 目錄(含 wrangler.toml),分 tier
|
|
77
|
+
const { tier1, tier2 } = discoverWorkerDirs(root);
|
|
78
|
+
if (tier1.length === 0 && tier2.length === 0) {
|
|
79
|
+
return { implemented: true, message: `部署物中找不到任何 wrangler.toml(root=${root})。` };
|
|
80
|
+
}
|
|
81
|
+
// 3. 對每個 worker:注入 KV id(+ cypher WORKER_SUBDOMAIN)→ wrangler deploy。tier1 先 tier2 後。
|
|
82
|
+
const failures = [];
|
|
83
|
+
let deployed = 0;
|
|
84
|
+
for (const dir of [...tier1, ...tier2]) {
|
|
85
|
+
const tomlPath = join(dir, 'wrangler.toml');
|
|
86
|
+
try {
|
|
87
|
+
injectWranglerConfig(tomlPath, ctx);
|
|
88
|
+
runWranglerDeploy(dir, ctx);
|
|
89
|
+
deployed++;
|
|
90
|
+
}
|
|
91
|
+
catch (e) {
|
|
92
|
+
failures.push(`${dir}: ${e instanceof Error ? e.message : String(e)}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const cypherExecutorUrl = ctx.workerSubdomain
|
|
96
|
+
? `https://arcrun-cypher-executor.${ctx.workerSubdomain}.workers.dev`
|
|
97
|
+
: undefined;
|
|
98
|
+
if (failures.length > 0) {
|
|
99
|
+
return {
|
|
100
|
+
implemented: true,
|
|
101
|
+
cypherExecutorUrl,
|
|
102
|
+
message: `部署 ${deployed}/${tier1.length + tier2.length} 成功,${failures.length} 失敗(誠實回報,未假綠):\n` +
|
|
103
|
+
failures.map(f => ` ✗ ${f}`).join('\n'),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
implemented: true,
|
|
108
|
+
cypherExecutorUrl,
|
|
109
|
+
message: `部署完成:${deployed} 個 Worker 全部成功。`,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/** 下載 codeload tarball 解壓到暫存目錄,回傳解壓出的 repo root 路徑。*/
|
|
113
|
+
async function downloadRepoTarball(ref) {
|
|
114
|
+
const url = `https://codeload.github.com/${ARCRUN_REPO}/tar.gz/${ref}`;
|
|
115
|
+
const res = await fetch(url, { signal: AbortSignal.timeout(120_000) });
|
|
116
|
+
if (!res.ok)
|
|
117
|
+
throw new Error(`codeload HTTP ${res.status}(${url})`);
|
|
118
|
+
const buf = Buffer.from(await res.arrayBuffer());
|
|
119
|
+
const dir = mkdtempSync(join(tmpdir(), 'arcrun-deploy-'));
|
|
120
|
+
const tarPath = join(dir, 'repo.tar.gz');
|
|
121
|
+
writeFileSync(tarPath, buf);
|
|
122
|
+
// 用系統 tar 解壓(macOS/Linux 內建)。tarball 解出單一頂層目錄 {repo}-{ref}/。
|
|
123
|
+
execFileSync('tar', ['-xzf', tarPath, '-C', dir], { stdio: 'ignore' });
|
|
124
|
+
const entries = readdirSync(dir).filter(n => n !== 'repo.tar.gz');
|
|
125
|
+
const top = entries.find(n => statSync(join(dir, n)).isDirectory());
|
|
126
|
+
if (!top)
|
|
127
|
+
throw new Error('tarball 解壓後找不到頂層目錄');
|
|
128
|
+
return join(dir, top);
|
|
129
|
+
}
|
|
130
|
+
/** 掃解壓出的部署物,回傳 tier1(.component-builds/*)與 tier2(cypher-executor/registry)目錄清單。*/
|
|
131
|
+
function discoverWorkerDirs(root) {
|
|
132
|
+
const tier1 = [];
|
|
133
|
+
const tier2 = [];
|
|
134
|
+
const cbRoot = join(root, '.component-builds');
|
|
135
|
+
if (existsSync(cbRoot)) {
|
|
136
|
+
for (const name of readdirSync(cbRoot)) {
|
|
137
|
+
const dir = join(cbRoot, name);
|
|
138
|
+
// 需同時有 wrangler.toml 且有 component.wasm 才部署。
|
|
139
|
+
// 「錯做成零件」的(claude_api / km_writer / kbdb_upsert_block)wasm 沒 commit 進 repo
|
|
140
|
+
// (.gitignore 排除,待降級成工作流/recipe)→ codeload 拿到的目錄缺 wasm → 自然跳過,
|
|
141
|
+
// 不讓 wrangler deploy 因缺檔失敗。
|
|
142
|
+
if (existsSync(join(dir, 'wrangler.toml')) && existsSync(join(dir, 'component.wasm'))) {
|
|
143
|
+
tier1.push(dir);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
for (const name of ['cypher-executor', 'registry']) {
|
|
148
|
+
const dir = join(root, name);
|
|
149
|
+
if (existsSync(join(dir, 'wrangler.toml')))
|
|
150
|
+
tier2.push(dir);
|
|
151
|
+
}
|
|
152
|
+
return { tier1, tier2 };
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* 注入用戶的 KV namespace id(取代 wrangler.toml 中各 binding 的 id)+ cypher WORKER_SUBDOMAIN,
|
|
156
|
+
* 並 strip 掉只有 arcrun 官方帳號才有的綁定(self-hosted fork 帳號沒有)。
|
|
157
|
+
*
|
|
158
|
+
* 為何 strip 而非刪 repo 內 toml(壓測 2026-06-04 阻斷項 #1#2#3#4):
|
|
159
|
+
* - repo 內各 worker toml 的 `[[routes]] zone_name="arcrun.dev"` 是**官方 prod CI 部署**需要的
|
|
160
|
+
* (對外開放零件)。直接從 repo 刪會破壞官方部署。
|
|
161
|
+
* - 但 fork 用戶**沒有 arcrun.dev zone** → wrangler deploy 找不到 zone 而失敗。
|
|
162
|
+
* - deploy.ts 只在 self-hosted 路徑跑,且改的是「暫存目錄副本」(SDD self-hosted-init.md §3 step 4),
|
|
163
|
+
* 不碰用戶 repo。所以在注入時 strip 掉這些官方專屬綁定 = 對的層級。
|
|
164
|
+
* - 每個 worker toml 都有 `workers_dev = true` → strip routes 後純靠 workers.dev URL,自架可達。
|
|
165
|
+
* - R2(`[[r2_buckets]]`)是 dead storage(registry-canon Phase 1.5),且綁卡違背開源免費 → 一併移除。
|
|
166
|
+
*/
|
|
167
|
+
function injectWranglerConfig(tomlPath, ctx) {
|
|
168
|
+
if (!existsSync(tomlPath))
|
|
169
|
+
return;
|
|
170
|
+
let toml = readFileSync(tomlPath, 'utf8');
|
|
171
|
+
// 對每個已建立的 KV namespace:把對應 binding 的 id 換成用戶的。
|
|
172
|
+
// 匹配 `[[kv_namespaces]] ... binding = "NAME" ... id = "OLD"` 的 id 行。
|
|
173
|
+
for (const [binding, id] of Object.entries(ctx.kvNamespaceIds)) {
|
|
174
|
+
if (!id)
|
|
175
|
+
continue;
|
|
176
|
+
const re = new RegExp(`(binding\\s*=\\s*"${binding}"\\s*\\n\\s*id\\s*=\\s*")[^"]*(")`, 'g');
|
|
177
|
+
toml = toml.replace(re, `$1${id}$2`);
|
|
178
|
+
}
|
|
179
|
+
// cypher-executor 的 WORKER_SUBDOMAIN(vars)換成用戶帳號 subdomain
|
|
180
|
+
if (ctx.workerSubdomain && /WORKER_SUBDOMAIN/.test(toml)) {
|
|
181
|
+
toml = toml.replace(/(WORKER_SUBDOMAIN\s*=\s*")[^"]*(")/, `$1${ctx.workerSubdomain}$2`);
|
|
182
|
+
}
|
|
183
|
+
toml = stripOfficialOnlyBindings(toml);
|
|
184
|
+
writeFileSync(tomlPath, toml, 'utf8');
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* 移除 self-hosted fork 帳號沒有、會導致 wrangler deploy 失敗的官方專屬 TOML 區塊:
|
|
188
|
+
* - `[[routes]]`(含 pattern/zone_name):fork 沒有 arcrun.dev zone
|
|
189
|
+
* - `[[r2_buckets]]`:dead storage + 綁卡違背開源免費(registry-canon 1.5)
|
|
190
|
+
* - `[ai]`(Workers AI binding):免費帳號未必啟用,且自架預設不需要
|
|
191
|
+
* 純文字行級移除(TOML table 以空行 / 下一個 `[` 區塊結束)。worker 仍靠 `workers_dev = true` 對外。
|
|
192
|
+
*/
|
|
193
|
+
export function stripOfficialOnlyBindings(toml) {
|
|
194
|
+
const lines = toml.split('\n');
|
|
195
|
+
const out = [];
|
|
196
|
+
let skipping = false;
|
|
197
|
+
const isBlockHeader = (l) => /^\s*\[\[?(routes|r2_buckets|ai)\]?\]\s*$/.test(l);
|
|
198
|
+
for (const line of lines) {
|
|
199
|
+
if (isBlockHeader(line)) {
|
|
200
|
+
skipping = true; // 進入要移除的區塊,連同 header 一起丟
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
if (skipping) {
|
|
204
|
+
// 區塊結束條件:遇到下一個 table header(`[...]`)或空行
|
|
205
|
+
if (/^\s*\[/.test(line)) {
|
|
206
|
+
skipping = false; // 這行是新區塊的開頭,保留並由下方邏輯處理
|
|
207
|
+
}
|
|
208
|
+
else if (line.trim() === '') {
|
|
209
|
+
skipping = false; // 空行結束區塊;空行本身丟掉避免堆疊空白
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
continue; // 仍在被移除區塊內(pattern/zone_name/binding/bucket_name 等)
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
out.push(line);
|
|
217
|
+
}
|
|
218
|
+
return out.join('\n');
|
|
219
|
+
}
|
|
220
|
+
/** 在 worker 目錄跑 wrangler deploy(用用戶的 CF token + account)。*/
|
|
221
|
+
function runWranglerDeploy(dir, ctx) {
|
|
222
|
+
// 先裝依賴(cypher-executor/registry 是 TS,wrangler 內建 esbuild bundle 需 node_modules)
|
|
223
|
+
if (existsSync(join(dir, 'package.json'))) {
|
|
224
|
+
const installer = existsSync(join(dir, 'pnpm-lock.yaml'))
|
|
225
|
+
? ['pnpm', 'install', '--frozen-lockfile']
|
|
226
|
+
: ['npm', 'install', '--no-audit', '--no-fund'];
|
|
227
|
+
execFileSync(installer[0], installer.slice(1), { cwd: dir, stdio: 'ignore' });
|
|
228
|
+
}
|
|
229
|
+
execFileSync('wrangler', ['deploy'], {
|
|
230
|
+
cwd: dir,
|
|
231
|
+
stdio: 'ignore',
|
|
232
|
+
env: {
|
|
233
|
+
...process.env,
|
|
234
|
+
CLOUDFLARE_API_TOKEN: ctx.apiToken,
|
|
235
|
+
CLOUDFLARE_ACCOUNT_ID: ctx.accountId,
|
|
236
|
+
},
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=deploy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/lib/deploy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface ExposureConsent {
|
|
2
|
+
confirmed_by_human: true;
|
|
3
|
+
understood: string;
|
|
4
|
+
confirmed_at: string;
|
|
5
|
+
suppress_future?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface ExposureWarningOptions {
|
|
8
|
+
_reserved?: never;
|
|
9
|
+
}
|
|
10
|
+
export interface ExposureContext {
|
|
11
|
+
/** 動作種類,顯示用:'webhook' | 'recipe' */
|
|
12
|
+
kind: string;
|
|
13
|
+
/** 資源名(用戶要打這個字確認)*/
|
|
14
|
+
resourceName: string;
|
|
15
|
+
/** 暴露後的 URL / 去向(顯示用,可選) */
|
|
16
|
+
destination?: string;
|
|
17
|
+
/** 這個資源讀取/送出什麼(盡力盤,盤不出傳 undefined) */
|
|
18
|
+
dataSummary?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 取得暴露同意。回傳 ExposureConsent(放進 push 請求 body)。
|
|
22
|
+
* 未取得同意 → 印訊息並 return null(呼叫端應中止)。
|
|
23
|
+
*/
|
|
24
|
+
export declare function obtainExposureConsent(ctx: ExposureContext, opts?: ExposureWarningOptions): Promise<ExposureConsent | null>;
|
|
25
|
+
//# sourceMappingURL=exposure-warning.d.ts.map
|