codexspec 0.7.2__tar.gz → 0.7.3__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.3}/PKG-INFO +3 -1
  2. {codexspec-0.7.2 → codexspec-0.7.3}/README.md +2 -0
  3. {codexspec-0.7.2 → codexspec-0.7.3}/pyproject.toml +1 -1
  4. {codexspec-0.7.2 → codexspec-0.7.3}/src/codexspec/__init__.py +174 -0
  5. {codexspec-0.7.2 → codexspec-0.7.3}/templates/commands/config.md +27 -3
  6. {codexspec-0.7.2 → codexspec-0.7.3}/.gitignore +0 -0
  7. {codexspec-0.7.2 → codexspec-0.7.3}/LICENSE +0 -0
  8. {codexspec-0.7.2 → codexspec-0.7.3}/codexspec-icon.svg +0 -0
  9. {codexspec-0.7.2 → codexspec-0.7.3}/codexspec-logo-dark.svg +0 -0
  10. {codexspec-0.7.2 → codexspec-0.7.3}/codexspec-logo-light.svg +0 -0
  11. {codexspec-0.7.2 → codexspec-0.7.3}/scripts/bash/check-i18n-completeness.sh +0 -0
  12. {codexspec-0.7.2 → codexspec-0.7.3}/scripts/bash/check-i18n-structure.sh +0 -0
  13. {codexspec-0.7.2 → codexspec-0.7.3}/scripts/bash/check-prerequisites.sh +0 -0
  14. {codexspec-0.7.2 → codexspec-0.7.3}/scripts/bash/common.sh +0 -0
  15. {codexspec-0.7.2 → codexspec-0.7.3}/scripts/bash/create-new-feature.sh +0 -0
  16. {codexspec-0.7.2 → codexspec-0.7.3}/scripts/powershell/check-prerequisites.ps1 +0 -0
  17. {codexspec-0.7.2 → codexspec-0.7.3}/scripts/powershell/common.ps1 +0 -0
  18. {codexspec-0.7.2 → codexspec-0.7.3}/scripts/powershell/create-new-feature.ps1 +0 -0
  19. {codexspec-0.7.2 → codexspec-0.7.3}/src/codexspec/commands/__init__.py +0 -0
  20. {codexspec-0.7.2 → codexspec-0.7.3}/src/codexspec/commands/installer.py +0 -0
  21. {codexspec-0.7.2 → codexspec-0.7.3}/src/codexspec/i18n.py +0 -0
  22. {codexspec-0.7.2 → codexspec-0.7.3}/src/codexspec/idea.md +0 -0
  23. {codexspec-0.7.2 → codexspec-0.7.3}/src/codexspec/integrations/__init__.py +0 -0
  24. {codexspec-0.7.2 → codexspec-0.7.3}/src/codexspec/integrations/base.py +0 -0
  25. {codexspec-0.7.2 → codexspec-0.7.3}/src/codexspec/integrations/claude.py +0 -0
  26. {codexspec-0.7.2 → codexspec-0.7.3}/src/codexspec/integrations/codex.py +0 -0
  27. {codexspec-0.7.2 → codexspec-0.7.3}/src/codexspec/translator.py +0 -0
  28. {codexspec-0.7.2 → codexspec-0.7.3}/templates/commands/analyze.md +0 -0
  29. {codexspec-0.7.2 → codexspec-0.7.3}/templates/commands/checklist.md +0 -0
  30. {codexspec-0.7.2 → codexspec-0.7.3}/templates/commands/clarify.md +0 -0
  31. {codexspec-0.7.2 → codexspec-0.7.3}/templates/commands/commit-staged.md +0 -0
  32. {codexspec-0.7.2 → codexspec-0.7.3}/templates/commands/constitution.md +0 -0
  33. {codexspec-0.7.2 → codexspec-0.7.3}/templates/commands/generate-spec.md +0 -0
  34. {codexspec-0.7.2 → codexspec-0.7.3}/templates/commands/implement-tasks.md +0 -0
  35. {codexspec-0.7.2 → codexspec-0.7.3}/templates/commands/plan-to-tasks.md +0 -0
  36. {codexspec-0.7.2 → codexspec-0.7.3}/templates/commands/pr.md +0 -0
  37. {codexspec-0.7.2 → codexspec-0.7.3}/templates/commands/quick.md +0 -0
  38. {codexspec-0.7.2 → codexspec-0.7.3}/templates/commands/review-code.md +0 -0
  39. {codexspec-0.7.2 → codexspec-0.7.3}/templates/commands/review-plan.md +0 -0
  40. {codexspec-0.7.2 → codexspec-0.7.3}/templates/commands/review-spec.md +0 -0
  41. {codexspec-0.7.2 → codexspec-0.7.3}/templates/commands/review-tasks.md +0 -0
  42. {codexspec-0.7.2 → codexspec-0.7.3}/templates/commands/spec-to-plan.md +0 -0
  43. {codexspec-0.7.2 → codexspec-0.7.3}/templates/commands/specify.md +0 -0
  44. {codexspec-0.7.2 → codexspec-0.7.3}/templates/commands/tasks-to-issues.md +0 -0
  45. {codexspec-0.7.2 → codexspec-0.7.3}/templates/docs/checklist-template.md +0 -0
  46. {codexspec-0.7.2 → codexspec-0.7.3}/templates/docs/constitution-template.md +0 -0
  47. {codexspec-0.7.2 → codexspec-0.7.3}/templates/docs/plan-template-detailed.md +0 -0
  48. {codexspec-0.7.2 → codexspec-0.7.3}/templates/docs/plan-template-simple.md +0 -0
  49. {codexspec-0.7.2 → codexspec-0.7.3}/templates/docs/requirements-template.md +0 -0
  50. {codexspec-0.7.2 → codexspec-0.7.3}/templates/docs/spec-template-detailed.md +0 -0
  51. {codexspec-0.7.2 → codexspec-0.7.3}/templates/docs/spec-template-simple.md +0 -0
  52. {codexspec-0.7.2 → codexspec-0.7.3}/templates/docs/tasks-template-detailed.md +0 -0
  53. {codexspec-0.7.2 → codexspec-0.7.3}/templates/docs/tasks-template-simple.md +0 -0
  54. {codexspec-0.7.2 → codexspec-0.7.3}/templates/translations/de.json +0 -0
  55. {codexspec-0.7.2 → codexspec-0.7.3}/templates/translations/en.json +0 -0
  56. {codexspec-0.7.2 → codexspec-0.7.3}/templates/translations/es.json +0 -0
  57. {codexspec-0.7.2 → codexspec-0.7.3}/templates/translations/fr.json +0 -0
  58. {codexspec-0.7.2 → codexspec-0.7.3}/templates/translations/ja.json +0 -0
  59. {codexspec-0.7.2 → codexspec-0.7.3}/templates/translations/ko.json +0 -0
  60. {codexspec-0.7.2 → codexspec-0.7.3}/templates/translations/pt-BR.json +0 -0
  61. {codexspec-0.7.2 → codexspec-0.7.3}/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.3
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.3"
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
 
@@ -104,6 +104,7 @@ Display the configuration as in Step 2, then exit.
104
104
  {"label": "Document language", "description": "Language for generated artifact files (requirements/spec/plan/tasks) (currently: {current value})"},
105
105
  {"label": "Output language (legacy)", "description": "Fallback language used when interaction/document are not set (currently: {current value})"},
106
106
  {"label": "Commit language", "description": "Language for commit messages (currently: {current value})"},
107
+ {"label": "Auto-next chain", "description": "Auto-advance the SDD pipeline once a stage passes (workflow.auto_next) (currently: {current value})"},
107
108
  {"label": "Back", "description": "Return to main menu"}
108
109
  ]
109
110
  }]
@@ -127,9 +128,32 @@ Display the configuration as in Step 2, then exit.
127
128
  }
128
129
  ```
129
130
 
130
- 3. Update the configuration file with the new value
131
- 4. Display the updated configuration
132
- 5. Exit
131
+ 3. For "Auto-next chain", ask whether to enable or disable:
132
+
133
+ ```json
134
+ {
135
+ "questions": [{
136
+ "question": "Set workflow.auto_next:",
137
+ "header": "Auto-next",
138
+ "options": [
139
+ {"label": "Enable", "description": "Auto-advance the SDD pipeline once a stage passes"},
140
+ {"label": "Disable", "description": "Do not auto-advance; advance to the next command manually"},
141
+ {"label": "Back", "description": "Return without changing"}
142
+ ]
143
+ }]
144
+ }
145
+ ```
146
+
147
+ Then read `.codexspec/config.yml`. The current value is enabled only when
148
+ `workflow.auto_next` is the literal `true`; an absent key/section, `false`,
149
+ or any other value is disabled. Write `workflow.auto_next` as an unquoted
150
+ `true`/`false` (update the value in place when the key exists; otherwise add
151
+ a `workflow:` section with `auto_next: <bool>`), preserving every other
152
+ line and comment.
153
+
154
+ 4. Update the configuration file with the new value
155
+ 5. Display the updated configuration
156
+ 6. Exit
133
157
 
134
158
  #### Option: Reset to defaults
135
159
 
File without changes
File without changes
File without changes