devlyn-cli 1.5.0 → 1.5.2

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.
@@ -11,6 +11,16 @@ $ARGUMENTS
11
11
 
12
12
  <pipeline_workflow>
13
13
 
14
+ <autonomy_contract>
15
+ This pipeline runs hands-free. The user launches it to walk away and come back to finished work, so the quality of this run is measured by how far it gets without human intervention. Apply these behaviors throughout every phase:
16
+
17
+ 1. **Make decisions autonomously and log them in the final report.** When you would otherwise ask the user something ("Should I commit this?", "Ready to proceed?", "Which approach?"), pick the safe default, proceed, and record the decision in PHASE 8's report so the user can review it at the end.
18
+ 2. **Run only the phases defined below, in the order given.** Doc updates, roadmap edits, changelog entries, and planning-doc changes belong in PHASE 7 (Docs). Resist inserting them earlier as freelance pre-work.
19
+ 3. **Delegate all file changes to spawned subagents.** As the orchestrator, your actions are: parse input, spawn phase agents, read handoff files (`.devlyn/*.md`), run `git` commands, branch on verdicts, and emit the final report.
20
+ 4. **Continue through the pipeline by default.** Stop only for: (a) a subagent reporting an unrecoverable failure, (b) PHASE 1 producing zero code changes, (c) `max-rounds` reached — in which case continue to PHASE 3 with a warning rather than halting. Every other situation means move on to the next phase.
21
+ 5. **Treat questions as a signal to act instead.** If you notice yourself drafting a question to the user mid-pipeline, convert it into a decision + log entry and spawn the next phase.
22
+ </autonomy_contract>
23
+
14
24
  ## PHASE 0: PARSE INPUT
15
25
 
16
26
  1. Extract the task/issue description from `<pipeline_config>`.
@@ -35,12 +35,32 @@ $ARGUMENTS
35
35
  - `--port PORT` — override detected port
36
36
  - `--tier N` — force a specific tier (1, 2, or 3)
37
37
  - `--mobile-only` / `--desktop-only` — limit viewport testing
38
+ - `--topic SLUG` — override the auto-derived screenshot topic slug
39
+
40
+ 8. **Derive the screenshot topic slug**. All screenshots for this run go under `.devlyn/screenshots/<topic-slug>/` so runs for different features don't pile up together. Resolution order:
41
+ 1. `--topic` flag value, kebab-cased
42
+ 2. First non-blank heading/line of `.devlyn/done-criteria.md` (strip `#`, kebab-case, max 40 chars)
43
+ 3. Current git branch name, if not `main`/`master`/`HEAD`
44
+ 4. Fallback: `run-<YYYYMMDD-HHMM>`
45
+
46
+ Then wipe and recreate the topic dir (fresh evidence per run; don't touch other topics' dirs):
47
+ ```bash
48
+ SCREENSHOT_DIR=".devlyn/screenshots/<topic-slug>"
49
+ rm -rf "$SCREENSHOT_DIR"
50
+ mkdir -p "$SCREENSHOT_DIR"/{smoke,feature,visual}
51
+ ```
52
+
53
+ Record `$SCREENSHOT_DIR` and reuse it through the run. All screenshot paths below are **relative to `$SCREENSHOT_DIR`**:
54
+ - Smoke: `smoke/<route-slug>.png` (root → `smoke/root.png`)
55
+ - Feature: `feature/<criterion-slug>-step<N>.png`
56
+ - Visual: `visual/<viewport>-<route-slug>.png` (e.g., `visual/mobile-dashboard.png`)
38
57
 
39
58
  Announce:
40
59
  ```
41
60
  Browser validation starting
42
61
  Feature: [what was built, from done-criteria or git diff]
43
62
  Framework: [detected] | Port: [PORT] | Tier: [N — name]
63
+ Topic: [topic-slug] → .devlyn/screenshots/<topic-slug>/
44
64
  Phases: Server → Smoke → Feature Test → Visual → Report
45
65
  ```
46
66
 
@@ -71,7 +71,12 @@ Identify fields with `find` first, then use `form_input` with the field selector
71
71
  ```
72
72
  computer → screenshot action captures the visible viewport
73
73
  ```
74
- Save screenshots with descriptive names: `smoke-root.png`, `flow-create-project-step3.png`, `visual-mobile-dashboard.png`.
74
+ Save screenshots into the topic-scoped directory that PHASE 1 set up (`.devlyn/screenshots/<topic-slug>/`), organized by phase:
75
+ - Smoke: `<topic>/smoke/<route>.png` — e.g., `smoke/root.png`, `smoke/dashboard.png`
76
+ - Feature: `<topic>/feature/<criterion>-step<N>.png` — e.g., `feature/create-project-step3.png`
77
+ - Visual: `<topic>/visual/<viewport>-<route>.png` — e.g., `visual/mobile-dashboard.png`
78
+
79
+ Since `computer → screenshot` writes to a default location, move/rename the captured file into the right subdirectory immediately after taking it, so evidence paths in the report match this scheme.
75
80
 
76
81
  ### Resize viewport
77
82
  ```
@@ -89,7 +89,10 @@ test.describe('Smoke Tests', () => {
89
89
  const pageUrl = page.url();
90
90
  expect(title, 'Page shows a browser error — server may be down').not.toBe(pageUrl);
91
91
 
92
- await page.screenshot({ path: `.devlyn/screenshots/smoke${route.replace(/\//g, '-') || '-root'}.png`, fullPage: true });
92
+ await page.screenshot({ path: `${SCREENSHOT_DIR}/smoke/${route.replace(/^\//, '').replace(/\//g, '-') || 'root'}.png`, fullPage: true });
93
+ // SCREENSHOT_DIR is the topic-scoped dir set up in PHASE 1 of SKILL.md
94
+ // (e.g., .devlyn/screenshots/add-login-page). Inject it at test-generation
95
+ // time so every test writes into the same per-run folder.
93
96
 
94
97
  if (errors.length > 0) {
95
98
  test.info().annotations.push({ type: 'console_errors', description: errors.join(' | ') });
@@ -123,7 +126,7 @@ test('flow: [criterion description]', async ({ page }) => {
123
126
  await expect(page.locator('[verification selector]')).toBeVisible();
124
127
 
125
128
  // Screenshot
126
- await page.screenshot({ path: '.devlyn/screenshots/flow-[name].png' });
129
+ await page.screenshot({ path: `${SCREENSHOT_DIR}/feature/[criterion-slug]-step[N].png` });
127
130
  });
128
131
  ```
129
132
 
@@ -135,7 +138,7 @@ test.describe('Visual - Mobile', () => {
135
138
  for (const route of ROUTES) {
136
139
  test(`visual-mobile: ${route}`, async ({ page }) => {
137
140
  await page.goto(`http://localhost:${PORT}${route}`, { waitUntil: 'networkidle' });
138
- await page.screenshot({ path: `.devlyn/screenshots/visual-mobile${route.replace(/\//g, '-') || '-root'}.png`, fullPage: true });
141
+ await page.screenshot({ path: `${SCREENSHOT_DIR}/visual/mobile-${route.replace(/^\//, '').replace(/\//g, '-') || 'root'}.png`, fullPage: true });
139
142
  });
140
143
  }
141
144
  });
@@ -145,7 +148,7 @@ test.describe('Visual - Desktop', () => {
145
148
  for (const route of ROUTES) {
146
149
  test(`visual-desktop: ${route}`, async ({ page }) => {
147
150
  await page.goto(`http://localhost:${PORT}${route}`, { waitUntil: 'networkidle' });
148
- await page.screenshot({ path: `.devlyn/screenshots/visual-desktop${route.replace(/\//g, '-') || '-root'}.png`, fullPage: true });
151
+ await page.screenshot({ path: `${SCREENSHOT_DIR}/visual/desktop-${route.replace(/^\//, '').replace(/\//g, '-') || 'root'}.png`, fullPage: true });
149
152
  });
150
153
  }
151
154
  });
@@ -154,7 +157,7 @@ test.describe('Visual - Desktop', () => {
154
157
  ## Execution
155
158
 
156
159
  ```bash
157
- mkdir -p .devlyn/screenshots
160
+ mkdir -p "$SCREENSHOT_DIR"/{smoke,feature,visual}
158
161
  npx playwright test .devlyn/browser-test.spec.ts \
159
162
  --reporter=json \
160
163
  --output=.devlyn/playwright-results \
@@ -182,7 +185,7 @@ rm -rf .devlyn/playwright-results
182
185
  rm -f .devlyn/playwright-output.json
183
186
  ```
184
187
 
185
- Keep `.devlyn/screenshots/` — those are evidence referenced by the report.
188
+ Keep `$SCREENSHOT_DIR` (`.devlyn/screenshots/<topic-slug>/`) — those are evidence referenced by the report. Don't touch other topics' directories.
186
189
 
187
190
  ## Limitations vs Tier 1
188
191
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devlyn-cli",
3
- "version": "1.5.0",
3
+ "version": "1.5.2",
4
4
  "description": "Claude Code configuration toolkit for teams",
5
5
  "bin": {
6
6
  "devlyn": "bin/devlyn.js"