library.dr-conversion 0.2.9 ā 0.3.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 +28 -2
- package/cli.js +297 -4
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
[](https://www.npmjs.com/package/library.dr-conversion)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
|
|
8
|
-
**Library.DR-Conversion** (v0.2.
|
|
8
|
+
**Library.DR-Conversion** (v0.2.9) is a TypeScript library that provides a unified, platform-agnostic interface for building chat bots that work across multiple platforms like Discord, Root, and potentially others. Write your bot logic once, and deploy it anywhere!
|
|
9
9
|
|
|
10
10
|
## ⨠Features
|
|
11
11
|
|
|
@@ -79,6 +79,28 @@ npx library.dr-conversion init -p root-app -n my-root-app
|
|
|
79
79
|
|
|
80
80
|
This creates a fully configured project with TypeScript, example code, and environment variables ready to go!
|
|
81
81
|
|
|
82
|
+
**Generate Root Bot Manifest:**
|
|
83
|
+
|
|
84
|
+
If you're building a Root bot, you'll need a `root-manifest.json` file:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Quick generation with defaults
|
|
88
|
+
npx library.dr-conversion generate-manifest
|
|
89
|
+
# or simply
|
|
90
|
+
npm run generate-manifest
|
|
91
|
+
|
|
92
|
+
# Interactive mode with guided prompts
|
|
93
|
+
npx library.dr-conversion generate-manifest -i
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The generator will:
|
|
97
|
+
- Create a proper UUID for your bot ID
|
|
98
|
+
- Guide you through version and configuration options
|
|
99
|
+
- Set up permissions for your bot
|
|
100
|
+
- Generate a valid `root-manifest.json` file
|
|
101
|
+
|
|
102
|
+
See the [Root Bot Manifest Guide](docs/ROOT_APP_MANIFEST.md) for details.
|
|
103
|
+
|
|
82
104
|
### Basic Usage
|
|
83
105
|
|
|
84
106
|
```typescript
|
|
@@ -273,11 +295,14 @@ await rootBot.connect();
|
|
|
273
295
|
|
|
274
296
|
#### Building Root Apps with This Library
|
|
275
297
|
|
|
276
|
-
**Prerequisites**:
|
|
298
|
+
**Prerequisites**:
|
|
277
299
|
```bash
|
|
300
|
+
# Install the Root client SDK
|
|
278
301
|
npm install @rootsdk/client-app
|
|
279
302
|
```
|
|
280
303
|
|
|
304
|
+
**Note**: Root Apps (client-side) have different deployment requirements than Root Bots. They run in the Root client browser and don't require server-side manifest files. Configuration is done through the Root platform's app management interface.
|
|
305
|
+
|
|
281
306
|
You can now create Root Apps (client-side) using the same unified interface:
|
|
282
307
|
|
|
283
308
|
```typescript
|
|
@@ -565,6 +590,7 @@ const client = new UnifiedClient({
|
|
|
565
590
|
- š **[API Reference](API.md)** - Detailed API documentation
|
|
566
591
|
- š **[Migration Guide](docs/MIGRATION.md)** - Upgrade and migration guides
|
|
567
592
|
- š **[Contributing Guide](CONTRIBUTING.md)** - How to contribute
|
|
593
|
+
- š **[Root Bot Manifest Guide](docs/ROOT_APP_MANIFEST.md)** - Creating root-manifest.json for Root Bots (server-side)
|
|
568
594
|
|
|
569
595
|
### Creating Rich Messages
|
|
570
596
|
|
package/cli.js
CHANGED
|
@@ -10,11 +10,49 @@ const fs = require('fs');
|
|
|
10
10
|
const path = require('path');
|
|
11
11
|
const { execSync } = require('child_process');
|
|
12
12
|
const readline = require('readline');
|
|
13
|
+
const crypto = require('crypto');
|
|
14
|
+
|
|
15
|
+
// Generate a UUID v4
|
|
16
|
+
function generateUUID() {
|
|
17
|
+
return crypto.randomUUID();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Detect platform from package.json dependencies
|
|
21
|
+
function detectPlatform() {
|
|
22
|
+
try {
|
|
23
|
+
const pkgPath = path.join(process.cwd(), 'package.json');
|
|
24
|
+
if (!fs.existsSync(pkgPath)) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
29
|
+
const allDeps = {
|
|
30
|
+
...pkg.dependencies,
|
|
31
|
+
...pkg.devDependencies,
|
|
32
|
+
...pkg.peerDependencies
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// Check for Root platforms
|
|
36
|
+
if (allDeps['@rootsdk/server-bot']) {
|
|
37
|
+
return 'root';
|
|
38
|
+
}
|
|
39
|
+
if (allDeps['@rootsdk/client-app']) {
|
|
40
|
+
return 'root-app';
|
|
41
|
+
}
|
|
42
|
+
if (allDeps['discord.js']) {
|
|
43
|
+
return 'discord';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return null;
|
|
47
|
+
} catch (error) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
13
51
|
|
|
14
52
|
program
|
|
15
53
|
.name('library.dr-conversion')
|
|
16
|
-
.description('CLI tools for Library.DR-Conversion v0.2.
|
|
17
|
-
.version('0.2.
|
|
54
|
+
.description('CLI tools for Library.DR-Conversion v0.2.9')
|
|
55
|
+
.version('0.2.9');
|
|
18
56
|
|
|
19
57
|
program
|
|
20
58
|
.command('init')
|
|
@@ -192,12 +230,72 @@ client.connect();
|
|
|
192
230
|
|
|
193
231
|
fs.writeFileSync(path.join(projectDir, 'src', 'index.ts'), botCode);
|
|
194
232
|
|
|
233
|
+
// Create root-manifest.json for Root Bots
|
|
234
|
+
if (options.platform === 'root') {
|
|
235
|
+
const manifest = {
|
|
236
|
+
id: generateUUID(),
|
|
237
|
+
version: '1.0.0',
|
|
238
|
+
package: {
|
|
239
|
+
server: {
|
|
240
|
+
launch: 'dist/index.js',
|
|
241
|
+
deploy: ['dist'],
|
|
242
|
+
node_modules: ['node_modules']
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
settings: {
|
|
246
|
+
groups: []
|
|
247
|
+
},
|
|
248
|
+
permissions: {
|
|
249
|
+
community: {},
|
|
250
|
+
channel: {
|
|
251
|
+
CreateMessage: true,
|
|
252
|
+
ReadMessage: true
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
fs.writeFileSync(
|
|
258
|
+
path.join(projectDir, 'root-manifest.json'),
|
|
259
|
+
JSON.stringify(manifest, null, 2)
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
// Create README explaining manifest
|
|
263
|
+
const manifestReadme = `# Root Bot Manifest
|
|
264
|
+
|
|
265
|
+
Your bot's root-manifest.json defines how it integrates with Root.
|
|
266
|
+
|
|
267
|
+
## Important:
|
|
268
|
+
- The 'id' field is unique to your bot - don't change it after publishing
|
|
269
|
+
- Update 'version' following semantic versioning when you make changes
|
|
270
|
+
- Add permissions your bot needs to 'permissions.community' or 'permissions.channel'
|
|
271
|
+
- See docs/ROOT_BOT_MANIFEST.md for full documentation
|
|
272
|
+
|
|
273
|
+
## Publishing:
|
|
274
|
+
\`\`\`bash
|
|
275
|
+
npm run build
|
|
276
|
+
npx @rootsdk/cli publish
|
|
277
|
+
\`\`\`
|
|
278
|
+
`;
|
|
279
|
+
fs.writeFileSync(path.join(projectDir, 'MANIFEST.md'), manifestReadme);
|
|
280
|
+
}
|
|
281
|
+
|
|
195
282
|
console.log(`ā
Created ${options.name}`);
|
|
196
283
|
console.log(`\nš Next steps:`);
|
|
197
284
|
console.log(` cd ${options.name}`);
|
|
198
285
|
console.log(` npm install`);
|
|
199
|
-
|
|
200
|
-
|
|
286
|
+
|
|
287
|
+
if (options.platform === 'root') {
|
|
288
|
+
console.log(` cp .env.example .env`);
|
|
289
|
+
console.log(` # Edit .env with your bot token`);
|
|
290
|
+
console.log(` # Edit root-manifest.json - change the 'id' to a unique value`);
|
|
291
|
+
console.log(` # See MANIFEST.md for manifest documentation`);
|
|
292
|
+
} else if (options.platform === 'discord') {
|
|
293
|
+
console.log(` cp .env.example .env`);
|
|
294
|
+
console.log(` # Edit .env with your bot token`);
|
|
295
|
+
} else if (options.platform === 'root-app') {
|
|
296
|
+
console.log(` # Root Apps run in the Root client - no token needed`);
|
|
297
|
+
console.log(` # Configure your app in the Root platform`);
|
|
298
|
+
}
|
|
201
299
|
console.log(` npm run dev`);
|
|
202
300
|
});
|
|
203
301
|
|
|
@@ -226,6 +324,201 @@ program
|
|
|
226
324
|
console.log('ā
Configuration is valid');
|
|
227
325
|
});
|
|
228
326
|
|
|
327
|
+
program
|
|
328
|
+
.command('generate-manifest')
|
|
329
|
+
.description('Generate a manifest file for Root Bots or Root Apps (auto-detects platform)')
|
|
330
|
+
.option('-i, --interactive', 'Interactive mode with prompts')
|
|
331
|
+
.option('-p, --platform <type>', 'Platform type (root, root-app) - auto-detected if not specified')
|
|
332
|
+
.action(async (options) => {
|
|
333
|
+
// Auto-detect platform if not specified
|
|
334
|
+
const platform = options.platform || detectPlatform();
|
|
335
|
+
|
|
336
|
+
if (!platform || (platform !== 'root' && platform !== 'root-app')) {
|
|
337
|
+
console.error('ā Could not detect Root platform.');
|
|
338
|
+
console.error(' Make sure you have @rootsdk/server-bot or @rootsdk/client-app installed,');
|
|
339
|
+
console.error(' or specify the platform: --platform root or --platform root-app');
|
|
340
|
+
process.exit(1);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const isRootBot = platform === 'root';
|
|
344
|
+
const manifestFile = isRootBot ? 'root-manifest.json' : 'root-app-manifest.json';
|
|
345
|
+
|
|
346
|
+
console.log(`\nš Detected platform: ${isRootBot ? 'Root Bot (server-side)' : 'Root App (client-side)'}`);
|
|
347
|
+
|
|
348
|
+
// Check if manifest already exists
|
|
349
|
+
if (fs.existsSync(manifestFile)) {
|
|
350
|
+
console.log(`ā ļø ${manifestFile} already exists in this directory.`);
|
|
351
|
+
if (!options.interactive) {
|
|
352
|
+
console.log('Use --interactive to configure a new one anyway.');
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
let manifest;
|
|
358
|
+
|
|
359
|
+
if (isRootBot) {
|
|
360
|
+
// Root Bot manifest (server-side)
|
|
361
|
+
manifest = {
|
|
362
|
+
id: generateUUID(),
|
|
363
|
+
version: '1.0.0',
|
|
364
|
+
package: {
|
|
365
|
+
server: {
|
|
366
|
+
launch: 'dist/index.js',
|
|
367
|
+
deploy: ['dist'],
|
|
368
|
+
node_modules: ['node_modules']
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
settings: {
|
|
372
|
+
groups: []
|
|
373
|
+
},
|
|
374
|
+
permissions: {
|
|
375
|
+
community: {},
|
|
376
|
+
channel: {}
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
} else {
|
|
380
|
+
// Root App manifest (client-side)
|
|
381
|
+
manifest = {
|
|
382
|
+
id: generateUUID(),
|
|
383
|
+
version: '1.0.0',
|
|
384
|
+
name: '',
|
|
385
|
+
description: '',
|
|
386
|
+
author: '',
|
|
387
|
+
homepage: '',
|
|
388
|
+
permissions: {
|
|
389
|
+
channel: {}
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
if (options.interactive) {
|
|
395
|
+
const rl = readline.createInterface({
|
|
396
|
+
input: process.stdin,
|
|
397
|
+
output: process.stdout
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
function question(prompt) {
|
|
401
|
+
return new Promise((resolve) => {
|
|
402
|
+
rl.question(prompt, resolve);
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
console.log('\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
407
|
+
console.log(`ā Root ${isRootBot ? 'Bot' : 'App'} Manifest Generator${' '.repeat(isRootBot ? 25 : 24)}ā`);
|
|
408
|
+
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n');
|
|
409
|
+
|
|
410
|
+
// Version
|
|
411
|
+
const version = await question('Version (default: 1.0.0): ');
|
|
412
|
+
if (version.trim()) manifest.version = version.trim();
|
|
413
|
+
|
|
414
|
+
if (isRootBot) {
|
|
415
|
+
// Root Bot specific fields
|
|
416
|
+
// Launch file
|
|
417
|
+
const launch = await question('Launch file (default: dist/index.js): ');
|
|
418
|
+
if (launch.trim()) manifest.package.server.launch = launch.trim();
|
|
419
|
+
|
|
420
|
+
// Permissions
|
|
421
|
+
console.log('\nš Bot Permissions:\n');
|
|
422
|
+
console.log('Community permissions:');
|
|
423
|
+
} else {
|
|
424
|
+
// Root App specific fields
|
|
425
|
+
const name = await question('App name: ');
|
|
426
|
+
if (name.trim()) manifest.name = name.trim();
|
|
427
|
+
|
|
428
|
+
const description = await question('App description: ');
|
|
429
|
+
if (description.trim()) manifest.description = description.trim();
|
|
430
|
+
|
|
431
|
+
const author = await question('Author: ');
|
|
432
|
+
if (author.trim()) manifest.author = author.trim();
|
|
433
|
+
|
|
434
|
+
const homepage = await question('Homepage URL (optional): ');
|
|
435
|
+
if (homepage.trim()) manifest.homepage = homepage.trim();
|
|
436
|
+
|
|
437
|
+
console.log('\nš App Permissions:\n');
|
|
438
|
+
console.log('Channel permissions (Root Apps run in browser):');
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
if (isRootBot) {
|
|
442
|
+
// Community permissions only for Root Bots
|
|
443
|
+
console.log('Community permissions:');
|
|
444
|
+
const manageRoles = await question(' Need to manage roles? (y/n): ');
|
|
445
|
+
if (manageRoles.toLowerCase() === 'y') {
|
|
446
|
+
manifest.permissions.community.ManageRoles = true;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
const manageCommunity = await question(' Need to manage community settings? (y/n): ');
|
|
450
|
+
if (manageCommunity.toLowerCase() === 'y') {
|
|
451
|
+
manifest.permissions.community.ManageCommunity = true;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
const manageChannels = await question(' Need to manage channels? (y/n): ');
|
|
455
|
+
if (manageChannels.toLowerCase() === 'y') {
|
|
456
|
+
manifest.permissions.community.ManageChannels = true;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
console.log('\nChannel permissions:');
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// Channel permissions (both Root Bot and Root App)
|
|
463
|
+
const createMsg = await question(' Need to send messages? (y/n): ');
|
|
464
|
+
if (createMsg.toLowerCase() === 'y') {
|
|
465
|
+
manifest.permissions.channel.CreateMessage = true;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
const readMsg = await question(' Need to read messages? (y/n): ');
|
|
469
|
+
if (readMsg.toLowerCase() === 'y') {
|
|
470
|
+
manifest.permissions.channel.ReadMessage = true;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
const deleteMsg = await question(' Need to delete messages? (y/n): ');
|
|
474
|
+
if (deleteMsg.toLowerCase() === 'y') {
|
|
475
|
+
manifest.permissions.channel.DeleteMessage = true;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
const managePins = await question(' Need to manage pins? (y/n): ');
|
|
479
|
+
if (managePins.toLowerCase() === 'y') {
|
|
480
|
+
manifest.permissions.channel.ManagePins = true;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
rl.close();
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
// Write manifest file
|
|
487
|
+
fs.writeFileSync(
|
|
488
|
+
manifestFile,
|
|
489
|
+
JSON.stringify(manifest, null, 2)
|
|
490
|
+
);
|
|
491
|
+
|
|
492
|
+
console.log(`\nā
Generated ${manifestFile} successfully!\n`);
|
|
493
|
+
console.log('š Manifest Details:');
|
|
494
|
+
console.log(` Platform: ${isRootBot ? 'Root Bot (server-side)' : 'Root App (client-side)'}`);
|
|
495
|
+
console.log(` ID: ${manifest.id}`);
|
|
496
|
+
console.log(` Version: ${manifest.version}`);
|
|
497
|
+
if (isRootBot) {
|
|
498
|
+
console.log(` Launch: ${manifest.package.server.launch}`);
|
|
499
|
+
} else {
|
|
500
|
+
console.log(` Name: ${manifest.name || '(not set)'}`);
|
|
501
|
+
}
|
|
502
|
+
console.log('');
|
|
503
|
+
console.log('ā ļø Important:');
|
|
504
|
+
console.log(' - The ID is unique to your ' + (isRootBot ? 'bot' : 'app') + ' - never change it after publishing');
|
|
505
|
+
console.log(' - Update version when you make changes (follow semver)');
|
|
506
|
+
if (isRootBot) {
|
|
507
|
+
console.log(' - See docs/ROOT_APP_MANIFEST.md for full documentation');
|
|
508
|
+
}
|
|
509
|
+
console.log('');
|
|
510
|
+
console.log('š Next steps:');
|
|
511
|
+
console.log(` 1. Review and customize ${manifestFile}`);
|
|
512
|
+
if (isRootBot) {
|
|
513
|
+
console.log(' 2. Build your bot: npm run build');
|
|
514
|
+
console.log(' 3. Publish: npx @rootsdk/cli publish');
|
|
515
|
+
} else {
|
|
516
|
+
console.log(' 2. Build your app: npm run build');
|
|
517
|
+
console.log(' 3. Deploy through Root platform interface');
|
|
518
|
+
}
|
|
519
|
+
console.log('');
|
|
520
|
+
});
|
|
521
|
+
|
|
229
522
|
program
|
|
230
523
|
.command('setup')
|
|
231
524
|
.description('Interactive setup wizard to install only the dependencies you need')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "library.dr-conversion",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Unified interface for building multi-platform chat bots (Discord, Root, and more)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"typecheck": "tsc --noEmit",
|
|
20
20
|
"dev": "tsc --watch",
|
|
21
21
|
"setup": "node cli.js setup",
|
|
22
|
+
"generate-manifest": "node cli.js generate-manifest",
|
|
22
23
|
"example:simple": "ts-node examples/simple-bot.ts",
|
|
23
24
|
"example:discord": "ts-node examples/discord-bot.ts",
|
|
24
25
|
"example:root": "ts-node examples/root-bot.ts",
|