@aipper/aiws-spec 0.0.21 → 0.0.24

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 (89) hide show
  1. package/docs/spec-contract.md +5 -4
  2. package/package.json +1 -1
  3. package/templates/workspace/.agents/skills/{aiws-change-archive → p-aiws-change-archive}/SKILL.md +3 -2
  4. package/templates/workspace/.agents/skills/{aiws-change-finish → p-aiws-change-finish}/SKILL.md +2 -2
  5. package/templates/workspace/.agents/skills/{aiws-change-list → p-aiws-change-list}/SKILL.md +2 -2
  6. package/templates/workspace/.agents/skills/{aiws-change-new → p-aiws-change-new}/SKILL.md +2 -2
  7. package/templates/workspace/.agents/skills/{aiws-change-next → p-aiws-change-next}/SKILL.md +2 -2
  8. package/templates/workspace/.agents/skills/{aiws-change-start → p-aiws-change-start}/SKILL.md +2 -2
  9. package/templates/workspace/.agents/skills/{aiws-change-status → p-aiws-change-status}/SKILL.md +2 -2
  10. package/templates/workspace/.agents/skills/{aiws-change-sync → p-aiws-change-sync}/SKILL.md +2 -2
  11. package/templates/workspace/.agents/skills/{aiws-change-templates-init → p-aiws-change-templates-init}/SKILL.md +2 -2
  12. package/templates/workspace/.agents/skills/{aiws-change-templates-which → p-aiws-change-templates-which}/SKILL.md +2 -2
  13. package/templates/workspace/.agents/skills/{aiws-change-validate → p-aiws-change-validate}/SKILL.md +2 -2
  14. package/templates/workspace/.agents/skills/{aiws-hooks-install → p-aiws-hooks-install}/SKILL.md +2 -2
  15. package/templates/workspace/.agents/skills/{aiws-hooks-status → p-aiws-hooks-status}/SKILL.md +2 -2
  16. package/templates/workspace/.agents/skills/{aiws-init → p-aiws-init}/SKILL.md +2 -2
  17. package/templates/workspace/.agents/skills/{aiws-rollback → p-aiws-rollback}/SKILL.md +2 -2
  18. package/templates/workspace/.agents/skills/{aiws-update → p-aiws-update}/SKILL.md +2 -2
  19. package/templates/workspace/.agents/skills/{aiws-validate → p-aiws-validate}/SKILL.md +2 -2
  20. package/templates/workspace/.agents/skills/p-tasks-plan/SKILL.md +37 -0
  21. package/templates/workspace/.agents/skills/ws-bugfix/SKILL.md +30 -7
  22. package/templates/workspace/.agents/skills/ws-commit/SKILL.md +23 -6
  23. package/templates/workspace/.agents/skills/ws-deliver/SKILL.md +61 -17
  24. package/templates/workspace/.agents/skills/ws-dev/SKILL.md +102 -2
  25. package/templates/workspace/.agents/skills/ws-finish/SKILL.md +96 -65
  26. package/templates/workspace/.agents/skills/ws-handoff/SKILL.md +31 -0
  27. package/templates/workspace/.agents/skills/ws-plan/SKILL.md +68 -1
  28. package/templates/workspace/.agents/skills/ws-push/SKILL.md +17 -12
  29. package/templates/workspace/.claude/commands/{aiws-change-archive.md → p-aiws-change-archive.md} +3 -1
  30. package/templates/workspace/.claude/commands/{aiws-change-finish.md → p-aiws-change-finish.md} +2 -0
  31. package/templates/workspace/.claude/commands/{aiws-change-list.md → p-aiws-change-list.md} +2 -0
  32. package/templates/workspace/.claude/commands/{aiws-change-new.md → p-aiws-change-new.md} +2 -0
  33. package/templates/workspace/.claude/commands/{aiws-change-next.md → p-aiws-change-next.md} +2 -0
  34. package/templates/workspace/.claude/commands/{aiws-change-start.md → p-aiws-change-start.md} +2 -0
  35. package/templates/workspace/.claude/commands/{aiws-change-status.md → p-aiws-change-status.md} +2 -0
  36. package/templates/workspace/.claude/commands/{aiws-change-sync.md → p-aiws-change-sync.md} +2 -0
  37. package/templates/workspace/.claude/commands/{aiws-change-templates-init.md → p-aiws-change-templates-init.md} +2 -0
  38. package/templates/workspace/.claude/commands/{aiws-change-templates-which.md → p-aiws-change-templates-which.md} +2 -0
  39. package/templates/workspace/.claude/commands/{aiws-change-validate.md → p-aiws-change-validate.md} +2 -0
  40. package/templates/workspace/.claude/commands/{aiws-hooks-install.md → p-aiws-hooks-install.md} +2 -0
  41. package/templates/workspace/.claude/commands/{aiws-hooks-status.md → p-aiws-hooks-status.md} +2 -0
  42. package/templates/workspace/.claude/commands/{aiws-init.md → p-aiws-init.md} +2 -1
  43. package/templates/workspace/.claude/commands/{aiws-rollback.md → p-aiws-rollback.md} +2 -1
  44. package/templates/workspace/.claude/commands/{aiws-update.md → p-aiws-update.md} +2 -1
  45. package/templates/workspace/.claude/commands/{aiws-validate.md → p-aiws-validate.md} +2 -1
  46. package/templates/workspace/.claude/commands/ws-bugfix.md +11 -6
  47. package/templates/workspace/.claude/commands/ws-commit.md +2 -1
  48. package/templates/workspace/.claude/commands/ws-deliver.md +6 -2
  49. package/templates/workspace/.claude/commands/ws-dev.md +7 -1
  50. package/templates/workspace/.claude/commands/ws-finish.md +19 -19
  51. package/templates/workspace/.claude/commands/ws-handoff.md +22 -0
  52. package/templates/workspace/.claude/commands/ws-plan.md +9 -5
  53. package/templates/workspace/.codex/prompts/ws-dev.md +5 -1
  54. package/templates/workspace/.githooks/commit-msg +109 -0
  55. package/templates/workspace/.iflow/commands/ws-commit.toml +2 -1
  56. package/templates/workspace/.iflow/commands/ws-deliver.toml +6 -2
  57. package/templates/workspace/.iflow/commands/ws-finish.toml +19 -19
  58. package/templates/workspace/.opencode/command/{aiws-change-archive.md → p-aiws-change-archive.md} +4 -2
  59. package/templates/workspace/.opencode/command/{aiws-change-finish.md → p-aiws-change-finish.md} +3 -1
  60. package/templates/workspace/.opencode/command/{aiws-change-list.md → p-aiws-change-list.md} +3 -1
  61. package/templates/workspace/.opencode/command/{aiws-change-new.md → p-aiws-change-new.md} +3 -1
  62. package/templates/workspace/.opencode/command/{aiws-change-next.md → p-aiws-change-next.md} +3 -1
  63. package/templates/workspace/.opencode/command/{aiws-change-start.md → p-aiws-change-start.md} +3 -1
  64. package/templates/workspace/.opencode/command/{aiws-change-status.md → p-aiws-change-status.md} +3 -1
  65. package/templates/workspace/.opencode/command/{aiws-change-sync.md → p-aiws-change-sync.md} +3 -1
  66. package/templates/workspace/.opencode/command/{aiws-change-templates-init.md → p-aiws-change-templates-init.md} +3 -1
  67. package/templates/workspace/.opencode/command/{aiws-change-templates-which.md → p-aiws-change-templates-which.md} +3 -1
  68. package/templates/workspace/.opencode/command/{aiws-change-validate.md → p-aiws-change-validate.md} +3 -1
  69. package/templates/workspace/.opencode/command/{aiws-hooks-install.md → p-aiws-hooks-install.md} +3 -1
  70. package/templates/workspace/.opencode/command/{aiws-hooks-status.md → p-aiws-hooks-status.md} +3 -1
  71. package/templates/workspace/.opencode/command/{aiws-init.md → p-aiws-init.md} +3 -1
  72. package/templates/workspace/.opencode/command/{aiws-rollback.md → p-aiws-rollback.md} +3 -1
  73. package/templates/workspace/.opencode/command/{aiws-update.md → p-aiws-update.md} +3 -1
  74. package/templates/workspace/.opencode/command/{aiws-validate.md → p-aiws-validate.md} +3 -1
  75. package/templates/workspace/.opencode/command/ws-bugfix.md +11 -6
  76. package/templates/workspace/.opencode/command/ws-commit.md +3 -2
  77. package/templates/workspace/.opencode/command/ws-deliver.md +6 -2
  78. package/templates/workspace/.opencode/command/ws-dev.md +7 -1
  79. package/templates/workspace/.opencode/command/ws-finish.md +19 -19
  80. package/templates/workspace/.opencode/command/ws-handoff.md +25 -0
  81. package/templates/workspace/.opencode/command/ws-plan.md +9 -5
  82. package/templates/workspace/.opencode/command/ws-review.md +1 -1
  83. package/templates/workspace/AGENTS.md +8 -4
  84. package/templates/workspace/AI_WORKSPACE.md +4 -4
  85. package/templates/workspace/changes/README.md +8 -2
  86. package/templates/workspace/manifest.json +173 -103
  87. package/templates/workspace/tools/ws_change_check.py +99 -0
  88. package/templates/workspace/tools/ws_resolve_sub_target.sh +47 -0
  89. package/templates/workspace/tools/ws_tasks_plan.py +137 -0
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Generate an update_plan JSON payload from changes/<id>/tasks.md checkbox tasks.
4
+
5
+ This script is intended to be used by the `p-tasks-plan` Codex skill.
6
+ It reads tasks.md only and does not modify it.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import argparse
12
+ import json
13
+ import re
14
+ import sys
15
+ from dataclasses import dataclass
16
+ from pathlib import Path
17
+
18
+
19
+ _TASK_RE = re.compile(r"^\s*[-*]\s+\[([ xX])\]\s+(.*\S)\s*$")
20
+
21
+
22
+ @dataclass(frozen=True)
23
+ class Task:
24
+ text: str
25
+ done: bool
26
+
27
+
28
+ def _read_tasks_md(path: Path) -> str:
29
+ if not path.exists():
30
+ raise FileNotFoundError(str(path))
31
+ return path.read_text(encoding="utf-8")
32
+
33
+
34
+ def _extract_tasks(markdown: str) -> list[Task]:
35
+ tasks: list[Task] = []
36
+ in_code_block = False
37
+ for raw_line in markdown.splitlines():
38
+ line = raw_line.rstrip("\n")
39
+ if line.lstrip().startswith("```"):
40
+ in_code_block = not in_code_block
41
+ continue
42
+ if in_code_block:
43
+ continue
44
+ m = _TASK_RE.match(line)
45
+ if not m:
46
+ continue
47
+ mark = m.group(1)
48
+ text = m.group(2).strip()
49
+ if not text:
50
+ continue
51
+ tasks.append(Task(text=text, done=(mark.lower() == "x")))
52
+ return tasks
53
+
54
+
55
+ def _plan_statuses(tasks: list[Task]) -> list[str]:
56
+ first_todo_idx = next((i for i, t in enumerate(tasks) if not t.done), None)
57
+ statuses: list[str] = []
58
+ for i, t in enumerate(tasks):
59
+ if t.done:
60
+ statuses.append("completed")
61
+ elif first_todo_idx is not None and i == first_todo_idx:
62
+ statuses.append("in_progress")
63
+ else:
64
+ statuses.append("pending")
65
+ return statuses
66
+
67
+
68
+ def cmd_status(args: argparse.Namespace) -> int:
69
+ path = Path(args.file).resolve()
70
+ try:
71
+ tasks = _extract_tasks(_read_tasks_md(path))
72
+ except FileNotFoundError:
73
+ print(f"tasks.md not found: {path}", file=sys.stderr)
74
+ return 2
75
+
76
+ if not tasks:
77
+ print(f"No checkbox tasks found in: {path}", file=sys.stderr)
78
+ return 2
79
+
80
+ total = len(tasks)
81
+ done = sum(1 for t in tasks if t.done)
82
+ first_todo_idx = next((i for i, t in enumerate(tasks) if not t.done), None)
83
+ suffix = f" (IN_PROGRESS: {first_todo_idx + 1})" if first_todo_idx is not None else ""
84
+ print(f"{done}/{total} DONE{suffix}")
85
+ return 0
86
+
87
+
88
+ def cmd_plan(args: argparse.Namespace) -> int:
89
+ path = Path(args.file).resolve()
90
+ try:
91
+ tasks = _extract_tasks(_read_tasks_md(path))
92
+ except FileNotFoundError:
93
+ print(f"tasks.md not found: {path}", file=sys.stderr)
94
+ return 2
95
+
96
+ if not tasks:
97
+ print(f"No checkbox tasks found in: {path}", file=sys.stderr)
98
+ return 2
99
+
100
+ statuses = _plan_statuses(tasks)
101
+ if len(tasks) != len(statuses):
102
+ print("Internal error: tasks/statuses length mismatch", file=sys.stderr)
103
+ return 2
104
+
105
+ payload = {
106
+ "explanation": args.explanation or "",
107
+ "plan": [{"step": t.text, "status": s} for t, s in zip(tasks, statuses)],
108
+ }
109
+ json.dump(payload, sys.stdout, ensure_ascii=False, indent=2)
110
+ sys.stdout.write("\n")
111
+ return 0
112
+
113
+
114
+ def build_parser() -> argparse.ArgumentParser:
115
+ p = argparse.ArgumentParser(prog="ws_tasks_plan.py")
116
+ sub = p.add_subparsers(dest="cmd", required=True)
117
+
118
+ p_status = sub.add_parser("status", help="Print progress summary from tasks.md")
119
+ p_status.add_argument("--file", required=True, help="Path to changes/<id>/tasks.md")
120
+ p_status.set_defaults(fn=cmd_status)
121
+
122
+ p_plan = sub.add_parser("plan", help="Generate update_plan JSON payload from tasks.md")
123
+ p_plan.add_argument("--file", required=True, help="Path to changes/<id>/tasks.md")
124
+ p_plan.add_argument("--explanation", default="", help="Explanation for update_plan payload")
125
+ p_plan.set_defaults(fn=cmd_plan)
126
+
127
+ return p
128
+
129
+
130
+ def main(argv: list[str]) -> int:
131
+ parser = build_parser()
132
+ args = parser.parse_args(argv)
133
+ return int(args.fn(args))
134
+
135
+
136
+ if __name__ == "__main__":
137
+ raise SystemExit(main(sys.argv[1:]))