autosnippet
Version:
Extract code patterns into a knowledge base for AI coding assistants
85 lines (84 loc) • 3.6 kB
JavaScript
/**
* SignalModule — Phase 0 信号基础设施注册
*
* 注册:
* - signalBus: 统一信号总线(基础设施层)
* - hitRecorder: 批量使用信号采集器(服务层)
* - intent JSONL persistence subscriber
*/
import fs from 'node:fs';
import path from 'node:path';
import { SignalAggregator } from '../../infrastructure/signal/SignalAggregator.js';
import { SignalBridge } from '../../infrastructure/signal/SignalBridge.js';
import { SignalBus } from '../../infrastructure/signal/SignalBus.js';
import { SignalTraceWriter } from '../../infrastructure/signal/SignalTraceWriter.js';
import { HitRecorder } from '../../service/signal/HitRecorder.js';
import { resolveProjectRoot } from '../../shared/resolveProjectRoot.js';
import { shutdown } from '../../shared/shutdown.js';
/**
* Register intent signal subscriber for JSONL persistence.
* Replaces standalone SignalLogger — writes IntentChainRecord to .autosnippet/logs/signals/YYYY-MM-DD.jsonl.
*/
function registerIntentPersistence(signalBus, projectRoot) {
signalBus.subscribe('intent', (signal) => {
try {
const chain = signal.metadata?.chain;
if (!chain) {
return;
}
const dir = path.join(projectRoot, '.autosnippet', 'logs', 'signals');
fs.mkdirSync(dir, { recursive: true });
const d = new Date(signal.timestamp);
const dateStr = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
const filePath = path.join(dir, `${dateStr}.jsonl`);
fs.appendFileSync(filePath, `${JSON.stringify(chain)}\n`, 'utf8');
}
catch {
// Write failure is non-blocking
}
});
}
export function register(c) {
// ═══ Infrastructure ═══
c.singleton('signalBus', () => new SignalBus());
// ═══ Service ═══
c.singleton('hitRecorder', (ct) => {
const bus = ct.get('signalBus');
const db = ct.get('database');
const recorder = new HitRecorder(bus, db);
recorder.start();
// shutdown hook: 在 DB close 之前 flush buffer
shutdown.register(async () => {
await recorder.stop();
}, 'hitRecorder');
return recorder;
});
// ═══ Intent Signal Persistence ═══
// Register after signalBus is created — subscribe for JSONL persistence
const signalBus = c.get('signalBus');
const projectRoot = resolveProjectRoot(c);
registerIntentPersistence(signalBus, projectRoot);
// ═══ SignalBridge — SignalBus → EventBus 桥接 ═══
c.singleton('signalBridge', (ct) => {
const bus = ct.get('signalBus');
const eventBus = ct.get('eventBus');
return new SignalBridge(bus, eventBus);
});
// ═══ SignalTraceWriter — 全类型信号 JSONL 留痕 ═══
c.singleton('signalTraceWriter', (ct) => {
const bus = ct.get('signalBus');
const root = resolveProjectRoot(ct);
return new SignalTraceWriter(bus, path.join(root, '.autosnippet', 'logs', 'signals'));
});
// ═══ SignalAggregator — 滑窗统计 + 异常检测 ═══
c.singleton('signalAggregator', (ct) => {
const bus = ct.get('signalBus');
const reportStore = ct.get('reportStore');
const agg = new SignalAggregator(bus, reportStore);
agg.start();
shutdown.register(async () => {
agg.stop();
}, 'signalAggregator');
return agg;
});
}