vinta-ai-workflows 0.2.0-alpha1 → 0.2.0-alpha2
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/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,32 @@ the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
7
7
|
|
|
8
8
|
## [0.2.0] — YYYY-MM-DD
|
|
9
9
|
|
|
10
|
+
<!-- pre-release: 0.2.0-alpha2 on 2026-06-13 -->
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **Fixed bug on setup-ai-tools.mjs**: Sub agents were being generated
|
|
15
|
+
with an invalid description and were not being loaded by claude-code and
|
|
16
|
+
possibly other AI tools.
|
|
17
|
+
|
|
18
|
+
- **`implement-plan` template — stray main-checkout-write guard (only
|
|
19
|
+
when `run_options.use_worktree = true`).** A subagent told to work
|
|
20
|
+
inside the worktree can resolve an absolute path back to the **main
|
|
21
|
+
checkout** and silently edit files there; because worktrees have
|
|
22
|
+
independent working trees those edits never reach the phase commit —
|
|
23
|
+
they sit as uncommitted thrash in the main checkout and read as a
|
|
24
|
+
silent implementer/fixer failure. Layer 1 mechanical checks gain a new
|
|
25
|
+
item: after **every** implementer **and** fixer subagent returns, run
|
|
26
|
+
`git -C <main-checkout-path> status --short | grep -vE '^\?\?'`
|
|
27
|
+
(tracked modifications only); any output is a BLOCKER — recover intent
|
|
28
|
+
via `git -C <main-checkout-path> diff`, re-dispatch the agent with an
|
|
29
|
+
explicit worktree-path instruction if the change belongs there, then
|
|
30
|
+
`git -C <main-checkout-path> restore` so the main checkout returns
|
|
31
|
+
clean between phases. `<main-checkout-path>` is the repo root the skill
|
|
32
|
+
was invoked from, never `run_options.worktree_path`. Skipped entirely
|
|
33
|
+
when `use_worktree = false`. Mirrored in the per-phase Quick checklist
|
|
34
|
+
Layer 1 line and a new **Important rules** bullet.
|
|
35
|
+
|
|
10
36
|
<!-- pre-release: 0.2.0-alpha1 on 2026-06-12 -->
|
|
11
37
|
|
|
12
38
|
### Added
|
package/package.json
CHANGED
|
@@ -193,6 +193,11 @@ Three layers, all required, in order. The orchestrator never edits — every iss
|
|
|
193
193
|
3. **Verify the outer gate** ran + green. Look in the report for explicit confirmation that `{{BUILD_CMD}}` AND `{{TEST_CMD}}` were executed + passed{{E2E_LAYER1_NOTE}}. Vague confirmation → **re-run yourself**.
|
|
194
194
|
4. **Scope creep**: file touched outside expected surface area? Unrelated formatting churn? Surface it.
|
|
195
195
|
5. **No-secrets scan**: `git diff` for `password|secret|token|api_key|AKIA|BEGIN [A-Z]+ KEY`.
|
|
196
|
+
6. **Stray main-checkout writes (only when `run_options.use_worktree = true`)**: a subagent is told to work inside the worktree, but a buggy agent (often a smaller model) can resolve an absolute path back to the **main checkout** and silently edit files there (worktrees have independent working trees, so those edits never reach the phase commit — they sit as uncommitted thrash in the main checkout, and the "missing" edits read as a silent fixer/implementer failure). After **every** implementer **and** fixer subagent returns, run `git -C <main-checkout-path> status --short | grep -vE '^\?\?'` (tracked modifications only). Any output is a BLOCKER for this phase:
|
|
197
|
+
- Diff the stray files (`git -C <main-checkout-path> diff -- <path>`) to recover intent.
|
|
198
|
+
- If the edit belongs in the worktree, re-dispatch the fixer/implementer with an explicit instruction to write to the worktree path (the change is missing from the phase commit until it does).
|
|
199
|
+
- Once recovered (or confirmed superseded by the correctly-committed worktree version), discard the stray edits with `git -C <main-checkout-path> restore -- <path>` so the main checkout returns clean. Never leave the main checkout dirty between phases — a later phase's Layer 1 can't tell new thrash from old.
|
|
200
|
+
`<main-checkout-path>` is the repo root the skill was invoked from (NOT `run_options.worktree_path`). Skip this check entirely when `run_options.use_worktree = false`.
|
|
196
201
|
{{DEPENDENCY_LICENSE_LAYER1_CHECK}}
|
|
197
202
|
{{COAUTHOR_LAYER1_CHECK}}
|
|
198
203
|
|
|
@@ -377,6 +382,7 @@ After all executable phases complete:
|
|
|
377
382
|
- **Honor opt-in flags.** `run_options.pause_between_phases` controls the [Per-phase pause gate](#1i-per-phase-pause-gate-opt-in); `run_options.generate_inline_comments` controls whether the [Open PR via context file](#1f-open-pr-via-context-file) step drafts inline comments (always writes the file when that step runs at all — empty comments when off); `run_options.use_worktree` controls whether the [Provision worktree](#step-05--provision-worktree-when-run_optionsuse_worktree--true) step runs and whether every later `git` / lint / test / build / migrate call uses the worktree path.
|
|
378
383
|
- **One worktree per plan run.** When `use_worktree = true`, provision once in the [Provision worktree](#step-05--provision-worktree-when-run_optionsuse_worktree--true) step and reuse for every phase. Never spawn a second worktree mid-plan; never silently fall back to the main checkout on prepare-worktree failure (ask the user).
|
|
379
384
|
- **Don't auto-tear-down the worktree.** Step 2 surfaces the teardown command; the user runs it when they're ready (after reviewer feedback is addressed, after the PR merges, etc.).
|
|
385
|
+
- **Catch stray main-checkout writes when `use_worktree = true`.** A subagent can resolve a path back to the main checkout and silently edit there, leaving the change out of the phase commit. Layer 1 runs `git -C <main-checkout-path> status --short` after every implementer and fixer; any tracked modification is a BLOCKER — recover the intent, re-dispatch to the worktree, then restore the main checkout clean. `<main-checkout-path>` is the repo root the skill was invoked from, never `run_options.worktree_path`.
|
|
380
386
|
- **PR-context file + `open-pr.sh` is the only PR-creation path.** No raw `gh pr create` / `glab mr create` calls outside the bundled script. The file is durable; the script is the publisher.
|
|
381
387
|
{{DEPENDENCY_LICENSE_RULE_LINE}}
|
|
382
388
|
- **[Open PR via context file](#1f-open-pr-via-context-file) gating** = combination of project PR policy ({{PR_POLICY_BLOCK}}) and `generate_inline_comments`. See the matrix in that step. Skip it entirely only when policy = branches only AND comments = off.
|
|
@@ -392,7 +398,7 @@ After all executable phases complete:
|
|
|
392
398
|
- [ ] Subagent spawned, report received.
|
|
393
399
|
- [ ] Inner loop green: scoped lint + new tests individually + scoped suite.
|
|
394
400
|
- [ ] **Outer gate green:** `{{BUILD_CMD}}` AND `{{TEST_CMD}}`{{E2E_OUTER_GATE_CHECKLIST}} both passed.
|
|
395
|
-
- [ ] Layer 1 review: full diff read; no scope creep; no secrets; outer gate confirmed{{COAUTHOR_CHECKLIST_NOTE}}.
|
|
401
|
+
- [ ] Layer 1 review: full diff read; no scope creep; no secrets; outer gate confirmed{{COAUTHOR_CHECKLIST_NOTE}}; when `use_worktree = true`, `git -C <main-checkout-path> status --short` clean (no stray main-checkout writes) after the implementer and after every fixer.
|
|
396
402
|
- [ ] Layer 2 review: every "Changes" ticked; every "Tests" materialized; acceptance line satisfiable; conventions, reusable skills, e2e + screenshot compliance (if applicable), flag wiring all checked.
|
|
397
403
|
- [ ] Layer 3 review: adversarial review run; BLOCKERs fixed; SHOULD-FIX either fixed or noted.
|
|
398
404
|
- [ ] After any fix-up: Layers 1 + 2 + outer gate re-run.
|
|
@@ -204,13 +204,23 @@ function autoGenHeader(srcPath, comment = '#') {
|
|
|
204
204
|
|
|
205
205
|
// ── Vendor emitters ──────────────────────────────────────────────────────
|
|
206
206
|
|
|
207
|
+
// Fold a (possibly multi-line) value into a YAML-safe single-line scalar.
|
|
208
|
+
// The agent `description` in the source YAML is authored as multi-line prose;
|
|
209
|
+
// interpolated raw into markdown frontmatter it produces invalid YAML
|
|
210
|
+
// (unindented continuation lines + embedded colons), so the harness silently
|
|
211
|
+
// skips the agent. A JSON string is also a valid YAML double-quoted flow
|
|
212
|
+
// scalar, so JSON.stringify gives correct escaping for free.
|
|
213
|
+
function yamlInlineScalar(value) {
|
|
214
|
+
return JSON.stringify(String(value).replace(/\s+/g, ' ').trim());
|
|
215
|
+
}
|
|
216
|
+
|
|
207
217
|
function emitClaude(name, doc, body) {
|
|
208
218
|
const cfg = resolveVendorConfig(doc, 'claude');
|
|
209
219
|
const lines = [
|
|
210
220
|
'---',
|
|
211
221
|
autoGenHeader(`ai-tools/agents/${name}.yaml`),
|
|
212
222
|
`name: ${doc.name}`,
|
|
213
|
-
`description: ${doc.description}`,
|
|
223
|
+
`description: ${yamlInlineScalar(doc.description)}`,
|
|
214
224
|
];
|
|
215
225
|
if (cfg.tools) lines.push(`tools: ${cfg.tools}`);
|
|
216
226
|
if (cfg.model) lines.push(`model: ${cfg.model}`);
|
|
@@ -224,7 +234,7 @@ function emitCursor(name, doc, body) {
|
|
|
224
234
|
'---',
|
|
225
235
|
autoGenHeader(`ai-tools/agents/${name}.yaml`),
|
|
226
236
|
`name: ${doc.name}`,
|
|
227
|
-
`description: ${doc.description}`,
|
|
237
|
+
`description: ${yamlInlineScalar(doc.description)}`,
|
|
228
238
|
];
|
|
229
239
|
if (cfg.model) lines.push(`model: ${cfg.model}`);
|
|
230
240
|
if (cfg.readonly !== undefined) lines.push(`readonly: ${cfg.readonly}`);
|
|
@@ -238,7 +248,7 @@ function emitCopilot(name, doc, body) {
|
|
|
238
248
|
const lines = [
|
|
239
249
|
'---',
|
|
240
250
|
autoGenHeader(`ai-tools/agents/${name}.yaml`),
|
|
241
|
-
`description: ${doc.description}`,
|
|
251
|
+
`description: ${yamlInlineScalar(doc.description)}`,
|
|
242
252
|
];
|
|
243
253
|
if (cfg.tools) lines.push(`tools: ${JSON.stringify(cfg.tools)}`);
|
|
244
254
|
if (cfg.model) lines.push(`model: ${cfg.model}`);
|