towns-bot 0.0.381 → 0.0.383
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/dist/index.js +16 -230
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +16 -235
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -23,7 +23,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
23
23
|
));
|
|
24
24
|
|
|
25
25
|
// src/index.ts
|
|
26
|
-
var
|
|
26
|
+
var import_picocolors4 = require("picocolors");
|
|
27
27
|
|
|
28
28
|
// src/modules/init.ts
|
|
29
29
|
var fs2 = __toESM(require("fs"));
|
|
@@ -429,183 +429,6 @@ async function getLatestVersion(packageName) {
|
|
|
429
429
|
});
|
|
430
430
|
}
|
|
431
431
|
|
|
432
|
-
// src/modules/update-commands.ts
|
|
433
|
-
var import_fs2 = __toESM(require("fs"));
|
|
434
|
-
var import_path2 = __toESM(require("path"));
|
|
435
|
-
var import_url = require("url");
|
|
436
|
-
var dotenv = __toESM(require("dotenv"));
|
|
437
|
-
var import_ethers = require("ethers");
|
|
438
|
-
var import_zod = require("zod");
|
|
439
|
-
var import_picocolors4 = require("picocolors");
|
|
440
|
-
var import_sdk = require("@towns-protocol/sdk");
|
|
441
|
-
var import_utils3 = require("@towns-protocol/utils");
|
|
442
|
-
var import_proto = require("@towns-protocol/proto");
|
|
443
|
-
var import_protobuf = require("@bufbuild/protobuf");
|
|
444
|
-
var slashCommandSchema = import_zod.z.object({
|
|
445
|
-
name: import_zod.z.string().min(1, "Command name is required").max(32, "Command name must be 32 characters or less").regex(
|
|
446
|
-
/^[a-zA-Z][a-zA-Z0-9_]*$/,
|
|
447
|
-
"Command name must start with a letter and contain only letters, numbers, and underscores"
|
|
448
|
-
),
|
|
449
|
-
description: import_zod.z.string().min(1, "Command description is required").max(256, "Command description must be 256 characters or less")
|
|
450
|
-
}).transform((data) => (0, import_protobuf.create)(import_proto.SlashCommandSchema, data));
|
|
451
|
-
async function updateCommands(argv) {
|
|
452
|
-
const filePath = argv.file || argv._[1];
|
|
453
|
-
const bearerToken = argv.bearerToken || argv._[2];
|
|
454
|
-
const envFile = argv.envFile || ".env";
|
|
455
|
-
if (!filePath || !bearerToken) {
|
|
456
|
-
console.error((0, import_picocolors4.red)("Error: Missing required arguments"));
|
|
457
|
-
console.log();
|
|
458
|
-
console.log((0, import_picocolors4.yellow)("Usage:"));
|
|
459
|
-
console.log(" towns-bot update-commands <file-path> <bearer-token>");
|
|
460
|
-
console.log((0, import_picocolors4.cyan)(" OR"));
|
|
461
|
-
console.log(
|
|
462
|
-
" towns-bot update-commands --file <path> --bearerToken <token> [--envFile <path>]"
|
|
463
|
-
);
|
|
464
|
-
console.log();
|
|
465
|
-
console.log((0, import_picocolors4.yellow)("Arguments:"));
|
|
466
|
-
console.log(" file-path Path to file exporting slash commands");
|
|
467
|
-
console.log(" bearer-token Owner's bearer token for authentication");
|
|
468
|
-
console.log();
|
|
469
|
-
console.log((0, import_picocolors4.yellow)("Options:"));
|
|
470
|
-
console.log(" -f, --file <path> Path to commands file");
|
|
471
|
-
console.log(" -t, --bearerToken <token> Bearer token");
|
|
472
|
-
console.log(" -e, --envFile <path> Path to .env file (default: .env)");
|
|
473
|
-
console.log();
|
|
474
|
-
console.log((0, import_picocolors4.yellow)("Note:"));
|
|
475
|
-
console.log(
|
|
476
|
-
" The bot address and environment are read from APP_PRIVATE_DATA in your .env file"
|
|
477
|
-
);
|
|
478
|
-
process.exit(1);
|
|
479
|
-
}
|
|
480
|
-
const envPath = import_path2.default.resolve(envFile);
|
|
481
|
-
if (!import_fs2.default.existsSync(envPath)) {
|
|
482
|
-
console.error((0, import_picocolors4.red)(`Error: Environment file not found: ${envPath}`));
|
|
483
|
-
console.log((0, import_picocolors4.yellow)("Please ensure your .env file exists and contains APP_PRIVATE_DATA"));
|
|
484
|
-
process.exit(1);
|
|
485
|
-
}
|
|
486
|
-
dotenv.config({ path: envPath });
|
|
487
|
-
const appPrivateDataStr = process.env.APP_PRIVATE_DATA;
|
|
488
|
-
if (!appPrivateDataStr) {
|
|
489
|
-
console.error((0, import_picocolors4.red)("Error: APP_PRIVATE_DATA not found in environment variables"));
|
|
490
|
-
console.log((0, import_picocolors4.yellow)("Please ensure your .env file contains APP_PRIVATE_DATA"));
|
|
491
|
-
process.exit(1);
|
|
492
|
-
}
|
|
493
|
-
let privateKey;
|
|
494
|
-
let env;
|
|
495
|
-
try {
|
|
496
|
-
const appPrivateData = (0, import_sdk.parseAppPrivateData)(appPrivateDataStr);
|
|
497
|
-
privateKey = appPrivateData.privateKey;
|
|
498
|
-
env = appPrivateData.env;
|
|
499
|
-
} catch {
|
|
500
|
-
console.error((0, import_picocolors4.red)("Error: Failed to parse APP_PRIVATE_DATA"));
|
|
501
|
-
console.log((0, import_picocolors4.yellow)("Please ensure APP_PRIVATE_DATA is in the correct format"));
|
|
502
|
-
process.exit(1);
|
|
503
|
-
}
|
|
504
|
-
if (!env) {
|
|
505
|
-
console.error((0, import_picocolors4.red)("Error: Environment not found in APP_PRIVATE_DATA"));
|
|
506
|
-
process.exit(1);
|
|
507
|
-
}
|
|
508
|
-
let appClientAddress;
|
|
509
|
-
try {
|
|
510
|
-
const wallet = new import_ethers.ethers.Wallet(privateKey);
|
|
511
|
-
appClientAddress = wallet.address.toLowerCase();
|
|
512
|
-
} catch {
|
|
513
|
-
console.error((0, import_picocolors4.red)("Error: Failed to derive address from private key"));
|
|
514
|
-
process.exit(1);
|
|
515
|
-
}
|
|
516
|
-
try {
|
|
517
|
-
const resolvedPath = import_path2.default.resolve(filePath);
|
|
518
|
-
if (!import_fs2.default.existsSync(resolvedPath)) {
|
|
519
|
-
throw new Error(`File not found: ${resolvedPath}`);
|
|
520
|
-
}
|
|
521
|
-
let commands = [];
|
|
522
|
-
const fileUrl = (0, import_url.pathToFileURL)(resolvedPath).href;
|
|
523
|
-
try {
|
|
524
|
-
const module2 = await import(fileUrl);
|
|
525
|
-
commands = module2.default || module2.commands;
|
|
526
|
-
if (!commands) {
|
|
527
|
-
throw new Error('No default export or "commands" export found in file');
|
|
528
|
-
}
|
|
529
|
-
} catch (error) {
|
|
530
|
-
throw new Error(
|
|
531
|
-
`Failed to import commands file: ${error instanceof Error ? error.message : String(error)}`
|
|
532
|
-
);
|
|
533
|
-
}
|
|
534
|
-
try {
|
|
535
|
-
const validatedCommands = import_zod.z.array(slashCommandSchema).parse(commands);
|
|
536
|
-
commands = validatedCommands;
|
|
537
|
-
} catch (zodError) {
|
|
538
|
-
if (zodError instanceof import_zod.z.ZodError) {
|
|
539
|
-
const errors = zodError.errors.map((err) => {
|
|
540
|
-
const path5 = err.path.length > 0 ? `[${err.path.join(".")}]` : "";
|
|
541
|
-
return ` ${path5} ${err.message}`;
|
|
542
|
-
}).join("\n");
|
|
543
|
-
throw new Error(`Invalid slash commands:
|
|
544
|
-
${errors}`);
|
|
545
|
-
}
|
|
546
|
-
throw zodError;
|
|
547
|
-
}
|
|
548
|
-
console.log((0, import_picocolors4.cyan)("Found"), (0, import_picocolors4.green)(commands.length.toString()), (0, import_picocolors4.cyan)("commands:"));
|
|
549
|
-
for (const cmd of commands) {
|
|
550
|
-
console.log(` /${(0, import_picocolors4.green)(cmd.name)} - ${cmd.description}`);
|
|
551
|
-
}
|
|
552
|
-
try {
|
|
553
|
-
const signerContext = await (0, import_sdk.makeSignerContextFromBearerToken)(bearerToken);
|
|
554
|
-
const appRegistryUrl = (0, import_sdk.townsEnv)().getAppRegistryUrl(env);
|
|
555
|
-
const { appRegistryRpcClient } = await import_sdk.AppRegistryService.authenticate(
|
|
556
|
-
signerContext,
|
|
557
|
-
appRegistryUrl
|
|
558
|
-
);
|
|
559
|
-
const appId = (0, import_utils3.bin_fromHexString)(appClientAddress);
|
|
560
|
-
const { metadata } = await appRegistryRpcClient.getAppMetadata({ appId });
|
|
561
|
-
if (!metadata) {
|
|
562
|
-
throw new Error("App not found or you do not have permission to modify it");
|
|
563
|
-
}
|
|
564
|
-
console.log();
|
|
565
|
-
await appRegistryRpcClient.updateAppMetadata({
|
|
566
|
-
appId,
|
|
567
|
-
updateMask: ["slash_commands"],
|
|
568
|
-
metadata: {
|
|
569
|
-
slashCommands: commands
|
|
570
|
-
}
|
|
571
|
-
});
|
|
572
|
-
console.log((0, import_picocolors4.cyan)("Bot:"), metadata.displayName);
|
|
573
|
-
console.log((0, import_picocolors4.green)("\u2713"), "Slash commands updated successfully!");
|
|
574
|
-
process.exit(0);
|
|
575
|
-
} catch (authError) {
|
|
576
|
-
const errorMessage = authError instanceof Error ? authError.message : String(authError);
|
|
577
|
-
if (errorMessage.includes("app was not found in registry")) {
|
|
578
|
-
throw new Error(
|
|
579
|
-
`Bot not found: ${appClientAddress}
|
|
580
|
-
|
|
581
|
-
Make sure the bot address is correct and the bot exists on the ${env} network.`
|
|
582
|
-
);
|
|
583
|
-
} else if (errorMessage.includes("permission") || errorMessage.includes("unauthorized")) {
|
|
584
|
-
throw new Error(
|
|
585
|
-
`Permission denied: You don't have permission to modify this bot.
|
|
586
|
-
|
|
587
|
-
Make sure the bearer token belongs to the bot owner.`
|
|
588
|
-
);
|
|
589
|
-
} else if (errorMessage.includes("invalid") || errorMessage.includes("malformed")) {
|
|
590
|
-
throw new Error(
|
|
591
|
-
`Invalid bearer token format.
|
|
592
|
-
|
|
593
|
-
Please check that the bearer token is correctly formatted.`
|
|
594
|
-
);
|
|
595
|
-
} else {
|
|
596
|
-
throw new Error(
|
|
597
|
-
`Failed to update commands: ${errorMessage}
|
|
598
|
-
|
|
599
|
-
Please check your bearer token and bot address.`
|
|
600
|
-
);
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
} catch (error) {
|
|
604
|
-
console.error((0, import_picocolors4.red)("Error:"), error instanceof Error ? error.message : error);
|
|
605
|
-
process.exit(1);
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
|
|
609
432
|
// src/parser.ts
|
|
610
433
|
var import_minimist = __toESM(require("minimist"));
|
|
611
434
|
var COMMAND_CONFIGS = {
|
|
@@ -616,20 +439,6 @@ var COMMAND_CONFIGS = {
|
|
|
616
439
|
},
|
|
617
440
|
update: {
|
|
618
441
|
// No special config needed
|
|
619
|
-
},
|
|
620
|
-
"list-commands": {
|
|
621
|
-
string: ["file"],
|
|
622
|
-
alias: { f: "file" }
|
|
623
|
-
},
|
|
624
|
-
"update-commands": {
|
|
625
|
-
// Force all positional args after command to be strings (prevents hex->number conversion)
|
|
626
|
-
string: ["file", "bearerToken", "envFile", "_"],
|
|
627
|
-
alias: {
|
|
628
|
-
f: "file",
|
|
629
|
-
t: "bearerToken",
|
|
630
|
-
e: "envFile"
|
|
631
|
-
},
|
|
632
|
-
default: { envFile: ".env" }
|
|
633
442
|
}
|
|
634
443
|
};
|
|
635
444
|
function parseArgs(args) {
|
|
@@ -660,9 +469,6 @@ function isInitArgs(args) {
|
|
|
660
469
|
function isUpdateArgs(args) {
|
|
661
470
|
return args._[0] === "update";
|
|
662
471
|
}
|
|
663
|
-
function isUpdateCommandsArgs(args) {
|
|
664
|
-
return args._[0] === "update-commands";
|
|
665
|
-
}
|
|
666
472
|
|
|
667
473
|
// src/index.ts
|
|
668
474
|
async function main() {
|
|
@@ -684,76 +490,56 @@ async function main() {
|
|
|
684
490
|
await update(args);
|
|
685
491
|
}
|
|
686
492
|
break;
|
|
687
|
-
case "update-commands":
|
|
688
|
-
if (isUpdateCommandsArgs(args)) {
|
|
689
|
-
await updateCommands(args);
|
|
690
|
-
}
|
|
691
|
-
break;
|
|
692
493
|
default:
|
|
693
|
-
console.error((0,
|
|
494
|
+
console.error((0, import_picocolors4.red)(`Unknown command: ${command}`));
|
|
694
495
|
showHelp();
|
|
695
496
|
process.exit(1);
|
|
696
497
|
}
|
|
697
498
|
} catch (error) {
|
|
698
|
-
console.error((0,
|
|
499
|
+
console.error((0, import_picocolors4.red)("Error:"), error instanceof Error ? error.message : error);
|
|
699
500
|
process.exit(1);
|
|
700
501
|
}
|
|
701
502
|
}
|
|
702
503
|
function showHelp() {
|
|
703
504
|
console.log(`
|
|
704
|
-
${(0,
|
|
505
|
+
${(0, import_picocolors4.cyan)("towns-bot")} - CLI for creating and managing Towns Protocol bot projects
|
|
705
506
|
|
|
706
|
-
${(0,
|
|
507
|
+
${(0, import_picocolors4.yellow)("Usage:")}
|
|
707
508
|
towns-bot <command> [options]
|
|
708
509
|
|
|
709
|
-
${(0,
|
|
710
|
-
${(0,
|
|
711
|
-
${(0,
|
|
712
|
-
${(0, import_picocolors5.green)("list-commands")} List slash commands from a file
|
|
713
|
-
${(0, import_picocolors5.green)("update-commands")} Update slash commands for a bot
|
|
510
|
+
${(0, import_picocolors4.yellow)("Commands:")}
|
|
511
|
+
${(0, import_picocolors4.green)("init")} [project-name] Create a new bot project
|
|
512
|
+
${(0, import_picocolors4.green)("update")} Update @towns-protocol dependencies to latest versions
|
|
714
513
|
|
|
715
|
-
${(0,
|
|
514
|
+
${(0, import_picocolors4.yellow)("Init Options:")}
|
|
716
515
|
-t, --template <name> Template to use:
|
|
717
516
|
${Object.entries(TEMPLATES).map(
|
|
718
517
|
([key, template]) => ` ${key} - ${template.description}`
|
|
719
518
|
).join("\n")}
|
|
720
519
|
Default: quickstart
|
|
721
520
|
|
|
722
|
-
${(0,
|
|
521
|
+
${(0, import_picocolors4.yellow)("List Commands Options:")}
|
|
723
522
|
-f, --file <path> Path to commands file
|
|
724
523
|
|
|
725
|
-
${(0,
|
|
524
|
+
${(0, import_picocolors4.yellow)("Update Commands Options:")}
|
|
726
525
|
-f, --file <path> Path to commands file
|
|
727
526
|
-t, --bearerToken <token> Bearer token for authentication
|
|
728
527
|
-e, --envFile <path> Path to .env file (default: .env)
|
|
729
528
|
|
|
730
|
-
${(0,
|
|
529
|
+
${(0, import_picocolors4.yellow)("Global Options:")}
|
|
731
530
|
-h, --help Show this help message
|
|
732
531
|
|
|
733
|
-
${(0,
|
|
734
|
-
${(0,
|
|
532
|
+
${(0, import_picocolors4.yellow)("Examples:")}
|
|
533
|
+
${(0, import_picocolors4.cyan)("# Create a new bot project")}
|
|
735
534
|
towns-bot init my-bot
|
|
736
535
|
towns-bot init my-ai-bot --template quickstart
|
|
737
536
|
|
|
738
|
-
${(0,
|
|
537
|
+
${(0, import_picocolors4.cyan)("# Update dependencies")}
|
|
739
538
|
towns-bot update
|
|
740
|
-
|
|
741
|
-
${(0, import_picocolors5.cyan)("# List slash commands")}
|
|
742
|
-
towns-bot list-commands src/commands.ts
|
|
743
|
-
towns-bot list-commands --file src/commands.ts
|
|
744
|
-
|
|
745
|
-
${(0, import_picocolors5.cyan)("# Update slash commands (positional arguments)")}
|
|
746
|
-
towns-bot update-commands commands.ts token123
|
|
747
|
-
|
|
748
|
-
${(0, import_picocolors5.cyan)("# Update slash commands (named arguments)")}
|
|
749
|
-
towns-bot update-commands --file commands.ts --bearerToken token123
|
|
750
|
-
towns-bot update-commands -f commands.ts -t token123 -e custom.env
|
|
751
|
-
|
|
752
|
-
${(0, import_picocolors5.cyan)("Note: Bot address and environment are read from APP_PRIVATE_DATA in .env")}
|
|
753
539
|
`);
|
|
754
540
|
}
|
|
755
541
|
main().catch((error) => {
|
|
756
|
-
console.error((0,
|
|
542
|
+
console.error((0, import_picocolors4.red)("Unexpected error:"), error);
|
|
757
543
|
process.exit(1);
|
|
758
544
|
});
|
|
759
545
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/modules/init.ts","../src/modules/utils.ts","../src/modules/update.ts","../src/modules/update-commands.ts","../src/parser.ts"],"sourcesContent":["import { green, red, yellow, cyan } from 'picocolors'\nimport { init, TEMPLATES, type Template } from './modules/init.js'\nimport { update } from './modules/update.js'\nimport { updateCommands } from './modules/update-commands.js'\nimport { parseArgs, isInitArgs, isUpdateArgs, isUpdateCommandsArgs } from './parser.js'\n\nasync function main() {\n const args = parseArgs(process.argv.slice(2))\n const command = args._[0]\n\n if (args.help || !command) {\n showHelp()\n return\n }\n\n try {\n switch (command) {\n case 'init':\n if (isInitArgs(args)) {\n await init(args)\n }\n break\n case 'update':\n if (isUpdateArgs(args)) {\n await update(args)\n }\n break\n case 'update-commands':\n if (isUpdateCommandsArgs(args)) {\n await updateCommands(args)\n }\n break\n default:\n console.error(red(`Unknown command: ${command}`))\n showHelp()\n process.exit(1)\n }\n } catch (error) {\n console.error(red('Error:'), error instanceof Error ? error.message : error)\n process.exit(1)\n }\n}\n\nfunction showHelp() {\n console.log(`\n${cyan('towns-bot')} - CLI for creating and managing Towns Protocol bot projects\n\n${yellow('Usage:')}\n towns-bot <command> [options]\n\n${yellow('Commands:')}\n ${green('init')} [project-name] Create a new bot project\n ${green('update')} Update @towns-protocol dependencies to latest versions\n ${green('list-commands')} List slash commands from a file\n ${green('update-commands')} Update slash commands for a bot\n\n${yellow('Init Options:')}\n -t, --template <name> Template to use:\n${Object.entries(TEMPLATES)\n .map(\n ([key, template]: [string, Template]) =>\n ` ${key} - ${template.description}`,\n )\n .join('\\n')}\n Default: quickstart\n\n${yellow('List Commands Options:')}\n -f, --file <path> Path to commands file\n\n${yellow('Update Commands Options:')}\n -f, --file <path> Path to commands file\n -t, --bearerToken <token> Bearer token for authentication\n -e, --envFile <path> Path to .env file (default: .env)\n\n${yellow('Global Options:')}\n -h, --help Show this help message\n\n${yellow('Examples:')}\n ${cyan('# Create a new bot project')}\n towns-bot init my-bot\n towns-bot init my-ai-bot --template quickstart\n\n ${cyan('# Update dependencies')}\n towns-bot update\n\n ${cyan('# List slash commands')}\n towns-bot list-commands src/commands.ts\n towns-bot list-commands --file src/commands.ts\n\n ${cyan('# Update slash commands (positional arguments)')}\n towns-bot update-commands commands.ts token123\n\n ${cyan('# Update slash commands (named arguments)')}\n towns-bot update-commands --file commands.ts --bearerToken token123\n towns-bot update-commands -f commands.ts -t token123 -e custom.env\n\n ${cyan('Note: Bot address and environment are read from APP_PRIVATE_DATA in .env')}\n`)\n}\n\nmain().catch((error) => {\n console.error(red('Unexpected error:'), error)\n process.exit(1)\n})\n","import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport { default as prompts } from 'prompts'\nimport { red, yellow, cyan } from 'picocolors'\nimport * as jsonc from 'jsonc-parser'\nimport {\n getPackageManager,\n getLatestTownsProtocolVersion,\n cloneTemplate,\n applyReplacements,\n printSuccess,\n initializeGitRepository,\n type PackageJson,\n} from './utils.js'\nimport type { InitArgs } from '../parser.js'\n\nexport type Template = (typeof TEMPLATES)[keyof typeof TEMPLATES]\nexport const TEMPLATES = {\n quickstart: {\n name: 'Bot Quickstart',\n description: 'Simple starter bot with basic commands',\n packagePath: 'bot-quickstart',\n },\n} as const\n\nexport async function init(argv: InitArgs) {\n const projectName = argv._[1]\n const template = argv.template || 'quickstart'\n\n if (!projectName) {\n console.error(red('Error: Please provide a project name'))\n console.log(yellow('Usage: towns-bot init <project-name>'))\n process.exit(1)\n }\n\n if (!TEMPLATES[template as keyof typeof TEMPLATES]) {\n console.error(red(`Error: Unknown template \"${template}\"`))\n console.log(yellow('Available templates:'), Object.keys(TEMPLATES).join(', '))\n process.exit(1)\n }\n\n const targetDir = path.resolve(process.cwd(), projectName)\n\n if (fs.existsSync(targetDir)) {\n const { overwrite } = await prompts({\n type: 'confirm',\n name: 'overwrite',\n message: `Directory ${projectName} already exists. Overwrite?`,\n initial: false,\n })\n\n if (!overwrite) {\n console.log(yellow('Operation cancelled'))\n process.exit(0)\n }\n\n fs.rmSync(targetDir, { recursive: true, force: true })\n }\n\n console.log(cyan(`Creating a new Towns Protocol bot in ${targetDir}`))\n if (template !== 'quickstart') {\n console.log(cyan(`Using template: ${TEMPLATES[template as keyof typeof TEMPLATES].name}`))\n }\n\n const packageManager = getPackageManager()\n const selectedTemplate = TEMPLATES[template as keyof typeof TEMPLATES]\n\n try {\n // Clone template from GitHub\n const success = await cloneTemplate(selectedTemplate.packagePath, targetDir)\n if (!success) {\n console.error(red('Failed to clone template'))\n process.exit(1)\n }\n const latestVersion = await getLatestTownsProtocolVersion()\n // Replace workspace dependencies in package.json and other files\n const replacements = new Map([\n ['workspace:\\\\^', `^${latestVersion}`],\n ['workspace:\\\\*', `^${latestVersion}`],\n ])\n\n // Apply replacements to all relevant files\n applyReplacements(targetDir, replacements)\n\n const packageJsonPath = path.join(targetDir, 'package.json')\n if (fs.existsSync(packageJsonPath)) {\n const content = fs.readFileSync(packageJsonPath, 'utf-8')\n const edits = [\n jsonc.modify(content, ['name'], projectName, {}),\n jsonc.modify(content, ['version'], '0.0.1', {}),\n ]\n\n let modifiedContent = jsonc.applyEdits(content, edits.flat())\n\n const parsed = jsonc.parse(modifiedContent) as PackageJson\n delete parsed.private\n\n modifiedContent = JSON.stringify(parsed, null, 2)\n fs.writeFileSync(packageJsonPath, modifiedContent)\n }\n await initializeGitRepository(targetDir)\n printSuccess(projectName, packageManager)\n } catch (error) {\n console.error(red('Error:'), error instanceof Error ? error.message : error)\n console.error(red(`Please delete the directory ${targetDir} and try again.`))\n process.exit(1)\n }\n}\n","import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport { default as spawn } from 'cross-spawn'\nimport picocolors from 'picocolors'\n\nexport type PackageJson = {\n private?: boolean\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n}\n\nexport const getPackageManager = () => {\n if (process.env.npm_config_user_agent) {\n const agent = process.env.npm_config_user_agent\n if (agent.startsWith('yarn')) return 'yarn'\n if (agent.startsWith('npm')) return 'npm'\n if (agent.startsWith('pnpm')) return 'pnpm'\n if (agent.startsWith('bun')) return 'bun'\n }\n // Default to npm if no user agent is found\n return 'npm'\n}\n\nexport function getInstallCommand(packageManager: string): string {\n switch (packageManager) {\n case 'bun':\n return 'bun install'\n case 'yarn':\n return 'yarn'\n case 'pnpm':\n return 'pnpm install'\n default:\n return 'npm install'\n }\n}\n\nexport function getRunCommand(packageManager: string, script: string): string {\n switch (packageManager) {\n case 'bun':\n return `bun run ${script}`\n case 'yarn':\n return `yarn ${script}`\n case 'pnpm':\n return `pnpm ${script}`\n default:\n return `npm run ${script}`\n }\n}\n\nexport function runCommand(\n command: string,\n args: string[],\n opts: { cwd?: string; silent?: boolean } = { cwd: undefined, silent: false },\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n stdio: opts.silent ? 'ignore' : 'inherit',\n cwd: opts.cwd,\n shell: process.platform === 'win32',\n })\n\n child.on('close', (code) => {\n if (code !== 0) {\n reject(new Error(`Command failed with exit code ${code}`))\n } else {\n resolve()\n }\n })\n\n child.on('error', reject)\n })\n}\n\nexport async function getLatestTownsProtocolVersion(): Promise<string> {\n return new Promise((resolve, reject) => {\n const child = spawn('npm', ['view', '@towns-protocol/bot', 'version'], {\n stdio: ['ignore', 'pipe', 'ignore'],\n })\n\n let output = ''\n child.stdout?.on('data', (data) => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n output += data.toString()\n })\n\n child.on('close', (code) => {\n if (code !== 0) {\n reject(new Error('Failed to fetch latest @towns-protocol/bot version'))\n } else {\n resolve(output.trim())\n }\n })\n\n child.on('error', reject)\n })\n}\n\nexport function copyDirectory(src: string, dest: string, replacements?: Map<string, string>) {\n if (!fs.existsSync(dest)) {\n fs.mkdirSync(dest, { recursive: true })\n }\n\n const entries = fs.readdirSync(src, { withFileTypes: true })\n\n for (const entry of entries) {\n const srcPath = path.join(src, entry.name)\n const destPath = path.join(dest, entry.name)\n\n if (entry.isDirectory()) {\n if (entry.name === 'node_modules' || entry.name === 'dist') {\n continue\n }\n copyDirectory(srcPath, destPath, replacements)\n } else {\n let content = fs.readFileSync(srcPath, 'utf-8')\n\n if (\n replacements &&\n (entry.name === 'package.json' ||\n entry.name.endsWith('.ts') ||\n entry.name.endsWith('.js'))\n ) {\n for (const [search, replace] of replacements) {\n content = content.replace(new RegExp(search, 'g'), replace)\n }\n }\n\n fs.writeFileSync(destPath, content)\n }\n }\n}\n\nexport function getLatestSdkTag(): string | null {\n const tagsResult = spawn.sync(\n 'git',\n ['ls-remote', '--tags', 'https://github.com/towns-protocol/towns.git', 'sdk-*'],\n { encoding: 'utf8' },\n )\n\n if (tagsResult.status !== 0 || !tagsResult.stdout) return null\n\n const tags = tagsResult.stdout\n .split('\\n')\n .filter(Boolean)\n .map((line) => {\n const [_hash, ref] = line.split('\\t')\n const tag = ref.replace('refs/tags/', '').replace(/\\^{}$/, '')\n\n // Extract version numbers from tags like sdk-hash-1.2.3\n const match = tag.match(/^sdk-[0-9a-f]+-(\\d+)\\.(\\d+)\\.(\\d+)$/)\n if (!match) return null\n\n return {\n tag,\n version: [parseInt(match[1]), parseInt(match[2]), parseInt(match[3])],\n }\n })\n .filter(\n (item): item is { tag: string; version: number[] } =>\n item !== null && Array.isArray(item.version) && item.version.length === 3,\n )\n .sort((a, b) => {\n // Compare version numbers\n for (let i = 0; i < 3; i++) {\n if (a.version[i] !== b.version[i]) {\n return b.version[i] - a.version[i]\n }\n }\n return 0\n })\n\n return tags.length > 0 ? tags[0].tag : null\n}\n\nexport async function cloneTemplate(packagePath: string, targetDir: string): Promise<boolean> {\n console.log(picocolors.blue('Cloning template from GitHub...'))\n\n const tempDir = `${targetDir}-temp`\n const fullTemplatePath = `packages/examples/${packagePath}`\n\n // Get latest SDK tag\n const latestSdkTag = getLatestSdkTag()\n if (!latestSdkTag) {\n console.error(picocolors.red('Failed to get latest SDK tag.'))\n return false\n }\n\n // Clone with minimal data to a temporary directory\n const cloneResult = spawn.sync(\n 'git',\n [\n 'clone',\n '--no-checkout',\n '--depth',\n '1',\n '--sparse',\n '--branch',\n latestSdkTag,\n 'https://github.com/towns-protocol/towns.git',\n tempDir,\n ],\n { stdio: 'pipe' },\n )\n if (cloneResult.status !== 0) return false\n\n // Set up sparse checkout for the specific template\n const sparseResult = spawn.sync('git', ['sparse-checkout', 'set', fullTemplatePath], {\n stdio: 'pipe',\n cwd: tempDir,\n })\n if (sparseResult.status !== 0) {\n fs.rmSync(tempDir, { recursive: true, force: true })\n return false\n }\n\n // Checkout the content\n const checkoutResult = spawn.sync('git', ['checkout'], {\n stdio: 'pipe',\n cwd: tempDir,\n })\n if (checkoutResult.status !== 0) {\n fs.rmSync(tempDir, { recursive: true, force: true })\n return false\n }\n\n // Verify template directory exists\n const sourceDir = path.join(tempDir, fullTemplatePath)\n if (!fs.existsSync(sourceDir)) {\n console.error(picocolors.red(`\\nTemplate directory not found at ${sourceDir}`))\n fs.rmSync(tempDir, { recursive: true, force: true })\n return false\n }\n\n // Copy template contents to target directory\n fs.mkdirSync(targetDir, { recursive: true })\n // Use filter to ensure all files (including hidden) are copied\n fs.cpSync(sourceDir, targetDir, {\n recursive: true,\n filter: () => {\n // Copy all files, including hidden ones\n return true\n },\n })\n\n // Clean up temporary directory\n fs.rmSync(tempDir, { recursive: true, force: true })\n\n console.log(picocolors.green('✓'), 'Template cloned successfully!')\n return true\n}\n\nexport function applyReplacements(targetDir: string, replacements: Map<string, string>) {\n function processDirectory(dir: string) {\n const entries = fs.readdirSync(dir, { withFileTypes: true })\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name)\n\n if (entry.isDirectory()) {\n if (entry.name === 'node_modules' || entry.name === 'dist') {\n continue\n }\n processDirectory(fullPath)\n } else {\n let content = fs.readFileSync(fullPath, 'utf-8')\n let modified = false\n\n if (\n entry.name === 'package.json' ||\n entry.name.endsWith('.ts') ||\n entry.name.endsWith('.js')\n ) {\n for (const [search, replace] of replacements) {\n const regex = new RegExp(search, 'g')\n if (regex.test(content)) {\n content = content.replace(regex, replace)\n modified = true\n }\n }\n\n if (modified) {\n fs.writeFileSync(fullPath, content)\n }\n }\n }\n }\n }\n\n processDirectory(targetDir)\n}\n\nexport function printSuccess(projectName: string, packageManager: string) {\n console.log(picocolors.green('✓'), 'Bot project created successfully!')\n console.log()\n console.log('Next steps:')\n console.log(picocolors.cyan(` cd ${projectName}`))\n console.log(picocolors.cyan(` ${getInstallCommand(packageManager)}`))\n console.log('Set up your environment variables:')\n console.log(picocolors.cyan(' cp .env.sample .env'))\n console.log(' Edit .env with your bot credentials')\n console.log('Start your bot:')\n console.log(picocolors.cyan(` ${getRunCommand(packageManager, 'dev')}`))\n}\n\nexport async function initializeGitRepository(targetDir: string): Promise<boolean> {\n try {\n await runCommand('git', ['init'], { cwd: targetDir, silent: true })\n await runCommand('git', ['add', '.'], { cwd: targetDir, silent: true })\n await runCommand('git', ['commit', '-m', 'feat: towns bot scaffolding'], {\n cwd: targetDir,\n silent: true,\n })\n return true\n } catch (error) {\n console.log(\n picocolors.yellow('⚠'),\n 'Failed to initialize git repository:',\n error instanceof Error ? error.message : 'Unknown error',\n )\n console.log(picocolors.yellow(' You can manually initialize git later with: git init'))\n return false\n }\n}\n","import fs from 'fs'\nimport path from 'path'\nimport { default as spawn } from 'cross-spawn'\nimport { green, red, yellow, cyan } from 'picocolors'\nimport * as jsonc from 'jsonc-parser'\nimport { getPackageManager, getInstallCommand, runCommand, type PackageJson } from './utils.js'\nimport type { UpdateArgs } from '../parser.js'\n\ninterface PackageVersions {\n [key: string]: string\n}\n\nexport async function update(_argv: UpdateArgs) {\n const packageJsonPath = path.join(process.cwd(), 'package.json')\n\n if (!fs.existsSync(packageJsonPath)) {\n console.error(red('Error: No package.json found in the current directory'))\n console.log(yellow('Please run this command from a Towns Protocol bot project directory'))\n process.exit(1)\n }\n\n const packageJson = jsonc.parse(fs.readFileSync(packageJsonPath, 'utf-8')) as PackageJson\n const dependencies = { ...packageJson.dependencies, ...packageJson.devDependencies }\n\n const townsPackages = Object.keys(dependencies).filter((pkg) =>\n pkg.startsWith('@towns-protocol/'),\n )\n\n if (townsPackages.length === 0) {\n console.log(yellow('No @towns-protocol packages found in this project'))\n process.exit(0)\n }\n\n console.log(cyan('Found Towns Protocol packages:'))\n townsPackages.forEach((pkg) => {\n console.log(` - ${pkg}@${dependencies[pkg]}`)\n })\n console.log()\n\n console.log(cyan('Fetching latest versions...'))\n const latestVersions: PackageVersions = {}\n\n for (const pkg of townsPackages) {\n try {\n const version = await getLatestVersion(pkg)\n latestVersions[pkg] = version\n console.log(green('✓'), `${pkg}: ${version}`)\n } catch {\n console.error(red('✗'), `Failed to fetch version for ${pkg}`)\n }\n }\n\n console.log()\n console.log(cyan('Updating package.json...'))\n\n const content = fs.readFileSync(packageJsonPath, 'utf-8')\n const edits: jsonc.Edit[] = []\n\n for (const [pkg, version] of Object.entries(latestVersions)) {\n const currentVersion = dependencies[pkg]\n if (currentVersion !== `^${version}`) {\n if (packageJson.dependencies?.[pkg]) {\n edits.push(...jsonc.modify(content, ['dependencies', pkg], `^${version}`, {}))\n }\n if (packageJson.devDependencies?.[pkg]) {\n edits.push(...jsonc.modify(content, ['devDependencies', pkg], `^${version}`, {}))\n }\n }\n }\n\n if (edits.length > 0) {\n const modifiedContent = jsonc.applyEdits(content, edits)\n fs.writeFileSync(packageJsonPath, modifiedContent)\n console.log(green('✓'), 'Updated package.json')\n\n const packageManager = getPackageManager()\n console.log()\n console.log(cyan(`Installing dependencies with ${packageManager}...`))\n\n try {\n await runCommand(packageManager, [\n getInstallCommand(packageManager).split(' ')[1] || 'install',\n ])\n console.log()\n console.log(green('✓'), 'Dependencies updated successfully!')\n } catch {\n console.error(red('Error:'), 'Failed to install dependencies')\n console.log(\n yellow('Please run'),\n cyan(getInstallCommand(packageManager)),\n yellow('manually'),\n )\n }\n } else {\n console.log(green('✓'), 'All packages are already up to date!')\n }\n}\n\nasync function getLatestVersion(packageName: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const child = spawn('npm', ['view', packageName, 'version'], {\n stdio: ['ignore', 'pipe', 'ignore'],\n })\n\n let output = ''\n child.stdout?.on('data', (data) => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n output += data.toString()\n })\n\n child.on('close', (code) => {\n if (code !== 0) {\n reject(new Error(`Failed to fetch version for ${packageName}`))\n } else {\n resolve(output.trim())\n }\n })\n\n child.on('error', reject)\n })\n}\n","import fs from 'fs'\nimport path from 'path'\nimport { pathToFileURL } from 'url'\nimport * as dotenv from 'dotenv'\nimport { ethers } from 'ethers'\nimport { z } from 'zod'\nimport { green, red, yellow, cyan } from 'picocolors'\nimport {\n makeSignerContextFromBearerToken,\n AppRegistryService,\n parseAppPrivateData,\n townsEnv,\n} from '@towns-protocol/sdk'\nimport { bin_fromHexString } from '@towns-protocol/utils'\nimport { SlashCommandSchema, type SlashCommand } from '@towns-protocol/proto'\nimport type { UpdateCommandsArgs } from '../parser.js'\nimport { create } from '@bufbuild/protobuf'\n\nconst slashCommandSchema = z\n .object({\n name: z\n .string()\n .min(1, 'Command name is required')\n .max(32, 'Command name must be 32 characters or less')\n .regex(\n /^[a-zA-Z][a-zA-Z0-9_]*$/,\n 'Command name must start with a letter and contain only letters, numbers, and underscores',\n ),\n description: z\n .string()\n .min(1, 'Command description is required')\n .max(256, 'Command description must be 256 characters or less'),\n })\n .transform((data) => create(SlashCommandSchema, data))\n\nexport async function updateCommands(argv: UpdateCommandsArgs) {\n const filePath = argv.file || argv._[1]\n const bearerToken = argv.bearerToken || argv._[2]\n const envFile = argv.envFile || '.env'\n\n if (!filePath || !bearerToken) {\n console.error(red('Error: Missing required arguments'))\n console.log()\n console.log(yellow('Usage:'))\n console.log(' towns-bot update-commands <file-path> <bearer-token>')\n console.log(cyan(' OR'))\n console.log(\n ' towns-bot update-commands --file <path> --bearerToken <token> [--envFile <path>]',\n )\n console.log()\n console.log(yellow('Arguments:'))\n console.log(' file-path Path to file exporting slash commands')\n console.log(\" bearer-token Owner's bearer token for authentication\")\n console.log()\n console.log(yellow('Options:'))\n console.log(' -f, --file <path> Path to commands file')\n console.log(' -t, --bearerToken <token> Bearer token')\n console.log(' -e, --envFile <path> Path to .env file (default: .env)')\n console.log()\n console.log(yellow('Note:'))\n console.log(\n ' The bot address and environment are read from APP_PRIVATE_DATA in your .env file',\n )\n process.exit(1)\n }\n\n const envPath = path.resolve(envFile)\n if (!fs.existsSync(envPath)) {\n console.error(red(`Error: Environment file not found: ${envPath}`))\n console.log(yellow('Please ensure your .env file exists and contains APP_PRIVATE_DATA'))\n process.exit(1)\n }\n\n dotenv.config({ path: envPath })\n\n const appPrivateDataStr = process.env.APP_PRIVATE_DATA\n if (!appPrivateDataStr) {\n console.error(red('Error: APP_PRIVATE_DATA not found in environment variables'))\n console.log(yellow('Please ensure your .env file contains APP_PRIVATE_DATA'))\n process.exit(1)\n }\n\n let privateKey: string\n let env: string | undefined\n try {\n const appPrivateData = parseAppPrivateData(appPrivateDataStr)\n privateKey = appPrivateData.privateKey\n env = appPrivateData.env\n } catch {\n console.error(red('Error: Failed to parse APP_PRIVATE_DATA'))\n console.log(yellow('Please ensure APP_PRIVATE_DATA is in the correct format'))\n process.exit(1)\n }\n\n if (!env) {\n // Old format isn't supported.\n console.error(red('Error: Environment not found in APP_PRIVATE_DATA'))\n process.exit(1)\n }\n\n // Derive app client address from private key\n let appClientAddress: string\n try {\n const wallet = new ethers.Wallet(privateKey)\n appClientAddress = wallet.address.toLowerCase()\n } catch {\n console.error(red('Error: Failed to derive address from private key'))\n process.exit(1)\n }\n\n try {\n const resolvedPath = path.resolve(filePath)\n if (!fs.existsSync(resolvedPath)) {\n throw new Error(`File not found: ${resolvedPath}`)\n }\n let commands: SlashCommand[] = []\n const fileUrl = pathToFileURL(resolvedPath).href\n try {\n const module = await import(fileUrl)\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n commands = module.default || module.commands\n if (!commands) {\n throw new Error('No default export or \"commands\" export found in file')\n }\n } catch (error) {\n throw new Error(\n `Failed to import commands file: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n\n try {\n const validatedCommands = z.array(slashCommandSchema).parse(commands)\n commands = validatedCommands\n } catch (zodError) {\n if (zodError instanceof z.ZodError) {\n const errors = zodError.errors\n .map((err) => {\n const path = err.path.length > 0 ? `[${err.path.join('.')}]` : ''\n return ` ${path} ${err.message}`\n })\n .join('\\n')\n throw new Error(`Invalid slash commands:\\n${errors}`)\n }\n throw zodError\n }\n\n console.log(cyan('Found'), green(commands.length.toString()), cyan('commands:'))\n for (const cmd of commands) {\n console.log(` /${green(cmd.name)} - ${cmd.description}`)\n }\n\n try {\n const signerContext = await makeSignerContextFromBearerToken(bearerToken)\n const appRegistryUrl = townsEnv().getAppRegistryUrl(env)\n const { appRegistryRpcClient } = await AppRegistryService.authenticate(\n signerContext,\n appRegistryUrl,\n )\n const appId = bin_fromHexString(appClientAddress)\n\n const { metadata } = await appRegistryRpcClient.getAppMetadata({ appId })\n if (!metadata) {\n throw new Error('App not found or you do not have permission to modify it')\n }\n\n console.log()\n await appRegistryRpcClient.updateAppMetadata({\n appId,\n updateMask: ['slash_commands'],\n metadata: {\n slashCommands: commands,\n },\n })\n\n console.log(cyan('Bot:'), metadata.displayName)\n console.log(green('✓'), 'Slash commands updated successfully!')\n process.exit(0)\n } catch (authError: unknown) {\n const errorMessage = authError instanceof Error ? authError.message : String(authError)\n\n if (errorMessage.includes('app was not found in registry')) {\n throw new Error(\n `Bot not found: ${appClientAddress}\\n\\nMake sure the bot address is correct and the bot exists on the ${env} network.`,\n )\n } else if (\n errorMessage.includes('permission') ||\n errorMessage.includes('unauthorized')\n ) {\n throw new Error(\n `Permission denied: You don't have permission to modify this bot.\\n\\nMake sure the bearer token belongs to the bot owner.`,\n )\n } else if (errorMessage.includes('invalid') || errorMessage.includes('malformed')) {\n throw new Error(\n `Invalid bearer token format.\\n\\nPlease check that the bearer token is correctly formatted.`,\n )\n } else {\n throw new Error(\n `Failed to update commands: ${errorMessage}\\n\\nPlease check your bearer token and bot address.`,\n )\n }\n }\n } catch (error) {\n console.error(red('Error:'), error instanceof Error ? error.message : error)\n process.exit(1)\n }\n}\n","import minimist from 'minimist'\n\n// Command-specific argument interfaces\nexport interface BaseArgs {\n _: string[]\n help?: boolean\n}\n\nexport interface InitArgs extends BaseArgs {\n template?: string\n}\n\nexport type UpdateArgs = BaseArgs\n\nexport interface UpdateCommandsArgs extends BaseArgs {\n file?: string\n bearerToken?: string\n envFile?: string\n}\n\nexport type CommandArgs = InitArgs | UpdateArgs | UpdateCommandsArgs\n\n// Command configurations for minimist\nconst COMMAND_CONFIGS: Record<string, minimist.Opts> = {\n init: {\n string: ['template'],\n alias: { t: 'template' },\n default: { template: 'quickstart' },\n },\n update: {\n // No special config needed\n },\n 'list-commands': {\n string: ['file'],\n alias: { f: 'file' },\n },\n 'update-commands': {\n // Force all positional args after command to be strings (prevents hex->number conversion)\n string: ['file', 'bearerToken', 'envFile', '_'],\n alias: {\n f: 'file',\n t: 'bearerToken',\n e: 'envFile',\n },\n default: { envFile: '.env' },\n },\n}\n\n/**\n * Parse command line arguments with command-specific configurations\n *\n * This function does a two-pass parse:\n * 1. First parse to identify the command\n * 2. Second parse with command-specific configuration\n *\n * This allows each command to have its own argument parsing rules,\n * preventing issues like hex addresses being converted to numbers.\n */\nexport function parseArgs(args: string[]): CommandArgs {\n // First, do a minimal parse to get the command\n const initial = minimist(args, {\n stopEarly: true,\n boolean: ['help'],\n alias: { h: 'help' },\n })\n\n const command = initial._[0]\n\n // If no command or help requested, return early\n if (!command || initial.help) {\n return initial as BaseArgs\n }\n\n // Get command-specific configuration\n const commandConfig = COMMAND_CONFIGS[command] || {}\n\n // Re-parse with command-specific configuration\n const booleanOptions = Array.isArray(commandConfig.boolean)\n ? ['help', ...commandConfig.boolean]\n : ['help']\n const parsed = minimist(args, {\n ...commandConfig,\n boolean: booleanOptions,\n alias: {\n ...commandConfig.alias,\n h: 'help',\n },\n })\n\n return parsed as CommandArgs\n}\n\n/**\n * Type guard functions for command-specific args\n */\nexport function isInitArgs(args: CommandArgs): args is InitArgs {\n return args._[0] === 'init'\n}\n\nexport function isUpdateArgs(args: CommandArgs): args is UpdateArgs {\n return args._[0] === 'update'\n}\n\nexport function isUpdateCommandsArgs(args: CommandArgs): args is UpdateCommandsArgs {\n return args._[0] === 'update-commands'\n}\n"],"mappings":"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","names":["import_picocolors","fs","path","import_picocolors","resolve","spawn","spawn","picocolors","prompts","import_cross_spawn","import_picocolors","jsonc","path","fs","resolve","spawn","import_fs","import_path","import_picocolors","import_utils","path","fs","module","minimist"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/modules/init.ts","../src/modules/utils.ts","../src/modules/update.ts","../src/parser.ts"],"sourcesContent":["import { green, red, yellow, cyan } from 'picocolors'\nimport { init, TEMPLATES, type Template } from './modules/init.js'\nimport { update } from './modules/update.js'\nimport { parseArgs, isInitArgs, isUpdateArgs } from './parser.js'\n\nasync function main() {\n const args = parseArgs(process.argv.slice(2))\n const command = args._[0]\n\n if (args.help || !command) {\n showHelp()\n return\n }\n\n try {\n switch (command) {\n case 'init':\n if (isInitArgs(args)) {\n await init(args)\n }\n break\n case 'update':\n if (isUpdateArgs(args)) {\n await update(args)\n }\n break\n default:\n console.error(red(`Unknown command: ${command}`))\n showHelp()\n process.exit(1)\n }\n } catch (error) {\n console.error(red('Error:'), error instanceof Error ? error.message : error)\n process.exit(1)\n }\n}\n\nfunction showHelp() {\n console.log(`\n${cyan('towns-bot')} - CLI for creating and managing Towns Protocol bot projects\n\n${yellow('Usage:')}\n towns-bot <command> [options]\n\n${yellow('Commands:')}\n ${green('init')} [project-name] Create a new bot project\n ${green('update')} Update @towns-protocol dependencies to latest versions\n\n${yellow('Init Options:')}\n -t, --template <name> Template to use:\n${Object.entries(TEMPLATES)\n .map(\n ([key, template]: [string, Template]) =>\n ` ${key} - ${template.description}`,\n )\n .join('\\n')}\n Default: quickstart\n\n${yellow('List Commands Options:')}\n -f, --file <path> Path to commands file\n\n${yellow('Update Commands Options:')}\n -f, --file <path> Path to commands file\n -t, --bearerToken <token> Bearer token for authentication\n -e, --envFile <path> Path to .env file (default: .env)\n\n${yellow('Global Options:')}\n -h, --help Show this help message\n\n${yellow('Examples:')}\n ${cyan('# Create a new bot project')}\n towns-bot init my-bot\n towns-bot init my-ai-bot --template quickstart\n\n ${cyan('# Update dependencies')}\n towns-bot update\n`)\n}\n\nmain().catch((error) => {\n console.error(red('Unexpected error:'), error)\n process.exit(1)\n})\n","import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport { default as prompts } from 'prompts'\nimport { red, yellow, cyan } from 'picocolors'\nimport * as jsonc from 'jsonc-parser'\nimport {\n getPackageManager,\n getLatestTownsProtocolVersion,\n cloneTemplate,\n applyReplacements,\n printSuccess,\n initializeGitRepository,\n type PackageJson,\n} from './utils.js'\nimport type { InitArgs } from '../parser.js'\n\nexport type Template = (typeof TEMPLATES)[keyof typeof TEMPLATES]\nexport const TEMPLATES = {\n quickstart: {\n name: 'Bot Quickstart',\n description: 'Simple starter bot with basic commands',\n packagePath: 'bot-quickstart',\n },\n} as const\n\nexport async function init(argv: InitArgs) {\n const projectName = argv._[1]\n const template = argv.template || 'quickstart'\n\n if (!projectName) {\n console.error(red('Error: Please provide a project name'))\n console.log(yellow('Usage: towns-bot init <project-name>'))\n process.exit(1)\n }\n\n if (!TEMPLATES[template as keyof typeof TEMPLATES]) {\n console.error(red(`Error: Unknown template \"${template}\"`))\n console.log(yellow('Available templates:'), Object.keys(TEMPLATES).join(', '))\n process.exit(1)\n }\n\n const targetDir = path.resolve(process.cwd(), projectName)\n\n if (fs.existsSync(targetDir)) {\n const { overwrite } = await prompts({\n type: 'confirm',\n name: 'overwrite',\n message: `Directory ${projectName} already exists. Overwrite?`,\n initial: false,\n })\n\n if (!overwrite) {\n console.log(yellow('Operation cancelled'))\n process.exit(0)\n }\n\n fs.rmSync(targetDir, { recursive: true, force: true })\n }\n\n console.log(cyan(`Creating a new Towns Protocol bot in ${targetDir}`))\n if (template !== 'quickstart') {\n console.log(cyan(`Using template: ${TEMPLATES[template as keyof typeof TEMPLATES].name}`))\n }\n\n const packageManager = getPackageManager()\n const selectedTemplate = TEMPLATES[template as keyof typeof TEMPLATES]\n\n try {\n // Clone template from GitHub\n const success = await cloneTemplate(selectedTemplate.packagePath, targetDir)\n if (!success) {\n console.error(red('Failed to clone template'))\n process.exit(1)\n }\n const latestVersion = await getLatestTownsProtocolVersion()\n // Replace workspace dependencies in package.json and other files\n const replacements = new Map([\n ['workspace:\\\\^', `^${latestVersion}`],\n ['workspace:\\\\*', `^${latestVersion}`],\n ])\n\n // Apply replacements to all relevant files\n applyReplacements(targetDir, replacements)\n\n const packageJsonPath = path.join(targetDir, 'package.json')\n if (fs.existsSync(packageJsonPath)) {\n const content = fs.readFileSync(packageJsonPath, 'utf-8')\n const edits = [\n jsonc.modify(content, ['name'], projectName, {}),\n jsonc.modify(content, ['version'], '0.0.1', {}),\n ]\n\n let modifiedContent = jsonc.applyEdits(content, edits.flat())\n\n const parsed = jsonc.parse(modifiedContent) as PackageJson\n delete parsed.private\n\n modifiedContent = JSON.stringify(parsed, null, 2)\n fs.writeFileSync(packageJsonPath, modifiedContent)\n }\n await initializeGitRepository(targetDir)\n printSuccess(projectName, packageManager)\n } catch (error) {\n console.error(red('Error:'), error instanceof Error ? error.message : error)\n console.error(red(`Please delete the directory ${targetDir} and try again.`))\n process.exit(1)\n }\n}\n","import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport { default as spawn } from 'cross-spawn'\nimport picocolors from 'picocolors'\n\nexport type PackageJson = {\n private?: boolean\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n}\n\nexport const getPackageManager = () => {\n if (process.env.npm_config_user_agent) {\n const agent = process.env.npm_config_user_agent\n if (agent.startsWith('yarn')) return 'yarn'\n if (agent.startsWith('npm')) return 'npm'\n if (agent.startsWith('pnpm')) return 'pnpm'\n if (agent.startsWith('bun')) return 'bun'\n }\n // Default to npm if no user agent is found\n return 'npm'\n}\n\nexport function getInstallCommand(packageManager: string): string {\n switch (packageManager) {\n case 'bun':\n return 'bun install'\n case 'yarn':\n return 'yarn'\n case 'pnpm':\n return 'pnpm install'\n default:\n return 'npm install'\n }\n}\n\nexport function getRunCommand(packageManager: string, script: string): string {\n switch (packageManager) {\n case 'bun':\n return `bun run ${script}`\n case 'yarn':\n return `yarn ${script}`\n case 'pnpm':\n return `pnpm ${script}`\n default:\n return `npm run ${script}`\n }\n}\n\nexport function runCommand(\n command: string,\n args: string[],\n opts: { cwd?: string; silent?: boolean } = { cwd: undefined, silent: false },\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n stdio: opts.silent ? 'ignore' : 'inherit',\n cwd: opts.cwd,\n shell: process.platform === 'win32',\n })\n\n child.on('close', (code) => {\n if (code !== 0) {\n reject(new Error(`Command failed with exit code ${code}`))\n } else {\n resolve()\n }\n })\n\n child.on('error', reject)\n })\n}\n\nexport async function getLatestTownsProtocolVersion(): Promise<string> {\n return new Promise((resolve, reject) => {\n const child = spawn('npm', ['view', '@towns-protocol/bot', 'version'], {\n stdio: ['ignore', 'pipe', 'ignore'],\n })\n\n let output = ''\n child.stdout?.on('data', (data) => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n output += data.toString()\n })\n\n child.on('close', (code) => {\n if (code !== 0) {\n reject(new Error('Failed to fetch latest @towns-protocol/bot version'))\n } else {\n resolve(output.trim())\n }\n })\n\n child.on('error', reject)\n })\n}\n\nexport function copyDirectory(src: string, dest: string, replacements?: Map<string, string>) {\n if (!fs.existsSync(dest)) {\n fs.mkdirSync(dest, { recursive: true })\n }\n\n const entries = fs.readdirSync(src, { withFileTypes: true })\n\n for (const entry of entries) {\n const srcPath = path.join(src, entry.name)\n const destPath = path.join(dest, entry.name)\n\n if (entry.isDirectory()) {\n if (entry.name === 'node_modules' || entry.name === 'dist') {\n continue\n }\n copyDirectory(srcPath, destPath, replacements)\n } else {\n let content = fs.readFileSync(srcPath, 'utf-8')\n\n if (\n replacements &&\n (entry.name === 'package.json' ||\n entry.name.endsWith('.ts') ||\n entry.name.endsWith('.js'))\n ) {\n for (const [search, replace] of replacements) {\n content = content.replace(new RegExp(search, 'g'), replace)\n }\n }\n\n fs.writeFileSync(destPath, content)\n }\n }\n}\n\nexport function getLatestSdkTag(): string | null {\n const tagsResult = spawn.sync(\n 'git',\n ['ls-remote', '--tags', 'https://github.com/towns-protocol/towns.git', 'sdk-*'],\n { encoding: 'utf8' },\n )\n\n if (tagsResult.status !== 0 || !tagsResult.stdout) return null\n\n const tags = tagsResult.stdout\n .split('\\n')\n .filter(Boolean)\n .map((line) => {\n const [_hash, ref] = line.split('\\t')\n const tag = ref.replace('refs/tags/', '').replace(/\\^{}$/, '')\n\n // Extract version numbers from tags like sdk-hash-1.2.3\n const match = tag.match(/^sdk-[0-9a-f]+-(\\d+)\\.(\\d+)\\.(\\d+)$/)\n if (!match) return null\n\n return {\n tag,\n version: [parseInt(match[1]), parseInt(match[2]), parseInt(match[3])],\n }\n })\n .filter(\n (item): item is { tag: string; version: number[] } =>\n item !== null && Array.isArray(item.version) && item.version.length === 3,\n )\n .sort((a, b) => {\n // Compare version numbers\n for (let i = 0; i < 3; i++) {\n if (a.version[i] !== b.version[i]) {\n return b.version[i] - a.version[i]\n }\n }\n return 0\n })\n\n return tags.length > 0 ? tags[0].tag : null\n}\n\nexport async function cloneTemplate(packagePath: string, targetDir: string): Promise<boolean> {\n console.log(picocolors.blue('Cloning template from GitHub...'))\n\n const tempDir = `${targetDir}-temp`\n const fullTemplatePath = `packages/examples/${packagePath}`\n\n // Get latest SDK tag\n const latestSdkTag = getLatestSdkTag()\n if (!latestSdkTag) {\n console.error(picocolors.red('Failed to get latest SDK tag.'))\n return false\n }\n\n // Clone with minimal data to a temporary directory\n const cloneResult = spawn.sync(\n 'git',\n [\n 'clone',\n '--no-checkout',\n '--depth',\n '1',\n '--sparse',\n '--branch',\n latestSdkTag,\n 'https://github.com/towns-protocol/towns.git',\n tempDir,\n ],\n { stdio: 'pipe' },\n )\n if (cloneResult.status !== 0) return false\n\n // Set up sparse checkout for the specific template\n const sparseResult = spawn.sync('git', ['sparse-checkout', 'set', fullTemplatePath], {\n stdio: 'pipe',\n cwd: tempDir,\n })\n if (sparseResult.status !== 0) {\n fs.rmSync(tempDir, { recursive: true, force: true })\n return false\n }\n\n // Checkout the content\n const checkoutResult = spawn.sync('git', ['checkout'], {\n stdio: 'pipe',\n cwd: tempDir,\n })\n if (checkoutResult.status !== 0) {\n fs.rmSync(tempDir, { recursive: true, force: true })\n return false\n }\n\n // Verify template directory exists\n const sourceDir = path.join(tempDir, fullTemplatePath)\n if (!fs.existsSync(sourceDir)) {\n console.error(picocolors.red(`\\nTemplate directory not found at ${sourceDir}`))\n fs.rmSync(tempDir, { recursive: true, force: true })\n return false\n }\n\n // Copy template contents to target directory\n fs.mkdirSync(targetDir, { recursive: true })\n // Use filter to ensure all files (including hidden) are copied\n fs.cpSync(sourceDir, targetDir, {\n recursive: true,\n filter: () => {\n // Copy all files, including hidden ones\n return true\n },\n })\n\n // Clean up temporary directory\n fs.rmSync(tempDir, { recursive: true, force: true })\n\n console.log(picocolors.green('✓'), 'Template cloned successfully!')\n return true\n}\n\nexport function applyReplacements(targetDir: string, replacements: Map<string, string>) {\n function processDirectory(dir: string) {\n const entries = fs.readdirSync(dir, { withFileTypes: true })\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name)\n\n if (entry.isDirectory()) {\n if (entry.name === 'node_modules' || entry.name === 'dist') {\n continue\n }\n processDirectory(fullPath)\n } else {\n let content = fs.readFileSync(fullPath, 'utf-8')\n let modified = false\n\n if (\n entry.name === 'package.json' ||\n entry.name.endsWith('.ts') ||\n entry.name.endsWith('.js')\n ) {\n for (const [search, replace] of replacements) {\n const regex = new RegExp(search, 'g')\n if (regex.test(content)) {\n content = content.replace(regex, replace)\n modified = true\n }\n }\n\n if (modified) {\n fs.writeFileSync(fullPath, content)\n }\n }\n }\n }\n }\n\n processDirectory(targetDir)\n}\n\nexport function printSuccess(projectName: string, packageManager: string) {\n console.log(picocolors.green('✓'), 'Bot project created successfully!')\n console.log()\n console.log('Next steps:')\n console.log(picocolors.cyan(` cd ${projectName}`))\n console.log(picocolors.cyan(` ${getInstallCommand(packageManager)}`))\n console.log('Set up your environment variables:')\n console.log(picocolors.cyan(' cp .env.sample .env'))\n console.log(' Edit .env with your bot credentials')\n console.log('Start your bot:')\n console.log(picocolors.cyan(` ${getRunCommand(packageManager, 'dev')}`))\n}\n\nexport async function initializeGitRepository(targetDir: string): Promise<boolean> {\n try {\n await runCommand('git', ['init'], { cwd: targetDir, silent: true })\n await runCommand('git', ['add', '.'], { cwd: targetDir, silent: true })\n await runCommand('git', ['commit', '-m', 'feat: towns bot scaffolding'], {\n cwd: targetDir,\n silent: true,\n })\n return true\n } catch (error) {\n console.log(\n picocolors.yellow('⚠'),\n 'Failed to initialize git repository:',\n error instanceof Error ? error.message : 'Unknown error',\n )\n console.log(picocolors.yellow(' You can manually initialize git later with: git init'))\n return false\n }\n}\n","import fs from 'fs'\nimport path from 'path'\nimport { default as spawn } from 'cross-spawn'\nimport { green, red, yellow, cyan } from 'picocolors'\nimport * as jsonc from 'jsonc-parser'\nimport { getPackageManager, getInstallCommand, runCommand, type PackageJson } from './utils.js'\nimport type { UpdateArgs } from '../parser.js'\n\ninterface PackageVersions {\n [key: string]: string\n}\n\nexport async function update(_argv: UpdateArgs) {\n const packageJsonPath = path.join(process.cwd(), 'package.json')\n\n if (!fs.existsSync(packageJsonPath)) {\n console.error(red('Error: No package.json found in the current directory'))\n console.log(yellow('Please run this command from a Towns Protocol bot project directory'))\n process.exit(1)\n }\n\n const packageJson = jsonc.parse(fs.readFileSync(packageJsonPath, 'utf-8')) as PackageJson\n const dependencies = { ...packageJson.dependencies, ...packageJson.devDependencies }\n\n const townsPackages = Object.keys(dependencies).filter((pkg) =>\n pkg.startsWith('@towns-protocol/'),\n )\n\n if (townsPackages.length === 0) {\n console.log(yellow('No @towns-protocol packages found in this project'))\n process.exit(0)\n }\n\n console.log(cyan('Found Towns Protocol packages:'))\n townsPackages.forEach((pkg) => {\n console.log(` - ${pkg}@${dependencies[pkg]}`)\n })\n console.log()\n\n console.log(cyan('Fetching latest versions...'))\n const latestVersions: PackageVersions = {}\n\n for (const pkg of townsPackages) {\n try {\n const version = await getLatestVersion(pkg)\n latestVersions[pkg] = version\n console.log(green('✓'), `${pkg}: ${version}`)\n } catch {\n console.error(red('✗'), `Failed to fetch version for ${pkg}`)\n }\n }\n\n console.log()\n console.log(cyan('Updating package.json...'))\n\n const content = fs.readFileSync(packageJsonPath, 'utf-8')\n const edits: jsonc.Edit[] = []\n\n for (const [pkg, version] of Object.entries(latestVersions)) {\n const currentVersion = dependencies[pkg]\n if (currentVersion !== `^${version}`) {\n if (packageJson.dependencies?.[pkg]) {\n edits.push(...jsonc.modify(content, ['dependencies', pkg], `^${version}`, {}))\n }\n if (packageJson.devDependencies?.[pkg]) {\n edits.push(...jsonc.modify(content, ['devDependencies', pkg], `^${version}`, {}))\n }\n }\n }\n\n if (edits.length > 0) {\n const modifiedContent = jsonc.applyEdits(content, edits)\n fs.writeFileSync(packageJsonPath, modifiedContent)\n console.log(green('✓'), 'Updated package.json')\n\n const packageManager = getPackageManager()\n console.log()\n console.log(cyan(`Installing dependencies with ${packageManager}...`))\n\n try {\n await runCommand(packageManager, [\n getInstallCommand(packageManager).split(' ')[1] || 'install',\n ])\n console.log()\n console.log(green('✓'), 'Dependencies updated successfully!')\n } catch {\n console.error(red('Error:'), 'Failed to install dependencies')\n console.log(\n yellow('Please run'),\n cyan(getInstallCommand(packageManager)),\n yellow('manually'),\n )\n }\n } else {\n console.log(green('✓'), 'All packages are already up to date!')\n }\n}\n\nasync function getLatestVersion(packageName: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const child = spawn('npm', ['view', packageName, 'version'], {\n stdio: ['ignore', 'pipe', 'ignore'],\n })\n\n let output = ''\n child.stdout?.on('data', (data) => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n output += data.toString()\n })\n\n child.on('close', (code) => {\n if (code !== 0) {\n reject(new Error(`Failed to fetch version for ${packageName}`))\n } else {\n resolve(output.trim())\n }\n })\n\n child.on('error', reject)\n })\n}\n","import minimist from 'minimist'\n\n// Command-specific argument interfaces\nexport interface BaseArgs {\n _: string[]\n help?: boolean\n}\n\nexport interface InitArgs extends BaseArgs {\n template?: string\n}\n\nexport type UpdateArgs = BaseArgs\n\nexport type CommandArgs = InitArgs | UpdateArgs\n\n// Command configurations for minimist\nconst COMMAND_CONFIGS: Record<string, minimist.Opts> = {\n init: {\n string: ['template'],\n alias: { t: 'template' },\n default: { template: 'quickstart' },\n },\n update: {\n // No special config needed\n },\n}\n\n/**\n * Parse command line arguments with command-specific configurations\n *\n * This function does a two-pass parse:\n * 1. First parse to identify the command\n * 2. Second parse with command-specific configuration\n *\n * This allows each command to have its own argument parsing rules,\n * preventing issues like hex addresses being converted to numbers.\n */\nexport function parseArgs(args: string[]): CommandArgs {\n // First, do a minimal parse to get the command\n const initial = minimist(args, {\n stopEarly: true,\n boolean: ['help'],\n alias: { h: 'help' },\n })\n\n const command = initial._[0]\n\n // If no command or help requested, return early\n if (!command || initial.help) {\n return initial as BaseArgs\n }\n\n // Get command-specific configuration\n const commandConfig = COMMAND_CONFIGS[command] || {}\n\n // Re-parse with command-specific configuration\n const booleanOptions = Array.isArray(commandConfig.boolean)\n ? ['help', ...commandConfig.boolean]\n : ['help']\n const parsed = minimist(args, {\n ...commandConfig,\n boolean: booleanOptions,\n alias: {\n ...commandConfig.alias,\n h: 'help',\n },\n })\n\n return parsed as CommandArgs\n}\n\n/**\n * Type guard functions for command-specific args\n */\nexport function isInitArgs(args: CommandArgs): args is InitArgs {\n return args._[0] === 'init'\n}\n\nexport function isUpdateArgs(args: CommandArgs): args is UpdateArgs {\n return args._[0] === 'update'\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,qBAAyC;;;ACAzC,IAAAC,MAAoB;AACpB,IAAAC,QAAsB;AACtB,qBAAmC;AACnC,IAAAC,qBAAkC;AAClC,YAAuB;;;ACJvB,SAAoB;AACpB,WAAsB;AACtB,yBAAiC;AACjC,wBAAuB;AAQhB,IAAM,oBAAoB,MAAM;AACnC,MAAI,QAAQ,IAAI,uBAAuB;AACnC,UAAM,QAAQ,QAAQ,IAAI;AAC1B,QAAI,MAAM,WAAW,MAAM,EAAG,QAAO;AACrC,QAAI,MAAM,WAAW,KAAK,EAAG,QAAO;AACpC,QAAI,MAAM,WAAW,MAAM,EAAG,QAAO;AACrC,QAAI,MAAM,WAAW,KAAK,EAAG,QAAO;AAAA,EACxC;AAEA,SAAO;AACX;AAEO,SAAS,kBAAkB,gBAAgC;AAC9D,UAAQ,gBAAgB;AAAA,IACpB,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX;AACI,aAAO;AAAA,EACf;AACJ;AAEO,SAAS,cAAc,gBAAwB,QAAwB;AAC1E,UAAQ,gBAAgB;AAAA,IACpB,KAAK;AACD,aAAO,WAAW,MAAM;AAAA,IAC5B,KAAK;AACD,aAAO,QAAQ,MAAM;AAAA,IACzB,KAAK;AACD,aAAO,QAAQ,MAAM;AAAA,IACzB;AACI,aAAO,WAAW,MAAM;AAAA,EAChC;AACJ;AAEO,SAAS,WACZ,SACA,MACA,OAA2C,EAAE,KAAK,QAAW,QAAQ,MAAM,GAC9D;AACb,SAAO,IAAI,QAAQ,CAACC,UAAS,WAAW;AACpC,UAAM,YAAQ,mBAAAC,SAAM,SAAS,MAAM;AAAA,MAC/B,OAAO,KAAK,SAAS,WAAW;AAAA,MAChC,KAAK,KAAK;AAAA,MACV,OAAO,QAAQ,aAAa;AAAA,IAChC,CAAC;AAED,UAAM,GAAG,SAAS,CAAC,SAAS;AACxB,UAAI,SAAS,GAAG;AACZ,eAAO,IAAI,MAAM,iCAAiC,IAAI,EAAE,CAAC;AAAA,MAC7D,OAAO;AACH,QAAAD,SAAQ;AAAA,MACZ;AAAA,IACJ,CAAC;AAED,UAAM,GAAG,SAAS,MAAM;AAAA,EAC5B,CAAC;AACL;AAEA,eAAsB,gCAAiD;AACnE,SAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACpC,UAAM,YAAQ,mBAAAC,SAAM,OAAO,CAAC,QAAQ,uBAAuB,SAAS,GAAG;AAAA,MACnE,OAAO,CAAC,UAAU,QAAQ,QAAQ;AAAA,IACtC,CAAC;AAED,QAAI,SAAS;AACb,UAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS;AAE/B,gBAAU,KAAK,SAAS;AAAA,IAC5B,CAAC;AAED,UAAM,GAAG,SAAS,CAAC,SAAS;AACxB,UAAI,SAAS,GAAG;AACZ,eAAO,IAAI,MAAM,oDAAoD,CAAC;AAAA,MAC1E,OAAO;AACH,QAAAD,SAAQ,OAAO,KAAK,CAAC;AAAA,MACzB;AAAA,IACJ,CAAC;AAED,UAAM,GAAG,SAAS,MAAM;AAAA,EAC5B,CAAC;AACL;AAqCO,SAAS,kBAAiC;AAC7C,QAAM,aAAa,mBAAAE,QAAM;AAAA,IACrB;AAAA,IACA,CAAC,aAAa,UAAU,+CAA+C,OAAO;AAAA,IAC9E,EAAE,UAAU,OAAO;AAAA,EACvB;AAEA,MAAI,WAAW,WAAW,KAAK,CAAC,WAAW,OAAQ,QAAO;AAE1D,QAAM,OAAO,WAAW,OACnB,MAAM,IAAI,EACV,OAAO,OAAO,EACd,IAAI,CAAC,SAAS;AACX,UAAM,CAAC,OAAO,GAAG,IAAI,KAAK,MAAM,GAAI;AACpC,UAAM,MAAM,IAAI,QAAQ,cAAc,EAAE,EAAE,QAAQ,SAAS,EAAE;AAG7D,UAAM,QAAQ,IAAI,MAAM,qCAAqC;AAC7D,QAAI,CAAC,MAAO,QAAO;AAEnB,WAAO;AAAA,MACH;AAAA,MACA,SAAS,CAAC,SAAS,MAAM,CAAC,CAAC,GAAG,SAAS,MAAM,CAAC,CAAC,GAAG,SAAS,MAAM,CAAC,CAAC,CAAC;AAAA,IACxE;AAAA,EACJ,CAAC,EACA;AAAA,IACG,CAAC,SACG,SAAS,QAAQ,MAAM,QAAQ,KAAK,OAAO,KAAK,KAAK,QAAQ,WAAW;AAAA,EAChF,EACC,KAAK,CAAC,GAAG,MAAM;AAEZ,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AACxB,UAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG;AAC/B,eAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;AAAA,MACrC;AAAA,IACJ;AACA,WAAO;AAAA,EACX,CAAC;AAEL,SAAO,KAAK,SAAS,IAAI,KAAK,CAAC,EAAE,MAAM;AAC3C;AAEA,eAAsB,cAAc,aAAqB,WAAqC;AAC1F,UAAQ,IAAI,kBAAAC,QAAW,KAAK,iCAAiC,CAAC;AAE9D,QAAM,UAAU,GAAG,SAAS;AAC5B,QAAM,mBAAmB,qBAAqB,WAAW;AAGzD,QAAM,eAAe,gBAAgB;AACrC,MAAI,CAAC,cAAc;AACf,YAAQ,MAAM,kBAAAA,QAAW,IAAI,+BAA+B,CAAC;AAC7D,WAAO;AAAA,EACX;AAGA,QAAM,cAAc,mBAAAD,QAAM;AAAA,IACtB;AAAA,IACA;AAAA,MACI;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACJ;AAAA,IACA,EAAE,OAAO,OAAO;AAAA,EACpB;AACA,MAAI,YAAY,WAAW,EAAG,QAAO;AAGrC,QAAM,eAAe,mBAAAA,QAAM,KAAK,OAAO,CAAC,mBAAmB,OAAO,gBAAgB,GAAG;AAAA,IACjF,OAAO;AAAA,IACP,KAAK;AAAA,EACT,CAAC;AACD,MAAI,aAAa,WAAW,GAAG;AAC3B,IAAG,UAAO,SAAS,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AACnD,WAAO;AAAA,EACX;AAGA,QAAM,iBAAiB,mBAAAA,QAAM,KAAK,OAAO,CAAC,UAAU,GAAG;AAAA,IACnD,OAAO;AAAA,IACP,KAAK;AAAA,EACT,CAAC;AACD,MAAI,eAAe,WAAW,GAAG;AAC7B,IAAG,UAAO,SAAS,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AACnD,WAAO;AAAA,EACX;AAGA,QAAM,YAAiB,UAAK,SAAS,gBAAgB;AACrD,MAAI,CAAI,cAAW,SAAS,GAAG;AAC3B,YAAQ,MAAM,kBAAAC,QAAW,IAAI;AAAA,kCAAqC,SAAS,EAAE,CAAC;AAC9E,IAAG,UAAO,SAAS,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AACnD,WAAO;AAAA,EACX;AAGA,EAAG,aAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAE3C,EAAG,UAAO,WAAW,WAAW;AAAA,IAC5B,WAAW;AAAA,IACX,QAAQ,MAAM;AAEV,aAAO;AAAA,IACX;AAAA,EACJ,CAAC;AAGD,EAAG,UAAO,SAAS,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAEnD,UAAQ,IAAI,kBAAAA,QAAW,MAAM,QAAG,GAAG,+BAA+B;AAClE,SAAO;AACX;AAEO,SAAS,kBAAkB,WAAmB,cAAmC;AACpF,WAAS,iBAAiB,KAAa;AACnC,UAAM,UAAa,eAAY,KAAK,EAAE,eAAe,KAAK,CAAC;AAE3D,eAAW,SAAS,SAAS;AACzB,YAAM,WAAgB,UAAK,KAAK,MAAM,IAAI;AAE1C,UAAI,MAAM,YAAY,GAAG;AACrB,YAAI,MAAM,SAAS,kBAAkB,MAAM,SAAS,QAAQ;AACxD;AAAA,QACJ;AACA,yBAAiB,QAAQ;AAAA,MAC7B,OAAO;AACH,YAAI,UAAa,gBAAa,UAAU,OAAO;AAC/C,YAAI,WAAW;AAEf,YACI,MAAM,SAAS,kBACf,MAAM,KAAK,SAAS,KAAK,KACzB,MAAM,KAAK,SAAS,KAAK,GAC3B;AACE,qBAAW,CAAC,QAAQ,OAAO,KAAK,cAAc;AAC1C,kBAAM,QAAQ,IAAI,OAAO,QAAQ,GAAG;AACpC,gBAAI,MAAM,KAAK,OAAO,GAAG;AACrB,wBAAU,QAAQ,QAAQ,OAAO,OAAO;AACxC,yBAAW;AAAA,YACf;AAAA,UACJ;AAEA,cAAI,UAAU;AACV,YAAG,iBAAc,UAAU,OAAO;AAAA,UACtC;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAEA,mBAAiB,SAAS;AAC9B;AAEO,SAAS,aAAa,aAAqB,gBAAwB;AACtE,UAAQ,IAAI,kBAAAA,QAAW,MAAM,QAAG,GAAG,mCAAmC;AACtE,UAAQ,IAAI;AACZ,UAAQ,IAAI,aAAa;AACzB,UAAQ,IAAI,kBAAAA,QAAW,KAAK,QAAQ,WAAW,EAAE,CAAC;AAClD,UAAQ,IAAI,kBAAAA,QAAW,KAAK,KAAK,kBAAkB,cAAc,CAAC,EAAE,CAAC;AACrE,UAAQ,IAAI,oCAAoC;AAChD,UAAQ,IAAI,kBAAAA,QAAW,KAAK,uBAAuB,CAAC;AACpD,UAAQ,IAAI,uCAAuC;AACnD,UAAQ,IAAI,iBAAiB;AAC7B,UAAQ,IAAI,kBAAAA,QAAW,KAAK,KAAK,cAAc,gBAAgB,KAAK,CAAC,EAAE,CAAC;AAC5E;AAEA,eAAsB,wBAAwB,WAAqC;AAC/E,MAAI;AACA,UAAM,WAAW,OAAO,CAAC,MAAM,GAAG,EAAE,KAAK,WAAW,QAAQ,KAAK,CAAC;AAClE,UAAM,WAAW,OAAO,CAAC,OAAO,GAAG,GAAG,EAAE,KAAK,WAAW,QAAQ,KAAK,CAAC;AACtE,UAAM,WAAW,OAAO,CAAC,UAAU,MAAM,6BAA6B,GAAG;AAAA,MACrE,KAAK;AAAA,MACL,QAAQ;AAAA,IACZ,CAAC;AACD,WAAO;AAAA,EACX,SAAS,OAAO;AACZ,YAAQ;AAAA,MACJ,kBAAAA,QAAW,OAAO,QAAG;AAAA,MACrB;AAAA,MACA,iBAAiB,QAAQ,MAAM,UAAU;AAAA,IAC7C;AACA,YAAQ,IAAI,kBAAAA,QAAW,OAAO,wDAAwD,CAAC;AACvF,WAAO;AAAA,EACX;AACJ;;;ADjTO,IAAM,YAAY;AAAA,EACrB,YAAY;AAAA,IACR,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aAAa;AAAA,EACjB;AACJ;AAEA,eAAsB,KAAK,MAAgB;AACvC,QAAM,cAAc,KAAK,EAAE,CAAC;AAC5B,QAAM,WAAW,KAAK,YAAY;AAElC,MAAI,CAAC,aAAa;AACd,YAAQ,UAAM,wBAAI,sCAAsC,CAAC;AACzD,YAAQ,QAAI,2BAAO,sCAAsC,CAAC;AAC1D,YAAQ,KAAK,CAAC;AAAA,EAClB;AAEA,MAAI,CAAC,UAAU,QAAkC,GAAG;AAChD,YAAQ,UAAM,wBAAI,4BAA4B,QAAQ,GAAG,CAAC;AAC1D,YAAQ,QAAI,2BAAO,sBAAsB,GAAG,OAAO,KAAK,SAAS,EAAE,KAAK,IAAI,CAAC;AAC7E,YAAQ,KAAK,CAAC;AAAA,EAClB;AAEA,QAAM,YAAiB,cAAQ,QAAQ,IAAI,GAAG,WAAW;AAEzD,MAAO,eAAW,SAAS,GAAG;AAC1B,UAAM,EAAE,UAAU,IAAI,UAAM,eAAAC,SAAQ;AAAA,MAChC,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,aAAa,WAAW;AAAA,MACjC,SAAS;AAAA,IACb,CAAC;AAED,QAAI,CAAC,WAAW;AACZ,cAAQ,QAAI,2BAAO,qBAAqB,CAAC;AACzC,cAAQ,KAAK,CAAC;AAAA,IAClB;AAEA,IAAG,WAAO,WAAW,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EACzD;AAEA,UAAQ,QAAI,yBAAK,wCAAwC,SAAS,EAAE,CAAC;AACrE,MAAI,aAAa,cAAc;AAC3B,YAAQ,QAAI,yBAAK,mBAAmB,UAAU,QAAkC,EAAE,IAAI,EAAE,CAAC;AAAA,EAC7F;AAEA,QAAM,iBAAiB,kBAAkB;AACzC,QAAM,mBAAmB,UAAU,QAAkC;AAErE,MAAI;AAEA,UAAM,UAAU,MAAM,cAAc,iBAAiB,aAAa,SAAS;AAC3E,QAAI,CAAC,SAAS;AACV,cAAQ,UAAM,wBAAI,0BAA0B,CAAC;AAC7C,cAAQ,KAAK,CAAC;AAAA,IAClB;AACA,UAAM,gBAAgB,MAAM,8BAA8B;AAE1D,UAAM,eAAe,oBAAI,IAAI;AAAA,MACzB,CAAC,iBAAiB,IAAI,aAAa,EAAE;AAAA,MACrC,CAAC,iBAAiB,IAAI,aAAa,EAAE;AAAA,IACzC,CAAC;AAGD,sBAAkB,WAAW,YAAY;AAEzC,UAAM,kBAAuB,WAAK,WAAW,cAAc;AAC3D,QAAO,eAAW,eAAe,GAAG;AAChC,YAAM,UAAa,iBAAa,iBAAiB,OAAO;AACxD,YAAM,QAAQ;AAAA,QACJ,aAAO,SAAS,CAAC,MAAM,GAAG,aAAa,CAAC,CAAC;AAAA,QACzC,aAAO,SAAS,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;AAAA,MAClD;AAEA,UAAI,kBAAwB,iBAAW,SAAS,MAAM,KAAK,CAAC;AAE5D,YAAM,SAAe,YAAM,eAAe;AAC1C,aAAO,OAAO;AAEd,wBAAkB,KAAK,UAAU,QAAQ,MAAM,CAAC;AAChD,MAAG,kBAAc,iBAAiB,eAAe;AAAA,IACrD;AACA,UAAM,wBAAwB,SAAS;AACvC,iBAAa,aAAa,cAAc;AAAA,EAC5C,SAAS,OAAO;AACZ,YAAQ,UAAM,wBAAI,QAAQ,GAAG,iBAAiB,QAAQ,MAAM,UAAU,KAAK;AAC3E,YAAQ,UAAM,wBAAI,+BAA+B,SAAS,iBAAiB,CAAC;AAC5E,YAAQ,KAAK,CAAC;AAAA,EAClB;AACJ;;;AE3GA,gBAAe;AACf,kBAAiB;AACjB,IAAAC,sBAAiC;AACjC,IAAAC,qBAAyC;AACzC,IAAAC,SAAuB;AAQvB,eAAsB,OAAO,OAAmB;AAC5C,QAAM,kBAAkB,YAAAC,QAAK,KAAK,QAAQ,IAAI,GAAG,cAAc;AAE/D,MAAI,CAAC,UAAAC,QAAG,WAAW,eAAe,GAAG;AACjC,YAAQ,UAAM,wBAAI,uDAAuD,CAAC;AAC1E,YAAQ,QAAI,2BAAO,qEAAqE,CAAC;AACzF,YAAQ,KAAK,CAAC;AAAA,EAClB;AAEA,QAAM,cAAoB,aAAM,UAAAA,QAAG,aAAa,iBAAiB,OAAO,CAAC;AACzE,QAAM,eAAe,EAAE,GAAG,YAAY,cAAc,GAAG,YAAY,gBAAgB;AAEnF,QAAM,gBAAgB,OAAO,KAAK,YAAY,EAAE;AAAA,IAAO,CAAC,QACpD,IAAI,WAAW,kBAAkB;AAAA,EACrC;AAEA,MAAI,cAAc,WAAW,GAAG;AAC5B,YAAQ,QAAI,2BAAO,mDAAmD,CAAC;AACvE,YAAQ,KAAK,CAAC;AAAA,EAClB;AAEA,UAAQ,QAAI,yBAAK,gCAAgC,CAAC;AAClD,gBAAc,QAAQ,CAAC,QAAQ;AAC3B,YAAQ,IAAI,OAAO,GAAG,IAAI,aAAa,GAAG,CAAC,EAAE;AAAA,EACjD,CAAC;AACD,UAAQ,IAAI;AAEZ,UAAQ,QAAI,yBAAK,6BAA6B,CAAC;AAC/C,QAAM,iBAAkC,CAAC;AAEzC,aAAW,OAAO,eAAe;AAC7B,QAAI;AACA,YAAM,UAAU,MAAM,iBAAiB,GAAG;AAC1C,qBAAe,GAAG,IAAI;AACtB,cAAQ,QAAI,0BAAM,QAAG,GAAG,GAAG,GAAG,KAAK,OAAO,EAAE;AAAA,IAChD,QAAQ;AACJ,cAAQ,UAAM,wBAAI,QAAG,GAAG,+BAA+B,GAAG,EAAE;AAAA,IAChE;AAAA,EACJ;AAEA,UAAQ,IAAI;AACZ,UAAQ,QAAI,yBAAK,0BAA0B,CAAC;AAE5C,QAAM,UAAU,UAAAA,QAAG,aAAa,iBAAiB,OAAO;AACxD,QAAM,QAAsB,CAAC;AAE7B,aAAW,CAAC,KAAK,OAAO,KAAK,OAAO,QAAQ,cAAc,GAAG;AACzD,UAAM,iBAAiB,aAAa,GAAG;AACvC,QAAI,mBAAmB,IAAI,OAAO,IAAI;AAClC,UAAI,YAAY,eAAe,GAAG,GAAG;AACjC,cAAM,KAAK,GAAS,cAAO,SAAS,CAAC,gBAAgB,GAAG,GAAG,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC;AAAA,MACjF;AACA,UAAI,YAAY,kBAAkB,GAAG,GAAG;AACpC,cAAM,KAAK,GAAS,cAAO,SAAS,CAAC,mBAAmB,GAAG,GAAG,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC;AAAA,MACpF;AAAA,IACJ;AAAA,EACJ;AAEA,MAAI,MAAM,SAAS,GAAG;AAClB,UAAM,kBAAwB,kBAAW,SAAS,KAAK;AACvD,cAAAA,QAAG,cAAc,iBAAiB,eAAe;AACjD,YAAQ,QAAI,0BAAM,QAAG,GAAG,sBAAsB;AAE9C,UAAM,iBAAiB,kBAAkB;AACzC,YAAQ,IAAI;AACZ,YAAQ,QAAI,yBAAK,gCAAgC,cAAc,KAAK,CAAC;AAErE,QAAI;AACA,YAAM,WAAW,gBAAgB;AAAA,QAC7B,kBAAkB,cAAc,EAAE,MAAM,GAAG,EAAE,CAAC,KAAK;AAAA,MACvD,CAAC;AACD,cAAQ,IAAI;AACZ,cAAQ,QAAI,0BAAM,QAAG,GAAG,oCAAoC;AAAA,IAChE,QAAQ;AACJ,cAAQ,UAAM,wBAAI,QAAQ,GAAG,gCAAgC;AAC7D,cAAQ;AAAA,YACJ,2BAAO,YAAY;AAAA,YACnB,yBAAK,kBAAkB,cAAc,CAAC;AAAA,YACtC,2BAAO,UAAU;AAAA,MACrB;AAAA,IACJ;AAAA,EACJ,OAAO;AACH,YAAQ,QAAI,0BAAM,QAAG,GAAG,sCAAsC;AAAA,EAClE;AACJ;AAEA,eAAe,iBAAiB,aAAsC;AAClE,SAAO,IAAI,QAAQ,CAACC,UAAS,WAAW;AACpC,UAAM,YAAQ,oBAAAC,SAAM,OAAO,CAAC,QAAQ,aAAa,SAAS,GAAG;AAAA,MACzD,OAAO,CAAC,UAAU,QAAQ,QAAQ;AAAA,IACtC,CAAC;AAED,QAAI,SAAS;AACb,UAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS;AAE/B,gBAAU,KAAK,SAAS;AAAA,IAC5B,CAAC;AAED,UAAM,GAAG,SAAS,CAAC,SAAS;AACxB,UAAI,SAAS,GAAG;AACZ,eAAO,IAAI,MAAM,+BAA+B,WAAW,EAAE,CAAC;AAAA,MAClE,OAAO;AACH,QAAAD,SAAQ,OAAO,KAAK,CAAC;AAAA,MACzB;AAAA,IACJ,CAAC;AAED,UAAM,GAAG,SAAS,MAAM;AAAA,EAC5B,CAAC;AACL;;;ACxHA,sBAAqB;AAiBrB,IAAM,kBAAiD;AAAA,EACnD,MAAM;AAAA,IACF,QAAQ,CAAC,UAAU;AAAA,IACnB,OAAO,EAAE,GAAG,WAAW;AAAA,IACvB,SAAS,EAAE,UAAU,aAAa;AAAA,EACtC;AAAA,EACA,QAAQ;AAAA;AAAA,EAER;AACJ;AAYO,SAAS,UAAU,MAA6B;AAEnD,QAAM,cAAU,gBAAAE,SAAS,MAAM;AAAA,IAC3B,WAAW;AAAA,IACX,SAAS,CAAC,MAAM;AAAA,IAChB,OAAO,EAAE,GAAG,OAAO;AAAA,EACvB,CAAC;AAED,QAAM,UAAU,QAAQ,EAAE,CAAC;AAG3B,MAAI,CAAC,WAAW,QAAQ,MAAM;AAC1B,WAAO;AAAA,EACX;AAGA,QAAM,gBAAgB,gBAAgB,OAAO,KAAK,CAAC;AAGnD,QAAM,iBAAiB,MAAM,QAAQ,cAAc,OAAO,IACpD,CAAC,QAAQ,GAAG,cAAc,OAAO,IACjC,CAAC,MAAM;AACb,QAAM,aAAS,gBAAAA,SAAS,MAAM;AAAA,IAC1B,GAAG;AAAA,IACH,SAAS;AAAA,IACT,OAAO;AAAA,MACH,GAAG,cAAc;AAAA,MACjB,GAAG;AAAA,IACP;AAAA,EACJ,CAAC;AAED,SAAO;AACX;AAKO,SAAS,WAAW,MAAqC;AAC5D,SAAO,KAAK,EAAE,CAAC,MAAM;AACzB;AAEO,SAAS,aAAa,MAAuC;AAChE,SAAO,KAAK,EAAE,CAAC,MAAM;AACzB;;;AJ5EA,eAAe,OAAO;AAClB,QAAM,OAAO,UAAU,QAAQ,KAAK,MAAM,CAAC,CAAC;AAC5C,QAAM,UAAU,KAAK,EAAE,CAAC;AAExB,MAAI,KAAK,QAAQ,CAAC,SAAS;AACvB,aAAS;AACT;AAAA,EACJ;AAEA,MAAI;AACA,YAAQ,SAAS;AAAA,MACb,KAAK;AACD,YAAI,WAAW,IAAI,GAAG;AAClB,gBAAM,KAAK,IAAI;AAAA,QACnB;AACA;AAAA,MACJ,KAAK;AACD,YAAI,aAAa,IAAI,GAAG;AACpB,gBAAM,OAAO,IAAI;AAAA,QACrB;AACA;AAAA,MACJ;AACI,gBAAQ,UAAM,wBAAI,oBAAoB,OAAO,EAAE,CAAC;AAChD,iBAAS;AACT,gBAAQ,KAAK,CAAC;AAAA,IACtB;AAAA,EACJ,SAAS,OAAO;AACZ,YAAQ,UAAM,wBAAI,QAAQ,GAAG,iBAAiB,QAAQ,MAAM,UAAU,KAAK;AAC3E,YAAQ,KAAK,CAAC;AAAA,EAClB;AACJ;AAEA,SAAS,WAAW;AAChB,UAAQ,IAAI;AAAA,MACd,yBAAK,WAAW,CAAC;AAAA;AAAA,MAEjB,2BAAO,QAAQ,CAAC;AAAA;AAAA;AAAA,MAGhB,2BAAO,WAAW,CAAC;AAAA,QACjB,0BAAM,MAAM,CAAC;AAAA,QACb,0BAAM,QAAQ,CAAC;AAAA;AAAA,MAEjB,2BAAO,eAAe,CAAC;AAAA;AAAA,EAEvB,OAAO,QAAQ,SAAS,EACrB;AAAA,IACG,CAAC,CAAC,KAAK,QAAQ,MACX,gCAAgC,GAAG,MAAM,SAAS,WAAW;AAAA,EACrE,EACC,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA,MAGb,2BAAO,wBAAwB,CAAC;AAAA;AAAA;AAAA,MAGhC,2BAAO,0BAA0B,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,MAKlC,2BAAO,iBAAiB,CAAC;AAAA;AAAA;AAAA,MAGzB,2BAAO,WAAW,CAAC;AAAA,QACjB,yBAAK,4BAA4B,CAAC;AAAA;AAAA;AAAA;AAAA,QAIlC,yBAAK,uBAAuB,CAAC;AAAA;AAAA,CAEhC;AACD;AAEA,KAAK,EAAE,MAAM,CAAC,UAAU;AACpB,UAAQ,UAAM,wBAAI,mBAAmB,GAAG,KAAK;AAC7C,UAAQ,KAAK,CAAC;AAClB,CAAC;","names":["import_picocolors","fs","path","import_picocolors","resolve","spawn","spawn","picocolors","prompts","import_cross_spawn","import_picocolors","jsonc","path","fs","resolve","spawn","minimist"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import { green as
|
|
2
|
+
import { green as green2, red as red3, yellow as yellow3, cyan as cyan3 } from "picocolors";
|
|
3
3
|
|
|
4
4
|
// src/modules/init.ts
|
|
5
5
|
import * as fs2 from "node:fs";
|
|
@@ -405,188 +405,6 @@ async function getLatestVersion(packageName) {
|
|
|
405
405
|
});
|
|
406
406
|
}
|
|
407
407
|
|
|
408
|
-
// src/modules/update-commands.ts
|
|
409
|
-
import fs4 from "fs";
|
|
410
|
-
import path4 from "path";
|
|
411
|
-
import { pathToFileURL } from "url";
|
|
412
|
-
import * as dotenv from "dotenv";
|
|
413
|
-
import { ethers } from "ethers";
|
|
414
|
-
import { z } from "zod";
|
|
415
|
-
import { green as green2, red as red3, yellow as yellow3, cyan as cyan3 } from "picocolors";
|
|
416
|
-
import {
|
|
417
|
-
makeSignerContextFromBearerToken,
|
|
418
|
-
AppRegistryService,
|
|
419
|
-
parseAppPrivateData,
|
|
420
|
-
townsEnv
|
|
421
|
-
} from "@towns-protocol/sdk";
|
|
422
|
-
import { bin_fromHexString } from "@towns-protocol/utils";
|
|
423
|
-
import { SlashCommandSchema } from "@towns-protocol/proto";
|
|
424
|
-
import { create } from "@bufbuild/protobuf";
|
|
425
|
-
var slashCommandSchema = z.object({
|
|
426
|
-
name: z.string().min(1, "Command name is required").max(32, "Command name must be 32 characters or less").regex(
|
|
427
|
-
/^[a-zA-Z][a-zA-Z0-9_]*$/,
|
|
428
|
-
"Command name must start with a letter and contain only letters, numbers, and underscores"
|
|
429
|
-
),
|
|
430
|
-
description: z.string().min(1, "Command description is required").max(256, "Command description must be 256 characters or less")
|
|
431
|
-
}).transform((data) => create(SlashCommandSchema, data));
|
|
432
|
-
async function updateCommands(argv) {
|
|
433
|
-
const filePath = argv.file || argv._[1];
|
|
434
|
-
const bearerToken = argv.bearerToken || argv._[2];
|
|
435
|
-
const envFile = argv.envFile || ".env";
|
|
436
|
-
if (!filePath || !bearerToken) {
|
|
437
|
-
console.error(red3("Error: Missing required arguments"));
|
|
438
|
-
console.log();
|
|
439
|
-
console.log(yellow3("Usage:"));
|
|
440
|
-
console.log(" towns-bot update-commands <file-path> <bearer-token>");
|
|
441
|
-
console.log(cyan3(" OR"));
|
|
442
|
-
console.log(
|
|
443
|
-
" towns-bot update-commands --file <path> --bearerToken <token> [--envFile <path>]"
|
|
444
|
-
);
|
|
445
|
-
console.log();
|
|
446
|
-
console.log(yellow3("Arguments:"));
|
|
447
|
-
console.log(" file-path Path to file exporting slash commands");
|
|
448
|
-
console.log(" bearer-token Owner's bearer token for authentication");
|
|
449
|
-
console.log();
|
|
450
|
-
console.log(yellow3("Options:"));
|
|
451
|
-
console.log(" -f, --file <path> Path to commands file");
|
|
452
|
-
console.log(" -t, --bearerToken <token> Bearer token");
|
|
453
|
-
console.log(" -e, --envFile <path> Path to .env file (default: .env)");
|
|
454
|
-
console.log();
|
|
455
|
-
console.log(yellow3("Note:"));
|
|
456
|
-
console.log(
|
|
457
|
-
" The bot address and environment are read from APP_PRIVATE_DATA in your .env file"
|
|
458
|
-
);
|
|
459
|
-
process.exit(1);
|
|
460
|
-
}
|
|
461
|
-
const envPath = path4.resolve(envFile);
|
|
462
|
-
if (!fs4.existsSync(envPath)) {
|
|
463
|
-
console.error(red3(`Error: Environment file not found: ${envPath}`));
|
|
464
|
-
console.log(yellow3("Please ensure your .env file exists and contains APP_PRIVATE_DATA"));
|
|
465
|
-
process.exit(1);
|
|
466
|
-
}
|
|
467
|
-
dotenv.config({ path: envPath });
|
|
468
|
-
const appPrivateDataStr = process.env.APP_PRIVATE_DATA;
|
|
469
|
-
if (!appPrivateDataStr) {
|
|
470
|
-
console.error(red3("Error: APP_PRIVATE_DATA not found in environment variables"));
|
|
471
|
-
console.log(yellow3("Please ensure your .env file contains APP_PRIVATE_DATA"));
|
|
472
|
-
process.exit(1);
|
|
473
|
-
}
|
|
474
|
-
let privateKey;
|
|
475
|
-
let env;
|
|
476
|
-
try {
|
|
477
|
-
const appPrivateData = parseAppPrivateData(appPrivateDataStr);
|
|
478
|
-
privateKey = appPrivateData.privateKey;
|
|
479
|
-
env = appPrivateData.env;
|
|
480
|
-
} catch {
|
|
481
|
-
console.error(red3("Error: Failed to parse APP_PRIVATE_DATA"));
|
|
482
|
-
console.log(yellow3("Please ensure APP_PRIVATE_DATA is in the correct format"));
|
|
483
|
-
process.exit(1);
|
|
484
|
-
}
|
|
485
|
-
if (!env) {
|
|
486
|
-
console.error(red3("Error: Environment not found in APP_PRIVATE_DATA"));
|
|
487
|
-
process.exit(1);
|
|
488
|
-
}
|
|
489
|
-
let appClientAddress;
|
|
490
|
-
try {
|
|
491
|
-
const wallet = new ethers.Wallet(privateKey);
|
|
492
|
-
appClientAddress = wallet.address.toLowerCase();
|
|
493
|
-
} catch {
|
|
494
|
-
console.error(red3("Error: Failed to derive address from private key"));
|
|
495
|
-
process.exit(1);
|
|
496
|
-
}
|
|
497
|
-
try {
|
|
498
|
-
const resolvedPath = path4.resolve(filePath);
|
|
499
|
-
if (!fs4.existsSync(resolvedPath)) {
|
|
500
|
-
throw new Error(`File not found: ${resolvedPath}`);
|
|
501
|
-
}
|
|
502
|
-
let commands = [];
|
|
503
|
-
const fileUrl = pathToFileURL(resolvedPath).href;
|
|
504
|
-
try {
|
|
505
|
-
const module = await import(fileUrl);
|
|
506
|
-
commands = module.default || module.commands;
|
|
507
|
-
if (!commands) {
|
|
508
|
-
throw new Error('No default export or "commands" export found in file');
|
|
509
|
-
}
|
|
510
|
-
} catch (error) {
|
|
511
|
-
throw new Error(
|
|
512
|
-
`Failed to import commands file: ${error instanceof Error ? error.message : String(error)}`
|
|
513
|
-
);
|
|
514
|
-
}
|
|
515
|
-
try {
|
|
516
|
-
const validatedCommands = z.array(slashCommandSchema).parse(commands);
|
|
517
|
-
commands = validatedCommands;
|
|
518
|
-
} catch (zodError) {
|
|
519
|
-
if (zodError instanceof z.ZodError) {
|
|
520
|
-
const errors = zodError.errors.map((err) => {
|
|
521
|
-
const path5 = err.path.length > 0 ? `[${err.path.join(".")}]` : "";
|
|
522
|
-
return ` ${path5} ${err.message}`;
|
|
523
|
-
}).join("\n");
|
|
524
|
-
throw new Error(`Invalid slash commands:
|
|
525
|
-
${errors}`);
|
|
526
|
-
}
|
|
527
|
-
throw zodError;
|
|
528
|
-
}
|
|
529
|
-
console.log(cyan3("Found"), green2(commands.length.toString()), cyan3("commands:"));
|
|
530
|
-
for (const cmd of commands) {
|
|
531
|
-
console.log(` /${green2(cmd.name)} - ${cmd.description}`);
|
|
532
|
-
}
|
|
533
|
-
try {
|
|
534
|
-
const signerContext = await makeSignerContextFromBearerToken(bearerToken);
|
|
535
|
-
const appRegistryUrl = townsEnv().getAppRegistryUrl(env);
|
|
536
|
-
const { appRegistryRpcClient } = await AppRegistryService.authenticate(
|
|
537
|
-
signerContext,
|
|
538
|
-
appRegistryUrl
|
|
539
|
-
);
|
|
540
|
-
const appId = bin_fromHexString(appClientAddress);
|
|
541
|
-
const { metadata } = await appRegistryRpcClient.getAppMetadata({ appId });
|
|
542
|
-
if (!metadata) {
|
|
543
|
-
throw new Error("App not found or you do not have permission to modify it");
|
|
544
|
-
}
|
|
545
|
-
console.log();
|
|
546
|
-
await appRegistryRpcClient.updateAppMetadata({
|
|
547
|
-
appId,
|
|
548
|
-
updateMask: ["slash_commands"],
|
|
549
|
-
metadata: {
|
|
550
|
-
slashCommands: commands
|
|
551
|
-
}
|
|
552
|
-
});
|
|
553
|
-
console.log(cyan3("Bot:"), metadata.displayName);
|
|
554
|
-
console.log(green2("\u2713"), "Slash commands updated successfully!");
|
|
555
|
-
process.exit(0);
|
|
556
|
-
} catch (authError) {
|
|
557
|
-
const errorMessage = authError instanceof Error ? authError.message : String(authError);
|
|
558
|
-
if (errorMessage.includes("app was not found in registry")) {
|
|
559
|
-
throw new Error(
|
|
560
|
-
`Bot not found: ${appClientAddress}
|
|
561
|
-
|
|
562
|
-
Make sure the bot address is correct and the bot exists on the ${env} network.`
|
|
563
|
-
);
|
|
564
|
-
} else if (errorMessage.includes("permission") || errorMessage.includes("unauthorized")) {
|
|
565
|
-
throw new Error(
|
|
566
|
-
`Permission denied: You don't have permission to modify this bot.
|
|
567
|
-
|
|
568
|
-
Make sure the bearer token belongs to the bot owner.`
|
|
569
|
-
);
|
|
570
|
-
} else if (errorMessage.includes("invalid") || errorMessage.includes("malformed")) {
|
|
571
|
-
throw new Error(
|
|
572
|
-
`Invalid bearer token format.
|
|
573
|
-
|
|
574
|
-
Please check that the bearer token is correctly formatted.`
|
|
575
|
-
);
|
|
576
|
-
} else {
|
|
577
|
-
throw new Error(
|
|
578
|
-
`Failed to update commands: ${errorMessage}
|
|
579
|
-
|
|
580
|
-
Please check your bearer token and bot address.`
|
|
581
|
-
);
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
} catch (error) {
|
|
585
|
-
console.error(red3("Error:"), error instanceof Error ? error.message : error);
|
|
586
|
-
process.exit(1);
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
|
|
590
408
|
// src/parser.ts
|
|
591
409
|
import minimist from "minimist";
|
|
592
410
|
var COMMAND_CONFIGS = {
|
|
@@ -597,20 +415,6 @@ var COMMAND_CONFIGS = {
|
|
|
597
415
|
},
|
|
598
416
|
update: {
|
|
599
417
|
// No special config needed
|
|
600
|
-
},
|
|
601
|
-
"list-commands": {
|
|
602
|
-
string: ["file"],
|
|
603
|
-
alias: { f: "file" }
|
|
604
|
-
},
|
|
605
|
-
"update-commands": {
|
|
606
|
-
// Force all positional args after command to be strings (prevents hex->number conversion)
|
|
607
|
-
string: ["file", "bearerToken", "envFile", "_"],
|
|
608
|
-
alias: {
|
|
609
|
-
f: "file",
|
|
610
|
-
t: "bearerToken",
|
|
611
|
-
e: "envFile"
|
|
612
|
-
},
|
|
613
|
-
default: { envFile: ".env" }
|
|
614
418
|
}
|
|
615
419
|
};
|
|
616
420
|
function parseArgs(args) {
|
|
@@ -641,9 +445,6 @@ function isInitArgs(args) {
|
|
|
641
445
|
function isUpdateArgs(args) {
|
|
642
446
|
return args._[0] === "update";
|
|
643
447
|
}
|
|
644
|
-
function isUpdateCommandsArgs(args) {
|
|
645
|
-
return args._[0] === "update-commands";
|
|
646
|
-
}
|
|
647
448
|
|
|
648
449
|
// src/index.ts
|
|
649
450
|
async function main() {
|
|
@@ -665,76 +466,56 @@ async function main() {
|
|
|
665
466
|
await update(args);
|
|
666
467
|
}
|
|
667
468
|
break;
|
|
668
|
-
case "update-commands":
|
|
669
|
-
if (isUpdateCommandsArgs(args)) {
|
|
670
|
-
await updateCommands(args);
|
|
671
|
-
}
|
|
672
|
-
break;
|
|
673
469
|
default:
|
|
674
|
-
console.error(
|
|
470
|
+
console.error(red3(`Unknown command: ${command}`));
|
|
675
471
|
showHelp();
|
|
676
472
|
process.exit(1);
|
|
677
473
|
}
|
|
678
474
|
} catch (error) {
|
|
679
|
-
console.error(
|
|
475
|
+
console.error(red3("Error:"), error instanceof Error ? error.message : error);
|
|
680
476
|
process.exit(1);
|
|
681
477
|
}
|
|
682
478
|
}
|
|
683
479
|
function showHelp() {
|
|
684
480
|
console.log(`
|
|
685
|
-
${
|
|
481
|
+
${cyan3("towns-bot")} - CLI for creating and managing Towns Protocol bot projects
|
|
686
482
|
|
|
687
|
-
${
|
|
483
|
+
${yellow3("Usage:")}
|
|
688
484
|
towns-bot <command> [options]
|
|
689
485
|
|
|
690
|
-
${
|
|
691
|
-
${
|
|
692
|
-
${
|
|
693
|
-
${green3("list-commands")} List slash commands from a file
|
|
694
|
-
${green3("update-commands")} Update slash commands for a bot
|
|
486
|
+
${yellow3("Commands:")}
|
|
487
|
+
${green2("init")} [project-name] Create a new bot project
|
|
488
|
+
${green2("update")} Update @towns-protocol dependencies to latest versions
|
|
695
489
|
|
|
696
|
-
${
|
|
490
|
+
${yellow3("Init Options:")}
|
|
697
491
|
-t, --template <name> Template to use:
|
|
698
492
|
${Object.entries(TEMPLATES).map(
|
|
699
493
|
([key, template]) => ` ${key} - ${template.description}`
|
|
700
494
|
).join("\n")}
|
|
701
495
|
Default: quickstart
|
|
702
496
|
|
|
703
|
-
${
|
|
497
|
+
${yellow3("List Commands Options:")}
|
|
704
498
|
-f, --file <path> Path to commands file
|
|
705
499
|
|
|
706
|
-
${
|
|
500
|
+
${yellow3("Update Commands Options:")}
|
|
707
501
|
-f, --file <path> Path to commands file
|
|
708
502
|
-t, --bearerToken <token> Bearer token for authentication
|
|
709
503
|
-e, --envFile <path> Path to .env file (default: .env)
|
|
710
504
|
|
|
711
|
-
${
|
|
505
|
+
${yellow3("Global Options:")}
|
|
712
506
|
-h, --help Show this help message
|
|
713
507
|
|
|
714
|
-
${
|
|
715
|
-
${
|
|
508
|
+
${yellow3("Examples:")}
|
|
509
|
+
${cyan3("# Create a new bot project")}
|
|
716
510
|
towns-bot init my-bot
|
|
717
511
|
towns-bot init my-ai-bot --template quickstart
|
|
718
512
|
|
|
719
|
-
${
|
|
513
|
+
${cyan3("# Update dependencies")}
|
|
720
514
|
towns-bot update
|
|
721
|
-
|
|
722
|
-
${cyan4("# List slash commands")}
|
|
723
|
-
towns-bot list-commands src/commands.ts
|
|
724
|
-
towns-bot list-commands --file src/commands.ts
|
|
725
|
-
|
|
726
|
-
${cyan4("# Update slash commands (positional arguments)")}
|
|
727
|
-
towns-bot update-commands commands.ts token123
|
|
728
|
-
|
|
729
|
-
${cyan4("# Update slash commands (named arguments)")}
|
|
730
|
-
towns-bot update-commands --file commands.ts --bearerToken token123
|
|
731
|
-
towns-bot update-commands -f commands.ts -t token123 -e custom.env
|
|
732
|
-
|
|
733
|
-
${cyan4("Note: Bot address and environment are read from APP_PRIVATE_DATA in .env")}
|
|
734
515
|
`);
|
|
735
516
|
}
|
|
736
517
|
main().catch((error) => {
|
|
737
|
-
console.error(
|
|
518
|
+
console.error(red3("Unexpected error:"), error);
|
|
738
519
|
process.exit(1);
|
|
739
520
|
});
|
|
740
521
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/modules/init.ts","../src/modules/utils.ts","../src/modules/update.ts","../src/modules/update-commands.ts","../src/parser.ts"],"sourcesContent":["import { green, red, yellow, cyan } from 'picocolors'\nimport { init, TEMPLATES, type Template } from './modules/init.js'\nimport { update } from './modules/update.js'\nimport { updateCommands } from './modules/update-commands.js'\nimport { parseArgs, isInitArgs, isUpdateArgs, isUpdateCommandsArgs } from './parser.js'\n\nasync function main() {\n const args = parseArgs(process.argv.slice(2))\n const command = args._[0]\n\n if (args.help || !command) {\n showHelp()\n return\n }\n\n try {\n switch (command) {\n case 'init':\n if (isInitArgs(args)) {\n await init(args)\n }\n break\n case 'update':\n if (isUpdateArgs(args)) {\n await update(args)\n }\n break\n case 'update-commands':\n if (isUpdateCommandsArgs(args)) {\n await updateCommands(args)\n }\n break\n default:\n console.error(red(`Unknown command: ${command}`))\n showHelp()\n process.exit(1)\n }\n } catch (error) {\n console.error(red('Error:'), error instanceof Error ? error.message : error)\n process.exit(1)\n }\n}\n\nfunction showHelp() {\n console.log(`\n${cyan('towns-bot')} - CLI for creating and managing Towns Protocol bot projects\n\n${yellow('Usage:')}\n towns-bot <command> [options]\n\n${yellow('Commands:')}\n ${green('init')} [project-name] Create a new bot project\n ${green('update')} Update @towns-protocol dependencies to latest versions\n ${green('list-commands')} List slash commands from a file\n ${green('update-commands')} Update slash commands for a bot\n\n${yellow('Init Options:')}\n -t, --template <name> Template to use:\n${Object.entries(TEMPLATES)\n .map(\n ([key, template]: [string, Template]) =>\n ` ${key} - ${template.description}`,\n )\n .join('\\n')}\n Default: quickstart\n\n${yellow('List Commands Options:')}\n -f, --file <path> Path to commands file\n\n${yellow('Update Commands Options:')}\n -f, --file <path> Path to commands file\n -t, --bearerToken <token> Bearer token for authentication\n -e, --envFile <path> Path to .env file (default: .env)\n\n${yellow('Global Options:')}\n -h, --help Show this help message\n\n${yellow('Examples:')}\n ${cyan('# Create a new bot project')}\n towns-bot init my-bot\n towns-bot init my-ai-bot --template quickstart\n\n ${cyan('# Update dependencies')}\n towns-bot update\n\n ${cyan('# List slash commands')}\n towns-bot list-commands src/commands.ts\n towns-bot list-commands --file src/commands.ts\n\n ${cyan('# Update slash commands (positional arguments)')}\n towns-bot update-commands commands.ts token123\n\n ${cyan('# Update slash commands (named arguments)')}\n towns-bot update-commands --file commands.ts --bearerToken token123\n towns-bot update-commands -f commands.ts -t token123 -e custom.env\n\n ${cyan('Note: Bot address and environment are read from APP_PRIVATE_DATA in .env')}\n`)\n}\n\nmain().catch((error) => {\n console.error(red('Unexpected error:'), error)\n process.exit(1)\n})\n","import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport { default as prompts } from 'prompts'\nimport { red, yellow, cyan } from 'picocolors'\nimport * as jsonc from 'jsonc-parser'\nimport {\n getPackageManager,\n getLatestTownsProtocolVersion,\n cloneTemplate,\n applyReplacements,\n printSuccess,\n initializeGitRepository,\n type PackageJson,\n} from './utils.js'\nimport type { InitArgs } from '../parser.js'\n\nexport type Template = (typeof TEMPLATES)[keyof typeof TEMPLATES]\nexport const TEMPLATES = {\n quickstart: {\n name: 'Bot Quickstart',\n description: 'Simple starter bot with basic commands',\n packagePath: 'bot-quickstart',\n },\n} as const\n\nexport async function init(argv: InitArgs) {\n const projectName = argv._[1]\n const template = argv.template || 'quickstart'\n\n if (!projectName) {\n console.error(red('Error: Please provide a project name'))\n console.log(yellow('Usage: towns-bot init <project-name>'))\n process.exit(1)\n }\n\n if (!TEMPLATES[template as keyof typeof TEMPLATES]) {\n console.error(red(`Error: Unknown template \"${template}\"`))\n console.log(yellow('Available templates:'), Object.keys(TEMPLATES).join(', '))\n process.exit(1)\n }\n\n const targetDir = path.resolve(process.cwd(), projectName)\n\n if (fs.existsSync(targetDir)) {\n const { overwrite } = await prompts({\n type: 'confirm',\n name: 'overwrite',\n message: `Directory ${projectName} already exists. Overwrite?`,\n initial: false,\n })\n\n if (!overwrite) {\n console.log(yellow('Operation cancelled'))\n process.exit(0)\n }\n\n fs.rmSync(targetDir, { recursive: true, force: true })\n }\n\n console.log(cyan(`Creating a new Towns Protocol bot in ${targetDir}`))\n if (template !== 'quickstart') {\n console.log(cyan(`Using template: ${TEMPLATES[template as keyof typeof TEMPLATES].name}`))\n }\n\n const packageManager = getPackageManager()\n const selectedTemplate = TEMPLATES[template as keyof typeof TEMPLATES]\n\n try {\n // Clone template from GitHub\n const success = await cloneTemplate(selectedTemplate.packagePath, targetDir)\n if (!success) {\n console.error(red('Failed to clone template'))\n process.exit(1)\n }\n const latestVersion = await getLatestTownsProtocolVersion()\n // Replace workspace dependencies in package.json and other files\n const replacements = new Map([\n ['workspace:\\\\^', `^${latestVersion}`],\n ['workspace:\\\\*', `^${latestVersion}`],\n ])\n\n // Apply replacements to all relevant files\n applyReplacements(targetDir, replacements)\n\n const packageJsonPath = path.join(targetDir, 'package.json')\n if (fs.existsSync(packageJsonPath)) {\n const content = fs.readFileSync(packageJsonPath, 'utf-8')\n const edits = [\n jsonc.modify(content, ['name'], projectName, {}),\n jsonc.modify(content, ['version'], '0.0.1', {}),\n ]\n\n let modifiedContent = jsonc.applyEdits(content, edits.flat())\n\n const parsed = jsonc.parse(modifiedContent) as PackageJson\n delete parsed.private\n\n modifiedContent = JSON.stringify(parsed, null, 2)\n fs.writeFileSync(packageJsonPath, modifiedContent)\n }\n await initializeGitRepository(targetDir)\n printSuccess(projectName, packageManager)\n } catch (error) {\n console.error(red('Error:'), error instanceof Error ? error.message : error)\n console.error(red(`Please delete the directory ${targetDir} and try again.`))\n process.exit(1)\n }\n}\n","import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport { default as spawn } from 'cross-spawn'\nimport picocolors from 'picocolors'\n\nexport type PackageJson = {\n private?: boolean\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n}\n\nexport const getPackageManager = () => {\n if (process.env.npm_config_user_agent) {\n const agent = process.env.npm_config_user_agent\n if (agent.startsWith('yarn')) return 'yarn'\n if (agent.startsWith('npm')) return 'npm'\n if (agent.startsWith('pnpm')) return 'pnpm'\n if (agent.startsWith('bun')) return 'bun'\n }\n // Default to npm if no user agent is found\n return 'npm'\n}\n\nexport function getInstallCommand(packageManager: string): string {\n switch (packageManager) {\n case 'bun':\n return 'bun install'\n case 'yarn':\n return 'yarn'\n case 'pnpm':\n return 'pnpm install'\n default:\n return 'npm install'\n }\n}\n\nexport function getRunCommand(packageManager: string, script: string): string {\n switch (packageManager) {\n case 'bun':\n return `bun run ${script}`\n case 'yarn':\n return `yarn ${script}`\n case 'pnpm':\n return `pnpm ${script}`\n default:\n return `npm run ${script}`\n }\n}\n\nexport function runCommand(\n command: string,\n args: string[],\n opts: { cwd?: string; silent?: boolean } = { cwd: undefined, silent: false },\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n stdio: opts.silent ? 'ignore' : 'inherit',\n cwd: opts.cwd,\n shell: process.platform === 'win32',\n })\n\n child.on('close', (code) => {\n if (code !== 0) {\n reject(new Error(`Command failed with exit code ${code}`))\n } else {\n resolve()\n }\n })\n\n child.on('error', reject)\n })\n}\n\nexport async function getLatestTownsProtocolVersion(): Promise<string> {\n return new Promise((resolve, reject) => {\n const child = spawn('npm', ['view', '@towns-protocol/bot', 'version'], {\n stdio: ['ignore', 'pipe', 'ignore'],\n })\n\n let output = ''\n child.stdout?.on('data', (data) => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n output += data.toString()\n })\n\n child.on('close', (code) => {\n if (code !== 0) {\n reject(new Error('Failed to fetch latest @towns-protocol/bot version'))\n } else {\n resolve(output.trim())\n }\n })\n\n child.on('error', reject)\n })\n}\n\nexport function copyDirectory(src: string, dest: string, replacements?: Map<string, string>) {\n if (!fs.existsSync(dest)) {\n fs.mkdirSync(dest, { recursive: true })\n }\n\n const entries = fs.readdirSync(src, { withFileTypes: true })\n\n for (const entry of entries) {\n const srcPath = path.join(src, entry.name)\n const destPath = path.join(dest, entry.name)\n\n if (entry.isDirectory()) {\n if (entry.name === 'node_modules' || entry.name === 'dist') {\n continue\n }\n copyDirectory(srcPath, destPath, replacements)\n } else {\n let content = fs.readFileSync(srcPath, 'utf-8')\n\n if (\n replacements &&\n (entry.name === 'package.json' ||\n entry.name.endsWith('.ts') ||\n entry.name.endsWith('.js'))\n ) {\n for (const [search, replace] of replacements) {\n content = content.replace(new RegExp(search, 'g'), replace)\n }\n }\n\n fs.writeFileSync(destPath, content)\n }\n }\n}\n\nexport function getLatestSdkTag(): string | null {\n const tagsResult = spawn.sync(\n 'git',\n ['ls-remote', '--tags', 'https://github.com/towns-protocol/towns.git', 'sdk-*'],\n { encoding: 'utf8' },\n )\n\n if (tagsResult.status !== 0 || !tagsResult.stdout) return null\n\n const tags = tagsResult.stdout\n .split('\\n')\n .filter(Boolean)\n .map((line) => {\n const [_hash, ref] = line.split('\\t')\n const tag = ref.replace('refs/tags/', '').replace(/\\^{}$/, '')\n\n // Extract version numbers from tags like sdk-hash-1.2.3\n const match = tag.match(/^sdk-[0-9a-f]+-(\\d+)\\.(\\d+)\\.(\\d+)$/)\n if (!match) return null\n\n return {\n tag,\n version: [parseInt(match[1]), parseInt(match[2]), parseInt(match[3])],\n }\n })\n .filter(\n (item): item is { tag: string; version: number[] } =>\n item !== null && Array.isArray(item.version) && item.version.length === 3,\n )\n .sort((a, b) => {\n // Compare version numbers\n for (let i = 0; i < 3; i++) {\n if (a.version[i] !== b.version[i]) {\n return b.version[i] - a.version[i]\n }\n }\n return 0\n })\n\n return tags.length > 0 ? tags[0].tag : null\n}\n\nexport async function cloneTemplate(packagePath: string, targetDir: string): Promise<boolean> {\n console.log(picocolors.blue('Cloning template from GitHub...'))\n\n const tempDir = `${targetDir}-temp`\n const fullTemplatePath = `packages/examples/${packagePath}`\n\n // Get latest SDK tag\n const latestSdkTag = getLatestSdkTag()\n if (!latestSdkTag) {\n console.error(picocolors.red('Failed to get latest SDK tag.'))\n return false\n }\n\n // Clone with minimal data to a temporary directory\n const cloneResult = spawn.sync(\n 'git',\n [\n 'clone',\n '--no-checkout',\n '--depth',\n '1',\n '--sparse',\n '--branch',\n latestSdkTag,\n 'https://github.com/towns-protocol/towns.git',\n tempDir,\n ],\n { stdio: 'pipe' },\n )\n if (cloneResult.status !== 0) return false\n\n // Set up sparse checkout for the specific template\n const sparseResult = spawn.sync('git', ['sparse-checkout', 'set', fullTemplatePath], {\n stdio: 'pipe',\n cwd: tempDir,\n })\n if (sparseResult.status !== 0) {\n fs.rmSync(tempDir, { recursive: true, force: true })\n return false\n }\n\n // Checkout the content\n const checkoutResult = spawn.sync('git', ['checkout'], {\n stdio: 'pipe',\n cwd: tempDir,\n })\n if (checkoutResult.status !== 0) {\n fs.rmSync(tempDir, { recursive: true, force: true })\n return false\n }\n\n // Verify template directory exists\n const sourceDir = path.join(tempDir, fullTemplatePath)\n if (!fs.existsSync(sourceDir)) {\n console.error(picocolors.red(`\\nTemplate directory not found at ${sourceDir}`))\n fs.rmSync(tempDir, { recursive: true, force: true })\n return false\n }\n\n // Copy template contents to target directory\n fs.mkdirSync(targetDir, { recursive: true })\n // Use filter to ensure all files (including hidden) are copied\n fs.cpSync(sourceDir, targetDir, {\n recursive: true,\n filter: () => {\n // Copy all files, including hidden ones\n return true\n },\n })\n\n // Clean up temporary directory\n fs.rmSync(tempDir, { recursive: true, force: true })\n\n console.log(picocolors.green('✓'), 'Template cloned successfully!')\n return true\n}\n\nexport function applyReplacements(targetDir: string, replacements: Map<string, string>) {\n function processDirectory(dir: string) {\n const entries = fs.readdirSync(dir, { withFileTypes: true })\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name)\n\n if (entry.isDirectory()) {\n if (entry.name === 'node_modules' || entry.name === 'dist') {\n continue\n }\n processDirectory(fullPath)\n } else {\n let content = fs.readFileSync(fullPath, 'utf-8')\n let modified = false\n\n if (\n entry.name === 'package.json' ||\n entry.name.endsWith('.ts') ||\n entry.name.endsWith('.js')\n ) {\n for (const [search, replace] of replacements) {\n const regex = new RegExp(search, 'g')\n if (regex.test(content)) {\n content = content.replace(regex, replace)\n modified = true\n }\n }\n\n if (modified) {\n fs.writeFileSync(fullPath, content)\n }\n }\n }\n }\n }\n\n processDirectory(targetDir)\n}\n\nexport function printSuccess(projectName: string, packageManager: string) {\n console.log(picocolors.green('✓'), 'Bot project created successfully!')\n console.log()\n console.log('Next steps:')\n console.log(picocolors.cyan(` cd ${projectName}`))\n console.log(picocolors.cyan(` ${getInstallCommand(packageManager)}`))\n console.log('Set up your environment variables:')\n console.log(picocolors.cyan(' cp .env.sample .env'))\n console.log(' Edit .env with your bot credentials')\n console.log('Start your bot:')\n console.log(picocolors.cyan(` ${getRunCommand(packageManager, 'dev')}`))\n}\n\nexport async function initializeGitRepository(targetDir: string): Promise<boolean> {\n try {\n await runCommand('git', ['init'], { cwd: targetDir, silent: true })\n await runCommand('git', ['add', '.'], { cwd: targetDir, silent: true })\n await runCommand('git', ['commit', '-m', 'feat: towns bot scaffolding'], {\n cwd: targetDir,\n silent: true,\n })\n return true\n } catch (error) {\n console.log(\n picocolors.yellow('⚠'),\n 'Failed to initialize git repository:',\n error instanceof Error ? error.message : 'Unknown error',\n )\n console.log(picocolors.yellow(' You can manually initialize git later with: git init'))\n return false\n }\n}\n","import fs from 'fs'\nimport path from 'path'\nimport { default as spawn } from 'cross-spawn'\nimport { green, red, yellow, cyan } from 'picocolors'\nimport * as jsonc from 'jsonc-parser'\nimport { getPackageManager, getInstallCommand, runCommand, type PackageJson } from './utils.js'\nimport type { UpdateArgs } from '../parser.js'\n\ninterface PackageVersions {\n [key: string]: string\n}\n\nexport async function update(_argv: UpdateArgs) {\n const packageJsonPath = path.join(process.cwd(), 'package.json')\n\n if (!fs.existsSync(packageJsonPath)) {\n console.error(red('Error: No package.json found in the current directory'))\n console.log(yellow('Please run this command from a Towns Protocol bot project directory'))\n process.exit(1)\n }\n\n const packageJson = jsonc.parse(fs.readFileSync(packageJsonPath, 'utf-8')) as PackageJson\n const dependencies = { ...packageJson.dependencies, ...packageJson.devDependencies }\n\n const townsPackages = Object.keys(dependencies).filter((pkg) =>\n pkg.startsWith('@towns-protocol/'),\n )\n\n if (townsPackages.length === 0) {\n console.log(yellow('No @towns-protocol packages found in this project'))\n process.exit(0)\n }\n\n console.log(cyan('Found Towns Protocol packages:'))\n townsPackages.forEach((pkg) => {\n console.log(` - ${pkg}@${dependencies[pkg]}`)\n })\n console.log()\n\n console.log(cyan('Fetching latest versions...'))\n const latestVersions: PackageVersions = {}\n\n for (const pkg of townsPackages) {\n try {\n const version = await getLatestVersion(pkg)\n latestVersions[pkg] = version\n console.log(green('✓'), `${pkg}: ${version}`)\n } catch {\n console.error(red('✗'), `Failed to fetch version for ${pkg}`)\n }\n }\n\n console.log()\n console.log(cyan('Updating package.json...'))\n\n const content = fs.readFileSync(packageJsonPath, 'utf-8')\n const edits: jsonc.Edit[] = []\n\n for (const [pkg, version] of Object.entries(latestVersions)) {\n const currentVersion = dependencies[pkg]\n if (currentVersion !== `^${version}`) {\n if (packageJson.dependencies?.[pkg]) {\n edits.push(...jsonc.modify(content, ['dependencies', pkg], `^${version}`, {}))\n }\n if (packageJson.devDependencies?.[pkg]) {\n edits.push(...jsonc.modify(content, ['devDependencies', pkg], `^${version}`, {}))\n }\n }\n }\n\n if (edits.length > 0) {\n const modifiedContent = jsonc.applyEdits(content, edits)\n fs.writeFileSync(packageJsonPath, modifiedContent)\n console.log(green('✓'), 'Updated package.json')\n\n const packageManager = getPackageManager()\n console.log()\n console.log(cyan(`Installing dependencies with ${packageManager}...`))\n\n try {\n await runCommand(packageManager, [\n getInstallCommand(packageManager).split(' ')[1] || 'install',\n ])\n console.log()\n console.log(green('✓'), 'Dependencies updated successfully!')\n } catch {\n console.error(red('Error:'), 'Failed to install dependencies')\n console.log(\n yellow('Please run'),\n cyan(getInstallCommand(packageManager)),\n yellow('manually'),\n )\n }\n } else {\n console.log(green('✓'), 'All packages are already up to date!')\n }\n}\n\nasync function getLatestVersion(packageName: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const child = spawn('npm', ['view', packageName, 'version'], {\n stdio: ['ignore', 'pipe', 'ignore'],\n })\n\n let output = ''\n child.stdout?.on('data', (data) => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n output += data.toString()\n })\n\n child.on('close', (code) => {\n if (code !== 0) {\n reject(new Error(`Failed to fetch version for ${packageName}`))\n } else {\n resolve(output.trim())\n }\n })\n\n child.on('error', reject)\n })\n}\n","import fs from 'fs'\nimport path from 'path'\nimport { pathToFileURL } from 'url'\nimport * as dotenv from 'dotenv'\nimport { ethers } from 'ethers'\nimport { z } from 'zod'\nimport { green, red, yellow, cyan } from 'picocolors'\nimport {\n makeSignerContextFromBearerToken,\n AppRegistryService,\n parseAppPrivateData,\n townsEnv,\n} from '@towns-protocol/sdk'\nimport { bin_fromHexString } from '@towns-protocol/utils'\nimport { SlashCommandSchema, type SlashCommand } from '@towns-protocol/proto'\nimport type { UpdateCommandsArgs } from '../parser.js'\nimport { create } from '@bufbuild/protobuf'\n\nconst slashCommandSchema = z\n .object({\n name: z\n .string()\n .min(1, 'Command name is required')\n .max(32, 'Command name must be 32 characters or less')\n .regex(\n /^[a-zA-Z][a-zA-Z0-9_]*$/,\n 'Command name must start with a letter and contain only letters, numbers, and underscores',\n ),\n description: z\n .string()\n .min(1, 'Command description is required')\n .max(256, 'Command description must be 256 characters or less'),\n })\n .transform((data) => create(SlashCommandSchema, data))\n\nexport async function updateCommands(argv: UpdateCommandsArgs) {\n const filePath = argv.file || argv._[1]\n const bearerToken = argv.bearerToken || argv._[2]\n const envFile = argv.envFile || '.env'\n\n if (!filePath || !bearerToken) {\n console.error(red('Error: Missing required arguments'))\n console.log()\n console.log(yellow('Usage:'))\n console.log(' towns-bot update-commands <file-path> <bearer-token>')\n console.log(cyan(' OR'))\n console.log(\n ' towns-bot update-commands --file <path> --bearerToken <token> [--envFile <path>]',\n )\n console.log()\n console.log(yellow('Arguments:'))\n console.log(' file-path Path to file exporting slash commands')\n console.log(\" bearer-token Owner's bearer token for authentication\")\n console.log()\n console.log(yellow('Options:'))\n console.log(' -f, --file <path> Path to commands file')\n console.log(' -t, --bearerToken <token> Bearer token')\n console.log(' -e, --envFile <path> Path to .env file (default: .env)')\n console.log()\n console.log(yellow('Note:'))\n console.log(\n ' The bot address and environment are read from APP_PRIVATE_DATA in your .env file',\n )\n process.exit(1)\n }\n\n const envPath = path.resolve(envFile)\n if (!fs.existsSync(envPath)) {\n console.error(red(`Error: Environment file not found: ${envPath}`))\n console.log(yellow('Please ensure your .env file exists and contains APP_PRIVATE_DATA'))\n process.exit(1)\n }\n\n dotenv.config({ path: envPath })\n\n const appPrivateDataStr = process.env.APP_PRIVATE_DATA\n if (!appPrivateDataStr) {\n console.error(red('Error: APP_PRIVATE_DATA not found in environment variables'))\n console.log(yellow('Please ensure your .env file contains APP_PRIVATE_DATA'))\n process.exit(1)\n }\n\n let privateKey: string\n let env: string | undefined\n try {\n const appPrivateData = parseAppPrivateData(appPrivateDataStr)\n privateKey = appPrivateData.privateKey\n env = appPrivateData.env\n } catch {\n console.error(red('Error: Failed to parse APP_PRIVATE_DATA'))\n console.log(yellow('Please ensure APP_PRIVATE_DATA is in the correct format'))\n process.exit(1)\n }\n\n if (!env) {\n // Old format isn't supported.\n console.error(red('Error: Environment not found in APP_PRIVATE_DATA'))\n process.exit(1)\n }\n\n // Derive app client address from private key\n let appClientAddress: string\n try {\n const wallet = new ethers.Wallet(privateKey)\n appClientAddress = wallet.address.toLowerCase()\n } catch {\n console.error(red('Error: Failed to derive address from private key'))\n process.exit(1)\n }\n\n try {\n const resolvedPath = path.resolve(filePath)\n if (!fs.existsSync(resolvedPath)) {\n throw new Error(`File not found: ${resolvedPath}`)\n }\n let commands: SlashCommand[] = []\n const fileUrl = pathToFileURL(resolvedPath).href\n try {\n const module = await import(fileUrl)\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n commands = module.default || module.commands\n if (!commands) {\n throw new Error('No default export or \"commands\" export found in file')\n }\n } catch (error) {\n throw new Error(\n `Failed to import commands file: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n\n try {\n const validatedCommands = z.array(slashCommandSchema).parse(commands)\n commands = validatedCommands\n } catch (zodError) {\n if (zodError instanceof z.ZodError) {\n const errors = zodError.errors\n .map((err) => {\n const path = err.path.length > 0 ? `[${err.path.join('.')}]` : ''\n return ` ${path} ${err.message}`\n })\n .join('\\n')\n throw new Error(`Invalid slash commands:\\n${errors}`)\n }\n throw zodError\n }\n\n console.log(cyan('Found'), green(commands.length.toString()), cyan('commands:'))\n for (const cmd of commands) {\n console.log(` /${green(cmd.name)} - ${cmd.description}`)\n }\n\n try {\n const signerContext = await makeSignerContextFromBearerToken(bearerToken)\n const appRegistryUrl = townsEnv().getAppRegistryUrl(env)\n const { appRegistryRpcClient } = await AppRegistryService.authenticate(\n signerContext,\n appRegistryUrl,\n )\n const appId = bin_fromHexString(appClientAddress)\n\n const { metadata } = await appRegistryRpcClient.getAppMetadata({ appId })\n if (!metadata) {\n throw new Error('App not found or you do not have permission to modify it')\n }\n\n console.log()\n await appRegistryRpcClient.updateAppMetadata({\n appId,\n updateMask: ['slash_commands'],\n metadata: {\n slashCommands: commands,\n },\n })\n\n console.log(cyan('Bot:'), metadata.displayName)\n console.log(green('✓'), 'Slash commands updated successfully!')\n process.exit(0)\n } catch (authError: unknown) {\n const errorMessage = authError instanceof Error ? authError.message : String(authError)\n\n if (errorMessage.includes('app was not found in registry')) {\n throw new Error(\n `Bot not found: ${appClientAddress}\\n\\nMake sure the bot address is correct and the bot exists on the ${env} network.`,\n )\n } else if (\n errorMessage.includes('permission') ||\n errorMessage.includes('unauthorized')\n ) {\n throw new Error(\n `Permission denied: You don't have permission to modify this bot.\\n\\nMake sure the bearer token belongs to the bot owner.`,\n )\n } else if (errorMessage.includes('invalid') || errorMessage.includes('malformed')) {\n throw new Error(\n `Invalid bearer token format.\\n\\nPlease check that the bearer token is correctly formatted.`,\n )\n } else {\n throw new Error(\n `Failed to update commands: ${errorMessage}\\n\\nPlease check your bearer token and bot address.`,\n )\n }\n }\n } catch (error) {\n console.error(red('Error:'), error instanceof Error ? error.message : error)\n process.exit(1)\n }\n}\n","import minimist from 'minimist'\n\n// Command-specific argument interfaces\nexport interface BaseArgs {\n _: string[]\n help?: boolean\n}\n\nexport interface InitArgs extends BaseArgs {\n template?: string\n}\n\nexport type UpdateArgs = BaseArgs\n\nexport interface UpdateCommandsArgs extends BaseArgs {\n file?: string\n bearerToken?: string\n envFile?: string\n}\n\nexport type CommandArgs = InitArgs | UpdateArgs | UpdateCommandsArgs\n\n// Command configurations for minimist\nconst COMMAND_CONFIGS: Record<string, minimist.Opts> = {\n init: {\n string: ['template'],\n alias: { t: 'template' },\n default: { template: 'quickstart' },\n },\n update: {\n // No special config needed\n },\n 'list-commands': {\n string: ['file'],\n alias: { f: 'file' },\n },\n 'update-commands': {\n // Force all positional args after command to be strings (prevents hex->number conversion)\n string: ['file', 'bearerToken', 'envFile', '_'],\n alias: {\n f: 'file',\n t: 'bearerToken',\n e: 'envFile',\n },\n default: { envFile: '.env' },\n },\n}\n\n/**\n * Parse command line arguments with command-specific configurations\n *\n * This function does a two-pass parse:\n * 1. First parse to identify the command\n * 2. Second parse with command-specific configuration\n *\n * This allows each command to have its own argument parsing rules,\n * preventing issues like hex addresses being converted to numbers.\n */\nexport function parseArgs(args: string[]): CommandArgs {\n // First, do a minimal parse to get the command\n const initial = minimist(args, {\n stopEarly: true,\n boolean: ['help'],\n alias: { h: 'help' },\n })\n\n const command = initial._[0]\n\n // If no command or help requested, return early\n if (!command || initial.help) {\n return initial as BaseArgs\n }\n\n // Get command-specific configuration\n const commandConfig = COMMAND_CONFIGS[command] || {}\n\n // Re-parse with command-specific configuration\n const booleanOptions = Array.isArray(commandConfig.boolean)\n ? ['help', ...commandConfig.boolean]\n : ['help']\n const parsed = minimist(args, {\n ...commandConfig,\n boolean: booleanOptions,\n alias: {\n ...commandConfig.alias,\n h: 'help',\n },\n })\n\n return parsed as CommandArgs\n}\n\n/**\n * Type guard functions for command-specific args\n */\nexport function isInitArgs(args: CommandArgs): args is InitArgs {\n return args._[0] === 'init'\n}\n\nexport function isUpdateArgs(args: CommandArgs): args is UpdateArgs {\n return args._[0] === 'update'\n}\n\nexport function isUpdateCommandsArgs(args: CommandArgs): args is UpdateCommandsArgs {\n return args._[0] === 'update-commands'\n}\n"],"mappings":";AAAA,SAAS,SAAAA,QAAO,OAAAC,MAAK,UAAAC,SAAQ,QAAAC,aAAY;;;ACAzC,YAAYC,SAAQ;AACpB,YAAYC,WAAU;AACtB,SAAS,WAAW,eAAe;AACnC,SAAS,KAAK,QAAQ,YAAY;AAClC,YAAY,WAAW;;;ACJvB,YAAY,QAAQ;AACpB,YAAY,UAAU;AACtB,SAAS,WAAW,aAAa;AACjC,OAAO,gBAAgB;AAQhB,IAAM,oBAAoB,MAAM;AACnC,MAAI,QAAQ,IAAI,uBAAuB;AACnC,UAAM,QAAQ,QAAQ,IAAI;AAC1B,QAAI,MAAM,WAAW,MAAM,EAAG,QAAO;AACrC,QAAI,MAAM,WAAW,KAAK,EAAG,QAAO;AACpC,QAAI,MAAM,WAAW,MAAM,EAAG,QAAO;AACrC,QAAI,MAAM,WAAW,KAAK,EAAG,QAAO;AAAA,EACxC;AAEA,SAAO;AACX;AAEO,SAAS,kBAAkB,gBAAgC;AAC9D,UAAQ,gBAAgB;AAAA,IACpB,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX;AACI,aAAO;AAAA,EACf;AACJ;AAEO,SAAS,cAAc,gBAAwB,QAAwB;AAC1E,UAAQ,gBAAgB;AAAA,IACpB,KAAK;AACD,aAAO,WAAW,MAAM;AAAA,IAC5B,KAAK;AACD,aAAO,QAAQ,MAAM;AAAA,IACzB,KAAK;AACD,aAAO,QAAQ,MAAM;AAAA,IACzB;AACI,aAAO,WAAW,MAAM;AAAA,EAChC;AACJ;AAEO,SAAS,WACZ,SACA,MACA,OAA2C,EAAE,KAAK,QAAW,QAAQ,MAAM,GAC9D;AACb,SAAO,IAAI,QAAQ,CAACC,UAAS,WAAW;AACpC,UAAM,QAAQ,MAAM,SAAS,MAAM;AAAA,MAC/B,OAAO,KAAK,SAAS,WAAW;AAAA,MAChC,KAAK,KAAK;AAAA,MACV,OAAO,QAAQ,aAAa;AAAA,IAChC,CAAC;AAED,UAAM,GAAG,SAAS,CAAC,SAAS;AACxB,UAAI,SAAS,GAAG;AACZ,eAAO,IAAI,MAAM,iCAAiC,IAAI,EAAE,CAAC;AAAA,MAC7D,OAAO;AACH,QAAAA,SAAQ;AAAA,MACZ;AAAA,IACJ,CAAC;AAED,UAAM,GAAG,SAAS,MAAM;AAAA,EAC5B,CAAC;AACL;AAEA,eAAsB,gCAAiD;AACnE,SAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACpC,UAAM,QAAQ,MAAM,OAAO,CAAC,QAAQ,uBAAuB,SAAS,GAAG;AAAA,MACnE,OAAO,CAAC,UAAU,QAAQ,QAAQ;AAAA,IACtC,CAAC;AAED,QAAI,SAAS;AACb,UAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS;AAE/B,gBAAU,KAAK,SAAS;AAAA,IAC5B,CAAC;AAED,UAAM,GAAG,SAAS,CAAC,SAAS;AACxB,UAAI,SAAS,GAAG;AACZ,eAAO,IAAI,MAAM,oDAAoD,CAAC;AAAA,MAC1E,OAAO;AACH,QAAAA,SAAQ,OAAO,KAAK,CAAC;AAAA,MACzB;AAAA,IACJ,CAAC;AAED,UAAM,GAAG,SAAS,MAAM;AAAA,EAC5B,CAAC;AACL;AAqCO,SAAS,kBAAiC;AAC7C,QAAM,aAAa,MAAM;AAAA,IACrB;AAAA,IACA,CAAC,aAAa,UAAU,+CAA+C,OAAO;AAAA,IAC9E,EAAE,UAAU,OAAO;AAAA,EACvB;AAEA,MAAI,WAAW,WAAW,KAAK,CAAC,WAAW,OAAQ,QAAO;AAE1D,QAAM,OAAO,WAAW,OACnB,MAAM,IAAI,EACV,OAAO,OAAO,EACd,IAAI,CAAC,SAAS;AACX,UAAM,CAAC,OAAO,GAAG,IAAI,KAAK,MAAM,GAAI;AACpC,UAAM,MAAM,IAAI,QAAQ,cAAc,EAAE,EAAE,QAAQ,SAAS,EAAE;AAG7D,UAAM,QAAQ,IAAI,MAAM,qCAAqC;AAC7D,QAAI,CAAC,MAAO,QAAO;AAEnB,WAAO;AAAA,MACH;AAAA,MACA,SAAS,CAAC,SAAS,MAAM,CAAC,CAAC,GAAG,SAAS,MAAM,CAAC,CAAC,GAAG,SAAS,MAAM,CAAC,CAAC,CAAC;AAAA,IACxE;AAAA,EACJ,CAAC,EACA;AAAA,IACG,CAAC,SACG,SAAS,QAAQ,MAAM,QAAQ,KAAK,OAAO,KAAK,KAAK,QAAQ,WAAW;AAAA,EAChF,EACC,KAAK,CAAC,GAAG,MAAM;AAEZ,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AACxB,UAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG;AAC/B,eAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;AAAA,MACrC;AAAA,IACJ;AACA,WAAO;AAAA,EACX,CAAC;AAEL,SAAO,KAAK,SAAS,IAAI,KAAK,CAAC,EAAE,MAAM;AAC3C;AAEA,eAAsB,cAAc,aAAqB,WAAqC;AAC1F,UAAQ,IAAI,WAAW,KAAK,iCAAiC,CAAC;AAE9D,QAAM,UAAU,GAAG,SAAS;AAC5B,QAAM,mBAAmB,qBAAqB,WAAW;AAGzD,QAAM,eAAe,gBAAgB;AACrC,MAAI,CAAC,cAAc;AACf,YAAQ,MAAM,WAAW,IAAI,+BAA+B,CAAC;AAC7D,WAAO;AAAA,EACX;AAGA,QAAM,cAAc,MAAM;AAAA,IACtB;AAAA,IACA;AAAA,MACI;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACJ;AAAA,IACA,EAAE,OAAO,OAAO;AAAA,EACpB;AACA,MAAI,YAAY,WAAW,EAAG,QAAO;AAGrC,QAAM,eAAe,MAAM,KAAK,OAAO,CAAC,mBAAmB,OAAO,gBAAgB,GAAG;AAAA,IACjF,OAAO;AAAA,IACP,KAAK;AAAA,EACT,CAAC;AACD,MAAI,aAAa,WAAW,GAAG;AAC3B,IAAG,UAAO,SAAS,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AACnD,WAAO;AAAA,EACX;AAGA,QAAM,iBAAiB,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG;AAAA,IACnD,OAAO;AAAA,IACP,KAAK;AAAA,EACT,CAAC;AACD,MAAI,eAAe,WAAW,GAAG;AAC7B,IAAG,UAAO,SAAS,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AACnD,WAAO;AAAA,EACX;AAGA,QAAM,YAAiB,UAAK,SAAS,gBAAgB;AACrD,MAAI,CAAI,cAAW,SAAS,GAAG;AAC3B,YAAQ,MAAM,WAAW,IAAI;AAAA,kCAAqC,SAAS,EAAE,CAAC;AAC9E,IAAG,UAAO,SAAS,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AACnD,WAAO;AAAA,EACX;AAGA,EAAG,aAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAE3C,EAAG,UAAO,WAAW,WAAW;AAAA,IAC5B,WAAW;AAAA,IACX,QAAQ,MAAM;AAEV,aAAO;AAAA,IACX;AAAA,EACJ,CAAC;AAGD,EAAG,UAAO,SAAS,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAEnD,UAAQ,IAAI,WAAW,MAAM,QAAG,GAAG,+BAA+B;AAClE,SAAO;AACX;AAEO,SAAS,kBAAkB,WAAmB,cAAmC;AACpF,WAAS,iBAAiB,KAAa;AACnC,UAAM,UAAa,eAAY,KAAK,EAAE,eAAe,KAAK,CAAC;AAE3D,eAAW,SAAS,SAAS;AACzB,YAAM,WAAgB,UAAK,KAAK,MAAM,IAAI;AAE1C,UAAI,MAAM,YAAY,GAAG;AACrB,YAAI,MAAM,SAAS,kBAAkB,MAAM,SAAS,QAAQ;AACxD;AAAA,QACJ;AACA,yBAAiB,QAAQ;AAAA,MAC7B,OAAO;AACH,YAAI,UAAa,gBAAa,UAAU,OAAO;AAC/C,YAAI,WAAW;AAEf,YACI,MAAM,SAAS,kBACf,MAAM,KAAK,SAAS,KAAK,KACzB,MAAM,KAAK,SAAS,KAAK,GAC3B;AACE,qBAAW,CAAC,QAAQ,OAAO,KAAK,cAAc;AAC1C,kBAAM,QAAQ,IAAI,OAAO,QAAQ,GAAG;AACpC,gBAAI,MAAM,KAAK,OAAO,GAAG;AACrB,wBAAU,QAAQ,QAAQ,OAAO,OAAO;AACxC,yBAAW;AAAA,YACf;AAAA,UACJ;AAEA,cAAI,UAAU;AACV,YAAG,iBAAc,UAAU,OAAO;AAAA,UACtC;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAEA,mBAAiB,SAAS;AAC9B;AAEO,SAAS,aAAa,aAAqB,gBAAwB;AACtE,UAAQ,IAAI,WAAW,MAAM,QAAG,GAAG,mCAAmC;AACtE,UAAQ,IAAI;AACZ,UAAQ,IAAI,aAAa;AACzB,UAAQ,IAAI,WAAW,KAAK,QAAQ,WAAW,EAAE,CAAC;AAClD,UAAQ,IAAI,WAAW,KAAK,KAAK,kBAAkB,cAAc,CAAC,EAAE,CAAC;AACrE,UAAQ,IAAI,oCAAoC;AAChD,UAAQ,IAAI,WAAW,KAAK,uBAAuB,CAAC;AACpD,UAAQ,IAAI,uCAAuC;AACnD,UAAQ,IAAI,iBAAiB;AAC7B,UAAQ,IAAI,WAAW,KAAK,KAAK,cAAc,gBAAgB,KAAK,CAAC,EAAE,CAAC;AAC5E;AAEA,eAAsB,wBAAwB,WAAqC;AAC/E,MAAI;AACA,UAAM,WAAW,OAAO,CAAC,MAAM,GAAG,EAAE,KAAK,WAAW,QAAQ,KAAK,CAAC;AAClE,UAAM,WAAW,OAAO,CAAC,OAAO,GAAG,GAAG,EAAE,KAAK,WAAW,QAAQ,KAAK,CAAC;AACtE,UAAM,WAAW,OAAO,CAAC,UAAU,MAAM,6BAA6B,GAAG;AAAA,MACrE,KAAK;AAAA,MACL,QAAQ;AAAA,IACZ,CAAC;AACD,WAAO;AAAA,EACX,SAAS,OAAO;AACZ,YAAQ;AAAA,MACJ,WAAW,OAAO,QAAG;AAAA,MACrB;AAAA,MACA,iBAAiB,QAAQ,MAAM,UAAU;AAAA,IAC7C;AACA,YAAQ,IAAI,WAAW,OAAO,wDAAwD,CAAC;AACvF,WAAO;AAAA,EACX;AACJ;;;ADjTO,IAAM,YAAY;AAAA,EACrB,YAAY;AAAA,IACR,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aAAa;AAAA,EACjB;AACJ;AAEA,eAAsB,KAAK,MAAgB;AACvC,QAAM,cAAc,KAAK,EAAE,CAAC;AAC5B,QAAM,WAAW,KAAK,YAAY;AAElC,MAAI,CAAC,aAAa;AACd,YAAQ,MAAM,IAAI,sCAAsC,CAAC;AACzD,YAAQ,IAAI,OAAO,sCAAsC,CAAC;AAC1D,YAAQ,KAAK,CAAC;AAAA,EAClB;AAEA,MAAI,CAAC,UAAU,QAAkC,GAAG;AAChD,YAAQ,MAAM,IAAI,4BAA4B,QAAQ,GAAG,CAAC;AAC1D,YAAQ,IAAI,OAAO,sBAAsB,GAAG,OAAO,KAAK,SAAS,EAAE,KAAK,IAAI,CAAC;AAC7E,YAAQ,KAAK,CAAC;AAAA,EAClB;AAEA,QAAM,YAAiB,cAAQ,QAAQ,IAAI,GAAG,WAAW;AAEzD,MAAO,eAAW,SAAS,GAAG;AAC1B,UAAM,EAAE,UAAU,IAAI,MAAM,QAAQ;AAAA,MAChC,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,aAAa,WAAW;AAAA,MACjC,SAAS;AAAA,IACb,CAAC;AAED,QAAI,CAAC,WAAW;AACZ,cAAQ,IAAI,OAAO,qBAAqB,CAAC;AACzC,cAAQ,KAAK,CAAC;AAAA,IAClB;AAEA,IAAG,WAAO,WAAW,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EACzD;AAEA,UAAQ,IAAI,KAAK,wCAAwC,SAAS,EAAE,CAAC;AACrE,MAAI,aAAa,cAAc;AAC3B,YAAQ,IAAI,KAAK,mBAAmB,UAAU,QAAkC,EAAE,IAAI,EAAE,CAAC;AAAA,EAC7F;AAEA,QAAM,iBAAiB,kBAAkB;AACzC,QAAM,mBAAmB,UAAU,QAAkC;AAErE,MAAI;AAEA,UAAM,UAAU,MAAM,cAAc,iBAAiB,aAAa,SAAS;AAC3E,QAAI,CAAC,SAAS;AACV,cAAQ,MAAM,IAAI,0BAA0B,CAAC;AAC7C,cAAQ,KAAK,CAAC;AAAA,IAClB;AACA,UAAM,gBAAgB,MAAM,8BAA8B;AAE1D,UAAM,eAAe,oBAAI,IAAI;AAAA,MACzB,CAAC,iBAAiB,IAAI,aAAa,EAAE;AAAA,MACrC,CAAC,iBAAiB,IAAI,aAAa,EAAE;AAAA,IACzC,CAAC;AAGD,sBAAkB,WAAW,YAAY;AAEzC,UAAM,kBAAuB,WAAK,WAAW,cAAc;AAC3D,QAAO,eAAW,eAAe,GAAG;AAChC,YAAM,UAAa,iBAAa,iBAAiB,OAAO;AACxD,YAAM,QAAQ;AAAA,QACJ,aAAO,SAAS,CAAC,MAAM,GAAG,aAAa,CAAC,CAAC;AAAA,QACzC,aAAO,SAAS,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;AAAA,MAClD;AAEA,UAAI,kBAAwB,iBAAW,SAAS,MAAM,KAAK,CAAC;AAE5D,YAAM,SAAe,YAAM,eAAe;AAC1C,aAAO,OAAO;AAEd,wBAAkB,KAAK,UAAU,QAAQ,MAAM,CAAC;AAChD,MAAG,kBAAc,iBAAiB,eAAe;AAAA,IACrD;AACA,UAAM,wBAAwB,SAAS;AACvC,iBAAa,aAAa,cAAc;AAAA,EAC5C,SAAS,OAAO;AACZ,YAAQ,MAAM,IAAI,QAAQ,GAAG,iBAAiB,QAAQ,MAAM,UAAU,KAAK;AAC3E,YAAQ,MAAM,IAAI,+BAA+B,SAAS,iBAAiB,CAAC;AAC5E,YAAQ,KAAK,CAAC;AAAA,EAClB;AACJ;;;AE3GA,OAAOC,SAAQ;AACf,OAAOC,WAAU;AACjB,SAAS,WAAWC,cAAa;AACjC,SAAS,OAAO,OAAAC,MAAK,UAAAC,SAAQ,QAAAC,aAAY;AACzC,YAAYC,YAAW;AAQvB,eAAsB,OAAO,OAAmB;AAC5C,QAAM,kBAAkBC,MAAK,KAAK,QAAQ,IAAI,GAAG,cAAc;AAE/D,MAAI,CAACC,IAAG,WAAW,eAAe,GAAG;AACjC,YAAQ,MAAMC,KAAI,uDAAuD,CAAC;AAC1E,YAAQ,IAAIC,QAAO,qEAAqE,CAAC;AACzF,YAAQ,KAAK,CAAC;AAAA,EAClB;AAEA,QAAM,cAAoB,aAAMF,IAAG,aAAa,iBAAiB,OAAO,CAAC;AACzE,QAAM,eAAe,EAAE,GAAG,YAAY,cAAc,GAAG,YAAY,gBAAgB;AAEnF,QAAM,gBAAgB,OAAO,KAAK,YAAY,EAAE;AAAA,IAAO,CAAC,QACpD,IAAI,WAAW,kBAAkB;AAAA,EACrC;AAEA,MAAI,cAAc,WAAW,GAAG;AAC5B,YAAQ,IAAIE,QAAO,mDAAmD,CAAC;AACvE,YAAQ,KAAK,CAAC;AAAA,EAClB;AAEA,UAAQ,IAAIC,MAAK,gCAAgC,CAAC;AAClD,gBAAc,QAAQ,CAAC,QAAQ;AAC3B,YAAQ,IAAI,OAAO,GAAG,IAAI,aAAa,GAAG,CAAC,EAAE;AAAA,EACjD,CAAC;AACD,UAAQ,IAAI;AAEZ,UAAQ,IAAIA,MAAK,6BAA6B,CAAC;AAC/C,QAAM,iBAAkC,CAAC;AAEzC,aAAW,OAAO,eAAe;AAC7B,QAAI;AACA,YAAM,UAAU,MAAM,iBAAiB,GAAG;AAC1C,qBAAe,GAAG,IAAI;AACtB,cAAQ,IAAI,MAAM,QAAG,GAAG,GAAG,GAAG,KAAK,OAAO,EAAE;AAAA,IAChD,QAAQ;AACJ,cAAQ,MAAMF,KAAI,QAAG,GAAG,+BAA+B,GAAG,EAAE;AAAA,IAChE;AAAA,EACJ;AAEA,UAAQ,IAAI;AACZ,UAAQ,IAAIE,MAAK,0BAA0B,CAAC;AAE5C,QAAM,UAAUH,IAAG,aAAa,iBAAiB,OAAO;AACxD,QAAM,QAAsB,CAAC;AAE7B,aAAW,CAAC,KAAK,OAAO,KAAK,OAAO,QAAQ,cAAc,GAAG;AACzD,UAAM,iBAAiB,aAAa,GAAG;AACvC,QAAI,mBAAmB,IAAI,OAAO,IAAI;AAClC,UAAI,YAAY,eAAe,GAAG,GAAG;AACjC,cAAM,KAAK,GAAS,cAAO,SAAS,CAAC,gBAAgB,GAAG,GAAG,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC;AAAA,MACjF;AACA,UAAI,YAAY,kBAAkB,GAAG,GAAG;AACpC,cAAM,KAAK,GAAS,cAAO,SAAS,CAAC,mBAAmB,GAAG,GAAG,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC;AAAA,MACpF;AAAA,IACJ;AAAA,EACJ;AAEA,MAAI,MAAM,SAAS,GAAG;AAClB,UAAM,kBAAwB,kBAAW,SAAS,KAAK;AACvD,IAAAA,IAAG,cAAc,iBAAiB,eAAe;AACjD,YAAQ,IAAI,MAAM,QAAG,GAAG,sBAAsB;AAE9C,UAAM,iBAAiB,kBAAkB;AACzC,YAAQ,IAAI;AACZ,YAAQ,IAAIG,MAAK,gCAAgC,cAAc,KAAK,CAAC;AAErE,QAAI;AACA,YAAM,WAAW,gBAAgB;AAAA,QAC7B,kBAAkB,cAAc,EAAE,MAAM,GAAG,EAAE,CAAC,KAAK;AAAA,MACvD,CAAC;AACD,cAAQ,IAAI;AACZ,cAAQ,IAAI,MAAM,QAAG,GAAG,oCAAoC;AAAA,IAChE,QAAQ;AACJ,cAAQ,MAAMF,KAAI,QAAQ,GAAG,gCAAgC;AAC7D,cAAQ;AAAA,QACJC,QAAO,YAAY;AAAA,QACnBC,MAAK,kBAAkB,cAAc,CAAC;AAAA,QACtCD,QAAO,UAAU;AAAA,MACrB;AAAA,IACJ;AAAA,EACJ,OAAO;AACH,YAAQ,IAAI,MAAM,QAAG,GAAG,sCAAsC;AAAA,EAClE;AACJ;AAEA,eAAe,iBAAiB,aAAsC;AAClE,SAAO,IAAI,QAAQ,CAACE,UAAS,WAAW;AACpC,UAAM,QAAQC,OAAM,OAAO,CAAC,QAAQ,aAAa,SAAS,GAAG;AAAA,MACzD,OAAO,CAAC,UAAU,QAAQ,QAAQ;AAAA,IACtC,CAAC;AAED,QAAI,SAAS;AACb,UAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS;AAE/B,gBAAU,KAAK,SAAS;AAAA,IAC5B,CAAC;AAED,UAAM,GAAG,SAAS,CAAC,SAAS;AACxB,UAAI,SAAS,GAAG;AACZ,eAAO,IAAI,MAAM,+BAA+B,WAAW,EAAE,CAAC;AAAA,MAClE,OAAO;AACH,QAAAD,SAAQ,OAAO,KAAK,CAAC;AAAA,MACzB;AAAA,IACJ,CAAC;AAED,UAAM,GAAG,SAAS,MAAM;AAAA,EAC5B,CAAC;AACL;;;ACxHA,OAAOE,SAAQ;AACf,OAAOC,WAAU;AACjB,SAAS,qBAAqB;AAC9B,YAAY,YAAY;AACxB,SAAS,cAAc;AACvB,SAAS,SAAS;AAClB,SAAS,SAAAC,QAAO,OAAAC,MAAK,UAAAC,SAAQ,QAAAC,aAAY;AACzC;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACG;AACP,SAAS,yBAAyB;AAClC,SAAS,0BAA6C;AAEtD,SAAS,cAAc;AAEvB,IAAM,qBAAqB,EACtB,OAAO;AAAA,EACJ,MAAM,EACD,OAAO,EACP,IAAI,GAAG,0BAA0B,EACjC,IAAI,IAAI,4CAA4C,EACpD;AAAA,IACG;AAAA,IACA;AAAA,EACJ;AAAA,EACJ,aAAa,EACR,OAAO,EACP,IAAI,GAAG,iCAAiC,EACxC,IAAI,KAAK,oDAAoD;AACtE,CAAC,EACA,UAAU,CAAC,SAAS,OAAO,oBAAoB,IAAI,CAAC;AAEzD,eAAsB,eAAe,MAA0B;AAC3D,QAAM,WAAW,KAAK,QAAQ,KAAK,EAAE,CAAC;AACtC,QAAM,cAAc,KAAK,eAAe,KAAK,EAAE,CAAC;AAChD,QAAM,UAAU,KAAK,WAAW;AAEhC,MAAI,CAAC,YAAY,CAAC,aAAa;AAC3B,YAAQ,MAAMF,KAAI,mCAAmC,CAAC;AACtD,YAAQ,IAAI;AACZ,YAAQ,IAAIC,QAAO,QAAQ,CAAC;AAC5B,YAAQ,IAAI,wDAAwD;AACpE,YAAQ,IAAIC,MAAK,MAAM,CAAC;AACxB,YAAQ;AAAA,MACJ;AAAA,IACJ;AACA,YAAQ,IAAI;AACZ,YAAQ,IAAID,QAAO,YAAY,CAAC;AAChC,YAAQ,IAAI,6DAA6D;AACzE,YAAQ,IAAI,+DAA+D;AAC3E,YAAQ,IAAI;AACZ,YAAQ,IAAIA,QAAO,UAAU,CAAC;AAC9B,YAAQ,IAAI,mDAAmD;AAC/D,YAAQ,IAAI,0CAA0C;AACtD,YAAQ,IAAI,+DAA+D;AAC3E,YAAQ,IAAI;AACZ,YAAQ,IAAIA,QAAO,OAAO,CAAC;AAC3B,YAAQ;AAAA,MACJ;AAAA,IACJ;AACA,YAAQ,KAAK,CAAC;AAAA,EAClB;AAEA,QAAM,UAAUH,MAAK,QAAQ,OAAO;AACpC,MAAI,CAACD,IAAG,WAAW,OAAO,GAAG;AACzB,YAAQ,MAAMG,KAAI,sCAAsC,OAAO,EAAE,CAAC;AAClE,YAAQ,IAAIC,QAAO,mEAAmE,CAAC;AACvF,YAAQ,KAAK,CAAC;AAAA,EAClB;AAEA,EAAO,cAAO,EAAE,MAAM,QAAQ,CAAC;AAE/B,QAAM,oBAAoB,QAAQ,IAAI;AACtC,MAAI,CAAC,mBAAmB;AACpB,YAAQ,MAAMD,KAAI,4DAA4D,CAAC;AAC/E,YAAQ,IAAIC,QAAO,wDAAwD,CAAC;AAC5E,YAAQ,KAAK,CAAC;AAAA,EAClB;AAEA,MAAI;AACJ,MAAI;AACJ,MAAI;AACA,UAAM,iBAAiB,oBAAoB,iBAAiB;AAC5D,iBAAa,eAAe;AAC5B,UAAM,eAAe;AAAA,EACzB,QAAQ;AACJ,YAAQ,MAAMD,KAAI,yCAAyC,CAAC;AAC5D,YAAQ,IAAIC,QAAO,yDAAyD,CAAC;AAC7E,YAAQ,KAAK,CAAC;AAAA,EAClB;AAEA,MAAI,CAAC,KAAK;AAEN,YAAQ,MAAMD,KAAI,kDAAkD,CAAC;AACrE,YAAQ,KAAK,CAAC;AAAA,EAClB;AAGA,MAAI;AACJ,MAAI;AACA,UAAM,SAAS,IAAI,OAAO,OAAO,UAAU;AAC3C,uBAAmB,OAAO,QAAQ,YAAY;AAAA,EAClD,QAAQ;AACJ,YAAQ,MAAMA,KAAI,kDAAkD,CAAC;AACrE,YAAQ,KAAK,CAAC;AAAA,EAClB;AAEA,MAAI;AACA,UAAM,eAAeF,MAAK,QAAQ,QAAQ;AAC1C,QAAI,CAACD,IAAG,WAAW,YAAY,GAAG;AAC9B,YAAM,IAAI,MAAM,mBAAmB,YAAY,EAAE;AAAA,IACrD;AACA,QAAI,WAA2B,CAAC;AAChC,UAAM,UAAU,cAAc,YAAY,EAAE;AAC5C,QAAI;AACA,YAAM,SAAS,MAAM,OAAO;AAE5B,iBAAW,OAAO,WAAW,OAAO;AACpC,UAAI,CAAC,UAAU;AACX,cAAM,IAAI,MAAM,sDAAsD;AAAA,MAC1E;AAAA,IACJ,SAAS,OAAO;AACZ,YAAM,IAAI;AAAA,QACN,mCAAmC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MAC7F;AAAA,IACJ;AAEA,QAAI;AACA,YAAM,oBAAoB,EAAE,MAAM,kBAAkB,EAAE,MAAM,QAAQ;AACpE,iBAAW;AAAA,IACf,SAAS,UAAU;AACf,UAAI,oBAAoB,EAAE,UAAU;AAChC,cAAM,SAAS,SAAS,OACnB,IAAI,CAAC,QAAQ;AACV,gBAAMC,QAAO,IAAI,KAAK,SAAS,IAAI,IAAI,IAAI,KAAK,KAAK,GAAG,CAAC,MAAM;AAC/D,iBAAO,KAAKA,KAAI,IAAI,IAAI,OAAO;AAAA,QACnC,CAAC,EACA,KAAK,IAAI;AACd,cAAM,IAAI,MAAM;AAAA,EAA4B,MAAM,EAAE;AAAA,MACxD;AACA,YAAM;AAAA,IACV;AAEA,YAAQ,IAAII,MAAK,OAAO,GAAGH,OAAM,SAAS,OAAO,SAAS,CAAC,GAAGG,MAAK,WAAW,CAAC;AAC/E,eAAW,OAAO,UAAU;AACxB,cAAQ,IAAI,MAAMH,OAAM,IAAI,IAAI,CAAC,MAAM,IAAI,WAAW,EAAE;AAAA,IAC5D;AAEA,QAAI;AACA,YAAM,gBAAgB,MAAM,iCAAiC,WAAW;AACxE,YAAM,iBAAiB,SAAS,EAAE,kBAAkB,GAAG;AACvD,YAAM,EAAE,qBAAqB,IAAI,MAAM,mBAAmB;AAAA,QACtD;AAAA,QACA;AAAA,MACJ;AACA,YAAM,QAAQ,kBAAkB,gBAAgB;AAEhD,YAAM,EAAE,SAAS,IAAI,MAAM,qBAAqB,eAAe,EAAE,MAAM,CAAC;AACxE,UAAI,CAAC,UAAU;AACX,cAAM,IAAI,MAAM,0DAA0D;AAAA,MAC9E;AAEA,cAAQ,IAAI;AACZ,YAAM,qBAAqB,kBAAkB;AAAA,QACzC;AAAA,QACA,YAAY,CAAC,gBAAgB;AAAA,QAC7B,UAAU;AAAA,UACN,eAAe;AAAA,QACnB;AAAA,MACJ,CAAC;AAED,cAAQ,IAAIG,MAAK,MAAM,GAAG,SAAS,WAAW;AAC9C,cAAQ,IAAIH,OAAM,QAAG,GAAG,sCAAsC;AAC9D,cAAQ,KAAK,CAAC;AAAA,IAClB,SAAS,WAAoB;AACzB,YAAM,eAAe,qBAAqB,QAAQ,UAAU,UAAU,OAAO,SAAS;AAEtF,UAAI,aAAa,SAAS,+BAA+B,GAAG;AACxD,cAAM,IAAI;AAAA,UACN,kBAAkB,gBAAgB;AAAA;AAAA,iEAAsE,GAAG;AAAA,QAC/G;AAAA,MACJ,WACI,aAAa,SAAS,YAAY,KAClC,aAAa,SAAS,cAAc,GACtC;AACE,cAAM,IAAI;AAAA,UACN;AAAA;AAAA;AAAA,QACJ;AAAA,MACJ,WAAW,aAAa,SAAS,SAAS,KAAK,aAAa,SAAS,WAAW,GAAG;AAC/E,cAAM,IAAI;AAAA,UACN;AAAA;AAAA;AAAA,QACJ;AAAA,MACJ,OAAO;AACH,cAAM,IAAI;AAAA,UACN,8BAA8B,YAAY;AAAA;AAAA;AAAA,QAC9C;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ,SAAS,OAAO;AACZ,YAAQ,MAAMC,KAAI,QAAQ,GAAG,iBAAiB,QAAQ,MAAM,UAAU,KAAK;AAC3E,YAAQ,KAAK,CAAC;AAAA,EAClB;AACJ;;;AC7MA,OAAO,cAAc;AAuBrB,IAAM,kBAAiD;AAAA,EACnD,MAAM;AAAA,IACF,QAAQ,CAAC,UAAU;AAAA,IACnB,OAAO,EAAE,GAAG,WAAW;AAAA,IACvB,SAAS,EAAE,UAAU,aAAa;AAAA,EACtC;AAAA,EACA,QAAQ;AAAA;AAAA,EAER;AAAA,EACA,iBAAiB;AAAA,IACb,QAAQ,CAAC,MAAM;AAAA,IACf,OAAO,EAAE,GAAG,OAAO;AAAA,EACvB;AAAA,EACA,mBAAmB;AAAA;AAAA,IAEf,QAAQ,CAAC,QAAQ,eAAe,WAAW,GAAG;AAAA,IAC9C,OAAO;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,IACP;AAAA,IACA,SAAS,EAAE,SAAS,OAAO;AAAA,EAC/B;AACJ;AAYO,SAAS,UAAU,MAA6B;AAEnD,QAAM,UAAU,SAAS,MAAM;AAAA,IAC3B,WAAW;AAAA,IACX,SAAS,CAAC,MAAM;AAAA,IAChB,OAAO,EAAE,GAAG,OAAO;AAAA,EACvB,CAAC;AAED,QAAM,UAAU,QAAQ,EAAE,CAAC;AAG3B,MAAI,CAAC,WAAW,QAAQ,MAAM;AAC1B,WAAO;AAAA,EACX;AAGA,QAAM,gBAAgB,gBAAgB,OAAO,KAAK,CAAC;AAGnD,QAAM,iBAAiB,MAAM,QAAQ,cAAc,OAAO,IACpD,CAAC,QAAQ,GAAG,cAAc,OAAO,IACjC,CAAC,MAAM;AACb,QAAM,SAAS,SAAS,MAAM;AAAA,IAC1B,GAAG;AAAA,IACH,SAAS;AAAA,IACT,OAAO;AAAA,MACH,GAAG,cAAc;AAAA,MACjB,GAAG;AAAA,IACP;AAAA,EACJ,CAAC;AAED,SAAO;AACX;AAKO,SAAS,WAAW,MAAqC;AAC5D,SAAO,KAAK,EAAE,CAAC,MAAM;AACzB;AAEO,SAAS,aAAa,MAAuC;AAChE,SAAO,KAAK,EAAE,CAAC,MAAM;AACzB;AAEO,SAAS,qBAAqB,MAA+C;AAChF,SAAO,KAAK,EAAE,CAAC,MAAM;AACzB;;;ALnGA,eAAe,OAAO;AAClB,QAAM,OAAO,UAAU,QAAQ,KAAK,MAAM,CAAC,CAAC;AAC5C,QAAM,UAAU,KAAK,EAAE,CAAC;AAExB,MAAI,KAAK,QAAQ,CAAC,SAAS;AACvB,aAAS;AACT;AAAA,EACJ;AAEA,MAAI;AACA,YAAQ,SAAS;AAAA,MACb,KAAK;AACD,YAAI,WAAW,IAAI,GAAG;AAClB,gBAAM,KAAK,IAAI;AAAA,QACnB;AACA;AAAA,MACJ,KAAK;AACD,YAAI,aAAa,IAAI,GAAG;AACpB,gBAAM,OAAO,IAAI;AAAA,QACrB;AACA;AAAA,MACJ,KAAK;AACD,YAAI,qBAAqB,IAAI,GAAG;AAC5B,gBAAM,eAAe,IAAI;AAAA,QAC7B;AACA;AAAA,MACJ;AACI,gBAAQ,MAAMG,KAAI,oBAAoB,OAAO,EAAE,CAAC;AAChD,iBAAS;AACT,gBAAQ,KAAK,CAAC;AAAA,IACtB;AAAA,EACJ,SAAS,OAAO;AACZ,YAAQ,MAAMA,KAAI,QAAQ,GAAG,iBAAiB,QAAQ,MAAM,UAAU,KAAK;AAC3E,YAAQ,KAAK,CAAC;AAAA,EAClB;AACJ;AAEA,SAAS,WAAW;AAChB,UAAQ,IAAI;AAAA,EACdC,MAAK,WAAW,CAAC;AAAA;AAAA,EAEjBC,QAAO,QAAQ,CAAC;AAAA;AAAA;AAAA,EAGhBA,QAAO,WAAW,CAAC;AAAA,IACjBC,OAAM,MAAM,CAAC;AAAA,IACbA,OAAM,QAAQ,CAAC;AAAA,IACfA,OAAM,eAAe,CAAC;AAAA,IACtBA,OAAM,iBAAiB,CAAC;AAAA;AAAA,EAE1BD,QAAO,eAAe,CAAC;AAAA;AAAA,EAEvB,OAAO,QAAQ,SAAS,EACrB;AAAA,IACG,CAAC,CAAC,KAAK,QAAQ,MACX,gCAAgC,GAAG,MAAM,SAAS,WAAW;AAAA,EACrE,EACC,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA,EAGbA,QAAO,wBAAwB,CAAC;AAAA;AAAA;AAAA,EAGhCA,QAAO,0BAA0B,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,EAKlCA,QAAO,iBAAiB,CAAC;AAAA;AAAA;AAAA,EAGzBA,QAAO,WAAW,CAAC;AAAA,IACjBD,MAAK,4BAA4B,CAAC;AAAA;AAAA;AAAA;AAAA,IAIlCA,MAAK,uBAAuB,CAAC;AAAA;AAAA;AAAA,IAG7BA,MAAK,uBAAuB,CAAC;AAAA;AAAA;AAAA;AAAA,IAI7BA,MAAK,gDAAgD,CAAC;AAAA;AAAA;AAAA,IAGtDA,MAAK,2CAA2C,CAAC;AAAA;AAAA;AAAA;AAAA,IAIjDA,MAAK,0EAA0E,CAAC;AAAA,CACnF;AACD;AAEA,KAAK,EAAE,MAAM,CAAC,UAAU;AACpB,UAAQ,MAAMD,KAAI,mBAAmB,GAAG,KAAK;AAC7C,UAAQ,KAAK,CAAC;AAClB,CAAC;","names":["green","red","yellow","cyan","fs","path","resolve","fs","path","spawn","red","yellow","cyan","jsonc","path","fs","red","yellow","cyan","resolve","spawn","fs","path","green","red","yellow","cyan","red","cyan","yellow","green"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/modules/init.ts","../src/modules/utils.ts","../src/modules/update.ts","../src/parser.ts"],"sourcesContent":["import { green, red, yellow, cyan } from 'picocolors'\nimport { init, TEMPLATES, type Template } from './modules/init.js'\nimport { update } from './modules/update.js'\nimport { parseArgs, isInitArgs, isUpdateArgs } from './parser.js'\n\nasync function main() {\n const args = parseArgs(process.argv.slice(2))\n const command = args._[0]\n\n if (args.help || !command) {\n showHelp()\n return\n }\n\n try {\n switch (command) {\n case 'init':\n if (isInitArgs(args)) {\n await init(args)\n }\n break\n case 'update':\n if (isUpdateArgs(args)) {\n await update(args)\n }\n break\n default:\n console.error(red(`Unknown command: ${command}`))\n showHelp()\n process.exit(1)\n }\n } catch (error) {\n console.error(red('Error:'), error instanceof Error ? error.message : error)\n process.exit(1)\n }\n}\n\nfunction showHelp() {\n console.log(`\n${cyan('towns-bot')} - CLI for creating and managing Towns Protocol bot projects\n\n${yellow('Usage:')}\n towns-bot <command> [options]\n\n${yellow('Commands:')}\n ${green('init')} [project-name] Create a new bot project\n ${green('update')} Update @towns-protocol dependencies to latest versions\n\n${yellow('Init Options:')}\n -t, --template <name> Template to use:\n${Object.entries(TEMPLATES)\n .map(\n ([key, template]: [string, Template]) =>\n ` ${key} - ${template.description}`,\n )\n .join('\\n')}\n Default: quickstart\n\n${yellow('List Commands Options:')}\n -f, --file <path> Path to commands file\n\n${yellow('Update Commands Options:')}\n -f, --file <path> Path to commands file\n -t, --bearerToken <token> Bearer token for authentication\n -e, --envFile <path> Path to .env file (default: .env)\n\n${yellow('Global Options:')}\n -h, --help Show this help message\n\n${yellow('Examples:')}\n ${cyan('# Create a new bot project')}\n towns-bot init my-bot\n towns-bot init my-ai-bot --template quickstart\n\n ${cyan('# Update dependencies')}\n towns-bot update\n`)\n}\n\nmain().catch((error) => {\n console.error(red('Unexpected error:'), error)\n process.exit(1)\n})\n","import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport { default as prompts } from 'prompts'\nimport { red, yellow, cyan } from 'picocolors'\nimport * as jsonc from 'jsonc-parser'\nimport {\n getPackageManager,\n getLatestTownsProtocolVersion,\n cloneTemplate,\n applyReplacements,\n printSuccess,\n initializeGitRepository,\n type PackageJson,\n} from './utils.js'\nimport type { InitArgs } from '../parser.js'\n\nexport type Template = (typeof TEMPLATES)[keyof typeof TEMPLATES]\nexport const TEMPLATES = {\n quickstart: {\n name: 'Bot Quickstart',\n description: 'Simple starter bot with basic commands',\n packagePath: 'bot-quickstart',\n },\n} as const\n\nexport async function init(argv: InitArgs) {\n const projectName = argv._[1]\n const template = argv.template || 'quickstart'\n\n if (!projectName) {\n console.error(red('Error: Please provide a project name'))\n console.log(yellow('Usage: towns-bot init <project-name>'))\n process.exit(1)\n }\n\n if (!TEMPLATES[template as keyof typeof TEMPLATES]) {\n console.error(red(`Error: Unknown template \"${template}\"`))\n console.log(yellow('Available templates:'), Object.keys(TEMPLATES).join(', '))\n process.exit(1)\n }\n\n const targetDir = path.resolve(process.cwd(), projectName)\n\n if (fs.existsSync(targetDir)) {\n const { overwrite } = await prompts({\n type: 'confirm',\n name: 'overwrite',\n message: `Directory ${projectName} already exists. Overwrite?`,\n initial: false,\n })\n\n if (!overwrite) {\n console.log(yellow('Operation cancelled'))\n process.exit(0)\n }\n\n fs.rmSync(targetDir, { recursive: true, force: true })\n }\n\n console.log(cyan(`Creating a new Towns Protocol bot in ${targetDir}`))\n if (template !== 'quickstart') {\n console.log(cyan(`Using template: ${TEMPLATES[template as keyof typeof TEMPLATES].name}`))\n }\n\n const packageManager = getPackageManager()\n const selectedTemplate = TEMPLATES[template as keyof typeof TEMPLATES]\n\n try {\n // Clone template from GitHub\n const success = await cloneTemplate(selectedTemplate.packagePath, targetDir)\n if (!success) {\n console.error(red('Failed to clone template'))\n process.exit(1)\n }\n const latestVersion = await getLatestTownsProtocolVersion()\n // Replace workspace dependencies in package.json and other files\n const replacements = new Map([\n ['workspace:\\\\^', `^${latestVersion}`],\n ['workspace:\\\\*', `^${latestVersion}`],\n ])\n\n // Apply replacements to all relevant files\n applyReplacements(targetDir, replacements)\n\n const packageJsonPath = path.join(targetDir, 'package.json')\n if (fs.existsSync(packageJsonPath)) {\n const content = fs.readFileSync(packageJsonPath, 'utf-8')\n const edits = [\n jsonc.modify(content, ['name'], projectName, {}),\n jsonc.modify(content, ['version'], '0.0.1', {}),\n ]\n\n let modifiedContent = jsonc.applyEdits(content, edits.flat())\n\n const parsed = jsonc.parse(modifiedContent) as PackageJson\n delete parsed.private\n\n modifiedContent = JSON.stringify(parsed, null, 2)\n fs.writeFileSync(packageJsonPath, modifiedContent)\n }\n await initializeGitRepository(targetDir)\n printSuccess(projectName, packageManager)\n } catch (error) {\n console.error(red('Error:'), error instanceof Error ? error.message : error)\n console.error(red(`Please delete the directory ${targetDir} and try again.`))\n process.exit(1)\n }\n}\n","import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport { default as spawn } from 'cross-spawn'\nimport picocolors from 'picocolors'\n\nexport type PackageJson = {\n private?: boolean\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n}\n\nexport const getPackageManager = () => {\n if (process.env.npm_config_user_agent) {\n const agent = process.env.npm_config_user_agent\n if (agent.startsWith('yarn')) return 'yarn'\n if (agent.startsWith('npm')) return 'npm'\n if (agent.startsWith('pnpm')) return 'pnpm'\n if (agent.startsWith('bun')) return 'bun'\n }\n // Default to npm if no user agent is found\n return 'npm'\n}\n\nexport function getInstallCommand(packageManager: string): string {\n switch (packageManager) {\n case 'bun':\n return 'bun install'\n case 'yarn':\n return 'yarn'\n case 'pnpm':\n return 'pnpm install'\n default:\n return 'npm install'\n }\n}\n\nexport function getRunCommand(packageManager: string, script: string): string {\n switch (packageManager) {\n case 'bun':\n return `bun run ${script}`\n case 'yarn':\n return `yarn ${script}`\n case 'pnpm':\n return `pnpm ${script}`\n default:\n return `npm run ${script}`\n }\n}\n\nexport function runCommand(\n command: string,\n args: string[],\n opts: { cwd?: string; silent?: boolean } = { cwd: undefined, silent: false },\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n stdio: opts.silent ? 'ignore' : 'inherit',\n cwd: opts.cwd,\n shell: process.platform === 'win32',\n })\n\n child.on('close', (code) => {\n if (code !== 0) {\n reject(new Error(`Command failed with exit code ${code}`))\n } else {\n resolve()\n }\n })\n\n child.on('error', reject)\n })\n}\n\nexport async function getLatestTownsProtocolVersion(): Promise<string> {\n return new Promise((resolve, reject) => {\n const child = spawn('npm', ['view', '@towns-protocol/bot', 'version'], {\n stdio: ['ignore', 'pipe', 'ignore'],\n })\n\n let output = ''\n child.stdout?.on('data', (data) => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n output += data.toString()\n })\n\n child.on('close', (code) => {\n if (code !== 0) {\n reject(new Error('Failed to fetch latest @towns-protocol/bot version'))\n } else {\n resolve(output.trim())\n }\n })\n\n child.on('error', reject)\n })\n}\n\nexport function copyDirectory(src: string, dest: string, replacements?: Map<string, string>) {\n if (!fs.existsSync(dest)) {\n fs.mkdirSync(dest, { recursive: true })\n }\n\n const entries = fs.readdirSync(src, { withFileTypes: true })\n\n for (const entry of entries) {\n const srcPath = path.join(src, entry.name)\n const destPath = path.join(dest, entry.name)\n\n if (entry.isDirectory()) {\n if (entry.name === 'node_modules' || entry.name === 'dist') {\n continue\n }\n copyDirectory(srcPath, destPath, replacements)\n } else {\n let content = fs.readFileSync(srcPath, 'utf-8')\n\n if (\n replacements &&\n (entry.name === 'package.json' ||\n entry.name.endsWith('.ts') ||\n entry.name.endsWith('.js'))\n ) {\n for (const [search, replace] of replacements) {\n content = content.replace(new RegExp(search, 'g'), replace)\n }\n }\n\n fs.writeFileSync(destPath, content)\n }\n }\n}\n\nexport function getLatestSdkTag(): string | null {\n const tagsResult = spawn.sync(\n 'git',\n ['ls-remote', '--tags', 'https://github.com/towns-protocol/towns.git', 'sdk-*'],\n { encoding: 'utf8' },\n )\n\n if (tagsResult.status !== 0 || !tagsResult.stdout) return null\n\n const tags = tagsResult.stdout\n .split('\\n')\n .filter(Boolean)\n .map((line) => {\n const [_hash, ref] = line.split('\\t')\n const tag = ref.replace('refs/tags/', '').replace(/\\^{}$/, '')\n\n // Extract version numbers from tags like sdk-hash-1.2.3\n const match = tag.match(/^sdk-[0-9a-f]+-(\\d+)\\.(\\d+)\\.(\\d+)$/)\n if (!match) return null\n\n return {\n tag,\n version: [parseInt(match[1]), parseInt(match[2]), parseInt(match[3])],\n }\n })\n .filter(\n (item): item is { tag: string; version: number[] } =>\n item !== null && Array.isArray(item.version) && item.version.length === 3,\n )\n .sort((a, b) => {\n // Compare version numbers\n for (let i = 0; i < 3; i++) {\n if (a.version[i] !== b.version[i]) {\n return b.version[i] - a.version[i]\n }\n }\n return 0\n })\n\n return tags.length > 0 ? tags[0].tag : null\n}\n\nexport async function cloneTemplate(packagePath: string, targetDir: string): Promise<boolean> {\n console.log(picocolors.blue('Cloning template from GitHub...'))\n\n const tempDir = `${targetDir}-temp`\n const fullTemplatePath = `packages/examples/${packagePath}`\n\n // Get latest SDK tag\n const latestSdkTag = getLatestSdkTag()\n if (!latestSdkTag) {\n console.error(picocolors.red('Failed to get latest SDK tag.'))\n return false\n }\n\n // Clone with minimal data to a temporary directory\n const cloneResult = spawn.sync(\n 'git',\n [\n 'clone',\n '--no-checkout',\n '--depth',\n '1',\n '--sparse',\n '--branch',\n latestSdkTag,\n 'https://github.com/towns-protocol/towns.git',\n tempDir,\n ],\n { stdio: 'pipe' },\n )\n if (cloneResult.status !== 0) return false\n\n // Set up sparse checkout for the specific template\n const sparseResult = spawn.sync('git', ['sparse-checkout', 'set', fullTemplatePath], {\n stdio: 'pipe',\n cwd: tempDir,\n })\n if (sparseResult.status !== 0) {\n fs.rmSync(tempDir, { recursive: true, force: true })\n return false\n }\n\n // Checkout the content\n const checkoutResult = spawn.sync('git', ['checkout'], {\n stdio: 'pipe',\n cwd: tempDir,\n })\n if (checkoutResult.status !== 0) {\n fs.rmSync(tempDir, { recursive: true, force: true })\n return false\n }\n\n // Verify template directory exists\n const sourceDir = path.join(tempDir, fullTemplatePath)\n if (!fs.existsSync(sourceDir)) {\n console.error(picocolors.red(`\\nTemplate directory not found at ${sourceDir}`))\n fs.rmSync(tempDir, { recursive: true, force: true })\n return false\n }\n\n // Copy template contents to target directory\n fs.mkdirSync(targetDir, { recursive: true })\n // Use filter to ensure all files (including hidden) are copied\n fs.cpSync(sourceDir, targetDir, {\n recursive: true,\n filter: () => {\n // Copy all files, including hidden ones\n return true\n },\n })\n\n // Clean up temporary directory\n fs.rmSync(tempDir, { recursive: true, force: true })\n\n console.log(picocolors.green('✓'), 'Template cloned successfully!')\n return true\n}\n\nexport function applyReplacements(targetDir: string, replacements: Map<string, string>) {\n function processDirectory(dir: string) {\n const entries = fs.readdirSync(dir, { withFileTypes: true })\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name)\n\n if (entry.isDirectory()) {\n if (entry.name === 'node_modules' || entry.name === 'dist') {\n continue\n }\n processDirectory(fullPath)\n } else {\n let content = fs.readFileSync(fullPath, 'utf-8')\n let modified = false\n\n if (\n entry.name === 'package.json' ||\n entry.name.endsWith('.ts') ||\n entry.name.endsWith('.js')\n ) {\n for (const [search, replace] of replacements) {\n const regex = new RegExp(search, 'g')\n if (regex.test(content)) {\n content = content.replace(regex, replace)\n modified = true\n }\n }\n\n if (modified) {\n fs.writeFileSync(fullPath, content)\n }\n }\n }\n }\n }\n\n processDirectory(targetDir)\n}\n\nexport function printSuccess(projectName: string, packageManager: string) {\n console.log(picocolors.green('✓'), 'Bot project created successfully!')\n console.log()\n console.log('Next steps:')\n console.log(picocolors.cyan(` cd ${projectName}`))\n console.log(picocolors.cyan(` ${getInstallCommand(packageManager)}`))\n console.log('Set up your environment variables:')\n console.log(picocolors.cyan(' cp .env.sample .env'))\n console.log(' Edit .env with your bot credentials')\n console.log('Start your bot:')\n console.log(picocolors.cyan(` ${getRunCommand(packageManager, 'dev')}`))\n}\n\nexport async function initializeGitRepository(targetDir: string): Promise<boolean> {\n try {\n await runCommand('git', ['init'], { cwd: targetDir, silent: true })\n await runCommand('git', ['add', '.'], { cwd: targetDir, silent: true })\n await runCommand('git', ['commit', '-m', 'feat: towns bot scaffolding'], {\n cwd: targetDir,\n silent: true,\n })\n return true\n } catch (error) {\n console.log(\n picocolors.yellow('⚠'),\n 'Failed to initialize git repository:',\n error instanceof Error ? error.message : 'Unknown error',\n )\n console.log(picocolors.yellow(' You can manually initialize git later with: git init'))\n return false\n }\n}\n","import fs from 'fs'\nimport path from 'path'\nimport { default as spawn } from 'cross-spawn'\nimport { green, red, yellow, cyan } from 'picocolors'\nimport * as jsonc from 'jsonc-parser'\nimport { getPackageManager, getInstallCommand, runCommand, type PackageJson } from './utils.js'\nimport type { UpdateArgs } from '../parser.js'\n\ninterface PackageVersions {\n [key: string]: string\n}\n\nexport async function update(_argv: UpdateArgs) {\n const packageJsonPath = path.join(process.cwd(), 'package.json')\n\n if (!fs.existsSync(packageJsonPath)) {\n console.error(red('Error: No package.json found in the current directory'))\n console.log(yellow('Please run this command from a Towns Protocol bot project directory'))\n process.exit(1)\n }\n\n const packageJson = jsonc.parse(fs.readFileSync(packageJsonPath, 'utf-8')) as PackageJson\n const dependencies = { ...packageJson.dependencies, ...packageJson.devDependencies }\n\n const townsPackages = Object.keys(dependencies).filter((pkg) =>\n pkg.startsWith('@towns-protocol/'),\n )\n\n if (townsPackages.length === 0) {\n console.log(yellow('No @towns-protocol packages found in this project'))\n process.exit(0)\n }\n\n console.log(cyan('Found Towns Protocol packages:'))\n townsPackages.forEach((pkg) => {\n console.log(` - ${pkg}@${dependencies[pkg]}`)\n })\n console.log()\n\n console.log(cyan('Fetching latest versions...'))\n const latestVersions: PackageVersions = {}\n\n for (const pkg of townsPackages) {\n try {\n const version = await getLatestVersion(pkg)\n latestVersions[pkg] = version\n console.log(green('✓'), `${pkg}: ${version}`)\n } catch {\n console.error(red('✗'), `Failed to fetch version for ${pkg}`)\n }\n }\n\n console.log()\n console.log(cyan('Updating package.json...'))\n\n const content = fs.readFileSync(packageJsonPath, 'utf-8')\n const edits: jsonc.Edit[] = []\n\n for (const [pkg, version] of Object.entries(latestVersions)) {\n const currentVersion = dependencies[pkg]\n if (currentVersion !== `^${version}`) {\n if (packageJson.dependencies?.[pkg]) {\n edits.push(...jsonc.modify(content, ['dependencies', pkg], `^${version}`, {}))\n }\n if (packageJson.devDependencies?.[pkg]) {\n edits.push(...jsonc.modify(content, ['devDependencies', pkg], `^${version}`, {}))\n }\n }\n }\n\n if (edits.length > 0) {\n const modifiedContent = jsonc.applyEdits(content, edits)\n fs.writeFileSync(packageJsonPath, modifiedContent)\n console.log(green('✓'), 'Updated package.json')\n\n const packageManager = getPackageManager()\n console.log()\n console.log(cyan(`Installing dependencies with ${packageManager}...`))\n\n try {\n await runCommand(packageManager, [\n getInstallCommand(packageManager).split(' ')[1] || 'install',\n ])\n console.log()\n console.log(green('✓'), 'Dependencies updated successfully!')\n } catch {\n console.error(red('Error:'), 'Failed to install dependencies')\n console.log(\n yellow('Please run'),\n cyan(getInstallCommand(packageManager)),\n yellow('manually'),\n )\n }\n } else {\n console.log(green('✓'), 'All packages are already up to date!')\n }\n}\n\nasync function getLatestVersion(packageName: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const child = spawn('npm', ['view', packageName, 'version'], {\n stdio: ['ignore', 'pipe', 'ignore'],\n })\n\n let output = ''\n child.stdout?.on('data', (data) => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n output += data.toString()\n })\n\n child.on('close', (code) => {\n if (code !== 0) {\n reject(new Error(`Failed to fetch version for ${packageName}`))\n } else {\n resolve(output.trim())\n }\n })\n\n child.on('error', reject)\n })\n}\n","import minimist from 'minimist'\n\n// Command-specific argument interfaces\nexport interface BaseArgs {\n _: string[]\n help?: boolean\n}\n\nexport interface InitArgs extends BaseArgs {\n template?: string\n}\n\nexport type UpdateArgs = BaseArgs\n\nexport type CommandArgs = InitArgs | UpdateArgs\n\n// Command configurations for minimist\nconst COMMAND_CONFIGS: Record<string, minimist.Opts> = {\n init: {\n string: ['template'],\n alias: { t: 'template' },\n default: { template: 'quickstart' },\n },\n update: {\n // No special config needed\n },\n}\n\n/**\n * Parse command line arguments with command-specific configurations\n *\n * This function does a two-pass parse:\n * 1. First parse to identify the command\n * 2. Second parse with command-specific configuration\n *\n * This allows each command to have its own argument parsing rules,\n * preventing issues like hex addresses being converted to numbers.\n */\nexport function parseArgs(args: string[]): CommandArgs {\n // First, do a minimal parse to get the command\n const initial = minimist(args, {\n stopEarly: true,\n boolean: ['help'],\n alias: { h: 'help' },\n })\n\n const command = initial._[0]\n\n // If no command or help requested, return early\n if (!command || initial.help) {\n return initial as BaseArgs\n }\n\n // Get command-specific configuration\n const commandConfig = COMMAND_CONFIGS[command] || {}\n\n // Re-parse with command-specific configuration\n const booleanOptions = Array.isArray(commandConfig.boolean)\n ? ['help', ...commandConfig.boolean]\n : ['help']\n const parsed = minimist(args, {\n ...commandConfig,\n boolean: booleanOptions,\n alias: {\n ...commandConfig.alias,\n h: 'help',\n },\n })\n\n return parsed as CommandArgs\n}\n\n/**\n * Type guard functions for command-specific args\n */\nexport function isInitArgs(args: CommandArgs): args is InitArgs {\n return args._[0] === 'init'\n}\n\nexport function isUpdateArgs(args: CommandArgs): args is UpdateArgs {\n return args._[0] === 'update'\n}\n"],"mappings":"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","names":["green","red","yellow","cyan","fs","path","resolve","fs","path","spawn","red","yellow","cyan","jsonc","path","fs","red","yellow","cyan","resolve","spawn","red","cyan","yellow","green"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "towns-bot",
|
|
3
3
|
"description": "CLI for creating and managing Towns Protocol bot projects",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.383",
|
|
5
5
|
"author": "Towns Protocol",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "tsup",
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@bufbuild/protobuf": "^2.9.0",
|
|
16
16
|
"@connectrpc/connect-node": "^2.1.0",
|
|
17
|
-
"@towns-protocol/proto": "^0.0.
|
|
18
|
-
"@towns-protocol/sdk": "^0.0.
|
|
19
|
-
"@towns-protocol/utils": "^0.0.
|
|
17
|
+
"@towns-protocol/proto": "^0.0.383",
|
|
18
|
+
"@towns-protocol/sdk": "^0.0.383",
|
|
19
|
+
"@towns-protocol/utils": "^0.0.383",
|
|
20
20
|
"cross-spawn": "^7.0.5",
|
|
21
21
|
"dotenv": "^16.4.7",
|
|
22
22
|
"ethers": "^5.8.0",
|
|
@@ -57,5 +57,5 @@
|
|
|
57
57
|
"publishConfig": {
|
|
58
58
|
"access": "public"
|
|
59
59
|
},
|
|
60
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "7c6bb682702d1d6977ee42ce7d249c2bd4f62c85"
|
|
61
61
|
}
|