@paperclipai/hermes-paperclip-adapter 0.3.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 (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +228 -0
  3. package/dist/cli/format-event.d.ts +14 -0
  4. package/dist/cli/format-event.d.ts.map +1 -0
  5. package/dist/cli/format-event.js +52 -0
  6. package/dist/cli/format-event.js.map +1 -0
  7. package/dist/cli/index.d.ts +5 -0
  8. package/dist/cli/index.d.ts.map +1 -0
  9. package/dist/cli/index.js +5 -0
  10. package/dist/cli/index.js.map +1 -0
  11. package/dist/index.d.ts +33 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +102 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/index.test.d.ts +2 -0
  16. package/dist/index.test.d.ts.map +1 -0
  17. package/dist/index.test.js +14 -0
  18. package/dist/index.test.js.map +1 -0
  19. package/dist/server/command-resolution.test.d.ts +2 -0
  20. package/dist/server/command-resolution.test.d.ts.map +1 -0
  21. package/dist/server/command-resolution.test.js +37 -0
  22. package/dist/server/command-resolution.test.js.map +1 -0
  23. package/dist/server/detect-model.d.ts +77 -0
  24. package/dist/server/detect-model.d.ts.map +1 -0
  25. package/dist/server/detect-model.js +158 -0
  26. package/dist/server/detect-model.js.map +1 -0
  27. package/dist/server/detect-model.test.d.ts +2 -0
  28. package/dist/server/detect-model.test.d.ts.map +1 -0
  29. package/dist/server/detect-model.test.js +166 -0
  30. package/dist/server/detect-model.test.js.map +1 -0
  31. package/dist/server/execute.d.ts +23 -0
  32. package/dist/server/execute.d.ts.map +1 -0
  33. package/dist/server/execute.js +482 -0
  34. package/dist/server/execute.js.map +1 -0
  35. package/dist/server/index.d.ts +16 -0
  36. package/dist/server/index.d.ts.map +1 -0
  37. package/dist/server/index.js +43 -0
  38. package/dist/server/index.js.map +1 -0
  39. package/dist/server/skills.d.ts +8 -0
  40. package/dist/server/skills.d.ts.map +1 -0
  41. package/dist/server/skills.js +177 -0
  42. package/dist/server/skills.js.map +1 -0
  43. package/dist/server/test.d.ts +9 -0
  44. package/dist/server/test.d.ts.map +1 -0
  45. package/dist/server/test.js +341 -0
  46. package/dist/server/test.js.map +1 -0
  47. package/dist/shared/constants.d.ts +47 -0
  48. package/dist/shared/constants.d.ts.map +1 -0
  49. package/dist/shared/constants.js +91 -0
  50. package/dist/shared/constants.js.map +1 -0
  51. package/dist/ui/build-config.d.ts +17 -0
  52. package/dist/ui/build-config.d.ts.map +1 -0
  53. package/dist/ui/build-config.js +69 -0
  54. package/dist/ui/build-config.js.map +1 -0
  55. package/dist/ui/index.d.ts +7 -0
  56. package/dist/ui/index.d.ts.map +1 -0
  57. package/dist/ui/index.js +7 -0
  58. package/dist/ui/index.js.map +1 -0
  59. package/dist/ui/parse-stdout.d.ts +25 -0
  60. package/dist/ui/parse-stdout.d.ts.map +1 -0
  61. package/dist/ui/parse-stdout.js +237 -0
  62. package/dist/ui/parse-stdout.js.map +1 -0
  63. package/package.json +80 -0
@@ -0,0 +1,177 @@
1
+ import fs from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { readPaperclipRuntimeSkillEntries, resolvePaperclipDesiredSkillNames, } from "@paperclipai/adapter-utils/server-utils";
5
+ import { fileURLToPath } from "node:url";
6
+ const __moduleDir = path.dirname(fileURLToPath(import.meta.url));
7
+ // ---------------------------------------------------------------------------
8
+ // Helpers
9
+ // ---------------------------------------------------------------------------
10
+ function asString(value) {
11
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
12
+ }
13
+ function resolveHermesHome(config) {
14
+ const env = typeof config.env === "object" && config.env !== null && !Array.isArray(config.env)
15
+ ? config.env
16
+ : {};
17
+ const configuredHome = asString(env.HOME);
18
+ return configuredHome ? path.resolve(configuredHome) : os.homedir();
19
+ }
20
+ function parseSkillFrontmatter(content) {
21
+ const match = content.match(/^---\s*\n([\s\S]*?)\n---/);
22
+ if (!match)
23
+ return {};
24
+ const frontmatter = {};
25
+ for (const line of match[1].split("\n")) {
26
+ const idx = line.indexOf(":");
27
+ if (idx === -1)
28
+ continue;
29
+ const key = line.slice(0, idx).trim();
30
+ let val = line.slice(idx + 1).trim();
31
+ // Strip quotes
32
+ if (typeof val === "string" && ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'")))) {
33
+ val = val.slice(1, -1);
34
+ }
35
+ frontmatter[key] = val;
36
+ }
37
+ return frontmatter;
38
+ }
39
+ async function scanHermesSkills(skillsHome) {
40
+ const entries = [];
41
+ try {
42
+ const categories = await fs.readdir(skillsHome, { withFileTypes: true });
43
+ for (const cat of categories) {
44
+ if (!cat.isDirectory())
45
+ continue;
46
+ const catPath = path.join(skillsHome, cat.name);
47
+ // Check if the category directory itself has a SKILL.md (top-level skill)
48
+ const topLevelSkillMd = path.join(catPath, "SKILL.md");
49
+ if (await fs.stat(topLevelSkillMd).catch(() => null)) {
50
+ entries.push(await buildSkillEntry(cat.name, topLevelSkillMd, cat.name));
51
+ }
52
+ // Scan for sub-skills
53
+ const items = await fs.readdir(catPath, { withFileTypes: true }).catch(() => []);
54
+ for (const item of items) {
55
+ if (!item.isDirectory())
56
+ continue;
57
+ const skillMd = path.join(catPath, item.name, "SKILL.md");
58
+ if (await fs.stat(skillMd).catch(() => null)) {
59
+ const key = item.name;
60
+ entries.push(await buildSkillEntry(key, skillMd, `${cat.name}/${item.name}`));
61
+ }
62
+ }
63
+ }
64
+ }
65
+ catch {
66
+ // ~/.hermes/skills/ doesn't exist — no skills available
67
+ }
68
+ return entries.sort((a, b) => a.key.localeCompare(b.key));
69
+ }
70
+ async function buildSkillEntry(key, skillMdPath, categoryPath) {
71
+ let description = null;
72
+ try {
73
+ const content = await fs.readFile(skillMdPath, "utf8");
74
+ const fm = parseSkillFrontmatter(content);
75
+ description = fm.description ?? null;
76
+ }
77
+ catch {
78
+ // ignore
79
+ }
80
+ return {
81
+ key,
82
+ runtimeName: key,
83
+ desired: true, // Hermes loads all available skills
84
+ managed: false,
85
+ state: "installed",
86
+ origin: "user_installed",
87
+ originLabel: "Hermes skill",
88
+ locationLabel: `~/.hermes/skills/${categoryPath}`,
89
+ readOnly: true, // Hermes manages its own skills — Paperclip can't toggle them
90
+ sourcePath: skillMdPath,
91
+ targetPath: null,
92
+ detail: description,
93
+ };
94
+ }
95
+ // ---------------------------------------------------------------------------
96
+ // Public API
97
+ // ---------------------------------------------------------------------------
98
+ async function buildHermesSkillSnapshot(config) {
99
+ const home = resolveHermesHome(config);
100
+ const hermesSkillsHome = path.join(home, ".hermes", "skills");
101
+ // 1. Scan Paperclip-managed skills (bundled with the adapter)
102
+ const paperclipEntries = await readPaperclipRuntimeSkillEntries(config, __moduleDir);
103
+ const desiredSkills = resolvePaperclipDesiredSkillNames(config, paperclipEntries);
104
+ const desiredSet = new Set(desiredSkills);
105
+ const availableByKey = new Map(paperclipEntries.map((e) => [e.key, e]));
106
+ // 2. Scan Hermes's own skills from ~/.hermes/skills/
107
+ const hermesSkillEntries = await scanHermesSkills(hermesSkillsHome);
108
+ const hermesKeys = new Set(hermesSkillEntries.map((e) => e.key));
109
+ // 3. Merge: Paperclip skills first (ephemeral), then Hermes skills
110
+ const entries = [];
111
+ const warnings = [];
112
+ // Paperclip-managed skills
113
+ for (const entry of paperclipEntries) {
114
+ const desired = desiredSet.has(entry.key);
115
+ entries.push({
116
+ key: entry.key,
117
+ runtimeName: entry.runtimeName,
118
+ desired,
119
+ managed: true,
120
+ state: desired ? "configured" : "available",
121
+ origin: "company_managed",
122
+ originLabel: "Managed by Paperclip",
123
+ readOnly: false,
124
+ sourcePath: entry.source,
125
+ targetPath: null,
126
+ detail: desired
127
+ ? "Will be available on the next run via Hermes skill loading."
128
+ : null,
129
+ });
130
+ }
131
+ // Hermes-installed skills (read-only, always loaded)
132
+ for (const entry of hermesSkillEntries) {
133
+ // Skip if Paperclip already manages a skill with the same key
134
+ if (availableByKey.has(entry.key))
135
+ continue;
136
+ entries.push(entry);
137
+ }
138
+ // Check for desired skills that don't exist
139
+ for (const desiredSkill of desiredSkills) {
140
+ if (availableByKey.has(desiredSkill) || hermesKeys.has(desiredSkill))
141
+ continue;
142
+ warnings.push(`Desired skill "${desiredSkill}" is not available in Paperclip or Hermes skills.`);
143
+ entries.push({
144
+ key: desiredSkill,
145
+ runtimeName: null,
146
+ desired: true,
147
+ managed: true,
148
+ state: "missing",
149
+ origin: "external_unknown",
150
+ originLabel: "External or unavailable",
151
+ readOnly: false,
152
+ sourcePath: null,
153
+ targetPath: null,
154
+ detail: "Cannot find this skill in Paperclip or ~/.hermes/skills/.",
155
+ });
156
+ }
157
+ return {
158
+ adapterType: "hermes_local",
159
+ supported: true,
160
+ mode: "persistent",
161
+ desiredSkills,
162
+ entries,
163
+ warnings,
164
+ };
165
+ }
166
+ export async function listHermesSkills(ctx) {
167
+ return buildHermesSkillSnapshot(ctx.config);
168
+ }
169
+ export async function syncHermesSkills(ctx, _desiredSkills) {
170
+ // Hermes manages its own skill loading — sync is a no-op.
171
+ // Return the current snapshot so the UI stays in sync.
172
+ return buildHermesSkillSnapshot(ctx.config);
173
+ }
174
+ export function resolveHermesDesiredSkillNames(config, availableEntries) {
175
+ return resolvePaperclipDesiredSkillNames(config, availableEntries);
176
+ }
177
+ //# sourceMappingURL=skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/server/skills.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAM7B,OAAO,EACL,gCAAgC,EAChC,iCAAiC,GAClC,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAEjE,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACpF,CAAC;AAED,SAAS,iBAAiB,CAAC,MAA+B;IACxD,MAAM,GAAG,GACP,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,GAAG,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC;QACjF,CAAC,CAAE,MAAM,CAAC,GAA+B;QACzC,CAAC,CAAC,EAAE,CAAC;IACT,MAAM,cAAc,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC;AACtE,CAAC;AAUD,SAAS,qBAAqB,CAAC,OAAe;IAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IACxD,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,MAAM,WAAW,GAA4B,EAAE,CAAC;IAChD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,SAAS;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QACtC,IAAI,GAAG,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9C,eAAe;QACf,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1H,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACzB,CAAC;QACD,WAAW,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IACzB,CAAC;IACD,OAAO,WAA+B,CAAC;AACzC,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC7B,UAAkB;IAElB,MAAM,OAAO,GAAwB,EAAE,CAAC;IAExC,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACzE,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;YAC7B,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE;gBAAE,SAAS;YACjC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;YAEhD,0EAA0E;YAC1E,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;YACvD,IAAI,MAAM,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrD,OAAO,CAAC,IAAI,CAAC,MAAM,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,eAAe,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;YAC3E,CAAC;YAED,sBAAsB;YACtB,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YACjF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;oBAAE,SAAS;gBAClC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;gBAC1D,IAAI,MAAM,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC;oBACtB,OAAO,CAAC,IAAI,CAAC,MAAM,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;gBAChF,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,wDAAwD;IAC1D,CAAC;IAED,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,KAAK,UAAU,eAAe,CAC5B,GAAW,EACX,WAAmB,EACnB,YAAoB;IAEpB,IAAI,WAAW,GAAkB,IAAI,CAAC;IACtC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACvD,MAAM,EAAE,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAC1C,WAAW,GAAG,EAAE,CAAC,WAAW,IAAI,IAAI,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;IAED,OAAO;QACL,GAAG;QACH,WAAW,EAAE,GAAG;QAChB,OAAO,EAAE,IAAI,EAAE,oCAAoC;QACnD,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,WAAW;QAClB,MAAM,EAAE,gBAAgB;QACxB,WAAW,EAAE,cAAc;QAC3B,aAAa,EAAE,oBAAoB,YAAY,EAAE;QACjD,QAAQ,EAAE,IAAI,EAAE,8DAA8D;QAC9E,UAAU,EAAE,WAAW;QACvB,UAAU,EAAE,IAAI;QAChB,MAAM,EAAE,WAAW;KACpB,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E,KAAK,UAAU,wBAAwB,CAAC,MAA+B;IACrE,MAAM,IAAI,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IAE9D,8DAA8D;IAC9D,MAAM,gBAAgB,GAAG,MAAM,gCAAgC,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACrF,MAAM,aAAa,GAAG,iCAAiC,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAClF,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;IAC1C,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAExE,qDAAqD;IACrD,MAAM,kBAAkB,GAAG,MAAM,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;IACpE,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAEjE,mEAAmE;IACnE,MAAM,OAAO,GAAwB,EAAE,CAAC;IACxC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,2BAA2B;IAC3B,KAAK,MAAM,KAAK,IAAI,gBAAgB,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1C,OAAO,CAAC,IAAI,CAAC;YACX,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,OAAO;YACP,OAAO,EAAE,IAAI;YACb,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW;YAC3C,MAAM,EAAE,iBAAiB;YACzB,WAAW,EAAE,sBAAsB;YACnC,QAAQ,EAAE,KAAK;YACf,UAAU,EAAE,KAAK,CAAC,MAAM;YACxB,UAAU,EAAE,IAAI;YAChB,MAAM,EAAE,OAAO;gBACb,CAAC,CAAC,6DAA6D;gBAC/D,CAAC,CAAC,IAAI;SACT,CAAC,CAAC;IACL,CAAC;IAED,qDAAqD;IACrD,KAAK,MAAM,KAAK,IAAI,kBAAkB,EAAE,CAAC;QACvC,8DAA8D;QAC9D,IAAI,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5C,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IAED,4CAA4C;IAC5C,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;QACzC,IAAI,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC;YAAE,SAAS;QAC/E,QAAQ,CAAC,IAAI,CACX,kBAAkB,YAAY,mDAAmD,CAClF,CAAC;QACF,OAAO,CAAC,IAAI,CAAC;YACX,GAAG,EAAE,YAAY;YACjB,WAAW,EAAE,IAAI;YACjB,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,IAAI;YACb,KAAK,EAAE,SAAS;YAChB,MAAM,EAAE,kBAAkB;YAC1B,WAAW,EAAE,yBAAyB;YACtC,QAAQ,EAAE,KAAK;YACf,UAAU,EAAE,IAAI;YAChB,UAAU,EAAE,IAAI;YAChB,MAAM,EACJ,2DAA2D;SAC9D,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,WAAW,EAAE,cAAc;QAC3B,SAAS,EAAE,IAAI;QACf,IAAI,EAAE,YAAY;QAClB,aAAa;QACb,OAAO;QACP,QAAQ;KACT,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAwB;IAExB,OAAO,wBAAwB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAwB,EACxB,cAAwB;IAExB,0DAA0D;IAC1D,uDAAuD;IACvD,OAAO,wBAAwB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,8BAA8B,CAC5C,MAA+B,EAC/B,gBAAqE;IAErE,OAAO,iCAAiC,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;AACrE,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Environment test for the Hermes Agent adapter.
3
+ *
4
+ * Verifies that Hermes Agent is installed, accessible, and configured
5
+ * before allowing the adapter to be used.
6
+ */
7
+ import type { AdapterEnvironmentTestContext, AdapterEnvironmentTestResult } from "@paperclipai/adapter-utils";
8
+ export declare function testEnvironment(ctx: AdapterEnvironmentTestContext): Promise<AdapterEnvironmentTestResult>;
9
+ //# sourceMappingURL=test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../src/server/test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,6BAA6B,EAC7B,4BAA4B,EAE7B,MAAM,4BAA4B,CAAC;AA4TpC,wBAAsB,eAAe,CACnC,GAAG,EAAE,6BAA6B,GACjC,OAAO,CAAC,4BAA4B,CAAC,CAyDvC"}
@@ -0,0 +1,341 @@
1
+ /**
2
+ * Environment test for the Hermes Agent adapter.
3
+ *
4
+ * Verifies that Hermes Agent is installed, accessible, and configured
5
+ * before allowing the adapter to be used.
6
+ */
7
+ import { execFile } from "node:child_process";
8
+ import { readFileSync } from "node:fs";
9
+ import { promisify } from "node:util";
10
+ import { ADAPTER_TYPE, VALID_PROVIDERS } from "../shared/constants.js";
11
+ import { detectModel, resolveProvider } from "./detect-model.js";
12
+ import { resolveHermesCommand } from "./execute.js";
13
+ const execFileAsync = promisify(execFile);
14
+ function asString(v) {
15
+ return typeof v === "string" ? v : undefined;
16
+ }
17
+ // ---------------------------------------------------------------------------
18
+ // Checks
19
+ // ---------------------------------------------------------------------------
20
+ async function checkCliInstalled(command) {
21
+ try {
22
+ // Try to run the command to see if it exists
23
+ await execFileAsync(command, ["--version"], { timeout: 10_000 });
24
+ return null; // OK — it ran successfully
25
+ }
26
+ catch (err) {
27
+ const e = err;
28
+ if (e.code === "ENOENT") {
29
+ return {
30
+ level: "error",
31
+ message: `Hermes CLI "${command}" not found in PATH`,
32
+ hint: "Install Hermes Agent: pip install hermes-agent",
33
+ code: "hermes_cli_not_found",
34
+ };
35
+ }
36
+ // Command exists but --version might have failed for some reason
37
+ // Still consider it installed
38
+ return null;
39
+ }
40
+ }
41
+ async function checkCliVersion(command) {
42
+ try {
43
+ const { stdout } = await execFileAsync(command, ["--version"], {
44
+ timeout: 10_000,
45
+ });
46
+ const version = stdout.trim();
47
+ if (version) {
48
+ return {
49
+ level: "info",
50
+ message: `Hermes Agent version: ${version}`,
51
+ code: "hermes_version",
52
+ };
53
+ }
54
+ return {
55
+ level: "warn",
56
+ message: "Could not determine Hermes Agent version",
57
+ code: "hermes_version_unknown",
58
+ };
59
+ }
60
+ catch {
61
+ return {
62
+ level: "warn",
63
+ message: "Could not determine Hermes Agent version (hermes --version failed)",
64
+ hint: "Make sure the hermes CLI is properly installed and functional",
65
+ code: "hermes_version_failed",
66
+ };
67
+ }
68
+ }
69
+ async function checkPython() {
70
+ try {
71
+ const { stdout } = await execFileAsync("python3", ["--version"], {
72
+ timeout: 5_000,
73
+ });
74
+ const version = stdout.trim();
75
+ const match = version.match(/(\d+)\.(\d+)/);
76
+ if (match) {
77
+ const major = parseInt(match[1], 10);
78
+ const minor = parseInt(match[2], 10);
79
+ if (major < 3 || (major === 3 && minor < 10)) {
80
+ return {
81
+ level: "error",
82
+ message: `Python ${version} found — Hermes requires Python 3.10+`,
83
+ hint: "Upgrade Python to 3.10 or later",
84
+ code: "hermes_python_old",
85
+ };
86
+ }
87
+ }
88
+ return null; // OK
89
+ }
90
+ catch {
91
+ return {
92
+ level: "warn",
93
+ message: "python3 not found in PATH",
94
+ hint: "Hermes Agent requires Python 3.10+. Install it from python.org",
95
+ code: "hermes_python_missing",
96
+ };
97
+ }
98
+ }
99
+ function checkModel(config) {
100
+ const model = asString(config.model);
101
+ if (!model) {
102
+ return {
103
+ level: "info",
104
+ message: "No model specified — Hermes will use its configured default model",
105
+ hint: "Set a model explicitly in Paperclip only if you want to override your local Hermes configuration.",
106
+ code: "hermes_configured_default_model",
107
+ };
108
+ }
109
+ return {
110
+ level: "info",
111
+ message: `Model: ${model}`,
112
+ code: "hermes_model_configured",
113
+ };
114
+ }
115
+ async function checkApiKeys(config, detectedConfig) {
116
+ // The server resolves secret refs into config.env before calling testEnvironment,
117
+ // so we check config.env first (adapter-configured secrets), then fall back to
118
+ // process.env (server/host environment), then ~/.hermes/.env (Hermes local config).
119
+ const envConfig = (config.env ?? {});
120
+ const resolvedEnv = {};
121
+ for (const [key, value] of Object.entries(envConfig)) {
122
+ if (typeof value === "string" && value.length > 0)
123
+ resolvedEnv[key] = value;
124
+ }
125
+ // Also read ~/.hermes/.env — Hermes stores API keys there by default and does
126
+ // not export them to the parent process, so Paperclip's process.env won't
127
+ // contain them. Parsing this file ensures the environment test reports
128
+ // accurate results for keys that Hermes already knows about.
129
+ const hermesEnvKeys = {};
130
+ try {
131
+ const homeDir = process.env.HOME || process.env.USERPROFILE || "/root";
132
+ const hermesEnvPath = `${homeDir}/.hermes/.env`;
133
+ const content = readFileSync(hermesEnvPath, "utf-8");
134
+ for (const line of content.split("\n")) {
135
+ const trimmed = line.trim();
136
+ if (!trimmed || trimmed.startsWith("#"))
137
+ continue;
138
+ const eqIdx = trimmed.indexOf("=");
139
+ if (eqIdx > 0) {
140
+ const key = trimmed.substring(0, eqIdx).trim();
141
+ const value = trimmed.substring(eqIdx + 1).trim();
142
+ if (value.length > 0)
143
+ hermesEnvKeys[key] = value;
144
+ }
145
+ }
146
+ }
147
+ catch {
148
+ // ~/.hermes/.env may not exist — that's fine
149
+ }
150
+ const has = (key) => !!(resolvedEnv[key] ?? process.env[key] ?? hermesEnvKeys[key]);
151
+ const hasAnthropic = has("ANTHROPIC_API_KEY");
152
+ const hasOpenRouter = has("OPENROUTER_API_KEY");
153
+ const hasOpenAI = has("OPENAI_API_KEY");
154
+ const hasZai = has("ZAI_API_KEY");
155
+ const hasKimi = has("KIMI_API_KEY");
156
+ const hasMiniMax = has("MINIMAX_API_KEY");
157
+ const providers = [];
158
+ if (hasAnthropic)
159
+ providers.push("Anthropic");
160
+ if (hasOpenRouter)
161
+ providers.push("OpenRouter");
162
+ if (hasOpenAI)
163
+ providers.push("OpenAI");
164
+ if (hasZai)
165
+ providers.push("Z.AI");
166
+ if (hasKimi)
167
+ providers.push("Kimi");
168
+ if (hasMiniMax)
169
+ providers.push("MiniMax");
170
+ if (providers.length > 0) {
171
+ return {
172
+ level: "info",
173
+ message: `API keys found: ${providers.join(", ")}`,
174
+ code: "hermes_api_keys_found",
175
+ };
176
+ }
177
+ const requestedModel = asString(config.model);
178
+ const supportedProviders = VALID_PROVIDERS;
179
+ const modelMatchesRequested = !!detectedConfig?.model &&
180
+ (!requestedModel || detectedConfig.model.toLowerCase() === requestedModel.toLowerCase());
181
+ const matchingHermesConfigApiKey = !!detectedConfig?.hasApiKey &&
182
+ modelMatchesRequested;
183
+ if (matchingHermesConfigApiKey && detectedConfig) {
184
+ const providerLabel = detectedConfig.provider.trim();
185
+ if (!providerLabel) {
186
+ return {
187
+ level: "info",
188
+ message: "Hermes config includes an API key for the requested model via ~/.hermes/config.yaml without an explicit provider",
189
+ hint: "Skipping the built-in API-key warning because Hermes can use model.api_key from the local Hermes config.",
190
+ code: "hermes_api_key_in_config",
191
+ };
192
+ }
193
+ if (!supportedProviders.includes(providerLabel)) {
194
+ return {
195
+ level: "info",
196
+ message: `Hermes config includes runtime settings for unsupported adapter provider "${providerLabel}" via ~/.hermes/config.yaml`,
197
+ hint: "Skipping the built-in API-key warning because Hermes can resolve this provider at runtime.",
198
+ code: "hermes_custom_provider_config",
199
+ };
200
+ }
201
+ return {
202
+ level: "info",
203
+ message: `Hermes config includes an API key for provider "${providerLabel}" via ~/.hermes/config.yaml`,
204
+ hint: "Skipping the built-in API-key warning because Hermes can use model.api_key from the local Hermes config.",
205
+ code: "hermes_api_key_in_config",
206
+ };
207
+ }
208
+ return {
209
+ level: "warn",
210
+ message: "No LLM API keys found in environment",
211
+ hint: "Set API keys in the agent's env secrets or ~/.hermes/.env. Hermes supports: ANTHROPIC_API_KEY, OPENROUTER_API_KEY, OPENAI_API_KEY, ZAI_API_KEY, KIMI_API_KEY, MINIMAX_API_KEY",
212
+ code: "hermes_no_api_keys",
213
+ };
214
+ }
215
+ /**
216
+ * Check provider/model consistency.
217
+ * Warns if the configured provider might be wrong for the model.
218
+ */
219
+ async function checkProviderConsistency(config, detectedConfig) {
220
+ const model = asString(config.model);
221
+ if (!model)
222
+ return null;
223
+ const explicitProvider = asString(config.provider);
224
+ const { provider: resolved, resolvedFrom } = resolveProvider({
225
+ explicitProvider,
226
+ detectedProvider: detectedConfig?.provider,
227
+ detectedModel: detectedConfig?.model,
228
+ detectedBaseUrl: detectedConfig?.baseUrl,
229
+ detectedHasApiKey: detectedConfig?.hasApiKey,
230
+ detectedApiMode: detectedConfig?.apiMode,
231
+ model,
232
+ });
233
+ // If provider was explicitly set but doesn't match what Hermes config says,
234
+ // that's worth flagging.
235
+ if (explicitProvider && detectedConfig?.provider && explicitProvider !== detectedConfig.provider) {
236
+ return {
237
+ level: "warn",
238
+ message: `Provider mismatch: adapterConfig has "${explicitProvider}" but ~/.hermes/config.yaml has "${detectedConfig.provider}". Using adapterConfig value.`,
239
+ hint: `Model "${model}" may not work correctly with provider "${explicitProvider}". Consider aligning with your Hermes config or removing the explicit provider to use auto-detection.`,
240
+ code: "hermes_provider_mismatch",
241
+ };
242
+ }
243
+ // If Hermes config matches the requested model but uses an adapter-unsupported
244
+ // provider such as "custom", do not report a false provider inference.
245
+ if (!explicitProvider && resolvedFrom.startsWith("hermesConfigUnsupported:")) {
246
+ const unsupportedProvider = resolvedFrom.split(":", 2)[1] || detectedConfig?.provider || "unknown";
247
+ return {
248
+ level: "info",
249
+ message: `Hermes config uses unsupported adapter provider "${unsupportedProvider}" for model "${model}" — deferring to Hermes auto-detection`,
250
+ hint: "Paperclip will avoid model-name provider inference here and let Hermes resolve the provider from ~/.hermes/config.yaml at runtime.",
251
+ code: "hermes_provider_unsupported",
252
+ };
253
+ }
254
+ // If matching Hermes config provides runtime signals without an explicit provider,
255
+ // also defer to Hermes rather than inventing a provider from the model name.
256
+ if (!explicitProvider && resolvedFrom === "hermesConfigRuntime") {
257
+ return {
258
+ level: "info",
259
+ message: `Hermes config provides runtime settings for model "${model}" without an explicit adapter provider — deferring to Hermes auto-detection`,
260
+ hint: "Paperclip will avoid model-name provider inference here and let Hermes resolve the provider from ~/.hermes/config.yaml at runtime.",
261
+ code: "hermes_provider_runtime_config",
262
+ };
263
+ }
264
+ // If provider was auto-detected (not explicitly set), log what was resolved
265
+ if (!explicitProvider && resolvedFrom !== "auto") {
266
+ return {
267
+ level: "info",
268
+ message: `Provider auto-detected as "${resolved}" (from ${resolvedFrom}) for model "${model}"`,
269
+ code: "hermes_provider_detected",
270
+ };
271
+ }
272
+ // If we couldn't resolve any provider, warn
273
+ if (resolvedFrom === "auto" && !explicitProvider) {
274
+ return {
275
+ level: "warn",
276
+ message: `Could not determine provider for model "${model}" — will use Hermes auto-detection`,
277
+ hint: "Set an explicit provider in the agent config or ensure ~/.hermes/config.yaml has a matching provider for this model.",
278
+ code: "hermes_provider_unknown",
279
+ };
280
+ }
281
+ return null;
282
+ }
283
+ // ---------------------------------------------------------------------------
284
+ // Main test
285
+ // ---------------------------------------------------------------------------
286
+ export async function testEnvironment(ctx) {
287
+ const config = (ctx.config ?? {});
288
+ const command = resolveHermesCommand(config);
289
+ const checks = [];
290
+ // 1. CLI installed?
291
+ const cliCheck = await checkCliInstalled(command);
292
+ if (cliCheck) {
293
+ checks.push(cliCheck);
294
+ if (cliCheck.level === "error") {
295
+ return {
296
+ adapterType: ADAPTER_TYPE,
297
+ status: "fail",
298
+ checks,
299
+ testedAt: new Date().toISOString(),
300
+ };
301
+ }
302
+ }
303
+ // 2. CLI version
304
+ const versionCheck = await checkCliVersion(command);
305
+ if (versionCheck)
306
+ checks.push(versionCheck);
307
+ // 3. Python available?
308
+ const pythonCheck = await checkPython();
309
+ if (pythonCheck)
310
+ checks.push(pythonCheck);
311
+ // 4. Model config
312
+ const modelCheck = checkModel(config);
313
+ if (modelCheck)
314
+ checks.push(modelCheck);
315
+ // 5. Detect Hermes config once for the remaining checks.
316
+ let detectedConfig = null;
317
+ try {
318
+ detectedConfig = await detectModel();
319
+ }
320
+ catch {
321
+ // Non-fatal
322
+ }
323
+ // 6. API keys (check config.env — server resolves secrets before calling us)
324
+ const apiKeyCheck = await checkApiKeys(config, detectedConfig);
325
+ if (apiKeyCheck)
326
+ checks.push(apiKeyCheck);
327
+ // 7. Provider/model consistency
328
+ const providerCheck = await checkProviderConsistency(config, detectedConfig);
329
+ if (providerCheck)
330
+ checks.push(providerCheck);
331
+ // Determine overall status
332
+ const hasErrors = checks.some((c) => c.level === "error");
333
+ const hasWarnings = checks.some((c) => c.level === "warn");
334
+ return {
335
+ adapterType: ADAPTER_TYPE,
336
+ status: hasErrors ? "fail" : hasWarnings ? "warn" : "pass",
337
+ checks,
338
+ testedAt: new Date().toISOString(),
339
+ };
340
+ }
341
+ //# sourceMappingURL=test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/server/test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Shared constants for the Hermes Agent adapter.
3
+ */
4
+ /** Adapter type identifier registered with Paperclip. */
5
+ export declare const ADAPTER_TYPE = "hermes_local";
6
+ /** Human-readable label shown in the Paperclip UI. */
7
+ export declare const ADAPTER_LABEL = "Hermes Agent";
8
+ /** Default CLI binary name. */
9
+ export declare const HERMES_CLI = "hermes";
10
+ /** Default timeout for a single execution run (seconds). */
11
+ export declare const DEFAULT_TIMEOUT_SEC = 1800;
12
+ /** Grace period after SIGTERM before SIGKILL (seconds). */
13
+ export declare const DEFAULT_GRACE_SEC = 10;
14
+ /**
15
+ * Default model to use if none specified.
16
+ *
17
+ * Use "auto" so that Hermes resolves the model from the user's local
18
+ * ~/.hermes/config.yaml — preventing the adapter from overriding a
19
+ * user's configured default (e.g. MiniMax, OpenRouter, etc.) with a
20
+ * hardcoded Anthropic model during Paperclip onboarding.
21
+ */
22
+ export declare const DEFAULT_MODEL = "auto";
23
+ /**
24
+ * Valid --provider choices for the hermes CLI.
25
+ * Must stay in sync with `hermes chat --help`.
26
+ */
27
+ export declare const VALID_PROVIDERS: readonly ["auto", "openrouter", "nous", "openai-codex", "copilot", "copilot-acp", "anthropic", "huggingface", "zai", "kimi-coding", "minimax", "minimax-cn", "kilocode"];
28
+ /**
29
+ * Model-name prefix → provider hint mapping.
30
+ * Used when no explicit provider is configured and we need to infer
31
+ * the correct provider from the model string alone.
32
+ *
33
+ * Keys are lowercased prefix patterns; values must be valid provider names.
34
+ * Longer prefixes are matched first (order matters).
35
+ */
36
+ export declare const MODEL_PREFIX_PROVIDER_HINTS: [string, string][];
37
+ /** Regex to extract session ID from Hermes CLI output. */
38
+ export declare const SESSION_ID_REGEX: RegExp;
39
+ /** Regex to extract token usage from Hermes output. */
40
+ export declare const TOKEN_USAGE_REGEX: RegExp;
41
+ /** Regex to extract cost from Hermes output. */
42
+ export declare const COST_REGEX: RegExp;
43
+ /** Prefix used by Hermes for tool output lines. */
44
+ export declare const TOOL_OUTPUT_PREFIX = "\u250A";
45
+ /** Prefix for Hermes thinking blocks. */
46
+ export declare const THINKING_PREFIX = "\uD83D\uDCAD";
47
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/shared/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,yDAAyD;AACzD,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAE3C,sDAAsD;AACtD,eAAO,MAAM,aAAa,iBAAiB,CAAC;AAE5C,+BAA+B;AAC/B,eAAO,MAAM,UAAU,WAAW,CAAC;AAEnC,4DAA4D;AAC5D,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAExC,2DAA2D;AAC3D,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,SAAS,CAAC;AAEpC;;;GAGG;AACH,eAAO,MAAM,eAAe,0KAclB,CAAC;AAEX;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EA8BzD,CAAC;AAEF,0DAA0D;AAC1D,eAAO,MAAM,gBAAgB,QAAmD,CAAC;AAEjF,uDAAuD;AACvD,eAAO,MAAM,iBAAiB,QACqC,CAAC;AAEpE,gDAAgD;AAChD,eAAO,MAAM,UAAU,QAAqC,CAAC;AAE7D,mDAAmD;AACnD,eAAO,MAAM,kBAAkB,WAAM,CAAC;AAEtC,yCAAyC;AACzC,eAAO,MAAM,eAAe,iBAAO,CAAC"}