Skip to content

feat(doctor): add tsk doctor diagnostic command#8

Merged
Sanjays2402 merged 1 commit into
mainfrom
feat/doctor
May 17, 2026
Merged

feat(doctor): add tsk doctor diagnostic command#8
Sanjays2402 merged 1 commit into
mainfrom
feat/doctor

Conversation

@Sanjays2402

Copy link
Copy Markdown
Owner

tsk doctor is a one-shot health check against the active .tsk.md and tsk configuration. Designed for pre-commit hooks, CI gates, and fast triage when "something's weird."

Example

$ tsk doctor
file:    /Users/sanjay/tasks/.tsk.md
tz:      America/Los_Angeles
tasks:   142

all checks passed ✓

$ tsk doctor   # with a busted file
file:    /tmp/.tsk.md
tz:      Local
tasks:   3

ERRORS:
  ✗ unique_ids: id #1 appears on 2 tasks
exit 1

Checks

  • file_present.tsk.md exists and is readable
  • file_parses — parses without error (error → exit 1)
  • unique_ids — no duplicate IDs across tasks (error → exit 1)
  • positive_ids — no negative IDs (error → exit 1)
  • non_empty_title — no whitespace-only titles (warning)
  • timestamp_sanity — completed >= created, due not 100+ years out (warning)
  • timezone — reports active TSK_TZ/TZ/system default

Flags

  • --json — machine-readable DoctorReport for scripts and CI

Exit Codes

  • 0 — all checks passed (warnings don't flip exit code)
  • 1 — at least one error
  • 2 — bad invocation

New: SilentExitCoder

To avoid the noisy error: <msg> prefix on the legit failure path (doctor already prints its own report), this PR introduces a SilentExitCoder interface — an error that carries an exit code AND tells main.go to skip the default prefix. Doctor uses it for the "issues found" return path.

Cobra commands that need this pattern in the future can implement SilentExitCoder in their command file (the interface is exported, silentExit itself is package-private).

Tests

5 cases in doctor_test.go:

  1. Clean store → "all checks passed"
  2. --json emits parseable DoctorReport
  3. Duplicate IDs → exit 1 + unique_ids error
  4. Missing file → exit 1 + file_present error
  5. SilentExitCoder shape: empty .Error(), code 1

All green with -race, gofmt-clean.

Part 4/10 of the v0.3.0 improvement series.

`tsk doctor` runs a one-shot health check against the active .tsk.md
and tsk configuration. Designed for pre-commit hooks, CI gates, and
fast triage when "something's weird."

Checks:
  - File exists, is readable, parses cleanly
  - No duplicate task IDs
  - All IDs non-negative
  - No empty/whitespace-only titles (warning)
  - Timestamp sanity: completed >= created, due not 100+ years out (warnings)
  - Reports active timezone (env override or system default)

Output:
  - Default: human-friendly text summary with ERRORS: / WARNINGS:
  - --json: machine-readable DoctorReport (stable schema)

Exit codes:
  0  all checks passed (warnings don't flip exit code)
  1  at least one error
  2  bad invocation

To avoid noisy "error: <msg>" prefix on the legit failure path, this
PR introduces a SilentExitCoder interface — errors that carry an exit
code AND tell main.go not to add the prefix. doctor uses it for the
"issues found" return path, since its own report is the message.

Tests: 5 cases — clean store, JSON parse, duplicate IDs, missing file,
SilentExitCoder shape. All green with -race + gofmt clean.
@Sanjays2402 Sanjays2402 merged commit 8bc854f into main May 17, 2026
4 checks passed
@Sanjays2402 Sanjays2402 deleted the feat/doctor branch May 17, 2026 04:33
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.

1 participant