feat(cli): add ao migrate to port legacy projects + settings into the rewrite daemon#2127
Closed
harshitsinghbhandari wants to merge 3 commits into
Closed
feat(cli): add ao migrate to port legacy projects + settings into the rewrite daemon#2127harshitsinghbhandari wants to merge 3 commits into
ao migrate to port legacy projects + settings into the rewrite daemon#2127harshitsinghbhandari wants to merge 3 commits into
Conversation
… daemon Implements the legacy half of the legacy->rewrite migration spec (aoagents/ReverbCode#247 sections 1 + 3): a new `ao migrate` command that ports the registered project registry and per-project settings into the rewrite (Go/Electron) daemon over its loopback REST API, mirroring the rewrite's own `ao project add` flow (POST /api/v1/projects then PUT /api/v1/projects/{id}/config). Sessions are out of scope for this cut. Respects the rewrite invariant that the daemon is the sole writer of ~/.ao/data/ao.db (the CLI never opens the DB). Ref: aoagents/ReverbCode#247 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ref: aoagents/ReverbCode#247 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>
Contributor
Test Coverage Report
Per-file breakdown
Uncovered lines
|
This was referenced Jun 16, 2026
Collaborator
Author
|
Closing in favor of a unified OFFLINE |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds
ao migrate— the legacy side of the legacy → rewrite (Go/Electron) data migration. It ports the registered project registry and per-project settings into the new AO daemon's SQLite store.It does not open
~/.ao/data/ao.dbdirectly. The rewrite daemon is the sole writer of that DB (the CLI/doctor are forbidden from opening it). Soao migratemirrors the rewrite's ownao project addflow over the daemon's loopback REST API:loadConfig(getGlobalConfigPath())(same sourceao updatealready trusts) — global identity merged with each project's localagent-orchestrator.yamlbehavioral config.--dry-runprints the plan with no network calls.--daemon-url/AO_DAEMON_URLoverride the target (defaulthttp://127.0.0.1:3001).409and is reported as skipped.Spec source
Implements the legacy-side, projects-only slice of aoagents/ReverbCode#247 (sections 1 + 3: project mapping and the
configblob mapping, incl. the permission enum remap and the §4 dropped-field set).Scope (deliberately narrow for this cut)
Why this shape (verification notes)
I cloned
aoagents/ReverbCodeand verified the contract before building. Key findings that shaped the implementation:ao migrate importCLI /POST /api/v1/migrate/importendpoint /InsertSessionVerbatim) does not exist yet — so there is nothing to hand off to. The existingPOST /api/v1/projectscontroller is the locked, contract-respecting write path, so this command uses that instead of an unbuilt endpoint.Originheader (we don't).repo_origin_url,registered_at, andkindare server-resolved and cannot be supplied in the create body — so we don't try to.config.yaml projects.<id>; in reality the global config holds identity fields only and behavioral settings live in each project's localagent-orchestrator.yaml.loadConfigmerges both, so we read the merged effective config.~/.ao/data/ao.db" does not match this codebase — the legacy TS side never writes that path (its only SQLite store is~/.agent-orchestrator/activity-events.db). That collision is purely rewrite-side, so this command does not touch~/.ao.AO_PORTfallback for the daemon URL:AO_PORTis overloaded (it points at the legacy dashboard, 3000, in a legacy environment), so falling back to it risked POSTing project payloads at the wrong server. Targeting the rewrite daemon is explicit.Tests
packages/cli/__tests__/lib/migrate.test.ts— 26 tests covering the pure mapping (permission/harness remap, config blob construction, lossy-suggest + dropped-field notes, id validation, daemon-url resolution) andrunMigrateorchestration against an injected fetch + config (create, 409-skip, error envelope, config-write-failure-keeps-project, degraded/invalid-id skips, daemon-unreachable).pnpm build,pnpm -r typecheck, and lint (0 errors on the new files) are green. Smoke-tested--dry-runand the unreachable-daemon path against a real legacy config.Changeset:
@aoagents/ao-climinor.