Repository navigation
Add attic status --json for machine-readable output - #11
Conversation
Emits library, backup-progress, retry-queue, and S3 manifest stats as a single stable JSON object on stdout. Optional sections are omitted when unavailable. Adds full ISO lastBackupAt alongside the display date.
| ) | ||
|
|
||
| StatusRenderer(isTTY: isTTY).render(data) | ||
| if json { |
There was a problem hiding this comment.
blocking: The advertised unconfigured case cannot reach this JSON branch. run() calls ensureManifestMigrated() before constructing DashboardData; that calls makeBackupDeps() → loadConfig() and throws notInitialized, so the later do/catch never produces the library-only object that the README/PR promise for “before attic init.” Conditionalize the migration/config path so an unconfigured status can serialize its library data, and add a CLI-level regression test.
There was a problem hiding this comment.
Fixed: notInitialized from the migration guard is now tolerated, so an unconfigured install gets the library-only output. Orchestration extracted into a testable buildDashboard with CLI-level regression tests. (Fixes authored by Claude AI — I haven't reviewed the changes in detail.)
| ) | ||
|
|
||
| StatusRenderer(isTTY: isTTY).render(data) | ||
| if json { |
There was a problem hiding this comment.
blocking: --json promises a single JSON object, but this branch runs only after ensureManifestMigrated(). When a v1 manifest or thumbnail cleanup is pending, that guard’s migration progress callback and completion messages use print, so stdout contains human text before the JSON and parsers fail. In JSON mode, route that progress to stderr (or return a structured error/avoid automatic migration) and cover a migration-needed status invocation with a JSON parse test.
There was a problem hiding this comment.
Fixed: the migration gate is now an injectable MigrationGuard; in --json mode progress/summaries go to stderr so stdout stays a single JSON object, covered by a mock-backed migration-needed parse test. (Fixes authored by Claude AI — I haven't reviewed the changes in detail.)
# Conflicts: # CHANGELOG.md
The migration guard ran before status could build DashboardData and threw CLIError.notInitialized on unconfigured installs, so the advertised before-attic-init library-only output (JSON and human) was unreachable. Tolerate notInitialized from the guard, extract the command orchestration into StatusCommand.buildDashboard with injected loaders, and add CLI-level regression tests (test target now links AtticCLI). Other guard errors, e.g. migrationRequired, still abort. Addresses PR tijs#11 review comment r3833054917.
The migration gate printed runner progress and completion summaries to stdout, so a migration-needed 'status --json' run emitted human text ahead of the JSON document and broke parsers. Extract the gate into an injectable MigrationGuard with separate prompt (always stderr) and status sinks; Dependencies.ensureManifestMigrated(statusToStderr:) routes status output to stderr in JSON mode, and human invocations keep the existing stdout behavior. Add MigrationGuard tests, including a mock-backed migration-needed status --json run asserting stdout parses as a single JSON object. Addresses PR tijs#11 review comment r3833055884.
Implements the
status --jsonpart of #7.Adds a
--jsonflag tostatusthat emits the already-computedDashboardDataas a single stable JSON object on stdout: library counts, backup progress (backed-up/pending/lanes/percentage), retry queue, manifest entry count, and last-backup timestamp. Follows the existingmigrate --jsonpattern (formatMigrationReportJSON) — a pure formatter in AtticCore, command writes to stdout.backup,s3,retry) are omitted — not null — when unavailable (e.g. beforeattic init)lastBackupAtfor machine consumers alongside the existing display date (additive, defaulted — no breakage)total,pendingCloud,percentage), section omission, unknown-lane omission; full suite 280/280, swiftlint + swiftformat cleanThe backup end-of-run summary mentioned in #7 is left for a follow-up: #10 already touches
BackupCommand(itsATTIC_*hook env covers much of that need), and keeping this PR off that file avoids cross-PR conflicts.Drafted with AI assistance; reviewed and tested locally against main.