Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .changeset/add-watch-command.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
"dev-workflows": minor
---

### CLI

- Add `devw watch` command — watches `.dwf/` for YAML changes and recompiles automatically
- Extract `executePipeline` from compile with structured return types (`BridgeResult`, `CompileResult`)
- Add `reload` icon to shared `ICONS` in `utils/ui.ts`
- Add chokidar v3 dependency for filesystem watching

### Documentation

- Add `devw watch` to README commands table
- Add `docs/commands/watch.mdx` for Mintlify docs site
- Register watch page in `docs.json` navigation

### Landing

- Add watch tab to terminal demo section
- Add global `*:focus-visible` with `var(--accent)` for consistent focus styling
- Fix active tab border to use `var(--accent)`
5 changes: 3 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ pnpm dev # dev mode

- `docs/internal/CLI_SPEC.md` → v0.1 specification (COMPLETE)
- `docs/internal/CLI_SPEC_v0.2.md` → v0.2 specification (COMPLETE)
- `docs/internal/CLI_SPEC_v0.2.1.md` → v0.2.1 UX polish specification (ACTIVE — implement this)
- `docs/internal/DOCS_SPEC.md` → Mintlify documentation spec
- `docs/internal/CLI_SPEC_v0.2.1.md` → v0.2.1 UX polish specification (COMPLETE)
- `docs/internal/DOCS_SPEC.md` → Mintlify documentation spec (COMPLETE)
- `docs/internal/WATCH_SPEC.md` → v0.3 watch mode specification (ACTIVE — implement this)
- `docs/internal/DECISIONS.md` → accepted decisions (source of truth if conflict)
- `docs/internal/` is gitignored — internal specs not published

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ You define rules in YAML. The compiler generates each editor's native format. Ch
| `devw add <block>` | Install a prebuilt rule block |
| `devw remove <block>` | Remove a rule block |
| `devw compile` | Generate editor-specific rule files |
| `devw watch` | Watch `.dwf/` and recompile on changes |
| `devw doctor` | Validate config and detect rule drift |
| `devw list rules` | List all active rules |
| `devw list blocks` | List installed blocks |
Expand Down
10 changes: 6 additions & 4 deletions apps/landing/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
}
::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }
* { scrollbar-width: thin; scrollbar-color: var(--border) transparent; }
*:focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; }

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
Expand Down Expand Up @@ -1050,8 +1051,8 @@
}
.term-tab.active {
color: var(--accent);
border-bottom-color: var(--accent);
background: rgba(34,211,126,0.03);
border: 1px solid var(--accent);
background: rgba(34,211,126,0.08);
}
.term-tab-arrow {
font-weight: 700;
Expand Down Expand Up @@ -1439,7 +1440,7 @@
<!-- ═══════ NAV ═══════ -->
<nav>
<div class="nav-left">
<a href="#" class="nav-logo">
<a href="/" class="nav-logo">
<img src="dark-logo-sm.png" alt="dev-workflows" class="logo-img">
</a>
<div class="nav-links">
Expand Down Expand Up @@ -1731,7 +1732,7 @@ <h1>
<div class="section-label">See it in action</div>
<div class="section-title">Every command at a glance.</div>
<p class="section-sub">
Six commands. That's the entire CLI. Click a tab to see what each one does.
Seven commands. That's the entire CLI. Click a tab to see what each one does.
</p>
</div>

Expand All @@ -1744,6 +1745,7 @@ <h1>
<button class="term-tab active" onclick="switchTermTab('init', this)"><span class="term-tab-arrow">›</span> init</button>
<button class="term-tab" onclick="switchTermTab('add', this)"><span class="term-tab-arrow">›</span> add</button>
<button class="term-tab" onclick="switchTermTab('compile', this)"><span class="term-tab-arrow">›</span> compile</button>
<button class="term-tab" onclick="switchTermTab('watch', this)"><span class="term-tab-arrow">›</span> watch</button>
<button class="term-tab" onclick="switchTermTab('doctor', this)"><span class="term-tab-arrow">›</span> doctor</button>
<button class="term-tab" onclick="switchTermTab('list', this)"><span class="term-tab-arrow">›</span> list</button>
<button class="term-tab" onclick="switchTermTab('remove', this)"><span class="term-tab-arrow">›</span> remove</button>
Expand Down
15 changes: 15 additions & 0 deletions apps/landing/scripts/terminal.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,21 @@ const TERM_TABS = {
{ html: '<span class="term-success"> Done.</span> <span class="term-muted">3 files compiled in 42ms</span>', delay: 350 },
]
},
watch: {
comment: '# Watch for changes and recompile automatically',
lines: [
{ html: '<span class="term-prompt">$</span> <span class="term-cmd">devw watch</span>', delay: 0 },
{ html: '', delay: 400 },
{ html: ' \uD83D\uDC40 <span class="term-success">Watching .dwf/ for changes...</span>', delay: 500 },
{ html: '<span class="term-muted"> Running initial compile...</span>', delay: 350 },
{ html: '', delay: 300 },
{ html: '<span class="term-success"> \u2714</span> claude <span class="term-muted">\u2192</span> <span class="term-file">CLAUDE.md</span>', delay: 300 },
{ html: '<span class="term-success"> \u2714</span> cursor <span class="term-muted">\u2192</span> <span class="term-file">.cursor/rules/devworkflows.mdc</span>', delay: 250 },
{ html: '<span class="term-muted"> Done in 21ms</span>', delay: 250 },
{ html: '', delay: 400 },
{ html: '<span class="term-muted"> Waiting for changes... (Ctrl+C to stop)</span>', delay: 350 },
]
},
doctor: {
comment: '# Validate config and diagnose issues',
lines: [
Expand Down
62 changes: 62 additions & 0 deletions docs/commands/watch.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
title: "devw watch"
description: "Watch .dwf/ and recompile automatically on changes"
---

```bash
devw watch
```

Watches your `.dwf/` directory and recompiles automatically whenever a rule file changes. This keeps your editor config files always in sync without running `devw compile` manually.

## What it watches

All `.yml` and `.yaml` files inside `.dwf/`, including:

- `.dwf/config.yml`
- `.dwf/rules/**/*.yml`

## Behavior

1. Runs an initial compile on startup
2. Watches `.dwf/` for file changes (add, edit, delete)
3. Debounces rapid changes into a single recompile
4. Prints per-bridge results after each compile
5. Errors are printed but never stop the watch process
6. `Ctrl+C` exits cleanly

## Flags

| Flag | Description |
|------|-------------|
| `--tool claude` | Recompile only a specific bridge |

## Output

### On change

```
⟳ Change detected: .dwf/rules/conventions.yml
Compiling...
✔ claude → CLAUDE.md
✔ cursor → .cursor/rules/devworkflows.mdc
✔ gemini → GEMINI.md
Done in 42ms
```

### On error

```
✖ Duplicate rule id "react-no-inline-styles"
Watch mode is still running. Fix the error and save again.
```

## Examples

```bash
# Watch all configured tools
devw watch

# Watch only Claude bridge
devw watch --tool claude
```
1 change: 1 addition & 0 deletions docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"pages": [
"commands/init",
"commands/compile",
"commands/watch",
"commands/doctor",
"commands/explain",
"commands/add",
Expand Down
5 changes: 3 additions & 2 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,13 @@
"build": "tsc",
"dev": "tsc --watch",
"typecheck": "tsc --noEmit",
"test": "tsc -p tsconfig.test.json && find .test-build/tests -name '*.test.js' -exec node --test {} +",
"test": "tsc && tsc -p tsconfig.test.json && find .test-build/tests -name '*.test.js' -exec node --test {} +",
"test:unit": "tsc -p tsconfig.test.json && find .test-build/tests -name '*.test.js' -not -path '*e2e*' -exec node --test {} +",
"test:e2e": "tsc -p tsconfig.test.json && find .test-build/tests/e2e -name '*.test.js' -exec node --test {} +"
"test:e2e": "tsc && tsc -p tsconfig.test.json && find .test-build/tests/e2e -name '*.test.js' -exec node --test {} +"
},
"dependencies": {
"@inquirer/prompts": "^7.0.0",
"chokidar": "^3.6.0",
"commander": "^13.0.0",
"yaml": "^2.7.0",
"chalk": "^5.4.0"
Expand Down
Loading