@kalphq/cli 0.0.0-dev-20260513152102 → 0.0.0-dev-20260517015600
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/{add-YZSIMRPC.js → add-5WUS5HGV.js} +16 -8
- package/dist/add-5WUS5HGV.js.map +1 -0
- package/dist/{agents-WYK6WNQP.js → agents-L22L47II.js} +3 -3
- package/dist/ai-7EBQF25Y.js +12 -0
- package/dist/ai-7EBQF25Y.js.map +1 -0
- package/dist/{chunk-IZXCZ3IA.js → chunk-4CPUJ537.js} +2 -2
- package/dist/chunk-5YUU3KLB.js +40 -0
- package/dist/chunk-5YUU3KLB.js.map +1 -0
- package/dist/chunk-7KVCCBPJ.js +139 -0
- package/dist/chunk-7KVCCBPJ.js.map +1 -0
- package/dist/{chunk-S3KAVLVM.js → chunk-D53K6UE6.js} +2 -2
- package/dist/chunk-D53K6UE6.js.map +1 -0
- package/dist/{chunk-4CEJYSJY.js → chunk-DLUULDXW.js} +12 -45
- package/dist/chunk-DLUULDXW.js.map +1 -0
- package/dist/chunk-DXNHT4HF.js +99 -0
- package/dist/chunk-DXNHT4HF.js.map +1 -0
- package/dist/{chunk-XVD3FFOJ.js → chunk-JXR6TPR5.js} +51 -72
- package/dist/chunk-JXR6TPR5.js.map +1 -0
- package/dist/chunk-LEKRFM4Q.js +49 -0
- package/dist/chunk-LEKRFM4Q.js.map +1 -0
- package/dist/chunk-QT2JFINP.js +99 -0
- package/dist/chunk-QT2JFINP.js.map +1 -0
- package/dist/{chunk-5SZMD7E6.js → chunk-TNNBTSDC.js} +2 -2
- package/dist/{chunk-5SZMD7E6.js.map → chunk-TNNBTSDC.js.map} +1 -1
- package/dist/{generate-JW2DMJ3W.js → chunk-ZX7TIQM7.js} +127 -120
- package/dist/chunk-ZX7TIQM7.js.map +1 -0
- package/dist/{create-UCJ77P62.js → create-ILPQCRA2.js} +2 -2
- package/dist/{delete-QPYVL4OU.js → delete-AJFAAGYJ.js} +9 -8
- package/dist/{delete-QPYVL4OU.js.map → delete-AJFAAGYJ.js.map} +1 -1
- package/dist/{delete-FIXMFFNZ.js → delete-IFVGULOA.js} +21 -13
- package/dist/delete-IFVGULOA.js.map +1 -0
- package/dist/{deploy-DRZZ3YRB.js → deploy-EWYNN3VU.js} +9 -6
- package/dist/{deploy-DRZZ3YRB.js.map → deploy-EWYNN3VU.js.map} +1 -1
- package/dist/{dev-5YY6W4WM.js → dev-3IEEUVYM.js} +66 -11
- package/dist/dev-3IEEUVYM.js.map +1 -0
- package/dist/generate-2MO7PZBT.js +69 -0
- package/dist/generate-2MO7PZBT.js.map +1 -0
- package/dist/generate-ODZUKTF2.js +146 -0
- package/dist/generate-ODZUKTF2.js.map +1 -0
- package/dist/index.js +32 -12
- package/dist/index.js.map +1 -1
- package/dist/{list-FKH4DWCF.js → list-BNQ34QG3.js} +6 -5
- package/dist/{list-FKH4DWCF.js.map → list-BNQ34QG3.js.map} +1 -1
- package/dist/{list-GZBBOFX5.js → list-WHYV5JZ4.js} +5 -4
- package/dist/{list-GZBBOFX5.js.map → list-WHYV5JZ4.js.map} +1 -1
- package/dist/{login-MGPA2VYV.js → login-BDLHS4HC.js} +13 -8
- package/dist/login-BDLHS4HC.js.map +1 -0
- package/dist/{mcp-DRMQYA7E.js → mcp-77OLNT5R.js} +2 -2
- package/dist/{pull-V7QJBVNZ.js → pull-CFDZS6VB.js} +8 -7
- package/dist/{pull-V7QJBVNZ.js.map → pull-CFDZS6VB.js.map} +1 -1
- package/dist/{push-P6CKRYT7.js → push-OL7562HM.js} +159 -47
- package/dist/push-OL7562HM.js.map +1 -0
- package/dist/runtime-template/studio/index.html +3 -0
- package/dist/{secrets-M43LLCTB.js → secrets-BPESLXMK.js} +6 -6
- package/dist/{sync-LTBH6DI5.js → sync-JJDODKMO.js} +8 -7
- package/dist/{sync-LTBH6DI5.js.map → sync-JJDODKMO.js.map} +1 -1
- package/package.json +5 -4
- package/dist/add-YZSIMRPC.js.map +0 -1
- package/dist/chunk-4CEJYSJY.js.map +0 -1
- package/dist/chunk-LPEV4QH2.js +0 -208
- package/dist/chunk-LPEV4QH2.js.map +0 -1
- package/dist/chunk-S3KAVLVM.js.map +0 -1
- package/dist/chunk-VCFH3R34.js +0 -103
- package/dist/chunk-VCFH3R34.js.map +0 -1
- package/dist/chunk-XVD3FFOJ.js.map +0 -1
- package/dist/delete-FIXMFFNZ.js.map +0 -1
- package/dist/dev-5YY6W4WM.js.map +0 -1
- package/dist/generate-JW2DMJ3W.js.map +0 -1
- package/dist/login-MGPA2VYV.js.map +0 -1
- package/dist/push-P6CKRYT7.js.map +0 -1
- /package/dist/{agents-WYK6WNQP.js.map → agents-L22L47II.js.map} +0 -0
- /package/dist/{chunk-IZXCZ3IA.js.map → chunk-4CPUJ537.js.map} +0 -0
- /package/dist/{create-UCJ77P62.js.map → create-ILPQCRA2.js.map} +0 -0
- /package/dist/{mcp-DRMQYA7E.js.map → mcp-77OLNT5R.js.map} +0 -0
- /package/dist/{secrets-M43LLCTB.js.map → secrets-BPESLXMK.js.map} +0 -0
|
@@ -4,6 +4,10 @@ import {
|
|
|
4
4
|
resolveIdentityAuthRequirements,
|
|
5
5
|
resolveRuntimeIdentityConfig
|
|
6
6
|
} from "./chunk-EXXTCGKR.js";
|
|
7
|
+
import {
|
|
8
|
+
getRequiredSecretForProvider,
|
|
9
|
+
resolveProviderFromConfig
|
|
10
|
+
} from "./chunk-LEKRFM4Q.js";
|
|
7
11
|
|
|
8
12
|
// src/utils/project-state.ts
|
|
9
13
|
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
@@ -64,63 +68,25 @@ async function writeProjectState(cwd, state) {
|
|
|
64
68
|
|
|
65
69
|
// src/utils/runtime.ts
|
|
66
70
|
import { createHash } from "crypto";
|
|
71
|
+
import { build as build2 } from "esbuild";
|
|
67
72
|
import {
|
|
68
|
-
access
|
|
73
|
+
access,
|
|
69
74
|
cp,
|
|
70
75
|
mkdir as mkdir2,
|
|
71
76
|
readdir,
|
|
72
|
-
readFile as
|
|
77
|
+
readFile as readFile2,
|
|
73
78
|
rm,
|
|
74
79
|
stat,
|
|
75
80
|
writeFile as writeFile3
|
|
76
81
|
} from "fs/promises";
|
|
77
|
-
import { basename, dirname, join as
|
|
82
|
+
import { basename, dirname, join as join3, resolve } from "path";
|
|
78
83
|
import { fileURLToPath } from "url";
|
|
79
84
|
import { deriveLabelFromName } from "@kalphq/project";
|
|
80
85
|
|
|
81
|
-
// src/utils/ai.ts
|
|
82
|
-
import { access, readFile as readFile2 } from "fs/promises";
|
|
83
|
-
import { constants } from "fs";
|
|
84
|
-
import { join as join2 } from "path";
|
|
85
|
-
import { createJiti } from "jiti";
|
|
86
|
-
var PROVIDER_SECRET_MAP = {
|
|
87
|
-
openai: "OPENAI_API_KEY",
|
|
88
|
-
anthropic: "ANTHROPIC_API_KEY",
|
|
89
|
-
openrouter: "OPENROUTER_API_KEY",
|
|
90
|
-
custom: "CUSTOM_AI_API_KEY"
|
|
91
|
-
};
|
|
92
|
-
function parseEnv(content) {
|
|
93
|
-
const env = {};
|
|
94
|
-
for (const raw of content.split(/\r?\n/g)) {
|
|
95
|
-
const line = raw.trim();
|
|
96
|
-
if (!line || line.startsWith("#")) continue;
|
|
97
|
-
const idx = line.indexOf("=");
|
|
98
|
-
if (idx <= 0) continue;
|
|
99
|
-
env[line.slice(0, idx).trim()] = line.slice(idx + 1);
|
|
100
|
-
}
|
|
101
|
-
return env;
|
|
102
|
-
}
|
|
103
|
-
async function resolveProviderFromConfig(cwd) {
|
|
104
|
-
const configPath = join2(cwd, "kalp.config.ts");
|
|
105
|
-
await access(configPath, constants.F_OK);
|
|
106
|
-
const jiti = createJiti(cwd, { interopDefault: true });
|
|
107
|
-
const config = await jiti.import(configPath);
|
|
108
|
-
const provider = config?.default?.ai?.provider ?? config?.ai?.provider ?? "openai";
|
|
109
|
-
return provider;
|
|
110
|
-
}
|
|
111
|
-
async function readDotEnv(cwd) {
|
|
112
|
-
const envPath = join2(cwd, ".env");
|
|
113
|
-
const content = await readFile2(envPath, "utf-8").catch(() => "");
|
|
114
|
-
return parseEnv(content);
|
|
115
|
-
}
|
|
116
|
-
function getRequiredSecretForProvider(provider) {
|
|
117
|
-
return PROVIDER_SECRET_MAP[provider];
|
|
118
|
-
}
|
|
119
|
-
|
|
120
86
|
// src/utils/runtime-identity.ts
|
|
121
87
|
import { build } from "esbuild";
|
|
122
88
|
import { writeFile as writeFile2 } from "fs/promises";
|
|
123
|
-
import { join as
|
|
89
|
+
import { join as join2 } from "path";
|
|
124
90
|
var DEFAULT_IDENTITY_MAP_SOURCE = `export default function mapIdentity(payload) {
|
|
125
91
|
const sub =
|
|
126
92
|
payload && typeof payload === "object" && typeof payload.sub === "string"
|
|
@@ -194,8 +160,8 @@ export default mapIdentity;
|
|
|
194
160
|
}
|
|
195
161
|
async function materializeRuntimeIdentity(params) {
|
|
196
162
|
const { cwd, runtimeDir } = params;
|
|
197
|
-
const identityConfigPath =
|
|
198
|
-
const identityMapPath =
|
|
163
|
+
const identityConfigPath = join2(runtimeDir, "identity.config.json");
|
|
164
|
+
const identityMapPath = join2(runtimeDir, "identity.map.mjs");
|
|
199
165
|
let rawConfig = {};
|
|
200
166
|
try {
|
|
201
167
|
const loaded = await loadProjectConfig(cwd);
|
|
@@ -241,9 +207,9 @@ function sanitizeSegment(input) {
|
|
|
241
207
|
}
|
|
242
208
|
async function resolveProjectSlug(cwd) {
|
|
243
209
|
const fallback = sanitizeSegment(basename(cwd)) || "agent";
|
|
244
|
-
const packageJsonPath =
|
|
210
|
+
const packageJsonPath = join3(cwd, "package.json");
|
|
245
211
|
try {
|
|
246
|
-
const content = await
|
|
212
|
+
const content = await readFile2(packageJsonPath, "utf-8");
|
|
247
213
|
const pkg = JSON.parse(content);
|
|
248
214
|
const name = typeof pkg.name === "string" ? pkg.name : "";
|
|
249
215
|
const sanitized = sanitizeSegment(name);
|
|
@@ -321,28 +287,28 @@ function runtimeTemplateCandidates() {
|
|
|
321
287
|
);
|
|
322
288
|
return [
|
|
323
289
|
{
|
|
324
|
-
studioTemplateDir:
|
|
325
|
-
workerEntryPath:
|
|
290
|
+
studioTemplateDir: join3(distTemplateRoot, STUDIO_DIR),
|
|
291
|
+
workerEntryPath: join3(distTemplateRoot, WORKER_ENTRY_FILE)
|
|
326
292
|
},
|
|
327
293
|
{
|
|
328
|
-
studioTemplateDir:
|
|
329
|
-
workerEntryPath:
|
|
294
|
+
studioTemplateDir: join3(packageRootTemplate, STUDIO_DIR),
|
|
295
|
+
workerEntryPath: join3(packageRootTemplate, WORKER_ENTRY_FILE)
|
|
330
296
|
},
|
|
331
297
|
{
|
|
332
|
-
studioTemplateDir:
|
|
333
|
-
workerEntryPath:
|
|
298
|
+
studioTemplateDir: join3(sourceTemplateRoot, STUDIO_DIR),
|
|
299
|
+
workerEntryPath: join3(sourceTemplateRoot, WORKER_ENTRY_FILE)
|
|
334
300
|
},
|
|
335
301
|
{
|
|
336
302
|
studioTemplateDir: monorepoStudioDist,
|
|
337
|
-
workerEntryPath:
|
|
303
|
+
workerEntryPath: join3(sourceTemplateRoot, WORKER_ENTRY_FILE)
|
|
338
304
|
}
|
|
339
305
|
];
|
|
340
306
|
}
|
|
341
307
|
async function resolveRuntimeTemplate() {
|
|
342
308
|
for (const candidate of runtimeTemplateCandidates()) {
|
|
343
309
|
try {
|
|
344
|
-
await
|
|
345
|
-
await
|
|
310
|
+
await access(candidate.studioTemplateDir);
|
|
311
|
+
await access(candidate.workerEntryPath);
|
|
346
312
|
return candidate;
|
|
347
313
|
} catch {
|
|
348
314
|
}
|
|
@@ -369,13 +335,13 @@ ${cssLinks}
|
|
|
369
335
|
`;
|
|
370
336
|
}
|
|
371
337
|
async function ensureStudioIndex(studioDir) {
|
|
372
|
-
const indexPath =
|
|
338
|
+
const indexPath = join3(studioDir, "index.html");
|
|
373
339
|
try {
|
|
374
|
-
await
|
|
340
|
+
await access(indexPath);
|
|
375
341
|
return;
|
|
376
342
|
} catch {
|
|
377
343
|
}
|
|
378
|
-
const assetsDir =
|
|
344
|
+
const assetsDir = join3(studioDir, "assets");
|
|
379
345
|
const assetFiles = await readdir(assetsDir);
|
|
380
346
|
const entryScript = assetFiles.find((file) => /^index-.*\.js$/i.test(file)) ?? assetFiles.find((file) => file.endsWith(".js"));
|
|
381
347
|
if (!entryScript) {
|
|
@@ -388,13 +354,13 @@ async function ensureStudioIndex(studioDir) {
|
|
|
388
354
|
await writeFile3(indexPath, html, "utf-8");
|
|
389
355
|
}
|
|
390
356
|
async function readLocalAgentNames(cwd) {
|
|
391
|
-
const agentsDir =
|
|
357
|
+
const agentsDir = join3(cwd, "agents");
|
|
392
358
|
try {
|
|
393
359
|
const entries = await readdir(agentsDir, { withFileTypes: true });
|
|
394
360
|
const names = [];
|
|
395
361
|
for (const entry of entries) {
|
|
396
362
|
if (!entry.isDirectory()) continue;
|
|
397
|
-
const indexPath =
|
|
363
|
+
const indexPath = join3(agentsDir, entry.name, "index.ts");
|
|
398
364
|
const exists = await stat(indexPath).then(() => true).catch(() => false);
|
|
399
365
|
if (exists) names.push(entry.name);
|
|
400
366
|
}
|
|
@@ -409,7 +375,7 @@ async function createAgentsSnapshot(cwd, mode) {
|
|
|
409
375
|
const byName = /* @__PURE__ */ new Map();
|
|
410
376
|
const stateAgents = state?.agents ?? {};
|
|
411
377
|
for (const name of localAgentNames) {
|
|
412
|
-
const localPath =
|
|
378
|
+
const localPath = join3(cwd, "agents", name, "index.ts");
|
|
413
379
|
const saved = stateAgents[name];
|
|
414
380
|
const hasRemoteVersion = !!saved?.lastRemoteHash && (saved?.currentVersion ?? 0) > 0;
|
|
415
381
|
if (mode === "remote" && !hasRemoteVersion) {
|
|
@@ -437,7 +403,7 @@ async function createAgentsSnapshot(cwd, mode) {
|
|
|
437
403
|
for (const [name, saved] of Object.entries(stateAgents)) {
|
|
438
404
|
const hasRemoteVersion = !!saved.lastRemoteHash && (saved.currentVersion ?? 0) > 0;
|
|
439
405
|
if (!hasRemoteVersion || byName.has(name)) continue;
|
|
440
|
-
const localPath = saved.localPath ??
|
|
406
|
+
const localPath = saved.localPath ?? join3(cwd, "agents", name, "index.ts");
|
|
441
407
|
const workerUrl = saved.workerUrl ?? (state?.workerUrl ? `${state.workerUrl.replace(/\/$/, "")}/a/${name}` : null);
|
|
442
408
|
const versionNumber = saved.currentVersion > 0 ? saved.currentVersion : null;
|
|
443
409
|
byName.set(name, {
|
|
@@ -468,7 +434,7 @@ async function createAgentsSnapshot(cwd, mode) {
|
|
|
468
434
|
async function writeRuntimeAgentsSnapshot(params) {
|
|
469
435
|
const snapshot = await createAgentsSnapshot(params.cwd, params.mode);
|
|
470
436
|
await writeFile3(
|
|
471
|
-
|
|
437
|
+
join3(params.runtimeDir, "agents.snapshot.json"),
|
|
472
438
|
`${JSON.stringify(snapshot, null, 2)}
|
|
473
439
|
`,
|
|
474
440
|
"utf-8"
|
|
@@ -476,16 +442,32 @@ async function writeRuntimeAgentsSnapshot(params) {
|
|
|
476
442
|
}
|
|
477
443
|
async function materializeRuntime(cwd, options = {}) {
|
|
478
444
|
const mode = options.mode ?? "remote";
|
|
479
|
-
const runtimeDir =
|
|
480
|
-
const studioDir =
|
|
481
|
-
const workerEntrypointPath =
|
|
482
|
-
const wranglerConfigPath =
|
|
445
|
+
const runtimeDir = join3(cwd, RUNTIME_ROOT, RUNTIME_DIR);
|
|
446
|
+
const studioDir = join3(runtimeDir, STUDIO_DIR);
|
|
447
|
+
const workerEntrypointPath = join3(runtimeDir, WORKER_ENTRY_FILE);
|
|
448
|
+
const wranglerConfigPath = join3(runtimeDir, WRANGLER_CONFIG_FILE);
|
|
483
449
|
const template = await resolveRuntimeTemplate();
|
|
484
450
|
await rm(runtimeDir, { recursive: true, force: true });
|
|
485
451
|
await mkdir2(runtimeDir, { recursive: true });
|
|
486
452
|
await cp(template.studioTemplateDir, studioDir, { recursive: true });
|
|
487
453
|
await cp(template.workerEntryPath, workerEntrypointPath);
|
|
488
454
|
await ensureStudioIndex(studioDir);
|
|
455
|
+
await build2({
|
|
456
|
+
entryPoints: [workerEntrypointPath],
|
|
457
|
+
bundle: true,
|
|
458
|
+
outfile: workerEntrypointPath,
|
|
459
|
+
allowOverwrite: true,
|
|
460
|
+
platform: "browser",
|
|
461
|
+
format: "esm",
|
|
462
|
+
target: "es2022",
|
|
463
|
+
external: [
|
|
464
|
+
"cloudflare:workers",
|
|
465
|
+
"./agents.snapshot.json",
|
|
466
|
+
"./identity.config.json",
|
|
467
|
+
"./identity.map.mjs"
|
|
468
|
+
],
|
|
469
|
+
logLevel: "error"
|
|
470
|
+
});
|
|
489
471
|
await writeRuntimeAgentsSnapshot({ cwd, runtimeDir, mode });
|
|
490
472
|
const identity = await materializeRuntimeIdentity({ cwd, runtimeDir });
|
|
491
473
|
const projectSlug = await resolveProjectSlug(cwd);
|
|
@@ -528,11 +510,8 @@ async function materializeRuntime(cwd, options = {}) {
|
|
|
528
510
|
export {
|
|
529
511
|
readProjectState,
|
|
530
512
|
writeProjectState,
|
|
531
|
-
resolveProviderFromConfig,
|
|
532
|
-
readDotEnv,
|
|
533
|
-
getRequiredSecretForProvider,
|
|
534
513
|
readLocalAgentNames,
|
|
535
514
|
writeRuntimeAgentsSnapshot,
|
|
536
515
|
materializeRuntime
|
|
537
516
|
};
|
|
538
|
-
//# sourceMappingURL=chunk-
|
|
517
|
+
//# sourceMappingURL=chunk-JXR6TPR5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/project-state.ts","../src/utils/runtime.ts","../src/utils/runtime-identity.ts"],"sourcesContent":["import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nexport interface ProjectAgentState {\n currentHash: string | null;\n currentVersion: number;\n lastLocalHash: string | null;\n lastRemoteHash: string | null;\n lastPushedAt: string | null;\n localPath: string;\n workerUrl: string | null;\n}\n\nexport interface ProjectState {\n workerUrl: string | null;\n deployedAt: string | null;\n accountId: string | null;\n studioCredentialsFingerprint?: string | null;\n serviceKeyFingerprint?: string | null;\n agents: Record<string, ProjectAgentState>;\n}\n\nconst KALP_DIR = \".kalp\";\nconst STATE_FILE = \"state.json\";\n\nfunction normalizeProjectState(raw: unknown): ProjectState | null {\n if (!raw || typeof raw !== \"object\") return null;\n const value = raw as Record<string, unknown>;\n const workerUrl =\n typeof value.workerUrl === \"string\" && value.workerUrl.length > 0\n ? value.workerUrl\n : null;\n const deployedAt =\n typeof value.deployedAt === \"string\" && value.deployedAt.length > 0\n ? value.deployedAt\n : null;\n const accountId =\n typeof value.accountId === \"string\" && value.accountId.length > 0\n ? value.accountId\n : null;\n const studioCredentialsFingerprint =\n typeof value.studioCredentialsFingerprint === \"string\" &&\n value.studioCredentialsFingerprint.length > 0\n ? value.studioCredentialsFingerprint\n : null;\n const serviceKeyFingerprint =\n typeof value.serviceKeyFingerprint === \"string\" &&\n value.serviceKeyFingerprint.length > 0\n ? value.serviceKeyFingerprint\n : null;\n\n const agents: Record<string, ProjectAgentState> = {};\n const rawAgents =\n value.agents && typeof value.agents === \"object\"\n ? (value.agents as Record<string, unknown>)\n : {};\n\n for (const [name, entry] of Object.entries(rawAgents)) {\n if (!entry || typeof entry !== \"object\") continue;\n const item = entry as Record<string, unknown>;\n if (typeof item.localPath !== \"string\" || item.localPath.length === 0) {\n continue;\n }\n\n const currentVersion =\n typeof item.currentVersion === \"number\" && Number.isFinite(item.currentVersion)\n ? Math.max(0, Math.floor(item.currentVersion))\n : 0;\n\n agents[name] = {\n currentHash: typeof item.currentHash === \"string\" ? item.currentHash : null,\n currentVersion,\n lastLocalHash: typeof item.lastLocalHash === \"string\" ? item.lastLocalHash : null,\n lastRemoteHash:\n typeof item.lastRemoteHash === \"string\" ? item.lastRemoteHash : null,\n lastPushedAt: typeof item.lastPushedAt === \"string\" ? item.lastPushedAt : null,\n localPath: item.localPath,\n workerUrl: typeof item.workerUrl === \"string\" ? item.workerUrl : null,\n };\n }\n\n return {\n workerUrl,\n deployedAt,\n accountId,\n studioCredentialsFingerprint,\n serviceKeyFingerprint,\n agents,\n };\n}\n\nexport async function readProjectState(cwd: string): Promise<ProjectState | null> {\n try {\n const statePath = join(cwd, KALP_DIR, STATE_FILE);\n const content = await readFile(statePath, \"utf-8\");\n return normalizeProjectState(JSON.parse(content));\n } catch {\n return null;\n }\n}\n\nexport async function writeProjectState(\n cwd: string,\n state: ProjectState,\n): Promise<void> {\n const dir = join(cwd, KALP_DIR);\n await mkdir(dir, { recursive: true });\n await writeFile(join(dir, STATE_FILE), `${JSON.stringify(state, null, 2)}\\n`, \"utf-8\");\n}\n","import { createHash } from \"node:crypto\";\nimport { build } from \"esbuild\";\nimport {\n access,\n cp,\n mkdir,\n readdir,\n readFile,\n rm,\n stat,\n writeFile,\n} from \"node:fs/promises\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { deriveLabelFromName } from \"@kalphq/project\";\nimport { getRequiredSecretForProvider, resolveProviderFromConfig } from \"@/utils/ai\";\nimport {\n resolveIdentityAuthRequirements,\n} from \"@/utils/project-config\";\nimport { readProjectState } from \"@/utils/project-state\";\nimport { materializeRuntimeIdentity } from \"@/utils/runtime-identity\";\n\nconst RUNTIME_ROOT = \".kalp\";\nconst RUNTIME_DIR = \"runtime\";\nconst STUDIO_DIR = \"studio\";\nconst WRANGLER_CONFIG_FILE = \"wrangler.jsonc\";\nconst WORKER_ENTRY_FILE = \"worker-entry.js\";\nconst COMPATIBILITY_DATE = \"2026-05-10\";\n\nexport interface RuntimePaths {\n runtimeDir: string;\n studioDir: string;\n workerEntrypointPath: string;\n wranglerConfigPath: string;\n workerName: string;\n}\n\ninterface RuntimeAgentRecord {\n name: string;\n label?: string;\n tags?: string[];\n environment: \"local\" | \"remote\" | \"both\";\n status: \"online\" | \"offline\";\n hash: string | null;\n version: string | null;\n versionNumber: number | null;\n lastRemoteHash: string | null;\n lastLocalHash: string | null;\n workerUrl: string | null;\n localPath: string | null;\n updatedAt: string | null;\n}\n\ninterface RuntimeAgentsSnapshot {\n generatedAt: string;\n projectPath: string;\n workerUrl: string | null;\n mode: \"local\" | \"remote\";\n agents: RuntimeAgentRecord[];\n}\n\nexport interface MaterializeRuntimeOptions {\n mode?: \"local\" | \"remote\";\n}\n\ninterface WranglerConfig {\n $schema: string;\n name: string;\n main: string;\n compatibility_date: string;\n compatibility_flags: string[];\n migrations: Array<{ tag: string; new_sqlite_classes: string[] }>;\n durable_objects: {\n bindings: Array<{ name: string; class_name: string }>;\n };\n kv_namespaces: Array<{ binding: string }>;\n assets: {\n directory: string;\n binding: string;\n run_worker_first: boolean;\n };\n observability: { enabled: boolean };\n upload_source_maps: boolean;\n vars: {\n KALP_ENV: \"local\" | \"remote\";\n };\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(\n workerName: string,\n mode: \"local\" | \"remote\",\n requiredSecrets: string[],\n): 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 vars: {\n KALP_ENV: mode,\n },\n secrets: {\n required: requiredSecrets,\n },\n };\n}\n\nfunction runtimeTemplateCandidates(): Array<{\n studioTemplateDir: string;\n workerEntryPath: string;\n}> {\n const here = dirname(fileURLToPath(import.meta.url));\n const distTemplateRoot = resolve(here, \"runtime-template\");\n const packageRootTemplate = resolve(here, \"..\", \"runtime-template\");\n const sourceTemplateRoot = resolve(here, \"..\", \"..\", \"runtime-template\");\n const monorepoStudioDist = resolve(\n here,\n \"..\",\n \"..\",\n \"..\",\n \"..\",\n \"apps\",\n \"studio\",\n \"dist\",\n \"client\",\n );\n\n return [\n {\n studioTemplateDir: join(distTemplateRoot, STUDIO_DIR),\n workerEntryPath: join(distTemplateRoot, WORKER_ENTRY_FILE),\n },\n {\n studioTemplateDir: join(packageRootTemplate, STUDIO_DIR),\n workerEntryPath: join(packageRootTemplate, WORKER_ENTRY_FILE),\n },\n {\n studioTemplateDir: join(sourceTemplateRoot, STUDIO_DIR),\n workerEntryPath: join(sourceTemplateRoot, WORKER_ENTRY_FILE),\n },\n {\n studioTemplateDir: monorepoStudioDist,\n workerEntryPath: join(sourceTemplateRoot, WORKER_ENTRY_FILE),\n },\n ];\n}\n\nasync function resolveRuntimeTemplate(): Promise<RuntimeTemplatePaths> {\n for (const candidate of runtimeTemplateCandidates()) {\n try {\n await access(candidate.studioTemplateDir);\n await access(candidate.workerEntryPath);\n return candidate;\n } catch {\n // continue\n }\n }\n\n throw new Error(\n \"Kalp runtime template not found in CLI package. Reinstall @kalphq/cli.\",\n );\n}\n\nfunction createStudioShell(entryScript: string, cssFiles: string[]): string {\n const cssLinks = cssFiles\n .map((file) => ` <link rel=\"stylesheet\" href=\"/studio/assets/${file}\" />`)\n .join(\"\\n\");\n\n return `<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>Kalp Studio</title>\n${cssLinks}\n </head>\n <body>\n <div id=\"root\"></div>\n <script type=\"module\" src=\"/studio/assets/${entryScript}\"></script>\n </body>\n</html>\n`;\n}\n\nasync function ensureStudioIndex(studioDir: string): Promise<void> {\n const indexPath = join(studioDir, \"index.html\");\n try {\n await access(indexPath);\n return;\n } catch {\n // index.html is missing on some TanStack Start static builds.\n }\n\n const assetsDir = join(studioDir, \"assets\");\n const assetFiles = await readdir(assetsDir);\n const entryScript =\n assetFiles.find((file) => /^index-.*\\.js$/i.test(file)) ??\n assetFiles.find((file) => file.endsWith(\".js\"));\n\n if (!entryScript) {\n throw new Error(\n \"Studio runtime template is missing an entry JS bundle in studio/assets.\",\n );\n }\n\n const cssFiles = assetFiles.filter((file) => file.endsWith(\".css\")).sort();\n const html = createStudioShell(entryScript, cssFiles);\n await writeFile(indexPath, html, \"utf-8\");\n}\n\nexport async function readLocalAgentNames(cwd: string): Promise<string[]> {\n const agentsDir = join(cwd, \"agents\");\n try {\n const entries = await readdir(agentsDir, { withFileTypes: true });\n const names: string[] = [];\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const indexPath = join(agentsDir, entry.name, \"index.ts\");\n const exists = await stat(indexPath)\n .then(() => true)\n .catch(() => false);\n if (exists) names.push(entry.name);\n }\n return names.sort((a, b) => a.localeCompare(b));\n } catch {\n return [];\n }\n}\n\nasync function createAgentsSnapshot(\n cwd: string,\n mode: \"local\" | \"remote\",\n): Promise<RuntimeAgentsSnapshot> {\n const localAgentNames = await readLocalAgentNames(cwd);\n const state = await readProjectState(cwd);\n\n const byName = new Map<string, RuntimeAgentRecord>();\n const stateAgents = state?.agents ?? {};\n\n for (const name of localAgentNames) {\n const localPath = join(cwd, \"agents\", name, \"index.ts\");\n const saved = stateAgents[name];\n const hasRemoteVersion = !!saved?.lastRemoteHash && (saved?.currentVersion ?? 0) > 0;\n\n if (mode === \"remote\" && !hasRemoteVersion) {\n continue;\n }\n\n const resolvedWorkerUrl =\n saved?.workerUrl ??\n (state?.workerUrl ? `${state.workerUrl.replace(/\\/$/, \"\")}/a/${name}` : null);\n const versionNumber =\n typeof saved?.currentVersion === \"number\" && saved.currentVersion > 0\n ? saved.currentVersion\n : null;\n\n byName.set(name, {\n name,\n label: deriveLabelFromName(name),\n tags: [],\n environment:\n mode === \"remote\"\n ? \"remote\"\n : hasRemoteVersion\n ? \"both\"\n : \"local\",\n status: resolvedWorkerUrl ? \"online\" : \"offline\",\n hash: saved?.currentHash ?? null,\n version: versionNumber ? `v${versionNumber}` : null,\n versionNumber,\n lastRemoteHash: saved?.lastRemoteHash ?? null,\n lastLocalHash: saved?.lastLocalHash ?? null,\n workerUrl: resolvedWorkerUrl,\n localPath,\n updatedAt: saved?.lastPushedAt ?? state?.deployedAt ?? null,\n });\n }\n\n if (mode === \"remote\") {\n for (const [name, saved] of Object.entries(stateAgents)) {\n const hasRemoteVersion =\n !!saved.lastRemoteHash && (saved.currentVersion ?? 0) > 0;\n if (!hasRemoteVersion || byName.has(name)) continue;\n\n const localPath = saved.localPath ?? join(cwd, \"agents\", name, \"index.ts\");\n const workerUrl =\n saved.workerUrl ??\n (state?.workerUrl ? `${state.workerUrl.replace(/\\/$/, \"\")}/a/${name}` : null);\n const versionNumber = saved.currentVersion > 0 ? saved.currentVersion : null;\n\n byName.set(name, {\n name,\n label: deriveLabelFromName(name),\n tags: [],\n environment: \"remote\",\n status: workerUrl ? \"online\" : \"offline\",\n hash: saved.currentHash ?? null,\n version: versionNumber ? `v${versionNumber}` : null,\n versionNumber,\n lastRemoteHash: saved.lastRemoteHash ?? null,\n lastLocalHash: saved.lastLocalHash ?? null,\n workerUrl,\n localPath,\n updatedAt: saved.lastPushedAt ?? state?.deployedAt ?? null,\n });\n }\n }\n\n return {\n generatedAt: new Date().toISOString(),\n projectPath: cwd,\n workerUrl: state?.workerUrl ?? null,\n mode,\n agents: Array.from(byName.values()).sort((a, b) => a.name.localeCompare(b.name)),\n };\n}\n\nexport async function writeRuntimeAgentsSnapshot(params: {\n cwd: string;\n runtimeDir: string;\n mode: \"local\" | \"remote\";\n}): Promise<void> {\n const snapshot = await createAgentsSnapshot(params.cwd, params.mode);\n await writeFile(\n join(params.runtimeDir, \"agents.snapshot.json\"),\n `${JSON.stringify(snapshot, null, 2)}\\n`,\n \"utf-8\",\n );\n}\n\nexport async function materializeRuntime(\n cwd: string,\n options: MaterializeRuntimeOptions = {},\n): Promise<RuntimePaths> {\n const mode = options.mode ?? \"remote\";\n const runtimeDir = join(cwd, RUNTIME_ROOT, RUNTIME_DIR);\n const studioDir = join(runtimeDir, STUDIO_DIR);\n const workerEntrypointPath = join(runtimeDir, WORKER_ENTRY_FILE);\n const wranglerConfigPath = join(runtimeDir, WRANGLER_CONFIG_FILE);\n\n const template = await resolveRuntimeTemplate();\n await rm(runtimeDir, { recursive: true, force: true });\n await mkdir(runtimeDir, { recursive: true });\n\n await cp(template.studioTemplateDir, studioDir, { recursive: true });\n await cp(template.workerEntryPath, workerEntrypointPath);\n await ensureStudioIndex(studioDir);\n\n // Bundle worker-entry.js to bake in dependencies (hono, jose, etc.)\n // We mark generated/dynamic files as external so they are resolved at runtime in the same dir.\n await build({\n entryPoints: [workerEntrypointPath],\n bundle: true,\n outfile: workerEntrypointPath,\n allowOverwrite: true,\n platform: \"browser\",\n format: \"esm\",\n target: \"es2022\",\n external: [\n \"cloudflare:workers\",\n \"./agents.snapshot.json\",\n \"./identity.config.json\",\n \"./identity.map.mjs\",\n ],\n logLevel: \"error\",\n });\n\n await writeRuntimeAgentsSnapshot({ cwd, runtimeDir, mode });\n const identity = await materializeRuntimeIdentity({ cwd, runtimeDir });\n\n const projectSlug = await resolveProjectSlug(cwd);\n const workerName = buildWorkerName(projectSlug, cwd);\n const requiredSecrets = new Set<string>([\n \"KALP_SECRET_KEY\",\n \"KALP_STUDIO_PASSWORD\",\n \"KALP_STUDIO_ADMIN_USER\",\n \"KALP_SERVICE_KEY\",\n ]);\n\n try {\n const provider = await resolveProviderFromConfig(cwd);\n requiredSecrets.add(getRequiredSecretForProvider(provider));\n } catch {\n // Ignore provider resolution errors here; deploy preflight handles strict checks.\n }\n\n const identityRequirements = resolveIdentityAuthRequirements(identity.identityConfig);\n for (const requirement of identityRequirements) {\n requiredSecrets.add(requirement.envKey);\n }\n\n const wranglerConfig = createRuntimeConfig(\n workerName,\n mode,\n [...requiredSecrets].sort((a, b) => a.localeCompare(b)),\n );\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","import { build } from \"esbuild\";\nimport { writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport {\n loadProjectConfig,\n resolveRuntimeIdentityConfig,\n type RuntimeIdentityConfig,\n} from \"@/utils/project-config\";\n\nexport interface MaterializeRuntimeIdentityResult {\n identityConfig: RuntimeIdentityConfig;\n identityConfigPath: string;\n identityMapPath: string;\n}\n\nconst DEFAULT_IDENTITY_MAP_SOURCE = `export default function mapIdentity(payload) {\n const sub =\n payload && typeof payload === \"object\" && typeof payload.sub === \"string\"\n ? payload.sub\n : \"anonymous\";\n return { userId: sub, claims: {} };\n}\n`;\n\nfunction readIdentityMapCandidate(rawConfig: Record<string, unknown>): unknown {\n if (!rawConfig.identity || typeof rawConfig.identity !== \"object\") return null;\n return (rawConfig.identity as Record<string, unknown>).mapIdentity;\n}\n\nfunction assertEdgeSafeSource(mapIdentitySource: string): void {\n const blockedPatterns: Array<{ regex: RegExp; label: string }> = [\n { regex: /\\brequire\\s*\\(/, label: \"require(...)\" },\n { regex: /\\bnode:/, label: \"node:* imports\" },\n { regex: /\\bprocess\\./, label: \"process.*\" },\n { regex: /\\bBuffer\\b/, label: \"Buffer\" },\n { regex: /\\bimport\\s*\\(/, label: \"dynamic import(...)\" },\n ];\n\n const hit = blockedPatterns.find((item) => item.regex.test(mapIdentitySource));\n if (!hit) return;\n\n throw new Error(\n `mapIdentity uses \"${hit.label}\", which is not supported in edge runtime.`,\n );\n}\n\nasync function writeDefaultIdentityMap(identityMapPath: string): Promise<void> {\n await writeFile(identityMapPath, DEFAULT_IDENTITY_MAP_SOURCE, \"utf-8\");\n}\n\nasync function bundleIdentityMap(params: {\n cwd: string;\n mapIdentitySource: string;\n identityMapPath: string;\n}): Promise<void> {\n const { cwd, mapIdentitySource, identityMapPath } = params;\n assertEdgeSafeSource(mapIdentitySource);\n\n const entrySource = `\nconst mapIdentity = (${mapIdentitySource});\nif (typeof mapIdentity !== \"function\") {\n throw new Error(\"identity.mapIdentity must be a function.\");\n}\nexport default mapIdentity;\n`;\n\n try {\n await build({\n absWorkingDir: cwd,\n bundle: true,\n format: \"esm\",\n platform: \"browser\",\n target: [\"es2022\"],\n write: true,\n outfile: identityMapPath,\n logLevel: \"silent\",\n stdin: {\n contents: entrySource,\n resolveDir: cwd,\n sourcefile: \"kalp-identity-map-entry.mjs\",\n loader: \"js\",\n },\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(\n [\n \"Could not bundle identity.mapIdentity for runtime.\",\n \"Please verify:\",\n \" • kalp.config.ts exists and exports default defineConfig(...)\",\n \" • mapIdentity is declared inline and does not capture external variables\",\n \" • mapIdentity does not use Node-specific APIs\",\n \" • kalp.config.ts has no broken imports\",\n `Technical details: ${message}`,\n ].join(\"\\n\"),\n );\n }\n}\n\nexport async function materializeRuntimeIdentity(params: {\n cwd: string;\n runtimeDir: string;\n}): Promise<MaterializeRuntimeIdentityResult> {\n const { cwd, runtimeDir } = params;\n const identityConfigPath = join(runtimeDir, \"identity.config.json\");\n const identityMapPath = join(runtimeDir, \"identity.map.mjs\");\n\n let rawConfig: Record<string, unknown> = {};\n try {\n const loaded = await loadProjectConfig(cwd);\n rawConfig = loaded.raw;\n } catch {\n rawConfig = {};\n }\n\n const identityConfig = resolveRuntimeIdentityConfig(rawConfig);\n await writeFile(\n identityConfigPath,\n `${JSON.stringify(identityConfig, null, 2)}\\n`,\n \"utf-8\",\n );\n\n const mapIdentity = readIdentityMapCandidate(rawConfig);\n if (typeof mapIdentity === \"function\") {\n const mapIdentitySource = mapIdentity.toString();\n if (!mapIdentitySource || /\\[native code\\]/.test(mapIdentitySource)) {\n throw new Error(\n \"Could not serialize identity.mapIdentity. Define it inline in kalp.config.ts as a regular function.\",\n );\n }\n await bundleIdentityMap({\n cwd,\n mapIdentitySource,\n identityMapPath,\n });\n } else {\n await writeDefaultIdentityMap(identityMapPath);\n }\n\n return { identityConfig, identityConfigPath, identityMapPath };\n}\n"],"mappings":"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","names":["build","mkdir","readFile","writeFile","join","writeFile","join","writeFile","join","join","readFile","writeFile","mkdir","build"]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/utils/ai.ts
|
|
4
|
+
import { access, readFile } from "fs/promises";
|
|
5
|
+
import { constants } from "fs";
|
|
6
|
+
import { join } from "path";
|
|
7
|
+
import { createJiti } from "jiti";
|
|
8
|
+
var PROVIDER_SECRET_MAP = {
|
|
9
|
+
openai: "OPENAI_API_KEY",
|
|
10
|
+
anthropic: "ANTHROPIC_API_KEY",
|
|
11
|
+
openrouter: "OPENROUTER_API_KEY",
|
|
12
|
+
cloudflare: "CLOUDFLARE_API_KEY",
|
|
13
|
+
vercel: "VERCEL_API_KEY",
|
|
14
|
+
custom: "CUSTOM_AI_API_KEY"
|
|
15
|
+
};
|
|
16
|
+
function parseEnv(content) {
|
|
17
|
+
const env = {};
|
|
18
|
+
for (const raw of content.split(/\r?\n/g)) {
|
|
19
|
+
const line = raw.trim();
|
|
20
|
+
if (!line || line.startsWith("#")) continue;
|
|
21
|
+
const idx = line.indexOf("=");
|
|
22
|
+
if (idx <= 0) continue;
|
|
23
|
+
env[line.slice(0, idx).trim()] = line.slice(idx + 1);
|
|
24
|
+
}
|
|
25
|
+
return env;
|
|
26
|
+
}
|
|
27
|
+
async function resolveProviderFromConfig(cwd) {
|
|
28
|
+
const configPath = join(cwd, "kalp.config.ts");
|
|
29
|
+
await access(configPath, constants.F_OK);
|
|
30
|
+
const jiti = createJiti(cwd, { interopDefault: true });
|
|
31
|
+
const config = await jiti.import(configPath);
|
|
32
|
+
const provider = config?.default?.ai?.provider ?? config?.ai?.provider ?? "openai";
|
|
33
|
+
return provider;
|
|
34
|
+
}
|
|
35
|
+
async function readDotEnv(cwd) {
|
|
36
|
+
const envPath = join(cwd, ".env");
|
|
37
|
+
const content = await readFile(envPath, "utf-8").catch(() => "");
|
|
38
|
+
return parseEnv(content);
|
|
39
|
+
}
|
|
40
|
+
function getRequiredSecretForProvider(provider) {
|
|
41
|
+
return PROVIDER_SECRET_MAP[provider];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export {
|
|
45
|
+
resolveProviderFromConfig,
|
|
46
|
+
readDotEnv,
|
|
47
|
+
getRequiredSecretForProvider
|
|
48
|
+
};
|
|
49
|
+
//# sourceMappingURL=chunk-LEKRFM4Q.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/ai.ts"],"sourcesContent":["import { access, readFile } from \"node:fs/promises\";\nimport { constants } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { createJiti } from \"jiti\";\n\nexport type AIProvider =\n | \"openai\"\n | \"anthropic\"\n | \"openrouter\"\n | \"cloudflare\"\n | \"vercel\"\n | \"custom\";\n\nconst PROVIDER_SECRET_MAP: Record<AIProvider, string> = {\n openai: \"OPENAI_API_KEY\",\n anthropic: \"ANTHROPIC_API_KEY\",\n openrouter: \"OPENROUTER_API_KEY\",\n cloudflare: \"CLOUDFLARE_API_KEY\",\n vercel: \"VERCEL_API_KEY\",\n custom: \"CUSTOM_AI_API_KEY\",\n};\n\nfunction parseEnv(content: string): Record<string, string> {\n const env: Record<string, string> = {};\n for (const raw of content.split(/\\r?\\n/g)) {\n const line = raw.trim();\n if (!line || line.startsWith(\"#\")) continue;\n const idx = line.indexOf(\"=\");\n if (idx <= 0) continue;\n env[line.slice(0, idx).trim()] = line.slice(idx + 1);\n }\n return env;\n}\n\nexport async function resolveProviderFromConfig(cwd: string): Promise<AIProvider> {\n const configPath = join(cwd, \"kalp.config.ts\");\n await access(configPath, constants.F_OK);\n const jiti = createJiti(cwd, { interopDefault: true });\n const config = (await jiti.import(configPath)) as\n | { default?: { ai?: { provider?: AIProvider } }; ai?: { provider?: AIProvider } }\n | undefined;\n const provider = config?.default?.ai?.provider ?? config?.ai?.provider ?? \"openai\";\n return provider;\n}\n\nexport async function readDotEnv(cwd: string): Promise<Record<string, string>> {\n const envPath = join(cwd, \".env\");\n const content = await readFile(envPath, \"utf-8\").catch(() => \"\");\n return parseEnv(content);\n}\n\nexport function getRequiredSecretForProvider(provider: AIProvider): string {\n return PROVIDER_SECRET_MAP[provider];\n}\n"],"mappings":";;;AAAA,SAAS,QAAQ,gBAAgB;AACjC,SAAS,iBAAiB;AAC1B,SAAS,YAAY;AACrB,SAAS,kBAAkB;AAU3B,IAAM,sBAAkD;AAAA,EACtD,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,QAAQ;AACV;AAEA,SAAS,SAAS,SAAyC;AACzD,QAAM,MAA8B,CAAC;AACrC,aAAW,OAAO,QAAQ,MAAM,QAAQ,GAAG;AACzC,UAAM,OAAO,IAAI,KAAK;AACtB,QAAI,CAAC,QAAQ,KAAK,WAAW,GAAG,EAAG;AACnC,UAAM,MAAM,KAAK,QAAQ,GAAG;AAC5B,QAAI,OAAO,EAAG;AACd,QAAI,KAAK,MAAM,GAAG,GAAG,EAAE,KAAK,CAAC,IAAI,KAAK,MAAM,MAAM,CAAC;AAAA,EACrD;AACA,SAAO;AACT;AAEA,eAAsB,0BAA0B,KAAkC;AAChF,QAAM,aAAa,KAAK,KAAK,gBAAgB;AAC7C,QAAM,OAAO,YAAY,UAAU,IAAI;AACvC,QAAM,OAAO,WAAW,KAAK,EAAE,gBAAgB,KAAK,CAAC;AACrD,QAAM,SAAU,MAAM,KAAK,OAAO,UAAU;AAG5C,QAAM,WAAW,QAAQ,SAAS,IAAI,YAAY,QAAQ,IAAI,YAAY;AAC1E,SAAO;AACT;AAEA,eAAsB,WAAW,KAA8C;AAC7E,QAAM,UAAU,KAAK,KAAK,MAAM;AAChC,QAAM,UAAU,MAAM,SAAS,SAAS,OAAO,EAAE,MAAM,MAAM,EAAE;AAC/D,SAAO,SAAS,OAAO;AACzB;AAEO,SAAS,6BAA6B,UAA8B;AACzE,SAAO,oBAAoB,QAAQ;AACrC;","names":[]}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// ../sdk/dist/index.js
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
function cron(expression) {
|
|
6
|
+
return expression;
|
|
7
|
+
}
|
|
8
|
+
var everyMinute = cron("* * * * *");
|
|
9
|
+
var everyHour = cron("0 * * * *");
|
|
10
|
+
var everySixHours = cron("0 */6 * * *");
|
|
11
|
+
var everyDayAtMidnight = cron("0 0 * * *");
|
|
12
|
+
var everyDayAtNoon = cron("0 12 * * *");
|
|
13
|
+
var everyWeekdayAt9Am = cron("0 9 * * 1-5");
|
|
14
|
+
var everySundayAt3Am = cron("0 3 * * 0");
|
|
15
|
+
var ENV_MARKER_PREFIX = "{{env:";
|
|
16
|
+
var ENV_MARKER_SUFFIX = "}}";
|
|
17
|
+
function extractEnvName(val) {
|
|
18
|
+
if (typeof val === "string" && val.startsWith(ENV_MARKER_PREFIX) && val.endsWith(ENV_MARKER_SUFFIX)) {
|
|
19
|
+
return val.slice(ENV_MARKER_PREFIX.length, -ENV_MARKER_SUFFIX.length);
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
function normalizeEnvValue(val) {
|
|
24
|
+
const envName = extractEnvName(val);
|
|
25
|
+
if (envName) {
|
|
26
|
+
return {
|
|
27
|
+
envName,
|
|
28
|
+
value: typeof process !== "undefined" ? process.env[envName] : void 0
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
return { value: val };
|
|
32
|
+
}
|
|
33
|
+
function normalizeMcpServer(input) {
|
|
34
|
+
if (typeof input === "string") {
|
|
35
|
+
return {
|
|
36
|
+
url: input,
|
|
37
|
+
transport: "sse"
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
const transport = input.transport || "sse";
|
|
41
|
+
const url = input.url;
|
|
42
|
+
if (!input.auth) {
|
|
43
|
+
return { url, transport };
|
|
44
|
+
}
|
|
45
|
+
let auth;
|
|
46
|
+
if (typeof input.auth === "string") {
|
|
47
|
+
const { value, envName } = normalizeEnvValue(input.auth);
|
|
48
|
+
auth = {
|
|
49
|
+
type: "bearer",
|
|
50
|
+
token: value,
|
|
51
|
+
tokenEnv: envName
|
|
52
|
+
};
|
|
53
|
+
} else if (input.auth.type === "bearer") {
|
|
54
|
+
const { value, envName } = normalizeEnvValue(input.auth.token);
|
|
55
|
+
auth = {
|
|
56
|
+
type: "bearer",
|
|
57
|
+
token: value,
|
|
58
|
+
tokenEnv: envName
|
|
59
|
+
};
|
|
60
|
+
} else if (input.auth.type === "headers") {
|
|
61
|
+
const headers = {};
|
|
62
|
+
const headersEnv = {};
|
|
63
|
+
for (const [key, val] of Object.entries(input.auth.headers)) {
|
|
64
|
+
const { value, envName } = normalizeEnvValue(val || "");
|
|
65
|
+
if (value !== void 0) headers[key] = value;
|
|
66
|
+
if (envName) headersEnv[key] = envName;
|
|
67
|
+
}
|
|
68
|
+
auth = {
|
|
69
|
+
type: "headers",
|
|
70
|
+
headers,
|
|
71
|
+
headersEnv
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
return { url, transport, auth };
|
|
75
|
+
}
|
|
76
|
+
function collectMcpSecretRequirements(config) {
|
|
77
|
+
if (!config.mcp) return [];
|
|
78
|
+
const secrets = /* @__PURE__ */ new Set();
|
|
79
|
+
for (const serverInput of Object.values(config.mcp)) {
|
|
80
|
+
const normalized = normalizeMcpServer(serverInput);
|
|
81
|
+
if (!normalized.auth) continue;
|
|
82
|
+
if (normalized.auth.type === "bearer") {
|
|
83
|
+
if (normalized.auth.tokenEnv) {
|
|
84
|
+
secrets.add(normalized.auth.tokenEnv);
|
|
85
|
+
}
|
|
86
|
+
} else if (normalized.auth.type === "headers") {
|
|
87
|
+
for (const envName of Object.values(normalized.auth.headersEnv)) {
|
|
88
|
+
secrets.add(envName);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return Array.from(secrets).sort();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export {
|
|
96
|
+
normalizeMcpServer,
|
|
97
|
+
collectMcpSecretRequirements
|
|
98
|
+
};
|
|
99
|
+
//# sourceMappingURL=chunk-QT2JFINP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../sdk/src/identity/brands.ts","../../sdk/src/utils/stack.ts","../../sdk/src/contracts/types.ts","../../sdk/src/schedule/cron.ts","../../sdk/src/schedule/timezones.ts","../../sdk/src/agent.ts","../../sdk/src/hooks/types.ts","../../sdk/src/registry.ts","../../sdk/src/listeners/types.ts","../../sdk/src/definitions/nodes.ts","../../sdk/src/definitions/routes.ts","../../sdk/src/cron-definition.ts","../../sdk/src/project/types.ts","../../sdk/src/project/config.ts","../../sdk/src/project/normalize.ts","../../sdk/src/errors.ts"],"sourcesContent":["/**\n * Branded types for Kalp identity system.\n *\n * These prevent accidental mixing of different ID types at compile time.\n * For example, you cannot pass a UserId where an AgentId is expected.\n *\n * @module\n */\n\n/** Unique identifier for users */\nexport type UserId = string & { readonly __brand: \"UserId\" };\n\n/** Unique identifier for agents */\nexport type AgentId = string & { readonly __brand: \"AgentId\" };\n\n/** Unique identifier for threads (actor instances) */\nexport type ThreadId = string & { readonly __brand: \"ThreadId\" };\n\n/** Unique identifier for executions (single handler invocation) */\nexport type ExecutionId = string & { readonly __brand: \"ExecutionId\" };\n\n/** Unique identifier for traces (single external stimulus) */\nexport type TraceId = string & { readonly __brand: \"TraceId\" };\n\n/**\n * Creates a UserId from a string.\n * Runtime validation should be performed in production code.\n *\n * @param id - The string identifier.\n * @returns A branded UserId.\n */\nexport function asUserId(id: string): UserId {\n return id as UserId;\n}\n\n/**\n * Creates an AgentId from a string.\n *\n * @param id - The string identifier.\n * @returns A branded AgentId.\n */\nexport function asAgentId(id: string): AgentId {\n return id as AgentId;\n}\n\n/**\n * Creates a ThreadId from a string.\n *\n * @param id - The string identifier.\n * @returns A branded ThreadId.\n */\nexport function asThreadId(id: string): ThreadId {\n return id as ThreadId;\n}\n\n/**\n * Creates an ExecutionId from a string.\n *\n * @param id - The string identifier.\n * @returns A branded ExecutionId.\n */\nexport function asExecutionId(id: string): ExecutionId {\n return id as ExecutionId;\n}\n\n/**\n * Creates a TraceId from a string.\n *\n * @param id - The string identifier.\n * @returns A branded TraceId.\n */\nexport function asTraceId(id: string): TraceId {\n return id as TraceId;\n}\n","import { normalize, sep } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nfunction normalizeCapturedPath(rawPath: string): string {\n let path = rawPath;\n\n if (path.startsWith(\"file:///\")) {\n path = fileURLToPath(path);\n }\n\n if (process.platform === \"win32\") {\n const driveStyle = path.match(/^\\/([a-zA-Z])\\/(.*)$/);\n if (driveStyle) {\n path = `${driveStyle[1]}:/${driveStyle[2]}`;\n } else if (path.startsWith(\"/Users/\")) {\n path = `C:${path}`;\n }\n }\n\n return normalize(path).split(sep).join(\"/\");\n}\n\nexport function extractFilePath(stack?: string): string | undefined {\n if (!stack) return undefined;\n\n const lines = stack.split(/\\r?\\n/);\n\n for (const line of lines) {\n const normalizedLine = line.replace(/\\\\/g, \"/\");\n\n if (\n normalizedLine.includes(\"captureFilePath\") ||\n normalizedLine.includes(\"extractFilePath\") ||\n normalizedLine.includes(\"registerNode\") ||\n normalizedLine.includes(\"defineTool\") ||\n normalizedLine.includes(\"defineRoute\") ||\n normalizedLine.includes(\"defineListener\") ||\n normalizedLine.includes(\"defineHook\") ||\n normalizedLine.includes(\"defineCron\") ||\n normalizedLine.includes(\"defineContract\") ||\n normalizedLine.includes(\"@kalphq/sdk/\") ||\n normalizedLine.includes(\"/packages/sdk/\") ||\n normalizedLine.includes(\"Error\")\n ) {\n continue;\n }\n\n const patterns = [\n /\\((file:\\/\\/\\/[^\\s)]+|[A-Za-z]:\\\\[^:]+|\\/[^:]+):\\d+:\\d+\\)/,\n /at\\s+(file:\\/\\/\\/[^\\s)]+|[A-Za-z]:\\\\[^:]+|\\/[^:]+):\\d+:\\d+/,\n /(file:\\/\\/\\/[^\\s)]+|[A-Za-z]:\\\\[^:]+|\\/[^:]+):\\d+:\\d+/,\n ];\n\n for (const pattern of patterns) {\n const match = line.match(pattern);\n if (!match?.[1]) continue;\n\n return normalizeCapturedPath(match[1]);\n }\n }\n\n return undefined;\n}\n\nexport function captureFilePath(): string | undefined {\n const oldLimit = Error.stackTraceLimit;\n Error.stackTraceLimit = 20;\n const err = new Error();\n const stack = err.stack;\n Error.stackTraceLimit = oldLimit;\n\n return extractFilePath(stack);\n}\r\n","import type { z } from \"zod\";\nimport type { TypedKalpContext } from \"@/context/types\";\nimport { captureFilePath } from \"@/utils\";\n\n/**\n * Contract types for type-safe RPC between agents.\n *\n * @module\n */\n\nexport interface AgentContract<\n TInput extends z.ZodTypeAny = z.ZodTypeAny,\n TOutput extends z.ZodTypeAny = z.ZodTypeAny,\n TState extends Record<string, unknown> = Record<string, unknown>,\n> {\n readonly kind: \"contract\";\n readonly name: string;\n readonly inputSchema: TInput;\n readonly outputSchema: TOutput;\n readonly handler: (\n input: z.infer<TInput>,\n context: TypedKalpContext<TState>,\n ) => Promise<z.infer<TOutput>> | z.infer<TOutput>;\n readonly __filePath?: string;\n readonly __internalId?: symbol;\n readonly __runtimeId?: string;\n}\n\nexport function defineContract<\n TState extends Record<string, unknown> = Record<string, unknown>,\n const TInput extends z.ZodTypeAny = z.ZodTypeAny,\n const TOutput extends z.ZodTypeAny = z.ZodTypeAny,\n>(config: {\n name: string;\n inputSchema: TInput;\n outputSchema: TOutput;\n handler: (\n input: z.infer<TInput>,\n context: TypedKalpContext<TState>,\n ) => Promise<z.infer<TOutput>> | z.infer<TOutput>;\n}): AgentContract<TInput, TOutput, TState> {\n return {\n kind: \"contract\",\n name: config.name,\n inputSchema: config.inputSchema,\n outputSchema: config.outputSchema,\n handler: config.handler,\n __filePath: captureFilePath(),\n __internalId: Symbol(`contract:${config.name}`),\n __runtimeId: `contract:${config.name}`,\n };\n}\n","import type { IanaTimezone } from \"@/schedule/timezones\";\n\nexport type CronExpression =\n `${string} ${string} ${string} ${string} ${string}`;\n\nexport type CronHour =\n | 0\n | 1\n | 2\n | 3\n | 4\n | 5\n | 6\n | 7\n | 8\n | 9\n | 10\n | 11\n | 12\n | 13\n | 14\n | 15\n | 16\n | 17\n | 18\n | 19\n | 20\n | 21\n | 22\n | 23;\n\nexport type CronMinute =\n | 0\n | 1\n | 2\n | 3\n | 4\n | 5\n | 6\n | 7\n | 8\n | 9\n | 10\n | 11\n | 12\n | 13\n | 14\n | 15\n | 16\n | 17\n | 18\n | 19\n | 20\n | 21\n | 22\n | 23\n | 24\n | 25\n | 26\n | 27\n | 28\n | 29\n | 30\n | 31\n | 32\n | 33\n | 34\n | 35\n | 36\n | 37\n | 38\n | 39\n | 40\n | 41\n | 42\n | 43\n | 44\n | 45\n | 46\n | 47\n | 48\n | 49\n | 50\n | 51\n | 52\n | 53\n | 54\n | 55\n | 56\n | 57\n | 58\n | 59;\n\nexport interface CronSchedule {\n expression: CronExpression;\n timezone?: IanaTimezone;\n}\n\nexport function cron<const TExpression extends CronExpression>(\n expression: TExpression,\n): TExpression {\n return expression;\n}\n\nexport function everyDayAt(\n hour: CronHour,\n minute: CronMinute = 0,\n): CronExpression {\n return `${minute} ${hour} * * *` as CronExpression;\n}\n\nexport function everyWeekdayAt(\n hour: CronHour,\n minute: CronMinute = 0,\n): CronExpression {\n return `${minute} ${hour} * * 1-5` as CronExpression;\n}\n\nexport function everyXMinutes(step: 1 | 5 | 10 | 15 | 20 | 30): CronExpression {\n return `*/${step} * * * *` as CronExpression;\n}\n\nexport const everyMinute = cron(\"* * * * *\");\nexport const everyHour = cron(\"0 * * * *\");\nexport const everySixHours = cron(\"0 */6 * * *\");\nexport const everyDayAtMidnight = cron(\"0 0 * * *\");\nexport const everyDayAtNoon = cron(\"0 12 * * *\");\nexport const everyDayAt12Pm = everyDayAtNoon;\nexport const everyWeekdayAt9Am = cron(\"0 9 * * 1-5\");\nexport const everySundayAt3Am = cron(\"0 3 * * 0\");\n","/**\n * IANA timezone identifiers supported by the runtime.\n */\nexport const IANA_TIMEZONES = [\n \"Africa/Abidjan\",\n \"Africa/Accra\",\n \"Africa/Addis_Ababa\",\n \"Africa/Algiers\",\n \"Africa/Asmera\",\n \"Africa/Bamako\",\n \"Africa/Bangui\",\n \"Africa/Banjul\",\n \"Africa/Bissau\",\n \"Africa/Blantyre\",\n \"Africa/Brazzaville\",\n \"Africa/Bujumbura\",\n \"Africa/Cairo\",\n \"Africa/Casablanca\",\n \"Africa/Ceuta\",\n \"Africa/Conakry\",\n \"Africa/Dakar\",\n \"Africa/Dar_es_Salaam\",\n \"Africa/Djibouti\",\n \"Africa/Douala\",\n \"Africa/El_Aaiun\",\n \"Africa/Freetown\",\n \"Africa/Gaborone\",\n \"Africa/Harare\",\n \"Africa/Johannesburg\",\n \"Africa/Juba\",\n \"Africa/Kampala\",\n \"Africa/Khartoum\",\n \"Africa/Kigali\",\n \"Africa/Kinshasa\",\n \"Africa/Lagos\",\n \"Africa/Libreville\",\n \"Africa/Lome\",\n \"Africa/Luanda\",\n \"Africa/Lubumbashi\",\n \"Africa/Lusaka\",\n \"Africa/Malabo\",\n \"Africa/Maputo\",\n \"Africa/Maseru\",\n \"Africa/Mbabane\",\n \"Africa/Mogadishu\",\n \"Africa/Monrovia\",\n \"Africa/Nairobi\",\n \"Africa/Ndjamena\",\n \"Africa/Niamey\",\n \"Africa/Nouakchott\",\n \"Africa/Ouagadougou\",\n \"Africa/Porto-Novo\",\n \"Africa/Sao_Tome\",\n \"Africa/Tripoli\",\n \"Africa/Tunis\",\n \"Africa/Windhoek\",\n \"America/Adak\",\n \"America/Anchorage\",\n \"America/Anguilla\",\n \"America/Antigua\",\n \"America/Araguaina\",\n \"America/Argentina/La_Rioja\",\n \"America/Argentina/Rio_Gallegos\",\n \"America/Argentina/Salta\",\n \"America/Argentina/San_Juan\",\n \"America/Argentina/San_Luis\",\n \"America/Argentina/Tucuman\",\n \"America/Argentina/Ushuaia\",\n \"America/Aruba\",\n \"America/Asuncion\",\n \"America/Bahia\",\n \"America/Bahia_Banderas\",\n \"America/Barbados\",\n \"America/Belem\",\n \"America/Belize\",\n \"America/Blanc-Sablon\",\n \"America/Boa_Vista\",\n \"America/Bogota\",\n \"America/Boise\",\n \"America/Buenos_Aires\",\n \"America/Cambridge_Bay\",\n \"America/Campo_Grande\",\n \"America/Cancun\",\n \"America/Caracas\",\n \"America/Catamarca\",\n \"America/Cayenne\",\n \"America/Cayman\",\n \"America/Chicago\",\n \"America/Chihuahua\",\n \"America/Ciudad_Juarez\",\n \"America/Coral_Harbour\",\n \"America/Cordoba\",\n \"America/Costa_Rica\",\n \"America/Coyhaique\",\n \"America/Creston\",\n \"America/Cuiaba\",\n \"America/Curacao\",\n \"America/Danmarkshavn\",\n \"America/Dawson\",\n \"America/Dawson_Creek\",\n \"America/Denver\",\n \"America/Detroit\",\n \"America/Dominica\",\n \"America/Edmonton\",\n \"America/Eirunepe\",\n \"America/El_Salvador\",\n \"America/Fort_Nelson\",\n \"America/Fortaleza\",\n \"America/Glace_Bay\",\n \"America/Godthab\",\n \"America/Goose_Bay\",\n \"America/Grand_Turk\",\n \"America/Grenada\",\n \"America/Guadeloupe\",\n \"America/Guatemala\",\n \"America/Guayaquil\",\n \"America/Guyana\",\n \"America/Halifax\",\n \"America/Havana\",\n \"America/Hermosillo\",\n \"America/Indiana/Knox\",\n \"America/Indiana/Marengo\",\n \"America/Indiana/Petersburg\",\n \"America/Indiana/Tell_City\",\n \"America/Indiana/Vevay\",\n \"America/Indiana/Vincennes\",\n \"America/Indiana/Winamac\",\n \"America/Indianapolis\",\n \"America/Inuvik\",\n \"America/Iqaluit\",\n \"America/Jamaica\",\n \"America/Jujuy\",\n \"America/Juneau\",\n \"America/Kentucky/Monticello\",\n \"America/Kralendijk\",\n \"America/La_Paz\",\n \"America/Lima\",\n \"America/Los_Angeles\",\n \"America/Louisville\",\n \"America/Lower_Princes\",\n \"America/Maceio\",\n \"America/Managua\",\n \"America/Manaus\",\n \"America/Marigot\",\n \"America/Martinique\",\n \"America/Matamoros\",\n \"America/Mazatlan\",\n \"America/Mendoza\",\n \"America/Menominee\",\n \"America/Merida\",\n \"America/Metlakatla\",\n \"America/Mexico_City\",\n \"America/Miquelon\",\n \"America/Moncton\",\n \"America/Monterrey\",\n \"America/Montevideo\",\n \"America/Montserrat\",\n \"America/Nassau\",\n \"America/New_York\",\n \"America/Nome\",\n \"America/Noronha\",\n \"America/North_Dakota/Beulah\",\n \"America/North_Dakota/Center\",\n \"America/North_Dakota/New_Salem\",\n \"America/Ojinaga\",\n \"America/Panama\",\n \"America/Paramaribo\",\n \"America/Phoenix\",\n \"America/Port-au-Prince\",\n \"America/Port_of_Spain\",\n \"America/Porto_Velho\",\n \"America/Puerto_Rico\",\n \"America/Punta_Arenas\",\n \"America/Rankin_Inlet\",\n \"America/Recife\",\n \"America/Regina\",\n \"America/Resolute\",\n \"America/Rio_Branco\",\n \"America/Santarem\",\n \"America/Santiago\",\n \"America/Santo_Domingo\",\n \"America/Sao_Paulo\",\n \"America/Scoresbysund\",\n \"America/Sitka\",\n \"America/St_Barthelemy\",\n \"America/St_Johns\",\n \"America/St_Kitts\",\n \"America/St_Lucia\",\n \"America/St_Thomas\",\n \"America/St_Vincent\",\n \"America/Swift_Current\",\n \"America/Tegucigalpa\",\n \"America/Thule\",\n \"America/Tijuana\",\n \"America/Toronto\",\n \"America/Tortola\",\n \"America/Vancouver\",\n \"America/Whitehorse\",\n \"America/Winnipeg\",\n \"America/Yakutat\",\n \"Antarctica/Casey\",\n \"Antarctica/Davis\",\n \"Antarctica/DumontDUrville\",\n \"Antarctica/Macquarie\",\n \"Antarctica/Mawson\",\n \"Antarctica/McMurdo\",\n \"Antarctica/Palmer\",\n \"Antarctica/Rothera\",\n \"Antarctica/Syowa\",\n \"Antarctica/Troll\",\n \"Antarctica/Vostok\",\n \"Arctic/Longyearbyen\",\n \"Asia/Aden\",\n \"Asia/Almaty\",\n \"Asia/Amman\",\n \"Asia/Anadyr\",\n \"Asia/Aqtau\",\n \"Asia/Aqtobe\",\n \"Asia/Ashgabat\",\n \"Asia/Atyrau\",\n \"Asia/Baghdad\",\n \"Asia/Bahrain\",\n \"Asia/Baku\",\n \"Asia/Bangkok\",\n \"Asia/Barnaul\",\n \"Asia/Beirut\",\n \"Asia/Bishkek\",\n \"Asia/Brunei\",\n \"Asia/Calcutta\",\n \"Asia/Chita\",\n \"Asia/Colombo\",\n \"Asia/Damascus\",\n \"Asia/Dhaka\",\n \"Asia/Dili\",\n \"Asia/Dubai\",\n \"Asia/Dushanbe\",\n \"Asia/Famagusta\",\n \"Asia/Gaza\",\n \"Asia/Hebron\",\n \"Asia/Hong_Kong\",\n \"Asia/Hovd\",\n \"Asia/Irkutsk\",\n \"Asia/Jakarta\",\n \"Asia/Jayapura\",\n \"Asia/Jerusalem\",\n \"Asia/Kabul\",\n \"Asia/Kamchatka\",\n \"Asia/Karachi\",\n \"Asia/Katmandu\",\n \"Asia/Khandyga\",\n \"Asia/Krasnoyarsk\",\n \"Asia/Kuala_Lumpur\",\n \"Asia/Kuching\",\n \"Asia/Kuwait\",\n \"Asia/Macau\",\n \"Asia/Magadan\",\n \"Asia/Makassar\",\n \"Asia/Manila\",\n \"Asia/Muscat\",\n \"Asia/Nicosia\",\n \"Asia/Novokuznetsk\",\n \"Asia/Novosibirsk\",\n \"Asia/Omsk\",\n \"Asia/Oral\",\n \"Asia/Phnom_Penh\",\n \"Asia/Pontianak\",\n \"Asia/Pyongyang\",\n \"Asia/Qatar\",\n \"Asia/Qostanay\",\n \"Asia/Qyzylorda\",\n \"Asia/Rangoon\",\n \"Asia/Riyadh\",\n \"Asia/Saigon\",\n \"Asia/Sakhalin\",\n \"Asia/Samarkand\",\n \"Asia/Seoul\",\n \"Asia/Shanghai\",\n \"Asia/Singapore\",\n \"Asia/Srednekolymsk\",\n \"Asia/Taipei\",\n \"Asia/Tashkent\",\n \"Asia/Tbilisi\",\n \"Asia/Tehran\",\n \"Asia/Thimphu\",\n \"Asia/Tokyo\",\n \"Asia/Tomsk\",\n \"Asia/Ulaanbaatar\",\n \"Asia/Urumqi\",\n \"Asia/Ust-Nera\",\n \"Asia/Vientiane\",\n \"Asia/Vladivostok\",\n \"Asia/Yakutsk\",\n \"Asia/Yekaterinburg\",\n \"Asia/Yerevan\",\n \"Atlantic/Azores\",\n \"Atlantic/Bermuda\",\n \"Atlantic/Canary\",\n \"Atlantic/Cape_Verde\",\n \"Atlantic/Faeroe\",\n \"Atlantic/Madeira\",\n \"Atlantic/Reykjavik\",\n \"Atlantic/South_Georgia\",\n \"Atlantic/St_Helena\",\n \"Atlantic/Stanley\",\n \"Australia/Adelaide\",\n \"Australia/Brisbane\",\n \"Australia/Broken_Hill\",\n \"Australia/Darwin\",\n \"Australia/Eucla\",\n \"Australia/Hobart\",\n \"Australia/Lindeman\",\n \"Australia/Lord_Howe\",\n \"Australia/Melbourne\",\n \"Australia/Perth\",\n \"Australia/Sydney\",\n \"Europe/Amsterdam\",\n \"Europe/Andorra\",\n \"Europe/Astrakhan\",\n \"Europe/Athens\",\n \"Europe/Belgrade\",\n \"Europe/Berlin\",\n \"Europe/Bratislava\",\n \"Europe/Brussels\",\n \"Europe/Bucharest\",\n \"Europe/Budapest\",\n \"Europe/Busingen\",\n \"Europe/Chisinau\",\n \"Europe/Copenhagen\",\n \"Europe/Dublin\",\n \"Europe/Gibraltar\",\n \"Europe/Guernsey\",\n \"Europe/Helsinki\",\n \"Europe/Isle_of_Man\",\n \"Europe/Istanbul\",\n \"Europe/Jersey\",\n \"Europe/Kaliningrad\",\n \"Europe/Kiev\",\n \"Europe/Kirov\",\n \"Europe/Lisbon\",\n \"Europe/Ljubljana\",\n \"Europe/London\",\n \"Europe/Luxembourg\",\n \"Europe/Madrid\",\n \"Europe/Malta\",\n \"Europe/Mariehamn\",\n \"Europe/Minsk\",\n \"Europe/Monaco\",\n \"Europe/Moscow\",\n \"Europe/Oslo\",\n \"Europe/Paris\",\n \"Europe/Podgorica\",\n \"Europe/Prague\",\n \"Europe/Riga\",\n \"Europe/Rome\",\n \"Europe/Samara\",\n \"Europe/San_Marino\",\n \"Europe/Sarajevo\",\n \"Europe/Saratov\",\n \"Europe/Simferopol\",\n \"Europe/Skopje\",\n \"Europe/Sofia\",\n \"Europe/Stockholm\",\n \"Europe/Tallinn\",\n \"Europe/Tirane\",\n \"Europe/Ulyanovsk\",\n \"Europe/Vaduz\",\n \"Europe/Vatican\",\n \"Europe/Vienna\",\n \"Europe/Vilnius\",\n \"Europe/Volgograd\",\n \"Europe/Warsaw\",\n \"Europe/Zagreb\",\n \"Europe/Zurich\",\n \"Indian/Antananarivo\",\n \"Indian/Chagos\",\n \"Indian/Christmas\",\n \"Indian/Cocos\",\n \"Indian/Comoro\",\n \"Indian/Kerguelen\",\n \"Indian/Mahe\",\n \"Indian/Maldives\",\n \"Indian/Mauritius\",\n \"Indian/Mayotte\",\n \"Indian/Reunion\",\n \"Pacific/Apia\",\n \"Pacific/Auckland\",\n \"Pacific/Bougainville\",\n \"Pacific/Chatham\",\n \"Pacific/Easter\",\n \"Pacific/Efate\",\n \"Pacific/Enderbury\",\n \"Pacific/Fakaofo\",\n \"Pacific/Fiji\",\n \"Pacific/Funafuti\",\n \"Pacific/Galapagos\",\n \"Pacific/Gambier\",\n \"Pacific/Guadalcanal\",\n \"Pacific/Guam\",\n \"Pacific/Honolulu\",\n \"Pacific/Kiritimati\",\n \"Pacific/Kosrae\",\n \"Pacific/Kwajalein\",\n \"Pacific/Majuro\",\n \"Pacific/Marquesas\",\n \"Pacific/Midway\",\n \"Pacific/Nauru\",\n \"Pacific/Niue\",\n \"Pacific/Norfolk\",\n \"Pacific/Noumea\",\n \"Pacific/Pago_Pago\",\n \"Pacific/Palau\",\n \"Pacific/Pitcairn\",\n \"Pacific/Ponape\",\n \"Pacific/Port_Moresby\",\n \"Pacific/Rarotonga\",\n \"Pacific/Saipan\",\n \"Pacific/Tahiti\",\n \"Pacific/Tarawa\",\n \"Pacific/Tongatapu\",\n \"Pacific/Truk\",\n \"Pacific/Wake\",\n \"Pacific/Wallis\",\n \"UTC\",\n \"GMT\",\n] as const;\n\nexport type IanaTimezone = (typeof IANA_TIMEZONES)[number] | (string & {});","import type { z } from \"zod\";\nimport type { AgentContract } from \"@/contracts\";\nimport type { Route } from \"@/nodes\";\nimport type { CronDefinition } from \"@/cron-definition\";\nimport type { Hook, MessageHook } from \"@/hooks\";\nimport type { KalpContext } from \"@/context\";\n\nimport type { Simplify } from \"@/utils/types\";\n\ntype HasDuplicateMessageHook<\n THooks extends readonly Hook<any>[],\n SeenMessage extends boolean = false,\n> = THooks extends readonly [infer First, ...infer Rest]\n ? First extends MessageHook<any>\n ? SeenMessage extends true\n ? true\n : Rest extends readonly Hook<any>[]\n ? HasDuplicateMessageHook<Rest, true>\n : false\n : Rest extends readonly Hook<any>[]\n ? HasDuplicateMessageHook<Rest, SeenMessage>\n : false\n : false;\n\ntype EnsureSingleMessageHook<THooks extends readonly Hook<any>[]> =\n HasDuplicateMessageHook<THooks> extends true ? never : THooks;\n\nexport interface AgentConfig<\n TStateSchema extends z.ZodTypeAny = z.ZodTypeAny,\n THooks extends readonly Hook<z.infer<TStateSchema>>[] = readonly Hook<z.infer<TStateSchema>>[],\n> {\n name: string;\n label?: string;\n description?: string;\n tags?: readonly string[];\n skipAuth?: boolean;\n systemPrompt?:\n | string\n | ((context: KalpContext<z.infer<TStateSchema>>) => string | Promise<string>);\n state: TStateSchema;\n routes?: readonly Route<any, any, z.infer<TStateSchema>>[];\n contracts?: readonly AgentContract<any, any, z.infer<TStateSchema>>[];\n cron?: readonly CronDefinition<z.infer<TStateSchema>>[];\n hooks?: EnsureSingleMessageHook<THooks>;\n}\n\nexport type DefinedAgent<\n TStateSchema extends z.ZodTypeAny = z.ZodTypeAny,\n THooks extends readonly Hook<z.infer<TStateSchema>>[] = readonly Hook<z.infer<TStateSchema>>[],\n> = Simplify<AgentConfig<TStateSchema, THooks>>;\n\nexport function defineAgent<\n TStateSchema extends z.ZodTypeAny,\n THooks extends readonly Hook<z.infer<TStateSchema>>[] = readonly Hook<z.infer<TStateSchema>>[],\n>(config: AgentConfig<TStateSchema, THooks>): DefinedAgent<TStateSchema, THooks> {\n return config as DefinedAgent<TStateSchema, THooks>;\n}\n","import type { AgentMessage, AgentResponse, TypedKalpContext } from \"@/context/types\";\nimport { captureFilePath } from \"@/utils\";\n\nexport type HookType = \"init\" | \"tick\" | \"message\";\n\ninterface HookMeta {\n __filePath?: string;\n __internalId?: symbol;\n __runtimeId?: string;\n}\n\nexport interface InitHook<TState extends Record<string, unknown> = Record<string, unknown>>\n extends HookMeta {\n type: \"init\";\n handler: (ctx: TypedKalpContext<TState>) => Promise<void> | void;\n}\n\nexport interface TickHook<TState extends Record<string, unknown> = Record<string, unknown>>\n extends HookMeta {\n type: \"tick\";\n handler: (ctx: TypedKalpContext<TState>) => Promise<void> | void;\n}\n\nexport interface MessageHook<\n TState extends Record<string, unknown> = Record<string, unknown>,\n> extends HookMeta {\n type: \"message\";\n handler: (\n message: AgentMessage,\n ctx: TypedKalpContext<TState>,\n ) => Promise<AgentResponse | ReadableStream> | AgentResponse | ReadableStream;\n}\n\nexport type Hook<TState extends Record<string, unknown> = Record<string, unknown>> =\n | InitHook<TState>\n | TickHook<TState>\n | MessageHook<TState>;\n\nexport function defineHook<\n TState extends Record<string, unknown> = Record<string, unknown>,\n THook extends Hook<TState> = Hook<TState>,\n>(config: THook): THook {\n const runtimeLabel =\n config.type === \"message\"\n ? \"hook:message\"\n : `hook:${config.type}:${crypto.randomUUID()}`;\n\n return {\n ...config,\n __filePath: captureFilePath(),\n __internalId: Symbol(`hook:${config.type}`),\n __runtimeId: runtimeLabel,\n };\n}\n","/**\n * Global scoped registry for autodiscovery of tools and listeners.\n *\n * @module\n */\n\nimport { captureFilePath } from \"@/utils\";\n\nexport interface RegistryEntry {\n kind: \"tool\" | \"listener\";\n id: string;\n ref: unknown;\n}\n\nconst REGISTRY_SYMBOL = Symbol.for(\"@kalphq/sdk/registry\");\n\nfunction getRegistryMap(): Map<string, RegistryEntry> {\n if (!(globalThis as any)[REGISTRY_SYMBOL]) {\n (globalThis as any)[REGISTRY_SYMBOL] = new Map<string, RegistryEntry>();\n }\n return (globalThis as any)[REGISTRY_SYMBOL];\n}\n\nexport function registerNode(\n kind: \"tool\" | \"listener\",\n id: string,\n ref: unknown,\n): void {\n const map = getRegistryMap();\n const key = `${kind}s.${id}`;\n\n if (map.has(key)) {\n throw new Error(`Node ID collision: ${id} is already registered as a ${kind}.`);\n }\n\n const internalId = Symbol(id);\n const filePath = captureFilePath();\n\n if (ref && typeof ref === \"object\") {\n (ref as any).__internalId = internalId;\n (ref as any).__filePath = filePath;\n }\n\n map.set(key, { kind, id, ref });\n}\n\nexport function getRegistry(): ReadonlyMap<string, RegistryEntry> {\n return getRegistryMap();\n}\n\nexport function clearRegistry(): void {\n getRegistryMap().clear();\n}\n","import type { z } from \"zod\";\nimport type { TypedKalpContext } from \"@/context/types\";\nimport { registerNode } from \"@/registry\";\nimport { captureFilePath } from \"@/utils\";\n\nexport interface Listener<\n TInput extends z.ZodTypeAny = z.ZodTypeAny,\n TOutput extends z.ZodTypeAny = z.ZodTypeAny,\n TState extends Record<string, unknown> = Record<string, unknown>,\n> {\n readonly kind: \"listener\";\n readonly event: string;\n readonly inputSchema: TInput;\n readonly outputSchema: TOutput;\n readonly handler: (\n payload: z.infer<TInput>,\n context: TypedKalpContext<TState>,\n ) => Promise<z.infer<TOutput>> | z.infer<TOutput>;\n readonly __filePath?: string;\n readonly __internalId?: symbol;\n readonly __runtimeId?: string;\n}\n\nexport function defineListener<\n TState extends Record<string, unknown> = Record<string, unknown>,\n const TInput extends z.ZodTypeAny = z.ZodTypeAny,\n const TOutput extends z.ZodTypeAny = z.ZodTypeAny,\n>(config: {\n event: string;\n inputSchema: TInput;\n outputSchema: TOutput;\n handler: (\n payload: z.infer<TInput>,\n context: TypedKalpContext<TState>,\n ) => Promise<z.infer<TOutput>> | z.infer<TOutput>;\n}): Listener<TInput, TOutput, TState> {\n const listener: Listener<TInput, TOutput, TState> = {\n kind: \"listener\",\n event: config.event,\n inputSchema: config.inputSchema,\n outputSchema: config.outputSchema,\n handler: config.handler,\n __filePath: captureFilePath(),\n __internalId: Symbol(`listener:${config.event}`),\n __runtimeId: `listener:${config.event}`,\n };\n\n registerNode(\"listener\", config.event, listener);\n return listener;\n}\n","import { z } from \"zod\";\nimport type { Tool, ToolConfig } from \"@/nodes\";\nimport { registerNode } from \"@/registry\";\n\n/**\n * Node factory functions for defining Tools.\n *\n * @module\n */\n\nexport function defineTool<\n TState extends Record<string, unknown> = Record<string, unknown>,\n I extends z.ZodTypeAny = z.ZodTypeAny,\n O = unknown,\n>(config: ToolConfig<I, O, TState>): Tool<I, O, TState> {\n const node: Tool<I, O, TState> = {\n ...config,\n kind: \"tool\",\n __runtimeId: `tool:${config.id}`,\n };\n\n registerNode(\"tool\", config.id, node);\n return node;\n}\n","import { z } from \"zod\";\nimport type { Route, RouteConfig } from \"@/nodes\";\nimport { captureFilePath } from \"@/utils\";\n\n/**\n * Defines an HTTP route exposed by the agent.\n */\nexport function defineRoute<\n TState extends Record<string, unknown> = Record<string, unknown>,\n I extends z.ZodTypeAny | undefined = undefined,\n R = unknown,\n>(config: RouteConfig<I, R, TState>): Route<I, R, TState> {\n return {\n ...config,\n kind: \"route\",\n __filePath: captureFilePath(),\n __internalId: Symbol(config.id || `${config.method}:${config.path}`),\n __runtimeId: `route:${config.method}:${config.path}`,\n };\n}\n","import type { TypedKalpContext } from \"@/context/types\";\nimport type { CronExpression, IanaTimezone } from \"@/schedule\";\nimport { captureFilePath } from \"@/utils\";\n\nexport interface CronDefinition<\n TState extends Record<string, unknown> = Record<string, unknown>,\n> {\n expression: CronExpression;\n timezone?: IanaTimezone;\n handler: (ctx: TypedKalpContext<TState>) => Promise<void> | void;\n __filePath?: string;\n __internalId?: symbol;\n __runtimeId?: string;\n}\n\nexport function defineCron<\n TState extends Record<string, unknown> = Record<string, unknown>,\n>(config: Omit<CronDefinition<TState>, \"__filePath\" | \"__internalId\" | \"__runtimeId\">): CronDefinition<TState> {\n return {\n ...config,\n __filePath: captureFilePath(),\n __internalId: Symbol(\"cron\"),\n __runtimeId: `cron:${crypto.randomUUID()}`,\n };\n}\n","import type { IdentityConfig } from \"@/identity\";\nimport type { AIProvider, ProviderModelMap } from \"@/primitives/ai\";\n\n/**\n * MCP (Model Context Protocol) server configuration.\n *\n * @module\n */\n/**\n * MCP (Model Context Protocol) server configuration.\n */\n\n/**\n * Marker for environment variables in config.\n * Format: {{env:NAME}}\n */\nexport const ENV_MARKER_PREFIX = \"{{env:\";\nexport const ENV_MARKER_SUFFIX = \"}}\";\n\n/**\n * Helper to reference environment variables in kalp.config.ts.\n * Returns a marker string that the CLI can identify to track secret requirements.\n */\nexport const env = (name: string) => `${ENV_MARKER_PREFIX}${name}${ENV_MARKER_SUFFIX}` as unknown as string;\n\nexport type McpAuthInput =\n | string // shorthand for { type: \"bearer\", token: env(string) }\n | {\n type: \"bearer\";\n token: string;\n }\n | {\n type: \"headers\";\n headers: Record<string, string>;\n };\n\nexport type McpServerInput =\n | string // shorthand for { url: string, transport: \"sse\" }\n | {\n url: string;\n transport?: \"sse\" | \"stdio\";\n auth?: McpAuthInput;\n };\n\n/**\n * Strict internal shape for a normalized MCP server.\n */\nexport interface NormalizedMcpServer {\n url: string;\n transport: \"sse\" | \"stdio\";\n auth?: {\n type: \"bearer\";\n token?: string;\n tokenEnv?: string;\n } | {\n type: \"headers\";\n headers: Record<string, string>;\n headersEnv: Record<string, string>; // Maps header name to env var name if applicable\n };\n}\n\n/**\n * Project-level configuration types for Kalp.\n *\n * @module\n */\n\n/**\n * Top-level Kalp project configuration, defined in `kalp.config.ts`.\n *\n * This configuration is global to all agents in the project and defines\n * shared resources like secrets and identity configuration.\n *\n * @typeParam TSecrets - Array of secret environment variable names\n * @typeParam TIdentity - Single identity configuration for the project\n */\nexport interface KalpProjectConfig<\n TSecrets extends readonly string[] = readonly string[],\n TIdentity extends IdentityConfig = IdentityConfig,\n TProvider extends AIProvider = AIProvider,\n> {\n /**\n * Environment variable names that should be treated as secrets.\n * These are validated at build time and securely injected at runtime.\n *\n * @example\n * ```typescript\n * secrets: [\"OPENAI_API_KEY\", \"STRIPE_SECRET_KEY\"]\n * ```\n */\n secrets: TSecrets;\n\n /**\n * Identity configuration for authentication.\n * Only ONE identity configuration is supported per project to ensure\n * consistent identity semantics across all agents.\n *\n * For multi-tenant scenarios (users + bots), use a single provider with\n * a custom mapIdentity that handles both cases based on token structure.\n *\n * If undefined, all requests are treated as unauthenticated (public).\n *\n * @example\n * ```typescript\n * identity: {\n * id: \"main\",\n * strategy: {\n * type: \"jwks\",\n * jwksUrl: \"https://clerk.example.com/.well-known/jwks.json\"\n * },\n * mapIdentity: (payload, headers) => {\n * // Handle both JWT users and API key bots in one config\n * if (headers?.[\"x-bot-key\"]) {\n * return { userId: \"bot-001\" as UserId, claims: { role: \"service\" } };\n * }\n * return {\n * userId: payload.sub as UserId,\n * email: payload.email as string,\n * claims: { role: payload.role || \"user\" }\n * };\n * }\n * }\n * ```\n */\n identity?: TIdentity;\n\n /**\n * Enforce authentication globally across all agents.\n *\n * - `true` (default): All requests must be authenticated. Unauthenticated\n * requests are rejected with a 401 before reaching the agent.\n * - `false`: Unauthenticated requests are allowed. The agent must check\n * `context.auth.isAuthenticated` and handle accordingly.\n *\n * @default true\n */\n enforceGlobalAuth?: boolean;\n\n /**\n * MCP (Model Context Protocol) server configurations.\n * Servers defined here are available at runtime through `ctx.mcp.<server>.*`.\n * Use `kalp mcp generate` to generate strongly typed tool signatures.\n *\n * @example\n * ```typescript\n * mcp: {\n * github: {\n * url: \"https://mcp.github.com/sse\",\n * auth: env(\"GITHUB_TOKEN\")\n * },\n * wikipedia: \"https://mcp.deepwiki.com/mcp\"\n * }\n * ```\n */\n mcp?: Record<string, McpServerInput>;\n\n /**\n * AI provider configuration used by primitives for model typing and defaults.\n */\n ai?: {\n provider: TProvider;\n defaultModel?: ProviderModelMap[TProvider];\n customModels?: readonly string[];\n };\n}\n","import type { IdentityConfig } from \"@/identity\";\nimport type { KalpProjectConfig } from \"@/project/types\";\nimport type { AIProvider } from \"@/primitives/ai\";\n\n/**\n * Project configuration factory function.\n *\n * @module\n */\n\n/**\n * Defines the Kalp project configuration with type checking.\n * Place this in your `kalp.config.ts` at the project root.\n *\n * Provides full type inference for secrets and identity configuration,\n * enabling IDE autocomplete and compile-time validation.\n *\n * @typeParam TSecrets - Array of secret environment variable names\n * @typeParam TIdentity - Single identity configuration\n * @param config - The project configuration object\n * @returns The same configuration object, typed\n *\n * @example\n * ```typescript\n * import { defineConfig, UserId } from \"@kalphq/sdk\";\n *\n * export default defineConfig({\n * secrets: [\"STRIPE_SECRET_KEY\", \"OPENAI_API_KEY\"],\n * identity: {\n * id: \"main\",\n * strategy: {\n * type: \"jwks\",\n * jwksUrl: \"https://clerk.example.com/.well-known/jwks.json\"\n * },\n * mapIdentity: (payload, headers) => {\n * // Handle both JWT users and API key bots\n * if (headers?.[\"x-bot-key\"]) {\n * return { userId: \"bot-001\" as UserId, claims: { role: \"service\" } };\n * }\n * return {\n * userId: payload.sub as UserId,\n * email: payload.email as string,\n * claims: { role: payload.role || \"user\" }\n * };\n * }\n * },\n * enforceGlobalAuth: true\n * } as const);\n * ```\n */\nexport function defineConfig<\n const TSecrets extends readonly string[],\n const TIdentity extends IdentityConfig = IdentityConfig,\n const TProvider extends AIProvider = AIProvider,\n>(\n config: KalpProjectConfig<TSecrets, TIdentity, TProvider>,\n): KalpProjectConfig<TSecrets, TIdentity, TProvider> {\n return config;\n}\n","import {\n ENV_MARKER_PREFIX,\n ENV_MARKER_SUFFIX,\n type McpAuthInput,\n type McpServerInput,\n type NormalizedMcpServer,\n type KalpProjectConfig,\n} from \"./types\";\n\n/**\n * Extracts the environment variable name from a marker string.\n */\nexport function extractEnvName(val: string): string | null {\n if (\n typeof val === \"string\" &&\n val.startsWith(ENV_MARKER_PREFIX) &&\n val.endsWith(ENV_MARKER_SUFFIX)\n ) {\n return val.slice(ENV_MARKER_PREFIX.length, -ENV_MARKER_SUFFIX.length);\n }\n return null;\n}\n\n/**\n * Normalizes a value that might be an environment variable reference.\n */\nfunction normalizeEnvValue(val: string): { value?: string; envName?: string } {\n const envName = extractEnvName(val);\n if (envName) {\n return {\n envName,\n value: typeof process !== \"undefined\" ? process.env[envName] : undefined,\n };\n }\n return { value: val };\n}\n\n/**\n * Converts a user-provided MCP configuration into a strict internal shape.\n */\nexport function normalizeMcpServer(input: McpServerInput): NormalizedMcpServer {\n if (typeof input === \"string\") {\n return {\n url: input,\n transport: \"sse\",\n };\n }\n\n const transport = input.transport || \"sse\";\n const url = input.url;\n\n if (!input.auth) {\n return { url, transport };\n }\n\n let auth: NormalizedMcpServer[\"auth\"];\n\n if (typeof input.auth === \"string\") {\n const { value, envName } = normalizeEnvValue(input.auth);\n auth = {\n type: \"bearer\",\n token: value,\n tokenEnv: envName,\n };\n } else if (input.auth.type === \"bearer\") {\n const { value, envName } = normalizeEnvValue(input.auth.token);\n auth = {\n type: \"bearer\",\n token: value,\n tokenEnv: envName,\n };\n } else if (input.auth.type === \"headers\") {\n const headers: Record<string, string> = {};\n const headersEnv: Record<string, string> = {};\n\n for (const [key, val] of Object.entries(input.auth.headers)) {\n const { value, envName } = normalizeEnvValue(val || \"\");\n if (value !== undefined) headers[key] = value;\n if (envName) headersEnv[key] = envName;\n }\n\n auth = {\n type: \"headers\",\n headers,\n headersEnv,\n };\n }\n\n return { url, transport, auth };\n}\n\n/**\n * Collects all environment variables required by the project's MCP configuration.\n */\nexport function collectMcpSecretRequirements(config: KalpProjectConfig): string[] {\n if (!config.mcp) return [];\n\n const secrets = new Set<string>();\n\n for (const serverInput of Object.values(config.mcp)) {\n const normalized = normalizeMcpServer(serverInput);\n if (!normalized.auth) continue;\n\n if (normalized.auth.type === \"bearer\") {\n if (normalized.auth.tokenEnv) {\n secrets.add(normalized.auth.tokenEnv);\n }\n } else if (normalized.auth.type === \"headers\") {\n for (const envName of Object.values(normalized.auth.headersEnv)) {\n secrets.add(envName);\n }\n }\n }\n\n return Array.from(secrets).sort();\n}\n","export type KalpErrorCode =\n | \"UNKNOWN\"\n | \"INVALID_INPUT\"\n | \"INVALID_MODEL_ID\"\n | \"UNSUPPORTED_MODEL\"\n | \"MISSING_CREDENTIALS\"\n | \"INVALID_CREDENTIALS\"\n | \"FORBIDDEN\"\n | \"NOT_FOUND\"\n | \"RATE_LIMITED\"\n | \"TIMEOUT\"\n | \"AI_PROVIDER_ERROR\"\n | \"MEMORY_ERROR\"\n | \"MEMORY_SUMMARIZATION_ERROR\"\n | \"STORAGE_ERROR\"\n | \"WAIT_ERROR\"\n | \"INTERNAL_ERROR\";\n\nexport interface KalpErrorOptions {\n code: KalpErrorCode;\n message: string;\n status?: number;\n retryable?: boolean;\n details?: Record<string, unknown>;\n cause?: unknown;\n}\n\nexport class KalpError extends Error {\n readonly code: KalpErrorCode;\n readonly status: number;\n readonly retryable: boolean;\n readonly details?: Record<string, unknown>;\n override readonly cause?: unknown;\n\n constructor(options: KalpErrorOptions) {\n super(options.message);\n this.name = \"KalpError\";\n this.code = options.code;\n this.status = options.status ?? 500;\n this.retryable = options.retryable ?? false;\n this.details = options.details;\n this.cause = options.cause;\n }\n\n toJSON(): {\n name: string;\n code: KalpErrorCode;\n message: string;\n status: number;\n retryable: boolean;\n details?: Record<string, unknown>;\n } {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n status: this.status,\n retryable: this.retryable,\n details: this.details,\n };\n }\n}\n\nexport class KalpValidationError extends KalpError {\n constructor(message: string, details?: Record<string, unknown>) {\n super({\n code: \"INVALID_INPUT\",\n message,\n status: 400,\n retryable: false,\n details,\n });\n this.name = \"KalpValidationError\";\n }\n}\n\nexport class KalpConfigurationError extends KalpError {\n constructor(\n message: string,\n code: \"INVALID_MODEL_ID\" | \"UNSUPPORTED_MODEL\" | \"MISSING_CREDENTIALS\" =\n \"MISSING_CREDENTIALS\",\n details?: Record<string, unknown>,\n ) {\n super({\n code,\n message,\n status: 400,\n retryable: false,\n details,\n });\n this.name = \"KalpConfigurationError\";\n }\n}\n\nexport class KalpAuthError extends KalpError {\n constructor(\n message: string,\n code: \"INVALID_CREDENTIALS\" | \"FORBIDDEN\" = \"INVALID_CREDENTIALS\",\n details?: Record<string, unknown>,\n ) {\n super({\n code,\n message,\n status: code === \"FORBIDDEN\" ? 403 : 401,\n retryable: false,\n details,\n });\n this.name = \"KalpAuthError\";\n }\n}\n\nexport class KalpNotFoundError extends KalpError {\n constructor(message: string, details?: Record<string, unknown>) {\n super({\n code: \"NOT_FOUND\",\n message,\n status: 404,\n retryable: false,\n details,\n });\n this.name = \"KalpNotFoundError\";\n }\n}\n\nexport class KalpRateLimitError extends KalpError {\n constructor(message = \"Rate limit exceeded\", details?: Record<string, unknown>) {\n super({\n code: \"RATE_LIMITED\",\n message,\n status: 429,\n retryable: true,\n details,\n });\n this.name = \"KalpRateLimitError\";\n }\n}\n\nexport class KalpTimeoutError extends KalpError {\n constructor(message = \"Operation timed out\", details?: Record<string, unknown>) {\n super({\n code: \"TIMEOUT\",\n message,\n status: 408,\n retryable: true,\n details,\n });\n this.name = \"KalpTimeoutError\";\n }\n}\n\nexport class KalpAIProviderError extends KalpError {\n constructor(message: string, details?: Record<string, unknown>, cause?: unknown) {\n super({\n code: \"AI_PROVIDER_ERROR\",\n message,\n status: 502,\n retryable: true,\n details,\n cause,\n });\n this.name = \"KalpAIProviderError\";\n }\n}\n\nexport class KalpMemoryError extends KalpError {\n constructor(\n message: string,\n code: \"MEMORY_ERROR\" | \"MEMORY_SUMMARIZATION_ERROR\" = \"MEMORY_ERROR\",\n details?: Record<string, unknown>,\n cause?: unknown,\n ) {\n super({\n code,\n message,\n status: 500,\n retryable: true,\n details,\n cause,\n });\n this.name = \"KalpMemoryError\";\n }\n}\n\nexport class KalpStorageError extends KalpError {\n constructor(message: string, details?: Record<string, unknown>, cause?: unknown) {\n super({\n code: \"STORAGE_ERROR\",\n message,\n status: 500,\n retryable: true,\n details,\n cause,\n });\n this.name = \"KalpStorageError\";\n }\n}\n\nexport class KalpWaitError extends KalpError {\n constructor(message: string, details?: Record<string, unknown>, cause?: unknown) {\n super({\n code: \"WAIT_ERROR\",\n message,\n status: 500,\n retryable: false,\n details,\n cause,\n });\n this.name = \"KalpWaitError\";\n }\n}\n\nexport function isKalpError(value: unknown): value is KalpError {\n return value instanceof KalpError;\n}\n\nexport function normalizeKalpError(error: unknown): KalpError {\n if (isKalpError(error)) {\n return error;\n }\n\n if (error instanceof Error) {\n return new KalpError({\n code: \"INTERNAL_ERROR\",\n message: error.message,\n status: 500,\n retryable: false,\n cause: error,\n });\n }\n\n return new KalpError({\n code: \"UNKNOWN\",\n message: \"Unknown runtime error\",\n status: 500,\n retryable: false,\n details: { error },\n });\n}\n"],"mappings":";;;;AGkGO,SAAS,KACd,YACa;AACb,SAAO;AACT;AAoBO,IAAM,cAAc,KAAK,WAAW;AACpC,IAAM,YAAY,KAAK,WAAW;AAClC,IAAM,gBAAgB,KAAK,aAAa;AACxC,IAAM,qBAAqB,KAAK,WAAW;AAC3C,IAAM,iBAAiB,KAAK,YAAY;AAExC,IAAM,oBAAoB,KAAK,aAAa;AAC5C,IAAM,mBAAmB,KAAK,WAAW;ASjHzC,IAAM,oBAAoB;AAC1B,IAAM,oBAAoB;AEL1B,SAAS,eAAe,KAA4B;AACzD,MACE,OAAO,QAAQ,YACf,IAAI,WAAW,iBAAiB,KAChC,IAAI,SAAS,iBAAiB,GAC9B;AACA,WAAO,IAAI,MAAM,kBAAkB,QAAQ,CAAC,kBAAkB,MAAM;EACtE;AACA,SAAO;AACT;AAKA,SAAS,kBAAkB,KAAmD;AAC5E,QAAM,UAAU,eAAe,GAAG;AAClC,MAAI,SAAS;AACX,WAAO;MACL;MACA,OAAO,OAAO,YAAY,cAAc,QAAQ,IAAI,OAAO,IAAI;IAAA;EAEnE;AACA,SAAO,EAAE,OAAO,IAAA;AAClB;AAKO,SAAS,mBAAmB,OAA4C;AAC7E,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;MACL,KAAK;MACL,WAAW;IAAA;EAEf;AAEA,QAAM,YAAY,MAAM,aAAa;AACrC,QAAM,MAAM,MAAM;AAElB,MAAI,CAAC,MAAM,MAAM;AACf,WAAO,EAAE,KAAK,UAAA;EAChB;AAEA,MAAI;AAEJ,MAAI,OAAO,MAAM,SAAS,UAAU;AAClC,UAAM,EAAE,OAAO,QAAA,IAAY,kBAAkB,MAAM,IAAI;AACvD,WAAO;MACL,MAAM;MACN,OAAO;MACP,UAAU;IAAA;EAEd,WAAW,MAAM,KAAK,SAAS,UAAU;AACvC,UAAM,EAAE,OAAO,QAAA,IAAY,kBAAkB,MAAM,KAAK,KAAK;AAC7D,WAAO;MACL,MAAM;MACN,OAAO;MACP,UAAU;IAAA;EAEd,WAAW,MAAM,KAAK,SAAS,WAAW;AACxC,UAAM,UAAkC,CAAA;AACxC,UAAM,aAAqC,CAAA;AAE3C,eAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,MAAM,KAAK,OAAO,GAAG;AAC3D,YAAM,EAAE,OAAO,QAAA,IAAY,kBAAkB,OAAO,EAAE;AACtD,UAAI,UAAU,OAAW,SAAQ,GAAG,IAAI;AACxC,UAAI,QAAS,YAAW,GAAG,IAAI;IACjC;AAEA,WAAO;MACL,MAAM;MACN;MACA;IAAA;EAEJ;AAEA,SAAO,EAAE,KAAK,WAAW,KAAA;AAC3B;AAKO,SAAS,6BAA6B,QAAqC;AAChF,MAAI,CAAC,OAAO,IAAK,QAAO,CAAA;AAExB,QAAM,UAAA,oBAAc,IAAA;AAEpB,aAAW,eAAe,OAAO,OAAO,OAAO,GAAG,GAAG;AACnD,UAAM,aAAa,mBAAmB,WAAW;AACjD,QAAI,CAAC,WAAW,KAAM;AAEtB,QAAI,WAAW,KAAK,SAAS,UAAU;AACrC,UAAI,WAAW,KAAK,UAAU;AAC5B,gBAAQ,IAAI,WAAW,KAAK,QAAQ;MACtC;IACF,WAAW,WAAW,KAAK,SAAS,WAAW;AAC7C,iBAAW,WAAW,OAAO,OAAO,WAAW,KAAK,UAAU,GAAG;AAC/D,gBAAQ,IAAI,OAAO;MACrB;IACF;EACF;AAEA,SAAO,MAAM,KAAK,OAAO,EAAE,KAAA;AAC7B;","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
resolveProvider
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-D53K6UE6.js";
|
|
5
5
|
|
|
6
6
|
// src/utils/agents-remote.ts
|
|
7
7
|
import { join } from "path";
|
|
@@ -61,4 +61,4 @@ export {
|
|
|
61
61
|
writeRemoteAgentsIndex,
|
|
62
62
|
readRemoteAgentPointers
|
|
63
63
|
};
|
|
64
|
-
//# sourceMappingURL=chunk-
|
|
64
|
+
//# sourceMappingURL=chunk-TNNBTSDC.js.map
|