@hivemindai/mcp-server 0.5.1 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/config.test.js +1 -1
- package/dist/__tests__/config.test.js 2.map +1 -0
- package/dist/__tests__/config.test.js.map +1 -1
- package/dist/__tests__/credentials.test 2.js +126 -0
- package/dist/__tests__/credentials.test.d.ts 2.map +1 -0
- package/dist/__tests__/credentials.test.js +5 -5
- package/dist/__tests__/credentials.test.js.map +1 -1
- package/dist/__tests__/editor-config.test.d 2.ts +2 -0
- package/dist/__tests__/editor-config.test.js 2.map +1 -0
- package/dist/__tests__/format.test.d.ts 2.map +1 -0
- package/dist/__tests__/format.test.js 2.map +1 -0
- package/dist/__tests__/helpers/mock-server 2.js +107 -0
- package/dist/__tests__/helpers/mock-server.d 2.ts +79 -0
- package/dist/__tests__/helpers/mock-server.d.ts +79 -0
- package/dist/__tests__/helpers/mock-server.d.ts 2.map +1 -0
- package/dist/__tests__/helpers/mock-server.d.ts.map +1 -0
- package/dist/__tests__/helpers/mock-server.js +107 -0
- package/dist/__tests__/helpers/mock-server.js 2.map +1 -0
- package/dist/__tests__/helpers/mock-server.js.map +1 -0
- package/dist/__tests__/remember.test 2.js +152 -0
- package/dist/__tests__/remember.test.d.ts +2 -0
- package/dist/__tests__/remember.test.d.ts.map +1 -0
- package/dist/__tests__/remember.test.js +152 -0
- package/dist/__tests__/remember.test.js.map +1 -0
- package/dist/__tests__/tools-approvals.test.d.ts +2 -0
- package/dist/__tests__/tools-approvals.test.d.ts.map +1 -0
- package/dist/__tests__/tools-approvals.test.js +219 -0
- package/dist/__tests__/tools-approvals.test.js.map +1 -0
- package/dist/__tests__/tools-context.test 2.js +107 -0
- package/dist/__tests__/tools-context.test.d.ts +2 -0
- package/dist/__tests__/tools-context.test.d.ts.map +1 -0
- package/dist/__tests__/tools-context.test.js +107 -0
- package/dist/__tests__/tools-context.test.js 2.map +1 -0
- package/dist/__tests__/tools-context.test.js.map +1 -0
- package/dist/__tests__/tools-handoffs.test.d.ts +2 -0
- package/dist/__tests__/tools-handoffs.test.d.ts.map +1 -0
- package/dist/__tests__/tools-handoffs.test.js +153 -0
- package/dist/__tests__/tools-handoffs.test.js.map +1 -0
- package/dist/__tests__/tools-knowledge.test.d 2.ts +2 -0
- package/dist/__tests__/tools-knowledge.test.d.ts +2 -0
- package/dist/__tests__/tools-knowledge.test.d.ts 2.map +1 -0
- package/dist/__tests__/tools-knowledge.test.d.ts.map +1 -0
- package/dist/__tests__/tools-knowledge.test.js +169 -0
- package/dist/__tests__/tools-knowledge.test.js.map +1 -0
- package/dist/__tests__/tools-plans.test.d 2.ts +2 -0
- package/dist/__tests__/tools-plans.test.d.ts +2 -0
- package/dist/__tests__/tools-plans.test.d.ts.map +1 -0
- package/dist/__tests__/tools-plans.test.js +307 -0
- package/dist/__tests__/tools-plans.test.js 2.map +1 -0
- package/dist/__tests__/tools-plans.test.js.map +1 -0
- package/dist/__tests__/tools-schedules.test.d.ts +2 -0
- package/dist/__tests__/tools-schedules.test.d.ts.map +1 -0
- package/dist/__tests__/tools-schedules.test.js +153 -0
- package/dist/__tests__/tools-schedules.test.js 2.map +1 -0
- package/dist/__tests__/tools-schedules.test.js.map +1 -0
- package/dist/__tests__/tools-skills.test.d 2.ts +2 -0
- package/dist/__tests__/tools-skills.test.d.ts +2 -0
- package/dist/__tests__/tools-skills.test.d.ts 2.map +1 -0
- package/dist/__tests__/tools-skills.test.d.ts.map +1 -0
- package/dist/__tests__/tools-skills.test.js +187 -0
- package/dist/__tests__/tools-skills.test.js 2.map +1 -0
- package/dist/__tests__/tools-skills.test.js.map +1 -0
- package/dist/__tests__/tools-tasks.test 2.js +83 -0
- package/dist/__tests__/tools-tasks.test.d 2.ts +2 -0
- package/dist/__tests__/tools-tasks.test.d.ts +2 -0
- package/dist/__tests__/tools-tasks.test.d.ts.map +1 -0
- package/dist/__tests__/tools-tasks.test.js +83 -0
- package/dist/__tests__/tools-tasks.test.js.map +1 -0
- package/dist/__tests__/tools-triggers.test.d 2.ts +2 -0
- package/dist/__tests__/tools-triggers.test.d.ts +2 -0
- package/dist/__tests__/tools-triggers.test.d.ts.map +1 -0
- package/dist/__tests__/tools-triggers.test.js +119 -0
- package/dist/__tests__/tools-triggers.test.js.map +1 -0
- package/dist/__tests__/tools-workflows.test.d.ts +2 -0
- package/dist/__tests__/tools-workflows.test.d.ts 2.map +1 -0
- package/dist/__tests__/tools-workflows.test.d.ts.map +1 -0
- package/dist/__tests__/tools-workflows.test.js +203 -0
- package/dist/__tests__/tools-workflows.test.js.map +1 -0
- package/dist/__tests__/tools.test.d.ts 2.map +1 -0
- package/dist/__tests__/tools.test.js +2 -2
- package/dist/__tests__/tools.test.js.map +1 -1
- package/dist/cli/commands/context-inject 2.js +112 -0
- package/dist/cli/commands/context-inject.d 2.ts +2 -0
- package/dist/cli/commands/context-inject.d.ts 2.map +1 -0
- package/dist/cli/commands/context-inject.js 2.map +1 -0
- package/dist/cli/commands/doc 2.js +144 -0
- package/dist/cli/commands/doc.d.ts 2.map +1 -0
- package/dist/cli/commands/doc.js 2.map +1 -0
- package/dist/cli/commands/git-hook 2.js +79 -0
- package/dist/cli/commands/git-hook.d 2.ts +2 -0
- package/dist/cli/commands/git-hook.d 3.ts +2 -0
- package/dist/cli/commands/git-hook.js 2.map +1 -0
- package/dist/cli/commands/guard 2.js +122 -0
- package/dist/cli/commands/guard.d.ts 2.map +1 -0
- package/dist/cli/commands/init 2.js +227 -0
- package/dist/cli/commands/init.d 2.ts +2 -0
- package/dist/cli/commands/init.d.ts 2.map +1 -0
- package/dist/cli/commands/init.js 2.map +1 -0
- package/dist/cli/commands/login 2.js +120 -0
- package/dist/cli/commands/login.d 2.ts +2 -0
- package/dist/cli/commands/login.d.ts 2.map +1 -0
- package/dist/cli/commands/login.d.ts 3.map +1 -0
- package/dist/cli/commands/login.js +1 -1
- package/dist/cli/commands/login.js.map +1 -1
- package/dist/cli/commands/logout 2.js +21 -0
- package/dist/cli/commands/logout.js 2.map +1 -0
- package/dist/cli/commands/logout.js 3.map +1 -0
- package/dist/cli/commands/release.d 2.ts +2 -0
- package/dist/cli/commands/release.d 3.ts +2 -0
- package/dist/cli/commands/release.d.ts 2.map +1 -0
- package/dist/cli/commands/release.js 2.map +1 -0
- package/dist/cli/commands/skill 2.js +185 -0
- package/dist/cli/commands/skill-inject 2.js +194 -0
- package/dist/cli/commands/skill-inject.d 2.ts +2 -0
- package/dist/cli/commands/skill-inject.d.ts 2.map +1 -0
- package/dist/cli/commands/skill-inject.d.ts.map +1 -1
- package/dist/cli/commands/skill-inject.js +23 -4
- package/dist/cli/commands/skill-inject.js 2.map +1 -0
- package/dist/cli/commands/skill-inject.js.map +1 -1
- package/dist/cli/commands/skill.d 2.ts +2 -0
- package/dist/cli/commands/status 2.js +45 -0
- package/dist/cli/commands/status.d.ts 2.map +1 -0
- package/dist/cli/commands/status.d.ts 3.map +1 -0
- package/dist/cli/commands/status.js 2.map +1 -0
- package/dist/cli/commands/switch 2.js +88 -0
- package/dist/cli/commands/switch 3.js +88 -0
- package/dist/cli/commands/switch.js 2.map +1 -0
- package/dist/cli/commands/whoami.d 2.ts +2 -0
- package/dist/cli/commands/whoami.d 3.ts +2 -0
- package/dist/cli/commands/whoami.d.ts 2.map +1 -0
- package/dist/cli/commands/whoami.js 2.map +1 -0
- package/dist/cli/commands/whoami.js 3.map +1 -0
- package/dist/cli/credentials.js +1 -1
- package/dist/cli/credentials.js 2.map +1 -0
- package/dist/cli/credentials.js.map +1 -1
- package/dist/cli/editor-config 2.js +109 -0
- package/dist/cli/editor-config.d 2.ts +9 -0
- package/dist/cli/editor-config.d.ts 2.map +1 -0
- package/dist/cli/editor-config.js 2.map +1 -0
- package/dist/cli/index 2.d 2.ts +2 -0
- package/dist/cli/index 2.d.ts +2 -0
- package/dist/cli/index 2.d.ts 2.map +1 -0
- package/dist/cli/index 2.d.ts.map +1 -0
- package/dist/cli/index 2.js +63 -0
- package/dist/cli/index 2.js 2.map +1 -0
- package/dist/cli/index 2.js.map +1 -0
- package/dist/cli/index 3.js +63 -0
- package/dist/cli/index 4.js +68 -0
- package/dist/cli/index.js 2.map +1 -0
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/tools/approvals.d.ts 2.map +1 -0
- package/dist/tools/blockers 2.js +24 -0
- package/dist/tools/blockers.d 2.ts +21 -0
- package/dist/tools/blockers.d.ts 2.map +1 -0
- package/dist/tools/handoffs.d.ts 2.map +1 -0
- package/dist/tools/knowledge.d.ts 2.map +1 -0
- package/dist/tools/knowledge.d.ts.map +1 -1
- package/dist/tools/knowledge.js +26 -3
- package/dist/tools/knowledge.js 2.map +1 -0
- package/dist/tools/knowledge.js 3.map +1 -0
- package/dist/tools/knowledge.js.map +1 -1
- package/dist/tools/lock.d 2.ts +24 -0
- package/dist/tools/lock.d.ts 2.map +1 -0
- package/dist/tools/lock.js 2.map +1 -0
- package/dist/tools/plans.d 2.ts +5 -0
- package/dist/tools/plans.d.ts +5 -0
- package/dist/tools/plans.d.ts.map +1 -0
- package/dist/tools/plans.js +359 -0
- package/dist/tools/plans.js.map +1 -0
- package/dist/tools/publish.d 2.ts +24 -0
- package/dist/tools/publish.d.ts 2.map +1 -0
- package/dist/tools/query 2.js +41 -0
- package/dist/tools/query.d 2.ts +27 -0
- package/dist/tools/query.js 2.map +1 -0
- package/dist/tools/remember.js 2.map +1 -0
- package/dist/tools/skills 2.js +273 -0
- package/dist/tools/skills.js 2.map +1 -0
- package/dist/tools/status.d.ts 2.map +1 -0
- package/dist/tools/status.js 2.map +1 -0
- package/dist/tools/subscribe.js 2.map +1 -0
- package/dist/tools/tasks 2.js +51 -0
- package/dist/tools/teams.d 2.ts +4 -0
- package/dist/tools/teams.js 2.map +1 -0
- package/dist/tools/triggers 2.js +212 -0
- package/dist/tools/triggers.d 2.ts +5 -0
- package/dist/tools/triggers.d.ts 2.map +1 -0
- package/dist/tools/triggers.d.ts 3.map +1 -0
- package/dist/tools/workflows.d.ts 2.map +1 -0
- package/package.json +11 -11
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { HivemindClient } from "@hivemindai/sdk-ts";
|
|
3
|
+
import { readCredentials } from "../credentials.js";
|
|
4
|
+
export async function doc(args) {
|
|
5
|
+
const creds = readCredentials();
|
|
6
|
+
if (!creds) {
|
|
7
|
+
console.log("Not logged in. Run `hivemind login` to authenticate.");
|
|
8
|
+
process.exit(1);
|
|
9
|
+
}
|
|
10
|
+
const client = new HivemindClient({
|
|
11
|
+
apiKey: creds.api_key,
|
|
12
|
+
baseUrl: creds.api_url,
|
|
13
|
+
});
|
|
14
|
+
const subcommand = args[0];
|
|
15
|
+
if (!subcommand || subcommand === "--help") {
|
|
16
|
+
console.log(`
|
|
17
|
+
Usage: hivemind doc <subcommand>
|
|
18
|
+
|
|
19
|
+
Subcommands:
|
|
20
|
+
add <title> --content "..." | --file <path> Add a knowledge doc
|
|
21
|
+
list List all docs
|
|
22
|
+
search <query> Semantic search
|
|
23
|
+
get <doc_id> Get a specific doc
|
|
24
|
+
update <doc_id> [--title "..."] [--content "..."] [--file <path>]
|
|
25
|
+
delete <doc_id> Delete a doc
|
|
26
|
+
`.trim());
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
if (subcommand === "add") {
|
|
31
|
+
const title = args[1];
|
|
32
|
+
if (!title) {
|
|
33
|
+
console.error("Usage: hivemind doc add <title> --content \"...\" | --file <path>");
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
let content = getFlag(args, "--content");
|
|
37
|
+
const filePath = getFlag(args, "--file");
|
|
38
|
+
if (filePath) {
|
|
39
|
+
content = readFileSync(filePath, "utf-8");
|
|
40
|
+
}
|
|
41
|
+
if (!content) {
|
|
42
|
+
console.error("Provide content via --content or --file");
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
const tags = getFlag(args, "--tags")?.split(",").map((t) => t.trim());
|
|
46
|
+
const result = await client.addKnowledgeDoc({ title, content, tags });
|
|
47
|
+
console.log(`Document created: ${result.id}`);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (subcommand === "list") {
|
|
51
|
+
const result = await client.listKnowledgeDocs();
|
|
52
|
+
if (result.docs.length === 0) {
|
|
53
|
+
console.log("No knowledge documents found.");
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
console.log(`Knowledge Base (${result.total} docs)\n`);
|
|
57
|
+
for (const d of result.docs) {
|
|
58
|
+
const tags = d.tags?.length ? ` [${d.tags.join(", ")}]` : "";
|
|
59
|
+
console.log(` ${d.id} ${d.title}${tags}`);
|
|
60
|
+
}
|
|
61
|
+
if (result.has_more) {
|
|
62
|
+
console.log("\n (more docs available)");
|
|
63
|
+
}
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (subcommand === "search") {
|
|
67
|
+
const query = args[1];
|
|
68
|
+
if (!query) {
|
|
69
|
+
console.error("Usage: hivemind doc search <query>");
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
const result = await client.searchKnowledge(query);
|
|
73
|
+
if (result.docs.length === 0) {
|
|
74
|
+
console.log("No matching documents found.");
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
console.log(`Search Results (${result.total})\n`);
|
|
78
|
+
for (const d of result.docs) {
|
|
79
|
+
const score = d._score !== undefined ? ` (${(d._score * 100).toFixed(0)}%)` : "";
|
|
80
|
+
console.log(` ${d.id} ${d.title}${score}`);
|
|
81
|
+
}
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (subcommand === "get") {
|
|
85
|
+
const docId = args[1];
|
|
86
|
+
if (!docId) {
|
|
87
|
+
console.error("Usage: hivemind doc get <doc_id>");
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
const result = await client.getKnowledgeDoc(docId);
|
|
91
|
+
const d = result.doc;
|
|
92
|
+
const tags = d.tags?.length ? `\nTags: ${d.tags.join(", ")}` : "";
|
|
93
|
+
console.log(`${d.title}\nID: ${d.id}${tags}\nUpdated: ${d.updated_at}\n\n${d.content}`);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (subcommand === "update") {
|
|
97
|
+
const docId = args[1];
|
|
98
|
+
if (!docId) {
|
|
99
|
+
console.error("Usage: hivemind doc update <doc_id> [--title ...] [--content ...] [--file ...]");
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
const updateParams = {};
|
|
103
|
+
const title = getFlag(args, "--title");
|
|
104
|
+
if (title)
|
|
105
|
+
updateParams.title = title;
|
|
106
|
+
let content = getFlag(args, "--content");
|
|
107
|
+
const filePath = getFlag(args, "--file");
|
|
108
|
+
if (filePath)
|
|
109
|
+
content = readFileSync(filePath, "utf-8");
|
|
110
|
+
if (content)
|
|
111
|
+
updateParams.content = content;
|
|
112
|
+
const tagsStr = getFlag(args, "--tags");
|
|
113
|
+
if (tagsStr)
|
|
114
|
+
updateParams.tags = tagsStr.split(",").map((t) => t.trim());
|
|
115
|
+
const result = await client.updateKnowledgeDoc(docId, updateParams);
|
|
116
|
+
console.log(result.updated ? `Document ${docId} updated.` : `Document ${docId} not found.`);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (subcommand === "delete") {
|
|
120
|
+
const docId = args[1];
|
|
121
|
+
if (!docId) {
|
|
122
|
+
console.error("Usage: hivemind doc delete <doc_id>");
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
125
|
+
const result = await client.deleteKnowledgeDoc(docId);
|
|
126
|
+
console.log(result.deleted ? `Document ${docId} deleted.` : `Document ${docId} not found.`);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
console.error(`Unknown subcommand: ${subcommand}`);
|
|
130
|
+
console.error('Run "hivemind doc --help" for usage.');
|
|
131
|
+
process.exit(1);
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
console.error(`Failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function getFlag(args, flag) {
|
|
139
|
+
const idx = args.indexOf(flag);
|
|
140
|
+
if (idx === -1 || idx + 1 >= args.length)
|
|
141
|
+
return undefined;
|
|
142
|
+
return args[idx + 1];
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=doc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doc.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/doc.ts"],"names":[],"mappings":"AAIA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAgJvD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doc.js","sourceRoot":"","sources":["../../../src/cli/commands/doc.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
function loadCredentials() {
|
|
5
|
+
const credPath = join(process.env.HOME ?? process.env.USERPROFILE ?? ".", ".hivemind", "credentials.json");
|
|
6
|
+
if (!existsSync(credPath))
|
|
7
|
+
return null;
|
|
8
|
+
try {
|
|
9
|
+
const creds = JSON.parse(readFileSync(credPath, "utf-8"));
|
|
10
|
+
return { api_key: creds.api_key, api_url: creds.api_url };
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function git(cmd) {
|
|
17
|
+
try {
|
|
18
|
+
return execSync(`git ${cmd}`, { encoding: "utf-8", timeout: 5000 }).trim();
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return "";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async function postCommit() {
|
|
25
|
+
const creds = loadCredentials();
|
|
26
|
+
if (!creds)
|
|
27
|
+
return; // No credentials — skip silently
|
|
28
|
+
const message = git("log -1 --pretty=%B");
|
|
29
|
+
const hash = git("log -1 --pretty=%H");
|
|
30
|
+
const shortHash = git("log -1 --pretty=%h");
|
|
31
|
+
const author = git("log -1 --pretty=%an");
|
|
32
|
+
const filesRaw = git("diff-tree --no-commit-id --name-only -r HEAD");
|
|
33
|
+
const files = filesRaw.split("\n").filter(Boolean);
|
|
34
|
+
const diffStat = git("diff-tree --no-commit-id --stat -r HEAD");
|
|
35
|
+
if (!message || files.length === 0)
|
|
36
|
+
return;
|
|
37
|
+
const description = `Committed: ${message.split("\n")[0]}`;
|
|
38
|
+
const data = {
|
|
39
|
+
channel: "general",
|
|
40
|
+
event_type: "task.completed",
|
|
41
|
+
source: "git-hook",
|
|
42
|
+
data: {
|
|
43
|
+
description,
|
|
44
|
+
commit_hash: hash,
|
|
45
|
+
commit_short: shortHash,
|
|
46
|
+
commit_message: message,
|
|
47
|
+
author,
|
|
48
|
+
files_changed: files,
|
|
49
|
+
diff_stat: diffStat,
|
|
50
|
+
auto_instrumented: true,
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
try {
|
|
54
|
+
await fetch(`${creds.api_url}/v1/events`, {
|
|
55
|
+
method: "POST",
|
|
56
|
+
headers: {
|
|
57
|
+
Authorization: `Bearer ${creds.api_key}`,
|
|
58
|
+
"Content-Type": "application/json",
|
|
59
|
+
},
|
|
60
|
+
body: JSON.stringify(data),
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// Don't block git operations on network errors
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
export async function gitHook(args = []) {
|
|
68
|
+
const hookType = args[0];
|
|
69
|
+
switch (hookType) {
|
|
70
|
+
case "post-commit":
|
|
71
|
+
await postCommit();
|
|
72
|
+
break;
|
|
73
|
+
default:
|
|
74
|
+
console.error(`Unknown git hook type: ${hookType}`);
|
|
75
|
+
console.error("Supported: post-commit");
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=git-hook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-hook.js","sourceRoot":"","sources":["../../../src/cli/commands/git-hook.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
function loadCredentials() {
|
|
4
|
+
const credPath = join(process.env.HOME ?? process.env.USERPROFILE ?? ".", ".hivemind", "credentials.json");
|
|
5
|
+
if (!existsSync(credPath))
|
|
6
|
+
return null;
|
|
7
|
+
try {
|
|
8
|
+
const creds = JSON.parse(readFileSync(credPath, "utf-8"));
|
|
9
|
+
return { api_key: creds.api_key, api_url: creds.api_url };
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function getAgentName(input) {
|
|
16
|
+
return process.env.HIVEMIND_AGENT ?? (input.session_id ? `claude-${input.session_id}` : `claude-${process.ppid}`);
|
|
17
|
+
}
|
|
18
|
+
export async function guard(args = []) {
|
|
19
|
+
const policiesOnly = args.includes("--policies-only");
|
|
20
|
+
// Read hook input from stdin
|
|
21
|
+
let input;
|
|
22
|
+
try {
|
|
23
|
+
const raw = readFileSync(0, "utf-8");
|
|
24
|
+
input = JSON.parse(raw);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
process.exit(0);
|
|
28
|
+
}
|
|
29
|
+
const filePath = input.tool_input?.file_path;
|
|
30
|
+
if (!filePath) {
|
|
31
|
+
process.exit(0);
|
|
32
|
+
}
|
|
33
|
+
const creds = loadCredentials();
|
|
34
|
+
if (!creds) {
|
|
35
|
+
process.exit(0);
|
|
36
|
+
}
|
|
37
|
+
const agent = getAgentName(input);
|
|
38
|
+
const headers = {
|
|
39
|
+
Authorization: `Bearer ${creds.api_key}`,
|
|
40
|
+
"Content-Type": "application/json",
|
|
41
|
+
};
|
|
42
|
+
// Make the file path relative to cwd for cleaner resource names
|
|
43
|
+
const cwd = input.cwd ?? process.cwd();
|
|
44
|
+
let resource = filePath;
|
|
45
|
+
if (resource.startsWith(cwd)) {
|
|
46
|
+
resource = resource.slice(cwd.length).replace(/^\//, "");
|
|
47
|
+
}
|
|
48
|
+
// 1. Check policies
|
|
49
|
+
try {
|
|
50
|
+
const policyRes = await fetch(`${creds.api_url}/v1/approvals/policies/check?resource=${encodeURIComponent(resource)}`, { headers });
|
|
51
|
+
if (policyRes.ok) {
|
|
52
|
+
const policyData = await policyRes.json();
|
|
53
|
+
if (policyData.requires_approval) {
|
|
54
|
+
const policies = policyData.matching_policies
|
|
55
|
+
.map((p) => ` - ${p.description} (pattern: ${p.resource_pattern})`)
|
|
56
|
+
.join("\n");
|
|
57
|
+
process.stderr.write(`BLOCKED: ${resource} requires approval.\n\nMatching policies:\n${policies}\n\n` +
|
|
58
|
+
`To proceed, request approval:\n` +
|
|
59
|
+
` hivemind_approvals(action: "request", channel: "general", description: "Need to edit ${resource}")\n` +
|
|
60
|
+
`Then wait for approval before retrying.\n`);
|
|
61
|
+
process.exit(2);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// Policy check failed — don't block on network errors
|
|
67
|
+
}
|
|
68
|
+
// 2. Non-blocking conflict check (informational only)
|
|
69
|
+
try {
|
|
70
|
+
const controller = new AbortController();
|
|
71
|
+
const timeout = setTimeout(() => controller.abort(), 3000);
|
|
72
|
+
const conflictRes = await fetch(`${creds.api_url}/v1/intelligence/conflicts/check?files=${encodeURIComponent(resource)}`, { headers, signal: controller.signal });
|
|
73
|
+
clearTimeout(timeout);
|
|
74
|
+
if (conflictRes.ok) {
|
|
75
|
+
const conflictData = await conflictRes.json();
|
|
76
|
+
if (conflictData.conflicts?.length > 0) {
|
|
77
|
+
for (const c of conflictData.conflicts) {
|
|
78
|
+
process.stderr.write(`WARNING: ${c.file} was recently modified by ${c.agent} ("${c.description}" at ${c.modified_at})\n` +
|
|
79
|
+
`Consider coordinating with the other agent before proceeding.\n\n`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// Conflict check is informational — don't block on errors
|
|
86
|
+
}
|
|
87
|
+
// 3. Acquire lock (skip if --policies-only)
|
|
88
|
+
if (!policiesOnly) {
|
|
89
|
+
try {
|
|
90
|
+
const lockRes = await fetch(`${creds.api_url}/v1/locks/${encodeURIComponent(resource)}`, {
|
|
91
|
+
method: "POST",
|
|
92
|
+
headers,
|
|
93
|
+
body: JSON.stringify({ agent }),
|
|
94
|
+
});
|
|
95
|
+
if (lockRes.ok) {
|
|
96
|
+
const lockData = await lockRes.json();
|
|
97
|
+
if (lockData.locked) {
|
|
98
|
+
process.exit(0);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (lockRes.status === 409) {
|
|
102
|
+
const lockData = await lockRes.json();
|
|
103
|
+
const holder = lockData.held_by?.agent ?? "unknown";
|
|
104
|
+
if (holder === agent) {
|
|
105
|
+
process.exit(0);
|
|
106
|
+
}
|
|
107
|
+
process.stderr.write(`BLOCKED: ${resource} is locked by ${holder}.\n\n` +
|
|
108
|
+
`Another agent is editing this file. To override:\n` +
|
|
109
|
+
`1. hivemind_approvals(action: "request", channel: "general", description: "Need to edit ${resource}, locked by ${holder}")\n` +
|
|
110
|
+
`2. Wait for approval\n` +
|
|
111
|
+
`3. hivemind_lock(action: "acquire", resource: "${resource}", force_correlation_id: "<correlation_id>")\n`);
|
|
112
|
+
process.exit(2);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// Lock request failed — don't block on network errors
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Default: allow
|
|
120
|
+
process.exit(0);
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/guard.ts"],"names":[],"mappings":"AAiCA,wBAAsB,KAAK,CAAC,IAAI,GAAE,MAAM,EAAO,iBA+H9C"}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
const HIVEMIND_SECTION_START = "<!-- hivemind:start -->";
|
|
4
|
+
const HIVEMIND_SECTION_END = "<!-- hivemind:end -->";
|
|
5
|
+
function buildClaudeMd(mode) {
|
|
6
|
+
const rules = [];
|
|
7
|
+
// Rule 1 — always present
|
|
8
|
+
rules.push(`### Rule 1: Announce your task IMMEDIATELY
|
|
9
|
+
|
|
10
|
+
As your FIRST action when starting any task, BEFORE reading files or planning, call:
|
|
11
|
+
\`\`\`
|
|
12
|
+
hivemind_publish(channel: "general", event_type: "task.created", data: {"description": "<what you are about to do>"})
|
|
13
|
+
\`\`\`
|
|
14
|
+
Also call \`hivemind_status()\` to see what other agents are working on.`);
|
|
15
|
+
// Rule 2 — enforcement (varies by mode)
|
|
16
|
+
if (mode === "full") {
|
|
17
|
+
rules.push(`### Rule 2: Locks and policies are enforced automatically
|
|
18
|
+
|
|
19
|
+
File locks and approval policies are enforced by hooks. If your edit is blocked, you will see an error message explaining why and what to do. Follow those instructions.
|
|
20
|
+
|
|
21
|
+
If a lock blocks you: another agent is editing that file. Request approval to override, or work on a different file.
|
|
22
|
+
If a policy blocks you: the file requires human approval. Request approval and wait.`);
|
|
23
|
+
}
|
|
24
|
+
else if (mode === "no-locks") {
|
|
25
|
+
rules.push(`### Rule 2: Approval policies are enforced automatically
|
|
26
|
+
|
|
27
|
+
Approval policies are enforced by hooks. If your edit is blocked because a file requires approval, you will see an error message explaining why and what to do. Follow those instructions.`);
|
|
28
|
+
}
|
|
29
|
+
// events-only: no Rule 2
|
|
30
|
+
// Publish outcomes — always present
|
|
31
|
+
const ruleNum = mode === "events-only" ? 2 : 3;
|
|
32
|
+
rules.push(`### Rule ${ruleNum}: Publish outcomes
|
|
33
|
+
|
|
34
|
+
After completing work, publish what you did:
|
|
35
|
+
\`\`\`
|
|
36
|
+
hivemind_publish(channel: "general", event_type: "task.completed", data: {"description": "<what you did>", "files_changed": ["file1.ts", "file2.ts"]})
|
|
37
|
+
\`\`\`
|
|
38
|
+
Also publish \`decision.made\` when choosing between approaches, \`task.blocked\` when stuck, and \`bug.found\` when discovering bugs.
|
|
39
|
+
|
|
40
|
+
Do NOT publish routine activity (file reads, retries, lint fixes). Only publish outcomes and decisions.`);
|
|
41
|
+
// Skills note — always present
|
|
42
|
+
const skillRuleNum = ruleNum + 1;
|
|
43
|
+
rules.push(`### Rule ${skillRuleNum}: Skills are injected automatically
|
|
44
|
+
|
|
45
|
+
When you edit files, relevant project skills are automatically loaded into your context.
|
|
46
|
+
You can also search for skills explicitly: \`hivemind_skill(action: "search", query: "...")\``);
|
|
47
|
+
return `${HIVEMIND_SECTION_START}
|
|
48
|
+
## Hivemind — MANDATORY agent coordination
|
|
49
|
+
|
|
50
|
+
This project uses Hivemind for multi-agent coordination. You MUST follow ALL of these rules. They are not optional.
|
|
51
|
+
|
|
52
|
+
${rules.join("\n\n")}
|
|
53
|
+
${HIVEMIND_SECTION_END}`;
|
|
54
|
+
}
|
|
55
|
+
function buildHooksConfig(mode) {
|
|
56
|
+
const hooks = {};
|
|
57
|
+
// Skill injection runs in ALL modes (even events-only) — it never blocks
|
|
58
|
+
const skillInjectHook = {
|
|
59
|
+
matcher: "Edit|Write|Bash",
|
|
60
|
+
hooks: [{ type: "command", command: "hivemind skill-inject", timeout: 5 }],
|
|
61
|
+
};
|
|
62
|
+
if (mode === "full") {
|
|
63
|
+
hooks.PreToolUse = [
|
|
64
|
+
skillInjectHook,
|
|
65
|
+
{
|
|
66
|
+
matcher: "Edit|Write",
|
|
67
|
+
hooks: [{ type: "command", command: "hivemind guard", timeout: 10 }],
|
|
68
|
+
},
|
|
69
|
+
];
|
|
70
|
+
hooks.PostToolUse = [
|
|
71
|
+
{
|
|
72
|
+
matcher: "Edit|Write",
|
|
73
|
+
hooks: [{ type: "command", command: "hivemind release", timeout: 10 }],
|
|
74
|
+
},
|
|
75
|
+
];
|
|
76
|
+
}
|
|
77
|
+
else if (mode === "no-locks") {
|
|
78
|
+
hooks.PreToolUse = [
|
|
79
|
+
skillInjectHook,
|
|
80
|
+
{
|
|
81
|
+
matcher: "Edit|Write",
|
|
82
|
+
hooks: [{ type: "command", command: "hivemind guard --policies-only", timeout: 10 }],
|
|
83
|
+
},
|
|
84
|
+
];
|
|
85
|
+
// No PostToolUse — no locks to release
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
// events-only: skill injection only
|
|
89
|
+
hooks.PreToolUse = [skillInjectHook];
|
|
90
|
+
}
|
|
91
|
+
return hooks;
|
|
92
|
+
}
|
|
93
|
+
export async function init(args = []) {
|
|
94
|
+
const mode = args.includes("--events-only")
|
|
95
|
+
? "events-only"
|
|
96
|
+
: args.includes("--no-locks")
|
|
97
|
+
? "no-locks"
|
|
98
|
+
: "full";
|
|
99
|
+
const cwd = process.cwd();
|
|
100
|
+
const claudeMdPath = join(cwd, "CLAUDE.md");
|
|
101
|
+
console.log("Hivemind Init\n");
|
|
102
|
+
if (mode !== "full") {
|
|
103
|
+
console.log(` Mode: ${mode}\n`);
|
|
104
|
+
}
|
|
105
|
+
// --- 1. Update CLAUDE.md ---
|
|
106
|
+
const claudeMdContent = buildClaudeMd(mode);
|
|
107
|
+
if (existsSync(claudeMdPath)) {
|
|
108
|
+
const existing = readFileSync(claudeMdPath, "utf-8");
|
|
109
|
+
if (existing.includes(HIVEMIND_SECTION_START)) {
|
|
110
|
+
const before = existing.slice(0, existing.indexOf(HIVEMIND_SECTION_START));
|
|
111
|
+
const after = existing.slice(existing.indexOf(HIVEMIND_SECTION_END) + HIVEMIND_SECTION_END.length);
|
|
112
|
+
writeFileSync(claudeMdPath, before + claudeMdContent + after);
|
|
113
|
+
console.log(" Updated Hivemind section in CLAUDE.md");
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
writeFileSync(claudeMdPath, existing.trimEnd() + "\n\n" + claudeMdContent + "\n");
|
|
117
|
+
console.log(" Added Hivemind section to CLAUDE.md");
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
writeFileSync(claudeMdPath, `# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n${claudeMdContent}\n`);
|
|
122
|
+
console.log(" Created CLAUDE.md with Hivemind instructions");
|
|
123
|
+
}
|
|
124
|
+
// --- 2. Configure Claude Code hooks ---
|
|
125
|
+
const hooksConfig = buildHooksConfig(mode);
|
|
126
|
+
const claudeDir = join(cwd, ".claude");
|
|
127
|
+
const settingsPath = join(claudeDir, "settings.local.json");
|
|
128
|
+
mkdirSync(claudeDir, { recursive: true });
|
|
129
|
+
let settings = {};
|
|
130
|
+
if (existsSync(settingsPath)) {
|
|
131
|
+
try {
|
|
132
|
+
settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
// If parse fails, start fresh
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Filter out any existing hivemind hooks
|
|
139
|
+
const existingHooks = (settings.hooks ?? {});
|
|
140
|
+
const newHooks = { ...existingHooks };
|
|
141
|
+
for (const event of ["PreToolUse", "PostToolUse"]) {
|
|
142
|
+
const existing = (existingHooks[event] ?? []);
|
|
143
|
+
const filtered = existing.filter((h) => {
|
|
144
|
+
const cmds = h.hooks?.map((hh) => hh.command ?? "") ?? [];
|
|
145
|
+
return !cmds.some((c) => c.startsWith("hivemind "));
|
|
146
|
+
});
|
|
147
|
+
if (hooksConfig && hooksConfig[event]) {
|
|
148
|
+
newHooks[event] = [...filtered, ...hooksConfig[event]];
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
// No hivemind hooks for this event — keep only non-hivemind hooks
|
|
152
|
+
newHooks[event] = filtered.length > 0 ? filtered : [];
|
|
153
|
+
if (newHooks[event].length === 0) {
|
|
154
|
+
delete newHooks[event];
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
settings.hooks = Object.keys(newHooks).length > 0 ? newHooks : undefined;
|
|
159
|
+
if (!settings.hooks)
|
|
160
|
+
delete settings.hooks;
|
|
161
|
+
writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
162
|
+
console.log(" Configured Claude Code hooks in .claude/settings.local.json");
|
|
163
|
+
// --- 3. Install git post-commit hook ---
|
|
164
|
+
const gitDir = join(cwd, ".git");
|
|
165
|
+
if (existsSync(gitDir)) {
|
|
166
|
+
const hooksDir = join(gitDir, "hooks");
|
|
167
|
+
mkdirSync(hooksDir, { recursive: true });
|
|
168
|
+
const postCommitPath = join(hooksDir, "post-commit");
|
|
169
|
+
const hookScript = `#!/bin/sh
|
|
170
|
+
# Hivemind auto-instrumentation — publishes commit events
|
|
171
|
+
hivemind git-hook post-commit 2>/dev/null || true
|
|
172
|
+
`;
|
|
173
|
+
if (existsSync(postCommitPath)) {
|
|
174
|
+
const existing = readFileSync(postCommitPath, "utf-8");
|
|
175
|
+
if (existing.includes("hivemind git-hook")) {
|
|
176
|
+
console.log(" Git post-commit hook already installed");
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
// Append to existing hook
|
|
180
|
+
writeFileSync(postCommitPath, existing.trimEnd() + "\n\n" + hookScript);
|
|
181
|
+
console.log(" Appended Hivemind to existing git post-commit hook");
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
writeFileSync(postCommitPath, hookScript, { mode: 0o755 });
|
|
186
|
+
console.log(" Installed git post-commit hook (auto-publishes commit events)");
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
console.log(" No .git directory found — skipped git hook installation");
|
|
191
|
+
}
|
|
192
|
+
// --- 4. Summary ---
|
|
193
|
+
if (mode === "full") {
|
|
194
|
+
console.log(`
|
|
195
|
+
Done! Hivemind is now active in this project:
|
|
196
|
+
|
|
197
|
+
- CLAUDE.md: Agent instructions for publishing events
|
|
198
|
+
- Hooks: Auto-lock files before edit, auto-release after
|
|
199
|
+
- Hooks: Auto-check approval policies before edit
|
|
200
|
+
- Hooks: Auto-inject skills based on file patterns and tools
|
|
201
|
+
- Git hook: Auto-publishes commit events to Hivemind
|
|
202
|
+
|
|
203
|
+
Locks and policies are enforced automatically.
|
|
204
|
+
`);
|
|
205
|
+
}
|
|
206
|
+
else if (mode === "no-locks") {
|
|
207
|
+
console.log(`
|
|
208
|
+
Done! Hivemind is now active in this project:
|
|
209
|
+
|
|
210
|
+
- CLAUDE.md: Agent instructions for publishing events
|
|
211
|
+
- Hooks: Auto-check approval policies before edit
|
|
212
|
+
- Hooks: Auto-inject skills based on file patterns and tools
|
|
213
|
+
- Git hook: Auto-publishes commit events to Hivemind
|
|
214
|
+
- No file locking (use this when agents work on separate branches)
|
|
215
|
+
`);
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
console.log(`
|
|
219
|
+
Done! Hivemind is now active in this project:
|
|
220
|
+
|
|
221
|
+
- CLAUDE.md: Agent instructions for publishing events
|
|
222
|
+
- Hooks: Auto-inject skills based on file patterns and tools
|
|
223
|
+
- Git hook: Auto-publishes commit events to Hivemind
|
|
224
|
+
`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAyFA,wBAAsB,IAAI,CAAC,IAAI,GAAE,MAAM,EAAO,iBAoJ7C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"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"}
|