@loom-framework/core 0.1.0-alpha.141 → 0.1.0-alpha.142

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/dist/backend/ai/button-resolver.d.ts +1 -1
  2. package/dist/backend/ai/button-resolver.d.ts.map +1 -1
  3. package/dist/backend/ai/engine.d.ts +1 -1
  4. package/dist/backend/ai/engine.d.ts.map +1 -1
  5. package/dist/backend/ai/output-parser.d.ts +1 -1
  6. package/dist/backend/ai/output-parser.d.ts.map +1 -1
  7. package/dist/backend/ai/session-manager.d.ts +1 -1
  8. package/dist/backend/ai/session-manager.d.ts.map +1 -1
  9. package/dist/backend/index.d.ts +3 -5
  10. package/dist/backend/index.d.ts.map +1 -1
  11. package/dist/backend/index.js +3 -15
  12. package/dist/backend/index.js.map +1 -1
  13. package/dist/backend/observe/logger.d.ts +1 -4
  14. package/dist/backend/observe/logger.d.ts.map +1 -1
  15. package/dist/backend/observe/logger.js +3 -18
  16. package/dist/backend/observe/logger.js.map +1 -1
  17. package/dist/backend/routes/chat-sse.d.ts +17 -0
  18. package/dist/backend/routes/chat-sse.d.ts.map +1 -0
  19. package/dist/backend/routes/chat-sse.js +60 -0
  20. package/dist/backend/routes/chat-sse.js.map +1 -0
  21. package/dist/backend/routes/chat.d.ts +2 -6
  22. package/dist/backend/routes/chat.d.ts.map +1 -1
  23. package/dist/backend/routes/chat.js +4 -137
  24. package/dist/backend/routes/chat.js.map +1 -1
  25. package/dist/backend/routes/data.d.ts +2 -1
  26. package/dist/backend/routes/data.d.ts.map +1 -1
  27. package/dist/backend/routes/data.js +1 -1
  28. package/dist/backend/routes/data.js.map +1 -1
  29. package/dist/backend/routes/health.d.ts +1 -1
  30. package/dist/backend/routes/health.d.ts.map +1 -1
  31. package/dist/backend/routes/index.d.ts +2 -0
  32. package/dist/backend/routes/index.d.ts.map +1 -1
  33. package/dist/backend/routes/index.js +1 -0
  34. package/dist/backend/routes/index.js.map +1 -1
  35. package/dist/backend/routes/session-routes.d.ts +20 -0
  36. package/dist/backend/routes/session-routes.d.ts.map +1 -0
  37. package/dist/backend/routes/session-routes.js +94 -0
  38. package/dist/backend/routes/session-routes.js.map +1 -0
  39. package/dist/backend/routes/skill-archive.d.ts +13 -0
  40. package/dist/backend/routes/skill-archive.d.ts.map +1 -0
  41. package/dist/backend/routes/skill-archive.js +84 -0
  42. package/dist/backend/routes/skill-archive.js.map +1 -0
  43. package/dist/backend/routes/skill-parser.d.ts +41 -0
  44. package/dist/backend/routes/skill-parser.d.ts.map +1 -0
  45. package/dist/backend/routes/skill-parser.js +184 -0
  46. package/dist/backend/routes/skill-parser.js.map +1 -0
  47. package/dist/backend/routes/skill-service.d.ts +113 -0
  48. package/dist/backend/routes/skill-service.d.ts.map +1 -0
  49. package/dist/backend/routes/skill-service.js +265 -0
  50. package/dist/backend/routes/skill-service.js.map +1 -0
  51. package/dist/backend/routes/skills.d.ts +3 -0
  52. package/dist/backend/routes/skills.d.ts.map +1 -1
  53. package/dist/backend/routes/skills.js +33 -456
  54. package/dist/backend/routes/skills.js.map +1 -1
  55. package/dist/cli/commands/data.d.ts.map +1 -1
  56. package/dist/cli/commands/data.js +3 -1
  57. package/dist/cli/commands/data.js.map +1 -1
  58. package/dist/cli/commands/dev.d.ts.map +1 -1
  59. package/dist/cli/commands/dev.js +2 -1
  60. package/dist/cli/commands/dev.js.map +1 -1
  61. package/dist/cli/commands/generate-capabilities.d.ts.map +1 -1
  62. package/dist/cli/commands/generate-capabilities.js +2 -1
  63. package/dist/cli/commands/generate-capabilities.js.map +1 -1
  64. package/dist/cli/commands/generate-dashboard.d.ts.map +1 -1
  65. package/dist/cli/commands/generate-dashboard.js +2 -2
  66. package/dist/cli/commands/generate-dashboard.js.map +1 -1
  67. package/dist/cli/commands/generate-page.d.ts.map +1 -1
  68. package/dist/cli/commands/generate-page.js +4 -2
  69. package/dist/cli/commands/generate-page.js.map +1 -1
  70. package/dist/cli/helpers/app-tsx-wiring.d.ts.map +1 -1
  71. package/dist/cli/helpers/app-tsx-wiring.js +39 -24
  72. package/dist/cli/helpers/app-tsx-wiring.js.map +1 -1
  73. package/dist/cli/helpers/column-template.d.ts +3 -1
  74. package/dist/cli/helpers/column-template.d.ts.map +1 -1
  75. package/dist/cli/helpers/column-template.js +1 -1
  76. package/dist/cli/helpers/column-template.js.map +1 -1
  77. package/dist/cli/helpers/duration.d.ts +2 -2
  78. package/dist/cli/helpers/duration.d.ts.map +1 -1
  79. package/dist/cli/helpers/duration.js +2 -16
  80. package/dist/cli/helpers/duration.js.map +1 -1
  81. package/dist/cli/helpers/field-template.d.ts +1 -1
  82. package/dist/cli/helpers/field-template.d.ts.map +1 -1
  83. package/dist/cli/helpers/field-template.js +1 -1
  84. package/dist/cli/helpers/field-template.js.map +1 -1
  85. package/dist/index.d.ts +1 -1
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js.map +1 -1
  88. package/dist/types/chat.d.ts +33 -32
  89. package/dist/types/chat.d.ts.map +1 -1
  90. package/dist/types/chat.js +4 -1
  91. package/dist/types/chat.js.map +1 -1
  92. package/dist/types/index.d.ts +1 -1
  93. package/dist/types/index.d.ts.map +1 -1
  94. package/dist/utils/duration.d.ts +8 -0
  95. package/dist/utils/duration.d.ts.map +1 -0
  96. package/dist/utils/duration.js +22 -0
  97. package/dist/utils/duration.js.map +1 -0
  98. package/package.json +1 -1
@@ -8,9 +8,11 @@
8
8
  * GET /api/v1/skills/:skillName/file/:filePath — Get a file's content
9
9
  * POST /api/v1/skills/:skillName/file — Upload/replace a file in a skill
10
10
  */
11
- import { promises as fs } from 'node:fs';
12
11
  import path from 'node:path';
13
- import AdmZip from 'adm-zip';
12
+ // Re-export helpers for backward compatibility (tests import from './skills.js')
13
+ export { parseFrontmatter, scanDirFiles, safeResolve, isValidSkillName, isTextFile, getContentType, TEXT_EXTENSIONS } from './skill-parser.js';
14
+ export { parseZipArchive } from './skill-archive.js';
15
+ import { listSkills, getSkillDetail, createSkill, deleteSkill, getSkillFile, uploadSkillFile, createSkillArchive, parseSkillArchive } from './skill-service.js';
14
16
  // ── Schemas ──
15
17
  const skillNameParamSchema = {
16
18
  type: 'object',
@@ -75,495 +77,78 @@ const uploadFileBodySchema = {
75
77
  content: { type: 'string' },
76
78
  },
77
79
  };
78
- // ── Helpers ─
79
- /**
80
- * Parse YAML frontmatter from markdown content using simple regex.
81
- */
82
- function parseFrontmatter(content) {
83
- const match = content.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
84
- if (!match)
85
- return { metadata: {}, body: content };
86
- try {
87
- const metadata = {};
88
- const lines = match[1].split('\n');
89
- let currentKey = '';
90
- let currentValues = [];
91
- let inArray = false;
92
- let inBlock = false;
93
- let blockLines = [];
94
- const flushBlock = () => {
95
- if (inBlock && currentKey) {
96
- metadata[currentKey] = blockLines.join('\n').trim();
97
- }
98
- inBlock = false;
99
- blockLines = [];
100
- };
101
- for (const line of lines) {
102
- if (inBlock) {
103
- if (/^[ \t]+/.test(line) || (line === '' && blockLines.length > 0)) {
104
- blockLines.push(line.replace(/^[ \t]+/, ''));
105
- continue;
106
- }
107
- else {
108
- flushBlock();
109
- }
110
- }
111
- const trimmed = line.trim();
112
- if (!trimmed)
113
- continue;
114
- const arrayMatch = trimmed.match(/^-\s+(.+)$/);
115
- if (inArray && arrayMatch) {
116
- currentValues.push(arrayMatch[1].replace(/^['"]|['"]$/g, '').trim());
117
- continue;
118
- }
119
- if (inArray && currentKey) {
120
- metadata[currentKey] = currentValues;
121
- inArray = false;
122
- currentValues = [];
123
- }
124
- const kvMatch = trimmed.match(/^([a-zA-Z_-][a-zA-Z0-9_-]*):\s*(.*)$/);
125
- if (kvMatch) {
126
- currentKey = kvMatch[1];
127
- let val = kvMatch[2].trim();
128
- if ((val.startsWith("'") && val.endsWith("'")) || (val.startsWith('"') && val.endsWith('"'))) {
129
- val = val.slice(1, -1);
130
- }
131
- if (val === '|' || val === '>') {
132
- inBlock = true;
133
- blockLines = [];
134
- continue;
135
- }
136
- if (val === '[') {
137
- inArray = true;
138
- currentValues = [];
139
- continue;
140
- }
141
- if (val.startsWith('[') && val.endsWith(']')) {
142
- metadata[currentKey] = val.slice(1, -1).split(',').map((s) => s.trim().replace(/^['"]|['"]$/g, ''));
143
- currentKey = '';
144
- continue;
145
- }
146
- metadata[currentKey] = val;
147
- currentKey = '';
148
- }
149
- }
150
- if (inArray && currentKey) {
151
- metadata[currentKey] = currentValues;
152
- }
153
- flushBlock();
154
- return { metadata, body: match[2] || '' };
155
- }
156
- catch {
157
- return { metadata: {}, body: content };
158
- }
159
- }
160
- /**
161
- * Recursively scan a directory for files, returning relative paths.
162
- * Excludes SKILL.md (handled separately).
163
- */
164
- async function scanDirFiles(dir, base) {
165
- const results = [];
166
- let entries;
167
- try {
168
- entries = await fs.readdir(dir, { withFileTypes: true });
169
- }
170
- catch {
171
- return results;
172
- }
173
- for (const entry of entries) {
174
- if (entry.isDirectory()) {
175
- const subFiles = await scanDirFiles(path.join(dir, entry.name), base);
176
- results.push(...subFiles);
177
- }
178
- else {
179
- const relPath = path.relative(base, path.join(dir, entry.name));
180
- results.push(relPath);
181
- }
182
- }
183
- return results;
184
- }
185
- /**
186
- * Safely resolve a file path within a directory. Rejects '..' traversal.
187
- */
188
- function safeResolve(baseDir, filePath) {
189
- if (filePath.includes('..'))
190
- return null;
191
- const resolved = path.resolve(baseDir, filePath);
192
- if (!resolved.startsWith(baseDir))
193
- return null;
194
- return resolved;
195
- }
196
- /**
197
- * Validate skill name.
198
- */
199
- function isValidSkillName(name) {
200
- return /^[a-zA-Z][a-zA-Z0-9_-]*$/.test(name);
201
- }
202
- /**
203
- * Text file extensions that should be kept when parsing zip archives.
204
- */
205
- const TEXT_EXTENSIONS = new Set([
206
- '.md', '.json', '.yaml', '.yml', '.txt', '.ts', '.js', '.tsx', '.jsx',
207
- '.xml', '.html', '.css', '.sh', '.py', '.rb', '.go', '.rs', '.java',
208
- '.kt', '.swift', '.c', '.cpp', '.h', '.hpp', '.toml', '.ini', '.cfg',
209
- '.env', '.gitignore', '.prettierrc', '.eslintrc', '.conf', '.properties',
210
- ]);
211
- /**
212
- * Check if a file path looks like a text file based on extension.
213
- */
214
- function isTextFile(filePath) {
215
- const ext = path.extname(filePath).toLowerCase();
216
- if (TEXT_EXTENSIONS.has(ext))
217
- return true;
218
- // Files with no extension but common names
219
- const basename = path.basename(filePath).toLowerCase();
220
- if (['readme', 'license', 'makefile', 'dockerfile', '.gitkeep', '.gitignore'].includes(basename))
221
- return true;
222
- if (basename.startsWith('.git'))
223
- return true;
224
- return false;
225
- }
226
- /**
227
- * Parse a zip archive buffer and extract skill structure.
228
- */
229
- function parseZipArchive(buffer) {
230
- const zip = new AdmZip(buffer);
231
- const entries = zip.getEntries();
232
- // Collect valid file entries
233
- const validEntries = entries.filter((entry) => {
234
- if (entry.isDirectory)
235
- return false;
236
- const entryPath = entry.entryName;
237
- // Skip macOS metadata
238
- if (entryPath.startsWith('__MACOSX/'))
239
- return false;
240
- // Skip .DS_Store and hidden files in root
241
- const parts = entryPath.split('/');
242
- if (parts.some((p) => p.startsWith('.') && p !== '.gitkeep' && p !== '.gitignore'))
243
- return false;
244
- return true;
245
- });
246
- if (validEntries.length === 0) {
247
- throw new Error('压缩包中没有任何有效文件');
248
- }
249
- // Detect common top-level directory prefix
250
- let prefix = '';
251
- const firstEntry = validEntries[0].entryName;
252
- const slashIdx = firstEntry.indexOf('/');
253
- if (slashIdx > 0) {
254
- const candidate = firstEntry.substring(0, slashIdx + 1);
255
- if (validEntries.every((e) => e.entryName.startsWith(candidate))) {
256
- prefix = candidate;
257
- }
258
- }
259
- // Strip prefix and collect files
260
- const allFiles = [];
261
- for (const entry of validEntries) {
262
- let relPath = entry.entryName;
263
- if (prefix && relPath.startsWith(prefix)) {
264
- relPath = relPath.substring(prefix.length);
265
- }
266
- // Skip if empty after stripping prefix
267
- if (!relPath)
268
- continue;
269
- // Only keep text files
270
- if (!isTextFile(relPath))
271
- continue;
272
- const content = entry.getData().toString('utf-8');
273
- allFiles.push({ path: relPath, content });
274
- }
275
- // Find SKILL.md
276
- const skillMdEntry = allFiles.find((f) => f.path === 'SKILL.md');
277
- if (!skillMdEntry) {
278
- throw new Error('压缩包中未找到 SKILL.md 文件');
279
- }
280
- // Check for duplicate SKILL.md in subdirectories
281
- const skillMdCount = allFiles.filter((f) => path.basename(f.path) === 'SKILL.md').length;
282
- if (skillMdCount > 1) {
283
- throw new Error('压缩包中包含多个 SKILL.md 文件,请确保只有一个');
284
- }
285
- // Extract skill name from frontmatter or directory name
286
- const { metadata } = parseFrontmatter(skillMdEntry.content);
287
- let skillName = metadata.name;
288
- if (!skillName || typeof skillName !== 'string') {
289
- // Fallback to directory name from prefix
290
- if (prefix) {
291
- skillName = prefix.replace(/\/$/, '');
292
- }
293
- else {
294
- throw new Error('无法确定 Skill 名称,请在 SKILL.md 的 frontmatter 中指定 name 字段');
295
- }
296
- }
297
- // Validate skill name
298
- if (!isValidSkillName(skillName)) {
299
- throw new Error(`Skill 名称 "${skillName}" 不合法,只能包含字母、数字、中划线和下划线,且以字母开头`);
300
- }
301
- // Separate SKILL.md from other files
302
- const files = allFiles.filter((f) => f.path !== 'SKILL.md');
303
- return { skillName, skillMd: skillMdEntry.content, files };
304
- }
305
- /**
306
- * Get MIME type for a file extension.
307
- */
308
- function getContentType(filePath) {
309
- const ext = path.extname(filePath).toLowerCase();
310
- const types = {
311
- '.md': 'text/markdown',
312
- '.txt': 'text/plain',
313
- '.json': 'application/json',
314
- '.xml': 'application/xml',
315
- '.yaml': 'text/yaml',
316
- '.yml': 'text/yaml',
317
- '.ts': 'text/typescript',
318
- '.js': 'text/javascript',
319
- '.html': 'text/html',
320
- '.css': 'text/css',
321
- };
322
- return types[ext] || 'text/plain';
323
- }
324
80
  export function registerSkillRoutes(fastify, options) {
325
81
  const skillsDir = path.join(options.projectRoot, '.claude', 'skills');
326
- const ensureSkillsDir = async () => {
327
- await fs.mkdir(skillsDir, { recursive: true });
328
- };
329
82
  // ── GET /api/v1/skills ──
330
83
  fastify.get('/api/v1/skills', async (_request, reply) => {
331
- await ensureSkillsDir();
332
- let entries;
333
- try {
334
- entries = await fs.readdir(skillsDir, { withFileTypes: true });
335
- }
336
- catch {
337
- return reply.send({ data: [] });
338
- }
339
- const skills = [];
340
- for (const entry of entries) {
341
- if (!entry.isDirectory())
342
- continue;
343
- const skillDir = path.join(skillsDir, entry.name);
344
- const skillMdPath = path.join(skillDir, 'SKILL.md');
345
- let metadata = {};
346
- try {
347
- const content = await fs.readFile(skillMdPath, 'utf-8');
348
- metadata = parseFrontmatter(content).metadata;
349
- }
350
- catch {
351
- // SKILL.md doesn't exist or is unreadable
352
- }
353
- // Scan subdirectories dynamically (any folder name, not just 'references')
354
- let subDirs = [];
355
- try {
356
- const dirEntries = await fs.readdir(skillDir, { withFileTypes: true });
357
- subDirs = dirEntries.filter((e) => e.isDirectory()).map((e) => e.name);
358
- }
359
- catch {
360
- // ignore
361
- }
362
- skills.push({ name: entry.name, metadata, subDirs });
363
- }
84
+ const skills = await listSkills(skillsDir);
364
85
  return reply.send({ data: skills });
365
86
  });
366
87
  // ── POST /api/v1/skills/parse-archive ──
367
88
  fastify.post('/api/v1/skills/parse-archive', {
368
89
  schema: { body: parseArchiveBodySchema },
369
90
  }, async (request, reply) => {
370
- const body = request.body;
371
- let buffer;
372
- try {
373
- buffer = Buffer.from(body.data, 'base64');
374
- }
375
- catch {
376
- return reply.status(400).send({ error: '无效的 base64 编码' });
377
- }
378
- try {
379
- const result = parseZipArchive(buffer);
380
- return reply.send({ data: result });
381
- }
382
- catch (err) {
383
- const msg = err instanceof Error ? err.message : '解析压缩包失败';
384
- return reply.status(400).send({ error: msg });
91
+ const { data } = request.body;
92
+ const result = parseSkillArchive(data);
93
+ if (!result.ok) {
94
+ return reply.status(result.status).send({ error: result.error });
385
95
  }
96
+ return reply.send({ data: result.data });
386
97
  });
387
98
  // ── GET /api/v1/skills/:skillName ──
388
99
  fastify.get('/api/v1/skills/:skillName', {
389
100
  schema: { params: skillNameParamSchema },
390
101
  }, async (request, reply) => {
391
102
  const { skillName } = request.params;
392
- const skillDir = path.join(skillsDir, skillName);
393
- const exists = await fs.access(skillDir).then(() => true, () => false);
394
- if (!exists) {
103
+ const detail = await getSkillDetail(skillsDir, skillName);
104
+ if (!detail) {
395
105
  return reply.status(404).send({ error: `Skill "${skillName}" not found` });
396
106
  }
397
- let skillMd = '';
398
- let metadata = {};
399
- try {
400
- skillMd = await fs.readFile(path.join(skillDir, 'SKILL.md'), 'utf-8');
401
- metadata = parseFrontmatter(skillMd).metadata;
402
- }
403
- catch {
404
- // SKILL.md doesn't exist
405
- }
406
- // Dynamically scan all files in subdirectories
407
- const allFiles = await scanDirFiles(skillDir, skillDir);
408
- const files = allFiles.map((p) => ({
409
- name: path.basename(p),
410
- path: p,
411
- }));
412
- return reply.send({ data: { name: skillName, metadata, skillMd, files } });
107
+ return reply.send({ data: detail });
413
108
  });
414
109
  // ── GET /api/v1/skills/:skillName/archive ──
415
110
  fastify.get('/api/v1/skills/:skillName/archive', {
416
111
  schema: { params: skillNameParamSchema },
417
112
  }, async (request, reply) => {
418
113
  const { skillName } = request.params;
419
- const skillDir = path.join(skillsDir, skillName);
420
- const exists = await fs.access(skillDir).then(() => true, () => false);
421
- if (!exists) {
422
- return reply.status(404).send({ error: `Skill "${skillName}" not found` });
423
- }
424
- const zip = new AdmZip();
425
- // Add SKILL.md
426
- const skillMdPath = path.join(skillDir, 'SKILL.md');
427
- try {
428
- const skillMd = await fs.readFile(skillMdPath, 'utf-8');
429
- zip.addFile('SKILL.md', Buffer.from(skillMd, 'utf-8'));
430
- }
431
- catch {
432
- // SKILL.md doesn't exist, skip
433
- }
434
- // Add all other files, preserving directory structure
435
- const allFiles = await scanDirFiles(skillDir, skillDir);
436
- for (const filePath of allFiles) {
437
- if (filePath === 'SKILL.md')
438
- continue;
439
- const resolvedPath = safeResolve(skillDir, filePath);
440
- if (!resolvedPath)
441
- continue;
442
- try {
443
- const content = await fs.readFile(resolvedPath);
444
- // Store under skillName/ prefix for proper extraction
445
- zip.addFile(`${skillName}/${filePath}`, content);
446
- }
447
- catch {
448
- // skip unreadable files
449
- }
114
+ const result = await createSkillArchive(skillsDir, skillName);
115
+ if (!result.ok) {
116
+ return reply.status(result.status).send({ error: result.error });
450
117
  }
451
- // Also put SKILL.md under the prefix
452
- zip.deleteFile('SKILL.md');
453
- try {
454
- const skillMd = await fs.readFile(skillMdPath, 'utf-8');
455
- zip.addFile(`${skillName}/SKILL.md`, Buffer.from(skillMd, 'utf-8'));
456
- }
457
- catch {
458
- // skip
459
- }
460
- const zipBuffer = zip.toBuffer();
461
118
  reply.header('Content-Type', 'application/zip');
462
119
  reply.header('Content-Disposition', `attachment; filename="${skillName}.zip"`);
463
- return reply.send(zipBuffer);
120
+ return reply.send(result.buffer);
464
121
  });
465
122
  // ── GET /api/v1/skills/:skillName/file/* ──
466
123
  fastify.get('/api/v1/skills/:skillName/file/*', async (request, reply) => {
467
124
  const { skillName } = request.params;
468
125
  const filePath = request.params['*'];
469
- const skillDir = path.join(skillsDir, skillName);
470
- const exists = await fs.access(skillDir).then(() => true, () => false);
471
- if (!exists) {
472
- return reply.status(404).send({ error: `Skill "${skillName}" not found` });
473
- }
474
- const resolvedPath = safeResolve(skillDir, filePath);
475
- if (!resolvedPath) {
476
- return reply.status(400).send({ error: 'Invalid file path' });
477
- }
478
- const fileExists = await fs.access(resolvedPath).then(() => true, () => false);
479
- if (!fileExists) {
480
- return reply.status(404).send({ error: `File "${filePath}" not found` });
481
- }
482
- try {
483
- const content = await fs.readFile(resolvedPath, 'utf-8');
484
- return reply.send({ data: { content, path: filePath } });
485
- }
486
- catch (err) {
487
- return reply.status(500).send({ error: `Failed to read file: ${err}` });
126
+ const result = await getSkillFile(skillsDir, skillName, filePath);
127
+ if (!result.ok) {
128
+ return reply.status(result.status).send({ error: result.error });
488
129
  }
130
+ return reply.send({ data: { content: result.content, path: result.path } });
489
131
  });
490
132
  // ── POST /api/v1/skills ──
491
133
  fastify.post('/api/v1/skills', {
492
134
  schema: { body: createSkillBodySchema },
493
135
  }, async (request, reply) => {
494
136
  const body = request.body;
495
- const { name, skillMd, references, scripts: scriptFiles, files: archiveFiles } = body;
496
- if (!isValidSkillName(name)) {
497
- return reply.status(400).send({ error: 'Invalid skill name. Use alphanumeric, hyphens, and underscores only.' });
498
- }
499
- const skillDir = path.join(skillsDir, name);
500
- const exists = await fs.access(skillDir).then(() => true, () => false);
501
- if (exists) {
502
- return reply.status(409).send({ error: `Skill "${name}" already exists` });
137
+ const result = await createSkill(skillsDir, body);
138
+ if (!result.created) {
139
+ return reply.status(result.status).send({ error: result.error });
503
140
  }
504
- await fs.mkdir(skillDir, { recursive: true });
505
- const contentToWrite = skillMd || `---
506
- name: ${name}
507
- description: ''
508
- version: 1.0.0
509
- ---
510
-
511
- # ${name}
512
-
513
- ## Overview
514
-
515
- [Describe what this skill does]
516
-
517
- ## Usage Scenarios
518
-
519
- - "User prompt" → [what the skill does]
520
- `;
521
- await fs.writeFile(path.join(skillDir, 'SKILL.md'), contentToWrite, 'utf-8');
522
- if (references && references.length > 0) {
523
- const refDir = path.join(skillDir, 'references');
524
- await fs.mkdir(refDir, { recursive: true });
525
- for (const ref of references) {
526
- const safePath = safeResolve(refDir, ref.name);
527
- if (safePath) {
528
- await fs.mkdir(path.dirname(safePath), { recursive: true });
529
- await fs.writeFile(safePath, ref.content, 'utf-8');
530
- }
531
- }
532
- }
533
- if (scriptFiles && scriptFiles.length > 0) {
534
- const scriptsDir = path.join(skillDir, 'scripts');
535
- await fs.mkdir(scriptsDir, { recursive: true });
536
- for (const script of scriptFiles) {
537
- const safePath = safeResolve(scriptsDir, script.name);
538
- if (safePath) {
539
- await fs.mkdir(path.dirname(safePath), { recursive: true });
540
- await fs.writeFile(safePath, script.content, 'utf-8');
541
- }
542
- }
543
- }
544
- if (archiveFiles && archiveFiles.length > 0) {
545
- for (const file of archiveFiles) {
546
- const safePath = safeResolve(skillDir, file.path);
547
- if (safePath) {
548
- await fs.mkdir(path.dirname(safePath), { recursive: true });
549
- await fs.writeFile(safePath, file.content, 'utf-8');
550
- }
551
- }
552
- }
553
- const metadata = parseFrontmatter(contentToWrite).metadata;
554
- return reply.code(201).send({ data: { name, metadata } });
141
+ return reply.code(201).send({ data: result.info });
555
142
  });
556
143
  // ── DELETE /api/v1/skills/:skillName ──
557
144
  fastify.delete('/api/v1/skills/:skillName', {
558
145
  schema: { params: skillNameParamSchema },
559
146
  }, async (request, reply) => {
560
147
  const { skillName } = request.params;
561
- const skillDir = path.join(skillsDir, skillName);
562
- const exists = await fs.access(skillDir).then(() => true, () => false);
563
- if (!exists) {
564
- return reply.status(404).send({ error: `Skill "${skillName}" not found` });
148
+ const result = await deleteSkill(skillsDir, skillName);
149
+ if (!result.ok) {
150
+ return reply.status(result.status).send({ error: result.error });
565
151
  }
566
- await fs.rm(skillDir, { recursive: true, force: true });
567
152
  return reply.send({ success: true });
568
153
  });
569
154
  // ── POST /api/v1/skills/:skillName/file ──
@@ -571,20 +156,12 @@ version: 1.0.0
571
156
  schema: { params: skillNameParamSchema, body: uploadFileBodySchema },
572
157
  }, async (request, reply) => {
573
158
  const { skillName } = request.params;
574
- const body = request.body;
575
- const { filename, content } = body;
576
- const skillDir = path.join(skillsDir, skillName);
577
- const exists = await fs.access(skillDir).then(() => true, () => false);
578
- if (!exists) {
579
- return reply.status(404).send({ error: `Skill "${skillName}" not found` });
580
- }
581
- const resolvedPath = safeResolve(skillDir, filename);
582
- if (!resolvedPath) {
583
- return reply.status(400).send({ error: 'Invalid file path' });
159
+ const { filename, content } = request.body;
160
+ const result = await uploadSkillFile(skillsDir, skillName, filename, content);
161
+ if (!result.ok) {
162
+ return reply.status(result.status).send({ error: result.error });
584
163
  }
585
- await fs.mkdir(path.dirname(resolvedPath), { recursive: true });
586
- await fs.writeFile(resolvedPath, content, 'utf-8');
587
- return reply.send({ success: true, path: filename });
164
+ return reply.send({ success: true, path: result.path });
588
165
  });
589
166
  }
590
167
  //# sourceMappingURL=skills.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../../src/backend/routes/skills.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../../src/backend/routes/skills.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/data.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA8H1D"}
1
+ {"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/data.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASzC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA8H1D"}
@@ -8,7 +8,9 @@
8
8
  * loom data schema [model]
9
9
  */
10
10
  import chalk from 'chalk';
11
- import { loadConfig, FileSystemAdapter, SQLiteAdapter } from '../../index.js';
11
+ import { loadConfig } from '../../config.js';
12
+ import { FileSystemAdapter } from '../../adapter-filesystem.js';
13
+ import { SQLiteAdapter } from '../../adapter-sqlite.js';
12
14
  import { resolveProjectRoot } from '../utils.js';
13
15
  import path from 'path';
14
16
  export function registerDataCommand(program) {