roadmap-cli 0.3.0__tar.gz → 0.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- roadmap_cli-0.3.1/CHANGELOG.md +224 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/PKG-INFO +43 -12
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/README.md +36 -3
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/pyproject.toml +18 -24
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/__init__.py +2 -2
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/__init__.py +39 -11
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/analysis/commands.py +37 -22
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/cleanup.py +57 -9
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/cli_command_helpers.py +114 -1
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/config/commands.py +26 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/decorators.py +22 -19
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/exception_handler.py +7 -6
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/health/commands.py +100 -34
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/init/commands.py +10 -0
- roadmap_cli-0.3.1/roadmap/adapters/inbound/cli/inspection.py +42 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/issues/archive.py +19 -2
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/issues/create.py +29 -8
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/issues/list.py +5 -1
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/issues/query_presenter.py +41 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/issues/resolution.py +5 -1
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/issues/restore.py +13 -1
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/issues/start.py +5 -1
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/issues/update.py +44 -13
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/issues/view.py +9 -2
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/migrate.py +13 -1
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/milestones/__init__.py +1 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/milestones/archive.py +24 -3
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/milestones/create.py +14 -3
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/milestones/recalculate.py +5 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/milestones/restore.py +13 -1
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/milestones/update.py +7 -1
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/milestones/view.py +8 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/models/output_models.py +12 -6
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/output_formatter.py +1 -1
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/projects/archive.py +24 -3
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/projects/close.py +13 -2
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/projects/create.py +23 -4
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/projects/restore.py +13 -1
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/projects/update.py +11 -2
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/projects/view.py +8 -1
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/status.py +2 -9
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/outbound/git/local.py +6 -2
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/outbound/persistence/canonical.py +161 -34
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/outbound/persistence/configuration.py +51 -3
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/outbound/persistence/diagnostics.py +19 -10
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/outbound/persistence/documents.py +27 -1
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/outbound/persistence/initialization.py +5 -3
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/outbound/persistence/migration.py +13 -4
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/application/contracts.py +13 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/application/ports.py +2 -2
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/application/use_cases/issue_mutations.py +64 -54
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/application/use_cases/issues.py +16 -1
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/application/use_cases/planning.py +99 -57
- roadmap_cli-0.3.1/roadmap/application/use_cases/updates.py +9 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/bootstrap/__init__.py +14 -2
- roadmap_cli-0.3.0/CHANGELOG.md +0 -118
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/.gitignore +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/LICENSE.md +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/__init__.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/__init__.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/analysis/__init__.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/analysis/presenter.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/column_factory.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/config/__init__.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/console.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/daily_summary.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/data/__init__.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/data/commands.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/datetime_parser.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/git/__init__.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/git/commands.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/health/__init__.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/init/__init__.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/issues/__init__.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/issues/block.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/issues/close.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/issues/comment.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/issues/delete.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/issues/deps.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/issues/progress.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/issues/unblock.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/layout.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/milestones/assign.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/milestones/close.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/milestones/delete.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/milestones/kanban.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/milestones/list.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/models/__init__.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/output_options.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/planning_resolution.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/projects/__init__.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/projects/delete.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/projects/list.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/styling.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/inbound/cli/today.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/outbound/__init__.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/outbound/git/__init__.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/outbound/persistence/__init__.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/outbound/persistence/issue_queries.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/outbound/persistence/projection.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/adapters/outbound/system.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/application/__init__.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/application/configuration.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/application/failures.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/application/use_cases/__init__.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/application/use_cases/health.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/application/use_cases/local_git.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/application/use_cases/workspace_initialization.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/application/use_cases/workspace_migration.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/bootstrap/core.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/domain/__init__.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/domain/aggregates.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/domain/failures.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/domain/transitions.py +0 -0
- {roadmap_cli-0.3.0 → roadmap_cli-0.3.1}/roadmap/domain/types.py +0 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Roadmap CLI are recorded here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and releases follow
|
|
5
|
+
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.3.1] - 2026-10-08
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Add CI gates for high-confidence dead code and active documentation links,
|
|
14
|
+
with negative fixtures proving rejected inputs.
|
|
15
|
+
|
|
16
|
+
- Add branch-outcome regressions for migration refusals, canonical transaction
|
|
17
|
+
failure/retry, planning idempotency, aggregate invariants and scoped issue-list
|
|
18
|
+
workload output.
|
|
19
|
+
|
|
20
|
+
- Add scoped requirement verification records, fail-closed evidence policy and
|
|
21
|
+
an executable maintainer handover runbook with a current release checklist.
|
|
22
|
+
|
|
23
|
+
- Add explicit workspace selection, JSON entity inspection with issue history,
|
|
24
|
+
project/milestone ID-only creation, nullable-field clearing, issue due dates and
|
|
25
|
+
label edits, project owner/priority controls, and stderr-only operational verbosity.
|
|
26
|
+
- Add a reviewed command/option evidence matrix and a guard against CLI drift.
|
|
27
|
+
|
|
28
|
+
- Add global `--debug` tracebacks for unexpected CLI failures. Configuration
|
|
29
|
+
access errors no longer silently use defaults; command import failures remain
|
|
30
|
+
errors. Log projection refresh exceptions with Python logging and send repair
|
|
31
|
+
warnings to stderr.
|
|
32
|
+
- Show candidate IDs and labels for ambiguous issue/project/milestone lookups.
|
|
33
|
+
- Explain effective configuration values, owning scope, and default/configured
|
|
34
|
+
source with `config explain KEY [--format json]`.
|
|
35
|
+
- Print only the created issue ID with `issue create --print-id`, keeping
|
|
36
|
+
warnings and branch notifications on stderr.
|
|
37
|
+
- Show repair-preview commands in plain health output and document built-in
|
|
38
|
+
shell completion.
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
|
|
42
|
+
- Replace deprecated Click filesystem isolation in tests with pytest-managed
|
|
43
|
+
temporary workspaces, remove retired coverage exclusions, and enable Bandit's
|
|
44
|
+
try/except/pass rule instead of suppressing it globally.
|
|
45
|
+
|
|
46
|
+
- Raise the statement-coverage floor to 90% after real-storage CLI safety journeys.
|
|
47
|
+
|
|
48
|
+
- Replace the hand-written import graph checker with Import Linter contracts
|
|
49
|
+
and narrow namespace/core dependency guards; raise the coverage floor to 87%.
|
|
50
|
+
|
|
51
|
+
- Standardize type checking on ty and remove Pyright and unused pytest plugins;
|
|
52
|
+
consolidate development dependencies into the dev extra.
|
|
53
|
+
- Run architecture checks in pre-commit, retain CI coverage evidence, and
|
|
54
|
+
require the full CI workflow before a release can publish.
|
|
55
|
+
|
|
56
|
+
### Fixed
|
|
57
|
+
|
|
58
|
+
- Correct the empty issue-list creation hint to include the required `--title`
|
|
59
|
+
option, with a CLI regression proving the suggested command works.
|
|
60
|
+
|
|
61
|
+
- Refuse migration when canonical directories cannot be enumerated or a personal
|
|
62
|
+
configuration schema version is boolean; protect changed migration previews
|
|
63
|
+
and prove projection failure rollback/retry with regression tests.
|
|
64
|
+
- Distinguish unpublished master behavior from PyPI 0.3.0 and correct the package
|
|
65
|
+
documentation URL to the actual default branch.
|
|
66
|
+
|
|
67
|
+
- Refuse dry-run recovery writes and parent-close guard bypasses; reject explicit
|
|
68
|
+
branch options without branch action before canonical writes.
|
|
69
|
+
- Preserve literal machine output, independent sort directions and empty CSV
|
|
70
|
+
headers; validate output options and export enums even when results are empty.
|
|
71
|
+
- Honor empty-analysis destinations and health summary-only across formats.
|
|
72
|
+
- Require explicit bounded health repair targets. Prefer `--format`, `--yes` and
|
|
73
|
+
`milestone progress`; warn on deprecated spellings through 0.3, retire in 0.4.
|
|
74
|
+
Archive keeps a lifecycle override; its legacy force-as-consent shortcut is
|
|
75
|
+
explicitly deprecated, as is project close's shortcut. Init force is deprecated
|
|
76
|
+
because initialization is idempotent and never overwrites canonical data.
|
|
77
|
+
|
|
78
|
+
- Keep broken-reference health findings visible when filtering by entity, with
|
|
79
|
+
workspace-relative scopes and an accurate unhealthy exit code.
|
|
80
|
+
- Validate manually edited configuration values using the same type rules as
|
|
81
|
+
scoped writes; reject boolean schema versions without rewriting input.
|
|
82
|
+
- Treat duplicate project/milestone names as ambiguous and list candidates.
|
|
83
|
+
|
|
84
|
+
- Preserve successful canonical mutation results when post-commit cleanup or
|
|
85
|
+
projection stale-marker persistence fails; retry journals on reopen.
|
|
86
|
+
- Reject symlinked backup directories/files and anchor cleanup deletion to a
|
|
87
|
+
directory descriptor, including revalidation after confirmation.
|
|
88
|
+
- Fail canonical scans on unreadable directories instead of treating them as
|
|
89
|
+
empty, and block projection repair when enumeration fails.
|
|
90
|
+
|
|
91
|
+
- Refuse recovery preview and projection repair when transaction journals
|
|
92
|
+
cannot be inspected, instead of silently treating them as absent.
|
|
93
|
+
- Validate complete recovery journals and snapshot integrity before replay;
|
|
94
|
+
preserve post-interruption manual edits and reject unsafe snapshot paths.
|
|
95
|
+
- Release workspace locks when recovery or lock-metadata persistence fails.
|
|
96
|
+
- Persist transaction snapshots and preparation/cleanup boundaries; preserve
|
|
97
|
+
rollback intent when an ordinary write failure cannot finish restoration.
|
|
98
|
+
- Rebuild missing projections when retrying a migration interrupted after
|
|
99
|
+
canonical commit.
|
|
100
|
+
- Explicitly select locked development dependencies for CI and pre-commit
|
|
101
|
+
checks and the documented contributor commands.
|
|
102
|
+
|
|
103
|
+
### Added
|
|
104
|
+
|
|
105
|
+
- Reliability coverage for deletion guards, reciprocal dependency edits,
|
|
106
|
+
populated backup cleanup, malformed canonical input, and repair refusal.
|
|
107
|
+
- A maintainer continuity/inactivity policy and a review closeout record that
|
|
108
|
+
distinguishes local verification from remote CI and independent review.
|
|
109
|
+
- A required CI audit of locked runtime/development dependencies using pinned
|
|
110
|
+
pip-audit, in addition to GitHub's Dependabot monitoring.
|
|
111
|
+
- Reliability tests covering actual process termination, separate writers,
|
|
112
|
+
filesystem replacement failures, recovery conflicts, and installed CLI
|
|
113
|
+
repair, plus a recovery guide and guarantee-to-test evidence map.
|
|
114
|
+
|
|
115
|
+
## [0.3.0] - 2026-09-02
|
|
116
|
+
|
|
117
|
+
### Changed
|
|
118
|
+
|
|
119
|
+
- Migrated static type checking from Pyright-only to `ty` running alongside
|
|
120
|
+
Pyright, both enforced in CI and pre-commit; aligned their configured
|
|
121
|
+
Python-version floor with the declared `>=3.12` support range.
|
|
122
|
+
- Reduced cyclomatic complexity across the codebase and enforced a
|
|
123
|
+
xenon B-or-better gate (absolute, per-module, and average) in CI and
|
|
124
|
+
pre-commit.
|
|
125
|
+
- Raised the enforced test coverage floor from 78% to 85%, backed by a
|
|
126
|
+
targeted test-coverage sweep (CLI output formatting and issue query
|
|
127
|
+
presentation) that reached 85.70%.
|
|
128
|
+
- Reduced DRY violations identified during the complexity-reduction pass.
|
|
129
|
+
- Enabled GitHub's native Dependabot vulnerability alerts for the repository.
|
|
130
|
+
|
|
131
|
+
### Fixed
|
|
132
|
+
|
|
133
|
+
- Removed the stale, inaccurate `.env.production` file (unverifiable "0 known
|
|
134
|
+
CVEs" claim, an obsolete `poetry install` reference, and unused
|
|
135
|
+
environment variables that nothing in the codebase reads).
|
|
136
|
+
- Removed the stale, tracked `output.txt` pytest-output artifact from version
|
|
137
|
+
control.
|
|
138
|
+
- Fixed a broken `SECURITY.md` reference to a nonexistent developer-notes
|
|
139
|
+
file; it now points to the ADR that documents credential handling.
|
|
140
|
+
|
|
141
|
+
### Removed
|
|
142
|
+
|
|
143
|
+
- Removed `.env.production` and `output.txt` from version control (see
|
|
144
|
+
Fixed, above).
|
|
145
|
+
|
|
146
|
+
## [0.2.0] - 2026-08-27
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
### Added
|
|
150
|
+
|
|
151
|
+
- Added explicit `roadmap migrate` preflight, dry-run, confirmed execution,
|
|
152
|
+
structured output, recovery, and idempotent rerun for supported 0.1.1
|
|
153
|
+
workspaces.
|
|
154
|
+
- Added versioned workspace/document schemas, stable entity IDs, scoped
|
|
155
|
+
configuration, deterministic JSON/CSV output, read-only health diagnosis,
|
|
156
|
+
previewable repair, and explicit local Git status/branch/reference commands.
|
|
157
|
+
- Added architecture, test-quality, package-installation, compatibility,
|
|
158
|
+
failure-injection, concurrency, corruption, migration, offline, and measured
|
|
159
|
+
performance gates.
|
|
160
|
+
|
|
161
|
+
### Changed
|
|
162
|
+
|
|
163
|
+
- Canonical Markdown/YAML documents are now the sole data authority. SQLite is
|
|
164
|
+
a disposable query projection refreshed or rebuilt only from those files.
|
|
165
|
+
- Projects, milestones, and issues use flat stable-ID paths. Lifecycle state is
|
|
166
|
+
metadata rather than a physical archive-directory contract.
|
|
167
|
+
- New IDs use complete UUID4 values; migration preserves existing IDs and
|
|
168
|
+
user-authored content.
|
|
169
|
+
- The package now has one Domain/Application/Adapters/Bootstrap architecture,
|
|
170
|
+
one configuration path, one persistence path, and one implementation for
|
|
171
|
+
each retained CLI journey.
|
|
172
|
+
- Supported runtimes now include Python 3.12 through 3.14 on macOS and Linux;
|
|
173
|
+
CI verifies the full Python range and installed artifacts on Ubuntu x64 and
|
|
174
|
+
macOS ARM64.
|
|
175
|
+
- Machine-readable stdout is isolated from diagnostics and confirmations on
|
|
176
|
+
stderr.
|
|
177
|
+
|
|
178
|
+
### Removed
|
|
179
|
+
|
|
180
|
+
- Removed provider-backed synchronization, GitHub entity replication,
|
|
181
|
+
Roadmap-owned credentials, connectivity/setup handlers, provider baselines,
|
|
182
|
+
reconciliation databases, and sync metrics. Ordinary Git transport remains
|
|
183
|
+
outside Roadmap and local file-to-SQLite projection maintenance remains.
|
|
184
|
+
- Removed the legacy `core`, `common`, `infrastructure`, `presentation`, and
|
|
185
|
+
superseded adapter ownership zones, along with duplicate configuration,
|
|
186
|
+
health, export, persistence, and compatibility implementations.
|
|
187
|
+
- Removed claimed features that did not belong to the retained product,
|
|
188
|
+
including hosted dashboards, predictive analytics, OAuth, and generated API
|
|
189
|
+
documentation stacks.
|
|
190
|
+
|
|
191
|
+
### Migration
|
|
192
|
+
|
|
193
|
+
- Existing 0.1.1 workspaces must run `roadmap migrate --dry-run` and review the
|
|
194
|
+
report before `roadmap migrate --yes`.
|
|
195
|
+
- Migration rewrites canonical entities to stable paths, externalizes user
|
|
196
|
+
preferences, removes legacy credential fields, and rebuilds SQLite without
|
|
197
|
+
treating it as authority. See `docs/user_guide/MIGRATING_TO_0_2.md`.
|
|
198
|
+
|
|
199
|
+
## [0.1.1] - 2026-08-09
|
|
200
|
+
|
|
201
|
+
### Fixed
|
|
202
|
+
|
|
203
|
+
- Removed the unrelated `roadmap` PyPI distribution from runtime dependencies;
|
|
204
|
+
it shadowed this project's package and broke the console command.
|
|
205
|
+
- Moved development and documentation tooling out of runtime dependencies.
|
|
206
|
+
- Read the installed version from distribution metadata and added clean wheel
|
|
207
|
+
and source-distribution smoke tests.
|
|
208
|
+
- Corrected supported Python/platform declarations, repository URLs, and
|
|
209
|
+
installation guidance.
|
|
210
|
+
|
|
211
|
+
## [0.1.0] - 2026-05-18
|
|
212
|
+
|
|
213
|
+
### Changed
|
|
214
|
+
|
|
215
|
+
- Reset the public version from premature 1.x tags to 0.1.0 so package versions
|
|
216
|
+
accurately communicate pre-1.0 compatibility and maturity.
|
|
217
|
+
|
|
218
|
+
## Pre-reset 1.x tags
|
|
219
|
+
|
|
220
|
+
Tags numbered 1.0.0 through 1.0.2 predated the maturity reset. Their release
|
|
221
|
+
notes contained aspirational and unverified feature, compatibility, coverage,
|
|
222
|
+
security, and performance claims, so they are not a description of the current
|
|
223
|
+
product contract. Git history remains available for provenance; supported
|
|
224
|
+
behavior begins with the honest 0.1.x line above.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: roadmap-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: Git-native command line tool for local project roadmap management
|
|
5
5
|
Project-URL: Homepage, https://github.com/shanewilkins/roadmap
|
|
6
6
|
Project-URL: Repository, https://github.com/shanewilkins/roadmap
|
|
7
7
|
Project-URL: Issues, https://github.com/shanewilkins/roadmap/issues
|
|
8
|
-
Project-URL: Documentation, https://github.com/shanewilkins/roadmap/tree/
|
|
8
|
+
Project-URL: Documentation, https://github.com/shanewilkins/roadmap/tree/master/docs
|
|
9
9
|
Author: Shane Wilkins
|
|
10
10
|
License: MIT
|
|
11
11
|
License-File: LICENSE.md
|
|
@@ -33,18 +33,16 @@ Requires-Dist: pyyaml<7.0.0,>=6.0.3
|
|
|
33
33
|
Requires-Dist: rich<16.0.0,>=15.0.0
|
|
34
34
|
Provides-Extra: dev
|
|
35
35
|
Requires-Dist: bandit[toml]>=1.9.4; extra == 'dev'
|
|
36
|
+
Requires-Dist: import-linter<3,>=2.11; extra == 'dev'
|
|
37
|
+
Requires-Dist: markdown-it-py<5,>=4.2; extra == 'dev'
|
|
36
38
|
Requires-Dist: pre-commit>=4.6.0; extra == 'dev'
|
|
37
|
-
Requires-Dist: pyright>=1.1.411; extra == 'dev'
|
|
38
|
-
Requires-Dist: pytest-aiohttp>=1.1.0; extra == 'dev'
|
|
39
|
-
Requires-Dist: pytest-asyncio>=1.3.0; extra == 'dev'
|
|
40
|
-
Requires-Dist: pytest-benchmark>=5.2.3; extra == 'dev'
|
|
41
39
|
Requires-Dist: pytest-cov>=7.1.0; extra == 'dev'
|
|
42
|
-
Requires-Dist: pytest-mock>=3.15.1; extra == 'dev'
|
|
43
40
|
Requires-Dist: pytest-xdist>=3.8.0; extra == 'dev'
|
|
44
41
|
Requires-Dist: pytest>=9.0.3; extra == 'dev'
|
|
45
42
|
Requires-Dist: radon<7.0.0,>=6.0.1; extra == 'dev'
|
|
46
|
-
Requires-Dist: ruff
|
|
47
|
-
Requires-Dist: ty>=0.0.
|
|
43
|
+
Requires-Dist: ruff>=0.16.10; extra == 'dev'
|
|
44
|
+
Requires-Dist: ty>=0.0.84; extra == 'dev'
|
|
45
|
+
Requires-Dist: vulture<3,>=2.14; extra == 'dev'
|
|
48
46
|
Requires-Dist: xenon<1.0.0,>=0.9.3; extra == 'dev'
|
|
49
47
|
Description-Content-Type: text/markdown
|
|
50
48
|
|
|
@@ -55,7 +53,13 @@ their planning data in reviewable Markdown and YAML files rather than a hosted
|
|
|
55
53
|
service. It supports issues, dependencies, comments, projects, milestones,
|
|
56
54
|
daily views, health checks, and machine-readable exports.
|
|
57
55
|
|
|
58
|
-
|
|
56
|
+
Version **0.3.1** adds CLI workflow improvements and reliability fixes. Use the
|
|
57
|
+
[versioned documentation](https://github.com/shanewilkins/roadmap/tree/v0.3.1/docs)
|
|
58
|
+
and [0.3.1 changelog](CHANGELOG.md#031---2026-10-08) for this version.
|
|
59
|
+
Source checkouts can precede package publication; check
|
|
60
|
+
[PyPI](https://pypi.org/project/roadmap-cli/) for available package versions.
|
|
61
|
+
|
|
62
|
+
The retained CLI and data behavior is defined
|
|
59
63
|
by an explicit
|
|
60
64
|
[public compatibility contract](docs/architecture/public-contract-0.2.md).
|
|
61
65
|
0.3 is an internal quality-hardening release; the 0.2 CLI and data contract is
|
|
@@ -142,7 +146,7 @@ Organize delivery:
|
|
|
142
146
|
|
|
143
147
|
```bash
|
|
144
148
|
roadmap project create --title "Web application"
|
|
145
|
-
roadmap milestone create --title "0.2" --due-date 2026-09-30
|
|
149
|
+
roadmap milestone create --title "0.2" --due-date 2026-09-30 --project "Web application"
|
|
146
150
|
roadmap milestone assign <issue-id> "0.2"
|
|
147
151
|
roadmap milestone view "0.2"
|
|
148
152
|
```
|
|
@@ -214,6 +218,7 @@ migration. Do not treat the internal SQLite schema as a public API.
|
|
|
214
218
|
- [Workflows](docs/user_guide/WORKFLOWS.md)
|
|
215
219
|
- [FAQ](docs/user_guide/FAQ.md)
|
|
216
220
|
- [0.2 migration guide](docs/user_guide/MIGRATING_TO_0_2.md)
|
|
221
|
+
- [Recovery guide](docs/user_guide/RECOVERY.md)
|
|
217
222
|
- [Architecture decisions](docs/architecture/README.md)
|
|
218
223
|
- [Refactor case study](docs/architecture/portfolio-case-study.md)
|
|
219
224
|
- [0.2 release checklist](docs/releases/0.2.0-checklist.md)
|
|
@@ -228,7 +233,9 @@ product direction.
|
|
|
228
233
|
|
|
229
234
|
## Project status
|
|
230
235
|
|
|
231
|
-
|
|
236
|
+
This checkout targets 0.3.1; the workflow shortcuts below describe that version. See the [next-release checklist](docs/releases/NEXT_RELEASE.md)
|
|
237
|
+
for the remaining publication checks. The architecture was established through
|
|
238
|
+
thirteen independently verified refactor phases for 0.2.0.
|
|
232
239
|
See the
|
|
233
240
|
[execution plan](docs/architecture/refactor-execution-plan.md) and published
|
|
234
241
|
[checkpoint reports](docs/architecture/README.md#execution-checkpoints).
|
|
@@ -236,3 +243,27 @@ See the
|
|
|
236
243
|
## License
|
|
237
244
|
|
|
238
245
|
[MIT](LICENSE.md)
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
### Small workflow shortcuts
|
|
249
|
+
|
|
250
|
+
- Ambiguous issue, project, and milestone lookups list matching IDs and labels.
|
|
251
|
+
- Plain health output offers repair-preview commands; previews never apply repairs.
|
|
252
|
+
- `roadmap config explain output.format` shows the effective value and its source;
|
|
253
|
+
add `--format json` for structured output.
|
|
254
|
+
- Capture a created issue ID without parsing prose:
|
|
255
|
+
|
|
256
|
+
```sh
|
|
257
|
+
issue_id=$(roadmap issue create --title "Improve recovery guidance" --print-id)
|
|
258
|
+
roadmap issue view "$issue_id"
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
`--print-id` keeps warnings and branch notifications on stderr. A subsequent
|
|
262
|
+
Git-branch failure still returns nonzero; the printed ID identifies the already
|
|
263
|
+
created issue, so inspect it before retrying creation.
|
|
264
|
+
|
|
265
|
+
Enable [shell completion](docs/user_guide/SHELL_COMPLETION.md) for commands,
|
|
266
|
+
options, and choice values.
|
|
267
|
+
|
|
268
|
+
The reviewed command and option contracts, compatibility guidance, and examples
|
|
269
|
+
are in the [CLI correctness guide](docs/architecture/cli-correctness-closeout.md).
|
|
@@ -5,7 +5,13 @@ their planning data in reviewable Markdown and YAML files rather than a hosted
|
|
|
5
5
|
service. It supports issues, dependencies, comments, projects, milestones,
|
|
6
6
|
daily views, health checks, and machine-readable exports.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Version **0.3.1** adds CLI workflow improvements and reliability fixes. Use the
|
|
9
|
+
[versioned documentation](https://github.com/shanewilkins/roadmap/tree/v0.3.1/docs)
|
|
10
|
+
and [0.3.1 changelog](CHANGELOG.md#031---2026-10-08) for this version.
|
|
11
|
+
Source checkouts can precede package publication; check
|
|
12
|
+
[PyPI](https://pypi.org/project/roadmap-cli/) for available package versions.
|
|
13
|
+
|
|
14
|
+
The retained CLI and data behavior is defined
|
|
9
15
|
by an explicit
|
|
10
16
|
[public compatibility contract](docs/architecture/public-contract-0.2.md).
|
|
11
17
|
0.3 is an internal quality-hardening release; the 0.2 CLI and data contract is
|
|
@@ -92,7 +98,7 @@ Organize delivery:
|
|
|
92
98
|
|
|
93
99
|
```bash
|
|
94
100
|
roadmap project create --title "Web application"
|
|
95
|
-
roadmap milestone create --title "0.2" --due-date 2026-09-30
|
|
101
|
+
roadmap milestone create --title "0.2" --due-date 2026-09-30 --project "Web application"
|
|
96
102
|
roadmap milestone assign <issue-id> "0.2"
|
|
97
103
|
roadmap milestone view "0.2"
|
|
98
104
|
```
|
|
@@ -164,6 +170,7 @@ migration. Do not treat the internal SQLite schema as a public API.
|
|
|
164
170
|
- [Workflows](docs/user_guide/WORKFLOWS.md)
|
|
165
171
|
- [FAQ](docs/user_guide/FAQ.md)
|
|
166
172
|
- [0.2 migration guide](docs/user_guide/MIGRATING_TO_0_2.md)
|
|
173
|
+
- [Recovery guide](docs/user_guide/RECOVERY.md)
|
|
167
174
|
- [Architecture decisions](docs/architecture/README.md)
|
|
168
175
|
- [Refactor case study](docs/architecture/portfolio-case-study.md)
|
|
169
176
|
- [0.2 release checklist](docs/releases/0.2.0-checklist.md)
|
|
@@ -178,7 +185,9 @@ product direction.
|
|
|
178
185
|
|
|
179
186
|
## Project status
|
|
180
187
|
|
|
181
|
-
|
|
188
|
+
This checkout targets 0.3.1; the workflow shortcuts below describe that version. See the [next-release checklist](docs/releases/NEXT_RELEASE.md)
|
|
189
|
+
for the remaining publication checks. The architecture was established through
|
|
190
|
+
thirteen independently verified refactor phases for 0.2.0.
|
|
182
191
|
See the
|
|
183
192
|
[execution plan](docs/architecture/refactor-execution-plan.md) and published
|
|
184
193
|
[checkpoint reports](docs/architecture/README.md#execution-checkpoints).
|
|
@@ -186,3 +195,27 @@ See the
|
|
|
186
195
|
## License
|
|
187
196
|
|
|
188
197
|
[MIT](LICENSE.md)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
### Small workflow shortcuts
|
|
201
|
+
|
|
202
|
+
- Ambiguous issue, project, and milestone lookups list matching IDs and labels.
|
|
203
|
+
- Plain health output offers repair-preview commands; previews never apply repairs.
|
|
204
|
+
- `roadmap config explain output.format` shows the effective value and its source;
|
|
205
|
+
add `--format json` for structured output.
|
|
206
|
+
- Capture a created issue ID without parsing prose:
|
|
207
|
+
|
|
208
|
+
```sh
|
|
209
|
+
issue_id=$(roadmap issue create --title "Improve recovery guidance" --print-id)
|
|
210
|
+
roadmap issue view "$issue_id"
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
`--print-id` keeps warnings and branch notifications on stderr. A subsequent
|
|
214
|
+
Git-branch failure still returns nonzero; the printed ID identifies the already
|
|
215
|
+
created issue, so inspect it before retrying creation.
|
|
216
|
+
|
|
217
|
+
Enable [shell completion](docs/user_guide/SHELL_COMPLETION.md) for commands,
|
|
218
|
+
options, and choice values.
|
|
219
|
+
|
|
220
|
+
The reviewed command and option contracts, compatibility guidance, and examples
|
|
221
|
+
are in the [CLI correctness guide](docs/architecture/cli-correctness-closeout.md).
|
|
@@ -13,7 +13,7 @@ build-backend = "hatchling.build"
|
|
|
13
13
|
# Installs the locked runtime and development dependency sets.
|
|
14
14
|
# ============================================================================
|
|
15
15
|
name = "roadmap-cli"
|
|
16
|
-
version = "0.3.
|
|
16
|
+
version = "0.3.1"
|
|
17
17
|
description = "Git-native command line tool for local project roadmap management"
|
|
18
18
|
readme = "README.md"
|
|
19
19
|
requires-python = ">=3.12,<4.0"
|
|
@@ -59,25 +59,23 @@ dependencies = [
|
|
|
59
59
|
dev = [
|
|
60
60
|
"pytest>=9.0.3",
|
|
61
61
|
"pytest-cov>=7.1.0",
|
|
62
|
-
"
|
|
63
|
-
"pytest-aiohttp>=1.1.0",
|
|
64
|
-
"ruff==0.16.5",
|
|
62
|
+
"ruff>=0.16.10",
|
|
65
63
|
"pre-commit>=4.6.0",
|
|
66
64
|
"bandit[toml]>=1.9.4",
|
|
67
65
|
"radon>=6.0.1,<7.0.0",
|
|
68
66
|
"xenon>=0.9.3,<1.0.0",
|
|
69
67
|
"pytest-xdist>=3.8.0",
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
68
|
+
"ty>=0.0.84",
|
|
69
|
+
"import-linter>=2.11,<3",
|
|
70
|
+
"markdown-it-py>=4.2,<5",
|
|
71
|
+
"vulture>=2.14,<3",
|
|
74
72
|
]
|
|
75
73
|
|
|
76
74
|
[project.urls]
|
|
77
75
|
Homepage = "https://github.com/shanewilkins/roadmap"
|
|
78
76
|
Repository = "https://github.com/shanewilkins/roadmap"
|
|
79
77
|
Issues = "https://github.com/shanewilkins/roadmap/issues"
|
|
80
|
-
Documentation = "https://github.com/shanewilkins/roadmap/tree/
|
|
78
|
+
Documentation = "https://github.com/shanewilkins/roadmap/tree/master/docs"
|
|
81
79
|
|
|
82
80
|
[project.scripts]
|
|
83
81
|
roadmap = "roadmap.bootstrap:main"
|
|
@@ -113,10 +111,9 @@ include = [
|
|
|
113
111
|
# - ruff.toml: Linting and formatting rules
|
|
114
112
|
# - bandit.toml: Security scanning configuration
|
|
115
113
|
# - .coveragerc: Test coverage thresholds and exclusions
|
|
116
|
-
# -
|
|
114
|
+
# - tool.ty below: Type checking configuration
|
|
117
115
|
|
|
118
|
-
# ty
|
|
119
|
-
# cleanup, see notes/path_to_1_point_0.md).
|
|
116
|
+
# ty is the sole type checker, enforced in CI and pre-commit.
|
|
120
117
|
[tool.ty.src]
|
|
121
118
|
include = ["roadmap", "tests"]
|
|
122
119
|
# These fixture trees are synthetic "roadmap" packages used only for the
|
|
@@ -127,6 +124,15 @@ exclude = ["tests/policy/fixtures/architecture"]
|
|
|
127
124
|
[tool.ty.environment]
|
|
128
125
|
python-version = "3.12"
|
|
129
126
|
|
|
127
|
+
[tool.ty.rules]
|
|
128
|
+
unresolved-import = "error"
|
|
129
|
+
unresolved-reference = "error"
|
|
130
|
+
invalid-argument-type = "error"
|
|
131
|
+
invalid-assignment = "error"
|
|
132
|
+
invalid-return-type = "error"
|
|
133
|
+
possibly-missing-attribute = "error"
|
|
134
|
+
unresolved-attribute = "error"
|
|
135
|
+
|
|
130
136
|
[tool.pytest.ini_options]
|
|
131
137
|
testpaths = ["tests"]
|
|
132
138
|
python_files = ["test_*.py"]
|
|
@@ -141,17 +147,5 @@ markers = [
|
|
|
141
147
|
"mock_scanning: Tests with mocked repository scanning operations",
|
|
142
148
|
"no_xdist: Tests that should not run in parallel (disables xdist parallelization)"
|
|
143
149
|
]
|
|
144
|
-
filterwarnings = [
|
|
145
|
-
"ignore::pytest_benchmark.logger.PytestBenchmarkWarning"
|
|
146
|
-
]
|
|
147
|
-
|
|
148
|
-
[dependency-groups]
|
|
149
|
-
dev = [
|
|
150
|
-
"pytest-asyncio>=1.4.0",
|
|
151
|
-
"pytest-benchmark>=5.2.3",
|
|
152
|
-
"pytest-cov>=7.1.0",
|
|
153
|
-
"pytest-mock>=3.15.1",
|
|
154
|
-
"pytest-xdist>=3.8.0",
|
|
155
|
-
]
|
|
156
150
|
|
|
157
151
|
# Coverage configuration moved to config/.coveragerc
|
|
@@ -4,10 +4,10 @@ from importlib.metadata import PackageNotFoundError, version
|
|
|
4
4
|
|
|
5
5
|
# Installed artifacts read their distribution metadata; source checkouts use the
|
|
6
6
|
# matching fallback without importing the executable adapter as a side effect.
|
|
7
|
-
__version__ = "0.3.
|
|
7
|
+
__version__ = "0.3.1"
|
|
8
8
|
try:
|
|
9
9
|
__version__ = version("roadmap-cli")
|
|
10
10
|
except PackageNotFoundError:
|
|
11
|
-
__version__ = "0.3.
|
|
11
|
+
__version__ = "0.3.1"
|
|
12
12
|
|
|
13
13
|
__all__ = ["__version__"]
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Lazy Click adapter assembled by :mod:`roadmap.bootstrap`."""
|
|
2
2
|
|
|
3
3
|
import importlib
|
|
4
|
+
import stat
|
|
4
5
|
from collections.abc import Callable, Mapping
|
|
5
6
|
from dataclasses import dataclass
|
|
6
7
|
from pathlib import Path
|
|
@@ -12,7 +13,9 @@ import click
|
|
|
12
13
|
def _handle_cli_exception(ctx: click.Context, error: Exception) -> Any:
|
|
13
14
|
from roadmap.adapters.inbound.cli.exception_handler import handle_cli_exception
|
|
14
15
|
|
|
15
|
-
return handle_cli_exception(
|
|
16
|
+
return handle_cli_exception(
|
|
17
|
+
ctx, error, show_traceback=bool(ctx.find_root().params.get("debug", False))
|
|
18
|
+
)
|
|
16
19
|
|
|
17
20
|
|
|
18
21
|
CommandLocation = tuple[str, str, str]
|
|
@@ -67,6 +70,7 @@ class CliRuntime:
|
|
|
67
70
|
migration_factory: Callable[[], Any]
|
|
68
71
|
initialization_factory: Callable[[str], Any]
|
|
69
72
|
version: str
|
|
73
|
+
workspace_factories: Callable[[Path], dict[str, Any]] | None = None
|
|
70
74
|
|
|
71
75
|
|
|
72
76
|
class RoadmapClickGroup(click.Group):
|
|
@@ -92,7 +96,7 @@ class RoadmapClickGroup(click.Group):
|
|
|
92
96
|
"""Render root help from static metadata without importing features."""
|
|
93
97
|
names = sorted(self._command_registry)
|
|
94
98
|
limit = formatter.width - 6 - max(map(len, names), default=0)
|
|
95
|
-
rows = [(name, click.
|
|
99
|
+
rows = [(name, click.Command(name, help=self._command_registry[name][2]).get_short_help_str(limit)) for name in names] # fmt: skip
|
|
96
100
|
with formatter.section("Commands"):
|
|
97
101
|
formatter.write_dl(rows)
|
|
98
102
|
|
|
@@ -106,13 +110,7 @@ class RoadmapClickGroup(click.Group):
|
|
|
106
110
|
if location is None:
|
|
107
111
|
return None
|
|
108
112
|
module_path, attribute, _help = location
|
|
109
|
-
|
|
110
|
-
self._command_cache[cmd_name] = command = getattr(importlib.import_module(module_path), attribute) # fmt: skip
|
|
111
|
-
except Exception as error:
|
|
112
|
-
self._console_factory().print(
|
|
113
|
-
f"⚠️ Failed to load command '{cmd_name}': {error}", style="yellow"
|
|
114
|
-
)
|
|
115
|
-
return None
|
|
113
|
+
self._command_cache[cmd_name] = command = getattr(importlib.import_module(module_path), attribute) # fmt: skip
|
|
116
114
|
return command
|
|
117
115
|
|
|
118
116
|
def invoke(self, ctx: click.Context) -> Any:
|
|
@@ -138,8 +136,16 @@ def create_cli(
|
|
|
138
136
|
console_factory=runtime.console_factory,
|
|
139
137
|
)
|
|
140
138
|
@click.version_option(version=runtime.version)
|
|
139
|
+
@click.option(
|
|
140
|
+
"--debug", is_flag=True, help="Show tracebacks for unexpected errors."
|
|
141
|
+
)
|
|
142
|
+
@click.option(
|
|
143
|
+
"--workspace",
|
|
144
|
+
type=click.Path(path_type=Path),
|
|
145
|
+
help="Canonical workspace directory; overrides the current-directory default.",
|
|
146
|
+
)
|
|
141
147
|
@click.pass_context
|
|
142
|
-
def cli(ctx: click.Context) -> None:
|
|
148
|
+
def cli(ctx: click.Context, debug: bool, workspace: Path | None) -> None: # noqa: ARG001
|
|
143
149
|
"""Roadmap CLI - A command line tool for creating and managing roadmaps."""
|
|
144
150
|
ctx.ensure_object(dict)
|
|
145
151
|
ctx.obj.setdefault("core_factory", runtime.core_factory)
|
|
@@ -147,12 +153,34 @@ def create_cli(
|
|
|
147
153
|
ctx.obj.setdefault("console_factory", runtime.console_factory)
|
|
148
154
|
ctx.obj.setdefault("migration_factory", runtime.migration_factory)
|
|
149
155
|
ctx.obj.setdefault("initialization_factory", runtime.initialization_factory)
|
|
156
|
+
if workspace is not None:
|
|
157
|
+
if runtime.workspace_factories is None:
|
|
158
|
+
raise click.ClickException(
|
|
159
|
+
"Explicit workspace selection requires Bootstrap"
|
|
160
|
+
)
|
|
161
|
+
selected = workspace.expanduser().absolute()
|
|
162
|
+
ctx.obj.update(runtime.workspace_factories(selected))
|
|
163
|
+
ctx.obj["workspace"] = selected
|
|
164
|
+
ctx.obj.pop("core", None)
|
|
165
|
+
if ctx.invoked_subcommand not in {None, "init", "migrate"}:
|
|
166
|
+
try:
|
|
167
|
+
valid = stat.S_ISDIR(selected.stat().st_mode) and stat.S_ISREG(
|
|
168
|
+
(selected / "config.yaml").stat().st_mode
|
|
169
|
+
)
|
|
170
|
+
except OSError as error:
|
|
171
|
+
raise click.ClickException(
|
|
172
|
+
f"Cannot open explicit workspace {selected}: {error}"
|
|
173
|
+
) from error
|
|
174
|
+
if not valid:
|
|
175
|
+
raise click.ClickException(
|
|
176
|
+
f"Explicit workspace is not initialized: {selected}"
|
|
177
|
+
)
|
|
150
178
|
if (
|
|
151
179
|
ctx.invoked_subcommand not in {None, "init", "migrate"}
|
|
152
180
|
and "core" not in ctx.obj
|
|
153
181
|
):
|
|
154
182
|
try:
|
|
155
|
-
ctx.obj["core"] =
|
|
183
|
+
ctx.obj["core"] = ctx.obj["core_factory"](".roadmap")
|
|
156
184
|
except Exception as error:
|
|
157
185
|
_handle_cli_exception(ctx, error)
|
|
158
186
|
|