@pellux/goodvibes-agent 0.1.21 → 0.1.22
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 +4 -0
- package/package.json +1 -1
- package/src/tools/wrfc-agent-guard.ts +21 -0
- package/src/version.ts +1 -1
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pellux/goodvibes-agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.22",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Near-fork GoodVibes operator assistant with the GoodVibes TUI shell, renderer, input, fullscreen workspace, and daemon-connected Agent product brain.",
|
|
6
6
|
"type": "module",
|
|
@@ -96,6 +96,7 @@ const READ_ONLY_TEAM_TOOL_MODES = ['list', 'show'] as const;
|
|
|
96
96
|
const READ_ONLY_WORKLIST_TOOL_MODES = ['list', 'show'] as const;
|
|
97
97
|
const READ_ONLY_PACKET_TOOL_MODES = ['list', 'show'] as const;
|
|
98
98
|
const READ_ONLY_QUERY_TOOL_MODES = ['list', 'show'] as const;
|
|
99
|
+
const READ_ONLY_CONTROL_TOOL_MODES = ['commands', 'panels', 'subscriptions', 'sandbox-presets'] as const;
|
|
99
100
|
const READ_ONLY_REMOTE_TOOL_MODE_SET = new Set<string>(READ_ONLY_REMOTE_TOOL_MODES);
|
|
100
101
|
const READ_ONLY_CHANNEL_TOOL_MODE_SET = new Set<string>(READ_ONLY_CHANNEL_TOOL_MODES);
|
|
101
102
|
const READ_ONLY_MCP_TOOL_MODE_SET = new Set<string>(READ_ONLY_MCP_TOOL_MODES);
|
|
@@ -110,6 +111,7 @@ const READ_ONLY_TEAM_TOOL_MODE_SET = new Set<string>(READ_ONLY_TEAM_TOOL_MODES);
|
|
|
110
111
|
const READ_ONLY_WORKLIST_TOOL_MODE_SET = new Set<string>(READ_ONLY_WORKLIST_TOOL_MODES);
|
|
111
112
|
const READ_ONLY_PACKET_TOOL_MODE_SET = new Set<string>(READ_ONLY_PACKET_TOOL_MODES);
|
|
112
113
|
const READ_ONLY_QUERY_TOOL_MODE_SET = new Set<string>(READ_ONLY_QUERY_TOOL_MODES);
|
|
114
|
+
const READ_ONLY_CONTROL_TOOL_MODE_SET = new Set<string>(READ_ONLY_CONTROL_TOOL_MODES);
|
|
113
115
|
|
|
114
116
|
const LOCAL_AGENT_DENIAL = [
|
|
115
117
|
'GoodVibes Agent does not spawn local Engineer/Reviewer/Tester/Verifier roots or run local WRFC chains.',
|
|
@@ -177,6 +179,12 @@ const DURABLE_WORKFLOW_MUTATION_DENIAL = [
|
|
|
177
179
|
'Use explicit Agent CLI/slash commands or GoodVibes TUI delegation for intentional workflow changes.',
|
|
178
180
|
].join(' ');
|
|
179
181
|
|
|
182
|
+
const CONTROL_MUTATION_DENIAL = [
|
|
183
|
+
'GoodVibes Agent only inspects copied product-control surfaces from the main conversation.',
|
|
184
|
+
'Product-control mutation, daemon lifecycle, and service posture changes are disabled here.',
|
|
185
|
+
'Use explicit Agent CLI/slash commands for Agent-owned changes, and keep daemon lifecycle external.',
|
|
186
|
+
].join(' ');
|
|
187
|
+
|
|
180
188
|
export function installAgentToolPolicyGuard(registry: ToolRegistry, options: AgentToolPolicyGuardOptions = {}): void {
|
|
181
189
|
const agentTool = registry.list().find((tool) => tool.definition.name === 'agent');
|
|
182
190
|
if (!agentTool) throw new Error('Agent tool policy guard could not find the agent tool.');
|
|
@@ -214,6 +222,16 @@ export function installAgentToolPolicyGuard(registry: ToolRegistry, options: Age
|
|
|
214
222
|
wrapBlockedSettingsToolForAgentPolicy(tool);
|
|
215
223
|
} else if (tool.definition.name === 'inspect') {
|
|
216
224
|
wrapInspectToolForAgentPolicy(tool);
|
|
225
|
+
} else if (tool.definition.name === 'control') {
|
|
226
|
+
wrapModeRestrictedToolForAgentPolicy(tool, {
|
|
227
|
+
allowedModes: READ_ONLY_CONTROL_TOOL_MODES,
|
|
228
|
+
modeSet: READ_ONLY_CONTROL_TOOL_MODE_SET,
|
|
229
|
+
description: [
|
|
230
|
+
'Read-only product-control inspection for GoodVibes Agent.',
|
|
231
|
+
'Command, panel, subscription, and sandbox preset catalogs can be inspected, but product-control mutation and daemon lifecycle are external.',
|
|
232
|
+
].join(' '),
|
|
233
|
+
denial: CONTROL_MUTATION_DENIAL,
|
|
234
|
+
});
|
|
217
235
|
} else if (tool.definition.name === 'task') {
|
|
218
236
|
wrapModeRestrictedToolForAgentPolicy(tool, {
|
|
219
237
|
allowedModes: READ_ONLY_TASK_TOOL_MODES,
|
|
@@ -505,6 +523,7 @@ export const AGENT_READ_ONLY_TEAM_TOOL_MODES = READ_ONLY_TEAM_TOOL_MODES;
|
|
|
505
523
|
export const AGENT_READ_ONLY_WORKLIST_TOOL_MODES = READ_ONLY_WORKLIST_TOOL_MODES;
|
|
506
524
|
export const AGENT_READ_ONLY_PACKET_TOOL_MODES = READ_ONLY_PACKET_TOOL_MODES;
|
|
507
525
|
export const AGENT_READ_ONLY_QUERY_TOOL_MODES = READ_ONLY_QUERY_TOOL_MODES;
|
|
526
|
+
export const AGENT_READ_ONLY_CONTROL_TOOL_MODES = READ_ONLY_CONTROL_TOOL_MODES;
|
|
508
527
|
export const AGENT_REMOTE_MUTATION_DENIAL_MESSAGE = REMOTE_MUTATION_DENIAL;
|
|
509
528
|
export const AGENT_CHANNEL_ACTION_DENIAL_MESSAGE = CHANNEL_ACTION_DENIAL;
|
|
510
529
|
export const AGENT_MCP_SECURITY_MUTATION_DENIAL_MESSAGE = MCP_SECURITY_MUTATION_DENIAL;
|
|
@@ -513,6 +532,7 @@ export const AGENT_STATE_MUTATION_DENIAL_MESSAGE = STATE_MUTATION_DENIAL;
|
|
|
513
532
|
export const AGENT_SETTINGS_MUTATION_DENIAL_MESSAGE = SETTINGS_MUTATION_DENIAL;
|
|
514
533
|
export const AGENT_INSPECT_WRITE_DENIAL_MESSAGE = INSPECT_WRITE_DENIAL;
|
|
515
534
|
export const AGENT_DURABLE_WORKFLOW_MUTATION_DENIAL_MESSAGE = DURABLE_WORKFLOW_MUTATION_DENIAL;
|
|
535
|
+
export const AGENT_CONTROL_MUTATION_DENIAL_MESSAGE = CONTROL_MUTATION_DENIAL;
|
|
516
536
|
|
|
517
537
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
518
538
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
@@ -659,6 +679,7 @@ function narrowInspectToolDefinitionForAgentPolicy(tool: Tool): void {
|
|
|
659
679
|
|
|
660
680
|
function narrowModeToolDefinitionForAgentPolicy(tool: Tool, allowedModes: readonly string[], description: string): void {
|
|
661
681
|
tool.definition.description = description;
|
|
682
|
+
tool.definition.sideEffects = [];
|
|
662
683
|
|
|
663
684
|
const properties = tool.definition.parameters.properties;
|
|
664
685
|
if (!isRecord(properties)) return;
|
package/src/version.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { join } from 'node:path';
|
|
|
6
6
|
// The prebuild script updates the fallback value before compilation.
|
|
7
7
|
// Uses import.meta.dir (Bun) to locate package.json relative to this file,
|
|
8
8
|
// which is correct regardless of the process working directory.
|
|
9
|
-
let _version = '0.1.
|
|
9
|
+
let _version = '0.1.22';
|
|
10
10
|
let _sdkVersion = '0.33.35';
|
|
11
11
|
try {
|
|
12
12
|
const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', 'package.json'), 'utf-8')) as {
|