@sapiom/harness 0.1.4 → 0.1.6

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 (98) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/dist/cli/bin.js +24 -7
  3. package/dist/cli/bin.js.map +1 -1
  4. package/dist/cli/consent.js +1 -1
  5. package/dist/core/adapters/adapter.d.ts +2 -2
  6. package/dist/core/api-key-provider.d.ts +79 -0
  7. package/dist/core/api-key-provider.d.ts.map +1 -0
  8. package/dist/core/api-key-provider.js +91 -0
  9. package/dist/core/api-key-provider.js.map +1 -0
  10. package/dist/core/canvas-run-state.d.ts +99 -0
  11. package/dist/core/canvas-run-state.d.ts.map +1 -0
  12. package/dist/core/canvas-run-state.js +191 -0
  13. package/dist/core/canvas-run-state.js.map +1 -0
  14. package/dist/core/canvas-svg.d.ts.map +1 -1
  15. package/dist/core/canvas-svg.js +28 -8
  16. package/dist/core/canvas-svg.js.map +1 -1
  17. package/dist/core/canvas-template.d.ts +4 -3
  18. package/dist/core/canvas-template.d.ts.map +1 -1
  19. package/dist/core/canvas-template.js +75 -3
  20. package/dist/core/canvas-template.js.map +1 -1
  21. package/dist/core/definition-slug-resolver.d.ts +46 -0
  22. package/dist/core/definition-slug-resolver.d.ts.map +1 -0
  23. package/dist/core/definition-slug-resolver.js +110 -0
  24. package/dist/core/definition-slug-resolver.js.map +1 -0
  25. package/dist/core/execution-detector.d.ts +59 -0
  26. package/dist/core/execution-detector.d.ts.map +1 -0
  27. package/dist/core/execution-detector.js +110 -0
  28. package/dist/core/execution-detector.js.map +1 -0
  29. package/dist/core/inject/mcp-config.d.ts.map +1 -1
  30. package/dist/core/inject/mcp-config.js +9 -1
  31. package/dist/core/inject/mcp-config.js.map +1 -1
  32. package/dist/core/render-local-run.d.ts +82 -0
  33. package/dist/core/render-local-run.d.ts.map +1 -0
  34. package/dist/core/render-local-run.js +105 -0
  35. package/dist/core/render-local-run.js.map +1 -0
  36. package/dist/core/render-log-slice.d.ts +30 -0
  37. package/dist/core/render-log-slice.d.ts.map +1 -0
  38. package/dist/core/render-log-slice.js +49 -0
  39. package/dist/core/render-log-slice.js.map +1 -0
  40. package/dist/core/render-run-state.d.ts +9 -0
  41. package/dist/core/render-run-state.d.ts.map +1 -0
  42. package/dist/core/render-run-state.js +120 -0
  43. package/dist/core/render-run-state.js.map +1 -0
  44. package/dist/core/run-local-bootstrap.d.ts +93 -0
  45. package/dist/core/run-local-bootstrap.d.ts.map +1 -0
  46. package/dist/core/run-local-bootstrap.js +155 -0
  47. package/dist/core/run-local-bootstrap.js.map +1 -0
  48. package/dist/core/run-state.d.ts +60 -0
  49. package/dist/core/run-state.d.ts.map +1 -0
  50. package/dist/core/run-state.js +122 -0
  51. package/dist/core/run-state.js.map +1 -0
  52. package/dist/core/stub-feedback.d.ts +52 -0
  53. package/dist/core/stub-feedback.d.ts.map +1 -0
  54. package/dist/core/stub-feedback.js +33 -0
  55. package/dist/core/stub-feedback.js.map +1 -0
  56. package/dist/core/workflow-registry.d.ts +12 -1
  57. package/dist/core/workflow-registry.d.ts.map +1 -1
  58. package/dist/core/workflow-registry.js +2 -0
  59. package/dist/core/workflow-registry.js.map +1 -1
  60. package/dist/server/actions.d.ts +139 -0
  61. package/dist/server/actions.d.ts.map +1 -0
  62. package/dist/server/actions.js +430 -0
  63. package/dist/server/actions.js.map +1 -0
  64. package/dist/server/auth-routes.d.ts +92 -0
  65. package/dist/server/auth-routes.d.ts.map +1 -0
  66. package/dist/server/auth-routes.js +151 -0
  67. package/dist/server/auth-routes.js.map +1 -0
  68. package/dist/server/index.d.ts.map +1 -1
  69. package/dist/server/index.js +0 -0
  70. package/dist/server/index.js.map +1 -1
  71. package/dist/server/rest.d.ts +5 -0
  72. package/dist/server/rest.d.ts.map +1 -1
  73. package/dist/server/rest.js +36 -12
  74. package/dist/server/rest.js.map +1 -1
  75. package/dist/server/runs.d.ts +34 -0
  76. package/dist/server/runs.d.ts.map +1 -0
  77. package/dist/server/runs.js +59 -0
  78. package/dist/server/runs.js.map +1 -0
  79. package/dist/server/static.d.ts +15 -1
  80. package/dist/server/static.d.ts.map +1 -1
  81. package/dist/server/static.js +54 -4
  82. package/dist/server/static.js.map +1 -1
  83. package/dist/shared/types.d.ts +136 -2
  84. package/dist/shared/types.d.ts.map +1 -1
  85. package/dist/shared/types.js.map +1 -1
  86. package/dist/web/assets/index-DCtyI4VW.css +32 -0
  87. package/dist/web/assets/index-WSw5RvYR.js +445 -0
  88. package/dist/web/canvas/sess-boot/index.html +305 -0
  89. package/dist/web/index.html +4 -9
  90. package/dist/web/welcome-hero-dark.png +0 -0
  91. package/dist/web/welcome-hero-light.png +0 -0
  92. package/package.json +6 -3
  93. package/dist/server/skills.d.ts +0 -51
  94. package/dist/server/skills.d.ts.map +0 -1
  95. package/dist/server/skills.js +0 -312
  96. package/dist/server/skills.js.map +0 -1
  97. package/dist/web/assets/index-BhKGSTTT.js +0 -214
  98. package/dist/web/assets/index-DRTrwTku.css +0 -32
@@ -1,312 +0,0 @@
1
- /**
2
- * Skills listing server — backs GET /api/skills and GET /api/skills/:id.
3
- *
4
- * Two skill sources are merged:
5
- * 1. Installed @sapiom packages: scans node_modules/@sapiom/{pkg}/skills/SKILL.md
6
- * (gracefully empty when no package ships skills yet).
7
- * 2. User's own ~/.claude/skills/{id}/SKILL.md (same convention Claude Code
8
- * uses for project-specific skills).
9
- *
10
- * Path-traversal safety: skill ids are slug-shaped identifiers (letters,
11
- * digits, hyphens, underscores) — any id that fails the SAFE_SLUG regex is
12
- * rejected with a 404 before any filesystem access.
13
- *
14
- * The list endpoint (GET /api/skills) does a full directory walk across both
15
- * roots. The detail endpoint (GET /api/skills/:id) resolves in O(1) by
16
- * constructing candidate paths directly from the slug (= directory name),
17
- * without re-walking the tree.
18
- *
19
- * Markdown is served as-is — the SPA renders it client-side (no HTML
20
- * injection here). The frontmatter block is stripped before delivery so the
21
- * rendered view shows only the body.
22
- */
23
- import * as fs from "node:fs/promises";
24
- import { existsSync } from "node:fs";
25
- import * as path from "node:path";
26
- import * as os from "node:os";
27
- import { createRequire } from "node:module";
28
- import { Router } from "express";
29
- import rateLimit from "express-rate-limit";
30
- /** Stable slug: only letters, digits, and hyphens/underscores. */
31
- const SAFE_SLUG = /^[a-zA-Z0-9_-]+$/;
32
- /**
33
- * Build `<root>/<slug>/SKILL.md` and return it ONLY if the resolved path stays
34
- * inside `root`. Two independent barriers against path traversal: (1) callers
35
- * validate the slug with SAFE_SLUG, and (2) this containment check on the
36
- * fully-resolved path — a defense-in-depth barrier that also makes the
37
- * no-traversal guarantee legible to static analysis (the resolved child must
38
- * sit under the resolved root + separator). Returns null if containment fails.
39
- */
40
- function resolveSkillFileWithin(root, slug) {
41
- const resolvedRoot = path.resolve(root);
42
- const candidate = path.resolve(resolvedRoot, slug, "SKILL.md");
43
- if (candidate !== path.join(resolvedRoot, slug, "SKILL.md") ||
44
- !candidate.startsWith(resolvedRoot + path.sep)) {
45
- return null;
46
- }
47
- return candidate;
48
- }
49
- /** Parse the `---\n...\n---` YAML frontmatter block (simple key: value only). */
50
- function parseFrontmatter(raw) {
51
- const meta = {};
52
- if (!raw.startsWith("---"))
53
- return { meta, body: raw };
54
- const end = raw.indexOf("\n---", 3);
55
- if (end === -1)
56
- return { meta, body: raw };
57
- const block = raw.slice(3, end).trim();
58
- for (const line of block.split("\n")) {
59
- const colon = line.indexOf(":");
60
- if (colon === -1)
61
- continue;
62
- const key = line.slice(0, colon).trim();
63
- // Strip inline quotes and leading whitespace; handle multi-line by
64
- // collapsing continuation lines (indented) into the value.
65
- const value = line.slice(colon + 1).trim().replace(/^["']|["']$/g, "");
66
- if (key)
67
- meta[key] = value;
68
- }
69
- return { meta, body: raw.slice(end + 4).trimStart() };
70
- }
71
- /** Read and parse a SKILL.md file, returning null on any fs/parse error. */
72
- async function readSkillFile(filePath, id, source) {
73
- try {
74
- const raw = await fs.readFile(filePath, "utf-8");
75
- const { meta, body } = parseFrontmatter(raw);
76
- return {
77
- id,
78
- name: meta.name ?? id,
79
- description: meta.description ?? "",
80
- source,
81
- body,
82
- filePath,
83
- };
84
- }
85
- catch {
86
- return null;
87
- }
88
- }
89
- /**
90
- * Scan node_modules/@sapiom/{pkg}/skills/{id}/SKILL.md, starting from the
91
- * given root (defaults to the directory this module lives in, walking up to
92
- * find the node_modules directory). Returns the discovered skills.
93
- */
94
- async function scanPackageSkills(nodeModulesRoot) {
95
- const nmRoot = nodeModulesRoot ?? findNodeModules();
96
- const sapiomDir = path.join(nmRoot, "@sapiom");
97
- const results = [];
98
- let pkgDirs;
99
- try {
100
- pkgDirs = await fs.readdir(sapiomDir);
101
- }
102
- catch {
103
- return results; // no @sapiom packages installed — gracefully empty
104
- }
105
- for (const pkg of pkgDirs) {
106
- const skillsDir = path.join(sapiomDir, pkg, "skills");
107
- let skillDirs;
108
- try {
109
- skillDirs = await fs.readdir(skillsDir);
110
- }
111
- catch {
112
- continue; // package has no skills directory
113
- }
114
- for (const skillDir of skillDirs) {
115
- const skillFile = path.join(skillsDir, skillDir, "SKILL.md");
116
- const parsed = await readSkillFile(skillFile, skillDir, "package");
117
- if (parsed)
118
- results.push(parsed);
119
- }
120
- }
121
- return results;
122
- }
123
- /**
124
- * Resolve the node_modules directory that actually holds the installed
125
- * @sapiom packages, robust to install layout.
126
- *
127
- * The naive "walk up from dist/server/skills.js to my own package-root's
128
- * node_modules" breaks under npm/npx HOISTING: `npx @sapiom/harness` installs
129
- * agent-core as a SIBLING in a shared node_modules (…/@sapiom/agent-core),
130
- * NOT nested under …/@sapiom/harness/node_modules — so the naive path reads an
131
- * empty (or absent) @sapiom dir and finds zero package skills.
132
- *
133
- * Use Node's own module search list (`require.resolve.paths`) for the scope
134
- * package — the node_modules dirs walking up from this file — and return the
135
- * first that actually contains `@sapiom/agent-core`. This is symlink-aware (it
136
- * stats the entry, not its realpath), so it works for BOTH npm/npx hoisting AND
137
- * pnpm workspace symlinks (where agent-core is linked under
138
- * packages/harness/node_modules, and resolving to its realpath would wrongly
139
- * point outside any node_modules). Falls back to the old relative guess, then cwd.
140
- */
141
- function findNodeModules() {
142
- try {
143
- const require = createRequire(import.meta.url);
144
- for (const p of require.resolve.paths("@sapiom/agent-core") ?? []) {
145
- if (existsSync(path.join(p, "@sapiom", "agent-core")))
146
- return p;
147
- }
148
- }
149
- catch {
150
- // agent-core unresolvable — fall through to the relative guess.
151
- }
152
- try {
153
- // Legacy fallback: dist/server/skills.js → dist/server → dist → package-root.
154
- const here = new URL(import.meta.url).pathname;
155
- return path.join(path.dirname(path.dirname(path.dirname(here))), "node_modules");
156
- }
157
- catch {
158
- return path.join(process.cwd(), "node_modules");
159
- }
160
- }
161
- /** Scan ~/.claude/skills/{id}/SKILL.md. Returns discovered skills. */
162
- async function scanUserSkills() {
163
- const skillsDir = path.join(os.homedir(), ".claude", "skills");
164
- const results = [];
165
- let skillDirs;
166
- try {
167
- skillDirs = await fs.readdir(skillsDir);
168
- }
169
- catch {
170
- return results; // directory doesn't exist — gracefully empty
171
- }
172
- for (const skillDir of skillDirs) {
173
- const skillFile = path.join(skillsDir, skillDir, "SKILL.md");
174
- const parsed = await readSkillFile(skillFile, skillDir, "user");
175
- if (parsed)
176
- results.push(parsed);
177
- }
178
- return results;
179
- }
180
- export function createSkillsRouter(options = {}) {
181
- const router = Router();
182
- // These routes touch the filesystem (skill discovery + detail reads). The
183
- // harness server is localhost-only and boot-token-gated (a single local
184
- // user), so this ceiling is far above any real interactive flow and never
185
- // fires in practice — it's a backstop that bounds a runaway/buggy client
186
- // from hammering the FS, and the explicit rate-limit control on an
187
- // FS-backed route surface.
188
- router.use(rateLimit({
189
- windowMs: 60000,
190
- limit: 240,
191
- standardHeaders: true,
192
- legacyHeaders: false,
193
- }));
194
- /**
195
- * GET /api/skills — list all discoverable skills with id, name, description,
196
- * and source. Safe: no paths are exposed; ids are directory names.
197
- */
198
- router.get("/api/skills", async (_req, res) => {
199
- try {
200
- // Personal user skills (~/.claude/skills) are OPT-IN, off by default: the
201
- // panel surfaces what Sapiom ships (e.g. sapiom-agent-authoring), not the
202
- // developer's own skills. Flip showUserSkills for a bring-your-own view.
203
- const [pkgSkills, userSkills] = await Promise.all([
204
- scanPackageSkills(options.nodeModulesRoot),
205
- options.showUserSkills
206
- ? options.userSkillsRoot
207
- ? scanUserSkillsFromRoot(options.userSkillsRoot)
208
- : scanUserSkills()
209
- : Promise.resolve([]),
210
- ]);
211
- // Dedupe by id: user skills (when enabled) win over package skills.
212
- const byId = new Map();
213
- for (const skill of [...pkgSkills, ...userSkills]) {
214
- byId.set(skill.id, { id: skill.id, name: skill.name, description: skill.description, source: skill.source });
215
- }
216
- res.json(Array.from(byId.values()));
217
- }
218
- catch (err) {
219
- res.status(500).json({ error: err.message });
220
- }
221
- });
222
- /**
223
- * GET /api/skills/:id — full detail (meta + markdown body) for a single
224
- * skill. Path-traversal safe: the id must be a safe slug (letters, digits,
225
- * hyphens, underscores only) — the slug IS the directory name, so we can
226
- * resolve it in O(1) by stat/reading `<root>/<slug>/SKILL.md` across the
227
- * two roots (user first, per collision rule) without a full directory walk.
228
- *
229
- * The slug regex + containment guard (SAFE_SLUG + the two fixed roots)
230
- * ensure no traversal is possible — a slug can never contain a path separator.
231
- */
232
- router.get("/api/skills/:id", async (req, res) => {
233
- const { id } = req.params;
234
- // Reject anything that isn't a safe slug up front — prevents any path-
235
- // traversal attempt before filesystem access.
236
- if (!id || !SAFE_SLUG.test(id)) {
237
- res.status(404).json({ error: `Unknown skill '${id}'` });
238
- return;
239
- }
240
- try {
241
- // O(1) resolution: the id is the directory name, so build the candidate
242
- // paths directly through the containment barrier. User root first (user
243
- // skills win on id collision).
244
- const userRoot = options.userSkillsRoot ??
245
- path.join(os.homedir(), ".claude", "skills");
246
- const userSkillFile = resolveSkillFileWithin(userRoot, id);
247
- // Try user skill first; fall through to package skills on null result.
248
- let found = userSkillFile
249
- ? await readSkillFile(userSkillFile, id, "user")
250
- : null;
251
- if (!found) {
252
- // Package skills: resolve the node_modules root and try each @sapiom
253
- // package's skills directory for a matching id. Still O(packages) but
254
- // avoids the full readdir of every skills subdirectory.
255
- const nmRoot = options.nodeModulesRoot ?? findNodeModules();
256
- const sapiomDir = path.join(nmRoot, "@sapiom");
257
- let pkgDirs;
258
- try {
259
- pkgDirs = await import("node:fs/promises").then((fsp) => fsp.readdir(sapiomDir));
260
- }
261
- catch {
262
- pkgDirs = [];
263
- }
264
- for (const pkg of pkgDirs) {
265
- const candidate = resolveSkillFileWithin(path.join(sapiomDir, pkg, "skills"), id);
266
- const parsed = candidate
267
- ? await readSkillFile(candidate, id, "package")
268
- : null;
269
- if (parsed) {
270
- found = parsed;
271
- break;
272
- }
273
- }
274
- }
275
- if (!found) {
276
- res.status(404).json({ error: `Unknown skill '${id}'` });
277
- return;
278
- }
279
- const detail = {
280
- id: found.id,
281
- name: found.name,
282
- description: found.description,
283
- source: found.source,
284
- body: found.body,
285
- };
286
- res.json(detail);
287
- }
288
- catch (err) {
289
- res.status(500).json({ error: err.message });
290
- }
291
- });
292
- return router;
293
- }
294
- /** Scan skills from a custom root (for testing). Same logic as scanUserSkills. */
295
- async function scanUserSkillsFromRoot(root) {
296
- const results = [];
297
- let skillDirs;
298
- try {
299
- skillDirs = await fs.readdir(root);
300
- }
301
- catch {
302
- return results;
303
- }
304
- for (const skillDir of skillDirs) {
305
- const skillFile = path.join(root, skillDir, "SKILL.md");
306
- const parsed = await readSkillFile(skillFile, skillDir, "user");
307
- if (parsed)
308
- results.push(parsed);
309
- }
310
- return results;
311
- }
312
- //# sourceMappingURL=skills.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/server/skills.ts"],"names":[],"mappings":"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"}