@cmdop/bot 2026.2.28 → 2026.3.1
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 +4 -3
- package/dist/index.cjs +99 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +99 -1
- package/dist/index.js.map +1 -1
- package/examples/discord.ts +1 -1
- package/examples/multi-channel.ts +1 -1
- package/examples/slack.ts +1 -1
- package/examples/telegram.ts +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @cmdop/bot
|
|
2
2
|
|
|
3
|
-
Multi-channel bot framework for [CMDOP](https://cmdop.com) — run `/exec`, `/agent`, and `/files` commands from Telegram, Discord, and Slack.
|
|
3
|
+
Multi-channel bot framework for [CMDOP](https://cmdop.com) — run `/exec`, `/agent`, `/skills`, and `/files` commands from Telegram, Discord, and Slack.
|
|
4
4
|
|
|
5
5
|
```
|
|
6
6
|
pnpm add @cmdop/bot
|
|
@@ -19,7 +19,7 @@ await hub.addTelegram({ token: process.env.TELEGRAM_TOKEN });
|
|
|
19
19
|
await hub.start();
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
That's it. Your bot now responds to `/exec`, `/agent`, `/files`, and `/help`.
|
|
22
|
+
That's it. Your bot now responds to `/exec`, `/agent`, `/skills`, `/files`, and `/help`.
|
|
23
23
|
|
|
24
24
|
---
|
|
25
25
|
|
|
@@ -76,6 +76,7 @@ Requires Socket Mode enabled in your Slack app settings. See [examples/slack.ts]
|
|
|
76
76
|
|---------|-------|-------------------|
|
|
77
77
|
| `/exec` | `/exec <shell command>` | `EXECUTE` |
|
|
78
78
|
| `/agent` | `/agent <prompt>` | `EXECUTE` |
|
|
79
|
+
| `/skills` | `/skills list \| show <name> \| run <name> <prompt>` | `EXECUTE` |
|
|
79
80
|
| `/files` | `/files [read] <path>` | `READ` |
|
|
80
81
|
| `/help` | `/help` | none |
|
|
81
82
|
|
|
@@ -102,7 +103,7 @@ Permission levels (ordered, each includes all levels below):
|
|
|
102
103
|
|-------|--------|
|
|
103
104
|
| `NONE` | No commands (only `/help`) |
|
|
104
105
|
| `READ` | `/files` |
|
|
105
|
-
| `EXECUTE` | `/exec`, `/agent` |
|
|
106
|
+
| `EXECUTE` | `/exec`, `/agent`, `/skills` |
|
|
106
107
|
| `FILES` | _(reserved for future write operations)_ |
|
|
107
108
|
| `ADMIN` | All commands |
|
|
108
109
|
|
package/dist/index.cjs
CHANGED
|
@@ -16356,7 +16356,7 @@ var init_channel3 = __esm({
|
|
|
16356
16356
|
{ title: "Get help", message: "/help" }
|
|
16357
16357
|
]
|
|
16358
16358
|
});
|
|
16359
|
-
await say("Hello! Use `/exec`, `/agent`, `/files`, or `/help`.");
|
|
16359
|
+
await say("Hello! Use `/exec`, `/agent`, `/skills`, `/files`, or `/help`.");
|
|
16360
16360
|
},
|
|
16361
16361
|
threadContextChanged: async ({ saveThreadContext }) => {
|
|
16362
16362
|
await saveThreadContext();
|
|
@@ -16888,6 +16888,103 @@ ${lines.join("\n\n")}`;
|
|
|
16888
16888
|
}
|
|
16889
16889
|
};
|
|
16890
16890
|
|
|
16891
|
+
// src/handlers/skills.ts
|
|
16892
|
+
init_errors();
|
|
16893
|
+
var SkillsHandler = class extends BaseHandler {
|
|
16894
|
+
name = "skills";
|
|
16895
|
+
description = "List, show, or run skills on the remote machine";
|
|
16896
|
+
usage = "/skills list | /skills show <name> | /skills run <name> <prompt>";
|
|
16897
|
+
requiredPermission = "EXECUTE";
|
|
16898
|
+
maxOutput;
|
|
16899
|
+
constructor(client, logger, config = {}) {
|
|
16900
|
+
super(client, logger);
|
|
16901
|
+
this.maxOutput = config.maxOutputLength ?? 4e3;
|
|
16902
|
+
}
|
|
16903
|
+
async handle(ctx) {
|
|
16904
|
+
const subcommand = ctx.args[0]?.toLowerCase();
|
|
16905
|
+
if (!subcommand) {
|
|
16906
|
+
return err(new exports.CommandArgsError("skills", "Subcommand required. Usage: /skills list | /skills show <name> | /skills run <name> <prompt>"));
|
|
16907
|
+
}
|
|
16908
|
+
try {
|
|
16909
|
+
if (ctx.machine) {
|
|
16910
|
+
await this.client.skills.setMachine(ctx.machine);
|
|
16911
|
+
}
|
|
16912
|
+
switch (subcommand) {
|
|
16913
|
+
case "list":
|
|
16914
|
+
return await this.handleList();
|
|
16915
|
+
case "show":
|
|
16916
|
+
return await this.handleShow(ctx);
|
|
16917
|
+
case "run":
|
|
16918
|
+
return await this.handleRun(ctx);
|
|
16919
|
+
default:
|
|
16920
|
+
return err(new exports.CommandArgsError("skills", `Unknown subcommand "${subcommand}". Usage: /skills list | /skills show <name> | /skills run <name> <prompt>`));
|
|
16921
|
+
}
|
|
16922
|
+
} catch (e3) {
|
|
16923
|
+
const errMsg = e3 instanceof Error ? e3.message : String(e3);
|
|
16924
|
+
this.logger.error("Skills operation failed", { error: errMsg });
|
|
16925
|
+
if (errMsg.includes("session_id") || errMsg.includes("No active session")) {
|
|
16926
|
+
return err(new exports.CMDOPError("Machine is offline or CMDOP agent is not running.\nhttps://cmdop.com/downloads/"));
|
|
16927
|
+
}
|
|
16928
|
+
if (errMsg.includes("DEADLINE_EXCEEDED") || errMsg.includes("timeout")) {
|
|
16929
|
+
return err(new exports.CMDOPError("Request timed out. The skill may be too complex \u2014 try a simpler prompt."));
|
|
16930
|
+
}
|
|
16931
|
+
if (errMsg.includes("UNAVAILABLE") || errMsg.includes("Connection refused")) {
|
|
16932
|
+
return err(new exports.CMDOPError("Server unavailable. Check your connection and try again."));
|
|
16933
|
+
}
|
|
16934
|
+
return err(new exports.CMDOPError(`Skills error: ${errMsg}`, e3 instanceof Error ? e3 : void 0));
|
|
16935
|
+
}
|
|
16936
|
+
}
|
|
16937
|
+
async handleList() {
|
|
16938
|
+
const skills = await this.client.skills.list();
|
|
16939
|
+
if (skills.length === 0) {
|
|
16940
|
+
return ok({ type: "text", text: "No skills installed." });
|
|
16941
|
+
}
|
|
16942
|
+
const lines = skills.map(
|
|
16943
|
+
(s4) => s4.description ? `${s4.name} \u2014 ${s4.description}` : s4.name
|
|
16944
|
+
);
|
|
16945
|
+
return ok({ type: "text", text: lines.join("\n") });
|
|
16946
|
+
}
|
|
16947
|
+
async handleShow(ctx) {
|
|
16948
|
+
const name = ctx.args[1];
|
|
16949
|
+
if (!name) {
|
|
16950
|
+
return err(new exports.CommandArgsError("skills", "Skill name required. Usage: /skills show <name>"));
|
|
16951
|
+
}
|
|
16952
|
+
const detail = await this.client.skills.show(name);
|
|
16953
|
+
if (!detail.found) {
|
|
16954
|
+
return err(new exports.CMDOPError(detail.error ?? `Skill "${name}" not found`));
|
|
16955
|
+
}
|
|
16956
|
+
const parts = [];
|
|
16957
|
+
if (detail.info) {
|
|
16958
|
+
parts.push(`Skill: ${detail.info.name}`);
|
|
16959
|
+
if (detail.info.description) parts.push(`Description: ${detail.info.description}`);
|
|
16960
|
+
if (detail.info.author) parts.push(`Author: ${detail.info.author}`);
|
|
16961
|
+
if (detail.info.version) parts.push(`Version: ${detail.info.version}`);
|
|
16962
|
+
if (detail.info.origin) parts.push(`Origin: ${detail.info.origin}`);
|
|
16963
|
+
}
|
|
16964
|
+
if (detail.source) parts.push(`Source: ${detail.source}`);
|
|
16965
|
+
if (detail.content) {
|
|
16966
|
+
const preview = detail.content.length > this.maxOutput ? detail.content.slice(0, this.maxOutput) + "\n...(truncated)" : detail.content;
|
|
16967
|
+
parts.push(`
|
|
16968
|
+
System prompt:
|
|
16969
|
+
${preview}`);
|
|
16970
|
+
}
|
|
16971
|
+
return ok({ type: "code", code: parts.join("\n") });
|
|
16972
|
+
}
|
|
16973
|
+
async handleRun(ctx) {
|
|
16974
|
+
const name = ctx.args[1];
|
|
16975
|
+
if (!name) {
|
|
16976
|
+
return err(new exports.CommandArgsError("skills", "Skill name and prompt required. Usage: /skills run <name> <prompt>"));
|
|
16977
|
+
}
|
|
16978
|
+
const prompt = ctx.args.slice(2).join(" ").trim();
|
|
16979
|
+
if (!prompt) {
|
|
16980
|
+
return err(new exports.CommandArgsError("skills", "Prompt required. Usage: /skills run <name> <prompt>"));
|
|
16981
|
+
}
|
|
16982
|
+
const result = await this.client.skills.run(name, prompt);
|
|
16983
|
+
const code = result.text.length > this.maxOutput ? result.text.slice(0, this.maxOutput) + "\n...(truncated)" : result.text;
|
|
16984
|
+
return ok({ type: "code", code });
|
|
16985
|
+
}
|
|
16986
|
+
};
|
|
16987
|
+
|
|
16891
16988
|
// src/config.ts
|
|
16892
16989
|
init_errors();
|
|
16893
16990
|
var BotSettingsSchema = v4.z.object({
|
|
@@ -17007,6 +17104,7 @@ var IntegrationHub = class _IntegrationHub {
|
|
|
17007
17104
|
const hub = new _IntegrationHub(client, logger, settings2, permissions, dispatcher, mode);
|
|
17008
17105
|
hub.registerHandler(new TerminalHandler(client, logger, { maxOutputLength: settings2.maxOutputLength }));
|
|
17009
17106
|
hub.registerHandler(new AgentHandler(client, logger, { maxOutputLength: settings2.maxOutputLength }));
|
|
17107
|
+
hub.registerHandler(new SkillsHandler(client, logger, { maxOutputLength: settings2.maxOutputLength }));
|
|
17010
17108
|
hub.registerHandler(new FilesHandler(client, logger));
|
|
17011
17109
|
hub.registerHandler(new HelpHandler(client, logger, {
|
|
17012
17110
|
getCommands: () => dispatcher.getCommandList()
|