Skip to content

Add attic status --json for machine-readable output - #11

Merged
tijs merged 4 commits into
tijs:mainfrom
janhoy:feature/status-json
Aug 22, 2026
Merged

tijs merged 4 commits into
tijs:mainfrom
janhoy:feature/status-json

Conversation

@janhoy

@janhoy janhoy commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Implements the status --json part of #7.

Adds a --json flag to status that emits the already-computed DashboardData as 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 existing migrate --json pattern (formatMigrationReportJSON) — a pure formatter in AtticCore, command writes to stdout.

  • Optional sections (backup, s3, retry) are omitted — not null — when unavailable (e.g. before attic init)
  • Adds full ISO lastBackupAt for machine consumers alongside the existing display date (additive, defaulted — no breakage)
  • 3 tests: full round-trip incl. derived fields (total, pendingCloud, percentage), section omission, unknown-lane omission; full suite 280/280, swiftlint + swiftformat clean

The backup end-of-run summary mentioned in #7 is left for a follow-up: #10 already touches BackupCommand (its ATTIC_* 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.

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.
Comment thread Sources/AtticCLI/StatusCommand.swift Outdated
)

StatusRenderer(isTTY: isTTY).render(data)
if json {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.)

Comment thread Sources/AtticCLI/StatusCommand.swift Outdated
)

StatusRenderer(isTTY: isTTY).render(data)
if json {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.)

janhoy added 3 commits August 22, 2026 15:02
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.
@tijs
tijs merged commit ae77352 into tijs:main Aug 22, 2026
4 checks passed
@janhoy
janhoy deleted the feature/status-json branch August 22, 2026 21:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants