@korajs/cli 1.0.0-beta.1 → 1.0.0-beta.10
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/bin.cjs +593 -290
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +122 -35
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-EOWLAAIV.js → chunk-4IKCHRJ6.js} +273 -57
- package/dist/chunk-4IKCHRJ6.js.map +1 -0
- package/dist/{chunk-B5YS4STN.js → chunk-G2PBYMMA.js} +2 -2
- package/dist/{chunk-B5YS4STN.js.map → chunk-G2PBYMMA.js.map} +1 -1
- package/dist/{chunk-BWTKRKNJ.js → chunk-Z7GCXMGW.js} +9 -5
- package/dist/chunk-Z7GCXMGW.js.map +1 -0
- package/dist/create.cjs +8 -4
- package/dist/create.cjs.map +1 -1
- package/dist/create.js +2 -2
- package/dist/index.cjs +389 -166
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +58 -1
- package/dist/index.d.ts +58 -1
- package/dist/index.js +12 -2
- package/package.json +8 -8
- package/templates/react-basic/README.md.hbs +1 -1
- package/templates/react-basic/src/main.tsx +1 -1
- package/templates/react-basic/src/vite-env.d.ts +1 -0
- package/templates/react-basic/vite.config.ts +7 -4
- package/templates/react-sync/README.md.hbs +6 -5
- package/templates/react-sync/server.ts +46 -3
- package/templates/react-sync/src/main.tsx +1 -1
- package/templates/react-sync/src/vite-env.d.ts +1 -0
- package/templates/react-sync/vite.config.ts +14 -4
- package/templates/react-tailwind/README.md.hbs +1 -1
- package/templates/react-tailwind/src/main.tsx +1 -1
- package/templates/react-tailwind/src/vite-env.d.ts +1 -0
- package/templates/react-tailwind/vite.config.ts +7 -4
- package/templates/react-tailwind-sync/README.md.hbs +6 -5
- package/templates/react-tailwind-sync/server.ts +46 -3
- package/templates/react-tailwind-sync/src/main.tsx +1 -1
- package/templates/react-tailwind-sync/src/vite-env.d.ts +1 -0
- package/templates/react-tailwind-sync/vite.config.ts +14 -4
- package/templates/svelte-basic/README.md.hbs +1 -1
- package/templates/svelte-basic/src/main.ts +1 -1
- package/templates/svelte-basic/vite.config.ts +4 -2
- package/templates/svelte-sync/README.md.hbs +6 -5
- package/templates/svelte-sync/server.ts +46 -3
- package/templates/svelte-sync/src/main.ts +1 -1
- package/templates/svelte-sync/src/vite-env.d.ts +1 -0
- package/templates/svelte-sync/vite.config.ts +11 -2
- package/templates/svelte-tailwind/README.md.hbs +1 -1
- package/templates/svelte-tailwind/src/main.ts +1 -1
- package/templates/svelte-tailwind/vite.config.ts +4 -2
- package/templates/svelte-tailwind-sync/README.md.hbs +6 -5
- package/templates/svelte-tailwind-sync/server.ts +46 -3
- package/templates/svelte-tailwind-sync/src/main.ts +1 -1
- package/templates/svelte-tailwind-sync/src/vite-env.d.ts +1 -0
- package/templates/svelte-tailwind-sync/vite.config.ts +11 -2
- package/templates/tauri-react/server.ts +44 -1
- package/templates/tauri-react/src/AppShell.tsx +1 -1
- package/templates/tauri-react/src/vite-env.d.ts +1 -0
- package/templates/vue-basic/README.md.hbs +1 -1
- package/templates/vue-basic/src/main.ts +1 -1
- package/templates/vue-basic/vite.config.ts +4 -2
- package/templates/vue-sync/README.md.hbs +6 -5
- package/templates/vue-sync/server.ts +46 -3
- package/templates/vue-sync/src/main.ts +1 -1
- package/templates/vue-sync/src/vite-env.d.ts +1 -0
- package/templates/vue-sync/vite.config.ts +11 -2
- package/templates/vue-tailwind/README.md.hbs +1 -1
- package/templates/vue-tailwind/src/main.ts +1 -1
- package/templates/vue-tailwind/vite.config.ts +4 -2
- package/templates/vue-tailwind-sync/README.md.hbs +6 -5
- package/templates/vue-tailwind-sync/server.ts +46 -3
- package/templates/vue-tailwind-sync/src/main.ts +1 -1
- package/templates/vue-tailwind-sync/src/vite-env.d.ts +1 -0
- package/templates/vue-tailwind-sync/vite.config.ts +11 -2
- package/dist/chunk-BWTKRKNJ.js.map +0 -1
- package/dist/chunk-EOWLAAIV.js.map +0 -1
|
@@ -3,12 +3,223 @@ import {
|
|
|
3
3
|
InvalidProjectError,
|
|
4
4
|
createLogger,
|
|
5
5
|
createPromptClient
|
|
6
|
-
} from "./chunk-
|
|
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 =
|
|
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(
|
|
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,
|
|
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
|
|
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 =
|
|
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 =
|
|
346
|
+
const fullPath = join3(projectRoot, candidate);
|
|
136
347
|
try {
|
|
137
|
-
await
|
|
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
|
|
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 =
|
|
179
|
-
await
|
|
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
|
|
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 =
|
|
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:
|
|
497
|
+
outDir: join5(deployDirectory, "dist"),
|
|
287
498
|
mode: "production"
|
|
288
499
|
});
|
|
289
500
|
return {
|
|
290
501
|
clientDirectory: client?.outDir ?? null,
|
|
291
|
-
serverBundlePath:
|
|
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
|
|
513
|
-
import { join as
|
|
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 =
|
|
540
|
-
await
|
|
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
|
|
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 =
|
|
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:
|
|
853
|
+
outDir: join7(deployDirectory, "dist"),
|
|
643
854
|
mode: "production"
|
|
644
855
|
});
|
|
645
856
|
return {
|
|
646
857
|
clientDirectory: client?.outDir ?? null,
|
|
647
|
-
serverBundlePath:
|
|
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
|
|
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 =
|
|
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:
|
|
1223
|
+
outDir: join8(deployDirectory, "dist"),
|
|
1013
1224
|
mode: "production"
|
|
1014
1225
|
});
|
|
1015
1226
|
return {
|
|
1016
1227
|
clientDirectory: client?.outDir ?? null,
|
|
1017
|
-
serverBundlePath:
|
|
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
|
|
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 =
|
|
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:
|
|
1574
|
+
outDir: join9(deployDirectory, "dist"),
|
|
1364
1575
|
mode: "production"
|
|
1365
1576
|
});
|
|
1366
1577
|
return {
|
|
1367
1578
|
clientDirectory: client?.outDir ?? null,
|
|
1368
|
-
serverBundlePath:
|
|
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
|
|
1690
|
-
import { join as
|
|
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 =
|
|
1758
|
-
await
|
|
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 =
|
|
1761
|
-
await
|
|
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 =
|
|
1768
|
-
await
|
|
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
|
|
1774
|
-
import { join as
|
|
1775
|
-
var KORA_DEPLOY_DIRECTORY =
|
|
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
|
|
1989
|
+
return join11(projectRoot, KORA_DEPLOY_DIRECTORY);
|
|
1779
1990
|
}
|
|
1780
1991
|
function resolveDeployStatePath(projectRoot) {
|
|
1781
|
-
return
|
|
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
|
|
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
|
|
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
|
|
1891
|
-
import { defineCommand } from "citty";
|
|
1892
|
-
var deployCommand =
|
|
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:
|
|
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:
|
|
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:
|
|
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(
|
|
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-
|
|
2559
|
+
//# sourceMappingURL=chunk-4IKCHRJ6.js.map
|