heedvane 0.2.0 → 0.3.3
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/README.md +20 -5
- package/dist/cli.d.ts +2 -1
- package/dist/cli.js +139 -55
- package/dist/clients/definitions.d.ts +1 -1
- package/dist/clients/definitions.js +24 -9
- package/dist/commands/memory.js +6 -1
- package/dist/doctor.js +25 -9
- package/dist/heed-file.d.ts +14 -1
- package/dist/heed-file.js +43 -20
- package/dist/installer.d.ts +9 -2
- package/dist/installer.js +30 -4
- package/dist/listener/serve.js +1 -1
- package/dist/listener/server.d.ts +2 -0
- package/dist/listener/server.js +23 -3
- package/dist/mcp.d.ts +21 -50
- package/dist/mcp.js +96 -65
- package/dist/plan.d.ts +15 -5
- package/dist/plan.js +53 -26
- package/dist/render.js +6 -7
- package/dist/reply/reply.js +2 -1
- package/dist/skill/content.d.ts +2 -2
- package/dist/skill/content.js +5 -5
- package/dist/status.d.ts +1 -0
- package/dist/status.js +29 -0
- package/dist/uninstall.d.ts +2 -0
- package/dist/uninstall.js +54 -31
- package/package.json +1 -1
- package/skills/heedvane-hooks/SKILL.md +3 -3
- package/skills/heedvane-hooks/references/events.md +2 -2
- package/dist/mcp-server.d.ts +0 -9
- package/dist/mcp-server.js +0 -187
package/dist/mcp-server.js
DELETED
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `npx heedvane mcp` — the MCP stdio server stub the installers register.
|
|
3
|
-
* v1 exposes two tools (status, doctor) over line-delimited JSON-RPC.
|
|
4
|
-
*/
|
|
5
|
-
import { createInterface } from "node:readline";
|
|
6
|
-
import { runDoctor } from "./doctor.js";
|
|
7
|
-
import { cmdMemory } from "./commands/memory.js";
|
|
8
|
-
const MCP_SERVER_INFO = { name: "heedvane-hooks", version: "0.1.0" };
|
|
9
|
-
const TOOLS = [
|
|
10
|
-
{
|
|
11
|
-
name: "heedvane_status",
|
|
12
|
-
description: "Report the live heedvane hook installation state for this machine (agents, skill, listener).",
|
|
13
|
-
inputSchema: { type: "object", properties: {} },
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
name: "heedvane_doctor",
|
|
17
|
-
description: "Run the scoped heedvane doctor and return its checks with remediations.",
|
|
18
|
-
inputSchema: {
|
|
19
|
-
type: "object",
|
|
20
|
-
properties: { clients: { type: "array", items: { type: "string" } } },
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
name: "heedvane_memory_list",
|
|
25
|
-
description: "List team memory folders and entries for the current repository.",
|
|
26
|
-
inputSchema: {
|
|
27
|
-
type: "object",
|
|
28
|
-
properties: {
|
|
29
|
-
folder: { type: "string", description: "Optional folder name to filter by." },
|
|
30
|
-
cwd: { type: "string", description: "Optional repository checkout path." },
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
name: "heedvane_memory_show",
|
|
36
|
-
description: "Read the full markdown content of a team memory entry by id.",
|
|
37
|
-
inputSchema: {
|
|
38
|
-
type: "object",
|
|
39
|
-
required: ["id"],
|
|
40
|
-
properties: {
|
|
41
|
-
id: { type: "string", description: "The team memory id." },
|
|
42
|
-
cwd: { type: "string", description: "Optional repository checkout path." },
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
name: "heedvane_memory_search",
|
|
48
|
-
description: "Semantically search team memory for the current repository.",
|
|
49
|
-
inputSchema: {
|
|
50
|
-
type: "object",
|
|
51
|
-
required: ["query"],
|
|
52
|
-
properties: {
|
|
53
|
-
query: { type: "string", description: "The question or search query." },
|
|
54
|
-
folder: { type: "string", description: "Optional folder name to restrict search." },
|
|
55
|
-
cwd: { type: "string", description: "Optional repository checkout path." },
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
},
|
|
59
|
-
];
|
|
60
|
-
/** Run a team memory command and return its collected lines. */
|
|
61
|
-
async function runMemoryTool(words, flags, cwd) {
|
|
62
|
-
const lines = [];
|
|
63
|
-
await cmdMemory({
|
|
64
|
-
home: process.env.HEED_HOME ?? homeDir(),
|
|
65
|
-
out: (line) => lines.push(line),
|
|
66
|
-
words,
|
|
67
|
-
flag: (name) => flags[name],
|
|
68
|
-
cwd: typeof cwd === "string" && cwd.trim() !== "" ? cwd : process.cwd(),
|
|
69
|
-
});
|
|
70
|
-
return lines.join("\n");
|
|
71
|
-
}
|
|
72
|
-
function handleMemoryToolCall(name, args, reply) {
|
|
73
|
-
if (name === "heedvane_memory_list") {
|
|
74
|
-
const folder = typeof args.folder === "string" && args.folder.trim() !== "" ? [args.folder.trim()] : [];
|
|
75
|
-
void runMemoryTool(["list", ...folder], {}, args.cwd).then((text) => reply(textContent(text)));
|
|
76
|
-
return true;
|
|
77
|
-
}
|
|
78
|
-
if (name === "heedvane_memory_show") {
|
|
79
|
-
const id = typeof args.id === "string" ? args.id.trim() : "";
|
|
80
|
-
void runMemoryTool(["show", ...(id ? [id] : [])], {}, args.cwd).then((text) => reply(textContent(text)));
|
|
81
|
-
return true;
|
|
82
|
-
}
|
|
83
|
-
if (name === "heedvane_memory_search") {
|
|
84
|
-
const query = typeof args.query === "string" ? args.query.trim() : "";
|
|
85
|
-
const folder = typeof args.folder === "string" && args.folder.trim() !== "" ? args.folder.trim() : undefined;
|
|
86
|
-
void runMemoryTool(["search", ...(query ? [query] : [])], { "--folder": folder }, args.cwd).then((text) => reply(textContent(text)));
|
|
87
|
-
return true;
|
|
88
|
-
}
|
|
89
|
-
return false;
|
|
90
|
-
}
|
|
91
|
-
/** The tools/call branch: reply with the tool's text content, or a unknown-tool error. */
|
|
92
|
-
function handleToolCall(msg, reply, fail) {
|
|
93
|
-
const name = msg.params?.name;
|
|
94
|
-
const args = msg.params?.arguments ?? {};
|
|
95
|
-
if (name === "heedvane_status") {
|
|
96
|
-
void statusText().then((text) => reply(textContent(text)));
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
if (name === "heedvane_doctor") {
|
|
100
|
-
const clients = args.clients;
|
|
101
|
-
const input = { home: process.env.HEED_HOME ?? homeDir(), env: process.env };
|
|
102
|
-
if (Array.isArray(clients))
|
|
103
|
-
input.clients = clients.map(String);
|
|
104
|
-
void runDoctor(input).then((report) => reply(textContent(JSON.stringify(report, null, 2))));
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
if (handleMemoryToolCall(name, args, reply))
|
|
108
|
-
return;
|
|
109
|
-
fail(-32602, `unknown tool: ${String(name)}`);
|
|
110
|
-
}
|
|
111
|
-
function handleRpc(msg, io) {
|
|
112
|
-
const { method, id } = msg;
|
|
113
|
-
if (!method || id === undefined)
|
|
114
|
-
return; // notification: ignore silently
|
|
115
|
-
const reply = (result) => io.write(JSON.stringify({ jsonrpc: "2.0", id, result }));
|
|
116
|
-
const fail = (code, message) => io.write(JSON.stringify({ jsonrpc: "2.0", id, error: { code, message } }));
|
|
117
|
-
switch (method) {
|
|
118
|
-
case "initialize":
|
|
119
|
-
reply({ protocolVersion: "2024-11-05", capabilities: { tools: {} }, serverInfo: MCP_SERVER_INFO });
|
|
120
|
-
return;
|
|
121
|
-
case "tools/list":
|
|
122
|
-
reply({ tools: TOOLS });
|
|
123
|
-
return;
|
|
124
|
-
case "tools/call":
|
|
125
|
-
handleToolCall(msg, reply, fail);
|
|
126
|
-
return;
|
|
127
|
-
default:
|
|
128
|
-
fail(-32601, `method not supported: ${method}`);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
function textContent(text) {
|
|
132
|
-
return { content: [{ type: "text", text }] };
|
|
133
|
-
}
|
|
134
|
-
import { homedir } from "node:os";
|
|
135
|
-
import { join } from "node:path";
|
|
136
|
-
import { HeedStateCorruptError, readState } from "./state.js";
|
|
137
|
-
import { readEndpoint } from "./listener/endpoint.js";
|
|
138
|
-
function homeDir() {
|
|
139
|
-
return homedir();
|
|
140
|
-
}
|
|
141
|
-
export async function statusText() {
|
|
142
|
-
const home = process.env.HEED_HOME ?? homeDir();
|
|
143
|
-
const root = join(home, ".heed");
|
|
144
|
-
const lines = [`heedvane hooks status (home: ${home})`];
|
|
145
|
-
try {
|
|
146
|
-
const state = await readState(root);
|
|
147
|
-
if (state !== null) {
|
|
148
|
-
const skill = state.skill?.digest.slice(0, 12) ?? "not installed";
|
|
149
|
-
lines.push(` state.json: ok (protocol v${state.protocolVersion}, skill ${skill})`);
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
lines.push(" state.json: absent (run npx heedvane init)");
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
catch (error) {
|
|
156
|
-
if (!(error instanceof HeedStateCorruptError))
|
|
157
|
-
throw error;
|
|
158
|
-
lines.push(` state.json: ${error.message}`);
|
|
159
|
-
}
|
|
160
|
-
const endpoint = await readEndpoint(root);
|
|
161
|
-
lines.push(` listener: ${endpoint ? `endpoint.env present (port ${endpoint.port})` : "not configured — events spool to ~/.heed/spool"}`);
|
|
162
|
-
lines.push(" next: npx heedvane doctor for scoped checks");
|
|
163
|
-
return lines.join("\n");
|
|
164
|
-
}
|
|
165
|
-
/** One stdin line → one RPC dispatch. A blank or unparseable line never crashes the host's transport. */
|
|
166
|
-
function dispatchLine(line, io) {
|
|
167
|
-
const trimmed = line.trim();
|
|
168
|
-
if (trimmed === "")
|
|
169
|
-
return;
|
|
170
|
-
try {
|
|
171
|
-
handleRpc(JSON.parse(trimmed), io);
|
|
172
|
-
}
|
|
173
|
-
catch {
|
|
174
|
-
return; // unparseable line: ignore (never crash the host's transport)
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
/** Entry point for the `mcp` subcommand. */
|
|
178
|
-
export function runMcpStdio(io) {
|
|
179
|
-
const log = io.log ?? (() => { });
|
|
180
|
-
const rl = createInterface({ input: process.stdin });
|
|
181
|
-
rl.on("line", (line) => {
|
|
182
|
-
dispatchLine(line, { write: io.write, log });
|
|
183
|
-
});
|
|
184
|
-
rl.on("close", () => {
|
|
185
|
-
log("heedvane mcp: stdin closed");
|
|
186
|
-
});
|
|
187
|
-
}
|