ugly-app 0.1.422 → 0.1.424
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/cli/build.d.ts.map +1 -1
- package/dist/cli/build.js +9 -2
- package/dist/cli/build.js.map +1 -1
- package/dist/cli/dev.d.ts.map +1 -1
- package/dist/cli/dev.js +101 -70
- package/dist/cli/dev.js.map +1 -1
- package/dist/cli/resolveBin.d.ts +23 -0
- package/dist/cli/resolveBin.d.ts.map +1 -0
- package/dist/cli/resolveBin.js +51 -0
- package/dist/cli/resolveBin.js.map +1 -0
- package/dist/cli/version.d.ts +1 -1
- package/dist/cli/version.js +1 -1
- package/dist/shared/FrameworkRequests.d.ts +2 -2
- package/package.json +1 -1
- package/src/cli/build.ts +21 -5
- package/src/cli/dev.ts +118 -75
- package/src/cli/resolveBin.ts +57 -0
- package/src/cli/version.ts +1 -1
package/dist/cli/build.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/cli/build.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/cli/build.ts"],"names":[],"mappings":"AAOA,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAiF9C"}
|
package/dist/cli/build.js
CHANGED
|
@@ -2,6 +2,7 @@ import { execSync } from 'child_process';
|
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import { runExportCollections } from './exportCollections.js';
|
|
5
|
+
import { nodeBinCommand } from './resolveBin.js';
|
|
5
6
|
import { runExportWorkers } from './workerGen.js';
|
|
6
7
|
export async function runBuild() {
|
|
7
8
|
// Emit database-collections.json first. Fast, pure TS import — fails
|
|
@@ -27,9 +28,15 @@ export const buildId = '${buildId}';
|
|
|
27
28
|
fs.rmSync(distDir, { recursive: true, force: true });
|
|
28
29
|
console.log('[Build] Cleaned dist/');
|
|
29
30
|
}
|
|
30
|
-
// Run vite build
|
|
31
|
+
// Run vite build. `npx vite build` does not work in pnpm-strict
|
|
32
|
+
// worktrees (vite is hoisted into `.pnpm/...` and not linked to
|
|
33
|
+
// top-level `.bin/`); resolve the bin path through Node module
|
|
34
|
+
// resolution instead. Same for esbuild + tsc below.
|
|
31
35
|
console.log('[Build] Running vite build...');
|
|
32
|
-
execSync('
|
|
36
|
+
execSync(nodeBinCommand('vite', 'build'), {
|
|
37
|
+
stdio: 'inherit',
|
|
38
|
+
cwd: process.cwd(),
|
|
39
|
+
});
|
|
33
40
|
// Bundle server with esbuild (only for simple projects without custom server build)
|
|
34
41
|
const serverEntry = path.join(process.cwd(), 'server', 'index.ts');
|
|
35
42
|
const hasCustomServerBuild = fs.existsSync(path.join(process.cwd(), 'vite.config.server.js'));
|
package/dist/cli/build.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/cli/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,qEAAqE;IACrE,wEAAwE;IACxE,MAAM,oBAAoB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC1C,MAAM,gBAAgB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAEtC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAEnC,wBAAwB;IACxB,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;IACrE,MAAM,gBAAgB,GAAG;0BACD,OAAO;CAChC,CAAC;IAEA,4BAA4B;IAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAC9C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,EAAE,CAAC,aAAa,CAAC,aAAa,EAAE,gBAAgB,EAAE,OAAO,CAAC,CAAC;IAC3D,OAAO,CAAC,GAAG,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;IAE3C,8BAA8B;IAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;IACjD,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;IACvC,CAAC;IAED,
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/cli/build.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/dev.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/cli/dev.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/cli/dev.ts"],"names":[],"mappings":"AA4DA,wBAAsB,MAAM,CAAC,IAAI,GAAE;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAqC,GAAG,OAAO,CAAC,IAAI,CAAC,CA6MzH"}
|
package/dist/cli/dev.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { exec, execSync
|
|
1
|
+
import { exec, execSync } from 'child_process';
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import net from 'net';
|
|
4
4
|
import path from 'path';
|
|
5
|
+
import { createRequire } from 'module';
|
|
6
|
+
import concurrently from 'concurrently';
|
|
5
7
|
/**
|
|
6
8
|
* Return the PID of the process listening on `port`, or null if none.
|
|
7
9
|
* Cross-platform; shells out to `lsof` on Unix and `netstat` on Windows.
|
|
@@ -127,79 +129,108 @@ export async function runDev(opts = { watch: false, verbose: false }) {
|
|
|
127
129
|
console.log(`[ugly-app] NODE_ENV: ${process.env['NODE_ENV']}`);
|
|
128
130
|
console.log(`[ugly-app] POSTGRES_URL: ${process.env['POSTGRES_URL'] ?? '(default)'}`);
|
|
129
131
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
].filter(Boolean).join(' ')
|
|
159
|
-
: [
|
|
160
|
-
bin('concurrently'),
|
|
161
|
-
'--names server',
|
|
162
|
-
'--prefix-colors green',
|
|
163
|
-
rawFlag,
|
|
164
|
-
'--kill-others-on-fail',
|
|
165
|
-
'--handle-input',
|
|
166
|
-
q(serverCmd),
|
|
167
|
-
].filter(Boolean).join(' ');
|
|
168
|
-
if (verbose) {
|
|
169
|
-
console.log(`[ugly-app] Spawning: ${cmd}`);
|
|
132
|
+
const isWin = process.platform === 'win32';
|
|
133
|
+
const noFail = (cmd) => isWin ? `(${cmd} || (exit /b 0))` : `${cmd} || true`;
|
|
134
|
+
// Resolve a tool's executable JS entry through the project's
|
|
135
|
+
// node_modules graph rather than assuming it's hoisted to
|
|
136
|
+
// `node_modules/.bin/`. Under pnpm-strict, transitive bins (e.g.
|
|
137
|
+
// `concurrently`, which is a dep of ugly-app and not of the user
|
|
138
|
+
// project) never land in the top-level `.bin/`, and the old
|
|
139
|
+
// `node_modules/.bin/<name>` path then exits 127. Resolving the
|
|
140
|
+
// package's `bin` entry via Node module resolution works for npm,
|
|
141
|
+
// yarn, pnpm-strict, and pnpm-shamefully-hoist alike, and also
|
|
142
|
+
// sidesteps Windows shebang issues since we invoke `node <jsfile>`
|
|
143
|
+
// directly.
|
|
144
|
+
function resolveBinJs(pkg, binName) {
|
|
145
|
+
try {
|
|
146
|
+
const fromCwd = path.join(process.cwd(), 'package.json');
|
|
147
|
+
const req = createRequire(fromCwd);
|
|
148
|
+
const pkgJsonPath = req.resolve(`${pkg}/package.json`);
|
|
149
|
+
const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
|
|
150
|
+
const pkgDir = path.dirname(pkgJsonPath);
|
|
151
|
+
const binField = pkgJson.bin;
|
|
152
|
+
if (!binField)
|
|
153
|
+
return null;
|
|
154
|
+
const rel = typeof binField === 'string'
|
|
155
|
+
? binField
|
|
156
|
+
: binField[binName ?? pkgJson.name];
|
|
157
|
+
if (!rel)
|
|
158
|
+
return null;
|
|
159
|
+
return path.join(pkgDir, rel);
|
|
170
160
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
cwd: process.cwd(),
|
|
174
|
-
shell: true,
|
|
175
|
-
});
|
|
176
|
-
// Open browser once the server is listening — opt-in only. Most users
|
|
177
|
-
// either run ugly-app inside ugly-studio's preview iframe or already
|
|
178
|
-
// have the tab open from a previous run, so a system browser window
|
|
179
|
-
// popping open on every restart is intrusive. Set UGLY_APP_OPEN_BROWSER=1
|
|
180
|
-
// to opt back in.
|
|
181
|
-
const openBrowser = process.env['UGLY_APP_OPEN_BROWSER'] === '1';
|
|
182
|
-
if (openBrowser) {
|
|
183
|
-
const url = `http://localhost:${port}`;
|
|
184
|
-
waitForPort(parseInt(port, 10)).then(() => {
|
|
185
|
-
const openCmd = process.platform === 'darwin' ? 'open' :
|
|
186
|
-
process.platform === 'win32' ? 'start' : 'xdg-open';
|
|
187
|
-
exec(`${openCmd} ${url}`);
|
|
188
|
-
}).catch(() => { });
|
|
161
|
+
catch {
|
|
162
|
+
return null;
|
|
189
163
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
164
|
+
}
|
|
165
|
+
const tsxBin = resolveBinJs('tsx', 'tsx');
|
|
166
|
+
const tscBin = resolveBinJs('typescript', 'tsc');
|
|
167
|
+
const eswBin = resolveBinJs('eslint-watch', 'esw');
|
|
168
|
+
if (!tsxBin) {
|
|
169
|
+
throw new Error(`[ugly-app] Could not resolve 'tsx' from ${process.cwd()}. ` +
|
|
170
|
+
`Run \`npm install\` (or \`pnpm install\`) and try again.`);
|
|
171
|
+
}
|
|
172
|
+
const q = (s) => `"${s.replace(/"/g, '\\"')}"`;
|
|
173
|
+
const node = q(process.execPath);
|
|
174
|
+
const serverCmd = opts.watch
|
|
175
|
+
? `${node} ${q(tsxBin)} watch --clear-screen=false --ignore ./client --ignore "**/node_modules/**" server/index.ts`
|
|
176
|
+
: `${node} ${q(tsxBin)} server/index.ts`;
|
|
177
|
+
const hasEsw = eswBin !== null;
|
|
178
|
+
const hasTsc = tscBin !== null;
|
|
179
|
+
const commands = [
|
|
180
|
+
{ command: serverCmd, name: 'server', prefixColor: 'green' },
|
|
181
|
+
];
|
|
182
|
+
if (hasTsc) {
|
|
183
|
+
commands.push({
|
|
184
|
+
command: noFail(`${node} ${q(tscBin)} --watch --noEmit --preserveWatchOutput`),
|
|
185
|
+
name: 'tsc',
|
|
186
|
+
prefixColor: 'yellow',
|
|
194
187
|
});
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
resolve();
|
|
188
|
+
}
|
|
189
|
+
if (opts.watch && hasEsw) {
|
|
190
|
+
commands.push({
|
|
191
|
+
command: noFail(`${node} ${q(eswBin)} --watch --changed server client shared`),
|
|
192
|
+
name: 'eslint',
|
|
193
|
+
prefixColor: 'magenta',
|
|
202
194
|
});
|
|
195
|
+
}
|
|
196
|
+
// Non-watch mode runs only the server.
|
|
197
|
+
const finalCommands = opts.watch ? commands : commands.slice(0, 1);
|
|
198
|
+
if (verbose) {
|
|
199
|
+
console.log('[ugly-app] Spawning:');
|
|
200
|
+
for (const c of finalCommands) {
|
|
201
|
+
console.log(` [${c.name}] ${c.command}`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
const { result } = concurrently(finalCommands, {
|
|
205
|
+
killOthersOn: ['failure'],
|
|
206
|
+
handleInput: true,
|
|
207
|
+
raw: !isWin,
|
|
203
208
|
});
|
|
209
|
+
// Open browser once the server is listening — opt-in only. Most users
|
|
210
|
+
// either run ugly-app inside ugly-studio's preview iframe or already
|
|
211
|
+
// have the tab open from a previous run, so a system browser window
|
|
212
|
+
// popping open on every restart is intrusive. Set UGLY_APP_OPEN_BROWSER=1
|
|
213
|
+
// to opt back in.
|
|
214
|
+
const openBrowser = process.env['UGLY_APP_OPEN_BROWSER'] === '1';
|
|
215
|
+
if (openBrowser) {
|
|
216
|
+
const url = `http://localhost:${port}`;
|
|
217
|
+
waitForPort(parseInt(port, 10)).then(() => {
|
|
218
|
+
const openCmd = process.platform === 'darwin' ? 'open' :
|
|
219
|
+
process.platform === 'win32' ? 'start' : 'xdg-open';
|
|
220
|
+
exec(`${openCmd} ${url}`);
|
|
221
|
+
}).catch(() => { });
|
|
222
|
+
}
|
|
223
|
+
try {
|
|
224
|
+
await result;
|
|
225
|
+
}
|
|
226
|
+
catch (err) {
|
|
227
|
+
// concurrently rejects with an array of CloseEvent on non-zero exits.
|
|
228
|
+
if (Array.isArray(err)) {
|
|
229
|
+
const failed = err.find((e) => e.exitCode !== 0);
|
|
230
|
+
const code = failed?.exitCode ?? 1;
|
|
231
|
+
throw new Error(`dev process exited with code ${code}`);
|
|
232
|
+
}
|
|
233
|
+
throw err;
|
|
234
|
+
}
|
|
204
235
|
}
|
|
205
236
|
//# sourceMappingURL=dev.js.map
|
package/dist/cli/dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/cli/dev.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/cli/dev.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve a package's bin entry to an absolute path to the JS file —
|
|
3
|
+
* using Node's module resolution (pnpm-strict-safe) rather than
|
|
4
|
+
* assuming `node_modules/.bin/<name>` exists.
|
|
5
|
+
*
|
|
6
|
+
* Why this matters: `npx <bin>` fails with `Unknown command: <bin>`
|
|
7
|
+
* inside a pnpm-style nested store because the binary lives in
|
|
8
|
+
* `node_modules/.pnpm/...` and was never linked to the top-level
|
|
9
|
+
* `.bin/`. Every `execSync('npx <x>')` call from this CLI broke
|
|
10
|
+
* coding-agent sessions in pnpm-managed apps. Resolve the bin path
|
|
11
|
+
* via require + package.json `bin` field instead.
|
|
12
|
+
*
|
|
13
|
+
* Returns `null` when the package isn't installed or has no bin entry.
|
|
14
|
+
*/
|
|
15
|
+
export declare function resolveBinJs(pkg: string, binName?: string): string | null;
|
|
16
|
+
/**
|
|
17
|
+
* Build a `node <abs.js> <args>` command string for execSync. The
|
|
18
|
+
* binary is resolved via `resolveBinJs`; when it can't be found we
|
|
19
|
+
* fall back to `npx <pkg> <args>` and let the user see the original
|
|
20
|
+
* failure mode rather than a confusing error from this helper.
|
|
21
|
+
*/
|
|
22
|
+
export declare function nodeBinCommand(pkg: string, args: string, binName?: string): string;
|
|
23
|
+
//# sourceMappingURL=resolveBin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveBin.d.ts","sourceRoot":"","sources":["../../src/cli/resolveBin.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmBzE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAOR"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import { createRequire } from 'module';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
/**
|
|
5
|
+
* Resolve a package's bin entry to an absolute path to the JS file —
|
|
6
|
+
* using Node's module resolution (pnpm-strict-safe) rather than
|
|
7
|
+
* assuming `node_modules/.bin/<name>` exists.
|
|
8
|
+
*
|
|
9
|
+
* Why this matters: `npx <bin>` fails with `Unknown command: <bin>`
|
|
10
|
+
* inside a pnpm-style nested store because the binary lives in
|
|
11
|
+
* `node_modules/.pnpm/...` and was never linked to the top-level
|
|
12
|
+
* `.bin/`. Every `execSync('npx <x>')` call from this CLI broke
|
|
13
|
+
* coding-agent sessions in pnpm-managed apps. Resolve the bin path
|
|
14
|
+
* via require + package.json `bin` field instead.
|
|
15
|
+
*
|
|
16
|
+
* Returns `null` when the package isn't installed or has no bin entry.
|
|
17
|
+
*/
|
|
18
|
+
export function resolveBinJs(pkg, binName) {
|
|
19
|
+
try {
|
|
20
|
+
const fromCwd = path.join(process.cwd(), 'package.json');
|
|
21
|
+
const req = createRequire(fromCwd);
|
|
22
|
+
const pkgJsonPath = req.resolve(`${pkg}/package.json`);
|
|
23
|
+
const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
|
|
24
|
+
const pkgDir = path.dirname(pkgJsonPath);
|
|
25
|
+
const binField = pkgJson.bin;
|
|
26
|
+
if (!binField)
|
|
27
|
+
return null;
|
|
28
|
+
const rel = typeof binField === 'string' ? binField : binField[binName ?? pkgJson.name];
|
|
29
|
+
if (!rel)
|
|
30
|
+
return null;
|
|
31
|
+
return path.join(pkgDir, rel);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Build a `node <abs.js> <args>` command string for execSync. The
|
|
39
|
+
* binary is resolved via `resolveBinJs`; when it can't be found we
|
|
40
|
+
* fall back to `npx <pkg> <args>` and let the user see the original
|
|
41
|
+
* failure mode rather than a confusing error from this helper.
|
|
42
|
+
*/
|
|
43
|
+
export function nodeBinCommand(pkg, args, binName) {
|
|
44
|
+
const bin = resolveBinJs(pkg, binName);
|
|
45
|
+
const q = (s) => `"${s.replace(/"/g, '\\"')}"`;
|
|
46
|
+
if (bin) {
|
|
47
|
+
return `${q(process.execPath)} ${q(bin)} ${args}`;
|
|
48
|
+
}
|
|
49
|
+
return `npx ${binName ?? pkg} ${args}`;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=resolveBin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveBin.js","sourceRoot":"","sources":["../../src/cli/resolveBin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,OAAgB;IACxD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;QACzD,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;QACnC,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,GAAG,eAAe,CAAC,CAAC;QACvD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAG/D,CAAC;QACF,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACzC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;QAC7B,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAC3B,MAAM,GAAG,GACP,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;QAC9E,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACtB,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAC5B,GAAW,EACX,IAAY,EACZ,OAAgB;IAEhB,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACvC,MAAM,CAAC,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC;IACvD,IAAI,GAAG,EAAE,CAAC;QACR,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;IACpD,CAAC;IACD,OAAO,OAAO,OAAO,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;AACzC,CAAC"}
|
package/dist/cli/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const CLI_VERSION = "0.1.
|
|
1
|
+
export declare const CLI_VERSION = "0.1.424";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/cli/version.js
CHANGED
|
@@ -40,7 +40,7 @@ export declare const frameworkRequests: {
|
|
|
40
40
|
id: string;
|
|
41
41
|
projectId: string;
|
|
42
42
|
title: string;
|
|
43
|
-
state: "
|
|
43
|
+
state: "build" | "done" | "plan";
|
|
44
44
|
markdown: string;
|
|
45
45
|
lastModifiedUserId: string | null;
|
|
46
46
|
sortOrder: number;
|
|
@@ -59,7 +59,7 @@ export declare const frameworkRequests: {
|
|
|
59
59
|
planId: string;
|
|
60
60
|
title?: string | undefined;
|
|
61
61
|
markdown?: string | undefined;
|
|
62
|
-
state?: "
|
|
62
|
+
state?: "build" | "done" | "plan" | undefined;
|
|
63
63
|
sortOrder?: number | undefined;
|
|
64
64
|
}, Record<string, never>>;
|
|
65
65
|
projectPlanDelete: import("./Api.js").AuthRequestDef<{
|
package/package.json
CHANGED
package/src/cli/build.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { execSync } from 'child_process';
|
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import { runExportCollections } from './exportCollections.js';
|
|
5
|
+
import { nodeBinCommand } from './resolveBin.js';
|
|
5
6
|
import { runExportWorkers } from './workerGen.js';
|
|
6
7
|
|
|
7
8
|
export async function runBuild(): Promise<void> {
|
|
@@ -34,9 +35,15 @@ export const buildId = '${buildId}';
|
|
|
34
35
|
console.log('[Build] Cleaned dist/');
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
// Run vite build
|
|
38
|
+
// Run vite build. `npx vite build` does not work in pnpm-strict
|
|
39
|
+
// worktrees (vite is hoisted into `.pnpm/...` and not linked to
|
|
40
|
+
// top-level `.bin/`); resolve the bin path through Node module
|
|
41
|
+
// resolution instead. Same for esbuild + tsc below.
|
|
38
42
|
console.log('[Build] Running vite build...');
|
|
39
|
-
execSync('
|
|
43
|
+
execSync(nodeBinCommand('vite', 'build'), {
|
|
44
|
+
stdio: 'inherit',
|
|
45
|
+
cwd: process.cwd(),
|
|
46
|
+
});
|
|
40
47
|
|
|
41
48
|
// Bundle server with esbuild (only for simple projects without custom server build)
|
|
42
49
|
const serverEntry = path.join(process.cwd(), 'server', 'index.ts');
|
|
@@ -46,7 +53,10 @@ export const buildId = '${buildId}';
|
|
|
46
53
|
const serverOutDir = path.join(distDir, 'server');
|
|
47
54
|
fs.mkdirSync(serverOutDir, { recursive: true });
|
|
48
55
|
execSync(
|
|
49
|
-
|
|
56
|
+
nodeBinCommand(
|
|
57
|
+
'esbuild',
|
|
58
|
+
'server/index.ts --bundle --platform=node --format=esm --outfile=dist/server/index.mjs --external:ugly-app --external:ugly-app/*',
|
|
59
|
+
),
|
|
50
60
|
{ stdio: 'inherit', cwd: process.cwd() },
|
|
51
61
|
);
|
|
52
62
|
}
|
|
@@ -68,7 +78,10 @@ export const buildId = '${buildId}';
|
|
|
68
78
|
];
|
|
69
79
|
const externalFlags = externals.map(e => `--external:${e}`).join(' ');
|
|
70
80
|
execSync(
|
|
71
|
-
|
|
81
|
+
nodeBinCommand(
|
|
82
|
+
'esbuild',
|
|
83
|
+
`server/task.ts --bundle --platform=node --format=esm --outfile=dist/tasks/task.js ${externalFlags}`,
|
|
84
|
+
),
|
|
72
85
|
{ stdio: 'inherit', cwd: process.cwd() },
|
|
73
86
|
);
|
|
74
87
|
console.log('[Build] Task bundle: dist/tasks/task.js');
|
|
@@ -76,7 +89,10 @@ export const buildId = '${buildId}';
|
|
|
76
89
|
|
|
77
90
|
// Run tsc for typecheck
|
|
78
91
|
console.log('[Build] Running tsc...');
|
|
79
|
-
execSync('
|
|
92
|
+
execSync(nodeBinCommand('typescript', '--noEmit', 'tsc'), {
|
|
93
|
+
stdio: 'inherit',
|
|
94
|
+
cwd: process.cwd(),
|
|
95
|
+
});
|
|
80
96
|
|
|
81
97
|
console.log(`[Build] Build complete (${buildId})`);
|
|
82
98
|
}
|
package/src/cli/dev.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { exec, execSync
|
|
1
|
+
import { exec, execSync } from 'child_process';
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import net from 'net';
|
|
4
4
|
import path from 'path';
|
|
5
|
+
import { createRequire } from 'module';
|
|
6
|
+
import concurrently from 'concurrently';
|
|
5
7
|
/**
|
|
6
8
|
* Return the PID of the process listening on `port`, or null if none.
|
|
7
9
|
* Cross-platform; shells out to `lsof` on Unix and `netstat` on Windows.
|
|
@@ -139,85 +141,126 @@ export async function runDev(opts: { watch: boolean; verbose: boolean } = { watc
|
|
|
139
141
|
console.log(`[ugly-app] POSTGRES_URL: ${process.env['POSTGRES_URL'] ?? '(default)'}`);
|
|
140
142
|
}
|
|
141
143
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
].filter(Boolean).join(' ')
|
|
177
|
-
: [
|
|
178
|
-
bin('concurrently'),
|
|
179
|
-
'--names server',
|
|
180
|
-
'--prefix-colors green',
|
|
181
|
-
rawFlag,
|
|
182
|
-
'--kill-others-on-fail',
|
|
183
|
-
'--handle-input',
|
|
184
|
-
q(serverCmd),
|
|
185
|
-
].filter(Boolean).join(' ');
|
|
186
|
-
|
|
187
|
-
if (verbose) {
|
|
188
|
-
console.log(`[ugly-app] Spawning: ${cmd}`);
|
|
144
|
+
const isWin = process.platform === 'win32';
|
|
145
|
+
const noFail = (cmd: string) =>
|
|
146
|
+
isWin ? `(${cmd} || (exit /b 0))` : `${cmd} || true`;
|
|
147
|
+
|
|
148
|
+
// Resolve a tool's executable JS entry through the project's
|
|
149
|
+
// node_modules graph rather than assuming it's hoisted to
|
|
150
|
+
// `node_modules/.bin/`. Under pnpm-strict, transitive bins (e.g.
|
|
151
|
+
// `concurrently`, which is a dep of ugly-app and not of the user
|
|
152
|
+
// project) never land in the top-level `.bin/`, and the old
|
|
153
|
+
// `node_modules/.bin/<name>` path then exits 127. Resolving the
|
|
154
|
+
// package's `bin` entry via Node module resolution works for npm,
|
|
155
|
+
// yarn, pnpm-strict, and pnpm-shamefully-hoist alike, and also
|
|
156
|
+
// sidesteps Windows shebang issues since we invoke `node <jsfile>`
|
|
157
|
+
// directly.
|
|
158
|
+
function resolveBinJs(pkg: string, binName?: string): string | null {
|
|
159
|
+
try {
|
|
160
|
+
const fromCwd = path.join(process.cwd(), 'package.json');
|
|
161
|
+
const req = createRequire(fromCwd);
|
|
162
|
+
const pkgJsonPath = req.resolve(`${pkg}/package.json`);
|
|
163
|
+
const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8')) as {
|
|
164
|
+
name: string;
|
|
165
|
+
bin?: string | Record<string, string>;
|
|
166
|
+
};
|
|
167
|
+
const pkgDir = path.dirname(pkgJsonPath);
|
|
168
|
+
const binField = pkgJson.bin;
|
|
169
|
+
if (!binField) return null;
|
|
170
|
+
const rel =
|
|
171
|
+
typeof binField === 'string'
|
|
172
|
+
? binField
|
|
173
|
+
: binField[binName ?? pkgJson.name];
|
|
174
|
+
if (!rel) return null;
|
|
175
|
+
return path.join(pkgDir, rel);
|
|
176
|
+
} catch {
|
|
177
|
+
return null;
|
|
189
178
|
}
|
|
179
|
+
}
|
|
190
180
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
shell: true,
|
|
195
|
-
});
|
|
181
|
+
const tsxBin = resolveBinJs('tsx', 'tsx');
|
|
182
|
+
const tscBin = resolveBinJs('typescript', 'tsc');
|
|
183
|
+
const eswBin = resolveBinJs('eslint-watch', 'esw');
|
|
196
184
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
if (openBrowser) {
|
|
204
|
-
const url = `http://localhost:${port}`;
|
|
205
|
-
waitForPort(parseInt(port, 10)).then(() => {
|
|
206
|
-
const openCmd =
|
|
207
|
-
process.platform === 'darwin' ? 'open' :
|
|
208
|
-
process.platform === 'win32' ? 'start' : 'xdg-open';
|
|
209
|
-
exec(`${openCmd} ${url}`);
|
|
210
|
-
}).catch(() => { /* best effort */ });
|
|
211
|
-
}
|
|
185
|
+
if (!tsxBin) {
|
|
186
|
+
throw new Error(
|
|
187
|
+
`[ugly-app] Could not resolve 'tsx' from ${process.cwd()}. ` +
|
|
188
|
+
`Run \`npm install\` (or \`pnpm install\`) and try again.`,
|
|
189
|
+
);
|
|
190
|
+
}
|
|
212
191
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
192
|
+
const q = (s: string) => `"${s.replace(/"/g, '\\"')}"`;
|
|
193
|
+
const node = q(process.execPath);
|
|
194
|
+
|
|
195
|
+
const serverCmd = opts.watch
|
|
196
|
+
? `${node} ${q(tsxBin)} watch --clear-screen=false --ignore ./client --ignore "**/node_modules/**" server/index.ts`
|
|
197
|
+
: `${node} ${q(tsxBin)} server/index.ts`;
|
|
198
|
+
|
|
199
|
+
const hasEsw = eswBin !== null;
|
|
200
|
+
const hasTsc = tscBin !== null;
|
|
201
|
+
|
|
202
|
+
const commands: { command: string; name: string; prefixColor: string }[] = [
|
|
203
|
+
{ command: serverCmd, name: 'server', prefixColor: 'green' },
|
|
204
|
+
];
|
|
205
|
+
if (hasTsc) {
|
|
206
|
+
commands.push({
|
|
207
|
+
command: noFail(
|
|
208
|
+
`${node} ${q(tscBin!)} --watch --noEmit --preserveWatchOutput`,
|
|
209
|
+
),
|
|
210
|
+
name: 'tsc',
|
|
211
|
+
prefixColor: 'yellow',
|
|
216
212
|
});
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
213
|
+
}
|
|
214
|
+
if (opts.watch && hasEsw) {
|
|
215
|
+
commands.push({
|
|
216
|
+
command: noFail(
|
|
217
|
+
`${node} ${q(eswBin!)} --watch --changed server client shared`,
|
|
218
|
+
),
|
|
219
|
+
name: 'eslint',
|
|
220
|
+
prefixColor: 'magenta',
|
|
221
221
|
});
|
|
222
|
+
}
|
|
223
|
+
// Non-watch mode runs only the server.
|
|
224
|
+
const finalCommands = opts.watch ? commands : commands.slice(0, 1);
|
|
225
|
+
|
|
226
|
+
if (verbose) {
|
|
227
|
+
console.log('[ugly-app] Spawning:');
|
|
228
|
+
for (const c of finalCommands) {
|
|
229
|
+
console.log(` [${c.name}] ${c.command}`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const { result } = concurrently(finalCommands, {
|
|
234
|
+
killOthersOn: ['failure'],
|
|
235
|
+
handleInput: true,
|
|
236
|
+
raw: !isWin,
|
|
222
237
|
});
|
|
238
|
+
|
|
239
|
+
// Open browser once the server is listening — opt-in only. Most users
|
|
240
|
+
// either run ugly-app inside ugly-studio's preview iframe or already
|
|
241
|
+
// have the tab open from a previous run, so a system browser window
|
|
242
|
+
// popping open on every restart is intrusive. Set UGLY_APP_OPEN_BROWSER=1
|
|
243
|
+
// to opt back in.
|
|
244
|
+
const openBrowser = process.env['UGLY_APP_OPEN_BROWSER'] === '1';
|
|
245
|
+
if (openBrowser) {
|
|
246
|
+
const url = `http://localhost:${port}`;
|
|
247
|
+
waitForPort(parseInt(port, 10)).then(() => {
|
|
248
|
+
const openCmd =
|
|
249
|
+
process.platform === 'darwin' ? 'open' :
|
|
250
|
+
process.platform === 'win32' ? 'start' : 'xdg-open';
|
|
251
|
+
exec(`${openCmd} ${url}`);
|
|
252
|
+
}).catch(() => { /* best effort */ });
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
try {
|
|
256
|
+
await result;
|
|
257
|
+
} catch (err) {
|
|
258
|
+
// concurrently rejects with an array of CloseEvent on non-zero exits.
|
|
259
|
+
if (Array.isArray(err)) {
|
|
260
|
+
const failed = err.find((e: { exitCode: number | string }) => e.exitCode !== 0);
|
|
261
|
+
const code = failed?.exitCode ?? 1;
|
|
262
|
+
throw new Error(`dev process exited with code ${code}`);
|
|
263
|
+
}
|
|
264
|
+
throw err;
|
|
265
|
+
}
|
|
223
266
|
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import { createRequire } from 'module';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Resolve a package's bin entry to an absolute path to the JS file —
|
|
7
|
+
* using Node's module resolution (pnpm-strict-safe) rather than
|
|
8
|
+
* assuming `node_modules/.bin/<name>` exists.
|
|
9
|
+
*
|
|
10
|
+
* Why this matters: `npx <bin>` fails with `Unknown command: <bin>`
|
|
11
|
+
* inside a pnpm-style nested store because the binary lives in
|
|
12
|
+
* `node_modules/.pnpm/...` and was never linked to the top-level
|
|
13
|
+
* `.bin/`. Every `execSync('npx <x>')` call from this CLI broke
|
|
14
|
+
* coding-agent sessions in pnpm-managed apps. Resolve the bin path
|
|
15
|
+
* via require + package.json `bin` field instead.
|
|
16
|
+
*
|
|
17
|
+
* Returns `null` when the package isn't installed or has no bin entry.
|
|
18
|
+
*/
|
|
19
|
+
export function resolveBinJs(pkg: string, binName?: string): string | null {
|
|
20
|
+
try {
|
|
21
|
+
const fromCwd = path.join(process.cwd(), 'package.json');
|
|
22
|
+
const req = createRequire(fromCwd);
|
|
23
|
+
const pkgJsonPath = req.resolve(`${pkg}/package.json`);
|
|
24
|
+
const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8')) as {
|
|
25
|
+
name: string;
|
|
26
|
+
bin?: string | Record<string, string>;
|
|
27
|
+
};
|
|
28
|
+
const pkgDir = path.dirname(pkgJsonPath);
|
|
29
|
+
const binField = pkgJson.bin;
|
|
30
|
+
if (!binField) return null;
|
|
31
|
+
const rel =
|
|
32
|
+
typeof binField === 'string' ? binField : binField[binName ?? pkgJson.name];
|
|
33
|
+
if (!rel) return null;
|
|
34
|
+
return path.join(pkgDir, rel);
|
|
35
|
+
} catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Build a `node <abs.js> <args>` command string for execSync. The
|
|
42
|
+
* binary is resolved via `resolveBinJs`; when it can't be found we
|
|
43
|
+
* fall back to `npx <pkg> <args>` and let the user see the original
|
|
44
|
+
* failure mode rather than a confusing error from this helper.
|
|
45
|
+
*/
|
|
46
|
+
export function nodeBinCommand(
|
|
47
|
+
pkg: string,
|
|
48
|
+
args: string,
|
|
49
|
+
binName?: string,
|
|
50
|
+
): string {
|
|
51
|
+
const bin = resolveBinJs(pkg, binName);
|
|
52
|
+
const q = (s: string) => `"${s.replace(/"/g, '\\"')}"`;
|
|
53
|
+
if (bin) {
|
|
54
|
+
return `${q(process.execPath)} ${q(bin)} ${args}`;
|
|
55
|
+
}
|
|
56
|
+
return `npx ${binName ?? pkg} ${args}`;
|
|
57
|
+
}
|
package/src/cli/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Auto-generated by prebuild — do not edit manually
|
|
2
|
-
export const CLI_VERSION = "0.1.
|
|
2
|
+
export const CLI_VERSION = "0.1.424";
|