@brunosps00/dev-workflow 1.0.5 → 1.1.0

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.
Files changed (55) hide show
  1. package/README.md +17 -13
  2. package/bin/dev-workflow.js +5 -0
  3. package/lib/constants.js +6 -4
  4. package/lib/install-deps.js +88 -3
  5. package/lib/setup-wsl-browser.js +149 -0
  6. package/package.json +1 -1
  7. package/scaffold/en/agent-instructions.md +7 -5
  8. package/scaffold/en/commands/dw-analyze-project.md +22 -0
  9. package/scaffold/en/commands/dw-autopilot.md +158 -275
  10. package/scaffold/en/commands/dw-bugfix.md +3 -2
  11. package/scaffold/en/commands/dw-functional-doc.md +11 -3
  12. package/scaffold/en/commands/dw-generate-pr.md +2 -2
  13. package/scaffold/en/commands/dw-goal.md +136 -0
  14. package/scaffold/en/commands/dw-help.md +9 -7
  15. package/scaffold/en/commands/dw-plan.md +9 -3
  16. package/scaffold/en/commands/dw-qa.md +1 -1
  17. package/scaffold/en/commands/dw-redesign-ui.md +2 -2
  18. package/scaffold/en/commands/dw-review.md +7 -5
  19. package/scaffold/en/commands/dw-secure-audit.md +72 -15
  20. package/scaffold/en/templates/constitution-template.md +8 -3
  21. package/scaffold/en/templates/functional-doc/playwright.flow.mjs.tpl +17 -0
  22. package/scaffold/pt-br/agent-instructions.md +7 -5
  23. package/scaffold/pt-br/commands/dw-analyze-project.md +22 -0
  24. package/scaffold/pt-br/commands/dw-autopilot.md +161 -278
  25. package/scaffold/pt-br/commands/dw-bugfix.md +3 -2
  26. package/scaffold/pt-br/commands/dw-functional-doc.md +11 -3
  27. package/scaffold/pt-br/commands/dw-generate-pr.md +2 -2
  28. package/scaffold/pt-br/commands/dw-goal.md +136 -0
  29. package/scaffold/pt-br/commands/dw-help.md +9 -7
  30. package/scaffold/pt-br/commands/dw-plan.md +9 -3
  31. package/scaffold/pt-br/commands/dw-qa.md +1 -1
  32. package/scaffold/pt-br/commands/dw-redesign-ui.md +2 -2
  33. package/scaffold/pt-br/commands/dw-review.md +7 -5
  34. package/scaffold/pt-br/commands/dw-secure-audit.md +72 -15
  35. package/scaffold/pt-br/templates/constitution-template.md +8 -3
  36. package/scaffold/pt-br/templates/functional-doc/playwright.flow.mjs.tpl +17 -0
  37. package/scaffold/scripts/cdp-relay/Cargo.toml +16 -0
  38. package/scaffold/scripts/cdp-relay/src/main.rs +49 -0
  39. package/scaffold/scripts/functional-doc/generate-dossier.mjs +7 -9
  40. package/scaffold/scripts/functional-doc/run-playwright-flow.mjs +192 -183
  41. package/scaffold/scripts/lib/capture-screenshots.mjs +133 -0
  42. package/scaffold/scripts/lib/resolve-browser.mjs +405 -0
  43. package/scaffold/scripts/lib/ui-slop-detect.mjs +102 -0
  44. package/scaffold/skills/dw-testing-discipline/references/playwright-recipes.md +50 -0
  45. package/scaffold/skills/dw-ui-discipline/SKILL.md +5 -0
  46. package/scaffold/skills/dw-ui-discipline/references/color-oklch.md +60 -0
  47. package/scaffold/skills/dw-ui-discipline/references/motion.md +52 -0
  48. package/scaffold/skills/dw-ui-discipline/references/responsive.md +52 -0
  49. package/scaffold/skills/dw-ui-discipline/references/type-scale.md +48 -0
  50. package/scaffold/skills/dw-ui-discipline/references/ux-writing.md +52 -0
  51. package/scaffold/skills/security-review/SKILL.md +19 -0
  52. package/scaffold/skills/security-review/references/sast.md +67 -0
  53. package/scaffold/skills/security-review/references/secrets.md +46 -0
  54. package/scaffold/en/templates/functional-doc/playwright.spec.ts.tpl +0 -19
  55. package/scaffold/pt-br/templates/functional-doc/playwright.spec.ts.tpl +0 -19
package/README.md CHANGED
@@ -19,20 +19,20 @@ This will:
19
19
 
20
20
  > **Compozy-inspired disciplines.** Since 0.5.0, dev-workflow bundles three primitives — `dw-verify`, `dw-memory`, `dw-review-rigor` — adapted from the [Compozy](https://github.com/compozy/compozy) project and invoked internally by existing commands. See [docs/compozy-integration.md](docs/compozy-integration.md) for what was ported and what was not.
21
21
 
22
- Optional dependencies (Playwright browsers, react-doctor, Trivy, Docker):
22
+ Optional dependencies (Playwright browsers, react-doctor, Trivy, Semgrep, gitleaks, Docker):
23
23
  ```bash
24
24
  npx @brunosps00/dev-workflow install-deps
25
25
  ```
26
26
 
27
27
  ## Commands
28
28
 
29
- dev-workflow v1.0.5 ships **30 commands** organized into four tiers. Most users only invoke Tier 1 + Tier 2.
29
+ dev-workflow v1.0.6 ships **31 commands** organized into four tiers. Most users only invoke Tier 1 + Tier 2.
30
30
 
31
31
  ### Tier 1 — Gateway (3)
32
32
 
33
33
  | Command | When |
34
34
  |---------|------|
35
- | **`/dw-autopilot "wish"`** | Default entry point. Full pipeline (PRD → TechSpec → Tasks → Run → QA → Review → Commit → PR) with 3 approval gates. Use `--from-prd <slug>` to resume from an existing PRD (e.g., after a `/dw-bugfix` safety-valve escalation): skips Steps 1–4 and starts at GATE 1. |
35
+ | **`/dw-autopilot "wish"`** | Default entry point in two invocations. First run completes PRD → TechSpec → Tasks and stops. Second run resumes from state, executes `/dw-goal --from-autopilot <slug>` for Run → Review → QA/Fix → Review, then Commit → PR. |
36
36
  | **`/dw-bugfix "description"`** | A bug report or pasted error. Triages bug-vs-feature-vs-scope, surgical fix or routes to a PRD. |
37
37
  | **`/dw-help [keyword]`** | Discover commands. Pass a keyword for shortcuts; `--advanced` reveals internal commands. |
38
38
 
@@ -67,7 +67,7 @@ Use these when you want step-by-step control instead of `/dw-autopilot`.
67
67
  | **`/dw-install-azure-skills`** | **Opt-in.** Clones curated Azure skills from [`MicrosoftDocs/Agent-Skills`](https://github.com/MicrosoftDocs/Agent-Skills) (CC-BY-4.0) into `.agents/skills/azure/` and registers the [Microsoft Learn MCP Server](https://learn.microsoft.com/en-us/training/support/mcp-get-started) (HTTP, no-auth). Interactive category selection (Compute / Data & Storage / AI & ML / Networking / Identity & Security / DevOps / Observability / Integration / Architecture / All). Re-run to refresh from upstream. Also available as CLI: `npx @brunosps00/dev-workflow install-azure-skills`. |
68
68
  | **`/dw-install-aws-skills`** | **Opt-in.** Clones curated AWS skills from [`aws/agent-toolkit-for-aws`](https://github.com/aws/agent-toolkit-for-aws) (Apache 2.0) into `.agents/skills/aws/` and registers the unified [AWS MCP Server](https://docs.aws.amazon.com/aws-mcp/) (stdio via `uvx mcp-proxy-for-aws@latest`). **Requires `uv`, `aws cli ≥ 2.32.0`, and AWS credentials.** Interactive category selection (Core / Analytics / Database / EC2 / Migration / Networking / Operations / Security / Serverless / Storage / All). The agent gains `aws___call_aws` (executes 15,000+ AWS APIs) and `aws___run_script` (Python sandboxed) — review `.dw/references/aws-mcp-instructions.md` for the destructive-operations protocol. Also available as CLI: `npx @brunosps00/dev-workflow install-aws-skills [--region=<aws-region>]`. |
69
69
 
70
- ### Tier 4 — Hidden/Internal (8)
70
+ ### Tier 4 — Hidden/Internal (9)
71
71
 
72
72
  These are auto-invoked by Tier 1-3 commands. Available standalone via `/dw-help --advanced`.
73
73
 
@@ -75,7 +75,8 @@ These are auto-invoked by Tier 1-3 commands. Available standalone via `/dw-help
75
75
  |---------|------|------------|
76
76
  | **`/dw-adr "decision"`** | Records an Architecture Decision Record at `.dw/spec/<prd>/adrs/`. | `/dw-plan techspec --council`; deviations from constitution |
77
77
  | **`/dw-intel "question"`** | Query codebase intelligence (`.dw/intel/`). `--build` (re)creates the index. | `/dw-plan`, `/dw-review`, `/dw-bugfix` |
78
- | **`/dw-secure-audit`** | Unified security: OWASP + Trivy SCA/secret/IaC + lockfile + supply-chain check. Hard gate. Flags: `--scan-only`, `--plan`, `--execute`. | `/dw-review`, `/dw-generate-pr` (for TS/Python/C#/Rust) |
78
+ | **`/dw-secure-audit`** | **Security Gate** (phase after review/QA, before commit/PR): OWASP + Semgrep SAST (diff/generated code) + gitleaks secrets + Trivy SCA/IaC + lockfile + supply-chain + outdated. Rigoroso: secrets/CRITICAL/HIGH block (secrets have no ADR escape). Flags: `--scan-only`, `--plan`, `--execute`. See [docs/security-gate.md](docs/security-gate.md). | `/dw-autopilot` (explicit step), enforced by `/dw-generate-pr` |
79
+ | **`/dw-goal "<objective>"`** | Durable objective contract. Uses Codex native `/goal` when available and `.dw/goals/` everywhere for Codex, Copilot, Claude Code, and OpenCode. | `/dw-autopilot` after planning |
79
80
  | **`/dw-find-skills "query"`** | Searches `npx skills` ecosystem, vets, installs. | manual when extending the bundle |
80
81
  | **`/dw-update`** | Updates dev-workflow to latest npm release with rollback snapshot. | manual maintenance |
81
82
  | **`/dw-subtask-start`** | Creates a minimal input packet for a subagent without injecting the parent transcript. | parent agent before delegation |
@@ -85,20 +86,19 @@ These are auto-invoked by Tier 1-3 commands. Available standalone via `/dw-help
85
86
  ## Workflow
86
87
 
87
88
  ```
88
- /dw-autopilot "wish" ------> Runs entire pipeline automatically
89
- (3 gates: PRD approval, Tasks approval, PR confirmation)
89
+ /dw-autopilot "wish" ------> First invocation: PRD → TechSpec → Tasks → STOP
90
+ /dw-autopilot ------> Second invocation: /dw-goal → Commit → PR
90
91
  --- OR step-by-step ---
91
92
 
92
93
  /dw-brainstorm --> /dw-plan --> .dw/spec/prd-{name}/{prd,techspec,tasks}.md
93
94
  |
94
- /dw-run --> atomic commits per task, dependency-aware
95
- |
96
- /dw-qa --> .dw/spec/prd-{name}/QA/ (UI / API / --ai)
97
- |
98
- /dw-review --> L2 PRD coverage + L3 code quality
95
+ /dw-goal --> /dw-run → /dw-review → /dw-qa → /dw-review
99
96
  |
100
97
  /dw-commit + /dw-generate-pr
101
98
 
99
+ Manual alternative after /dw-plan:
100
+ /dw-run → /dw-review → /dw-qa → /dw-review → /dw-commit → /dw-generate-pr
101
+
102
102
  Shortcuts:
103
103
  /dw-intel "question" Query codebase intelligence
104
104
  /dw-redesign-ui "target" Visual redesign of a page or component
@@ -135,7 +135,7 @@ Customize templates locally without losing dev-workflow updates. Drop a file at
135
135
 
136
136
  **What's inside:**
137
137
 
138
- - **Trigger Map** — 15 mappings from user intent ("Implement X", "Bug in Y", "Review my PR", ...) to the `dw-*` command the agent should run. `/dw-autopilot` is the safest default for non-trivial feature requests.
138
+ - **Trigger Map** — mappings from user intent ("Implement X", "Bug in Y", "Review my PR", "resume autopilot", ...) to the `dw-*` command the agent should run. `/dw-autopilot` is the safest default for non-trivial feature requests; `/dw-goal` is the durable execution contract after planning.
139
139
  - **Hard Gates** — reminders that constitution violations (high/critical), missing `dw-verify` PASS, and security failures block downstream commands.
140
140
  - **Escape Hatches** — explicit cases where the agent should NOT auto-trigger (typos, exploration, aesthetic edits, user opt-out).
141
141
 
@@ -168,6 +168,10 @@ npx @brunosps00/dev-workflow update
168
168
 
169
169
  All wrappers point to `.dw/commands/` as the single source of truth.
170
170
 
171
+ ### Durable Goals
172
+
173
+ `/dw-goal` gives every supported agent a portable version of Codex's durable goal workflow. In Codex, it may bridge to the native experimental `/goal` command when `features.goals` is enabled. In every platform, the canonical state is still stored under `.dw/goals/<slug>/` so Copilot, Claude Code, OpenCode, and Codex all follow the same objective, checkpoints, progress log, and stopping condition.
174
+
171
175
  ## Project Structure (after init)
172
176
 
173
177
  ```
@@ -5,6 +5,7 @@ const installDeps = require('../lib/install-deps');
5
5
  const installAzureSkills = require('../lib/install-azure-skills');
6
6
  const installAwsSkills = require('../lib/install-aws-skills');
7
7
  const uninstall = require('../lib/uninstall');
8
+ const setupWslBrowser = require('../lib/setup-wsl-browser');
8
9
 
9
10
  const args = process.argv.slice(2);
10
11
  const command = args[0];
@@ -45,6 +46,7 @@ const HELP_TEXT = `
45
46
  repair Reconcile managed files using the recorded install state
46
47
  subtask Create, complete, consume, and list local subagent handoffs
47
48
  install-deps Install system dependencies (Playwright browsers, MCP servers)
49
+ setup-wsl-browser (WSL) Build the CDP relay on Windows + add the Hyper-V firewall rule so flows can drive the real Windows browser
48
50
  install-azure-skills Opt-in: clone curated Azure skills from MicrosoftDocs/Agent-Skills
49
51
  into .agents/skills/azure/ and register the Microsoft Learn MCP
50
52
  server (HTTP, no-auth). Interactive category selection.
@@ -95,6 +97,9 @@ async function main() {
95
97
  case 'install-deps':
96
98
  installDeps.run();
97
99
  break;
100
+ case 'setup-wsl-browser':
101
+ setupWslBrowser.run();
102
+ break;
98
103
  case 'install-azure-skills':
99
104
  await installAzureSkills.run();
100
105
  break;
package/lib/constants.js CHANGED
@@ -2,7 +2,7 @@ const COMMANDS = {
2
2
  en: [
3
3
  { name: 'dw-adr', description: 'Records an architectural decision and the trade-offs accepted, before they get lost.' },
4
4
  { name: 'dw-analyze-project', description: 'Scans the repo to learn its stack and conventions, then writes the rules other commands rely on.' },
5
- { name: 'dw-autopilot', description: 'Trigger when user asks to implement, build, create, or add a feature non-trivially. Runs full PRD-to-PR pipeline with three gates. Use --from-prd <slug> to resume from an existing PRD (e.g., after a /dw-bugfix safety-valve escalation), skipping Steps 1-4 and starting at GATE 1.' },
5
+ { name: 'dw-autopilot', description: 'Trigger when user asks to implement, build, create, or add a feature non-trivially. First invocation plans and stops; second invocation resumes via dw-goal, then commit and PR.' },
6
6
  { name: 'dw-brainstorm', description: 'Refine an idea against the product\'s existing features. Modes: default ideation, --research (multi-source cited research), --refactor (Fowler code-smell catalog), --onepager, --council.' },
7
7
  { name: 'dw-bugfix', description: 'Trigger when user reports a bug, pastes an error, or describes broken behavior. Triages with three questions, then fixes or routes to PRD.' },
8
8
  { name: 'dw-commit', description: 'Trigger when implementation is complete and pending changes need to be committed. Atomic commits with Conventional Commits messages.' },
@@ -10,6 +10,7 @@ const COMMANDS = {
10
10
  { name: 'dw-find-skills', description: 'Searches the npx skills ecosystem for a skill matching what you need, vets it, and installs it where you choose.' },
11
11
  { name: 'dw-functional-doc', description: 'Maps screens and user flows into a functional doc, validated end-to-end with Playwright.' },
12
12
  { name: 'dw-generate-pr', description: 'Trigger when commits are ready and the branch needs a PR. Pushes branch and opens PR with summary + test plan + hard verify gate.' },
13
+ { name: 'dw-goal', description: 'Trigger when long-running implementation work needs a durable objective. Portable Codex-style goal contract; used by autopilot after planning.' },
13
14
  { name: 'dw-help', description: 'Lists primary commands and the flows that connect them. Pass --advanced to see internal/hidden commands.' },
14
15
  { name: 'dw-context-budget', description: 'Audits context overhead from commands, skills, agents, instructions, and MCPs; recommends token savings.' },
15
16
  { name: 'dw-harness-audit', description: 'Runs a deterministic health scorecard for dev-workflow installation, agents, MCPs, gates, and context discipline.' },
@@ -24,7 +25,7 @@ const COMMANDS = {
24
25
  { name: 'dw-resume', description: 'Trigger when user says "resume work", "where did we stop?", or starts a session in a project with an existing .dw/STATE.md. Reads STATE.md, presents a TLDR, and suggests the next dw-* command.' },
25
26
  { name: 'dw-review', description: 'Trigger when user asks to review code, check quality, or verify PR readiness. Default runs L2 (PRD coverage) + L3 (code quality). Flags --coverage-only / --code-only / --bugfix <slug>.' },
26
27
  { name: 'dw-run', description: 'Trigger when user wants to execute tasks. Default runs all pending in dependency order; \'run <task-id>\' runs one; \'run --resume\' continues an interrupted plan.' },
27
- { name: 'dw-secure-audit', description: 'Unified security audit: OWASP + Trivy SCA/secret/IaC + lockfile + supply-chain compromise check. Hidden; auto-invoked by /dw-review and /dw-generate-pr.' },
28
+ { name: 'dw-secure-audit', description: 'Security Gate: OWASP + Semgrep SAST (diff) + gitleaks secrets + Trivy SCA/IaC + lockfile + supply-chain + outdated. Rigoroso: secrets/CRITICAL/HIGH block. Auto-invoked by /dw-review and /dw-generate-pr, explicit phase in /dw-autopilot, and runnable standalone.' },
28
29
  { name: 'dw-skill-health', description: 'Audits installed skills and agents for bloat, duplication, missing references, and stale or unused modules.' },
29
30
  { name: 'dw-subtask-start', description: 'Creates a minimal input packet for a subagent without injecting the parent transcript.' },
30
31
  { name: 'dw-subtask-complete', description: 'Records a structured subagent handoff with result, files, decisions, risks, verification, and blockers.' },
@@ -34,7 +35,7 @@ const COMMANDS = {
34
35
  'pt-br': [
35
36
  { name: 'dw-adr', description: 'Registra uma decisao arquitetural e os trade-offs aceitos, antes que se percam.' },
36
37
  { name: 'dw-analyze-project', description: 'Escaneia o repo para aprender stack e convencoes, e escreve as regras que os outros commands usam.' },
37
- { name: 'dw-autopilot', description: 'Trigger quando usuario pede pra implementar, criar ou adicionar uma feature nao-trivial. Roda pipeline completo PRD-ao-PR com tres gates. Use --from-prd <slug> para retomar de um PRD existente (ex: apos escalacao do safety valve do /dw-bugfix), pulando Etapas 1-4 e comecando no GATE 1.' },
38
+ { name: 'dw-autopilot', description: 'Trigger quando usuario pede pra implementar, criar ou adicionar uma feature nao-trivial. Primeira invocacao planeja e para; segunda retoma via dw-goal, depois commit e PR.' },
38
39
  { name: 'dw-brainstorm', description: 'Refina uma ideia contra features existentes do produto. Modos: ideacao default, --research (research multi-fonte citada), --refactor (catalogo de code smells Fowler), --onepager, --council.' },
39
40
  { name: 'dw-bugfix', description: 'Trigger quando usuario reporta bug, cola erro ou descreve comportamento quebrado. Tria com tres perguntas, depois corrige ou roteia pra PRD.' },
40
41
  { name: 'dw-commit', description: 'Trigger quando implementacao esta completa e ha mudancas pendentes pra commit. Commits atomicos com mensagens Conventional Commits.' },
@@ -42,6 +43,7 @@ const COMMANDS = {
42
43
  { name: 'dw-find-skills', description: 'Busca no ecossistema npx skills uma skill que resolva o que voce precisa, valida e instala onde voce escolher.' },
43
44
  { name: 'dw-functional-doc', description: 'Mapeia telas e fluxos em um dossie funcional, validado E2E com Playwright.' },
44
45
  { name: 'dw-generate-pr', description: 'Trigger quando commits estao prontos e branch precisa de PR. Push da branch e abre PR com summary + test plan + hard verify gate.' },
46
+ { name: 'dw-goal', description: 'Trigger quando trabalho longo precisa de objetivo duravel. Contrato portavel estilo Codex goal; usado pelo autopilot apos o planejamento.' },
45
47
  { name: 'dw-help', description: 'Lista comandos primarios e fluxos que os conectam. Passe --advanced para ver comandos internos/escondidos.' },
46
48
  { name: 'dw-context-budget', description: 'Audita overhead de contexto em comandos, skills, agentes, instrucoes e MCPs; recomenda economia de tokens.' },
47
49
  { name: 'dw-harness-audit', description: 'Roda um scorecard deterministico da instalacao dev-workflow, agentes, MCPs, gates e disciplina de contexto.' },
@@ -56,7 +58,7 @@ const COMMANDS = {
56
58
  { name: 'dw-resume', description: 'Trigger quando usuario diz "retoma", "onde paramos?" ou comeca sessao num projeto com .dw/STATE.md existente. Le STATE.md, apresenta TLDR e sugere proximo comando dw-*.' },
57
59
  { name: 'dw-review', description: 'Trigger quando usuario pede pra revisar codigo, checar qualidade ou validar prontidao pra PR. Default roda L2 (cobertura PRD) + L3 (qualidade). Flags --coverage-only / --code-only / --bugfix <slug>.' },
58
60
  { name: 'dw-run', description: 'Trigger quando usuario quer executar tasks. Default roda todas pendentes em ordem de dependencia; \'run <task-id>\' roda uma; \'run --resume\' continua plan interrompido.' },
59
- { name: 'dw-secure-audit', description: 'Audit unificado de seguranca: OWASP + Trivy SCA/secret/IaC + lockfile + supply-chain compromise. Hidden; auto-invocado por /dw-review e /dw-generate-pr.' },
61
+ { name: 'dw-secure-audit', description: 'Security Gate: OWASP + Semgrep SAST (diff) + gitleaks secrets + Trivy SCA/IaC + lockfile + supply-chain + outdated. Rigoroso: secrets/CRITICAL/HIGH bloqueiam. Auto-invocado por /dw-review e /dw-generate-pr, fase explicita no /dw-autopilot, e executavel standalone.' },
60
62
  { name: 'dw-skill-health', description: 'Audita skills e agentes instalados por bloat, duplicacao, referencias quebradas e modulos sem uso.' },
61
63
  { name: 'dw-subtask-start', description: 'Cria um input packet minimo para subagente sem injetar transcript bruto do parent.' },
62
64
  { name: 'dw-subtask-complete', description: 'Registra handoff estruturado do subagente com resultado, arquivos, decisoes, riscos, verificacao e bloqueios.' },
@@ -6,9 +6,9 @@ function run() {
6
6
 
7
7
  const deps = [
8
8
  {
9
- name: 'Playwright browsers',
9
+ name: 'Playwright browsers (Chromium + deps)',
10
10
  check: 'npx playwright --version',
11
- install: 'npx playwright install --with-deps',
11
+ install: 'npx playwright install --with-deps chromium',
12
12
  },
13
13
  {
14
14
  name: 'Context7 MCP',
@@ -31,7 +31,44 @@ function run() {
31
31
  ' Windows: choco install trivy (or: scoop install trivy)',
32
32
  ' Docker: docker pull aquasec/trivy:latest (use via alias or wrapper)',
33
33
  '',
34
- 'Once installed, /dw-security-check will use it for CVE, secret, and IaC scanning.',
34
+ 'Once installed, /dw-secure-audit will use it for CVE, secret, and IaC scanning.',
35
+ ],
36
+ },
37
+ {
38
+ name: 'Semgrep (SAST)',
39
+ check: 'semgrep --version',
40
+ install: null,
41
+ instructions: [
42
+ 'Semgrep powers the SAST layer of /dw-secure-audit (semantic analysis of generated code).',
43
+ ' pipx: pipx install semgrep (recommended — isolated)',
44
+ ' pip: python3 -m pip install --user semgrep',
45
+ ' macOS: brew install semgrep',
46
+ ' Docker: docker pull semgrep/semgrep:latest (use via alias or wrapper)',
47
+ '',
48
+ 'The gate runs pinned rulesets (p/security-audit, p/owasp-top-ten, p/secrets) on the diff.',
49
+ ],
50
+ },
51
+ {
52
+ name: 'gitleaks (secret scanner)',
53
+ check: 'gitleaks version',
54
+ install: null,
55
+ instructions: [
56
+ 'gitleaks is the dedicated secret scanner for /dw-secure-audit (any hit blocks the gate).',
57
+ ' macOS: brew install gitleaks',
58
+ ' Linux: download from https://github.com/gitleaks/gitleaks/releases (or: go install github.com/gitleaks/gitleaks/v8@latest)',
59
+ ' Windows: scoop install gitleaks (or: choco install gitleaks)',
60
+ ' Docker: docker pull zricethezav/gitleaks:latest',
61
+ ],
62
+ },
63
+ {
64
+ name: 'syft (SBOM, optional)',
65
+ check: 'syft version',
66
+ install: null,
67
+ instructions: [
68
+ 'syft generates the SBOM for the advisory SBOM/license layer of /dw-secure-audit (optional, non-blocking).',
69
+ ' macOS: brew install syft',
70
+ ' Linux: curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin',
71
+ ' Windows: scoop install syft',
35
72
  ],
36
73
  },
37
74
  {
@@ -93,6 +130,54 @@ function run() {
93
130
  if (failed) parts.push(`${failed} failed`);
94
131
  console.log(` Done! ${parts.join(', ')}`);
95
132
  console.log();
133
+
134
+ checkPlaywrightVersion();
135
+ printBrowserGuidance();
136
+ }
137
+
138
+ // page.screencast (used by /dw-functional-doc to record video, including over CDP) needs
139
+ // Playwright >= 1.60. Warn if the installed version is older.
140
+ function checkPlaywrightVersion() {
141
+ try {
142
+ const raw = execSync('npx playwright --version', { stdio: 'pipe', timeout: 15000 }).toString();
143
+ const match = raw.match(/(\d+)\.(\d+)\.(\d+)/);
144
+ if (!match) return;
145
+ const [, major, minor] = match.map(Number);
146
+ if (major < 1 || (major === 1 && minor < 60)) {
147
+ console.log(` \x1b[33m⚠ Playwright ${match[0]} detected.\x1b[0m /dw-functional-doc video needs >= 1.60 (page.screencast).`);
148
+ console.log(' Upgrade in your project: npm i -D @playwright/test@latest');
149
+ console.log();
150
+ }
151
+ } catch {
152
+ // playwright not resolvable here; the flow runner reports it at runtime
153
+ }
154
+ }
155
+
156
+ function isWsl() {
157
+ if (process.env.WSL_DISTRO_NAME) return true;
158
+ try {
159
+ return /microsoft/i.test(require('fs').readFileSync('/proc/version', 'utf8'));
160
+ } catch {
161
+ return false;
162
+ }
163
+ }
164
+
165
+ function printBrowserGuidance() {
166
+ if (!isWsl()) return;
167
+ const mirrored = require('fs').existsSync('/sys/class/net/loopback0');
168
+ console.log(' Browser automation on WSL (dw-qa / dw-functional-doc / dw-redesign-ui):');
169
+ console.log(' Default: full headless Chromium (desktop-faithful, no WSLg) — works out of the box.');
170
+ console.log(' To drive the real Windows browser, set BROWSER_TEST to its exe path, e.g.');
171
+ console.log(' BROWSER_TEST="/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe".');
172
+ if (mirrored) {
173
+ console.log(' Mirrored networking detected — connects to the Windows browser on 127.0.0.1 directly.');
174
+ } else {
175
+ console.log(' NAT networking — run `npx @brunosps00/dev-workflow setup-wsl-browser` once to build the');
176
+ console.log(' cdp-relay.exe (needs Rust on Windows) and add the Hyper-V firewall rule. Otherwise flows');
177
+ console.log(' fall back to the local headless Chromium (faithful video, no Windows browser).');
178
+ }
179
+ console.log(' Details: .dw/skills/dw-testing-discipline/references/playwright-recipes.md ("Browser on WSL").');
180
+ console.log();
96
181
  }
97
182
 
98
183
  module.exports = { run };
@@ -0,0 +1,149 @@
1
+ const { execSync, spawnSync } = require('child_process');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+
5
+ // Builds the Rust CDP relay (cdp-relay.exe) on Windows and adds the one-time Hyper-V firewall
6
+ // rule so WSL (NAT networking) can drive the real Windows browser over CDP. Idempotent.
7
+ //
8
+ // Why: Chromium binds its debug port to Windows loopback only, and the WSL Hyper-V firewall
9
+ // defaults inbound to Block. A fixed-port relay + one Hyper-V allow rule bridges WSL -> browser.
10
+ // The relay is a tiny static .exe — no Node/Python/PowerShell runtime dependency at run time.
11
+
12
+ const RELAY_PORT = 39222;
13
+ const WSL_VM_CREATOR_ID = '{40E0AC32-46A5-438A-A0B2-2B479E8F2E90}'; // standard WSL VM creator id
14
+ const RULE_NAME = 'dw-cdp-relay';
15
+
16
+ function isWsl() {
17
+ if (process.env.WSL_DISTRO_NAME) return true;
18
+ try {
19
+ return /microsoft/i.test(fs.readFileSync('/proc/version', 'utf8'));
20
+ } catch {
21
+ return false;
22
+ }
23
+ }
24
+
25
+ function winEnv(name) {
26
+ try {
27
+ const out = execSync(`cmd.exe /c "echo %${name}%"`, { stdio: 'pipe' }).toString().split(/\r?\n/)[0].trim();
28
+ return /^[A-Za-z]:\\/.test(out) ? out : null;
29
+ } catch {
30
+ return null;
31
+ }
32
+ }
33
+
34
+ function findWindowsCargo() {
35
+ try {
36
+ const line = execSync('cmd.exe /c where cargo', { stdio: 'pipe' })
37
+ .toString()
38
+ .split(/\r?\n/)
39
+ .map((s) => s.trim())
40
+ .find((s) => /cargo\.exe$/i.test(s));
41
+ if (!line) return null;
42
+ const wsl = execSync(`wslpath -u "${line}"`, { stdio: 'pipe' }).toString().trim();
43
+ return fs.existsSync(wsl) ? { winPath: line, wslPath: wsl } : null;
44
+ } catch {
45
+ return null;
46
+ }
47
+ }
48
+
49
+ function copyCrate(srcDir, destWslDir) {
50
+ fs.mkdirSync(path.join(destWslDir, 'src'), { recursive: true });
51
+ fs.copyFileSync(path.join(srcDir, 'Cargo.toml'), path.join(destWslDir, 'Cargo.toml'));
52
+ fs.copyFileSync(path.join(srcDir, 'src', 'main.rs'), path.join(destWslDir, 'src', 'main.rs'));
53
+ }
54
+
55
+ function run() {
56
+ console.log('\n dev-workflow setup-wsl-browser');
57
+ console.log(` ${'='.repeat(40)}\n`);
58
+
59
+ if (!isWsl()) {
60
+ console.log(' This command is only needed on WSL. On native Windows/macOS/Linux, flows use the local browser directly.');
61
+ return;
62
+ }
63
+
64
+ const localAppData = winEnv('LOCALAPPDATA');
65
+ if (!localAppData) {
66
+ console.log(' \x1b[31m✗\x1b[0m Could not resolve %LOCALAPPDATA% on Windows. Is Windows interop enabled?');
67
+ return;
68
+ }
69
+ const destWin = `${localAppData}\\dev-workflow`;
70
+ const destWsl = execSync(`wslpath -u "${destWin}"`, { stdio: 'pipe' }).toString().trim();
71
+ const srcWslDir = `${destWsl}/cdp-relay-src`;
72
+ const srcWinDir = `${destWin}\\cdp-relay-src`;
73
+
74
+ // 1) Build the relay with the Windows Rust toolchain.
75
+ const cargo = findWindowsCargo();
76
+ if (!cargo) {
77
+ console.log(' \x1b[33m—\x1b[0m No Windows `cargo` found (where cargo). Install Rust on Windows: https://rustup.rs');
78
+ console.log(' Without the relay, WSL flows fall back to the local headless Chromium (faithful, no Windows browser).');
79
+ return;
80
+ }
81
+
82
+ const crateSrc = path.join(__dirname, '..', 'scaffold', 'scripts', 'cdp-relay');
83
+ if (!fs.existsSync(path.join(crateSrc, 'Cargo.toml'))) {
84
+ console.log(` \x1b[31m✗\x1b[0m Relay crate source not found at ${crateSrc}`);
85
+ return;
86
+ }
87
+
88
+ process.stdout.write(' Building cdp-relay.exe (Windows cargo, release)...');
89
+ try {
90
+ fs.mkdirSync(destWsl, { recursive: true });
91
+ copyCrate(crateSrc, srcWslDir);
92
+ execSync(`"${cargo.wslPath}" build --release --manifest-path "${srcWinDir}\\Cargo.toml"`, {
93
+ stdio: 'pipe',
94
+ timeout: 180000,
95
+ });
96
+ fs.copyFileSync(path.join(srcWslDir, 'target', 'release', 'cdp-relay.exe'), path.join(destWsl, 'cdp-relay.exe'));
97
+ console.log(' \x1b[32m✓\x1b[0m');
98
+ console.log(` ${destWin}\\cdp-relay.exe`);
99
+ } catch (err) {
100
+ console.log(' \x1b[31m✗\x1b[0m');
101
+ console.log(` ${String(err.message).split('\n')[0]}`);
102
+ return;
103
+ }
104
+
105
+ // 2) Add the Hyper-V firewall inbound rule (one-time, elevated -> UAC prompt).
106
+ console.log(`\n Adding Hyper-V firewall rule for TCP ${RELAY_PORT} (a UAC prompt will appear — accept it)...`);
107
+ const inner = [
108
+ `Remove-NetFirewallHyperVRule -Name '${RULE_NAME}' -ErrorAction SilentlyContinue;`,
109
+ `New-NetFirewallHyperVRule -Name '${RULE_NAME}' -DisplayName 'dev-workflow cdp-relay'`,
110
+ `-Direction Inbound -Action Allow -VMCreatorId '${WSL_VM_CREATOR_ID}' -Protocol TCP -LocalPorts ${RELAY_PORT}`,
111
+ ].join(' ');
112
+ try {
113
+ execSync(
114
+ `powershell.exe -NoProfile -Command "Start-Process powershell -Verb RunAs -WindowStyle Hidden -ArgumentList '-NoProfile','-Command',\\"${inner}\\""`,
115
+ { stdio: 'pipe', timeout: 60000 },
116
+ );
117
+ } catch {
118
+ // Start-Process returns before the elevated process finishes; verify below regardless.
119
+ }
120
+
121
+ // 3) Verify.
122
+ let ok = false;
123
+ for (let i = 0; i < 10 && !ok; i += 1) {
124
+ try {
125
+ const out = execSync(
126
+ `powershell.exe -NoProfile -c "Get-NetFirewallHyperVRule -Name '${RULE_NAME}' -ErrorAction SilentlyContinue | Select-Object -Expand Action"`,
127
+ { stdio: 'pipe', timeout: 15000 },
128
+ ).toString();
129
+ ok = /Allow/i.test(out);
130
+ } catch {
131
+ ok = false;
132
+ }
133
+ if (!ok) execSync('sleep 1');
134
+ }
135
+
136
+ console.log(` ${'='.repeat(40)}`);
137
+ if (ok) {
138
+ console.log(' \x1b[32m✓ Done.\x1b[0m The Windows browser is reachable from WSL over CDP.');
139
+ console.log(` Set BROWSER_TEST to a Windows browser exe to use it, e.g.`);
140
+ console.log(' BROWSER_TEST="/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"');
141
+ } else {
142
+ console.log(' \x1b[33m⚠ Hyper-V firewall rule not confirmed.\x1b[0m UAC may have been declined, or this Windows lacks');
143
+ console.log(' Hyper-V firewall cmdlets. Flows will fall back to the local headless Chromium (faithful video, no');
144
+ console.log(' Windows browser). You can also enable mirrored networking instead. Re-run to retry.');
145
+ }
146
+ console.log();
147
+ }
148
+
149
+ module.exports = { run, RELAY_PORT };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brunosps00/dev-workflow",
3
- "version": "1.0.5",
3
+ "version": "1.1.0",
4
4
  "description": "AI-driven development workflow commands for any project. Scaffolds a complete PRD-to-PR pipeline with multi-platform AI assistant support.",
5
5
  "bin": {
6
6
  "dev-workflow": "./bin/dev-workflow.js"
@@ -13,7 +13,7 @@ Before picking a command from the Trigger Map, gauge the change's actual scope.
13
13
  |------|---------------------|----------|
14
14
  | **Small** | ≤3 files, no migration, no new endpoint, can be summarized in one sentence. Examples: typo, log message, single-line config, dependency bump, version pin. | Just do it inline. No `dw-*` command. |
15
15
  | **Medium** | Clear feature or bug, <10 numbered tasks expected, single component or single service, no architectural decisions. Examples: add a form field with validation, fix a regression in a known module, wire a new API endpoint into an existing handler. | `/dw-bugfix` (for bugs) or `/dw-plan` (for features) — straight, not via `/dw-autopilot`. |
16
- | **Large** | Multi-component feature, ≥10 tasks expected, touches multiple modules, has user-visible UX surface AND backend. Examples: add a new entity end-to-end (model + migration + API + UI), introduce a third-party integration, redesign a flow. | `/dw-autopilot "<wish>"` — full PRD → TechSpec → Tasks → Run → QA → Review → Commit → PR pipeline with three gates. |
16
+ | **Large** | Multi-component feature, ≥10 tasks expected, touches multiple modules, has user-visible UX surface AND backend. Examples: add a new entity end-to-end (model + migration + API + UI), introduce a third-party integration, redesign a flow. | `/dw-autopilot "<wish>"` — first invocation plans and stops; second invocation resumes via `/dw-goal` for Run → Review → QA/Fix → Review, then Commit → PR. |
17
17
  | **Complex** | New domain, ambiguous requirements, architectural decision required, regulatory or compliance surface, or scope that spans multiple PRDs. Examples: introduce event sourcing, rebuild auth, multi-tenancy, a new product line. | `/dw-brainstorm "<idea>"` first (auto-dispatches research/council modes), then `/dw-plan --council` so the techspec stage runs the multi-advisor debate. |
18
18
 
19
19
  **Safety valve:** if you start in Small or Medium but the work reveals it's actually Large (the inline listing exceeds 5 steps, or `/dw-bugfix` triggers its `Step 5.0` valve), STOP and escalate. There is no flag to bypass. Escalation is the correct outcome.
@@ -26,6 +26,7 @@ Before picking a command from the Trigger Map, gauge the change's actual scope.
26
26
  |--------------------------------------|--------------|
27
27
  | "Implement X" / "Build Y" / "Add feature Z" / "I need ..." / "Create ..." | `/dw-autopilot "X"` |
28
28
  | "Autopilot this PRD" / "Take this PRD to PR" / continue a bugfix escalation autonomously | `/dw-autopilot --from-prd <slug>` (existing PRD at `.dw/spec/<slug>/`) |
29
+ | "Resume autopilot" / "continue after plan" / `autopilot-state.json` has `status: plan_complete` | `/dw-autopilot` (or `/dw-goal --from-autopilot <slug>` if the user specifically asks for the goal step) |
29
30
  | Pasted error / "X is broken" / "Bug in Y" / failing test screenshot | `/dw-bugfix "X"` |
30
31
  | "Plan this feature" / "Write a PRD + techspec + tasks" | `/dw-plan "X"` |
31
32
  | "Write a PRD for X" / "Spec out Y" | `/dw-plan prd "X"` |
@@ -33,6 +34,7 @@ Before picking a command from the Trigger Map, gauge the change's actual scope.
33
34
  | "Break this into tasks" | `/dw-plan tasks` |
34
35
  | "Run this task" (with task ID) | `/dw-run <ID>` |
35
36
  | "Run all pending tasks" / "Execute the plan" | `/dw-run` |
37
+ | "Run this as a goal" / "durable goal" / "long-running objective" | `/dw-goal "<objective>"` |
36
38
  | "Continue where I left off" | `/dw-run --resume` |
37
39
  | "Pause work" / "End the session" / "Save where we are" | `/dw-pause` |
38
40
  | "Resume" / "Where did we stop?" / "Pick up where we left off" | `/dw-resume` |
@@ -63,7 +65,7 @@ Before picking a command from the Trigger Map, gauge the change's actual scope.
63
65
  | "Install Azure skills" / "Setup Microsoft docs MCP" / "Add Azure expertise" / "I'm going to work on Azure" | `/dw-install-azure-skills` |
64
66
  | "Install AWS skills" / "Setup AWS MCP" / "Add AWS expertise" / "I'm going to work on AWS" | `/dw-install-aws-skills` |
65
67
 
66
- **Priority:** when in doubt between two commands, `/dw-autopilot` is the safest default for any non-trivial feature request — it composes the rest.
68
+ **Priority:** when in doubt between two commands, `/dw-autopilot` is the safest default for any non-trivial feature request. If a planned autopilot has already stopped with `status: plan_complete`, resume it instead of starting a new plan; the execution phase is owned by `/dw-goal`.
67
69
 
68
70
  ## Hard Gates (the commands enforce these — don't bypass)
69
71
 
@@ -131,12 +133,12 @@ Skills are compact protocols first. Read the `SKILL.md` entrypoint, then load fi
131
133
  ## Workflow Reference
132
134
 
133
135
  ```
134
- /dw-autopilot "wish" ────► Runs entire pipeline automatically
135
- (3 gates: PRD approval, Tasks approval, PR confirmation)
136
+ /dw-autopilot "wish" ────► First invocation plans: PRD → TechSpec → Tasks → STOP
137
+ /dw-autopilot ────► Second invocation resumes: /dw-goal → Commit → PR
136
138
 
137
139
  --- OR step-by-step ---
138
140
 
139
- /dw-brainstorm ─► /dw-plan ─► /dw-run ─► /dw-qa ─► /dw-review ─► /dw-commit ─► /dw-generate-pr
141
+ /dw-brainstorm ─► /dw-plan ─► /dw-goal ─► /dw-commit ─► /dw-generate-pr
140
142
  ```
141
143
 
142
144
  Full command list and contextual help: `/dw-help`.
@@ -827,6 +827,27 @@ If after the heuristics nothing crosses the bar (small codebase, low churn, no i
827
827
 
828
828
  **Refresh cadence:** users re-run `/dw-analyze-project` whenever rules drift. Step 9 refreshes auto sections while keeping preserved entries. There is no separate refresh-only command.
829
829
 
830
+ ### Step 10: Design authority (DESIGN.md) — frontend projects only
831
+
832
+ Run this when a frontend was detected (React/Vue/Angular/Svelte/Tailwind/CSS) so `dw-ui-discipline`'s
833
+ grounding question 1 ("where do design decisions come from?") has a project authority to defer to. This
834
+ closes the loop the grounding only *reads* today.
835
+
836
+ 1. **Check for an existing authority first.** If `DESIGN.md`, `BRAND.md`, or `STYLE_GUIDE.md` already
837
+ exists at the project (or a frontend module) root, do NOT overwrite — note its location and stop.
838
+ 2. **Detect design tokens** in priority order: Tailwind `theme`/`@theme` (colors, fontFamily, spacing,
839
+ radius), CSS custom properties in `globals.css`/`theme.css`/`tokens.css`, MUI/Chakra theme exports,
840
+ shadcn `components.json`, Storybook theme. Read the real values — do not invent.
841
+ 3. **If tokens exist:** synthesize `DESIGN.md` at the frontend root capturing what the project ALREADY
842
+ uses — palette (with the actual hex/oklch values and token names), typography (families, scale,
843
+ weights), spacing/radius scale, and any component conventions observed. Head it with:
844
+ `> Generated by /dw-analyze-project from existing tokens on <date>. Curate before treating as canon.`
845
+ 4. **If no tokens exist:** do NOT fabricate a palette. Recommend bootstrapping from
846
+ `dw-ui-discipline/references/curated-defaults.md` and record that recommendation in the rules index.
847
+ 5. Reference the new `DESIGN.md` from `.dw/rules/<frontend-module>.md` so downstream commands find it.
848
+
849
+ This step is additive and reversible; it never edits component code, only documents what is there.
850
+
830
851
  ## Quality Checklist
831
852
 
832
853
  Before declaring the analysis complete, verify:
@@ -850,6 +871,7 @@ Before declaring the analysis complete, verify:
850
871
  - [ ] All file paths in rules reference real, existing files
851
872
  - [ ] Step 8 (constitution) offered and resolved (A/B/C)
852
873
  - [ ] Step 9 (concerns map) presented candidates, awaited approval, wrote `.dw/rules/concerns.md` (or noted no signals)
874
+ - [ ] Step 10 (design authority) ran for frontend projects: existing authority respected, or `DESIGN.md` generated from real tokens, or curated-defaults bootstrap recommended
853
875
  - [ ] Preserved-marker blocks in concerns.md kept verbatim on refresh
854
876
  - [ ] Topology analysis completed (god nodes, coupling metrics, dependency graph)
855
877
  - [ ] Critical nodes table generated with Ca, Ce, instability