@kalphq/cli 0.0.0-dev-20260510053149 → 0.0.0-dev-20260510062740
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-OE6N3E5B.js → chunk-NIPAXEFM.js} +29 -30
- package/dist/chunk-NIPAXEFM.js.map +1 -0
- package/dist/chunk-RT2DIIQ5.js +407 -0
- package/dist/chunk-RT2DIIQ5.js.map +1 -0
- package/dist/{deploy-6UTG5A76.js → deploy-3EVKLTWF.js} +3 -3
- package/dist/{dev-MBANBST4.js → dev-UC2WFSOE.js} +5 -19
- package/dist/dev-UC2WFSOE.js.map +1 -0
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/{push-B4UM7AVH.js → push-4WZVTK2Z.js} +14 -40
- package/dist/push-4WZVTK2Z.js.map +1 -0
- package/dist/runtime-template/studio/assets/QueryClientProvider-DAZmVr20.js +1 -0
- package/dist/runtime-template/studio/assets/agent._agentName-D0WHDceC.js +1 -0
- package/dist/runtime-template/studio/assets/button-D0LvXgpN.js +1 -0
- package/dist/runtime-template/studio/assets/card-B2bzwIGM.js +1 -0
- package/dist/runtime-template/studio/assets/globe-qCpO1Z-s.js +1 -0
- package/dist/runtime-template/studio/assets/index-DcJItVMf.js +75 -0
- package/dist/runtime-template/studio/assets/link-D3Ad09qM.js +1 -0
- package/dist/runtime-template/studio/assets/login-Cqmvx0NQ.js +1 -0
- package/dist/runtime-template/studio/assets/preload-helper-DHF8Plid.js +1 -0
- package/dist/runtime-template/studio/assets/replay._executionId-8boDJLx9.js +41 -0
- package/dist/runtime-template/studio/assets/routes-CaRwwZyr.js +1 -0
- package/dist/runtime-template/studio/assets/skeleton-CJLC4mqH.js +1 -0
- package/dist/runtime-template/studio/assets/styles-GI30ROBZ.css +2 -0
- package/dist/runtime-template/studio/assets/useNavigate-F1VFNun_.js +1 -0
- package/dist/runtime-template/studio/favicon.ico +0 -0
- package/dist/runtime-template/studio/index.html +2 -2
- package/dist/runtime-template/studio/kalp-logo.png +0 -0
- package/dist/runtime-template/worker-entry.js +185 -102
- package/package.json +4 -4
- package/dist/chunk-OE6N3E5B.js.map +0 -1
- package/dist/chunk-TUF2J67G.js +0 -225
- package/dist/chunk-TUF2J67G.js.map +0 -1
- package/dist/dev-MBANBST4.js.map +0 -1
- package/dist/push-B4UM7AVH.js.map +0 -1
- package/dist/runtime-template/studio/assets/QueryClientProvider-D-LxTiBd.js +0 -1
- package/dist/runtime-template/studio/assets/index-DpfZiZAs.js +0 -75
- package/dist/runtime-template/studio/assets/replay._executionId-Cs7M_t4A.js +0 -41
- package/dist/runtime-template/studio/assets/routes-DM2dr3uc.js +0 -1
- package/dist/runtime-template/studio/assets/styles-DnCmVxlg.css +0 -2
- package/dist/runtime-template/studio/assets/useAuth-CNMCKtPc.js +0 -1
- /package/dist/{deploy-6UTG5A76.js.map → deploy-3EVKLTWF.js.map} +0 -0
|
@@ -1,34 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
materializeRuntime
|
|
5
|
-
|
|
3
|
+
ensureStudioSecrets,
|
|
4
|
+
materializeRuntime,
|
|
5
|
+
writeProjectState
|
|
6
|
+
} from "./chunk-RT2DIIQ5.js";
|
|
6
7
|
import {
|
|
7
8
|
requireAuth
|
|
8
9
|
} from "./chunk-5RODADXW.js";
|
|
9
10
|
|
|
10
|
-
// src/utils/project-state.ts
|
|
11
|
-
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
12
|
-
import { join } from "path";
|
|
13
|
-
var KALP_DIR = ".kalp";
|
|
14
|
-
var STATE_FILE = "state.json";
|
|
15
|
-
async function readProjectState(cwd) {
|
|
16
|
-
try {
|
|
17
|
-
const statePath = join(cwd, KALP_DIR, STATE_FILE);
|
|
18
|
-
const content = await readFile(statePath, "utf-8");
|
|
19
|
-
return JSON.parse(content);
|
|
20
|
-
} catch {
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
async function writeProjectState(cwd, state) {
|
|
25
|
-
const dir = join(cwd, KALP_DIR);
|
|
26
|
-
await mkdir(dir, { recursive: true });
|
|
27
|
-
await writeFile(join(dir, STATE_FILE), JSON.stringify(state, null, 2), "utf-8");
|
|
28
|
-
}
|
|
29
|
-
|
|
30
11
|
// src/utils/deploy.ts
|
|
31
|
-
import { readFile
|
|
12
|
+
import { readFile } from "fs/promises";
|
|
32
13
|
import { execa } from "execa";
|
|
33
14
|
function findWorkersUrl(output) {
|
|
34
15
|
const match = output.match(/https:\/\/[^\s]+\.workers\.dev/);
|
|
@@ -37,7 +18,7 @@ function findWorkersUrl(output) {
|
|
|
37
18
|
async function resolveWorkerUrl(configPath, deployOutput) {
|
|
38
19
|
const fromOutput = findWorkersUrl(deployOutput);
|
|
39
20
|
if (fromOutput) return fromOutput;
|
|
40
|
-
const configText = await
|
|
21
|
+
const configText = await readFile(configPath, "utf-8").catch(
|
|
41
22
|
() => null
|
|
42
23
|
);
|
|
43
24
|
const workerName = configText?.match(/"name"\s*:\s*"([^"]+)"/)?.[1];
|
|
@@ -48,18 +29,37 @@ async function resolveWorkerUrl(configPath, deployOutput) {
|
|
|
48
29
|
}
|
|
49
30
|
async function runInitialDeploy(cwd) {
|
|
50
31
|
const auth = await requireAuth();
|
|
51
|
-
await
|
|
32
|
+
const secrets = await ensureStudioSecrets(cwd);
|
|
52
33
|
const runtime = await materializeRuntime(cwd);
|
|
34
|
+
let secretSyncFailed = false;
|
|
35
|
+
const secretEntries = [
|
|
36
|
+
["KALP_SECRET_KEY", secrets.key],
|
|
37
|
+
["KALP_STUDIO_PASSWORD", secrets.studioPassword],
|
|
38
|
+
["KALP_STUDIO_ADMIN_USER", secrets.studioAdminUser]
|
|
39
|
+
];
|
|
40
|
+
for (const [name, value] of secretEntries) {
|
|
41
|
+
try {
|
|
42
|
+
await execa(
|
|
43
|
+
"npx",
|
|
44
|
+
["wrangler", "secret", "put", name, "--config", runtime.wranglerConfigPath],
|
|
45
|
+
{ cwd, input: `${value}
|
|
46
|
+
` }
|
|
47
|
+
);
|
|
48
|
+
} catch {
|
|
49
|
+
secretSyncFailed = true;
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
53
|
const deploy = await execa(
|
|
54
54
|
"npx",
|
|
55
|
-
[
|
|
55
|
+
secretSyncFailed ? [
|
|
56
56
|
"wrangler",
|
|
57
57
|
"deploy",
|
|
58
58
|
"--config",
|
|
59
59
|
runtime.wranglerConfigPath,
|
|
60
60
|
"--secrets-file",
|
|
61
61
|
".env"
|
|
62
|
-
],
|
|
62
|
+
] : ["wrangler", "deploy", "--config", runtime.wranglerConfigPath],
|
|
63
63
|
{
|
|
64
64
|
cwd
|
|
65
65
|
}
|
|
@@ -78,7 +78,6 @@ async function runInitialDeploy(cwd) {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
export {
|
|
81
|
-
readProjectState,
|
|
82
81
|
runInitialDeploy
|
|
83
82
|
};
|
|
84
|
-
//# sourceMappingURL=chunk-
|
|
83
|
+
//# sourceMappingURL=chunk-NIPAXEFM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/deploy.ts"],"sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport { execa } from \"execa\";\nimport { requireAuth } from \"@/utils/auth\";\nimport { ensureStudioSecrets } from \"@/utils/secret\";\nimport { writeProjectState } from \"@/utils/project-state\";\nimport { materializeRuntime } from \"@/utils/runtime\";\n\nfunction findWorkersUrl(output: string): string | null {\n const match = output.match(/https:\\/\\/[^\\s]+\\.workers\\.dev/);\n return match?.[0] ?? null;\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 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 ] 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 const deploy = await execa(\n \"npx\",\n 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 cwd,\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 await writeProjectState(cwd, {\n workerUrl,\n deployedAt: new Date().toISOString(),\n accountId: auth.accountId,\n });\n\n return { workerUrl, accountId: auth.accountId };\n}\n"],"mappings":";;;;;;;;;;;AAAA,SAAS,gBAAgB;AACzB,SAAS,aAAa;AAMtB,SAAS,eAAe,QAA+B;AACrD,QAAM,QAAQ,OAAO,MAAM,gCAAgC;AAC3D,SAAO,QAAQ,CAAC,KAAK;AACvB;AAEA,eAAe,iBACb,YACA,cACiB;AACjB,QAAM,aAAa,eAAe,YAAY;AAC9C,MAAI,WAAY,QAAO;AAEvB,QAAM,aAAa,MAAM,SAAS,YAAY,OAAO,EAAE;AAAA,IACrD,MAAM;AAAA,EACR;AACA,QAAM,aAAa,YAAY,MAAM,wBAAwB,IAAI,CAAC;AAElE,MAAI,YAAY;AACd,WAAO,WAAW,UAAU;AAAA,EAC9B;AAEA,QAAM,IAAI,MAAM,2DAA2D;AAC7E;AAEA,eAAsB,iBAAiB,KAGpC;AACD,QAAM,OAAO,MAAM,YAAY;AAC/B,QAAM,UAAU,MAAM,oBAAoB,GAAG;AAC7C,QAAM,UAAU,MAAM,mBAAmB,GAAG;AAC5C,MAAI,mBAAmB;AACvB,QAAM,gBAAgB;AAAA,IACpB,CAAC,mBAAmB,QAAQ,GAAG;AAAA,IAC/B,CAAC,wBAAwB,QAAQ,cAAc;AAAA,IAC/C,CAAC,0BAA0B,QAAQ,eAAe;AAAA,EACpD;AAEA,aAAW,CAAC,MAAM,KAAK,KAAK,eAAe;AACzC,QAAI;AACF,YAAM;AAAA,QACJ;AAAA,QACA,CAAC,YAAY,UAAU,OAAO,MAAM,YAAY,QAAQ,kBAAkB;AAAA,QAC1E,EAAE,KAAK,OAAO,GAAG,KAAK;AAAA,EAAK;AAAA,MAC7B;AAAA,IACF,QAAQ;AACN,yBAAmB;AACnB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA,mBACI;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,IACF,IACA,CAAC,YAAY,UAAU,YAAY,QAAQ,kBAAkB;AAAA,IACjE;AAAA,MACE;AAAA,IACF;AAAA,EACF;AAEA,QAAM,eAAe,CAAC,OAAO,QAAQ,OAAO,MAAM,EAC/C,OAAO,OAAO,EACd,KAAK,IAAI;AAEZ,QAAM,YAAY,MAAM;AAAA,IACtB,QAAQ;AAAA,IACR;AAAA,EACF;AAEA,QAAM,kBAAkB,KAAK;AAAA,IAC3B;AAAA,IACA,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,IACnC,WAAW,KAAK;AAAA,EAClB,CAAC;AAED,SAAO,EAAE,WAAW,WAAW,KAAK,UAAU;AAChD;","names":[]}
|
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
ensureGlobalConfigDir
|
|
4
|
+
} from "./chunk-FO24J6XL.js";
|
|
5
|
+
|
|
6
|
+
// src/utils/secret.ts
|
|
7
|
+
import { randomBytes } from "crypto";
|
|
8
|
+
import { readFile, writeFile } from "fs/promises";
|
|
9
|
+
import { join } from "path";
|
|
10
|
+
var SECRET_KEY = "KALP_SECRET_KEY";
|
|
11
|
+
var STUDIO_PASSWORD = "KALP_STUDIO_PASSWORD";
|
|
12
|
+
var STUDIO_ADMIN_USER = "KALP_STUDIO_ADMIN_USER";
|
|
13
|
+
function parseEnv(content) {
|
|
14
|
+
const result = {};
|
|
15
|
+
for (const line of content.split(/\r?\n/g)) {
|
|
16
|
+
const trimmed = line.trim();
|
|
17
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
18
|
+
const eqIndex = trimmed.indexOf("=");
|
|
19
|
+
if (eqIndex <= 0) continue;
|
|
20
|
+
const key = trimmed.slice(0, eqIndex).trim();
|
|
21
|
+
const value = trimmed.slice(eqIndex + 1).trim();
|
|
22
|
+
result[key] = value;
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
function toEnvContent(values) {
|
|
27
|
+
const lines = [
|
|
28
|
+
"# Kalp Studio Authentication Secrets",
|
|
29
|
+
`${SECRET_KEY}=${values[SECRET_KEY]}`,
|
|
30
|
+
`${STUDIO_PASSWORD}=${values[STUDIO_PASSWORD]}`,
|
|
31
|
+
`${STUDIO_ADMIN_USER}=${values[STUDIO_ADMIN_USER]}`,
|
|
32
|
+
""
|
|
33
|
+
];
|
|
34
|
+
return lines.join("\n");
|
|
35
|
+
}
|
|
36
|
+
async function readEnvFile(cwd) {
|
|
37
|
+
const envPath = join(cwd, ".env");
|
|
38
|
+
try {
|
|
39
|
+
return await readFile(envPath, "utf-8");
|
|
40
|
+
} catch {
|
|
41
|
+
return "";
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function generateStudioPassword() {
|
|
45
|
+
return randomBytes(24).toString("base64url");
|
|
46
|
+
}
|
|
47
|
+
async function ensureStudioSecrets(cwd) {
|
|
48
|
+
const envPath = join(cwd, ".env");
|
|
49
|
+
const content = await readEnvFile(cwd);
|
|
50
|
+
const parsed = parseEnv(content);
|
|
51
|
+
const key = parsed[SECRET_KEY] || randomBytes(32).toString("hex");
|
|
52
|
+
const studioPassword = parsed[STUDIO_PASSWORD] || generateStudioPassword();
|
|
53
|
+
const studioAdminUser = parsed[STUDIO_ADMIN_USER] || "admin";
|
|
54
|
+
const isNew = !parsed[SECRET_KEY] || !parsed[STUDIO_PASSWORD] || !parsed[STUDIO_ADMIN_USER];
|
|
55
|
+
if (isNew || !content.trim()) {
|
|
56
|
+
await writeFile(
|
|
57
|
+
envPath,
|
|
58
|
+
toEnvContent({
|
|
59
|
+
...parsed,
|
|
60
|
+
[SECRET_KEY]: key,
|
|
61
|
+
[STUDIO_PASSWORD]: studioPassword,
|
|
62
|
+
[STUDIO_ADMIN_USER]: studioAdminUser
|
|
63
|
+
}),
|
|
64
|
+
"utf-8"
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
return { key, studioPassword, studioAdminUser, isNew };
|
|
68
|
+
}
|
|
69
|
+
async function ensureSecretKey(cwd) {
|
|
70
|
+
const secrets = await ensureStudioSecrets(cwd);
|
|
71
|
+
return { key: secrets.key, isNew: secrets.isNew };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// src/utils/project-state.ts
|
|
75
|
+
import { mkdir, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
76
|
+
import { join as join2 } from "path";
|
|
77
|
+
var KALP_DIR = ".kalp";
|
|
78
|
+
var STATE_FILE = "state.json";
|
|
79
|
+
async function readProjectState(cwd) {
|
|
80
|
+
try {
|
|
81
|
+
const statePath = join2(cwd, KALP_DIR, STATE_FILE);
|
|
82
|
+
const content = await readFile2(statePath, "utf-8");
|
|
83
|
+
return JSON.parse(content);
|
|
84
|
+
} catch {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
async function writeProjectState(cwd, state) {
|
|
89
|
+
const dir = join2(cwd, KALP_DIR);
|
|
90
|
+
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");
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// src/utils/runtime.ts
|
|
121
|
+
import { createHash } from "crypto";
|
|
122
|
+
import {
|
|
123
|
+
access,
|
|
124
|
+
cp,
|
|
125
|
+
mkdir as mkdir2,
|
|
126
|
+
readdir,
|
|
127
|
+
readFile as readFile4,
|
|
128
|
+
rm,
|
|
129
|
+
stat,
|
|
130
|
+
writeFile as writeFile4
|
|
131
|
+
} from "fs/promises";
|
|
132
|
+
import { basename, dirname, join as join4, normalize, resolve } from "path";
|
|
133
|
+
import { fileURLToPath } from "url";
|
|
134
|
+
var RUNTIME_ROOT = ".kalp";
|
|
135
|
+
var RUNTIME_DIR = "runtime";
|
|
136
|
+
var STUDIO_DIR = "studio";
|
|
137
|
+
var WRANGLER_CONFIG_FILE = "wrangler.jsonc";
|
|
138
|
+
var WORKER_ENTRY_FILE = "worker-entry.js";
|
|
139
|
+
var COMPATIBILITY_DATE = "2026-05-10";
|
|
140
|
+
function sanitizeSegment(input) {
|
|
141
|
+
return input.toLowerCase().replace(/^@/, "").replace(/\//g, "-").replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-+|-+$/g, "");
|
|
142
|
+
}
|
|
143
|
+
async function resolveProjectSlug(cwd) {
|
|
144
|
+
const fallback = sanitizeSegment(basename(cwd)) || "agent";
|
|
145
|
+
const packageJsonPath = join4(cwd, "package.json");
|
|
146
|
+
try {
|
|
147
|
+
const content = await readFile4(packageJsonPath, "utf-8");
|
|
148
|
+
const pkg = JSON.parse(content);
|
|
149
|
+
const name = typeof pkg.name === "string" ? pkg.name : "";
|
|
150
|
+
const sanitized = sanitizeSegment(name);
|
|
151
|
+
return sanitized || fallback;
|
|
152
|
+
} catch {
|
|
153
|
+
return fallback;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function buildWorkerName(slug, cwd) {
|
|
157
|
+
const cwdHash = createHash("sha1").update(cwd).digest("hex").slice(0, 8);
|
|
158
|
+
const withPrefix = `kalp-${slug}-${cwdHash}`;
|
|
159
|
+
const maxLen = 63;
|
|
160
|
+
if (withPrefix.length <= maxLen) {
|
|
161
|
+
return withPrefix;
|
|
162
|
+
}
|
|
163
|
+
const clipped = withPrefix.slice(0, maxLen).replace(/-+$/g, "");
|
|
164
|
+
return clipped || `kalp-${cwdHash}`;
|
|
165
|
+
}
|
|
166
|
+
function createRuntimeConfig(workerName) {
|
|
167
|
+
return {
|
|
168
|
+
$schema: "node_modules/wrangler/config-schema.json",
|
|
169
|
+
name: workerName,
|
|
170
|
+
main: `./${WORKER_ENTRY_FILE}`,
|
|
171
|
+
compatibility_date: COMPATIBILITY_DATE,
|
|
172
|
+
compatibility_flags: ["nodejs_compat"],
|
|
173
|
+
migrations: [
|
|
174
|
+
{
|
|
175
|
+
tag: "v1",
|
|
176
|
+
new_sqlite_classes: ["AgentDurableObject"]
|
|
177
|
+
}
|
|
178
|
+
],
|
|
179
|
+
durable_objects: {
|
|
180
|
+
bindings: [
|
|
181
|
+
{
|
|
182
|
+
name: "KALP_RUNTIME_CLOUDFLARE",
|
|
183
|
+
class_name: "AgentDurableObject"
|
|
184
|
+
}
|
|
185
|
+
]
|
|
186
|
+
},
|
|
187
|
+
kv_namespaces: [
|
|
188
|
+
{
|
|
189
|
+
binding: "KALP_MANIFESTS"
|
|
190
|
+
}
|
|
191
|
+
],
|
|
192
|
+
assets: {
|
|
193
|
+
directory: `./${STUDIO_DIR}`,
|
|
194
|
+
binding: "ASSETS",
|
|
195
|
+
run_worker_first: true
|
|
196
|
+
},
|
|
197
|
+
observability: { enabled: true },
|
|
198
|
+
upload_source_maps: true,
|
|
199
|
+
secrets: {
|
|
200
|
+
required: [
|
|
201
|
+
"KALP_SECRET_KEY",
|
|
202
|
+
"KALP_STUDIO_PASSWORD",
|
|
203
|
+
"KALP_STUDIO_ADMIN_USER"
|
|
204
|
+
]
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
function runtimeTemplateCandidates() {
|
|
209
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
210
|
+
const distTemplateRoot = resolve(here, "runtime-template");
|
|
211
|
+
const packageRootTemplate = resolve(here, "..", "runtime-template");
|
|
212
|
+
const sourceTemplateRoot = resolve(here, "..", "..", "runtime-template");
|
|
213
|
+
const monorepoStudioDist = resolve(
|
|
214
|
+
here,
|
|
215
|
+
"..",
|
|
216
|
+
"..",
|
|
217
|
+
"..",
|
|
218
|
+
"..",
|
|
219
|
+
"apps",
|
|
220
|
+
"studio",
|
|
221
|
+
"dist",
|
|
222
|
+
"client"
|
|
223
|
+
);
|
|
224
|
+
return [
|
|
225
|
+
{
|
|
226
|
+
studioTemplateDir: join4(distTemplateRoot, STUDIO_DIR),
|
|
227
|
+
workerEntryPath: join4(distTemplateRoot, WORKER_ENTRY_FILE)
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
studioTemplateDir: join4(packageRootTemplate, STUDIO_DIR),
|
|
231
|
+
workerEntryPath: join4(packageRootTemplate, WORKER_ENTRY_FILE)
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
studioTemplateDir: join4(sourceTemplateRoot, STUDIO_DIR),
|
|
235
|
+
workerEntryPath: join4(sourceTemplateRoot, WORKER_ENTRY_FILE)
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
studioTemplateDir: monorepoStudioDist,
|
|
239
|
+
workerEntryPath: join4(sourceTemplateRoot, WORKER_ENTRY_FILE)
|
|
240
|
+
}
|
|
241
|
+
];
|
|
242
|
+
}
|
|
243
|
+
async function resolveRuntimeTemplate() {
|
|
244
|
+
for (const candidate of runtimeTemplateCandidates()) {
|
|
245
|
+
try {
|
|
246
|
+
await access(candidate.studioTemplateDir);
|
|
247
|
+
await access(candidate.workerEntryPath);
|
|
248
|
+
return candidate;
|
|
249
|
+
} catch {
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
throw new Error(
|
|
253
|
+
"Kalp runtime template not found in CLI package. Reinstall @kalphq/cli."
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
function createStudioShell(entryScript, cssFiles) {
|
|
257
|
+
const cssLinks = cssFiles.map((file) => ` <link rel="stylesheet" href="/studio/assets/${file}" />`).join("\n");
|
|
258
|
+
return `<!doctype html>
|
|
259
|
+
<html lang="en">
|
|
260
|
+
<head>
|
|
261
|
+
<meta charset="UTF-8" />
|
|
262
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
263
|
+
<title>Kalp Studio</title>
|
|
264
|
+
${cssLinks}
|
|
265
|
+
</head>
|
|
266
|
+
<body>
|
|
267
|
+
<div id="root"></div>
|
|
268
|
+
<script type="module" src="/studio/assets/${entryScript}"></script>
|
|
269
|
+
</body>
|
|
270
|
+
</html>
|
|
271
|
+
`;
|
|
272
|
+
}
|
|
273
|
+
async function ensureStudioIndex(studioDir) {
|
|
274
|
+
const indexPath = join4(studioDir, "index.html");
|
|
275
|
+
try {
|
|
276
|
+
await access(indexPath);
|
|
277
|
+
return;
|
|
278
|
+
} catch {
|
|
279
|
+
}
|
|
280
|
+
const assetsDir = join4(studioDir, "assets");
|
|
281
|
+
const assetFiles = await readdir(assetsDir);
|
|
282
|
+
const entryScript = assetFiles.find((file) => /^index-.*\.js$/i.test(file)) ?? assetFiles.find((file) => file.endsWith(".js"));
|
|
283
|
+
if (!entryScript) {
|
|
284
|
+
throw new Error(
|
|
285
|
+
"Studio runtime template is missing an entry JS bundle in studio/assets."
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
const cssFiles = assetFiles.filter((file) => file.endsWith(".css")).sort();
|
|
289
|
+
const html = createStudioShell(entryScript, cssFiles);
|
|
290
|
+
await writeFile4(indexPath, html, "utf-8");
|
|
291
|
+
}
|
|
292
|
+
async function readLocalAgentNames(cwd) {
|
|
293
|
+
const agentsDir = join4(cwd, "agents");
|
|
294
|
+
try {
|
|
295
|
+
const entries = await readdir(agentsDir, { withFileTypes: true });
|
|
296
|
+
const names = [];
|
|
297
|
+
for (const entry of entries) {
|
|
298
|
+
if (!entry.isDirectory()) continue;
|
|
299
|
+
const indexPath = join4(agentsDir, entry.name, "index.ts");
|
|
300
|
+
const exists = await stat(indexPath).then(() => true).catch(() => false);
|
|
301
|
+
if (exists) names.push(entry.name);
|
|
302
|
+
}
|
|
303
|
+
return names.sort((a, b) => a.localeCompare(b));
|
|
304
|
+
} catch {
|
|
305
|
+
return [];
|
|
306
|
+
}
|
|
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) {
|
|
314
|
+
const localAgentNames = await readLocalAgentNames(cwd);
|
|
315
|
+
const state = await readProjectState(cwd);
|
|
316
|
+
const globalStore = await readAgentStore();
|
|
317
|
+
const byName = /* @__PURE__ */ new Map();
|
|
318
|
+
for (const name of localAgentNames) {
|
|
319
|
+
const localPath = join4(cwd, "agents", name, "index.ts");
|
|
320
|
+
byName.set(name, {
|
|
321
|
+
name,
|
|
322
|
+
environment: "local",
|
|
323
|
+
status: "offline",
|
|
324
|
+
hash: null,
|
|
325
|
+
workerUrl: null,
|
|
326
|
+
localPath,
|
|
327
|
+
updatedAt: null
|
|
328
|
+
});
|
|
329
|
+
}
|
|
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
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
return {
|
|
356
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
357
|
+
projectPath: cwd,
|
|
358
|
+
workerUrl: state?.workerUrl ?? null,
|
|
359
|
+
agents: Array.from(byName.values()).sort((a, b) => a.name.localeCompare(b.name))
|
|
360
|
+
};
|
|
361
|
+
}
|
|
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);
|
|
367
|
+
const template = await resolveRuntimeTemplate();
|
|
368
|
+
await rm(runtimeDir, { recursive: true, force: true });
|
|
369
|
+
await mkdir2(runtimeDir, { recursive: true });
|
|
370
|
+
await cp(template.studioTemplateDir, studioDir, { recursive: true });
|
|
371
|
+
await cp(template.workerEntryPath, workerEntrypointPath);
|
|
372
|
+
await ensureStudioIndex(studioDir);
|
|
373
|
+
const agentsSnapshot = await createAgentsSnapshot(cwd);
|
|
374
|
+
await writeFile4(
|
|
375
|
+
join4(runtimeDir, "agents.snapshot.json"),
|
|
376
|
+
`${JSON.stringify(agentsSnapshot, null, 2)}
|
|
377
|
+
`,
|
|
378
|
+
"utf-8"
|
|
379
|
+
);
|
|
380
|
+
const projectSlug = await resolveProjectSlug(cwd);
|
|
381
|
+
const workerName = buildWorkerName(projectSlug, cwd);
|
|
382
|
+
const wranglerConfig = createRuntimeConfig(workerName);
|
|
383
|
+
await writeFile4(
|
|
384
|
+
wranglerConfigPath,
|
|
385
|
+
`${JSON.stringify(wranglerConfig, null, 2)}
|
|
386
|
+
`,
|
|
387
|
+
"utf-8"
|
|
388
|
+
);
|
|
389
|
+
return {
|
|
390
|
+
runtimeDir,
|
|
391
|
+
studioDir,
|
|
392
|
+
workerEntrypointPath,
|
|
393
|
+
wranglerConfigPath,
|
|
394
|
+
workerName
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
export {
|
|
399
|
+
ensureStudioSecrets,
|
|
400
|
+
ensureSecretKey,
|
|
401
|
+
readProjectState,
|
|
402
|
+
writeProjectState,
|
|
403
|
+
getAgentStoreEntry,
|
|
404
|
+
writeAgentStoreEntry,
|
|
405
|
+
materializeRuntime
|
|
406
|
+
};
|
|
407
|
+
//# sourceMappingURL=chunk-RT2DIIQ5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/secret.ts","../src/utils/project-state.ts","../src/utils/agent-store.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 ProjectState {\n workerUrl: string;\n deployedAt: string;\n accountId: string;\n}\n\nconst KALP_DIR = \".kalp\";\nconst STATE_FILE = \"state.json\";\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 JSON.parse(content) as ProjectState;\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), \"utf-8\");\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { ensureGlobalConfigDir } from \"@/utils/config\";\n\nexport interface AgentStoreEntry {\n hash: string;\n timestamp: string;\n workerUrl: string;\n localPath: string;\n}\n\nexport type AgentStore = Record<string, AgentStoreEntry>;\n\nasync function getStorePath(): Promise<string> {\n return join(await ensureGlobalConfigDir(), \"agents.json\");\n}\n\nexport async function readAgentStore(): Promise<AgentStore> {\n try {\n const storePath = await getStorePath();\n const content = await readFile(storePath, \"utf-8\");\n return JSON.parse(content) as AgentStore;\n } catch {\n return {};\n }\n}\n\nexport async function getAgentStoreEntry(\n agentName: string,\n): Promise<AgentStoreEntry | null> {\n const store = await readAgentStore();\n return store[agentName] ?? null;\n}\n\nexport async function writeAgentStoreEntry(\n agentName: string,\n entry: AgentStoreEntry,\n): Promise<void> {\n const storePath = await getStorePath();\n const store = await readAgentStore();\n store[agentName] = entry;\n await writeFile(storePath, JSON.stringify(store, null, 2), \"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, normalize, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { readAgentStore } from \"@/utils/agent-store\";\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 environment: \"local\" | \"remote\" | \"both\";\n status: \"online\" | \"offline\";\n hash: 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 agents: RuntimeAgentRecord[];\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\nasync 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\nfunction isPathInsideProject(projectPath: string, candidatePath: string): boolean {\n const project = normalize(projectPath).toLowerCase();\n const candidate = normalize(candidatePath).toLowerCase();\n return candidate.startsWith(project);\n}\n\nasync function createAgentsSnapshot(cwd: string): Promise<RuntimeAgentsSnapshot> {\n const localAgentNames = await readLocalAgentNames(cwd);\n const state = await readProjectState(cwd);\n const globalStore = await readAgentStore();\n\n const byName = new Map<string, RuntimeAgentRecord>();\n\n for (const name of localAgentNames) {\n const localPath = join(cwd, \"agents\", name, \"index.ts\");\n byName.set(name, {\n name,\n environment: \"local\",\n status: \"offline\",\n hash: null,\n workerUrl: null,\n localPath,\n updatedAt: null,\n });\n }\n\n for (const [name, entry] of Object.entries(globalStore)) {\n if (!entry.localPath || !isPathInsideProject(cwd, entry.localPath)) continue;\n\n const existing = byName.get(name);\n const workerUrl =\n state?.workerUrl && !entry.workerUrl\n ? `${state.workerUrl.replace(/\\/$/, \"\")}/a/${name}`\n : entry.workerUrl ?? null;\n\n byName.set(name, {\n name,\n environment: existing ? \"both\" : \"remote\",\n status: workerUrl ? \"online\" : \"offline\",\n hash: entry.hash ?? null,\n workerUrl,\n localPath: existing?.localPath ?? entry.localPath,\n updatedAt: entry.timestamp ?? state?.deployedAt ?? null,\n });\n }\n\n if (state?.workerUrl) {\n for (const [name, record] of byName.entries()) {\n if (!record.workerUrl) {\n record.workerUrl = `${state.workerUrl.replace(/\\/$/, \"\")}/a/${name}`;\n record.environment =\n record.environment === \"local\" ? \"both\" : record.environment;\n record.status = \"online\";\n record.updatedAt = record.updatedAt ?? state.deployedAt;\n byName.set(name, record);\n }\n }\n }\n\n return {\n generatedAt: new Date().toISOString(),\n projectPath: cwd,\n workerUrl: state?.workerUrl ?? null,\n agents: Array.from(byName.values()).sort((a, b) => a.name.localeCompare(b.name)),\n };\n}\n\nexport async function materializeRuntime(cwd: string): Promise<RuntimePaths> {\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);\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","readFile","writeFile","join","join","readFile","writeFile","mkdir","readFile","writeFile","join","join","readFile","writeFile","mkdir"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runInitialDeploy
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-NIPAXEFM.js";
|
|
5
|
+
import "./chunk-RT2DIIQ5.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-
|
|
63
|
+
//# sourceMappingURL=deploy-3EVKLTWF.js.map
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
import {
|
|
3
3
|
ensureSecretKey,
|
|
4
4
|
materializeRuntime
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-RT2DIIQ5.js";
|
|
6
|
+
import "./chunk-FO24J6XL.js";
|
|
6
7
|
|
|
7
8
|
// src/commands/dev.ts
|
|
8
9
|
import { copyFile } from "fs/promises";
|
|
@@ -13,29 +14,14 @@ import * as p from "@clack/prompts";
|
|
|
13
14
|
import pc from "picocolors";
|
|
14
15
|
import { execa } from "execa";
|
|
15
16
|
import open from "open";
|
|
16
|
-
|
|
17
|
-
// src/utils/studio-token.ts
|
|
18
|
-
import { SignJWT } from "jose";
|
|
19
|
-
async function createStudioToken(secretKey) {
|
|
20
|
-
const secret = new TextEncoder().encode(secretKey);
|
|
21
|
-
return new SignJWT({
|
|
22
|
-
sub: "cli-user",
|
|
23
|
-
aud: "kalp-studio",
|
|
24
|
-
iat: Math.floor(Date.now() / 1e3),
|
|
25
|
-
exp: Math.floor(Date.now() / 1e3) + 3600
|
|
26
|
-
}).setProtectedHeader({ alg: "HS256" }).sign(secret);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// src/commands/dev.ts
|
|
30
17
|
var LOGO = "\u{1F98B}";
|
|
31
18
|
var dev_default = defineCommand({
|
|
32
19
|
meta: { name: "dev", description: "Run Worker + Studio local environment" },
|
|
33
20
|
async run() {
|
|
34
21
|
const cwd = process.cwd();
|
|
35
22
|
p.intro(`${LOGO} ${pc.bold("kalp dev")}`);
|
|
36
|
-
|
|
23
|
+
await ensureSecretKey(cwd);
|
|
37
24
|
await copyFile(join(cwd, ".env"), join(cwd, ".dev.vars"));
|
|
38
|
-
const token = await createStudioToken(key);
|
|
39
25
|
const runtime = await materializeRuntime(cwd);
|
|
40
26
|
p.note("Starting local runtime (wrangler dev :8787)");
|
|
41
27
|
const backend = execa(
|
|
@@ -56,7 +42,7 @@ var dev_default = defineCommand({
|
|
|
56
42
|
process.on("SIGINT", shutdown);
|
|
57
43
|
process.on("SIGTERM", shutdown);
|
|
58
44
|
await delay(2500);
|
|
59
|
-
const studioUrl =
|
|
45
|
+
const studioUrl = "http://localhost:8787/studio/login";
|
|
60
46
|
await open(studioUrl);
|
|
61
47
|
p.log.success(`Studio opened at ${pc.cyan(studioUrl)}`);
|
|
62
48
|
try {
|
|
@@ -71,4 +57,4 @@ var dev_default = defineCommand({
|
|
|
71
57
|
export {
|
|
72
58
|
dev_default as default
|
|
73
59
|
};
|
|
74
|
-
//# sourceMappingURL=dev-
|
|
60
|
+
//# sourceMappingURL=dev-UC2WFSOE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/dev.ts"],"sourcesContent":["import { copyFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { setTimeout as delay } from \"node:timers/promises\";\nimport { defineCommand } from \"citty\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { execa } from \"execa\";\nimport open from \"open\";\nimport { ensureSecretKey } from \"@/utils/secret\";\nimport { materializeRuntime } from \"@/utils/runtime\";\n\nconst LOGO = \"🦋\";\n\nexport default defineCommand({\n meta: { name: \"dev\", description: \"Run Worker + Studio local environment\" },\n async run() {\n const cwd = process.cwd();\n\n p.intro(`${LOGO} ${pc.bold(\"kalp dev\")}`);\n\n await ensureSecretKey(cwd);\n await copyFile(join(cwd, \".env\"), join(cwd, \".dev.vars\"));\n const runtime = await materializeRuntime(cwd);\n\n p.note(\"Starting local runtime (wrangler dev :8787)\");\n\n const backend = execa(\n \"npx\",\n [\n \"wrangler\",\n \"dev\",\n \"--port\",\n \"8787\",\n \"--config\",\n runtime.wranglerConfigPath,\n ],\n { cwd, stdio: \"inherit\" },\n );\n\n const shutdown = () => {\n backend.kill(\"SIGINT\");\n };\n\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n\n await delay(2500);\n const studioUrl = \"http://localhost:8787/studio/login\";\n await open(studioUrl);\n p.log.success(`Studio opened at ${pc.cyan(studioUrl)}`);\n\n try {\n await backend;\n } finally {\n shutdown();\n process.off(\"SIGINT\", shutdown);\n process.off(\"SIGTERM\", shutdown);\n }\n },\n});\n"],"mappings":";;;;;;;;AAAA,SAAS,gBAAgB;AACzB,SAAS,YAAY;AACrB,SAAS,cAAc,aAAa;AACpC,SAAS,qBAAqB;AAC9B,YAAY,OAAO;AACnB,OAAO,QAAQ;AACf,SAAS,aAAa;AACtB,OAAO,UAAU;AAIjB,IAAM,OAAO;AAEb,IAAO,cAAQ,cAAc;AAAA,EAC3B,MAAM,EAAE,MAAM,OAAO,aAAa,wCAAwC;AAAA,EAC1E,MAAM,MAAM;AACV,UAAM,MAAM,QAAQ,IAAI;AAExB,IAAE,QAAM,GAAG,IAAI,IAAI,GAAG,KAAK,UAAU,CAAC,EAAE;AAExC,UAAM,gBAAgB,GAAG;AACzB,UAAM,SAAS,KAAK,KAAK,MAAM,GAAG,KAAK,KAAK,WAAW,CAAC;AACxD,UAAM,UAAU,MAAM,mBAAmB,GAAG;AAE5C,IAAE,OAAK,6CAA6C;AAEpD,UAAM,UAAU;AAAA,MACd;AAAA,MACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,MACV;AAAA,MACA,EAAE,KAAK,OAAO,UAAU;AAAA,IAC1B;AAEA,UAAM,WAAW,MAAM;AACrB,cAAQ,KAAK,QAAQ;AAAA,IACvB;AAEA,YAAQ,GAAG,UAAU,QAAQ;AAC7B,YAAQ,GAAG,WAAW,QAAQ;AAE9B,UAAM,MAAM,IAAI;AAChB,UAAM,YAAY;AAClB,UAAM,KAAK,SAAS;AACpB,IAAE,MAAI,QAAQ,oBAAoB,GAAG,KAAK,SAAS,CAAC,EAAE;AAEtD,QAAI;AACF,YAAM;AAAA,IACR,UAAE;AACA,eAAS;AACT,cAAQ,IAAI,UAAU,QAAQ;AAC9B,cAAQ,IAAI,WAAW,QAAQ;AAAA,IACjC;AAAA,EACF;AACF,CAAC;","names":[]}
|