@thread-memory/core 0.1.1 → 1.0.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.
Files changed (69) hide show
  1. package/dist/assets.d.ts +14 -0
  2. package/dist/assets.js +104 -0
  3. package/dist/assets.js.map +1 -0
  4. package/dist/assets.test.d.ts +1 -0
  5. package/dist/assets.test.js +88 -0
  6. package/dist/assets.test.js.map +1 -0
  7. package/dist/behavior-contract.d.ts +2 -0
  8. package/dist/behavior-contract.js +9 -0
  9. package/dist/behavior-contract.js.map +1 -0
  10. package/dist/closing.d.ts +11 -0
  11. package/dist/closing.js +37 -0
  12. package/dist/closing.js.map +1 -0
  13. package/dist/delta.d.ts +24 -0
  14. package/dist/delta.js +55 -0
  15. package/dist/delta.js.map +1 -0
  16. package/dist/index.d.ts +6 -0
  17. package/dist/index.js +6 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/isolation.test.js +3 -5
  20. package/dist/isolation.test.js.map +1 -1
  21. package/dist/light-confirm.d.ts +3 -21
  22. package/dist/light-confirm.js +80 -97
  23. package/dist/light-confirm.js.map +1 -1
  24. package/dist/light-confirm.test.js +185 -103
  25. package/dist/light-confirm.test.js.map +1 -1
  26. package/dist/lineage.test.js +10 -12
  27. package/dist/lineage.test.js.map +1 -1
  28. package/dist/nav.d.ts +26 -0
  29. package/dist/nav.js +139 -0
  30. package/dist/nav.js.map +1 -0
  31. package/dist/nav.test.d.ts +1 -0
  32. package/dist/nav.test.js +100 -0
  33. package/dist/nav.test.js.map +1 -0
  34. package/dist/query-tool.d.ts +20 -0
  35. package/dist/query-tool.js +61 -0
  36. package/dist/query-tool.js.map +1 -0
  37. package/dist/query.test.js +8 -5
  38. package/dist/query.test.js.map +1 -1
  39. package/dist/schema.d.ts +3 -1
  40. package/dist/schema.js +104 -1
  41. package/dist/schema.js.map +1 -1
  42. package/dist/schema.test.js +90 -3
  43. package/dist/schema.test.js.map +1 -1
  44. package/dist/sediment.test.d.ts +1 -0
  45. package/dist/sediment.test.js +89 -0
  46. package/dist/sediment.test.js.map +1 -0
  47. package/dist/segment.d.ts +3 -0
  48. package/dist/segment.js +84 -0
  49. package/dist/segment.js.map +1 -0
  50. package/dist/segment.test.d.ts +1 -0
  51. package/dist/segment.test.js +37 -0
  52. package/dist/segment.test.js.map +1 -0
  53. package/dist/state-delta.test.d.ts +1 -0
  54. package/dist/state-delta.test.js +90 -0
  55. package/dist/state-delta.test.js.map +1 -0
  56. package/dist/status-card.d.ts +7 -0
  57. package/dist/status-card.js +108 -3
  58. package/dist/status-card.js.map +1 -1
  59. package/dist/status-card.test.js +76 -3
  60. package/dist/status-card.test.js.map +1 -1
  61. package/dist/store.d.ts +121 -11
  62. package/dist/store.js +425 -61
  63. package/dist/store.js.map +1 -1
  64. package/dist/store.test.js +120 -10
  65. package/dist/store.test.js.map +1 -1
  66. package/dist/v7.test.d.ts +1 -0
  67. package/dist/v7.test.js +106 -0
  68. package/dist/v7.test.js.map +1 -0
  69. package/package.json +2 -1
@@ -1,4 +1,5 @@
1
1
  import type { ThreadStore } from "./store.js";
2
+ export type StatusCardSituation = "normal" | "new-session" | "post-compact" | "decision-change";
2
3
  export interface BuildStatusCardOptions {
3
4
  sessionId: string;
4
5
  projectKey?: string;
@@ -6,5 +7,11 @@ export interface BuildStatusCardOptions {
6
7
  recentCount?: number;
7
8
  isolated?: boolean;
8
9
  firstTurn?: boolean;
10
+ situation?: StatusCardSituation;
9
11
  }
10
12
  export declare function buildStatusCard(store: ThreadStore, opts: BuildStatusCardOptions): string;
13
+ export declare function detectSituation(store: ThreadStore, opts: {
14
+ sessionId: string;
15
+ turn: number;
16
+ projectKey?: string;
17
+ }): StatusCardSituation;
@@ -1,4 +1,8 @@
1
1
  import { applyScopePriority } from "./store.js";
2
+ function shortSession(sessionId) {
3
+ const cleaned = sessionId.replace(/^session-/, "");
4
+ return cleaned.slice(0, 7);
5
+ }
2
6
  export function buildStatusCard(store, opts) {
3
7
  const sessionId = opts.sessionId;
4
8
  const projectKey = opts.projectKey;
@@ -8,6 +12,7 @@ export function buildStatusCard(store, opts) {
8
12
  const listLimit = firstTurn ? 8 : 5;
9
13
  const feedbackLimit = firstTurn ? 8 : 5;
10
14
  const isolated = opts.isolated ?? false;
15
+ const situation = opts.situation ?? "normal";
11
16
  let goals = [];
12
17
  let decisions = [];
13
18
  let feedback = [];
@@ -32,7 +37,56 @@ export function buildStatusCard(store, opts) {
32
37
  const shareMark = (row) => row.scope === "global" ? "(全局)" : row.session_id !== sessionId ? "(来自其他会话)" : "";
33
38
  const lines = [];
34
39
  lines.push(isolated ? "[Thread 会话记忆状态卡](本会话已隔离,内容仅自己可见)" : "[Thread 会话记忆状态卡]");
35
- if (goals.length > 0) {
40
+ // 情境 A:新会话续接块(§1.5 P0 + max 2.3.1 接续包)——开场即知上次上下文,无需用户显式提醒
41
+ if (situation === "new-session" && !isolated) {
42
+ const carryGoals = goals.length > 0 ? `目标:${goals.map((g) => g.text.slice(0, 60)).join(";")}` : null;
43
+ const carryDecisions = decisions.length > 0 ? `生效决策:${decisions.map((d) => d.text.slice(0, 60)).join(";")}` : null;
44
+ const assets = store.listAssets({ visibleToSession: sessionId, limit: 3 });
45
+ const todos = store.listTodos({ visibleToSession: sessionId, status: "pending", limit: 3 });
46
+ if (carryGoals || carryDecisions || assets.length > 0 || todos.length > 0) {
47
+ lines.push("会话接续(来自之前的工作):");
48
+ if (carryGoals)
49
+ lines.push(` - ${carryGoals}`);
50
+ if (carryDecisions)
51
+ lines.push(` - ${carryDecisions}`);
52
+ if (assets.length > 0)
53
+ lines.push(` - 最近产出: ${assets.map((a) => `${a.title}(${a.path})`).join(";")}`);
54
+ if (todos.length > 0)
55
+ lines.push(` - 待办: ${todos.map((t) => `${t.text.slice(0, 60)} #${t.id}`).join(";")}`);
56
+ lines.push(" 基于以上继续,不要重新开始;查更多用 query_session_memory 导航(ls/cd/cat/grep)。");
57
+ }
58
+ // 发现层(max 2.4):活跃会话区块——模型知道别的会话存在
59
+ const activeSessions = store.listActiveSessionsWithAssets(4);
60
+ const others = activeSessions.filter((s) => s.session_id !== sessionId).slice(0, 3);
61
+ if (others.length > 0) {
62
+ lines.push(`活跃会话: ${others.map((s) => `${shortSession(s.session_id)}(${s.latest_title})`).join(" | ")}`);
63
+ }
64
+ }
65
+ // 情境 C:压缩回归块(§1.5,P0)——压缩边界后目标不漂移
66
+ if (situation === "post-compact" && !isolated) {
67
+ if (goals.length > 0) {
68
+ lines.push("压缩后回归(目标保持):");
69
+ goals
70
+ .slice()
71
+ .reverse()
72
+ .slice(0, listLimit)
73
+ .forEach((g) => lines.push(` - ${g.text.slice(0, 120)}${shareMark(g)} #${g.id}`));
74
+ lines.push(" 主线目标不变,被压缩掉的细节用 query_session_memory 回拉。");
75
+ }
76
+ }
77
+ // 决策变更情境(§1.5.3c 机制 3):项目最近定的决策 → 传达,防模型基于旧状态行动
78
+ if (situation === "decision-change" && !isolated) {
79
+ const recentDecisions = store.getRecentDecisionsMerged(sessionId, projectKey, 3);
80
+ if (recentDecisions.length > 0) {
81
+ lines.push("最近决策:");
82
+ recentDecisions.forEach((d) => {
83
+ const status = d.status === "active" ? "生效" : d.status === "proposed" ? "提议" : d.status;
84
+ lines.push(` - [${status}] ${d.text.slice(0, 120)}${shareMark(d)} #${d.id}`);
85
+ });
86
+ lines.push(" 基于最近决策行动;如有冲突需先确认,不要自行推翻。");
87
+ }
88
+ }
89
+ if (goals.length > 0 && situation !== "post-compact") {
36
90
  lines.push("目标:");
37
91
  goals
38
92
  .slice()
@@ -40,7 +94,7 @@ export function buildStatusCard(store, opts) {
40
94
  .slice(0, listLimit)
41
95
  .forEach((g, i) => lines.push(` ${i + 1}. ${g.text.slice(0, 120)}${shareMark(g)} #${g.id}`));
42
96
  }
43
- if (decisions.length > 0) {
97
+ if (decisions.length > 0 && situation !== "new-session") {
44
98
  lines.push("决策(生效中):");
45
99
  decisions.slice(0, listLimit).forEach((d, i) => lines.push(` ${i + 1}. ${d.text.slice(0, 120)}${shareMark(d)} #${d.id}`));
46
100
  }
@@ -57,9 +111,60 @@ export function buildStatusCard(store, opts) {
57
111
  .reverse()
58
112
  .forEach((e) => lines.push(` - ${e.kind}: ${e.body.slice(0, 60)}`));
59
113
  }
114
+ // 待处理事项唤醒(§1.5.3d 通道二 + 2026-08-20 复盘修复 + 2026-08-21 收件箱化):计数 + 前 2 条原文——
115
+ // 无 UI 环境(headless)折叠卡片不触发,候选堆积数天未决(狗粮实证);完成/转正/丢弃走
116
+ // /thread-cfm do/cnl,原文入卡让模型可向用户转述推进,修复"重要决策既不转正又被实际遵循"的脱节
117
+ if (!isolated) {
118
+ try {
119
+ const pending = store.listPendingCandidates({ sessionId, projectKey });
120
+ if (pending.length > 0) {
121
+ lines.push(`待处理候选(${pending.length} 条,/thread-cfm 查看): 候选转正前不得当正式决策执行。`);
122
+ pending
123
+ .slice(0, 2)
124
+ .forEach((c) => lines.push(` - c#${c.id} [${c.kind === "decision" ? "决策" : "偏好"}] ${c.text.slice(0, 60)}`));
125
+ }
126
+ }
127
+ catch {
128
+ // 失败降级,不阻塞
129
+ }
130
+ }
60
131
  // 收束语(外部借鉴③):绑定式行动收束,防止纯"再想想"式开放引导
61
132
  lines.push("需要更早的历史细节时,调用 query_session_memory 工具查询,并基于结果给出结论。");
62
- lines.push("收到 隔离//unisolate//thread-publish 单命令时,只回一句状态确认,不展开思考。");
133
+ lines.push("收到 Thread 管理命令(/thread-reg /thread-rev /thread-cfm /thread-iso /thread-uniso /thread-pub)或\"隔离/静默\"指令时,只回一句状态确认,不展开思考。");
63
134
  return lines.slice(0, budgetLines).join("\n");
64
135
  }
136
+ // 情境判定(程序确定性,§1.5):供适配器在 pre-step 调用。
137
+ // new-session = 首轮且项目已有历史(跨会话续接);post-compact = 最近事件是压缩 checkpoint;
138
+ // decision-change = 项目最近决策晚于本会话最新事件(会话外新定,防基于旧状态行动)。
139
+ export function detectSituation(store, opts) {
140
+ if (opts.turn === 1) {
141
+ // 首轮:本会话无事件(新会话)但项目有历史 → 续接情境(跨会话)
142
+ const own = store.getRecentEvents(opts.sessionId, 1);
143
+ if (own.length === 0) {
144
+ const merged = store.getActiveDecisionsMerged(opts.sessionId, opts.projectKey);
145
+ const goals = store.getActiveGoalsMerged(opts.sessionId, opts.projectKey);
146
+ if (merged.length > 0 || goals.length > 0) {
147
+ return "new-session";
148
+ }
149
+ }
150
+ }
151
+ try {
152
+ const recent = store.getRecentEvents(opts.sessionId, 3);
153
+ if (recent.some((e) => e.kind === "compact_checkpoint")) {
154
+ return "post-compact";
155
+ }
156
+ // 决策变更:项目最近决策的 updated_at 晚于本会话最新事件时间(会话外新定)
157
+ if (recent.length > 0) {
158
+ const latestEventTs = recent[0].ts;
159
+ const recentDecisions = store.getRecentDecisionsMerged(opts.sessionId, opts.projectKey, 1);
160
+ if (recentDecisions.length > 0 && recentDecisions[0].updated_at > latestEventTs) {
161
+ return "decision-change";
162
+ }
163
+ }
164
+ }
165
+ catch {
166
+ // 判定失败降级为 normal,不阻塞注入
167
+ }
168
+ return "normal";
169
+ }
65
170
  //# sourceMappingURL=status-card.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"status-card.js","sourceRoot":"","sources":["../src/status-card.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"status-card.js","sourceRoot":"","sources":["../src/status-card.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@ import { afterAll, beforeAll, describe, expect, it } from "vitest";
2
2
  import { mkdtempSync, rmSync } from "node:fs";
3
3
  import { tmpdir } from "node:os";
4
4
  import { join } from "node:path";
5
- import { buildStatusCard } from "./status-card.js";
5
+ import { buildStatusCard, detectSituation } from "./status-card.js";
6
6
  import { ThreadStore } from "./store.js";
7
7
  let dir;
8
8
  let store;
@@ -11,8 +11,7 @@ beforeAll(() => {
11
11
  store = new ThreadStore({ eventsPath: join(dir, "events.db"), structuredPath: join(dir, "structured.db"), projectKey: "card-proj" });
12
12
  for (let i = 1; i <= 6; i++) {
13
13
  store.addGoal("s1", `目标 ${i}`);
14
- store.proposeDecision("s1", `决策 ${i}`);
15
- store.confirmLatestProposed("s1");
14
+ store.addDecision("s1", `决策 ${i}`);
16
15
  }
17
16
  store.addFeedback("s1", "偏好 1", "preference");
18
17
  store.append({ session_id: "s1", kind: "user_message", ts: new Date().toISOString(), body: "事件 1" });
@@ -27,6 +26,18 @@ describe("buildStatusCard(外部借鉴 ①③:首轮加权 + 收束语)",
27
26
  const card = buildStatusCard(store, { sessionId: "s1", projectKey: "card-proj" });
28
27
  expect(card).toContain("需要更早的历史细节时,调用 query_session_memory 工具查询,并基于结果给出结论。");
29
28
  });
29
+ it("候选唤醒(2026-08-20 复盘修复):待确认计数 + 前 2 条原文入卡", () => {
30
+ store.addPendingCandidate({ sessionId: "s1", text: "候选决策 A", kind: "decision", projectKey: "card-proj" });
31
+ store.addPendingCandidate({ sessionId: "s1", text: "候选决策 B", kind: "decision", projectKey: "card-proj" });
32
+ store.addPendingCandidate({ sessionId: "s1", text: "候选偏好 C", kind: "preference", projectKey: "card-proj" });
33
+ const card = buildStatusCard(store, { sessionId: "s1", projectKey: "card-proj" });
34
+ expect(card).toContain("待处理候选(3 条");
35
+ expect(card).toContain("候选偏好 C"); // 最近优先(listPendingCandidates ORDER BY id DESC)
36
+ expect(card).toContain("候选决策 B");
37
+ expect(card).not.toContain("候选决策 A"); // 只露前 2 条,控制预算
38
+ // 清理候选,避免影响后续用例
39
+ store.ignoreAllPendingCandidates({ projectKey: "card-proj" });
40
+ });
30
41
  it("首轮档展示更多目标/决策(① 锚点全量)", () => {
31
42
  const normal = buildStatusCard(store, { sessionId: "s1", projectKey: "card-proj" });
32
43
  const first = buildStatusCard(store, { sessionId: "s1", projectKey: "card-proj", firstTurn: true });
@@ -50,4 +61,66 @@ describe("buildStatusCard(外部借鉴 ①③:首轮加权 + 收束语)",
50
61
  expect(card).toMatch(/偏好 1 #\d+/);
51
62
  });
52
63
  });
64
+ describe("detectSituation(§1.5 P0 情境判定,程序确定性)", () => {
65
+ it("首轮且本会话无事件、项目有历史 → new-session(跨会话续接)", () => {
66
+ // s1 有历史(beforeAll 造),s2 是本会话(无事件)→ 续接情境
67
+ expect(detectSituation(store, { sessionId: "s2", turn: 1, projectKey: "card-proj" })).toBe("new-session");
68
+ });
69
+ it("首轮且本会话已有事件(续写会话)→ normal", () => {
70
+ // s1 自己有事件 → 不是新会话续接
71
+ expect(detectSituation(store, { sessionId: "s1", turn: 1, projectKey: "card-proj" })).toBe("normal");
72
+ });
73
+ it("最近事件含 compact_checkpoint → post-compact", () => {
74
+ store.append({
75
+ session_id: "s1",
76
+ kind: "compact_checkpoint",
77
+ ts: new Date().toISOString(),
78
+ body: "摘要全文",
79
+ });
80
+ expect(detectSituation(store, { sessionId: "s1", turn: 5, projectKey: "card-proj" })).toBe("post-compact");
81
+ });
82
+ it("无 checkpoint 且非首轮 → normal", () => {
83
+ expect(detectSituation(store, { sessionId: "brand-new", turn: 5, projectKey: "card-proj" })).toBe("normal");
84
+ });
85
+ it("项目有比本会话最新事件更新的决策 → decision-change(§1.5.3c 机制 3)", () => {
86
+ // 先造一个本会话事件(作为时间基准,用过去时间),再在另一会话定决策(updated_at 明确更晚)
87
+ const past = new Date(Date.now() - 60_000).toISOString();
88
+ store.append({ session_id: "s-change", kind: "user_message", ts: past, body: "本会话事件" });
89
+ store.addDecision("s-other", "新定的开发基线决策(标准模式为主)");
90
+ // 判定:本会话最新事件(60s 前)< 项目最近决策 updated_at(现在)→ decision-change
91
+ expect(detectSituation(store, { sessionId: "s-change", turn: 2, projectKey: "card-proj" })).toBe("decision-change");
92
+ });
93
+ });
94
+ describe("buildStatusCard 情境传达块(§1.5 P0 C+A)", () => {
95
+ it("new-session 情境出现会话接续块(含沿用决策)", () => {
96
+ const card = buildStatusCard(store, { sessionId: "s1", projectKey: "card-proj", situation: "new-session" });
97
+ expect(card).toContain("会话接续");
98
+ expect(card).toContain("生效决策");
99
+ expect(card).toContain("基于以上继续");
100
+ });
101
+ it("post-compact 情境出现压缩回归块(目标重述)", () => {
102
+ const card = buildStatusCard(store, { sessionId: "s1", projectKey: "card-proj", situation: "post-compact" });
103
+ expect(card).toContain("压缩后回归");
104
+ expect(card).toContain("主线目标不变");
105
+ });
106
+ it("normal 情境不出现传达块(避免每轮塞指令)", () => {
107
+ const card = buildStatusCard(store, { sessionId: "s1", projectKey: "card-proj", situation: "normal" });
108
+ expect(card).not.toContain("会话接续");
109
+ expect(card).not.toContain("压缩后回归");
110
+ });
111
+ it("隔离 + new-session 组合不出现续接块(隔离不继承)", () => {
112
+ const card = buildStatusCard(store, { sessionId: "s1", projectKey: "card-proj", situation: "new-session", isolated: true });
113
+ expect(card).not.toContain("会话接续");
114
+ expect(card).toContain("本会话已隔离");
115
+ });
116
+ it("decision-change 情境出现最近决策块(§1.5.3c 机制 3)", () => {
117
+ const card = buildStatusCard(store, { sessionId: "s1", projectKey: "card-proj", situation: "decision-change" });
118
+ expect(card).toContain("最近决策");
119
+ expect(card).toContain("基于最近决策行动");
120
+ });
121
+ it("normal 情境不出现最近决策块", () => {
122
+ const card = buildStatusCard(store, { sessionId: "s1", projectKey: "card-proj", situation: "normal" });
123
+ expect(card).not.toContain("最近决策");
124
+ });
125
+ });
53
126
  //# sourceMappingURL=status-card.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"status-card.test.js","sourceRoot":"","sources":["../src/status-card.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"status-card.test.js","sourceRoot":"","sources":["../src/status-card.test.ts"],"names":[],"mappings":"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"}
package/dist/store.d.ts CHANGED
@@ -2,8 +2,8 @@ import Database from "better-sqlite3";
2
2
  import type { EventKind, SessionEvent } from "./events.js";
3
3
  import type { DecisionStatus, GoalStatus } from "./state.js";
4
4
  import { SpillPolicy } from "./governor.js";
5
- export declare const EVENTS_SCHEMA = "\nCREATE TABLE IF NOT EXISTS events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL,\n kind TEXT NOT NULL,\n ts TEXT NOT NULL,\n seq INTEGER NOT NULL,\n body TEXT NOT NULL,\n meta TEXT,\n truncated INTEGER NOT NULL DEFAULT 0,\n project_key TEXT,\n scope TEXT NOT NULL DEFAULT 'project',\n origin TEXT,\n spilled INTEGER NOT NULL DEFAULT 0,\n isolation INTEGER NOT NULL DEFAULT 0\n);\nCREATE INDEX IF NOT EXISTS idx_events_session ON events(session_id, seq);\n\nCREATE VIRTUAL TABLE IF NOT EXISTS events_fts USING fts5(\n body,\n content='events',\n content_rowid='id',\n tokenize='unicode61'\n);\n\nCREATE TABLE IF NOT EXISTS episodes (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL,\n seq_start INTEGER NOT NULL,\n seq_end INTEGER,\n status TEXT NOT NULL DEFAULT 'active',\n summary TEXT,\n created_at TEXT NOT NULL\n);\nCREATE INDEX IF NOT EXISTS idx_episodes_session ON episodes(session_id, id);\n\nCREATE TABLE IF NOT EXISTS spills (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n event_id INTEGER NOT NULL REFERENCES events(id),\n ref TEXT NOT NULL,\n blob TEXT,\n sha256 TEXT NOT NULL,\n created_at TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS lineage_edges (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL,\n src_type TEXT NOT NULL,\n src_id INTEGER,\n dst_type TEXT NOT NULL,\n dst_id INTEGER,\n ref TEXT,\n edge_type TEXT NOT NULL,\n confidence REAL NOT NULL DEFAULT 1.0,\n ts TEXT NOT NULL\n);\nCREATE INDEX IF NOT EXISTS idx_lineage_src ON lineage_edges(session_id, src_type, src_id);\nCREATE INDEX IF NOT EXISTS idx_lineage_dst ON lineage_edges(session_id, dst_type, dst_id);\n\nCREATE TABLE IF NOT EXISTS schema_version (\n version INTEGER NOT NULL,\n applied_at TEXT NOT NULL\n);\n";
6
- export declare const STRUCTURED_SCHEMA = "\nCREATE TABLE IF NOT EXISTS goals (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL,\n text TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'active',\n source_event INTEGER,\n created_at TEXT NOT NULL,\n project_key TEXT,\n scope TEXT NOT NULL DEFAULT 'project',\n origin TEXT,\n isolation INTEGER NOT NULL DEFAULT 0\n);\nCREATE INDEX IF NOT EXISTS idx_goals_session ON goals(session_id, id);\n\nCREATE TABLE IF NOT EXISTS decisions (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL,\n text TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'proposed',\n superseded_by INTEGER,\n source_event INTEGER,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n project_key TEXT,\n scope TEXT NOT NULL DEFAULT 'project',\n origin TEXT,\n isolation INTEGER NOT NULL DEFAULT 0\n);\nCREATE INDEX IF NOT EXISTS idx_decisions_session ON decisions(session_id, status);\n\nCREATE TABLE IF NOT EXISTS feedback (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL,\n text TEXT NOT NULL,\n kind TEXT NOT NULL DEFAULT 'preference',\n source_event INTEGER,\n created_at TEXT NOT NULL,\n project_key TEXT,\n scope TEXT NOT NULL DEFAULT 'project',\n origin TEXT,\n isolation INTEGER NOT NULL DEFAULT 0\n);\nCREATE INDEX IF NOT EXISTS idx_feedback_session ON feedback(session_id, id);\n\nCREATE TABLE IF NOT EXISTS session_isolation (\n session_id TEXT PRIMARY KEY,\n isolated INTEGER NOT NULL DEFAULT 0,\n updated_at TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS lineage_edges (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL,\n src_type TEXT NOT NULL,\n src_id INTEGER,\n dst_type TEXT NOT NULL,\n dst_id INTEGER,\n ref TEXT,\n edge_type TEXT NOT NULL,\n confidence REAL NOT NULL DEFAULT 1.0,\n ts TEXT NOT NULL\n);\nCREATE INDEX IF NOT EXISTS idx_lineage_src ON lineage_edges(session_id, src_type, src_id);\nCREATE INDEX IF NOT EXISTS idx_lineage_dst ON lineage_edges(session_id, dst_type, dst_id);\n\nCREATE TABLE IF NOT EXISTS schema_version (\n version INTEGER NOT NULL,\n applied_at TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS entities (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL UNIQUE,\n kind TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS decision_entities (\n decision_id INTEGER NOT NULL REFERENCES decisions(id),\n entity_id INTEGER NOT NULL REFERENCES entities(id),\n edge TEXT NOT NULL DEFAULT 'references',\n ts TEXT NOT NULL,\n PRIMARY KEY (decision_id, entity_id)\n);\n\nCREATE TABLE IF NOT EXISTS metrics (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n event_id INTEGER,\n name TEXT NOT NULL,\n value REAL NOT NULL,\n ts TEXT NOT NULL\n);\n";
5
+ export declare const EVENTS_SCHEMA = "\nCREATE TABLE IF NOT EXISTS events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL,\n kind TEXT NOT NULL,\n ts TEXT NOT NULL,\n seq INTEGER NOT NULL,\n body TEXT NOT NULL,\n meta TEXT,\n truncated INTEGER NOT NULL DEFAULT 0,\n project_key TEXT,\n scope TEXT NOT NULL DEFAULT 'project',\n origin TEXT,\n spilled INTEGER NOT NULL DEFAULT 0,\n isolation INTEGER NOT NULL DEFAULT 0\n);\nCREATE INDEX IF NOT EXISTS idx_events_session ON events(session_id, seq);\n\nCREATE VIRTUAL TABLE IF NOT EXISTS events_fts USING fts5(\n body_seg,\n content='',\n tokenize='unicode61'\n);\n\nCREATE VIRTUAL TABLE IF NOT EXISTS events_fts_tri USING fts5(\n body,\n content='',\n tokenize='trigram'\n);\n\nCREATE TABLE IF NOT EXISTS episodes (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL,\n seq_start INTEGER NOT NULL,\n seq_end INTEGER,\n status TEXT NOT NULL DEFAULT 'active',\n summary TEXT,\n created_at TEXT NOT NULL\n);\nCREATE INDEX IF NOT EXISTS idx_episodes_session ON episodes(session_id, id);\n\nCREATE TABLE IF NOT EXISTS spills (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n event_id INTEGER NOT NULL REFERENCES events(id),\n ref TEXT NOT NULL,\n blob TEXT,\n sha256 TEXT NOT NULL,\n created_at TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS lineage_edges (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL,\n src_type TEXT NOT NULL,\n src_id INTEGER,\n dst_type TEXT NOT NULL,\n dst_id INTEGER,\n ref TEXT,\n edge_type TEXT NOT NULL,\n confidence REAL NOT NULL DEFAULT 1.0,\n ts TEXT NOT NULL\n);\nCREATE INDEX IF NOT EXISTS idx_lineage_src ON lineage_edges(session_id, src_type, src_id);\nCREATE INDEX IF NOT EXISTS idx_lineage_dst ON lineage_edges(session_id, dst_type, dst_id);\n\nCREATE TABLE IF NOT EXISTS schema_version (\n version INTEGER NOT NULL,\n applied_at TEXT NOT NULL\n);\n";
6
+ export declare const STRUCTURED_SCHEMA = "\nCREATE TABLE IF NOT EXISTS goals (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL,\n text TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'active',\n source_event INTEGER,\n created_at TEXT NOT NULL,\n updated_at TEXT,\n project_key TEXT,\n scope TEXT NOT NULL DEFAULT 'project',\n origin TEXT,\n isolation INTEGER NOT NULL DEFAULT 0\n);\nCREATE INDEX IF NOT EXISTS idx_goals_session ON goals(session_id, id);\n\nCREATE TABLE IF NOT EXISTS decisions (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL,\n text TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'proposed',\n superseded_by INTEGER,\n source_event INTEGER,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n project_key TEXT,\n scope TEXT NOT NULL DEFAULT 'project',\n origin TEXT,\n isolation INTEGER NOT NULL DEFAULT 0\n);\nCREATE INDEX IF NOT EXISTS idx_decisions_session ON decisions(session_id, status);\n\nCREATE TABLE IF NOT EXISTS feedback (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL,\n text TEXT NOT NULL,\n kind TEXT NOT NULL DEFAULT 'preference',\n source_event INTEGER,\n created_at TEXT NOT NULL,\n updated_at TEXT,\n project_key TEXT,\n scope TEXT NOT NULL DEFAULT 'project',\n origin TEXT,\n isolation INTEGER NOT NULL DEFAULT 0\n);\nCREATE INDEX IF NOT EXISTS idx_feedback_session ON feedback(session_id, id);\n\nCREATE TABLE IF NOT EXISTS session_isolation (\n session_id TEXT PRIMARY KEY,\n isolated INTEGER NOT NULL DEFAULT 0,\n updated_at TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS lineage_edges (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL,\n src_type TEXT NOT NULL,\n src_id INTEGER,\n dst_type TEXT NOT NULL,\n dst_id INTEGER,\n ref TEXT,\n edge_type TEXT NOT NULL,\n confidence REAL NOT NULL DEFAULT 1.0,\n ts TEXT NOT NULL\n);\nCREATE INDEX IF NOT EXISTS idx_lineage_src ON lineage_edges(session_id, src_type, src_id);\nCREATE INDEX IF NOT EXISTS idx_lineage_dst ON lineage_edges(session_id, dst_type, dst_id);\n\nCREATE TABLE IF NOT EXISTS schema_version (\n version INTEGER NOT NULL,\n applied_at TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS entities (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL UNIQUE,\n kind TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS decision_entities (\n decision_id INTEGER NOT NULL REFERENCES decisions(id),\n entity_id INTEGER NOT NULL REFERENCES entities(id),\n edge TEXT NOT NULL DEFAULT 'references',\n ts TEXT NOT NULL,\n PRIMARY KEY (decision_id, entity_id)\n);\n\nCREATE TABLE IF NOT EXISTS metrics (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n event_id INTEGER,\n name TEXT NOT NULL,\n value REAL NOT NULL,\n ts TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS pending_candidates (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL,\n text TEXT NOT NULL,\n kind TEXT NOT NULL DEFAULT 'preference',\n status TEXT NOT NULL DEFAULT 'pending',\n source_event INTEGER,\n created_at TEXT NOT NULL,\n updated_at TEXT,\n prompt_count INTEGER NOT NULL DEFAULT 0,\n last_prompt_ts TEXT,\n project_key TEXT,\n isolation INTEGER NOT NULL DEFAULT 0\n);\nCREATE INDEX IF NOT EXISTS idx_pending_project ON pending_candidates(project_key, status);\nCREATE INDEX IF NOT EXISTS idx_pending_session ON pending_candidates(session_id, status);\n\nCREATE TABLE IF NOT EXISTS knowledge_assets (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n path TEXT NOT NULL,\n title TEXT NOT NULL,\n topic TEXT,\n scenario TEXT,\n session_id TEXT NOT NULL,\n source_event INTEGER,\n created_at TEXT NOT NULL,\n isolation INTEGER NOT NULL DEFAULT 0\n);\nCREATE INDEX IF NOT EXISTS idx_assets_session ON knowledge_assets(session_id, created_at);\nCREATE INDEX IF NOT EXISTS idx_assets_visible ON knowledge_assets(isolation, created_at);\n\nCREATE TABLE IF NOT EXISTS todos (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL,\n text TEXT NOT NULL,\n basis TEXT,\n status TEXT NOT NULL DEFAULT 'pending',\n created_at TEXT NOT NULL,\n project_key TEXT,\n isolation INTEGER NOT NULL DEFAULT 0\n);\nCREATE INDEX IF NOT EXISTS idx_todos_project ON todos(project_key, status);\nCREATE INDEX IF NOT EXISTS idx_todos_session ON todos(session_id, status);\n\nCREATE TABLE IF NOT EXISTS thread_meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\n";
7
7
  export interface ThreadStoreOptions {
8
8
  eventsPath: string;
9
9
  structuredPath: string;
@@ -40,6 +40,7 @@ export interface Goal {
40
40
  status: GoalStatus;
41
41
  source_event: number | null;
42
42
  created_at: string;
43
+ updated_at?: string | null;
43
44
  project_key?: string | null;
44
45
  scope?: string;
45
46
  origin?: string | null;
@@ -66,11 +67,47 @@ export interface FeedbackRow {
66
67
  kind: "preference" | "correction";
67
68
  source_event: number | null;
68
69
  created_at: string;
70
+ updated_at?: string | null;
69
71
  project_key?: string | null;
70
72
  scope?: string;
71
73
  origin?: string | null;
72
74
  isolation?: number;
73
75
  }
76
+ export interface PendingCandidate {
77
+ id: number;
78
+ session_id: string;
79
+ text: string;
80
+ kind: "decision" | "preference";
81
+ status: "pending" | "confirmed" | "ignored";
82
+ source_event: number | null;
83
+ created_at: string;
84
+ updated_at?: string | null;
85
+ prompt_count: number;
86
+ last_prompt_ts: string | null;
87
+ project_key?: string | null;
88
+ isolation: number;
89
+ }
90
+ export interface KnowledgeAsset {
91
+ id: number;
92
+ path: string;
93
+ title: string;
94
+ topic: string | null;
95
+ scenario: string | null;
96
+ session_id: string;
97
+ source_event: number | null;
98
+ created_at: string;
99
+ isolation: number;
100
+ }
101
+ export interface Todo {
102
+ id: number;
103
+ session_id: string;
104
+ text: string;
105
+ basis: string | null;
106
+ status: "pending" | "done" | "dropped";
107
+ created_at: string;
108
+ project_key: string | null;
109
+ isolation: number;
110
+ }
74
111
  export interface LineageNeighbor {
75
112
  id: number;
76
113
  session_id: string;
@@ -105,6 +142,75 @@ export declare class ThreadStore {
105
142
  }): string;
106
143
  hasAssistantTurn(sessionId: string, uuid: string): boolean;
107
144
  close(): void;
145
+ addPendingCandidate(input: {
146
+ sessionId: string;
147
+ text: string;
148
+ kind: "decision" | "preference";
149
+ sourceEvent?: number;
150
+ projectKey?: string;
151
+ isolation?: boolean;
152
+ }): PendingCandidate;
153
+ listPendingCandidates(opts?: {
154
+ sessionId?: string;
155
+ projectKey?: string;
156
+ }): PendingCandidate[];
157
+ confirmCandidate(id: number): PendingCandidate | undefined;
158
+ ignoreCandidate(id: number): PendingCandidate | undefined;
159
+ ignoreAllPendingCandidates(opts?: {
160
+ sessionId?: string;
161
+ projectKey?: string;
162
+ }): number;
163
+ markCandidatePrompted(id: number): void;
164
+ expireCandidates(opts: {
165
+ before: string;
166
+ projectKey?: string;
167
+ }): number;
168
+ pendingCount(opts?: {
169
+ sessionId?: string;
170
+ projectKey?: string;
171
+ }): number;
172
+ registerAsset(input: {
173
+ sessionId: string;
174
+ path: string;
175
+ title: string;
176
+ topic?: string;
177
+ scenario?: string;
178
+ sourceEvent?: number;
179
+ projectKey?: string;
180
+ isolation?: boolean;
181
+ ts?: string;
182
+ }): KnowledgeAsset;
183
+ listAssets(opts?: {
184
+ sessionId?: string;
185
+ visibleToSession?: string;
186
+ limit?: number;
187
+ }): KnowledgeAsset[];
188
+ getAsset(id: number): KnowledgeAsset | undefined;
189
+ deleteAsset(id: number): boolean;
190
+ listActiveSessionsWithAssets(limit: number): Array<{
191
+ session_id: string;
192
+ latest_title: string;
193
+ latest_ts: string;
194
+ }>;
195
+ addTodo(input: {
196
+ sessionId: string;
197
+ text: string;
198
+ basis?: string;
199
+ projectKey?: string;
200
+ isolation?: boolean;
201
+ ts?: string;
202
+ }): Todo;
203
+ listTodos(opts?: {
204
+ sessionId?: string;
205
+ projectKey?: string;
206
+ status?: Todo["status"];
207
+ basis?: string;
208
+ visibleToSession?: string;
209
+ limit?: number;
210
+ }): Todo[];
211
+ updateTodoStatus(id: number, status: Todo["status"]): boolean;
212
+ getMeta(key: string): string | undefined;
213
+ setMeta(key: string, value: string): void;
108
214
  append(event: Omit<SessionEvent, "id" | "seq" | "truncated">, opts?: AppendOptions): SessionEvent & {
109
215
  project_key?: string;
110
216
  scope?: string;
@@ -117,10 +223,12 @@ export declare class ThreadStore {
117
223
  limit?: number;
118
224
  sessionId?: string;
119
225
  }): SearchHit[];
226
+ private runFtsSearch;
120
227
  getActiveEpisode(sessionId: string): Episode | undefined;
121
228
  getLatestEpisodeWithSummary(sessionId: string): Episode | undefined;
122
229
  addGoal(sessionId: string, text: string, opts?: StructuredWriteOptions): Goal;
123
230
  getActiveGoals(sessionId: string): Goal[];
231
+ getGoals(sessionId: string): Goal[];
124
232
  getFeedback(sessionId: string, limit?: number): FeedbackRow[];
125
233
  getRecentEvents(sessionId: string, limit?: number): SessionEvent[];
126
234
  updateGoalStatus(sessionId: string, goalId: number, status: GoalStatus): Goal | undefined;
@@ -128,13 +236,10 @@ export declare class ThreadStore {
128
236
  deleteFeedback(id: number): boolean;
129
237
  proposeDecision(sessionId: string, text: string, opts?: StructuredWriteOptions): Decision;
130
238
  private findByOrigin;
131
- confirmLatestProposed(sessionId: string, opts?: {
132
- ts?: string;
133
- }): Decision | undefined;
134
- revokeLatestActive(sessionId: string, opts?: {
135
- ts?: string;
136
- }): Decision | undefined;
137
- supersedeLatestActive(sessionId: string, replacementText: string, opts?: {
239
+ addDecision(sessionId: string, text: string, opts?: StructuredWriteOptions): Decision;
240
+ promoteCandidate(id: number, newText?: string): Decision | undefined;
241
+ deleteDecision(id: number): boolean;
242
+ supersedeDecisionById(sessionId: string, id: number, replacementText: string, opts?: {
138
243
  sourceEvent?: number;
139
244
  ts?: string;
140
245
  }): {
@@ -143,12 +248,17 @@ export declare class ThreadStore {
143
248
  } | undefined;
144
249
  getActiveDecisions(sessionId: string): Decision[];
145
250
  getActiveDecisionsMerged(sessionId: string, projectKey?: string): Decision[];
251
+ getRecentDecisionsMerged(sessionId: string, projectKey: string | undefined, limit?: number): Decision[];
146
252
  getActiveGoalsMerged(sessionId: string, projectKey?: string): Goal[];
147
253
  getFeedbackMerged(sessionId: string, projectKey: string | undefined, limit?: number): FeedbackRow[];
148
254
  setSessionIsolation(sessionId: string, isolated: boolean): void;
149
255
  getSessionIsolation(sessionId: string): boolean;
150
- unisolateRow(sessionId: string, table: "goals" | "decisions" | "feedback", id: number): boolean;
151
- getLatestProposed(sessionId: string): Decision | undefined;
256
+ unisolateRow(sessionId: string, table: "goals" | "decisions" | "feedback" | "knowledge_assets", id: number): boolean;
257
+ listIsolatedRows(sessionId: string): Array<{
258
+ kind: "ast" | "goal" | "decision" | "feedback";
259
+ id: number;
260
+ text: string;
261
+ }>;
152
262
  getDecisions(sessionId: string, status?: DecisionStatus): Decision[];
153
263
  private lineageDb;
154
264
  addLineageEdge(sessionId: string, srcType: string, srcId: number | null, dstType: string, dstId: number | null, edgeType: string, opts?: {