Build V1 as a TypeScript CLI-first local sidecar with a small TUI dashboard.
Do not build OAuth, LLM policy, cloud sync, or dynamic plugins in V1. Keep real provider work experimental, opt-in, and outside the default product loop.
The first shippable product is:
sample events -> safe workflow-state -> deterministic policy -> fake/local adapter -> TUI + logs
Use a compact terminal UI for vibe dev --fake.
It should not occupy much space. Default mode should feel like a small status widget, not a full-screen app.
It should show only six things:
- Current workflow state.
- Current ambient intent / fake track.
- Adapter connection status.
next/ change round.- play / pause.
- settings.
This is enough for V1. It proves whether the ambient state loop feels useful without forcing a browser UI or real provider setup.
┌─ Vibe ─────────────────────────────────┐
│ debugging 0.78 blocked fake:ready │
│ now low-vocal steady local-ambient-02 │
│ space play/pause n next , settings │
└────────────────────────────────────────┘
Expanded debug view is optional and should appear only after pressing e or running vibe explain.
space: play/pause fake adapter state.n: choose the next candidate from the sanitized fake/local candidate set.,: open compact settings menu.e: show policy explanation.s: print current workflow-state JSON summary.q: quit.
Settings menu should be tiny:
┌─ Settings ───────────────┐
│ adapter fake │
│ volume simulated │
│ mode compact │
│ privacy strict │
│ esc close │
└──────────────────────────┘
V1 settings are local-only and mostly toggles for the fake loop. No provider login appears in settings until provider adapters exist.
- No web dashboard in V1.
- No desktop tray in V1.
- No platform connection screen in V1.
- No OAuth UI in V1.
Platform connection can appear later as a disabled status row:
Provider none default loop uses fake adapter
TypeScript on Node.js.
Reason: best fit for CLI package distribution, JSON schema work, MCP SDK later, and plugin ecosystem.
Use npm metadata and keep the package runnable through npx.
Local development can use pnpm if desired, but published UX should be:
npx coding-vibe init
npx coding-vibe dev --fakeUse commander.
Reason: boring, stable, obvious to contributors.
Use ink only if we actually need live keyboard handling.
Fallback: start with plain terminal rendering using readline and process.stdin.setRawMode.
Decision for V1: plain terminal first. Add ink only if the manual rendering gets messy.
Use ajv for JSON Schema validation.
Ship schemas/workflow-state.schema.json.
Use vitest.
Required test areas:
- Schema validation.
- Privacy redaction.
- Atomic file handoff.
- Policy precedence.
- Fake adapter behavior.
- CLI command smoke tests.
Use tsup for building CLI output.
Reason: simple TypeScript bundling without heavy config.
MCP is implemented as a safe local surface, not a provider-control surface.
Current command:
vibe mcpIt starts a stdio MCP server with tools for local state inspection, policy explanation, listing supported workflow modes, and setting a workflow vibe.
It must not expose:
provider APIs
OAuth tokens
cookies
raw source code
raw logs
browser data
arbitrary shell access
Reason: MCP is useful only if it reinforces the trust boundary. It lets an agent express ambient workflow intent without turning Coding Vibe into an arbitrary automation proxy.
.
├── package.json
├── tsconfig.json
├── tsup.config.ts
├── vitest.config.ts
├── README.md
├── LICENSE
├── LICENSE.schemas
├── schemas/
│ └── workflow-state.schema.json
├── examples/
│ ├── workflow-state.min.json
│ ├── workflow-state.full.json
│ ├── policy.default.json
│ └── candidates.fake.json
├── src/
│ ├── cli.ts
│ ├── commands/
│ │ ├── init.ts
│ │ ├── dev.ts
│ │ ├── state.ts
│ │ ├── validate.ts
│ │ ├── explain.ts
│ │ └── mcp.ts
│ ├── schema/
│ │ ├── load-schema.ts
│ │ └── validate-state.ts
│ ├── state/
│ │ ├── atomic-write.ts
│ │ ├── read-state.ts
│ │ └── redact.ts
│ ├── watcher/
│ │ └── fake-watcher.ts
│ ├── policy/
│ │ ├── evaluate-policy.ts
│ │ └── default-policy.ts
│ ├── adapters/
│ │ ├── types.ts
│ │ ├── fake-adapter.ts
│ │ └── local-adapter.ts
│ └── tui/
│ ├── dashboard.ts
│ └── keybindings.ts
└── tests/
├── schema.test.ts
├── privacy.test.ts
├── atomic-write.test.ts
├── policy.test.ts
├── fake-adapter.test.ts
└── cli.test.ts
type WorkflowMode =
| "unknown"
| "deep_work"
| "planning"
| "debugging"
| "reviewing"
| "writing"
| "waiting_ci"
| "idle";
type WorkflowState = {
schema_version: "1.0.0";
producer: "coding-vibe";
generated_at: string;
ttl_ms: number;
workflow: {
mode: WorkflowMode;
phase?: string;
momentum?: "moving" | "blocked" | "waiting" | "unknown";
confidence: number;
signals: string[];
};
safety: {
redactions_applied: string[];
forbidden_fields_seen: boolean;
};
};type AdapterCapability =
| "pause"
| "next"
| "candidate_selection"
| "play_local_file"
| "personalized_seed"
| "no_song_level_control";
type SafeCandidate = {
id: string;
labels: string[];
traits: {
energy?: "low" | "medium" | "high";
tempo?: "slow" | "medium" | "fast";
vocals?: "none" | "low" | "medium" | "high";
familiarity?: "new" | "familiar" | "heavy_rotation";
};
source: "fake" | "local_library" | "personalized_seed";
};
type MusicAdapter = {
id: string;
stability: "official" | "semi_official" | "unofficial" | "local_only" | "fake";
capabilities(): AdapterCapability[];
listCandidates(state: WorkflowState): Promise<SafeCandidate[]>;
playCandidate(candidateId: string, reason: string): Promise<void>;
pause(): Promise<void>;
next(): Promise<SafeCandidate | null>;
};V1 ships only fake and maybe local.
Provider plugins such as Spotify, NetEase Cloud Music, QQ Music, MPD, and VLC come later.
Creates:
.vibe/policy.json.vibe/candidates.fake.json.vibe/vibe-state.json
It must not inspect source files.
Runs:
- Fake watcher.
- Safe state writer.
- Policy evaluator.
- Fake adapter.
- TUI dashboard.
It cycles through sample workflow events so users can see state transitions immediately.
Prints current state summary:
mode=debugging confidence=0.78 generated=21s ago redactions=0
signals: pytest failed twice; same module edited repeatedly
Prints why the adapter did what it did:
matched_rule=debugging-caution
reason=workflow.mode=debugging matched rule debugging-caution
action=fake_music_state mood=low_distraction candidate=local-ambient-02
Validates:
- State schema.
- Policy file.
- Candidate file.
- Privacy rules.
Placeholder in first slice. Implement after CLI loop works.
- Create package metadata.
- Add TypeScript config.
- Add Vitest.
- Add
vibeCLI entrypoint. - Add
vibe --help.
Definition of done:
npm testruns.npm run buildruns.node dist/cli.js --helpworks.
- Add
workflow-state.schema.json. - Add minimal and full example states.
- Add
validate-statemodule.
Definition of done:
- Valid examples pass.
- Invalid examples fail with useful messages.
- Add ordered first-match policy evaluator.
- Add fallback rule requirement.
- Add explain output.
Definition of done:
- First match wins.
- No match uses fallback.
- Same input produces same output.
- Add fake event source.
- Convert events to safe state.
- Write
vibe-state.json.tmpthen rename.
Definition of done:
- Partial temp file is never read.
- Expired state becomes unknown.
- Forbidden fields are dropped.
- Add fake candidate list.
- Add play/pause/next behavior.
- Write
adapter-log.jsonl.
Definition of done:
- Adapter never calls network.
- Adapter only receives safe candidate IDs.
nextrotates candidates deterministically.
- Implement
init. - Implement
dev --fake. - Implement
state. - Implement
explain. - Implement
validate. - Add
mcpplaceholder.
Definition of done:
- New user can run the quick start from an empty directory.
- Time to first state is under 2 minutes.
- Add terminal dashboard.
- Add keybindings:
space,n,,,e,s,q. - Keep output readable without color.
- Keep default UI compact enough to sit beside an editor or terminal pane.
Definition of done:
- TUI works in a normal terminal.
- Non-interactive CLI commands still work in CI.
- Add quick start.
- Add privacy model.
- Add non-goals.
- Add external validation task script.
Definition of done:
- A tester can complete the scripted flow without private explanation.
TUI is the right V1 front end.
Reason:
- The first users are developers already in terminals.
- It keeps the product local and inspectable.
- It avoids browser UI, auth screens, and styling work.
- It tests the core loop without requiring real provider integration.
The UI is intentionally small:
- Current music or fake candidate.
- Current workflow state.
- Connection status.
- Next round.
- Play/pause.
- Settings.
- Explain.
That is enough. Anything more belongs after V1 validation.
- TUI key handling can be flaky on Windows terminals.
- Fake watcher might feel too artificial unless sample events are realistic.
- Users may ask for real provider connection before workflow-state value is proven.
- Experimental provider adapters can blur the V1 trust story if they are presented as default product surface.
vibepackage name may be unavailable.
- Final package name:
coding-vibe. - Whether
localadapter should ship before external provider adapters become more prominent. - Whether to use
inkafter plain terminal prototype. - Whether experimental Spotify and NetEase commands should move behind plugin/package boundaries before distribution.
Start Slice 1 and Slice 2.
Do not start OAuth, broad provider plugins, or LLM selection until the CLI/TUI fake loop is validated. Keep the existing MCP server limited to safe local state tools, and keep existing Spotify/NetEase commands clearly labeled experimental.