@tacuchi/agent-workflow-cli 20.21.0 → 20.23.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 +17 -6
- package/dist/adapters/git-cli.js +42 -0
- package/dist/adapters/git-cli.js.map +1 -1
- package/dist/application/artifacts-service.js +5 -5
- package/dist/application/artifacts-service.js.map +1 -1
- package/dist/application/checkpoint-service.js +60 -55
- package/dist/application/checkpoint-service.js.map +1 -1
- package/dist/application/checkpoint-write-service.js +61 -66
- package/dist/application/checkpoint-write-service.js.map +1 -1
- package/dist/application/decisiones-service.js +5 -5
- package/dist/application/decisiones-service.js.map +1 -1
- package/dist/application/export-service.js +250 -0
- package/dist/application/export-service.js.map +1 -0
- package/dist/application/fix-git-service.js +244 -0
- package/dist/application/fix-git-service.js.map +1 -0
- package/dist/application/history-update-service.js +35 -24
- package/dist/application/history-update-service.js.map +1 -1
- package/dist/application/lifecycle-target.js +39 -0
- package/dist/application/lifecycle-target.js.map +1 -0
- package/dist/application/markdown.js +61 -16
- package/dist/application/markdown.js.map +1 -1
- package/dist/application/parsers/phases.js +38 -45
- package/dist/application/parsers/phases.js.map +1 -1
- package/dist/application/parsers/plan-status.js +75 -0
- package/dist/application/parsers/plan-status.js.map +1 -0
- package/dist/application/parsers/spec-relation.js +80 -0
- package/dist/application/parsers/spec-relation.js.map +1 -0
- package/dist/application/paths-service.js +8 -0
- package/dist/application/paths-service.js.map +1 -1
- package/dist/application/persist-service.js +285 -0
- package/dist/application/persist-service.js.map +1 -0
- package/dist/application/release-data/artifacts.js +17 -21
- package/dist/application/release-data/artifacts.js.map +1 -1
- package/dist/application/resume-service.js +184 -0
- package/dist/application/resume-service.js.map +1 -0
- package/dist/application/semantic-operation/protocol.js +247 -0
- package/dist/application/semantic-operation/protocol.js.map +1 -0
- package/dist/application/semantic-operation/publish.js +80 -0
- package/dist/application/semantic-operation/publish.js.map +1 -0
- package/dist/application/session-binding-service.js +125 -0
- package/dist/application/session-binding-service.js.map +1 -0
- package/dist/application/session-close-service.js +60 -39
- package/dist/application/session-close-service.js.map +1 -1
- package/dist/application/session-create-service.js +45 -19
- package/dist/application/session-create-service.js.map +1 -1
- package/dist/application/session-resolver.js +180 -44
- package/dist/application/session-resolver.js.map +1 -1
- package/dist/application/session-resume-service.js +39 -9
- package/dist/application/session-resume-service.js.map +1 -1
- package/dist/application/sessions-service.js +0 -2
- package/dist/application/sessions-service.js.map +1 -1
- package/dist/application/status-service.js +24 -352
- package/dist/application/status-service.js.map +1 -1
- package/dist/application/tasks-service.js +5 -5
- package/dist/application/tasks-service.js.map +1 -1
- package/dist/application/workline-index-service.js +510 -0
- package/dist/application/workline-index-service.js.map +1 -0
- package/dist/cli/commands/checkpoint-read.js +10 -6
- package/dist/cli/commands/checkpoint-read.js.map +1 -1
- package/dist/cli/commands/checkpoint-write.js +38 -11
- package/dist/cli/commands/checkpoint-write.js.map +1 -1
- package/dist/cli/commands/export.js +117 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/fix-git.js +109 -0
- package/dist/cli/commands/fix-git.js.map +1 -0
- package/dist/cli/commands/generate-launch.js +35 -3
- package/dist/cli/commands/generate-launch.js.map +1 -1
- package/dist/cli/commands/history-update.js +1 -1
- package/dist/cli/commands/history-update.js.map +1 -1
- package/dist/cli/commands/index.js +11 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/persist.js +67 -0
- package/dist/cli/commands/persist.js.map +1 -0
- package/dist/cli/commands/resume-summary.js +14 -3
- package/dist/cli/commands/resume-summary.js.map +1 -1
- package/dist/cli/commands/resume.js +73 -0
- package/dist/cli/commands/resume.js.map +1 -0
- package/dist/cli/commands/session-artifacts.js +12 -11
- package/dist/cli/commands/session-artifacts.js.map +1 -1
- package/dist/cli/commands/session-close.js +8 -7
- package/dist/cli/commands/session-close.js.map +1 -1
- package/dist/cli/commands/session-create.js +5 -1
- package/dist/cli/commands/session-create.js.map +1 -1
- package/dist/cli/commands/session-resume.js +16 -10
- package/dist/cli/commands/session-resume.js.map +1 -1
- package/dist/cli/commands/status.js +66 -2
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/workspace-init.js +21 -2
- package/dist/cli/commands/workspace-init.js.map +1 -1
- package/dist/cli/context-id.js +133 -0
- package/dist/cli/context-id.js.map +1 -0
- package/dist/cli/help-groups.js +16 -1
- package/dist/cli/help-groups.js.map +1 -1
- package/dist/cli/main.js +44 -16
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/output-mode.js +41 -0
- package/dist/cli/output-mode.js.map +1 -0
- package/dist/cli/parser.js +6 -0
- package/dist/cli/parser.js.map +1 -1
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli/render.js +53 -0
- package/dist/cli/render.js.map +1 -1
- package/package.json +1 -1
- package/skills/w/SKILL.md +3 -1
- package/skills/w/commands/export-diagrams.md +19 -10
- package/skills/w/commands/export-manuals.md +20 -10
- package/skills/w/commands/export-reports.md +20 -11
- package/skills/w/commands/export-scripts.md +20 -10
- package/skills/w/commands/fix-git.md +31 -12
- package/skills/w/commands/generate-launch.md +1 -1
- package/skills/w/commands/persist.md +33 -68
- package/skills/w/commands/plan-new.md +1 -1
- package/skills/w/commands/resume.md +25 -41
- package/skills/w/commands/spec-refine.md +12 -0
- package/skills/w/commands/status.md +12 -40
- package/skills/w/commands/workspace-init.md +3 -3
- package/skills/w/hooks/README.md +21 -2
- package/skills/w/hooks/hooks.template.json +2 -2
- package/skills/w/loops/README.md +5 -3
- package/skills/w/loops/plan-exec-loop/LOOP.md +10 -5
- package/skills/w/loops/plan-new-loop/LOOP.md +17 -8
- package/skills/w/loops/plan-refine-loop/LOOP.md +3 -1
- package/skills/w/loops/spec-refine-loop/LOOP.md +20 -7
- package/skills/w/roles/git/ROLE.md +7 -8
|
@@ -71,7 +71,9 @@ question that changed nothing, is NOT transcribed.
|
|
|
71
71
|
|
|
72
72
|
> **No gating contract** (unlike spec↔plan): the presence of `## Refinement decisions` in the plan is **audit trace only** — `plan-exec` neither requires nor checks it (it runs any plan). It serves to (a) distinguish a re-refined plan from a freshly generated one on resume, and (b) record what changed and why. *(Legacy plans may also carry `## Q&A traceability`; new runs never write it.)*
|
|
73
73
|
|
|
74
|
-
> **Execution updates progress; refinement changes structure.** `plan-exec` updates the plan's operational state in place — task checkboxes, the phase `> Estado:` line with its `> Bloqueo:` line while blocked, declared deferrals and the
|
|
74
|
+
> **Execution updates progress; refinement changes structure.** `plan-exec` updates the plan's operational state in place — task checkboxes, the phase `> Estado:` line with its `> Bloqueo:` line while blocked, declared deferrals and the plan's own status mark. It does **not** redesign contracts, phase shape or order, participating components, evidence or simulation boundaries: those structural changes are this loop's, and a change of functional behavior belongs to `spec-refine`.
|
|
75
|
+
|
|
76
|
+
> **Normalize on write, never invent.** A save through this loop leaves the document on the current contract. The plan-level `> Estado:` line sits under the title — `open`, unless execution already closed it, and then with the date and session on their own `> Cierre:` line. Each `### Fn` carries its required blocks, and **no conditional block is written empty**: a phase with no temporary behavior gets no `Límite de simulación`, one with nothing excluded gets no `Diferido`. Normalizing is a rewrite of form — it never changes a phase's state, never ticks a box, and never closes a plan.
|
|
75
77
|
|
|
76
78
|
## Delta 2 — Gap taxonomy (of "plan")
|
|
77
79
|
|
|
@@ -46,7 +46,9 @@ Closing *every* gap turns the spec into a premature plan. Close what changes **w
|
|
|
46
46
|
**Adopt, do not repeat.** `spec-new`'s **facts** are reused; its **assumptions** are re-validated **only when one blocks a gap**; its `Open questions` are re-classified by destination; its one-vs-many hypothesis is re-judged at the *Change-shape gate*. The shallow sweep is never re-run wholesale. Keep the labels distinct — a spec that blurs them cannot be gated: **fact** (backed by repo, data or docs) · **inference** (unproven) · **user decision** · **deferred decision** (owner declared) · **open question** (can still move the contract).
|
|
47
47
|
|
|
48
48
|
## Writes
|
|
49
|
-
Updates `docs/specs/NNN-spec-<slug>.md` **in place** (when the user picks `Guardar especificación refinada`): completes sections, **adds** `## Decisions`, closes `Open questions` as they get resolved, and stamps the frontmatter `status: ready-for-plan`. Since it overwrites an existing doc, it asks the user's **confirmation**.
|
|
49
|
+
Updates `docs/specs/NNN-spec-<slug>.md` **in place** (when the user picks `Guardar especificación refinada`): completes sections, **adds** `## Decisions`, closes `Open questions` as they get resolved, and stamps the frontmatter `status: ready-for-plan`. Since it overwrites an existing doc, it asks the user's **confirmation**.
|
|
50
|
+
|
|
51
|
+
> **Not every shape decision creates a file** (§ *Change-shape gate*). An accepted **split** writes the reduced original **and** the extracted sibling specs; a replacement by **`Crear una nueva spec`** writes one new file and leaves this one untouched; **`Reformular esta spec`** creates nothing — it edits this same file, same number, same path. Every write, new or overwriting, is confirmed first.
|
|
50
52
|
|
|
51
53
|
> **Boundary invariant:** this loop writes **only** into `docs/specs`. It never graduates/exports other artifacts to `docs/` — that is separate `export-*` work (chassis § *docs/ boundary*).
|
|
52
54
|
|
|
@@ -82,6 +84,8 @@ When the project already exists, establish the current behavior the change rests
|
|
|
82
84
|
|
|
83
85
|
Runs once the baseline exists and **before** closing details: the investigation can reveal the draft's shape was wrong. Does the spec still carry **one** functional outcome, did its purpose survive, can the delivery be accepted as a unit? The verdict is **one of three shapes** — `same` | `split` | `replace` — each with its own branch; only the last two ask anything.
|
|
84
86
|
|
|
87
|
+
> **Resolved before the gap loop starts, never carried into it (hard rule).** A `split` or a `replace` is asked, answered and applied **immediately** — its own structured-choice, in its own step, between the baseline and the first gap batch. It never travels in `pending_human`: that collection is rebuilt on every iteration and is reserved for questions about functional, technical or scope **gaps**, so a shape decision parked there is erased by the next batch — or never asked at all, because a spec with no blocking gap breaks out of the loop before the batch is built. The resolution lands in `CHECKPOINT` **before** anything else runs, so a resume re-enters with the shape already decided and never re-asks it.
|
|
88
|
+
|
|
85
89
|
- same outcome — more clarity, or more technical components → **`same`**: no shape question, keep refining this spec;
|
|
86
90
|
- independent functional outcomes discovered → **`split`** (below);
|
|
87
91
|
- purpose fundamentally changed → **`replace`** (below);
|
|
@@ -97,6 +101,8 @@ Runs once the baseline exists and **before** closing details: the investigation
|
|
|
97
101
|
- **New spec:** this one is **preserved**, its purpose never silently rewritten; the new one is minted with `aw next-number docs/specs`, born **`status: draft`**, its `## Origin` recording the origin spec, the replaced purpose and the user's decision. Its path goes to the `CHECKPOINT`; the run closes reporting `/w:spec-refine <new path>` as the next step.
|
|
98
102
|
- **Reformulate:** same number/path, the work treated as `refining` while rewritten; baseline, gap classification and the *ready-for-plan gate* run again over the new purpose; `status` is stamped only on the save that follows the passing gate, and the material decision lands in `## Decisions`.
|
|
99
103
|
|
|
104
|
+
**Every branch has a way out that changes nothing.** The `flow` control present on every structured-choice (chassis) is that exit here: `Cerrar` closes the run **without applying the shape change** — no sibling minted, no spec reformulated, the document untouched and the decision recorded in `CHECKPOINT` as declined. And no branch writes a file without the user's confirmation: minting siblings and minting a replacement both go through the same confirm-before-write rule as an in-place save.
|
|
105
|
+
|
|
100
106
|
Neither branch adds a `superseded` status or archives the replaced spec: a historical close needs its own runtime contract, out of scope here.
|
|
101
107
|
|
|
102
108
|
## Deliverable schema (the spec, edited in place)
|
|
@@ -193,15 +199,23 @@ spec-refine-loop(spec):
|
|
|
193
199
|
adopt(spec-new facts + assumptions + open questions + conversation) # never re-derive (§ Reads)
|
|
194
200
|
baseline = resolve_current_behavior(work) # inline research, ONLY what the change rests on
|
|
195
201
|
shape = change_shape_gate(work, baseline) # BEFORE closing details → same | split | replace
|
|
196
|
-
if shape
|
|
197
|
-
|
|
202
|
+
if shape != same: # RESOLVED HERE — never queued into pending_human
|
|
203
|
+
ans = structured_choice(content: [the offer of THIS branch], # split and replace never share labels
|
|
204
|
+
flow: [Compactar, Cerrar])
|
|
205
|
+
write CHECKPOINT (the decision + its consequence) # BEFORE acting: a resume re-enters already decided
|
|
206
|
+
flow Cerrar → goto finalize # closed without applying the change; the spec stays untouched
|
|
207
|
+
`Una sola spec` → shape resolved as same; keep refining this spec
|
|
208
|
+
`Dividir en varias specs` → the accepted cut is fixed now; its writes wait for `Guardar specs`
|
|
209
|
+
`Crear una nueva spec` → mint draft with confirmation (## Origin) ; THIS spec untouched ;
|
|
210
|
+
CHECKPOINT.Next = refine it ; goto finalize
|
|
211
|
+
`Reformular esta spec` → same number/path ; re-run baseline + this gate before any stamp
|
|
198
212
|
attempts = {} # anti re-fire per gap
|
|
199
213
|
repeat:
|
|
200
214
|
gaps = classify_by_destination(detect_gaps(work)) minus the "exhausted" gaps
|
|
201
215
|
record(gaps.plan_owned + gaps.deferrable) → ## Open questions with destination # never closed here
|
|
202
216
|
blocking = gaps.spec_blocking
|
|
203
217
|
if blocking == ∅: break
|
|
204
|
-
batch = top ≤3 blocking ; pending_human = []
|
|
218
|
+
batch = top ≤3 blocking ; pending_human = [] # gap questions ONLY — the shape was resolved above
|
|
205
219
|
seed CHECKPOINT.Pending/Next = batch (refine_session) # BEFORE: seed the intent (artifact-first)
|
|
206
220
|
for each gap in batch:
|
|
207
221
|
if gap = UI (requirement involves UI, ## UI spec missing):
|
|
@@ -222,9 +236,7 @@ spec-refine-loop(spec):
|
|
|
222
236
|
switch(flow):
|
|
223
237
|
Compactar → write CHECKPOINT (refine_session) ; compact(harness) ; continue
|
|
224
238
|
Cerrar → goto finalize
|
|
225
|
-
work = integrate(work, ans) # → Decisions / Open questions
|
|
226
|
-
accepted `Crear una nueva spec` → mint draft (## Origin) ; this one untouched ; CHECKPOINT.Next = refine it ; goto finalize
|
|
227
|
-
accepted `Reformular esta spec` → same number/path ; re-run baseline + gaps + ready-for-plan gate before any stamp
|
|
239
|
+
work = integrate(work, ans) # → Decisions / Open questions
|
|
228
240
|
ideation offer accepted → run the round NOW, then its verdicts as a NEW ≤3+flow batch (§ Ideation gate)
|
|
229
241
|
ideation offer declined → mark that gap exhausted # anti re-fire; on-demand entry stays open
|
|
230
242
|
# no BLOCKING gaps → ready-for-plan gate = Success criteria green (read-only) before offering Guardar:
|
|
@@ -247,6 +259,7 @@ finalize:
|
|
|
247
259
|
Full mechanism (3 cases, `Compactar`, re-run on demand with `--reopen`) in the chassis (§ *Compact / resume*). SPEC keys:
|
|
248
260
|
|
|
249
261
|
- The **prior-work mark** is the frontmatter `status: ready-for-plan` (legacy specs: `## Refinement decisions`, older ones also `## Q&A traceability`).
|
|
262
|
+
- The **shape decision survives a resume.** It is written to `CHECKPOINT` the moment it is taken, before anything acts on it, so a compact, a `Cerrar` or a crash between the gate and the save re-enters with the shape settled — the gate is not re-run and the question is not re-asked. Only a *new* run over a spec whose baseline changed re-opens it.
|
|
250
263
|
- Re-refining on demand is a **first-class operation** while the flow stays in SPEC (new requirements, scope changes, after re-reading the spec): it always reads the **spec itself**, incremental re-refinement; on `Guardar`, edits in place with confirmation.
|
|
251
264
|
- **Legacy migration happens only here.** A re-refined legacy spec runs the gate like any other; on `Guardar`, its `## Refinement decisions` is renamed `## Decisions` and pruned to the material decisions — **in the same write that stamps `status`**, so the spec is never left with no mark. Specs nobody re-refines are not migrated.
|
|
252
265
|
- **`Cerrar` before converging leaves the spec untouched**: the progress lives in the `CHECKPOINT`, and `status` is neither invented nor downgraded. `refining` is understood **on read** (a hand-written spec may declare it) — this loop never writes a partial spec.
|
|
@@ -97,14 +97,13 @@ Outside an active session: relax to "1 line + no co-author"; the `session<NNN>`
|
|
|
97
97
|
|
|
98
98
|
Autonomous `git merge` is forbidden (above), **but** resolving an **in-progress** merge (MERGE_HEAD), or one invoked by the user via `/w:fix-git`, **is** sanctioned work. **Workspace-agnostic**: it operates on any repo (no `.workflow/`, flows or sessions required).
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
5. **Proposed commit**: completing the merge is a `git commit` (the merge commit) → **propose-then-execute** like any commit (canonical format above; outside a session → 1 line without the `session<NNN>` tag; never `--no-verify`/`--amend`/`push`). The `git-commit-advisor` hook gates it.
|
|
100
|
+
**The mechanics live in the CLI** (`aw fix-git prepare | apply | commit`); what follows is the reasoning it expects from you. Never edit a conflicted file, `git add` or `git commit` by hand here — see [`../../commands/fix-git.md`](../../commands/fix-git.md) for the exact invocations.
|
|
101
|
+
|
|
102
|
+
1. **Detect + identify**: `aw fix-git prepare` (read-only) returns the merge direction (**theirs → ours**), the conflicted paths and, per path, its three index stages with their blob hashes. `aw merge-state` remains the lighter inspector when you only need the state.
|
|
103
|
+
2. **Analyze each conflict's intent** **before** resolving — never pick a side blindly. The request already carries the three versions: `base` (common ancestor), `ours` (destination) and `theirs` (origin). Add `git log --merge -p -- <file>` when the *why* of a hunk is not evident, and read the surrounding code for coherence.
|
|
104
|
+
3. **Resolve** by composing the complete resolved file: pick **ours**, **theirs**, **combine** both intents, or **rewrite** to satisfy both — with no `<<<<<<<` / `=======` / `>>>>>>>` left. The CLI writes and stages it; a leftover marker is rejected, and so is a path that is no longer in conflict.
|
|
105
|
+
4. **Ask** (*structured-choice*) when the intent is **ambiguous** or both sides are **incoherent** with each other (not combinable without losing something): answer `state: "ambiguous"` so nothing is written, then ask one content question per doubtful file/hunk (≤3 + `flow` control), options "Ours (`<destination>`)" / "Theirs (`<origin>`)" / "Combine" / "Edit manually". **Never invent** a resolution under real doubt. A **binary** conflict is never resolved automatically: propose `git checkout --ours|--theirs`.
|
|
106
|
+
5. **Proposed commit**: completing the merge is a `git commit` (the merge commit) → **propose-then-execute** like any commit (canonical format above; outside a session → 1 line without the `session<NNN>` tag; never `--no-verify`/`--amend`/`push`). It is a **separate, confirmed** invocation — `aw fix-git commit --message "<msg>" --confirm` — which refuses while any file stays unmerged. The `git-commit-advisor` hook gates it.
|
|
108
107
|
6. **Escape hatch**: if the merge must not complete, `git merge --abort` **after user confirmation** (*structured-choice*) — leaves the repo as before the merge.
|
|
109
108
|
|
|
110
109
|
> **Resume via git**: the merge state in `.git` (MERGE_HEAD + index) **is** the checkpoint; re-running `/w:fix-git` resumes from the remaining conflicts. No session, no artifact.
|