chat-recall 0.6.4 → 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 +11 -9
- package/dist/cli.js.map +1 -1
- package/dist/mcp-relay.js +1 -1
- package/dist/mcp.js +214 -16
- package/dist/watch.js +11 -10
- 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
|
}
|
|
@@ -23008,6 +23009,118 @@ function resumeCommandFor(sessionId, tool) {
|
|
|
23008
23009
|
|
|
23009
23010
|
// ../engine/dist/mcp/tools.js
|
|
23010
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
|
|
23011
23124
|
import { config } from "dotenv";
|
|
23012
23125
|
|
|
23013
23126
|
// ../engine/dist/mcp/diagnostics.js
|
|
@@ -23856,10 +23969,20 @@ var RecallDecisionRecordSchema = z.object({
|
|
|
23856
23969
|
subject: z.string().describe('What the decision is about (e.g., "chat-recall", "auth strategy")'),
|
|
23857
23970
|
decision: z.string().describe('The decision itself in plain words (e.g., "use Postgres full-text search as the default backend")'),
|
|
23858
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."),
|
|
23859
23977
|
importance: z.number().min(1).max(5).optional().default(4).describe("1\u20135; the classifier surfaces 4+ in wake-up context"),
|
|
23860
23978
|
session_id: z.string().optional().describe("Session this decision was made in (for traceability)"),
|
|
23861
23979
|
agent_name: z.string().optional().default("agent").describe("Who recorded the decision (for diary linkage)")
|
|
23862
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
|
+
});
|
|
23863
23986
|
var RecallAnalyticsSummarySchema = z.object({
|
|
23864
23987
|
// No required inputs — returns the same summary the dashboard renders.
|
|
23865
23988
|
view: z.enum(["summary", "patterns"]).optional().default("summary").describe("summary = spend/activity rollup; patterns = behavioural patterns across sessions")
|
|
@@ -24008,6 +24131,7 @@ var LEAN_TOOLS = /* @__PURE__ */ new Set([
|
|
|
24008
24131
|
"recall_kg_query",
|
|
24009
24132
|
"recall_kg_add",
|
|
24010
24133
|
"recall_decision_record",
|
|
24134
|
+
"recall_decisions",
|
|
24011
24135
|
"recall_diary_write",
|
|
24012
24136
|
"recall_diary_read",
|
|
24013
24137
|
// Health, and the one that pays out on day one.
|
|
@@ -24904,13 +25028,19 @@ I asking yesterday?" or "what did I tell the agent in this session?".`,
|
|
|
24904
25028
|
name: "recall_decision_record",
|
|
24905
25029
|
description: `Record an explicit decision so it shows up in wake-up context. Writes a KG triple
|
|
24906
25030
|
(subject \u2192 decided \u2192 decision) plus a diary entry. Use this when you and the user agree on
|
|
24907
|
-
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.`,
|
|
24908
25036
|
inputSchema: {
|
|
24909
25037
|
type: "object",
|
|
24910
25038
|
properties: {
|
|
24911
25039
|
subject: { type: "string", description: "What the decision is about" },
|
|
24912
25040
|
decision: { type: "string", description: "The decision itself" },
|
|
24913
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." },
|
|
24914
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." },
|
|
24915
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." },
|
|
24916
25046
|
agent_name: { type: "string", default: "agent", description: "Which agent is recording this, so diary entries stay separable per agent." }
|
|
@@ -24918,6 +25048,25 @@ something non-obvious that future sessions should remember.`,
|
|
|
24918
25048
|
required: ["subject", "decision"]
|
|
24919
25049
|
}
|
|
24920
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
|
+
},
|
|
24921
25070
|
{
|
|
24922
25071
|
name: "recall_analytics_summary",
|
|
24923
25072
|
description: `Cross-tool spend & activity overview. Returns total sessions, total cost,
|
|
@@ -27028,8 +27177,10 @@ ${JSON.stringify(r, null, 2)}
|
|
|
27028
27177
|
const wal = getWAL();
|
|
27029
27178
|
wal.log("decision_record", { subject: params.subject, importance: params.importance });
|
|
27030
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;
|
|
27031
27182
|
await remotePost("/api/kg/add", {
|
|
27032
|
-
subject:
|
|
27183
|
+
subject: kgSubject,
|
|
27033
27184
|
predicate: "decided",
|
|
27034
27185
|
object: params.decision,
|
|
27035
27186
|
confidence,
|
|
@@ -27037,11 +27188,12 @@ ${JSON.stringify(r, null, 2)}
|
|
|
27037
27188
|
});
|
|
27038
27189
|
if (params.reason) {
|
|
27039
27190
|
await remotePost("/api/kg/add", {
|
|
27040
|
-
subject:
|
|
27191
|
+
subject: kgSubject,
|
|
27041
27192
|
predicate: "because",
|
|
27042
27193
|
object: params.reason,
|
|
27043
27194
|
confidence,
|
|
27044
|
-
source_session: params.session_id
|
|
27195
|
+
source_session: params.session_id,
|
|
27196
|
+
supersede: false
|
|
27045
27197
|
});
|
|
27046
27198
|
}
|
|
27047
27199
|
const diaryText = params.reason ? `Decided: ${params.decision}
|
|
@@ -27057,12 +27209,58 @@ Subject: ${params.subject}`;
|
|
|
27057
27209
|
return {
|
|
27058
27210
|
content: [{
|
|
27059
27211
|
type: "text",
|
|
27060
|
-
text:
|
|
27061
|
-
|
|
27062
|
-
|
|
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")
|
|
27063
27218
|
}]
|
|
27064
27219
|
};
|
|
27065
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
|
+
}
|
|
27066
27264
|
// ── Analytics summary ──────────────────────────────────────
|
|
27067
27265
|
case "recall_analytics_summary": {
|
|
27068
27266
|
const analyticsParams = RecallAnalyticsSummarySchema.parse(args ?? {});
|
|
@@ -27808,7 +28006,7 @@ function installCrashGuards() {
|
|
|
27808
28006
|
reportClientEvent2("mcp_crash", { message: err.stack || err.message });
|
|
27809
28007
|
});
|
|
27810
28008
|
}
|
|
27811
|
-
var RELAY_VERSION = true ? "0.6.
|
|
28009
|
+
var RELAY_VERSION = true ? "0.6.5" : "0.0.0";
|
|
27812
28010
|
function daemonIdleSecs() {
|
|
27813
28011
|
const raw = process.env.CHAT_RECALL_DAEMON_IDLE_SECS;
|
|
27814
28012
|
if (raw === void 0) return 900;
|
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
|
}
|
|
@@ -23847,7 +23848,7 @@ try {
|
|
|
23847
23848
|
ownVersion2 = JSON.parse(readFileSync39(join48(dir, "../package.json"), "utf-8")).version || ownVersion2;
|
|
23848
23849
|
} catch {
|
|
23849
23850
|
try {
|
|
23850
|
-
if (true) ownVersion2 = "0.6.
|
|
23851
|
+
if (true) ownVersion2 = "0.6.5";
|
|
23851
23852
|
} catch {
|
|
23852
23853
|
}
|
|
23853
23854
|
}
|
|
@@ -24195,7 +24196,7 @@ async function runCollectorMigration(opts) {
|
|
|
24195
24196
|
init_sync_ledger();
|
|
24196
24197
|
init_collector_health();
|
|
24197
24198
|
import { existsSync as existsSync49, readFileSync as readFileSync45, statSync as statSync44 } from "fs";
|
|
24198
|
-
var CLI_VERSION3 = true ? "0.6.
|
|
24199
|
+
var CLI_VERSION3 = true ? "0.6.5" : "0.0.0";
|
|
24199
24200
|
var DEBOUNCE_MS = 5e3;
|
|
24200
24201
|
var CLAUDE_DIR = claudeBackend.projectsDir();
|
|
24201
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
|
|
|
@@ -26,11 +26,27 @@ future sessions inherit them.
|
|
|
26
26
|
- `mcp__chat-recall__recall_diary_read` — prior agent diary entries (narrative
|
|
27
27
|
notes across sessions). `mcp__chat-recall__recall_get` — a scoped key/value.
|
|
28
28
|
|
|
29
|
+
## Check what is already decided (do this BEFORE you choose)
|
|
30
|
+
|
|
31
|
+
- `mcp__chat-recall__recall_decisions` — the decision register, cascade already
|
|
32
|
+
resolved: one value per area (auth, database, payments, deploy, pricing,
|
|
33
|
+
licensing…), what it replaced and when, and the session behind it. Call it
|
|
34
|
+
before picking a library, a datastore or an auth method. If the area is
|
|
35
|
+
already decided, follow it or say plainly that you are proposing a reversal.
|
|
36
|
+
It also returns `gaps` — areas nobody has decided, where you are free to
|
|
37
|
+
choose and should record the choice afterwards.
|
|
38
|
+
|
|
39
|
+
Project overrides beat account-wide decisions. A personal preference is
|
|
40
|
+
returned marked `advisory` and never overrides a team decision.
|
|
41
|
+
|
|
29
42
|
## Record new knowledge (do this when something non-obvious is decided)
|
|
30
43
|
|
|
31
44
|
- `mcp__chat-recall__recall_decision_record` — an explicit decision (subject,
|
|
32
|
-
decision, reason, importance).
|
|
33
|
-
|
|
45
|
+
decision, reason, importance). **Pass `area`**: it is the key a reversal
|
|
46
|
+
supersedes on, so recording a new `auth` decision closes the previous one and
|
|
47
|
+
leaves every other area alone. Without it nothing the decision contradicts is
|
|
48
|
+
closed. Shows up in future wake-up context. Use the moment you and the user
|
|
49
|
+
agree on something a later session would need.
|
|
34
50
|
- `mcp__chat-recall__recall_kg_add` — assert a fact triple
|
|
35
51
|
(subject → predicate → object, optional `valid_from`). E.g.
|
|
36
52
|
`("chat-recall", "uses", "Postgres")`.
|