@pellux/goodvibes-agent 1.0.33 → 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 (57) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +71 -59
  3. package/dist/package/main.js +565 -420
  4. package/docs/README.md +25 -21
  5. package/docs/channels-remote-and-api.md +2 -2
  6. package/docs/connected-host.md +3 -3
  7. package/docs/getting-started.md +87 -86
  8. package/docs/providers-and-routing.md +3 -3
  9. package/docs/release-and-publishing.md +3 -3
  10. package/docs/tools-and-commands.md +149 -139
  11. package/docs/voice-and-live-tts.md +1 -1
  12. package/package.json +1 -1
  13. package/release/live-verification/live-verification.json +2 -2
  14. package/release/live-verification/live-verification.md +2 -2
  15. package/release/release-notes.md +6 -15
  16. package/release/release-readiness.json +4 -4
  17. package/src/agent/harness-control.ts +42 -3
  18. package/src/runtime/bootstrap.ts +10 -18
  19. package/src/tools/agent-analysis-registry-policy.ts +2 -9
  20. package/src/tools/agent-channel-send-tool.ts +1 -5
  21. package/src/tools/agent-context-policy.ts +1 -5
  22. package/src/tools/agent-find-policy.ts +1 -4
  23. package/src/tools/agent-harness-channel-metadata.ts +23 -23
  24. package/src/tools/agent-harness-cli-metadata.ts +4 -1
  25. package/src/tools/agent-harness-command-catalog.ts +10 -3
  26. package/src/tools/agent-harness-connected-host-status.ts +8 -2
  27. package/src/tools/agent-harness-delegation-posture.ts +5 -5
  28. package/src/tools/agent-harness-mcp-metadata.ts +30 -28
  29. package/src/tools/agent-harness-media-posture.ts +9 -9
  30. package/src/tools/agent-harness-metadata.ts +25 -7
  31. package/src/tools/agent-harness-model-routing.ts +14 -14
  32. package/src/tools/agent-harness-model-tool-catalog.ts +7 -2
  33. package/src/tools/agent-harness-notification-metadata.ts +17 -17
  34. package/src/tools/agent-harness-pairing-posture.ts +7 -7
  35. package/src/tools/agent-harness-panel-metadata.ts +26 -12
  36. package/src/tools/agent-harness-provider-account-metadata.ts +33 -31
  37. package/src/tools/agent-harness-security-posture.ts +9 -7
  38. package/src/tools/agent-harness-service-posture.ts +22 -16
  39. package/src/tools/agent-harness-session-metadata.ts +9 -7
  40. package/src/tools/agent-harness-setup-posture.ts +6 -6
  41. package/src/tools/agent-harness-tool-schema.ts +1 -0
  42. package/src/tools/agent-harness-tool.ts +79 -36
  43. package/src/tools/agent-harness-ui-surface-metadata.ts +19 -11
  44. package/src/tools/agent-harness-workspace-actions.ts +29 -1
  45. package/src/tools/agent-knowledge-ingest-tool.ts +1 -5
  46. package/src/tools/agent-knowledge-tool.ts +1 -5
  47. package/src/tools/agent-local-registry-tool.ts +1 -4
  48. package/src/tools/agent-media-generate-tool.ts +1 -5
  49. package/src/tools/agent-notify-tool.ts +1 -5
  50. package/src/tools/agent-operator-action-tool.ts +1 -5
  51. package/src/tools/agent-operator-briefing-tool.ts +1 -5
  52. package/src/tools/agent-read-policy.ts +1 -4
  53. package/src/tools/agent-reminder-schedule-tool.ts +1 -5
  54. package/src/tools/agent-tool-policy-guard.ts +7 -34
  55. package/src/tools/agent-web-search-policy.ts +1 -4
  56. package/src/tools/agent-work-plan-tool.ts +1 -5
  57. package/src/version.ts +1 -1
@@ -132,25 +132,25 @@ function describeTarget(
132
132
  ...(target.hasQuery !== undefined ? { hasQuery: target.hasQuery } : {}),
133
133
  value: '<redacted>',
134
134
  ...(options.lookup ? { lookup: options.lookup } : {}),
135
- policy: {
136
- effect: 'read-only',
137
- values: 'Full webhook URLs are not returned because they can contain bearer tokens or secret path/query values.',
138
- delivery: 'Use agent_notify only for one explicit, confirmed notification requested by the user.',
139
- management: 'Use confirmed /notify mirrors only when the user explicitly asks to add, remove, clear, test, or send notification targets.',
140
- },
141
- modelAccess: {
142
- sendTool: 'agent_notify',
143
- listCommand: '/notify list',
144
- addCommand: '/notify add <url> --yes',
145
- removeCommand: '/notify remove <url> --yes',
146
- clearCommand: '/notify clear --yes',
147
- testCommand: '/notify test --yes',
148
- settingsCategory: 'notifications.webhookUrls',
149
- ...(options.includeParameters ? {
135
+ ...(options.includeParameters ? {
136
+ policy: {
137
+ effect: 'read-only',
138
+ values: 'Full webhook URLs are not returned because they can contain bearer tokens or secret path/query values.',
139
+ delivery: 'Use agent_notify only for one explicit, confirmed notification requested by the user.',
140
+ management: 'Use confirmed /notify mirrors only when the user explicitly asks to add, remove, clear, test, or send notification targets.',
141
+ },
142
+ modelAccess: {
143
+ sendTool: 'agent_notify',
144
+ listCommand: '/notify list',
145
+ addCommand: '/notify add <url> --yes',
146
+ removeCommand: '/notify remove <url> --yes',
147
+ clearCommand: '/notify clear --yes',
148
+ testCommand: '/notify test --yes',
149
+ settingsCategory: 'notifications.webhookUrls',
150
150
  targetValueRequiredForRemove: true,
151
151
  targetValuePolicy: 'Ask the user for the exact webhook URL before removing one target; do not infer it from redacted metadata.',
152
- } : {}),
153
- },
152
+ },
153
+ } : {}),
154
154
  };
155
155
  }
156
156
 
@@ -77,7 +77,7 @@ function pairingRoutes(): readonly PairingRoute[] {
77
77
  detail: 'Visible companion pairing route that prints QR setup details in the Agent TUI without printing the raw token.',
78
78
  effect: 'external-network',
79
79
  command: '/pair',
80
- harnessRoute: 'agent_harness mode:"run_command" command:"/pair" confirm:true',
80
+ harnessRoute: 'agent_harness mode:"run_command" command:"/pair" confirm:true explicitUserRequest:"..."',
81
81
  requiresConfirmation: true,
82
82
  },
83
83
  {
@@ -86,7 +86,7 @@ function pairingRoutes(): readonly PairingRoute[] {
86
86
  detail: 'Explicitly confirmed fallback route that prints the raw companion token only when the user asks for manual setup.',
87
87
  effect: 'confirmation-gated-secret-display',
88
88
  command: '/pair --show-token --yes',
89
- harnessRoute: 'agent_harness mode:"run_command" command:"/pair --show-token --yes" confirm:true',
89
+ harnessRoute: 'agent_harness mode:"run_command" command:"/pair --show-token --yes" confirm:true explicitUserRequest:"..."',
90
90
  requiresConfirmation: true,
91
91
  },
92
92
  {
@@ -166,12 +166,12 @@ function describeRoute(route: PairingRoute, options: { readonly includeParameter
166
166
  ...(route.capabilityIds ? { capabilityIds: route.capabilityIds } : {}),
167
167
  requiresConfirmation: route.requiresConfirmation === true,
168
168
  ...(options.lookup ? { lookup: options.lookup } : {}),
169
- policy: {
170
- effect: route.effect,
171
- values: 'Pairing posture returns endpoint binding and token fingerprint only; raw companion tokens and QR payloads are never returned by this read-only mode.',
172
- mutation: 'Pairing display, manual token display, companion connection, channel sends, provider/model changes, approval actions, and attachment flows stay explicit visible user flows.',
173
- },
174
169
  ...(options.includeParameters ? {
170
+ policy: {
171
+ effect: route.effect,
172
+ values: 'Pairing posture returns endpoint binding and token fingerprint only; raw companion tokens and QR payloads are never returned by this read-only mode.',
173
+ mutation: 'Pairing display, manual token display, companion connection, channel sends, provider/model changes, approval actions, and attachment flows stay explicit visible user flows.',
174
+ },
175
175
  modelAccess: {
176
176
  inspectPairing: 'agent_harness mode:"pairing_posture"',
177
177
  inspectRoute: 'agent_harness mode:"pairing_route"',
@@ -7,6 +7,7 @@ export interface AgentHarnessPanelArgs {
7
7
  readonly panelId?: unknown;
8
8
  readonly target?: unknown;
9
9
  readonly category?: unknown;
10
+ readonly includeParameters?: unknown;
10
11
  readonly limit?: unknown;
11
12
  readonly pane?: unknown;
12
13
  }
@@ -39,6 +40,11 @@ function readLimit(value: unknown, fallback: number): number {
39
40
  return Math.max(1, Math.min(500, Math.trunc(parsed)));
40
41
  }
41
42
 
43
+ function previewText(value: string, maxLength = 120): string {
44
+ const normalized = value.replace(/\s+/g, ' ').trim();
45
+ return normalized.length <= maxLength ? normalized : `${normalized.slice(0, maxLength - 1).trimEnd()}...`;
46
+ }
47
+
42
48
  function panelManager(context: CommandContext) {
43
49
  return context.workspace.panelManager ?? null;
44
50
  }
@@ -50,6 +56,7 @@ function panelMatches(panel: Record<string, unknown>, query: string): boolean {
50
56
  panel.name,
51
57
  panel.category,
52
58
  panel.description,
59
+ panel.summary,
53
60
  panel.workspaceRoute,
54
61
  ].map((value) => typeof value === 'object' ? JSON.stringify(value) : String(value ?? '')).join('\n').toLowerCase().includes(query.toLowerCase());
55
62
  }
@@ -69,7 +76,7 @@ function panelCandidate(registration: PanelRegistration): Record<string, unknown
69
76
  id: registration.id,
70
77
  name: registration.name,
71
78
  category: registration.category,
72
- description: registration.description,
79
+ summary: previewText(registration.description),
73
80
  workspaceRoute: {
74
81
  categoryId: agentWorkspaceCategoryForPanel(registration.id),
75
82
  command: agentWorkspaceCommandForPanel(registration.id),
@@ -103,7 +110,11 @@ function resolveHarnessPanel(context: CommandContext, args: AgentHarnessPanelArg
103
110
  return null;
104
111
  }
105
112
 
106
- function describePanelRegistration(context: CommandContext, registration: PanelRegistration, lookup?: PanelLookup): Record<string, unknown> {
113
+ function describePanelRegistration(
114
+ context: CommandContext,
115
+ registration: PanelRegistration,
116
+ options: { readonly includeParameters?: boolean; readonly lookup?: PanelLookup } = {},
117
+ ): Record<string, unknown> {
107
118
  const manager = panelManager(context);
108
119
  const openPanel = manager?.getPanel(registration.id) ?? null;
109
120
  const pane = manager?.getPaneOf(registration.id) ?? null;
@@ -113,8 +124,8 @@ function describePanelRegistration(context: CommandContext, registration: PanelR
113
124
  name: registration.name,
114
125
  icon: registration.icon,
115
126
  category: registration.category,
116
- description: registration.description,
117
- ...(lookup ? { lookup } : {}),
127
+ ...(options.includeParameters ? { description: registration.description } : { summary: previewText(registration.description) }),
128
+ ...(options.lookup ? { lookup: options.lookup } : {}),
118
129
  preload: registration.preload === true,
119
130
  open: openPanel !== null,
120
131
  pane,
@@ -124,11 +135,13 @@ function describePanelRegistration(context: CommandContext, registration: PanelR
124
135
  categoryId: agentWorkspaceCategoryForPanel(registration.id),
125
136
  command: agentWorkspaceCommandForPanel(registration.id),
126
137
  },
127
- policy: {
128
- effect: 'ui-navigation',
129
- confirmation: 'agent_harness mode:"open_panel" requires confirm:true and explicitUserRequest.',
130
- boundary: 'Panels are Agent/TUI operator views. The model can inspect panel catalog/open state; panel routing uses the existing Agent workspace bridge and does not mutate connected-host lifecycle.',
131
- },
138
+ ...(options.includeParameters ? {
139
+ policy: {
140
+ effect: 'ui-navigation',
141
+ confirmation: 'agent_harness mode:"open_panel" requires confirm:true and explicitUserRequest.',
142
+ boundary: 'Panels are Agent/TUI operator views. The model can inspect panel catalog/open state; panel routing uses the existing Agent workspace bridge and does not mutate connected-host lifecycle.',
143
+ },
144
+ } : {}),
132
145
  };
133
146
  }
134
147
 
@@ -142,8 +155,9 @@ export function listHarnessPanels(context: CommandContext, args: AgentHarnessPan
142
155
  const query = readString(args.query);
143
156
  const category = readString(args.category);
144
157
  const limit = readLimit(args.limit, 200);
158
+ const includeParameters = args.includeParameters === true;
145
159
  return manager.getRegisteredTypes()
146
- .map((registration) => describePanelRegistration(context, registration))
160
+ .map((registration) => describePanelRegistration(context, registration, { includeParameters }))
147
161
  .filter((panel) => !category || panel.category === category)
148
162
  .filter((panel) => panelMatches(panel, query))
149
163
  .sort((a, b) => String(a.id).localeCompare(String(b.id)))
@@ -152,7 +166,7 @@ export function listHarnessPanels(context: CommandContext, args: AgentHarnessPan
152
166
 
153
167
  export function describeHarnessPanel(context: CommandContext, args: AgentHarnessPanelArgs): Record<string, unknown> | null {
154
168
  const resolved = resolveHarnessPanel(context, args);
155
- if (resolved?.status === 'found') return describePanelRegistration(context, resolved.registration, resolved.lookup);
169
+ if (resolved?.status === 'found') return describePanelRegistration(context, resolved.registration, { includeParameters: true, lookup: resolved.lookup });
156
170
  if (resolved?.status === 'ambiguous') {
157
171
  return { status: 'ambiguous', input: resolved.input, candidates: resolved.candidates };
158
172
  }
@@ -171,7 +185,7 @@ export function openHarnessPanel(context: CommandContext, args: AgentHarnessPane
171
185
  availablePanels: listHarnessPanels(context, { limit: 50 }).map((entry) => entry.id),
172
186
  };
173
187
  }
174
- const panel = describePanelRegistration(context, resolved.registration, resolved.lookup);
188
+ const panel = describePanelRegistration(context, resolved.registration, { includeParameters: true, lookup: resolved.lookup });
175
189
  const requestedPane = readString(args.pane);
176
190
  const pane = requestedPane === 'bottom' || requestedPane === 'top' ? requestedPane : undefined;
177
191
  if (!context.showPanel) {
@@ -97,42 +97,44 @@ function describeAccount(
97
97
  ...(account.fallbackRisk ? { fallbackRisk: account.fallbackRisk } : {}),
98
98
  ...(account.expiresAt ? { expiresAt: new Date(account.expiresAt).toISOString() } : {}),
99
99
  ...(account.tokenType ? { tokenType: account.tokenType } : {}),
100
- routeRecords: account.routeRecords.map((route) => ({
101
- route: route.route,
102
- usable: route.usable,
103
- freshness: route.freshness,
104
- detail: route.detail,
105
- issues: route.issues,
106
- })),
107
- usageWindows: account.usageWindows,
108
- issues: account.issues,
109
- notes: account.notes,
110
- recommendedActions: account.recommendedActions,
100
+ issueCount: account.issues.length,
101
+ recommendedActionCount: account.recommendedActions.length,
111
102
  ...(options.lookup ? { lookup: options.lookup } : {}),
112
- policy: {
113
- effect: 'read-only',
114
- values: 'Provider account posture reports route and freshness metadata only; raw tokens, authorization codes, and secret values are never returned.',
115
- mutation: 'Provider login, logout, subscription bundle export, and account repair actions stay explicit confirmation-gated workspace or slash-command flows.',
116
- },
117
- modelAccess: {
118
- reviewCommand: '/accounts review',
119
- showCommand: `/accounts show ${account.providerId}`,
120
- routesCommand: `/accounts routes ${account.providerId}`,
121
- repairCommand: `/accounts repair ${account.providerId}`,
122
- subscriptionInspectCommand: `/subscription inspect ${account.providerId}`,
123
- workspaceActions: [
124
- 'provider-accounts',
125
- 'provider-account-repair',
126
- 'subscription-review',
127
- 'subscription-inspect',
128
- ],
129
- ...(options.includeParameters ? {
103
+ ...(options.includeParameters ? {
104
+ routeRecords: account.routeRecords.map((route) => ({
105
+ route: route.route,
106
+ usable: route.usable,
107
+ freshness: route.freshness,
108
+ detail: route.detail,
109
+ issues: route.issues,
110
+ })),
111
+ usageWindows: account.usageWindows,
112
+ issues: account.issues,
113
+ notes: account.notes,
114
+ recommendedActions: account.recommendedActions,
115
+ policy: {
116
+ effect: 'read-only',
117
+ values: 'Provider account posture reports route and freshness metadata only; raw tokens, authorization codes, and secret values are never returned.',
118
+ mutation: 'Provider login, logout, subscription bundle export, and account repair actions stay explicit confirmation-gated workspace or slash-command flows.',
119
+ },
120
+ modelAccess: {
121
+ reviewCommand: '/accounts review',
122
+ showCommand: `/accounts show ${account.providerId}`,
123
+ routesCommand: `/accounts routes ${account.providerId}`,
124
+ repairCommand: `/accounts repair ${account.providerId}`,
125
+ subscriptionInspectCommand: `/subscription inspect ${account.providerId}`,
126
+ workspaceActions: [
127
+ 'provider-accounts',
128
+ 'provider-account-repair',
129
+ 'subscription-review',
130
+ 'subscription-inspect',
131
+ ],
130
132
  loginStartCommand: `/subscription login ${account.providerId} start --yes`,
131
133
  loginFinishCommand: `/subscription login ${account.providerId} finish <code-or-url> --yes`,
132
134
  logoutCommand: `/subscription logout ${account.providerId} --yes`,
133
135
  confirmationRequired: true,
134
- } : {}),
135
- },
136
+ },
137
+ } : {}),
136
138
  };
137
139
  }
138
140
 
@@ -166,11 +166,13 @@ function describeFinding(finding: SecurityFinding, includeParameters: boolean, l
166
166
  route: finding.route,
167
167
  ...(lookup ? { lookup } : {}),
168
168
  ...(includeParameters && finding.detail ? { detail: finding.detail } : {}),
169
- policy: {
170
- effect: 'read-only',
171
- values: 'Security posture returns counts, labels, policy ids, route names, and redacted bundle summaries only; token values, secret values, and raw config values are never returned.',
172
- mutation: 'Token rotation, policy changes, MCP trust changes, bundle export/import, auth repair, and voice enable/disable stay explicit confirmation-gated workspace or slash-command flows.',
173
- },
169
+ ...(includeParameters ? {
170
+ policy: {
171
+ effect: 'read-only',
172
+ values: 'Security posture returns counts, labels, policy ids, route names, and redacted bundle summaries only; token values, secret values, and raw config values are never returned.',
173
+ mutation: 'Token rotation, policy changes, MCP trust changes, bundle export/import, auth repair, and voice enable/disable stay explicit confirmation-gated workspace or slash-command flows.',
174
+ },
175
+ } : {}),
174
176
  };
175
177
  }
176
178
 
@@ -463,7 +465,7 @@ export async function securityPostureSummary(context: CommandContext, args: Agen
463
465
  returned: filtered.length,
464
466
  total: findings.length,
465
467
  policy: 'Read-only security posture. Token rotation, policy changes, MCP trust changes, bundle export/import, auth repair, and voice enable/disable remain confirmation-gated workspace or slash-command flows.',
466
- modelAccess: {
468
+ ...(args.includeParameters === true ? { modelAccess: {
467
469
  reviewCommand: '/security review',
468
470
  tokensCommand: '/security tokens',
469
471
  attackPathsCommand: '/security attack-paths',
@@ -471,7 +473,7 @@ export async function securityPostureSummary(context: CommandContext, args: Agen
471
473
  authReviewCommand: '/auth review',
472
474
  bundleCatalogMode: 'support_bundles',
473
475
  singleFindingMode: 'security_finding',
474
- },
476
+ } } : {}),
475
477
  };
476
478
  }
477
479
 
@@ -65,7 +65,10 @@ function summarizeLog(posture: CliServicePosture, includeTail: boolean): Record<
65
65
  };
66
66
  }
67
67
 
68
- function describeEndpoint(endpoint: CliServiceEndpointPosture, lookup?: Record<string, unknown>): Record<string, unknown> {
68
+ function describeEndpoint(
69
+ endpoint: CliServiceEndpointPosture,
70
+ options: { readonly includeParameters?: boolean; readonly lookup?: Record<string, unknown> } = {},
71
+ ): Record<string, unknown> {
69
72
  return {
70
73
  id: endpoint.id,
71
74
  label: endpoint.label,
@@ -74,13 +77,15 @@ function describeEndpoint(endpoint: CliServiceEndpointPosture, lookup?: Record<s
74
77
  bindPosture: endpoint.bindPosture,
75
78
  networkFacing: endpoint.networkFacing,
76
79
  ...(endpoint.reachable !== undefined ? { reachable: endpoint.reachable } : {}),
77
- ...(lookup ? { lookup } : {}),
78
- policy: {
79
- effect: 'read-only',
80
- modelOperation: 'Inspect endpoint binding, network-facing posture, and optional reachability only.',
81
- lifecycle: 'GoodVibes Agent does not start, stop, restart, install, expose, or mutate connected-host listeners.',
82
- settings: 'Use agent_harness settings/get_setting for read-only inspection of endpoint settings; connected-host lifecycle/listener settings stay locked in Agent.',
83
- },
80
+ ...(options.lookup ? { lookup: options.lookup } : {}),
81
+ ...(options.includeParameters ? {
82
+ policy: {
83
+ effect: 'read-only',
84
+ modelOperation: 'Inspect endpoint binding, network-facing posture, and optional reachability only.',
85
+ lifecycle: 'GoodVibes Agent does not start, stop, restart, install, expose, or mutate connected-host listeners.',
86
+ settings: 'Use agent_harness settings/get_setting for read-only inspection of endpoint settings; connected-host lifecycle/listener settings stay locked in Agent.',
87
+ },
88
+ } : {}),
84
89
  };
85
90
  }
86
91
 
@@ -118,6 +123,7 @@ function endpointSearchText(endpoint: CliServiceEndpointPosture): string {
118
123
  function resolveEndpoint(
119
124
  posture: CliServicePosture,
120
125
  args: AgentHarnessServicePostureArgs,
126
+ options: { readonly includeParameters?: boolean } = {},
121
127
  ): ServiceEndpointResolution {
122
128
  const lookup = endpointLookupFromArgs(args);
123
129
  if (!lookup) {
@@ -130,19 +136,19 @@ function resolveEndpoint(
130
136
  const normalized = lookup.input.toLowerCase();
131
137
  const exact = endpoints.find((endpoint) => endpoint.id === lookup.input);
132
138
  if (exact) {
133
- return { status: 'found', endpoint: describeEndpoint(exact, { ...lookup, resolvedBy: 'id' }) };
139
+ return { status: 'found', endpoint: describeEndpoint(exact, { includeParameters: options.includeParameters, lookup: { ...lookup, resolvedBy: 'id' } }) };
134
140
  }
135
141
  const insensitive = endpoints.find((endpoint) => endpoint.id.toLowerCase() === normalized);
136
142
  if (insensitive) {
137
- return { status: 'found', endpoint: describeEndpoint(insensitive, { ...lookup, resolvedBy: 'case-insensitive-id' }) };
143
+ return { status: 'found', endpoint: describeEndpoint(insensitive, { includeParameters: options.includeParameters, lookup: { ...lookup, resolvedBy: 'case-insensitive-id' } }) };
138
144
  }
139
145
  const label = endpoints.find((endpoint) => endpoint.label.toLowerCase() === normalized);
140
146
  if (label) {
141
- return { status: 'found', endpoint: describeEndpoint(label, { ...lookup, resolvedBy: 'label' }) };
147
+ return { status: 'found', endpoint: describeEndpoint(label, { includeParameters: options.includeParameters, lookup: { ...lookup, resolvedBy: 'label' } }) };
142
148
  }
143
149
  const searched = endpoints.filter((endpoint) => endpointSearchText(endpoint).includes(normalized));
144
150
  if (searched.length === 1) {
145
- return { status: 'found', endpoint: describeEndpoint(searched[0]!, { ...lookup, resolvedBy: 'search' }) };
151
+ return { status: 'found', endpoint: describeEndpoint(searched[0]!, { includeParameters: options.includeParameters, lookup: { ...lookup, resolvedBy: 'search' } }) };
146
152
  }
147
153
  if (searched.length > 1) {
148
154
  return {
@@ -178,14 +184,14 @@ export async function servicePostureSummary(
178
184
  lifecycle: 'GoodVibes Agent reports connected-host/service posture but does not start, stop, restart, install, expose, or mutate host listeners.',
179
185
  config: posture.config,
180
186
  managed: posture.managed,
181
- endpoints: posture.endpoints.map((endpoint) => describeEndpoint(endpoint)),
187
+ endpoints: posture.endpoints.map((endpoint) => describeEndpoint(endpoint, { includeParameters: includeDetails })),
182
188
  log: summarizeLog(posture, includeDetails),
183
189
  issues: posture.issues,
184
- modelAccess: {
190
+ ...(includeDetails ? { modelAccess: {
185
191
  endpointLookup: 'Use mode:"service_endpoint" with endpointId, target, or query to inspect one endpoint.',
186
192
  settings: 'Use mode:"settings" with includeHidden:true for endpoint setting descriptors. Host-owned listener settings remain read-only.',
187
193
  liveHostStatus: 'Use mode:"connected_host_status" for SDK compatibility, token posture, and Agent Knowledge route readiness.',
188
- },
194
+ } } : {}),
189
195
  };
190
196
  }
191
197
 
@@ -197,5 +203,5 @@ export async function describeHarnessServiceEndpoint(
197
203
  ...servicePostureOptions(args),
198
204
  probe: true,
199
205
  });
200
- return resolveEndpoint(posture, args);
206
+ return resolveEndpoint(posture, args, { includeParameters: true });
201
207
  }
@@ -129,11 +129,13 @@ function describeSession(
129
129
  },
130
130
  } : {}),
131
131
  ...(options.lookup ? { lookup: options.lookup } : {}),
132
- policy: {
133
- effect: 'read-only',
134
- values: 'Session posture returns saved-session metadata, search counts, optional snippets, return-context counts, bookmark counts, and saved bookmark file counts.',
135
- mutation: 'Session save, rename, fork, resume, export, delete, bookmark toggles, and bookmark file writes remain visible workspace or slash-command flows with confirmation where mutating.',
136
- },
132
+ ...(options.includeParameters ? {
133
+ policy: {
134
+ effect: 'read-only',
135
+ values: 'Session posture returns saved-session metadata, search counts, optional snippets, return-context counts, bookmark counts, and saved bookmark file counts.',
136
+ mutation: 'Session save, rename, fork, resume, export, delete, bookmark toggles, and bookmark file writes remain visible workspace or slash-command flows with confirmation where mutating.',
137
+ },
138
+ } : {}),
137
139
  };
138
140
  }
139
141
 
@@ -176,9 +178,9 @@ function bookmarkSummary(context: CommandContext): Record<string, unknown> {
176
178
  bookmarks: manager.list().length,
177
179
  savedFiles: manager.listSavedFiles().length,
178
180
  modelRoutes: {
179
- visibleBookmarkPicker: 'agent_harness open_ui_surface surfaceId:"bookmarks"',
181
+ visibleBookmarkPicker: 'agent_harness mode:"open_ui_surface" surfaceId:"bookmarks" confirm:true explicitUserRequest:"..."',
180
182
  command: '/bookmarks',
181
- importIntoKnowledge: 'agent_knowledge_ingest sourceKind:"bookmarks_file" with confirm:true',
183
+ importIntoKnowledge: 'agent_knowledge_ingest sourceKind:"bookmarks_file" confirm:true explicitUserRequest:"..."',
182
184
  },
183
185
  };
184
186
  }
@@ -178,16 +178,16 @@ function describeItem(
178
178
  detail: item.detail,
179
179
  signals: signalsForItem(item, snapshot),
180
180
  ...(options.lookup ? { lookup: options.lookup } : {}),
181
- policy: {
182
- effect: 'read-only',
183
- values: 'Setup posture returns onboarding readiness, counts, safe setting keys, and route metadata only; secret values and raw provider tokens are never returned.',
184
- mutation: 'Setup apply, provider auth, local behavior import/create, channel delivery, and starter profile changes stay visible workspace, settings, slash-command, or first-class tool flows.',
185
- },
186
181
  ...(options.includeParameters ? {
182
+ policy: {
183
+ effect: 'read-only',
184
+ values: 'Setup posture returns onboarding readiness, counts, safe setting keys, and route metadata only; secret values and raw provider tokens are never returned.',
185
+ mutation: 'Setup apply, provider auth, local behavior import/create, channel delivery, and starter profile changes stay visible workspace, settings, slash-command, or first-class tool flows.',
186
+ },
187
187
  modelAccess: {
188
188
  inspectSetup: 'agent_harness mode:"setup_posture"',
189
189
  inspectSetupItem: 'agent_harness mode:"setup_item"',
190
- openOnboarding: 'agent_harness mode:"open_ui_surface" surfaceId:"onboarding" confirm:true',
190
+ openOnboarding: 'agent_harness mode:"open_ui_surface" surfaceId:"onboarding" confirm:true explicitUserRequest:"..."',
191
191
  setupWorkspace: 'agent_harness mode:"workspace_action" target:"setup"',
192
192
  settings: 'agent_harness modes settings/get_setting/set_setting/reset_setting',
193
193
  providerRouting: 'agent_harness mode:"model_routing"',
@@ -18,6 +18,7 @@ export const AGENT_HARNESS_MODES = [
18
18
  'operator_methods', 'operator_method',
19
19
  'service_posture', 'service_endpoint',
20
20
  'connected_host', 'connected_host_status', 'connected_host_capability',
21
+ 'daemon', 'daemon_status',
21
22
  ] as const;
22
23
 
23
24
  const KEY_COMBO_PARAMETER_SCHEMA = {
@@ -127,6 +127,67 @@ function output(value: unknown): { readonly success: true; readonly output: stri
127
127
 
128
128
  function error(message: string): { readonly success: false; readonly error: string } { return { success: false, error: message }; }
129
129
 
130
+ function compactHarnessModeGuide(): Record<string, unknown> {
131
+ return {
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.',
156
+ };
157
+ }
158
+
159
+ function detailedHarnessModelAccessGuide(): Record<string, string> {
160
+ return {
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.',
188
+ };
189
+ }
190
+
130
191
  function requireConfirmedAction(args: AgentHarnessToolArgs, action: string): string | null {
131
192
  const explicitUserRequest = readString(args.explicitUserRequest);
132
193
  if (!explicitUserRequest) return `${action} requires explicitUserRequest with the user's exact request or a short faithful summary.`;
@@ -348,11 +409,7 @@ export function createAgentHarnessTool(deps: AgentHarnessToolDeps): Tool {
348
409
  return {
349
410
  definition: {
350
411
  name: 'agent_harness',
351
- description: [
352
- 'Inspect or operate the GoodVibes Agent harness.',
353
- 'Use summary for mode help.',
354
- 'Effects require confirm:true plus explicitUserRequest; no host lifecycle or raw secrets.',
355
- ].join(' '),
412
+ description: 'Inspect or operate GoodVibes Agent harness surfaces.',
356
413
  parameters: {
357
414
  type: 'object',
358
415
  properties: AGENT_HARNESS_PARAMETER_PROPERTIES,
@@ -407,36 +464,12 @@ export function createAgentHarnessTool(deps: AgentHarnessToolDeps): Tool {
407
464
  releaseReadiness: releaseReadinessInventoryStatus(),
408
465
  operatorMethods: operatorMethodCatalogStatus(),
409
466
  servicePosture: servicePostureCatalogStatus(),
410
- modelAccess: {
411
- cliCommands: 'List mode:"cli_commands"; inspect mode:"cli_command" with cliCommand|commandName|query. Discovery only.',
412
- panels: 'List mode:"panels"; inspect mode:"panel"; navigate mode:"open_panel" with confirm:true and explicitUserRequest.',
413
- uiSurfaces: 'List mode:"ui_surfaces"; inspect mode:"ui_surface"; navigate mode:"open_ui_surface" with confirmation.',
414
- shortcuts: 'List mode:"shortcuts"; inspect mode:"keybinding"; run mode:"run_keybinding"; edit with set_keybinding/reset_keybinding and confirmation.',
415
- slashCommands: 'List mode:"commands"; inspect mode:"command"; execute mode:"run_command" with confirmation.',
416
- channels: 'List mode:"channels"; inspect mode:"channel"; deliver with agent_channel_send and confirmation.',
417
- notifications: 'List mode:"notifications"; inspect mode:"notification_target"; deliver with agent_notify and confirmation.',
418
- providerAccounts: 'List mode:"provider_accounts"; inspect mode:"provider_account"; auth changes stay confirmed workspace/command flows.',
419
- mcpServers: 'List mode:"mcp_servers"; inspect mode:"mcp_server"; trust/server changes stay confirmed workspace/command flows.',
420
- setupPosture: 'List mode:"setup_posture"; inspect mode:"setup_item"; setup mutations stay confirmed visible flows.',
421
- modelRouting: 'List mode:"model_routing"; inspect mode:"model_route"; selection and provider edits stay confirmed visible flows.',
422
- pairingPosture: 'List mode:"pairing_posture"; inspect mode:"pairing_route"; raw token/QR and pairing effects stay visible user flows.',
423
- delegationPosture: 'List mode:"delegation_posture"; inspect mode:"delegation_route"; delegated submission stays confirmed visible flow.',
424
- securityPosture: 'List mode:"security_posture"; inspect mode:"security_finding"; mutate only through confirmed security routes.',
425
- supportBundles: 'List mode:"support_bundles"; inspect mode:"support_bundle"; export/import stays confirmation-gated.',
426
- mediaPosture: 'List mode:"media_posture"; inspect mode:"media_provider"; generate with agent_media_generate and confirmation.',
427
- sessions: 'List mode:"sessions"; inspect mode:"session"; save/resume/export/delete stays visible confirmed flow.',
428
- workspace: 'List mode:"workspace" or mode:"workspace_categories"; actions via workspace_actions/workspace_action/run_workspace_action; includeParameters:true inlines editor schemas.',
429
- settings: 'List mode:"settings" with category|prefix|query|includeHidden:true; get_setting/set_setting/reset_setting use key|target|query and confirmation for writes.',
430
- tools: 'List mode:"tools" with query|limit|includeParameters:true; inspect mode:"tool" with toolName|target|query.',
431
- releaseEvidence: 'List mode:"release_evidence"; inspect mode:"release_evidence_artifact"; includeParameters:true inlines artifact detail.',
432
- releaseReadiness: 'List mode:"release_readiness"; inspect mode:"release_readiness_item"; includeParameters:true inlines item detail.',
433
- operatorMethods: 'List mode:"operator_methods"; inspect mode:"operator_method"; execute only through the returned first-class tool.',
434
- servicePosture: 'List mode:"service_posture"; inspect mode:"service_endpoint"; includeParameters:true adds probes and redacted log tail.',
435
- connectedHost: 'Map mode:"connected_host"; inspect mode:"connected_host_capability"; no lifecycle control.',
436
- connectedHostStatus: 'Live read-only mode:"connected_host_status" for host reachability, SDK compatibility, token posture, and Knowledge readiness.',
437
- },
467
+ modeGuide: compactHarnessModeGuide(),
468
+ ...(args.includeParameters === true ? { modelAccess: detailedHarnessModelAccessGuide() } : {}),
438
469
  settingsPolicy: settingsPolicySummary(),
439
- connectedHost: connectedHostSummary(deps.commandContext, deps.toolRegistry),
470
+ connectedHost: connectedHostSummary(deps.commandContext, deps.toolRegistry, {
471
+ includeParameters: args.includeParameters === true,
472
+ }),
440
473
  });
441
474
  }
442
475
  if (args.mode === 'cli_commands') {
@@ -603,6 +636,8 @@ export function createAgentHarnessTool(deps: AgentHarnessToolDeps): Tool {
603
636
  query: readString(args.query) || undefined,
604
637
  includeHidden: args.includeHidden === true,
605
638
  limit: readLimit(args.limit, 100),
639
+ }, {
640
+ includeParameters: args.includeParameters === true,
606
641
  });
607
642
  return output({ settings, returned: settings.length, policy: settingsPolicySummary() });
608
643
  }
@@ -714,7 +749,11 @@ export function createAgentHarnessTool(deps: AgentHarnessToolDeps): Tool {
714
749
  if (resolved.status === 'ambiguous') return error(`Ambiguous service endpoint ${resolved.input}. Candidates: ${JSON.stringify(resolved.candidates)}`);
715
750
  return error(resolved.usage);
716
751
  }
717
- if (args.mode === 'connected_host') return output(connectedHostSummary(deps.commandContext, deps.toolRegistry));
752
+ if (args.mode === 'connected_host' || args.mode === 'daemon') {
753
+ return output(connectedHostSummary(deps.commandContext, deps.toolRegistry, {
754
+ includeParameters: args.includeParameters === true,
755
+ }));
756
+ }
718
757
  if (args.mode === 'connected_host_capability') {
719
758
  const query = readString(args.capabilityId || args.target || args.query);
720
759
  const resolved = describeConnectedHostCapability(deps.toolRegistry, query);
@@ -722,7 +761,11 @@ export function createAgentHarnessTool(deps: AgentHarnessToolDeps): Tool {
722
761
  if (resolved?.status === 'ambiguous') return error(`Ambiguous connected-host capability ${resolved.input}. Candidates: ${JSON.stringify(resolved.candidates)}`);
723
762
  return error(`Unknown connected-host capability ${query || '<missing>'}. Use mode:"connected_host" to inspect allowed and blocked capability ids.`);
724
763
  }
725
- 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
+ }
726
769
  return error(`Unhandled agent_harness mode: ${args.mode}`);
727
770
  } catch (err) {
728
771
  return error(formatHarnessError(err));