@chinhae/atw-cli 0.3.6 → 0.5.0
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.
- package/README.md +191 -17
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +25 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +154 -17
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mode.d.ts +21 -0
- package/dist/commands/mode.d.ts.map +1 -0
- package/dist/commands/mode.js +401 -0
- package/dist/commands/mode.js.map +1 -0
- package/dist/commands/update.d.ts +7 -0
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +20 -13
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/workflow.d.ts +17 -0
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +9 -3
- package/dist/commands/workflow.js.map +1 -1
- package/dist/configurators/claude.d.ts +3 -2
- package/dist/configurators/claude.d.ts.map +1 -1
- package/dist/configurators/claude.js +3 -3
- package/dist/configurators/claude.js.map +1 -1
- package/dist/configurators/codex.d.ts +4 -3
- package/dist/configurators/codex.d.ts.map +1 -1
- package/dist/configurators/codex.js +10 -10
- package/dist/configurators/codex.js.map +1 -1
- package/dist/configurators/index.d.ts +9 -3
- package/dist/configurators/index.d.ts.map +1 -1
- package/dist/configurators/index.js +95 -17
- package/dist/configurators/index.js.map +1 -1
- package/dist/configurators/shared.d.ts +13 -0
- package/dist/configurators/shared.d.ts.map +1 -1
- package/dist/configurators/shared.js +25 -0
- package/dist/configurators/shared.js.map +1 -1
- package/dist/configurators/workflow.d.ts +15 -1
- package/dist/configurators/workflow.d.ts.map +1 -1
- package/dist/configurators/workflow.js +23 -5
- package/dist/configurators/workflow.js.map +1 -1
- package/dist/configurators/zcode.d.ts +1 -1
- package/dist/configurators/zcode.d.ts.map +1 -1
- package/dist/configurators/zcode.js +2 -2
- package/dist/configurators/zcode.js.map +1 -1
- package/dist/constants/paths.d.ts +4 -0
- package/dist/constants/paths.d.ts.map +1 -1
- package/dist/constants/paths.js +4 -0
- package/dist/constants/paths.js.map +1 -1
- package/dist/migrations/manifests/0.4.0.json +9 -0
- package/dist/migrations/manifests/0.5.0.json +9 -0
- package/dist/templates/atw/config.yaml +7 -6
- package/dist/templates/atw/index.d.ts +10 -1
- package/dist/templates/atw/index.d.ts.map +1 -1
- package/dist/templates/atw/index.js +11 -1
- package/dist/templates/atw/index.js.map +1 -1
- package/dist/templates/atw/scripts/add_session.py +34 -13
- package/dist/templates/atw/scripts/common/active_task.py +2 -2
- package/dist/templates/atw/scripts/common/config.py +13 -0
- package/dist/templates/atw/scripts/common/developer.py +15 -4
- package/dist/templates/atw/scripts/common/noob_mode.py +35 -15
- package/dist/templates/atw/scripts/common/packages_context.py +16 -3
- package/dist/templates/atw/scripts/common/session_context.py +77 -19
- package/dist/templates/atw/scripts/common/task_store.py +78 -27
- package/dist/templates/atw/scripts/noob_mode.py +16 -4
- package/dist/templates/atw/scripts/task.py +99 -38
- package/dist/templates/atw/workflow-general.md +554 -0
- package/dist/templates/atw/workflow.md +49 -19
- package/dist/templates/codex/hooks/session-start.py +69 -18
- package/dist/templates/common/bundled-skills/atw-implement/SKILL.md +8 -0
- package/dist/templates/common/bundled-skills/atw-implement-all/SKILL.md +93 -0
- package/dist/templates/common/bundled-skills/atw-implement-all/agents/openai.yaml +5 -0
- package/dist/templates/common/bundled-skills/atw-init-repo/references/issue-tracker-atw-local.md +3 -1
- package/dist/templates/common/bundled-skills/atw-init-repo/references/issue-tracker-atw.md +3 -1
- package/dist/templates/common/bundled-skills/atw-noob-mode/SKILL.md +7 -5
- package/dist/templates/common/bundled-skills/atw-tickets/SKILL.md +2 -0
- package/dist/templates/common/commands/continue.md +1 -1
- package/dist/templates/common/commands/start.md +43 -0
- package/dist/templates/copilot/hooks/session-start.py +69 -18
- package/dist/templates/dsh/DSH.md +43 -0
- package/dist/templates/markdown/agents.md +11 -0
- package/dist/templates/markdown/index.d.ts +9 -0
- package/dist/templates/markdown/index.d.ts.map +1 -1
- package/dist/templates/markdown/index.js +14 -1
- package/dist/templates/markdown/index.js.map +1 -1
- package/dist/templates/markdown/spec/conventions.md.txt +13 -0
- package/dist/templates/opencode/lib/atw-context.js +19 -0
- package/dist/templates/opencode/lib/session-utils.js +79 -24
- package/dist/templates/opencode/plugins/inject-workflow-state.js +18 -8
- package/dist/templates/pi/extensions/atw/index.ts.txt +20 -9
- package/dist/templates/shared-hooks/inject-shell-session-context.py +3 -3
- package/dist/templates/shared-hooks/inject-workflow-state.py +23 -4
- package/dist/templates/shared-hooks/session-start.py +70 -22
- package/dist/templates/snow/SNOW.md +31 -1
- package/dist/templates/snow/hooks/write-atw-context.py +64 -0
- package/dist/utils/manifest-prune.d.ts +2 -1
- package/dist/utils/manifest-prune.d.ts.map +1 -1
- package/dist/utils/manifest-prune.js +10 -7
- package/dist/utils/manifest-prune.js.map +1 -1
- package/dist/utils/optional-skills.d.ts.map +1 -1
- package/dist/utils/optional-skills.js +2 -1
- package/dist/utils/optional-skills.js.map +1 -1
- package/dist/utils/project-mode.d.ts +30 -0
- package/dist/utils/project-mode.d.ts.map +1 -0
- package/dist/utils/project-mode.js +86 -0
- package/dist/utils/project-mode.js.map +1 -0
- package/dist/utils/workflow-resolver.d.ts +9 -5
- package/dist/utils/workflow-resolver.d.ts.map +1 -1
- package/dist/utils/workflow-resolver.js +25 -11
- package/dist/utils/workflow-resolver.js.map +1 -1
- package/package.json +3 -3
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
1. **Plan before code** — figure out what to do before you start
|
|
8
8
|
2. **Specs injected, not remembered** — guidelines are injected via hook/skill, not recalled from memory
|
|
9
9
|
3. **Persist everything** — research, decisions, and lessons all go to files; conversations get compacted, files don't
|
|
10
|
-
4. **One ticket at a time, unless the user asks for the whole spec at once** — serial by default: claim, finish, close, then take the next. `/atw-implement-spec` is the one parallel path,
|
|
10
|
+
4. **One ticket at a time, unless the user asks for the whole spec at once** — serial by default: claim, finish, close, then take the next. `/atw-implement-spec` is the one parallel path; `/atw-implement-all` is the third way through stop ③ — started once, still serial, still reviewed per ticket. Only the user starts any of them
|
|
11
11
|
5. **Capture learnings** — after each ticket, review and write new knowledge back to spec
|
|
12
12
|
|
|
13
13
|
---
|
|
@@ -32,7 +32,7 @@ For a user who is not an engineer. While it is on, every reply in every stage is
|
|
|
32
32
|
python3 ./.atw/scripts/noob_mode.py on|off|status
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
The user switches it by saying "开启小白模式" / "关闭小白模式" or running `/atw-noob-mode`; the skill runs the script.
|
|
35
|
+
The user switches it by saying "开启小白模式" / "关闭小白模式" or running `/atw-noob-mode`; the skill runs the script. Their choice — on or off — is one line in that user's own `.atw/.developer`, so it is personal and never committed. A user who has never chosen gets the project mode's default: on when `.atw/config.yaml` says `mode: general`, off when it says `mode: dev` or has no `mode` entry. Switching off is recorded as a choice, so neither the default nor a change of project mode turns it back on; `status` says which of the two is in effect. It changes how the AI talks to the user — not the stages, the stops, or what goes into task files.
|
|
36
36
|
|
|
37
37
|
### Spec System
|
|
38
38
|
|
|
@@ -205,7 +205,7 @@ python3 ./.atw/scripts/get_context.py --mode phase --step <X.Y> # detailed guid
|
|
|
205
205
|
|
|
206
206
|
```
|
|
207
207
|
Phase 1: Plan → discover, specify, and (when needed) slice into tickets
|
|
208
|
-
Phase 2: Execute → one ticket at a time through the full implement chain, or the whole spec in one parallel
|
|
208
|
+
Phase 2: Execute → one ticket at a time through the full implement chain, or the whole spec in one run — parallel, or serial with a review per ticket
|
|
209
209
|
Phase 3: Finish → read-only acceptance check, then archive
|
|
210
210
|
```
|
|
211
211
|
|
|
@@ -243,7 +243,7 @@ Outside these four, the AI advances stages on its own. It does not stop to ask "
|
|
|
243
243
|
|---|---|---|
|
|
244
244
|
| ① | Before creating a task | Does this work deserve a record — the user's |
|
|
245
245
|
| ② | After the spec is written | Is the spec right — the user's |
|
|
246
|
-
| ③ | Before implementation starts | The user runs `/atw-implement` per ticket, or `/atw-implement-
|
|
246
|
+
| ③ | Before implementation starts | The user runs `/atw-implement` per ticket, `/atw-implement-spec` once for the whole spec in parallel, or `/atw-implement-all` once for the whole spec serially; the AI cannot invoke any of the three |
|
|
247
247
|
| ④ | Before archiving | "This is done" — the user's acceptance |
|
|
248
248
|
|
|
249
249
|
### Planning Artifacts
|
|
@@ -335,19 +335,21 @@ When the tickets are written, run `task.py start <task>` (step 1.5) to enter imp
|
|
|
335
335
|
- 2.4 Close the ticket `[required · repeatable]`
|
|
336
336
|
- 2.5 Roll back `[on demand]`
|
|
337
337
|
- 2.7 Whole-spec run `[alternative to 2.1–2.4 · once]` (stop ③; the user picks it)
|
|
338
|
+
- 2.8 Serial whole-spec run `[alternative to 2.1–2.4 · once]` (stop ③; the user picks it)
|
|
338
339
|
|
|
339
340
|
<!-- Per-turn breadcrumb: stage 'implement' — set by task.py start, held for all of Phase 2 -->
|
|
340
341
|
|
|
341
342
|
[workflow-state:implement]
|
|
342
|
-
Stop ③: implementation is the user's to start. You may not invoke
|
|
343
|
+
Stop ③: implementation is the user's to start. You may not invoke any of the three skills below yourself, and you may not do the implementation inline instead. When the task has tickets, name all three ways and let the user pick; a task with no tickets has only the first.
|
|
343
344
|
Per-ticket path (the default): one ticket at a time. Run `tickets.py frontier`, pick one, `tickets.py claim NN` — never hold two tickets at `doing` — then tell the user to run `/atw-implement` for the claimed ticket. One user invocation per ticket.
|
|
344
345
|
Whole-spec path: the user runs `/atw-implement-spec` once. It owns the run from the first claim to the closing commit: it claims with `tickets.py claim NN --parallel`, dispatches implementer sub-agents across the frontier, each in its own worktree, lands everything on one integration branch, marks each ticket `done` as its work merges, reviews that branch once at the end, and writes spec updates back before its closing commit. Do not claim, review or commit around it. It needs a platform that dispatches sub-agents.
|
|
346
|
+
Serial whole-spec path: the user runs `/atw-implement-all` once. The main session is the orchestrator and the loop is the per-ticket chain without the per-ticket "start": claim → dispatch an implementer → review → fix once, re-check once → write spec updates back → `tickets.py done` → commit state → next ticket. Plain `tickets.py claim NN`, one ticket at `doing`, in place on the current branch, a review per ticket. It halts for four things — an implementer's result-changing ambiguity, a finding still open after the one re-check, a ticket that cannot be finished as written, a frontier holding only `ready-for-human` tickets or a next ticket that is plainly human work — and for `--max N`; a ticket left at `doing` is the breakpoint, and running the same command again resumes from it. It needs a platform that dispatches sub-agents.
|
|
345
347
|
On the per-ticket path, that one `/atw-implement` run is a closed chain and must not be broken up from the outside: implement (test-first where it fits) → run tests, full suite on the last pass → review → handle findings → write spec updates back → commit. Never instruct it to skip the review or the commit.
|
|
346
348
|
Findings triage: spec-axis findings and anything the standards axis calls a hard violation get fixed once, then only what was fixed is re-checked, once, then the commit. No second full review and no loop: anything still open after that one re-check goes to the user before the commit. Judgement calls ship and get reported.
|
|
347
349
|
Relay every review report to the user verbatim — Standards and Spec, plus Visual when the ticket changed UI — even when the verdict is "nothing found". No report reaching you is not a passing review.
|
|
348
350
|
Any sub-agent dispatched from here starts its prompt with `Active task: <task path from task.py current>` — the role files read that line to find the task, and it is the context hooks' fallback when session resolution misses.
|
|
349
|
-
Main-session default: run the process; on the per-ticket path the implementation itself is written inside `/atw-implement`, never by a dispatched `atw-implement-agent` — that role file is reserved and is not a step in this flow. The only sub-agent that path raises is `atw-review` (twice, from inside `/atw-implement` — three times when the ticket changes UI and a Visual review runs). Implementer sub-agents exist only inside a `/atw-implement-spec` run, dispatched by that skill and by nothing else. Sub-agent self-exemption: this breadcrumb reaches sub-agent turns on some hosts. If you are already running as `atw-review`, do NOT spawn another `atw-review` — do the review you were dispatched for. If you were dispatched by `/atw-implement-spec` as an implementer or merger, stop ③ is already satisfied — do the work you were dispatched for and dispatch nothing. Dispatch is main session only.
|
|
350
|
-
Per-ticket path: then `tickets.py done NN` and back to the frontier.
|
|
351
|
+
Main-session default: run the process; on the per-ticket path the implementation itself is written inside `/atw-implement`, never by a dispatched `atw-implement-agent` — that role file is reserved and is not a step in this flow. The only sub-agent that path raises is `atw-review` (twice, from inside `/atw-implement` — three times when the ticket changes UI and a Visual review runs). Implementer sub-agents exist only inside a `/atw-implement-spec` or `/atw-implement-all` run, dispatched by that skill and by nothing else. Sub-agent self-exemption: this breadcrumb reaches sub-agent turns on some hosts. If you are already running as `atw-review`, do NOT spawn another `atw-review` — do the review you were dispatched for. If you were dispatched by `/atw-implement-spec` as an implementer or merger, or by `/atw-implement-all` as an implementer, stop ③ is already satisfied — do the work you were dispatched for and dispatch nothing. Dispatch is main session only.
|
|
352
|
+
Per-ticket path: then `tickets.py done NN` and back to the frontier. Any path: when the frontier is empty and every ticket is `done`, run `task.py set-status <task> accept` and commit the `task.json` change, so the tree is clean when 3.1 starts.
|
|
351
353
|
[/workflow-state:implement]
|
|
352
354
|
|
|
353
355
|
### Phase 3: Finish
|
|
@@ -360,6 +362,7 @@ Per-ticket path: then `tickets.py done NN` and back to the frontier. Either path
|
|
|
360
362
|
[workflow-state:accept]
|
|
361
363
|
Read-only from here. Do not open new work, do not fix things you notice — file them as tickets or a follow-up task instead.
|
|
362
364
|
Walk the acceptance criteria in `prd.md` one by one and report which are met, with evidence; for UI criteria the evidence is a screenshot of the named screen, state and viewport (`/atw-ui` can review read-only). Confirm `tickets.py summary` shows every ticket `done` and `git status --porcelain` is clean.
|
|
365
|
+
As each criterion checks out, tick its checkbox in `prd.md` and in the ticket that carried it — the ticks are the acceptance record, nobody earlier ticks them. Commit the ticks once (`chore(task): <task> acceptance check`) before stop ④.
|
|
363
366
|
Stop ④: present that and wait for the user to accept. Acceptance is the user's judgement, not yours.
|
|
364
367
|
Once accepted, run `task.py archive <task>` — status goes to `completed` and the task moves to `archive/`.
|
|
365
368
|
[/workflow-state:accept]
|
|
@@ -391,14 +394,15 @@ When a user request matches one of these intents inside an active task, route fi
|
|
|
391
394
|
- Slicing a confirmed spec into tickets → `/atw-tickets`
|
|
392
395
|
- Starting a claimed ticket → `/atw-implement` (the user runs it; stop ③)
|
|
393
396
|
- Implementing every ticket of a sliced spec in one parallel run → `/atw-implement-spec` (the user runs it; stop ③)
|
|
397
|
+
- Implementing every ticket of a sliced spec in one serial run, reviewed per ticket → `/atw-implement-all` (the user runs it; stop ③)
|
|
394
398
|
- Building or polishing a screen for a claimed ticket → `/atw-ui`, used from inside `/atw-implement`
|
|
395
399
|
- Same bug fixed more than once → `/atw-diagnosing-bugs`
|
|
396
400
|
- Knowledge worth keeping outside a ticket → `/atw-update-spec`
|
|
397
401
|
- The user cannot follow the terms, an approval prompt or an error, or says "开启小白模式" / "关闭小白模式" → `/atw-noob-mode` (in any stage, with or without a task)
|
|
398
402
|
|
|
399
|
-
|
|
403
|
+
Eight of these are user-triggered and the AI cannot invoke them: `/atw-askme`,
|
|
400
404
|
`/atw-askme-with-docs`, `/atw-map`, `/atw-spec`, `/atw-tickets`, `/atw-implement`,
|
|
401
|
-
`/atw-implement-spec`.
|
|
405
|
+
`/atw-implement-spec`, `/atw-implement-all`.
|
|
402
406
|
Name the one that fits and let the user run it — calling the Skill tool on one
|
|
403
407
|
returns an error and nothing else.
|
|
404
408
|
|
|
@@ -408,6 +412,7 @@ returns an error and nothing else.
|
|
|
408
412
|
- Stops ①–④ are the user's calls. Never advance through one by inferring the answer.
|
|
409
413
|
- Planning must be persisted to task artifacts; the review chain must run before reporting a ticket complete.
|
|
410
414
|
- Never mark two tickets `**Impl:** doing` at the same time. The only thing that may is a `/atw-implement-spec` run, through `tickets.py claim NN --parallel`.
|
|
415
|
+
- `/atw-implement-all` is a user-started run like `/atw-implement-spec`: it claims serially and dispatches its own implementers. Outside one of those two runs, no implementer sub-agent is dispatched.
|
|
411
416
|
|
|
412
417
|
### Loading Step Detail
|
|
413
418
|
|
|
@@ -590,16 +595,17 @@ Ready to leave Phase 1:
|
|
|
590
595
|
|
|
591
596
|
Goal: turn the confirmed spec into committed, reviewed code.
|
|
592
597
|
|
|
593
|
-
There are
|
|
598
|
+
There are three ways through this phase, and the user picks at stop ③:
|
|
594
599
|
|
|
595
600
|
| Path | What the user runs | How the tickets move |
|
|
596
601
|
|---|---|---|
|
|
597
602
|
| Per ticket (the default) | `/atw-implement`, once per ticket | Steps 2.1–2.4: one ticket at a time, each reviewed before it is closed |
|
|
598
603
|
| Whole spec | `/atw-implement-spec`, once | Step 2.7: implementer sub-agents work the frontier in parallel on one integration branch, reviewed once at the end |
|
|
604
|
+
| Whole spec, serial | `/atw-implement-all`, once | Step 2.8: the main session orchestrates — one implementer sub-agent per ticket, in place on the current branch, each ticket reviewed before it is closed |
|
|
599
605
|
|
|
600
|
-
A task with no tickets has only the per-ticket path.
|
|
606
|
+
A task with no tickets has only the per-ticket path. Both whole-spec paths also need a platform that dispatches sub-agents; on one that does not, name only the per-ticket path.
|
|
601
607
|
|
|
602
|
-
The main session runs the process. On the per-ticket path it does not write the implementation itself and it does not dispatch an implementation sub-agent — the work happens inside `/atw-implement`, which the user starts. On
|
|
608
|
+
The main session runs the process. On the per-ticket path it does not write the implementation itself and it does not dispatch an implementation sub-agent — the work happens inside `/atw-implement`, which the user starts. On either whole-spec path the main session is the orchestrator that skill describes — `/atw-implement-spec` or `/atw-implement-all` — and each run dispatches its own implementers; they are that skill's, not a step of this file.
|
|
603
609
|
|
|
604
610
|
**Sub-agent dispatch protocol** — applies to every platform and every sub-agent
|
|
605
611
|
dispatched anywhere in this workflow (the review sub-agents raised inside the
|
|
@@ -624,9 +630,9 @@ dispatch, and it dispatches itself.
|
|
|
624
630
|
Implementation is never dispatched on the per-ticket path. `atw-implement-agent`
|
|
625
631
|
ships as a reserved role file so the injection path stays wired (D23), but no
|
|
626
632
|
step in this workflow spawns it — the code is written inside `/atw-implement`.
|
|
627
|
-
A `/atw-implement-spec` run does dispatch implementers,
|
|
628
|
-
sub-agents carrying that skill's own brief — not
|
|
629
|
-
may not commit.
|
|
633
|
+
A `/atw-implement-spec` or `/atw-implement-all` run does dispatch implementers,
|
|
634
|
+
as general-purpose sub-agents carrying that skill's own brief — not
|
|
635
|
+
`atw-implement-agent`, which may not commit.
|
|
630
636
|
|
|
631
637
|
On Grok Build, use `spawn_subagent` with `subagent_type` set to the ATW agent
|
|
632
638
|
name (e.g. `atw-review`). On Kimi Code, dispatch the built-in `coder` /
|
|
@@ -654,7 +660,7 @@ For a task that was never sliced, skip to 2.2: the whole `prd.md` is the unit of
|
|
|
654
660
|
|
|
655
661
|
**Stop ③**: tell the user to run `/atw-implement`.
|
|
656
662
|
|
|
657
|
-
You cannot invoke it and you must not substitute for it — not by implementing inline, and not by reading its instructions and following them yourself. One user invocation per ticket.
|
|
663
|
+
You cannot invoke it and you must not substitute for it — not by implementing inline, and not by reading its instructions and following them yourself. One user invocation per ticket. A ticket whose `**Status:**` is `ready-for-human` is not skipped on this path, but `/atw-implement` confirms with the user before touching code: they do it themselves, or they explicitly authorize the AI to do it, and that authorization goes into the commit `/atw-implement` makes at the end of its chain.
|
|
658
664
|
|
|
659
665
|
That single run is a closed chain:
|
|
660
666
|
|
|
@@ -712,7 +718,7 @@ If the same issue has now been fixed more than once, stop patching and tell the
|
|
|
712
718
|
|
|
713
719
|
#### 2.7 Whole-spec run `[alternative to 2.1–2.4 · once]`
|
|
714
720
|
|
|
715
|
-
**Stop ③**, the
|
|
721
|
+
**Stop ③**, the second way through it: the user runs `/atw-implement-spec` instead of `/atw-implement`. You cannot invoke it, and you do not start it because it looks faster — the user is trading a per-ticket look at the work for one review at the end, and that trade is theirs.
|
|
716
722
|
|
|
717
723
|
It replaces steps 2.1–2.4 for the whole task. The skill carries the procedure; what this file needs you to know is what changes around it:
|
|
718
724
|
|
|
@@ -730,6 +736,28 @@ When every ticket is `done`:
|
|
|
730
736
|
python3 ./.atw/scripts/task.py set-status <task-dir> accept
|
|
731
737
|
```
|
|
732
738
|
|
|
739
|
+
#### 2.8 Serial whole-spec run `[alternative to 2.1–2.4 · once]`
|
|
740
|
+
|
|
741
|
+
**Stop ③**, the third way through it: the user runs `/atw-implement-all` instead of `/atw-implement`. You cannot invoke it, and you do not start it because the user seems to want the whole spec done — removing the per-ticket "start" is the user's trade to make, same as in 2.7.
|
|
742
|
+
|
|
743
|
+
It replaces steps 2.1–2.4 for the whole task. The skill carries the procedure; what this file needs you to know is how it differs from 2.7:
|
|
744
|
+
|
|
745
|
+
- **Tickets run serially.** The main session is the orchestrator. It claims with the plain `tickets.py claim NN`, so exactly one ticket is at `**Impl:** doing` and it is the current ticket, as on the per-ticket path. Do not claim by hand during the run.
|
|
746
|
+
- **Work lands in place**, on the branch the task started on. One implementer sub-agent per ticket works on the current branch and commits there; no worktree, no integration branch, no merger.
|
|
747
|
+
- **One review per ticket**, run by the orchestrator in the main session against the `implementation_base_sha` the claim recorded, before the ticket is closed. Findings follow the 2.2 triage: fixed once by the same implementer, re-checked once; whatever is still open goes to the user before the spec is written back.
|
|
748
|
+
- **Spec updates land per ticket**, before the state commit that closes it. Every ticket leaves the implementer's code commit and the orchestrator's state commit.
|
|
749
|
+
- **Review reports are relayed as written** (step 2.3 applies unchanged).
|
|
750
|
+
|
|
751
|
+
The orchestrator takes the lowest-numbered frontier ticket whose `**Status:**` is not `ready-for-human`, and reads it before dispatching: plainly human work stops the run instead of being dispatched.
|
|
752
|
+
|
|
753
|
+
The run halts and reports when an implementer hits an ambiguity that would change the result (the orchestrator asks the user and continues), when a finding is still open after the one re-check (same), when a ticket cannot be finished as written, or when the frontier holds only `ready-for-human` tickets. `--max N` halts it cleanly after N tickets. Every closed ticket is already written back and committed, so stopping needs no cleanup: a ticket left at `doing` is the breakpoint, and running `/atw-implement-all` again resumes from it — or the user finishes that ticket with `/atw-implement` and runs it again. After the user finishes a `ready-for-human` ticket — by hand, or through `/atw-implement` — the next `/atw-implement-all` starts from whatever state that left: one ticket at `doing` (the per-ticket path may already have claimed the next frontier ticket, as 2.4 says) is resumed, not re-claimed; nothing at `doing` means the run claims from the frontier. A `doing` ticket after a human ticket is an expected state, not a broken one, and both branches close the ticket the same way — review, write-back, `done`, state commit. Every halt reports one table: a row per ticket with its state, commits, review verdicts and what the user was asked.
|
|
754
|
+
|
|
755
|
+
When every ticket is `done`, the run itself moves the task on, then commits the `task.json` change as the run's last state commit, so it ends on a clean tree:
|
|
756
|
+
|
|
757
|
+
```bash
|
|
758
|
+
python3 ./.atw/scripts/task.py set-status <task-dir> accept
|
|
759
|
+
```
|
|
760
|
+
|
|
733
761
|
---
|
|
734
762
|
|
|
735
763
|
## Phase 3: Finish
|
|
@@ -747,7 +775,9 @@ python3 ./.atw/scripts/tickets.py summary # every ticket done
|
|
|
747
775
|
git status --porcelain # clean tree; the chain commits as it goes
|
|
748
776
|
```
|
|
749
777
|
|
|
750
|
-
|
|
778
|
+
As each criterion checks out, tick its checkbox — in `prd.md` and in the ticket that carried it. Nobody earlier in the chain ticks them (`tickets.py done` flips `**Impl:**` only), so the ticks are the acceptance record, not new work. When every criterion has been walked, commit the ticks once — `chore(task): <task> acceptance check` — so the tree is clean before stop ④.
|
|
779
|
+
|
|
780
|
+
After a parallel whole-spec run (2.7) the work sits on the integration branch named in `task.json.branch`; a serial run (2.8) lands in place on the task branch. Say so in the report: merging it is the user's call, made after acceptance.
|
|
751
781
|
|
|
752
782
|
**Stop ④**: present that and wait. Whether the work is done is the user's judgement, not yours — you can report that every criterion is met, but you cannot accept on their behalf.
|
|
753
783
|
|
|
@@ -775,7 +805,7 @@ Edit the corresponding step's walkthrough body in the Phase 1 / 2 / 3 sections a
|
|
|
775
805
|
|
|
776
806
|
- No active task must triage first and ask for task-creation consent before creating an ATW task.
|
|
777
807
|
- Each of the four stops must stay reachable and must stay the user's call.
|
|
778
|
-
- Every execution path must keep review and spec update inside the run, never after it: before each ticket's commit on the per-ticket path, before the closing commit on the integration branch on the whole-spec path.
|
|
808
|
+
- Every execution path must keep review and spec update inside the run, never after it: before each ticket's commit on the per-ticket path and the serial whole-spec path, before the closing commit on the integration branch on the parallel whole-spec path.
|
|
779
809
|
|
|
780
810
|
Structure is guarded by `packages/cli/test/scripts/workflow-structure.test.ts`, which runs with `pnpm test` — there is no separate step to remember.
|
|
781
811
|
|
|
@@ -132,6 +132,24 @@ def read_file(path: Path, fallback: str = "") -> str:
|
|
|
132
132
|
return fallback
|
|
133
133
|
|
|
134
134
|
|
|
135
|
+
def _conventions_context(project_dir: Path) -> str:
|
|
136
|
+
"""The `<conventions>` block of a `general` project, else "".
|
|
137
|
+
|
|
138
|
+
A general project has one flat conventions file instead of per-package,
|
|
139
|
+
per-layer guideline indexes. An install whose scripts predate the helper is
|
|
140
|
+
treated as a dev project.
|
|
141
|
+
"""
|
|
142
|
+
scripts_dir = project_dir / ".atw" / "scripts"
|
|
143
|
+
if str(scripts_dir) not in sys.path:
|
|
144
|
+
sys.path.insert(0, str(scripts_dir))
|
|
145
|
+
try:
|
|
146
|
+
from common.session_context import conventions_context # type: ignore[import-not-found]
|
|
147
|
+
|
|
148
|
+
return conventions_context(project_dir)
|
|
149
|
+
except Exception:
|
|
150
|
+
return ""
|
|
151
|
+
|
|
152
|
+
|
|
135
153
|
def _resolve_context_key(project_dir: Path, hook_input: dict) -> str | None:
|
|
136
154
|
scripts_dir = project_dir / ".atw" / "scripts"
|
|
137
155
|
if str(scripts_dir) not in sys.path:
|
|
@@ -203,9 +221,20 @@ def _resolve_task_dir(atw_dir: Path, task_ref: str) -> Path:
|
|
|
203
221
|
return atw_dir / "tasks" / path_obj
|
|
204
222
|
|
|
205
223
|
|
|
206
|
-
def _get_task_status(atw_dir: Path, hook_input: dict) -> str:
|
|
224
|
+
def _get_task_status(atw_dir: Path, hook_input: dict, general: bool = False) -> str:
|
|
225
|
+
"""Compact active-task status and next action.
|
|
226
|
+
|
|
227
|
+
In a `general` project the AI decides on its own whether a request gets a
|
|
228
|
+
task, so the no-task line defers to the workflow instead of telling it to
|
|
229
|
+
ask first.
|
|
230
|
+
"""
|
|
207
231
|
active = _resolve_active_task(atw_dir, hook_input)
|
|
208
232
|
if not active.task_path:
|
|
233
|
+
if general:
|
|
234
|
+
return (
|
|
235
|
+
"Status: NO ACTIVE TASK\n"
|
|
236
|
+
"Next: Do what <atw-workflow> above says for a session with no current task."
|
|
237
|
+
)
|
|
209
238
|
return (
|
|
210
239
|
"Status: NO ACTIVE TASK\n"
|
|
211
240
|
"Next: Classify the current turn and ask for task-creation consent "
|
|
@@ -232,6 +261,13 @@ def _get_task_status(atw_dir: Path, hook_input: dict) -> str:
|
|
|
232
261
|
task_status = task_data.get("status", "unknown")
|
|
233
262
|
|
|
234
263
|
if task_status == "completed":
|
|
264
|
+
if general:
|
|
265
|
+
# general 的任务不记分支;在有远端的仓库里不带这个开关归档会被拒绝。
|
|
266
|
+
return (
|
|
267
|
+
f"Status: COMPLETED\nTask: {task_title}\n"
|
|
268
|
+
"Next: The archive was interrupted. Finish it with "
|
|
269
|
+
f"`python3 ./.atw/scripts/task.py archive {task_dir.name} --skip-branch-validation`."
|
|
270
|
+
)
|
|
235
271
|
return (
|
|
236
272
|
f"Status: COMPLETED\nTask: {task_title}\n"
|
|
237
273
|
f"Next: Archive with `python3 ./.atw/scripts/task.py archive {task_dir.name}` "
|
|
@@ -249,6 +285,12 @@ def _get_task_status(atw_dir: Path, hook_input: dict) -> str:
|
|
|
249
285
|
if not has_prd:
|
|
250
286
|
# 这条不以任务状态为门,任何阶段缺 prd.md 都会进——所以状态名要照实报,
|
|
251
287
|
# 不能像以前那样硬编码成一个词表里已经没有的阶段。
|
|
288
|
+
if general:
|
|
289
|
+
# general 不装头脑风暴技能,prd.md 由 AI 照流程自己写。
|
|
290
|
+
return (
|
|
291
|
+
f"Status: {task_status.upper()}\nTask: {task_title}\nPresent: {present_line}\n"
|
|
292
|
+
"Next: Write prd.md as <atw-workflow> above says before task.py start."
|
|
293
|
+
)
|
|
252
294
|
return (
|
|
253
295
|
f"Status: {task_status.upper()}\nTask: {task_title}\nPresent: {present_line}\n"
|
|
254
296
|
"Next: Load atw-brainstorm and write prd.md before task.py start."
|
|
@@ -281,6 +323,9 @@ def _run_git(repo_root: Path, args: list[str]) -> str:
|
|
|
281
323
|
|
|
282
324
|
|
|
283
325
|
def _format_git_state(repo_root: Path) -> str:
|
|
326
|
+
# 普通文件夹没有分支,也谈不上干净:照实说,不编一个状态出来。
|
|
327
|
+
if _run_git(repo_root, ["rev-parse", "--is-inside-work-tree"]) != "true":
|
|
328
|
+
return "Git: not a git repository."
|
|
284
329
|
branch = _run_git(repo_root, ["branch", "--show-current"]) or "(detached)"
|
|
285
330
|
dirty_lines = [
|
|
286
331
|
line for line in _run_git(repo_root, ["status", "--porcelain"]).splitlines()
|
|
@@ -453,7 +498,10 @@ def main() -> None:
|
|
|
453
498
|
configure_project_encoding(project_dir)
|
|
454
499
|
|
|
455
500
|
atw_dir = project_dir / ".atw"
|
|
456
|
-
|
|
501
|
+
# A general project keeps no guideline indexes — whatever a switch from dev
|
|
502
|
+
# left under `.atw/spec/` is not offered there.
|
|
503
|
+
conventions = _conventions_context(project_dir)
|
|
504
|
+
spec_index_paths = [] if conventions else _collect_spec_index_paths(atw_dir)
|
|
457
505
|
|
|
458
506
|
output = StringIO()
|
|
459
507
|
|
|
@@ -473,24 +521,27 @@ ATW compact SessionStart context. Use it to orient the session; load details on
|
|
|
473
521
|
output.write(_build_workflow_toc(atw_dir / "workflow.md"))
|
|
474
522
|
output.write("\n</atw-workflow>\n\n")
|
|
475
523
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
524
|
+
if conventions:
|
|
525
|
+
output.write(f"{conventions}\n\n")
|
|
526
|
+
else:
|
|
527
|
+
output.write("<guidelines>\n")
|
|
528
|
+
output.write(
|
|
529
|
+
"Task context order for implementation/check: jsonl entries -> `prd.md`.\n\n"
|
|
530
|
+
)
|
|
480
531
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
532
|
+
if spec_index_paths:
|
|
533
|
+
output.write("## Available indexes (read on demand)\n")
|
|
534
|
+
for p in spec_index_paths:
|
|
535
|
+
output.write(f"- {p}\n")
|
|
536
|
+
output.write("\n")
|
|
537
|
+
|
|
538
|
+
output.write(
|
|
539
|
+
"Discover more via: "
|
|
540
|
+
"`python3 ./.atw/scripts/get_context.py --mode packages`\n"
|
|
541
|
+
)
|
|
542
|
+
output.write("</guidelines>\n\n")
|
|
492
543
|
|
|
493
|
-
task_status = _get_task_status(atw_dir, hook_input)
|
|
544
|
+
task_status = _get_task_status(atw_dir, hook_input, general=bool(conventions))
|
|
494
545
|
output.write(f"<task-status>\n{task_status}\n</task-status>\n\n")
|
|
495
546
|
|
|
496
547
|
output.write("""<ready>
|
|
@@ -8,6 +8,14 @@ Implement the work described by the user in the spec or tickets.
|
|
|
8
8
|
|
|
9
9
|
If the user passes a ticket reference, fetch it from the issue tracker and state its title before starting. If the reference is ambiguous, ask. If the tracker already marks a different ticket as in progress, stop and say so — don't switch tickets on your own.
|
|
10
10
|
|
|
11
|
+
Then, before touching any code, read the ticket's `**Status:**` line. `ready-for-human` means the slicer decided a person should do this ticket. Stop there: say the ticket is marked for a human, quote the reason the ticket gives, and ask the user to pick one of two things — they do it themselves, or they explicitly authorize you to do it in their place.
|
|
12
|
+
|
|
13
|
+
- Nothing short of an explicit yes counts. A question back, a vague answer or silence is not authorization: ask once more, or end the run.
|
|
14
|
+
- They do it themselves: tell them to run `python3 .atw/scripts/tickets.py done NN` when finished and commit that ticket-state change, so the tree is clean for the next run. This run ends there and changes no file.
|
|
15
|
+
- They authorize you: continue with the chain below. The commit you make at the end of it carries one extra line — `ready-for-human ticket implemented by AI with the user's authorization` — followed by the gist of what the user said, so the record shows who decided.
|
|
16
|
+
|
|
17
|
+
A task without tickets, or a run with no ticket reference, has no `Status:` line and this step does not apply.
|
|
18
|
+
|
|
11
19
|
Call the Skill tool with "atw-tdd" where possible, at pre-agreed seams.
|
|
12
20
|
|
|
13
21
|
Run typechecking regularly, single test files regularly, and the full test suite once at the end.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: atw-implement-all
|
|
3
|
+
description: "把切好工单的规格一次串行做完:主会话当指挥者,按前沿逐张派出实现子代理,每张票在主会话里审查、处理发现、回写 spec、关单、提交状态;可选 --max N 干净停,停下后再跑同一条命令从断点续上。"
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You have been provided a spec sliced into tickets on an ATW task. This skill is the third way through stop ③: the user runs it once, and you — the main session — become the **orchestrator**. You work the ticket frontier one ticket at a time, dispatching one **implementer sub-agent** per ticket, and you run every ticket's review, findings, spec write-back, close-out and state commit yourself, in this session. It is the per-ticket `/atw-implement` chain with the "press start" removed — not the parallel `/atw-implement-spec` run: no worktrees, no integration branch, no merger, and a review per ticket instead of one at the end.
|
|
8
|
+
|
|
9
|
+
Only the user starts this skill. You never invoke it yourself.
|
|
10
|
+
|
|
11
|
+
This skill needs an ATW task directory (`.atw/scripts/tickets.py` exists). If it does not, tell the user to run `/atw-init-repo`.
|
|
12
|
+
|
|
13
|
+
## Before the first ticket
|
|
14
|
+
|
|
15
|
+
Check in this order, and stop with the named pointer when a check fails:
|
|
16
|
+
|
|
17
|
+
- The current task (`python3 .atw/scripts/task.py current`) is in the `implement` stage.
|
|
18
|
+
- The task has an `issues/` directory with tickets. A task with no tickets has only `/atw-implement`; tell the user to run that instead.
|
|
19
|
+
- When no ticket is at `**Impl:** doing`, the working tree is clean (`git status --porcelain` prints nothing). An uncommitted change belongs to nobody once implementers start committing; ask the user to commit or discard it first. With one ticket at `doing`, uncommitted changes are that ticket's breakpoint and are left for the resumed implementer (see "Resuming").
|
|
20
|
+
- The platform can dispatch sub-agents. On one that cannot, tell the user to run `/atw-implement` once per ticket.
|
|
21
|
+
- Either `tickets.py frontier` is non-empty, or exactly one ticket is at `**Impl:** doing` (see "Resuming"). Two or more at `doing` while the task's `meta.ticket_mode` is not `parallel` is a contradiction: stop and let the user sort it out; do not guess. Two or more at `doing` with `ticket_mode` set to `parallel` belong to a `/atw-implement-spec` run: stop and tell the user to finish or resume that run instead.
|
|
22
|
+
|
|
23
|
+
## Arguments
|
|
24
|
+
|
|
25
|
+
The only argument is an optional `--max N`: close N tickets in this run, then stop cleanly and report. Nothing else is accepted — not a ticket number, not `--only`, not `--skip`. If the user passes any of those, say so and stop; the ticket to work next is always chosen by the rule below.
|
|
26
|
+
|
|
27
|
+
## Your role
|
|
28
|
+
|
|
29
|
+
You are the only writer of ticket state. No sub-agent edits a ticket file, `check.jsonl`, `task.json`, or anything else the tracker owns.
|
|
30
|
+
|
|
31
|
+
You write no code, you do not edit ticket content, and you do not do the implementation in the implementer's place. The whole of your job is: pick, claim, dispatch, relay questions, review, triage, write back, close, commit state, report.
|
|
32
|
+
|
|
33
|
+
The `- [ ]` checkboxes in the tickets and in `prd.md` are not yours either, and not the implementer's: they are ticked during the acceptance check (workflow.md 3.1), one at a time against the evidence. `tickets.py done` flips `**Impl:**` and nothing else; leave the boxes as they are.
|
|
34
|
+
|
|
35
|
+
Communication to and from the implementer is sparse. Communicate through **context pointers** — to the spec, the one ticket, the research notes — and never paste their contents into the prompt.
|
|
36
|
+
|
|
37
|
+
## The loop
|
|
38
|
+
|
|
39
|
+
For each ticket:
|
|
40
|
+
|
|
41
|
+
1. **Pick.** Run `python3 .atw/scripts/tickets.py frontier`. Take the lowest-numbered ticket whose `**Status:**` line is not `ready-for-human`. If the frontier holds only `ready-for-human` tickets, stop (see "When the run halts"). Read the ticket file before dispatching: if it is plainly human work the ticket forgot to label — an external account, a manual test pass, a design decision — stop the same way rather than dispatching it.
|
|
42
|
+
|
|
43
|
+
2. **Claim.** `python3 .atw/scripts/tickets.py claim <NN>` — the plain serial claim, never `--parallel`. This writes the current-ticket line into `check.jsonl` and records `implementation_base_sha` on the task; the review step depends on both.
|
|
44
|
+
|
|
45
|
+
3. **Dispatch** one general-purpose implementer sub-agent in the foreground, with the brief below. Not the `atw-implement-agent` role, which may not commit.
|
|
46
|
+
|
|
47
|
+
4. **Handle the report.**
|
|
48
|
+
- It asks a question: ask the user, with your recommendation, then send the answer back to the same sub-agent and let it continue. On a platform that cannot continue a sub-agent, dispatch a fresh implementer with the answer added to the pointers.
|
|
49
|
+
- It reports the ticket cannot be finished as written: the whole run stops (see "When the run halts").
|
|
50
|
+
- It reports done with a commit: go on.
|
|
51
|
+
|
|
52
|
+
5. **Review.** Call the Skill tool with "atw-code-review", with the task's `implementation_base_sha` (`task.json` → `meta`) as the fixed point; when the implementer captured screenshots, pass their paths so the review runs its Visual axis. Relay every review report to the user as written — Standards and Spec, plus Visual when the ticket changed UI — even when the verdict is "nothing found". No report reaching you is not a passing review: re-run it.
|
|
53
|
+
|
|
54
|
+
6. **Triage** the findings by the table in workflow.md: spec-axis findings and standards-axis hard violations get fixed; judgement calls ship and are reported. Send the findings to fix back to the same implementer for one fix round that ends in a commit. Then re-check **only the findings that were fixed**, once. Do not start a second full review, and do not loop. Anything still open after that one re-check goes to the user — ship it, fix again, or change the spec — before you write the spec back.
|
|
55
|
+
|
|
56
|
+
7. **Write back and close.** Call the Skill tool with "atw-update-spec", then `python3 .atw/scripts/tickets.py done <NN>`, then commit the spec and ticket-state changes together. Every ticket leaves two kinds of commit on the branch: the implementer's code commit(s) and your state commit.
|
|
57
|
+
|
|
58
|
+
8. **Next.** If `--max N` was given and N tickets have been closed in this run, stop and report. Otherwise go back to step 1. When the frontier is empty and `tickets.py summary` shows every ticket `done`: `python3 .atw/scripts/task.py set-status <task-dir> accept`, then commit the `task.json` change as the run's last state commit, so the run ends on a clean tree. Then report; the task stage in the report is `accept`.
|
|
59
|
+
|
|
60
|
+
## Implementer brief
|
|
61
|
+
|
|
62
|
+
Every dispatch prompt starts with `Active task: <task path from task.py current>`, then states the role, then gives pointers and rules — nothing more:
|
|
63
|
+
|
|
64
|
+
- "You are an implementer sub-agent dispatched by `/atw-implement-all`. Stop ③ is already satisfied. Do the work yourself: do not dispatch sub-agents, and do not run a code review — the orchestrator reviews this ticket when you report."
|
|
65
|
+
- pointers to `prd.md`, this one ticket, `research/`, and the coding-standards files the review will hold the work to (the `check.jsonl` entries);
|
|
66
|
+
- work in place on the current branch — no worktree, no new branch;
|
|
67
|
+
- call the Skill tool with "atw-tdd" to build the ticket; build any part that changes what a user sees by calling the Skill tool with "atw-ui", and capture a screenshot into the task directory's `screenshots/` for each UI acceptance criterion (screen, state, viewport in the file name);
|
|
68
|
+
- run typechecking and single test files regularly, and the full suite once at the end;
|
|
69
|
+
- commit to the current branch yourself; do not hand a diff back;
|
|
70
|
+
- do not edit any ticket file or tracker state;
|
|
71
|
+
- make routine judgement calls yourself; stop and ask only when the ambiguity would change the result;
|
|
72
|
+
- if the ticket cannot be finished as written — the spec is wrong or self-contradictory, the fix needs a decision nobody has made, or it reaches outside this ticket's slice — stop and report why; do not widen the scope;
|
|
73
|
+
- report in under 200 words: what changed, test results, commit SHAs, screenshot paths if any, open questions.
|
|
74
|
+
|
|
75
|
+
A fix-round dispatch is the same brief plus the findings to fix, and ends in a commit the same way.
|
|
76
|
+
|
|
77
|
+
## Resuming
|
|
78
|
+
|
|
79
|
+
Stopping is always safe: every halt leaves the spec written back and the ticket state committed for every closed ticket, and the user resumes by running the same command again.
|
|
80
|
+
|
|
81
|
+
When the run starts with exactly one ticket at `**Impl:** doing`, that ticket is the breakpoint. Do not claim it again. Dispatch an implementer with the brief above plus the instruction to finish the ticket from the current git state and commit — untouched, it is implemented from scratch; changed but uncommitted, the work is finished and committed; already committed, there is nothing to do — then continue from step 4: the resumed implementer's report is handled like any other, and the review follows. The review's fixed point is the `implementation_base_sha` recorded at claim time, whichever way the earlier run broke off.
|
|
82
|
+
|
|
83
|
+
## When the run halts
|
|
84
|
+
|
|
85
|
+
The run comes back to the user in four situations, plus the `--max` count:
|
|
86
|
+
|
|
87
|
+
1. An implementer hits an ambiguity that would change the result → ask, with a recommendation, and continue after the answer.
|
|
88
|
+
2. A finding is still open after the one re-check → ask before writing the spec back, and continue after the answer.
|
|
89
|
+
3. An implementer reports its ticket cannot be finished as written → the run stops. Do not paper over it, do not rewrite the ticket to fit, do not widen the scope.
|
|
90
|
+
4. The frontier holds only `ready-for-human` tickets, or the next ticket is plainly human work → the run stops. Name the tickets that need the user, and say that the run continues once they are done with `/atw-implement`. Say also what the next run does: it starts from whatever state `/atw-implement` left — one ticket at `doing` (the per-ticket path may already have claimed the next frontier ticket) is resumed, not re-claimed (see "Resuming"); nothing at `doing` means the run claims from the frontier. Both ways in, the ticket is closed the same way: review, write-back, `done`, state commit.
|
|
91
|
+
5. `--max N` is reached → the run stops.
|
|
92
|
+
|
|
93
|
+
Every time the run halts — for a question in situations 1 and 2 as much as for a stop — and when it finishes, report one table with a row per ticket: number and title; state (`done`, `doing`, untouched); commit SHAs; review verdict per axis; what the user was asked. End with the task stage after the halt and the command that picks the run back up.
|
package/dist/templates/common/bundled-skills/atw-init-repo/references/issue-tracker-atw-local.md
CHANGED
|
@@ -36,7 +36,7 @@ On top of the standard ticket template, tickets here carry one extra line:
|
|
|
36
36
|
|
|
37
37
|
| Field | Vocabulary | Who writes it |
|
|
38
38
|
|---|---|---|
|
|
39
|
-
| `Status:` | triage roles (see `triage-labels.md`) |
|
|
39
|
+
| `Status:` | triage roles (see `triage-labels.md`) | The slicer, when it writes the ticket. Default `ready-for-agent`: these tickets are ones you sliced yourself, so they never go through triage. Set `ready-for-human` on a ticket a person must do — it needs an external account, a manual test pass, or a design or legal decision. `/atw-implement-all` never dispatches such a ticket and stops when the frontier holds only those; `/atw-implement` confirms with the user before touching code — they do it themselves, or explicitly authorize the AI. `tickets.py` does not read this field; the frontier ignores it. |
|
|
40
40
|
| `Impl:` | `ready` / `doing` / `done` | `tickets.py`. This is the field the workflow actually routes on, and the only field the parser requires. |
|
|
41
41
|
|
|
42
42
|
The ticket template `tickets.py` writes also carries an empty `**Issue:**` line. It is meaningless in this variant — nothing fills it in — and `tickets.py` never reads it. Leave it or delete it; neither breaks anything.
|
|
@@ -75,6 +75,8 @@ python3 .atw/scripts/tickets.py claim <NN> --parallel # → Impl: doing, alongs
|
|
|
75
75
|
|
|
76
76
|
**The one parallel path is `/atw-implement-spec`.** Its orchestrator claims with `--parallel`, which lets several tickets sit at `Impl: doing`, records `implementation_base_sha` once for the whole run, and writes no current-ticket line into `$TASK/check.jsonl` — there is no single live ticket. Only the orchestrator writes ticket state; each implementer works in its own worktree.
|
|
77
77
|
|
|
78
|
+
`/atw-implement-all` is not a second parallel path: its orchestrator claims with plain `claim <NN>`, one ticket at `Impl: doing` at a time, so the current-ticket line and `implementation_base_sha` are recorded per ticket exactly as on the per-ticket path. It too is the only writer of ticket state; its implementers work in place on the current branch.
|
|
79
|
+
|
|
78
80
|
## Wayfinding operations
|
|
79
81
|
|
|
80
82
|
Used by `atw-map`. A map is a **discover-phase** artifact and lives in the task directory alongside everything else.
|
|
@@ -44,7 +44,7 @@ On top of the standard ticket template, tickets here carry two extra lines:
|
|
|
44
44
|
|
|
45
45
|
| Field | Vocabulary | Who writes it |
|
|
46
46
|
|---|---|---|
|
|
47
|
-
| `Status:` | triage roles (see `triage-labels.md`) |
|
|
47
|
+
| `Status:` | triage roles (see `triage-labels.md`) | The slicer, when it writes the ticket. Default `ready-for-agent`: these tickets are ones you sliced yourself, so they never go through triage. Set `ready-for-human` on a ticket a person must do — it needs an external account, a manual test pass, or a design or legal decision. `/atw-implement-all` never dispatches such a ticket and stops when the frontier holds only those; `/atw-implement` confirms with the user before touching code — they do it themselves, or explicitly authorize the AI. `tickets.py` does not read this field; the frontier ignores it. |
|
|
48
48
|
| `Impl:` | `ready` / `doing` / `done` | `tickets.py`. This is the field the workflow actually routes on, and the only field the parser requires. |
|
|
49
49
|
| `Issue:` | `#58`, or empty | Filled in by `github_sync.py sync-tickets`; it is also the only ticket ↔ remote-issue mapping, so there is no separate mapping table. |
|
|
50
50
|
|
|
@@ -83,6 +83,8 @@ python3 .atw/scripts/tickets.py claim <NN> --parallel # → Impl: doing, alongs
|
|
|
83
83
|
|
|
84
84
|
**The one parallel path is `/atw-implement-spec`.** Its orchestrator claims with `--parallel`, which lets several tickets sit at `Impl: doing`, records `implementation_base_sha` once for the whole run, and writes no current-ticket line into `$TASK/check.jsonl` — there is no single live ticket. Only the orchestrator writes ticket state; each implementer works in its own worktree.
|
|
85
85
|
|
|
86
|
+
`/atw-implement-all` is not a second parallel path: its orchestrator claims with plain `claim <NN>`, one ticket at `Impl: doing` at a time, so the current-ticket line and `implementation_base_sha` are recorded per ticket exactly as on the per-ticket path. It too is the only writer of ticket state; its implementers work in place on the current branch.
|
|
87
|
+
|
|
86
88
|
## Wayfinding operations
|
|
87
89
|
|
|
88
90
|
Used by `atw-map`. A map is a **discover-phase** artifact and lives in the task directory alongside everything else.
|
|
@@ -7,18 +7,20 @@ description: "小白模式:给不懂技术的用户全程用大白话沟通—
|
|
|
7
7
|
|
|
8
8
|
The user is not an engineer. They are still the one in charge: they decide what gets built, what is good enough, and what must not happen. They can only do that when they understand what you tell them and what you are about to do. An update they cannot read leaves them able to approve your work but not to review it — and then your choices ship unexamined.
|
|
9
9
|
|
|
10
|
-
Noob mode keeps every reply, in every ATW stage, in language they can act on.
|
|
10
|
+
Noob mode keeps every reply, in every ATW stage, in language they can act on. In a `general` project it is on from the start; in a `dev` project it starts when it is switched on. Either way it lasts until the user switches it off.
|
|
11
11
|
|
|
12
12
|
## Switching
|
|
13
13
|
|
|
14
|
+
Each user is in one of three states: switched on, switched off, or never chose. On and off are the user's own choice and always win. A user who never chose gets the project's default — on in a `general` project, off in a `dev` one (a project whose `.atw/config.yaml` has no `mode` entry is `dev`).
|
|
15
|
+
|
|
14
16
|
The user's words or the argument decide the action. With neither, turn it on — unless you loaded this skill yourself because the `<noob-mode>` reminder told you to, which is "Already on" below.
|
|
15
17
|
|
|
16
18
|
- **On** — `/atw-noob-mode`, "开启小白模式", "turn on noob mode", or the user says they cannot follow the terms, an approval prompt, an error or command output. Run `python3 ./.atw/scripts/noob_mode.py on`, then confirm in the user's language, for example: "小白模式已开启。接下来我会用大白话说明我在做什么、需要你决定什么、有什么风险。随时可以说“关闭小白模式”。" Apply everything below from that reply on, then do the catch-up in "Catching up".
|
|
17
|
-
- **Off** — `/atw-noob-mode off`, "关闭小白模式", "turn off noob mode". Run `python3 ./.atw/scripts/noob_mode.py off`, confirm in one sentence, and stop applying these rules.
|
|
18
|
-
- **Status** — `python3 ./.atw/scripts/noob_mode.py status`.
|
|
19
|
+
- **Off** — `/atw-noob-mode off`, "关闭小白模式", "turn off noob mode". Run `python3 ./.atw/scripts/noob_mode.py off`, confirm in one sentence, and stop applying these rules. Off is recorded as the user's choice: the project default will not turn it back on, and neither will a change of project mode.
|
|
20
|
+
- **Status** — `python3 ./.atw/scripts/noob_mode.py status`. It prints whether the mode is on, and a `Source:` line saying whether that is the user's own setting or the project default.
|
|
19
21
|
- **Already on** — you loaded this skill yourself because the `<noob-mode>` reminder told you to. Nothing is being switched: run no script and announce nothing. Read on, and apply all of it starting with the reply you are about to write.
|
|
20
22
|
|
|
21
|
-
The
|
|
23
|
+
The choice is personal: it is a line in this user's own `.atw/.developer`, which is never committed, so teammates are unaffected. While it is on, ATW hands you a `<noob-mode>` reminder at session start and on every turn — that is what makes the mode last through long conversations and new sessions. The reminder carries only the core of these rules. When the text of this skill is not in front of you — a new session, or a long conversation that has been summarized — load it before you reply: the reminder alone leaves out most of what is here, limits included. If the script fails, tell the user plainly and still follow the rules for this conversation.
|
|
22
24
|
|
|
23
25
|
Never switch it off on your own, and never drift out of it because a stage is long or technical. Only the user ends it.
|
|
24
26
|
|
|
@@ -89,7 +91,7 @@ Noob mode changes how you talk to the user. It changes nothing about what the wo
|
|
|
89
91
|
|
|
90
92
|
- **Stages.** The first time a stage comes up, say in a few words what it is for — discover is "getting clear on what you want", specify is "writing it down so we both agree", slice is "cutting the work into small pieces", implement is "building it", accept is "checking it against what we agreed".
|
|
91
93
|
- **Stops ①–④.** These are the user's decisions. Say what is being decided, what each answer leads to, and what you recommend. Never present a stop as a formality.
|
|
92
|
-
- **Skills only the user can run.** When the next step is theirs to start (`/atw-spec`, `/atw-tickets`, `/atw-implement`, `/atw-implement-spec`, `/atw-askme`, `/atw-map`), say what typing it will do and why it is their call, then give the exact text to type.
|
|
94
|
+
- **Skills only the user can run.** When the next step is theirs to start (`/atw-spec`, `/atw-tickets`, `/atw-implement`, `/atw-implement-spec`, `/atw-implement-all`, `/atw-askme`, `/atw-map`), say what typing it will do and why it is their call, then give the exact text to type.
|
|
93
95
|
- **Asking them to confirm a file.** Do not hand over `prd.md` or a ticket list and ask "confirm?". Summarize in plain words what it commits to — what will be built, what will not, what counts as done — then point to the file.
|
|
94
96
|
- **Other skills' output.** A skill with its own format keeps it. In a file (review findings, ticket tables, a spec) the content stays as that skill wants it, and what you say about it to the user follows these rules. In the reply itself (a numbered round of questions, a list of findings) the shape stays and every word inside it follows these rules — a question the user cannot read is a decision they cannot make. No skill's format outranks noob mode.
|
|
95
97
|
|
|
@@ -67,6 +67,8 @@ Publish the approved tickets. **How** depends on the tracker this repo uses —
|
|
|
67
67
|
- **File-based trackers** → consult the tracker doc's "When a skill says publish to the issue tracker" section for the directory and naming convention; write one file per ticket, numbered from `01` in dependency order (blockers first). Each file's "Blocked by" lists the numbers/titles it depends on — always written in the file, even where a mirror also draws native edges on a remote tracker, because tooling reads the line. Use the per-ticket file template below — one ticket per file, never a single combined file. **If the tracker doc defines extra ticket fields, add them on top of the template.**
|
|
68
68
|
- **A real issue tracker (GitHub, Linear, …)** → publish one issue per ticket in dependency order (blockers first) so each ticket's blocking edges can reference real identifiers. Use the platform's native blocking relationship where it has one; otherwise set each ticket's "Blocked by" to the blocking issues. If the source was an existing issue, make each ticket its sub-issue (tracker doc's operation). Apply the `ready-for-agent` triage label unless instructed otherwise — the tickets are agent-grabbable by construction.
|
|
69
69
|
|
|
70
|
+
Mark a ticket a person must do — it needs an external account, a manual test pass, or a design or legal decision — as `ready-for-human` instead (the tracker doc's `Status:` line, or the triage label): `/atw-implement-all` will not dispatch it, and `/atw-implement` asks the user before doing it in their place.
|
|
71
|
+
|
|
70
72
|
Work the **frontier**: any ticket whose blockers are all done. For a purely linear chain that means top to bottom.
|
|
71
73
|
|
|
72
74
|
Do NOT close or modify any parent issue.
|
|
@@ -28,7 +28,7 @@ Shows the Phase Index (Plan / Execute / Finish) with routing + skill mapping.
|
|
|
28
28
|
- `status=specify` + no `prd.md` → **1.2** (`/atw-spec` turns the discover findings into `prd.md`)
|
|
29
29
|
- `status=specify` + `prd.md` exists → **1.3**. Sub-agent-dispatch platforms curate `check.jsonl` (empty, or only a legacy `_example` placeholder row, counts as uncurated); inline platforms skip. Then **stop ②** — the user confirms `prd.md` before anything advances. After that: `task.py set-status <task> slice` if the work needs tickets, otherwise straight to **1.5**.
|
|
30
30
|
- `status=slice` → **1.4** (`/atw-tickets`). Every ticket needs `**Impl:** ready` and a `**Blocked by:**` line. When they are written, run `task.py start <task>` (**1.5**).
|
|
31
|
-
- `status=implement` → **2.1**. `tickets.py frontier` → `tickets.py claim NN` (never two at `doing`) → **stop ③**: the user runs `/atw-implement`; you may not invoke it or inline the work → relay both review reports verbatim → `tickets.py done NN`. Frontier empty → `task.py set-status <task> accept`. When the task has tickets, also name the other
|
|
31
|
+
- `status=implement` → **2.1**. `tickets.py frontier` → `tickets.py claim NN` (never two at `doing`) → **stop ③**: the user runs `/atw-implement`; you may not invoke it or inline the work → relay both review reports verbatim → `tickets.py done NN`. Frontier empty → `task.py set-status <task> accept`. When the task has tickets, also name the other two ways through stop ③ — the user runs `/atw-implement-spec` once for the whole spec in parallel (**2.7**), or `/atw-implement-all` once for the whole spec serially, reviewed per ticket (**2.8**); several tickets at `doing` with `meta.ticket_mode = parallel` in `task.json` is an `/atw-implement-spec` run in progress, not a broken state, and one ticket at `doing` is where `/atw-implement-all` resumes.
|
|
32
32
|
- `status=accept` → **3.1**. Read-only: file anything you notice instead of fixing it. Walk the `prd.md` acceptance criteria with evidence, confirm `tickets.py summary` is all `done` and `git status --porcelain` is clean, then **stop ④** and wait for the user to accept. Once accepted, `task.py archive <task>` (**3.2**).
|
|
33
33
|
- `status=completed` on a task still under `.atw/tasks/` → **3.2, unfinished**. `task.py archive` writes `completed` first, then re-parents children, then moves the directory — and it does not roll back, so a task sitting here with this status means the archive was interrupted partway. Re-run `task.py archive <task>` to finish it: every step before the move is idempotent, so the re-run redoes them and completes the move.
|
|
34
34
|
|