@metatell/bot-cli 0.0.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 ADDED
@@ -0,0 +1,63 @@
1
+ # @metatell/cli
2
+
3
+ CLI tool for Metatell bot development and testing.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g @metatell/cli
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Interactive Mode (Default)
14
+
15
+ ```bash
16
+ # 未ログインで入室
17
+ metatell-cli https://metatell.app/ROOM_ID
18
+
19
+ # ログイン済みユーザーとして入室
20
+ metatell-cli https://metatell.app/ROOM_ID -t "your-auth-token"
21
+ ```
22
+
23
+ Interactive mode provides:
24
+ - Real-time event monitoring
25
+ - Simple chat interface
26
+ - Commands: `status`, `users`, `quit`
27
+
28
+ ### Connect Command
29
+
30
+ Quick connection test:
31
+
32
+ ```bash
33
+ # 未ログインで接続テスト
34
+ metatell-cli connect https://metatell.app/ROOM_ID
35
+ ```
36
+
37
+ ### Inspect Command
38
+
39
+ Room inspection and monitoring:
40
+
41
+ ```bash
42
+ # ルーム情報の確認
43
+ metatell-cli inspect https://metatell.app/ROOM_ID
44
+ ```
45
+
46
+ ### Options
47
+
48
+ - `-t, --token <token>`: Authentication token (optional - 未ログインでも入室可能)
49
+ - `-n, --name <name>`: Bot display name (interactive mode)
50
+ - `-d, --debug`: Enable debug logging
51
+
52
+ ### Environment Variables
53
+
54
+ - `METATELL_TOKEN`: Default authentication token (optional)
55
+
56
+ ## Features
57
+
58
+ - Simple connection testing
59
+ - Room state inspection
60
+ - Interactive command-line interface
61
+ - User presence monitoring
62
+ - Message activity tracking
63
+ - Clean implementation using SDK facade API
package/dist/cli.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Metatell CLI - Interactive tool for bot development and testing
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;GAEG"}
package/dist/cli.js ADDED
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * Metatell CLI - Interactive tool for bot development and testing
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ var commander_1 = require("commander");
8
+ var connect_js_1 = require("./commands/connect.js");
9
+ var inspect_js_1 = require("./commands/inspect.js");
10
+ var interactive_js_1 = require("./commands/interactive.js");
11
+ var program = new commander_1.Command();
12
+ program
13
+ .name('metatell-cli')
14
+ .description('CLI tool for Metatell bot development and testing')
15
+ .version('1.0.0');
16
+ // Connect command - Simple connection test
17
+ program
18
+ .command('connect <url>')
19
+ .description('Connect to a Metatell room and show basic info')
20
+ .option('-t, --token <token>', 'Authentication token')
21
+ .option('-d, --debug', 'Enable debug logging')
22
+ .action(connect_js_1.connectCommand);
23
+ // Inspect command - Room inspection
24
+ program
25
+ .command('inspect <url>')
26
+ .description('Inspect room state and user presence')
27
+ .option('-t, --token <token>', 'Authentication token')
28
+ .action(inspect_js_1.inspectCommand);
29
+ // Interactive mode (default)
30
+ program
31
+ .command('interactive <url>')
32
+ .alias('i')
33
+ .description('Start interactive CLI mode')
34
+ .option('-t, --token <token>', 'Authentication token')
35
+ .option('-n, --name <name>', 'Bot display name', 'MetatellCLI')
36
+ .option('-d, --debug', 'Enable debug logging')
37
+ .action(interactive_js_1.startInteractiveMode);
38
+ // Default to interactive mode
39
+ program
40
+ .arguments('<url>')
41
+ .option('-t, --token <token>', 'Authentication token')
42
+ .option('-n, --name <name>', 'Bot display name', 'MetatellCLI')
43
+ .option('-d, --debug', 'Enable debug logging')
44
+ .action(function (url, options) {
45
+ (0, interactive_js_1.startInteractiveMode)(url, options);
46
+ });
47
+ program.parse();
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Simple connection test command
3
+ */
4
+ import type { CliOptions } from '../types.js';
5
+ export declare function connectCommand(url: string, options: CliOptions): Promise<void>;
6
+ //# sourceMappingURL=connect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAG7C,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,iBAkCpE"}
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ /**
3
+ * Simple connection test command
4
+ */
5
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7
+ return new (P || (P = Promise))(function (resolve, reject) {
8
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
9
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
11
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
12
+ });
13
+ };
14
+ var __generator = (this && this.__generator) || function (thisArg, body) {
15
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
16
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
17
+ function verb(n) { return function (v) { return step([n, v]); }; }
18
+ function step(op) {
19
+ if (f) throw new TypeError("Generator is already executing.");
20
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
21
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
22
+ if (y = 0, t) op = [op[0] & 2, t.value];
23
+ switch (op[0]) {
24
+ case 0: case 1: t = op; break;
25
+ case 4: _.label++; return { value: op[1], done: false };
26
+ case 5: _.label++; y = op[1]; op = [0]; continue;
27
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
28
+ default:
29
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
30
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
31
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
32
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
33
+ if (t[2]) _.ops.pop();
34
+ _.trys.pop(); continue;
35
+ }
36
+ op = body.call(thisArg, _);
37
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
38
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
39
+ }
40
+ };
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.connectCommand = connectCommand;
43
+ var sdk_1 = require("@metatell/sdk");
44
+ var url_js_1 = require("../utils/url.js");
45
+ function connectCommand(url, options) {
46
+ return __awaiter(this, void 0, void 0, function () {
47
+ var _a, serverUrl, roomId, client, users, error_1;
48
+ return __generator(this, function (_b) {
49
+ switch (_b.label) {
50
+ case 0:
51
+ console.log('Connecting to:', url);
52
+ _b.label = 1;
53
+ case 1:
54
+ _b.trys.push([1, 4, , 5]);
55
+ _a = (0, url_js_1.parseUrl)(url), serverUrl = _a.serverUrl, roomId = _a.roomId;
56
+ client = (0, sdk_1.createMetatellClient)({
57
+ serverUrl: serverUrl,
58
+ roomId: roomId,
59
+ token: options.token || process.env.METATELL_TOKEN || '',
60
+ username: 'MetatellCLI',
61
+ debug: options.debug,
62
+ });
63
+ return [4 /*yield*/, client.connect()];
64
+ case 2:
65
+ _b.sent();
66
+ console.log('✓ Connected successfully!');
67
+ console.log('Session ID:', client.getSessionId());
68
+ console.log('Status:', client.getStatus());
69
+ users = client.getUsers();
70
+ console.log("\nUsers in room: ".concat(users.length));
71
+ users.forEach(function (user) {
72
+ console.log("- ".concat(user.name || 'Anonymous', " (").concat(user.id, ")").concat(user.isBot ? ' [Bot]' : ''));
73
+ });
74
+ // Clean disconnect
75
+ return [4 /*yield*/, client.disconnect()];
76
+ case 3:
77
+ // Clean disconnect
78
+ _b.sent();
79
+ console.log('\n✓ Disconnected successfully');
80
+ process.exit(0);
81
+ return [3 /*break*/, 5];
82
+ case 4:
83
+ error_1 = _b.sent();
84
+ console.error('Connection failed:', error_1);
85
+ process.exit(1);
86
+ return [3 /*break*/, 5];
87
+ case 5: return [2 /*return*/];
88
+ }
89
+ });
90
+ });
91
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Room inspection command
3
+ */
4
+ import type { CliOptions } from '../types.js';
5
+ export declare function inspectCommand(url: string, options: CliOptions): Promise<void>;
6
+ //# sourceMappingURL=inspect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../../src/commands/inspect.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAG7C,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,iBA8DpE"}
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ /**
3
+ * Room inspection command
4
+ */
5
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7
+ return new (P || (P = Promise))(function (resolve, reject) {
8
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
9
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
11
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
12
+ });
13
+ };
14
+ var __generator = (this && this.__generator) || function (thisArg, body) {
15
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
16
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
17
+ function verb(n) { return function (v) { return step([n, v]); }; }
18
+ function step(op) {
19
+ if (f) throw new TypeError("Generator is already executing.");
20
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
21
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
22
+ if (y = 0, t) op = [op[0] & 2, t.value];
23
+ switch (op[0]) {
24
+ case 0: case 1: t = op; break;
25
+ case 4: _.label++; return { value: op[1], done: false };
26
+ case 5: _.label++; y = op[1]; op = [0]; continue;
27
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
28
+ default:
29
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
30
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
31
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
32
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
33
+ if (t[2]) _.ops.pop();
34
+ _.trys.pop(); continue;
35
+ }
36
+ op = body.call(thisArg, _);
37
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
38
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
39
+ }
40
+ };
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.inspectCommand = inspectCommand;
43
+ var sdk_1 = require("@metatell/sdk");
44
+ var url_js_1 = require("../utils/url.js");
45
+ function inspectCommand(url, options) {
46
+ return __awaiter(this, void 0, void 0, function () {
47
+ var _a, serverUrl, roomId, client, users, humans, bots, messageCount_1, joinCount_1, leaveCount_1, error_1;
48
+ return __generator(this, function (_b) {
49
+ switch (_b.label) {
50
+ case 0:
51
+ console.log('Inspecting room:', url);
52
+ _b.label = 1;
53
+ case 1:
54
+ _b.trys.push([1, 5, , 6]);
55
+ _a = (0, url_js_1.parseUrl)(url), serverUrl = _a.serverUrl, roomId = _a.roomId;
56
+ client = (0, sdk_1.createMetatellClient)({
57
+ serverUrl: serverUrl,
58
+ roomId: roomId,
59
+ token: options.token || process.env.METATELL_TOKEN || '',
60
+ username: 'MetatellInspector',
61
+ debug: false, // Keep quiet for inspection
62
+ });
63
+ return [4 /*yield*/, client.connect()];
64
+ case 2:
65
+ _b.sent();
66
+ console.log('\n=== Room Information ===');
67
+ console.log('Room ID:', roomId);
68
+ console.log('Server:', serverUrl);
69
+ console.log('Session:', client.getSessionId());
70
+ users = client.getUsers();
71
+ console.log('\n=== User Presence ===');
72
+ console.log("Total users: ".concat(users.length));
73
+ humans = users.filter(function (u) { return !u.isBot; });
74
+ bots = users.filter(function (u) { return u.isBot; });
75
+ console.log("Humans: ".concat(humans.length));
76
+ console.log("Bots: ".concat(bots.length));
77
+ if (users.length > 0) {
78
+ console.log('\nDetailed list:');
79
+ users.forEach(function (user) {
80
+ var type = user.isBot ? '[Bot]' : '[Human]';
81
+ console.log(" ".concat(type, " ").concat(user.name || 'Anonymous', " (").concat(user.id, ")"));
82
+ });
83
+ }
84
+ // Listen for a few seconds to detect activity
85
+ console.log('\n=== Monitoring Activity (5 seconds) ===');
86
+ messageCount_1 = 0;
87
+ joinCount_1 = 0;
88
+ leaveCount_1 = 0;
89
+ client.on('message', function () { return messageCount_1++; });
90
+ client.on('user-join', function () { return joinCount_1++; });
91
+ client.on('user-leave', function () { return leaveCount_1++; });
92
+ return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 5000); })];
93
+ case 3:
94
+ _b.sent();
95
+ console.log("Messages: ".concat(messageCount_1));
96
+ console.log("Users joined: ".concat(joinCount_1));
97
+ console.log("Users left: ".concat(leaveCount_1));
98
+ return [4 /*yield*/, client.disconnect()];
99
+ case 4:
100
+ _b.sent();
101
+ console.log('\n✓ Inspection complete');
102
+ process.exit(0);
103
+ return [3 /*break*/, 6];
104
+ case 5:
105
+ error_1 = _b.sent();
106
+ console.error('Inspection failed:', error_1);
107
+ process.exit(1);
108
+ return [3 /*break*/, 6];
109
+ case 6: return [2 /*return*/];
110
+ }
111
+ });
112
+ });
113
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Interactive mode command with rich commands support
3
+ */
4
+ import type { CliOptions } from '../types.js';
5
+ export declare function startInteractiveMode(url: string, options: CliOptions): Promise<void>;
6
+ //# sourceMappingURL=interactive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../../src/commands/interactive.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAI7C,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,iBAoH1E"}
@@ -0,0 +1,185 @@
1
+ "use strict";
2
+ /**
3
+ * Interactive mode command with rich commands support
4
+ */
5
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7
+ return new (P || (P = Promise))(function (resolve, reject) {
8
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
9
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
11
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
12
+ });
13
+ };
14
+ var __generator = (this && this.__generator) || function (thisArg, body) {
15
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
16
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
17
+ function verb(n) { return function (v) { return step([n, v]); }; }
18
+ function step(op) {
19
+ if (f) throw new TypeError("Generator is already executing.");
20
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
21
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
22
+ if (y = 0, t) op = [op[0] & 2, t.value];
23
+ switch (op[0]) {
24
+ case 0: case 1: t = op; break;
25
+ case 4: _.label++; return { value: op[1], done: false };
26
+ case 5: _.label++; y = op[1]; op = [0]; continue;
27
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
28
+ default:
29
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
30
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
31
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
32
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
33
+ if (t[2]) _.ops.pop();
34
+ _.trys.pop(); continue;
35
+ }
36
+ op = body.call(thisArg, _);
37
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
38
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
39
+ }
40
+ };
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.startInteractiveMode = startInteractiveMode;
43
+ var node_readline_1 = require("node:readline");
44
+ var sdk_1 = require("@metatell/sdk");
45
+ var commands_js_1 = require("../utils/commands.js");
46
+ var url_js_1 = require("../utils/url.js");
47
+ function startInteractiveMode(url, options) {
48
+ return __awaiter(this, void 0, void 0, function () {
49
+ var _a, serverUrl, roomId, client_1, rl_1, parser_1, error_1;
50
+ var _this = this;
51
+ return __generator(this, function (_b) {
52
+ switch (_b.label) {
53
+ case 0:
54
+ console.log('Starting interactive mode...');
55
+ _b.label = 1;
56
+ case 1:
57
+ _b.trys.push([1, 3, , 4]);
58
+ _a = (0, url_js_1.parseUrl)(url), serverUrl = _a.serverUrl, roomId = _a.roomId;
59
+ client_1 = (0, sdk_1.createMetatellClient)({
60
+ serverUrl: serverUrl,
61
+ roomId: roomId,
62
+ token: options.token || process.env.METATELL_TOKEN || '',
63
+ username: options.name || 'MetatellCLI',
64
+ debug: options.debug,
65
+ });
66
+ // Event handlers
67
+ client_1.on('connected', function () {
68
+ console.log('[Connected]');
69
+ });
70
+ client_1.on('disconnected', function (reason) {
71
+ console.log('[Disconnected]', reason || 'Connection closed');
72
+ });
73
+ // chat-messageイベントを使用して、より詳細なメッセージ情報を取得
74
+ client_1.on('chat-message', function (message) {
75
+ var mentionInfo = message.mention ? " (mentions @".concat(message.mention.name, ")") : '';
76
+ console.log("[Chat] ".concat(message.from.name, ": ").concat(message.text).concat(mentionInfo));
77
+ // デバッグ情報
78
+ if (options.debug) {
79
+ console.log("[Debug] Sender ID: ".concat(message.from.id));
80
+ }
81
+ });
82
+ // メンションハンドラーを設定
83
+ client_1.chat.onMention(function (event) {
84
+ console.log("[Mentioned by ".concat(event.from.name, "] ").concat(event.text));
85
+ // 自動的に返信
86
+ event.reply("Hello ".concat(event.from.name, "! You said: \"").concat(event.text, "\"")).catch(function (err) {
87
+ console.error('[Error replying]', err);
88
+ });
89
+ });
90
+ client_1.on('user-join', function (user) {
91
+ console.log('[User joined]', user.name || 'Anonymous', "(".concat(user.id, ")"));
92
+ });
93
+ client_1.on('user-leave', function (user) {
94
+ console.log('[User left]', user.name || 'Anonymous', "(".concat(user.id, ")"));
95
+ });
96
+ return [4 /*yield*/, client_1.connect()];
97
+ case 2:
98
+ _b.sent();
99
+ console.log('Connected to room:', roomId);
100
+ console.log('Session ID:', client_1.getSessionId());
101
+ console.log('Commands: /help for list of commands');
102
+ console.log('Type messages to send, or "quit" to exit\n');
103
+ rl_1 = (0, node_readline_1.createInterface)({
104
+ input: process.stdin,
105
+ output: process.stdout,
106
+ prompt: '> ',
107
+ });
108
+ parser_1 = new commands_js_1.CommandParser();
109
+ rl_1.on('line', function (line) { return __awaiter(_this, void 0, void 0, function () {
110
+ var input, result, error_2, error_3;
111
+ return __generator(this, function (_a) {
112
+ switch (_a.label) {
113
+ case 0:
114
+ input = line.trim();
115
+ // 特殊なキーワードのみ特別扱い
116
+ if (input === 'quit' || input === 'exit') {
117
+ rl_1.close();
118
+ return [2 /*return*/];
119
+ }
120
+ if (!input.startsWith('/')) return [3 /*break*/, 5];
121
+ _a.label = 1;
122
+ case 1:
123
+ _a.trys.push([1, 3, , 4]);
124
+ return [4 /*yield*/, parser_1.execute(input, client_1)];
125
+ case 2:
126
+ result = _a.sent();
127
+ if (!result.success) {
128
+ console.error('[Error]', result.message);
129
+ }
130
+ return [3 /*break*/, 4];
131
+ case 3:
132
+ error_2 = _a.sent();
133
+ console.error('[Error]', error_2 instanceof Error ? error_2.message : 'Command failed');
134
+ return [3 /*break*/, 4];
135
+ case 4: return [3 /*break*/, 9];
136
+ case 5:
137
+ if (!input) return [3 /*break*/, 9];
138
+ _a.label = 6;
139
+ case 6:
140
+ _a.trys.push([6, 8, , 9]);
141
+ return [4 /*yield*/, client_1.chat.send(input)];
142
+ case 7:
143
+ _a.sent();
144
+ console.log("[Sent] ".concat(input));
145
+ return [3 /*break*/, 9];
146
+ case 8:
147
+ error_3 = _a.sent();
148
+ console.error('[Error sending message]', error_3);
149
+ return [3 /*break*/, 9];
150
+ case 9:
151
+ rl_1.prompt();
152
+ return [2 /*return*/];
153
+ }
154
+ });
155
+ }); });
156
+ rl_1.on('close', function () { return __awaiter(_this, void 0, void 0, function () {
157
+ return __generator(this, function (_a) {
158
+ switch (_a.label) {
159
+ case 0:
160
+ console.log('\nShutting down...');
161
+ return [4 /*yield*/, client_1.disconnect()];
162
+ case 1:
163
+ _a.sent();
164
+ process.exit(0);
165
+ return [2 /*return*/];
166
+ }
167
+ });
168
+ }); });
169
+ // Show initial prompt
170
+ rl_1.prompt();
171
+ // Handle process termination
172
+ process.on('SIGINT', function () {
173
+ rl_1.close();
174
+ });
175
+ return [3 /*break*/, 4];
176
+ case 3:
177
+ error_1 = _b.sent();
178
+ console.error('Failed to start interactive mode:', error_1);
179
+ process.exit(1);
180
+ return [3 /*break*/, 4];
181
+ case 4: return [2 /*return*/];
182
+ }
183
+ });
184
+ });
185
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Main exports for @metatell/cli
3
+ */
4
+ export { connectCommand } from './commands/connect.js';
5
+ export { inspectCommand } from './commands/inspect.js';
6
+ export { startInteractiveMode } from './commands/interactive.js';
7
+ export type { CliOptions } from './types.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAChE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ /**
3
+ * Main exports for @metatell/cli
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.startInteractiveMode = exports.inspectCommand = exports.connectCommand = void 0;
7
+ var connect_js_1 = require("./commands/connect.js");
8
+ Object.defineProperty(exports, "connectCommand", { enumerable: true, get: function () { return connect_js_1.connectCommand; } });
9
+ var inspect_js_1 = require("./commands/inspect.js");
10
+ Object.defineProperty(exports, "inspectCommand", { enumerable: true, get: function () { return inspect_js_1.inspectCommand; } });
11
+ var interactive_js_1 = require("./commands/interactive.js");
12
+ Object.defineProperty(exports, "startInteractiveMode", { enumerable: true, get: function () { return interactive_js_1.startInteractiveMode; } });
@@ -0,0 +1,9 @@
1
+ /**
2
+ * CLI type definitions
3
+ */
4
+ export interface CliOptions {
5
+ token?: string;
6
+ name?: string;
7
+ debug?: boolean;
8
+ }
9
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB"}
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ /**
3
+ * CLI type definitions
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Command parser and executor for CLI commands
3
+ */
4
+ import type { MetatellClient } from '@metatell/sdk';
5
+ export interface CommandResult {
6
+ success: boolean;
7
+ message?: string;
8
+ data?: unknown;
9
+ }
10
+ export declare class CommandParser {
11
+ execute(input: string, client: MetatellClient): Promise<CommandResult>;
12
+ private showHelp;
13
+ private say;
14
+ private move;
15
+ private look;
16
+ private nearby;
17
+ private listUsers;
18
+ private showStatus;
19
+ private showInfo;
20
+ private changeAvatar;
21
+ private listAssets;
22
+ private playAnimation;
23
+ private stopAnimation;
24
+ private listAnimations;
25
+ }
26
+ //# sourceMappingURL=commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/utils/commands.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAEnD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,qBAAa,aAAa;IAClB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAuD5E,OAAO,CAAC,QAAQ;YAuBF,GAAG;YAWH,IAAI;YAkBJ,IAAI;YAwCJ,MAAM;YAiBN,SAAS;IASvB,OAAO,CAAC,UAAU;YAYJ,QAAQ;YAWR,YAAY;YAWZ,UAAU;YAWV,aAAa;YAuBb,aAAa;YAeb,cAAc;CAW7B"}
@@ -0,0 +1,361 @@
1
+ "use strict";
2
+ /**
3
+ * Command parser and executor for CLI commands
4
+ */
5
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7
+ return new (P || (P = Promise))(function (resolve, reject) {
8
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
9
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
11
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
12
+ });
13
+ };
14
+ var __generator = (this && this.__generator) || function (thisArg, body) {
15
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
16
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
17
+ function verb(n) { return function (v) { return step([n, v]); }; }
18
+ function step(op) {
19
+ if (f) throw new TypeError("Generator is already executing.");
20
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
21
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
22
+ if (y = 0, t) op = [op[0] & 2, t.value];
23
+ switch (op[0]) {
24
+ case 0: case 1: t = op; break;
25
+ case 4: _.label++; return { value: op[1], done: false };
26
+ case 5: _.label++; y = op[1]; op = [0]; continue;
27
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
28
+ default:
29
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
30
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
31
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
32
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
33
+ if (t[2]) _.ops.pop();
34
+ _.trys.pop(); continue;
35
+ }
36
+ op = body.call(thisArg, _);
37
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
38
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
39
+ }
40
+ };
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.CommandParser = void 0;
43
+ var CommandParser = /** @class */ (function () {
44
+ function CommandParser() {
45
+ }
46
+ CommandParser.prototype.execute = function (input, client) {
47
+ return __awaiter(this, void 0, void 0, function () {
48
+ var parts, command, args;
49
+ return __generator(this, function (_a) {
50
+ parts = input.split(/\s+/);
51
+ command = parts[0].toLowerCase();
52
+ args = parts.slice(1);
53
+ switch (command) {
54
+ case '/help':
55
+ case '/?':
56
+ return [2 /*return*/, this.showHelp()];
57
+ case '/say':
58
+ return [2 /*return*/, this.say(args, client)];
59
+ case '/move':
60
+ return [2 /*return*/, this.move(args, client)];
61
+ case '/look':
62
+ return [2 /*return*/, this.look(args, client)];
63
+ case '/nearby':
64
+ return [2 /*return*/, this.nearby(args, client)];
65
+ case '/users':
66
+ return [2 /*return*/, this.listUsers(client)];
67
+ case '/status':
68
+ return [2 /*return*/, this.showStatus(client)];
69
+ case '/info':
70
+ return [2 /*return*/, this.showInfo(client)];
71
+ case '/anime':
72
+ case '/animation':
73
+ return [2 /*return*/, this.playAnimation(args, client)];
74
+ case '/stop':
75
+ return [2 /*return*/, this.stopAnimation(client)];
76
+ case '/avatar':
77
+ return [2 /*return*/, this.changeAvatar(args, client)];
78
+ case '/assets':
79
+ return [2 /*return*/, this.listAssets(client)];
80
+ case '/animations':
81
+ return [2 /*return*/, this.listAnimations(client)];
82
+ default:
83
+ return [2 /*return*/, {
84
+ success: false,
85
+ message: "Unknown command: ".concat(command, ". Type /help for commands."),
86
+ }];
87
+ }
88
+ return [2 /*return*/];
89
+ });
90
+ });
91
+ };
92
+ CommandParser.prototype.showHelp = function () {
93
+ var help = "\nAvailable commands:\n /help, /? - Show this help\n /say <message> - Send a message\n /move <x> <y> <z> - Move avatar to position\n /look <x> <y> <z> - Look at position\n /look @<username> - Look at user\n /nearby [radius] - Show nearby users (default: 10)\n /users - List all users\n /status - Show connection status\n /info - Show bot info\n /avatar <id> - Change avatar\n /assets - List available avatars\n /anime <name> - Play animation\n /animations - List available animations\n /stop - Stop current animation\n quit, exit - Exit the program\n";
94
+ console.log(help);
95
+ return { success: true };
96
+ };
97
+ CommandParser.prototype.say = function (args, client) {
98
+ return __awaiter(this, void 0, void 0, function () {
99
+ var message;
100
+ return __generator(this, function (_a) {
101
+ switch (_a.label) {
102
+ case 0:
103
+ if (args.length === 0) {
104
+ return [2 /*return*/, { success: false, message: 'Usage: /say <message>' }];
105
+ }
106
+ message = args.join(' ');
107
+ return [4 /*yield*/, client.chat.send(message)];
108
+ case 1:
109
+ _a.sent();
110
+ console.log('[Sent]', message);
111
+ return [2 /*return*/, { success: true }];
112
+ }
113
+ });
114
+ });
115
+ };
116
+ CommandParser.prototype.move = function (args, client) {
117
+ return __awaiter(this, void 0, void 0, function () {
118
+ var x, y, z;
119
+ return __generator(this, function (_a) {
120
+ switch (_a.label) {
121
+ case 0:
122
+ if (args.length !== 3) {
123
+ return [2 /*return*/, { success: false, message: 'Usage: /move <x> <y> <z>' }];
124
+ }
125
+ x = parseFloat(args[0]);
126
+ y = parseFloat(args[1]);
127
+ z = parseFloat(args[2]);
128
+ if (Number.isNaN(x) || Number.isNaN(y) || Number.isNaN(z)) {
129
+ return [2 /*return*/, { success: false, message: 'Invalid coordinates. Must be numbers.' }];
130
+ }
131
+ return [4 /*yield*/, client.avatar.moveTo({ x: x, y: y, z: z })];
132
+ case 1:
133
+ _a.sent();
134
+ console.log("[Moved to] x:".concat(x, " y:").concat(y, " z:").concat(z));
135
+ return [2 /*return*/, { success: true }];
136
+ }
137
+ });
138
+ });
139
+ };
140
+ CommandParser.prototype.look = function (args, client) {
141
+ return __awaiter(this, void 0, void 0, function () {
142
+ var username_1, users, targetUser, x, y, z;
143
+ return __generator(this, function (_a) {
144
+ switch (_a.label) {
145
+ case 0:
146
+ if (args.length === 0) {
147
+ return [2 /*return*/, { success: false, message: 'Usage: /look <x> <y> <z> or /look @<username>' }];
148
+ }
149
+ if (!args[0].startsWith('@')) return [3 /*break*/, 2];
150
+ username_1 = args[0].substring(1);
151
+ return [4 /*yield*/, client.room.getUsers()];
152
+ case 1:
153
+ users = _a.sent();
154
+ targetUser = users.find(function (u) { var _a; return ((_a = u.name) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === username_1.toLowerCase(); });
155
+ if (!targetUser) {
156
+ return [2 /*return*/, { success: false, message: "User not found: ".concat(username_1) }];
157
+ }
158
+ // TODO: ユーザーの位置を取得して見る機能はSDKに未実装
159
+ console.log("[Looking at] ".concat(targetUser.name));
160
+ return [2 /*return*/, { success: true, message: 'Looking at user (position tracking not yet implemented)' }];
161
+ case 2:
162
+ // 座標を見る場合
163
+ if (args.length !== 3) {
164
+ return [2 /*return*/, { success: false, message: 'Usage: /look <x> <y> <z>' }];
165
+ }
166
+ x = parseFloat(args[0]);
167
+ y = parseFloat(args[1]);
168
+ z = parseFloat(args[2]);
169
+ if (Number.isNaN(x) || Number.isNaN(y) || Number.isNaN(z)) {
170
+ return [2 /*return*/, { success: false, message: 'Invalid coordinates. Must be numbers.' }];
171
+ }
172
+ // 指定座標を見る
173
+ return [4 /*yield*/, client.avatar.lookAt({ x: x, y: y, z: z })];
174
+ case 3:
175
+ // 指定座標を見る
176
+ _a.sent();
177
+ console.log("[Looking at] x:".concat(x, " y:").concat(y, " z:").concat(z));
178
+ return [2 /*return*/, { success: true }];
179
+ }
180
+ });
181
+ });
182
+ };
183
+ CommandParser.prototype.nearby = function (args, client) {
184
+ return __awaiter(this, void 0, void 0, function () {
185
+ var radius, nearbyUsers;
186
+ return __generator(this, function (_a) {
187
+ switch (_a.label) {
188
+ case 0:
189
+ radius = args.length > 0 ? parseFloat(args[0]) : 10;
190
+ if (Number.isNaN(radius)) {
191
+ return [2 /*return*/, { success: false, message: 'Invalid radius. Must be a number.' }];
192
+ }
193
+ return [4 /*yield*/, client.room.getNearbyUsers(radius)];
194
+ case 1:
195
+ nearbyUsers = _a.sent();
196
+ console.log("[Nearby users within ".concat(radius, "m]"));
197
+ nearbyUsers.forEach(function (u) {
198
+ console.log("- ".concat(u.name || 'Anonymous', " (").concat(u.id, ")").concat(u.isBot ? ' [Bot]' : ''));
199
+ });
200
+ return [2 /*return*/, { success: true }];
201
+ }
202
+ });
203
+ });
204
+ };
205
+ CommandParser.prototype.listUsers = function (client) {
206
+ return __awaiter(this, void 0, void 0, function () {
207
+ var users;
208
+ return __generator(this, function (_a) {
209
+ switch (_a.label) {
210
+ case 0: return [4 /*yield*/, client.room.getUsers()];
211
+ case 1:
212
+ users = _a.sent();
213
+ console.log("[Users (".concat(users.length, ")]"));
214
+ users.forEach(function (u) {
215
+ console.log("- ".concat(u.name || 'Anonymous', " (").concat(u.id, ")").concat(u.isBot ? ' [Bot]' : ''));
216
+ });
217
+ return [2 /*return*/, { success: true }];
218
+ }
219
+ });
220
+ });
221
+ };
222
+ CommandParser.prototype.showStatus = function (client) {
223
+ var status = client.getStatus();
224
+ var sessionId = client.getSessionId();
225
+ console.log('[Status]');
226
+ console.log("Connected: ".concat(status.connected));
227
+ console.log("Connecting: ".concat(status.connecting));
228
+ console.log("Session ID: ".concat(sessionId || 'N/A'));
229
+ return { success: true };
230
+ };
231
+ CommandParser.prototype.showInfo = function (client) {
232
+ return __awaiter(this, void 0, void 0, function () {
233
+ var info;
234
+ return __generator(this, function (_a) {
235
+ switch (_a.label) {
236
+ case 0: return [4 /*yield*/, client.getInfo()];
237
+ case 1:
238
+ info = _a.sent();
239
+ console.log('[Bot Info]');
240
+ console.log("Name: ".concat(info.name));
241
+ console.log("Version: ".concat(info.version));
242
+ console.log("Room ID: ".concat(info.roomId));
243
+ return [2 /*return*/, { success: true }];
244
+ }
245
+ });
246
+ });
247
+ };
248
+ CommandParser.prototype.changeAvatar = function (args, client) {
249
+ return __awaiter(this, void 0, void 0, function () {
250
+ var avatarId;
251
+ return __generator(this, function (_a) {
252
+ switch (_a.label) {
253
+ case 0:
254
+ if (args.length === 0) {
255
+ return [2 /*return*/, { success: false, message: 'Usage: /avatar <id>' }];
256
+ }
257
+ avatarId = args[0];
258
+ return [4 /*yield*/, client.avatar.select(avatarId)];
259
+ case 1:
260
+ _a.sent();
261
+ console.log("[Avatar changed to] ".concat(avatarId));
262
+ return [2 /*return*/, { success: true }];
263
+ }
264
+ });
265
+ });
266
+ };
267
+ CommandParser.prototype.listAssets = function (client) {
268
+ return __awaiter(this, void 0, void 0, function () {
269
+ var assets;
270
+ return __generator(this, function (_a) {
271
+ switch (_a.label) {
272
+ case 0: return [4 /*yield*/, client.avatar.getAvailableAssets()];
273
+ case 1:
274
+ assets = _a.sent();
275
+ console.log("[Available avatars (".concat(assets.length, ")]"));
276
+ assets.forEach(function (asset) {
277
+ console.log("- ".concat(asset.id, ": ").concat(asset.name));
278
+ });
279
+ return [2 /*return*/, { success: true }];
280
+ }
281
+ });
282
+ });
283
+ };
284
+ CommandParser.prototype.playAnimation = function (args, client) {
285
+ return __awaiter(this, void 0, void 0, function () {
286
+ var animationName, error_1;
287
+ return __generator(this, function (_a) {
288
+ switch (_a.label) {
289
+ case 0:
290
+ if (args.length === 0) {
291
+ return [2 /*return*/, { success: false, message: 'Usage: /anime <name>' }];
292
+ }
293
+ animationName = args.join(' ');
294
+ _a.label = 1;
295
+ case 1:
296
+ _a.trys.push([1, 3, , 4]);
297
+ return [4 /*yield*/, client.avatar.play({
298
+ name: animationName,
299
+ id: animationName,
300
+ loop: false,
301
+ })];
302
+ case 2:
303
+ _a.sent();
304
+ console.log("[Playing animation] ".concat(animationName));
305
+ return [2 /*return*/, { success: true }];
306
+ case 3:
307
+ error_1 = _a.sent();
308
+ return [2 /*return*/, {
309
+ success: false,
310
+ message: "Failed to play animation: ".concat(error_1 instanceof Error ? error_1.message : 'Unknown error'),
311
+ }];
312
+ case 4: return [2 /*return*/];
313
+ }
314
+ });
315
+ });
316
+ };
317
+ CommandParser.prototype.stopAnimation = function (client) {
318
+ return __awaiter(this, void 0, void 0, function () {
319
+ var _a;
320
+ return __generator(this, function (_b) {
321
+ switch (_b.label) {
322
+ case 0:
323
+ _b.trys.push([0, 2, , 3]);
324
+ return [4 /*yield*/, client.avatar.play({
325
+ name: 'idle',
326
+ id: 'idle',
327
+ loop: true,
328
+ })];
329
+ case 1:
330
+ _b.sent();
331
+ console.log('[Stopped animation]');
332
+ return [2 /*return*/, { success: true }];
333
+ case 2:
334
+ _a = _b.sent();
335
+ return [2 /*return*/, { success: true, message: 'Animation stopped' }];
336
+ case 3: return [2 /*return*/];
337
+ }
338
+ });
339
+ });
340
+ };
341
+ CommandParser.prototype.listAnimations = function (client) {
342
+ return __awaiter(this, void 0, void 0, function () {
343
+ var animations;
344
+ return __generator(this, function (_a) {
345
+ switch (_a.label) {
346
+ case 0: return [4 /*yield*/, client.avatar.getAvailableAnimations()];
347
+ case 1:
348
+ animations = _a.sent();
349
+ console.log("[Available animations (".concat(animations.length, ")]"));
350
+ animations.forEach(function (anim) {
351
+ var duration = anim.duration ? " (".concat(anim.duration.toFixed(1), "s)") : '';
352
+ console.log("- ".concat(anim.id || anim.name, ": ").concat(anim.name).concat(duration));
353
+ });
354
+ return [2 /*return*/, { success: true }];
355
+ }
356
+ });
357
+ });
358
+ };
359
+ return CommandParser;
360
+ }());
361
+ exports.CommandParser = CommandParser;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * URL parsing utilities
3
+ */
4
+ export declare function parseUrl(url: string): {
5
+ serverUrl: string;
6
+ roomId: string;
7
+ };
8
+ //# sourceMappingURL=url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../../src/utils/url.ts"],"names":[],"mappings":"AAAA;;GAEG;AA6BH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAyB3E"}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ /**
3
+ * URL parsing utilities
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.parseUrl = parseUrl;
7
+ var METATELL_DOMAINS = ['metatell.app', 'metatell-stg.app', 'metatell-dev.app'];
8
+ /**
9
+ * Check if hostname is a Metatell domain
10
+ */
11
+ function isMetatellDomain(hostname) {
12
+ return METATELL_DOMAINS.some(function (domain) { return hostname.endsWith(domain); });
13
+ }
14
+ /**
15
+ * Remove tenant subdomain from Metatell URL
16
+ */
17
+ function removeMetatellTenantSubdomain(hostname) {
18
+ if (!isMetatellDomain(hostname)) {
19
+ return hostname;
20
+ }
21
+ // メタテルドメインの場合、ベースドメインに変換
22
+ for (var _i = 0, METATELL_DOMAINS_1 = METATELL_DOMAINS; _i < METATELL_DOMAINS_1.length; _i++) {
23
+ var domain = METATELL_DOMAINS_1[_i];
24
+ if (hostname.endsWith(domain)) {
25
+ return domain;
26
+ }
27
+ }
28
+ return hostname;
29
+ }
30
+ function parseUrl(url) {
31
+ try {
32
+ var urlObj = new URL(url);
33
+ // メタテルドメインの場合のみテナントサブドメインを除去
34
+ var hostname = isMetatellDomain(urlObj.hostname)
35
+ ? removeMetatellTenantSubdomain(urlObj.hostname)
36
+ : urlObj.hostname;
37
+ var protocol = urlObj.protocol === 'https:' ? 'wss:' : 'ws:';
38
+ var port = urlObj.port ? ":".concat(urlObj.port) : '';
39
+ var serverUrl = "".concat(protocol, "//").concat(hostname).concat(port);
40
+ // Extract room ID from path - it's the first path segment
41
+ var pathParts = urlObj.pathname.split('/').filter(Boolean);
42
+ var roomId = pathParts[0] || 'default';
43
+ if (!roomId || roomId === '/') {
44
+ throw new Error('No room ID found in URL');
45
+ }
46
+ return { serverUrl: serverUrl, roomId: roomId };
47
+ }
48
+ catch (error) {
49
+ throw new Error("Invalid URL: ".concat(error instanceof Error ? error.message : 'Unknown error'));
50
+ }
51
+ }
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@metatell/bot-cli",
3
+ "version": "0.0.1",
4
+ "description": "CLI tool for Metatell bot development and testing",
5
+ "type": "module",
6
+ "bin": {
7
+ "metatell-cli": "./dist/cli.js"
8
+ },
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsc",
21
+ "dev": "tsx watch src/cli.ts",
22
+ "typecheck": "tsc --noEmit"
23
+ },
24
+ "dependencies": {
25
+ "@metatell/bot-sdk": "file:../sdk",
26
+ "commander": "^12.0.0",
27
+ "ink": "^5.0.1",
28
+ "react": "^18.3.1"
29
+ },
30
+ "devDependencies": {
31
+ "@types/node": "^22.0.0",
32
+ "@types/react": "^18.3.12",
33
+ "tsx": "^4.20.0",
34
+ "typescript": "^5.6.3"
35
+ }
36
+ }