towns-bot 0.0.432 → 0.0.434

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 CHANGED
@@ -71,6 +71,18 @@ function getRunCommand(packageManager, script) {
71
71
  return `npm run ${script}`;
72
72
  }
73
73
  }
74
+ function getDlxCommand(packageManager) {
75
+ switch (packageManager) {
76
+ case "bun":
77
+ return "bunx";
78
+ case "yarn":
79
+ return "yarn dlx";
80
+ case "pnpm":
81
+ return "pnpm dlx";
82
+ default:
83
+ return "npx";
84
+ }
85
+ }
74
86
  function runCommand(command, args, opts = { cwd: void 0, silent: false }) {
75
87
  return new Promise((resolve2, reject) => {
76
88
  const child = (0, import_cross_spawn.default)(command, args, {
@@ -334,9 +346,20 @@ async function init(argv) {
334
346
  // src/modules/update.ts
335
347
  var import_fs = __toESM(require("fs"));
336
348
  var import_path = __toESM(require("path"));
337
- var import_cross_spawn2 = __toESM(require("cross-spawn"));
338
349
  var import_picocolors3 = require("picocolors");
339
- var jsonc2 = __toESM(require("jsonc-parser"));
350
+ function getTownsVersions(packageJson) {
351
+ const versions = {};
352
+ for (const deps of [packageJson.dependencies, packageJson.devDependencies]) {
353
+ if (deps) {
354
+ for (const [pkg, version] of Object.entries(deps)) {
355
+ if (pkg.startsWith("@towns-protocol/")) {
356
+ versions[pkg] = version;
357
+ }
358
+ }
359
+ }
360
+ }
361
+ return versions;
362
+ }
340
363
  async function update(_argv) {
341
364
  const packageJsonPath = import_path.default.join(process.cwd(), "package.json");
342
365
  if (!import_fs.default.existsSync(packageJsonPath)) {
@@ -344,90 +367,49 @@ async function update(_argv) {
344
367
  console.log((0, import_picocolors3.yellow)("Please run this command from a Towns Protocol bot project directory"));
345
368
  process.exit(1);
346
369
  }
347
- const packageJson = jsonc2.parse(import_fs.default.readFileSync(packageJsonPath, "utf-8"));
348
- const dependencies = { ...packageJson.dependencies, ...packageJson.devDependencies };
349
- const townsPackages = Object.keys(dependencies).filter(
350
- (pkg) => pkg.startsWith("@towns-protocol/")
351
- );
352
- if (townsPackages.length === 0) {
353
- console.log((0, import_picocolors3.yellow)("No @towns-protocol packages found in this project"));
354
- process.exit(0);
355
- }
356
- console.log((0, import_picocolors3.cyan)("Found Towns Protocol packages:"));
357
- townsPackages.forEach((pkg) => {
358
- console.log(` - ${pkg}@${dependencies[pkg]}`);
359
- });
360
- console.log();
361
- console.log((0, import_picocolors3.cyan)("Fetching latest versions..."));
362
- const latestVersions = {};
363
- for (const pkg of townsPackages) {
364
- try {
365
- const version = await getLatestVersion(pkg);
366
- latestVersions[pkg] = version;
367
- console.log((0, import_picocolors3.green)("\u2713"), `${pkg}: ${version}`);
368
- } catch {
369
- console.error((0, import_picocolors3.red)("\u2717"), `Failed to fetch version for ${pkg}`);
370
- }
371
- }
372
- console.log();
373
- console.log((0, import_picocolors3.cyan)("Updating package.json..."));
374
- const content = import_fs.default.readFileSync(packageJsonPath, "utf-8");
375
- const edits = [];
376
- for (const [pkg, version] of Object.entries(latestVersions)) {
377
- const currentVersion = dependencies[pkg];
378
- if (currentVersion !== `^${version}`) {
379
- if (packageJson.dependencies?.[pkg]) {
380
- edits.push(...jsonc2.modify(content, ["dependencies", pkg], `^${version}`, {}));
370
+ const packageManager = getPackageManager();
371
+ const dlxCommand = getDlxCommand(packageManager);
372
+ console.log((0, import_picocolors3.cyan)("Checking for @towns-protocol updates..."));
373
+ try {
374
+ const [dlxBin, ...dlxArgs] = dlxCommand.split(" ");
375
+ const packageJsonBefore = JSON.parse(import_fs.default.readFileSync(packageJsonPath, "utf-8"));
376
+ const versionsBefore = getTownsVersions(packageJsonBefore);
377
+ await runCommand(
378
+ dlxBin,
379
+ [...dlxArgs, "npm-check-updates", "-u", "-f", "@towns-protocol/*"],
380
+ {
381
+ silent: true
381
382
  }
382
- if (packageJson.devDependencies?.[pkg]) {
383
- edits.push(...jsonc2.modify(content, ["devDependencies", pkg], `^${version}`, {}));
383
+ );
384
+ const packageJsonAfter = JSON.parse(import_fs.default.readFileSync(packageJsonPath, "utf-8"));
385
+ const versionsAfter = getTownsVersions(packageJsonAfter);
386
+ const updates = [];
387
+ for (const [pkg, newVersion] of Object.entries(versionsAfter)) {
388
+ const oldVersion = versionsBefore[pkg];
389
+ if (oldVersion && oldVersion !== newVersion) {
390
+ updates.push({ package: pkg, from: oldVersion, to: newVersion });
384
391
  }
385
392
  }
386
- }
387
- if (edits.length > 0) {
388
- const modifiedContent = jsonc2.applyEdits(content, edits);
389
- import_fs.default.writeFileSync(packageJsonPath, modifiedContent);
390
- console.log((0, import_picocolors3.green)("\u2713"), "Updated package.json");
391
- const packageManager = getPackageManager();
393
+ if (updates.length === 0) {
394
+ console.log((0, import_picocolors3.green)("\u2713"), "All @towns-protocol packages are up to date!");
395
+ return;
396
+ }
392
397
  console.log();
393
- console.log((0, import_picocolors3.cyan)(`Installing dependencies with ${packageManager}...`));
394
- try {
395
- await runCommand(packageManager, [
396
- getInstallCommand(packageManager).split(" ")[1] || "install"
397
- ]);
398
- console.log();
399
- console.log((0, import_picocolors3.green)("\u2713"), "Dependencies updated successfully!");
400
- } catch {
401
- console.error((0, import_picocolors3.red)("Error:"), "Failed to install dependencies");
402
- console.log(
403
- (0, import_picocolors3.yellow)("Please run"),
404
- (0, import_picocolors3.cyan)(getInstallCommand(packageManager)),
405
- (0, import_picocolors3.yellow)("manually")
406
- );
398
+ for (const update2 of updates) {
399
+ console.log((0, import_picocolors3.green)("\u2713"), `${update2.package} ${update2.from} \u2192 ${update2.to}`);
407
400
  }
408
- } else {
409
- console.log((0, import_picocolors3.green)("\u2713"), "All packages are already up to date!");
401
+ console.log();
402
+ console.log((0, import_picocolors3.cyan)(`Installing dependencies with ${packageManager}...`));
403
+ const installCmd = getInstallCommand(packageManager);
404
+ const [installBin, ...installArgs] = installCmd.split(" ");
405
+ await runCommand(installBin, installArgs.length > 0 ? installArgs : []);
406
+ console.log();
407
+ console.log((0, import_picocolors3.green)("\u2713"), "Dependencies updated successfully!");
408
+ } catch {
409
+ console.error((0, import_picocolors3.red)("Error:"), "Failed to update dependencies");
410
+ process.exit(1);
410
411
  }
411
412
  }
412
- async function getLatestVersion(packageName) {
413
- return new Promise((resolve2, reject) => {
414
- const child = (0, import_cross_spawn2.default)("npm", ["view", packageName, "version"], {
415
- stdio: ["ignore", "pipe", "ignore"]
416
- });
417
- let output = "";
418
- child.stdout?.on("data", (data) => {
419
- output += data.toString();
420
- });
421
- child.on("close", (code) => {
422
- if (code !== 0) {
423
- reject(new Error(`Failed to fetch version for ${packageName}`));
424
- } else {
425
- resolve2(output.trim());
426
- }
427
- });
428
- child.on("error", reject);
429
- });
430
- }
431
413
 
432
414
  // src/parser.ts
433
415
  var import_minimist = __toESM(require("minimist"));
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/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":["import_picocolors","fs","path","import_picocolors","resolve","spawn","spawn","picocolors","prompts","import_cross_spawn","import_picocolors","jsonc","path","fs","resolve","spawn","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 getDlxCommand(packageManager: string): string {\n switch (packageManager) {\n case 'bun':\n return 'bunx'\n case 'yarn':\n return 'yarn dlx'\n case 'pnpm':\n return 'pnpm dlx'\n default:\n return 'npx'\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 function runCommandWithOutput(\n command: string,\n args: string[],\n opts: { cwd?: string } = {},\n): Promise<string> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n stdio: ['ignore', 'pipe', 'pipe'],\n cwd: opts.cwd,\n shell: process.platform === 'win32',\n })\n\n let stdout = ''\n let stderr = ''\n\n child.stdout?.on('data', (data: Buffer) => {\n stdout += data.toString()\n })\n\n child.stderr?.on('data', (data: Buffer) => {\n stderr += data.toString()\n })\n\n child.on('close', (code) => {\n if (code !== 0) {\n reject(new Error(stderr || `Command failed with exit code ${code}`))\n } else {\n resolve(stdout)\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 { green, red, yellow, cyan } from 'picocolors'\nimport { getPackageManager, getInstallCommand, getDlxCommand, runCommand } from './utils.js'\nimport type { UpdateArgs } from '../parser.js'\n\ninterface PackageJson {\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n}\n\ninterface VersionUpdate {\n package: string\n from: string\n to: string\n}\n\nfunction getTownsVersions(packageJson: PackageJson): Record<string, string> {\n const versions: Record<string, string> = {}\n for (const deps of [packageJson.dependencies, packageJson.devDependencies]) {\n if (deps) {\n for (const [pkg, version] of Object.entries(deps)) {\n if (pkg.startsWith('@towns-protocol/')) {\n versions[pkg] = version\n }\n }\n }\n }\n return versions\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 packageManager = getPackageManager()\n const dlxCommand = getDlxCommand(packageManager)\n\n console.log(cyan('Checking for @towns-protocol updates...'))\n\n try {\n const [dlxBin, ...dlxArgs] = dlxCommand.split(' ')\n\n const packageJsonBefore: PackageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))\n const versionsBefore = getTownsVersions(packageJsonBefore)\n\n await runCommand(\n dlxBin,\n [...dlxArgs, 'npm-check-updates', '-u', '-f', '@towns-protocol/*'],\n {\n silent: true,\n },\n )\n\n const packageJsonAfter: PackageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))\n const versionsAfter = getTownsVersions(packageJsonAfter)\n\n const updates: VersionUpdate[] = []\n for (const [pkg, newVersion] of Object.entries(versionsAfter)) {\n const oldVersion = versionsBefore[pkg]\n if (oldVersion && oldVersion !== newVersion) {\n updates.push({ package: pkg, from: oldVersion, to: newVersion })\n }\n }\n\n if (updates.length === 0) {\n console.log(green('✓'), 'All @towns-protocol packages are up to date!')\n return\n }\n\n console.log()\n for (const update of updates) {\n console.log(green('✓'), `${update.package} ${update.from} → ${update.to}`)\n }\n\n console.log()\n console.log(cyan(`Installing dependencies with ${packageManager}...`))\n const installCmd = getInstallCommand(packageManager)\n const [installBin, ...installArgs] = installCmd.split(' ')\n await runCommand(installBin, installArgs.length > 0 ? installArgs : [])\n\n console.log()\n console.log(green('✓'), 'Dependencies updated successfully!')\n } catch {\n console.error(red('Error:'), 'Failed to update dependencies')\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 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":["import_picocolors","fs","path","import_picocolors","resolve","spawn","resolve","spawn","spawn","picocolors","prompts","import_picocolors","path","fs","update","minimist"]}
package/dist/index.mjs CHANGED
@@ -47,6 +47,18 @@ function getRunCommand(packageManager, script) {
47
47
  return `npm run ${script}`;
48
48
  }
49
49
  }
50
+ function getDlxCommand(packageManager) {
51
+ switch (packageManager) {
52
+ case "bun":
53
+ return "bunx";
54
+ case "yarn":
55
+ return "yarn dlx";
56
+ case "pnpm":
57
+ return "pnpm dlx";
58
+ default:
59
+ return "npx";
60
+ }
61
+ }
50
62
  function runCommand(command, args, opts = { cwd: void 0, silent: false }) {
51
63
  return new Promise((resolve2, reject) => {
52
64
  const child = spawn(command, args, {
@@ -310,9 +322,20 @@ async function init(argv) {
310
322
  // src/modules/update.ts
311
323
  import fs3 from "fs";
312
324
  import path3 from "path";
313
- import { default as spawn2 } from "cross-spawn";
314
325
  import { green, red as red2, yellow as yellow2, cyan as cyan2 } from "picocolors";
315
- import * as jsonc2 from "jsonc-parser";
326
+ function getTownsVersions(packageJson) {
327
+ const versions = {};
328
+ for (const deps of [packageJson.dependencies, packageJson.devDependencies]) {
329
+ if (deps) {
330
+ for (const [pkg, version] of Object.entries(deps)) {
331
+ if (pkg.startsWith("@towns-protocol/")) {
332
+ versions[pkg] = version;
333
+ }
334
+ }
335
+ }
336
+ }
337
+ return versions;
338
+ }
316
339
  async function update(_argv) {
317
340
  const packageJsonPath = path3.join(process.cwd(), "package.json");
318
341
  if (!fs3.existsSync(packageJsonPath)) {
@@ -320,90 +343,49 @@ async function update(_argv) {
320
343
  console.log(yellow2("Please run this command from a Towns Protocol bot project directory"));
321
344
  process.exit(1);
322
345
  }
323
- const packageJson = jsonc2.parse(fs3.readFileSync(packageJsonPath, "utf-8"));
324
- const dependencies = { ...packageJson.dependencies, ...packageJson.devDependencies };
325
- const townsPackages = Object.keys(dependencies).filter(
326
- (pkg) => pkg.startsWith("@towns-protocol/")
327
- );
328
- if (townsPackages.length === 0) {
329
- console.log(yellow2("No @towns-protocol packages found in this project"));
330
- process.exit(0);
331
- }
332
- console.log(cyan2("Found Towns Protocol packages:"));
333
- townsPackages.forEach((pkg) => {
334
- console.log(` - ${pkg}@${dependencies[pkg]}`);
335
- });
336
- console.log();
337
- console.log(cyan2("Fetching latest versions..."));
338
- const latestVersions = {};
339
- for (const pkg of townsPackages) {
340
- try {
341
- const version = await getLatestVersion(pkg);
342
- latestVersions[pkg] = version;
343
- console.log(green("\u2713"), `${pkg}: ${version}`);
344
- } catch {
345
- console.error(red2("\u2717"), `Failed to fetch version for ${pkg}`);
346
- }
347
- }
348
- console.log();
349
- console.log(cyan2("Updating package.json..."));
350
- const content = fs3.readFileSync(packageJsonPath, "utf-8");
351
- const edits = [];
352
- for (const [pkg, version] of Object.entries(latestVersions)) {
353
- const currentVersion = dependencies[pkg];
354
- if (currentVersion !== `^${version}`) {
355
- if (packageJson.dependencies?.[pkg]) {
356
- edits.push(...jsonc2.modify(content, ["dependencies", pkg], `^${version}`, {}));
346
+ const packageManager = getPackageManager();
347
+ const dlxCommand = getDlxCommand(packageManager);
348
+ console.log(cyan2("Checking for @towns-protocol updates..."));
349
+ try {
350
+ const [dlxBin, ...dlxArgs] = dlxCommand.split(" ");
351
+ const packageJsonBefore = JSON.parse(fs3.readFileSync(packageJsonPath, "utf-8"));
352
+ const versionsBefore = getTownsVersions(packageJsonBefore);
353
+ await runCommand(
354
+ dlxBin,
355
+ [...dlxArgs, "npm-check-updates", "-u", "-f", "@towns-protocol/*"],
356
+ {
357
+ silent: true
357
358
  }
358
- if (packageJson.devDependencies?.[pkg]) {
359
- edits.push(...jsonc2.modify(content, ["devDependencies", pkg], `^${version}`, {}));
359
+ );
360
+ const packageJsonAfter = JSON.parse(fs3.readFileSync(packageJsonPath, "utf-8"));
361
+ const versionsAfter = getTownsVersions(packageJsonAfter);
362
+ const updates = [];
363
+ for (const [pkg, newVersion] of Object.entries(versionsAfter)) {
364
+ const oldVersion = versionsBefore[pkg];
365
+ if (oldVersion && oldVersion !== newVersion) {
366
+ updates.push({ package: pkg, from: oldVersion, to: newVersion });
360
367
  }
361
368
  }
362
- }
363
- if (edits.length > 0) {
364
- const modifiedContent = jsonc2.applyEdits(content, edits);
365
- fs3.writeFileSync(packageJsonPath, modifiedContent);
366
- console.log(green("\u2713"), "Updated package.json");
367
- const packageManager = getPackageManager();
369
+ if (updates.length === 0) {
370
+ console.log(green("\u2713"), "All @towns-protocol packages are up to date!");
371
+ return;
372
+ }
368
373
  console.log();
369
- console.log(cyan2(`Installing dependencies with ${packageManager}...`));
370
- try {
371
- await runCommand(packageManager, [
372
- getInstallCommand(packageManager).split(" ")[1] || "install"
373
- ]);
374
- console.log();
375
- console.log(green("\u2713"), "Dependencies updated successfully!");
376
- } catch {
377
- console.error(red2("Error:"), "Failed to install dependencies");
378
- console.log(
379
- yellow2("Please run"),
380
- cyan2(getInstallCommand(packageManager)),
381
- yellow2("manually")
382
- );
374
+ for (const update2 of updates) {
375
+ console.log(green("\u2713"), `${update2.package} ${update2.from} \u2192 ${update2.to}`);
383
376
  }
384
- } else {
385
- console.log(green("\u2713"), "All packages are already up to date!");
377
+ console.log();
378
+ console.log(cyan2(`Installing dependencies with ${packageManager}...`));
379
+ const installCmd = getInstallCommand(packageManager);
380
+ const [installBin, ...installArgs] = installCmd.split(" ");
381
+ await runCommand(installBin, installArgs.length > 0 ? installArgs : []);
382
+ console.log();
383
+ console.log(green("\u2713"), "Dependencies updated successfully!");
384
+ } catch {
385
+ console.error(red2("Error:"), "Failed to update dependencies");
386
+ process.exit(1);
386
387
  }
387
388
  }
388
- async function getLatestVersion(packageName) {
389
- return new Promise((resolve2, reject) => {
390
- const child = spawn2("npm", ["view", packageName, "version"], {
391
- stdio: ["ignore", "pipe", "ignore"]
392
- });
393
- let output = "";
394
- child.stdout?.on("data", (data) => {
395
- output += data.toString();
396
- });
397
- child.on("close", (code) => {
398
- if (code !== 0) {
399
- reject(new Error(`Failed to fetch version for ${packageName}`));
400
- } else {
401
- resolve2(output.trim());
402
- }
403
- });
404
- child.on("error", reject);
405
- });
406
- }
407
389
 
408
390
  // src/parser.ts
409
391
  import minimist from "minimist";
@@ -1 +1 @@
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"]}
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 getDlxCommand(packageManager: string): string {\n switch (packageManager) {\n case 'bun':\n return 'bunx'\n case 'yarn':\n return 'yarn dlx'\n case 'pnpm':\n return 'pnpm dlx'\n default:\n return 'npx'\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 function runCommandWithOutput(\n command: string,\n args: string[],\n opts: { cwd?: string } = {},\n): Promise<string> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n stdio: ['ignore', 'pipe', 'pipe'],\n cwd: opts.cwd,\n shell: process.platform === 'win32',\n })\n\n let stdout = ''\n let stderr = ''\n\n child.stdout?.on('data', (data: Buffer) => {\n stdout += data.toString()\n })\n\n child.stderr?.on('data', (data: Buffer) => {\n stderr += data.toString()\n })\n\n child.on('close', (code) => {\n if (code !== 0) {\n reject(new Error(stderr || `Command failed with exit code ${code}`))\n } else {\n resolve(stdout)\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 { green, red, yellow, cyan } from 'picocolors'\nimport { getPackageManager, getInstallCommand, getDlxCommand, runCommand } from './utils.js'\nimport type { UpdateArgs } from '../parser.js'\n\ninterface PackageJson {\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n}\n\ninterface VersionUpdate {\n package: string\n from: string\n to: string\n}\n\nfunction getTownsVersions(packageJson: PackageJson): Record<string, string> {\n const versions: Record<string, string> = {}\n for (const deps of [packageJson.dependencies, packageJson.devDependencies]) {\n if (deps) {\n for (const [pkg, version] of Object.entries(deps)) {\n if (pkg.startsWith('@towns-protocol/')) {\n versions[pkg] = version\n }\n }\n }\n }\n return versions\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 packageManager = getPackageManager()\n const dlxCommand = getDlxCommand(packageManager)\n\n console.log(cyan('Checking for @towns-protocol updates...'))\n\n try {\n const [dlxBin, ...dlxArgs] = dlxCommand.split(' ')\n\n const packageJsonBefore: PackageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))\n const versionsBefore = getTownsVersions(packageJsonBefore)\n\n await runCommand(\n dlxBin,\n [...dlxArgs, 'npm-check-updates', '-u', '-f', '@towns-protocol/*'],\n {\n silent: true,\n },\n )\n\n const packageJsonAfter: PackageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))\n const versionsAfter = getTownsVersions(packageJsonAfter)\n\n const updates: VersionUpdate[] = []\n for (const [pkg, newVersion] of Object.entries(versionsAfter)) {\n const oldVersion = versionsBefore[pkg]\n if (oldVersion && oldVersion !== newVersion) {\n updates.push({ package: pkg, from: oldVersion, to: newVersion })\n }\n }\n\n if (updates.length === 0) {\n console.log(green('✓'), 'All @towns-protocol packages are up to date!')\n return\n }\n\n console.log()\n for (const update of updates) {\n console.log(green('✓'), `${update.package} ${update.from} → ${update.to}`)\n }\n\n console.log()\n console.log(cyan(`Installing dependencies with ${packageManager}...`))\n const installCmd = getInstallCommand(packageManager)\n const [installBin, ...installArgs] = installCmd.split(' ')\n await runCommand(installBin, installArgs.length > 0 ? installArgs : [])\n\n console.log()\n console.log(green('✓'), 'Dependencies updated successfully!')\n } catch {\n console.error(red('Error:'), 'Failed to update dependencies')\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 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","resolve","fs","path","red","yellow","cyan","path","fs","red","yellow","cyan","update","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.432",
4
+ "version": "0.0.434",
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.432",
18
- "@towns-protocol/sdk": "^0.0.432",
19
- "@towns-protocol/utils": "^0.0.432",
17
+ "@towns-protocol/proto": "^0.0.434",
18
+ "@towns-protocol/sdk": "^0.0.434",
19
+ "@towns-protocol/utils": "^0.0.434",
20
20
  "cross-spawn": "^7.0.5",
21
21
  "dotenv": "^17.2.3",
22
22
  "ethers": "^5.8.0",
@@ -57,5 +57,5 @@
57
57
  "publishConfig": {
58
58
  "access": "public"
59
59
  },
60
- "gitHead": "aed1393cc61f669c852b2d244630e27ae27a5922"
60
+ "gitHead": "29fca5be72f7f98c7410d3f9d6d5428350822fab"
61
61
  }