Skip to content

feat(cli): standardize Doctor service interface - #21

Merged
thenotoriousllama merged 5 commits into
mainfrom
legion/prd-003-doctor-cli-standard
Jul 14, 2026
Merged

feat(cli): standardize Doctor service interface#21
thenotoriousllama merged 5 commits into
mainfrom
legion/prd-003-doctor-cli-standard

Conversation

@thenotoriousllama

@thenotoriousllama thenotoriousllama commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • standardize Doctor on the Apiary CLI service interface while retaining the register exemption
  • add canonical lifecycle, service-installation, update, status, Doctor-isolated logs, telemetry, branding, JSON, and exit-code behavior
  • preserve Doctor-specific commands and deprecated migration aliases
  • harden Windows service ownership, restart/stop verification, update rollback, output redaction, and packed-artifact boundaries
  • add cross-platform adapter fixtures and full packed CLI conformance coverage

Validation

  • npm run ci — 72 files, 871 tests passed
  • npm run build
  • npm run test:packed-cli
  • npm run pack:check — 5 files, no forbidden patterns or source leak
  • npm audit --audit-level=high — 0 vulnerabilities
  • live Windows dogfood completed for install/start/stop/restart/service-install/service-uninstall/status/logs/telemetry/update-check

PRD

Implements Doctor adoption for PRD-003 Apiary CLI Interface Standard. Doctor intentionally omits register because it validates and supervises registry entries written by the other products.

Summary by CodeRabbit

  • New Features

    • Standardized the Doctor CLI with grouped help, stable JSON responses, shared exit codes, and clearer service, incident, telemetry, logs, and update commands.
    • Added deprecated aliases for renamed commands to preserve compatibility.
    • Added self-update version checks, health verification, and rollback support.
    • Added authoritative service-log viewing with follow, filtering, and secret redaction.
    • Improved service lifecycle handling across macOS, Linux, and Windows, including reconciliation and stale-process cleanup.
    • Added packed CLI and cross-platform integration validation.
  • Documentation

    • Updated installation and CLI usage guidance for the new command names and behaviors.
    • Released version 0.6.0.

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e51356a4-53d0-4939-91c2-544fa1fc45fc

📥 Commits

Reviewing files that changed from the base of the PR and between 88adfa6 and 59d403e.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (2)
  • CHANGELOG.md
  • package.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • package.json
  • CHANGELOG.md

📝 Walkthrough

Walkthrough

Doctor 0.6.0 standardizes the CLI around a shared manifest, adds stable JSON and lifecycle contracts, introduces authoritative service logs, strengthens self-update and native service reconciliation, and adds packed-bundle and cross-platform fixture validation.

Changes

Doctor CLI contract

Layer / File(s) Summary
Manifest-driven commands and rendering
src/cli/command-table.ts, src/cli/banner.ts, src/cli/bin.ts, src/cli/direct-invocation.ts, README.md
Doctor commands, aliases, banners, help output, entrypoint behavior, and documented service command names now use the shared CLI contract.
Dispatcher, lifecycle, updates, and telemetry
src/cli/dispatch.ts, src/cli/index.ts, src/cli/context.ts, src/cli/self-update.ts, src/cli/service-logs.ts
Dispatch validation, JSON envelopes, status, logs, telemetry, lifecycle confirmation, pinned self-update resolution, rollback, and authoritative service-log handling are implemented.
Native service reconciliation
src/service/argv.ts, src/service/index.ts, src/service/templates.ts
launchd, systemd, schtasks, and Windows service flows reconcile existing state, clean up stale Doctor processes, classify status, and write stdout/stderr to service.log.
Conformance and release validation
scripts/verify-packed-cli.mjs, tests/cli/*, tests/service/*, tests/compose/*, tests/config.test.ts, .github/workflows/ci.yaml, package.json, CHANGELOG.md
Packed CLI behavior, standard interfaces, service transactions, direct invocation, dependency boundaries, CI checks, and version metadata are validated.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related issues

Possibly related PRs

  • legioncodeinc/doctor#6 — Shares the SQLite telemetry reader contract and its lazy node:sqlite loading.
  • legioncodeinc/doctor#12 — Overlaps directly in dispatcher lifecycle commands, including start, stop, and gated uninstall.

Poem

I’m a bunny with a manifest bright,
Hopping through commands trimmed just right.
Logs stay tucked and secrets hide,
Services reconcile side by side.
Updates roll back when health goes gray—
Packaged Doctor passes the day!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 76.79% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the PR’s main change: standardizing Doctor’s CLI/service interface.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch legion/prd-003-doctor-cli-standard

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
src/cli/banner.ts (1)

33-51: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Unify the banner/menu rendering renderMenu hand-builds the menu, while renderBannerWithMenu patches renderProductBanner() output with a hard-coded "\nService lifecycle" replacement. That leaves the two paths easy to drift; derive both from one renderer or expose a cli-kit hook for the commands header so the banner doesn't depend on a literal section title.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/cli/banner.ts` around lines 33 - 51, The menu and banner currently
duplicate command-rendering logic and rely on a fragile literal “Service
lifecycle” replacement. Update renderMenu and renderBannerWithMenu to share a
single menu-rendering path, or use an existing cli-kit command-header hook, so
both outputs derive command sections from DOCTOR_MANIFEST without hard-coded
section-title matching.
tests/cli/dispatch.test.ts (1)

328-336: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Stale test title: says "logs" but exercises incidents.

This test dispatches ["incidents"], not ["logs"], yet is titled "logs prints recent incident lines...". Given this PR's core change splits logs (Doctor-only, fails closed) from incidents (fleet incident tail), keeping this misnamed makes future failures harder to triage against the right command contract.

✏️ Suggested rename
-		it("logs prints recent incident lines, or a friendly empty message", async () => {
+		it("incidents prints recent incident lines, or a friendly empty message", async () => {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/cli/dispatch.test.ts` around lines 328 - 336, Rename the test case
around dispatch(["incidents"]) to describe the incidents command and its
recent-line output, replacing the stale “logs” wording while preserving the
existing assertions and test behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/cli/banner.ts`:
- Around line 33-51: The menu and banner currently duplicate command-rendering
logic and rely on a fragile literal “Service lifecycle” replacement. Update
renderMenu and renderBannerWithMenu to share a single menu-rendering path, or
use an existing cli-kit command-header hook, so both outputs derive command
sections from DOCTOR_MANIFEST without hard-coded section-title matching.

In `@tests/cli/dispatch.test.ts`:
- Around line 328-336: Rename the test case around dispatch(["incidents"]) to
describe the incidents command and its recent-line output, replacing the stale
“logs” wording while preserving the existing assertions and test behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0eda789c-6a48-4b8c-a937-029c5820c4aa

📥 Commits

Reviewing files that changed from the base of the PR and between 5489851 and 0781f18.

⛔ Files ignored due to path filters (3)
  • package-lock.json is excluded by !**/package-lock.json
  • tests/cli/__snapshots__/banner.test.ts.snap is excluded by !**/*.snap
  • tests/cli/__snapshots__/standard-interface.test.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (32)
  • .changeset/ai-503e26e.md
  • .github/workflows/ci.yaml
  • CHANGELOG.md
  • README.md
  • package.json
  • scripts/verify-packed-cli.mjs
  • src/cli/banner.ts
  • src/cli/bin.ts
  • src/cli/command-table.ts
  • src/cli/context.ts
  • src/cli/dispatch.ts
  • src/cli/index.ts
  • src/cli/self-update.ts
  • src/cli/service-logs.ts
  • src/service/argv.ts
  • src/service/index.ts
  • src/service/install-guard.ts
  • src/service/templates.ts
  • src/telemetry/sqlite-reader.ts
  • tests/cli/banner.test.ts
  • tests/cli/dispatch.test.ts
  • tests/cli/helpers/fake-cli.ts
  • tests/cli/lifecycle-commands.test.ts
  • tests/cli/self-update.test.ts
  • tests/cli/service-logs.test.ts
  • tests/cli/standard-interface.test.ts
  • tests/compose/registry-reload-reconcile.test.ts
  • tests/config.test.ts
  • tests/service/argv.test.ts
  • tests/service/native-adapter.integration.test.ts
  • tests/service/service-module.test.ts
  • tests/service/templates.test.ts
👮 Files not reviewed due to content moderation or server errors (8)
  • src/cli/command-table.ts
  • src/cli/context.ts
  • src/cli/dispatch.ts
  • src/cli/index.ts
  • src/cli/self-update.ts
  • src/cli/service-logs.ts
  • scripts/verify-packed-cli.mjs
  • tests/cli/standard-interface.test.ts

@thenotoriousllama

Copy link
Copy Markdown
Contributor Author

Approved Release

@thenotoriousllama

Copy link
Copy Markdown
Contributor Author

✅ Approved — applying the minor bump. The release-gate check will go green; it publishes on merge.

@thenotoriousllama
thenotoriousllama merged commit 5f374ec into main Jul 14, 2026
7 checks passed
@thenotoriousllama
thenotoriousllama deleted the legion/prd-003-doctor-cli-standard branch July 14, 2026 07:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants