import test from 'node:test'; import assert from 'node:assert/strict'; import { buildAgentExtensionPolicy, CAPABILITY_CATALOG, clampUserCapabilities, DEFAULT_USER_CAPABILITIES, normalizeCapabilityPatch, sandboxDeveloperTools, } from './capabilities.mjs'; import { applyPoliciesToCapabilities } from './policies.mjs'; test('default user policy blocks dangerous capabilities', () => { assert.equal(DEFAULT_USER_CAPABILITIES.shell, false); assert.equal(DEFAULT_USER_CAPABILITIES.filesystem, false); assert.equal(DEFAULT_USER_CAPABILITIES.extension_admin, false); assert.equal(DEFAULT_USER_CAPABILITIES.static_publish, false); assert.equal(DEFAULT_USER_CAPABILITIES.code_browse, false); }); test('buildAgentExtensionPolicy returns null for unrestricted users', () => { const policy = buildAgentExtensionPolicy({}, { unrestricted: true }); assert.equal(policy.extensionOverrides, null); }); test('static_publish enables sandbox developer tools without shell by default', () => { const caps = { ...DEFAULT_USER_CAPABILITIES, static_publish: true }; assert.deepEqual(sandboxDeveloperTools(caps), ['write', 'edit', 'read_image']); const policy = buildAgentExtensionPolicy(caps); const developer = policy.extensionOverrides.find((ext) => ext.name === 'developer'); assert.deepEqual(developer?.available_tools, ['write', 'edit', 'read_image']); assert.equal(developer?.available_tools.includes('shell'), false); assert.equal(developer?.available_tools.includes('tree'), false); const summon = policy.extensionOverrides.find((ext) => ext.name === 'summon'); assert.deepEqual(summon?.available_tools, ['load_skill']); assert.ok(policy.extensionOverrides.some((ext) => ext.name === 'projectmemory')); assert.equal(policy.enableContextMemory, true); }); test('static_publish with shell survives network deny and includes tree', () => { const caps = applyPoliciesToCapabilities( { ...DEFAULT_USER_CAPABILITIES, static_publish: true, shell: true }, { network_egress: 'deny' }, ); assert.equal(caps.shell, true); const policy = buildAgentExtensionPolicy(caps, { policies: { network_egress: 'deny', goose_mode: 'chat' }, }); const developer = policy.extensionOverrides.find((ext) => ext.name === 'developer'); assert.deepEqual(developer?.available_tools, ['write', 'edit', 'shell', 'tree', 'read_image']); }); test('buildAgentExtensionPolicy filters developer tools', () => { const policy = buildAgentExtensionPolicy({ ...DEFAULT_USER_CAPABILITIES, shell: true, filesystem: false, code_browse: true, }); const developer = policy.extensionOverrides.find((ext) => ext.name === 'developer'); assert.ok(developer); assert.deepEqual(developer.available_tools, ['shell', 'tree', 'read_image']); assert.equal( policy.extensionOverrides.some((ext) => ext.name === 'extensionmanager'), false, ); }); test('normalizeCapabilityPatch ignores unknown keys', () => { assert.deepEqual(normalizeCapabilityPatch({ shell: true, unknown: true }), { shell: true }); }); test('clampUserCapabilities blocks extension_admin even when stored as true', () => { const clamped = clampUserCapabilities({ ...DEFAULT_USER_CAPABILITIES, extension_admin: true, shell: true, }); assert.equal(clamped.extension_admin, false); assert.equal(clamped.shell, true); }); test('catalog keys are unique', () => { const keys = CAPABILITY_CATALOG.map((item) => item.key); assert.equal(keys.length, new Set(keys).size); });