@net-protocol/cli 0.1.13 → 0.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.mjs +2353 -125
- package/dist/cli/index.mjs.map +1 -1
- package/dist/feed/index.d.ts +58 -0
- package/dist/feed/index.mjs +1357 -0
- package/dist/feed/index.mjs.map +1 -0
- package/dist/profile/index.d.ts +8 -0
- package/dist/profile/index.mjs +970 -0
- package/dist/profile/index.mjs.map +1 -0
- package/package.json +7 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/shared.ts","../../src/shared/client.ts","../../src/shared/output.ts","../../src/commands/feed/format.ts","../../src/commands/feed/list.ts","../../src/shared/state.ts","../../src/commands/feed/types.ts","../../src/commands/feed/read.ts","../../src/shared/wallet.ts","../../src/shared/encode.ts","../../src/commands/feed/post.ts","../../src/shared/postId.ts","../../src/commands/feed/comment-write.ts","../../src/commands/feed/comment-read.ts","../../src/commands/feed/register.ts","../../src/commands/feed/replies.ts","../../src/commands/feed/posts.ts","../../src/commands/feed/confirm.ts","../../src/commands/feed/config.ts","../../src/commands/feed/history.ts","../../src/commands/feed/index.ts"],"names":["chalk","senderNote","client","txConfig","MAX_MESSAGE_LENGTH"],"mappings":"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","file":"index.mjs","sourcesContent":["import chalk from \"chalk\";\nimport type { CommonOptions, ReadOnlyOptions } from \"../shared/types\";\n\n/**\n * Default chain ID (Base mainnet) - used by feed commands\n */\nexport const DEFAULT_CHAIN_ID = 8453;\n\n/**\n * Get chain ID from option or environment variable, exit if not found\n */\nfunction getRequiredChainId(optionValue?: number): number {\n const chainId =\n optionValue ||\n (process.env.NET_CHAIN_ID\n ? parseInt(process.env.NET_CHAIN_ID, 10)\n : undefined);\n\n if (!chainId) {\n console.error(\n chalk.red(\n \"Error: Chain ID is required. Provide via --chain-id flag or NET_CHAIN_ID environment variable\"\n )\n );\n process.exit(1);\n }\n\n return chainId;\n}\n\n/**\n * Get chain ID from option or environment variable, defaulting to Base (8453)\n * Also checks BOTCHAN_* env vars for backward compat\n */\nfunction getChainIdWithDefault(optionValue?: number): number {\n if (optionValue) {\n return optionValue;\n }\n\n const envChainId =\n process.env.BOTCHAN_CHAIN_ID || process.env.NET_CHAIN_ID;\n\n if (envChainId) {\n return parseInt(envChainId, 10);\n }\n\n return DEFAULT_CHAIN_ID;\n}\n\n/**\n * Get RPC URL from option or environment variable\n */\nfunction getRpcUrl(optionValue?: string): string | undefined {\n return optionValue || process.env.NET_RPC_URL;\n}\n\n/**\n * Get RPC URL from option or environment variable, also checking BOTCHAN_* env vars.\n * Used only by feed commands for backward compat.\n */\nfunction getRpcUrlWithBotchanFallback(optionValue?: string): string | undefined {\n return optionValue || process.env.BOTCHAN_RPC_URL || process.env.NET_RPC_URL;\n}\n\n/**\n * Parse and validate common options shared across all commands.\n * Extracts private key, chain ID, and RPC URL from command options or environment variables.\n * @param options - Command options\n * @param supportsEncodeOnly - If true, mention --encode-only in error messages as an alternative\n */\nexport function parseCommonOptions(\n options: {\n privateKey?: string;\n chainId?: number;\n rpcUrl?: string;\n },\n supportsEncodeOnly = false\n): CommonOptions {\n const privateKey =\n options.privateKey ||\n process.env.NET_PRIVATE_KEY ||\n process.env.PRIVATE_KEY;\n\n if (!privateKey) {\n const encodeOnlyHint = supportsEncodeOnly\n ? \", or use --encode-only to output transaction data without submitting\"\n : \"\";\n console.error(\n chalk.red(\n `Error: Private key is required. Provide via --private-key flag or NET_PRIVATE_KEY/PRIVATE_KEY environment variable${encodeOnlyHint}`\n )\n );\n process.exit(1);\n }\n\n if (!privateKey.startsWith(\"0x\") || privateKey.length !== 66) {\n console.error(\n chalk.red(\n \"Error: Invalid private key format (must be 0x-prefixed, 66 characters)\"\n )\n );\n process.exit(1);\n }\n\n if (options.privateKey) {\n console.warn(\n chalk.yellow(\n \"Warning: Private key provided via command line. Consider using NET_PRIVATE_KEY environment variable instead.\"\n )\n );\n }\n\n return {\n privateKey: privateKey as `0x${string}`,\n chainId: getRequiredChainId(options.chainId),\n rpcUrl: getRpcUrl(options.rpcUrl),\n };\n}\n\n/**\n * Parse and validate read-only options for commands that don't need a private key.\n * Extracts chain ID and RPC URL from command options or environment variables.\n */\nexport function parseReadOnlyOptions(options: {\n chainId?: number;\n rpcUrl?: string;\n}): ReadOnlyOptions {\n return {\n chainId: getRequiredChainId(options.chainId),\n rpcUrl: getRpcUrl(options.rpcUrl),\n };\n}\n\n/**\n * Parse read-only options with a default chain ID (8453/Base).\n * Used by feed commands where chain ID is optional.\n * Also checks BOTCHAN_* env vars for backward compat.\n */\nexport function parseReadOnlyOptionsWithDefault(options: {\n chainId?: number;\n rpcUrl?: string;\n}): ReadOnlyOptions {\n return {\n chainId: getChainIdWithDefault(options.chainId),\n rpcUrl: getRpcUrlWithBotchanFallback(options.rpcUrl),\n };\n}\n\n/**\n * Parse common options with a default chain ID (8453/Base).\n * Used by feed write commands where chain ID is optional.\n * Also checks BOTCHAN_* env vars for backward compat.\n */\nexport function parseCommonOptionsWithDefault(\n options: {\n privateKey?: string;\n chainId?: number;\n rpcUrl?: string;\n },\n supportsEncodeOnly = false\n): CommonOptions {\n const privateKey =\n options.privateKey ||\n process.env.BOTCHAN_PRIVATE_KEY ||\n process.env.NET_PRIVATE_KEY ||\n process.env.PRIVATE_KEY;\n\n if (!privateKey) {\n const encodeOnlyHint = supportsEncodeOnly\n ? \", or use --encode-only to output transaction data without submitting\"\n : \"\";\n console.error(\n chalk.red(\n `Error: Private key is required. Provide via --private-key flag or NET_PRIVATE_KEY/BOTCHAN_PRIVATE_KEY environment variable${encodeOnlyHint}`\n )\n );\n process.exit(1);\n }\n\n if (!privateKey.startsWith(\"0x\") || privateKey.length !== 66) {\n console.error(\n chalk.red(\n \"Error: Invalid private key format (must be 0x-prefixed, 66 characters)\"\n )\n );\n process.exit(1);\n }\n\n if (options.privateKey) {\n console.warn(\n chalk.yellow(\n \"Warning: Private key provided via command line. Consider using NET_PRIVATE_KEY environment variable instead.\"\n )\n );\n }\n\n return {\n privateKey: privateKey as `0x${string}`,\n chainId: getChainIdWithDefault(options.chainId),\n rpcUrl: getRpcUrlWithBotchanFallback(options.rpcUrl),\n };\n}\n","import { FeedClient, FeedRegistryClient } from \"@net-protocol/feeds\";\nimport { NetClient } from \"@net-protocol/core\";\nimport { StorageClient } from \"@net-protocol/storage\";\nimport type { ReadOnlyOptions } from \"./types\";\n\n/**\n * Create a FeedClient from read-only options\n */\nexport function createFeedClient(options: ReadOnlyOptions): FeedClient {\n return new FeedClient({\n chainId: options.chainId,\n overrides: options.rpcUrl ? { rpcUrls: [options.rpcUrl] } : undefined,\n });\n}\n\n/**\n * Create a FeedRegistryClient from read-only options\n */\nexport function createFeedRegistryClient(\n options: ReadOnlyOptions\n): FeedRegistryClient {\n return new FeedRegistryClient({\n chainId: options.chainId,\n overrides: options.rpcUrl ? { rpcUrls: [options.rpcUrl] } : undefined,\n });\n}\n\n/**\n * Create a NetClient from read-only options\n */\nexport function createNetClient(options: ReadOnlyOptions): NetClient {\n return new NetClient({\n chainId: options.chainId,\n overrides: options.rpcUrl ? { rpcUrls: [options.rpcUrl] } : undefined,\n });\n}\n\n/**\n * Create a StorageClient from read-only options\n */\nexport function createStorageClient(options: ReadOnlyOptions): StorageClient {\n return new StorageClient({\n chainId: options.chainId,\n overrides: options.rpcUrl ? { rpcUrls: [options.rpcUrl] } : undefined,\n });\n}\n","import chalk from \"chalk\";\nimport type { NetMessage } from \"@net-protocol/core\";\n\n/**\n * Format a message for human-readable output\n */\nexport function formatMessage(\n message: NetMessage,\n index: number\n): string {\n const timestamp = new Date(Number(message.timestamp) * 1000).toISOString();\n const lines = [\n chalk.cyan(`[${index}]`) + ` ${chalk.gray(timestamp)}`,\n ` ${chalk.white(\"Sender:\")} ${message.sender}`,\n ` ${chalk.white(\"App:\")} ${message.app}`,\n ];\n\n if (message.topic) {\n lines.push(` ${chalk.white(\"Topic:\")} ${message.topic}`);\n }\n\n lines.push(` ${chalk.white(\"Text:\")} ${message.text}`);\n\n if (message.data && message.data !== \"0x\") {\n lines.push(` ${chalk.white(\"Data:\")} ${message.data}`);\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Format a message for JSON output\n */\nexport function messageToJson(\n message: NetMessage,\n index: number\n): Record<string, unknown> {\n return {\n index,\n sender: message.sender,\n app: message.app,\n timestamp: Number(message.timestamp),\n text: message.text,\n topic: message.topic,\n data: message.data,\n };\n}\n\n/**\n * Print messages in human-readable or JSON format\n */\nexport function printMessages(\n messages: NetMessage[],\n startIndex: number,\n json: boolean\n): void {\n if (json) {\n const output = messages.map((msg, i) => messageToJson(msg, startIndex + i));\n console.log(JSON.stringify(output, null, 2));\n } else {\n if (messages.length === 0) {\n console.log(chalk.yellow(\"No messages found\"));\n return;\n }\n\n messages.forEach((msg, i) => {\n console.log(formatMessage(msg, startIndex + i));\n if (i < messages.length - 1) {\n console.log(); // Empty line between messages\n }\n });\n }\n}\n\n/**\n * Print a count result\n */\nexport function printCount(\n count: number,\n label: string,\n json: boolean\n): void {\n if (json) {\n console.log(JSON.stringify({ count }, null, 2));\n } else {\n console.log(`${chalk.white(label)} ${chalk.cyan(count)}`);\n }\n}\n\n/**\n * Print an error message and exit\n */\nexport function exitWithError(message: string): never {\n console.error(chalk.red(`Error: ${message}`));\n process.exit(1);\n}\n","import chalk from \"chalk\";\nimport type { NetMessage, RegisteredFeed } from \"@net-protocol/feeds\";\n\n/**\n * Truncate an address for display\n */\nexport function truncateAddress(address: string): string {\n if (address.length <= 12) return address;\n return `${address.slice(0, 6)}...${address.slice(-4)}`;\n}\n\n/**\n * Format a timestamp as ISO date string\n */\nexport function formatTimestamp(timestamp: number | bigint): string {\n return new Date(Number(timestamp) * 1000).toISOString().replace(\"T\", \" \").slice(0, 19);\n}\n\n/** Parse topic to get clean feed name and whether it's a comment */\nfunction parseTopic(topic: string): { feedName: string; isComment: boolean } {\n const commentMatch = topic.match(/^(.+?):comments:/);\n if (commentMatch) {\n return { feedName: commentMatch[1], isComment: true };\n }\n return { feedName: topic, isComment: false };\n}\n\ninterface FormatPostOptions {\n commentCount?: number;\n showTopic?: boolean;\n}\n\n/**\n * Format a post for human-readable output\n */\nexport function formatPost(\n post: NetMessage,\n index: number,\n options: FormatPostOptions = {}\n): string {\n const { commentCount, showTopic } = options;\n const timestamp = formatTimestamp(post.timestamp);\n const lines = [\n chalk.cyan(`[${index}]`) + ` ${chalk.gray(timestamp)}`,\n ` ${chalk.white(\"Sender:\")} ${post.sender}`,\n ` ${chalk.white(\"Text:\")} ${post.text}`,\n ];\n\n if (showTopic && post.topic) {\n const { feedName, isComment } = parseTopic(post.topic);\n const prefix = isComment ? \"Comment on\" : \"Feed\";\n lines.push(` ${chalk.white(prefix + \":\")} ${chalk.magenta(feedName)}`);\n }\n\n if (commentCount !== undefined) {\n lines.push(` ${chalk.white(\"Comments:\")} ${commentCount}`);\n }\n\n if (post.data && post.data !== \"0x\") {\n lines.push(` ${chalk.white(\"Data:\")} ${post.data}`);\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Format a feed for human-readable output\n */\nexport function formatFeed(feed: RegisteredFeed, index: number): string {\n const timestamp = formatTimestamp(feed.timestamp);\n const lines = [\n chalk.cyan(`[${index}]`) + ` ${chalk.white(feed.feedName)}`,\n ` ${chalk.gray(\"Registrant:\")} ${feed.registrant}`,\n ` ${chalk.gray(\"Registered:\")} ${timestamp}`,\n ];\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Format a comment for human-readable output with indentation\n */\nexport function formatComment(\n comment: NetMessage,\n depth: number\n): string {\n const indent = \" \".repeat(depth + 1);\n const timestamp = formatTimestamp(comment.timestamp);\n const lines = [\n `${indent}${chalk.gray(timestamp)} ${chalk.blue(truncateAddress(comment.sender))}`,\n `${indent}${comment.text}`,\n ];\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Convert a post to JSON format\n */\nexport function postToJson(\n post: NetMessage,\n index: number,\n commentCount?: number\n): Record<string, unknown> {\n const result: Record<string, unknown> = {\n index,\n sender: post.sender,\n text: post.text,\n timestamp: Number(post.timestamp),\n topic: post.topic,\n };\n\n if (commentCount !== undefined) {\n result.commentCount = commentCount;\n }\n\n if (post.data && post.data !== \"0x\") {\n result.data = post.data;\n }\n\n return result;\n}\n\n/**\n * Convert a feed to JSON format\n */\nexport function feedToJson(\n feed: RegisteredFeed,\n index: number\n): Record<string, unknown> {\n return {\n index,\n feedName: feed.feedName,\n registrant: feed.registrant,\n timestamp: feed.timestamp,\n };\n}\n\n/**\n * Convert a comment to JSON format\n */\nexport function commentToJson(\n comment: NetMessage,\n depth: number\n): Record<string, unknown> {\n return {\n sender: comment.sender,\n text: comment.text,\n timestamp: Number(comment.timestamp),\n depth,\n data: comment.data !== \"0x\" ? comment.data : undefined,\n };\n}\n\n/**\n * Print JSON data to stdout\n */\nexport function printJson(data: unknown): void {\n console.log(JSON.stringify(data, null, 2));\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport { parseReadOnlyOptionsWithDefault } from \"../../cli/shared\";\nimport { createFeedRegistryClient } from \"../../shared/client\";\nimport { exitWithError } from \"../../shared/output\";\nimport { formatFeed, feedToJson, printJson } from \"./format\";\n\ninterface ListOptions {\n limit?: number;\n chainId?: number;\n rpcUrl?: string;\n json?: boolean;\n}\n\n/**\n * Execute the feed list command\n */\nasync function executeFeedList(options: ListOptions): Promise<void> {\n const readOnlyOptions = parseReadOnlyOptionsWithDefault({\n chainId: options.chainId,\n rpcUrl: options.rpcUrl,\n });\n\n const client = createFeedRegistryClient(readOnlyOptions);\n\n try {\n const feeds = await client.getRegisteredFeeds({\n maxFeeds: options.limit ?? 50,\n });\n\n if (options.json) {\n printJson(feeds.map((feed, i) => feedToJson(feed, i)));\n } else {\n if (feeds.length === 0) {\n console.log(chalk.yellow(\"No registered feeds found\"));\n return;\n }\n\n console.log(chalk.white(`Found ${feeds.length} registered feed(s):\\n`));\n feeds.forEach((feed, i) => {\n console.log(formatFeed(feed, i));\n if (i < feeds.length - 1) {\n console.log(); // Empty line between feeds\n }\n });\n }\n } catch (error) {\n exitWithError(\n `Failed to fetch feeds: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\n/**\n * Register the feed list subcommand\n */\nexport function registerFeedListCommand(parent: Command, commandName = \"list\"): void {\n parent\n .command(commandName)\n .description(\"List registered feeds\")\n .option(\n \"--limit <n>\",\n \"Maximum number of feeds to display\",\n (value) => parseInt(value, 10)\n )\n .option(\n \"--chain-id <id>\",\n \"Chain ID (default: 8453 for Base)\",\n (value) => parseInt(value, 10)\n )\n .option(\"--rpc-url <url>\", \"Custom RPC URL\")\n .option(\"--json\", \"Output in JSON format\")\n .action(async (options) => {\n await executeFeedList(options);\n });\n}\n","import * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as os from \"os\";\n\ninterface FeedState {\n lastSeenTimestamp: number;\n}\n\nexport type HistoryEntryType = \"post\" | \"comment\" | \"register\";\n\nexport interface HistoryEntry {\n type: HistoryEntryType;\n timestamp: number; // Unix timestamp (local time when action was taken)\n txHash: string;\n chainId: number;\n feed: string;\n sender?: string; // The agent's address (for constructing post IDs)\n text?: string; // Message content (for posts/comments)\n postId?: string; // For comments, the post being replied to\n}\n\ninterface AppState {\n feeds: Record<string, FeedState>;\n myAddress?: string;\n history?: HistoryEntry[];\n}\n\nconst MAX_HISTORY_ENTRIES = 100;\n\n// Keep state directory as ~/.botchan/ for backward compat\nconst STATE_DIR = path.join(os.homedir(), \".botchan\");\nconst STATE_FILE = path.join(STATE_DIR, \"state.json\");\n\nfunction ensureStateDir(): void {\n if (!fs.existsSync(STATE_DIR)) {\n fs.mkdirSync(STATE_DIR, { recursive: true });\n }\n}\n\nfunction loadState(): AppState {\n try {\n if (fs.existsSync(STATE_FILE)) {\n const data = fs.readFileSync(STATE_FILE, \"utf-8\");\n return JSON.parse(data);\n }\n } catch {\n // If file is corrupted, start fresh\n }\n return { feeds: {} };\n}\n\nfunction saveState(state: AppState): void {\n ensureStateDir();\n // Atomic write: write to temp file, then rename\n const tempFile = `${STATE_FILE}.tmp`;\n fs.writeFileSync(tempFile, JSON.stringify(state, null, 2));\n fs.renameSync(tempFile, STATE_FILE);\n}\n\n/**\n * Get the last seen timestamp for a feed\n */\nexport function getLastSeenTimestamp(feedName: string): number | null {\n const state = loadState();\n return state.feeds[feedName]?.lastSeenTimestamp ?? null;\n}\n\n/**\n * Update the last seen timestamp for a feed\n */\nexport function setLastSeenTimestamp(feedName: string, timestamp: number): void {\n const state = loadState();\n if (!state.feeds[feedName]) {\n state.feeds[feedName] = { lastSeenTimestamp: timestamp };\n } else {\n state.feeds[feedName].lastSeenTimestamp = timestamp;\n }\n saveState(state);\n}\n\n/**\n * Mark a feed as seen up to the latest post timestamp\n */\nexport function markFeedSeen(feedName: string, posts: { timestamp: bigint }[]): void {\n if (posts.length === 0) return;\n\n // Find the max timestamp\n const maxTimestamp = posts.reduce(\n (max, post) => (post.timestamp > max ? post.timestamp : max),\n posts[0].timestamp\n );\n\n setLastSeenTimestamp(feedName, Number(maxTimestamp));\n}\n\n/**\n * Get the configured \"my address\" for filtering own posts\n */\nexport function getMyAddress(): string | null {\n const state = loadState();\n return state.myAddress ?? null;\n}\n\n/**\n * Set the \"my address\" for filtering own posts\n */\nexport function setMyAddress(address: string): void {\n const state = loadState();\n state.myAddress = address.toLowerCase();\n saveState(state);\n}\n\n/**\n * Clear the \"my address\"\n */\nexport function clearMyAddress(): void {\n const state = loadState();\n delete state.myAddress;\n saveState(state);\n}\n\n/**\n * Get full state (for debugging)\n */\nexport function getFullState(): AppState {\n return loadState();\n}\n\n/**\n * Reset all state (delete the state file)\n */\nexport function resetState(): void {\n if (fs.existsSync(STATE_FILE)) {\n fs.unlinkSync(STATE_FILE);\n }\n}\n\n/**\n * Get the state file path (for display purposes)\n */\nexport function getStateFilePath(): string {\n return STATE_FILE;\n}\n\n/**\n * Add an entry to the agent's history\n * Keeps only the most recent MAX_HISTORY_ENTRIES entries\n */\nexport function addHistoryEntry(entry: Omit<HistoryEntry, \"timestamp\">): void {\n const state = loadState();\n const history = state.history ?? [];\n\n const newEntry: HistoryEntry = {\n ...entry,\n timestamp: Math.floor(Date.now() / 1000),\n };\n\n // Add to beginning (most recent first)\n history.unshift(newEntry);\n\n // Trim to max size\n if (history.length > MAX_HISTORY_ENTRIES) {\n history.length = MAX_HISTORY_ENTRIES;\n }\n\n state.history = history;\n saveState(state);\n}\n\n/**\n * Get the agent's history\n * Returns entries in reverse chronological order (most recent first)\n */\nexport function getHistory(limit?: number): HistoryEntry[] {\n const state = loadState();\n const history = state.history ?? [];\n return limit ? history.slice(0, limit) : history;\n}\n\n/**\n * Get history entries of a specific type\n */\nexport function getHistoryByType(\n type: HistoryEntryType,\n limit?: number\n): HistoryEntry[] {\n const history = getHistory();\n const filtered = history.filter((entry) => entry.type === type);\n return limit ? filtered.slice(0, limit) : filtered;\n}\n\n/**\n * Clear all history\n */\nexport function clearHistory(): void {\n const state = loadState();\n state.history = [];\n saveState(state);\n}\n\n/**\n * Get history count\n */\nexport function getHistoryCount(): number {\n const state = loadState();\n return state.history?.length ?? 0;\n}\n\n/**\n * Check if a feed name is a wallet address (i.e., a direct message)\n */\nexport function isWalletAddress(feed: string): boolean {\n return /^0x[a-fA-F0-9]{40}$/.test(feed);\n}\n\n/**\n * Contact info derived from history\n */\nexport interface Contact {\n address: string;\n lastInteraction: number;\n interactionCount: number;\n firstInteraction: number;\n}\n\n/**\n * Get contacts - wallet addresses you've posted to (DMs)\n * Returns contacts sorted by last interaction (most recent first)\n */\nexport function getContacts(): Contact[] {\n const history = getHistory();\n const contactMap = new Map<string, Contact>();\n\n // Only look at posts (not comments) to wallet addresses\n for (const entry of history) {\n if (entry.type === \"post\" && isWalletAddress(entry.feed)) {\n const address = entry.feed.toLowerCase();\n const existing = contactMap.get(address);\n\n if (existing) {\n existing.interactionCount++;\n // Update first/last interaction times\n if (entry.timestamp > existing.lastInteraction) {\n existing.lastInteraction = entry.timestamp;\n }\n if (entry.timestamp < existing.firstInteraction) {\n existing.firstInteraction = entry.timestamp;\n }\n } else {\n contactMap.set(address, {\n address,\n lastInteraction: entry.timestamp,\n firstInteraction: entry.timestamp,\n interactionCount: 1,\n });\n }\n }\n }\n\n // Sort by last interaction (most recent first)\n return Array.from(contactMap.values()).sort(\n (a, b) => b.lastInteraction - a.lastInteraction\n );\n}\n\n/**\n * Feed activity info derived from history\n */\nexport interface FeedActivity {\n feed: string;\n postCount: number;\n commentCount: number;\n lastActivity: number;\n firstActivity: number;\n}\n\n/**\n * Get feeds the agent has been active in\n * Returns feeds sorted by last activity (most recent first)\n * Excludes wallet addresses (those are contacts, not feeds)\n */\nexport function getActiveFeeds(): FeedActivity[] {\n const history = getHistory();\n const feedMap = new Map<string, FeedActivity>();\n\n for (const entry of history) {\n // Skip wallet addresses - those are contacts\n if (isWalletAddress(entry.feed)) continue;\n // Skip feed registrations - only count actual posts/comments\n if (entry.type === \"register\") continue;\n\n const feedName = entry.feed.toLowerCase();\n const existing = feedMap.get(feedName);\n\n if (existing) {\n if (entry.type === \"post\") existing.postCount++;\n if (entry.type === \"comment\") existing.commentCount++;\n if (entry.timestamp > existing.lastActivity) {\n existing.lastActivity = entry.timestamp;\n }\n if (entry.timestamp < existing.firstActivity) {\n existing.firstActivity = entry.timestamp;\n }\n } else {\n feedMap.set(feedName, {\n feed: feedName,\n postCount: entry.type === \"post\" ? 1 : 0,\n commentCount: entry.type === \"comment\" ? 1 : 0,\n lastActivity: entry.timestamp,\n firstActivity: entry.timestamp,\n });\n }\n }\n\n // Sort by last activity (most recent first)\n return Array.from(feedMap.values()).sort(\n (a, b) => b.lastActivity - a.lastActivity\n );\n}\n","/**\n * Normalize a feed name to lowercase for consistency.\n */\nexport function normalizeFeedName(feed: string): string {\n return feed.toLowerCase();\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport { parseReadOnlyOptionsWithDefault } from \"../../cli/shared\";\nimport { createFeedClient } from \"../../shared/client\";\nimport { exitWithError } from \"../../shared/output\";\nimport { getLastSeenTimestamp, markFeedSeen, getMyAddress } from \"../../shared/state\";\nimport { formatPost, postToJson, printJson } from \"./format\";\nimport { normalizeFeedName } from \"./types\";\n\ninterface ReadOptions {\n limit?: number;\n chainId?: number;\n rpcUrl?: string;\n json?: boolean;\n sender?: string;\n unseen?: boolean;\n markSeen?: boolean;\n}\n\n/**\n * Execute the feed read command\n */\nasync function executeFeedRead(feed: string, options: ReadOptions): Promise<void> {\n const normalizedFeed = normalizeFeedName(feed);\n const readOnlyOptions = parseReadOnlyOptionsWithDefault({\n chainId: options.chainId,\n rpcUrl: options.rpcUrl,\n });\n\n const client = createFeedClient(readOnlyOptions);\n const limit = options.limit ?? 20;\n\n try {\n // First check if the feed has any posts\n const count = await client.getFeedPostCount(normalizedFeed);\n\n if (count === 0) {\n if (options.json) {\n printJson([]);\n } else {\n console.log(chalk.yellow(`No posts found in feed \"${normalizedFeed}\"`));\n }\n return;\n }\n\n // Fetch more posts if filtering by sender (we need to find enough matches)\n const fetchLimit = options.sender ? Math.max(limit * 5, 100) : limit;\n\n let posts = await client.getFeedPosts({\n topic: normalizedFeed,\n maxPosts: fetchLimit,\n });\n\n // Filter by sender if specified\n if (options.sender) {\n const senderLower = options.sender.toLowerCase();\n posts = posts.filter(\n (post) => post.sender.toLowerCase() === senderLower\n );\n // Apply limit after filtering\n posts = posts.slice(0, limit);\n }\n\n // Filter to unseen posts if --unseen flag is set\n if (options.unseen) {\n const lastSeen = getLastSeenTimestamp(normalizedFeed);\n const myAddress = getMyAddress();\n\n posts = posts.filter((post) => {\n // Must be newer than last seen (or no last seen = all are unseen)\n const isNew = lastSeen === null || Number(post.timestamp) > lastSeen;\n // Exclude own posts if myAddress is configured\n const isFromOther = !myAddress || post.sender.toLowerCase() !== myAddress;\n return isNew && isFromOther;\n });\n }\n\n // Mark feed as seen if --mark-seen flag is set\n // Use the original unfiltered posts to get the true latest timestamp\n if (options.markSeen) {\n const allPosts = await client.getFeedPosts({\n topic: normalizedFeed,\n maxPosts: 1, // Just need the latest\n });\n if (allPosts.length > 0) {\n markFeedSeen(normalizedFeed, allPosts);\n }\n }\n\n // Fetch comment counts for each post\n const commentCounts = await Promise.all(\n posts.map((post) => client.getCommentCount(post))\n );\n\n if (options.json) {\n printJson(\n posts.map((post, i) => postToJson(post, i, commentCounts[i]))\n );\n } else {\n if (posts.length === 0) {\n const senderNote = options.sender ? ` by ${options.sender}` : \"\";\n console.log(chalk.yellow(`No posts found in feed \"${normalizedFeed}\"${senderNote}`));\n return;\n }\n\n const senderNote = options.sender ? ` by ${options.sender}` : \"\";\n console.log(\n chalk.white(`Found ${posts.length} post(s) in feed \"${normalizedFeed}\"${senderNote}:\\n`)\n );\n posts.forEach((post, i) => {\n console.log(formatPost(post, i, { commentCount: commentCounts[i] }));\n if (i < posts.length - 1) {\n console.log(); // Empty line between posts\n }\n });\n }\n } catch (error) {\n exitWithError(\n `Failed to read feed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\n/**\n * Register the feed read subcommand\n */\nexport function registerFeedReadCommand(parent: Command): void {\n parent\n .command(\"read <feed>\")\n .description(\"Read posts from a feed\")\n .option(\n \"--limit <n>\",\n \"Maximum number of posts to display\",\n (value) => parseInt(value, 10)\n )\n .option(\n \"--chain-id <id>\",\n \"Chain ID (default: 8453 for Base)\",\n (value) => parseInt(value, 10)\n )\n .option(\"--rpc-url <url>\", \"Custom RPC URL\")\n .option(\"--sender <address>\", \"Filter posts by sender address\")\n .option(\"--unseen\", \"Only show posts not yet seen (newer than last --mark-seen)\")\n .option(\"--mark-seen\", \"Mark the feed as seen up to the latest post\")\n .option(\"--json\", \"Output in JSON format\")\n .action(async (feed, options) => {\n await executeFeedRead(feed, options);\n });\n}\n","import { createWalletClient, http } from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { getChainRpcUrls } from \"@net-protocol/core\";\nimport type { WriteTransactionConfig } from \"@net-protocol/core\";\n\n/**\n * Create a wallet client from a private key\n */\nexport function createWallet(\n privateKey: `0x${string}`,\n chainId: number,\n rpcUrl?: string\n) {\n const account = privateKeyToAccount(privateKey);\n const rpcUrls = getChainRpcUrls({\n chainId,\n rpcUrl: rpcUrl,\n });\n\n return createWalletClient({\n account,\n transport: http(rpcUrls[0]),\n });\n}\n\n/**\n * Execute a transaction using a wallet client\n */\nexport async function executeTransaction(\n walletClient: ReturnType<typeof createWallet>,\n txConfig: WriteTransactionConfig\n): Promise<`0x${string}`> {\n const hash = await walletClient.writeContract({\n address: txConfig.to,\n abi: txConfig.abi,\n functionName: txConfig.functionName,\n args: txConfig.args,\n value: txConfig.value,\n chain: null,\n } as Parameters<typeof walletClient.writeContract>[0]);\n\n return hash;\n}\n","import { encodeFunctionData } from \"viem\";\nimport type { WriteTransactionConfig } from \"@net-protocol/core\";\nimport type { EncodedTransaction } from \"./types\";\n\nexport type { EncodedTransaction };\n\n/**\n * Encode a write transaction config into transaction data\n * Used for --encode-only mode where we output transaction data instead of executing\n */\nexport function encodeTransaction(\n config: WriteTransactionConfig,\n chainId: number\n): EncodedTransaction {\n const calldata = encodeFunctionData({\n abi: config.abi,\n functionName: config.functionName,\n args: config.args,\n });\n\n return {\n to: config.to,\n data: calldata,\n chainId,\n value: config.value?.toString() ?? \"0\",\n };\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport { parseReadOnlyOptionsWithDefault, parseCommonOptionsWithDefault } from \"../../cli/shared\";\nimport { createFeedClient } from \"../../shared/client\";\nimport { createWallet, executeTransaction } from \"../../shared/wallet\";\nimport { encodeTransaction } from \"../../shared/encode\";\nimport { exitWithError } from \"../../shared/output\";\nimport { addHistoryEntry } from \"../../shared/state\";\nimport { printJson } from \"./format\";\nimport { normalizeFeedName } from \"./types\";\n\ninterface PostOptions {\n chainId?: number;\n rpcUrl?: string;\n privateKey?: string;\n encodeOnly?: boolean;\n data?: string;\n body?: string;\n}\n\nconst MAX_MESSAGE_LENGTH = 4000;\n\n/**\n * Execute the feed post command\n */\nasync function executeFeedPost(\n feed: string,\n message: string,\n options: PostOptions\n): Promise<void> {\n const normalizedFeed = normalizeFeedName(feed);\n\n if (message.length === 0) {\n exitWithError(\"Message cannot be empty\");\n }\n\n // If --body is provided, format as title + body\n // The message argument becomes the title, --body becomes the body\n const fullMessage = options.body\n ? `${message}\\n\\n${options.body}`\n : message;\n\n if (fullMessage.length > MAX_MESSAGE_LENGTH) {\n exitWithError(\n `Message too long (${fullMessage.length} chars). Maximum is ${MAX_MESSAGE_LENGTH} characters.`\n );\n }\n\n // For encode-only mode, we don't need a private key\n if (options.encodeOnly) {\n const readOnlyOptions = parseReadOnlyOptionsWithDefault({\n chainId: options.chainId,\n rpcUrl: options.rpcUrl,\n });\n\n const client = createFeedClient(readOnlyOptions);\n const txConfig = client.preparePostToFeed({\n topic: normalizedFeed,\n text: fullMessage,\n data: options.data,\n });\n const encoded = encodeTransaction(txConfig, readOnlyOptions.chainId);\n\n printJson(encoded);\n return;\n }\n\n // For actual execution, we need a private key\n const commonOptions = parseCommonOptionsWithDefault(\n {\n privateKey: options.privateKey,\n chainId: options.chainId,\n rpcUrl: options.rpcUrl,\n },\n true // supports --encode-only\n );\n\n const client = createFeedClient(commonOptions);\n const txConfig = client.preparePostToFeed({\n topic: normalizedFeed,\n text: fullMessage,\n data: options.data,\n });\n\n const walletClient = createWallet(\n commonOptions.privateKey,\n commonOptions.chainId,\n commonOptions.rpcUrl\n );\n\n console.log(chalk.blue(`Posting to feed \"${normalizedFeed}\"...`));\n\n try {\n const hash = await executeTransaction(walletClient, txConfig);\n const senderAddress = walletClient.account.address;\n\n // Try to fetch the post to get its actual post ID\n let postId: string | undefined;\n try {\n const posts = await client.getFeedPosts({\n topic: normalizedFeed,\n maxPosts: 10,\n });\n // Find our post (most recent from our sender with matching text)\n const ourPost = posts.find(\n (p) =>\n p.sender.toLowerCase() === senderAddress.toLowerCase() &&\n p.text === fullMessage\n );\n if (ourPost) {\n postId = `${ourPost.sender}:${ourPost.timestamp}`;\n }\n } catch {\n // Non-fatal: we can still record history without the post ID\n }\n\n // Record in history with the actual post ID\n addHistoryEntry({\n type: \"post\",\n txHash: hash,\n chainId: commonOptions.chainId,\n feed: normalizedFeed,\n sender: senderAddress,\n text: fullMessage,\n postId, // Now we have the actual post ID for checking comments later\n });\n\n const displayText = options.body\n ? `${message} (+ body)`\n : message;\n\n const postIdInfo = postId ? `\\n Post ID: ${postId}` : \"\";\n console.log(\n chalk.green(\n `Message posted successfully!\\n Transaction: ${hash}\\n Feed: ${normalizedFeed}${postIdInfo}\\n Text: ${displayText}`\n )\n );\n } catch (error) {\n exitWithError(\n `Failed to post message: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\n/**\n * Register the feed post subcommand\n */\nexport function registerFeedPostCommand(parent: Command): void {\n parent\n .command(\"post <feed> <message>\")\n .description(\"Post a message to a feed\")\n .option(\n \"--chain-id <id>\",\n \"Chain ID (default: 8453 for Base)\",\n (value) => parseInt(value, 10)\n )\n .option(\"--rpc-url <url>\", \"Custom RPC URL\")\n .option(\"--private-key <key>\", \"Private key (0x-prefixed)\")\n .option(\n \"--encode-only\",\n \"Output transaction data as JSON instead of executing\"\n )\n .option(\"--data <data>\", \"Optional data to attach to the post\")\n .option(\"--body <text>\", \"Post body (message becomes the title)\")\n .action(async (feed, message, options) => {\n await executeFeedPost(feed, message, options);\n });\n}\n","import type { NetMessage } from \"@net-protocol/feeds\";\n\n/**\n * Create a post ID from a message\n * Format: {sender}:{timestamp}\n */\nexport function createPostId(post: NetMessage): string {\n return `${post.sender}:${post.timestamp}`;\n}\n\n/**\n * Parse a post ID string into sender and timestamp\n * Format: {sender}:{timestamp}\n * @throws Error if the format is invalid\n */\nexport function parsePostId(postId: string): {\n sender: `0x${string}`;\n timestamp: bigint;\n} {\n const parts = postId.split(\":\");\n if (parts.length !== 2) {\n throw new Error(\n `Invalid post ID format. Expected {sender}:{timestamp}, got: ${postId}`\n );\n }\n\n const [sender, timestampStr] = parts;\n\n if (!sender.startsWith(\"0x\") || sender.length !== 42) {\n throw new Error(`Invalid sender address in post ID: ${sender}`);\n }\n\n const timestamp = BigInt(timestampStr);\n if (timestamp <= 0) {\n throw new Error(`Invalid timestamp in post ID: ${timestampStr}`);\n }\n\n return {\n sender: sender as `0x${string}`,\n timestamp,\n };\n}\n\n/**\n * Find a post in a list by its ID components\n */\nexport function findPostByParsedId(\n posts: NetMessage[],\n parsedId: { sender: `0x${string}`; timestamp: bigint }\n): NetMessage | undefined {\n return posts.find(\n (p) =>\n p.sender.toLowerCase() === parsedId.sender.toLowerCase() &&\n p.timestamp === parsedId.timestamp\n );\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport { parseReadOnlyOptionsWithDefault, parseCommonOptionsWithDefault } from \"../../cli/shared\";\nimport { createFeedClient } from \"../../shared/client\";\nimport { createWallet, executeTransaction } from \"../../shared/wallet\";\nimport { encodeTransaction } from \"../../shared/encode\";\nimport { exitWithError } from \"../../shared/output\";\nimport { parsePostId, findPostByParsedId } from \"../../shared/postId\";\nimport { addHistoryEntry } from \"../../shared/state\";\nimport { printJson } from \"./format\";\nimport { normalizeFeedName } from \"./types\";\n\ninterface CommentWriteOptions {\n chainId?: number;\n rpcUrl?: string;\n privateKey?: string;\n encodeOnly?: boolean;\n}\n\nconst MAX_MESSAGE_LENGTH = 4000;\n\n/**\n * Execute the feed comment-write command\n */\nasync function executeFeedCommentWrite(\n feed: string,\n postId: string,\n message: string,\n options: CommentWriteOptions\n): Promise<void> {\n const normalizedFeed = normalizeFeedName(feed);\n\n if (message.length === 0) {\n exitWithError(\"Comment cannot be empty\");\n }\n\n if (message.length > MAX_MESSAGE_LENGTH) {\n exitWithError(\n `Comment too long (${message.length} chars). Maximum is ${MAX_MESSAGE_LENGTH} characters.`\n );\n }\n\n // Parse post ID\n let parsedId: { sender: `0x${string}`; timestamp: bigint };\n try {\n parsedId = parsePostId(postId);\n } catch (error) {\n exitWithError(\n error instanceof Error ? error.message : \"Invalid post ID format\"\n );\n }\n\n // Determine options based on encode-only mode\n const readOnlyOptions = parseReadOnlyOptionsWithDefault({\n chainId: options.chainId,\n rpcUrl: options.rpcUrl,\n });\n\n const client = createFeedClient(readOnlyOptions);\n\n // First check if the feed has any posts\n const count = await client.getFeedPostCount(normalizedFeed);\n\n if (count === 0) {\n exitWithError(\n `Feed \"${normalizedFeed}\" has no posts. Cannot find post ${postId}.`\n );\n }\n\n // Fetch the target post to get its full data (needed to generate comment topic hash)\n const posts = await client.getFeedPosts({\n topic: normalizedFeed,\n maxPosts: 100, // Fetch enough to find the post\n });\n\n const targetPost = findPostByParsedId(posts, parsedId);\n if (!targetPost) {\n exitWithError(\n `Post not found with ID ${postId} in feed \"${normalizedFeed}\". Make sure the sender and timestamp are correct.`\n );\n }\n\n const txConfig = client.prepareComment({\n post: targetPost,\n text: message,\n });\n\n // For encode-only mode, just output the transaction data\n if (options.encodeOnly) {\n const encoded = encodeTransaction(txConfig, readOnlyOptions.chainId);\n printJson(encoded);\n return;\n }\n\n // For actual execution, we need a private key\n const commonOptions = parseCommonOptionsWithDefault(\n {\n privateKey: options.privateKey,\n chainId: options.chainId,\n rpcUrl: options.rpcUrl,\n },\n true // supports --encode-only\n );\n\n const walletClient = createWallet(\n commonOptions.privateKey,\n commonOptions.chainId,\n commonOptions.rpcUrl\n );\n\n console.log(chalk.blue(`Commenting on post ${postId}...`));\n\n try {\n const hash = await executeTransaction(walletClient, txConfig);\n\n // Record in history\n addHistoryEntry({\n type: \"comment\",\n txHash: hash,\n chainId: commonOptions.chainId,\n feed: normalizedFeed,\n sender: walletClient.account.address,\n text: message,\n postId: postId,\n });\n\n console.log(\n chalk.green(\n `Comment posted successfully!\\n Transaction: ${hash}\\n Post: ${postId}\\n Comment: ${message}`\n )\n );\n } catch (error) {\n exitWithError(\n `Failed to post comment: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\n/**\n * Register the feed comment-write subcommand\n */\nexport function registerFeedCommentWriteCommand(parent: Command): void {\n parent\n .command(\"comment <feed> <post-id> <message>\")\n .description(\n \"Comment on a post. Post ID format: {sender}:{timestamp}\"\n )\n .option(\n \"--chain-id <id>\",\n \"Chain ID (default: 8453 for Base)\",\n (value) => parseInt(value, 10)\n )\n .option(\"--rpc-url <url>\", \"Custom RPC URL\")\n .option(\"--private-key <key>\", \"Private key (0x-prefixed)\")\n .option(\n \"--encode-only\",\n \"Output transaction data as JSON instead of executing\"\n )\n .action(async (feed, postId, message, options) => {\n await executeFeedCommentWrite(feed, postId, message, options);\n });\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport { parseReadOnlyOptionsWithDefault } from \"../../cli/shared\";\nimport { createFeedClient } from \"../../shared/client\";\nimport { exitWithError } from \"../../shared/output\";\nimport { parsePostId, findPostByParsedId } from \"../../shared/postId\";\nimport { formatComment, commentToJson, printJson } from \"./format\";\nimport { normalizeFeedName } from \"./types\";\n\ninterface CommentReadOptions {\n limit?: number;\n chainId?: number;\n rpcUrl?: string;\n json?: boolean;\n}\n\n/**\n * Execute the feed comment-read command\n */\nasync function executeFeedCommentRead(\n feed: string,\n postId: string,\n options: CommentReadOptions\n): Promise<void> {\n const normalizedFeed = normalizeFeedName(feed);\n const readOnlyOptions = parseReadOnlyOptionsWithDefault({\n chainId: options.chainId,\n rpcUrl: options.rpcUrl,\n });\n\n const client = createFeedClient(readOnlyOptions);\n\n // Parse post ID\n let parsedId: { sender: `0x${string}`; timestamp: bigint };\n try {\n parsedId = parsePostId(postId);\n } catch (error) {\n exitWithError(\n error instanceof Error ? error.message : \"Invalid post ID format\"\n );\n }\n\n try {\n // First check if the feed has any posts\n const count = await client.getFeedPostCount(normalizedFeed);\n\n if (count === 0) {\n exitWithError(\n `Feed \"${normalizedFeed}\" has no posts. Cannot find post ${postId}.`\n );\n }\n\n // Fetch posts to find the target post\n const posts = await client.getFeedPosts({\n topic: normalizedFeed,\n maxPosts: 100, // Fetch enough to find the post\n });\n\n const targetPost = findPostByParsedId(posts, parsedId);\n if (!targetPost) {\n exitWithError(\n `Post not found with ID ${postId} in feed \"${normalizedFeed}\". Make sure the sender and timestamp are correct.`\n );\n }\n\n // Check comment count first\n const commentCount = await client.getCommentCount(targetPost);\n\n if (commentCount === 0) {\n if (options.json) {\n printJson([]);\n } else {\n console.log(chalk.yellow(`No comments found for post ${postId}`));\n }\n return;\n }\n\n // Fetch comments for the post\n const comments = await client.getComments({\n post: targetPost,\n maxComments: options.limit ?? 50,\n });\n\n // Build a tree structure for nested comments (simplified - flat with depth)\n // For now, we'll display comments flat with depth 0 (top-level)\n const commentsWithDepth = comments.map((comment) => ({\n comment,\n depth: 0,\n }));\n\n if (options.json) {\n printJson(\n commentsWithDepth.map(({ comment, depth }) =>\n commentToJson(comment, depth)\n )\n );\n } else {\n if (comments.length === 0) {\n console.log(chalk.yellow(`No comments found for post ${postId}`));\n return;\n }\n\n console.log(\n chalk.white(`Found ${comments.length} comment(s) for post ${postId}:\\n`)\n );\n commentsWithDepth.forEach(({ comment, depth }, i) => {\n console.log(formatComment(comment, depth));\n if (i < commentsWithDepth.length - 1) {\n console.log(); // Empty line between comments\n }\n });\n }\n } catch (error) {\n if ((error as Error).message?.includes(\"Post not found\")) {\n throw error;\n }\n exitWithError(\n `Failed to fetch comments: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\n/**\n * Register the feed comments subcommand\n */\nexport function registerFeedCommentReadCommand(parent: Command): void {\n parent\n .command(\"comments <feed> <post-id>\")\n .description(\n \"Read comments on a post. Post ID format: {sender}:{timestamp}\"\n )\n .option(\n \"--limit <n>\",\n \"Maximum number of comments to display\",\n (value) => parseInt(value, 10)\n )\n .option(\n \"--chain-id <id>\",\n \"Chain ID (default: 8453 for Base)\",\n (value) => parseInt(value, 10)\n )\n .option(\"--rpc-url <url>\", \"Custom RPC URL\")\n .option(\"--json\", \"Output in JSON format\")\n .action(async (feed, postId, options) => {\n await executeFeedCommentRead(feed, postId, options);\n });\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport { parseReadOnlyOptionsWithDefault, parseCommonOptionsWithDefault } from \"../../cli/shared\";\nimport { createFeedRegistryClient } from \"../../shared/client\";\nimport { createWallet, executeTransaction } from \"../../shared/wallet\";\nimport { encodeTransaction } from \"../../shared/encode\";\nimport { exitWithError } from \"../../shared/output\";\nimport { addHistoryEntry } from \"../../shared/state\";\nimport { printJson } from \"./format\";\n\ninterface RegisterOptions {\n chainId?: number;\n rpcUrl?: string;\n privateKey?: string;\n encodeOnly?: boolean;\n}\n\n/**\n * Execute the feed register command\n */\nasync function executeFeedRegister(\n feedName: string,\n options: RegisterOptions\n): Promise<void> {\n // Validate feed name length\n if (feedName.length > 64) {\n exitWithError(\"Feed name cannot exceed 64 characters\");\n }\n\n if (feedName.length === 0) {\n exitWithError(\"Feed name cannot be empty\");\n }\n\n // For encode-only mode, we don't need a private key\n if (options.encodeOnly) {\n const readOnlyOptions = parseReadOnlyOptionsWithDefault({\n chainId: options.chainId,\n rpcUrl: options.rpcUrl,\n });\n\n const client = createFeedRegistryClient(readOnlyOptions);\n const txConfig = client.prepareRegisterFeed({ feedName });\n const encoded = encodeTransaction(txConfig, readOnlyOptions.chainId);\n\n printJson(encoded);\n return;\n }\n\n // For actual execution, we need a private key\n const commonOptions = parseCommonOptionsWithDefault(\n {\n privateKey: options.privateKey,\n chainId: options.chainId,\n rpcUrl: options.rpcUrl,\n },\n true // supports --encode-only\n );\n\n const client = createFeedRegistryClient(commonOptions);\n\n // Check if feed is already registered\n const isRegistered = await client.isFeedRegistered(feedName);\n if (isRegistered) {\n exitWithError(`Feed \"${feedName}\" is already registered`);\n }\n\n const txConfig = client.prepareRegisterFeed({ feedName });\n const walletClient = createWallet(\n commonOptions.privateKey,\n commonOptions.chainId,\n commonOptions.rpcUrl\n );\n\n console.log(chalk.blue(`Registering feed \"${feedName}\"...`));\n\n try {\n const hash = await executeTransaction(walletClient, txConfig);\n\n // Record in history\n addHistoryEntry({\n type: \"register\",\n txHash: hash,\n chainId: commonOptions.chainId,\n feed: feedName,\n sender: walletClient.account.address,\n });\n\n console.log(\n chalk.green(\n `Feed registered successfully!\\n Transaction: ${hash}\\n Feed: ${feedName}`\n )\n );\n } catch (error) {\n exitWithError(\n `Failed to register feed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\n/**\n * Register the feed register subcommand\n */\nexport function registerFeedRegisterCommand(parent: Command): void {\n parent\n .command(\"register <feed-name>\")\n .description(\"Register a new feed\")\n .option(\n \"--chain-id <id>\",\n \"Chain ID (default: 8453 for Base)\",\n (value) => parseInt(value, 10)\n )\n .option(\"--rpc-url <url>\", \"Custom RPC URL\")\n .option(\"--private-key <key>\", \"Private key (0x-prefixed)\")\n .option(\n \"--encode-only\",\n \"Output transaction data as JSON instead of executing\"\n )\n .action(async (feedName, options) => {\n await executeFeedRegister(feedName, options);\n });\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport { parseReadOnlyOptionsWithDefault } from \"../../cli/shared\";\nimport { createFeedClient } from \"../../shared/client\";\nimport { getHistoryByType, type HistoryEntry } from \"../../shared/state\";\nimport { printJson } from \"./format\";\nimport { formatTimestamp } from \"./format\";\n\ninterface RepliesOptions {\n chainId?: number;\n rpcUrl?: string;\n limit?: number;\n json?: boolean;\n}\n\ninterface PostWithReplies {\n feed: string;\n postId: string;\n text: string;\n postedAt: number;\n commentCount: number;\n}\n\n/**\n * Truncate text for display\n */\nfunction truncateText(text: string, maxLen: number): string {\n if (text.length <= maxLen) return text;\n return text.slice(0, maxLen) + \"...\";\n}\n\n/**\n * Execute the feed replies command\n */\nasync function executeFeedReplies(options: RepliesOptions): Promise<void> {\n // Get recent posts from history that have post IDs\n const postHistory = getHistoryByType(\"post\", options.limit ?? 10);\n const postsWithIds = postHistory.filter(\n (entry): entry is HistoryEntry & { postId: string } => !!entry.postId\n );\n\n if (postsWithIds.length === 0) {\n if (options.json) {\n printJson([]);\n } else {\n console.log(chalk.gray(\"No posts with trackable IDs found in history.\"));\n console.log(\n chalk.gray(\"Post IDs are captured when you post with a wallet.\")\n );\n }\n return;\n }\n\n const readOnlyOptions = parseReadOnlyOptionsWithDefault({\n chainId: options.chainId,\n rpcUrl: options.rpcUrl,\n });\n\n const client = createFeedClient(readOnlyOptions);\n\n console.log(chalk.blue(`Checking replies on ${postsWithIds.length} posts...\\n`));\n\n const results: PostWithReplies[] = [];\n\n for (const entry of postsWithIds) {\n try {\n // Parse post ID to get sender and timestamp\n const [sender, timestampStr] = entry.postId.split(\":\");\n const timestamp = BigInt(timestampStr);\n\n // Get comment count for this post\n // Construct a minimal post object for the comment count query\n const postObj = {\n sender: sender as `0x${string}`,\n timestamp,\n text: entry.text ?? \"\",\n topic: entry.feed,\n app: \"\" as `0x${string}`,\n data: \"0x\" as `0x${string}`,\n };\n const commentCount = await client.getCommentCount(postObj);\n\n results.push({\n feed: entry.feed,\n postId: entry.postId,\n text: entry.text ?? \"\",\n postedAt: entry.timestamp,\n commentCount: Number(commentCount),\n });\n } catch {\n // Skip posts we can't check (e.g., if feed no longer exists)\n }\n }\n\n if (options.json) {\n printJson(results);\n return;\n }\n\n // Display results\n const postsWithReplies = results.filter((r) => r.commentCount > 0);\n const totalReplies = results.reduce((sum, r) => sum + r.commentCount, 0);\n\n console.log(\n chalk.cyan(\n `Found ${totalReplies} total replies across ${postsWithReplies.length} posts\\n`\n )\n );\n\n if (results.length === 0) {\n console.log(chalk.gray(\"Could not check any posts.\"));\n return;\n }\n\n // Sort by comment count (most replies first)\n results.sort((a, b) => b.commentCount - a.commentCount);\n\n for (const post of results) {\n const timeAgo = formatTimestamp(post.postedAt);\n const replyText =\n post.commentCount === 0\n ? chalk.gray(\"no replies\")\n : post.commentCount === 1\n ? chalk.green(\"1 reply\")\n : chalk.green(`${post.commentCount} replies`);\n\n console.log(\n `${chalk.white(post.feed)} ${chalk.gray(\"•\")} ${replyText} ${chalk.gray(`• ${timeAgo}`)}`\n );\n console.log(` ${chalk.gray(truncateText(post.text, 60))}`);\n\n if (post.commentCount > 0) {\n console.log(\n chalk.blue(` → netp feed comments ${post.feed} ${post.postId}`)\n );\n }\n console.log(\"\");\n }\n}\n\n/**\n * Register the feed replies subcommand\n */\nexport function registerFeedRepliesCommand(parent: Command): void {\n parent\n .command(\"replies\")\n .description(\"Check for replies on your recent posts\")\n .option(\n \"--chain-id <id>\",\n \"Chain ID (default: 8453 for Base)\",\n (value) => parseInt(value, 10)\n )\n .option(\"--rpc-url <url>\", \"Custom RPC URL\")\n .option(\"--limit <n>\", \"Number of recent posts to check (default: 10)\", (value) =>\n parseInt(value, 10)\n )\n .option(\"--json\", \"Output as JSON\")\n .action(async (options) => {\n await executeFeedReplies(options);\n });\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport { NULL_ADDRESS } from \"@net-protocol/core\";\nimport { parseReadOnlyOptionsWithDefault } from \"../../cli/shared\";\nimport { createNetClient } from \"../../shared/client\";\nimport { exitWithError } from \"../../shared/output\";\nimport { formatPost, postToJson, printJson } from \"./format\";\n\ninterface PostsOptions {\n limit?: number;\n chainId?: number;\n rpcUrl?: string;\n json?: boolean;\n}\n\n/**\n * Execute the feed posts command\n */\nasync function executeFeedPosts(\n address: string,\n options: PostsOptions\n): Promise<void> {\n // Validate address format\n if (!address.startsWith(\"0x\") || address.length !== 42) {\n exitWithError(\"Invalid address format. Must be 0x-prefixed, 42 characters\");\n }\n\n const readOnlyOptions = parseReadOnlyOptionsWithDefault({\n chainId: options.chainId,\n rpcUrl: options.rpcUrl,\n });\n\n const client = createNetClient(readOnlyOptions);\n const limit = options.limit ?? 20;\n\n try {\n // Get message count for this user from feeds (app = NULL_ADDRESS)\n const count = await client.getMessageCount({\n filter: {\n appAddress: NULL_ADDRESS as `0x${string}`,\n maker: address as `0x${string}`,\n },\n });\n\n if (count === 0) {\n if (options.json) {\n printJson([]);\n } else {\n console.log(chalk.yellow(`No posts found for address ${address}`));\n }\n return;\n }\n\n // Calculate range for fetching\n const startIndex = count > limit ? count - limit : 0;\n\n const messages = await client.getMessages({\n filter: {\n appAddress: NULL_ADDRESS as `0x${string}`,\n maker: address as `0x${string}`,\n },\n startIndex,\n endIndex: count,\n });\n\n if (options.json) {\n printJson(messages.map((msg, i) => postToJson(msg, i)));\n } else {\n console.log(\n chalk.white(`Found ${messages.length} post(s) by ${address}:\\n`)\n );\n messages.forEach((msg, i) => {\n console.log(formatPost(msg, i, { showTopic: true }));\n if (i < messages.length - 1) {\n console.log(); // Empty line between posts\n }\n });\n }\n } catch (error) {\n exitWithError(\n `Failed to fetch posts: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\n/**\n * Register the feed posts subcommand\n */\nexport function registerFeedPostsCommand(parent: Command): void {\n parent\n .command(\"posts <address>\")\n .description(\"View posts by an address\")\n .option(\n \"--limit <n>\",\n \"Maximum number of posts to display\",\n (value) => parseInt(value, 10)\n )\n .option(\n \"--chain-id <id>\",\n \"Chain ID (default: 8453 for Base)\",\n (value) => parseInt(value, 10)\n )\n .option(\"--rpc-url <url>\", \"Custom RPC URL\")\n .option(\"--json\", \"Output in JSON format\")\n .action(async (address, options) => {\n await executeFeedPosts(address, options);\n });\n}\n","import * as readline from \"readline\";\n\n/**\n * Prompt user for confirmation\n */\nexport async function confirm(message: string): Promise<boolean> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n return new Promise((resolve) => {\n rl.question(`${message} (y/N): `, (answer) => {\n rl.close();\n resolve(answer.toLowerCase() === \"y\" || answer.toLowerCase() === \"yes\");\n });\n });\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport {\n getMyAddress,\n setMyAddress,\n clearMyAddress,\n getFullState,\n resetState,\n getStateFilePath,\n getHistoryCount,\n getContacts,\n getActiveFeeds,\n} from \"../../shared/state\";\nimport { formatTimestamp } from \"./format\";\nimport { confirm } from \"./confirm\";\n\ninterface ConfigOptions {\n myAddress?: string;\n clearAddress?: boolean;\n show?: boolean;\n reset?: boolean;\n force?: boolean;\n}\n\n/**\n * Execute the feed config command\n */\nasync function executeFeedConfig(options: ConfigOptions): Promise<void> {\n // Handle --reset\n if (options.reset) {\n const statePath = getStateFilePath();\n console.log(chalk.yellow(`This will delete all stored state at:`));\n console.log(chalk.white(` ${statePath}`));\n console.log(chalk.yellow(`\\nThis includes:`));\n console.log(chalk.white(` - All \"last seen\" timestamps for feeds`));\n console.log(chalk.white(` - Your configured address`));\n console.log(chalk.white(` - Your activity history`));\n\n if (!options.force) {\n const confirmed = await confirm(chalk.red(\"\\nAre you sure you want to reset?\"));\n if (!confirmed) {\n console.log(chalk.gray(\"Cancelled.\"));\n return;\n }\n }\n\n resetState();\n console.log(chalk.green(\"State reset successfully.\"));\n return;\n }\n\n // Handle --my-address\n if (options.myAddress) {\n // Basic validation\n if (!options.myAddress.match(/^0x[a-fA-F0-9]{40}$/)) {\n console.error(chalk.red(\"Invalid address format. Expected 0x followed by 40 hex characters.\"));\n process.exit(1);\n }\n setMyAddress(options.myAddress);\n console.log(chalk.green(`Set my address to: ${options.myAddress}`));\n return;\n }\n\n // Handle --clear-address\n if (options.clearAddress) {\n clearMyAddress();\n console.log(chalk.green(\"Cleared my address.\"));\n return;\n }\n\n // Default: --show (or no options)\n const state = getFullState();\n const myAddress = getMyAddress();\n\n console.log(chalk.cyan(\"Feed Configuration\\n\"));\n console.log(chalk.white(`State file: ${getStateFilePath()}`));\n console.log(chalk.white(`My address: ${myAddress ?? chalk.gray(\"(not set)\")}`));\n\n const feedCount = Object.keys(state.feeds).length;\n console.log(chalk.white(`Tracked feeds: ${feedCount}`));\n\n const historyCount = getHistoryCount();\n console.log(chalk.white(`History entries: ${historyCount}`));\n\n if (feedCount > 0 && feedCount <= 20) {\n console.log(chalk.gray(\"\\nLast seen timestamps:\"));\n for (const [feed, data] of Object.entries(state.feeds)) {\n const date = new Date(data.lastSeenTimestamp * 1000);\n console.log(chalk.gray(` ${feed}: ${date.toLocaleString()}`));\n }\n } else if (feedCount > 20) {\n console.log(chalk.gray(`\\n(${feedCount} feeds tracked, use --json for full list)`));\n }\n\n // Show active feeds (topics the agent has participated in)\n const activeFeeds = getActiveFeeds();\n if (activeFeeds.length > 0) {\n console.log(chalk.cyan(\"\\nActive Feeds:\"));\n const displayFeeds = activeFeeds.slice(0, 10);\n for (const feed of displayFeeds) {\n const activity = [];\n if (feed.postCount > 0) activity.push(`${feed.postCount} post${feed.postCount !== 1 ? \"s\" : \"\"}`);\n if (feed.commentCount > 0) activity.push(`${feed.commentCount} comment${feed.commentCount !== 1 ? \"s\" : \"\"}`);\n const lastActive = formatTimestamp(feed.lastActivity);\n console.log(chalk.white(` ${feed.feed}`) + chalk.gray(` • ${activity.join(\", \")} • ${lastActive}`));\n }\n if (activeFeeds.length > 10) {\n console.log(chalk.gray(` ... and ${activeFeeds.length - 10} more`));\n }\n }\n\n // Show contacts (wallet addresses the agent has DM'd)\n const contacts = getContacts();\n if (contacts.length > 0) {\n console.log(chalk.cyan(\"\\nRecent Contacts (DMs):\"));\n const displayContacts = contacts.slice(0, 10);\n for (const contact of displayContacts) {\n const truncAddr = `${contact.address.slice(0, 6)}...${contact.address.slice(-4)}`;\n const msgCount = contact.interactionCount;\n const lastActive = formatTimestamp(contact.lastInteraction);\n console.log(\n chalk.white(` ${truncAddr}`) +\n chalk.gray(` • ${msgCount} message${msgCount !== 1 ? \"s\" : \"\"} • ${lastActive}`)\n );\n }\n if (contacts.length > 10) {\n console.log(chalk.gray(` ... and ${contacts.length - 10} more`));\n }\n }\n}\n\n/**\n * Register the feed config subcommand\n */\nexport function registerFeedConfigCommand(parent: Command): void {\n parent\n .command(\"config\")\n .description(\"View or modify feed configuration\")\n .option(\"--my-address <address>\", \"Set your address (to filter out own posts with --unseen)\")\n .option(\"--clear-address\", \"Clear your configured address\")\n .option(\"--show\", \"Show current configuration (default)\")\n .option(\"--reset\", \"Reset all state (clears last-seen timestamps and address)\")\n .option(\"--force\", \"Skip confirmation prompt for --reset\")\n .action(async (options) => {\n await executeFeedConfig(options);\n });\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport {\n getHistory,\n getHistoryByType,\n clearHistory,\n getHistoryCount,\n type HistoryEntry,\n type HistoryEntryType,\n} from \"../../shared/state\";\nimport { formatTimestamp, printJson, truncateAddress } from \"./format\";\nimport { confirm } from \"./confirm\";\n\ninterface HistoryOptions {\n limit?: number;\n type?: string;\n json?: boolean;\n clear?: boolean;\n force?: boolean;\n}\n\n/**\n * Format a history entry for human-readable output\n */\nfunction formatHistoryEntry(entry: HistoryEntry, index: number): string {\n const timestamp = formatTimestamp(entry.timestamp);\n const typeColor =\n entry.type === \"post\"\n ? chalk.green\n : entry.type === \"comment\"\n ? chalk.blue\n : chalk.yellow;\n\n const lines = [\n chalk.cyan(`[${index}]`) +\n ` ${chalk.gray(timestamp)} ` +\n typeColor(entry.type.toUpperCase()),\n ` ${chalk.white(\"Feed:\")} ${entry.feed}`,\n ` ${chalk.white(\"Tx:\")} ${entry.txHash}`,\n ];\n\n if (entry.sender) {\n lines.push(` ${chalk.white(\"Sender:\")} ${truncateAddress(entry.sender)}`);\n }\n\n if (entry.text) {\n const truncatedText =\n entry.text.length > 80 ? entry.text.slice(0, 80) + \"...\" : entry.text;\n lines.push(` ${chalk.white(\"Text:\")} ${truncatedText}`);\n }\n\n // Show postId context based on entry type\n if (entry.type === \"post\" && entry.postId) {\n lines.push(` ${chalk.white(\"Post ID:\")} ${entry.postId}`);\n } else if (entry.type === \"comment\" && entry.postId) {\n lines.push(` ${chalk.white(\"Reply to:\")} ${entry.postId}`);\n }\n\n // Show follow-up hint\n if (entry.type === \"post\" && entry.postId) {\n lines.push(\n chalk.gray(` → Check replies: netp feed comments ${entry.feed} ${entry.postId}`)\n );\n } else if (entry.type === \"post\" && entry.sender) {\n lines.push(\n chalk.gray(` → Find post: netp feed read ${entry.feed} --sender ${entry.sender} --json`)\n );\n } else if (entry.type === \"comment\" && entry.postId) {\n lines.push(\n chalk.gray(` → See thread: netp feed comments ${entry.feed} ${entry.postId}`)\n );\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Convert a history entry to JSON format\n */\nfunction historyEntryToJson(\n entry: HistoryEntry,\n index: number\n): Record<string, unknown> {\n const result: Record<string, unknown> = {\n index,\n type: entry.type,\n timestamp: entry.timestamp,\n txHash: entry.txHash,\n chainId: entry.chainId,\n feed: entry.feed,\n };\n\n if (entry.sender) {\n result.sender = entry.sender;\n }\n\n if (entry.text) {\n result.text = entry.text;\n }\n\n if (entry.postId) {\n result.postId = entry.postId;\n }\n\n return result;\n}\n\n/**\n * Validate history type option\n */\nfunction validateType(type: string): HistoryEntryType {\n const validTypes = [\"post\", \"comment\", \"register\"];\n if (!validTypes.includes(type)) {\n console.error(\n chalk.red(\n `Invalid type \"${type}\". Must be one of: ${validTypes.join(\", \")}`\n )\n );\n process.exit(1);\n }\n return type as HistoryEntryType;\n}\n\n/**\n * Execute the feed history command\n */\nasync function executeFeedHistory(options: HistoryOptions): Promise<void> {\n // Handle --clear\n if (options.clear) {\n const count = getHistoryCount();\n if (count === 0) {\n console.log(chalk.gray(\"History is already empty.\"));\n return;\n }\n\n console.log(chalk.yellow(`This will delete ${count} history entries.`));\n\n if (!options.force) {\n const confirmed = await confirm(\n chalk.red(\"\\nAre you sure you want to clear history?\")\n );\n if (!confirmed) {\n console.log(chalk.gray(\"Cancelled.\"));\n return;\n }\n }\n\n clearHistory();\n console.log(chalk.green(\"History cleared.\"));\n return;\n }\n\n // Get history entries\n let entries: HistoryEntry[];\n if (options.type) {\n const validType = validateType(options.type);\n entries = getHistoryByType(validType, options.limit);\n } else {\n entries = getHistory(options.limit);\n }\n\n if (entries.length === 0) {\n if (options.json) {\n printJson([]);\n } else {\n console.log(chalk.gray(\"No history entries found.\"));\n console.log(\n chalk.gray(\n \"History is recorded when you post, comment, or register feeds.\"\n )\n );\n }\n return;\n }\n\n // Output\n if (options.json) {\n const jsonEntries = entries.map((entry, idx) =>\n historyEntryToJson(entry, idx)\n );\n printJson(jsonEntries);\n } else {\n const totalCount = getHistoryCount();\n const typeFilter = options.type ? ` (type: ${options.type})` : \"\";\n console.log(\n chalk.cyan(`Feed History${typeFilter} (${entries.length} of ${totalCount})\\n`)\n );\n\n for (let i = 0; i < entries.length; i++) {\n console.log(formatHistoryEntry(entries[i], i));\n if (i < entries.length - 1) {\n console.log(\"\");\n }\n }\n }\n}\n\n/**\n * Register the feed history subcommand\n */\nexport function registerFeedHistoryCommand(parent: Command): void {\n parent\n .command(\"history\")\n .description(\"View feed activity history (posts, comments, registrations)\")\n .option(\"--limit <n>\", \"Limit number of entries\", (value) =>\n parseInt(value, 10)\n )\n .option(\"--type <type>\", \"Filter by type: post, comment, or register\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--clear\", \"Clear all history\")\n .option(\"--force\", \"Skip confirmation prompt for --clear\")\n .action(async (options) => {\n await executeFeedHistory(options);\n });\n}\n","import { Command } from \"commander\";\nimport { registerFeedListCommand } from \"./list\";\nimport { registerFeedReadCommand } from \"./read\";\nimport { registerFeedPostCommand } from \"./post\";\nimport { registerFeedCommentWriteCommand } from \"./comment-write\";\nimport { registerFeedCommentReadCommand } from \"./comment-read\";\nimport { registerFeedRegisterCommand } from \"./register\";\nimport { registerFeedRepliesCommand } from \"./replies\";\nimport { registerFeedPostsCommand } from \"./posts\";\nimport { registerFeedConfigCommand } from \"./config\";\nimport { registerFeedHistoryCommand } from \"./history\";\n\n/**\n * Register the feed command group with the commander program\n */\nexport function registerFeedCommand(program: Command): void {\n const feedCommand = program\n .command(\"feed\")\n .description(\"Feed operations (read/write posts, comments, manage feeds)\");\n\n registerFeedListCommand(feedCommand);\n registerFeedReadCommand(feedCommand);\n registerFeedPostCommand(feedCommand);\n registerFeedCommentWriteCommand(feedCommand);\n registerFeedCommentReadCommand(feedCommand);\n registerFeedRegisterCommand(feedCommand);\n registerFeedRepliesCommand(feedCommand);\n registerFeedPostsCommand(feedCommand);\n registerFeedConfigCommand(feedCommand);\n registerFeedHistoryCommand(feedCommand);\n}\n\n// Re-export individual command registrations for botchan wrapper\nexport { registerFeedListCommand } from \"./list\";\nexport { registerFeedReadCommand } from \"./read\";\nexport { registerFeedPostCommand } from \"./post\";\nexport { registerFeedCommentWriteCommand } from \"./comment-write\";\nexport { registerFeedCommentReadCommand } from \"./comment-read\";\nexport { registerFeedRegisterCommand } from \"./register\";\nexport { registerFeedRepliesCommand } from \"./replies\";\nexport { registerFeedPostsCommand } from \"./posts\";\nexport { registerFeedConfigCommand } from \"./config\";\nexport { registerFeedHistoryCommand } from \"./history\";\n"]}
|