@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.
- package/dist/backend/ai/button-resolver.d.ts +1 -1
- package/dist/backend/ai/button-resolver.d.ts.map +1 -1
- package/dist/backend/ai/engine.d.ts +1 -1
- package/dist/backend/ai/engine.d.ts.map +1 -1
- package/dist/backend/ai/output-parser.d.ts +1 -1
- package/dist/backend/ai/output-parser.d.ts.map +1 -1
- package/dist/backend/ai/session-manager.d.ts +1 -1
- package/dist/backend/ai/session-manager.d.ts.map +1 -1
- package/dist/backend/index.d.ts +3 -5
- package/dist/backend/index.d.ts.map +1 -1
- package/dist/backend/index.js +3 -15
- package/dist/backend/index.js.map +1 -1
- package/dist/backend/observe/logger.d.ts +1 -4
- package/dist/backend/observe/logger.d.ts.map +1 -1
- package/dist/backend/observe/logger.js +3 -18
- package/dist/backend/observe/logger.js.map +1 -1
- package/dist/backend/routes/chat-sse.d.ts +17 -0
- package/dist/backend/routes/chat-sse.d.ts.map +1 -0
- package/dist/backend/routes/chat-sse.js +60 -0
- package/dist/backend/routes/chat-sse.js.map +1 -0
- package/dist/backend/routes/chat.d.ts +2 -6
- package/dist/backend/routes/chat.d.ts.map +1 -1
- package/dist/backend/routes/chat.js +4 -137
- package/dist/backend/routes/chat.js.map +1 -1
- package/dist/backend/routes/data.d.ts +2 -1
- package/dist/backend/routes/data.d.ts.map +1 -1
- package/dist/backend/routes/data.js +1 -1
- package/dist/backend/routes/data.js.map +1 -1
- package/dist/backend/routes/health.d.ts +1 -1
- package/dist/backend/routes/health.d.ts.map +1 -1
- package/dist/backend/routes/index.d.ts +2 -0
- package/dist/backend/routes/index.d.ts.map +1 -1
- package/dist/backend/routes/index.js +1 -0
- package/dist/backend/routes/index.js.map +1 -1
- package/dist/backend/routes/session-routes.d.ts +20 -0
- package/dist/backend/routes/session-routes.d.ts.map +1 -0
- package/dist/backend/routes/session-routes.js +94 -0
- package/dist/backend/routes/session-routes.js.map +1 -0
- package/dist/backend/routes/skill-archive.d.ts +13 -0
- package/dist/backend/routes/skill-archive.d.ts.map +1 -0
- package/dist/backend/routes/skill-archive.js +84 -0
- package/dist/backend/routes/skill-archive.js.map +1 -0
- package/dist/backend/routes/skill-parser.d.ts +41 -0
- package/dist/backend/routes/skill-parser.d.ts.map +1 -0
- package/dist/backend/routes/skill-parser.js +184 -0
- package/dist/backend/routes/skill-parser.js.map +1 -0
- package/dist/backend/routes/skill-service.d.ts +113 -0
- package/dist/backend/routes/skill-service.d.ts.map +1 -0
- package/dist/backend/routes/skill-service.js +265 -0
- package/dist/backend/routes/skill-service.js.map +1 -0
- package/dist/backend/routes/skills.d.ts +3 -0
- package/dist/backend/routes/skills.d.ts.map +1 -1
- package/dist/backend/routes/skills.js +33 -456
- package/dist/backend/routes/skills.js.map +1 -1
- package/dist/cli/commands/data.d.ts.map +1 -1
- package/dist/cli/commands/data.js +3 -1
- package/dist/cli/commands/data.js.map +1 -1
- package/dist/cli/commands/dev.d.ts.map +1 -1
- package/dist/cli/commands/dev.js +2 -1
- package/dist/cli/commands/dev.js.map +1 -1
- package/dist/cli/commands/generate-capabilities.d.ts.map +1 -1
- package/dist/cli/commands/generate-capabilities.js +2 -1
- package/dist/cli/commands/generate-capabilities.js.map +1 -1
- package/dist/cli/commands/generate-dashboard.d.ts.map +1 -1
- package/dist/cli/commands/generate-dashboard.js +2 -2
- package/dist/cli/commands/generate-dashboard.js.map +1 -1
- package/dist/cli/commands/generate-page.d.ts.map +1 -1
- package/dist/cli/commands/generate-page.js +4 -2
- package/dist/cli/commands/generate-page.js.map +1 -1
- package/dist/cli/helpers/app-tsx-wiring.d.ts.map +1 -1
- package/dist/cli/helpers/app-tsx-wiring.js +39 -24
- package/dist/cli/helpers/app-tsx-wiring.js.map +1 -1
- package/dist/cli/helpers/column-template.d.ts +3 -1
- package/dist/cli/helpers/column-template.d.ts.map +1 -1
- package/dist/cli/helpers/column-template.js +1 -1
- package/dist/cli/helpers/column-template.js.map +1 -1
- package/dist/cli/helpers/duration.d.ts +2 -2
- package/dist/cli/helpers/duration.d.ts.map +1 -1
- package/dist/cli/helpers/duration.js +2 -16
- package/dist/cli/helpers/duration.js.map +1 -1
- package/dist/cli/helpers/field-template.d.ts +1 -1
- package/dist/cli/helpers/field-template.d.ts.map +1 -1
- package/dist/cli/helpers/field-template.js +1 -1
- package/dist/cli/helpers/field-template.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/types/chat.d.ts +33 -32
- package/dist/types/chat.d.ts.map +1 -1
- package/dist/types/chat.js +4 -1
- package/dist/types/chat.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/duration.d.ts +8 -0
- package/dist/utils/duration.d.ts.map +1 -0
- package/dist/utils/duration.js +22 -0
- package/dist/utils/duration.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/** Skill business logic — filesystem operations independent of Fastify */
|
|
2
|
+
import type { SkillMetadata } from './skill-parser.js';
|
|
3
|
+
import { parseZipArchive } from './skill-archive.js';
|
|
4
|
+
export interface SkillInfo {
|
|
5
|
+
name: string;
|
|
6
|
+
metadata: SkillMetadata;
|
|
7
|
+
subDirs: string[];
|
|
8
|
+
}
|
|
9
|
+
export interface SkillDetail {
|
|
10
|
+
name: string;
|
|
11
|
+
metadata: SkillMetadata;
|
|
12
|
+
skillMd: string;
|
|
13
|
+
files: {
|
|
14
|
+
name: string;
|
|
15
|
+
path: string;
|
|
16
|
+
}[];
|
|
17
|
+
}
|
|
18
|
+
export interface CreateSkillBody {
|
|
19
|
+
name: string;
|
|
20
|
+
skillMd?: string;
|
|
21
|
+
references?: Array<{
|
|
22
|
+
name: string;
|
|
23
|
+
content: string;
|
|
24
|
+
}>;
|
|
25
|
+
scripts?: Array<{
|
|
26
|
+
name: string;
|
|
27
|
+
content: string;
|
|
28
|
+
}>;
|
|
29
|
+
files?: Array<{
|
|
30
|
+
path: string;
|
|
31
|
+
content: string;
|
|
32
|
+
}>;
|
|
33
|
+
}
|
|
34
|
+
export interface UploadFileBody {
|
|
35
|
+
filename: string;
|
|
36
|
+
content: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* List all skills with metadata.
|
|
40
|
+
*/
|
|
41
|
+
export declare function listSkills(skillsDir: string): Promise<SkillInfo[]>;
|
|
42
|
+
/**
|
|
43
|
+
* Get detailed information about a single skill.
|
|
44
|
+
*/
|
|
45
|
+
export declare function getSkillDetail(skillsDir: string, skillName: string): Promise<SkillDetail | null>;
|
|
46
|
+
/**
|
|
47
|
+
* Create a new skill directory with SKILL.md and optional files.
|
|
48
|
+
* Returns the created skill info, or throws on conflict / invalid name.
|
|
49
|
+
*/
|
|
50
|
+
export declare function createSkill(skillsDir: string, body: CreateSkillBody): Promise<{
|
|
51
|
+
created: true;
|
|
52
|
+
info: SkillInfo;
|
|
53
|
+
} | {
|
|
54
|
+
created: false;
|
|
55
|
+
status: number;
|
|
56
|
+
error: string;
|
|
57
|
+
}>;
|
|
58
|
+
/**
|
|
59
|
+
* Delete a skill directory.
|
|
60
|
+
*/
|
|
61
|
+
export declare function deleteSkill(skillsDir: string, skillName: string): Promise<{
|
|
62
|
+
ok: true;
|
|
63
|
+
} | {
|
|
64
|
+
ok: false;
|
|
65
|
+
status: number;
|
|
66
|
+
error: string;
|
|
67
|
+
}>;
|
|
68
|
+
/**
|
|
69
|
+
* Read a file within a skill directory.
|
|
70
|
+
*/
|
|
71
|
+
export declare function getSkillFile(skillsDir: string, skillName: string, filePath: string): Promise<{
|
|
72
|
+
ok: true;
|
|
73
|
+
content: string;
|
|
74
|
+
path: string;
|
|
75
|
+
} | {
|
|
76
|
+
ok: false;
|
|
77
|
+
status: number;
|
|
78
|
+
error: string;
|
|
79
|
+
}>;
|
|
80
|
+
/**
|
|
81
|
+
* Upload/replace a file in a skill directory.
|
|
82
|
+
*/
|
|
83
|
+
export declare function uploadSkillFile(skillsDir: string, skillName: string, filename: string, content: string): Promise<{
|
|
84
|
+
ok: true;
|
|
85
|
+
path: string;
|
|
86
|
+
} | {
|
|
87
|
+
ok: false;
|
|
88
|
+
status: number;
|
|
89
|
+
error: string;
|
|
90
|
+
}>;
|
|
91
|
+
/**
|
|
92
|
+
* Create a ZIP archive of a skill directory.
|
|
93
|
+
*/
|
|
94
|
+
export declare function createSkillArchive(skillsDir: string, skillName: string): Promise<{
|
|
95
|
+
ok: true;
|
|
96
|
+
buffer: Buffer;
|
|
97
|
+
} | {
|
|
98
|
+
ok: false;
|
|
99
|
+
status: number;
|
|
100
|
+
error: string;
|
|
101
|
+
}>;
|
|
102
|
+
/**
|
|
103
|
+
* Parse a base64-encoded ZIP archive and extract skill structure.
|
|
104
|
+
*/
|
|
105
|
+
export declare function parseSkillArchive(base64Data: string): {
|
|
106
|
+
ok: true;
|
|
107
|
+
data: ReturnType<typeof parseZipArchive>;
|
|
108
|
+
} | {
|
|
109
|
+
ok: false;
|
|
110
|
+
status: number;
|
|
111
|
+
error: string;
|
|
112
|
+
};
|
|
113
|
+
//# sourceMappingURL=skill-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-service.d.ts","sourceRoot":"","sources":["../../../src/backend/routes/skill-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
/** Skill business logic — filesystem operations independent of Fastify */
|
|
2
|
+
import { promises as fs } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import AdmZip from 'adm-zip';
|
|
5
|
+
import { parseFrontmatter, scanDirFiles, safeResolve, isValidSkillName } from './skill-parser.js';
|
|
6
|
+
import { parseZipArchive } from './skill-archive.js';
|
|
7
|
+
// ── Service functions ──
|
|
8
|
+
/**
|
|
9
|
+
* Ensure the skills directory exists.
|
|
10
|
+
*/
|
|
11
|
+
async function ensureSkillsDir(skillsDir) {
|
|
12
|
+
await fs.mkdir(skillsDir, { recursive: true });
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* List all skills with metadata.
|
|
16
|
+
*/
|
|
17
|
+
export async function listSkills(skillsDir) {
|
|
18
|
+
await ensureSkillsDir(skillsDir);
|
|
19
|
+
let entries;
|
|
20
|
+
try {
|
|
21
|
+
entries = await fs.readdir(skillsDir, { withFileTypes: true });
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
const skills = [];
|
|
27
|
+
for (const entry of entries) {
|
|
28
|
+
if (!entry.isDirectory())
|
|
29
|
+
continue;
|
|
30
|
+
const skillDir = path.join(skillsDir, entry.name);
|
|
31
|
+
const skillMdPath = path.join(skillDir, 'SKILL.md');
|
|
32
|
+
let metadata = {};
|
|
33
|
+
try {
|
|
34
|
+
const content = await fs.readFile(skillMdPath, 'utf-8');
|
|
35
|
+
metadata = parseFrontmatter(content).metadata;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// SKILL.md doesn't exist or is unreadable
|
|
39
|
+
}
|
|
40
|
+
// Scan subdirectories dynamically (any folder name, not just 'references')
|
|
41
|
+
let subDirs = [];
|
|
42
|
+
try {
|
|
43
|
+
const dirEntries = await fs.readdir(skillDir, { withFileTypes: true });
|
|
44
|
+
subDirs = dirEntries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// ignore
|
|
48
|
+
}
|
|
49
|
+
skills.push({ name: entry.name, metadata, subDirs });
|
|
50
|
+
}
|
|
51
|
+
return skills;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get detailed information about a single skill.
|
|
55
|
+
*/
|
|
56
|
+
export async function getSkillDetail(skillsDir, skillName) {
|
|
57
|
+
const skillDir = path.join(skillsDir, skillName);
|
|
58
|
+
const exists = await fs.access(skillDir).then(() => true, () => false);
|
|
59
|
+
if (!exists)
|
|
60
|
+
return null;
|
|
61
|
+
let skillMd = '';
|
|
62
|
+
let metadata = {};
|
|
63
|
+
try {
|
|
64
|
+
skillMd = await fs.readFile(path.join(skillDir, 'SKILL.md'), 'utf-8');
|
|
65
|
+
metadata = parseFrontmatter(skillMd).metadata;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// SKILL.md doesn't exist
|
|
69
|
+
}
|
|
70
|
+
// Dynamically scan all files in subdirectories
|
|
71
|
+
const allFiles = await scanDirFiles(skillDir, skillDir);
|
|
72
|
+
const files = allFiles.map((p) => ({
|
|
73
|
+
name: path.basename(p),
|
|
74
|
+
path: p,
|
|
75
|
+
}));
|
|
76
|
+
return { name: skillName, metadata, skillMd, files };
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Create a new skill directory with SKILL.md and optional files.
|
|
80
|
+
* Returns the created skill info, or throws on conflict / invalid name.
|
|
81
|
+
*/
|
|
82
|
+
export async function createSkill(skillsDir, body) {
|
|
83
|
+
const { name, skillMd, references, scripts: scriptFiles, files: archiveFiles } = body;
|
|
84
|
+
if (!isValidSkillName(name)) {
|
|
85
|
+
return { created: false, status: 400, error: 'Invalid skill name. Use alphanumeric, hyphens, and underscores only.' };
|
|
86
|
+
}
|
|
87
|
+
const skillDir = path.join(skillsDir, name);
|
|
88
|
+
const exists = await fs.access(skillDir).then(() => true, () => false);
|
|
89
|
+
if (exists) {
|
|
90
|
+
return { created: false, status: 409, error: `Skill "${name}" already exists` };
|
|
91
|
+
}
|
|
92
|
+
await fs.mkdir(skillDir, { recursive: true });
|
|
93
|
+
const contentToWrite = skillMd || `---
|
|
94
|
+
name: ${name}
|
|
95
|
+
description: ''
|
|
96
|
+
version: 1.0.0
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
# ${name}
|
|
100
|
+
|
|
101
|
+
## Overview
|
|
102
|
+
|
|
103
|
+
[Describe what this skill does]
|
|
104
|
+
|
|
105
|
+
## Usage Scenarios
|
|
106
|
+
|
|
107
|
+
- "User prompt" → [what the skill does]
|
|
108
|
+
`;
|
|
109
|
+
await fs.writeFile(path.join(skillDir, 'SKILL.md'), contentToWrite, 'utf-8');
|
|
110
|
+
if (references && references.length > 0) {
|
|
111
|
+
const refDir = path.join(skillDir, 'references');
|
|
112
|
+
await fs.mkdir(refDir, { recursive: true });
|
|
113
|
+
for (const ref of references) {
|
|
114
|
+
const safePath = safeResolve(refDir, ref.name);
|
|
115
|
+
if (safePath) {
|
|
116
|
+
await fs.mkdir(path.dirname(safePath), { recursive: true });
|
|
117
|
+
await fs.writeFile(safePath, ref.content, 'utf-8');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (scriptFiles && scriptFiles.length > 0) {
|
|
122
|
+
const scriptsDir = path.join(skillDir, 'scripts');
|
|
123
|
+
await fs.mkdir(scriptsDir, { recursive: true });
|
|
124
|
+
for (const script of scriptFiles) {
|
|
125
|
+
const safePath = safeResolve(scriptsDir, script.name);
|
|
126
|
+
if (safePath) {
|
|
127
|
+
await fs.mkdir(path.dirname(safePath), { recursive: true });
|
|
128
|
+
await fs.writeFile(safePath, script.content, 'utf-8');
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (archiveFiles && archiveFiles.length > 0) {
|
|
133
|
+
for (const file of archiveFiles) {
|
|
134
|
+
const safePath = safeResolve(skillDir, file.path);
|
|
135
|
+
if (safePath) {
|
|
136
|
+
await fs.mkdir(path.dirname(safePath), { recursive: true });
|
|
137
|
+
await fs.writeFile(safePath, file.content, 'utf-8');
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
const metadata = parseFrontmatter(contentToWrite).metadata;
|
|
142
|
+
return { created: true, info: { name, metadata, subDirs: [] } };
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Delete a skill directory.
|
|
146
|
+
*/
|
|
147
|
+
export async function deleteSkill(skillsDir, skillName) {
|
|
148
|
+
const skillDir = path.join(skillsDir, skillName);
|
|
149
|
+
const exists = await fs.access(skillDir).then(() => true, () => false);
|
|
150
|
+
if (!exists) {
|
|
151
|
+
return { ok: false, status: 404, error: `Skill "${skillName}" not found` };
|
|
152
|
+
}
|
|
153
|
+
await fs.rm(skillDir, { recursive: true, force: true });
|
|
154
|
+
return { ok: true };
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Read a file within a skill directory.
|
|
158
|
+
*/
|
|
159
|
+
export async function getSkillFile(skillsDir, skillName, filePath) {
|
|
160
|
+
const skillDir = path.join(skillsDir, skillName);
|
|
161
|
+
const exists = await fs.access(skillDir).then(() => true, () => false);
|
|
162
|
+
if (!exists) {
|
|
163
|
+
return { ok: false, status: 404, error: `Skill "${skillName}" not found` };
|
|
164
|
+
}
|
|
165
|
+
const resolvedPath = safeResolve(skillDir, filePath);
|
|
166
|
+
if (!resolvedPath) {
|
|
167
|
+
return { ok: false, status: 400, error: 'Invalid file path' };
|
|
168
|
+
}
|
|
169
|
+
const fileExists = await fs.access(resolvedPath).then(() => true, () => false);
|
|
170
|
+
if (!fileExists) {
|
|
171
|
+
return { ok: false, status: 404, error: `File "${filePath}" not found` };
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
const content = await fs.readFile(resolvedPath, 'utf-8');
|
|
175
|
+
return { ok: true, content, path: filePath };
|
|
176
|
+
}
|
|
177
|
+
catch (err) {
|
|
178
|
+
return { ok: false, status: 500, error: `Failed to read file: ${err}` };
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Upload/replace a file in a skill directory.
|
|
183
|
+
*/
|
|
184
|
+
export async function uploadSkillFile(skillsDir, skillName, filename, content) {
|
|
185
|
+
const skillDir = path.join(skillsDir, skillName);
|
|
186
|
+
const exists = await fs.access(skillDir).then(() => true, () => false);
|
|
187
|
+
if (!exists) {
|
|
188
|
+
return { ok: false, status: 404, error: `Skill "${skillName}" not found` };
|
|
189
|
+
}
|
|
190
|
+
const resolvedPath = safeResolve(skillDir, filename);
|
|
191
|
+
if (!resolvedPath) {
|
|
192
|
+
return { ok: false, status: 400, error: 'Invalid file path' };
|
|
193
|
+
}
|
|
194
|
+
await fs.mkdir(path.dirname(resolvedPath), { recursive: true });
|
|
195
|
+
await fs.writeFile(resolvedPath, content, 'utf-8');
|
|
196
|
+
return { ok: true, path: filename };
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Create a ZIP archive of a skill directory.
|
|
200
|
+
*/
|
|
201
|
+
export async function createSkillArchive(skillsDir, skillName) {
|
|
202
|
+
const skillDir = path.join(skillsDir, skillName);
|
|
203
|
+
const exists = await fs.access(skillDir).then(() => true, () => false);
|
|
204
|
+
if (!exists) {
|
|
205
|
+
return { ok: false, status: 404, error: `Skill "${skillName}" not found` };
|
|
206
|
+
}
|
|
207
|
+
const zip = new AdmZip();
|
|
208
|
+
// Add SKILL.md
|
|
209
|
+
const skillMdPath = path.join(skillDir, 'SKILL.md');
|
|
210
|
+
try {
|
|
211
|
+
const skillMd = await fs.readFile(skillMdPath, 'utf-8');
|
|
212
|
+
zip.addFile('SKILL.md', Buffer.from(skillMd, 'utf-8'));
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
// SKILL.md doesn't exist, skip
|
|
216
|
+
}
|
|
217
|
+
// Add all other files, preserving directory structure
|
|
218
|
+
const allFiles = await scanDirFiles(skillDir, skillDir);
|
|
219
|
+
for (const filePath of allFiles) {
|
|
220
|
+
if (filePath === 'SKILL.md')
|
|
221
|
+
continue;
|
|
222
|
+
const resolvedPath = safeResolve(skillDir, filePath);
|
|
223
|
+
if (!resolvedPath)
|
|
224
|
+
continue;
|
|
225
|
+
try {
|
|
226
|
+
const content = await fs.readFile(resolvedPath);
|
|
227
|
+
// Store under skillName/ prefix for proper extraction
|
|
228
|
+
zip.addFile(`${skillName}/${filePath}`, content);
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
// skip unreadable files
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
// Also put SKILL.md under the prefix
|
|
235
|
+
zip.deleteFile('SKILL.md');
|
|
236
|
+
try {
|
|
237
|
+
const skillMd = await fs.readFile(skillMdPath, 'utf-8');
|
|
238
|
+
zip.addFile(`${skillName}/SKILL.md`, Buffer.from(skillMd, 'utf-8'));
|
|
239
|
+
}
|
|
240
|
+
catch {
|
|
241
|
+
// skip
|
|
242
|
+
}
|
|
243
|
+
return { ok: true, buffer: zip.toBuffer() };
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Parse a base64-encoded ZIP archive and extract skill structure.
|
|
247
|
+
*/
|
|
248
|
+
export function parseSkillArchive(base64Data) {
|
|
249
|
+
let buffer;
|
|
250
|
+
try {
|
|
251
|
+
buffer = Buffer.from(base64Data, 'base64');
|
|
252
|
+
}
|
|
253
|
+
catch {
|
|
254
|
+
return { ok: false, status: 400, error: '无效的 base64 编码' };
|
|
255
|
+
}
|
|
256
|
+
try {
|
|
257
|
+
const result = parseZipArchive(buffer);
|
|
258
|
+
return { ok: true, data: result };
|
|
259
|
+
}
|
|
260
|
+
catch (err) {
|
|
261
|
+
const msg = err instanceof Error ? err.message : '解析压缩包失败';
|
|
262
|
+
return { ok: false, status: 400, error: msg };
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=skill-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-service.js","sourceRoot":"","sources":["../../../src/backend/routes/skill-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
* POST /api/v1/skills/:skillName/file — Upload/replace a file in a skill
|
|
10
10
|
*/
|
|
11
11
|
import type { FastifyInstance } from 'fastify';
|
|
12
|
+
export { parseFrontmatter, scanDirFiles, safeResolve, isValidSkillName, isTextFile, getContentType, TEXT_EXTENSIONS } from './skill-parser.js';
|
|
13
|
+
export type { SkillMetadata } from './skill-parser.js';
|
|
14
|
+
export { parseZipArchive } from './skill-archive.js';
|
|
12
15
|
export interface SkillRouteOptions {
|
|
13
16
|
projectRoot: string;
|
|
14
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../../src/backend/routes/skills.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../../src/backend/routes/skills.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAI/C,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC/I,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AA4ErD,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,iBAAiB,GACzB,IAAI,CA8FN"}
|