chapterhouse 0.9.1 → 0.10.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 (112) hide show
  1. package/README.md +1 -1
  2. package/agents/korg.agent.md +20 -0
  3. package/dist/api/auth.js +11 -1
  4. package/dist/api/auth.test.js +29 -0
  5. package/dist/api/errors.js +23 -0
  6. package/dist/api/route-coverage.test.js +61 -21
  7. package/dist/api/routes/agents.js +472 -0
  8. package/dist/api/routes/memory.js +299 -0
  9. package/dist/api/routes/projects.js +170 -0
  10. package/dist/api/routes/sessions.js +347 -0
  11. package/dist/api/routes/system.js +82 -0
  12. package/dist/api/routes/wiki.js +455 -0
  13. package/dist/api/routes/wiki.test.js +49 -0
  14. package/dist/api/send-json.js +16 -0
  15. package/dist/api/send-json.test.js +18 -0
  16. package/dist/api/server-runtime.js +45 -3
  17. package/dist/api/server.js +34 -1764
  18. package/dist/api/server.test.js +239 -8
  19. package/dist/api/sse-hub.js +37 -0
  20. package/dist/cli.js +1 -1
  21. package/dist/config.js +151 -58
  22. package/dist/config.test.js +29 -0
  23. package/dist/copilot/okr-mapper.js +2 -11
  24. package/dist/copilot/orchestrator.js +358 -352
  25. package/dist/copilot/orchestrator.test.js +139 -4
  26. package/dist/copilot/prompt-date.js +2 -1
  27. package/dist/copilot/session-manager.js +25 -23
  28. package/dist/copilot/session-manager.test.js +35 -1
  29. package/dist/copilot/standup.js +2 -2
  30. package/dist/copilot/task-event-log.js +7 -1
  31. package/dist/copilot/task-event-log.test.js +13 -0
  32. package/dist/copilot/tools/agent.js +608 -0
  33. package/dist/copilot/tools/index.js +19 -0
  34. package/dist/copilot/tools/memory.js +678 -0
  35. package/dist/copilot/tools/models.js +2 -0
  36. package/dist/copilot/tools/okr.js +171 -0
  37. package/dist/copilot/tools/wiki.js +333 -0
  38. package/dist/copilot/tools-deps.js +4 -0
  39. package/dist/copilot/tools.agent.test.js +10 -8
  40. package/dist/copilot/tools.inventory.test.js +76 -0
  41. package/dist/copilot/tools.js +1 -1725
  42. package/dist/copilot/tools.okr.test.js +31 -0
  43. package/dist/copilot/tools.wiki.test.js +358 -6
  44. package/dist/copilot/turn-event-log.js +31 -4
  45. package/dist/copilot/turn-event-log.test.js +24 -2
  46. package/dist/copilot/workiq-installer.test.js +2 -2
  47. package/dist/daemon-install.js +3 -2
  48. package/dist/daemon.js +9 -17
  49. package/dist/integrations/ado-client.js +90 -9
  50. package/dist/integrations/ado-client.test.js +56 -0
  51. package/dist/integrations/team-push.js +1 -0
  52. package/dist/integrations/team-push.test.js +6 -0
  53. package/dist/integrations/teams-notify.js +1 -0
  54. package/dist/integrations/teams-notify.test.js +5 -0
  55. package/dist/memory/active-scope.test.js +0 -1
  56. package/dist/memory/checkpoint.js +89 -72
  57. package/dist/memory/checkpoint.test.js +23 -3
  58. package/dist/memory/eot.js +194 -89
  59. package/dist/memory/eot.test.js +186 -3
  60. package/dist/memory/hooks.js +2 -4
  61. package/dist/memory/housekeeping-scheduler.js +1 -1
  62. package/dist/memory/housekeeping-scheduler.test.js +1 -2
  63. package/dist/memory/housekeeping.js +100 -3
  64. package/dist/memory/housekeeping.test.js +33 -2
  65. package/dist/memory/reflect.test.js +2 -0
  66. package/dist/memory/scope-lock.js +26 -0
  67. package/dist/memory/scope-lock.test.js +118 -0
  68. package/dist/memory/scopes.test.js +0 -1
  69. package/dist/mode-context.js +58 -5
  70. package/dist/mode-context.test.js +68 -0
  71. package/dist/paths.js +1 -0
  72. package/dist/setup.js +3 -2
  73. package/dist/shared/api-schemas.js +48 -5
  74. package/dist/store/connection.js +96 -0
  75. package/dist/store/db.js +5 -1498
  76. package/dist/store/db.test.js +182 -1
  77. package/dist/store/migrations.js +460 -0
  78. package/dist/store/repositories/memory.js +281 -0
  79. package/dist/store/repositories/okr.js +3 -0
  80. package/dist/store/repositories/projects.js +5 -0
  81. package/dist/store/repositories/sessions.js +284 -0
  82. package/dist/store/repositories/wiki.js +60 -0
  83. package/dist/store/schema.js +501 -0
  84. package/dist/util/logger.js +3 -2
  85. package/dist/wiki/consolidation.js +50 -9
  86. package/dist/wiki/consolidation.test.js +45 -0
  87. package/dist/wiki/frontmatter.js +45 -14
  88. package/dist/wiki/frontmatter.test.js +26 -1
  89. package/dist/wiki/fs.js +16 -4
  90. package/dist/wiki/fs.test.js +84 -0
  91. package/dist/wiki/index-manager.js +30 -2
  92. package/dist/wiki/index-manager.test.js +43 -12
  93. package/dist/wiki/ingest.js +17 -1
  94. package/dist/wiki/lock.js +11 -1
  95. package/dist/wiki/log-manager.js +2 -7
  96. package/dist/wiki/migrate.js +44 -17
  97. package/dist/wiki/project-registry.js +10 -5
  98. package/dist/wiki/project-registry.test.js +14 -0
  99. package/dist/wiki/scheduler.js +1 -1
  100. package/dist/wiki/seed-team-wiki.js +2 -1
  101. package/dist/wiki/team-sync.js +31 -6
  102. package/dist/wiki/team-sync.test.js +81 -0
  103. package/package.json +1 -1
  104. package/web/dist/assets/WikiEdit-BZXAdarz.js +30 -0
  105. package/web/dist/assets/WikiEdit-BZXAdarz.js.map +1 -0
  106. package/web/dist/assets/WikiGraph-KrCYco4v.js +2 -0
  107. package/web/dist/assets/WikiGraph-KrCYco4v.js.map +1 -0
  108. package/web/dist/assets/index-CUm2Wbuh.js +250 -0
  109. package/web/dist/assets/index-CUm2Wbuh.js.map +1 -0
  110. package/web/dist/index.html +1 -1
  111. package/web/dist/assets/index-iQrv3lQN.js +0 -286
  112. package/web/dist/assets/index-iQrv3lQN.js.map +0 -1
@@ -2,10 +2,9 @@
2
2
  * Shared API contract schemas — single source of truth for every server↔client
3
3
  * response type in Chapterhouse.
4
4
  *
5
- * Both the backend (`src/api/server.ts`) and the frontend (`web/src/api-schemas.ts`)
6
- * import from here. When a server response shape changes, the TypeScript compiler
7
- * immediately surfaces any mismatch on the import side schema drift becomes a
8
- * compile error rather than a runtime bug.
5
+ * The frontend (`web/src/api-schemas.ts`) re-exports these schemas, and selected
6
+ * backend routes validate payloads with them before sending JSON responses. New
7
+ * server↔client response contracts should be added here rather than in route files.
9
8
  *
10
9
  * Excluded from this file:
11
10
  * - Parts model (TextPart, ToolCallPart, etc.) — client-only; synthesised from SSE
@@ -63,6 +62,13 @@ export const CancelResponseSchema = z.object({
63
62
  status: z.string(),
64
63
  cancelled: z.boolean(),
65
64
  });
65
+ export const HealthResponseSchema = z.object({
66
+ status: z.string(),
67
+ timestamp: z.string(),
68
+ fts5Available: z.boolean(),
69
+ fts5Ready: z.boolean(),
70
+ });
71
+ export const OkResponseSchema = z.object({ ok: z.literal(true) });
66
72
  // ---------------------------------------------------------------------------
67
73
  // /api/agents
68
74
  // ---------------------------------------------------------------------------
@@ -176,7 +182,7 @@ export const WorkerDetailSchema = z.object({
176
182
  // ---------------------------------------------------------------------------
177
183
  // /api/workers/:taskId/events (historical event log)
178
184
  // ---------------------------------------------------------------------------
179
- export const TaskEventSchema = z.object({
185
+ const ToolTaskEventSchema = z.object({
180
186
  id: z.number(),
181
187
  taskId: z.string(),
182
188
  seq: z.number(),
@@ -185,6 +191,28 @@ export const TaskEventSchema = z.object({
185
191
  toolName: z.string().nullable(),
186
192
  summary: z.string().nullable(),
187
193
  });
194
+ const OutputDeltaTaskEventSchema = z.object({
195
+ id: z.number(),
196
+ taskId: z.string(),
197
+ seq: z.number(),
198
+ ts: z.number(),
199
+ type: z.literal("output_delta"),
200
+ text: z.string(),
201
+ });
202
+ const TaskStatusEventSchema = z.object({
203
+ id: z.number(),
204
+ taskId: z.string(),
205
+ seq: z.number(),
206
+ ts: z.number(),
207
+ type: z.literal("task_status"),
208
+ status: z.string(),
209
+ summary: z.string().nullable().optional(),
210
+ });
211
+ export const TaskEventSchema = z.union([
212
+ ToolTaskEventSchema,
213
+ OutputDeltaTaskEventSchema,
214
+ TaskStatusEventSchema,
215
+ ]);
188
216
  export const TaskEventsResponseSchema = z.object({
189
217
  taskId: z.string(),
190
218
  events: z.array(TaskEventSchema),
@@ -558,6 +586,12 @@ export const SetActiveScopeResponseSchema = z.object({
558
586
  ok: z.literal(true),
559
587
  scope: z.string().nullable(),
560
588
  });
589
+ export const MemoryScopeCreateResponseSchema = z.object({
590
+ slug: z.string(),
591
+ title: z.string(),
592
+ description: z.string(),
593
+ active: z.boolean(),
594
+ });
561
595
  // ---------------------------------------------------------------------------
562
596
  // /api/memory/scopes
563
597
  // ---------------------------------------------------------------------------
@@ -583,6 +617,7 @@ export const MemoryScopeListSchema = z.object({
583
617
  export const MemoryEntriesSchema = z.object({
584
618
  entries: z.array(z.record(z.string(), z.unknown())),
585
619
  total: z.number(),
620
+ nextCursor: z.string().optional(),
586
621
  });
587
622
  // ---------------------------------------------------------------------------
588
623
  // /api/memory/:scope/remember
@@ -612,4 +647,12 @@ export const MemoryInboxSchema = z.object({
612
647
  export const InboxRouteResponseSchema = z.object({
613
648
  ok: z.literal(true),
614
649
  });
650
+ export const MemoryHookResponseSchema = z.object({
651
+ ok: z.literal(true),
652
+ observation_id: z.string(),
653
+ });
654
+ export const WikiPinResponseSchema = z.object({
655
+ ok: z.literal(true),
656
+ pinned: z.boolean(),
657
+ });
615
658
  //# sourceMappingURL=api-schemas.js.map
@@ -0,0 +1,96 @@
1
+ import Database from "better-sqlite3";
2
+ import { randomUUID } from "node:crypto";
3
+ import { ensureChapterhouseHome, getDbPath } from "../paths.js";
4
+ import { logger } from "../util/logger.js";
5
+ import { resetSessionRepositoryForTests } from "./repositories/sessions.js";
6
+ import { initializeSchema } from "./schema.js";
7
+ let db;
8
+ let fts5Available = false;
9
+ let fts5Ready = false;
10
+ let fts5RebuildTimer;
11
+ let currentDaemonRunId;
12
+ let daemonRunRecorded = false;
13
+ export function getCurrentRunId() {
14
+ currentDaemonRunId ??= randomUUID();
15
+ return currentDaemonRunId;
16
+ }
17
+ function recordCurrentDaemonRun(database) {
18
+ if (daemonRunRecorded) {
19
+ return;
20
+ }
21
+ database.prepare(`INSERT OR IGNORE INTO daemon_runs (run_id) VALUES (?)`).run(getCurrentRunId());
22
+ daemonRunRecorded = true;
23
+ }
24
+ function queueFts5Rebuild(database, rebuildTables) {
25
+ if (rebuildTables.length === 0) {
26
+ fts5Ready = true;
27
+ return;
28
+ }
29
+ fts5Ready = false;
30
+ if (fts5RebuildTimer) {
31
+ clearTimeout(fts5RebuildTimer);
32
+ }
33
+ fts5RebuildTimer = setTimeout(() => {
34
+ fts5RebuildTimer = undefined;
35
+ try {
36
+ for (const table of rebuildTables) {
37
+ database.exec(`INSERT INTO ${table}(${table}) VALUES ('rebuild')`);
38
+ }
39
+ fts5Ready = true;
40
+ }
41
+ catch (error) {
42
+ fts5Available = false;
43
+ fts5Ready = true;
44
+ logger.warn({ err: error }, "FTS5 rebuild failed — memory recall will use LIKE queries (degraded quality)");
45
+ }
46
+ }, 0);
47
+ }
48
+ export function getDb() {
49
+ if (!db) {
50
+ ensureChapterhouseHome();
51
+ db = new Database(getDbPath());
52
+ db.pragma("journal_mode = WAL");
53
+ db.pragma("busy_timeout = 15000");
54
+ db.pragma("foreign_keys = ON");
55
+ initializeSchema(db, {
56
+ recordCurrentDaemonRun,
57
+ queueFts5Rebuild,
58
+ setFts5Available: (available) => {
59
+ fts5Available = available;
60
+ },
61
+ setFts5Ready: (ready) => {
62
+ fts5Ready = ready;
63
+ },
64
+ });
65
+ }
66
+ return db;
67
+ }
68
+ export function isFts5Available() {
69
+ getDb();
70
+ return fts5Available;
71
+ }
72
+ export function isFts5Ready() {
73
+ getDb();
74
+ return fts5Ready;
75
+ }
76
+ export function closeDb() {
77
+ if (fts5RebuildTimer) {
78
+ clearTimeout(fts5RebuildTimer);
79
+ fts5RebuildTimer = undefined;
80
+ }
81
+ if (db) {
82
+ db.close();
83
+ db = undefined;
84
+ daemonRunRecorded = false;
85
+ }
86
+ fts5Ready = false;
87
+ }
88
+ export function resetDbForTests() {
89
+ closeDb();
90
+ resetSessionRepositoryForTests();
91
+ fts5Available = false;
92
+ fts5Ready = false;
93
+ currentDaemonRunId = undefined;
94
+ daemonRunRecorded = false;
95
+ }
96
+ //# sourceMappingURL=connection.js.map