Flows YAML — loader, file watcher, reload endpoint #1061

Closed
opened 2026-05-10 15:38:48 +00:00 by claude-desktop · 0 comments
Collaborator

User story

As the platform operator, I want flow definitions to live as .yml files on disk under flows/defaults/ and flows/custom/, so that I can author, diff, and version-control them with git instead of editing JSON in a database.

Acceptance criteria

Loader

  • New module apps/server/src/domain/flows-yaml/loader.ts parses every *.yml under flows/defaults/ and flows/custom/ at boot.
  • flows/custom/<name>.yml shadows flows/defaults/<name>.yml (same name key wins from custom).
  • Parse failures are logged with file path + YAML error; the bad file is skipped, last-good copy stays active.
  • Loader exposes listFlows() and getFlow(name) to the executor and HTTP layer.

File watcher

  • chokidar (or bun fs.watch) watches both directories with 200ms debounce.
  • On any add/change/unlink, loader re-reads only the affected file and broadcasts flow.changed { name } over SSE.
  • Watcher survives temporary parse errors without unmounting.

Reload endpoint

  • POST /flows/reload forces a full re-scan; returns { loaded, errors[] }.
  • Endpoint gated by existing dashboard auth.

Tests

  • Unit: parse minimal flow, parse with overlay, parse with bad YAML, custom overrides default.
  • Integration: write file → SSE event fires; bad write keeps prior version active.

Out of scope

  • Schema validation beyond YAML syntax (covered by #flows-3 / op registry + #flows-9 schema pipeline).
  • Editor / UI (covered by #flows-11..13).
  • Git commit-and-push from the server (deferred).

References

  • Spec: docs/specs/flows-yaml.md §3, §10.
  • Replaces: in-memory flows table loader at apps/server/src/domain/flows/flow-dispatch.ts:561.
## User story As the platform operator, I want flow definitions to live as `.yml` files on disk under `flows/defaults/` and `flows/custom/`, so that I can author, diff, and version-control them with git instead of editing JSON in a database. ## Acceptance criteria ### Loader - [ ] New module `apps/server/src/domain/flows-yaml/loader.ts` parses every `*.yml` under `flows/defaults/` and `flows/custom/` at boot. - [ ] `flows/custom/<name>.yml` shadows `flows/defaults/<name>.yml` (same `name` key wins from custom). - [ ] Parse failures are logged with file path + YAML error; the bad file is skipped, last-good copy stays active. - [ ] Loader exposes `listFlows()` and `getFlow(name)` to the executor and HTTP layer. ### File watcher - [ ] `chokidar` (or bun fs.watch) watches both directories with 200ms debounce. - [ ] On any add/change/unlink, loader re-reads only the affected file and broadcasts `flow.changed { name }` over SSE. - [ ] Watcher survives temporary parse errors without unmounting. ### Reload endpoint - [ ] `POST /flows/reload` forces a full re-scan; returns `{ loaded, errors[] }`. - [ ] Endpoint gated by existing dashboard auth. ### Tests - [ ] Unit: parse minimal flow, parse with overlay, parse with bad YAML, custom overrides default. - [ ] Integration: write file → SSE event fires; bad write keeps prior version active. ## Out of scope - Schema validation beyond YAML syntax (covered by #flows-3 / op registry + #flows-9 schema pipeline). - Editor / UI (covered by #flows-11..13). - Git commit-and-push from the server (deferred). ## References - Spec: `docs/specs/flows-yaml.md` §3, §10. - Replaces: in-memory `flows` table loader at `apps/server/src/domain/flows/flow-dispatch.ts:561`.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/claude-hooks#1061
No description provided.