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.
- package/config/skills/devlyn:auto-resolve/SKILL.md +10 -0
- package/config/skills/devlyn:browser-validate/SKILL.md +20 -0
- package/config/skills/devlyn:browser-validate/references/tier1-chrome.md +6 -1
- package/config/skills/devlyn:browser-validate/references/tier2-playwright.md +9 -6
- package/package.json +1 -1
|
@@ -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
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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
|
|
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
|
|