tcw-cli 2.1.3__tar.gz → 2.2.0__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.
Files changed (151) hide show
  1. {tcw_cli-2.1.3/tcw_cli.egg-info → tcw_cli-2.2.0}/PKG-INFO +153 -42
  2. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/README.md +152 -41
  3. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/pyproject.toml +1 -1
  4. tcw_cli-2.2.0/tcw/__init__.py +1 -0
  5. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/capabilities/cli.py +12 -8
  6. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/serve/__init__.py +41 -0
  7. tcw_cli-2.1.3/tcw/serve/dist/client/assets/index-Dz5B7M8G.js → tcw_cli-2.2.0/tcw/serve/dist/client/assets/index-CCjF_dHr.js +24 -24
  8. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/serve/dist/client/index.html +1 -1
  9. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/store/base.py +306 -5
  10. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/store/fs.py +48 -3
  11. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/taxonomy/cli.py +9 -7
  12. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/tracker/intake.py +87 -65
  13. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/tracker/jira.py +30 -0
  14. tcw_cli-2.2.0/tcw/tracker/progress.py +163 -0
  15. tcw_cli-2.2.0/tcw/tracker/sync.py +410 -0
  16. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/work/cli.py +595 -87
  17. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/work/projection.py +63 -0
  18. {tcw_cli-2.1.3 → tcw_cli-2.2.0/tcw_cli.egg-info}/PKG-INFO +153 -42
  19. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw_cli.egg-info/SOURCES.txt +12 -1
  20. tcw_cli-2.2.0/tests/test_cli_help_coverage.py +55 -0
  21. tcw_cli-2.2.0/tests/test_configuration_text_home.py +61 -0
  22. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_documentation_config.py +2 -1
  23. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_documentation_sync_wiring.py +24 -24
  24. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_eval_fixture.py +1 -1
  25. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_eval_grading.py +51 -0
  26. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_plugin_manifests.py +1 -1
  27. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_repo_lifecycle.py +3 -1
  28. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_skill_lifecycle_parity.py +133 -56
  29. tcw_cli-2.2.0/tests/test_skill_path_pointers.py +25 -0
  30. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_tracker_binding.py +27 -6
  31. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_tracker_client.py +25 -0
  32. tcw_cli-2.2.0/tests/test_tracker_comment.py +550 -0
  33. tcw_cli-2.2.0/tests/test_tracker_help.py +88 -0
  34. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_tracker_import.py +2 -3
  35. tcw_cli-2.2.0/tests/test_tracker_link.py +295 -0
  36. tcw_cli-2.2.0/tests/test_tracker_strict.py +714 -0
  37. tcw_cli-2.2.0/tests/test_tracker_surface.py +405 -0
  38. tcw_cli-2.2.0/tests/test_tracker_sync.py +965 -0
  39. tcw_cli-2.2.0/tests/test_tracker_sync_config.py +113 -0
  40. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_tracker_validate.py +7 -5
  41. tcw_cli-2.1.3/tcw/__init__.py +0 -1
  42. tcw_cli-2.1.3/tests/test_tracker_link.py +0 -192
  43. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/LICENSE +0 -0
  44. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/setup.cfg +0 -0
  45. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/capabilities/__init__.py +0 -0
  46. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/cli.py +0 -0
  47. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/refs.py +0 -0
  48. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/serve/dist/client/assets/index-CXNiOIeg.css +0 -0
  49. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/serve/dist/client/theme-init.js +0 -0
  50. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/serve/dist/server.cjs +0 -0
  51. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/serve/runtime.py +0 -0
  52. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/stdin.py +0 -0
  53. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/store/__init__.py +0 -0
  54. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/store/checkouts.py +0 -0
  55. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/store/project.py +0 -0
  56. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/taxonomy/__init__.py +0 -0
  57. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/tracker/__init__.py +0 -0
  58. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/tracker/claim.py +0 -0
  59. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/validate.py +0 -0
  60. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/work/__init__.py +0 -0
  61. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/work/generate.py +0 -0
  62. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/work/hooks.py +0 -0
  63. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/work/prompts/implement.md +0 -0
  64. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/work/prompts/inbox.md +0 -0
  65. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/work/prompts/plan.md +0 -0
  66. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/work/prompts/postmortem.md +0 -0
  67. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/work/prompts/request.md +0 -0
  68. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/work/prompts/spec.md +0 -0
  69. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/work/prompts/verify.md +0 -0
  70. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/work/recursion.py +0 -0
  71. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/work/resolve.py +0 -0
  72. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw/work/templates.py +0 -0
  73. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw_cli.egg-info/dependency_links.txt +0 -0
  74. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw_cli.egg-info/entry_points.txt +0 -0
  75. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw_cli.egg-info/requires.txt +0 -0
  76. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tcw_cli.egg-info/top_level.txt +0 -0
  77. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_body_prompt.py +0 -0
  78. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_capabilities.py +0 -0
  79. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_capabilities_federation.py +0 -0
  80. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_capabilities_reset.py +0 -0
  81. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_capabilities_rm.py +0 -0
  82. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_capabilities_sidecar.py +0 -0
  83. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_capability_ref_wording.py +0 -0
  84. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_committed_paths.py +0 -0
  85. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_cut_version.py +0 -0
  86. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_documentation_prompt.py +0 -0
  87. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_documented_cli_surface.py +0 -0
  88. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_environment_hardness.py +0 -0
  89. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_epic_completable.py +0 -0
  90. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_eval_coverage.py +0 -0
  91. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_eval_files_changed.py +0 -0
  92. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_eval_runner.py +0 -0
  93. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_external_work_store.py +0 -0
  94. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_falsification_rule.py +0 -0
  95. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_generate_hook.py +0 -0
  96. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_inbox_title.py +0 -0
  97. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_lifecycle_baseline.py +0 -0
  98. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_lifecycle_hooks.py +0 -0
  99. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_lifecycle_inert.py +0 -0
  100. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_lifecycle_policy.py +0 -0
  101. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_lifecycle_validation.py +0 -0
  102. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_multiproject.py +0 -0
  103. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_non_git_writes.py +0 -0
  104. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_project_overrides.py +0 -0
  105. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_project_registry.py +0 -0
  106. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_projection.py +0 -0
  107. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_prompt_fallback.py +0 -0
  108. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_qualified_ref.py +0 -0
  109. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_recursion.py +0 -0
  110. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_refs.py +0 -0
  111. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_remote_session_setup.py +0 -0
  112. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_resolve.py +0 -0
  113. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_retention.py +0 -0
  114. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_scaffold.py +0 -0
  115. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_serve.py +0 -0
  116. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_serve_descendants.py +0 -0
  117. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_serve_projection.py +0 -0
  118. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_serve_resolve.py +0 -0
  119. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_serve_runtime.py +0 -0
  120. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_serve_write.py +0 -0
  121. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_session_bootstrap.py +0 -0
  122. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_shipped_prompts.py +0 -0
  123. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_show_json.py +0 -0
  124. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_skill_flow.py +0 -0
  125. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_smoke.py +0 -0
  126. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_stage_verb.py +0 -0
  127. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_status_parity.py +0 -0
  128. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_stdin.py +0 -0
  129. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_stdin_cli.py +0 -0
  130. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_store_bounds.py +0 -0
  131. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_store_editor.py +0 -0
  132. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_store_nodes.py +0 -0
  133. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_store_provisioning.py +0 -0
  134. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_store_publication.py +0 -0
  135. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_subprocess_stdin.py +0 -0
  136. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_taxonomy.py +0 -0
  137. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_tombstone.py +0 -0
  138. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_tracker_absent.py +0 -0
  139. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_tracker_claim.py +0 -0
  140. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_tracker_claimability.py +0 -0
  141. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_tracker_cli.py +0 -0
  142. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_tracker_config.py +0 -0
  143. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_tracker_inheritance.py +0 -0
  144. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_tracker_replay.py +0 -0
  145. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_unpushed_version_script.py +0 -0
  146. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_validate.py +0 -0
  147. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_validate_target.py +0 -0
  148. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_work.py +0 -0
  149. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_work_autocommit.py +0 -0
  150. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_work_review.py +0 -0
  151. {tcw_cli-2.1.3 → tcw_cli-2.2.0}/tests/test_work_tags.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tcw-cli
3
- Version: 2.1.3
3
+ Version: 2.2.0
4
4
  Summary: Taxonomy · Capabilities · Work — a storage-abstracted framework for describing and evolving a software project.
5
5
  License: Apache License
6
6
  Version 2.0, January 2004
@@ -247,7 +247,7 @@ other's content.
247
247
  - [Documentation](#documentation)
248
248
  - [Skills — the judgment layer](#skills--the-judgment-layer)
249
249
  - [Reading a lifecycle stage](#reading-a-lifecycle-stage)
250
- - [Review agents and slash commands](#review-agents-and-slash-commands)
250
+ - [Review agents and command skills](#review-agents-and-command-skills)
251
251
  - [Status](#status)
252
252
  - [Further reading](#further-reading)
253
253
 
@@ -430,20 +430,20 @@ by installing `tcw-cli` from PyPI with `pipx`, so one installed mid-session
430
430
  cannot run until the next one begins. That first session needs network access. It
431
431
  installs over an existing `pipx install tcw-cli` rather than beside it, and
432
432
  leaves a development checkout (`pip install -e .`) alone. If `tcw` goes missing
433
- anyway, `pipx install tcw-cli` is the whole fix — the **`tcw-plugin`** skill
433
+ anyway, `pipx install tcw-cli` is the whole fix — the **`tcw-setup`** skill
434
434
  carries the cases where it is not.
435
435
 
436
- In **Codex** (skills only, no slash commands):
436
+ In **Codex**:
437
437
 
438
438
  ```bash
439
439
  codex plugin marketplace add brocef/TCW --ref main
440
440
  codex plugin add tcw@tcw
441
441
  ```
442
442
 
443
- Codex has no session-start hook, so ask the agent to run the **`tcw-plugin`**
444
- setup — it runs the same install script Claude runs automatically.
443
+ Codex has no session-start hook, so ask the agent to run the **`tcw-setup`**
444
+ skill — it runs the same install script Claude runs automatically.
445
445
 
446
- The plugin ships the agent skills, slash commands, and read-only review agents
446
+ The plugin ships the agent skills, command skills, and read-only review agents
447
447
  listed under [Skills](#skills--the-judgment-layer).
448
448
 
449
449
  ### As a Python package
@@ -565,8 +565,10 @@ projects. Each component group also has its own `init`: `tcw taxonomy init`,
565
565
  `tcw capabilities init`, `tcw work init`.
566
566
 
567
567
  To bootstrap a taxonomy or capabilities ledger on a project that already has a
568
- codebase, run `/tcw-taxonomy-init` or `/tcw-capabilities-init` — the assistant
569
- studies your code, proposes a first draft, refines it with you, and writes it.
568
+ codebase, ask for the `tcw-setup` skill — the assistant studies your code,
569
+ proposes a first draft, refines it with you, and writes it. To change a working
570
+ project's configuration afterwards — documentation entries, lifecycle bindings,
571
+ a tracker, where stores live — ask for the `tcw-configure` skill.
570
572
 
571
573
  ---
572
574
 
@@ -579,8 +581,9 @@ a work item.
579
581
  tcw work tracker list # tickets the configured query selects
580
582
  tcw work tracker show ENG-482 # one ticket, and whether it is yours to take
581
583
  tcw work tracker import ENG-482 # take the ticket and get a work item for it
582
- tcw work tracker link <slug> ENG-482 # take it for an item you already have
584
+ tcw work tracker link <slug> ENG-482 # record that an item and a ticket are the same work
583
585
  tcw work tracker unlink <slug> --reason "wrong ticket"
586
+ tcw work tracker sync --all # retry tickets that did not follow their items
584
587
  ```
585
588
 
586
589
  Configuration goes in the node's `tcw-config.yaml`:
@@ -596,6 +599,11 @@ work:
596
599
  token-env: TCW_JIRA_API_TOKEN
597
600
  transitions:
598
601
  claim: Start Progress
602
+ statuses: # optional: where a bound ticket goes as its item moves
603
+ active: In Progress
604
+ review: In Review
605
+ completed: Done
606
+ discarded: Won't Do
599
607
  timeout-seconds: 15 # optional
600
608
  ```
601
609
 
@@ -654,14 +662,113 @@ refused, and so is one that is already closed.
654
662
  Running `import` again for the same ticket in the same node gives you the same item
655
663
  rather than a second one, and if the first run took the ticket but stopped before creating the
656
664
  item, the second run finishes the job. One ticket can deliberately become several
657
- items with `--part api`, `--part web`, and so on. `unlink` removes a wrong binding
658
- and keeps a record of it with your reason; it never changes the ticket in Jira.
659
-
660
- Three limits to know. On a workflow that lets anyone start a ticket from any status,
661
- two people can both take the same ticket, and TCW does not stop that. Two runs by the
662
- same Jira account at the same moment can both create an item. And each node keeps its
665
+ items with `--part api`, `--part web`, and so on.
666
+
667
+ **Recording that a ticket and an item are the same work.** `tracker link` is the
668
+ other half, and it does only that: it writes the cross-reference down and leaves
669
+ Jira alone. The ticket keeps its status and whoever holds it — you can link a ticket
670
+ somebody else is assigned, because writing a note about a ticket takes it from
671
+ nobody. On your side nothing but the binding is written, so the item keeps its
672
+ status, its owner and its documents. Any item can be linked, a finished one
673
+ included, which is how work that is already done gets tied to the ticket that
674
+ tracked it; the same goes for `unlink`, so a binding pointed at the wrong ticket is
675
+ repairable wherever you find it. A finished item's folder is kept out of git by
676
+ default, so a binding on one stays on your machine along with the rest of that
677
+ item. `unlink` keeps a record of what was bound and your
678
+ reason, and like `link` it never changes the ticket in Jira.
679
+
680
+ **Seeing which ticket an item answers.** A bound item says so wherever you read it:
681
+ `tcw work show` adds a `tracker:` line with the ticket, the provider, the part and
682
+ the ticket's link; its row on `tcw work list` ends with the ticket key, and notes the part and anything
683
+ not yet sent to the ticket; `tcw work show
684
+ --json` carries it as `tracker`; and `tcw serve`'s item page shows the ticket as a
685
+ link. What you see is what the binding records, not what Jira says right now, so
686
+ none of it needs the tracker configured or reachable. A binding file that cannot be
687
+ read is reported in the same places instead of breaking the board.
688
+
689
+ **Tickets follow their items.** `link` claims nothing, so `tcw work start` does:
690
+ starting a bound item claims its ticket by the same rules `import` uses. After that,
691
+ `submit`, `rework`, `complete` and discarding move the ticket to the status you map
692
+ the item's new status to under `statuses` (`discarded` can name a status per
693
+ resolution, such as `duplicate: Duplicate`); a status you leave out sends nothing,
694
+ and `active` is required once you map any other. `import` on a ticket that is only
695
+ linked still refuses rather than claiming it.
696
+
697
+ TCW moves a ticket only when it is assigned to you and is still where the item's
698
+ previous status left it. A ticket someone else holds, one moved on in Jira, or one
699
+ whose workflow does not offer a single transition to the mapped status is left
700
+ alone. Your local move always happens and is committed first; when the ticket does
701
+ not follow, the command exits 1, says the item moved, and records why — *pending*
702
+ when Jira could not be reached or your credentials are missing, *conflicting* when
703
+ Jira's answer stopped it. `tcw work show` and `tcw work list` show that state, and
704
+ `tcw work tracker sync <slug>` (or `--all`) retries it once the cause is fixed. `sync`
705
+ acts only on items you started, because it acts as whoever runs it. A ticket that
706
+ followed first time leaves no record and no change in your repository.
707
+
708
+ Two things are not caught: a move made in `tcw serve`, and a command interrupted
709
+ between its commit and its call to Jira, leave no record, so the board shows them as
710
+ in step; `sync <slug>` checks such an item but will not move its ticket. And a
711
+ binding whose ticket link is on a different Jira site from the one configured is
712
+ never written through — `import` and `link` refuse it and name the item.
713
+
714
+ Five limits to know. A ticket bound to several parts moves only when the last open
715
+ part here moves; parts in other nodes are not seen. On a workflow that lets anyone start a ticket from any status,
716
+ two people can both take the same ticket, and TCW does not stop that outside strict
717
+ mode (below). Two runs by the
718
+ same Jira account at the same moment can both create an item. Each node keeps its
663
719
  own bindings: importing one ticket in two nodes of a workspace, even nodes sharing
664
- inherited settings, gives two items, one in each.
720
+ inherited settings, gives two items, one in each. And a ticket held by a finished
721
+ item can be bound to a second item, open or finished, with no warning — a discarded
722
+ item's ticket is meant to be available again, and TCW cannot tell that case from the
723
+ other.
724
+
725
+ **Comments on the ticket.** Set `comments: true` in the `tracker` block and each
726
+ move also leaves a short comment on the ticket, such as
727
+ `TCW: "Checkout page" (part api) went to review.`, for anyone who follows the work
728
+ in Jira rather than in the repository. A `link` template adds a link, for example
729
+ `link: https://tcw.example.com/work/{slug}` for a team that hosts `tcw serve`; the
730
+ only placeholders are `{project}` and `{slug}`. Nothing from `spec.md`, `plan.md` or
731
+ the other lifecycle documents is ever copied. A comment is posted only while the
732
+ ticket is assigned to you, and a ticket held by someone else gets none. When a
733
+ comment cannot be posted, the command exits 1, `show` prints a `tracker comment:`
734
+ line, and `tcw work tracker sync` sends it later. Before resending, it looks for the
735
+ comment on the ticket, so a post that landed without an answer is not repeated.
736
+ Limits: a newer move's comment replaces one still waiting; two runs at once, or an
737
+ edited or deleted comment, can still give a repeat; moves in `tcw serve` post
738
+ nothing. On a Jira Service Management project a comment may be visible to
739
+ customers, so leave comments off there unless item titles may be seen. Every copy
740
+ of `tcw` on the project must understand these keys before you set them: an older
741
+ one treats the whole `tracker` block as broken.
742
+
743
+ **Strict mode: no work without a ticket.** Set `strict: true` in the `tracker` block
744
+ when every piece of work must come from a ticket you have claimed. Then:
745
+
746
+ - `tcw work new` and `tcw work inbox accept` refuse and point you at
747
+ `tcw work tracker import <ticket>`. `new --epic` is allowed; epics are never gated.
748
+ - `tcw work start` refuses an item with no ticket. For a bound item it claims the
749
+ ticket *first*, and starts the item only if the claim worked.
750
+ - `submit`, `rework` and completing as `done` read the ticket first and refuse unless
751
+ it is assigned to you and is where the item's last step left it. A `--worktree`
752
+ item is checked before anything is merged.
753
+ - A claim on a workflow that would let a second person claim the same ticket is
754
+ refused, by `start` and by `import`; the ticket is left claimed for you to release.
755
+ - An epic can be created and started, since it only groups work, but not with
756
+ `--worktree`.
757
+ - A ticket shared by several parts is recognised only from the parts' items in
758
+ this checkout. If the part that held the ticket back was completed elsewhere, or
759
+ was not kept (`work.retain`), the last part's `complete` is refused; put the
760
+ ticket in the status the message names, or discard.
761
+ - Discarding is always allowed. `drop` refuses an item that was ever bound — discard
762
+ it instead, so the record stays.
763
+ - `tcw serve` refuses the same changes, since it cannot check a ticket, and names the
764
+ command to use.
765
+
766
+ A refusal changes nothing in your project and says what to fix; a `start` or `import`
767
+ refused after claiming leaves the ticket claimed. There is no flag to get past it;
768
+ `--force` and `--take-over` do not. Strict mode needs Jira: while it cannot be
769
+ reached, gated commands refuse. It also needs `statuses.active`,
770
+ `statuses.completed` and a `statuses.discarded` covering every discard reason, which
771
+ `tcw validate` checks. To turn it off, set `strict: false` or remove the key.
665
772
 
666
773
  Two guarantees worth stating plainly. A project with no `tracker` block behaves
667
774
  exactly as before, with no new required setting and no network access. And
@@ -691,48 +798,52 @@ Every command group also has `--help`, and a `check` that validates its tree.
691
798
  ## Skills — the judgment layer
692
799
 
693
800
  The CLI is the _mechanism_. Fifteen skills in [`skills/`](skills/) supply the
694
- _judgment_ that drives it — the parts a deterministic tool cannot decide. Nine
695
- carry a distinct procedure; the other six all compose one lifecycle stage and
696
- are listed together at the end.
801
+ _judgment_ that drives it — the parts a deterministic tool cannot decide. They
802
+ come in three groups, told apart by name: eight core skills (seven in the table
803
+ below, and `tcw-work-stage`, which composes a lifecycle stage and is described
804
+ after it), four `tcw-commands-*` skills for the everyday workflow, and three
805
+ optional `tcw-extras-*` skills.
697
806
 
698
807
  | Skill | What it does |
699
808
  | ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
700
809
  | [`tcw-work`](skills/tcw-work/SKILL.md) | Plans a request through spec and plan, drives implementation and verification, triages the inbox, runs the lifecycle, decomposes epics, searches the board |
701
810
  | [`tcw-capabilities`](skills/tcw-capabilities/SKILL.md) | The capability-delta planning check, contradiction detection, and the ledger flip at completion |
702
- | [`tcw-taxonomy`](skills/tcw-taxonomy/SKILL.md) | Declaring vocabulary and features, linking them, and federating shared vocabulary |
703
- | [`tcw-plugin`](skills/tcw-plugin/SKILL.md) | Installs the CLI from PyPI, and maps the other skills |
704
- | [`tcw-report`](skills/tcw-report/SKILL.md) | Reporting a `tcw` bug or suggestion upstream to [this project's issues](https://github.com/brocef/TCW/issues) |
705
- | [`tcw-triage-issues`](skills/tcw-triage-issues/SKILL.md) | Sweeps **your** project's GitHub issues and turns the ones worth doing into work items |
811
+ | [`tcw-taxonomy`](skills/tcw-taxonomy/SKILL.md) | Declaring vocabulary and features, linking them, and resolving vocabulary inherited from another project |
812
+ | [`tcw-setup`](skills/tcw-setup/SKILL.md) | Gets TCW working: installs or repairs the CLI, sets up a repository, starts a taxonomy or capabilities ledger |
813
+ | [`tcw-configure`](skills/tcw-configure/SKILL.md) | Changes a project's configuration: lifecycle bindings, Definition of Done, documentation entries, tracker, stores, connected and inherited projects |
706
814
  | [`documentation-sync`](skills/documentation-sync/SKILL.md) | Keeps README, changelogs, release notes, and driving skills moving with the code that changes them |
707
815
  | [`tcw-post-mortem`](skills/tcw-post-mortem/SKILL.md) | Finds which lifecycle stage could first have caught a problem, once one has surfaced |
708
- | [`autonomous-work`](skills/autonomous-work/SKILL.md) | Drives work items to completion unattended, consulting two read-only advisors wherever the lifecycle would ask you |
816
+
817
+ **Extras.** `tcw-extras-*` skills are optional, built for one way of working, and not needed to use TCW.
818
+
819
+ | Skill | What it does |
820
+ | ----- | ------------ |
821
+ | [`tcw-extras-autonomous-work`](skills/tcw-extras-autonomous-work/SKILL.md) | Drives work items to completion unattended, consulting two read-only advisors wherever the lifecycle would ask you |
822
+ | [`tcw-extras-triage-issues`](skills/tcw-extras-triage-issues/SKILL.md) | Sweeps **your** project's GitHub issues and turns the ones worth doing into work items |
823
+ | [`tcw-extras-report`](skills/tcw-extras-report/SKILL.md) | Reporting a `tcw` bug or suggestion upstream to [this project's issues](https://github.com/brocef/TCW/issues) |
709
824
 
710
825
  They name `tcw` commands and never reimplement tool logic: mechanism stays in the
711
826
  binary, judgment stays in the skills.
712
827
 
713
828
  ### Reading a lifecycle stage
714
829
 
715
- Six more skills do one job between them: hand you a stage's own working document
716
- and the instructions your project resolves for it, as a single read rather than a
717
- file you open and a command you run separately. They only read — `tcw work stage
718
- gate` is still what refuses.
719
-
720
- [`tcw-work-stage`](skills/tcw-work-stage/SKILL.md) is the general one and takes
721
- the stage id, so it reaches all seven stages including `inbox` and `postmortem`.
722
- The other five bake their stage in and ask only for the work item, which is
723
- optional: `tcw-work-stage-request`, `tcw-work-stage-spec`,
724
- `tcw-work-stage-plan`, `tcw-work-stage-implement`, `tcw-work-stage-verify`.
830
+ One more skill, [`tcw-work-stage`](skills/tcw-work-stage/SKILL.md), hands you a
831
+ stage's own working document and the instructions your project resolves for it,
832
+ as a single read rather than a file you open and a command you run separately.
833
+ It takes the stage id and the work item, so it reaches all seven stages
834
+ including `inbox` and `postmortem`, under Claude and Codex alike. It only reads
835
+ — `tcw work stage gate` is still what refuses.
725
836
 
726
- ### Review agents and slash commands
837
+ ### Review agents and command skills
727
838
 
728
839
  Three read-only review agents ship alongside them — `tcw-verifier`,
729
840
  `tcw-backlog-auditor`, and `tcw-post-mortem`, which accelerates the skill of the
730
- same name — plus slash commands for each skill's main procedure
731
- (`/tcw-plan-work`, `/tcw-drive-work-to-completion`, `/tcw-verify-work`,
732
- `/tcw-process-inbox`, `/tcw-work-search`, `/tcw-triage-issues`,
733
- `/tcw-audit-work-backlog`, `/tcw-consolidate-plans`, `/tcw-taxonomy-init`,
734
- `/tcw-capabilities-init`, `/tcw-docs-sync-setup`, `/tcw-cut-version`,
735
- `/tcw-post-mortem`).
841
+ same name. Four command skills carry the everyday workflows:
842
+ `tcw-commands-plan-work`, `tcw-commands-drive-work-to-completion`,
843
+ `tcw-commands-verify-work` and `tcw-commands-process-inbox`. The three extras,
844
+ `tcw-extras-autonomous-work`, `tcw-extras-triage-issues` and
845
+ `tcw-extras-report`, are optional. Under Claude and Codex alike, every entry
846
+ point is a skill.
736
847
 
737
848
  ---
738
849
 
@@ -31,7 +31,7 @@ other's content.
31
31
  - [Documentation](#documentation)
32
32
  - [Skills — the judgment layer](#skills--the-judgment-layer)
33
33
  - [Reading a lifecycle stage](#reading-a-lifecycle-stage)
34
- - [Review agents and slash commands](#review-agents-and-slash-commands)
34
+ - [Review agents and command skills](#review-agents-and-command-skills)
35
35
  - [Status](#status)
36
36
  - [Further reading](#further-reading)
37
37
 
@@ -214,20 +214,20 @@ by installing `tcw-cli` from PyPI with `pipx`, so one installed mid-session
214
214
  cannot run until the next one begins. That first session needs network access. It
215
215
  installs over an existing `pipx install tcw-cli` rather than beside it, and
216
216
  leaves a development checkout (`pip install -e .`) alone. If `tcw` goes missing
217
- anyway, `pipx install tcw-cli` is the whole fix — the **`tcw-plugin`** skill
217
+ anyway, `pipx install tcw-cli` is the whole fix — the **`tcw-setup`** skill
218
218
  carries the cases where it is not.
219
219
 
220
- In **Codex** (skills only, no slash commands):
220
+ In **Codex**:
221
221
 
222
222
  ```bash
223
223
  codex plugin marketplace add brocef/TCW --ref main
224
224
  codex plugin add tcw@tcw
225
225
  ```
226
226
 
227
- Codex has no session-start hook, so ask the agent to run the **`tcw-plugin`**
228
- setup — it runs the same install script Claude runs automatically.
227
+ Codex has no session-start hook, so ask the agent to run the **`tcw-setup`**
228
+ skill — it runs the same install script Claude runs automatically.
229
229
 
230
- The plugin ships the agent skills, slash commands, and read-only review agents
230
+ The plugin ships the agent skills, command skills, and read-only review agents
231
231
  listed under [Skills](#skills--the-judgment-layer).
232
232
 
233
233
  ### As a Python package
@@ -349,8 +349,10 @@ projects. Each component group also has its own `init`: `tcw taxonomy init`,
349
349
  `tcw capabilities init`, `tcw work init`.
350
350
 
351
351
  To bootstrap a taxonomy or capabilities ledger on a project that already has a
352
- codebase, run `/tcw-taxonomy-init` or `/tcw-capabilities-init` — the assistant
353
- studies your code, proposes a first draft, refines it with you, and writes it.
352
+ codebase, ask for the `tcw-setup` skill — the assistant studies your code,
353
+ proposes a first draft, refines it with you, and writes it. To change a working
354
+ project's configuration afterwards — documentation entries, lifecycle bindings,
355
+ a tracker, where stores live — ask for the `tcw-configure` skill.
354
356
 
355
357
  ---
356
358
 
@@ -363,8 +365,9 @@ a work item.
363
365
  tcw work tracker list # tickets the configured query selects
364
366
  tcw work tracker show ENG-482 # one ticket, and whether it is yours to take
365
367
  tcw work tracker import ENG-482 # take the ticket and get a work item for it
366
- tcw work tracker link <slug> ENG-482 # take it for an item you already have
368
+ tcw work tracker link <slug> ENG-482 # record that an item and a ticket are the same work
367
369
  tcw work tracker unlink <slug> --reason "wrong ticket"
370
+ tcw work tracker sync --all # retry tickets that did not follow their items
368
371
  ```
369
372
 
370
373
  Configuration goes in the node's `tcw-config.yaml`:
@@ -380,6 +383,11 @@ work:
380
383
  token-env: TCW_JIRA_API_TOKEN
381
384
  transitions:
382
385
  claim: Start Progress
386
+ statuses: # optional: where a bound ticket goes as its item moves
387
+ active: In Progress
388
+ review: In Review
389
+ completed: Done
390
+ discarded: Won't Do
383
391
  timeout-seconds: 15 # optional
384
392
  ```
385
393
 
@@ -438,14 +446,113 @@ refused, and so is one that is already closed.
438
446
  Running `import` again for the same ticket in the same node gives you the same item
439
447
  rather than a second one, and if the first run took the ticket but stopped before creating the
440
448
  item, the second run finishes the job. One ticket can deliberately become several
441
- items with `--part api`, `--part web`, and so on. `unlink` removes a wrong binding
442
- and keeps a record of it with your reason; it never changes the ticket in Jira.
443
-
444
- Three limits to know. On a workflow that lets anyone start a ticket from any status,
445
- two people can both take the same ticket, and TCW does not stop that. Two runs by the
446
- same Jira account at the same moment can both create an item. And each node keeps its
449
+ items with `--part api`, `--part web`, and so on.
450
+
451
+ **Recording that a ticket and an item are the same work.** `tracker link` is the
452
+ other half, and it does only that: it writes the cross-reference down and leaves
453
+ Jira alone. The ticket keeps its status and whoever holds it — you can link a ticket
454
+ somebody else is assigned, because writing a note about a ticket takes it from
455
+ nobody. On your side nothing but the binding is written, so the item keeps its
456
+ status, its owner and its documents. Any item can be linked, a finished one
457
+ included, which is how work that is already done gets tied to the ticket that
458
+ tracked it; the same goes for `unlink`, so a binding pointed at the wrong ticket is
459
+ repairable wherever you find it. A finished item's folder is kept out of git by
460
+ default, so a binding on one stays on your machine along with the rest of that
461
+ item. `unlink` keeps a record of what was bound and your
462
+ reason, and like `link` it never changes the ticket in Jira.
463
+
464
+ **Seeing which ticket an item answers.** A bound item says so wherever you read it:
465
+ `tcw work show` adds a `tracker:` line with the ticket, the provider, the part and
466
+ the ticket's link; its row on `tcw work list` ends with the ticket key, and notes the part and anything
467
+ not yet sent to the ticket; `tcw work show
468
+ --json` carries it as `tracker`; and `tcw serve`'s item page shows the ticket as a
469
+ link. What you see is what the binding records, not what Jira says right now, so
470
+ none of it needs the tracker configured or reachable. A binding file that cannot be
471
+ read is reported in the same places instead of breaking the board.
472
+
473
+ **Tickets follow their items.** `link` claims nothing, so `tcw work start` does:
474
+ starting a bound item claims its ticket by the same rules `import` uses. After that,
475
+ `submit`, `rework`, `complete` and discarding move the ticket to the status you map
476
+ the item's new status to under `statuses` (`discarded` can name a status per
477
+ resolution, such as `duplicate: Duplicate`); a status you leave out sends nothing,
478
+ and `active` is required once you map any other. `import` on a ticket that is only
479
+ linked still refuses rather than claiming it.
480
+
481
+ TCW moves a ticket only when it is assigned to you and is still where the item's
482
+ previous status left it. A ticket someone else holds, one moved on in Jira, or one
483
+ whose workflow does not offer a single transition to the mapped status is left
484
+ alone. Your local move always happens and is committed first; when the ticket does
485
+ not follow, the command exits 1, says the item moved, and records why — *pending*
486
+ when Jira could not be reached or your credentials are missing, *conflicting* when
487
+ Jira's answer stopped it. `tcw work show` and `tcw work list` show that state, and
488
+ `tcw work tracker sync <slug>` (or `--all`) retries it once the cause is fixed. `sync`
489
+ acts only on items you started, because it acts as whoever runs it. A ticket that
490
+ followed first time leaves no record and no change in your repository.
491
+
492
+ Two things are not caught: a move made in `tcw serve`, and a command interrupted
493
+ between its commit and its call to Jira, leave no record, so the board shows them as
494
+ in step; `sync <slug>` checks such an item but will not move its ticket. And a
495
+ binding whose ticket link is on a different Jira site from the one configured is
496
+ never written through — `import` and `link` refuse it and name the item.
497
+
498
+ Five limits to know. A ticket bound to several parts moves only when the last open
499
+ part here moves; parts in other nodes are not seen. On a workflow that lets anyone start a ticket from any status,
500
+ two people can both take the same ticket, and TCW does not stop that outside strict
501
+ mode (below). Two runs by the
502
+ same Jira account at the same moment can both create an item. Each node keeps its
447
503
  own bindings: importing one ticket in two nodes of a workspace, even nodes sharing
448
- inherited settings, gives two items, one in each.
504
+ inherited settings, gives two items, one in each. And a ticket held by a finished
505
+ item can be bound to a second item, open or finished, with no warning — a discarded
506
+ item's ticket is meant to be available again, and TCW cannot tell that case from the
507
+ other.
508
+
509
+ **Comments on the ticket.** Set `comments: true` in the `tracker` block and each
510
+ move also leaves a short comment on the ticket, such as
511
+ `TCW: "Checkout page" (part api) went to review.`, for anyone who follows the work
512
+ in Jira rather than in the repository. A `link` template adds a link, for example
513
+ `link: https://tcw.example.com/work/{slug}` for a team that hosts `tcw serve`; the
514
+ only placeholders are `{project}` and `{slug}`. Nothing from `spec.md`, `plan.md` or
515
+ the other lifecycle documents is ever copied. A comment is posted only while the
516
+ ticket is assigned to you, and a ticket held by someone else gets none. When a
517
+ comment cannot be posted, the command exits 1, `show` prints a `tracker comment:`
518
+ line, and `tcw work tracker sync` sends it later. Before resending, it looks for the
519
+ comment on the ticket, so a post that landed without an answer is not repeated.
520
+ Limits: a newer move's comment replaces one still waiting; two runs at once, or an
521
+ edited or deleted comment, can still give a repeat; moves in `tcw serve` post
522
+ nothing. On a Jira Service Management project a comment may be visible to
523
+ customers, so leave comments off there unless item titles may be seen. Every copy
524
+ of `tcw` on the project must understand these keys before you set them: an older
525
+ one treats the whole `tracker` block as broken.
526
+
527
+ **Strict mode: no work without a ticket.** Set `strict: true` in the `tracker` block
528
+ when every piece of work must come from a ticket you have claimed. Then:
529
+
530
+ - `tcw work new` and `tcw work inbox accept` refuse and point you at
531
+ `tcw work tracker import <ticket>`. `new --epic` is allowed; epics are never gated.
532
+ - `tcw work start` refuses an item with no ticket. For a bound item it claims the
533
+ ticket *first*, and starts the item only if the claim worked.
534
+ - `submit`, `rework` and completing as `done` read the ticket first and refuse unless
535
+ it is assigned to you and is where the item's last step left it. A `--worktree`
536
+ item is checked before anything is merged.
537
+ - A claim on a workflow that would let a second person claim the same ticket is
538
+ refused, by `start` and by `import`; the ticket is left claimed for you to release.
539
+ - An epic can be created and started, since it only groups work, but not with
540
+ `--worktree`.
541
+ - A ticket shared by several parts is recognised only from the parts' items in
542
+ this checkout. If the part that held the ticket back was completed elsewhere, or
543
+ was not kept (`work.retain`), the last part's `complete` is refused; put the
544
+ ticket in the status the message names, or discard.
545
+ - Discarding is always allowed. `drop` refuses an item that was ever bound — discard
546
+ it instead, so the record stays.
547
+ - `tcw serve` refuses the same changes, since it cannot check a ticket, and names the
548
+ command to use.
549
+
550
+ A refusal changes nothing in your project and says what to fix; a `start` or `import`
551
+ refused after claiming leaves the ticket claimed. There is no flag to get past it;
552
+ `--force` and `--take-over` do not. Strict mode needs Jira: while it cannot be
553
+ reached, gated commands refuse. It also needs `statuses.active`,
554
+ `statuses.completed` and a `statuses.discarded` covering every discard reason, which
555
+ `tcw validate` checks. To turn it off, set `strict: false` or remove the key.
449
556
 
450
557
  Two guarantees worth stating plainly. A project with no `tracker` block behaves
451
558
  exactly as before, with no new required setting and no network access. And
@@ -475,48 +582,52 @@ Every command group also has `--help`, and a `check` that validates its tree.
475
582
  ## Skills — the judgment layer
476
583
 
477
584
  The CLI is the _mechanism_. Fifteen skills in [`skills/`](skills/) supply the
478
- _judgment_ that drives it — the parts a deterministic tool cannot decide. Nine
479
- carry a distinct procedure; the other six all compose one lifecycle stage and
480
- are listed together at the end.
585
+ _judgment_ that drives it — the parts a deterministic tool cannot decide. They
586
+ come in three groups, told apart by name: eight core skills (seven in the table
587
+ below, and `tcw-work-stage`, which composes a lifecycle stage and is described
588
+ after it), four `tcw-commands-*` skills for the everyday workflow, and three
589
+ optional `tcw-extras-*` skills.
481
590
 
482
591
  | Skill | What it does |
483
592
  | ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
484
593
  | [`tcw-work`](skills/tcw-work/SKILL.md) | Plans a request through spec and plan, drives implementation and verification, triages the inbox, runs the lifecycle, decomposes epics, searches the board |
485
594
  | [`tcw-capabilities`](skills/tcw-capabilities/SKILL.md) | The capability-delta planning check, contradiction detection, and the ledger flip at completion |
486
- | [`tcw-taxonomy`](skills/tcw-taxonomy/SKILL.md) | Declaring vocabulary and features, linking them, and federating shared vocabulary |
487
- | [`tcw-plugin`](skills/tcw-plugin/SKILL.md) | Installs the CLI from PyPI, and maps the other skills |
488
- | [`tcw-report`](skills/tcw-report/SKILL.md) | Reporting a `tcw` bug or suggestion upstream to [this project's issues](https://github.com/brocef/TCW/issues) |
489
- | [`tcw-triage-issues`](skills/tcw-triage-issues/SKILL.md) | Sweeps **your** project's GitHub issues and turns the ones worth doing into work items |
595
+ | [`tcw-taxonomy`](skills/tcw-taxonomy/SKILL.md) | Declaring vocabulary and features, linking them, and resolving vocabulary inherited from another project |
596
+ | [`tcw-setup`](skills/tcw-setup/SKILL.md) | Gets TCW working: installs or repairs the CLI, sets up a repository, starts a taxonomy or capabilities ledger |
597
+ | [`tcw-configure`](skills/tcw-configure/SKILL.md) | Changes a project's configuration: lifecycle bindings, Definition of Done, documentation entries, tracker, stores, connected and inherited projects |
490
598
  | [`documentation-sync`](skills/documentation-sync/SKILL.md) | Keeps README, changelogs, release notes, and driving skills moving with the code that changes them |
491
599
  | [`tcw-post-mortem`](skills/tcw-post-mortem/SKILL.md) | Finds which lifecycle stage could first have caught a problem, once one has surfaced |
492
- | [`autonomous-work`](skills/autonomous-work/SKILL.md) | Drives work items to completion unattended, consulting two read-only advisors wherever the lifecycle would ask you |
600
+
601
+ **Extras.** `tcw-extras-*` skills are optional, built for one way of working, and not needed to use TCW.
602
+
603
+ | Skill | What it does |
604
+ | ----- | ------------ |
605
+ | [`tcw-extras-autonomous-work`](skills/tcw-extras-autonomous-work/SKILL.md) | Drives work items to completion unattended, consulting two read-only advisors wherever the lifecycle would ask you |
606
+ | [`tcw-extras-triage-issues`](skills/tcw-extras-triage-issues/SKILL.md) | Sweeps **your** project's GitHub issues and turns the ones worth doing into work items |
607
+ | [`tcw-extras-report`](skills/tcw-extras-report/SKILL.md) | Reporting a `tcw` bug or suggestion upstream to [this project's issues](https://github.com/brocef/TCW/issues) |
493
608
 
494
609
  They name `tcw` commands and never reimplement tool logic: mechanism stays in the
495
610
  binary, judgment stays in the skills.
496
611
 
497
612
  ### Reading a lifecycle stage
498
613
 
499
- Six more skills do one job between them: hand you a stage's own working document
500
- and the instructions your project resolves for it, as a single read rather than a
501
- file you open and a command you run separately. They only read — `tcw work stage
502
- gate` is still what refuses.
503
-
504
- [`tcw-work-stage`](skills/tcw-work-stage/SKILL.md) is the general one and takes
505
- the stage id, so it reaches all seven stages including `inbox` and `postmortem`.
506
- The other five bake their stage in and ask only for the work item, which is
507
- optional: `tcw-work-stage-request`, `tcw-work-stage-spec`,
508
- `tcw-work-stage-plan`, `tcw-work-stage-implement`, `tcw-work-stage-verify`.
614
+ One more skill, [`tcw-work-stage`](skills/tcw-work-stage/SKILL.md), hands you a
615
+ stage's own working document and the instructions your project resolves for it,
616
+ as a single read rather than a file you open and a command you run separately.
617
+ It takes the stage id and the work item, so it reaches all seven stages
618
+ including `inbox` and `postmortem`, under Claude and Codex alike. It only reads
619
+ — `tcw work stage gate` is still what refuses.
509
620
 
510
- ### Review agents and slash commands
621
+ ### Review agents and command skills
511
622
 
512
623
  Three read-only review agents ship alongside them — `tcw-verifier`,
513
624
  `tcw-backlog-auditor`, and `tcw-post-mortem`, which accelerates the skill of the
514
- same name — plus slash commands for each skill's main procedure
515
- (`/tcw-plan-work`, `/tcw-drive-work-to-completion`, `/tcw-verify-work`,
516
- `/tcw-process-inbox`, `/tcw-work-search`, `/tcw-triage-issues`,
517
- `/tcw-audit-work-backlog`, `/tcw-consolidate-plans`, `/tcw-taxonomy-init`,
518
- `/tcw-capabilities-init`, `/tcw-docs-sync-setup`, `/tcw-cut-version`,
519
- `/tcw-post-mortem`).
625
+ same name. Four command skills carry the everyday workflows:
626
+ `tcw-commands-plan-work`, `tcw-commands-drive-work-to-completion`,
627
+ `tcw-commands-verify-work` and `tcw-commands-process-inbox`. The three extras,
628
+ `tcw-extras-autonomous-work`, `tcw-extras-triage-issues` and
629
+ `tcw-extras-report`, are optional. Under Claude and Codex alike, every entry
630
+ point is a skill.
520
631
 
521
632
  ---
522
633
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "tcw-cli"
7
- version = "2.1.3"
7
+ version = "2.2.0"
8
8
  description = "Taxonomy · Capabilities · Work — a storage-abstracted framework for describing and evolving a software project."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -0,0 +1 @@
1
+ __version__ = "2.2.0"
@@ -286,38 +286,42 @@ def add_subparser(sub: argparse._SubParsersAction) -> None:
286
286
  pl.set_defaults(func=_list)
287
287
 
288
288
  ps = g.add_parser("show", help="read a capability by path")
289
- ps.add_argument("id", metavar="path")
289
+ ps.add_argument("id", metavar="path",
290
+ help="capability path, e.g. web/login (alias-prefixed if inherited)")
290
291
  ps.set_defaults(func=_show)
291
292
 
292
293
  g.add_parser("path", help="print the capabilities store folder path").set_defaults(func=_path)
293
294
 
294
295
  pa = g.add_parser("add", help="scaffold a capability folder")
295
- pa.add_argument("path", metavar="namespace/path")
296
- pa.add_argument("name", nargs="?")
296
+ pa.add_argument("path", metavar="namespace/path",
297
+ help="path for the new capability, namespace folder first")
298
+ pa.add_argument("name", nargs="?",
299
+ help="display name (default: titled from the last path segment)")
297
300
  pa.add_argument("-s", "--status", default="Missing")
298
301
  pa.set_defaults(func=_add)
299
302
 
300
303
  pset = g.add_parser("set", help="update a capability's status/fields in place")
301
- pset.add_argument("id", metavar="path")
304
+ pset.add_argument("id", metavar="path",
305
+ help="capability path to update; an inherited one gains a local override")
302
306
  pset.add_argument("--status", help="shorthand for --field Status=<S>")
303
307
  pset.add_argument("--field", action="append", metavar="K=V",
304
308
  help="set a metadata field (repeatable; Subject accepts a,b,c)")
305
309
  pset.set_defaults(func=_set)
306
310
 
307
311
  prst = g.add_parser("reset", help="drop a local override, re-inheriting upstream")
308
- prst.add_argument("id", metavar="path")
312
+ prst.add_argument("id", metavar="path", help="path of the local override to drop")
309
313
  prst.set_defaults(func=_reset)
310
314
 
311
315
  prm = g.add_parser("rm", help="remove a local capability")
312
- prm.add_argument("id", metavar="path")
316
+ prm.add_argument("id", metavar="path", help="path of the local capability to remove")
313
317
  prm.set_defaults(func=_rm)
314
318
 
315
319
  pse = g.add_parser("search", help="search names + bodies")
316
- pse.add_argument("query")
320
+ pse.add_argument("query", help="text matched case-insensitively in names + bodies")
317
321
  pse.set_defaults(func=_search)
318
322
 
319
323
  pe = g.add_parser("extends", help="federate another project's capabilities")
320
- pe.add_argument("project_id")
324
+ pe.add_argument("project_id", help="registered project ID whose capabilities to federate")
321
325
  pe.add_argument("--rm", action="store_true", help="remove the project instead")
322
326
  pe.set_defaults(func=_extends)
323
327