@tznthou/ccrecall 0.7.2 → 0.8.0
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 +31 -16
- package/README_ZH.md +29 -16
- package/dist/api/routes.d.ts.map +1 -1
- package/dist/api/routes.js +25 -10
- package/dist/api/routes.js.map +1 -1
- package/dist/core/database.d.ts +52 -0
- package/dist/core/database.d.ts.map +1 -1
- package/dist/core/database.js +173 -23
- package/dist/core/database.js.map +1 -1
- package/dist/core/integrity-monitor.d.ts.map +1 -1
- package/dist/core/integrity-monitor.js +7 -3
- package/dist/core/integrity-monitor.js.map +1 -1
- package/dist/core/recall-telemetry.d.ts.map +1 -1
- package/dist/core/recall-telemetry.js +9 -3
- package/dist/core/recall-telemetry.js.map +1 -1
- package/dist/core/secure-dir.d.ts +7 -0
- package/dist/core/secure-dir.d.ts.map +1 -0
- package/dist/core/secure-dir.js +64 -0
- package/dist/core/secure-dir.js.map +1 -0
- package/dist/core/token-budget.d.ts +59 -3
- package/dist/core/token-budget.d.ts.map +1 -1
- package/dist/core/token-budget.js +115 -11
- package/dist/core/token-budget.js.map +1 -1
- package/dist/mcp/tools.d.ts +2 -1
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +51 -3
- package/dist/mcp/tools.js.map +1 -1
- package/hooks/lib/secure-dir.mjs +52 -0
- package/hooks/session-start.mjs +20 -3
- package/package.json +3 -2
- package/scripts/extraction-prompt.md +52 -1
- package/scripts/l3-prescription-position.py +835 -0
- package/scripts/post-session-extract.sh +36 -4
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
//
|
|
3
|
+
// #95: ~/.ccrecall holds the database — every memory, every session title — and
|
|
4
|
+
// telemetry whose rows carry `cwd`: the account name and every project name
|
|
5
|
+
// worked on. Four call sites create that directory; whichever ran first decided
|
|
6
|
+
// its mode, and three of them passed none. On a `umask 022` machine that is
|
|
7
|
+
// 0755, and under the `umask 002` that several distributions default to, 0775 —
|
|
8
|
+
// a directory another local user can write into.
|
|
9
|
+
//
|
|
10
|
+
// ⚠️ There is a second copy of this logic in hooks/lib/secure-dir.mjs. The hooks
|
|
11
|
+
// ship as standalone .mjs installed via npm and are never bundled through the
|
|
12
|
+
// TypeScript build, so they cannot import this file. The two are kept in step
|
|
13
|
+
// by tests/ccrecall-dir-permissions.test.ts, which imports both and asserts
|
|
14
|
+
// they agree — the same arrangement src/core/project-id.ts has with
|
|
15
|
+
// hooks/lib/project-id.mjs.
|
|
16
|
+
import { mkdirSync, chmodSync } from 'node:fs';
|
|
17
|
+
import os from 'node:os';
|
|
18
|
+
import path from 'node:path';
|
|
19
|
+
export const CCRECALL_DIR_MODE = 0o700;
|
|
20
|
+
export const CCRECALL_FILE_MODE = 0o600;
|
|
21
|
+
/** Resolved per call, never at module load: tests move $HOME, and a value
|
|
22
|
+
* frozen at import time would answer "is this ours?" about the real home
|
|
23
|
+
* directory no matter where the caller was pointed. */
|
|
24
|
+
function isOurs(dir) {
|
|
25
|
+
const root = path.join(os.homedir(), '.ccrecall');
|
|
26
|
+
const resolved = path.resolve(dir);
|
|
27
|
+
return resolved === root || resolved.startsWith(root + path.sep);
|
|
28
|
+
}
|
|
29
|
+
/** Create a ccRecall directory 0700, and repair one we already own. */
|
|
30
|
+
export function ensureCcrecallDir(dir) {
|
|
31
|
+
mkdirSync(dir, { recursive: true, mode: CCRECALL_DIR_MODE });
|
|
32
|
+
// mkdirSync leaves an existing directory's mode alone, so without this every
|
|
33
|
+
// install predating the fix keeps whatever its first creator gave it. The
|
|
34
|
+
// repair is limited to a path we know is ours because PR #94 did it to a
|
|
35
|
+
// configurable one: with a relative CCRECALL_EXTRACT_LOG the parent is the
|
|
36
|
+
// working directory, and a user's project directory went 0755 -> 0700 in
|
|
37
|
+
// testing. That attempt was reverted twice. A creator may choose the mode of
|
|
38
|
+
// a directory it makes; it may not re-mode a directory that was already
|
|
39
|
+
// there and belongs to someone else.
|
|
40
|
+
if (isOurs(dir)) {
|
|
41
|
+
try {
|
|
42
|
+
chmodSync(dir, CCRECALL_DIR_MODE);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// Raced away, or owned by another user. Nothing safe left to do, and the
|
|
46
|
+
// caller's real work must not fail over a mode.
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** Hold a ccRecall file at 0600, whoever chose its location. */
|
|
51
|
+
export function secureCcrecallFile(file) {
|
|
52
|
+
// Unconditional, unlike the directory above: a user-chosen *location* does
|
|
53
|
+
// not make the file someone else's — ccRecall wrote it either way. This is
|
|
54
|
+
// what the shell wrapper has done since #94, and it is what repairs the logs
|
|
55
|
+
// that are already 0644 on existing installs, since `mode` on appendFileSync
|
|
56
|
+
// only applies when the file is created.
|
|
57
|
+
try {
|
|
58
|
+
chmodSync(file, CCRECALL_FILE_MODE);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// Not there yet, or not ours. Telemetry must never break a caller.
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=secure-dir.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secure-dir.js","sourceRoot":"","sources":["../../src/core/secure-dir.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,EAAE;AACF,gFAAgF;AAChF,4EAA4E;AAC5E,gFAAgF;AAChF,4EAA4E;AAC5E,gFAAgF;AAChF,iDAAiD;AACjD,EAAE;AACF,iFAAiF;AACjF,8EAA8E;AAC9E,8EAA8E;AAC9E,4EAA4E;AAC5E,oEAAoE;AACpE,4BAA4B;AAC5B,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAC9C,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,CAAA;AACtC,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAA;AAEvC;;wDAEwD;AACxD,SAAS,MAAM,CAAC,GAAW;IACzB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAA;IACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAClC,OAAO,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAA;AAClE,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,CAAA;IAC5D,6EAA6E;IAC7E,0EAA0E;IAC1E,yEAAyE;IACzE,2EAA2E;IAC3E,yEAAyE;IACzE,6EAA6E;IAC7E,wEAAwE;IACxE,qCAAqC;IACrC,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAChB,IAAI,CAAC;YACH,SAAS,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAA;QACnC,CAAC;QAAC,MAAM,CAAC;YACP,yEAAyE;YACzE,gDAAgD;QAClD,CAAC;IACH,CAAC;AACH,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,2EAA2E;IAC3E,2EAA2E;IAC3E,6EAA6E;IAC7E,6EAA6E;IAC7E,yCAAyC;IACzC,IAAI,CAAC;QACH,SAAS,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAA;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,mEAAmE;IACrE,CAAC;AACH,CAAC"}
|
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Token budget primitives for recall output (Issue #12).
|
|
3
|
-
* Implementation of the
|
|
3
|
+
* Implementation of the injection budget contract documented in tutorial.md.
|
|
4
|
+
* The number lives in DEFAULT_MAX_TOKENS below, not in this sentence: stating
|
|
5
|
+
* it twice is how the file came to say "<300 tokens" three lines above the
|
|
6
|
+
* constant that reads 400.
|
|
4
7
|
*/
|
|
5
|
-
|
|
8
|
+
/** Total output budget for one SessionStart injection.
|
|
9
|
+
*
|
|
10
|
+
* Raised from 300 on 2026-09-11 alongside honest accounting. The old number
|
|
11
|
+
* was not a smaller budget, it was a wrong one: measured against the real hook
|
|
12
|
+
* with a corpus-shaped payload, a "300 token" injection emitted 363 because
|
|
13
|
+
* only `content` was priced. 400 keeps the same five rows reaching the reader
|
|
14
|
+
* now that the prefix, confidence suffix, [key: …] handle, header and footer
|
|
15
|
+
* are all counted. It buys no extra content — it stops the contract lying. */
|
|
16
|
+
export declare const DEFAULT_MAX_TOKENS = 400;
|
|
6
17
|
export declare const DEFAULT_PER_ROW_CHAR_CAP = 150;
|
|
7
18
|
/**
|
|
8
19
|
* Conservative token estimate without a real tokenizer.
|
|
@@ -25,6 +36,28 @@ export interface BudgetResult<R extends BudgetRow> {
|
|
|
25
36
|
usedTokens: number;
|
|
26
37
|
truncated: boolean;
|
|
27
38
|
}
|
|
39
|
+
/** What a row costs once the hook has rendered it — prefix, suffixes and all.
|
|
40
|
+
* Receives the clipped content so the caller never re-derives the clipping. */
|
|
41
|
+
export type RowCostFn<R extends BudgetRow> = (clipped: string, row: R) => number;
|
|
42
|
+
export interface BudgetOptions<R extends BudgetRow> {
|
|
43
|
+
/** Price of a rendered row. Defaults to the content alone, which is what the
|
|
44
|
+
* budget did before it learned about the decoration around it. */
|
|
45
|
+
costOf?: RowCostFn<R>;
|
|
46
|
+
/** Fixed output the caller will add regardless of how many rows survive —
|
|
47
|
+
* a header, a footer. Charged up front, and included in `usedTokens`, so
|
|
48
|
+
* the reported number is the size of the whole emission. */
|
|
49
|
+
reservedTokens?: number;
|
|
50
|
+
/** When the first row will not fit, trim it to what remains instead of
|
|
51
|
+
* emitting nothing. Off by default: this changes what callers receive.
|
|
52
|
+
*
|
|
53
|
+
* Exists because honest accounting makes "nothing fits" common on the
|
|
54
|
+
* mid-conversation path, where one CJK memory costs one token per character
|
|
55
|
+
* and alone exceeds the budget. Silence there is indistinguishable from
|
|
56
|
+
* "no relevant memory", so the failure was invisible. Trimming keeps the
|
|
57
|
+
* contract intact — the budget is never exceeded — while still saying
|
|
58
|
+
* something. */
|
|
59
|
+
minimumOneRow?: boolean;
|
|
60
|
+
}
|
|
28
61
|
/**
|
|
29
62
|
* Apply a token budget to a list of row-like objects with a `content` field.
|
|
30
63
|
* Per-row content is truncated to perRowCharCap (ellipsis-aware), cumulative
|
|
@@ -34,5 +67,28 @@ export interface BudgetResult<R extends BudgetRow> {
|
|
|
34
67
|
* Callers should touch/log only `emitted` ids — dropped rows never reached
|
|
35
68
|
* the client.
|
|
36
69
|
*/
|
|
37
|
-
export declare function applyRowBudget<R extends BudgetRow>(rows: R[], maxTokens?: number, perRowCharCap?: number): BudgetResult<R>;
|
|
70
|
+
export declare function applyRowBudget<R extends BudgetRow>(rows: R[], maxTokens?: number, perRowCharCap?: number, options?: BudgetOptions<R>): BudgetResult<R>;
|
|
71
|
+
/** A key longer than this is dropped by both hooks rather than truncated, so
|
|
72
|
+
* it costs nothing. Mirrors MAX_KEY_CHARS in both hook files. */
|
|
73
|
+
export declare const MAX_KEY_CHARS = 60;
|
|
74
|
+
/** Header, blank lines and footer the startup hook wraps around the rows.
|
|
75
|
+
* Sized against the longest footer variant (the one carrying the corpus
|
|
76
|
+
* count), so the reservation cannot come up short as the corpus grows. */
|
|
77
|
+
export declare const STARTUP_CHROME_TOKENS = 52;
|
|
78
|
+
/** Same for the mid-conversation hook, whose footer is a single short line. */
|
|
79
|
+
export declare const PROMPT_CHROME_TOKENS = 31;
|
|
80
|
+
/** Only the fields the hooks render alongside the content. Deliberately not
|
|
81
|
+
* extending BudgetRow: these functions receive the clipped text as their first
|
|
82
|
+
* argument and must never read `row.content`, which is the unclipped original. */
|
|
83
|
+
interface DecoratedRow {
|
|
84
|
+
confidence?: number;
|
|
85
|
+
key?: string | null;
|
|
86
|
+
}
|
|
87
|
+
/** Cost of one startup line: `- <content>[ (conf N.NN)][ [key: …]]` plus the
|
|
88
|
+
* newline joining it to the previous line. */
|
|
89
|
+
export declare function startupLineCost(clipped: string, row: DecoratedRow): number;
|
|
90
|
+
/** Cost of one mid-conversation line. No confidence suffix — that hook does
|
|
91
|
+
* not render one. */
|
|
92
|
+
export declare function promptLineCost(clipped: string, row: DecoratedRow): number;
|
|
93
|
+
export {};
|
|
38
94
|
//# sourceMappingURL=token-budget.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-budget.d.ts","sourceRoot":"","sources":["../../src/core/token-budget.ts"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"token-budget.d.ts","sourceRoot":"","sources":["../../src/core/token-budget.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH;;;;;;;+EAO+E;AAC/E,eAAO,MAAM,kBAAkB,MAAM,CAAA;AACrC,eAAO,MAAM,wBAAwB,MAAM,CAAA;AAI3C;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQtD;AAID;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMtE;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,SAAS;IAC/C,OAAO,EAAE,CAAC,EAAE,CAAA;IACZ,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,OAAO,CAAA;CACnB;AAED;gFACgF;AAChF,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,SAAS,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,MAAM,CAAA;AAEhF,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,SAAS;IAChD;uEACmE;IACnE,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;IACrB;;iEAE6D;IAC7D,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;;;;;;qBAQiB;IACjB,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAoBD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,SAAS,EAChD,IAAI,EAAE,CAAC,EAAE,EACT,SAAS,GAAE,MAA2B,EACtC,aAAa,GAAE,MAAiC,EAChD,OAAO,GAAE,aAAa,CAAC,CAAC,CAAM,GAC7B,YAAY,CAAC,CAAC,CAAC,CAmCjB;AAUD;kEACkE;AAClE,eAAO,MAAM,aAAa,KAAK,CAAA;AAE/B;;2EAE2E;AAC3E,eAAO,MAAM,qBAAqB,KAAK,CAAA;AAEvC,+EAA+E;AAC/E,eAAO,MAAM,oBAAoB,KAAK,CAAA;AAEtC;;mFAEmF;AACnF,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACpB;AAMD;+CAC+C;AAC/C,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,MAAM,CAK1E;AAED;sBACsB;AACtB,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,MAAM,CAEzE"}
|
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
/**
|
|
3
3
|
* Token budget primitives for recall output (Issue #12).
|
|
4
|
-
* Implementation of the
|
|
4
|
+
* Implementation of the injection budget contract documented in tutorial.md.
|
|
5
|
+
* The number lives in DEFAULT_MAX_TOKENS below, not in this sentence: stating
|
|
6
|
+
* it twice is how the file came to say "<300 tokens" three lines above the
|
|
7
|
+
* constant that reads 400.
|
|
5
8
|
*/
|
|
6
|
-
|
|
9
|
+
/** Total output budget for one SessionStart injection.
|
|
10
|
+
*
|
|
11
|
+
* Raised from 300 on 2026-09-11 alongside honest accounting. The old number
|
|
12
|
+
* was not a smaller budget, it was a wrong one: measured against the real hook
|
|
13
|
+
* with a corpus-shaped payload, a "300 token" injection emitted 363 because
|
|
14
|
+
* only `content` was priced. 400 keeps the same five rows reaching the reader
|
|
15
|
+
* now that the prefix, confidence suffix, [key: …] handle, header and footer
|
|
16
|
+
* are all counted. It buys no extra content — it stops the contract lying. */
|
|
17
|
+
export const DEFAULT_MAX_TOKENS = 400;
|
|
7
18
|
export const DEFAULT_PER_ROW_CHAR_CAP = 150;
|
|
8
19
|
const CJK_REGEX = /[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}]/u;
|
|
9
20
|
/**
|
|
@@ -38,6 +49,25 @@ export function truncateToChars(text, maxChars) {
|
|
|
38
49
|
return ELLIPSIS;
|
|
39
50
|
return chars.slice(0, maxChars - 1).join('') + ELLIPSIS;
|
|
40
51
|
}
|
|
52
|
+
/** Number of code points of `text` that fit in `budget` tokens.
|
|
53
|
+
*
|
|
54
|
+
* Walks from the front accumulating real cost rather than dividing by an
|
|
55
|
+
* average: the two scripts price an order of magnitude apart (CJK 1.0,
|
|
56
|
+
* Latin 0.3), so an average is wrong for any mixed string and silently
|
|
57
|
+
* overshoots on the CJK-heavy ones this exists to serve. */
|
|
58
|
+
function charsWithin(text, budget) {
|
|
59
|
+
if (budget <= 0)
|
|
60
|
+
return 0;
|
|
61
|
+
let used = 0;
|
|
62
|
+
let count = 0;
|
|
63
|
+
for (const ch of text) {
|
|
64
|
+
used += CJK_REGEX.test(ch) ? 1 : 0.3;
|
|
65
|
+
if (Math.ceil(used) > budget)
|
|
66
|
+
break;
|
|
67
|
+
count++;
|
|
68
|
+
}
|
|
69
|
+
return count;
|
|
70
|
+
}
|
|
41
71
|
/**
|
|
42
72
|
* Apply a token budget to a list of row-like objects with a `content` field.
|
|
43
73
|
* Per-row content is truncated to perRowCharCap (ellipsis-aware), cumulative
|
|
@@ -47,27 +77,101 @@ export function truncateToChars(text, maxChars) {
|
|
|
47
77
|
* Callers should touch/log only `emitted` ids — dropped rows never reached
|
|
48
78
|
* the client.
|
|
49
79
|
*/
|
|
50
|
-
export function applyRowBudget(rows, maxTokens = DEFAULT_MAX_TOKENS, perRowCharCap = DEFAULT_PER_ROW_CHAR_CAP) {
|
|
80
|
+
export function applyRowBudget(rows, maxTokens = DEFAULT_MAX_TOKENS, perRowCharCap = DEFAULT_PER_ROW_CHAR_CAP, options = {}) {
|
|
81
|
+
const costOf = options.costOf ?? ((clipped) => approximateTokens(clipped));
|
|
82
|
+
const reserved = options.reservedTokens ?? 0;
|
|
51
83
|
const emitted = [];
|
|
52
|
-
let used =
|
|
84
|
+
let used = reserved;
|
|
53
85
|
let truncated = false;
|
|
54
86
|
for (let i = 0; i < rows.length; i++) {
|
|
55
87
|
const row = rows[i];
|
|
56
88
|
const clipped = truncateToChars(row.content, perRowCharCap);
|
|
57
89
|
if (clipped !== row.content)
|
|
58
90
|
truncated = true;
|
|
59
|
-
const cost =
|
|
91
|
+
const cost = costOf(clipped, row);
|
|
60
92
|
if (used + cost > maxTokens) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
93
|
+
// The floor applies only to the first row: once something has been
|
|
94
|
+
// emitted, silence is no longer the failure mode this guards against.
|
|
95
|
+
if (options.minimumOneRow && emitted.length === 0) {
|
|
96
|
+
const trimmed = trimToBudget(clipped, row, maxTokens - used, costOf, perRowCharCap);
|
|
97
|
+
if (trimmed !== null) {
|
|
98
|
+
emitted.push({ ...row, content: trimmed });
|
|
99
|
+
return {
|
|
100
|
+
emitted,
|
|
101
|
+
droppedCount: rows.length - 1,
|
|
102
|
+
usedTokens: used + costOf(trimmed, row),
|
|
103
|
+
truncated: true,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return { emitted, droppedCount: rows.length - i, usedTokens: used, truncated };
|
|
67
108
|
}
|
|
68
109
|
emitted.push({ ...row, content: clipped });
|
|
69
110
|
used += cost;
|
|
70
111
|
}
|
|
71
112
|
return { emitted, droppedCount: 0, usedTokens: used, truncated };
|
|
72
113
|
}
|
|
114
|
+
// ── What the hooks actually render ──────────────────────────────────────────
|
|
115
|
+
//
|
|
116
|
+
// These mirror `formatStartupV1` in hooks/session-start.mjs and `formatRecall`
|
|
117
|
+
// in hooks/user-prompt-submit.mjs. Two copies of a format is how they drift
|
|
118
|
+
// apart, so tests/token-budget-honesty.test.ts spawns the real hooks and
|
|
119
|
+
// asserts the prediction against their actual stdout. Change a hook's
|
|
120
|
+
// rendering and that test fails — which is the point.
|
|
121
|
+
/** A key longer than this is dropped by both hooks rather than truncated, so
|
|
122
|
+
* it costs nothing. Mirrors MAX_KEY_CHARS in both hook files. */
|
|
123
|
+
export const MAX_KEY_CHARS = 60;
|
|
124
|
+
/** Header, blank lines and footer the startup hook wraps around the rows.
|
|
125
|
+
* Sized against the longest footer variant (the one carrying the corpus
|
|
126
|
+
* count), so the reservation cannot come up short as the corpus grows. */
|
|
127
|
+
export const STARTUP_CHROME_TOKENS = 52;
|
|
128
|
+
/** Same for the mid-conversation hook, whose footer is a single short line. */
|
|
129
|
+
export const PROMPT_CHROME_TOKENS = 31;
|
|
130
|
+
function handleFor(row) {
|
|
131
|
+
return row.key && row.key.length <= MAX_KEY_CHARS ? ` [key: ${row.key}]` : '';
|
|
132
|
+
}
|
|
133
|
+
/** Cost of one startup line: `- <content>[ (conf N.NN)][ [key: …]]` plus the
|
|
134
|
+
* newline joining it to the previous line. */
|
|
135
|
+
export function startupLineCost(clipped, row) {
|
|
136
|
+
const conf = row.confidence != null && row.confidence !== 1
|
|
137
|
+
? ` (conf ${Number(row.confidence).toFixed(2)})`
|
|
138
|
+
: '';
|
|
139
|
+
return approximateTokens(`- ${clipped}${conf}${handleFor(row)}`) + 1;
|
|
140
|
+
}
|
|
141
|
+
/** Cost of one mid-conversation line. No confidence suffix — that hook does
|
|
142
|
+
* not render one. */
|
|
143
|
+
export function promptLineCost(clipped, row) {
|
|
144
|
+
return approximateTokens(`- ${clipped}${handleFor(row)}`) + 1;
|
|
145
|
+
}
|
|
146
|
+
/** Longest prefix of `clipped` whose *rendered* cost fits `budget`, or null if
|
|
147
|
+
* even a minimal one does not.
|
|
148
|
+
*
|
|
149
|
+
* Budgets against the rendered cost, not the content's own: the decoration is
|
|
150
|
+
* charged per row whether the content is 150 characters or 5, so trimming
|
|
151
|
+
* against the raw length would overshoot by exactly the amount this change
|
|
152
|
+
* exists to stop hiding. Returns null rather than an empty string — an empty
|
|
153
|
+
* bullet costs the reader a line and tells them nothing. */
|
|
154
|
+
function trimToBudget(clipped, row, budget, costOf, perRowCharCap) {
|
|
155
|
+
if (budget <= 0)
|
|
156
|
+
return null;
|
|
157
|
+
const overhead = costOf('', row);
|
|
158
|
+
let chars = Math.min(charsWithin(clipped, budget - overhead), perRowCharCap);
|
|
159
|
+
// charsWithin works off raw content cost; the ellipsis truncateToChars adds
|
|
160
|
+
// and any rounding in costOf can still push it over. Walk down until it fits
|
|
161
|
+
// rather than trusting the estimate.
|
|
162
|
+
//
|
|
163
|
+
// Stops at MIN_TRIMMED_CHARS rather than 1: truncateToChars(text, 1) returns
|
|
164
|
+
// the ellipsis alone, and a bullet reading "- …" costs the reader a line to
|
|
165
|
+
// learn nothing. Below the floor there is no row worth emitting.
|
|
166
|
+
while (chars >= MIN_TRIMMED_CHARS) {
|
|
167
|
+
const candidate = truncateToChars(clipped, chars);
|
|
168
|
+
if (costOf(candidate, row) <= budget)
|
|
169
|
+
return candidate;
|
|
170
|
+
chars--;
|
|
171
|
+
}
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
/** Shortest trimmed row worth emitting. Under this the line is an ellipsis and
|
|
175
|
+
* a word or two — it occupies a slot and conveys nothing. */
|
|
176
|
+
const MIN_TRIMMED_CHARS = 12;
|
|
73
177
|
//# sourceMappingURL=token-budget.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-budget.js","sourceRoot":"","sources":["../../src/core/token-budget.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC
|
|
1
|
+
{"version":3,"file":"token-budget.js","sourceRoot":"","sources":["../../src/core/token-budget.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;;;;GAMG;AAEH;;;;;;;+EAO+E;AAC/E,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAA;AACrC,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,CAAA;AAE3C,MAAM,SAAS,GAAG,0EAA0E,CAAA;AAE5F;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,IAAI,GAAG,GAAG,CAAC,CAAA;IACX,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,KAAK,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;QACtB,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;YAAE,GAAG,EAAE,CAAA;;YACxB,KAAK,EAAE,CAAA;IACd,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,KAAK,GAAG,GAAG,CAAC,CAAA;AACrC,CAAC;AAED,MAAM,QAAQ,GAAG,GAAG,CAAA;AAEpB;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,QAAgB;IAC5D,IAAI,QAAQ,IAAI,CAAC;QAAE,OAAO,EAAE,CAAA;IAC5B,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC9B,IAAI,KAAK,CAAC,MAAM,IAAI,QAAQ;QAAE,OAAO,IAAI,CAAA;IACzC,IAAI,QAAQ,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAA;IACnC,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAA;AACzD,CAAC;AAqCD;;;;;6DAK6D;AAC7D,SAAS,WAAW,CAAC,IAAY,EAAE,MAAc;IAC/C,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,CAAC,CAAA;IACzB,IAAI,IAAI,GAAG,CAAC,CAAA;IACZ,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,KAAK,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;QACtB,IAAI,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;QACpC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM;YAAE,MAAK;QACnC,KAAK,EAAE,CAAA;IACT,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAC5B,IAAS,EACT,YAAoB,kBAAkB,EACtC,gBAAwB,wBAAwB,EAChD,UAA4B,EAAE;IAE9B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC,OAAe,EAAE,EAAE,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAA;IAClF,MAAM,QAAQ,GAAG,OAAO,CAAC,cAAc,IAAI,CAAC,CAAA;IAC5C,MAAM,OAAO,GAAQ,EAAE,CAAA;IACvB,IAAI,IAAI,GAAG,QAAQ,CAAA;IACnB,IAAI,SAAS,GAAG,KAAK,CAAA;IAErB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;QACnB,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,OAAO,EAAE,aAAa,CAAC,CAAA;QAC3D,IAAI,OAAO,KAAK,GAAG,CAAC,OAAO;YAAE,SAAS,GAAG,IAAI,CAAA;QAC7C,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;QAEjC,IAAI,IAAI,GAAG,IAAI,GAAG,SAAS,EAAE,CAAC;YAC5B,mEAAmE;YACnE,sEAAsE;YACtE,IAAI,OAAO,CAAC,aAAa,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAClD,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,CAAA;gBACnF,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;oBACrB,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,EAAE,OAAO,EAAE,OAAO,EAAO,CAAC,CAAA;oBAC/C,OAAO;wBACL,OAAO;wBACP,YAAY,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC;wBAC7B,UAAU,EAAE,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC;wBACvC,SAAS,EAAE,IAAI;qBAChB,CAAA;gBACH,CAAC;YACH,CAAC;YACD,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;QAChF,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,EAAE,OAAO,EAAE,OAAO,EAAO,CAAC,CAAA;QAC/C,IAAI,IAAI,IAAI,CAAA;IACd,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;AAClE,CAAC;AAED,+EAA+E;AAC/E,EAAE;AACF,+EAA+E;AAC/E,4EAA4E;AAC5E,yEAAyE;AACzE,sEAAsE;AACtE,sDAAsD;AAEtD;kEACkE;AAClE,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,CAAA;AAE/B;;2EAE2E;AAC3E,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAA;AAEvC,+EAA+E;AAC/E,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAA;AAUtC,SAAS,SAAS,CAAC,GAAiB;IAClC,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,aAAa,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;AAC/E,CAAC;AAED;+CAC+C;AAC/C,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,GAAiB;IAChE,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,IAAI,IAAI,IAAI,GAAG,CAAC,UAAU,KAAK,CAAC;QACzD,CAAC,CAAC,UAAU,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;QAChD,CAAC,CAAC,EAAE,CAAA;IACN,OAAO,iBAAiB,CAAC,KAAK,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;AACtE,CAAC;AAED;sBACsB;AACtB,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,GAAiB;IAC/D,OAAO,iBAAiB,CAAC,KAAK,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;AAC/D,CAAC;AAED;;;;;;;6DAO6D;AAC7D,SAAS,YAAY,CACnB,OAAe,EACf,GAAM,EACN,MAAc,EACd,MAAoB,EACpB,aAAqB;IAErB,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA;IAC5B,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;IAChC,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAAC,EAAE,aAAa,CAAC,CAAA;IAC5E,4EAA4E;IAC5E,6EAA6E;IAC7E,qCAAqC;IACrC,EAAE;IACF,6EAA6E;IAC7E,4EAA4E;IAC5E,iEAAiE;IACjE,OAAO,KAAK,IAAI,iBAAiB,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;QACjD,IAAI,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,IAAI,MAAM;YAAE,OAAO,SAAS,CAAA;QACtD,KAAK,EAAE,CAAA;IACT,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED;8DAC8D;AAC9D,MAAM,iBAAiB,GAAG,EAAE,CAAA"}
|
package/dist/mcp/tools.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import type { Database } from '../core/database.js';
|
|
2
|
+
import type { Database, MemoryOrigin } from '../core/database.js';
|
|
3
3
|
import { MemoryService } from '../core/memory-service.js';
|
|
4
4
|
import type { Memory, MemoryType, KnowledgeDepth } from '../core/types.js';
|
|
5
5
|
type McpTextResult = {
|
|
@@ -41,6 +41,7 @@ export declare function recallSaveHandler(db: Database, args: {
|
|
|
41
41
|
confidence?: number;
|
|
42
42
|
projectId?: string | null;
|
|
43
43
|
key?: string;
|
|
44
|
+
origin?: MemoryOrigin;
|
|
44
45
|
}): McpTextResult;
|
|
45
46
|
export declare function registerTools(server: McpServer, db: Database): void;
|
|
46
47
|
export {};
|
package/dist/mcp/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AACxE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AACxE,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAEjE,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AACzD,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAiB1E,KAAK,aAAa,GAAG;IACnB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC9C,OAAO,CAAC,EAAE,IAAI,CAAA;CACf,CAAA;AAmDD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,EAAE,CAAA;CACrB;AAED,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAAE,EAClB,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,MAA2B,GACrC,eAAe,CAMjB;AAED,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,QAAQ,EACZ,aAAa,EAAE,aAAa,EAC5B,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7E,aAAa,CAsBf;AA+BD,UAAU,YAAY;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,cAAc,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,YAAY,EAAE,EACxB,iBAAiB,EAAE,MAAM,EAAE,EAC3B,gBAAgB,EAAE,MAAM,EAAE,GAAG,IAAI,EACjC,QAAQ,EAAE,MAAM,EAAE,EAClB,SAAS,GAAE,MAA2B,GACrC,eAAe,CAmDjB;AAiBD,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,QAAQ,EACZ,aAAa,EAAE,aAAa,EAC5B,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACxF,aAAa,CA+Df;AAED,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,QAAQ,EACZ,IAAI,EAAE;IACJ,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,UAAU,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,YAAY,CAAA;CACtB,GACA,aAAa,CA2Ef;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,GAAG,IAAI,CAkJnE"}
|
package/dist/mcp/tools.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
import * as z from 'zod';
|
|
3
|
+
import { normaliseMessageUuid } from '../core/database.js';
|
|
3
4
|
import { MemoryService } from '../core/memory-service.js';
|
|
4
5
|
import { deriveDepth } from '../core/types.js';
|
|
5
6
|
import { normalizeTopicKey, extractTopicsFromContent } from '../core/topic-extractor.js';
|
|
@@ -83,10 +84,21 @@ const recallSaveInput = {
|
|
|
83
84
|
content: z.string().min(1).describe('Memory content — the fact or insight to remember'),
|
|
84
85
|
type: z.enum(MEMORY_TYPES).describe('Memory category'),
|
|
85
86
|
sessionId: z.string().nullable().optional().describe('Origin session ID (optional)'),
|
|
86
|
-
messageId: z.string().nullable().optional().describe('
|
|
87
|
+
messageId: z.string().nullable().optional().describe('The uuid of the single message this memory came from. Post-session ' +
|
|
88
|
+
'extraction reads it from the transcript header (`--- human [<uuid>] ---`). ' +
|
|
89
|
+
'Checked against the messages of the session named in sessionId: a uuid ' +
|
|
90
|
+
'that session does not hold is dropped and the memory is saved without it, ' +
|
|
91
|
+
'so omit this rather than guess. Storing a citation does not assert that ' +
|
|
92
|
+
'the cited message proves the memory — it records where it came from.'),
|
|
87
93
|
confidence: z.number().min(0).max(1).optional().describe('Confidence 0-1 (default 1)'),
|
|
88
94
|
projectId: z.string().nullable().optional().describe('Project ID for scoped queries. Session-backed memories derive this from sessions.project_id automatically. Omit projectId for knowledge reusable across all projects.'),
|
|
89
95
|
key: z.string().min(1).max(100).optional().describe('Stable hyphenated slug for dedup (e.g. "sqlite-wal-truncate-checkpoint"). Same (projectId, key) updates instead of creating a duplicate.'),
|
|
96
|
+
origin: z.enum(['explicit', 'agent-inferred']).optional().describe('Who is writing. Leave unset (defaults to "explicit") whenever a human is in ' +
|
|
97
|
+
'the conversation — including when you decide on your own that something is ' +
|
|
98
|
+
'worth saving mid-session. Set "agent-inferred" ONLY from the automated ' +
|
|
99
|
+
'post-session extraction pass, which reads a finished transcript with nobody ' +
|
|
100
|
+
'watching. The difference is enforced: an agent-inferred save will not ' +
|
|
101
|
+
'overwrite an existing explicit memory under the same key.'),
|
|
90
102
|
};
|
|
91
103
|
export function formatContextResult(clusters, unmatchedKeywords, fallbackMemories, keywords, maxTokens = DEFAULT_MAX_TOKENS) {
|
|
92
104
|
if (clusters.length === 0 && (!fallbackMemories || fallbackMemories.length === 0)) {
|
|
@@ -211,14 +223,50 @@ export function recallContextHandler(db, memoryService, args) {
|
|
|
211
223
|
}
|
|
212
224
|
export function recallSaveHandler(db, args) {
|
|
213
225
|
try {
|
|
226
|
+
// Q1 (2026-09-11): a citation is stored only if this session really holds
|
|
227
|
+
// that message. The model is a small one copying a 36-char hex string out
|
|
228
|
+
// of a 200KB transcript, so the failure to design against is not refusal
|
|
229
|
+
// but a plausible-looking wrong value — `message_id` reads as evidence,
|
|
230
|
+
// and evidence that can be invented is worse than an empty column.
|
|
231
|
+
//
|
|
232
|
+
// Verification failure drops the citation and keeps the memory: provenance
|
|
233
|
+
// is additive, never a gate on content. The note back to the caller says
|
|
234
|
+
// so explicitly, because an extraction run has a hard turn budget
|
|
235
|
+
// (--max-turns 5) and a retry loop would cost saves it has not made yet.
|
|
236
|
+
let messageId = null;
|
|
237
|
+
let provenanceNote = '';
|
|
238
|
+
const citedMessageId = normaliseMessageUuid(args.messageId);
|
|
239
|
+
if (citedMessageId !== null) {
|
|
240
|
+
if (db.hasMessageUuid(citedMessageId, args.sessionId ?? null)) {
|
|
241
|
+
messageId = citedMessageId;
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
// Where this trace actually lands (measured 2026-09-11): NOT in the
|
|
245
|
+
// extraction wrapper's extract.log.jsonl. Claude Code does not forward
|
|
246
|
+
// an MCP server's stderr to its own — it captures it into a per-project
|
|
247
|
+
// MCP log, on macOS ~/Library/Caches/claude-cli-nodejs/<projectId>/
|
|
248
|
+
// mcp-logs-ccrecall/<ts>.jsonl, one entry per line prefixed
|
|
249
|
+
// `Server stderr:`. Measured against the banner every launch prints:
|
|
250
|
+
// 0 of 590 wrapper runs captured it, while the MCP log holds it every
|
|
251
|
+
// time. Look in the wrong file and a dropped citation reads as
|
|
252
|
+
// byte-identical to a model that never cited anything — the same
|
|
253
|
+
// silent-miss shape #75 took months to notice.
|
|
254
|
+
console.warn('[recall_save] messageId failed verification (unknown uuid, or a message ' +
|
|
255
|
+
'from a different session) — provenance dropped, memory saved');
|
|
256
|
+
provenanceNote =
|
|
257
|
+
' — the supplied messageId is not a message of this session and was dropped; ' +
|
|
258
|
+
'the memory itself is saved, so do not retry';
|
|
259
|
+
}
|
|
260
|
+
}
|
|
214
261
|
const id = db.saveMemory({
|
|
215
262
|
sessionId: args.sessionId ?? null,
|
|
216
|
-
messageId
|
|
263
|
+
messageId,
|
|
217
264
|
content: args.content,
|
|
218
265
|
type: args.type,
|
|
219
266
|
confidence: args.confidence ?? 1,
|
|
220
267
|
projectId: args.projectId ?? null,
|
|
221
268
|
key: args.key ?? null,
|
|
269
|
+
origin: args.origin,
|
|
222
270
|
});
|
|
223
271
|
// Auto topic extraction — Phase 3 Tier 0 needs memory_topics to exist.
|
|
224
272
|
// Resolve projectId the same way saveMemory does (session-backed →
|
|
@@ -242,7 +290,7 @@ export function recallSaveHandler(db, args) {
|
|
|
242
290
|
console.warn('[recall_save] topic extraction failed:', err instanceof Error ? err.message : String(err));
|
|
243
291
|
}
|
|
244
292
|
}
|
|
245
|
-
return textResult(`Saved memory #${id} (type: ${args.type})`);
|
|
293
|
+
return textResult(`Saved memory #${id} (type: ${args.type})${provenanceNote}`);
|
|
246
294
|
}
|
|
247
295
|
catch (err) {
|
|
248
296
|
return textError('Error saving memory', err);
|
package/dist/mcp/tools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
//
|
|
3
|
+
// #95: mode for the directory and files under ~/.ccrecall.
|
|
4
|
+
//
|
|
5
|
+
// ⚠️ Deliberately a second copy of src/core/secure-dir.ts. The hooks ship as
|
|
6
|
+
// standalone .mjs installed via npm and are never bundled through the
|
|
7
|
+
// TypeScript build, so importing the compiled module is not an option — the
|
|
8
|
+
// same reason hooks/lib/project-id.mjs exists beside src/core/project-id.ts.
|
|
9
|
+
// tests/ccrecall-dir-permissions.test.ts imports both and asserts they agree,
|
|
10
|
+
// which is what keeps them from drifting apart.
|
|
11
|
+
import { mkdirSync, chmodSync } from 'node:fs'
|
|
12
|
+
import os from 'node:os'
|
|
13
|
+
import path from 'node:path'
|
|
14
|
+
|
|
15
|
+
export const CCRECALL_DIR_MODE = 0o700
|
|
16
|
+
export const CCRECALL_FILE_MODE = 0o600
|
|
17
|
+
|
|
18
|
+
/** Resolved per call, never at module load: tests move $HOME, and a frozen
|
|
19
|
+
* value would answer about the real home directory instead. */
|
|
20
|
+
function isOurs(dir) {
|
|
21
|
+
const root = path.join(os.homedir(), '.ccrecall')
|
|
22
|
+
const resolved = path.resolve(dir)
|
|
23
|
+
return resolved === root || resolved.startsWith(root + path.sep)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Create a ccRecall directory 0700, and repair one we already own. */
|
|
27
|
+
export function ensureCcrecallDir(dir) {
|
|
28
|
+
mkdirSync(dir, { recursive: true, mode: CCRECALL_DIR_MODE })
|
|
29
|
+
// Existing directories keep their mode through mkdirSync, so the repair is
|
|
30
|
+
// what reaches installs that predate this. Limited to paths we own: PR #94
|
|
31
|
+
// re-moded a user's project directory by doing this to a configurable path
|
|
32
|
+
// and was reverted twice.
|
|
33
|
+
if (isOurs(dir)) {
|
|
34
|
+
try {
|
|
35
|
+
chmodSync(dir, CCRECALL_DIR_MODE)
|
|
36
|
+
} catch {
|
|
37
|
+
// Raced away or owned by another user; a mode must never fail the hook.
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Hold a ccRecall file at 0600, whoever chose its location. */
|
|
43
|
+
export function secureCcrecallFile(file) {
|
|
44
|
+
// Unconditional: a user-chosen location does not make the file someone
|
|
45
|
+
// else's. Also the only thing that repairs a log already at 0644, since the
|
|
46
|
+
// `mode` option applies solely when a file is created.
|
|
47
|
+
try {
|
|
48
|
+
chmodSync(file, CCRECALL_FILE_MODE)
|
|
49
|
+
} catch {
|
|
50
|
+
// Not there yet, or not ours.
|
|
51
|
+
}
|
|
52
|
+
}
|
package/hooks/session-start.mjs
CHANGED
|
@@ -13,11 +13,14 @@ import fs from 'node:fs'
|
|
|
13
13
|
import path from 'node:path'
|
|
14
14
|
import os from 'node:os'
|
|
15
15
|
import { resolveProjectId } from './lib/project-id.mjs'
|
|
16
|
+
import { ensureCcrecallDir, secureCcrecallFile, CCRECALL_FILE_MODE } from './lib/secure-dir.mjs'
|
|
16
17
|
|
|
17
18
|
const PORT = Number(process.env.CCRECALL_PORT ?? 7749)
|
|
18
19
|
const HOST = '127.0.0.1'
|
|
19
20
|
const TIMEOUT_MS = 2000
|
|
20
21
|
const MEMORY_LIMIT = 5
|
|
22
|
+
// Legacy strategy only. /memory/query treats an absent maxTokens as "no budget
|
|
23
|
+
// at all" and would emit whole memories, so this one still has to be sent.
|
|
21
24
|
const MAX_TOKENS = 300
|
|
22
25
|
// A key longer than this is not rendered at all rather than truncated: a clipped
|
|
23
26
|
// key is a handle that silently resolves to nothing. Observed keys run to 52
|
|
@@ -82,11 +85,16 @@ async function queryLegacy(query, projectId) {
|
|
|
82
85
|
}
|
|
83
86
|
|
|
84
87
|
async function queryStartupV1(query, projectId, sessionId) {
|
|
88
|
+
// No maxTokens: the daemon owns budget policy, same as the prompt hook. It
|
|
89
|
+
// prices the rendered line — prefix, confidence suffix, [key: …] handle,
|
|
90
|
+
// header and footer — and this file is the thing being priced, so it cannot
|
|
91
|
+
// be the one naming the number. It also means an upgrade to the service
|
|
92
|
+
// changes the budget without rewriting a hook already installed in the
|
|
93
|
+
// user's settings.json.
|
|
85
94
|
const params = new URLSearchParams({
|
|
86
95
|
project: projectId,
|
|
87
96
|
q: query,
|
|
88
97
|
limit: String(MEMORY_LIMIT),
|
|
89
|
-
maxTokens: String(MAX_TOKENS),
|
|
90
98
|
})
|
|
91
99
|
if (sessionId) params.set('sessionId', sessionId)
|
|
92
100
|
const result = await httpGet(`/memory/startup?${params.toString()}`)
|
|
@@ -101,8 +109,17 @@ async function queryStartupV1(query, projectId, sessionId) {
|
|
|
101
109
|
function writeTelemetry(record) {
|
|
102
110
|
if (TELEMETRY_OFF) return
|
|
103
111
|
try {
|
|
104
|
-
|
|
105
|
-
|
|
112
|
+
// #95: this hook runs on every session start, which made it the creator
|
|
113
|
+
// that in practice decided ~/.ccrecall's mode — 0755 on the dogfood
|
|
114
|
+
// machine. secureCcrecallFile also repairs a log already sitting at 0644,
|
|
115
|
+
// which appendFileSync's own `mode` option would not: that applies only
|
|
116
|
+
// when the file is created.
|
|
117
|
+
ensureCcrecallDir(path.dirname(TELEMETRY_PATH))
|
|
118
|
+
fs.appendFileSync(TELEMETRY_PATH, JSON.stringify(record) + '\n', {
|
|
119
|
+
encoding: 'utf8',
|
|
120
|
+
mode: CCRECALL_FILE_MODE,
|
|
121
|
+
})
|
|
122
|
+
secureCcrecallFile(TELEMETRY_PATH)
|
|
106
123
|
} catch (err) {
|
|
107
124
|
console.error(`[ccRecall] telemetry write failed: ${err.message}`)
|
|
108
125
|
}
|