@inixiative/hivemind 0.1.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 (287) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +115 -0
  3. package/dist/agents/agents.test.d.ts +1 -0
  4. package/dist/agents/agents.test.js +167 -0
  5. package/dist/agents/getActiveAgents.d.ts +6 -0
  6. package/dist/agents/getActiveAgents.js +11 -0
  7. package/dist/agents/getAgent.d.ts +6 -0
  8. package/dist/agents/getAgent.js +7 -0
  9. package/dist/agents/getAgentBySessionId.d.ts +10 -0
  10. package/dist/agents/getAgentBySessionId.js +17 -0
  11. package/dist/agents/index.d.ts +10 -0
  12. package/dist/agents/index.js +12 -0
  13. package/dist/agents/markAgentDead.d.ts +6 -0
  14. package/dist/agents/markAgentDead.js +26 -0
  15. package/dist/agents/markAgentIdle.d.ts +5 -0
  16. package/dist/agents/markAgentIdle.js +12 -0
  17. package/dist/agents/registerAgent.d.ts +6 -0
  18. package/dist/agents/registerAgent.js +29 -0
  19. package/dist/agents/types.d.ts +30 -0
  20. package/dist/agents/types.js +1 -0
  21. package/dist/agents/unregisterAgent.d.ts +5 -0
  22. package/dist/agents/unregisterAgent.js +8 -0
  23. package/dist/agents/updateAgentContext.d.ts +5 -0
  24. package/dist/agents/updateAgentContext.js +12 -0
  25. package/dist/agents/updateAgentTask.d.ts +5 -0
  26. package/dist/agents/updateAgentTask.js +12 -0
  27. package/dist/agents/updateAgentWorktree.d.ts +5 -0
  28. package/dist/agents/updateAgentWorktree.js +12 -0
  29. package/dist/cli/index.d.ts +8 -0
  30. package/dist/cli/index.js +8 -0
  31. package/dist/cli/init.d.ts +14 -0
  32. package/dist/cli/init.js +71 -0
  33. package/dist/cli/install.d.ts +8 -0
  34. package/dist/cli/install.js +47 -0
  35. package/dist/cli/join.d.ts +9 -0
  36. package/dist/cli/join.js +38 -0
  37. package/dist/cli/registerMcp.d.ts +28 -0
  38. package/dist/cli/registerMcp.js +138 -0
  39. package/dist/cli/status.d.ts +8 -0
  40. package/dist/cli/status.js +82 -0
  41. package/dist/cli/watch.d.ts +6 -0
  42. package/dist/cli/watch.js +68 -0
  43. package/dist/cli.d.ts +12 -0
  44. package/dist/cli.js +49 -0
  45. package/dist/coordinator/coordinator.test.d.ts +1 -0
  46. package/dist/coordinator/coordinator.test.js +171 -0
  47. package/dist/coordinator/index.d.ts +16 -0
  48. package/dist/coordinator/index.js +166 -0
  49. package/dist/coordinator/spawn.d.ts +22 -0
  50. package/dist/coordinator/spawn.js +66 -0
  51. package/dist/datetime/datetime.test.d.ts +1 -0
  52. package/dist/datetime/datetime.test.js +63 -0
  53. package/dist/datetime/formatDate.d.ts +6 -0
  54. package/dist/datetime/formatDate.js +11 -0
  55. package/dist/datetime/formatDatetime.d.ts +6 -0
  56. package/dist/datetime/formatDatetime.js +12 -0
  57. package/dist/datetime/formatTime.d.ts +6 -0
  58. package/dist/datetime/formatTime.js +11 -0
  59. package/dist/datetime/index.d.ts +4 -0
  60. package/dist/datetime/index.js +7 -0
  61. package/dist/datetime/isStale.d.ts +10 -0
  62. package/dist/datetime/isStale.js +18 -0
  63. package/dist/datetime/now.d.ts +6 -0
  64. package/dist/datetime/now.js +9 -0
  65. package/dist/datetime/parseDatetime.d.ts +7 -0
  66. package/dist/datetime/parseDatetime.js +28 -0
  67. package/dist/db/constants.d.ts +4 -0
  68. package/dist/db/constants.js +6 -0
  69. package/dist/db/db.test.d.ts +1 -0
  70. package/dist/db/db.test.js +141 -0
  71. package/dist/db/ensureProjectDirs.d.ts +4 -0
  72. package/dist/db/ensureProjectDirs.js +12 -0
  73. package/dist/db/getConnection.d.ts +19 -0
  74. package/dist/db/getConnection.js +51 -0
  75. package/dist/db/getCurrentProject.d.ts +8 -0
  76. package/dist/db/getCurrentProject.js +14 -0
  77. package/dist/db/getProjectPaths.d.ts +21 -0
  78. package/dist/db/getProjectPaths.js +26 -0
  79. package/dist/db/index.d.ts +10 -0
  80. package/dist/db/index.js +13 -0
  81. package/dist/db/initializeDb.d.ts +7 -0
  82. package/dist/db/initializeDb.js +23 -0
  83. package/dist/db/nextEventSeq.d.ts +5 -0
  84. package/dist/db/nextEventSeq.js +13 -0
  85. package/dist/db/nextSubtaskSeq.d.ts +5 -0
  86. package/dist/db/nextSubtaskSeq.js +12 -0
  87. package/dist/db/nextTaskSeq.d.ts +5 -0
  88. package/dist/db/nextTaskSeq.js +13 -0
  89. package/dist/db/resetDb.d.ts +10 -0
  90. package/dist/db/resetDb.js +36 -0
  91. package/dist/events/emit.d.ts +6 -0
  92. package/dist/events/emit.js +31 -0
  93. package/dist/events/events.test.d.ts +1 -0
  94. package/dist/events/events.test.js +145 -0
  95. package/dist/events/getEventsByAgent.d.ts +6 -0
  96. package/dist/events/getEventsByAgent.js +14 -0
  97. package/dist/events/getEventsByBranch.d.ts +6 -0
  98. package/dist/events/getEventsByBranch.js +12 -0
  99. package/dist/events/getEventsByPlan.d.ts +6 -0
  100. package/dist/events/getEventsByPlan.js +14 -0
  101. package/dist/events/getEventsByWorktree.d.ts +6 -0
  102. package/dist/events/getEventsByWorktree.js +12 -0
  103. package/dist/events/getEventsSince.d.ts +12 -0
  104. package/dist/events/getEventsSince.js +47 -0
  105. package/dist/events/getRecentEvents.d.ts +6 -0
  106. package/dist/events/getRecentEvents.js +12 -0
  107. package/dist/events/index.d.ts +8 -0
  108. package/dist/events/index.js +9 -0
  109. package/dist/events/types.d.ts +34 -0
  110. package/dist/events/types.js +1 -0
  111. package/dist/git/getBranch.d.ts +4 -0
  112. package/dist/git/getBranch.js +14 -0
  113. package/dist/git/getCurrentWorktree.d.ts +5 -0
  114. package/dist/git/getCurrentWorktree.js +15 -0
  115. package/dist/git/getGitInfo.d.ts +10 -0
  116. package/dist/git/getGitInfo.js +23 -0
  117. package/dist/git/getRepoName.d.ts +4 -0
  118. package/dist/git/getRepoName.js +32 -0
  119. package/dist/git/getRepoRoot.d.ts +4 -0
  120. package/dist/git/getRepoRoot.js +14 -0
  121. package/dist/git/getWorktrees.d.ts +10 -0
  122. package/dist/git/getWorktrees.js +39 -0
  123. package/dist/git/index.d.ts +9 -0
  124. package/dist/git/index.js +7 -0
  125. package/dist/git/isGitRepo.d.ts +4 -0
  126. package/dist/git/isGitRepo.js +13 -0
  127. package/dist/hooks/index.d.ts +1 -0
  128. package/dist/hooks/index.js +1 -0
  129. package/dist/hooks/sessionStart.d.ts +21 -0
  130. package/dist/hooks/sessionStart.js +93 -0
  131. package/dist/ids/generateHex.d.ts +4 -0
  132. package/dist/ids/generateHex.js +7 -0
  133. package/dist/ids/getParentTaskId.d.ts +7 -0
  134. package/dist/ids/getParentTaskId.js +15 -0
  135. package/dist/ids/getPlanHexFromTaskId.d.ts +6 -0
  136. package/dist/ids/getPlanHexFromTaskId.js +9 -0
  137. package/dist/ids/ids.test.d.ts +1 -0
  138. package/dist/ids/ids.test.js +215 -0
  139. package/dist/ids/index.d.ts +16 -0
  140. package/dist/ids/index.js +17 -0
  141. package/dist/ids/isSubtask.d.ts +7 -0
  142. package/dist/ids/isSubtask.js +11 -0
  143. package/dist/ids/isValidId.d.ts +9 -0
  144. package/dist/ids/isValidId.js +22 -0
  145. package/dist/ids/makeAgentId.d.ts +8 -0
  146. package/dist/ids/makeAgentId.js +15 -0
  147. package/dist/ids/makeEventId.d.ts +11 -0
  148. package/dist/ids/makeEventId.js +12 -0
  149. package/dist/ids/makePlanId.d.ts +11 -0
  150. package/dist/ids/makePlanId.js +15 -0
  151. package/dist/ids/makeSubtaskId.d.ts +8 -0
  152. package/dist/ids/makeSubtaskId.js +15 -0
  153. package/dist/ids/makeTaskId.d.ts +8 -0
  154. package/dist/ids/makeTaskId.js +14 -0
  155. package/dist/ids/makeWorktreeId.d.ts +5 -0
  156. package/dist/ids/makeWorktreeId.js +12 -0
  157. package/dist/ids/parseId.d.ts +11 -0
  158. package/dist/ids/parseId.js +26 -0
  159. package/dist/ids/sanitizeLabel.d.ts +7 -0
  160. package/dist/ids/sanitizeLabel.js +12 -0
  161. package/dist/ids/typedIds.d.ts +34 -0
  162. package/dist/ids/typedIds.js +22 -0
  163. package/dist/ids/types.d.ts +14 -0
  164. package/dist/ids/types.js +1 -0
  165. package/dist/init/claudeConfig.d.ts +39 -0
  166. package/dist/init/claudeConfig.js +161 -0
  167. package/dist/llm/extractTasks.d.ts +28 -0
  168. package/dist/llm/extractTasks.js +108 -0
  169. package/dist/llm/index.d.ts +2 -0
  170. package/dist/llm/index.js +2 -0
  171. package/dist/llm/reconcileTasks.d.ts +21 -0
  172. package/dist/llm/reconcileTasks.js +82 -0
  173. package/dist/mcp/server.d.ts +2 -0
  174. package/dist/mcp/server.js +100 -0
  175. package/dist/mcp/tools/emitEvent.d.ts +62 -0
  176. package/dist/mcp/tools/emitEvent.js +84 -0
  177. package/dist/mcp/tools/events.d.ts +55 -0
  178. package/dist/mcp/tools/events.js +56 -0
  179. package/dist/mcp/tools/index.d.ts +18 -0
  180. package/dist/mcp/tools/index.js +13 -0
  181. package/dist/mcp/tools/query.d.ts +54 -0
  182. package/dist/mcp/tools/query.js +70 -0
  183. package/dist/mcp/tools/register.d.ts +47 -0
  184. package/dist/mcp/tools/register.js +79 -0
  185. package/dist/mcp/tools/reset.d.ts +38 -0
  186. package/dist/mcp/tools/reset.js +56 -0
  187. package/dist/mcp/tools/setup.d.ts +42 -0
  188. package/dist/mcp/tools/setup.js +75 -0
  189. package/dist/mcp/tools/status.d.ts +44 -0
  190. package/dist/mcp/tools/status.js +74 -0
  191. package/dist/mcp/tools/tasks.d.ts +116 -0
  192. package/dist/mcp/tools/tasks.js +143 -0
  193. package/dist/mcp/tools/worktreeCleanup.d.ts +38 -0
  194. package/dist/mcp/tools/worktreeCleanup.js +67 -0
  195. package/dist/plans/createPlan.d.ts +6 -0
  196. package/dist/plans/createPlan.js +29 -0
  197. package/dist/plans/getActivePlans.d.ts +6 -0
  198. package/dist/plans/getActivePlans.js +11 -0
  199. package/dist/plans/getPlan.d.ts +6 -0
  200. package/dist/plans/getPlan.js +7 -0
  201. package/dist/plans/index.d.ts +5 -0
  202. package/dist/plans/index.js +5 -0
  203. package/dist/plans/plans.test.d.ts +1 -0
  204. package/dist/plans/plans.test.js +107 -0
  205. package/dist/plans/types.d.ts +32 -0
  206. package/dist/plans/types.js +1 -0
  207. package/dist/plans/updatePlanStatus.d.ts +6 -0
  208. package/dist/plans/updatePlanStatus.js +8 -0
  209. package/dist/tasks/assignTask.d.ts +7 -0
  210. package/dist/tasks/assignTask.js +20 -0
  211. package/dist/tasks/blockTask.d.ts +5 -0
  212. package/dist/tasks/blockTask.js +12 -0
  213. package/dist/tasks/claimTask.d.ts +7 -0
  214. package/dist/tasks/claimTask.js +21 -0
  215. package/dist/tasks/completeTask.d.ts +6 -0
  216. package/dist/tasks/completeTask.js +18 -0
  217. package/dist/tasks/createTask.d.ts +6 -0
  218. package/dist/tasks/createTask.js +36 -0
  219. package/dist/tasks/getPendingTasks.d.ts +6 -0
  220. package/dist/tasks/getPendingTasks.js +19 -0
  221. package/dist/tasks/getTask.d.ts +6 -0
  222. package/dist/tasks/getTask.js +7 -0
  223. package/dist/tasks/getTasksByPlan.d.ts +6 -0
  224. package/dist/tasks/getTasksByPlan.js +11 -0
  225. package/dist/tasks/index.d.ts +11 -0
  226. package/dist/tasks/index.js +12 -0
  227. package/dist/tasks/startTask.d.ts +5 -0
  228. package/dist/tasks/startTask.js +12 -0
  229. package/dist/tasks/tasks.test.d.ts +1 -0
  230. package/dist/tasks/tasks.test.js +209 -0
  231. package/dist/tasks/types.d.ts +36 -0
  232. package/dist/tasks/types.js +1 -0
  233. package/dist/tasks/unclaimTask.d.ts +5 -0
  234. package/dist/tasks/unclaimTask.js +12 -0
  235. package/dist/test/factories/agentFactory.d.ts +13 -0
  236. package/dist/test/factories/agentFactory.js +5 -0
  237. package/dist/test/factories/eventFactory.d.ts +20 -0
  238. package/dist/test/factories/eventFactory.js +16 -0
  239. package/dist/test/factories/factories.test.d.ts +1 -0
  240. package/dist/test/factories/factories.test.js +101 -0
  241. package/dist/test/factories/index.d.ts +4 -0
  242. package/dist/test/factories/index.js +4 -0
  243. package/dist/test/factories/planFactory.d.ts +15 -0
  244. package/dist/test/factories/planFactory.js +14 -0
  245. package/dist/test/factories/taskFactory.d.ts +22 -0
  246. package/dist/test/factories/taskFactory.js +44 -0
  247. package/dist/test/multiAgentDemo.d.ts +16 -0
  248. package/dist/test/multiAgentDemo.js +20 -0
  249. package/dist/test/multiAgentDemo.test.d.ts +1 -0
  250. package/dist/test/multiAgentDemo.test.js +14 -0
  251. package/dist/test/setup.d.ts +9 -0
  252. package/dist/test/setup.js +50 -0
  253. package/dist/utils/index.d.ts +5 -0
  254. package/dist/utils/index.js +5 -0
  255. package/dist/utils/math.d.ts +6 -0
  256. package/dist/utils/math.js +10 -0
  257. package/dist/utils/math.test.d.ts +1 -0
  258. package/dist/utils/math.test.js +26 -0
  259. package/dist/utils/string.d.ts +11 -0
  260. package/dist/utils/string.js +17 -0
  261. package/dist/utils/string.test.d.ts +1 -0
  262. package/dist/utils/string.test.js +30 -0
  263. package/dist/watcher/index.d.ts +1 -0
  264. package/dist/watcher/index.js +1 -0
  265. package/dist/watcher/planWatcher.d.ts +31 -0
  266. package/dist/watcher/planWatcher.js +171 -0
  267. package/dist/worktrees/getAllWorktrees.d.ts +6 -0
  268. package/dist/worktrees/getAllWorktrees.js +10 -0
  269. package/dist/worktrees/getWorktreeById.d.ts +6 -0
  270. package/dist/worktrees/getWorktreeById.js +7 -0
  271. package/dist/worktrees/getWorktreeByPath.d.ts +6 -0
  272. package/dist/worktrees/getWorktreeByPath.js +7 -0
  273. package/dist/worktrees/index.d.ts +9 -0
  274. package/dist/worktrees/index.js +13 -0
  275. package/dist/worktrees/registerWorktree.d.ts +6 -0
  276. package/dist/worktrees/registerWorktree.js +28 -0
  277. package/dist/worktrees/removeWorktree.d.ts +6 -0
  278. package/dist/worktrees/removeWorktree.js +9 -0
  279. package/dist/worktrees/syncWorktreesFromGit.d.ts +7 -0
  280. package/dist/worktrees/syncWorktreesFromGit.js +51 -0
  281. package/dist/worktrees/types.d.ts +29 -0
  282. package/dist/worktrees/types.js +1 -0
  283. package/dist/worktrees/updateWorktreeCommit.d.ts +5 -0
  284. package/dist/worktrees/updateWorktreeCommit.js +13 -0
  285. package/dist/worktrees/updateWorktreeSeen.d.ts +5 -0
  286. package/dist/worktrees/updateWorktreeSeen.js +13 -0
  287. package/package.json +58 -0
@@ -0,0 +1,71 @@
1
+ /**
2
+ * hivemind init - Register a project with hivemind
3
+ *
4
+ * Run from a project directory to:
5
+ * 1. Create database in ~/.hivemind/<project>/
6
+ * 2. Set up .claude/settings.json hooks
7
+ * 3. Add CLAUDE.md instructions
8
+ */
9
+ import { dirname, join } from 'path';
10
+ import { fileURLToPath } from 'url';
11
+ import { getGitInfo } from '../git/getGitInfo';
12
+ import { initializeDb } from '../db/initializeDb';
13
+ import { getProjectPaths } from '../db/getProjectPaths';
14
+ import { initClaudeConfig } from '../init/claudeConfig';
15
+ const __dirname = dirname(fileURLToPath(import.meta.url));
16
+ const HIVEMIND_ROOT = join(__dirname, '../..');
17
+ export async function initCommand(options) {
18
+ // Determine project name
19
+ const gitInfo = getGitInfo();
20
+ let projectName = options.project;
21
+ if (!projectName) {
22
+ if (gitInfo.isRepo && gitInfo.repoName) {
23
+ projectName = gitInfo.repoName;
24
+ }
25
+ else {
26
+ projectName = process.cwd().split('/').pop() || 'default';
27
+ }
28
+ }
29
+ console.log(`hivemind init: ${projectName}\n`);
30
+ // 1. Initialize database
31
+ console.log('[1/2] Database');
32
+ const paths = getProjectPaths(projectName);
33
+ const db = initializeDb(projectName);
34
+ // Get stats
35
+ const agentCount = db.prepare('SELECT COUNT(*) as c FROM agents').get().c;
36
+ const planCount = db.prepare('SELECT COUNT(*) as c FROM plans').get().c;
37
+ const eventCount = db.prepare('SELECT COUNT(*) as c FROM events').get().c;
38
+ db.close();
39
+ console.log(` path: ${paths.dbPath}`);
40
+ if (agentCount > 0 || planCount > 0) {
41
+ console.log(` stats: ${agentCount} agents, ${planCount} plans, ${eventCount} events`);
42
+ }
43
+ else {
44
+ console.log(' status: created');
45
+ }
46
+ // 2. Set up Claude config (hooks + CLAUDE.md)
47
+ if (options.hooks !== false) {
48
+ console.log('\n[2/2] Claude Config');
49
+ const projectRoot = gitInfo.root || process.cwd();
50
+ const configResult = initClaudeConfig(projectRoot, projectName, HIVEMIND_ROOT);
51
+ if (configResult.created.length > 0) {
52
+ console.log(` created: ${configResult.created.join(', ')}`);
53
+ }
54
+ if (configResult.updated.length > 0) {
55
+ console.log(` updated: ${configResult.updated.join(', ')}`);
56
+ }
57
+ if (configResult.created.length === 0 && configResult.updated.length === 0) {
58
+ console.log(' status: already configured');
59
+ }
60
+ }
61
+ else {
62
+ console.log('\n[2/2] Claude Config (skipped)');
63
+ }
64
+ // Success
65
+ console.log('\n---');
66
+ console.log('Project registered! Restart Claude Code to activate.');
67
+ console.log('\nNext session will:');
68
+ console.log(' - Auto-register as a hivemind agent');
69
+ console.log(' - Have hivemind MCP tools available');
70
+ console.log(' - Follow 001-style task numbering');
71
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * hivemind install - One-time global setup
3
+ *
4
+ * Run from hivemind directory to:
5
+ * 1. Install dependencies
6
+ * 2. Register MCP server globally
7
+ */
8
+ export declare function installCommand(): Promise<void>;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * hivemind install - One-time global setup
3
+ *
4
+ * Run from hivemind directory to:
5
+ * 1. Install dependencies
6
+ * 2. Register MCP server globally
7
+ */
8
+ import { dirname, join } from 'path';
9
+ import { fileURLToPath } from 'url';
10
+ import { $ } from 'bun';
11
+ import { registerMcpServer, configurePermissions } from './registerMcp';
12
+ const __dirname = dirname(fileURLToPath(import.meta.url));
13
+ const HIVEMIND_ROOT = join(__dirname, '../..');
14
+ export async function installCommand() {
15
+ console.log('hivemind install\n');
16
+ // 1. Install dependencies
17
+ console.log('[1/3] Dependencies');
18
+ try {
19
+ await $ `cd ${HIVEMIND_ROOT} && bun install`.quiet();
20
+ console.log(' installed');
21
+ }
22
+ catch (error) {
23
+ console.error(' failed to install dependencies');
24
+ process.exit(1);
25
+ }
26
+ // 2. Register MCP server
27
+ console.log('\n[2/3] MCP Server');
28
+ const mcpResult = await registerMcpServer(HIVEMIND_ROOT);
29
+ console.log(` ${mcpResult.message}`);
30
+ if (!mcpResult.success) {
31
+ process.exit(1);
32
+ }
33
+ // 3. Configure permissions (auto-approve structured tools)
34
+ console.log('\n[3/3] Permissions');
35
+ const permResult = configurePermissions();
36
+ console.log(` ${permResult.message}`);
37
+ if (permResult.added.length > 0) {
38
+ console.log(' auto-approved: status, events, query, claim/start/complete task');
39
+ console.log(' requires approval: emit (ad-hoc messages)');
40
+ }
41
+ // Success
42
+ console.log('\n---');
43
+ console.log('Hivemind installed globally!');
44
+ console.log('\nNext steps:');
45
+ console.log(' cd <your-project>');
46
+ console.log(' bun run /path/to/hivemind init');
47
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * hivemind join - Join the hivemind as an agent
3
+ */
4
+ type JoinOptions = {
5
+ label?: string;
6
+ context?: string;
7
+ };
8
+ export declare function joinCommand(options: JoinOptions): Promise<void>;
9
+ export {};
@@ -0,0 +1,38 @@
1
+ /**
2
+ * hivemind join - Join the hivemind as an agent
3
+ */
4
+ import { executeRegister } from '../mcp/tools/register';
5
+ import { executeStatus } from '../mcp/tools/status';
6
+ import { getGitInfo } from '../git/getGitInfo';
7
+ export async function joinCommand(options) {
8
+ const gitInfo = getGitInfo();
9
+ if (!gitInfo.isRepo || !gitInfo.repoName) {
10
+ console.log('Not in a git repository. Run from a git project directory.');
11
+ return;
12
+ }
13
+ console.log(`hivemind join: ${gitInfo.repoName}\n`);
14
+ try {
15
+ const result = executeRegister({
16
+ project: gitInfo.repoName,
17
+ label: options.label,
18
+ contextSummary: options.context,
19
+ });
20
+ console.log(`Agent: ${result.agentId}`);
21
+ if (result.branch) {
22
+ console.log(`Branch: ${result.branch}`);
23
+ }
24
+ // Show other active agents
25
+ const status = executeStatus({ project: gitInfo.repoName });
26
+ const otherAgents = status.activeAgents?.filter((a) => a.id !== result.agentId) || [];
27
+ if (otherAgents.length > 0) {
28
+ console.log('\nOther active agents:');
29
+ for (const agent of otherAgents) {
30
+ console.log(` ${agent.id}`);
31
+ }
32
+ }
33
+ console.log('\nJoined successfully!');
34
+ }
35
+ catch (error) {
36
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
37
+ }
38
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Register hivemind MCP server with Claude Code
3
+ */
4
+ type RegisterResult = {
5
+ success: boolean;
6
+ message: string;
7
+ alreadyRegistered?: boolean;
8
+ };
9
+ /**
10
+ * Register the hivemind MCP server using `claude mcp add`
11
+ */
12
+ export declare function registerMcpServer(hivemindRoot: string): Promise<RegisterResult>;
13
+ /**
14
+ * Check if hivemind MCP server is registered
15
+ */
16
+ export declare function isMcpRegistered(): Promise<boolean>;
17
+ type PermissionResult = {
18
+ success: boolean;
19
+ message: string;
20
+ added: string[];
21
+ alreadyPresent: string[];
22
+ };
23
+ /**
24
+ * Configure auto-approve permissions for hivemind tools
25
+ * Adds structured tools to ~/.claude/settings.json permissions.allow
26
+ */
27
+ export declare function configurePermissions(): PermissionResult;
28
+ export {};
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Register hivemind MCP server with Claude Code
3
+ */
4
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
5
+ import { join } from 'path';
6
+ import { homedir } from 'os';
7
+ import { $ } from 'bun';
8
+ /**
9
+ * Hivemind tools that should be auto-approved (structured operations)
10
+ * These have predictable semantics and don't require human oversight
11
+ */
12
+ const AUTO_APPROVED_TOOLS = [
13
+ // Lifecycle
14
+ 'mcp__hivemind__hivemind_setup',
15
+ 'mcp__hivemind__hivemind_register',
16
+ // Read-only queries
17
+ 'mcp__hivemind__hivemind_status',
18
+ 'mcp__hivemind__hivemind_events',
19
+ 'mcp__hivemind__hivemind_query',
20
+ // Task management (structured operations)
21
+ 'mcp__hivemind__hivemind_claim_task',
22
+ 'mcp__hivemind__hivemind_start_task',
23
+ 'mcp__hivemind__hivemind_complete_task',
24
+ // Maintenance
25
+ 'mcp__hivemind__hivemind_worktree_cleanup',
26
+ ];
27
+ // NOT auto-approved (require human oversight):
28
+ // - hivemind_emit: allows arbitrary messages to other agents
29
+ // - hivemind_reset: destructive operation that wipes the database
30
+ /**
31
+ * Register the hivemind MCP server using `claude mcp add`
32
+ */
33
+ export async function registerMcpServer(hivemindRoot) {
34
+ const serverPath = join(hivemindRoot, 'src/mcp/server.ts');
35
+ const command = `bun run ${serverPath}`;
36
+ try {
37
+ // Check if already registered
38
+ const listResult = await $ `claude mcp list 2>/dev/null`.text();
39
+ if (listResult.includes('hivemind')) {
40
+ return {
41
+ success: true,
42
+ message: 'already registered',
43
+ alreadyRegistered: true,
44
+ };
45
+ }
46
+ // Register the MCP server
47
+ await $ `claude mcp add --transport stdio hivemind -- ${command}`.quiet();
48
+ return {
49
+ success: true,
50
+ message: `registered: hivemind -> ${command}`,
51
+ };
52
+ }
53
+ catch (error) {
54
+ // Check if claude CLI is available
55
+ try {
56
+ await $ `which claude`.quiet();
57
+ }
58
+ catch {
59
+ return {
60
+ success: false,
61
+ message: 'claude CLI not found. Install Claude Code first.',
62
+ };
63
+ }
64
+ // Some other error
65
+ const msg = error instanceof Error ? error.message : String(error);
66
+ return {
67
+ success: false,
68
+ message: `failed: ${msg}`,
69
+ };
70
+ }
71
+ }
72
+ /**
73
+ * Check if hivemind MCP server is registered
74
+ */
75
+ export async function isMcpRegistered() {
76
+ try {
77
+ const result = await $ `claude mcp list 2>/dev/null`.text();
78
+ return result.includes('hivemind');
79
+ }
80
+ catch {
81
+ return false;
82
+ }
83
+ }
84
+ /**
85
+ * Configure auto-approve permissions for hivemind tools
86
+ * Adds structured tools to ~/.claude/settings.json permissions.allow
87
+ */
88
+ export function configurePermissions() {
89
+ const claudeDir = join(homedir(), '.claude');
90
+ const settingsPath = join(claudeDir, 'settings.json');
91
+ // Ensure ~/.claude exists
92
+ if (!existsSync(claudeDir)) {
93
+ mkdirSync(claudeDir, { recursive: true });
94
+ }
95
+ // Load existing settings
96
+ let settings = {};
97
+ if (existsSync(settingsPath)) {
98
+ try {
99
+ settings = JSON.parse(readFileSync(settingsPath, 'utf-8'));
100
+ }
101
+ catch {
102
+ // Invalid JSON, start fresh
103
+ }
104
+ }
105
+ // Ensure permissions.allow exists
106
+ if (!settings.permissions) {
107
+ settings.permissions = {};
108
+ }
109
+ const permissions = settings.permissions;
110
+ if (!Array.isArray(permissions.allow)) {
111
+ permissions.allow = [];
112
+ }
113
+ const allowList = permissions.allow;
114
+ // Track what we add
115
+ const added = [];
116
+ const alreadyPresent = [];
117
+ for (const tool of AUTO_APPROVED_TOOLS) {
118
+ if (allowList.includes(tool)) {
119
+ alreadyPresent.push(tool);
120
+ }
121
+ else {
122
+ allowList.push(tool);
123
+ added.push(tool);
124
+ }
125
+ }
126
+ // Write back if we added anything
127
+ if (added.length > 0) {
128
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
129
+ }
130
+ return {
131
+ success: true,
132
+ message: added.length > 0
133
+ ? `added ${added.length} permission rules`
134
+ : 'permissions already configured',
135
+ added,
136
+ alreadyPresent,
137
+ };
138
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * hivemind status - Show hivemind status for a project
3
+ */
4
+ type StatusOptions = {
5
+ project?: string;
6
+ };
7
+ export declare function statusCommand(options: StatusOptions): Promise<void>;
8
+ export {};
@@ -0,0 +1,82 @@
1
+ /**
2
+ * hivemind status - Show hivemind status for a project
3
+ */
4
+ import { existsSync } from 'fs';
5
+ import { getGitInfo } from '../git/getGitInfo';
6
+ import { getProjectPaths } from '../db/getProjectPaths';
7
+ import { getConnection } from '../db/getConnection';
8
+ import { getActiveAgents } from '../agents/getActiveAgents';
9
+ import { getActivePlans } from '../plans/getActivePlans';
10
+ import { getRecentEvents } from '../events/getRecentEvents';
11
+ import { isMcpRegistered } from './registerMcp';
12
+ import { formatDatetime } from '../datetime/formatDatetime';
13
+ export async function statusCommand(options) {
14
+ // Determine project
15
+ const gitInfo = getGitInfo();
16
+ let projectName = options.project;
17
+ if (!projectName) {
18
+ if (gitInfo.isRepo && gitInfo.repoName) {
19
+ projectName = gitInfo.repoName;
20
+ }
21
+ else {
22
+ projectName = process.cwd().split('/').pop() || 'default';
23
+ }
24
+ }
25
+ console.log(`hivemind status: ${projectName}\n`);
26
+ // Check if database exists
27
+ const paths = getProjectPaths(projectName);
28
+ if (!existsSync(paths.dbPath)) {
29
+ console.log(' not initialized');
30
+ console.log(' run: hivemind init');
31
+ return;
32
+ }
33
+ // Database stats
34
+ const db = getConnection(projectName);
35
+ const agentCount = db.prepare('SELECT COUNT(*) as c FROM agents').get().c;
36
+ const planCount = db.prepare('SELECT COUNT(*) as c FROM plans').get().c;
37
+ const eventCount = db.prepare('SELECT COUNT(*) as c FROM events').get().c;
38
+ console.log('Database');
39
+ console.log(` path: ${paths.dbPath}`);
40
+ console.log(` agents: ${agentCount}, plans: ${planCount}, events: ${eventCount}`);
41
+ // Active agents
42
+ const activeAgents = getActiveAgents(db);
43
+ console.log('\nActive Agents');
44
+ if (activeAgents.length === 0) {
45
+ console.log(' none');
46
+ }
47
+ else {
48
+ for (const agent of activeAgents) {
49
+ const context = agent.context_summary ? ` - ${agent.context_summary}` : '';
50
+ console.log(` ${agent.id}${context}`);
51
+ }
52
+ }
53
+ // Active plans
54
+ const activePlans = getActivePlans(db);
55
+ console.log('\nActive Plans');
56
+ if (activePlans.length === 0) {
57
+ console.log(' none');
58
+ }
59
+ else {
60
+ for (const plan of activePlans) {
61
+ console.log(` ${plan.id}: ${plan.title}`);
62
+ }
63
+ }
64
+ // Recent events
65
+ const recentEvents = getRecentEvents(db, 5);
66
+ console.log('\nRecent Events');
67
+ if (recentEvents.length === 0) {
68
+ console.log(' none');
69
+ }
70
+ else {
71
+ for (const event of recentEvents) {
72
+ const time = formatDatetime(new Date(event.timestamp));
73
+ const content = event.content?.slice(0, 50) || '';
74
+ console.log(` [${time}] ${event.event_type}: ${content}`);
75
+ }
76
+ }
77
+ db.close();
78
+ // MCP status
79
+ console.log('\nMCP Server');
80
+ const mcpRegistered = await isMcpRegistered();
81
+ console.log(` registered: ${mcpRegistered ? 'yes' : 'no'}`);
82
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * hivemind watch - Live tail of events
3
+ */
4
+ export declare function watchCommand(options: {
5
+ project?: string;
6
+ }): Promise<void>;
@@ -0,0 +1,68 @@
1
+ /**
2
+ * hivemind watch - Live tail of events
3
+ */
4
+ import { getConnection } from '../db/getConnection';
5
+ import { getRecentEvents } from '../events/getRecentEvents';
6
+ import { getGitInfo } from '../git/getGitInfo';
7
+ const EVENT_ICONS = {
8
+ 'task:claim': '🎯',
9
+ 'task:start': '▶️',
10
+ 'task:complete': '✅',
11
+ 'task:block': '🚫',
12
+ 'decision': '💡',
13
+ 'question': '❓',
14
+ 'answer': '💬',
15
+ 'note': '📝',
16
+ 'context': '📋',
17
+ 'agent:register': '👋',
18
+ 'agent:unregister': '👋',
19
+ 'plan:create': '📊',
20
+ 'plan:sync': '🔄',
21
+ };
22
+ function formatEvent(event) {
23
+ const icon = EVENT_ICONS[event.event_type] || '•';
24
+ const time = event.timestamp.split(' ')[1]; // Just the time part
25
+ const agent = event.agent_id?.replace('agt_', '') || 'system';
26
+ const content = event.content ? ` ${event.content}` : '';
27
+ return `${icon} [${time}] ${agent} ${event.event_type}${content}`;
28
+ }
29
+ export async function watchCommand(options) {
30
+ let project = options.project;
31
+ if (!project) {
32
+ const gitInfo = getGitInfo();
33
+ if (!gitInfo.isRepo || !gitInfo.repoName) {
34
+ console.error('Not in a git repository. Use --project <name>');
35
+ process.exit(1);
36
+ }
37
+ project = gitInfo.repoName;
38
+ }
39
+ const db = getConnection(project);
40
+ let lastSeq = 0;
41
+ // Get initial last seq
42
+ const initial = getRecentEvents(db, 1);
43
+ if (initial.length > 0) {
44
+ lastSeq = initial[0].seq;
45
+ }
46
+ console.log(`👁️ Watching hivemind events for: ${project}`);
47
+ console.log(` Press Ctrl+C to stop\n`);
48
+ // Poll loop
49
+ const POLL_INTERVAL = 1000; // 1 second
50
+ while (true) {
51
+ try {
52
+ const stmt = db.prepare(`
53
+ SELECT * FROM events
54
+ WHERE seq > ?
55
+ ORDER BY seq ASC
56
+ `);
57
+ const newEvents = stmt.all(lastSeq);
58
+ for (const event of newEvents) {
59
+ console.log(formatEvent(event));
60
+ lastSeq = event.seq;
61
+ }
62
+ }
63
+ catch {
64
+ // DB might be locked, just retry
65
+ }
66
+ await Bun.sleep(POLL_INTERVAL);
67
+ }
68
+ }
package/dist/cli.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * Hivemind CLI
4
+ *
5
+ * Usage:
6
+ * bun run src/cli.ts install # One-time global setup
7
+ * bun run src/cli.ts init # Register current project
8
+ * bun run src/cli.ts status # Show project status
9
+ * bun run src/cli.ts join # Join as an agent
10
+ * bun run src/cli.ts watch # Live tail of events
11
+ */
12
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * Hivemind CLI
4
+ *
5
+ * Usage:
6
+ * bun run src/cli.ts install # One-time global setup
7
+ * bun run src/cli.ts init # Register current project
8
+ * bun run src/cli.ts status # Show project status
9
+ * bun run src/cli.ts join # Join as an agent
10
+ * bun run src/cli.ts watch # Live tail of events
11
+ */
12
+ import { Command } from 'commander';
13
+ import { installCommand } from './cli/install';
14
+ import { initCommand } from './cli/init';
15
+ import { statusCommand } from './cli/status';
16
+ import { joinCommand } from './cli/join';
17
+ import { watchCommand } from './cli/watch';
18
+ const program = new Command();
19
+ program
20
+ .name('hivemind')
21
+ .description('Multi-agent coordination system for Claude Code')
22
+ .version('0.1.0');
23
+ program
24
+ .command('install')
25
+ .description('One-time setup: install dependencies and register MCP server')
26
+ .action(installCommand);
27
+ program
28
+ .command('init')
29
+ .description('Register current project with hivemind')
30
+ .option('-p, --project <name>', 'Project name (defaults to git repo name)')
31
+ .option('--no-hooks', 'Skip session hook setup')
32
+ .action(initCommand);
33
+ program
34
+ .command('status')
35
+ .description('Show hivemind status for the current project')
36
+ .option('-p, --project <name>', 'Project name')
37
+ .action(statusCommand);
38
+ program
39
+ .command('join')
40
+ .description('Join the hivemind as an agent')
41
+ .option('-l, --label <label>', 'Agent label')
42
+ .option('-c, --context <summary>', 'Context summary')
43
+ .action(joinCommand);
44
+ program
45
+ .command('watch')
46
+ .description('Live tail of hivemind events')
47
+ .option('-p, --project <name>', 'Project name')
48
+ .action(watchCommand);
49
+ program.parse();
@@ -0,0 +1 @@
1
+ export {};