@cleocode/core 2026.3.45 → 2026.3.47
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/bootstrap.d.ts.map +1 -1
- package/dist/index.js +1508 -377
- package/dist/index.js.map +4 -4
- package/dist/init.d.ts.map +1 -1
- package/dist/injection.d.ts +1 -1
- package/dist/injection.d.ts.map +1 -1
- package/dist/routing/capability-matrix.d.ts +6 -4
- package/dist/routing/capability-matrix.d.ts.map +1 -1
- package/dist/scaffold.d.ts +35 -9
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/skills/agents/install.d.ts.map +1 -1
- package/dist/skills/routing-table.d.ts +17 -16
- package/dist/skills/routing-table.d.ts.map +1 -1
- package/dist/skills/skill-paths.d.ts.map +1 -1
- package/dist/system/health.d.ts.map +1 -1
- package/dist/ui/index.d.ts +0 -1
- package/dist/ui/index.d.ts.map +1 -1
- package/package.json +9 -4
- package/schemas/adr-frontmatter.schema.json +72 -0
- package/schemas/agent-configs.schema.json +120 -0
- package/schemas/agent-registry.json +243 -0
- package/schemas/agent-registry.schema.json +132 -0
- package/schemas/archive/research-manifest.schema.json +257 -0
- package/schemas/archive.schema.json +450 -0
- package/schemas/brain-decision.schema.json +69 -0
- package/schemas/brain-learning.schema.json +57 -0
- package/schemas/brain-pattern.schema.json +72 -0
- package/schemas/config.schema.json +2606 -0
- package/schemas/context-state.schema.json +137 -0
- package/schemas/contribution.schema.json +722 -0
- package/schemas/critical-path.schema.json +246 -0
- package/schemas/deps-cache.schema.json +97 -0
- package/schemas/doctor-output.schema.json +283 -0
- package/schemas/error.schema.json +161 -0
- package/schemas/export-package.schema.json +375 -0
- package/schemas/global-config.schema.json +219 -0
- package/schemas/grade.schema.json +49 -0
- package/schemas/log.schema.json +250 -0
- package/schemas/metrics.schema.json +328 -0
- package/schemas/migrations.schema.json +150 -0
- package/schemas/nexus-registry.schema.json +90 -0
- package/schemas/operation-constitution.schema.json +438 -0
- package/schemas/output.schema.json +164 -0
- package/schemas/project-context.schema.json +164 -0
- package/schemas/project-info.schema.json +180 -0
- package/schemas/projects-registry.schema.json +107 -0
- package/schemas/protocol-frontmatter.schema.json +72 -0
- package/schemas/rcasd-consensus-report.schema.json +10 -0
- package/schemas/rcasd-evidence.schema.json +42 -0
- package/schemas/rcasd-gate-result.schema.json +46 -0
- package/schemas/rcasd-hitl-resolution.schema.json +10 -0
- package/schemas/rcasd-index.schema.json +10 -0
- package/schemas/rcasd-manifest.schema.json +10 -0
- package/schemas/rcasd-research-output.schema.json +10 -0
- package/schemas/rcasd-spec-frontmatter.schema.json +10 -0
- package/schemas/rcasd-stage-transition.schema.json +38 -0
- package/schemas/releases.schema.json +267 -0
- package/schemas/skills-manifest.schema.json +91 -0
- package/schemas/skillsmp.schema.json +208 -0
- package/schemas/spec-index.schema.json +196 -0
- package/schemas/system-flow-atlas.schema.json +125 -0
- package/src/__tests__/injection-chain.test.d.ts +4 -3
- package/src/__tests__/injection-chain.test.d.ts.map +1 -1
- package/src/__tests__/injection-chain.test.js +11 -10
- package/src/__tests__/injection-chain.test.js.map +1 -1
- package/src/__tests__/injection-chain.test.ts +11 -10
- package/src/__tests__/injection-mvi-tiers.test.js +4 -2
- package/src/__tests__/injection-mvi-tiers.test.js.map +1 -1
- package/src/__tests__/injection-mvi-tiers.test.ts +4 -2
- package/src/agents/__tests__/capacity.test.d.ts +7 -0
- package/src/agents/__tests__/capacity.test.d.ts.map +1 -0
- package/src/agents/__tests__/capacity.test.js +173 -0
- package/src/agents/__tests__/capacity.test.js.map +1 -0
- package/src/agents/__tests__/registry.test.d.ts +8 -0
- package/src/agents/__tests__/registry.test.d.ts.map +1 -0
- package/src/agents/__tests__/registry.test.js +348 -0
- package/src/agents/__tests__/registry.test.js.map +1 -0
- package/src/agents/__tests__/retry.test.d.ts +7 -0
- package/src/agents/__tests__/retry.test.d.ts.map +1 -0
- package/src/agents/__tests__/retry.test.js +225 -0
- package/src/agents/__tests__/retry.test.js.map +1 -0
- package/src/bootstrap.ts +37 -6
- package/src/init.ts +63 -18
- package/src/injection.ts +11 -5
- package/src/intelligence/__tests__/impact.test.d.ts +15 -0
- package/src/intelligence/__tests__/impact.test.d.ts.map +1 -0
- package/src/intelligence/__tests__/impact.test.js +384 -0
- package/src/intelligence/__tests__/impact.test.js.map +1 -0
- package/src/intelligence/__tests__/patterns.test.d.ts +8 -0
- package/src/intelligence/__tests__/patterns.test.d.ts.map +1 -0
- package/src/intelligence/__tests__/patterns.test.js +370 -0
- package/src/intelligence/__tests__/patterns.test.js.map +1 -0
- package/src/intelligence/__tests__/prediction.test.d.ts +8 -0
- package/src/intelligence/__tests__/prediction.test.d.ts.map +1 -0
- package/src/intelligence/__tests__/prediction.test.js +314 -0
- package/src/intelligence/__tests__/prediction.test.js.map +1 -0
- package/src/nexus/__tests__/nexus-e2e.test.d.ts +12 -0
- package/src/nexus/__tests__/nexus-e2e.test.d.ts.map +1 -0
- package/src/nexus/__tests__/nexus-e2e.test.js +1220 -0
- package/src/nexus/__tests__/nexus-e2e.test.js.map +1 -0
- package/src/nexus/__tests__/transfer.test.d.ts +8 -0
- package/src/nexus/__tests__/transfer.test.d.ts.map +1 -0
- package/src/nexus/__tests__/transfer.test.js +372 -0
- package/src/nexus/__tests__/transfer.test.js.map +1 -0
- package/src/nexus/__tests__/transfer.test.ts +1 -1
- package/src/routing/capability-matrix.ts +1435 -205
- package/src/scaffold.ts +70 -13
- package/src/sessions/__tests__/briefing.test.js +28 -2
- package/src/sessions/__tests__/briefing.test.js.map +1 -1
- package/src/skills/__tests__/routing-table.test.js +48 -31
- package/src/skills/__tests__/routing-table.test.js.map +1 -1
- package/src/skills/__tests__/routing-table.test.ts +53 -33
- package/src/skills/agents/install.ts +9 -1
- package/src/skills/orchestrator/__tests__/spawn-tier.test.js +41 -32
- package/src/skills/orchestrator/__tests__/spawn-tier.test.js.map +1 -1
- package/src/skills/routing-table.ts +39 -253
- package/src/skills/skill-paths.ts +3 -2
- package/src/store/__tests__/project-detect.test.js +1 -1
- package/src/store/__tests__/project-detect.test.js.map +1 -1
- package/src/store/__tests__/project-detect.test.ts +1 -1
- package/src/store/__tests__/test-db-helper.d.ts.map +1 -1
- package/src/store/__tests__/test-db-helper.js +0 -1
- package/src/store/__tests__/test-db-helper.js.map +1 -1
- package/src/system/health.ts +18 -7
- package/src/ui/index.ts +0 -6
- package/src/validation/operation-gate-validators.ts +2 -2
- package/templates/CLEO-INJECTION.md +120 -0
- package/templates/README.md +29 -0
- package/templates/agent-registry.json +305 -0
- package/templates/cleo-gitignore +74 -0
- package/templates/config.template.json +187 -0
- package/templates/git-hooks/commit-msg +149 -0
- package/templates/git-hooks/pre-commit +40 -0
- package/templates/git-hooks/pre-push +79 -0
- package/templates/github/ISSUE_TEMPLATE/bug_report.yml +143 -0
- package/templates/github/ISSUE_TEMPLATE/config.yml +8 -0
- package/templates/github/ISSUE_TEMPLATE/feature_request.yml +125 -0
- package/templates/github/ISSUE_TEMPLATE/help_question.yml +99 -0
- package/templates/global-config.template.json +56 -0
- package/templates/hooks/precompact-safestop.sh +89 -0
- package/templates/issue-templates/bug_report.yml +143 -0
- package/templates/issue-templates/config.yml +8 -0
- package/templates/issue-templates/feature_request.yml +125 -0
- package/templates/issue-templates/help_question.yml +99 -0
- package/templates/skillsmp.json.example +28 -0
- package/templates/skillsmp.json.example.md +214 -0
- package/dist/ui/injection-legacy.d.ts +0 -26
- package/dist/ui/injection-legacy.d.ts.map +0 -1
- package/src/ui/__tests__/injection-registry.test.d.ts +0 -11
- package/src/ui/__tests__/injection-registry.test.d.ts.map +0 -1
- package/src/ui/__tests__/injection-registry.test.js +0 -46
- package/src/ui/__tests__/injection-registry.test.js.map +0 -1
- package/src/ui/__tests__/injection-registry.test.ts +0 -57
- package/src/ui/injection-legacy.ts +0 -44
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for retry logic, exponential backoff, and self-healing recovery.
|
|
3
|
+
*
|
|
4
|
+
* @module agents/__tests__/retry.test
|
|
5
|
+
*/
|
|
6
|
+
import { mkdir, mkdtemp, rm } from 'node:fs/promises';
|
|
7
|
+
import { tmpdir } from 'node:os';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
10
|
+
import { registerAgent, updateAgentStatus } from '../registry.js';
|
|
11
|
+
import { calculateDelay, createRetryPolicy, DEFAULT_RETRY_POLICY, recoverCrashedAgents, shouldRetry, withRetry, } from '../retry.js';
|
|
12
|
+
// ==========================================================================
|
|
13
|
+
// Retry Policy
|
|
14
|
+
// ==========================================================================
|
|
15
|
+
describe('Retry Policy', () => {
|
|
16
|
+
describe('createRetryPolicy', () => {
|
|
17
|
+
it('returns default policy when no overrides', () => {
|
|
18
|
+
const policy = createRetryPolicy();
|
|
19
|
+
expect(policy.maxRetries).toBe(3);
|
|
20
|
+
expect(policy.baseDelayMs).toBe(1_000);
|
|
21
|
+
expect(policy.maxDelayMs).toBe(30_000);
|
|
22
|
+
expect(policy.backoffMultiplier).toBe(2);
|
|
23
|
+
expect(policy.jitter).toBe(true);
|
|
24
|
+
expect(policy.retryOnUnknown).toBe(true);
|
|
25
|
+
});
|
|
26
|
+
it('merges partial overrides with defaults', () => {
|
|
27
|
+
const policy = createRetryPolicy({ maxRetries: 5, baseDelayMs: 500 });
|
|
28
|
+
expect(policy.maxRetries).toBe(5);
|
|
29
|
+
expect(policy.baseDelayMs).toBe(500);
|
|
30
|
+
expect(policy.maxDelayMs).toBe(30_000); // unchanged default
|
|
31
|
+
});
|
|
32
|
+
it('DEFAULT_RETRY_POLICY is frozen', () => {
|
|
33
|
+
expect(Object.isFrozen(DEFAULT_RETRY_POLICY)).toBe(true);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
describe('calculateDelay', () => {
|
|
37
|
+
it('applies exponential backoff', () => {
|
|
38
|
+
const policy = createRetryPolicy({ jitter: false, baseDelayMs: 100, backoffMultiplier: 2 });
|
|
39
|
+
expect(calculateDelay(0, policy)).toBe(100); // 100 * 2^0
|
|
40
|
+
expect(calculateDelay(1, policy)).toBe(200); // 100 * 2^1
|
|
41
|
+
expect(calculateDelay(2, policy)).toBe(400); // 100 * 2^2
|
|
42
|
+
expect(calculateDelay(3, policy)).toBe(800); // 100 * 2^3
|
|
43
|
+
});
|
|
44
|
+
it('caps at maxDelay', () => {
|
|
45
|
+
const policy = createRetryPolicy({
|
|
46
|
+
jitter: false,
|
|
47
|
+
baseDelayMs: 100,
|
|
48
|
+
maxDelayMs: 500,
|
|
49
|
+
backoffMultiplier: 10,
|
|
50
|
+
});
|
|
51
|
+
expect(calculateDelay(0, policy)).toBe(100);
|
|
52
|
+
expect(calculateDelay(1, policy)).toBe(500); // capped
|
|
53
|
+
expect(calculateDelay(2, policy)).toBe(500); // capped
|
|
54
|
+
});
|
|
55
|
+
it('adds jitter when enabled', () => {
|
|
56
|
+
const policy = createRetryPolicy({
|
|
57
|
+
jitter: true,
|
|
58
|
+
baseDelayMs: 1000,
|
|
59
|
+
backoffMultiplier: 1,
|
|
60
|
+
});
|
|
61
|
+
// With jitter, delay should be >= base but <= base * 1.25
|
|
62
|
+
const delays = Array.from({ length: 20 }, () => calculateDelay(0, policy));
|
|
63
|
+
const allInRange = delays.every((d) => d >= 1000 && d <= 1250);
|
|
64
|
+
expect(allInRange).toBe(true);
|
|
65
|
+
// With 20 samples, at least some should differ (jitter is random)
|
|
66
|
+
const uniqueDelays = new Set(delays);
|
|
67
|
+
expect(uniqueDelays.size).toBeGreaterThan(1);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
describe('shouldRetry', () => {
|
|
71
|
+
it('allows retry for retriable errors within limit', () => {
|
|
72
|
+
const policy = createRetryPolicy({ maxRetries: 3 });
|
|
73
|
+
expect(shouldRetry(new Error('ECONNREFUSED'), 0, policy)).toBe(true);
|
|
74
|
+
expect(shouldRetry(new Error('timeout'), 1, policy)).toBe(true);
|
|
75
|
+
expect(shouldRetry(new Error('503 Service Unavailable'), 2, policy)).toBe(true);
|
|
76
|
+
});
|
|
77
|
+
it('denies retry when attempt exceeds maxRetries', () => {
|
|
78
|
+
const policy = createRetryPolicy({ maxRetries: 3 });
|
|
79
|
+
expect(shouldRetry(new Error('ECONNREFUSED'), 3, policy)).toBe(false);
|
|
80
|
+
expect(shouldRetry(new Error('ECONNREFUSED'), 4, policy)).toBe(false);
|
|
81
|
+
});
|
|
82
|
+
it('denies retry for permanent errors', () => {
|
|
83
|
+
const policy = createRetryPolicy({ maxRetries: 10 });
|
|
84
|
+
expect(shouldRetry(new Error('Permission denied'), 0, policy)).toBe(false);
|
|
85
|
+
expect(shouldRetry(new Error('401 Unauthorized'), 0, policy)).toBe(false);
|
|
86
|
+
});
|
|
87
|
+
it('respects retryOnUnknown policy', () => {
|
|
88
|
+
const retryUnknown = createRetryPolicy({ retryOnUnknown: true });
|
|
89
|
+
const noRetryUnknown = createRetryPolicy({ retryOnUnknown: false });
|
|
90
|
+
const unknownError = new Error('Something weird');
|
|
91
|
+
expect(shouldRetry(unknownError, 0, retryUnknown)).toBe(true);
|
|
92
|
+
expect(shouldRetry(unknownError, 0, noRetryUnknown)).toBe(false);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
// ==========================================================================
|
|
97
|
+
// withRetry wrapper
|
|
98
|
+
// ==========================================================================
|
|
99
|
+
describe('withRetry', () => {
|
|
100
|
+
it('succeeds on first attempt', async () => {
|
|
101
|
+
let callCount = 0;
|
|
102
|
+
const result = await withRetry(async () => {
|
|
103
|
+
callCount++;
|
|
104
|
+
return 'success';
|
|
105
|
+
});
|
|
106
|
+
expect(result.success).toBe(true);
|
|
107
|
+
expect(result.value).toBe('success');
|
|
108
|
+
expect(result.attempts).toBe(1);
|
|
109
|
+
expect(callCount).toBe(1);
|
|
110
|
+
});
|
|
111
|
+
it('retries on retriable error and eventually succeeds', async () => {
|
|
112
|
+
let callCount = 0;
|
|
113
|
+
const result = await withRetry(async () => {
|
|
114
|
+
callCount++;
|
|
115
|
+
if (callCount < 3)
|
|
116
|
+
throw new Error('ECONNREFUSED');
|
|
117
|
+
return 'recovered';
|
|
118
|
+
}, { baseDelayMs: 1, maxDelayMs: 5, jitter: false });
|
|
119
|
+
expect(result.success).toBe(true);
|
|
120
|
+
expect(result.value).toBe('recovered');
|
|
121
|
+
expect(result.attempts).toBe(3);
|
|
122
|
+
expect(callCount).toBe(3);
|
|
123
|
+
});
|
|
124
|
+
it('fails immediately on permanent error', async () => {
|
|
125
|
+
let callCount = 0;
|
|
126
|
+
const result = await withRetry(async () => {
|
|
127
|
+
callCount++;
|
|
128
|
+
throw new Error('Permission denied');
|
|
129
|
+
}, { baseDelayMs: 1, jitter: false });
|
|
130
|
+
expect(result.success).toBe(false);
|
|
131
|
+
expect(result.error?.message).toBe('Permission denied');
|
|
132
|
+
expect(result.attempts).toBe(1);
|
|
133
|
+
expect(callCount).toBe(1);
|
|
134
|
+
});
|
|
135
|
+
it('exhausts retries and fails', async () => {
|
|
136
|
+
let callCount = 0;
|
|
137
|
+
const result = await withRetry(async () => {
|
|
138
|
+
callCount++;
|
|
139
|
+
throw new Error('ECONNREFUSED');
|
|
140
|
+
}, { maxRetries: 2, baseDelayMs: 1, maxDelayMs: 5, jitter: false });
|
|
141
|
+
expect(result.success).toBe(false);
|
|
142
|
+
expect(result.attempts).toBe(3); // 1 initial + 2 retries
|
|
143
|
+
expect(callCount).toBe(3);
|
|
144
|
+
});
|
|
145
|
+
it('tracks total delay time', async () => {
|
|
146
|
+
let callCount = 0;
|
|
147
|
+
const result = await withRetry(async () => {
|
|
148
|
+
callCount++;
|
|
149
|
+
if (callCount <= 2)
|
|
150
|
+
throw new Error('timeout');
|
|
151
|
+
return 'ok';
|
|
152
|
+
}, { baseDelayMs: 10, backoffMultiplier: 1, jitter: false });
|
|
153
|
+
expect(result.success).toBe(true);
|
|
154
|
+
expect(result.totalDelayMs).toBeGreaterThanOrEqual(20); // 10 + 10
|
|
155
|
+
});
|
|
156
|
+
it('uses custom retry policy', async () => {
|
|
157
|
+
let callCount = 0;
|
|
158
|
+
const result = await withRetry(async () => {
|
|
159
|
+
callCount++;
|
|
160
|
+
throw new Error('rate limit');
|
|
161
|
+
}, { maxRetries: 1, baseDelayMs: 1, jitter: false });
|
|
162
|
+
expect(result.success).toBe(false);
|
|
163
|
+
expect(result.attempts).toBe(2); // 1 initial + 1 retry
|
|
164
|
+
expect(callCount).toBe(2);
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
// ==========================================================================
|
|
168
|
+
// Self-Healing Recovery
|
|
169
|
+
// ==========================================================================
|
|
170
|
+
describe('recoverCrashedAgents', () => {
|
|
171
|
+
let tempDir;
|
|
172
|
+
beforeEach(async () => {
|
|
173
|
+
tempDir = await mkdtemp(join(tmpdir(), 'cleo-recover-test-'));
|
|
174
|
+
await mkdir(join(tempDir, '.cleo'), { recursive: true });
|
|
175
|
+
await mkdir(join(tempDir, '.cleo', 'backups', 'operational'), { recursive: true });
|
|
176
|
+
});
|
|
177
|
+
afterEach(async () => {
|
|
178
|
+
try {
|
|
179
|
+
const { closeAllDatabases } = await import('../../store/sqlite.js');
|
|
180
|
+
await closeAllDatabases();
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
/* module may not be loaded */
|
|
184
|
+
}
|
|
185
|
+
await Promise.race([
|
|
186
|
+
rm(tempDir, { recursive: true, force: true, maxRetries: 3, retryDelay: 300 }).catch(() => { }),
|
|
187
|
+
new Promise((resolve) => setTimeout(resolve, 8_000)),
|
|
188
|
+
]);
|
|
189
|
+
});
|
|
190
|
+
it('recovers crashed agents with retriable errors', async () => {
|
|
191
|
+
const agent = await registerAgent({ agentType: 'executor' }, tempDir);
|
|
192
|
+
await updateAgentStatus(agent.id, { status: 'crashed', error: 'ECONNREFUSED' }, tempDir);
|
|
193
|
+
const results = await recoverCrashedAgents(30_000, tempDir);
|
|
194
|
+
expect(results.length).toBe(1);
|
|
195
|
+
expect(results[0].recovered).toBe(true);
|
|
196
|
+
expect(results[0].action).toBe('restarted');
|
|
197
|
+
});
|
|
198
|
+
it('abandons agents with permanent errors', async () => {
|
|
199
|
+
const agent = await registerAgent({ agentType: 'executor' }, tempDir);
|
|
200
|
+
await updateAgentStatus(agent.id, { status: 'crashed', error: 'Permission denied' }, tempDir);
|
|
201
|
+
const results = await recoverCrashedAgents(30_000, tempDir);
|
|
202
|
+
expect(results.length).toBe(1);
|
|
203
|
+
expect(results[0].recovered).toBe(false);
|
|
204
|
+
expect(results[0].action).toBe('abandoned');
|
|
205
|
+
});
|
|
206
|
+
it('abandons agents exceeding error threshold', async () => {
|
|
207
|
+
const agent = await registerAgent({ agentType: 'executor' }, tempDir);
|
|
208
|
+
// Simulate 5+ errors
|
|
209
|
+
for (let i = 0; i < 5; i++) {
|
|
210
|
+
await updateAgentStatus(agent.id, { status: 'error', error: `Error ${i}` }, tempDir);
|
|
211
|
+
}
|
|
212
|
+
await updateAgentStatus(agent.id, { status: 'crashed' }, tempDir);
|
|
213
|
+
const results = await recoverCrashedAgents(30_000, tempDir);
|
|
214
|
+
expect(results.length).toBe(1);
|
|
215
|
+
expect(results[0].recovered).toBe(false);
|
|
216
|
+
expect(results[0].action).toBe('abandoned');
|
|
217
|
+
expect(results[0].reason).toContain('exceeds threshold');
|
|
218
|
+
});
|
|
219
|
+
it('returns empty results when no crashed agents', async () => {
|
|
220
|
+
await registerAgent({ agentType: 'executor' }, tempDir);
|
|
221
|
+
const results = await recoverCrashedAgents(60_000, tempDir);
|
|
222
|
+
expect(results.length).toBe(0);
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
//# sourceMappingURL=retry.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.test.js","sourceRoot":"","sources":["retry.test.ts"],"names":[],"mappings":"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"}
|
package/src/bootstrap.ts
CHANGED
|
@@ -65,7 +65,10 @@ export async function bootstrapGlobalCleo(options?: BootstrapOptions): Promise<B
|
|
|
65
65
|
// Step 4: Install core skills globally
|
|
66
66
|
await installSkillsGlobally(ctx);
|
|
67
67
|
|
|
68
|
-
// Step 5: Install
|
|
68
|
+
// Step 5: Install agent definition (cleo-subagent symlink)
|
|
69
|
+
await installAgentDefinitionGlobally(ctx);
|
|
70
|
+
|
|
71
|
+
// Step 6: Install provider adapters
|
|
69
72
|
await installProviderAdapters(ctx, options?.packageRoot);
|
|
70
73
|
|
|
71
74
|
return ctx;
|
|
@@ -132,16 +135,21 @@ async function injectAgentsHub(ctx: BootstrapContext): Promise<void> {
|
|
|
132
135
|
if (!ctx.isDryRun) {
|
|
133
136
|
await mkdir(globalAgentsDir, { recursive: true });
|
|
134
137
|
|
|
135
|
-
// Strip any legacy CLEO blocks first
|
|
138
|
+
// Strip any legacy CLEO blocks first (handles bare and versioned markers)
|
|
136
139
|
if (existsSync(globalAgentsMd)) {
|
|
137
140
|
const content = await readFile(globalAgentsMd, 'utf8');
|
|
138
|
-
const stripped = content.replace(
|
|
141
|
+
const stripped = content.replace(
|
|
142
|
+
/\n?<!-- CLEO:START[^>]*-->[\s\S]*?<!-- CLEO:END -->\n?/g,
|
|
143
|
+
'',
|
|
144
|
+
);
|
|
139
145
|
if (stripped !== content) {
|
|
140
146
|
await writeFile(globalAgentsMd, stripped, 'utf8');
|
|
141
147
|
}
|
|
142
148
|
}
|
|
143
149
|
|
|
144
|
-
|
|
150
|
+
// Direct call — CAAMP 1.8.0 handles idempotency
|
|
151
|
+
const expectedContent = '@~/.cleo/templates/CLEO-INJECTION.md';
|
|
152
|
+
const action = await inject(globalAgentsMd, expectedContent);
|
|
145
153
|
ctx.created.push(`~/.agents/AGENTS.md (${action})`);
|
|
146
154
|
} else {
|
|
147
155
|
ctx.created.push('~/.agents/AGENTS.md (would create/update CAAMP block)');
|
|
@@ -159,12 +167,13 @@ async function injectAgentsHub(ctx: BootstrapContext): Promise<void> {
|
|
|
159
167
|
|
|
160
168
|
if (!ctx.isDryRun) {
|
|
161
169
|
// Strip legacy CLEO blocks from global provider files first
|
|
170
|
+
// (handles bare and versioned markers, e.g. <!-- CLEO:START v0.53.4 -->)
|
|
162
171
|
for (const provider of providers) {
|
|
163
172
|
const instructFilePath = join(provider.pathGlobal, provider.instructFile);
|
|
164
173
|
if (existsSync(instructFilePath)) {
|
|
165
174
|
const fileContent = await readFile(instructFilePath, 'utf8');
|
|
166
175
|
const stripped = fileContent.replace(
|
|
167
|
-
/\n?<!-- CLEO:START
|
|
176
|
+
/\n?<!-- CLEO:START[^>]*-->[\s\S]*?<!-- CLEO:END -->\n?/g,
|
|
168
177
|
'',
|
|
169
178
|
);
|
|
170
179
|
if (stripped !== fileContent) {
|
|
@@ -252,7 +261,29 @@ export async function installSkillsGlobally(ctx: BootstrapContext): Promise<void
|
|
|
252
261
|
}
|
|
253
262
|
}
|
|
254
263
|
|
|
255
|
-
// ── Step 5:
|
|
264
|
+
// ── Step 5: Agent definition installation ────────────────────────────
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Install the cleo-subagent agent definition to ~/.agents/agents/.
|
|
268
|
+
* Delegates to initAgentDefinition() in init.ts which handles require.resolve
|
|
269
|
+
* fallback and symlink/copy logic.
|
|
270
|
+
*/
|
|
271
|
+
async function installAgentDefinitionGlobally(ctx: BootstrapContext): Promise<void> {
|
|
272
|
+
try {
|
|
273
|
+
if (!ctx.isDryRun) {
|
|
274
|
+
const { initAgentDefinition } = await import('./init.js');
|
|
275
|
+
await initAgentDefinition(ctx.created, ctx.warnings);
|
|
276
|
+
} else {
|
|
277
|
+
ctx.created.push('agent: cleo-subagent (would symlink)');
|
|
278
|
+
}
|
|
279
|
+
} catch (err) {
|
|
280
|
+
ctx.warnings.push(
|
|
281
|
+
`Agent definition install: ${err instanceof Error ? err.message : String(err)}`,
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// ── Step 6: Provider adapter installation ────────────────────────────
|
|
256
287
|
|
|
257
288
|
async function installProviderAdapters(
|
|
258
289
|
ctx: BootstrapContext,
|
package/src/init.ts
CHANGED
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
|
|
35
35
|
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
36
36
|
import { copyFile, lstat, mkdir, readFile, symlink, unlink, writeFile } from 'node:fs/promises';
|
|
37
|
+
import { platform } from 'node:os';
|
|
37
38
|
import { basename, dirname, join } from 'node:path';
|
|
38
39
|
import { ExitCode } from '@cleocode/contracts';
|
|
39
40
|
import { CleoError } from './errors.js';
|
|
@@ -83,6 +84,15 @@ export interface InitResult {
|
|
|
83
84
|
updateDocsOnly?: boolean;
|
|
84
85
|
}
|
|
85
86
|
|
|
87
|
+
// ── Helpers ──────────────────────────────────────────────────────────
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Symlink type for directory symlinks.
|
|
91
|
+
* On Windows, use 'junction' (no admin privileges required).
|
|
92
|
+
* On Unix, use 'dir'.
|
|
93
|
+
*/
|
|
94
|
+
const DIR_SYMLINK_TYPE: 'junction' | 'dir' = platform() === 'win32' ? 'junction' : 'dir';
|
|
95
|
+
|
|
86
96
|
// ── Init-specific operations ─────────────────────────────────────────
|
|
87
97
|
|
|
88
98
|
/**
|
|
@@ -90,10 +100,30 @@ export interface InitResult {
|
|
|
90
100
|
* @task T4685
|
|
91
101
|
*/
|
|
92
102
|
export async function initAgentDefinition(created: string[], warnings: string[]): Promise<void> {
|
|
93
|
-
|
|
94
|
-
|
|
103
|
+
// Resolve agents package via require.resolve, then workspace/bundled fallback
|
|
104
|
+
let agentSourceDir: string | null = null;
|
|
105
|
+
try {
|
|
106
|
+
const { createRequire } = await import('node:module');
|
|
107
|
+
const req = createRequire(import.meta.url);
|
|
108
|
+
const agentsPkgMain = req.resolve('@cleocode/agents/package.json');
|
|
109
|
+
const agentsPkgRoot = dirname(agentsPkgMain);
|
|
110
|
+
const candidate = join(agentsPkgRoot, 'cleo-subagent');
|
|
111
|
+
if (existsSync(candidate)) {
|
|
112
|
+
agentSourceDir = candidate;
|
|
113
|
+
}
|
|
114
|
+
} catch {
|
|
115
|
+
// Not resolvable via require.resolve — fall through to bundled path
|
|
116
|
+
}
|
|
95
117
|
|
|
96
|
-
if (!
|
|
118
|
+
if (!agentSourceDir) {
|
|
119
|
+
const packageRoot = getPackageRoot();
|
|
120
|
+
const bundled = join(packageRoot, 'agents', 'cleo-subagent');
|
|
121
|
+
if (existsSync(bundled)) {
|
|
122
|
+
agentSourceDir = bundled;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (!agentSourceDir) {
|
|
97
127
|
warnings.push('agents/cleo-subagent/ not found in package, skipping agent definition install');
|
|
98
128
|
return;
|
|
99
129
|
}
|
|
@@ -114,7 +144,7 @@ export async function initAgentDefinition(created: string[], warnings: string[])
|
|
|
114
144
|
}
|
|
115
145
|
|
|
116
146
|
// Create symlink from ~/.agents/agents/cleo-subagent -> package agents/cleo-subagent/
|
|
117
|
-
await symlink(agentSourceDir, globalAgentsDir,
|
|
147
|
+
await symlink(agentSourceDir, globalAgentsDir, DIR_SYMLINK_TYPE);
|
|
118
148
|
created.push('agent: cleo-subagent (symlinked)');
|
|
119
149
|
} catch (_err) {
|
|
120
150
|
// If symlink fails (e.g., permissions), try copying
|
|
@@ -201,23 +231,38 @@ export async function initCoreSkills(created: string[], warnings: string[]): Pro
|
|
|
201
231
|
return;
|
|
202
232
|
}
|
|
203
233
|
|
|
204
|
-
// Find skills package
|
|
234
|
+
// Find skills package via require.resolve, then workspace path, then node_modules fallback
|
|
205
235
|
const packageRoot = getPackageRoot();
|
|
206
236
|
let ctSkillsRoot: string | null = null;
|
|
207
237
|
try {
|
|
208
|
-
//
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
if (existsSync(join(ctSkillsPath, 'skills.json'))) {
|
|
216
|
-
ctSkillsRoot = ctSkillsPath;
|
|
217
|
-
}
|
|
238
|
+
// Primary: resolve via Node module resolution (@cleocode/skills)
|
|
239
|
+
const { createRequire } = await import('node:module');
|
|
240
|
+
const req = createRequire(import.meta.url);
|
|
241
|
+
const skillsPkgMain = req.resolve('@cleocode/skills/package.json');
|
|
242
|
+
const skillsPkgRoot = dirname(skillsPkgMain);
|
|
243
|
+
if (existsSync(join(skillsPkgRoot, 'skills.json'))) {
|
|
244
|
+
ctSkillsRoot = skillsPkgRoot;
|
|
218
245
|
}
|
|
219
246
|
} catch {
|
|
220
|
-
//
|
|
247
|
+
// Not resolvable via require.resolve — try workspace and node_modules fallbacks
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (!ctSkillsRoot) {
|
|
251
|
+
try {
|
|
252
|
+
// Workspace monorepo fallback (packages/skills/)
|
|
253
|
+
const bundledPath = join(packageRoot, 'packages', 'skills');
|
|
254
|
+
if (existsSync(join(bundledPath, 'skills.json'))) {
|
|
255
|
+
ctSkillsRoot = bundledPath;
|
|
256
|
+
} else {
|
|
257
|
+
// node_modules fallback
|
|
258
|
+
const ctSkillsPath = join(packageRoot, 'node_modules', '@cleocode', 'skills');
|
|
259
|
+
if (existsSync(join(ctSkillsPath, 'skills.json'))) {
|
|
260
|
+
ctSkillsRoot = ctSkillsPath;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
} catch {
|
|
264
|
+
// not found
|
|
265
|
+
}
|
|
221
266
|
}
|
|
222
267
|
|
|
223
268
|
if (!ctSkillsRoot) {
|
|
@@ -651,8 +696,8 @@ export async function initProject(opts: InitOptions = {}): Promise<InitResult> {
|
|
|
651
696
|
// T4685: Agent definition (cleo-subagent)
|
|
652
697
|
await initAgentDefinition(created, warnings);
|
|
653
698
|
|
|
654
|
-
//
|
|
655
|
-
|
|
699
|
+
// Note: Core skills installation is global-only (bootstrapGlobalCleo / installSkillsGlobally).
|
|
700
|
+
// Skills are NOT installed during project-level init — they are installed once globally.
|
|
656
701
|
|
|
657
702
|
// T4684: NEXUS registration (reconcile-based handshake, T5368)
|
|
658
703
|
await initNexusRegistration(projRoot, created, warnings);
|
package/src/injection.ts
CHANGED
|
@@ -78,7 +78,7 @@ async function removeStaleAgentInjection(projectRoot: string): Promise<boolean>
|
|
|
78
78
|
*
|
|
79
79
|
* Target architecture:
|
|
80
80
|
* CLAUDE.md/GEMINI.md -> @AGENTS.md (via injectAll)
|
|
81
|
-
* AGENTS.md -> @~/.
|
|
81
|
+
* AGENTS.md -> @~/.agents/AGENTS.md + @.cleo/project-context.json + @.cleo/memory-bridge.md
|
|
82
82
|
*
|
|
83
83
|
* @task T4682
|
|
84
84
|
*/
|
|
@@ -125,8 +125,9 @@ export async function ensureInjection(projectRoot: string): Promise<ScaffoldResu
|
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
// Step 2: Inject CLEO protocol content into AGENTS.md itself
|
|
128
|
+
// Project AGENTS.md references the global hub, which loads CLEO-INJECTION.md
|
|
128
129
|
const agentsMdPath = join(projectRoot, 'AGENTS.md');
|
|
129
|
-
const agentsMdLines = ['@~/.
|
|
130
|
+
const agentsMdLines = ['@~/.agents/AGENTS.md'];
|
|
130
131
|
|
|
131
132
|
const projectContextPath = join(projectRoot, '.cleo', 'project-context.json');
|
|
132
133
|
if (existsSync(projectContextPath)) {
|
|
@@ -146,7 +147,10 @@ export async function ensureInjection(projectRoot: string): Promise<ScaffoldResu
|
|
|
146
147
|
agentsMdLines.push(contributorBlock);
|
|
147
148
|
}
|
|
148
149
|
|
|
149
|
-
const
|
|
150
|
+
const agentsMdContent = agentsMdLines.join('\n');
|
|
151
|
+
|
|
152
|
+
// Direct call — CAAMP 1.8.0 handles idempotency
|
|
153
|
+
const agentsAction = await inject(agentsMdPath, agentsMdContent);
|
|
150
154
|
actions.push(`AGENTS.md CLEO content (${agentsAction})`);
|
|
151
155
|
|
|
152
156
|
// Step 3: Install CLEO-INJECTION.md to global templates dir
|
|
@@ -161,12 +165,14 @@ export async function ensureInjection(projectRoot: string): Promise<ScaffoldResu
|
|
|
161
165
|
}
|
|
162
166
|
}
|
|
163
167
|
|
|
164
|
-
// Step 4: Create global ~/.agents/AGENTS.md hub
|
|
168
|
+
// Step 4: Create global ~/.agents/AGENTS.md hub (idempotent)
|
|
165
169
|
try {
|
|
166
170
|
const globalAgentsDir = getAgentsHome();
|
|
167
171
|
const globalAgentsMd = join(globalAgentsDir, 'AGENTS.md');
|
|
172
|
+
const globalHubContent = '@~/.cleo/templates/CLEO-INJECTION.md';
|
|
168
173
|
await mkdir(globalAgentsDir, { recursive: true });
|
|
169
|
-
|
|
174
|
+
// Direct call — CAAMP 1.8.0 handles idempotency
|
|
175
|
+
await inject(globalAgentsMd, globalHubContent);
|
|
170
176
|
} catch {
|
|
171
177
|
// Best-effort — don't fail if global hub creation fails
|
|
172
178
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for impact analysis module.
|
|
3
|
+
*
|
|
4
|
+
* Covers:
|
|
5
|
+
* - Simple dependency chains (A->B->C)
|
|
6
|
+
* - Complex graphs (diamond dependencies)
|
|
7
|
+
* - Each change type (cancel, block, complete, reprioritize)
|
|
8
|
+
* - Blast radius calculation
|
|
9
|
+
* - Critical path detection
|
|
10
|
+
* - Edge cases (orphan tasks, circular refs, no deps)
|
|
11
|
+
*
|
|
12
|
+
* @module intelligence
|
|
13
|
+
*/
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=impact.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"impact.test.d.ts","sourceRoot":"","sources":["impact.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG"}
|