@cleocode/core 2026.5.131 → 2026.5.133
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/db/index.d.ts +36 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +36 -0
- package/dist/db/index.js.map +1 -0
- package/dist/gc/daemon.d.ts +17 -8
- package/dist/gc/daemon.d.ts.map +1 -1
- package/dist/gc/daemon.js +24 -67
- package/dist/gc/daemon.js.map +1 -1
- package/dist/gc/gc-subsystem.d.ts +96 -0
- package/dist/gc/gc-subsystem.d.ts.map +1 -0
- package/dist/gc/gc-subsystem.js +186 -0
- package/dist/gc/gc-subsystem.js.map +1 -0
- package/dist/gc/index.d.ts +1 -0
- package/dist/gc/index.d.ts.map +1 -1
- package/dist/gc/index.js +1 -0
- package/dist/gc/index.js.map +1 -1
- package/dist/go/driver.d.ts +132 -0
- package/dist/go/driver.d.ts.map +1 -0
- package/dist/go/driver.js +191 -0
- package/dist/go/driver.js.map +1 -0
- package/dist/go/index.d.ts +13 -0
- package/dist/go/index.d.ts.map +1 -0
- package/dist/go/index.js +13 -0
- package/dist/go/index.js.map +1 -0
- package/dist/goal/advance-with-persist.d.ts +80 -0
- package/dist/goal/advance-with-persist.d.ts.map +1 -0
- package/dist/goal/advance-with-persist.js +105 -0
- package/dist/goal/advance-with-persist.js.map +1 -0
- package/dist/goal/arm.d.ts +61 -0
- package/dist/goal/arm.d.ts.map +1 -0
- package/dist/goal/arm.js +65 -0
- package/dist/goal/arm.js.map +1 -0
- package/dist/goal/index.d.ts +2 -0
- package/dist/goal/index.d.ts.map +1 -1
- package/dist/goal/index.js +2 -0
- package/dist/goal/index.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/orchestrate/lifecycle-ops.js +1 -1
- package/dist/orchestrate/lifecycle-ops.js.map +1 -1
- package/dist/orchestration/classify-readiness.d.ts +172 -0
- package/dist/orchestration/classify-readiness.d.ts.map +1 -0
- package/dist/orchestration/classify-readiness.js +346 -0
- package/dist/orchestration/classify-readiness.js.map +1 -0
- package/dist/orchestration/index.d.ts +2 -0
- package/dist/orchestration/index.d.ts.map +1 -1
- package/dist/orchestration/index.js +1 -0
- package/dist/orchestration/index.js.map +1 -1
- package/dist/output.d.ts +2 -0
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +59 -1
- package/dist/output.js.map +1 -1
- package/dist/release/pr-evidence.d.ts +4 -3
- package/dist/release/pr-evidence.d.ts.map +1 -1
- package/dist/release/pr-evidence.js +4 -3
- package/dist/release/pr-evidence.js.map +1 -1
- package/dist/sagas/index.d.ts +1 -0
- package/dist/sagas/index.d.ts.map +1 -1
- package/dist/sagas/index.js +1 -0
- package/dist/sagas/index.js.map +1 -1
- package/dist/sagas/next.d.ts +77 -0
- package/dist/sagas/next.d.ts.map +1 -0
- package/dist/sagas/next.js +159 -0
- package/dist/sagas/next.js.map +1 -0
- package/dist/sentient/daemon-entry.d.ts +6 -0
- package/dist/sentient/daemon-entry.d.ts.map +1 -1
- package/dist/sentient/daemon-entry.js +10 -1
- package/dist/sentient/daemon-entry.js.map +1 -1
- package/dist/sentient/daemon.d.ts +30 -0
- package/dist/sentient/daemon.d.ts.map +1 -1
- package/dist/sentient/daemon.js +12 -2
- package/dist/sentient/daemon.js.map +1 -1
- package/dist/sentient/index.d.ts +2 -0
- package/dist/sentient/index.d.ts.map +1 -1
- package/dist/sentient/index.js +5 -0
- package/dist/sentient/index.js.map +1 -1
- package/dist/sentient/propose-tick.d.ts +101 -0
- package/dist/sentient/propose-tick.d.ts.map +1 -1
- package/dist/sentient/propose-tick.js +284 -0
- package/dist/sentient/propose-tick.js.map +1 -1
- package/dist/sentient/tick.d.ts +23 -0
- package/dist/sentient/tick.d.ts.map +1 -1
- package/dist/sentient/tick.js +91 -21
- package/dist/sentient/tick.js.map +1 -1
- package/dist/store/dual-scope-db.d.ts +183 -0
- package/dist/store/dual-scope-db.d.ts.map +1 -0
- package/dist/store/dual-scope-db.js +315 -0
- package/dist/store/dual-scope-db.js.map +1 -0
- package/dist/store/open-cleo-db.d.ts +51 -4
- package/dist/store/open-cleo-db.d.ts.map +1 -1
- package/dist/store/open-cleo-db.js +56 -2
- package/dist/store/open-cleo-db.js.map +1 -1
- package/dist/store/schema/cleo-global/nexus.d.ts +1 -1
- package/dist/store/schema/cleo-global/signaldock.d.ts +1 -1
- package/dist/store/schema/cleo-shared/brain.d.ts +1 -1
- package/dist/tasks/add.d.ts.map +1 -1
- package/dist/tasks/add.js +16 -2
- package/dist/tasks/add.js.map +1 -1
- package/dist/tasks/evidence.d.ts +3 -2
- package/dist/tasks/evidence.d.ts.map +1 -1
- package/dist/tasks/evidence.js.map +1 -1
- package/dist/verification/verify-tools.d.ts +164 -0
- package/dist/verification/verify-tools.d.ts.map +1 -0
- package/dist/verification/verify-tools.js +236 -0
- package/dist/verification/verify-tools.js.map +1 -0
- package/package.json +16 -11
- package/templates/CLEO-INJECTION.md +3 -2
- package/templates/workflows/release-prepare.yml.tmpl +86 -7
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@cleocode/core/db` subpath export — typed dual-scope SQLite client.
|
|
3
|
+
*
|
|
4
|
+
* This barrel re-exports the public API of the dual-scope DB chokepoint
|
|
5
|
+
* implemented in `packages/core/src/store/dual-scope-db.ts` as the
|
|
6
|
+
* `@cleocode/core/db` subpath module.
|
|
7
|
+
*
|
|
8
|
+
* ## What is exported
|
|
9
|
+
*
|
|
10
|
+
* - {@link openDualScopeDb} — open (or re-use) the consolidated `cleo.db`
|
|
11
|
+
* for either scope.
|
|
12
|
+
* - {@link DualScopeDbHandle} — handle type returned by `openDualScopeDb`.
|
|
13
|
+
* - {@link DualScope} — the `'project' | 'global'` scope union.
|
|
14
|
+
* - {@link CleoProjectDb} — typed Drizzle handle for the project scope.
|
|
15
|
+
* - {@link CleoGlobalDb} — typed Drizzle handle for the global scope.
|
|
16
|
+
* - {@link resolveDualScopeDbPath} — resolve the absolute DB file path.
|
|
17
|
+
* - {@link insertIdempotent} — retry-safe insert (ON CONFLICT DO NOTHING).
|
|
18
|
+
* - {@link upsertIdempotent} — retry-safe upsert (ON CONFLICT DO UPDATE).
|
|
19
|
+
* - {@link _resetDualScopeDbCache} — test helper: clear singleton cache.
|
|
20
|
+
*
|
|
21
|
+
* ## Usage
|
|
22
|
+
*
|
|
23
|
+
* ```ts
|
|
24
|
+
* import { openDualScopeDb, insertIdempotent } from '@cleocode/core/db';
|
|
25
|
+
*
|
|
26
|
+
* const proj = await openDualScopeDb('project', process.cwd());
|
|
27
|
+
* const global = await openDualScopeDb('global');
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @packageDocumentation
|
|
31
|
+
* @task T11514 (E4-T3)
|
|
32
|
+
* @epic T11247 (E4)
|
|
33
|
+
* @saga T11242 (SG-DB-SUBSTRATE-V2)
|
|
34
|
+
*/
|
|
35
|
+
export { _resetDualScopeDbCache, type CleoGlobalDb, type CleoProjectDb, type DualScope, type DualScopeDbHandle, insertIdempotent, openDualScopeDb, resolveDualScopeDbPath, upsertIdempotent, } from '../store/dual-scope-db.js';
|
|
36
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EACL,sBAAsB,EACtB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,gBAAgB,EAChB,eAAe,EACf,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,2BAA2B,CAAC"}
|
package/dist/db/index.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@cleocode/core/db` subpath export — typed dual-scope SQLite client.
|
|
3
|
+
*
|
|
4
|
+
* This barrel re-exports the public API of the dual-scope DB chokepoint
|
|
5
|
+
* implemented in `packages/core/src/store/dual-scope-db.ts` as the
|
|
6
|
+
* `@cleocode/core/db` subpath module.
|
|
7
|
+
*
|
|
8
|
+
* ## What is exported
|
|
9
|
+
*
|
|
10
|
+
* - {@link openDualScopeDb} — open (or re-use) the consolidated `cleo.db`
|
|
11
|
+
* for either scope.
|
|
12
|
+
* - {@link DualScopeDbHandle} — handle type returned by `openDualScopeDb`.
|
|
13
|
+
* - {@link DualScope} — the `'project' | 'global'` scope union.
|
|
14
|
+
* - {@link CleoProjectDb} — typed Drizzle handle for the project scope.
|
|
15
|
+
* - {@link CleoGlobalDb} — typed Drizzle handle for the global scope.
|
|
16
|
+
* - {@link resolveDualScopeDbPath} — resolve the absolute DB file path.
|
|
17
|
+
* - {@link insertIdempotent} — retry-safe insert (ON CONFLICT DO NOTHING).
|
|
18
|
+
* - {@link upsertIdempotent} — retry-safe upsert (ON CONFLICT DO UPDATE).
|
|
19
|
+
* - {@link _resetDualScopeDbCache} — test helper: clear singleton cache.
|
|
20
|
+
*
|
|
21
|
+
* ## Usage
|
|
22
|
+
*
|
|
23
|
+
* ```ts
|
|
24
|
+
* import { openDualScopeDb, insertIdempotent } from '@cleocode/core/db';
|
|
25
|
+
*
|
|
26
|
+
* const proj = await openDualScopeDb('project', process.cwd());
|
|
27
|
+
* const global = await openDualScopeDb('global');
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @packageDocumentation
|
|
31
|
+
* @task T11514 (E4-T3)
|
|
32
|
+
* @epic T11247 (E4)
|
|
33
|
+
* @saga T11242 (SG-DB-SUBSTRATE-V2)
|
|
34
|
+
*/
|
|
35
|
+
export { _resetDualScopeDbCache, insertIdempotent, openDualScopeDb, resolveDualScopeDbPath, upsertIdempotent, } from '../store/dual-scope-db.js';
|
|
36
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EACL,sBAAsB,EAKtB,gBAAgB,EAChB,eAAe,EACf,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,2BAA2B,CAAC"}
|
package/dist/gc/daemon.d.ts
CHANGED
|
@@ -8,13 +8,21 @@
|
|
|
8
8
|
* - Crash recovery via `.cleo/gc-state.json` startup-check
|
|
9
9
|
* - node-cron v4 for scheduling (zero runtime deps, cross-platform)
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
11
|
+
* R5 migration (T11256)
|
|
12
|
+
* ----------------------
|
|
13
|
+
* The standalone cron loop that previously lived inside `bootstrapDaemon` has
|
|
14
|
+
* been migrated to the `@cleocode/runtime` subsystem framework
|
|
15
|
+
* (`gc-subsystem.ts`). `bootstrapDaemon` now delegates to
|
|
16
|
+
* `createGcSubsystem(cleoDir).start()` so the same startup algorithm (crash
|
|
17
|
+
* recovery → missed-run recovery → cron schedule) is expressed once, in the
|
|
18
|
+
* `Subsystem<GcSubsystemContext>` shape, and the standalone entry-point
|
|
19
|
+
* (`daemon-entry.ts`) drives it through the uniform lifecycle.
|
|
17
20
|
*
|
|
21
|
+
* The spawn helpers (`spawnGCDaemon`, `stopGCDaemon`, `getGCDaemonStatus`) are
|
|
22
|
+
* preserved unchanged — they are the parent-process-side interface and are
|
|
23
|
+
* unaffected by the internal lifecycle migration.
|
|
24
|
+
*
|
|
25
|
+
* @see packages/core/src/gc/gc-subsystem.ts — subsystem adapter (R5-T1)
|
|
18
26
|
* @see ADR-047 — Autonomous GC and Disk Safety
|
|
19
27
|
* @see T751 §2.2 for sidecar daemon pattern rationale
|
|
20
28
|
* @task T731
|
|
@@ -23,8 +31,9 @@
|
|
|
23
31
|
/**
|
|
24
32
|
* Bootstrap the GC daemon process.
|
|
25
33
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
34
|
+
* Delegates to `createGcSubsystem(cleoDir).start()` which performs crash
|
|
35
|
+
* recovery, missed-run recovery, and schedules future GC runs — the
|
|
36
|
+
* standalone cron loop no longer lives here (R5 migration, T11256).
|
|
28
37
|
*
|
|
29
38
|
* @param cleoDir - Absolute path to the `.cleo/` directory
|
|
30
39
|
*/
|
package/dist/gc/daemon.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/gc/daemon.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/gc/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAeH;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOpE;AAMD;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmCpE;AAED;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAgCnE;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAChE,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,gBAAgB,EAAE,OAAO,CAAC;CAC3B,CAAC,CAsBD"}
|
package/dist/gc/daemon.js
CHANGED
|
@@ -8,13 +8,21 @@
|
|
|
8
8
|
* - Crash recovery via `.cleo/gc-state.json` startup-check
|
|
9
9
|
* - node-cron v4 for scheduling (zero runtime deps, cross-platform)
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
11
|
+
* R5 migration (T11256)
|
|
12
|
+
* ----------------------
|
|
13
|
+
* The standalone cron loop that previously lived inside `bootstrapDaemon` has
|
|
14
|
+
* been migrated to the `@cleocode/runtime` subsystem framework
|
|
15
|
+
* (`gc-subsystem.ts`). `bootstrapDaemon` now delegates to
|
|
16
|
+
* `createGcSubsystem(cleoDir).start()` so the same startup algorithm (crash
|
|
17
|
+
* recovery → missed-run recovery → cron schedule) is expressed once, in the
|
|
18
|
+
* `Subsystem<GcSubsystemContext>` shape, and the standalone entry-point
|
|
19
|
+
* (`daemon-entry.ts`) drives it through the uniform lifecycle.
|
|
17
20
|
*
|
|
21
|
+
* The spawn helpers (`spawnGCDaemon`, `stopGCDaemon`, `getGCDaemonStatus`) are
|
|
22
|
+
* preserved unchanged — they are the parent-process-side interface and are
|
|
23
|
+
* unaffected by the internal lifecycle migration.
|
|
24
|
+
*
|
|
25
|
+
* @see packages/core/src/gc/gc-subsystem.ts — subsystem adapter (R5-T1)
|
|
18
26
|
* @see ADR-047 — Autonomous GC and Disk Safety
|
|
19
27
|
* @see T751 §2.2 for sidecar daemon pattern rationale
|
|
20
28
|
* @task T731
|
|
@@ -26,78 +34,27 @@ import { createWriteStream } from 'node:fs';
|
|
|
26
34
|
import { mkdir } from 'node:fs/promises';
|
|
27
35
|
import { join } from 'node:path';
|
|
28
36
|
import { fileURLToPath } from 'node:url';
|
|
29
|
-
import
|
|
30
|
-
import { runGC } from './runner.js';
|
|
37
|
+
import { createGcSubsystem } from './gc-subsystem.js';
|
|
31
38
|
import { patchGCState, readGCState } from './state.js';
|
|
32
39
|
// ---------------------------------------------------------------------------
|
|
33
|
-
// Constants
|
|
34
|
-
// ---------------------------------------------------------------------------
|
|
35
|
-
/** Cron expression: daily at 03:00 UTC. */
|
|
36
|
-
const GC_CRON_EXPR = '0 3 * * *';
|
|
37
|
-
/** Interval for missed-run recovery check (24 hours in ms). */
|
|
38
|
-
const GC_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
39
|
-
// ---------------------------------------------------------------------------
|
|
40
40
|
// Daemon Bootstrap (runs when this module is executed as a standalone script)
|
|
41
41
|
// ---------------------------------------------------------------------------
|
|
42
42
|
/**
|
|
43
43
|
* Bootstrap the GC daemon process.
|
|
44
44
|
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
45
|
+
* Delegates to `createGcSubsystem(cleoDir).start()` which performs crash
|
|
46
|
+
* recovery, missed-run recovery, and schedules future GC runs — the
|
|
47
|
+
* standalone cron loop no longer lives here (R5 migration, T11256).
|
|
47
48
|
*
|
|
48
49
|
* @param cleoDir - Absolute path to the `.cleo/` directory
|
|
49
50
|
*/
|
|
50
51
|
export async function bootstrapDaemon(cleoDir) {
|
|
51
|
-
const
|
|
52
|
-
//
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const state = await readGCState(statePath);
|
|
58
|
-
// Step 1: Crash recovery — resume pending prune from prior run
|
|
59
|
-
if (state.pendingPrune && state.pendingPrune.length > 0) {
|
|
60
|
-
try {
|
|
61
|
-
await runGC({ cleoDir, resumeFrom: state.pendingPrune });
|
|
62
|
-
}
|
|
63
|
-
catch {
|
|
64
|
-
// Crash recovery failure is non-fatal; continue with scheduled runs
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
// Step 2: Missed-run recovery — if last run was > 24h ago, run immediately
|
|
68
|
-
const lastRunTs = state.lastRunAt ? new Date(state.lastRunAt).getTime() : 0;
|
|
69
|
-
const elapsed = Date.now() - lastRunTs;
|
|
70
|
-
if (elapsed > GC_INTERVAL_MS) {
|
|
71
|
-
try {
|
|
72
|
-
await runGC({ cleoDir });
|
|
73
|
-
}
|
|
74
|
-
catch {
|
|
75
|
-
// Immediate GC failure is non-fatal; cron will retry next cycle
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
// Step 3: Schedule future runs via node-cron
|
|
79
|
-
// noOverlap: true prevents double-runs if a previous run exceeds 24h
|
|
80
|
-
cron.schedule(GC_CRON_EXPR, async () => {
|
|
81
|
-
try {
|
|
82
|
-
await runGC({ cleoDir });
|
|
83
|
-
}
|
|
84
|
-
catch {
|
|
85
|
-
// Log failures via stderr (already redirected to gc.log by spawn)
|
|
86
|
-
const state2 = await readGCState(statePath);
|
|
87
|
-
await patchGCState(statePath, {
|
|
88
|
-
consecutiveFailures: state2.consecutiveFailures + 1,
|
|
89
|
-
lastRunResult: 'failed',
|
|
90
|
-
escalationNeeded: state2.consecutiveFailures + 1 >= 3,
|
|
91
|
-
escalationReason: state2.consecutiveFailures + 1 >= 3
|
|
92
|
-
? `GC daemon: ${state2.consecutiveFailures + 1} consecutive failures. Check logs.`
|
|
93
|
-
: state2.escalationReason,
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
}, {
|
|
97
|
-
timezone: 'UTC',
|
|
98
|
-
noOverlap: true,
|
|
99
|
-
name: 'cleo-gc',
|
|
100
|
-
});
|
|
52
|
+
const subsystem = createGcSubsystem(cleoDir);
|
|
53
|
+
// start() handles crash recovery, missed-run recovery, and cron scheduling.
|
|
54
|
+
// The returned context (cron task handle) keeps the cron alive for the
|
|
55
|
+
// lifetime of this process — we intentionally do not call shutdown() so the
|
|
56
|
+
// daemon continues running until the process receives SIGTERM.
|
|
57
|
+
await subsystem.start();
|
|
101
58
|
}
|
|
102
59
|
// ---------------------------------------------------------------------------
|
|
103
60
|
// Spawn Helpers (called by `cleo daemon start` in the parent CLI process)
|
package/dist/gc/daemon.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/gc/daemon.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/gc/daemon.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GC daemon expressed as a supervised daemon subsystem.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the GC bootstrap logic (`bootstrapDaemon`, crash recovery, missed-run
|
|
5
|
+
* recovery, and the node-cron schedule) in the uniform
|
|
6
|
+
* `start → healthProbe → shutdown` lifecycle from `@cleocode/contracts/daemon`
|
|
7
|
+
* so the `@cleocode/runtime` `SubsystemRegistry` can drive it identically to
|
|
8
|
+
* every other long-running concern (Studio supervision, the web server, …).
|
|
9
|
+
*
|
|
10
|
+
* Design constraints
|
|
11
|
+
* ------------------
|
|
12
|
+
* `@cleocode/core` CANNOT depend on `@cleocode/runtime` (runtime already
|
|
13
|
+
* depends on core). To remain dependency-cycle free this module imports only
|
|
14
|
+
* the pure type contracts from `@cleocode/contracts` and returns a plain
|
|
15
|
+
* frozen object that satisfies the `Subsystem<GcSubsystemContext>` interface
|
|
16
|
+
* without calling `defineSubsystem()` (a runtime-layer factory). A caller that
|
|
17
|
+
* holds a `SubsystemRegistry` (from `@cleocode/runtime/daemon`) simply calls
|
|
18
|
+
* `registry.register(createGcSubsystem(cleoDir))` — the frozen shape is
|
|
19
|
+
* identical to what `defineSubsystem` returns and the registry types accept it.
|
|
20
|
+
*
|
|
21
|
+
* Thread-through context
|
|
22
|
+
* ----------------------
|
|
23
|
+
* `start()` returns a {@link GcSubsystemContext} that is threaded into
|
|
24
|
+
* `shutdown()` by the registry (same pattern as `GatewaySubsystemContext`
|
|
25
|
+
* in `@cleocode/runtime/gateway`). This lets `shutdown()` cancel the exact
|
|
26
|
+
* cron task that `start()` scheduled without requiring module-level mutable
|
|
27
|
+
* state.
|
|
28
|
+
*
|
|
29
|
+
* @see packages/core/src/gc/daemon.ts — standalone bootstrap / spawn helpers
|
|
30
|
+
* @see packages/runtime/src/daemon/define-subsystem.ts — `defineSubsystem` factory
|
|
31
|
+
* @see packages/runtime/src/gateway/daemon-subsystem.ts — reference implementation
|
|
32
|
+
*
|
|
33
|
+
* @packageDocumentation
|
|
34
|
+
* @module @cleocode/core/gc
|
|
35
|
+
*
|
|
36
|
+
* @task T11503 (R5-T1)
|
|
37
|
+
* @task T11504 (R5-T2)
|
|
38
|
+
* @epic T11256
|
|
39
|
+
* @saga T11243 SG-RUNTIME-UNIFICATION
|
|
40
|
+
*/
|
|
41
|
+
import type { Subsystem } from '@cleocode/contracts';
|
|
42
|
+
/**
|
|
43
|
+
* The live context `start()` returns and the registry threads into
|
|
44
|
+
* `shutdown()`. Carries the scheduled cron task so `shutdown()` can destroy
|
|
45
|
+
* exactly the task that `start()` created.
|
|
46
|
+
*/
|
|
47
|
+
export interface GcSubsystemContext {
|
|
48
|
+
/** The OS pid of this daemon process (set at subsystem start). */
|
|
49
|
+
readonly pid: number;
|
|
50
|
+
/** The ISO-8601 timestamp when this subsystem started. */
|
|
51
|
+
readonly startedAt: string;
|
|
52
|
+
/**
|
|
53
|
+
* The scheduled cron task. `ScheduledTask` is the node-cron return value.
|
|
54
|
+
* Typed as the minimal destroy surface so callers do not need to import
|
|
55
|
+
* node-cron types.
|
|
56
|
+
*/
|
|
57
|
+
readonly cronTask: {
|
|
58
|
+
destroy: () => void;
|
|
59
|
+
};
|
|
60
|
+
/** Count of GC runs performed since subsystem start. */
|
|
61
|
+
runs: number;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Create a GC cron-daemon expressed as a uniform daemon subsystem.
|
|
65
|
+
*
|
|
66
|
+
* The returned object is a frozen `Subsystem<GcSubsystemContext>` that any
|
|
67
|
+
* `SubsystemRegistry` (from `@cleocode/runtime/daemon`) can `register()`.
|
|
68
|
+
*
|
|
69
|
+
* Lifecycle
|
|
70
|
+
* ---------
|
|
71
|
+
* - `start(cleoDir)` — reads gc-state.json, performs crash recovery
|
|
72
|
+
* (resumes `pendingPrune` if non-empty), performs missed-run recovery (runs
|
|
73
|
+
* GC immediately if elapsed > 24 h), then schedules the daily cron job.
|
|
74
|
+
* Returns a {@link GcSubsystemContext} for health-probe and shutdown.
|
|
75
|
+
* - `healthProbe()` — reports a single {@link SubsystemHealth} row keyed on
|
|
76
|
+
* `child_id: 'gc'`; `running` while the cron task is active, with a `detail`
|
|
77
|
+
* summarising run count and last-run timestamp.
|
|
78
|
+
* - `shutdown(context)` — destroys the cron task so the daemon process can
|
|
79
|
+
* exit cleanly.
|
|
80
|
+
*
|
|
81
|
+
* @param cleoDir - Absolute path to the `.cleo/` directory for this project.
|
|
82
|
+
* @returns A frozen `Subsystem<GcSubsystemContext>`.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* // In the daemon process:
|
|
87
|
+
* import { SubsystemRegistry } from '@cleocode/runtime/daemon';
|
|
88
|
+
* import { createGcSubsystem } from '@cleocode/core/gc/gc-subsystem.js';
|
|
89
|
+
*
|
|
90
|
+
* const registry = new SubsystemRegistry();
|
|
91
|
+
* registry.register(createGcSubsystem('/home/user/.local/share/cleo/project/abc/.cleo'));
|
|
92
|
+
* await registry.startAll();
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
export declare function createGcSubsystem(cleoDir: string): Subsystem<GcSubsystemContext>;
|
|
96
|
+
//# sourceMappingURL=gc-subsystem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gc-subsystem.d.ts","sourceRoot":"","sources":["../../src/gc/gc-subsystem.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAmC,MAAM,qBAAqB,CAAC;AAmBtF;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,kEAAkE;IAClE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE;QAAE,OAAO,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC;IAC3C,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;CACd;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC,kBAAkB,CAAC,CA+GhF"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GC daemon expressed as a supervised daemon subsystem.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the GC bootstrap logic (`bootstrapDaemon`, crash recovery, missed-run
|
|
5
|
+
* recovery, and the node-cron schedule) in the uniform
|
|
6
|
+
* `start → healthProbe → shutdown` lifecycle from `@cleocode/contracts/daemon`
|
|
7
|
+
* so the `@cleocode/runtime` `SubsystemRegistry` can drive it identically to
|
|
8
|
+
* every other long-running concern (Studio supervision, the web server, …).
|
|
9
|
+
*
|
|
10
|
+
* Design constraints
|
|
11
|
+
* ------------------
|
|
12
|
+
* `@cleocode/core` CANNOT depend on `@cleocode/runtime` (runtime already
|
|
13
|
+
* depends on core). To remain dependency-cycle free this module imports only
|
|
14
|
+
* the pure type contracts from `@cleocode/contracts` and returns a plain
|
|
15
|
+
* frozen object that satisfies the `Subsystem<GcSubsystemContext>` interface
|
|
16
|
+
* without calling `defineSubsystem()` (a runtime-layer factory). A caller that
|
|
17
|
+
* holds a `SubsystemRegistry` (from `@cleocode/runtime/daemon`) simply calls
|
|
18
|
+
* `registry.register(createGcSubsystem(cleoDir))` — the frozen shape is
|
|
19
|
+
* identical to what `defineSubsystem` returns and the registry types accept it.
|
|
20
|
+
*
|
|
21
|
+
* Thread-through context
|
|
22
|
+
* ----------------------
|
|
23
|
+
* `start()` returns a {@link GcSubsystemContext} that is threaded into
|
|
24
|
+
* `shutdown()` by the registry (same pattern as `GatewaySubsystemContext`
|
|
25
|
+
* in `@cleocode/runtime/gateway`). This lets `shutdown()` cancel the exact
|
|
26
|
+
* cron task that `start()` scheduled without requiring module-level mutable
|
|
27
|
+
* state.
|
|
28
|
+
*
|
|
29
|
+
* @see packages/core/src/gc/daemon.ts — standalone bootstrap / spawn helpers
|
|
30
|
+
* @see packages/runtime/src/daemon/define-subsystem.ts — `defineSubsystem` factory
|
|
31
|
+
* @see packages/runtime/src/gateway/daemon-subsystem.ts — reference implementation
|
|
32
|
+
*
|
|
33
|
+
* @packageDocumentation
|
|
34
|
+
* @module @cleocode/core/gc
|
|
35
|
+
*
|
|
36
|
+
* @task T11503 (R5-T1)
|
|
37
|
+
* @task T11504 (R5-T2)
|
|
38
|
+
* @epic T11256
|
|
39
|
+
* @saga T11243 SG-RUNTIME-UNIFICATION
|
|
40
|
+
*/
|
|
41
|
+
import { join } from 'node:path';
|
|
42
|
+
import cron from 'node-cron';
|
|
43
|
+
import { runGC } from './runner.js';
|
|
44
|
+
import { patchGCState, readGCState } from './state.js';
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// Constants (mirrors daemon.ts — single authority is retained in daemon.ts)
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
/** Cron expression: daily at 03:00 UTC. Kept in sync with daemon.ts. */
|
|
49
|
+
const GC_CRON_EXPR = '0 3 * * *';
|
|
50
|
+
/** Interval for missed-run recovery check (24 hours in ms). */
|
|
51
|
+
const GC_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
// Factory
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
/**
|
|
56
|
+
* Create a GC cron-daemon expressed as a uniform daemon subsystem.
|
|
57
|
+
*
|
|
58
|
+
* The returned object is a frozen `Subsystem<GcSubsystemContext>` that any
|
|
59
|
+
* `SubsystemRegistry` (from `@cleocode/runtime/daemon`) can `register()`.
|
|
60
|
+
*
|
|
61
|
+
* Lifecycle
|
|
62
|
+
* ---------
|
|
63
|
+
* - `start(cleoDir)` — reads gc-state.json, performs crash recovery
|
|
64
|
+
* (resumes `pendingPrune` if non-empty), performs missed-run recovery (runs
|
|
65
|
+
* GC immediately if elapsed > 24 h), then schedules the daily cron job.
|
|
66
|
+
* Returns a {@link GcSubsystemContext} for health-probe and shutdown.
|
|
67
|
+
* - `healthProbe()` — reports a single {@link SubsystemHealth} row keyed on
|
|
68
|
+
* `child_id: 'gc'`; `running` while the cron task is active, with a `detail`
|
|
69
|
+
* summarising run count and last-run timestamp.
|
|
70
|
+
* - `shutdown(context)` — destroys the cron task so the daemon process can
|
|
71
|
+
* exit cleanly.
|
|
72
|
+
*
|
|
73
|
+
* @param cleoDir - Absolute path to the `.cleo/` directory for this project.
|
|
74
|
+
* @returns A frozen `Subsystem<GcSubsystemContext>`.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* // In the daemon process:
|
|
79
|
+
* import { SubsystemRegistry } from '@cleocode/runtime/daemon';
|
|
80
|
+
* import { createGcSubsystem } from '@cleocode/core/gc/gc-subsystem.js';
|
|
81
|
+
*
|
|
82
|
+
* const registry = new SubsystemRegistry();
|
|
83
|
+
* registry.register(createGcSubsystem('/home/user/.local/share/cleo/project/abc/.cleo'));
|
|
84
|
+
* await registry.startAll();
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export function createGcSubsystem(cleoDir) {
|
|
88
|
+
const statePath = join(cleoDir, 'gc-state.json');
|
|
89
|
+
// Closure-held live context so `healthProbe()` (which receives no arguments
|
|
90
|
+
// per the Subsystem contract) can read the current state.
|
|
91
|
+
let live;
|
|
92
|
+
const subsystem = {
|
|
93
|
+
name: 'gc',
|
|
94
|
+
async start() {
|
|
95
|
+
// Register daemon PID in state file
|
|
96
|
+
await patchGCState(statePath, {
|
|
97
|
+
daemonPid: process.pid,
|
|
98
|
+
daemonStartedAt: new Date().toISOString(),
|
|
99
|
+
});
|
|
100
|
+
const state = await readGCState(statePath);
|
|
101
|
+
let runs = 0;
|
|
102
|
+
// Step 1: Crash recovery — resume pending prune from prior run
|
|
103
|
+
if (state.pendingPrune && state.pendingPrune.length > 0) {
|
|
104
|
+
try {
|
|
105
|
+
await runGC({ cleoDir, resumeFrom: state.pendingPrune });
|
|
106
|
+
runs += 1;
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// Crash-recovery failure is non-fatal; continue with scheduled runs
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// Step 2: Missed-run recovery — if last run was > 24 h ago, run immediately
|
|
113
|
+
const lastRunTs = state.lastRunAt ? new Date(state.lastRunAt).getTime() : 0;
|
|
114
|
+
const elapsed = Date.now() - lastRunTs;
|
|
115
|
+
if (elapsed > GC_INTERVAL_MS) {
|
|
116
|
+
try {
|
|
117
|
+
await runGC({ cleoDir });
|
|
118
|
+
runs += 1;
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
// Immediate GC failure is non-fatal; cron will retry next cycle
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Step 3: Schedule future runs via node-cron
|
|
125
|
+
// noOverlap: true prevents double-runs if a previous run exceeds 24 h
|
|
126
|
+
const cronTask = cron.schedule(GC_CRON_EXPR, async () => {
|
|
127
|
+
try {
|
|
128
|
+
await runGC({ cleoDir });
|
|
129
|
+
if (live !== undefined) {
|
|
130
|
+
live.runs += 1;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
// Log failures via stderr (redirected to gc.log by spawn)
|
|
135
|
+
const currentState = await readGCState(statePath);
|
|
136
|
+
await patchGCState(statePath, {
|
|
137
|
+
consecutiveFailures: currentState.consecutiveFailures + 1,
|
|
138
|
+
lastRunResult: 'failed',
|
|
139
|
+
escalationNeeded: currentState.consecutiveFailures + 1 >= 3,
|
|
140
|
+
escalationReason: currentState.consecutiveFailures + 1 >= 3
|
|
141
|
+
? `GC daemon: ${currentState.consecutiveFailures + 1} consecutive failures. Check logs.`
|
|
142
|
+
: currentState.escalationReason,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}, {
|
|
146
|
+
timezone: 'UTC',
|
|
147
|
+
noOverlap: true,
|
|
148
|
+
name: 'cleo-gc',
|
|
149
|
+
});
|
|
150
|
+
const context = {
|
|
151
|
+
pid: process.pid,
|
|
152
|
+
startedAt: new Date().toISOString(),
|
|
153
|
+
cronTask,
|
|
154
|
+
runs,
|
|
155
|
+
};
|
|
156
|
+
live = context;
|
|
157
|
+
return context;
|
|
158
|
+
},
|
|
159
|
+
healthProbe() {
|
|
160
|
+
if (live === undefined) {
|
|
161
|
+
const stopped = 'stopped';
|
|
162
|
+
return {
|
|
163
|
+
child_id: 'gc',
|
|
164
|
+
pid: 0,
|
|
165
|
+
state: stopped,
|
|
166
|
+
restart_count: 0,
|
|
167
|
+
detail: 'gc subsystem not started',
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
const running = 'running';
|
|
171
|
+
return {
|
|
172
|
+
child_id: 'gc',
|
|
173
|
+
pid: live.pid,
|
|
174
|
+
state: running,
|
|
175
|
+
restart_count: live.runs,
|
|
176
|
+
detail: `runs=${live.runs} startedAt=${live.startedAt}`,
|
|
177
|
+
};
|
|
178
|
+
},
|
|
179
|
+
shutdown(context) {
|
|
180
|
+
context.cronTask.destroy();
|
|
181
|
+
live = undefined;
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
return Object.freeze(subsystem);
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=gc-subsystem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gc-subsystem.js","sourceRoot":"","sources":["../../src/gc/gc-subsystem.ts"],"names":[],"mappings":"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"}
|
package/dist/gc/index.d.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
export { auditOrphanTempDirs, auditOrphanWorktrees, } from '../validation/doctor/checks.js';
|
|
11
11
|
export * from './daemon.js';
|
|
12
|
+
export * from './gc-subsystem.js';
|
|
12
13
|
export * from './runner.js';
|
|
13
14
|
export * from './state.js';
|
|
14
15
|
export * from './transcript.js';
|
package/dist/gc/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/gc/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EACL,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,gCAAgC,CAAC;AACxC,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/gc/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EACL,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,gCAAgC,CAAC;AACxC,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC"}
|
package/dist/gc/index.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
// Read-only audit counterparts to pruneOrphanWorktrees / pruneOrphanTempDirs.
|
|
12
12
|
export { auditOrphanTempDirs, auditOrphanWorktrees, } from '../validation/doctor/checks.js';
|
|
13
13
|
export * from './daemon.js';
|
|
14
|
+
export * from './gc-subsystem.js';
|
|
14
15
|
export * from './runner.js';
|
|
15
16
|
export * from './state.js';
|
|
16
17
|
export * from './transcript.js';
|
package/dist/gc/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gc/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,yFAAyF;AACzF,8EAA8E;AAC9E,OAAO,EACL,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,gCAAgC,CAAC;AACxC,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gc/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,yFAAyF;AACzF,8EAA8E;AAC9E,OAAO,EACL,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,gCAAgC,CAAC;AACxC,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC"}
|