593f12ae6a
readRouterState(sessionId, {baseDir}) -- pure read state-файла сторожа.
extractRouterFields(state) -- pure извлечение 4 полей для primary_rationale.
Используется парсером эпизодов на следующем шаге (Task 3).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
45 lines
1.4 KiB
JavaScript
45 lines
1.4 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Router state enricher for observer episodes.
|
|
* Reads ~/.claude/runtime/router-state-<sessionId>.json and exposes pure
|
|
* extraction helpers for primary_rationale enrichment.
|
|
*
|
|
* Pure-ish — fs is parameterized via options.baseDir for testability.
|
|
*
|
|
* Per spec: docs/superpowers/specs/2026-05-24-router-stage3-three-fixes-design.md
|
|
*/
|
|
|
|
import { readFileSync, existsSync } from 'fs';
|
|
import { join } from 'path';
|
|
import { homedir } from 'os';
|
|
|
|
function defaultBaseDir() {
|
|
return join(homedir(), '.claude', 'runtime');
|
|
}
|
|
|
|
export function readRouterState(sessionId, options = {}) {
|
|
if (!sessionId || typeof sessionId !== 'string') return null;
|
|
const baseDir = options.baseDir || defaultBaseDir();
|
|
const path = join(baseDir, `router-state-${sessionId}.json`);
|
|
if (!existsSync(path)) return null;
|
|
try {
|
|
const content = readFileSync(path, 'utf-8');
|
|
return JSON.parse(content);
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export function extractRouterFields(state) {
|
|
if (!state || typeof state !== 'object') {
|
|
return { recommended_node: null, recommended_chain: null, chain_progress: [], chain_completed: false };
|
|
}
|
|
const cls = state.classification || {};
|
|
return {
|
|
recommended_node: cls.recommendedNode || null,
|
|
recommended_chain: cls.recommendedChain || null,
|
|
chain_progress: Array.isArray(state.chainProgress) ? state.chainProgress : [],
|
|
chain_completed: state.chainCompleted === true,
|
|
};
|
|
}
|