chat-recall 0.6.3 → 0.6.5
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 +3 -3
- package/dist/cli.js +21 -10
- package/dist/cli.js.map +1 -1
- package/dist/mcp-relay.js +1 -1
- package/dist/mcp.js +224 -17
- package/dist/service-installer.d.ts.map +1 -1
- package/dist/service-installer.js +19 -2
- package/dist/service-installer.js.map +1 -1
- package/dist/watch.js +21 -11
- package/package.json +1 -1
- package/skills/chat-recall/SKILL.md +2 -1
- package/skills/chat-recall-memory/SKILL.md +18 -2
package/dist/mcp-relay.js
CHANGED
|
@@ -118,7 +118,7 @@ function daemonEnabled() {
|
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
// src/mcp-relay.ts
|
|
121
|
-
var VERSION = true ? "0.6.
|
|
121
|
+
var VERSION = true ? "0.6.5" : "0.0.0";
|
|
122
122
|
var SERVER_URL = new URL("./mcp.js", import.meta.url);
|
|
123
123
|
var SERVER_PATH = fileURLToPath(SERVER_URL);
|
|
124
124
|
var START_TIMEOUT_MS = 15e3;
|
package/dist/mcp.js
CHANGED
|
@@ -15259,12 +15259,12 @@ function extractEntities(text, context = {}) {
|
|
|
15259
15259
|
if (chosen && looksLikeStrictTool(chosen) && looksLikeStrictTool(rejected)) {
|
|
15260
15260
|
const c = canonTool(chosen), r = canonTool(rejected);
|
|
15261
15261
|
if (projectName)
|
|
15262
|
-
addTriple(projectName, "chose", c,
|
|
15263
|
-
addTriple(projectName || "project", "rejected", r,
|
|
15264
|
-
addTriple(c, "chosen_over", r,
|
|
15262
|
+
addTriple(projectName, "chose", c, DECISION_GUESS_CONFIDENCE);
|
|
15263
|
+
addTriple(projectName || "project", "rejected", r, DECISION_GUESS_CONFIDENCE);
|
|
15264
|
+
addTriple(c, "chosen_over", r, DECISION_GUESS_CONFIDENCE);
|
|
15265
15265
|
}
|
|
15266
15266
|
} else if (chosen && looksLikeDecisionObject(chosen) && projectName) {
|
|
15267
|
-
addTriple(projectName, "chose", canonTool(chosen),
|
|
15267
|
+
addTriple(projectName, "chose", canonTool(chosen), DECISION_GUESS_CONFIDENCE);
|
|
15268
15268
|
}
|
|
15269
15269
|
}
|
|
15270
15270
|
}
|
|
@@ -15301,7 +15301,7 @@ function extractEntities(text, context = {}) {
|
|
|
15301
15301
|
}
|
|
15302
15302
|
return triples;
|
|
15303
15303
|
}
|
|
15304
|
-
var KNOWN_TOOLS, AMBIGUOUS_TOOLS, toolContextRe, TOOL_PATTERNS, DECISION_PATTERNS2, DECISION_OBJECT_STOPWORDS, KNOWN_TOOL_NAMES, CANONICAL_TOOL, canonTool, PROJECT_PATH_PATTERN, PEOPLE_PATTERNS, NOT_PEOPLE;
|
|
15304
|
+
var KNOWN_TOOLS, AMBIGUOUS_TOOLS, toolContextRe, TOOL_PATTERNS, DECISION_PATTERNS2, DECISION_OBJECT_STOPWORDS, KNOWN_TOOL_NAMES, CANONICAL_TOOL, canonTool, DECISION_GUESS_CONFIDENCE, PROJECT_PATH_PATTERN, PEOPLE_PATTERNS, NOT_PEOPLE;
|
|
15305
15305
|
var init_entity_extractor = __esm({
|
|
15306
15306
|
"../engine/dist/core/entity-extractor.js"() {
|
|
15307
15307
|
"use strict";
|
|
@@ -15522,6 +15522,7 @@ var init_entity_extractor = __esm({
|
|
|
15522
15522
|
"nextjs": "next.js"
|
|
15523
15523
|
};
|
|
15524
15524
|
canonTool = (n) => CANONICAL_TOOL[n.toLowerCase()] ?? n;
|
|
15525
|
+
DECISION_GUESS_CONFIDENCE = 0.6;
|
|
15525
15526
|
PROJECT_PATH_PATTERN = /\/(?:home|Users)\/\w+\/(?:code|projects|work|dev|src)\/(?:\w+\/)?([a-zA-Z][a-zA-Z0-9_-]{1,40})/g;
|
|
15526
15527
|
PEOPLE_PATTERNS = [
|
|
15527
15528
|
/\b(?:my name is|I'm|I am)\s+([A-Z][a-z]{1,15}(?:\s+[A-Z][a-z]{1,15})?)/g,
|
|
@@ -19727,7 +19728,7 @@ var init_http = __esm({
|
|
|
19727
19728
|
CLI_VERSION = JSON.parse(readFileSync35(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION;
|
|
19728
19729
|
} catch {
|
|
19729
19730
|
try {
|
|
19730
|
-
if (true) CLI_VERSION = "0.6.
|
|
19731
|
+
if (true) CLI_VERSION = "0.6.5";
|
|
19731
19732
|
} catch {
|
|
19732
19733
|
}
|
|
19733
19734
|
}
|
|
@@ -20247,7 +20248,7 @@ var init_telemetry = __esm({
|
|
|
20247
20248
|
init_sync_client();
|
|
20248
20249
|
cliVersion2 = () => {
|
|
20249
20250
|
try {
|
|
20250
|
-
return true ? "0.6.
|
|
20251
|
+
return true ? "0.6.5" : "dev";
|
|
20251
20252
|
} catch {
|
|
20252
20253
|
return "dev";
|
|
20253
20254
|
}
|
|
@@ -22157,7 +22158,7 @@ var init_sync_client = __esm({
|
|
|
22157
22158
|
ownVersion = JSON.parse(readFileSync37(join48(dir, "../package.json"), "utf-8")).version || ownVersion;
|
|
22158
22159
|
} catch {
|
|
22159
22160
|
try {
|
|
22160
|
-
if (true) ownVersion = "0.6.
|
|
22161
|
+
if (true) ownVersion = "0.6.5";
|
|
22161
22162
|
} catch {
|
|
22162
22163
|
}
|
|
22163
22164
|
}
|
|
@@ -22625,6 +22626,8 @@ function refreshServiceDefinition() {
|
|
|
22625
22626
|
const { watchJs, node, logFile } = resolveDaemonPaths();
|
|
22626
22627
|
const unitPath = join51(homedir17(), ".config", "systemd", "user", "chat-recall-watch.service");
|
|
22627
22628
|
if (!existsSync46(unitPath)) return false;
|
|
22629
|
+
const current = readFileSync41(unitPath, "utf8");
|
|
22630
|
+
if (!current.includes(watchJs)) return false;
|
|
22628
22631
|
const wanted = renderSystemdUnit(watchJs, node, logFile);
|
|
22629
22632
|
if (readFileSync41(unitPath, "utf8") === wanted) return false;
|
|
22630
22633
|
writeFileSync13(unitPath, wanted);
|
|
@@ -22673,6 +22676,14 @@ function renderSystemdUnit(watchJs, node, logFile) {
|
|
|
22673
22676
|
"[Unit]",
|
|
22674
22677
|
"Description=chat-recall live indexer (sessions \u2192 local index, optional server sync)",
|
|
22675
22678
|
"After=default.target",
|
|
22679
|
+
// NEVER STOP RETRYING, and it must be in [Unit] — systemd reads the start
|
|
22680
|
+
// limiter there and ignores it under [Service], silently. The default gives
|
|
22681
|
+
// up after a burst and leaves the unit dead until a human notices: 53
|
|
22682
|
+
// restarts here, then "Start request repeated too quickly", then twelve
|
|
22683
|
+
// hours with nothing collected and nothing said. A collector that stops
|
|
22684
|
+
// forever after a crash loop is worse than one that keeps crashing.
|
|
22685
|
+
// 0 disables the limiter, so RestartSec below is the only pacing.
|
|
22686
|
+
"StartLimitIntervalSec=0",
|
|
22676
22687
|
"",
|
|
22677
22688
|
"[Service]",
|
|
22678
22689
|
// Bounded heap: the daemon does bursty batch work (transcript parse,
|
|
@@ -22695,7 +22706,6 @@ function renderSystemdUnit(watchJs, node, logFile) {
|
|
|
22695
22706
|
// that stops forever after a crash loop is worse than one that keeps
|
|
22696
22707
|
// crashing: the user is told nothing and their history silently ends.
|
|
22697
22708
|
// 0 disables the limiter, so RestartSec above is the only pacing.
|
|
22698
|
-
"StartLimitIntervalSec=0",
|
|
22699
22709
|
// A bounded cgroup, so a leak becomes a restart rather than a machine that
|
|
22700
22710
|
// swaps. MemoryHigh throttles and reclaims first; MemoryMax is the kill.
|
|
22701
22711
|
// --max-old-space-size bounds the V8 heap and NOT Buffers, and the observed
|
|
@@ -22999,6 +23009,118 @@ function resumeCommandFor(sessionId, tool) {
|
|
|
22999
23009
|
|
|
23000
23010
|
// ../engine/dist/mcp/tools.js
|
|
23001
23011
|
init_project_resolver();
|
|
23012
|
+
|
|
23013
|
+
// ../engine/dist/core/decision-areas.js
|
|
23014
|
+
var DECISION_AREAS = [
|
|
23015
|
+
"auth",
|
|
23016
|
+
"database",
|
|
23017
|
+
"payments",
|
|
23018
|
+
"api",
|
|
23019
|
+
"frontend",
|
|
23020
|
+
"deploy",
|
|
23021
|
+
"testing",
|
|
23022
|
+
"observability",
|
|
23023
|
+
"security",
|
|
23024
|
+
"pricing",
|
|
23025
|
+
"licensing",
|
|
23026
|
+
"positioning"
|
|
23027
|
+
];
|
|
23028
|
+
var AREA_SET = new Set(DECISION_AREAS);
|
|
23029
|
+
var AREA_ALIASES = {
|
|
23030
|
+
// auth
|
|
23031
|
+
authentication: "auth",
|
|
23032
|
+
authn: "auth",
|
|
23033
|
+
authz: "auth",
|
|
23034
|
+
authorisation: "auth",
|
|
23035
|
+
authorization: "auth",
|
|
23036
|
+
login: "auth",
|
|
23037
|
+
"sign-in": "auth",
|
|
23038
|
+
signin: "auth",
|
|
23039
|
+
sso: "auth",
|
|
23040
|
+
identity: "auth",
|
|
23041
|
+
// database
|
|
23042
|
+
db: "database",
|
|
23043
|
+
datastore: "database",
|
|
23044
|
+
storage: "database",
|
|
23045
|
+
persistence: "database",
|
|
23046
|
+
orm: "database",
|
|
23047
|
+
migrations: "database",
|
|
23048
|
+
// payments
|
|
23049
|
+
billing: "payments",
|
|
23050
|
+
payment: "payments",
|
|
23051
|
+
checkout: "payments",
|
|
23052
|
+
subscriptions: "payments",
|
|
23053
|
+
// api
|
|
23054
|
+
backend: "api",
|
|
23055
|
+
server: "api",
|
|
23056
|
+
rpc: "api",
|
|
23057
|
+
// frontend
|
|
23058
|
+
ui: "frontend",
|
|
23059
|
+
client: "frontend",
|
|
23060
|
+
web: "frontend",
|
|
23061
|
+
styling: "frontend",
|
|
23062
|
+
css: "frontend",
|
|
23063
|
+
// deploy
|
|
23064
|
+
deployment: "deploy",
|
|
23065
|
+
infra: "deploy",
|
|
23066
|
+
infrastructure: "deploy",
|
|
23067
|
+
hosting: "deploy",
|
|
23068
|
+
ci: "deploy",
|
|
23069
|
+
cd: "deploy",
|
|
23070
|
+
"ci-cd": "deploy",
|
|
23071
|
+
release: "deploy",
|
|
23072
|
+
// testing
|
|
23073
|
+
tests: "testing",
|
|
23074
|
+
test: "testing",
|
|
23075
|
+
qa: "testing",
|
|
23076
|
+
e2e: "testing",
|
|
23077
|
+
// observability
|
|
23078
|
+
monitoring: "observability",
|
|
23079
|
+
logging: "observability",
|
|
23080
|
+
metrics: "observability",
|
|
23081
|
+
alerting: "observability",
|
|
23082
|
+
tracing: "observability",
|
|
23083
|
+
// security
|
|
23084
|
+
secrets: "security",
|
|
23085
|
+
compliance: "security",
|
|
23086
|
+
privacy: "security",
|
|
23087
|
+
// pricing
|
|
23088
|
+
price: "pricing",
|
|
23089
|
+
plans: "pricing",
|
|
23090
|
+
tiers: "pricing",
|
|
23091
|
+
// licensing
|
|
23092
|
+
licence: "licensing",
|
|
23093
|
+
license: "licensing",
|
|
23094
|
+
// positioning
|
|
23095
|
+
marketing: "positioning",
|
|
23096
|
+
branding: "positioning",
|
|
23097
|
+
messaging: "positioning"
|
|
23098
|
+
};
|
|
23099
|
+
function canonArea(raw) {
|
|
23100
|
+
if (!raw)
|
|
23101
|
+
return null;
|
|
23102
|
+
const lowered = raw.trim().toLowerCase();
|
|
23103
|
+
if (!lowered)
|
|
23104
|
+
return null;
|
|
23105
|
+
const slug = lowered.replace(/[\s_/]+/g, "-").replace(/[^a-z0-9-]/g, "").replace(/-{2,}/g, "-").replace(/^-|-$/g, "");
|
|
23106
|
+
if (!slug)
|
|
23107
|
+
return null;
|
|
23108
|
+
if (AREA_SET.has(slug))
|
|
23109
|
+
return slug;
|
|
23110
|
+
if (AREA_ALIASES[slug])
|
|
23111
|
+
return AREA_ALIASES[slug];
|
|
23112
|
+
return slug.slice(0, 40);
|
|
23113
|
+
}
|
|
23114
|
+
function isKnownArea(key2) {
|
|
23115
|
+
return !!key2 && AREA_SET.has(key2);
|
|
23116
|
+
}
|
|
23117
|
+
var ACCOUNT_SCOPE = "*";
|
|
23118
|
+
function decisionSubject(project, area) {
|
|
23119
|
+
const p = (project || "").trim() || ACCOUNT_SCOPE;
|
|
23120
|
+
return `${p}:${area}`;
|
|
23121
|
+
}
|
|
23122
|
+
|
|
23123
|
+
// ../engine/dist/mcp/tools.js
|
|
23002
23124
|
import { config } from "dotenv";
|
|
23003
23125
|
|
|
23004
23126
|
// ../engine/dist/mcp/diagnostics.js
|
|
@@ -23847,10 +23969,20 @@ var RecallDecisionRecordSchema = z.object({
|
|
|
23847
23969
|
subject: z.string().describe('What the decision is about (e.g., "chat-recall", "auth strategy")'),
|
|
23848
23970
|
decision: z.string().describe('The decision itself in plain words (e.g., "use Postgres full-text search as the default backend")'),
|
|
23849
23971
|
reason: z.string().optional().describe("Why this was decided \u2014 short rationale"),
|
|
23972
|
+
// The key a reversal supersedes on. Without it the subject is free text, so
|
|
23973
|
+
// "auth", "authentication" and "auth setup" are three separate facts and a
|
|
23974
|
+
// later decision never closes an earlier one — see core/decision-areas.ts.
|
|
23975
|
+
area: z.string().optional().describe(`The area this decides, so a later decision about the SAME area supersedes it. Use one of: ${DECISION_AREAS.join(", ")} \u2014 or any short slug for an area not listed. Without it the decision is recorded but nothing it contradicts is closed.`),
|
|
23976
|
+
project: z.string().optional().describe("Project this decision applies to. Omit for an account-wide decision that applies everywhere."),
|
|
23850
23977
|
importance: z.number().min(1).max(5).optional().default(4).describe("1\u20135; the classifier surfaces 4+ in wake-up context"),
|
|
23851
23978
|
session_id: z.string().optional().describe("Session this decision was made in (for traceability)"),
|
|
23852
23979
|
agent_name: z.string().optional().default("agent").describe("Who recorded the decision (for diary linkage)")
|
|
23853
23980
|
});
|
|
23981
|
+
var RecallDecisionsSchema = z.object({
|
|
23982
|
+
area: z.string().optional().describe("Only this area"),
|
|
23983
|
+
project: z.string().optional().describe("Resolve for this project"),
|
|
23984
|
+
include_candidates: z.boolean().optional().default(false)
|
|
23985
|
+
});
|
|
23854
23986
|
var RecallAnalyticsSummarySchema = z.object({
|
|
23855
23987
|
// No required inputs — returns the same summary the dashboard renders.
|
|
23856
23988
|
view: z.enum(["summary", "patterns"]).optional().default("summary").describe("summary = spend/activity rollup; patterns = behavioural patterns across sessions")
|
|
@@ -23999,6 +24131,7 @@ var LEAN_TOOLS = /* @__PURE__ */ new Set([
|
|
|
23999
24131
|
"recall_kg_query",
|
|
24000
24132
|
"recall_kg_add",
|
|
24001
24133
|
"recall_decision_record",
|
|
24134
|
+
"recall_decisions",
|
|
24002
24135
|
"recall_diary_write",
|
|
24003
24136
|
"recall_diary_read",
|
|
24004
24137
|
// Health, and the one that pays out on day one.
|
|
@@ -24895,13 +25028,19 @@ I asking yesterday?" or "what did I tell the agent in this session?".`,
|
|
|
24895
25028
|
name: "recall_decision_record",
|
|
24896
25029
|
description: `Record an explicit decision so it shows up in wake-up context. Writes a KG triple
|
|
24897
25030
|
(subject \u2192 decided \u2192 decision) plus a diary entry. Use this when you and the user agree on
|
|
24898
|
-
something non-obvious that future sessions should remember
|
|
25031
|
+
something non-obvious that future sessions should remember.
|
|
25032
|
+
|
|
25033
|
+
PASS \`area\`. It is the key a reversal supersedes on: recording a new \`auth\` decision closes the
|
|
25034
|
+
previous \`auth\` one and leaves every other area alone. Without it the decision is stored but
|
|
25035
|
+
nothing it contradicts is closed, and both answers stay live forever.`,
|
|
24899
25036
|
inputSchema: {
|
|
24900
25037
|
type: "object",
|
|
24901
25038
|
properties: {
|
|
24902
25039
|
subject: { type: "string", description: "What the decision is about" },
|
|
24903
25040
|
decision: { type: "string", description: "The decision itself" },
|
|
24904
25041
|
reason: { type: "string", description: "Why this was decided" },
|
|
25042
|
+
area: { type: "string", description: `The area this decides, so a later decision on the same area supersedes it. Standard areas: ${DECISION_AREAS.join(", ")}. Any short slug works for an area not listed.` },
|
|
25043
|
+
project: { type: "string", description: "Project this applies to. Omit for an account-wide decision that applies everywhere." },
|
|
24905
25044
|
importance: { type: "number", minimum: 1, maximum: 5, default: 4, description: "1-5. Only 4 and 5 surface in the wake-up bundle, so reserve those for decisions a future session must not miss." },
|
|
24906
25045
|
session_id: { type: "string", description: "Session this decision came out of. Pass your own current session id so the decision can be traced back to the conversation that made it." },
|
|
24907
25046
|
agent_name: { type: "string", default: "agent", description: "Which agent is recording this, so diary entries stay separable per agent." }
|
|
@@ -24909,6 +25048,25 @@ something non-obvious that future sessions should remember.`,
|
|
|
24909
25048
|
required: ["subject", "decision"]
|
|
24910
25049
|
}
|
|
24911
25050
|
},
|
|
25051
|
+
{
|
|
25052
|
+
name: "recall_decisions",
|
|
25053
|
+
description: `What this codebase has already settled \u2014 read it BEFORE choosing a library, a
|
|
25054
|
+
datastore, an auth method or anything else in a decided area, and you will not rebuild what was
|
|
25055
|
+
already ruled out.
|
|
25056
|
+
|
|
25057
|
+
Returns one effective value per area with the cascade already resolved (project beats account;
|
|
25058
|
+
personal preferences fill gaps and never override a team decision), what each value replaced and
|
|
25059
|
+
when, and the session it came from. Also returns \`gaps\` \u2014 areas nobody has decided, where you are
|
|
25060
|
+
free to choose, and where recording the choice afterwards is worth doing.`,
|
|
25061
|
+
inputSchema: {
|
|
25062
|
+
type: "object",
|
|
25063
|
+
properties: {
|
|
25064
|
+
area: { type: "string", description: `Only this area. Standard areas: ${DECISION_AREAS.join(", ")}.` },
|
|
25065
|
+
project: { type: "string", description: "Resolve for this project, so its overrides win over account-wide decisions. Omit for the account-wide view." },
|
|
25066
|
+
include_candidates: { type: "boolean", default: false, description: "Also return unconfirmed guesses the indexer extracted. These are NOT decisions \u2014 never treat one as settled." }
|
|
25067
|
+
}
|
|
25068
|
+
}
|
|
25069
|
+
},
|
|
24912
25070
|
{
|
|
24913
25071
|
name: "recall_analytics_summary",
|
|
24914
25072
|
description: `Cross-tool spend & activity overview. Returns total sessions, total cost,
|
|
@@ -27019,8 +27177,10 @@ ${JSON.stringify(r, null, 2)}
|
|
|
27019
27177
|
const wal = getWAL();
|
|
27020
27178
|
wal.log("decision_record", { subject: params.subject, importance: params.importance });
|
|
27021
27179
|
const confidence = Math.min(1, params.importance / 5);
|
|
27180
|
+
const area = canonArea(params.area);
|
|
27181
|
+
const kgSubject = area ? decisionSubject(params.project, area) : params.subject;
|
|
27022
27182
|
await remotePost("/api/kg/add", {
|
|
27023
|
-
subject:
|
|
27183
|
+
subject: kgSubject,
|
|
27024
27184
|
predicate: "decided",
|
|
27025
27185
|
object: params.decision,
|
|
27026
27186
|
confidence,
|
|
@@ -27028,11 +27188,12 @@ ${JSON.stringify(r, null, 2)}
|
|
|
27028
27188
|
});
|
|
27029
27189
|
if (params.reason) {
|
|
27030
27190
|
await remotePost("/api/kg/add", {
|
|
27031
|
-
subject:
|
|
27191
|
+
subject: kgSubject,
|
|
27032
27192
|
predicate: "because",
|
|
27033
27193
|
object: params.reason,
|
|
27034
27194
|
confidence,
|
|
27035
|
-
source_session: params.session_id
|
|
27195
|
+
source_session: params.session_id,
|
|
27196
|
+
supersede: false
|
|
27036
27197
|
});
|
|
27037
27198
|
}
|
|
27038
27199
|
const diaryText = params.reason ? `Decided: ${params.decision}
|
|
@@ -27048,12 +27209,58 @@ Subject: ${params.subject}`;
|
|
|
27048
27209
|
return {
|
|
27049
27210
|
content: [{
|
|
27050
27211
|
type: "text",
|
|
27051
|
-
text:
|
|
27052
|
-
|
|
27053
|
-
|
|
27212
|
+
text: [
|
|
27213
|
+
"Decision recorded.",
|
|
27214
|
+
`- KG: ${kgSubject} \u2192 decided \u2192 ${params.decision}`,
|
|
27215
|
+
area ? `- Area: ${area}${isKnownArea(area) ? "" : " (not a standard area \u2014 kept as a slug)"} \xB7 a later decision on this area supersedes this one` : "- No area given, so nothing this contradicts was closed. Pass `area` to make reversals work.",
|
|
27216
|
+
`- Diary entry: ${diary.id} (importance ${params.importance})`
|
|
27217
|
+
].join("\n")
|
|
27054
27218
|
}]
|
|
27055
27219
|
};
|
|
27056
27220
|
}
|
|
27221
|
+
// ── The decision register ──────────────────────────────────
|
|
27222
|
+
case "recall_decisions": {
|
|
27223
|
+
const p = RecallDecisionsSchema.parse(args ?? {});
|
|
27224
|
+
requireRemote();
|
|
27225
|
+
const r = await remoteGetQS("/api/decisions", {
|
|
27226
|
+
project: p.project,
|
|
27227
|
+
include_candidates: p.include_candidates ? "1" : "0"
|
|
27228
|
+
});
|
|
27229
|
+
const rows = p.area ? r.decisions.filter((d) => d.area === canonArea(p.area)) : r.decisions;
|
|
27230
|
+
const lines = [];
|
|
27231
|
+
lines.push(r.project ? `Decisions for ${r.project}` : "Decisions \u2014 account-wide");
|
|
27232
|
+
if (rows.length === 0) {
|
|
27233
|
+
lines.push("", p.area ? `Nothing decided for "${p.area}". You are free to choose \u2014 record it afterwards with recall_decision_record.` : "Nothing decided yet.");
|
|
27234
|
+
} else {
|
|
27235
|
+
lines.push("");
|
|
27236
|
+
for (const d of rows) {
|
|
27237
|
+
const tags = [
|
|
27238
|
+
d.override ? "OVERRIDES ACCOUNT" : "",
|
|
27239
|
+
d.inherited ? "inherited from account" : "",
|
|
27240
|
+
d.advisory ? "advisory \u2014 a personal preference, not binding" : ""
|
|
27241
|
+
].filter(Boolean).join(" \xB7 ");
|
|
27242
|
+
lines.push(`${d.area}: ${d.value}${d.since ? ` (since ${d.since})` : ""}${tags ? ` [${tags}]` : ""}`);
|
|
27243
|
+
if (d.why)
|
|
27244
|
+
lines.push(` why: ${d.why}`);
|
|
27245
|
+
const replaced = d.history.filter((h) => !h.current);
|
|
27246
|
+
for (const h of replaced)
|
|
27247
|
+
lines.push(` replaced: ${h.value} (ended ${h.to})`);
|
|
27248
|
+
if (d.source_session)
|
|
27249
|
+
lines.push(` from session ${d.source_session}`);
|
|
27250
|
+
}
|
|
27251
|
+
}
|
|
27252
|
+
if (!p.area && r.gaps.length) {
|
|
27253
|
+
lines.push("", `Not decided: ${r.gaps.map((g) => g.area).join(", ")}`);
|
|
27254
|
+
lines.push("Free to choose in these. Record the choice so the next session inherits it.");
|
|
27255
|
+
}
|
|
27256
|
+
if (p.include_candidates && r.candidates?.length) {
|
|
27257
|
+
lines.push("", "Unconfirmed guesses from indexing \u2014 NOT decisions, do not treat as settled:");
|
|
27258
|
+
for (const c of r.candidates.slice(0, 10)) {
|
|
27259
|
+
lines.push(` ${c.value} (seen ${c.mentions}\xD7${c.last_seen ? `, latest ${c.last_seen}` : ""})`);
|
|
27260
|
+
}
|
|
27261
|
+
}
|
|
27262
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
27263
|
+
}
|
|
27057
27264
|
// ── Analytics summary ──────────────────────────────────────
|
|
27058
27265
|
case "recall_analytics_summary": {
|
|
27059
27266
|
const analyticsParams = RecallAnalyticsSummarySchema.parse(args ?? {});
|
|
@@ -27799,7 +28006,7 @@ function installCrashGuards() {
|
|
|
27799
28006
|
reportClientEvent2("mcp_crash", { message: err.stack || err.message });
|
|
27800
28007
|
});
|
|
27801
28008
|
}
|
|
27802
|
-
var RELAY_VERSION = true ? "0.6.
|
|
28009
|
+
var RELAY_VERSION = true ? "0.6.5" : "0.0.0";
|
|
27803
28010
|
function daemonIdleSecs() {
|
|
27804
28011
|
const raw = process.env.CHAT_RECALL_DAEMON_IDLE_SECS;
|
|
27805
28012
|
if (raw === void 0) return 900;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-installer.d.ts","sourceRoot":"","sources":["../src/service-installer.ts"],"names":[],"mappings":"AAiBA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;AAE9D,MAAM,WAAW,YAAY;IAC3B,4EAA4E;IAC5E,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;CACjB;AAiBD,0EAA0E;AAC1E,wBAAgB,gBAAgB,IAAI,OAAO,CAe1C;AAED;;;GAGG;AACH;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,wBAAwB,IAAI,OAAO,
|
|
1
|
+
{"version":3,"file":"service-installer.d.ts","sourceRoot":"","sources":["../src/service-installer.ts"],"names":[],"mappings":"AAiBA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;AAE9D,MAAM,WAAW,YAAY;IAC3B,4EAA4E;IAC5E,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;CACjB;AAiBD,0EAA0E;AAC1E,wBAAgB,gBAAgB,IAAI,OAAO,CAe1C;AAED;;;GAGG;AACH;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,wBAAwB,IAAI,OAAO,CA2BlD;AAED,wBAAgB,cAAc,IAAI,YAAY,CAiB7C;AAsBD,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CA6CxF;AAmBD,6DAA6D;AAC7D,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,SAA0B,GAAG,MAAM,CAa1H;AAuBD,4DAA4D;AAC5D,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,SAAsB,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAKhI;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAoB1C;AAED,kDAAkD;AAClD,wBAAgB,YAAY,IAAI,MAAM,CAKrC;AAED,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;gBACF,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;CAI3C"}
|
|
@@ -77,6 +77,16 @@ export function refreshServiceDefinition() {
|
|
|
77
77
|
const unitPath = join(homedir(), '.config', 'systemd', 'user', 'chat-recall-watch.service');
|
|
78
78
|
if (!existsSync(unitPath))
|
|
79
79
|
return false; // not service-managed; nothing to refresh
|
|
80
|
+
const current = readFileSync(unitPath, 'utf8');
|
|
81
|
+
// ONLY refresh the unit this build is actually installed as. A daemon run
|
|
82
|
+
// straight out of a checkout would otherwise rewrite ExecStart to its own
|
|
83
|
+
// path and take over the user's service — which is exactly what happened
|
|
84
|
+
// while testing this: the unit ended up pointing at a worktree instead of
|
|
85
|
+
// the installed CLI. Supervision settings are worth refreshing; which
|
|
86
|
+
// binary the service runs is the installer's decision, not a running
|
|
87
|
+
// process's.
|
|
88
|
+
if (!current.includes(watchJs))
|
|
89
|
+
return false;
|
|
80
90
|
const wanted = renderSystemdUnit(watchJs, node, logFile);
|
|
81
91
|
if (readFileSync(unitPath, 'utf8') === wanted)
|
|
82
92
|
return false;
|
|
@@ -132,7 +142,15 @@ function installSystemd(watchJs, node, logFile) {
|
|
|
132
142
|
/** Render the systemd --user unit file body (pure — no FS, no exec). */
|
|
133
143
|
export function renderSystemdUnit(watchJs, node, logFile) {
|
|
134
144
|
return [
|
|
135
|
-
'[Unit]', 'Description=chat-recall live indexer (sessions → local index, optional server sync)', 'After=default.target',
|
|
145
|
+
'[Unit]', 'Description=chat-recall live indexer (sessions → local index, optional server sync)', 'After=default.target',
|
|
146
|
+
// NEVER STOP RETRYING, and it must be in [Unit] — systemd reads the start
|
|
147
|
+
// limiter there and ignores it under [Service], silently. The default gives
|
|
148
|
+
// up after a burst and leaves the unit dead until a human notices: 53
|
|
149
|
+
// restarts here, then "Start request repeated too quickly", then twelve
|
|
150
|
+
// hours with nothing collected and nothing said. A collector that stops
|
|
151
|
+
// forever after a crash loop is worse than one that keeps crashing.
|
|
152
|
+
// 0 disables the limiter, so RestartSec below is the only pacing.
|
|
153
|
+
'StartLimitIntervalSec=0', '',
|
|
136
154
|
'[Service]',
|
|
137
155
|
// Bounded heap: the daemon does bursty batch work (transcript parse,
|
|
138
156
|
// base64 payloads); V8's default old-space on a big-RAM box is ~4GB and
|
|
@@ -152,7 +170,6 @@ export function renderSystemdUnit(watchJs, node, logFile) {
|
|
|
152
170
|
// that stops forever after a crash loop is worse than one that keeps
|
|
153
171
|
// crashing: the user is told nothing and their history silently ends.
|
|
154
172
|
// 0 disables the limiter, so RestartSec above is the only pacing.
|
|
155
|
-
'StartLimitIntervalSec=0',
|
|
156
173
|
// A bounded cgroup, so a leak becomes a restart rather than a machine that
|
|
157
174
|
// swaps. MemoryHigh throttles and reclaims first; MemoryMax is the kill.
|
|
158
175
|
// --max-old-space-size bounds the V8 heap and NOT Buffers, and the observed
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-installer.js","sourceRoot":"","sources":["../src/service-installer.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"service-installer.js","sourceRoot":"","sources":["../src/service-installer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAChF,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAWpC,0EAA0E;AAC1E,SAAS,kBAAkB;IACzB,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACtE,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC;IAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,cAAc,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAC3C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAC7C,CAAC;AAED,2EAA2E;AAC3E,SAAS,MAAM,CAAC,GAAW;IACzB,IAAI,CAAC;QAAC,OAAO,QAAQ,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IAAC,CAAC;IACjF,MAAM,CAAC;QAAC,OAAO,EAAE,CAAC;IAAC,CAAC;AACtB,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,gBAAgB;IAC9B,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,yDAAyD,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QACpG,OAAO,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,8DAA8D,CAAC,CAAC,CAAC;IACnG,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,2DAA2D;QAC3D,OAAO,yBAAyB,CAAC,IAAI,CAAC,MAAM,CAAC,4BAA4B,CAAC,CAAC,CAAC;IAC9E,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,kEAAkE;QAClE,0EAA0E;QAC1E,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,kEAAkE,CAAC,CAAC,CAAC;IACnG,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,wBAAwB;IACtC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC,CAAG,wCAAwC;IAC1F,IAAI,CAAC;QACH,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,kBAAkB,EAAE,CAAC;QACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,2BAA2B,CAAC,CAAC;QAC5F,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO,KAAK,CAAC,CAAQ,0CAA0C;QAC1F,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC/C,0EAA0E;QAC1E,0EAA0E;QAC1E,yEAAyE;QACzE,0EAA0E;QAC1E,sEAAsE;QACtE,qEAAqE;QACrE,aAAa;QACb,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,OAAO,KAAK,CAAC;QAC7C,MAAM,MAAM,GAAG,iBAAiB,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACzD,IAAI,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,MAAM;YAAE,OAAO,KAAK,CAAC;QAC5D,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAChC,qEAAqE;QACrE,0EAA0E;QAC1E,uEAAuE;QACvE,mBAAmB;QACnB,QAAQ,CAAC,gCAAgC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAChE,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,kBAAkB,EAAE,CAAC;IACjE,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAExC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,kBAAkB,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IACpD,CAAC;IACD,MAAM,IAAI,mBAAmB,CAC3B,4CAA4C,OAAO,CAAC,QAAQ,IAAI,EAChE,+FAA+F,CAChG,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,OAAe,EAAE,IAAY,EAAE,OAAe;IACpE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,2BAA2B,CAAC,CAAC;IAC5D,MAAM,IAAI,GAAG,iBAAiB,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IACvD,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACxC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC9B,IAAI,CAAC;QACH,0EAA0E;QAC1E,0EAA0E;QAC1E,2EAA2E;QAC3E,QAAQ,CAAC,2IAA2I,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAC5K,wEAAwE;QACxE,yCAAyC;QACzC,IAAI,CAAC;YAAC,QAAQ,CAAC,4CAA4C,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;IAC/G,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,mBAAmB,CAAC,oCAAoC,EAAE,SAAS,QAAQ,EAAE,CAAC,CAAC;IAC3F,CAAC;IACD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AAC/C,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,iBAAiB,CAAC,OAAe,EAAE,IAAY,EAAE,OAAe;IAC9E,OAAO;QACL,QAAQ,EAAE,qFAAqF,EAAE,sBAAsB;QACvH,0EAA0E;QAC1E,4EAA4E;QAC5E,sEAAsE;QACtE,wEAAwE;QACxE,wEAAwE;QACxE,oEAAoE;QACpE,kEAAkE;QAClE,yBAAyB,EAAE,EAAE;QAC7B,WAAW;QACX,qEAAqE;QACrE,wEAAwE;QACxE,wEAAwE;QACxE,sHAAsH;QACtH,uBAAuB;QACvB,aAAa,IAAI,8BAA8B,OAAO,EAAE;QACxD,oBAAoB,EAAE,eAAe,EAAE,SAAS;QAChD,wEAAwE;QACxE,yEAAyE;QACzE,oDAAoD;QACpD,EAAE;QACF,mEAAmE;QACnE,8CAA8C;QAC9C,EAAE;QACF,wEAAwE;QACxE,qEAAqE;QACrE,sEAAsE;QACtE,kEAAkE;QAClE,2EAA2E;QAC3E,yEAAyE;QACzE,4EAA4E;QAC5E,yEAAyE;QACzE,4BAA4B;QAC5B,sBAAsB,EAAE,eAAe,EAAE,cAAc;QACvD,wEAAwE;QACxE,yEAAyE;QACzE,uEAAuE;QACvE,0EAA0E;QAC1E,iEAAiE;QACjE,8CAA8C;QAC9C,wBAAwB,EAAE,uBAAuB,EAAE,EAAE;QACrD,WAAW,EAAE,yBAAyB,EAAE,EAAE;KAC3C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,SAAS,cAAc,CAAC,OAAe,EAAE,IAAY,EAAE,OAAe;IACpE,MAAM,KAAK,GAAG,uBAAuB,CAAC;IACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;IAC5D,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,KAAK,QAAQ,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,kBAAkB,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IAChE,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,aAAa,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAChC,IAAI,CAAC;QACH,sEAAsE;QACtE,IAAI,CAAC;YAAC,QAAQ,CAAC,qBAAqB,SAAS,GAAG,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,CAAC;QACxG,QAAQ,CAAC,mBAAmB,SAAS,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,mBAAmB,CAAC,qCAAqC,EAAE,UAAU,SAAS,EAAE,CAAC,CAAC;IAC9F,CAAC;IACD,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AAChD,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,kBAAkB,CAAC,OAAe,EAAE,IAAY,EAAE,OAAe,EAAE,KAAK,GAAG,uBAAuB;IAChH,OAAO;QACL,wCAAwC;QACxC,wGAAwG;QACxG,6BAA6B;QAC7B,6BAA6B,KAAK,WAAW;QAC7C,+CAA+C,IAAI,8DAA8D,OAAO,mBAAmB;QAC3I,+BAA+B;QAC/B,+BAA+B;QAC/B,uCAAuC,OAAO,WAAW;QACzD,yCAAyC,OAAO,WAAW;QAC3D,iBAAiB,EAAE,EAAE;KACtB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,SAAS,kBAAkB,CAAC,OAAe,EAAE,IAAY,EAAE,OAAe;IACxE,MAAM,QAAQ,GAAG,mBAAmB,CAAC;IACrC,yEAAyE;IACzE,yEAAyE;IACzE,2EAA2E;IAC3E,2EAA2E;IAC3E,mEAAmE;IACnE,EAAE;IACF,yEAAyE;IACzE,6DAA6D;IAC7D,MAAM,EAAE,GAAG,gBAAgB,IAAI,oCAAoC,OAAO,aAAa,OAAO,aAAa,CAAC;IAC5G,IAAI,CAAC;QACH,QAAQ,CAAC,yBAAyB,QAAQ,UAAU,EAAE,8BAA8B,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAC5G,uEAAuE;QACvE,IAAI,CAAC;YAAC,QAAQ,CAAC,sBAAsB,QAAQ,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,uBAAuB,CAAC,CAAC;IAC9G,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,mBAAmB,CAAC,4CAA4C,EAAE,EAAE,CAAC,CAAC;IAClF,CAAC;IACD,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3C,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,wBAAwB,CAAC,OAAe,EAAE,IAAY,EAAE,QAAQ,GAAG,mBAAmB,EAAE,OAAgB;IACtH,MAAM,EAAE,GAAG,OAAO;QAChB,CAAC,CAAC,gBAAgB,IAAI,oCAAoC,OAAO,aAAa,OAAO,aAAa;QAClG,CAAC,CAAC,MAAM,IAAI,oCAAoC,OAAO,KAAK,CAAC;IAC/D,OAAO,yBAAyB,QAAQ,UAAU,EAAE,8BAA8B,CAAC;AACrF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB;IAC9B,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC;YAAC,QAAQ,CAAC,sEAAsE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YAAC,OAAO,GAAG,IAAI,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,CAAC;QAC5J,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,2BAA2B,CAAC,CAAC;QAC5F,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAAC,OAAO,GAAG,IAAI,CAAC;QAAC,CAAC;QAChF,IAAI,CAAC;YAAC,QAAQ,CAAC,4CAA4C,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;QAC7G,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,6BAA6B,CAAC,CAAC;QAC5F,IAAI,CAAC;YAAC,QAAQ,CAAC,qBAAqB,SAAS,eAAe,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,gBAAgB,CAAC,CAAC;QAChH,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAAC,MAAM,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAAC,OAAO,GAAG,IAAI,CAAC;QAAC,CAAC;QAClF,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,IAAI,CAAC;YAAC,QAAQ,CAAC,iDAAiD,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YAAC,OAAO,IAAI,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,OAAO,KAAK,CAAC;QAAC,CAAC;IAChI,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,YAAY;IAC1B,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO,gBAAgB,CAAC;IAC1D,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IACpD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO,gBAAgB,CAAC;IAC1D,OAAO,OAAO,CAAC,QAAQ,CAAC;AAC1B,CAAC;AAED,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC5C,IAAI,CAAU;IACd,YAAY,OAAe,EAAE,IAAa;QACxC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
|
package/dist/watch.js
CHANGED
|
@@ -13769,12 +13769,12 @@ function extractEntities(text, context = {}) {
|
|
|
13769
13769
|
if (chosen && looksLikeStrictTool(chosen) && looksLikeStrictTool(rejected)) {
|
|
13770
13770
|
const c = canonTool(chosen), r = canonTool(rejected);
|
|
13771
13771
|
if (projectName)
|
|
13772
|
-
addTriple(projectName, "chose", c,
|
|
13773
|
-
addTriple(projectName || "project", "rejected", r,
|
|
13774
|
-
addTriple(c, "chosen_over", r,
|
|
13772
|
+
addTriple(projectName, "chose", c, DECISION_GUESS_CONFIDENCE);
|
|
13773
|
+
addTriple(projectName || "project", "rejected", r, DECISION_GUESS_CONFIDENCE);
|
|
13774
|
+
addTriple(c, "chosen_over", r, DECISION_GUESS_CONFIDENCE);
|
|
13775
13775
|
}
|
|
13776
13776
|
} else if (chosen && looksLikeDecisionObject(chosen) && projectName) {
|
|
13777
|
-
addTriple(projectName, "chose", canonTool(chosen),
|
|
13777
|
+
addTriple(projectName, "chose", canonTool(chosen), DECISION_GUESS_CONFIDENCE);
|
|
13778
13778
|
}
|
|
13779
13779
|
}
|
|
13780
13780
|
}
|
|
@@ -13811,7 +13811,7 @@ function extractEntities(text, context = {}) {
|
|
|
13811
13811
|
}
|
|
13812
13812
|
return triples;
|
|
13813
13813
|
}
|
|
13814
|
-
var KNOWN_TOOLS, AMBIGUOUS_TOOLS, toolContextRe, TOOL_PATTERNS, DECISION_PATTERNS2, DECISION_OBJECT_STOPWORDS, KNOWN_TOOL_NAMES, CANONICAL_TOOL, canonTool, PROJECT_PATH_PATTERN, PEOPLE_PATTERNS, NOT_PEOPLE;
|
|
13814
|
+
var KNOWN_TOOLS, AMBIGUOUS_TOOLS, toolContextRe, TOOL_PATTERNS, DECISION_PATTERNS2, DECISION_OBJECT_STOPWORDS, KNOWN_TOOL_NAMES, CANONICAL_TOOL, canonTool, DECISION_GUESS_CONFIDENCE, PROJECT_PATH_PATTERN, PEOPLE_PATTERNS, NOT_PEOPLE;
|
|
13815
13815
|
var init_entity_extractor = __esm({
|
|
13816
13816
|
"../engine/dist/core/entity-extractor.js"() {
|
|
13817
13817
|
"use strict";
|
|
@@ -14032,6 +14032,7 @@ var init_entity_extractor = __esm({
|
|
|
14032
14032
|
"nextjs": "next.js"
|
|
14033
14033
|
};
|
|
14034
14034
|
canonTool = (n) => CANONICAL_TOOL[n.toLowerCase()] ?? n;
|
|
14035
|
+
DECISION_GUESS_CONFIDENCE = 0.6;
|
|
14035
14036
|
PROJECT_PATH_PATTERN = /\/(?:home|Users)\/\w+\/(?:code|projects|work|dev|src)\/(?:\w+\/)?([a-zA-Z][a-zA-Z0-9_-]{1,40})/g;
|
|
14036
14037
|
PEOPLE_PATTERNS = [
|
|
14037
14038
|
/\b(?:my name is|I'm|I am)\s+([A-Z][a-z]{1,15}(?:\s+[A-Z][a-z]{1,15})?)/g,
|
|
@@ -18304,7 +18305,7 @@ var init_http = __esm({
|
|
|
18304
18305
|
CLI_VERSION = JSON.parse(readFileSync31(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION;
|
|
18305
18306
|
} catch {
|
|
18306
18307
|
try {
|
|
18307
|
-
if (true) CLI_VERSION = "0.6.
|
|
18308
|
+
if (true) CLI_VERSION = "0.6.5";
|
|
18308
18309
|
} catch {
|
|
18309
18310
|
}
|
|
18310
18311
|
}
|
|
@@ -18820,7 +18821,7 @@ var init_telemetry = __esm({
|
|
|
18820
18821
|
init_sync_client();
|
|
18821
18822
|
cliVersion = () => {
|
|
18822
18823
|
try {
|
|
18823
|
-
return true ? "0.6.
|
|
18824
|
+
return true ? "0.6.5" : "dev";
|
|
18824
18825
|
} catch {
|
|
18825
18826
|
return "dev";
|
|
18826
18827
|
}
|
|
@@ -20763,7 +20764,7 @@ var init_sync_client = __esm({
|
|
|
20763
20764
|
ownVersion = JSON.parse(readFileSync35(join42(dir, "../package.json"), "utf-8")).version || ownVersion;
|
|
20764
20765
|
} catch {
|
|
20765
20766
|
try {
|
|
20766
|
-
if (true) ownVersion = "0.6.
|
|
20767
|
+
if (true) ownVersion = "0.6.5";
|
|
20767
20768
|
} catch {
|
|
20768
20769
|
}
|
|
20769
20770
|
}
|
|
@@ -23308,6 +23309,8 @@ function refreshServiceDefinition() {
|
|
|
23308
23309
|
const { watchJs, node, logFile } = resolveDaemonPaths();
|
|
23309
23310
|
const unitPath = join53(homedir19(), ".config", "systemd", "user", "chat-recall-watch.service");
|
|
23310
23311
|
if (!existsSync48(unitPath)) return false;
|
|
23312
|
+
const current = readFileSync44(unitPath, "utf8");
|
|
23313
|
+
if (!current.includes(watchJs)) return false;
|
|
23311
23314
|
const wanted = renderSystemdUnit(watchJs, node, logFile);
|
|
23312
23315
|
if (readFileSync44(unitPath, "utf8") === wanted) return false;
|
|
23313
23316
|
writeFileSync16(unitPath, wanted);
|
|
@@ -23356,6 +23359,14 @@ function renderSystemdUnit(watchJs, node, logFile) {
|
|
|
23356
23359
|
"[Unit]",
|
|
23357
23360
|
"Description=chat-recall live indexer (sessions \u2192 local index, optional server sync)",
|
|
23358
23361
|
"After=default.target",
|
|
23362
|
+
// NEVER STOP RETRYING, and it must be in [Unit] — systemd reads the start
|
|
23363
|
+
// limiter there and ignores it under [Service], silently. The default gives
|
|
23364
|
+
// up after a burst and leaves the unit dead until a human notices: 53
|
|
23365
|
+
// restarts here, then "Start request repeated too quickly", then twelve
|
|
23366
|
+
// hours with nothing collected and nothing said. A collector that stops
|
|
23367
|
+
// forever after a crash loop is worse than one that keeps crashing.
|
|
23368
|
+
// 0 disables the limiter, so RestartSec below is the only pacing.
|
|
23369
|
+
"StartLimitIntervalSec=0",
|
|
23359
23370
|
"",
|
|
23360
23371
|
"[Service]",
|
|
23361
23372
|
// Bounded heap: the daemon does bursty batch work (transcript parse,
|
|
@@ -23378,7 +23389,6 @@ function renderSystemdUnit(watchJs, node, logFile) {
|
|
|
23378
23389
|
// that stops forever after a crash loop is worse than one that keeps
|
|
23379
23390
|
// crashing: the user is told nothing and their history silently ends.
|
|
23380
23391
|
// 0 disables the limiter, so RestartSec above is the only pacing.
|
|
23381
|
-
"StartLimitIntervalSec=0",
|
|
23382
23392
|
// A bounded cgroup, so a leak becomes a restart rather than a machine that
|
|
23383
23393
|
// swaps. MemoryHigh throttles and reclaims first; MemoryMax is the kill.
|
|
23384
23394
|
// --max-old-space-size bounds the V8 heap and NOT Buffers, and the observed
|
|
@@ -23838,7 +23848,7 @@ try {
|
|
|
23838
23848
|
ownVersion2 = JSON.parse(readFileSync39(join48(dir, "../package.json"), "utf-8")).version || ownVersion2;
|
|
23839
23849
|
} catch {
|
|
23840
23850
|
try {
|
|
23841
|
-
if (true) ownVersion2 = "0.6.
|
|
23851
|
+
if (true) ownVersion2 = "0.6.5";
|
|
23842
23852
|
} catch {
|
|
23843
23853
|
}
|
|
23844
23854
|
}
|
|
@@ -24186,7 +24196,7 @@ async function runCollectorMigration(opts) {
|
|
|
24186
24196
|
init_sync_ledger();
|
|
24187
24197
|
init_collector_health();
|
|
24188
24198
|
import { existsSync as existsSync49, readFileSync as readFileSync45, statSync as statSync44 } from "fs";
|
|
24189
|
-
var CLI_VERSION3 = true ? "0.6.
|
|
24199
|
+
var CLI_VERSION3 = true ? "0.6.5" : "0.0.0";
|
|
24190
24200
|
var DEBOUNCE_MS = 5e3;
|
|
24191
24201
|
var CLAUDE_DIR = claudeBackend.projectsDir();
|
|
24192
24202
|
var PLANS_DIR = claudeBackend.plansDir();
|
package/package.json
CHANGED
|
@@ -29,7 +29,7 @@ All tools are MCP tools on the `chat-recall` server, named
|
|
|
29
29
|
**Reads are safe to call proactively. Writes are not.** Everything below is a
|
|
30
30
|
read except these, which change stored memory or state — treat each as an edit
|
|
31
31
|
and apply the test in `chat-recall-memory` before calling one:
|
|
32
|
-
`recall_kg_add`, `recall_kg_invalidate`, `recall_decision_record`,
|
|
32
|
+
`recall_kg_add`, `recall_kg_invalidate`, `recall_decision_record`, `recall_decisions`,
|
|
33
33
|
`recall_diary_write`, `recall_set`, `recall_task_create`, `recall_task_update`,
|
|
34
34
|
`recall_task_comment`,
|
|
35
35
|
`recall_task_policy`,
|
|
@@ -88,6 +88,7 @@ CLAUDE.md rule is additive and reversible, so take it; ask first before setting
|
|
|
88
88
|
**Findings, ranked** — `recall_claude_suggestions` (every finding that becomes an agent-instruction change — the CLAUDE.md rules and skill installs — merged across account scope and every indexed project) and `recall_improvements` (everything else, most urgent first; `create_tasks: true` opens one team task per item). They split the same engines, so an item never appears in both. Neither needs the codeindex binary: without it you still get the account-level half.
|
|
89
89
|
**What changed** — `recall_edits_timeline` (cross-tool edits), `recall_diff` (per-session diffs), `recall_commits` (did it actually land), `recall_markers` (where a session went sideways).
|
|
90
90
|
**Durable memory / KG** — `recall_kg_query` / `recall_kg_add` / `recall_kg_invalidate` / `recall_kg_timeline` / `recall_kg_stats`, `recall_decision_record`, `recall_diary_write` / `recall_diary_read`, `recall_set` / `recall_get`.
|
|
91
|
+
**Decisions** — `recall_decisions` (what is already settled per area, cascade resolved; call it before choosing a library or a datastore).
|
|
91
92
|
**Team** — `recall_tasks` (the shared task board), `recall_task_create`, `recall_task_update` (status, assignee, linked session; task ids look like `t_…`; when you start work on a task, set it `in_progress` and pass your session id as `linked_session_id` so the board can verify the work shipped), `recall_task_comment` (leave a progress note on a card), `recall_task_policy` (read or change WHAT the board files — severity floor, open-card ceiling, cards per run, categories, and the projects that never file at all via `exclude_project` — reach for that one when the user says "do not put work on my board for this repo", e.g. a client's codebase they keep separate; call it with no arguments to read, and reach for it when the user says "only security", "high and critical for now", or asks why a full board has stopped filing), `recall_team_activity` (per-teammate × per-project rollup), `recall_shares` (which projects are shared — private by default, nothing is visible to teammates until shared).
|
|
92
93
|
**Toolkit sync across tools and devices** — `recall_toolkit_status` (which MCP servers, skills, commands and agents exist, on which tool, on which device — and which of them can be installed elsewhere at all), `recall_toolkit_sync` (queue an install: everything or one type, every device or one machine, or fan a machine's own artifacts across its own tools). Reach for these on "set up my other laptop", "get my MCPs everywhere", "why does this tool not have my skill".
|
|
93
94
|
|