@kalphq/cli 0.0.0-dev-20260510070528 → 0.0.0-dev-20260512045454

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.
Files changed (40) hide show
  1. package/dist/{chunk-RT2DIIQ5.js → chunk-5AEWO2OC.js} +104 -96
  2. package/dist/chunk-5AEWO2OC.js.map +1 -0
  3. package/dist/{chunk-WRCC37FP.js → chunk-MKVNPOVJ.js} +61 -7
  4. package/dist/chunk-MKVNPOVJ.js.map +1 -0
  5. package/dist/{create-QTVTQ6QL.js → create-WU5JH6FP.js} +13 -2
  6. package/dist/create-WU5JH6FP.js.map +1 -0
  7. package/dist/{deploy-YZ3OP2MN.js → deploy-FVOKQP6K.js} +3 -3
  8. package/dist/{dev-UC2WFSOE.js → dev-AHTXYEF2.js} +3 -4
  9. package/dist/dev-AHTXYEF2.js.map +1 -0
  10. package/dist/index.js +6 -5
  11. package/dist/index.js.map +1 -1
  12. package/dist/push-FIZZS6HQ.js +341 -0
  13. package/dist/push-FIZZS6HQ.js.map +1 -0
  14. package/dist/runtime-template/studio/assets/geist-cyrillic-wght-normal-CHSlOQsW.woff2 +0 -0
  15. package/dist/runtime-template/studio/assets/geist-latin-ext-wght-normal-DMtmJ5ZE.woff2 +0 -0
  16. package/dist/runtime-template/studio/assets/geist-latin-wght-normal-Dm3htQBi.woff2 +0 -0
  17. package/dist/runtime-template/studio/assets/geist-mono-cyrillic-wght-normal-BZdD_g9V.woff2 +0 -0
  18. package/dist/runtime-template/studio/assets/geist-mono-latin-ext-wght-normal-b6lpi8_2.woff2 +0 -0
  19. package/dist/runtime-template/studio/assets/geist-mono-latin-wght-normal-Cjtb1TV-.woff2 +0 -0
  20. package/dist/runtime-template/studio/assets/index-BHzMtWls.css +2 -0
  21. package/dist/runtime-template/studio/assets/index-rgoZQzco.js +112 -0
  22. package/dist/runtime-template/studio/index.html +2 -2
  23. package/dist/runtime-template/studio/mockServiceWorker.js +349 -0
  24. package/package.json +5 -4
  25. package/dist/chunk-RT2DIIQ5.js.map +0 -1
  26. package/dist/chunk-WRCC37FP.js.map +0 -1
  27. package/dist/create-QTVTQ6QL.js.map +0 -1
  28. package/dist/dev-UC2WFSOE.js.map +0 -1
  29. package/dist/push-XGNM2IEY.js +0 -263
  30. package/dist/push-XGNM2IEY.js.map +0 -1
  31. package/dist/runtime-template/studio/assets/index-D8vnrQHk.js +0 -112
  32. package/dist/runtime-template/studio/assets/index-GI30ROBZ.css +0 -2
  33. package/dist/runtime-template/studio/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  34. package/dist/runtime-template/studio/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  35. package/dist/runtime-template/studio/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  36. package/dist/runtime-template/studio/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  37. package/dist/runtime-template/studio/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  38. package/dist/runtime-template/studio/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  39. package/dist/runtime-template/studio/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  40. /package/dist/{deploy-YZ3OP2MN.js.map → deploy-FVOKQP6K.js.map} +0 -0
@@ -1,7 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- ensureGlobalConfigDir
4
- } from "./chunk-FO24J6XL.js";
5
2
 
6
3
  // src/utils/secret.ts
7
4
  import { randomBytes } from "crypto";
@@ -76,11 +73,38 @@ import { mkdir, readFile as readFile2, writeFile as writeFile2 } from "fs/promis
76
73
  import { join as join2 } from "path";
77
74
  var KALP_DIR = ".kalp";
78
75
  var STATE_FILE = "state.json";
76
+ function normalizeProjectState(raw) {
77
+ if (!raw || typeof raw !== "object") return null;
78
+ const value = raw;
79
+ const workerUrl = typeof value.workerUrl === "string" && value.workerUrl.length > 0 ? value.workerUrl : null;
80
+ const deployedAt = typeof value.deployedAt === "string" && value.deployedAt.length > 0 ? value.deployedAt : null;
81
+ const accountId = typeof value.accountId === "string" && value.accountId.length > 0 ? value.accountId : null;
82
+ const agents = {};
83
+ const rawAgents = value.agents && typeof value.agents === "object" ? value.agents : {};
84
+ for (const [name, entry] of Object.entries(rawAgents)) {
85
+ if (!entry || typeof entry !== "object") continue;
86
+ const item = entry;
87
+ if (typeof item.localPath !== "string" || item.localPath.length === 0) {
88
+ continue;
89
+ }
90
+ const currentVersion = typeof item.currentVersion === "number" && Number.isFinite(item.currentVersion) ? Math.max(0, Math.floor(item.currentVersion)) : 0;
91
+ agents[name] = {
92
+ currentHash: typeof item.currentHash === "string" ? item.currentHash : null,
93
+ currentVersion,
94
+ lastLocalHash: typeof item.lastLocalHash === "string" ? item.lastLocalHash : null,
95
+ lastRemoteHash: typeof item.lastRemoteHash === "string" ? item.lastRemoteHash : null,
96
+ lastPushedAt: typeof item.lastPushedAt === "string" ? item.lastPushedAt : null,
97
+ localPath: item.localPath,
98
+ workerUrl: typeof item.workerUrl === "string" ? item.workerUrl : null
99
+ };
100
+ }
101
+ return { workerUrl, deployedAt, accountId, agents };
102
+ }
79
103
  async function readProjectState(cwd) {
80
104
  try {
81
105
  const statePath = join2(cwd, KALP_DIR, STATE_FILE);
82
106
  const content = await readFile2(statePath, "utf-8");
83
- return JSON.parse(content);
107
+ return normalizeProjectState(JSON.parse(content));
84
108
  } catch {
85
109
  return null;
86
110
  }
@@ -88,33 +112,8 @@ async function readProjectState(cwd) {
88
112
  async function writeProjectState(cwd, state) {
89
113
  const dir = join2(cwd, KALP_DIR);
90
114
  await mkdir(dir, { recursive: true });
91
- await writeFile2(join2(dir, STATE_FILE), JSON.stringify(state, null, 2), "utf-8");
92
- }
93
-
94
- // src/utils/agent-store.ts
95
- import { readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
96
- import { join as join3 } from "path";
97
- async function getStorePath() {
98
- return join3(await ensureGlobalConfigDir(), "agents.json");
99
- }
100
- async function readAgentStore() {
101
- try {
102
- const storePath = await getStorePath();
103
- const content = await readFile3(storePath, "utf-8");
104
- return JSON.parse(content);
105
- } catch {
106
- return {};
107
- }
108
- }
109
- async function getAgentStoreEntry(agentName) {
110
- const store = await readAgentStore();
111
- return store[agentName] ?? null;
112
- }
113
- async function writeAgentStoreEntry(agentName, entry) {
114
- const storePath = await getStorePath();
115
- const store = await readAgentStore();
116
- store[agentName] = entry;
117
- await writeFile3(storePath, JSON.stringify(store, null, 2), "utf-8");
115
+ await writeFile2(join2(dir, STATE_FILE), `${JSON.stringify(state, null, 2)}
116
+ `, "utf-8");
118
117
  }
119
118
 
120
119
  // src/utils/runtime.ts
@@ -124,13 +123,14 @@ import {
124
123
  cp,
125
124
  mkdir as mkdir2,
126
125
  readdir,
127
- readFile as readFile4,
126
+ readFile as readFile3,
128
127
  rm,
129
128
  stat,
130
- writeFile as writeFile4
129
+ writeFile as writeFile3
131
130
  } from "fs/promises";
132
- import { basename, dirname, join as join4, normalize, resolve } from "path";
131
+ import { basename, dirname, join as join3, resolve } from "path";
133
132
  import { fileURLToPath } from "url";
133
+ import { deriveLabelFromName } from "@kalphq/project";
134
134
  var RUNTIME_ROOT = ".kalp";
135
135
  var RUNTIME_DIR = "runtime";
136
136
  var STUDIO_DIR = "studio";
@@ -142,9 +142,9 @@ function sanitizeSegment(input) {
142
142
  }
143
143
  async function resolveProjectSlug(cwd) {
144
144
  const fallback = sanitizeSegment(basename(cwd)) || "agent";
145
- const packageJsonPath = join4(cwd, "package.json");
145
+ const packageJsonPath = join3(cwd, "package.json");
146
146
  try {
147
- const content = await readFile4(packageJsonPath, "utf-8");
147
+ const content = await readFile3(packageJsonPath, "utf-8");
148
148
  const pkg = JSON.parse(content);
149
149
  const name = typeof pkg.name === "string" ? pkg.name : "";
150
150
  const sanitized = sanitizeSegment(name);
@@ -223,20 +223,20 @@ function runtimeTemplateCandidates() {
223
223
  );
224
224
  return [
225
225
  {
226
- studioTemplateDir: join4(distTemplateRoot, STUDIO_DIR),
227
- workerEntryPath: join4(distTemplateRoot, WORKER_ENTRY_FILE)
226
+ studioTemplateDir: join3(distTemplateRoot, STUDIO_DIR),
227
+ workerEntryPath: join3(distTemplateRoot, WORKER_ENTRY_FILE)
228
228
  },
229
229
  {
230
- studioTemplateDir: join4(packageRootTemplate, STUDIO_DIR),
231
- workerEntryPath: join4(packageRootTemplate, WORKER_ENTRY_FILE)
230
+ studioTemplateDir: join3(packageRootTemplate, STUDIO_DIR),
231
+ workerEntryPath: join3(packageRootTemplate, WORKER_ENTRY_FILE)
232
232
  },
233
233
  {
234
- studioTemplateDir: join4(sourceTemplateRoot, STUDIO_DIR),
235
- workerEntryPath: join4(sourceTemplateRoot, WORKER_ENTRY_FILE)
234
+ studioTemplateDir: join3(sourceTemplateRoot, STUDIO_DIR),
235
+ workerEntryPath: join3(sourceTemplateRoot, WORKER_ENTRY_FILE)
236
236
  },
237
237
  {
238
238
  studioTemplateDir: monorepoStudioDist,
239
- workerEntryPath: join4(sourceTemplateRoot, WORKER_ENTRY_FILE)
239
+ workerEntryPath: join3(sourceTemplateRoot, WORKER_ENTRY_FILE)
240
240
  }
241
241
  ];
242
242
  }
@@ -271,13 +271,13 @@ ${cssLinks}
271
271
  `;
272
272
  }
273
273
  async function ensureStudioIndex(studioDir) {
274
- const indexPath = join4(studioDir, "index.html");
274
+ const indexPath = join3(studioDir, "index.html");
275
275
  try {
276
276
  await access(indexPath);
277
277
  return;
278
278
  } catch {
279
279
  }
280
- const assetsDir = join4(studioDir, "assets");
280
+ const assetsDir = join3(studioDir, "assets");
281
281
  const assetFiles = await readdir(assetsDir);
282
282
  const entryScript = assetFiles.find((file) => /^index-.*\.js$/i.test(file)) ?? assetFiles.find((file) => file.endsWith(".js"));
283
283
  if (!entryScript) {
@@ -287,16 +287,16 @@ async function ensureStudioIndex(studioDir) {
287
287
  }
288
288
  const cssFiles = assetFiles.filter((file) => file.endsWith(".css")).sort();
289
289
  const html = createStudioShell(entryScript, cssFiles);
290
- await writeFile4(indexPath, html, "utf-8");
290
+ await writeFile3(indexPath, html, "utf-8");
291
291
  }
292
292
  async function readLocalAgentNames(cwd) {
293
- const agentsDir = join4(cwd, "agents");
293
+ const agentsDir = join3(cwd, "agents");
294
294
  try {
295
295
  const entries = await readdir(agentsDir, { withFileTypes: true });
296
296
  const names = [];
297
297
  for (const entry of entries) {
298
298
  if (!entry.isDirectory()) continue;
299
- const indexPath = join4(agentsDir, entry.name, "index.ts");
299
+ const indexPath = join3(agentsDir, entry.name, "index.ts");
300
300
  const exists = await stat(indexPath).then(() => true).catch(() => false);
301
301
  if (exists) names.push(entry.name);
302
302
  }
@@ -305,74 +305,83 @@ async function readLocalAgentNames(cwd) {
305
305
  return [];
306
306
  }
307
307
  }
308
- function isPathInsideProject(projectPath, candidatePath) {
309
- const project = normalize(projectPath).toLowerCase();
310
- const candidate = normalize(candidatePath).toLowerCase();
311
- return candidate.startsWith(project);
312
- }
313
- async function createAgentsSnapshot(cwd) {
308
+ async function createAgentsSnapshot(cwd, mode) {
314
309
  const localAgentNames = await readLocalAgentNames(cwd);
315
310
  const state = await readProjectState(cwd);
316
- const globalStore = await readAgentStore();
317
311
  const byName = /* @__PURE__ */ new Map();
312
+ const stateAgents = state?.agents ?? {};
318
313
  for (const name of localAgentNames) {
319
- const localPath = join4(cwd, "agents", name, "index.ts");
314
+ const localPath = join3(cwd, "agents", name, "index.ts");
315
+ const saved = stateAgents[name];
316
+ const hasRemoteVersion = !!saved?.lastRemoteHash && (saved?.currentVersion ?? 0) > 0;
317
+ if (mode === "remote" && !hasRemoteVersion) {
318
+ continue;
319
+ }
320
+ const resolvedWorkerUrl = saved?.workerUrl ?? (state?.workerUrl ? `${state.workerUrl.replace(/\/$/, "")}/a/${name}` : null);
321
+ const versionNumber = typeof saved?.currentVersion === "number" && saved.currentVersion > 0 ? saved.currentVersion : null;
320
322
  byName.set(name, {
321
323
  name,
322
- environment: "local",
323
- status: "offline",
324
- hash: null,
325
- workerUrl: null,
324
+ label: deriveLabelFromName(name),
325
+ tags: [],
326
+ environment: mode === "remote" ? "remote" : hasRemoteVersion ? "both" : "local",
327
+ status: resolvedWorkerUrl ? "online" : "offline",
328
+ hash: saved?.currentHash ?? null,
329
+ version: versionNumber ? `v${versionNumber}` : null,
330
+ versionNumber,
331
+ lastRemoteHash: saved?.lastRemoteHash ?? null,
332
+ lastLocalHash: saved?.lastLocalHash ?? null,
333
+ workerUrl: resolvedWorkerUrl,
326
334
  localPath,
327
- updatedAt: null
335
+ updatedAt: saved?.lastPushedAt ?? state?.deployedAt ?? null
328
336
  });
329
337
  }
330
- for (const [name, entry] of Object.entries(globalStore)) {
331
- if (!entry.localPath || !isPathInsideProject(cwd, entry.localPath)) continue;
332
- const existing = byName.get(name);
333
- const workerUrl = state?.workerUrl && !entry.workerUrl ? `${state.workerUrl.replace(/\/$/, "")}/a/${name}` : entry.workerUrl ?? null;
334
- byName.set(name, {
335
- name,
336
- environment: existing ? "both" : "remote",
337
- status: workerUrl ? "online" : "offline",
338
- hash: entry.hash ?? null,
339
- workerUrl,
340
- localPath: existing?.localPath ?? entry.localPath,
341
- updatedAt: entry.timestamp ?? state?.deployedAt ?? null
342
- });
343
- }
344
- if (state?.workerUrl) {
345
- for (const [name, record] of byName.entries()) {
346
- if (!record.workerUrl) {
347
- record.workerUrl = `${state.workerUrl.replace(/\/$/, "")}/a/${name}`;
348
- record.environment = record.environment === "local" ? "both" : record.environment;
349
- record.status = "online";
350
- record.updatedAt = record.updatedAt ?? state.deployedAt;
351
- byName.set(name, record);
352
- }
338
+ if (mode === "remote") {
339
+ for (const [name, saved] of Object.entries(stateAgents)) {
340
+ const hasRemoteVersion = !!saved.lastRemoteHash && (saved.currentVersion ?? 0) > 0;
341
+ if (!hasRemoteVersion || byName.has(name)) continue;
342
+ const localPath = saved.localPath ?? join3(cwd, "agents", name, "index.ts");
343
+ const workerUrl = saved.workerUrl ?? (state?.workerUrl ? `${state.workerUrl.replace(/\/$/, "")}/a/${name}` : null);
344
+ const versionNumber = saved.currentVersion > 0 ? saved.currentVersion : null;
345
+ byName.set(name, {
346
+ name,
347
+ label: deriveLabelFromName(name),
348
+ tags: [],
349
+ environment: "remote",
350
+ status: workerUrl ? "online" : "offline",
351
+ hash: saved.currentHash ?? null,
352
+ version: versionNumber ? `v${versionNumber}` : null,
353
+ versionNumber,
354
+ lastRemoteHash: saved.lastRemoteHash ?? null,
355
+ lastLocalHash: saved.lastLocalHash ?? null,
356
+ workerUrl,
357
+ localPath,
358
+ updatedAt: saved.lastPushedAt ?? state?.deployedAt ?? null
359
+ });
353
360
  }
354
361
  }
355
362
  return {
356
363
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
357
364
  projectPath: cwd,
358
365
  workerUrl: state?.workerUrl ?? null,
366
+ mode,
359
367
  agents: Array.from(byName.values()).sort((a, b) => a.name.localeCompare(b.name))
360
368
  };
361
369
  }
362
- async function materializeRuntime(cwd) {
363
- const runtimeDir = join4(cwd, RUNTIME_ROOT, RUNTIME_DIR);
364
- const studioDir = join4(runtimeDir, STUDIO_DIR);
365
- const workerEntrypointPath = join4(runtimeDir, WORKER_ENTRY_FILE);
366
- const wranglerConfigPath = join4(runtimeDir, WRANGLER_CONFIG_FILE);
370
+ async function materializeRuntime(cwd, options = {}) {
371
+ const mode = options.mode ?? "remote";
372
+ const runtimeDir = join3(cwd, RUNTIME_ROOT, RUNTIME_DIR);
373
+ const studioDir = join3(runtimeDir, STUDIO_DIR);
374
+ const workerEntrypointPath = join3(runtimeDir, WORKER_ENTRY_FILE);
375
+ const wranglerConfigPath = join3(runtimeDir, WRANGLER_CONFIG_FILE);
367
376
  const template = await resolveRuntimeTemplate();
368
377
  await rm(runtimeDir, { recursive: true, force: true });
369
378
  await mkdir2(runtimeDir, { recursive: true });
370
379
  await cp(template.studioTemplateDir, studioDir, { recursive: true });
371
380
  await cp(template.workerEntryPath, workerEntrypointPath);
372
381
  await ensureStudioIndex(studioDir);
373
- const agentsSnapshot = await createAgentsSnapshot(cwd);
374
- await writeFile4(
375
- join4(runtimeDir, "agents.snapshot.json"),
382
+ const agentsSnapshot = await createAgentsSnapshot(cwd, mode);
383
+ await writeFile3(
384
+ join3(runtimeDir, "agents.snapshot.json"),
376
385
  `${JSON.stringify(agentsSnapshot, null, 2)}
377
386
  `,
378
387
  "utf-8"
@@ -380,7 +389,7 @@ async function materializeRuntime(cwd) {
380
389
  const projectSlug = await resolveProjectSlug(cwd);
381
390
  const workerName = buildWorkerName(projectSlug, cwd);
382
391
  const wranglerConfig = createRuntimeConfig(workerName);
383
- await writeFile4(
392
+ await writeFile3(
384
393
  wranglerConfigPath,
385
394
  `${JSON.stringify(wranglerConfig, null, 2)}
386
395
  `,
@@ -400,8 +409,7 @@ export {
400
409
  ensureSecretKey,
401
410
  readProjectState,
402
411
  writeProjectState,
403
- getAgentStoreEntry,
404
- writeAgentStoreEntry,
412
+ readLocalAgentNames,
405
413
  materializeRuntime
406
414
  };
407
- //# sourceMappingURL=chunk-RT2DIIQ5.js.map
415
+ //# sourceMappingURL=chunk-5AEWO2OC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/secret.ts","../src/utils/project-state.ts","../src/utils/runtime.ts"],"sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nconst SECRET_KEY = \"KALP_SECRET_KEY\";\nconst STUDIO_PASSWORD = \"KALP_STUDIO_PASSWORD\";\nconst STUDIO_ADMIN_USER = \"KALP_STUDIO_ADMIN_USER\";\n\nfunction parseEnv(content: string): Record<string, string> {\n const result: Record<string, string> = {};\n for (const line of content.split(/\\r?\\n/g)) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const eqIndex = trimmed.indexOf(\"=\");\n if (eqIndex <= 0) continue;\n const key = trimmed.slice(0, eqIndex).trim();\n const value = trimmed.slice(eqIndex + 1).trim();\n result[key] = value;\n }\n return result;\n}\n\nfunction toEnvContent(values: Record<string, string>): string {\n const lines = [\n \"# Kalp Studio Authentication Secrets\",\n `${SECRET_KEY}=${values[SECRET_KEY]}`,\n `${STUDIO_PASSWORD}=${values[STUDIO_PASSWORD]}`,\n `${STUDIO_ADMIN_USER}=${values[STUDIO_ADMIN_USER]}`,\n \"\",\n ];\n return lines.join(\"\\n\");\n}\n\nasync function readEnvFile(cwd: string): Promise<string> {\n const envPath = join(cwd, \".env\");\n try {\n return await readFile(envPath, \"utf-8\");\n } catch {\n return \"\";\n }\n}\n\nfunction generateStudioPassword(): string {\n return randomBytes(24).toString(\"base64url\");\n}\n\nexport interface StudioSecrets {\n key: string;\n studioPassword: string;\n studioAdminUser: string;\n isNew: boolean;\n}\n\nexport async function ensureStudioSecrets(cwd: string): Promise<StudioSecrets> {\n const envPath = join(cwd, \".env\");\n const content = await readEnvFile(cwd);\n const parsed = parseEnv(content);\n\n const key = parsed[SECRET_KEY] || randomBytes(32).toString(\"hex\");\n const studioPassword = parsed[STUDIO_PASSWORD] || generateStudioPassword();\n const studioAdminUser = parsed[STUDIO_ADMIN_USER] || \"admin\";\n\n const isNew =\n !parsed[SECRET_KEY] || !parsed[STUDIO_PASSWORD] || !parsed[STUDIO_ADMIN_USER];\n\n if (isNew || !content.trim()) {\n await writeFile(\n envPath,\n toEnvContent({\n ...parsed,\n [SECRET_KEY]: key,\n [STUDIO_PASSWORD]: studioPassword,\n [STUDIO_ADMIN_USER]: studioAdminUser,\n }),\n \"utf-8\",\n );\n }\n\n return { key, studioPassword, studioAdminUser, isNew };\n}\n\nexport async function ensureSecretKey(\n cwd: string,\n): Promise<{ key: string; isNew: boolean }> {\n const secrets = await ensureStudioSecrets(cwd);\n return { key: secrets.key, isNew: secrets.isNew };\n}\n\nexport async function readSecretKey(cwd: string): Promise<string | null> {\n try {\n const envContent = await readEnvFile(cwd);\n const parsed = parseEnv(envContent);\n return parsed[SECRET_KEY] ?? null;\n } catch {\n return null;\n }\n}\n\nexport async function readStudioSecrets(cwd: string): Promise<{\n key: string;\n studioPassword: string;\n studioAdminUser: string;\n} | null> {\n try {\n const envContent = await readEnvFile(cwd);\n const parsed = parseEnv(envContent);\n const key = parsed[SECRET_KEY];\n const studioPassword = parsed[STUDIO_PASSWORD];\n const studioAdminUser = parsed[STUDIO_ADMIN_USER] || \"admin\";\n if (!key || !studioPassword) return null;\n return { key, studioPassword, studioAdminUser };\n } catch {\n return null;\n }\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nexport interface ProjectAgentState {\n currentHash: string | null;\n currentVersion: number;\n lastLocalHash: string | null;\n lastRemoteHash: string | null;\n lastPushedAt: string | null;\n localPath: string;\n workerUrl: string | null;\n}\n\nexport interface ProjectState {\n workerUrl: string | null;\n deployedAt: string | null;\n accountId: string | null;\n agents: Record<string, ProjectAgentState>;\n}\n\nconst KALP_DIR = \".kalp\";\nconst STATE_FILE = \"state.json\";\n\nfunction normalizeProjectState(raw: unknown): ProjectState | null {\n if (!raw || typeof raw !== \"object\") return null;\n const value = raw as Record<string, unknown>;\n const workerUrl =\n typeof value.workerUrl === \"string\" && value.workerUrl.length > 0\n ? value.workerUrl\n : null;\n const deployedAt =\n typeof value.deployedAt === \"string\" && value.deployedAt.length > 0\n ? value.deployedAt\n : null;\n const accountId =\n typeof value.accountId === \"string\" && value.accountId.length > 0\n ? value.accountId\n : null;\n\n const agents: Record<string, ProjectAgentState> = {};\n const rawAgents =\n value.agents && typeof value.agents === \"object\"\n ? (value.agents as Record<string, unknown>)\n : {};\n\n for (const [name, entry] of Object.entries(rawAgents)) {\n if (!entry || typeof entry !== \"object\") continue;\n const item = entry as Record<string, unknown>;\n if (typeof item.localPath !== \"string\" || item.localPath.length === 0) {\n continue;\n }\n\n const currentVersion =\n typeof item.currentVersion === \"number\" && Number.isFinite(item.currentVersion)\n ? Math.max(0, Math.floor(item.currentVersion))\n : 0;\n\n agents[name] = {\n currentHash: typeof item.currentHash === \"string\" ? item.currentHash : null,\n currentVersion,\n lastLocalHash: typeof item.lastLocalHash === \"string\" ? item.lastLocalHash : null,\n lastRemoteHash:\n typeof item.lastRemoteHash === \"string\" ? item.lastRemoteHash : null,\n lastPushedAt: typeof item.lastPushedAt === \"string\" ? item.lastPushedAt : null,\n localPath: item.localPath,\n workerUrl: typeof item.workerUrl === \"string\" ? item.workerUrl : null,\n };\n }\n\n return { workerUrl, deployedAt, accountId, agents };\n}\n\nexport async function readProjectState(cwd: string): Promise<ProjectState | null> {\n try {\n const statePath = join(cwd, KALP_DIR, STATE_FILE);\n const content = await readFile(statePath, \"utf-8\");\n return normalizeProjectState(JSON.parse(content));\n } catch {\n return null;\n }\n}\n\nexport async function writeProjectState(\n cwd: string,\n state: ProjectState,\n): Promise<void> {\n const dir = join(cwd, KALP_DIR);\n await mkdir(dir, { recursive: true });\n await writeFile(join(dir, STATE_FILE), `${JSON.stringify(state, null, 2)}\\n`, \"utf-8\");\n}\n","import { createHash } from \"node:crypto\";\nimport {\n access,\n cp,\n mkdir,\n readdir,\n readFile,\n rm,\n stat,\n writeFile,\n} from \"node:fs/promises\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { deriveLabelFromName } from \"@kalphq/project\";\nimport { readProjectState } from \"@/utils/project-state\";\n\nconst RUNTIME_ROOT = \".kalp\";\nconst RUNTIME_DIR = \"runtime\";\nconst STUDIO_DIR = \"studio\";\nconst WRANGLER_CONFIG_FILE = \"wrangler.jsonc\";\nconst WORKER_ENTRY_FILE = \"worker-entry.js\";\nconst COMPATIBILITY_DATE = \"2026-05-10\";\n\nexport interface RuntimePaths {\n runtimeDir: string;\n studioDir: string;\n workerEntrypointPath: string;\n wranglerConfigPath: string;\n workerName: string;\n}\n\ninterface RuntimeAgentRecord {\n name: string;\n label?: string;\n tags?: string[];\n environment: \"local\" | \"remote\" | \"both\";\n status: \"online\" | \"offline\";\n hash: string | null;\n version: string | null;\n versionNumber: number | null;\n lastRemoteHash: string | null;\n lastLocalHash: string | null;\n workerUrl: string | null;\n localPath: string | null;\n updatedAt: string | null;\n}\n\ninterface RuntimeAgentsSnapshot {\n generatedAt: string;\n projectPath: string;\n workerUrl: string | null;\n mode: \"local\" | \"remote\";\n agents: RuntimeAgentRecord[];\n}\n\nexport interface MaterializeRuntimeOptions {\n mode?: \"local\" | \"remote\";\n}\n\ninterface WranglerConfig {\n $schema: string;\n name: string;\n main: string;\n compatibility_date: string;\n compatibility_flags: string[];\n migrations: Array<{ tag: string; new_sqlite_classes: string[] }>;\n durable_objects: {\n bindings: Array<{ name: string; class_name: string }>;\n };\n kv_namespaces: Array<{ binding: string }>;\n assets: {\n directory: string;\n binding: string;\n run_worker_first: boolean;\n };\n observability: { enabled: boolean };\n upload_source_maps: boolean;\n secrets: { required: string[] };\n}\n\ninterface RuntimeTemplatePaths {\n studioTemplateDir: string;\n workerEntryPath: string;\n}\n\nfunction sanitizeSegment(input: string): string {\n return input\n .toLowerCase()\n .replace(/^@/, \"\")\n .replace(/\\//g, \"-\")\n .replace(/[^a-z0-9-]/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\n\nasync function resolveProjectSlug(cwd: string): Promise<string> {\n const fallback = sanitizeSegment(basename(cwd)) || \"agent\";\n const packageJsonPath = join(cwd, \"package.json\");\n\n try {\n const content = await readFile(packageJsonPath, \"utf-8\");\n const pkg = JSON.parse(content) as { name?: string };\n const name = typeof pkg.name === \"string\" ? pkg.name : \"\";\n const sanitized = sanitizeSegment(name);\n return sanitized || fallback;\n } catch {\n return fallback;\n }\n}\n\nfunction buildWorkerName(slug: string, cwd: string): string {\n const cwdHash = createHash(\"sha1\").update(cwd).digest(\"hex\").slice(0, 8);\n const withPrefix = `kalp-${slug}-${cwdHash}`;\n const maxLen = 63;\n if (withPrefix.length <= maxLen) {\n return withPrefix;\n }\n\n const clipped = withPrefix.slice(0, maxLen).replace(/-+$/g, \"\");\n return clipped || `kalp-${cwdHash}`;\n}\n\nfunction createRuntimeConfig(workerName: string): WranglerConfig {\n return {\n $schema: \"node_modules/wrangler/config-schema.json\",\n name: workerName,\n main: `./${WORKER_ENTRY_FILE}`,\n compatibility_date: COMPATIBILITY_DATE,\n compatibility_flags: [\"nodejs_compat\"],\n migrations: [\n {\n tag: \"v1\",\n new_sqlite_classes: [\"AgentDurableObject\"],\n },\n ],\n durable_objects: {\n bindings: [\n {\n name: \"KALP_RUNTIME_CLOUDFLARE\",\n class_name: \"AgentDurableObject\",\n },\n ],\n },\n kv_namespaces: [\n {\n binding: \"KALP_MANIFESTS\",\n },\n ],\n assets: {\n directory: `./${STUDIO_DIR}`,\n binding: \"ASSETS\",\n run_worker_first: true,\n },\n observability: { enabled: true },\n upload_source_maps: true,\n secrets: {\n required: [\n \"KALP_SECRET_KEY\",\n \"KALP_STUDIO_PASSWORD\",\n \"KALP_STUDIO_ADMIN_USER\",\n ],\n },\n };\n}\n\nfunction runtimeTemplateCandidates(): Array<{\n studioTemplateDir: string;\n workerEntryPath: string;\n}> {\n const here = dirname(fileURLToPath(import.meta.url));\n const distTemplateRoot = resolve(here, \"runtime-template\");\n const packageRootTemplate = resolve(here, \"..\", \"runtime-template\");\n const sourceTemplateRoot = resolve(here, \"..\", \"..\", \"runtime-template\");\n const monorepoStudioDist = resolve(\n here,\n \"..\",\n \"..\",\n \"..\",\n \"..\",\n \"apps\",\n \"studio\",\n \"dist\",\n \"client\",\n );\n\n return [\n {\n studioTemplateDir: join(distTemplateRoot, STUDIO_DIR),\n workerEntryPath: join(distTemplateRoot, WORKER_ENTRY_FILE),\n },\n {\n studioTemplateDir: join(packageRootTemplate, STUDIO_DIR),\n workerEntryPath: join(packageRootTemplate, WORKER_ENTRY_FILE),\n },\n {\n studioTemplateDir: join(sourceTemplateRoot, STUDIO_DIR),\n workerEntryPath: join(sourceTemplateRoot, WORKER_ENTRY_FILE),\n },\n {\n studioTemplateDir: monorepoStudioDist,\n workerEntryPath: join(sourceTemplateRoot, WORKER_ENTRY_FILE),\n },\n ];\n}\n\nasync function resolveRuntimeTemplate(): Promise<RuntimeTemplatePaths> {\n for (const candidate of runtimeTemplateCandidates()) {\n try {\n await access(candidate.studioTemplateDir);\n await access(candidate.workerEntryPath);\n return candidate;\n } catch {\n // continue\n }\n }\n\n throw new Error(\n \"Kalp runtime template not found in CLI package. Reinstall @kalphq/cli.\",\n );\n}\n\nfunction createStudioShell(entryScript: string, cssFiles: string[]): string {\n const cssLinks = cssFiles\n .map((file) => ` <link rel=\"stylesheet\" href=\"/studio/assets/${file}\" />`)\n .join(\"\\n\");\n\n return `<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>Kalp Studio</title>\n${cssLinks}\n </head>\n <body>\n <div id=\"root\"></div>\n <script type=\"module\" src=\"/studio/assets/${entryScript}\"></script>\n </body>\n</html>\n`;\n}\n\nasync function ensureStudioIndex(studioDir: string): Promise<void> {\n const indexPath = join(studioDir, \"index.html\");\n try {\n await access(indexPath);\n return;\n } catch {\n // index.html is missing on some TanStack Start static builds.\n }\n\n const assetsDir = join(studioDir, \"assets\");\n const assetFiles = await readdir(assetsDir);\n const entryScript =\n assetFiles.find((file) => /^index-.*\\.js$/i.test(file)) ??\n assetFiles.find((file) => file.endsWith(\".js\"));\n\n if (!entryScript) {\n throw new Error(\n \"Studio runtime template is missing an entry JS bundle in studio/assets.\",\n );\n }\n\n const cssFiles = assetFiles.filter((file) => file.endsWith(\".css\")).sort();\n const html = createStudioShell(entryScript, cssFiles);\n await writeFile(indexPath, html, \"utf-8\");\n}\n\nexport async function readLocalAgentNames(cwd: string): Promise<string[]> {\n const agentsDir = join(cwd, \"agents\");\n try {\n const entries = await readdir(agentsDir, { withFileTypes: true });\n const names: string[] = [];\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const indexPath = join(agentsDir, entry.name, \"index.ts\");\n const exists = await stat(indexPath)\n .then(() => true)\n .catch(() => false);\n if (exists) names.push(entry.name);\n }\n return names.sort((a, b) => a.localeCompare(b));\n } catch {\n return [];\n }\n}\n\nasync function createAgentsSnapshot(\n cwd: string,\n mode: \"local\" | \"remote\",\n): Promise<RuntimeAgentsSnapshot> {\n const localAgentNames = await readLocalAgentNames(cwd);\n const state = await readProjectState(cwd);\n\n const byName = new Map<string, RuntimeAgentRecord>();\n const stateAgents = state?.agents ?? {};\n\n for (const name of localAgentNames) {\n const localPath = join(cwd, \"agents\", name, \"index.ts\");\n const saved = stateAgents[name];\n const hasRemoteVersion = !!saved?.lastRemoteHash && (saved?.currentVersion ?? 0) > 0;\n\n if (mode === \"remote\" && !hasRemoteVersion) {\n continue;\n }\n\n const resolvedWorkerUrl =\n saved?.workerUrl ??\n (state?.workerUrl ? `${state.workerUrl.replace(/\\/$/, \"\")}/a/${name}` : null);\n const versionNumber =\n typeof saved?.currentVersion === \"number\" && saved.currentVersion > 0\n ? saved.currentVersion\n : null;\n\n byName.set(name, {\n name,\n label: deriveLabelFromName(name),\n tags: [],\n environment:\n mode === \"remote\"\n ? \"remote\"\n : hasRemoteVersion\n ? \"both\"\n : \"local\",\n status: resolvedWorkerUrl ? \"online\" : \"offline\",\n hash: saved?.currentHash ?? null,\n version: versionNumber ? `v${versionNumber}` : null,\n versionNumber,\n lastRemoteHash: saved?.lastRemoteHash ?? null,\n lastLocalHash: saved?.lastLocalHash ?? null,\n workerUrl: resolvedWorkerUrl,\n localPath,\n updatedAt: saved?.lastPushedAt ?? state?.deployedAt ?? null,\n });\n }\n\n if (mode === \"remote\") {\n for (const [name, saved] of Object.entries(stateAgents)) {\n const hasRemoteVersion =\n !!saved.lastRemoteHash && (saved.currentVersion ?? 0) > 0;\n if (!hasRemoteVersion || byName.has(name)) continue;\n\n const localPath = saved.localPath ?? join(cwd, \"agents\", name, \"index.ts\");\n const workerUrl =\n saved.workerUrl ??\n (state?.workerUrl ? `${state.workerUrl.replace(/\\/$/, \"\")}/a/${name}` : null);\n const versionNumber = saved.currentVersion > 0 ? saved.currentVersion : null;\n\n byName.set(name, {\n name,\n label: deriveLabelFromName(name),\n tags: [],\n environment: \"remote\",\n status: workerUrl ? \"online\" : \"offline\",\n hash: saved.currentHash ?? null,\n version: versionNumber ? `v${versionNumber}` : null,\n versionNumber,\n lastRemoteHash: saved.lastRemoteHash ?? null,\n lastLocalHash: saved.lastLocalHash ?? null,\n workerUrl,\n localPath,\n updatedAt: saved.lastPushedAt ?? state?.deployedAt ?? null,\n });\n }\n }\n\n return {\n generatedAt: new Date().toISOString(),\n projectPath: cwd,\n workerUrl: state?.workerUrl ?? null,\n mode,\n agents: Array.from(byName.values()).sort((a, b) => a.name.localeCompare(b.name)),\n };\n}\n\nexport async function materializeRuntime(\n cwd: string,\n options: MaterializeRuntimeOptions = {},\n): Promise<RuntimePaths> {\n const mode = options.mode ?? \"remote\";\n const runtimeDir = join(cwd, RUNTIME_ROOT, RUNTIME_DIR);\n const studioDir = join(runtimeDir, STUDIO_DIR);\n const workerEntrypointPath = join(runtimeDir, WORKER_ENTRY_FILE);\n const wranglerConfigPath = join(runtimeDir, WRANGLER_CONFIG_FILE);\n\n const template = await resolveRuntimeTemplate();\n await rm(runtimeDir, { recursive: true, force: true });\n await mkdir(runtimeDir, { recursive: true });\n\n await cp(template.studioTemplateDir, studioDir, { recursive: true });\n await cp(template.workerEntryPath, workerEntrypointPath);\n await ensureStudioIndex(studioDir);\n const agentsSnapshot = await createAgentsSnapshot(cwd, mode);\n await writeFile(\n join(runtimeDir, \"agents.snapshot.json\"),\n `${JSON.stringify(agentsSnapshot, null, 2)}\\n`,\n \"utf-8\",\n );\n\n const projectSlug = await resolveProjectSlug(cwd);\n const workerName = buildWorkerName(projectSlug, cwd);\n const wranglerConfig = createRuntimeConfig(workerName);\n await writeFile(\n wranglerConfigPath,\n `${JSON.stringify(wranglerConfig, null, 2)}\\n`,\n \"utf-8\",\n );\n\n return {\n runtimeDir,\n studioDir,\n workerEntrypointPath,\n wranglerConfigPath,\n workerName,\n };\n}\n"],"mappings":"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","names":["readFile","writeFile","join","mkdir","readFile","writeFile","join","join","readFile","writeFile","mkdir"]}
@@ -2,21 +2,63 @@
2
2
  import {
3
3
  ensureStudioSecrets,
4
4
  materializeRuntime,
5
+ readProjectState,
5
6
  writeProjectState
6
- } from "./chunk-RT2DIIQ5.js";
7
+ } from "./chunk-5AEWO2OC.js";
7
8
  import {
8
9
  requireAuth
9
10
  } from "./chunk-5RODADXW.js";
10
11
 
11
12
  // src/utils/deploy.ts
12
- import { readFile, writeFile } from "fs/promises";
13
+ import { readFile as readFile2, writeFile } from "fs/promises";
13
14
  import { execa } from "execa";
15
+
16
+ // src/utils/ai.ts
17
+ import { access, readFile } from "fs/promises";
18
+ import { constants } from "fs";
19
+ import { join } from "path";
20
+ import { createJiti } from "jiti";
21
+ var PROVIDER_SECRET_MAP = {
22
+ openai: "OPENAI_API_KEY",
23
+ anthropic: "ANTHROPIC_API_KEY",
24
+ openrouter: "OPENROUTER_API_KEY",
25
+ custom: "CUSTOM_AI_API_KEY"
26
+ };
27
+ function parseEnv(content) {
28
+ const env = {};
29
+ for (const raw of content.split(/\r?\n/g)) {
30
+ const line = raw.trim();
31
+ if (!line || line.startsWith("#")) continue;
32
+ const idx = line.indexOf("=");
33
+ if (idx <= 0) continue;
34
+ env[line.slice(0, idx).trim()] = line.slice(idx + 1);
35
+ }
36
+ return env;
37
+ }
38
+ async function resolveProviderFromConfig(cwd) {
39
+ const configPath = join(cwd, "kalp.config.ts");
40
+ await access(configPath, constants.F_OK);
41
+ const jiti = createJiti(cwd, { interopDefault: true });
42
+ const config = await jiti.import(configPath);
43
+ const provider = config?.default?.ai?.provider ?? config?.ai?.provider ?? "openai";
44
+ return provider;
45
+ }
46
+ async function readDotEnv(cwd) {
47
+ const envPath = join(cwd, ".env");
48
+ const content = await readFile(envPath, "utf-8").catch(() => "");
49
+ return parseEnv(content);
50
+ }
51
+ function getRequiredSecretForProvider(provider) {
52
+ return PROVIDER_SECRET_MAP[provider];
53
+ }
54
+
55
+ // src/utils/deploy.ts
14
56
  function findWorkersUrl(output) {
15
57
  const match = output.match(/https:\/\/[^\s]+\.workers\.dev/);
16
58
  return match?.[0] ?? null;
17
59
  }
18
60
  async function readWranglerConfig(configPath) {
19
- const text = await readFile(configPath, "utf-8");
61
+ const text = await readFile2(configPath, "utf-8");
20
62
  return JSON.parse(text);
21
63
  }
22
64
  async function writeWranglerConfig(configPath, config) {
@@ -82,7 +124,7 @@ function isNamespaceAlreadyExistsError(output) {
82
124
  async function resolveWorkerUrl(configPath, deployOutput) {
83
125
  const fromOutput = findWorkersUrl(deployOutput);
84
126
  if (fromOutput) return fromOutput;
85
- const configText = await readFile(configPath, "utf-8").catch(
127
+ const configText = await readFile2(configPath, "utf-8").catch(
86
128
  () => null
87
129
  );
88
130
  const workerName = configText?.match(/"name"\s*:\s*"([^"]+)"/)?.[1];
@@ -93,13 +135,23 @@ async function resolveWorkerUrl(configPath, deployOutput) {
93
135
  }
94
136
  async function runInitialDeploy(cwd) {
95
137
  const auth = await requireAuth();
138
+ const provider = await resolveProviderFromConfig(cwd);
139
+ const requiredProviderSecret = getRequiredSecretForProvider(provider);
140
+ const envMap = await readDotEnv(cwd);
141
+ const providerSecretValue = envMap[requiredProviderSecret]?.trim();
142
+ if (!providerSecretValue) {
143
+ throw new Error(
144
+ `Missing required secret ${requiredProviderSecret} for provider "${provider}". Add it to .env before deploy.`
145
+ );
146
+ }
96
147
  const secrets = await ensureStudioSecrets(cwd);
97
148
  const runtime = await materializeRuntime(cwd);
98
149
  let secretSyncFailed = false;
99
150
  const secretEntries = [
100
151
  ["KALP_SECRET_KEY", secrets.key],
101
152
  ["KALP_STUDIO_PASSWORD", secrets.studioPassword],
102
- ["KALP_STUDIO_ADMIN_USER", secrets.studioAdminUser]
153
+ ["KALP_STUDIO_ADMIN_USER", secrets.studioAdminUser],
154
+ [requiredProviderSecret, providerSecretValue]
103
155
  ];
104
156
  for (const [name, value] of secretEntries) {
105
157
  try {
@@ -140,10 +192,12 @@ async function runInitialDeploy(cwd) {
140
192
  runtime.wranglerConfigPath,
141
193
  deployStdout
142
194
  );
195
+ const existingState = await readProjectState(cwd);
143
196
  await writeProjectState(cwd, {
144
197
  workerUrl,
145
198
  deployedAt: (/* @__PURE__ */ new Date()).toISOString(),
146
- accountId: auth.accountId
199
+ accountId: auth.accountId,
200
+ agents: existingState?.agents ?? {}
147
201
  });
148
202
  return { workerUrl, accountId: auth.accountId };
149
203
  }
@@ -151,4 +205,4 @@ async function runInitialDeploy(cwd) {
151
205
  export {
152
206
  runInitialDeploy
153
207
  };
154
- //# sourceMappingURL=chunk-WRCC37FP.js.map
208
+ //# sourceMappingURL=chunk-MKVNPOVJ.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\";\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"]}
@@ -13,6 +13,7 @@ import { scaffoldAgent } from "@kalphq/project";
13
13
 
14
14
  // src/utils/ui.ts
15
15
  import * as p from "@clack/prompts";
16
+ import { deriveLabelFromName } from "@kalphq/project";
16
17
  async function promptTemplateSelection() {
17
18
  const answer = await p.select({
18
19
  message: "Choose an agent template:",
@@ -55,7 +56,15 @@ async function promptAgentDetails(opts) {
55
56
  }),
56
57
  ...opts?.includeTemplate && {
57
58
  template: () => promptTemplateSelection()
58
- }
59
+ },
60
+ label: ({ results }) => p.text({
61
+ message: "Agent label? (display name)",
62
+ placeholder: deriveLabelFromName(results.name),
63
+ initialValue: deriveLabelFromName(results.name),
64
+ validate: (v) => {
65
+ if (!v.trim()) return "Agent label is required.";
66
+ }
67
+ })
59
68
  },
60
69
  {
61
70
  onCancel: () => {
@@ -66,6 +75,7 @@ async function promptAgentDetails(opts) {
66
75
  );
67
76
  return {
68
77
  name: answers.name,
78
+ label: answers.label,
69
79
  template: answers.template
70
80
  };
71
81
  }
@@ -102,6 +112,7 @@ var create_default = defineCommand({
102
112
  s.start(`Scaffolding agent ${pc.cyan(agentAnswers.name)}`);
103
113
  await scaffoldAgent({
104
114
  agentName: agentAnswers.name,
115
+ label: agentAnswers.label,
105
116
  cwd,
106
117
  template: agentAnswers.template
107
118
  });
@@ -127,4 +138,4 @@ var create_default = defineCommand({
127
138
  export {
128
139
  create_default as default
129
140
  };
130
- //# sourceMappingURL=create-QTVTQ6QL.js.map
141
+ //# sourceMappingURL=create-WU5JH6FP.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 });\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,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runInitialDeploy
4
- } from "./chunk-WRCC37FP.js";
5
- import "./chunk-RT2DIIQ5.js";
4
+ } from "./chunk-MKVNPOVJ.js";
5
+ import "./chunk-5AEWO2OC.js";
6
6
  import {
7
7
  requireAuth
8
8
  } from "./chunk-5RODADXW.js";
@@ -60,4 +60,4 @@ var deploy_default = defineCommand({
60
60
  export {
61
61
  deploy_default as default
62
62
  };
63
- //# sourceMappingURL=deploy-YZ3OP2MN.js.map
63
+ //# sourceMappingURL=deploy-FVOKQP6K.js.map