nightshift-mcp 1.0.0

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.
Files changed (74) hide show
  1. package/README.md +670 -0
  2. package/dist/agent-spawner.d.ts +55 -0
  3. package/dist/agent-spawner.d.ts.map +1 -0
  4. package/dist/agent-spawner.js +468 -0
  5. package/dist/agent-spawner.js.map +1 -0
  6. package/dist/chat-manager.d.ts +72 -0
  7. package/dist/chat-manager.d.ts.map +1 -0
  8. package/dist/chat-manager.js +331 -0
  9. package/dist/chat-manager.js.map +1 -0
  10. package/dist/daemon.d.ts +65 -0
  11. package/dist/daemon.d.ts.map +1 -0
  12. package/dist/daemon.js +563 -0
  13. package/dist/daemon.js.map +1 -0
  14. package/dist/file-lock.d.ts +41 -0
  15. package/dist/file-lock.d.ts.map +1 -0
  16. package/dist/file-lock.js +157 -0
  17. package/dist/file-lock.js.map +1 -0
  18. package/dist/index.d.ts +3 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +2433 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/ralph-manager.d.ts +148 -0
  23. package/dist/ralph-manager.d.ts.map +1 -0
  24. package/dist/ralph-manager.js +399 -0
  25. package/dist/ralph-manager.js.map +1 -0
  26. package/dist/tool-registry.d.ts +130 -0
  27. package/dist/tool-registry.d.ts.map +1 -0
  28. package/dist/tool-registry.js +280 -0
  29. package/dist/tool-registry.js.map +1 -0
  30. package/dist/tools/agents.d.ts +7 -0
  31. package/dist/tools/agents.d.ts.map +1 -0
  32. package/dist/tools/agents.js +366 -0
  33. package/dist/tools/agents.js.map +1 -0
  34. package/dist/tools/bugs.d.ts +6 -0
  35. package/dist/tools/bugs.d.ts.map +1 -0
  36. package/dist/tools/bugs.js +184 -0
  37. package/dist/tools/bugs.js.map +1 -0
  38. package/dist/tools/chat.d.ts +10 -0
  39. package/dist/tools/chat.d.ts.map +1 -0
  40. package/dist/tools/chat.js +287 -0
  41. package/dist/tools/chat.js.map +1 -0
  42. package/dist/tools/index.d.ts +33 -0
  43. package/dist/tools/index.d.ts.map +1 -0
  44. package/dist/tools/index.js +51 -0
  45. package/dist/tools/index.js.map +1 -0
  46. package/dist/tools/prd.d.ts +8 -0
  47. package/dist/tools/prd.d.ts.map +1 -0
  48. package/dist/tools/prd.js +275 -0
  49. package/dist/tools/prd.js.map +1 -0
  50. package/dist/tools/progress.d.ts +5 -0
  51. package/dist/tools/progress.d.ts.map +1 -0
  52. package/dist/tools/progress.js +81 -0
  53. package/dist/tools/progress.js.map +1 -0
  54. package/dist/tools/savepoints.d.ts +5 -0
  55. package/dist/tools/savepoints.d.ts.map +1 -0
  56. package/dist/tools/savepoints.js +100 -0
  57. package/dist/tools/savepoints.js.map +1 -0
  58. package/dist/tools/utility.d.ts +4 -0
  59. package/dist/tools/utility.d.ts.map +1 -0
  60. package/dist/tools/utility.js +375 -0
  61. package/dist/tools/utility.js.map +1 -0
  62. package/dist/tools/workflow.d.ts +10 -0
  63. package/dist/tools/workflow.d.ts.map +1 -0
  64. package/dist/tools/workflow.js +321 -0
  65. package/dist/tools/workflow.js.map +1 -0
  66. package/dist/types.d.ts +105 -0
  67. package/dist/types.d.ts.map +1 -0
  68. package/dist/types.js +2 -0
  69. package/dist/types.js.map +1 -0
  70. package/dist/workflow-manager.d.ts +154 -0
  71. package/dist/workflow-manager.d.ts.map +1 -0
  72. package/dist/workflow-manager.js +356 -0
  73. package/dist/workflow-manager.js.map +1 -0
  74. package/package.json +48 -0
package/dist/daemon.js ADDED
@@ -0,0 +1,563 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * NightShift Daemon
4
+ *
5
+ * Event-driven orchestrator with polling fallback.
6
+ * Manages agent lifecycle, story assignments, and failover handling.
7
+ */
8
+ import * as fs from "fs";
9
+ import * as path from "path";
10
+ import { RalphManager } from "./ralph-manager.js";
11
+ import { ChatManager } from "./chat-manager.js";
12
+ import { WorkflowManager } from "./workflow-manager.js";
13
+ import { spawnAgentBackground, getAvailableAgents, } from "./agent-spawner.js";
14
+ // ============================================
15
+ // Daemon Class
16
+ // ============================================
17
+ export class NightShiftDaemon {
18
+ config;
19
+ ralph;
20
+ chat;
21
+ workflow;
22
+ // State
23
+ running = false;
24
+ activeAgents = new Map();
25
+ storyStates = new Map();
26
+ availableAgents = [];
27
+ agentIndex = 0; // Round-robin
28
+ // File watchers
29
+ prdWatcher = null;
30
+ chatWatcher = null;
31
+ watchersHealthy = true;
32
+ // Timers
33
+ healthCheckTimer = null;
34
+ debounceTimers = new Map();
35
+ // Singleton lock
36
+ lockFile;
37
+ lockFd = null;
38
+ constructor(config) {
39
+ this.config = {
40
+ projectPath: config.projectPath,
41
+ healthCheckInterval: config.healthCheckInterval ?? 2 * 60 * 1000, // 2 minutes
42
+ debounceInterval: config.debounceInterval ?? 500, // 500ms
43
+ stuckTimeout: config.stuckTimeout ?? 15 * 60 * 1000, // 15 minutes
44
+ maxConcurrentAgents: config.maxConcurrentAgents ?? 3,
45
+ maxRetries: config.maxRetries ?? 3,
46
+ agents: config.agents ?? ["claude", "codex", "gemini", "vibe"],
47
+ verbose: config.verbose ?? false,
48
+ dryRun: config.dryRun ?? false,
49
+ };
50
+ this.ralph = new RalphManager(this.config.projectPath);
51
+ this.chat = new ChatManager(this.config.projectPath);
52
+ this.workflow = new WorkflowManager(this.config.projectPath);
53
+ this.lockFile = path.join(this.config.projectPath, ".robot-chat", "daemon.lock");
54
+ }
55
+ // ============================================
56
+ // Logging
57
+ // ============================================
58
+ log(level, message, data) {
59
+ if (level === "debug" && !this.config.verbose)
60
+ return;
61
+ const timestamp = new Date().toISOString();
62
+ const prefix = {
63
+ info: "ℹ️ ",
64
+ warn: "⚠️ ",
65
+ error: "❌",
66
+ debug: "🔍",
67
+ }[level];
68
+ const logLine = `[${timestamp}] ${prefix} ${message}`;
69
+ if (level === "error") {
70
+ console.error(logLine, data ?? "");
71
+ }
72
+ else {
73
+ console.log(logLine, data ? JSON.stringify(data) : "");
74
+ }
75
+ }
76
+ // ============================================
77
+ // Singleton Lock
78
+ // ============================================
79
+ acquireLock() {
80
+ try {
81
+ const lockDir = path.dirname(this.lockFile);
82
+ if (!fs.existsSync(lockDir)) {
83
+ fs.mkdirSync(lockDir, { recursive: true });
84
+ }
85
+ // Try to open exclusively
86
+ this.lockFd = fs.openSync(this.lockFile, "wx");
87
+ fs.writeFileSync(this.lockFile, String(process.pid));
88
+ // Clean up on exit
89
+ process.on("exit", () => this.releaseLock());
90
+ process.on("SIGINT", () => { this.releaseLock(); process.exit(0); });
91
+ process.on("SIGTERM", () => { this.releaseLock(); process.exit(0); });
92
+ return true;
93
+ }
94
+ catch (err) {
95
+ if (err.code === "EEXIST") {
96
+ // Check if the process is still running
97
+ try {
98
+ const pid = parseInt(fs.readFileSync(this.lockFile, "utf-8").trim());
99
+ process.kill(pid, 0); // Check if process exists
100
+ this.log("error", `Another daemon is running (PID: ${pid})`);
101
+ return false;
102
+ }
103
+ catch {
104
+ // Process doesn't exist, remove stale lock
105
+ fs.unlinkSync(this.lockFile);
106
+ return this.acquireLock();
107
+ }
108
+ }
109
+ throw err;
110
+ }
111
+ }
112
+ releaseLock() {
113
+ try {
114
+ if (this.lockFd !== null) {
115
+ fs.closeSync(this.lockFd);
116
+ this.lockFd = null;
117
+ }
118
+ if (fs.existsSync(this.lockFile)) {
119
+ fs.unlinkSync(this.lockFile);
120
+ }
121
+ }
122
+ catch {
123
+ // Ignore cleanup errors
124
+ }
125
+ }
126
+ // ============================================
127
+ // File Watchers
128
+ // ============================================
129
+ startWatchers() {
130
+ const prdPath = path.join(this.config.projectPath, "prd.json");
131
+ const chatPath = path.join(this.config.projectPath, ".robot-chat", "chat.txt");
132
+ try {
133
+ // Watch prd.json for story changes
134
+ if (fs.existsSync(prdPath)) {
135
+ this.prdWatcher = fs.watch(prdPath, (event) => {
136
+ if (event === "change") {
137
+ this.debounce("prd", () => this.onPrdChanged());
138
+ }
139
+ });
140
+ this.log("info", "Watching prd.json");
141
+ }
142
+ // Watch chat.txt for failovers and completions
143
+ if (fs.existsSync(chatPath)) {
144
+ this.chatWatcher = fs.watch(chatPath, (event) => {
145
+ if (event === "change") {
146
+ this.debounce("chat", () => this.onChatChanged());
147
+ }
148
+ });
149
+ this.log("info", "Watching chat.txt");
150
+ }
151
+ this.watchersHealthy = true;
152
+ }
153
+ catch (err) {
154
+ this.log("error", "Failed to start file watchers", { error: String(err) });
155
+ this.watchersHealthy = false;
156
+ }
157
+ }
158
+ stopWatchers() {
159
+ if (this.prdWatcher) {
160
+ this.prdWatcher.close();
161
+ this.prdWatcher = null;
162
+ }
163
+ if (this.chatWatcher) {
164
+ this.chatWatcher.close();
165
+ this.chatWatcher = null;
166
+ }
167
+ }
168
+ restartWatchers() {
169
+ this.log("warn", "Restarting file watchers");
170
+ this.stopWatchers();
171
+ this.startWatchers();
172
+ }
173
+ debounce(key, fn) {
174
+ const existing = this.debounceTimers.get(key);
175
+ if (existing) {
176
+ clearTimeout(existing);
177
+ }
178
+ const timer = setTimeout(() => {
179
+ this.debounceTimers.delete(key);
180
+ fn();
181
+ }, this.config.debounceInterval);
182
+ this.debounceTimers.set(key, timer);
183
+ }
184
+ // ============================================
185
+ // Event Handlers
186
+ // ============================================
187
+ async onPrdChanged() {
188
+ this.log("debug", "PRD changed");
189
+ await this.reconcile();
190
+ }
191
+ async onChatChanged() {
192
+ this.log("debug", "Chat changed");
193
+ // Check for failovers
194
+ const failovers = this.chat.findUnclaimedFailovers();
195
+ for (const failover of failovers) {
196
+ this.log("info", `Found unclaimed failover from ${failover.requestingAgent}`);
197
+ await this.handleFailover(failover);
198
+ }
199
+ // Update agent activity timestamps
200
+ const recentMessages = this.chat.readMessages({ limit: 10 });
201
+ for (const msg of recentMessages) {
202
+ // Find agent process and update lastActivity
203
+ for (const [storyId, proc] of this.activeAgents) {
204
+ if (msg.content.includes(storyId)) {
205
+ proc.lastActivity = Date.now();
206
+ }
207
+ }
208
+ }
209
+ await this.reconcile();
210
+ }
211
+ async handleFailover(failover) {
212
+ if (this.config.dryRun) {
213
+ this.log("info", `[DRY RUN] Would claim failover from ${failover.requestingAgent}`);
214
+ return;
215
+ }
216
+ // Extract story ID from failover message if possible
217
+ const storyMatch = failover.message.content.match(/US-\d+/);
218
+ const storyId = storyMatch?.[0];
219
+ if (storyId) {
220
+ // Remove from active agents if tracked
221
+ this.activeAgents.delete(storyId);
222
+ }
223
+ // Claim the failover
224
+ const nextAgent = this.getNextAgent();
225
+ if (nextAgent) {
226
+ await this.chat.claimFailover(nextAgent, failover.requestingAgent, failover.task);
227
+ this.log("info", `${nextAgent} claimed failover from ${failover.requestingAgent}`);
228
+ }
229
+ }
230
+ // ============================================
231
+ // Reconciliation Loop
232
+ // ============================================
233
+ async reconcile() {
234
+ if (!this.running)
235
+ return;
236
+ this.log("debug", "Reconciling state");
237
+ // Get current state
238
+ const prd = this.ralph.readPRD();
239
+ if (!prd) {
240
+ this.log("warn", "No prd.json found");
241
+ return;
242
+ }
243
+ const incomplete = prd.userStories.filter(s => !s.passes);
244
+ const activeCount = this.activeAgents.size;
245
+ // Check if all complete
246
+ if (incomplete.length === 0) {
247
+ this.log("info", "🎉 All stories complete!");
248
+ await this.shutdown();
249
+ return;
250
+ }
251
+ // Find orphaned stories (incomplete but not assigned)
252
+ const assignedIds = new Set(this.activeAgents.keys());
253
+ const orphaned = incomplete.filter(s => !assignedIds.has(s.id) &&
254
+ !this.isQuarantined(s.id));
255
+ // Spawn agents for orphaned stories up to concurrency limit
256
+ const slotsAvailable = this.config.maxConcurrentAgents - activeCount;
257
+ const toSpawn = orphaned.slice(0, slotsAvailable);
258
+ for (const story of toSpawn) {
259
+ await this.spawnAgentForStory(story.id);
260
+ }
261
+ // Log status
262
+ this.log("info", `Status: ${incomplete.length} incomplete, ${activeCount} active, ${orphaned.length} orphaned`);
263
+ }
264
+ // ============================================
265
+ // Agent Management
266
+ // ============================================
267
+ getNextAgent() {
268
+ if (this.availableAgents.length === 0)
269
+ return null;
270
+ const agent = this.availableAgents[this.agentIndex % this.availableAgents.length];
271
+ this.agentIndex++;
272
+ return agent;
273
+ }
274
+ async spawnAgentForStory(storyId) {
275
+ const agent = this.getNextAgent();
276
+ if (!agent) {
277
+ this.log("warn", "No agents available");
278
+ return;
279
+ }
280
+ if (this.config.dryRun) {
281
+ this.log("info", `[DRY RUN] Would spawn ${agent} for ${storyId}`);
282
+ return;
283
+ }
284
+ this.log("info", `Spawning ${agent} for ${storyId}`);
285
+ // Get story details
286
+ const story = this.ralph.getStory(storyId);
287
+ if (!story) {
288
+ this.log("error", `Story ${storyId} not found`);
289
+ return;
290
+ }
291
+ // Build prompt
292
+ const prompt = this.buildAgentPrompt(story);
293
+ // Spawn in background
294
+ const result = spawnAgentBackground({
295
+ agent,
296
+ prompt,
297
+ projectPath: this.config.projectPath,
298
+ });
299
+ // Track the agent
300
+ this.activeAgents.set(storyId, {
301
+ agent,
302
+ storyId,
303
+ pid: result.pid,
304
+ startTime: Date.now(),
305
+ lastActivity: Date.now(),
306
+ outputFile: result.outputFile,
307
+ });
308
+ // Post to chat
309
+ this.chat.writeMessage({
310
+ agent: "NightShift",
311
+ type: "INFO",
312
+ content: `Spawned ${agent} to work on ${storyId}: ${story.title}`,
313
+ });
314
+ // Monitor the agent process
315
+ this.monitorAgent(storyId, result.pid, result.outputFile);
316
+ }
317
+ buildAgentPrompt(story) {
318
+ const progress = this.ralph.readProgress();
319
+ return `You are working on a NightShift MCP project.
320
+
321
+ ## Your Task
322
+ Story: ${story.id} - ${story.title}
323
+ Description: ${story.description}
324
+
325
+ Acceptance Criteria:
326
+ ${story.acceptanceCriteria.map((c) => `- ${c}`).join("\n")}
327
+
328
+ ## Instructions
329
+ 1. Read CLAUDE.md for project context and nightshift tools
330
+ 2. Use claim_story to claim ${story.id}
331
+ 3. Implement the story
332
+ 4. Run quality checks (typecheck, lint, test)
333
+ 5. Commit your changes
334
+ 6. Use complete_story when done
335
+
336
+ ## Progress Context
337
+ ${progress ? progress.substring(0, 2000) : "No progress file yet."}
338
+
339
+ ## Important
340
+ - If you hit rate limits or context limits, post FAILOVER_NEEDED
341
+ - Post STATUS_UPDATE messages periodically
342
+ - Focus only on this story, don't work on others
343
+ `;
344
+ }
345
+ monitorAgent(storyId, pid, outputFile) {
346
+ if (!pid)
347
+ return;
348
+ // Check periodically if process is still running
349
+ const checkInterval = setInterval(() => {
350
+ try {
351
+ process.kill(pid, 0); // Check if process exists
352
+ }
353
+ catch {
354
+ // Process exited
355
+ clearInterval(checkInterval);
356
+ this.onAgentExit(storyId, pid);
357
+ }
358
+ }, 10000); // Check every 10 seconds
359
+ }
360
+ async onAgentExit(storyId, pid) {
361
+ const agentProc = this.activeAgents.get(storyId);
362
+ if (!agentProc)
363
+ return;
364
+ this.log("info", `Agent ${agentProc.agent} (PID: ${pid}) exited for ${storyId}`);
365
+ // Check if story is complete
366
+ const story = this.ralph.getStory(storyId);
367
+ if (story?.passes) {
368
+ this.log("info", `✅ ${storyId} completed successfully`);
369
+ this.activeAgents.delete(storyId);
370
+ }
371
+ else {
372
+ // Agent exited without completing - might need retry
373
+ this.incrementRetry(storyId);
374
+ this.activeAgents.delete(storyId);
375
+ if (this.isQuarantined(storyId)) {
376
+ this.log("warn", `${storyId} quarantined after ${this.config.maxRetries} failures`);
377
+ }
378
+ }
379
+ // Reconcile to pick up more work
380
+ await this.reconcile();
381
+ }
382
+ incrementRetry(storyId) {
383
+ const state = this.storyStates.get(storyId) ?? {
384
+ id: storyId,
385
+ retryCount: 0,
386
+ quarantined: false,
387
+ };
388
+ state.retryCount++;
389
+ if (state.retryCount >= this.config.maxRetries) {
390
+ state.quarantined = true;
391
+ }
392
+ this.storyStates.set(storyId, state);
393
+ }
394
+ isQuarantined(storyId) {
395
+ return this.storyStates.get(storyId)?.quarantined ?? false;
396
+ }
397
+ // ============================================
398
+ // Health Check (Polling Fallback)
399
+ // ============================================
400
+ startHealthCheck() {
401
+ this.healthCheckTimer = setInterval(() => this.healthCheck(), this.config.healthCheckInterval);
402
+ // Run immediately on start
403
+ this.healthCheck();
404
+ }
405
+ stopHealthCheck() {
406
+ if (this.healthCheckTimer) {
407
+ clearInterval(this.healthCheckTimer);
408
+ this.healthCheckTimer = null;
409
+ }
410
+ }
411
+ async healthCheck() {
412
+ this.log("debug", "Running health check");
413
+ // 1. Check for stuck agents
414
+ const now = Date.now();
415
+ for (const [storyId, proc] of this.activeAgents) {
416
+ const inactiveTime = now - proc.lastActivity;
417
+ if (inactiveTime > this.config.stuckTimeout) {
418
+ this.log("warn", `Agent ${proc.agent} stuck on ${storyId} (inactive ${Math.round(inactiveTime / 60000)}min)`);
419
+ // Kill the stuck process
420
+ if (proc.pid) {
421
+ try {
422
+ process.kill(proc.pid, "SIGTERM");
423
+ }
424
+ catch {
425
+ // Process may already be dead
426
+ }
427
+ }
428
+ this.activeAgents.delete(storyId);
429
+ this.incrementRetry(storyId);
430
+ }
431
+ }
432
+ // 2. Check for unclaimed failovers
433
+ const failovers = this.chat.findUnclaimedFailovers();
434
+ if (failovers.length > 0) {
435
+ this.log("info", `Health check found ${failovers.length} unclaimed failovers`);
436
+ for (const failover of failovers) {
437
+ await this.handleFailover(failover);
438
+ }
439
+ }
440
+ // 3. Restart watchers if needed
441
+ if (!this.watchersHealthy) {
442
+ this.restartWatchers();
443
+ }
444
+ // 4. Reconcile state
445
+ await this.reconcile();
446
+ }
447
+ // ============================================
448
+ // Lifecycle
449
+ // ============================================
450
+ async start() {
451
+ this.log("info", "Starting NightShift daemon");
452
+ // Acquire singleton lock
453
+ if (!this.acquireLock()) {
454
+ this.log("error", "Could not acquire lock - another daemon may be running");
455
+ process.exit(1);
456
+ }
457
+ // Check available agents
458
+ this.availableAgents = await getAvailableAgents();
459
+ const configuredAgents = this.config.agents.filter(a => this.availableAgents.includes(a));
460
+ if (configuredAgents.length === 0) {
461
+ this.log("error", "No configured agents are available");
462
+ process.exit(1);
463
+ }
464
+ this.availableAgents = configuredAgents;
465
+ this.log("info", `Available agents: ${this.availableAgents.join(", ")}`);
466
+ this.running = true;
467
+ // Start event watchers (primary)
468
+ this.startWatchers();
469
+ // Start health check (fallback)
470
+ this.startHealthCheck();
471
+ this.log("info", "Daemon started successfully");
472
+ this.log("info", `Health check interval: ${this.config.healthCheckInterval / 1000}s`);
473
+ this.log("info", `Max concurrent agents: ${this.config.maxConcurrentAgents}`);
474
+ // Initial reconciliation
475
+ await this.reconcile();
476
+ }
477
+ async shutdown() {
478
+ this.log("info", "Shutting down daemon");
479
+ this.running = false;
480
+ // Stop timers
481
+ this.stopHealthCheck();
482
+ for (const timer of this.debounceTimers.values()) {
483
+ clearTimeout(timer);
484
+ }
485
+ this.debounceTimers.clear();
486
+ // Stop watchers
487
+ this.stopWatchers();
488
+ // Release lock
489
+ this.releaseLock();
490
+ this.log("info", "Daemon stopped");
491
+ process.exit(0);
492
+ }
493
+ }
494
+ // ============================================
495
+ // CLI Entry Point
496
+ // ============================================
497
+ async function main() {
498
+ const args = process.argv.slice(2);
499
+ // Parse arguments
500
+ const projectPath = process.env.ROBOT_CHAT_PROJECT_PATH || process.cwd();
501
+ let verbose = false;
502
+ let dryRun = false;
503
+ let healthCheckInterval = 2 * 60 * 1000;
504
+ let maxConcurrentAgents = 3;
505
+ for (let i = 0; i < args.length; i++) {
506
+ switch (args[i]) {
507
+ case "--verbose":
508
+ case "-v":
509
+ verbose = true;
510
+ break;
511
+ case "--dry-run":
512
+ dryRun = true;
513
+ break;
514
+ case "--health-check":
515
+ const interval = args[++i];
516
+ if (interval?.endsWith("m")) {
517
+ healthCheckInterval = parseInt(interval) * 60 * 1000;
518
+ }
519
+ else if (interval?.endsWith("s")) {
520
+ healthCheckInterval = parseInt(interval) * 1000;
521
+ }
522
+ break;
523
+ case "--max-agents":
524
+ maxConcurrentAgents = parseInt(args[++i]) || 3;
525
+ break;
526
+ case "--help":
527
+ case "-h":
528
+ console.log(`
529
+ NightShift Daemon - Event-driven multi-agent orchestrator
530
+
531
+ Usage: nightshift-daemon [options]
532
+
533
+ Options:
534
+ --verbose, -v Enable verbose logging
535
+ --dry-run Show what would happen without spawning agents
536
+ --health-check <N> Health check interval (e.g., "2m", "30s") [default: 2m]
537
+ --max-agents <N> Maximum concurrent agents [default: 3]
538
+ --help, -h Show this help
539
+
540
+ Environment:
541
+ ROBOT_CHAT_PROJECT_PATH Project directory [default: cwd]
542
+ `);
543
+ process.exit(0);
544
+ }
545
+ }
546
+ const daemon = new NightShiftDaemon({
547
+ projectPath,
548
+ verbose,
549
+ dryRun,
550
+ healthCheckInterval,
551
+ maxConcurrentAgents,
552
+ });
553
+ await daemon.start();
554
+ }
555
+ // Run if executed directly
556
+ const isMain = import.meta.url === `file://${process.argv[1]}`;
557
+ if (isMain) {
558
+ main().catch((err) => {
559
+ console.error("Fatal error:", err);
560
+ process.exit(1);
561
+ });
562
+ }
563
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Options for file operations with locking
3
+ */
4
+ export interface LockOptions {
5
+ retries?: number;
6
+ stale?: number;
7
+ }
8
+ /**
9
+ * Execute a function with exclusive file lock
10
+ */
11
+ export declare function withFileLock<T>(filePath: string, fn: () => T | Promise<T>, options?: LockOptions): Promise<T>;
12
+ /**
13
+ * Read a file with locking
14
+ */
15
+ export declare function readFileWithLock(filePath: string, options?: LockOptions): Promise<string>;
16
+ /**
17
+ * Write a file with locking
18
+ */
19
+ export declare function writeFileWithLock(filePath: string, content: string, options?: LockOptions): Promise<void>;
20
+ /**
21
+ * Append to a file with locking
22
+ */
23
+ export declare function appendFileWithLock(filePath: string, content: string, options?: LockOptions): Promise<void>;
24
+ /**
25
+ * Read and parse JSON with locking, with safe fallback on parse error
26
+ */
27
+ export declare function readJsonWithLock<T>(filePath: string, defaultValue: T, options?: LockOptions): Promise<T>;
28
+ /**
29
+ * Write JSON with locking
30
+ */
31
+ export declare function writeJsonWithLock<T>(filePath: string, data: T, options?: LockOptions): Promise<void>;
32
+ /**
33
+ * Atomic read-modify-write operation with locking
34
+ */
35
+ export declare function modifyJsonWithLock<T>(filePath: string, modifier: (current: T | null) => T, options?: LockOptions): Promise<T>;
36
+ /**
37
+ * Escape shell string to prevent command injection
38
+ * Escapes single quotes, backticks, and $() constructs
39
+ */
40
+ export declare function escapeShellString(str: string): string;
41
+ //# sourceMappingURL=file-lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-lock.d.ts","sourceRoot":"","sources":["../src/file-lock.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAOD;;GAEG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAClC,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EACxB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,CAAC,CAAC,CA+BZ;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,MAAM,CAAC,CAWjB;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,CAAC,EACf,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,CAAC,CAAC,CAuBZ;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,CAAC,EACP,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,CAAC,EACxC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,KAAK,CAAC,EAClC,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,CAAC,CAAC,CA+BZ;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAiBrD"}