@codeledger/codeledger-daemon 0.7.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +27 -0
- package/dist/api/server.d.ts +4 -0
- package/dist/api/server.d.ts.map +1 -0
- package/dist/api/server.js +69 -0
- package/dist/api/server.js.map +1 -0
- package/dist/daemon.d.ts +12 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +316 -0
- package/dist/daemon.js.map +1 -0
- package/dist/events/appendEvent.d.ts +9 -0
- package/dist/events/appendEvent.d.ts.map +1 -0
- package/dist/events/appendEvent.js +14 -0
- package/dist/events/appendEvent.js.map +1 -0
- package/dist/events/eventConsumer.d.ts +13 -0
- package/dist/events/eventConsumer.d.ts.map +1 -0
- package/dist/events/eventConsumer.js +42 -0
- package/dist/events/eventConsumer.js.map +1 -0
- package/dist/events/eventReducer.d.ts +4 -0
- package/dist/events/eventReducer.d.ts.map +1 -0
- package/dist/events/eventReducer.js +185 -0
- package/dist/events/eventReducer.js.map +1 -0
- package/dist/events/eventTypes.d.ts +31 -0
- package/dist/events/eventTypes.d.ts.map +1 -0
- package/dist/events/eventTypes.js +15 -0
- package/dist/events/eventTypes.js.map +1 -0
- package/dist/health/heartbeat.d.ts +9 -0
- package/dist/health/heartbeat.d.ts.map +1 -0
- package/dist/health/heartbeat.js +8 -0
- package/dist/health/heartbeat.js.map +1 -0
- package/dist/health/status.d.ts +4 -0
- package/dist/health/status.d.ts.map +1 -0
- package/dist/health/status.js +46 -0
- package/dist/health/status.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/ipc/fileIpcTransport.d.ts +4 -0
- package/dist/ipc/fileIpcTransport.d.ts.map +1 -0
- package/dist/ipc/fileIpcTransport.js +64 -0
- package/dist/ipc/fileIpcTransport.js.map +1 -0
- package/dist/ipc/transport.d.ts +21 -0
- package/dist/ipc/transport.d.ts.map +1 -0
- package/dist/ipc/transport.js +2 -0
- package/dist/ipc/transport.js.map +1 -0
- package/dist/ipc/transportSelector.d.ts +6 -0
- package/dist/ipc/transportSelector.d.ts.map +1 -0
- package/dist/ipc/transportSelector.js +17 -0
- package/dist/ipc/transportSelector.js.map +1 -0
- package/dist/ipc/unixSocketTransport.d.ts +3 -0
- package/dist/ipc/unixSocketTransport.d.ts.map +1 -0
- package/dist/ipc/unixSocketTransport.js +81 -0
- package/dist/ipc/unixSocketTransport.js.map +1 -0
- package/dist/signals/taskHintDetector.d.ts +2 -0
- package/dist/signals/taskHintDetector.d.ts.map +1 -0
- package/dist/signals/taskHintDetector.js +29 -0
- package/dist/signals/taskHintDetector.js.map +1 -0
- package/dist/store/daemonState.d.ts +79 -0
- package/dist/store/daemonState.d.ts.map +1 -0
- package/dist/store/daemonState.js +83 -0
- package/dist/store/daemonState.js.map +1 -0
- package/dist/store/eventJournal.d.ts +12 -0
- package/dist/store/eventJournal.d.ts.map +1 -0
- package/dist/store/eventJournal.js +105 -0
- package/dist/store/eventJournal.js.map +1 -0
- package/dist/store/rebuildState.d.ts +11 -0
- package/dist/store/rebuildState.d.ts.map +1 -0
- package/dist/store/rebuildState.js +39 -0
- package/dist/store/rebuildState.js.map +1 -0
- package/dist/store/runJournal.d.ts +2 -0
- package/dist/store/runJournal.d.ts.map +1 -0
- package/dist/store/runJournal.js +14 -0
- package/dist/store/runJournal.js.map +1 -0
- package/dist/store/snapshotStore.d.ts +16 -0
- package/dist/store/snapshotStore.d.ts.map +1 -0
- package/dist/store/snapshotStore.js +111 -0
- package/dist/store/snapshotStore.js.map +1 -0
- package/dist/warmers/bundleWarmer.d.ts +10 -0
- package/dist/warmers/bundleWarmer.d.ts.map +1 -0
- package/dist/warmers/bundleWarmer.js +36 -0
- package/dist/warmers/bundleWarmer.js.map +1 -0
- package/dist/warmers/scanWarmer.d.ts +5 -0
- package/dist/warmers/scanWarmer.d.ts.map +1 -0
- package/dist/warmers/scanWarmer.js +13 -0
- package/dist/warmers/scanWarmer.js.map +1 -0
- package/dist/watchers/fileWatcher.d.ts +2 -0
- package/dist/watchers/fileWatcher.d.ts.map +1 -0
- package/dist/watchers/fileWatcher.js +24 -0
- package/dist/watchers/fileWatcher.js.map +1 -0
- package/dist/watchers/gitWatcher.d.ts +8 -0
- package/dist/watchers/gitWatcher.d.ts.map +1 -0
- package/dist/watchers/gitWatcher.js +47 -0
- package/dist/watchers/gitWatcher.js.map +1 -0
- package/package.json +38 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Intelligent Context AI, Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
Note: This license applies to the CLI wrapper, types, repository scanning,
|
|
26
|
+
instrumentation, harness, and report packages (the "Plugin"). The scoring
|
|
27
|
+
engine (packages/core-engine/bin/) is licensed separately under LICENSE-CORE.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type Server } from 'node:http';
|
|
2
|
+
import { type DaemonState } from '../store/daemonState.js';
|
|
3
|
+
export declare function startDaemonServer(cwd: string, socketPath: string, getState: () => DaemonState, setState: (state: DaemonState) => void, onError: (err: Error) => void): Server;
|
|
4
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/api/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAmB,KAAK,WAAW,EAAoB,MAAM,yBAAyB,CAAC;AAG9F,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,WAAW,EAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,EACtC,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,GAC5B,MAAM,CAyDR"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { existsSync, unlinkSync } from 'node:fs';
|
|
2
|
+
import { createServer } from 'node:http';
|
|
3
|
+
import { loadDaemonState, writeDaemonState } from '../store/daemonState.js';
|
|
4
|
+
import { appendDaemonJournal } from '../store/runJournal.js';
|
|
5
|
+
export function startDaemonServer(cwd, socketPath, getState, setState, onError) {
|
|
6
|
+
const server = createServer((req, res) => {
|
|
7
|
+
const url = req.url ?? '/';
|
|
8
|
+
if (req.method === 'GET' && url === '/status') {
|
|
9
|
+
sendJson(res, 200, getState());
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
if (req.method === 'GET' && url === '/recent-bundle') {
|
|
13
|
+
sendJson(res, 200, { recentBundle: getState().recentBundles[0] ?? null });
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (req.method === 'POST' && (url === '/task/start' || url === '/task/finish')) {
|
|
17
|
+
let body = '';
|
|
18
|
+
req.on('data', (chunk) => {
|
|
19
|
+
body += chunk;
|
|
20
|
+
});
|
|
21
|
+
req.on('end', () => {
|
|
22
|
+
let payload = {};
|
|
23
|
+
try {
|
|
24
|
+
payload = body ? JSON.parse(body) : {};
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
payload = {};
|
|
28
|
+
}
|
|
29
|
+
const state = loadDaemonState(cwd) ?? getState();
|
|
30
|
+
state.activeTaskId = url === '/task/start' ? String(payload['taskId'] ?? '') : undefined;
|
|
31
|
+
if (typeof payload['runId'] === 'string' && typeof payload['task'] === 'string' && typeof payload['status'] === 'string') {
|
|
32
|
+
state.recentRuns.unshift({
|
|
33
|
+
runId: payload['runId'],
|
|
34
|
+
task: payload['task'],
|
|
35
|
+
status: payload['status'],
|
|
36
|
+
at: new Date().toISOString(),
|
|
37
|
+
});
|
|
38
|
+
state.recentRuns = state.recentRuns.slice(0, 10);
|
|
39
|
+
}
|
|
40
|
+
state.updatedAt = new Date().toISOString();
|
|
41
|
+
writeDaemonState(cwd, state);
|
|
42
|
+
setState(state);
|
|
43
|
+
appendDaemonJournal(cwd, { kind: url === '/task/start' ? 'task_started' : 'task_finished', payload });
|
|
44
|
+
sendJson(res, 200, { ok: true });
|
|
45
|
+
});
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
sendJson(res, 404, { error: 'not_found' });
|
|
49
|
+
});
|
|
50
|
+
if (existsSync(socketPath)) {
|
|
51
|
+
try {
|
|
52
|
+
unlinkSync(socketPath);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// ignore stale socket cleanup
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
server.on('error', (err) => {
|
|
59
|
+
onError(err);
|
|
60
|
+
});
|
|
61
|
+
server.listen(socketPath);
|
|
62
|
+
return server;
|
|
63
|
+
}
|
|
64
|
+
function sendJson(res, code, data) {
|
|
65
|
+
res.statusCode = code;
|
|
66
|
+
res.setHeader('content-type', 'application/json');
|
|
67
|
+
res.end(JSON.stringify(data));
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/api/server.ts"],"names":[],"mappings":"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"}
|
package/dist/daemon.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type DaemonEventType } from './events/eventTypes.js';
|
|
2
|
+
import { type DaemonState, type WarmBundleEntry } from './store/daemonState.js';
|
|
3
|
+
export declare function runDaemonCommand(cwd: string, flags: Record<string, string>): Promise<void>;
|
|
4
|
+
export declare function loadWarmBundleForTask(cwd: string, task: string): string | null;
|
|
5
|
+
export declare function notifyDaemonTask(cwd: string, kind: 'start' | 'finish', payload: Record<string, unknown>): Promise<boolean>;
|
|
6
|
+
export declare function notifyDaemonEvent(cwd: string, type: DaemonEventType, payload: Record<string, unknown>, meta?: {
|
|
7
|
+
branch?: string;
|
|
8
|
+
taskId?: string;
|
|
9
|
+
runId?: string;
|
|
10
|
+
}): Promise<boolean>;
|
|
11
|
+
export declare function loadPersistedWarmBundles(cwd: string, previous: DaemonState | null): WarmBundleEntry[];
|
|
12
|
+
//# sourceMappingURL=daemon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AAMA,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAUlF,OAAO,EAOL,KAAK,WAAW,EAChB,KAAK,eAAe,EACrB,MAAM,wBAAwB,CAAC;AAQhC,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBhG;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK9E;AAED,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAWhI;AAED,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,IAAI,CAAC,EAAE;IACL,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GACA,OAAO,CAAC,OAAO,CAAC,CAwBlB;AA8ND,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,GAAG,IAAI,GAAG,eAAe,EAAE,CAmCrG"}
|
package/dist/daemon.js
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import { existsSync, readFileSync, readdirSync, statSync, unlinkSync } from 'node:fs';
|
|
2
|
+
import { request } from 'node:http';
|
|
3
|
+
import { spawn } from 'node:child_process';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { createDaemonEvent } from './events/appendEvent.js';
|
|
6
|
+
import { createEventConsumer } from './events/eventConsumer.js';
|
|
7
|
+
import { DAEMON_EVENT_TYPES } from './events/eventTypes.js';
|
|
8
|
+
import { createHeartbeatEvent } from './health/heartbeat.js';
|
|
9
|
+
import { renderDaemonStatus } from './health/status.js';
|
|
10
|
+
import { startFileIpcTransport, writeFileIpcRequest } from './ipc/fileIpcTransport.js';
|
|
11
|
+
import { selectTransport } from './ipc/transportSelector.js';
|
|
12
|
+
import { captureGitSnapshot } from './watchers/gitWatcher.js';
|
|
13
|
+
import { readManifestEpoch } from './watchers/fileWatcher.js';
|
|
14
|
+
import { warmScan } from './warmers/scanWarmer.js';
|
|
15
|
+
import { warmBundles } from './warmers/bundleWarmer.js';
|
|
16
|
+
import { detectTaskHints } from './signals/taskHintDetector.js';
|
|
17
|
+
import { DEFAULT_DAEMON_RETENTION, daemonPidPath, daemonRequestsDir, daemonResponsesDir, daemonSocketPath, loadDaemonState, } from './store/daemonState.js';
|
|
18
|
+
import { rebuildState } from './store/rebuildState.js';
|
|
19
|
+
const DEFAULT_PORT = 42637;
|
|
20
|
+
const DEFAULT_STALE_AFTER = 2 * 60 * 60;
|
|
21
|
+
const POLL_MS = 5000;
|
|
22
|
+
const DEBOUNCE_MS = 1500;
|
|
23
|
+
export async function runDaemonCommand(cwd, flags) {
|
|
24
|
+
const sub = flags['_sub'] ?? 'status';
|
|
25
|
+
switch (sub) {
|
|
26
|
+
case 'start':
|
|
27
|
+
await runStart(cwd, flags);
|
|
28
|
+
break;
|
|
29
|
+
case 'status':
|
|
30
|
+
await runStatus(cwd);
|
|
31
|
+
break;
|
|
32
|
+
case 'stop':
|
|
33
|
+
await runStop(cwd);
|
|
34
|
+
break;
|
|
35
|
+
default:
|
|
36
|
+
console.error(`Unknown daemon subcommand: ${sub}`);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export function loadWarmBundleForTask(cwd, task) {
|
|
41
|
+
const state = loadDaemonState(cwd);
|
|
42
|
+
if (!state)
|
|
43
|
+
return null;
|
|
44
|
+
const match = state.recentBundles.find((entry) => normalize(entry.task) === normalize(task) && existsSync(entry.bundlePath));
|
|
45
|
+
return match?.bundlePath ?? null;
|
|
46
|
+
}
|
|
47
|
+
export async function notifyDaemonTask(cwd, kind, payload) {
|
|
48
|
+
return await notifyDaemonEvent(cwd, kind === 'start' ? DAEMON_EVENT_TYPES.TASK_STARTED : DAEMON_EVENT_TYPES.TASK_FINISHED, payload, {
|
|
49
|
+
taskId: stringValue(payload['taskId']),
|
|
50
|
+
runId: stringValue(payload['runId']),
|
|
51
|
+
branch: stringValue(payload['branch']) ?? captureGitSnapshot(cwd).branch,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
export async function notifyDaemonEvent(cwd, type, payload, meta) {
|
|
55
|
+
const branch = meta?.branch ?? stringValue(payload['branch']) ?? captureGitSnapshot(cwd).branch;
|
|
56
|
+
const event = createDaemonEvent(cwd, type, payload, {
|
|
57
|
+
branch,
|
|
58
|
+
taskId: meta?.taskId ?? stringValue(payload['taskId']),
|
|
59
|
+
runId: meta?.runId ?? stringValue(payload['runId']),
|
|
60
|
+
});
|
|
61
|
+
const state = loadDaemonState(cwd);
|
|
62
|
+
if (state?.transport === 'unix-socket' && state.socketPath) {
|
|
63
|
+
try {
|
|
64
|
+
await postEventToSocket(state.socketPath, event);
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// fall through to file IPC
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
writeFileIpcRequest(state?.requestsPath ?? daemonRequestsDir(cwd), {
|
|
72
|
+
id: event.id,
|
|
73
|
+
ts: event.ts,
|
|
74
|
+
event,
|
|
75
|
+
});
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
async function runStart(cwd, flags) {
|
|
79
|
+
const port = parsePort(flags['port']);
|
|
80
|
+
if (flags['background'] === 'true' && process.env['CODELEDGER_DAEMON_CHILD'] !== '1') {
|
|
81
|
+
const cliPath = process.argv[1];
|
|
82
|
+
const child = spawn(process.execPath, [cliPath, 'daemon', 'start', '--port', String(port)], {
|
|
83
|
+
cwd,
|
|
84
|
+
detached: true,
|
|
85
|
+
env: { ...process.env, CODELEDGER_DAEMON_CHILD: '1' },
|
|
86
|
+
stdio: 'ignore',
|
|
87
|
+
});
|
|
88
|
+
child.unref();
|
|
89
|
+
console.log(`CodeLedger daemon started in background (pid ${child.pid ?? 'unknown'})`);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const rebuilt = rebuildState(cwd, port);
|
|
93
|
+
const git = captureGitSnapshot(cwd);
|
|
94
|
+
const retention = {
|
|
95
|
+
hotJournalDays: parsePositiveInt(flags['hot-days']) ?? rebuilt.state.retention.hotJournalDays ?? DEFAULT_DAEMON_RETENTION.hotJournalDays,
|
|
96
|
+
snapshotLimit: parsePositiveInt(flags['snapshot-limit']) ?? rebuilt.state.retention.snapshotLimit ?? DEFAULT_DAEMON_RETENTION.snapshotLimit,
|
|
97
|
+
snapshotIntervalEvents: parsePositiveInt(flags['snapshot-interval']) ?? rebuilt.state.retention.snapshotIntervalEvents ?? DEFAULT_DAEMON_RETENTION.snapshotIntervalEvents,
|
|
98
|
+
};
|
|
99
|
+
const initialState = {
|
|
100
|
+
...rebuilt.state,
|
|
101
|
+
port,
|
|
102
|
+
repoRoot: cwd,
|
|
103
|
+
gitBranch: git.branch || rebuilt.state.gitBranch,
|
|
104
|
+
gitHead: git.head || rebuilt.state.gitHead,
|
|
105
|
+
retention,
|
|
106
|
+
changedFiles: git.changedFiles,
|
|
107
|
+
recentBundles: rebuilt.state.recentBundles.length > 0
|
|
108
|
+
? rebuilt.state.recentBundles
|
|
109
|
+
: loadPersistedWarmBundles(cwd, rebuilt.state),
|
|
110
|
+
};
|
|
111
|
+
const consumer = createEventConsumer(cwd, initialState, rebuilt.seenEventIds, retention);
|
|
112
|
+
const context = {
|
|
113
|
+
cwd,
|
|
114
|
+
getState: () => consumer.getState(),
|
|
115
|
+
handleEvent: (event) => consumer.consume(event),
|
|
116
|
+
};
|
|
117
|
+
const requestTransport = startFileIpcTransport(context, daemonRequestsDir(cwd), daemonResponsesDir(cwd));
|
|
118
|
+
const selected = await selectTransport(context);
|
|
119
|
+
const transport = selected.transport.kind === 'file-ipc' ? requestTransport : selected.transport;
|
|
120
|
+
consumer.consume(createDaemonEvent(cwd, DAEMON_EVENT_TYPES.DAEMON_STARTED, {
|
|
121
|
+
pid: process.pid,
|
|
122
|
+
transport: transport.kind,
|
|
123
|
+
socketPath: transport.socketPath ?? daemonSocketPath(cwd),
|
|
124
|
+
requestsPath: daemonRequestsDir(cwd),
|
|
125
|
+
responsesPath: daemonResponsesDir(cwd),
|
|
126
|
+
gitBranch: git.branch,
|
|
127
|
+
gitHead: git.head,
|
|
128
|
+
}, {
|
|
129
|
+
branch: git.branch,
|
|
130
|
+
}));
|
|
131
|
+
let lastManifestEpoch = readManifestEpoch(cwd);
|
|
132
|
+
let debounceUntil = 0;
|
|
133
|
+
let staleMarked = false;
|
|
134
|
+
const tick = async () => {
|
|
135
|
+
await requestTransport.poll?.();
|
|
136
|
+
const snapshot = captureGitSnapshot(cwd);
|
|
137
|
+
const manifestEpoch = readManifestEpoch(cwd);
|
|
138
|
+
const hints = detectTaskHints(snapshot.changedFiles);
|
|
139
|
+
const changed = snapshot.head !== consumer.getState().gitHead
|
|
140
|
+
|| snapshot.branch !== consumer.getState().gitBranch
|
|
141
|
+
|| manifestEpoch !== lastManifestEpoch
|
|
142
|
+
|| snapshot.changedFiles.join('\n') !== consumer.getState().changedFiles.join('\n');
|
|
143
|
+
if (changed) {
|
|
144
|
+
debounceUntil = Date.now() + DEBOUNCE_MS;
|
|
145
|
+
lastManifestEpoch = manifestEpoch;
|
|
146
|
+
if (!staleMarked) {
|
|
147
|
+
consumer.consume(createDaemonEvent(cwd, DAEMON_EVENT_TYPES.SCAN_MARKED_STALE, {
|
|
148
|
+
changedFiles: snapshot.changedFiles,
|
|
149
|
+
gitBranch: snapshot.branch,
|
|
150
|
+
gitHead: snapshot.head,
|
|
151
|
+
}, { branch: snapshot.branch }));
|
|
152
|
+
staleMarked = true;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
consumer.consume(createHeartbeatEvent(cwd, {
|
|
156
|
+
pid: process.pid,
|
|
157
|
+
transport: transport.kind,
|
|
158
|
+
gitBranch: snapshot.branch,
|
|
159
|
+
gitHead: snapshot.head,
|
|
160
|
+
changedFiles: snapshot.changedFiles,
|
|
161
|
+
taskHints: hints,
|
|
162
|
+
}));
|
|
163
|
+
if (Date.now() < debounceUntil) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const scan = warmScan(cwd, DEFAULT_STALE_AFTER);
|
|
167
|
+
consumer.consume(createDaemonEvent(cwd, DAEMON_EVENT_TYPES.SCAN_COMPLETED, {
|
|
168
|
+
refreshed: scan.refreshed,
|
|
169
|
+
indexPath: scan.indexPath,
|
|
170
|
+
gitBranch: snapshot.branch,
|
|
171
|
+
gitHead: snapshot.head,
|
|
172
|
+
}, { branch: snapshot.branch }));
|
|
173
|
+
staleMarked = false;
|
|
174
|
+
const warmed = await warmBundles(cwd, hints, consumer.getState().recentBundles);
|
|
175
|
+
for (const action of warmed.actions) {
|
|
176
|
+
consumer.consume(createDaemonEvent(cwd, action.type === 'reused' ? DAEMON_EVENT_TYPES.BUNDLE_REUSED : DAEMON_EVENT_TYPES.BUNDLE_WARMED, {
|
|
177
|
+
task: action.entry.task,
|
|
178
|
+
bundlePath: action.entry.bundlePath,
|
|
179
|
+
bundleId: action.entry.bundleId,
|
|
180
|
+
generatedAt: action.entry.generatedAt,
|
|
181
|
+
confidenceLevel: action.entry.confidenceLevel,
|
|
182
|
+
confidenceScore: action.entry.confidenceScore,
|
|
183
|
+
relevantTests: action.entry.relevantTests ?? [],
|
|
184
|
+
filesSkipped: action.entry.filesSkipped ?? 0,
|
|
185
|
+
estimatedTimeSavedSeconds: action.entry.estimatedTimeSavedSeconds ?? 0,
|
|
186
|
+
}, { branch: snapshot.branch }));
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
await tick();
|
|
190
|
+
const timer = setInterval(() => {
|
|
191
|
+
void tick();
|
|
192
|
+
}, POLL_MS);
|
|
193
|
+
const shutdown = () => {
|
|
194
|
+
clearInterval(timer);
|
|
195
|
+
transport.close();
|
|
196
|
+
if (transport !== requestTransport) {
|
|
197
|
+
requestTransport.close();
|
|
198
|
+
}
|
|
199
|
+
consumer.consume(createDaemonEvent(cwd, DAEMON_EVENT_TYPES.DAEMON_STOPPED, {
|
|
200
|
+
pid: process.pid,
|
|
201
|
+
transport: transport.kind,
|
|
202
|
+
}, { branch: consumer.getState().gitBranch }));
|
|
203
|
+
try {
|
|
204
|
+
unlinkSync(daemonPidPath(cwd));
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
// ignore
|
|
208
|
+
}
|
|
209
|
+
process.exit(0);
|
|
210
|
+
};
|
|
211
|
+
process.on('SIGINT', shutdown);
|
|
212
|
+
process.on('SIGTERM', shutdown);
|
|
213
|
+
if (selected.fallbackReason) {
|
|
214
|
+
console.log(`CodeLedger daemon running (file IPC fallback: ${selected.fallbackReason})`);
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
console.log(`CodeLedger daemon running (${transport.kind})`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
async function runStatus(cwd) {
|
|
221
|
+
console.log(renderDaemonStatus(loadDaemonState(cwd)));
|
|
222
|
+
}
|
|
223
|
+
async function runStop(cwd) {
|
|
224
|
+
const pidPath = daemonPidPath(cwd);
|
|
225
|
+
if (!existsSync(pidPath)) {
|
|
226
|
+
console.log('Daemon: not running');
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
const pid = parseInt(readFileSync(pidPath, 'utf-8').trim(), 10);
|
|
230
|
+
if (!Number.isFinite(pid)) {
|
|
231
|
+
console.log('Daemon: pid file invalid');
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
try {
|
|
235
|
+
process.kill(pid, 'SIGTERM');
|
|
236
|
+
console.log(`Daemon stopped (pid ${pid})`);
|
|
237
|
+
}
|
|
238
|
+
catch (err) {
|
|
239
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
240
|
+
console.log(`Failed to stop daemon: ${message}`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
function parsePort(value) {
|
|
244
|
+
const parsed = value ? parseInt(value, 10) : DEFAULT_PORT;
|
|
245
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_PORT;
|
|
246
|
+
}
|
|
247
|
+
function parsePositiveInt(value) {
|
|
248
|
+
if (!value)
|
|
249
|
+
return undefined;
|
|
250
|
+
const parsed = parseInt(value, 10);
|
|
251
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;
|
|
252
|
+
}
|
|
253
|
+
function normalize(value) {
|
|
254
|
+
return value.trim().toLowerCase();
|
|
255
|
+
}
|
|
256
|
+
async function postEventToSocket(socketPath, event) {
|
|
257
|
+
return await new Promise((resolve, reject) => {
|
|
258
|
+
const req = request({
|
|
259
|
+
socketPath,
|
|
260
|
+
path: '/events',
|
|
261
|
+
method: 'POST',
|
|
262
|
+
headers: {
|
|
263
|
+
'content-type': 'application/json',
|
|
264
|
+
},
|
|
265
|
+
}, (res) => {
|
|
266
|
+
res.resume();
|
|
267
|
+
res.on('end', resolve);
|
|
268
|
+
});
|
|
269
|
+
req.on('error', reject);
|
|
270
|
+
req.write(JSON.stringify(event));
|
|
271
|
+
req.end();
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
function stringValue(value) {
|
|
275
|
+
return typeof value === 'string' && value.length > 0 ? value : undefined;
|
|
276
|
+
}
|
|
277
|
+
export function loadPersistedWarmBundles(cwd, previous) {
|
|
278
|
+
const remembered = (previous?.recentBundles ?? []).filter((entry) => existsSync(entry.bundlePath));
|
|
279
|
+
if (remembered.length > 0)
|
|
280
|
+
return remembered.slice(0, 5);
|
|
281
|
+
const bundlesDir = join(cwd, '.codeledger', 'artifacts', 'bundles');
|
|
282
|
+
if (!existsSync(bundlesDir))
|
|
283
|
+
return [];
|
|
284
|
+
return readdirSync(bundlesDir)
|
|
285
|
+
.filter((file) => file.endsWith('.json'))
|
|
286
|
+
.map((file) => join(bundlesDir, file))
|
|
287
|
+
.map((bundlePath) => {
|
|
288
|
+
try {
|
|
289
|
+
const bundle = JSON.parse(readFileSync(bundlePath, 'utf-8'));
|
|
290
|
+
return {
|
|
291
|
+
task: bundle.task ?? bundle.bundle_id ?? bundlePath.split('/').pop() ?? 'recent bundle',
|
|
292
|
+
bundlePath,
|
|
293
|
+
bundleId: bundle.bundle_id ?? bundlePath.split('/').pop()?.replace(/\.json$/, '') ?? bundlePath,
|
|
294
|
+
generatedAt: bundle.generated_at ?? safeMtime(bundlePath),
|
|
295
|
+
confidenceLevel: bundle.confidence?.level,
|
|
296
|
+
confidenceScore: bundle.confidence?.score,
|
|
297
|
+
relevantTests: (bundle.files ?? []).filter((file) => /(^|\/)(test|tests)\b|\.test\./.test(file.path)).map((file) => file.path),
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
catch {
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
})
|
|
304
|
+
.filter((entry) => entry !== null)
|
|
305
|
+
.sort((a, b) => b.generatedAt.localeCompare(a.generatedAt))
|
|
306
|
+
.slice(0, 5);
|
|
307
|
+
}
|
|
308
|
+
function safeMtime(path) {
|
|
309
|
+
try {
|
|
310
|
+
return statSync(path).mtime.toISOString();
|
|
311
|
+
}
|
|
312
|
+
catch {
|
|
313
|
+
return new Date(0).toISOString();
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
//# sourceMappingURL=daemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DaemonEvent, DaemonEventType } from './eventTypes.js';
|
|
2
|
+
export declare function createDaemonEvent(repoRoot: string, type: DaemonEventType, payload: Record<string, unknown>, meta?: {
|
|
3
|
+
branch?: string;
|
|
4
|
+
taskId?: string;
|
|
5
|
+
runId?: string;
|
|
6
|
+
id?: string;
|
|
7
|
+
ts?: string;
|
|
8
|
+
}): DaemonEvent;
|
|
9
|
+
//# sourceMappingURL=appendEvent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appendEvent.d.ts","sourceRoot":"","sources":["../../src/events/appendEvent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEpE,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,IAAI,CAAC,EAAE;IACL,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,GACA,WAAW,CAWb"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
export function createDaemonEvent(repoRoot, type, payload, meta) {
|
|
3
|
+
return {
|
|
4
|
+
id: meta?.id ?? randomUUID(),
|
|
5
|
+
type,
|
|
6
|
+
ts: meta?.ts ?? new Date().toISOString(),
|
|
7
|
+
repoRoot,
|
|
8
|
+
branch: meta?.branch,
|
|
9
|
+
taskId: meta?.taskId,
|
|
10
|
+
runId: meta?.runId,
|
|
11
|
+
payload,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=appendEvent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appendEvent.js","sourceRoot":"","sources":["../../src/events/appendEvent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,MAAM,UAAU,iBAAiB,CAC/B,QAAgB,EAChB,IAAqB,EACrB,OAAgC,EAChC,IAMC;IAED,OAAO;QACL,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,UAAU,EAAE;QAC5B,IAAI;QACJ,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACxC,QAAQ;QACR,MAAM,EAAE,IAAI,EAAE,MAAM;QACpB,MAAM,EAAE,IAAI,EAAE,MAAM;QACpB,KAAK,EAAE,IAAI,EAAE,KAAK;QAClB,OAAO;KACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { DaemonState } from '../store/daemonState.js';
|
|
2
|
+
import type { DaemonEvent } from './eventTypes.js';
|
|
3
|
+
export interface DaemonEventConsumer {
|
|
4
|
+
getState(): DaemonState;
|
|
5
|
+
getSeenEventIds(): Set<string>;
|
|
6
|
+
consume(event: DaemonEvent): boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function createEventConsumer(cwd: string, initialState: DaemonState, initialSeenEventIds?: Iterable<string>, options?: {
|
|
9
|
+
snapshotIntervalEvents?: number;
|
|
10
|
+
hotJournalDays?: number;
|
|
11
|
+
snapshotLimit?: number;
|
|
12
|
+
}): DaemonEventConsumer;
|
|
13
|
+
//# sourceMappingURL=eventConsumer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eventConsumer.d.ts","sourceRoot":"","sources":["../../src/events/eventConsumer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAInD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,IAAI,WAAW,CAAC;IACxB,eAAe,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/B,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC;CACtC;AAED,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,WAAW,EACzB,mBAAmB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,EACtC,OAAO,CAAC,EAAE;IACR,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GACA,mBAAmB,CAyCrB"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { appendJournalEvent, compactJournalFiles } from '../store/eventJournal.js';
|
|
2
|
+
import { writeCurrentState, writeSnapshot } from '../store/snapshotStore.js';
|
|
3
|
+
import { reduceDaemonEvent } from './eventReducer.js';
|
|
4
|
+
const SNAPSHOT_INTERVAL_EVENTS = 25;
|
|
5
|
+
export function createEventConsumer(cwd, initialState, initialSeenEventIds, options) {
|
|
6
|
+
let state = initialState;
|
|
7
|
+
const seenEventIds = new Set(initialSeenEventIds ?? []);
|
|
8
|
+
let lastRotatedSnapshotEventCount = state.eventCount;
|
|
9
|
+
const snapshotIntervalEvents = Math.max(1, options?.snapshotIntervalEvents ?? SNAPSHOT_INTERVAL_EVENTS);
|
|
10
|
+
const hotJournalDays = Math.max(1, options?.hotJournalDays ?? state.retention.hotJournalDays);
|
|
11
|
+
const snapshotLimit = Math.max(1, options?.snapshotLimit ?? state.retention.snapshotLimit);
|
|
12
|
+
const persist = (forceRotatedSnapshot = false) => {
|
|
13
|
+
writeCurrentState(cwd, state);
|
|
14
|
+
if (forceRotatedSnapshot || state.eventCount - lastRotatedSnapshotEventCount >= snapshotIntervalEvents) {
|
|
15
|
+
writeSnapshot(cwd, state, snapshotLimit);
|
|
16
|
+
compactJournalFiles(cwd, state.updatedAt, hotJournalDays);
|
|
17
|
+
lastRotatedSnapshotEventCount = state.eventCount;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
persist(true);
|
|
21
|
+
return {
|
|
22
|
+
getState() {
|
|
23
|
+
return state;
|
|
24
|
+
},
|
|
25
|
+
getSeenEventIds() {
|
|
26
|
+
return seenEventIds;
|
|
27
|
+
},
|
|
28
|
+
consume(event) {
|
|
29
|
+
if (seenEventIds.has(event.id)) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
appendJournalEvent(cwd, event);
|
|
33
|
+
state = reduceDaemonEvent(state, event);
|
|
34
|
+
seenEventIds.add(event.id);
|
|
35
|
+
persist(event.type === 'DAEMON_STARTED'
|
|
36
|
+
|| event.type === 'DAEMON_STOPPED'
|
|
37
|
+
|| event.type === 'TASK_FINISHED');
|
|
38
|
+
return true;
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=eventConsumer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eventConsumer.js","sourceRoot":"","sources":["../../src/events/eventConsumer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAGtD,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAQpC,MAAM,UAAU,mBAAmB,CACjC,GAAW,EACX,YAAyB,EACzB,mBAAsC,EACtC,OAIC;IAED,IAAI,KAAK,GAAG,YAAY,CAAC;IACzB,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAC;IACxD,IAAI,6BAA6B,GAAG,KAAK,CAAC,UAAU,CAAC;IACrD,MAAM,sBAAsB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,sBAAsB,IAAI,wBAAwB,CAAC,CAAC;IACxG,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,IAAI,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC9F,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,IAAI,KAAK,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;IAE3F,MAAM,OAAO,GAAG,CAAC,oBAAoB,GAAG,KAAK,EAAQ,EAAE;QACrD,iBAAiB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC9B,IAAI,oBAAoB,IAAI,KAAK,CAAC,UAAU,GAAG,6BAA6B,IAAI,sBAAsB,EAAE,CAAC;YACvG,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC;YACzC,mBAAmB,CAAC,GAAG,EAAE,KAAK,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;YAC1D,6BAA6B,GAAG,KAAK,CAAC,UAAU,CAAC;QACnD,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,CAAC,IAAI,CAAC,CAAC;IAEd,OAAO;QACL,QAAQ;YACN,OAAO,KAAK,CAAC;QACf,CAAC;QACD,eAAe;YACb,OAAO,YAAY,CAAC;QACtB,CAAC;QACD,OAAO,CAAC,KAAkB;YACxB,IAAI,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC/B,OAAO,KAAK,CAAC;YACf,CAAC;YACD,kBAAkB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAC/B,KAAK,GAAG,iBAAiB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YACxC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC3B,OAAO,CACL,KAAK,CAAC,IAAI,KAAK,gBAAgB;mBAC5B,KAAK,CAAC,IAAI,KAAK,gBAAgB;mBAC/B,KAAK,CAAC,IAAI,KAAK,eAAe,CAClC,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eventReducer.d.ts","sourceRoot":"","sources":["../../src/events/eventReducer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAiD,MAAM,yBAAyB,CAAC;AAE1G,OAAO,EAAsB,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEvE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,EAAE,KAAK,EAAE,WAAW,GAAG,WAAW,CAoI5F"}
|