@sesamespace/hivemind 0.4.3 → 0.5.1

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.
@@ -3,10 +3,12 @@ import {
3
3
  } from "./chunk-GPI4RU7N.js";
4
4
 
5
5
  // packages/cli/src/commands/init.ts
6
- import { resolve } from "path";
7
- import { existsSync, writeFileSync, mkdirSync } from "fs";
6
+ import { resolve, dirname } from "path";
7
+ import { existsSync, writeFileSync, mkdirSync, copyFileSync } from "fs";
8
8
  import { createInterface } from "readline";
9
- var HIVEMIND_DIR = resolve(process.env.HIVEMIND_HOME || ".");
9
+ import { fileURLToPath } from "url";
10
+ import { homedir } from "os";
11
+ var HIVEMIND_DIR = resolve(process.env.HIVEMIND_HOME || resolve(homedir(), "hivemind"));
10
12
  var CONFIG_DIR = resolve(HIVEMIND_DIR, "config");
11
13
  var WORKSPACE_DIR = resolve(HIVEMIND_DIR, "workspace");
12
14
  var ENV_FILE = resolve(HIVEMIND_DIR, ".env");
@@ -111,6 +113,23 @@ async function runInitCommand(args) {
111
113
  console.log("\n\u2192 Writing configuration...");
112
114
  mkdirSync(CONFIG_DIR, { recursive: true });
113
115
  mkdirSync(WORKSPACE_DIR, { recursive: true });
116
+ const defaultToml = resolve(CONFIG_DIR, "default.toml");
117
+ if (!existsSync(defaultToml)) {
118
+ const packageConfigDir = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "config");
119
+ const packageDefault = resolve(packageConfigDir, "default.toml");
120
+ if (existsSync(packageDefault)) {
121
+ copyFileSync(packageDefault, defaultToml);
122
+ console.log(` \u2713 ${defaultToml}`);
123
+ const packageCharter = resolve(packageConfigDir, "TEAM-CHARTER.md");
124
+ const localCharter = resolve(CONFIG_DIR, "TEAM-CHARTER.md");
125
+ if (existsSync(packageCharter) && !existsSync(localCharter)) {
126
+ copyFileSync(packageCharter, localCharter);
127
+ console.log(` \u2713 ${localCharter}`);
128
+ }
129
+ } else {
130
+ console.log(` ! default.toml not found in package \u2014 you may need to copy it manually`);
131
+ }
132
+ }
114
133
  const soulPath = resolve(WORKSPACE_DIR, "SOUL.md");
115
134
  if (!existsSync(soulPath)) {
116
135
  const personality = config.personality || "A helpful, capable agent.";
@@ -145,6 +164,9 @@ workspace = "workspace"
145
164
  ${config.llmModel ? `[llm]
146
165
  model = "${config.llmModel}"` : "# [llm] using defaults"}
147
166
  ${config.llmBaseUrl ? `# base_url = "${config.llmBaseUrl}"` : ""}
167
+
168
+ [sesame]
169
+ api_key = "${sesameApiKey}"
148
170
  `;
149
171
  writeFileSync(LOCAL_TOML, localToml);
150
172
  console.log(` \u2713 ${LOCAL_TOML}`);
@@ -160,10 +182,10 @@ AGENT_NAME=${config.agentName}
160
182
  \u2713 Hivemind initialized for ${config.agentName}!
161
183
 
162
184
  To start the agent:
163
- ./start.sh
185
+ hivemind start
164
186
 
165
- To start in background:
166
- nohup ./start.sh > /tmp/hivemind.log 2>&1 &
187
+ To install as a service:
188
+ hivemind service install
167
189
 
168
190
  Agent ID: ${config.agentId}
169
191
  Channels: ${config.channels.map((c) => c.name || c.id).join(", ")}
@@ -191,4 +213,4 @@ Options:
191
213
  export {
192
214
  runInitCommand
193
215
  };
194
- //# sourceMappingURL=chunk-2OIRJFI5.js.map
216
+ //# sourceMappingURL=chunk-56Z4WDJC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../packages/cli/src/commands/init.ts"],"sourcesContent":["import { resolve, dirname } from \"path\";\nimport { existsSync, writeFileSync, mkdirSync, readFileSync, copyFileSync } from \"fs\";\nimport { createInterface } from \"readline\";\nimport { fileURLToPath } from \"url\";\nimport { SesameClient } from \"@sesamespace/sdk\";\nimport { homedir } from \"os\";\n\nconst HIVEMIND_DIR = resolve(process.env.HIVEMIND_HOME || resolve(homedir(), \"hivemind\"));\nconst CONFIG_DIR = resolve(HIVEMIND_DIR, \"config\");\nconst WORKSPACE_DIR = resolve(HIVEMIND_DIR, \"workspace\");\nconst ENV_FILE = resolve(HIVEMIND_DIR, \".env\");\nconst LOCAL_TOML = resolve(CONFIG_DIR, \"local.toml\");\n\nconst VAULT_CONFIG_NAME = \"hivemind-config\";\n\ninterface ProvisioningConfig {\n agentName: string;\n agentHandle: string;\n agentId: string;\n personality?: string;\n llmApiKey?: string;\n llmBaseUrl?: string;\n llmModel?: string;\n fleetRole?: string;\n channels: Array<{ id: string; name: string | null; kind: string }>;\n}\n\nasync function prompt(question: string): Promise<string> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\nexport async function runInitCommand(args: string[]): Promise<void> {\n const nonInteractive = args.includes(\"--yes\") || args.includes(\"-y\") || args.includes(\"--non-interactive\");\n const filteredArgs = args.filter((a) => ![\"--yes\", \"-y\", \"--non-interactive\", \"--help\", \"-h\"].includes(a));\n let sesameApiKey = filteredArgs[0];\n\n if (args.includes(\"--help\") || args.includes(\"-h\")) {\n printHelp();\n return;\n }\n\n console.log(`\n ╦ ╦╦╦ ╦╔═╗╔╦╗╦╔╗╔╔╦╗\n ╠═╣║╚╗╔╝║╣ ║║║║║║║ ║║\n ╩ ╩╩ ╚╝ ╚═╝╩ ╩╩╝╚╝═╩╝\n Agent Initialization\n`);\n\n // --- Step 1: Get Sesame API key ---\n if (!sesameApiKey) {\n sesameApiKey = await prompt(\" Sesame API key: \");\n }\n if (!sesameApiKey) {\n console.error(\"Error: Sesame API key is required\");\n process.exit(1);\n }\n\n // --- Step 2: Connect to Sesame and fetch manifest ---\n console.log(\"\\n→ Connecting to Sesame...\");\n const sdk = new SesameClient({\n apiUrl: \"https://api.sesame.space\",\n wsUrl: \"wss://ws.sesame.space\",\n apiKey: sesameApiKey,\n });\n\n let config: ProvisioningConfig;\n try {\n const manifest = await sdk.getManifest();\n console.log(` ✓ Authenticated as ${manifest.agent.handle} (${manifest.agent.id})`);\n console.log(` ✓ Workspace: ${manifest.workspace.name}`);\n console.log(` ✓ Channels: ${manifest.channels.length}`);\n for (const ch of manifest.channels) {\n console.log(` - ${ch.name || ch.id} (${ch.kind})`);\n }\n\n config = {\n agentName: manifest.agent.handle,\n agentHandle: manifest.agent.handle,\n agentId: manifest.agent.id,\n channels: manifest.channels.map((ch) => ({\n id: ch.id,\n name: ch.name,\n kind: ch.kind,\n })),\n };\n\n // --- Step 3: Check vault for config ---\n console.log(\"\\n→ Checking vault for provisioning config...\");\n try {\n const vaultResp = await sdk.listVaultItems() as any;\n const items = vaultResp.items || vaultResp.data || [];\n const configItem = items.find((i: any) => i.name === VAULT_CONFIG_NAME);\n\n if (configItem) {\n console.log(` ✓ Found ${VAULT_CONFIG_NAME} vault item`);\n const revealResp = await sdk.revealItem(configItem.id) as any;\n const fields = revealResp.fields || revealResp.data || {};\n\n config.llmApiKey = fields.llm_api_key || fields.openrouter_api_key;\n config.llmBaseUrl = fields.llm_base_url;\n config.llmModel = fields.llm_model;\n config.personality = fields.agent_personality || fields.personality;\n config.fleetRole = fields.fleet_role;\n\n if (config.llmApiKey) console.log(\" ✓ LLM API key loaded from vault\");\n if (config.personality) console.log(` ✓ Personality: ${config.personality.slice(0, 60)}...`);\n if (config.fleetRole) console.log(` ✓ Fleet role: ${config.fleetRole}`);\n } else {\n console.log(\" ! No hivemind-config vault item found\");\n console.log(\" ! Will prompt for LLM API key instead\");\n }\n } catch (err) {\n console.log(` ! Could not read vault: ${(err as Error).message}`);\n }\n } catch (err) {\n console.error(`\\n ✗ Failed to connect to Sesame: ${(err as Error).message}`);\n console.error(\" Check your API key and try again.\");\n process.exit(1);\n } finally {\n sdk.disconnect();\n }\n\n // --- Step 4: Prompt for anything missing (skip in non-interactive mode) ---\n if (!config.llmApiKey && !nonInteractive) {\n config.llmApiKey = await prompt(\"\\n OpenRouter API key: \");\n } else if (!config.llmApiKey) {\n console.log(\" ! No LLM API key found in vault — set LLM_API_KEY in .env after init\");\n }\n\n if (!nonInteractive) {\n const nameOverride = await prompt(` Agent name [${config.agentName}]: `);\n if (nameOverride) config.agentName = nameOverride;\n }\n\n // --- Step 5: Write config files ---\n console.log(\"\\n→ Writing configuration...\");\n\n mkdirSync(CONFIG_DIR, { recursive: true });\n mkdirSync(WORKSPACE_DIR, { recursive: true });\n\n // Copy default.toml from installed package if not present\n const defaultToml = resolve(CONFIG_DIR, \"default.toml\");\n if (!existsSync(defaultToml)) {\n // Resolve from the package install location (../../config/default.toml relative to this file)\n const packageConfigDir = resolve(dirname(fileURLToPath(import.meta.url)), \"..\", \"..\", \"config\");\n const packageDefault = resolve(packageConfigDir, \"default.toml\");\n if (existsSync(packageDefault)) {\n copyFileSync(packageDefault, defaultToml);\n console.log(` ✓ ${defaultToml}`);\n // Also copy team charter if available\n const packageCharter = resolve(packageConfigDir, \"TEAM-CHARTER.md\");\n const localCharter = resolve(CONFIG_DIR, \"TEAM-CHARTER.md\");\n if (existsSync(packageCharter) && !existsSync(localCharter)) {\n copyFileSync(packageCharter, localCharter);\n console.log(` ✓ ${localCharter}`);\n }\n } else {\n console.log(` ! default.toml not found in package — you may need to copy it manually`);\n }\n }\n\n // Write workspace identity files\n const soulPath = resolve(WORKSPACE_DIR, \"SOUL.md\");\n if (!existsSync(soulPath)) {\n const personality = config.personality || \"A helpful, capable agent.\";\n writeFileSync(soulPath, `# SOUL.md — Who You Are\n\n${personality}\n\n---\n\n_This file defines your personality and values. Edit it to evolve who you are._\n`);\n console.log(` ✓ ${soulPath}`);\n }\n\n const identityPath = resolve(WORKSPACE_DIR, \"IDENTITY.md\");\n if (!existsSync(identityPath)) {\n writeFileSync(identityPath, `# IDENTITY.md\n\n- **Name:** ${config.agentName}\n- **Handle:** ${config.agentHandle}\n- **Agent ID:** ${config.agentId}\n`);\n console.log(` ✓ ${identityPath}`);\n }\n\n // Write local.toml (overrides)\n const localToml = `# Generated by hivemind init — ${new Date().toISOString()}\n# Overrides config/default.toml with agent-specific settings\n\n[agent]\nname = \"${config.agentName}\"\n${config.personality ? `personality = \"${config.personality.replace(/\"/g, '\\\\\"')}\"` : \"# personality = (using default)\"}\nworkspace = \"workspace\"\n\n${config.llmModel ? `[llm]\\nmodel = \"${config.llmModel}\"` : \"# [llm] using defaults\"}\n${config.llmBaseUrl ? `# base_url = \"${config.llmBaseUrl}\"` : \"\"}\n\n[sesame]\napi_key = \"${sesameApiKey}\"\n`;\n\n writeFileSync(LOCAL_TOML, localToml);\n console.log(` ✓ ${LOCAL_TOML}`);\n\n // Write .env\n const envContent = `# Hivemind Agent — ${config.agentName}\n# Generated by hivemind init — ${new Date().toISOString()}\nSESAME_API_KEY=${sesameApiKey}\nLLM_API_KEY=${config.llmApiKey || \"\"}\nAGENT_NAME=${config.agentName}\n`;\n\n writeFileSync(ENV_FILE, envContent, { mode: 0o600 });\n console.log(` ✓ ${ENV_FILE} (chmod 600)`);\n\n // --- Done ---\n console.log(`\n ✓ Hivemind initialized for ${config.agentName}!\n\n To start the agent:\n hivemind start\n\n To install as a service:\n hivemind service install\n\n Agent ID: ${config.agentId}\n Channels: ${config.channels.map((c) => c.name || c.id).join(\", \")}\n Fleet role: ${config.fleetRole || \"standalone\"}\n`);\n}\n\nfunction printHelp(): void {\n console.log(`hivemind init — Initialize a Hivemind agent from Sesame\n\nUsage: hivemind init [sesame-api-key]\n\nThe API key can also be passed as the first argument.\n\nWhat it does:\n 1. Connects to Sesame and fetches agent identity\n 2. Reads provisioning config from Sesame vault (if available)\n 3. Prompts for any missing configuration\n 4. Writes config/local.toml and .env\n\nOptions:\n -h, --help Show this help\n`);\n}\n"],"mappings":"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","names":["resolve"]}
@@ -4,9 +4,34 @@ import {
4
4
 
5
5
  // packages/cli/src/commands/start.ts
6
6
  import { resolve } from "path";
7
- import { existsSync } from "fs";
7
+ import { existsSync, readFileSync } from "fs";
8
+ import { homedir } from "os";
8
9
  var DEFAULT_CONFIG = "config/default.toml";
10
+ function loadEnvFile(dir) {
11
+ const envPath = resolve(dir, ".env");
12
+ if (!existsSync(envPath)) return;
13
+ try {
14
+ const content = readFileSync(envPath, "utf-8");
15
+ for (const line of content.split("\n")) {
16
+ const trimmed = line.trim();
17
+ if (!trimmed || trimmed.startsWith("#")) continue;
18
+ const eqIdx = trimmed.indexOf("=");
19
+ if (eqIdx < 1) continue;
20
+ const key = trimmed.slice(0, eqIdx).trim();
21
+ let value = trimmed.slice(eqIdx + 1).trim();
22
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
23
+ value = value.slice(1, -1);
24
+ }
25
+ if (!(key in process.env)) {
26
+ process.env[key] = value;
27
+ }
28
+ }
29
+ } catch {
30
+ }
31
+ }
9
32
  async function runStartCommand(args) {
33
+ const hivemindHome = process.env.HIVEMIND_HOME || resolve(homedir(), "hivemind");
34
+ loadEnvFile(hivemindHome);
10
35
  let configPath = DEFAULT_CONFIG;
11
36
  for (let i = 0; i < args.length; i++) {
12
37
  if ((args[i] === "--config" || args[i] === "-c") && args[i + 1]) {
@@ -41,4 +66,4 @@ Options:
41
66
  export {
42
67
  runStartCommand
43
68
  };
44
- //# sourceMappingURL=chunk-O257FXSX.js.map
69
+ //# sourceMappingURL=chunk-LNV373IF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../packages/cli/src/commands/start.ts"],"sourcesContent":["import { resolve } from \"path\";\nimport { existsSync, readFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { startPipeline } from \"@hivemind/runtime\";\n\nconst DEFAULT_CONFIG = \"config/default.toml\";\n\n/**\n * Load .env file from HIVEMIND_HOME, setting any missing env vars.\n * Simple KEY=VALUE parser — no dotenv dependency needed.\n */\nfunction loadEnvFile(dir: string): void {\n const envPath = resolve(dir, \".env\");\n if (!existsSync(envPath)) return;\n\n try {\n const content = readFileSync(envPath, \"utf-8\");\n for (const line of content.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const eqIdx = trimmed.indexOf(\"=\");\n if (eqIdx < 1) continue;\n const key = trimmed.slice(0, eqIdx).trim();\n let value = trimmed.slice(eqIdx + 1).trim();\n // Strip surrounding quotes\n if ((value.startsWith('\"') && value.endsWith('\"')) || (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n value = value.slice(1, -1);\n }\n // Don't overwrite existing env vars\n if (!(key in process.env)) {\n process.env[key] = value;\n }\n }\n } catch {\n // Silently ignore read errors\n }\n}\n\nexport async function runStartCommand(args: string[]): Promise<void> {\n // Load .env from HIVEMIND_HOME before anything else\n const hivemindHome = process.env.HIVEMIND_HOME || resolve(homedir(), \"hivemind\");\n loadEnvFile(hivemindHome);\n\n let configPath = DEFAULT_CONFIG;\n\n // Parse args\n for (let i = 0; i < args.length; i++) {\n if ((args[i] === \"--config\" || args[i] === \"-c\") && args[i + 1]) {\n configPath = args[++i];\n } else if (args[i] === \"--help\" || args[i] === \"-h\") {\n printHelp();\n return;\n } else {\n console.error(`Unknown argument: ${args[i]}`);\n printHelp();\n process.exit(1);\n }\n }\n\n const resolved = resolve(configPath);\n if (!existsSync(resolved)) {\n console.error(`Config not found: ${resolved}`);\n process.exit(1);\n }\n\n await startPipeline(resolved);\n}\n\nfunction printHelp(): void {\n console.log(`hivemind start — Start the Hivemind agent\n\nUsage: hivemind start [options]\n\nOptions:\n -c, --config <path> Config file (default: config/default.toml)\n -h, --help Show this help\n`);\n}\n"],"mappings":";;;;;AAAA,SAAS,eAAe;AACxB,SAAS,YAAY,oBAAoB;AACzC,SAAS,eAAe;AAGxB,IAAM,iBAAiB;AAMvB,SAAS,YAAY,KAAmB;AACtC,QAAM,UAAU,QAAQ,KAAK,MAAM;AACnC,MAAI,CAAC,WAAW,OAAO,EAAG;AAE1B,MAAI;AACF,UAAM,UAAU,aAAa,SAAS,OAAO;AAC7C,eAAW,QAAQ,QAAQ,MAAM,IAAI,GAAG;AACtC,YAAM,UAAU,KAAK,KAAK;AAC1B,UAAI,CAAC,WAAW,QAAQ,WAAW,GAAG,EAAG;AACzC,YAAM,QAAQ,QAAQ,QAAQ,GAAG;AACjC,UAAI,QAAQ,EAAG;AACf,YAAM,MAAM,QAAQ,MAAM,GAAG,KAAK,EAAE,KAAK;AACzC,UAAI,QAAQ,QAAQ,MAAM,QAAQ,CAAC,EAAE,KAAK;AAE1C,UAAK,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,KAAO,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,GAAI;AACpG,gBAAQ,MAAM,MAAM,GAAG,EAAE;AAAA,MAC3B;AAEA,UAAI,EAAE,OAAO,QAAQ,MAAM;AACzB,gBAAQ,IAAI,GAAG,IAAI;AAAA,MACrB;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AACF;AAEA,eAAsB,gBAAgB,MAA+B;AAEnE,QAAM,eAAe,QAAQ,IAAI,iBAAiB,QAAQ,QAAQ,GAAG,UAAU;AAC/E,cAAY,YAAY;AAExB,MAAI,aAAa;AAGjB,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,SAAK,KAAK,CAAC,MAAM,cAAc,KAAK,CAAC,MAAM,SAAS,KAAK,IAAI,CAAC,GAAG;AAC/D,mBAAa,KAAK,EAAE,CAAC;AAAA,IACvB,WAAW,KAAK,CAAC,MAAM,YAAY,KAAK,CAAC,MAAM,MAAM;AACnD,gBAAU;AACV;AAAA,IACF,OAAO;AACL,cAAQ,MAAM,qBAAqB,KAAK,CAAC,CAAC,EAAE;AAC5C,gBAAU;AACV,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AAEA,QAAM,WAAW,QAAQ,UAAU;AACnC,MAAI,CAAC,WAAW,QAAQ,GAAG;AACzB,YAAQ,MAAM,qBAAqB,QAAQ,EAAE;AAC7C,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,cAAc,QAAQ;AAC9B;AAEA,SAAS,YAAkB;AACzB,UAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAOb;AACD;","names":[]}
@@ -0,0 +1,151 @@
1
+ // packages/cli/src/commands/service.ts
2
+ import { resolve } from "path";
3
+ import { writeFileSync, existsSync, unlinkSync, mkdirSync } from "fs";
4
+ import { execSync } from "child_process";
5
+ import { homedir } from "os";
6
+ var LAUNCH_AGENTS_DIR = resolve(homedir(), "Library/LaunchAgents");
7
+ var AGENT_LABEL = "com.hivemind.agent";
8
+ function getHivemindHome() {
9
+ return process.env.HIVEMIND_HOME || resolve(homedir(), "hivemind");
10
+ }
11
+ function getHivemindBin() {
12
+ try {
13
+ const which = execSync("which hivemind", { encoding: "utf-8" }).trim();
14
+ if (which) return which;
15
+ } catch {
16
+ }
17
+ return process.argv[1] || "hivemind";
18
+ }
19
+ function generatePlist(hivemindHome, hivemindBin) {
20
+ return `<?xml version="1.0" encoding="UTF-8"?>
21
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
22
+ <plist version="1.0">
23
+ <dict>
24
+ <key>Label</key>
25
+ <string>${AGENT_LABEL}</string>
26
+ <key>ProgramArguments</key>
27
+ <array>
28
+ <string>${hivemindBin}</string>
29
+ <string>start</string>
30
+ </array>
31
+ <key>WorkingDirectory</key>
32
+ <string>${hivemindHome}</string>
33
+ <key>EnvironmentVariables</key>
34
+ <dict>
35
+ <key>PATH</key>
36
+ <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>
37
+ <key>HIVEMIND_HOME</key>
38
+ <string>${hivemindHome}</string>
39
+ </dict>
40
+ <key>RunAtLoad</key>
41
+ <true/>
42
+ <key>KeepAlive</key>
43
+ <true/>
44
+ <key>StandardOutPath</key>
45
+ <string>/tmp/hivemind-agent.log</string>
46
+ <key>StandardErrorPath</key>
47
+ <string>/tmp/hivemind-error.log</string>
48
+ <key>ThrottleInterval</key>
49
+ <integer>5</integer>
50
+ </dict>
51
+ </plist>`;
52
+ }
53
+ async function runServiceCommand(args) {
54
+ const subcommand = args[0];
55
+ switch (subcommand) {
56
+ case "install":
57
+ await installService();
58
+ break;
59
+ case "uninstall":
60
+ await uninstallService();
61
+ break;
62
+ case "status":
63
+ showStatus();
64
+ break;
65
+ case "logs":
66
+ showLogs(args[1]);
67
+ break;
68
+ default:
69
+ printHelp();
70
+ if (subcommand) {
71
+ console.error(`Unknown subcommand: ${subcommand}`);
72
+ process.exit(1);
73
+ }
74
+ break;
75
+ }
76
+ }
77
+ async function installService() {
78
+ const hivemindHome = getHivemindHome();
79
+ const hivemindBin = getHivemindBin();
80
+ console.log(`
81
+ \u2192 Installing launchd service for ${hivemindHome}
82
+ `);
83
+ console.log(` Binary: ${hivemindBin}`);
84
+ mkdirSync(LAUNCH_AGENTS_DIR, { recursive: true });
85
+ const plistContent = generatePlist(hivemindHome, hivemindBin);
86
+ const destPath = resolve(LAUNCH_AGENTS_DIR, `${AGENT_LABEL}.plist`);
87
+ try {
88
+ execSync(`launchctl unload ${destPath} 2>/dev/null`);
89
+ } catch {
90
+ }
91
+ writeFileSync(destPath, plistContent);
92
+ execSync(`launchctl load ${destPath}`);
93
+ console.log(` \u2713 ${AGENT_LABEL} installed and started`);
94
+ console.log("\n Service will auto-start on boot.");
95
+ console.log(" Logs: /tmp/hivemind-agent.log, /tmp/hivemind-error.log\n");
96
+ }
97
+ async function uninstallService() {
98
+ console.log("\n\u2192 Uninstalling launchd service\n");
99
+ const plistPath = resolve(LAUNCH_AGENTS_DIR, `${AGENT_LABEL}.plist`);
100
+ if (existsSync(plistPath)) {
101
+ try {
102
+ execSync(`launchctl unload ${plistPath} 2>/dev/null`);
103
+ } catch {
104
+ }
105
+ unlinkSync(plistPath);
106
+ console.log(` \u2713 ${AGENT_LABEL} uninstalled`);
107
+ } else {
108
+ console.log(` - ${AGENT_LABEL} not installed`);
109
+ }
110
+ console.log("");
111
+ }
112
+ function showStatus() {
113
+ console.log("\n\u2192 Service status\n");
114
+ try {
115
+ const out = execSync(`launchctl list ${AGENT_LABEL} 2>/dev/null`, { encoding: "utf-8" });
116
+ const pidMatch = out.match(/"PID"\s*=\s*(\d+)/);
117
+ const pid = pidMatch ? pidMatch[1] : "unknown";
118
+ console.log(` \u2713 ${AGENT_LABEL}: running (PID ${pid})`);
119
+ } catch {
120
+ console.log(` - ${AGENT_LABEL}: not running`);
121
+ }
122
+ console.log("");
123
+ }
124
+ function showLogs(which) {
125
+ const logFile = which === "error" ? "/tmp/hivemind-error.log" : "/tmp/hivemind-agent.log";
126
+ try {
127
+ execSync(`tail -30 ${logFile}`, { stdio: "inherit" });
128
+ } catch {
129
+ console.error(`No log file at ${logFile}`);
130
+ }
131
+ }
132
+ function printHelp() {
133
+ console.log(`hivemind service \u2014 Manage launchd service
134
+
135
+ Usage: hivemind service <subcommand>
136
+
137
+ Subcommands:
138
+ install Install and start launchd service (survives reboots)
139
+ uninstall Stop and remove launchd service
140
+ status Show service status
141
+ logs [agent|error] Show recent logs
142
+
143
+ Service:
144
+ com.hivemind.agent \u2014 Agent runtime (Node.js, Sesame)
145
+ `);
146
+ }
147
+
148
+ export {
149
+ runServiceCommand
150
+ };
151
+ //# sourceMappingURL=chunk-PPQGQHXJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../packages/cli/src/commands/service.ts"],"sourcesContent":["import { resolve } from \"path\";\nimport { writeFileSync, existsSync, unlinkSync, mkdirSync } 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\";\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 generatePlist(hivemindHome: string, hivemindBin: string): string {\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>${hivemindBin}</string>\n <string>start</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-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 \"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\n console.log(`\\n→ Installing launchd service for ${hivemindHome}\\n`);\n console.log(` Binary: ${hivemindBin}`);\n\n mkdirSync(LAUNCH_AGENTS_DIR, { recursive: true });\n\n const plistContent = generatePlist(hivemindHome, hivemindBin);\n const destPath = resolve(LAUNCH_AGENTS_DIR, `${AGENT_LABEL}.plist`);\n\n // Unload if already loaded\n try { execSync(`launchctl unload ${destPath} 2>/dev/null`); } catch {}\n\n writeFileSync(destPath, plistContent);\n execSync(`launchctl load ${destPath}`);\n\n console.log(` ✓ ${AGENT_LABEL} installed and started`);\n console.log(\"\\n Service will auto-start on boot.\");\n console.log(\" Logs: /tmp/hivemind-agent.log, /tmp/hivemind-error.log\\n\");\n}\n\nasync function uninstallService(): Promise<void> {\n console.log(\"\\n→ Uninstalling launchd service\\n\");\n\n const plistPath = resolve(LAUNCH_AGENTS_DIR, `${AGENT_LABEL}.plist`);\n if (existsSync(plistPath)) {\n try { execSync(`launchctl unload ${plistPath} 2>/dev/null`); } catch {}\n unlinkSync(plistPath);\n console.log(` ✓ ${AGENT_LABEL} uninstalled`);\n } else {\n console.log(` - ${AGENT_LABEL} not installed`);\n }\n console.log(\"\");\n}\n\nfunction showStatus(): void {\n console.log(\"\\n→ Service status\\n\");\n try {\n const out = execSync(`launchctl list ${AGENT_LABEL} 2>/dev/null`, { encoding: \"utf-8\" });\n const pidMatch = out.match(/\"PID\"\\s*=\\s*(\\d+)/);\n const pid = pidMatch ? pidMatch[1] : \"unknown\";\n console.log(` ✓ ${AGENT_LABEL}: running (PID ${pid})`);\n } catch {\n console.log(` - ${AGENT_LABEL}: not running`);\n }\n console.log(\"\");\n}\n\nfunction showLogs(which?: string): void {\n const logFile = which === \"error\"\n ? \"/tmp/hivemind-error.log\"\n : \"/tmp/hivemind-agent.log\";\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 service\n\nUsage: hivemind service <subcommand>\n\nSubcommands:\n install Install and start launchd service (survives reboots)\n uninstall Stop and remove launchd service\n status Show service status\n logs [agent|error] Show recent logs\n\nService:\n com.hivemind.agent — Agent runtime (Node.js, Sesame)\n`);\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runInitCommand
3
- } from "../chunk-2OIRJFI5.js";
3
+ } from "../chunk-56Z4WDJC.js";
4
4
  import "../chunk-GPI4RU7N.js";
5
5
  export {
6
6
  runInitCommand
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runServiceCommand
3
- } from "../chunk-MBS5A6BZ.js";
3
+ } from "../chunk-PPQGQHXJ.js";
4
4
  export {
5
5
  runServiceCommand
6
6
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runStartCommand
3
- } from "../chunk-O257FXSX.js";
3
+ } from "../chunk-LNV373IF.js";
4
4
  import "../chunk-S3RVZBPZ.js";
5
5
  import "../chunk-YHRGEWAZ.js";
6
6
  import "../chunk-GPI4RU7N.js";
package/dist/main.js CHANGED
@@ -1,16 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runInitCommand
4
- } from "./chunk-2OIRJFI5.js";
4
+ } from "./chunk-56Z4WDJC.js";
5
5
  import {
6
6
  runStartCommand
7
- } from "./chunk-O257FXSX.js";
7
+ } from "./chunk-LNV373IF.js";
8
8
  import {
9
9
  runFleetCommand
10
10
  } from "./chunk-CGSXJVSS.js";
11
11
  import {
12
12
  runServiceCommand
13
- } from "./chunk-MBS5A6BZ.js";
13
+ } from "./chunk-PPQGQHXJ.js";
14
14
  import {
15
15
  runUpgradeCommand
16
16
  } from "./chunk-SJI2KAIN.js";
package/install.sh CHANGED
@@ -1,9 +1,23 @@
1
1
  #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
- # Hivemind — One-shot install for macOS (Apple Silicon)
5
- # Usage (from repo): cd hivemind && ./install.sh <sesame-api-key>
6
- # Preferred: curl -sL api.sesame.space/api/v1/hivemind/install | bash -s -- <sesame-api-key>
4
+ # Hivemind — One-shot install for macOS
5
+ # Usage: curl -sL api.sesame.space/api/v1/hivemind/install | bash -s -- <sesame-api-key>
6
+
7
+ # --- Handle curl-pipe-bash stdin issue ---
8
+ # When piped from curl, stdin is the script itself. We need stdin for interactive prompts.
9
+ # Self-extract: download to temp, re-exec from disk with /dev/tty as stdin.
10
+ if [ -z "${HIVEMIND_INSTALL_REEXEC:-}" ]; then
11
+ TMPSCRIPT="$(mktemp /tmp/hivemind-install.XXXXXX)"
12
+ # If we're being piped, cat has already consumed stdin — use $0 or re-download
13
+ cat > "$TMPSCRIPT" < /dev/stdin 2>/dev/null || cp "$0" "$TMPSCRIPT" 2>/dev/null || true
14
+ # If the temp file is empty or too small, we're running from disk already
15
+ if [ -s "$TMPSCRIPT" ] && [ "$(wc -c < "$TMPSCRIPT")" -gt 100 ]; then
16
+ chmod +x "$TMPSCRIPT"
17
+ HIVEMIND_INSTALL_REEXEC=1 exec bash "$TMPSCRIPT" "$@" < /dev/tty
18
+ fi
19
+ rm -f "$TMPSCRIPT"
20
+ fi
7
21
 
8
22
  BOLD='\033[1m'
9
23
  GREEN='\033[0;32m'
@@ -16,6 +30,8 @@ warn() { echo -e "${YELLOW}[!]${NC} $1"; }
16
30
  err() { echo -e "${RED}[✗]${NC} $1"; }
17
31
  step() { echo -e "\n${BOLD}→ $1${NC}"; }
18
32
 
33
+ HIVEMIND_HOME="${HIVEMIND_HOME:-$HOME/hivemind}"
34
+
19
35
  echo -e "${BOLD}"
20
36
  echo " ╦ ╦╦╦ ╦╔═╗╔╦╗╦╔╗╔╔╦╗"
21
37
  echo " ╠═╣║╚╗╔╝║╣ ║║║║║║║ ║║"
@@ -50,138 +66,55 @@ else
50
66
  fi
51
67
  fi
52
68
 
53
- # pnpm
54
- if ! command -v pnpm &>/dev/null; then
55
- warn "pnpm not found — installing..."
56
- npm install -g pnpm
69
+ # --- 2. Install hivemind via npm ---
70
+ step "Installing @sesamespace/hivemind"
71
+ npm install -g @sesamespace/hivemind
72
+ info "Hivemind CLI installed: $(which hivemind)"
73
+
74
+ # --- 3. Set up HIVEMIND_HOME ---
75
+ step "Setting up ${HIVEMIND_HOME}"
76
+ mkdir -p "${HIVEMIND_HOME}/config"
77
+
78
+ # Copy default config
79
+ NPM_GLOBAL="$(npm root -g)"
80
+ DEFAULT_CONFIG="${NPM_GLOBAL}/@sesamespace/hivemind/config/default.toml"
81
+ if [ -f "$DEFAULT_CONFIG" ]; then
82
+ cp "$DEFAULT_CONFIG" "${HIVEMIND_HOME}/config/default.toml"
83
+ info "Copied default config"
57
84
  else
58
- info "pnpm $(pnpm -v)"
85
+ warn "Default config not found at ${DEFAULT_CONFIG} — skipping"
59
86
  fi
60
87
 
61
- # Rust
62
- if ! command -v cargo &>/dev/null; then
63
- warn "Rust not found — installing via rustup..."
64
- curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
65
- source "$HOME/.cargo/env"
66
- else
67
- info "Rust $(rustc --version | awk '{print $2}')"
68
- fi
88
+ # --- 4. Initialize agent ---
89
+ step "Initializing agent"
69
90
 
70
- # Ollama
71
- if ! command -v ollama &>/dev/null; then
72
- warn "Ollama not found installing via brew..."
73
- brew install ollama
74
- else
75
- info "Ollama found"
91
+ SESAME_KEY="${1:-${SESAME_API_KEY:-}}"
92
+ if [ -z "$SESAME_KEY" ]; then
93
+ read -rp " Sesame API key: " SESAME_KEY
76
94
  fi
77
95
 
78
- # --- 2. Pull embedding model ---
79
- step "Setting up Ollama embedding model"
80
-
81
- # Start Ollama if not running
82
- if ! curl -s http://localhost:11434/api/tags &>/dev/null; then
83
- warn "Ollama not running — starting..."
84
- ollama serve &>/dev/null &
85
- sleep 3
96
+ if [ -z "$SESAME_KEY" ]; then
97
+ err "Sesame API key is required"
98
+ exit 1
86
99
  fi
87
100
 
88
- if ollama list 2>/dev/null | grep -q "nomic-embed-text"; then
89
- info "nomic-embed-text model ready"
90
- else
91
- warn "Pulling nomic-embed-text (274MB)..."
92
- ollama pull nomic-embed-text
93
- info "nomic-embed-text ready"
94
- fi
95
-
96
- # --- 3. Build TypeScript packages ---
97
- step "Installing Node dependencies"
98
- pnpm install
99
- info "Dependencies installed"
100
-
101
- step "Building TypeScript"
102
- pnpm build
103
- info "TypeScript build complete"
104
-
105
- # --- 4. Build Rust memory daemon ---
106
- step "Building memory daemon (Rust — this takes ~60s first time)"
107
- cd packages/memory
108
- cargo build --release 2>&1 | tail -3
109
- cd ../..
110
- info "Memory daemon built"
111
-
112
- # --- 5. Configuration via Sesame ---
113
- step "Configuring agent via Sesame"
114
-
115
- if [ -f ".env" ]; then
116
- info "Existing .env found — keeping it"
117
- else
118
- SESAME_KEY="${1:-${SESAME_API_KEY:-}}"
119
- if [ -z "$SESAME_KEY" ]; then
120
- read -rp " Sesame API key: " SESAME_KEY
121
- fi
122
- node packages/cli/dist/main.js init "$SESAME_KEY"
123
- fi
101
+ export HIVEMIND_HOME
102
+ hivemind init "$SESAME_KEY" --non-interactive
124
103
 
125
- # --- 6. Create launch script ---
126
- step "Creating launch script"
127
-
128
- cat > start.sh <<'LAUNCH'
129
- #!/usr/bin/env bash
130
- set -euo pipefail
131
-
132
- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
133
- cd "$SCRIPT_DIR"
134
-
135
- # Load env
136
- if [ -f .env ]; then
137
- set -a; source .env; set +a
138
- fi
139
-
140
- # Start memory daemon if not running
141
- if ! curl -s http://localhost:3434/health &>/dev/null; then
142
- echo "[hivemind] Starting memory daemon..."
143
- nohup ./packages/memory/target/release/hivemind-memory > /tmp/hivemind-memory.log 2>&1 &
144
- sleep 2
145
- if curl -s http://localhost:3434/health &>/dev/null; then
146
- echo "[hivemind] Memory daemon ready"
147
- else
148
- echo "[hivemind] WARNING: Memory daemon failed to start"
149
- fi
150
- else
151
- echo "[hivemind] Memory daemon already running"
152
- fi
153
-
154
- # Start Ollama if not running
155
- if ! curl -s http://localhost:11434/api/tags &>/dev/null; then
156
- echo "[hivemind] Starting Ollama..."
157
- ollama serve &>/dev/null &
158
- sleep 3
159
- fi
160
-
161
- # Start agent (auto-restart on crash)
162
- echo "[hivemind] Starting agent..."
163
- while true; do
164
- node packages/cli/dist/main.js start --config config/default.toml
165
- EXIT_CODE=$?
166
- echo "[hivemind] Agent exited with code $EXIT_CODE — restarting in 5s..."
167
- sleep 5
168
- done
169
- LAUNCH
170
-
171
- chmod +x start.sh
172
- info "Created start.sh (with auto-restart)"
104
+ # --- 5. Install launchd service ---
105
+ step "Installing launchd service"
106
+ hivemind service install
173
107
 
174
108
  # --- Done ---
175
109
  echo ""
176
110
  echo -e "${GREEN}${BOLD} ✓ Hivemind installed successfully!${NC}"
177
111
  echo ""
178
- echo " To start the agent:"
179
- echo " ./start.sh"
180
- echo ""
181
- echo " To start in background:"
182
- echo " nohup ./start.sh > /tmp/hivemind.log 2>&1 &"
112
+ echo " Home: ${HIVEMIND_HOME}"
113
+ echo " Config: ${HIVEMIND_HOME}/config/"
114
+ echo " Logs: /tmp/hivemind-agent.log"
183
115
  echo ""
184
- echo " Logs:"
185
- echo " Agent: stdout (or /tmp/hivemind.log)"
186
- echo " Memory: /tmp/hivemind-memory.log"
116
+ echo " Commands:"
117
+ echo " hivemind service status — Check service"
118
+ echo " hivemind service logs — View logs"
119
+ echo " hivemind upgrade — Update to latest"
187
120
  echo ""
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sesamespace/hivemind",
3
- "version": "0.4.3",
3
+ "version": "0.5.1",
4
4
  "description": "Cognitive architecture for AI agents with multi-layered memory",
5
5
  "scripts": {
6
6
  "build": "pnpm -r build",
@@ -1,9 +1,11 @@
1
1
  import { resolve, dirname } from "path";
2
- import { existsSync, writeFileSync, mkdirSync, readFileSync } from "fs";
2
+ import { existsSync, writeFileSync, mkdirSync, readFileSync, copyFileSync } from "fs";
3
3
  import { createInterface } from "readline";
4
+ import { fileURLToPath } from "url";
4
5
  import { SesameClient } from "@sesamespace/sdk";
6
+ import { homedir } from "os";
5
7
 
6
- const HIVEMIND_DIR = resolve(process.env.HIVEMIND_HOME || ".");
8
+ const HIVEMIND_DIR = resolve(process.env.HIVEMIND_HOME || resolve(homedir(), "hivemind"));
7
9
  const CONFIG_DIR = resolve(HIVEMIND_DIR, "config");
8
10
  const WORKSPACE_DIR = resolve(HIVEMIND_DIR, "workspace");
9
11
  const ENV_FILE = resolve(HIVEMIND_DIR, ".env");
@@ -142,6 +144,27 @@ export async function runInitCommand(args: string[]): Promise<void> {
142
144
  mkdirSync(CONFIG_DIR, { recursive: true });
143
145
  mkdirSync(WORKSPACE_DIR, { recursive: true });
144
146
 
147
+ // Copy default.toml from installed package if not present
148
+ const defaultToml = resolve(CONFIG_DIR, "default.toml");
149
+ if (!existsSync(defaultToml)) {
150
+ // Resolve from the package install location (../../config/default.toml relative to this file)
151
+ const packageConfigDir = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "config");
152
+ const packageDefault = resolve(packageConfigDir, "default.toml");
153
+ if (existsSync(packageDefault)) {
154
+ copyFileSync(packageDefault, defaultToml);
155
+ console.log(` ✓ ${defaultToml}`);
156
+ // Also copy team charter if available
157
+ const packageCharter = resolve(packageConfigDir, "TEAM-CHARTER.md");
158
+ const localCharter = resolve(CONFIG_DIR, "TEAM-CHARTER.md");
159
+ if (existsSync(packageCharter) && !existsSync(localCharter)) {
160
+ copyFileSync(packageCharter, localCharter);
161
+ console.log(` ✓ ${localCharter}`);
162
+ }
163
+ } else {
164
+ console.log(` ! default.toml not found in package — you may need to copy it manually`);
165
+ }
166
+ }
167
+
145
168
  // Write workspace identity files
146
169
  const soulPath = resolve(WORKSPACE_DIR, "SOUL.md");
147
170
  if (!existsSync(soulPath)) {
@@ -179,6 +202,9 @@ workspace = "workspace"
179
202
 
180
203
  ${config.llmModel ? `[llm]\nmodel = "${config.llmModel}"` : "# [llm] using defaults"}
181
204
  ${config.llmBaseUrl ? `# base_url = "${config.llmBaseUrl}"` : ""}
205
+
206
+ [sesame]
207
+ api_key = "${sesameApiKey}"
182
208
  `;
183
209
 
184
210
  writeFileSync(LOCAL_TOML, localToml);
@@ -200,10 +226,10 @@ AGENT_NAME=${config.agentName}
200
226
  ✓ Hivemind initialized for ${config.agentName}!
201
227
 
202
228
  To start the agent:
203
- ./start.sh
229
+ hivemind start
204
230
 
205
- To start in background:
206
- nohup ./start.sh > /tmp/hivemind.log 2>&1 &
231
+ To install as a service:
232
+ hivemind service install
207
233
 
208
234
  Agent ID: ${config.agentId}
209
235
  Channels: ${config.channels.map((c) => c.name || c.id).join(", ")}