@gethmy/mcp 2.5.1 → 2.5.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/README.md +1 -1
- package/dist/cli.js +127 -464
- package/dist/index.js +48 -1
- package/dist/lib/api-client.js +11 -0
- package/package.json +1 -1
- package/src/api-client.ts +51 -0
- package/src/server.ts +66 -2
- package/src/skills.ts +67 -485
- package/src/tui/setup.ts +57 -40
package/src/tui/setup.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
import { homedir } from "node:os";
|
|
9
9
|
import { dirname, join } from "node:path";
|
|
10
10
|
import * as p from "@clack/prompts";
|
|
11
|
+
import { HarmonyApiClient } from "../api-client.js";
|
|
11
12
|
import {
|
|
12
13
|
areSkillsInstalled,
|
|
13
14
|
getConfigPath,
|
|
@@ -223,56 +224,68 @@ export interface SymlinkToCreate {
|
|
|
223
224
|
}
|
|
224
225
|
|
|
225
226
|
/**
|
|
226
|
-
* Generate agent configuration files
|
|
227
|
+
* Generate agent configuration files. Async because the Claude Code path
|
|
228
|
+
* fetches skill content from /v1/skills (skill_resource is the source of
|
|
229
|
+
* truth — see card #162 Phase 0b).
|
|
227
230
|
*/
|
|
228
|
-
function getAgentFiles(
|
|
231
|
+
async function getAgentFiles(
|
|
229
232
|
agentId: AgentId,
|
|
230
233
|
cwd: string,
|
|
231
234
|
installMode: InstallMode = "global",
|
|
232
|
-
): { files: FileToWrite[]; symlinks: SymlinkToCreate[] } {
|
|
235
|
+
): Promise<{ files: FileToWrite[]; symlinks: SymlinkToCreate[] }> {
|
|
233
236
|
const home = homedir();
|
|
234
237
|
const files: FileToWrite[] = [];
|
|
235
238
|
const symlinks: SymlinkToCreate[] = [];
|
|
236
239
|
|
|
237
240
|
switch (agentId) {
|
|
238
241
|
case "claude": {
|
|
239
|
-
// Claude Code
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
type: "text",
|
|
249
|
-
});
|
|
250
|
-
symlinks.push({
|
|
251
|
-
target: join(GLOBAL_SKILLS_DIR, "hmy"),
|
|
252
|
-
link: join(home, ".claude", "skills", "hmy"),
|
|
253
|
-
});
|
|
242
|
+
// Claude Code skills come from /v1/skills (DB-backed). Fetch the
|
|
243
|
+
// canonical list, then each body. hmy-update-check is intentionally
|
|
244
|
+
// skipped — it's a shell script the auto-update preamble curls on
|
|
245
|
+
// demand, not an installed SKILL.md.
|
|
246
|
+
const client = new HarmonyApiClient();
|
|
247
|
+
const versionInfo = await client.fetchSkillsVersion();
|
|
248
|
+
const installableNames = versionInfo.skills.filter(
|
|
249
|
+
(name) => name !== "hmy-update-check",
|
|
250
|
+
);
|
|
254
251
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
252
|
+
const skillFailures: { name: string; error: string }[] = [];
|
|
253
|
+
for (const name of installableNames) {
|
|
254
|
+
try {
|
|
255
|
+
const fetched = await client.fetchSkill(name);
|
|
256
|
+
const content = buildSkillFile(fetched);
|
|
257
|
+
|
|
258
|
+
if (installMode === "global") {
|
|
259
|
+
// Global: write to ~/.agents/skills/<name>/SKILL.md and symlink
|
|
260
|
+
// ~/.claude/skills/<name> → that directory.
|
|
261
|
+
files.push({
|
|
262
|
+
path: join(GLOBAL_SKILLS_DIR, name, "SKILL.md"),
|
|
263
|
+
content,
|
|
264
|
+
type: "text",
|
|
265
|
+
});
|
|
266
|
+
symlinks.push({
|
|
267
|
+
target: join(GLOBAL_SKILLS_DIR, name),
|
|
268
|
+
link: join(home, ".claude", "skills", name),
|
|
269
|
+
});
|
|
270
|
+
} else {
|
|
271
|
+
files.push({
|
|
272
|
+
path: join(cwd, ".claude", "skills", name, "SKILL.md"),
|
|
273
|
+
content,
|
|
274
|
+
type: "text",
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
} catch (err) {
|
|
278
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
279
|
+
skillFailures.push({ name, error: msg });
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (skillFailures.length > 0) {
|
|
283
|
+
const summary = skillFailures
|
|
284
|
+
.map((f) => ` - ${f.name}: ${f.error}`)
|
|
285
|
+
.join("\n");
|
|
286
|
+
throw new Error(
|
|
287
|
+
`Failed to fetch ${skillFailures.length}/${installableNames.length} skill(s) from /v1/skills:\n${summary}`,
|
|
288
|
+
);
|
|
276
289
|
}
|
|
277
290
|
|
|
278
291
|
// Note: MCP server registration is handled separately via `claude mcp add` CLI
|
|
@@ -914,7 +927,11 @@ export async function runSetup(options: SetupOptions = {}): Promise<void> {
|
|
|
914
927
|
// Agent-specific files
|
|
915
928
|
if (needsSkills && selectedAgents.length > 0) {
|
|
916
929
|
for (const agentId of selectedAgents) {
|
|
917
|
-
const { files, symlinks } = getAgentFiles(
|
|
930
|
+
const { files, symlinks } = await getAgentFiles(
|
|
931
|
+
agentId,
|
|
932
|
+
cwd,
|
|
933
|
+
installMode,
|
|
934
|
+
);
|
|
918
935
|
allFiles.push(...files);
|
|
919
936
|
allSymlinks.push(...symlinks);
|
|
920
937
|
}
|