@haposoft/cafekit 0.13.2 → 0.13.3
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haposoft/cafekit",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.3",
|
|
4
4
|
"description": "Claude Code-first spec-driven workflow for AI coding assistants. Bundles CafeKit hapo: skills, runtime hooks, agents, and installer scaffolding.",
|
|
5
5
|
"author": "Haposoft <nghialt@haposoft.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -132,6 +132,28 @@ function validateTaskSections(taskPath, content, errors) {
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
/**
|
|
136
|
+
* Task files are created from the scaffold template (the scaffold-guard hook
|
|
137
|
+
* forces creation through it), so every task starts as a stub full of `{{...}}`
|
|
138
|
+
* placeholders. The hook guarantees the stub is CREATED via scaffold, but
|
|
139
|
+
* nothing guaranteed the model FILLED it. An unfilled `{{...}}` is an
|
|
140
|
+
* incomplete task — SKILL.md: "Leave NO {{...}} placeholder ... fails DoCT" —
|
|
141
|
+
* so it is a hard error here. A `.../` path fragment is a not-yet-resolved path
|
|
142
|
+
* placeholder; it is only a warning, because it usually survives in prose Steps
|
|
143
|
+
* while the Related Files table (which spec-ground.cjs does verify) is already
|
|
144
|
+
* concrete. Matching `\.\.\.\/` (three dots + slash) avoids flagging a relative
|
|
145
|
+
* `../` path or a prose ellipsis.
|
|
146
|
+
*/
|
|
147
|
+
function validateTaskPlaceholders(taskPath, content, errors, warnings) {
|
|
148
|
+
const stub = content.match(/\{\{[^}\n]+\}\}/);
|
|
149
|
+
if (stub) {
|
|
150
|
+
errors.push(`${taskPath}: unfilled scaffold placeholder ${stub[0]} — task stub was not completed`);
|
|
151
|
+
}
|
|
152
|
+
if (/\.\.\.\//.test(content)) {
|
|
153
|
+
warnings.push(`${taskPath}: contains a '.../' path placeholder — replace with a concrete path`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
135
157
|
/**
|
|
136
158
|
* Each phase completion must carry its own timestamp. Reusing `timestamps.init`
|
|
137
159
|
* for a later phase is forbidden (SKILL.md spec.json Update Rules). This used to
|
|
@@ -344,6 +366,7 @@ function validateSpec(specDir) {
|
|
|
344
366
|
const fullPath = path.join(specDir, taskFile);
|
|
345
367
|
const content = fs.readFileSync(fullPath, 'utf8');
|
|
346
368
|
validateTaskSections(taskFile, content, errors);
|
|
369
|
+
validateTaskPlaceholders(taskFile, content, errors, warnings);
|
|
347
370
|
|
|
348
371
|
const idRe = /\b((?:REQ-\d+)|(?:R\d+))\b/gi;
|
|
349
372
|
let match;
|
|
@@ -335,7 +335,7 @@ Rules:
|
|
|
335
335
|
- Load `references/ask-user-question-gates.md`; if scoring reveals unapproved scope expansion or an unresolved user-owned choice, pause before writing task files.
|
|
336
336
|
- **Scaffold is mandatory — raw `Write` to a task file is blocked.** A PreToolUse hook (`task-scaffold-guard.cjs`) rejects any `Write` whose path matches `specs/<feature>/tasks/task-*.md`. The only path to a task file is scaffold → Edit. Once the task list is decided, generate the stubs:
|
|
337
337
|
`node .claude/scripts/spec-scaffold.cjs <feature> --tasks "R0-01-slug,R1-01-slug,..." --tasks-only`
|
|
338
|
-
This creates each `tasks/task-R*.md` from `templates/task.md` and merges `task_files` + `task_registry` into the existing `spec.json` (pending, no overwrite of already-filled tasks). Then **Edit-fill** the `{{...}}` placeholders in each stub (`Edit`/`MultiEdit` are allowed; `Write` is not).
|
|
338
|
+
This creates each `tasks/task-R*.md` from `templates/task.md` and merges `task_files` + `task_registry` into the existing `spec.json` (pending, no overwrite of already-filled tasks). Then **Edit-fill** the `{{...}}` placeholders in each stub (`Edit`/`MultiEdit` are allowed; `Write` is not). (The guard fails open if the scaffold script is absent, and can be disabled via `"spec": { "scaffold_guard": false }` in `.claude/runtime.json`.)
|
|
339
339
|
- Each task file follows template `templates/task.md` (scaffold already applies it). **Leave NO `{{...}}` placeholder unfilled** — a stub with placeholders is an incomplete task.
|
|
340
340
|
- `Related Files` and test plans must inherit paths, contracts, and test targets from the codebase scout. If exact files/tests cannot be named for an enhancement, run targeted inspect before generating tasks. Every `Related Files` path will be grounded (Layer 2) at Step 8.5 — phantom paths hard-fail, so cite real paths.
|
|
341
341
|
- Each task file MUST include `Completion Criteria` and `Evidence` sections detailed enough that a downstream quality gate can prove the task is truly done. Existing specs may use `Task Test Plan & Verification Evidence` or legacy `Verification & Evidence`.
|