agent-orchestrator/frontend
Harshit Singh Bhandari 572093de9d
feat: dashboard legacy-migration popup + app-state migration marker (#2219)
* docs: design for dashboard legacy-migration popup + app-state marker

Spec for the app-side migration trigger (Approach A): projects-only import
daemon API + a migration marker in ~/.ao/app-state.json, with a launch-time
popup (Proceed / Skip / Don't Migrate). Settings redo path deferred to #2205.
Includes the projects-only import-offer backend plan it consumes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs: implementation plan for legacy-migration popup + marker

Part A reuses the projects-only import API (import-offer plan) with an
availability-only Status; Part B adds the app-state migration marker (schema v2),
IPC, the useMigrationOffer gate, and the MigrationPopup (Proceed/Skip/Don't
Migrate). Settings redo path deferred to #2205.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* refactor(legacyimport): scope import to projects + settings only

Remove orchestrator/transcript import code (orchestrator.go, claude.go,
session_import_store.go and their tests). Trim Store, Options, Report to
projects-only fields. Drop defaultClaudeProjectsDir and projectSessionsDir
from paths.go. Add yaml.TypeError robustness in config.go. Update cli/import.go
confirm prompt and summary. Update importer_test.go to projects-only assertions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(importer): availability probe + projects-only run

Create service/importer.Manager with Status (physical availability check only,
no DB heuristic) and Run (delegates to legacyimport.Run). The app-state.json
marker governs whether to prompt; this service only answers whether legacy data
is physically present.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(httpd): import controller + DTOs (GET/POST /api/v1/import)

Add ImportStatusResponse/ImportRunResponse DTOs to dto.go. Create
ImportController with GET (status probe) and POST (run) handlers, both
returning 501 when Svc is nil. Wire APIDeps.Import + API.imports in api.go.
Add controller tests (status, status error, run, run error).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(apispec): describe /api/v1/import; regenerate openapi + schema.ts

Add import tag, importOperations() (GET + POST /api/v1/import), and schema
name mappings (ImportStatusResponse, ImportRunResponse, ImportReport) to
build.go. Regenerate openapi.yaml and frontend/src/api/schema.ts. Route-spec
parity test passes. Restore the nil-svc-501 import controller test now that
the spec includes the operation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(daemon): mount import service on the API

Wire importsvc.New(importsvc.Deps{Store: store}) into APIDeps.Import in
daemon.go so the daemon serves GET/POST /api/v1/import backed by the live
sqlite store. Projects-only; no DataDir.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* chore(cli): drop resolved §6.4 first-boot-import TODO

The legacy import is now a daemon API (GET/POST /api/v1/import) served by
the importer service and the desktop app handles the popup prompt via the
app-state.json migration marker. The TODO comment is resolved.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* chore(legacyimport): remove dead isDir helper

isDir was only used by the deleted projectSessionsDir function.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* chore: update package-lock.json after npm install for api:ts

openapi-typescript was missing from root node_modules; npm install
populated it so npm run api:ts could regenerate schema.ts.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(httpd): drop em-dash comment + unused ImportStatusResult alias

Review findings M1/M2 from G1 task review.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(app-state): migration marker (schema v2) + updateMigration

Bump SCHEMA_VERSION to 2, add MigrationStatus/MigrationState types and
migration? field to AppStateMarker. Extract atomicWriteMarker helper and
reuse it. writeAppStateMarker now preserves an existing migration block
across launch writes. Add updateMigration (IPC setter) and readMigrationState
(IPC getter) exports. TDD: tests added first (red), then implementation (green).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(ipc): expose app-state migration getter/setter to the renderer

Add appState:getMigration / appState:setMigration IPC handlers in main.ts.
Add ao.appState.getMigration / setMigration to preload.ts (typed via AoBridge).
Add appState preview fallback in bridge.ts and test setup so AoBridge stays
satisfied in both browser preview and test environments.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test(app-state): cover corrupt-marker case + clean up temp dirs

G2 review findings I2 (corrupt-JSON branch untested) and m1 (temp dirs not cleaned).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(renderer): useMigrationOffer gate (marker + availability)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(renderer): MigrationPopup (Proceed / Skip / Don't Migrate)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(renderer): surface MigrationPopup on the dashboard

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* chore: format with prettier [skip ci]

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-06-27 02:24:36 +05:30
..
assets fix(desktop): green the tag desktop build on Linux/Windows and add app icon (#348) 2026-06-20 21:53:11 +05:30
docs fix(desktop): package Windows via NSIS instead of Squirrel (#403) 2026-06-23 20:44:30 +05:30
e2e test(e2e): guard sidebar brand vs macOS titlebar cluster (#366) (#374) 2026-06-22 13:14:01 +05:30
makers feat(cli): ao start fetch/open for Windows and Linux (T6/T7) (#2204) 2026-06-26 20:50:30 +05:30
scripts Split: backend runtime/session updates + frontend shell refactor (#222) 2026-06-13 12:18:55 +05:30
src feat: dashboard legacy-migration popup + app-state migration marker (#2219) 2026-06-27 02:24:36 +05:30
.npmrc feat(renderer): clone agent-orchestrator shell and inspector 2026-06-11 16:45:00 +05:30
components.json feat(renderer): clone agent-orchestrator shell and inspector 2026-06-11 16:45:00 +05:30
forge.config.ts feat(cli): ao start fetch/open for Windows and Linux (T6/T7) (#2204) 2026-06-26 20:50:30 +05:30
index.html feat(frontend): scaffold for frontend with complimentary backend changes (#168) 2026-06-10 11:40:17 +05:30
package-lock.json fix(desktop): package Windows via NSIS instead of Squirrel (#403) 2026-06-23 20:44:30 +05:30
package.json fix(desktop): package Windows via NSIS instead of Squirrel (#403) 2026-06-23 20:44:30 +05:30
playwright.config.ts feat(frontend): scaffold for frontend with complimentary backend changes (#168) 2026-06-10 11:40:17 +05:30
pnpm-lock.yaml Zellij to tmux + ConPTY runtime, session save/restore, crash-proof reconcile (port #404) (#2183) 2026-06-25 15:05:41 +05:30
pnpm-workspace.yaml feat(renderer): clone agent-orchestrator shell and inspector 2026-06-11 16:45:00 +05:30
tsconfig.json fix(desktop): package Windows via NSIS instead of Squirrel (#403) 2026-06-23 20:44:30 +05:30
vite.main.config.ts feat(frontend): scaffold for frontend with complimentary backend changes (#168) 2026-06-10 11:40:17 +05:30
vite.preload.config.ts feat(frontend): scaffold for frontend with complimentary backend changes (#168) 2026-06-10 11:40:17 +05:30
vite.renderer.config.ts feat(frontend): add live browser panel (#375) 2026-06-22 04:14:18 +05:30
vitest.config.ts fix(spawn): stop sending branch on spawn, render API errors, wire worker name (#171) 2026-06-11 12:13:30 +05:30