@emblemvault/hustle-react 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +225 -0
- package/dist/browser/hustle-react.js +14705 -0
- package/dist/browser/hustle-react.js.map +1 -0
- package/dist/components/index.cjs +3170 -0
- package/dist/components/index.cjs.map +1 -0
- package/dist/components/index.d.cts +58 -0
- package/dist/components/index.d.ts +58 -0
- package/dist/components/index.js +3143 -0
- package/dist/components/index.js.map +1 -0
- package/dist/hooks/index.cjs +695 -0
- package/dist/hooks/index.cjs.map +1 -0
- package/dist/hooks/index.d.cts +46 -0
- package/dist/hooks/index.d.ts +46 -0
- package/dist/hooks/index.js +691 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hustle-S48t4lTZ.d.cts +222 -0
- package/dist/hustle-S48t4lTZ.d.ts +222 -0
- package/dist/index.cjs +3588 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +229 -0
- package/dist/index.d.ts +229 -0
- package/dist/index.js +3547 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin-BUg7vMxe.d.cts +172 -0
- package/dist/plugin-BUg7vMxe.d.ts +172 -0
- package/dist/plugins/index.cjs +1235 -0
- package/dist/plugins/index.cjs.map +1 -0
- package/dist/plugins/index.d.cts +192 -0
- package/dist/plugins/index.d.ts +192 -0
- package/dist/plugins/index.js +1225 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/providers/index.cjs +694 -0
- package/dist/providers/index.cjs.map +1 -0
- package/dist/providers/index.d.cts +46 -0
- package/dist/providers/index.d.ts +46 -0
- package/dist/providers/index.js +691 -0
- package/dist/providers/index.js.map +1 -0
- package/package.json +87 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/plugins/predictionMarket.ts","../../src/plugins/migrateFun.ts","../../src/plugins/piiProtection.ts","../../src/plugins/userQuestion.ts","../../src/plugins/alert.ts","../../src/plugins/jsExecutor.ts","../../src/plugins/screenshot.ts","../../src/plugins/index.ts"],"names":["args"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n* Prediction Market Alpha Plugin\n*\n* Provides AI tools for searching and analyzing prediction markets\n* using the Dome API (https://api.domeapi.io)\n*\n* Supported platforms: Polymarket, Kalshi\n* \n* Get specific market details:\n* - \"Get details on the [market-slug] market\"\n* - \"Tell me more about that Bitcoin prediction market\"\n*\n* Get prices/odds:\n* - \"What are the current odds on [market]?\"\n* - \"What's the probability showing for [market]?\"\n*\n* Get trading activity:\n* - \"Show me recent trades on that market\"\n* - \"What's the trading activity like?\"\n* - \"What prediction market platforms are supported?\"\n* - \"Search Kalshi for markets about crypto\"\n* - \"Show me prediction markets on Polymarket about politics\"\n* - \"Get details on [ticker] from Kalshi\" \n */\n\nimport type { HustlePlugin } from '../types';\n\nconst DOME_API_BASE = 'https://api.domeapi.io/v1';\n\n/**\n * Supported prediction market platforms\n */\ntype Platform = 'polymarket' | 'kalshi';\n\n/**\n * Prediction Market Alpha Plugin\n *\n * Tools:\n * - get_supported_platforms: List supported prediction market platforms\n * - search_prediction_markets: Search for markets on Polymarket or Kalshi\n * - get_market_details: Get detailed info about a specific market\n * - get_market_prices: Get current prices/odds for a market\n * - get_market_trades: Get recent trading activity\n */\nexport const predictionMarketPlugin: HustlePlugin = {\n name: 'prediction-market-alpha',\n version: '1.1.0',\n description: 'Search and analyze prediction markets on Polymarket and Kalshi',\n\n tools: [\n {\n name: 'get_supported_platforms',\n description:\n 'Get a list of supported prediction market platforms. Call this first to know which platforms are available for querying.',\n parameters: {\n type: 'object',\n properties: {},\n },\n },\n {\n name: 'search_prediction_markets',\n description:\n 'Search for prediction markets. Find markets about politics, crypto, sports, and more. Returns market titles, current odds, volume, and status. You MUST provide tags to filter results.',\n parameters: {\n type: 'object',\n properties: {\n platform: {\n type: 'string',\n enum: ['polymarket', 'kalshi'],\n description: 'The prediction market platform to search (default: polymarket)',\n },\n tags: {\n type: 'array',\n items: { type: 'string' },\n description: 'REQUIRED: Single word categories or tags to identify a market segment (e.g., \"politics\", \"crypto\", \"sports\", \"finance\", \"entertainment\", \"ai\")',\n },\n status: {\n type: 'string',\n enum: ['open', 'closed'],\n description: 'Filter by market status',\n },\n limit: {\n type: 'number',\n description: 'Number of results (1-100)',\n default: 10,\n },\n },\n required: ['tags'],\n },\n },\n {\n name: 'get_market_details',\n description:\n 'Get detailed information about a specific prediction market including current prices, trading history, and resolution source.',\n parameters: {\n type: 'object',\n properties: {\n platform: {\n type: 'string',\n enum: ['polymarket', 'kalshi'],\n description: 'The prediction market platform (default: polymarket)',\n },\n market_slug: {\n type: 'string',\n description: 'The market slug/identifier (ticker for Kalshi)',\n },\n },\n required: ['market_slug'],\n },\n },\n {\n name: 'get_market_prices',\n description:\n 'Get current prices/odds for a prediction market. Shows probability for each outcome.',\n parameters: {\n type: 'object',\n properties: {\n platform: {\n type: 'string',\n enum: ['polymarket', 'kalshi'],\n description: 'The prediction market platform (default: polymarket)',\n },\n market_slug: {\n type: 'string',\n description: 'The market slug/identifier (ticker for Kalshi)',\n },\n },\n required: ['market_slug'],\n },\n },\n {\n name: 'get_market_trades',\n description: 'Get recent orders/trading activity for a prediction market.',\n parameters: {\n type: 'object',\n properties: {\n platform: {\n type: 'string',\n enum: ['polymarket', 'kalshi'],\n description: 'The prediction market platform (default: polymarket)',\n },\n market_slug: {\n type: 'string',\n description: 'The market slug/identifier (ticker for Kalshi)',\n },\n limit: {\n type: 'number',\n description: 'Number of orders to return (max 100)',\n default: 20,\n },\n },\n required: ['market_slug'],\n },\n },\n ],\n\n executors: {\n get_supported_platforms: async () => {\n return {\n platforms: [\n {\n id: 'polymarket',\n name: 'Polymarket',\n description: 'Decentralized prediction market on Polygon',\n features: ['tags', 'volume_filtering'],\n },\n {\n id: 'kalshi',\n name: 'Kalshi',\n description: 'CFTC-regulated prediction market exchange',\n features: ['regulated', 'event_based'],\n },\n ],\n };\n },\n\n search_prediction_markets: async (args) => {\n const platform = (args.platform as Platform) || 'polymarket';\n const params = new URLSearchParams();\n\n if (args.limit) params.append('limit', String(args.limit));\n\n if (platform === 'polymarket') {\n if (args.tags) params.append('tags', (args.tags as string[]).join(','));\n if (args.status) params.append('status', args.status as string);\n\n const response = await fetch(`${DOME_API_BASE}/polymarket/markets?${params}`);\n\n if (!response.ok) {\n throw new Error(`Dome API error: ${response.status} ${response.statusText}`);\n }\n\n const data = await response.json();\n\n return {\n platform: 'polymarket',\n markets: data.markets?.map((m: Record<string, unknown>) => ({\n slug: m.market_slug,\n title: m.title,\n status: m.status,\n volume: m.volume_total,\n tags: m.tags,\n outcomes: [\n { label: (m.side_a as Record<string, unknown>)?.label, id: (m.side_a as Record<string, unknown>)?.id },\n { label: (m.side_b as Record<string, unknown>)?.label, id: (m.side_b as Record<string, unknown>)?.id },\n ],\n winner: m.winning_side,\n })) || [],\n total: data.pagination?.total || 0,\n hasMore: data.pagination?.has_more || false,\n };\n } else if (platform === 'kalshi') {\n if (args.status) params.append('status', args.status as string);\n\n const response = await fetch(`${DOME_API_BASE}/kalshi/markets?${params}`);\n\n if (!response.ok) {\n throw new Error(`Dome API error: ${response.status} ${response.statusText}`);\n }\n\n const data = await response.json();\n\n return {\n platform: 'kalshi',\n markets: data.markets?.map((m: Record<string, unknown>) => ({\n ticker: m.ticker,\n title: m.title,\n status: m.status,\n category: m.category,\n subtitle: m.subtitle,\n yesAsk: m.yes_ask,\n yesBid: m.yes_bid,\n volume: m.volume,\n })) || [],\n total: data.pagination?.total || 0,\n hasMore: data.pagination?.has_more || false,\n };\n }\n\n throw new Error(`Unsupported platform: ${platform}`);\n },\n\n get_market_details: async (args) => {\n const platform = (args.platform as Platform) || 'polymarket';\n\n if (platform === 'polymarket') {\n const response = await fetch(\n `${DOME_API_BASE}/polymarket/markets?market_slug=${args.market_slug}`\n );\n\n if (!response.ok) {\n throw new Error(`Dome API error: ${response.status} ${response.statusText}`);\n }\n\n const data = await response.json();\n const market = data.markets?.[0];\n\n if (!market) {\n throw new Error(`Market not found: ${args.market_slug}`);\n }\n\n return {\n platform: 'polymarket',\n slug: market.market_slug,\n title: market.title,\n status: market.status,\n startTime: market.start_time\n ? new Date(market.start_time * 1000).toISOString()\n : null,\n endTime: market.end_time\n ? new Date(market.end_time * 1000).toISOString()\n : null,\n volume: {\n total: market.volume_total,\n week: market.volume_1_week,\n month: market.volume_1_month,\n },\n resolutionSource: market.resolution_source,\n outcomes: [\n { label: market.side_a?.label, id: market.side_a?.id },\n { label: market.side_b?.label, id: market.side_b?.id },\n ],\n winner: market.winning_side,\n tags: market.tags,\n };\n } else if (platform === 'kalshi') {\n const response = await fetch(\n `${DOME_API_BASE}/kalshi/markets?ticker=${args.market_slug}`\n );\n\n if (!response.ok) {\n throw new Error(`Dome API error: ${response.status} ${response.statusText}`);\n }\n\n const data = await response.json();\n const market = data.markets?.[0];\n\n if (!market) {\n throw new Error(`Market not found: ${args.market_slug}`);\n }\n\n return {\n platform: 'kalshi',\n ticker: market.ticker,\n title: market.title,\n subtitle: market.subtitle,\n status: market.status,\n category: market.category,\n yesAsk: market.yes_ask,\n yesBid: market.yes_bid,\n volume: market.volume,\n openInterest: market.open_interest,\n };\n }\n\n throw new Error(`Unsupported platform: ${platform}`);\n },\n\n get_market_prices: async (args) => {\n const platform = (args.platform as Platform) || 'polymarket';\n\n if (platform === 'polymarket') {\n const response = await fetch(\n `${DOME_API_BASE}/polymarket/market-price?market_slug=${args.market_slug}`\n );\n\n if (!response.ok) {\n throw new Error(`Dome API error: ${response.status} ${response.statusText}`);\n }\n\n const data = await response.json();\n return { platform: 'polymarket', ...data };\n } else if (platform === 'kalshi') {\n // Kalshi prices are included in the market details\n const response = await fetch(\n `${DOME_API_BASE}/kalshi/markets?ticker=${args.market_slug}`\n );\n\n if (!response.ok) {\n throw new Error(`Dome API error: ${response.status} ${response.statusText}`);\n }\n\n const data = await response.json();\n const market = data.markets?.[0];\n\n if (!market) {\n throw new Error(`Market not found: ${args.market_slug}`);\n }\n\n return {\n platform: 'kalshi',\n ticker: market.ticker,\n yesAsk: market.yes_ask,\n yesBid: market.yes_bid,\n lastPrice: market.last_price,\n };\n }\n\n throw new Error(`Unsupported platform: ${platform}`);\n },\n\n get_market_trades: async (args) => {\n const platform = (args.platform as Platform) || 'polymarket';\n const limit = String(args.limit || 20);\n\n if (platform === 'polymarket') {\n const params = new URLSearchParams({\n market_slug: args.market_slug as string,\n limit,\n });\n\n const response = await fetch(\n `${DOME_API_BASE}/polymarket/orders?${params}`\n );\n\n if (!response.ok) {\n throw new Error(`Dome API error: ${response.status} ${response.statusText}`);\n }\n\n const data = await response.json();\n return { platform: 'polymarket', ...data };\n } else if (platform === 'kalshi') {\n const params = new URLSearchParams({\n ticker: args.market_slug as string,\n limit,\n });\n\n const response = await fetch(\n `${DOME_API_BASE}/kalshi/trades?${params}`\n );\n\n if (!response.ok) {\n throw new Error(`Dome API error: ${response.status} ${response.statusText}`);\n }\n\n const data = await response.json();\n return { platform: 'kalshi', ...data };\n }\n\n throw new Error(`Unsupported platform: ${platform}`);\n },\n },\n\n hooks: {\n onRegister: () => {\n console.log('[Plugin] Prediction Market Alpha v1.1.0 registered (Polymarket + Kalshi)');\n },\n },\n};\n\nexport default predictionMarketPlugin;\n","/**\n * Migrate.fun Knowledge Base Plugin\n *\n * Provides AI tools for answering questions about token migrations\n * using an embedded knowledge base from real support conversations.\n *\n * Supported topics: Bonk Fun, Pump Fun, Raydium migrations,\n * costs/fees, timelines, post-migration steps, technical details.\n *\n * Example prompts:\n * - \"How does a migration to Pump Fun work?\"\n * - \"What does Migrate Fun cost?\"\n * - \"What steps do I need to do after the migration?\"\n * - \"How long is the migration period?\"\n * - \"What is the claim period for migrations?\"\n * - \"Has Migrate Fun been audited?\"\n * - \"What happens to tokens on exchanges during migration?\"\n * - \"Can I change the total supply when migrating?\"\n *\n * System prompt suggestion (for optimal results):\n * You are a support agent for Migrate.fun, the token migration platform on Solana.\n * You have the `search_migrate_fun_docs` tool - ALWAYS use it when users ask about migrations.\n * Key facts: 3.75% fee, 90-day claim period, supports Bonk Fun/Pump Fun/Raydium, audited by Halborn.\n * For complex questions: direct to https://x.com/MigrateFun\n */\n\nimport type { HustlePlugin } from '../types';\n\n/**\n * Q&A entry structure\n */\ninterface QAEntry {\n id: string;\n question: string;\n answer: string;\n keywords: string[];\n category: string;\n}\n\n/**\n * Embedded knowledge base from real support conversations\n */\nconst QA: QAEntry[] = [\n { id: 'migration-steps-bonk', question: 'What are all the steps for migrations to Bonk?', answer: `Here's how MigrateFun migrates your token to BonkFun:\\n1) The creator/team sets up a migration portal through migratefun - Create new CA for BonkFun (Ticker, name, image, supply) and set timeline period (1-30 days, 14 days average)\\n2) After portal setup, holders commit their tokens to migration - tokens are locked in migration vault until time period ends\\n3) Once migration ends, ALL tokens are market sold in a single candle to retrieve as much SOL as possible from the locked liquidity pool\\n4) The recovered SOL seeds the new LP paired with appropriate amount of tokens. Set market cap at or slightly below current market cap\\n5) Claims open for 90 days - users burn MFTs and receive new tokens`, keywords: ['bonk', 'bonkfun', 'steps', 'process', 'how'], category: 'process' },\n { id: 'migration-steps-pumpfun', question: 'How does a migration work to Pump Fun?', answer: `Here's how the migration to Pump Fun works:\\n1) Set up a new CA for pumpfun using MigrateFun creator dashboard (Ticker, CA, image)\\n2) Users migrate their tokens in the migration portal for a specific time period\\n3) Once migration ends, MigrateFun sells all migrated tokens\\n4) MigrateFun takes all recovered SOL and buys out new token's bonding curve + purchases until it reaches old market cap levels\\n5) Users return to migratefun and claim their new tokens\\n6) 90-day claim period for all users, regardless if they migrated on time or late\\n7) The claim period can also be used to swap tokens with centralized exchanges\\n8) After 90 days, all unclaimed tokens and remaining SOL are returned to the team`, keywords: ['pump', 'pumpfun', 'steps', 'process', 'how'], category: 'process' },\n { id: 'migration-steps-raydium', question: 'How does Migrate Fun migrate tokens to Raydium?', answer: `1) The creator/team sets up a migration portal through migratefun.com - Create new CA (Ticker, name, image, supply) and set timeline period (1-30 days, 14 days average)\\n2) After portal setup, holders commit their tokens to migration and get MFTs in exchange - tokens are locked in migration vault until time period ends\\n3) Once migration ends, ALL old tokens are market sold in a single candle to retrieve as much SOL as possible\\n4) The recovered SOL seeds the new LP paired with appropriate amount of new tokens. Market Cap is set by the user\\n5) Claims open for 90 days - users burn MFTs and receive new tokens. Late migrators can swap at discounted rate\\n6) At the end of the 90 day claim window all remaining tokens can be claimed by the team`, keywords: ['raydium', 'steps', 'process', 'how'], category: 'process' },\n { id: 'post-migration-checklist', question: 'What are the steps I need to do after the migration?', answer: `Admin Checklist - places to register your new CA:\\n\\nPRIMARY:\\n- Coingecko (Free + migration application process)\\n- Dexscreener ($300)\\n- GeckoTerminal (free for 5 days wait)\\n- Holderscan (Listing free, Verify $125)\\n\\nSECONDARY:\\n- Solscan (if metadata updates needed)\\n- CoinMarketCap ($5000 for immediate listing)\\n- Dextools ($300 for verification)\\n- Photon (2 SOL)\\n- Cookie.fun (Free, DM needed) [For AI accounts]\\n- Kaito (DM needed) [For AI accounts]\\n\\nNote: Coingecko and CoinMarketCap will ask for a post from official twitter with migration details and new CA.`, keywords: ['after', 'post', 'checklist', 'listing', 'dexscreener', 'coingecko'], category: 'post-migration' },\n { id: 'post-migration-approval', question: 'Do we need to do anything after the migration ends?', answer: `Yes, the team needs to approve several steps in the migration portal including:\\n1) Selling the migrated tokens into the old LP\\n2) Setting the new market cap\\n3) Opening the claim portal\\n\\nVideo tutorial: https://www.youtube.com/watch?v=SjPN-1DnXtM`, keywords: ['after', 'ends', 'approve', 'portal'], category: 'post-migration' },\n { id: 'market-cap-setting', question: 'What market cap should we set?', answer: `Set at or slightly below the ending market cap at migration. For example, if your ending market cap is $1 million, set it to around $950,000. This accounts for the fact you won't receive 1:1 liquidity from the old pool compared to the new pool, which is determined by migration participation.`, keywords: ['market cap', 'marketcap', 'set', 'recommend'], category: 'settings' },\n { id: 'migrate-fun-cost', question: 'What does Migrate Fun cost?', answer: `Migrate Fun charges a flat 3.75% fee on the total SOL unlocked from the old Liquidity Pool. This fee is taken automatically during the migration process.`, keywords: ['cost', 'fee', 'price', 'charge', '3.75', 'percent'], category: 'fees' },\n { id: 'claim-fees-bonk', question: 'How does the team claim their fees on Bonk Fun?', answer: `Go to https://bonk.fun/creator-rewards to claim your creator fees.`, keywords: ['claim', 'fees', 'bonk', 'creator', 'rewards'], category: 'fees' },\n { id: 'claim-fees-raydium', question: 'How do I claim fees on Raydium?', answer: `You can claim fees from https://raydium.io/portfolio/ with the same wallet that set up the migration.`, keywords: ['claim', 'fees', 'raydium', 'portfolio'], category: 'fees' },\n { id: 'claim-fees-pumpfun', question: 'How do I claim fees on Pump Fun?', answer: `Fees are paid automatically to the wallet used to set up the migration. Once migrated to PumpSwap you will receive creator rewards based on their Ascend Program. Details: https://pump.fun/docs/fees`, keywords: ['claim', 'fees', 'pump', 'pumpfun', 'automatic'], category: 'fees' },\n { id: 'audit-info', question: 'Has Migrate Fun been audited?', answer: `Yes. Migrate Fun was audited by Halborn, the same auditing firm used by the Solana Foundation.\\nAudit: https://www.halborn.com/audits/emblem-vault/migratefun-8ad34b\\nAnnouncement: https://x.com/HalbornSecurity/status/1978869642744811933`, keywords: ['audit', 'audited', 'security', 'halborn', 'safe'], category: 'security' },\n { id: 'user-experience', question: 'What is the process like for the user?', answer: `Super easy - takes less than 20 seconds.\\n1) During migration: users swap old tokens for Migrate Fun Tokens (MFTs)\\n2) Once migration ends: claim period opens for 90 days, users burn MFTs to claim new tokens\\n3) Late migrators: can swap old tokens for new at a discounted rate set by the team\\n\\nVideo guides:\\n- Migration: https://x.com/MigrateFun/status/1971259552856408433\\n- Claims: https://x.com/MigrateFun/status/1976376597906325767`, keywords: ['user', 'experience', 'process', 'simple', 'easy'], category: 'user-experience' },\n { id: 'what-is-migrate-fun', question: 'What is Migrate Fun?', answer: `Migrate Fun is the category-defining platform that created the migration meta. It allows users to migrate locked liquidity from one launchpad to another.\\n\\nAs of October 2025: 15 migrations completed, $5+ million in liquidity moved, largest migration was $35M market cap project. Supports migrations to Bonk Fun, Raydium, and Pump Fun.\\n\\nLinks:\\n- Website: https://migrate.fun/\\n- X: https://x.com/MigrateFun\\n- Docs: https://github.com/EmblemCompany/Migrate-fun-docs/\\n- Audit: https://www.halborn.com/audits/emblem-vault/migratefun-8ad34b\\n- Calculator: https://migrate.fun/migration-calculator`, keywords: ['what', 'migrate fun', 'about', 'general', 'overview'], category: 'general' },\n { id: 'sol-recovery-estimate', question: 'How can I see how much SOL we can get from the old LP?', answer: `Use the migration calculator to estimate SOL recovery based on participation percentages: https://migrate.fun/migration-calculator`, keywords: ['sol', 'recovery', 'estimate', 'calculator', 'liquidity', 'how much'], category: 'tools' },\n { id: 'documentation', question: 'Do you have documentation?', answer: `Yes, documentation is available at: https://github.com/EmblemCompany/Migrate-fun-docs/`, keywords: ['documentation', 'docs', 'guide', 'help'], category: 'general' },\n { id: 'rebrand', question: 'What if I want to rebrand?', answer: `The migration enables a full rebrand - reset metadata, image, logo, name, everything. Or keep it all the same if you prefer.`, keywords: ['rebrand', 'change', 'name', 'logo', 'image', 'metadata'], category: 'features' },\n { id: 'sniper-protection', question: 'How do you prevent snipers when migrating to Pump Fun?', answer: `On Solana you can stack transactions. When deploying the bonding curve, you are first to purchase so you can buyout the bonding curve and more in the first transaction, preventing snipers.`, keywords: ['sniper', 'snipers', 'protection', 'front-run', 'mev'], category: 'security' },\n { id: 'claim-period-flexibility', question: 'Is there flexibility on the 90 day claim period?', answer: `The 90-day claim period is mandatory. Reasons:\\n- All users need time to claim tokens after migration\\n- Those who missed migration need a window\\n- Users don't get tokens until after migration completes\\n- Allowing team to withdraw during claims would be risky (potential rug)`, keywords: ['90 day', 'claim', 'period', 'flexibility', 'change'], category: 'settings' },\n { id: 'migration-duration', question: 'How long is the migration?', answer: `You can set the migration window for as long as you'd like. Average is 14 days. Some teams choose 7 days (works great), some go up to 30 days.\\n\\nNote: Majority of participation happens in the first and last 24 hours. Example: 76% participation with 50%+ migrating in first 24 hours and additional 10% on the last day.`, keywords: ['how long', 'duration', 'time', 'days', 'period', 'window'], category: 'settings' },\n { id: 'migration-performance', question: 'Can you give examples of token performance after migration?', answer: `Migration squeeze: When large percentage of old tokens migrate, sell pressure reduces, often causing market cap spike near migration end.\\n\\nExample charts:\\n- ZERA Old: https://dexscreener.com/solana/95at5r4i85gfqeew2yr6byfg8rlry1d9ztps7qrskdvc\\n New: https://dexscreener.com/solana/nn9vmhjtqgg9l9f8sp3geufwc5zvuhradcwehh7n7di\\n- HUSTLE Old: https://dexscreener.com/solana/gjckb2eesjk65nuvpaw4tn2rabnr8wmfcwcwpagk5dzs\\n New: https://dexscreener.com/solana/hxo1wrcrdewek8l2j6rxswnolumej2mweh38gajxtw7y\\n\\nThread: https://x.com/jakegallen_/status/1973051293213028468`, keywords: ['performance', 'charts', 'example', 'before', 'after', 'squeeze'], category: 'examples' },\n { id: 'why-migrate', question: 'Why would teams want to migrate?', answer: `Top reasons:\\n- Access to creator rewards\\n- Rebrand opportunity\\n- Fresh chart\\n- Reclaim part of the token supply\\n- Reinvigorated community on the other side`, keywords: ['why', 'reasons', 'benefits', 'advantages', 'should'], category: 'general' },\n { id: 'migration-recommendation-steps', question: 'What steps do you recommend when considering a migration?', answer: `1) Discuss with Migrate Fun team: process details, where to move LP (Raydium, Bonk Fun, or Pump Fun)\\n2) Discuss benefits with your community, especially whale holders - get buy-in\\n3) Announce on all social channels - maximize awareness for maximum participation`, keywords: ['recommend', 'steps', 'considering', 'planning', 'prepare'], category: 'process' },\n { id: 'multiple-wallets', question: 'Do holders with multiple wallets need to consolidate?', answer: `No. Migration is linear - users can migrate all tokens together or separately. Makes no difference.`, keywords: ['multiple', 'wallets', 'consolidate', 'separate'], category: 'user-experience' },\n { id: 'mft-value', question: 'Do MFTs show value in wallets?', answer: `MFTs (Migrate Fun Tokens) are just placeholder tokens for the migration. They are valueless.`, keywords: ['mft', 'migrate fun tokens', 'value', 'placeholder'], category: 'user-experience' },\n { id: 'announcement-examples', question: 'Can you give me sample migration announcements?', answer: `Here are announcements made by teams:\\n- https://x.com/radrdotfun/status/1952127168101949620\\n- https://x.com/project_89/status/1951345024656089368\\n- https://x.com/HKittyOnSol/status/1948925330032349210\\n- https://x.com/ModernStoicAI/status/1948129627362218483\\n- https://x.com/pokithehamster/status/1950238636928327927\\n- https://x.com/IQ6900_/status/1953002036599173499\\n- https://x.com/TheBongoCat/status/1965538945132843333`, keywords: ['announcement', 'sample', 'example', 'post', 'twitter'], category: 'examples' },\n { id: 'graphics', question: 'Does Migrate Fun provide graphics for announcements?', answer: `No. For your own migration announcement you create the graphic. Migrate Fun's designer creates group migration announcements only.`, keywords: ['graphics', 'images', 'design', 'announcement'], category: 'general' },\n { id: 'developer-required', question: 'Do I need to be a developer to migrate?', answer: `No development required. The entire process is a few clicks for both pre-migration and post-migration.`, keywords: ['developer', 'technical', 'coding', 'code'], category: 'general' },\n { id: 'exchange-tokens', question: 'What happens to tokens on exchanges or locked in Streamflow?', answer: `They will miss the migration as those tokens are considered circulating supply onchain. Options:\\n1) Join as late migrator during 90-day claim window\\n2) After 90-day period, team takes possession of unclaimed tokens and can reimburse directly`, keywords: ['exchange', 'streamflow', 'locked', 'vested', 'cex'], category: 'edge-cases' },\n { id: 'unclaimed-tokens', question: 'Can we get unclaimed tokens?', answer: `After the 90-day claim period ends, all unclaimed tokens are returned to whichever wallet set up the migration (the team).`, keywords: ['unclaimed', 'supply', 'remaining', 'tokens', 'team'], category: 'post-migration' },\n { id: 'participation-rate', question: 'What is typical participation percentage?', answer: `Nearly all projects have had over 50% migration participation. View all stats at https://migrate.fun/projects`, keywords: ['participation', 'percentage', 'rate', 'typical', 'average'], category: 'statistics' },\n { id: 'late-penalty', question: 'What penalty can teams set for late migrators?', answer: `Teams can set 0-100% penalty for late migrators who swap during the 90-day claim window. 25% seems to be a good balance - encourages participation without being overly punishing.`, keywords: ['penalty', 'late', 'discount', 'punish', 'percent'], category: 'settings' },\n { id: 'new-ca', question: 'Will we get a new CA or just change the pair?', answer: `A new CA. If migrating to Bonk Fun your CA will end with \"bonk\". If migrating to Pump Fun it will end with \"pump\".`, keywords: ['ca', 'contract', 'address', 'new', 'pair'], category: 'process' },\n { id: 'vanity-ca', question: 'Can we create a vanity CA?', answer: `Yes, but if migrating to Bonk Fun it needs to end with \"bonk\", or for Pump Fun it needs to end with \"pump\".`, keywords: ['vanity', 'ca', 'custom', 'address', 'contract'], category: 'features' },\n { id: 'vested-tokens', question: 'What about team tokens locked with Streamflow?', answer: `Those tokens can't be migrated. They won't be lost - you'll recapture that supply post-migration. Any unmigrated tokens return to team at full or discounted rate depending on your late migrator penalty setting.`, keywords: ['vested', 'streamflow', 'locked', 'team'], category: 'edge-cases' },\n { id: 'wallet-tracking', question: 'Can I track wallet addresses post-migration?', answer: `At the end of migration, there's a snapshot tool that lets you download a CSV of all wallets holding the old token.`, keywords: ['wallet', 'track', 'snapshot', 'csv', 'addresses'], category: 'tools' },\n { id: 'old-listings', question: 'What happens to old token listings?', answer: `You will need to apply to new directories. Migrate Fun provides a list once you begin the migration process.`, keywords: ['listings', 'directories', 'old', 'new', 'update'], category: 'post-migration' },\n { id: 'lp-locking', question: 'Does the new LP get locked?', answer: `If migrating to Bonk Fun or Pump Fun: LP is locked (their rules). If migrating to Raydium: LP is unlocked and you control it.`, keywords: ['lp', 'locked', 'liquidity', 'pool', 'control'], category: 'process' },\n { id: 'sol-pairs', question: 'Are Bonk migrations confined to SOL pairs?', answer: `As of October 2025, they are SOL migrations. Check with the team to see if USD1 pairs are possible.`, keywords: ['sol', 'pair', 'usd1', 'usdc', 'bonk'], category: 'settings' },\n { id: 'change-penalty', question: 'Can I change the penalty after setup?', answer: `No. The penalty must be set during migration creation and cannot be changed after.`, keywords: ['change', 'penalty', 'modify', 'update', 'after'], category: 'settings' },\n { id: 'unhappy-holders', question: 'What if someone is unhappy about the migration?', answer: `They can sell their tokens and not participate. Migrations are a fresh start - holders who migrate are voting with their tokens that they support the team and believe in the project's future.`, keywords: ['unhappy', 'disagree', 'against', 'sell'], category: 'user-experience' },\n { id: 'sample-announcement', question: 'What is a good announcement template?', answer: `Sample for Bonk Fun migration:\\n\\n\"We're excited to announce that we're migrating with @MigrateFun and officially joining the @bonk_inu ecosystem next month!\\n\\nWith our 1-year anniversary less than a month away, this migration to @bonk_fun marks the beginning of our next chapter.\\n\\nWhy Bonk Fun?\\n🧰 Purpose-built tools for community projects\\n💸 Transaction fee rev share\\n🔁 Seamless LP migration\\n🤝 Strategic alignment with top meme coin teams\\n\\nOur migration timeline + holder instructions drop soon.\"`, keywords: ['announcement', 'template', 'sample', 'post'], category: 'examples' },\n { id: 'share-link', question: 'Do you have a link to share explaining Migrate Fun?', answer: `Overview thread: https://x.com/migratefun/status/1957492884355314035\\nDeep dive docs: https://github.com/EmblemCompany/Migrate-fun-docs/`, keywords: ['link', 'share', 'explain', 'overview'], category: 'general' },\n { id: 'exchange-rate', question: 'Is the exchange rate always 1:1?', answer: `Yes, 1 old token = 1 new token for users who participate in migration. Users who miss can swap during the 90-day claim window at a discounted rate set by the team.`, keywords: ['exchange', 'rate', '1:1', 'ratio', 'same'], category: 'process' },\n { id: 'change-supply', question: 'Can I change the total supply?', answer: `Generally yes, with some constraints depending on destination platform. Reach out to Migrate Fun team to discuss specifics.`, keywords: ['supply', 'change', 'total', 'amount'], category: 'features' },\n { id: 'contact', question: 'How can I get in touch with the Migrate Fun team?', answer: `Send a direct message to the Migrate Fun X account: https://x.com/MigrateFun`, keywords: ['contact', 'reach', 'touch', 'dm', 'message', 'talk'], category: 'general' },\n { id: 'ready-to-migrate', question: 'I am ready to migrate, what is next?', answer: `Send a direct message to the Migrate Fun X account: https://x.com/MigrateFun`, keywords: ['ready', 'start', 'begin', 'next'], category: 'general' },\n { id: 'risks', question: 'What are the risks of migrating?', answer: `Main risk: Failed migration where not enough tokens migrate to fund the new LP. In that case, migrated tokens are sold into the old LP and SOL is returned to community members who participated.`, keywords: ['risk', 'danger', 'fail', 'problem', 'issue'], category: 'security' },\n { id: 'how-detect-non-migrators', question: 'How does Migrate Fun know who did not migrate?', answer: `Migrate Fun has a snapshot and claim tool that puts onchain all wallets holding old tokens at migration end. This enables late migrators to swap old tokens for new during the 90-day claim window at the team-set discount.`, keywords: ['snapshot', 'detect', 'know', 'non-migrators'], category: 'tools' },\n { id: 'no-penalty', question: 'What if I do not want to penalize non-migrators?', answer: `Set the late claim penalty to zero. Holders who didn't migrate can then swap old tokens for new at a 1:1 rate during the 90-day claim window.`, keywords: ['no penalty', 'zero', 'fair'], category: 'settings' },\n { id: 'missed-claim-window', question: 'What happens if holders miss both migration and claim window?', answer: `They won't have access to new tokens through Migrate Fun platform. All remaining tokens go to the team after 90-day window closes. The team has a snapshot of all old token holders and can handle at their discretion.`, keywords: ['missed', 'both', 'claim', 'window', 'late'], category: 'edge-cases' },\n { id: 'exchange-options', question: 'What options do exchanges have to swap tokens?', answer: `Two options:\\n\\nOption 1: Participate onchain through the migration portal (same as retail). Load tokens into Phantom wallet, migrate, then claim. ~10 seconds each step.\\n\\nOption 2: Admin withdraw function during 90-day claim period. Migration admin can withdraw new tokens from claims vault and manually swap with exchange.\\n- 90-day window for exchange procedures\\n- Exchange can observe migration complete before acting\\n- Can receive new tokens before sending old\\n- Can pause trading during process`, keywords: ['exchange', 'cex', 'swap', 'options', 'centralized'], category: 'edge-cases' },\n { id: 'buy-prevent-dump', question: 'Can we buy supply before migration to prevent dumping?', answer: `I would recommend buying now. There is no arb opportunity as you set the market cap of the new token.\\n\\nTo regain control of non-migrated tokens, you can penalize non-migrators. Example: If 60% migrate, 40% didn't. With a 50% penalty on non-migrators, you'd recoup 20% of total supply if everyone claimed.`, keywords: ['buy', 'dump', 'supply', 'control', 'arb'], category: 'strategy' },\n];\n\n/**\n * Search result structure\n */\ninterface SearchResult {\n rank: number;\n relevance: number;\n question: string;\n answer: string;\n category: string;\n}\n\n/**\n * Migrate.fun Knowledge Base Plugin\n *\n * Tools:\n * - search_migrate_fun_docs: Search the knowledge base for migration Q&A\n */\nexport const migrateFunPlugin: HustlePlugin = {\n name: 'migrate-fun-knowledge',\n version: '1.0.0',\n description: 'Search Migrate.fun knowledge base for token migration answers',\n\n tools: [\n {\n name: 'search_migrate_fun_docs',\n description:\n 'Search the Migrate.fun knowledge base for answers about token migrations. Use this tool when users ask about: how migrations work (Bonk Fun, Pump Fun, Raydium), costs/fees/timelines, post-migration steps, user experience, technical details (LP, CA, penalties), or examples. Returns ranked Q&A pairs from real support conversations.',\n parameters: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'The search query - user question or key terms about token migrations',\n },\n topK: {\n type: 'number',\n description: 'Number of results to return (default: 5, max: 10)',\n },\n },\n required: ['query'],\n },\n },\n ],\n\n executors: {\n search_migrate_fun_docs: async (args) => {\n const query = args.query as string;\n const topK = Math.min(Math.max(1, (args.topK as number) || 5), 10);\n\n const queryLower = query.toLowerCase();\n const queryWords = queryLower.split(/\\s+/).filter(w => w.length > 2);\n\n // Score each Q&A entry\n const scored = QA.map(qa => {\n let score = 0;\n const questionLower = qa.question.toLowerCase();\n const answerLower = qa.answer.toLowerCase();\n const keywordsStr = qa.keywords.join(' ').toLowerCase();\n const fullText = `${questionLower} ${answerLower} ${keywordsStr}`;\n\n // Exact phrase match in question (highest weight)\n if (questionLower.includes(queryLower)) score += 15;\n\n // Exact phrase match anywhere\n if (fullText.includes(queryLower)) score += 8;\n\n // Individual word matches\n for (const word of queryWords) {\n // Keyword match (high weight)\n if (qa.keywords.some(kw => kw.toLowerCase().includes(word) || word.includes(kw.toLowerCase()))) {\n score += 4;\n }\n // Question match (medium weight)\n if (questionLower.includes(word)) score += 3;\n // Answer match (low weight)\n if (answerLower.includes(word)) score += 1;\n }\n\n return { ...qa, score };\n });\n\n // Filter, sort, and format results\n const results: SearchResult[] = scored\n .filter(qa => qa.score > 0)\n .sort((a, b) => b.score - a.score)\n .slice(0, topK)\n .map((qa, i) => ({\n rank: i + 1,\n relevance: Math.round((qa.score / 30) * 100) / 100,\n question: qa.question,\n answer: qa.answer,\n category: qa.category,\n }));\n\n return {\n success: true,\n query,\n resultCount: results.length,\n results,\n hint: results.length === 0\n ? 'No matches found. Suggest contacting @MigrateFun on X: https://x.com/MigrateFun'\n : 'Use these Q&A pairs to answer. Include relevant links from the answers.',\n };\n },\n },\n\n hooks: {\n onRegister: () => {\n console.log('[Plugin] Migrate.fun Knowledge Base v1.0.0 registered');\n },\n },\n};\n\nexport default migrateFunPlugin;\n","/**\n * PII Protection Plugin\n *\n * Demonstrates the beforeRequest/afterResponse hook lifecycle by\n * tokenizing PII (Personally Identifiable Information) before sending\n * to the AI, then restoring it in responses.\n *\n * Supported PII types:\n * - Social Security Numbers (XXX-XX-XXXX)\n * - Email addresses\n * - Phone numbers (various formats)\n * - Credit card numbers\n *\n * This plugin maintains a persistent token map so the same PII value\n * always maps to the same token across requests (prevents re-masking\n * with different tokens on follow-up messages).\n */\n\nimport type { HustlePlugin, HustleRequest, ProcessedResponse } from '../types';\n\n/**\n * Storage keys for cross-hook communication\n */\nconst TOKEN_MAP_KEY = '__piiTokenMaps';\nconst PERSISTENT_MAP_KEY = '__piiPersistentMap';\n\n/**\n * Get the request-specific token maps (for cleanup)\n */\nfunction getTokenMaps(): Map<string, Map<string, string>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const storage: Record<string, unknown> = typeof window !== 'undefined' ? (window as any) : (global as any);\n\n if (!storage[TOKEN_MAP_KEY]) {\n storage[TOKEN_MAP_KEY] = new Map();\n }\n return storage[TOKEN_MAP_KEY] as Map<string, Map<string, string>>;\n}\n\n/**\n * Get the persistent PII -> token map (reuses tokens for same PII)\n */\nfunction getPersistentMap(): { piiToToken: Map<string, string>; tokenToPii: Map<string, string>; counter: { value: number } } {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const storage: Record<string, unknown> = typeof window !== 'undefined' ? (window as any) : (global as any);\n\n if (!storage[PERSISTENT_MAP_KEY]) {\n storage[PERSISTENT_MAP_KEY] = {\n piiToToken: new Map<string, string>(),\n tokenToPii: new Map<string, string>(),\n counter: { value: 0 },\n };\n }\n return storage[PERSISTENT_MAP_KEY] as { piiToToken: Map<string, string>; tokenToPii: Map<string, string>; counter: { value: number } };\n}\n\n/**\n * PII Protection Plugin\n *\n * Uses beforeRequest to tokenize PII, afterResponse to restore it.\n * Maintains persistent mapping so same PII always gets same token.\n */\nexport const piiProtectionPlugin: HustlePlugin = {\n name: 'pii-protection',\n version: '1.0.0',\n description: 'Tokenizes PII before sending to AI, restores in responses',\n\n tools: [],\n executors: {},\n\n hooks: {\n onRegister: () => {\n console.log('[PII Protection] Plugin registered - PII will be tokenized in requests');\n },\n\n beforeRequest: (request: HustleRequest): HustleRequest => {\n const maps = getTokenMaps();\n const persistent = getPersistentMap();\n const requestId = Date.now().toString();\n const requestTokenMap = new Map<string, string>();\n\n const tokenize = (text: string): string => {\n if (typeof text !== 'string') return text;\n\n return text\n // SSNs: 123-45-6789\n .replace(/\\b\\d{3}-\\d{2}-\\d{4}\\b/g, (match) => {\n // Check if we already have a token for this PII\n if (persistent.piiToToken.has(match)) {\n const existingToken = persistent.piiToToken.get(match)!;\n requestTokenMap.set(existingToken, match);\n return existingToken;\n }\n const token = `{{SSN_${++persistent.counter.value}}}`;\n persistent.piiToToken.set(match, token);\n persistent.tokenToPii.set(token, match);\n requestTokenMap.set(token, match);\n return token;\n })\n // Email addresses\n .replace(/\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b/gi, (match) => {\n if (persistent.piiToToken.has(match)) {\n const existingToken = persistent.piiToToken.get(match)!;\n requestTokenMap.set(existingToken, match);\n return existingToken;\n }\n const token = `{{EMAIL_${++persistent.counter.value}}}`;\n persistent.piiToToken.set(match, token);\n persistent.tokenToPii.set(token, match);\n requestTokenMap.set(token, match);\n return token;\n })\n // Phone numbers\n .replace(/\\(?\\d{3}\\)?[-.\\s]?\\d{3}[-.\\s]?\\d{4}/g, (match) => {\n if (persistent.piiToToken.has(match)) {\n const existingToken = persistent.piiToToken.get(match)!;\n requestTokenMap.set(existingToken, match);\n return existingToken;\n }\n const token = `{{PHONE_${++persistent.counter.value}}}`;\n persistent.piiToToken.set(match, token);\n persistent.tokenToPii.set(token, match);\n requestTokenMap.set(token, match);\n return token;\n })\n // Credit card numbers\n .replace(/\\b\\d{4}[-\\s]?\\d{4}[-\\s]?\\d{4}[-\\s]?\\d{4}\\b/g, (match) => {\n if (persistent.piiToToken.has(match)) {\n const existingToken = persistent.piiToToken.get(match)!;\n requestTokenMap.set(existingToken, match);\n return existingToken;\n }\n const token = `{{CARD_${++persistent.counter.value}}}`;\n persistent.piiToToken.set(match, token);\n persistent.tokenToPii.set(token, match);\n requestTokenMap.set(token, match);\n return token;\n });\n };\n\n // Tokenize PII in each message\n const anonymizedMessages = request.messages.map(msg => ({\n ...msg,\n content: typeof msg.content === 'string' ? tokenize(msg.content) : msg.content,\n }));\n\n // Store the token map for this request\n if (requestTokenMap.size > 0) {\n maps.set(requestId, requestTokenMap);\n console.log(`[PII Protection] Tokenized ${requestTokenMap.size} PII values`);\n }\n\n return { ...request, messages: anonymizedMessages };\n },\n\n afterResponse: (response: ProcessedResponse): void => {\n const persistent = getPersistentMap();\n\n // Restore tokens using the persistent map\n if (typeof response.content === 'string') {\n let restored = response.content;\n let restoredCount = 0;\n\n for (const [token, original] of persistent.tokenToPii.entries()) {\n if (restored.includes(token)) {\n restored = restored.split(token).join(original);\n restoredCount++;\n }\n }\n\n if (restoredCount > 0) {\n response.content = restored;\n console.log(`[PII Protection] Restored ${restoredCount} PII values`);\n }\n }\n },\n },\n};\n","/**\n * User Question Plugin\n *\n * Provides a tool that allows the AI to ask the user multiple choice\n * questions via a modal dialog. The executor returns a Promise that\n * resolves when the user makes a selection, enabling synchronous-feeling\n * async user interaction.\n *\n * This demonstrates:\n * - Tool executor returning a Promise for async UI interaction\n * - Creating and managing DOM elements from an executor\n * - Collecting user input and returning it to the AI\n */\n\nimport type { HustlePlugin, ClientToolDefinition, ToolExecutor } from '../types';\n\n/**\n * Create modal styles if they don't exist\n */\nfunction ensureModalStyles(): void {\n if (typeof document === 'undefined') return;\n\n const styleId = 'user-question-modal-styles';\n if (document.getElementById(styleId)) return;\n\n const styles = document.createElement('style');\n styles.id = styleId;\n styles.textContent = `\n .user-question-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.6);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n animation: uqFadeIn 0.2s ease-out;\n }\n\n @keyframes uqFadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n\n .user-question-modal {\n background: #1a1a2e;\n border: 1px solid #333;\n border-radius: 12px;\n padding: 24px;\n max-width: 480px;\n width: 90%;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4);\n animation: uqSlideUp 0.2s ease-out;\n }\n\n @keyframes uqSlideUp {\n from { transform: translateY(20px); opacity: 0; }\n to { transform: translateY(0); opacity: 1; }\n }\n\n .user-question-title {\n font-size: 18px;\n font-weight: 600;\n color: #fff;\n margin: 0 0 16px 0;\n }\n\n .user-question-choices {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 20px;\n }\n\n .user-question-choice {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n background: #252540;\n border: 1px solid #333;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s ease;\n }\n\n .user-question-choice:hover {\n background: #2a2a4a;\n border-color: #4a4a6a;\n }\n\n .user-question-choice.selected {\n background: #2a3a5a;\n border-color: #4a7aff;\n }\n\n .user-question-choice input {\n margin: 0;\n accent-color: #4a7aff;\n }\n\n .user-question-choice label {\n flex: 1;\n color: #e0e0e0;\n cursor: pointer;\n font-size: 14px;\n }\n\n .user-question-actions {\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n }\n\n .user-question-btn {\n padding: 10px 20px;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n }\n\n .user-question-btn-cancel {\n background: transparent;\n border: 1px solid #444;\n color: #aaa;\n }\n\n .user-question-btn-cancel:hover {\n background: #333;\n color: #fff;\n }\n\n .user-question-btn-submit {\n background: #4a7aff;\n border: none;\n color: #fff;\n }\n\n .user-question-btn-submit:hover {\n background: #5a8aff;\n }\n\n .user-question-btn-submit:disabled {\n background: #333;\n color: #666;\n cursor: not-allowed;\n }\n `;\n document.head.appendChild(styles);\n}\n\n/**\n * Tool definition for ask_user\n */\nconst askUserTool: ClientToolDefinition = {\n name: 'ask_user',\n description: `Ask the user a multiple choice question and wait for their response. Use this when you need user input to proceed - for example: clarifying requirements, getting preferences, or confirming actions. The tool blocks until the user responds.`,\n parameters: {\n type: 'object',\n properties: {\n question: {\n type: 'string',\n description: 'The question to ask the user',\n },\n choices: {\n type: 'array',\n items: { type: 'string' },\n description: 'Array of choices to present (2-6 options recommended)',\n },\n allowMultiple: {\n type: 'boolean',\n description: 'If true, user can select multiple choices. Default: false',\n },\n },\n required: ['question', 'choices'],\n },\n};\n\n/**\n * Arguments for ask_user tool\n */\ninterface AskUserArgs {\n question: string;\n choices: string[];\n allowMultiple?: boolean;\n}\n\n/**\n * Result from ask_user tool\n */\ninterface AskUserResult {\n question: string;\n selectedChoices: string[];\n answered: boolean;\n}\n\n/**\n * Executor for ask_user tool\n * Creates a modal and returns a Promise that resolves when user responds\n */\nconst askUserExecutor: ToolExecutor = async (args: Record<string, unknown>): Promise<AskUserResult> => {\n const { question, choices, allowMultiple = false } = args as unknown as AskUserArgs;\n\n // Validate inputs\n if (!question || !choices || !Array.isArray(choices) || choices.length === 0) {\n return {\n question: question || '',\n selectedChoices: [],\n answered: false,\n };\n }\n\n // Server-side fallback\n if (typeof document === 'undefined') {\n console.log(`[User Question] Question: ${question}`);\n console.log(`[User Question] Choices: ${choices.join(', ')}`);\n return {\n question,\n selectedChoices: [choices[0]],\n answered: true,\n };\n }\n\n ensureModalStyles();\n\n return new Promise<AskUserResult>((resolve) => {\n const selected = new Set<string>();\n\n // Create overlay\n const overlay = document.createElement('div');\n overlay.className = 'user-question-overlay';\n\n // Create modal\n const modal = document.createElement('div');\n modal.className = 'user-question-modal';\n\n // Title\n const title = document.createElement('h3');\n title.className = 'user-question-title';\n title.textContent = question;\n modal.appendChild(title);\n\n // Choices container\n const choicesDiv = document.createElement('div');\n choicesDiv.className = 'user-question-choices';\n\n const inputType = allowMultiple ? 'checkbox' : 'radio';\n const inputName = `uq-${Date.now()}`;\n\n choices.forEach((choice, index) => {\n const choiceDiv = document.createElement('div');\n choiceDiv.className = 'user-question-choice';\n\n const input = document.createElement('input');\n input.type = inputType;\n input.name = inputName;\n input.id = `${inputName}-${index}`;\n input.value = choice;\n\n const label = document.createElement('label');\n label.htmlFor = input.id;\n label.textContent = choice;\n\n choiceDiv.appendChild(input);\n choiceDiv.appendChild(label);\n\n // Handle selection\n const handleSelect = () => {\n if (allowMultiple) {\n if (selected.has(choice)) {\n selected.delete(choice);\n choiceDiv.classList.remove('selected');\n } else {\n selected.add(choice);\n choiceDiv.classList.add('selected');\n }\n } else {\n selected.clear();\n selected.add(choice);\n choicesDiv.querySelectorAll('.user-question-choice').forEach(c => c.classList.remove('selected'));\n choiceDiv.classList.add('selected');\n }\n updateSubmitButton();\n };\n\n input.addEventListener('change', handleSelect);\n choiceDiv.addEventListener('click', (e) => {\n if (e.target !== input) {\n input.checked = !input.checked || !allowMultiple;\n handleSelect();\n }\n });\n\n choicesDiv.appendChild(choiceDiv);\n });\n\n modal.appendChild(choicesDiv);\n\n // Actions\n const actions = document.createElement('div');\n actions.className = 'user-question-actions';\n\n const cancelBtn = document.createElement('button');\n cancelBtn.className = 'user-question-btn user-question-btn-cancel';\n cancelBtn.textContent = 'Skip';\n cancelBtn.onclick = () => {\n cleanup();\n resolve({\n question,\n selectedChoices: [],\n answered: false,\n });\n };\n\n const submitBtn = document.createElement('button');\n submitBtn.className = 'user-question-btn user-question-btn-submit';\n submitBtn.textContent = 'Submit';\n submitBtn.disabled = true;\n submitBtn.onclick = () => {\n cleanup();\n resolve({\n question,\n selectedChoices: Array.from(selected),\n answered: true,\n });\n };\n\n const updateSubmitButton = () => {\n submitBtn.disabled = selected.size === 0;\n };\n\n actions.appendChild(cancelBtn);\n actions.appendChild(submitBtn);\n modal.appendChild(actions);\n\n overlay.appendChild(modal);\n document.body.appendChild(overlay);\n\n // Cleanup function\n const cleanup = () => {\n overlay.remove();\n };\n\n // Close on escape\n const handleEscape = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n document.removeEventListener('keydown', handleEscape);\n cleanup();\n resolve({\n question,\n selectedChoices: [],\n answered: false,\n });\n }\n };\n document.addEventListener('keydown', handleEscape);\n });\n};\n\n/**\n * User Question Plugin\n *\n * Provides the ask_user tool for AI to request user input via modal.\n */\nexport const userQuestionPlugin: HustlePlugin = {\n name: 'user-question',\n version: '1.0.0',\n description: 'Allows AI to ask users multiple choice questions via modal',\n\n tools: [askUserTool],\n executors: {\n ask_user: askUserExecutor,\n },\n\n hooks: {\n onRegister: () => {\n console.log('[User Question] Plugin registered - AI can now ask you questions');\n },\n },\n};\n","/**\n * Alert Plugin\n *\n * Provides a simple tool to display browser alert popups.\n * Useful for notifications, confirmations, or getting user attention.\n */\n\nimport type { HustlePlugin, ClientToolDefinition, ToolExecutor } from '../types';\n\n/**\n * Tool definition for send_alert\n */\nconst sendAlertTool: ClientToolDefinition = {\n name: 'send_alert',\n description: 'Display a browser alert popup with a message to the user',\n parameters: {\n type: 'object',\n properties: {\n message: {\n type: 'string',\n description: 'The message to display in the alert popup',\n },\n },\n required: ['message'],\n },\n};\n\n/**\n * Executor for send_alert tool\n */\nconst sendAlertExecutor: ToolExecutor = async (args: Record<string, unknown>) => {\n const message = args.message as string;\n\n // Server-side fallback\n if (typeof window === 'undefined') {\n console.log(`[Alert] ${message}`);\n return { success: true, message, environment: 'server' };\n }\n\n alert(message);\n return { success: true, message };\n};\n\n/**\n * Alert Plugin\n */\nexport const alertPlugin: HustlePlugin = {\n name: 'alert',\n version: '1.0.0',\n description: 'Display browser alert popups',\n\n tools: [sendAlertTool],\n executors: {\n send_alert: sendAlertExecutor,\n },\n\n hooks: {\n onRegister: () => {\n console.log('[Alert] Plugin registered');\n },\n },\n};\n","/**\n * JavaScript Executor Plugin\n *\n * Provides a tool to execute arbitrary JavaScript code in the browser.\n * Captures console output and return values for AI consumption.\n *\n * WARNING: This plugin executes arbitrary code. Only enable for trusted contexts.\n */\n\nimport type { HustlePlugin, ClientToolDefinition, ToolExecutor } from '../types';\n\n/**\n * Tool definition for execute_javascript\n */\nconst executeJsTool: ClientToolDefinition = {\n name: 'execute_javascript',\n description: `Execute JavaScript code in the browser and return the results. The code runs in the page context with access to DOM, window, localStorage, etc.\n\nIMPORTANT USAGE NOTES:\n- Use console.log() to output values that will be captured and returned\n- The last expression's value OR explicit return statement will be captured as 'returnValue'\n- All console.log calls are captured in the 'logs' array\n- For multi-line code, escape newlines or use semicolons: \"const x = 1; const y = 2; console.log(x + y);\"\n- Example: \"const prices = [100, 200, 150]; const avg = prices.reduce((a,b) => a+b, 0) / prices.length; console.log('Average:', avg); return avg;\"\n- Can access: document, window, localStorage, fetch, etc.`,\n parameters: {\n type: 'object',\n properties: {\n code: {\n type: 'string',\n description: 'The JavaScript code to execute. Use console.log() for output and/or return a value.',\n },\n },\n required: ['code'],\n },\n};\n\ninterface LogEntry {\n type: 'log' | 'warn' | 'error';\n args: string[];\n}\n\ninterface ExecuteResult {\n success: boolean;\n returnValue: string | null;\n logs: LogEntry[];\n error: { message: string; stack?: string } | null;\n}\n\n/**\n * Executor for execute_javascript tool\n */\nconst executeJsExecutor: ToolExecutor = async (args: Record<string, unknown>): Promise<ExecuteResult> => {\n const code = args.code as string;\n\n // Server-side fallback\n if (typeof window === 'undefined') {\n return {\n success: false,\n returnValue: null,\n logs: [],\n error: { message: 'JavaScript execution requires browser environment' },\n };\n }\n\n const logs: LogEntry[] = [];\n const originalLog = console.log;\n const originalWarn = console.warn;\n const originalError = console.error;\n\n // Hook console methods to capture output\n console.log = (...logArgs: unknown[]) => {\n logs.push({\n type: 'log',\n args: logArgs.map(a => typeof a === 'object' ? JSON.stringify(a) : String(a)),\n });\n originalLog.apply(console, logArgs);\n };\n console.warn = (...logArgs: unknown[]) => {\n logs.push({\n type: 'warn',\n args: logArgs.map(a => typeof a === 'object' ? JSON.stringify(a) : String(a)),\n });\n originalWarn.apply(console, logArgs);\n };\n console.error = (...logArgs: unknown[]) => {\n logs.push({\n type: 'error',\n args: logArgs.map(a => typeof a === 'object' ? JSON.stringify(a) : String(a)),\n });\n originalError.apply(console, logArgs);\n };\n\n let returnValue: unknown;\n let error: { message: string; stack?: string } | null = null;\n\n try {\n // Wrap code to capture return value\n const wrappedCode = '(async () => { ' + code + ' })()';\n // eslint-disable-next-line no-eval\n returnValue = await eval(wrappedCode);\n } catch (e) {\n const err = e as Error;\n error = { message: err.message, stack: err.stack };\n } finally {\n // Restore original console methods\n console.log = originalLog;\n console.warn = originalWarn;\n console.error = originalError;\n }\n\n return {\n success: !error,\n returnValue: returnValue !== undefined\n ? (typeof returnValue === 'object' ? JSON.stringify(returnValue) : String(returnValue))\n : null,\n logs,\n error,\n };\n};\n\n/**\n * JavaScript Executor Plugin\n */\nexport const jsExecutorPlugin: HustlePlugin = {\n name: 'js-executor',\n version: '1.0.0',\n description: 'Execute JavaScript code in the browser',\n\n tools: [executeJsTool],\n executors: {\n execute_javascript: executeJsExecutor,\n },\n\n hooks: {\n onRegister: () => {\n console.log('[JS Executor] Plugin registered - AI can now execute JavaScript');\n },\n },\n};\n","/**\n * Screenshot Plugin\n *\n * Provides a tool to capture screenshots of the current page or specific elements.\n * Uses html2canvas for rendering and uploads to the server.\n */\n\nimport type { HustlePlugin, ClientToolDefinition, ToolExecutor } from '../types';\n\n// Extend window type for html2canvas\ndeclare global {\n interface Window {\n html2canvas?: (\n element: HTMLElement,\n options?: Record<string, unknown>\n ) => Promise<HTMLCanvasElement>;\n }\n}\n\n/**\n * Tool definition for take_screenshot\n */\nconst screenshotTool: ClientToolDefinition = {\n name: 'take_screenshot',\n description: `Take a screenshot of the current page and upload it. Returns the URL of the uploaded image that can be used in conversation or for analysis.\n\nThe screenshot captures the visible viewport of the page. The image is uploaded to the server and a permanent URL is returned.\n\nUse this when:\n- User asks to see what's on their screen\n- You need to analyze the current page visually\n- User wants to share/save the current view`,\n parameters: {\n type: 'object',\n properties: {\n selector: {\n type: 'string',\n description: 'Optional CSS selector to capture a specific element instead of the full page. Leave empty for full page screenshot.',\n },\n },\n },\n};\n\ninterface ScreenshotResult {\n success: boolean;\n url?: string;\n contentType?: string;\n message?: string;\n error?: string;\n}\n\n/**\n * Executor for take_screenshot tool\n */\nconst screenshotExecutor: ToolExecutor = async (args: Record<string, unknown>): Promise<ScreenshotResult> => {\n const selector = args.selector as string | undefined;\n\n // Server-side fallback\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n return {\n success: false,\n error: 'Screenshot requires browser environment',\n };\n }\n\n try {\n // Dynamically load html2canvas if not already loaded\n if (!window.html2canvas) {\n await new Promise<void>((resolve, reject) => {\n const script = document.createElement('script');\n script.src = 'https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js';\n script.onload = () => resolve();\n script.onerror = () => reject(new Error('Failed to load html2canvas'));\n document.head.appendChild(script);\n });\n }\n\n // Determine target element\n const target = selector\n ? document.querySelector(selector) as HTMLElement\n : document.body;\n\n if (!target) {\n return { success: false, error: 'Element not found: ' + selector };\n }\n\n // Capture screenshot\n const canvas = await window.html2canvas!(target, {\n useCORS: true,\n allowTaint: true,\n backgroundColor: '#000000',\n scale: 1,\n });\n\n // Convert to blob\n const blob = await new Promise<Blob | null>((resolve) => {\n canvas.toBlob(resolve, 'image/png', 0.9);\n });\n\n if (!blob) {\n return { success: false, error: 'Failed to create image blob' };\n }\n\n // Create FormData and upload\n const formData = new FormData();\n formData.append('file', blob, 'screenshot-' + Date.now() + '.png');\n\n const response = await fetch('/api/files/upload', {\n method: 'POST',\n body: formData,\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({})) as { error?: string };\n return { success: false, error: errorData.error || 'Upload failed' };\n }\n\n const data = await response.json() as { url: string; contentType: string };\n\n return {\n success: true,\n url: data.url,\n contentType: data.contentType,\n message: 'Screenshot captured and uploaded successfully',\n };\n } catch (e) {\n const err = e as Error;\n return {\n success: false,\n error: err.message || 'Screenshot failed',\n };\n }\n};\n\n/**\n * Screenshot Plugin\n */\nexport const screenshotPlugin: HustlePlugin = {\n name: 'screenshot',\n version: '1.0.0',\n description: 'Take screenshots of the current page',\n\n tools: [screenshotTool],\n executors: {\n take_screenshot: screenshotExecutor,\n },\n\n hooks: {\n onRegister: () => {\n console.log('[Screenshot] Plugin registered - AI can now take screenshots');\n },\n },\n};\n","/**\n * Plugin Registry\n *\n * Available plugins that can be installed by users.\n * This is a hardcoded registry for the PoC - in the future\n * this could be fetched from a remote plugin marketplace.\n *\n * NOTE: Plugins no longer need to be pre-registered. Executor code\n * is now serialized to localStorage as executorCode strings and\n * reconstituted at runtime via eval().\n */\n\nimport { predictionMarketPlugin } from './predictionMarket';\nimport { migrateFunPlugin } from './migrateFun';\nimport { piiProtectionPlugin } from './piiProtection';\nimport { userQuestionPlugin } from './userQuestion';\nimport { alertPlugin } from './alert';\nimport { jsExecutorPlugin } from './jsExecutor';\nimport { screenshotPlugin } from './screenshot';\nimport type { HustlePlugin } from '../types';\n\n/**\n * Available plugin with display metadata\n */\nexport interface AvailablePlugin extends HustlePlugin {\n /** Short description for UI display */\n description: string;\n}\n\n/**\n * All available plugins that can be installed\n */\nexport const availablePlugins: AvailablePlugin[] = [\n {\n ...predictionMarketPlugin,\n description: 'Search and analyze Polymarket and Kalshi prediction markets',\n },\n {\n ...migrateFunPlugin,\n description: 'Search Migrate.fun knowledge base for token migration answers',\n },\n {\n ...piiProtectionPlugin,\n description: 'Tokenizes PII before sending to AI, restores in responses',\n },\n {\n ...userQuestionPlugin,\n description: 'Allows AI to ask users multiple choice questions via modal',\n },\n {\n ...alertPlugin,\n description: 'Display browser alert popups',\n },\n {\n ...jsExecutorPlugin,\n description: 'Execute JavaScript code in the browser',\n },\n {\n ...screenshotPlugin,\n description: 'Take screenshots of the current page',\n },\n];\n\n/**\n * Get an available plugin by name\n */\nexport function getAvailablePlugin(name: string): AvailablePlugin | undefined {\n return availablePlugins.find(p => p.name === name);\n}\n\n// Re-export individual plugins\nexport { predictionMarketPlugin };\nexport { migrateFunPlugin };\nexport { piiProtectionPlugin };\nexport { userQuestionPlugin };\nexport { alertPlugin };\nexport { jsExecutorPlugin };\nexport { screenshotPlugin };\n"]}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { H as HustlePlugin } from '../plugin-BUg7vMxe.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Prediction Market Alpha Plugin
|
|
5
|
+
*
|
|
6
|
+
* Provides AI tools for searching and analyzing prediction markets
|
|
7
|
+
* using the Dome API (https://api.domeapi.io)
|
|
8
|
+
*
|
|
9
|
+
* Supported platforms: Polymarket, Kalshi
|
|
10
|
+
*
|
|
11
|
+
* Get specific market details:
|
|
12
|
+
* - "Get details on the [market-slug] market"
|
|
13
|
+
* - "Tell me more about that Bitcoin prediction market"
|
|
14
|
+
*
|
|
15
|
+
* Get prices/odds:
|
|
16
|
+
* - "What are the current odds on [market]?"
|
|
17
|
+
* - "What's the probability showing for [market]?"
|
|
18
|
+
*
|
|
19
|
+
* Get trading activity:
|
|
20
|
+
* - "Show me recent trades on that market"
|
|
21
|
+
* - "What's the trading activity like?"
|
|
22
|
+
* - "What prediction market platforms are supported?"
|
|
23
|
+
* - "Search Kalshi for markets about crypto"
|
|
24
|
+
* - "Show me prediction markets on Polymarket about politics"
|
|
25
|
+
* - "Get details on [ticker] from Kalshi"
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Prediction Market Alpha Plugin
|
|
30
|
+
*
|
|
31
|
+
* Tools:
|
|
32
|
+
* - get_supported_platforms: List supported prediction market platforms
|
|
33
|
+
* - search_prediction_markets: Search for markets on Polymarket or Kalshi
|
|
34
|
+
* - get_market_details: Get detailed info about a specific market
|
|
35
|
+
* - get_market_prices: Get current prices/odds for a market
|
|
36
|
+
* - get_market_trades: Get recent trading activity
|
|
37
|
+
*/
|
|
38
|
+
declare const predictionMarketPlugin: HustlePlugin;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Migrate.fun Knowledge Base Plugin
|
|
42
|
+
*
|
|
43
|
+
* Provides AI tools for answering questions about token migrations
|
|
44
|
+
* using an embedded knowledge base from real support conversations.
|
|
45
|
+
*
|
|
46
|
+
* Supported topics: Bonk Fun, Pump Fun, Raydium migrations,
|
|
47
|
+
* costs/fees, timelines, post-migration steps, technical details.
|
|
48
|
+
*
|
|
49
|
+
* Example prompts:
|
|
50
|
+
* - "How does a migration to Pump Fun work?"
|
|
51
|
+
* - "What does Migrate Fun cost?"
|
|
52
|
+
* - "What steps do I need to do after the migration?"
|
|
53
|
+
* - "How long is the migration period?"
|
|
54
|
+
* - "What is the claim period for migrations?"
|
|
55
|
+
* - "Has Migrate Fun been audited?"
|
|
56
|
+
* - "What happens to tokens on exchanges during migration?"
|
|
57
|
+
* - "Can I change the total supply when migrating?"
|
|
58
|
+
*
|
|
59
|
+
* System prompt suggestion (for optimal results):
|
|
60
|
+
* You are a support agent for Migrate.fun, the token migration platform on Solana.
|
|
61
|
+
* You have the `search_migrate_fun_docs` tool - ALWAYS use it when users ask about migrations.
|
|
62
|
+
* Key facts: 3.75% fee, 90-day claim period, supports Bonk Fun/Pump Fun/Raydium, audited by Halborn.
|
|
63
|
+
* For complex questions: direct to https://x.com/MigrateFun
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Migrate.fun Knowledge Base Plugin
|
|
68
|
+
*
|
|
69
|
+
* Tools:
|
|
70
|
+
* - search_migrate_fun_docs: Search the knowledge base for migration Q&A
|
|
71
|
+
*/
|
|
72
|
+
declare const migrateFunPlugin: HustlePlugin;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* PII Protection Plugin
|
|
76
|
+
*
|
|
77
|
+
* Demonstrates the beforeRequest/afterResponse hook lifecycle by
|
|
78
|
+
* tokenizing PII (Personally Identifiable Information) before sending
|
|
79
|
+
* to the AI, then restoring it in responses.
|
|
80
|
+
*
|
|
81
|
+
* Supported PII types:
|
|
82
|
+
* - Social Security Numbers (XXX-XX-XXXX)
|
|
83
|
+
* - Email addresses
|
|
84
|
+
* - Phone numbers (various formats)
|
|
85
|
+
* - Credit card numbers
|
|
86
|
+
*
|
|
87
|
+
* This plugin maintains a persistent token map so the same PII value
|
|
88
|
+
* always maps to the same token across requests (prevents re-masking
|
|
89
|
+
* with different tokens on follow-up messages).
|
|
90
|
+
*/
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* PII Protection Plugin
|
|
94
|
+
*
|
|
95
|
+
* Uses beforeRequest to tokenize PII, afterResponse to restore it.
|
|
96
|
+
* Maintains persistent mapping so same PII always gets same token.
|
|
97
|
+
*/
|
|
98
|
+
declare const piiProtectionPlugin: HustlePlugin;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* User Question Plugin
|
|
102
|
+
*
|
|
103
|
+
* Provides a tool that allows the AI to ask the user multiple choice
|
|
104
|
+
* questions via a modal dialog. The executor returns a Promise that
|
|
105
|
+
* resolves when the user makes a selection, enabling synchronous-feeling
|
|
106
|
+
* async user interaction.
|
|
107
|
+
*
|
|
108
|
+
* This demonstrates:
|
|
109
|
+
* - Tool executor returning a Promise for async UI interaction
|
|
110
|
+
* - Creating and managing DOM elements from an executor
|
|
111
|
+
* - Collecting user input and returning it to the AI
|
|
112
|
+
*/
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* User Question Plugin
|
|
116
|
+
*
|
|
117
|
+
* Provides the ask_user tool for AI to request user input via modal.
|
|
118
|
+
*/
|
|
119
|
+
declare const userQuestionPlugin: HustlePlugin;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Alert Plugin
|
|
123
|
+
*
|
|
124
|
+
* Provides a simple tool to display browser alert popups.
|
|
125
|
+
* Useful for notifications, confirmations, or getting user attention.
|
|
126
|
+
*/
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Alert Plugin
|
|
130
|
+
*/
|
|
131
|
+
declare const alertPlugin: HustlePlugin;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* JavaScript Executor Plugin
|
|
135
|
+
*
|
|
136
|
+
* Provides a tool to execute arbitrary JavaScript code in the browser.
|
|
137
|
+
* Captures console output and return values for AI consumption.
|
|
138
|
+
*
|
|
139
|
+
* WARNING: This plugin executes arbitrary code. Only enable for trusted contexts.
|
|
140
|
+
*/
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* JavaScript Executor Plugin
|
|
144
|
+
*/
|
|
145
|
+
declare const jsExecutorPlugin: HustlePlugin;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Screenshot Plugin
|
|
149
|
+
*
|
|
150
|
+
* Provides a tool to capture screenshots of the current page or specific elements.
|
|
151
|
+
* Uses html2canvas for rendering and uploads to the server.
|
|
152
|
+
*/
|
|
153
|
+
|
|
154
|
+
declare global {
|
|
155
|
+
interface Window {
|
|
156
|
+
html2canvas?: (element: HTMLElement, options?: Record<string, unknown>) => Promise<HTMLCanvasElement>;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Screenshot Plugin
|
|
161
|
+
*/
|
|
162
|
+
declare const screenshotPlugin: HustlePlugin;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Plugin Registry
|
|
166
|
+
*
|
|
167
|
+
* Available plugins that can be installed by users.
|
|
168
|
+
* This is a hardcoded registry for the PoC - in the future
|
|
169
|
+
* this could be fetched from a remote plugin marketplace.
|
|
170
|
+
*
|
|
171
|
+
* NOTE: Plugins no longer need to be pre-registered. Executor code
|
|
172
|
+
* is now serialized to localStorage as executorCode strings and
|
|
173
|
+
* reconstituted at runtime via eval().
|
|
174
|
+
*/
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Available plugin with display metadata
|
|
178
|
+
*/
|
|
179
|
+
interface AvailablePlugin extends HustlePlugin {
|
|
180
|
+
/** Short description for UI display */
|
|
181
|
+
description: string;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* All available plugins that can be installed
|
|
185
|
+
*/
|
|
186
|
+
declare const availablePlugins: AvailablePlugin[];
|
|
187
|
+
/**
|
|
188
|
+
* Get an available plugin by name
|
|
189
|
+
*/
|
|
190
|
+
declare function getAvailablePlugin(name: string): AvailablePlugin | undefined;
|
|
191
|
+
|
|
192
|
+
export { type AvailablePlugin, alertPlugin, availablePlugins, getAvailablePlugin, jsExecutorPlugin, migrateFunPlugin, piiProtectionPlugin, predictionMarketPlugin, screenshotPlugin, userQuestionPlugin };
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { H as HustlePlugin } from '../plugin-BUg7vMxe.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Prediction Market Alpha Plugin
|
|
5
|
+
*
|
|
6
|
+
* Provides AI tools for searching and analyzing prediction markets
|
|
7
|
+
* using the Dome API (https://api.domeapi.io)
|
|
8
|
+
*
|
|
9
|
+
* Supported platforms: Polymarket, Kalshi
|
|
10
|
+
*
|
|
11
|
+
* Get specific market details:
|
|
12
|
+
* - "Get details on the [market-slug] market"
|
|
13
|
+
* - "Tell me more about that Bitcoin prediction market"
|
|
14
|
+
*
|
|
15
|
+
* Get prices/odds:
|
|
16
|
+
* - "What are the current odds on [market]?"
|
|
17
|
+
* - "What's the probability showing for [market]?"
|
|
18
|
+
*
|
|
19
|
+
* Get trading activity:
|
|
20
|
+
* - "Show me recent trades on that market"
|
|
21
|
+
* - "What's the trading activity like?"
|
|
22
|
+
* - "What prediction market platforms are supported?"
|
|
23
|
+
* - "Search Kalshi for markets about crypto"
|
|
24
|
+
* - "Show me prediction markets on Polymarket about politics"
|
|
25
|
+
* - "Get details on [ticker] from Kalshi"
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Prediction Market Alpha Plugin
|
|
30
|
+
*
|
|
31
|
+
* Tools:
|
|
32
|
+
* - get_supported_platforms: List supported prediction market platforms
|
|
33
|
+
* - search_prediction_markets: Search for markets on Polymarket or Kalshi
|
|
34
|
+
* - get_market_details: Get detailed info about a specific market
|
|
35
|
+
* - get_market_prices: Get current prices/odds for a market
|
|
36
|
+
* - get_market_trades: Get recent trading activity
|
|
37
|
+
*/
|
|
38
|
+
declare const predictionMarketPlugin: HustlePlugin;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Migrate.fun Knowledge Base Plugin
|
|
42
|
+
*
|
|
43
|
+
* Provides AI tools for answering questions about token migrations
|
|
44
|
+
* using an embedded knowledge base from real support conversations.
|
|
45
|
+
*
|
|
46
|
+
* Supported topics: Bonk Fun, Pump Fun, Raydium migrations,
|
|
47
|
+
* costs/fees, timelines, post-migration steps, technical details.
|
|
48
|
+
*
|
|
49
|
+
* Example prompts:
|
|
50
|
+
* - "How does a migration to Pump Fun work?"
|
|
51
|
+
* - "What does Migrate Fun cost?"
|
|
52
|
+
* - "What steps do I need to do after the migration?"
|
|
53
|
+
* - "How long is the migration period?"
|
|
54
|
+
* - "What is the claim period for migrations?"
|
|
55
|
+
* - "Has Migrate Fun been audited?"
|
|
56
|
+
* - "What happens to tokens on exchanges during migration?"
|
|
57
|
+
* - "Can I change the total supply when migrating?"
|
|
58
|
+
*
|
|
59
|
+
* System prompt suggestion (for optimal results):
|
|
60
|
+
* You are a support agent for Migrate.fun, the token migration platform on Solana.
|
|
61
|
+
* You have the `search_migrate_fun_docs` tool - ALWAYS use it when users ask about migrations.
|
|
62
|
+
* Key facts: 3.75% fee, 90-day claim period, supports Bonk Fun/Pump Fun/Raydium, audited by Halborn.
|
|
63
|
+
* For complex questions: direct to https://x.com/MigrateFun
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Migrate.fun Knowledge Base Plugin
|
|
68
|
+
*
|
|
69
|
+
* Tools:
|
|
70
|
+
* - search_migrate_fun_docs: Search the knowledge base for migration Q&A
|
|
71
|
+
*/
|
|
72
|
+
declare const migrateFunPlugin: HustlePlugin;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* PII Protection Plugin
|
|
76
|
+
*
|
|
77
|
+
* Demonstrates the beforeRequest/afterResponse hook lifecycle by
|
|
78
|
+
* tokenizing PII (Personally Identifiable Information) before sending
|
|
79
|
+
* to the AI, then restoring it in responses.
|
|
80
|
+
*
|
|
81
|
+
* Supported PII types:
|
|
82
|
+
* - Social Security Numbers (XXX-XX-XXXX)
|
|
83
|
+
* - Email addresses
|
|
84
|
+
* - Phone numbers (various formats)
|
|
85
|
+
* - Credit card numbers
|
|
86
|
+
*
|
|
87
|
+
* This plugin maintains a persistent token map so the same PII value
|
|
88
|
+
* always maps to the same token across requests (prevents re-masking
|
|
89
|
+
* with different tokens on follow-up messages).
|
|
90
|
+
*/
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* PII Protection Plugin
|
|
94
|
+
*
|
|
95
|
+
* Uses beforeRequest to tokenize PII, afterResponse to restore it.
|
|
96
|
+
* Maintains persistent mapping so same PII always gets same token.
|
|
97
|
+
*/
|
|
98
|
+
declare const piiProtectionPlugin: HustlePlugin;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* User Question Plugin
|
|
102
|
+
*
|
|
103
|
+
* Provides a tool that allows the AI to ask the user multiple choice
|
|
104
|
+
* questions via a modal dialog. The executor returns a Promise that
|
|
105
|
+
* resolves when the user makes a selection, enabling synchronous-feeling
|
|
106
|
+
* async user interaction.
|
|
107
|
+
*
|
|
108
|
+
* This demonstrates:
|
|
109
|
+
* - Tool executor returning a Promise for async UI interaction
|
|
110
|
+
* - Creating and managing DOM elements from an executor
|
|
111
|
+
* - Collecting user input and returning it to the AI
|
|
112
|
+
*/
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* User Question Plugin
|
|
116
|
+
*
|
|
117
|
+
* Provides the ask_user tool for AI to request user input via modal.
|
|
118
|
+
*/
|
|
119
|
+
declare const userQuestionPlugin: HustlePlugin;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Alert Plugin
|
|
123
|
+
*
|
|
124
|
+
* Provides a simple tool to display browser alert popups.
|
|
125
|
+
* Useful for notifications, confirmations, or getting user attention.
|
|
126
|
+
*/
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Alert Plugin
|
|
130
|
+
*/
|
|
131
|
+
declare const alertPlugin: HustlePlugin;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* JavaScript Executor Plugin
|
|
135
|
+
*
|
|
136
|
+
* Provides a tool to execute arbitrary JavaScript code in the browser.
|
|
137
|
+
* Captures console output and return values for AI consumption.
|
|
138
|
+
*
|
|
139
|
+
* WARNING: This plugin executes arbitrary code. Only enable for trusted contexts.
|
|
140
|
+
*/
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* JavaScript Executor Plugin
|
|
144
|
+
*/
|
|
145
|
+
declare const jsExecutorPlugin: HustlePlugin;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Screenshot Plugin
|
|
149
|
+
*
|
|
150
|
+
* Provides a tool to capture screenshots of the current page or specific elements.
|
|
151
|
+
* Uses html2canvas for rendering and uploads to the server.
|
|
152
|
+
*/
|
|
153
|
+
|
|
154
|
+
declare global {
|
|
155
|
+
interface Window {
|
|
156
|
+
html2canvas?: (element: HTMLElement, options?: Record<string, unknown>) => Promise<HTMLCanvasElement>;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Screenshot Plugin
|
|
161
|
+
*/
|
|
162
|
+
declare const screenshotPlugin: HustlePlugin;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Plugin Registry
|
|
166
|
+
*
|
|
167
|
+
* Available plugins that can be installed by users.
|
|
168
|
+
* This is a hardcoded registry for the PoC - in the future
|
|
169
|
+
* this could be fetched from a remote plugin marketplace.
|
|
170
|
+
*
|
|
171
|
+
* NOTE: Plugins no longer need to be pre-registered. Executor code
|
|
172
|
+
* is now serialized to localStorage as executorCode strings and
|
|
173
|
+
* reconstituted at runtime via eval().
|
|
174
|
+
*/
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Available plugin with display metadata
|
|
178
|
+
*/
|
|
179
|
+
interface AvailablePlugin extends HustlePlugin {
|
|
180
|
+
/** Short description for UI display */
|
|
181
|
+
description: string;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* All available plugins that can be installed
|
|
185
|
+
*/
|
|
186
|
+
declare const availablePlugins: AvailablePlugin[];
|
|
187
|
+
/**
|
|
188
|
+
* Get an available plugin by name
|
|
189
|
+
*/
|
|
190
|
+
declare function getAvailablePlugin(name: string): AvailablePlugin | undefined;
|
|
191
|
+
|
|
192
|
+
export { type AvailablePlugin, alertPlugin, availablePlugins, getAvailablePlugin, jsExecutorPlugin, migrateFunPlugin, piiProtectionPlugin, predictionMarketPlugin, screenshotPlugin, userQuestionPlugin };
|