@pellux/goodvibes-agent 1.0.31 → 1.0.34

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 (74) hide show
  1. package/CHANGELOG.md +59 -2
  2. package/README.md +72 -58
  3. package/dist/package/main.js +7572 -2430
  4. package/docs/README.md +25 -21
  5. package/docs/channels-remote-and-api.md +6 -2
  6. package/docs/connected-host.md +27 -6
  7. package/docs/getting-started.md +87 -66
  8. package/docs/knowledge-artifacts-and-multimodal.md +16 -4
  9. package/docs/project-planning.md +2 -2
  10. package/docs/providers-and-routing.md +3 -2
  11. package/docs/release-and-publishing.md +15 -11
  12. package/docs/tools-and-commands.md +150 -128
  13. package/docs/voice-and-live-tts.md +1 -1
  14. package/package.json +8 -3
  15. package/release/live-verification/live-verification.json +148 -0
  16. package/release/live-verification/live-verification.md +187 -0
  17. package/release/performance-snapshot.json +57 -0
  18. package/release/release-notes.md +19 -0
  19. package/release/release-readiness.json +581 -0
  20. package/src/agent/harness-control.ts +42 -3
  21. package/src/cli/agent-knowledge-command.ts +5 -5
  22. package/src/cli/agent-knowledge-format.ts +11 -0
  23. package/src/cli/agent-knowledge-runtime.ts +92 -13
  24. package/src/cli/bundle-command.ts +5 -4
  25. package/src/cli/entrypoint.ts +5 -2
  26. package/src/cli/external-runtime.ts +2 -15
  27. package/src/cli/management.ts +4 -3
  28. package/src/input/commands/guidance-runtime.ts +1 -1
  29. package/src/input/commands/knowledge.ts +2 -2
  30. package/src/runtime/bootstrap.ts +10 -18
  31. package/src/runtime/connected-host-auth.ts +16 -0
  32. package/src/tools/agent-analysis-registry-policy.ts +2 -9
  33. package/src/tools/agent-channel-send-tool.ts +3 -9
  34. package/src/tools/agent-context-policy.ts +1 -5
  35. package/src/tools/agent-find-policy.ts +1 -4
  36. package/src/tools/agent-harness-channel-metadata.ts +177 -0
  37. package/src/tools/agent-harness-cli-metadata.ts +4 -1
  38. package/src/tools/agent-harness-command-catalog.ts +10 -3
  39. package/src/tools/agent-harness-connected-host-status.ts +9 -3
  40. package/src/tools/agent-harness-delegation-posture.ts +216 -0
  41. package/src/tools/agent-harness-keybinding-metadata.ts +57 -22
  42. package/src/tools/agent-harness-mcp-metadata.ts +248 -0
  43. package/src/tools/agent-harness-media-posture.ts +282 -0
  44. package/src/tools/agent-harness-metadata.ts +44 -9
  45. package/src/tools/agent-harness-model-routing.ts +501 -0
  46. package/src/tools/agent-harness-model-tool-catalog.ts +7 -2
  47. package/src/tools/agent-harness-notification-metadata.ts +217 -0
  48. package/src/tools/agent-harness-operator-methods.ts +285 -0
  49. package/src/tools/agent-harness-pairing-posture.ts +265 -0
  50. package/src/tools/agent-harness-panel-metadata.ts +26 -12
  51. package/src/tools/agent-harness-provider-account-metadata.ts +205 -0
  52. package/src/tools/agent-harness-release-evidence.ts +364 -0
  53. package/src/tools/agent-harness-release-readiness.ts +298 -0
  54. package/src/tools/agent-harness-security-posture.ts +648 -0
  55. package/src/tools/agent-harness-service-posture.ts +207 -0
  56. package/src/tools/agent-harness-session-metadata.ts +284 -0
  57. package/src/tools/agent-harness-setup-posture.ts +295 -0
  58. package/src/tools/agent-harness-tool-schema.ts +104 -27
  59. package/src/tools/agent-harness-tool.ts +251 -235
  60. package/src/tools/agent-harness-ui-surface-metadata.ts +20 -12
  61. package/src/tools/agent-harness-workspace-actions.ts +260 -0
  62. package/src/tools/agent-knowledge-ingest-tool.ts +4 -10
  63. package/src/tools/agent-knowledge-tool.ts +120 -25
  64. package/src/tools/agent-local-registry-tool.ts +3 -7
  65. package/src/tools/agent-media-generate-tool.ts +2 -8
  66. package/src/tools/agent-notify-tool.ts +3 -8
  67. package/src/tools/agent-operator-action-tool.ts +4 -10
  68. package/src/tools/agent-operator-briefing-tool.ts +1 -6
  69. package/src/tools/agent-read-policy.ts +1 -4
  70. package/src/tools/agent-reminder-schedule-tool.ts +4 -9
  71. package/src/tools/agent-tool-policy-guard.ts +15 -51
  72. package/src/tools/agent-web-search-policy.ts +1 -4
  73. package/src/tools/agent-work-plan-tool.ts +1 -6
  74. package/src/version.ts +2 -2
@@ -2,42 +2,37 @@ import type { Tool } from '@pellux/goodvibes-sdk/platform/types';
2
2
  import type { ToolRegistry } from '@pellux/goodvibes-sdk/platform/tools';
3
3
  import type { CommandContext, CommandRegistry } from '../input/command-registry.ts';
4
4
  import { buildAgentWorkspaceCommandEditorSubmission, isAgentWorkspaceCommandEditorKind } from '../input/agent-workspace-command-editor.ts';
5
- import { createAgentWorkspaceEditor } from '../input/agent-workspace-activation.ts';
6
- import { AGENT_WORKSPACE_CATEGORIES } from '../input/agent-workspace-categories.ts';
7
5
  import { isAffirmative, splitList } from '../input/agent-workspace-editors.ts';
8
6
  import { createAgentWorkspaceLearnedBehavior } from '../input/agent-workspace-learned-behavior.ts';
9
- import { searchAgentWorkspaceActions } from '../input/agent-workspace-search.ts';
10
- import { buildAgentWorkspaceRuntimeSnapshot } from '../input/agent-workspace-snapshot.ts';
11
- import type {
12
- AgentWorkspaceAction,
13
- AgentWorkspaceCategory,
14
- AgentWorkspaceEditorKind,
15
- AgentWorkspaceLocalEditor,
16
- AgentWorkspaceLocalLibraryItem,
17
- AgentWorkspaceRuntimeSnapshot,
18
- } from '../input/agent-workspace-types.ts';
7
+ import type { AgentWorkspaceAction, AgentWorkspaceLocalEditor } from '../input/agent-workspace-types.ts';
8
+ import { channelReadinessCatalogStatus, describeHarnessChannel, listHarnessChannels } from './agent-harness-channel-metadata.ts';
19
9
  import { blockedHarnessCliCommandTokens, describeHarnessCliCommand, listHarnessCliCommands, totalHarnessCliCommands } from './agent-harness-cli-metadata.ts';
20
10
  import { describeHarnessCommand, listHarnessCommands, resolveHarnessCommandDetail, type CommandDetailLookup } from './agent-harness-command-catalog.ts';
11
+ import { delegationPostureCatalogStatus, delegationPostureSummary, describeHarnessDelegationRoute } from './agent-harness-delegation-posture.ts';
21
12
  import { describeHarnessKeybinding, listHarnessKeybindings, listHarnessShortcuts, resetHarnessKeybinding, runHarnessKeybinding, setHarnessKeybinding, totalHarnessKeybindings, totalHarnessShortcuts } from './agent-harness-keybinding-metadata.ts';
13
+ import { describeHarnessMediaProvider, mediaPostureCatalogStatus, mediaPostureSummary } from './agent-harness-media-posture.ts';
14
+ import { describeHarnessNotificationTarget, listHarnessNotificationTargets, notificationTargetCatalogStatus } from './agent-harness-notification-metadata.ts';
22
15
  import { describeHarnessPanel, listHarnessPanels, openHarnessPanel, totalHarnessPanels } from './agent-harness-panel-metadata.ts';
23
16
  import { connectedHostStatusSummary } from './agent-harness-connected-host-status.ts';
24
- import { describeLocalWorkspaceModelExecution, runLocalWorkspaceAction, runLocalWorkspaceEditorAction } from './agent-harness-local-operations.ts';
17
+ import { runLocalWorkspaceAction, runLocalWorkspaceEditorAction } from './agent-harness-local-operations.ts';
18
+ import { describeHarnessMcpServer, mcpServerCatalogStatus, mcpServerSummary } from './agent-harness-mcp-metadata.ts';
19
+ import { describeHarnessModelRoute, modelRoutingCatalogStatus, modelRoutingSummary } from './agent-harness-model-routing.ts';
25
20
  import { describeHarnessModelTool, listHarnessModelTools } from './agent-harness-model-tool-catalog.ts';
21
+ import { describeHarnessOperatorMethod, operatorMethodCatalogStatus, operatorMethodSummary } from './agent-harness-operator-methods.ts';
22
+ import { describeHarnessPairingRoute, pairingPostureCatalogStatus, pairingPostureSummary } from './agent-harness-pairing-posture.ts';
23
+ import { describeHarnessProviderAccount, providerAccountCatalogStatus, providerAccountSummary } from './agent-harness-provider-account-metadata.ts';
24
+ import { describeHarnessReleaseEvidenceArtifact, releaseEvidenceBundleStatus, releaseEvidenceSummary } from './agent-harness-release-evidence.ts';
25
+ import { describeHarnessReleaseReadinessItem, releaseReadinessInventoryStatus, releaseReadinessSummary } from './agent-harness-release-readiness.ts';
26
+ import { describeHarnessSecurityFinding, describeHarnessSupportBundle, securityPostureCatalogStatus, securityPostureSummary, supportBundleCatalogStatus, supportBundleSummary } from './agent-harness-security-posture.ts';
27
+ import { describeHarnessSession, sessionCatalogStatus, sessionSummary } from './agent-harness-session-metadata.ts';
28
+ import { describeHarnessServiceEndpoint, servicePostureCatalogStatus, servicePostureSummary } from './agent-harness-service-posture.ts';
29
+ import { describeHarnessSetupItem, setupPostureCatalogStatus, setupPostureSummary } from './agent-harness-setup-posture.ts';
26
30
  import { AGENT_HARNESS_MODES, AGENT_HARNESS_PARAMETER_PROPERTIES } from './agent-harness-tool-schema.ts';
27
31
  import { describeHarnessUiSurface, listHarnessUiSurfaces, openHarnessUiSurface, totalHarnessUiSurfaces } from './agent-harness-ui-surface-metadata.ts';
32
+ import { AGENT_WORKSPACE_CATEGORIES, allWorkspaceActions, buildWorkspaceEditorContext, createWorkspaceEditor, describeWorkspaceAction, describeWorkspaceCategory, describeWorkspaceEditor, listWorkspaceActions, resolveWorkspaceActionDetail } from './agent-harness-workspace-actions.ts';
28
33
  import { describeWorkspaceEditorModelExecution } from './agent-harness-workspace-editor-execution.ts';
29
- import {
30
- connectedHostSummary,
31
- describeConnectedHostCapability,
32
- settingsPolicySummary,
33
- } from './agent-harness-metadata.ts';
34
- import {
35
- formatHarnessError,
36
- listHarnessSettings,
37
- resetHarnessSetting,
38
- resolveHarnessSetting,
39
- setHarnessSetting,
40
- } from '../agent/harness-control.ts';
34
+ import { connectedHostSummary, describeConnectedHostCapability, settingsPolicySummary } from './agent-harness-metadata.ts';
35
+ import { formatHarnessError, listHarnessSettings, resetHarnessSetting, resolveHarnessSetting, setHarnessSetting } from '../agent/harness-control.ts';
41
36
 
42
37
  type AgentHarnessMode = typeof AGENT_HARNESS_MODES[number];
43
38
 
@@ -48,6 +43,18 @@ interface AgentHarnessToolArgs {
48
43
  readonly cliCommand?: unknown;
49
44
  readonly commandName?: unknown;
50
45
  readonly args?: unknown;
46
+ readonly channelId?: unknown;
47
+ readonly notificationTargetId?: unknown;
48
+ readonly providerId?: unknown;
49
+ readonly mcpServerId?: unknown;
50
+ readonly setupItemId?: unknown;
51
+ readonly modelRouteId?: unknown;
52
+ readonly pairingRouteId?: unknown;
53
+ readonly delegationRouteId?: unknown;
54
+ readonly findingId?: unknown;
55
+ readonly bundlePath?: unknown;
56
+ readonly mediaProviderId?: unknown;
57
+ readonly sessionId?: unknown;
51
58
  readonly categoryId?: unknown;
52
59
  readonly panelId?: unknown;
53
60
  readonly actionId?: unknown;
@@ -59,6 +66,10 @@ interface AgentHarnessToolArgs {
59
66
  readonly key?: unknown;
60
67
  readonly value?: unknown;
61
68
  readonly target?: unknown;
69
+ readonly artifactId?: unknown;
70
+ readonly itemId?: unknown;
71
+ readonly methodId?: unknown;
72
+ readonly endpointId?: unknown;
62
73
  readonly capabilityId?: unknown;
63
74
  readonly toolName?: unknown;
64
75
  readonly category?: unknown;
@@ -77,30 +88,6 @@ interface AgentHarnessToolDeps {
77
88
  readonly toolRegistry: ToolRegistry;
78
89
  }
79
90
 
80
- interface WorkspaceEditorContext {
81
- readonly runtimeStarterTemplates: AgentWorkspaceRuntimeSnapshot['runtimeStarterTemplates'];
82
- readonly selectedRoutine: AgentWorkspaceLocalLibraryItem | null;
83
- }
84
-
85
- interface WorkspaceActionLookup {
86
- readonly source: 'actionId' | 'command' | 'target' | 'query';
87
- readonly input: string;
88
- readonly resolvedBy: 'id' | 'case-insensitive-id' | 'label' | 'case-insensitive-label' | 'command' | 'search';
89
- }
90
-
91
- type WorkspaceActionResolution =
92
- | {
93
- readonly status: 'found';
94
- readonly category: AgentWorkspaceCategory;
95
- readonly action: AgentWorkspaceAction;
96
- readonly lookup: WorkspaceActionLookup;
97
- }
98
- | {
99
- readonly status: 'ambiguous';
100
- readonly input: string;
101
- readonly candidates: readonly { readonly actionId: string; readonly categoryId: string; readonly label: string; readonly command?: string }[];
102
- };
103
-
104
91
  function isMode(value: unknown): value is AgentHarnessMode {
105
92
  return typeof value === 'string' && AGENT_HARNESS_MODES.includes(value as AgentHarnessMode);
106
93
  }
@@ -140,173 +127,67 @@ function output(value: unknown): { readonly success: true; readonly output: stri
140
127
 
141
128
  function error(message: string): { readonly success: false; readonly error: string } { return { success: false, error: message }; }
142
129
 
143
- function allWorkspaceActions(): ReadonlyArray<{
144
- readonly category: AgentWorkspaceCategory;
145
- readonly action: AgentWorkspaceAction;
146
- }> {
147
- return AGENT_WORKSPACE_CATEGORIES.flatMap((category) => category.actions.map((action) => ({ category, action })));
148
- }
149
-
150
- function describeWorkspaceCategory(category: AgentWorkspaceCategory): Record<string, unknown> {
130
+ function compactHarnessModeGuide(): Record<string, unknown> {
151
131
  return {
152
- id: category.id,
153
- group: category.group,
154
- label: category.label,
155
- summary: category.summary,
156
- detail: category.detail,
157
- actions: category.actions.length,
132
+ discover: [
133
+ 'cli_commands', 'panels', 'ui_surfaces', 'shortcuts', 'keybindings',
134
+ 'commands', 'channels', 'notifications', 'provider_accounts', 'mcp_servers',
135
+ 'setup_posture', 'model_routing', 'pairing_posture', 'delegation_posture',
136
+ 'security_posture', 'support_bundles', 'media_posture', 'sessions',
137
+ 'settings', 'workspace', 'workspace_categories', 'workspace_actions',
138
+ 'tools', 'release_evidence', 'release_readiness', 'operator_methods',
139
+ 'service_posture', 'connected_host', 'daemon',
140
+ ],
141
+ inspect: [
142
+ 'cli_command', 'panel', 'ui_surface', 'keybinding', 'command', 'channel',
143
+ 'notification_target', 'provider_account', 'mcp_server', 'setup_item',
144
+ 'model_route', 'pairing_route', 'delegation_route', 'security_finding',
145
+ 'support_bundle', 'media_provider', 'session', 'get_setting',
146
+ 'workspace_action', 'tool', 'release_evidence_artifact',
147
+ 'release_readiness_item', 'operator_method', 'service_endpoint',
148
+ 'connected_host_capability', 'connected_host_status', 'daemon_status',
149
+ ],
150
+ effects: [
151
+ 'open_panel', 'open_ui_surface', 'run_keybinding', 'set_keybinding',
152
+ 'reset_keybinding', 'run_command', 'set_setting', 'reset_setting',
153
+ 'run_workspace_action',
154
+ ],
155
+ pattern: 'Use query|target for search, exact ids for inspect modes, and confirm:true plus explicitUserRequest for effects.',
158
156
  };
159
157
  }
160
158
 
161
- function describeWorkspaceEditor(editor: AgentWorkspaceLocalEditor): Record<string, unknown> {
159
+ function detailedHarnessModelAccessGuide(): Record<string, string> {
162
160
  return {
163
- kind: editor.kind,
164
- mode: editor.mode,
165
- title: editor.title,
166
- message: editor.message,
167
- fields: editor.fields.map((field) => ({
168
- id: field.id,
169
- label: field.label,
170
- required: field.required,
171
- multiline: field.multiline,
172
- hint: field.hint,
173
- redact: field.redact === true,
174
- default: field.redact ? '<redacted>' : field.value,
175
- })),
161
+ cliCommands: 'List mode:"cli_commands"; inspect mode:"cli_command" with cliCommand|commandName|query. Discovery only.',
162
+ panels: 'List mode:"panels"; inspect mode:"panel"; navigate mode:"open_panel" with confirm:true and explicitUserRequest.',
163
+ uiSurfaces: 'List mode:"ui_surfaces"; inspect mode:"ui_surface"; navigate mode:"open_ui_surface" with confirmation.',
164
+ shortcuts: 'List mode:"shortcuts"; inspect mode:"keybinding"; run mode:"run_keybinding"; edit with set_keybinding/reset_keybinding and confirmation.',
165
+ slashCommands: 'List mode:"commands"; inspect mode:"command"; execute mode:"run_command" with confirmation.',
166
+ channels: 'List mode:"channels"; inspect mode:"channel"; deliver with agent_channel_send and confirmation.',
167
+ notifications: 'List mode:"notifications"; inspect mode:"notification_target"; deliver with agent_notify and confirmation.',
168
+ providerAccounts: 'List mode:"provider_accounts"; inspect mode:"provider_account"; auth changes stay confirmed workspace/command flows.',
169
+ mcpServers: 'List mode:"mcp_servers"; inspect mode:"mcp_server"; trust/server changes stay confirmed workspace/command flows.',
170
+ setupPosture: 'List mode:"setup_posture"; inspect mode:"setup_item"; setup mutations stay confirmed visible flows.',
171
+ modelRouting: 'List mode:"model_routing"; inspect mode:"model_route"; selection and provider edits stay confirmed visible flows.',
172
+ pairingPosture: 'List mode:"pairing_posture"; inspect mode:"pairing_route"; raw token/QR and pairing effects stay visible user flows.',
173
+ delegationPosture: 'List mode:"delegation_posture"; inspect mode:"delegation_route"; delegated submission stays confirmed visible flow.',
174
+ securityPosture: 'List mode:"security_posture"; inspect mode:"security_finding"; mutate only through confirmed security routes.',
175
+ supportBundles: 'List mode:"support_bundles"; inspect mode:"support_bundle"; export/import stays confirmation-gated.',
176
+ mediaPosture: 'List mode:"media_posture"; inspect mode:"media_provider"; generate with agent_media_generate and confirmation.',
177
+ sessions: 'List mode:"sessions"; inspect mode:"session"; save/resume/export/delete stays visible confirmed flow.',
178
+ workspace: 'List mode:"workspace" or mode:"workspace_categories"; actions via workspace_actions/workspace_action/run_workspace_action; includeParameters:true inlines editor schemas.',
179
+ settings: 'List mode:"settings" with category|prefix|query|includeHidden:true; get_setting/set_setting/reset_setting use key|target|query and confirmation for writes.',
180
+ tools: 'List mode:"tools" with query|limit|includeParameters:true; inspect mode:"tool" with toolName|target|query.',
181
+ releaseEvidence: 'List mode:"release_evidence"; inspect mode:"release_evidence_artifact"; includeParameters:true inlines artifact detail.',
182
+ releaseReadiness: 'List mode:"release_readiness"; inspect mode:"release_readiness_item"; includeParameters:true inlines item detail.',
183
+ operatorMethods: 'List mode:"operator_methods"; inspect mode:"operator_method"; execute only through the returned first-class tool.',
184
+ servicePosture: 'List mode:"service_posture"; inspect mode:"service_endpoint"; includeParameters:true adds probes and redacted log tail.',
185
+ connectedHost: 'Map mode:"connected_host"; inspect mode:"connected_host_capability"; no lifecycle control.',
186
+ connectedHostStatus: 'Live read-only mode:"connected_host_status" for host reachability, SDK compatibility, token posture, and Knowledge readiness.',
187
+ daemon: 'Daemon aliases route to mode:"connected_host" and mode:"connected_host_status"; lifecycle control is not exposed.',
176
188
  };
177
189
  }
178
190
 
179
- function selectedRoutineFromArgs(
180
- snapshot: AgentWorkspaceRuntimeSnapshot,
181
- args: AgentHarnessToolArgs,
182
- ): AgentWorkspaceLocalLibraryItem | null {
183
- const fields = readFieldMap(args.fields);
184
- const routineId = readString(args.recordId) || readString(fields.routineId) || readString(fields.id);
185
- if (!routineId) return null;
186
- return snapshot.localRoutines.find((routine) => routine.id === routineId || routine.name.toLowerCase() === routineId.toLowerCase()) ?? null;
187
- }
188
-
189
- function buildWorkspaceEditorContext(context: CommandContext, args: AgentHarnessToolArgs): WorkspaceEditorContext {
190
- try {
191
- const snapshot = buildAgentWorkspaceRuntimeSnapshot(context);
192
- return {
193
- runtimeStarterTemplates: snapshot.runtimeStarterTemplates,
194
- selectedRoutine: selectedRoutineFromArgs(snapshot, args),
195
- };
196
- } catch {
197
- return {
198
- runtimeStarterTemplates: [],
199
- selectedRoutine: null,
200
- };
201
- }
202
- }
203
-
204
- function createWorkspaceEditor(
205
- editorKind: AgentWorkspaceEditorKind,
206
- editorContext: WorkspaceEditorContext | null,
207
- ): AgentWorkspaceLocalEditor | null {
208
- return createAgentWorkspaceEditor(editorKind, {
209
- runtimeStarterTemplates: editorContext?.runtimeStarterTemplates ?? [],
210
- selectedRoutine: editorKind === 'routine-schedule' ? editorContext?.selectedRoutine ?? null : null,
211
- });
212
- }
213
-
214
- function describeWorkspaceAction(
215
- category: AgentWorkspaceCategory,
216
- action: AgentWorkspaceAction,
217
- options: { readonly includeEditor?: boolean; readonly editorContext?: WorkspaceEditorContext | null; readonly lookup?: WorkspaceActionLookup } = {},
218
- ): Record<string, unknown> {
219
- const editor = options.includeEditor && action.editorKind ? createWorkspaceEditor(action.editorKind, options.editorContext ?? null) : null;
220
- return {
221
- id: action.id,
222
- categoryId: category.id,
223
- category: category.label,
224
- group: category.group,
225
- label: action.label,
226
- detail: action.detail,
227
- kind: action.kind,
228
- safety: action.safety,
229
- ...(action.command ? { command: action.command } : {}),
230
- ...(action.targetCategoryId ? { targetCategoryId: action.targetCategoryId } : {}),
231
- ...(action.editorKind ? { editorKind: action.editorKind } : {}),
232
- ...(action.localKind ? { localKind: action.localKind } : {}),
233
- ...(action.localOperation ? { localOperation: action.localOperation } : {}),
234
- ...(options.lookup ? { lookup: options.lookup } : {}),
235
- ...(editor ? { editor: describeWorkspaceEditor(editor) } : {}),
236
- ...(action.kind === 'local-selection' || action.kind === 'local-operation' ? {
237
- modelExecution: describeLocalWorkspaceModelExecution(action),
238
- } : {}),
239
- ...(action.kind === 'editor' && action.editorKind ? {
240
- modelExecution: describeWorkspaceEditorModelExecution(action.editorKind),
241
- } : {}),
242
- };
243
- }
244
-
245
- function listWorkspaceActions(deps: AgentHarnessToolDeps, args: AgentHarnessToolArgs): readonly Record<string, unknown>[] {
246
- const query = readString(args.query);
247
- const categoryId = readString(args.categoryId || args.category);
248
- const limit = readLimit(args.limit, 200);
249
- const includeEditor = args.includeParameters === true;
250
- const editorContext = includeEditor ? buildWorkspaceEditorContext(deps.commandContext, args) : null;
251
- const source = query
252
- ? searchAgentWorkspaceActions(AGENT_WORKSPACE_CATEGORIES, query).map((result) => ({ category: result.category, action: result.action }))
253
- : allWorkspaceActions();
254
- return source
255
- .filter((entry) => !categoryId || entry.category.id === categoryId)
256
- .slice(0, limit)
257
- .map((entry) => describeWorkspaceAction(entry.category, entry.action, { includeEditor, editorContext }));
258
- }
259
-
260
- function workspaceActionLookupFromArgs(args: AgentHarnessToolArgs): { readonly source: WorkspaceActionLookup['source']; readonly input: string } | null {
261
- const actionId = readString(args.actionId);
262
- if (actionId) return { source: 'actionId', input: actionId };
263
- const command = readString(args.command);
264
- if (command) return { source: 'command', input: command };
265
- const target = readString(args.target);
266
- if (target) return { source: 'target', input: target };
267
- const query = readString(args.query);
268
- return query ? { source: 'query', input: query } : null;
269
- }
270
-
271
- function describeWorkspaceActionCandidates(
272
- entries: readonly { readonly category: AgentWorkspaceCategory; readonly action: AgentWorkspaceAction }[],
273
- ): readonly { readonly actionId: string; readonly categoryId: string; readonly label: string; readonly command?: string }[] {
274
- return entries.slice(0, 8).map((entry) => ({
275
- actionId: entry.action.id,
276
- categoryId: entry.category.id,
277
- label: entry.action.label,
278
- ...(entry.action.command ? { command: entry.action.command } : {}),
279
- }));
280
- }
281
-
282
- function resolveWorkspaceActionDetail(args: AgentHarnessToolArgs): WorkspaceActionResolution | null {
283
- const lookup = workspaceActionLookupFromArgs(args);
284
- const categoryId = readString(args.categoryId || args.category);
285
- if (!lookup) return null;
286
- const entries = allWorkspaceActions().filter((entry) => !categoryId || entry.category.id === categoryId);
287
- const normalized = lookup.input.toLowerCase();
288
- const commandInput = lookup.source === 'command' ? lookup.input.trim() : '';
289
-
290
- const exactId = entries.find((entry) => entry.action.id === lookup.input);
291
- if (exactId) return { status: 'found', ...exactId, lookup: { ...lookup, resolvedBy: 'id' } };
292
- const exactLabel = entries.find((entry) => entry.action.label === lookup.input);
293
- if (exactLabel) return { status: 'found', ...exactLabel, lookup: { ...lookup, resolvedBy: 'label' } };
294
- const exactCommand = commandInput ? entries.find((entry) => entry.action.command === commandInput) : null;
295
- if (exactCommand) return { status: 'found', ...exactCommand, lookup: { ...lookup, resolvedBy: 'command' } };
296
-
297
- const insensitiveId = entries.find((entry) => entry.action.id.toLowerCase() === normalized);
298
- if (insensitiveId) return { status: 'found', ...insensitiveId, lookup: { ...lookup, resolvedBy: 'case-insensitive-id' } };
299
- const insensitiveLabel = entries.find((entry) => entry.action.label.toLowerCase() === normalized);
300
- if (insensitiveLabel) return { status: 'found', ...insensitiveLabel, lookup: { ...lookup, resolvedBy: 'case-insensitive-label' } };
301
-
302
- const searched = searchAgentWorkspaceActions(AGENT_WORKSPACE_CATEGORIES, lookup.input)
303
- .map((result) => ({ category: result.category, action: result.action }))
304
- .filter((entry) => !categoryId || entry.category.id === categoryId);
305
- if (searched.length === 1) return { status: 'found', ...searched[0]!, lookup: { ...lookup, resolvedBy: 'search' } };
306
- if (searched.length > 1) return { status: 'ambiguous', input: lookup.input, candidates: describeWorkspaceActionCandidates(searched) };
307
- return null;
308
- }
309
-
310
191
  function requireConfirmedAction(args: AgentHarnessToolArgs, action: string): string | null {
311
192
  const explicitUserRequest = readString(args.explicitUserRequest);
312
193
  if (!explicitUserRequest) return `${action} requires explicitUserRequest with the user's exact request or a short faithful summary.`;
@@ -528,12 +409,7 @@ export function createAgentHarnessTool(deps: AgentHarnessToolDeps): Tool {
528
409
  return {
529
410
  definition: {
530
411
  name: 'agent_harness',
531
- description: [
532
- 'Discover and operate the GoodVibes Agent harness from the main conversation.',
533
- 'Use this tool to inspect Agent workspace categories/actions, built-in panels, top-level CLI mirrors, UI surfaces, keybindings, slash commands with policy metadata, model tools or one model tool schema, connected-host capabilities or one connected-host capability detail, and Agent settings, or to invoke a workspace action/command through the same in-process command registry the user uses in the TUI.',
534
- 'Discovery modes are read-only. Setting/keybinding writes, resets, keybinding actions, UI routing, slash command invocation, and workspace action invocation require confirm:true plus explicitUserRequest.',
535
- 'This tool preserves Agent product boundaries: connected-host lifecycle and listener posture stay externally owned, connected-host mode reports allowed and blocked route families, and secret-backed settings store raw values through the secret manager while config receives only a secret reference.',
536
- ].join(' '),
412
+ description: 'Inspect or operate GoodVibes Agent harness surfaces.',
537
413
  parameters: {
538
414
  type: 'object',
539
415
  properties: AGENT_HARNESS_PARAMETER_PROPERTIES,
@@ -556,24 +432,44 @@ export function createAgentHarnessTool(deps: AgentHarnessToolDeps): Tool {
556
432
  shortcuts: totalHarnessShortcuts(deps.commandContext),
557
433
  keybindings: totalHarnessKeybindings(deps.commandContext),
558
434
  commands: deps.commandRegistry.list().length,
435
+ channelReadiness: channelReadinessCatalogStatus(deps.commandContext),
436
+ notificationTargets: notificationTargetCatalogStatus(deps.commandContext),
437
+ providerAccounts: await providerAccountCatalogStatus(deps.commandContext).catch((err) => ({
438
+ modes: ['provider_accounts', 'provider_account'],
439
+ status: 'unavailable',
440
+ error: formatHarnessError(err),
441
+ })),
442
+ mcpServers: mcpServerCatalogStatus(deps.commandContext),
443
+ setupPosture: await setupPostureCatalogStatus(deps.commandContext).catch((err) => ({
444
+ modes: ['setup_posture', 'setup_item'],
445
+ status: 'unavailable',
446
+ error: formatHarnessError(err),
447
+ })),
448
+ modelRouting: await modelRoutingCatalogStatus(deps.commandContext).catch((err) => ({
449
+ modes: ['model_routing', 'model_route'],
450
+ status: 'unavailable',
451
+ error: formatHarnessError(err),
452
+ })),
453
+ pairingPosture: pairingPostureCatalogStatus(deps.commandContext),
454
+ delegationPosture: delegationPostureCatalogStatus(deps.commandContext),
455
+ securityPosture: securityPostureCatalogStatus(deps.commandContext),
456
+ supportBundles: supportBundleCatalogStatus(),
457
+ mediaPosture: mediaPostureCatalogStatus(deps.commandContext),
458
+ sessions: sessionCatalogStatus(deps.commandContext),
559
459
  settings: deps.commandContext.platform.configManager.getSchema().length,
560
460
  workspaceCategories: AGENT_WORKSPACE_CATEGORIES.length,
561
461
  workspaceActions: allWorkspaceActions().length,
562
462
  tools: deps.toolRegistry.getToolDefinitions().length,
563
- modelAccess: {
564
- cliCommands: 'Use mode:"cli_commands" to list and mode:"cli_command" with cliCommand, command, commandName, target, or query to inspect package CLI mirrors and their preferred in-process model routes. CLI modes are discovery-only.',
565
- panels: 'Use mode:"panels" to list and mode:"panel" with panelId, target, or query to inspect built-in panel catalog/open state; use mode:"open_panel" with confirm:true plus explicitUserRequest to route a visible panel/workspace change.',
566
- uiSurfaces: 'Use mode:"ui_surfaces" to list and mode:"ui_surface" with surfaceId, target, or query to inspect modal/overlay/picker/workspace surfaces; use mode:"open_ui_surface" with confirm:true plus explicitUserRequest to route visible UI navigation.',
567
- shortcuts: 'Use mode:"shortcuts" to inspect fixed shortcuts plus configurable keybindings. Use mode:"keybinding" with actionId, target, key, or query; use mode:"run_keybinding" for confirmation-gated shell-safe shortcut equivalents; use mode:"set_keybinding" and mode:"reset_keybinding" with confirm:true plus explicitUserRequest to edit the same config file the user edits.',
568
- slashCommands: 'Use mode:"commands" to list slash commands and mode:"command" with command, commandName, target, or query to inspect one command; use mode:"run_command" with the same lookup fields plus confirm:true and explicitUserRequest to execute one uniquely resolved command.',
569
- workspace: 'Use mode:"workspace" or mode:"workspace_categories" to list Agent workspace categories, mode:"workspace_actions" to list actions, mode:"workspace_action" with actionId, command, target, or query for one action, editor schema, and modelExecution route metadata, and mode:"run_workspace_action" with the same lookup fields plus confirmation for executable actions; set includeParameters:true on workspace_actions to inline editor schemas.',
570
- settings: 'Use mode:"settings" with optional category, prefix, query, includeHidden:true, and limit to list/filter settings, and mode:"get_setting" with key, target, or query for one setting. Use mode:"set_setting" or mode:"reset_setting" with key, target, or query plus confirm:true and explicitUserRequest.',
571
- tools: 'Use mode:"tools" with optional query, limit, and includeParameters:true to list first-class model tools or inline schemas, or mode:"tool" with toolName, target, or query to inspect one schema.',
572
- connectedHost: 'Use mode:"connected_host" for the connected-host capability map and blocked boundaries. Use mode:"connected_host_capability" with capabilityId, target, or query for one allowed or blocked capability.',
573
- connectedHostStatus: 'Use mode:"connected_host_status" for live read-only host reachability, SDK compatibility, token posture, and Agent Knowledge route readiness.',
574
- },
463
+ releaseEvidence: releaseEvidenceBundleStatus(),
464
+ releaseReadiness: releaseReadinessInventoryStatus(),
465
+ operatorMethods: operatorMethodCatalogStatus(),
466
+ servicePosture: servicePostureCatalogStatus(),
467
+ modeGuide: compactHarnessModeGuide(),
468
+ ...(args.includeParameters === true ? { modelAccess: detailedHarnessModelAccessGuide() } : {}),
575
469
  settingsPolicy: settingsPolicySummary(),
576
- connectedHost: connectedHostSummary(deps.commandContext, deps.toolRegistry),
470
+ connectedHost: connectedHostSummary(deps.commandContext, deps.toolRegistry, {
471
+ includeParameters: args.includeParameters === true,
472
+ }),
577
473
  });
578
474
  }
579
475
  if (args.mode === 'cli_commands') {
@@ -650,6 +546,89 @@ export function createAgentHarnessTool(deps: AgentHarnessToolDeps): Tool {
650
546
  : error(`Unknown slash command ${query || '<missing>'}. Use mode:"commands" to inspect available commands.`);
651
547
  }
652
548
  if (args.mode === 'run_command') return runCommand(deps, args);
549
+ if (args.mode === 'channels') return output(listHarnessChannels(deps.commandContext, args));
550
+ if (args.mode === 'channel') {
551
+ const resolved = describeHarnessChannel(deps.commandContext, args);
552
+ if (resolved.status === 'found') return output(resolved.channel);
553
+ if (resolved.status === 'ambiguous') return error(`Ambiguous channel ${resolved.input}. Candidates: ${JSON.stringify(resolved.candidates)}`);
554
+ return error(resolved.usage);
555
+ }
556
+ if (args.mode === 'notifications') return output(listHarnessNotificationTargets(deps.commandContext, args));
557
+ if (args.mode === 'notification_target') {
558
+ const resolved = describeHarnessNotificationTarget(deps.commandContext, args);
559
+ if (resolved.status === 'found') return output(resolved.target);
560
+ if (resolved.status === 'ambiguous') return error(`Ambiguous notification target ${resolved.input}. Candidates: ${JSON.stringify(resolved.candidates)}`);
561
+ return error(resolved.usage);
562
+ }
563
+ if (args.mode === 'provider_accounts') return output(await providerAccountSummary(deps.commandContext, args));
564
+ if (args.mode === 'provider_account') {
565
+ const resolved = await describeHarnessProviderAccount(deps.commandContext, args);
566
+ if (resolved.status === 'found') return output(resolved.account);
567
+ if (resolved.status === 'ambiguous') return error(`Ambiguous provider account ${resolved.input}. Candidates: ${JSON.stringify(resolved.candidates)}`);
568
+ return error(resolved.usage);
569
+ }
570
+ if (args.mode === 'mcp_servers') return output(await mcpServerSummary(deps.commandContext, args));
571
+ if (args.mode === 'mcp_server') {
572
+ const resolved = await describeHarnessMcpServer(deps.commandContext, args);
573
+ if (resolved.status === 'found') return output(resolved.server);
574
+ if (resolved.status === 'ambiguous') return error(`Ambiguous MCP server ${resolved.input}. Candidates: ${JSON.stringify(resolved.candidates)}`);
575
+ return error(resolved.usage);
576
+ }
577
+ if (args.mode === 'setup_posture') return output(await setupPostureSummary(deps.commandContext, args));
578
+ if (args.mode === 'setup_item') {
579
+ const resolved = await describeHarnessSetupItem(deps.commandContext, args);
580
+ if (resolved.status === 'found') return output(resolved.item);
581
+ if (resolved.status === 'ambiguous') return error(`Ambiguous setup item ${resolved.input}. Candidates: ${JSON.stringify(resolved.candidates)}`);
582
+ return error(resolved.usage);
583
+ }
584
+ if (args.mode === 'model_routing') return output(await modelRoutingSummary(deps.commandContext, args));
585
+ if (args.mode === 'model_route') {
586
+ const resolved = await describeHarnessModelRoute(deps.commandContext, args);
587
+ if (resolved.status === 'found') return output(resolved.route);
588
+ if (resolved.status === 'ambiguous') return error(`Ambiguous model route ${resolved.input}. Candidates: ${JSON.stringify(resolved.candidates)}`);
589
+ return error(resolved.usage);
590
+ }
591
+ if (args.mode === 'pairing_posture') return output(pairingPostureSummary(deps.commandContext, args));
592
+ if (args.mode === 'pairing_route') {
593
+ const resolved = describeHarnessPairingRoute(deps.commandContext, args);
594
+ if (resolved.status === 'found') return output(resolved.route);
595
+ if (resolved.status === 'ambiguous') return error(`Ambiguous pairing route ${resolved.input}. Candidates: ${JSON.stringify(resolved.candidates)}`);
596
+ return error(resolved.usage);
597
+ }
598
+ if (args.mode === 'delegation_posture') return output(delegationPostureSummary(deps.commandContext, args));
599
+ if (args.mode === 'delegation_route') {
600
+ const resolved = describeHarnessDelegationRoute(deps.commandContext, args);
601
+ if (resolved.status === 'found') return output(resolved.route);
602
+ if (resolved.status === 'ambiguous') return error(`Ambiguous delegation route ${resolved.input}. Candidates: ${JSON.stringify(resolved.candidates)}`);
603
+ return error(resolved.usage);
604
+ }
605
+ if (args.mode === 'security_posture') return output(await securityPostureSummary(deps.commandContext, args));
606
+ if (args.mode === 'security_finding') {
607
+ const resolved = describeHarnessSecurityFinding(deps.commandContext, args);
608
+ if (resolved.status === 'found') return output(resolved.finding);
609
+ if (resolved.status === 'ambiguous') return error(`Ambiguous security finding ${resolved.input}. Candidates: ${JSON.stringify(resolved.candidates)}`);
610
+ return error(resolved.usage);
611
+ }
612
+ if (args.mode === 'support_bundles') return output(supportBundleSummary(args));
613
+ if (args.mode === 'support_bundle') {
614
+ const resolved = describeHarnessSupportBundle(deps.commandContext, args);
615
+ if (resolved.status === 'found') return output(resolved.bundle);
616
+ return error(resolved.usage);
617
+ }
618
+ if (args.mode === 'media_posture') return output(await mediaPostureSummary(deps.commandContext, args));
619
+ if (args.mode === 'media_provider') {
620
+ const resolved = await describeHarnessMediaProvider(deps.commandContext, args);
621
+ if (resolved.status === 'found') return output(resolved.provider);
622
+ if (resolved.status === 'ambiguous') return error(`Ambiguous media provider ${resolved.input}. Candidates: ${JSON.stringify(resolved.candidates)}`);
623
+ return error(resolved.usage);
624
+ }
625
+ if (args.mode === 'sessions') return output(sessionSummary(deps.commandContext, args));
626
+ if (args.mode === 'session') {
627
+ const resolved = describeHarnessSession(deps.commandContext, args);
628
+ if (resolved.status === 'found') return output(resolved.session);
629
+ if (resolved.status === 'ambiguous') return error(`Ambiguous session ${resolved.input}. Candidates: ${JSON.stringify(resolved.candidates)}`);
630
+ return error(resolved.usage);
631
+ }
653
632
  if (args.mode === 'settings') {
654
633
  const settings = listHarnessSettings(deps.commandContext.platform.configManager, {
655
634
  category: readString(args.category) || undefined,
@@ -657,6 +636,8 @@ export function createAgentHarnessTool(deps: AgentHarnessToolDeps): Tool {
657
636
  query: readString(args.query) || undefined,
658
637
  includeHidden: args.includeHidden === true,
659
638
  limit: readLimit(args.limit, 100),
639
+ }, {
640
+ includeParameters: args.includeParameters === true,
660
641
  });
661
642
  return output({ settings, returned: settings.length, policy: settingsPolicySummary() });
662
643
  }
@@ -711,7 +692,7 @@ export function createAgentHarnessTool(deps: AgentHarnessToolDeps): Tool {
711
692
  });
712
693
  }
713
694
  if (args.mode === 'workspace_actions') {
714
- const actions = listWorkspaceActions(deps, args);
695
+ const actions = listWorkspaceActions(deps.commandContext, args);
715
696
  return output({ actions, returned: actions.length, total: allWorkspaceActions().length });
716
697
  }
717
698
  if (args.mode === 'workspace_action') {
@@ -737,7 +718,42 @@ export function createAgentHarnessTool(deps: AgentHarnessToolDeps): Tool {
737
718
  if (resolved?.status === 'ambiguous') return error(`Ambiguous model tool ${resolved.input}. Candidates: ${JSON.stringify(resolved.candidates)}`);
738
719
  return error(`Unknown model tool ${query || '<missing>'}. Use mode:"tools" to inspect available model tools.`);
739
720
  }
740
- if (args.mode === 'connected_host') return output(connectedHostSummary(deps.commandContext, deps.toolRegistry));
721
+ if (args.mode === 'release_evidence') return output(releaseEvidenceSummary(args));
722
+ if (args.mode === 'release_evidence_artifact') {
723
+ const resolved = describeHarnessReleaseEvidenceArtifact(args);
724
+ if (resolved.status === 'found') return output(resolved);
725
+ if (resolved.status === 'ambiguous') return error(`Ambiguous release evidence artifact ${resolved.input}. Candidates: ${JSON.stringify(resolved.candidates)}`);
726
+ if (resolved.status === 'missing_lookup') return error(resolved.usage ?? 'release_evidence_artifact requires artifactId, target, or query.');
727
+ return error(`Unknown release evidence artifact ${readString(args.artifactId || args.target || args.query) || '<missing>'}. Use mode:"release_evidence" to inspect available artifacts.`);
728
+ }
729
+ if (args.mode === 'release_readiness') return output(releaseReadinessSummary(args));
730
+ if (args.mode === 'release_readiness_item') {
731
+ const resolved = describeHarnessReleaseReadinessItem(args);
732
+ if (resolved.status === 'found') return output(resolved);
733
+ if (resolved.status === 'ambiguous') return error(`Ambiguous release readiness item ${resolved.input}. Candidates: ${JSON.stringify(resolved.candidates)}`);
734
+ if (resolved.status === 'unavailable') return output(resolved);
735
+ if (resolved.status === 'missing_lookup') return error(resolved.usage ?? 'release_readiness_item requires itemId, target, or query.');
736
+ return error(`Unknown release readiness item ${readString(args.itemId || args.target || args.query) || '<missing>'}. Use mode:"release_readiness" to inspect available items.`);
737
+ }
738
+ if (args.mode === 'operator_methods') return output(operatorMethodSummary(args));
739
+ if (args.mode === 'operator_method') {
740
+ const resolved = describeHarnessOperatorMethod(args);
741
+ if (resolved.status === 'found') return output(resolved.method);
742
+ if (resolved.status === 'ambiguous') return error(`Ambiguous operator method ${resolved.input}. Candidates: ${JSON.stringify(resolved.candidates)}`);
743
+ return error(resolved.usage);
744
+ }
745
+ if (args.mode === 'service_posture') return output(await servicePostureSummary(deps.commandContext, args));
746
+ if (args.mode === 'service_endpoint') {
747
+ const resolved = await describeHarnessServiceEndpoint(deps.commandContext, args);
748
+ if (resolved.status === 'found') return output(resolved.endpoint);
749
+ if (resolved.status === 'ambiguous') return error(`Ambiguous service endpoint ${resolved.input}. Candidates: ${JSON.stringify(resolved.candidates)}`);
750
+ return error(resolved.usage);
751
+ }
752
+ if (args.mode === 'connected_host' || args.mode === 'daemon') {
753
+ return output(connectedHostSummary(deps.commandContext, deps.toolRegistry, {
754
+ includeParameters: args.includeParameters === true,
755
+ }));
756
+ }
741
757
  if (args.mode === 'connected_host_capability') {
742
758
  const query = readString(args.capabilityId || args.target || args.query);
743
759
  const resolved = describeConnectedHostCapability(deps.toolRegistry, query);
@@ -745,7 +761,11 @@ export function createAgentHarnessTool(deps: AgentHarnessToolDeps): Tool {
745
761
  if (resolved?.status === 'ambiguous') return error(`Ambiguous connected-host capability ${resolved.input}. Candidates: ${JSON.stringify(resolved.candidates)}`);
746
762
  return error(`Unknown connected-host capability ${query || '<missing>'}. Use mode:"connected_host" to inspect allowed and blocked capability ids.`);
747
763
  }
748
- if (args.mode === 'connected_host_status') return output(await connectedHostStatusSummary(deps.commandContext, deps.toolRegistry));
764
+ if (args.mode === 'connected_host_status' || args.mode === 'daemon_status') {
765
+ return output(await connectedHostStatusSummary(deps.commandContext, deps.toolRegistry, {
766
+ includeParameters: args.includeParameters === true,
767
+ }));
768
+ }
749
769
  return error(`Unhandled agent_harness mode: ${args.mode}`);
750
770
  } catch (err) {
751
771
  return error(formatHarnessError(err));
@@ -759,9 +779,5 @@ export function registerAgentHarnessTool(
759
779
  commandRegistry: CommandRegistry,
760
780
  commandContext: CommandContext,
761
781
  ): void {
762
- registry.register(createAgentHarnessTool({
763
- commandRegistry,
764
- commandContext,
765
- toolRegistry: registry,
766
- }));
782
+ registry.register(createAgentHarnessTool({ commandRegistry, commandContext, toolRegistry: registry }));
767
783
  }