@sesamespace/hivemind 0.11.3 → 0.11.4
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.
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"timestamp": "2026-03-10T00:00:00Z",
|
|
3
|
+
"summary": "Fixed stale PID reporting in `hivemind service status` by rewriting showStatus() to parse PIDs from `launchctl list` output instead of PID files. Added kickstart recovery for KeepAlive services (memory, watchdog). Removed hardcoded wrapper scripts from git tracking and added them to .gitignore since they are generated dynamically during `hivemind service install`.",
|
|
4
|
+
"decisions": [
|
|
5
|
+
{
|
|
6
|
+
"topic": "PID source",
|
|
7
|
+
"choice": "Parse PID from launchctl list output using regex",
|
|
8
|
+
"rationale": "launchctl is the authoritative source for launchd-managed process PIDs; PID files go stale when launchd restarts a crashed process",
|
|
9
|
+
"alternatives_considered": ["Keep PID file approach with periodic refresh", "Use ps/pgrep to find processes"]
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"topic": "Stale service recovery",
|
|
13
|
+
"choice": "Auto-kickstart KeepAlive services (memory, watchdog) but not agent",
|
|
14
|
+
"rationale": "Agent is managed by watchdog, so kickstarting it from status would bypass watchdog's coordination",
|
|
15
|
+
"alternatives_considered": ["Kickstart all services", "Only report status without recovery"]
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"patterns": [
|
|
19
|
+
{
|
|
20
|
+
"pattern": "Wrapper scripts in bin/ are generated dynamically during `hivemind service install` with correct local paths — never commit them",
|
|
21
|
+
"scope": "project-wide"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"gotchas": [
|
|
25
|
+
{
|
|
26
|
+
"issue": "Wrapper scripts had hardcoded paths from another developer's machine committed to git",
|
|
27
|
+
"resolution": "Removed from git tracking with `git rm --cached`, added bin/*-wrapper.sh to .gitignore",
|
|
28
|
+
"prevention": "The .gitignore entry will prevent future accidental commits"
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
"files_changed": [
|
|
32
|
+
{
|
|
33
|
+
"path": "packages/cli/src/commands/service.ts",
|
|
34
|
+
"action": "modified",
|
|
35
|
+
"purpose": "Rewrote showStatus() to use launchctl as PID source with kickstart recovery"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"path": ".gitignore",
|
|
39
|
+
"action": "modified",
|
|
40
|
+
"purpose": "Added bin/*-wrapper.sh pattern"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"path": "bin/agent-wrapper.sh",
|
|
44
|
+
"action": "deleted",
|
|
45
|
+
"purpose": "Removed hardcoded wrapper script from git tracking"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"path": "bin/memory-wrapper.sh",
|
|
49
|
+
"action": "deleted",
|
|
50
|
+
"purpose": "Removed hardcoded wrapper script from git tracking"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"path": "bin/watchdog-wrapper.sh",
|
|
54
|
+
"action": "deleted",
|
|
55
|
+
"purpose": "Removed hardcoded wrapper script from git tracking"
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// packages/cli/src/commands/service.ts
|
|
2
2
|
import { resolve } from "path";
|
|
3
|
-
import { writeFileSync, existsSync, unlinkSync, mkdirSync
|
|
3
|
+
import { writeFileSync, existsSync, unlinkSync, mkdirSync } from "fs";
|
|
4
4
|
import { execSync } from "child_process";
|
|
5
5
|
import { homedir } from "os";
|
|
6
6
|
var LAUNCH_AGENTS_DIR = resolve(homedir(), "Library/LaunchAgents");
|
|
@@ -291,6 +291,7 @@ function startService() {
|
|
|
291
291
|
}
|
|
292
292
|
function showStatus() {
|
|
293
293
|
console.log("\n\u2192 Service status\n");
|
|
294
|
+
const keepAliveServices = /* @__PURE__ */ new Set([MEMORY_LABEL, WATCHDOG_LABEL]);
|
|
294
295
|
const pidFiles = {
|
|
295
296
|
[AGENT_LABEL]: "/tmp/hivemind-agent.pid",
|
|
296
297
|
[WATCHDOG_LABEL]: "/tmp/hivemind-watchdog.pid",
|
|
@@ -298,25 +299,32 @@ function showStatus() {
|
|
|
298
299
|
};
|
|
299
300
|
for (const label of [AGENT_LABEL, WATCHDOG_LABEL, MEMORY_LABEL]) {
|
|
300
301
|
try {
|
|
301
|
-
execSync(`launchctl list ${label} 2>/dev/null`, { encoding: "utf-8" });
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
const filePid = readFileSync(pidFile, "utf-8").trim();
|
|
306
|
-
try {
|
|
307
|
-
execSync(`ps -p ${filePid} > /dev/null 2>&1`);
|
|
308
|
-
pid = filePid;
|
|
309
|
-
} catch {
|
|
310
|
-
pid = "stale";
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
if (pid === "stale") {
|
|
314
|
-
console.log(` ! ${label}: loaded but not running (stale PID file)`);
|
|
302
|
+
const listOutput = execSync(`launchctl list ${label} 2>/dev/null`, { encoding: "utf-8" });
|
|
303
|
+
const pidMatch = listOutput.match(/"PID"\s*=\s*(\d+)/);
|
|
304
|
+
if (pidMatch) {
|
|
305
|
+
console.log(` \u2713 ${label}: running (PID ${pidMatch[1]})`);
|
|
315
306
|
} else {
|
|
316
|
-
|
|
307
|
+
const pidFile = pidFiles[label];
|
|
308
|
+
if (pidFile && existsSync(pidFile)) {
|
|
309
|
+
try {
|
|
310
|
+
unlinkSync(pidFile);
|
|
311
|
+
} catch {
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
if (keepAliveServices.has(label)) {
|
|
315
|
+
try {
|
|
316
|
+
const uid = execSync("id -u", { encoding: "utf-8" }).trim();
|
|
317
|
+
execSync(`launchctl kickstart gui/${uid}/${label} 2>/dev/null`);
|
|
318
|
+
console.log(` ! ${label}: was not running, kickstarted`);
|
|
319
|
+
} catch {
|
|
320
|
+
console.log(` ! ${label}: loaded but not running`);
|
|
321
|
+
}
|
|
322
|
+
} else {
|
|
323
|
+
console.log(` ! ${label}: loaded but not running`);
|
|
324
|
+
}
|
|
317
325
|
}
|
|
318
326
|
} catch {
|
|
319
|
-
console.log(` - ${label}: not
|
|
327
|
+
console.log(` - ${label}: not loaded`);
|
|
320
328
|
}
|
|
321
329
|
}
|
|
322
330
|
try {
|
|
@@ -364,4 +372,4 @@ Services:
|
|
|
364
372
|
export {
|
|
365
373
|
runServiceCommand
|
|
366
374
|
};
|
|
367
|
-
//# sourceMappingURL=chunk-
|
|
375
|
+
//# sourceMappingURL=chunk-6QZDXOMW.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../packages/cli/src/commands/service.ts"],"sourcesContent":["import { resolve } from \"path\";\nimport { writeFileSync, existsSync, unlinkSync, mkdirSync, readFileSync } from \"fs\";\nimport { execSync } from \"child_process\";\nimport { homedir } from \"os\";\n\nconst LAUNCH_AGENTS_DIR = resolve(homedir(), \"Library/LaunchAgents\");\nconst AGENT_LABEL = \"com.hivemind.agent\";\nconst WATCHDOG_LABEL = \"com.hivemind.watchdog\";\nconst MEMORY_LABEL = \"com.hivemind.memory\";\nconst STOP_FLAG_FILE = \"/tmp/hivemind-agent.stopped\";\n\nfunction getHivemindHome(): string {\n return process.env.HIVEMIND_HOME || resolve(homedir(), \"hivemind\");\n}\n\nfunction getHivemindBin(): string {\n // Try to find the hivemind binary\n try {\n const which = execSync(\"which hivemind\", { encoding: \"utf-8\" }).trim();\n if (which) return which;\n } catch {}\n // Fallback to process.argv[1] (the script being run)\n return process.argv[1] || \"hivemind\";\n}\n\nfunction generateMemoryPlist(hivemindHome: string): string {\n const memoryBin = resolve(hivemindHome, \"bin\", \"hivemind-memory\");\n const dbPath = resolve(hivemindHome, \"data\", \"lancedb\");\n const pidFile = `/tmp/hivemind-memory.pid`;\n \n // Create a wrapper script that writes PID\n const wrapperScript = resolve(hivemindHome, \"bin\", \"memory-wrapper.sh\");\n const wrapperContent = `#!/bin/bash\necho $$ > ${pidFile}\nexec \"${memoryBin}\" \"$@\"\n`;\n writeFileSync(wrapperScript, wrapperContent);\n execSync(`chmod +x \"${wrapperScript}\"`);\n \n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${MEMORY_LABEL}</string>\n <key>ProgramArguments</key>\n <array>\n <string>${wrapperScript}</string>\n </array>\n <key>WorkingDirectory</key>\n <string>${hivemindHome}</string>\n <key>EnvironmentVariables</key>\n <dict>\n <key>PORT</key>\n <string>3434</string>\n <key>DB_PATH</key>\n <string>${dbPath}</string>\n <key>OLLAMA_URL</key>\n <string>http://localhost:11434</string>\n <key>EMBEDDING_MODEL</key>\n <string>nomic-embed-text</string>\n </dict>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <true/>\n <key>StandardOutPath</key>\n <string>/tmp/hivemind-memory.log</string>\n <key>StandardErrorPath</key>\n <string>/tmp/hivemind-memory-error.log</string>\n <key>ThrottleInterval</key>\n <integer>5</integer>\n</dict>\n</plist>`;\n}\n\nfunction generateWatchdogPlist(hivemindHome: string, hivemindBin: string): string {\n const pidFile = `/tmp/hivemind-watchdog.pid`;\n \n // Create a wrapper script that writes PID\n const wrapperScript = resolve(hivemindHome, \"bin\", \"watchdog-wrapper.sh\");\n const wrapperContent = `#!/bin/bash\necho $$ > ${pidFile}\nexec \"${hivemindBin}\" watchdog \"$@\"\n`;\n writeFileSync(wrapperScript, wrapperContent);\n execSync(`chmod +x \"${wrapperScript}\"`);\n \n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${WATCHDOG_LABEL}</string>\n <key>ProgramArguments</key>\n <array>\n <string>${wrapperScript}</string>\n </array>\n <key>WorkingDirectory</key>\n <string>${hivemindHome}</string>\n <key>EnvironmentVariables</key>\n <dict>\n <key>PATH</key>\n <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>\n <key>HIVEMIND_HOME</key>\n <string>${hivemindHome}</string>\n </dict>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <true/>\n <key>StandardOutPath</key>\n <string>/tmp/hivemind-watchdog.log</string>\n <key>StandardErrorPath</key>\n <string>/tmp/hivemind-watchdog-error.log</string>\n <key>ThrottleInterval</key>\n <integer>5</integer>\n</dict>\n</plist>`;\n}\n\nfunction generatePlist(hivemindHome: string, hivemindBin: string): string {\n const pidFile = `/tmp/hivemind-agent.pid`;\n \n // Create a wrapper script that writes PID\n const wrapperScript = resolve(hivemindHome, \"bin\", \"agent-wrapper.sh\");\n const wrapperContent = `#!/bin/bash\necho $$ > ${pidFile}\nexec \"${hivemindBin}\" start \"$@\"\n`;\n writeFileSync(wrapperScript, wrapperContent);\n execSync(`chmod +x \"${wrapperScript}\"`);\n \n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${AGENT_LABEL}</string>\n <key>ProgramArguments</key>\n <array>\n <string>${wrapperScript}</string>\n </array>\n <key>WorkingDirectory</key>\n <string>${hivemindHome}</string>\n <key>EnvironmentVariables</key>\n <dict>\n <key>PATH</key>\n <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>\n <key>HIVEMIND_HOME</key>\n <string>${hivemindHome}</string>\n </dict>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <false/>\n <key>StandardOutPath</key>\n <string>/tmp/hivemind-agent.log</string>\n <key>StandardErrorPath</key>\n <string>/tmp/hivemind-error.log</string>\n <key>ThrottleInterval</key>\n <integer>5</integer>\n</dict>\n</plist>`;\n}\n\nexport async function runServiceCommand(args: string[]): Promise<void> {\n const subcommand = args[0];\n\n switch (subcommand) {\n case \"install\":\n await installService();\n break;\n case \"uninstall\":\n await uninstallService();\n break;\n case \"stop\":\n stopService();\n break;\n case \"start\":\n startService();\n break;\n case \"status\":\n showStatus();\n break;\n case \"logs\":\n showLogs(args[1]);\n break;\n default:\n printHelp();\n if (subcommand) {\n console.error(`Unknown subcommand: ${subcommand}`);\n process.exit(1);\n }\n break;\n }\n}\n\nasync function installService(): Promise<void> {\n const hivemindHome = getHivemindHome();\n const hivemindBin = getHivemindBin();\n const memoryBin = resolve(hivemindHome, \"bin\", \"hivemind-memory\");\n\n console.log(`\\n→ Installing launchd services for ${hivemindHome}\\n`);\n console.log(` Agent binary: ${hivemindBin}`);\n console.log(` Memory binary: ${memoryBin}`);\n\n mkdirSync(LAUNCH_AGENTS_DIR, { recursive: true });\n\n // --- Memory daemon service ---\n if (existsSync(memoryBin)) {\n const memoryPlist = generateMemoryPlist(hivemindHome);\n const memoryDest = resolve(LAUNCH_AGENTS_DIR, `${MEMORY_LABEL}.plist`);\n try { execSync(`launchctl unload ${memoryDest} 2>/dev/null`); } catch {}\n writeFileSync(memoryDest, memoryPlist);\n execSync(`launchctl load ${memoryDest}`);\n console.log(` ✓ ${MEMORY_LABEL} installed and started`);\n } else {\n console.log(` ! Memory daemon not found at ${memoryBin} — skipping`);\n console.log(` ! Run 'hivemind init' to download it`);\n }\n\n // --- Ollama service (ensure running) ---\n try {\n execSync(\"curl -sf http://localhost:11434/api/tags > /dev/null\", { stdio: \"ignore\" });\n console.log(\" ✓ Ollama already running\");\n } catch {\n try {\n execSync(\"brew services start ollama 2>/dev/null\", { stdio: \"ignore\" });\n console.log(\" ✓ Ollama started via brew services\");\n } catch {\n console.log(\" ! Ollama not running — start manually: ollama serve\");\n }\n }\n\n // --- Watchdog service ---\n const watchdogPlist = generateWatchdogPlist(hivemindHome, hivemindBin);\n const watchdogDest = resolve(LAUNCH_AGENTS_DIR, `${WATCHDOG_LABEL}.plist`);\n try { execSync(`launchctl unload ${watchdogDest} 2>/dev/null`); } catch {}\n writeFileSync(watchdogDest, watchdogPlist);\n execSync(`launchctl load ${watchdogDest}`);\n console.log(` ✓ ${WATCHDOG_LABEL} installed and started`);\n\n // --- Agent service (KeepAlive: false — watchdog manages restarts) ---\n const plistContent = generatePlist(hivemindHome, hivemindBin);\n const destPath = resolve(LAUNCH_AGENTS_DIR, `${AGENT_LABEL}.plist`);\n try { execSync(`launchctl unload ${destPath} 2>/dev/null`); } catch {}\n writeFileSync(destPath, plistContent);\n execSync(`launchctl load ${destPath}`);\n console.log(` ✓ ${AGENT_LABEL} installed and started`);\n\n console.log(\"\\n Services will auto-start on boot.\");\n console.log(\" Logs:\");\n console.log(\" Agent: /tmp/hivemind-agent.log\");\n console.log(\" Watchdog: /tmp/hivemind-watchdog.log\");\n console.log(\" Memory: /tmp/hivemind-memory.log\\n\");\n}\n\nasync function uninstallService(): Promise<void> {\n console.log(\"\\n→ Uninstalling launchd services\\n\");\n\n for (const label of [AGENT_LABEL, WATCHDOG_LABEL, MEMORY_LABEL]) {\n const plistPath = resolve(LAUNCH_AGENTS_DIR, `${label}.plist`);\n if (existsSync(plistPath)) {\n try { execSync(`launchctl unload ${plistPath} 2>/dev/null`); } catch {}\n unlinkSync(plistPath);\n console.log(` ✓ ${label} uninstalled`);\n } else {\n console.log(` - ${label} not installed`);\n }\n }\n\n // Clean up stop flag if present\n try { unlinkSync(STOP_FLAG_FILE); } catch {}\n console.log(\"\");\n}\n\nfunction stopService(): void {\n console.log(\"\\n→ Stopping agent\\n\");\n\n // Write stop flag so watchdog doesn't restart\n writeFileSync(STOP_FLAG_FILE, String(Date.now()));\n console.log(` ✓ Stop flag written (${STOP_FLAG_FILE})`);\n\n // Stop agent via launchctl\n try {\n const uid = execSync(\"id -u\", { encoding: \"utf-8\" }).trim();\n execSync(`launchctl kill SIGTERM gui/${uid}/${AGENT_LABEL} 2>/dev/null`);\n console.log(` ✓ ${AGENT_LABEL} stopped`);\n } catch {\n console.log(` - ${AGENT_LABEL} was not running`);\n }\n\n console.log(\" Watchdog will NOT restart the agent while stop flag exists.\");\n console.log(\" Use 'hivemind service start' to resume.\\n\");\n}\n\nfunction startService(): void {\n console.log(\"\\n→ Starting agent\\n\");\n\n // Remove stop flag\n try {\n unlinkSync(STOP_FLAG_FILE);\n console.log(` ✓ Stop flag removed (${STOP_FLAG_FILE})`);\n } catch {\n console.log(\" - No stop flag present\");\n }\n\n // Start agent via launchctl\n try {\n const uid = execSync(\"id -u\", { encoding: \"utf-8\" }).trim();\n execSync(`launchctl kickstart gui/${uid}/${AGENT_LABEL}`);\n console.log(` ✓ ${AGENT_LABEL} started`);\n } catch (err) {\n console.error(` ! Failed to start agent: ${(err as Error).message}`);\n }\n console.log(\"\");\n}\n\nfunction showStatus(): void {\n console.log(\"\\n→ Service status\\n\");\n \n const pidFiles: Record<string, string> = {\n [AGENT_LABEL]: \"/tmp/hivemind-agent.pid\",\n [WATCHDOG_LABEL]: \"/tmp/hivemind-watchdog.pid\",\n [MEMORY_LABEL]: \"/tmp/hivemind-memory.pid\"\n };\n \n for (const label of [AGENT_LABEL, WATCHDOG_LABEL, MEMORY_LABEL]) {\n try {\n // First check if service is loaded in launchctl\n execSync(`launchctl list ${label} 2>/dev/null`, { encoding: \"utf-8\" });\n \n // Then try to get PID from file\n let pid = \"unknown\";\n const pidFile = pidFiles[label];\n if (existsSync(pidFile)) {\n const filePid = readFileSync(pidFile, \"utf-8\").trim();\n // Verify the process is actually running\n try {\n execSync(`ps -p ${filePid} > /dev/null 2>&1`);\n pid = filePid;\n } catch {\n // PID file exists but process is dead\n pid = \"stale\";\n }\n }\n \n if (pid === \"stale\") {\n console.log(` ! ${label}: loaded but not running (stale PID file)`);\n } else {\n console.log(` ✓ ${label}: running (PID ${pid})`);\n }\n } catch {\n console.log(` - ${label}: not running`);\n }\n }\n\n // Check Ollama\n try {\n execSync(\"curl -sf http://localhost:11434/api/tags > /dev/null\", { stdio: \"ignore\" });\n console.log(\" ✓ ollama: running\");\n } catch {\n console.log(\" - ollama: not running\");\n }\n console.log(\"\");\n}\n\nfunction showLogs(which?: string): void {\n const logMap: Record<string, string> = {\n agent: \"/tmp/hivemind-agent.log\",\n error: \"/tmp/hivemind-error.log\",\n watchdog: \"/tmp/hivemind-watchdog.log\",\n memory: \"/tmp/hivemind-memory.log\",\n };\n const logFile = logMap[which || \"agent\"] || logMap.agent;\n try {\n execSync(`tail -30 ${logFile}`, { stdio: \"inherit\" });\n } catch {\n console.error(`No log file at ${logFile}`);\n }\n}\n\nfunction printHelp(): void {\n console.log(`hivemind service — Manage launchd services\n\nUsage: hivemind service <subcommand>\n\nSubcommands:\n install Install and start all launchd services (survives reboots)\n uninstall Stop and remove all launchd services\n stop Stop agent (watchdog will not restart it)\n start Start agent (removes stop flag)\n status Show service status\n logs [agent|watchdog|memory|error] Show recent logs\n\nServices:\n com.hivemind.watchdog — Watchdog daemon (health monitoring, restart/upgrade orchestration)\n com.hivemind.agent — Agent runtime (Node.js, Sesame) — managed by watchdog\n com.hivemind.memory — Memory daemon (LanceDB + Ollama embeddings)\n`);\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../packages/cli/src/commands/service.ts"],"sourcesContent":["import { resolve } from \"path\";\nimport { writeFileSync, existsSync, unlinkSync, mkdirSync, readFileSync } from \"fs\";\nimport { execSync } from \"child_process\";\nimport { homedir } from \"os\";\n\nconst LAUNCH_AGENTS_DIR = resolve(homedir(), \"Library/LaunchAgents\");\nconst AGENT_LABEL = \"com.hivemind.agent\";\nconst WATCHDOG_LABEL = \"com.hivemind.watchdog\";\nconst MEMORY_LABEL = \"com.hivemind.memory\";\nconst STOP_FLAG_FILE = \"/tmp/hivemind-agent.stopped\";\n\nfunction getHivemindHome(): string {\n return process.env.HIVEMIND_HOME || resolve(homedir(), \"hivemind\");\n}\n\nfunction getHivemindBin(): string {\n // Try to find the hivemind binary\n try {\n const which = execSync(\"which hivemind\", { encoding: \"utf-8\" }).trim();\n if (which) return which;\n } catch {}\n // Fallback to process.argv[1] (the script being run)\n return process.argv[1] || \"hivemind\";\n}\n\nfunction generateMemoryPlist(hivemindHome: string): string {\n const memoryBin = resolve(hivemindHome, \"bin\", \"hivemind-memory\");\n const dbPath = resolve(hivemindHome, \"data\", \"lancedb\");\n const pidFile = `/tmp/hivemind-memory.pid`;\n \n // Create a wrapper script that writes PID\n const wrapperScript = resolve(hivemindHome, \"bin\", \"memory-wrapper.sh\");\n const wrapperContent = `#!/bin/bash\necho $$ > ${pidFile}\nexec \"${memoryBin}\" \"$@\"\n`;\n writeFileSync(wrapperScript, wrapperContent);\n execSync(`chmod +x \"${wrapperScript}\"`);\n \n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${MEMORY_LABEL}</string>\n <key>ProgramArguments</key>\n <array>\n <string>${wrapperScript}</string>\n </array>\n <key>WorkingDirectory</key>\n <string>${hivemindHome}</string>\n <key>EnvironmentVariables</key>\n <dict>\n <key>PORT</key>\n <string>3434</string>\n <key>DB_PATH</key>\n <string>${dbPath}</string>\n <key>OLLAMA_URL</key>\n <string>http://localhost:11434</string>\n <key>EMBEDDING_MODEL</key>\n <string>nomic-embed-text</string>\n </dict>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <true/>\n <key>StandardOutPath</key>\n <string>/tmp/hivemind-memory.log</string>\n <key>StandardErrorPath</key>\n <string>/tmp/hivemind-memory-error.log</string>\n <key>ThrottleInterval</key>\n <integer>5</integer>\n</dict>\n</plist>`;\n}\n\nfunction generateWatchdogPlist(hivemindHome: string, hivemindBin: string): string {\n const pidFile = `/tmp/hivemind-watchdog.pid`;\n \n // Create a wrapper script that writes PID\n const wrapperScript = resolve(hivemindHome, \"bin\", \"watchdog-wrapper.sh\");\n const wrapperContent = `#!/bin/bash\necho $$ > ${pidFile}\nexec \"${hivemindBin}\" watchdog \"$@\"\n`;\n writeFileSync(wrapperScript, wrapperContent);\n execSync(`chmod +x \"${wrapperScript}\"`);\n \n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${WATCHDOG_LABEL}</string>\n <key>ProgramArguments</key>\n <array>\n <string>${wrapperScript}</string>\n </array>\n <key>WorkingDirectory</key>\n <string>${hivemindHome}</string>\n <key>EnvironmentVariables</key>\n <dict>\n <key>PATH</key>\n <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>\n <key>HIVEMIND_HOME</key>\n <string>${hivemindHome}</string>\n </dict>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <true/>\n <key>StandardOutPath</key>\n <string>/tmp/hivemind-watchdog.log</string>\n <key>StandardErrorPath</key>\n <string>/tmp/hivemind-watchdog-error.log</string>\n <key>ThrottleInterval</key>\n <integer>5</integer>\n</dict>\n</plist>`;\n}\n\nfunction generatePlist(hivemindHome: string, hivemindBin: string): string {\n const pidFile = `/tmp/hivemind-agent.pid`;\n \n // Create a wrapper script that writes PID\n const wrapperScript = resolve(hivemindHome, \"bin\", \"agent-wrapper.sh\");\n const wrapperContent = `#!/bin/bash\necho $$ > ${pidFile}\nexec \"${hivemindBin}\" start \"$@\"\n`;\n writeFileSync(wrapperScript, wrapperContent);\n execSync(`chmod +x \"${wrapperScript}\"`);\n \n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${AGENT_LABEL}</string>\n <key>ProgramArguments</key>\n <array>\n <string>${wrapperScript}</string>\n </array>\n <key>WorkingDirectory</key>\n <string>${hivemindHome}</string>\n <key>EnvironmentVariables</key>\n <dict>\n <key>PATH</key>\n <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>\n <key>HIVEMIND_HOME</key>\n <string>${hivemindHome}</string>\n </dict>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <false/>\n <key>StandardOutPath</key>\n <string>/tmp/hivemind-agent.log</string>\n <key>StandardErrorPath</key>\n <string>/tmp/hivemind-error.log</string>\n <key>ThrottleInterval</key>\n <integer>5</integer>\n</dict>\n</plist>`;\n}\n\nexport async function runServiceCommand(args: string[]): Promise<void> {\n const subcommand = args[0];\n\n switch (subcommand) {\n case \"install\":\n await installService();\n break;\n case \"uninstall\":\n await uninstallService();\n break;\n case \"stop\":\n stopService();\n break;\n case \"start\":\n startService();\n break;\n case \"status\":\n showStatus();\n break;\n case \"logs\":\n showLogs(args[1]);\n break;\n default:\n printHelp();\n if (subcommand) {\n console.error(`Unknown subcommand: ${subcommand}`);\n process.exit(1);\n }\n break;\n }\n}\n\nasync function installService(): Promise<void> {\n const hivemindHome = getHivemindHome();\n const hivemindBin = getHivemindBin();\n const memoryBin = resolve(hivemindHome, \"bin\", \"hivemind-memory\");\n\n console.log(`\\n→ Installing launchd services for ${hivemindHome}\\n`);\n console.log(` Agent binary: ${hivemindBin}`);\n console.log(` Memory binary: ${memoryBin}`);\n\n mkdirSync(LAUNCH_AGENTS_DIR, { recursive: true });\n\n // --- Memory daemon service ---\n if (existsSync(memoryBin)) {\n const memoryPlist = generateMemoryPlist(hivemindHome);\n const memoryDest = resolve(LAUNCH_AGENTS_DIR, `${MEMORY_LABEL}.plist`);\n try { execSync(`launchctl unload ${memoryDest} 2>/dev/null`); } catch {}\n writeFileSync(memoryDest, memoryPlist);\n execSync(`launchctl load ${memoryDest}`);\n console.log(` ✓ ${MEMORY_LABEL} installed and started`);\n } else {\n console.log(` ! Memory daemon not found at ${memoryBin} — skipping`);\n console.log(` ! Run 'hivemind init' to download it`);\n }\n\n // --- Ollama service (ensure running) ---\n try {\n execSync(\"curl -sf http://localhost:11434/api/tags > /dev/null\", { stdio: \"ignore\" });\n console.log(\" ✓ Ollama already running\");\n } catch {\n try {\n execSync(\"brew services start ollama 2>/dev/null\", { stdio: \"ignore\" });\n console.log(\" ✓ Ollama started via brew services\");\n } catch {\n console.log(\" ! Ollama not running — start manually: ollama serve\");\n }\n }\n\n // --- Watchdog service ---\n const watchdogPlist = generateWatchdogPlist(hivemindHome, hivemindBin);\n const watchdogDest = resolve(LAUNCH_AGENTS_DIR, `${WATCHDOG_LABEL}.plist`);\n try { execSync(`launchctl unload ${watchdogDest} 2>/dev/null`); } catch {}\n writeFileSync(watchdogDest, watchdogPlist);\n execSync(`launchctl load ${watchdogDest}`);\n console.log(` ✓ ${WATCHDOG_LABEL} installed and started`);\n\n // --- Agent service (KeepAlive: false — watchdog manages restarts) ---\n const plistContent = generatePlist(hivemindHome, hivemindBin);\n const destPath = resolve(LAUNCH_AGENTS_DIR, `${AGENT_LABEL}.plist`);\n try { execSync(`launchctl unload ${destPath} 2>/dev/null`); } catch {}\n writeFileSync(destPath, plistContent);\n execSync(`launchctl load ${destPath}`);\n console.log(` ✓ ${AGENT_LABEL} installed and started`);\n\n console.log(\"\\n Services will auto-start on boot.\");\n console.log(\" Logs:\");\n console.log(\" Agent: /tmp/hivemind-agent.log\");\n console.log(\" Watchdog: /tmp/hivemind-watchdog.log\");\n console.log(\" Memory: /tmp/hivemind-memory.log\\n\");\n}\n\nasync function uninstallService(): Promise<void> {\n console.log(\"\\n→ Uninstalling launchd services\\n\");\n\n for (const label of [AGENT_LABEL, WATCHDOG_LABEL, MEMORY_LABEL]) {\n const plistPath = resolve(LAUNCH_AGENTS_DIR, `${label}.plist`);\n if (existsSync(plistPath)) {\n try { execSync(`launchctl unload ${plistPath} 2>/dev/null`); } catch {}\n unlinkSync(plistPath);\n console.log(` ✓ ${label} uninstalled`);\n } else {\n console.log(` - ${label} not installed`);\n }\n }\n\n // Clean up stop flag if present\n try { unlinkSync(STOP_FLAG_FILE); } catch {}\n console.log(\"\");\n}\n\nfunction stopService(): void {\n console.log(\"\\n→ Stopping agent\\n\");\n\n // Write stop flag so watchdog doesn't restart\n writeFileSync(STOP_FLAG_FILE, String(Date.now()));\n console.log(` ✓ Stop flag written (${STOP_FLAG_FILE})`);\n\n // Stop agent via launchctl\n try {\n const uid = execSync(\"id -u\", { encoding: \"utf-8\" }).trim();\n execSync(`launchctl kill SIGTERM gui/${uid}/${AGENT_LABEL} 2>/dev/null`);\n console.log(` ✓ ${AGENT_LABEL} stopped`);\n } catch {\n console.log(` - ${AGENT_LABEL} was not running`);\n }\n\n console.log(\" Watchdog will NOT restart the agent while stop flag exists.\");\n console.log(\" Use 'hivemind service start' to resume.\\n\");\n}\n\nfunction startService(): void {\n console.log(\"\\n→ Starting agent\\n\");\n\n // Remove stop flag\n try {\n unlinkSync(STOP_FLAG_FILE);\n console.log(` ✓ Stop flag removed (${STOP_FLAG_FILE})`);\n } catch {\n console.log(\" - No stop flag present\");\n }\n\n // Start agent via launchctl\n try {\n const uid = execSync(\"id -u\", { encoding: \"utf-8\" }).trim();\n execSync(`launchctl kickstart gui/${uid}/${AGENT_LABEL}`);\n console.log(` ✓ ${AGENT_LABEL} started`);\n } catch (err) {\n console.error(` ! Failed to start agent: ${(err as Error).message}`);\n }\n console.log(\"\");\n}\n\nfunction showStatus(): void {\n console.log(\"\\n→ Service status\\n\");\n\n const keepAliveServices = new Set([MEMORY_LABEL, WATCHDOG_LABEL]);\n const pidFiles: Record<string, string> = {\n [AGENT_LABEL]: \"/tmp/hivemind-agent.pid\",\n [WATCHDOG_LABEL]: \"/tmp/hivemind-watchdog.pid\",\n [MEMORY_LABEL]: \"/tmp/hivemind-memory.pid\"\n };\n\n for (const label of [AGENT_LABEL, WATCHDOG_LABEL, MEMORY_LABEL]) {\n try {\n // Check if service is loaded and get PID from launchctl\n const listOutput = execSync(`launchctl list ${label} 2>/dev/null`, { encoding: \"utf-8\" });\n const pidMatch = listOutput.match(/\"PID\"\\s*=\\s*(\\d+)/);\n\n if (pidMatch) {\n console.log(` ✓ ${label}: running (PID ${pidMatch[1]})`);\n } else {\n // Loaded but no PID — process crashed or hasn't started\n // Clean up stale PID file if present\n const pidFile = pidFiles[label];\n if (pidFile && existsSync(pidFile)) {\n try { unlinkSync(pidFile); } catch {}\n }\n\n // Attempt kickstart for KeepAlive services (not agent — watchdog manages it)\n if (keepAliveServices.has(label)) {\n try {\n const uid = execSync(\"id -u\", { encoding: \"utf-8\" }).trim();\n execSync(`launchctl kickstart gui/${uid}/${label} 2>/dev/null`);\n console.log(` ! ${label}: was not running, kickstarted`);\n } catch {\n console.log(` ! ${label}: loaded but not running`);\n }\n } else {\n console.log(` ! ${label}: loaded but not running`);\n }\n }\n } catch {\n console.log(` - ${label}: not loaded`);\n }\n }\n\n // Check Ollama\n try {\n execSync(\"curl -sf http://localhost:11434/api/tags > /dev/null\", { stdio: \"ignore\" });\n console.log(\" ✓ ollama: running\");\n } catch {\n console.log(\" - ollama: not running\");\n }\n console.log(\"\");\n}\n\nfunction showLogs(which?: string): void {\n const logMap: Record<string, string> = {\n agent: \"/tmp/hivemind-agent.log\",\n error: \"/tmp/hivemind-error.log\",\n watchdog: \"/tmp/hivemind-watchdog.log\",\n memory: \"/tmp/hivemind-memory.log\",\n };\n const logFile = logMap[which || \"agent\"] || logMap.agent;\n try {\n execSync(`tail -30 ${logFile}`, { stdio: \"inherit\" });\n } catch {\n console.error(`No log file at ${logFile}`);\n }\n}\n\nfunction printHelp(): void {\n console.log(`hivemind service — Manage launchd services\n\nUsage: hivemind service <subcommand>\n\nSubcommands:\n install Install and start all launchd services (survives reboots)\n uninstall Stop and remove all launchd services\n stop Stop agent (watchdog will not restart it)\n start Start agent (removes stop flag)\n status Show service status\n logs [agent|watchdog|memory|error] Show recent logs\n\nServices:\n com.hivemind.watchdog — Watchdog daemon (health monitoring, restart/upgrade orchestration)\n com.hivemind.agent — Agent runtime (Node.js, Sesame) — managed by watchdog\n com.hivemind.memory — Memory daemon (LanceDB + Ollama embeddings)\n`);\n}\n"],"mappings":"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","names":[]}
|
package/dist/commands/service.js
CHANGED
package/dist/main.js
CHANGED