@pellux/goodvibes-agent 0.1.20 → 0.1.21
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 +47 -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.21",
|
|
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",
|
|
@@ -54,6 +54,12 @@ type StateToolArgs = {
|
|
|
54
54
|
readonly [key: string]: unknown;
|
|
55
55
|
};
|
|
56
56
|
|
|
57
|
+
type InspectToolArgs = {
|
|
58
|
+
readonly mode?: unknown;
|
|
59
|
+
readonly dryRun?: unknown;
|
|
60
|
+
readonly [key: string]: unknown;
|
|
61
|
+
};
|
|
62
|
+
|
|
57
63
|
type AgentToolPolicyGuardOptions = {
|
|
58
64
|
readonly getLastUserMessage?: () => string | null;
|
|
59
65
|
};
|
|
@@ -159,6 +165,12 @@ const SETTINGS_MUTATION_DENIAL = [
|
|
|
159
165
|
'Secrets, tokens, passwords, daemon lifecycle settings, and service exposure settings require explicit user action outside the model tool surface.',
|
|
160
166
|
].join(' ');
|
|
161
167
|
|
|
168
|
+
const INSPECT_WRITE_DENIAL = [
|
|
169
|
+
'GoodVibes Agent only uses inspect scaffold mode for dry-run planning from the main conversation.',
|
|
170
|
+
'File scaffolding and code creation are disabled in the Agent model tool surface.',
|
|
171
|
+
'Delegate explicit build/implement/fix/review work to GoodVibes TUI instead.',
|
|
172
|
+
].join(' ');
|
|
173
|
+
|
|
162
174
|
const DURABLE_WORKFLOW_MUTATION_DENIAL = [
|
|
163
175
|
'GoodVibes Agent only inspects copied durable workflow tools from the main conversation.',
|
|
164
176
|
'Task, team, worklist, packet, and query creation or lifecycle mutation is disabled here.',
|
|
@@ -200,6 +212,8 @@ export function installAgentToolPolicyGuard(registry: ToolRegistry, options: Age
|
|
|
200
212
|
wrapStateToolForAgentPolicy(tool);
|
|
201
213
|
} else if (tool.definition.name === 'goodvibes_settings') {
|
|
202
214
|
wrapBlockedSettingsToolForAgentPolicy(tool);
|
|
215
|
+
} else if (tool.definition.name === 'inspect') {
|
|
216
|
+
wrapInspectToolForAgentPolicy(tool);
|
|
203
217
|
} else if (tool.definition.name === 'task') {
|
|
204
218
|
wrapModeRestrictedToolForAgentPolicy(tool, {
|
|
205
219
|
allowedModes: READ_ONLY_TASK_TOOL_MODES,
|
|
@@ -320,6 +334,17 @@ export function wrapBlockedSettingsToolForAgentPolicy(tool: Tool): void {
|
|
|
320
334
|
tool.execute = async () => ({ success: false, error: SETTINGS_MUTATION_DENIAL });
|
|
321
335
|
}
|
|
322
336
|
|
|
337
|
+
export function wrapInspectToolForAgentPolicy(tool: Tool): void {
|
|
338
|
+
narrowInspectToolDefinitionForAgentPolicy(tool);
|
|
339
|
+
const originalExecute = tool.execute.bind(tool);
|
|
340
|
+
tool.execute = async (args) => {
|
|
341
|
+
const inspectArgs = args as InspectToolArgs;
|
|
342
|
+
const denial = validateInspectToolInvocationForAgentPolicy(inspectArgs);
|
|
343
|
+
if (denial) return { success: false, error: denial };
|
|
344
|
+
return originalExecute(normalizeInspectToolInvocationForAgentPolicy(inspectArgs) as Parameters<Tool['execute']>[0]);
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
|
|
323
348
|
export function validateExecToolInvocationForAgentPolicy(args: ExecToolArgs): string | null {
|
|
324
349
|
if (args.parallel === true) return BACKGROUND_EXEC_DENIAL;
|
|
325
350
|
if (Array.isArray(args.file_ops) && args.file_ops.length > 0) return BACKGROUND_EXEC_DENIAL;
|
|
@@ -404,6 +429,16 @@ export function validateStateToolInvocationForAgentPolicy(args: StateToolArgs):
|
|
|
404
429
|
return null;
|
|
405
430
|
}
|
|
406
431
|
|
|
432
|
+
export function validateInspectToolInvocationForAgentPolicy(args: InspectToolArgs): string | null {
|
|
433
|
+
if (args.mode === 'scaffold' && args.dryRun === false) return INSPECT_WRITE_DENIAL;
|
|
434
|
+
return null;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
export function normalizeInspectToolInvocationForAgentPolicy(args: InspectToolArgs): InspectToolArgs {
|
|
438
|
+
if (args.mode !== 'scaffold') return args;
|
|
439
|
+
return { ...args, dryRun: true };
|
|
440
|
+
}
|
|
441
|
+
|
|
407
442
|
type ModeRestrictedToolPolicy = {
|
|
408
443
|
readonly allowedModes: readonly string[];
|
|
409
444
|
readonly modeSet: ReadonlySet<string>;
|
|
@@ -476,6 +511,7 @@ export const AGENT_MCP_SECURITY_MUTATION_DENIAL_MESSAGE = MCP_SECURITY_MUTATION_
|
|
|
476
511
|
export const AGENT_FETCH_NETWORK_MUTATION_DENIAL_MESSAGE = FETCH_NETWORK_MUTATION_DENIAL;
|
|
477
512
|
export const AGENT_STATE_MUTATION_DENIAL_MESSAGE = STATE_MUTATION_DENIAL;
|
|
478
513
|
export const AGENT_SETTINGS_MUTATION_DENIAL_MESSAGE = SETTINGS_MUTATION_DENIAL;
|
|
514
|
+
export const AGENT_INSPECT_WRITE_DENIAL_MESSAGE = INSPECT_WRITE_DENIAL;
|
|
479
515
|
export const AGENT_DURABLE_WORKFLOW_MUTATION_DENIAL_MESSAGE = DURABLE_WORKFLOW_MUTATION_DENIAL;
|
|
480
516
|
|
|
481
517
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
@@ -610,6 +646,17 @@ function narrowStateToolDefinitionForAgentPolicy(tool: Tool): void {
|
|
|
610
646
|
narrowStringEnumProperty(properties, 'analyticsAction', READ_ONLY_STATE_ANALYTICS_ACTIONS, 'Read-only analytics actions allowed by GoodVibes Agent.');
|
|
611
647
|
}
|
|
612
648
|
|
|
649
|
+
function narrowInspectToolDefinitionForAgentPolicy(tool: Tool): void {
|
|
650
|
+
tool.definition.description = [
|
|
651
|
+
'Inspect and analyze project structure for GoodVibes Agent.',
|
|
652
|
+
'Scaffold mode is dry-run-only in the main conversation; code creation must be delegated to GoodVibes TUI.',
|
|
653
|
+
].join(' ');
|
|
654
|
+
|
|
655
|
+
const properties = tool.definition.parameters.properties;
|
|
656
|
+
if (!isRecord(properties)) return;
|
|
657
|
+
delete properties.dryRun;
|
|
658
|
+
}
|
|
659
|
+
|
|
613
660
|
function narrowModeToolDefinitionForAgentPolicy(tool: Tool, allowedModes: readonly string[], description: string): void {
|
|
614
661
|
tool.definition.description = description;
|
|
615
662
|
|
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.21';
|
|
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 {
|