@cleocode/core 2026.3.57 → 2026.3.59
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/agent-registry.d.ts +206 -0
- package/dist/agents/agent-registry.d.ts.map +1 -0
- package/dist/agents/agent-schema.d.ts.map +1 -1
- package/dist/agents/execution-learning.d.ts +223 -0
- package/dist/agents/execution-learning.d.ts.map +1 -0
- package/dist/agents/health-monitor.d.ts +161 -0
- package/dist/agents/health-monitor.d.ts.map +1 -0
- package/dist/agents/index.d.ts +4 -1
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/retry.d.ts +57 -4
- package/dist/agents/retry.d.ts.map +1 -1
- package/dist/backfill/index.d.ts +83 -0
- package/dist/backfill/index.d.ts.map +1 -0
- package/dist/bootstrap.d.ts +1 -1
- package/dist/config.d.ts +47 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6985 -5068
- package/dist/index.js.map +4 -4
- package/dist/intelligence/adaptive-validation.d.ts +151 -0
- package/dist/intelligence/adaptive-validation.d.ts.map +1 -0
- package/dist/intelligence/impact.d.ts +34 -1
- package/dist/intelligence/impact.d.ts.map +1 -1
- package/dist/intelligence/index.d.ts +7 -2
- package/dist/intelligence/index.d.ts.map +1 -1
- package/dist/intelligence/types.d.ts +60 -0
- package/dist/intelligence/types.d.ts.map +1 -1
- package/dist/internal.d.ts +8 -4
- package/dist/internal.d.ts.map +1 -1
- package/dist/lib/index.d.ts +10 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/retry.d.ts +128 -0
- package/dist/lib/retry.d.ts.map +1 -0
- package/dist/nexus/sharing/index.d.ts +48 -2
- package/dist/nexus/sharing/index.d.ts.map +1 -1
- package/dist/sessions/session-enforcement.d.ts.map +1 -1
- package/dist/stats/index.d.ts +1 -0
- package/dist/stats/index.d.ts.map +1 -1
- package/dist/stats/workflow-telemetry.d.ts +89 -0
- package/dist/stats/workflow-telemetry.d.ts.map +1 -0
- package/dist/store/brain-schema.d.ts.map +1 -1
- package/dist/store/converters.d.ts.map +1 -1
- package/dist/store/cross-db-cleanup.d.ts +93 -0
- package/dist/store/cross-db-cleanup.d.ts.map +1 -0
- package/dist/store/db-helpers.d.ts.map +1 -1
- package/dist/store/migration-sqlite.d.ts.map +1 -1
- package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
- package/dist/store/sqlite.d.ts.map +1 -1
- package/dist/store/task-store.d.ts.map +1 -1
- package/dist/store/tasks-schema.d.ts +18 -3
- package/dist/store/tasks-schema.d.ts.map +1 -1
- package/dist/store/validation-schemas.d.ts +32 -0
- package/dist/store/validation-schemas.d.ts.map +1 -1
- package/dist/tasks/add.d.ts +10 -1
- package/dist/tasks/add.d.ts.map +1 -1
- package/dist/tasks/complete.d.ts.map +1 -1
- package/dist/tasks/enforcement.d.ts +22 -0
- package/dist/tasks/enforcement.d.ts.map +1 -0
- package/dist/tasks/epic-enforcement.d.ts +199 -0
- package/dist/tasks/epic-enforcement.d.ts.map +1 -0
- package/dist/tasks/index.d.ts +1 -1
- package/dist/tasks/index.d.ts.map +1 -1
- package/dist/tasks/pipeline-stage.d.ts +181 -0
- package/dist/tasks/pipeline-stage.d.ts.map +1 -0
- package/dist/tasks/update.d.ts +2 -0
- package/dist/tasks/update.d.ts.map +1 -1
- package/migrations/drizzle-brain/20260321000001_t033-brain-indexes/migration.sql +12 -0
- package/migrations/drizzle-brain/20260321000001_t033-brain-indexes/snapshot.json +1232 -0
- package/migrations/drizzle-tasks/20260321000000_t033-connection-health/migration.sql +518 -0
- package/migrations/drizzle-tasks/20260321000000_t033-connection-health/snapshot.json +4312 -0
- package/migrations/drizzle-tasks/20260321000002_t060-pipeline-stage-binding/migration.sql +82 -0
- package/migrations/drizzle-tasks/20260321000002_t060-pipeline-stage-binding/snapshot.json +9 -0
- package/package.json +5 -5
- package/schemas/config.schema.json +37 -1547
- package/src/__tests__/sharing.test.ts +24 -0
- package/src/agents/__tests__/agent-registry.test.ts +351 -0
- package/src/agents/__tests__/execution-learning.test.ts +684 -0
- package/src/agents/__tests__/health-monitor.test.ts +332 -0
- package/src/agents/__tests__/registry.test.ts +30 -2
- package/src/agents/agent-registry.ts +394 -0
- package/src/agents/agent-schema.ts +5 -0
- package/src/agents/execution-learning.ts +675 -0
- package/src/agents/health-monitor.ts +279 -0
- package/src/agents/index.ts +37 -1
- package/src/agents/retry.ts +57 -4
- package/src/backfill/index.ts +309 -0
- package/src/bootstrap.ts +1 -1
- package/src/config.ts +126 -0
- package/src/index.ts +8 -1
- package/src/intelligence/__tests__/adaptive-validation.test.ts +694 -0
- package/src/intelligence/__tests__/impact.test.ts +165 -1
- package/src/intelligence/adaptive-validation.ts +764 -0
- package/src/intelligence/impact.ts +203 -0
- package/src/intelligence/index.ts +19 -0
- package/src/intelligence/types.ts +76 -0
- package/src/internal.ts +39 -0
- package/src/lib/__tests__/retry.test.ts +321 -0
- package/src/lib/index.ts +16 -0
- package/src/lib/retry.ts +224 -0
- package/src/lifecycle/__tests__/chain-store.test.ts +7 -0
- package/src/lifecycle/__tests__/tessera-engine.test.ts +52 -0
- package/src/nexus/sharing/index.ts +142 -2
- package/src/sessions/__tests__/session-edge-cases.test.ts +24 -1
- package/src/sessions/session-enforcement.ts +13 -2
- package/src/stats/index.ts +7 -0
- package/src/stats/workflow-telemetry.ts +502 -0
- package/src/store/__tests__/migration-safety.test.ts +3 -0
- package/src/store/__tests__/session-store.test.ts +132 -1
- package/src/store/__tests__/task-store.test.ts +22 -1
- package/src/store/__tests__/test-db-helper.ts +29 -2
- package/src/store/brain-schema.ts +4 -1
- package/src/store/converters.ts +2 -0
- package/src/store/cross-db-cleanup.ts +192 -0
- package/src/store/db-helpers.ts +2 -0
- package/src/store/migration-sqlite.ts +6 -0
- package/src/store/sqlite-data-accessor.ts +20 -28
- package/src/store/sqlite.ts +14 -2
- package/src/store/task-store.ts +6 -0
- package/src/store/tasks-schema.ts +59 -20
- package/src/tasks/__tests__/add.test.ts +16 -0
- package/src/tasks/__tests__/complete-unblocks.test.ts +10 -1
- package/src/tasks/__tests__/complete.test.ts +11 -2
- package/src/tasks/__tests__/epic-enforcement.test.ts +909 -0
- package/src/tasks/__tests__/minimal-test.test.ts +28 -0
- package/src/tasks/__tests__/pipeline-stage.test.ts +403 -0
- package/src/tasks/__tests__/update.test.ts +40 -6
- package/src/tasks/add.ts +128 -2
- package/src/tasks/complete.ts +29 -17
- package/src/tasks/enforcement.ts +127 -0
- package/src/tasks/epic-enforcement.ts +364 -0
- package/src/tasks/index.ts +1 -0
- package/src/tasks/pipeline-stage.ts +293 -0
- package/src/tasks/update.ts +62 -0
- package/templates/config.template.json +34 -111
- package/templates/global-config.template.json +24 -40
|
@@ -8,13 +8,19 @@
|
|
|
8
8
|
* - Blast radius calculation
|
|
9
9
|
* - Critical path detection
|
|
10
10
|
* - Edge cases (orphan tasks, circular refs, no deps)
|
|
11
|
+
* - predictImpact: free-text change description matching (T043)
|
|
11
12
|
*
|
|
12
13
|
* @module intelligence
|
|
13
14
|
*/
|
|
14
15
|
|
|
15
16
|
import type { DataAccessor, Task } from '@cleocode/contracts';
|
|
16
17
|
import { describe, expect, it } from 'vitest';
|
|
17
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
analyzeChangeImpact,
|
|
20
|
+
analyzeTaskImpact,
|
|
21
|
+
calculateBlastRadius,
|
|
22
|
+
predictImpact,
|
|
23
|
+
} from '../impact.js';
|
|
18
24
|
|
|
19
25
|
// ============================================================================
|
|
20
26
|
// Test Helpers
|
|
@@ -451,3 +457,161 @@ describe('calculateBlastRadius', () => {
|
|
|
451
457
|
expect(result.transitiveCount).toBe(2);
|
|
452
458
|
});
|
|
453
459
|
});
|
|
460
|
+
|
|
461
|
+
// ============================================================================
|
|
462
|
+
// predictImpact (T043)
|
|
463
|
+
// ============================================================================
|
|
464
|
+
|
|
465
|
+
describe('predictImpact', () => {
|
|
466
|
+
it('returns empty report when no tasks match the change description', async () => {
|
|
467
|
+
const tasks = [
|
|
468
|
+
makeTask({ id: 'T001', title: 'Set up CI pipeline', description: 'Configure CI runner' }),
|
|
469
|
+
makeTask({ id: 'T002', title: 'Write unit tests', description: 'Add test coverage' }),
|
|
470
|
+
];
|
|
471
|
+
const acc = mockAccessor(tasks);
|
|
472
|
+
|
|
473
|
+
const result = await predictImpact('authentication login oauth', undefined, acc);
|
|
474
|
+
|
|
475
|
+
expect(result.change).toBe('authentication login oauth');
|
|
476
|
+
expect(result.matchedTasks).toHaveLength(0);
|
|
477
|
+
expect(result.affectedTasks).toHaveLength(0);
|
|
478
|
+
expect(result.totalAffected).toBe(0);
|
|
479
|
+
expect(result.summary).toContain('No tasks matched');
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
it('returns direct match when task title contains change keywords', async () => {
|
|
483
|
+
const tasks = [
|
|
484
|
+
makeTask({
|
|
485
|
+
id: 'T001',
|
|
486
|
+
title: 'Implement authentication module',
|
|
487
|
+
description: 'Add JWT auth',
|
|
488
|
+
}),
|
|
489
|
+
makeTask({ id: 'T002', title: 'Set up database schema', description: 'Create tables' }),
|
|
490
|
+
];
|
|
491
|
+
const acc = mockAccessor(tasks);
|
|
492
|
+
|
|
493
|
+
const result = await predictImpact('authentication module', undefined, acc);
|
|
494
|
+
|
|
495
|
+
expect(result.matchedTasks).toHaveLength(1);
|
|
496
|
+
expect(result.matchedTasks[0]?.id).toBe('T001');
|
|
497
|
+
expect(result.matchedTasks[0]?.exposure).toBe('direct');
|
|
498
|
+
expect(result.totalAffected).toBe(1);
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
it('traces downstream dependents from matched seed tasks', async () => {
|
|
502
|
+
const tasks = [
|
|
503
|
+
makeTask({ id: 'T001', title: 'authentication service implementation', description: '' }),
|
|
504
|
+
makeTask({
|
|
505
|
+
id: 'T002',
|
|
506
|
+
title: 'User login form',
|
|
507
|
+
description: 'Depends on auth service',
|
|
508
|
+
depends: ['T001'],
|
|
509
|
+
}),
|
|
510
|
+
makeTask({
|
|
511
|
+
id: 'T003',
|
|
512
|
+
title: 'Dashboard access control',
|
|
513
|
+
description: 'Requires user login',
|
|
514
|
+
depends: ['T002'],
|
|
515
|
+
}),
|
|
516
|
+
makeTask({
|
|
517
|
+
id: 'T004',
|
|
518
|
+
title: 'Unrelated database migration',
|
|
519
|
+
description: 'Schema changes',
|
|
520
|
+
}),
|
|
521
|
+
];
|
|
522
|
+
const acc = mockAccessor(tasks);
|
|
523
|
+
|
|
524
|
+
const result = await predictImpact('authentication service', undefined, acc);
|
|
525
|
+
|
|
526
|
+
// T001 is the direct match (seed)
|
|
527
|
+
expect(result.matchedTasks.map((t) => t.id)).toContain('T001');
|
|
528
|
+
|
|
529
|
+
// T002 and T003 should be in affectedTasks as dependents/transitive
|
|
530
|
+
const ids = result.affectedTasks.map((t) => t.id);
|
|
531
|
+
expect(ids).toContain('T001');
|
|
532
|
+
expect(ids).toContain('T002');
|
|
533
|
+
expect(ids).toContain('T003');
|
|
534
|
+
// T004 is unrelated and should not appear
|
|
535
|
+
expect(ids).not.toContain('T004');
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
it('classifies exposure correctly: direct, dependent, transitive', async () => {
|
|
539
|
+
const tasks = [
|
|
540
|
+
makeTask({ id: 'T001', title: 'auth login service', description: '' }),
|
|
541
|
+
makeTask({ id: 'T002', title: 'Session management', description: '', depends: ['T001'] }),
|
|
542
|
+
makeTask({ id: 'T003', title: 'Profile page', description: '', depends: ['T002'] }),
|
|
543
|
+
];
|
|
544
|
+
const acc = mockAccessor(tasks);
|
|
545
|
+
|
|
546
|
+
const result = await predictImpact('auth login', undefined, acc);
|
|
547
|
+
|
|
548
|
+
const t1 = result.affectedTasks.find((t) => t.id === 'T001');
|
|
549
|
+
const t2 = result.affectedTasks.find((t) => t.id === 'T002');
|
|
550
|
+
const t3 = result.affectedTasks.find((t) => t.id === 'T003');
|
|
551
|
+
|
|
552
|
+
expect(t1?.exposure).toBe('direct');
|
|
553
|
+
expect(t2?.exposure).toBe('dependent');
|
|
554
|
+
expect(t3?.exposure).toBe('transitive');
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
it('sorts affectedTasks: direct first, then dependent, then transitive', async () => {
|
|
558
|
+
const tasks = [
|
|
559
|
+
makeTask({ id: 'T001', title: 'auth service core', description: '' }),
|
|
560
|
+
makeTask({ id: 'T002', title: 'Login controller', description: '', depends: ['T001'] }),
|
|
561
|
+
makeTask({ id: 'T003', title: 'Session store', description: '', depends: ['T002'] }),
|
|
562
|
+
];
|
|
563
|
+
const acc = mockAccessor(tasks);
|
|
564
|
+
|
|
565
|
+
const result = await predictImpact('auth service', undefined, acc);
|
|
566
|
+
|
|
567
|
+
const exposures = result.affectedTasks.map((t) => t.exposure);
|
|
568
|
+
// direct must come before dependent which must come before transitive
|
|
569
|
+
const directIdx = exposures.indexOf('direct');
|
|
570
|
+
const dependentIdx = exposures.indexOf('dependent');
|
|
571
|
+
const transitiveIdx = exposures.indexOf('transitive');
|
|
572
|
+
|
|
573
|
+
if (directIdx !== -1 && dependentIdx !== -1) {
|
|
574
|
+
expect(directIdx).toBeLessThan(dependentIdx);
|
|
575
|
+
}
|
|
576
|
+
if (dependentIdx !== -1 && transitiveIdx !== -1) {
|
|
577
|
+
expect(dependentIdx).toBeLessThan(transitiveIdx);
|
|
578
|
+
}
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
it('respects matchLimit parameter', async () => {
|
|
582
|
+
const tasks = [
|
|
583
|
+
makeTask({ id: 'T001', title: 'auth module setup', description: '' }),
|
|
584
|
+
makeTask({ id: 'T002', title: 'auth token generation', description: '' }),
|
|
585
|
+
makeTask({ id: 'T003', title: 'auth session management', description: '' }),
|
|
586
|
+
];
|
|
587
|
+
const acc = mockAccessor(tasks);
|
|
588
|
+
|
|
589
|
+
// Limit to 1 seed
|
|
590
|
+
const result = await predictImpact('auth', undefined, acc, 1);
|
|
591
|
+
|
|
592
|
+
// Only 1 direct match seeded
|
|
593
|
+
expect(result.matchedTasks).toHaveLength(1);
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
it('produces a meaningful summary string', async () => {
|
|
597
|
+
const tasks = [
|
|
598
|
+
makeTask({ id: 'T001', title: 'auth service', description: '' }),
|
|
599
|
+
makeTask({ id: 'T002', title: 'Login page', description: '', depends: ['T001'] }),
|
|
600
|
+
];
|
|
601
|
+
const acc = mockAccessor(tasks);
|
|
602
|
+
|
|
603
|
+
const result = await predictImpact('auth service', undefined, acc);
|
|
604
|
+
|
|
605
|
+
expect(result.summary).toContain('auth service');
|
|
606
|
+
expect(result.summary).toMatch(/\d+ task/);
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
it('downstreamCount is 0 for leaf tasks with no dependents', async () => {
|
|
610
|
+
const tasks = [makeTask({ id: 'T001', title: 'auth service core', description: '' })];
|
|
611
|
+
const acc = mockAccessor(tasks);
|
|
612
|
+
|
|
613
|
+
const result = await predictImpact('auth service', undefined, acc);
|
|
614
|
+
|
|
615
|
+
expect(result.affectedTasks[0]?.downstreamCount).toBe(0);
|
|
616
|
+
});
|
|
617
|
+
});
|