@pellux/goodvibes-agent 1.1.7 → 1.3.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 +329 -0
- package/README.md +46 -30
- package/dist/package/{ast-grep-napi.linux-x64-gnu-mkk8xwww.node → ast-grep-napi.linux-x64-gnu-swtppvy9.node} +0 -0
- package/dist/package/{ast-grep-napi.linux-x64-musl-ryqtgdv6.node → ast-grep-napi.linux-x64-musl-ttfcdtap.node} +0 -0
- package/dist/package/main.js +138903 -91477
- package/docs/README.md +14 -7
- package/docs/channels-remote-and-api.md +8 -5
- package/docs/connected-host.md +14 -12
- package/docs/getting-started.md +58 -30
- package/docs/knowledge-artifacts-and-multimodal.md +7 -5
- package/docs/project-planning.md +2 -2
- package/docs/providers-and-routing.md +11 -3
- package/docs/tools-and-commands.md +116 -45
- package/docs/voice-and-live-tts.md +3 -1
- package/package.json +3 -2
- package/release/release-notes.md +142 -5
- package/release/release-readiness.json +124 -94
- package/src/agent/assistant-cockpit.ts +247 -0
- package/src/agent/autonomy-schedule-format.ts +96 -0
- package/src/agent/autonomy-schedule.ts +514 -0
- package/src/agent/channel-delivery-receipts.ts +292 -0
- package/src/agent/competitive-feature-inventory.ts +294 -0
- package/src/agent/document-registry-types.ts +106 -0
- package/src/agent/document-registry.ts +734 -0
- package/src/agent/harness-control.ts +2 -2
- package/src/agent/memory-prompt.ts +2 -2
- package/src/agent/operator-actions.ts +50 -6
- package/src/agent/persona-registry.ts +8 -0
- package/src/agent/project-context-files.ts +273 -0
- package/src/agent/prompt-context-receipts.ts +502 -0
- package/src/agent/reminder-schedule-format.ts +16 -2
- package/src/agent/research-run-registry.ts +582 -0
- package/src/agent/research-source-registry.ts +441 -0
- package/src/agent/routine-registry.ts +19 -3
- package/src/agent/routine-schedule-format.ts +27 -2
- package/src/agent/runtime-profile-starters.ts +7 -0
- package/src/agent/runtime-profile.ts +106 -4
- package/src/agent/schedule-edit-format.ts +129 -0
- package/src/agent/schedule-edit.ts +496 -0
- package/src/agent/schedule-next-routes.ts +42 -0
- package/src/agent/setup-wizard-artifact-receipts.ts +366 -0
- package/src/agent/setup-wizard-checkpoint.ts +140 -0
- package/src/agent/setup-wizard.ts +683 -0
- package/src/agent/skill-registry-types.ts +102 -0
- package/src/agent/skill-registry.ts +81 -107
- package/src/agent/vibe-confirmation-routes.ts +62 -0
- package/src/agent/vibe-file.ts +285 -0
- package/src/cli/agent-knowledge-command.ts +45 -2
- package/src/cli/help.ts +3 -0
- package/src/cli/profiles-command.ts +25 -11
- package/src/config/agent-settings-policy.ts +1 -18
- package/src/input/agent-workspace-activation.ts +53 -0
- package/src/input/agent-workspace-artifact-browser-editor.ts +494 -0
- package/src/input/agent-workspace-artifact-metadata.ts +17 -0
- package/src/input/agent-workspace-basic-command-editors.ts +5 -1
- package/src/input/agent-workspace-categories.ts +153 -155
- package/src/input/agent-workspace-channel-triage.ts +481 -0
- package/src/input/agent-workspace-channels.ts +263 -0
- package/src/input/agent-workspace-command-editor.ts +152 -0
- package/src/input/agent-workspace-context-snapshot.ts +349 -0
- package/src/input/agent-workspace-delegation-editor-submission.ts +8 -0
- package/src/input/agent-workspace-document-editor.ts +502 -0
- package/src/input/agent-workspace-document-ops-editor.ts +523 -0
- package/src/input/agent-workspace-host-category.ts +1 -1
- package/src/input/agent-workspace-local-library-snapshot.ts +167 -0
- package/src/input/agent-workspace-model-compare-editor.ts +376 -0
- package/src/input/agent-workspace-model-compare-prompt-submission.ts +552 -0
- package/src/input/agent-workspace-model-compare-types.ts +82 -0
- package/src/input/agent-workspace-model-compare-utils.ts +35 -0
- package/src/input/agent-workspace-onboarding-categories.ts +141 -0
- package/src/input/agent-workspace-operations-command-editor-submission.ts +53 -0
- package/src/input/agent-workspace-operations-command-editors.ts +22 -0
- package/src/input/agent-workspace-research-report-editor.ts +212 -0
- package/src/input/agent-workspace-research-run-editor.ts +144 -0
- package/src/input/agent-workspace-research-source-editor.ts +167 -0
- package/src/input/agent-workspace-review-packet-snapshot.ts +593 -0
- package/src/input/agent-workspace-review-packet-utils.ts +265 -0
- package/src/input/agent-workspace-settings.ts +313 -30
- package/src/input/agent-workspace-setup-checkpoint-action.ts +127 -0
- package/src/input/agent-workspace-setup-snapshot.ts +217 -0
- package/src/input/agent-workspace-setup.ts +61 -1
- package/src/input/agent-workspace-snapshot.ts +184 -149
- package/src/input/agent-workspace-types.ts +287 -2
- package/src/input/agent-workspace.ts +23 -1
- package/src/input/command-registry.ts +9 -2
- package/src/input/commands/agent-runtime-profile-runtime.ts +28 -13
- package/src/input/commands/channels-runtime.ts +102 -114
- package/src/input/commands/delegation-runtime.ts +87 -24
- package/src/input/commands/knowledge-browser-flags.ts +12 -0
- package/src/input/commands/knowledge.ts +28 -14
- package/src/input/commands/operator-actions-runtime.ts +6 -3
- package/src/input/commands/schedule-runtime.ts +71 -14
- package/src/input/commands/session-content.ts +2 -2
- package/src/input/commands/shell-core.ts +2 -0
- package/src/input/commands/vibe-runtime.ts +140 -0
- package/src/input/commands.ts +2 -0
- package/src/input/connected-host-routes.ts +123 -0
- package/src/input/settings-modal-types.ts +14 -0
- package/src/input/setup-wizard-live-receipts.ts +76 -0
- package/src/main.ts +15 -15
- package/src/panels/qr-panel.ts +2 -2
- package/src/renderer/agent-workspace-context-lines.ts +701 -0
- package/src/renderer/agent-workspace.ts +68 -421
- package/src/renderer/settings-modal-helpers.ts +12 -0
- package/src/renderer/settings-modal.ts +12 -0
- package/src/runtime/bootstrap-command-context.ts +11 -1
- package/src/runtime/bootstrap-command-parts.ts +14 -3
- package/src/runtime/bootstrap-core.ts +39 -1
- package/src/runtime/bootstrap-shell.ts +6 -0
- package/src/runtime/bootstrap.ts +113 -30
- package/src/runtime/connected-host-auth.ts +3 -2
- package/src/runtime/execution-ledger.ts +231 -0
- package/src/runtime/services.ts +88 -10
- package/src/runtime/tool-permission-safety.ts +199 -5
- package/src/shell/session-continuity-hints.ts +39 -0
- package/src/tools/agent-artifacts-tool.ts +606 -0
- package/src/tools/agent-audit-tool.ts +155 -0
- package/src/tools/agent-autonomy-schedule-tool.ts +238 -0
- package/src/tools/agent-autonomy-tool.ts +140 -0
- package/src/tools/agent-channel-send-tool.ts +24 -2
- package/src/tools/agent-channels-tool.ts +140 -0
- package/src/tools/agent-computer-tool.ts +168 -0
- package/src/tools/agent-context-policy.ts +137 -7
- package/src/tools/agent-context-tool.ts +143 -0
- package/src/tools/agent-delegation-tool.ts +128 -0
- package/src/tools/agent-device-tool.ts +240 -0
- package/src/tools/agent-documents-tool.ts +684 -0
- package/src/tools/agent-execution-tool.ts +230 -0
- package/src/tools/agent-harness-agent-orchestration-policy.ts +75 -0
- package/src/tools/agent-harness-agent-orchestration.ts +791 -0
- package/src/tools/agent-harness-autonomy-intake.ts +785 -0
- package/src/tools/agent-harness-autonomy-live-records.ts +742 -0
- package/src/tools/agent-harness-autonomy-queue-types.ts +88 -0
- package/src/tools/agent-harness-autonomy-queue.ts +571 -0
- package/src/tools/agent-harness-autonomy-watcher-read-models.ts +509 -0
- package/src/tools/agent-harness-background-processes-types.ts +35 -0
- package/src/tools/agent-harness-background-processes.ts +798 -0
- package/src/tools/agent-harness-browser-cockpit-route.ts +373 -0
- package/src/tools/agent-harness-browser-control.ts +346 -0
- package/src/tools/agent-harness-browser-pwa-read-models.ts +622 -0
- package/src/tools/agent-harness-channel-metadata.ts +168 -10
- package/src/tools/agent-harness-cli-command-policy.ts +110 -0
- package/src/tools/agent-harness-command-catalog.ts +4 -2
- package/src/tools/agent-harness-command-runner.ts +42 -0
- package/src/tools/agent-harness-connected-host-status.ts +7 -4
- package/src/tools/agent-harness-delegation-posture.ts +234 -19
- package/src/tools/agent-harness-device-live-read-models.ts +366 -0
- package/src/tools/agent-harness-document-ops-reviewer-readiness.ts +234 -0
- package/src/tools/agent-harness-document-ops-types.ts +72 -0
- package/src/tools/agent-harness-document-ops.ts +671 -0
- package/src/tools/agent-harness-execution-history.ts +489 -0
- package/src/tools/agent-harness-execution-posture.ts +385 -0
- package/src/tools/agent-harness-file-recovery.ts +135 -0
- package/src/tools/agent-harness-interactive-runtime-records.ts +421 -0
- package/src/tools/agent-harness-keybinding-metadata.ts +16 -12
- package/src/tools/agent-harness-learning-curator-common.ts +102 -0
- package/src/tools/agent-harness-learning-curator-consolidation.ts +295 -0
- package/src/tools/agent-harness-learning-curator-proposals.ts +606 -0
- package/src/tools/agent-harness-learning-curator-types.ts +151 -0
- package/src/tools/agent-harness-learning-curator.ts +417 -0
- package/src/tools/agent-harness-local-model-benchmarks.ts +269 -0
- package/src/tools/agent-harness-local-model-cookbook.ts +238 -0
- package/src/tools/agent-harness-local-model-endpoints.ts +788 -0
- package/src/tools/agent-harness-local-model-smoke.ts +277 -0
- package/src/tools/agent-harness-local-model-url.ts +78 -0
- package/src/tools/agent-harness-media-posture.ts +223 -2
- package/src/tools/agent-harness-memory-external-providers.ts +796 -0
- package/src/tools/agent-harness-memory-posture.ts +672 -0
- package/src/tools/agent-harness-memory-provider-certification.ts +219 -0
- package/src/tools/agent-harness-memory-refinement.ts +340 -0
- package/src/tools/agent-harness-metadata.ts +100 -168
- package/src/tools/agent-harness-mode-catalog.ts +86 -33
- package/src/tools/agent-harness-model-catalog.ts +162 -0
- package/src/tools/agent-harness-model-provider-health.ts +283 -0
- package/src/tools/agent-harness-model-readiness.ts +432 -0
- package/src/tools/agent-harness-model-routing-types.ts +327 -0
- package/src/tools/agent-harness-model-routing-utils.ts +30 -0
- package/src/tools/agent-harness-model-routing.ts +165 -193
- package/src/tools/agent-harness-operator-methods.ts +115 -133
- package/src/tools/agent-harness-pairing-posture.ts +452 -18
- package/src/tools/agent-harness-personal-ops-certification.ts +116 -0
- package/src/tools/agent-harness-personal-ops-discovery.ts +533 -0
- package/src/tools/agent-harness-personal-ops-intake.ts +385 -0
- package/src/tools/agent-harness-personal-ops-lanes.ts +270 -0
- package/src/tools/agent-harness-personal-ops-operations.ts +225 -0
- package/src/tools/agent-harness-personal-ops-provider-records.ts +358 -0
- package/src/tools/agent-harness-personal-ops-provider-task-records.ts +321 -0
- package/src/tools/agent-harness-personal-ops-records.ts +684 -0
- package/src/tools/agent-harness-personal-ops-runner.ts +637 -0
- package/src/tools/agent-harness-personal-ops-types.ts +240 -0
- package/src/tools/agent-harness-personal-ops.ts +613 -0
- package/src/tools/agent-harness-project-context.ts +144 -0
- package/src/tools/agent-harness-prompt-context.ts +589 -0
- package/src/tools/agent-harness-provider-account-metadata.ts +2 -2
- package/src/tools/agent-harness-release-evidence.ts +9 -7
- package/src/tools/agent-harness-release-readiness.ts +9 -7
- package/src/tools/agent-harness-remote-read-models.ts +541 -0
- package/src/tools/agent-harness-research-briefing.ts +446 -0
- package/src/tools/agent-harness-research-live-read-models.ts +500 -0
- package/src/tools/agent-harness-research-queue.ts +250 -0
- package/src/tools/agent-harness-research-runs.ts +307 -0
- package/src/tools/agent-harness-research-workflow.ts +395 -0
- package/src/tools/agent-harness-security-posture.ts +2 -2
- package/src/tools/agent-harness-service-posture.ts +9 -9
- package/src/tools/agent-harness-session-metadata.ts +3 -3
- package/src/tools/agent-harness-setup-connected-host.ts +501 -0
- package/src/tools/agent-harness-setup-describe.ts +557 -0
- package/src/tools/agent-harness-setup-handoffs.ts +502 -0
- package/src/tools/agent-harness-setup-model-helpers.ts +102 -0
- package/src/tools/agent-harness-setup-plan.ts +253 -0
- package/src/tools/agent-harness-setup-posture-types.ts +218 -0
- package/src/tools/agent-harness-setup-posture-utils.ts +173 -0
- package/src/tools/agent-harness-setup-posture.ts +449 -221
- package/src/tools/agent-harness-setup-smoke.ts +533 -0
- package/src/tools/agent-harness-sudo-posture.ts +114 -0
- package/src/tools/agent-harness-tool-schema.ts +142 -7
- package/src/tools/agent-harness-tool-types.ts +83 -0
- package/src/tools/agent-harness-tool-utils.ts +43 -0
- package/src/tools/agent-harness-tool.ts +319 -370
- package/src/tools/agent-harness-ui-surface-metadata.ts +76 -69
- package/src/tools/agent-harness-ui-surface-types.ts +46 -0
- package/src/tools/agent-harness-vibe-health.ts +105 -0
- package/src/tools/agent-harness-workspace-action-runner.ts +149 -0
- package/src/tools/agent-harness-workspace-actions.ts +114 -8
- package/src/tools/agent-harness-workspace-editor-execution.ts +214 -0
- package/src/tools/agent-harness-workspace-editor-runner.ts +755 -0
- package/src/tools/agent-host-tool.ts +159 -0
- package/src/tools/agent-knowledge-ingest-tool.ts +34 -1
- package/src/tools/agent-learning-consolidation-core.ts +327 -0
- package/src/tools/agent-learning-consolidation-tool.ts +758 -0
- package/src/tools/agent-memory-tool.ts +253 -0
- package/src/tools/agent-model-compare-export.ts +315 -0
- package/src/tools/agent-model-compare-handoff.ts +592 -0
- package/src/tools/agent-model-compare-judgment.ts +633 -0
- package/src/tools/agent-model-compare-run.ts +735 -0
- package/src/tools/agent-model-compare-tool.ts +698 -0
- package/src/tools/agent-model-compare-types.ts +191 -0
- package/src/tools/agent-model-compare-utils.ts +93 -0
- package/src/tools/agent-models-tool.ts +208 -0
- package/src/tools/agent-operator-action-tool.ts +1 -1
- package/src/tools/agent-operator-method-tool.ts +643 -0
- package/src/tools/agent-personal-ops-tool.ts +197 -0
- package/src/tools/agent-policy-explanation.ts +415 -0
- package/src/tools/agent-research-report-tool.ts +608 -0
- package/src/tools/agent-research-runner.ts +367 -0
- package/src/tools/agent-research-runs-tool.ts +434 -0
- package/src/tools/agent-research-sources-tool.ts +443 -0
- package/src/tools/agent-research-tool.ts +515 -0
- package/src/tools/agent-review-packet-presets-core.ts +757 -0
- package/src/tools/agent-review-packet-presets-tool.ts +466 -0
- package/src/tools/agent-review-packet-share-tool.ts +305 -0
- package/src/tools/agent-route-planner-candidates-setup.ts +411 -0
- package/src/tools/agent-route-planner-candidates-surfaces.ts +432 -0
- package/src/tools/agent-route-planner-candidates-work.ts +251 -0
- package/src/tools/agent-route-planner-helpers.ts +667 -0
- package/src/tools/agent-route-planner.ts +185 -0
- package/src/tools/agent-route-tool.ts +105 -0
- package/src/tools/agent-schedule-edit-tool.ts +210 -0
- package/src/tools/agent-schedule-tool.ts +282 -0
- package/src/tools/agent-security-tool.ts +145 -0
- package/src/tools/agent-sessions-tool.ts +122 -0
- package/src/tools/agent-settings-import-tool.ts +104 -0
- package/src/tools/agent-settings-tool.ts +176 -0
- package/src/tools/agent-setup-tool.ts +226 -0
- package/src/tools/agent-support-tool.ts +122 -0
- package/src/tools/agent-terminal-process-tools.ts +167 -0
- package/src/tools/agent-tool-policy-guard-types.ts +77 -0
- package/src/tools/agent-tool-policy-guard.ts +106 -85
- package/src/tools/agent-vibe-tool.ts +297 -0
- package/src/tools/agent-work-plan-tool.ts +265 -6
- package/src/tools/agent-workspace-tool.ts +305 -0
- package/src/tools/artifact-archive.ts +169 -0
- package/src/tools/tool-definition-compaction.ts +36 -0
- package/src/version.ts +1 -1
|
@@ -1,58 +1,17 @@
|
|
|
1
1
|
import type { CommandContext } from '../input/command-registry.ts';
|
|
2
2
|
import { openTtsProviderPicker, openTtsVoicePicker } from '../input/tts-settings-actions.ts';
|
|
3
|
+
import { openExternalUrl } from '@pellux/goodvibes-sdk/platform/utils';
|
|
4
|
+
import { connectedBrowserCockpitRoute } from './agent-harness-browser-cockpit-route.ts';
|
|
5
|
+
import type { AgentHarnessUiSurfaceArgs, UiSurfaceDefinition, UiSurfaceLookup, UiSurfaceResolution } from './agent-harness-ui-surface-types.ts';
|
|
6
|
+
export type { AgentHarnessUiSurfaceArgs } from './agent-harness-ui-surface-types.ts';
|
|
3
7
|
|
|
4
|
-
|
|
8
|
+
function agentHarnessModes(...modes: readonly string[]): string { return `agent_harness ${modes.map((mode) => `mode:"${mode}"`).join(', ')}`; }
|
|
5
9
|
|
|
6
|
-
function
|
|
7
|
-
return `agent_harness ${modes.map((mode) => `mode:"${mode}"`).join(', ')}`;
|
|
8
|
-
}
|
|
10
|
+
function settingsActions(...actions: readonly string[]): string { return `settings ${actions.map((action) => `action:"${action}"`).join('|')}`; }
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
readonly query?: unknown;
|
|
12
|
-
readonly surfaceId?: unknown;
|
|
13
|
-
readonly categoryId?: unknown;
|
|
14
|
-
readonly category?: unknown;
|
|
15
|
-
readonly target?: unknown;
|
|
16
|
-
readonly key?: unknown;
|
|
17
|
-
readonly prefix?: unknown;
|
|
18
|
-
readonly includeParameters?: unknown;
|
|
19
|
-
readonly limit?: unknown;
|
|
20
|
-
readonly pane?: unknown;
|
|
21
|
-
}
|
|
12
|
+
function hostActions(...actions: readonly string[]): string { return `host ${actions.map((action) => `action:"${action}"`).join('|')}`; }
|
|
22
13
|
|
|
23
|
-
|
|
24
|
-
readonly id: string;
|
|
25
|
-
readonly label: string;
|
|
26
|
-
readonly kind: UiSurfaceKind;
|
|
27
|
-
readonly summary: string;
|
|
28
|
-
readonly command: string;
|
|
29
|
-
readonly preferredModelRoute: string;
|
|
30
|
-
readonly parameters?: readonly string[];
|
|
31
|
-
readonly available: (context: CommandContext) => boolean;
|
|
32
|
-
readonly open: (context: CommandContext, args: AgentHarnessUiSurfaceArgs) => Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
interface UiSurfaceLookup {
|
|
36
|
-
readonly source: 'surfaceId' | 'target' | 'query';
|
|
37
|
-
readonly input: string;
|
|
38
|
-
readonly resolvedBy: 'id' | 'case-insensitive-id' | 'label' | 'case-insensitive-label' | 'search';
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
type UiSurfaceResolution =
|
|
42
|
-
| {
|
|
43
|
-
readonly status: 'found';
|
|
44
|
-
readonly surface: UiSurfaceDefinition;
|
|
45
|
-
readonly lookup: UiSurfaceLookup;
|
|
46
|
-
}
|
|
47
|
-
| {
|
|
48
|
-
readonly status: 'ambiguous';
|
|
49
|
-
readonly input: string;
|
|
50
|
-
readonly candidates: readonly Record<string, unknown>[];
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
function readString(value: unknown): string {
|
|
54
|
-
return typeof value === 'string' ? value.trim() : '';
|
|
55
|
-
}
|
|
14
|
+
function readString(value: unknown): string { return typeof value === 'string' ? value.trim() : ''; }
|
|
56
15
|
|
|
57
16
|
function readLimit(value: unknown, fallback: number): number {
|
|
58
17
|
const parsed = typeof value === 'string' && value.trim() ? Number(value) : value;
|
|
@@ -181,6 +140,47 @@ const UI_SURFACES: readonly UiSurfaceDefinition[] = [
|
|
|
181
140
|
return opened(surface, { categoryId: categoryId ?? 'default' });
|
|
182
141
|
},
|
|
183
142
|
},
|
|
143
|
+
{
|
|
144
|
+
id: 'connected-browser-cockpit',
|
|
145
|
+
label: 'Connected Browser Cockpit',
|
|
146
|
+
kind: 'workspace',
|
|
147
|
+
summary: 'Connected-host browser cockpit/PWA route.',
|
|
148
|
+
command: 'connected host web route',
|
|
149
|
+
preferredModelRoute: `Use ${hostActions('service', 'services', 'status')} or ${settingsActions('list', 'get')} to inspect or repair web readiness; use mode:"open_ui_surface" only to visibly open the configured cockpit URL.`,
|
|
150
|
+
available: (context) => {
|
|
151
|
+
try {
|
|
152
|
+
return context.platform?.configManager?.get?.('web.enabled') === true;
|
|
153
|
+
} catch {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
open: async (context) => {
|
|
158
|
+
const surface = findSurfaceById('connected-browser-cockpit')!;
|
|
159
|
+
const route = connectedBrowserCockpitRoute(context);
|
|
160
|
+
if (route.enabled !== true) {
|
|
161
|
+
return {
|
|
162
|
+
status: 'setup_needed',
|
|
163
|
+
surface: surface.id,
|
|
164
|
+
kind: surface.kind,
|
|
165
|
+
route,
|
|
166
|
+
note: 'The connected-host web endpoint is disabled. Inspect service posture or web settings before opening a browser cockpit.',
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
const url = typeof route.url === 'string' ? route.url : '';
|
|
170
|
+
const browserOpened = url ? await openExternalUrl(url) : false;
|
|
171
|
+
return browserOpened
|
|
172
|
+
? opened(surface, { url, route, browserOpened })
|
|
173
|
+
: {
|
|
174
|
+
status: 'open_failed',
|
|
175
|
+
surface: surface.id,
|
|
176
|
+
kind: surface.kind,
|
|
177
|
+
url,
|
|
178
|
+
route,
|
|
179
|
+
browserOpened,
|
|
180
|
+
note: 'The configured browser cockpit URL was resolved, but the external browser opener did not report success.',
|
|
181
|
+
};
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
184
|
{
|
|
185
185
|
id: 'panel-picker',
|
|
186
186
|
label: 'Panel Picker',
|
|
@@ -258,7 +258,7 @@ const UI_SURFACES: readonly UiSurfaceDefinition[] = [
|
|
|
258
258
|
kind: 'modal',
|
|
259
259
|
summary: 'Fullscreen settings workspace for Agent config, secrets, MCP, and tools.',
|
|
260
260
|
command: '/settings',
|
|
261
|
-
preferredModelRoute: `Use ${
|
|
261
|
+
preferredModelRoute: `Use ${settingsActions('list', 'get', 'set', 'reset', 'import')} for model operation; use mode:"open_ui_surface" only to visibly navigate.`,
|
|
262
262
|
parameters: ['target', 'key', 'prefix'],
|
|
263
263
|
available: (context) => typeof context.openSettingsModal === 'function',
|
|
264
264
|
open: (context, args) => {
|
|
@@ -275,7 +275,7 @@ const UI_SURFACES: readonly UiSurfaceDefinition[] = [
|
|
|
275
275
|
kind: 'workspace',
|
|
276
276
|
summary: 'MCP server setup, trust posture, and tool inventory workspace.',
|
|
277
277
|
command: '/mcp',
|
|
278
|
-
preferredModelRoute: `Use ${agentHarnessModes('workspace_actions', 'tools', '
|
|
278
|
+
preferredModelRoute: `Use ${agentHarnessModes('workspace_actions', 'tools')} or ${settingsActions('list', 'get', 'set')} for model operation.`,
|
|
279
279
|
available: (context) => typeof context.openMcpWorkspace === 'function',
|
|
280
280
|
open: (context) => openSimpleContextSurface(context, 'mcp-workspace', 'openMcpWorkspace'),
|
|
281
281
|
},
|
|
@@ -285,7 +285,7 @@ const UI_SURFACES: readonly UiSurfaceDefinition[] = [
|
|
|
285
285
|
kind: 'picker',
|
|
286
286
|
summary: 'Interactive model picker for main, helper, tool, and TTS model routes.',
|
|
287
287
|
command: '/model',
|
|
288
|
-
preferredModelRoute: `Use ${
|
|
288
|
+
preferredModelRoute: `Use ${settingsActions('get', 'set')} for direct provider.model changes, or mode:"run_command" with confirmation when a concrete model id is known.`,
|
|
289
289
|
parameters: ['target'],
|
|
290
290
|
available: (context) => typeof context.openModelPicker === 'function' || typeof context.openModelPickerWithTarget === 'function',
|
|
291
291
|
open: (context, args) => {
|
|
@@ -306,7 +306,7 @@ const UI_SURFACES: readonly UiSurfaceDefinition[] = [
|
|
|
306
306
|
kind: 'picker',
|
|
307
307
|
summary: 'Interactive provider picker for model route setup.',
|
|
308
308
|
command: '/provider',
|
|
309
|
-
preferredModelRoute: `Use ${
|
|
309
|
+
preferredModelRoute: `Use ${settingsActions('get', 'set')} for direct provider routing changes, or confirmed mode:"run_command" mirrors for concrete provider changes.`,
|
|
310
310
|
parameters: ['target'],
|
|
311
311
|
available: (context) => typeof context.openProviderPicker === 'function' || typeof context.openProviderModelPickerWithTarget === 'function',
|
|
312
312
|
open: (context, args) => {
|
|
@@ -327,7 +327,7 @@ const UI_SURFACES: readonly UiSurfaceDefinition[] = [
|
|
|
327
327
|
kind: 'picker',
|
|
328
328
|
summary: 'Reasoning-effort selector for models that expose effort levels.',
|
|
329
329
|
command: '/effort',
|
|
330
|
-
preferredModelRoute: `Use ${
|
|
330
|
+
preferredModelRoute: `Use ${settingsActions('get', 'set')} for provider.reasoningEffort when a concrete level is known, or mode:"run_workspace_action" setup-reasoning-effort with confirmation.`,
|
|
331
331
|
available: (context) => typeof context.openReasoningEffortPicker === 'function',
|
|
332
332
|
open: (context) => {
|
|
333
333
|
const surface = findSurfaceById('reasoning-effort-picker')!;
|
|
@@ -355,7 +355,7 @@ const UI_SURFACES: readonly UiSurfaceDefinition[] = [
|
|
|
355
355
|
kind: 'picker',
|
|
356
356
|
summary: 'Streaming TTS provider picker from Agent settings.',
|
|
357
357
|
command: '/config tts.provider',
|
|
358
|
-
preferredModelRoute: `Use ${
|
|
358
|
+
preferredModelRoute: `Use ${settingsActions('get', 'set')} for tts.provider when a concrete provider id is known; use mode:"open_ui_surface" only to visibly navigate.`,
|
|
359
359
|
available: (context) => typeof context.openSelection === 'function' && Boolean(context.platform.voiceProviderRegistry),
|
|
360
360
|
open: (context) => {
|
|
361
361
|
const surface = findSurfaceById('tts-provider-picker')!;
|
|
@@ -370,7 +370,7 @@ const UI_SURFACES: readonly UiSurfaceDefinition[] = [
|
|
|
370
370
|
kind: 'picker',
|
|
371
371
|
summary: 'TTS voice picker for the selected or supplied provider.',
|
|
372
372
|
command: '/config tts.voice',
|
|
373
|
-
preferredModelRoute: `Use ${
|
|
373
|
+
preferredModelRoute: `Use ${settingsActions('get', 'set', 'reset')} for tts.voice when a concrete voice id is known; use mode:"open_ui_surface" only to visibly navigate.`,
|
|
374
374
|
parameters: ['target'],
|
|
375
375
|
available: (context) => typeof context.openSelection === 'function' && Boolean(context.platform.voiceService),
|
|
376
376
|
open: async (context, args) => {
|
|
@@ -613,7 +613,7 @@ const UI_SURFACES: readonly UiSurfaceDefinition[] = [
|
|
|
613
613
|
kind: 'workspace',
|
|
614
614
|
summary: 'Agent workspace entry for first-run and setup review.',
|
|
615
615
|
command: '/agent',
|
|
616
|
-
preferredModelRoute: `Use ${agentHarnessModes('workspace', 'workspace_actions', '
|
|
616
|
+
preferredModelRoute: `Use ${agentHarnessModes('workspace', 'workspace_actions')} or ${settingsActions('list', 'get', 'set')} for concrete setup operation.`,
|
|
617
617
|
available: (context) => typeof context.openAgentWorkspace === 'function',
|
|
618
618
|
open: (context) => {
|
|
619
619
|
const surface = findSurfaceById('onboarding')!;
|
|
@@ -630,7 +630,7 @@ function findSurfaceById(surfaceId: string): UiSurfaceDefinition | undefined {
|
|
|
630
630
|
|
|
631
631
|
function surfaceMatches(surface: Record<string, unknown>, query: string): boolean {
|
|
632
632
|
if (!query) return true;
|
|
633
|
-
|
|
633
|
+
const haystack = [
|
|
634
634
|
surface.id,
|
|
635
635
|
surface.label,
|
|
636
636
|
surface.kind,
|
|
@@ -638,7 +638,11 @@ function surfaceMatches(surface: Record<string, unknown>, query: string): boolea
|
|
|
638
638
|
surface.command,
|
|
639
639
|
surface.modelRoute,
|
|
640
640
|
surface.preferredModelRoute,
|
|
641
|
-
].map((value) => String(value ?? '')).join('\n').toLowerCase()
|
|
641
|
+
].map((value) => String(value ?? '')).join('\n').toLowerCase();
|
|
642
|
+
const normalized = query.toLowerCase().trim();
|
|
643
|
+
if (haystack.includes(normalized)) return true;
|
|
644
|
+
const tokens = normalized.split(/[^a-z0-9]+/).filter((token) => token.length > 0);
|
|
645
|
+
return tokens.length > 0 && tokens.every((token) => haystack.includes(token));
|
|
642
646
|
}
|
|
643
647
|
|
|
644
648
|
function surfaceLookupFromArgs(args: AgentHarnessUiSurfaceArgs): { readonly source: UiSurfaceLookup['source']; readonly input: string } | null {
|
|
@@ -664,43 +668,45 @@ function surfaceCandidate(surface: UiSurfaceDefinition): Record<string, unknown>
|
|
|
664
668
|
|
|
665
669
|
function uiSurfaceModelRoute(surface: UiSurfaceDefinition): string {
|
|
666
670
|
switch (surface.id) {
|
|
671
|
+
case 'connected-browser-cockpit':
|
|
672
|
+
return 'computer action:"browser|open_browser" or workspace action:"open"';
|
|
667
673
|
case 'agent-workspace':
|
|
668
674
|
case 'panel-picker':
|
|
669
675
|
case 'security-panel':
|
|
670
676
|
case 'subscription-panel':
|
|
671
677
|
case 'mcp-workspace':
|
|
672
678
|
case 'onboarding':
|
|
673
|
-
return '
|
|
679
|
+
return 'workspace action:"actions|open"';
|
|
674
680
|
case 'knowledge-panel':
|
|
675
|
-
return 'agent_knowledge, agent_knowledge_ingest, or
|
|
681
|
+
return 'agent_knowledge, agent_knowledge_ingest, or workspace action:"actions"';
|
|
676
682
|
case 'settings':
|
|
677
683
|
case 'tts-provider-picker':
|
|
678
684
|
case 'tts-voice-picker':
|
|
679
685
|
case 'reasoning-effort-picker':
|
|
680
|
-
return '
|
|
686
|
+
return 'settings action:"list|get|set" or workspace action:"open"';
|
|
681
687
|
case 'model-picker':
|
|
682
688
|
case 'provider-picker':
|
|
683
|
-
return '
|
|
689
|
+
return 'settings action:"get|set" or workspace action:"run_command"';
|
|
684
690
|
case 'session-picker':
|
|
685
691
|
case 'bookmark-modal':
|
|
686
692
|
case 'context-inspector':
|
|
687
693
|
case 'slash-command-mode':
|
|
688
694
|
case 'command-browser':
|
|
689
695
|
case 'block-actions':
|
|
690
|
-
return '
|
|
696
|
+
return 'workspace action:"commands|run_command"';
|
|
691
697
|
case 'process-monitor':
|
|
692
698
|
case 'live-tail':
|
|
693
699
|
case 'file-picker':
|
|
694
|
-
return 'first-class tools or
|
|
700
|
+
return 'first-class tools or workspace action:"open"';
|
|
695
701
|
case 'conversation-search':
|
|
696
702
|
case 'prompt-history-search':
|
|
697
|
-
return '
|
|
703
|
+
return 'workspace action:"open"';
|
|
698
704
|
case 'help-overlay':
|
|
699
|
-
return '
|
|
705
|
+
return 'workspace action:"commands|shortcuts"';
|
|
700
706
|
case 'shortcuts-overlay':
|
|
701
|
-
return '
|
|
707
|
+
return 'workspace action:"shortcuts|keybindings"';
|
|
702
708
|
default:
|
|
703
|
-
return '
|
|
709
|
+
return 'workspace action:"open"';
|
|
704
710
|
}
|
|
705
711
|
}
|
|
706
712
|
|
|
@@ -738,6 +744,7 @@ function describeSurface(
|
|
|
738
744
|
...(options.lookup ? { lookup: options.lookup } : {}),
|
|
739
745
|
modelRoute: uiSurfaceModelRoute(surface),
|
|
740
746
|
available: surface.available(context),
|
|
747
|
+
...(surface.id === 'connected-browser-cockpit' ? { cockpit: connectedBrowserCockpitRoute(context, { includeWorkspaceCoverage: options.includeParameters === true }) } : {}),
|
|
741
748
|
...(options.includeParameters ? {
|
|
742
749
|
preferredModelRoute: surface.preferredModelRoute,
|
|
743
750
|
parameters: surface.parameters ?? [],
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { CommandContext } from '../input/command-registry.ts';
|
|
2
|
+
|
|
3
|
+
export type UiSurfaceKind = 'overlay' | 'modal' | 'workspace' | 'picker';
|
|
4
|
+
|
|
5
|
+
export interface AgentHarnessUiSurfaceArgs {
|
|
6
|
+
readonly query?: unknown;
|
|
7
|
+
readonly surfaceId?: unknown;
|
|
8
|
+
readonly categoryId?: unknown;
|
|
9
|
+
readonly category?: unknown;
|
|
10
|
+
readonly target?: unknown;
|
|
11
|
+
readonly key?: unknown;
|
|
12
|
+
readonly prefix?: unknown;
|
|
13
|
+
readonly includeParameters?: unknown;
|
|
14
|
+
readonly limit?: unknown;
|
|
15
|
+
readonly pane?: unknown;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface UiSurfaceDefinition {
|
|
19
|
+
readonly id: string;
|
|
20
|
+
readonly label: string;
|
|
21
|
+
readonly kind: UiSurfaceKind;
|
|
22
|
+
readonly summary: string;
|
|
23
|
+
readonly command: string;
|
|
24
|
+
readonly preferredModelRoute: string;
|
|
25
|
+
readonly parameters?: readonly string[];
|
|
26
|
+
readonly available: (context: CommandContext) => boolean;
|
|
27
|
+
readonly open: (context: CommandContext, args: AgentHarnessUiSurfaceArgs) => Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface UiSurfaceLookup {
|
|
31
|
+
readonly source: 'surfaceId' | 'target' | 'query';
|
|
32
|
+
readonly input: string;
|
|
33
|
+
readonly resolvedBy: 'id' | 'case-insensitive-id' | 'label' | 'case-insensitive-label' | 'search';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type UiSurfaceResolution =
|
|
37
|
+
| {
|
|
38
|
+
readonly status: 'found';
|
|
39
|
+
readonly surface: UiSurfaceDefinition;
|
|
40
|
+
readonly lookup: UiSurfaceLookup;
|
|
41
|
+
}
|
|
42
|
+
| {
|
|
43
|
+
readonly status: 'ambiguous';
|
|
44
|
+
readonly input: string;
|
|
45
|
+
readonly candidates: readonly Record<string, unknown>[];
|
|
46
|
+
};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { CommandContext } from '../input/command-registry.ts';
|
|
2
|
+
import type { AgentVibeFile, BlockedAgentVibeFile } from '../agent/vibe-file.ts';
|
|
3
|
+
import { discoverVibeFiles } from '../agent/vibe-file.ts';
|
|
4
|
+
import { previewHarnessText } from './agent-harness-text.ts';
|
|
5
|
+
|
|
6
|
+
export interface AgentHarnessVibeHealthFile {
|
|
7
|
+
readonly path: string;
|
|
8
|
+
readonly scope: string;
|
|
9
|
+
readonly truncated?: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface AgentHarnessVibeHealthBlockedFile {
|
|
13
|
+
readonly path: string;
|
|
14
|
+
readonly scope: string;
|
|
15
|
+
readonly reason: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface AgentHarnessVibeHealth {
|
|
19
|
+
readonly status: 'ready' | 'check' | 'recommended';
|
|
20
|
+
readonly applied: number;
|
|
21
|
+
readonly blocked: number;
|
|
22
|
+
readonly truncated: number;
|
|
23
|
+
readonly files: readonly AgentHarnessVibeHealthFile[];
|
|
24
|
+
readonly blockedFiles: readonly AgentHarnessVibeHealthBlockedFile[];
|
|
25
|
+
readonly searchedPaths: readonly string[];
|
|
26
|
+
readonly projectInitPath: string;
|
|
27
|
+
readonly globalInitPath: string;
|
|
28
|
+
readonly nextAction: string;
|
|
29
|
+
readonly userRoute: string;
|
|
30
|
+
readonly modelRoute: string;
|
|
31
|
+
readonly signals: readonly string[];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function describeVibeFile(file: AgentVibeFile): AgentHarnessVibeHealthFile {
|
|
35
|
+
return {
|
|
36
|
+
path: file.path,
|
|
37
|
+
scope: file.scope,
|
|
38
|
+
...(file.truncated ? { truncated: true } : {}),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function describeBlockedVibeFile(file: BlockedAgentVibeFile): AgentHarnessVibeHealthBlockedFile {
|
|
43
|
+
return {
|
|
44
|
+
path: file.path,
|
|
45
|
+
scope: file.scope,
|
|
46
|
+
reason: previewHarnessText(file.reason, 180),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function agentHarnessVibeHealth(context: CommandContext): AgentHarnessVibeHealth {
|
|
51
|
+
const shellPaths = context.workspace.shellPaths;
|
|
52
|
+
if (!shellPaths) {
|
|
53
|
+
return {
|
|
54
|
+
status: 'recommended',
|
|
55
|
+
applied: 0,
|
|
56
|
+
blocked: 0,
|
|
57
|
+
truncated: 0,
|
|
58
|
+
files: [],
|
|
59
|
+
blockedFiles: [],
|
|
60
|
+
searchedPaths: [],
|
|
61
|
+
projectInitPath: '',
|
|
62
|
+
globalInitPath: '',
|
|
63
|
+
nextAction: 'VIBE.md discovery is unavailable because shell paths are not wired into this runtime.',
|
|
64
|
+
userRoute: 'Agent Workspace -> Local Context -> Personas -> VIBE.md; /vibe status',
|
|
65
|
+
modelRoute: 'vibe action:"status"',
|
|
66
|
+
signals: ['VIBE.md discovery unavailable: shell paths are not wired.'],
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
const snapshot = discoverVibeFiles(shellPaths);
|
|
70
|
+
const truncated = snapshot.files.filter((file) => file.truncated);
|
|
71
|
+
const status = snapshot.blocked.length > 0 || truncated.length > 0
|
|
72
|
+
? 'check'
|
|
73
|
+
: snapshot.files.length > 0
|
|
74
|
+
? 'ready'
|
|
75
|
+
: 'recommended';
|
|
76
|
+
const nextAction = snapshot.blocked.length > 0
|
|
77
|
+
? 'Run /vibe status, inspect blocked files, and edit or remove secret-looking content before relying on personality instructions.'
|
|
78
|
+
: truncated.length > 0
|
|
79
|
+
? 'Run /vibe status and shorten the truncated VIBE.md file if the omitted content matters.'
|
|
80
|
+
: snapshot.files.length > 0
|
|
81
|
+
? 'Review /vibe status when changing project or global personality instructions.'
|
|
82
|
+
: 'Create a project VIBE.md or import a reviewed persona when the user wants a custom assistant feel.';
|
|
83
|
+
const signals = [
|
|
84
|
+
`applied VIBE.md files: ${snapshot.files.length}`,
|
|
85
|
+
`blocked VIBE.md files: ${snapshot.blocked.length}`,
|
|
86
|
+
`truncated VIBE.md files: ${truncated.length}`,
|
|
87
|
+
...(snapshot.files.slice(0, 3).map((file) => `${file.scope}: ${file.path}${file.truncated ? ' (truncated)' : ''}`)),
|
|
88
|
+
...(snapshot.blocked.slice(0, 3).map((file) => `blocked ${file.scope}: ${file.path} - ${previewHarnessText(file.reason, 96)}`)),
|
|
89
|
+
];
|
|
90
|
+
return {
|
|
91
|
+
status,
|
|
92
|
+
applied: snapshot.files.length,
|
|
93
|
+
blocked: snapshot.blocked.length,
|
|
94
|
+
truncated: truncated.length,
|
|
95
|
+
files: snapshot.files.map(describeVibeFile),
|
|
96
|
+
blockedFiles: snapshot.blocked.map(describeBlockedVibeFile),
|
|
97
|
+
searchedPaths: snapshot.searchedPaths,
|
|
98
|
+
projectInitPath: snapshot.projectInitPath,
|
|
99
|
+
globalInitPath: snapshot.globalInitPath,
|
|
100
|
+
nextAction,
|
|
101
|
+
userRoute: 'Agent Workspace -> Local Context -> Personas -> VIBE.md; /vibe status',
|
|
102
|
+
modelRoute: 'vibe action:"status"',
|
|
103
|
+
signals,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import type { AgentHarnessToolArgs, AgentHarnessToolDeps } from './agent-harness-tool-types.ts';
|
|
2
|
+
import { clearSetupCheckpoint, markSetupCheckpoint, setupCheckpointSummary } from './agent-harness-setup-posture.ts';
|
|
3
|
+
import { runLocalWorkspaceAction } from './agent-harness-local-operations.ts';
|
|
4
|
+
import { AGENT_WORKSPACE_CATEGORIES, buildWorkspaceEditorContext, createWorkspaceEditor, describeWorkspaceAction, describeWorkspaceCategory, listWorkspaceActions, resolveWorkspaceActionDetail } from './agent-harness-workspace-actions.ts';
|
|
5
|
+
import { runCommand } from './agent-harness-command-runner.ts';
|
|
6
|
+
import { runWorkspaceEditorAction } from './agent-harness-workspace-editor-runner.ts';
|
|
7
|
+
import { error, output, readString, requireConfirmedAction } from './agent-harness-tool-utils.ts';
|
|
8
|
+
import { importAgentWorkspaceTuiSettings, previewAgentWorkspaceTuiSettingsImport } from '../input/agent-workspace-settings.ts';
|
|
9
|
+
import { writeOnboardingCheckMarker, writeOnboardingCompletionMarker } from '../runtime/onboarding/index.ts';
|
|
10
|
+
|
|
11
|
+
export async function runWorkspaceAction(
|
|
12
|
+
deps: AgentHarnessToolDeps,
|
|
13
|
+
args: AgentHarnessToolArgs,
|
|
14
|
+
): Promise<{ readonly success: boolean; readonly output?: string; readonly error?: string }> {
|
|
15
|
+
const resolved = resolveWorkspaceActionDetail(args);
|
|
16
|
+
if (resolved?.status === 'ambiguous') return error(`Ambiguous Agent workspace action ${resolved.input}. Candidates: ${JSON.stringify(resolved.candidates)}`);
|
|
17
|
+
if (!resolved) return error('run_workspace_action requires a valid actionId, command, target, or query. Use mode:"workspace_actions" to inspect available actions.');
|
|
18
|
+
const { category, action, lookup } = resolved;
|
|
19
|
+
|
|
20
|
+
if (action.safety === 'blocked') {
|
|
21
|
+
return error(`Workspace action ${action.id} is blocked in Agent: ${action.detail}`);
|
|
22
|
+
}
|
|
23
|
+
if (action.kind === 'guidance') {
|
|
24
|
+
const editorContext = buildWorkspaceEditorContext(deps.commandContext, args);
|
|
25
|
+
return output({
|
|
26
|
+
status: 'guidance',
|
|
27
|
+
action: describeWorkspaceAction(category, action, { includeEditor: true, editorContext, lookup }),
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
if (action.kind === 'workspace' && action.targetCategoryId) {
|
|
31
|
+
const target = AGENT_WORKSPACE_CATEGORIES.find((entry) => entry.id === action.targetCategoryId);
|
|
32
|
+
return output({
|
|
33
|
+
status: 'workspace_target',
|
|
34
|
+
action: describeWorkspaceAction(category, action, { lookup }),
|
|
35
|
+
targetCategory: target ? describeWorkspaceCategory(target) : action.targetCategoryId,
|
|
36
|
+
targetActions: target ? target.actions.map((entry) => describeWorkspaceAction(target, entry)).slice(0, 40) : [],
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
if (action.kind === 'command' && action.command) {
|
|
40
|
+
if (/<[^>\s]+(?:\s+[^>]*)?>/.test(action.command)) {
|
|
41
|
+
return output({
|
|
42
|
+
status: 'needs_concrete_command',
|
|
43
|
+
action: describeWorkspaceAction(category, action, { lookup }),
|
|
44
|
+
note: 'This workspace action is a command template. Provide concrete values with mode:"run_command" once the exact command is known.',
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return runCommand(deps, { ...args, command: action.command });
|
|
48
|
+
}
|
|
49
|
+
if (action.kind === 'settings-import') {
|
|
50
|
+
const preview = previewAgentWorkspaceTuiSettingsImport(deps.commandContext);
|
|
51
|
+
if (!preview) return error('GoodVibes settings import is unavailable in this runtime.');
|
|
52
|
+
if (args.confirm !== true) {
|
|
53
|
+
return output({
|
|
54
|
+
status: 'confirmation_required',
|
|
55
|
+
action: describeWorkspaceAction(category, action, { lookup }),
|
|
56
|
+
preview,
|
|
57
|
+
next: 'Run with confirm:true and explicitUserRequest after the user asks to import these settings.',
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
const explicitUserRequest = readString(args.explicitUserRequest);
|
|
61
|
+
if (!explicitUserRequest) {
|
|
62
|
+
return error('GoodVibes settings import requires explicitUserRequest when confirm is true.');
|
|
63
|
+
}
|
|
64
|
+
const outcome = await importAgentWorkspaceTuiSettings(deps.commandContext);
|
|
65
|
+
return output({
|
|
66
|
+
status: outcome.status,
|
|
67
|
+
action: describeWorkspaceAction(category, action, { lookup }),
|
|
68
|
+
preview,
|
|
69
|
+
actionResult: outcome.result,
|
|
70
|
+
runtimeSnapshot: outcome.runtimeSnapshot,
|
|
71
|
+
policy: {
|
|
72
|
+
effect: 'state',
|
|
73
|
+
confirmation: 'confirmed',
|
|
74
|
+
explicitUserRequest,
|
|
75
|
+
boundary: 'Applied only Agent-owned settings and subscription state from published GoodVibes platform sources; source package stores were not mutated.',
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (action.kind === 'setup-checkpoint') {
|
|
80
|
+
const operation = action.setupCheckpointOperation ?? 'show';
|
|
81
|
+
if (operation === 'show') {
|
|
82
|
+
return output({
|
|
83
|
+
status: 'checkpoint_inspected',
|
|
84
|
+
action: describeWorkspaceAction(category, action, { lookup }),
|
|
85
|
+
checkpoint: await setupCheckpointSummary(deps.commandContext),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
const confirmationError = requireConfirmedAction(args, operation === 'clear' ? 'Setup wizard checkpoint clear' : 'Setup wizard checkpoint save');
|
|
89
|
+
if (confirmationError) return error(confirmationError);
|
|
90
|
+
const result = operation === 'clear'
|
|
91
|
+
? clearSetupCheckpoint(deps.commandContext, args)
|
|
92
|
+
: await markSetupCheckpoint(deps.commandContext, args);
|
|
93
|
+
return output({
|
|
94
|
+
status: 'checkpoint_action_completed',
|
|
95
|
+
action: describeWorkspaceAction(category, action, { lookup }),
|
|
96
|
+
result,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
if (action.kind === 'editor' && action.editorKind) {
|
|
100
|
+
const editor = createWorkspaceEditor(action.editorKind, buildWorkspaceEditorContext(deps.commandContext, args));
|
|
101
|
+
if (!editor) return error(`No workspace editor route exists for ${action.editorKind}.`);
|
|
102
|
+
return runWorkspaceEditorAction(deps, action, editor, args);
|
|
103
|
+
}
|
|
104
|
+
if (action.kind === 'local-selection' || action.kind === 'local-operation') {
|
|
105
|
+
return runLocalWorkspaceAction(deps, action, args);
|
|
106
|
+
}
|
|
107
|
+
if (action.kind === 'onboarding-complete') {
|
|
108
|
+
const confirmationError = requireConfirmedAction(args, 'Onboarding completion');
|
|
109
|
+
if (confirmationError) return error(confirmationError);
|
|
110
|
+
const explicitUserRequest = readString(args.explicitUserRequest);
|
|
111
|
+
if (!explicitUserRequest) return error('Onboarding completion requires explicitUserRequest when confirm is true.');
|
|
112
|
+
const shellPaths = deps.commandContext.workspace?.shellPaths;
|
|
113
|
+
if (!shellPaths) return error('Onboarding completion requires Agent shell paths.');
|
|
114
|
+
const marker = { scope: 'user', source: 'wizard', mode: 'new', workspaceRoot: shellPaths.workingDirectory } as const;
|
|
115
|
+
const checkMarker = writeOnboardingCheckMarker(shellPaths, marker);
|
|
116
|
+
const completionMarker = writeOnboardingCompletionMarker(shellPaths, marker);
|
|
117
|
+
return output({
|
|
118
|
+
status: 'onboarding_completed',
|
|
119
|
+
action: describeWorkspaceAction(category, action, { lookup }),
|
|
120
|
+
explicitUserRequest,
|
|
121
|
+
checkMarker: {
|
|
122
|
+
exists: checkMarker.exists,
|
|
123
|
+
path: checkMarker.path,
|
|
124
|
+
updatedAt: checkMarker.payload?.updatedAt ?? null,
|
|
125
|
+
source: checkMarker.payload?.source ?? null,
|
|
126
|
+
mode: checkMarker.payload?.mode ?? null,
|
|
127
|
+
},
|
|
128
|
+
completionMarker: {
|
|
129
|
+
exists: completionMarker.exists,
|
|
130
|
+
path: completionMarker.path,
|
|
131
|
+
updatedAt: completionMarker.payload?.updatedAt ?? null,
|
|
132
|
+
source: completionMarker.payload?.source ?? null,
|
|
133
|
+
mode: completionMarker.payload?.mode ?? null,
|
|
134
|
+
},
|
|
135
|
+
routes: {
|
|
136
|
+
inspectSetup: 'setup action:"status" includeParameters:true',
|
|
137
|
+
},
|
|
138
|
+
policy: {
|
|
139
|
+
effect: 'confirmed-onboarding-marker-write',
|
|
140
|
+
boundary: 'Writes only the user onboarding check and completion markers. It does not mutate provider credentials, connected-host state, channels, schedules, or local behavior.',
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
const editorContext = buildWorkspaceEditorContext(deps.commandContext, args);
|
|
145
|
+
return output({
|
|
146
|
+
status: 'no_direct_effect',
|
|
147
|
+
action: describeWorkspaceAction(category, action, { includeEditor: true, editorContext, lookup }),
|
|
148
|
+
});
|
|
149
|
+
}
|