@lemoncat7/dsh-partner 1.4.1 → 1.5.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.
- package/README.md +39 -0
- package/docs/architecture.md +99 -0
- package/lib/agent-runtime.d.ts +31 -8
- package/lib/agent-runtime.d.ts.map +1 -1
- package/lib/agent-runtime.js +236 -52
- package/lib/agent-runtime.js.map +1 -1
- package/lib/api/features/workspace-api.d.ts +18 -0
- package/lib/api/features/workspace-api.d.ts.map +1 -0
- package/lib/api/features/workspace-api.js +188 -0
- package/lib/api/features/workspace-api.js.map +1 -0
- package/lib/api/http.d.ts +12 -0
- package/lib/api/http.d.ts.map +1 -0
- package/lib/api/http.js +53 -0
- package/lib/api/http.js.map +1 -0
- package/lib/api.d.ts +10 -0
- package/lib/api.d.ts.map +1 -1
- package/lib/api.js +48 -63
- package/lib/api.js.map +1 -1
- package/lib/autonomy.d.ts.map +1 -1
- package/lib/autonomy.js +2 -1
- package/lib/autonomy.js.map +1 -1
- package/lib/channels/manager.d.ts +4 -1
- package/lib/channels/manager.d.ts.map +1 -1
- package/lib/channels/manager.js +20 -3
- package/lib/channels/manager.js.map +1 -1
- package/lib/client-api.d.ts +157 -1
- package/lib/client-api.d.ts.map +1 -1
- package/lib/client-api.js.map +1 -1
- package/lib/client-controller.d.ts +15 -0
- package/lib/client-controller.d.ts.map +1 -0
- package/lib/client-controller.js +69 -0
- package/lib/client-controller.js.map +1 -0
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +2702 -885
- package/lib/client.js.map +4 -4
- package/lib/collaboration/composition.d.ts +27 -0
- package/lib/collaboration/composition.d.ts.map +1 -0
- package/lib/collaboration/composition.js +345 -0
- package/lib/collaboration/composition.js.map +1 -0
- package/lib/collaboration/domain.d.ts +38 -0
- package/lib/collaboration/domain.d.ts.map +1 -0
- package/lib/collaboration/domain.js +3 -0
- package/lib/collaboration/domain.js.map +1 -0
- package/lib/collaboration/retry-policy.d.ts +4 -0
- package/lib/collaboration/retry-policy.d.ts.map +1 -0
- package/lib/collaboration/retry-policy.js +18 -0
- package/lib/collaboration/retry-policy.js.map +1 -0
- package/lib/collaboration/service.d.ts +76 -0
- package/lib/collaboration/service.d.ts.map +1 -0
- package/lib/collaboration/service.js +370 -0
- package/lib/collaboration/service.js.map +1 -0
- package/lib/companions/service.d.ts +13 -0
- package/lib/companions/service.d.ts.map +1 -0
- package/lib/companions/service.js +51 -0
- package/lib/companions/service.js.map +1 -0
- package/lib/concern-domain.d.ts +8 -1
- package/lib/concern-domain.d.ts.map +1 -1
- package/lib/concern-domain.js +25 -1
- package/lib/concern-domain.js.map +1 -1
- package/lib/concern-store.d.ts.map +1 -1
- package/lib/concern-store.js +2 -1
- package/lib/concern-store.js.map +1 -1
- package/lib/concern-tool.d.ts +6 -0
- package/lib/concern-tool.d.ts.map +1 -1
- package/lib/concern-tool.js +35 -9
- package/lib/concern-tool.js.map +1 -1
- package/lib/core/collections.d.ts +2 -0
- package/lib/core/collections.d.ts.map +1 -0
- package/lib/core/collections.js +6 -0
- package/lib/core/collections.js.map +1 -0
- package/lib/core/semaphore.d.ts +10 -0
- package/lib/core/semaphore.d.ts.map +1 -0
- package/lib/core/semaphore.js +32 -0
- package/lib/core/semaphore.js.map +1 -0
- package/lib/core/validation.d.ts +7 -0
- package/lib/core/validation.d.ts.map +1 -0
- package/lib/core/validation.js +40 -0
- package/lib/core/validation.js.map +1 -0
- package/lib/domain.d.ts +28 -2
- package/lib/domain.d.ts.map +1 -1
- package/lib/domain.js +3 -3
- package/lib/domain.js.map +1 -1
- package/lib/execution/agent-support.d.ts +12 -0
- package/lib/execution/agent-support.d.ts.map +1 -0
- package/lib/execution/agent-support.js +48 -0
- package/lib/execution/agent-support.js.map +1 -0
- package/lib/execution/domain.d.ts +17 -0
- package/lib/execution/domain.d.ts.map +1 -0
- package/lib/execution/domain.js +2 -0
- package/lib/execution/domain.js.map +1 -0
- package/lib/execution/service.d.ts +52 -0
- package/lib/execution/service.d.ts.map +1 -0
- package/lib/execution/service.js +175 -0
- package/lib/execution/service.js.map +1 -0
- package/lib/heartbeat-command.d.ts +15 -0
- package/lib/heartbeat-command.d.ts.map +1 -0
- package/lib/heartbeat-command.js +211 -0
- package/lib/heartbeat-command.js.map +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +42 -3
- package/lib/index.js.map +1 -1
- package/lib/memory-reflection.js +2 -2
- package/lib/memory-reflection.js.map +1 -1
- package/lib/scheduler/domain.d.ts +25 -0
- package/lib/scheduler/domain.d.ts.map +1 -0
- package/lib/scheduler/domain.js +2 -0
- package/lib/scheduler/domain.js.map +1 -0
- package/lib/scheduler/service.d.ts +26 -0
- package/lib/scheduler/service.d.ts.map +1 -0
- package/lib/scheduler/service.js +177 -0
- package/lib/scheduler/service.js.map +1 -0
- package/lib/skills/builtin.d.ts +7 -0
- package/lib/skills/builtin.d.ts.map +1 -0
- package/lib/skills/builtin.js +16 -0
- package/lib/skills/builtin.js.map +1 -0
- package/lib/skills/domain.d.ts +52 -0
- package/lib/skills/domain.d.ts.map +1 -0
- package/lib/skills/domain.js +2 -0
- package/lib/skills/domain.js.map +1 -0
- package/lib/skills/loader.d.ts +18 -0
- package/lib/skills/loader.d.ts.map +1 -0
- package/lib/skills/loader.js +134 -0
- package/lib/skills/loader.js.map +1 -0
- package/lib/skills/markets/adapters.d.ts +8 -0
- package/lib/skills/markets/adapters.d.ts.map +1 -0
- package/lib/skills/markets/adapters.js +72 -0
- package/lib/skills/markets/adapters.js.map +1 -0
- package/lib/skills/markets/builtin.d.ts +10 -0
- package/lib/skills/markets/builtin.d.ts.map +1 -0
- package/lib/skills/markets/builtin.js +19 -0
- package/lib/skills/markets/builtin.js.map +1 -0
- package/lib/skills/network.d.ts +14 -0
- package/lib/skills/network.d.ts.map +1 -0
- package/lib/skills/network.js +174 -0
- package/lib/skills/network.js.map +1 -0
- package/lib/skills/repository.d.ts +17 -0
- package/lib/skills/repository.d.ts.map +1 -0
- package/lib/skills/repository.js +76 -0
- package/lib/skills/repository.js.map +1 -0
- package/lib/skills/service.d.ts +48 -0
- package/lib/skills/service.d.ts.map +1 -0
- package/lib/skills/service.js +248 -0
- package/lib/skills/service.js.map +1 -0
- package/lib/skills/zip.d.ts +3 -0
- package/lib/skills/zip.d.ts.map +1 -0
- package/lib/skills/zip.js +59 -0
- package/lib/skills/zip.js.map +1 -0
- package/lib/store.d.ts.map +1 -1
- package/lib/store.js +69 -3
- package/lib/store.js.map +1 -1
- package/lib/tasks/domain.d.ts +39 -0
- package/lib/tasks/domain.d.ts.map +1 -0
- package/lib/tasks/domain.js +3 -0
- package/lib/tasks/domain.js.map +1 -0
- package/lib/tasks/result.d.ts +14 -0
- package/lib/tasks/result.d.ts.map +1 -0
- package/lib/tasks/result.js +109 -0
- package/lib/tasks/result.js.map +1 -0
- package/lib/tasks/service.d.ts +39 -0
- package/lib/tasks/service.d.ts.map +1 -0
- package/lib/tasks/service.js +334 -0
- package/lib/tasks/service.js.map +1 -0
- package/lib/ui/companion-access-panel.d.ts +4 -0
- package/lib/ui/companion-access-panel.d.ts.map +1 -0
- package/lib/ui/companion-access-panel.js +46 -0
- package/lib/ui/companion-access-panel.js.map +1 -0
- package/lib/ui/companion-create.d.ts +11 -0
- package/lib/ui/companion-create.d.ts.map +1 -0
- package/lib/ui/companion-create.js +30 -0
- package/lib/ui/companion-create.js.map +1 -0
- package/lib/ui/partner-components.d.ts +36 -0
- package/lib/ui/partner-components.d.ts.map +1 -0
- package/lib/ui/partner-components.js +32 -0
- package/lib/ui/partner-components.js.map +1 -0
- package/lib/ui/schedule-panel.d.ts +5 -0
- package/lib/ui/schedule-panel.d.ts.map +1 -0
- package/lib/ui/schedule-panel.js +86 -0
- package/lib/ui/schedule-panel.js.map +1 -0
- package/lib/ui/skills-panel.d.ts +5 -0
- package/lib/ui/skills-panel.d.ts.map +1 -0
- package/lib/ui/skills-panel.js +236 -0
- package/lib/ui/skills-panel.js.map +1 -0
- package/lib/ui/task-board-panel.d.ts +2 -0
- package/lib/ui/task-board-panel.d.ts.map +1 -0
- package/lib/ui/task-board-panel.js +231 -0
- package/lib/ui/task-board-panel.js.map +1 -0
- package/lib/ui/workspace-components.d.ts +40 -0
- package/lib/ui/workspace-components.d.ts.map +1 -0
- package/lib/ui/workspace-components.js +61 -0
- package/lib/ui/workspace-components.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import { basename, resolve } from 'node:path';
|
|
4
|
+
import { SKILL_CONTEXTS } from './domain.js';
|
|
5
|
+
const MAX_SKILL_BYTES = 512 * 1024;
|
|
6
|
+
export async function loadSkill(input) {
|
|
7
|
+
const file = resolve(input.rootPath, 'SKILL.md');
|
|
8
|
+
const buffer = await readFile(file);
|
|
9
|
+
if (buffer.byteLength > MAX_SKILL_BYTES)
|
|
10
|
+
throw new Error('SKILL.md exceeds the 512 KiB limit');
|
|
11
|
+
const raw = buffer.toString('utf8');
|
|
12
|
+
const { metadata, body } = parseSkillDocument(raw);
|
|
13
|
+
const name = readableName(field(metadata, 'name') ?? basename(input.rootPath), 'Skill name');
|
|
14
|
+
const description = field(metadata, 'description') ?? firstSentence(body);
|
|
15
|
+
if (!description)
|
|
16
|
+
throw new Error('Skill description is required');
|
|
17
|
+
const requestedContext = enumField(metadata, 'context', SKILL_CONTEXTS) ?? 'fork';
|
|
18
|
+
const executionContext = input.trusted ? requestedContext : 'fork';
|
|
19
|
+
const skill = {
|
|
20
|
+
id: input.id,
|
|
21
|
+
name,
|
|
22
|
+
displayName: readableName(field(metadata, 'display-name') ?? name, 'Skill display name'),
|
|
23
|
+
description: description.slice(0, 600),
|
|
24
|
+
version: field(metadata, 'version') ?? '0.0.0',
|
|
25
|
+
source: input.source,
|
|
26
|
+
...(input.sourceId ? { sourceId: input.sourceId } : {}),
|
|
27
|
+
rootPath: input.rootPath,
|
|
28
|
+
checksum: sha256(raw),
|
|
29
|
+
allowedTools: listField(metadata, 'allowed-tools'),
|
|
30
|
+
executionContext,
|
|
31
|
+
userInvocable: booleanField(metadata, 'user-invocable', true),
|
|
32
|
+
trusted: input.trusted,
|
|
33
|
+
installedAt: input.installedAt,
|
|
34
|
+
updatedAt: input.updatedAt,
|
|
35
|
+
body: body.trim(),
|
|
36
|
+
};
|
|
37
|
+
if (!skill.body)
|
|
38
|
+
throw new Error('Skill body is empty');
|
|
39
|
+
return skill;
|
|
40
|
+
}
|
|
41
|
+
export function skillMetadata(skill) {
|
|
42
|
+
const { body: _body, ...metadata } = skill;
|
|
43
|
+
return metadata;
|
|
44
|
+
}
|
|
45
|
+
export function parseSkillDocument(raw) {
|
|
46
|
+
const metadata = new Map();
|
|
47
|
+
if (!raw.startsWith('---\n') && !raw.startsWith('---\r\n'))
|
|
48
|
+
return { metadata, body: raw };
|
|
49
|
+
const lines = raw.replace(/\r\n/g, '\n').split('\n');
|
|
50
|
+
const end = lines.indexOf('---', 1);
|
|
51
|
+
if (end < 0)
|
|
52
|
+
throw new Error('Skill frontmatter is not closed');
|
|
53
|
+
let listKey;
|
|
54
|
+
for (const line of lines.slice(1, end)) {
|
|
55
|
+
if (!line.trim() || line.trimStart().startsWith('#'))
|
|
56
|
+
continue;
|
|
57
|
+
const listItem = line.match(/^\s+-\s+(.+)$/u);
|
|
58
|
+
if (listItem) {
|
|
59
|
+
if (!listKey)
|
|
60
|
+
throw new Error(`Invalid Skill frontmatter list item: ${line.trim()}`);
|
|
61
|
+
const item = unquote(listItem[1].trim());
|
|
62
|
+
if (!item)
|
|
63
|
+
throw new Error(`Invalid Skill frontmatter list item: ${line.trim()}`);
|
|
64
|
+
const previous = metadata.get(listKey)?.trim();
|
|
65
|
+
metadata.set(listKey, previous ? `${previous}, ${item}` : item);
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
listKey = undefined;
|
|
69
|
+
if (/^\s/u.test(line))
|
|
70
|
+
throw new Error(`Unsupported nested Skill frontmatter line: ${line.trim()}`);
|
|
71
|
+
const separator = line.indexOf(':');
|
|
72
|
+
if (separator < 1)
|
|
73
|
+
throw new Error(`Invalid Skill frontmatter line: ${line}`);
|
|
74
|
+
const key = line.slice(0, separator).trim().toLocaleLowerCase();
|
|
75
|
+
const value = unquote(line.slice(separator + 1).trim());
|
|
76
|
+
if (metadata.has(key))
|
|
77
|
+
throw new Error(`Duplicate Skill frontmatter field: ${key}`);
|
|
78
|
+
metadata.set(key, value);
|
|
79
|
+
if (!value)
|
|
80
|
+
listKey = key;
|
|
81
|
+
}
|
|
82
|
+
return { metadata, body: lines.slice(end + 1).join('\n') };
|
|
83
|
+
}
|
|
84
|
+
export function sha256(value) {
|
|
85
|
+
return createHash('sha256').update(value).digest('hex');
|
|
86
|
+
}
|
|
87
|
+
function field(metadata, key) {
|
|
88
|
+
const value = metadata.get(key)?.trim();
|
|
89
|
+
return value || undefined;
|
|
90
|
+
}
|
|
91
|
+
function enumField(metadata, key, values) {
|
|
92
|
+
const value = field(metadata, key);
|
|
93
|
+
if (value === undefined)
|
|
94
|
+
return undefined;
|
|
95
|
+
if (!values.includes(value))
|
|
96
|
+
throw new Error(`${key} is invalid`);
|
|
97
|
+
return value;
|
|
98
|
+
}
|
|
99
|
+
function booleanField(metadata, key, fallback) {
|
|
100
|
+
const value = field(metadata, key)?.toLocaleLowerCase();
|
|
101
|
+
if (value === undefined)
|
|
102
|
+
return fallback;
|
|
103
|
+
if (value === 'true')
|
|
104
|
+
return true;
|
|
105
|
+
if (value === 'false')
|
|
106
|
+
return false;
|
|
107
|
+
throw new Error(`${key} must be true or false`);
|
|
108
|
+
}
|
|
109
|
+
function listField(metadata, key) {
|
|
110
|
+
const raw = field(metadata, key);
|
|
111
|
+
if (!raw)
|
|
112
|
+
return [];
|
|
113
|
+
const value = raw.startsWith('[') && raw.endsWith(']') ? raw.slice(1, -1) : raw;
|
|
114
|
+
return [...new Set(value.split(',').map(item => unquote(item.trim())).filter(Boolean))].slice(0, 64);
|
|
115
|
+
}
|
|
116
|
+
function unquote(value) {
|
|
117
|
+
if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'")))
|
|
118
|
+
return value.slice(1, -1);
|
|
119
|
+
return value;
|
|
120
|
+
}
|
|
121
|
+
function firstSentence(body) {
|
|
122
|
+
return body.split('\n').map(line => line.replace(/^#+\s*/, '').trim()).find(Boolean)?.slice(0, 600) ?? '';
|
|
123
|
+
}
|
|
124
|
+
function readableName(value, label) {
|
|
125
|
+
const normalized = value.trim();
|
|
126
|
+
if (!normalized)
|
|
127
|
+
throw new Error(`${label} is required`);
|
|
128
|
+
if (normalized.length > 120)
|
|
129
|
+
throw new Error(`${label} must be at most 120 characters`);
|
|
130
|
+
if (/[\u0000-\u001f\u007f]/u.test(normalized))
|
|
131
|
+
throw new Error(`${label} contains control characters`);
|
|
132
|
+
return normalized;
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/skills/loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { MarketSkillEntry, SkillMarketSource } from '../domain.js';
|
|
2
|
+
export interface MarketRequest {
|
|
3
|
+
url: string;
|
|
4
|
+
init?: RequestInit;
|
|
5
|
+
}
|
|
6
|
+
export declare function marketRequest(source: SkillMarketSource): MarketRequest;
|
|
7
|
+
export declare function parseMarketResponse(raw: unknown, source: SkillMarketSource): MarketSkillEntry[];
|
|
8
|
+
//# sourceMappingURL=adapters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapters.d.ts","sourceRoot":"","sources":["../../../src/skills/markets/adapters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAEvE,MAAM,WAAW,aAAa;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,WAAW,CAAA;CAAE;AAElE,wBAAgB,aAAa,CAAC,MAAM,EAAE,iBAAiB,GAAG,aAAa,CAGtE;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,iBAAiB,GAAG,gBAAgB,EAAE,CAK/F"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export function marketRequest(source) {
|
|
2
|
+
if (source.kind !== 'clawhub')
|
|
3
|
+
return { url: source.indexUrl };
|
|
4
|
+
return { url: source.indexUrl, init: { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ path: 'skills:listPublicPageV4', format: 'convex_encoded_json', args: [{ dir: 'desc', numItems: 100, sort: 'newest' }] }) } };
|
|
5
|
+
}
|
|
6
|
+
export function parseMarketResponse(raw, source) {
|
|
7
|
+
if (source.kind === 'dsh-index')
|
|
8
|
+
return parseDshIndex(raw, source);
|
|
9
|
+
if (source.kind === 'clawhub')
|
|
10
|
+
return parseClawHub(raw, source);
|
|
11
|
+
if (source.kind === 'loophub')
|
|
12
|
+
return parseLoopHub(raw, source);
|
|
13
|
+
return parseSkillHub(raw, source);
|
|
14
|
+
}
|
|
15
|
+
function parseClawHub(root, source) {
|
|
16
|
+
const rows = valueAt(root, ['value', 'page']) ?? valueAt(root, ['value', 'items']);
|
|
17
|
+
return bounded(rows).flatMap((row, index) => {
|
|
18
|
+
const skill = objectAt(row, 'skill');
|
|
19
|
+
const version = objectAt(row, 'latestVersion');
|
|
20
|
+
const slug = cleanId(textAt(skill, 'slug'));
|
|
21
|
+
const owner = cleanId(textAt(row, 'ownerHandle'));
|
|
22
|
+
if (!slug || !owner || skill.isSuspicious === true)
|
|
23
|
+
return [];
|
|
24
|
+
return [{ id: cleanId(`clawhub-${owner}-${slug}`) || `clawhub-${index}`, name: textAt(skill, 'displayName') || slug, description: textAt(skill, 'summary') || textAt(version, 'parsed', 'description') || 'ClawHub Skill', version: textAt(version, 'version') || '0.0.0', tags: stringList(skill.topics), skillUrl: `https://clawhub.ai/api/v1/download?slug=${encodeURIComponent(slug)}&version=${encodeURIComponent(textAt(version, 'version') || 'latest')}`, installKind: 'zip', sourceId: source.id }];
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
function parseLoopHub(root, source) {
|
|
28
|
+
return bounded(valueAt(root, ['data', 'items'])).flatMap((row, index) => {
|
|
29
|
+
const skillUrl = textAt(row, 'download_url');
|
|
30
|
+
if (!/^https:\/\/dl\.cocoloop\.cn\/bss\/skills\//.test(skillUrl))
|
|
31
|
+
return [];
|
|
32
|
+
const author = cleanId(textAt(row, 'author')) || 'community';
|
|
33
|
+
const name = textAt(row, 'name') || `LoopHub Skill ${index + 1}`;
|
|
34
|
+
return [{ id: cleanId(`loophub-${author}-${name}`) || `loophub-${index}`, name, description: textAt(row, 'brief') || textAt(row, 'subtitle') || 'LoopHub Skill', version: versionFromUrl(skillUrl), tags: [textAt(row, 'category'), textAt(row, 'security_level')].filter(Boolean), skillUrl, installKind: 'zip', sourceId: source.id }];
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function parseSkillHub(root, source) {
|
|
38
|
+
return bounded(valueAt(root, ['data', 'skills'])).flatMap((row, index) => {
|
|
39
|
+
const namespace = objectAt(row, 'namespace');
|
|
40
|
+
const canonical = textAt(namespace, 'canonicalName');
|
|
41
|
+
const handle = cleanId(textAt(namespace, 'handle'));
|
|
42
|
+
const slug = cleanId(textAt(row, 'slug'));
|
|
43
|
+
if (!handle || !slug)
|
|
44
|
+
return [];
|
|
45
|
+
return [{ id: cleanId(`skillhub-${handle}-${slug}`) || `skillhub-${index}`, name: textAt(row, 'name') || canonical || slug, description: textAt(row, 'description_zh') || textAt(row, 'description') || 'SkillHub Skill', version: textAt(row, 'version') || '0.0.0', tags: bounded(valueAt(row, ['subCategories']), 12).map(item => textAt(item, 'name')).filter(Boolean), skillUrl: `https://api.skillhub.cn/api/v1/download?slug=${encodeURIComponent(slug)}`, installKind: 'zip', sourceId: source.id }];
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function parseDshIndex(value, source) {
|
|
49
|
+
const entries = Array.isArray(value) ? value : object(value).skills;
|
|
50
|
+
if (!Array.isArray(entries) || entries.length > 2000)
|
|
51
|
+
throw new Error('Skill market index must contain at most 2000 skills');
|
|
52
|
+
const base = new URL(source.indexUrl);
|
|
53
|
+
return entries.map(item => {
|
|
54
|
+
const row = object(item);
|
|
55
|
+
const id = required(row.id, 'id', 120);
|
|
56
|
+
const skillUrl = new URL(required(row.skillUrl, 'skillUrl', 2000), base).toString();
|
|
57
|
+
const checksum = typeof row.checksum === 'string' && row.checksum.trim() ? row.checksum.trim() : undefined;
|
|
58
|
+
return { id, name: required(row.name, 'name', 120), description: required(row.description, 'description', 600), version: typeof row.version === 'string' ? row.version.slice(0, 80) : '0.0.0', tags: stringList(row.tags), skillUrl, installKind: 'markdown', ...(checksum ? { checksum } : {}), sourceId: source.id };
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function bounded(value, max = 200) { return Array.isArray(value) ? value.slice(0, max).filter(item => typeof item === 'object' && item !== null && !Array.isArray(item)) : []; }
|
|
62
|
+
function object(value) { return typeof value === 'object' && value !== null && !Array.isArray(value) ? value : {}; }
|
|
63
|
+
function objectAt(value, key) { return object(object(value)[key]); }
|
|
64
|
+
function valueAt(value, path) { let current = value; for (const key of path)
|
|
65
|
+
current = object(current)[key]; return current; }
|
|
66
|
+
function textAt(value, ...path) { const result = valueAt(value, path); return typeof result === 'string' ? result.trim().slice(0, 600) : ''; }
|
|
67
|
+
function stringList(value) { return Array.isArray(value) ? value.filter((item) => typeof item === 'string').map(item => item.trim().slice(0, 40)).filter(Boolean).slice(0, 20) : []; }
|
|
68
|
+
function cleanId(value) { return value.trim().toLocaleLowerCase().replace(/[^a-z0-9._-]+/g, '-').replace(/^[._-]+|[._-]+$/g, '').slice(0, 120); }
|
|
69
|
+
function required(value, label, max) { if (typeof value !== 'string' || !value.trim())
|
|
70
|
+
throw new Error(`${label} is required`); return value.trim().slice(0, max); }
|
|
71
|
+
function versionFromUrl(url) { return url.match(/-(\d+\.\d+\.\d+)\.zip(?:$|\?)/)?.[1] ?? '0.0.0'; }
|
|
72
|
+
//# sourceMappingURL=adapters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapters.js","sourceRoot":"","sources":["../../../src/skills/markets/adapters.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { SkillMarketSource } from '../domain.js';
|
|
2
|
+
export declare const BUILTIN_MARKET_IDS: {
|
|
3
|
+
readonly clawhub: "market-clawhub";
|
|
4
|
+
readonly loophub: "market-loophub";
|
|
5
|
+
readonly skillhub: "market-skillhub";
|
|
6
|
+
};
|
|
7
|
+
/** Public Skill rankings built into nomifun's Skill market. */
|
|
8
|
+
export declare function builtinMarketSources(now?: number): SkillMarketSource[];
|
|
9
|
+
export declare function mergeBuiltinMarketSources(sources: SkillMarketSource[], now?: number): SkillMarketSource[];
|
|
10
|
+
//# sourceMappingURL=builtin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builtin.d.ts","sourceRoot":"","sources":["../../../src/skills/markets/builtin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAErD,eAAO,MAAM,kBAAkB;;;;CAIrB,CAAA;AAEV,+DAA+D;AAC/D,wBAAgB,oBAAoB,CAAC,GAAG,SAAa,GAAG,iBAAiB,EAAE,CAM1E;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,iBAAiB,EAAE,EAAE,GAAG,SAAa,GAAG,iBAAiB,EAAE,CAI7G"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const BUILTIN_MARKET_IDS = {
|
|
2
|
+
clawhub: 'market-clawhub',
|
|
3
|
+
loophub: 'market-loophub',
|
|
4
|
+
skillhub: 'market-skillhub',
|
|
5
|
+
};
|
|
6
|
+
/** Public Skill rankings built into nomifun's Skill market. */
|
|
7
|
+
export function builtinMarketSources(now = Date.now()) {
|
|
8
|
+
return [
|
|
9
|
+
{ id: BUILTIN_MARKET_IDS.clawhub, name: 'ClawHub', kind: 'clawhub', indexUrl: 'https://wry-manatee-359.convex.cloud/api/query', enabled: true, trusted: false, builtin: true, createdAt: now, updatedAt: now },
|
|
10
|
+
{ id: BUILTIN_MARKET_IDS.loophub, name: 'LoopHub', kind: 'loophub', indexUrl: 'https://api.cocoloop.cn/api/v1/store/skills?page=1&page_size=100&sort=downloads&tab=overall', enabled: true, trusted: false, builtin: true, createdAt: now, updatedAt: now },
|
|
11
|
+
{ id: BUILTIN_MARKET_IDS.skillhub, name: 'SkillHub', kind: 'skillhub', indexUrl: 'https://api.skillhub.cn/api/skills?page=1&pageSize=100&sortBy=score&order=desc', enabled: true, trusted: false, builtin: true, createdAt: now, updatedAt: now },
|
|
12
|
+
];
|
|
13
|
+
}
|
|
14
|
+
export function mergeBuiltinMarketSources(sources, now = Date.now()) {
|
|
15
|
+
const builtins = builtinMarketSources(now);
|
|
16
|
+
const byId = new Map(sources.map(source => [source.id, source]));
|
|
17
|
+
return [...builtins.map(source => ({ ...source, enabled: byId.get(source.id)?.enabled ?? source.enabled })), ...sources.filter(source => !builtins.some(builtin => builtin.id === source.id))];
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=builtin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builtin.js","sourceRoot":"","sources":["../../../src/skills/markets/builtin.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,OAAO,EAAE,gBAAgB;IACzB,OAAO,EAAE,gBAAgB;IACzB,QAAQ,EAAE,iBAAiB;CACnB,CAAA;AAEV,+DAA+D;AAC/D,MAAM,UAAU,oBAAoB,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IACnD,OAAO;QACL,EAAE,EAAE,EAAE,kBAAkB,CAAC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,gDAAgD,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE;QAC9M,EAAE,EAAE,EAAE,kBAAkB,CAAC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,6FAA6F,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE;QAC3P,EAAE,EAAE,EAAE,kBAAkB,CAAC,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,gFAAgF,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE;KAClP,CAAA;AACH,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,OAA4B,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IACtF,MAAM,QAAQ,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAA;IAC1C,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;IAChE,OAAO,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;AAChM,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface RemoteTextRequest {
|
|
2
|
+
url: string;
|
|
3
|
+
maxBytes: number;
|
|
4
|
+
timeoutMs: number;
|
|
5
|
+
method?: string;
|
|
6
|
+
headers?: HeadersInit;
|
|
7
|
+
body?: string;
|
|
8
|
+
proxyUrl?: string;
|
|
9
|
+
}
|
|
10
|
+
/** A bounded HTTP client used by both market discovery and package installs. */
|
|
11
|
+
export declare function requestRemoteText(input: RemoteTextRequest): Promise<string>;
|
|
12
|
+
export declare function requestRemoteBytes(input: RemoteTextRequest): Promise<Uint8Array>;
|
|
13
|
+
export declare function normalizeProxyUrl(value: unknown): string | undefined;
|
|
14
|
+
//# sourceMappingURL=network.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network.d.ts","sourceRoot":"","sources":["../../src/skills/network.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,gFAAgF;AAChF,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAEjF;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,CAIhF;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAQpE"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { request as httpRequest } from 'node:http';
|
|
2
|
+
import { request as httpsRequest } from 'node:https';
|
|
3
|
+
import { connect as tlsConnect } from 'node:tls';
|
|
4
|
+
const MAX_REDIRECTS = 5;
|
|
5
|
+
/** A bounded HTTP client used by both market discovery and package installs. */
|
|
6
|
+
export async function requestRemoteText(input) {
|
|
7
|
+
return new TextDecoder().decode(await requestRemoteBytes(input));
|
|
8
|
+
}
|
|
9
|
+
export function requestRemoteBytes(input) {
|
|
10
|
+
return input.proxyUrl
|
|
11
|
+
? requestThroughHttpProxy(input, 0)
|
|
12
|
+
: requestDirect(input);
|
|
13
|
+
}
|
|
14
|
+
export function normalizeProxyUrl(value) {
|
|
15
|
+
if (value === undefined || value === null || value === '')
|
|
16
|
+
return undefined;
|
|
17
|
+
if (typeof value !== 'string')
|
|
18
|
+
throw new Error('proxyUrl must be a string');
|
|
19
|
+
const proxy = new URL(value.trim());
|
|
20
|
+
if (proxy.protocol !== 'http:')
|
|
21
|
+
throw new Error('Skill 市场代理目前仅支持 http:// 地址');
|
|
22
|
+
if (proxy.username || proxy.password)
|
|
23
|
+
throw new Error('Skill 市场代理地址不能包含账号或密码');
|
|
24
|
+
if (proxy.pathname !== '/' || proxy.search || proxy.hash)
|
|
25
|
+
throw new Error('Skill 市场代理地址不能包含路径、查询参数或片段');
|
|
26
|
+
return proxy.toString();
|
|
27
|
+
}
|
|
28
|
+
async function requestDirect(input) {
|
|
29
|
+
const response = await fetch(input.url, {
|
|
30
|
+
...(input.method ? { method: input.method } : {}),
|
|
31
|
+
...(input.headers ? { headers: input.headers } : {}),
|
|
32
|
+
...(input.body !== undefined ? { body: input.body } : {}),
|
|
33
|
+
signal: AbortSignal.timeout(input.timeoutMs),
|
|
34
|
+
});
|
|
35
|
+
if (!response.ok)
|
|
36
|
+
throw new Error(`HTTP ${response.status} while fetching ${new URL(input.url).host}`);
|
|
37
|
+
const advertised = Number(response.headers.get('content-length') ?? 0);
|
|
38
|
+
if (advertised > input.maxBytes)
|
|
39
|
+
throw new Error('Remote content exceeds the size limit');
|
|
40
|
+
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
41
|
+
if (bytes.byteLength > input.maxBytes)
|
|
42
|
+
throw new Error('Remote content exceeds the size limit');
|
|
43
|
+
return bytes;
|
|
44
|
+
}
|
|
45
|
+
async function requestThroughHttpProxy(input, redirects) {
|
|
46
|
+
if (redirects > MAX_REDIRECTS)
|
|
47
|
+
throw new Error('Skill market request exceeded the redirect limit');
|
|
48
|
+
const target = new URL(input.url);
|
|
49
|
+
const proxy = new URL(normalizeProxyUrl(input.proxyUrl));
|
|
50
|
+
const response = target.protocol === 'https:'
|
|
51
|
+
? await tunnelHttps(target, proxy, input)
|
|
52
|
+
: await proxyHttp(target, proxy, input);
|
|
53
|
+
const location = response.headers.location;
|
|
54
|
+
if (location && [301, 302, 303, 307, 308].includes(response.statusCode ?? 0)) {
|
|
55
|
+
response.resume();
|
|
56
|
+
const switchToGet = response.statusCode === 303 || ((response.statusCode === 301 || response.statusCode === 302) && input.method === 'POST');
|
|
57
|
+
if (switchToGet) {
|
|
58
|
+
const { body: _body, method: _method, ...rest } = input;
|
|
59
|
+
return requestThroughHttpProxy({ ...rest, method: 'GET', url: new URL(location, target).toString() }, redirects + 1);
|
|
60
|
+
}
|
|
61
|
+
return requestThroughHttpProxy({ ...input, url: new URL(location, target).toString() }, redirects + 1);
|
|
62
|
+
}
|
|
63
|
+
return readBounded(response, input.maxBytes, target.host);
|
|
64
|
+
}
|
|
65
|
+
function proxyHttp(target, proxy, input) {
|
|
66
|
+
const headers = requestHeaders(input.headers, target.host, input.body);
|
|
67
|
+
return issue(httpRequest, {
|
|
68
|
+
hostname: proxy.hostname,
|
|
69
|
+
port: proxy.port || 80,
|
|
70
|
+
method: input.method ?? 'GET',
|
|
71
|
+
path: target.toString(),
|
|
72
|
+
headers,
|
|
73
|
+
}, input.body, input.timeoutMs);
|
|
74
|
+
}
|
|
75
|
+
function tunnelHttps(target, proxy, input) {
|
|
76
|
+
return new Promise((resolve, reject) => {
|
|
77
|
+
const targetPort = Number(target.port || 443);
|
|
78
|
+
const connectRequest = httpRequest({
|
|
79
|
+
hostname: proxy.hostname,
|
|
80
|
+
port: proxy.port || 80,
|
|
81
|
+
method: 'CONNECT',
|
|
82
|
+
path: `${target.hostname}:${targetPort}`,
|
|
83
|
+
headers: { host: `${target.hostname}:${targetPort}` },
|
|
84
|
+
});
|
|
85
|
+
const fail = (error) => reject(networkError(error));
|
|
86
|
+
connectRequest.setTimeout(input.timeoutMs, () => connectRequest.destroy(new Error('Skill market proxy connection timed out')));
|
|
87
|
+
connectRequest.on('error', fail);
|
|
88
|
+
connectRequest.once('connect', (response, socket, head) => {
|
|
89
|
+
if (response.statusCode !== 200) {
|
|
90
|
+
socket.destroy();
|
|
91
|
+
reject(new Error(`Skill market proxy CONNECT returned HTTP ${response.statusCode ?? 0}`));
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
// CONNECT exposes the underlying socket separately from the TLS wrapper.
|
|
95
|
+
// Some proxies reset that raw socket during package downloads; keep an
|
|
96
|
+
// error consumer attached for the socket's full lifetime so a failed
|
|
97
|
+
// install cannot become an uncaught process-level error.
|
|
98
|
+
socket.on('error', fail);
|
|
99
|
+
if (head.byteLength > 0)
|
|
100
|
+
socket.unshift(head);
|
|
101
|
+
const secureSocket = tlsConnect({ socket, servername: target.hostname });
|
|
102
|
+
secureSocket.setTimeout(input.timeoutMs, () => secureSocket.destroy(new Error('Skill market TLS connection timed out')));
|
|
103
|
+
secureSocket.on('error', fail);
|
|
104
|
+
secureSocket.once('secureConnect', () => {
|
|
105
|
+
const headers = requestHeaders(input.headers, target.host, input.body);
|
|
106
|
+
void issue(httpsRequest, {
|
|
107
|
+
hostname: target.hostname,
|
|
108
|
+
port: targetPort,
|
|
109
|
+
method: input.method ?? 'GET',
|
|
110
|
+
path: `${target.pathname}${target.search}`,
|
|
111
|
+
headers,
|
|
112
|
+
agent: false,
|
|
113
|
+
createConnection: () => secureSocket,
|
|
114
|
+
}, input.body, input.timeoutMs).then(resolve, reject);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
connectRequest.end();
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
function issue(request, options, body, timeoutMs) {
|
|
121
|
+
return new Promise((resolve, reject) => {
|
|
122
|
+
const outgoing = request(options, resolve);
|
|
123
|
+
outgoing.setTimeout(timeoutMs, () => outgoing.destroy(new Error('Skill market request timed out')));
|
|
124
|
+
outgoing.on('error', error => reject(networkError(error)));
|
|
125
|
+
if (body)
|
|
126
|
+
outgoing.write(body);
|
|
127
|
+
outgoing.end();
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
function requestHeaders(value, host, body) {
|
|
131
|
+
const headers = Object.fromEntries(new Headers(value).entries());
|
|
132
|
+
headers.host = host;
|
|
133
|
+
if (body !== undefined)
|
|
134
|
+
headers['content-length'] = String(Buffer.byteLength(body));
|
|
135
|
+
return headers;
|
|
136
|
+
}
|
|
137
|
+
function readBounded(response, limit, host) {
|
|
138
|
+
return new Promise((resolve, reject) => {
|
|
139
|
+
if ((response.statusCode ?? 0) < 200 || (response.statusCode ?? 0) >= 300) {
|
|
140
|
+
response.resume();
|
|
141
|
+
reject(new Error(`HTTP ${response.statusCode ?? 0} while fetching ${host}`));
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const advertised = Number(response.headers['content-length'] ?? 0);
|
|
145
|
+
if (advertised > limit) {
|
|
146
|
+
response.destroy();
|
|
147
|
+
reject(new Error('Remote content exceeds the size limit'));
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const chunks = [];
|
|
151
|
+
let total = 0;
|
|
152
|
+
response.on('data', (chunk) => {
|
|
153
|
+
total += chunk.byteLength;
|
|
154
|
+
if (total > limit) {
|
|
155
|
+
response.destroy(new Error('Remote content exceeds the size limit'));
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
chunks.push(chunk);
|
|
159
|
+
});
|
|
160
|
+
response.once('end', () => resolve(Buffer.concat(chunks)));
|
|
161
|
+
response.on('error', error => reject(networkError(error)));
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
function networkError(error) {
|
|
165
|
+
const code = error?.code;
|
|
166
|
+
if (code === 'ECONNRESET')
|
|
167
|
+
return new Error('Skill 市场代理连接被中断,请检查代理后重试');
|
|
168
|
+
if (code === 'ECONNREFUSED')
|
|
169
|
+
return new Error('无法连接 Skill 市场代理,请确认地址和端口可用');
|
|
170
|
+
if (code === 'ENOTFOUND')
|
|
171
|
+
return new Error('无法解析 Skill 市场或代理地址,请检查网络配置');
|
|
172
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=network.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network.js","sourceRoot":"","sources":["../../src/skills/network.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { LoadedSkill, PartnerSkill, SkillSourceKind } from './domain.js';
|
|
2
|
+
export declare class SkillRepository {
|
|
3
|
+
readonly root: string;
|
|
4
|
+
constructor(root: string);
|
|
5
|
+
initialize(): Promise<void>;
|
|
6
|
+
read(skill: PartnerSkill): Promise<LoadedSkill>;
|
|
7
|
+
install(input: {
|
|
8
|
+
id: string;
|
|
9
|
+
document: string;
|
|
10
|
+
source: SkillSourceKind;
|
|
11
|
+
sourceId?: string;
|
|
12
|
+
trusted: boolean;
|
|
13
|
+
now?: number;
|
|
14
|
+
}): Promise<PartnerSkill>;
|
|
15
|
+
remove(skill: PartnerSkill): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=repository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../src/skills/repository.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAI7E,qBAAa,eAAe;IACd,QAAQ,CAAC,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM;IAE3B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,IAAI,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAQ/C,OAAO,CAAC,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,eAAe,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,YAAY,CAAC;IA+BnJ,MAAM,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;CAKjD"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { mkdir, rename, rm, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
4
|
+
import { loadSkill, skillMetadata } from './loader.js';
|
|
5
|
+
const SAFE_ID = /^[a-z0-9][a-z0-9._-]{0,119}$/i;
|
|
6
|
+
export class SkillRepository {
|
|
7
|
+
root;
|
|
8
|
+
constructor(root) {
|
|
9
|
+
this.root = root;
|
|
10
|
+
}
|
|
11
|
+
async initialize() {
|
|
12
|
+
await mkdir(this.root, { recursive: true, mode: 0o700 });
|
|
13
|
+
}
|
|
14
|
+
async read(skill) {
|
|
15
|
+
assertInside(this.root, skill.rootPath);
|
|
16
|
+
return loadSkill({
|
|
17
|
+
id: skill.id, rootPath: skill.rootPath, source: skill.source, ...(skill.sourceId ? { sourceId: skill.sourceId } : {}),
|
|
18
|
+
trusted: skill.trusted, installedAt: skill.installedAt, updatedAt: skill.updatedAt,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
async install(input) {
|
|
22
|
+
if (!SAFE_ID.test(input.id))
|
|
23
|
+
throw new Error('Skill id is invalid');
|
|
24
|
+
if (Buffer.byteLength(input.document) > 512 * 1024)
|
|
25
|
+
throw new Error('SKILL.md exceeds the 512 KiB limit');
|
|
26
|
+
await this.initialize();
|
|
27
|
+
const now = input.now ?? Date.now();
|
|
28
|
+
const target = join(this.root, input.id);
|
|
29
|
+
const temporary = join(this.root, `.${input.id}.${randomUUID()}.tmp`);
|
|
30
|
+
const backup = join(this.root, `.${input.id}.${randomUUID()}.backup`);
|
|
31
|
+
await mkdir(temporary, { recursive: false, mode: 0o700 });
|
|
32
|
+
try {
|
|
33
|
+
await writeFile(join(temporary, 'SKILL.md'), input.document, { encoding: 'utf8', mode: 0o600, flag: 'wx' });
|
|
34
|
+
const loaded = await loadSkill({
|
|
35
|
+
id: input.id, rootPath: temporary, source: input.source, ...(input.sourceId ? { sourceId: input.sourceId } : {}),
|
|
36
|
+
trusted: input.trusted, installedAt: now, updatedAt: now,
|
|
37
|
+
});
|
|
38
|
+
let replaced = false;
|
|
39
|
+
try {
|
|
40
|
+
await rename(target, backup);
|
|
41
|
+
replaced = true;
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
if (error.code !== 'ENOENT')
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
await rename(temporary, target);
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
if (replaced)
|
|
52
|
+
await rename(backup, target).catch(() => { });
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
await rm(backup, { recursive: true, force: true });
|
|
56
|
+
return { ...skillMetadata(loaded), rootPath: target };
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
await rm(temporary, { recursive: true, force: true }).catch(() => { });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async remove(skill) {
|
|
63
|
+
assertInside(this.root, skill.rootPath);
|
|
64
|
+
await rm(skill.rootPath, { recursive: true, force: true });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function assertInside(root, path) {
|
|
68
|
+
const base = resolve(root);
|
|
69
|
+
const candidate = resolve(path);
|
|
70
|
+
const rel = relative(base, candidate);
|
|
71
|
+
if (rel === '..' || rel.startsWith(`..${sep}`) || isAbsolute(rel))
|
|
72
|
+
throw new Error('Skill path escapes the repository');
|
|
73
|
+
if (dirname(candidate) !== base)
|
|
74
|
+
throw new Error('Skill path must be a direct repository child');
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../../src/skills/repository.ts"],"names":[],"mappings":"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"}
|