mirror of
https://github.com/nexu-io/open-design.git
synced 2026-06-01 03:14:35 +07:00
Merge b80de1414b into 53fb175855
This commit is contained in:
commit
17de37cf20
3 changed files with 70 additions and 5 deletions
16
tools/dev/src/cli-hints.ts
Normal file
16
tools/dev/src/cli-hints.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
export function formatSourceInstallCliHints(args: {
|
||||
daemonUrl: string | null;
|
||||
odBinPath: string;
|
||||
}): string[] {
|
||||
if (args.daemonUrl == null) return [];
|
||||
|
||||
return [
|
||||
"",
|
||||
" Source install CLI",
|
||||
"",
|
||||
" ➜ Run: pnpm exec od skills list",
|
||||
` ➜ URL: export OD_DAEMON_URL=${args.daemonUrl}`,
|
||||
` ➜ Note: system 'od' is not Open Design — use pnpm exec od or ${args.odBinPath}`,
|
||||
"",
|
||||
];
|
||||
}
|
||||
|
|
@ -64,6 +64,7 @@ import {
|
|||
waitForWebRuntime,
|
||||
} from "./sidecar-client.js";
|
||||
import { ensureDaemonGateForDesktop } from "./desktop-auth-gate.js";
|
||||
import { formatSourceInstallCliHints } from "./cli-hints.js";
|
||||
import { resolveSharedPortsFromRunningState } from "./shared-ports.js";
|
||||
|
||||
type CliOptions = ToolDevOptions & {
|
||||
|
|
@ -183,12 +184,28 @@ function printStartSection(result: Partial<Record<ToolDevAppName, unknown>>, hea
|
|||
}
|
||||
}
|
||||
|
||||
function printStartResult(result: Partial<Record<ToolDevAppName, unknown>>, options: CliOptions, heading = "tools-dev start"): void {
|
||||
function printSourceInstallCliHints(config: ToolDevConfig, daemonUrl: string | null): void {
|
||||
for (const line of formatSourceInstallCliHints({
|
||||
daemonUrl,
|
||||
odBinPath: path.join(config.workspaceRoot, "node_modules/.bin/od"),
|
||||
})) {
|
||||
process.stdout.write(`${line}\n`);
|
||||
}
|
||||
}
|
||||
|
||||
function printStartResult(
|
||||
result: Partial<Record<ToolDevAppName, unknown>>,
|
||||
options: CliOptions,
|
||||
config: ToolDevConfig,
|
||||
heading = "tools-dev start",
|
||||
): void {
|
||||
if (options.json === true) {
|
||||
printJson(result);
|
||||
return;
|
||||
}
|
||||
printStartSection(result, heading);
|
||||
const daemonStatus = asRecord(asRecord(result.daemon)?.status);
|
||||
printSourceInstallCliHints(config, stringField(daemonStatus ?? {}, "url"));
|
||||
}
|
||||
|
||||
function printStopSection(result: Partial<Record<ToolDevAppName, unknown>>, heading: string): void {
|
||||
|
|
@ -254,7 +271,11 @@ function printStatusResult(result: unknown, options: CliOptions, appName: string
|
|||
process.stdout.write(`- ${appName ?? ALL_APPS.join("/")}: ${formatStatusSummary(result)}\n`);
|
||||
}
|
||||
|
||||
function printRunForegroundResult(started: Partial<Record<ToolDevAppName, unknown>>, options: CliOptions): void {
|
||||
function printRunForegroundResult(
|
||||
started: Partial<Record<ToolDevAppName, unknown>>,
|
||||
options: CliOptions,
|
||||
config: ToolDevConfig,
|
||||
): void {
|
||||
if (options.json === true) {
|
||||
printJson({ mode: "foreground", started });
|
||||
return;
|
||||
|
|
@ -269,7 +290,8 @@ function printRunForegroundResult(started: Partial<Record<ToolDevAppName, unknow
|
|||
process.stdout.write("\n Open Design dev server ready\n\n");
|
||||
if (webUrl != null) process.stdout.write(` ➜ Web: ${colorizeLink(normalizeDisplayUrl(webUrl))}\n`);
|
||||
if (daemonUrl != null) process.stdout.write(` ➜ Daemon: ${colorizeLink(normalizeDisplayUrl(daemonUrl))}\n`);
|
||||
process.stdout.write("\n Press Ctrl+C to stop\n\n");
|
||||
printSourceInstallCliHints(config, daemonUrl);
|
||||
process.stdout.write(" Press Ctrl+C to stop\n\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1044,7 +1066,7 @@ async function runForeground(config: ToolDevConfig, appName: string | undefined,
|
|||
webUrl: async () => (await inspectWebRuntime(runtimeLookup(config)))?.url,
|
||||
});
|
||||
const started = await runSequential(targets, (target) => startApp(config, target, foregroundOptions, { targets }));
|
||||
printRunForegroundResult(started, options);
|
||||
printRunForegroundResult(started, options, config);
|
||||
|
||||
let shuttingDown = false;
|
||||
const keepAlive = setInterval(() => undefined, 60_000);
|
||||
|
|
@ -1094,7 +1116,7 @@ addPortOptions(addSharedOptions(cli.command("start [app]", "Start daemon, web, d
|
|||
webUrl: async () => (await inspectWebRuntime(runtimeLookup(config)))?.url,
|
||||
});
|
||||
const result = await runSequential(targets, (target) => startApp(config, target, options, { targets }));
|
||||
printStartResult(result, options);
|
||||
printStartResult(result, options, config);
|
||||
},
|
||||
);
|
||||
|
||||
|
|
|
|||
27
tools/dev/tests/cli-hints.test.ts
Normal file
27
tools/dev/tests/cli-hints.test.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import assert from "node:assert/strict";
|
||||
import { describe, it } from "node:test";
|
||||
|
||||
import { formatSourceInstallCliHints } from "../src/cli-hints.js";
|
||||
|
||||
describe("formatSourceInstallCliHints", () => {
|
||||
it("returns empty output when the daemon URL is unavailable", () => {
|
||||
assert.deepEqual(
|
||||
formatSourceInstallCliHints({
|
||||
daemonUrl: null,
|
||||
odBinPath: "/repo/node_modules/.bin/od",
|
||||
}),
|
||||
[],
|
||||
);
|
||||
});
|
||||
|
||||
it("prints pnpm exec od guidance and OD_DAEMON_URL export (#2801)", () => {
|
||||
const text = formatSourceInstallCliHints({
|
||||
daemonUrl: "http://127.0.0.1:49980",
|
||||
odBinPath: "/repo/node_modules/.bin/od",
|
||||
}).join("\n");
|
||||
|
||||
assert.match(text, /pnpm exec od skills list/);
|
||||
assert.match(text, /export OD_DAEMON_URL=http:\/\/127\.0\.0\.1:49980/);
|
||||
assert.match(text, /\/repo\/node_modules\/\.bin\/od/);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue