chapterhouse 0.13.1 → 0.14.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 (116) hide show
  1. package/dist/api/route-coverage.test.js +1 -3
  2. package/dist/api/server.js +0 -2
  3. package/dist/api/server.test.js +0 -281
  4. package/dist/config.js +3 -85
  5. package/dist/config.test.js +5 -123
  6. package/dist/copilot/agents.js +13 -10
  7. package/dist/copilot/agents.test.js +10 -11
  8. package/dist/copilot/memory-coordinator.js +12 -227
  9. package/dist/copilot/memory-coordinator.test.js +31 -250
  10. package/dist/copilot/orchestrator.js +8 -66
  11. package/dist/copilot/orchestrator.test.js +9 -467
  12. package/dist/copilot/skills.js +15 -1
  13. package/dist/copilot/system-message.js +9 -15
  14. package/dist/copilot/system-message.test.js +9 -22
  15. package/dist/copilot/tools/index.js +3 -3
  16. package/dist/copilot/tools-deps.js +1 -1
  17. package/dist/copilot/tools.agent.test.js +6 -0
  18. package/dist/copilot/tools.inventory.test.js +1 -14
  19. package/dist/daemon.js +7 -9
  20. package/dist/memory/assets.js +33 -0
  21. package/dist/memory/domains.js +58 -0
  22. package/dist/memory/domains.test.js +47 -0
  23. package/dist/memory/git.js +66 -0
  24. package/dist/memory/git.test.js +32 -0
  25. package/dist/memory/history.js +19 -0
  26. package/dist/memory/hottier.js +32 -0
  27. package/dist/memory/hottier.test.js +33 -0
  28. package/dist/memory/index.js +5 -13
  29. package/dist/memory/instructions.js +17 -0
  30. package/dist/memory/manager.js +84 -0
  31. package/dist/memory/markdown.js +78 -0
  32. package/dist/memory/markdown.test.js +42 -0
  33. package/dist/memory/mutex.js +18 -0
  34. package/dist/memory/path-guard.js +26 -0
  35. package/dist/memory/path-guard.test.js +27 -0
  36. package/dist/memory/paths.js +12 -0
  37. package/dist/memory/reconcile.js +75 -0
  38. package/dist/memory/reconcile.test.js +50 -0
  39. package/dist/memory/scaffold.js +37 -0
  40. package/dist/memory/scaffold.test.js +52 -0
  41. package/dist/memory/tools/commit-wrapper.js +32 -0
  42. package/dist/memory/tools/domains.js +73 -0
  43. package/dist/memory/tools/domains.test.js +66 -0
  44. package/dist/memory/tools/git.js +52 -0
  45. package/dist/memory/tools/index.js +25 -0
  46. package/dist/memory/tools/read.js +101 -0
  47. package/dist/memory/tools/read.test.js +69 -0
  48. package/dist/memory/tools/search.js +103 -0
  49. package/dist/memory/tools/search.test.js +63 -0
  50. package/dist/memory/tools/sessions.js +45 -0
  51. package/dist/memory/tools/sessions.test.js +74 -0
  52. package/dist/memory/tools/shared.js +7 -0
  53. package/dist/memory/tools/write.js +116 -0
  54. package/dist/memory/tools/write.test.js +107 -0
  55. package/dist/memory/walk.js +39 -0
  56. package/dist/store/repositories/sessions.js +40 -0
  57. package/dist/wiki/consolidation.js +3 -31
  58. package/dist/wiki/consolidation.test.js +0 -19
  59. package/package.json +1 -1
  60. package/skills/system/evolve/SKILL.md +131 -0
  61. package/skills/system/foresight/SKILL.md +116 -0
  62. package/skills/system/history/SKILL.md +58 -0
  63. package/skills/system/housekeeping/SKILL.md +185 -0
  64. package/skills/system/reflect/SKILL.md +214 -0
  65. package/skills/system/scenario/SKILL.md +198 -0
  66. package/skills/system/setup/SKILL.md +113 -0
  67. package/web/dist/assets/{WikiEdit-CGRxNazp.js → WikiEdit-BTsiBfbC.js} +2 -2
  68. package/web/dist/assets/{WikiEdit-CGRxNazp.js.map → WikiEdit-BTsiBfbC.js.map} +1 -1
  69. package/web/dist/assets/{WikiGraph-eVWNhZS3.js → WikiGraph-COOZbUeH.js} +2 -2
  70. package/web/dist/assets/{WikiGraph-eVWNhZS3.js.map → WikiGraph-COOZbUeH.js.map} +1 -1
  71. package/web/dist/assets/{index-gAvLNEvJ.js → index-aCcfpaLM.js} +101 -101
  72. package/web/dist/assets/index-aCcfpaLM.js.map +1 -0
  73. package/web/dist/index.html +1 -1
  74. package/dist/api/routes/memory.js +0 -475
  75. package/dist/api/routes/memory.test.js +0 -108
  76. package/dist/copilot/tools/memory.js +0 -678
  77. package/dist/copilot/tools.memory.test.js +0 -590
  78. package/dist/memory/action-items.js +0 -100
  79. package/dist/memory/action-items.test.js +0 -83
  80. package/dist/memory/active-scope.js +0 -78
  81. package/dist/memory/active-scope.test.js +0 -80
  82. package/dist/memory/checkpoint-prompt.js +0 -71
  83. package/dist/memory/checkpoint.js +0 -274
  84. package/dist/memory/checkpoint.test.js +0 -275
  85. package/dist/memory/decisions.js +0 -54
  86. package/dist/memory/decisions.test.js +0 -92
  87. package/dist/memory/entities.js +0 -70
  88. package/dist/memory/entities.test.js +0 -65
  89. package/dist/memory/eot.js +0 -459
  90. package/dist/memory/eot.test.js +0 -949
  91. package/dist/memory/hooks.js +0 -149
  92. package/dist/memory/hooks.test.js +0 -325
  93. package/dist/memory/hot-tier.js +0 -283
  94. package/dist/memory/hot-tier.test.js +0 -275
  95. package/dist/memory/housekeeping-scheduler.js +0 -187
  96. package/dist/memory/housekeeping-scheduler.test.js +0 -236
  97. package/dist/memory/housekeeping.js +0 -497
  98. package/dist/memory/housekeeping.test.js +0 -410
  99. package/dist/memory/inbox.js +0 -83
  100. package/dist/memory/inbox.test.js +0 -178
  101. package/dist/memory/migration.js +0 -244
  102. package/dist/memory/migration.test.js +0 -108
  103. package/dist/memory/observations.js +0 -46
  104. package/dist/memory/observations.test.js +0 -86
  105. package/dist/memory/recall.js +0 -269
  106. package/dist/memory/recall.test.js +0 -265
  107. package/dist/memory/reflect.js +0 -273
  108. package/dist/memory/reflect.test.js +0 -256
  109. package/dist/memory/scope-lock.js +0 -26
  110. package/dist/memory/scope-lock.test.js +0 -118
  111. package/dist/memory/scopes.js +0 -89
  112. package/dist/memory/scopes.test.js +0 -176
  113. package/dist/memory/tiering.js +0 -223
  114. package/dist/memory/tiering.test.js +0 -323
  115. package/dist/memory/types.js +0 -2
  116. package/web/dist/assets/index-gAvLNEvJ.js.map +0 -1
@@ -3,8 +3,7 @@ import { randomUUID } from "node:crypto";
3
3
  import { approveAll } from "@github/copilot-sdk";
4
4
  import { createTools } from "./tools.js";
5
5
  import { getOrchestratorSystemMessage } from "./system-message.js";
6
- import { getActiveScope, withActiveScope } from "../memory/active-scope.js";
7
- import { getScope } from "../memory/scopes.js";
6
+ import { getMemoryManager } from "../memory/index.js";
8
7
  import { MemoryCoordinator } from "./memory-coordinator.js";
9
8
  import { CHAPTERHOUSE_VERSION } from "../version.js";
10
9
  import { config, DEFAULT_MODEL } from "../config.js";
@@ -39,18 +38,6 @@ const AGENT_REPLY_CHUNK_THRESHOLD = 8 * 1024;
39
38
  const ORCHESTRATOR_SESSION_KEY = "orchestrator_session_id";
40
39
  const LAST_AUTHENTICATED_USER_KEY = "last_authenticated_user";
41
40
  let taskEventLogCleanup;
42
- function getWikiSummary() {
43
- try {
44
- const db = getDb();
45
- const pages = db.prepare(`SELECT title, summary, last_updated FROM wiki_pages ORDER BY last_updated DESC LIMIT 50`).all();
46
- if (pages.length === 0)
47
- return "";
48
- return pages.map((page) => `${page.title}: ${page.summary || ""}`.trim()).join("\n");
49
- }
50
- catch {
51
- return "";
52
- }
53
- }
54
41
  let logMessage = () => { };
55
42
  export function setMessageLogger(fn) {
56
43
  logMessage = fn;
@@ -84,14 +71,6 @@ let memoryCoordinator;
84
71
  export function getLastRouteResult() {
85
72
  return lastRouteResult;
86
73
  }
87
- export function resetCheckpointSessionState(sessionKey) {
88
- memoryCoordinator?.reset(sessionKey);
89
- }
90
- export function maybeScheduleScopeChangeCheckpoint(sessionKey, previousScope, nextScope) {
91
- void memoryCoordinator?.onScopeChange(sessionKey, previousScope?.slug ?? "", nextScope?.slug ?? "").catch((error) => {
92
- log.error({ err: error, sessionKey }, "memory.checkpoint.error");
93
- });
94
- }
95
74
  export function subscribeTaskEvents(taskId, listener) {
96
75
  return agentEventBus.subscribe("session:tool_call", (event) => {
97
76
  if (event.sessionId !== taskId)
@@ -176,6 +155,7 @@ export function getCurrentAuthorizationHeader() {
176
155
  function getSessionConfig() {
177
156
  const baseTools = createTools({
178
157
  client: copilotClient,
158
+ memoryManager: getMemoryManager(),
179
159
  onAgentTaskComplete: feedAgentResult,
180
160
  });
181
161
  const tools = agentsModule.bindToolsToAgent?.("chapterhouse", baseTools) ?? baseTools;
@@ -200,18 +180,9 @@ function getPersistentAgentForSessionKey(sessionKey) {
200
180
  const agent = getAgent(slug);
201
181
  return agent?.persistent ? agent : undefined;
202
182
  }
203
- function getMemoryScopeForSession(sessionKey) {
204
- const persistentAgent = getPersistentAgentForSessionKey(sessionKey);
205
- if (persistentAgent?.scope) {
206
- return getScope(persistentAgent.scope) ?? null;
207
- }
208
- return getActiveScope();
209
- }
210
- function getSystemMessageOptions(memorySummary, hotTierXml) {
183
+ function getSystemMessageOptions() {
211
184
  return {
212
185
  selfEditEnabled: config.selfEditEnabled,
213
- memorySummary: memorySummary || undefined,
214
- hotTierXml,
215
186
  agentRoster: buildAgentRoster(),
216
187
  userContext: currentUserContext,
217
188
  };
@@ -242,9 +213,6 @@ function recordLastAuthenticatedUser(source) {
242
213
  }
243
214
  }
244
215
  export function feedAgentResult(taskId, agentSlug, result) {
245
- void memoryCoordinator?.onAgentTaskComplete(taskId, result).catch((error) => {
246
- log.error({ err: error, taskId }, "memory.eot.error");
247
- });
248
216
  const sessionKey = getTaskSessionKey(taskId) || "default";
249
217
  const agentTurnId = randomUUID();
250
218
  const agentDisplayName = getAgentRegistry().find((agent) => agent.slug === agentSlug)?.name ?? agentSlug;
@@ -346,7 +314,7 @@ async function createOrResumeSession(sessionKey, projectRoot) {
346
314
  backgroundCompactionThreshold: 0.80,
347
315
  bufferExhaustionThreshold: 0.95,
348
316
  };
349
- const memoryHooks = memoryCoordinator?.buildPerTurnHooks(sessionKey);
317
+ const memoryHooks = memoryCoordinator?.buildPerTurnHooks();
350
318
  let model = config.copilotModel;
351
319
  let systemMessageContent;
352
320
  let sessionMode = isProjectSession ? "project" : "default";
@@ -354,23 +322,20 @@ async function createOrResumeSession(sessionKey, projectRoot) {
354
322
  model = persistentAgent.model === "auto" ? config.copilotModel : persistentAgent.model;
355
323
  tools = agentsModule.bindToolsToAgent(persistentAgent.slug, filterToolsForAgent(persistentAgent, createTools({
356
324
  client: copilotClient,
325
+ memoryManager: getMemoryManager(),
357
326
  onAgentTaskComplete: feedAgentResult,
358
327
  })));
359
328
  mcpServers = filterMcpServersForAgent(persistentAgent, mcpServers);
360
- const scopedHotTier = (await memoryCoordinator?.buildHotTierContext(sessionKey)) || undefined;
361
- const channelNote = `You are in your persistent Chapterhouse channel (${sessionKey}). Your memory scope is ${persistentAgent.scope}.`;
329
+ const channelNote = `You are in your persistent Chapterhouse channel (${sessionKey}).`;
362
330
  systemMessageContent = [
363
331
  composeAgentSystemMessage(persistentAgent),
364
332
  channelNote,
365
- scopedHotTier,
366
333
  ].filter(Boolean).join("\n\n");
367
334
  sessionMode = "agent";
368
335
  }
369
336
  else {
370
- const memorySummary = getWikiSummary();
371
- const hotTierXml = (await memoryCoordinator?.buildHotTierContext(sessionKey)) || undefined;
372
337
  systemMessageContent = getOrchestratorSystemMessage({
373
- ...getSystemMessageOptions(memorySummary, hotTierXml),
338
+ ...getSystemMessageOptions(),
374
339
  version: CHAPTERHOUSE_VERSION,
375
340
  });
376
341
  }
@@ -393,7 +358,6 @@ async function createOrResumeSession(sessionKey, projectRoot) {
393
358
  infiniteSessions,
394
359
  });
395
360
  log.info({ sessionKey }, "Session resumed successfully");
396
- memoryCoordinator?.reset(sessionKey);
397
361
  upsertCopilotSession(sessionKey, sessionMode, session.sessionId, projectRoot, model);
398
362
  const mgr = registry?.get(sessionKey);
399
363
  if (mgr)
@@ -422,7 +386,6 @@ async function createOrResumeSession(sessionKey, projectRoot) {
422
386
  infiniteSessions,
423
387
  });
424
388
  log.info({ sessionKey, sessionId: session.sessionId.slice(0, 8) }, "Session created");
425
- memoryCoordinator?.reset(sessionKey);
426
389
  upsertCopilotSession(sessionKey, sessionMode, session.sessionId, projectRoot, model);
427
390
  if (sessionKey === "default")
428
391
  setState(ORCHESTRATOR_SESSION_KEY, session.sessionId);
@@ -433,12 +396,7 @@ async function createOrResumeSession(sessionKey, projectRoot) {
433
396
  }
434
397
  export async function initOrchestrator(client) {
435
398
  copilotClient = client;
436
- memoryCoordinator?.shutdown();
437
- memoryCoordinator = new MemoryCoordinator({
438
- getCopilotClient: () => copilotClient,
439
- config,
440
- resolveScopeForSession: getMemoryScopeForSession,
441
- });
399
+ memoryCoordinator = new MemoryCoordinator();
442
400
  // Initialize per-task ring buffer — subscribes to agentEventBus for session:tool_call events.
443
401
  taskEventLogCleanup?.();
444
402
  taskEventLogCleanup = initTaskEventLog();
@@ -738,11 +696,6 @@ async function executeOnSession(manager, item) {
738
696
  log.warn({ taskId, length: finalResult.length, limit: 10_000 }, "subagent result truncated before persistence");
739
697
  }
740
698
  db.prepare(`UPDATE agent_tasks SET status = 'completed', result = ?, completed_at = CURRENT_TIMESTAMP WHERE task_id = ?`).run(finalResult?.slice(0, 10000) ?? null, taskId);
741
- if (finalResult) {
742
- void memoryCoordinator?.onAgentTaskComplete(taskId, finalResult).catch((error) => {
743
- log.error({ err: error, taskId }, "memory.eot.error");
744
- });
745
- }
746
699
  const taskRow = db.prepare(`SELECT agent_slug FROM agent_tasks WHERE task_id = ?`).get(taskId);
747
700
  void agentEventBus.emit({
748
701
  type: "session:destroyed",
@@ -902,13 +855,9 @@ async function executeOnSession(manager, item) {
902
855
  unsubTurnReasoning();
903
856
  }
904
857
  });
905
- const persistentAgent = getPersistentAgentForSessionKey(sessionKey);
906
858
  const scopedRunTurn = () => item.taskId
907
859
  ? withToolTaskContext(item.taskId, runTurn)
908
860
  : runTurn();
909
- if (persistentAgent?.scope) {
910
- return withActiveScope(persistentAgent.scope, scopedRunTurn);
911
- }
912
861
  return scopedRunTurn();
913
862
  }
914
863
  /**
@@ -1087,9 +1036,6 @@ export function sendToOrchestrator(prompt, source, callback, attachments, onActi
1087
1036
  logConversation("assistant", finalContent, logSource, sessionKey, { turnId });
1088
1037
  }
1089
1038
  catch { /* best-effort */ }
1090
- void memoryCoordinator?.onTurnComplete(sessionKey, prompt, finalContent, source.type).catch((error) => {
1091
- log.error({ err: error, sessionKey }, "memory.turn_complete.error");
1092
- });
1093
1039
  if (copilotClient) {
1094
1040
  maybeWriteEpisode(copilotClient).catch((err) => {
1095
1041
  log.error({ err: err instanceof Error ? err.message : err }, "Episode write failed (non-fatal)");
@@ -1194,9 +1140,6 @@ export async function interruptCurrentTurn(sessionKey, newPrompt, source, callba
1194
1140
  logConversation("assistant", finalContent, sourceLabel, sessionKey, { turnId });
1195
1141
  }
1196
1142
  catch { /* best-effort */ }
1197
- void memoryCoordinator?.onTurnComplete(sessionKey, newPrompt, finalContent, source.type).catch((error) => {
1198
- log.error({ err: error, sessionKey }, "memory.turn_complete.error");
1199
- });
1200
1143
  if (copilotClient) {
1201
1144
  maybeWriteEpisode(copilotClient).catch((err) => {
1202
1145
  log.error({ err: err instanceof Error ? err.message : err }, "Episode write failed (non-fatal)");
@@ -1373,7 +1316,6 @@ export function getAgentInfo() {
1373
1316
  /** Clean up on shutdown/restart. */
1374
1317
  export async function shutdownAgents() {
1375
1318
  stopClassifier();
1376
- memoryCoordinator?.shutdown();
1377
1319
  memoryCoordinator = undefined;
1378
1320
  if (!registry) {
1379
1321
  await clearActiveTasks();