rol-websocket-channel 1.4.2 → 1.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/{MQTT-API /346/226/260/345/242/236/346/226/207/344/273/266/345/212/237/350/203/275.md" → MQTT-API 5-6.md } +89 -1
  2. package/dist/index.js +617 -617
  3. package/dist/message-handler.js +515 -503
  4. package/dist/src/admin/cli.js +43 -43
  5. package/dist/src/admin/jsonrpc.js +60 -60
  6. package/dist/src/admin/lib/fs.js +30 -30
  7. package/dist/src/admin/lib/paths.js +80 -80
  8. package/dist/src/admin/methods/admin.js +60 -60
  9. package/dist/src/admin/methods/agents-extended.js +251 -251
  10. package/dist/src/admin/methods/artifacts.js +736 -642
  11. package/dist/src/admin/methods/artifacts.test.js +210 -191
  12. package/dist/src/admin/methods/cron.js +250 -250
  13. package/dist/src/admin/methods/index.js +104 -102
  14. package/dist/src/admin/methods/mem9.js +309 -270
  15. package/dist/src/admin/methods/mem9.test.js +34 -0
  16. package/dist/src/admin/methods/memory.js +363 -363
  17. package/dist/src/admin/methods/models-extended.js +190 -190
  18. package/dist/src/admin/methods/models.js +195 -195
  19. package/dist/src/admin/methods/pairing.js +268 -268
  20. package/dist/src/admin/methods/sessions-extended.js +215 -215
  21. package/dist/src/admin/methods/sessions.js +75 -75
  22. package/dist/src/admin/methods/skills-extended.js +157 -157
  23. package/dist/src/admin/methods/skills-toggle.js +183 -183
  24. package/dist/src/admin/methods/skills.js +528 -528
  25. package/dist/src/admin/methods/system.js +271 -180
  26. package/dist/src/admin/methods/usage.js +1170 -1170
  27. package/dist/src/admin/types.js +1 -1
  28. package/dist/src/mqtt/connection-manager.js +209 -209
  29. package/dist/src/mqtt/index.js +5 -5
  30. package/dist/src/mqtt/mqtt-client.js +110 -110
  31. package/dist/src/mqtt/mqtt.test.js +418 -418
  32. package/dist/src/mqtt/types.js +2 -2
  33. package/dist/src/shared/context.js +24 -24
  34. package/dist/src/shared/wrapper.js +23 -23
  35. package/message-handler.ts +15 -1
  36. package/openclaw.plugin.json +73 -0
  37. package/package.json +1 -1
  38. package/src/admin/methods/artifacts.test.ts +35 -0
  39. package/src/admin/methods/artifacts.ts +140 -2
  40. package/src/admin/methods/index.ts +3 -1
  41. package/src/admin/methods/mem9.test.ts +39 -0
  42. package/src/admin/methods/mem9.ts +48 -1
  43. package/src/admin/methods/system.ts +129 -1
@@ -1,157 +1,157 @@
1
- import fs from 'node:fs';
2
- import path from 'node:path';
3
- import { pathExists, readJsonFile, writeJsonFile } from '../lib/fs.js';
4
- import { JsonRpcException, JSON_RPC_ERRORS } from '../jsonrpc.js';
5
- import { getInstalledSkillsFromCli } from './skills.js';
6
- export const getInstalledSkill = async (params, context) => {
7
- const objectParams = isObject(params) ? params : {};
8
- const slug = typeof objectParams.slug === 'string' ? objectParams.slug : null;
9
- if (!slug) {
10
- throw new JsonRpcException(JSON_RPC_ERRORS.invalidParams, 'Missing required parameter: slug');
11
- }
12
- const skills = await getInstalledSkillsFromCli(context);
13
- const skill = skills.find((item) => isObject(item) && item.slug === slug);
14
- if (!skill) {
15
- throw new JsonRpcException(JSON_RPC_ERRORS.invalidParams, `Skill not installed: ${slug}`);
16
- }
17
- return skill;
18
- };
19
- export const uninstallSkill = async (params, context) => {
20
- const objectParams = isObject(params) ? params : {};
21
- const slug = typeof objectParams.slug === 'string' ? objectParams.slug : null;
22
- const scope = typeof objectParams.scope === 'string' ? objectParams.scope : 'global';
23
- if (!slug) {
24
- throw new JsonRpcException(JSON_RPC_ERRORS.invalidParams, 'Missing required parameter: slug');
25
- }
26
- if (slug.includes('..')) {
27
- throw new JsonRpcException(JSON_RPC_ERRORS.invalidParams, 'Invalid skill slug: must not contain ..');
28
- }
29
- const customSkill = await findCustomInstalledSkill(context, slug);
30
- const skills = await getInstalledSkillsFromCli(context);
31
- const skill = customSkill ?? skills.find((item) => isObject(item) && item.slug === slug);
32
- if (!skill || !isObject(skill)) {
33
- throw new JsonRpcException(JSON_RPC_ERRORS.invalidParams, `Skill not installed: ${slug}`);
34
- }
35
- const skillPathValue = typeof skill.customInstallPath === 'string' ? skill.customInstallPath :
36
- typeof skill.installPath === 'string' ? skill.installPath :
37
- null;
38
- if (!skillPathValue) {
39
- throw new JsonRpcException(JSON_RPC_ERRORS.invalidParams, `Skill cannot be uninstalled: ${slug}`);
40
- }
41
- const normalizedSkillPath = path.normalize(skillPathValue);
42
- const globalSkillsRoot = path.normalize(path.join(context.openclawRoot, 'skills'));
43
- const workspaceSkillsRoot = path.normalize(path.join(context.openclawRoot, 'workspace', '.openclaw', 'skills'));
44
- const insideGlobal = normalizedSkillPath === globalSkillsRoot || normalizedSkillPath.startsWith(`${globalSkillsRoot}${path.sep}`);
45
- const insideWorkspace = normalizedSkillPath === workspaceSkillsRoot || normalizedSkillPath.startsWith(`${workspaceSkillsRoot}${path.sep}`);
46
- if (!insideGlobal && !insideWorkspace) {
47
- throw new JsonRpcException(JSON_RPC_ERRORS.invalidParams, 'Invalid skill path: must be within skills directory');
48
- }
49
- if (!(await pathExists(skillPathValue))) {
50
- throw new JsonRpcException(JSON_RPC_ERRORS.invalidParams, `Skill not installed: ${slug} (scope: ${scope})`);
51
- }
52
- await fs.promises.rm(skillPathValue, { recursive: true, force: true });
53
- await removeSkillFromDefaults(context, slug);
54
- return {
55
- success: true,
56
- slug,
57
- scope,
58
- removedPath: skillPathValue,
59
- message: `Skill ${slug} uninstalled successfully`
60
- };
61
- };
62
- function isObject(value) {
63
- return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
64
- }
65
- async function findCustomInstalledSkill(context, requestedSlug) {
66
- const roots = [
67
- path.join(context.openclawRoot, 'skills'),
68
- path.join(context.openclawRoot, 'workspace', '.openclaw', 'skills')
69
- ];
70
- for (const root of roots) {
71
- if (!(await pathExists(root))) {
72
- continue;
73
- }
74
- const entries = await fs.promises.readdir(root, { withFileTypes: true });
75
- for (const entry of entries) {
76
- if (!entry.isDirectory()) {
77
- continue;
78
- }
79
- const installPath = path.join(root, entry.name);
80
- const aliases = await collectCustomSkillAliases(installPath, entry.name);
81
- if (!aliases.has(requestedSlug)) {
82
- continue;
83
- }
84
- return {
85
- slug: aliases.has(requestedSlug) ? requestedSlug : entry.name,
86
- custom: true,
87
- installPath
88
- };
89
- }
90
- }
91
- return null;
92
- }
93
- async function collectCustomSkillAliases(installPath, dirName) {
94
- const aliases = new Set([dirName, sanitizeAlias(dirName)]);
95
- const skillJsonPath = path.join(installPath, 'skill.json');
96
- const packageJsonPath = path.join(installPath, 'package.json');
97
- const installMetaPath = path.join(installPath, '.openclaw-admin-bridge-install.json');
98
- if (await pathExists(skillJsonPath)) {
99
- const skillJson = await readJsonFile(skillJsonPath);
100
- if (typeof skillJson.slug === 'string')
101
- aliases.add(skillJson.slug);
102
- if (typeof skillJson.name === 'string')
103
- aliases.add(skillJson.name);
104
- }
105
- if (await pathExists(packageJsonPath)) {
106
- const packageJson = await readJsonFile(packageJsonPath);
107
- if (typeof packageJson.name === 'string') {
108
- aliases.add(packageJson.name);
109
- const lastSegment = packageJson.name.includes('/') ? (packageJson.name.split('/').at(-1) ?? packageJson.name) : packageJson.name;
110
- aliases.add(lastSegment);
111
- aliases.add(sanitizeAlias(lastSegment));
112
- }
113
- }
114
- if (await pathExists(installMetaPath)) {
115
- const installMeta = await readJsonFile(installMetaPath);
116
- if (typeof installMeta.package === 'string') {
117
- aliases.add(installMeta.package);
118
- const lastSegment = installMeta.package.includes('/') ? (installMeta.package.split('/').at(-1) ?? installMeta.package) : installMeta.package;
119
- aliases.add(lastSegment);
120
- aliases.add(sanitizeAlias(lastSegment));
121
- }
122
- }
123
- return aliases;
124
- }
125
- function sanitizeAlias(value) {
126
- return value
127
- .replace(/^@/, '')
128
- .replace(/[\\/]/g, '-')
129
- .replace(/[^a-zA-Z0-9._-]+/g, '-')
130
- .replace(/-+/g, '-')
131
- .replace(/^-|-$/g, '')
132
- .toLowerCase();
133
- }
134
- async function removeSkillFromDefaults(context, slug) {
135
- const configPath = path.join(context.openclawRoot, 'openclaw.json');
136
- if (!(await pathExists(configPath))) {
137
- return;
138
- }
139
- const config = await readJsonFile(configPath);
140
- const currentSkills = config.agents?.defaults?.skills;
141
- if (!Array.isArray(currentSkills)) {
142
- return;
143
- }
144
- const nextSkills = currentSkills.filter((item) => item !== slug);
145
- if (nextSkills.length === currentSkills.length) {
146
- return;
147
- }
148
- if (!config.agents)
149
- config.agents = {};
150
- if (!config.agents.defaults)
151
- config.agents.defaults = {};
152
- config.agents.defaults.skills = nextSkills;
153
- await writeJsonFile(configPath, config);
154
- }
155
- function pickString(value) {
156
- return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;
157
- }
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { pathExists, readJsonFile, writeJsonFile } from '../lib/fs.js';
4
+ import { JsonRpcException, JSON_RPC_ERRORS } from '../jsonrpc.js';
5
+ import { getInstalledSkillsFromCli } from './skills.js';
6
+ export const getInstalledSkill = async (params, context) => {
7
+ const objectParams = isObject(params) ? params : {};
8
+ const slug = typeof objectParams.slug === 'string' ? objectParams.slug : null;
9
+ if (!slug) {
10
+ throw new JsonRpcException(JSON_RPC_ERRORS.invalidParams, 'Missing required parameter: slug');
11
+ }
12
+ const skills = await getInstalledSkillsFromCli(context);
13
+ const skill = skills.find((item) => isObject(item) && item.slug === slug);
14
+ if (!skill) {
15
+ throw new JsonRpcException(JSON_RPC_ERRORS.invalidParams, `Skill not installed: ${slug}`);
16
+ }
17
+ return skill;
18
+ };
19
+ export const uninstallSkill = async (params, context) => {
20
+ const objectParams = isObject(params) ? params : {};
21
+ const slug = typeof objectParams.slug === 'string' ? objectParams.slug : null;
22
+ const scope = typeof objectParams.scope === 'string' ? objectParams.scope : 'global';
23
+ if (!slug) {
24
+ throw new JsonRpcException(JSON_RPC_ERRORS.invalidParams, 'Missing required parameter: slug');
25
+ }
26
+ if (slug.includes('..')) {
27
+ throw new JsonRpcException(JSON_RPC_ERRORS.invalidParams, 'Invalid skill slug: must not contain ..');
28
+ }
29
+ const customSkill = await findCustomInstalledSkill(context, slug);
30
+ const skills = await getInstalledSkillsFromCli(context);
31
+ const skill = customSkill ?? skills.find((item) => isObject(item) && item.slug === slug);
32
+ if (!skill || !isObject(skill)) {
33
+ throw new JsonRpcException(JSON_RPC_ERRORS.invalidParams, `Skill not installed: ${slug}`);
34
+ }
35
+ const skillPathValue = typeof skill.customInstallPath === 'string' ? skill.customInstallPath :
36
+ typeof skill.installPath === 'string' ? skill.installPath :
37
+ null;
38
+ if (!skillPathValue) {
39
+ throw new JsonRpcException(JSON_RPC_ERRORS.invalidParams, `Skill cannot be uninstalled: ${slug}`);
40
+ }
41
+ const normalizedSkillPath = path.normalize(skillPathValue);
42
+ const globalSkillsRoot = path.normalize(path.join(context.openclawRoot, 'skills'));
43
+ const workspaceSkillsRoot = path.normalize(path.join(context.openclawRoot, 'workspace', '.openclaw', 'skills'));
44
+ const insideGlobal = normalizedSkillPath === globalSkillsRoot || normalizedSkillPath.startsWith(`${globalSkillsRoot}${path.sep}`);
45
+ const insideWorkspace = normalizedSkillPath === workspaceSkillsRoot || normalizedSkillPath.startsWith(`${workspaceSkillsRoot}${path.sep}`);
46
+ if (!insideGlobal && !insideWorkspace) {
47
+ throw new JsonRpcException(JSON_RPC_ERRORS.invalidParams, 'Invalid skill path: must be within skills directory');
48
+ }
49
+ if (!(await pathExists(skillPathValue))) {
50
+ throw new JsonRpcException(JSON_RPC_ERRORS.invalidParams, `Skill not installed: ${slug} (scope: ${scope})`);
51
+ }
52
+ await fs.promises.rm(skillPathValue, { recursive: true, force: true });
53
+ await removeSkillFromDefaults(context, slug);
54
+ return {
55
+ success: true,
56
+ slug,
57
+ scope,
58
+ removedPath: skillPathValue,
59
+ message: `Skill ${slug} uninstalled successfully`
60
+ };
61
+ };
62
+ function isObject(value) {
63
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
64
+ }
65
+ async function findCustomInstalledSkill(context, requestedSlug) {
66
+ const roots = [
67
+ path.join(context.openclawRoot, 'skills'),
68
+ path.join(context.openclawRoot, 'workspace', '.openclaw', 'skills')
69
+ ];
70
+ for (const root of roots) {
71
+ if (!(await pathExists(root))) {
72
+ continue;
73
+ }
74
+ const entries = await fs.promises.readdir(root, { withFileTypes: true });
75
+ for (const entry of entries) {
76
+ if (!entry.isDirectory()) {
77
+ continue;
78
+ }
79
+ const installPath = path.join(root, entry.name);
80
+ const aliases = await collectCustomSkillAliases(installPath, entry.name);
81
+ if (!aliases.has(requestedSlug)) {
82
+ continue;
83
+ }
84
+ return {
85
+ slug: aliases.has(requestedSlug) ? requestedSlug : entry.name,
86
+ custom: true,
87
+ installPath
88
+ };
89
+ }
90
+ }
91
+ return null;
92
+ }
93
+ async function collectCustomSkillAliases(installPath, dirName) {
94
+ const aliases = new Set([dirName, sanitizeAlias(dirName)]);
95
+ const skillJsonPath = path.join(installPath, 'skill.json');
96
+ const packageJsonPath = path.join(installPath, 'package.json');
97
+ const installMetaPath = path.join(installPath, '.openclaw-admin-bridge-install.json');
98
+ if (await pathExists(skillJsonPath)) {
99
+ const skillJson = await readJsonFile(skillJsonPath);
100
+ if (typeof skillJson.slug === 'string')
101
+ aliases.add(skillJson.slug);
102
+ if (typeof skillJson.name === 'string')
103
+ aliases.add(skillJson.name);
104
+ }
105
+ if (await pathExists(packageJsonPath)) {
106
+ const packageJson = await readJsonFile(packageJsonPath);
107
+ if (typeof packageJson.name === 'string') {
108
+ aliases.add(packageJson.name);
109
+ const lastSegment = packageJson.name.includes('/') ? (packageJson.name.split('/').at(-1) ?? packageJson.name) : packageJson.name;
110
+ aliases.add(lastSegment);
111
+ aliases.add(sanitizeAlias(lastSegment));
112
+ }
113
+ }
114
+ if (await pathExists(installMetaPath)) {
115
+ const installMeta = await readJsonFile(installMetaPath);
116
+ if (typeof installMeta.package === 'string') {
117
+ aliases.add(installMeta.package);
118
+ const lastSegment = installMeta.package.includes('/') ? (installMeta.package.split('/').at(-1) ?? installMeta.package) : installMeta.package;
119
+ aliases.add(lastSegment);
120
+ aliases.add(sanitizeAlias(lastSegment));
121
+ }
122
+ }
123
+ return aliases;
124
+ }
125
+ function sanitizeAlias(value) {
126
+ return value
127
+ .replace(/^@/, '')
128
+ .replace(/[\\/]/g, '-')
129
+ .replace(/[^a-zA-Z0-9._-]+/g, '-')
130
+ .replace(/-+/g, '-')
131
+ .replace(/^-|-$/g, '')
132
+ .toLowerCase();
133
+ }
134
+ async function removeSkillFromDefaults(context, slug) {
135
+ const configPath = path.join(context.openclawRoot, 'openclaw.json');
136
+ if (!(await pathExists(configPath))) {
137
+ return;
138
+ }
139
+ const config = await readJsonFile(configPath);
140
+ const currentSkills = config.agents?.defaults?.skills;
141
+ if (!Array.isArray(currentSkills)) {
142
+ return;
143
+ }
144
+ const nextSkills = currentSkills.filter((item) => item !== slug);
145
+ if (nextSkills.length === currentSkills.length) {
146
+ return;
147
+ }
148
+ if (!config.agents)
149
+ config.agents = {};
150
+ if (!config.agents.defaults)
151
+ config.agents.defaults = {};
152
+ config.agents.defaults.skills = nextSkills;
153
+ await writeJsonFile(configPath, config);
154
+ }
155
+ function pickString(value) {
156
+ return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;
157
+ }