@korajs/cli 1.0.0-beta.1 → 1.0.0-beta.4

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.
@@ -3,12 +3,223 @@ import {
3
3
  InvalidProjectError,
4
4
  createLogger,
5
5
  createPromptClient
6
- } from "./chunk-B5YS4STN.js";
6
+ } from "./chunk-G2PBYMMA.js";
7
7
  import {
8
8
  findProjectRoot,
9
9
  resolveProjectBinaryEntryPoint
10
10
  } from "./chunk-5NI2FEQL.js";
11
11
 
12
+ // src/commands/agents/agents-md-content.ts
13
+ var AGENTS_FRAMEWORKS = ["react", "vue", "svelte"];
14
+ function isAgentsFramework(value) {
15
+ return AGENTS_FRAMEWORKS.includes(value);
16
+ }
17
+ function detectFrameworkFromManifest(manifest) {
18
+ if (typeof manifest !== "object" || manifest === null) return null;
19
+ const record = manifest;
20
+ const deps = collectDependencyNames(record.dependencies, record.devDependencies);
21
+ if (deps.has("@korajs/react")) return "react";
22
+ if (deps.has("@korajs/vue")) return "vue";
23
+ if (deps.has("@korajs/svelte")) return "svelte";
24
+ return null;
25
+ }
26
+ function collectDependencyNames(...groups) {
27
+ const names = /* @__PURE__ */ new Set();
28
+ for (const group of groups) {
29
+ if (typeof group !== "object" || group === null) continue;
30
+ for (const name of Object.keys(group)) {
31
+ names.add(name);
32
+ }
33
+ }
34
+ return names;
35
+ }
36
+ var FRAMEWORK_BINDINGS = {
37
+ react: `## React bindings
38
+
39
+ \`\`\`tsx
40
+ import { KoraProvider, useCollection, useMutation, useQuery, useSyncStatus } from '@korajs/react'
41
+
42
+ // Wrap the tree once near your app entry: <KoraProvider app={app}><App /></KoraProvider>
43
+
44
+ const todos = useCollection('todos')
45
+ const rows = useQuery(todos.where({ completed: false }).orderBy('createdAt'))
46
+ const addTodo = useMutation((data) => todos.insert(data))
47
+ addTodo.mutate({ title: 'x' }) // fire-and-forget; errors land in addTodo.error
48
+ await addTodo.mutateAsync({ title: 'x' }) // resolves with the result; throws on failure
49
+ const status = useSyncStatus() // status.status, status.pendingOperations
50
+ \`\`\`
51
+
52
+ Rules: always render \`mutation.error\` somewhere. Keep \`<StrictMode>\` in place; the hooks are StrictMode-safe. \`useQuery\` returns data synchronously from the local store, so do not add loading spinners for local reads.`,
53
+ vue: `## Vue bindings
54
+
55
+ \`\`\`ts
56
+ import { useCollection, useMutation, useQuery, useSyncStatus } from '@korajs/vue'
57
+
58
+ const todos = useCollection('todos')
59
+ const rows = useQuery(todos.where({ completed: false }).orderBy('createdAt')) // readonly reactive ref
60
+ const addTodo = useMutation((data) => todos.insert(data))
61
+ addTodo.mutate({ title: 'x' }) // fire-and-forget; errors land in addTodo.error
62
+ const status = useSyncStatus() // status.status, status.pendingOperations
63
+ \`\`\`
64
+
65
+ Rules: surface the mutation's error state in the UI. \`useQuery\` reads synchronously from the local store, so avoid loading spinners for local data. The Kora context comes from \`KoraProvider\`, wired in your app entry (for example \`src/main.ts\`).`,
66
+ svelte: `## Svelte bindings
67
+
68
+ Kora's Svelte bindings from \`@korajs/svelte\` expose \`useCollection\`, \`useQuery\`, \`useMutation\`, and \`useSyncStatus\`, wired through the provider set up in your app entry.
69
+
70
+ \`\`\`ts
71
+ import { useCollection, useMutation, useQuery, useSyncStatus } from '@korajs/svelte'
72
+
73
+ const todos = useCollection('todos')
74
+ const rows = useQuery(todos.where({ completed: false }).orderBy('createdAt')) // reactive store
75
+ const addTodo = useMutation((data) => todos.insert(data))
76
+ addTodo.mutate({ title: 'x' }) // fire-and-forget; errors land in addTodo.error
77
+ const status = useSyncStatus() // readable store; read $status.status in markup
78
+ \`\`\`
79
+
80
+ Rules: queries are reactive stores that read synchronously from the local database, so avoid loading spinners for local reads. Mutations expose an \`error\` state that must be surfaced in the UI.`
81
+ };
82
+ function generateAgentsMd(framework) {
83
+ return `# AGENTS.md
84
+
85
+ Guidance for AI coding agents working in this project. Humans: this is useful for you too.
86
+
87
+ ## What this project is
88
+
89
+ This project uses **Kora.js**, an offline-first application framework. All application data lives in a local SQLite database (WASM + OPFS in the browser, native SQLite on desktop and server) and optionally syncs across devices through a Kora sync server. Offline is the normal state, not an error state. Full docs live at https://korajs.dev, with a machine-readable index at https://korajs.dev/llms.txt and the complete docs in one file at https://korajs.dev/llms-full.txt. Any documentation page is available as raw markdown by appending \`.md\` to its URL.
90
+
91
+ ## Golden rules
92
+
93
+ 1. **The schema is the source of truth.** Collections are defined with \`defineSchema\` and the \`t.*\` field builders (by convention in \`src/schema.ts\`). To add or change data shapes, edit the schema first; types flow from it automatically. Never hand-write types for records.
94
+ 2. **Never fetch application data over HTTP.** Do not add REST or GraphQL calls for app data, and do not talk to the sync server directly. Read and write through Kora collections only; sync happens automatically in the background.
95
+ 3. **Await readiness before direct collection access.** Outside the UI bindings, \`await app.ready\` before calling \`app.<collection>\` methods. The framework bindings handle this for you inside components.
96
+ 4. **Offline must keep working.** Any feature you add must function with the network off. Never gate a read or write on connectivity. If you are checking \`navigator.onLine\` before a data operation, you are doing it wrong.
97
+ 5. **Surface mutation errors.** Fire-and-forget \`mutate\` calls fold errors into the mutation state. Always render the mutation's \`error\`, or handle the promise from the \`mutateAsync\` variant. Silent failure is the worst failure.
98
+ 6. **Do not add a state library for server or app data.** Kora's reactive queries are the store. Do not reach for react-query, SWR, Redux, Zustand, or similar for data that lives in a collection. Local UI state (form inputs, toggles) can use your framework's normal state tools.
99
+ 7. **Do not add loading spinners for local reads.** \`useQuery\` returns data synchronously from the local store, so there is no loading state to wait on for local data.
100
+
101
+ ## Data API cheat sheet
102
+
103
+ \`\`\`ts
104
+ await app.ready
105
+ const rec = await app.todos.insert({ title: 'x' }) // defaults and .auto() fields applied
106
+ await app.todos.update(rec.id, { completed: true }) // partial update, changed fields only
107
+ await app.todos.delete(rec.id)
108
+ const one = await app.todos.findById(rec.id)
109
+ const unsubscribe = app.todos
110
+ .where({ completed: false })
111
+ .orderBy('createdAt', 'desc')
112
+ .subscribe((rows) => {/* fires immediately, then on every change */})
113
+ \`\`\`
114
+
115
+ Schema example (\`src/schema.ts\`):
116
+
117
+ \`\`\`ts
118
+ import { defineSchema, t } from 'korajs'
119
+
120
+ export default defineSchema({
121
+ version: 1,
122
+ collections: {
123
+ todos: {
124
+ fields: {
125
+ title: t.string(),
126
+ completed: t.boolean().default(false),
127
+ tags: t.array(t.string()).default([]),
128
+ priority: t.enum(['low', 'medium', 'high']).default('medium'),
129
+ createdAt: t.timestamp().auto(), // set automatically; never pass it on insert
130
+ },
131
+ indexes: ['completed', 'createdAt'],
132
+ },
133
+ },
134
+ })
135
+ \`\`\`
136
+
137
+ If you change collection shapes, increment \`version\` and run \`npx kora migrate\`.
138
+
139
+ ## Conflict handling
140
+
141
+ Concurrent edits merge automatically: last-write-wins per field, add-wins for arrays, and character-level CRDT for \`t.richtext()\` fields. When a field needs domain-specific merging (counters, quantities), add a \`resolve\` function in the schema rather than writing sync logic by hand. Never write your own conflict or merge code.
142
+
143
+ ## Sync and auth
144
+
145
+ Enable sync by adding one line to \`createApp\`: \`createApp({ schema, sync: { url } })\`. When the app is offline, writes queue locally and sync when connectivity returns. If the project uses \`@korajs/auth\`, pass its client as \`createApp({ schema, sync: { url, authClient } })\`. Local writes work without sign-in; sync requires the server to accept the connection.
146
+
147
+ ${FRAMEWORK_BINDINGS[framework]}
148
+
149
+ ## Commands
150
+
151
+ - \`npx kora dev\` runs the dev environment (app server, local sync server when configured, schema watcher).
152
+ - \`npx kora doctor\` diagnoses a broken setup.
153
+ - \`npx kora migrate\` applies a schema change to the local store.
154
+ - In a running app, the DevTools overlay (Ctrl+Shift+K, Cmd+Shift+K on macOS) inspects operations, merges, and sync status.
155
+ `;
156
+ }
157
+
158
+ // src/commands/agents/agents-command.ts
159
+ import { access, readFile, writeFile } from "fs/promises";
160
+ import { join } from "path";
161
+ import { defineCommand } from "citty";
162
+ async function fileExists(path) {
163
+ try {
164
+ await access(path);
165
+ return true;
166
+ } catch {
167
+ return false;
168
+ }
169
+ }
170
+ async function readManifest(root) {
171
+ try {
172
+ return JSON.parse(await readFile(join(root, "package.json"), "utf-8"));
173
+ } catch {
174
+ return null;
175
+ }
176
+ }
177
+ function resolveFramework(override, manifest) {
178
+ if (override !== void 0 && isAgentsFramework(override)) return override;
179
+ return detectFrameworkFromManifest(manifest) ?? "react";
180
+ }
181
+ var agentsCommand = defineCommand({
182
+ meta: {
183
+ name: "agents-md",
184
+ description: "Write an AGENTS.md with Kora rules for AI coding agents into this project"
185
+ },
186
+ args: {
187
+ force: {
188
+ type: "boolean",
189
+ description: "Overwrite an existing AGENTS.md",
190
+ default: false
191
+ },
192
+ framework: {
193
+ type: "string",
194
+ description: "Override framework detection (react, vue, or svelte)"
195
+ }
196
+ },
197
+ async run({ args }) {
198
+ const logger = createLogger();
199
+ const projectRoot = await findProjectRoot() ?? process.cwd();
200
+ const manifest = await readManifest(projectRoot);
201
+ const override = typeof args.framework === "string" ? args.framework : void 0;
202
+ if (override !== void 0 && !isAgentsFramework(override)) {
203
+ logger.error(`Unknown framework "${override}". Use one of: react, vue, svelte.`);
204
+ process.exitCode = 1;
205
+ return;
206
+ }
207
+ const framework = resolveFramework(override, manifest);
208
+ const target = join(projectRoot, "AGENTS.md");
209
+ const force = args.force === true;
210
+ if (await fileExists(target) && !force) {
211
+ logger.warn("AGENTS.md already exists. Re-run with --force to overwrite it.");
212
+ process.exitCode = 1;
213
+ return;
214
+ }
215
+ await writeFile(target, generateAgentsMd(framework), "utf-8");
216
+ logger.banner();
217
+ logger.success(`Wrote AGENTS.md (${framework} bindings) to ${target}`);
218
+ logger.step("Commit it so coding agents pick up Kora conventions automatically.");
219
+ logger.blank();
220
+ }
221
+ });
222
+
12
223
  // src/commands/deploy/adapters/adapter.ts
13
224
  var DEPLOY_PLATFORMS = [
14
225
  "fly",
@@ -27,7 +238,7 @@ function isDeployPlatform(value) {
27
238
  import { spawn } from "child_process";
28
239
  import { existsSync } from "fs";
29
240
  import { copyFile, readdir } from "fs/promises";
30
- import { join, resolve } from "path";
241
+ import { join as join2, resolve } from "path";
31
242
  async function buildClient(options) {
32
243
  const viteEntryPoint = await resolveProjectBinaryEntryPoint(options.projectRoot, "vite", "vite");
33
244
  if (!viteEntryPoint) {
@@ -48,12 +259,12 @@ async function buildClient(options) {
48
259
  return { outDir: options.outDir };
49
260
  }
50
261
  async function patchSqliteWasmAssets(projectRoot, outDir) {
51
- const assetsDir = join(outDir, "assets");
262
+ const assetsDir = join2(outDir, "assets");
52
263
  if (!existsSync(assetsDir)) return;
53
264
  const files = await readdir(assetsDir);
54
265
  const hashedWasm = files.find((f) => /^sqlite3-.+\.wasm$/.test(f));
55
266
  if (hashedWasm && !files.includes("sqlite3.wasm")) {
56
- await copyFile(join(assetsDir, hashedWasm), join(assetsDir, "sqlite3.wasm"));
267
+ await copyFile(join2(assetsDir, hashedWasm), join2(assetsDir, "sqlite3.wasm"));
57
268
  }
58
269
  if (!files.includes("sqlite3-opfs-async-proxy.js")) {
59
270
  const proxyFile = resolve(
@@ -66,7 +277,7 @@ async function patchSqliteWasmAssets(projectRoot, outDir) {
66
277
  "sqlite3-opfs-async-proxy.js"
67
278
  );
68
279
  if (existsSync(proxyFile)) {
69
- await copyFile(proxyFile, join(assetsDir, "sqlite3-opfs-async-proxy.js"));
280
+ await copyFile(proxyFile, join2(assetsDir, "sqlite3-opfs-async-proxy.js"));
70
281
  }
71
282
  }
72
283
  }
@@ -92,8 +303,8 @@ async function runProcess(command, args, cwd) {
92
303
 
93
304
  // src/commands/deploy/builder/server-bundler.ts
94
305
  import { mkdir } from "fs/promises";
95
- import { access } from "fs/promises";
96
- import { join as join2 } from "path";
306
+ import { access as access2 } from "fs/promises";
307
+ import { join as join3 } from "path";
97
308
  import { build } from "esbuild";
98
309
  var DEFAULT_ENTRY_CANDIDATES = [
99
310
  "server.ts",
@@ -110,7 +321,7 @@ async function bundleServer(options) {
110
321
  );
111
322
  }
112
323
  await mkdir(options.deployDirectory, { recursive: true });
113
- const outputFilePath = join2(options.deployDirectory, "server-bundled.js");
324
+ const outputFilePath = join3(options.deployDirectory, "server-bundled.js");
114
325
  await build({
115
326
  entryPoints: [entryFilePath],
116
327
  outfile: outputFilePath,
@@ -132,9 +343,9 @@ async function bundleServer(options) {
132
343
  }
133
344
  async function resolveServerEntry(projectRoot, candidates) {
134
345
  for (const candidate of candidates) {
135
- const fullPath = join2(projectRoot, candidate);
346
+ const fullPath = join3(projectRoot, candidate);
136
347
  try {
137
- await access(fullPath);
348
+ await access2(fullPath);
138
349
  return fullPath;
139
350
  } catch {
140
351
  }
@@ -143,8 +354,8 @@ async function resolveServerEntry(projectRoot, candidates) {
143
354
  }
144
355
 
145
356
  // src/commands/deploy/artifacts/fly-toml-generator.ts
146
- import { mkdir as mkdir2, writeFile } from "fs/promises";
147
- import { join as join3 } from "path";
357
+ import { mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
358
+ import { join as join4 } from "path";
148
359
  var GENERATED_HEADER = "# Generated by kora deploy \u2014 do not edit manually";
149
360
  function generateFlyToml(options) {
150
361
  const internalPort = options.internalPort ?? 3e3;
@@ -175,14 +386,14 @@ function generateFlyToml(options) {
175
386
  }
176
387
  async function writeFlyTomlArtifact(deployDirectory, options) {
177
388
  await mkdir2(deployDirectory, { recursive: true });
178
- const filePath = join3(deployDirectory, "fly.toml");
179
- await writeFile(filePath, generateFlyToml(options), "utf-8");
389
+ const filePath = join4(deployDirectory, "fly.toml");
390
+ await writeFile2(filePath, generateFlyToml(options), "utf-8");
180
391
  return filePath;
181
392
  }
182
393
 
183
394
  // src/commands/deploy/adapters/fly-adapter.ts
184
395
  import { spawn as spawn2 } from "child_process";
185
- import { join as join4 } from "path";
396
+ import { join as join5 } from "path";
186
397
  var FlyAdapter = class {
187
398
  name = "fly";
188
399
  logger = createLogger();
@@ -272,7 +483,7 @@ var FlyAdapter = class {
272
483
  appName: config.appName,
273
484
  region: config.region
274
485
  };
275
- const deployDirectory = join4(config.projectRoot, ".kora", "deploy");
486
+ const deployDirectory = join5(config.projectRoot, ".kora", "deploy");
276
487
  await writeFlyTomlArtifact(deployDirectory, {
277
488
  appName: config.appName,
278
489
  region: config.region ?? "iad"
@@ -283,12 +494,12 @@ var FlyAdapter = class {
283
494
  });
284
495
  const client = config.deployTarget === "sync-server" ? null : await buildClient({
285
496
  projectRoot: config.projectRoot,
286
- outDir: join4(deployDirectory, "dist"),
497
+ outDir: join5(deployDirectory, "dist"),
287
498
  mode: "production"
288
499
  });
289
500
  return {
290
501
  clientDirectory: client?.outDir ?? null,
291
- serverBundlePath: join4(deployDirectory, "server-bundled.js"),
502
+ serverBundlePath: join5(deployDirectory, "server-bundled.js"),
292
503
  deployDirectory
293
504
  };
294
505
  }
@@ -509,8 +720,8 @@ ${stdout}`.toLowerCase();
509
720
  }
510
721
 
511
722
  // src/commands/deploy/artifacts/railway-json-generator.ts
512
- import { mkdir as mkdir3, writeFile as writeFile2 } from "fs/promises";
513
- import { join as join5 } from "path";
723
+ import { mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
724
+ import { join as join6 } from "path";
514
725
  var GENERATED_HEADER2 = "Generated by kora deploy - do not edit manually.";
515
726
  function generateRailwayJson(options) {
516
727
  const file = {
@@ -536,14 +747,14 @@ function generateRailwayJson(options) {
536
747
  }
537
748
  async function writeRailwayJsonArtifact(deployDirectory, options) {
538
749
  await mkdir3(deployDirectory, { recursive: true });
539
- const filePath = join5(deployDirectory, "railway.json");
540
- await writeFile2(filePath, generateRailwayJson(options), "utf-8");
750
+ const filePath = join6(deployDirectory, "railway.json");
751
+ await writeFile3(filePath, generateRailwayJson(options), "utf-8");
541
752
  return filePath;
542
753
  }
543
754
 
544
755
  // src/commands/deploy/adapters/railway-adapter.ts
545
756
  import { spawn as spawn3 } from "child_process";
546
- import { join as join6 } from "path";
757
+ import { join as join7 } from "path";
547
758
  var RailwayAdapter = class {
548
759
  name = "railway";
549
760
  logger = createLogger();
@@ -628,7 +839,7 @@ var RailwayAdapter = class {
628
839
  appName: config.appName,
629
840
  region: config.region
630
841
  };
631
- const deployDirectory = join6(config.projectRoot, ".kora", "deploy");
842
+ const deployDirectory = join7(config.projectRoot, ".kora", "deploy");
632
843
  await writeRailwayJsonArtifact(deployDirectory, {
633
844
  appName: config.appName,
634
845
  environment: config.environment
@@ -639,12 +850,12 @@ var RailwayAdapter = class {
639
850
  });
640
851
  const client = config.deployTarget === "sync-server" ? null : await buildClient({
641
852
  projectRoot: config.projectRoot,
642
- outDir: join6(deployDirectory, "dist"),
853
+ outDir: join7(deployDirectory, "dist"),
643
854
  mode: "production"
644
855
  });
645
856
  return {
646
857
  clientDirectory: client?.outDir ?? null,
647
- serverBundlePath: join6(deployDirectory, "server-bundled.js"),
858
+ serverBundlePath: join7(deployDirectory, "server-bundled.js"),
648
859
  deployDirectory
649
860
  };
650
861
  }
@@ -908,7 +1119,7 @@ var StubDeployAdapter = class {
908
1119
 
909
1120
  // src/commands/deploy/adapters/aws-ecs-adapter.ts
910
1121
  import { spawn as spawn4 } from "child_process";
911
- import { join as join7 } from "path";
1122
+ import { join as join8 } from "path";
912
1123
  var AwsEcsAdapter = class {
913
1124
  name = "aws-ecs";
914
1125
  logger = createLogger();
@@ -1002,19 +1213,19 @@ var AwsEcsAdapter = class {
1002
1213
  appName: config.appName,
1003
1214
  region: config.region
1004
1215
  };
1005
- const deployDirectory = join7(config.projectRoot, ".kora", "deploy");
1216
+ const deployDirectory = join8(config.projectRoot, ".kora", "deploy");
1006
1217
  await bundleServer({
1007
1218
  projectRoot: config.projectRoot,
1008
1219
  deployDirectory
1009
1220
  });
1010
1221
  const client = config.deployTarget === "sync-server" ? null : await buildClient({
1011
1222
  projectRoot: config.projectRoot,
1012
- outDir: join7(deployDirectory, "dist"),
1223
+ outDir: join8(deployDirectory, "dist"),
1013
1224
  mode: "production"
1014
1225
  });
1015
1226
  return {
1016
1227
  clientDirectory: client?.outDir ?? null,
1017
- serverBundlePath: join7(deployDirectory, "server-bundled.js"),
1228
+ serverBundlePath: join8(deployDirectory, "server-bundled.js"),
1018
1229
  deployDirectory
1019
1230
  };
1020
1231
  }
@@ -1280,7 +1491,7 @@ function inferLogLevel3(line) {
1280
1491
 
1281
1492
  // src/commands/deploy/adapters/aws-lightsail-adapter.ts
1282
1493
  import { spawn as spawn5 } from "child_process";
1283
- import { join as join8 } from "path";
1494
+ import { join as join9 } from "path";
1284
1495
  var AwsLightsailAdapter = class {
1285
1496
  name = "aws-lightsail";
1286
1497
  logger = createLogger();
@@ -1353,19 +1564,19 @@ var AwsLightsailAdapter = class {
1353
1564
  appName: config.appName,
1354
1565
  region: config.region
1355
1566
  };
1356
- const deployDirectory = join8(config.projectRoot, ".kora", "deploy");
1567
+ const deployDirectory = join9(config.projectRoot, ".kora", "deploy");
1357
1568
  await bundleServer({
1358
1569
  projectRoot: config.projectRoot,
1359
1570
  deployDirectory
1360
1571
  });
1361
1572
  const client = config.deployTarget === "sync-server" ? null : await buildClient({
1362
1573
  projectRoot: config.projectRoot,
1363
- outDir: join8(deployDirectory, "dist"),
1574
+ outDir: join9(deployDirectory, "dist"),
1364
1575
  mode: "production"
1365
1576
  });
1366
1577
  return {
1367
1578
  clientDirectory: client?.outDir ?? null,
1368
- serverBundlePath: join8(deployDirectory, "server-bundled.js"),
1579
+ serverBundlePath: join9(deployDirectory, "server-bundled.js"),
1369
1580
  deployDirectory
1370
1581
  };
1371
1582
  }
@@ -1686,8 +1897,8 @@ function createDeployAdapter(platform) {
1686
1897
  }
1687
1898
 
1688
1899
  // src/commands/deploy/artifacts/dockerfile-generator.ts
1689
- import { mkdir as mkdir4, writeFile as writeFile3 } from "fs/promises";
1690
- import { join as join9 } from "path";
1900
+ import { mkdir as mkdir4, writeFile as writeFile4 } from "fs/promises";
1901
+ import { join as join10 } from "path";
1691
1902
  var GENERATED_HEADER3 = "# Generated by kora deploy \u2014 do not edit manually";
1692
1903
  function generateDockerfile(options = {}) {
1693
1904
  const nodeVersion = options.nodeVersion ?? "20-alpine";
@@ -1754,36 +1965,36 @@ function generateDockerIgnore() {
1754
1965
  }
1755
1966
  async function writeDockerfileArtifact(deployDirectory, options = {}) {
1756
1967
  await mkdir4(deployDirectory, { recursive: true });
1757
- const dockerfilePath = join9(deployDirectory, "Dockerfile");
1758
- await writeFile3(dockerfilePath, generateDockerfile(options), "utf-8");
1968
+ const dockerfilePath = join10(deployDirectory, "Dockerfile");
1969
+ await writeFile4(dockerfilePath, generateDockerfile(options), "utf-8");
1759
1970
  if (options.nativeDependencies && Object.keys(options.nativeDependencies).length > 0) {
1760
- const pkgJsonPath = join9(deployDirectory, "package.json");
1761
- await writeFile3(pkgJsonPath, generateDeployPackageJson(options.nativeDependencies), "utf-8");
1971
+ const pkgJsonPath = join10(deployDirectory, "package.json");
1972
+ await writeFile4(pkgJsonPath, generateDeployPackageJson(options.nativeDependencies), "utf-8");
1762
1973
  }
1763
1974
  return dockerfilePath;
1764
1975
  }
1765
1976
  async function writeDockerIgnoreArtifact(deployDirectory) {
1766
1977
  await mkdir4(deployDirectory, { recursive: true });
1767
- const dockerIgnorePath = join9(deployDirectory, ".dockerignore");
1768
- await writeFile3(dockerIgnorePath, generateDockerIgnore(), "utf-8");
1978
+ const dockerIgnorePath = join10(deployDirectory, ".dockerignore");
1979
+ await writeFile4(dockerIgnorePath, generateDockerIgnore(), "utf-8");
1769
1980
  return dockerIgnorePath;
1770
1981
  }
1771
1982
 
1772
1983
  // src/commands/deploy/state/deploy-state.ts
1773
- import { mkdir as mkdir5, readFile, rm, writeFile as writeFile4 } from "fs/promises";
1774
- import { join as join10 } from "path";
1775
- var KORA_DEPLOY_DIRECTORY = join10(".kora", "deploy");
1984
+ import { mkdir as mkdir5, readFile as readFile2, rm, writeFile as writeFile5 } from "fs/promises";
1985
+ import { join as join11 } from "path";
1986
+ var KORA_DEPLOY_DIRECTORY = join11(".kora", "deploy");
1776
1987
  var DEPLOY_STATE_FILENAME = "deploy.json";
1777
1988
  function resolveDeployDirectory(projectRoot) {
1778
- return join10(projectRoot, KORA_DEPLOY_DIRECTORY);
1989
+ return join11(projectRoot, KORA_DEPLOY_DIRECTORY);
1779
1990
  }
1780
1991
  function resolveDeployStatePath(projectRoot) {
1781
- return join10(resolveDeployDirectory(projectRoot), DEPLOY_STATE_FILENAME);
1992
+ return join11(resolveDeployDirectory(projectRoot), DEPLOY_STATE_FILENAME);
1782
1993
  }
1783
1994
  async function readDeployState(projectRoot) {
1784
1995
  const statePath = resolveDeployStatePath(projectRoot);
1785
1996
  try {
1786
- const source = await readFile(statePath, "utf-8");
1997
+ const source = await readFile2(statePath, "utf-8");
1787
1998
  const parsed = JSON.parse(source);
1788
1999
  return parseDeployState(parsed);
1789
2000
  } catch (error) {
@@ -1836,7 +2047,7 @@ async function persistDeployState(projectRoot, state) {
1836
2047
  const deployDir = resolveDeployDirectory(projectRoot);
1837
2048
  const statePath = resolveDeployStatePath(projectRoot);
1838
2049
  await mkdir5(deployDir, { recursive: true });
1839
- await writeFile4(statePath, `${JSON.stringify(state, null, 2)}
2050
+ await writeFile5(statePath, `${JSON.stringify(state, null, 2)}
1840
2051
  `, "utf-8");
1841
2052
  }
1842
2053
  function parseDeployState(value) {
@@ -1887,9 +2098,9 @@ function readOptionalString(value, field) {
1887
2098
 
1888
2099
  // src/commands/deploy/deploy-command.ts
1889
2100
  import { existsSync as existsSync2 } from "fs";
1890
- import { basename, join as join11 } from "path";
1891
- import { defineCommand } from "citty";
1892
- var deployCommand = defineCommand({
2101
+ import { basename, join as join12 } from "path";
2102
+ import { defineCommand as defineCommand2 } from "citty";
2103
+ var deployCommand = defineCommand2({
1893
2104
  meta: {
1894
2105
  name: "deploy",
1895
2106
  description: "Deploy a Kora project to your selected platform"
@@ -1924,7 +2135,7 @@ var deployCommand = defineCommand({
1924
2135
  }
1925
2136
  },
1926
2137
  subCommands: {
1927
- status: defineCommand({
2138
+ status: defineCommand2({
1928
2139
  meta: {
1929
2140
  name: "status",
1930
2141
  description: "Show current deployment status"
@@ -1955,7 +2166,7 @@ var deployCommand = defineCommand({
1955
2166
  logger.step(`Sync URL: ${state.syncUrl ?? "n/a"}`);
1956
2167
  }
1957
2168
  }),
1958
- rollback: defineCommand({
2169
+ rollback: defineCommand2({
1959
2170
  meta: {
1960
2171
  name: "rollback",
1961
2172
  description: "Rollback the current deployment"
@@ -1986,7 +2197,7 @@ var deployCommand = defineCommand({
1986
2197
  logger.success(`Rolled back ${state.platform} deployment to ${deploymentId}.`);
1987
2198
  }
1988
2199
  }),
1989
- logs: defineCommand({
2200
+ logs: defineCommand2({
1990
2201
  meta: {
1991
2202
  name: "logs",
1992
2203
  description: "Read deployment logs"
@@ -2208,7 +2419,7 @@ function configureAdapterContext(adapter, context) {
2208
2419
  }
2209
2420
  }
2210
2421
  function detectDeployTarget(projectRoot) {
2211
- return existsSync2(join11(projectRoot, "src-tauri")) ? "sync-server" : "full-stack";
2422
+ return existsSync2(join12(projectRoot, "src-tauri")) ? "sync-server" : "full-stack";
2212
2423
  }
2213
2424
  function hasContextSetter(adapter) {
2214
2425
  return typeof adapter.setContext === "function";
@@ -2312,6 +2523,11 @@ function toPascalCase(name) {
2312
2523
  }
2313
2524
 
2314
2525
  export {
2526
+ AGENTS_FRAMEWORKS,
2527
+ isAgentsFramework,
2528
+ detectFrameworkFromManifest,
2529
+ generateAgentsMd,
2530
+ agentsCommand,
2315
2531
  DEPLOY_PLATFORMS,
2316
2532
  isDeployPlatform,
2317
2533
  buildClient,
@@ -2340,4 +2556,4 @@ export {
2340
2556
  deployCommand,
2341
2557
  generateTypes
2342
2558
  };
2343
- //# sourceMappingURL=chunk-EOWLAAIV.js.map
2559
+ //# sourceMappingURL=chunk-4IKCHRJ6.js.map