@pellux/goodvibes-tui 0.20.3 → 0.22.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.
- package/CHANGELOG.md +50 -0
- package/README.md +23 -2
- package/docs/foundation-artifacts/operator-contract.json +78 -1
- package/package.json +4 -2
- package/src/audio/spoken-turn-controller.ts +31 -1
- package/src/audio/spoken-turn-wiring.ts +26 -4
- package/src/cli/bundle-command.ts +1 -1
- package/src/cli/completions/generate.ts +658 -0
- package/src/cli/config-overrides.ts +68 -0
- package/src/cli/entrypoint.ts +6 -0
- package/src/cli/help.ts +4 -2
- package/src/cli/management-commands.ts +1 -1
- package/src/cli/management.ts +1 -8
- package/src/cli/parser.ts +31 -18
- package/src/cli/service-command.ts +1 -1
- package/src/cli/surface-command.ts +1 -1
- package/src/cli/tui-startup.ts +72 -10
- package/src/cli/types.ts +14 -3
- package/src/cli-flags.ts +1 -0
- package/src/config/atomic-write.ts +70 -0
- package/src/config/goodvibes-home-audit.ts +2 -0
- package/src/config/read-versioned.ts +115 -0
- package/src/core/context-auto-compact.ts +77 -0
- package/src/core/conversation-rendering.ts +49 -15
- package/src/core/conversation.ts +101 -16
- package/src/core/format-user-error.ts +192 -0
- package/src/core/stream-event-wiring.ts +144 -0
- package/src/core/stream-stall-watchdog.ts +103 -0
- package/src/core/system-message-router.ts +5 -1
- package/src/core/turn-event-wiring.ts +124 -0
- package/src/daemon/cli.ts +5 -0
- package/src/export/cost-utils.ts +71 -0
- package/src/export/gist-uploader.ts +136 -0
- package/src/input/command-registry.ts +32 -1
- package/src/input/commands/control-room-runtime.ts +10 -10
- package/src/input/commands/experience-runtime.ts +5 -4
- package/src/input/commands/knowledge.ts +1 -1
- package/src/input/commands/local-auth-runtime.ts +27 -5
- package/src/input/commands/local-setup.ts +4 -6
- package/src/input/commands/memory-product-runtime.ts +8 -6
- package/src/input/commands/operator-panel-runtime.ts +1 -1
- package/src/input/commands/operator-runtime.ts +3 -10
- package/src/input/commands/{integration-runtime.ts → plugin-runtime.ts} +1 -1
- package/src/input/commands/provider.ts +57 -3
- package/src/input/commands/recall-review.ts +26 -2
- package/src/input/commands/services-runtime.ts +2 -2
- package/src/input/commands/session-workflow.ts +8 -16
- package/src/input/commands/session.ts +70 -20
- package/src/input/commands/share-runtime.ts +99 -12
- package/src/input/commands/tts-runtime.ts +30 -4
- package/src/input/commands.ts +2 -4
- package/src/input/delete-key-policy.ts +46 -0
- package/src/input/feed-context-factory.ts +2 -0
- package/src/input/handler-feed.ts +3 -0
- package/src/input/handler-interactions.ts +2 -15
- package/src/input/handler-modal-routes.ts +128 -12
- package/src/input/handler-modal-token-routes.ts +22 -5
- package/src/input/handler-onboarding-cloudflare.ts +1 -1
- package/src/input/handler-onboarding.ts +73 -69
- package/src/input/handler-types.ts +163 -0
- package/src/input/handler.ts +6 -2
- package/src/input/input-history.ts +76 -6
- package/src/input/model-picker-filter.ts +265 -0
- package/src/input/model-picker-items.ts +208 -0
- package/src/input/model-picker.ts +92 -325
- package/src/input/onboarding/handler-onboarding-routes.ts +7 -2
- package/src/input/onboarding/onboarding-verification-helpers.ts +76 -0
- package/src/input/onboarding/onboarding-wizard-apply.ts +14 -4
- package/src/input/onboarding/onboarding-wizard-cloudflare-step.ts +16 -2
- package/src/input/onboarding/onboarding-wizard-cloudflare.ts +8 -8
- package/src/input/onboarding/onboarding-wizard-external-surface-extra-specs.ts +1 -1
- package/src/input/onboarding/onboarding-wizard-external-surfaces.ts +2 -29
- package/src/input/onboarding/onboarding-wizard-rules.ts +28 -28
- package/src/input/onboarding/onboarding-wizard-state.ts +20 -20
- package/src/input/onboarding/onboarding-wizard-steps.ts +24 -25
- package/src/input/onboarding/onboarding-wizard-types.ts +145 -3
- package/src/input/onboarding/onboarding-wizard-validation.ts +77 -0
- package/src/input/onboarding/onboarding-wizard.ts +3 -3
- package/src/input/settings-modal-behavior.ts +5 -0
- package/src/input/settings-modal-data.ts +378 -0
- package/src/input/settings-modal-mutations.ts +157 -0
- package/src/input/settings-modal-reset.ts +154 -0
- package/src/input/settings-modal.ts +236 -232
- package/src/main.ts +93 -85
- package/src/panels/agent-inspector-panel.ts +120 -18
- package/src/panels/agent-inspector-shared.ts +29 -0
- package/src/panels/builtin/agent.ts +4 -1
- package/src/panels/builtin/development.ts +5 -1
- package/src/panels/builtin/knowledge.ts +14 -13
- package/src/panels/builtin/operations.ts +22 -1
- package/src/panels/builtin/shared.ts +7 -0
- package/src/panels/cockpit-panel.ts +123 -3
- package/src/panels/cockpit-read-model.ts +232 -0
- package/src/panels/confirm-state.ts +27 -12
- package/src/panels/cost-tracker-panel.ts +23 -67
- package/src/panels/eval-panel.ts +10 -9
- package/src/panels/index.ts +1 -1
- package/src/panels/knowledge-graph-panel.ts +84 -0
- package/src/panels/local-auth-panel.ts +124 -4
- package/src/panels/memory-panel.ts +370 -40
- package/src/panels/project-planning-panel.ts +42 -4
- package/src/panels/search-focus.ts +11 -5
- package/src/panels/session-maintenance.ts +66 -15
- package/src/panels/subscription-panel.ts +33 -25
- package/src/panels/types.ts +28 -1
- package/src/panels/wrfc-panel.ts +224 -41
- package/src/renderer/agent-detail-modal.ts +118 -13
- package/src/renderer/code-block.ts +10 -2
- package/src/renderer/compositor.ts +18 -4
- package/src/renderer/context-inspector.ts +1 -5
- package/src/renderer/context-status-hint.ts +54 -0
- package/src/renderer/diff.ts +94 -21
- package/src/renderer/markdown.ts +29 -13
- package/src/renderer/settings-modal-helpers.ts +1 -1
- package/src/renderer/settings-modal.ts +90 -10
- package/src/renderer/shell-surface.ts +10 -0
- package/src/renderer/syntax-highlighter.ts +10 -3
- package/src/renderer/term-caps.ts +318 -0
- package/src/renderer/theme.ts +158 -0
- package/src/renderer/tool-call.ts +12 -2
- package/src/renderer/ui-factory.ts +50 -6
- package/src/runtime/bootstrap-command-context.ts +1 -0
- package/src/runtime/bootstrap-command-parts.ts +18 -0
- package/src/runtime/bootstrap-core.ts +145 -13
- package/src/runtime/bootstrap-shell.ts +11 -0
- package/src/runtime/bootstrap.ts +9 -0
- package/src/runtime/onboarding/apply.ts +4 -6
- package/src/runtime/onboarding/index.ts +1 -0
- package/src/runtime/onboarding/markers.ts +42 -49
- package/src/runtime/onboarding/progress.ts +148 -0
- package/src/runtime/onboarding/state.ts +133 -55
- package/src/runtime/onboarding/types.ts +20 -0
- package/src/runtime/services.ts +27 -1
- package/src/runtime/wrfc-persistence.ts +237 -0
- package/src/shell/blocking-input.ts +20 -5
- package/src/tools/wrfc-agent-guard.ts +64 -3
- package/src/utils/format-elapsed.ts +30 -0
- package/src/utils/terminal-width.ts +45 -0
- package/src/version.ts +1 -1
- package/src/work-plans/work-plan-store.ts +4 -6
- package/src/panels/knowledge-panel.ts +0 -345
- package/src/planning/project-planning-coordinator.ts +0 -543
|
@@ -25,6 +25,7 @@ export class SpokenTurnController {
|
|
|
25
25
|
private readonly abortControllers = new Set<AbortController>();
|
|
26
26
|
private timer: ReturnType<typeof setInterval> | null = null;
|
|
27
27
|
private errorReportedForTurn = false;
|
|
28
|
+
private noPlayerNoticed = false;
|
|
28
29
|
private readonly voiceService: Pick<VoiceService, 'synthesizeStream'>;
|
|
29
30
|
private readonly configManager: Pick<ConfigManager, 'get'>;
|
|
30
31
|
private readonly player: StreamingAudioPlayer;
|
|
@@ -48,9 +49,14 @@ export class SpokenTurnController {
|
|
|
48
49
|
if (!normalized) return false;
|
|
49
50
|
this.stop();
|
|
50
51
|
if (!this.player.available) {
|
|
51
|
-
this.
|
|
52
|
+
if (!this.noPlayerNoticed) {
|
|
53
|
+
this.noPlayerNoticed = true;
|
|
54
|
+
this.notify?.('[TTS] Text response will continue, but live audio is unavailable. Install mpv or ffplay.');
|
|
55
|
+
}
|
|
52
56
|
return false;
|
|
53
57
|
}
|
|
58
|
+
// Reset the no-player notice if player becomes available again.
|
|
59
|
+
this.noPlayerNoticed = false;
|
|
54
60
|
this.pendingPrompt = normalized;
|
|
55
61
|
return true;
|
|
56
62
|
}
|
|
@@ -169,10 +175,15 @@ export class SpokenTurnController {
|
|
|
169
175
|
}
|
|
170
176
|
|
|
171
177
|
private synthesize(text: string, turnId: string, sequence: number, signal: AbortSignal): Promise<VoiceSynthesisStreamResult> {
|
|
178
|
+
// tts.speed: VoiceSynthesisRequest accepts speed (number | undefined).
|
|
179
|
+
// No ConfigKey for tts.speed exists in the current SDK schema — pending
|
|
180
|
+
// SDK schema addition. Speed is not threaded from config until that key
|
|
181
|
+
// is added. See docs/voice-and-live-tts.md § Speed.
|
|
172
182
|
return this.voiceService.synthesizeStream(readOptionalConfigString(this.configManager, 'tts.provider'), {
|
|
173
183
|
text,
|
|
174
184
|
voiceId: readOptionalConfigString(this.configManager, 'tts.voice'),
|
|
175
185
|
format: 'mp3',
|
|
186
|
+
speed: readOptionalConfigNumber(this.configManager, 'tts.speed'),
|
|
176
187
|
signal,
|
|
177
188
|
metadata: {
|
|
178
189
|
source: 'goodvibes-tui',
|
|
@@ -201,3 +212,22 @@ function readOptionalConfigString(configManager: Pick<ConfigManager, 'get'>, key
|
|
|
201
212
|
const value = String(configManager.get(key) ?? '').trim();
|
|
202
213
|
return value || undefined;
|
|
203
214
|
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* readOptionalConfigNumber — reads a numeric config value by key.
|
|
218
|
+
*
|
|
219
|
+
* `tts.speed` is not yet a ConfigKey in the SDK schema. This helper accepts
|
|
220
|
+
* a string key and casts it, returning undefined when the value is absent,
|
|
221
|
+
* zero, or not a finite positive number. Once `tts.speed` is added to the
|
|
222
|
+
* SDK schema the cast can be removed and the key typed statically.
|
|
223
|
+
*
|
|
224
|
+
* SDK handoff note: add { key: 'tts.speed', type: 'number', default: 1,
|
|
225
|
+
* description: '...' } to schema-domain-core.js and `tts: { ..., speed: 1 }`
|
|
226
|
+
* to DEFAULT_CONFIG.tts to complete this feature.
|
|
227
|
+
*/
|
|
228
|
+
function readOptionalConfigNumber(configManager: Pick<ConfigManager, 'get'>, key: string): number | undefined {
|
|
229
|
+
// Cast required: key is not yet a valid ConfigKey in the SDK schema.
|
|
230
|
+
const raw = configManager.get(key as ConfigKey);
|
|
231
|
+
const value = typeof raw === 'number' ? raw : parseFloat(String(raw ?? ''));
|
|
232
|
+
return isFinite(value) && value > 0 ? value : undefined;
|
|
233
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ConfigManager } from '@pellux/goodvibes-sdk/platform/config';
|
|
2
2
|
import type { UiRuntimeEvents } from '@/runtime/index.ts';
|
|
3
3
|
import type { VoiceService } from '@pellux/goodvibes-sdk/platform/voice';
|
|
4
|
+
import type { StreamingAudioPlayer } from './player.ts';
|
|
4
5
|
import { LocalStreamingAudioPlayer } from './player.ts';
|
|
5
6
|
import { SpokenTurnController } from './spoken-turn-controller.ts';
|
|
6
7
|
|
|
@@ -11,23 +12,44 @@ export interface SpokenTurnRuntime {
|
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
export interface WireSpokenTurnRuntimeOptions {
|
|
14
|
-
readonly voiceService: VoiceService
|
|
15
|
-
readonly configManager: ConfigManager
|
|
15
|
+
readonly voiceService: Pick<VoiceService, 'synthesizeStream'>;
|
|
16
|
+
readonly configManager: Pick<ConfigManager, 'get'>;
|
|
16
17
|
readonly events: UiRuntimeEvents;
|
|
17
18
|
readonly notify: (message: string) => void;
|
|
19
|
+
/**
|
|
20
|
+
* Optional player factory — injected in tests to avoid spawning real
|
|
21
|
+
* subprocesses. Defaults to LocalStreamingAudioPlayer.
|
|
22
|
+
*/
|
|
23
|
+
readonly playerFactory?: () => StreamingAudioPlayer;
|
|
18
24
|
}
|
|
19
25
|
|
|
26
|
+
/**
|
|
27
|
+
* wireSpokenTurnRuntime — wires the spoken-turn pipeline against the runtime
|
|
28
|
+
* event bus.
|
|
29
|
+
*
|
|
30
|
+
* Always-speak mode: when `ui.voiceEnabled` is true in config, every
|
|
31
|
+
* TURN_SUBMITTED event arms the turn for spoken output automatically — the
|
|
32
|
+
* user does not need to prefix the prompt with /tts. The availability check
|
|
33
|
+
* inside SpokenTurnController still gates gracefully when no player is found.
|
|
34
|
+
*/
|
|
20
35
|
export function wireSpokenTurnRuntime(options: WireSpokenTurnRuntimeOptions): SpokenTurnRuntime {
|
|
36
|
+
const player = options.playerFactory ? options.playerFactory() : new LocalStreamingAudioPlayer();
|
|
21
37
|
const controller = new SpokenTurnController({
|
|
22
38
|
voiceService: options.voiceService,
|
|
23
39
|
configManager: options.configManager,
|
|
24
|
-
player
|
|
40
|
+
player,
|
|
25
41
|
notify: options.notify,
|
|
26
42
|
});
|
|
27
43
|
|
|
28
44
|
const turns = options.events.turns;
|
|
29
45
|
const unsubs = [
|
|
30
|
-
turns.on('TURN_SUBMITTED', (event) =>
|
|
46
|
+
turns.on('TURN_SUBMITTED', (event) => {
|
|
47
|
+
// Always-speak mode: auto-arm when ui.voiceEnabled is set.
|
|
48
|
+
if (options.configManager.get('ui.voiceEnabled')) {
|
|
49
|
+
controller.submitNextTurn(event.prompt);
|
|
50
|
+
}
|
|
51
|
+
controller.handleTurnEvent(event);
|
|
52
|
+
}),
|
|
31
53
|
turns.on('PREFLIGHT_FAIL', (event) => controller.handleTurnEvent(event)),
|
|
32
54
|
turns.on('STREAM_DELTA', (event) => controller.handleTurnEvent(event)),
|
|
33
55
|
turns.on('STREAM_END', (event) => controller.handleTurnEvent(event)),
|
|
@@ -9,7 +9,7 @@ import { getOnboardingCheckMarkerPath } from '../runtime/onboarding/index.ts';
|
|
|
9
9
|
import { CONFIG_SCHEMA } from '../config/index.ts';
|
|
10
10
|
import { SecretsManager } from '../config/secrets.ts';
|
|
11
11
|
import type { ConfigKey } from '../config/index.ts';
|
|
12
|
-
import type { CliCommandRuntime } from './
|
|
12
|
+
import type { CliCommandRuntime } from './types.ts';
|
|
13
13
|
import type { CliCommandOutput } from './types.ts';
|
|
14
14
|
import { getPackageVersion } from './help.ts';
|
|
15
15
|
import { classifyProviderSetup } from './provider-classification.ts';
|