feat(cli): implement full CLI interface and symlink resolution #99

Merged
fuzzy merged 3 commits from feature/0040-implement-cli-interface into main 2026-07-05 14:36:49 +00:00
Owner

What

Implement the kronai CLI with list/run/interval commands, and symlink resolution for job lookup by name.

Why

Users can now interact with kronai via the command line — list jobs, run by ID or name, and execute intervals.

Testing

  • 102 unit tests pass (24 new for CLI + discovery helpers)
  • Pre-commit hooks pass (ruff + mypy strict)
  • Coverage: 90%

Breaking Changes

None.

Notes

kronai list shows all jobs with IDs, names (from name file or dir name), intervals, types, and symlinks. kronai run <id|symlink> resolves by either. kronai hourly|daily|weekly|monthly runs all jobs in an interval.

Closes #0031
Closes #0032
Closes #0033
Closes #0034
Closes #0035
Closes #0036
Closes #0037
Closes #0038
Closes #0039
Closes #0040
Closes #0041
Closes #0042
Closes #0043
Closes #0044

## What Implement the `kronai` CLI with list/run/interval commands, and symlink resolution for job lookup by name. ## Why Users can now interact with kronai via the command line — list jobs, run by ID or name, and execute intervals. ## Testing - [x] 102 unit tests pass (24 new for CLI + discovery helpers) - [x] Pre-commit hooks pass (ruff + mypy strict) - [x] Coverage: 90% ## Breaking Changes None. ## Notes `kronai list` shows all jobs with IDs, names (from `name` file or dir name), intervals, types, and symlinks. `kronai run <id|symlink>` resolves by either. `kronai hourly|daily|weekly|monthly` runs all jobs in an interval. Closes #0031 Closes #0032 Closes #0033 Closes #0034 Closes #0035 Closes #0036 Closes #0037 Closes #0038 Closes #0039 Closes #0040 Closes #0041 Closes #0042 Closes #0043 Closes #0044
- kronai list: show all jobs with IDs, names, intervals, types, symlinks
- kronai run <id|name>: run job by numeric ID or symlink name
- kronai <interval>: run all jobs in interval shorthand
- find_job(): lookup by numeric ID or symlink name
- find_job_symlinks(): discover symlinks pointing to a job
- get_job_name(): read name file or fall back to directory name
Closes #0031
Closes #0032
Closes #0033
Closes #0034
Closes #0035
Closes #0036
Closes #0037
Closes #0038
Closes #0039
Closes #0040
Cover argument parsing, list/run/interval commands, job name
resolution, find by ID/symlink, symlink discovery, and
broken symlink handling.
docs: mark Phase 3 Tasks 1-2 complete
All checks were successful
CI / test (pull_request) Successful in 46s
CI / lint (pull_request) Successful in 1m18s
d13045eebb
CLI interface (list/run/interval) and symlink resolution done.
Closes #0044
the.auditor left a comment

Automated Review — PR #99

Result: APPROVED


Completes Phase 3 — full CLI with list, run <id|name>, and <interval> shorthand, plus symlink resolution and job name support.

  • Correctness: CLI parsing works correctly for all subcommands and interval shorthands. find_job resolves by numeric ID first, then falls back to symlink name search. find_job_symlinks correctly discovers symlinks pointing to a job and ignores broken ones.
  • Completeness: Closes 14 issues (#31–#44). ROADMAP updated. T201 suppressed appropriately for CLI prints.
  • Test coverage: 24 tests across 8 test classes — parser args, list (empty/with jobs), run (success/failure/not found), interval (empty/all-ok/partial-fail), get_job_name, find_job (by ID/by symlink/not found), find_job_symlinks (none/detected/filters-other-jobs/broken), NAME_FILE constant.
  • Error handling: sys.exit(1) on job not found, run failure, and partial interval failure. Broken symlinks silently ignored in find_job_symlinks.
  • Maintainability: Clean separation of _cmd_list, _cmd_run, _cmd_interval. Discovery helpers are well-factored.

Suggestions (non-blocking)

  1. src/kronai/discovery.py:155-170find_job() calls discover_jobs(jobs_dir) then manually re-iterates the filesystem for symlink search. It could reuse the already-discovered job paths for the symlink search instead of re-scanning, avoiding redundant I/O.

  2. src/kronai/cli.py:56-60_cmd_list() reads get_job_name(job) which re-reads the name file from disk each time. For large job lists, consider caching names or collecting them in bulk. Minor.

  3. src/kronai/cli.py:81-83_cmd_interval() prints "No jobs found" but still returns exit code 0. _cmd_run() exits 1 on not-found. Consider consistent behavior (exit 1 on "nothing to do" is debatable either way).

## Automated Review — PR #99 **Result: APPROVED** --- Completes Phase 3 — full CLI with `list`, `run <id|name>`, and `<interval>` shorthand, plus symlink resolution and job name support. - **Correctness**: CLI parsing works correctly for all subcommands and interval shorthands. `find_job` resolves by numeric ID first, then falls back to symlink name search. `find_job_symlinks` correctly discovers symlinks pointing to a job and ignores broken ones. - **Completeness**: Closes 14 issues (#31–#44). ROADMAP updated. `T201` suppressed appropriately for CLI prints. - **Test coverage**: 24 tests across 8 test classes — parser args, list (empty/with jobs), run (success/failure/not found), interval (empty/all-ok/partial-fail), get_job_name, find_job (by ID/by symlink/not found), find_job_symlinks (none/detected/filters-other-jobs/broken), NAME_FILE constant. - **Error handling**: `sys.exit(1)` on job not found, run failure, and partial interval failure. Broken symlinks silently ignored in `find_job_symlinks`. - **Maintainability**: Clean separation of `_cmd_list`, `_cmd_run`, `_cmd_interval`. Discovery helpers are well-factored. ### Suggestions (non-blocking) 1. **`src/kronai/discovery.py:155-170`** — `find_job()` calls `discover_jobs(jobs_dir)` then manually re-iterates the filesystem for symlink search. It could reuse the already-discovered job paths for the symlink search instead of re-scanning, avoiding redundant I/O. 2. **`src/kronai/cli.py:56-60`** — `_cmd_list()` reads `get_job_name(job)` which re-reads the `name` file from disk each time. For large job lists, consider caching names or collecting them in bulk. Minor. 3. **`src/kronai/cli.py:81-83`** — `_cmd_interval()` prints "No jobs found" but still returns exit code 0. `_cmd_run()` exits 1 on not-found. Consider consistent behavior (exit 1 on "nothing to do" is debatable either way).
fuzzy merged commit d13045eebb into main 2026-07-05 14:36:49 +00:00
fuzzy deleted branch feature/0040-implement-cli-interface 2026-07-05 14:36:50 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
thwap/kronai!99
No description provided.