@amodalai/amodal 0.2.10 → 0.3.1
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/CHANGELOG.md +29 -0
- package/dist/src/commands/dev.d.ts +6 -1
- package/dist/src/commands/dev.d.ts.map +1 -1
- package/dist/src/commands/dev.js +351 -21
- package/dist/src/commands/dev.js.map +1 -1
- package/dist/src/shared/env-resolution.d.ts +13 -0
- package/dist/src/shared/env-resolution.d.ts.map +1 -0
- package/dist/src/shared/env-resolution.js +54 -0
- package/dist/src/shared/env-resolution.js.map +1 -0
- package/dist/src/shared/find-free-port.d.ts +21 -0
- package/dist/src/shared/find-free-port.d.ts.map +1 -0
- package/dist/src/shared/find-free-port.js +62 -0
- package/dist/src/shared/find-free-port.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -5
- package/src/commands/dev.test.ts +96 -33
- package/src/commands/dev.ts +440 -19
- package/src/shared/env-resolution.test.ts +93 -0
- package/src/shared/env-resolution.ts +52 -0
- package/src/shared/find-free-port.ts +67 -0
- package/tsconfig.json +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# @amodalai/amodal
|
|
2
2
|
|
|
3
|
+
## 0.3.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#198](https://github.com/amodalai/amodal/pull/198) [`9833d69`](https://github.com/amodalai/amodal/commit/9833d696fb641d08f39fc3296f49a61c04350fe2) Thanks [@gte620v](https://github.com/gte620v)! - Publish `@amodalai/db` to npm. The 0.3.0 release of `@amodalai/runtime` and `@amodalai/amodal` declared a workspace dependency on `@amodalai/db@0.0.0`, which was never published (the package was `private: true`), causing `pnpm add -g @amodalai/amodal` to fail with an `ERR_PNPM_FETCH_404` on `@amodalai/db`. This release unprivate's the package, adds standard publish metadata, and brings it into the fixed version group so it is released in lockstep with the rest of the public packages.
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`9833d69`](https://github.com/amodalai/amodal/commit/9833d696fb641d08f39fc3296f49a61c04350fe2)]:
|
|
10
|
+
- @amodalai/db@0.3.1
|
|
11
|
+
- @amodalai/runtime@0.3.1
|
|
12
|
+
- @amodalai/types@0.3.1
|
|
13
|
+
- @amodalai/core@0.3.1
|
|
14
|
+
- @amodalai/runtime-app@0.3.1
|
|
15
|
+
|
|
16
|
+
## 0.3.0
|
|
17
|
+
|
|
18
|
+
### Minor Changes
|
|
19
|
+
|
|
20
|
+
- [#194](https://github.com/amodalai/amodal/pull/194) [`13723ff`](https://github.com/amodalai/amodal/commit/13723ff5be1e9983a1a66c697ec352d3a2dbfcd7) Thanks [@gte620v](https://github.com/gte620v)! - Studio standalone: separate Studio into its own Next.js service, strip admin code from runtime, add workspace tools, update CLI to spawn Studio + admin agent subprocesses
|
|
21
|
+
|
|
22
|
+
- [#194](https://github.com/amodalai/amodal/pull/194) [`13723ff`](https://github.com/amodalai/amodal/commit/13723ff5be1e9983a1a66c697ec352d3a2dbfcd7) Thanks [@gte620v](https://github.com/gte620v)! - Studio admin UI: move all admin/config/stores/automations/evals/feedback to Studio. Runtime-app is now chat + pages only. Postgres required (no PGLite). DATABASE_URL configuration via ~/.amodal/env or agent .env.
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- Updated dependencies [[`13723ff`](https://github.com/amodalai/amodal/commit/13723ff5be1e9983a1a66c697ec352d3a2dbfcd7), [`13723ff`](https://github.com/amodalai/amodal/commit/13723ff5be1e9983a1a66c697ec352d3a2dbfcd7)]:
|
|
27
|
+
- @amodalai/core@0.3.0
|
|
28
|
+
- @amodalai/runtime@0.3.0
|
|
29
|
+
- @amodalai/types@0.3.0
|
|
30
|
+
- @amodalai/runtime-app@0.3.0
|
|
31
|
+
|
|
3
32
|
## 0.2.10
|
|
4
33
|
|
|
5
34
|
### Patch Changes
|
|
@@ -11,9 +11,14 @@ export interface DevOptions {
|
|
|
11
11
|
resume?: string;
|
|
12
12
|
verbose?: number;
|
|
13
13
|
quiet?: boolean;
|
|
14
|
+
/** Disable Studio subprocess. */
|
|
15
|
+
noStudio?: boolean;
|
|
16
|
+
/** Disable admin agent subprocess. */
|
|
17
|
+
noAdmin?: boolean;
|
|
14
18
|
}
|
|
15
19
|
/**
|
|
16
|
-
* Starts a local development server for the repo with hot reload enabled
|
|
20
|
+
* Starts a local development server for the repo with hot reload enabled,
|
|
21
|
+
* and optionally spawns Studio and admin agent as subprocesses.
|
|
17
22
|
*/
|
|
18
23
|
export declare function runDev(options?: DevOptions): Promise<void>;
|
|
19
24
|
export declare const devCommand: CommandModule;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../../src/commands/dev.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../../src/commands/dev.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,OAAO,CAAC;AAwDzC,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sCAAsC;IACtC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAmOD;;;GAGG;AACH,wBAAsB,MAAM,CAAC,OAAO,GAAE,UAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAoOpE;AAED,eAAO,MAAM,UAAU,EAAE,aAwDxB,CAAC"}
|
package/dist/src/commands/dev.js
CHANGED
|
@@ -5,14 +5,214 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { existsSync, readFileSync } from 'node:fs';
|
|
7
7
|
import { createRequire } from 'node:module';
|
|
8
|
+
import { spawn } from 'node:child_process';
|
|
8
9
|
import path from 'node:path';
|
|
9
10
|
import { fileURLToPath } from 'node:url';
|
|
10
|
-
import { createLocalServer, initLogLevel, interceptConsole } from '@amodalai/runtime';
|
|
11
|
+
import { createLocalServer, initLogLevel, interceptConsole, log } from '@amodalai/runtime';
|
|
12
|
+
import { resolveAdminAgent } from '@amodalai/core';
|
|
11
13
|
import { findRepoRoot } from '../shared/repo-discovery.js';
|
|
14
|
+
import { findFreePort } from '../shared/find-free-port.js';
|
|
12
15
|
import { runConnectionPreflight, printPreflightTable } from '../shared/connection-preflight.js';
|
|
13
|
-
|
|
16
|
+
import { resolveEnv } from '../shared/env-resolution.js';
|
|
17
|
+
import { getDb, ensureSchema, closeDb } from '@amodalai/db';
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Constants
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
const DEFAULT_RUNTIME_PORT = 3847;
|
|
22
|
+
const DEFAULT_STUDIO_PORT = 3848;
|
|
23
|
+
const DEFAULT_ADMIN_PORT = 3849;
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
// Studio resolution
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
14
27
|
/**
|
|
15
|
-
*
|
|
28
|
+
* Locate the @amodalai/studio package directory. Two strategies:
|
|
29
|
+
* 1. Sibling directory relative to the CLI package (works when symlinked)
|
|
30
|
+
* 2. Node module resolution via createRequire (works when installed)
|
|
31
|
+
*/
|
|
32
|
+
function resolveStudioDir() {
|
|
33
|
+
// scriptDir is packages/cli/dist/src/commands/ at runtime (or packages/cli/src/commands/ in source)
|
|
34
|
+
// CLI package root is 3 levels up, then ../studio is the sibling package
|
|
35
|
+
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
|
36
|
+
const cliRoot = path.resolve(scriptDir, '..', '..', '..');
|
|
37
|
+
const siblingCandidate = path.resolve(cliRoot, '..', 'studio');
|
|
38
|
+
if (existsSync(path.join(siblingCandidate, 'package.json'))) {
|
|
39
|
+
return siblingCandidate;
|
|
40
|
+
}
|
|
41
|
+
const require = createRequire(import.meta.url);
|
|
42
|
+
try {
|
|
43
|
+
return path.dirname(require.resolve('@amodalai/studio/package.json'));
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
log.debug('studio_resolve_failed', {
|
|
47
|
+
error: err instanceof Error ? err.message : String(err),
|
|
48
|
+
});
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Pipe a child process's stdout/stderr to the parent's stderr, prefixed
|
|
54
|
+
* with a label. Lines are buffered per-stream to avoid interleaved output
|
|
55
|
+
* from concurrent subprocesses.
|
|
56
|
+
*/
|
|
57
|
+
function pipeWithLabel(child, label) {
|
|
58
|
+
const prefix = `[${label}] `;
|
|
59
|
+
for (const stream of [child.stdout, child.stderr]) {
|
|
60
|
+
if (!stream)
|
|
61
|
+
continue;
|
|
62
|
+
let buffer = '';
|
|
63
|
+
stream.setEncoding('utf-8');
|
|
64
|
+
stream.on('data', (chunk) => {
|
|
65
|
+
buffer += chunk;
|
|
66
|
+
const lines = buffer.split('\n');
|
|
67
|
+
// Keep the last (potentially incomplete) line in the buffer
|
|
68
|
+
buffer = lines.pop() ?? '';
|
|
69
|
+
for (const line of lines) {
|
|
70
|
+
process.stderr.write(`${prefix}${line}\n`);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
stream.on('end', () => {
|
|
74
|
+
if (buffer.length > 0) {
|
|
75
|
+
process.stderr.write(`${prefix}${buffer}\n`);
|
|
76
|
+
buffer = '';
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Kill all managed subprocesses. Returns once all processes have exited
|
|
83
|
+
* or after a 5-second timeout (whichever comes first).
|
|
84
|
+
*/
|
|
85
|
+
async function killAll(processes) {
|
|
86
|
+
const KILL_TIMEOUT_MS = 5000;
|
|
87
|
+
const exitPromises = [];
|
|
88
|
+
for (const { child, label } of processes) {
|
|
89
|
+
if (child.exitCode !== null)
|
|
90
|
+
continue; // already exited
|
|
91
|
+
exitPromises.push(new Promise((resolve) => {
|
|
92
|
+
const timer = setTimeout(() => {
|
|
93
|
+
log.warn('subprocess_kill_timeout', { label });
|
|
94
|
+
child.kill('SIGKILL');
|
|
95
|
+
resolve();
|
|
96
|
+
}, KILL_TIMEOUT_MS);
|
|
97
|
+
child.once('exit', () => {
|
|
98
|
+
clearTimeout(timer);
|
|
99
|
+
resolve();
|
|
100
|
+
});
|
|
101
|
+
child.kill('SIGTERM');
|
|
102
|
+
}));
|
|
103
|
+
}
|
|
104
|
+
await Promise.all(exitPromises);
|
|
105
|
+
}
|
|
106
|
+
function spawnStudio(opts) {
|
|
107
|
+
// Resolve @amodalai/studio package directory. Try two strategies:
|
|
108
|
+
// 1. Sibling directory relative to the CLI package (works when symlinked from outside)
|
|
109
|
+
// 2. Node module resolution via createRequire (works when installed as a dependency)
|
|
110
|
+
const studioDir = resolveStudioDir();
|
|
111
|
+
if (!studioDir) {
|
|
112
|
+
log.info('studio_not_available', {
|
|
113
|
+
hint: '@amodalai/studio package not found — Studio subprocess skipped',
|
|
114
|
+
});
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
// Resolve the `next` binary from the studio-app's dependency tree.
|
|
118
|
+
// In pnpm the binary may live in the package's own node_modules or in a
|
|
119
|
+
// hoisted location; createRequire resolves correctly in both cases.
|
|
120
|
+
let nextBin;
|
|
121
|
+
try {
|
|
122
|
+
const studioRequire = createRequire(path.join(studioDir, 'package.json'));
|
|
123
|
+
// next/dist/bin/next is the actual CLI entrypoint
|
|
124
|
+
nextBin = studioRequire.resolve('next/dist/bin/next');
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
log.info('studio_next_not_found', {
|
|
128
|
+
hint: 'next binary not resolvable from @amodalai/studio — Studio subprocess skipped',
|
|
129
|
+
});
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
const studioUrl = `http://localhost:${String(opts.port)}`;
|
|
133
|
+
const child = spawn(process.execPath, [nextBin, 'dev', '--port', String(opts.port)], {
|
|
134
|
+
cwd: studioDir,
|
|
135
|
+
env: {
|
|
136
|
+
...process.env,
|
|
137
|
+
REPO_PATH: opts.repoPath,
|
|
138
|
+
STUDIO_CORS_ORIGINS: `http://localhost:${String(opts.runtimePort)}`,
|
|
139
|
+
RUNTIME_URL: `http://localhost:${String(opts.runtimePort)}`,
|
|
140
|
+
PORT: String(opts.port),
|
|
141
|
+
...(opts.agentId ? { AGENT_ID: opts.agentId } : {}),
|
|
142
|
+
},
|
|
143
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
144
|
+
});
|
|
145
|
+
child.once('error', (err) => {
|
|
146
|
+
log.warn('studio_spawn_error', { error: err.message });
|
|
147
|
+
});
|
|
148
|
+
const label = 'studio';
|
|
149
|
+
pipeWithLabel(child, label);
|
|
150
|
+
child.once('exit', (code, signal) => {
|
|
151
|
+
if (code !== null && code !== 0) {
|
|
152
|
+
log.warn('subprocess_exited', { label, code });
|
|
153
|
+
}
|
|
154
|
+
else if (signal) {
|
|
155
|
+
log.debug('subprocess_signaled', { label, signal });
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
return {
|
|
159
|
+
process: { label, child },
|
|
160
|
+
url: studioUrl,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
async function spawnAdminAgent(opts) {
|
|
164
|
+
const adminAgentPath = await resolveAdminAgent(opts.repoPath);
|
|
165
|
+
if (!adminAgentPath) {
|
|
166
|
+
log.info('admin_agent_not_available', {
|
|
167
|
+
hint: 'No admin agent found at ~/.amodal/admin-agent/ or in amodal.json — skipped',
|
|
168
|
+
});
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
// Verify it has an amodal.json (is a valid agent directory)
|
|
172
|
+
if (!existsSync(path.join(adminAgentPath, 'amodal.json'))) {
|
|
173
|
+
log.warn('admin_agent_invalid', {
|
|
174
|
+
path: adminAgentPath,
|
|
175
|
+
hint: 'Directory exists but has no amodal.json — skipped',
|
|
176
|
+
});
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
// Resolve the CLI entrypoint. We're running inside the CLI already, so
|
|
180
|
+
// use the same executable to spawn the admin agent's dev server.
|
|
181
|
+
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
|
182
|
+
const cliEntrypoint = path.resolve(scriptDir, '..', 'main.js');
|
|
183
|
+
const adminUrl = `http://localhost:${String(opts.port)}`;
|
|
184
|
+
const env = {
|
|
185
|
+
...process.env,
|
|
186
|
+
};
|
|
187
|
+
if (opts.studioUrl) {
|
|
188
|
+
env['STUDIO_URL'] = opts.studioUrl;
|
|
189
|
+
}
|
|
190
|
+
const child = spawn(process.execPath, [cliEntrypoint, 'dev', '--port', String(opts.port)], {
|
|
191
|
+
cwd: adminAgentPath,
|
|
192
|
+
env,
|
|
193
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
194
|
+
});
|
|
195
|
+
const label = 'admin';
|
|
196
|
+
pipeWithLabel(child, label);
|
|
197
|
+
child.once('exit', (code, signal) => {
|
|
198
|
+
if (code !== null && code !== 0) {
|
|
199
|
+
log.warn('subprocess_exited', { label, code });
|
|
200
|
+
}
|
|
201
|
+
else if (signal) {
|
|
202
|
+
log.debug('subprocess_signaled', { label, signal });
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
return {
|
|
206
|
+
process: { label, child },
|
|
207
|
+
url: adminUrl,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
// ---------------------------------------------------------------------------
|
|
211
|
+
// Main dev command
|
|
212
|
+
// ---------------------------------------------------------------------------
|
|
213
|
+
/**
|
|
214
|
+
* Starts a local development server for the repo with hot reload enabled,
|
|
215
|
+
* and optionally spawns Studio and admin agent as subprocesses.
|
|
16
216
|
*/
|
|
17
217
|
export async function runDev(options = {}) {
|
|
18
218
|
initLogLevel({ verbosity: options.verbose ?? 0, quiet: options.quiet ?? false });
|
|
@@ -26,26 +226,120 @@ export async function runDev(options = {}) {
|
|
|
26
226
|
process.stderr.write(`[dev] ${msg}\n`);
|
|
27
227
|
process.exit(1);
|
|
28
228
|
}
|
|
29
|
-
//
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
229
|
+
// -------------------------------------------------------------------------
|
|
230
|
+
// Require DATABASE_URL
|
|
231
|
+
// -------------------------------------------------------------------------
|
|
232
|
+
const databaseUrl = resolveEnv('DATABASE_URL', repoPath);
|
|
233
|
+
if (!databaseUrl) {
|
|
234
|
+
log.error('database_url_required', {});
|
|
235
|
+
process.stderr.write(`
|
|
236
|
+
DATABASE_URL is required. Start Postgres and configure it:
|
|
237
|
+
|
|
238
|
+
docker run -d --name amodal-pg -p 5432:5432 \\
|
|
239
|
+
-e POSTGRES_DB=amodal -e POSTGRES_HOST_AUTH_METHOD=trust postgres:17
|
|
240
|
+
|
|
241
|
+
Then set the connection string:
|
|
242
|
+
|
|
243
|
+
echo 'DATABASE_URL=postgres://localhost:5432/amodal' >> ~/.amodal/.env
|
|
244
|
+
|
|
245
|
+
Or add it to your agent's .env file:
|
|
246
|
+
|
|
247
|
+
echo 'DATABASE_URL=postgres://localhost:5432/amodal' >> .env
|
|
248
|
+
|
|
249
|
+
`);
|
|
250
|
+
process.exit(1);
|
|
251
|
+
}
|
|
252
|
+
// Make DATABASE_URL available to child processes (runtime, Studio)
|
|
253
|
+
process.env['DATABASE_URL'] = databaseUrl;
|
|
254
|
+
// Read agent name from amodal.json for AGENT_ID
|
|
255
|
+
const amodalJsonPath = path.join(repoPath, 'amodal.json');
|
|
256
|
+
let agentId;
|
|
257
|
+
if (existsSync(amodalJsonPath)) {
|
|
258
|
+
try {
|
|
259
|
+
const amodalJson = JSON.parse(readFileSync(amodalJsonPath, 'utf-8'));
|
|
260
|
+
const parsed = typeof amodalJson === 'object' && amodalJson !== null
|
|
261
|
+
? amodalJson
|
|
262
|
+
: undefined;
|
|
263
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- JSON.parse boundary: validated with typeof guard above
|
|
264
|
+
const nameValue = parsed !== undefined ? parsed['name'] : undefined;
|
|
265
|
+
if (typeof nameValue === 'string') {
|
|
266
|
+
agentId = nameValue;
|
|
267
|
+
process.env['AGENT_ID'] = agentId;
|
|
44
268
|
}
|
|
45
269
|
}
|
|
270
|
+
catch (err) {
|
|
271
|
+
log.warn('amodal_json_parse_error', {
|
|
272
|
+
path: amodalJsonPath,
|
|
273
|
+
error: err instanceof Error ? err.message : String(err),
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
// -------------------------------------------------------------------------
|
|
278
|
+
// Run schema migrations
|
|
279
|
+
// -------------------------------------------------------------------------
|
|
280
|
+
try {
|
|
281
|
+
const migrationDb = getDb(databaseUrl);
|
|
282
|
+
await ensureSchema(migrationDb);
|
|
283
|
+
await closeDb(); // Close migration connection — runtime and Studio open their own
|
|
284
|
+
log.info('schema_migration_complete', {});
|
|
285
|
+
}
|
|
286
|
+
catch (err) {
|
|
287
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
288
|
+
log.error('schema_migration_failed', { error: msg });
|
|
289
|
+
process.stderr.write(`[dev] Failed to run database migrations: ${msg}\n`);
|
|
290
|
+
process.stderr.write('[dev] Is Postgres running and DATABASE_URL correct?\n');
|
|
291
|
+
process.exit(1);
|
|
46
292
|
}
|
|
47
|
-
const port = options.port ?? DEFAULT_PORT;
|
|
48
293
|
const host = options.host ?? '0.0.0.0';
|
|
294
|
+
// -------------------------------------------------------------------------
|
|
295
|
+
// Port allocation
|
|
296
|
+
// -------------------------------------------------------------------------
|
|
297
|
+
const runtimePort = await findFreePort(options.port ?? DEFAULT_RUNTIME_PORT);
|
|
298
|
+
const studioPort = options.noStudio
|
|
299
|
+
? DEFAULT_STUDIO_PORT
|
|
300
|
+
: await findFreePort(DEFAULT_STUDIO_PORT);
|
|
301
|
+
const adminPort = options.noAdmin
|
|
302
|
+
? DEFAULT_ADMIN_PORT
|
|
303
|
+
: await findFreePort(DEFAULT_ADMIN_PORT);
|
|
304
|
+
log.info('ports_allocated', {
|
|
305
|
+
runtime: runtimePort,
|
|
306
|
+
studio: options.noStudio ? null : studioPort,
|
|
307
|
+
admin: options.noAdmin ? null : adminPort,
|
|
308
|
+
});
|
|
309
|
+
// -------------------------------------------------------------------------
|
|
310
|
+
// Spawn subprocesses
|
|
311
|
+
// -------------------------------------------------------------------------
|
|
312
|
+
const managedProcesses = [];
|
|
313
|
+
let studioUrl = null;
|
|
314
|
+
let adminAgentUrl = null;
|
|
315
|
+
// Studio
|
|
316
|
+
if (!options.noStudio) {
|
|
317
|
+
const studioResult = spawnStudio({
|
|
318
|
+
port: studioPort,
|
|
319
|
+
runtimePort,
|
|
320
|
+
repoPath,
|
|
321
|
+
agentId,
|
|
322
|
+
});
|
|
323
|
+
if (studioResult) {
|
|
324
|
+
managedProcesses.push(studioResult.process);
|
|
325
|
+
studioUrl = studioResult.url;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
// Admin agent
|
|
329
|
+
if (!options.noAdmin) {
|
|
330
|
+
const adminResult = await spawnAdminAgent({
|
|
331
|
+
port: adminPort,
|
|
332
|
+
studioUrl,
|
|
333
|
+
repoPath,
|
|
334
|
+
});
|
|
335
|
+
if (adminResult) {
|
|
336
|
+
managedProcesses.push(adminResult.process);
|
|
337
|
+
adminAgentUrl = adminResult.url;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
// -------------------------------------------------------------------------
|
|
341
|
+
// Start the runtime server
|
|
342
|
+
// -------------------------------------------------------------------------
|
|
49
343
|
process.stderr.write(`[dev] Starting dev server for ${repoPath}\n`);
|
|
50
344
|
try {
|
|
51
345
|
let staticAppDir;
|
|
@@ -69,14 +363,27 @@ export async function runDev(options = {}) {
|
|
|
69
363
|
}
|
|
70
364
|
const server = await createLocalServer({
|
|
71
365
|
repoPath,
|
|
72
|
-
port,
|
|
366
|
+
port: runtimePort,
|
|
73
367
|
host,
|
|
74
368
|
hotReload: true,
|
|
75
369
|
corsOrigin: '*',
|
|
76
370
|
staticAppDir,
|
|
77
371
|
resumeSessionId: options.resume,
|
|
372
|
+
studioUrl: studioUrl ?? undefined,
|
|
373
|
+
adminAgentUrl: adminAgentUrl ?? undefined,
|
|
78
374
|
});
|
|
79
375
|
await server.start();
|
|
376
|
+
// Print all URLs
|
|
377
|
+
process.stderr.write('\n');
|
|
378
|
+
process.stderr.write(` Runtime: http://localhost:${String(runtimePort)}\n`);
|
|
379
|
+
if (studioUrl) {
|
|
380
|
+
process.stderr.write(` Studio: ${studioUrl}\n`);
|
|
381
|
+
}
|
|
382
|
+
if (adminAgentUrl) {
|
|
383
|
+
process.stderr.write(` Admin Agent: ${adminAgentUrl}\n`);
|
|
384
|
+
}
|
|
385
|
+
process.stderr.write(` Database: ${databaseUrl}\n`);
|
|
386
|
+
process.stderr.write('\n');
|
|
80
387
|
// Preflight connection check (non-blocking)
|
|
81
388
|
const preflight = await runConnectionPreflight(repoPath);
|
|
82
389
|
if (preflight.results.length > 0) {
|
|
@@ -90,6 +397,11 @@ export async function runDev(options = {}) {
|
|
|
90
397
|
// Graceful shutdown
|
|
91
398
|
const shutdown = async (signal) => {
|
|
92
399
|
process.stderr.write(`\n[dev] Received ${signal}, shutting down...\n`);
|
|
400
|
+
// Kill subprocesses first
|
|
401
|
+
if (managedProcesses.length > 0) {
|
|
402
|
+
log.info('subprocess_shutdown', { count: managedProcesses.length });
|
|
403
|
+
await killAll(managedProcesses);
|
|
404
|
+
}
|
|
93
405
|
await server.stop();
|
|
94
406
|
process.exit(0);
|
|
95
407
|
};
|
|
@@ -97,6 +409,10 @@ export async function runDev(options = {}) {
|
|
|
97
409
|
process.on('SIGINT', () => void shutdown('SIGINT'));
|
|
98
410
|
}
|
|
99
411
|
catch (err) {
|
|
412
|
+
// Kill any already-spawned subprocesses before exiting
|
|
413
|
+
if (managedProcesses.length > 0) {
|
|
414
|
+
await killAll(managedProcesses);
|
|
415
|
+
}
|
|
100
416
|
const msg = err instanceof Error ? err.message : String(err);
|
|
101
417
|
process.stderr.write(`[dev] Failed to start: ${msg}\n`);
|
|
102
418
|
process.exit(1);
|
|
@@ -130,6 +446,16 @@ export const devCommand = {
|
|
|
130
446
|
describe: 'Only show errors',
|
|
131
447
|
default: false,
|
|
132
448
|
},
|
|
449
|
+
'no-studio': {
|
|
450
|
+
type: 'boolean',
|
|
451
|
+
describe: 'Do not spawn Studio subprocess',
|
|
452
|
+
default: false,
|
|
453
|
+
},
|
|
454
|
+
'no-admin': {
|
|
455
|
+
type: 'boolean',
|
|
456
|
+
describe: 'Do not spawn admin agent subprocess',
|
|
457
|
+
default: false,
|
|
458
|
+
},
|
|
133
459
|
},
|
|
134
460
|
handler: async (argv) => {
|
|
135
461
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
@@ -142,7 +468,11 @@ export const devCommand = {
|
|
|
142
468
|
const verbose = argv['verbose'];
|
|
143
469
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
144
470
|
const quiet = argv['quiet'];
|
|
145
|
-
|
|
471
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
472
|
+
const noStudio = argv['no-studio'];
|
|
473
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
474
|
+
const noAdmin = argv['no-admin'];
|
|
475
|
+
await runDev({ port, host, resume, verbose, quiet, noStudio, noAdmin });
|
|
146
476
|
},
|
|
147
477
|
};
|
|
148
478
|
//# sourceMappingURL=dev.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../../src/commands/dev.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../../src/commands/dev.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Amodal Labs, Inc.
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Resolve a config value from (in priority order):
|
|
8
|
+
* 1. Agent .env file (cwd/.env)
|
|
9
|
+
* 2. Global ~/.amodal/env
|
|
10
|
+
* 3. Shell environment (process.env)
|
|
11
|
+
*/
|
|
12
|
+
export declare function resolveEnv(key: string, cwd: string): string | undefined;
|
|
13
|
+
//# sourceMappingURL=env-resolution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-resolution.d.ts","sourceRoot":"","sources":["../../../src/shared/env-resolution.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAavE"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Amodal Labs, Inc.
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import os from 'node:os';
|
|
9
|
+
/**
|
|
10
|
+
* Resolve a config value from (in priority order):
|
|
11
|
+
* 1. Agent .env file (cwd/.env)
|
|
12
|
+
* 2. Global ~/.amodal/env
|
|
13
|
+
* 3. Shell environment (process.env)
|
|
14
|
+
*/
|
|
15
|
+
export function resolveEnv(key, cwd) {
|
|
16
|
+
// 1. Agent .env
|
|
17
|
+
const agentEnvPath = path.join(cwd, '.env');
|
|
18
|
+
const agentValue = readEnvFile(agentEnvPath, key);
|
|
19
|
+
if (agentValue !== undefined)
|
|
20
|
+
return agentValue;
|
|
21
|
+
// 2. Global ~/.amodal/.env
|
|
22
|
+
const globalEnvPath = path.join(os.homedir(), '.amodal', '.env');
|
|
23
|
+
const globalValue = readEnvFile(globalEnvPath, key);
|
|
24
|
+
if (globalValue !== undefined)
|
|
25
|
+
return globalValue;
|
|
26
|
+
// 3. Shell environment
|
|
27
|
+
return process.env[key];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Read a single key from a .env-style file. Returns undefined if the file
|
|
31
|
+
* does not exist, cannot be read, or does not contain the key.
|
|
32
|
+
*/
|
|
33
|
+
function readEnvFile(filePath, key) {
|
|
34
|
+
if (!existsSync(filePath))
|
|
35
|
+
return undefined;
|
|
36
|
+
try {
|
|
37
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
38
|
+
for (const line of content.split('\n')) {
|
|
39
|
+
const trimmed = line.trim();
|
|
40
|
+
if (trimmed.startsWith('#') || !trimmed.includes('='))
|
|
41
|
+
continue;
|
|
42
|
+
const eqIndex = trimmed.indexOf('=');
|
|
43
|
+
const k = trimmed.slice(0, eqIndex).trim();
|
|
44
|
+
const v = trimmed.slice(eqIndex + 1).trim().replace(/^["']|["']$/g, '');
|
|
45
|
+
if (k === key)
|
|
46
|
+
return v;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=env-resolution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-resolution.js","sourceRoot":"","sources":["../../../src/shared/env-resolution.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,GAAW;IACjD,gBAAgB;IAChB,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC5C,MAAM,UAAU,GAAG,WAAW,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;IAClD,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO,UAAU,CAAC;IAEhD,2BAA2B;IAC3B,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IACjE,MAAM,WAAW,GAAG,WAAW,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;IACpD,IAAI,WAAW,KAAK,SAAS;QAAE,OAAO,WAAW,CAAC;IAElD,uBAAuB;IACvB,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED;;;GAGG;AACH,SAAS,WAAW,CAAC,QAAgB,EAAE,GAAW;IAChD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,SAAS,CAAC;IAC5C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAChD,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,SAAS;YAChE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACrC,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;YAC3C,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;YACxE,IAAI,CAAC,KAAK,GAAG;gBAAE,OAAO,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Amodal Labs, Inc.
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Find a free TCP port, starting from `preferred`. If `preferred` is taken,
|
|
8
|
+
* tries incrementally higher ports up to `preferred + maxAttempts`.
|
|
9
|
+
*
|
|
10
|
+
* Uses the "bind then close" technique: creates a TCP server on the candidate
|
|
11
|
+
* port, reads the actual assigned port, then closes the server. This avoids
|
|
12
|
+
* TOCTOU races better than simply checking if a port is open — the OS reserves
|
|
13
|
+
* the port for the brief lifetime of the server.
|
|
14
|
+
*/
|
|
15
|
+
export declare function findFreePort(preferred: number, maxAttempts?: number): Promise<number>;
|
|
16
|
+
export declare class PortAllocationError extends Error {
|
|
17
|
+
readonly preferred: number;
|
|
18
|
+
readonly maxAttempts: number;
|
|
19
|
+
constructor(preferred: number, maxAttempts: number);
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=find-free-port.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find-free-port.d.ts","sourceRoot":"","sources":["../../../src/shared/find-free-port.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,SAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAUvF;AA0BD,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;gBAEjB,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;CASnD"}
|