@botmux-ai/plugin-demo-addon 0.1.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 ADDED
@@ -0,0 +1,13 @@
1
+ # Botmux Demo Addon
2
+
3
+ Full-surface example plugin for the Botmux plugin system. It contributes CLI,
4
+ Skill, MCP, Dashboard, and service integrations, and depends on `demo-base`.
5
+
6
+ GitHub: https://github.com/botmux-ai/botmux-plugin-demo/tree/main/packages/demo-addon
7
+
8
+ ```bash
9
+ botmux plugin install demo-base
10
+ botmux plugin install demo-addon
11
+ botmux plugin enable demo-base
12
+ botmux plugin enable demo-addon
13
+ ```
@@ -0,0 +1,13 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "commands": [
4
+ {
5
+ "name": "addon:ping",
6
+ "description": "Return a structured response from the demo-addon CLI surface."
7
+ },
8
+ {
9
+ "name": "addon:resolve",
10
+ "description": "Resolve a path through the plugin API."
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,13 @@
1
+ export default {
2
+ 'addon:ping'(ctx) {
3
+ return JSON.stringify({
4
+ pluginId: ctx.pluginId,
5
+ args: ctx.args,
6
+ settingsPath: ctx.api.settingsPath,
7
+ });
8
+ },
9
+
10
+ 'addon:resolve'(ctx) {
11
+ return ctx.api.resolve('./dashboard/index.js');
12
+ },
13
+ };
@@ -0,0 +1,3 @@
1
+ export default function DemoAddonDashboard({ pluginId }) {
2
+ return `Demo dashboard loaded for ${pluginId}`;
3
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "transport": "stdio",
3
+ "command": [
4
+ "./mcp/server.js",
5
+ "--direct"
6
+ ],
7
+ "env": {
8
+ "DEMO_MCP_PLUGIN": "demo-addon"
9
+ }
10
+ }
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+ import { createInterface } from 'node:readline';
3
+
4
+ const serverName = process.env.DEMO_MCP_PLUGIN || 'demo-addon';
5
+ const routeName = 'demo-addon';
6
+ const input = createInterface({ input: process.stdin, crlfDelay: Infinity });
7
+
8
+ function send(message) {
9
+ process.stdout.write(`${JSON.stringify(message)}\n`);
10
+ }
11
+
12
+ input.on('line', (line) => {
13
+ if (!line.trim()) return;
14
+ let request;
15
+ try {
16
+ request = JSON.parse(line);
17
+ } catch {
18
+ send({ jsonrpc: '2.0', id: null, error: { code: -32700, message: 'Parse error' } });
19
+ return;
20
+ }
21
+ if (request.id === undefined) return;
22
+ if (request.method === 'initialize') {
23
+ send({
24
+ jsonrpc: '2.0',
25
+ id: request.id,
26
+ result: {
27
+ protocolVersion: request.params?.protocolVersion ?? '2024-11-05',
28
+ capabilities: { tools: {} },
29
+ serverInfo: { name: serverName, version: '0.1.0' },
30
+ },
31
+ });
32
+ return;
33
+ }
34
+ if (request.method === 'tools/list') {
35
+ send({
36
+ jsonrpc: '2.0',
37
+ id: request.id,
38
+ result: {
39
+ tools: [
40
+ { name: 'echo', description: 'Shared collision fixture', inputSchema: { type: 'object' } },
41
+ { name: `${routeName}_unique`, description: 'Unique addon tool', inputSchema: { type: 'object' } },
42
+ ],
43
+ },
44
+ });
45
+ return;
46
+ }
47
+ if (request.method === 'tools/call') {
48
+ send({
49
+ jsonrpc: '2.0',
50
+ id: request.id,
51
+ result: { content: [{ type: 'text', text: `${routeName}:${request.params?.name}` }] },
52
+ });
53
+ return;
54
+ }
55
+ if (request.method === 'ping') {
56
+ send({ jsonrpc: '2.0', id: request.id, result: {} });
57
+ return;
58
+ }
59
+ send({ jsonrpc: '2.0', id: request.id, error: { code: -32601, message: 'Method not found' } });
60
+ });
@@ -0,0 +1,4 @@
1
+ {
2
+ "private": true,
3
+ "type": "module"
4
+ }
@@ -0,0 +1,20 @@
1
+ const port = Number(process.env.BOTMUX_DEMO_ADDON_SERVICE_PORT ?? 9356);
2
+
3
+ export default {
4
+ mode: 'auto',
5
+ port,
6
+ pm2: {
7
+ script: './service/server.js',
8
+ args: ['--port', String(port)],
9
+ env: {
10
+ PORT: String(port),
11
+ },
12
+ autorestart: true,
13
+ },
14
+ urls({ host }) {
15
+ return {
16
+ openUrl: `http://${host}:${port}/`,
17
+ healthUrl: `http://${host}:${port}/health`,
18
+ };
19
+ },
20
+ };
@@ -0,0 +1,32 @@
1
+ import { createServer } from 'node:http';
2
+
3
+ if (process.argv.includes('--check')) {
4
+ process.exit(0);
5
+ }
6
+
7
+ function argValue(flag) {
8
+ const index = process.argv.indexOf(flag);
9
+ return index >= 0 ? process.argv[index + 1] : undefined;
10
+ }
11
+
12
+ const port = Number(argValue('--port') ?? process.env.PORT ?? 9356);
13
+ const startedAt = new Date().toISOString();
14
+ const server = createServer((req, res) => {
15
+ if (req.url === '/health') {
16
+ res.writeHead(200, { 'content-type': 'application/json' });
17
+ res.end(JSON.stringify({ ok: true, pid: process.pid, startedAt }));
18
+ return;
19
+ }
20
+ res.writeHead(200, { 'content-type': 'text/plain' });
21
+ res.end('botmux demo addon service\n');
22
+ });
23
+
24
+ server.listen(port, '0.0.0.0');
25
+
26
+ function shutdown() {
27
+ server.close(() => process.exit(0));
28
+ setTimeout(() => process.exit(0), 1000).unref();
29
+ }
30
+
31
+ process.on('SIGINT', shutdown);
32
+ process.on('SIGTERM', shutdown);
@@ -0,0 +1,8 @@
1
+ ---
2
+ name: botmux-demo-addon
3
+ description: Demo skill installed by the botmux demo-addon plugin.
4
+ ---
5
+
6
+ # Botmux Demo Addon
7
+
8
+ Use this skill only as a fixture for botmux plugin installation and cleanup.
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@botmux-ai/plugin-demo-addon",
3
+ "version": "0.1.0",
4
+ "description": "Addon fixture plugin for botmux plugin conformance tests.",
5
+ "type": "module",
6
+ "keywords": [
7
+ "botmux-plugin"
8
+ ],
9
+ "botmux": {
10
+ "schemaVersion": 1,
11
+ "id": "demo-addon",
12
+ "displayName": "Demo Addon",
13
+ "dependencies": {
14
+ "plugins": [
15
+ "demo-base"
16
+ ]
17
+ },
18
+ "service": {
19
+ "mode": "auto"
20
+ }
21
+ },
22
+ "files": [
23
+ "dist/"
24
+ ],
25
+ "publishConfig": {
26
+ "registry": "https://registry.npmjs.org/",
27
+ "access": "public"
28
+ },
29
+ "license": "MIT"
30
+ }