@cleocode/core 2026.3.69 → 2026.3.71

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 (129) hide show
  1. package/dist/agents/retry.d.ts.map +1 -1
  2. package/dist/agents/retry.js +23 -42
  3. package/dist/agents/retry.js.map +1 -1
  4. package/dist/cleo.d.ts +2 -300
  5. package/dist/cleo.d.ts.map +1 -1
  6. package/dist/cleo.js +2 -2
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/config.js +30 -0
  9. package/dist/config.js.map +1 -1
  10. package/dist/hooks/handlers/file-hooks.d.ts +5 -2
  11. package/dist/hooks/handlers/file-hooks.d.ts.map +1 -1
  12. package/dist/hooks/handlers/index.d.ts +2 -0
  13. package/dist/hooks/handlers/index.d.ts.map +1 -1
  14. package/dist/hooks/handlers/mcp-hooks.d.ts +11 -7
  15. package/dist/hooks/handlers/mcp-hooks.d.ts.map +1 -1
  16. package/dist/hooks/handlers/memory-bridge-refresh.d.ts +20 -0
  17. package/dist/hooks/handlers/memory-bridge-refresh.d.ts.map +1 -0
  18. package/dist/hooks/handlers/memory-bridge-refresh.js +42 -0
  19. package/dist/hooks/handlers/memory-bridge-refresh.js.map +1 -0
  20. package/dist/hooks/handlers/session-hooks.d.ts +10 -0
  21. package/dist/hooks/handlers/session-hooks.d.ts.map +1 -1
  22. package/dist/hooks/handlers/session-hooks.js +36 -0
  23. package/dist/hooks/handlers/session-hooks.js.map +1 -1
  24. package/dist/hooks/handlers/task-hooks.d.ts +4 -0
  25. package/dist/hooks/handlers/task-hooks.d.ts.map +1 -1
  26. package/dist/hooks/handlers/task-hooks.js +7 -0
  27. package/dist/hooks/handlers/task-hooks.js.map +1 -1
  28. package/dist/hooks/handlers/work-capture-hooks.d.ts +40 -0
  29. package/dist/hooks/handlers/work-capture-hooks.d.ts.map +1 -0
  30. package/dist/index.d.ts +2 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +5069 -4678
  33. package/dist/index.js.map +4 -4
  34. package/dist/internal.d.ts +10 -2
  35. package/dist/internal.d.ts.map +1 -1
  36. package/dist/internal.js +10 -3
  37. package/dist/internal.js.map +1 -1
  38. package/dist/memory/auto-extract.d.ts +13 -0
  39. package/dist/memory/auto-extract.d.ts.map +1 -1
  40. package/dist/memory/auto-extract.js +34 -0
  41. package/dist/memory/auto-extract.js.map +1 -1
  42. package/dist/memory/brain-embedding.d.ts +13 -0
  43. package/dist/memory/brain-embedding.d.ts.map +1 -1
  44. package/dist/memory/brain-embedding.js +17 -0
  45. package/dist/memory/brain-embedding.js.map +1 -1
  46. package/dist/memory/brain-maintenance.d.ts +110 -0
  47. package/dist/memory/brain-maintenance.d.ts.map +1 -0
  48. package/dist/memory/brain-maintenance.js +98 -0
  49. package/dist/memory/brain-maintenance.js.map +1 -0
  50. package/dist/memory/brain-retrieval.d.ts +31 -5
  51. package/dist/memory/brain-retrieval.d.ts.map +1 -1
  52. package/dist/memory/brain-retrieval.js +53 -6
  53. package/dist/memory/brain-retrieval.js.map +1 -1
  54. package/dist/memory/embedding-local.d.ts +55 -0
  55. package/dist/memory/embedding-local.d.ts.map +1 -0
  56. package/dist/memory/embedding-local.js +97 -0
  57. package/dist/memory/embedding-local.js.map +1 -0
  58. package/dist/memory/embedding-queue.d.ts +90 -0
  59. package/dist/memory/embedding-queue.d.ts.map +1 -0
  60. package/dist/memory/embedding-queue.js +271 -0
  61. package/dist/memory/embedding-queue.js.map +1 -0
  62. package/dist/memory/embedding-worker.d.ts +19 -0
  63. package/dist/memory/embedding-worker.d.ts.map +1 -0
  64. package/dist/memory/embedding-worker.js +58 -0
  65. package/dist/memory/embedding-worker.js.map +1 -0
  66. package/dist/memory/memory-bridge.d.ts +21 -1
  67. package/dist/memory/memory-bridge.d.ts.map +1 -1
  68. package/dist/memory/memory-bridge.js +83 -2
  69. package/dist/memory/memory-bridge.js.map +1 -1
  70. package/dist/memory/session-memory.d.ts +26 -0
  71. package/dist/memory/session-memory.d.ts.map +1 -1
  72. package/dist/memory/session-memory.js +105 -0
  73. package/dist/memory/session-memory.js.map +1 -1
  74. package/dist/pagination.js +3 -0
  75. package/dist/pagination.js.map +1 -1
  76. package/dist/sessions/index.d.ts.map +1 -1
  77. package/dist/sessions/index.js +2 -6
  78. package/dist/sessions/index.js.map +1 -1
  79. package/dist/store/brain-sqlite.js +13 -62
  80. package/dist/store/brain-sqlite.js.map +1 -1
  81. package/dist/store/migration-manager.js +151 -0
  82. package/dist/store/migration-manager.js.map +1 -0
  83. package/dist/store/sqlite.d.ts.map +1 -1
  84. package/dist/store/sqlite.js +16 -134
  85. package/dist/store/sqlite.js.map +1 -1
  86. package/dist/tasks/add.js +27 -22
  87. package/dist/tasks/add.js.map +1 -1
  88. package/dist/tasks/complete.d.ts.map +1 -1
  89. package/dist/tasks/complete.js +13 -40
  90. package/dist/tasks/complete.js.map +1 -1
  91. package/dist/tasks/enforcement.js +12 -15
  92. package/dist/tasks/enforcement.js.map +1 -1
  93. package/dist/upgrade.js +246 -3
  94. package/dist/upgrade.js.map +1 -1
  95. package/migrations/drizzle-tasks/20260320013731_wave0-schema-hardening/migration.sql +17 -17
  96. package/package.json +6 -5
  97. package/src/agents/retry.ts +30 -24
  98. package/src/cleo.ts +30 -251
  99. package/src/config.ts +18 -0
  100. package/src/hooks/handlers/file-hooks.ts +29 -3
  101. package/src/hooks/handlers/index.ts +2 -0
  102. package/src/hooks/handlers/mcp-hooks.ts +32 -13
  103. package/src/hooks/handlers/memory-bridge-refresh.ts +47 -0
  104. package/src/hooks/handlers/session-hooks.ts +38 -0
  105. package/src/hooks/handlers/task-hooks.ts +8 -0
  106. package/src/hooks/handlers/work-capture-hooks.ts +184 -0
  107. package/src/index.ts +5 -0
  108. package/src/internal.ts +28 -2
  109. package/src/memory/__tests__/brain-automation.test.ts +941 -0
  110. package/src/memory/auto-extract.ts +40 -0
  111. package/src/memory/brain-embedding.ts +18 -0
  112. package/src/memory/brain-maintenance.ts +183 -0
  113. package/src/memory/brain-retrieval.ts +85 -7
  114. package/src/memory/embedding-local.ts +107 -0
  115. package/src/memory/embedding-queue.ts +304 -0
  116. package/src/memory/embedding-worker.ts +79 -0
  117. package/src/memory/memory-bridge.ts +101 -2
  118. package/src/memory/session-memory.ts +123 -0
  119. package/src/sessions/index.ts +2 -6
  120. package/src/store/__tests__/test-db-helper.js +14 -2
  121. package/src/store/__tests__/test-db-helper.ts +4 -1
  122. package/src/store/sqlite.ts +28 -0
  123. package/src/tasks/__tests__/complete-unblocks.test.ts +4 -1
  124. package/src/tasks/__tests__/complete.test.ts +18 -6
  125. package/src/tasks/__tests__/epic-enforcement.test.ts +4 -1
  126. package/src/tasks/__tests__/update.test.ts +4 -1
  127. package/src/tasks/complete.ts +8 -8
  128. package/templates/config.template.json +19 -0
  129. package/templates/global-config.template.json +19 -0
@@ -0,0 +1,184 @@
1
+ /**
2
+ * Active-Work Capture Hook Handlers
3
+ *
4
+ * Captures dispatch mutation events to BRAIN during active work, closing
5
+ * the gap between lifecycle-only capture (session end, task complete) and
6
+ * continuous capture. Only WRITE operations that represent meaningful work
7
+ * are captured — reads and operations already handled by lifecycle hooks
8
+ * are skipped to avoid flooding brain.db.
9
+ *
10
+ * Disabled by default. Enable via:
11
+ * - Config: brain.captureWork = true (checked first)
12
+ * - Env: CLEO_BRAIN_CAPTURE_WORK=true (overrides config)
13
+ *
14
+ * Auto-registers on module load.
15
+ *
16
+ * @task T142
17
+ */
18
+
19
+ import { hooks } from '../registry.js';
20
+ import type { OnPromptSubmitPayload, OnResponseCompletePayload } from '../types.js';
21
+
22
+ // ---------------------------------------------------------------------------
23
+ // Shared helpers
24
+ // ---------------------------------------------------------------------------
25
+
26
+ function isMissingBrainSchemaError(err: unknown): boolean {
27
+ if (!(err instanceof Error)) return false;
28
+ const message = String(err.message || '').toLowerCase();
29
+ return message.includes('no such table') && message.includes('brain_');
30
+ }
31
+
32
+ /**
33
+ * Check whether active-work capture is enabled.
34
+ *
35
+ * Resolution order (first truthy wins):
36
+ * 1. CLEO_BRAIN_CAPTURE_WORK env var (explicit override)
37
+ * 2. brain.captureWork project config value
38
+ *
39
+ * Defaults to false when neither is set.
40
+ */
41
+ async function isWorkCaptureEnabled(projectRoot: string): Promise<boolean> {
42
+ const envOverride = process.env['CLEO_BRAIN_CAPTURE_WORK'];
43
+ if (envOverride !== undefined) {
44
+ return envOverride === 'true';
45
+ }
46
+ try {
47
+ const { loadConfig } = await import('../../config.js');
48
+ const config = await loadConfig(projectRoot);
49
+ return config.brain?.captureWork ?? false;
50
+ } catch {
51
+ return false;
52
+ }
53
+ }
54
+
55
+ // ---------------------------------------------------------------------------
56
+ // Smart-filter: which mutations to capture
57
+ // ---------------------------------------------------------------------------
58
+
59
+ /**
60
+ * Mutations that represent novel work not already captured by lifecycle hooks.
61
+ *
62
+ * Excluded (already captured elsewhere):
63
+ * - tasks.complete → task-hooks.ts (onToolComplete)
64
+ * - session.start → session-hooks.ts (onSessionStart)
65
+ * - session.end → session-hooks.ts (onSessionEnd)
66
+ * - memory.brain.observe → observeBrain itself writes to brain; self-loop
67
+ *
68
+ * All query gateway operations are excluded by the gateway check before
69
+ * this set is consulted.
70
+ */
71
+ const CAPTURE_OPERATIONS = new Set<string>([
72
+ 'tasks.add',
73
+ 'tasks.update',
74
+ 'tasks.move',
75
+ 'tasks.link',
76
+ 'tasks.unlink',
77
+ 'tasks.label',
78
+ 'tasks.unlabel',
79
+ 'tasks.note',
80
+ ]);
81
+
82
+ /**
83
+ * Determine whether a mutate operation should be captured.
84
+ *
85
+ * Only `mutate` gateway operations in CAPTURE_OPERATIONS are captured.
86
+ * All `query` gateway calls are skipped (reads produce no novel work).
87
+ *
88
+ * @param gateway - 'query' or 'mutate'
89
+ * @param domain - e.g. 'tasks'
90
+ * @param operation - e.g. 'add'
91
+ */
92
+ function shouldCapture(gateway: string, domain: string, operation: string): boolean {
93
+ if (gateway !== 'mutate') return false;
94
+ const key = `${domain}.${operation}`;
95
+ return CAPTURE_OPERATIONS.has(key);
96
+ }
97
+
98
+ // ---------------------------------------------------------------------------
99
+ // Handlers
100
+ // ---------------------------------------------------------------------------
101
+
102
+ /**
103
+ * Handle onPromptSubmit — log incoming mutation intents to BRAIN.
104
+ *
105
+ * Only fires for mutate operations in CAPTURE_OPERATIONS.
106
+ * Gated behind brain.captureWork config (or CLEO_BRAIN_CAPTURE_WORK env).
107
+ *
108
+ * @param projectRoot - Absolute path to the project root
109
+ * @param payload - onPromptSubmit event payload
110
+ */
111
+ export async function handleWorkPromptSubmit(
112
+ projectRoot: string,
113
+ payload: OnPromptSubmitPayload,
114
+ ): Promise<void> {
115
+ if (!shouldCapture(payload.gateway, payload.domain, payload.operation)) return;
116
+ if (!(await isWorkCaptureEnabled(projectRoot))) return;
117
+
118
+ const { observeBrain } = await import('../../memory/brain-retrieval.js');
119
+
120
+ try {
121
+ await observeBrain(projectRoot, {
122
+ text: `Dispatch intent: ${payload.gateway}:${payload.domain}.${payload.operation}${payload.source ? ` (from ${payload.source})` : ''}`,
123
+ title: `Work intent: ${payload.domain}.${payload.operation}`,
124
+ type: 'discovery',
125
+ sourceType: 'agent',
126
+ });
127
+ } catch (err) {
128
+ if (!isMissingBrainSchemaError(err)) throw err;
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Handle onResponseComplete — capture completed mutations to BRAIN.
134
+ *
135
+ * Only fires for successful mutate operations in CAPTURE_OPERATIONS.
136
+ * Failures are skipped — the intent was already captured by handleWorkPromptSubmit.
137
+ * Gated behind brain.captureWork config (or CLEO_BRAIN_CAPTURE_WORK env).
138
+ *
139
+ * @param projectRoot - Absolute path to the project root
140
+ * @param payload - onResponseComplete event payload
141
+ */
142
+ export async function handleWorkResponseComplete(
143
+ projectRoot: string,
144
+ payload: OnResponseCompletePayload,
145
+ ): Promise<void> {
146
+ if (!shouldCapture(payload.gateway, payload.domain, payload.operation)) return;
147
+ // Only capture successful completions — failures are noise
148
+ if (!payload.success) return;
149
+ if (!(await isWorkCaptureEnabled(projectRoot))) return;
150
+
151
+ const { observeBrain } = await import('../../memory/brain-retrieval.js');
152
+
153
+ try {
154
+ const durationNote = payload.durationMs != null ? ` (${payload.durationMs}ms)` : '';
155
+ await observeBrain(projectRoot, {
156
+ text: `Dispatch complete: ${payload.gateway}:${payload.domain}.${payload.operation}${durationNote}`,
157
+ title: `Work done: ${payload.domain}.${payload.operation}`,
158
+ type: 'change',
159
+ sourceType: 'agent',
160
+ });
161
+ } catch (err) {
162
+ if (!isMissingBrainSchemaError(err)) throw err;
163
+ }
164
+ }
165
+
166
+ // ---------------------------------------------------------------------------
167
+ // Auto-registration
168
+ // ---------------------------------------------------------------------------
169
+
170
+ // Register at lower priority (90) than lifecycle hooks (100) so lifecycle
171
+ // handlers always run first.
172
+ hooks.register({
173
+ id: 'work-capture-prompt-submit',
174
+ event: 'onPromptSubmit',
175
+ handler: handleWorkPromptSubmit,
176
+ priority: 90,
177
+ });
178
+
179
+ hooks.register({
180
+ id: 'work-capture-response-complete',
181
+ event: 'onResponseComplete',
182
+ handler: handleWorkResponseComplete,
183
+ priority: 90,
184
+ });
package/src/index.ts CHANGED
@@ -268,10 +268,15 @@ export type {
268
268
  export { Cleo } from './cleo.js';
269
269
  // Hooks
270
270
  export { HookRegistry, hooks } from './hooks/registry.js';
271
+ export type {
272
+ PopulateEmbeddingsOptions,
273
+ PopulateEmbeddingsResult,
274
+ } from './memory/brain-retrieval.js';
271
275
  // Memory
272
276
  export {
273
277
  fetchBrainEntries,
274
278
  observeBrain,
279
+ populateEmbeddings,
275
280
  searchBrainCompact,
276
281
  timelineBrain,
277
282
  } from './memory/brain-retrieval.js';
package/src/internal.ts CHANGED
@@ -135,6 +135,23 @@ export { instantiateTessera, showTessera } from './lifecycle/tessera-engine.js';
135
135
 
136
136
  // MCP helpers
137
137
  export { detectEnvMode, generateMcpServerEntry, getMcpServerName } from './mcp/index.js';
138
+ // Memory — brain lifecycle (temporal decay + consolidation)
139
+ export type { ConsolidationResult, DecayResult } from './memory/brain-lifecycle.js';
140
+ export { applyTemporalDecay, consolidateMemories } from './memory/brain-lifecycle.js';
141
+ // Memory — brain maintenance
142
+ export type {
143
+ BrainMaintenanceConsolidationResult,
144
+ BrainMaintenanceDecayResult,
145
+ BrainMaintenanceEmbeddingsResult,
146
+ BrainMaintenanceOptions,
147
+ BrainMaintenanceResult,
148
+ } from './memory/brain-maintenance.js';
149
+ export { runBrainMaintenance } from './memory/brain-maintenance.js';
150
+ export type {
151
+ PopulateEmbeddingsOptions,
152
+ PopulateEmbeddingsResult,
153
+ } from './memory/brain-retrieval.js';
154
+ export { populateEmbeddings } from './memory/brain-retrieval.js';
138
155
  export { migrateClaudeMem } from './memory/claude-mem-migration.js';
139
156
  // Memory — engine-compat
140
157
  export {
@@ -686,6 +703,10 @@ export type { BuildConfig } from './config/build-config.js';
686
703
  export { BUILD_CONFIG } from './config/build-config.js';
687
704
  // Init (additional)
688
705
  export { initCoreSkills } from './init.js';
706
+ // Memory — auto-extract (additional)
707
+ export { extractFromTranscript } from './memory/auto-extract.js';
708
+ // Memory — brain embedding (additional)
709
+ export { initDefaultProvider } from './memory/brain-embedding.js';
689
710
  // Memory — brain row types
690
711
  export type {
691
712
  BrainAnchor,
@@ -699,9 +720,14 @@ export type {
699
720
  BrainTimelineNeighborRow,
700
721
  } from './memory/brain-row-types.js';
701
722
  // Memory (additional)
702
- export { writeMemoryBridge } from './memory/memory-bridge.js';
723
+ export { generateContextAwareContent, writeMemoryBridge } from './memory/memory-bridge.js';
703
724
  export type { SessionMemoryContext } from './memory/session-memory.js';
704
- export { getSessionMemoryContext, persistSessionMemory } from './memory/session-memory.js';
725
+ export {
726
+ buildSummarizationPrompt,
727
+ getSessionMemoryContext,
728
+ ingestStructuredSummary,
729
+ persistSessionMemory,
730
+ } from './memory/session-memory.js';
705
731
  // Nexus — discoverRelated (exported as nexusDiscoverRelated to avoid name clash with tasks discoverRelated)
706
732
  // Nexus — searchAcrossProjects
707
733
  export {