mirror of
https://github.com/affaan-m/ECC.git
synced 2026-09-13 13:17:55 +02:00
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.
This commit is contained in:
+66
-45
@@ -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)) {
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user