viepilot 1.9.11 → 2.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 (60) hide show
  1. package/CHANGELOG.md +175 -2
  2. package/README.md +3 -3
  3. package/bin/viepilot.cjs +7 -5
  4. package/bin/vp-tools.cjs +193 -0
  5. package/dev-install.sh +34 -13
  6. package/docs/user/features/architect-design-mode.md +170 -0
  7. package/docs/user/features/hooks.md +93 -0
  8. package/docs/user/features/ui-direction.md +79 -3
  9. package/lib/adapters/claude-code.cjs +42 -0
  10. package/lib/adapters/cursor.cjs +31 -0
  11. package/lib/adapters/index.cjs +26 -0
  12. package/lib/hooks/brainstorm-staleness.cjs +231 -0
  13. package/lib/viepilot-config.cjs +103 -0
  14. package/lib/viepilot-install.cjs +128 -153
  15. package/package.json +1 -1
  16. package/skills/vp-audit/SKILL.md +21 -21
  17. package/skills/vp-auto/SKILL.md +21 -7
  18. package/skills/vp-brainstorm/SKILL.md +46 -35
  19. package/skills/vp-crystallize/SKILL.md +37 -25
  20. package/skills/vp-debug/SKILL.md +2 -2
  21. package/skills/vp-docs/SKILL.md +7 -7
  22. package/skills/vp-evolve/SKILL.md +25 -12
  23. package/skills/vp-info/SKILL.md +23 -23
  24. package/skills/vp-pause/SKILL.md +5 -5
  25. package/skills/vp-request/SKILL.md +12 -12
  26. package/skills/vp-resume/SKILL.md +4 -4
  27. package/skills/vp-rollback/SKILL.md +3 -3
  28. package/skills/vp-status/SKILL.md +4 -4
  29. package/skills/vp-task/SKILL.md +3 -3
  30. package/skills/vp-ui-components/SKILL.md +12 -12
  31. package/skills/vp-update/SKILL.md +17 -17
  32. package/templates/architect/apis.html +159 -0
  33. package/templates/architect/architect-actions.js +217 -0
  34. package/templates/architect/architecture.html +160 -0
  35. package/templates/architect/data-flow.html +109 -0
  36. package/templates/architect/decisions.html +96 -0
  37. package/templates/architect/deployment.html +184 -0
  38. package/templates/architect/erd.html +154 -0
  39. package/templates/architect/feature-map.html +113 -0
  40. package/templates/architect/index.html +108 -0
  41. package/templates/architect/sequence-diagram.html +133 -0
  42. package/templates/architect/style.css +365 -0
  43. package/templates/architect/tech-notes.html +89 -0
  44. package/templates/architect/tech-stack.html +114 -0
  45. package/templates/architect/user-use-cases.html +154 -0
  46. package/templates/project/AI-GUIDE.md +53 -54
  47. package/templates/project/PROJECT-CONTEXT.md +7 -11
  48. package/templates/project/README.md +43 -0
  49. package/templates/project/ROADMAP.md +1 -27
  50. package/workflows/audit.md +3 -3
  51. package/workflows/autonomous.md +38 -5
  52. package/workflows/brainstorm.md +575 -191
  53. package/workflows/crystallize.md +168 -58
  54. package/workflows/debug.md +9 -9
  55. package/workflows/documentation.md +5 -5
  56. package/workflows/evolve.md +44 -12
  57. package/workflows/pause-work.md +2 -2
  58. package/workflows/request.md +8 -8
  59. package/workflows/resume-work.md +1 -1
  60. package/workflows/rollback.md +1 -1
package/CHANGELOG.md CHANGED
@@ -7,9 +7,182 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
- ### Planned
10
+ ## [2.1.0] - 2026-04-08
11
11
 
12
- - None.
12
+ ### Added (FEAT-012 — Phase 54)
13
+ - **Brainstorm staleness hook**: `lib/hooks/brainstorm-staleness.cjs` — Claude Code `Stop` event handler; fires after each AI response in a brainstorm session; detects stale architect HTML items via keyword matching; marks `data-arch-stale="true"` (amber badge, flag-only); non-blocking (exit 0 always)
14
+ - `bin/vp-tools.cjs`: `hooks install [--adapter <id>]` subcommand — merges ViePilot hook entry into `~/.claude/settings.json`; idempotent (re-run safe)
15
+ - `docs/user/features/hooks.md` — new user doc: install instructions, adapter table, troubleshooting
16
+ - `workflows/brainstorm.md`: `architect_delta_sync` step now references automatic hook mode; `/hooks-install` command added
17
+
18
+ ### Tests
19
+ - Added `tests/unit/brainstorm-staleness-hook.test.js` (20 tests, 4 groups) — session discovery, keyword detection, HTML patching, install command
20
+ - Total: 578 tests (was 558)
21
+
22
+ ## [2.0.0] - 2026-04-08
23
+
24
+ ### Added (FEAT-013 — Phase 53)
25
+ - **Dynamic agent adapter system**: `lib/adapters/` module with `claude-code.cjs`, `cursor.cjs`, `index.cjs` registry — each platform is a self-contained adapter (skillsDir, viepilotDir, executionContextBase, hooks config, installSubdirs, isAvailable, pathRewrite)
26
+ - `lib/viepilot-install.cjs`: `buildInstallPlan()` now resolves all platform paths from adapter registry — no hardcoded `.cursor/` constants; single adapter loop replaces cursor + claude-code if-blocks
27
+ - `bin/viepilot.cjs`: TARGETS sourced from adapter registry; default non-interactive target = `claude-code`
28
+ - `dev-install.sh`: `VIEPILOT_ADAPTER` env var (default: `claude-code`); backward-compat `VIEPILOT_INSTALL_PROFILE` alias preserved
29
+ - `bin/vp-tools.cjs`: `hooks scaffold [--adapter <id>]` subcommand — prints `~/.claude/settings.json` hook registration snippet for Claude Code; Cursor: prints explanation
30
+
31
+ ### BREAKING CHANGES
32
+ - Default install target changes from `cursor-ide` → `claude-code` (`~/.claude/`)
33
+ - Cursor users: set `VIEPILOT_ADAPTER=cursor-agent` (or `VIEPILOT_INSTALL_PROFILE=cursor-agent`) or pass `--target cursor-agent`
34
+ - `normalizeInstallEnv({})` default profile is now `claude-code` (was `cursor-ide`)
35
+
36
+ ### Tests
37
+ - Added `tests/unit/viepilot-adapters.test.js` (19 tests, 4 groups) — adapter interface, registry, install plan, dev-install.sh
38
+ - Updated `tests/unit/viepilot-install.test.js` — 7 tests updated to reflect claude-code default; cursor-explicit tests use `VIEPILOT_INSTALL_PROFILE: 'cursor-ide'`
39
+ - Total: 558 tests (was 539)
40
+
41
+ ## [1.19.0] - 2026-04-08
42
+
43
+ ### Added (ENH-034 — Phase 52)
44
+ - **vp-brainstorm UI: Architect Delta Sync** — new `architect_delta_sync` step in `workflows/brainstorm.md`: bridges UI Direction Mode and Architect HTML workspace; when a UI session surfaces architect-related gaps, the step parses session for deltas, maps them to affected pages (using existing trigger keyword lists), updates `<tr>` / `<div class="card">` HTML content, marks changed items `data-updated="true"`, and records delta in `notes.md ## architect_sync`
45
+ - `/sync-arch` command: manual trigger for architect delta sync at any point in a brainstorm session
46
+ - `notes.md` YAML schema extended with `## architect_sync` section (synced_at, source_session, trigger, changes)
47
+ - `templates/architect/style.css`: `.arch-gap-badge` (amber) + `[data-arch-stale="true"]` amber left-border indicator — visually distinct from `.updated` (yellow = changed); light-mode overrides included
48
+ - `templates/architect/architect-actions.js`: `markStale(id, reason)` + `injectStaleBadges()` — auto-scans `[data-arch-stale="true"]` on DOMContentLoaded and injects amber "⚠ gap" badges; `window.vpMarkStale` exposed for browser console use
49
+
50
+ ### Tests
51
+ - Added `tests/unit/vp-enh034-architect-delta-sync.test.js` (14 tests, 3 groups) — all pass (539 total)
52
+
53
+ ## [1.18.1] - 2026-04-07
54
+
55
+ ### Fixed (BUG-010 — Phase 51)
56
+ - **Approve/Edit buttons missing on Mermaid diagram cards:** added `data-arch-id` + `data-arch-title` to all 9 diagram cards across 6 pages (architecture ARCH-DIAG1/2, data-flow DF-DIAG1/2, erd ERD-DIAG1, use-cases UC-DIAG1, sequence SEQ-DIAG1/2, deployment DEP-DIAG1)
57
+
58
+ ### Tests
59
+ - Added Test Group 5 to `tests/unit/vp-enh033-architect-item-actions.test.js` (9 new tests) — 525 total
60
+
61
+ ## [1.18.0] - 2026-04-07
62
+
63
+ ### Added (ENH-033 — Phase 50)
64
+ - **Architect HTML item actions:** stable `data-arch-id` IDs on every item across all 11 content pages (decisions D1–D2, architecture C1–C4, erd E1–E4, use-cases UC1–UC5, apis A1–A9, deployment DEP1–DEP7, data-flow DF1, sequence SEQ1–SEQ2, tech-stack TS1–TS6, tech-notes TN1, features F1–F3)
65
+ - `templates/architect/architect-actions.js` — new shared vanilla JS: `approvePrompt()`, `editPrompt()`, `copyText()` with clipboard API + execCommand fallback, button injection on DOMContentLoaded
66
+ - **✅ Approve button**: copies `[ARCH:{slug}:{id}] APPROVE — "{title}" on {slug} page. No changes needed.`
67
+ - **✏️ Edit button**: copies `[ARCH:{slug}:{id}] EDIT — "{title}" on {slug} page. Current: "{excerpt}". What should I change?`
68
+ - `templates/architect/style.css`: `.arch-id-badge`, `.arch-item-actions`, `.arch-btn`, `.arch-btn-approve`, `.arch-btn-edit`, `.arch-btn.copied`, `.arch-actions-cell` — hover-reveal pattern, light-mode overrides
69
+ - `workflows/brainstorm.md`: **Architect Item Actions (ENH-033)** section — isolation rule, APPROVE/EDIT prompt handling spec, cross-page cascade prohibition
70
+
71
+ ### Tests
72
+ - Added `tests/unit/vp-enh033-architect-item-actions.test.js` (50 tests, 4 groups) — all pass (516 total)
73
+
74
+ ## [1.17.0] - 2026-04-06
75
+
76
+ ### Added (ENH-032 — Phase 49)
77
+ - **Language configuration system:** `~/.viepilot/config.json` stores `language.communication` and `language.document` (defaults: `en`/`en`)
78
+ - `lib/viepilot-config.cjs` — new module: `readConfig`, `writeConfig`, `resetConfig`, `getConfigPath`; deep-merge with defaults; missing-file safe
79
+ - `vp-tools config get/set/reset` — CLI commands to read and write language config
80
+ - `lib/viepilot-install.cjs`: `language_config_prompt` step writes config at end of install; `--yes` uses defaults without prompting
81
+ - `workflows/crystallize.md`: Step 0-A `load_language_config` — reads `DOCUMENT_LANG` + `COMMUNICATION_LANG` for file generation and session messages
82
+ - `workflows/brainstorm.md`: Step 0 `detect_session_language` — reads `BRAINSTORM_LANG` for file storage; user session language overrides config
83
+ - `workflows/autonomous.md`: `load_language_config` in Initialize — `COMMUNICATION_LANG` for banners and control-point messages
84
+ - `skills/vp-crystallize/SKILL.md`, `skills/vp-brainstorm/SKILL.md`, `skills/vp-auto/SKILL.md`: ENH-032 language config notes
85
+
86
+ ### Tests
87
+ - Added `tests/unit/vp-enh032-language-config.test.js` (18 tests) — all pass (466 total)
88
+
89
+ ## [1.16.0] - 2026-04-06
90
+
91
+ ### Changed (ENH-031 — Phase 48)
92
+ - **Language standardization (English-primary):** all 12 workflows, all 16 skills, and `templates/project/AI-GUIDE.md` converted to English; Vietnamese retained only in `cursor_skill_adapter` invocation trigger keywords and UI scope signal detection patterns
93
+
94
+ ### Tests
95
+ - Added `tests/unit/vp-enh031-language-standardization.test.js` (63 tests) — all pass (448 total)
96
+ - Updated `vp-fe010-ui-walkthrough-contracts.test.js` + `vp-enh026-ui-extraction-contracts.test.js` to match translated English strings
97
+
98
+ ## [1.15.0] - 2026-04-06
99
+
100
+ ### Fixed (BUG-009 — Phase 47)
101
+ - **Task path guard:** `workflows/evolve.md` now enforces repo-relative paths in task `## Paths` blocks (prevents generating `~/.claude/...` paths that would edit the live install instead of source)
102
+ - **Preflight validation:** `workflows/autonomous.md` aborts task execution if `## Paths` contains `~/` or absolute path — error message names offending path and task file
103
+ - `skills/vp-evolve/SKILL.md` + `skills/vp-auto/SKILL.md`: path convention documented in `<context>`
104
+
105
+ ### Tests
106
+ - Added `tests/unit/vp-bug009-path-guard.test.js` (13 tests) — all pass (385 total)
107
+
108
+ ## [1.14.0] - 2026-04-06
109
+
110
+ ### Changed (ENH-030 — Phase 46)
111
+
112
+ - **Remove MVP/Post-MVP/Future concept** — all projects now use phase-based planning only:
113
+ - `workflows/brainstorm.md`: replaced `## Product horizon` section + ENH-014 rule with Phase assignment rule (ENH-030) and `## Phases` session template
114
+ - `workflows/crystallize.md`: replaced Horizon validation gate with Phase assignment gate; Step 7 ROADMAP generation now uses `phases_inventory` (no Post-MVP block)
115
+ - `templates/architect/feature-map.html`: mindmap nodes + badge classes updated — MVP/Post-MVP/Future → Phase 1/Phase 2/Phase 3
116
+ - `templates/architect/style.css`: `.badge-mvp/.badge-post-mvp/.badge-future` → `.badge-phase-1/.badge-phase-2/.badge-phase-3`
117
+ - `templates/architect/user-use-cases.html`: Priority column → Phase; badge-mvp/post-mvp/future → badge-phase-1/2/3
118
+ - `templates/architect/index.html`: feature map subtitle updated (no MVP/Post-MVP text)
119
+ - `templates/project/PROJECT-CONTEXT.md`: MVP boundary + Post-MVP themes sections replaced with Project scope + Phase overview table
120
+ - `templates/project/ROADMAP.md`: Post-MVP / Product horizon block removed; maintenance note updated
121
+ - `templates/project/AI-GUIDE.md`: all MVP/horizon reading instructions replaced with phase-centric equivalents
122
+ - `skills/vp-brainstorm/SKILL.md` v1.1.0: phase assignment rule replaces product horizon rule
123
+ - `skills/vp-crystallize/SKILL.md` v0.8.0: phase assignment gate replaces horizon gate
124
+ - `skills/vp-task/SKILL.md`: example updated (no MVP reference)
125
+
126
+ ### Tests
127
+ - Added `tests/unit/vp-enh030-no-mvp-contracts.test.js` (10 tests) — all pass (372 total)
128
+
129
+ ## [1.13.0] - 2026-04-04
130
+
131
+ ### Added
132
+
133
+ - **ENH-029 — Architect Design Mode: C4/Sequence/Deployment/APIs pages (12-page workspace)**:
134
+ - `templates/architect/architecture.html`: C4 Context diagram section (Mermaid `C4Context`) + External Systems table (6 columns: System/Type/Description/Integration method/Owned by/Notes).
135
+ - `templates/architect/sequence-diagram.html` (new): per-scenario sequences — Scenario Index table, 2 placeholder `sequenceDiagram` blocks, differentiation note linking to data-flow.html.
136
+ - `templates/architect/deployment.html` (new): infra `graph TD` with dev/staging/prod, Environments table, Infrastructure Components table, CI/CD `flowchart LR`.
137
+ - `templates/architect/apis.html` (new): per-service endpoint tables (Method/Path/Auth?/Request Body/Response/Status codes/Notes), HTTP method badges, API Design Decisions table with style badges.
138
+ - `templates/architect/style.css`: 5 HTTP method badge classes (`.method-get/post/put/delete/patch`).
139
+ - All 12 architect pages updated with full 12-item sidebar nav (Sequence + Deployment + APIs items added to all existing pages).
140
+ - `templates/architect/index.html`: 3 new hub cards (Sequence Diagram, Deployment, APIs); Architecture card subtitle updated.
141
+ - `workflows/brainstorm.md`: Page Boundary Rules table; Sequence/Deployment/APIs trigger keyword sections; C4Context added to diagram types; `## apis` YAML schema section; 3 new pages in workspace layout.
142
+ - `workflows/crystallize.md` Step 1D: steps 5–6 extract `deployment.html`/`notes.md ## deployment` → `## Deployment & Infrastructure` and `apis.html`/`notes.md ## apis` → `## API Design` in ARCHITECTURE.md; sequence-diagram.html explicitly excluded with rationale.
143
+ - `skills/vp-brainstorm/SKILL.md`: ENH-029 capability note added.
144
+ - `tests/unit/vp-enh029-architect-pages-contracts.test.js` (new): 11 contract tests — all pass (362 total).
145
+
146
+ ## [1.12.0] - 2026-04-04
147
+
148
+ ### Added
149
+
150
+ - **ENH-027 — Architect Design Mode: ERD page**:
151
+ - `templates/architect/erd.html` (new): Mermaid `erDiagram` with sample entities (User/Order/OrderItem/Product), Entity List table (Entity/Attributes/PK/FK/Notes), Relationship Summary table.
152
+ - `workflows/brainstorm.md`: ERD trigger keywords (entity, table, relationship, foreign key, schema, DB, database); `## erd` section in notes.md YAML schema; `erDiagram` added to supported Mermaid types.
153
+ - `workflows/crystallize.md` Step 1D: step 3 — extracts `## erd` → `## Database Schema (from Architect ERD)` in ARCHITECTURE.md.
154
+ - All 7 existing architect templates updated with `🗄️ ERD` sidebar nav link.
155
+ - **ENH-028 — Architect Design Mode: User Use Cases page**:
156
+ - `templates/architect/user-use-cases.html` (new): Mermaid `flowchart LR` with Actors/Use Cases subgraphs, Use Case List table (ID/Actor/Priority), Actor Summary table.
157
+ - `workflows/brainstorm.md`: Use Case trigger keywords (user story, actor, role, use case, scenario); `## use_cases` section in notes.md YAML schema.
158
+ - `workflows/crystallize.md` Step 1D: step 4 — extracts `## use_cases` → `## User Stories & Use Cases (from Architect Mode)` in PROJECT-CONTEXT.md.
159
+ - All architect templates updated with `👤 Use Cases` sidebar nav link; `index.html` adds 2 hub cards.
160
+ - **vp-brainstorm v1.0.0**: bumped from 0.9.0 with ENH-027 + ENH-028 capability notes.
161
+
162
+ ## [1.11.0] - 2026-04-04
163
+
164
+ ### Added
165
+
166
+ - **FEAT-011 — Architect Design Mode**:
167
+ - `workflows/brainstorm.md`: new `### Architect Design Mode` section — activate via `--architect` flag or auto-heuristic (≥3 components OR ≥1 stack mention); generates HTML workspace with 7 sections (architecture, data-flow, decisions, tech-stack, tech-notes, feature-map, hub) + `notes.md` YAML schema; incremental updates per decision with `.updated` CSS highlight; `/review-arch` command for summary + open_questions review.
168
+ - `templates/architect/`: 7 HTML templates + `style.css` — dark/light toggle, Mermaid.js diagrams, `.updated` diff indicator, responsive sidebar nav. Self-contained, open in browser.
169
+ - `workflows/crystallize.md`: new Step 1D `consume_architect_artifacts` — reads `notes.md` YAML; imports `decisions[]` → ARCHITECTURE.md, uses `tech_stack{}` as authoritative, surfaces `open_questions[]` status=open; cross-references `feature-map.html` with Product Horizon; soft suggestion (not hard block) when architect dir missing.
170
+ - `skills/vp-brainstorm/SKILL.md`: bumped to `0.9.0`, FEAT-011 listed in capabilities.
171
+ - `skills/vp-crystallize/SKILL.md`: bumped to `0.7.0`, FEAT-011 listed in capabilities.
172
+ - `docs/user/features/architect-design-mode.md`: new — 8 sections covering overview, activation, HTML artifacts, dialogue cadence, `/review-arch`, crystallize integration, notes.md schema, tips.
173
+ - `tests/unit/vp-feat011-architect-design-mode-contracts.test.js`: 8 contract tests (333 total, all pass).
174
+
175
+ ## [1.10.0] - 2026-04-04
176
+
177
+ ### Added
178
+
179
+ - **ENH-026 — Background UI Extraction + Crystallize Hard Gate**:
180
+ - `workflows/brainstorm.md`: new `### Background UI Extraction (silent mode)` section — auto-detects 35 UI signal keywords in any brainstorm session; silent `ui_idea_buffer[]` accumulation; surfaces 3-option confirmation dialogue (save to notes, activate UI Direction Mode, or keep buffer) at topic end / `/save` / ≥5 signals. Non-blocking.
181
+ - `workflows/crystallize.md`: Step 1A upgraded to **hard gate** — scans brainstorm sessions for ≥3 UI signals; if `ui_scope_detected = true` and artifacts missing → STOP with 2-option dialogue; Option 2 bypass writes `## UI Direction Assumptions` to `.viepilot/ARCHITECTURE.md`.
182
+ - `skills/vp-brainstorm/SKILL.md`: bumped to `0.8.0`, ENH-026 background extraction listed in capabilities.
183
+ - `skills/vp-crystallize/SKILL.md`: bumped to `0.6.0`, ENH-026 hard gate listed in capabilities.
184
+ - `docs/user/features/ui-direction.md`: new `## Background Extraction` and updated `## Crystallize Integration` sections with hard gate docs, dialogue examples, and diff table vs `--ui` mode.
185
+ - `tests/unit/vp-enh026-ui-extraction-contracts.test.js`: 6 contract tests (325 total, all pass).
13
186
 
14
187
  ## [1.9.11] - 2026-04-02
15
188
 
package/README.md CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  **Autonomous Vibe Coding Framework / Bộ khung phát triển tự động có kiểm soát**
4
4
 
5
- [![Version](https://img.shields.io/badge/version-1.9.5-blue.svg)](CHANGELOG.md)
5
+ [![Version](https://img.shields.io/badge/version-1.16.0-blue.svg)](CHANGELOG.md)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
7
7
  [![Skills](https://img.shields.io/badge/skills-16-purple.svg)](#skills-reference)
8
8
  [![Workflows](https://img.shields.io/badge/workflows-12-orange.svg)](#workflows)
9
9
  [![Templates](https://img.shields.io/badge/templates-17-cyan.svg)](#templates)
10
- [![Tests](https://img.shields.io/badge/tests-308%20passing-brightgreen.svg)](tests/)
10
+ [![Tests](https://img.shields.io/badge/tests-448%20passing-brightgreen.svg)](tests/)
11
11
  [![GitHub](https://img.shields.io/github/stars/0-CODE/viepilot?style=social)](https://github.com/0-CODE/viepilot)
12
12
 
13
13
  **Versioning:** Shield **1.9.5** is the **ViePilot framework SemVer** tracked in `.viepilot/TRACKER.md` and `CHANGELOG.md`. The npm `package.json` field `version` (**1.9.5**) is the Node package identifier for this repo; use the framework version for milestone releases and docs.
@@ -28,7 +28,7 @@ Nếu ViePilot giúp ích cho bạn, bạn có thể ủng hộ một ly cafe:
28
28
 
29
29
  | Chỉ số / Metric | Giá trị / Value |
30
30
  |-----------------|-----------------|
31
- | Total LOC | **~27,991+** (`.md`, `.js`, `.cjs`, `.yml`, `.json`, `.sh`; không gồm `node_modules`) |
31
+ | Total LOC | **~34,308+** (`.md`, `.js`, `.cjs`, `.yml`, `.json`, `.sh`; không gồm `node_modules`) |
32
32
  | Skills | **16** |
33
33
  | Workflows | **12** |
34
34
  | Templates | **17** (Project: 12, Phase: 5) |
package/bin/viepilot.cjs CHANGED
@@ -14,11 +14,13 @@ const { buildInstallPlan, applyInstallPlan, resolveViepilotPackageRoot } = requi
14
14
  'lib',
15
15
  'viepilot-install.cjs',
16
16
  ));
17
+ const { adapters: adapterMap } = require(path.join(__dirname, '..', 'lib', 'adapters', 'index.cjs'));
17
18
 
19
+ // UI target list — keep cursor-agent and cursor-ide as distinct choices for users.
18
20
  const TARGETS = [
19
- { id: 'claude-code', label: 'Claude Code' },
21
+ { id: 'claude-code', label: adapterMap['claude-code'].name + ' (default)' },
20
22
  { id: 'cursor-agent', label: 'Cursor Agent' },
21
- { id: 'cursor-ide', label: 'Cursor IDE' },
23
+ { id: 'cursor-ide', label: 'Cursor IDE' },
22
24
  ];
23
25
 
24
26
  function printHelp() {
@@ -254,7 +256,7 @@ async function interactiveTargetSelection() {
254
256
  function runInstallViaNode(selectedTargets, dryRun) {
255
257
  const fallbackRoot = path.join(__dirname, '..');
256
258
  const pkgRoot = resolveViepilotPackageRoot(fallbackRoot) || fallbackRoot;
257
- const profile = selectedTargets[0] || 'cursor-ide';
259
+ const profile = selectedTargets[0] || 'claude-code';
258
260
  const env = {
259
261
  ...process.env,
260
262
  VIEPILOT_AUTO_YES: '1',
@@ -307,8 +309,8 @@ async function installCommand(rawArgs) {
307
309
 
308
310
  if (!selectedTargets) {
309
311
  if (options.yes) {
310
- selectedTargets = TARGETS.map((t) => t.id);
311
- console.log('No --target provided with --yes; defaulting to all targets.');
312
+ selectedTargets = ['claude-code'];
313
+ console.log('No --target provided with --yes; defaulting to claude-code.');
312
314
  } else {
313
315
  selectedTargets = await interactiveTargetSelection();
314
316
  if (selectedTargets.length === 0) {
package/bin/vp-tools.cjs CHANGED
@@ -13,6 +13,7 @@
13
13
  const fs = require('fs');
14
14
  const path = require('path');
15
15
  const readline = require('readline');
16
+ const os = require('os');
16
17
 
17
18
  const {
18
19
  validators,
@@ -25,6 +26,7 @@ const {
25
26
 
26
27
  const viepilotInfo = require(path.join(__dirname, '../lib/viepilot-info.cjs'));
27
28
  const viepilotUpdate = require(path.join(__dirname, '../lib/viepilot-update.cjs'));
29
+ const viepilotConfig = require(path.join(__dirname, '../lib/viepilot-config.cjs'));
28
30
 
29
31
  // ============================================================================
30
32
  // Output Formatting (TTY-aware)
@@ -946,6 +948,195 @@ const commands = {
946
948
  }, null, 2));
947
949
  },
948
950
 
951
+ /**
952
+ * Hooks scaffold + install — FEAT-013/FEAT-012 adapter hook management
953
+ * Usage: vp-tools hooks <scaffold|install> [--adapter <id>]
954
+ */
955
+ hooks: (args) => {
956
+ const sub = args[0];
957
+ if (!sub || sub === 'help') {
958
+ console.log(`${colors.cyan}Usage:${colors.reset}
959
+ vp-tools hooks scaffold [--adapter <id>]
960
+ vp-tools hooks install [--adapter <id>]
961
+
962
+ ${colors.cyan}Subcommands:${colors.reset}
963
+ scaffold Print hook config snippet for the target adapter (default: claude-code)
964
+ install Install ViePilot staleness hook into adapter config file (idempotent)
965
+
966
+ ${colors.cyan}Options:${colors.reset}
967
+ --adapter <id> Adapter ID: claude-code (default), cursor-agent, cursor-ide
968
+
969
+ ${colors.cyan}Examples:${colors.reset}
970
+ ${colors.gray}$${colors.reset} vp-tools hooks scaffold
971
+ ${colors.gray}$${colors.reset} vp-tools hooks scaffold --adapter cursor-agent
972
+ ${colors.gray}$${colors.reset} vp-tools hooks install
973
+ ${colors.gray}$${colors.reset} vp-tools hooks install --adapter claude-code`);
974
+ return;
975
+ }
976
+
977
+ // ── shared adapter resolution ──────────────────────────────────────────
978
+ const adapterArgIdx = args.indexOf('--adapter');
979
+ const adapterId = adapterArgIdx !== -1 ? args[adapterArgIdx + 1] : 'claude-code';
980
+ if (adapterArgIdx !== -1 && !adapterId) {
981
+ console.error(formatError('--adapter requires a value (e.g. claude-code, cursor-agent)'));
982
+ process.exit(1);
983
+ }
984
+ const { getAdapter } = require(path.join(__dirname, '../lib/adapters/index.cjs'));
985
+ let adapter;
986
+ try {
987
+ adapter = getAdapter(adapterId);
988
+ } catch (e) {
989
+ console.error(formatError(e.message));
990
+ process.exit(1);
991
+ }
992
+
993
+ if (sub === 'scaffold') {
994
+ if (!adapter.hooks || !adapter.hooks.configFile) {
995
+ console.log(`Adapter "${adapterId}" (${adapter.name}) does not use a settings.json hook config.`);
996
+ console.log(`For Cursor, hooks are configured via .cursorrules or project MDC files.`);
997
+ process.exit(0);
998
+ }
999
+ const home = os.homedir();
1000
+ const configPath = adapter.hooks.configFile(home);
1001
+ console.log(`\nViePilot hooks scaffold for: ${adapter.name}`);
1002
+ console.log(`Config file: ${configPath}\n`);
1003
+ console.log(`Add the following to your ${configPath}:\n`);
1004
+ console.log(JSON.stringify({
1005
+ hooks: {
1006
+ Stop: [{
1007
+ matcher: {},
1008
+ hooks: [{
1009
+ type: 'command',
1010
+ command: `node ${path.join(home, '.viepilot', 'hooks', 'brainstorm-staleness.cjs')}`
1011
+ }]
1012
+ }]
1013
+ }
1014
+ }, null, 2));
1015
+ console.log(`\nRun 'vp-tools hooks install' to register this hook automatically.`);
1016
+ process.exit(0);
1017
+ }
1018
+
1019
+ if (sub === 'install') {
1020
+ if (!adapter.hooks || !adapter.hooks.configFile) {
1021
+ console.log(`Adapter "${adapterId}" (${adapter.name}) does not support settings.json hooks.`);
1022
+ console.log(`For Cursor, add hooks via .cursorrules or project MDC files.`);
1023
+ process.exit(0);
1024
+ }
1025
+ const home = os.homedir();
1026
+ const configPath = adapter.hooks.configFile(home);
1027
+ const hookCommand = `node ${path.join(home, '.viepilot', 'hooks', 'brainstorm-staleness.cjs')}`;
1028
+
1029
+ // Read existing settings.json (create if missing)
1030
+ let settings = {};
1031
+ if (fs.existsSync(configPath)) {
1032
+ try { settings = JSON.parse(fs.readFileSync(configPath, 'utf8')); } catch (_e) { settings = {}; }
1033
+ }
1034
+
1035
+ // Merge hook entry — idempotent check
1036
+ if (!settings.hooks) settings.hooks = {};
1037
+ if (!settings.hooks.Stop) settings.hooks.Stop = [];
1038
+
1039
+ const alreadyInstalled = settings.hooks.Stop.some((entry) =>
1040
+ Array.isArray(entry.hooks) &&
1041
+ entry.hooks.some((h) => h.type === 'command' && h.command === hookCommand)
1042
+ );
1043
+
1044
+ if (alreadyInstalled) {
1045
+ console.log(formatSuccess('ViePilot staleness hook already installed.'));
1046
+ console.log(` Config: ${configPath}`);
1047
+ process.exit(0);
1048
+ }
1049
+
1050
+ settings.hooks.Stop.push({
1051
+ matcher: {},
1052
+ hooks: [{ type: 'command', command: hookCommand }],
1053
+ });
1054
+
1055
+ try {
1056
+ fs.mkdirSync(path.dirname(configPath), { recursive: true });
1057
+ fs.writeFileSync(configPath, JSON.stringify(settings, null, 2) + '\n', 'utf8');
1058
+ } catch (e) {
1059
+ console.error(formatError(`Failed to write ${configPath}: ${e.message}`));
1060
+ process.exit(1);
1061
+ }
1062
+
1063
+ console.log(formatSuccess('ViePilot staleness hook installed.'));
1064
+ console.log(` Config: ${configPath}`);
1065
+ console.log(` Command: ${hookCommand}`);
1066
+ process.exit(0);
1067
+ }
1068
+
1069
+ console.error(formatError(`Unknown hooks subcommand: ${sub}`, 'Use: scaffold, install'));
1070
+ process.exit(1);
1071
+ },
1072
+
1073
+ /**
1074
+ * Config get/set/reset — ENH-032 language configuration
1075
+ */
1076
+ config: (args) => {
1077
+ const sub = args[0];
1078
+ if (!sub || sub === 'help') {
1079
+ console.log(`${colors.cyan}Usage:${colors.reset}
1080
+ vp-tools config get <key>
1081
+ vp-tools config set <key> <value>
1082
+ vp-tools config reset
1083
+
1084
+ ${colors.cyan}Keys:${colors.reset}
1085
+ language.communication Language for AI communication/banners (e.g. en, vi)
1086
+ language.document Language for generated project files (e.g. en, vi)
1087
+
1088
+ ${colors.cyan}Examples:${colors.reset}
1089
+ ${colors.gray}$${colors.reset} vp-tools config get language.communication
1090
+ ${colors.gray}$${colors.reset} vp-tools config set language.communication vi
1091
+ ${colors.gray}$${colors.reset} vp-tools config reset`);
1092
+ return;
1093
+ }
1094
+ if (sub === 'get') {
1095
+ const key = args[1];
1096
+ if (!key) {
1097
+ console.error(formatError('Missing key', 'Usage: vp-tools config get <key>'));
1098
+ process.exit(1);
1099
+ }
1100
+ const cfg = viepilotConfig.readConfig();
1101
+ const parts = key.split('.');
1102
+ let val = cfg;
1103
+ for (const p of parts) {
1104
+ if (val == null || typeof val !== 'object') { val = undefined; break; }
1105
+ val = val[p];
1106
+ }
1107
+ if (val === undefined) {
1108
+ console.error(formatError(`Unknown config key: ${key}`));
1109
+ process.exit(1);
1110
+ }
1111
+ console.log(val);
1112
+ return;
1113
+ }
1114
+ if (sub === 'set') {
1115
+ const key = args[1];
1116
+ const value = args[2];
1117
+ if (!key || value === undefined) {
1118
+ console.error(formatError('Usage: vp-tools config set <key> <value>'));
1119
+ process.exit(1);
1120
+ }
1121
+ const parts = key.split('.');
1122
+ if (parts.length !== 2) {
1123
+ console.error(formatError('Key must be in format <section>.<field> (e.g. language.communication)'));
1124
+ process.exit(1);
1125
+ }
1126
+ const [section, field] = parts;
1127
+ viepilotConfig.writeConfig({ [section]: { [field]: value } });
1128
+ console.log(formatSuccess(`Set ${key} = ${value}`));
1129
+ return;
1130
+ }
1131
+ if (sub === 'reset') {
1132
+ viepilotConfig.resetConfig();
1133
+ console.log(formatSuccess('Config reset to defaults (communication=en, document=en)'));
1134
+ return;
1135
+ }
1136
+ console.error(formatError(`Unknown config subcommand: ${sub}`, 'Use get, set, or reset'));
1137
+ process.exit(1);
1138
+ },
1139
+
949
1140
  /**
950
1141
  * Help
951
1142
  */
@@ -1088,6 +1279,8 @@ ${colors.cyan}Commands:${colors.reset}
1088
1279
  ${colors.bold}info${colors.reset} [--json] Show ViePilot version, npm latest, skills/workflows
1089
1280
  ${colors.bold}update${colors.reset} [--dry-run] Update viepilot via npm (use --yes non-interactive)
1090
1281
  ${colors.bold}conflicts${colors.reset} Check for potential conflicts
1282
+ ${colors.bold}hooks${colors.reset} scaffold|install [--adapter] scaffold: print snippet; install: write to settings.json
1283
+ ${colors.bold}config${colors.reset} <get|set|reset> Read/write language config (~/.viepilot/config.json)
1091
1284
  ${colors.bold}save-state${colors.reset} Save current state for precise resume
1092
1285
  ${colors.bold}help${colors.reset} [command] Show help (optionally for specific command)
1093
1286
 
package/dev-install.sh CHANGED
@@ -3,8 +3,11 @@
3
3
  # ViePilot Development Installation Script
4
4
  # Installs development build without symlink dependency by default
5
5
  #
6
- # Optional: VIEPILOT_SYMLINK_SKILLS=1 — symlink each skills/vp-* into ~/.cursor/skills/
7
- # (live edits from this repo; default remains copy for reliability — see FEAT-005)
6
+ # Optional env vars:
7
+ # VIEPILOT_ADAPTER — target platform: claude-code (default), cursor, cursor-agent, cursor-ide
8
+ # VIEPILOT_INSTALL_PROFILE — backward-compat alias for VIEPILOT_ADAPTER
9
+ # VIEPILOT_AUTO_YES — skip confirmation prompt (set to 1)
10
+ # VIEPILOT_SYMLINK_SKILLS=1 — symlink each skills/vp-* instead of copy
8
11
 
9
12
  set -e
10
13
 
@@ -17,10 +20,27 @@ NC='\033[0m'
17
20
 
18
21
  # Get script directory (project root)
19
22
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
20
- CURSOR_SKILLS_DIR="$HOME/.cursor/skills"
21
- VIEPILOT_DIR="$HOME/.cursor/viepilot"
22
23
  AUTO_YES="${VIEPILOT_AUTO_YES:-0}"
23
- INSTALL_PROFILE="${VIEPILOT_INSTALL_PROFILE:-cursor-agent}"
24
+
25
+ # Backward compat: VIEPILOT_INSTALL_PROFILE accepted as alias for VIEPILOT_ADAPTER
26
+ ADAPTER="${VIEPILOT_ADAPTER:-${VIEPILOT_INSTALL_PROFILE:-claude-code}}"
27
+
28
+ case "$ADAPTER" in
29
+ claude-code)
30
+ SKILLS_DIR="$HOME/.claude/skills"
31
+ VIEPILOT_DIR="$HOME/.claude/viepilot"
32
+ PROFILE_LABEL="Claude Code"
33
+ ;;
34
+ cursor|cursor-agent|cursor-ide)
35
+ SKILLS_DIR="$HOME/.cursor/skills"
36
+ VIEPILOT_DIR="$HOME/.cursor/viepilot"
37
+ PROFILE_LABEL="Cursor"
38
+ ;;
39
+ *)
40
+ echo "Unknown adapter: $ADAPTER. Use: claude-code (default), cursor-agent, cursor-ide"
41
+ exit 1
42
+ ;;
43
+ esac
24
44
 
25
45
  echo -e "${BLUE}"
26
46
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@@ -33,9 +53,10 @@ if [ "${VIEPILOT_SYMLINK_SKILLS:-0}" = "1" ]; then
33
53
  else
34
54
  echo -e "${YELLOW}Development mode installation (copy-first for reliability)${NC}"
35
55
  fi
36
- echo " Source: $SCRIPT_DIR"
37
- echo " Target: $CURSOR_SKILLS_DIR, $VIEPILOT_DIR"
38
- echo " Profile: $INSTALL_PROFILE"
56
+ echo " Source: $SCRIPT_DIR"
57
+ echo " Skills: $SKILLS_DIR"
58
+ echo " Viepilot: $VIEPILOT_DIR"
59
+ echo " Adapter: $ADAPTER ($PROFILE_LABEL)"
39
60
  echo ""
40
61
 
41
62
  check_cloc_dependency() {
@@ -68,7 +89,7 @@ echo ""
68
89
  echo -e "${BLUE}Removing old installations...${NC}"
69
90
 
70
91
  # Remove old skill installations
71
- for skill in "$CURSOR_SKILLS_DIR"/vp-*/; do
92
+ for skill in "$SKILLS_DIR"/vp-*/; do
72
93
  if [ -d "$skill" ] || [ -L "$skill" ]; then
73
94
  rm -rf "$skill"
74
95
  echo " Removed: $(basename "$skill")"
@@ -85,7 +106,7 @@ echo ""
85
106
  echo -e "${BLUE}Installing skills...${NC}"
86
107
 
87
108
  # Install skills: copy (default) or symlink when VIEPILOT_SYMLINK_SKILLS=1
88
- mkdir -p "$CURSOR_SKILLS_DIR"
109
+ mkdir -p "$SKILLS_DIR"
89
110
  for skill in "$SCRIPT_DIR"/skills/vp-*/; do
90
111
  skill_name=$(basename "$skill")
91
112
  if [ "${VIEPILOT_SYMLINK_SKILLS:-0}" = "1" ]; then
@@ -94,10 +115,10 @@ for skill in "$SCRIPT_DIR"/skills/vp-*/; do
94
115
  else
95
116
  skill_abs=$(cd "$skill" && pwd)
96
117
  fi
97
- ln -sfn "$skill_abs" "$CURSOR_SKILLS_DIR/$skill_name"
118
+ ln -sfn "$skill_abs" "$SKILLS_DIR/$skill_name"
98
119
  echo -e " ${GREEN}✓${NC} $skill_name (symlink)"
99
120
  else
100
- cp -R "$skill" "$CURSOR_SKILLS_DIR/$skill_name"
121
+ cp -R "$skill" "$SKILLS_DIR/$skill_name"
101
122
  echo -e " ${GREEN}✓${NC} $skill_name"
102
123
  fi
103
124
  done
@@ -129,7 +150,7 @@ echo -e " ${GREEN}✓${NC} ui-components"
129
150
  check_cloc_dependency
130
151
 
131
152
  # Count installed
132
- SKILL_COUNT=$(ls -d "$CURSOR_SKILLS_DIR"/vp-*/ 2>/dev/null | wc -l | tr -d ' ')
153
+ SKILL_COUNT=$(ls -d "$SKILLS_DIR"/vp-*/ 2>/dev/null | wc -l | tr -d ' ')
133
154
  WORKFLOW_COUNT=$(ls "$SCRIPT_DIR"/workflows/*.md 2>/dev/null | wc -l | tr -d ' ')
134
155
 
135
156
  echo ""