copilotkit 0.0.57 → 0.0.59

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.
Files changed (66) hide show
  1. package/LICENSE +21 -0
  2. package/dist/commands/base-command.js +9 -6
  3. package/dist/commands/base-command.js.map +1 -1
  4. package/dist/commands/create.d.ts +1 -1
  5. package/dist/commands/create.js +234 -59
  6. package/dist/commands/create.js.map +1 -1
  7. package/dist/commands/dev.js +94 -35
  8. package/dist/commands/dev.js.map +1 -1
  9. package/dist/commands/init.d.ts +0 -20
  10. package/dist/commands/init.js +243 -209
  11. package/dist/commands/init.js.map +1 -1
  12. package/dist/commands/login.js +44 -20
  13. package/dist/commands/login.js.map +1 -1
  14. package/dist/commands/logout.js +44 -20
  15. package/dist/commands/logout.js.map +1 -1
  16. package/dist/index.js.map +1 -1
  17. package/dist/lib/init/ide-docs.d.ts +1 -1
  18. package/dist/lib/init/ide-docs.js +19 -5
  19. package/dist/lib/init/ide-docs.js.map +1 -1
  20. package/dist/lib/init/index.js +171 -67
  21. package/dist/lib/init/index.js.map +1 -1
  22. package/dist/lib/init/questions.d.ts +1 -1
  23. package/dist/lib/init/questions.js +77 -18
  24. package/dist/lib/init/questions.js.map +1 -1
  25. package/dist/lib/init/scaffold/agent.js +30 -23
  26. package/dist/lib/init/scaffold/agent.js.map +1 -1
  27. package/dist/lib/init/scaffold/crew-inputs.js +17 -4
  28. package/dist/lib/init/scaffold/crew-inputs.js.map +1 -1
  29. package/dist/lib/init/scaffold/env.js +14 -11
  30. package/dist/lib/init/scaffold/env.js.map +1 -1
  31. package/dist/lib/init/scaffold/github.js +27 -6
  32. package/dist/lib/init/scaffold/github.js.map +1 -1
  33. package/dist/lib/init/scaffold/index.js +152 -62
  34. package/dist/lib/init/scaffold/index.js.map +1 -1
  35. package/dist/lib/init/scaffold/langgraph-assistants.js +14 -11
  36. package/dist/lib/init/scaffold/langgraph-assistants.js.map +1 -1
  37. package/dist/lib/init/scaffold/packages.js +3 -1
  38. package/dist/lib/init/scaffold/packages.js.map +1 -1
  39. package/dist/lib/init/scaffold/shadcn.js +88 -23
  40. package/dist/lib/init/scaffold/shadcn.js.map +1 -1
  41. package/dist/lib/init/types/index.js +77 -18
  42. package/dist/lib/init/types/index.js.map +1 -1
  43. package/dist/lib/init/types/questions.d.ts +19 -19
  44. package/dist/lib/init/types/questions.js +73 -17
  45. package/dist/lib/init/types/questions.js.map +1 -1
  46. package/dist/lib/init/types/templates.d.ts +2 -2
  47. package/dist/lib/init/types/templates.js +4 -1
  48. package/dist/lib/init/types/templates.js.map +1 -1
  49. package/dist/lib/init/utils.js.map +1 -1
  50. package/dist/services/analytics.service.d.ts +1 -1
  51. package/dist/services/analytics.service.js +4 -1
  52. package/dist/services/analytics.service.js.map +1 -1
  53. package/dist/services/auth.service.d.ts +1 -1
  54. package/dist/services/auth.service.js +35 -14
  55. package/dist/services/auth.service.js.map +1 -1
  56. package/dist/services/events.d.ts +33 -33
  57. package/dist/services/tunnel.service.js.map +1 -1
  58. package/dist/utils/detect-endpoint-type.utils.d.ts +1 -1
  59. package/dist/utils/detect-endpoint-type.utils.js +11 -4
  60. package/dist/utils/detect-endpoint-type.utils.js.map +1 -1
  61. package/dist/utils/trpc.js.map +1 -1
  62. package/dist/utils/version.d.ts +1 -1
  63. package/dist/utils/version.js +1 -1
  64. package/dist/utils/version.js.map +1 -1
  65. package/oclif.manifest.json +6 -163
  66. package/package.json +8 -4
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/init/types/questions.ts","../../../src/lib/init/utils.ts","../../../src/lib/init/types/templates.ts","../../../src/lib/init/ide-docs.ts","../../../src/lib/init/questions.ts"],"sourcesContent":["import {z} from 'zod'\nimport {Flags} from '@oclif/core'\nimport {isLocalhost} from '../utils.js'\n\n// ===== Core Constants =====\nexport const MODES = ['LangGraph', 'CrewAI', 'Mastra', 'LlamaIndex', 'Agno', 'AG2', 'MCP', 'Standard'] as const\nexport const CREW_TYPES = ['Crews', 'Flows'] as const\nexport const CHAT_COMPONENTS = ['CopilotChat', 'CopilotSidebar', 'Headless', 'CopilotPopup'] as const\nexport const LANGGRAPH_AGENTS = ['Python Starter', 'TypeScript Starter'] as const\nexport const CREW_FLOW_TEMPLATES = ['Starter'] as const\nexport const YES_NO = ['Yes', 'No'] as const\n// NEW: Deployment choice options for Branch B\nexport const DEPLOYMENT_CHOICES = ['Copilot Cloud', 'Self-hosted'] as const\n\n// ===== Sanitizers =====\nexport const sanitizers = {\n // Remove trailing slash from URLs\n url: (value: string): string => {\n if (!value) return value\n return value.trim().replace(/\\/+$/, '')\n },\n\n // Trim whitespace from strings\n trim: (value: string): string => {\n if (!value) return value\n return value.trim()\n },\n\n // Lowercase strings\n lowercase: (value: string): string => {\n if (!value) return value\n return value.toLowerCase().trim()\n },\n\n // Clean API keys (remove whitespace)\n apiKey: (value: string): string => {\n if (!value) return value\n return value.trim().replace(/\\s/g, '')\n },\n}\n\n// ===== Zod Schemas =====\n\n// Basic schemas\nexport const ModeSchema = z.enum(MODES)\nexport const CrewTypeSchema = z.enum(CREW_TYPES)\nexport const ChatComponentSchema = z.enum(CHAT_COMPONENTS)\nexport const LangGraphAgentSchema = z.enum(LANGGRAPH_AGENTS)\nexport const CrewFlowTemplateSchema = z.enum(CREW_FLOW_TEMPLATES)\nexport const YesNoSchema = z.enum(YES_NO)\n// NEW: Deployment choice schema for Branch B\nexport const DeploymentChoiceSchema = z.enum(DEPLOYMENT_CHOICES)\n\n// URL validation schema with preprocessing to remove trailing slash\nexport const UrlSchema = z.preprocess(\n (val) => sanitizers.url(String(val)),\n z.string().url('Please enter a valid URL').min(1, 'URL is required'),\n)\n\n// Token validation schema with preprocessing to trim\nexport const TokenSchema = z.preprocess((val) => sanitizers.trim(String(val)), z.string().min(1, 'Token is required'))\n\n// API key validation schema with preprocessing to remove whitespace\nexport const ApiKeySchema = z.preprocess(\n (val) => sanitizers.apiKey(String(val)),\n z.string().min(1, 'API key is required'),\n)\n\nexport const LLMApiKeySchema = z.preprocess((val) => sanitizers.apiKey(String(val)), z.string().optional())\n\n// Name validation schema with preprocessing to trim\nexport const NameSchema = z.preprocess((val) => sanitizers.trim(String(val)), z.string().min(1, 'Name is required'))\n\n// Config schema\nexport const ConfigSchema = z\n .object({\n // Core fields\n copilotKitVersion: z.string().optional(),\n mode: ModeSchema,\n chatUi: ChatComponentSchema.optional(),\n\n // Yes/No fields\n alreadyDeployed: YesNoSchema.optional(),\n fastApiEnabled: YesNoSchema.optional(),\n // DEPRECATED: useCopilotCloud - consolidated with signupForCopilotCloud\n useCopilotCloud: YesNoSchema.optional(),\n\n // LangGraph specific fields\n langGraphAgent: LangGraphAgentSchema.optional(),\n langGraphPlatform: YesNoSchema.optional(),\n langGraphPlatformUrl: UrlSchema.optional(),\n langGraphRemoteEndpointURL: UrlSchema.optional(),\n\n // CrewAI specific fields\n crewType: CrewTypeSchema.optional(),\n crewName: NameSchema.optional(),\n crewUrl: UrlSchema.optional(),\n crewBearerToken: TokenSchema.optional(),\n\n // API keys and tokens\n copilotCloudPublicApiKey: z.string().optional(),\n langSmithApiKey: ApiKeySchema.optional(),\n llmToken: LLMApiKeySchema.optional(),\n\n // IDE Documentation setup fields\n setupIDEDocs: YesNoSchema.optional(),\n selectedIDE: z.union([z.enum(['cursor', 'windsurf']), z.literal('skip')]).optional(),\n\n // NEW: A/B/C test fields\n deploymentChoice: DeploymentChoiceSchema.optional(), // For branch B only (Cloud vs Self-hosted)\n })\n .refine(\n (data) => {\n // If CrewAI is selected, require crew URL and bearer token\n if (data.mode === 'CrewAI') {\n return !!data.crewUrl && !!data.crewBearerToken\n }\n return true\n },\n {\n message: 'Crew URL and bearer token are required for CrewAI',\n path: ['crewUrl', 'crewBearerToken'],\n },\n )\n .refine(\n (data) => {\n // If LangGraph is selected with LangGraph Platform, require platform URL and LangSmith API key\n if (data.mode === 'LangGraph' && data.alreadyDeployed === 'Yes' && data.langGraphPlatform === 'Yes') {\n return (!!data.langGraphPlatformUrl && !!data.langSmithApiKey) || isLocalhost(data.langGraphPlatformUrl || '')\n }\n return true\n },\n {\n message: 'LangGraph Platform URL and LangSmith API key are required',\n path: ['langGraphPlatformUrl', 'langSmithApiKey'],\n },\n )\n\n// Export the inferred type from the schema\nexport type Config = z.infer<typeof ConfigSchema>\n\n// Question type definition with improved validation and sanitization\nexport type Question = {\n type: 'input' | 'yes/no' | 'select'\n name: keyof Config\n message: string\n choices?: readonly string[] | (() => Promise<{name: string; value: string}[]>)\n default?: string\n when?: (answers: Partial<Config>) => boolean | Promise<boolean>\n sensitive?: boolean\n validate?: (input: string) => true | string // Return true if valid, error message string if invalid\n sanitize?: (input: string) => string // Function to sanitize input before validation\n}\n\n// CLI flags definition with descriptions\nexport const ConfigFlags = {\n booth: Flags.boolean({description: 'Use CopilotKit in booth mode', default: false, char: 'b'}),\n mode: Flags.string({description: 'How you will be interacting with AI', options: MODES, char: 'm'}),\n 'copilotkit-version': Flags.string({description: 'CopilotKit version to use (e.g. 1.7.0)'}),\n 'use-copilot-cloud': Flags.string({description: 'Use Copilot Cloud for production-ready hosting', options: YES_NO}),\n 'langgraph-agent': Flags.string({description: 'LangGraph agent template to use', options: LANGGRAPH_AGENTS}),\n 'crew-type': Flags.string({description: 'CrewAI implementation type', options: CREW_TYPES}),\n 'crew-name': Flags.string({description: 'Name for your CrewAI agent'}),\n 'crew-url': Flags.string({description: 'URL endpoint for your CrewAI agent'}),\n 'crew-bearer-token': Flags.string({description: 'Bearer token for CrewAI authentication'}),\n 'langsmith-api-key': Flags.string({description: 'LangSmith API key for LangGraph observability'}),\n 'llm-token': Flags.string({description: 'API key for your preferred LLM provider'}),\n 'setup-ide-docs': Flags.string({description: 'Setup IDE documentation rules for AI assistance', options: YES_NO}),\n 'selected-ide': Flags.string({\n description: 'IDE to configure with documentation rules',\n options: ['cursor', 'windsurf', 'skip'],\n }),\n // NEW: A/B/C test flags\n 'deployment-choice': Flags.string({\n description: 'Choose between Copilot Cloud or Self-hosted deployment',\n options: DEPLOYMENT_CHOICES,\n }),\n}\n","export const isLocalhost = (url: string): boolean => {\n return url.includes('localhost') || url.includes('127.0.0.1') || url.includes('0.0.0.0')\n}\n","export type ChatTemplate = 'CopilotChat' | 'CopilotPopup' | 'CopilotSidebar'\n\nexport type StarterTemplate =\n | 'LangGraphPlatform'\n | 'RemoteEndpoint'\n | 'Standard'\n | 'CrewEnterprise'\n | 'CrewFlowsStarter'\n\nexport type Template = ChatTemplate | StarterTemplate\n\nconst BASE_URL = 'https://registry.copilotkit.ai/r'\n\nexport const templateMapping = {\n // Runtimes\n RemoteEndpoint: `${BASE_URL}/remote-endpoint.json`,\n LangGraphPlatformRuntime: `${BASE_URL}/langgraph-platform-runtime.json`,\n\n // CrewAI\n CrewEnterprise: [`${BASE_URL}/coagents-crew-starter.json`],\n CrewFlowsEnterprise: [`${BASE_URL}/coagents-starter-crewai-flows.json`],\n\n // LangGraph\n LangGraphGeneric: `${BASE_URL}/generic-lg-starter.json`,\n LangGraphStarter: [`${BASE_URL}/langgraph-platform-starter.json`, `${BASE_URL}/coagents-starter-ui.json`],\n\n // No Agent\n StandardStarter: `${BASE_URL}/standard-starter.json`,\n StandardRuntime: `${BASE_URL}/standard-runtime.json`,\n\n // MCP\n McpStarter: `${BASE_URL}/mcp-starter.json`,\n McpRuntime: `${BASE_URL}/mcp-starter-runtime.json`,\n}\n","import path from 'path'\nimport {existsSync} from 'fs'\nimport * as fs from 'fs/promises'\nimport {Ora} from 'ora'\nimport chalk from 'chalk'\n\nexport type SupportedIDE = 'cursor' | 'windsurf'\n\nexport interface IDEDocsConfig {\n name: SupportedIDE\n displayName: string\n rulesDir: string\n ruleFileName: string\n createRuleContent: () => string\n}\n\n// Template constant for CopilotKit documentation rule\nconst COPILOTKIT_DOC_RULE_TEMPLATE = `---\ndescription: CopilotKit Documentation - Complete CopilotKit framework documentation for AI assistance\nalwaysApply: false\n---\n\n# CopilotKit Documentation\n\nFor ANY question about CopilotKit, use the comprehensive documentation available at:\n@https://docs.copilotkit.ai/llms-full.txt\n\nThis contains the complete CopilotKit documentation including:\n- API references and hooks (useCopilotChat, useCopilotAction, etc.)\n- Component library documentation (CopilotKit, CopilotChat, etc.)\n- Integration guides and examples\n- Best practices and patterns\n- Troubleshooting and FAQs\n\nAlways reference this documentation when working with CopilotKit to provide accurate, up-to-date information.\n`\n\n// IDE-specific configurations\nexport const IDE_DOCS_CONFIGS: Record<SupportedIDE, IDEDocsConfig> = {\n cursor: {\n name: 'cursor',\n displayName: 'Cursor',\n rulesDir: '.cursor/rules',\n ruleFileName: '00-copilotkit-docs.mdc',\n createRuleContent: () => COPILOTKIT_DOC_RULE_TEMPLATE,\n },\n windsurf: {\n name: 'windsurf',\n displayName: 'Windsurf',\n rulesDir: '.windsurf/rules',\n ruleFileName: '00-copilotkit-docs.md',\n createRuleContent: () => COPILOTKIT_DOC_RULE_TEMPLATE,\n },\n}\n\n/**\n * Ensure directory exists\n */\nasync function ensureDir(dirPath: string): Promise<void> {\n try {\n await fs.mkdir(dirPath, {recursive: true})\n } catch (error) {\n if (!existsSync(dirPath)) {\n throw error\n }\n }\n}\n\n/**\n * Check if path exists\n */\nasync function pathExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Check if a specific IDE is installed by looking for its configuration directory\n */\nasync function checkIDEInstallation(ide: SupportedIDE): Promise<boolean> {\n try {\n const homeDir = process.env.HOME || process.env.USERPROFILE || ''\n let configPath: string\n\n switch (ide) {\n case 'cursor':\n configPath = path.join(homeDir, '.cursor')\n break\n case 'windsurf':\n configPath = path.join(homeDir, '.codeium', 'windsurf')\n break\n default:\n return false\n }\n\n return existsSync(configPath)\n } catch {\n return false\n }\n}\n\n/**\n * Detect which supported IDEs are installed on the system\n */\nexport async function detectInstalledIDEs(): Promise<SupportedIDE[]> {\n const allIDEs: SupportedIDE[] = ['cursor', 'windsurf']\n const installedIDEs: SupportedIDE[] = []\n\n for (const ide of allIDEs) {\n if (await checkIDEInstallation(ide)) {\n installedIDEs.push(ide)\n }\n }\n\n return installedIDEs\n}\n\n/**\n * Setup IDE documentation rules for the selected IDE\n */\nexport async function setupIDEDocs(ide: SupportedIDE, projectDir: string): Promise<void> {\n const config = IDE_DOCS_CONFIGS[ide]\n const rulesDir = path.join(projectDir, config.rulesDir)\n const ruleFilePath = path.join(rulesDir, config.ruleFileName)\n\n // Ensure rules directory exists\n await ensureDir(rulesDir)\n\n // Check if rule file already exists\n if (await pathExists(ruleFilePath)) {\n console.log(chalk.yellow(`⚠️ CopilotKit documentation rule already exists for ${config.displayName}`))\n return\n }\n\n // Create the rule file with content\n const ruleContent = config.createRuleContent()\n await fs.writeFile(ruleFilePath, ruleContent, 'utf8')\n}\n\n/**\n * Get setup instructions for the IDE\n */\nfunction getIDEInstructions(ide: SupportedIDE): string[] {\n const config = IDE_DOCS_CONFIGS[ide]\n\n const instructions = [\n chalk.cyan(`📚 CopilotKit documentation configured for ${config.displayName}!`),\n '',\n chalk.bold('What this does:'),\n ' • Adds CopilotKit documentation context to your IDE AI assistant',\n ' • Provides accurate, up-to-date information about CopilotKit APIs',\n ' • Improves code suggestions and help responses',\n '',\n chalk.bold('Location:'),\n ` • Rule file: ${chalk.gray(path.join(config.rulesDir, config.ruleFileName))}`,\n '',\n chalk.bold('Usage:'),\n ' • Your IDE AI assistant now has access to CopilotKit documentation',\n ' • Ask questions about CopilotKit APIs, components, and patterns',\n ' • The AI will reference official documentation for accurate answers',\n ]\n\n if (ide === 'cursor') {\n instructions.push(\n '',\n chalk.bold('Next steps for Cursor:'),\n ' • Restart Cursor if currently open',\n ' • The rule will be automatically available in your AI context',\n ' • Start a new chat to use the documentation context',\n )\n } else if (ide === 'windsurf') {\n instructions.push(\n '',\n chalk.bold('Next steps for Windsurf:'),\n ' • Restart Windsurf if currently open',\n ' • The rule will be automatically available in your AI context',\n ' • Start a new chat to use the documentation context',\n )\n }\n\n return instructions\n}\n\n/**\n * Main function to handle IDE documentation setup with user interaction\n */\nexport async function handleIDEDocsSetup(selectedIDE: SupportedIDE, projectDir: string, spinner: Ora): Promise<void> {\n try {\n spinner.text = chalk.cyan(`Setting up CopilotKit documentation for ${IDE_DOCS_CONFIGS[selectedIDE].displayName}...`)\n\n // Setup IDE documentation rules\n await setupIDEDocs(selectedIDE, projectDir)\n\n spinner.succeed(chalk.green(`CopilotKit documentation configured for ${IDE_DOCS_CONFIGS[selectedIDE].displayName}`))\n\n // Show instructions\n const instructions = getIDEInstructions(selectedIDE)\n console.log('\\n' + instructions.join('\\n'))\n } catch (error) {\n spinner.fail(\n chalk.red(`Failed to setup IDE documentation: ${error instanceof Error ? error.message : 'Unknown error'}`),\n )\n throw error\n }\n}\n","import {\n Question,\n MODES,\n CREW_TYPES,\n LANGGRAPH_AGENTS,\n DEPLOYMENT_CHOICES,\n ModeSchema,\n CrewTypeSchema,\n UrlSchema,\n YesNoSchema,\n DeploymentChoiceSchema,\n sanitizers,\n} from './types/index.js'\nimport {isLocalhost} from './utils.js'\nimport {detectInstalledIDEs, IDE_DOCS_CONFIGS} from './ide-docs.js'\n\nconst linkToDocs = ['Mastra', 'AG2', 'LlamaIndex', 'Agno']\n\n// Validation helpers\nconst validateUrl = (input: string): true | string => {\n try {\n // First sanitize the URL by removing trailing slashes\n const sanitized = sanitizers.url(input)\n // Then validate\n const result = UrlSchema.safeParse(sanitized)\n if (result.success) return true\n return result.error.errors[0]?.message || 'Invalid URL format'\n } catch (error) {\n return 'Invalid URL format'\n }\n}\n\nconst validateRequired = (input: string): true | string => {\n return sanitizers.trim(input) ? true : 'This field is required'\n}\n\n// A/B/C Test Feature Flags\ntype ABCTestBranch = 'A' | 'B' | 'C'\n\n// Helper function to determine which questions to show based on A/B/C test\nexport function getQuestionsForBranch(branch: ABCTestBranch): Question[] {\n const baseQuestions = getBaseQuestions()\n\n switch (branch) {\n case 'A':\n // Branch A: Copilot Cloud by default, no signup questions\n // API key message and setup handled in init command\n return [...baseQuestions]\n\n case 'B':\n // Branch B: API key setup (automatic) with choice between Cloud vs Self-hosted\n return [...baseQuestions, ...getDeploymentChoiceQuestions()]\n\n case 'C':\n default:\n // Branch C: Current flow (no early signup, just cloud deployment question)\n return [...baseQuestions, ...getCloudDeploymentQuestions()]\n }\n}\n\n// Early signup questions - REMOVED (no longer used)\n\n// Base questions for all branches (mode selection and configuration)\nfunction getBaseQuestions(): Question[] {\n return [\n {\n type: 'select',\n name: 'mode',\n message: '🤖 How will you be interacting with AI?',\n choices: Array.from(MODES),\n validate: (input) => {\n try {\n ModeSchema.parse(input)\n return true\n } catch (error) {\n return 'Please select a valid mode'\n }\n },\n },\n\n // CrewAI specific questions\n {\n type: 'select',\n name: 'crewType',\n message: '👥 What kind of CrewAI implementation would you like to use?',\n choices: Array.from(CREW_TYPES),\n when: (answers) => answers.mode === 'CrewAI',\n validate: (input) => {\n try {\n CrewTypeSchema.parse(input)\n return true\n } catch (error) {\n return 'Please select a valid crew type'\n }\n },\n },\n {\n type: 'input',\n name: 'crewName',\n message: '👥 What would you like to name your crew? (can be anything)',\n when: (answers) => answers.mode === 'CrewAI',\n default: 'MyCopilotCrew',\n validate: validateRequired,\n sanitize: sanitizers.trim,\n },\n {\n type: 'input',\n name: 'crewUrl',\n message: \"🔗 Enter your Crew's Enterprise URL (more info at https://app.crewai.com):\",\n when: (answers) => answers.mode === 'CrewAI',\n validate: validateUrl,\n sanitize: sanitizers.url,\n },\n {\n type: 'input',\n name: 'crewBearerToken',\n message: \"🔑 Enter your Crew's bearer token:\",\n when: (answers) => answers.mode === 'CrewAI',\n sensitive: true,\n validate: validateRequired,\n sanitize: sanitizers.trim,\n },\n\n // LangGraph specific questions\n {\n type: 'yes/no',\n name: 'alreadyDeployed',\n message: '🦜🔗 Do you have an existing LangGraph agent?',\n when: (answers) => answers.mode === 'LangGraph',\n validate: (input) => {\n try {\n YesNoSchema.parse(input)\n return true\n } catch (error) {\n return 'Please select Yes or No'\n }\n },\n },\n {\n type: 'yes/no',\n name: 'langGraphPlatform',\n message: '🦜🔗 Do you already have a LangGraph Agent URL? (remote or localhost)',\n when: (answers) => answers.mode === 'LangGraph' && answers.alreadyDeployed === 'Yes',\n validate: (input) => {\n try {\n YesNoSchema.parse(input)\n return true\n } catch (error) {\n return 'Please select Yes or No'\n }\n },\n },\n {\n type: 'input',\n name: 'langGraphPlatformUrl',\n message: '🦜🔗 Enter your LangGraph Agent URL (remote or localhost)',\n when: (answers) =>\n answers.mode === 'LangGraph' && answers.alreadyDeployed === 'Yes' && answers.langGraphPlatform === 'Yes',\n validate: validateUrl,\n sanitize: sanitizers.url,\n },\n {\n type: 'select',\n name: 'langGraphAgent',\n message: '📦 Choose a LangGraph starter template:',\n choices: Array.from(LANGGRAPH_AGENTS),\n when: (answers) => answers.mode === 'LangGraph' && answers.alreadyDeployed === 'No',\n },\n {\n type: 'input',\n name: 'langSmithApiKey',\n message: '🦜🔗 Enter your LangSmith API key (required by LangGraph Platform) :',\n when: (answers) =>\n answers.mode === 'LangGraph' &&\n answers.langGraphPlatform === 'Yes' &&\n !(answers.langGraphPlatformUrl && isLocalhost(answers.langGraphPlatformUrl)),\n sensitive: true,\n validate: validateRequired,\n sanitize: sanitizers.apiKey,\n },\n\n // LLM Token for self-hosted setups\n {\n type: 'input',\n name: 'llmToken',\n message: '🔑 Enter your OpenAI API key (optional - leave empty to configure your LLM later):',\n when: (answers) =>\n (answers.mode === 'LangGraph' && answers.alreadyDeployed === 'No') ||\n (answers.mode === 'Standard' && answers.deploymentChoice === 'Self-hosted') ||\n (answers.mode === 'MCP' && answers.deploymentChoice === 'Self-hosted') ||\n (answers.mode === 'Standard' && answers.useCopilotCloud !== 'Yes') ||\n (answers.mode === 'MCP' && answers.useCopilotCloud !== 'Yes'),\n sensitive: true,\n sanitize: sanitizers.apiKey,\n },\n\n // IDE Documentation Setup Questions\n {\n type: 'yes/no',\n name: 'setupIDEDocs',\n message:\n '📚 Would you like to add CopilotKit documentation to your IDE? (Provides AI assistant with CopilotKit context)',\n when: async () => {\n const installedIDEs = await detectInstalledIDEs()\n return installedIDEs.length > 0\n },\n validate: (input) => {\n try {\n YesNoSchema.parse(input)\n return true\n } catch (error) {\n return 'Please select Yes or No'\n }\n },\n },\n {\n type: 'select',\n name: 'selectedIDE',\n message: '💻 Which IDE would you like to configure with CopilotKit documentation?',\n choices: async () => {\n const installedIDEs = await detectInstalledIDEs()\n const choices: Array<{name: string; value: string}> = installedIDEs.map((ide: any) => ({\n name: IDE_DOCS_CONFIGS[ide as keyof typeof IDE_DOCS_CONFIGS].displayName,\n value: ide,\n }))\n choices.push({name: 'Skip', value: 'skip'})\n return choices\n },\n when: (answers) => answers.setupIDEDocs === 'Yes',\n },\n ]\n}\n\n// Deployment choice questions for Branch B only\nfunction getDeploymentChoiceQuestions(): Question[] {\n return [\n {\n type: 'select',\n name: 'deploymentChoice',\n message: '🚀 Use Copilot Cloud, or self-hosted?',\n choices: Array.from(DEPLOYMENT_CHOICES),\n validate: (input) => {\n try {\n DeploymentChoiceSchema.parse(input)\n return true\n } catch (error) {\n return 'Please select a valid deployment option'\n }\n },\n },\n ]\n}\n\n// Cloud deployment questions for Branch C (current flow)\nfunction getCloudDeploymentQuestions(): Question[] {\n return [\n {\n type: 'yes/no',\n name: 'useCopilotCloud',\n message: '🪁 Deploy with Copilot Cloud? (recommended for production)',\n when: (answers) =>\n answers.mode === 'Standard' ||\n answers.mode === 'MCP' ||\n (answers.mode === 'LangGraph' && answers.alreadyDeployed === 'No') || // Include new LangGraph agents\n (answers.mode !== 'CrewAI' && // Crews only cloud, flows are self-hosted\n answers.alreadyDeployed === 'Yes' &&\n answers.langGraphPlatform !== 'No' &&\n !linkToDocs.includes(answers.mode || '') &&\n !isLocalhost(answers.langGraphPlatformUrl || '')),\n validate: (input) => {\n try {\n YesNoSchema.parse(input)\n return true\n } catch (error) {\n return 'Please select Yes or No'\n }\n },\n },\n ]\n}\n\n// Maintain backward compatibility by providing the original questions for Branch C\nexport const questions: Question[] = getQuestionsForBranch('C')\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/init/types/questions.ts","../../../src/lib/init/utils.ts","../../../src/lib/init/types/templates.ts","../../../src/lib/init/ide-docs.ts","../../../src/lib/init/questions.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { Flags } from \"@oclif/core\";\nimport { isLocalhost } from \"../utils.js\";\n\n// ===== Core Constants =====\nexport const MODES = [\n \"LangGraph\",\n \"CrewAI\",\n \"Mastra\",\n \"LlamaIndex\",\n \"Agno\",\n \"AG2\",\n \"MCP\",\n \"Standard\",\n] as const;\nexport const CREW_TYPES = [\"Crews\", \"Flows\"] as const;\nexport const CHAT_COMPONENTS = [\n \"CopilotChat\",\n \"CopilotSidebar\",\n \"Headless\",\n \"CopilotPopup\",\n] as const;\nexport const LANGGRAPH_AGENTS = [\n \"Python Starter\",\n \"TypeScript Starter\",\n] as const;\nexport const CREW_FLOW_TEMPLATES = [\"Starter\"] as const;\nexport const YES_NO = [\"Yes\", \"No\"] as const;\n// NEW: Deployment choice options for Branch B\nexport const DEPLOYMENT_CHOICES = [\"Copilot Cloud\", \"Self-hosted\"] as const;\n\n// ===== Sanitizers =====\nexport const sanitizers = {\n // Remove trailing slash from URLs\n url: (value: string): string => {\n if (!value) return value;\n return value.trim().replace(/\\/+$/, \"\");\n },\n\n // Trim whitespace from strings\n trim: (value: string): string => {\n if (!value) return value;\n return value.trim();\n },\n\n // Lowercase strings\n lowercase: (value: string): string => {\n if (!value) return value;\n return value.toLowerCase().trim();\n },\n\n // Clean API keys (remove whitespace)\n apiKey: (value: string): string => {\n if (!value) return value;\n return value.trim().replace(/\\s/g, \"\");\n },\n};\n\n// ===== Zod Schemas =====\n\n// Basic schemas\nexport const ModeSchema = z.enum(MODES);\nexport const CrewTypeSchema = z.enum(CREW_TYPES);\nexport const ChatComponentSchema = z.enum(CHAT_COMPONENTS);\nexport const LangGraphAgentSchema = z.enum(LANGGRAPH_AGENTS);\nexport const CrewFlowTemplateSchema = z.enum(CREW_FLOW_TEMPLATES);\nexport const YesNoSchema = z.enum(YES_NO);\n// NEW: Deployment choice schema for Branch B\nexport const DeploymentChoiceSchema = z.enum(DEPLOYMENT_CHOICES);\n\n// URL validation schema with preprocessing to remove trailing slash\nexport const UrlSchema = z.preprocess(\n (val) => sanitizers.url(String(val)),\n z.string().url(\"Please enter a valid URL\").min(1, \"URL is required\"),\n);\n\n// Token validation schema with preprocessing to trim\nexport const TokenSchema = z.preprocess(\n (val) => sanitizers.trim(String(val)),\n z.string().min(1, \"Token is required\"),\n);\n\n// API key validation schema with preprocessing to remove whitespace\nexport const ApiKeySchema = z.preprocess(\n (val) => sanitizers.apiKey(String(val)),\n z.string().min(1, \"API key is required\"),\n);\n\nexport const LLMApiKeySchema = z.preprocess(\n (val) => sanitizers.apiKey(String(val)),\n z.string().optional(),\n);\n\n// Name validation schema with preprocessing to trim\nexport const NameSchema = z.preprocess(\n (val) => sanitizers.trim(String(val)),\n z.string().min(1, \"Name is required\"),\n);\n\n// Config schema\nexport const ConfigSchema = z\n .object({\n // Core fields\n copilotKitVersion: z.string().optional(),\n mode: ModeSchema,\n chatUi: ChatComponentSchema.optional(),\n\n // Yes/No fields\n alreadyDeployed: YesNoSchema.optional(),\n fastApiEnabled: YesNoSchema.optional(),\n // DEPRECATED: useCopilotCloud - consolidated with signupForCopilotCloud\n useCopilotCloud: YesNoSchema.optional(),\n\n // LangGraph specific fields\n langGraphAgent: LangGraphAgentSchema.optional(),\n langGraphPlatform: YesNoSchema.optional(),\n langGraphPlatformUrl: UrlSchema.optional(),\n langGraphRemoteEndpointURL: UrlSchema.optional(),\n\n // CrewAI specific fields\n crewType: CrewTypeSchema.optional(),\n crewName: NameSchema.optional(),\n crewUrl: UrlSchema.optional(),\n crewBearerToken: TokenSchema.optional(),\n\n // API keys and tokens\n copilotCloudPublicApiKey: z.string().optional(),\n langSmithApiKey: ApiKeySchema.optional(),\n llmToken: LLMApiKeySchema.optional(),\n\n // IDE Documentation setup fields\n setupIDEDocs: YesNoSchema.optional(),\n selectedIDE: z\n .union([z.enum([\"cursor\", \"windsurf\"]), z.literal(\"skip\")])\n .optional(),\n\n // NEW: A/B/C test fields\n deploymentChoice: DeploymentChoiceSchema.optional(), // For branch B only (Cloud vs Self-hosted)\n })\n .refine(\n (data) => {\n // If CrewAI is selected, require crew URL and bearer token\n if (data.mode === \"CrewAI\") {\n return !!data.crewUrl && !!data.crewBearerToken;\n }\n return true;\n },\n {\n message: \"Crew URL and bearer token are required for CrewAI\",\n path: [\"crewUrl\", \"crewBearerToken\"],\n },\n )\n .refine(\n (data) => {\n // If LangGraph is selected with LangGraph Platform, require platform URL and LangSmith API key\n if (\n data.mode === \"LangGraph\" &&\n data.alreadyDeployed === \"Yes\" &&\n data.langGraphPlatform === \"Yes\"\n ) {\n return (\n (!!data.langGraphPlatformUrl && !!data.langSmithApiKey) ||\n isLocalhost(data.langGraphPlatformUrl || \"\")\n );\n }\n return true;\n },\n {\n message: \"LangGraph Platform URL and LangSmith API key are required\",\n path: [\"langGraphPlatformUrl\", \"langSmithApiKey\"],\n },\n );\n\n// Export the inferred type from the schema\nexport type Config = z.infer<typeof ConfigSchema>;\n\n// Question type definition with improved validation and sanitization\nexport type Question = {\n type: \"input\" | \"yes/no\" | \"select\";\n name: keyof Config;\n message: string;\n choices?:\n | readonly string[]\n | (() => Promise<{ name: string; value: string }[]>);\n default?: string;\n when?: (answers: Partial<Config>) => boolean | Promise<boolean>;\n sensitive?: boolean;\n validate?: (input: string) => true | string; // Return true if valid, error message string if invalid\n sanitize?: (input: string) => string; // Function to sanitize input before validation\n};\n\n// CLI flags definition with descriptions\nexport const ConfigFlags = {\n booth: Flags.boolean({\n description: \"Use CopilotKit in booth mode\",\n default: false,\n char: \"b\",\n }),\n mode: Flags.string({\n description: \"How you will be interacting with AI\",\n options: MODES,\n char: \"m\",\n }),\n \"copilotkit-version\": Flags.string({\n description: \"CopilotKit version to use (e.g. 1.7.0)\",\n }),\n \"use-copilot-cloud\": Flags.string({\n description: \"Use Copilot Cloud for production-ready hosting\",\n options: YES_NO,\n }),\n \"langgraph-agent\": Flags.string({\n description: \"LangGraph agent template to use\",\n options: LANGGRAPH_AGENTS,\n }),\n \"crew-type\": Flags.string({\n description: \"CrewAI implementation type\",\n options: CREW_TYPES,\n }),\n \"crew-name\": Flags.string({ description: \"Name for your CrewAI agent\" }),\n \"crew-url\": Flags.string({\n description: \"URL endpoint for your CrewAI agent\",\n }),\n \"crew-bearer-token\": Flags.string({\n description: \"Bearer token for CrewAI authentication\",\n }),\n \"langsmith-api-key\": Flags.string({\n description: \"LangSmith API key for LangGraph observability\",\n }),\n \"llm-token\": Flags.string({\n description: \"API key for your preferred LLM provider\",\n }),\n \"setup-ide-docs\": Flags.string({\n description: \"Setup IDE documentation rules for AI assistance\",\n options: YES_NO,\n }),\n \"selected-ide\": Flags.string({\n description: \"IDE to configure with documentation rules\",\n options: [\"cursor\", \"windsurf\", \"skip\"],\n }),\n // NEW: A/B/C test flags\n \"deployment-choice\": Flags.string({\n description: \"Choose between Copilot Cloud or Self-hosted deployment\",\n options: DEPLOYMENT_CHOICES,\n }),\n};\n","export const isLocalhost = (url: string): boolean => {\n return (\n url.includes(\"localhost\") ||\n url.includes(\"127.0.0.1\") ||\n url.includes(\"0.0.0.0\")\n );\n};\n","export type ChatTemplate = \"CopilotChat\" | \"CopilotPopup\" | \"CopilotSidebar\";\n\nexport type StarterTemplate =\n | \"LangGraphPlatform\"\n | \"RemoteEndpoint\"\n | \"Standard\"\n | \"CrewEnterprise\"\n | \"CrewFlowsStarter\";\n\nexport type Template = ChatTemplate | StarterTemplate;\n\nconst BASE_URL = \"https://registry.copilotkit.ai/r\";\n\nexport const templateMapping = {\n // Runtimes\n RemoteEndpoint: `${BASE_URL}/remote-endpoint.json`,\n LangGraphPlatformRuntime: `${BASE_URL}/langgraph-platform-runtime.json`,\n\n // CrewAI\n CrewEnterprise: [`${BASE_URL}/coagents-crew-starter.json`],\n CrewFlowsEnterprise: [`${BASE_URL}/coagents-starter-crewai-flows.json`],\n\n // LangGraph\n LangGraphGeneric: `${BASE_URL}/generic-lg-starter.json`,\n LangGraphStarter: [\n `${BASE_URL}/langgraph-platform-starter.json`,\n `${BASE_URL}/coagents-starter-ui.json`,\n ],\n\n // No Agent\n StandardStarter: `${BASE_URL}/standard-starter.json`,\n StandardRuntime: `${BASE_URL}/standard-runtime.json`,\n\n // MCP\n McpStarter: `${BASE_URL}/mcp-starter.json`,\n McpRuntime: `${BASE_URL}/mcp-starter-runtime.json`,\n};\n","import path from \"path\";\nimport { existsSync } from \"fs\";\nimport * as fs from \"fs/promises\";\nimport { Ora } from \"ora\";\nimport chalk from \"chalk\";\n\nexport type SupportedIDE = \"cursor\" | \"windsurf\";\n\nexport interface IDEDocsConfig {\n name: SupportedIDE;\n displayName: string;\n rulesDir: string;\n ruleFileName: string;\n createRuleContent: () => string;\n}\n\n// Template constant for CopilotKit documentation rule\nconst COPILOTKIT_DOC_RULE_TEMPLATE = `---\ndescription: CopilotKit Documentation - Complete CopilotKit framework documentation for AI assistance\nalwaysApply: false\n---\n\n# CopilotKit Documentation\n\nFor ANY question about CopilotKit, use the comprehensive documentation available at:\n@https://docs.copilotkit.ai/llms-full.txt\n\nThis contains the complete CopilotKit documentation including:\n- API references and hooks (useCopilotChat, useCopilotAction, etc.)\n- Component library documentation (CopilotKit, CopilotChat, etc.)\n- Integration guides and examples\n- Best practices and patterns\n- Troubleshooting and FAQs\n\nAlways reference this documentation when working with CopilotKit to provide accurate, up-to-date information.\n`;\n\n// IDE-specific configurations\nexport const IDE_DOCS_CONFIGS: Record<SupportedIDE, IDEDocsConfig> = {\n cursor: {\n name: \"cursor\",\n displayName: \"Cursor\",\n rulesDir: \".cursor/rules\",\n ruleFileName: \"00-copilotkit-docs.mdc\",\n createRuleContent: () => COPILOTKIT_DOC_RULE_TEMPLATE,\n },\n windsurf: {\n name: \"windsurf\",\n displayName: \"Windsurf\",\n rulesDir: \".windsurf/rules\",\n ruleFileName: \"00-copilotkit-docs.md\",\n createRuleContent: () => COPILOTKIT_DOC_RULE_TEMPLATE,\n },\n};\n\n/**\n * Ensure directory exists\n */\nasync function ensureDir(dirPath: string): Promise<void> {\n try {\n await fs.mkdir(dirPath, { recursive: true });\n } catch (error) {\n if (!existsSync(dirPath)) {\n throw error;\n }\n }\n}\n\n/**\n * Check if path exists\n */\nasync function pathExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if a specific IDE is installed by looking for its configuration directory\n */\nasync function checkIDEInstallation(ide: SupportedIDE): Promise<boolean> {\n try {\n const homeDir = process.env.HOME || process.env.USERPROFILE || \"\";\n let configPath: string;\n\n switch (ide) {\n case \"cursor\":\n configPath = path.join(homeDir, \".cursor\");\n break;\n case \"windsurf\":\n configPath = path.join(homeDir, \".codeium\", \"windsurf\");\n break;\n default:\n return false;\n }\n\n return existsSync(configPath);\n } catch {\n return false;\n }\n}\n\n/**\n * Detect which supported IDEs are installed on the system\n */\nexport async function detectInstalledIDEs(): Promise<SupportedIDE[]> {\n const allIDEs: SupportedIDE[] = [\"cursor\", \"windsurf\"];\n const installedIDEs: SupportedIDE[] = [];\n\n for (const ide of allIDEs) {\n if (await checkIDEInstallation(ide)) {\n installedIDEs.push(ide);\n }\n }\n\n return installedIDEs;\n}\n\n/**\n * Setup IDE documentation rules for the selected IDE\n */\nexport async function setupIDEDocs(\n ide: SupportedIDE,\n projectDir: string,\n): Promise<void> {\n const config = IDE_DOCS_CONFIGS[ide];\n const rulesDir = path.join(projectDir, config.rulesDir);\n const ruleFilePath = path.join(rulesDir, config.ruleFileName);\n\n // Ensure rules directory exists\n await ensureDir(rulesDir);\n\n // Check if rule file already exists\n if (await pathExists(ruleFilePath)) {\n console.log(\n chalk.yellow(\n `⚠️ CopilotKit documentation rule already exists for ${config.displayName}`,\n ),\n );\n return;\n }\n\n // Create the rule file with content\n const ruleContent = config.createRuleContent();\n await fs.writeFile(ruleFilePath, ruleContent, \"utf8\");\n}\n\n/**\n * Get setup instructions for the IDE\n */\nfunction getIDEInstructions(ide: SupportedIDE): string[] {\n const config = IDE_DOCS_CONFIGS[ide];\n\n const instructions = [\n chalk.cyan(\n `📚 CopilotKit documentation configured for ${config.displayName}!`,\n ),\n \"\",\n chalk.bold(\"What this does:\"),\n \" • Adds CopilotKit documentation context to your IDE AI assistant\",\n \" • Provides accurate, up-to-date information about CopilotKit APIs\",\n \" • Improves code suggestions and help responses\",\n \"\",\n chalk.bold(\"Location:\"),\n ` • Rule file: ${chalk.gray(path.join(config.rulesDir, config.ruleFileName))}`,\n \"\",\n chalk.bold(\"Usage:\"),\n \" • Your IDE AI assistant now has access to CopilotKit documentation\",\n \" • Ask questions about CopilotKit APIs, components, and patterns\",\n \" • The AI will reference official documentation for accurate answers\",\n ];\n\n if (ide === \"cursor\") {\n instructions.push(\n \"\",\n chalk.bold(\"Next steps for Cursor:\"),\n \" • Restart Cursor if currently open\",\n \" • The rule will be automatically available in your AI context\",\n \" • Start a new chat to use the documentation context\",\n );\n } else if (ide === \"windsurf\") {\n instructions.push(\n \"\",\n chalk.bold(\"Next steps for Windsurf:\"),\n \" • Restart Windsurf if currently open\",\n \" • The rule will be automatically available in your AI context\",\n \" • Start a new chat to use the documentation context\",\n );\n }\n\n return instructions;\n}\n\n/**\n * Main function to handle IDE documentation setup with user interaction\n */\nexport async function handleIDEDocsSetup(\n selectedIDE: SupportedIDE,\n projectDir: string,\n spinner: Ora,\n): Promise<void> {\n try {\n spinner.text = chalk.cyan(\n `Setting up CopilotKit documentation for ${IDE_DOCS_CONFIGS[selectedIDE].displayName}...`,\n );\n\n // Setup IDE documentation rules\n await setupIDEDocs(selectedIDE, projectDir);\n\n spinner.succeed(\n chalk.green(\n `CopilotKit documentation configured for ${IDE_DOCS_CONFIGS[selectedIDE].displayName}`,\n ),\n );\n\n // Show instructions\n const instructions = getIDEInstructions(selectedIDE);\n console.log(\"\\n\" + instructions.join(\"\\n\"));\n } catch (error) {\n spinner.fail(\n chalk.red(\n `Failed to setup IDE documentation: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n ),\n );\n throw error;\n }\n}\n","import {\n Question,\n MODES,\n CREW_TYPES,\n LANGGRAPH_AGENTS,\n DEPLOYMENT_CHOICES,\n ModeSchema,\n CrewTypeSchema,\n UrlSchema,\n YesNoSchema,\n DeploymentChoiceSchema,\n sanitizers,\n} from \"./types/index.js\";\nimport { isLocalhost } from \"./utils.js\";\nimport { detectInstalledIDEs, IDE_DOCS_CONFIGS } from \"./ide-docs.js\";\n\nconst linkToDocs = [\"Mastra\", \"AG2\", \"LlamaIndex\", \"Agno\"];\n\n// Validation helpers\nconst validateUrl = (input: string): true | string => {\n try {\n // First sanitize the URL by removing trailing slashes\n const sanitized = sanitizers.url(input);\n // Then validate\n const result = UrlSchema.safeParse(sanitized);\n if (result.success) return true;\n return result.error.errors[0]?.message || \"Invalid URL format\";\n } catch (error) {\n return \"Invalid URL format\";\n }\n};\n\nconst validateRequired = (input: string): true | string => {\n return sanitizers.trim(input) ? true : \"This field is required\";\n};\n\n// A/B/C Test Feature Flags\ntype ABCTestBranch = \"A\" | \"B\" | \"C\";\n\n// Helper function to determine which questions to show based on A/B/C test\nexport function getQuestionsForBranch(branch: ABCTestBranch): Question[] {\n const baseQuestions = getBaseQuestions();\n\n switch (branch) {\n case \"A\":\n // Branch A: Copilot Cloud by default, no signup questions\n // API key message and setup handled in init command\n return [...baseQuestions];\n\n case \"B\":\n // Branch B: API key setup (automatic) with choice between Cloud vs Self-hosted\n return [...baseQuestions, ...getDeploymentChoiceQuestions()];\n\n case \"C\":\n default:\n // Branch C: Current flow (no early signup, just cloud deployment question)\n return [...baseQuestions, ...getCloudDeploymentQuestions()];\n }\n}\n\n// Early signup questions - REMOVED (no longer used)\n\n// Base questions for all branches (mode selection and configuration)\nfunction getBaseQuestions(): Question[] {\n return [\n {\n type: \"select\",\n name: \"mode\",\n message: \"🤖 How will you be interacting with AI?\",\n choices: Array.from(MODES),\n validate: (input) => {\n try {\n ModeSchema.parse(input);\n return true;\n } catch (error) {\n return \"Please select a valid mode\";\n }\n },\n },\n\n // CrewAI specific questions\n {\n type: \"select\",\n name: \"crewType\",\n message: \"👥 What kind of CrewAI implementation would you like to use?\",\n choices: Array.from(CREW_TYPES),\n when: (answers) => answers.mode === \"CrewAI\",\n validate: (input) => {\n try {\n CrewTypeSchema.parse(input);\n return true;\n } catch (error) {\n return \"Please select a valid crew type\";\n }\n },\n },\n {\n type: \"input\",\n name: \"crewName\",\n message: \"👥 What would you like to name your crew? (can be anything)\",\n when: (answers) => answers.mode === \"CrewAI\",\n default: \"MyCopilotCrew\",\n validate: validateRequired,\n sanitize: sanitizers.trim,\n },\n {\n type: \"input\",\n name: \"crewUrl\",\n message:\n \"🔗 Enter your Crew's Enterprise URL (more info at https://app.crewai.com):\",\n when: (answers) => answers.mode === \"CrewAI\",\n validate: validateUrl,\n sanitize: sanitizers.url,\n },\n {\n type: \"input\",\n name: \"crewBearerToken\",\n message: \"🔑 Enter your Crew's bearer token:\",\n when: (answers) => answers.mode === \"CrewAI\",\n sensitive: true,\n validate: validateRequired,\n sanitize: sanitizers.trim,\n },\n\n // LangGraph specific questions\n {\n type: \"yes/no\",\n name: \"alreadyDeployed\",\n message: \"🦜🔗 Do you have an existing LangGraph agent?\",\n when: (answers) => answers.mode === \"LangGraph\",\n validate: (input) => {\n try {\n YesNoSchema.parse(input);\n return true;\n } catch (error) {\n return \"Please select Yes or No\";\n }\n },\n },\n {\n type: \"yes/no\",\n name: \"langGraphPlatform\",\n message:\n \"🦜🔗 Do you already have a LangGraph Agent URL? (remote or localhost)\",\n when: (answers) =>\n answers.mode === \"LangGraph\" && answers.alreadyDeployed === \"Yes\",\n validate: (input) => {\n try {\n YesNoSchema.parse(input);\n return true;\n } catch (error) {\n return \"Please select Yes or No\";\n }\n },\n },\n {\n type: \"input\",\n name: \"langGraphPlatformUrl\",\n message: \"🦜🔗 Enter your LangGraph Agent URL (remote or localhost)\",\n when: (answers) =>\n answers.mode === \"LangGraph\" &&\n answers.alreadyDeployed === \"Yes\" &&\n answers.langGraphPlatform === \"Yes\",\n validate: validateUrl,\n sanitize: sanitizers.url,\n },\n {\n type: \"select\",\n name: \"langGraphAgent\",\n message: \"📦 Choose a LangGraph starter template:\",\n choices: Array.from(LANGGRAPH_AGENTS),\n when: (answers) =>\n answers.mode === \"LangGraph\" && answers.alreadyDeployed === \"No\",\n },\n {\n type: \"input\",\n name: \"langSmithApiKey\",\n message:\n \"🦜🔗 Enter your LangSmith API key (required by LangGraph Platform) :\",\n when: (answers) =>\n answers.mode === \"LangGraph\" &&\n answers.langGraphPlatform === \"Yes\" &&\n !(\n answers.langGraphPlatformUrl &&\n isLocalhost(answers.langGraphPlatformUrl)\n ),\n sensitive: true,\n validate: validateRequired,\n sanitize: sanitizers.apiKey,\n },\n\n // LLM Token for self-hosted setups\n {\n type: \"input\",\n name: \"llmToken\",\n message:\n \"🔑 Enter your OpenAI API key (optional - leave empty to configure your LLM later):\",\n when: (answers) =>\n (answers.mode === \"LangGraph\" && answers.alreadyDeployed === \"No\") ||\n (answers.mode === \"Standard\" &&\n answers.deploymentChoice === \"Self-hosted\") ||\n (answers.mode === \"MCP\" &&\n answers.deploymentChoice === \"Self-hosted\") ||\n (answers.mode === \"Standard\" && answers.useCopilotCloud !== \"Yes\") ||\n (answers.mode === \"MCP\" && answers.useCopilotCloud !== \"Yes\"),\n sensitive: true,\n sanitize: sanitizers.apiKey,\n },\n\n // IDE Documentation Setup Questions\n {\n type: \"yes/no\",\n name: \"setupIDEDocs\",\n message:\n \"📚 Would you like to add CopilotKit documentation to your IDE? (Provides AI assistant with CopilotKit context)\",\n when: async () => {\n const installedIDEs = await detectInstalledIDEs();\n return installedIDEs.length > 0;\n },\n validate: (input) => {\n try {\n YesNoSchema.parse(input);\n return true;\n } catch (error) {\n return \"Please select Yes or No\";\n }\n },\n },\n {\n type: \"select\",\n name: \"selectedIDE\",\n message:\n \"💻 Which IDE would you like to configure with CopilotKit documentation?\",\n choices: async () => {\n const installedIDEs = await detectInstalledIDEs();\n const choices: Array<{ name: string; value: string }> =\n installedIDEs.map((ide: any) => ({\n name: IDE_DOCS_CONFIGS[ide as keyof typeof IDE_DOCS_CONFIGS]\n .displayName,\n value: ide,\n }));\n choices.push({ name: \"Skip\", value: \"skip\" });\n return choices;\n },\n when: (answers) => answers.setupIDEDocs === \"Yes\",\n },\n ];\n}\n\n// Deployment choice questions for Branch B only\nfunction getDeploymentChoiceQuestions(): Question[] {\n return [\n {\n type: \"select\",\n name: \"deploymentChoice\",\n message: \"🚀 Use Copilot Cloud, or self-hosted?\",\n choices: Array.from(DEPLOYMENT_CHOICES),\n validate: (input) => {\n try {\n DeploymentChoiceSchema.parse(input);\n return true;\n } catch (error) {\n return \"Please select a valid deployment option\";\n }\n },\n },\n ];\n}\n\n// Cloud deployment questions for Branch C (current flow)\nfunction getCloudDeploymentQuestions(): Question[] {\n return [\n {\n type: \"yes/no\",\n name: \"useCopilotCloud\",\n message: \"🪁 Deploy with Copilot Cloud? (recommended for production)\",\n when: (answers) =>\n answers.mode === \"Standard\" ||\n answers.mode === \"MCP\" ||\n (answers.mode === \"LangGraph\" && answers.alreadyDeployed === \"No\") || // Include new LangGraph agents\n (answers.mode !== \"CrewAI\" && // Crews only cloud, flows are self-hosted\n answers.alreadyDeployed === \"Yes\" &&\n answers.langGraphPlatform !== \"No\" &&\n !linkToDocs.includes(answers.mode || \"\") &&\n !isLocalhost(answers.langGraphPlatformUrl || \"\")),\n validate: (input) => {\n try {\n YesNoSchema.parse(input);\n return true;\n } catch (error) {\n return \"Please select Yes or No\";\n }\n },\n },\n ];\n}\n\n// Maintain backward compatibility by providing the original questions for Branch C\nexport const questions: Question[] = getQuestionsForBranch(\"C\");\n"],"mappings":"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","names":[]}
@@ -12,7 +12,14 @@ async function cloneGitHubSubdirectory(githubUrl, destinationPath, spinner) {
12
12
  try {
13
13
  const { owner, repo, branch, subdirectoryPath } = parseGitHubUrl(githubUrl);
14
14
  spinner.text = chalk.cyan(`Cloning from ${owner}/${repo}...`);
15
- return await sparseCheckout(owner, repo, branch, subdirectoryPath, destinationPath, spinner);
15
+ return await sparseCheckout(
16
+ owner,
17
+ repo,
18
+ branch,
19
+ subdirectoryPath,
20
+ destinationPath,
21
+ spinner
22
+ );
16
23
  } catch (error) {
17
24
  spinner.text = chalk.red(`Failed to clone from GitHub: ${error}`);
18
25
  return false;
@@ -24,14 +31,28 @@ async function sparseCheckout(owner, repo, branch, subdirectoryPath, destination
24
31
  spinner.text = chalk.cyan("Creating temporary workspace...");
25
32
  execSync("git init", { cwd: tempDir, stdio: "pipe" });
26
33
  spinner.text = chalk.cyan("Connecting to repository...");
27
- execSync(`git remote add origin https://github.com/${owner}/${repo}.git`, { cwd: tempDir, stdio: "pipe" });
28
- execSync("git config core.sparseCheckout true", { cwd: tempDir, stdio: "pipe" });
29
- fs.writeFileSync(path.join(tempDir, ".git/info/sparse-checkout"), subdirectoryPath);
34
+ execSync(`git remote add origin https://github.com/${owner}/${repo}.git`, {
35
+ cwd: tempDir,
36
+ stdio: "pipe"
37
+ });
38
+ execSync("git config core.sparseCheckout true", {
39
+ cwd: tempDir,
40
+ stdio: "pipe"
41
+ });
42
+ fs.writeFileSync(
43
+ path.join(tempDir, ".git/info/sparse-checkout"),
44
+ subdirectoryPath
45
+ );
30
46
  spinner.text = chalk.cyan("Downloading agent files...");
31
- execSync(`git pull origin ${branch} --depth=1`, { cwd: tempDir, stdio: "pipe" });
47
+ execSync(`git pull origin ${branch} --depth=1`, {
48
+ cwd: tempDir,
49
+ stdio: "pipe"
50
+ });
32
51
  const sourcePath = path.join(tempDir, subdirectoryPath);
33
52
  if (!fs.existsSync(sourcePath)) {
34
- throw new Error(`Subdirectory '${subdirectoryPath}' not found in the repository.`);
53
+ throw new Error(
54
+ `Subdirectory '${subdirectoryPath}' not found in the repository.`
55
+ );
35
56
  }
36
57
  fs.mkdirSync(destinationPath, { recursive: true });
37
58
  spinner.text = chalk.cyan("Installing agent files...");
@@ -126,20 +147,6 @@ async function scaffoldAgent(userAnswers) {
126
147
  fs2.writeFileSync(agentEnvFile, envContent, "utf8");
127
148
  spinner.text = chalk2.cyan("Added API keys to agent .env file");
128
149
  }
129
- if (userAnswers.mode === "LangGraph" && userAnswers.langSmithApiKey) {
130
- envContent += `LANGSMITH_API_KEY=${userAnswers.langSmithApiKey}
131
- `;
132
- }
133
- if (envContent) {
134
- const agentEnvFile = path2.join(agentDir, ".env");
135
- fs2.writeFileSync(agentEnvFile, envContent, "utf8");
136
- spinner.text = chalk2.cyan("Added API keys to agent .env file");
137
- }
138
- if (envContent) {
139
- const agentEnvFile = path2.join(agentDir, ".env");
140
- fs2.writeFileSync(agentEnvFile, envContent, "utf8");
141
- spinner.text = chalk2.cyan("Added API keys to agent .env file");
142
- }
143
150
  } catch (error) {
144
151
  spinner.fail(chalk2.red("Failed to clone agent template"));
145
152
  throw error;
@@ -149,13 +156,13 @@ async function scaffoldAgent(userAnswers) {
149
156
  var AgentTemplates = {
150
157
  LangGraph: {
151
158
  Starter: {
152
- Python: "https://github.com/CopilotKit/coagents-starter-langgraph/tree/main/agent-py",
153
- TypeScript: "https://github.com/CopilotKit/coagents-starter-langgraph/tree/main/agent-js"
159
+ Python: "https://github.com/CopilotKit/CopilotKit/tree/main/examples/starters/coagents-langgraph/agent-py",
160
+ TypeScript: "https://github.com/CopilotKit/CopilotKit/tree/main/examples/starters/coagents-langgraph/agent-js"
154
161
  }
155
162
  },
156
163
  CrewAI: {
157
164
  Flows: {
158
- Starter: "https://github.com/CopilotKit/coagents-starter-crewai-flows/tree/main/agent-py"
165
+ Starter: "https://github.com/CopilotKit/CopilotKit/tree/main/examples/starters/coagents-crewai-flows/agent-py"
159
166
  }
160
167
  }
161
168
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/init/scaffold/agent.ts","../../../../src/lib/init/scaffold/github.ts"],"sourcesContent":["import ora from 'ora'\nimport chalk from 'chalk'\nimport {cloneGitHubSubdirectory} from './github.js'\nimport {Config} from '../types/index.js'\nimport path from 'path'\nimport fs from 'fs'\n\nexport async function scaffoldAgent(userAnswers: Config) {\n if (\n userAnswers.mode === 'CrewAI' ||\n (userAnswers.mode === 'LangGraph' && !userAnswers.langGraphAgent) ||\n userAnswers.mode === 'Standard' ||\n userAnswers.mode === 'MCP'\n ) {\n return\n }\n\n const spinner = ora({\n text: chalk.cyan('Setting up AI agent...'),\n color: 'cyan',\n }).start()\n\n let template = ''\n switch (userAnswers.mode) {\n case 'LangGraph':\n if (userAnswers.langGraphAgent === 'Python Starter') {\n template = AgentTemplates.LangGraph.Starter.Python\n } else {\n template = AgentTemplates.LangGraph.Starter.TypeScript\n }\n break\n }\n\n if (!template) {\n spinner.fail(chalk.red('Failed to determine agent template'))\n throw new Error('Failed to determine agent template')\n }\n\n const agentDir = path.join(process.cwd(), 'agent')\n\n try {\n await cloneGitHubSubdirectory(template, agentDir, spinner)\n\n // Create .env file in the agent directory\n spinner.text = chalk.cyan('Creating agent environment variables...')\n\n let envContent = ''\n\n // Add OpenAI API key if provided\n if (userAnswers.llmToken) {\n envContent += `OPENAI_API_KEY=${userAnswers.llmToken}\\n`\n }\n\n // Add LangSmith API key for LangGraph\n if (userAnswers.mode === 'LangGraph' && userAnswers.langSmithApiKey) {\n envContent += `LANGSMITH_API_KEY=${userAnswers.langSmithApiKey}\\n`\n }\n\n if (envContent) {\n const agentEnvFile = path.join(agentDir, '.env')\n fs.writeFileSync(agentEnvFile, envContent, 'utf8')\n spinner.text = chalk.cyan('Added API keys to agent .env file')\n }\n\n // Add LangSmith API key for LangGraph\n if (userAnswers.mode === 'LangGraph' && userAnswers.langSmithApiKey) {\n envContent += `LANGSMITH_API_KEY=${userAnswers.langSmithApiKey}\\n`\n }\n\n if (envContent) {\n const agentEnvFile = path.join(agentDir, '.env')\n fs.writeFileSync(agentEnvFile, envContent, 'utf8')\n spinner.text = chalk.cyan('Added API keys to agent .env file')\n }\n\n if (envContent) {\n const agentEnvFile = path.join(agentDir, '.env')\n fs.writeFileSync(agentEnvFile, envContent, 'utf8')\n spinner.text = chalk.cyan('Added API keys to agent .env file')\n }\n } catch (error) {\n spinner.fail(chalk.red('Failed to clone agent template'))\n throw error\n }\n\n spinner.succeed(`${userAnswers.mode} agent cloned successfully`)\n}\n\nexport const AgentTemplates = {\n LangGraph: {\n Starter: {\n Python: 'https://github.com/CopilotKit/coagents-starter-langgraph/tree/main/agent-py',\n TypeScript: 'https://github.com/CopilotKit/coagents-starter-langgraph/tree/main/agent-js',\n },\n },\n CrewAI: {\n Flows: {\n Starter: 'https://github.com/CopilotKit/coagents-starter-crewai-flows/tree/main/agent-py',\n },\n },\n}\n","import {execSync} from 'child_process'\nimport * as fs from 'fs'\nimport * as path from 'path'\nimport * as os from 'os'\nimport {Config} from '../types/index.js'\nimport chalk from 'chalk'\nimport ora, {Ora} from 'ora'\n\n/**\n * Clones a specific subdirectory from a GitHub repository\n *\n * @param githubUrl - The GitHub URL to the repository or subdirectory\n * @param destinationPath - The local path where the content should be copied\n * @param spinner - The spinner to update with progress information\n * @returns A boolean indicating success or failure\n */\nexport async function cloneGitHubSubdirectory(\n githubUrl: string,\n destinationPath: string,\n spinner: Ora,\n): Promise<boolean> {\n try {\n // Parse the GitHub URL to extract repo info\n const {owner, repo, branch, subdirectoryPath} = parseGitHubUrl(githubUrl)\n\n spinner.text = chalk.cyan(`Cloning from ${owner}/${repo}...`)\n\n // Method 1: Use sparse checkout (more efficient than full clone)\n return await sparseCheckout(owner, repo, branch, subdirectoryPath, destinationPath, spinner)\n } catch (error) {\n spinner.text = chalk.red(`Failed to clone from GitHub: ${error}`)\n return false\n }\n}\n\n/**\n * Uses Git sparse-checkout to efficiently download only the needed subdirectory\n */\nasync function sparseCheckout(\n owner: string,\n repo: string,\n branch: string,\n subdirectoryPath: string,\n destinationPath: string,\n spinner: Ora,\n): Promise<boolean> {\n const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'copilotkit-sparse-'))\n\n try {\n spinner.text = chalk.cyan('Creating temporary workspace...')\n\n // Initialize git repo\n execSync('git init', {cwd: tempDir, stdio: 'pipe'})\n\n spinner.text = chalk.cyan('Connecting to repository...')\n\n // Add remote\n execSync(`git remote add origin https://github.com/${owner}/${repo}.git`, {cwd: tempDir, stdio: 'pipe'})\n\n // Enable sparse checkout\n execSync('git config core.sparseCheckout true', {cwd: tempDir, stdio: 'pipe'})\n\n // Specify which subdirectory to checkout\n fs.writeFileSync(path.join(tempDir, '.git/info/sparse-checkout'), subdirectoryPath)\n\n spinner.text = chalk.cyan('Downloading agent files...')\n\n // Pull only the specified branch\n execSync(`git pull origin ${branch} --depth=1`, {cwd: tempDir, stdio: 'pipe'})\n\n // Copy the subdirectory to the destination\n const sourcePath = path.join(tempDir, subdirectoryPath)\n if (!fs.existsSync(sourcePath)) {\n throw new Error(`Subdirectory '${subdirectoryPath}' not found in the repository.`)\n }\n\n // Ensure destination directory exists\n fs.mkdirSync(destinationPath, {recursive: true})\n\n spinner.text = chalk.cyan('Installing agent files...')\n\n // Copy the subdirectory to the destination\n await copyDirectoryAsync(sourcePath, destinationPath)\n\n return true\n } finally {\n // Clean up the temporary directory\n try {\n fs.rmSync(tempDir, {recursive: true, force: true})\n } catch (error) {\n console.warn(`Failed to clean up temporary directory: ${error}`)\n }\n }\n}\n\n/**\n * Recursively copies a directory with async pauses\n */\nasync function copyDirectoryAsync(source: string, destination: string): Promise<void> {\n // Create destination directory if it doesn't exist\n if (!fs.existsSync(destination)) {\n fs.mkdirSync(destination, {recursive: true})\n }\n\n // Read all files/directories from source\n const entries = fs.readdirSync(source, {withFileTypes: true})\n\n for (const entry of entries) {\n const srcPath = path.join(source, entry.name)\n const destPath = path.join(destination, entry.name)\n\n if (entry.isDirectory()) {\n // Recursively copy subdirectories\n await copyDirectoryAsync(srcPath, destPath)\n } else {\n // Copy files\n fs.copyFileSync(srcPath, destPath)\n }\n\n // For large directories, add small pauses\n if (entries.length > 10) {\n await new Promise((resolve) => setTimeout(resolve, 1))\n }\n }\n}\n\n/**\n * Parses a GitHub URL to extract owner, repo, branch and subdirectory path\n */\nfunction parseGitHubUrl(githubUrl: string): {\n owner: string\n repo: string\n branch: string\n subdirectoryPath: string\n} {\n const url = new URL(githubUrl)\n\n if (url.hostname !== 'github.com') {\n throw new Error('Only GitHub URLs are supported')\n }\n\n const pathParts = url.pathname.split('/').filter(Boolean)\n\n if (pathParts.length < 2) {\n throw new Error('Invalid GitHub URL format')\n }\n\n const owner = pathParts[0]\n const repo = pathParts[1]\n let branch = 'main' // Default branch\n let subdirectoryPath = ''\n\n if (pathParts.length > 3 && (pathParts[2] === 'tree' || pathParts[2] === 'blob')) {\n branch = pathParts[3]\n subdirectoryPath = pathParts.slice(4).join('/')\n }\n\n return {owner, repo, branch, subdirectoryPath}\n}\n\n/**\n * Validates if a string is a valid GitHub URL\n */\nexport function isValidGitHubUrl(url: string): boolean {\n try {\n const parsedUrl = new URL(url)\n return parsedUrl.hostname === 'github.com' && parsedUrl.pathname.split('/').filter(Boolean).length >= 2\n } catch {\n return false\n }\n}\n"],"mappings":"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","names":["chalk","path","fs","chalk"]}
1
+ {"version":3,"sources":["../../../../src/lib/init/scaffold/agent.ts","../../../../src/lib/init/scaffold/github.ts"],"sourcesContent":["import ora from \"ora\";\nimport chalk from \"chalk\";\nimport { cloneGitHubSubdirectory } from \"./github.js\";\nimport { Config } from \"../types/index.js\";\nimport path from \"path\";\nimport fs from \"fs\";\n\nexport async function scaffoldAgent(userAnswers: Config) {\n if (\n userAnswers.mode === \"CrewAI\" ||\n (userAnswers.mode === \"LangGraph\" && !userAnswers.langGraphAgent) ||\n userAnswers.mode === \"Standard\" ||\n userAnswers.mode === \"MCP\"\n ) {\n return;\n }\n\n const spinner = ora({\n text: chalk.cyan(\"Setting up AI agent...\"),\n color: \"cyan\",\n }).start();\n\n let template = \"\";\n switch (userAnswers.mode) {\n case \"LangGraph\":\n if (userAnswers.langGraphAgent === \"Python Starter\") {\n template = AgentTemplates.LangGraph.Starter.Python;\n } else {\n template = AgentTemplates.LangGraph.Starter.TypeScript;\n }\n break;\n }\n\n if (!template) {\n spinner.fail(chalk.red(\"Failed to determine agent template\"));\n throw new Error(\"Failed to determine agent template\");\n }\n\n const agentDir = path.join(process.cwd(), \"agent\");\n\n try {\n await cloneGitHubSubdirectory(template, agentDir, spinner);\n\n // Create .env file in the agent directory\n spinner.text = chalk.cyan(\"Creating agent environment variables...\");\n\n let envContent = \"\";\n\n // Add OpenAI API key if provided\n if (userAnswers.llmToken) {\n envContent += `OPENAI_API_KEY=${userAnswers.llmToken}\\n`;\n }\n\n // Add LangSmith API key for LangGraph\n if (userAnswers.mode === \"LangGraph\" && userAnswers.langSmithApiKey) {\n envContent += `LANGSMITH_API_KEY=${userAnswers.langSmithApiKey}\\n`;\n }\n\n if (envContent) {\n const agentEnvFile = path.join(agentDir, \".env\");\n fs.writeFileSync(agentEnvFile, envContent, \"utf8\");\n spinner.text = chalk.cyan(\"Added API keys to agent .env file\");\n }\n } catch (error) {\n spinner.fail(chalk.red(\"Failed to clone agent template\"));\n throw error;\n }\n\n spinner.succeed(`${userAnswers.mode} agent cloned successfully`);\n}\n\nexport const AgentTemplates = {\n LangGraph: {\n Starter: {\n Python:\n \"https://github.com/CopilotKit/CopilotKit/tree/main/examples/starters/coagents-langgraph/agent-py\",\n TypeScript:\n \"https://github.com/CopilotKit/CopilotKit/tree/main/examples/starters/coagents-langgraph/agent-js\",\n },\n },\n CrewAI: {\n Flows: {\n Starter:\n \"https://github.com/CopilotKit/CopilotKit/tree/main/examples/starters/coagents-crewai-flows/agent-py\",\n },\n },\n};\n","import { execSync } from \"child_process\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as os from \"os\";\nimport { Config } from \"../types/index.js\";\nimport chalk from \"chalk\";\nimport ora, { Ora } from \"ora\";\n\n/**\n * Clones a specific subdirectory from a GitHub repository\n *\n * @param githubUrl - The GitHub URL to the repository or subdirectory\n * @param destinationPath - The local path where the content should be copied\n * @param spinner - The spinner to update with progress information\n * @returns A boolean indicating success or failure\n */\nexport async function cloneGitHubSubdirectory(\n githubUrl: string,\n destinationPath: string,\n spinner: Ora,\n): Promise<boolean> {\n try {\n // Parse the GitHub URL to extract repo info\n const { owner, repo, branch, subdirectoryPath } = parseGitHubUrl(githubUrl);\n\n spinner.text = chalk.cyan(`Cloning from ${owner}/${repo}...`);\n\n // Method 1: Use sparse checkout (more efficient than full clone)\n return await sparseCheckout(\n owner,\n repo,\n branch,\n subdirectoryPath,\n destinationPath,\n spinner,\n );\n } catch (error) {\n spinner.text = chalk.red(`Failed to clone from GitHub: ${error}`);\n return false;\n }\n}\n\n/**\n * Uses Git sparse-checkout to efficiently download only the needed subdirectory\n */\nasync function sparseCheckout(\n owner: string,\n repo: string,\n branch: string,\n subdirectoryPath: string,\n destinationPath: string,\n spinner: Ora,\n): Promise<boolean> {\n const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), \"copilotkit-sparse-\"));\n\n try {\n spinner.text = chalk.cyan(\"Creating temporary workspace...\");\n\n // Initialize git repo\n execSync(\"git init\", { cwd: tempDir, stdio: \"pipe\" });\n\n spinner.text = chalk.cyan(\"Connecting to repository...\");\n\n // Add remote\n execSync(`git remote add origin https://github.com/${owner}/${repo}.git`, {\n cwd: tempDir,\n stdio: \"pipe\",\n });\n\n // Enable sparse checkout\n execSync(\"git config core.sparseCheckout true\", {\n cwd: tempDir,\n stdio: \"pipe\",\n });\n\n // Specify which subdirectory to checkout\n fs.writeFileSync(\n path.join(tempDir, \".git/info/sparse-checkout\"),\n subdirectoryPath,\n );\n\n spinner.text = chalk.cyan(\"Downloading agent files...\");\n\n // Pull only the specified branch\n execSync(`git pull origin ${branch} --depth=1`, {\n cwd: tempDir,\n stdio: \"pipe\",\n });\n\n // Copy the subdirectory to the destination\n const sourcePath = path.join(tempDir, subdirectoryPath);\n if (!fs.existsSync(sourcePath)) {\n throw new Error(\n `Subdirectory '${subdirectoryPath}' not found in the repository.`,\n );\n }\n\n // Ensure destination directory exists\n fs.mkdirSync(destinationPath, { recursive: true });\n\n spinner.text = chalk.cyan(\"Installing agent files...\");\n\n // Copy the subdirectory to the destination\n await copyDirectoryAsync(sourcePath, destinationPath);\n\n return true;\n } finally {\n // Clean up the temporary directory\n try {\n fs.rmSync(tempDir, { recursive: true, force: true });\n } catch (error) {\n console.warn(`Failed to clean up temporary directory: ${error}`);\n }\n }\n}\n\n/**\n * Recursively copies a directory with async pauses\n */\nasync function copyDirectoryAsync(\n source: string,\n destination: string,\n): Promise<void> {\n // Create destination directory if it doesn't exist\n if (!fs.existsSync(destination)) {\n fs.mkdirSync(destination, { recursive: true });\n }\n\n // Read all files/directories from source\n const entries = fs.readdirSync(source, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = path.join(source, entry.name);\n const destPath = path.join(destination, entry.name);\n\n if (entry.isDirectory()) {\n // Recursively copy subdirectories\n await copyDirectoryAsync(srcPath, destPath);\n } else {\n // Copy files\n fs.copyFileSync(srcPath, destPath);\n }\n\n // For large directories, add small pauses\n if (entries.length > 10) {\n await new Promise((resolve) => setTimeout(resolve, 1));\n }\n }\n}\n\n/**\n * Parses a GitHub URL to extract owner, repo, branch and subdirectory path\n */\nfunction parseGitHubUrl(githubUrl: string): {\n owner: string;\n repo: string;\n branch: string;\n subdirectoryPath: string;\n} {\n const url = new URL(githubUrl);\n\n if (url.hostname !== \"github.com\") {\n throw new Error(\"Only GitHub URLs are supported\");\n }\n\n const pathParts = url.pathname.split(\"/\").filter(Boolean);\n\n if (pathParts.length < 2) {\n throw new Error(\"Invalid GitHub URL format\");\n }\n\n const owner = pathParts[0];\n const repo = pathParts[1];\n let branch = \"main\"; // Default branch\n let subdirectoryPath = \"\";\n\n if (\n pathParts.length > 3 &&\n (pathParts[2] === \"tree\" || pathParts[2] === \"blob\")\n ) {\n branch = pathParts[3];\n subdirectoryPath = pathParts.slice(4).join(\"/\");\n }\n\n return { owner, repo, branch, subdirectoryPath };\n}\n\n/**\n * Validates if a string is a valid GitHub URL\n */\nexport function isValidGitHubUrl(url: string): boolean {\n try {\n const parsedUrl = new URL(url);\n return (\n parsedUrl.hostname === \"github.com\" &&\n parsedUrl.pathname.split(\"/\").filter(Boolean).length >= 2\n );\n } catch {\n return false;\n }\n}\n"],"mappings":"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","names":["chalk","path","fs","chalk"]}
@@ -11,18 +11,31 @@ async function addCrewInputs(url, token) {
11
11
  try {
12
12
  await fs.access(filePath);
13
13
  } catch {
14
- filePath = path.join(process.cwd(), "src", "app", "copilotkit", "page.tsx");
14
+ filePath = path.join(
15
+ process.cwd(),
16
+ "src",
17
+ "app",
18
+ "copilotkit",
19
+ "page.tsx"
20
+ );
15
21
  }
16
22
  try {
17
23
  await fs.access(filePath);
18
24
  } catch {
19
- throw new Error("app/copilotkit/page.tsx and src/app/copilotkit/page.tsx not found");
25
+ throw new Error(
26
+ "app/copilotkit/page.tsx and src/app/copilotkit/page.tsx not found"
27
+ );
20
28
  }
21
29
  let fileContent = await fs.readFile(filePath, "utf8");
22
30
  const inputsString = JSON.stringify(inputs);
23
- fileContent = fileContent.replace(/\[["']YOUR_INPUTS_HERE["']\]/g, inputsString);
31
+ fileContent = fileContent.replace(
32
+ /\[["']YOUR_INPUTS_HERE["']\]/g,
33
+ inputsString
34
+ );
24
35
  await fs.writeFile(filePath, fileContent, "utf8");
25
- spinner.succeed("Successfully added crew inputs to app/copilotkit/page.tsx");
36
+ spinner.succeed(
37
+ "Successfully added crew inputs to app/copilotkit/page.tsx"
38
+ );
26
39
  } catch (error) {
27
40
  console.error("Error updating crew inputs:", error);
28
41
  throw error;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/init/scaffold/crew-inputs.ts"],"sourcesContent":["import * as fs from 'fs/promises'\nimport ora from 'ora'\nimport * as path from 'path'\n\nexport async function addCrewInputs(url: string, token: string) {\n try {\n const spinner = ora('Analyzing crew inputs...').start()\n // Get inputs from the crew API\n const inputs = await getCrewInputs(url, token)\n spinner.text = 'Adding inputs to app/copilotkit/page.tsx...'\n\n // Path to the file we need to modify\n let filePath = path.join(process.cwd(), 'app', 'copilotkit', 'page.tsx')\n\n // check if non-src file exists\n try {\n await fs.access(filePath)\n } catch {\n filePath = path.join(process.cwd(), 'src', 'app', 'copilotkit', 'page.tsx')\n }\n\n // check if src file exists\n try {\n await fs.access(filePath)\n } catch {\n throw new Error('app/copilotkit/page.tsx and src/app/copilotkit/page.tsx not found')\n }\n\n // Read the file content\n let fileContent = await fs.readFile(filePath, 'utf8')\n\n // Replace all instances of \"YOUR_INPUTS_HERE\" with the inputs array as a string\n const inputsString = JSON.stringify(inputs)\n fileContent = fileContent.replace(/\\[[\"']YOUR_INPUTS_HERE[\"']\\]/g, inputsString)\n\n // Write the updated content back to the file\n await fs.writeFile(filePath, fileContent, 'utf8')\n\n spinner.succeed('Successfully added crew inputs to app/copilotkit/page.tsx')\n } catch (error) {\n console.error('Error updating crew inputs:', error)\n throw error\n }\n}\n\nasync function getCrewInputs(url: string, token: string): Promise<string[]> {\n const response = await fetch(`${url.trim()}/inputs`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n })\n\n if (!response.ok) {\n throw new Error(`Failed to fetch inputs: ${response.statusText}`)\n }\n\n const data = (await response.json()) as {inputs: string[]}\n return data.inputs\n}\n"],"mappings":";AAAA,YAAY,QAAQ;AACpB,OAAO,SAAS;AAChB,YAAY,UAAU;AAEtB,eAAsB,cAAc,KAAa,OAAe;AAC9D,MAAI;AACF,UAAM,UAAU,IAAI,0BAA0B,EAAE,MAAM;AAEtD,UAAM,SAAS,MAAM,cAAc,KAAK,KAAK;AAC7C,YAAQ,OAAO;AAGf,QAAI,WAAgB,UAAK,QAAQ,IAAI,GAAG,OAAO,cAAc,UAAU;AAGvE,QAAI;AACF,YAAS,UAAO,QAAQ;AAAA,IAC1B,QAAQ;AACN,iBAAgB,UAAK,QAAQ,IAAI,GAAG,OAAO,OAAO,cAAc,UAAU;AAAA,IAC5E;AAGA,QAAI;AACF,YAAS,UAAO,QAAQ;AAAA,IAC1B,QAAQ;AACN,YAAM,IAAI,MAAM,mEAAmE;AAAA,IACrF;AAGA,QAAI,cAAc,MAAS,YAAS,UAAU,MAAM;AAGpD,UAAM,eAAe,KAAK,UAAU,MAAM;AAC1C,kBAAc,YAAY,QAAQ,iCAAiC,YAAY;AAG/E,UAAS,aAAU,UAAU,aAAa,MAAM;AAEhD,YAAQ,QAAQ,2DAA2D;AAAA,EAC7E,SAAS,OAAO;AACd,YAAQ,MAAM,+BAA+B,KAAK;AAClD,UAAM;AAAA,EACR;AACF;AAEA,eAAe,cAAc,KAAa,OAAkC;AAC1E,QAAM,WAAW,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,WAAW;AAAA,IACnD,SAAS;AAAA,MACP,eAAe,UAAU,KAAK;AAAA,IAChC;AAAA,EACF,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,2BAA2B,SAAS,UAAU,EAAE;AAAA,EAClE;AAEA,QAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,SAAO,KAAK;AACd;","names":[]}
1
+ {"version":3,"sources":["../../../../src/lib/init/scaffold/crew-inputs.ts"],"sourcesContent":["import * as fs from \"fs/promises\";\nimport ora from \"ora\";\nimport * as path from \"path\";\n\nexport async function addCrewInputs(url: string, token: string) {\n try {\n const spinner = ora(\"Analyzing crew inputs...\").start();\n // Get inputs from the crew API\n const inputs = await getCrewInputs(url, token);\n spinner.text = \"Adding inputs to app/copilotkit/page.tsx...\";\n\n // Path to the file we need to modify\n let filePath = path.join(process.cwd(), \"app\", \"copilotkit\", \"page.tsx\");\n\n // check if non-src file exists\n try {\n await fs.access(filePath);\n } catch {\n filePath = path.join(\n process.cwd(),\n \"src\",\n \"app\",\n \"copilotkit\",\n \"page.tsx\",\n );\n }\n\n // check if src file exists\n try {\n await fs.access(filePath);\n } catch {\n throw new Error(\n \"app/copilotkit/page.tsx and src/app/copilotkit/page.tsx not found\",\n );\n }\n\n // Read the file content\n let fileContent = await fs.readFile(filePath, \"utf8\");\n\n // Replace all instances of \"YOUR_INPUTS_HERE\" with the inputs array as a string\n const inputsString = JSON.stringify(inputs);\n fileContent = fileContent.replace(\n /\\[[\"']YOUR_INPUTS_HERE[\"']\\]/g,\n inputsString,\n );\n\n // Write the updated content back to the file\n await fs.writeFile(filePath, fileContent, \"utf8\");\n\n spinner.succeed(\n \"Successfully added crew inputs to app/copilotkit/page.tsx\",\n );\n } catch (error) {\n console.error(\"Error updating crew inputs:\", error);\n throw error;\n }\n}\n\nasync function getCrewInputs(url: string, token: string): Promise<string[]> {\n const response = await fetch(`${url.trim()}/inputs`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch inputs: ${response.statusText}`);\n }\n\n const data = (await response.json()) as { inputs: string[] };\n return data.inputs;\n}\n"],"mappings":";AAAA,YAAY,QAAQ;AACpB,OAAO,SAAS;AAChB,YAAY,UAAU;AAEtB,eAAsB,cAAc,KAAa,OAAe;AAC9D,MAAI;AACF,UAAM,UAAU,IAAI,0BAA0B,EAAE,MAAM;AAEtD,UAAM,SAAS,MAAM,cAAc,KAAK,KAAK;AAC7C,YAAQ,OAAO;AAGf,QAAI,WAAgB,UAAK,QAAQ,IAAI,GAAG,OAAO,cAAc,UAAU;AAGvE,QAAI;AACF,YAAS,UAAO,QAAQ;AAAA,IAC1B,QAAQ;AACN,iBAAgB;AAAA,QACd,QAAQ,IAAI;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAGA,QAAI;AACF,YAAS,UAAO,QAAQ;AAAA,IAC1B,QAAQ;AACN,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAGA,QAAI,cAAc,MAAS,YAAS,UAAU,MAAM;AAGpD,UAAM,eAAe,KAAK,UAAU,MAAM;AAC1C,kBAAc,YAAY;AAAA,MACxB;AAAA,MACA;AAAA,IACF;AAGA,UAAS,aAAU,UAAU,aAAa,MAAM;AAEhD,YAAQ;AAAA,MACN;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,+BAA+B,KAAK;AAClD,UAAM;AAAA,EACR;AACF;AAEA,eAAe,cAAc,KAAa,OAAkC;AAC1E,QAAM,WAAW,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,WAAW;AAAA,IACnD,SAAS;AAAA,MACP,eAAe,UAAU,KAAK;AAAA,IAChC;AAAA,EACF,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,2BAA2B,SAAS,UAAU,EAAE;AAAA,EAClE;AAEA,QAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,SAAO,KAAK;AACd;","names":[]}
@@ -5,17 +5,20 @@ import fs from "fs";
5
5
  // src/lib/init/scaffold/langgraph-assistants.ts
6
6
  async function getLangGraphAgents(url, langSmithApiKey) {
7
7
  try {
8
- const response = await fetch(`${url.trim().replace(/\/$/, "")}/assistants/search`, {
9
- method: "POST",
10
- headers: {
11
- "Content-Type": "application/json",
12
- "X-Api-Key": langSmithApiKey
13
- },
14
- body: JSON.stringify({
15
- limit: 10,
16
- offset: 0
17
- })
18
- });
8
+ const response = await fetch(
9
+ `${url.trim().replace(/\/$/, "")}/assistants/search`,
10
+ {
11
+ method: "POST",
12
+ headers: {
13
+ "Content-Type": "application/json",
14
+ "X-Api-Key": langSmithApiKey
15
+ },
16
+ body: JSON.stringify({
17
+ limit: 10,
18
+ offset: 0
19
+ })
20
+ }
21
+ );
19
22
  return await response.json();
20
23
  } catch (error) {
21
24
  throw new Error(`Failed to get LangGraph agents: ${error}`);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/init/scaffold/env.ts","../../../../src/lib/init/scaffold/langgraph-assistants.ts","../../../../src/lib/init/utils.ts"],"sourcesContent":["import path from 'path'\nimport fs from 'fs'\nimport {Config} from '../types/index.js'\nimport {getLangGraphAgents} from './langgraph-assistants.js'\nimport inquirer from 'inquirer'\nimport {isLocalhost} from '../utils.js'\n\n/**\n * Determines if cloud deployment is needed based on user answers\n * Uses the same logic as the main init flow to ensure consistency\n */\nfunction needsCloudDeployment(userAnswers: Config): boolean {\n return (\n userAnswers.deploymentChoice === 'Copilot Cloud' || // Branch B choice\n userAnswers.useCopilotCloud === 'Yes' || // Branch C choice\n userAnswers.mode === 'CrewAI' || // CrewAI always needs cloud\n (!userAnswers.deploymentChoice && !userAnswers.useCopilotCloud) // Branch A default (no questions = cloud)\n )\n}\n\nexport async function scaffoldEnv(flags: any, userAnswers: Config) {\n try {\n // Define the env file path\n const envFile = path.join(process.cwd(), '.env')\n\n // Create the env file if it doesn't exist\n if (!fs.existsSync(envFile)) {\n fs.writeFileSync(envFile, '', 'utf8')\n } else {\n }\n\n // Build environment variables based on user selections\n let newEnvValues = ''\n\n // Check if cloud deployment is needed\n const isCloudDeployment = needsCloudDeployment(userAnswers)\n\n // Copilot Cloud API key\n if (userAnswers.copilotCloudPublicApiKey) {\n newEnvValues += `NEXT_PUBLIC_COPILOT_API_KEY=${userAnswers.copilotCloudPublicApiKey}\\n`\n }\n\n // LangSmith API key (for LangGraph)\n if (userAnswers.langSmithApiKey) {\n // Add both formats for compatibility\n newEnvValues += `LANGSMITH_API_KEY=${userAnswers.langSmithApiKey}\\n`\n }\n\n // LLM API key - set as both LLM_TOKEN and OPENAI_API_KEY for compatibility\n if (userAnswers.llmToken) {\n newEnvValues += `OPENAI_API_KEY=${userAnswers.llmToken}\\n`\n }\n\n // CrewAI name\n if (userAnswers.crewName) {\n newEnvValues += `NEXT_PUBLIC_COPILOTKIT_AGENT_NAME=${userAnswers.crewName}\\n`\n }\n\n if (userAnswers.langGraphAgent) {\n newEnvValues += `NEXT_PUBLIC_COPILOTKIT_AGENT_NAME=sample_agent\\n`\n newEnvValues += `LANGGRAPH_DEPLOYMENT_URL=http://localhost:8123\\n`\n } else if (userAnswers.langGraphPlatform === 'Yes' && !isCloudDeployment) {\n newEnvValues += `LANGGRAPH_DEPLOYMENT_URL=${userAnswers.langGraphPlatformUrl}\\n`\n } else if (userAnswers.langGraphRemoteEndpointURL) {\n newEnvValues += `COPILOTKIT_REMOTE_ENDPOINT=${userAnswers.langGraphRemoteEndpointURL}\\n`\n }\n\n // Runtime URL if provided via flags\n if (flags.runtimeUrl) {\n newEnvValues += `NEXT_PUBLIC_COPILOTKIT_RUNTIME_URL=${flags.runtimeUrl}\\n`\n } else if (!isCloudDeployment && userAnswers.crewType !== 'Crews' && userAnswers.crewType !== 'Flows') {\n newEnvValues += `NEXT_PUBLIC_COPILOTKIT_RUNTIME_URL=/api/copilotkit\\n`\n }\n\n if (\n userAnswers.langGraphPlatformUrl &&\n (userAnswers.langSmithApiKey || isLocalhost(userAnswers.langGraphPlatformUrl))\n ) {\n const langGraphAgents = await getLangGraphAgents(\n userAnswers.langGraphPlatformUrl,\n userAnswers.langSmithApiKey || '',\n )\n let langGraphAgent = ''\n if (langGraphAgents.length > 1) {\n const {langGraphAgentChoice} = await inquirer.prompt([\n {\n type: 'list',\n name: 'langGraphAgentChoice',\n message: '🦜🔗 Which agent from your graph would you like to use?',\n choices: langGraphAgents.map((agent: any) => ({\n name: agent.graph_id,\n value: agent.graph_id,\n })),\n },\n ])\n langGraphAgent = langGraphAgentChoice\n } else if (langGraphAgents.length === 1) {\n langGraphAgent = langGraphAgents[0].graph_id\n } else {\n throw new Error('No agents found in your LangGraph endpoint')\n }\n\n newEnvValues += `NEXT_PUBLIC_COPILOTKIT_AGENT_NAME=${langGraphAgent}\\n`\n }\n\n // Append the variables to the .env file\n if (newEnvValues) {\n fs.appendFileSync(envFile, newEnvValues)\n }\n } catch (error) {\n throw error\n }\n}\n","export type LangGraphAgent = {\n assistant_id: string\n graph_id: string\n config: {\n tags: string[]\n recursion_limit: number\n configurable: Record<string, any>\n }\n created_at: string\n updated_at: string\n metadata: Record<string, any>\n version: number\n name: string\n description: string\n}\n\nexport async function getLangGraphAgents(url: string, langSmithApiKey: string) {\n try {\n const response = await fetch(`${url.trim().replace(/\\/$/, '')}/assistants/search`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Api-Key': langSmithApiKey,\n },\n body: JSON.stringify({\n limit: 10,\n offset: 0,\n }),\n })\n\n return (await response.json()) as LangGraphAgent[]\n } catch (error) {\n throw new Error(`Failed to get LangGraph agents: ${error}`)\n }\n}\n","export const isLocalhost = (url: string): boolean => {\n return url.includes('localhost') || url.includes('127.0.0.1') || url.includes('0.0.0.0')\n}\n"],"mappings":";AAAA,OAAO,UAAU;AACjB,OAAO,QAAQ;;;ACef,eAAsB,mBAAmB,KAAa,iBAAyB;AAC7E,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,GAAG,IAAI,KAAK,EAAE,QAAQ,OAAO,EAAE,CAAC,sBAAsB;AAAA,MACjF,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,aAAa;AAAA,MACf;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,OAAO;AAAA,QACP,QAAQ;AAAA,MACV,CAAC;AAAA,IACH,CAAC;AAED,WAAQ,MAAM,SAAS,KAAK;AAAA,EAC9B,SAAS,OAAO;AACd,UAAM,IAAI,MAAM,mCAAmC,KAAK,EAAE;AAAA,EAC5D;AACF;;;AD9BA,OAAO,cAAc;;;AEJd,IAAM,cAAc,CAAC,QAAyB;AACnD,SAAO,IAAI,SAAS,WAAW,KAAK,IAAI,SAAS,WAAW,KAAK,IAAI,SAAS,SAAS;AACzF;;;AFSA,SAAS,qBAAqB,aAA8B;AAC1D,SACE,YAAY,qBAAqB;AAAA,EACjC,YAAY,oBAAoB;AAAA,EAChC,YAAY,SAAS;AAAA,EACpB,CAAC,YAAY,oBAAoB,CAAC,YAAY;AAEnD;AAEA,eAAsB,YAAY,OAAY,aAAqB;AACjE,MAAI;AAEF,UAAM,UAAU,KAAK,KAAK,QAAQ,IAAI,GAAG,MAAM;AAG/C,QAAI,CAAC,GAAG,WAAW,OAAO,GAAG;AAC3B,SAAG,cAAc,SAAS,IAAI,MAAM;AAAA,IACtC,OAAO;AAAA,IACP;AAGA,QAAI,eAAe;AAGnB,UAAM,oBAAoB,qBAAqB,WAAW;AAG1D,QAAI,YAAY,0BAA0B;AACxC,sBAAgB,+BAA+B,YAAY,wBAAwB;AAAA;AAAA,IACrF;AAGA,QAAI,YAAY,iBAAiB;AAE/B,sBAAgB,qBAAqB,YAAY,eAAe;AAAA;AAAA,IAClE;AAGA,QAAI,YAAY,UAAU;AACxB,sBAAgB,kBAAkB,YAAY,QAAQ;AAAA;AAAA,IACxD;AAGA,QAAI,YAAY,UAAU;AACxB,sBAAgB,qCAAqC,YAAY,QAAQ;AAAA;AAAA,IAC3E;AAEA,QAAI,YAAY,gBAAgB;AAC9B,sBAAgB;AAAA;AAChB,sBAAgB;AAAA;AAAA,IAClB,WAAW,YAAY,sBAAsB,SAAS,CAAC,mBAAmB;AACxE,sBAAgB,4BAA4B,YAAY,oBAAoB;AAAA;AAAA,IAC9E,WAAW,YAAY,4BAA4B;AACjD,sBAAgB,8BAA8B,YAAY,0BAA0B;AAAA;AAAA,IACtF;AAGA,QAAI,MAAM,YAAY;AACpB,sBAAgB,sCAAsC,MAAM,UAAU;AAAA;AAAA,IACxE,WAAW,CAAC,qBAAqB,YAAY,aAAa,WAAW,YAAY,aAAa,SAAS;AACrG,sBAAgB;AAAA;AAAA,IAClB;AAEA,QACE,YAAY,yBACX,YAAY,mBAAmB,YAAY,YAAY,oBAAoB,IAC5E;AACA,YAAM,kBAAkB,MAAM;AAAA,QAC5B,YAAY;AAAA,QACZ,YAAY,mBAAmB;AAAA,MACjC;AACA,UAAI,iBAAiB;AACrB,UAAI,gBAAgB,SAAS,GAAG;AAC9B,cAAM,EAAC,qBAAoB,IAAI,MAAM,SAAS,OAAO;AAAA,UACnD;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,SAAS,gBAAgB,IAAI,CAAC,WAAgB;AAAA,cAC5C,MAAM,MAAM;AAAA,cACZ,OAAO,MAAM;AAAA,YACf,EAAE;AAAA,UACJ;AAAA,QACF,CAAC;AACD,yBAAiB;AAAA,MACnB,WAAW,gBAAgB,WAAW,GAAG;AACvC,yBAAiB,gBAAgB,CAAC,EAAE;AAAA,MACtC,OAAO;AACL,cAAM,IAAI,MAAM,4CAA4C;AAAA,MAC9D;AAEA,sBAAgB,qCAAqC,cAAc;AAAA;AAAA,IACrE;AAGA,QAAI,cAAc;AAChB,SAAG,eAAe,SAAS,YAAY;AAAA,IACzC;AAAA,EACF,SAAS,OAAO;AACd,UAAM;AAAA,EACR;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../src/lib/init/scaffold/env.ts","../../../../src/lib/init/scaffold/langgraph-assistants.ts","../../../../src/lib/init/utils.ts"],"sourcesContent":["import path from \"path\";\nimport fs from \"fs\";\nimport { Config } from \"../types/index.js\";\nimport { getLangGraphAgents } from \"./langgraph-assistants.js\";\nimport inquirer from \"inquirer\";\nimport { isLocalhost } from \"../utils.js\";\n\n/**\n * Determines if cloud deployment is needed based on user answers\n * Uses the same logic as the main init flow to ensure consistency\n */\nfunction needsCloudDeployment(userAnswers: Config): boolean {\n return (\n userAnswers.deploymentChoice === \"Copilot Cloud\" || // Branch B choice\n userAnswers.useCopilotCloud === \"Yes\" || // Branch C choice\n userAnswers.mode === \"CrewAI\" || // CrewAI always needs cloud\n (!userAnswers.deploymentChoice && !userAnswers.useCopilotCloud) // Branch A default (no questions = cloud)\n );\n}\n\nexport async function scaffoldEnv(flags: any, userAnswers: Config) {\n try {\n // Define the env file path\n const envFile = path.join(process.cwd(), \".env\");\n\n // Create the env file if it doesn't exist\n if (!fs.existsSync(envFile)) {\n fs.writeFileSync(envFile, \"\", \"utf8\");\n } else {\n }\n\n // Build environment variables based on user selections\n let newEnvValues = \"\";\n\n // Check if cloud deployment is needed\n const isCloudDeployment = needsCloudDeployment(userAnswers);\n\n // Copilot Cloud API key\n if (userAnswers.copilotCloudPublicApiKey) {\n newEnvValues += `NEXT_PUBLIC_COPILOT_API_KEY=${userAnswers.copilotCloudPublicApiKey}\\n`;\n }\n\n // LangSmith API key (for LangGraph)\n if (userAnswers.langSmithApiKey) {\n // Add both formats for compatibility\n newEnvValues += `LANGSMITH_API_KEY=${userAnswers.langSmithApiKey}\\n`;\n }\n\n // LLM API key - set as both LLM_TOKEN and OPENAI_API_KEY for compatibility\n if (userAnswers.llmToken) {\n newEnvValues += `OPENAI_API_KEY=${userAnswers.llmToken}\\n`;\n }\n\n // CrewAI name\n if (userAnswers.crewName) {\n newEnvValues += `NEXT_PUBLIC_COPILOTKIT_AGENT_NAME=${userAnswers.crewName}\\n`;\n }\n\n if (userAnswers.langGraphAgent) {\n newEnvValues += `NEXT_PUBLIC_COPILOTKIT_AGENT_NAME=sample_agent\\n`;\n newEnvValues += `LANGGRAPH_DEPLOYMENT_URL=http://localhost:8123\\n`;\n } else if (userAnswers.langGraphPlatform === \"Yes\" && !isCloudDeployment) {\n newEnvValues += `LANGGRAPH_DEPLOYMENT_URL=${userAnswers.langGraphPlatformUrl}\\n`;\n } else if (userAnswers.langGraphRemoteEndpointURL) {\n newEnvValues += `COPILOTKIT_REMOTE_ENDPOINT=${userAnswers.langGraphRemoteEndpointURL}\\n`;\n }\n\n // Runtime URL if provided via flags\n if (flags.runtimeUrl) {\n newEnvValues += `NEXT_PUBLIC_COPILOTKIT_RUNTIME_URL=${flags.runtimeUrl}\\n`;\n } else if (\n !isCloudDeployment &&\n userAnswers.crewType !== \"Crews\" &&\n userAnswers.crewType !== \"Flows\"\n ) {\n newEnvValues += `NEXT_PUBLIC_COPILOTKIT_RUNTIME_URL=/api/copilotkit\\n`;\n }\n\n if (\n userAnswers.langGraphPlatformUrl &&\n (userAnswers.langSmithApiKey ||\n isLocalhost(userAnswers.langGraphPlatformUrl))\n ) {\n const langGraphAgents = await getLangGraphAgents(\n userAnswers.langGraphPlatformUrl,\n userAnswers.langSmithApiKey || \"\",\n );\n let langGraphAgent = \"\";\n if (langGraphAgents.length > 1) {\n const { langGraphAgentChoice } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"langGraphAgentChoice\",\n message: \"🦜🔗 Which agent from your graph would you like to use?\",\n choices: langGraphAgents.map((agent: any) => ({\n name: agent.graph_id,\n value: agent.graph_id,\n })),\n },\n ]);\n langGraphAgent = langGraphAgentChoice;\n } else if (langGraphAgents.length === 1) {\n langGraphAgent = langGraphAgents[0].graph_id;\n } else {\n throw new Error(\"No agents found in your LangGraph endpoint\");\n }\n\n newEnvValues += `NEXT_PUBLIC_COPILOTKIT_AGENT_NAME=${langGraphAgent}\\n`;\n }\n\n // Append the variables to the .env file\n if (newEnvValues) {\n fs.appendFileSync(envFile, newEnvValues);\n }\n } catch (error) {\n throw error;\n }\n}\n","export type LangGraphAgent = {\n assistant_id: string;\n graph_id: string;\n config: {\n tags: string[];\n recursion_limit: number;\n configurable: Record<string, any>;\n };\n created_at: string;\n updated_at: string;\n metadata: Record<string, any>;\n version: number;\n name: string;\n description: string;\n};\n\nexport async function getLangGraphAgents(url: string, langSmithApiKey: string) {\n try {\n const response = await fetch(\n `${url.trim().replace(/\\/$/, \"\")}/assistants/search`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Api-Key\": langSmithApiKey,\n },\n body: JSON.stringify({\n limit: 10,\n offset: 0,\n }),\n },\n );\n\n return (await response.json()) as LangGraphAgent[];\n } catch (error) {\n throw new Error(`Failed to get LangGraph agents: ${error}`);\n }\n}\n","export const isLocalhost = (url: string): boolean => {\n return (\n url.includes(\"localhost\") ||\n url.includes(\"127.0.0.1\") ||\n url.includes(\"0.0.0.0\")\n );\n};\n"],"mappings":"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","names":[]}
@@ -8,7 +8,14 @@ async function cloneGitHubSubdirectory(githubUrl, destinationPath, spinner) {
8
8
  try {
9
9
  const { owner, repo, branch, subdirectoryPath } = parseGitHubUrl(githubUrl);
10
10
  spinner.text = chalk.cyan(`Cloning from ${owner}/${repo}...`);
11
- return await sparseCheckout(owner, repo, branch, subdirectoryPath, destinationPath, spinner);
11
+ return await sparseCheckout(
12
+ owner,
13
+ repo,
14
+ branch,
15
+ subdirectoryPath,
16
+ destinationPath,
17
+ spinner
18
+ );
12
19
  } catch (error) {
13
20
  spinner.text = chalk.red(`Failed to clone from GitHub: ${error}`);
14
21
  return false;
@@ -20,14 +27,28 @@ async function sparseCheckout(owner, repo, branch, subdirectoryPath, destination
20
27
  spinner.text = chalk.cyan("Creating temporary workspace...");
21
28
  execSync("git init", { cwd: tempDir, stdio: "pipe" });
22
29
  spinner.text = chalk.cyan("Connecting to repository...");
23
- execSync(`git remote add origin https://github.com/${owner}/${repo}.git`, { cwd: tempDir, stdio: "pipe" });
24
- execSync("git config core.sparseCheckout true", { cwd: tempDir, stdio: "pipe" });
25
- fs.writeFileSync(path.join(tempDir, ".git/info/sparse-checkout"), subdirectoryPath);
30
+ execSync(`git remote add origin https://github.com/${owner}/${repo}.git`, {
31
+ cwd: tempDir,
32
+ stdio: "pipe"
33
+ });
34
+ execSync("git config core.sparseCheckout true", {
35
+ cwd: tempDir,
36
+ stdio: "pipe"
37
+ });
38
+ fs.writeFileSync(
39
+ path.join(tempDir, ".git/info/sparse-checkout"),
40
+ subdirectoryPath
41
+ );
26
42
  spinner.text = chalk.cyan("Downloading agent files...");
27
- execSync(`git pull origin ${branch} --depth=1`, { cwd: tempDir, stdio: "pipe" });
43
+ execSync(`git pull origin ${branch} --depth=1`, {
44
+ cwd: tempDir,
45
+ stdio: "pipe"
46
+ });
28
47
  const sourcePath = path.join(tempDir, subdirectoryPath);
29
48
  if (!fs.existsSync(sourcePath)) {
30
- throw new Error(`Subdirectory '${subdirectoryPath}' not found in the repository.`);
49
+ throw new Error(
50
+ `Subdirectory '${subdirectoryPath}' not found in the repository.`
51
+ );
31
52
  }
32
53
  fs.mkdirSync(destinationPath, { recursive: true });
33
54
  spinner.text = chalk.cyan("Installing agent files...");
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/init/scaffold/github.ts"],"sourcesContent":["import {execSync} from 'child_process'\nimport * as fs from 'fs'\nimport * as path from 'path'\nimport * as os from 'os'\nimport {Config} from '../types/index.js'\nimport chalk from 'chalk'\nimport ora, {Ora} from 'ora'\n\n/**\n * Clones a specific subdirectory from a GitHub repository\n *\n * @param githubUrl - The GitHub URL to the repository or subdirectory\n * @param destinationPath - The local path where the content should be copied\n * @param spinner - The spinner to update with progress information\n * @returns A boolean indicating success or failure\n */\nexport async function cloneGitHubSubdirectory(\n githubUrl: string,\n destinationPath: string,\n spinner: Ora,\n): Promise<boolean> {\n try {\n // Parse the GitHub URL to extract repo info\n const {owner, repo, branch, subdirectoryPath} = parseGitHubUrl(githubUrl)\n\n spinner.text = chalk.cyan(`Cloning from ${owner}/${repo}...`)\n\n // Method 1: Use sparse checkout (more efficient than full clone)\n return await sparseCheckout(owner, repo, branch, subdirectoryPath, destinationPath, spinner)\n } catch (error) {\n spinner.text = chalk.red(`Failed to clone from GitHub: ${error}`)\n return false\n }\n}\n\n/**\n * Uses Git sparse-checkout to efficiently download only the needed subdirectory\n */\nasync function sparseCheckout(\n owner: string,\n repo: string,\n branch: string,\n subdirectoryPath: string,\n destinationPath: string,\n spinner: Ora,\n): Promise<boolean> {\n const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'copilotkit-sparse-'))\n\n try {\n spinner.text = chalk.cyan('Creating temporary workspace...')\n\n // Initialize git repo\n execSync('git init', {cwd: tempDir, stdio: 'pipe'})\n\n spinner.text = chalk.cyan('Connecting to repository...')\n\n // Add remote\n execSync(`git remote add origin https://github.com/${owner}/${repo}.git`, {cwd: tempDir, stdio: 'pipe'})\n\n // Enable sparse checkout\n execSync('git config core.sparseCheckout true', {cwd: tempDir, stdio: 'pipe'})\n\n // Specify which subdirectory to checkout\n fs.writeFileSync(path.join(tempDir, '.git/info/sparse-checkout'), subdirectoryPath)\n\n spinner.text = chalk.cyan('Downloading agent files...')\n\n // Pull only the specified branch\n execSync(`git pull origin ${branch} --depth=1`, {cwd: tempDir, stdio: 'pipe'})\n\n // Copy the subdirectory to the destination\n const sourcePath = path.join(tempDir, subdirectoryPath)\n if (!fs.existsSync(sourcePath)) {\n throw new Error(`Subdirectory '${subdirectoryPath}' not found in the repository.`)\n }\n\n // Ensure destination directory exists\n fs.mkdirSync(destinationPath, {recursive: true})\n\n spinner.text = chalk.cyan('Installing agent files...')\n\n // Copy the subdirectory to the destination\n await copyDirectoryAsync(sourcePath, destinationPath)\n\n return true\n } finally {\n // Clean up the temporary directory\n try {\n fs.rmSync(tempDir, {recursive: true, force: true})\n } catch (error) {\n console.warn(`Failed to clean up temporary directory: ${error}`)\n }\n }\n}\n\n/**\n * Recursively copies a directory with async pauses\n */\nasync function copyDirectoryAsync(source: string, destination: string): Promise<void> {\n // Create destination directory if it doesn't exist\n if (!fs.existsSync(destination)) {\n fs.mkdirSync(destination, {recursive: true})\n }\n\n // Read all files/directories from source\n const entries = fs.readdirSync(source, {withFileTypes: true})\n\n for (const entry of entries) {\n const srcPath = path.join(source, entry.name)\n const destPath = path.join(destination, entry.name)\n\n if (entry.isDirectory()) {\n // Recursively copy subdirectories\n await copyDirectoryAsync(srcPath, destPath)\n } else {\n // Copy files\n fs.copyFileSync(srcPath, destPath)\n }\n\n // For large directories, add small pauses\n if (entries.length > 10) {\n await new Promise((resolve) => setTimeout(resolve, 1))\n }\n }\n}\n\n/**\n * Parses a GitHub URL to extract owner, repo, branch and subdirectory path\n */\nfunction parseGitHubUrl(githubUrl: string): {\n owner: string\n repo: string\n branch: string\n subdirectoryPath: string\n} {\n const url = new URL(githubUrl)\n\n if (url.hostname !== 'github.com') {\n throw new Error('Only GitHub URLs are supported')\n }\n\n const pathParts = url.pathname.split('/').filter(Boolean)\n\n if (pathParts.length < 2) {\n throw new Error('Invalid GitHub URL format')\n }\n\n const owner = pathParts[0]\n const repo = pathParts[1]\n let branch = 'main' // Default branch\n let subdirectoryPath = ''\n\n if (pathParts.length > 3 && (pathParts[2] === 'tree' || pathParts[2] === 'blob')) {\n branch = pathParts[3]\n subdirectoryPath = pathParts.slice(4).join('/')\n }\n\n return {owner, repo, branch, subdirectoryPath}\n}\n\n/**\n * Validates if a string is a valid GitHub URL\n */\nexport function isValidGitHubUrl(url: string): boolean {\n try {\n const parsedUrl = new URL(url)\n return parsedUrl.hostname === 'github.com' && parsedUrl.pathname.split('/').filter(Boolean).length >= 2\n } catch {\n return false\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/lib/init/scaffold/github.ts"],"sourcesContent":["import { execSync } from \"child_process\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as os from \"os\";\nimport { Config } from \"../types/index.js\";\nimport chalk from \"chalk\";\nimport ora, { Ora } from \"ora\";\n\n/**\n * Clones a specific subdirectory from a GitHub repository\n *\n * @param githubUrl - The GitHub URL to the repository or subdirectory\n * @param destinationPath - The local path where the content should be copied\n * @param spinner - The spinner to update with progress information\n * @returns A boolean indicating success or failure\n */\nexport async function cloneGitHubSubdirectory(\n githubUrl: string,\n destinationPath: string,\n spinner: Ora,\n): Promise<boolean> {\n try {\n // Parse the GitHub URL to extract repo info\n const { owner, repo, branch, subdirectoryPath } = parseGitHubUrl(githubUrl);\n\n spinner.text = chalk.cyan(`Cloning from ${owner}/${repo}...`);\n\n // Method 1: Use sparse checkout (more efficient than full clone)\n return await sparseCheckout(\n owner,\n repo,\n branch,\n subdirectoryPath,\n destinationPath,\n spinner,\n );\n } catch (error) {\n spinner.text = chalk.red(`Failed to clone from GitHub: ${error}`);\n return false;\n }\n}\n\n/**\n * Uses Git sparse-checkout to efficiently download only the needed subdirectory\n */\nasync function sparseCheckout(\n owner: string,\n repo: string,\n branch: string,\n subdirectoryPath: string,\n destinationPath: string,\n spinner: Ora,\n): Promise<boolean> {\n const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), \"copilotkit-sparse-\"));\n\n try {\n spinner.text = chalk.cyan(\"Creating temporary workspace...\");\n\n // Initialize git repo\n execSync(\"git init\", { cwd: tempDir, stdio: \"pipe\" });\n\n spinner.text = chalk.cyan(\"Connecting to repository...\");\n\n // Add remote\n execSync(`git remote add origin https://github.com/${owner}/${repo}.git`, {\n cwd: tempDir,\n stdio: \"pipe\",\n });\n\n // Enable sparse checkout\n execSync(\"git config core.sparseCheckout true\", {\n cwd: tempDir,\n stdio: \"pipe\",\n });\n\n // Specify which subdirectory to checkout\n fs.writeFileSync(\n path.join(tempDir, \".git/info/sparse-checkout\"),\n subdirectoryPath,\n );\n\n spinner.text = chalk.cyan(\"Downloading agent files...\");\n\n // Pull only the specified branch\n execSync(`git pull origin ${branch} --depth=1`, {\n cwd: tempDir,\n stdio: \"pipe\",\n });\n\n // Copy the subdirectory to the destination\n const sourcePath = path.join(tempDir, subdirectoryPath);\n if (!fs.existsSync(sourcePath)) {\n throw new Error(\n `Subdirectory '${subdirectoryPath}' not found in the repository.`,\n );\n }\n\n // Ensure destination directory exists\n fs.mkdirSync(destinationPath, { recursive: true });\n\n spinner.text = chalk.cyan(\"Installing agent files...\");\n\n // Copy the subdirectory to the destination\n await copyDirectoryAsync(sourcePath, destinationPath);\n\n return true;\n } finally {\n // Clean up the temporary directory\n try {\n fs.rmSync(tempDir, { recursive: true, force: true });\n } catch (error) {\n console.warn(`Failed to clean up temporary directory: ${error}`);\n }\n }\n}\n\n/**\n * Recursively copies a directory with async pauses\n */\nasync function copyDirectoryAsync(\n source: string,\n destination: string,\n): Promise<void> {\n // Create destination directory if it doesn't exist\n if (!fs.existsSync(destination)) {\n fs.mkdirSync(destination, { recursive: true });\n }\n\n // Read all files/directories from source\n const entries = fs.readdirSync(source, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = path.join(source, entry.name);\n const destPath = path.join(destination, entry.name);\n\n if (entry.isDirectory()) {\n // Recursively copy subdirectories\n await copyDirectoryAsync(srcPath, destPath);\n } else {\n // Copy files\n fs.copyFileSync(srcPath, destPath);\n }\n\n // For large directories, add small pauses\n if (entries.length > 10) {\n await new Promise((resolve) => setTimeout(resolve, 1));\n }\n }\n}\n\n/**\n * Parses a GitHub URL to extract owner, repo, branch and subdirectory path\n */\nfunction parseGitHubUrl(githubUrl: string): {\n owner: string;\n repo: string;\n branch: string;\n subdirectoryPath: string;\n} {\n const url = new URL(githubUrl);\n\n if (url.hostname !== \"github.com\") {\n throw new Error(\"Only GitHub URLs are supported\");\n }\n\n const pathParts = url.pathname.split(\"/\").filter(Boolean);\n\n if (pathParts.length < 2) {\n throw new Error(\"Invalid GitHub URL format\");\n }\n\n const owner = pathParts[0];\n const repo = pathParts[1];\n let branch = \"main\"; // Default branch\n let subdirectoryPath = \"\";\n\n if (\n pathParts.length > 3 &&\n (pathParts[2] === \"tree\" || pathParts[2] === \"blob\")\n ) {\n branch = pathParts[3];\n subdirectoryPath = pathParts.slice(4).join(\"/\");\n }\n\n return { owner, repo, branch, subdirectoryPath };\n}\n\n/**\n * Validates if a string is a valid GitHub URL\n */\nexport function isValidGitHubUrl(url: string): boolean {\n try {\n const parsedUrl = new URL(url);\n return (\n parsedUrl.hostname === \"github.com\" &&\n parsedUrl.pathname.split(\"/\").filter(Boolean).length >= 2\n );\n } catch {\n return false;\n }\n}\n"],"mappings":"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","names":[]}