@kalphq/cli 0.0.0-dev-20260416055233 → 0.0.2
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-VMU456Z7.js → chunk-BO2MEQKM.js} +13 -1
- package/dist/chunk-BO2MEQKM.js.map +1 -0
- package/dist/{create-VKJ6C6DZ.js → create-ZNKKOQLH.js} +2 -2
- package/dist/index.js +2 -2
- package/dist/{init-5UAVM2WR.js → init-7FSWWKI5.js} +7 -15
- package/dist/init-7FSWWKI5.js.map +1 -0
- package/package.json +2 -2
- package/dist/chunk-VMU456Z7.js.map +0 -1
- package/dist/init-5UAVM2WR.js.map +0 -1
- package/templates/project-root/package.json +0 -9
- /package/dist/{create-VKJ6C6DZ.js.map → create-ZNKKOQLH.js.map} +0 -0
|
@@ -76,6 +76,18 @@ export default defineConfig({
|
|
|
76
76
|
force: true
|
|
77
77
|
});
|
|
78
78
|
await replacePlaceholders(kalpDir, { __PROJECT_NAME__: projectName });
|
|
79
|
+
const gitignorePath = join(cwd, ".gitignore");
|
|
80
|
+
let existing = "";
|
|
81
|
+
try {
|
|
82
|
+
existing = await readFile(gitignorePath, "utf-8");
|
|
83
|
+
} catch {
|
|
84
|
+
}
|
|
85
|
+
const entries = ["kalp/meta/", ".env", "node_modules/", "dist/"];
|
|
86
|
+
const toAdd = entries.filter((e) => !existing.includes(e));
|
|
87
|
+
if (toAdd.length > 0) {
|
|
88
|
+
const appended = existing ? existing.trimEnd() + "\n" + toAdd.join("\n") + "\n" : toAdd.join("\n") + "\n";
|
|
89
|
+
await writeFile(gitignorePath, appended, "utf-8");
|
|
90
|
+
}
|
|
79
91
|
}
|
|
80
92
|
async function scaffoldAgent(opts) {
|
|
81
93
|
const { agentName, templateId, cwd } = opts;
|
|
@@ -106,4 +118,4 @@ export {
|
|
|
106
118
|
scaffoldProject,
|
|
107
119
|
scaffoldAgent
|
|
108
120
|
};
|
|
109
|
-
//# sourceMappingURL=chunk-
|
|
121
|
+
//# sourceMappingURL=chunk-BO2MEQKM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/templates/index.ts","../src/scaffold.ts"],"sourcesContent":["export type TemplateId =\n | \"customer-support\"\n | \"b2b-sales\"\n | \"financial-agent\"\n | \"minimal\";\n\nexport interface TemplateMeta {\n id: TemplateId;\n label: string;\n hint: string;\n secrets: string[];\n}\n\nexport const TEMPLATES: TemplateMeta[] = [\n {\n id: \"customer-support\",\n label: \"Customer Support\",\n hint: \"ticket routing, escalation, knowledge base\",\n secrets: [\"OPENAI_API_KEY\"],\n },\n {\n id: \"b2b-sales\",\n label: \"B2B Sales Outreach\",\n hint: \"CRM enrichment, lead scoring\",\n secrets: [\"OPENAI_API_KEY\", \"CRM_API_KEY\"],\n },\n {\n id: \"financial-agent\",\n label: \"Financial Agent\",\n hint: \"market signals, portfolio analysis\",\n secrets: [\"OPENAI_API_KEY\", \"MARKET_DATA_API_KEY\"],\n },\n {\n id: \"minimal\",\n label: \"Minimal Skeleton\",\n hint: \"bare structure, start from scratch\",\n secrets: [],\n },\n];\n\nexport function getTemplateMeta(id: TemplateId): TemplateMeta {\n return TEMPLATES.find((t) => t.id === id)!;\n}\n","import { writeFile, readFile, readdir, cp } from \"node:fs/promises\";\nimport { fileURLToPath } from \"node:url\";\nimport { join, dirname } from \"node:path\";\nimport { getTemplateMeta, type TemplateId } from \"./templates/index.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nexport const TEMPLATES_DIR = join(__dirname, \"..\", \"templates\");\n\nasync function replacePlaceholders(\n dir: string,\n map: Record<string, string>,\n): Promise<void> {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fp = join(dir, entry.name);\n if (entry.isDirectory()) {\n await replacePlaceholders(fp, map);\n } else if (entry.isFile() && entry.name !== \".gitkeep\") {\n try {\n let src = await readFile(fp, \"utf-8\");\n let changed = false;\n for (const [from, to] of Object.entries(map)) {\n if (src.includes(from)) {\n src = src.replaceAll(from, to);\n changed = true;\n }\n }\n if (changed) await writeFile(fp, src, \"utf-8\");\n } catch {\n // binary file — skip\n }\n }\n }\n}\n\nexport async function scaffoldProject(opts: {\n projectName: string;\n cwd: string;\n}): Promise<void> {\n const { projectName, cwd } = opts;\n\n // ── kalp.config.ts at root ─────────────────────────────────────────────\n const kalpConfig = `import { defineConfig } from \"@kalphq/sdk\";\n\nexport default defineConfig({\n projectId: \"${projectName}\",\n secrets: [],\n});\n`;\n await writeFile(join(cwd, \"kalp.config.ts\"), kalpConfig, \"utf-8\");\n\n // ── kalp/ sub-package via fs.cp ───────────────────────────────────────\n const kalpDir = join(cwd, \"kalp\");\n await cp(join(TEMPLATES_DIR, \"project\"), kalpDir, {\n recursive: true,\n force: true,\n });\n await replacePlaceholders(kalpDir, { __PROJECT_NAME__: projectName });\n\n // ── Root .gitignore ────────────────────────────────────────────────────\n const gitignorePath = join(cwd, \".gitignore\");\n let existing = \"\";\n try {\n existing = await readFile(gitignorePath, \"utf-8\");\n } catch {\n // doesn't exist yet\n }\n const entries = [\"kalp/meta/\", \".env\", \"node_modules/\", \"dist/\"];\n const toAdd = entries.filter((e) => !existing.includes(e));\n if (toAdd.length > 0) {\n const appended = existing\n ? existing.trimEnd() + \"\\n\" + toAdd.join(\"\\n\") + \"\\n\"\n : toAdd.join(\"\\n\") + \"\\n\";\n await writeFile(gitignorePath, appended, \"utf-8\");\n }\n}\n\nexport async function scaffoldAgent(opts: {\n agentName: string;\n templateId: TemplateId;\n cwd: string;\n}): Promise<void> {\n const { agentName, templateId, cwd } = opts;\n const meta = getTemplateMeta(templateId);\n const agentDir = join(cwd, \"kalp\", \"agents\", agentName);\n\n // ── Agent files via fs.cp ─────────────────────────────────────────────\n await cp(join(TEMPLATES_DIR, \"agents\", templateId), agentDir, {\n recursive: true,\n force: true,\n });\n await replacePlaceholders(agentDir, { __AGENT_NAME__: agentName });\n\n // ── .env at root (append missing secrets) ─────────────────────────────\n if (meta.secrets.length > 0) {\n const envPath = join(cwd, \".env\");\n let envExisting = \"\";\n try {\n envExisting = await readFile(envPath, \"utf-8\");\n } catch {\n // doesn't exist yet\n }\n const toAdd = meta.secrets\n .filter((s) => !envExisting.includes(s))\n .map((s) => `${s}=`)\n .join(\"\\n\");\n if (toAdd) {\n const content = envExisting\n ? envExisting.trimEnd() + \"\\n\" + toAdd + \"\\n\"\n : toAdd + \"\\n\";\n await writeFile(envPath, content, \"utf-8\");\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
TEMPLATES,
|
|
4
4
|
scaffoldAgent,
|
|
5
5
|
scaffoldProject
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-BO2MEQKM.js";
|
|
7
7
|
|
|
8
8
|
// src/commands/create.ts
|
|
9
9
|
import { join } from "path";
|
|
@@ -115,4 +115,4 @@ var create_default = defineCommand({
|
|
|
115
115
|
export {
|
|
116
116
|
create_default as default
|
|
117
117
|
};
|
|
118
|
-
//# sourceMappingURL=create-
|
|
118
|
+
//# sourceMappingURL=create-ZNKKOQLH.js.map
|
package/dist/index.js
CHANGED
|
@@ -9,8 +9,8 @@ var main = defineCommand({
|
|
|
9
9
|
description: "\u{1F98B} Zero-config agent infrastructure"
|
|
10
10
|
},
|
|
11
11
|
subCommands: {
|
|
12
|
-
init: () => import("./init-
|
|
13
|
-
create: () => import("./create-
|
|
12
|
+
init: () => import("./init-7FSWWKI5.js").then((r) => r.default),
|
|
13
|
+
create: () => import("./create-ZNKKOQLH.js").then((r) => r.default),
|
|
14
14
|
build: () => import("./build-ZMN2247N.js").then((r) => r.default)
|
|
15
15
|
}
|
|
16
16
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
scaffoldProject
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-BO2MEQKM.js";
|
|
5
5
|
|
|
6
6
|
// src/commands/init.ts
|
|
7
7
|
import { join } from "path";
|
|
@@ -9,7 +9,6 @@ import { access } from "fs/promises";
|
|
|
9
9
|
import { defineCommand } from "citty";
|
|
10
10
|
import * as p from "@clack/prompts";
|
|
11
11
|
import pc from "picocolors";
|
|
12
|
-
import { addDependency } from "nypm";
|
|
13
12
|
var LOGO = "\u{1F98B}";
|
|
14
13
|
var init_default = defineCommand({
|
|
15
14
|
meta: { name: "init", description: "Scaffold a new Kalp project" },
|
|
@@ -47,28 +46,21 @@ var init_default = defineCommand({
|
|
|
47
46
|
s.start("Creating project structure");
|
|
48
47
|
await scaffoldProject({ projectName: answers.name, cwd });
|
|
49
48
|
s.stop("Project structure created");
|
|
50
|
-
s.start(`Adding ${pc.cyan("@kalphq/sdk")} to your project`);
|
|
51
|
-
try {
|
|
52
|
-
await addDependency("@kalphq/sdk", { cwd, dev: true, silent: true });
|
|
53
|
-
s.stop(`${pc.cyan("@kalphq/sdk")} installed`);
|
|
54
|
-
} catch {
|
|
55
|
-
s.stop(pc.yellow(`Skipped \u2014 run manually: npm install -D @kalphq/sdk`));
|
|
56
|
-
}
|
|
57
49
|
p.note(
|
|
58
50
|
[
|
|
59
51
|
`${pc.dim("\u2022")} ${pc.cyan("kalp.config.ts")} ${pc.dim("\u2014 project config")}`,
|
|
60
52
|
`${pc.dim("\u2022")} ${pc.cyan("kalp/")} ${pc.dim("\u2014 agents sub-package")}`,
|
|
61
53
|
``,
|
|
62
|
-
`${pc.dim("Next:")}`,
|
|
63
|
-
`
|
|
64
|
-
`
|
|
54
|
+
`${pc.dim("Next steps:")}`,
|
|
55
|
+
` ${pc.cyan("cd kalp && npm install")}`,
|
|
56
|
+
` ${pc.cyan("kalp create")} ${pc.dim("\u2014 add your first agent")}`
|
|
65
57
|
].join("\n"),
|
|
66
|
-
"
|
|
58
|
+
"Created"
|
|
67
59
|
);
|
|
68
|
-
p.outro(pc.green("
|
|
60
|
+
p.outro(`${LOGO} ${pc.green("Project initialized.")}`);
|
|
69
61
|
}
|
|
70
62
|
});
|
|
71
63
|
export {
|
|
72
64
|
init_default as default
|
|
73
65
|
};
|
|
74
|
-
//# sourceMappingURL=init-
|
|
66
|
+
//# sourceMappingURL=init-7FSWWKI5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/init.ts"],"sourcesContent":["import { join } from \"node:path\";\nimport { access } from \"node:fs/promises\";\nimport { defineCommand } from \"citty\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { scaffoldProject } from \"../scaffold.js\";\n\nconst LOGO = \"🦋\";\n\nexport default defineCommand({\n meta: { name: \"init\", description: \"Scaffold a new Kalp project\" },\n async run() {\n const cwd = process.cwd();\n\n p.intro(`${LOGO} ${pc.bold(\"kalp init\")}`);\n\n // ── Guard: already initialized ───────────────────────────────────────\n try {\n await access(join(cwd, \"kalp.config.ts\"));\n p.log.error(\n `${pc.cyan(\"kalp.config.ts\")} already exists. Run ${pc.cyan(\"kalp create\")} to add an agent.`,\n );\n process.exit(1);\n } catch {\n // expected: file doesn't exist yet\n }\n\n const answers = await p.group(\n {\n name: () =>\n p.text({\n message: \"What is the name of your project?\",\n placeholder: \"my-project\",\n validate: (v) => {\n if (!v.trim()) return \"Project name is required.\";\n if (!/^[a-z0-9-]+$/.test(v))\n return \"Use lowercase letters, numbers, and dashes only.\";\n },\n }),\n },\n {\n onCancel: () => {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n },\n },\n );\n\n const s = p.spinner();\n s.start(\"Creating project structure\");\n await scaffoldProject({ projectName: answers.name, cwd });\n s.stop(\"Project structure created\");\n\n p.note(\n [\n `${pc.dim(\"•\")} ${pc.cyan(\"kalp.config.ts\")} ${pc.dim(\"— project config\")}`,\n `${pc.dim(\"•\")} ${pc.cyan(\"kalp/\")} ${pc.dim(\"— agents sub-package\")}`,\n ``,\n `${pc.dim(\"Next steps:\")}`,\n ` ${pc.cyan(\"cd kalp && npm install\")}`,\n ` ${pc.cyan(\"kalp create\")} ${pc.dim(\"— add your first agent\")}`,\n ].join(\"\\n\"),\n \"Created\",\n );\n\n p.outro(`${LOGO} ${pc.green(\"Project initialized.\")}`);\n },\n});\n"],"mappings":";;;;;;AAAA,SAAS,YAAY;AACrB,SAAS,cAAc;AACvB,SAAS,qBAAqB;AAC9B,YAAY,OAAO;AACnB,OAAO,QAAQ;AAGf,IAAM,OAAO;AAEb,IAAO,eAAQ,cAAc;AAAA,EAC3B,MAAM,EAAE,MAAM,QAAQ,aAAa,8BAA8B;AAAA,EACjE,MAAM,MAAM;AACV,UAAM,MAAM,QAAQ,IAAI;AAExB,IAAE,QAAM,GAAG,IAAI,IAAI,GAAG,KAAK,WAAW,CAAC,EAAE;AAGzC,QAAI;AACF,YAAM,OAAO,KAAK,KAAK,gBAAgB,CAAC;AACxC,MAAE,MAAI;AAAA,QACJ,GAAG,GAAG,KAAK,gBAAgB,CAAC,wBAAwB,GAAG,KAAK,aAAa,CAAC;AAAA,MAC5E;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB,QAAQ;AAAA,IAER;AAEA,UAAM,UAAU,MAAQ;AAAA,MACtB;AAAA,QACE,MAAM,MACF,OAAK;AAAA,UACL,SAAS;AAAA,UACT,aAAa;AAAA,UACb,UAAU,CAAC,MAAM;AACf,gBAAI,CAAC,EAAE,KAAK,EAAG,QAAO;AACtB,gBAAI,CAAC,eAAe,KAAK,CAAC;AACxB,qBAAO;AAAA,UACX;AAAA,QACF,CAAC;AAAA,MACL;AAAA,MACA;AAAA,QACE,UAAU,MAAM;AACd,UAAE,SAAO,kBAAkB;AAC3B,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAEA,UAAM,IAAM,UAAQ;AACpB,MAAE,MAAM,4BAA4B;AACpC,UAAM,gBAAgB,EAAE,aAAa,QAAQ,MAAM,IAAI,CAAC;AACxD,MAAE,KAAK,2BAA2B;AAElC,IAAE;AAAA,MACA;AAAA,QACE,GAAG,GAAG,IAAI,QAAG,CAAC,IAAI,GAAG,KAAK,gBAAgB,CAAC,IAAI,GAAG,IAAI,uBAAkB,CAAC;AAAA,QACzE,GAAG,GAAG,IAAI,QAAG,CAAC,IAAI,GAAG,KAAK,OAAO,CAAC,IAAI,GAAG,IAAI,2BAAsB,CAAC;AAAA,QACpE;AAAA,QACA,GAAG,GAAG,IAAI,aAAa,CAAC;AAAA,QACxB,KAAK,GAAG,KAAK,wBAAwB,CAAC;AAAA,QACtC,KAAK,GAAG,KAAK,aAAa,CAAC,IAAI,GAAG,IAAI,6BAAwB,CAAC;AAAA,MACjE,EAAE,KAAK,IAAI;AAAA,MACX;AAAA,IACF;AAEA,IAAE,QAAM,GAAG,IAAI,IAAI,GAAG,MAAM,sBAAsB,CAAC,EAAE;AAAA,EACvD;AACF,CAAC;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kalphq/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "Zero-config CLI for deploying Kalp agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"nypm": "^0.3.12",
|
|
25
25
|
"picocolors": "^1.1.1",
|
|
26
26
|
"zod": "^3.25.76",
|
|
27
|
-
"@kalphq/sdk": "0.
|
|
27
|
+
"@kalphq/sdk": "0.1.0"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@types/node": "^22.15.3",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/templates/index.ts","../src/scaffold.ts"],"sourcesContent":["export type TemplateId =\n | \"customer-support\"\n | \"b2b-sales\"\n | \"financial-agent\"\n | \"minimal\";\n\nexport interface TemplateMeta {\n id: TemplateId;\n label: string;\n hint: string;\n secrets: string[];\n}\n\nexport const TEMPLATES: TemplateMeta[] = [\n {\n id: \"customer-support\",\n label: \"Customer Support\",\n hint: \"ticket routing, escalation, knowledge base\",\n secrets: [\"OPENAI_API_KEY\"],\n },\n {\n id: \"b2b-sales\",\n label: \"B2B Sales Outreach\",\n hint: \"CRM enrichment, lead scoring\",\n secrets: [\"OPENAI_API_KEY\", \"CRM_API_KEY\"],\n },\n {\n id: \"financial-agent\",\n label: \"Financial Agent\",\n hint: \"market signals, portfolio analysis\",\n secrets: [\"OPENAI_API_KEY\", \"MARKET_DATA_API_KEY\"],\n },\n {\n id: \"minimal\",\n label: \"Minimal Skeleton\",\n hint: \"bare structure, start from scratch\",\n secrets: [],\n },\n];\n\nexport function getTemplateMeta(id: TemplateId): TemplateMeta {\n return TEMPLATES.find((t) => t.id === id)!;\n}\n","import { writeFile, readFile, readdir, cp } from \"node:fs/promises\";\nimport { fileURLToPath } from \"node:url\";\nimport { join, dirname } from \"node:path\";\nimport { getTemplateMeta, type TemplateId } from \"./templates/index.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nexport const TEMPLATES_DIR = join(__dirname, \"..\", \"templates\");\n\nasync function replacePlaceholders(\n dir: string,\n map: Record<string, string>,\n): Promise<void> {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fp = join(dir, entry.name);\n if (entry.isDirectory()) {\n await replacePlaceholders(fp, map);\n } else if (entry.isFile() && entry.name !== \".gitkeep\") {\n try {\n let src = await readFile(fp, \"utf-8\");\n let changed = false;\n for (const [from, to] of Object.entries(map)) {\n if (src.includes(from)) {\n src = src.replaceAll(from, to);\n changed = true;\n }\n }\n if (changed) await writeFile(fp, src, \"utf-8\");\n } catch {\n // binary file — skip\n }\n }\n }\n}\n\nexport async function scaffoldProject(opts: {\n projectName: string;\n cwd: string;\n}): Promise<void> {\n const { projectName, cwd } = opts;\n\n // ── kalp.config.ts at root ─────────────────────────────────────────────\n const kalpConfig = `import { defineConfig } from \"@kalphq/sdk\";\n\nexport default defineConfig({\n projectId: \"${projectName}\",\n secrets: [],\n});\n`;\n await writeFile(join(cwd, \"kalp.config.ts\"), kalpConfig, \"utf-8\");\n\n // ── kalp/ sub-package via fs.cp ───────────────────────────────────────\n const kalpDir = join(cwd, \"kalp\");\n await cp(join(TEMPLATES_DIR, \"project\"), kalpDir, {\n recursive: true,\n force: true,\n });\n await replacePlaceholders(kalpDir, { __PROJECT_NAME__: projectName });\n}\n\nexport async function scaffoldAgent(opts: {\n agentName: string;\n templateId: TemplateId;\n cwd: string;\n}): Promise<void> {\n const { agentName, templateId, cwd } = opts;\n const meta = getTemplateMeta(templateId);\n const agentDir = join(cwd, \"kalp\", \"agents\", agentName);\n\n // ── Agent files via fs.cp ─────────────────────────────────────────────\n await cp(join(TEMPLATES_DIR, \"agents\", templateId), agentDir, {\n recursive: true,\n force: true,\n });\n await replacePlaceholders(agentDir, { __AGENT_NAME__: agentName });\n\n // ── .env at root (append missing secrets) ─────────────────────────────\n if (meta.secrets.length > 0) {\n const envPath = join(cwd, \".env\");\n let envExisting = \"\";\n try {\n envExisting = await readFile(envPath, \"utf-8\");\n } catch {\n // doesn't exist yet\n }\n const toAdd = meta.secrets\n .filter((s) => !envExisting.includes(s))\n .map((s) => `${s}=`)\n .join(\"\\n\");\n if (toAdd) {\n const content = envExisting\n ? envExisting.trimEnd() + \"\\n\" + toAdd + \"\\n\"\n : toAdd + \"\\n\";\n await writeFile(envPath, content, \"utf-8\");\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/init.ts"],"sourcesContent":["import { join } from \"node:path\";\nimport { access } from \"node:fs/promises\";\nimport { defineCommand } from \"citty\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { addDependency } from \"nypm\";\nimport { scaffoldProject } from \"../scaffold.js\";\n\nconst LOGO = \"🦋\";\n\nexport default defineCommand({\n meta: { name: \"init\", description: \"Scaffold a new Kalp project\" },\n async run() {\n const cwd = process.cwd();\n\n p.intro(`${LOGO} ${pc.bold(\"kalp init\")}`);\n\n // ── Guard: already initialized ───────────────────────────────────────\n try {\n await access(join(cwd, \"kalp.config.ts\"));\n p.log.error(\n `${pc.cyan(\"kalp.config.ts\")} already exists. Run ${pc.cyan(\"kalp create\")} to add an agent.`,\n );\n process.exit(1);\n } catch {\n // expected: file doesn't exist yet\n }\n\n const answers = await p.group(\n {\n name: () =>\n p.text({\n message: \"What is the name of your project?\",\n placeholder: \"my-project\",\n validate: (v) => {\n if (!v.trim()) return \"Project name is required.\";\n if (!/^[a-z0-9-]+$/.test(v))\n return \"Use lowercase letters, numbers, and dashes only.\";\n },\n }),\n },\n {\n onCancel: () => {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n },\n },\n );\n\n const s = p.spinner();\n\n s.start(\"Creating project structure\");\n await scaffoldProject({ projectName: answers.name, cwd });\n s.stop(\"Project structure created\");\n\n s.start(`Adding ${pc.cyan(\"@kalphq/sdk\")} to your project`);\n try {\n await addDependency(\"@kalphq/sdk\", { cwd, dev: true, silent: true });\n s.stop(`${pc.cyan(\"@kalphq/sdk\")} installed`);\n } catch {\n s.stop(pc.yellow(`Skipped — run manually: npm install -D @kalphq/sdk`));\n }\n\n p.note(\n [\n `${pc.dim(\"•\")} ${pc.cyan(\"kalp.config.ts\")} ${pc.dim(\"— project config\")}`,\n `${pc.dim(\"•\")} ${pc.cyan(\"kalp/\")} ${pc.dim(\"— agents sub-package\")}`,\n ``,\n `${pc.dim(\"Next:\")}`,\n ` 1. ${pc.cyan(\"cd kalp && npm install\")}`,\n ` 2. ${pc.cyan(\"kalp create\")} ${pc.dim(\"— add your first agent\")}`,\n ].join(\"\\n\"),\n \"You're ready 🦋\",\n );\n\n p.outro(pc.green(\"Kalp initialized successfully.\"));\n },\n});\n"],"mappings":";;;;;;AAAA,SAAS,YAAY;AACrB,SAAS,cAAc;AACvB,SAAS,qBAAqB;AAC9B,YAAY,OAAO;AACnB,OAAO,QAAQ;AACf,SAAS,qBAAqB;AAG9B,IAAM,OAAO;AAEb,IAAO,eAAQ,cAAc;AAAA,EAC3B,MAAM,EAAE,MAAM,QAAQ,aAAa,8BAA8B;AAAA,EACjE,MAAM,MAAM;AACV,UAAM,MAAM,QAAQ,IAAI;AAExB,IAAE,QAAM,GAAG,IAAI,IAAI,GAAG,KAAK,WAAW,CAAC,EAAE;AAGzC,QAAI;AACF,YAAM,OAAO,KAAK,KAAK,gBAAgB,CAAC;AACxC,MAAE,MAAI;AAAA,QACJ,GAAG,GAAG,KAAK,gBAAgB,CAAC,wBAAwB,GAAG,KAAK,aAAa,CAAC;AAAA,MAC5E;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB,QAAQ;AAAA,IAER;AAEA,UAAM,UAAU,MAAQ;AAAA,MACtB;AAAA,QACE,MAAM,MACF,OAAK;AAAA,UACL,SAAS;AAAA,UACT,aAAa;AAAA,UACb,UAAU,CAAC,MAAM;AACf,gBAAI,CAAC,EAAE,KAAK,EAAG,QAAO;AACtB,gBAAI,CAAC,eAAe,KAAK,CAAC;AACxB,qBAAO;AAAA,UACX;AAAA,QACF,CAAC;AAAA,MACL;AAAA,MACA;AAAA,QACE,UAAU,MAAM;AACd,UAAE,SAAO,kBAAkB;AAC3B,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAEA,UAAM,IAAM,UAAQ;AAEpB,MAAE,MAAM,4BAA4B;AACpC,UAAM,gBAAgB,EAAE,aAAa,QAAQ,MAAM,IAAI,CAAC;AACxD,MAAE,KAAK,2BAA2B;AAElC,MAAE,MAAM,UAAU,GAAG,KAAK,aAAa,CAAC,kBAAkB;AAC1D,QAAI;AACF,YAAM,cAAc,eAAe,EAAE,KAAK,KAAK,MAAM,QAAQ,KAAK,CAAC;AACnE,QAAE,KAAK,GAAG,GAAG,KAAK,aAAa,CAAC,YAAY;AAAA,IAC9C,QAAQ;AACN,QAAE,KAAK,GAAG,OAAO,yDAAoD,CAAC;AAAA,IACxE;AAEA,IAAE;AAAA,MACA;AAAA,QACE,GAAG,GAAG,IAAI,QAAG,CAAC,IAAI,GAAG,KAAK,gBAAgB,CAAC,IAAI,GAAG,IAAI,uBAAkB,CAAC;AAAA,QACzE,GAAG,GAAG,IAAI,QAAG,CAAC,IAAI,GAAG,KAAK,OAAO,CAAC,IAAI,GAAG,IAAI,2BAAsB,CAAC;AAAA,QACpE;AAAA,QACA,GAAG,GAAG,IAAI,OAAO,CAAC;AAAA,QAClB,QAAQ,GAAG,KAAK,wBAAwB,CAAC;AAAA,QACzC,QAAQ,GAAG,KAAK,aAAa,CAAC,IAAI,GAAG,IAAI,6BAAwB,CAAC;AAAA,MACpE,EAAE,KAAK,IAAI;AAAA,MACX;AAAA,IACF;AAEA,IAAE,QAAM,GAAG,MAAM,gCAAgC,CAAC;AAAA,EACpD;AACF,CAAC;","names":[]}
|
|
File without changes
|