@ekairos/cli 1.22.40-beta.development.0

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/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # Ekairos CLI
2
+
3
+ CLI for installing and updating Ekairos UI components and agent-facing packages.
4
+
5
+ ## Run
6
+
7
+ ```bash
8
+ npm install -g @ekairos/cli
9
+ ekairos --help
10
+ ```
11
+
12
+ Create a domain app:
13
+
14
+ ```bash
15
+ ekairos create-app ./supply-chain --next --install --smoke --json
16
+ ```
17
+
18
+ Run the full local demo cycle:
19
+
20
+ ```bash
21
+ ekairos create-app --demo
22
+ ```
23
+
24
+ ## Async mode
25
+
26
+ Use async mode when the caller is another tool or agent.
27
+
28
+ ```bash
29
+ ekairos --async
30
+ ```
31
+
32
+ Resume a session:
33
+
34
+ ```bash
35
+ ekairos --session <session-id> --input '{"action":"update-all"}'
36
+ ```
37
+
38
+ ## Local development
39
+
40
+ ```bash
41
+ pnpm --filter @ekairos/cli build
42
+ EKAIROS_REGISTRY_URL=http://localhost:3001 node packages/cli/dist/index.mjs
43
+ ```
package/SKILL.md ADDED
@@ -0,0 +1,79 @@
1
+ # Skill: ekairos-cli
2
+
3
+ Use this skill when operating the Ekairos CLI, creating apps with the CLI, smoke-testing generated apps, or preparing CLI-driven workflows for agents.
4
+
5
+ ## Dependencies
6
+
7
+ This CLI uses the domain library and its skill:
8
+
9
+ - Domain package: `@ekairos/domain`
10
+ - Domain skill: `../domain/SKILL.md`
11
+
12
+ Always read the domain skill when the CLI task involves schemas, actions, runtime routes, or generated app code.
13
+
14
+ ## CLI Contract
15
+
16
+ Canonical command:
17
+
18
+ ```powershell
19
+ ekairos create-app <dir> --next --install --smoke --json
20
+ ```
21
+
22
+ Full demo cycle:
23
+
24
+ ```powershell
25
+ ekairos create-app --demo
26
+ ```
27
+
28
+ `--demo` defaults to a supply-chain app, `--next`, `--install`, `--smoke`, `--keep-server`, and `pnpm`.
29
+
30
+ Domain operations stay under the domain namespace:
31
+
32
+ ```powershell
33
+ ekairos domain query "{ procurement_order: { supplier: {} } }" --baseUrl=http://localhost:3000 --admin
34
+ ```
35
+
36
+ Non-interactive app creation must be explicit:
37
+
38
+ - `--json`
39
+ - `--plain`
40
+ - `--no-ui`
41
+
42
+ Non-interactive app creation must also pass a framework:
43
+
44
+ - `--next`
45
+ - or `--framework=next`
46
+
47
+ ## App Creation Workflow
48
+
49
+ 1. Choose a target directory under a test-apps folder when experimenting.
50
+ 2. Use `--instantToken` or provide `--appId` and `--adminToken` when provisioning is required.
51
+ 3. Use `--smoke` when the generated app should be verified end to end.
52
+ 4. Use `--smoke --keep-server` when the user needs a live local review URL.
53
+ 5. Never print admin tokens unless the user explicitly passes `--print-secrets`.
54
+
55
+ ## Supply Chain Template Smoke
56
+
57
+ The default app scaffold validates:
58
+
59
+ - `supplyChain.order.launch`
60
+ - `procurement_order` nested with supplier, stock items, shipments, and inspections
61
+ - optional `supplyChain.shipment.expedite`
62
+
63
+ Expected smoke summary:
64
+
65
+ ```txt
66
+ orders >= 1
67
+ shipments >= 1
68
+ inspections >= 1
69
+ ```
70
+
71
+ ## Help And Skill Discovery
72
+
73
+ `ekairos --help`, `ekairos create-app --help`, and `ekairos domain --help` should show skill paths.
74
+
75
+ Agents should prefer the printed skill path over guessing package internals.
76
+
77
+ ## Related Skills
78
+
79
+ - Domain design and runtime code: `../domain/SKILL.md`
@@ -0,0 +1,228 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/lib/dataset.ts
4
+ import meow from "meow";
5
+ import { readFile } from "fs/promises";
6
+ import { resolve } from "path";
7
+ import { init, id as newId } from "@instantdb/admin";
8
+ import { DatasetService, datasetDomain } from "@ekairos/dataset";
9
+ function readEnv(name) {
10
+ return String(process.env[name] ?? "").trim();
11
+ }
12
+ function resolveInstantCredentials(flags) {
13
+ const appId = flags.appId || readEnv("INSTANT_APP_ID") || readEnv("NEXT_PUBLIC_INSTANT_APP_ID");
14
+ const adminToken = flags.adminToken || readEnv("INSTANT_APP_ADMIN_TOKEN");
15
+ return { appId, adminToken };
16
+ }
17
+ function parseJsonValue(value, label) {
18
+ try {
19
+ return JSON.parse(value);
20
+ } catch (error) {
21
+ const msg = error instanceof Error ? error.message : String(error);
22
+ throw new Error(`${label} must be valid JSON: ${msg}`);
23
+ }
24
+ }
25
+ async function readJsonFile(filePath, label) {
26
+ const absPath = resolve(process.cwd(), filePath);
27
+ const content = await readFile(absPath, "utf-8");
28
+ return parseJsonValue(content, label);
29
+ }
30
+ function parseJsonl(content) {
31
+ const rows = [];
32
+ const lines = content.split(/\r?\n/);
33
+ for (const line of lines) {
34
+ const trimmed = line.trim();
35
+ if (!trimmed) continue;
36
+ rows.push(parseJsonValue(trimmed, "rowsFile JSONL"));
37
+ }
38
+ return rows;
39
+ }
40
+ function normalizeRows(data) {
41
+ if (Array.isArray(data)) return data;
42
+ if (data && typeof data === "object" && Array.isArray(data.rows)) {
43
+ return data.rows;
44
+ }
45
+ throw new Error("rows must be a JSON array or an object with a rows[] field.");
46
+ }
47
+ async function loadRows(flags) {
48
+ if (flags.rows && flags.rowsFile) {
49
+ throw new Error("Provide either --rows or --rows-file, not both.");
50
+ }
51
+ if (flags.rows) {
52
+ const parsed = parseJsonValue(flags.rows, "rows");
53
+ return normalizeRows(parsed);
54
+ }
55
+ if (flags.rowsFile) {
56
+ const absPath = resolve(process.cwd(), flags.rowsFile);
57
+ const content = await readFile(absPath, "utf-8");
58
+ if (absPath.endsWith(".jsonl") || absPath.endsWith(".ndjson")) {
59
+ return parseJsonl(content);
60
+ }
61
+ const parsed = parseJsonValue(content, "rowsFile");
62
+ return normalizeRows(parsed);
63
+ }
64
+ throw new Error("Missing dataset rows. Provide --rows or --rows-file.");
65
+ }
66
+ async function loadSchema(flags, rows) {
67
+ if (flags.schema && flags.schemaFile) {
68
+ throw new Error("Provide either --schema or --schema-file, not both.");
69
+ }
70
+ if (flags.schema) {
71
+ return parseJsonValue(flags.schema, "schema");
72
+ }
73
+ if (flags.schemaFile) {
74
+ return await readJsonFile(flags.schemaFile, "schemaFile");
75
+ }
76
+ return inferSchema(rows);
77
+ }
78
+ function inferSchema(rows) {
79
+ const first = rows[0] ?? {};
80
+ const schema = {};
81
+ for (const [key, value] of Object.entries(first)) {
82
+ if (typeof value === "number") {
83
+ schema[key] = "number";
84
+ } else if (typeof value === "boolean") {
85
+ schema[key] = "boolean";
86
+ } else if (value === null || value === void 0) {
87
+ schema[key] = "null";
88
+ } else {
89
+ schema[key] = "string";
90
+ }
91
+ }
92
+ return { schema };
93
+ }
94
+ function toJson(data, pretty) {
95
+ return JSON.stringify(data, null, pretty ? 2 : 0);
96
+ }
97
+ async function runDatasetCreate(rawArgs) {
98
+ const datasetCli = meow(
99
+ `
100
+ Usage
101
+ $ ekairos dataset create --rows-file rows.json --app-id <id> --admin-token <token>
102
+
103
+ Options
104
+ --app-id InstantDB app id (or INSTANT_APP_ID / NEXT_PUBLIC_INSTANT_APP_ID)
105
+ --admin-token InstantDB admin token (or INSTANT_APP_ADMIN_TOKEN)
106
+ --dataset-id Optional dataset id (default: generated)
107
+ --title Optional dataset title
108
+ --status Dataset status (default: completed)
109
+ --rows JSON array of rows (string)
110
+ --rows-file Path to JSON or JSONL file
111
+ --schema JSON schema object (string)
112
+ --schema-file Path to JSON schema file
113
+ --pretty Pretty-print JSON output
114
+
115
+ Examples
116
+ $ ekairos dataset create --rows-file rows.jsonl --app-id app_x --admin-token tok_y
117
+ $ ekairos dataset create --rows '[{"id":"1","price":10}]' --pretty
118
+ `,
119
+ {
120
+ importMeta: import.meta,
121
+ argv: rawArgs,
122
+ flags: {
123
+ appId: { type: "string" },
124
+ adminToken: { type: "string" },
125
+ datasetId: { type: "string" },
126
+ title: { type: "string" },
127
+ status: { type: "string" },
128
+ rows: { type: "string" },
129
+ rowsFile: { type: "string" },
130
+ schema: { type: "string" },
131
+ schemaFile: { type: "string" },
132
+ pretty: { type: "boolean", default: false }
133
+ }
134
+ }
135
+ );
136
+ const flags = datasetCli.flags;
137
+ const { appId, adminToken } = resolveInstantCredentials(flags);
138
+ if (!appId || !adminToken) {
139
+ console.error(
140
+ toJson(
141
+ {
142
+ ok: false,
143
+ error: "Missing Instant credentials. Provide --app-id and --admin-token (or env vars)."
144
+ },
145
+ flags.pretty
146
+ )
147
+ );
148
+ process.exit(1);
149
+ }
150
+ const rows = await loadRows(flags);
151
+ const schema = await loadSchema(flags, rows);
152
+ const datasetId = flags.datasetId || newId();
153
+ const title = flags.title || `dataset:${datasetId}`;
154
+ const status = flags.status || "completed";
155
+ const db = init({
156
+ appId,
157
+ adminToken,
158
+ schema: datasetDomain.toInstantSchema()
159
+ });
160
+ const service = new DatasetService(db);
161
+ const createResult = await service.createDataset({
162
+ id: datasetId,
163
+ title,
164
+ status: "created",
165
+ schema
166
+ });
167
+ if (!createResult.ok) {
168
+ console.error(toJson({ ok: false, error: createResult.error }, flags.pretty));
169
+ process.exit(1);
170
+ }
171
+ const records = rows.map((row, idx) => ({
172
+ rowContent: row,
173
+ order: idx
174
+ }));
175
+ const addResult = await service.addDatasetRecords({
176
+ datasetId,
177
+ records
178
+ });
179
+ if (!addResult.ok) {
180
+ console.error(toJson({ ok: false, error: addResult.error }, flags.pretty));
181
+ process.exit(1);
182
+ }
183
+ const statusResult = await service.updateDatasetStatus({
184
+ datasetId,
185
+ status,
186
+ calculatedTotalRows: rows.length,
187
+ actualGeneratedRowCount: rows.length
188
+ });
189
+ if (!statusResult.ok) {
190
+ console.error(toJson({ ok: false, error: statusResult.error }, flags.pretty));
191
+ process.exit(1);
192
+ }
193
+ console.log(
194
+ toJson(
195
+ {
196
+ ok: true,
197
+ datasetId,
198
+ title,
199
+ status,
200
+ rowCount: rows.length
201
+ },
202
+ flags.pretty
203
+ )
204
+ );
205
+ }
206
+ async function runDatasetCommand(commandArgs) {
207
+ const [subcommand, ...rest] = commandArgs;
208
+ if (!subcommand || subcommand === "create") {
209
+ await runDatasetCreate(rest);
210
+ return;
211
+ }
212
+ if (subcommand === "help" || subcommand === "--help" || subcommand === "-h") {
213
+ await runDatasetCreate(["--help"]);
214
+ return;
215
+ }
216
+ console.error(
217
+ JSON.stringify(
218
+ { ok: false, error: `Unknown dataset command: ${subcommand}` },
219
+ null,
220
+ 2
221
+ )
222
+ );
223
+ process.exit(1);
224
+ }
225
+ export {
226
+ runDatasetCommand
227
+ };
228
+ //# sourceMappingURL=dataset-6DOS7T3V.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/dataset.ts"],"sourcesContent":["import meow from \"meow\";\nimport { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { init, id as newId } from \"@instantdb/admin\";\nimport { DatasetService, datasetDomain } from \"@ekairos/dataset\";\n\ntype DatasetRows = Array<Record<string, any>>;\n\ntype DatasetCreateFlags = {\n appId?: string;\n adminToken?: string;\n datasetId?: string;\n title?: string;\n status?: string;\n rows?: string;\n rowsFile?: string;\n schema?: string;\n schemaFile?: string;\n pretty?: boolean;\n};\n\nfunction readEnv(name: string): string {\n return String(process.env[name] ?? \"\").trim();\n}\n\nfunction resolveInstantCredentials(flags: DatasetCreateFlags) {\n const appId =\n flags.appId ||\n readEnv(\"INSTANT_APP_ID\") ||\n readEnv(\"NEXT_PUBLIC_INSTANT_APP_ID\");\n const adminToken = flags.adminToken || readEnv(\"INSTANT_APP_ADMIN_TOKEN\");\n return { appId, adminToken };\n}\n\nfunction parseJsonValue(value: string, label: string) {\n try {\n return JSON.parse(value);\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n throw new Error(`${label} must be valid JSON: ${msg}`);\n }\n}\n\nasync function readJsonFile(filePath: string, label: string) {\n const absPath = resolve(process.cwd(), filePath);\n const content = await readFile(absPath, \"utf-8\");\n return parseJsonValue(content, label);\n}\n\nfunction parseJsonl(content: string): DatasetRows {\n const rows: DatasetRows = [];\n const lines = content.split(/\\r?\\n/);\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n rows.push(parseJsonValue(trimmed, \"rowsFile JSONL\"));\n }\n return rows;\n}\n\nfunction normalizeRows(data: any): DatasetRows {\n if (Array.isArray(data)) return data as DatasetRows;\n if (data && typeof data === \"object\" && Array.isArray(data.rows)) {\n return data.rows as DatasetRows;\n }\n throw new Error(\"rows must be a JSON array or an object with a rows[] field.\");\n}\n\nasync function loadRows(flags: DatasetCreateFlags): Promise<DatasetRows> {\n if (flags.rows && flags.rowsFile) {\n throw new Error(\"Provide either --rows or --rows-file, not both.\");\n }\n\n if (flags.rows) {\n const parsed = parseJsonValue(flags.rows, \"rows\");\n return normalizeRows(parsed);\n }\n\n if (flags.rowsFile) {\n const absPath = resolve(process.cwd(), flags.rowsFile);\n const content = await readFile(absPath, \"utf-8\");\n if (absPath.endsWith(\".jsonl\") || absPath.endsWith(\".ndjson\")) {\n return parseJsonl(content);\n }\n const parsed = parseJsonValue(content, \"rowsFile\");\n return normalizeRows(parsed);\n }\n\n throw new Error(\"Missing dataset rows. Provide --rows or --rows-file.\");\n}\n\nasync function loadSchema(flags: DatasetCreateFlags, rows: DatasetRows) {\n if (flags.schema && flags.schemaFile) {\n throw new Error(\"Provide either --schema or --schema-file, not both.\");\n }\n\n if (flags.schema) {\n return parseJsonValue(flags.schema, \"schema\");\n }\n\n if (flags.schemaFile) {\n return await readJsonFile(flags.schemaFile, \"schemaFile\");\n }\n\n return inferSchema(rows);\n}\n\nfunction inferSchema(rows: DatasetRows) {\n const first = rows[0] ?? {};\n const schema: Record<string, string> = {};\n for (const [key, value] of Object.entries(first)) {\n if (typeof value === \"number\") {\n schema[key] = \"number\";\n } else if (typeof value === \"boolean\") {\n schema[key] = \"boolean\";\n } else if (value === null || value === undefined) {\n schema[key] = \"null\";\n } else {\n schema[key] = \"string\";\n }\n }\n return { schema };\n}\n\nfunction toJson(data: any, pretty?: boolean) {\n return JSON.stringify(data, null, pretty ? 2 : 0);\n}\n\nasync function runDatasetCreate(rawArgs: string[]) {\n const datasetCli = meow(\n `\nUsage\n $ ekairos dataset create --rows-file rows.json --app-id <id> --admin-token <token>\n\nOptions\n --app-id InstantDB app id (or INSTANT_APP_ID / NEXT_PUBLIC_INSTANT_APP_ID)\n --admin-token InstantDB admin token (or INSTANT_APP_ADMIN_TOKEN)\n --dataset-id Optional dataset id (default: generated)\n --title Optional dataset title\n --status Dataset status (default: completed)\n --rows JSON array of rows (string)\n --rows-file Path to JSON or JSONL file\n --schema JSON schema object (string)\n --schema-file Path to JSON schema file\n --pretty Pretty-print JSON output\n\nExamples\n $ ekairos dataset create --rows-file rows.jsonl --app-id app_x --admin-token tok_y\n $ ekairos dataset create --rows '[{\"id\":\"1\",\"price\":10}]' --pretty\n`,\n {\n importMeta: import.meta,\n argv: rawArgs,\n flags: {\n appId: { type: \"string\" },\n adminToken: { type: \"string\" },\n datasetId: { type: \"string\" },\n title: { type: \"string\" },\n status: { type: \"string\" },\n rows: { type: \"string\" },\n rowsFile: { type: \"string\" },\n schema: { type: \"string\" },\n schemaFile: { type: \"string\" },\n pretty: { type: \"boolean\", default: false },\n },\n },\n );\n\n const flags = datasetCli.flags as DatasetCreateFlags;\n const { appId, adminToken } = resolveInstantCredentials(flags);\n\n if (!appId || !adminToken) {\n console.error(\n toJson(\n {\n ok: false,\n error:\n \"Missing Instant credentials. Provide --app-id and --admin-token (or env vars).\",\n },\n flags.pretty,\n ),\n );\n process.exit(1);\n }\n\n const rows = await loadRows(flags);\n const schema = await loadSchema(flags, rows);\n const datasetId = flags.datasetId || newId();\n const title = flags.title || `dataset:${datasetId}`;\n const status = flags.status || \"completed\";\n\n const db = init({\n appId,\n adminToken,\n schema: datasetDomain.toInstantSchema(),\n });\n const service = new DatasetService(db as any);\n\n const createResult = await service.createDataset({\n id: datasetId,\n title,\n status: \"created\",\n schema,\n });\n\n if (!createResult.ok) {\n console.error(toJson({ ok: false, error: createResult.error }, flags.pretty));\n process.exit(1);\n }\n\n const records = rows.map((row, idx) => ({\n rowContent: row,\n order: idx,\n }));\n\n const addResult = await service.addDatasetRecords({\n datasetId,\n records,\n });\n\n if (!addResult.ok) {\n console.error(toJson({ ok: false, error: addResult.error }, flags.pretty));\n process.exit(1);\n }\n\n const statusResult = await service.updateDatasetStatus({\n datasetId,\n status,\n calculatedTotalRows: rows.length,\n actualGeneratedRowCount: rows.length,\n });\n\n if (!statusResult.ok) {\n console.error(toJson({ ok: false, error: statusResult.error }, flags.pretty));\n process.exit(1);\n }\n\n console.log(\n toJson(\n {\n ok: true,\n datasetId,\n title,\n status,\n rowCount: rows.length,\n },\n flags.pretty,\n ),\n );\n}\n\nexport async function runDatasetCommand(commandArgs: string[]) {\n const [subcommand, ...rest] = commandArgs;\n if (!subcommand || subcommand === \"create\") {\n await runDatasetCreate(rest);\n return;\n }\n\n if (subcommand === \"help\" || subcommand === \"--help\" || subcommand === \"-h\") {\n await runDatasetCreate([\"--help\"]);\n return;\n }\n\n console.error(\n JSON.stringify(\n { ok: false, error: `Unknown dataset command: ${subcommand}` },\n null,\n 2,\n ),\n );\n process.exit(1);\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/index.js ADDED
@@ -0,0 +1,475 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.tsx
4
+ import { render } from "ink";
5
+ import meow from "meow";
6
+ import { fileURLToPath } from "url";
7
+ import { runCli as runDomainCli } from "@ekairos/domain/cli";
8
+
9
+ // src/app.tsx
10
+ import { useState, useEffect } from "react";
11
+ import { Box, Text, useApp } from "ink";
12
+ import Spinner from "ink-spinner";
13
+ import SelectInput from "ink-select-input";
14
+ import { createRequire } from "module";
15
+
16
+ // src/lib/shadcn.ts
17
+ import fs from "fs-extra";
18
+ import path from "path";
19
+ import { execa } from "execa";
20
+
21
+ // src/lib/config.ts
22
+ var getRegistryUrl = () => {
23
+ if (process.env.EKAIROS_REGISTRY_URL) {
24
+ return process.env.EKAIROS_REGISTRY_URL;
25
+ }
26
+ return "https://registry.ekairos.dev/";
27
+ };
28
+ var REGISTRY_ALIAS = "@ekairos";
29
+
30
+ // src/lib/shadcn.ts
31
+ async function checkShadcnConfig() {
32
+ return fs.pathExists(path.join(process.cwd(), "components.json"));
33
+ }
34
+ async function ensureEkairosRegistry() {
35
+ const configPath = path.join(process.cwd(), "components.json");
36
+ if (!await fs.pathExists(configPath)) return;
37
+ const config = await fs.readJson(configPath);
38
+ if (!config.registries) {
39
+ config.registries = {};
40
+ }
41
+ const rawRegistryUrl = getRegistryUrl();
42
+ const sanitizedUrl = rawRegistryUrl.trim().replace(/\s+/g, "");
43
+ let registryConfigUrl;
44
+ if (sanitizedUrl.includes("{name}")) {
45
+ registryConfigUrl = sanitizedUrl;
46
+ } else {
47
+ const baseUrl = sanitizedUrl.replace(/\/registry\.json$/i, "").replace(/\/+$/, "");
48
+ registryConfigUrl = `${baseUrl}/{name}.json`;
49
+ }
50
+ if (config.registries[REGISTRY_ALIAS] !== registryConfigUrl) {
51
+ config.registries[REGISTRY_ALIAS] = registryConfigUrl;
52
+ await fs.writeJson(configPath, config, { spaces: 2 });
53
+ }
54
+ }
55
+ async function getInstalledComponents() {
56
+ const possiblePaths = [
57
+ "src/components/ekairos",
58
+ "components/ekairos",
59
+ "lib/components/ekairos"
60
+ ];
61
+ for (const p of possiblePaths) {
62
+ const fullPath = path.join(process.cwd(), p);
63
+ if (await fs.pathExists(fullPath)) {
64
+ const files = await fs.readdir(fullPath, { recursive: true });
65
+ const detected = [];
66
+ const fileList = Array.isArray(files) ? files : [];
67
+ if (await fs.pathExists(path.join(fullPath, "agent"))) detected.push("agent");
68
+ return detected;
69
+ }
70
+ }
71
+ return [];
72
+ }
73
+ async function installComponent(componentName) {
74
+ let target = componentName;
75
+ if (!target.startsWith("@") && !target.startsWith("http")) {
76
+ target = `${REGISTRY_ALIAS}/${componentName}`;
77
+ }
78
+ await execa("npx", [
79
+ "--yes",
80
+ "shadcn@latest",
81
+ "add",
82
+ target,
83
+ "-y",
84
+ "--overwrite"
85
+ ], {
86
+ stdio: "inherit"
87
+ // Let the user see shadcn output
88
+ });
89
+ }
90
+ async function initShadcn() {
91
+ await execa("npx", ["--yes", "shadcn@latest", "init"], { stdio: "inherit" });
92
+ }
93
+
94
+ // src/app.tsx
95
+ import { jsx, jsxs } from "react/jsx-runtime";
96
+ var require2 = createRequire(import.meta.url);
97
+ var { version: CLI_VERSION = "dev" } = require2("../package.json");
98
+ var REGISTRY_URL = getRegistryUrl();
99
+ function App() {
100
+ const { exit } = useApp();
101
+ const [state, setState] = useState({
102
+ step: "check-config",
103
+ message: "Checking configuration...",
104
+ installedComponents: []
105
+ });
106
+ useEffect(() => {
107
+ const init = async () => {
108
+ try {
109
+ const hasConfig = await checkShadcnConfig();
110
+ if (!hasConfig) {
111
+ setState((s) => ({ ...s, step: "init-shadcn", message: "components.json not found." }));
112
+ return;
113
+ }
114
+ await runScan();
115
+ } catch (err) {
116
+ setState((s) => ({ ...s, step: "error", error: err instanceof Error ? err.message : "Unknown error" }));
117
+ }
118
+ };
119
+ if (state.step === "check-config") {
120
+ init();
121
+ }
122
+ }, [state.step]);
123
+ const runScan = async () => {
124
+ await ensureEkairosRegistry();
125
+ setState((s) => ({ ...s, step: "check-installed", message: "Scanning installed components..." }));
126
+ const installed = await getInstalledComponents();
127
+ setState({
128
+ step: "prompt-action",
129
+ message: installed.length > 0 ? `Found ${installed.length} Ekairos components.` : "No Ekairos components found.",
130
+ installedComponents: installed,
131
+ error: void 0
132
+ });
133
+ };
134
+ const handleSelect = async (item) => {
135
+ if (item.value === "init-shadcn") {
136
+ try {
137
+ setState((s) => ({ ...s, message: "Initializing shadcn..." }));
138
+ await initShadcn();
139
+ setState((s) => ({ ...s, step: "check-config" }));
140
+ } catch (err) {
141
+ setState((s) => ({ ...s, step: "error", error: "Failed to initialize shadcn." }));
142
+ }
143
+ } else if (item.value === "update-all" || item.value === "install-essentials") {
144
+ setState((s) => ({ ...s, step: "installing", message: "Running shadcn..." }));
145
+ try {
146
+ const componentsToInstall = item.value === "update-all" ? state.installedComponents : ["agent"];
147
+ const targets = [...new Set(componentsToInstall)].map(
148
+ (c) => c.startsWith("@ekairos/") ? c : `@ekairos/${c}`
149
+ );
150
+ if (targets.length === 0) {
151
+ targets.push("@ekairos/agent");
152
+ }
153
+ for (const component of targets) {
154
+ setState((s) => ({ ...s, message: `Installing ${component}...` }));
155
+ await installComponent(component);
156
+ }
157
+ setState((s) => ({ ...s, step: "success", message: "All operations completed successfully!" }));
158
+ setTimeout(() => exit(), 2e3);
159
+ } catch (err) {
160
+ setState((s) => ({ ...s, step: "error", error: err instanceof Error ? err.message : "Installation failed" }));
161
+ }
162
+ } else if (item.value === "exit") {
163
+ exit();
164
+ }
165
+ };
166
+ const options = state.step === "init-shadcn" ? [
167
+ { label: "Initialize shadcn project", value: "init-shadcn" },
168
+ { label: "Exit", value: "exit" }
169
+ ] : state.installedComponents.length > 0 ? [
170
+ { label: "Update all components", value: "update-all" },
171
+ { label: "Exit", value: "exit" }
172
+ ] : [
173
+ { label: "Install Ekairos Essentials (Agent)", value: "install-essentials" },
174
+ { label: "Exit", value: "exit" }
175
+ ];
176
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", padding: 1, children: [
177
+ /* @__PURE__ */ jsxs(Box, { marginBottom: 1, flexDirection: "column", children: [
178
+ /* @__PURE__ */ jsxs(Text, { bold: true, color: "cyan", children: [
179
+ "Ekairos CLI v",
180
+ CLI_VERSION
181
+ ] }),
182
+ /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
183
+ "using registry: ",
184
+ REGISTRY_URL
185
+ ] })
186
+ ] }),
187
+ (state.step === "check-config" || state.step === "check-installed" || state.step === "installing") && /* @__PURE__ */ jsxs(Box, { children: [
188
+ /* @__PURE__ */ jsxs(Text, { color: "green", children: [
189
+ /* @__PURE__ */ jsx(Spinner, { type: "dots" }),
190
+ " "
191
+ ] }),
192
+ /* @__PURE__ */ jsx(Text, { children: state.message })
193
+ ] }),
194
+ (state.step === "prompt-action" || state.step === "init-shadcn") && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
195
+ /* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { children: state.message }) }),
196
+ /* @__PURE__ */ jsx(Text, { children: "What would you like to do?" }),
197
+ /* @__PURE__ */ jsx(SelectInput, { items: options, onSelect: handleSelect })
198
+ ] }),
199
+ state.step === "success" && /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { color: "green", children: [
200
+ "\u2714 ",
201
+ state.message
202
+ ] }) }),
203
+ state.step === "error" && /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { color: "red", children: [
204
+ "\u2716 Error: ",
205
+ state.error
206
+ ] }) })
207
+ ] });
208
+ }
209
+
210
+ // src/lib/session.ts
211
+ import fs2 from "fs-extra";
212
+ import path2 from "path";
213
+ import os from "os";
214
+ var TMP_DIR = path2.join(os.tmpdir(), "ekairos-package-cli-sessions");
215
+ async function createSession() {
216
+ const sessionId = crypto.randomUUID();
217
+ const state = {
218
+ sessionId,
219
+ step: "INIT",
220
+ installedComponents: []
221
+ };
222
+ await saveSession(state);
223
+ return state;
224
+ }
225
+ async function loadSession(sessionId) {
226
+ const filePath = path2.join(TMP_DIR, `${sessionId}.json`);
227
+ if (!await fs2.pathExists(filePath)) return null;
228
+ return fs2.readJson(filePath);
229
+ }
230
+ async function saveSession(state) {
231
+ await fs2.ensureDir(TMP_DIR);
232
+ const filePath = path2.join(TMP_DIR, `${state.sessionId}.json`);
233
+ await fs2.writeJson(filePath, state, { spaces: 2 });
234
+ }
235
+ async function deleteSession(sessionId) {
236
+ const filePath = path2.join(TMP_DIR, `${sessionId}.json`);
237
+ await fs2.remove(filePath);
238
+ }
239
+ async function processAsyncStep(state, input) {
240
+ if (state.step === "INIT") {
241
+ const hasConfig = await checkShadcnConfig();
242
+ if (!hasConfig) {
243
+ state.step = "ERROR";
244
+ state.error = "components.json not found";
245
+ state.message = "Configuration missing. Action required.";
246
+ await saveSession(state);
247
+ return {
248
+ sessionId: state.sessionId,
249
+ step: "CONFIG_MISSING",
250
+ // Custom step name for the output
251
+ message: state.message,
252
+ inputSchema: {
253
+ type: "object",
254
+ properties: {
255
+ action: { type: "string", enum: ["init-shadcn", "exit"] }
256
+ },
257
+ required: ["action"]
258
+ }
259
+ };
260
+ }
261
+ await ensureEkairosRegistry();
262
+ state.installedComponents = await getInstalledComponents();
263
+ state.step = "MENU";
264
+ state.message = `Found ${state.installedComponents.length} components.`;
265
+ await saveSession(state);
266
+ return {
267
+ sessionId: state.sessionId,
268
+ step: "MENU",
269
+ message: state.message,
270
+ context: { installedComponents: state.installedComponents },
271
+ inputSchema: {
272
+ type: "object",
273
+ properties: {
274
+ action: { type: "string", enum: ["update-all", "install-essentials", "exit"] }
275
+ },
276
+ required: ["action"]
277
+ }
278
+ };
279
+ }
280
+ if (input && input.action === "exit") {
281
+ await deleteSession(state.sessionId);
282
+ return {
283
+ sessionId: state.sessionId,
284
+ step: "TERMINATED",
285
+ message: "Session ended by user."
286
+ };
287
+ }
288
+ if (input && input.action === "init-shadcn") {
289
+ await initShadcn();
290
+ state.step = "INIT";
291
+ state.error = void 0;
292
+ return processAsyncStep(state, null);
293
+ }
294
+ if (state.step === "MENU" && input) {
295
+ if (input.action === "update-all" || input.action === "install-essentials") {
296
+ state.step = "INSTALLING";
297
+ await saveSession(state);
298
+ const componentsToInstall = input.action === "update-all" ? state.installedComponents : ["agent"];
299
+ let targets = [...new Set(componentsToInstall)].map(
300
+ (c) => c.startsWith("@ekairos/") ? c : `@ekairos/${c}`
301
+ );
302
+ if (targets.length === 0) targets.push("@ekairos/agent");
303
+ for (const component of targets) {
304
+ await installComponent(component);
305
+ }
306
+ state.step = "SUCCESS";
307
+ state.message = "Operations completed successfully.";
308
+ await deleteSession(state.sessionId);
309
+ return {
310
+ sessionId: state.sessionId,
311
+ step: "SUCCESS",
312
+ message: state.message
313
+ };
314
+ }
315
+ }
316
+ return {
317
+ sessionId: state.sessionId,
318
+ step: state.step,
319
+ message: state.message,
320
+ error: "Invalid state or input for current step."
321
+ };
322
+ }
323
+
324
+ // src/index.tsx
325
+ import { jsx as jsx2 } from "react/jsx-runtime";
326
+ var VALID_ACTIONS = /* @__PURE__ */ new Set(["init-shadcn", "update-all", "install-essentials", "exit"]);
327
+ var CLI_SKILL_PATH = fileURLToPath(new URL("../SKILL.md", import.meta.url));
328
+ var DOMAIN_SKILL_PATH = fileURLToPath(new URL("../../domain/SKILL.md", import.meta.url));
329
+ var rawArgv = process.argv.slice(2);
330
+ var cli = meow(
331
+ `
332
+ Usage
333
+ $ ekairos
334
+ $ ekairos create-app --demo
335
+ $ ekairos create-app <dir> --next --install --smoke --json
336
+ $ ekairos domain query "<json5>" --baseUrl=<url> --admin
337
+ $ ekairos dataset <command> [options]
338
+
339
+ Skills
340
+ CLI skill: ${CLI_SKILL_PATH}
341
+ Domain skill: ${DOMAIN_SKILL_PATH}
342
+
343
+ Options
344
+ --async Run in async/session mode
345
+ --session Session ID for continuing an async session
346
+ --input JSON input for the session step
347
+ --action Convenience flag for async actions (update-all, install-essentials, init-shadcn, exit)
348
+
349
+ Examples
350
+ $ ekairos --async
351
+ $ ekairos create-app --demo
352
+ $ ekairos create-app ./supply-chain --next --install --smoke --json
353
+ $ ekairos domain query "{ procurement_order: { supplier: {} } }" --baseUrl=http://localhost:3000 --admin
354
+ $ ekairos --session <uuid> --input '{"action": "update-all"}'
355
+ $ ekairos dataset create --rows-file rows.jsonl --app-id <id> --admin-token <token>
356
+ `,
357
+ {
358
+ importMeta: import.meta,
359
+ flags: {
360
+ async: {
361
+ type: "boolean"
362
+ },
363
+ session: {
364
+ type: "string"
365
+ },
366
+ input: {
367
+ type: "string"
368
+ },
369
+ action: {
370
+ type: "string"
371
+ },
372
+ dev: {
373
+ type: "boolean",
374
+ default: false
375
+ }
376
+ }
377
+ }
378
+ );
379
+ var [command, ...commandArgs] = cli.input;
380
+ async function runAddCommand(componentTarget) {
381
+ if (!componentTarget) {
382
+ console.error("Please specify a component, e.g. ekairos add @ekairos/agent");
383
+ process.exit(1);
384
+ }
385
+ const hasConfig = await checkShadcnConfig();
386
+ if (!hasConfig) {
387
+ console.error('components.json not found. Run "shadcn init" first.');
388
+ process.exit(1);
389
+ }
390
+ try {
391
+ await ensureEkairosRegistry();
392
+ await installComponent(componentTarget);
393
+ console.log(`\u2714 Installed ${componentTarget}`);
394
+ process.exit(0);
395
+ } catch (error) {
396
+ console.error(error instanceof Error ? error.message : "Installation failed");
397
+ process.exit(1);
398
+ }
399
+ }
400
+ async function run() {
401
+ if (cli.flags.dev) {
402
+ process.env.EKAIROS_REGISTRY_URL = "http://localhost:3030/";
403
+ console.log("Using local registry: http://localhost:3030/");
404
+ }
405
+ if (command === "add") {
406
+ await runAddCommand(commandArgs[0]);
407
+ return;
408
+ }
409
+ if (command === "create-app") {
410
+ const code = await runDomainCli(["create-app", ...rawArgv.slice(1)]);
411
+ process.exit(code);
412
+ }
413
+ if (command === "domain") {
414
+ if (commandArgs[0] === "create-app") {
415
+ console.error("Use `ekairos create-app ...` for app creation.");
416
+ process.exit(1);
417
+ }
418
+ const code = await runDomainCli(rawArgv.slice(1));
419
+ process.exit(code);
420
+ }
421
+ if (command === "dataset") {
422
+ const { runDatasetCommand } = await import("./dataset-6DOS7T3V.js");
423
+ await runDatasetCommand(commandArgs);
424
+ return;
425
+ }
426
+ if (cli.flags.async || cli.flags.session) {
427
+ try {
428
+ let state;
429
+ let input = null;
430
+ const tryParseActionString = (value) => {
431
+ if (!value) return null;
432
+ const trimmed = value.trim();
433
+ return VALID_ACTIONS.has(trimmed) ? { action: trimmed } : null;
434
+ };
435
+ if (cli.flags.input) {
436
+ try {
437
+ input = JSON.parse(cli.flags.input);
438
+ } catch (e) {
439
+ input = tryParseActionString(cli.flags.input);
440
+ if (!input) {
441
+ console.error(JSON.stringify({ error: "Invalid JSON input" }));
442
+ process.exit(1);
443
+ }
444
+ }
445
+ }
446
+ if (!input && cli.flags.action) {
447
+ const parsed = tryParseActionString(cli.flags.action);
448
+ if (!parsed) {
449
+ console.error(JSON.stringify({ error: "Invalid action value" }));
450
+ process.exit(1);
451
+ }
452
+ input = parsed;
453
+ }
454
+ if (cli.flags.session) {
455
+ state = await loadSession(cli.flags.session);
456
+ if (!state) {
457
+ console.error(JSON.stringify({ error: "Session not found or expired" }));
458
+ process.exit(1);
459
+ }
460
+ } else {
461
+ state = await createSession();
462
+ }
463
+ const response = await processAsyncStep(state, input);
464
+ console.log(JSON.stringify(response, null, 2));
465
+ process.exit(0);
466
+ } catch (error) {
467
+ console.error(JSON.stringify({ error: error instanceof Error ? error.message : "Unknown error" }));
468
+ process.exit(1);
469
+ }
470
+ } else {
471
+ render(/* @__PURE__ */ jsx2(App, {}));
472
+ }
473
+ }
474
+ run();
475
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.tsx","../src/app.tsx","../src/lib/shadcn.ts","../src/lib/config.ts","../src/lib/session.ts"],"sourcesContent":["import React from 'react';\nimport { render } from 'ink';\nimport meow from 'meow';\nimport { fileURLToPath } from 'node:url';\nimport { runCli as runDomainCli } from '@ekairos/domain/cli';\nimport App from './app.js';\nimport { createSession, loadSession, processAsyncStep } from './lib/session.js';\nimport { checkShadcnConfig, ensureEkairosRegistry, installComponent } from './lib/shadcn.js';\n\nconst VALID_ACTIONS = new Set(['init-shadcn', 'update-all', 'install-essentials', 'exit']);\nconst CLI_SKILL_PATH = fileURLToPath(new URL('../SKILL.md', import.meta.url));\nconst DOMAIN_SKILL_PATH = fileURLToPath(new URL('../../domain/SKILL.md', import.meta.url));\nconst rawArgv = process.argv.slice(2);\n\nconst cli = meow(\n\t`\n\tUsage\n\t $ ekairos\n\t $ ekairos create-app --demo\n\t $ ekairos create-app <dir> --next --install --smoke --json\n\t $ ekairos domain query \"<json5>\" --baseUrl=<url> --admin\n\t $ ekairos dataset <command> [options]\n\n\tSkills\n\t CLI skill: ${CLI_SKILL_PATH}\n\t Domain skill: ${DOMAIN_SKILL_PATH}\n\n\tOptions\n\t\t--async Run in async/session mode\n\t\t--session Session ID for continuing an async session\n\t\t--input JSON input for the session step\n\t\t--action Convenience flag for async actions (update-all, install-essentials, init-shadcn, exit)\n\n\tExamples\n\t $ ekairos --async\n\t $ ekairos create-app --demo\n\t $ ekairos create-app ./supply-chain --next --install --smoke --json\n\t $ ekairos domain query \"{ procurement_order: { supplier: {} } }\" --baseUrl=http://localhost:3000 --admin\n\t $ ekairos --session <uuid> --input '{\"action\": \"update-all\"}'\n\t $ ekairos dataset create --rows-file rows.jsonl --app-id <id> --admin-token <token>\n`,\n\t{\n\t\timportMeta: import.meta,\n\t\tflags: {\n\t\t\tasync: {\n\t\t\t\ttype: 'boolean',\n\t\t\t},\n\t\t\tsession: {\n\t\t\t\ttype: 'string',\n\t\t\t},\n\t\t\tinput: {\n\t\t\t\ttype: 'string',\n\t\t\t},\n\t\t\taction: {\n\t\t\t\ttype: 'string',\n\t\t\t},\n\t\t\tdev: {\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: false,\n\t\t\t},\n\t\t},\n\t},\n);\n\nconst [command, ...commandArgs] = cli.input;\n\nasync function runAddCommand(componentTarget?: string) {\n\tif (!componentTarget) {\n\t\tconsole.error('Please specify a component, e.g. ekairos add @ekairos/agent');\n\t\tprocess.exit(1);\n\t}\n\n\tconst hasConfig = await checkShadcnConfig();\n\tif (!hasConfig) {\n\t\tconsole.error('components.json not found. Run \"shadcn init\" first.');\n\t\tprocess.exit(1);\n\t}\n\n\ttry {\n\t\tawait ensureEkairosRegistry();\n\t\tawait installComponent(componentTarget);\n\t\tconsole.log(`✔ Installed ${componentTarget}`);\n\t\tprocess.exit(0);\n\t} catch (error) {\n\t\tconsole.error(error instanceof Error ? error.message : 'Installation failed');\n\t\tprocess.exit(1);\n\t}\n}\n\nasync function run() {\n\tif (cli.flags.dev) {\n\t\tprocess.env.EKAIROS_REGISTRY_URL = 'http://localhost:3030/';\n\t\tconsole.log('Using local registry: http://localhost:3030/');\n\t}\n\n\tif (command === 'add') {\n\t\tawait runAddCommand(commandArgs[0]);\n\t\treturn;\n\t}\n\n\tif (command === 'create-app') {\n\t\tconst code = await runDomainCli(['create-app', ...rawArgv.slice(1)]);\n\t\tprocess.exit(code);\n\t}\n\n\tif (command === 'domain') {\n\t\tif (commandArgs[0] === 'create-app') {\n\t\t\tconsole.error('Use `ekairos create-app ...` for app creation.');\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tconst code = await runDomainCli(rawArgv.slice(1));\n\t\tprocess.exit(code);\n\t}\n\n\tif (command === 'dataset') {\n\t\tconst { runDatasetCommand } = await import('./lib/dataset.js');\n\t\tawait runDatasetCommand(commandArgs);\n\t\treturn;\n\t}\n\n\tif (cli.flags.async || cli.flags.session) {\n\t\ttry {\n\t\t\tlet state;\n\t\t\tlet input = null;\n\n\t\t\tconst tryParseActionString = (value: string | undefined) => {\n\t\t\t\tif (!value) return null;\n\t\t\t\tconst trimmed = value.trim();\n\t\t\t\treturn VALID_ACTIONS.has(trimmed) ? { action: trimmed } : null;\n\t\t\t};\n\n\t\t\tif (cli.flags.input) {\n\t\t\t\ttry {\n\t\t\t\t\tinput = JSON.parse(cli.flags.input);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tinput = tryParseActionString(cli.flags.input);\n\t\t\t\t\tif (!input) {\n\t\t\t\t\t\tconsole.error(JSON.stringify({ error: 'Invalid JSON input' }));\n\t\t\t\t\t\tprocess.exit(1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!input && cli.flags.action) {\n\t\t\t\tconst parsed = tryParseActionString(cli.flags.action);\n\t\t\t\tif (!parsed) {\n\t\t\t\t\tconsole.error(JSON.stringify({ error: 'Invalid action value' }));\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tinput = parsed;\n\t\t\t}\n\n\t\t\tif (cli.flags.session) {\n\t\t\t\tstate = await loadSession(cli.flags.session);\n\t\t\t\tif (!state) {\n\t\t\t\t\tconsole.error(JSON.stringify({ error: 'Session not found or expired' }));\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// New session\n\t\t\t\tstate = await createSession();\n\t\t\t}\n\n\t\t\tconst response = await processAsyncStep(state!, input);\n\t\t\tconsole.log(JSON.stringify(response, null, 2));\n\t\t\tprocess.exit(0);\n\n\t\t} catch (error) {\n\t\t\tconsole.error(JSON.stringify({ error: error instanceof Error ? error.message : 'Unknown error' }));\n\t\t\tprocess.exit(1);\n\t\t}\n\t} else {\n\t\t// Interactive Mode\n\t\trender(<App />);\n\t}\n}\n\nrun();\n","import React, { useState, useEffect } from 'react';\nimport { Box, Text, useApp } from 'ink';\nimport Spinner from 'ink-spinner';\nimport SelectInput from 'ink-select-input';\nimport { createRequire } from 'module';\nimport { checkShadcnConfig, ensureEkairosRegistry, getInstalledComponents, installComponent, initShadcn } from './lib/shadcn.js';\nimport { getRegistryUrl } from './lib/config.js';\n\nconst require = createRequire(import.meta.url);\nconst { version: CLI_VERSION = 'dev' } = require('../package.json') as { version?: string };\n\nconst REGISTRY_URL = getRegistryUrl();\n\ntype Step = 'check-config' | 'init-shadcn' | 'check-installed' | 'prompt-action' | 'installing' | 'success' | 'error';\n\ninterface AppState {\n step: Step;\n message: string;\n installedComponents: string[];\n error?: string;\n}\n\nexport default function App() {\n const { exit } = useApp();\n const [state, setState] = useState<AppState>({\n step: 'check-config',\n message: 'Checking configuration...',\n installedComponents: []\n });\n\n useEffect(() => {\n const init = async () => {\n try {\n // 1. Check Shadcn Config\n const hasConfig = await checkShadcnConfig();\n if (!hasConfig) {\n // Prompt for init\n setState(s => ({ ...s, step: 'init-shadcn', message: 'components.json not found.' }));\n return;\n }\n\n await runScan();\n\n } catch (err) {\n setState(s => ({ ...s, step: 'error', error: err instanceof Error ? err.message : 'Unknown error' }));\n }\n };\n\n if (state.step === 'check-config') {\n init();\n }\n }, [state.step]); // Dependency on step to retry after init\n\n const runScan = async () => {\n // 2. Ensure Registry Config\n await ensureEkairosRegistry();\n\n // 3. Check Installed Components\n setState(s => ({ ...s, step: 'check-installed', message: 'Scanning installed components...' }));\n const installed = await getInstalledComponents();\n \n setState({\n step: 'prompt-action',\n message: installed.length > 0 \n ? `Found ${installed.length} Ekairos components.` \n : 'No Ekairos components found.',\n installedComponents: installed,\n error: undefined\n });\n };\n\n const handleSelect = async (item: { value: string }) => {\n if (item.value === 'init-shadcn') {\n try {\n setState(s => ({ ...s, message: 'Initializing shadcn...' }));\n await initShadcn();\n // After init, check again\n setState(s => ({ ...s, step: 'check-config' }));\n } catch (err) {\n setState(s => ({ ...s, step: 'error', error: 'Failed to initialize shadcn.' }));\n }\n } else if (item.value === 'update-all' || item.value === 'install-essentials') {\n\n setState(s => ({ ...s, step: 'installing', message: 'Running shadcn...' }));\n \n try {\n const componentsToInstall = item.value === 'update-all' \n ? state.installedComponents \n : ['agent']; // Default Ekairos agent bundle from registry\n\n // Dedup and ensure prefix\n const targets = [...new Set(componentsToInstall)].map(c => \n c.startsWith('@ekairos/') ? c : `@ekairos/${c}`\n );\n\n if (targets.length === 0) {\n // Fallback if update-all called but nothing detected, force main agent bundle\n targets.push('@ekairos/agent');\n }\n\n for (const component of targets) {\n setState(s => ({ ...s, message: `Installing ${component}...` }));\n await installComponent(component);\n }\n\n setState(s => ({ ...s, step: 'success', message: 'All operations completed successfully!' }));\n setTimeout(() => exit(), 2000);\n\n } catch (err) {\n setState(s => ({ ...s, step: 'error', error: err instanceof Error ? err.message : 'Installation failed' }));\n }\n } else if (item.value === 'exit') {\n exit();\n }\n };\n\n const options = state.step === 'init-shadcn'\n ? [\n { label: 'Initialize shadcn project', value: 'init-shadcn' },\n { label: 'Exit', value: 'exit' }\n ]\n : state.installedComponents.length > 0\n ? [\n { label: 'Update all components', value: 'update-all' },\n { label: 'Exit', value: 'exit' }\n ]\n : [\n { label: 'Install Ekairos Essentials (Agent)', value: 'install-essentials' },\n { label: 'Exit', value: 'exit' }\n ];\n\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Box marginBottom={1} flexDirection=\"column\">\n <Text bold color=\"cyan\">Ekairos CLI v{CLI_VERSION}</Text>\n <Text color=\"gray\">using registry: {REGISTRY_URL}</Text>\n </Box>\n\n {(state.step === 'check-config' || state.step === 'check-installed' || state.step === 'installing') && (\n <Box>\n <Text color=\"green\"><Spinner type=\"dots\" /> </Text>\n <Text>{state.message}</Text>\n </Box>\n )}\n\n {(state.step === 'prompt-action' || state.step === 'init-shadcn') && (\n <Box flexDirection=\"column\">\n <Box marginBottom={1}>\n <Text>{state.message}</Text>\n </Box>\n <Text>What would you like to do?</Text>\n <SelectInput items={options} onSelect={handleSelect} />\n </Box>\n )}\n\n {state.step === 'success' && (\n <Box>\n <Text color=\"green\">✔ {state.message}</Text>\n </Box>\n )}\n\n {state.step === 'error' && (\n <Box>\n <Text color=\"red\">✖ Error: {state.error}</Text>\n </Box>\n )}\n </Box>\n );\n}\n\n","import fs from 'fs-extra';\nimport path from 'path';\nimport { execa } from 'execa';\nimport { REGISTRY_ALIAS, getRegistryUrl } from './config.js';\n\n// Check if components.json exists in CWD\nexport async function checkShadcnConfig(): Promise<boolean> {\n return fs.pathExists(path.join(process.cwd(), 'components.json'));\n}\n\n// Ensure @ekairos registry is configured in components.json\nexport async function ensureEkairosRegistry() {\n const configPath = path.join(process.cwd(), 'components.json');\n if (!await fs.pathExists(configPath)) return;\n\n const config = await fs.readJson(configPath);\n \n if (!config.registries) {\n config.registries = {};\n }\n\n const rawRegistryUrl = getRegistryUrl();\n const sanitizedUrl = rawRegistryUrl.trim().replace(/\\s+/g, '');\n\n let registryConfigUrl: string;\n if (sanitizedUrl.includes('{name}')) {\n registryConfigUrl = sanitizedUrl;\n } else {\n const baseUrl = sanitizedUrl\n .replace(/\\/registry\\.json$/i, '')\n .replace(/\\/+$/, '');\n registryConfigUrl = `${baseUrl}/{name}.json`;\n }\n\n if (config.registries[REGISTRY_ALIAS] !== registryConfigUrl) {\n config.registries[REGISTRY_ALIAS] = registryConfigUrl;\n await fs.writeJson(configPath, config, { spaces: 2 });\n }\n}\n\n// Scan components to see what is installed\nexport async function getInstalledComponents(): Promise<string[]> {\n // Logic: Check src/components/ekairos folder? \n // Or check components.json aliases? \n // A simple robust way is checking the filesystem based on the alias.\n \n // Assuming default alias @/components\n // We can read components.json to find the resolved path for \"components\" alias if needed,\n // but searching for \"src/components/ekairos\" is a safe 80/20 bet for this project structure.\n \n const possiblePaths = [\n 'src/components/ekairos',\n 'components/ekairos',\n 'lib/components/ekairos'\n ];\n\n for (const p of possiblePaths) {\n const fullPath = path.join(process.cwd(), p);\n if (await fs.pathExists(fullPath)) {\n // Read directories/files in there\n // This is a heuristic. A folder \"agent\" means the main Ekairos Agent bundle is likely installed\n // Ideally we track this in a manifest, but we don't have one yet.\n // So we will just return detected component names based on files.\n \n // For simplicity in v1, we just return a single canonical component name\n const files = await fs.readdir(fullPath, { recursive: true });\n \n // If we find 'agent', we assume 'agent' as the installed Ekairos bundle\n // This maps directly to the lower-case registry component name.\n \n const detected: string[] = [];\n const fileList = Array.isArray(files) ? files : []; // readdir recursive returns string[] in node 20+? wait fs-extra might differ.\n \n // fs-extra readdir is standard. recursive not supported in older node with string, but let's assume standard recursive or walk.\n // Let's stick to checking specific known folders for v1.\n \n if (await fs.pathExists(path.join(fullPath, 'agent'))) detected.push('agent');\n // Add more detections here as registry grows\n \n return detected;\n }\n }\n \n return [];\n}\n\nexport async function installComponent(componentName: string) {\n // Run shadcn add\n // npx --yes shadcn@latest add @ekairos/name -y --overwrite\n \n // Ensure component has prefix if it's a known component without one\n // But for now, we assume input is correct or handled by caller.\n // However, if we are using namespaces, we should prefer the namespaced format.\n \n let target = componentName;\n if (!target.startsWith('@') && !target.startsWith('http')) {\n target = `${REGISTRY_ALIAS}/${componentName}`;\n }\n\n await execa('npx', [\n '--yes',\n 'shadcn@latest', \n 'add', \n target, \n '-y', \n '--overwrite'\n ], {\n stdio: 'inherit' // Let the user see shadcn output\n });\n}\n\nexport async function initShadcn() {\n await execa('npx', ['--yes', 'shadcn@latest', 'init'], { stdio: 'inherit' });\n}\n\n","export const getRegistryUrl = () => {\n // Allow override for local testing / staging\n if (process.env.EKAIROS_REGISTRY_URL) {\n return process.env.EKAIROS_REGISTRY_URL;\n }\n // Default production URL (canonical base)\n return \"https://registry.ekairos.dev/\";\n};\n\nexport const REGISTRY_ALIAS = \"@ekairos\";\n\n\n","import fs from 'fs-extra';\nimport path from 'path';\nimport os from 'os';\nimport { checkShadcnConfig, ensureEkairosRegistry, getInstalledComponents, initShadcn, installComponent } from './shadcn.js';\n\nexport interface SessionState {\n sessionId: string;\n step: 'INIT' | 'MENU' | 'INSTALLING' | 'SUCCESS' | 'ERROR';\n installedComponents: string[];\n message?: string;\n error?: string;\n}\n\nconst TMP_DIR = path.join(os.tmpdir(), 'ekairos-package-cli-sessions');\n\nexport async function createSession(): Promise<SessionState> {\n const sessionId = crypto.randomUUID();\n const state: SessionState = {\n sessionId,\n step: 'INIT',\n installedComponents: []\n };\n await saveSession(state);\n return state;\n}\n\nexport async function loadSession(sessionId: string): Promise<SessionState | null> {\n const filePath = path.join(TMP_DIR, `${sessionId}.json`);\n if (!await fs.pathExists(filePath)) return null;\n return fs.readJson(filePath);\n}\n\nexport async function saveSession(state: SessionState) {\n await fs.ensureDir(TMP_DIR);\n const filePath = path.join(TMP_DIR, `${state.sessionId}.json`);\n await fs.writeJson(filePath, state, { spaces: 2 });\n}\n\nexport async function deleteSession(sessionId: string) {\n const filePath = path.join(TMP_DIR, `${sessionId}.json`);\n await fs.remove(filePath);\n}\n\nexport interface AsyncResponse {\n sessionId: string;\n step: string;\n message?: string;\n error?: string;\n inputSchema?: object;\n context?: any;\n}\n\nexport async function processAsyncStep(state: SessionState, input: any): Promise<AsyncResponse> {\n // State Machine Logic\n \n // 1. INIT -> Check Config -> MENU or ERROR_CONFIG\n if (state.step === 'INIT') {\n const hasConfig = await checkShadcnConfig();\n if (!hasConfig) {\n state.step = 'ERROR'; \n // We treat config missing as a special state that allows input, but let's map it to MENU-like behavior\n // Or we can just handle it here.\n // Let's define a sub-step or just reuse steps.\n // Simplified: If no config, we return a state waiting for 'init' action.\n state.error = 'components.json not found';\n state.message = 'Configuration missing. Action required.';\n \n await saveSession(state);\n return {\n sessionId: state.sessionId,\n step: 'CONFIG_MISSING', // Custom step name for the output\n message: state.message,\n inputSchema: {\n type: 'object',\n properties: {\n action: { type: 'string', enum: ['init-shadcn', 'exit'] }\n },\n required: ['action']\n }\n };\n }\n\n // If config exists, ensure registry and scan\n await ensureEkairosRegistry();\n state.installedComponents = await getInstalledComponents();\n state.step = 'MENU';\n state.message = `Found ${state.installedComponents.length} components.`;\n \n await saveSession(state);\n return {\n sessionId: state.sessionId,\n step: 'MENU',\n message: state.message,\n context: { installedComponents: state.installedComponents },\n inputSchema: {\n type: 'object',\n properties: {\n action: { type: 'string', enum: ['update-all', 'install-essentials', 'exit'] }\n },\n required: ['action']\n }\n };\n }\n\n // 2. Handle Inputs based on current step\n if (input && input.action === 'exit') {\n await deleteSession(state.sessionId);\n return {\n sessionId: state.sessionId,\n step: 'TERMINATED',\n message: 'Session ended by user.'\n };\n }\n\n // Handle CONFIG_MISSING logic (simulated via state check)\n // If we are in a state where config was missing, we expect 'init-shadcn'\n // But since we persisted 'ERROR' step, let's check if input handles it.\n // To make it clean, let's rely on input action primarily if valid.\n\n if (input && input.action === 'init-shadcn') {\n await initShadcn();\n // Reset to INIT to re-check\n state.step = 'INIT';\n state.error = undefined;\n // Recursively call process to advance\n return processAsyncStep(state, null);\n }\n\n if (state.step === 'MENU' && input) {\n if (input.action === 'update-all' || input.action === 'install-essentials') {\n state.step = 'INSTALLING';\n await saveSession(state);\n \n // Perform installation\n const componentsToInstall = input.action === 'update-all' \n ? state.installedComponents \n : ['agent'];\n\n let targets = [...new Set(componentsToInstall)].map(c => \n c.startsWith('@ekairos/') ? c : `@ekairos/${c}`\n );\n\n if (targets.length === 0) targets.push('@ekairos/agent');\n\n for (const component of targets) {\n await installComponent(component);\n }\n\n state.step = 'SUCCESS';\n state.message = 'Operations completed successfully.';\n await deleteSession(state.sessionId); // Done\n\n return {\n sessionId: state.sessionId,\n step: 'SUCCESS',\n message: state.message\n };\n }\n }\n \n // Default fallback if state didn't advance or input invalid\n return {\n sessionId: state.sessionId,\n step: state.step,\n message: state.message,\n error: 'Invalid state or input for current step.'\n };\n}\n\n\n"],"mappings":"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","names":["require","fs","path","path","fs","jsx"]}
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@ekairos/cli",
3
+ "version": "1.22.40-beta.development.0",
4
+ "description": "CLI for Ekairos components",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "default": "./dist/index.js"
13
+ }
14
+ },
15
+ "bin": {
16
+ "ekairos": "./dist/index.js"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "SKILL.md",
21
+ "README.md"
22
+ ],
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "scripts": {
27
+ "build": "tsup",
28
+ "dev": "tsup --watch",
29
+ "start": "node dist/index.js",
30
+ "typecheck": "tsc --noEmit"
31
+ },
32
+ "keywords": [
33
+ "cli",
34
+ "ink",
35
+ "ekairos",
36
+ "shadcn"
37
+ ],
38
+ "dependencies": {
39
+ "@ekairos/dataset": "^1.22.40-beta.development.0",
40
+ "@ekairos/domain": "^1.22.40-beta.development.0",
41
+ "@instantdb/admin": "0.22.126",
42
+ "chalk": "^5.3.0",
43
+ "execa": "^8.0.0",
44
+ "fs-extra": "^11.2.0",
45
+ "ink": "^5.0.0",
46
+ "ink-select-input": "^6.0.0",
47
+ "ink-spinner": "^5.0.0",
48
+ "ink-text-input": "^6.0.0",
49
+ "meow": "^13.2.0",
50
+ "node-fetch": "^3.3.2",
51
+ "react": "^18.2.0",
52
+ "zod": "^3.22.4"
53
+ },
54
+ "devDependencies": {
55
+ "@types/fs-extra": "^11.0.0",
56
+ "@types/node": "^20.0.0",
57
+ "@types/react": "^18.2.0",
58
+ "eslint": "^8.0.0",
59
+ "tsup": "^8.0.0",
60
+ "typescript": "^5.0.0"
61
+ },
62
+ "repository": {
63
+ "type": "git",
64
+ "url": "git+https://github.com/e-kairos/ekairos.git"
65
+ },
66
+ "homepage": "https://github.com/e-kairos/ekairos#readme",
67
+ "bugs": {
68
+ "url": "https://github.com/e-kairos/ekairos/issues"
69
+ }
70
+ }