fix(cli): drop AO_PORT fallback in ao migrate daemon-url resolution
AO_PORT is overloaded — in a legacy environment it points at the legacy Next.js dashboard (3000), not the rewrite daemon (3001). Falling back to it could silently POST project-create payloads at the wrong server. Targeting the rewrite daemon is now explicit: --daemon-url or AO_DAEMON_URL, else the rewrite's 3001 default. Ref: aoagents/ReverbCode#247 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
ecd94f4af1
commit
37e0dbda44
|
|
@ -21,7 +21,9 @@ function project(overrides: Partial<ProjectConfig> = {}): ProjectConfig {
|
|||
name: "My Project",
|
||||
path: "/repos/my-project",
|
||||
defaultBranch: "main",
|
||||
sessionPrefix: "mp",
|
||||
// Empty by default so per-field assertions stay focused; a dedicated test
|
||||
// covers sessionPrefix carry-over.
|
||||
sessionPrefix: "",
|
||||
...overrides,
|
||||
} as ProjectConfig;
|
||||
}
|
||||
|
|
@ -79,9 +81,9 @@ describe("resolveDaemonUrl", () => {
|
|||
process.env.AO_DAEMON_URL = "http://host:1234";
|
||||
expect(resolveDaemonUrl()).toBe("http://host:1234");
|
||||
});
|
||||
it("builds a loopback url from AO_PORT", () => {
|
||||
process.env.AO_PORT = "4567";
|
||||
expect(resolveDaemonUrl()).toBe("http://127.0.0.1:4567");
|
||||
it("ignores AO_PORT (overloaded with the legacy dashboard) and uses the default", () => {
|
||||
process.env.AO_PORT = "3000";
|
||||
expect(resolveDaemonUrl()).toBe(DEFAULT_DAEMON_URL);
|
||||
});
|
||||
it("uses the rewrite default when nothing is set", () => {
|
||||
expect(resolveDaemonUrl()).toBe(DEFAULT_DAEMON_URL);
|
||||
|
|
@ -153,6 +155,12 @@ describe("buildRewriteConfig", () => {
|
|||
});
|
||||
});
|
||||
|
||||
it("carries a non-empty sessionPrefix", () => {
|
||||
expect(buildRewriteConfig(project({ sessionPrefix: "app" }), [])).toEqual({
|
||||
sessionPrefix: "app",
|
||||
});
|
||||
});
|
||||
|
||||
it("carries env, symlinks, and postCreate verbatim", () => {
|
||||
const config = buildRewriteConfig(
|
||||
project({
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ export function registerMigrate(program: Command): void {
|
|||
.option("--dry-run", "Parse and map the legacy registry, print the plan, write nothing")
|
||||
.option(
|
||||
"--daemon-url <url>",
|
||||
"New AO daemon base URL (default http://127.0.0.1:3001; env AO_DAEMON_URL / AO_PORT)",
|
||||
"New AO daemon base URL (default http://127.0.0.1:3001; env AO_DAEMON_URL)",
|
||||
)
|
||||
.action(async (opts: { dryRun?: boolean; daemonUrl?: string }) => {
|
||||
const dryRun = opts.dryRun === true;
|
||||
|
|
@ -51,7 +51,7 @@ export function registerMigrate(program: Command): void {
|
|||
console.error(
|
||||
chalk.dim(
|
||||
"Start the new AO (the rewrite) first so its daemon is listening, then run `ao migrate`.\n" +
|
||||
"Override the address with --daemon-url or the AO_DAEMON_URL / AO_PORT env vars.",
|
||||
"Override the address with --daemon-url or the AO_DAEMON_URL env var.",
|
||||
),
|
||||
);
|
||||
process.exit(1);
|
||||
|
|
|
|||
|
|
@ -68,14 +68,17 @@ export const DEFAULT_DAEMON_URL = "http://127.0.0.1:3001";
|
|||
|
||||
/**
|
||||
* Resolve the rewrite daemon base URL. Precedence: explicit flag → AO_DAEMON_URL
|
||||
* → AO_PORT (loopback) → the rewrite's hardcoded default.
|
||||
* → the rewrite's hardcoded default.
|
||||
*
|
||||
* We deliberately do NOT fall back to `AO_PORT`: that variable is overloaded
|
||||
* (the legacy dashboard and the rewrite daemon both use it for "the port"), so
|
||||
* in a legacy environment it usually points at the legacy Next.js dashboard.
|
||||
* Targeting the rewrite daemon must be explicit and unambiguous.
|
||||
*/
|
||||
export function resolveDaemonUrl(explicit?: string): string {
|
||||
if (explicit && explicit.trim().length > 0) return stripTrailingSlash(explicit.trim());
|
||||
const url = process.env.AO_DAEMON_URL;
|
||||
if (url && url.trim().length > 0) return stripTrailingSlash(url.trim());
|
||||
const port = process.env.AO_PORT;
|
||||
if (port && /^\d+$/.test(port.trim())) return `http://127.0.0.1:${port.trim()}`;
|
||||
return DEFAULT_DAEMON_URL;
|
||||
}
|
||||
|
||||
|
|
@ -389,15 +392,14 @@ export async function runMigrate(opts: MigrateOptions): Promise<MigrateSummary>
|
|||
});
|
||||
}
|
||||
|
||||
const ids = Object.keys(config.projects);
|
||||
const entries = Object.entries(config.projects);
|
||||
|
||||
// Fail fast if the daemon is down (skip the probe on dry runs — they never hit it).
|
||||
if (!opts.dryRun && ids.length > 0) {
|
||||
if (!opts.dryRun && entries.length > 0) {
|
||||
await apiRequest(fetchImpl, opts.daemonUrl, "GET", "/api/v1/projects");
|
||||
}
|
||||
|
||||
for (const id of ids) {
|
||||
const pc = config.projects[id]!;
|
||||
for (const [id, pc] of entries) {
|
||||
const plan = buildProjectPlan(id, pc);
|
||||
|
||||
if (!isValidRewriteProjectId(id)) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue