@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 CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  All notable changes to GoodVibes Agent will be recorded here.
4
4
 
5
+ ## 0.1.21 - 2026-05-31
6
+
7
+ - d83f325 Keep inspect scaffold dry-run-only in agent runtime
8
+
5
9
  ## 0.1.20 - 2026-05-31
6
10
 
7
11
  - c0eca13 Block settings mutation tool in agent runtime
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pellux/goodvibes-agent",
3
- "version": "0.1.20",
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.20';
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 {