@hypercli.com/sdk 2026.6.26 → 2026.8.11
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 +181 -1
- package/dist/agent-slots.d.ts +17 -0
- package/dist/agent-slots.d.ts.map +1 -0
- package/dist/agent-slots.js +18 -0
- package/dist/agent-slots.js.map +1 -0
- package/dist/agent.d.ts +67 -12
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +220 -28
- package/dist/agent.js.map +1 -1
- package/dist/agents.d.ts +690 -82
- package/dist/agents.d.ts.map +1 -1
- package/dist/agents.js +2595 -225
- package/dist/agents.js.map +1 -1
- package/dist/browser.d.ts +4 -2
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +10 -3
- package/dist/browser.js.map +1 -1
- package/dist/channels.d.ts +156 -0
- package/dist/channels.d.ts.map +1 -0
- package/dist/channels.js +110 -0
- package/dist/channels.js.map +1 -0
- package/dist/client.d.ts +2 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +14 -4
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +2 -2
- package/dist/config.js.map +1 -1
- package/dist/connectors.d.ts +79 -0
- package/dist/connectors.d.ts.map +1 -0
- package/dist/connectors.js +2 -0
- package/dist/connectors.js.map +1 -0
- package/dist/errors.d.ts +4 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +9 -2
- package/dist/errors.js.map +1 -1
- package/dist/hermes/gateway.d.ts +194 -0
- package/dist/hermes/gateway.d.ts.map +1 -0
- package/dist/hermes/gateway.js +209 -0
- package/dist/hermes/gateway.js.map +1 -0
- package/dist/http.d.ts +16 -3
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +196 -63
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +15 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -4
- package/dist/index.js.map +1 -1
- package/dist/job/base.d.ts +6 -0
- package/dist/job/base.d.ts.map +1 -1
- package/dist/job/base.js +7 -1
- package/dist/job/base.js.map +1 -1
- package/dist/keys.d.ts +21 -5
- package/dist/keys.d.ts.map +1 -1
- package/dist/keys.js +62 -3
- package/dist/keys.js.map +1 -1
- package/dist/openclaw/channels.d.ts +86 -0
- package/dist/openclaw/channels.d.ts.map +1 -0
- package/dist/openclaw/channels.js +290 -0
- package/dist/openclaw/channels.js.map +1 -0
- package/dist/openclaw/connectors.d.ts +61 -0
- package/dist/openclaw/connectors.d.ts.map +1 -0
- package/dist/openclaw/connectors.js +174 -0
- package/dist/openclaw/connectors.js.map +1 -0
- package/dist/openclaw/gateway.d.ts +682 -16
- package/dist/openclaw/gateway.d.ts.map +1 -1
- package/dist/openclaw/gateway.js +1794 -187
- package/dist/openclaw/gateway.js.map +1 -1
- package/dist/openclaw/skills.d.ts +106 -0
- package/dist/openclaw/skills.d.ts.map +1 -0
- package/dist/openclaw/skills.js +575 -0
- package/dist/openclaw/skills.js.map +1 -0
- package/dist/openclaw/slack.d.ts +818 -0
- package/dist/openclaw/slack.d.ts.map +1 -0
- package/dist/openclaw/slack.js +536 -0
- package/dist/openclaw/slack.js.map +1 -0
- package/dist/openclaw/whatsapp.d.ts +63 -0
- package/dist/openclaw/whatsapp.d.ts.map +1 -0
- package/dist/openclaw/whatsapp.js +264 -0
- package/dist/openclaw/whatsapp.js.map +1 -0
- package/dist/renders.js +11 -11
- package/dist/renders.js.map +1 -1
- package/dist/skills.d.ts +126 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +2 -0
- package/dist/skills.js.map +1 -0
- package/dist/user.d.ts +15 -2
- package/dist/user.d.ts.map +1 -1
- package/dist/user.js +51 -4
- package/dist/user.js.map +1 -1
- package/dist/voice-session.d.ts +74 -0
- package/dist/voice-session.d.ts.map +1 -0
- package/dist/voice-session.js +255 -0
- package/dist/voice-session.js.map +1 -0
- package/dist/voice.d.ts +27 -3
- package/dist/voice.d.ts.map +1 -1
- package/dist/voice.js +89 -6
- package/dist/voice.js.map +1 -1
- package/dist/workspaces.d.ts +181 -0
- package/dist/workspaces.d.ts.map +1 -0
- package/dist/workspaces.js +495 -0
- package/dist/workspaces.js.map +1 -0
- package/dist/x402.d.ts.map +1 -1
- package/dist/x402.js +1 -2
- package/dist/x402.js.map +1 -1
- package/package.json +42 -2
|
@@ -0,0 +1,575 @@
|
|
|
1
|
+
const MAX_SKILL_DOCUMENT_BYTES = 1024 * 1024;
|
|
2
|
+
const MAX_SKILL_RESOURCE_BYTES = 10 * 1024 * 1024;
|
|
3
|
+
const SKILL_RESOURCE_WRITE_CHUNK_BYTES = 48 * 1024;
|
|
4
|
+
const MAX_SKILL_DIRECTORIES = 64;
|
|
5
|
+
const MAX_SKILL_DIRECTORY_PATH_BYTES = 1024;
|
|
6
|
+
const MAX_SKILL_RECOVERY_ENTRIES = 2048;
|
|
7
|
+
const MAX_SKILL_RECOVERY_BYTES = 100 * 1024 * 1024;
|
|
8
|
+
const LOOSE_WORKSPACE_SKILL_CANDIDATE_ID = 'workspace-skills-root';
|
|
9
|
+
function shellQuoteArgument(value) {
|
|
10
|
+
return `'${value.replace(/'/g, `'"'"'`)}'`;
|
|
11
|
+
}
|
|
12
|
+
function normalizeAbsolutePath(value) {
|
|
13
|
+
const normalized = value.trim().replace(/\\/g, '/').replace(/\/+$/, '');
|
|
14
|
+
return normalized || '/';
|
|
15
|
+
}
|
|
16
|
+
function pathIsWithin(path, root) {
|
|
17
|
+
if (!root)
|
|
18
|
+
return false;
|
|
19
|
+
const normalizedPath = normalizeAbsolutePath(path);
|
|
20
|
+
const normalizedRoot = normalizeAbsolutePath(root);
|
|
21
|
+
return normalizedRoot === '/'
|
|
22
|
+
? normalizedPath.startsWith('/')
|
|
23
|
+
: normalizedPath === normalizedRoot || normalizedPath.startsWith(`${normalizedRoot}/`);
|
|
24
|
+
}
|
|
25
|
+
function isLooseWorkspaceSkillEntry(entry, workspaceDir) {
|
|
26
|
+
if (!workspaceDir || !entry.baseDir || !entry.filePath)
|
|
27
|
+
return false;
|
|
28
|
+
const root = `${normalizeAbsolutePath(workspaceDir)}/skills`;
|
|
29
|
+
return normalizeAbsolutePath(entry.baseDir) === root
|
|
30
|
+
&& normalizeAbsolutePath(entry.filePath) === `${root}/SKILL.md`;
|
|
31
|
+
}
|
|
32
|
+
function bytesToBase64(content) {
|
|
33
|
+
let binary = '';
|
|
34
|
+
for (let offset = 0; offset < content.length; offset += 0x8000) {
|
|
35
|
+
binary += String.fromCharCode(...content.subarray(offset, offset + 0x8000));
|
|
36
|
+
}
|
|
37
|
+
return globalThis.btoa(binary);
|
|
38
|
+
}
|
|
39
|
+
function base64ToBytes(content) {
|
|
40
|
+
const binary = globalThis.atob(content);
|
|
41
|
+
return Uint8Array.from(binary, (character) => character.charCodeAt(0));
|
|
42
|
+
}
|
|
43
|
+
function validateResourcePath(value, allowRoot = false) {
|
|
44
|
+
if (value.includes('\0'))
|
|
45
|
+
throw new Error('Skill resource paths cannot contain NUL bytes.');
|
|
46
|
+
const normalized = value.trim().replace(/\\/g, '/').replace(/^\.\//, '').replace(/\/+$/, '');
|
|
47
|
+
if (!normalized) {
|
|
48
|
+
if (allowRoot)
|
|
49
|
+
return '';
|
|
50
|
+
throw new Error('A skill-relative resource path is required.');
|
|
51
|
+
}
|
|
52
|
+
if (normalized.startsWith('/') || /^[A-Za-z]:\//.test(normalized) || normalized.startsWith('//')) {
|
|
53
|
+
throw new Error('Skill resource paths must be relative.');
|
|
54
|
+
}
|
|
55
|
+
const segments = normalized.split('/');
|
|
56
|
+
if (segments.some((segment) => !segment || segment === '.' || segment === '..')) {
|
|
57
|
+
throw new Error('Skill resource paths cannot contain empty or traversal segments.');
|
|
58
|
+
}
|
|
59
|
+
return segments.join('/');
|
|
60
|
+
}
|
|
61
|
+
export function buildOpenClawSkillResourceCommand(input) {
|
|
62
|
+
const payload = {
|
|
63
|
+
action: input.action,
|
|
64
|
+
root: input.root,
|
|
65
|
+
path: input.path,
|
|
66
|
+
content: input.content ? bytesToBase64(input.content) : undefined,
|
|
67
|
+
recursive: input.recursive === true,
|
|
68
|
+
writableRoots: input.writableRoots ?? [],
|
|
69
|
+
uploadToken: input.uploadToken,
|
|
70
|
+
maxBytes: MAX_SKILL_RESOURCE_BYTES,
|
|
71
|
+
};
|
|
72
|
+
const script = [
|
|
73
|
+
'const fs=require("node:fs"),p=require("node:path");',
|
|
74
|
+
`const input=${JSON.stringify(payload)};`,
|
|
75
|
+
'const root=fs.realpathSync(input.root);',
|
|
76
|
+
'const inside=(value)=>value===root||value.startsWith(root+p.sep);',
|
|
77
|
+
'if(input.action.startsWith("write-")||["delete","mkdir"].includes(input.action)){const allowed=input.writableRoots.flatMap((value)=>{try{return [fs.realpathSync(value)];}catch{return [];}});if(!allowed.some((value)=>root===value||root.startsWith(value+p.sep)))throw new Error("Writable skill root escapes the managed skills directories.");}',
|
|
78
|
+
'const target=p.resolve(root,input.path||".");',
|
|
79
|
+
'if(!inside(target))throw new Error("Skill resource path escapes its root.");',
|
|
80
|
+
'const existingReal=(value)=>{const real=fs.realpathSync(value);if(!inside(real))throw new Error("Skill resource symlink escapes its root.");return real;};',
|
|
81
|
+
'const writableTarget=()=>{if(!input.path)throw new Error("Cannot overwrite the skill root.");const parent=existingReal(p.dirname(target));if(!fs.statSync(parent).isDirectory())throw new Error("Skill resource parent is not a directory.");if(fs.existsSync(target)){const item=fs.lstatSync(target);if(item.isSymbolicLink())throw new Error("Cannot overwrite a symbolic link.");existingReal(target);if(!item.isFile())throw new Error("Skill resource is not a regular file.");}return parent;};',
|
|
82
|
+
'const uploadPath=()=>{if(!/^[a-z0-9-]+$/i.test(input.uploadToken||""))throw new Error("Invalid skill upload token.");const parent=writableTarget();const file=p.join(parent,`.hypercli-upload-${input.uploadToken}`);if(!inside(file))throw new Error("Skill upload path escapes its root.");return file;};',
|
|
83
|
+
'if(input.action==="list"){const dir=existingReal(target);const stat=fs.statSync(dir);if(!stat.isDirectory())throw new Error("Skill resource path is not a directory.");const entries=fs.readdirSync(dir,{withFileTypes:true}).flatMap((entry)=>{const child=p.join(dir,entry.name);let real,childStat;try{real=existingReal(child);childStat=fs.statSync(real);}catch{return [];}if(!childStat.isFile()&&!childStat.isDirectory())return [];const relative=p.relative(root,child).split(p.sep).join("/");return [{name:entry.name,path:relative,type:childStat.isDirectory()?"directory":"file",...(childStat.isFile()?{size:childStat.size}:{}) ,lastModified:childStat.mtime.toISOString()}];});process.stdout.write(JSON.stringify(entries));}',
|
|
84
|
+
'else if(input.action==="read"){const file=existingReal(target);const stat=fs.statSync(file);if(!stat.isFile())throw new Error("Skill resource is not a regular file.");if(stat.size>input.maxBytes)throw new Error("Skill resource exceeds the read limit.");process.stdout.write(JSON.stringify({content:fs.readFileSync(file).toString("base64")}));}',
|
|
85
|
+
'else if(input.action==="write-start"){const file=uploadPath();fs.writeFileSync(file,"",{flag:"wx"});process.stdout.write("{}");}',
|
|
86
|
+
'else if(input.action==="write-append"){const file=uploadPath();const item=fs.lstatSync(file);if(item.isSymbolicLink()||!item.isFile())throw new Error("Invalid skill upload file.");const bytes=Buffer.from(input.content||"","base64");if(item.size+bytes.length>input.maxBytes)throw new Error("Skill resource exceeds the write limit.");fs.appendFileSync(file,bytes);process.stdout.write("{}");}',
|
|
87
|
+
'else if(input.action==="write-finish"){const file=uploadPath();const item=fs.lstatSync(file);if(item.isSymbolicLink()||!item.isFile())throw new Error("Invalid skill upload file.");fs.renameSync(file,target);process.stdout.write("{}");}',
|
|
88
|
+
'else if(input.action==="write-abort"){const file=uploadPath();if(fs.existsSync(file)){const item=fs.lstatSync(file);if(item.isFile()||item.isSymbolicLink())fs.unlinkSync(file);}process.stdout.write("{}");}',
|
|
89
|
+
'else if(input.action==="delete"){if(!input.path)throw new Error("Cannot delete the skill root.");if(!fs.existsSync(target))throw new Error("Skill resource does not exist.");const item=fs.lstatSync(target);if(!item.isSymbolicLink())existingReal(target);fs.rmSync(target,{recursive:input.recursive,force:false});process.stdout.write("{}");}',
|
|
90
|
+
'else if(input.action==="mkdir"){if(!input.path)throw new Error("Cannot create the skill root.");const parent=existingReal(p.dirname(target));if(!fs.statSync(parent).isDirectory())throw new Error("Skill resource parent is not a directory.");fs.mkdirSync(target);process.stdout.write("{}");}',
|
|
91
|
+
'else throw new Error("Unsupported skill resource operation.");',
|
|
92
|
+
].join('');
|
|
93
|
+
return `node -e ${shellQuoteArgument(script)}`;
|
|
94
|
+
}
|
|
95
|
+
export function buildOpenClawSkillCreateCommand(input) {
|
|
96
|
+
const payload = {
|
|
97
|
+
action: input.action,
|
|
98
|
+
root: input.root,
|
|
99
|
+
id: input.id,
|
|
100
|
+
createToken: input.createToken,
|
|
101
|
+
directories: input.directories ?? [],
|
|
102
|
+
content: input.content ? bytesToBase64(input.content) : undefined,
|
|
103
|
+
maxBytes: MAX_SKILL_DOCUMENT_BYTES,
|
|
104
|
+
};
|
|
105
|
+
const script = [
|
|
106
|
+
'const fs=require("node:fs"),p=require("node:path");',
|
|
107
|
+
`const input=${JSON.stringify(payload)};`,
|
|
108
|
+
'if(!/^[a-z0-9](?:[a-z0-9-]{0,78}[a-z0-9])?$/.test(input.id))throw new Error("Invalid skill identifier.");',
|
|
109
|
+
'if(!/^[a-z0-9-]+$/i.test(input.createToken))throw new Error("Invalid skill create token.");',
|
|
110
|
+
'fs.mkdirSync(input.root,{recursive:true,mode:0o700});',
|
|
111
|
+
'const root=fs.realpathSync(input.root);',
|
|
112
|
+
'if(!fs.statSync(root).isDirectory())throw new Error("Managed skills root is not a directory.");',
|
|
113
|
+
'const inside=(base,value)=>value===base||value.startsWith(base+p.sep);',
|
|
114
|
+
'const target=p.join(root,input.id);',
|
|
115
|
+
'const stage=p.join(root,`.hypercli-create-${input.createToken}`);',
|
|
116
|
+
'if(p.dirname(target)!==root||p.dirname(stage)!==root)throw new Error("Skill create path escapes the managed root.");',
|
|
117
|
+
'const requireStage=()=>{const item=fs.lstatSync(stage);if(item.isSymbolicLink()||!item.isDirectory())throw new Error("Invalid staged skill directory.");const real=fs.realpathSync(stage);if(!inside(root,real))throw new Error("Staged skill directory escapes the managed root.");return real;};',
|
|
118
|
+
'if(input.action==="create-start"){if(fs.existsSync(target))throw new Error("A skill with this ID already exists.");fs.mkdirSync(stage,{mode:0o700});try{const realStage=requireStage();for(const directory of input.directories){const destination=p.resolve(realStage,directory);if(!inside(realStage,destination))throw new Error("Skill directory escapes its root.");fs.mkdirSync(destination,{recursive:true});}fs.writeFileSync(p.join(realStage,"SKILL.md"),"",{flag:"wx",mode:0o600});process.stdout.write("{}");}catch(error){fs.rmSync(stage,{recursive:true,force:true});throw error;}}',
|
|
119
|
+
'else if(input.action==="create-append"){const realStage=requireStage();const file=p.join(realStage,"SKILL.md");const item=fs.lstatSync(file);if(item.isSymbolicLink()||!item.isFile())throw new Error("Invalid staged skill document.");const bytes=Buffer.from(input.content||"","base64");if(item.size+bytes.length>input.maxBytes)throw new Error("Skill document exceeds the write limit.");fs.appendFileSync(file,bytes);process.stdout.write("{}");}',
|
|
120
|
+
'else if(input.action==="create-finish"){const realStage=requireStage();const file=p.join(realStage,"SKILL.md");const item=fs.lstatSync(file);if(item.isSymbolicLink()||!item.isFile()||item.size===0)throw new Error("Skill document is empty or invalid.");if(fs.existsSync(target))throw new Error("A skill with this ID already exists.");fs.renameSync(realStage,target);process.stdout.write(JSON.stringify({skillId:input.id}));}',
|
|
121
|
+
'else if(input.action==="create-abort"){if(fs.existsSync(stage)){const item=fs.lstatSync(stage);if(item.isDirectory()&&!item.isSymbolicLink()){const real=fs.realpathSync(stage);if(inside(root,real))fs.rmSync(real,{recursive:true,force:true});}}process.stdout.write("{}");}',
|
|
122
|
+
'else throw new Error("Unsupported skill create operation.");',
|
|
123
|
+
].join('');
|
|
124
|
+
return `node -e ${shellQuoteArgument(script)}`;
|
|
125
|
+
}
|
|
126
|
+
export function buildOpenClawSkillRecoveryScanCommand(workspaceDir) {
|
|
127
|
+
const payload = {
|
|
128
|
+
workspaceDir,
|
|
129
|
+
candidateId: LOOSE_WORKSPACE_SKILL_CANDIDATE_ID,
|
|
130
|
+
maxDocumentBytes: MAX_SKILL_DOCUMENT_BYTES,
|
|
131
|
+
maxResourceBytes: MAX_SKILL_RESOURCE_BYTES,
|
|
132
|
+
maxEntries: MAX_SKILL_RECOVERY_ENTRIES,
|
|
133
|
+
};
|
|
134
|
+
const script = [
|
|
135
|
+
'const fs=require("node:fs"),p=require("node:path");',
|
|
136
|
+
`const input=${JSON.stringify(payload)};`,
|
|
137
|
+
'(()=>{',
|
|
138
|
+
'if(!fs.existsSync(input.workspaceDir)){process.stdout.write("[]");return;}',
|
|
139
|
+
'const workspace=fs.realpathSync(input.workspaceDir);const rootPath=p.join(workspace,"skills");',
|
|
140
|
+
'if(!fs.existsSync(rootPath)){process.stdout.write("[]");return;}',
|
|
141
|
+
'const rootItem=fs.lstatSync(rootPath);if(rootItem.isSymbolicLink()||!rootItem.isDirectory())throw new Error("Workspace skills root is invalid.");',
|
|
142
|
+
'const root=fs.realpathSync(rootPath);if(p.dirname(root)!==workspace)throw new Error("Workspace skills root escapes the workspace.");',
|
|
143
|
+
'const document=p.join(root,"SKILL.md");if(!fs.existsSync(document)){process.stdout.write("[]");return;}',
|
|
144
|
+
'const documentItem=fs.lstatSync(document);if(documentItem.isSymbolicLink()||!documentItem.isFile())throw new Error("Loose SKILL.md is not a regular file.");',
|
|
145
|
+
'if(documentItem.size===0||documentItem.size>input.maxDocumentBytes)throw new Error("Loose SKILL.md is empty or exceeds the 1 MiB limit.");',
|
|
146
|
+
'const content=fs.readFileSync(document,"utf8");const frontmatter=content.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---(?:\\r?\\n|$)/)?.[1]||"";',
|
|
147
|
+
'const field=(key)=>{const line=frontmatter.split(/\\r?\\n/).find((value)=>new RegExp(`^\\\\s*${key}\\\\s*:`,"i").test(value));if(!line)return "";let value=line.slice(line.indexOf(":")+1).trim();if(value.startsWith(String.fromCharCode(34))&&value.endsWith(String.fromCharCode(34))){try{value=JSON.parse(value);}catch{}}else if(value.startsWith("\'")&&value.endsWith("\'")){value=value.slice(1,-1);}return String(value).trim();};',
|
|
148
|
+
'const rawName=field("name");const heading=content.match(/^#\\s+(.+)$/m)?.[1]?.trim()||"";const name=(rawName||heading||"Unorganized skill").slice(0,200);',
|
|
149
|
+
'const suggestedSkillId=(rawName||heading||"recovered-skill").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,80)||"recovered-skill";',
|
|
150
|
+
'const description=(field("description")||"Skill files created directly in the workspace skills folder.").replace(/[\\r\\n]+/g," ").slice(0,500);',
|
|
151
|
+
'const standard=new Set(["assets","references","scripts"]);',
|
|
152
|
+
'const inspect=(target)=>{let count=0;const visit=(value)=>{if(++count>input.maxEntries)throw new Error("Resource contains too many entries.");const item=fs.lstatSync(value);if(item.isSymbolicLink())throw new Error("Symbolic links cannot be recovered.");if(item.isFile()){if(item.size>input.maxResourceBytes)throw new Error("Resource exceeds the 10 MiB limit.");return;}if(!item.isDirectory())throw new Error("Only regular files and directories can be recovered.");for(const child of fs.readdirSync(value))visit(p.join(value,child));};try{visit(target);return null;}catch(error){return error instanceof Error?error.message:"Resource cannot be recovered.";}};',
|
|
153
|
+
'const entries=fs.readdirSync(root,{withFileTypes:true}).filter((entry)=>entry.name!=="SKILL.md"&&!entry.name.startsWith(".hypercli-")).map((entry)=>{const target=p.join(root,entry.name);let reason;if(entry.isSymbolicLink())reason="Symbolic links cannot be recovered.";else if(entry.isDirectory()&&fs.existsSync(p.join(target,"SKILL.md")))reason="This folder is already a separate skill.";else if(!entry.isFile()&&!entry.isDirectory())reason="Only regular files and directories can be recovered.";else reason=inspect(target)||undefined;return {name:entry.name,path:entry.name,type:entry.isDirectory()?"directory":"file",selectedByDefault:!reason&&entry.isDirectory()&&standard.has(entry.name.toLowerCase()),selectable:!reason,...(reason?{reason}:{})};}).sort((a,b)=>a.name.localeCompare(b.name));',
|
|
154
|
+
'process.stdout.write(JSON.stringify([{id:input.candidateId,name,description,suggestedSkillId,entries}]));',
|
|
155
|
+
'})();',
|
|
156
|
+
].join('');
|
|
157
|
+
return `node -e ${shellQuoteArgument(script)}`;
|
|
158
|
+
}
|
|
159
|
+
export function buildOpenClawSkillRecoverCommand(input) {
|
|
160
|
+
const payload = {
|
|
161
|
+
...input,
|
|
162
|
+
maxDocumentBytes: MAX_SKILL_DOCUMENT_BYTES,
|
|
163
|
+
maxResourceBytes: MAX_SKILL_RESOURCE_BYTES,
|
|
164
|
+
maxEntries: MAX_SKILL_RECOVERY_ENTRIES,
|
|
165
|
+
maxTotalBytes: MAX_SKILL_RECOVERY_BYTES,
|
|
166
|
+
};
|
|
167
|
+
const script = [
|
|
168
|
+
'const fs=require("node:fs"),p=require("node:path");',
|
|
169
|
+
`const input=${JSON.stringify(payload)};`,
|
|
170
|
+
'if(!/^[a-z0-9](?:[a-z0-9-]{0,78}[a-z0-9])?$/.test(input.skillId))throw new Error("Invalid skill identifier.");',
|
|
171
|
+
'if(!/^[a-z0-9-]+$/i.test(input.recoveryToken))throw new Error("Invalid skill recovery token.");',
|
|
172
|
+
'if(!Array.isArray(input.paths)||input.paths.some((name)=>typeof name!=="string"||!name||name==="SKILL.md"||name.startsWith(".")||p.basename(name)!==name))throw new Error("Invalid recovery path.");',
|
|
173
|
+
'input.paths=[...new Set(input.paths)];',
|
|
174
|
+
'const workspace=fs.realpathSync(input.workspaceDir);const sourcePath=p.join(workspace,"skills");const sourceItem=fs.lstatSync(sourcePath);if(sourceItem.isSymbolicLink()||!sourceItem.isDirectory())throw new Error("Workspace skills root is invalid.");const source=fs.realpathSync(sourcePath);',
|
|
175
|
+
'if(p.dirname(source)!==workspace)throw new Error("Workspace skills root is invalid.");',
|
|
176
|
+
'fs.mkdirSync(input.managedSkillsDir,{recursive:true,mode:0o700});const managed=fs.realpathSync(input.managedSkillsDir);',
|
|
177
|
+
'if(source===managed||source.startsWith(managed+p.sep)||managed.startsWith(source+p.sep))throw new Error("Skill recovery roots must be separate.");',
|
|
178
|
+
'const target=p.join(managed,input.skillId);const stage=p.join(managed,`.hypercli-recover-${input.recoveryToken}`);const quarantine=p.join(source,`.hypercli-recover-${input.recoveryToken}`);',
|
|
179
|
+
'if(p.dirname(target)!==managed||p.dirname(stage)!==managed||p.dirname(quarantine)!==source)throw new Error("Skill recovery path escapes its root.");',
|
|
180
|
+
'if(fs.existsSync(target))throw new Error("A skill with this ID already exists.");if(fs.existsSync(stage)||fs.existsSync(quarantine))throw new Error("Skill recovery staging already exists.");',
|
|
181
|
+
'let entries=0,totalBytes=0;const validate=(value,isDocument=false)=>{if(++entries>input.maxEntries)throw new Error("Skill recovery contains too many entries.");const item=fs.lstatSync(value);if(item.isSymbolicLink())throw new Error("Symbolic links cannot be recovered.");if(item.isFile()){const limit=isDocument?input.maxDocumentBytes:input.maxResourceBytes;if(item.size===0&&isDocument)throw new Error("SKILL.md cannot be empty.");if(item.size>limit)throw new Error(isDocument?"SKILL.md exceeds the 1 MiB limit.":"A skill resource exceeds the 10 MiB limit.");totalBytes+=item.size;if(totalBytes>input.maxTotalBytes)throw new Error("Skill recovery exceeds the 100 MiB total limit.");return;}if(!item.isDirectory())throw new Error("Only regular files and directories can be recovered.");for(const child of fs.readdirSync(value)){if(child.toLowerCase()==="skill.md")throw new Error("A selected folder contains another skill.");validate(p.join(value,child));}};',
|
|
182
|
+
'const document=p.join(source,"SKILL.md");if(!fs.existsSync(document))throw new Error("Loose workspace SKILL.md no longer exists.");validate(document,true);for(const name of input.paths){const value=p.join(source,name);if(!fs.existsSync(value))throw new Error(`Recovery item no longer exists: ${name}`);validate(value);}',
|
|
183
|
+
'const copy=(from,to)=>{const item=fs.lstatSync(from);if(item.isSymbolicLink())throw new Error("Symbolic links cannot be recovered.");if(item.isFile()){fs.copyFileSync(from,to,fs.constants.COPYFILE_EXCL);fs.chmodSync(to,item.mode&0o777);return;}if(!item.isDirectory())throw new Error("Only regular files and directories can be recovered.");fs.mkdirSync(to,{mode:item.mode&0o777});for(const child of fs.readdirSync(from))copy(p.join(from,child),p.join(to,child));};',
|
|
184
|
+
'let committed=false;const moved=[];try{fs.mkdirSync(quarantine,{mode:0o700});for(const name of ["SKILL.md",...input.paths]){fs.renameSync(p.join(source,name),p.join(quarantine,name));moved.push(name);}fs.mkdirSync(stage,{mode:0o700});copy(p.join(quarantine,"SKILL.md"),p.join(stage,"SKILL.md"));for(const name of input.paths)copy(p.join(quarantine,name),p.join(stage,name));if(fs.existsSync(target))throw new Error("A skill with this ID already exists.");fs.renameSync(stage,target);committed=true;try{fs.rmSync(quarantine,{recursive:true,force:true});}catch{}process.stdout.write(JSON.stringify({skillId:input.skillId}));}catch(error){if(!committed){for(const name of [...moved].reverse()){const backup=p.join(quarantine,name),original=p.join(source,name);if(fs.existsSync(backup)&&!fs.existsSync(original))fs.renameSync(backup,original);}if(fs.existsSync(stage))fs.rmSync(stage,{recursive:true,force:true});if(fs.existsSync(quarantine)&&fs.readdirSync(quarantine).length===0)fs.rmdirSync(quarantine);}throw error;}',
|
|
185
|
+
].join('');
|
|
186
|
+
return `node -e ${shellQuoteArgument(script)}`;
|
|
187
|
+
}
|
|
188
|
+
export function buildOpenClawSkillDocumentReadCommand(path) {
|
|
189
|
+
const script = [
|
|
190
|
+
'const fs=require("node:fs");',
|
|
191
|
+
`const file=${JSON.stringify(path)};`,
|
|
192
|
+
'const stat=fs.statSync(file);',
|
|
193
|
+
'if(!stat.isFile())throw new Error("Skill document is not a regular file.");',
|
|
194
|
+
`if(stat.size>${MAX_SKILL_DOCUMENT_BYTES})throw new Error("Skill document exceeds the 1 MiB read limit.");`,
|
|
195
|
+
'process.stdout.write(fs.readFileSync(file,"utf8"));',
|
|
196
|
+
].join('');
|
|
197
|
+
return `node -e ${shellQuoteArgument(script)}`;
|
|
198
|
+
}
|
|
199
|
+
function stringList(value) {
|
|
200
|
+
if (Array.isArray(value)) {
|
|
201
|
+
return value.filter((item) => typeof item === 'string' && item.trim().length > 0);
|
|
202
|
+
}
|
|
203
|
+
if (typeof value === 'string' && value.trim())
|
|
204
|
+
return [value.trim()];
|
|
205
|
+
if (value && typeof value === 'object')
|
|
206
|
+
return Object.keys(value);
|
|
207
|
+
return [];
|
|
208
|
+
}
|
|
209
|
+
function requirements(value) {
|
|
210
|
+
return {
|
|
211
|
+
env: stringList(value?.env),
|
|
212
|
+
bins: stringList(value?.bins),
|
|
213
|
+
os: stringList(value?.os),
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
function origin(entry) {
|
|
217
|
+
if (entry.bundled)
|
|
218
|
+
return 'built-in';
|
|
219
|
+
const source = entry.source.trim().toLowerCase();
|
|
220
|
+
if (source.includes('plugin') || source.includes('extension'))
|
|
221
|
+
return 'extension';
|
|
222
|
+
if (source.includes('clawhub') || source.includes('catalog') || source.includes('registry'))
|
|
223
|
+
return 'registry';
|
|
224
|
+
if (source.includes('custom') || source.includes('managed') || source.includes('workspace'))
|
|
225
|
+
return 'custom';
|
|
226
|
+
return 'unknown';
|
|
227
|
+
}
|
|
228
|
+
function availability(entry) {
|
|
229
|
+
if (entry.disabled)
|
|
230
|
+
return 'disabled';
|
|
231
|
+
if (entry.blockedByAllowlist || entry.blockedByAgentFilter)
|
|
232
|
+
return 'blocked';
|
|
233
|
+
if (!entry.eligible)
|
|
234
|
+
return 'needs-setup';
|
|
235
|
+
return 'active';
|
|
236
|
+
}
|
|
237
|
+
export function normalizeOpenClawSkill(entry, options = {}) {
|
|
238
|
+
const required = requirements(entry.requirements);
|
|
239
|
+
if (required.env.length === 0 && entry.primaryEnv)
|
|
240
|
+
required.env = [entry.primaryEnv];
|
|
241
|
+
if (required.bins.length === 0)
|
|
242
|
+
required.bins = entry.install.flatMap((option) => option.bins ?? []);
|
|
243
|
+
const missing = requirements(entry.missing);
|
|
244
|
+
const skillOrigin = origin(entry);
|
|
245
|
+
let resourceAccess = 'none';
|
|
246
|
+
if (options.resources && entry.baseDir && !isLooseWorkspaceSkillEntry(entry, options.workspaceDir)) {
|
|
247
|
+
const managed = pathIsWithin(entry.baseDir, options.managedSkillsDir);
|
|
248
|
+
const workspaceSkills = options.workspaceDir
|
|
249
|
+
? pathIsWithin(entry.baseDir, `${normalizeAbsolutePath(options.workspaceDir)}/skills`)
|
|
250
|
+
: false;
|
|
251
|
+
resourceAccess = skillOrigin === 'custom' && (managed || workspaceSkills) ? 'read-write' : 'read-only';
|
|
252
|
+
}
|
|
253
|
+
return {
|
|
254
|
+
id: entry.skillKey,
|
|
255
|
+
name: entry.name || entry.skillKey,
|
|
256
|
+
description: entry.description || 'Skill instructions',
|
|
257
|
+
origin: skillOrigin,
|
|
258
|
+
availability: availability(entry),
|
|
259
|
+
enabled: !entry.disabled,
|
|
260
|
+
ready: !entry.disabled && entry.eligible && !entry.blockedByAllowlist && !entry.blockedByAgentFilter,
|
|
261
|
+
documentAvailable: Boolean(entry.filePath || entry.skillCard?.present),
|
|
262
|
+
resourceAccess,
|
|
263
|
+
requirements: required,
|
|
264
|
+
missingRequirements: missing,
|
|
265
|
+
emoji: entry.emoji,
|
|
266
|
+
homepage: entry.homepage,
|
|
267
|
+
installHints: entry.install.map((option) => option.label).filter(Boolean),
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
export class OpenClawSkillsProvider {
|
|
271
|
+
client;
|
|
272
|
+
options;
|
|
273
|
+
capabilities;
|
|
274
|
+
entries = new Map();
|
|
275
|
+
resourceAccess = new Map();
|
|
276
|
+
writableRoots = [];
|
|
277
|
+
agentId;
|
|
278
|
+
constructor(client, options = {}) {
|
|
279
|
+
this.client = client;
|
|
280
|
+
this.options = options;
|
|
281
|
+
this.capabilities = {
|
|
282
|
+
readDocument: true,
|
|
283
|
+
configure: true,
|
|
284
|
+
searchRegistry: true,
|
|
285
|
+
installRegistry: true,
|
|
286
|
+
installUpload: false,
|
|
287
|
+
resources: Boolean(options.exec),
|
|
288
|
+
createSkill: Boolean(options.exec),
|
|
289
|
+
recoverSkill: Boolean(options.exec),
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
async list() {
|
|
293
|
+
const report = await this.client.skillsStatus();
|
|
294
|
+
this.agentId = report.agentId;
|
|
295
|
+
this.entries.clear();
|
|
296
|
+
this.resourceAccess.clear();
|
|
297
|
+
this.writableRoots = [report.managedSkillsDir, report.workspaceDir ? `${normalizeAbsolutePath(report.workspaceDir)}/skills` : undefined]
|
|
298
|
+
.filter((path) => Boolean(path));
|
|
299
|
+
const catalogSkills = report.skills.filter((entry) => !isLooseWorkspaceSkillEntry(entry, report.workspaceDir));
|
|
300
|
+
catalogSkills.forEach((entry) => this.entries.set(entry.skillKey, entry));
|
|
301
|
+
const summaries = catalogSkills.map((entry) => normalizeOpenClawSkill(entry, {
|
|
302
|
+
resources: this.capabilities.resources,
|
|
303
|
+
workspaceDir: report.workspaceDir,
|
|
304
|
+
managedSkillsDir: report.managedSkillsDir,
|
|
305
|
+
}));
|
|
306
|
+
summaries.forEach((summary) => this.resourceAccess.set(summary.id, summary.resourceAccess));
|
|
307
|
+
return summaries.sort((a, b) => a.name.localeCompare(b.name));
|
|
308
|
+
}
|
|
309
|
+
async readDocument(skillId) {
|
|
310
|
+
if (this.entries.size === 0)
|
|
311
|
+
await this.list();
|
|
312
|
+
const entry = this.entries.get(skillId);
|
|
313
|
+
if (!entry)
|
|
314
|
+
return null;
|
|
315
|
+
let fileReadError = null;
|
|
316
|
+
if (entry.filePath && this.options.readFile) {
|
|
317
|
+
try {
|
|
318
|
+
const content = await this.options.readFile(entry.filePath);
|
|
319
|
+
return { skillId, content };
|
|
320
|
+
}
|
|
321
|
+
catch (error) {
|
|
322
|
+
fileReadError = error;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
if (entry.filePath && this.options.exec) {
|
|
326
|
+
try {
|
|
327
|
+
const result = await this.options.exec(buildOpenClawSkillDocumentReadCommand(entry.filePath));
|
|
328
|
+
if (result.exitCode !== 0)
|
|
329
|
+
throw new Error(result.stderr || `Could not read ${skillId} instructions.`);
|
|
330
|
+
return { skillId, content: result.stdout };
|
|
331
|
+
}
|
|
332
|
+
catch (error) {
|
|
333
|
+
fileReadError = error;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
if (!entry.skillCard?.present) {
|
|
337
|
+
if (fileReadError)
|
|
338
|
+
throw fileReadError;
|
|
339
|
+
return null;
|
|
340
|
+
}
|
|
341
|
+
const card = await this.client.skillsSkillCard({ agentId: this.agentId, skillKey: skillId });
|
|
342
|
+
return { skillId, content: card.content, sizeBytes: card.sizeBytes };
|
|
343
|
+
}
|
|
344
|
+
async update(skillId, update) {
|
|
345
|
+
await this.client.skillsUpdate({ skillKey: skillId, ...update });
|
|
346
|
+
}
|
|
347
|
+
async search(query, limit) {
|
|
348
|
+
const result = await this.client.skillsSearch({ query, limit });
|
|
349
|
+
return result.results.map((item) => ({
|
|
350
|
+
id: item.slug,
|
|
351
|
+
name: item.displayName || item.slug,
|
|
352
|
+
description: item.summary,
|
|
353
|
+
version: item.version,
|
|
354
|
+
owner: item.owner?.displayName || item.ownerHandle,
|
|
355
|
+
}));
|
|
356
|
+
}
|
|
357
|
+
async install(request) {
|
|
358
|
+
const result = request.source === 'registry'
|
|
359
|
+
? await this.client.skillsInstall({ source: 'clawhub', slug: request.id, version: request.version, force: request.force })
|
|
360
|
+
: await this.client.skillsInstall({ source: 'upload', uploadId: request.uploadId, slug: request.id, force: request.force, sha256: request.sha256 });
|
|
361
|
+
return {
|
|
362
|
+
ok: result.ok,
|
|
363
|
+
skillId: result.slug ?? request.id,
|
|
364
|
+
message: result.message,
|
|
365
|
+
warnings: result.warnings,
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
async createSkill(request) {
|
|
369
|
+
if (!this.options.exec)
|
|
370
|
+
throw new Error('Creating skills is unavailable for this agent.');
|
|
371
|
+
const id = request.id.trim();
|
|
372
|
+
if (!/^[a-z0-9](?:[a-z0-9-]{0,78}[a-z0-9])?$/.test(id)) {
|
|
373
|
+
throw new Error('Skill IDs must be lowercase slugs between 1 and 80 characters.');
|
|
374
|
+
}
|
|
375
|
+
if (!request.content.trim())
|
|
376
|
+
throw new Error('SKILL.md cannot be empty.');
|
|
377
|
+
const content = new globalThis.TextEncoder().encode(request.content);
|
|
378
|
+
if (content.length > MAX_SKILL_DOCUMENT_BYTES)
|
|
379
|
+
throw new Error('SKILL.md exceeds the 1 MiB write limit.');
|
|
380
|
+
if ((request.directories?.length ?? 0) > MAX_SKILL_DIRECTORIES) {
|
|
381
|
+
throw new Error(`A skill can contain at most ${MAX_SKILL_DIRECTORIES} empty directories during creation.`);
|
|
382
|
+
}
|
|
383
|
+
const directories = [...new Set((request.directories ?? []).map((path) => validateResourcePath(path)))]
|
|
384
|
+
.sort((a, b) => a.split('/').length - b.split('/').length || a.localeCompare(b));
|
|
385
|
+
for (const directory of directories) {
|
|
386
|
+
if (new globalThis.TextEncoder().encode(directory).length > MAX_SKILL_DIRECTORY_PATH_BYTES) {
|
|
387
|
+
throw new Error('Skill directory paths cannot exceed 1 KiB.');
|
|
388
|
+
}
|
|
389
|
+
if (directory.split('/').some((segment) => segment.toLowerCase() === 'skill.md')) {
|
|
390
|
+
throw new Error('SKILL.md must be a file, not a directory.');
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
const report = await this.client.skillsStatus();
|
|
394
|
+
if (report.skills.some((skill) => skill.skillKey === id))
|
|
395
|
+
throw new Error('A skill with this ID already exists.');
|
|
396
|
+
if (!report.managedSkillsDir?.trim())
|
|
397
|
+
throw new Error('The managed skills directory is unavailable.');
|
|
398
|
+
const createToken = globalThis.crypto.randomUUID();
|
|
399
|
+
const baseInput = { root: report.managedSkillsDir, id, createToken };
|
|
400
|
+
let staged = false;
|
|
401
|
+
try {
|
|
402
|
+
await this.executeCreate({ action: 'create-start', ...baseInput, directories });
|
|
403
|
+
staged = true;
|
|
404
|
+
for (let offset = 0; offset < content.length; offset += SKILL_RESOURCE_WRITE_CHUNK_BYTES) {
|
|
405
|
+
await this.executeCreate({
|
|
406
|
+
action: 'create-append',
|
|
407
|
+
...baseInput,
|
|
408
|
+
content: content.subarray(offset, offset + SKILL_RESOURCE_WRITE_CHUNK_BYTES),
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
const result = await this.executeCreate({ action: 'create-finish', ...baseInput });
|
|
412
|
+
this.entries.clear();
|
|
413
|
+
this.resourceAccess.clear();
|
|
414
|
+
this.writableRoots = [];
|
|
415
|
+
return result;
|
|
416
|
+
}
|
|
417
|
+
catch (error) {
|
|
418
|
+
if (staged)
|
|
419
|
+
await this.executeCreate({ action: 'create-abort', ...baseInput }).catch(() => undefined);
|
|
420
|
+
throw error;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
async listRecoveryCandidates() {
|
|
424
|
+
if (!this.options.exec)
|
|
425
|
+
return [];
|
|
426
|
+
const report = await this.client.skillsStatus();
|
|
427
|
+
if (!report.workspaceDir?.trim() || !report.managedSkillsDir?.trim())
|
|
428
|
+
return [];
|
|
429
|
+
const result = await this.options.exec(buildOpenClawSkillRecoveryScanCommand(report.workspaceDir));
|
|
430
|
+
if (result.exitCode !== 0)
|
|
431
|
+
throw new Error(result.stderr || 'Could not inspect workspace skill files.');
|
|
432
|
+
try {
|
|
433
|
+
const candidates = JSON.parse(result.stdout || '[]');
|
|
434
|
+
return Array.isArray(candidates) ? candidates : [];
|
|
435
|
+
}
|
|
436
|
+
catch {
|
|
437
|
+
throw new Error('Workspace skill recovery returned an invalid response.');
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
async recoverSkill(request) {
|
|
441
|
+
if (!this.options.exec)
|
|
442
|
+
throw new Error('Recovering workspace skills is unavailable for this agent.');
|
|
443
|
+
if (request.candidateId !== LOOSE_WORKSPACE_SKILL_CANDIDATE_ID)
|
|
444
|
+
throw new Error('Unknown workspace skill recovery candidate.');
|
|
445
|
+
const skillId = request.skillId.trim();
|
|
446
|
+
if (!/^[a-z0-9](?:[a-z0-9-]{0,78}[a-z0-9])?$/.test(skillId)) {
|
|
447
|
+
throw new Error('Skill IDs must be lowercase slugs between 1 and 80 characters.');
|
|
448
|
+
}
|
|
449
|
+
const paths = [...new Set(request.paths.map((path) => validateResourcePath(path)))]
|
|
450
|
+
.filter((path) => path !== 'SKILL.md');
|
|
451
|
+
if (paths.some((path) => path.includes('/')))
|
|
452
|
+
throw new Error('Recovery items must be direct children of the workspace skills folder.');
|
|
453
|
+
const report = await this.client.skillsStatus();
|
|
454
|
+
if (!report.workspaceDir?.trim())
|
|
455
|
+
throw new Error('The workspace directory is unavailable.');
|
|
456
|
+
if (!report.managedSkillsDir?.trim())
|
|
457
|
+
throw new Error('The managed skills directory is unavailable.');
|
|
458
|
+
const sourceRoot = `${normalizeAbsolutePath(report.workspaceDir)}/skills`;
|
|
459
|
+
const collision = report.skills.some((skill) => skill.skillKey === skillId
|
|
460
|
+
&& !(normalizeAbsolutePath(skill.baseDir ?? '') === sourceRoot
|
|
461
|
+
&& normalizeAbsolutePath(skill.filePath ?? '') === `${sourceRoot}/SKILL.md`));
|
|
462
|
+
if (collision)
|
|
463
|
+
throw new Error('A skill with this ID already exists.');
|
|
464
|
+
const result = await this.options.exec(buildOpenClawSkillRecoverCommand({
|
|
465
|
+
workspaceDir: report.workspaceDir,
|
|
466
|
+
managedSkillsDir: report.managedSkillsDir,
|
|
467
|
+
skillId,
|
|
468
|
+
paths,
|
|
469
|
+
recoveryToken: globalThis.crypto.randomUUID(),
|
|
470
|
+
}));
|
|
471
|
+
if (result.exitCode !== 0)
|
|
472
|
+
throw new Error(result.stderr || 'Workspace skill recovery failed.');
|
|
473
|
+
try {
|
|
474
|
+
const recovered = JSON.parse(result.stdout || '{}');
|
|
475
|
+
if (recovered.skillId !== skillId)
|
|
476
|
+
throw new Error();
|
|
477
|
+
this.entries.clear();
|
|
478
|
+
this.resourceAccess.clear();
|
|
479
|
+
this.writableRoots = [];
|
|
480
|
+
return recovered;
|
|
481
|
+
}
|
|
482
|
+
catch {
|
|
483
|
+
throw new Error('Workspace skill recovery returned an invalid response.');
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
async resourceEntry(skillId) {
|
|
487
|
+
if (this.entries.size === 0)
|
|
488
|
+
await this.list();
|
|
489
|
+
const entry = this.entries.get(skillId);
|
|
490
|
+
if (!entry?.baseDir)
|
|
491
|
+
throw new Error(`Skill resources are unavailable for ${skillId}.`);
|
|
492
|
+
if (!this.options.exec)
|
|
493
|
+
throw new Error('Skill resources are unavailable for this agent.');
|
|
494
|
+
return entry;
|
|
495
|
+
}
|
|
496
|
+
async executeResource(input) {
|
|
497
|
+
if (!this.options.exec)
|
|
498
|
+
throw new Error('Skill resources are unavailable for this agent.');
|
|
499
|
+
const result = await this.options.exec(buildOpenClawSkillResourceCommand(input));
|
|
500
|
+
if (result.exitCode !== 0)
|
|
501
|
+
throw new Error(result.stderr || 'Skill resource operation failed.');
|
|
502
|
+
try {
|
|
503
|
+
return JSON.parse(result.stdout || '{}');
|
|
504
|
+
}
|
|
505
|
+
catch {
|
|
506
|
+
throw new Error('Skill resource operation returned an invalid response.');
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
async executeCreate(input) {
|
|
510
|
+
if (!this.options.exec)
|
|
511
|
+
throw new Error('Creating skills is unavailable for this agent.');
|
|
512
|
+
const result = await this.options.exec(buildOpenClawSkillCreateCommand(input));
|
|
513
|
+
if (result.exitCode !== 0)
|
|
514
|
+
throw new Error(result.stderr || 'Skill creation failed.');
|
|
515
|
+
try {
|
|
516
|
+
return JSON.parse(result.stdout || '{}');
|
|
517
|
+
}
|
|
518
|
+
catch {
|
|
519
|
+
throw new Error('Skill creation returned an invalid response.');
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
assertWritable(skillId) {
|
|
523
|
+
if (this.resourceAccess.get(skillId) !== 'read-write') {
|
|
524
|
+
throw new Error('This skill is read-only.');
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
async listResources(skillId, path = '') {
|
|
528
|
+
const entry = await this.resourceEntry(skillId);
|
|
529
|
+
const relativePath = validateResourcePath(path, true);
|
|
530
|
+
return this.executeResource({ action: 'list', root: entry.baseDir, path: relativePath });
|
|
531
|
+
}
|
|
532
|
+
async readResource(skillId, path) {
|
|
533
|
+
const entry = await this.resourceEntry(skillId);
|
|
534
|
+
const relativePath = validateResourcePath(path);
|
|
535
|
+
const result = await this.executeResource({ action: 'read', root: entry.baseDir, path: relativePath });
|
|
536
|
+
return base64ToBytes(result.content);
|
|
537
|
+
}
|
|
538
|
+
async writeResource(skillId, path, content) {
|
|
539
|
+
const entry = await this.resourceEntry(skillId);
|
|
540
|
+
this.assertWritable(skillId);
|
|
541
|
+
const relativePath = validateResourcePath(path);
|
|
542
|
+
if (content.length > MAX_SKILL_RESOURCE_BYTES)
|
|
543
|
+
throw new Error('Skill resource exceeds the 10 MiB write limit.');
|
|
544
|
+
const uploadToken = globalThis.crypto.randomUUID();
|
|
545
|
+
const baseInput = { root: entry.baseDir, path: relativePath, writableRoots: this.writableRoots, uploadToken };
|
|
546
|
+
try {
|
|
547
|
+
await this.executeResource({ action: 'write-start', ...baseInput });
|
|
548
|
+
for (let offset = 0; offset < content.length; offset += SKILL_RESOURCE_WRITE_CHUNK_BYTES) {
|
|
549
|
+
await this.executeResource({
|
|
550
|
+
action: 'write-append',
|
|
551
|
+
...baseInput,
|
|
552
|
+
content: content.subarray(offset, offset + SKILL_RESOURCE_WRITE_CHUNK_BYTES),
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
await this.executeResource({ action: 'write-finish', ...baseInput });
|
|
556
|
+
}
|
|
557
|
+
catch (error) {
|
|
558
|
+
await this.executeResource({ action: 'write-abort', ...baseInput }).catch(() => undefined);
|
|
559
|
+
throw error;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
async deleteResource(skillId, path, options) {
|
|
563
|
+
const entry = await this.resourceEntry(skillId);
|
|
564
|
+
this.assertWritable(skillId);
|
|
565
|
+
const relativePath = validateResourcePath(path);
|
|
566
|
+
await this.executeResource({ action: 'delete', root: entry.baseDir, path: relativePath, recursive: options?.recursive, writableRoots: this.writableRoots });
|
|
567
|
+
}
|
|
568
|
+
async createResourceDirectory(skillId, path) {
|
|
569
|
+
const entry = await this.resourceEntry(skillId);
|
|
570
|
+
this.assertWritable(skillId);
|
|
571
|
+
const relativePath = validateResourcePath(path);
|
|
572
|
+
await this.executeResource({ action: 'mkdir', root: entry.baseDir, path: relativePath, writableRoots: this.writableRoots });
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
//# sourceMappingURL=skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/openclaw/skills.ts"],"names":[],"mappings":"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"}
|