verbalcoding 0.2.11 → 0.2.12

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 (93) hide show
  1. package/.env.example +27 -1
  2. package/README.es.md +132 -0
  3. package/README.fr.md +132 -0
  4. package/README.ja.md +132 -0
  5. package/README.ko.md +132 -0
  6. package/README.md +116 -74
  7. package/README.ru.md +132 -0
  8. package/README.zh.md +131 -0
  9. package/app-node/agent_adapters.mjs +37 -5
  10. package/app-node/agent_adapters.test.mjs +13 -1
  11. package/app-node/agent_detect.mjs +73 -0
  12. package/app-node/agent_detect.test.mjs +77 -0
  13. package/app-node/install_config.mjs +3 -0
  14. package/app-node/main.mjs +339 -4
  15. package/app-node/notify.mjs +73 -0
  16. package/app-node/notify.test.mjs +68 -0
  17. package/app-node/plan_mode.mjs +174 -0
  18. package/app-node/plan_mode.test.mjs +153 -0
  19. package/app-node/smart_progress.mjs +94 -0
  20. package/app-node/smart_progress.test.mjs +66 -0
  21. package/app-node/stream_sentencer.mjs +61 -0
  22. package/app-node/stream_sentencer.test.mjs +64 -0
  23. package/app-node/streaming_tts_queue.mjs +48 -0
  24. package/app-node/streaming_tts_queue.test.mjs +58 -0
  25. package/app-node/text_routing.mjs +20 -0
  26. package/app-node/text_routing.test.mjs +23 -1
  27. package/docs/CONFIGURATION.md +69 -96
  28. package/docs/FRESH_INSTALL.md +105 -63
  29. package/docs/HERMES_VOICE.md +65 -0
  30. package/docs/MULTI_INSTANCE.md +16 -0
  31. package/docs/README.md +49 -0
  32. package/docs/RELEASE.md +42 -19
  33. package/docs/ROADMAP.md +38 -0
  34. package/docs/TROUBLESHOOTING.md +126 -0
  35. package/docs/USAGE.md +72 -40
  36. package/docs/assets/figures/verbalcoding-flow.svg +1 -1
  37. package/docs/i18n/CONFIGURATION.es.md +25 -0
  38. package/docs/i18n/CONFIGURATION.fr.md +25 -0
  39. package/docs/i18n/CONFIGURATION.ja.md +25 -0
  40. package/docs/i18n/CONFIGURATION.ko.md +25 -0
  41. package/docs/i18n/CONFIGURATION.ru.md +25 -0
  42. package/docs/i18n/CONFIGURATION.zh.md +25 -0
  43. package/docs/i18n/FRESH_INSTALL.es.md +27 -2
  44. package/docs/i18n/FRESH_INSTALL.fr.md +27 -2
  45. package/docs/i18n/FRESH_INSTALL.ja.md +27 -2
  46. package/docs/i18n/FRESH_INSTALL.ko.md +27 -2
  47. package/docs/i18n/FRESH_INSTALL.ru.md +27 -2
  48. package/docs/i18n/FRESH_INSTALL.zh.md +27 -2
  49. package/docs/i18n/HERMES_VOICE.es.md +46 -0
  50. package/docs/i18n/HERMES_VOICE.fr.md +46 -0
  51. package/docs/i18n/HERMES_VOICE.ja.md +46 -0
  52. package/docs/i18n/HERMES_VOICE.ko.md +65 -0
  53. package/docs/i18n/HERMES_VOICE.ru.md +46 -0
  54. package/docs/i18n/HERMES_VOICE.zh.md +46 -0
  55. package/docs/i18n/MULTI_INSTANCE.es.md +25 -0
  56. package/docs/i18n/MULTI_INSTANCE.fr.md +25 -0
  57. package/docs/i18n/MULTI_INSTANCE.ja.md +25 -0
  58. package/docs/i18n/MULTI_INSTANCE.ko.md +25 -0
  59. package/docs/i18n/MULTI_INSTANCE.ru.md +25 -0
  60. package/docs/i18n/MULTI_INSTANCE.zh.md +25 -0
  61. package/docs/i18n/README.es.md +20 -134
  62. package/docs/i18n/README.fr.md +20 -134
  63. package/docs/i18n/README.ja.md +20 -134
  64. package/docs/i18n/README.ko.md +20 -133
  65. package/docs/i18n/README.ru.md +20 -134
  66. package/docs/i18n/README.zh.md +20 -133
  67. package/docs/i18n/RELEASE.es.md +26 -1
  68. package/docs/i18n/RELEASE.fr.md +26 -1
  69. package/docs/i18n/RELEASE.ja.md +26 -1
  70. package/docs/i18n/RELEASE.ko.md +26 -1
  71. package/docs/i18n/RELEASE.ru.md +26 -1
  72. package/docs/i18n/RELEASE.zh.md +26 -1
  73. package/docs/i18n/TROUBLESHOOTING.es.md +39 -0
  74. package/docs/i18n/TROUBLESHOOTING.fr.md +39 -0
  75. package/docs/i18n/TROUBLESHOOTING.ja.md +39 -0
  76. package/docs/i18n/TROUBLESHOOTING.ko.md +39 -0
  77. package/docs/i18n/TROUBLESHOOTING.ru.md +39 -0
  78. package/docs/i18n/TROUBLESHOOTING.zh.md +39 -0
  79. package/docs/i18n/USAGE.es.md +25 -0
  80. package/docs/i18n/USAGE.fr.md +25 -0
  81. package/docs/i18n/USAGE.ja.md +25 -0
  82. package/docs/i18n/USAGE.ko.md +25 -0
  83. package/docs/i18n/USAGE.ru.md +25 -0
  84. package/docs/i18n/USAGE.zh.md +25 -0
  85. package/docs/superpowers/plans/2026-05-13-phase1-streaming-pipeline.md +122 -0
  86. package/docs/superpowers/plans/2026-05-13-phase10-push-notifications.md +152 -0
  87. package/docs/superpowers/plans/2026-05-13-phase2-agent-adapters.md +242 -0
  88. package/docs/superpowers/plans/2026-05-13-phase6-smart-progress.md +172 -0
  89. package/docs/superpowers/plans/2026-05-13-phase7-voice-plan-mode.md +108 -0
  90. package/package.json +2 -1
  91. package/scripts/cli.mjs +4 -3
  92. package/scripts/doctor.mjs +11 -0
  93. package/scripts/install.mjs +15 -1
@@ -0,0 +1,108 @@
1
+ # Phase 7 — Voice Plan Mode Implementation Plan
2
+
3
+ > **For agentic workers:** REQUIRED SUB-SKILL: superpowers:subagent-driven-development or superpowers:executing-plans.
4
+
5
+ **Goal:** Let the user say "plan it first" and the agent returns a numbered plan, narrated step-by-step; the user can say "skip step 3", "add a test for X after step 2", or "approve" to run the modified plan.
6
+
7
+ **Architecture:** Stateful plan session in `app-node/plan_mode.mjs`. The first user request is wrapped with a planning preamble in `voiceBridgePrompt`. Agent returns a numbered plan in a `PLAN_BEGIN ... PLAN_END` envelope; we parse, narrate, and listen for follow-up voice commands. Commands mutate the plan; the approval command sends the modified plan back to the agent with an "act on this plan now" preamble.
8
+
9
+ **Tech Stack:** Node 20 ESM, existing adapter + sentencer, regex grammar (no external NLP).
10
+
11
+ ---
12
+
13
+ ## Spec
14
+
15
+ ### Plan envelope
16
+
17
+ Agent returns:
18
+ ```
19
+ PLAN_BEGIN
20
+ 1. <step>
21
+ 2. <step>
22
+ PLAN_END
23
+ ```
24
+
25
+ Parser strips envelope and yields `{ id, text, status }`.
26
+
27
+ ### Voice command grammar
28
+
29
+ - enter: `plan it first` / `plan first` / `먼저 계획`
30
+ - skip: `skip step N` / `step N 건너뛰어`
31
+ - insert: `add <text> after step N` / `step N 다음에 <text> 추가`
32
+ - approve: `approve` / `go ahead` / `실행`
33
+ - cancel: `cancel` / `취소`
34
+
35
+ ### Session state
36
+
37
+ `{ active: boolean, steps: Step[], language: 'en'|'ko' }` stored in `bridge_state.mjs` per channel.
38
+
39
+ ---
40
+
41
+ ## File Structure
42
+
43
+ - Create: `app-node/plan_mode.mjs`, `app-node/plan_mode.test.mjs`.
44
+ - Modify: `app-node/agent_adapters.mjs::voiceBridgePrompt` — add `planMode` branch.
45
+ - Modify: `app-node/discord_text.mjs` and `app-node/main.mjs` — route plan-mode utterances.
46
+
47
+ ---
48
+
49
+ ## Tasks
50
+
51
+ ### Task 1: TDD — parsers
52
+
53
+ - [ ] Write tests in `app-node/plan_mode.test.mjs`:
54
+ 1. `parsePlanOutput` extracts numbered steps between markers.
55
+ 2. `parseVoiceCommand` recognises skip (en + ko).
56
+ 3. `parseVoiceCommand` recognises insert (en + ko).
57
+ 4. `parseVoiceCommand` recognises approve in both languages.
58
+ 5. `applyCommand` skip flips a step's status.
59
+ 6. `applyCommand` insert places a new step after the named one.
60
+
61
+ - [ ] Run, expect FAIL.
62
+
63
+ ### Task 2: Implement `plan_mode.mjs`
64
+
65
+ - [ ] Functions to export:
66
+ - `parsePlanOutput(text)` — regex on `/PLAN_BEGIN\s*\n([\s\S]*?)\nPLAN_END/`, then split lines matching `^\s*(\d+)\.\s*(.+)$`.
67
+ - `parseVoiceCommand(text, language)` — small regex set, returns discriminated union `{ type: 'skip'|'insert'|'approve'|'cancel'|'unknown', ...}`.
68
+ - `applyCommand(steps, cmd)` — pure reducer.
69
+ - `renderFinalPlan(steps)` — re-numbers active steps for the approval prompt.
70
+
71
+ - [ ] Run tests: PASS.
72
+ - [ ] Commit: `feat(plan-mode): parsers and reducer`.
73
+
74
+ ### Task 3: Wire `voiceBridgePrompt`
75
+
76
+ - [ ] In `agent_adapters.mjs::voiceBridgePrompt`, accept `options.planMode`. When set, append:
77
+ ```
78
+ You are in PLAN MODE. Do NOT modify any files. Reply ONLY with a plan:
79
+ PLAN_BEGIN
80
+ 1. ...
81
+ 2. ...
82
+ PLAN_END
83
+ Each step under 12 words.
84
+ ```
85
+ Korean variant included.
86
+ - [ ] Test: `voiceBridgePrompt('do X', { planMode: true })` contains `PLAN_BEGIN`.
87
+ - [ ] Commit.
88
+
89
+ ### Task 4: Bridge wiring
90
+
91
+ - [ ] In `main.mjs`:
92
+ - Detect enter phrase → call agent with `planMode: true` → parse output → store in channel state → speak each step.
93
+ - Each follow-up utterance while `state.active` → `parseVoiceCommand` → mutate state OR on approve call agent again with `renderFinalPlan(...)` as the user prompt and clear state.
94
+ - [ ] Add integration test using a fake adapter.
95
+ - [ ] Commit.
96
+
97
+ ### Task 5: Document
98
+
99
+ - [ ] Add a "Voice plan mode" section to `docs/USAGE.md` with example transcript.
100
+ - [ ] Commit.
101
+
102
+ ---
103
+
104
+ ## Self-Review
105
+
106
+ - Spec covered.
107
+ - No placeholders.
108
+ - Names consistent: `parsePlanOutput`, `parseVoiceCommand`, `applyCommand`, `renderFinalPlan`, `planMode`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "verbalcoding",
3
- "version": "0.2.11",
3
+ "version": "0.2.12",
4
4
  "description": "Discord voice bridge for CLI coding agents.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -38,6 +38,7 @@
38
38
  "run.sh",
39
39
  ".env.example",
40
40
  "README.md",
41
+ "README.*.md",
41
42
  "LICENSE"
42
43
  ],
43
44
  "scripts": {
package/scripts/cli.mjs CHANGED
@@ -48,9 +48,10 @@ Usage:
48
48
  vc doctor
49
49
 
50
50
  Examples:
51
- npx verbalcoding setup --yes
52
- vc setup --yes
53
- vc setup token
51
+ npx verbalcoding setup
52
+ vc setup
53
+ vc setup --yes # automation/non-interactive starter config
54
+ vc setup token # later token update
54
55
  vc setup channels "General,Team Voice"
55
56
  vc start
56
57
  vc language en
@@ -5,6 +5,7 @@ import { spawnSync } from 'node:child_process';
5
5
  import { parseKeyValueEnv } from '../app-node/install_config.mjs';
6
6
  import { checkInstanceConfigs, formatInstanceDoctor } from '../app-node/instance_doctor.mjs';
7
7
  import { autoRestartVoiceBotEnabled } from '../app-node/restart_policy.mjs';
8
+ import { detectInstalledAgents, formatAgentDetectionReport } from '../app-node/agent_detect.mjs';
8
9
 
9
10
  const ROOT = path.resolve(path.dirname(new URL(import.meta.url).pathname), '..');
10
11
  const args = process.argv.slice(2);
@@ -210,6 +211,16 @@ if (!autoFixEnabled) note('Automatic prerequisite bootstrap', 'off');
210
211
  if (autoFixAttempted) note('Automatic prerequisite bootstrap', 'attempted');
211
212
  console.log('');
212
213
 
214
+ try {
215
+ const detection = await detectInstalledAgents(env);
216
+ console.log(formatAgentDetectionReport(detection));
217
+ const selected = detection.find(r => r.backend === backend || r.backend === backend.replace(/-/g, ''));
218
+ if (selected && !selected.present) note(`Selected backend "${backend}"`, `binary ${selected.bin} not on PATH`);
219
+ console.log('');
220
+ } catch (e) {
221
+ note('Agent backend detection', `skipped: ${e?.message || e}`);
222
+ }
223
+
213
224
  const nodeCommand = commandExists('node');
214
225
  const npmCommand = commandExists('npm');
215
226
  const ffmpegCommand = commandExists('ffmpeg');
@@ -4,6 +4,7 @@ import path from 'node:path';
4
4
  import readline from 'node:readline/promises';
5
5
  import { stdin as input, stdout as output } from 'node:process';
6
6
  import { buildEnvFile, normalizeInstallAnswers, renderInstallSummary, SUPPORTED_HARNESSES } from '../app-node/install_config.mjs';
7
+ import { detectInstalledAgents, pickDefaultBackend, formatAgentDetectionReport } from '../app-node/agent_detect.mjs';
7
8
 
8
9
  const ROOT = path.resolve(path.dirname(new URL(import.meta.url).pathname), '..');
9
10
 
@@ -138,7 +139,20 @@ async function main() {
138
139
  try {
139
140
  console.log('VerbalCoding installer');
140
141
  console.log(`Supported harnesses: ${SUPPORTED_HARNESSES.join(', ')}`);
141
- const harness = await ask('Harness/backend', 'hermes');
142
+ console.log('Discord setup: keep https://discord.com/developers/applications open.');
143
+ console.log('Create an application/bot, enable Message Content intent, then paste the bot token and application/client ID below.');
144
+ console.log('If you are not ready, press Enter to skip and run `vc setup token` / `vc setup channels` later.');
145
+ let detectionDefault = 'hermes';
146
+ try {
147
+ const detection = await detectInstalledAgents(process.env);
148
+ console.log('');
149
+ console.log(formatAgentDetectionReport(detection));
150
+ detectionDefault = pickDefaultBackend(detection, process.env.AGENT_BACKEND);
151
+ console.log('');
152
+ } catch (e) {
153
+ console.log(`(agent detection skipped: ${e?.message || e})`);
154
+ }
155
+ const harness = await ask('Harness/backend', detectionDefault);
142
156
  let agentCommand = '';
143
157
  let agentLabel = '';
144
158
  if (harness.toLowerCase() === 'custom') {