@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.
- package/CHANGELOG.md +22 -0
- package/README.md +71 -59
- package/dist/package/main.js +565 -420
- package/docs/README.md +25 -21
- package/docs/channels-remote-and-api.md +2 -2
- package/docs/connected-host.md +3 -3
- package/docs/getting-started.md +87 -86
- package/docs/providers-and-routing.md +3 -3
- package/docs/release-and-publishing.md +3 -3
- package/docs/tools-and-commands.md +149 -139
- package/docs/voice-and-live-tts.md +1 -1
- package/package.json +1 -1
- package/release/live-verification/live-verification.json +2 -2
- package/release/live-verification/live-verification.md +2 -2
- package/release/release-notes.md +6 -15
- package/release/release-readiness.json +4 -4
- package/src/agent/harness-control.ts +42 -3
- package/src/runtime/bootstrap.ts +10 -18
- package/src/tools/agent-analysis-registry-policy.ts +2 -9
- package/src/tools/agent-channel-send-tool.ts +1 -5
- package/src/tools/agent-context-policy.ts +1 -5
- package/src/tools/agent-find-policy.ts +1 -4
- package/src/tools/agent-harness-channel-metadata.ts +23 -23
- package/src/tools/agent-harness-cli-metadata.ts +4 -1
- package/src/tools/agent-harness-command-catalog.ts +10 -3
- package/src/tools/agent-harness-connected-host-status.ts +8 -2
- package/src/tools/agent-harness-delegation-posture.ts +5 -5
- package/src/tools/agent-harness-mcp-metadata.ts +30 -28
- package/src/tools/agent-harness-media-posture.ts +9 -9
- package/src/tools/agent-harness-metadata.ts +25 -7
- package/src/tools/agent-harness-model-routing.ts +14 -14
- package/src/tools/agent-harness-model-tool-catalog.ts +7 -2
- package/src/tools/agent-harness-notification-metadata.ts +17 -17
- package/src/tools/agent-harness-pairing-posture.ts +7 -7
- package/src/tools/agent-harness-panel-metadata.ts +26 -12
- package/src/tools/agent-harness-provider-account-metadata.ts +33 -31
- package/src/tools/agent-harness-security-posture.ts +9 -7
- package/src/tools/agent-harness-service-posture.ts +22 -16
- package/src/tools/agent-harness-session-metadata.ts +9 -7
- package/src/tools/agent-harness-setup-posture.ts +6 -6
- package/src/tools/agent-harness-tool-schema.ts +1 -0
- package/src/tools/agent-harness-tool.ts +79 -36
- package/src/tools/agent-harness-ui-surface-metadata.ts +19 -11
- package/src/tools/agent-harness-workspace-actions.ts +29 -1
- package/src/tools/agent-knowledge-ingest-tool.ts +1 -5
- package/src/tools/agent-knowledge-tool.ts +1 -5
- package/src/tools/agent-local-registry-tool.ts +1 -4
- package/src/tools/agent-media-generate-tool.ts +1 -5
- package/src/tools/agent-notify-tool.ts +1 -5
- package/src/tools/agent-operator-action-tool.ts +1 -5
- package/src/tools/agent-operator-briefing-tool.ts +1 -5
- package/src/tools/agent-read-policy.ts +1 -4
- package/src/tools/agent-reminder-schedule-tool.ts +1 -5
- package/src/tools/agent-tool-policy-guard.ts +7 -34
- package/src/tools/agent-web-search-policy.ts +1 -4
- package/src/tools/agent-work-plan-tool.ts +1 -5
- 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
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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
|
-
|
|
101
|
-
|
|
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
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
'
|
|
126
|
-
'
|
|
127
|
-
'subscription-
|
|
128
|
-
|
|
129
|
-
|
|
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
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
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(
|
|
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
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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"
|
|
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
|
-
|
|
411
|
-
|
|
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'
|
|
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'
|
|
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));
|