@open-agent-toolkit/cli 0.2.62 → 0.2.64
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/assets/bundle-metadata.json +1 -1
- package/assets/docs/cli-utilities/config-and-local-state.md +1 -0
- package/assets/docs/cli-utilities/configuration.md +10 -8
- package/assets/docs/cli-utilities/project-log.md +16 -0
- package/assets/docs/cli-utilities/tool-packs.md +83 -0
- package/assets/docs/cli-utilities/workflow-gates.md +124 -16
- package/assets/docs/contributing/skills.md +42 -7
- package/assets/docs/provider-sync/commands.md +3 -0
- package/assets/docs/provider-sync/instruction-sync.md +107 -0
- package/assets/docs/provider-sync/manifest-and-drift.md +105 -0
- package/assets/docs/reference/cli-reference.md +16 -6
- package/assets/docs/reference/oat-directory-structure.md +32 -31
- package/assets/docs/workflows/projects/lifecycle.md +45 -0
- package/assets/docs/workflows/projects/picking-up-projects.md +14 -0
- package/assets/docs/workflows/skills/explainer-kit.md +10 -4
- package/assets/docs/workflows/skills/repo-improve.md +15 -1
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/create-agnostic-skill/SKILL.md +9 -7
- package/assets/skills/create-agnostic-skill/references/skill-template.md +9 -7
- package/assets/skills/oat-explainer-kit/SKILL.md +14 -1
- package/assets/skills/oat-explainer-kit/references/config-contract.md +12 -0
- package/assets/skills/oat-explainer-kit/references/lifecycle-contract.md +57 -10
- package/assets/skills/oat-explainer-kit/scripts/check-terminal-outcome.mjs +28 -5
- package/assets/skills/oat-explainer-kit/scripts/probe-recap-seams.mjs +371 -0
- package/assets/skills/oat-explainer-kit/scripts/resolve-intent.mjs +123 -1
- package/assets/skills/oat-project-autonomous/SKILL.md +10 -1
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +122 -121
- package/assets/skills/oat-project-complete/SKILL.md +134 -4
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +122 -121
- package/assets/skills/oat-project-implement/SKILL.md +1 -1
- package/assets/skills/oat-project-implement/references/completion-and-closeout.md +38 -6
- package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +122 -121
- package/assets/skills/oat-project-lite/references/docs/autonomy-contract.md +122 -121
- package/assets/skills/oat-project-next/SKILL.md +62 -19
- package/assets/skills/oat-project-plan/SKILL.md +31 -5
- package/assets/skills/oat-project-pr-final/SKILL.md +281 -6
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +122 -121
- package/assets/skills/oat-project-progress/SKILL.md +12 -3
- package/assets/skills/oat-project-quick-start/SKILL.md +264 -4
- package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +122 -121
- package/assets/skills/oat-project-summary/SKILL.md +34 -23
- package/assets/skills/oat-repo-improve/SKILL.md +40 -5
- package/assets/skills/oat-repo-improve/references/plan-template.md +84 -7
- package/dist/agents/canonical/resolve.d.ts.map +1 -1
- package/dist/agents/canonical/resolve.js +25 -4
- package/dist/commands/config/index.d.ts +1 -0
- package/dist/commands/config/index.d.ts.map +1 -1
- package/dist/commands/config/index.js +401 -18
- package/dist/commands/doctor/index.d.ts +7 -0
- package/dist/commands/doctor/index.d.ts.map +1 -1
- package/dist/commands/doctor/index.js +10 -2
- package/dist/commands/gate/index.d.ts +3 -1
- package/dist/commands/gate/index.d.ts.map +1 -1
- package/dist/commands/gate/index.js +699 -211
- package/dist/commands/init/tools/index.d.ts.map +1 -1
- package/dist/commands/init/tools/index.js +68 -36
- package/dist/commands/init/tools/shared/skill-script-references.d.ts +126 -0
- package/dist/commands/init/tools/shared/skill-script-references.d.ts.map +1 -0
- package/dist/commands/init/tools/shared/skill-script-references.js +311 -0
- package/dist/commands/instructions/instructions.types.d.ts +63 -0
- package/dist/commands/instructions/instructions.types.d.ts.map +1 -1
- package/dist/commands/instructions/instructions.utils.d.ts +51 -2
- package/dist/commands/instructions/instructions.utils.d.ts.map +1 -1
- package/dist/commands/instructions/instructions.utils.js +201 -4
- package/dist/commands/instructions/sync/sync.d.ts.map +1 -1
- package/dist/commands/instructions/sync/sync.js +12 -1
- package/dist/commands/instructions/validate/validate.d.ts.map +1 -1
- package/dist/commands/instructions/validate/validate.js +12 -1
- package/dist/commands/project/log/append.d.ts +195 -0
- package/dist/commands/project/log/append.d.ts.map +1 -1
- package/dist/commands/project/log/append.js +1034 -11
- package/dist/commands/shared/frontmatter.d.ts +51 -0
- package/dist/commands/shared/frontmatter.d.ts.map +1 -1
- package/dist/commands/shared/frontmatter.js +118 -6
- package/dist/commands/status/index.d.ts.map +1 -1
- package/dist/commands/status/index.js +5 -3
- package/dist/commands/sync/index.d.ts +14 -0
- package/dist/commands/sync/index.d.ts.map +1 -1
- package/dist/commands/sync/index.js +21 -0
- package/dist/commands/tools/info/index.d.ts.map +1 -1
- package/dist/commands/tools/info/index.js +14 -1
- package/dist/commands/tools/info/info-tool.d.ts +12 -0
- package/dist/commands/tools/info/info-tool.d.ts.map +1 -1
- package/dist/commands/tools/info/info-tool.js +54 -6
- package/dist/commands/tools/info/skill-views.d.ts +86 -0
- package/dist/commands/tools/info/skill-views.d.ts.map +1 -0
- package/dist/commands/tools/info/skill-views.js +383 -0
- package/dist/commands/tools/install/index.d.ts.map +1 -1
- package/dist/commands/tools/install/index.js +3 -25
- package/dist/commands/tools/list/list-tools.d.ts +2 -0
- package/dist/commands/tools/list/list-tools.d.ts.map +1 -1
- package/dist/commands/tools/list/list-tools.js +23 -4
- package/dist/commands/tools/remove/index.d.ts.map +1 -1
- package/dist/commands/tools/remove/index.js +35 -42
- package/dist/commands/tools/remove/remove-tools.d.ts +3 -2
- package/dist/commands/tools/remove/remove-tools.d.ts.map +1 -1
- package/dist/commands/tools/remove/remove-tools.js +14 -4
- package/dist/commands/tools/shared/auto-sync.d.ts +12 -1
- package/dist/commands/tools/shared/auto-sync.d.ts.map +1 -1
- package/dist/commands/tools/shared/auto-sync.js +20 -4
- package/dist/commands/tools/shared/format-pack-inventory.d.ts +12 -1
- package/dist/commands/tools/shared/format-pack-inventory.d.ts.map +1 -1
- package/dist/commands/tools/shared/format-pack-inventory.js +48 -6
- package/dist/commands/tools/shared/in-process-sync.d.ts +11 -0
- package/dist/commands/tools/shared/in-process-sync.d.ts.map +1 -0
- package/dist/commands/tools/shared/in-process-sync.js +79 -0
- package/dist/commands/tools/shared/pack-evidence.d.ts +78 -2
- package/dist/commands/tools/shared/pack-evidence.d.ts.map +1 -1
- package/dist/commands/tools/shared/pack-evidence.js +96 -2
- package/dist/commands/tools/shared/pack-lifecycle-outcome.d.ts +11 -0
- package/dist/commands/tools/shared/pack-lifecycle-outcome.d.ts.map +1 -1
- package/dist/commands/tools/shared/pack-lifecycle-outcome.js +24 -3
- package/dist/commands/tools/shared/pack-provider-evidence.d.ts +73 -0
- package/dist/commands/tools/shared/pack-provider-evidence.d.ts.map +1 -0
- package/dist/commands/tools/shared/pack-provider-evidence.js +161 -0
- package/dist/commands/tools/shared/provider-context.d.ts +88 -0
- package/dist/commands/tools/shared/provider-context.d.ts.map +1 -0
- package/dist/commands/tools/shared/provider-context.js +77 -0
- package/dist/commands/tools/shared/provider-reachability.d.ts +93 -0
- package/dist/commands/tools/shared/provider-reachability.d.ts.map +1 -0
- package/dist/commands/tools/shared/provider-reachability.js +358 -0
- package/dist/commands/tools/shared/sync-evidence.d.ts +57 -0
- package/dist/commands/tools/shared/sync-evidence.d.ts.map +1 -0
- package/dist/commands/tools/shared/sync-evidence.js +147 -0
- package/dist/commands/tools/update/index.d.ts +0 -4
- package/dist/commands/tools/update/index.d.ts.map +1 -1
- package/dist/commands/tools/update/index.js +22 -40
- package/dist/commands/tools/update/update-tools.d.ts.map +1 -1
- package/dist/commands/tools/update/update-tools.js +23 -8
- package/dist/config/json.d.ts +36 -0
- package/dist/config/json.d.ts.map +1 -1
- package/dist/config/json.js +135 -3
- package/dist/config/oat-config.d.ts +41 -0
- package/dist/config/oat-config.d.ts.map +1 -1
- package/dist/config/oat-config.js +111 -0
- package/dist/drift/index.d.ts +2 -0
- package/dist/drift/index.d.ts.map +1 -1
- package/dist/drift/index.js +1 -0
- package/dist/drift/skill-view-diagnostic.d.ts +197 -0
- package/dist/drift/skill-view-diagnostic.d.ts.map +1 -0
- package/dist/drift/skill-view-diagnostic.js +343 -0
- package/dist/validation/skills.d.ts +1 -0
- package/dist/validation/skills.d.ts.map +1 -1
- package/dist/validation/skills.js +181 -19
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: oat-project-progress
|
|
3
|
-
version: 1.4.
|
|
3
|
+
version: 1.4.1
|
|
4
4
|
description: Use when the user explicitly asks to check OAT project progress — e.g. "check progress", "what's next", "where are we", or confirms a previously offered progress check. Do NOT auto-invoke just because a workflow step completed. Reads project status and offers the next route.
|
|
5
5
|
disable-model-invocation: false
|
|
6
6
|
user-invocable: true
|
|
@@ -276,12 +276,21 @@ Routing matrix by mode:
|
|
|
276
276
|
| --------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
|
277
277
|
| discovery | in_progress | Continue `oat-project-discover` |
|
|
278
278
|
| discovery | complete | `oat-project-plan` |
|
|
279
|
-
| plan | in_progress | Continue `oat-project-plan`
|
|
280
|
-
| plan | complete | `oat-project-implement`
|
|
279
|
+
| plan | in_progress | Continue `oat-project-quick-start` when the plan is not implementation-ready; otherwise `oat-project-implement` |
|
|
280
|
+
| plan | complete | `oat-project-implement` when the plan is implementation-ready; otherwise `oat-project-quick-start` |
|
|
281
281
|
| implement | in_progress | Continue `oat-project-implement`. If drift detected (see drift detection above), also mention `oat-project-reconcile` as an option. |
|
|
282
282
|
| implement | complete | Ready for final review / PR |
|
|
283
283
|
| implement | pr_open | `oat-project-complete` |
|
|
284
284
|
|
|
285
|
+
**Quick plan readiness.** "Implementation-ready" in the two `plan` rows above is
|
|
286
|
+
the named **quick plan readiness** predicate, defined once beside Step 3.7 of the
|
|
287
|
+
quick workflow. Load `oat-project-quick-start/SKILL.md` and apply that predicate
|
|
288
|
+
as written to `{PROJECT_PATH}/plan.md`; do not restate or re-derive its
|
|
289
|
+
conditions here, and never read the presence of substantive tasks as readiness on
|
|
290
|
+
its own. A not-ready quick plan is not a dead end and does not need spec-driven
|
|
291
|
+
planning: load `oat-project-quick-start/SKILL.md` and follow its Step 0.5 resume
|
|
292
|
+
branch, which finishes the plan in place without re-scaffolding the project.
|
|
293
|
+
|
|
285
294
|
**Import mode (`oat_workflow_mode: import`):**
|
|
286
295
|
|
|
287
296
|
| oat_phase | oat_phase_status | Next Skill |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: oat-project-quick-start
|
|
3
|
-
version: 2.3.
|
|
3
|
+
version: 2.3.10
|
|
4
4
|
description: Use when a task is small enough for quick mode or rapid iteration is preferred. Scaffolds a lightweight OAT project from discovery directly to a runnable plan, with optional brainstorming and lightweight design.
|
|
5
5
|
argument-hint: '<project-name> ["project description"]'
|
|
6
6
|
oat_gateable: true
|
|
@@ -125,6 +125,26 @@ PROJECTS_ROOT="${OAT_PROJECTS_ROOT:-$(oat config get projects.root 2>/dev/null |
|
|
|
125
125
|
PROJECTS_ROOT="${PROJECTS_ROOT%/}"
|
|
126
126
|
```
|
|
127
127
|
|
|
128
|
+
**Resume in place (existing incomplete quick project).** When `PROJECT_PATH`
|
|
129
|
+
resolves to an existing project whose `state.md` records
|
|
130
|
+
`oat_workflow_mode: quick`, this skill resumes that project and never
|
|
131
|
+
re-scaffolds it: `oat project new` is not re-run, and `discovery.md`,
|
|
132
|
+
`design.md`, and any existing `plan.md` content are preserved as they stand.
|
|
133
|
+
Evaluate **quick plan readiness** — the named predicate defined below, beside
|
|
134
|
+
Step 3.7 — against `"$PROJECT_PATH/plan.md"`:
|
|
135
|
+
|
|
136
|
+
- Not ready → re-enter this skill's own steps from the earliest one whose
|
|
137
|
+
output is missing or still pre-review, and carry on through Step 3.7 so the
|
|
138
|
+
plan reaches a durable review disposition. This is the in-place resume branch
|
|
139
|
+
that the lifecycle routers send a not-ready quick project to; nothing is
|
|
140
|
+
re-scaffolded and no artifact is overwritten from a template. On this path
|
|
141
|
+
Step 3 updates the existing `plan.md` in place: it reads `.oat/templates/plan.md`
|
|
142
|
+
only when `plan.md` is missing, re-asserts the Step 3 pre-review frontmatter
|
|
143
|
+
values, and never replaces phases, tasks, or `## Reviews` rows that the
|
|
144
|
+
earlier run already wrote.
|
|
145
|
+
- Ready → there is nothing left to author here; load
|
|
146
|
+
`oat-project-implement/SKILL.md` and follow it to begin execution.
|
|
147
|
+
|
|
128
148
|
If no valid active project exists:
|
|
129
149
|
|
|
130
150
|
- Resolve startup input from `$ARGUMENTS` before doing any discovery work:
|
|
@@ -132,10 +152,41 @@ If no valid active project exists:
|
|
|
132
152
|
- If `$ARGUMENTS` contains only a bare `{project-name}` (for example a slug or short title) without a substantive description, ask the user for a short project description before scanning the repo or drafting discovery.
|
|
133
153
|
- Do not infer requirements from the project name alone or go exploring the codebase to guess what the project means.
|
|
134
154
|
- If neither field is available, ask for both the project name and a short project description. One or two sentences is enough for the description.
|
|
135
|
-
- Create project via the same scaffolding path used by `oat-project-new
|
|
155
|
+
- Create project via the same scaffolding path used by `oat-project-new`, then
|
|
156
|
+
re-resolve `PROJECT_PATH` from the path the scaffold reports:
|
|
136
157
|
|
|
137
158
|
```bash
|
|
138
|
-
oat project new "{project-name}" --mode quick
|
|
159
|
+
SCAFFOLD=$(oat project new "{project-name}" --mode quick --json) || SCAFFOLD=''
|
|
160
|
+
# Report what the scaffolder said, so a `commitStatus` of anything but
|
|
161
|
+
# `committed`, and its `commitError`, stay as visible as they were before this
|
|
162
|
+
# branch started capturing the output.
|
|
163
|
+
printf '%s\n' "$SCAFFOLD"
|
|
164
|
+
# Scaffolding creates the project directory and repoints `activeProject`, so
|
|
165
|
+
# the Step 0.5 value of PROJECT_PATH is stale from here on. Left unresolved it
|
|
166
|
+
# still names whatever project was active before this run -- sending the Step 1
|
|
167
|
+
# and consolidation writes into a project this run is retiring -- or is empty,
|
|
168
|
+
# which makes "$PROJECT_PATH/state.md" the absolute path /state.md. Re-resolve
|
|
169
|
+
# from the report the scaffolder just made.
|
|
170
|
+
SCAFFOLD_STATUS=$(printf '%s\n' "$SCAFFOLD" |
|
|
171
|
+
sed -n 's/.*"status"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' |
|
|
172
|
+
head -1)
|
|
173
|
+
PROJECT_PATH=$(printf '%s\n' "$SCAFFOLD" |
|
|
174
|
+
sed -n 's/.*"projectPath"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' |
|
|
175
|
+
head -1)
|
|
176
|
+
# Only a reported success may fall back to the pointer the scaffolder set. A
|
|
177
|
+
# failed scaffold reports no path and leaves the old pointer untouched, so an
|
|
178
|
+
# unconditional fallback would resolve straight back to the stale project and
|
|
179
|
+
# pass the check below on that project state.md.
|
|
180
|
+
if [ "$SCAFFOLD_STATUS" = "ok" ] && [ -z "$PROJECT_PATH" ]; then
|
|
181
|
+
PROJECT_PATH=$(oat config get activeProject 2>/dev/null || true)
|
|
182
|
+
fi
|
|
183
|
+
# Validate before anything writes. A failed scaffold, an unresolved path, or a
|
|
184
|
+
# path with no state.md stops the run; it never silently writes somewhere else.
|
|
185
|
+
if [ "$SCAFFOLD_STATUS" != "ok" ] || [ -z "$PROJECT_PATH" ] ||
|
|
186
|
+
[ ! -f "$PROJECT_PATH/state.md" ]; then
|
|
187
|
+
printf 'quick-start: scaffolding did not yield a project path with state.md\n' >&2
|
|
188
|
+
exit 1
|
|
189
|
+
fi
|
|
139
190
|
```
|
|
140
191
|
|
|
141
192
|
This guarantees:
|
|
@@ -143,10 +194,34 @@ This guarantees:
|
|
|
143
194
|
- standard artifact scaffolding from `.oat/templates/`
|
|
144
195
|
- `activeProject` update in `.oat/config.local.json`
|
|
145
196
|
- repo dashboard refresh (`.oat/state.md`) via existing scaffolder behavior
|
|
197
|
+
- a `PROJECT_PATH` that names the project this run just created, validated
|
|
198
|
+
before Step 1 and before the consolidation write below
|
|
199
|
+
|
|
200
|
+
**Consolidating earlier scaffolds.** When this project absorbs work that earlier
|
|
201
|
+
project scaffolds already started — those directories are being retired into
|
|
202
|
+
this one rather than continued — record what was absorbed in
|
|
203
|
+
`"$PROJECT_PATH/state.md"` frontmatter as part of the same Step 1 frontmatter
|
|
204
|
+
write, so this branch adds fields to that single write rather than performing
|
|
205
|
+
its own. `PROJECT_PATH` here is the re-resolved, validated path above, never the
|
|
206
|
+
pre-scaffold value:
|
|
207
|
+
|
|
208
|
+
- `absorbed_projects: [<slug>]` — the project slug of every retired scaffold,
|
|
209
|
+
which also names the scaffold directory under the projects root that this
|
|
210
|
+
project supersedes.
|
|
211
|
+
- `absorbed_backlog_ids: [<BL-id>]` — every backlog ID those scaffolds carried
|
|
212
|
+
into this project.
|
|
213
|
+
|
|
214
|
+
Record both fields only when a consolidation actually happened; an absent field
|
|
215
|
+
and an empty list are equivalent. These two fields are the only inputs the
|
|
216
|
+
absorbed-project retirement sweep reads at completion, where retiring a scaffold
|
|
217
|
+
is treated as a semantic claim about the planning surfaces rather than the
|
|
218
|
+
physical removal of a directory.
|
|
146
219
|
|
|
147
220
|
### Step 1: Set Quick Workflow Metadata
|
|
148
221
|
|
|
149
|
-
Update `"$PROJECT_PATH/state.md"` frontmatter
|
|
222
|
+
Update `"$PROJECT_PATH/state.md"` frontmatter, using the `PROJECT_PATH` that
|
|
223
|
+
Step 0.5 resolved for a resumed project or that scaffolding re-resolved and
|
|
224
|
+
validated for a new one:
|
|
150
225
|
|
|
151
226
|
- `oat_workflow_mode: quick`
|
|
152
227
|
- `oat_workflow_origin: native`
|
|
@@ -515,6 +590,13 @@ preserved value is `null` or malformed for the phase-review contract.
|
|
|
515
590
|
|
|
516
591
|
Create/update `"$PROJECT_PATH/plan.md"` from `.oat/templates/plan.md`.
|
|
517
592
|
|
|
593
|
+
`.oat/templates/plan.md` is read only when `"$PROJECT_PATH/plan.md"` is missing.
|
|
594
|
+
On the Step 0.5 resume path the file already exists, so this step updates it in
|
|
595
|
+
place: it re-asserts the frontmatter values below and continues authoring the
|
|
596
|
+
plan body, and it never replaces phases, tasks, or `## Reviews` rows an earlier
|
|
597
|
+
run already wrote. Step 2.9's snapshot restore below is a frontmatter operation
|
|
598
|
+
and does not license a template rewrite of existing content.
|
|
599
|
+
|
|
518
600
|
Restore the exact snapshot into the resulting `plan.md` frontmatter as part of
|
|
519
601
|
the first resulting plan write, before any later frontmatter rewrite and before
|
|
520
602
|
Step 3.55 invokes the shared setup contract. Carry the snapshot losslessly
|
|
@@ -842,6 +924,183 @@ cannot be recorded, leave the Step 3 pre-review values unchanged and commit
|
|
|
842
924
|
them before stopping. Never expose a partially reviewed quick plan to
|
|
843
925
|
`oat-project-implement`.
|
|
844
926
|
|
|
927
|
+
### Quick Plan Readiness (Named Predicate)
|
|
928
|
+
|
|
929
|
+
**Quick plan readiness** is defined here, once. `oat-project-plan`,
|
|
930
|
+
`oat-project-progress`, and `oat-project-next` reference it by this name and do
|
|
931
|
+
not restate its conditions.
|
|
932
|
+
|
|
933
|
+
A quick `plan.md` is implementation-ready only when all of the following hold:
|
|
934
|
+
|
|
935
|
+
1. Frontmatter `oat_status: complete`, quoted or bare.
|
|
936
|
+
2. Frontmatter `oat_ready_for: oat-project-implement`, quoted or bare.
|
|
937
|
+
3. Frontmatter `oat_template` is not `true`: `oat_template: false`, an explicit
|
|
938
|
+
null, or an absent key, which is the same absent-or-false convention
|
|
939
|
+
`oat-project-next` applies when it classifies boundary tiers. A duplicated
|
|
940
|
+
`oat_template` key is contradictory, and an unrecognized value is not read as
|
|
941
|
+
ready.
|
|
942
|
+
4. The `## Reviews` section records the Step 3.7 disposition: a `plan` artifact
|
|
943
|
+
row whose Status is something other than `pending` or `-`, or the explicit
|
|
944
|
+
`Plan artifact review: skipped (workflow.autoArtifactReview.plan=false)`
|
|
945
|
+
recorded on a line of its own, starting at column 0 — never quoted inside
|
|
946
|
+
other prose, never indented into a code block, and never inside a fenced
|
|
947
|
+
example. Fences are read as CommonMark reads them — a fence closes only on a
|
|
948
|
+
bare run of its own marker, at least as long as the one that opened it — so an
|
|
949
|
+
example nested inside another fence stays an example. Indentation is measured
|
|
950
|
+
in columns, with a tab advancing to the next multiple of four, so any line
|
|
951
|
+
indented four or more columns — including a single tab-indented apparent fence
|
|
952
|
+
marker — is example code rather than the record.
|
|
953
|
+
5. At least one phase carries a substantive task — a `### Task pNN-tNN:`
|
|
954
|
+
heading under a `## Phase` heading, outside any fenced example, whose title
|
|
955
|
+
still reads as text once every `{placeholder}` is removed.
|
|
956
|
+
|
|
957
|
+
Substantive tasks alone never make a plan ready. The plan that Step 3 writes
|
|
958
|
+
already has concrete tasks, yet it carries the Step 3 pre-review frontmatter, so
|
|
959
|
+
it fails conditions 1–3 and is NOT ready. Readiness is the frontmatter plus the
|
|
960
|
+
durably recorded review disposition, never the presence of tasks. A not-ready
|
|
961
|
+
plan resumes through the Step 0.5 resume branch above, in place.
|
|
962
|
+
|
|
963
|
+
Evaluate the predicate mechanically with this guard. It reads `plan.md` only,
|
|
964
|
+
needs no CLI probe, and exits `0` when the plan is ready and `1` when it is not:
|
|
965
|
+
|
|
966
|
+
```bash
|
|
967
|
+
quick_plan_ready() {
|
|
968
|
+
PLAN_FILE="$1"
|
|
969
|
+
[ -f "$PLAN_FILE" ] || return 1
|
|
970
|
+
|
|
971
|
+
# The frontmatter block must be closed. An unterminated delimiter would
|
|
972
|
+
# otherwise let an ordinary body line satisfy a readiness field.
|
|
973
|
+
FRONTMATTER=$(awk '
|
|
974
|
+
NR == 1 && /^---[[:space:]]*$/ { inside = 1; next }
|
|
975
|
+
inside && /^---[[:space:]]*$/ { closed = 1; exit }
|
|
976
|
+
inside { print }
|
|
977
|
+
END { if (!closed) exit 1 }
|
|
978
|
+
' "$PLAN_FILE") || return 1
|
|
979
|
+
|
|
980
|
+
# Each field is declared exactly once, with exactly the required value, so a
|
|
981
|
+
# duplicated or contradictory key cannot be read as ready.
|
|
982
|
+
# Quotes must pair: `'complete` and `complete"` are different scalars to YAML
|
|
983
|
+
# and are not the required value here either.
|
|
984
|
+
quick_plan_key() { printf '[\"'\'']?%s[\"'\'']?[[:space:]]*:' "$1"; }
|
|
985
|
+
quick_plan_field() {
|
|
986
|
+
[ "$(printf '%s\n' "$FRONTMATTER" | grep -cE "^$(quick_plan_key "$1")")" = "1" ] || return 1
|
|
987
|
+
printf '%s\n' "$FRONTMATTER" |
|
|
988
|
+
grep -qE "^$(quick_plan_key "$1")[[:space:]]+($2|'$2'|\"$2\")[[:space:]]*(#.*)?$"
|
|
989
|
+
}
|
|
990
|
+
quick_plan_field oat_status complete || return 1
|
|
991
|
+
quick_plan_field oat_ready_for oat-project-implement || return 1
|
|
992
|
+
|
|
993
|
+
# `oat_template` follows the absent-or-false convention `oat-project-next`
|
|
994
|
+
# documents: only an explicit `true` disqualifies a plan. Absent, null, and
|
|
995
|
+
# false all mean "not a template"; a duplicated key is contradictory, and an
|
|
996
|
+
# unrecognized scalar is not read as ready.
|
|
997
|
+
TEMPLATE_KEY=$(quick_plan_key oat_template)
|
|
998
|
+
TEMPLATE_COUNT=$(printf '%s\n' "$FRONTMATTER" | grep -cE "^$TEMPLATE_KEY")
|
|
999
|
+
[ "$TEMPLATE_COUNT" -le 1 ] || return 1
|
|
1000
|
+
if [ "$TEMPLATE_COUNT" = "1" ]; then
|
|
1001
|
+
printf '%s\n' "$FRONTMATTER" |
|
|
1002
|
+
grep -qE "^$TEMPLATE_KEY[[:space:]]*(false|'false'|\"false\"|null|~)?[[:space:]]*(#.*)?$" || return 1
|
|
1003
|
+
fi
|
|
1004
|
+
|
|
1005
|
+
# Fenced examples are not the record: a sample review section inside a code
|
|
1006
|
+
# block must not dispose of a real pending row.
|
|
1007
|
+
REVIEWS=$(awk '
|
|
1008
|
+
# CommonMark measures indentation in columns, not characters: a tab
|
|
1009
|
+
# advances to the next multiple of four, so a single leading tab is
|
|
1010
|
+
# already a four-column code indentation. Counting raw characters would
|
|
1011
|
+
# let a tab-indented apparent closer end the fence used here while the
|
|
1012
|
+
# document still reads it as example content.
|
|
1013
|
+
function indent_columns(text, i, column, character) {
|
|
1014
|
+
column = 0
|
|
1015
|
+
for (i = 1; i <= length(text); i++) {
|
|
1016
|
+
character = substr(text, i, 1)
|
|
1017
|
+
if (character == " ") column++
|
|
1018
|
+
else if (character == "\t") column += 4 - (column % 4)
|
|
1019
|
+
else break
|
|
1020
|
+
}
|
|
1021
|
+
return column
|
|
1022
|
+
}
|
|
1023
|
+
# CommonMark fences: a fence closes only on its own marker character, at
|
|
1024
|
+
# least as long as the one that opened it, and a closing fence carries no
|
|
1025
|
+
# info string. A marker indented four or more columns is indented code.
|
|
1026
|
+
/^[[:space:]]*([`][`][`]|~~~)/ {
|
|
1027
|
+
line = $0
|
|
1028
|
+
if (indent_columns(line) < 4) {
|
|
1029
|
+
sub(/^[[:space:]]*/, "", line)
|
|
1030
|
+
marker = substr(line, 1, 1)
|
|
1031
|
+
len = 0
|
|
1032
|
+
while (substr(line, len + 1, 1) == marker) len++
|
|
1033
|
+
rest = substr(line, len + 1)
|
|
1034
|
+
if (!fence) { fence = 1; fmark = marker; flen = len }
|
|
1035
|
+
else if (marker == fmark && len >= flen && rest ~ /^[[:space:]]*$/) fence = 0
|
|
1036
|
+
}
|
|
1037
|
+
next
|
|
1038
|
+
}
|
|
1039
|
+
fence { next }
|
|
1040
|
+
indent_columns($0) >= 4 { next }
|
|
1041
|
+
/^## Reviews[[:space:]]*$/ { inside = 1; next }
|
|
1042
|
+
inside && /^##[[:space:]]/ { exit }
|
|
1043
|
+
inside { print }
|
|
1044
|
+
' "$PLAN_FILE")
|
|
1045
|
+
# The skip disposition counts only as its own recorded line, never as a
|
|
1046
|
+
# substring of prose that merely quotes it.
|
|
1047
|
+
if ! printf '%s\n' "$REVIEWS" | grep -qE '^(- )?Plan artifact review: skipped \(workflow\.autoArtifactReview\.plan=false\)[[:space:]]*$'; then
|
|
1048
|
+
PLAN_STATUS=$(printf '%s\n' "$REVIEWS" |
|
|
1049
|
+
grep -E '^\|[[:space:]]*plan[[:space:]]*\|[[:space:]]*artifact[[:space:]]*\|' |
|
|
1050
|
+
tail -1 |
|
|
1051
|
+
awk -F'|' '{ gsub(/^[[:space:]]+|[[:space:]]+$/, "", $4); print $4 }')
|
|
1052
|
+
case "$PLAN_STATUS" in
|
|
1053
|
+
'' | '-' | pending) return 1 ;;
|
|
1054
|
+
esac
|
|
1055
|
+
fi
|
|
1056
|
+
|
|
1057
|
+
# At least one real task heading, inside a phase and outside fenced examples,
|
|
1058
|
+
# whose title still reads as text once every {placeholder} is removed.
|
|
1059
|
+
awk '
|
|
1060
|
+
# CommonMark measures indentation in columns, not characters: a tab
|
|
1061
|
+
# advances to the next multiple of four, so a single leading tab is
|
|
1062
|
+
# already a four-column code indentation. Counting raw characters would
|
|
1063
|
+
# let a tab-indented apparent closer end the fence used here while the
|
|
1064
|
+
# document still reads it as example content.
|
|
1065
|
+
function indent_columns(text, i, column, character) {
|
|
1066
|
+
column = 0
|
|
1067
|
+
for (i = 1; i <= length(text); i++) {
|
|
1068
|
+
character = substr(text, i, 1)
|
|
1069
|
+
if (character == " ") column++
|
|
1070
|
+
else if (character == "\t") column += 4 - (column % 4)
|
|
1071
|
+
else break
|
|
1072
|
+
}
|
|
1073
|
+
return column
|
|
1074
|
+
}
|
|
1075
|
+
# CommonMark fences: a fence closes only on its own marker character, at
|
|
1076
|
+
# least as long as the one that opened it, and a closing fence carries no
|
|
1077
|
+
# info string. A marker indented four or more columns is indented code.
|
|
1078
|
+
/^[[:space:]]*([`][`][`]|~~~)/ {
|
|
1079
|
+
line = $0
|
|
1080
|
+
if (indent_columns(line) < 4) {
|
|
1081
|
+
sub(/^[[:space:]]*/, "", line)
|
|
1082
|
+
marker = substr(line, 1, 1)
|
|
1083
|
+
len = 0
|
|
1084
|
+
while (substr(line, len + 1, 1) == marker) len++
|
|
1085
|
+
rest = substr(line, len + 1)
|
|
1086
|
+
if (!fence) { fence = 1; fmark = marker; flen = len }
|
|
1087
|
+
else if (marker == fmark && len >= flen && rest ~ /^[[:space:]]*$/) fence = 0
|
|
1088
|
+
}
|
|
1089
|
+
next
|
|
1090
|
+
}
|
|
1091
|
+
fence { next }
|
|
1092
|
+
indent_columns($0) >= 4 { next }
|
|
1093
|
+
/^##[[:space:]]/ { inphase = ($0 ~ /^##[[:space:]]+Phase/); next }
|
|
1094
|
+
inphase && /^### Task p[0-9]+-t[0-9]+:[[:space:]]/ {
|
|
1095
|
+
sub(/^### Task p[0-9]+-t[0-9]+:[[:space:]]*/, "")
|
|
1096
|
+
print
|
|
1097
|
+
}
|
|
1098
|
+
' "$PLAN_FILE" | sed -E 's/\{[^}]*\}//g' | grep -qE '[[:alnum:]]' || return 1
|
|
1099
|
+
|
|
1100
|
+
return 0
|
|
1101
|
+
}
|
|
1102
|
+
```
|
|
1103
|
+
|
|
845
1104
|
### Step 4: Sync Project State
|
|
846
1105
|
|
|
847
1106
|
Update `"$PROJECT_PATH/state.md"`:
|
|
@@ -917,3 +1176,4 @@ Report:
|
|
|
917
1176
|
- ✅ `implementation.md` is initialized for resumable execution.
|
|
918
1177
|
- ✅ Changed quick-start artifacts are committed before handoff or pause; `.oat/state.md` is refreshed locally when available.
|
|
919
1178
|
- ✅ Configured gate has run, and only a corroborated, receive-eligible artifact has been handed off to `oat-project-review-receive` before it is treated as consumed.
|
|
1179
|
+
- ✅ An existing incomplete quick project resumed in place against **quick plan readiness** instead of being re-scaffolded.
|