@cleocode/core 2026.3.69 → 2026.3.70
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/dist/agents/retry.d.ts.map +1 -1
- package/dist/agents/retry.js +23 -42
- package/dist/agents/retry.js.map +1 -1
- package/dist/cleo.js +2 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +30 -0
- package/dist/config.js.map +1 -1
- package/dist/hooks/handlers/file-hooks.d.ts +5 -2
- package/dist/hooks/handlers/file-hooks.d.ts.map +1 -1
- package/dist/hooks/handlers/index.d.ts +2 -0
- package/dist/hooks/handlers/index.d.ts.map +1 -1
- package/dist/hooks/handlers/mcp-hooks.d.ts +11 -7
- package/dist/hooks/handlers/mcp-hooks.d.ts.map +1 -1
- package/dist/hooks/handlers/memory-bridge-refresh.d.ts +20 -0
- package/dist/hooks/handlers/memory-bridge-refresh.d.ts.map +1 -0
- package/dist/hooks/handlers/memory-bridge-refresh.js +42 -0
- package/dist/hooks/handlers/memory-bridge-refresh.js.map +1 -0
- package/dist/hooks/handlers/session-hooks.d.ts +10 -0
- package/dist/hooks/handlers/session-hooks.d.ts.map +1 -1
- package/dist/hooks/handlers/session-hooks.js +36 -0
- package/dist/hooks/handlers/session-hooks.js.map +1 -1
- package/dist/hooks/handlers/task-hooks.d.ts +4 -0
- package/dist/hooks/handlers/task-hooks.d.ts.map +1 -1
- package/dist/hooks/handlers/task-hooks.js +7 -0
- package/dist/hooks/handlers/task-hooks.js.map +1 -1
- package/dist/hooks/handlers/work-capture-hooks.d.ts +40 -0
- package/dist/hooks/handlers/work-capture-hooks.d.ts.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5016 -4662
- package/dist/index.js.map +4 -4
- package/dist/internal.d.ts +10 -2
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +10 -3
- package/dist/internal.js.map +1 -1
- package/dist/memory/auto-extract.d.ts +13 -0
- package/dist/memory/auto-extract.d.ts.map +1 -1
- package/dist/memory/auto-extract.js +34 -0
- package/dist/memory/auto-extract.js.map +1 -1
- package/dist/memory/brain-embedding.d.ts +13 -0
- package/dist/memory/brain-embedding.d.ts.map +1 -1
- package/dist/memory/brain-embedding.js +17 -0
- package/dist/memory/brain-embedding.js.map +1 -1
- package/dist/memory/brain-maintenance.d.ts +110 -0
- package/dist/memory/brain-maintenance.d.ts.map +1 -0
- package/dist/memory/brain-maintenance.js +98 -0
- package/dist/memory/brain-maintenance.js.map +1 -0
- package/dist/memory/brain-retrieval.d.ts +31 -5
- package/dist/memory/brain-retrieval.d.ts.map +1 -1
- package/dist/memory/brain-retrieval.js +53 -6
- package/dist/memory/brain-retrieval.js.map +1 -1
- package/dist/memory/embedding-local.d.ts +55 -0
- package/dist/memory/embedding-local.d.ts.map +1 -0
- package/dist/memory/embedding-local.js +97 -0
- package/dist/memory/embedding-local.js.map +1 -0
- package/dist/memory/embedding-queue.d.ts +90 -0
- package/dist/memory/embedding-queue.d.ts.map +1 -0
- package/dist/memory/embedding-queue.js +271 -0
- package/dist/memory/embedding-queue.js.map +1 -0
- package/dist/memory/embedding-worker.d.ts +19 -0
- package/dist/memory/embedding-worker.d.ts.map +1 -0
- package/dist/memory/embedding-worker.js +58 -0
- package/dist/memory/embedding-worker.js.map +1 -0
- package/dist/memory/memory-bridge.d.ts +21 -1
- package/dist/memory/memory-bridge.d.ts.map +1 -1
- package/dist/memory/memory-bridge.js +83 -2
- package/dist/memory/memory-bridge.js.map +1 -1
- package/dist/memory/session-memory.d.ts +26 -0
- package/dist/memory/session-memory.d.ts.map +1 -1
- package/dist/memory/session-memory.js +105 -0
- package/dist/memory/session-memory.js.map +1 -1
- package/dist/pagination.js +3 -0
- package/dist/pagination.js.map +1 -1
- package/dist/sessions/index.d.ts.map +1 -1
- package/dist/sessions/index.js +2 -6
- package/dist/sessions/index.js.map +1 -1
- package/dist/store/brain-sqlite.js +13 -62
- package/dist/store/brain-sqlite.js.map +1 -1
- package/dist/store/migration-manager.js +151 -0
- package/dist/store/migration-manager.js.map +1 -0
- package/dist/store/sqlite.d.ts.map +1 -1
- package/dist/store/sqlite.js +16 -134
- package/dist/store/sqlite.js.map +1 -1
- package/dist/tasks/add.js +27 -22
- package/dist/tasks/add.js.map +1 -1
- package/dist/tasks/complete.d.ts.map +1 -1
- package/dist/tasks/complete.js +13 -40
- package/dist/tasks/complete.js.map +1 -1
- package/dist/tasks/enforcement.js +12 -15
- package/dist/tasks/enforcement.js.map +1 -1
- package/dist/upgrade.js +246 -3
- package/dist/upgrade.js.map +1 -1
- package/migrations/drizzle-tasks/20260320013731_wave0-schema-hardening/migration.sql +17 -17
- package/package.json +6 -5
- package/src/agents/retry.ts +30 -24
- package/src/config.ts +18 -0
- package/src/hooks/handlers/file-hooks.ts +29 -3
- package/src/hooks/handlers/index.ts +2 -0
- package/src/hooks/handlers/mcp-hooks.ts +32 -13
- package/src/hooks/handlers/memory-bridge-refresh.ts +47 -0
- package/src/hooks/handlers/session-hooks.ts +38 -0
- package/src/hooks/handlers/task-hooks.ts +8 -0
- package/src/hooks/handlers/work-capture-hooks.ts +184 -0
- package/src/index.ts +5 -0
- package/src/internal.ts +28 -2
- package/src/memory/__tests__/brain-automation.test.ts +941 -0
- package/src/memory/auto-extract.ts +40 -0
- package/src/memory/brain-embedding.ts +18 -0
- package/src/memory/brain-maintenance.ts +183 -0
- package/src/memory/brain-retrieval.ts +85 -7
- package/src/memory/embedding-local.ts +107 -0
- package/src/memory/embedding-queue.ts +304 -0
- package/src/memory/embedding-worker.ts +79 -0
- package/src/memory/memory-bridge.ts +101 -2
- package/src/memory/session-memory.ts +123 -0
- package/src/sessions/index.ts +2 -6
- package/src/store/__tests__/test-db-helper.js +14 -2
- package/src/store/__tests__/test-db-helper.ts +4 -1
- package/src/store/sqlite.ts +28 -0
- package/src/tasks/__tests__/complete-unblocks.test.ts +4 -1
- package/src/tasks/__tests__/complete.test.ts +18 -6
- package/src/tasks/__tests__/epic-enforcement.test.ts +4 -1
- package/src/tasks/__tests__/update.test.ts +4 -1
- package/src/tasks/complete.ts +8 -8
- package/templates/config.template.json +19 -0
- package/templates/global-config.template.json +19 -0
package/src/store/sqlite.ts
CHANGED
|
@@ -405,6 +405,27 @@ import type { RequiredColumn } from './migration-manager.js';
|
|
|
405
405
|
|
|
406
406
|
const REQUIRED_TASK_COLUMNS: RequiredColumn[] = [{ name: 'pipeline_stage', ddl: 'text' }];
|
|
407
407
|
|
|
408
|
+
/**
|
|
409
|
+
* Required columns that MUST exist on the sessions table before the
|
|
410
|
+
* wave0-schema-hardening migration runs.
|
|
411
|
+
*
|
|
412
|
+
* The wave0 migration rebuilds the sessions table via:
|
|
413
|
+
* INSERT INTO __new_sessions(..., provider_id, stats_json, resume_count, grade_mode)
|
|
414
|
+
* SELECT ..., provider_id, stats_json, resume_count, grade_mode FROM sessions
|
|
415
|
+
*
|
|
416
|
+
* If an existing sessions table (created before these columns were added) is
|
|
417
|
+
* missing any of them, the SELECT fails with "no such column". ensureColumns()
|
|
418
|
+
* adds them as NULL-able columns before the migration runs, making the SELECT safe.
|
|
419
|
+
*
|
|
420
|
+
* @see https://github.com/anthropics/cleo/issues/83
|
|
421
|
+
*/
|
|
422
|
+
const REQUIRED_SESSION_COLUMNS: RequiredColumn[] = [
|
|
423
|
+
{ name: 'provider_id', ddl: 'text' },
|
|
424
|
+
{ name: 'stats_json', ddl: 'text' },
|
|
425
|
+
{ name: 'resume_count', ddl: 'integer' },
|
|
426
|
+
{ name: 'grade_mode', ddl: 'integer' },
|
|
427
|
+
];
|
|
428
|
+
|
|
408
429
|
/**
|
|
409
430
|
* Run drizzle migrations to create/update tables.
|
|
410
431
|
*
|
|
@@ -426,6 +447,13 @@ function runMigrations(nativeDb: DatabaseSync, db: NodeSQLiteDatabase<typeof sch
|
|
|
426
447
|
// Bootstrap baseline + reconcile stale journal entries
|
|
427
448
|
reconcileJournal(nativeDb, migrationsFolder, 'tasks', 'sqlite');
|
|
428
449
|
|
|
450
|
+
// Pre-migration column safety: ensure sessions table has the columns that the
|
|
451
|
+
// wave0-schema-hardening migration SELECTs during its table rebuild. Without
|
|
452
|
+
// this, upgrading from a pre-wave0 DB fails with "no such column: provider_id".
|
|
453
|
+
// Must run BEFORE migrateWithRetry so the migration's INSERT...SELECT succeeds.
|
|
454
|
+
// @see https://github.com/anthropics/cleo/issues/83
|
|
455
|
+
ensureColumns(nativeDb, 'sessions', REQUIRED_SESSION_COLUMNS, 'sqlite');
|
|
456
|
+
|
|
429
457
|
// Run pending migrations with SQLITE_BUSY retry
|
|
430
458
|
migrateWithRetry(db, migrationsFolder);
|
|
431
459
|
|
|
@@ -23,7 +23,10 @@ describe('completeTask unblocked tasks', () => {
|
|
|
23
23
|
await writeFile(
|
|
24
24
|
join(env.cleoDir, 'config.json'),
|
|
25
25
|
JSON.stringify({
|
|
26
|
-
enforcement: {
|
|
26
|
+
enforcement: {
|
|
27
|
+
session: { requiredForMutate: false },
|
|
28
|
+
acceptance: { mode: 'off' },
|
|
29
|
+
},
|
|
27
30
|
lifecycle: { mode: 'off' },
|
|
28
31
|
verification: { enabled: false },
|
|
29
32
|
}),
|
|
@@ -22,7 +22,10 @@ describe('completeTask', () => {
|
|
|
22
22
|
// Pin CLEO_DIR so concurrent workers cannot contaminate path resolution
|
|
23
23
|
process.env['CLEO_DIR'] = env.cleoDir;
|
|
24
24
|
await writeConfig({
|
|
25
|
-
enforcement: {
|
|
25
|
+
enforcement: {
|
|
26
|
+
session: { requiredForMutate: false },
|
|
27
|
+
acceptance: { mode: 'off' },
|
|
28
|
+
},
|
|
26
29
|
lifecycle: { mode: 'off' },
|
|
27
30
|
verification: { enabled: false },
|
|
28
31
|
});
|
|
@@ -162,7 +165,10 @@ describe('completeTask', () => {
|
|
|
162
165
|
type: 'task',
|
|
163
166
|
},
|
|
164
167
|
]);
|
|
165
|
-
await writeConfig({
|
|
168
|
+
await writeConfig({
|
|
169
|
+
enforcement: { acceptance: { mode: 'off' } },
|
|
170
|
+
verification: { enabled: true },
|
|
171
|
+
});
|
|
166
172
|
|
|
167
173
|
await expect(completeTask({ taskId: 'T001' }, env.tempDir, accessor)).rejects.toThrow(
|
|
168
174
|
'missing verification metadata',
|
|
@@ -180,9 +186,11 @@ describe('completeTask', () => {
|
|
|
180
186
|
type: 'task',
|
|
181
187
|
},
|
|
182
188
|
]);
|
|
183
|
-
//
|
|
184
|
-
|
|
185
|
-
await
|
|
189
|
+
// Write a config that only disables acceptance enforcement but no verification
|
|
190
|
+
// settings — verifying that verification defaults to disabled (opt-in behavior).
|
|
191
|
+
await writeConfig({
|
|
192
|
+
enforcement: { acceptance: { mode: 'off' } },
|
|
193
|
+
});
|
|
186
194
|
|
|
187
195
|
const result = await completeTask({ taskId: 'T001' }, env.tempDir, accessor);
|
|
188
196
|
expect(result.task.status).toBe('done');
|
|
@@ -199,7 +207,10 @@ describe('completeTask', () => {
|
|
|
199
207
|
type: 'task',
|
|
200
208
|
},
|
|
201
209
|
]);
|
|
202
|
-
await writeConfig({
|
|
210
|
+
await writeConfig({
|
|
211
|
+
enforcement: { acceptance: { mode: 'off' } },
|
|
212
|
+
verification: { enabled: false },
|
|
213
|
+
});
|
|
203
214
|
|
|
204
215
|
const result = await completeTask({ taskId: 'T001' }, env.tempDir, accessor);
|
|
205
216
|
expect(result.task.status).toBe('done');
|
|
@@ -228,6 +239,7 @@ describe('completeTask', () => {
|
|
|
228
239
|
},
|
|
229
240
|
]);
|
|
230
241
|
await writeConfig({
|
|
242
|
+
enforcement: { acceptance: { mode: 'off' } },
|
|
231
243
|
verification: {
|
|
232
244
|
enabled: true,
|
|
233
245
|
requiredGates: ['implemented', 'testsPassed'],
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* @epic T056
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import { writeFile } from 'node:fs/promises';
|
|
15
|
+
import { unlink, writeFile } from 'node:fs/promises';
|
|
16
16
|
import { join } from 'node:path';
|
|
17
17
|
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from 'vitest';
|
|
18
18
|
import { createTestDb, type TestDbEnv } from '../../store/__tests__/test-db-helper.js';
|
|
@@ -80,6 +80,9 @@ describe('getLifecycleMode', () => {
|
|
|
80
80
|
});
|
|
81
81
|
|
|
82
82
|
it('returns strict by default when no config', async () => {
|
|
83
|
+
// Remove the config.json written by createTestDb() so getLifecycleMode
|
|
84
|
+
// sees no project config and falls back to the 'strict' default.
|
|
85
|
+
await unlink(join(env.cleoDir, 'config.json'));
|
|
83
86
|
const mode = await getLifecycleMode(env.tempDir);
|
|
84
87
|
expect(mode).toBe('strict');
|
|
85
88
|
});
|
|
@@ -24,7 +24,10 @@ describe('updateTask', () => {
|
|
|
24
24
|
await writeFile(
|
|
25
25
|
join(env.cleoDir, 'config.json'),
|
|
26
26
|
JSON.stringify({
|
|
27
|
-
enforcement: {
|
|
27
|
+
enforcement: {
|
|
28
|
+
session: { requiredForMutate: false },
|
|
29
|
+
acceptance: { mode: 'off' },
|
|
30
|
+
},
|
|
28
31
|
lifecycle: { mode: 'off' },
|
|
29
32
|
verification: { enabled: false },
|
|
30
33
|
}),
|
package/src/tasks/complete.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import type { Task, TaskRef, VerificationGate } from '@cleocode/contracts';
|
|
8
8
|
// safeAppendLog replaced by tx.appendLog inside transaction (T023)
|
|
9
9
|
import { ExitCode } from '@cleocode/contracts';
|
|
10
|
-
import { loadConfig } from '../config.js';
|
|
10
|
+
import { getRawConfigValue, loadConfig } from '../config.js';
|
|
11
11
|
import { CleoError } from '../errors.js';
|
|
12
12
|
import { requireActiveSession } from '../sessions/session-enforcement.js';
|
|
13
13
|
import type { DataAccessor } from '../store/data-accessor.js';
|
|
@@ -69,7 +69,11 @@ async function loadCompletionEnforcement(cwd?: string): Promise<CompletionEnforc
|
|
|
69
69
|
const acceptanceMode = acceptance?.mode ?? (isTest ? 'off' : 'block');
|
|
70
70
|
const acceptanceRequiredForPriorities =
|
|
71
71
|
acceptance?.requiredForPriorities ?? (isTest ? [] : ['critical', 'high', 'medium', 'low']);
|
|
72
|
-
|
|
72
|
+
// Use getRawConfigValue to read only the project-level config (no DEFAULTS cascade).
|
|
73
|
+
// This ensures the isTest fallback activates when verification.enabled is not explicitly set.
|
|
74
|
+
const rawVerificationEnabled = await getRawConfigValue('verification.enabled', cwd);
|
|
75
|
+
const verificationEnabled =
|
|
76
|
+
rawVerificationEnabled !== undefined ? (rawVerificationEnabled as boolean) : !isTest;
|
|
73
77
|
const verificationRequiredGates =
|
|
74
78
|
(verificationCfg?.requiredGates ?? []).filter(isVerificationGate).length > 0
|
|
75
79
|
? (verificationCfg?.requiredGates ?? []).filter(isVerificationGate)
|
|
@@ -278,12 +282,8 @@ export async function completeTask(
|
|
|
278
282
|
}
|
|
279
283
|
}
|
|
280
284
|
|
|
281
|
-
//
|
|
282
|
-
|
|
283
|
-
.then(({ refreshMemoryBridge }) => refreshMemoryBridge(cwd ?? process.cwd()))
|
|
284
|
-
.catch(() => {
|
|
285
|
-
/* Memory bridge refresh is best-effort */
|
|
286
|
-
});
|
|
285
|
+
// NOTE: Memory bridge refresh is now handled by the onToolComplete hook
|
|
286
|
+
// via memory-bridge-refresh.ts (T138). No direct call needed here.
|
|
287
287
|
|
|
288
288
|
// Auto-extract memory from task completion (best-effort, T-audit)
|
|
289
289
|
import('../memory/auto-extract.js')
|
|
@@ -106,5 +106,24 @@
|
|
|
106
106
|
|
|
107
107
|
"retention": {
|
|
108
108
|
"autoEndActiveAfterDays": 7
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
"brain": {
|
|
112
|
+
"autoCapture": true,
|
|
113
|
+
"captureFiles": false,
|
|
114
|
+
"captureMcp": false,
|
|
115
|
+
"captureWork": false,
|
|
116
|
+
"embedding": {
|
|
117
|
+
"enabled": true,
|
|
118
|
+
"provider": "local"
|
|
119
|
+
},
|
|
120
|
+
"memoryBridge": {
|
|
121
|
+
"autoRefresh": true,
|
|
122
|
+
"contextAware": true,
|
|
123
|
+
"maxTokens": 2000
|
|
124
|
+
},
|
|
125
|
+
"summarization": {
|
|
126
|
+
"enabled": true
|
|
127
|
+
}
|
|
109
128
|
}
|
|
110
129
|
}
|
|
@@ -36,5 +36,24 @@
|
|
|
36
36
|
},
|
|
37
37
|
"defaults": {
|
|
38
38
|
"priority": "medium"
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
"brain": {
|
|
42
|
+
"autoCapture": true,
|
|
43
|
+
"captureFiles": false,
|
|
44
|
+
"captureMcp": false,
|
|
45
|
+
"captureWork": false,
|
|
46
|
+
"embedding": {
|
|
47
|
+
"enabled": true,
|
|
48
|
+
"provider": "local"
|
|
49
|
+
},
|
|
50
|
+
"memoryBridge": {
|
|
51
|
+
"autoRefresh": true,
|
|
52
|
+
"contextAware": true,
|
|
53
|
+
"maxTokens": 2000
|
|
54
|
+
},
|
|
55
|
+
"summarization": {
|
|
56
|
+
"enabled": true
|
|
57
|
+
}
|
|
39
58
|
}
|
|
40
59
|
}
|