@pellux/goodvibes-tui 1.16.1 → 1.18.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 +138 -9
- package/README.md +1 -1
- package/docs/foundation-artifacts/operator-contract.json +5490 -1806
- package/package.json +7 -7
- package/src/cli/completions/generate.ts +5 -4
- package/src/cli/config-overrides.ts +51 -11
- package/src/cli/doctor.ts +4 -5
- package/src/cli/entrypoint.ts +13 -8
- package/src/cli/help.ts +7 -6
- package/src/cli/launch-auto-update.ts +214 -0
- package/src/cli/management-commands.ts +82 -15
- package/src/cli/management.ts +0 -2
- package/src/cli/parser.ts +5 -0
- package/src/cli/status.ts +13 -0
- package/src/cli/surface-command.ts +5 -5
- package/src/cli/tui-startup.ts +60 -97
- package/src/cli/types.ts +2 -0
- package/src/config/index.ts +1 -1
- package/src/config/tui-extension-settings.ts +33 -0
- package/src/core/composer-state.ts +1 -1
- package/src/core/consolidation-receipt.ts +41 -0
- package/src/core/conversation-line-cache.ts +3 -3
- package/src/core/conversation-rendering.ts +18 -9
- package/src/core/conversation.ts +2 -2
- package/src/core/long-task-notifier.ts +7 -7
- package/src/core/memory-provenance.ts +67 -0
- package/src/core/pairing-devices.ts +49 -0
- package/src/core/pairing-handoff.ts +101 -0
- package/src/core/pairing-offers.ts +83 -0
- package/src/core/pairing-origin.ts +78 -0
- package/src/core/pairing-tailscale-gateway.ts +56 -0
- package/src/core/power-chip-source.ts +91 -0
- package/src/core/power-status.ts +95 -0
- package/src/core/stable-host.ts +171 -0
- package/src/core/stream-event-wiring.ts +29 -6
- package/src/core/system-message-noise.ts +1 -1
- package/src/core/system-message-router.ts +6 -6
- package/src/core/turn-budget-outcome.ts +60 -0
- package/src/core/turn-cancellation.ts +40 -1
- package/src/core/turn-event-wiring.ts +14 -8
- package/src/daemon/cli.ts +64 -58
- package/src/daemon/lifecycle.ts +41 -0
- package/src/daemon/service-commands.ts +5 -5
- package/src/export/cost-utils.ts +128 -6
- package/src/input/autocomplete.ts +2 -2
- package/src/input/command-registry.ts +55 -9
- package/src/input/commands/acp-runtime.ts +72 -0
- package/src/input/commands/ci-runtime.ts +5 -1
- package/src/input/commands/codebase-runtime.ts +6 -6
- package/src/input/commands/cost-runtime.ts +1 -1
- package/src/input/commands/devices-runtime.ts +109 -0
- package/src/input/commands/git-runtime.ts +28 -4
- package/src/input/commands/graph-runtime.ts +45 -0
- package/src/input/commands/health-runtime.ts +2 -2
- package/src/input/commands/intelligence-runtime.ts +1 -1
- package/src/input/commands/local-auth-runtime.ts +1 -1
- package/src/input/commands/local-provider-runtime.ts +49 -10
- package/src/input/commands/local-runtime.ts +53 -5
- package/src/input/commands/memory.ts +2 -2
- package/src/input/commands/operator-panel-runtime.ts +5 -5
- package/src/input/commands/operator-rpc.ts +32 -11
- package/src/input/commands/permissions-provenance.ts +1 -1
- package/src/input/commands/permissions-runtime.ts +99 -8
- package/src/input/commands/planning-runtime.ts +3 -3
- package/src/input/commands/platform-sandbox-runtime.ts +1 -1
- package/src/input/commands/power-runtime.ts +56 -0
- package/src/input/commands/provider-accounts-runtime.ts +71 -6
- package/src/input/commands/provider.ts +7 -5
- package/src/input/commands/qrcode-runtime.ts +14 -19
- package/src/input/commands/queue-runtime.ts +70 -0
- package/src/input/commands/recall-files-git.ts +13 -51
- package/src/input/commands/recall-files.ts +8 -11
- package/src/input/commands/recall-review.ts +2 -2
- package/src/input/commands/relay-runtime.ts +1 -1
- package/src/input/commands/remote-runtime.ts +1 -1
- package/src/input/commands/runtime-services.ts +4 -4
- package/src/input/commands/schedule-runtime.ts +14 -7
- package/src/input/commands/services-runtime.ts +1 -1
- package/src/input/commands/session-workflow.ts +2 -2
- package/src/input/commands/settings-sync-runtime.ts +2 -2
- package/src/input/commands/share-runtime.ts +1 -1
- package/src/input/commands/shell-core.ts +46 -68
- package/src/input/commands/subscription-runtime.ts +1 -1
- package/src/input/commands/update-runtime.ts +153 -96
- package/src/input/commands/work-plan-runtime.ts +1 -1
- package/src/input/commands/workstream-attempts.ts +6 -1
- package/src/input/commands/workstream-runtime.ts +46 -27
- package/src/input/commands/worktree-runtime.ts +35 -8
- package/src/input/commands.ts +10 -2
- package/src/input/config-modal-types.ts +14 -3
- package/src/input/config-modal.ts +75 -13
- package/src/input/feature-unit-layout.ts +93 -82
- package/src/input/feed-context-factory.ts +2 -2
- package/src/input/handler-command-route.ts +2 -2
- package/src/input/handler-content-actions.ts +1 -1
- package/src/input/handler-feed-routes.ts +7 -7
- package/src/input/handler-feed.ts +4 -4
- package/src/input/handler-interactions.ts +3 -2
- package/src/input/handler-modal-routes.ts +12 -4
- package/src/input/handler-modal-token-routes.ts +1 -1
- package/src/input/handler-onboarding-daemon-adopt.ts +2 -2
- package/src/input/handler-onboarding.ts +3 -2
- package/src/input/handler-picker-routes.ts +26 -13
- package/src/input/handler-shortcuts.ts +29 -6
- package/src/input/handler.ts +2 -2
- package/src/input/keybindings.ts +21 -3
- package/src/input/onboarding/onboarding-feature-units.ts +34 -27
- package/src/input/onboarding/onboarding-provider-key-fields.ts +112 -0
- package/src/input/onboarding/onboarding-wizard-apply.ts +22 -21
- package/src/input/onboarding/onboarding-wizard-external-surfaces.ts +17 -0
- package/src/input/onboarding/onboarding-wizard-network-adopt.ts +2 -2
- package/src/input/onboarding/onboarding-wizard-steps.ts +30 -42
- package/src/input/panel-integration-actions.ts +2 -2
- package/src/input/panel-mouse-geometry.ts +1 -1
- package/src/input/panel-paste-flood-guard.ts +1 -1
- package/src/input/provider-key-intake.ts +167 -0
- package/src/input/sandbox-exec-config.ts +2 -2
- package/src/input/selection-modal.ts +1 -1
- package/src/input/settings-modal-activation.ts +5 -0
- package/src/input/settings-modal-adjustment.ts +4 -31
- package/src/input/settings-modal-data.ts +52 -57
- package/src/input/settings-modal-mutations.ts +12 -68
- package/src/input/settings-modal-types.ts +27 -17
- package/src/input/settings-modal.ts +74 -55
- package/src/main.ts +90 -90
- package/src/panels/agent-inspector-shared.ts +4 -4
- package/src/panels/base-panel.ts +2 -2
- package/src/panels/builtin/agent.ts +4 -4
- package/src/panels/builtin/development.ts +4 -4
- package/src/panels/builtin/knowledge.ts +1 -1
- package/src/panels/builtin/operations.ts +83 -11
- package/src/panels/builtin/session.ts +5 -5
- package/src/panels/builtin/shared.ts +16 -4
- package/src/panels/builtin-modals.ts +59 -42
- package/src/panels/builtin-panels.ts +1 -1
- package/src/panels/cost-tracker-panel.ts +124 -7
- package/src/panels/diff-panel.ts +39 -6
- package/src/panels/eval-registry.ts +2 -2
- package/src/panels/fleet-acts.ts +446 -0
- package/src/panels/fleet-deep-link.ts +1 -1
- package/src/panels/fleet-gateway.ts +117 -0
- package/src/panels/fleet-observed-render.ts +128 -0
- package/src/panels/fleet-panel-format.ts +163 -11
- package/src/panels/fleet-panel-worktree-detail.ts +14 -0
- package/src/panels/fleet-panel.ts +73 -57
- package/src/panels/fleet-read-model.ts +84 -14
- package/src/panels/fleet-spawn.ts +266 -0
- package/src/panels/fleet-steer.ts +2 -2
- package/src/panels/fleet-stop.ts +41 -5
- package/src/panels/fleet-tabs.ts +15 -16
- package/src/panels/fleet-transcript.ts +5 -5
- package/src/panels/git-panel.ts +2 -2
- package/src/panels/index.ts +4 -1
- package/src/panels/local-auth-panel.ts +1 -1
- package/src/panels/memory-consolidation-gateway.ts +94 -0
- package/src/panels/modals/devices-modal.ts +161 -0
- package/src/panels/modals/hooks-modal.ts +1 -1
- package/src/panels/modals/keybindings-modal.ts +2 -2
- package/src/panels/modals/knowledge-modal.ts +1 -1
- package/src/panels/modals/marketplace-modal.ts +4 -4
- package/src/panels/modals/memory-modal.ts +153 -9
- package/src/panels/modals/modal-surface-helpers.ts +1 -1
- package/src/panels/modals/modal-theme.ts +1 -1
- package/src/panels/modals/pairing-modal.ts +198 -68
- package/src/panels/modals/planning-modal.ts +2 -2
- package/src/panels/modals/plugins-modal.ts +1 -1
- package/src/panels/modals/policy-modal.ts +1 -1
- package/src/panels/modals/security-modal.ts +7 -1
- package/src/panels/modals/skills-modal.ts +1 -1
- package/src/panels/modals/work-plan-modal.ts +3 -3
- package/src/panels/notifications-feed.ts +127 -0
- package/src/panels/notifications-panel.ts +160 -0
- package/src/panels/panel-manager.ts +9 -9
- package/src/panels/plugins-panel.ts +4 -4
- package/src/panels/project-planning-answer-actions.ts +1 -1
- package/src/panels/provider-health-routes.ts +2 -2
- package/src/panels/skills-panel.ts +4 -5
- package/src/panels/token-budget-panel.ts +11 -3
- package/src/panels/types.ts +5 -5
- package/src/panels/workstream-graph-render.ts +123 -0
- package/src/permissions/broker-approval-card.ts +201 -0
- package/src/permissions/hunk-selection.ts +28 -4
- package/src/permissions/prompt.ts +244 -29
- package/src/renderer/autocomplete-overlay.ts +107 -54
- package/src/renderer/code-block.ts +2 -2
- package/src/renderer/compaction-history-modal.ts +1 -1
- package/src/renderer/compaction-preview.ts +1 -1
- package/src/renderer/compaction-quality.ts +1 -1
- package/src/renderer/composer-fragments.ts +69 -0
- package/src/renderer/compositor.ts +2 -2
- package/src/renderer/config-modal.ts +1 -1
- package/src/renderer/conversation-overlays.ts +1 -1
- package/src/renderer/footer-tips.ts +3 -3
- package/src/renderer/hint-grammar.ts +1 -1
- package/src/renderer/modal-factory.ts +1 -1
- package/src/renderer/model-picker-overlay.ts +1 -1
- package/src/renderer/model-workspace.ts +7 -2
- package/src/renderer/panel-composite.ts +2 -2
- package/src/renderer/panel-workspace-bar.ts +1 -1
- package/src/renderer/process-indicator.ts +1 -1
- package/src/renderer/selection-modal-overlay.ts +1 -1
- package/src/renderer/session-picker-modal.ts +2 -2
- package/src/renderer/settings-modal-helpers.ts +23 -5
- package/src/renderer/settings-modal.ts +129 -39
- package/src/renderer/shell-surface.ts +6 -0
- package/src/renderer/terminal-bg-probe.ts +1 -1
- package/src/renderer/theme.ts +3 -3
- package/src/renderer/tool-call.ts +13 -7
- package/src/renderer/tool-result-summary.ts +1 -1
- package/src/renderer/turn-injection.ts +7 -6
- package/src/renderer/ui-factory.ts +38 -1
- package/src/runtime/bootstrap-command-context.ts +7 -2
- package/src/runtime/bootstrap-command-parts.ts +9 -5
- package/src/runtime/bootstrap-core.ts +41 -41
- package/src/runtime/bootstrap-hook-bridge.ts +1 -1
- package/src/runtime/bootstrap-shell.ts +13 -5
- package/src/runtime/bootstrap.ts +34 -32
- package/src/runtime/channel-composition.ts +46 -0
- package/src/runtime/code-index-services.ts +3 -4
- package/src/runtime/daemon-attach-notices.ts +120 -0
- package/src/runtime/durability-services.ts +90 -0
- package/src/runtime/embedded-service-factories.ts +40 -0
- package/src/runtime/feature-settings.ts +147 -0
- package/src/runtime/fleet-services.ts +41 -0
- package/src/runtime/idle-power-services.ts +85 -0
- package/src/runtime/index.ts +6 -21
- package/src/runtime/interaction-seams.ts +109 -0
- package/src/runtime/legacy-daemon-migration.ts +29 -19
- package/src/runtime/memory-fold.ts +1 -1
- package/src/runtime/notification-dispatch.ts +110 -0
- package/src/runtime/onboarding/apply.ts +3 -29
- package/src/runtime/onboarding/fast-path.ts +39 -6
- package/src/runtime/onboarding/provider-key-capture.ts +126 -0
- package/src/runtime/onboarding/snapshot.ts +0 -1
- package/src/runtime/onboarding/types.ts +9 -3
- package/src/runtime/power-keepawake-remote.ts +75 -0
- package/src/runtime/process-lifecycle.ts +3 -1
- package/src/runtime/provider-fallback.ts +55 -0
- package/src/runtime/provider-optimizer-wiring.ts +55 -0
- package/src/runtime/release-artifacts.ts +19 -103
- package/src/runtime/resume-notice.ts +1 -1
- package/src/runtime/services.ts +113 -113
- package/src/runtime/session-continuity-hints.ts +38 -0
- package/src/runtime/surface-feature-flags.ts +40 -9
- package/src/runtime/terminal-output-guard.ts +2 -2
- package/src/runtime/trust/workspace-registration.ts +10 -2
- package/src/runtime/trust/workspace-trust.ts +58 -31
- package/src/runtime/ui-services.ts +6 -1
- package/src/runtime/update-check.ts +15 -69
- package/src/runtime/workstream-services.ts +2 -2
- package/src/shell/blocking-input.ts +108 -132
- package/src/shell/recovery-input-helpers.ts +53 -166
- package/src/shell/ui-openers.ts +38 -6
- package/src/utils/format-duration.ts +1 -1
- package/src/verification/verification-ledger.ts +21 -4
- package/src/version.ts +1 -1
- package/src/input/commands/flags-runtime.ts +0 -328
|
@@ -5,9 +5,12 @@
|
|
|
5
5
|
* - Active category (Tab to cycle)
|
|
6
6
|
* - Selected setting index within category (↑↓)
|
|
7
7
|
* - Editing mode for inline string/number input
|
|
8
|
-
* - Feature
|
|
8
|
+
* - Feature-unit headers (each capability's real enablement row in its domain)
|
|
9
9
|
*
|
|
10
|
-
*
|
|
10
|
+
* Every save is a plain configManager.set(key, value) on a domain settings
|
|
11
|
+
* key; the SDK settings bridge keeps the runtime gate manager in sync, and
|
|
12
|
+
* this modal re-reads the manager after enablement writes so pending-restart
|
|
13
|
+
* markers are shown honestly at the point of change.
|
|
11
14
|
*
|
|
12
15
|
* Data assembly delegates to settings-modal-data.ts (buildSettingGroups, etc.).
|
|
13
16
|
* Mutation logic delegates to settings-modal-mutations.ts (applySettingValue, etc.).
|
|
@@ -41,7 +44,6 @@ import {
|
|
|
41
44
|
} from './settings-modal-types.ts';
|
|
42
45
|
import {
|
|
43
46
|
buildSettingGroups,
|
|
44
|
-
buildFlagEntries,
|
|
45
47
|
buildMcpEntries,
|
|
46
48
|
buildSubscriptionEntries,
|
|
47
49
|
buildNetworkFilteredItems,
|
|
@@ -51,9 +53,10 @@ import {
|
|
|
51
53
|
import { getSettingLabel } from '../renderer/settings-modal-helpers.ts';
|
|
52
54
|
import {
|
|
53
55
|
applySettingValue,
|
|
54
|
-
|
|
56
|
+
syncFlagEntryFromManager,
|
|
55
57
|
type SettingAppliedCallback,
|
|
56
58
|
} from './settings-modal-mutations.ts';
|
|
59
|
+
import { featureEnablementWrite, isFeatureValueEnabled } from '../runtime/feature-settings.ts';
|
|
57
60
|
import {
|
|
58
61
|
activateSelected as _activateSelected,
|
|
59
62
|
handleSubscriptionLogoutKey as _handleSubscriptionLogoutKey,
|
|
@@ -117,6 +120,13 @@ export class SettingsModal {
|
|
|
117
120
|
|
|
118
121
|
/** Current value of the inline edit buffer. */
|
|
119
122
|
public editBuffer = '';
|
|
123
|
+
/**
|
|
124
|
+
* Scroll offset (in wrapped lines) of the documentation pane for the
|
|
125
|
+
* selected row. The renderer clamps it to the pane's real content height
|
|
126
|
+
* and shows honest more-above/below markers — long feature documentation
|
|
127
|
+
* scrolls, it never clips. Reset whenever the selection changes.
|
|
128
|
+
*/
|
|
129
|
+
public contextScroll = 0;
|
|
120
130
|
/** Server awaiting explicit allow-all confirmation, if any. */
|
|
121
131
|
public mcpAllowAllConfirmationTarget: string | null = null;
|
|
122
132
|
/**
|
|
@@ -140,8 +150,6 @@ export class SettingsModal {
|
|
|
140
150
|
/** Settings grouped by category. */
|
|
141
151
|
public groups: Map<SettingsCategory, SettingEntry[]> = new Map();
|
|
142
152
|
|
|
143
|
-
/** Feature flag entries (populated when flags tab is active). */
|
|
144
|
-
public flagEntries: FlagEntry[] = [];
|
|
145
153
|
/** MCP server trust entries (populated when mcp tab is active). */
|
|
146
154
|
public mcpEntries: McpEntry[] = [];
|
|
147
155
|
/** Provider subscription entries (populated when subscriptions tab is active). */
|
|
@@ -207,7 +215,6 @@ export class SettingsModal {
|
|
|
207
215
|
this.mcpRegistry = mcpRegistry ?? null;
|
|
208
216
|
this.onSettingApplied = options?.onSettingApplied ?? null;
|
|
209
217
|
this.groups = buildSettingGroups(configManager, featureFlagManager);
|
|
210
|
-
this.flagEntries = buildFlagEntries(featureFlagManager);
|
|
211
218
|
this.mcpEntries = buildMcpEntries(this.mcpRegistry);
|
|
212
219
|
this.subscriptionEntries = buildSubscriptionEntries(subscriptionManager, serviceRegistry);
|
|
213
220
|
this.categoryIndex = 0;
|
|
@@ -225,9 +232,15 @@ export class SettingsModal {
|
|
|
225
232
|
this.searchQuery = '';
|
|
226
233
|
this.searchResults = [];
|
|
227
234
|
this.searchFocused = false;
|
|
235
|
+
this.contextScroll = 0;
|
|
228
236
|
this.active = true;
|
|
229
237
|
}
|
|
230
238
|
|
|
239
|
+
/** Scroll the documentation pane by `delta` wrapped lines (renderer clamps the top end). */
|
|
240
|
+
scrollContext(delta: number): void {
|
|
241
|
+
this.contextScroll = Math.max(0, this.contextScroll + delta);
|
|
242
|
+
}
|
|
243
|
+
|
|
231
244
|
close(): void {
|
|
232
245
|
this.active = false;
|
|
233
246
|
this.editingMode = false;
|
|
@@ -242,6 +255,7 @@ export class SettingsModal {
|
|
|
242
255
|
this.searchQuery = '';
|
|
243
256
|
this.searchResults = [];
|
|
244
257
|
this.searchFocused = false;
|
|
258
|
+
this.contextScroll = 0;
|
|
245
259
|
this.serviceRegistry = null;
|
|
246
260
|
this.secretsManager = null;
|
|
247
261
|
this.onSettingApplied = null;
|
|
@@ -266,6 +280,7 @@ export class SettingsModal {
|
|
|
266
280
|
setSearchQuery(query: string): void {
|
|
267
281
|
this.searchQuery = query;
|
|
268
282
|
this.searchFocused = true;
|
|
283
|
+
this.contextScroll = 0;
|
|
269
284
|
if (query.trim().length === 0) {
|
|
270
285
|
this.searchResults = [];
|
|
271
286
|
} else {
|
|
@@ -286,6 +301,7 @@ export class SettingsModal {
|
|
|
286
301
|
if (this.editingMode) return;
|
|
287
302
|
this.categoryIndex = (this.categoryIndex + 1) % SETTINGS_CATEGORIES.length;
|
|
288
303
|
this.selectedIndex = 0;
|
|
304
|
+
this.contextScroll = 0;
|
|
289
305
|
this.subscriptionLogoutConfirmationTarget = null;
|
|
290
306
|
this._reloadTabEntries();
|
|
291
307
|
}
|
|
@@ -295,6 +311,7 @@ export class SettingsModal {
|
|
|
295
311
|
if (this.editingMode) return;
|
|
296
312
|
this.categoryIndex = (this.categoryIndex - 1 + SETTINGS_CATEGORIES.length) % SETTINGS_CATEGORIES.length;
|
|
297
313
|
this.selectedIndex = 0;
|
|
314
|
+
this.contextScroll = 0;
|
|
298
315
|
this.subscriptionLogoutConfirmationTarget = null;
|
|
299
316
|
this._reloadTabEntries();
|
|
300
317
|
}
|
|
@@ -326,6 +343,7 @@ export class SettingsModal {
|
|
|
326
343
|
|
|
327
344
|
moveUp(): void {
|
|
328
345
|
if (this.editingMode) return;
|
|
346
|
+
this.contextScroll = 0;
|
|
329
347
|
if (this.searchFocused) {
|
|
330
348
|
if (this.searchResults.length > 0) {
|
|
331
349
|
this.selectedIndex = (this.selectedIndex - 1 + this.searchResults.length) % this.searchResults.length;
|
|
@@ -334,9 +352,7 @@ export class SettingsModal {
|
|
|
334
352
|
}
|
|
335
353
|
const items = this._currentItems();
|
|
336
354
|
if (items.length === 0) {
|
|
337
|
-
if (this.currentCategory === '
|
|
338
|
-
this.selectedIndex = (this.selectedIndex - 1 + this.flagEntries.length) % this.flagEntries.length;
|
|
339
|
-
} else if (this.currentCategory === 'mcp' && this.mcpEntries.length > 0) {
|
|
355
|
+
if (this.currentCategory === 'mcp' && this.mcpEntries.length > 0) {
|
|
340
356
|
this.selectedIndex = (this.selectedIndex - 1 + this.mcpEntries.length) % this.mcpEntries.length;
|
|
341
357
|
} else if (this.currentCategory === 'subscriptions' && this.subscriptionEntries.length > 0) {
|
|
342
358
|
this.selectedIndex = (this.selectedIndex - 1 + this.subscriptionEntries.length) % this.subscriptionEntries.length;
|
|
@@ -350,6 +366,7 @@ export class SettingsModal {
|
|
|
350
366
|
|
|
351
367
|
moveDown(): void {
|
|
352
368
|
if (this.editingMode) return;
|
|
369
|
+
this.contextScroll = 0;
|
|
353
370
|
if (this.searchFocused) {
|
|
354
371
|
if (this.searchResults.length > 0) {
|
|
355
372
|
this.selectedIndex = (this.selectedIndex + 1) % this.searchResults.length;
|
|
@@ -358,9 +375,7 @@ export class SettingsModal {
|
|
|
358
375
|
}
|
|
359
376
|
const items = this._currentItems();
|
|
360
377
|
if (items.length === 0) {
|
|
361
|
-
if (this.currentCategory === '
|
|
362
|
-
this.selectedIndex = (this.selectedIndex + 1) % this.flagEntries.length;
|
|
363
|
-
} else if (this.currentCategory === 'mcp' && this.mcpEntries.length > 0) {
|
|
378
|
+
if (this.currentCategory === 'mcp' && this.mcpEntries.length > 0) {
|
|
364
379
|
this.selectedIndex = (this.selectedIndex + 1) % this.mcpEntries.length;
|
|
365
380
|
} else if (this.currentCategory === 'subscriptions' && this.subscriptionEntries.length > 0) {
|
|
366
381
|
this.selectedIndex = (this.selectedIndex + 1) % this.subscriptionEntries.length;
|
|
@@ -414,6 +429,7 @@ export class SettingsModal {
|
|
|
414
429
|
selectTarget(target?: string): void {
|
|
415
430
|
const normalized = target?.trim();
|
|
416
431
|
if (!normalized) return;
|
|
432
|
+
this.contextScroll = 0;
|
|
417
433
|
|
|
418
434
|
const categoryIndex = SETTINGS_CATEGORIES.indexOf(normalized as SettingsCategory);
|
|
419
435
|
if (categoryIndex >= 0) {
|
|
@@ -493,38 +509,21 @@ export class SettingsModal {
|
|
|
493
509
|
}
|
|
494
510
|
|
|
495
511
|
/**
|
|
496
|
-
* Toggle the currently selected feature
|
|
497
|
-
*
|
|
498
|
-
*
|
|
499
|
-
*
|
|
512
|
+
* Toggle the currently selected feature unit through its real domain
|
|
513
|
+
* settings key: boolean/constant enablements flip the key, enum enablements
|
|
514
|
+
* jump between the feature's stock active mode and its off mode. Killed
|
|
515
|
+
* features cannot be toggled; constant capabilities with no off position
|
|
516
|
+
* (non-boolean keys) are left to their domain settings.
|
|
500
517
|
*/
|
|
501
518
|
toggleSelectedFlag(): void {
|
|
502
519
|
const entry = this.getSelected();
|
|
503
520
|
if (!entry?.flag) return;
|
|
504
521
|
if (entry.flag.state === 'killed') return;
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
* header entry, applies the desired state through the flag manager (runtime +
|
|
511
|
-
* persisted override), and refreshes the header row's value/default marker in
|
|
512
|
-
* place. Killed flags and no-op toggles are ignored.
|
|
513
|
-
*/
|
|
514
|
-
private _toggleFlagValue(key: ConfigKey, value: unknown): void {
|
|
515
|
-
if (!this.featureFlagManager || !this.configManager) return;
|
|
516
|
-
let target: SettingEntry | null = null;
|
|
517
|
-
for (const entries of this.groups.values()) {
|
|
518
|
-
const candidate = entries.find((e) => e.setting.key === key && e.flag);
|
|
519
|
-
if (candidate) { target = candidate; break; }
|
|
520
|
-
}
|
|
521
|
-
if (!target?.flag) return;
|
|
522
|
-
if (target.flag.state === 'killed') return;
|
|
523
|
-
const desired = value ? 'enabled' : 'disabled';
|
|
524
|
-
if (target.flag.state === desired) return;
|
|
525
|
-
applyFlagState(target.flag, desired, this.featureFlagManager, this.configManager);
|
|
526
|
-
target.currentValue = target.flag.state === 'enabled';
|
|
527
|
-
target.isDefault = target.flag.state === target.flag.flag.defaultState;
|
|
522
|
+
const feature = entry.flag.feature;
|
|
523
|
+
const currentlyOn = isFeatureValueEnabled(feature, entry.currentValue);
|
|
524
|
+
const write = featureEnablementWrite(feature.id, !currentlyOn);
|
|
525
|
+
if (!write) return;
|
|
526
|
+
this._setValue(write.key, write.value);
|
|
528
527
|
}
|
|
529
528
|
|
|
530
529
|
/**
|
|
@@ -586,6 +585,18 @@ export class SettingsModal {
|
|
|
586
585
|
}
|
|
587
586
|
}
|
|
588
587
|
|
|
588
|
+
if (setting.type === 'object') {
|
|
589
|
+
// Object-typed keys (e.g. pricing.modelPrices) edit as JSON; the
|
|
590
|
+
// schema's validate() below still rules on the parsed shape.
|
|
591
|
+
try {
|
|
592
|
+
parsed = JSON.parse(this.editBuffer);
|
|
593
|
+
} catch {
|
|
594
|
+
this.editingMode = false;
|
|
595
|
+
this.editBuffer = '';
|
|
596
|
+
return false;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
|
|
589
600
|
if (setting.validate && !setting.validate(parsed)) {
|
|
590
601
|
this.editingMode = false;
|
|
591
602
|
this.editBuffer = '';
|
|
@@ -685,11 +696,9 @@ export class SettingsModal {
|
|
|
685
696
|
|
|
686
697
|
// ── Private helpers ────────────────────────────────────────────────────────────────
|
|
687
698
|
|
|
688
|
-
/** Reload
|
|
699
|
+
/** Reload mcp/subscription entries when the active tab changes. */
|
|
689
700
|
private _reloadTabEntries(): void {
|
|
690
|
-
if (this.currentCategory === '
|
|
691
|
-
this.flagEntries = buildFlagEntries(this.featureFlagManager);
|
|
692
|
-
} else if (this.currentCategory === 'mcp') {
|
|
701
|
+
if (this.currentCategory === 'mcp') {
|
|
693
702
|
this.mcpEntries = buildMcpEntries(this.mcpRegistry);
|
|
694
703
|
} else if (this.currentCategory === 'subscriptions') {
|
|
695
704
|
this.subscriptionEntries = buildSubscriptionEntries(this.subscriptionManager, this.serviceRegistry);
|
|
@@ -698,8 +707,8 @@ export class SettingsModal {
|
|
|
698
707
|
|
|
699
708
|
/**
|
|
700
709
|
* Returns [] for the mcp/subscriptions categories (which render their own
|
|
701
|
-
* entry types).
|
|
702
|
-
*
|
|
710
|
+
* entry types). Every other category flows through the normal group path,
|
|
711
|
+
* feature-unit headers included.
|
|
703
712
|
*/
|
|
704
713
|
private _currentItems(): SettingEntry[] {
|
|
705
714
|
if (
|
|
@@ -716,15 +725,6 @@ export class SettingsModal {
|
|
|
716
725
|
private _setValue(key: ConfigKey, value: unknown): void {
|
|
717
726
|
if (!this.configManager) return;
|
|
718
727
|
|
|
719
|
-
// Feature-unit toggle headers write to `featureFlags.<id>`; route those to
|
|
720
|
-
// the feature-flag manager (runtime toggle + persisted override) instead of
|
|
721
|
-
// a plain config write. Reset/adjust/activate all funnel a boolean value
|
|
722
|
-
// here (true = enabled), so this is the single flag-toggle chokepoint.
|
|
723
|
-
if (typeof key === 'string' && key.startsWith('featureFlags.')) {
|
|
724
|
-
this._toggleFlagValue(key, value);
|
|
725
|
-
return;
|
|
726
|
-
}
|
|
727
|
-
|
|
728
728
|
const callback: SettingAppliedCallback | null = this.onSettingApplied
|
|
729
729
|
? (change) => this.onSettingApplied!(change)
|
|
730
730
|
: null;
|
|
@@ -740,6 +740,13 @@ export class SettingsModal {
|
|
|
740
740
|
},
|
|
741
741
|
});
|
|
742
742
|
|
|
743
|
+
// Feature-unit headers write plain domain keys; the SDK settings bridge
|
|
744
|
+
// has already applied the change to the gate manager (live flip for
|
|
745
|
+
// runtime-toggleable features, pending-restart marker for startup-gated
|
|
746
|
+
// ones). Re-read the manager for every header bound to this key so the
|
|
747
|
+
// rows and the context pane show the honest state at the point of change.
|
|
748
|
+
this._syncFeatureHeadersForKey(key);
|
|
749
|
+
|
|
743
750
|
if (result.restartDomain !== null) {
|
|
744
751
|
this.lastSaveTriggeredRestart = result.restartDomain;
|
|
745
752
|
}
|
|
@@ -749,4 +756,16 @@ export class SettingsModal {
|
|
|
749
756
|
// No-op (result.changed === false, effectMessage === null): leave lastSettingEffectMessage untouched.
|
|
750
757
|
}
|
|
751
758
|
|
|
759
|
+
/** Refresh live/persisted/pending state for every feature header bound to `key`. */
|
|
760
|
+
private _syncFeatureHeadersForKey(key: ConfigKey): void {
|
|
761
|
+
if (!this.featureFlagManager) return;
|
|
762
|
+
for (const entries of this.groups.values()) {
|
|
763
|
+
for (const entry of entries) {
|
|
764
|
+
if (entry.flag && entry.flag.feature.enablement.key === key) {
|
|
765
|
+
syncFlagEntryFromManager(entry.flag, this.featureFlagManager);
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
|
|
752
771
|
}
|