chat-recall 0.5.6 → 0.5.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/README.md +332 -0
- package/dist/cli.js +7057 -4542
- package/dist/cli.js.map +1 -1
- package/dist/code-index-cursor.d.ts +18 -0
- package/dist/code-index-cursor.d.ts.map +1 -0
- package/dist/code-index-cursor.js +89 -0
- package/dist/code-index-cursor.js.map +1 -0
- package/dist/daemon-log.d.ts +44 -0
- package/dist/daemon-log.d.ts.map +1 -0
- package/dist/daemon-log.js +74 -0
- package/dist/daemon-log.js.map +1 -0
- package/dist/derived.d.ts +20 -0
- package/dist/derived.d.ts.map +1 -0
- package/dist/derived.js +106 -0
- package/dist/derived.js.map +1 -0
- package/dist/install-skills.d.ts.map +1 -1
- package/dist/install-skills.js +6 -1
- package/dist/install-skills.js.map +1 -1
- package/dist/log-rotate.d.ts +16 -0
- package/dist/log-rotate.d.ts.map +1 -0
- package/dist/log-rotate.js +50 -0
- package/dist/log-rotate.js.map +1 -0
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +5865 -3789
- package/dist/mcp.js.map +1 -1
- package/dist/project-tasks.js +1 -1
- package/dist/project-tasks.js.map +1 -1
- package/dist/redact-deep.d.ts +4 -0
- package/dist/redact-deep.d.ts.map +1 -0
- package/dist/redact-deep.js +26 -0
- package/dist/redact-deep.js.map +1 -0
- package/dist/scan-pool.d.ts +56 -0
- package/dist/scan-pool.d.ts.map +1 -0
- package/dist/scan-pool.js +245 -0
- package/dist/scan-pool.js.map +1 -0
- package/dist/scan-worker.d.ts +78 -0
- package/dist/scan-worker.d.ts.map +1 -0
- package/dist/scan-worker.js +11175 -0
- package/dist/scan-worker.js.map +1 -0
- package/dist/self-restart.d.ts +20 -2
- package/dist/self-restart.d.ts.map +1 -1
- package/dist/self-restart.js +16 -6
- package/dist/self-restart.js.map +1 -1
- package/dist/server-probe.d.ts +76 -0
- package/dist/server-probe.d.ts.map +1 -0
- package/dist/server-probe.js +106 -0
- package/dist/server-probe.js.map +1 -0
- package/dist/sync-client.d.ts +24 -0
- package/dist/sync-client.d.ts.map +1 -1
- package/dist/sync-client.js +496 -151
- package/dist/sync-client.js.map +1 -1
- package/dist/target-breaker.d.ts +61 -0
- package/dist/target-breaker.d.ts.map +1 -0
- package/dist/target-breaker.js +85 -0
- package/dist/target-breaker.js.map +1 -0
- package/dist/telemetry-consent.d.ts +31 -0
- package/dist/telemetry-consent.d.ts.map +1 -0
- package/dist/telemetry-consent.js +115 -0
- package/dist/telemetry-consent.js.map +1 -0
- package/dist/telemetry.d.ts +22 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +125 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/tick-queue.d.ts +67 -0
- package/dist/tick-queue.d.ts.map +1 -0
- package/dist/tick-queue.js +104 -0
- package/dist/tick-queue.js.map +1 -0
- package/dist/transport-safety.d.ts +43 -0
- package/dist/transport-safety.d.ts.map +1 -0
- package/dist/transport-safety.js +100 -0
- package/dist/transport-safety.js.map +1 -0
- package/dist/verify-repair.js +1 -1
- package/dist/verify-repair.js.map +1 -1
- package/dist/watch.js +8069 -5720
- package/package.json +21 -2
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** workspace path → epoch ms of the last COMPLETED index. */
|
|
2
|
+
export type CodeIndexCursor = Record<string, number>;
|
|
3
|
+
export declare function readCursor(): CodeIndexCursor;
|
|
4
|
+
/** Record a COMPLETED index. Never called for a failure — see the header. */
|
|
5
|
+
export declare function noteIndexed(workspace: string, now?: number): void;
|
|
6
|
+
/**
|
|
7
|
+
* Order workspaces least-recently-indexed first, so a sweep that keeps getting
|
|
8
|
+
* interrupted still eventually covers everything.
|
|
9
|
+
*
|
|
10
|
+
* Never-indexed workspaces sort before indexed ones — a repo the collector has
|
|
11
|
+
* never looked at is more valuable than refreshing one done an hour ago. Ties
|
|
12
|
+
* keep the caller's order, which is recency, so a first run behaves exactly as
|
|
13
|
+
* it did before this existed.
|
|
14
|
+
*/
|
|
15
|
+
export declare function orderByStaleness(workspaces: string[], cursor?: CodeIndexCursor): string[];
|
|
16
|
+
/** Drop entries for paths that are no longer candidates. */
|
|
17
|
+
export declare function pruneCursor(known: string[]): void;
|
|
18
|
+
//# sourceMappingURL=code-index-cursor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-index-cursor.d.ts","sourceRoot":"","sources":["../src/code-index-cursor.ts"],"names":[],"mappings":"AA8BA,6DAA6D;AAC7D,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAErD,wBAAgB,UAAU,IAAI,eAAe,CAY5C;AAUD,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,IAAI,CAMrE;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,MAAM,kBAAe,GAAG,MAAM,EAAE,CAKtF;AAED,4DAA4D;AAC5D,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAQjD"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remember which workspaces have been code-indexed, so a restart makes progress
|
|
3
|
+
* instead of starting the sweep over.
|
|
4
|
+
*
|
|
5
|
+
* ── The behaviour this fixes ──────────────────────────────────────────────
|
|
6
|
+
* `codeIndexTick` discovered up to 50 workspaces sorted by most-recently-used
|
|
7
|
+
* and walked them in that order, holding nothing across process boundaries. The
|
|
8
|
+
* daemon's median uptime during the OOM crash-loop was ~105 seconds, and a
|
|
9
|
+
* single large repo takes tens of seconds — so every restart re-indexed the same
|
|
10
|
+
* first workspace or two and the tail of the list was never reached AT ALL. The
|
|
11
|
+
* log showed 8,919 `indexing` lines against 382 completions.
|
|
12
|
+
*
|
|
13
|
+
* Ordering by recency is right for a first run and wrong for every run after it:
|
|
14
|
+
* the busiest repo is always first, so it is always the one that gets done. What
|
|
15
|
+
* makes a sweep finish is going to the LEAST-RECENTLY-INDEXED workspace next,
|
|
16
|
+
* which is what this cursor provides.
|
|
17
|
+
*
|
|
18
|
+
* ── Shape ────────────────────────────────────────────────────────────────
|
|
19
|
+
* A tiny JSON map of workspace path → last successful index. Best-effort in both
|
|
20
|
+
* directions: a missing or corrupt file just means "nothing indexed yet", and a
|
|
21
|
+
* write that fails is ignored. It records COMPLETIONS only, so a workspace that
|
|
22
|
+
* crashes the indexer is retried rather than being marked done — the opposite
|
|
23
|
+
* choice would silently drop a repo forever.
|
|
24
|
+
*/
|
|
25
|
+
import { readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
26
|
+
import { join, dirname } from 'path';
|
|
27
|
+
import { getDataDir } from '@chat-recall/engine/core/paths.js';
|
|
28
|
+
const cursorPath = () => join(getDataDir(), 'code-index-cursor.json');
|
|
29
|
+
export function readCursor() {
|
|
30
|
+
try {
|
|
31
|
+
const raw = JSON.parse(readFileSync(cursorPath(), 'utf-8'));
|
|
32
|
+
if (raw && typeof raw === 'object' && !Array.isArray(raw)) {
|
|
33
|
+
const out = {};
|
|
34
|
+
for (const [k, v] of Object.entries(raw)) {
|
|
35
|
+
if (typeof v === 'number' && Number.isFinite(v))
|
|
36
|
+
out[k] = v;
|
|
37
|
+
}
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch { /* absent or corrupt — nothing indexed yet */ }
|
|
42
|
+
return {};
|
|
43
|
+
}
|
|
44
|
+
function writeCursor(c) {
|
|
45
|
+
try {
|
|
46
|
+
const p = cursorPath();
|
|
47
|
+
mkdirSync(dirname(p), { recursive: true });
|
|
48
|
+
writeFileSync(p, JSON.stringify(c));
|
|
49
|
+
}
|
|
50
|
+
catch { /* housekeeping must never fail a sweep */ }
|
|
51
|
+
}
|
|
52
|
+
/** Record a COMPLETED index. Never called for a failure — see the header. */
|
|
53
|
+
export function noteIndexed(workspace, now = Date.now()) {
|
|
54
|
+
const c = readCursor();
|
|
55
|
+
c[workspace] = now;
|
|
56
|
+
// Forget paths that are no longer candidates, so a machine that has moved on
|
|
57
|
+
// does not carry a growing map of dead repos forever.
|
|
58
|
+
writeCursor(c);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Order workspaces least-recently-indexed first, so a sweep that keeps getting
|
|
62
|
+
* interrupted still eventually covers everything.
|
|
63
|
+
*
|
|
64
|
+
* Never-indexed workspaces sort before indexed ones — a repo the collector has
|
|
65
|
+
* never looked at is more valuable than refreshing one done an hour ago. Ties
|
|
66
|
+
* keep the caller's order, which is recency, so a first run behaves exactly as
|
|
67
|
+
* it did before this existed.
|
|
68
|
+
*/
|
|
69
|
+
export function orderByStaleness(workspaces, cursor = readCursor()) {
|
|
70
|
+
return workspaces
|
|
71
|
+
.map((w, i) => ({ w, i, at: cursor[w] ?? -1 }))
|
|
72
|
+
.sort((a, b) => (a.at - b.at) || (a.i - b.i))
|
|
73
|
+
.map((e) => e.w);
|
|
74
|
+
}
|
|
75
|
+
/** Drop entries for paths that are no longer candidates. */
|
|
76
|
+
export function pruneCursor(known) {
|
|
77
|
+
const keep = new Set(known);
|
|
78
|
+
const c = readCursor();
|
|
79
|
+
let changed = false;
|
|
80
|
+
for (const k of Object.keys(c)) {
|
|
81
|
+
if (!keep.has(k)) {
|
|
82
|
+
delete c[k];
|
|
83
|
+
changed = true;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (changed)
|
|
87
|
+
writeCursor(c);
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=code-index-cursor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-index-cursor.js","sourceRoot":"","sources":["../src/code-index-cursor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The watch daemon's log — readable by a human by default, JSON when a machine
|
|
3
|
+
* is going to read it.
|
|
4
|
+
*
|
|
5
|
+
* ── Why this is not just `createLogger()` ────────────────────────────────
|
|
6
|
+
* The engine's logger emits JSON to stdout, which is right for a server pod whose
|
|
7
|
+
* output goes to Loki. This daemon's output goes somewhere different: a file on
|
|
8
|
+
* the user's own laptop that THEY tail, that `chat-recall doctor` points them at,
|
|
9
|
+
* and that is the first thing anyone reads when their sync looks wrong. And
|
|
10
|
+
* `pino-pretty` is not a dependency of this package — the native-free guard keeps
|
|
11
|
+
* the collector's dependency list minimal — so LOG_PRETTY silently falls back to
|
|
12
|
+
* JSON here.
|
|
13
|
+
*
|
|
14
|
+
* Converting 48 `console.*` calls to JSON would therefore have made the one
|
|
15
|
+
* surface a user actually reads unreadable, in exchange for structure nothing was
|
|
16
|
+
* consuming. So: human-readable lines by default, identical in shape to what the
|
|
17
|
+
* daemon has always printed, and `CHAT_RECALL_LOG_JSON=1` for an operator
|
|
18
|
+
* shipping to Loki or Vector.
|
|
19
|
+
*
|
|
20
|
+
* ── What this buys over console.* ────────────────────────────────────────
|
|
21
|
+
* LEVELS `CHAT_RECALL_LOG_LEVEL=warn` silences the routine chatter. There
|
|
22
|
+
* was no way to turn down a daemon that logs a heartbeat a minute.
|
|
23
|
+
* STRUCTURE fields travel alongside the message, so the JSON mode is
|
|
24
|
+
* genuinely parseable rather than a string to regex.
|
|
25
|
+
* ONE PLACE the timestamp format, the level filter and the destination are
|
|
26
|
+
* decided once instead of at 48 call sites.
|
|
27
|
+
*/
|
|
28
|
+
/** Ordered so a threshold comparison is a number comparison. */
|
|
29
|
+
declare const LEVELS: {
|
|
30
|
+
readonly debug: 10;
|
|
31
|
+
readonly info: 20;
|
|
32
|
+
readonly warn: 30;
|
|
33
|
+
readonly error: 40;
|
|
34
|
+
};
|
|
35
|
+
export type LogLevel = keyof typeof LEVELS;
|
|
36
|
+
export interface DaemonLog {
|
|
37
|
+
debug(msg: string, fields?: Record<string, unknown>): void;
|
|
38
|
+
info(msg: string, fields?: Record<string, unknown>): void;
|
|
39
|
+
warn(msg: string, fields?: Record<string, unknown>): void;
|
|
40
|
+
error(msg: string, fields?: Record<string, unknown>): void;
|
|
41
|
+
}
|
|
42
|
+
export declare const daemonLog: DaemonLog;
|
|
43
|
+
export {};
|
|
44
|
+
//# sourceMappingURL=daemon-log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon-log.d.ts","sourceRoot":"","sources":["../src/daemon-log.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,gEAAgE;AAChE,QAAA,MAAM,MAAM;;;;;CAAwD,CAAC;AACrE,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,MAAM,CAAC;AAe3C,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC3D,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC1D,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC1D,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC5D;AA6BD,eAAO,MAAM,SAAS,EAAE,SAKvB,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The watch daemon's log — readable by a human by default, JSON when a machine
|
|
3
|
+
* is going to read it.
|
|
4
|
+
*
|
|
5
|
+
* ── Why this is not just `createLogger()` ────────────────────────────────
|
|
6
|
+
* The engine's logger emits JSON to stdout, which is right for a server pod whose
|
|
7
|
+
* output goes to Loki. This daemon's output goes somewhere different: a file on
|
|
8
|
+
* the user's own laptop that THEY tail, that `chat-recall doctor` points them at,
|
|
9
|
+
* and that is the first thing anyone reads when their sync looks wrong. And
|
|
10
|
+
* `pino-pretty` is not a dependency of this package — the native-free guard keeps
|
|
11
|
+
* the collector's dependency list minimal — so LOG_PRETTY silently falls back to
|
|
12
|
+
* JSON here.
|
|
13
|
+
*
|
|
14
|
+
* Converting 48 `console.*` calls to JSON would therefore have made the one
|
|
15
|
+
* surface a user actually reads unreadable, in exchange for structure nothing was
|
|
16
|
+
* consuming. So: human-readable lines by default, identical in shape to what the
|
|
17
|
+
* daemon has always printed, and `CHAT_RECALL_LOG_JSON=1` for an operator
|
|
18
|
+
* shipping to Loki or Vector.
|
|
19
|
+
*
|
|
20
|
+
* ── What this buys over console.* ────────────────────────────────────────
|
|
21
|
+
* LEVELS `CHAT_RECALL_LOG_LEVEL=warn` silences the routine chatter. There
|
|
22
|
+
* was no way to turn down a daemon that logs a heartbeat a minute.
|
|
23
|
+
* STRUCTURE fields travel alongside the message, so the JSON mode is
|
|
24
|
+
* genuinely parseable rather than a string to regex.
|
|
25
|
+
* ONE PLACE the timestamp format, the level filter and the destination are
|
|
26
|
+
* decided once instead of at 48 call sites.
|
|
27
|
+
*/
|
|
28
|
+
/** Ordered so a threshold comparison is a number comparison. */
|
|
29
|
+
const LEVELS = { debug: 10, info: 20, warn: 30, error: 40 };
|
|
30
|
+
function threshold() {
|
|
31
|
+
const raw = (process.env.CHAT_RECALL_LOG_LEVEL || process.env.LOG_LEVEL || 'info').toLowerCase();
|
|
32
|
+
return LEVELS[raw] ?? LEVELS.info;
|
|
33
|
+
}
|
|
34
|
+
const asJson = () => {
|
|
35
|
+
const v = (process.env.CHAT_RECALL_LOG_JSON || '').trim();
|
|
36
|
+
return v === '1' || v.toLowerCase() === 'true';
|
|
37
|
+
};
|
|
38
|
+
/** The daemon's existing prefix format: `[ISO-8601] message`. */
|
|
39
|
+
const stamp = () => `[${new Date().toISOString()}]`;
|
|
40
|
+
function emit(level, msg, fields) {
|
|
41
|
+
if (LEVELS[level] < threshold())
|
|
42
|
+
return;
|
|
43
|
+
// stderr for warn/error, stdout otherwise — so a shell can separate them even
|
|
44
|
+
// though the unit sends both to the same place.
|
|
45
|
+
const out = LEVELS[level] >= LEVELS.warn ? process.stderr : process.stdout;
|
|
46
|
+
if (asJson()) {
|
|
47
|
+
out.write(`${JSON.stringify({ t: Date.now(), level, msg, ...fields })}\n`);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
// Human mode: the message first, because that is what the reader is scanning
|
|
51
|
+
// for. Fields are appended compactly and only when present — a trailing
|
|
52
|
+
// `{...}` on every line would defeat the point of the human format.
|
|
53
|
+
const extra = fields && Object.keys(fields).length > 0
|
|
54
|
+
? ` ${Object.entries(fields).map(([k, v]) => `${k}=${fmt(v)}`).join(' ')}`
|
|
55
|
+
: '';
|
|
56
|
+
const prefix = level === 'warn' || level === 'error' ? `${stamp()} ${level.toUpperCase()}` : stamp();
|
|
57
|
+
out.write(`${prefix} ${msg}${extra}\n`);
|
|
58
|
+
}
|
|
59
|
+
/** Compact enough to sit on a log line without wrapping it. */
|
|
60
|
+
function fmt(v) {
|
|
61
|
+
if (v === null || v === undefined)
|
|
62
|
+
return String(v);
|
|
63
|
+
if (typeof v === 'number' || typeof v === 'boolean')
|
|
64
|
+
return String(v);
|
|
65
|
+
const s = String(v);
|
|
66
|
+
return /\s/.test(s) ? JSON.stringify(s) : s;
|
|
67
|
+
}
|
|
68
|
+
export const daemonLog = {
|
|
69
|
+
debug: (m, f) => emit('debug', m, f),
|
|
70
|
+
info: (m, f) => emit('info', m, f),
|
|
71
|
+
warn: (m, f) => emit('warn', m, f),
|
|
72
|
+
error: (m, f) => emit('error', m, f),
|
|
73
|
+
};
|
|
74
|
+
//# sourceMappingURL=daemon-log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon-log.js","sourceRoot":"","sources":["../src/daemon-log.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** Which compute rows a session ships. */
|
|
2
|
+
export declare const COMPUTE_KINDS: readonly ["diff", "outcome", "commits", "markers"];
|
|
3
|
+
export interface DerivedRows {
|
|
4
|
+
session_id: string;
|
|
5
|
+
mtime: number;
|
|
6
|
+
compute: Array<{
|
|
7
|
+
kind: string;
|
|
8
|
+
mtime: number;
|
|
9
|
+
data: unknown;
|
|
10
|
+
}>;
|
|
11
|
+
outcome_row: unknown | null;
|
|
12
|
+
}
|
|
13
|
+
export declare function collectDerivedRows(ref: {
|
|
14
|
+
prefixedId: string;
|
|
15
|
+
toolId: string;
|
|
16
|
+
mtime: number;
|
|
17
|
+
}, mtime: number, count: {
|
|
18
|
+
redactions: number;
|
|
19
|
+
}, maxRowBytes: number): DerivedRows;
|
|
20
|
+
//# sourceMappingURL=derived.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"derived.d.ts","sourceRoot":"","sources":["../src/derived.ts"],"names":[],"mappings":"AA2BA,0CAA0C;AAC1C,eAAO,MAAM,aAAa,oDAAqD,CAAC;AAEhF,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC/D,WAAW,EAAE,OAAO,GAAG,IAAI,CAAC;CAC7B;AAED,wBAAgB,kBAAkB,CAChC,GAAG,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAC1D,KAAK,EAAE,MAAM,EACb,KAAK,EAAE;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,EAC7B,WAAW,EAAE,MAAM,GAClB,WAAW,CAmEb"}
|
package/dist/derived.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-session derived data: diff, outcome, commits, markers.
|
|
3
|
+
*
|
|
4
|
+
* ── Why this is its own module ───────────────────────────────────────────
|
|
5
|
+
* It is the heaviest work in a sync walk and it now runs in TWO places — on a
|
|
6
|
+
* worker thread (the fast path) and inline (the fallback when no worker is
|
|
7
|
+
* available). Two copies of this logic would be two things to keep correct, and
|
|
8
|
+
* the one that runs less often would rot. So it lives here and both callers
|
|
9
|
+
* import it.
|
|
10
|
+
*
|
|
11
|
+
* Measured cost, on the sessions that actually need rebuilding: ~5 seconds each,
|
|
12
|
+
* against 78ms for the secret scan. `replaySessionAny`, `computeOutcome` and
|
|
13
|
+
* `extractTurnsAny` each read the whole transcript and shell out to git —
|
|
14
|
+
* `withSessionReadCache` collapses that to one read, and moving the whole thing
|
|
15
|
+
* to a worker is what takes it off the thread that has to answer signals and
|
|
16
|
+
* fire the heartbeat.
|
|
17
|
+
*
|
|
18
|
+
* Takes an id, reads from disk itself, returns small-ish rows. That shape is
|
|
19
|
+
* what makes it cheap to hand to a worker: nothing large crosses the boundary on
|
|
20
|
+
* the way in.
|
|
21
|
+
*/
|
|
22
|
+
import { withSessionReadCache } from '@chat-recall/engine/core/live-session-scan.js';
|
|
23
|
+
import { replaySessionAny, extractTurnsAny } from '@chat-recall/engine/core/session-multi-tool.js';
|
|
24
|
+
import { computeOutcome } from '@chat-recall/engine/core/session-outcome.js';
|
|
25
|
+
import { markPrompt, summarizeMarkers } from '@chat-recall/engine/core/session-sentiment.js';
|
|
26
|
+
import { redactDeep } from './redact-deep.js';
|
|
27
|
+
/** Which compute rows a session ships. */
|
|
28
|
+
export const COMPUTE_KINDS = ['diff', 'outcome', 'commits', 'markers'];
|
|
29
|
+
export function collectDerivedRows(ref, mtime, count, maxRowBytes) {
|
|
30
|
+
const id = ref.prefixedId;
|
|
31
|
+
const compute = [];
|
|
32
|
+
let fullOutcome = null;
|
|
33
|
+
// One read of this transcript instead of four. replay, computeOutcome (twice
|
|
34
|
+
// internally) and extractTurns each re-read the whole file; the scope holds
|
|
35
|
+
// exactly one session's text and drops it on the way out.
|
|
36
|
+
return withSessionReadCache(() => {
|
|
37
|
+
for (const kind of COMPUTE_KINDS) {
|
|
38
|
+
let data = null;
|
|
39
|
+
try {
|
|
40
|
+
if (kind === 'diff') {
|
|
41
|
+
const replay = replaySessionAny(id);
|
|
42
|
+
if (replay.found)
|
|
43
|
+
data = replay;
|
|
44
|
+
}
|
|
45
|
+
else if (kind === 'outcome') {
|
|
46
|
+
fullOutcome = computeOutcome(id);
|
|
47
|
+
if (fullOutcome.found)
|
|
48
|
+
data = fullOutcome;
|
|
49
|
+
}
|
|
50
|
+
else if (kind === 'commits') {
|
|
51
|
+
// computeOutcome already ran git for the session window — reuse.
|
|
52
|
+
if (!fullOutcome)
|
|
53
|
+
fullOutcome = computeOutcome(id);
|
|
54
|
+
if (fullOutcome.found)
|
|
55
|
+
data = fullOutcome.commits;
|
|
56
|
+
}
|
|
57
|
+
else if (kind === 'markers') {
|
|
58
|
+
// Analysis-only use of the turns extractor (R4) — markers need
|
|
59
|
+
// per-prompt line/ts, not render fidelity.
|
|
60
|
+
const turns = extractTurnsAny(id, { maxTurns: 50_000 });
|
|
61
|
+
const prompts = turns.turns
|
|
62
|
+
.filter((t) => t.kind === 'user' && t.text)
|
|
63
|
+
.map((t) => ({ line: t.line, ts: t.ts, tsIso: t.tsIso, ...markPrompt(t.text) }));
|
|
64
|
+
data = { sessionId: id, prompts, summary: summarizeMarkers(prompts) };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
data = null;
|
|
69
|
+
}
|
|
70
|
+
if (data === null)
|
|
71
|
+
continue;
|
|
72
|
+
const redacted = redactDeep(data, count);
|
|
73
|
+
if (JSON.stringify(redacted).length > maxRowBytes)
|
|
74
|
+
continue;
|
|
75
|
+
compute.push({ kind, mtime, data: redacted });
|
|
76
|
+
}
|
|
77
|
+
// Outcome-badge row (session_outcome_cache) — what the list badges read.
|
|
78
|
+
// Computed live from the outcome we already ran above.
|
|
79
|
+
let outcomeRow = null;
|
|
80
|
+
if (fullOutcome?.found) {
|
|
81
|
+
outcomeRow = {
|
|
82
|
+
sessionId: id,
|
|
83
|
+
tool: ref.toolId,
|
|
84
|
+
status: fullOutcome.status,
|
|
85
|
+
reason: fullOutcome.reason,
|
|
86
|
+
fileMtime: mtime,
|
|
87
|
+
fileSize: 0,
|
|
88
|
+
contentHash: '',
|
|
89
|
+
fileCount: fullOutcome.fileCount,
|
|
90
|
+
linesAdded: fullOutcome.totalLinesAdded,
|
|
91
|
+
linesRemoved: fullOutcome.totalLinesRemoved,
|
|
92
|
+
commits: fullOutcome.commits?.totalCommits ?? 0,
|
|
93
|
+
isFull: true,
|
|
94
|
+
classifiedAt: Date.now(),
|
|
95
|
+
lastScannedOffset: 0,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
session_id: id,
|
|
100
|
+
mtime,
|
|
101
|
+
compute,
|
|
102
|
+
outcome_row: outcomeRow ? redactDeep({ ...outcomeRow, sessionId: undefined }, count) : null,
|
|
103
|
+
};
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=derived.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"derived.js","sourceRoot":"","sources":["../src/derived.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,oBAAoB,EAAE,MAAM,+CAA+C,CAAC;AACrF,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,gDAAgD,CAAC;AACnG,OAAO,EAAE,cAAc,EAAE,MAAM,6CAA6C,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,+CAA+C,CAAC;AAC7F,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,0CAA0C;AAC1C,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,CAAU,CAAC;AAShF,MAAM,UAAU,kBAAkB,CAChC,GAA0D,EAC1D,KAAa,EACb,KAA6B,EAC7B,WAAmB;IAEnB,MAAM,EAAE,GAAG,GAAG,CAAC,UAAU,CAAC;IAC1B,MAAM,OAAO,GAA0D,EAAE,CAAC;IAC1E,IAAI,WAAW,GAA6C,IAAI,CAAC;IAEjE,6EAA6E;IAC7E,4EAA4E;IAC5E,0DAA0D;IAC1D,OAAO,oBAAoB,CAAC,GAAG,EAAE;QACjC,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;YACjC,IAAI,IAAI,GAAY,IAAI,CAAC;YACzB,IAAI,CAAC;gBACH,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;oBACpB,MAAM,MAAM,GAAG,gBAAgB,CAAC,EAAE,CAAC,CAAC;oBACpC,IAAI,MAAM,CAAC,KAAK;wBAAE,IAAI,GAAG,MAAM,CAAC;gBAClC,CAAC;qBAAM,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;oBAC9B,WAAW,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC;oBACjC,IAAI,WAAW,CAAC,KAAK;wBAAE,IAAI,GAAG,WAAW,CAAC;gBAC5C,CAAC;qBAAM,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;oBAC9B,iEAAiE;oBACjE,IAAI,CAAC,WAAW;wBAAE,WAAW,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC;oBACnD,IAAI,WAAW,CAAC,KAAK;wBAAE,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC;gBACpD,CAAC;qBAAM,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;oBAC9B,+DAA+D;oBAC/D,2CAA2C;oBAC3C,MAAM,KAAK,GAAG,eAAe,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;oBACxD,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK;yBACxB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC;yBAC1C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,IAAK,CAAC,EAAE,CAAC,CAAC,CAAC;oBACpF,IAAI,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;gBACxE,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBAAC,IAAI,GAAG,IAAI,CAAC;YAAC,CAAC;YACxB,IAAI,IAAI,KAAK,IAAI;gBAAE,SAAS;YAC5B,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACzC,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,WAAW;gBAAE,SAAS;YAC5D,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QAChD,CAAC;QAED,yEAAyE;QACzE,uDAAuD;QACvD,IAAI,UAAU,GAAmC,IAAI,CAAC;QACtD,IAAI,WAAW,EAAE,KAAK,EAAE,CAAC;YACvB,UAAU,GAAG;gBACX,SAAS,EAAE,EAAE;gBACb,IAAI,EAAE,GAAG,CAAC,MAAM;gBAChB,MAAM,EAAE,WAAW,CAAC,MAAa;gBACjC,MAAM,EAAE,WAAW,CAAC,MAAM;gBAC1B,SAAS,EAAE,KAAK;gBAChB,QAAQ,EAAE,CAAC;gBACX,WAAW,EAAE,EAAE;gBACf,SAAS,EAAE,WAAW,CAAC,SAAS;gBAChC,UAAU,EAAE,WAAW,CAAC,eAAe;gBACvC,YAAY,EAAE,WAAW,CAAC,iBAAiB;gBAC3C,OAAO,EAAE,WAAW,CAAC,OAAO,EAAE,YAAY,IAAI,CAAC;gBAC/C,MAAM,EAAE,IAAI;gBACZ,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE;gBACxB,iBAAiB,EAAE,CAAC;aACrB,CAAC;QACJ,CAAC;QAED,OAAO;YACL,UAAU,EAAE,EAAE;YACd,KAAK;YACL,OAAO;YACP,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,GAAG,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI;SAC5F,CAAC;IACF,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-skills.d.ts","sourceRoot":"","sources":["../src/install-skills.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"install-skills.d.ts","sourceRoot":"","sources":["../src/install-skills.ts"],"names":[],"mappings":"AAgCA,sFAAsF;AACtF,wBAAgB,eAAe,IAAI,MAAM,CAExC;AA0DD,qFAAqF;AACrF,wBAAgB,iBAAiB,IAAI,MAAM,EAAE,CAO5C;AAED,MAAM,WAAW,WAAW;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;CAAE;AA+C5F;sFACsF;AACtF,wBAAgB,YAAY,IAAI,WAAW,EAAE,CAgB5C;AAOD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAC;QAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACnI;AAED;0FAC0F;AAC1F,wBAAgB,aAAa,CAAC,IAAI,GAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,aAAa,CAyBnF;AAED,MAAM,WAAW,eAAe;IAAG,SAAS,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CAAE;AAExG,yEAAyE;AACzE,wBAAgB,eAAe,IAAI,eAAe,CAkBjD;AAED;;4EAE4E;AAC5E,wBAAgB,iBAAiB,IAAI,OAAO,CAa3C;AAED,0EAA0E;AAC1E,wBAAgB,WAAW,IAAI,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAcjI"}
|
package/dist/install-skills.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* chat-recall ships a set of SKILL.md skills (../skills, bundled in the npm
|
|
5
5
|
* package) that teach any agent when/how to use the recall_* MCP tools. Every
|
|
6
6
|
* supported tool reads the SAME SKILL.md shape from its own skills dir, so one
|
|
7
|
-
* set covers Claude Code, Gemini, Codex, OpenCode and
|
|
7
|
+
* set covers Claude Code, Gemini, Codex, OpenCode, Antigravity and Cursor. We drop the
|
|
8
8
|
* files straight into each tool's dir (the only mechanism that works across all
|
|
9
9
|
* of them — Claude *plugins* are Claude-only).
|
|
10
10
|
*
|
|
@@ -22,6 +22,8 @@ import { geminiBackend } from '@chat-recall/engine/core/backends/gemini.js';
|
|
|
22
22
|
import { opencodeBackend } from '@chat-recall/engine/core/backends/opencode.js';
|
|
23
23
|
import { codexBackend } from '@chat-recall/engine/core/backends/codex.js';
|
|
24
24
|
import { agyBackend } from '@chat-recall/engine/core/backends/agy.js';
|
|
25
|
+
import { cursorBackend } from '@chat-recall/engine/core/backends/cursor.js';
|
|
26
|
+
import { cursorHomeDir } from '@chat-recall/engine/core/tool-paths.js';
|
|
25
27
|
// NOTE: Antigravity (agy) has no skills dir of its own — it reads Gemini's
|
|
26
28
|
// ~/.gemini/skills (same decision as team-merge.installPathFor). So the Gemini
|
|
27
29
|
// target covers agy; we surface agy only for the "available" hint.
|
|
@@ -161,6 +163,9 @@ export function skillTargets() {
|
|
|
161
163
|
{ id: 'gemini', label: 'Gemini CLI / Antigravity', dir: geminiBackend.skillsDir(), available: geminiBackend.isAvailable() || agyBackend.isAvailable() },
|
|
162
164
|
{ id: 'codex', label: 'Codex', dir: codexBackend.skillsDir(), available: codexBackend.isAvailable() },
|
|
163
165
|
{ id: 'opencode', label: 'OpenCode', dir: opencodeBackend.skillsDir(), available: opencodeBackend.isAvailable() },
|
|
166
|
+
// Cursor DOES have its own dir (~/.cursor/skills). `skills-cursor` next to
|
|
167
|
+
// it is Cursor's bundled set — read-only, never an install target.
|
|
168
|
+
{ id: 'cursor', label: 'Cursor', dir: join(cursorHomeDir(), 'skills'), available: cursorBackend.isAvailable() },
|
|
164
169
|
];
|
|
165
170
|
}
|
|
166
171
|
/** True if a dir is a chat-recall-managed skill (safe to overwrite/remove). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-skills.js","sourceRoot":"","sources":["../src/install-skills.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"install-skills.js","sourceRoot":"","sources":["../src/install-skills.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Rotate above this size. Two generations at 32 MB bounds the log at ~64 MB. */
|
|
2
|
+
export declare const LOG_MAX_BYTES: number;
|
|
3
|
+
export interface RotateResult {
|
|
4
|
+
rotated: boolean;
|
|
5
|
+
/** Size at rotation, in bytes. 0 when nothing was rotated. */
|
|
6
|
+
sizeBefore: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Rotate `logPath` if it exceeds `maxBytes`.
|
|
10
|
+
*
|
|
11
|
+
* Best-effort in both directions: a missing log, an unreadable one, or a
|
|
12
|
+
* read-only directory all mean "not rotated", never an error. A daemon must not
|
|
13
|
+
* fail to start because it could not tidy its own log.
|
|
14
|
+
*/
|
|
15
|
+
export declare function rotateLogIfLarge(logPath: string, maxBytes?: number): RotateResult;
|
|
16
|
+
//# sourceMappingURL=log-rotate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-rotate.d.ts","sourceRoot":"","sources":["../src/log-rotate.ts"],"names":[],"mappings":"AA4BA,iFAAiF;AACjF,eAAO,MAAM,aAAa,QAAmB,CAAC;AAE9C,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,SAAgB,GAAG,YAAY,CAUxF"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bound the daemon's log file without destroying it.
|
|
3
|
+
*
|
|
4
|
+
* ── Why this is its own module ────────────────────────────────────────────
|
|
5
|
+
* The rule here is one line of code and was wrong for months, in a way no test
|
|
6
|
+
* could catch while it lived inside the daemon entry module. It lives here so a
|
|
7
|
+
* test can drive the real function — the same lesson the task-board tests taught:
|
|
8
|
+
* a test that re-implements the rule passes while the shipped rule is broken.
|
|
9
|
+
*
|
|
10
|
+
* ── The rule: COPY, THEN TRUNCATE IN PLACE. NEVER RENAME. ─────────────────
|
|
11
|
+
* A rename looks safe at startup and is not. Every supervisor that redirects our
|
|
12
|
+
* output opens the log and hands us the fd BEFORE our first line runs — systemd
|
|
13
|
+
* `StandardOutput=append:`, launchd `StandardOutPath`, the Windows task's `>>`.
|
|
14
|
+
* By the time rotation runs, our own stdout already points at that inode.
|
|
15
|
+
* Renaming the path leaves every writer appending to the renamed file, while the
|
|
16
|
+
* path the CLI, `chat-recall doctor` and the user all tail no longer exists.
|
|
17
|
+
*
|
|
18
|
+
* That is not theory. On the maintainer's machine `/proc/<pid>/fd/1` resolved to
|
|
19
|
+
* `watch.log.1`, `watch.log` was absent, the "rotated" file had grown back to
|
|
20
|
+
* 47.6 MB unbounded, and eight hours of a wedged daemon left NOTHING in the place
|
|
21
|
+
* anyone looks. Rotation was silently deleting the log it existed to keep.
|
|
22
|
+
*
|
|
23
|
+
* Truncating keeps the inode, so every open fd stays valid and the next line
|
|
24
|
+
* lands at offset 0. All three redirections we write are append-mode, which is
|
|
25
|
+
* what makes that offset correct.
|
|
26
|
+
*/
|
|
27
|
+
import { statSync, copyFileSync, truncateSync } from 'fs';
|
|
28
|
+
/** Rotate above this size. Two generations at 32 MB bounds the log at ~64 MB. */
|
|
29
|
+
export const LOG_MAX_BYTES = 32 * 1024 * 1024;
|
|
30
|
+
/**
|
|
31
|
+
* Rotate `logPath` if it exceeds `maxBytes`.
|
|
32
|
+
*
|
|
33
|
+
* Best-effort in both directions: a missing log, an unreadable one, or a
|
|
34
|
+
* read-only directory all mean "not rotated", never an error. A daemon must not
|
|
35
|
+
* fail to start because it could not tidy its own log.
|
|
36
|
+
*/
|
|
37
|
+
export function rotateLogIfLarge(logPath, maxBytes = LOG_MAX_BYTES) {
|
|
38
|
+
try {
|
|
39
|
+
const size = statSync(logPath).size;
|
|
40
|
+
if (size < maxBytes)
|
|
41
|
+
return { rotated: false, sizeBefore: 0 };
|
|
42
|
+
copyFileSync(logPath, `${logPath}.1`); // overwrites any previous generation
|
|
43
|
+
truncateSync(logPath, 0); // same inode, so every open fd survives
|
|
44
|
+
return { rotated: true, sizeBefore: size };
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return { rotated: false, sizeBefore: 0 };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=log-rotate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-rotate.js","sourceRoot":"","sources":["../src/log-rotate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAE1D,iFAAiF;AACjF,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAQ9C;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe,EAAE,QAAQ,GAAG,aAAa;IACxE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC;QACpC,IAAI,IAAI,GAAG,QAAQ;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;QAC9D,YAAY,CAAC,OAAO,EAAE,GAAG,OAAO,IAAI,CAAC,CAAC,CAAG,qCAAqC;QAC9E,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAgB,wCAAwC;QACjF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;IAC3C,CAAC;AACH,CAAC"}
|
package/dist/mcp.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":";AACA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":";AACA;;;;GAIG;AA8BH,OAAO,4CAA4C,CAAC"}
|