chat-recall 0.5.4 → 0.5.6
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/dist/cli.js +1506 -733
- package/dist/cli.js.map +1 -1
- package/dist/mcp-diagnostics.d.ts +45 -0
- package/dist/mcp-diagnostics.d.ts.map +1 -0
- package/dist/mcp-diagnostics.js +98 -0
- package/dist/mcp-diagnostics.js.map +1 -0
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +2096 -1151
- package/dist/mcp.js.map +1 -1
- package/dist/project-tasks.d.ts.map +1 -1
- package/dist/project-tasks.js +12 -7
- package/dist/project-tasks.js.map +1 -1
- package/dist/service-installer.d.ts +1 -1
- package/dist/service-installer.d.ts.map +1 -1
- package/dist/service-installer.js +20 -6
- package/dist/service-installer.js.map +1 -1
- package/dist/sync-client.d.ts +1 -0
- package/dist/sync-client.d.ts.map +1 -1
- package/dist/sync-client.js +179 -92
- package/dist/sync-client.js.map +1 -1
- package/dist/sync-ledger.d.ts +22 -0
- package/dist/sync-ledger.d.ts.map +1 -1
- package/dist/sync-ledger.js +108 -1
- package/dist/sync-ledger.js.map +1 -1
- package/dist/watch.js +1104 -481
- package/hooks/chat_recall_escalate_hook.sh +28 -2
- package/hooks/chat_recall_save_hook.sh +17 -11
- package/hooks/chat_recall_wakeup_hook.sh +27 -1
- package/package.json +7 -3
- package/skills/chat-recall/SKILL.md +3 -2
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the MCP tells an agent when something is refused or stale.
|
|
3
|
+
*
|
|
4
|
+
* Pure functions, in their own module so they are testable without importing
|
|
5
|
+
* mcp.ts — which registers handlers and starts a server on import.
|
|
6
|
+
*
|
|
7
|
+
* Both exist because of the same class of bug: an answer that looks fine and
|
|
8
|
+
* isn't. A 402 that read "request rejected" told an agent nothing, and a search
|
|
9
|
+
* over a history that stopped growing three weeks ago looked exactly like a
|
|
10
|
+
* search over a current one.
|
|
11
|
+
*/
|
|
12
|
+
/** The tenant's entitlement, as the server reports it. */
|
|
13
|
+
export interface SyncState {
|
|
14
|
+
/** The server's OWN answer. Never re-derived here from status and dates: that
|
|
15
|
+
* is a second copy of the gate's decision, and a second copy drifts. */
|
|
16
|
+
entitled: boolean;
|
|
17
|
+
status: string;
|
|
18
|
+
periodEnd: number | null;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Turn a failed response into something an agent can act on.
|
|
22
|
+
*
|
|
23
|
+
* The status alone is not enough, and 402 proved it: every payment and
|
|
24
|
+
* entitlement refusal fell through to "request rejected", so an agent whose sync
|
|
25
|
+
* had stopped learned nothing, retried, and reported a vague failure. The server
|
|
26
|
+
* already answers precisely — `error`, `detail`, `checkoutHint`, `resendHint`,
|
|
27
|
+
* and for a feature gate `feature` / `requires` / `upgradeUrl` — and all of it
|
|
28
|
+
* was being discarded in favour of the number.
|
|
29
|
+
*/
|
|
30
|
+
export declare function buildHttpError(path: string, res: Response): Promise<Error>;
|
|
31
|
+
/**
|
|
32
|
+
* The line prepended to every successful read while sync is paused.
|
|
33
|
+
*
|
|
34
|
+
* A lapsed tenant keeps read access, so searches keep answering — from data that
|
|
35
|
+
* stopped growing when the subscription ended. The agent cannot see that, so it
|
|
36
|
+
* will state that work does not exist when it simply was not indexed. The banner
|
|
37
|
+
* therefore does three things: says sync stopped, says when, and tells the agent
|
|
38
|
+
* what conclusion NOT to draw.
|
|
39
|
+
*
|
|
40
|
+
* Returns null when entitled, and when the state is unknown — an unreachable
|
|
41
|
+
* billing endpoint must not decorate every answer with a warning it cannot
|
|
42
|
+
* substantiate.
|
|
43
|
+
*/
|
|
44
|
+
export declare function stalenessBanner(state: SyncState | null): string | null;
|
|
45
|
+
//# sourceMappingURL=mcp-diagnostics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-diagnostics.d.ts","sourceRoot":"","sources":["../src/mcp-diagnostics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,0DAA0D;AAC1D,MAAM,WAAW,SAAS;IACxB;6EACyE;IACzE,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,CAgChF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAwBtE"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the MCP tells an agent when something is refused or stale.
|
|
3
|
+
*
|
|
4
|
+
* Pure functions, in their own module so they are testable without importing
|
|
5
|
+
* mcp.ts — which registers handlers and starts a server on import.
|
|
6
|
+
*
|
|
7
|
+
* Both exist because of the same class of bug: an answer that looks fine and
|
|
8
|
+
* isn't. A 402 that read "request rejected" told an agent nothing, and a search
|
|
9
|
+
* over a history that stopped growing three weeks ago looked exactly like a
|
|
10
|
+
* search over a current one.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Turn a failed response into something an agent can act on.
|
|
14
|
+
*
|
|
15
|
+
* The status alone is not enough, and 402 proved it: every payment and
|
|
16
|
+
* entitlement refusal fell through to "request rejected", so an agent whose sync
|
|
17
|
+
* had stopped learned nothing, retried, and reported a vague failure. The server
|
|
18
|
+
* already answers precisely — `error`, `detail`, `checkoutHint`, `resendHint`,
|
|
19
|
+
* and for a feature gate `feature` / `requires` / `upgradeUrl` — and all of it
|
|
20
|
+
* was being discarded in favour of the number.
|
|
21
|
+
*/
|
|
22
|
+
export async function buildHttpError(path, res) {
|
|
23
|
+
const status = res.status;
|
|
24
|
+
let body = null;
|
|
25
|
+
try {
|
|
26
|
+
body = await res.clone().json();
|
|
27
|
+
}
|
|
28
|
+
catch { /* not JSON */ }
|
|
29
|
+
const str = (k) => (typeof body?.[k] === 'string' ? body[k] : '');
|
|
30
|
+
if (status === 402) {
|
|
31
|
+
// Three distinct reasons with three distinct fixes. Telling someone to
|
|
32
|
+
// subscribe when they need to click a link in their inbox is a wrong
|
|
33
|
+
// message, not a terse one.
|
|
34
|
+
const parts = [str('error') || 'payment required'];
|
|
35
|
+
if (str('detail'))
|
|
36
|
+
parts.push(str('detail'));
|
|
37
|
+
if (str('feature')) {
|
|
38
|
+
parts.push(`This is the "${str('feature')}" capability${str('requires') ? `, on the ${str('requires')} plan` : ''}.`);
|
|
39
|
+
}
|
|
40
|
+
if (str('upgradeUrl'))
|
|
41
|
+
parts.push(`Upgrade: ${str('upgradeUrl')}`);
|
|
42
|
+
if (str('checkoutHint'))
|
|
43
|
+
parts.push(str('checkoutHint'));
|
|
44
|
+
if (str('resendHint'))
|
|
45
|
+
parts.push(str('resendHint'));
|
|
46
|
+
// "Reads still work" was the OLD lapse contract (blanket read-only). The
|
|
47
|
+
// free tier replaced it: feature-level 402s refuse READS of paid tools too,
|
|
48
|
+
// so promising reads on the error a failed read raised gaslights the agent.
|
|
49
|
+
parts.push('Nothing has been deleted. The free plan keeps sync and recent-history search working.');
|
|
50
|
+
return new Error(`server ${path}: ${parts.join(' ')}`);
|
|
51
|
+
}
|
|
52
|
+
const hint = status === 401 || status === 403 ? 'auth failed — re-run `chat-recall login <server-url>`' :
|
|
53
|
+
status === 404 ? 'not found — the id may be wrong, or the server is older than this CLI' :
|
|
54
|
+
status === 429 ? 'rate limited — retry in a moment' :
|
|
55
|
+
status >= 500 ? 'server error — check the chat-recall server logs' :
|
|
56
|
+
str('error') || str('detail') || 'request rejected';
|
|
57
|
+
return new Error(`server ${path}: HTTP ${status} (${hint})`);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The line prepended to every successful read while sync is paused.
|
|
61
|
+
*
|
|
62
|
+
* A lapsed tenant keeps read access, so searches keep answering — from data that
|
|
63
|
+
* stopped growing when the subscription ended. The agent cannot see that, so it
|
|
64
|
+
* will state that work does not exist when it simply was not indexed. The banner
|
|
65
|
+
* therefore does three things: says sync stopped, says when, and tells the agent
|
|
66
|
+
* what conclusion NOT to draw.
|
|
67
|
+
*
|
|
68
|
+
* Returns null when entitled, and when the state is unknown — an unreachable
|
|
69
|
+
* billing endpoint must not decorate every answer with a warning it cannot
|
|
70
|
+
* substantiate.
|
|
71
|
+
*/
|
|
72
|
+
export function stalenessBanner(state) {
|
|
73
|
+
if (!state || state.entitled)
|
|
74
|
+
return null;
|
|
75
|
+
const since = state.periodEnd ? new Date(state.periodEnd).toISOString().slice(0, 10) : null;
|
|
76
|
+
const days = state.periodEnd
|
|
77
|
+
? Math.max(0, Math.floor((Date.now() - state.periodEnd) / 86_400_000))
|
|
78
|
+
: null;
|
|
79
|
+
const reason = state.status === 'trialing'
|
|
80
|
+
? 'the trial has ended'
|
|
81
|
+
: state.status === 'past_due'
|
|
82
|
+
? 'a payment has not gone through'
|
|
83
|
+
: 'the subscription has lapsed';
|
|
84
|
+
// What the agent must get right about a dormant account: READS are complete.
|
|
85
|
+
// Two earlier versions of this text were wrong in opposite directions —
|
|
86
|
+
// "sync is paused, search is read-only", then "sync continues under a monthly
|
|
87
|
+
// quota, search covers the recent window". Since 2026-08-22 exactly one thing
|
|
88
|
+
// stops, and it is ingest.
|
|
89
|
+
return [
|
|
90
|
+
`⚠ SYNCING IS OFF — ${reason}.`,
|
|
91
|
+
'Search and lists cover the WHOLE synced history; nothing is windowed or locked.',
|
|
92
|
+
since ? `The plan lapsed ${since}${days !== null ? ` (${days} days ago)` : ''}.` : '',
|
|
93
|
+
'What is missing is only work done SINCE the lapse, because new sessions stopped uploading.',
|
|
94
|
+
'Do not tell the user their history is gone or locked. Say new sessions are not syncing, and that '
|
|
95
|
+
+ 'subscribing plus one `chat-recall sync --full` brings everything current. Export always works.',
|
|
96
|
+
].filter(Boolean).join(' ');
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=mcp-diagnostics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-diagnostics.js","sourceRoot":"","sources":["../src/mcp-diagnostics.ts"],"names":[],"mappings":"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"}
|
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;AA4BH,OAAO,4CAA4C,CAAC"}
|