@kalphq/cli 0.0.0-dev-20260512060317 → 0.0.0-dev-20260512061708
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/{chunk-MKVNPOVJ.js → chunk-5QU2DXPC.js} +32 -68
- package/dist/chunk-5QU2DXPC.js.map +1 -0
- package/dist/chunk-MMR5WRLY.js +147 -0
- package/dist/chunk-MMR5WRLY.js.map +1 -0
- package/dist/{create-WU5JH6FP.js → create-XC55BUCS.js} +7 -2
- package/dist/create-XC55BUCS.js.map +1 -0
- package/dist/{deploy-FVOKQP6K.js → deploy-MJLWDGOT.js} +11 -21
- package/dist/deploy-MJLWDGOT.js.map +1 -0
- package/dist/index.js +8 -8
- package/dist/index.js.map +1 -1
- package/dist/login-72Q2FQZR.js +61 -0
- package/dist/login-72Q2FQZR.js.map +1 -0
- package/dist/{push-R3YYM4VP.js → push-RNJ7PQUW.js} +62 -85
- package/dist/push-RNJ7PQUW.js.map +1 -0
- package/package.json +4 -4
- package/dist/chunk-MKVNPOVJ.js.map +0 -1
- package/dist/create-WU5JH6FP.js.map +0 -1
- package/dist/deploy-FVOKQP6K.js.map +0 -1
- package/dist/login-M5Y57ZZU.js +0 -73
- package/dist/login-M5Y57ZZU.js.map +0 -1
- package/dist/push-R3YYM4VP.js.map +0 -1
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
resolveProvider
|
|
4
|
+
} from "./chunk-MMR5WRLY.js";
|
|
2
5
|
import {
|
|
3
6
|
ensureStudioSecrets,
|
|
4
7
|
materializeRuntime,
|
|
@@ -11,7 +14,6 @@ import {
|
|
|
11
14
|
|
|
12
15
|
// src/utils/deploy.ts
|
|
13
16
|
import { readFile as readFile2, writeFile } from "fs/promises";
|
|
14
|
-
import { execa } from "execa";
|
|
15
17
|
|
|
16
18
|
// src/utils/ai.ts
|
|
17
19
|
import { access, readFile } from "fs/promises";
|
|
@@ -53,10 +55,6 @@ function getRequiredSecretForProvider(provider) {
|
|
|
53
55
|
}
|
|
54
56
|
|
|
55
57
|
// src/utils/deploy.ts
|
|
56
|
-
function findWorkersUrl(output) {
|
|
57
|
-
const match = output.match(/https:\/\/[^\s]+\.workers\.dev/);
|
|
58
|
-
return match?.[0] ?? null;
|
|
59
|
-
}
|
|
60
58
|
async function readWranglerConfig(configPath) {
|
|
61
59
|
const text = await readFile2(configPath, "utf-8");
|
|
62
60
|
return JSON.parse(text);
|
|
@@ -68,40 +66,13 @@ async function writeWranglerConfig(configPath, config) {
|
|
|
68
66
|
function deriveKvNamespaceTitle(workerName, binding) {
|
|
69
67
|
return `${workerName}-${binding.toLowerCase().replace(/_/g, "-")}`;
|
|
70
68
|
}
|
|
71
|
-
function parseKvListOutput(stdout) {
|
|
72
|
-
const trimmed = stdout.trim();
|
|
73
|
-
if (!trimmed) return [];
|
|
74
|
-
try {
|
|
75
|
-
const parsed = JSON.parse(trimmed);
|
|
76
|
-
if (Array.isArray(parsed)) {
|
|
77
|
-
return parsed.map((item) => ({
|
|
78
|
-
id: String(item.id ?? ""),
|
|
79
|
-
title: String(item.title ?? "")
|
|
80
|
-
})).filter((item) => !!item.id && !!item.title);
|
|
81
|
-
}
|
|
82
|
-
} catch {
|
|
83
|
-
}
|
|
84
|
-
const matches = trimmed.match(/[a-f0-9]{32}\s+[^\r\n]+/gi) ?? [];
|
|
85
|
-
return matches.map((line) => {
|
|
86
|
-
const [id, ...rest] = line.trim().split(/\s+/g);
|
|
87
|
-
return { id: id ?? "", title: rest.join(" ") };
|
|
88
|
-
}).filter((item) => !!item.id && !!item.title);
|
|
89
|
-
}
|
|
90
69
|
async function listKvNamespaces(cwd, configPath) {
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
return parseKvListOutput(tryJson.stdout);
|
|
98
|
-
}
|
|
99
|
-
const plain = await execa(
|
|
100
|
-
"npx",
|
|
101
|
-
["wrangler", "kv", "namespace", "list", "--config", configPath],
|
|
102
|
-
{ cwd }
|
|
103
|
-
);
|
|
104
|
-
return parseKvListOutput(plain.stdout);
|
|
70
|
+
const provider = resolveProvider();
|
|
71
|
+
const namespaces = await provider.listNamespaces({ cwd, configPath });
|
|
72
|
+
return namespaces.map((item) => ({
|
|
73
|
+
id: item.id,
|
|
74
|
+
title: item.title
|
|
75
|
+
}));
|
|
105
76
|
}
|
|
106
77
|
async function ensureKvNamespaceBindingId(cwd, configPath) {
|
|
107
78
|
const config = await readWranglerConfig(configPath);
|
|
@@ -121,30 +92,19 @@ async function ensureKvNamespaceBindingId(cwd, configPath) {
|
|
|
121
92
|
function isNamespaceAlreadyExistsError(output) {
|
|
122
93
|
return output.includes("[code: 10014]") && output.includes("already exists");
|
|
123
94
|
}
|
|
124
|
-
async function resolveWorkerUrl(configPath, deployOutput) {
|
|
125
|
-
const fromOutput = findWorkersUrl(deployOutput);
|
|
126
|
-
if (fromOutput) return fromOutput;
|
|
127
|
-
const configText = await readFile2(configPath, "utf-8").catch(
|
|
128
|
-
() => null
|
|
129
|
-
);
|
|
130
|
-
const workerName = configText?.match(/"name"\s*:\s*"([^"]+)"/)?.[1];
|
|
131
|
-
if (workerName) {
|
|
132
|
-
return `https://${workerName}.workers.dev`;
|
|
133
|
-
}
|
|
134
|
-
throw new Error("Could not resolve worker URL from wrangler deploy output.");
|
|
135
|
-
}
|
|
136
95
|
async function runInitialDeploy(cwd) {
|
|
137
96
|
const auth = await requireAuth();
|
|
138
|
-
const
|
|
139
|
-
const requiredProviderSecret = getRequiredSecretForProvider(
|
|
97
|
+
const aiProvider = await resolveProviderFromConfig(cwd);
|
|
98
|
+
const requiredProviderSecret = getRequiredSecretForProvider(aiProvider);
|
|
140
99
|
const envMap = await readDotEnv(cwd);
|
|
141
100
|
const providerSecretValue = envMap[requiredProviderSecret]?.trim();
|
|
142
101
|
if (!providerSecretValue) {
|
|
143
102
|
throw new Error(
|
|
144
|
-
`Missing required secret ${requiredProviderSecret} for provider "${
|
|
103
|
+
`Missing required secret ${requiredProviderSecret} for provider "${aiProvider}". Add it to .env before deploy.`
|
|
145
104
|
);
|
|
146
105
|
}
|
|
147
106
|
const secrets = await ensureStudioSecrets(cwd);
|
|
107
|
+
const runtimeProvider = resolveProvider();
|
|
148
108
|
const runtime = await materializeRuntime(cwd);
|
|
149
109
|
let secretSyncFailed = false;
|
|
150
110
|
const secretEntries = [
|
|
@@ -155,12 +115,12 @@ async function runInitialDeploy(cwd) {
|
|
|
155
115
|
];
|
|
156
116
|
for (const [name, value] of secretEntries) {
|
|
157
117
|
try {
|
|
158
|
-
await
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
);
|
|
118
|
+
await runtimeProvider.putSecret({
|
|
119
|
+
cwd,
|
|
120
|
+
configPath: runtime.wranglerConfigPath,
|
|
121
|
+
name,
|
|
122
|
+
value
|
|
123
|
+
});
|
|
164
124
|
} catch {
|
|
165
125
|
secretSyncFailed = true;
|
|
166
126
|
break;
|
|
@@ -177,21 +137,25 @@ async function runInitialDeploy(cwd) {
|
|
|
177
137
|
"--secrets-file",
|
|
178
138
|
".env"
|
|
179
139
|
] : ["wrangler", "deploy", "--config", runtime.wranglerConfigPath];
|
|
180
|
-
let deploy = await
|
|
140
|
+
let deploy = await runtimeProvider.deployRuntime({
|
|
141
|
+
cwd,
|
|
142
|
+
configPath: runtime.wranglerConfigPath,
|
|
143
|
+
useSecretsFile: secretSyncFailed
|
|
144
|
+
}).catch((error) => error);
|
|
181
145
|
if (deploy instanceof Error) {
|
|
182
|
-
const combined =
|
|
146
|
+
const combined = deploy.message;
|
|
183
147
|
if (isNamespaceAlreadyExistsError(combined)) {
|
|
184
148
|
await ensureKvNamespaceBindingId(cwd, runtime.wranglerConfigPath);
|
|
185
|
-
deploy = await
|
|
149
|
+
deploy = await runtimeProvider.deployRuntime({
|
|
150
|
+
cwd,
|
|
151
|
+
configPath: runtime.wranglerConfigPath,
|
|
152
|
+
useSecretsFile: secretSyncFailed
|
|
153
|
+
});
|
|
186
154
|
} else {
|
|
187
155
|
throw deploy;
|
|
188
156
|
}
|
|
189
157
|
}
|
|
190
|
-
const
|
|
191
|
-
const workerUrl = await resolveWorkerUrl(
|
|
192
|
-
runtime.wranglerConfigPath,
|
|
193
|
-
deployStdout
|
|
194
|
-
);
|
|
158
|
+
const workerUrl = deploy.workerUrl;
|
|
195
159
|
const existingState = await readProjectState(cwd);
|
|
196
160
|
await writeProjectState(cwd, {
|
|
197
161
|
workerUrl,
|
|
@@ -205,4 +169,4 @@ async function runInitialDeploy(cwd) {
|
|
|
205
169
|
export {
|
|
206
170
|
runInitialDeploy
|
|
207
171
|
};
|
|
208
|
-
//# sourceMappingURL=chunk-
|
|
172
|
+
//# sourceMappingURL=chunk-5QU2DXPC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/deploy.ts","../src/utils/ai.ts"],"sourcesContent":["import { readFile, writeFile } from \"node:fs/promises\";\nimport { execa } from \"execa\";\nimport { requireAuth } from \"@/utils/auth\";\nimport { ensureStudioSecrets } from \"@/utils/secret\";\nimport { readProjectState, writeProjectState } from \"@/utils/project-state\";\nimport { materializeRuntime } from \"@/utils/runtime\";\nimport {\n getRequiredSecretForProvider,\n readDotEnv,\n resolveProviderFromConfig,\n} from \"@/utils/ai\";\nimport { resolveProvider } from \"@/utils/providers\";\n\nfunction findWorkersUrl(output: string): string | null {\n const match = output.match(/https:\\/\\/[^\\s]+\\.workers\\.dev/);\n return match?.[0] ?? null;\n}\n\ninterface RuntimeWranglerConfig {\n name?: string;\n kv_namespaces?: Array<{ binding: string; id?: string }>;\n}\n\ninterface KvNamespaceInfo {\n id: string;\n title: string;\n}\n\nasync function readWranglerConfig(\n configPath: string,\n): Promise<RuntimeWranglerConfig> {\n const text = await readFile(configPath, \"utf-8\");\n return JSON.parse(text) as RuntimeWranglerConfig;\n}\n\nasync function writeWranglerConfig(\n configPath: string,\n config: RuntimeWranglerConfig,\n): Promise<void> {\n await writeFile(configPath, `${JSON.stringify(config, null, 2)}\\n`, \"utf-8\");\n}\n\nfunction deriveKvNamespaceTitle(workerName: string, binding: string): string {\n return `${workerName}-${binding.toLowerCase().replace(/_/g, \"-\")}`;\n}\n\nfunction parseKvListOutput(stdout: string): KvNamespaceInfo[] {\n const trimmed = stdout.trim();\n if (!trimmed) return [];\n\n try {\n const parsed = JSON.parse(trimmed);\n if (Array.isArray(parsed)) {\n return parsed\n .map((item) => ({\n id: String((item as { id?: string }).id ?? \"\"),\n title: String((item as { title?: string }).title ?? \"\"),\n }))\n .filter((item) => !!item.id && !!item.title);\n }\n } catch {\n // fallback to text parsing below\n }\n\n const matches = trimmed.match(/[a-f0-9]{32}\\s+[^\\r\\n]+/gi) ?? [];\n return matches\n .map((line) => {\n const [id, ...rest] = line.trim().split(/\\s+/g);\n return { id: id ?? \"\", title: rest.join(\" \") };\n })\n .filter((item) => !!item.id && !!item.title);\n}\n\nasync function listKvNamespaces(\n cwd: string,\n configPath: string,\n): Promise<KvNamespaceInfo[]> {\n const provider = resolveProvider();\n const namespaces = await provider.listNamespaces({ cwd, configPath });\n return namespaces.map((item) => ({\n id: item.id,\n title: item.title,\n }));\n}\n\nasync function ensureKvNamespaceBindingId(\n cwd: string,\n configPath: string,\n): Promise<string | null> {\n const config = await readWranglerConfig(configPath);\n const binding = config.kv_namespaces?.find(\n (item) => item.binding === \"KALP_MANIFESTS\",\n );\n\n if (!binding || !config.name) return null;\n if (binding.id) return binding.id;\n\n const expectedTitle = deriveKvNamespaceTitle(config.name, binding.binding);\n const namespaces = await listKvNamespaces(cwd, configPath);\n const existing = namespaces.find((item) => item.title === expectedTitle);\n if (!existing) return null;\n\n binding.id = existing.id;\n await writeWranglerConfig(configPath, config);\n return existing.id;\n}\n\nfunction isNamespaceAlreadyExistsError(output: string): boolean {\n return output.includes(\"[code: 10014]\") && output.includes(\"already exists\");\n}\n\nasync function resolveWorkerUrl(\n configPath: string,\n deployOutput: string,\n): Promise<string> {\n const fromOutput = findWorkersUrl(deployOutput);\n if (fromOutput) return fromOutput;\n\n const configText = await readFile(configPath, \"utf-8\").catch(\n () => null as string | null,\n );\n const workerName = configText?.match(/\"name\"\\s*:\\s*\"([^\"]+)\"/)?.[1];\n\n if (workerName) {\n return `https://${workerName}.workers.dev`;\n }\n\n throw new Error(\"Could not resolve worker URL from wrangler deploy output.\");\n}\n\nexport async function runInitialDeploy(cwd: string): Promise<{\n workerUrl: string;\n accountId: string;\n}> {\n const auth = await requireAuth();\n const aiProvider = await resolveProviderFromConfig(cwd);\n const requiredProviderSecret = getRequiredSecretForProvider(aiProvider);\n const envMap = await readDotEnv(cwd);\n const providerSecretValue = envMap[requiredProviderSecret]?.trim();\n if (!providerSecretValue) {\n throw new Error(\n `Missing required secret ${requiredProviderSecret} for provider \"${aiProvider}\". Add it to .env before deploy.`,\n );\n }\n\n const secrets = await ensureStudioSecrets(cwd);\n const runtimeProvider = resolveProvider();\n const runtime = await materializeRuntime(cwd);\n let secretSyncFailed = false;\n const secretEntries = [\n [\"KALP_SECRET_KEY\", secrets.key],\n [\"KALP_STUDIO_PASSWORD\", secrets.studioPassword],\n [\"KALP_STUDIO_ADMIN_USER\", secrets.studioAdminUser],\n [requiredProviderSecret, providerSecretValue],\n ] as const;\n\n for (const [name, value] of secretEntries) {\n try {\n await runtimeProvider.putSecret({\n cwd,\n configPath: runtime.wranglerConfigPath,\n name,\n value,\n });\n } catch {\n secretSyncFailed = true;\n break;\n }\n }\n\n await ensureKvNamespaceBindingId(cwd, runtime.wranglerConfigPath).catch(\n () => null,\n );\n\n const deployArgs = secretSyncFailed\n ? [\n \"wrangler\",\n \"deploy\",\n \"--config\",\n runtime.wranglerConfigPath,\n \"--secrets-file\",\n \".env\",\n ]\n : [\"wrangler\", \"deploy\", \"--config\", runtime.wranglerConfigPath];\n\n let deploy = await runtimeProvider\n .deployRuntime({\n cwd,\n configPath: runtime.wranglerConfigPath,\n useSecretsFile: secretSyncFailed,\n })\n .catch((error) => error);\n if (deploy instanceof Error) {\n const combined = deploy.message;\n if (isNamespaceAlreadyExistsError(combined)) {\n await ensureKvNamespaceBindingId(cwd, runtime.wranglerConfigPath);\n deploy = await runtimeProvider.deployRuntime({\n cwd,\n configPath: runtime.wranglerConfigPath,\n useSecretsFile: secretSyncFailed,\n });\n } else {\n throw deploy;\n }\n }\n\n const workerUrl = deploy.workerUrl;\n\n const existingState = await readProjectState(cwd);\n\n await writeProjectState(cwd, {\n workerUrl,\n deployedAt: new Date().toISOString(),\n accountId: auth.accountId,\n agents: existingState?.agents ?? {},\n });\n\n return { workerUrl, accountId: auth.accountId };\n}\n","import { access, readFile } from \"node:fs/promises\";\nimport { constants } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { createJiti } from \"jiti\";\n\nexport type AIProvider = \"openai\" | \"anthropic\" | \"openrouter\" | \"custom\";\n\nconst PROVIDER_SECRET_MAP: Record<AIProvider, string> = {\n openai: \"OPENAI_API_KEY\",\n anthropic: \"ANTHROPIC_API_KEY\",\n openrouter: \"OPENROUTER_API_KEY\",\n custom: \"CUSTOM_AI_API_KEY\",\n};\n\nfunction parseEnv(content: string): Record<string, string> {\n const env: Record<string, string> = {};\n for (const raw of content.split(/\\r?\\n/g)) {\n const line = raw.trim();\n if (!line || line.startsWith(\"#\")) continue;\n const idx = line.indexOf(\"=\");\n if (idx <= 0) continue;\n env[line.slice(0, idx).trim()] = line.slice(idx + 1);\n }\n return env;\n}\n\nexport async function resolveProviderFromConfig(cwd: string): Promise<AIProvider> {\n const configPath = join(cwd, \"kalp.config.ts\");\n await access(configPath, constants.F_OK);\n const jiti = createJiti(cwd, { interopDefault: true });\n const config = (await jiti.import(configPath)) as\n | { default?: { ai?: { provider?: AIProvider } }; ai?: { provider?: AIProvider } }\n | undefined;\n const provider = config?.default?.ai?.provider ?? config?.ai?.provider ?? \"openai\";\n return provider;\n}\n\nexport async function readDotEnv(cwd: string): Promise<Record<string, string>> {\n const envPath = join(cwd, \".env\");\n const content = await readFile(envPath, \"utf-8\").catch(() => \"\");\n return parseEnv(content);\n}\n\nexport function getRequiredSecretForProvider(provider: AIProvider): string {\n return PROVIDER_SECRET_MAP[provider];\n}\n"],"mappings":";;;;;;;;;;;;;;;AAAA,SAAS,YAAAA,WAAU,iBAAiB;;;ACApC,SAAS,QAAQ,gBAAgB;AACjC,SAAS,iBAAiB;AAC1B,SAAS,YAAY;AACrB,SAAS,kBAAkB;AAI3B,IAAM,sBAAkD;AAAA,EACtD,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,QAAQ;AACV;AAEA,SAAS,SAAS,SAAyC;AACzD,QAAM,MAA8B,CAAC;AACrC,aAAW,OAAO,QAAQ,MAAM,QAAQ,GAAG;AACzC,UAAM,OAAO,IAAI,KAAK;AACtB,QAAI,CAAC,QAAQ,KAAK,WAAW,GAAG,EAAG;AACnC,UAAM,MAAM,KAAK,QAAQ,GAAG;AAC5B,QAAI,OAAO,EAAG;AACd,QAAI,KAAK,MAAM,GAAG,GAAG,EAAE,KAAK,CAAC,IAAI,KAAK,MAAM,MAAM,CAAC;AAAA,EACrD;AACA,SAAO;AACT;AAEA,eAAsB,0BAA0B,KAAkC;AAChF,QAAM,aAAa,KAAK,KAAK,gBAAgB;AAC7C,QAAM,OAAO,YAAY,UAAU,IAAI;AACvC,QAAM,OAAO,WAAW,KAAK,EAAE,gBAAgB,KAAK,CAAC;AACrD,QAAM,SAAU,MAAM,KAAK,OAAO,UAAU;AAG5C,QAAM,WAAW,QAAQ,SAAS,IAAI,YAAY,QAAQ,IAAI,YAAY;AAC1E,SAAO;AACT;AAEA,eAAsB,WAAW,KAA8C;AAC7E,QAAM,UAAU,KAAK,KAAK,MAAM;AAChC,QAAM,UAAU,MAAM,SAAS,SAAS,OAAO,EAAE,MAAM,MAAM,EAAE;AAC/D,SAAO,SAAS,OAAO;AACzB;AAEO,SAAS,6BAA6B,UAA8B;AACzE,SAAO,oBAAoB,QAAQ;AACrC;;;ADjBA,eAAe,mBACb,YACgC;AAChC,QAAM,OAAO,MAAMC,UAAS,YAAY,OAAO;AAC/C,SAAO,KAAK,MAAM,IAAI;AACxB;AAEA,eAAe,oBACb,YACA,QACe;AACf,QAAM,UAAU,YAAY,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,GAAM,OAAO;AAC7E;AAEA,SAAS,uBAAuB,YAAoB,SAAyB;AAC3E,SAAO,GAAG,UAAU,IAAI,QAAQ,YAAY,EAAE,QAAQ,MAAM,GAAG,CAAC;AAClE;AA6BA,eAAe,iBACb,KACA,YAC4B;AAC5B,QAAM,WAAW,gBAAgB;AACjC,QAAM,aAAa,MAAM,SAAS,eAAe,EAAE,KAAK,WAAW,CAAC;AACpE,SAAO,WAAW,IAAI,CAAC,UAAU;AAAA,IAC/B,IAAI,KAAK;AAAA,IACT,OAAO,KAAK;AAAA,EACd,EAAE;AACJ;AAEA,eAAe,2BACb,KACA,YACwB;AACxB,QAAM,SAAS,MAAM,mBAAmB,UAAU;AAClD,QAAM,UAAU,OAAO,eAAe;AAAA,IACpC,CAAC,SAAS,KAAK,YAAY;AAAA,EAC7B;AAEA,MAAI,CAAC,WAAW,CAAC,OAAO,KAAM,QAAO;AACrC,MAAI,QAAQ,GAAI,QAAO,QAAQ;AAE/B,QAAM,gBAAgB,uBAAuB,OAAO,MAAM,QAAQ,OAAO;AACzE,QAAM,aAAa,MAAM,iBAAiB,KAAK,UAAU;AACzD,QAAM,WAAW,WAAW,KAAK,CAAC,SAAS,KAAK,UAAU,aAAa;AACvE,MAAI,CAAC,SAAU,QAAO;AAEtB,UAAQ,KAAK,SAAS;AACtB,QAAM,oBAAoB,YAAY,MAAM;AAC5C,SAAO,SAAS;AAClB;AAEA,SAAS,8BAA8B,QAAyB;AAC9D,SAAO,OAAO,SAAS,eAAe,KAAK,OAAO,SAAS,gBAAgB;AAC7E;AAqBA,eAAsB,iBAAiB,KAGpC;AACD,QAAM,OAAO,MAAM,YAAY;AAC/B,QAAM,aAAa,MAAM,0BAA0B,GAAG;AACtD,QAAM,yBAAyB,6BAA6B,UAAU;AACtE,QAAM,SAAS,MAAM,WAAW,GAAG;AACnC,QAAM,sBAAsB,OAAO,sBAAsB,GAAG,KAAK;AACjE,MAAI,CAAC,qBAAqB;AACxB,UAAM,IAAI;AAAA,MACR,2BAA2B,sBAAsB,kBAAkB,UAAU;AAAA,IAC/E;AAAA,EACF;AAEA,QAAM,UAAU,MAAM,oBAAoB,GAAG;AAC7C,QAAM,kBAAkB,gBAAgB;AACxC,QAAM,UAAU,MAAM,mBAAmB,GAAG;AAC5C,MAAI,mBAAmB;AACvB,QAAM,gBAAgB;AAAA,IACpB,CAAC,mBAAmB,QAAQ,GAAG;AAAA,IAC/B,CAAC,wBAAwB,QAAQ,cAAc;AAAA,IAC/C,CAAC,0BAA0B,QAAQ,eAAe;AAAA,IAClD,CAAC,wBAAwB,mBAAmB;AAAA,EAC9C;AAEA,aAAW,CAAC,MAAM,KAAK,KAAK,eAAe;AACzC,QAAI;AACF,YAAM,gBAAgB,UAAU;AAAA,QAC9B;AAAA,QACA,YAAY,QAAQ;AAAA,QACpB;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH,QAAQ;AACN,yBAAmB;AACnB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,2BAA2B,KAAK,QAAQ,kBAAkB,EAAE;AAAA,IAChE,MAAM;AAAA,EACR;AAEA,QAAM,aAAa,mBACf;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,EACF,IACA,CAAC,YAAY,UAAU,YAAY,QAAQ,kBAAkB;AAEjE,MAAI,SAAS,MAAM,gBAChB,cAAc;AAAA,IACb;AAAA,IACA,YAAY,QAAQ;AAAA,IACpB,gBAAgB;AAAA,EAClB,CAAC,EACA,MAAM,CAAC,UAAU,KAAK;AACzB,MAAI,kBAAkB,OAAO;AAC3B,UAAM,WAAW,OAAO;AACxB,QAAI,8BAA8B,QAAQ,GAAG;AAC3C,YAAM,2BAA2B,KAAK,QAAQ,kBAAkB;AAChE,eAAS,MAAM,gBAAgB,cAAc;AAAA,QAC3C;AAAA,QACA,YAAY,QAAQ;AAAA,QACpB,gBAAgB;AAAA,MAClB,CAAC;AAAA,IACH,OAAO;AACL,YAAM;AAAA,IACR;AAAA,EACF;AAEA,QAAM,YAAY,OAAO;AAEzB,QAAM,gBAAgB,MAAM,iBAAiB,GAAG;AAEhD,QAAM,kBAAkB,KAAK;AAAA,IAC3B;AAAA,IACA,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,IACnC,WAAW,KAAK;AAAA,IAChB,QAAQ,eAAe,UAAU,CAAC;AAAA,EACpC,CAAC;AAED,SAAO,EAAE,WAAW,WAAW,KAAK,UAAU;AAChD;","names":["readFile","readFile"]}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
getCloudflareIdentity
|
|
4
|
+
} from "./chunk-5RODADXW.js";
|
|
5
|
+
|
|
6
|
+
// src/utils/providers/cloudflare.ts
|
|
7
|
+
import { execa } from "execa";
|
|
8
|
+
import { mkdtemp, readFile, rm, writeFile } from "fs/promises";
|
|
9
|
+
import { join } from "path";
|
|
10
|
+
import { tmpdir } from "os";
|
|
11
|
+
function parseNamespaceList(stdout) {
|
|
12
|
+
try {
|
|
13
|
+
const parsed = JSON.parse(stdout);
|
|
14
|
+
if (Array.isArray(parsed)) {
|
|
15
|
+
return parsed.map((item) => ({
|
|
16
|
+
id: String(item.id ?? ""),
|
|
17
|
+
title: String(item.title ?? "")
|
|
18
|
+
})).filter((item) => !!item.id && !!item.title);
|
|
19
|
+
}
|
|
20
|
+
} catch {
|
|
21
|
+
}
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
function findWorkerUrl(output) {
|
|
25
|
+
const match = output.match(/https:\/\/[^\s]+\.workers\.dev/);
|
|
26
|
+
return match?.[0] ?? null;
|
|
27
|
+
}
|
|
28
|
+
var cloudflareProvider = {
|
|
29
|
+
name: "cloudflare",
|
|
30
|
+
async login() {
|
|
31
|
+
await execa("npx", ["wrangler", "login"], { stdio: "inherit" });
|
|
32
|
+
},
|
|
33
|
+
async whoami() {
|
|
34
|
+
const identity = await getCloudflareIdentity();
|
|
35
|
+
const account = identity?.accounts?.[0];
|
|
36
|
+
const accountId = account?.id ?? account?.account_tag;
|
|
37
|
+
const email = identity?.email;
|
|
38
|
+
if (!accountId || !email) return null;
|
|
39
|
+
return { provider: "cloudflare", accountId, email };
|
|
40
|
+
},
|
|
41
|
+
async putSecret({ cwd, configPath, name, value }) {
|
|
42
|
+
await execa(
|
|
43
|
+
"npx",
|
|
44
|
+
["wrangler", "secret", "put", name, "--config", configPath],
|
|
45
|
+
{ cwd, input: `${value}
|
|
46
|
+
` }
|
|
47
|
+
);
|
|
48
|
+
},
|
|
49
|
+
async deployRuntime({ cwd, configPath, useSecretsFile }) {
|
|
50
|
+
const args = useSecretsFile ? ["wrangler", "deploy", "--config", configPath, "--secrets-file", ".env"] : ["wrangler", "deploy", "--config", configPath];
|
|
51
|
+
const deploy = await execa("npx", args, { cwd });
|
|
52
|
+
const rawOutput = [deploy.stdout, deploy.stderr].filter(Boolean).join("\n");
|
|
53
|
+
const workerUrl = findWorkerUrl(rawOutput);
|
|
54
|
+
if (!workerUrl) {
|
|
55
|
+
const configText = await readFile(configPath, "utf-8").catch(() => null);
|
|
56
|
+
const workerName = configText?.match(/"name"\s*:\s*"([^"]+)"/)?.[1];
|
|
57
|
+
if (!workerName) {
|
|
58
|
+
throw new Error("Could not resolve runtime URL from deployment output.");
|
|
59
|
+
}
|
|
60
|
+
return { workerUrl: `https://${workerName}.workers.dev`, rawOutput };
|
|
61
|
+
}
|
|
62
|
+
return { workerUrl, rawOutput };
|
|
63
|
+
},
|
|
64
|
+
async putManifest({ cwd, configPath, key, jsonPath }) {
|
|
65
|
+
await execa(
|
|
66
|
+
"npx",
|
|
67
|
+
[
|
|
68
|
+
"wrangler",
|
|
69
|
+
"kv",
|
|
70
|
+
"key",
|
|
71
|
+
"put",
|
|
72
|
+
"--binding",
|
|
73
|
+
"KALP_MANIFESTS",
|
|
74
|
+
key,
|
|
75
|
+
"--path",
|
|
76
|
+
jsonPath,
|
|
77
|
+
"--remote",
|
|
78
|
+
"--config",
|
|
79
|
+
configPath
|
|
80
|
+
],
|
|
81
|
+
{ cwd }
|
|
82
|
+
);
|
|
83
|
+
},
|
|
84
|
+
async putValue({ cwd, configPath, key, value }) {
|
|
85
|
+
await execa(
|
|
86
|
+
"npx",
|
|
87
|
+
[
|
|
88
|
+
"wrangler",
|
|
89
|
+
"kv",
|
|
90
|
+
"key",
|
|
91
|
+
"put",
|
|
92
|
+
"--binding",
|
|
93
|
+
"KALP_MANIFESTS",
|
|
94
|
+
key,
|
|
95
|
+
value,
|
|
96
|
+
"--remote",
|
|
97
|
+
"--config",
|
|
98
|
+
configPath
|
|
99
|
+
],
|
|
100
|
+
{ cwd }
|
|
101
|
+
);
|
|
102
|
+
},
|
|
103
|
+
async getValue({ cwd, configPath, key }) {
|
|
104
|
+
const result = await execa(
|
|
105
|
+
"npx",
|
|
106
|
+
[
|
|
107
|
+
"wrangler",
|
|
108
|
+
"kv",
|
|
109
|
+
"key",
|
|
110
|
+
"get",
|
|
111
|
+
"--binding",
|
|
112
|
+
"KALP_MANIFESTS",
|
|
113
|
+
key,
|
|
114
|
+
"--remote",
|
|
115
|
+
"--config",
|
|
116
|
+
configPath
|
|
117
|
+
],
|
|
118
|
+
{ cwd }
|
|
119
|
+
).catch(() => null);
|
|
120
|
+
const output = result?.stdout?.trim();
|
|
121
|
+
return output ? output : null;
|
|
122
|
+
},
|
|
123
|
+
async listNamespaces({ cwd, configPath }) {
|
|
124
|
+
const json = await execa(
|
|
125
|
+
"npx",
|
|
126
|
+
["wrangler", "kv", "namespace", "list", "--config", configPath, "--json"],
|
|
127
|
+
{ cwd }
|
|
128
|
+
).catch(() => null);
|
|
129
|
+
if (json) return parseNamespaceList(json.stdout);
|
|
130
|
+
const plain = await execa(
|
|
131
|
+
"npx",
|
|
132
|
+
["wrangler", "kv", "namespace", "list", "--config", configPath],
|
|
133
|
+
{ cwd }
|
|
134
|
+
);
|
|
135
|
+
return parseNamespaceList(plain.stdout);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
// src/utils/providers/index.ts
|
|
140
|
+
function resolveProvider() {
|
|
141
|
+
return cloudflareProvider;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export {
|
|
145
|
+
resolveProvider
|
|
146
|
+
};
|
|
147
|
+
//# sourceMappingURL=chunk-MMR5WRLY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/providers/cloudflare.ts","../src/utils/providers/index.ts"],"sourcesContent":["import { execa } from \"execa\";\nimport { mkdtemp, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport type { RuntimeProvider } from \"@/utils/providers/types\";\nimport { getCloudflareIdentity } from \"@/utils/auth\";\n\nfunction parseNamespaceList(stdout: string): Array<{ id: string; title: string }> {\n try {\n const parsed = JSON.parse(stdout);\n if (Array.isArray(parsed)) {\n return parsed\n .map((item) => ({\n id: String((item as { id?: string }).id ?? \"\"),\n title: String((item as { title?: string }).title ?? \"\"),\n }))\n .filter((item) => !!item.id && !!item.title);\n }\n } catch {}\n return [];\n}\n\nfunction findWorkerUrl(output: string): string | null {\n const match = output.match(/https:\\/\\/[^\\s]+\\.workers\\.dev/);\n return match?.[0] ?? null;\n}\n\nexport const cloudflareProvider: RuntimeProvider = {\n name: \"cloudflare\",\n async login() {\n await execa(\"npx\", [\"wrangler\", \"login\"], { stdio: \"inherit\" });\n },\n async whoami() {\n const identity = await getCloudflareIdentity();\n const account = identity?.accounts?.[0];\n const accountId = account?.id ?? account?.account_tag;\n const email = identity?.email;\n if (!accountId || !email) return null;\n return { provider: \"cloudflare\", accountId, email };\n },\n async putSecret({ cwd, configPath, name, value }) {\n await execa(\n \"npx\",\n [\"wrangler\", \"secret\", \"put\", name, \"--config\", configPath],\n { cwd, input: `${value}\\n` },\n );\n },\n async deployRuntime({ cwd, configPath, useSecretsFile }) {\n const args = useSecretsFile\n ? [\"wrangler\", \"deploy\", \"--config\", configPath, \"--secrets-file\", \".env\"]\n : [\"wrangler\", \"deploy\", \"--config\", configPath];\n const deploy = await execa(\"npx\", args, { cwd });\n const rawOutput = [deploy.stdout, deploy.stderr].filter(Boolean).join(\"\\n\");\n const workerUrl = findWorkerUrl(rawOutput);\n if (!workerUrl) {\n const configText = await readFile(configPath, \"utf-8\").catch(() => null);\n const workerName = configText?.match(/\"name\"\\s*:\\s*\"([^\"]+)\"/)?.[1];\n if (!workerName) {\n throw new Error(\"Could not resolve runtime URL from deployment output.\");\n }\n return { workerUrl: `https://${workerName}.workers.dev`, rawOutput };\n }\n return { workerUrl, rawOutput };\n },\n async putManifest({ cwd, configPath, key, jsonPath }) {\n await execa(\n \"npx\",\n [\n \"wrangler\",\n \"kv\",\n \"key\",\n \"put\",\n \"--binding\",\n \"KALP_MANIFESTS\",\n key,\n \"--path\",\n jsonPath,\n \"--remote\",\n \"--config\",\n configPath,\n ],\n { cwd },\n );\n },\n async putValue({ cwd, configPath, key, value }) {\n await execa(\n \"npx\",\n [\n \"wrangler\",\n \"kv\",\n \"key\",\n \"put\",\n \"--binding\",\n \"KALP_MANIFESTS\",\n key,\n value,\n \"--remote\",\n \"--config\",\n configPath,\n ],\n { cwd },\n );\n },\n async getValue({ cwd, configPath, key }) {\n const result = await execa(\n \"npx\",\n [\n \"wrangler\",\n \"kv\",\n \"key\",\n \"get\",\n \"--binding\",\n \"KALP_MANIFESTS\",\n key,\n \"--remote\",\n \"--config\",\n configPath,\n ],\n { cwd },\n ).catch(() => null);\n const output = result?.stdout?.trim();\n return output ? output : null;\n },\n async listNamespaces({ cwd, configPath }) {\n const json = await execa(\n \"npx\",\n [\"wrangler\", \"kv\", \"namespace\", \"list\", \"--config\", configPath, \"--json\"],\n { cwd },\n ).catch(() => null);\n if (json) return parseNamespaceList(json.stdout);\n const plain = await execa(\n \"npx\",\n [\"wrangler\", \"kv\", \"namespace\", \"list\", \"--config\", configPath],\n { cwd },\n );\n return parseNamespaceList(plain.stdout);\n },\n};\n\nexport async function withTempJsonFile<T>(\n prefix: string,\n payload: unknown,\n fn: (path: string) => Promise<T>,\n): Promise<T> {\n const dir = await mkdtemp(join(tmpdir(), prefix));\n const filePath = join(dir, \"payload.json\");\n await writeFile(filePath, JSON.stringify(payload), \"utf-8\");\n try {\n return await fn(filePath);\n } finally {\n await rm(dir, { recursive: true, force: true });\n }\n}\n","import { cloudflareProvider } from \"@/utils/providers/cloudflare\";\nimport type { RuntimeProvider } from \"@/utils/providers/types\";\n\nexport function resolveProvider(): RuntimeProvider {\n return cloudflareProvider;\n}\n\nexport type { RuntimeProvider, ProviderIdentity, DeployResult } from \"@/utils/providers/types\";\n"],"mappings":"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","names":[]}
|
|
@@ -32,6 +32,11 @@ async function promptTemplateSelection() {
|
|
|
32
32
|
value: "blank",
|
|
33
33
|
label: "\u2B1C Blank",
|
|
34
34
|
hint: "Minimal structure with modern Kalp v1 syntax"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
value: "ops-revenue",
|
|
38
|
+
label: "\u{1F4C8} Revenue Ops",
|
|
39
|
+
hint: "Pipeline qualification + human handoff + event-driven orchestration"
|
|
35
40
|
}
|
|
36
41
|
]
|
|
37
42
|
});
|
|
@@ -75,7 +80,7 @@ async function promptAgentDetails(opts) {
|
|
|
75
80
|
);
|
|
76
81
|
return {
|
|
77
82
|
name: answers.name,
|
|
78
|
-
label: answers.label,
|
|
83
|
+
label: String(answers.label),
|
|
79
84
|
template: answers.template
|
|
80
85
|
};
|
|
81
86
|
}
|
|
@@ -138,4 +143,4 @@ var create_default = defineCommand({
|
|
|
138
143
|
export {
|
|
139
144
|
create_default as default
|
|
140
145
|
};
|
|
141
|
-
//# sourceMappingURL=create-
|
|
146
|
+
//# sourceMappingURL=create-XC55BUCS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/create.ts","../src/utils/ui.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { scaffoldAgent } from \"@kalphq/project\";\nimport { isProjectInitialized } from \"@/utils/fs\";\nimport { promptAgentDetails } from \"@/utils/ui\";\n\nconst LOGO = \"🦋\";\n\nexport default defineCommand({\n meta: { name: \"create\", description: \"Add a new agent to the project\" },\n async run() {\n const cwd = process.cwd();\n\n p.intro(`${LOGO} ${pc.bold(\"kalp create\")}`);\n\n // ── Check if project is initialized ─────────────────────────────────\n const needsInit = !(await isProjectInitialized(cwd));\n\n if (needsInit) {\n p.log.error(\"This is not a Kalp project.\");\n console.log(\"\");\n console.log(\" Run:\");\n console.log(` ${pc.cyan(\"npx create-kalp@latest\")}`);\n console.log(\"\");\n process.exit(1);\n }\n\n // ── Agent prompts ────────────────────────────────────────────────────\n const agentAnswers = await promptAgentDetails({ includeTemplate: true });\n\n // ── Check if agent already exists ────────────────────────────────────\n const agentDir = join(cwd, \"agents\", agentAnswers.name);\n if (existsSync(agentDir)) {\n p.log.error(`Agent \"${agentAnswers.name}\" already exists.`);\n console.log(\"\");\n console.log(` ${pc.dim(\"Location:\")} ${pc.cyan(agentDir)}`);\n console.log(\"\");\n console.log(\n ` ${pc.dim(\"Choose a different name or remove the existing agent.\")}`,\n );\n process.exit(1);\n }\n\n const s = p.spinner();\n\n // ── Scaffold agent ───────────────────────────────────────────────────\n s.start(`Scaffolding agent ${pc.cyan(agentAnswers.name)}`);\n await scaffoldAgent({\n agentName: agentAnswers.name,\n label: agentAnswers.label,\n cwd,\n template: agentAnswers.template,\n });\n s.stop(\n agentAnswers.template\n ? `Agent created (${agentAnswers.template} template)`\n : \"Agent created\",\n );\n\n p.note(\n [\n `${pc.dim(\"•\")} ${pc.cyan(`agents/${agentAnswers.name}/index.ts`)} ${pc.dim(\"— Agent entrypoint with config\")}`,\n `${pc.dim(\"•\")} ${pc.cyan(`agents/${agentAnswers.name}/contract/`)} ${pc.dim(\"— RPC contract definition\")}`,\n `${pc.dim(\"•\")} ${pc.cyan(`agents/${agentAnswers.name}/hooks/`)} ${pc.dim(\"— Lifecycle hooks (onInit, onTick)\")}`,\n `${pc.dim(\"•\")} ${pc.cyan(`agents/${agentAnswers.name}/routes/`)} ${pc.dim(\"— HTTP endpoints\")}`,\n `${pc.dim(\"•\")} ${pc.cyan(`agents/${agentAnswers.name}/steps/`)} ${pc.dim(\"— Reusable workflow steps\")}`,\n `${pc.dim(\"•\")} ${pc.cyan(`agents/${agentAnswers.name}/tools/`)} ${pc.dim(\"— Callable agent tools\")}`,\n ].join(\"\\n\"),\n \"Created\",\n );\n\n p.outro(\n `${LOGO} ${pc.green(`Agent ${pc.bold(agentAnswers.name)} is ready.`)}`,\n );\n },\n});\n","import * as p from \"@clack/prompts\";\nimport { deriveLabelFromName, type TemplateId } from \"@kalphq/project\";\n\n/**\n * Prompt user to select an agent template.\n */\nexport async function promptTemplateSelection(): Promise<TemplateId> {\n const answer = await p.select({\n message: \"Choose an agent template:\",\n options: [\n {\n value: \"researcher\",\n label: \"🔬 Researcher\",\n hint: \"Deterministic scheduling - pause 24h and auto-resume\",\n },\n {\n value: \"support\",\n label: \"🎧 Support Agent\",\n hint: \"Human-in-the-Loop - pause for days until resolved\",\n },\n {\n value: \"blank\",\n label: \"⬜ Blank\",\n hint: \"Minimal structure with modern Kalp v1 syntax\",\n },\n {\n value: \"ops-revenue\",\n label: \"📈 Revenue Ops\",\n hint: \"Pipeline qualification + human handoff + event-driven orchestration\",\n },\n ],\n });\n\n if (p.isCancel(answer)) {\n p.cancel(\"Cancelled.\");\n process.exit(0);\n }\n\n return answer as TemplateId;\n}\n\nexport async function promptProjectName(opts?: {\n message?: string;\n placeholder?: string;\n allowCurrentDir?: boolean;\n}): Promise<string> {\n const message = opts?.message ?? \"Project name?\";\n const placeholder = opts?.placeholder ?? \"my-project\";\n const allowCurrentDir = opts?.allowCurrentDir ?? false;\n\n const answer = await p.text({\n message,\n placeholder,\n validate: (v) => {\n const value = v.trim();\n if (!value) return \"Project name is required.\";\n if (allowCurrentDir && value === \".\") return;\n if (!/^[a-z0-9-]+$/.test(value)) {\n return allowCurrentDir\n ? \"Use lowercase letters, numbers, and dashes only (or . for current directory).\"\n : \"Use lowercase letters, numbers, and dashes only.\";\n }\n },\n });\n\n if (p.isCancel(answer)) {\n p.cancel(\"Cancelled.\");\n process.exit(0);\n }\n\n return answer.trim();\n}\n\nexport async function promptAgentDetails(opts?: {\n includeTemplate?: boolean;\n}): Promise<{\n name: string;\n label: string;\n template?: TemplateId;\n}> {\n const answers = await p.group(\n {\n name: () =>\n p.text({\n message: \"Agent name?\",\n placeholder: \"my-agent\",\n validate: (v) => {\n if (!v.trim()) return \"Agent name is required.\";\n if (!/^[a-z0-9-]+$/.test(v)) {\n return \"Use lowercase letters, numbers, and dashes only.\";\n }\n },\n }),\n ...(opts?.includeTemplate && {\n template: () => promptTemplateSelection(),\n }),\n label: ({ results }) =>\n p.text({\n message: \"Agent label? (display name)\",\n placeholder: deriveLabelFromName(results.name as string),\n initialValue: deriveLabelFromName(results.name as string),\n validate: (v) => {\n if (!v.trim()) return \"Agent label is required.\";\n },\n }),\n },\n {\n onCancel: () => {\n p.cancel(\"Cancelled.\");\n process.exit(0);\n },\n },\n );\n\n return {\n name: answers.name,\n label: String(answers.label),\n template: answers.template as TemplateId | undefined,\n };\n}\n"],"mappings":"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","names":["p"]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runInitialDeploy
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-5QU2DXPC.js";
|
|
5
|
+
import "./chunk-MMR5WRLY.js";
|
|
5
6
|
import "./chunk-5AEWO2OC.js";
|
|
6
7
|
import {
|
|
7
8
|
requireAuth
|
|
@@ -14,7 +15,7 @@ import * as p from "@clack/prompts";
|
|
|
14
15
|
import pc from "picocolors";
|
|
15
16
|
var LOGO = "\u{1F98B}";
|
|
16
17
|
var deploy_default = defineCommand({
|
|
17
|
-
meta: { name: "deploy", description: "Deploy
|
|
18
|
+
meta: { name: "deploy", description: "Deploy your agents runtime" },
|
|
18
19
|
async run() {
|
|
19
20
|
const cwd = process.cwd();
|
|
20
21
|
p.intro(`${LOGO} ${pc.bold("kalp deploy")}`);
|
|
@@ -22,32 +23,21 @@ var deploy_default = defineCommand({
|
|
|
22
23
|
p.log.error("Not authenticated. Run `kalp login` first.");
|
|
23
24
|
process.exit(1);
|
|
24
25
|
});
|
|
25
|
-
const
|
|
26
|
-
message: "
|
|
27
|
-
|
|
28
|
-
{ label: "Cloudflare (Recommended)", value: "cloudflare" },
|
|
29
|
-
{ label: "Kalp Cloud (Coming soon)", value: "kalp-cloud" }
|
|
30
|
-
]
|
|
26
|
+
const proceed = await p.confirm({
|
|
27
|
+
message: "Deploy your runtime now?",
|
|
28
|
+
initialValue: true
|
|
31
29
|
});
|
|
32
|
-
if (p.isCancel(
|
|
30
|
+
if (p.isCancel(proceed) || !proceed) {
|
|
33
31
|
p.outro("Cancelled");
|
|
34
32
|
return;
|
|
35
33
|
}
|
|
36
|
-
if (target === "kalp-cloud") {
|
|
37
|
-
p.note(
|
|
38
|
-
"Coming soon. Enterprise cloud execution is currently waitlisted.",
|
|
39
|
-
"Kalp Cloud"
|
|
40
|
-
);
|
|
41
|
-
p.outro(pc.dim("No deployment executed."));
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
34
|
const s = p.spinner();
|
|
45
|
-
s.start("Deploying
|
|
35
|
+
s.start("Deploying your agents runtime");
|
|
46
36
|
try {
|
|
47
37
|
const result = await runInitialDeploy(cwd);
|
|
48
38
|
s.stop("Deployment completed");
|
|
49
|
-
p.log.success(`
|
|
50
|
-
p.outro(pc.green("
|
|
39
|
+
p.log.success(`Runtime URL: ${pc.cyan(result.workerUrl)}`);
|
|
40
|
+
p.outro(pc.green("Your runtime is ready"));
|
|
51
41
|
} catch (error) {
|
|
52
42
|
s.stop("Deployment failed");
|
|
53
43
|
p.log.error(
|
|
@@ -60,4 +50,4 @@ var deploy_default = defineCommand({
|
|
|
60
50
|
export {
|
|
61
51
|
deploy_default as default
|
|
62
52
|
};
|
|
63
|
-
//# sourceMappingURL=deploy-
|
|
53
|
+
//# sourceMappingURL=deploy-MJLWDGOT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/deploy.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { requireAuth } from \"@/utils/auth\";\nimport { runInitialDeploy } from \"@/utils/deploy\";\n\nconst LOGO = \"🦋\";\n\nexport default defineCommand({\n meta: { name: \"deploy\", description: \"Deploy your agents runtime\" },\n async run() {\n const cwd = process.cwd();\n\n p.intro(`${LOGO} ${pc.bold(\"kalp deploy\")}`);\n\n await requireAuth().catch(() => {\n p.log.error(\"Not authenticated. Run `kalp login` first.\");\n process.exit(1);\n });\n\n const proceed = await p.confirm({\n message: \"Deploy your runtime now?\",\n initialValue: true,\n });\n if (p.isCancel(proceed) || !proceed) {\n p.outro(\"Cancelled\");\n return;\n }\n\n const s = p.spinner();\n s.start(\"Deploying your agents runtime\");\n\n try {\n const result = await runInitialDeploy(cwd);\n s.stop(\"Deployment completed\");\n p.log.success(`Runtime URL: ${pc.cyan(result.workerUrl)}`);\n p.outro(pc.green(\"Your runtime is ready\"));\n } catch (error) {\n s.stop(\"Deployment failed\");\n p.log.error(\n error instanceof Error ? error.message : \"Unknown deployment error\",\n );\n process.exit(1);\n }\n },\n});\n"],"mappings":";;;;;;;;;;;;AAAA,SAAS,qBAAqB;AAC9B,YAAY,OAAO;AACnB,OAAO,QAAQ;AAIf,IAAM,OAAO;AAEb,IAAO,iBAAQ,cAAc;AAAA,EAC3B,MAAM,EAAE,MAAM,UAAU,aAAa,6BAA6B;AAAA,EAClE,MAAM,MAAM;AACV,UAAM,MAAM,QAAQ,IAAI;AAExB,IAAE,QAAM,GAAG,IAAI,IAAI,GAAG,KAAK,aAAa,CAAC,EAAE;AAE3C,UAAM,YAAY,EAAE,MAAM,MAAM;AAC9B,MAAE,MAAI,MAAM,4CAA4C;AACxD,cAAQ,KAAK,CAAC;AAAA,IAChB,CAAC;AAED,UAAM,UAAU,MAAQ,UAAQ;AAAA,MAC9B,SAAS;AAAA,MACT,cAAc;AAAA,IAChB,CAAC;AACD,QAAM,WAAS,OAAO,KAAK,CAAC,SAAS;AACnC,MAAE,QAAM,WAAW;AACnB;AAAA,IACF;AAEA,UAAM,IAAM,UAAQ;AACpB,MAAE,MAAM,+BAA+B;AAEvC,QAAI;AACF,YAAM,SAAS,MAAM,iBAAiB,GAAG;AACzC,QAAE,KAAK,sBAAsB;AAC7B,MAAE,MAAI,QAAQ,gBAAgB,GAAG,KAAK,OAAO,SAAS,CAAC,EAAE;AACzD,MAAE,QAAM,GAAG,MAAM,uBAAuB,CAAC;AAAA,IAC3C,SAAS,OAAO;AACd,QAAE,KAAK,mBAAmB;AAC1B,MAAE,MAAI;AAAA,QACJ,iBAAiB,QAAQ,MAAM,UAAU;AAAA,MAC3C;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AACF,CAAC;","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import pc from "picocolors";
|
|
|
8
8
|
// package.json
|
|
9
9
|
var package_default = {
|
|
10
10
|
name: "@kalphq/cli",
|
|
11
|
-
version: "0.0.0-dev-
|
|
11
|
+
version: "0.0.0-dev-20260512061708",
|
|
12
12
|
description: "Zero-config CLI for deploying Kalp agents",
|
|
13
13
|
type: "module",
|
|
14
14
|
license: "MIT",
|
|
@@ -59,11 +59,11 @@ var package_default = {
|
|
|
59
59
|
var LOGO = "\u{1F98B}";
|
|
60
60
|
var COMMANDS = [
|
|
61
61
|
["create", "Add a new agent"],
|
|
62
|
-
["deploy", "Deploy
|
|
63
|
-
["push", "
|
|
62
|
+
["deploy", "Deploy your agents runtime"],
|
|
63
|
+
["push", "Publish agent runtime version"],
|
|
64
64
|
["link", "Link project to Kalp cloud"],
|
|
65
65
|
["secrets", "Manage secrets"],
|
|
66
|
-
["login", "
|
|
66
|
+
["login", "Sign in to remote runtime"],
|
|
67
67
|
["logout", "Sign out from Kalp"],
|
|
68
68
|
["dev", "Run Worker + Studio locally"]
|
|
69
69
|
];
|
|
@@ -92,12 +92,12 @@ var main = defineCommand({
|
|
|
92
92
|
}
|
|
93
93
|
},
|
|
94
94
|
subCommands: {
|
|
95
|
-
create: () => import("./create-
|
|
96
|
-
deploy: () => import("./deploy-
|
|
97
|
-
push: () => import("./push-
|
|
95
|
+
create: () => import("./create-XC55BUCS.js").then((r) => r.default),
|
|
96
|
+
deploy: () => import("./deploy-MJLWDGOT.js").then((r) => r.default),
|
|
97
|
+
push: () => import("./push-RNJ7PQUW.js").then((r) => r.default),
|
|
98
98
|
link: () => import("./link-WZQSR2TM.js").then((r) => r.default),
|
|
99
99
|
secrets: () => import("./secrets-P7ADVLOS.js").then((r) => r.default),
|
|
100
|
-
login: () => import("./login-
|
|
100
|
+
login: () => import("./login-72Q2FQZR.js").then((r) => r.default),
|
|
101
101
|
logout: () => import("./logout-U5V5K775.js").then((r) => r.default),
|
|
102
102
|
dev: () => import("./dev-AHTXYEF2.js").then((r) => r.default)
|
|
103
103
|
},
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../package.json"],"sourcesContent":["import { defineCommand, runMain } from \"citty\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport pkg from \"../package.json\";\n\nconst LOGO = \"🦋\";\n\nconst COMMANDS = [\n [\"create\", \"Add a new agent\"],\n [\"deploy\", \"Deploy
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../package.json"],"sourcesContent":["import { defineCommand, runMain } from \"citty\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport pkg from \"../package.json\";\n\nconst LOGO = \"🦋\";\n\nconst COMMANDS = [\n [\"create\", \"Add a new agent\"],\n [\"deploy\", \"Deploy your agents runtime\"],\n [\"push\", \"Publish agent runtime version\"],\n [\"link\", \"Link project to Kalp cloud\"],\n [\"secrets\", \"Manage secrets\"],\n [\"login\", \"Sign in to remote runtime\"],\n [\"logout\", \"Sign out from Kalp\"],\n [\"dev\", \"Run Worker + Studio locally\"],\n] as const;\n\nfunction printHelp(): void {\n p.log.info(`${pc.bold(\"Usage\")}: kalp <command> [options]`);\n console.log(\"\");\n p.log.info(pc.bold(\"Commands\"));\n\n for (const [name, desc] of COMMANDS) {\n console.log(` ${pc.cyan(name.padEnd(10))}${desc}`);\n }\n\n console.log(\"\");\n p.log.info(`Run ${pc.cyan(\"kalp <command> --help\")} for more info.`);\n}\n\nconst main = defineCommand({\n meta: {\n name: \"kalp\",\n version: pkg.version,\n description: \"🦋 Zero-config agent infrastructure\",\n },\n args: {\n help: {\n type: \"boolean\",\n alias: \"h\",\n description: \"Show help\",\n default: false,\n },\n },\n subCommands: {\n create: () => import(\"./commands/create\").then((r) => r.default),\n deploy: () => import(\"./commands/deploy\").then((r) => r.default),\n push: () => import(\"./commands/push\").then((r) => r.default),\n link: () => import(\"./commands/link\").then((r) => r.default),\n secrets: () => import(\"./commands/secrets\").then((r) => r.default),\n login: () => import(\"./commands/login\").then((r) => r.default),\n logout: () => import(\"./commands/logout\").then((r) => r.default),\n dev: () => import(\"./commands/dev\").then((r) => r.default),\n },\n run({ args }) {\n const firstArg = process.argv[2];\n\n if (args.help) {\n p.intro(`${LOGO} ${pc.bold(\"kalp\")}`);\n printHelp();\n p.outro(\"Happy coding 🦋\");\n return;\n }\n\n if (firstArg) {\n return;\n }\n\n p.intro(`${LOGO} ${pc.bold(\"kalp\")}`);\n printHelp();\n p.outro(\"Happy coding 🦋\");\n },\n});\n\nrunMain(main);\n","{\n \"name\": \"@kalphq/cli\",\n \"version\": \"0.0.0-dev-20260512061708\",\n \"description\": \"Zero-config CLI for deploying Kalp agents\",\n \"type\": \"module\",\n \"license\": \"MIT\",\n \"author\": \"Kalp HQ\",\n \"bin\": {\n \"kalp\": \"./dist/index.js\"\n },\n \"main\": \"./dist/index.js\",\n \"files\": [\n \"dist\"\n ],\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"scripts\": {\n \"build\": \"tsup && pnpm run build:studio && pnpm run build:runtime-template\",\n \"build:studio\": \"pnpm --filter=@kalphq/studio build\",\n \"build:runtime-template\": \"node ./scripts/prepare-runtime-template.mjs\",\n \"dev\": \"tsup --watch\",\n \"lint\": \"tsc --noEmit\",\n \"prepublishOnly\": \"pnpm build\"\n },\n \"dependencies\": {\n \"@antfu/ni\": \"24.4.0\",\n \"@clack/prompts\": \"0.9.1\",\n \"@kalphq/compiler\": \"workspace:*\",\n \"@kalphq/project\": \"workspace:*\",\n \"@kalphq/sdk\": \"workspace:*\",\n \"citty\": \"0.1.6\",\n \"esbuild\": \"0.25.0\",\n \"execa\": \"^9.6.1\",\n \"jiti\": \"^2.6.1\",\n \"jose\": \"^5.10.0\",\n \"json-stable-stringify\": \"1.3.0\",\n \"open\": \"^11.0.0\",\n \"picocolors\": \"1.1.1\",\n \"zod\": \"3.25.76\"\n },\n \"devDependencies\": {\n \"@types/json-stable-stringify\": \"1.2.0\",\n \"@types/node\": \"^22.15.3\",\n \"tsup\": \"^8.3.5\",\n \"typescript\": \"^5.0.0\"\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
resolveProvider
|
|
4
|
+
} from "./chunk-MMR5WRLY.js";
|
|
5
|
+
import {
|
|
6
|
+
saveAuthConfig
|
|
7
|
+
} from "./chunk-5RODADXW.js";
|
|
8
|
+
import "./chunk-FO24J6XL.js";
|
|
9
|
+
|
|
10
|
+
// src/commands/login.ts
|
|
11
|
+
import { defineCommand } from "citty";
|
|
12
|
+
import * as p from "@clack/prompts";
|
|
13
|
+
import pc from "picocolors";
|
|
14
|
+
var LOGO = "\u{1F98B}";
|
|
15
|
+
var login_default = defineCommand({
|
|
16
|
+
meta: { name: "login", description: "Sign in to remote runtime" },
|
|
17
|
+
async run() {
|
|
18
|
+
p.intro(`${LOGO} ${pc.bold("kalp login")}`);
|
|
19
|
+
const provider = resolveProvider();
|
|
20
|
+
const proceed = await p.confirm({
|
|
21
|
+
message: "Sign in to remote runtime now?",
|
|
22
|
+
initialValue: true
|
|
23
|
+
});
|
|
24
|
+
if (p.isCancel(proceed) || !proceed) {
|
|
25
|
+
p.outro("Cancelled");
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const s = p.spinner();
|
|
29
|
+
s.start("Opening sign-in flow");
|
|
30
|
+
try {
|
|
31
|
+
await provider.login();
|
|
32
|
+
} catch {
|
|
33
|
+
s.stop(pc.red("Sign-in failed"));
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
s.stop("Sign-in complete");
|
|
37
|
+
s.start("Reading runtime identity");
|
|
38
|
+
const identity = await provider.whoami();
|
|
39
|
+
const accountId = identity?.accountId;
|
|
40
|
+
const email = identity?.email;
|
|
41
|
+
if (!accountId || !email) {
|
|
42
|
+
s.stop(pc.red("Could not resolve account identity from wrangler whoami"));
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
const authConfig = {
|
|
46
|
+
provider: "cloudflare",
|
|
47
|
+
accountId,
|
|
48
|
+
email,
|
|
49
|
+
expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1e3).toISOString()
|
|
50
|
+
};
|
|
51
|
+
await saveAuthConfig(authConfig);
|
|
52
|
+
s.stop("Authentication saved");
|
|
53
|
+
p.log.success(`Logged in as ${pc.cyan(authConfig.email)}`);
|
|
54
|
+
p.note(`Workspace ID: ${pc.cyan(authConfig.accountId)}`, "Runtime");
|
|
55
|
+
p.outro(pc.green("Ready to deploy your agents"));
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
export {
|
|
59
|
+
login_default as default
|
|
60
|
+
};
|
|
61
|
+
//# sourceMappingURL=login-72Q2FQZR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/login.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport {\n saveAuthConfig,\n type AuthConfig,\n} from \"@/utils/auth\";\nimport { resolveProvider } from \"@/utils/providers\";\n\nconst LOGO = \"🦋\";\n\nexport default defineCommand({\n meta: { name: \"login\", description: \"Sign in to remote runtime\" },\n async run() {\n p.intro(`${LOGO} ${pc.bold(\"kalp login\")}`);\n\n const provider = resolveProvider();\n const proceed = await p.confirm({\n message: \"Sign in to remote runtime now?\",\n initialValue: true,\n });\n if (p.isCancel(proceed) || !proceed) {\n p.outro(\"Cancelled\");\n return;\n }\n\n const s = p.spinner();\n s.start(\"Opening sign-in flow\");\n\n try {\n await provider.login();\n } catch {\n s.stop(pc.red(\"Sign-in failed\"));\n process.exit(1);\n }\n\n s.stop(\"Sign-in complete\");\n s.start(\"Reading runtime identity\");\n const identity = await provider.whoami();\n const accountId = identity?.accountId;\n const email = identity?.email;\n\n if (!accountId || !email) {\n s.stop(pc.red(\"Could not resolve account identity from wrangler whoami\"));\n process.exit(1);\n }\n\n const authConfig: AuthConfig = {\n provider: \"cloudflare\",\n accountId,\n email,\n expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(),\n };\n\n await saveAuthConfig(authConfig);\n\n s.stop(\"Authentication saved\");\n p.log.success(`Logged in as ${pc.cyan(authConfig.email)}`);\n p.note(`Workspace ID: ${pc.cyan(authConfig.accountId)}`, \"Runtime\");\n p.outro(pc.green(\"Ready to deploy your agents\"));\n },\n});\n"],"mappings":";;;;;;;;;;AAAA,SAAS,qBAAqB;AAC9B,YAAY,OAAO;AACnB,OAAO,QAAQ;AAOf,IAAM,OAAO;AAEb,IAAO,gBAAQ,cAAc;AAAA,EAC3B,MAAM,EAAE,MAAM,SAAS,aAAa,4BAA4B;AAAA,EAChE,MAAM,MAAM;AACV,IAAE,QAAM,GAAG,IAAI,IAAI,GAAG,KAAK,YAAY,CAAC,EAAE;AAE1C,UAAM,WAAW,gBAAgB;AACjC,UAAM,UAAU,MAAQ,UAAQ;AAAA,MAC9B,SAAS;AAAA,MACT,cAAc;AAAA,IAChB,CAAC;AACD,QAAM,WAAS,OAAO,KAAK,CAAC,SAAS;AACnC,MAAE,QAAM,WAAW;AACnB;AAAA,IACF;AAEA,UAAM,IAAM,UAAQ;AACpB,MAAE,MAAM,sBAAsB;AAE9B,QAAI;AACF,YAAM,SAAS,MAAM;AAAA,IACvB,QAAQ;AACN,QAAE,KAAK,GAAG,IAAI,gBAAgB,CAAC;AAC/B,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,MAAE,KAAK,kBAAkB;AACzB,MAAE,MAAM,0BAA0B;AAClC,UAAM,WAAW,MAAM,SAAS,OAAO;AACvC,UAAM,YAAY,UAAU;AAC5B,UAAM,QAAQ,UAAU;AAExB,QAAI,CAAC,aAAa,CAAC,OAAO;AACxB,QAAE,KAAK,GAAG,IAAI,yDAAyD,CAAC;AACxE,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,aAAyB;AAAA,MAC7B,UAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA,WAAW,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,KAAK,GAAI,EAAE,YAAY;AAAA,IACzE;AAEA,UAAM,eAAe,UAAU;AAE/B,MAAE,KAAK,sBAAsB;AAC7B,IAAE,MAAI,QAAQ,gBAAgB,GAAG,KAAK,WAAW,KAAK,CAAC,EAAE;AACzD,IAAE,OAAK,iBAAiB,GAAG,KAAK,WAAW,SAAS,CAAC,IAAI,SAAS;AAClE,IAAE,QAAM,GAAG,MAAM,6BAA6B,CAAC;AAAA,EACjD;AACF,CAAC;","names":[]}
|
|
@@ -4,7 +4,10 @@ import {
|
|
|
4
4
|
} from "./chunk-INB3LG6O.js";
|
|
5
5
|
import {
|
|
6
6
|
runInitialDeploy
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-5QU2DXPC.js";
|
|
8
|
+
import {
|
|
9
|
+
resolveProvider
|
|
10
|
+
} from "./chunk-MMR5WRLY.js";
|
|
8
11
|
import {
|
|
9
12
|
materializeRuntime,
|
|
10
13
|
readLocalAgentNames,
|
|
@@ -17,12 +20,11 @@ import {
|
|
|
17
20
|
import "./chunk-FO24J6XL.js";
|
|
18
21
|
|
|
19
22
|
// src/commands/push.ts
|
|
20
|
-
import { access as access2, mkdir, rm as rm2, writeFile } from "fs/promises";
|
|
21
|
-
import { join as
|
|
23
|
+
import { access as access2, mkdir as mkdir2, rm as rm2, writeFile as writeFile2 } from "fs/promises";
|
|
24
|
+
import { join as join3 } from "path";
|
|
22
25
|
import { defineCommand } from "citty";
|
|
23
26
|
import * as p from "@clack/prompts";
|
|
24
27
|
import pc from "picocolors";
|
|
25
|
-
import { execa } from "execa";
|
|
26
28
|
|
|
27
29
|
// src/utils/manifest/index.ts
|
|
28
30
|
import { access, readFile, rm, mkdtemp } from "fs/promises";
|
|
@@ -121,6 +123,19 @@ function validateCompiledIR(input) {
|
|
|
121
123
|
return { ok: true, analysis };
|
|
122
124
|
}
|
|
123
125
|
|
|
126
|
+
// src/utils/ir/export.ts
|
|
127
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
128
|
+
import { join as join2 } from "path";
|
|
129
|
+
async function exportCompiledIrForDebug(params) {
|
|
130
|
+
const { cwd, agentName, ir } = params;
|
|
131
|
+
const outDir = join2(cwd, ".kalp", "exports", agentName);
|
|
132
|
+
await mkdir(outDir, { recursive: true });
|
|
133
|
+
const outputPath = join2(outDir, "ir.json");
|
|
134
|
+
await writeFile(outputPath, `${JSON.stringify(ir, null, 2)}
|
|
135
|
+
`, "utf-8");
|
|
136
|
+
return outputPath;
|
|
137
|
+
}
|
|
138
|
+
|
|
124
139
|
// src/commands/push.ts
|
|
125
140
|
var LOGO = "\u{1F98B}";
|
|
126
141
|
function formatBytes(bytes) {
|
|
@@ -154,25 +169,15 @@ function ensureAgentState(state, agentName, localPath) {
|
|
|
154
169
|
return created;
|
|
155
170
|
}
|
|
156
171
|
async function readRemoteAgentsIndex(cwd, wranglerConfigPath) {
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
"--binding",
|
|
165
|
-
"KALP_MANIFESTS",
|
|
166
|
-
"agents:index",
|
|
167
|
-
"--remote",
|
|
168
|
-
"--config",
|
|
169
|
-
wranglerConfigPath
|
|
170
|
-
],
|
|
171
|
-
{ cwd }
|
|
172
|
-
).catch(() => null);
|
|
173
|
-
if (!result?.stdout?.trim()) return [];
|
|
172
|
+
const provider = resolveProvider();
|
|
173
|
+
const output = await provider.getValue({
|
|
174
|
+
cwd,
|
|
175
|
+
configPath: wranglerConfigPath,
|
|
176
|
+
key: "agents:index"
|
|
177
|
+
});
|
|
178
|
+
if (!output) return [];
|
|
174
179
|
try {
|
|
175
|
-
const parsed = JSON.parse(
|
|
180
|
+
const parsed = JSON.parse(output);
|
|
176
181
|
if (!Array.isArray(parsed)) return [];
|
|
177
182
|
return parsed;
|
|
178
183
|
} catch {
|
|
@@ -180,27 +185,16 @@ async function readRemoteAgentsIndex(cwd, wranglerConfigPath) {
|
|
|
180
185
|
}
|
|
181
186
|
}
|
|
182
187
|
async function writeRemoteAgentsIndex(cwd, wranglerConfigPath, entries) {
|
|
183
|
-
const path =
|
|
184
|
-
await
|
|
188
|
+
const path = join3(cwd, ".kalp", "agents-index.json");
|
|
189
|
+
await writeFile2(path, JSON.stringify(entries, null, 2), "utf-8");
|
|
190
|
+
const provider = resolveProvider();
|
|
185
191
|
try {
|
|
186
|
-
await
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
"put",
|
|
193
|
-
"--binding",
|
|
194
|
-
"KALP_MANIFESTS",
|
|
195
|
-
"agents:index",
|
|
196
|
-
"--path",
|
|
197
|
-
path,
|
|
198
|
-
"--remote",
|
|
199
|
-
"--config",
|
|
200
|
-
wranglerConfigPath
|
|
201
|
-
],
|
|
202
|
-
{ cwd }
|
|
203
|
-
);
|
|
192
|
+
await provider.putManifest({
|
|
193
|
+
cwd,
|
|
194
|
+
configPath: wranglerConfigPath,
|
|
195
|
+
key: "agents:index",
|
|
196
|
+
jsonPath: path
|
|
197
|
+
});
|
|
204
198
|
} finally {
|
|
205
199
|
await rm2(path, { force: true });
|
|
206
200
|
}
|
|
@@ -209,51 +203,29 @@ async function pushRemoteManifest(params) {
|
|
|
209
203
|
const { cwd, wranglerConfigPath, agentName, hash, ir } = params;
|
|
210
204
|
const manifestKey = `${agentName}:${hash}`;
|
|
211
205
|
const latestKey = `${agentName}:latest`;
|
|
212
|
-
const manifestPath =
|
|
213
|
-
await
|
|
214
|
-
await
|
|
206
|
+
const manifestPath = join3(cwd, ".kalp", `${agentName}-${hash}.json`);
|
|
207
|
+
await mkdir2(join3(cwd, ".kalp"), { recursive: true });
|
|
208
|
+
await writeFile2(manifestPath, JSON.stringify(ir), "utf-8");
|
|
209
|
+
const provider = resolveProvider();
|
|
215
210
|
try {
|
|
216
|
-
await
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
"--remote",
|
|
229
|
-
"--config",
|
|
230
|
-
wranglerConfigPath
|
|
231
|
-
],
|
|
232
|
-
{ cwd }
|
|
233
|
-
);
|
|
234
|
-
await execa(
|
|
235
|
-
"npx",
|
|
236
|
-
[
|
|
237
|
-
"wrangler",
|
|
238
|
-
"kv",
|
|
239
|
-
"key",
|
|
240
|
-
"put",
|
|
241
|
-
"--binding",
|
|
242
|
-
"KALP_MANIFESTS",
|
|
243
|
-
latestKey,
|
|
244
|
-
hash,
|
|
245
|
-
"--remote",
|
|
246
|
-
"--config",
|
|
247
|
-
wranglerConfigPath
|
|
248
|
-
],
|
|
249
|
-
{ cwd }
|
|
250
|
-
);
|
|
211
|
+
await provider.putManifest({
|
|
212
|
+
cwd,
|
|
213
|
+
configPath: wranglerConfigPath,
|
|
214
|
+
key: manifestKey,
|
|
215
|
+
jsonPath: manifestPath
|
|
216
|
+
});
|
|
217
|
+
await provider.putValue({
|
|
218
|
+
cwd,
|
|
219
|
+
configPath: wranglerConfigPath,
|
|
220
|
+
key: latestKey,
|
|
221
|
+
value: hash
|
|
222
|
+
});
|
|
251
223
|
} finally {
|
|
252
224
|
await rm2(manifestPath, { force: true });
|
|
253
225
|
}
|
|
254
226
|
}
|
|
255
227
|
var push_default = defineCommand({
|
|
256
|
-
meta: { name: "push", description: "
|
|
228
|
+
meta: { name: "push", description: "Publish agent runtime version" },
|
|
257
229
|
args: {
|
|
258
230
|
agent: {
|
|
259
231
|
type: "string",
|
|
@@ -312,7 +284,7 @@ var push_default = defineCommand({
|
|
|
312
284
|
const result = { pushed: 0, skipped: 0, failed: 0 };
|
|
313
285
|
const failures = [];
|
|
314
286
|
for (const agentName of selectedAgents) {
|
|
315
|
-
const agentPath =
|
|
287
|
+
const agentPath = join3(cwd, "agents", agentName, "index.ts");
|
|
316
288
|
await access2(agentPath).catch(() => {
|
|
317
289
|
failures.push(`${agentName}: missing ${agentPath}`);
|
|
318
290
|
});
|
|
@@ -335,7 +307,7 @@ var push_default = defineCommand({
|
|
|
335
307
|
continue;
|
|
336
308
|
}
|
|
337
309
|
if (target === "remote") {
|
|
338
|
-
spinner2.message("
|
|
310
|
+
spinner2.message("Publishing runtime version");
|
|
339
311
|
await pushRemoteManifest({
|
|
340
312
|
cwd,
|
|
341
313
|
wranglerConfigPath: runtime.wranglerConfigPath,
|
|
@@ -374,6 +346,11 @@ var push_default = defineCommand({
|
|
|
374
346
|
await writeRemoteAgentsIndex(cwd, runtime.wranglerConfigPath, merged);
|
|
375
347
|
}
|
|
376
348
|
const bundles = manifest.ir.bundles || {};
|
|
349
|
+
await exportCompiledIrForDebug({
|
|
350
|
+
cwd,
|
|
351
|
+
agentName,
|
|
352
|
+
ir: manifest.ir
|
|
353
|
+
});
|
|
377
354
|
const totalSize = Object.values(bundles).reduce(
|
|
378
355
|
(sum, bundle) => sum + Buffer.byteLength(bundle.code),
|
|
379
356
|
0
|
|
@@ -399,7 +376,7 @@ var push_default = defineCommand({
|
|
|
399
376
|
if (target === "remote" && result.pushed > 0) {
|
|
400
377
|
p.log.info(
|
|
401
378
|
pc.dim(
|
|
402
|
-
"Changes propagating to remote Studio (
|
|
379
|
+
"Changes propagating to remote Studio (eventual consistency, up to ~60s)."
|
|
403
380
|
)
|
|
404
381
|
);
|
|
405
382
|
}
|
|
@@ -416,4 +393,4 @@ var push_default = defineCommand({
|
|
|
416
393
|
export {
|
|
417
394
|
push_default as default
|
|
418
395
|
};
|
|
419
|
-
//# sourceMappingURL=push-
|
|
396
|
+
//# sourceMappingURL=push-RNJ7PQUW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/push.ts","../src/utils/manifest/index.ts","../src/utils/ir/hashIR.ts","../src/utils/validate.ts","../src/utils/ir/export.ts"],"sourcesContent":["import { access, mkdir, rm, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { defineCommand } from \"citty\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { ensureConfig } from \"@/utils/fs\";\nimport { readAgentManifest, computePushHash } from \"@/utils/manifest\";\nimport { requireAuth } from \"@/utils/auth\";\nimport { runInitialDeploy } from \"@/utils/deploy\";\nimport {\n type ProjectAgentState,\n type ProjectState,\n readProjectState,\n writeProjectState,\n} from \"@/utils/project-state\";\nimport { validateCompiledIR } from \"@/utils/validate\";\nimport { materializeRuntime, readLocalAgentNames } from \"@/utils/runtime\";\nimport { resolveProvider } from \"@/utils/providers\";\nimport { exportCompiledIrForDebug } from \"@/utils/ir/export\";\n\nconst LOGO = \"🦋\";\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n return `${(bytes / 1024).toFixed(1)} KB`;\n}\n\nfunction createInitialState(): ProjectState {\n return {\n workerUrl: null,\n deployedAt: null,\n accountId: null,\n agents: {},\n };\n}\n\nfunction ensureAgentState(\n state: ProjectState,\n agentName: string,\n localPath: string,\n): ProjectAgentState {\n const existing = state.agents[agentName];\n if (existing) {\n existing.localPath = localPath;\n return existing;\n }\n\n const created: ProjectAgentState = {\n currentHash: null,\n currentVersion: 0,\n lastLocalHash: null,\n lastRemoteHash: null,\n lastPushedAt: null,\n localPath,\n workerUrl:\n state.workerUrl ? `${state.workerUrl.replace(/\\/$/, \"\")}/a/${agentName}` : null,\n };\n state.agents[agentName] = created;\n return created;\n}\n\ntype PushTarget = \"local\" | \"remote\";\n\ninterface PushResult {\n pushed: number;\n skipped: number;\n failed: number;\n}\n\ninterface RemoteAgentIndexEntry {\n name: string;\n hash: string;\n version: string | null;\n versionNumber: number | null;\n updatedAt: string;\n workerUrl: string | null;\n label?: string;\n tags?: string[];\n}\n\nasync function readRemoteAgentsIndex(\n cwd: string,\n wranglerConfigPath: string,\n): Promise<RemoteAgentIndexEntry[]> {\n const provider = resolveProvider();\n const output = await provider.getValue({\n cwd,\n configPath: wranglerConfigPath,\n key: \"agents:index\",\n });\n if (!output) return [];\n try {\n const parsed = JSON.parse(output) as unknown;\n if (!Array.isArray(parsed)) return [];\n return parsed as RemoteAgentIndexEntry[];\n } catch {\n return [];\n }\n}\n\nasync function writeRemoteAgentsIndex(\n cwd: string,\n wranglerConfigPath: string,\n entries: RemoteAgentIndexEntry[],\n): Promise<void> {\n const path = join(cwd, \".kalp\", \"agents-index.json\");\n await writeFile(path, JSON.stringify(entries, null, 2), \"utf-8\");\n const provider = resolveProvider();\n try {\n await provider.putManifest({\n cwd,\n configPath: wranglerConfigPath,\n key: \"agents:index\",\n jsonPath: path,\n });\n } finally {\n await rm(path, { force: true });\n }\n}\n\nasync function pushRemoteManifest(params: {\n cwd: string;\n wranglerConfigPath: string;\n agentName: string;\n hash: string;\n ir: unknown;\n}): Promise<void> {\n const { cwd, wranglerConfigPath, agentName, hash, ir } = params;\n const manifestKey = `${agentName}:${hash}`;\n const latestKey = `${agentName}:latest`;\n const manifestPath = join(cwd, \".kalp\", `${agentName}-${hash}.json`);\n await mkdir(join(cwd, \".kalp\"), { recursive: true });\n await writeFile(manifestPath, JSON.stringify(ir), \"utf-8\");\n\n const provider = resolveProvider();\n try {\n await provider.putManifest({\n cwd,\n configPath: wranglerConfigPath,\n key: manifestKey,\n jsonPath: manifestPath,\n });\n await provider.putValue({\n cwd,\n configPath: wranglerConfigPath,\n key: latestKey,\n value: hash,\n });\n } finally {\n await rm(manifestPath, { force: true });\n }\n}\n\nexport default defineCommand({\n meta: { name: \"push\", description: \"Publish agent runtime version\" },\n args: {\n agent: {\n type: \"string\",\n alias: \"a\",\n description: \"Agent name to push\",\n required: false,\n },\n local: {\n type: \"boolean\",\n description: \"Update only local runtime snapshot and state\",\n required: false,\n default: false,\n },\n },\n async run({ args }) {\n const cwd = process.cwd();\n const target: PushTarget = args.local ? \"local\" : \"remote\";\n\n p.intro(`${LOGO} ${pc.bold(\"kalp push\")}`);\n\n await ensureConfig(cwd).catch(() => {\n p.log.error(`${pc.cyan(\"kalp.config.ts\")} not found`);\n process.exit(1);\n });\n\n const availableAgents = await readLocalAgentNames(cwd);\n if (availableAgents.length === 0) {\n p.log.error(\"No local agents found in ./agents\");\n process.exit(1);\n }\n\n let selectedAgents: string[] = [];\n if (args.agent) {\n if (!availableAgents.includes(args.agent)) {\n p.log.error(`Agent ${pc.cyan(args.agent)} not found`);\n process.exit(1);\n }\n selectedAgents = [args.agent];\n } else {\n selectedAgents = availableAgents;\n }\n\n let state = (await readProjectState(cwd)) ?? createInitialState();\n let runtime = await materializeRuntime(cwd, { mode: target });\n\n if (target === \"remote\") {\n await requireAuth().catch(() => {\n p.log.error(\"Not authenticated. Run `kalp login` first.\");\n process.exit(1);\n });\n\n if (!state.workerUrl) {\n p.log.warn(\"No .kalp/state.json found. Running initial deploy first...\");\n const deploy = await runInitialDeploy(cwd);\n state = (await readProjectState(cwd)) ?? createInitialState();\n state.workerUrl = deploy.workerUrl;\n state.accountId = deploy.accountId;\n state.deployedAt = new Date().toISOString();\n }\n\n runtime = await materializeRuntime(cwd, { mode: \"remote\" });\n }\n\n const spinner = p.spinner();\n const result: PushResult = { pushed: 0, skipped: 0, failed: 0 };\n const failures: string[] = [];\n\n for (const agentName of selectedAgents) {\n const agentPath = join(cwd, \"agents\", agentName, \"index.ts\");\n await access(agentPath).catch(() => {\n failures.push(`${agentName}: missing ${agentPath}`);\n });\n\n try {\n spinner.start(`Compiling ${pc.cyan(agentName)}`);\n const manifest = await readAgentManifest({ cwd, agentName });\n const hash = computePushHash(manifest.ir);\n const validation = validateCompiledIR({ agentName, ir: manifest.ir, hash });\n if (!validation.ok) {\n const details = (validation.errors ?? []).join(\" | \");\n throw new Error(\n `validation failed (${validation.phase})${details ? `: ${details}` : \"\"}`,\n );\n }\n\n const agentState = ensureAgentState(state, agentName, agentPath);\n const previousHash =\n target === \"local\" ? agentState.lastLocalHash : agentState.lastRemoteHash;\n\n if (previousHash === hash) {\n result.skipped += 1;\n spinner.stop(`Skipped ${pc.cyan(agentName)} (no changes)`);\n continue;\n }\n\n if (target === \"remote\") {\n spinner.message(\"Publishing runtime version\");\n await pushRemoteManifest({\n cwd,\n wranglerConfigPath: runtime.wranglerConfigPath,\n agentName,\n hash,\n ir: manifest.ir,\n });\n }\n\n agentState.currentVersion = Math.max(0, agentState.currentVersion) + 1;\n agentState.currentHash = hash;\n agentState.lastPushedAt = new Date().toISOString();\n agentState.workerUrl =\n state.workerUrl && target === \"remote\"\n ? `${state.workerUrl.replace(/\\/$/, \"\")}/a/${agentName}`\n : agentState.workerUrl;\n\n if (target === \"local\") {\n agentState.lastLocalHash = hash;\n } else {\n agentState.lastRemoteHash = hash;\n agentState.lastLocalHash = hash;\n\n const currentIndex = await readRemoteAgentsIndex(\n cwd,\n runtime.wranglerConfigPath,\n );\n const nextEntry: RemoteAgentIndexEntry = {\n name: agentName,\n hash,\n version: `v${agentState.currentVersion}`,\n versionNumber: agentState.currentVersion,\n updatedAt: agentState.lastPushedAt,\n workerUrl: agentState.workerUrl,\n label: manifest.ir.metadata?.label,\n tags: manifest.ir.metadata?.tags,\n };\n const merged = [\n ...currentIndex.filter((entry) => entry.name !== agentName),\n nextEntry,\n ].sort((a, b) => a.name.localeCompare(b.name));\n await writeRemoteAgentsIndex(cwd, runtime.wranglerConfigPath, merged);\n }\n\n const bundles = manifest.ir.bundles || {};\n await exportCompiledIrForDebug({\n cwd,\n agentName,\n ir: manifest.ir,\n });\n const totalSize = Object.values(bundles).reduce(\n (sum, bundle) => sum + Buffer.byteLength(bundle.code),\n 0,\n );\n const handlerCount = Object.keys(bundles).length;\n spinner.stop(\n `${pc.bold(agentName)} pushed ${pc.dim(`(v${agentState.currentVersion})`)} · ${handlerCount} handlers · ${formatBytes(totalSize)}`,\n );\n result.pushed += 1;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n failures.push(`${agentName}: ${message}`);\n spinner.stop(`Failed ${pc.cyan(agentName)}`);\n result.failed += 1;\n }\n }\n\n await writeProjectState(cwd, state);\n await materializeRuntime(cwd, { mode: target });\n\n p.note(\n `Successfully pushed ${result.pushed} agents. ${result.skipped} omitted (no changes). ${result.failed} failed.`,\n target === \"local\" ? \"Local push\" : \"Remote push\",\n );\n if (target === \"remote\" && result.pushed > 0) {\n p.log.info(\n pc.dim(\n \"Changes propagating to remote Studio (eventual consistency, up to ~60s).\",\n ),\n );\n }\n\n if (failures.length > 0) {\n for (const failure of failures) {\n p.log.error(failure);\n }\n p.outro(`${LOGO} ${pc.red(\"Push completed with failures\")}`);\n process.exit(1);\n }\n\n p.outro(`${LOGO} ${pc.green(\"Push complete\")}`);\n },\n});\n","import { access, readFile, rm, mkdtemp } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport { buildAgent } from \"@kalphq/compiler\";\n\nimport type { AgentManifestV3 } from \"@/utils/manifest/types\";\nexport type { AgentManifestV3 } from \"@/utils/manifest/types\";\nexport { computePushHash } from \"@/utils/ir/hashIR\";\n\n/**\n * Reads and compiles an agent into a pushable manifest.\n */\nexport async function readAgentManifest(params: {\n cwd: string;\n agentName: string;\n}): Promise<AgentManifestV3> {\n const { cwd, agentName } = params;\n const agentPath = join(cwd, \"agents\", agentName, \"index.ts\");\n await access(agentPath);\n\n // Use a temporary directory for the compiler output\n const tempOutDir = await mkdtemp(join(tmpdir(), \"kalp-build-\"));\n\n try {\n // Build the agent - compiler produces ir.bundles with all handler code\n await buildAgent(agentPath, tempOutDir, cwd);\n\n // Load the IR generated by the compiler (includes bundles with code)\n const irContent = await readFile(join(tempOutDir, \"ir.json\"), \"utf-8\");\n const ir = JSON.parse(irContent);\n\n return {\n format: \"kalp-agent-manifest\",\n schemaVersion: 3,\n ir,\n metadata: {\n generatedAt: new Date().toISOString(),\n },\n };\n } finally {\n // Cleanup temp build directory\n await rm(tempOutDir, { recursive: true, force: true });\n }\n}\n","import type { IRGraph } from \"@kalphq/sdk\";\nimport { calculateAgentHash } from \"@kalphq/compiler\";\n\nexport function getIRHash(ir: IRGraph): string {\n const { calculateIRHash } = require(\"@kalphq/compiler\");\n return calculateIRHash(ir);\n}\n\nexport function computePushHash(\n ir: IRGraph & { bundles?: Record<string, { code: string }> },\n): string {\n const bundles = ir.bundles || {};\n const handlers = Object.keys(bundles).reduce(\n (acc, hash) => ({\n ...acc,\n [hash]: { hash },\n }),\n {} as Record<string, { hash: string }>,\n );\n\n return calculateAgentHash(ir, handlers);\n}\n","import {\n analyzeHandler,\n calculateAgentHash,\n validateIR,\n validateIRBindings,\n} from \"@kalphq/compiler\";\nimport type { IRGraph } from \"@kalphq/sdk\";\n\nexport interface NamedAnalysis {\n name: string;\n capabilities: string[];\n imports: { external: string[]; internal: string[] };\n blockers: string[];\n warnings: string[];\n}\n\ntype IRWithBundles = IRGraph & {\n bundles?: Record<string, { code: string }>;\n};\n\nexport function validateCompiledIR(input: {\n agentName: string;\n ir: IRWithBundles;\n hash: string;\n}): {\n ok: boolean;\n phase?: \"ir\" | \"bindings\" | \"hash\" | \"analysis\";\n errors?: string[];\n blockers?: string[];\n analysis?: NamedAnalysis[];\n} {\n const { ir, hash } = input;\n const bundles = ir.bundles || {};\n const bundleHashes = Object.keys(bundles);\n\n const irValidation = validateIR(ir);\n if (!irValidation.valid) {\n return { ok: false, phase: \"ir\", errors: irValidation.errors };\n }\n\n const bindingsValidation = validateIRBindings(ir, bundleHashes);\n if (!bindingsValidation.valid) {\n return { ok: false, phase: \"bindings\", errors: bindingsValidation.errors };\n }\n\n const handlers = bundleHashes.reduce(\n (acc, key) => ({ ...acc, [key]: { hash: key } }),\n {} as Record<string, { hash: string }>,\n );\n const expectedHash = calculateAgentHash(ir, handlers);\n\n if (expectedHash !== hash) {\n return {\n ok: false,\n phase: \"hash\",\n errors: [\n `Hash mismatch: client provided ${hash}, calculated ${expectedHash}`,\n ],\n };\n }\n\n const analysis: NamedAnalysis[] = Object.entries(bundles).map(\n ([name, bundle]) => ({\n name,\n ...analyzeHandler(bundle.code),\n }),\n );\n\n const blockers = analysis.flatMap((entry) =>\n entry.blockers.map((blocker) => `${blocker} in ${entry.name}`),\n );\n\n if (blockers.length > 0) {\n return {\n ok: false,\n phase: \"analysis\",\n blockers,\n errors: blockers.map((b) => `[Analysis Blocker] ${b}`),\n analysis,\n };\n }\n\n return { ok: true, analysis };\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\n/**\n * TODO remove after SaaS observability: debug IR export for local inspection.\n */\nexport async function exportCompiledIrForDebug(params: {\n cwd: string;\n agentName: string;\n ir: unknown;\n}): Promise<string> {\n const { cwd, agentName, ir } = params;\n const outDir = join(cwd, \".kalp\", \"exports\", agentName);\n await mkdir(outDir, { recursive: true });\n const outputPath = join(outDir, \"ir.json\");\n await writeFile(outputPath, `${JSON.stringify(ir, null, 2)}\\n`, \"utf-8\");\n return outputPath;\n}\n"],"mappings":"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","names":["access","mkdir","rm","writeFile","join","calculateAgentHash","join","join","writeFile","rm","mkdir","spinner","access"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kalphq/cli",
|
|
3
|
-
"version": "0.0.0-dev-
|
|
3
|
+
"version": "0.0.0-dev-20260512061708",
|
|
4
4
|
"description": "Zero-config CLI for deploying Kalp agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
"open": "^11.0.0",
|
|
28
28
|
"picocolors": "1.1.1",
|
|
29
29
|
"zod": "3.25.76",
|
|
30
|
-
"@kalphq/compiler": "0.0.0-dev-
|
|
31
|
-
"@kalphq/
|
|
32
|
-
"@kalphq/
|
|
30
|
+
"@kalphq/compiler": "0.0.0-dev-20260512061708",
|
|
31
|
+
"@kalphq/project": "0.0.0-dev-20260512061708",
|
|
32
|
+
"@kalphq/sdk": "0.0.0-dev-20260512061708"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@types/json-stable-stringify": "1.2.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/deploy.ts","../src/utils/ai.ts"],"sourcesContent":["import { readFile, writeFile } from \"node:fs/promises\";\nimport { execa } from \"execa\";\nimport { requireAuth } from \"@/utils/auth\";\nimport { ensureStudioSecrets } from \"@/utils/secret\";\nimport { readProjectState, writeProjectState } from \"@/utils/project-state\";\nimport { materializeRuntime } from \"@/utils/runtime\";\nimport {\n getRequiredSecretForProvider,\n readDotEnv,\n resolveProviderFromConfig,\n} from \"@/utils/ai\";\n\nfunction findWorkersUrl(output: string): string | null {\n const match = output.match(/https:\\/\\/[^\\s]+\\.workers\\.dev/);\n return match?.[0] ?? null;\n}\n\ninterface RuntimeWranglerConfig {\n name?: string;\n kv_namespaces?: Array<{ binding: string; id?: string }>;\n}\n\ninterface KvNamespaceInfo {\n id: string;\n title: string;\n}\n\nasync function readWranglerConfig(\n configPath: string,\n): Promise<RuntimeWranglerConfig> {\n const text = await readFile(configPath, \"utf-8\");\n return JSON.parse(text) as RuntimeWranglerConfig;\n}\n\nasync function writeWranglerConfig(\n configPath: string,\n config: RuntimeWranglerConfig,\n): Promise<void> {\n await writeFile(configPath, `${JSON.stringify(config, null, 2)}\\n`, \"utf-8\");\n}\n\nfunction deriveKvNamespaceTitle(workerName: string, binding: string): string {\n return `${workerName}-${binding.toLowerCase().replace(/_/g, \"-\")}`;\n}\n\nfunction parseKvListOutput(stdout: string): KvNamespaceInfo[] {\n const trimmed = stdout.trim();\n if (!trimmed) return [];\n\n try {\n const parsed = JSON.parse(trimmed);\n if (Array.isArray(parsed)) {\n return parsed\n .map((item) => ({\n id: String((item as { id?: string }).id ?? \"\"),\n title: String((item as { title?: string }).title ?? \"\"),\n }))\n .filter((item) => !!item.id && !!item.title);\n }\n } catch {\n // fallback to text parsing below\n }\n\n const matches = trimmed.match(/[a-f0-9]{32}\\s+[^\\r\\n]+/gi) ?? [];\n return matches\n .map((line) => {\n const [id, ...rest] = line.trim().split(/\\s+/g);\n return { id: id ?? \"\", title: rest.join(\" \") };\n })\n .filter((item) => !!item.id && !!item.title);\n}\n\nasync function listKvNamespaces(\n cwd: string,\n configPath: string,\n): Promise<KvNamespaceInfo[]> {\n const tryJson = await execa(\n \"npx\",\n [\"wrangler\", \"kv\", \"namespace\", \"list\", \"--config\", configPath, \"--json\"],\n { cwd },\n ).catch(() => null);\n\n if (tryJson) {\n return parseKvListOutput(tryJson.stdout);\n }\n\n const plain = await execa(\n \"npx\",\n [\"wrangler\", \"kv\", \"namespace\", \"list\", \"--config\", configPath],\n { cwd },\n );\n return parseKvListOutput(plain.stdout);\n}\n\nasync function ensureKvNamespaceBindingId(\n cwd: string,\n configPath: string,\n): Promise<string | null> {\n const config = await readWranglerConfig(configPath);\n const binding = config.kv_namespaces?.find(\n (item) => item.binding === \"KALP_MANIFESTS\",\n );\n\n if (!binding || !config.name) return null;\n if (binding.id) return binding.id;\n\n const expectedTitle = deriveKvNamespaceTitle(config.name, binding.binding);\n const namespaces = await listKvNamespaces(cwd, configPath);\n const existing = namespaces.find((item) => item.title === expectedTitle);\n if (!existing) return null;\n\n binding.id = existing.id;\n await writeWranglerConfig(configPath, config);\n return existing.id;\n}\n\nfunction isNamespaceAlreadyExistsError(output: string): boolean {\n return output.includes(\"[code: 10014]\") && output.includes(\"already exists\");\n}\n\nasync function resolveWorkerUrl(\n configPath: string,\n deployOutput: string,\n): Promise<string> {\n const fromOutput = findWorkersUrl(deployOutput);\n if (fromOutput) return fromOutput;\n\n const configText = await readFile(configPath, \"utf-8\").catch(\n () => null as string | null,\n );\n const workerName = configText?.match(/\"name\"\\s*:\\s*\"([^\"]+)\"/)?.[1];\n\n if (workerName) {\n return `https://${workerName}.workers.dev`;\n }\n\n throw new Error(\"Could not resolve worker URL from wrangler deploy output.\");\n}\n\nexport async function runInitialDeploy(cwd: string): Promise<{\n workerUrl: string;\n accountId: string;\n}> {\n const auth = await requireAuth();\n const provider = await resolveProviderFromConfig(cwd);\n const requiredProviderSecret = getRequiredSecretForProvider(provider);\n const envMap = await readDotEnv(cwd);\n const providerSecretValue = envMap[requiredProviderSecret]?.trim();\n if (!providerSecretValue) {\n throw new Error(\n `Missing required secret ${requiredProviderSecret} for provider \"${provider}\". Add it to .env before deploy.`,\n );\n }\n\n const secrets = await ensureStudioSecrets(cwd);\n const runtime = await materializeRuntime(cwd);\n let secretSyncFailed = false;\n const secretEntries = [\n [\"KALP_SECRET_KEY\", secrets.key],\n [\"KALP_STUDIO_PASSWORD\", secrets.studioPassword],\n [\"KALP_STUDIO_ADMIN_USER\", secrets.studioAdminUser],\n [requiredProviderSecret, providerSecretValue],\n ] as const;\n\n for (const [name, value] of secretEntries) {\n try {\n await execa(\n \"npx\",\n [\"wrangler\", \"secret\", \"put\", name, \"--config\", runtime.wranglerConfigPath],\n { cwd, input: `${value}\\n` },\n );\n } catch {\n secretSyncFailed = true;\n break;\n }\n }\n\n await ensureKvNamespaceBindingId(cwd, runtime.wranglerConfigPath).catch(\n () => null,\n );\n\n const deployArgs = secretSyncFailed\n ? [\n \"wrangler\",\n \"deploy\",\n \"--config\",\n runtime.wranglerConfigPath,\n \"--secrets-file\",\n \".env\",\n ]\n : [\"wrangler\", \"deploy\", \"--config\", runtime.wranglerConfigPath];\n\n let deploy = await execa(\"npx\", deployArgs, { cwd }).catch((error) => error);\n if (deploy instanceof Error) {\n const combined = [String((deploy as { stdout?: string }).stdout ?? \"\"), String((deploy as { stderr?: string }).stderr ?? \"\"), deploy.message]\n .join(\"\\n\")\n .trim();\n if (isNamespaceAlreadyExistsError(combined)) {\n await ensureKvNamespaceBindingId(cwd, runtime.wranglerConfigPath);\n deploy = await execa(\"npx\", deployArgs, { cwd });\n } else {\n throw deploy;\n }\n }\n\n const deployStdout = [deploy.stdout, deploy.stderr]\n .filter(Boolean)\n .join(\"\\n\");\n\n const workerUrl = await resolveWorkerUrl(\n runtime.wranglerConfigPath,\n deployStdout,\n );\n\n const existingState = await readProjectState(cwd);\n\n await writeProjectState(cwd, {\n workerUrl,\n deployedAt: new Date().toISOString(),\n accountId: auth.accountId,\n agents: existingState?.agents ?? {},\n });\n\n return { workerUrl, accountId: auth.accountId };\n}\n","import { access, readFile } from \"node:fs/promises\";\nimport { constants } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { createJiti } from \"jiti\";\n\nexport type AIProvider = \"openai\" | \"anthropic\" | \"openrouter\" | \"custom\";\n\nconst PROVIDER_SECRET_MAP: Record<AIProvider, string> = {\n openai: \"OPENAI_API_KEY\",\n anthropic: \"ANTHROPIC_API_KEY\",\n openrouter: \"OPENROUTER_API_KEY\",\n custom: \"CUSTOM_AI_API_KEY\",\n};\n\nfunction parseEnv(content: string): Record<string, string> {\n const env: Record<string, string> = {};\n for (const raw of content.split(/\\r?\\n/g)) {\n const line = raw.trim();\n if (!line || line.startsWith(\"#\")) continue;\n const idx = line.indexOf(\"=\");\n if (idx <= 0) continue;\n env[line.slice(0, idx).trim()] = line.slice(idx + 1);\n }\n return env;\n}\n\nexport async function resolveProviderFromConfig(cwd: string): Promise<AIProvider> {\n const configPath = join(cwd, \"kalp.config.ts\");\n await access(configPath, constants.F_OK);\n const jiti = createJiti(cwd, { interopDefault: true });\n const config = (await jiti.import(configPath)) as\n | { default?: { ai?: { provider?: AIProvider } }; ai?: { provider?: AIProvider } }\n | undefined;\n const provider = config?.default?.ai?.provider ?? config?.ai?.provider ?? \"openai\";\n return provider;\n}\n\nexport async function readDotEnv(cwd: string): Promise<Record<string, string>> {\n const envPath = join(cwd, \".env\");\n const content = await readFile(envPath, \"utf-8\").catch(() => \"\");\n return parseEnv(content);\n}\n\nexport function getRequiredSecretForProvider(provider: AIProvider): string {\n return PROVIDER_SECRET_MAP[provider];\n}\n"],"mappings":"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","names":["readFile","readFile"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/create.ts","../src/utils/ui.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { scaffoldAgent } from \"@kalphq/project\";\nimport { isProjectInitialized } from \"@/utils/fs\";\nimport { promptAgentDetails } from \"@/utils/ui\";\n\nconst LOGO = \"🦋\";\n\nexport default defineCommand({\n meta: { name: \"create\", description: \"Add a new agent to the project\" },\n async run() {\n const cwd = process.cwd();\n\n p.intro(`${LOGO} ${pc.bold(\"kalp create\")}`);\n\n // ── Check if project is initialized ─────────────────────────────────\n const needsInit = !(await isProjectInitialized(cwd));\n\n if (needsInit) {\n p.log.error(\"This is not a Kalp project.\");\n console.log(\"\");\n console.log(\" Run:\");\n console.log(` ${pc.cyan(\"npx create-kalp@latest\")}`);\n console.log(\"\");\n process.exit(1);\n }\n\n // ── Agent prompts ────────────────────────────────────────────────────\n const agentAnswers = await promptAgentDetails({ includeTemplate: true });\n\n // ── Check if agent already exists ────────────────────────────────────\n const agentDir = join(cwd, \"agents\", agentAnswers.name);\n if (existsSync(agentDir)) {\n p.log.error(`Agent \"${agentAnswers.name}\" already exists.`);\n console.log(\"\");\n console.log(` ${pc.dim(\"Location:\")} ${pc.cyan(agentDir)}`);\n console.log(\"\");\n console.log(\n ` ${pc.dim(\"Choose a different name or remove the existing agent.\")}`,\n );\n process.exit(1);\n }\n\n const s = p.spinner();\n\n // ── Scaffold agent ───────────────────────────────────────────────────\n s.start(`Scaffolding agent ${pc.cyan(agentAnswers.name)}`);\n await scaffoldAgent({\n agentName: agentAnswers.name,\n label: agentAnswers.label,\n cwd,\n template: agentAnswers.template,\n });\n s.stop(\n agentAnswers.template\n ? `Agent created (${agentAnswers.template} template)`\n : \"Agent created\",\n );\n\n p.note(\n [\n `${pc.dim(\"•\")} ${pc.cyan(`agents/${agentAnswers.name}/index.ts`)} ${pc.dim(\"— Agent entrypoint with config\")}`,\n `${pc.dim(\"•\")} ${pc.cyan(`agents/${agentAnswers.name}/contract/`)} ${pc.dim(\"— RPC contract definition\")}`,\n `${pc.dim(\"•\")} ${pc.cyan(`agents/${agentAnswers.name}/hooks/`)} ${pc.dim(\"— Lifecycle hooks (onInit, onTick)\")}`,\n `${pc.dim(\"•\")} ${pc.cyan(`agents/${agentAnswers.name}/routes/`)} ${pc.dim(\"— HTTP endpoints\")}`,\n `${pc.dim(\"•\")} ${pc.cyan(`agents/${agentAnswers.name}/steps/`)} ${pc.dim(\"— Reusable workflow steps\")}`,\n `${pc.dim(\"•\")} ${pc.cyan(`agents/${agentAnswers.name}/tools/`)} ${pc.dim(\"— Callable agent tools\")}`,\n ].join(\"\\n\"),\n \"Created\",\n );\n\n p.outro(\n `${LOGO} ${pc.green(`Agent ${pc.bold(agentAnswers.name)} is ready.`)}`,\n );\n },\n});\n","import * as p from \"@clack/prompts\";\nimport { deriveLabelFromName, type TemplateId } from \"@kalphq/project\";\n\n/**\n * Prompt user to select an agent template.\n */\nexport async function promptTemplateSelection(): Promise<TemplateId> {\n const answer = await p.select({\n message: \"Choose an agent template:\",\n options: [\n {\n value: \"researcher\",\n label: \"🔬 Researcher\",\n hint: \"Deterministic scheduling - pause 24h and auto-resume\",\n },\n {\n value: \"support\",\n label: \"🎧 Support Agent\",\n hint: \"Human-in-the-Loop - pause for days until resolved\",\n },\n {\n value: \"blank\",\n label: \"⬜ Blank\",\n hint: \"Minimal structure with modern Kalp v1 syntax\",\n },\n ],\n });\n\n if (p.isCancel(answer)) {\n p.cancel(\"Cancelled.\");\n process.exit(0);\n }\n\n return answer as TemplateId;\n}\n\nexport async function promptProjectName(opts?: {\n message?: string;\n placeholder?: string;\n allowCurrentDir?: boolean;\n}): Promise<string> {\n const message = opts?.message ?? \"Project name?\";\n const placeholder = opts?.placeholder ?? \"my-project\";\n const allowCurrentDir = opts?.allowCurrentDir ?? false;\n\n const answer = await p.text({\n message,\n placeholder,\n validate: (v) => {\n const value = v.trim();\n if (!value) return \"Project name is required.\";\n if (allowCurrentDir && value === \".\") return;\n if (!/^[a-z0-9-]+$/.test(value)) {\n return allowCurrentDir\n ? \"Use lowercase letters, numbers, and dashes only (or . for current directory).\"\n : \"Use lowercase letters, numbers, and dashes only.\";\n }\n },\n });\n\n if (p.isCancel(answer)) {\n p.cancel(\"Cancelled.\");\n process.exit(0);\n }\n\n return answer.trim();\n}\n\nexport async function promptAgentDetails(opts?: {\n includeTemplate?: boolean;\n}): Promise<{\n name: string;\n label: string;\n template?: TemplateId;\n}> {\n const answers = await p.group(\n {\n name: () =>\n p.text({\n message: \"Agent name?\",\n placeholder: \"my-agent\",\n validate: (v) => {\n if (!v.trim()) return \"Agent name is required.\";\n if (!/^[a-z0-9-]+$/.test(v)) {\n return \"Use lowercase letters, numbers, and dashes only.\";\n }\n },\n }),\n ...(opts?.includeTemplate && {\n template: () => promptTemplateSelection(),\n }),\n label: ({ results }) =>\n p.text({\n message: \"Agent label? (display name)\",\n placeholder: deriveLabelFromName(results.name as string),\n initialValue: deriveLabelFromName(results.name as string),\n validate: (v) => {\n if (!v.trim()) return \"Agent label is required.\";\n },\n }),\n },\n {\n onCancel: () => {\n p.cancel(\"Cancelled.\");\n process.exit(0);\n },\n },\n );\n\n return {\n name: answers.name,\n label: answers.label,\n template: answers.template as TemplateId | undefined,\n };\n}\n"],"mappings":"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","names":["p"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/deploy.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { requireAuth } from \"@/utils/auth\";\nimport { runInitialDeploy } from \"@/utils/deploy\";\n\nconst LOGO = \"🦋\";\n\nexport default defineCommand({\n meta: { name: \"deploy\", description: \"Deploy Worker + Studio to Cloudflare\" },\n async run() {\n const cwd = process.cwd();\n\n p.intro(`${LOGO} ${pc.bold(\"kalp deploy\")}`);\n\n await requireAuth().catch(() => {\n p.log.error(\"Not authenticated. Run `kalp login` first.\");\n process.exit(1);\n });\n\n const target = await p.select({\n message: \"Choose deployment target\",\n options: [\n { label: \"Cloudflare (Recommended)\", value: \"cloudflare\" },\n { label: \"Kalp Cloud (Coming soon)\", value: \"kalp-cloud\" },\n ],\n });\n\n if (p.isCancel(target)) {\n p.outro(\"Cancelled\");\n return;\n }\n\n if (target === \"kalp-cloud\") {\n p.note(\n \"Coming soon. Enterprise cloud execution is currently waitlisted.\",\n \"Kalp Cloud\",\n );\n p.outro(pc.dim(\"No deployment executed.\"));\n return;\n }\n\n const s = p.spinner();\n s.start(\"Deploying to Cloudflare\");\n\n try {\n const result = await runInitialDeploy(cwd);\n s.stop(\"Deployment completed\");\n p.log.success(`Worker URL: ${pc.cyan(result.workerUrl)}`);\n p.outro(pc.green(\"Cloudflare deployment ready\"));\n } catch (error) {\n s.stop(\"Deployment failed\");\n p.log.error(\n error instanceof Error ? error.message : \"Unknown deployment error\",\n );\n process.exit(1);\n }\n },\n});\n"],"mappings":";;;;;;;;;;;AAAA,SAAS,qBAAqB;AAC9B,YAAY,OAAO;AACnB,OAAO,QAAQ;AAIf,IAAM,OAAO;AAEb,IAAO,iBAAQ,cAAc;AAAA,EAC3B,MAAM,EAAE,MAAM,UAAU,aAAa,uCAAuC;AAAA,EAC5E,MAAM,MAAM;AACV,UAAM,MAAM,QAAQ,IAAI;AAExB,IAAE,QAAM,GAAG,IAAI,IAAI,GAAG,KAAK,aAAa,CAAC,EAAE;AAE3C,UAAM,YAAY,EAAE,MAAM,MAAM;AAC9B,MAAE,MAAI,MAAM,4CAA4C;AACxD,cAAQ,KAAK,CAAC;AAAA,IAChB,CAAC;AAED,UAAM,SAAS,MAAQ,SAAO;AAAA,MAC5B,SAAS;AAAA,MACT,SAAS;AAAA,QACP,EAAE,OAAO,4BAA4B,OAAO,aAAa;AAAA,QACzD,EAAE,OAAO,4BAA4B,OAAO,aAAa;AAAA,MAC3D;AAAA,IACF,CAAC;AAED,QAAM,WAAS,MAAM,GAAG;AACtB,MAAE,QAAM,WAAW;AACnB;AAAA,IACF;AAEA,QAAI,WAAW,cAAc;AAC3B,MAAE;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,MAAE,QAAM,GAAG,IAAI,yBAAyB,CAAC;AACzC;AAAA,IACF;AAEA,UAAM,IAAM,UAAQ;AACpB,MAAE,MAAM,yBAAyB;AAEjC,QAAI;AACF,YAAM,SAAS,MAAM,iBAAiB,GAAG;AACzC,QAAE,KAAK,sBAAsB;AAC7B,MAAE,MAAI,QAAQ,eAAe,GAAG,KAAK,OAAO,SAAS,CAAC,EAAE;AACxD,MAAE,QAAM,GAAG,MAAM,6BAA6B,CAAC;AAAA,IACjD,SAAS,OAAO;AACd,QAAE,KAAK,mBAAmB;AAC1B,MAAE,MAAI;AAAA,QACJ,iBAAiB,QAAQ,MAAM,UAAU;AAAA,MAC3C;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AACF,CAAC;","names":[]}
|
package/dist/login-M5Y57ZZU.js
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
getCloudflareIdentity,
|
|
4
|
-
saveAuthConfig
|
|
5
|
-
} from "./chunk-5RODADXW.js";
|
|
6
|
-
import "./chunk-FO24J6XL.js";
|
|
7
|
-
|
|
8
|
-
// src/commands/login.ts
|
|
9
|
-
import { defineCommand } from "citty";
|
|
10
|
-
import * as p from "@clack/prompts";
|
|
11
|
-
import pc from "picocolors";
|
|
12
|
-
import { execa } from "execa";
|
|
13
|
-
var LOGO = "\u{1F98B}";
|
|
14
|
-
var login_default = defineCommand({
|
|
15
|
-
meta: { name: "login", description: "Authenticate with Cloudflare" },
|
|
16
|
-
async run() {
|
|
17
|
-
p.intro(`${LOGO} ${pc.bold("kalp login")}`);
|
|
18
|
-
const provider = await p.select({
|
|
19
|
-
message: "Choose login provider",
|
|
20
|
-
options: [
|
|
21
|
-
{ label: "Cloudflare (Recommended)", value: "cloudflare" },
|
|
22
|
-
{ label: "Kalp Cloud", value: "kalp-cloud" }
|
|
23
|
-
]
|
|
24
|
-
});
|
|
25
|
-
if (p.isCancel(provider)) {
|
|
26
|
-
p.outro("Cancelled");
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
if (provider === "kalp-cloud") {
|
|
30
|
-
p.note(
|
|
31
|
-
"Coming soon. Enterprise cloud execution is currently waitlisted.",
|
|
32
|
-
"Kalp Cloud"
|
|
33
|
-
);
|
|
34
|
-
p.outro(pc.dim("No login executed."));
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
const s = p.spinner();
|
|
38
|
-
s.start("Opening Cloudflare OAuth login");
|
|
39
|
-
try {
|
|
40
|
-
await execa("npx", ["wrangler", "login"], {
|
|
41
|
-
stdio: "inherit"
|
|
42
|
-
});
|
|
43
|
-
} catch {
|
|
44
|
-
s.stop(pc.red("Cloudflare login failed"));
|
|
45
|
-
process.exit(1);
|
|
46
|
-
}
|
|
47
|
-
s.stop("Cloudflare login complete");
|
|
48
|
-
s.start("Reading Cloudflare identity");
|
|
49
|
-
const identity = await getCloudflareIdentity();
|
|
50
|
-
const account = identity?.accounts?.[0];
|
|
51
|
-
const accountId = account?.id ?? account?.account_tag;
|
|
52
|
-
const email = identity?.email;
|
|
53
|
-
if (!accountId || !email) {
|
|
54
|
-
s.stop(pc.red("Could not resolve account identity from wrangler whoami"));
|
|
55
|
-
process.exit(1);
|
|
56
|
-
}
|
|
57
|
-
const authConfig = {
|
|
58
|
-
provider: "cloudflare",
|
|
59
|
-
accountId,
|
|
60
|
-
email,
|
|
61
|
-
expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1e3).toISOString()
|
|
62
|
-
};
|
|
63
|
-
await saveAuthConfig(authConfig);
|
|
64
|
-
s.stop("Cloudflare authentication saved");
|
|
65
|
-
p.log.success(`Logged in as ${pc.cyan(authConfig.email)}`);
|
|
66
|
-
p.note(`Account ID: ${pc.cyan(authConfig.accountId)}`, "Cloudflare");
|
|
67
|
-
p.outro(pc.green("Ready to deploy with Cloudflare Workers"));
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
export {
|
|
71
|
-
login_default as default
|
|
72
|
-
};
|
|
73
|
-
//# sourceMappingURL=login-M5Y57ZZU.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/login.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { execa } from \"execa\";\nimport {\n getCloudflareIdentity,\n saveAuthConfig,\n type AuthConfig,\n} from \"@/utils/auth\";\n\nconst LOGO = \"🦋\";\n\nexport default defineCommand({\n meta: { name: \"login\", description: \"Authenticate with Cloudflare\" },\n async run() {\n p.intro(`${LOGO} ${pc.bold(\"kalp login\")}`);\n\n const provider = await p.select({\n message: \"Choose login provider\",\n options: [\n { label: \"Cloudflare (Recommended)\", value: \"cloudflare\" },\n { label: \"Kalp Cloud\", value: \"kalp-cloud\" },\n ],\n });\n\n if (p.isCancel(provider)) {\n p.outro(\"Cancelled\");\n return;\n }\n\n if (provider === \"kalp-cloud\") {\n p.note(\n \"Coming soon. Enterprise cloud execution is currently waitlisted.\",\n \"Kalp Cloud\",\n );\n p.outro(pc.dim(\"No login executed.\"));\n return;\n }\n\n const s = p.spinner();\n s.start(\"Opening Cloudflare OAuth login\");\n\n try {\n await execa(\"npx\", [\"wrangler\", \"login\"], {\n stdio: \"inherit\",\n });\n } catch {\n s.stop(pc.red(\"Cloudflare login failed\"));\n process.exit(1);\n }\n\n s.stop(\"Cloudflare login complete\");\n s.start(\"Reading Cloudflare identity\");\n const identity = await getCloudflareIdentity();\n const account = identity?.accounts?.[0];\n const accountId = account?.id ?? account?.account_tag;\n const email = identity?.email;\n\n if (!accountId || !email) {\n s.stop(pc.red(\"Could not resolve account identity from wrangler whoami\"));\n process.exit(1);\n }\n\n const authConfig: AuthConfig = {\n provider: \"cloudflare\",\n accountId,\n email,\n expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(),\n };\n\n await saveAuthConfig(authConfig);\n\n s.stop(\"Cloudflare authentication saved\");\n p.log.success(`Logged in as ${pc.cyan(authConfig.email)}`);\n p.note(`Account ID: ${pc.cyan(authConfig.accountId)}`, \"Cloudflare\");\n p.outro(pc.green(\"Ready to deploy with Cloudflare Workers\"));\n },\n});\n"],"mappings":";;;;;;;;AAAA,SAAS,qBAAqB;AAC9B,YAAY,OAAO;AACnB,OAAO,QAAQ;AACf,SAAS,aAAa;AAOtB,IAAM,OAAO;AAEb,IAAO,gBAAQ,cAAc;AAAA,EAC3B,MAAM,EAAE,MAAM,SAAS,aAAa,+BAA+B;AAAA,EACnE,MAAM,MAAM;AACV,IAAE,QAAM,GAAG,IAAI,IAAI,GAAG,KAAK,YAAY,CAAC,EAAE;AAE1C,UAAM,WAAW,MAAQ,SAAO;AAAA,MAC9B,SAAS;AAAA,MACT,SAAS;AAAA,QACP,EAAE,OAAO,4BAA4B,OAAO,aAAa;AAAA,QACzD,EAAE,OAAO,cAAc,OAAO,aAAa;AAAA,MAC7C;AAAA,IACF,CAAC;AAED,QAAM,WAAS,QAAQ,GAAG;AACxB,MAAE,QAAM,WAAW;AACnB;AAAA,IACF;AAEA,QAAI,aAAa,cAAc;AAC7B,MAAE;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,MAAE,QAAM,GAAG,IAAI,oBAAoB,CAAC;AACpC;AAAA,IACF;AAEA,UAAM,IAAM,UAAQ;AACpB,MAAE,MAAM,gCAAgC;AAExC,QAAI;AACF,YAAM,MAAM,OAAO,CAAC,YAAY,OAAO,GAAG;AAAA,QACxC,OAAO;AAAA,MACT,CAAC;AAAA,IACH,QAAQ;AACN,QAAE,KAAK,GAAG,IAAI,yBAAyB,CAAC;AACxC,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,MAAE,KAAK,2BAA2B;AAClC,MAAE,MAAM,6BAA6B;AACrC,UAAM,WAAW,MAAM,sBAAsB;AAC7C,UAAM,UAAU,UAAU,WAAW,CAAC;AACtC,UAAM,YAAY,SAAS,MAAM,SAAS;AAC1C,UAAM,QAAQ,UAAU;AAExB,QAAI,CAAC,aAAa,CAAC,OAAO;AACxB,QAAE,KAAK,GAAG,IAAI,yDAAyD,CAAC;AACxE,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,aAAyB;AAAA,MAC7B,UAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA,WAAW,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,KAAK,GAAI,EAAE,YAAY;AAAA,IACzE;AAEA,UAAM,eAAe,UAAU;AAE/B,MAAE,KAAK,iCAAiC;AACxC,IAAE,MAAI,QAAQ,gBAAgB,GAAG,KAAK,WAAW,KAAK,CAAC,EAAE;AACzD,IAAE,OAAK,eAAe,GAAG,KAAK,WAAW,SAAS,CAAC,IAAI,YAAY;AACnE,IAAE,QAAM,GAAG,MAAM,yCAAyC,CAAC;AAAA,EAC7D;AACF,CAAC;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/push.ts","../src/utils/manifest/index.ts","../src/utils/ir/hashIR.ts","../src/utils/validate.ts"],"sourcesContent":["import { access, mkdir, rm, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { defineCommand } from \"citty\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { execa } from \"execa\";\nimport { ensureConfig } from \"@/utils/fs\";\nimport { readAgentManifest, computePushHash } from \"@/utils/manifest\";\nimport { requireAuth } from \"@/utils/auth\";\nimport { runInitialDeploy } from \"@/utils/deploy\";\nimport {\n type ProjectAgentState,\n type ProjectState,\n readProjectState,\n writeProjectState,\n} from \"@/utils/project-state\";\nimport { validateCompiledIR } from \"@/utils/validate\";\nimport { materializeRuntime, readLocalAgentNames } from \"@/utils/runtime\";\n\nconst LOGO = \"🦋\";\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n return `${(bytes / 1024).toFixed(1)} KB`;\n}\n\nfunction createInitialState(): ProjectState {\n return {\n workerUrl: null,\n deployedAt: null,\n accountId: null,\n agents: {},\n };\n}\n\nfunction ensureAgentState(\n state: ProjectState,\n agentName: string,\n localPath: string,\n): ProjectAgentState {\n const existing = state.agents[agentName];\n if (existing) {\n existing.localPath = localPath;\n return existing;\n }\n\n const created: ProjectAgentState = {\n currentHash: null,\n currentVersion: 0,\n lastLocalHash: null,\n lastRemoteHash: null,\n lastPushedAt: null,\n localPath,\n workerUrl:\n state.workerUrl ? `${state.workerUrl.replace(/\\/$/, \"\")}/a/${agentName}` : null,\n };\n state.agents[agentName] = created;\n return created;\n}\n\ntype PushTarget = \"local\" | \"remote\";\n\ninterface PushResult {\n pushed: number;\n skipped: number;\n failed: number;\n}\n\ninterface RemoteAgentIndexEntry {\n name: string;\n hash: string;\n version: string | null;\n versionNumber: number | null;\n updatedAt: string;\n workerUrl: string | null;\n label?: string;\n tags?: string[];\n}\n\nasync function readRemoteAgentsIndex(\n cwd: string,\n wranglerConfigPath: string,\n): Promise<RemoteAgentIndexEntry[]> {\n const result = await execa(\n \"npx\",\n [\n \"wrangler\",\n \"kv\",\n \"key\",\n \"get\",\n \"--binding\",\n \"KALP_MANIFESTS\",\n \"agents:index\",\n \"--remote\",\n \"--config\",\n wranglerConfigPath,\n ],\n { cwd },\n ).catch(() => null);\n\n if (!result?.stdout?.trim()) return [];\n try {\n const parsed = JSON.parse(result.stdout) as unknown;\n if (!Array.isArray(parsed)) return [];\n return parsed as RemoteAgentIndexEntry[];\n } catch {\n return [];\n }\n}\n\nasync function writeRemoteAgentsIndex(\n cwd: string,\n wranglerConfigPath: string,\n entries: RemoteAgentIndexEntry[],\n): Promise<void> {\n const path = join(cwd, \".kalp\", \"agents-index.json\");\n await writeFile(path, JSON.stringify(entries, null, 2), \"utf-8\");\n try {\n await execa(\n \"npx\",\n [\n \"wrangler\",\n \"kv\",\n \"key\",\n \"put\",\n \"--binding\",\n \"KALP_MANIFESTS\",\n \"agents:index\",\n \"--path\",\n path,\n \"--remote\",\n \"--config\",\n wranglerConfigPath,\n ],\n { cwd },\n );\n } finally {\n await rm(path, { force: true });\n }\n}\n\nasync function pushRemoteManifest(params: {\n cwd: string;\n wranglerConfigPath: string;\n agentName: string;\n hash: string;\n ir: unknown;\n}): Promise<void> {\n const { cwd, wranglerConfigPath, agentName, hash, ir } = params;\n const manifestKey = `${agentName}:${hash}`;\n const latestKey = `${agentName}:latest`;\n const manifestPath = join(cwd, \".kalp\", `${agentName}-${hash}.json`);\n await mkdir(join(cwd, \".kalp\"), { recursive: true });\n await writeFile(manifestPath, JSON.stringify(ir), \"utf-8\");\n\n try {\n await execa(\n \"npx\",\n [\n \"wrangler\",\n \"kv\",\n \"key\",\n \"put\",\n \"--binding\",\n \"KALP_MANIFESTS\",\n manifestKey,\n \"--path\",\n manifestPath,\n \"--remote\",\n \"--config\",\n wranglerConfigPath,\n ],\n { cwd },\n );\n\n await execa(\n \"npx\",\n [\n \"wrangler\",\n \"kv\",\n \"key\",\n \"put\",\n \"--binding\",\n \"KALP_MANIFESTS\",\n latestKey,\n hash,\n \"--remote\",\n \"--config\",\n wranglerConfigPath,\n ],\n { cwd },\n );\n } finally {\n await rm(manifestPath, { force: true });\n }\n}\n\nexport default defineCommand({\n meta: { name: \"push\", description: \"Push agent manifest to Cloudflare KV\" },\n args: {\n agent: {\n type: \"string\",\n alias: \"a\",\n description: \"Agent name to push\",\n required: false,\n },\n local: {\n type: \"boolean\",\n description: \"Update only local runtime snapshot and state\",\n required: false,\n default: false,\n },\n },\n async run({ args }) {\n const cwd = process.cwd();\n const target: PushTarget = args.local ? \"local\" : \"remote\";\n\n p.intro(`${LOGO} ${pc.bold(\"kalp push\")}`);\n\n await ensureConfig(cwd).catch(() => {\n p.log.error(`${pc.cyan(\"kalp.config.ts\")} not found`);\n process.exit(1);\n });\n\n const availableAgents = await readLocalAgentNames(cwd);\n if (availableAgents.length === 0) {\n p.log.error(\"No local agents found in ./agents\");\n process.exit(1);\n }\n\n let selectedAgents: string[] = [];\n if (args.agent) {\n if (!availableAgents.includes(args.agent)) {\n p.log.error(`Agent ${pc.cyan(args.agent)} not found`);\n process.exit(1);\n }\n selectedAgents = [args.agent];\n } else {\n selectedAgents = availableAgents;\n }\n\n let state = (await readProjectState(cwd)) ?? createInitialState();\n let runtime = await materializeRuntime(cwd, { mode: target });\n\n if (target === \"remote\") {\n await requireAuth().catch(() => {\n p.log.error(\"Not authenticated. Run `kalp login` first.\");\n process.exit(1);\n });\n\n if (!state.workerUrl) {\n p.log.warn(\"No .kalp/state.json found. Running initial deploy first...\");\n const deploy = await runInitialDeploy(cwd);\n state = (await readProjectState(cwd)) ?? createInitialState();\n state.workerUrl = deploy.workerUrl;\n state.accountId = deploy.accountId;\n state.deployedAt = new Date().toISOString();\n }\n\n runtime = await materializeRuntime(cwd, { mode: \"remote\" });\n }\n\n const spinner = p.spinner();\n const result: PushResult = { pushed: 0, skipped: 0, failed: 0 };\n const failures: string[] = [];\n\n for (const agentName of selectedAgents) {\n const agentPath = join(cwd, \"agents\", agentName, \"index.ts\");\n await access(agentPath).catch(() => {\n failures.push(`${agentName}: missing ${agentPath}`);\n });\n\n try {\n spinner.start(`Compiling ${pc.cyan(agentName)}`);\n const manifest = await readAgentManifest({ cwd, agentName });\n const hash = computePushHash(manifest.ir);\n const validation = validateCompiledIR({ agentName, ir: manifest.ir, hash });\n if (!validation.ok) {\n const details = (validation.errors ?? []).join(\" | \");\n throw new Error(\n `validation failed (${validation.phase})${details ? `: ${details}` : \"\"}`,\n );\n }\n\n const agentState = ensureAgentState(state, agentName, agentPath);\n const previousHash =\n target === \"local\" ? agentState.lastLocalHash : agentState.lastRemoteHash;\n\n if (previousHash === hash) {\n result.skipped += 1;\n spinner.stop(`Skipped ${pc.cyan(agentName)} (no changes)`);\n continue;\n }\n\n if (target === \"remote\") {\n spinner.message(\"Uploading manifest to Cloudflare KV\");\n await pushRemoteManifest({\n cwd,\n wranglerConfigPath: runtime.wranglerConfigPath,\n agentName,\n hash,\n ir: manifest.ir,\n });\n }\n\n agentState.currentVersion = Math.max(0, agentState.currentVersion) + 1;\n agentState.currentHash = hash;\n agentState.lastPushedAt = new Date().toISOString();\n agentState.workerUrl =\n state.workerUrl && target === \"remote\"\n ? `${state.workerUrl.replace(/\\/$/, \"\")}/a/${agentName}`\n : agentState.workerUrl;\n\n if (target === \"local\") {\n agentState.lastLocalHash = hash;\n } else {\n agentState.lastRemoteHash = hash;\n agentState.lastLocalHash = hash;\n\n const currentIndex = await readRemoteAgentsIndex(\n cwd,\n runtime.wranglerConfigPath,\n );\n const nextEntry: RemoteAgentIndexEntry = {\n name: agentName,\n hash,\n version: `v${agentState.currentVersion}`,\n versionNumber: agentState.currentVersion,\n updatedAt: agentState.lastPushedAt,\n workerUrl: agentState.workerUrl,\n label: manifest.ir.metadata?.label,\n tags: manifest.ir.metadata?.tags,\n };\n const merged = [\n ...currentIndex.filter((entry) => entry.name !== agentName),\n nextEntry,\n ].sort((a, b) => a.name.localeCompare(b.name));\n await writeRemoteAgentsIndex(cwd, runtime.wranglerConfigPath, merged);\n }\n\n const bundles = manifest.ir.bundles || {};\n const totalSize = Object.values(bundles).reduce(\n (sum, bundle) => sum + Buffer.byteLength(bundle.code),\n 0,\n );\n const handlerCount = Object.keys(bundles).length;\n spinner.stop(\n `${pc.bold(agentName)} pushed ${pc.dim(`(v${agentState.currentVersion})`)} · ${handlerCount} handlers · ${formatBytes(totalSize)}`,\n );\n result.pushed += 1;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n failures.push(`${agentName}: ${message}`);\n spinner.stop(`Failed ${pc.cyan(agentName)}`);\n result.failed += 1;\n }\n }\n\n await writeProjectState(cwd, state);\n await materializeRuntime(cwd, { mode: target });\n\n p.note(\n `Successfully pushed ${result.pushed} agents. ${result.skipped} omitted (no changes). ${result.failed} failed.`,\n target === \"local\" ? \"Local push\" : \"Remote push\",\n );\n if (target === \"remote\" && result.pushed > 0) {\n p.log.info(\n pc.dim(\n \"Changes propagating to remote Studio (Cloudflare KV eventual consistency, up to ~60s).\",\n ),\n );\n }\n\n if (failures.length > 0) {\n for (const failure of failures) {\n p.log.error(failure);\n }\n p.outro(`${LOGO} ${pc.red(\"Push completed with failures\")}`);\n process.exit(1);\n }\n\n p.outro(`${LOGO} ${pc.green(\"Push complete\")}`);\n },\n});\n","import { access, readFile, rm, mkdtemp } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport { buildAgent } from \"@kalphq/compiler\";\n\nimport type { AgentManifestV3 } from \"@/utils/manifest/types\";\nexport type { AgentManifestV3 } from \"@/utils/manifest/types\";\nexport { computePushHash } from \"@/utils/ir/hashIR\";\n\n/**\n * Reads and compiles an agent into a pushable manifest.\n */\nexport async function readAgentManifest(params: {\n cwd: string;\n agentName: string;\n}): Promise<AgentManifestV3> {\n const { cwd, agentName } = params;\n const agentPath = join(cwd, \"agents\", agentName, \"index.ts\");\n await access(agentPath);\n\n // Use a temporary directory for the compiler output\n const tempOutDir = await mkdtemp(join(tmpdir(), \"kalp-build-\"));\n\n try {\n // Build the agent - compiler produces ir.bundles with all handler code\n await buildAgent(agentPath, tempOutDir, cwd);\n\n // Load the IR generated by the compiler (includes bundles with code)\n const irContent = await readFile(join(tempOutDir, \"ir.json\"), \"utf-8\");\n const ir = JSON.parse(irContent);\n\n return {\n format: \"kalp-agent-manifest\",\n schemaVersion: 3,\n ir,\n metadata: {\n generatedAt: new Date().toISOString(),\n },\n };\n } finally {\n // Cleanup temp build directory\n await rm(tempOutDir, { recursive: true, force: true });\n }\n}\n","import type { IRGraph } from \"@kalphq/sdk\";\nimport { calculateAgentHash } from \"@kalphq/compiler\";\n\nexport function getIRHash(ir: IRGraph): string {\n const { calculateIRHash } = require(\"@kalphq/compiler\");\n return calculateIRHash(ir);\n}\n\nexport function computePushHash(\n ir: IRGraph & { bundles?: Record<string, { code: string }> },\n): string {\n const bundles = ir.bundles || {};\n const handlers = Object.keys(bundles).reduce(\n (acc, hash) => ({\n ...acc,\n [hash]: { hash },\n }),\n {} as Record<string, { hash: string }>,\n );\n\n return calculateAgentHash(ir, handlers);\n}\n","import {\n analyzeHandler,\n calculateAgentHash,\n validateIR,\n validateIRBindings,\n} from \"@kalphq/compiler\";\nimport type { IRGraph } from \"@kalphq/sdk\";\n\nexport interface NamedAnalysis {\n name: string;\n capabilities: string[];\n imports: { external: string[]; internal: string[] };\n blockers: string[];\n warnings: string[];\n}\n\ntype IRWithBundles = IRGraph & {\n bundles?: Record<string, { code: string }>;\n};\n\nexport function validateCompiledIR(input: {\n agentName: string;\n ir: IRWithBundles;\n hash: string;\n}): {\n ok: boolean;\n phase?: \"ir\" | \"bindings\" | \"hash\" | \"analysis\";\n errors?: string[];\n blockers?: string[];\n analysis?: NamedAnalysis[];\n} {\n const { ir, hash } = input;\n const bundles = ir.bundles || {};\n const bundleHashes = Object.keys(bundles);\n\n const irValidation = validateIR(ir);\n if (!irValidation.valid) {\n return { ok: false, phase: \"ir\", errors: irValidation.errors };\n }\n\n const bindingsValidation = validateIRBindings(ir, bundleHashes);\n if (!bindingsValidation.valid) {\n return { ok: false, phase: \"bindings\", errors: bindingsValidation.errors };\n }\n\n const handlers = bundleHashes.reduce(\n (acc, key) => ({ ...acc, [key]: { hash: key } }),\n {} as Record<string, { hash: string }>,\n );\n const expectedHash = calculateAgentHash(ir, handlers);\n\n if (expectedHash !== hash) {\n return {\n ok: false,\n phase: \"hash\",\n errors: [\n `Hash mismatch: client provided ${hash}, calculated ${expectedHash}`,\n ],\n };\n }\n\n const analysis: NamedAnalysis[] = Object.entries(bundles).map(\n ([name, bundle]) => ({\n name,\n ...analyzeHandler(bundle.code),\n }),\n );\n\n const blockers = analysis.flatMap((entry) =>\n entry.blockers.map((blocker) => `${blocker} in ${entry.name}`),\n );\n\n if (blockers.length > 0) {\n return {\n ok: false,\n phase: \"analysis\",\n blockers,\n errors: blockers.map((b) => `[Analysis Blocker] ${b}`),\n analysis,\n };\n }\n\n return { ok: true, analysis };\n}\n"],"mappings":"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","names":["access","rm","join","calculateAgentHash","join","rm","spinner","access"]}
|