@kodycodes/cli 1.25.1 → 1.26.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 +32 -0
- package/dist/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/dev/dev-assets.d.ts +40 -0
- package/dist/dev/dev-assets.js +202 -0
- package/dist/dev/dev-assets.js.map +1 -0
- package/dist/dev/dev-bundler.d.ts +3 -1
- package/dist/dev/dev-bundler.js +21 -7
- package/dist/dev/dev-bundler.js.map +1 -1
- package/dist/dev/dev-events.d.ts +1 -1
- package/dist/dev/dev-events.js +1 -1
- package/dist/dev/dev-events.js.map +1 -1
- package/dist/dev/dev-port.d.ts +22 -0
- package/dist/dev/dev-port.js +80 -0
- package/dist/dev/dev-port.js.map +1 -0
- package/dist/dev/prebuild.d.ts +17 -0
- package/dist/dev/prebuild.js +102 -0
- package/dist/dev/prebuild.js.map +1 -0
- package/dist/dev/process-reaper.d.ts +3 -0
- package/dist/dev/process-reaper.js +8 -1
- package/dist/dev/process-reaper.js.map +1 -1
- package/dist/dev-command.d.ts +1 -0
- package/dist/dev-command.js +65 -29
- package/dist/dev-command.js.map +1 -1
- package/dist/help.js +7 -0
- package/dist/help.js.map +1 -1
- package/dist/package-app-dev.d.ts +16 -0
- package/dist/package-app-dev.js +153 -18
- package/dist/package-app-dev.js.map +1 -1
- package/dist/package-manifest.d.ts +11 -0
- package/dist/package-manifest.js +66 -1
- package/dist/package-manifest.js.map +1 -1
- package/dist/structured-error.d.ts +1 -1
- package/dist/structured-error.js.map +1 -1
- package/package.json +1 -1
package/dist/dev/dev-bundler.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `kody dev` bundles of `kody.app.entry`: same esbuild options as one-shot
|
|
3
3
|
* local bundles, plus an in-memory source map (for mapping workerd stacks back
|
|
4
|
-
* to `.ts`) and the list of input files (for the watcher's stat poll).
|
|
4
|
+
* to `.ts`) and the list of input files (for the watcher's stat poll). Uses an
|
|
5
|
+
* incremental esbuild context so rebuilds only reparse changed files.
|
|
5
6
|
*/
|
|
6
7
|
import * as esbuild from 'esbuild';
|
|
7
8
|
import { join, resolve } from 'node:path';
|
|
@@ -18,20 +19,36 @@ export function createDevBundler(input) {
|
|
|
18
19
|
outfile: join(input.root, '__kody_dev_bundle.js'),
|
|
19
20
|
};
|
|
20
21
|
const paths = { workingDir: base.absWorkingDir, displayRoot: input.root };
|
|
22
|
+
let disposed = false;
|
|
23
|
+
let context = null;
|
|
21
24
|
return {
|
|
22
25
|
build: async () => {
|
|
23
26
|
let result;
|
|
24
27
|
try {
|
|
25
|
-
|
|
28
|
+
// A context created after dispose would never be released and keeps Node alive.
|
|
29
|
+
if (disposed)
|
|
30
|
+
throw new Error('kody dev bundler was already disposed.');
|
|
31
|
+
context ??= esbuild.context(options);
|
|
32
|
+
result = await (await context).rebuild();
|
|
26
33
|
}
|
|
27
34
|
catch (error) {
|
|
28
35
|
throw createBundleError(input.entryPath, error, paths);
|
|
29
36
|
}
|
|
30
37
|
return readBundle(result, base.absWorkingDir, input.entryPath);
|
|
31
38
|
},
|
|
32
|
-
dispose: async () => {
|
|
39
|
+
dispose: async () => {
|
|
40
|
+
disposed = true;
|
|
41
|
+
const current = context;
|
|
42
|
+
context = null;
|
|
43
|
+
await (await current?.catch(() => null))?.dispose();
|
|
44
|
+
},
|
|
33
45
|
};
|
|
34
46
|
}
|
|
47
|
+
export function bundleInputs(metafile, workingDir) {
|
|
48
|
+
return Object.keys(metafile?.inputs ?? {})
|
|
49
|
+
.filter((path) => !path.includes('node_modules') && !path.includes(':'))
|
|
50
|
+
.map((path) => resolve(workingDir, path));
|
|
51
|
+
}
|
|
35
52
|
export function readBundle(result, workingDir, entryPath) {
|
|
36
53
|
const outputs = result.outputFiles ?? [];
|
|
37
54
|
const js = outputs.find((file) => file.path.endsWith('.js'));
|
|
@@ -39,13 +56,10 @@ export function readBundle(result, workingDir, entryPath) {
|
|
|
39
56
|
if (!js) {
|
|
40
57
|
throw new BundleError(`Could not bundle ${entryPath}: esbuild produced no output.`, []);
|
|
41
58
|
}
|
|
42
|
-
const inputs = Object.keys(result.metafile?.inputs ?? {})
|
|
43
|
-
.filter((path) => !path.includes('node_modules') && !path.includes(':'))
|
|
44
|
-
.map((path) => resolve(workingDir, path));
|
|
45
59
|
return {
|
|
46
60
|
code: js.text.replace(/\n\/\/# sourceMappingURL=\S+\s*$/, '\n'),
|
|
47
61
|
sourceMap: map?.text ?? null,
|
|
48
|
-
inputs,
|
|
62
|
+
inputs: bundleInputs(result.metafile, workingDir),
|
|
49
63
|
};
|
|
50
64
|
}
|
|
51
65
|
//# sourceMappingURL=dev-bundler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-bundler.js","sourceRoot":"","sources":["../../src/dev/dev-bundler.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"dev-bundler.js","sourceRoot":"","sources":["../../src/dev/dev-bundler.ts"],"names":[],"mappings":"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"}
|
package/dist/dev/dev-events.d.ts
CHANGED
package/dist/dev/dev-events.js
CHANGED
|
@@ -67,7 +67,7 @@ export function formatDevEvent(event) {
|
|
|
67
67
|
text: `${formatRequestTag(event.request)} Uncaught ${event.stack || event.message}`,
|
|
68
68
|
};
|
|
69
69
|
case 'log': {
|
|
70
|
-
const tag = event.source === '
|
|
70
|
+
const tag = event.source === 'app' ? formatRequestTag(event.request) : `[${event.source}]`;
|
|
71
71
|
const level = event.level === 'log' || event.level === 'info' ? '' : `${event.level}: `;
|
|
72
72
|
const stream = event.level === 'error' || event.level === 'warn' ? 'stderr' : 'stdout';
|
|
73
73
|
return { stream, text: `${tag} ${level}${event.message}` };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-events.js","sourceRoot":"","sources":["../../src/dev/dev-events.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"dev-events.js","sourceRoot":"","sources":["../../src/dev/dev-events.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `kody dev` ports: each package gets a stable default (so bookmarks, OAuth
|
|
3
|
+
* redirect URIs, and agent notes keep working across restarts) and walks up to
|
|
4
|
+
* the next free port when that one is taken. An explicit `--port` is honored
|
|
5
|
+
* exactly and fails with an actionable message instead.
|
|
6
|
+
*/
|
|
7
|
+
import type { Server } from 'node:http';
|
|
8
|
+
export declare const devPortRange: {
|
|
9
|
+
readonly min: 4100;
|
|
10
|
+
readonly max: 4999;
|
|
11
|
+
};
|
|
12
|
+
export declare function defaultDevPort(kodyId: string): number;
|
|
13
|
+
export declare function parseDevPort(raw: string): number;
|
|
14
|
+
/**
|
|
15
|
+
* Listen on `port` exactly when `explicit`, otherwise on `port` or the next
|
|
16
|
+
* free port above it. Returns the bound port.
|
|
17
|
+
*/
|
|
18
|
+
export declare function listenDevServer(server: Server, input: {
|
|
19
|
+
host: string;
|
|
20
|
+
port: number;
|
|
21
|
+
explicit: boolean;
|
|
22
|
+
}): Promise<number>;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `kody dev` ports: each package gets a stable default (so bookmarks, OAuth
|
|
3
|
+
* redirect URIs, and agent notes keep working across restarts) and walks up to
|
|
4
|
+
* the next free port when that one is taken. An explicit `--port` is honored
|
|
5
|
+
* exactly and fails with an actionable message instead.
|
|
6
|
+
*/
|
|
7
|
+
import { createHash } from 'node:crypto';
|
|
8
|
+
import { StructuredCliError } from '../structured-error.js';
|
|
9
|
+
export const devPortRange = { min: 4100, max: 4999 };
|
|
10
|
+
const fallbackAttempts = 20;
|
|
11
|
+
export function defaultDevPort(kodyId) {
|
|
12
|
+
const span = devPortRange.max - devPortRange.min + 1;
|
|
13
|
+
const hash = createHash('sha256').update(kodyId).digest();
|
|
14
|
+
return devPortRange.min + (hash.readUInt32BE(0) % span);
|
|
15
|
+
}
|
|
16
|
+
export function parseDevPort(raw) {
|
|
17
|
+
const port = /^\d+$/.test(raw.trim()) ? Number(raw) : Number.NaN;
|
|
18
|
+
if (!Number.isInteger(port) || port > 65_535) {
|
|
19
|
+
throw new StructuredCliError({
|
|
20
|
+
code: 'invalid_port',
|
|
21
|
+
message: `--port must be an integer from 0 to 65535 (got "${raw}").`,
|
|
22
|
+
fix: 'Pass --port 0 for any free port, or omit --port to use this package’s stable default.',
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
return port;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Listen on `port` exactly when `explicit`, otherwise on `port` or the next
|
|
29
|
+
* free port above it. Returns the bound port.
|
|
30
|
+
*/
|
|
31
|
+
export async function listenDevServer(server, input) {
|
|
32
|
+
const attempts = input.explicit || input.port === 0 ? 1 : fallbackAttempts;
|
|
33
|
+
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
|
34
|
+
const port = input.port === 0 ? 0 : wrapPort(input.port + attempt);
|
|
35
|
+
try {
|
|
36
|
+
await listenOnce(server, input.host, port);
|
|
37
|
+
return server.address().port;
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
if (!isAddressInUse(error))
|
|
41
|
+
throw error;
|
|
42
|
+
if (input.explicit)
|
|
43
|
+
throw portInUseError(input.host, port);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
throw new StructuredCliError({
|
|
47
|
+
code: 'dev_port_in_use',
|
|
48
|
+
message: `Ports ${input.port}–${wrapPort(input.port + attempts - 1)} on ${input.host} are all in use.`,
|
|
49
|
+
fix: 'Stop old `kody dev` processes, or pass --port 0 for any free port.',
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function portInUseError(host, port) {
|
|
53
|
+
return new StructuredCliError({
|
|
54
|
+
code: 'dev_port_in_use',
|
|
55
|
+
message: `Port ${port} on ${host} is already in use.`,
|
|
56
|
+
fix: `Find the owner with \`lsof -nP -iTCP:${port} -sTCP:LISTEN\` and stop it, pass another --port, or omit --port to use this package’s default (it moves to the next free port automatically).`,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function wrapPort(port) {
|
|
60
|
+
return port > 65_535 ? devPortRange.min + (port - 65_536) : port;
|
|
61
|
+
}
|
|
62
|
+
function listenOnce(server, host, port) {
|
|
63
|
+
return new Promise((resolve, reject) => {
|
|
64
|
+
const onError = (error) => {
|
|
65
|
+
server.off('listening', onListening);
|
|
66
|
+
reject(error);
|
|
67
|
+
};
|
|
68
|
+
const onListening = () => {
|
|
69
|
+
server.off('error', onError);
|
|
70
|
+
resolve();
|
|
71
|
+
};
|
|
72
|
+
server.once('error', onError);
|
|
73
|
+
server.once('listening', onListening);
|
|
74
|
+
server.listen(port, host);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function isAddressInUse(error) {
|
|
78
|
+
return error?.code === 'EADDRINUSE';
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=dev-port.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-port.js","sourceRoot":"","sources":["../../src/dev/dev-port.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `kody.dev.prebuild`: a shell command `kody dev` runs from the package root
|
|
3
|
+
* before every build, so generated assets (CSS, icons, data files) stay in
|
|
4
|
+
* sync with the source without a second watcher process.
|
|
5
|
+
*/
|
|
6
|
+
export declare class PrebuildError extends Error {
|
|
7
|
+
constructor(message: string);
|
|
8
|
+
}
|
|
9
|
+
export declare function runPrebuild(input: {
|
|
10
|
+
command: string;
|
|
11
|
+
cwd: string;
|
|
12
|
+
onSpawn?: (pid: number) => void;
|
|
13
|
+
onExit?: (pid: number) => void;
|
|
14
|
+
onLine?: (line: string, stream: 'stdout' | 'stderr') => void;
|
|
15
|
+
/** When aborted, the child is SIGKILLed so graceful `kody dev` shutdown is not blocked. */
|
|
16
|
+
signal?: AbortSignal;
|
|
17
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `kody.dev.prebuild`: a shell command `kody dev` runs from the package root
|
|
3
|
+
* before every build, so generated assets (CSS, icons, data files) stay in
|
|
4
|
+
* sync with the source without a second watcher process.
|
|
5
|
+
*/
|
|
6
|
+
import { spawn } from 'node:child_process';
|
|
7
|
+
import { apiTokenEnvVar } from '../defaults.js';
|
|
8
|
+
const outputTailLines = 20;
|
|
9
|
+
export class PrebuildError extends Error {
|
|
10
|
+
constructor(message) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.name = 'PrebuildError';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export async function runPrebuild(input) {
|
|
16
|
+
if (input.signal?.aborted) {
|
|
17
|
+
throw new PrebuildError('kody.dev.prebuild aborted before start');
|
|
18
|
+
}
|
|
19
|
+
const env = { ...process.env, KODY_DEV: '1' };
|
|
20
|
+
delete env[apiTokenEnvVar];
|
|
21
|
+
// New process group so abort can SIGKILL the whole tree (sh + npm/node/…).
|
|
22
|
+
const child = spawn('sh', ['-c', input.command], {
|
|
23
|
+
cwd: input.cwd,
|
|
24
|
+
env,
|
|
25
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
26
|
+
detached: true,
|
|
27
|
+
});
|
|
28
|
+
if (child.pid)
|
|
29
|
+
input.onSpawn?.(child.pid);
|
|
30
|
+
const tail = [];
|
|
31
|
+
const collect = (stream) => (line) => {
|
|
32
|
+
tail.push(line);
|
|
33
|
+
if (tail.length > outputTailLines)
|
|
34
|
+
tail.shift();
|
|
35
|
+
input.onLine?.(line, stream);
|
|
36
|
+
};
|
|
37
|
+
forEachLine(child.stdout, collect('stdout'));
|
|
38
|
+
forEachLine(child.stderr, collect('stderr'));
|
|
39
|
+
const killChild = () => {
|
|
40
|
+
if (child.exitCode !== null || child.signalCode !== null)
|
|
41
|
+
return;
|
|
42
|
+
const pid = child.pid;
|
|
43
|
+
if (pid === undefined)
|
|
44
|
+
return;
|
|
45
|
+
try {
|
|
46
|
+
process.kill(-pid, 'SIGKILL');
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
try {
|
|
50
|
+
child.kill('SIGKILL');
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// already gone
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
if (input.signal) {
|
|
58
|
+
if (input.signal.aborted)
|
|
59
|
+
killChild();
|
|
60
|
+
else
|
|
61
|
+
input.signal.addEventListener('abort', killChild, { once: true });
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
const result = await new Promise((resolve, reject) => {
|
|
65
|
+
child.once('error', reject);
|
|
66
|
+
child.once('close', (code, signal) => resolve({ code, signal }));
|
|
67
|
+
});
|
|
68
|
+
if (input.signal?.aborted) {
|
|
69
|
+
throw new PrebuildError('kody.dev.prebuild aborted');
|
|
70
|
+
}
|
|
71
|
+
if (result.code === 0)
|
|
72
|
+
return;
|
|
73
|
+
const how = result.signal ? `signal ${result.signal}` : `exit ${result.code}`;
|
|
74
|
+
throw new PrebuildError([`kody.dev.prebuild failed (${how}): ${input.command}`, ...tail.map((line) => ` ${line}`)].join('\n'));
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
input.signal?.removeEventListener('abort', killChild);
|
|
78
|
+
if (child.pid)
|
|
79
|
+
input.onExit?.(child.pid);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** Split stream chunks into lines, including a final incomplete line on end. */
|
|
83
|
+
function forEachLine(stream, onLine) {
|
|
84
|
+
if (!stream)
|
|
85
|
+
return;
|
|
86
|
+
let buffered = '';
|
|
87
|
+
stream.on('data', (chunk) => {
|
|
88
|
+
buffered += typeof chunk === 'string' ? chunk : chunk.toString('utf8');
|
|
89
|
+
const lines = buffered.split('\n');
|
|
90
|
+
buffered = lines.pop() ?? '';
|
|
91
|
+
for (const line of lines) {
|
|
92
|
+
if (line.length > 0)
|
|
93
|
+
onLine(line);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
stream.on('end', () => {
|
|
97
|
+
if (buffered.length > 0)
|
|
98
|
+
onLine(buffered);
|
|
99
|
+
buffered = '';
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=prebuild.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prebuild.js","sourceRoot":"","sources":["../../src/dev/prebuild.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,9 @@ export declare const devWorkDirPrefix = "kody-dev-";
|
|
|
11
11
|
export type ProcessReaper = {
|
|
12
12
|
track: (pid: number) => void;
|
|
13
13
|
untrack: (pid: number) => void;
|
|
14
|
+
/** Track a detached process-group leader; hard CLI death SIGKILLs the whole tree. */
|
|
15
|
+
trackGroup: (pid: number) => void;
|
|
16
|
+
untrackGroup: (pid: number) => void;
|
|
14
17
|
close: () => void;
|
|
15
18
|
};
|
|
16
19
|
export declare function startProcessReaper(input: {
|
|
@@ -24,7 +24,12 @@ while IFS= read -r line; do
|
|
|
24
24
|
-*) pids="$(printf '%s' "$pids" | sed "s/ \${line#-} / /g")" ;;
|
|
25
25
|
esac
|
|
26
26
|
done
|
|
27
|
-
for
|
|
27
|
+
for entry in $pids; do
|
|
28
|
+
case "$entry" in
|
|
29
|
+
g*) /bin/kill -s KILL -- -\${entry#g} 2>/dev/null ;;
|
|
30
|
+
*) /bin/kill -s KILL -- \$entry 2>/dev/null ;;
|
|
31
|
+
esac
|
|
32
|
+
done
|
|
28
33
|
rm -rf "$1"
|
|
29
34
|
`;
|
|
30
35
|
export async function startProcessReaper(input) {
|
|
@@ -52,6 +57,8 @@ export async function startProcessReaper(input) {
|
|
|
52
57
|
return {
|
|
53
58
|
track: (pid) => send(`+${pid}`),
|
|
54
59
|
untrack: (pid) => send(`-${pid}`),
|
|
60
|
+
trackGroup: (pid) => send(`+g${pid}`),
|
|
61
|
+
untrackGroup: (pid) => send(`-g${pid}`),
|
|
55
62
|
close: () => {
|
|
56
63
|
reaper?.stdin?.end();
|
|
57
64
|
reaper = undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-reaper.js","sourceRoot":"","sources":["../../src/dev/process-reaper.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,KAAK,EAAqB,MAAM,oBAAoB,CAAA;AAC7D,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACzE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,MAAM,MAAM,SAAS,CAAA;AAE5B,MAAM,CAAC,MAAM,gBAAgB,GAAG,WAAW,CAAA;AAC3C,MAAM,aAAa,GAAG,YAAY,CAAA;AAClC,wEAAwE;AACxE,MAAM,iBAAiB,GAAG,EAAE,GAAG,MAAM,CAAA;AAErC,MAAM,YAAY,GAAG
|
|
1
|
+
{"version":3,"file":"process-reaper.js","sourceRoot":"","sources":["../../src/dev/process-reaper.ts"],"names":[],"mappings":"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"}
|
package/dist/dev-command.d.ts
CHANGED
package/dist/dev-command.js
CHANGED
|
@@ -15,7 +15,9 @@ import { StructuredCliError } from './structured-error.js';
|
|
|
15
15
|
import { formatToolResult } from './tool-result.js';
|
|
16
16
|
import { bundleLocalUserModule } from './local-bundle.js';
|
|
17
17
|
import { formatDevEvent } from './dev/dev-events.js';
|
|
18
|
+
import { defaultDevPort } from './dev/dev-port.js';
|
|
18
19
|
import { devStatusPath, findRunningDevServer, removeDevRegistration, writeDevRegistration, } from './dev/dev-registry.js';
|
|
20
|
+
export { parseDevPort } from './dev/dev-port.js';
|
|
19
21
|
export async function resolveDevAuth(input) {
|
|
20
22
|
if (input.target !== 'mock') {
|
|
21
23
|
return {
|
|
@@ -55,29 +57,71 @@ export async function resolveDevAuth(input) {
|
|
|
55
57
|
}
|
|
56
58
|
export async function runDevServe(input) {
|
|
57
59
|
const manifest = await loadPackageManifest(input.cwd);
|
|
60
|
+
if (input.port === undefined) {
|
|
61
|
+
const running = await findRunningDevServer({ root: manifest.root, target: input.target });
|
|
62
|
+
if (running) {
|
|
63
|
+
const { registration } = running;
|
|
64
|
+
throw new StructuredCliError({
|
|
65
|
+
code: 'dev_already_running',
|
|
66
|
+
target: input.target,
|
|
67
|
+
message: `kody dev is already running for ${manifest.name} at ${registration.origin}${registration.basePath || '/'} (pid ${registration.pid}).`,
|
|
68
|
+
fix: `Reuse it (\`kody dev fetch <path>\` attaches automatically), stop it with \`kill ${registration.pid}\`, or pass --port to start a second server.`,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
58
72
|
const onEvent = input.json
|
|
59
73
|
? (event) => writeJsonEvent(input.io, event)
|
|
60
74
|
: (event) => writeDevEvent(input.io, event);
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
: input.auth.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
75
|
+
let registered = false;
|
|
76
|
+
let server;
|
|
77
|
+
try {
|
|
78
|
+
server = await startPackageAppDev({
|
|
79
|
+
manifest,
|
|
80
|
+
token: input.auth.token,
|
|
81
|
+
apiUrl: input.auth.apiUrl,
|
|
82
|
+
target: input.target,
|
|
83
|
+
port: input.port,
|
|
84
|
+
defaultPort: defaultDevPort(manifest.kodyId),
|
|
85
|
+
appBasePath: input.appBasePath,
|
|
86
|
+
...(input.auth.org ? { org: input.auth.org } : {}),
|
|
87
|
+
...(input.auth.depResolve ? { depResolve: input.auth.depResolve } : {}),
|
|
88
|
+
...(input.passthroughHosts?.length
|
|
89
|
+
? { passthroughHosts: input.passthroughHosts }
|
|
90
|
+
: input.auth.passthroughHosts?.length
|
|
91
|
+
? { passthroughHosts: input.auth.passthroughHosts }
|
|
92
|
+
: {}),
|
|
93
|
+
allowPrivateNetwork: input.allowPrivateNetwork,
|
|
94
|
+
liveReload: input.liveReload ?? true,
|
|
95
|
+
onStatus: (message) => input.io.stderr(`${message}\n`),
|
|
96
|
+
onError: (message) => input.io.stderr(`${message}\n`),
|
|
97
|
+
onEvent,
|
|
98
|
+
// Register as soon as the port is bound so a second `kody dev`
|
|
99
|
+
// during the first build hits `dev_already_running` instead of
|
|
100
|
+
// stealing the next free port and overwriting the registry.
|
|
101
|
+
// Explicit `--port` starts a second server on purpose — leave the
|
|
102
|
+
// primary attach registry alone so fetch keeps talking to it.
|
|
103
|
+
onListening: async ({ port, hostedUrl, appBasePath }) => {
|
|
104
|
+
if (input.port !== undefined)
|
|
105
|
+
return;
|
|
106
|
+
await writeDevRegistration({
|
|
107
|
+
pid: process.pid,
|
|
108
|
+
origin: hostedUrl,
|
|
109
|
+
port,
|
|
110
|
+
basePath: appBasePath,
|
|
111
|
+
target: input.target,
|
|
112
|
+
root: manifest.root,
|
|
113
|
+
});
|
|
114
|
+
registered = true;
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
if (registered) {
|
|
120
|
+
await removeDevRegistration(manifest.root, process.pid, input.target).catch(() => { });
|
|
121
|
+
}
|
|
122
|
+
await input.auth.closeMock?.();
|
|
123
|
+
throw error;
|
|
124
|
+
}
|
|
81
125
|
const shutdown = async () => {
|
|
82
126
|
await server.close();
|
|
83
127
|
await removeDevRegistration(manifest.root, process.pid, input.target).catch(() => { });
|
|
@@ -95,14 +139,6 @@ export async function runDevServe(input) {
|
|
|
95
139
|
pid: process.pid,
|
|
96
140
|
statusUrl,
|
|
97
141
|
};
|
|
98
|
-
await writeDevRegistration({
|
|
99
|
-
pid: process.pid,
|
|
100
|
-
origin: server.hostedUrl,
|
|
101
|
-
port: server.port,
|
|
102
|
-
basePath: server.appBasePath,
|
|
103
|
-
target: input.target,
|
|
104
|
-
root: manifest.root,
|
|
105
|
-
}).catch(() => { });
|
|
106
142
|
if (input.readyFile) {
|
|
107
143
|
await mkdir(dirname(input.readyFile), { recursive: true });
|
|
108
144
|
await writeFile(input.readyFile, `${JSON.stringify(ready, null, 2)}\n`);
|
|
@@ -127,7 +163,7 @@ export async function runDevServe(input) {
|
|
|
127
163
|
}
|
|
128
164
|
}
|
|
129
165
|
catch (error) {
|
|
130
|
-
// Ready-file
|
|
166
|
+
// Ready-file failures must not leave the listen handles up.
|
|
131
167
|
await shutdown().catch(() => { });
|
|
132
168
|
throw error;
|
|
133
169
|
}
|