@pellux/goodvibes-agent 1.0.34 → 1.0.36

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 (87) hide show
  1. package/CHANGELOG.md +28 -13
  2. package/README.md +11 -8
  3. package/dist/package/main.js +1592 -921
  4. package/docs/README.md +6 -5
  5. package/docs/channels-remote-and-api.md +3 -3
  6. package/docs/connected-host.md +3 -3
  7. package/docs/getting-started.md +20 -12
  8. package/docs/knowledge-artifacts-and-multimodal.md +9 -4
  9. package/docs/project-planning.md +3 -3
  10. package/docs/providers-and-routing.md +2 -2
  11. package/docs/release-and-publishing.md +8 -8
  12. package/docs/tools-and-commands.md +34 -17
  13. package/docs/voice-and-live-tts.md +1 -1
  14. package/package.json +1 -1
  15. package/release/live-verification/live-verification.json +15 -15
  16. package/release/live-verification/live-verification.md +19 -21
  17. package/release/release-notes.md +6 -6
  18. package/release/release-readiness.json +64 -64
  19. package/src/agent/harness-control.ts +35 -9
  20. package/src/agent/reminder-schedule-format.ts +2 -5
  21. package/src/agent/reminder-schedule.ts +4 -11
  22. package/src/agent/routine-schedule-format.ts +3 -6
  23. package/src/agent/routine-schedule-promotion.ts +5 -14
  24. package/src/agent/routine-schedule-receipts.ts +4 -9
  25. package/src/cli/agent-knowledge-command.ts +6 -11
  26. package/src/cli/agent-knowledge-format.ts +4 -9
  27. package/src/cli/agent-knowledge-runtime.ts +7 -14
  28. package/src/cli/external-runtime.ts +3 -46
  29. package/src/cli/help.ts +2 -2
  30. package/src/cli/status.ts +6 -7
  31. package/src/input/agent-workspace-categories.ts +23 -23
  32. package/src/input/agent-workspace-channels.ts +3 -3
  33. package/src/input/agent-workspace-operations-command-editors.ts +1 -1
  34. package/src/input/command-registry.ts +1 -1
  35. package/src/input/commands/compat-runtime.ts +1 -1
  36. package/src/input/commands/planning-runtime.ts +1 -1
  37. package/src/input/commands/runtime-services.ts +1 -1
  38. package/src/input/mcp-workspace.ts +1 -1
  39. package/src/input/submission-router.ts +1 -1
  40. package/src/panels/builtin/shared.ts +1 -1
  41. package/src/panels/project-planning-panel.ts +4 -4
  42. package/src/panels/qr-panel.ts +2 -2
  43. package/src/renderer/conversation-overlays.ts +1 -0
  44. package/src/runtime/bootstrap-command-parts.ts +1 -1
  45. package/src/runtime/bootstrap-core.ts +3 -1
  46. package/src/runtime/bootstrap-hook-bridge.ts +1 -1
  47. package/src/runtime/bootstrap-shell.ts +1 -1
  48. package/src/runtime/bootstrap.ts +7 -4
  49. package/src/runtime/context.ts +2 -2
  50. package/src/runtime/index.ts +88 -5
  51. package/src/runtime/store/state.ts +1 -1
  52. package/src/tools/agent-channel-send-tool.ts +1 -1
  53. package/src/tools/agent-harness-channel-metadata.ts +36 -25
  54. package/src/tools/agent-harness-cli-metadata.ts +19 -1
  55. package/src/tools/agent-harness-command-catalog.ts +15 -4
  56. package/src/tools/agent-harness-connected-host-status.ts +7 -6
  57. package/src/tools/agent-harness-delegation-posture.ts +15 -4
  58. package/src/tools/agent-harness-keybinding-metadata.ts +67 -16
  59. package/src/tools/agent-harness-mcp-metadata.ts +11 -3
  60. package/src/tools/agent-harness-media-posture.ts +25 -14
  61. package/src/tools/agent-harness-metadata.ts +140 -37
  62. package/src/tools/agent-harness-mode-catalog.ts +258 -0
  63. package/src/tools/agent-harness-model-routing.ts +18 -3
  64. package/src/tools/agent-harness-model-tool-catalog.ts +85 -7
  65. package/src/tools/agent-harness-notification-metadata.ts +30 -19
  66. package/src/tools/agent-harness-operator-methods.ts +15 -10
  67. package/src/tools/agent-harness-pairing-posture.ts +17 -5
  68. package/src/tools/agent-harness-panel-metadata.ts +10 -4
  69. package/src/tools/agent-harness-provider-account-metadata.ts +46 -35
  70. package/src/tools/agent-harness-release-evidence.ts +31 -3
  71. package/src/tools/agent-harness-release-readiness.ts +30 -0
  72. package/src/tools/agent-harness-security-posture.ts +18 -4
  73. package/src/tools/agent-harness-service-posture.ts +9 -2
  74. package/src/tools/agent-harness-session-metadata.ts +24 -8
  75. package/src/tools/agent-harness-setup-posture.ts +32 -21
  76. package/src/tools/agent-harness-text.ts +6 -0
  77. package/src/tools/agent-harness-tool-schema.ts +1 -1
  78. package/src/tools/agent-harness-tool.ts +38 -36
  79. package/src/tools/agent-harness-ui-surface-metadata.ts +105 -101
  80. package/src/tools/agent-harness-workspace-actions.ts +64 -3
  81. package/src/tools/agent-knowledge-ingest-tool.ts +1 -1
  82. package/src/tools/agent-knowledge-tool.ts +1 -1
  83. package/src/tools/agent-media-generate-tool.ts +2 -2
  84. package/src/tools/agent-notify-tool.ts +1 -1
  85. package/src/tools/agent-reminder-schedule-tool.ts +1 -1
  86. package/src/tools/tool-definition-compaction.ts +76 -0
  87. package/src/version.ts +2 -8
@@ -4,6 +4,7 @@ import { GOODVIBES_AGENT_PAIRING_SURFACE } from '../config/surface.ts';
4
4
  import { resolveRuntimeEndpointBinding } from '../cli/endpoints.ts';
5
5
  import { connectedHostOperatorTokenFingerprint, readConnectedHostOperatorToken } from '../runtime/connected-host-auth.ts';
6
6
  import { requirePlatform, requireShellPaths } from '../input/commands/runtime-services.ts';
7
+ import { previewHarnessText } from './agent-harness-text.ts';
7
8
 
8
9
  export interface AgentHarnessPairingArgs {
9
10
  readonly pairingRouteId?: unknown;
@@ -101,7 +102,7 @@ function pairingRoutes(): readonly PairingRoute[] {
101
102
  {
102
103
  id: 'connected-host-status',
103
104
  label: 'Connected host live posture',
104
- detail: 'Read-only reachability, token posture, SDK compatibility, and route readiness used before companion setup.',
105
+ detail: 'Read-only reachability, token posture, and route readiness used before companion setup.',
105
106
  effect: 'read-only',
106
107
  harnessRoute: 'agent_harness mode:"connected_host_status"',
107
108
  capabilityIds: ['connected-host-status'],
@@ -152,6 +153,7 @@ function describeCandidate(route: PairingRoute): Record<string, unknown> {
152
153
  label: route.label,
153
154
  effect: route.effect,
154
155
  requiresConfirmation: route.requiresConfirmation === true,
156
+ modelRoute: pairingRouteModelRoute(route),
155
157
  };
156
158
  }
157
159
 
@@ -159,12 +161,15 @@ function describeRoute(route: PairingRoute, options: { readonly includeParameter
159
161
  return {
160
162
  pairingRouteId: route.id,
161
163
  label: route.label,
162
- detail: route.detail,
164
+ ...(options.includeParameters ? { detail: route.detail } : { summary: previewHarnessText(route.detail) }),
163
165
  effect: route.effect,
164
- ...(route.command ? { command: route.command } : {}),
165
- ...(route.harnessRoute ? { harnessRoute: route.harnessRoute } : {}),
166
- ...(route.capabilityIds ? { capabilityIds: route.capabilityIds } : {}),
167
166
  requiresConfirmation: route.requiresConfirmation === true,
167
+ modelRoute: pairingRouteModelRoute(route),
168
+ ...(options.includeParameters ? {
169
+ ...(route.command ? { command: route.command } : {}),
170
+ ...(route.harnessRoute ? { harnessRoute: route.harnessRoute } : {}),
171
+ ...(route.capabilityIds ? { capabilityIds: route.capabilityIds } : {}),
172
+ } : {}),
168
173
  ...(options.lookup ? { lookup: options.lookup } : {}),
169
174
  ...(options.includeParameters ? {
170
175
  policy: {
@@ -183,6 +188,13 @@ function describeRoute(route: PairingRoute, options: { readonly includeParameter
183
188
  };
184
189
  }
185
190
 
191
+ function pairingRouteModelRoute(route: PairingRoute): string {
192
+ if (route.command === '/pair') return 'agent_harness mode:"run_command" command:"/pair"';
193
+ if (route.command === '/pair --show-token --yes') return 'agent_harness mode:"run_command" command:"/pair --show-token --yes"';
194
+ if (route.id === 'pairing-ui') return 'agent_harness mode:"workspace_action" target:"pair"';
195
+ return previewHarnessText(route.harnessRoute ?? 'agent_harness mode:"pairing_route"');
196
+ }
197
+
186
198
  function pairingState(context: CommandContext): Record<string, unknown> {
187
199
  const shellPaths = requireShellPaths(context);
188
200
  const configManager = requirePlatform(context).configManager;
@@ -40,9 +40,9 @@ function readLimit(value: unknown, fallback: number): number {
40
40
  return Math.max(1, Math.min(500, Math.trunc(parsed)));
41
41
  }
42
42
 
43
- function previewText(value: string, maxLength = 120): string {
43
+ function previewText(value: string, maxLength = 56): string {
44
44
  const normalized = value.replace(/\s+/g, ' ').trim();
45
- return normalized.length <= maxLength ? normalized : `${normalized.slice(0, maxLength - 1).trimEnd()}...`;
45
+ return normalized.length <= maxLength ? normalized : `${normalized.slice(0, maxLength - 3).trimEnd()}...`;
46
46
  }
47
47
 
48
48
  function panelManager(context: CommandContext) {
@@ -77,6 +77,7 @@ function panelCandidate(registration: PanelRegistration): Record<string, unknown
77
77
  name: registration.name,
78
78
  category: registration.category,
79
79
  summary: previewText(registration.description),
80
+ modelRoute: panelModelRoute(),
80
81
  workspaceRoute: {
81
82
  categoryId: agentWorkspaceCategoryForPanel(registration.id),
82
83
  command: agentWorkspaceCommandForPanel(registration.id),
@@ -84,6 +85,10 @@ function panelCandidate(registration: PanelRegistration): Record<string, unknown
84
85
  };
85
86
  }
86
87
 
88
+ function panelModelRoute(): string {
89
+ return 'agent_harness mode:"open_panel" or mode:"workspace_actions"';
90
+ }
91
+
87
92
  function resolveHarnessPanel(context: CommandContext, args: AgentHarnessPanelArgs): PanelResolution | null {
88
93
  const manager = panelManager(context);
89
94
  const lookup = panelLookupFromArgs(args);
@@ -131,6 +136,7 @@ function describePanelRegistration(
131
136
  pane,
132
137
  active: activePanel?.id === registration.id,
133
138
  focused: activePanel?.id === registration.id,
139
+ modelRoute: panelModelRoute(),
134
140
  workspaceRoute: {
135
141
  categoryId: agentWorkspaceCategoryForPanel(registration.id),
136
142
  command: agentWorkspaceCommandForPanel(registration.id),
@@ -139,7 +145,7 @@ function describePanelRegistration(
139
145
  policy: {
140
146
  effect: 'ui-navigation',
141
147
  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.',
148
+ boundary: 'Panels are Agent/TUI operator views. The model can inspect panel catalog/open state; panel routing uses the existing Agent workspace route and does not mutate connected-host lifecycle.',
143
149
  },
144
150
  } : {}),
145
151
  };
@@ -200,6 +206,6 @@ export function openHarnessPanel(context: CommandContext, args: AgentHarnessPane
200
206
  status: 'routed',
201
207
  panel,
202
208
  pane: pane ?? 'default',
203
- note: 'Panel routing was handed to the current Agent shell bridge.',
209
+ note: 'Panel routing was handed to the current Agent operator surface.',
204
210
  };
205
211
  }
@@ -2,6 +2,7 @@ import type { CommandContext } from '../input/command-registry.ts';
2
2
  import type { ProviderAccountRecord, ProviderAccountSnapshot } from '../panels/provider-account-snapshot.ts';
3
3
  import { buildProviderAccountSnapshot } from '../panels/provider-account-snapshot.ts';
4
4
  import { requireProvider, requireServiceRegistry, requireSubscriptionManager } from '../input/commands/runtime-services.ts';
5
+ import { previewHarnessText } from './agent-harness-text.ts';
5
6
 
6
7
  export interface AgentHarnessProviderAccountArgs {
7
8
  readonly providerId?: unknown;
@@ -74,9 +75,14 @@ function describeCandidate(account: ProviderAccountRecord): Record<string, unkno
74
75
  authFreshness: account.authFreshness,
75
76
  configured: account.configured,
76
77
  issues: account.issues.length,
78
+ modelRoute: providerAccountModelRoute(),
77
79
  };
78
80
  }
79
81
 
82
+ function providerAccountModelRoute(): string {
83
+ return 'agent_harness mode:"provider_account" or mode:"run_command"';
84
+ }
85
+
80
86
  function describeAccount(
81
87
  account: ProviderAccountRecord,
82
88
  options: { readonly includeParameters?: boolean; readonly lookup?: Record<string, unknown> } = {},
@@ -99,42 +105,47 @@ function describeAccount(
99
105
  ...(account.tokenType ? { tokenType: account.tokenType } : {}),
100
106
  issueCount: account.issues.length,
101
107
  recommendedActionCount: account.recommendedActions.length,
108
+ modelRoute: providerAccountModelRoute(),
102
109
  ...(options.lookup ? { lookup: options.lookup } : {}),
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
- ],
132
- loginStartCommand: `/subscription login ${account.providerId} start --yes`,
133
- loginFinishCommand: `/subscription login ${account.providerId} finish <code-or-url> --yes`,
134
- logoutCommand: `/subscription logout ${account.providerId} --yes`,
135
- confirmationRequired: true,
136
- },
137
- } : {}),
110
+ ...(options.includeParameters
111
+ ? {
112
+ routeRecords: account.routeRecords.map((route) => ({
113
+ route: route.route,
114
+ usable: route.usable,
115
+ freshness: route.freshness,
116
+ detail: route.detail,
117
+ issues: route.issues,
118
+ })),
119
+ usageWindows: account.usageWindows,
120
+ issues: account.issues,
121
+ notes: account.notes,
122
+ recommendedActions: account.recommendedActions,
123
+ policy: {
124
+ effect: 'read-only',
125
+ values: 'Provider account posture reports route and freshness metadata only; raw tokens, authorization codes, and secret values are never returned.',
126
+ mutation: 'Provider login, logout, subscription bundle export, and account repair actions stay explicit confirmation-gated workspace or slash-command flows.',
127
+ },
128
+ modelAccess: {
129
+ reviewCommand: '/accounts review',
130
+ showCommand: `/accounts show ${account.providerId}`,
131
+ routesCommand: `/accounts routes ${account.providerId}`,
132
+ repairCommand: `/accounts repair ${account.providerId}`,
133
+ subscriptionInspectCommand: `/subscription inspect ${account.providerId}`,
134
+ workspaceActions: [
135
+ 'provider-accounts',
136
+ 'provider-account-repair',
137
+ 'subscription-review',
138
+ 'subscription-inspect',
139
+ ],
140
+ loginStartCommand: `/subscription login ${account.providerId} start --yes`,
141
+ loginFinishCommand: `/subscription login ${account.providerId} finish <code-or-url> --yes`,
142
+ logoutCommand: `/subscription logout ${account.providerId} --yes`,
143
+ confirmationRequired: true,
144
+ },
145
+ }
146
+ : {
147
+ summary: previewHarnessText(`${account.providerId} ${account.authFreshness}; ${account.issues.length} issue(s)`),
148
+ }),
138
149
  };
139
150
  }
140
151
 
@@ -1,12 +1,13 @@
1
1
  import { existsSync, readFileSync, statSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
+ import { previewHarnessText } from './agent-harness-text.ts';
3
4
 
4
5
  const RELEASE_EVIDENCE_ARTIFACTS = [
5
6
  {
6
7
  id: 'release-notes',
7
8
  path: 'release/release-notes.md',
8
9
  kind: 'markdown',
9
- description: 'Product-facing release notes for the current release evidence bundle.',
10
+ description: 'Shipped release notes included with operator/audit release artifacts.',
10
11
  },
11
12
  {
12
13
  id: 'performance-snapshot',
@@ -18,7 +19,7 @@ const RELEASE_EVIDENCE_ARTIFACTS = [
18
19
  id: 'release-readiness',
19
20
  path: 'release/release-readiness.json',
20
21
  kind: 'json',
21
- description: 'Release capability inventory with owner, evidence, and quality dimensions.',
22
+ description: 'Release inventory with owner, evidence, and quality dimensions.',
22
23
  },
23
24
  {
24
25
  id: 'live-verification-json',
@@ -120,6 +121,20 @@ function artifactSearchText(artifact: ReleaseEvidenceArtifact): string {
120
121
  return `${artifact.id}\n${artifact.path}\n${artifact.kind}\n${artifact.description}`.toLowerCase();
121
122
  }
122
123
 
124
+ function releaseEvidenceModelRoute(artifact?: ReleaseEvidenceArtifact): string {
125
+ if (artifact) return 'agent_harness mode:"release_evidence_artifact"';
126
+ return 'agent_harness mode:"release_evidence" or mode:"release_evidence_artifact"';
127
+ }
128
+
129
+ function releaseEvidencePolicy(): Record<string, unknown> {
130
+ return {
131
+ effect: 'operator-audit-read-only',
132
+ audience: 'release operators and maintainers',
133
+ values: 'Returns packaged release artifacts, summaries, and optional artifact content for release audit.',
134
+ boundary: 'Release artifacts are audit material. They are not visible product routes and do not mutate runtime state.',
135
+ };
136
+ }
137
+
123
138
  function evidenceLookupFromArgs(args: ReleaseEvidenceArgs): ReleaseEvidenceLookup | null {
124
139
  const artifactId = readString(args.artifactId);
125
140
  if (artifactId) return { source: 'artifactId', input: artifactId };
@@ -243,6 +258,7 @@ function summarizeLoadedArtifact(
243
258
  kind: loaded.artifact.kind,
244
259
  description: loaded.artifact.description,
245
260
  status: loaded.status,
261
+ modelRoute: releaseEvidenceModelRoute(loaded.artifact),
246
262
  };
247
263
  if (loaded.status !== 'available') {
248
264
  return { ...base, reason: loaded.reason };
@@ -255,6 +271,12 @@ function summarizeLoadedArtifact(
255
271
  ...base,
256
272
  sizeBytes: loaded.sizeBytes,
257
273
  summary,
274
+ policy: releaseEvidencePolicy(),
275
+ modelAccess: {
276
+ listArtifacts: 'agent_harness mode:"release_evidence"',
277
+ inspectArtifact: `agent_harness mode:"release_evidence_artifact" artifactId:"${loaded.artifact.id}"`,
278
+ includeContent: 'Pass includeParameters:true only when release audit requires artifact content.',
279
+ },
258
280
  ...(options.includeSource
259
281
  ? loaded.artifact.kind === 'json'
260
282
  ? { data: loaded.parsed }
@@ -268,7 +290,8 @@ function releaseEvidenceCandidates(artifacts: readonly ReleaseEvidenceArtifact[]
268
290
  id: artifact.id,
269
291
  path: artifact.path,
270
292
  kind: artifact.kind,
271
- description: artifact.description,
293
+ summary: previewHarnessText(artifact.description),
294
+ modelRoute: releaseEvidenceModelRoute(artifact),
272
295
  }));
273
296
  }
274
297
 
@@ -298,6 +321,11 @@ export function releaseEvidenceSummary(args: ReleaseEvidenceArgs): Record<string
298
321
  filtered: filtered.length,
299
322
  returned: loaded.length,
300
323
  artifactsList: loaded.map((artifact) => summarizeLoadedArtifact(artifact, { includeSource: args.includeParameters === true })),
324
+ policy: releaseEvidencePolicy(),
325
+ modelAccess: {
326
+ listArtifacts: 'agent_harness mode:"release_evidence"',
327
+ inspectArtifact: 'agent_harness mode:"release_evidence_artifact" with artifactId, target, or query',
328
+ },
301
329
  artifactLookup: 'Use mode:"release_evidence_artifact" with artifactId, target, or query to inspect one release evidence artifact.',
302
330
  };
303
331
  }
@@ -103,6 +103,20 @@ function itemSearchText(item: Record<string, unknown>): string {
103
103
  return fields.join('\n').toLowerCase();
104
104
  }
105
105
 
106
+ function releaseReadinessModelRoute(item?: Record<string, unknown>): string {
107
+ if (item) return 'agent_harness mode:"release_readiness_item"';
108
+ return 'agent_harness mode:"release_readiness" or mode:"release_readiness_item"';
109
+ }
110
+
111
+ function releaseReadinessPolicy(): Record<string, unknown> {
112
+ return {
113
+ effect: 'operator-audit-read-only',
114
+ audience: 'release operators and maintainers',
115
+ values: 'Returns release-quality inventory status, evidence, and quality dimensions for audit.',
116
+ boundary: 'Release readiness is audit material. It is not a visible product route and does not mutate runtime state.',
117
+ };
118
+ }
119
+
106
120
  function countBy(items: readonly Record<string, unknown>[], key: string): Record<string, number> {
107
121
  const counts: Record<string, number> = {};
108
122
  for (const item of items) {
@@ -134,7 +148,15 @@ function summarizeItem(item: Record<string, unknown>, options: { readonly includ
134
148
  status: item.status,
135
149
  evidence: item.evidence,
136
150
  action: item.action,
151
+ modelRoute: releaseReadinessModelRoute(item),
137
152
  ...(options.includeQuality ? { quality: item.quality } : {}),
153
+ ...(options.includeQuality ? {
154
+ policy: releaseReadinessPolicy(),
155
+ modelAccess: {
156
+ listItems: 'agent_harness mode:"release_readiness"',
157
+ inspectItem: `agent_harness mode:"release_readiness_item" itemId:"${readString(item.id)}"`,
158
+ },
159
+ } : {}),
138
160
  };
139
161
  }
140
162
 
@@ -153,6 +175,7 @@ function releaseReadinessCandidates(items: readonly Record<string, unknown>[]):
153
175
  capability: item.capability,
154
176
  owner: item.owner,
155
177
  status: item.status,
178
+ modelRoute: releaseReadinessModelRoute(item),
156
179
  }));
157
180
  }
158
181
 
@@ -173,6 +196,8 @@ export function releaseReadinessInventoryStatus(): Record<string, unknown> {
173
196
  checkedAt: loaded.root.checkedAt,
174
197
  items: items.length,
175
198
  qualityDimensions: QUALITY_DIMENSIONS,
199
+ modelRoute: releaseReadinessModelRoute(),
200
+ policy: releaseReadinessPolicy(),
176
201
  };
177
202
  }
178
203
 
@@ -203,6 +228,11 @@ export function releaseReadinessSummary(args: ReleaseReadinessArgs): Record<stri
203
228
  schemaVersion: loaded.root.schemaVersion,
204
229
  checkedAt: loaded.root.checkedAt,
205
230
  policy: loaded.root.policy,
231
+ operatorAuditPolicy: releaseReadinessPolicy(),
232
+ modelAccess: {
233
+ listItems: 'agent_harness mode:"release_readiness"',
234
+ inspectItem: 'agent_harness mode:"release_readiness_item" with itemId, target, or query',
235
+ },
206
236
  totals: {
207
237
  items: items.length,
208
238
  filtered: filtered.length,
@@ -2,6 +2,7 @@ import { existsSync, readFileSync } from 'node:fs';
2
2
  import { buildMcpAttackPathReview } from '@/runtime/index.ts';
3
3
  import { listBuiltinSubscriptionProviders } from '@pellux/goodvibes-sdk/platform/config';
4
4
  import type { CommandContext } from '../input/command-registry.ts';
5
+ import { previewHarnessText } from './agent-harness-text.ts';
5
6
 
6
7
  export interface AgentHarnessSecurityArgs {
7
8
  readonly query?: unknown;
@@ -153,9 +154,18 @@ function describeFindingCandidate(finding: SecurityFinding): Record<string, unkn
153
154
  source: finding.source,
154
155
  severity: finding.severity,
155
156
  title: finding.title,
157
+ modelRoute: securityFindingModelRoute(),
156
158
  };
157
159
  }
158
160
 
161
+ function securityFindingModelRoute(): string {
162
+ return 'agent_harness mode:"security_finding" or mode:"run_command"';
163
+ }
164
+
165
+ function supportBundleModelRoute(): string {
166
+ return 'agent_harness mode:"support_bundle" or mode:"run_workspace_action"';
167
+ }
168
+
159
169
  function describeFinding(finding: SecurityFinding, includeParameters: boolean, lookup?: Record<string, unknown>): Record<string, unknown> {
160
170
  return {
161
171
  findingId: finding.findingId,
@@ -164,6 +174,7 @@ function describeFinding(finding: SecurityFinding, includeParameters: boolean, l
164
174
  title: finding.title,
165
175
  summary: finding.summary,
166
176
  route: finding.route,
177
+ modelRoute: securityFindingModelRoute(),
167
178
  ...(lookup ? { lookup } : {}),
168
179
  ...(includeParameters && finding.detail ? { detail: finding.detail } : {}),
169
180
  ...(includeParameters ? {
@@ -537,15 +548,18 @@ export function supportBundleSummary(args: AgentHarnessSecurityArgs): Record<str
537
548
  bundleType: route.bundleType,
538
549
  defaultPath: route.defaultPath,
539
550
  inspectCommand: route.inspectCommand,
540
- exportCommand: route.exportCommand,
541
- ...(route.importCommand ? { importCommand: route.importCommand } : {}),
542
- workspaceActionIds: route.workspaceActionIds,
551
+ modelRoute: supportBundleModelRoute(),
543
552
  ...(args.includeParameters === true ? {
553
+ exportCommand: route.exportCommand,
554
+ ...(route.importCommand ? { importCommand: route.importCommand } : {}),
555
+ workspaceActionIds: route.workspaceActionIds,
544
556
  parameters: {
545
557
  bundlePath: 'Workspace-relative path for support_bundle inspection.',
546
558
  confirm: 'Required for export/import routes through run_workspace_action or run_command.',
547
559
  },
548
- } : {}),
560
+ } : {
561
+ summary: previewHarnessText(`${route.bundleType} bundle inspection route`),
562
+ }),
549
563
  }));
550
564
  return {
551
565
  bundles: routes,
@@ -77,13 +77,14 @@ function describeEndpoint(
77
77
  bindPosture: endpoint.bindPosture,
78
78
  networkFacing: endpoint.networkFacing,
79
79
  ...(endpoint.reachable !== undefined ? { reachable: endpoint.reachable } : {}),
80
+ modelRoute: serviceEndpointModelRoute(),
80
81
  ...(options.lookup ? { lookup: options.lookup } : {}),
81
82
  ...(options.includeParameters ? {
82
83
  policy: {
83
84
  effect: 'read-only',
84
85
  modelOperation: 'Inspect endpoint binding, network-facing posture, and optional reachability only.',
85
86
  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
+ settings: 'Use agent_harness mode:"settings" or mode:"get_setting" for read-only inspection of endpoint settings; connected-host lifecycle/listener settings stay locked in Agent.',
87
88
  },
88
89
  } : {}),
89
90
  };
@@ -95,9 +96,14 @@ function describeEndpointCandidate(endpoint: CliServiceEndpointPosture): Record<
95
96
  label: endpoint.label,
96
97
  enabled: endpoint.enabled,
97
98
  binding: endpoint.binding,
99
+ modelRoute: serviceEndpointModelRoute(),
98
100
  };
99
101
  }
100
102
 
103
+ function serviceEndpointModelRoute(): string {
104
+ return 'agent_harness mode:"service_endpoint" or mode:"settings"';
105
+ }
106
+
101
107
  function endpointLookupFromArgs(args: AgentHarnessServicePostureArgs): { readonly source: ServiceEndpointLookupSource; readonly input: string } | null {
102
108
  const endpointId = readString(args.endpointId);
103
109
  if (endpointId) return { source: 'endpointId', input: endpointId };
@@ -182,6 +188,7 @@ export async function servicePostureSummary(
182
188
  ownership: 'external-connected-host',
183
189
  readOnly: true,
184
190
  lifecycle: 'GoodVibes Agent reports connected-host/service posture but does not start, stop, restart, install, expose, or mutate host listeners.',
191
+ modelRoute: serviceEndpointModelRoute(),
185
192
  config: posture.config,
186
193
  managed: posture.managed,
187
194
  endpoints: posture.endpoints.map((endpoint) => describeEndpoint(endpoint, { includeParameters: includeDetails })),
@@ -190,7 +197,7 @@ export async function servicePostureSummary(
190
197
  ...(includeDetails ? { modelAccess: {
191
198
  endpointLookup: 'Use mode:"service_endpoint" with endpointId, target, or query to inspect one endpoint.',
192
199
  settings: 'Use mode:"settings" with includeHidden:true for endpoint setting descriptors. Host-owned listener settings remain read-only.',
193
- liveHostStatus: 'Use mode:"connected_host_status" for SDK compatibility, token posture, and Agent Knowledge route readiness.',
200
+ liveHostStatus: 'Use mode:"connected_host_status" for token posture and Agent Knowledge route readiness.',
194
201
  } } : {}),
195
202
  };
196
203
  }
@@ -1,4 +1,5 @@
1
1
  import type { CommandContext } from '../input/command-registry.ts';
2
+ import { previewHarnessText } from './agent-harness-text.ts';
2
3
 
3
4
  export interface AgentHarnessSessionArgs {
4
5
  readonly sessionId?: unknown;
@@ -89,9 +90,18 @@ function describeSessionCandidate(session: SessionInfoLike, currentSessionId: st
89
90
  title: session.title || '(untitled)',
90
91
  messageCount: session.messageCount,
91
92
  active: session.name === currentSessionId,
93
+ modelRoute: sessionModelRoute(),
92
94
  };
93
95
  }
94
96
 
97
+ function sessionModelRoute(): string {
98
+ return 'agent_harness mode:"session" or mode:"run_command"';
99
+ }
100
+
101
+ function bookmarkModelRoute(): string {
102
+ return 'agent_harness mode:"open_ui_surface" or agent_knowledge_ingest';
103
+ }
104
+
95
105
  function describeSession(
96
106
  session: SessionInfoLike,
97
107
  options: {
@@ -110,6 +120,8 @@ function describeSession(
110
120
  model: session.model || null,
111
121
  provider: session.provider || null,
112
122
  active: session.name === options.currentSessionId,
123
+ modelRoute: sessionModelRoute(),
124
+ ...(options.includeParameters ? {} : { summary: previewHarnessText(session.title || session.name) }),
113
125
  ...(posture ? { returnContext: posture } : {}),
114
126
  ...(options.search ? {
115
127
  search: {
@@ -164,24 +176,28 @@ function currentSession(context: CommandContext): Record<string, unknown> {
164
176
  };
165
177
  }
166
178
 
167
- function bookmarkSummary(context: CommandContext): Record<string, unknown> {
179
+ function bookmarkSummary(context: CommandContext, includeParameters = false): Record<string, unknown> {
168
180
  const manager = context.workspace.bookmarkManager;
169
181
  if (!manager) {
170
182
  return {
171
183
  status: 'unavailable',
172
184
  bookmarks: 0,
173
185
  savedFiles: 0,
186
+ modelRoute: bookmarkModelRoute(),
174
187
  };
175
188
  }
176
189
  return {
177
190
  status: 'available',
178
191
  bookmarks: manager.list().length,
179
192
  savedFiles: manager.listSavedFiles().length,
180
- modelRoutes: {
181
- visibleBookmarkPicker: 'agent_harness mode:"open_ui_surface" surfaceId:"bookmarks" confirm:true explicitUserRequest:"..."',
182
- command: '/bookmarks',
183
- importIntoKnowledge: 'agent_knowledge_ingest sourceKind:"bookmarks_file" confirm:true explicitUserRequest:"..."',
184
- },
193
+ modelRoute: bookmarkModelRoute(),
194
+ ...(includeParameters ? {
195
+ modelRoutes: {
196
+ visibleBookmarkPicker: 'agent_harness mode:"open_ui_surface" surfaceId:"bookmarks" confirm:true explicitUserRequest:"..."',
197
+ command: '/bookmarks',
198
+ importIntoKnowledge: 'agent_knowledge_ingest sourceKind:"bookmarks_file" confirm:true explicitUserRequest:"..."',
199
+ },
200
+ } : {}),
185
201
  };
186
202
  }
187
203
 
@@ -206,7 +222,7 @@ export function sessionSummary(context: CommandContext, args: AgentHarnessSessio
206
222
  returned: 0,
207
223
  total: 0,
208
224
  current: currentSession(context),
209
- bookmarks: bookmarkSummary(context),
225
+ bookmarks: bookmarkSummary(context, args.includeParameters === true),
210
226
  policy: 'Session runtime or session manager is unavailable in this Agent context.',
211
227
  };
212
228
  }
@@ -221,7 +237,7 @@ export function sessionSummary(context: CommandContext, args: AgentHarnessSessio
221
237
  return {
222
238
  status: 'available',
223
239
  current: currentSession(context),
224
- bookmarks: bookmarkSummary(context),
240
+ bookmarks: bookmarkSummary(context, args.includeParameters === true),
225
241
  sessions: limited.map((session) => {
226
242
  const search = searchByName.get(session.name);
227
243
  return describeSession(session, {
@@ -3,6 +3,7 @@ import { collectOnboardingSnapshot, deriveStep1Capabilities, deriveStep1Capabili
3
3
  import type { CommandContext } from '../input/command-registry.ts';
4
4
  import { buildProviderAccountSnapshot } from '../panels/provider-account-snapshot.ts';
5
5
  import { requireLocalUserAuthManager, requirePlatform, requireProvider, requireSecretsManager, requireServiceRegistry, requireShellPaths, requireSubscriptionManager } from '../input/commands/runtime-services.ts';
6
+ import { previewHarnessText } from './agent-harness-text.ts';
6
7
 
7
8
  export interface AgentHarnessSetupArgs {
8
9
  readonly setupItemId?: unknown;
@@ -175,36 +176,46 @@ function describeItem(
175
176
  setupItemId: item.id,
176
177
  label: item.label,
177
178
  selected: item.selected,
178
- detail: item.detail,
179
- signals: signalsForItem(item, snapshot),
179
+ modelRoute: setupItemModelRoute(),
180
180
  ...(options.lookup ? { lookup: options.lookup } : {}),
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
- modelAccess: {
188
- inspectSetup: 'agent_harness mode:"setup_posture"',
189
- inspectSetupItem: 'agent_harness mode:"setup_item"',
190
- openOnboarding: 'agent_harness mode:"open_ui_surface" surfaceId:"onboarding" confirm:true explicitUserRequest:"..."',
191
- setupWorkspace: 'agent_harness mode:"workspace_action" target:"setup"',
192
- settings: 'agent_harness modes settings/get_setting/set_setting/reset_setting',
193
- providerRouting: 'agent_harness mode:"model_routing"',
194
- providerAccounts: 'agent_harness mode:"provider_accounts"',
195
- channels: 'agent_harness mode:"channels"',
196
- media: 'agent_harness mode:"media_posture"',
197
- security: 'agent_harness mode:"security_posture"',
198
- },
199
- } : {}),
181
+ ...(options.includeParameters
182
+ ? {
183
+ detail: item.detail,
184
+ signals: signalsForItem(item, snapshot),
185
+ policy: {
186
+ effect: 'read-only',
187
+ values: 'Setup posture returns onboarding readiness, counts, safe setting keys, and route metadata only; secret values and raw provider tokens are never returned.',
188
+ 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.',
189
+ },
190
+ modelAccess: {
191
+ inspectSetup: 'agent_harness mode:"setup_posture"',
192
+ inspectSetupItem: 'agent_harness mode:"setup_item"',
193
+ openOnboarding: 'agent_harness mode:"open_ui_surface" surfaceId:"onboarding" confirm:true explicitUserRequest:"..."',
194
+ setupWorkspace: 'agent_harness mode:"workspace_action" target:"setup"',
195
+ settings: 'agent_harness mode:"settings"; inspect or mutate with get_setting, set_setting, or reset_setting',
196
+ providerRouting: 'agent_harness mode:"model_routing"',
197
+ providerAccounts: 'agent_harness mode:"provider_accounts"',
198
+ channels: 'agent_harness mode:"channels"',
199
+ media: 'agent_harness mode:"media_posture"',
200
+ security: 'agent_harness mode:"security_posture"',
201
+ },
202
+ }
203
+ : {
204
+ summary: previewHarnessText(item.detail),
205
+ }),
200
206
  };
201
207
  }
202
208
 
209
+ function setupItemModelRoute(): string {
210
+ return 'agent_harness mode:"setup_item" or mode:"open_ui_surface"';
211
+ }
212
+
203
213
  function describeCandidate(item: OnboardingStep1CapabilityItem): Record<string, unknown> {
204
214
  return {
205
215
  setupItemId: item.id,
206
216
  label: item.label,
207
217
  selected: item.selected,
218
+ modelRoute: setupItemModelRoute(),
208
219
  };
209
220
  }
210
221
 
@@ -0,0 +1,6 @@
1
+ export const HARNESS_PREVIEW_LIMIT = 56;
2
+
3
+ export function previewHarnessText(value: string, maxLength = HARNESS_PREVIEW_LIMIT): string {
4
+ const normalized = value.replace(/\s+/g, ' ').trim();
5
+ return normalized.length <= maxLength ? normalized : `${normalized.slice(0, maxLength - 3).trimEnd()}...`;
6
+ }
@@ -1,5 +1,5 @@
1
1
  export const AGENT_HARNESS_MODES = [
2
- 'summary', 'cli_commands', 'cli_command', 'panels', 'panel', 'open_panel',
2
+ 'summary', 'modes', 'mode', 'cli_commands', 'cli_command', 'panels', 'panel', 'open_panel',
3
3
  'ui_surfaces', 'ui_surface', 'open_ui_surface',
4
4
  'shortcuts', 'keybindings', 'keybinding', 'run_keybinding', 'set_keybinding', 'reset_keybinding',
5
5
  'commands', 'command', 'run_command', 'channels', 'channel', 'notifications', 'notification_target',