@cleocode/core 2026.3.58 → 2026.3.60
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-registry.js +288 -0
- package/dist/agents/agent-registry.js.map +1 -0
- package/dist/agents/agent-schema.js +5 -0
- package/dist/agents/agent-schema.js.map +1 -1
- package/dist/agents/execution-learning.js +474 -0
- package/dist/agents/execution-learning.js.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/health-monitor.js +217 -0
- package/dist/agents/health-monitor.js.map +1 -0
- package/dist/agents/index.d.ts +3 -1
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +9 -1
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/retry.d.ts +57 -4
- package/dist/agents/retry.d.ts.map +1 -1
- package/dist/agents/retry.js +57 -4
- package/dist/agents/retry.js.map +1 -1
- package/dist/backfill/index.d.ts +27 -0
- package/dist/backfill/index.d.ts.map +1 -1
- package/dist/backfill/index.js +229 -0
- package/dist/backfill/index.js.map +1 -0
- package/dist/bootstrap.d.ts +2 -1
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +135 -28
- package/dist/bootstrap.js.map +1 -1
- package/dist/cleo.d.ts +40 -0
- package/dist/cleo.d.ts.map +1 -1
- package/dist/config.js +83 -0
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1036 -536
- package/dist/index.js.map +4 -4
- package/dist/intelligence/adaptive-validation.js +497 -0
- package/dist/intelligence/adaptive-validation.js.map +1 -0
- package/dist/intelligence/impact.d.ts +34 -1
- package/dist/intelligence/impact.d.ts.map +1 -1
- package/dist/intelligence/impact.js +176 -0
- package/dist/intelligence/impact.js.map +1 -1
- package/dist/intelligence/index.d.ts +2 -2
- package/dist/intelligence/index.d.ts.map +1 -1
- package/dist/intelligence/index.js +6 -1
- package/dist/intelligence/index.js.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 +5 -4
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +11 -2
- package/dist/internal.js.map +1 -1
- package/dist/lib/index.d.ts +10 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +10 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/retry.d.ts +128 -0
- package/dist/lib/retry.d.ts.map +1 -0
- package/dist/lib/retry.js +152 -0
- package/dist/lib/retry.js.map +1 -0
- package/dist/nexus/sharing/index.d.ts +48 -2
- package/dist/nexus/sharing/index.d.ts.map +1 -1
- package/dist/nexus/sharing/index.js +110 -1
- package/dist/nexus/sharing/index.js.map +1 -1
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/scaffold.js +22 -2
- package/dist/scaffold.js.map +1 -1
- package/dist/sessions/session-enforcement.js +4 -0
- package/dist/sessions/session-enforcement.js.map +1 -1
- package/dist/stats/index.js +2 -0
- package/dist/stats/index.js.map +1 -1
- package/dist/stats/workflow-telemetry.d.ts +15 -0
- package/dist/stats/workflow-telemetry.d.ts.map +1 -1
- package/dist/stats/workflow-telemetry.js +400 -0
- package/dist/stats/workflow-telemetry.js.map +1 -0
- package/dist/store/brain-schema.js +4 -1
- package/dist/store/brain-schema.js.map +1 -1
- package/dist/store/converters.js +2 -0
- package/dist/store/converters.js.map +1 -1
- package/dist/store/cross-db-cleanup.d.ts +35 -0
- package/dist/store/cross-db-cleanup.d.ts.map +1 -1
- package/dist/store/cross-db-cleanup.js +169 -0
- package/dist/store/cross-db-cleanup.js.map +1 -0
- package/dist/store/db-helpers.js +2 -0
- package/dist/store/db-helpers.js.map +1 -1
- package/dist/store/migration-sqlite.js +5 -0
- package/dist/store/migration-sqlite.js.map +1 -1
- package/dist/store/sqlite-data-accessor.js +20 -28
- package/dist/store/sqlite-data-accessor.js.map +1 -1
- package/dist/store/sqlite.js +13 -2
- package/dist/store/sqlite.js.map +1 -1
- package/dist/store/task-store.js +4 -0
- package/dist/store/task-store.js.map +1 -1
- package/dist/store/tasks-schema.js +50 -20
- package/dist/store/tasks-schema.js.map +1 -1
- package/dist/tasks/add.js +87 -3
- package/dist/tasks/add.js.map +1 -1
- package/dist/tasks/complete.d.ts.map +1 -1
- package/dist/tasks/complete.js +15 -4
- package/dist/tasks/complete.js.map +1 -1
- package/dist/tasks/enforcement.d.ts.map +1 -1
- package/dist/tasks/enforcement.js +8 -1
- package/dist/tasks/enforcement.js.map +1 -1
- package/dist/tasks/epic-enforcement.d.ts +61 -0
- package/dist/tasks/epic-enforcement.d.ts.map +1 -1
- package/dist/tasks/epic-enforcement.js +294 -0
- package/dist/tasks/epic-enforcement.js.map +1 -0
- package/dist/tasks/index.js +1 -1
- package/dist/tasks/index.js.map +1 -1
- package/dist/tasks/pipeline-stage.d.ts +70 -1
- package/dist/tasks/pipeline-stage.d.ts.map +1 -1
- package/dist/tasks/pipeline-stage.js +248 -0
- package/dist/tasks/pipeline-stage.js.map +1 -0
- package/dist/tasks/update.js +28 -0
- package/dist/tasks/update.js.map +1 -1
- 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__/health-monitor.test.ts +332 -0
- package/src/agents/agent-registry.ts +394 -0
- package/src/agents/health-monitor.ts +279 -0
- package/src/agents/index.ts +24 -1
- package/src/agents/retry.ts +57 -4
- package/src/backfill/index.ts +27 -0
- package/src/bootstrap.ts +171 -30
- package/src/cleo.ts +103 -2
- package/src/config.ts +3 -3
- package/src/index.ts +1 -0
- package/src/intelligence/__tests__/impact.test.ts +165 -1
- package/src/intelligence/impact.ts +203 -0
- package/src/intelligence/index.ts +3 -0
- package/src/intelligence/types.ts +76 -0
- package/src/internal.ts +20 -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/nexus/sharing/index.ts +142 -2
- package/src/scaffold.ts +24 -2
- package/src/stats/workflow-telemetry.ts +15 -0
- package/src/store/__tests__/session-store.test.ts +43 -7
- package/src/store/__tests__/task-store.test.ts +1 -1
- package/src/store/__tests__/test-db-helper.ts +7 -3
- package/src/store/cross-db-cleanup.ts +35 -0
- package/src/tasks/__tests__/epic-enforcement.test.ts +9 -4
- package/src/tasks/__tests__/minimal-test.test.ts +2 -2
- package/src/tasks/__tests__/update.test.ts +25 -25
- package/src/tasks/complete.ts +11 -6
- package/src/tasks/enforcement.ts +6 -3
- package/src/tasks/epic-enforcement.ts +61 -0
- package/src/tasks/pipeline-stage.ts +70 -1
- package/templates/config.template.json +5 -116
- package/templates/global-config.template.json +2 -44
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* General-purpose retry utility with exponential backoff.
|
|
3
|
+
*
|
|
4
|
+
* This module provides a shared, dependency-free retry primitive for use
|
|
5
|
+
* anywhere in the CLEO core. Unlike the agent-specific retry in
|
|
6
|
+
* `agents/retry.ts`, this utility has no database coupling and is safe to
|
|
7
|
+
* import from any layer.
|
|
8
|
+
*
|
|
9
|
+
* Default schedule (3 attempts, task T040 spec):
|
|
10
|
+
* - Attempt 1: immediate (0 ms delay before retry)
|
|
11
|
+
* - Attempt 2: 2 000 ms delay before retry
|
|
12
|
+
* - Attempt 3: 4 000 ms delay before retry
|
|
13
|
+
* - After attempt 3: throw last error
|
|
14
|
+
*
|
|
15
|
+
* @module lib/retry
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* A predicate or pattern used to decide whether an error is retryable.
|
|
19
|
+
*
|
|
20
|
+
* - `RegExp` — matched against `error.message` (or `String(error)`)
|
|
21
|
+
* - `(error: unknown) => boolean` — arbitrary predicate function
|
|
22
|
+
*/
|
|
23
|
+
export type RetryablePredicate = RegExp | ((error: unknown) => boolean);
|
|
24
|
+
/**
|
|
25
|
+
* Options that control retry behavior for {@link withRetry}.
|
|
26
|
+
*/
|
|
27
|
+
export interface RetryOptions {
|
|
28
|
+
/**
|
|
29
|
+
* Maximum total number of attempts (initial + retries).
|
|
30
|
+
*
|
|
31
|
+
* @default 3
|
|
32
|
+
*/
|
|
33
|
+
maxAttempts?: number;
|
|
34
|
+
/**
|
|
35
|
+
* Delay before the second attempt in milliseconds.
|
|
36
|
+
* Each subsequent delay is `baseDelayMs * 2^(attempt - 1)`.
|
|
37
|
+
*
|
|
38
|
+
* @default 2000
|
|
39
|
+
*/
|
|
40
|
+
baseDelayMs?: number;
|
|
41
|
+
/**
|
|
42
|
+
* Upper bound on computed delay in milliseconds.
|
|
43
|
+
* Prevents unbounded growth with many retries.
|
|
44
|
+
*
|
|
45
|
+
* @default 30000
|
|
46
|
+
*/
|
|
47
|
+
maxDelayMs?: number;
|
|
48
|
+
/**
|
|
49
|
+
* Explicit list of patterns or predicates that identify retryable errors.
|
|
50
|
+
*
|
|
51
|
+
* When provided, ONLY errors matching at least one entry are retried.
|
|
52
|
+
* Errors that match none of the entries cause immediate failure.
|
|
53
|
+
*
|
|
54
|
+
* When omitted, all errors are treated as retryable (up to `maxAttempts`).
|
|
55
|
+
*/
|
|
56
|
+
retryableErrors?: ReadonlyArray<RetryablePredicate>;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Metadata attached to errors thrown after all retry attempts are exhausted.
|
|
60
|
+
*
|
|
61
|
+
* The last error from the final attempt is augmented with these fields so
|
|
62
|
+
* callers can distinguish a retry-exhausted failure from a first-attempt one.
|
|
63
|
+
*/
|
|
64
|
+
export interface RetryContext {
|
|
65
|
+
/** Total number of attempts made (always equal to `maxAttempts`). */
|
|
66
|
+
attempts: number;
|
|
67
|
+
/** Cumulative delay applied across all retry waits in milliseconds. */
|
|
68
|
+
totalDelayMs: number;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Execute an async function with automatic retry and exponential backoff.
|
|
72
|
+
*
|
|
73
|
+
* @remarks
|
|
74
|
+
* The function is called up to `maxAttempts` times. After the first failure,
|
|
75
|
+
* the utility waits `baseDelayMs` milliseconds, then retries. Each subsequent
|
|
76
|
+
* wait doubles: `baseDelayMs * 2^(attempt - 1)`, capped at `maxDelayMs`.
|
|
77
|
+
*
|
|
78
|
+
* If `retryableErrors` is supplied, only errors matching at least one entry
|
|
79
|
+
* are retried; other errors cause immediate re-throw.
|
|
80
|
+
*
|
|
81
|
+
* On final failure the original error is re-thrown. Use {@link RetryContext}
|
|
82
|
+
* fields (attached to the error) to inspect retry metadata.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* // Basic usage — 3 attempts with 0 ms / 2 000 ms / 4 000 ms delays
|
|
87
|
+
* const data = await withRetry(() => fetchFromApi());
|
|
88
|
+
*
|
|
89
|
+
* // Custom retry window — only on network errors
|
|
90
|
+
* const result = await withRetry(
|
|
91
|
+
* () => db.query(sql),
|
|
92
|
+
* {
|
|
93
|
+
* maxAttempts: 5,
|
|
94
|
+
* baseDelayMs: 500,
|
|
95
|
+
* retryableErrors: [/SQLITE_BUSY/, /database is locked/i],
|
|
96
|
+
* },
|
|
97
|
+
* );
|
|
98
|
+
* ```
|
|
99
|
+
*
|
|
100
|
+
* @typeParam T - The resolved type of the async function
|
|
101
|
+
* @param fn - Async factory that is called on each attempt.
|
|
102
|
+
* @param options - Optional retry configuration.
|
|
103
|
+
* @returns Resolved value of `fn` on success.
|
|
104
|
+
* @throws The last error thrown by `fn`, augmented with {@link RetryContext}
|
|
105
|
+
* fields (`attempts`, `totalDelayMs`).
|
|
106
|
+
*/
|
|
107
|
+
export declare function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
|
|
108
|
+
/**
|
|
109
|
+
* Compute the wait time before the next attempt.
|
|
110
|
+
*
|
|
111
|
+
* @remarks
|
|
112
|
+
* Formula: `min(baseDelayMs * 2^(attempt - 1), maxDelayMs)`.
|
|
113
|
+
* On the first retry (`attempt === 1`) the delay is `baseDelayMs * 1 = baseDelayMs`.
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```ts
|
|
117
|
+
* computeDelay(1, 2000, 30000); // 2000
|
|
118
|
+
* computeDelay(2, 2000, 30000); // 4000
|
|
119
|
+
* computeDelay(3, 2000, 30000); // 8000
|
|
120
|
+
* ```
|
|
121
|
+
*
|
|
122
|
+
* @param attempt - The 1-based attempt number that just failed.
|
|
123
|
+
* @param baseDelayMs - Base delay in milliseconds.
|
|
124
|
+
* @param maxDelayMs - Maximum allowed delay in milliseconds.
|
|
125
|
+
* @returns Delay in milliseconds before the next attempt.
|
|
126
|
+
*/
|
|
127
|
+
export declare function computeDelay(attempt: number, baseDelayMs: number, maxDelayMs: number): number;
|
|
128
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/lib/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC;AAExE;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;CACrD;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,qEAAqE;IACrE,QAAQ,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,YAAY,EAAE,MAAM,CAAC;CACtB;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CA+B3F;AAMD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAG7F"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* General-purpose retry utility with exponential backoff.
|
|
3
|
+
*
|
|
4
|
+
* This module provides a shared, dependency-free retry primitive for use
|
|
5
|
+
* anywhere in the CLEO core. Unlike the agent-specific retry in
|
|
6
|
+
* `agents/retry.ts`, this utility has no database coupling and is safe to
|
|
7
|
+
* import from any layer.
|
|
8
|
+
*
|
|
9
|
+
* Default schedule (3 attempts, task T040 spec):
|
|
10
|
+
* - Attempt 1: immediate (0 ms delay before retry)
|
|
11
|
+
* - Attempt 2: 2 000 ms delay before retry
|
|
12
|
+
* - Attempt 3: 4 000 ms delay before retry
|
|
13
|
+
* - After attempt 3: throw last error
|
|
14
|
+
*
|
|
15
|
+
* @module lib/retry
|
|
16
|
+
*/
|
|
17
|
+
// ============================================================================
|
|
18
|
+
// Public API
|
|
19
|
+
// ============================================================================
|
|
20
|
+
/**
|
|
21
|
+
* Execute an async function with automatic retry and exponential backoff.
|
|
22
|
+
*
|
|
23
|
+
* @remarks
|
|
24
|
+
* The function is called up to `maxAttempts` times. After the first failure,
|
|
25
|
+
* the utility waits `baseDelayMs` milliseconds, then retries. Each subsequent
|
|
26
|
+
* wait doubles: `baseDelayMs * 2^(attempt - 1)`, capped at `maxDelayMs`.
|
|
27
|
+
*
|
|
28
|
+
* If `retryableErrors` is supplied, only errors matching at least one entry
|
|
29
|
+
* are retried; other errors cause immediate re-throw.
|
|
30
|
+
*
|
|
31
|
+
* On final failure the original error is re-thrown. Use {@link RetryContext}
|
|
32
|
+
* fields (attached to the error) to inspect retry metadata.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* // Basic usage — 3 attempts with 0 ms / 2 000 ms / 4 000 ms delays
|
|
37
|
+
* const data = await withRetry(() => fetchFromApi());
|
|
38
|
+
*
|
|
39
|
+
* // Custom retry window — only on network errors
|
|
40
|
+
* const result = await withRetry(
|
|
41
|
+
* () => db.query(sql),
|
|
42
|
+
* {
|
|
43
|
+
* maxAttempts: 5,
|
|
44
|
+
* baseDelayMs: 500,
|
|
45
|
+
* retryableErrors: [/SQLITE_BUSY/, /database is locked/i],
|
|
46
|
+
* },
|
|
47
|
+
* );
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* @typeParam T - The resolved type of the async function
|
|
51
|
+
* @param fn - Async factory that is called on each attempt.
|
|
52
|
+
* @param options - Optional retry configuration.
|
|
53
|
+
* @returns Resolved value of `fn` on success.
|
|
54
|
+
* @throws The last error thrown by `fn`, augmented with {@link RetryContext}
|
|
55
|
+
* fields (`attempts`, `totalDelayMs`).
|
|
56
|
+
*/
|
|
57
|
+
export async function withRetry(fn, options) {
|
|
58
|
+
const maxAttempts = options?.maxAttempts ?? 3;
|
|
59
|
+
const baseDelayMs = options?.baseDelayMs ?? 2_000;
|
|
60
|
+
const maxDelayMs = options?.maxDelayMs ?? 30_000;
|
|
61
|
+
const retryableErrors = options?.retryableErrors;
|
|
62
|
+
let lastError;
|
|
63
|
+
let totalDelayMs = 0;
|
|
64
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
65
|
+
try {
|
|
66
|
+
return await fn();
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
lastError = err;
|
|
70
|
+
const isLastAttempt = attempt === maxAttempts;
|
|
71
|
+
if (isLastAttempt)
|
|
72
|
+
break;
|
|
73
|
+
// If a filter list is provided, only retry matching errors.
|
|
74
|
+
if (retryableErrors !== undefined && !isRetryable(err, retryableErrors))
|
|
75
|
+
break;
|
|
76
|
+
const delay = computeDelay(attempt, baseDelayMs, maxDelayMs);
|
|
77
|
+
totalDelayMs += delay;
|
|
78
|
+
await sleep(delay);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Augment last error with retry context before re-throwing.
|
|
82
|
+
const context = { attempts: maxAttempts, totalDelayMs };
|
|
83
|
+
augmentError(lastError, context);
|
|
84
|
+
throw lastError;
|
|
85
|
+
}
|
|
86
|
+
// ============================================================================
|
|
87
|
+
// Delay helpers (exported for unit testing)
|
|
88
|
+
// ============================================================================
|
|
89
|
+
/**
|
|
90
|
+
* Compute the wait time before the next attempt.
|
|
91
|
+
*
|
|
92
|
+
* @remarks
|
|
93
|
+
* Formula: `min(baseDelayMs * 2^(attempt - 1), maxDelayMs)`.
|
|
94
|
+
* On the first retry (`attempt === 1`) the delay is `baseDelayMs * 1 = baseDelayMs`.
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* computeDelay(1, 2000, 30000); // 2000
|
|
99
|
+
* computeDelay(2, 2000, 30000); // 4000
|
|
100
|
+
* computeDelay(3, 2000, 30000); // 8000
|
|
101
|
+
* ```
|
|
102
|
+
*
|
|
103
|
+
* @param attempt - The 1-based attempt number that just failed.
|
|
104
|
+
* @param baseDelayMs - Base delay in milliseconds.
|
|
105
|
+
* @param maxDelayMs - Maximum allowed delay in milliseconds.
|
|
106
|
+
* @returns Delay in milliseconds before the next attempt.
|
|
107
|
+
*/
|
|
108
|
+
export function computeDelay(attempt, baseDelayMs, maxDelayMs) {
|
|
109
|
+
const exponential = baseDelayMs * 2 ** (attempt - 1);
|
|
110
|
+
return Math.min(exponential, maxDelayMs);
|
|
111
|
+
}
|
|
112
|
+
// ============================================================================
|
|
113
|
+
// Internal helpers
|
|
114
|
+
// ============================================================================
|
|
115
|
+
/**
|
|
116
|
+
* Test whether an error matches at least one retryable predicate.
|
|
117
|
+
*
|
|
118
|
+
* @param err - The caught error.
|
|
119
|
+
* @param predicates - List of `RegExp` or predicate functions.
|
|
120
|
+
* @returns `true` if the error is retryable.
|
|
121
|
+
*/
|
|
122
|
+
function isRetryable(err, predicates) {
|
|
123
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
124
|
+
return predicates.some((predicate) => {
|
|
125
|
+
if (predicate instanceof RegExp)
|
|
126
|
+
return predicate.test(message);
|
|
127
|
+
return predicate(err);
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Attach `RetryContext` fields to an error value in-place when possible.
|
|
132
|
+
* Falls back gracefully for non-Error thrown values.
|
|
133
|
+
*
|
|
134
|
+
* @param err - The value to augment.
|
|
135
|
+
* @param context - Retry metadata to attach.
|
|
136
|
+
*/
|
|
137
|
+
function augmentError(err, context) {
|
|
138
|
+
if (err instanceof Error) {
|
|
139
|
+
const mutableErr = err;
|
|
140
|
+
mutableErr.attempts = context.attempts;
|
|
141
|
+
mutableErr.totalDelayMs = context.totalDelayMs;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Promisified `setTimeout` for testability.
|
|
146
|
+
*
|
|
147
|
+
* @param ms - Duration in milliseconds.
|
|
148
|
+
*/
|
|
149
|
+
function sleep(ms) {
|
|
150
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/lib/retry.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,13 +7,40 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @task T4883
|
|
9
9
|
*/
|
|
10
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* Result of a sharing status check.
|
|
12
|
+
*
|
|
13
|
+
* @remarks
|
|
14
|
+
* Provides a complete view of which `.cleo/` files are tracked vs ignored under
|
|
15
|
+
* the current sharing config, plus git sync state for Nexus multi-project visibility.
|
|
16
|
+
* The `hasGit`, `remotes`, `pendingChanges`, and `lastSync` fields are populated
|
|
17
|
+
* only when a `.cleo/.git` repo exists; otherwise they carry safe defaults.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const status = await getSharingStatus();
|
|
22
|
+
* if (status.hasGit && status.pendingChanges) {
|
|
23
|
+
* console.log('Uncommitted changes in .cleo/ — run: cleo checkpoint');
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
11
27
|
export interface SharingStatus {
|
|
12
28
|
mode: string;
|
|
13
29
|
allowlist: string[];
|
|
14
30
|
denylist: string[];
|
|
15
31
|
tracked: string[];
|
|
16
32
|
ignored: string[];
|
|
33
|
+
/** Whether the `.cleo/.git` isolated repo exists and is initialized. */
|
|
34
|
+
hasGit: boolean;
|
|
35
|
+
/** Git remote names configured in `.cleo/.git` (e.g. `['origin']`). */
|
|
36
|
+
remotes: string[];
|
|
37
|
+
/** Whether the `.cleo/.git` working tree has uncommitted changes. */
|
|
38
|
+
pendingChanges: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* ISO 8601 timestamp of the last push or pull to/from a remote, or `null`
|
|
41
|
+
* if no remote sync has ever occurred.
|
|
42
|
+
*/
|
|
43
|
+
lastSync: string | null;
|
|
17
44
|
}
|
|
18
45
|
/**
|
|
19
46
|
* Match a file path against a glob-like pattern.
|
|
@@ -23,8 +50,27 @@ export interface SharingStatus {
|
|
|
23
50
|
*/
|
|
24
51
|
export declare function matchesPattern(filePath: string, pattern: string): boolean;
|
|
25
52
|
/**
|
|
26
|
-
* Get the sharing status: which .cleo/ files are tracked vs ignored
|
|
53
|
+
* Get the sharing status: which .cleo/ files are tracked vs ignored,
|
|
54
|
+
* plus git sync state for Nexus multi-project visibility.
|
|
55
|
+
*
|
|
56
|
+
* @remarks
|
|
57
|
+
* Populates `hasGit`, `remotes`, `pendingChanges`, and `lastSync` by inspecting
|
|
58
|
+
* the `.cleo/.git` isolated repo when it exists. All git operations are
|
|
59
|
+
* non-fatal — if the repo is absent or a command fails, the fields carry safe
|
|
60
|
+
* defaults (`false`, `[]`, `null`).
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* const status = await getSharingStatus('/path/to/project');
|
|
65
|
+
* console.log(status.mode); // 'project'
|
|
66
|
+
* console.log(status.hasGit); // true
|
|
67
|
+
* console.log(status.remotes); // ['origin']
|
|
68
|
+
* console.log(status.pendingChanges); // false
|
|
69
|
+
* console.log(status.lastSync); // '2026-03-21T18:00:00.000Z'
|
|
70
|
+
* ```
|
|
71
|
+
*
|
|
27
72
|
* @task T4883
|
|
73
|
+
* @task T110
|
|
28
74
|
*/
|
|
29
75
|
export declare function getSharingStatus(cwd?: string): Promise<SharingStatus>;
|
|
30
76
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/nexus/sharing/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/nexus/sharing/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAUH;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,wEAAwE;IACxE,MAAM,EAAE,OAAO,CAAC;IAChB,uEAAuE;IACvE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,qEAAqE;IACrE,cAAc,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAMD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CA2BzE;AAqHD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA4C3E;AAkCD;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CAiCrD"}
|
|
@@ -12,6 +12,7 @@ import { readFile, writeFile } from 'node:fs/promises';
|
|
|
12
12
|
import { join, relative } from 'node:path';
|
|
13
13
|
import { loadConfig } from '../../config.js';
|
|
14
14
|
import { getCleoDirAbsolute, getProjectRoot } from '../../paths.js';
|
|
15
|
+
import { cleoGitCommand, isCleoGitInitialized } from '../../store/git-checkpoint.js';
|
|
15
16
|
/** Markers for the managed section in .gitignore. */
|
|
16
17
|
const GITIGNORE_START = '# CLEO:SHARING:START - Auto-managed by cleo sharing sync';
|
|
17
18
|
const GITIGNORE_END = '# CLEO:SHARING:END';
|
|
@@ -85,8 +86,100 @@ function collectCleoFiles(cleoDir) {
|
|
|
85
86
|
return files.sort();
|
|
86
87
|
}
|
|
87
88
|
/**
|
|
88
|
-
*
|
|
89
|
+
* Retrieve the names of git remotes configured in the `.cleo/.git` repo.
|
|
90
|
+
*
|
|
91
|
+
* @remarks
|
|
92
|
+
* Returns an empty array if the repo is not initialized or has no remotes.
|
|
93
|
+
* Errors are suppressed — callers should treat an empty array as "no remotes known".
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```typescript
|
|
97
|
+
* const remotes = await getCleoGitRemotes('/path/to/project/.cleo');
|
|
98
|
+
* // ['origin']
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
async function getCleoGitRemotes(cleoDir) {
|
|
102
|
+
const result = await cleoGitCommand(['remote'], cleoDir);
|
|
103
|
+
if (!result.success || !result.stdout)
|
|
104
|
+
return [];
|
|
105
|
+
return result.stdout
|
|
106
|
+
.split('\n')
|
|
107
|
+
.map((r) => r.trim())
|
|
108
|
+
.filter(Boolean);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Determine whether the `.cleo/.git` working tree has any uncommitted changes.
|
|
112
|
+
*
|
|
113
|
+
* @remarks
|
|
114
|
+
* Uses `git status --porcelain`. A non-empty output means pending changes exist.
|
|
115
|
+
* Returns `false` if the repo is not initialized or the command fails.
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```typescript
|
|
119
|
+
* const dirty = await hasCleoGitPendingChanges('/path/to/project/.cleo');
|
|
120
|
+
* // true if any files are modified/untracked
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
async function hasCleoGitPendingChanges(cleoDir) {
|
|
124
|
+
const result = await cleoGitCommand(['status', '--porcelain'], cleoDir);
|
|
125
|
+
if (!result.success)
|
|
126
|
+
return false;
|
|
127
|
+
return result.stdout.length > 0;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Read the ISO 8601 timestamp of the last push or pull recorded in the reflog.
|
|
131
|
+
*
|
|
132
|
+
* @remarks
|
|
133
|
+
* Scans the git reflog for `fetch` or `push` entries and returns the committer
|
|
134
|
+
* date of the most recent one. Returns `null` if no push/pull has occurred or
|
|
135
|
+
* if the repo has no commits yet.
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* ```typescript
|
|
139
|
+
* const lastSync = await getLastSyncTimestamp('/path/to/project/.cleo');
|
|
140
|
+
* // '2026-03-21T18:00:00.000Z' or null
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
async function getLastSyncTimestamp(cleoDir) {
|
|
144
|
+
// The reflog format: `%gd %gs %ci` — reflog selector, subject, committer ISO date
|
|
145
|
+
const result = await cleoGitCommand(['reflog', '--format=%gs %ci', 'HEAD'], cleoDir);
|
|
146
|
+
if (!result.success || !result.stdout)
|
|
147
|
+
return null;
|
|
148
|
+
for (const line of result.stdout.split('\n')) {
|
|
149
|
+
const trimmed = line.trim();
|
|
150
|
+
// Match lines describing a fetch or push action (e.g. "fetch origin: fast-forward")
|
|
151
|
+
if (/^(fetch|push|pull)\b/i.test(trimmed)) {
|
|
152
|
+
// The date is everything after the action description — last ISO-like token
|
|
153
|
+
const isoMatch = trimmed.match(/(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [+-]\d{4})$/);
|
|
154
|
+
if (isoMatch?.[1]) {
|
|
155
|
+
return new Date(isoMatch[1]).toISOString();
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Get the sharing status: which .cleo/ files are tracked vs ignored,
|
|
163
|
+
* plus git sync state for Nexus multi-project visibility.
|
|
164
|
+
*
|
|
165
|
+
* @remarks
|
|
166
|
+
* Populates `hasGit`, `remotes`, `pendingChanges`, and `lastSync` by inspecting
|
|
167
|
+
* the `.cleo/.git` isolated repo when it exists. All git operations are
|
|
168
|
+
* non-fatal — if the repo is absent or a command fails, the fields carry safe
|
|
169
|
+
* defaults (`false`, `[]`, `null`).
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* ```typescript
|
|
173
|
+
* const status = await getSharingStatus('/path/to/project');
|
|
174
|
+
* console.log(status.mode); // 'project'
|
|
175
|
+
* console.log(status.hasGit); // true
|
|
176
|
+
* console.log(status.remotes); // ['origin']
|
|
177
|
+
* console.log(status.pendingChanges); // false
|
|
178
|
+
* console.log(status.lastSync); // '2026-03-21T18:00:00.000Z'
|
|
179
|
+
* ```
|
|
180
|
+
*
|
|
89
181
|
* @task T4883
|
|
182
|
+
* @task T110
|
|
90
183
|
*/
|
|
91
184
|
export async function getSharingStatus(cwd) {
|
|
92
185
|
const config = await loadConfig(cwd);
|
|
@@ -106,12 +199,28 @@ export async function getSharingStatus(cwd) {
|
|
|
106
199
|
ignored.push(file);
|
|
107
200
|
}
|
|
108
201
|
}
|
|
202
|
+
// Populate git sync fields
|
|
203
|
+
const hasGit = isCleoGitInitialized(cleoDir);
|
|
204
|
+
let remotes = [];
|
|
205
|
+
let pendingChanges = false;
|
|
206
|
+
let lastSync = null;
|
|
207
|
+
if (hasGit) {
|
|
208
|
+
[remotes, pendingChanges, lastSync] = await Promise.all([
|
|
209
|
+
getCleoGitRemotes(cleoDir),
|
|
210
|
+
hasCleoGitPendingChanges(cleoDir),
|
|
211
|
+
getLastSyncTimestamp(cleoDir),
|
|
212
|
+
]);
|
|
213
|
+
}
|
|
109
214
|
return {
|
|
110
215
|
mode: sharing.mode,
|
|
111
216
|
allowlist: sharing.commitAllowlist,
|
|
112
217
|
denylist: sharing.denylist,
|
|
113
218
|
tracked,
|
|
114
219
|
ignored,
|
|
220
|
+
hasGit,
|
|
221
|
+
remotes,
|
|
222
|
+
pendingChanges,
|
|
223
|
+
lastSync,
|
|
115
224
|
};
|
|
116
225
|
}
|
|
117
226
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/nexus/sharing/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/nexus/sharing/index.ts"],"names":[],"mappings":"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"}
|
package/dist/scaffold.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
1
|
+
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"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"}
|
package/dist/scaffold.js
CHANGED
|
@@ -13,6 +13,7 @@ import { execFile } from 'node:child_process';
|
|
|
13
13
|
import { randomUUID } from 'node:crypto';
|
|
14
14
|
import { existsSync, constants as fsConstants, readFileSync, statSync } from 'node:fs';
|
|
15
15
|
import { access, mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
16
|
+
import { homedir as getHomedir } from 'node:os';
|
|
16
17
|
import { dirname, join, resolve } from 'node:path';
|
|
17
18
|
import { fileURLToPath } from 'node:url';
|
|
18
19
|
import { promisify } from 'node:util';
|
|
@@ -1121,12 +1122,31 @@ export function checkGlobalTemplates() {
|
|
|
1121
1122
|
fix: 'cleo init (or restart MCP server)',
|
|
1122
1123
|
};
|
|
1123
1124
|
}
|
|
1125
|
+
// Check version sync between XDG and legacy paths
|
|
1126
|
+
const xdgContent = readFileSync(injectionPath, 'utf-8');
|
|
1127
|
+
const xdgVersion = xdgContent.match(/^Version:\s*(.+)$/m)?.[1]?.trim();
|
|
1128
|
+
const home = getHomedir();
|
|
1129
|
+
const legacyPath = join(home, '.cleo', 'templates', 'CLEO-INJECTION.md');
|
|
1130
|
+
if (existsSync(legacyPath)) {
|
|
1131
|
+
const legacyContent = readFileSync(legacyPath, 'utf-8');
|
|
1132
|
+
const legacyVersion = legacyContent.match(/^Version:\s*(.+)$/m)?.[1]?.trim();
|
|
1133
|
+
if (legacyVersion && xdgVersion && legacyVersion !== xdgVersion) {
|
|
1134
|
+
return {
|
|
1135
|
+
id: 'global_templates',
|
|
1136
|
+
category: 'global',
|
|
1137
|
+
status: 'warning',
|
|
1138
|
+
message: `Legacy template version (${legacyVersion}) out of sync with XDG (${xdgVersion})`,
|
|
1139
|
+
details: { path: injectionPath, exists: true, xdgVersion, legacyVersion, legacyPath },
|
|
1140
|
+
fix: 'npm install -g @cleocode/cleo (reinstall syncs both paths)',
|
|
1141
|
+
};
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1124
1144
|
return {
|
|
1125
1145
|
id: 'global_templates',
|
|
1126
1146
|
category: 'global',
|
|
1127
1147
|
status: 'passed',
|
|
1128
|
-
message:
|
|
1129
|
-
details: { path: injectionPath, exists: true },
|
|
1148
|
+
message: `Global injection template present (v${xdgVersion ?? 'unknown'})`,
|
|
1149
|
+
details: { path: injectionPath, exists: true, version: xdgVersion },
|
|
1130
1150
|
fix: null,
|
|
1131
1151
|
};
|
|
1132
1152
|
}
|