@kalphq/cli 0.0.0-dev-20260508055746 โ†’ 0.0.0-dev-20260509012111

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/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-20260508055746",
11
+ version: "0.0.0-dev-20260509012111",
12
12
  description: "Zero-config CLI for deploying Kalp agents",
13
13
  type: "module",
14
14
  license: "MIT",
@@ -37,7 +37,9 @@ var package_default = {
37
37
  "@kalphq/sdk": "workspace:*",
38
38
  citty: "0.1.6",
39
39
  esbuild: "0.25.0",
40
+ jose: "^5.10.0",
40
41
  "json-stable-stringify": "1.3.0",
42
+ open: "^11.0.0",
41
43
  picocolors: "1.1.1",
42
44
  zod: "3.25.76"
43
45
  },
@@ -57,7 +59,8 @@ var COMMANDS = [
57
59
  ["link", "Link project to Kalp cloud"],
58
60
  ["secrets", "Manage secrets"],
59
61
  ["login", "Authenticate with Kalp"],
60
- ["logout", "Sign out from Kalp"]
62
+ ["logout", "Sign out from Kalp"],
63
+ ["studio", "Open Kalp Studio"]
61
64
  ];
62
65
  function printHelp() {
63
66
  p.log.info(`${pc.bold("Usage")}: kalp <command> [options]`);
@@ -85,11 +88,12 @@ var main = defineCommand({
85
88
  },
86
89
  subCommands: {
87
90
  create: () => import("./create-QTVTQ6QL.js").then((r) => r.default),
88
- push: () => import("./push-AR5R7BS6.js").then((r) => r.default),
91
+ push: () => import("./push-UZADV7TZ.js").then((r) => r.default),
89
92
  link: () => import("./link-WZQSR2TM.js").then((r) => r.default),
90
93
  secrets: () => import("./secrets-KFMVBKJQ.js").then((r) => r.default),
91
94
  login: () => import("./login-JYPWGL6P.js").then((r) => r.default),
92
- logout: () => import("./logout-V67DZZXO.js").then((r) => r.default)
95
+ logout: () => import("./logout-V67DZZXO.js").then((r) => r.default),
96
+ studio: () => import("./studio-SSJ27ZHR.js").then((r) => r.default)
93
97
  },
94
98
  run({ args }) {
95
99
  const firstArg = process.argv[2];
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 [\"push\", \"Push agent to Kalp\"],\n [\"link\", \"Link project to Kalp cloud\"],\n [\"secrets\", \"Manage secrets\"],\n [\"login\", \"Authenticate with Kalp\"],\n [\"logout\", \"Sign out from Kalp\"],\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 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 },\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-20260508055746\",\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\",\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 \"json-stable-stringify\": \"1.3.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":";;;AAAA,SAAS,eAAe,eAAe;AACvC,YAAY,OAAO;AACnB,OAAO,QAAQ;;;ACFf;AAAA,EACE,MAAQ;AAAA,EACR,SAAW;AAAA,EACX,aAAe;AAAA,EACf,MAAQ;AAAA,EACR,SAAW;AAAA,EACX,QAAU;AAAA,EACV,KAAO;AAAA,IACL,MAAQ;AAAA,EACV;AAAA,EACA,MAAQ;AAAA,EACR,OAAS;AAAA,IACP;AAAA,EACF;AAAA,EACA,eAAiB;AAAA,IACf,QAAU;AAAA,EACZ;AAAA,EACA,SAAW;AAAA,IACT,OAAS;AAAA,IACT,KAAO;AAAA,IACP,MAAQ;AAAA,IACR,gBAAkB;AAAA,EACpB;AAAA,EACA,cAAgB;AAAA,IACd,aAAa;AAAA,IACb,kBAAkB;AAAA,IAClB,oBAAoB;AAAA,IACpB,mBAAmB;AAAA,IACnB,eAAe;AAAA,IACf,OAAS;AAAA,IACT,SAAW;AAAA,IACX,yBAAyB;AAAA,IACzB,YAAc;AAAA,IACd,KAAO;AAAA,EACT;AAAA,EACA,iBAAmB;AAAA,IACjB,gCAAgC;AAAA,IAChC,eAAe;AAAA,IACf,MAAQ;AAAA,IACR,YAAc;AAAA,EAChB;AACF;;;ADpCA,IAAM,OAAO;AAEb,IAAM,WAAW;AAAA,EACf,CAAC,UAAU,iBAAiB;AAAA,EAC5B,CAAC,QAAQ,oBAAoB;AAAA,EAC7B,CAAC,QAAQ,4BAA4B;AAAA,EACrC,CAAC,WAAW,gBAAgB;AAAA,EAC5B,CAAC,SAAS,wBAAwB;AAAA,EAClC,CAAC,UAAU,oBAAoB;AACjC;AAEA,SAAS,YAAkB;AACzB,EAAE,MAAI,KAAK,GAAG,GAAG,KAAK,OAAO,CAAC,4BAA4B;AAC1D,UAAQ,IAAI,EAAE;AACd,EAAE,MAAI,KAAK,GAAG,KAAK,UAAU,CAAC;AAE9B,aAAW,CAAC,MAAM,IAAI,KAAK,UAAU;AACnC,YAAQ,IAAI,KAAK,GAAG,KAAK,KAAK,OAAO,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE;AAAA,EACpD;AAEA,UAAQ,IAAI,EAAE;AACd,EAAE,MAAI,KAAK,OAAO,GAAG,KAAK,uBAAuB,CAAC,iBAAiB;AACrE;AAEA,IAAM,OAAO,cAAc;AAAA,EACzB,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,gBAAI;AAAA,IACb,aAAa;AAAA,EACf;AAAA,EACA,MAAM;AAAA,IACJ,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EACA,aAAa;AAAA,IACX,QAAQ,MAAM,OAAO,sBAAmB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAC/D,MAAM,MAAM,OAAO,oBAAiB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAC3D,MAAM,MAAM,OAAO,oBAAiB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAC3D,SAAS,MAAM,OAAO,uBAAoB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IACjE,OAAO,MAAM,OAAO,qBAAkB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAC7D,QAAQ,MAAM,OAAO,sBAAmB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EACjE;AAAA,EACA,IAAI,EAAE,KAAK,GAAG;AACZ,UAAM,WAAW,QAAQ,KAAK,CAAC;AAE/B,QAAI,KAAK,MAAM;AACb,MAAE,QAAM,GAAG,IAAI,IAAI,GAAG,KAAK,MAAM,CAAC,EAAE;AACpC,gBAAU;AACV,MAAE,QAAM,wBAAiB;AACzB;AAAA,IACF;AAEA,QAAI,UAAU;AACZ;AAAA,IACF;AAEA,IAAE,QAAM,GAAG,IAAI,IAAI,GAAG,KAAK,MAAM,CAAC,EAAE;AACpC,cAAU;AACV,IAAE,QAAM,wBAAiB;AAAA,EAC3B;AACF,CAAC;AAED,QAAQ,IAAI;","names":[]}
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 [\"push\", \"Push agent to Kalp\"],\n [\"link\", \"Link project to Kalp cloud\"],\n [\"secrets\", \"Manage secrets\"],\n [\"login\", \"Authenticate with Kalp\"],\n [\"logout\", \"Sign out from Kalp\"],\n [\"studio\", \"Open Kalp Studio\"],\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 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 studio: () => import(\"./commands/studio\").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-20260509012111\",\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\",\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 \"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":[]}
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-INB3LG6O.js";
5
5
 
6
6
  // src/commands/push.ts
7
- import { access as access2 } from "fs/promises";
7
+ import { access as access2, mkdir, writeFile, readFile as readFile2 } from "fs/promises";
8
8
  import { join as join2 } from "path";
9
9
  import { defineCommand } from "citty";
10
10
  import * as p2 from "@clack/prompts";
@@ -184,13 +184,31 @@ var push_default = defineCommand({
184
184
  return;
185
185
  }
186
186
  s.start(`Pushing to cloud`);
187
+ let secretKey;
188
+ try {
189
+ const envPath = join2(cwd, ".env");
190
+ const envContent = await readFile2(envPath, "utf-8");
191
+ const match = envContent.match(/^KALP_SECRET_KEY=(.+)$/m);
192
+ if (match && match[1]) {
193
+ secretKey = match[1].trim();
194
+ }
195
+ } catch {
196
+ }
197
+ if (!secretKey) {
198
+ p2.log.warning(
199
+ "KALP_SECRET_KEY not found in .env. Studio authentication will not work."
200
+ );
201
+ p2.note("Run 'kalp studio' to generate a new secret.", "Action");
202
+ }
187
203
  const response = await fetch(`http://localhost:3000/api/agents/push`, {
188
204
  method: "POST",
189
205
  headers: { "Content-Type": "application/json" },
190
206
  body: JSON.stringify({
191
207
  agentName,
192
208
  ir: manifest.ir,
193
- hash
209
+ hash,
210
+ secretKey
211
+ // Send secret for injection into Cloudflare
194
212
  })
195
213
  });
196
214
  const body = await response.json().catch(() => null);
@@ -213,6 +231,19 @@ var push_default = defineCommand({
213
231
  );
214
232
  s.stop(pc.green("Pushed successfully"));
215
233
  printPushResult(agentName, hash, displayHandlers);
234
+ const kalpDir = join2(cwd, ".kalp");
235
+ await mkdir(kalpDir, { recursive: true });
236
+ const stateData = {
237
+ agentName,
238
+ workerUrl: `http://localhost:3000/a/${agentName}`,
239
+ lastPush: (/* @__PURE__ */ new Date()).toISOString(),
240
+ hash
241
+ };
242
+ await writeFile(
243
+ join2(kalpDir, "state.json"),
244
+ JSON.stringify(stateData, null, 2),
245
+ "utf-8"
246
+ );
216
247
  const dashboardUrl = `http://localhost:3000/a/${agentName}`;
217
248
  p2.outro(`${LOGO} ${pc.green("Agent live at")} ${pc.cyan(dashboardUrl)}`);
218
249
  process.exit(0);
@@ -221,4 +252,4 @@ var push_default = defineCommand({
221
252
  export {
222
253
  push_default as default
223
254
  };
224
- //# sourceMappingURL=push-AR5R7BS6.js.map
255
+ //# sourceMappingURL=push-UZADV7TZ.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/issues.ts"],"sourcesContent":["import { access, mkdir, writeFile, readFile } 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 { renderLegacyError } from \"@/utils/issues\";\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 printPushResult(\n agentName: string,\n hash: string,\n handlers: Record<string, { size: number }>,\n) {\n const div = pc.dim(\"โ”€\".repeat(48));\n const handlerCount = Object.keys(handlers).length;\n const totalSize = Object.values(handlers).reduce((sum, h) => sum + h.size, 0);\n\n console.log(\"\\n\" + div);\n console.log(pc.green(\"โœ” Deployed\"));\n console.log(\"\");\n console.log(` ${pc.bold(agentName)} ${pc.dim(hash.slice(0, 7))}...`);\n console.log(\n ` ${pc.dim(String(handlerCount))} handlers ยท ${formatBytes(totalSize)}`,\n );\n console.log(div + \"\\n\");\n}\n\nfunction printPushError(\n phase: string,\n errors: string[],\n blockers?: string[],\n verbose?: boolean,\n) {\n const div = pc.dim(\"โ”€\".repeat(48));\n console.log(\"\\n\" + div);\n\n for (const e of errors) {\n console.log(renderLegacyError(e, verbose));\n console.log(\"\");\n }\n\n if (phase === \"analysis\" && blockers) {\n for (const b of blockers) {\n console.log(pc.red(`โœ˜ Blocker: ${b}`));\n }\n }\n\n if (!verbose) {\n console.log(pc.dim(`\\nRun with --verbose for more details.\\n`));\n }\n\n console.log(div + \"\\n\");\n}\n\nexport default defineCommand({\n meta: { name: \"push\", description: \"Push agent to Kalp cloud\" },\n args: {\n agent: {\n type: \"string\",\n alias: \"a\",\n description: \"Agent name to push\",\n required: false,\n },\n verbose: {\n type: \"boolean\",\n alias: \"v\",\n description: \"Show debug information\",\n default: false,\n },\n },\n async run({ args }) {\n const cwd = process.cwd();\n const agentName = args.agent;\n\n p.intro(`${LOGO} ${pc.bold(\"kalp push\")}`);\n\n if (!agentName) {\n p.log.error(`Missing required flag ${pc.cyan(\"-a <agent-name>\")}`);\n process.exit(1);\n }\n\n try {\n await ensureConfig(cwd);\n } catch {\n p.log.error(`${pc.cyan(\"kalp.config.ts\")} not found`);\n process.exit(1);\n }\n\n const agentPath = join(cwd, \"agents\", agentName, \"index.ts\");\n try {\n await access(agentPath);\n } catch {\n p.log.error(`Agent ${pc.cyan(agentName)} not found`);\n process.exit(1);\n }\n\n const s = p.spinner();\n s.start(`Compiling ${pc.cyan(agentName)}`);\n\n const manifest = await readAgentManifest({ cwd, agentName });\n\n const bundles = (manifest.ir.bundles || {}) as Record<\n string,\n { code: string }\n >;\n const handlerCount = Object.keys(bundles).length;\n\n const hash = computePushHash(manifest.ir);\n\n s.stop(`Compiled ${pc.cyan(agentName)} โ€” ${handlerCount} handlers`);\n\n s.start(`Checking for changes`);\n\n const statusResponse = await fetch(\n `http://localhost:3000/api/agents/${agentName}/status`,\n );\n\n const statusData = (await statusResponse.json().catch(() => null)) as {\n agentName: string;\n hash?: string;\n exists: boolean;\n } | null;\n\n if (statusData?.exists && statusData.hash === hash) {\n s.stop(pc.green(\"No changes detected\"));\n p.note(\n `Agent ${pc.cyan(agentName)} is already deployed with the same logic.`,\n \"Skipped\",\n );\n p.outro(`${LOGO} ${pc.green(\"No deployment needed\")}`);\n return;\n }\n\n s.start(`Pushing to cloud`);\n\n // Read KALP_SECRET_KEY from .env local\n let secretKey: string | undefined;\n try {\n const envPath = join(cwd, \".env\");\n const envContent = await readFile(envPath, \"utf-8\");\n const match = envContent.match(/^KALP_SECRET_KEY=(.+)$/m);\n if (match && match[1]) {\n secretKey = match[1].trim();\n }\n } catch {\n // .env doesn't exist\n }\n\n if (!secretKey) {\n p.log.warning(\n \"KALP_SECRET_KEY not found in .env. Studio authentication will not work.\",\n );\n p.note(\"Run 'kalp studio' to generate a new secret.\", \"Action\");\n }\n\n const response = await fetch(`http://localhost:3000/api/agents/push`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n agentName,\n ir: manifest.ir,\n hash,\n secretKey, // Send secret for injection into Cloudflare\n }),\n });\n\n const body = (await response.json().catch(() => null)) as Record<\n string,\n unknown\n > | null;\n\n if (!response.ok) {\n s.stop(pc.red(\"Push failed\"));\n const phase = (body?.phase as string) ?? \"unknown\";\n const errors = (body?.errors as string[]) ?? [`HTTP ${response.status}`];\n const blockers = body?.blockers as string[] | undefined;\n printPushError(phase, errors, blockers);\n process.exit(1);\n }\n\n const displayHandlers = Object.entries(bundles).reduce(\n (acc, [hash, bundle]) => ({\n ...acc,\n [hash]: {\n size: Buffer.byteLength(bundle.code),\n },\n }),\n {} as Record<string, { size: number }>,\n );\n\n s.stop(pc.green(\"Pushed successfully\"));\n printPushResult(agentName, hash, displayHandlers);\n\n // Save worker URL to .kalp/state.json\n const kalpDir = join(cwd, \".kalp\");\n await mkdir(kalpDir, { recursive: true });\n\n const stateData = {\n agentName,\n workerUrl: `http://localhost:3000/a/${agentName}`,\n lastPush: new Date().toISOString(),\n hash,\n };\n\n await writeFile(\n join(kalpDir, \"state.json\"),\n JSON.stringify(stateData, null, 2),\n \"utf-8\",\n );\n\n const dashboardUrl = `http://localhost:3000/a/${agentName}`;\n p.outro(`${LOGO} ${pc.green(\"Agent live at\")} ${pc.cyan(dashboardUrl)}`);\n\n process.exit(0);\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 p from \"picocolors\";\n\n/**\n * Severity level for a validation issue.\n */\nexport type Severity = \"error\" | \"warning\" | \"info\";\n\n/**\n * A structured validation issue found during agent analysis or compilation.\n */\nexport interface ValidationIssue {\n severity: Severity;\n message: string;\n context?: string;\n location?: string;\n fix?: string;\n debug?: string;\n}\n\ninterface RenderOptions {\n format?: \"pretty\" | \"json\" | \"minimal\";\n showDebug?: boolean;\n}\n\nconst severityIcons: Record<Severity, string> = {\n error: p.red(\"โœ˜\"),\n warning: p.yellow(\"โš \"),\n info: p.blue(\"โ„น\"),\n};\n\nconst severityLabels: Record<Severity, string> = {\n error: p.red(\"Error\"),\n warning: p.yellow(\"Warning\"),\n info: p.blue(\"Info\"),\n};\n\nfunction groupByContext(\n issues: ValidationIssue[],\n): Map<string, ValidationIssue[]> {\n const groups = new Map<string, ValidationIssue[]>();\n\n for (const issue of issues) {\n const context = issue.context ?? \"General\";\n const existing = groups.get(context) ?? [];\n existing.push(issue);\n groups.set(context, existing);\n }\n\n return groups;\n}\n\nfunction renderPrettyIssue(issue: ValidationIssue, showDebug: boolean): string {\n const lines: string[] = [];\n\n // Header with icon, severity label, and message\n lines.push(\n `${severityIcons[issue.severity]} ${severityLabels[issue.severity]}: ${p.bold(issue.message)}`,\n );\n\n // Context (location in code)\n if (issue.context) {\n lines.push(p.dim(` Found in: ${issue.context}`));\n }\n if (issue.location) {\n lines.push(p.dim(` Location: ${issue.location}`));\n }\n\n // Empty line before fix\n lines.push(\"\");\n\n // Fix section\n if (issue.fix) {\n lines.push(p.green(\" Fix:\"));\n const fixLines = issue.fix.split(\"\\n\");\n for (const fixLine of fixLines) {\n lines.push(` ${fixLine}`);\n }\n }\n\n // Debug info (optional)\n if (showDebug && issue.debug) {\n lines.push(\"\");\n lines.push(p.dim(` (debug: ${issue.debug})`));\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction renderGroupedIssues(\n issues: ValidationIssue[],\n showDebug: boolean,\n): string {\n const groups = groupByContext(issues);\n const output: string[] = [];\n\n for (const [context, contextIssues] of groups) {\n // Context header\n output.push(p.cyan(p.bold(`โ†’ ${context}`)));\n output.push(\"\");\n\n // Issues in this context\n for (const issue of contextIssues) {\n output.push(renderPrettyIssue(issue, showDebug));\n output.push(\"\"); // Empty line between issues\n }\n }\n\n return output.join(\"\\n\");\n}\n\nfunction renderMinimalIssue(issue: ValidationIssue): string {\n const icon =\n issue.severity === \"error\" ? \"โœ˜\" : issue.severity === \"warning\" ? \"โš \" : \"โ„น\";\n const context = issue.context ? ` [${issue.context}]` : \"\";\n return `${icon} ${issue.message}${context}`;\n}\n\nexport function renderIssues(\n issues: ValidationIssue[],\n options: RenderOptions = {},\n): string {\n const { format = \"pretty\", showDebug = false } = options;\n\n if (issues.length === 0) {\n return p.green(\"โœ“ No issues found\");\n }\n\n // Sort by severity: errors first, then warnings, then info\n const sorted = [...issues].sort((a, b) => {\n const severityOrder: Record<Severity, number> = {\n error: 0,\n warning: 1,\n info: 2,\n };\n return severityOrder[a.severity]! - severityOrder[b.severity]!;\n });\n\n switch (format) {\n case \"json\":\n return JSON.stringify(sorted, null, 2);\n\n case \"minimal\":\n return sorted.map(renderMinimalIssue).join(\"\\n\");\n\n case \"pretty\":\n default: {\n const output: string[] = [];\n\n // Summary header\n const errorCount = issues.filter((i) => i.severity === \"error\").length;\n const warningCount = issues.filter(\n (i) => i.severity === \"warning\",\n ).length;\n const infoCount = issues.filter((i) => i.severity === \"info\").length;\n\n if (errorCount > 0) {\n output.push(\n p.red(\n p.bold(`Found ${errorCount} error${errorCount > 1 ? \"s\" : \"\"}`),\n ),\n );\n }\n if (warningCount > 0) {\n output.push(\n p.yellow(`${warningCount} warning${warningCount > 1 ? \"s\" : \"\"}`),\n );\n }\n if (infoCount > 0) {\n output.push(p.blue(`${infoCount} info`));\n }\n output.push(\"\");\n\n // Grouped issues\n output.push(renderGroupedIssues(sorted, showDebug));\n\n return output.join(\"\\n\");\n }\n }\n}\n\n// Render legacy error strings in DX-first format\nexport function renderLegacyError(\n error: string,\n showDebug: boolean = true,\n): string {\n const lines: string[] = [];\n\n // Extract debug info if present\n const debugMatch = error.match(/\\(debug: (.+)\\)$/);\n const debug = debugMatch ? debugMatch[1] : undefined;\n const mainError = debugMatch\n ? error.replace(/\\(debug: .+\\)$/, \"\").trim()\n : error;\n\n lines.push(p.red(p.bold(`โœ˜ ${mainError.split(\"\\n\")[0]}`)));\n\n // Show fix if present in the error\n const fixMatch = mainError.match(/Fix:\\n((?:- .+\\n?)+)/);\n if (fixMatch) {\n lines.push(\"\");\n lines.push(p.green(\" Fix:\"));\n const fixLines = fixMatch[1]?.split(\"\\n\").filter(Boolean) ?? [];\n for (const line of fixLines) {\n lines.push(` ${line.replace(/^- /, \"\")}`);\n }\n }\n\n if (showDebug && debug) {\n lines.push(\"\");\n lines.push(p.dim(` (debug: ${debug})`));\n }\n\n return lines.join(\"\\n\");\n}\n"],"mappings":"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","names":["access","readFile","join","p","join","access","readFile","hash"]}
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/commands/studio.ts
4
+ import { defineCommand } from "citty";
5
+ import * as p from "@clack/prompts";
6
+ import pc from "picocolors";
7
+ import { readFile, writeFile } from "fs/promises";
8
+ import { join } from "path";
9
+ import { randomBytes } from "crypto";
10
+ import { SignJWT } from "jose";
11
+ import open from "open";
12
+ var LOGO = "\u{1F98B}";
13
+ async function ensureSecretKey(cwd) {
14
+ const envPath = join(cwd, ".env");
15
+ try {
16
+ const envContent2 = await readFile(envPath, "utf-8");
17
+ const match = envContent2.match(/^KALP_SECRET_KEY=(.+)$/m);
18
+ if (match && match[1]) {
19
+ return { key: match[1].trim(), isNew: false };
20
+ }
21
+ } catch {
22
+ }
23
+ const secretKey = randomBytes(32).toString("hex");
24
+ const envContent = `# Kalp Studio Authentication Secret
25
+ KALP_SECRET_KEY=${secretKey}
26
+ `;
27
+ await writeFile(envPath, envContent, "utf-8");
28
+ return { key: secretKey, isNew: true };
29
+ }
30
+ async function readWorkerUrl(cwd) {
31
+ try {
32
+ const statePath = join(cwd, ".kalp", "state.json");
33
+ const content = await readFile(statePath, "utf-8");
34
+ const state = JSON.parse(content);
35
+ return state.workerUrl || null;
36
+ } catch {
37
+ return null;
38
+ }
39
+ }
40
+ var studio_default = defineCommand({
41
+ meta: { name: "studio", description: "Open Kalp Studio in browser" },
42
+ args: {
43
+ url: {
44
+ type: "string",
45
+ alias: "u",
46
+ description: "Worker URL (overrides saved state)",
47
+ required: false
48
+ }
49
+ },
50
+ async run({ args }) {
51
+ const cwd = process.cwd();
52
+ p.intro(`${LOGO} ${pc.bold("kalp studio")}`);
53
+ const s = p.spinner();
54
+ s.start("Checking authentication secret");
55
+ const { key: secretKey, isNew: isNewSecret } = await ensureSecretKey(cwd);
56
+ s.stop("Authentication secret ready");
57
+ if (isNewSecret) {
58
+ p.log.warning("No KALP_SECRET_KEY found. Generated a new one in .env");
59
+ p.note(
60
+ "Please run 'kalp push' to sync the new secret with Cloudflare",
61
+ "Action Required"
62
+ );
63
+ }
64
+ const workerUrl = args.url || await readWorkerUrl(cwd);
65
+ const isDev = !args.url;
66
+ const studioBaseUrl = isDev ? "http://localhost:5173" : workerUrl;
67
+ if (isDev) {
68
+ p.log.info("Using local Studio dev server (http://localhost:5173)");
69
+ p.note(
70
+ "Make sure to run 'pnpm --filter=@kalphq/studio dev' first",
71
+ "Dev Mode"
72
+ );
73
+ } else if (!studioBaseUrl) {
74
+ p.log.error(
75
+ "No worker URL found. Run 'kalp push' first or use --url flag"
76
+ );
77
+ process.exit(1);
78
+ }
79
+ s.start("Generating authentication token");
80
+ const secret = new TextEncoder().encode(secretKey);
81
+ const token = await new SignJWT({
82
+ sub: "cli-user",
83
+ aud: "kalp-studio",
84
+ iat: Date.now(),
85
+ exp: Math.floor(Date.now() / 1e3) + 3600
86
+ // 1 hour
87
+ }).setProtectedHeader({ alg: "HS256" }).sign(secret);
88
+ s.stop("Token generated");
89
+ let studioUrl;
90
+ if (isDev) {
91
+ studioUrl = `${studioBaseUrl}/?token=${token}`;
92
+ } else {
93
+ studioUrl = studioBaseUrl.replace(/\/a\//, "/studio/a/") + `?token=${token}`;
94
+ }
95
+ p.log.info(`Opening Studio at ${pc.cyan(studioUrl)}`);
96
+ await open(studioUrl);
97
+ p.outro(`${LOGO} ${pc.green("Studio opened")}`);
98
+ }
99
+ });
100
+ export {
101
+ studio_default as default
102
+ };
103
+ //# sourceMappingURL=studio-SSJ27ZHR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/studio.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { randomBytes } from \"node:crypto\";\nimport { SignJWT } from \"jose\";\nimport open from \"open\";\n\nconst LOGO = \"๐Ÿฆ‹\";\n\n/**\n * Generate KALP_SECRET_KEY if not exists.\n * Returns the key and whether it was newly created.\n */\nasync function ensureSecretKey(\n cwd: string,\n): Promise<{ key: string; isNew: boolean }> {\n const envPath = join(cwd, \".env\");\n\n try {\n const envContent = await readFile(envPath, \"utf-8\");\n const match = envContent.match(/^KALP_SECRET_KEY=(.+)$/m);\n if (match && match[1]) {\n return { key: match[1].trim(), isNew: false };\n }\n } catch {\n // .env doesn't exist, create it\n }\n\n // Generate new secret\n const secretKey = randomBytes(32).toString(\"hex\");\n const envContent = `# Kalp Studio Authentication Secret\nKALP_SECRET_KEY=${secretKey}\n`;\n\n await writeFile(envPath, envContent, \"utf-8\");\n return { key: secretKey, isNew: true };\n}\n\n/**\n * Read worker URL from .kalp/state.json.\n */\nasync function readWorkerUrl(cwd: string): Promise<string | null> {\n try {\n const statePath = join(cwd, \".kalp\", \"state.json\");\n const content = await readFile(statePath, \"utf-8\");\n const state = JSON.parse(content);\n return state.workerUrl || null;\n } catch {\n return null;\n }\n}\n\nexport default defineCommand({\n meta: { name: \"studio\", description: \"Open Kalp Studio in browser\" },\n args: {\n url: {\n type: \"string\",\n alias: \"u\",\n description: \"Worker URL (overrides saved state)\",\n required: false,\n },\n },\n async run({ args }) {\n const cwd = process.cwd();\n\n p.intro(`${LOGO} ${pc.bold(\"kalp studio\")}`);\n\n // 1. Ensure KALP_SECRET_KEY exists\n const s = p.spinner();\n s.start(\"Checking authentication secret\");\n\n const { key: secretKey, isNew: isNewSecret } = await ensureSecretKey(cwd);\n\n s.stop(\"Authentication secret ready\");\n\n if (isNewSecret) {\n p.log.warning(\"No KALP_SECRET_KEY found. Generated a new one in .env\");\n p.note(\n \"Please run 'kalp push' to sync the new secret with Cloudflare\",\n \"Action Required\",\n );\n }\n\n // 2. Get worker URL (for production Cloudflare deployment)\n // For development, use the local Studio dev server\n const workerUrl = args.url || (await readWorkerUrl(cwd));\n\n // For local development, use the Studio dev server on port 5173\n // For production, the Studio is embedded in the Cloudflare Worker\n const isDev = !args.url; // If user didn't provide --url, assume dev mode\n const studioBaseUrl = isDev ? \"http://localhost:5173\" : workerUrl;\n\n if (isDev) {\n p.log.info(\"Using local Studio dev server (http://localhost:5173)\");\n p.note(\n \"Make sure to run 'pnpm --filter=@kalphq/studio dev' first\",\n \"Dev Mode\",\n );\n } else if (!studioBaseUrl) {\n p.log.error(\n \"No worker URL found. Run 'kalp push' first or use --url flag\",\n );\n process.exit(1);\n }\n\n // 3. Generate JWT (1 hour expiry)\n s.start(\"Generating authentication token\");\n\n const secret = new TextEncoder().encode(secretKey);\n const token = await new SignJWT({\n sub: \"cli-user\",\n aud: \"kalp-studio\",\n iat: Date.now(),\n exp: Math.floor(Date.now() / 1000) + 3600, // 1 hour\n })\n .setProtectedHeader({ alg: \"HS256\" })\n .sign(secret);\n\n s.stop(\"Token generated\");\n\n // 4. Open browser\n let studioUrl: string;\n if (isDev) {\n // Dev mode: use local Studio dev server\n studioUrl = `${studioBaseUrl}/?token=${token}`;\n } else {\n // Production: construct URL by inserting /studio before /a/agentName\n // workerUrl is like http://localhost:3000/a/support\n // We want http://localhost:3000/studio/a/support\n studioUrl =\n studioBaseUrl!.replace(/\\/a\\//, \"/studio/a/\") + `?token=${token}`;\n }\n p.log.info(`Opening Studio at ${pc.cyan(studioUrl)}`);\n\n await open(studioUrl);\n\n p.outro(`${LOGO} ${pc.green(\"Studio opened\")}`);\n },\n});\n"],"mappings":"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","names":["envContent"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kalphq/cli",
3
- "version": "0.0.0-dev-20260508055746",
3
+ "version": "0.0.0-dev-20260509012111",
4
4
  "description": "Zero-config CLI for deploying Kalp agents",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -20,12 +20,14 @@
20
20
  "@clack/prompts": "0.9.1",
21
21
  "citty": "0.1.6",
22
22
  "esbuild": "0.25.0",
23
+ "jose": "^5.10.0",
23
24
  "json-stable-stringify": "1.3.0",
25
+ "open": "^11.0.0",
24
26
  "picocolors": "1.1.1",
25
27
  "zod": "3.25.76",
26
- "@kalphq/project": "0.0.0-dev-20260508055746",
27
- "@kalphq/compiler": "0.0.0-dev-20260508055746",
28
- "@kalphq/sdk": "0.0.0-dev-20260508055746"
28
+ "@kalphq/compiler": "0.0.0-dev-20260509012111",
29
+ "@kalphq/sdk": "0.0.0-dev-20260509012111",
30
+ "@kalphq/project": "0.0.0-dev-20260509012111"
29
31
  },
30
32
  "devDependencies": {
31
33
  "@types/json-stable-stringify": "1.2.0",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/commands/push.ts","../src/utils/manifest/index.ts","../src/utils/ir/hashIR.ts","../src/utils/issues.ts"],"sourcesContent":["import { access } 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 { renderLegacyError } from \"@/utils/issues\";\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 printPushResult(\n agentName: string,\n hash: string,\n handlers: Record<string, { size: number }>,\n) {\n const div = pc.dim(\"โ”€\".repeat(48));\n const handlerCount = Object.keys(handlers).length;\n const totalSize = Object.values(handlers).reduce((sum, h) => sum + h.size, 0);\n\n console.log(\"\\n\" + div);\n console.log(pc.green(\"โœ” Deployed\"));\n console.log(\"\");\n console.log(` ${pc.bold(agentName)} ${pc.dim(hash.slice(0, 7))}...`);\n console.log(\n ` ${pc.dim(String(handlerCount))} handlers ยท ${formatBytes(totalSize)}`,\n );\n console.log(div + \"\\n\");\n}\n\nfunction printPushError(\n phase: string,\n errors: string[],\n blockers?: string[],\n verbose?: boolean,\n) {\n const div = pc.dim(\"โ”€\".repeat(48));\n console.log(\"\\n\" + div);\n\n for (const e of errors) {\n console.log(renderLegacyError(e, verbose));\n console.log(\"\");\n }\n\n if (phase === \"analysis\" && blockers) {\n for (const b of blockers) {\n console.log(pc.red(`โœ˜ Blocker: ${b}`));\n }\n }\n\n if (!verbose) {\n console.log(pc.dim(`\\nRun with --verbose for more details.\\n`));\n }\n\n console.log(div + \"\\n\");\n}\n\nexport default defineCommand({\n meta: { name: \"push\", description: \"Push agent to Kalp cloud\" },\n args: {\n agent: {\n type: \"string\",\n alias: \"a\",\n description: \"Agent name to push\",\n required: false,\n },\n verbose: {\n type: \"boolean\",\n alias: \"v\",\n description: \"Show debug information\",\n default: false,\n },\n },\n async run({ args }) {\n const cwd = process.cwd();\n const agentName = args.agent;\n\n p.intro(`${LOGO} ${pc.bold(\"kalp push\")}`);\n\n if (!agentName) {\n p.log.error(`Missing required flag ${pc.cyan(\"-a <agent-name>\")}`);\n process.exit(1);\n }\n\n try {\n await ensureConfig(cwd);\n } catch {\n p.log.error(`${pc.cyan(\"kalp.config.ts\")} not found`);\n process.exit(1);\n }\n\n const agentPath = join(cwd, \"agents\", agentName, \"index.ts\");\n try {\n await access(agentPath);\n } catch {\n p.log.error(`Agent ${pc.cyan(agentName)} not found`);\n process.exit(1);\n }\n\n const s = p.spinner();\n s.start(`Compiling ${pc.cyan(agentName)}`);\n\n const manifest = await readAgentManifest({ cwd, agentName });\n\n const bundles = (manifest.ir.bundles || {}) as Record<\n string,\n { code: string }\n >;\n const handlerCount = Object.keys(bundles).length;\n\n const hash = computePushHash(manifest.ir);\n\n s.stop(`Compiled ${pc.cyan(agentName)} โ€” ${handlerCount} handlers`);\n\n s.start(`Checking for changes`);\n\n const statusResponse = await fetch(\n `http://localhost:3000/api/agents/${agentName}/status`,\n );\n\n const statusData = (await statusResponse.json().catch(() => null)) as {\n agentName: string;\n hash?: string;\n exists: boolean;\n } | null;\n\n if (statusData?.exists && statusData.hash === hash) {\n s.stop(pc.green(\"No changes detected\"));\n p.note(\n `Agent ${pc.cyan(agentName)} is already deployed with the same logic.`,\n \"Skipped\",\n );\n p.outro(`${LOGO} ${pc.green(\"No deployment needed\")}`);\n return;\n }\n\n s.start(`Pushing to cloud`);\n\n const response = await fetch(`http://localhost:3000/api/agents/push`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n agentName,\n ir: manifest.ir,\n hash,\n }),\n });\n\n const body = (await response.json().catch(() => null)) as Record<\n string,\n unknown\n > | null;\n\n if (!response.ok) {\n s.stop(pc.red(\"Push failed\"));\n const phase = (body?.phase as string) ?? \"unknown\";\n const errors = (body?.errors as string[]) ?? [`HTTP ${response.status}`];\n const blockers = body?.blockers as string[] | undefined;\n printPushError(phase, errors, blockers);\n process.exit(1);\n }\n\n const displayHandlers = Object.entries(bundles).reduce(\n (acc, [hash, bundle]) => ({\n ...acc,\n [hash]: {\n size: Buffer.byteLength(bundle.code),\n },\n }),\n {} as Record<string, { size: number }>,\n );\n\n s.stop(pc.green(\"Pushed successfully\"));\n printPushResult(agentName, hash, displayHandlers);\n\n const dashboardUrl = `http://localhost:3000/a/${agentName}`;\n p.outro(`${LOGO} ${pc.green(\"Agent live at\")} ${pc.cyan(dashboardUrl)}`);\n\n process.exit(0);\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 p from \"picocolors\";\n\n/**\n * Severity level for a validation issue.\n */\nexport type Severity = \"error\" | \"warning\" | \"info\";\n\n/**\n * A structured validation issue found during agent analysis or compilation.\n */\nexport interface ValidationIssue {\n severity: Severity;\n message: string;\n context?: string;\n location?: string;\n fix?: string;\n debug?: string;\n}\n\ninterface RenderOptions {\n format?: \"pretty\" | \"json\" | \"minimal\";\n showDebug?: boolean;\n}\n\nconst severityIcons: Record<Severity, string> = {\n error: p.red(\"โœ˜\"),\n warning: p.yellow(\"โš \"),\n info: p.blue(\"โ„น\"),\n};\n\nconst severityLabels: Record<Severity, string> = {\n error: p.red(\"Error\"),\n warning: p.yellow(\"Warning\"),\n info: p.blue(\"Info\"),\n};\n\nfunction groupByContext(\n issues: ValidationIssue[],\n): Map<string, ValidationIssue[]> {\n const groups = new Map<string, ValidationIssue[]>();\n\n for (const issue of issues) {\n const context = issue.context ?? \"General\";\n const existing = groups.get(context) ?? [];\n existing.push(issue);\n groups.set(context, existing);\n }\n\n return groups;\n}\n\nfunction renderPrettyIssue(issue: ValidationIssue, showDebug: boolean): string {\n const lines: string[] = [];\n\n // Header with icon, severity label, and message\n lines.push(\n `${severityIcons[issue.severity]} ${severityLabels[issue.severity]}: ${p.bold(issue.message)}`,\n );\n\n // Context (location in code)\n if (issue.context) {\n lines.push(p.dim(` Found in: ${issue.context}`));\n }\n if (issue.location) {\n lines.push(p.dim(` Location: ${issue.location}`));\n }\n\n // Empty line before fix\n lines.push(\"\");\n\n // Fix section\n if (issue.fix) {\n lines.push(p.green(\" Fix:\"));\n const fixLines = issue.fix.split(\"\\n\");\n for (const fixLine of fixLines) {\n lines.push(` ${fixLine}`);\n }\n }\n\n // Debug info (optional)\n if (showDebug && issue.debug) {\n lines.push(\"\");\n lines.push(p.dim(` (debug: ${issue.debug})`));\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction renderGroupedIssues(\n issues: ValidationIssue[],\n showDebug: boolean,\n): string {\n const groups = groupByContext(issues);\n const output: string[] = [];\n\n for (const [context, contextIssues] of groups) {\n // Context header\n output.push(p.cyan(p.bold(`โ†’ ${context}`)));\n output.push(\"\");\n\n // Issues in this context\n for (const issue of contextIssues) {\n output.push(renderPrettyIssue(issue, showDebug));\n output.push(\"\"); // Empty line between issues\n }\n }\n\n return output.join(\"\\n\");\n}\n\nfunction renderMinimalIssue(issue: ValidationIssue): string {\n const icon =\n issue.severity === \"error\" ? \"โœ˜\" : issue.severity === \"warning\" ? \"โš \" : \"โ„น\";\n const context = issue.context ? ` [${issue.context}]` : \"\";\n return `${icon} ${issue.message}${context}`;\n}\n\nexport function renderIssues(\n issues: ValidationIssue[],\n options: RenderOptions = {},\n): string {\n const { format = \"pretty\", showDebug = false } = options;\n\n if (issues.length === 0) {\n return p.green(\"โœ“ No issues found\");\n }\n\n // Sort by severity: errors first, then warnings, then info\n const sorted = [...issues].sort((a, b) => {\n const severityOrder: Record<Severity, number> = {\n error: 0,\n warning: 1,\n info: 2,\n };\n return severityOrder[a.severity]! - severityOrder[b.severity]!;\n });\n\n switch (format) {\n case \"json\":\n return JSON.stringify(sorted, null, 2);\n\n case \"minimal\":\n return sorted.map(renderMinimalIssue).join(\"\\n\");\n\n case \"pretty\":\n default: {\n const output: string[] = [];\n\n // Summary header\n const errorCount = issues.filter((i) => i.severity === \"error\").length;\n const warningCount = issues.filter(\n (i) => i.severity === \"warning\",\n ).length;\n const infoCount = issues.filter((i) => i.severity === \"info\").length;\n\n if (errorCount > 0) {\n output.push(\n p.red(\n p.bold(`Found ${errorCount} error${errorCount > 1 ? \"s\" : \"\"}`),\n ),\n );\n }\n if (warningCount > 0) {\n output.push(\n p.yellow(`${warningCount} warning${warningCount > 1 ? \"s\" : \"\"}`),\n );\n }\n if (infoCount > 0) {\n output.push(p.blue(`${infoCount} info`));\n }\n output.push(\"\");\n\n // Grouped issues\n output.push(renderGroupedIssues(sorted, showDebug));\n\n return output.join(\"\\n\");\n }\n }\n}\n\n// Render legacy error strings in DX-first format\nexport function renderLegacyError(\n error: string,\n showDebug: boolean = true,\n): string {\n const lines: string[] = [];\n\n // Extract debug info if present\n const debugMatch = error.match(/\\(debug: (.+)\\)$/);\n const debug = debugMatch ? debugMatch[1] : undefined;\n const mainError = debugMatch\n ? error.replace(/\\(debug: .+\\)$/, \"\").trim()\n : error;\n\n lines.push(p.red(p.bold(`โœ˜ ${mainError.split(\"\\n\")[0]}`)));\n\n // Show fix if present in the error\n const fixMatch = mainError.match(/Fix:\\n((?:- .+\\n?)+)/);\n if (fixMatch) {\n lines.push(\"\");\n lines.push(p.green(\" Fix:\"));\n const fixLines = fixMatch[1]?.split(\"\\n\").filter(Boolean) ?? [];\n for (const line of fixLines) {\n lines.push(` ${line.replace(/^- /, \"\")}`);\n }\n }\n\n if (showDebug && debug) {\n lines.push(\"\");\n lines.push(p.dim(` (debug: ${debug})`));\n }\n\n return lines.join(\"\\n\");\n}\n"],"mappings":"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","names":["access","join","p","join","access","hash"]}