@cleocode/core 2026.4.98 → 2026.4.100
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/gc/daemon-entry.d.ts +15 -0
- package/dist/gc/daemon-entry.d.ts.map +1 -0
- package/dist/gc/daemon.d.ts +71 -0
- package/dist/gc/daemon.d.ts.map +1 -0
- package/dist/gc/daemon.js +481 -0
- package/dist/gc/daemon.js.map +7 -0
- package/dist/gc/index.d.ts +14 -0
- package/dist/gc/index.d.ts.map +1 -0
- package/dist/gc/index.js +669 -0
- package/dist/gc/index.js.map +7 -0
- package/dist/gc/runner.d.ts +132 -0
- package/dist/gc/runner.d.ts.map +1 -0
- package/dist/gc/runner.js +360 -0
- package/dist/gc/runner.js.map +7 -0
- package/dist/gc/state.d.ts +94 -0
- package/dist/gc/state.d.ts.map +1 -0
- package/dist/gc/state.js +49 -0
- package/dist/gc/state.js.map +7 -0
- package/dist/gc/transcript.d.ts +130 -0
- package/dist/gc/transcript.d.ts.map +1 -0
- package/dist/gc/transcript.js +209 -0
- package/dist/gc/transcript.js.map +7 -0
- package/dist/memory/brain-backfill.js +14643 -0
- package/dist/memory/brain-backfill.js.map +7 -0
- package/dist/memory/precompact-flush.js +47725 -0
- package/dist/memory/precompact-flush.js.map +7 -0
- package/dist/sentient/daemon-entry.d.ts +11 -0
- package/dist/sentient/daemon-entry.d.ts.map +1 -0
- package/dist/sentient/daemon.d.ts +160 -0
- package/dist/sentient/daemon.d.ts.map +1 -0
- package/dist/sentient/daemon.js +1100 -0
- package/dist/sentient/daemon.js.map +7 -0
- package/dist/sentient/index.d.ts +18 -0
- package/dist/sentient/index.d.ts.map +1 -0
- package/dist/sentient/index.js +1162 -0
- package/dist/sentient/index.js.map +7 -0
- package/dist/sentient/ingesters/brain-ingester.d.ts +44 -0
- package/dist/sentient/ingesters/brain-ingester.d.ts.map +1 -0
- package/dist/sentient/ingesters/nexus-ingester.d.ts +45 -0
- package/dist/sentient/ingesters/nexus-ingester.d.ts.map +1 -0
- package/dist/sentient/ingesters/test-ingester.d.ts +43 -0
- package/dist/sentient/ingesters/test-ingester.d.ts.map +1 -0
- package/dist/sentient/proposal-rate-limiter.d.ts +93 -0
- package/dist/sentient/proposal-rate-limiter.d.ts.map +1 -0
- package/dist/sentient/propose-tick.d.ts +105 -0
- package/dist/sentient/propose-tick.d.ts.map +1 -0
- package/dist/sentient/propose-tick.js +549 -0
- package/dist/sentient/propose-tick.js.map +7 -0
- package/dist/sentient/state.d.ts +143 -0
- package/dist/sentient/state.d.ts.map +1 -0
- package/dist/sentient/state.js +85 -0
- package/dist/sentient/state.js.map +7 -0
- package/dist/sentient/tick.d.ts +193 -0
- package/dist/sentient/tick.d.ts.map +1 -0
- package/dist/sentient/tick.js +396 -0
- package/dist/sentient/tick.js.map +7 -0
- package/dist/system/platform-paths.js +36 -0
- package/dist/system/platform-paths.js.map +7 -0
- package/package.json +76 -8
- package/src/gc/__tests__/runner.test.ts +367 -0
- package/src/gc/__tests__/state.test.ts +169 -0
- package/src/gc/__tests__/transcript.test.ts +371 -0
- package/src/gc/daemon-entry.ts +26 -0
- package/src/gc/daemon.ts +251 -0
- package/src/gc/index.ts +14 -0
- package/src/gc/runner.ts +378 -0
- package/src/gc/state.ts +140 -0
- package/src/gc/transcript.ts +380 -0
- package/src/sentient/__tests__/brain-ingester.test.ts +154 -0
- package/src/sentient/__tests__/daemon.test.ts +472 -0
- package/src/sentient/__tests__/dream-tick.test.ts +200 -0
- package/src/sentient/__tests__/nexus-ingester.test.ts +138 -0
- package/src/sentient/__tests__/proposal-rate-limiter.test.ts +247 -0
- package/src/sentient/__tests__/propose-tick.test.ts +296 -0
- package/src/sentient/__tests__/test-ingester.test.ts +104 -0
- package/src/sentient/daemon-entry.ts +20 -0
- package/src/sentient/daemon.ts +471 -0
- package/src/sentient/index.ts +18 -0
- package/src/sentient/ingesters/brain-ingester.ts +122 -0
- package/src/sentient/ingesters/nexus-ingester.ts +171 -0
- package/src/sentient/ingesters/test-ingester.ts +205 -0
- package/src/sentient/proposal-rate-limiter.ts +172 -0
- package/src/sentient/propose-tick.ts +415 -0
- package/src/sentient/state.ts +229 -0
- package/src/sentient/tick.ts +688 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sentient Daemon Entry Point — spawned by `spawnSentientDaemon()`.
|
|
3
|
+
*
|
|
4
|
+
* Runs as a detached background process. Receives the project root as
|
|
5
|
+
* argv[2]. Does NOT import the CLI shim — only the sentient/ subtree.
|
|
6
|
+
*
|
|
7
|
+
* @see sentient/daemon.ts for spawn logic
|
|
8
|
+
* @task T946
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=daemon-entry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon-entry.d.ts","sourceRoot":"","sources":["../../src/sentient/daemon-entry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sentient Daemon — Tier-1 autonomous loop sidecar.
|
|
3
|
+
*
|
|
4
|
+
* Runs as a detached Node.js process and executes `runTick()` every 5
|
|
5
|
+
* minutes. Mirrors the gc/daemon.ts sidecar pattern (ADR-047) and honours
|
|
6
|
+
* the worktree protocol — all state lives under the project's `.cleo/`.
|
|
7
|
+
*
|
|
8
|
+
* Scoped IN (this module):
|
|
9
|
+
* - Tier-1 execution of unblocked tasks via `cleo orchestrate spawn`
|
|
10
|
+
* - Kill-switch with re-check at every tick checkpoint
|
|
11
|
+
* - Advisory locking via an OS-level lockfile (two daemons cannot coexist)
|
|
12
|
+
* - Stuck detection + self-pause on stuck-rate threshold
|
|
13
|
+
* - fs.watch-based fast kill propagation
|
|
14
|
+
*
|
|
15
|
+
* Scoped OUT (separate epics):
|
|
16
|
+
* - Tier-2 proposal queue (`cleo propose` / status='proposed' generation)
|
|
17
|
+
* - Tier-3 sandbox auto-merge (requires agent-in-container infra)
|
|
18
|
+
* - Ed25519 signing of receipts (handled by Agent B2 llmtxt/identity wiring)
|
|
19
|
+
*
|
|
20
|
+
* @see ADR-054 — Sentient Loop Tier-1
|
|
21
|
+
* @task T946
|
|
22
|
+
*/
|
|
23
|
+
import { type FileHandle } from 'node:fs/promises';
|
|
24
|
+
import { type SentientState } from './state.js';
|
|
25
|
+
/** Relative subpath under a project root where sentient state lives. */
|
|
26
|
+
export declare const SENTIENT_STATE_FILE: ".cleo/sentient-state.json";
|
|
27
|
+
/** Relative subpath for the daemon lockfile. */
|
|
28
|
+
export declare const SENTIENT_LOCK_FILE: ".cleo/sentient.lock";
|
|
29
|
+
/** Cron expression: every 5 minutes (Tier-1 tick). */
|
|
30
|
+
export declare const SENTIENT_CRON_EXPR = "*/5 * * * *";
|
|
31
|
+
/**
|
|
32
|
+
* Cron expression: every 2 hours (Tier-2 propose tick).
|
|
33
|
+
*
|
|
34
|
+
* Separate from the Tier-1 cron to avoid proposal flooding.
|
|
35
|
+
* Only fires when `tier2Enabled = true` in sentient-state.json.
|
|
36
|
+
*
|
|
37
|
+
* @task T1008
|
|
38
|
+
*/
|
|
39
|
+
export declare const SENTIENT_PROPOSE_CRON_EXPR = "0 */2 * * *";
|
|
40
|
+
/** Subdirectory for daemon logs. */
|
|
41
|
+
export declare const SENTIENT_LOG_DIR: ".cleo/logs";
|
|
42
|
+
/** Log filename (stdout). */
|
|
43
|
+
export declare const SENTIENT_LOG: "sentient.log";
|
|
44
|
+
/** Log filename (stderr). */
|
|
45
|
+
export declare const SENTIENT_ERR: "sentient.err";
|
|
46
|
+
/** Handle to an active advisory lock. */
|
|
47
|
+
export interface LockHandle {
|
|
48
|
+
/** Absolute path to the lockfile. */
|
|
49
|
+
path: string;
|
|
50
|
+
/** Underlying file handle held exclusively by this process. */
|
|
51
|
+
handle: FileHandle;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Acquire an exclusive advisory lock on the sentient lockfile.
|
|
55
|
+
*
|
|
56
|
+
* Uses `fs.open` with `O_CREAT | O_EXCL` semantics — if the file already
|
|
57
|
+
* exists AND its recorded pid is alive, acquisition fails. Stale lockfiles
|
|
58
|
+
* (pid dead) are reclaimed automatically.
|
|
59
|
+
*
|
|
60
|
+
* @param lockPath - Absolute path to `.cleo/sentient.lock`
|
|
61
|
+
* @returns Lock handle, or null if lock is held by a live process
|
|
62
|
+
*/
|
|
63
|
+
export declare function acquireLock(lockPath: string): Promise<LockHandle | null>;
|
|
64
|
+
/**
|
|
65
|
+
* Release an advisory lock acquired via {@link acquireLock}.
|
|
66
|
+
* Does NOT remove the lockfile — the pid inside is a useful diagnostic.
|
|
67
|
+
*/
|
|
68
|
+
export declare function releaseLock(lock: LockHandle): Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* Bootstrap the sentient daemon process.
|
|
71
|
+
*
|
|
72
|
+
* Steps:
|
|
73
|
+
* 1. Acquire advisory lock (fail fast if another daemon is running)
|
|
74
|
+
* 2. Persist our pid + startedAt to state.json
|
|
75
|
+
* 3. Watch state.json for killSwitch changes (fast propagation)
|
|
76
|
+
* 4. Register a SIGTERM handler for graceful shutdown
|
|
77
|
+
* 5. Schedule cron with noOverlap so long ticks don't stack
|
|
78
|
+
*
|
|
79
|
+
* @param projectRoot - Absolute path to the project (contains `.cleo/`)
|
|
80
|
+
*/
|
|
81
|
+
export declare function bootstrapDaemon(projectRoot: string): Promise<void>;
|
|
82
|
+
/** Outcome of {@link spawnSentientDaemon}. */
|
|
83
|
+
export interface SpawnDaemonResult {
|
|
84
|
+
/** PID of the spawned daemon. */
|
|
85
|
+
pid: number;
|
|
86
|
+
/** Absolute path to the .cleo/sentient-state.json file. */
|
|
87
|
+
statePath: string;
|
|
88
|
+
/** Absolute path to the log file. */
|
|
89
|
+
logPath: string;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Spawn the sentient daemon as a detached background process.
|
|
93
|
+
*
|
|
94
|
+
* All three T751 §2.2 requirements:
|
|
95
|
+
* 1. `detached: true` — process-group leader survives parent exit
|
|
96
|
+
* 2. File-based stdio — no TTY inheritance
|
|
97
|
+
* 3. `child.unref()` — parent CLI returns immediately
|
|
98
|
+
*
|
|
99
|
+
* @param projectRoot - Absolute path to the project root (contains `.cleo/`)
|
|
100
|
+
* @returns PID + log paths
|
|
101
|
+
*/
|
|
102
|
+
export declare function spawnSentientDaemon(projectRoot: string): Promise<SpawnDaemonResult>;
|
|
103
|
+
/** Outcome of {@link stopSentientDaemon}. */
|
|
104
|
+
export interface StopDaemonResult {
|
|
105
|
+
/** Whether the stop signal was delivered. */
|
|
106
|
+
stopped: boolean;
|
|
107
|
+
/** Last known pid; null if no pid was recorded. */
|
|
108
|
+
pid: number | null;
|
|
109
|
+
/** Human-readable reason. */
|
|
110
|
+
reason: string;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Stop the sentient daemon.
|
|
114
|
+
*
|
|
115
|
+
* Flips killSwitch=true FIRST (so an in-flight tick notices on its next
|
|
116
|
+
* checkpoint re-read), then sends SIGTERM. This gives the daemon a fast,
|
|
117
|
+
* graceful shutdown path even during a long-running spawn.
|
|
118
|
+
*
|
|
119
|
+
* @param projectRoot - Absolute path to the project root
|
|
120
|
+
* @param reason - Optional reason stored on state file for diagnostics
|
|
121
|
+
* @returns Stop result
|
|
122
|
+
*/
|
|
123
|
+
export declare function stopSentientDaemon(projectRoot: string, reason?: string): Promise<StopDaemonResult>;
|
|
124
|
+
/**
|
|
125
|
+
* Clear the kill switch so the cron schedule resumes executing ticks.
|
|
126
|
+
*
|
|
127
|
+
* Does NOT restart the daemon process — that is the caller's responsibility
|
|
128
|
+
* via `cleo sentient start` if the process itself exited.
|
|
129
|
+
*
|
|
130
|
+
* @param projectRoot - Absolute path to the project root
|
|
131
|
+
*/
|
|
132
|
+
export declare function resumeSentientDaemon(projectRoot: string): Promise<SentientState>;
|
|
133
|
+
/** Status snapshot returned by {@link getSentientDaemonStatus}. */
|
|
134
|
+
export interface SentientStatus {
|
|
135
|
+
/** Whether the pid on file is currently alive. */
|
|
136
|
+
running: boolean;
|
|
137
|
+
/** Recorded pid (null when never started or cleared on stop). */
|
|
138
|
+
pid: number | null;
|
|
139
|
+
/** ISO-8601 timestamp of last start. */
|
|
140
|
+
startedAt: string | null;
|
|
141
|
+
/** ISO-8601 timestamp of the last completed tick. */
|
|
142
|
+
lastTickAt: string | null;
|
|
143
|
+
/** Kill-switch state. */
|
|
144
|
+
killSwitch: boolean;
|
|
145
|
+
/** Reason supplied with the last kill. */
|
|
146
|
+
killSwitchReason: string | null;
|
|
147
|
+
/** Rolling stats. */
|
|
148
|
+
stats: SentientState['stats'];
|
|
149
|
+
/** Number of currently-stuck tasks. */
|
|
150
|
+
stuckCount: number;
|
|
151
|
+
/** Currently active task id (set mid-tick). */
|
|
152
|
+
activeTaskId: string | null;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Return a diagnostic snapshot for `cleo sentient status`.
|
|
156
|
+
*
|
|
157
|
+
* @param projectRoot - Absolute path to the project root
|
|
158
|
+
*/
|
|
159
|
+
export declare function getSentientDaemonStatus(projectRoot: string): Promise<SentientStatus>;
|
|
160
|
+
//# sourceMappingURL=daemon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/sentient/daemon.ts"],"names":[],"mappings":"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"}
|