codexspec 0.7.2__tar.gz → 0.7.4__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 (61) hide show
  1. {codexspec-0.7.2 → codexspec-0.7.4}/PKG-INFO +3 -1
  2. {codexspec-0.7.2 → codexspec-0.7.4}/README.md +2 -0
  3. {codexspec-0.7.2 → codexspec-0.7.4}/pyproject.toml +1 -1
  4. {codexspec-0.7.2 → codexspec-0.7.4}/src/codexspec/__init__.py +174 -0
  5. {codexspec-0.7.2 → codexspec-0.7.4}/templates/commands/config.md +30 -4
  6. {codexspec-0.7.2 → codexspec-0.7.4}/templates/commands/constitution.md +3 -1
  7. {codexspec-0.7.2 → codexspec-0.7.4}/.gitignore +0 -0
  8. {codexspec-0.7.2 → codexspec-0.7.4}/LICENSE +0 -0
  9. {codexspec-0.7.2 → codexspec-0.7.4}/codexspec-icon.svg +0 -0
  10. {codexspec-0.7.2 → codexspec-0.7.4}/codexspec-logo-dark.svg +0 -0
  11. {codexspec-0.7.2 → codexspec-0.7.4}/codexspec-logo-light.svg +0 -0
  12. {codexspec-0.7.2 → codexspec-0.7.4}/scripts/bash/check-i18n-completeness.sh +0 -0
  13. {codexspec-0.7.2 → codexspec-0.7.4}/scripts/bash/check-i18n-structure.sh +0 -0
  14. {codexspec-0.7.2 → codexspec-0.7.4}/scripts/bash/check-prerequisites.sh +0 -0
  15. {codexspec-0.7.2 → codexspec-0.7.4}/scripts/bash/common.sh +0 -0
  16. {codexspec-0.7.2 → codexspec-0.7.4}/scripts/bash/create-new-feature.sh +0 -0
  17. {codexspec-0.7.2 → codexspec-0.7.4}/scripts/powershell/check-prerequisites.ps1 +0 -0
  18. {codexspec-0.7.2 → codexspec-0.7.4}/scripts/powershell/common.ps1 +0 -0
  19. {codexspec-0.7.2 → codexspec-0.7.4}/scripts/powershell/create-new-feature.ps1 +0 -0
  20. {codexspec-0.7.2 → codexspec-0.7.4}/src/codexspec/commands/__init__.py +0 -0
  21. {codexspec-0.7.2 → codexspec-0.7.4}/src/codexspec/commands/installer.py +0 -0
  22. {codexspec-0.7.2 → codexspec-0.7.4}/src/codexspec/i18n.py +0 -0
  23. {codexspec-0.7.2 → codexspec-0.7.4}/src/codexspec/idea.md +0 -0
  24. {codexspec-0.7.2 → codexspec-0.7.4}/src/codexspec/integrations/__init__.py +0 -0
  25. {codexspec-0.7.2 → codexspec-0.7.4}/src/codexspec/integrations/base.py +0 -0
  26. {codexspec-0.7.2 → codexspec-0.7.4}/src/codexspec/integrations/claude.py +0 -0
  27. {codexspec-0.7.2 → codexspec-0.7.4}/src/codexspec/integrations/codex.py +0 -0
  28. {codexspec-0.7.2 → codexspec-0.7.4}/src/codexspec/translator.py +0 -0
  29. {codexspec-0.7.2 → codexspec-0.7.4}/templates/commands/analyze.md +0 -0
  30. {codexspec-0.7.2 → codexspec-0.7.4}/templates/commands/checklist.md +0 -0
  31. {codexspec-0.7.2 → codexspec-0.7.4}/templates/commands/clarify.md +0 -0
  32. {codexspec-0.7.2 → codexspec-0.7.4}/templates/commands/commit-staged.md +0 -0
  33. {codexspec-0.7.2 → codexspec-0.7.4}/templates/commands/generate-spec.md +0 -0
  34. {codexspec-0.7.2 → codexspec-0.7.4}/templates/commands/implement-tasks.md +0 -0
  35. {codexspec-0.7.2 → codexspec-0.7.4}/templates/commands/plan-to-tasks.md +0 -0
  36. {codexspec-0.7.2 → codexspec-0.7.4}/templates/commands/pr.md +0 -0
  37. {codexspec-0.7.2 → codexspec-0.7.4}/templates/commands/quick.md +0 -0
  38. {codexspec-0.7.2 → codexspec-0.7.4}/templates/commands/review-code.md +0 -0
  39. {codexspec-0.7.2 → codexspec-0.7.4}/templates/commands/review-plan.md +0 -0
  40. {codexspec-0.7.2 → codexspec-0.7.4}/templates/commands/review-spec.md +0 -0
  41. {codexspec-0.7.2 → codexspec-0.7.4}/templates/commands/review-tasks.md +0 -0
  42. {codexspec-0.7.2 → codexspec-0.7.4}/templates/commands/spec-to-plan.md +0 -0
  43. {codexspec-0.7.2 → codexspec-0.7.4}/templates/commands/specify.md +0 -0
  44. {codexspec-0.7.2 → codexspec-0.7.4}/templates/commands/tasks-to-issues.md +0 -0
  45. {codexspec-0.7.2 → codexspec-0.7.4}/templates/docs/checklist-template.md +0 -0
  46. {codexspec-0.7.2 → codexspec-0.7.4}/templates/docs/constitution-template.md +0 -0
  47. {codexspec-0.7.2 → codexspec-0.7.4}/templates/docs/plan-template-detailed.md +0 -0
  48. {codexspec-0.7.2 → codexspec-0.7.4}/templates/docs/plan-template-simple.md +0 -0
  49. {codexspec-0.7.2 → codexspec-0.7.4}/templates/docs/requirements-template.md +0 -0
  50. {codexspec-0.7.2 → codexspec-0.7.4}/templates/docs/spec-template-detailed.md +0 -0
  51. {codexspec-0.7.2 → codexspec-0.7.4}/templates/docs/spec-template-simple.md +0 -0
  52. {codexspec-0.7.2 → codexspec-0.7.4}/templates/docs/tasks-template-detailed.md +0 -0
  53. {codexspec-0.7.2 → codexspec-0.7.4}/templates/docs/tasks-template-simple.md +0 -0
  54. {codexspec-0.7.2 → codexspec-0.7.4}/templates/translations/de.json +0 -0
  55. {codexspec-0.7.2 → codexspec-0.7.4}/templates/translations/en.json +0 -0
  56. {codexspec-0.7.2 → codexspec-0.7.4}/templates/translations/es.json +0 -0
  57. {codexspec-0.7.2 → codexspec-0.7.4}/templates/translations/fr.json +0 -0
  58. {codexspec-0.7.2 → codexspec-0.7.4}/templates/translations/ja.json +0 -0
  59. {codexspec-0.7.2 → codexspec-0.7.4}/templates/translations/ko.json +0 -0
  60. {codexspec-0.7.2 → codexspec-0.7.4}/templates/translations/pt-BR.json +0 -0
  61. {codexspec-0.7.2 → codexspec-0.7.4}/templates/translations/zh-CN.json +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codexspec
3
- Version: 0.7.2
3
+ Version: 0.7.4
4
4
  Summary: CodexSpec - A Requirements-First SDD toolkit for Claude Code
5
5
  Project-URL: Homepage, https://github.com/Zts0hg/codexspec
6
6
  Project-URL: Repository, https://github.com/Zts0hg/codexspec
@@ -554,6 +554,7 @@ Implementation follows **conditional TDD workflow**:
554
554
  | `--set-document-lang` | Set the document language |
555
555
  | `--set-commit-lang`, `-c` | Set the commit-message language |
556
556
  | `--list-langs` | List all supported languages |
557
+ | `--auto-next` | Toggle/set `workflow.auto_next` (bare toggles; or on/off) |
557
558
 
558
559
  </details>
559
560
 
@@ -677,6 +678,7 @@ codexspec config --set-lang zh-CN
677
678
  codexspec config --set-interaction-lang zh-CN
678
679
  codexspec config --set-document-lang en
679
680
  codexspec config --set-commit-lang en
681
+ codexspec config --auto-next
680
682
  ```
681
683
 
682
684
  ### Supported Languages
@@ -509,6 +509,7 @@ Implementation follows **conditional TDD workflow**:
509
509
  | `--set-document-lang` | Set the document language |
510
510
  | `--set-commit-lang`, `-c` | Set the commit-message language |
511
511
  | `--list-langs` | List all supported languages |
512
+ | `--auto-next` | Toggle/set `workflow.auto_next` (bare toggles; or on/off) |
512
513
 
513
514
  </details>
514
515
 
@@ -632,6 +633,7 @@ codexspec config --set-lang zh-CN
632
633
  codexspec config --set-interaction-lang zh-CN
633
634
  codexspec config --set-document-lang en
634
635
  codexspec config --set-commit-lang en
636
+ codexspec config --auto-next
635
637
  ```
636
638
 
637
639
  ### Supported Languages
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "codexspec"
3
- version = "0.7.2"
3
+ version = "0.7.4"
4
4
  description = "CodexSpec - A Requirements-First SDD toolkit for Claude Code"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -173,6 +173,15 @@ def check() -> None:
173
173
  console.print(table)
174
174
 
175
175
 
176
+ # workflow.auto_next toggle (used by the ``config --auto-next`` option).
177
+ # Defined here because ``config()``'s ``flag_value`` default is evaluated at
178
+ # function-definition time.
179
+ _AUTO_NEXT_TRUE = {"on", "true", "1", "yes"}
180
+ _AUTO_NEXT_FALSE = {"off", "false", "0", "no"}
181
+ _AUTO_NEXT_SENTINEL = "__toggle__"
182
+ _AUTO_NEXT_ACCEPTED = "on/off, true/false, 1/0, yes/no"
183
+
184
+
176
185
  @app.command()
177
186
  def config(
178
187
  set_lang: Optional[str] = typer.Option(
@@ -202,6 +211,16 @@ def config(
202
211
  "--list-langs",
203
212
  help="List all supported languages",
204
213
  ),
214
+ # ``--auto-next`` accepts an explicit value (on/off|true/false|1/0|yes/no).
215
+ # The bare form (toggle) is rewritten to ``--auto-next=<sentinel>`` by
216
+ # ``_normalize_auto_next_argv`` in ``main()``: Click 8.3 no longer honors
217
+ # ``flag_value`` for a bare optional-value option (it errors "requires an
218
+ # argument"), so the bare case is handled before Click parses.
219
+ auto_next: Optional[str] = typer.Option(
220
+ None,
221
+ "--auto-next",
222
+ help="Toggle workflow.auto_next (bare), or set it (on/off|true/false|1/0|yes/no).",
223
+ ),
205
224
  ) -> None:
206
225
  """
207
226
  View or modify CodexSpec project configuration.
@@ -213,6 +232,7 @@ def config(
213
232
  codexspec config # Show current configuration
214
233
  codexspec config --set-lang zh-CN # Set language to Chinese
215
234
  codexspec config --set-commit-lang en # Set commit messages to English
235
+ codexspec config --auto-next # Toggle workflow.auto_next
216
236
  codexspec config --list-langs # List supported languages
217
237
  """
218
238
  # Handle list languages
@@ -235,6 +255,25 @@ def config(
235
255
  console.print("Run [cyan]codexspec init[/cyan] to create a new project.")
236
256
  raise typer.Exit(1)
237
257
 
258
+ # Handle auto-next toggle/set
259
+ if auto_next is not None:
260
+ if auto_next == _AUTO_NEXT_SENTINEL:
261
+ target = not _read_auto_next(config_file)
262
+ else:
263
+ try:
264
+ target = parse_auto_next_value(auto_next)
265
+ except ValueError:
266
+ console.print(f"[red]Invalid --auto-next value:[/red] {auto_next!r}")
267
+ console.print(f"Accepted values: {_AUTO_NEXT_ACCEPTED} (or pass --auto-next bare to toggle).")
268
+ raise typer.Exit(1)
269
+ if _write_auto_next(config_file, target):
270
+ state = "enabled" if target else "disabled"
271
+ console.print(f"[green]auto_next {state}[/green] (workflow.auto_next = {str(target).lower()})")
272
+ else:
273
+ console.print("[red]Failed to update workflow.auto_next[/red]")
274
+ raise typer.Exit(1)
275
+ return
276
+
238
277
  # Handle set language
239
278
  if set_lang:
240
279
  normalized = normalize_locale(set_lang)
@@ -898,6 +937,111 @@ def _update_project_ai(config_file: Path, ai: str) -> None:
898
937
  return
899
938
 
900
939
 
940
+ # --- workflow.auto_next toggle helpers -------------------------------------
941
+
942
+
943
+ def parse_auto_next_value(raw: str) -> bool:
944
+ """Parse an explicit ``--auto-next`` value into a boolean.
945
+
946
+ Accepts ``on/off``, ``true/false``, ``1/0``, ``yes/no`` (case-insensitive,
947
+ surrounding whitespace ignored). Raises ``ValueError`` for any other token
948
+ so the caller can report the error and exit non-zero.
949
+ """
950
+ token = (raw or "").strip().lower()
951
+ if token in _AUTO_NEXT_TRUE:
952
+ return True
953
+ if token in _AUTO_NEXT_FALSE:
954
+ return False
955
+ raise ValueError(f"invalid --auto-next value: {raw!r}")
956
+
957
+
958
+ def _read_auto_next(config_file: Path) -> bool:
959
+ """Return True only when ``workflow.auto_next`` is the literal ``true``.
960
+
961
+ An absent key/section, ``false``, or any malformed value is treated as
962
+ ``False`` — matching the runtime rule that only literal ``true`` enables
963
+ auto-next.
964
+ """
965
+ try:
966
+ content = config_file.read_text(encoding="utf-8")
967
+ except OSError:
968
+ return False
969
+ in_workflow = False
970
+ for line in content.splitlines():
971
+ if not line.strip():
972
+ continue
973
+ if not line[0].isspace(): # top-level key (or comment)
974
+ key = line.split("#", 1)[0].strip()
975
+ in_workflow = key == "workflow:"
976
+ continue
977
+ if in_workflow:
978
+ match = re.match(r"^\s*auto_next:\s*(\S+?)\s*(?:#.*)?$", line)
979
+ if match:
980
+ return match.group(1) == "true"
981
+ return False
982
+
983
+
984
+ def _write_auto_next(config_file: Path, value: bool) -> bool:
985
+ """Set ``workflow.auto_next`` to an unquoted boolean.
986
+
987
+ Three cases: (1) the key exists under the ``workflow:`` section — update
988
+ the value in place; (2) the section exists but the key is absent — insert
989
+ ``auto_next: <bool>`` as its first child; (3) the section is absent —
990
+ append a ``workflow:`` section at the end of the file. All other lines and
991
+ comments are preserved; the inserted line is bare (no reconstructed
992
+ comment). Returns ``False`` on I/O error.
993
+ """
994
+ try:
995
+ content = config_file.read_text(encoding="utf-8")
996
+ except OSError:
997
+ return False
998
+
999
+ token = "true" if value else "false"
1000
+ lines = content.split("\n")
1001
+
1002
+ workflow_idx: Optional[int] = None
1003
+ in_workflow = False
1004
+ for i, line in enumerate(lines):
1005
+ if not line.strip():
1006
+ continue
1007
+ if not line[0].isspace():
1008
+ key = line.split("#", 1)[0].strip()
1009
+ in_workflow = key == "workflow:"
1010
+ if in_workflow:
1011
+ workflow_idx = i
1012
+ continue
1013
+ if in_workflow and re.match(r"^\s*auto_next:\s*\S+", line):
1014
+ indent = line[: len(line) - len(line.lstrip())]
1015
+ lines[i] = f"{indent}auto_next: {token}"
1016
+ return _dump_lines(config_file, lines)
1017
+
1018
+ if workflow_idx is not None:
1019
+ lines.insert(workflow_idx + 1, f" auto_next: {token}")
1020
+ return _dump_lines(config_file, lines)
1021
+
1022
+ section = f"workflow:\n auto_next: {token}"
1023
+ if not content:
1024
+ new_content = section + "\n"
1025
+ elif content.endswith("\n"):
1026
+ new_content = content + "\n" + section + "\n"
1027
+ else:
1028
+ new_content = content + "\n\n" + section + "\n"
1029
+ try:
1030
+ config_file.write_text(new_content, encoding="utf-8")
1031
+ except OSError:
1032
+ return False
1033
+ return True
1034
+
1035
+
1036
+ def _dump_lines(path: Path, lines: list[str]) -> bool:
1037
+ """Write ``lines`` joined by newlines; return False on I/O error."""
1038
+ try:
1039
+ path.write_text("\n".join(lines), encoding="utf-8")
1040
+ except OSError:
1041
+ return False
1042
+ return True
1043
+
1044
+
901
1045
  def _next_step_start(integration_keys: set[str], language: str) -> str:
902
1046
  """Return a target-aware start instruction."""
903
1047
  if integration_keys == {"codex"}:
@@ -1295,8 +1439,38 @@ The following slash commands are available in this project:
1295
1439
  """
1296
1440
 
1297
1441
 
1442
+ def _normalize_auto_next_argv(argv: list[str]) -> list[str]:
1443
+ """Rewrite a bare ``--auto-next`` into ``--auto-next=<sentinel>``.
1444
+
1445
+ Click 8.3 no longer honors ``flag_value`` for a bare optional-value option
1446
+ (it errors "requires an argument"). To preserve ``codexspec config
1447
+ --auto-next`` (bare) as a toggle, a standalone ``--auto-next`` token — one
1448
+ that is not already in ``--auto-next=...`` form and is not followed by a
1449
+ value token — is rewritten to ``--auto-next=<sentinel>``, which the
1450
+ ``config`` handler interprets as a toggle.
1451
+ """
1452
+ out: list[str] = []
1453
+ i = 0
1454
+ while i < len(argv):
1455
+ tok = argv[i]
1456
+ if tok == "--auto-next":
1457
+ nxt = argv[i + 1] if i + 1 < len(argv) else None
1458
+ if nxt is None or nxt.startswith("-"):
1459
+ out.append(f"--auto-next={_AUTO_NEXT_SENTINEL}")
1460
+ else:
1461
+ out.append(tok)
1462
+ out.append(nxt)
1463
+ i += 1
1464
+ else:
1465
+ out.append(tok)
1466
+ i += 1
1467
+ return out
1468
+
1469
+
1298
1470
  def main() -> None:
1299
1471
  """Main entry point for the CLI."""
1472
+ if "--auto-next" in sys.argv:
1473
+ sys.argv = _normalize_auto_next_argv(sys.argv)
1300
1474
  app()
1301
1475
 
1302
1476
 
@@ -67,7 +67,7 @@ To create a new configuration, run `/codexspec:config` without arguments.
67
67
 
68
68
  ### Step 3: Interactive Mode (Configuration Exists)
69
69
 
70
- If configuration exists and no `--view` flag, present the management menu using `AskUserQuestion`:
70
+ If configuration exists and no `--view` flag, present the management menu using the host agent's structured-question tool (e.g., `AskUserQuestion` or `request_user_input`):
71
71
 
72
72
  ```json
73
73
  {
@@ -84,6 +84,8 @@ If configuration exists and no `--view` flag, present the management menu using
84
84
  }
85
85
  ```
86
86
 
87
+ > **Note**: The field schema above follows the `AskUserQuestion` convention. Under `request_user_input`, each question additionally requires an `id` (snake_case) and accepts 2–3 options — follow the host tool's actual schema rather than copying this example verbatim.
88
+
87
89
  Then handle each option:
88
90
 
89
91
  #### Option: View current config
@@ -104,6 +106,7 @@ Display the configuration as in Step 2, then exit.
104
106
  {"label": "Document language", "description": "Language for generated artifact files (requirements/spec/plan/tasks) (currently: {current value})"},
105
107
  {"label": "Output language (legacy)", "description": "Fallback language used when interaction/document are not set (currently: {current value})"},
106
108
  {"label": "Commit language", "description": "Language for commit messages (currently: {current value})"},
109
+ {"label": "Auto-next chain", "description": "Auto-advance the SDD pipeline once a stage passes (workflow.auto_next) (currently: {current value})"},
107
110
  {"label": "Back", "description": "Return to main menu"}
108
111
  ]
109
112
  }]
@@ -127,9 +130,32 @@ Display the configuration as in Step 2, then exit.
127
130
  }
128
131
  ```
129
132
 
130
- 3. Update the configuration file with the new value
131
- 4. Display the updated configuration
132
- 5. Exit
133
+ 3. For "Auto-next chain", ask whether to enable or disable:
134
+
135
+ ```json
136
+ {
137
+ "questions": [{
138
+ "question": "Set workflow.auto_next:",
139
+ "header": "Auto-next",
140
+ "options": [
141
+ {"label": "Enable", "description": "Auto-advance the SDD pipeline once a stage passes"},
142
+ {"label": "Disable", "description": "Do not auto-advance; advance to the next command manually"},
143
+ {"label": "Back", "description": "Return without changing"}
144
+ ]
145
+ }]
146
+ }
147
+ ```
148
+
149
+ Then read `.codexspec/config.yml`. The current value is enabled only when
150
+ `workflow.auto_next` is the literal `true`; an absent key/section, `false`,
151
+ or any other value is disabled. Write `workflow.auto_next` as an unquoted
152
+ `true`/`false` (update the value in place when the key exists; otherwise add
153
+ a `workflow:` section with `auto_next: <bool>`), preserving every other
154
+ line and comment.
155
+
156
+ 4. Update the configuration file with the new value
157
+ 5. Display the updated configuration
158
+ 6. Exit
133
159
 
134
160
  #### Option: Reset to defaults
135
161
 
@@ -53,7 +53,7 @@ Parse `$ARGUMENTS` to determine execution mode:
53
53
 
54
54
  ### Mode A: No Arguments - Present Options
55
55
 
56
- **IMPORTANT**: Use the `AskUserQuestion` tool to present structured choices.
56
+ **IMPORTANT**: Use the host agent's structured-question tool (e.g., `AskUserQuestion` or `request_user_input`) to present structured choices.
57
57
 
58
58
  ```json
59
59
  {
@@ -78,6 +78,8 @@ Parse `$ARGUMENTS` to determine execution mode:
78
78
  }
79
79
  ```
80
80
 
81
+ > **Note**: The field schema above follows the `AskUserQuestion` convention. Under `request_user_input`, each question additionally requires an `id` (snake_case) and accepts 2–3 options — follow the host tool's actual schema rather than copying this example verbatim.
82
+
81
83
  **After user responds:**
82
84
 
83
85
  - If user selects `quick` → proceed to Mode B Quick Exploration
File without changes
File without changes
File without changes