genesis-ai-cli 7.4.5
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/.env.example +78 -0
- package/README.md +282 -0
- package/dist/src/active-inference/actions.d.ts +75 -0
- package/dist/src/active-inference/actions.js +250 -0
- package/dist/src/active-inference/autonomous-loop.d.ts +103 -0
- package/dist/src/active-inference/autonomous-loop.js +289 -0
- package/dist/src/active-inference/core.d.ts +85 -0
- package/dist/src/active-inference/core.js +555 -0
- package/dist/src/active-inference/demo-autonomous-loop.d.ts +8 -0
- package/dist/src/active-inference/demo-autonomous-loop.js +338 -0
- package/dist/src/active-inference/demo-value-integration.d.ts +8 -0
- package/dist/src/active-inference/demo-value-integration.js +174 -0
- package/dist/src/active-inference/index.d.ts +32 -0
- package/dist/src/active-inference/index.js +88 -0
- package/dist/src/active-inference/integration.d.ts +114 -0
- package/dist/src/active-inference/integration.js +698 -0
- package/dist/src/active-inference/memory-integration.d.ts +51 -0
- package/dist/src/active-inference/memory-integration.js +232 -0
- package/dist/src/active-inference/observations.d.ts +67 -0
- package/dist/src/active-inference/observations.js +147 -0
- package/dist/src/active-inference/test-active-inference.d.ts +8 -0
- package/dist/src/active-inference/test-active-inference.js +320 -0
- package/dist/src/active-inference/test-value-integration.d.ts +6 -0
- package/dist/src/active-inference/test-value-integration.js +168 -0
- package/dist/src/active-inference/types.d.ts +150 -0
- package/dist/src/active-inference/types.js +59 -0
- package/dist/src/active-inference/value-integration.d.ts +164 -0
- package/dist/src/active-inference/value-integration.js +459 -0
- package/dist/src/agents/base-agent.d.ts +53 -0
- package/dist/src/agents/base-agent.js +178 -0
- package/dist/src/agents/builder.d.ts +67 -0
- package/dist/src/agents/builder.js +537 -0
- package/dist/src/agents/critic.d.ts +35 -0
- package/dist/src/agents/critic.js +322 -0
- package/dist/src/agents/ethicist.d.ts +54 -0
- package/dist/src/agents/ethicist.js +393 -0
- package/dist/src/agents/explorer.d.ts +26 -0
- package/dist/src/agents/explorer.js +216 -0
- package/dist/src/agents/feeling.d.ts +41 -0
- package/dist/src/agents/feeling.js +320 -0
- package/dist/src/agents/index.d.ts +111 -0
- package/dist/src/agents/index.js +222 -0
- package/dist/src/agents/memory.d.ts +69 -0
- package/dist/src/agents/memory.js +404 -0
- package/dist/src/agents/message-bus.d.ts +88 -0
- package/dist/src/agents/message-bus.js +267 -0
- package/dist/src/agents/narrator.d.ts +90 -0
- package/dist/src/agents/narrator.js +473 -0
- package/dist/src/agents/planner.d.ts +38 -0
- package/dist/src/agents/planner.js +341 -0
- package/dist/src/agents/predictor.d.ts +73 -0
- package/dist/src/agents/predictor.js +506 -0
- package/dist/src/agents/sensor.d.ts +88 -0
- package/dist/src/agents/sensor.js +377 -0
- package/dist/src/agents/test-agents.d.ts +6 -0
- package/dist/src/agents/test-agents.js +73 -0
- package/dist/src/agents/types.d.ts +194 -0
- package/dist/src/agents/types.js +7 -0
- package/dist/src/brain/index.d.ts +185 -0
- package/dist/src/brain/index.js +843 -0
- package/dist/src/brain/trace.d.ts +91 -0
- package/dist/src/brain/trace.js +327 -0
- package/dist/src/brain/types.d.ts +165 -0
- package/dist/src/brain/types.js +51 -0
- package/dist/src/cli/chat.d.ts +237 -0
- package/dist/src/cli/chat.js +1959 -0
- package/dist/src/cli/dispatcher.d.ts +182 -0
- package/dist/src/cli/dispatcher.js +718 -0
- package/dist/src/cli/human-loop.d.ts +170 -0
- package/dist/src/cli/human-loop.js +543 -0
- package/dist/src/cli/index.d.ts +12 -0
- package/dist/src/cli/index.js +28 -0
- package/dist/src/cli/interactive.d.ts +141 -0
- package/dist/src/cli/interactive.js +757 -0
- package/dist/src/cli/ui.d.ts +205 -0
- package/dist/src/cli/ui.js +632 -0
- package/dist/src/consciousness/attention-schema.d.ts +154 -0
- package/dist/src/consciousness/attention-schema.js +432 -0
- package/dist/src/consciousness/global-workspace.d.ts +149 -0
- package/dist/src/consciousness/global-workspace.js +422 -0
- package/dist/src/consciousness/index.d.ts +186 -0
- package/dist/src/consciousness/index.js +476 -0
- package/dist/src/consciousness/phi-calculator.d.ts +119 -0
- package/dist/src/consciousness/phi-calculator.js +445 -0
- package/dist/src/consciousness/phi-decisions.d.ts +169 -0
- package/dist/src/consciousness/phi-decisions.js +383 -0
- package/dist/src/consciousness/phi-monitor.d.ts +153 -0
- package/dist/src/consciousness/phi-monitor.js +465 -0
- package/dist/src/consciousness/types.d.ts +260 -0
- package/dist/src/consciousness/types.js +44 -0
- package/dist/src/daemon/dream-mode.d.ts +115 -0
- package/dist/src/daemon/dream-mode.js +470 -0
- package/dist/src/daemon/index.d.ts +162 -0
- package/dist/src/daemon/index.js +542 -0
- package/dist/src/daemon/maintenance.d.ts +139 -0
- package/dist/src/daemon/maintenance.js +549 -0
- package/dist/src/daemon/process.d.ts +82 -0
- package/dist/src/daemon/process.js +442 -0
- package/dist/src/daemon/scheduler.d.ts +90 -0
- package/dist/src/daemon/scheduler.js +494 -0
- package/dist/src/daemon/types.d.ts +213 -0
- package/dist/src/daemon/types.js +50 -0
- package/dist/src/epistemic/index.d.ts +74 -0
- package/dist/src/epistemic/index.js +225 -0
- package/dist/src/grounding/epistemic-stack.d.ts +100 -0
- package/dist/src/grounding/epistemic-stack.js +408 -0
- package/dist/src/grounding/feedback.d.ts +98 -0
- package/dist/src/grounding/feedback.js +276 -0
- package/dist/src/grounding/index.d.ts +123 -0
- package/dist/src/grounding/index.js +224 -0
- package/dist/src/grounding/verifier.d.ts +149 -0
- package/dist/src/grounding/verifier.js +484 -0
- package/dist/src/healing/detector.d.ts +110 -0
- package/dist/src/healing/detector.js +436 -0
- package/dist/src/healing/fixer.d.ts +138 -0
- package/dist/src/healing/fixer.js +572 -0
- package/dist/src/healing/index.d.ts +23 -0
- package/dist/src/healing/index.js +43 -0
- package/dist/src/hooks/index.d.ts +135 -0
- package/dist/src/hooks/index.js +317 -0
- package/dist/src/index.d.ts +23 -0
- package/dist/src/index.js +1266 -0
- package/dist/src/kernel/index.d.ts +155 -0
- package/dist/src/kernel/index.js +795 -0
- package/dist/src/kernel/invariants.d.ts +153 -0
- package/dist/src/kernel/invariants.js +355 -0
- package/dist/src/kernel/test-kernel.d.ts +6 -0
- package/dist/src/kernel/test-kernel.js +108 -0
- package/dist/src/kernel/test-real-mcp.d.ts +10 -0
- package/dist/src/kernel/test-real-mcp.js +295 -0
- package/dist/src/llm/index.d.ts +146 -0
- package/dist/src/llm/index.js +428 -0
- package/dist/src/llm/router.d.ts +136 -0
- package/dist/src/llm/router.js +510 -0
- package/dist/src/mcp/index.d.ts +85 -0
- package/dist/src/mcp/index.js +657 -0
- package/dist/src/mcp/resilient.d.ts +139 -0
- package/dist/src/mcp/resilient.js +417 -0
- package/dist/src/memory/cache.d.ts +118 -0
- package/dist/src/memory/cache.js +356 -0
- package/dist/src/memory/cognitive-workspace.d.ts +231 -0
- package/dist/src/memory/cognitive-workspace.js +521 -0
- package/dist/src/memory/consolidation.d.ts +99 -0
- package/dist/src/memory/consolidation.js +443 -0
- package/dist/src/memory/episodic.d.ts +114 -0
- package/dist/src/memory/episodic.js +394 -0
- package/dist/src/memory/forgetting.d.ts +134 -0
- package/dist/src/memory/forgetting.js +324 -0
- package/dist/src/memory/index.d.ts +211 -0
- package/dist/src/memory/index.js +367 -0
- package/dist/src/memory/indexer.d.ts +123 -0
- package/dist/src/memory/indexer.js +479 -0
- package/dist/src/memory/procedural.d.ts +136 -0
- package/dist/src/memory/procedural.js +479 -0
- package/dist/src/memory/semantic.d.ts +132 -0
- package/dist/src/memory/semantic.js +497 -0
- package/dist/src/memory/types.d.ts +193 -0
- package/dist/src/memory/types.js +15 -0
- package/dist/src/orchestrator.d.ts +65 -0
- package/dist/src/orchestrator.js +317 -0
- package/dist/src/persistence/index.d.ts +257 -0
- package/dist/src/persistence/index.js +763 -0
- package/dist/src/pipeline/executor.d.ts +51 -0
- package/dist/src/pipeline/executor.js +695 -0
- package/dist/src/pipeline/index.d.ts +7 -0
- package/dist/src/pipeline/index.js +11 -0
- package/dist/src/self-production.d.ts +67 -0
- package/dist/src/self-production.js +205 -0
- package/dist/src/subagents/executor.d.ts +58 -0
- package/dist/src/subagents/executor.js +283 -0
- package/dist/src/subagents/index.d.ts +37 -0
- package/dist/src/subagents/index.js +53 -0
- package/dist/src/subagents/registry.d.ts +23 -0
- package/dist/src/subagents/registry.js +167 -0
- package/dist/src/subagents/types.d.ts +79 -0
- package/dist/src/subagents/types.js +14 -0
- package/dist/src/tools/bash.d.ts +139 -0
- package/dist/src/tools/bash.js +583 -0
- package/dist/src/tools/edit.d.ts +125 -0
- package/dist/src/tools/edit.js +424 -0
- package/dist/src/tools/git.d.ts +179 -0
- package/dist/src/tools/git.js +504 -0
- package/dist/src/tools/index.d.ts +21 -0
- package/dist/src/tools/index.js +163 -0
- package/dist/src/types.d.ts +145 -0
- package/dist/src/types.js +7 -0
- package/dist/src/world-model/decoder.d.ts +163 -0
- package/dist/src/world-model/decoder.js +517 -0
- package/dist/src/world-model/digital-twin.d.ts +219 -0
- package/dist/src/world-model/digital-twin.js +695 -0
- package/dist/src/world-model/encoder.d.ts +141 -0
- package/dist/src/world-model/encoder.js +564 -0
- package/dist/src/world-model/index.d.ts +221 -0
- package/dist/src/world-model/index.js +772 -0
- package/dist/src/world-model/predictor.d.ts +161 -0
- package/dist/src/world-model/predictor.js +681 -0
- package/dist/src/world-model/test-value-jepa.d.ts +8 -0
- package/dist/src/world-model/test-value-jepa.js +430 -0
- package/dist/src/world-model/types.d.ts +341 -0
- package/dist/src/world-model/types.js +69 -0
- package/dist/src/world-model/value-jepa.d.ts +247 -0
- package/dist/src/world-model/value-jepa.js +622 -0
- package/dist/test/brain.test.d.ts +11 -0
- package/dist/test/brain.test.js +358 -0
- package/dist/test/cli/dispatcher.test.d.ts +4 -0
- package/dist/test/cli/dispatcher.test.js +332 -0
- package/dist/test/cli/human-loop.test.d.ts +4 -0
- package/dist/test/cli/human-loop.test.js +270 -0
- package/dist/test/grounding/feedback.test.d.ts +4 -0
- package/dist/test/grounding/feedback.test.js +462 -0
- package/dist/test/grounding/verifier.test.d.ts +4 -0
- package/dist/test/grounding/verifier.test.js +442 -0
- package/dist/test/grounding.test.d.ts +6 -0
- package/dist/test/grounding.test.js +246 -0
- package/dist/test/healing/detector.test.d.ts +4 -0
- package/dist/test/healing/detector.test.js +266 -0
- package/dist/test/healing/fixer.test.d.ts +4 -0
- package/dist/test/healing/fixer.test.js +369 -0
- package/dist/test/integration.test.d.ts +5 -0
- package/dist/test/integration.test.js +290 -0
- package/dist/test/tools/bash.test.d.ts +4 -0
- package/dist/test/tools/bash.test.js +348 -0
- package/dist/test/tools/edit.test.d.ts +4 -0
- package/dist/test/tools/edit.test.js +350 -0
- package/dist/test/tools/git.test.d.ts +4 -0
- package/dist/test/tools/git.test.js +350 -0
- package/package.json +60 -0
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Genesis 6.0 - Daemon Process Manager
|
|
4
|
+
*
|
|
5
|
+
* Handles background process spawning, PID management, and IPC.
|
|
6
|
+
*
|
|
7
|
+
* Architecture:
|
|
8
|
+
* - Parent process spawns detached child
|
|
9
|
+
* - Child creates Unix socket for IPC
|
|
10
|
+
* - CLI commands communicate via socket
|
|
11
|
+
*/
|
|
12
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
15
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
16
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
17
|
+
}
|
|
18
|
+
Object.defineProperty(o, k2, desc);
|
|
19
|
+
}) : (function(o, m, k, k2) {
|
|
20
|
+
if (k2 === undefined) k2 = k;
|
|
21
|
+
o[k2] = m[k];
|
|
22
|
+
}));
|
|
23
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
24
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
25
|
+
}) : function(o, v) {
|
|
26
|
+
o["default"] = v;
|
|
27
|
+
});
|
|
28
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
29
|
+
var ownKeys = function(o) {
|
|
30
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
31
|
+
var ar = [];
|
|
32
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
33
|
+
return ar;
|
|
34
|
+
};
|
|
35
|
+
return ownKeys(o);
|
|
36
|
+
};
|
|
37
|
+
return function (mod) {
|
|
38
|
+
if (mod && mod.__esModule) return mod;
|
|
39
|
+
var result = {};
|
|
40
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
41
|
+
__setModuleDefault(result, mod);
|
|
42
|
+
return result;
|
|
43
|
+
};
|
|
44
|
+
})();
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
exports.LOG_FILE = exports.SOCKET_PATH = exports.PID_FILE = exports.DATA_DIR = exports.DaemonProcessManager = void 0;
|
|
47
|
+
exports.getProcessManager = getProcessManager;
|
|
48
|
+
const fs = __importStar(require("fs"));
|
|
49
|
+
const path = __importStar(require("path"));
|
|
50
|
+
const net = __importStar(require("net"));
|
|
51
|
+
const child_process_1 = require("child_process");
|
|
52
|
+
const index_js_1 = require("./index.js");
|
|
53
|
+
// ============================================================================
|
|
54
|
+
// Constants
|
|
55
|
+
// ============================================================================
|
|
56
|
+
const DATA_DIR = path.join(process.env.HOME || '/tmp', '.genesis');
|
|
57
|
+
exports.DATA_DIR = DATA_DIR;
|
|
58
|
+
const PID_FILE = path.join(DATA_DIR, 'daemon.pid');
|
|
59
|
+
exports.PID_FILE = PID_FILE;
|
|
60
|
+
const SOCKET_PATH = path.join(DATA_DIR, 'daemon.sock');
|
|
61
|
+
exports.SOCKET_PATH = SOCKET_PATH;
|
|
62
|
+
const LOG_FILE = path.join(DATA_DIR, 'daemon.log');
|
|
63
|
+
exports.LOG_FILE = LOG_FILE;
|
|
64
|
+
// ============================================================================
|
|
65
|
+
// Process Manager
|
|
66
|
+
// ============================================================================
|
|
67
|
+
class DaemonProcessManager {
|
|
68
|
+
daemon = null;
|
|
69
|
+
server = null;
|
|
70
|
+
logStream = null;
|
|
71
|
+
constructor() {
|
|
72
|
+
this.ensureDataDir();
|
|
73
|
+
}
|
|
74
|
+
// ============================================================================
|
|
75
|
+
// Data Directory
|
|
76
|
+
// ============================================================================
|
|
77
|
+
ensureDataDir() {
|
|
78
|
+
if (!fs.existsSync(DATA_DIR)) {
|
|
79
|
+
fs.mkdirSync(DATA_DIR, { recursive: true });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// ============================================================================
|
|
83
|
+
// PID Management
|
|
84
|
+
// ============================================================================
|
|
85
|
+
writePid() {
|
|
86
|
+
fs.writeFileSync(PID_FILE, String(process.pid));
|
|
87
|
+
}
|
|
88
|
+
readPid() {
|
|
89
|
+
try {
|
|
90
|
+
const pid = parseInt(fs.readFileSync(PID_FILE, 'utf-8').trim(), 10);
|
|
91
|
+
return isNaN(pid) ? null : pid;
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
removePid() {
|
|
98
|
+
try {
|
|
99
|
+
fs.unlinkSync(PID_FILE);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// Ignore
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
isProcessRunning(pid) {
|
|
106
|
+
try {
|
|
107
|
+
process.kill(pid, 0);
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// ============================================================================
|
|
115
|
+
// Socket Management
|
|
116
|
+
// ============================================================================
|
|
117
|
+
cleanupSocket() {
|
|
118
|
+
try {
|
|
119
|
+
if (fs.existsSync(SOCKET_PATH)) {
|
|
120
|
+
fs.unlinkSync(SOCKET_PATH);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
// Ignore
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// ============================================================================
|
|
128
|
+
// Logging
|
|
129
|
+
// ============================================================================
|
|
130
|
+
initLogging() {
|
|
131
|
+
this.logStream = fs.createWriteStream(LOG_FILE, { flags: 'a' });
|
|
132
|
+
// Redirect console to log file
|
|
133
|
+
const originalLog = console.log;
|
|
134
|
+
const originalError = console.error;
|
|
135
|
+
const stream = this.logStream;
|
|
136
|
+
console.log = (...args) => {
|
|
137
|
+
const msg = `[${new Date().toISOString()}] ${args.join(' ')}\n`;
|
|
138
|
+
stream.write(msg);
|
|
139
|
+
};
|
|
140
|
+
console.error = (...args) => {
|
|
141
|
+
const msg = `[${new Date().toISOString()}] ERROR: ${args.join(' ')}\n`;
|
|
142
|
+
stream.write(msg);
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
closeLogging() {
|
|
146
|
+
if (this.logStream) {
|
|
147
|
+
this.logStream.end();
|
|
148
|
+
this.logStream = null;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// ============================================================================
|
|
152
|
+
// IPC Server
|
|
153
|
+
// ============================================================================
|
|
154
|
+
startIPCServer() {
|
|
155
|
+
this.cleanupSocket();
|
|
156
|
+
this.server = net.createServer((socket) => {
|
|
157
|
+
let buffer = '';
|
|
158
|
+
socket.on('data', (data) => {
|
|
159
|
+
buffer += data.toString();
|
|
160
|
+
// Process complete messages (newline-delimited JSON)
|
|
161
|
+
const lines = buffer.split('\n');
|
|
162
|
+
buffer = lines.pop() || '';
|
|
163
|
+
for (const line of lines) {
|
|
164
|
+
if (line.trim()) {
|
|
165
|
+
this.handleIPCRequest(socket, line.trim());
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
socket.on('error', (err) => {
|
|
170
|
+
console.error('IPC socket error:', err.message);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
this.server.listen(SOCKET_PATH, () => {
|
|
174
|
+
console.log(`IPC server listening on ${SOCKET_PATH}`);
|
|
175
|
+
});
|
|
176
|
+
this.server.on('error', (err) => {
|
|
177
|
+
console.error('IPC server error:', err);
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
handleIPCRequest(socket, data) {
|
|
181
|
+
let request;
|
|
182
|
+
try {
|
|
183
|
+
request = JSON.parse(data);
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
this.sendResponse(socket, { id: 'unknown', success: false, error: 'Invalid JSON' });
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const respond = (success, data, error) => {
|
|
190
|
+
this.sendResponse(socket, { id: request.id, success, data, error });
|
|
191
|
+
};
|
|
192
|
+
try {
|
|
193
|
+
switch (request.method) {
|
|
194
|
+
case 'ping':
|
|
195
|
+
respond(true, { pong: true });
|
|
196
|
+
break;
|
|
197
|
+
case 'status':
|
|
198
|
+
if (this.daemon) {
|
|
199
|
+
respond(true, this.daemon.status());
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
respond(false, null, 'Daemon not initialized');
|
|
203
|
+
}
|
|
204
|
+
break;
|
|
205
|
+
case 'stop':
|
|
206
|
+
respond(true, { stopping: true });
|
|
207
|
+
// Schedule stop after response is sent
|
|
208
|
+
setImmediate(() => this.stopDaemon());
|
|
209
|
+
break;
|
|
210
|
+
case 'dream':
|
|
211
|
+
if (this.daemon) {
|
|
212
|
+
this.daemon.dream(request.params || {})
|
|
213
|
+
.then((results) => respond(true, results))
|
|
214
|
+
.catch((err) => respond(false, null, err.message));
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
respond(false, null, 'Daemon not initialized');
|
|
218
|
+
}
|
|
219
|
+
break;
|
|
220
|
+
case 'maintenance':
|
|
221
|
+
if (this.daemon) {
|
|
222
|
+
this.daemon.runMaintenance()
|
|
223
|
+
.then((report) => respond(true, report))
|
|
224
|
+
.catch((err) => respond(false, null, err.message));
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
respond(false, null, 'Daemon not initialized');
|
|
228
|
+
}
|
|
229
|
+
break;
|
|
230
|
+
case 'tasks':
|
|
231
|
+
if (this.daemon) {
|
|
232
|
+
const tasks = this.daemon.getTasks().map((t) => ({
|
|
233
|
+
id: t.id,
|
|
234
|
+
name: t.name,
|
|
235
|
+
schedule: t.schedule,
|
|
236
|
+
state: t.state,
|
|
237
|
+
lastRun: t.lastRun,
|
|
238
|
+
nextRun: t.nextRun,
|
|
239
|
+
}));
|
|
240
|
+
respond(true, { tasks });
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
respond(false, null, 'Daemon not initialized');
|
|
244
|
+
}
|
|
245
|
+
break;
|
|
246
|
+
default:
|
|
247
|
+
respond(false, null, `Unknown method: ${request.method}`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
catch (err) {
|
|
251
|
+
respond(false, null, err instanceof Error ? err.message : String(err));
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
sendResponse(socket, response) {
|
|
255
|
+
try {
|
|
256
|
+
socket.write(JSON.stringify(response) + '\n');
|
|
257
|
+
}
|
|
258
|
+
catch {
|
|
259
|
+
// Socket may be closed
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
stopIPCServer() {
|
|
263
|
+
if (this.server) {
|
|
264
|
+
this.server.close();
|
|
265
|
+
this.server = null;
|
|
266
|
+
}
|
|
267
|
+
this.cleanupSocket();
|
|
268
|
+
}
|
|
269
|
+
// ============================================================================
|
|
270
|
+
// Daemon Lifecycle
|
|
271
|
+
// ============================================================================
|
|
272
|
+
/**
|
|
273
|
+
* Start daemon in current process (for background mode)
|
|
274
|
+
*/
|
|
275
|
+
startDaemon() {
|
|
276
|
+
console.log('Starting Genesis daemon...');
|
|
277
|
+
// Write PID
|
|
278
|
+
this.writePid();
|
|
279
|
+
// Initialize logging
|
|
280
|
+
this.initLogging();
|
|
281
|
+
// Create daemon
|
|
282
|
+
this.daemon = (0, index_js_1.createDaemon)({
|
|
283
|
+
log: (msg, level) => console.log(`[${level?.toUpperCase() || 'INFO'}] ${msg}`),
|
|
284
|
+
}, {
|
|
285
|
+
logLevel: 'info',
|
|
286
|
+
});
|
|
287
|
+
// Start IPC server
|
|
288
|
+
this.startIPCServer();
|
|
289
|
+
// Start daemon
|
|
290
|
+
this.daemon.start();
|
|
291
|
+
// Handle shutdown signals
|
|
292
|
+
process.on('SIGTERM', () => this.stopDaemon());
|
|
293
|
+
process.on('SIGINT', () => this.stopDaemon());
|
|
294
|
+
process.on('SIGHUP', () => this.stopDaemon());
|
|
295
|
+
console.log(`Daemon started (PID: ${process.pid})`);
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Stop daemon
|
|
299
|
+
*/
|
|
300
|
+
stopDaemon() {
|
|
301
|
+
console.log('Stopping Genesis daemon...');
|
|
302
|
+
if (this.daemon) {
|
|
303
|
+
this.daemon.stop();
|
|
304
|
+
this.daemon = null;
|
|
305
|
+
}
|
|
306
|
+
this.stopIPCServer();
|
|
307
|
+
this.removePid();
|
|
308
|
+
this.closeLogging();
|
|
309
|
+
console.log('Daemon stopped');
|
|
310
|
+
process.exit(0);
|
|
311
|
+
}
|
|
312
|
+
// ============================================================================
|
|
313
|
+
// CLI Interface
|
|
314
|
+
// ============================================================================
|
|
315
|
+
/**
|
|
316
|
+
* Check if daemon is running
|
|
317
|
+
*/
|
|
318
|
+
getInfo() {
|
|
319
|
+
const pid = this.readPid();
|
|
320
|
+
const running = pid !== null && this.isProcessRunning(pid);
|
|
321
|
+
// Clean up stale PID file
|
|
322
|
+
if (!running && pid !== null) {
|
|
323
|
+
this.removePid();
|
|
324
|
+
}
|
|
325
|
+
return {
|
|
326
|
+
running,
|
|
327
|
+
pid: running ? pid : null,
|
|
328
|
+
uptime: null, // Would need to query via IPC
|
|
329
|
+
socketPath: SOCKET_PATH,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Spawn daemon as background process
|
|
334
|
+
*/
|
|
335
|
+
async spawn() {
|
|
336
|
+
const info = this.getInfo();
|
|
337
|
+
if (info.running) {
|
|
338
|
+
return { success: false, error: `Daemon already running (PID: ${info.pid})` };
|
|
339
|
+
}
|
|
340
|
+
// Find the entry point
|
|
341
|
+
const entryPoint = process.argv[1];
|
|
342
|
+
const args = ['daemon', 'run'];
|
|
343
|
+
// Spawn detached child
|
|
344
|
+
const child = (0, child_process_1.spawn)(process.execPath, [entryPoint, ...args], {
|
|
345
|
+
detached: true,
|
|
346
|
+
stdio: ['ignore', 'ignore', 'ignore'],
|
|
347
|
+
env: { ...process.env, GENESIS_DAEMON_MODE: 'background' },
|
|
348
|
+
});
|
|
349
|
+
child.unref();
|
|
350
|
+
// Wait a moment for the daemon to start
|
|
351
|
+
await new Promise((r) => setTimeout(r, 1000));
|
|
352
|
+
// Verify it started
|
|
353
|
+
const newInfo = this.getInfo();
|
|
354
|
+
if (newInfo.running) {
|
|
355
|
+
return { success: true, pid: newInfo.pid };
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
return { success: false, error: 'Daemon failed to start' };
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Stop running daemon via IPC
|
|
363
|
+
*/
|
|
364
|
+
async kill() {
|
|
365
|
+
const info = this.getInfo();
|
|
366
|
+
if (!info.running) {
|
|
367
|
+
return { success: false, error: 'Daemon is not running' };
|
|
368
|
+
}
|
|
369
|
+
try {
|
|
370
|
+
// Try IPC first
|
|
371
|
+
const response = await this.ipcCall('stop');
|
|
372
|
+
if (response.success) {
|
|
373
|
+
// Wait for process to exit
|
|
374
|
+
await new Promise((r) => setTimeout(r, 1000));
|
|
375
|
+
return { success: true };
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
catch {
|
|
379
|
+
// IPC failed, try SIGTERM
|
|
380
|
+
}
|
|
381
|
+
// Fallback to SIGTERM
|
|
382
|
+
if (info.pid) {
|
|
383
|
+
try {
|
|
384
|
+
process.kill(info.pid, 'SIGTERM');
|
|
385
|
+
await new Promise((r) => setTimeout(r, 1000));
|
|
386
|
+
return { success: true };
|
|
387
|
+
}
|
|
388
|
+
catch {
|
|
389
|
+
return { success: false, error: 'Failed to kill process' };
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
return { success: false, error: 'Unknown error' };
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Send IPC command to daemon
|
|
396
|
+
*/
|
|
397
|
+
async ipcCall(method, params) {
|
|
398
|
+
const info = this.getInfo();
|
|
399
|
+
if (!info.running) {
|
|
400
|
+
throw new Error('Daemon is not running');
|
|
401
|
+
}
|
|
402
|
+
return new Promise((resolve, reject) => {
|
|
403
|
+
const socket = net.createConnection(SOCKET_PATH);
|
|
404
|
+
const id = Math.random().toString(36).slice(2);
|
|
405
|
+
let timeout;
|
|
406
|
+
socket.on('connect', () => {
|
|
407
|
+
const request = { id, method, params };
|
|
408
|
+
socket.write(JSON.stringify(request) + '\n');
|
|
409
|
+
timeout = setTimeout(() => {
|
|
410
|
+
socket.destroy();
|
|
411
|
+
reject(new Error('IPC timeout'));
|
|
412
|
+
}, 10000);
|
|
413
|
+
});
|
|
414
|
+
socket.on('data', (data) => {
|
|
415
|
+
clearTimeout(timeout);
|
|
416
|
+
try {
|
|
417
|
+
const response = JSON.parse(data.toString().trim());
|
|
418
|
+
resolve(response);
|
|
419
|
+
}
|
|
420
|
+
catch {
|
|
421
|
+
reject(new Error('Invalid response'));
|
|
422
|
+
}
|
|
423
|
+
socket.end();
|
|
424
|
+
});
|
|
425
|
+
socket.on('error', (err) => {
|
|
426
|
+
clearTimeout(timeout);
|
|
427
|
+
reject(err);
|
|
428
|
+
});
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
exports.DaemonProcessManager = DaemonProcessManager;
|
|
433
|
+
// ============================================================================
|
|
434
|
+
// Singleton
|
|
435
|
+
// ============================================================================
|
|
436
|
+
let processManager = null;
|
|
437
|
+
function getProcessManager() {
|
|
438
|
+
if (!processManager) {
|
|
439
|
+
processManager = new DaemonProcessManager();
|
|
440
|
+
}
|
|
441
|
+
return processManager;
|
|
442
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Genesis 6.0 - Task Scheduler
|
|
3
|
+
*
|
|
4
|
+
* Background task scheduling with priorities, retries, and monitoring.
|
|
5
|
+
*
|
|
6
|
+
* Features:
|
|
7
|
+
* - Priority-based execution queue
|
|
8
|
+
* - Interval and cron scheduling
|
|
9
|
+
* - Automatic retries with backoff
|
|
10
|
+
* - Task timeout handling
|
|
11
|
+
* - Concurrent execution limits
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { createScheduler } from './daemon/scheduler.js';
|
|
16
|
+
*
|
|
17
|
+
* const scheduler = createScheduler({ maxConcurrentTasks: 5 });
|
|
18
|
+
*
|
|
19
|
+
* // Schedule a recurring task
|
|
20
|
+
* scheduler.schedule({
|
|
21
|
+
* name: 'health-check',
|
|
22
|
+
* schedule: { type: 'interval', intervalMs: 60000 },
|
|
23
|
+
* handler: async (ctx) => {
|
|
24
|
+
* ctx.logger.info('Running health check');
|
|
25
|
+
* return { success: true, duration: 50 };
|
|
26
|
+
* },
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* // Start the scheduler
|
|
30
|
+
* scheduler.start();
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
import { ScheduledTask, CreateTaskOptions } from './types.js';
|
|
34
|
+
export interface SchedulerConfig {
|
|
35
|
+
maxConcurrentTasks: number;
|
|
36
|
+
defaultTimeout: number;
|
|
37
|
+
defaultRetries: number;
|
|
38
|
+
defaultRetryDelay: number;
|
|
39
|
+
tickIntervalMs: number;
|
|
40
|
+
}
|
|
41
|
+
export declare const DEFAULT_SCHEDULER_CONFIG: SchedulerConfig;
|
|
42
|
+
export type SchedulerEventType = 'started' | 'stopped' | 'task_scheduled' | 'task_started' | 'task_completed' | 'task_failed' | 'task_cancelled';
|
|
43
|
+
export type SchedulerEventHandler = (event: {
|
|
44
|
+
type: SchedulerEventType;
|
|
45
|
+
task?: ScheduledTask;
|
|
46
|
+
error?: Error;
|
|
47
|
+
}) => void;
|
|
48
|
+
export declare class Scheduler {
|
|
49
|
+
private tasks;
|
|
50
|
+
private running;
|
|
51
|
+
private tickTimer;
|
|
52
|
+
private config;
|
|
53
|
+
private started;
|
|
54
|
+
private eventHandlers;
|
|
55
|
+
constructor(config?: Partial<SchedulerConfig>);
|
|
56
|
+
start(): void;
|
|
57
|
+
stop(): void;
|
|
58
|
+
isRunning(): boolean;
|
|
59
|
+
schedule(options: CreateTaskOptions): ScheduledTask;
|
|
60
|
+
cancel(taskId: string): boolean;
|
|
61
|
+
remove(taskId: string): boolean;
|
|
62
|
+
pause(taskId: string): boolean;
|
|
63
|
+
resume(taskId: string): boolean;
|
|
64
|
+
trigger(taskId: string): boolean;
|
|
65
|
+
get(taskId: string): ScheduledTask | undefined;
|
|
66
|
+
getByName(name: string): ScheduledTask | undefined;
|
|
67
|
+
getAll(): ScheduledTask[];
|
|
68
|
+
getPending(): ScheduledTask[];
|
|
69
|
+
getRunning(): ScheduledTask[];
|
|
70
|
+
getByTag(tag: string): ScheduledTask[];
|
|
71
|
+
stats(): {
|
|
72
|
+
total: number;
|
|
73
|
+
pending: number;
|
|
74
|
+
scheduled: number;
|
|
75
|
+
running: number;
|
|
76
|
+
completed: number;
|
|
77
|
+
failed: number;
|
|
78
|
+
cancelled: number;
|
|
79
|
+
paused: number;
|
|
80
|
+
};
|
|
81
|
+
on(handler: SchedulerEventHandler): () => void;
|
|
82
|
+
private emit;
|
|
83
|
+
private tick;
|
|
84
|
+
private getDueTasks;
|
|
85
|
+
private executeTask;
|
|
86
|
+
private runWithTimeout;
|
|
87
|
+
private calculateNextRun;
|
|
88
|
+
private sleep;
|
|
89
|
+
}
|
|
90
|
+
export declare function createScheduler(config?: Partial<SchedulerConfig>): Scheduler;
|