@geekbeer/minion 2.60.0 → 2.67.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.
- package/core/api.js +110 -0
- package/core/lib/config-warnings.js +85 -0
- package/core/lib/reflection-scheduler.js +1 -5
- package/core/lib/revision-watcher.js +12 -1
- package/core/lib/step-poller.js +12 -1
- package/core/lib/thread-watcher.js +359 -0
- package/core/routes/daemons.js +34 -0
- package/core/routes/help-threads.js +189 -0
- package/docs/api-reference.md +195 -0
- package/docs/environment-setup.md +75 -7
- package/linux/minion-cli.sh +6 -0
- package/linux/server.js +15 -2
- package/package.json +1 -1
- package/rules/core.md +45 -0
- package/win/minion-cli.ps1 +12 -2
- package/win/server.js +15 -2
package/win/minion-cli.ps1
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# minion-cli-win setup --hq-url https://... --minion-id <UUID> --api-token <TOKEN>
|
|
5
5
|
# minion-cli-win setup --setup-tunnel
|
|
6
6
|
# minion-cli-win uninstall [--keep-data]
|
|
7
|
-
# minion-cli-win start | stop | restart | status | health | diagnose | version | help
|
|
7
|
+
# minion-cli-win start | stop | restart | status | health | daemons | diagnose | version | help
|
|
8
8
|
|
|
9
9
|
# Parse arguments manually to avoid issues with npm wrapper passing $args as array
|
|
10
10
|
$Command = 'help'
|
|
@@ -18,7 +18,7 @@ $i = 0
|
|
|
18
18
|
while ($i -lt $args.Count) {
|
|
19
19
|
$arg = [string]$args[$i]
|
|
20
20
|
switch -Regex ($arg) {
|
|
21
|
-
'^(setup|reconfigure|uninstall|start|stop|restart|status|health|diagnose|version|help)$' { $Command = $arg }
|
|
21
|
+
'^(setup|reconfigure|uninstall|start|stop|restart|status|health|daemons|diagnose|version|help)$' { $Command = $arg }
|
|
22
22
|
'^(-v|--version)$' { $Command = 'version' }
|
|
23
23
|
'^--hq-url$' { $i++; if ($i -lt $args.Count) { $HqUrl = [string]$args[$i] } }
|
|
24
24
|
'^--minion-id$' { $i++; if ($i -lt $args.Count) { $MinionId = [string]$args[$i] } }
|
|
@@ -895,6 +895,7 @@ Remove-Item `$PidFile -Force -ErrorAction SilentlyContinue
|
|
|
895
895
|
Write-Host "Useful commands:"
|
|
896
896
|
Write-Host " minion-cli-win status # Agent status"
|
|
897
897
|
Write-Host " minion-cli-win health # Health check"
|
|
898
|
+
Write-Host " minion-cli-win daemons # Daemon status"
|
|
898
899
|
Write-Host " minion-cli-win restart # Restart agent"
|
|
899
900
|
Write-Host " minion-cli-win stop # Stop agent"
|
|
900
901
|
Write-Host " Get-Content $(Join-Path $LogDir 'service-stdout.log') -Tail 50 # View logs"
|
|
@@ -1164,6 +1165,15 @@ switch ($Command) {
|
|
|
1164
1165
|
Write-Error "Health check failed. Is the agent running?"
|
|
1165
1166
|
}
|
|
1166
1167
|
}
|
|
1168
|
+
'daemons' {
|
|
1169
|
+
try {
|
|
1170
|
+
$response = Invoke-RestMethod -Uri "$AgentUrl/api/daemons/status" -TimeoutSec 5
|
|
1171
|
+
$response | ConvertTo-Json -Depth 5
|
|
1172
|
+
}
|
|
1173
|
+
catch {
|
|
1174
|
+
Write-Error "Failed to get daemon status. Is the agent running?"
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1167
1177
|
'diagnose' {
|
|
1168
1178
|
Write-Host "Running diagnostics..."
|
|
1169
1179
|
Write-Host ""
|
package/win/server.js
CHANGED
|
@@ -23,15 +23,20 @@ const routineStore = require('../core/stores/routine-store')
|
|
|
23
23
|
// Heartbeat interval: fixed at 30s (not user-configurable)
|
|
24
24
|
const HEARTBEAT_INTERVAL_MS = 30_000
|
|
25
25
|
let heartbeatTimer = null
|
|
26
|
+
let lastBeatAt = null
|
|
26
27
|
|
|
27
28
|
// Windows-specific modules
|
|
28
29
|
const workflowRunner = require('./workflow-runner')
|
|
29
30
|
const routineRunner = require('./routine-runner')
|
|
30
31
|
|
|
32
|
+
// Config warnings (included in heartbeat)
|
|
33
|
+
const { getConfigWarnings } = require('../core/lib/config-warnings')
|
|
34
|
+
|
|
31
35
|
// Pull-model daemons (from core/)
|
|
32
36
|
const stepPoller = require('../core/lib/step-poller')
|
|
33
37
|
const revisionWatcher = require('../core/lib/revision-watcher')
|
|
34
38
|
const reflectionScheduler = require('../core/lib/reflection-scheduler')
|
|
39
|
+
const threadWatcher = require('../core/lib/thread-watcher')
|
|
35
40
|
const { commandRoutes, getProcessManager, getAllowedCommands } = require('./routes/commands')
|
|
36
41
|
const { terminalRoutes, cleanupSessions } = require('./routes/terminal')
|
|
37
42
|
const { startTerminalServer, stopTerminalServer } = require('./terminal-server')
|
|
@@ -51,6 +56,8 @@ const { variableRoutes } = require('../core/routes/variables')
|
|
|
51
56
|
const { memoryRoutes } = require('../core/routes/memory')
|
|
52
57
|
const { dailyLogRoutes } = require('../core/routes/daily-logs')
|
|
53
58
|
const { permissionRoutes } = require('../core/routes/permissions')
|
|
59
|
+
const { helpThreadRoutes } = require('../core/routes/help-threads')
|
|
60
|
+
const { daemonRoutes } = require('../core/routes/daemons')
|
|
54
61
|
|
|
55
62
|
// Validate configuration
|
|
56
63
|
validate()
|
|
@@ -86,6 +93,7 @@ async function shutdown(signal) {
|
|
|
86
93
|
stepPoller.stop()
|
|
87
94
|
revisionWatcher.stop()
|
|
88
95
|
reflectionScheduler.stop()
|
|
96
|
+
threadWatcher.stop()
|
|
89
97
|
workflowRunner.stopAll()
|
|
90
98
|
routineRunner.stopAll()
|
|
91
99
|
stopTerminalServer()
|
|
@@ -203,6 +211,8 @@ async function registerRoutes(app) {
|
|
|
203
211
|
await app.register(memoryRoutes)
|
|
204
212
|
await app.register(dailyLogRoutes)
|
|
205
213
|
await app.register(permissionRoutes)
|
|
214
|
+
await app.register(helpThreadRoutes)
|
|
215
|
+
await app.register(daemonRoutes, { heartbeatStatus: () => ({ running: !!heartbeatTimer, last_beat_at: lastBeatAt }) })
|
|
206
216
|
|
|
207
217
|
// Windows-specific routes
|
|
208
218
|
await app.register(commandRoutes)
|
|
@@ -284,14 +294,16 @@ async function start() {
|
|
|
284
294
|
// Send initial online heartbeat
|
|
285
295
|
const { getStatus } = require('../core/routes/health')
|
|
286
296
|
const { currentTask } = getStatus()
|
|
287
|
-
sendHeartbeat({ status: 'online', current_task: currentTask, version }).catch(err => {
|
|
297
|
+
sendHeartbeat({ status: 'online', current_task: currentTask, config_warnings: getConfigWarnings(), version }).catch(err => {
|
|
288
298
|
console.error('[Heartbeat] Initial heartbeat failed:', err.message)
|
|
289
299
|
})
|
|
290
300
|
|
|
291
301
|
// Start periodic heartbeat
|
|
292
302
|
heartbeatTimer = setInterval(() => {
|
|
293
303
|
const { currentStatus, currentTask } = getStatus()
|
|
294
|
-
sendHeartbeat({ status: currentStatus, current_task: currentTask, version }).
|
|
304
|
+
sendHeartbeat({ status: currentStatus, current_task: currentTask, config_warnings: getConfigWarnings(), version }).then(() => {
|
|
305
|
+
lastBeatAt = new Date().toISOString()
|
|
306
|
+
}).catch(err => {
|
|
295
307
|
console.error('[Heartbeat] Periodic heartbeat failed:', err.message)
|
|
296
308
|
})
|
|
297
309
|
}, HEARTBEAT_INTERVAL_MS)
|
|
@@ -300,6 +312,7 @@ async function start() {
|
|
|
300
312
|
// Start Pull-model daemons
|
|
301
313
|
stepPoller.start()
|
|
302
314
|
revisionWatcher.start()
|
|
315
|
+
threadWatcher.start(runQuickLlmCall)
|
|
303
316
|
} else {
|
|
304
317
|
console.log('[Server] Running in standalone mode (no HQ connection)')
|
|
305
318
|
}
|