From 27b7c673e25a0c6b8cf6fb93377e7b3e1edb5fda Mon Sep 17 00:00:00 2001 From: Affaan Mustafa Date: Sun, 26 Jul 2026 05:01:27 -0400 Subject: [PATCH] refactor: simplify memory command dispatch Split memory CLI actions into focused handlers, keep dispatch below the project function-size guideline, and strengthen install-manifest assertions for the separately installed runtime. --- scripts/memory.js | 111 +++++++++++++++++----------- tests/lib/install-manifests.test.js | 3 +- tests/scripts/memory.test.js | 11 ++- 3 files changed, 78 insertions(+), 47 deletions(-) diff --git a/scripts/memory.js b/scripts/memory.js index 7fa25fe9d..07471906a 100755 --- a/scripts/memory.js +++ b/scripts/memory.js @@ -401,6 +401,67 @@ function assertMutationAllowed(command) { } } +function runInitCommand({ command, options, positionals, roots }) { + requireNoPositionals(positionals, command); + return printInit( + initializeVault({ roots, scopes: options.scopes || undefined }), + options.json + ); +} + +function runWriteCommand({ command, options, positionals, roots }) { + requireNoPositionals(positionals, command); + if (!options.title) throw new Error('--title is required.'); + if (command === 'handoff' && !options.from) { + throw new Error('--from is required for handoffs.'); + } + if (command === 'handoff' && (!options.targets || options.targets.length === 0)) { + throw new Error('At least one --target is required for handoffs.'); + } + return printWrite( + saveMemory(saveInput(options, command === 'handoff' ? 'handoff' : null), { roots }), + options.json + ); +} + +function runSearchCommand({ options, positionals, roots }) { + const query = positionals.join(' '); + return printSearch(query, searchMemories(query, { + roots, + scopes: options.scopes, + kinds: options.kinds, + targetHarness: options.targetHarness, + limit: options.limit, + }), options.json); +} + +function runReadCommand({ options, positionals, roots }) { + if (positionals.length !== 1) { + throw new Error('read requires exactly one memory ID.'); + } + return printRead(readMemoryById(positionals[0], { + roots, + scopes: options.scopes, + }), options.json); +} + +function runDoctorCommand({ command, options, positionals, roots }) { + requireNoPositionals(positionals, command); + return printDoctor(doctorMemoryVault({ + roots, + scopes: options.scopes, + }), options.json); +} + +const COMMAND_HANDLERS = Object.freeze({ + doctor: runDoctorCommand, + handoff: runWriteCommand, + init: runInitCommand, + read: runReadCommand, + save: runWriteCommand, + search: runSearchCommand, +}); + function runCommand(parsed) { const { command, options, positionals } = parsed; if (options.help || command === 'help') { @@ -411,51 +472,11 @@ function runCommand(parsed) { assertMutationAllowed(command); } const roots = resolveVaultRoots(); - - if (command === 'init') { - requireNoPositionals(positionals, command); - return printInit( - initializeVault({ roots, scopes: options.scopes || undefined }), - options.json - ); - } - if (command === 'save' || command === 'handoff') { - requireNoPositionals(positionals, command); - if (!options.title) throw new Error('--title is required.'); - if (command === 'handoff' && !options.from) throw new Error('--from is required for handoffs.'); - if (command === 'handoff' && (!options.targets || options.targets.length === 0)) { - throw new Error('At least one --target is required for handoffs.'); - } - return printWrite( - saveMemory(saveInput(options, command === 'handoff' ? 'handoff' : null), { roots }), - options.json - ); - } - if (command === 'search') { - const query = positionals.join(' '); - return printSearch(query, searchMemories(query, { - roots, - scopes: options.scopes, - kinds: options.kinds, - targetHarness: options.targetHarness, - limit: options.limit, - }), options.json); - } - if (command === 'read') { - if (positionals.length !== 1) throw new Error('read requires exactly one memory ID.'); - return printRead(readMemoryById(positionals[0], { - roots, - scopes: options.scopes, - }), options.json); - } - if (command === 'doctor') { - requireNoPositionals(positionals, command); - return printDoctor(doctorMemoryVault({ - roots, - scopes: options.scopes, - }), options.json); - } - throw new Error(`Unknown memory command: ${command}`); + const handler = Object.hasOwn(COMMAND_HANDLERS, command) + ? COMMAND_HANDLERS[command] + : null; + if (!handler) throw new Error(`Unknown memory command: ${command}`); + return handler({ command, options, positionals, roots }); } function main(argv = process.argv.slice(2)) { diff --git a/tests/lib/install-manifests.test.js b/tests/lib/install-manifests.test.js index 84f4b186b..9cbbf6bf6 100644 --- a/tests/lib/install-manifests.test.js +++ b/tests/lib/install-manifests.test.js @@ -172,13 +172,14 @@ function runTests() { const component = getInstallComponent('skill:unified-memory'); assert.deepStrictEqual(component.moduleIds, ['skill-unified-memory']); assert.match(component.description, /ecc-universal/i); - assert.match(component.description, /separate|external|runtime/i); + assert.match(component.description, /separate|external/i); const modules = listInstallModules(); const singleSkillModule = modules.find(module => module.id === 'skill-unified-memory'); const workflowModule = modules.find(module => module.id === 'workflow-quality'); assert.ok(singleSkillModule, 'Should define an explicit unified-memory module'); assert.match(singleSkillModule.description, /ecc-universal/i); + assert.match(singleSkillModule.description, /separate|external/i); assert.match(workflowModule.description, /ecc-universal/i); const plan = resolveInstallPlan({ diff --git a/tests/scripts/memory.test.js b/tests/scripts/memory.test.js index af1b4f193..ec2b2224e 100644 --- a/tests/scripts/memory.test.js +++ b/tests/scripts/memory.test.js @@ -8,7 +8,11 @@ const { spawnSync } = require('child_process'); const MEMORY_SCRIPT = path.join(__dirname, '..', '..', 'scripts', 'memory.js'); const ECC_SCRIPT = path.join(__dirname, '..', '..', 'scripts', 'ecc.js'); -const { readBoundedStdin, sanitizeTerminalText } = require(MEMORY_SCRIPT); +const { + readBoundedStdin, + runCommand, + sanitizeTerminalText, +} = require(MEMORY_SCRIPT); let passed = 0; let failed = 0; @@ -62,6 +66,11 @@ function json(result) { console.log('\n=== Testing ecc memory CLI ===\n'); +test('keeps runCommand focused on dispatch under the function-size guideline', () => { + const lineCount = runCommand.toString().split('\n').length; + assert.ok(lineCount < 50, `runCommand is ${lineCount} lines; expected fewer than 50`); +}); + test('shows memory command help directly and through the ecc router', () => { const fixture = createFixture(); try {