copilotkit 0.0.25 → 0.0.27

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 (47) hide show
  1. package/dist/commands/base-command.js +1 -1
  2. package/dist/commands/base-command.js.map +1 -1
  3. package/dist/commands/dev.js +1 -1
  4. package/dist/commands/dev.js.map +1 -1
  5. package/dist/commands/init.js +329 -102
  6. package/dist/commands/init.js.map +1 -1
  7. package/dist/commands/login.js +1 -1
  8. package/dist/commands/login.js.map +1 -1
  9. package/dist/commands/logout.js +1 -1
  10. package/dist/commands/logout.js.map +1 -1
  11. package/dist/lib/init/index.d.ts +4 -3
  12. package/dist/lib/init/index.js +243 -59
  13. package/dist/lib/init/index.js.map +1 -1
  14. package/dist/lib/init/questions.d.ts +1 -0
  15. package/dist/lib/init/questions.js +198 -35
  16. package/dist/lib/init/questions.js.map +1 -1
  17. package/dist/lib/init/scaffold/agent.d.ts +1 -0
  18. package/dist/lib/init/scaffold/agent.js +1 -1
  19. package/dist/lib/init/scaffold/agent.js.map +1 -1
  20. package/dist/lib/init/scaffold/crew-inputs.js +1 -1
  21. package/dist/lib/init/scaffold/crew-inputs.js.map +1 -1
  22. package/dist/lib/init/scaffold/env.d.ts +1 -0
  23. package/dist/lib/init/scaffold/env.js +5 -2
  24. package/dist/lib/init/scaffold/env.js.map +1 -1
  25. package/dist/lib/init/scaffold/index.d.ts +1 -0
  26. package/dist/lib/init/scaffold/index.js +133 -32
  27. package/dist/lib/init/scaffold/index.js.map +1 -1
  28. package/dist/lib/init/scaffold/langgraph-assistants.js +1 -1
  29. package/dist/lib/init/scaffold/langgraph-assistants.js.map +1 -1
  30. package/dist/lib/init/scaffold/packages.d.ts +1 -0
  31. package/dist/lib/init/scaffold/shadcn.d.ts +1 -0
  32. package/dist/lib/init/scaffold/shadcn.js +126 -28
  33. package/dist/lib/init/scaffold/shadcn.js.map +1 -1
  34. package/dist/lib/init/types/index.d.ts +2 -1
  35. package/dist/lib/init/types/index.js +114 -8
  36. package/dist/lib/init/types/index.js.map +1 -1
  37. package/dist/lib/init/types/questions.d.ts +164 -36
  38. package/dist/lib/init/types/questions.js +112 -6
  39. package/dist/lib/init/types/questions.js.map +1 -1
  40. package/dist/lib/init/types/templates.d.ts +1 -1
  41. package/dist/lib/init/types/templates.js +3 -3
  42. package/dist/lib/init/types/templates.js.map +1 -1
  43. package/dist/utils/version.d.ts +1 -1
  44. package/dist/utils/version.js +1 -1
  45. package/dist/utils/version.js.map +1 -1
  46. package/oclif.manifest.json +4 -7
  47. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/init/types/questions.ts","../../../src/lib/init/types/templates.ts","../../../src/lib/init/questions.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\"\n\nexport type Question = {\n type: 'input' | 'yes/no' | 'select'\n name: Fields\n message: string\n choices?: string[]\n default?: string\n when?: (answers: Record<string, any>) => boolean\n sensitive?: boolean\n}\n\n// Agent framework options\nexport const AGENT_FRAMEWORKS = ['CrewAI', 'LangGraph', 'None'] as const;\nexport type AgentFramework = typeof AGENT_FRAMEWORKS[number];\n\n// CrewAI types\nexport const CREW_TYPES = ['Crews', 'Flows'] as const;\nexport type CrewType = typeof CREW_TYPES[number];\n\n// UI component options\nexport const CHAT_COMPONENTS = ['CopilotChat','CopilotSidebar', 'Headless', 'CopilotPopup'] as const;\nexport type ChatComponent = typeof CHAT_COMPONENTS[number];\n\n// LangGraph agent types\nexport const LANGGRAPH_AGENTS = ['Python Starter', 'TypeScript Starter', 'None'] as const;\nexport type LangGraphAgent = typeof LANGGRAPH_AGENTS[number];\n\n// CrewAI Flow templates\nexport const CREW_FLOW_TEMPLATES = ['Starter', 'None'] as const;\nexport type CrewFlowTemplate = typeof CREW_FLOW_TEMPLATES[number];\n\n// Yes/No type for consistent options\nexport type YesNo = 'Yes' | 'No';\n\n// All possible field names for questions\nexport type Fields = \n \"copilotKitVersion\" | \n \"agentFramework\" | \n \"alreadyDeployed\" |\n \"fastApiEnabled\" | \n \"useCopilotCloud\" | \n \"chatUi\" | \n \"langGraphAgent\" | \n \"langGraphPlatform\" |\n \"langGraphPlatformUrl\" | \n \"crewType\" | \n \"crewName\" | \n \"langGraphRemoteEndpointURL\" |\n \"crewUrl\" | \n \"crewBearerToken\" | \n \"langSmithApiKey\" | \n \"llmToken\" |\n \"crewFlowAgent\";\n\n// Complete configuration shape that holds all possible answers\nexport interface Config {\n copilotKitVersion: string;\n agentFramework: AgentFramework;\n alreadyDeployed?: YesNo;\n fastApiEnabled?: YesNo;\n useCopilotCloud?: YesNo;\n chatUi: ChatComponent;\n\n // LangGraph\n langGraphAgent?: LangGraphAgent;\n langGraphPlatform?: YesNo;\n langGraphPlatformUrl?: string;\n langGraphRemoteEndpointURL?: string;\n\n // CrewAI\n crewType?: CrewType;\n crewName?: string;\n crewUrl?: string;\n crewBearerToken?: string;\n crewFlowAgent?: string;\n\n // API keys and tokens\n copilotCloudPublicApiKey?: string;\n langSmithApiKey?: string;\n llmToken?: string;\n}\n\n// CLI flags definition - single source of truth for flag descriptions\nexport const ConfigFlags = {\n copilotKitVersion: Flags.string({description: 'CopilotKit version to use (e.g. 1.7.0)'}),\n agentFramework: Flags.string({description: 'Agent framework to power your copilot', options: AGENT_FRAMEWORKS}),\n fastApiEnabled: Flags.string({description: 'Use FastAPI to serve your agent locally', options: ['Yes', 'No']}),\n useCopilotCloud: Flags.string({description: 'Use Copilot Cloud for production-ready hosting', options: ['Yes', 'No']}),\n chatUi: Flags.string({description: 'Chat UI component to add to your app', options: CHAT_COMPONENTS}),\n langGraphAgent: Flags.string({description: 'LangGraph agent template to use', options: LANGGRAPH_AGENTS}),\n crewType: Flags.string({description: 'CrewAI implementation type', options: CREW_TYPES}),\n crewName: Flags.string({description: 'Name for your CrewAI agent'}),\n crewUrl: Flags.string({description: 'URL endpoint for your CrewAI agent'}),\n crewBearerToken: Flags.string({description: 'Bearer token for CrewAI authentication'}),\n langSmithApiKey: Flags.string({description: 'LangSmith API key for LangGraph observability'}),\n llmToken: Flags.string({description: 'API key for your preferred LLM provider'}),\n crewFlowAgent: Flags.string({description: 'CrewAI Flow template to use', options: CREW_FLOW_TEMPLATES}),\n}","export type ChatTemplate = \n \"CopilotChat\" |\n \"CopilotPopup\" |\n \"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 \"LangGraphPlatform\": `${BASE_URL}/langgraph-platform-starter.json`,\n \"RemoteEndpoint\": `${BASE_URL}/remote-endpoint-starter.json`,\n \"CrewEnterprise\": [\n `${BASE_URL}/coagents-crew-starter.json`,\n ],\n\n \"LangGraphGeneric\": `${BASE_URL}/generic-lg-starter.json`,\n\n \"CrewFlowsStarter\": [\n `${BASE_URL}/coagents-starter-ui.json`,\n `${BASE_URL}/agent-layout.json`,\n `${BASE_URL}/remote-endpoint.json`\n ],\n\n \"LangGraphStarter\": [\n `${BASE_URL}/langgraph-platform-starter.json`,\n `${BASE_URL}/coagents-starter-ui.json`,\n ],\n\n \"Standard\": `${BASE_URL}/standard-starter.json`,\n \"CopilotChat\": `${BASE_URL}/chat.json`,\n \"CopilotPopup\": `${BASE_URL}/popup.json`,\n \"CopilotSidebar\": `${BASE_URL}/sidebar.json`,\n}","import { \n Question, \n CHAT_COMPONENTS,\n AGENT_FRAMEWORKS,\n CREW_TYPES,\n LANGGRAPH_AGENTS,\n CREW_FLOW_TEMPLATES,\n} from './types/index.js';\n\n// Single source of truth for all questions in the CLI\n// Organized in a logical flow with improved phrasing\nexport const questions: Question[] = [\n // Core setup questions - always shown first\n {\n type: 'select',\n name: 'agentFramework',\n message: '🤖 Choose your AI framework:',\n choices: Array.from(AGENT_FRAMEWORKS),\n },\n \n // CrewAI specific questions - shown when CrewAI selected\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.agentFramework === 'CrewAI',\n },\n\n // CrewAI Crews specific questions - shown when CrewAI Crews selected\n {\n type: 'input',\n name: 'crewName',\n message: '👥 What would you like to name your crew? (can be anything)',\n when: (answers) => answers.agentFramework === 'CrewAI' && answers.crewType === 'Crews',\n default: 'MyCopilotCrew',\n },\n {\n type: 'input',\n name: 'crewUrl',\n message: '🔗 Enter your Crew\\'s URL:',\n when: (answers) => answers.agentFramework === 'CrewAI' && answers.crewType === 'Crews',\n },\n {\n type: 'input',\n name: 'crewBearerToken',\n message: '🔑 Enter your Crew\\'s bearer token:',\n when: (answers) => answers.agentFramework === 'CrewAI' && answers.crewType === 'Crews',\n sensitive: true,\n },\n\n // CrewAI Flows specific questions - shown when CrewAI Flows selected\n {\n type: 'select',\n name: 'crewFlowAgent',\n message: '📦 Choose a CrewAI Flow Template',\n choices: Array.from(CREW_FLOW_TEMPLATES),\n when: (answers) => answers.agentFramework === 'CrewAI' && answers.crewType === 'Flows',\n },\n \n // LangGraph specific questions - shown when LangGraph selected\n {\n type: 'yes/no',\n name: 'alreadyDeployed',\n message: '🚀 Is your LangGraph agent already deployed?',\n when: (answers) => answers.agentFramework === 'LangGraph',\n },\n {\n type: 'yes/no',\n name: 'langGraphPlatform',\n message: '🦜🔗 Is it hosted with LangGraph Platform (local or cloud)?',\n when: (answers) => \n answers.agentFramework === 'LangGraph' && \n answers.alreadyDeployed === 'Yes',\n },\n {\n type: 'input',\n name: 'langGraphPlatformUrl',\n message: '🦜🔗 Enter your LangGraph platform URL:',\n when: (answers) => \n answers.agentFramework === 'LangGraph' && \n answers.alreadyDeployed === 'Yes' &&\n answers.langGraphPlatform === 'Yes',\n },\n {\n type: 'input',\n name: 'langGraphRemoteEndpointURL',\n message: '🔌 Enter your LangGraph endpoint URL:',\n when: (answers) => \n answers.agentFramework === 'LangGraph' && \n answers.alreadyDeployed === 'Yes' &&\n answers.langGraphPlatform === 'No',\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.agentFramework === 'LangGraph' && \n 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.agentFramework === 'LangGraph' && \n answers.langGraphPlatform === 'Yes',\n sensitive: true,\n },\n \n // Deployment options\n {\n type: 'yes/no',\n name: 'useCopilotCloud',\n message: '🪁 Deploy with Copilot Cloud? (recommended for production)',\n when: (answers) => \n !(answers.agentFramework === 'CrewAI' && answers.crewType === 'Crews') &&\n answers.crewType !== 'Flows' &&\n answers.alreadyDeployed === 'Yes',\n },\n // {\n // type: 'yes/no',\n // name: 'fastApiEnabled',\n // message: '⚡ Set up a FastAPI server for local development?',\n // when: (answers) => \n // answers.agentFramework === 'LangGraph' && \n // answers.alreadyDeployed === 'No' && \n // answers.langGraphAgent === 'Python Starter' &&\n // answers.useCopilotCloud !== 'Yes',\n // },\n \n // UI components - always shown last\n {\n type: 'select',\n name: 'chatUi',\n message: '💬 Select a UI component for your copilot:',\n choices: Array.from(CHAT_COMPONENTS),\n default: 'CopilotChat',\n when: (answers) => answers.agentFramework === 'None',\n },\n {\n type: 'input',\n name: 'llmToken',\n message: '🔑 Enter your OpenAI API key (required for agent functionality):',\n when: (answers) =>\n (answers.agentFramework === 'LangGraph' && answers.alreadyDeployed === 'No') ||\n (answers.agentFramework === 'CrewAI' && answers.crewType === 'Flows'),\n sensitive: true,\n },\n];\n\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/init/types/questions.ts","../../../src/lib/init/types/templates.ts","../../../src/lib/init/questions.ts"],"sourcesContent":["import { z } from 'zod';\nimport { Flags } from \"@oclif/core\"\n\n// ===== Core Constants =====\nexport const AGENT_FRAMEWORKS = ['CrewAI', 'LangGraph'] 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\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 AgentFrameworkSchema = z.enum(AGENT_FRAMEWORKS);\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\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\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.object({\n // Core fields\n copilotKitVersion: z.string().optional(),\n agentFramework: AgentFrameworkSchema,\n chatUi: ChatComponentSchema.optional(),\n \n // Yes/No fields\n alreadyDeployed: YesNoSchema.optional(),\n fastApiEnabled: YesNoSchema.optional(),\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 crewFlowAgent: CrewFlowTemplateSchema.optional(),\n \n // API keys and tokens\n copilotCloudPublicApiKey: z.string().optional(),\n langSmithApiKey: ApiKeySchema.optional(),\n llmToken: ApiKeySchema.optional(),\n})\n.refine(\n (data) => {\n // If CrewAI is selected with Crews type, require crew URL and bearer token\n if (data.agentFramework === 'CrewAI' && data.crewType === 'Crews') {\n return !!data.crewUrl && !!data.crewBearerToken;\n }\n return true;\n },\n {\n message: \"Crew URL and bearer token are required for CrewAI Crews\",\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.agentFramework === 'LangGraph' && \n data.alreadyDeployed === 'Yes' && \n data.langGraphPlatform === 'Yes'\n ) {\n return !!data.langGraphPlatformUrl && !!data.langSmithApiKey;\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[];\n default?: string;\n when?: (answers: Partial<Config>) => 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 copilotKitVersion: Flags.string({description: 'CopilotKit version to use (e.g. 1.7.0)'}),\n agentFramework: Flags.string({description: 'Agent framework to power your copilot', options: AGENT_FRAMEWORKS}),\n fastApiEnabled: Flags.string({description: 'Use FastAPI to serve your agent locally', options: YES_NO}),\n useCopilotCloud: Flags.string({description: 'Use Copilot Cloud for production-ready hosting', options: YES_NO}),\n chatUi: Flags.string({description: 'Chat UI component to add to your app', options: CHAT_COMPONENTS}),\n langGraphAgent: Flags.string({description: 'LangGraph agent template to use', options: LANGGRAPH_AGENTS}),\n crewType: Flags.string({description: 'CrewAI implementation type', options: CREW_TYPES}),\n crewName: Flags.string({description: 'Name for your CrewAI agent'}),\n crewUrl: Flags.string({description: 'URL endpoint for your CrewAI agent'}),\n crewBearerToken: Flags.string({description: 'Bearer token for CrewAI authentication'}),\n langSmithApiKey: Flags.string({description: 'LangSmith API key for LangGraph observability'}),\n llmToken: Flags.string({description: 'API key for your preferred LLM provider'}),\n crewFlowAgent: Flags.string({description: 'CrewAI Flow template to use', options: CREW_FLOW_TEMPLATES}),\n}","export type ChatTemplate = \n \"CopilotChat\" |\n \"CopilotPopup\" |\n \"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 = \"http://localhost:3002/r\"\n\nexport const templateMapping = {\n \"LangGraphPlatformRuntime\": `${BASE_URL}/langgraph-platform-starter.json`,\n \"RemoteEndpoint\": `${BASE_URL}/remote-endpoint-starter.json`,\n \"CrewEnterprise\": [\n `${BASE_URL}/coagents-crew-starter.json`,\n ],\n\n \"LangGraphGeneric\": `${BASE_URL}/generic-lg-starter-with-cloud.json`,\n\n \"CrewFlowsStarter\": [\n `${BASE_URL}/coagents-starter-ui.json`,\n `${BASE_URL}/agent-layout.json`,\n `${BASE_URL}/remote-endpoint.json`\n ],\n\n \"LangGraphStarter\": [\n `${BASE_URL}/langgraph-platform-starter.json`,\n `${BASE_URL}/coagents-starter-ui.json`,\n ],\n\n \"Standard\": `${BASE_URL}/standard-starter.json`,\n \"CopilotChat\": `${BASE_URL}/chat.json`,\n \"CopilotPopup\": `${BASE_URL}/popup.json`,\n \"CopilotSidebar\": `${BASE_URL}/sidebar.json`,\n}","import { \n Question, \n CHAT_COMPONENTS,\n AGENT_FRAMEWORKS,\n CREW_TYPES,\n LANGGRAPH_AGENTS,\n CREW_FLOW_TEMPLATES,\n AgentFrameworkSchema,\n CrewTypeSchema,\n UrlSchema,\n YesNoSchema,\n sanitizers,\n} from './types/index.js';\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// Single source of truth for all questions in the CLI\n// Organized in a logical flow with improved phrasing\nexport const questions: Question[] = [\n // Core setup questions - always shown first\n {\n type: 'select',\n name: 'agentFramework',\n message: '🤖 Choose your AI framework:',\n choices: Array.from(AGENT_FRAMEWORKS),\n validate: (input) => {\n try {\n AgentFrameworkSchema.parse(input);\n return true;\n } catch (error) {\n return 'Please select a valid framework';\n }\n }\n },\n \n // CrewAI specific questions - shown when CrewAI selected\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.agentFramework === '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 // CrewAI Crews specific questions - shown when CrewAI Crews selected\n {\n type: 'input',\n name: 'crewName',\n message: '👥 What would you like to name your crew? (can be anything)',\n when: (answers) => answers.agentFramework === 'CrewAI' && answers.crewType === 'Crews',\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.agentFramework === 'CrewAI' && answers.crewType === 'Crews',\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.agentFramework === 'CrewAI' && answers.crewType === 'Crews',\n sensitive: true,\n validate: validateRequired,\n sanitize: sanitizers.trim\n },\n\n // CrewAI Flows specific questions - shown when CrewAI Flows selected\n {\n type: 'select',\n name: 'crewFlowAgent',\n message: '📦 Choose a CrewAI Flow Template',\n choices: Array.from(CREW_FLOW_TEMPLATES),\n when: (answers) => answers.agentFramework === 'CrewAI' && answers.crewType === 'Flows',\n },\n \n // LangGraph specific questions - shown when LangGraph selected\n {\n type: 'yes/no',\n name: 'alreadyDeployed',\n message: '🚀 Is your LangGraph agent already deployed?',\n when: (answers) => answers.agentFramework === '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: '🦜🔗 Is it hosted with LangGraph Platform (either self-hosted or in LangSmith)?',\n when: (answers) => \n answers.agentFramework === 'LangGraph' && \n 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 platform URL:',\n when: (answers) => \n answers.agentFramework === 'LangGraph' && \n answers.alreadyDeployed === 'Yes' &&\n answers.langGraphPlatform === 'Yes',\n validate: validateUrl,\n sanitize: sanitizers.url\n },\n // {\n // type: 'input',\n // name: 'langGraphRemoteEndpointURL',\n // message: '🔌 Enter your LangGraph endpoint URL:',\n // when: (answers) => \n // answers.agentFramework === 'LangGraph' && \n // answers.alreadyDeployed === 'Yes' &&\n // answers.langGraphPlatform === 'No',\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.agentFramework === 'LangGraph' && \n 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.agentFramework === 'LangGraph' && \n answers.langGraphPlatform === 'Yes',\n sensitive: true,\n validate: validateRequired,\n sanitize: sanitizers.apiKey\n },\n \n // Deployment options\n {\n type: 'yes/no',\n name: 'useCopilotCloud',\n message: '🪁 Deploy with Copilot Cloud? (recommended for production)',\n when: (answers) => \n !(answers.agentFramework === 'CrewAI' && answers.crewType === 'Crews') &&\n answers.crewType !== 'Flows' &&\n answers.alreadyDeployed === 'Yes' &&\n answers.langGraphPlatform !== 'No',\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: 'fastApiEnabled',\n // message: '⚡ Set up a FastAPI server for local development?',\n // when: (answers) => \n // answers.agentFramework === 'LangGraph' && \n // answers.alreadyDeployed === 'No' && \n // answers.langGraphAgent === 'Python Starter' &&\n // answers.useCopilotCloud !== 'Yes',\n // },\n \n // UI components - always shown last\n // {\n // type: 'select',\n // name: 'chatUi',\n // message: '💬 Select a UI component for your copilot:',\n // choices: Array.from(CHAT_COMPONENTS),\n // default: 'CopilotChat',\n // when: (answers) => answers.agentFramework === 'None',\n // },\n {\n type: 'input',\n name: 'llmToken',\n message: '🔑 Enter your OpenAI API key (required for agent functionality):',\n when: (answers) =>\n (answers.agentFramework === 'LangGraph' && answers.alreadyDeployed === 'No') ||\n (answers.agentFramework === 'CrewAI' && answers.crewType === 'Flows'),\n sensitive: true,\n validate: validateRequired,\n sanitize: sanitizers.apiKey\n },\n];\n\n"],"mappings":"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","names":[]}
@@ -1,5 +1,6 @@
1
1
  import { Config } from '../types/questions.js';
2
2
  import '@oclif/core/interfaces';
3
+ import 'zod';
3
4
 
4
5
  declare function scaffoldAgent(userAnswers: Config): Promise<void>;
5
6
  declare const AgentTemplates: {
@@ -87,7 +87,7 @@ function parseGitHubUrl(githubUrl) {
87
87
  import path2 from "path";
88
88
  import fs2 from "fs";
89
89
  async function scaffoldAgent(userAnswers) {
90
- if (userAnswers.agentFramework === "None" || userAnswers.agentFramework === "CrewAI" && userAnswers.crewType === "Crews" || userAnswers.agentFramework === "LangGraph" && (!userAnswers.langGraphAgent || userAnswers.langGraphAgent === "None")) {
90
+ if (userAnswers.agentFramework === "CrewAI" && userAnswers.crewType === "Crews" || userAnswers.agentFramework === "LangGraph" && !userAnswers.langGraphAgent) {
91
91
  return;
92
92
  }
93
93
  const spinner = ora({
@@ -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 // Skip if no agent framework or using CrewAI Crews (which are handled by cloud)\n if (userAnswers.agentFramework === 'None' || \n (userAnswers.agentFramework === 'CrewAI' && userAnswers.crewType === 'Crews') ||\n (userAnswers.agentFramework === 'LangGraph' && (!userAnswers.langGraphAgent || userAnswers.langGraphAgent === 'None'))) {\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.agentFramework) {\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 case 'CrewAI':\n if (userAnswers.crewFlowAgent === 'Starter') {\n template = AgentTemplates.CrewAI.Flows.Starter;\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(\n template, \n agentDir,\n spinner\n );\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.agentFramework === '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 } catch (error) {\n spinner.fail(chalk.red('Failed to clone agent template'));\n throw error;\n }\n\n spinner.succeed(`${userAnswers.agentFramework} 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}","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' && \n 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.agentFramework === 'CrewAI' && userAnswers.crewType === 'Crews') ||\n (userAnswers.agentFramework === 'LangGraph' && !userAnswers.langGraphAgent)\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.agentFramework) {\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 case 'CrewAI':\n if (userAnswers.crewFlowAgent === 'Starter') {\n template = AgentTemplates.CrewAI.Flows.Starter;\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(\n template, \n agentDir,\n spinner\n );\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.agentFramework === '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 } catch (error) {\n spinner.fail(chalk.red('Failed to clone agent template'));\n throw error;\n }\n\n spinner.succeed(`${userAnswers.agentFramework} 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}","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' && \n 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"]}
@@ -29,7 +29,7 @@ async function addCrewInputs(url, token) {
29
29
  }
30
30
  }
31
31
  async function getCrewInputs(url, token) {
32
- const response = await fetch(`${url}/inputs`, {
32
+ const response = await fetch(`${url.trim()}/inputs`, {
33
33
  headers: {
34
34
  Authorization: `Bearer ${token}`
35
35
  }
@@ -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\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}/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\n"],"mappings":";AAAA,YAAY,QAAQ;AACpB,OAAO,SAAS;AAChB,YAAY,UAAU;AAGtB,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,GAAG,WAAW;AAAA,IAC5C,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,OAAO,MAAM,SAAS,KAAK;AACjC,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\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\n"],"mappings":";AAAA,YAAY,QAAQ;AACpB,OAAO,SAAS;AAChB,YAAY,UAAU;AAGtB,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,OAAO,MAAM,SAAS,KAAK;AACjC,SAAO,KAAK;AACd;","names":[]}
@@ -1,5 +1,6 @@
1
1
  import { Config } from '../types/questions.js';
2
2
  import '@oclif/core/interfaces';
3
+ import 'zod';
3
4
 
4
5
  declare function scaffoldEnv(flags: any, userAnswers: Config): Promise<void>;
5
6
 
@@ -6,7 +6,7 @@ import fs from "fs";
6
6
  async function getLangGraphAgents(url, langSmithApiKey) {
7
7
  try {
8
8
  const response = await fetch(
9
- `${url}/assistants/search`,
9
+ `${url.trim().replace(/\/$/, "")}/assistants/search`,
10
10
  {
11
11
  method: "POST",
12
12
  headers: {
@@ -51,13 +51,16 @@ async function scaffoldEnv(flags, userAnswers) {
51
51
  newEnvValues += `NEXT_PUBLIC_COPILOTKIT_AGENT_NAME=${userAnswers.crewName}
52
52
  `;
53
53
  }
54
- if (userAnswers.langGraphAgent !== "None" && userAnswers.langGraphPlatform !== "Yes") {
54
+ if (userAnswers.langGraphAgent) {
55
55
  newEnvValues += `NEXT_PUBLIC_COPILOTKIT_AGENT_NAME=sample_agent
56
56
  `;
57
57
  newEnvValues += `LANGGRAPH_DEPLOYMENT_URL=http://localhost:8123
58
58
  `;
59
59
  } else if (userAnswers.langGraphPlatform === "Yes" && userAnswers.useCopilotCloud === "No") {
60
60
  newEnvValues += `LANGGRAPH_DEPLOYMENT_URL=${userAnswers.langGraphPlatformUrl}
61
+ `;
62
+ } else if (userAnswers.langGraphRemoteEndpointURL) {
63
+ newEnvValues += `COPILOTKIT_REMOTE_ENDPOINT=${userAnswers.langGraphRemoteEndpointURL}
61
64
  `;
62
65
  }
63
66
  if (flags.runtimeUrl) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/init/scaffold/env.ts","../../../../src/lib/init/scaffold/langgraph-assistants.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\"\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 // 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 !== 'None' && userAnswers.langGraphPlatform !== 'Yes') {\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' && userAnswers.useCopilotCloud === 'No') {\n newEnvValues += `LANGGRAPH_DEPLOYMENT_URL=${userAnswers.langGraphPlatformUrl}\\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 (userAnswers.useCopilotCloud !== 'Yes' && userAnswers.crewType !== 'Crews') {\n newEnvValues += `NEXT_PUBLIC_COPILOTKIT_RUNTIME_URL=/api/copilotkit\\n`\n }\n\n if (userAnswers.crewFlowAgent === 'Starter') {\n newEnvValues += `NEXT_PUBLIC_COPILOTKIT_AGENT_NAME=sample_agent\\n`\n }\n\n if (userAnswers.langGraphPlatformUrl && userAnswers.langSmithApiKey) {\n const langGraphAgents = await getLangGraphAgents(userAnswers.langGraphPlatformUrl, userAnswers.langSmithApiKey);\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}/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 return await response.json() as LangGraphAgent[];\n } catch (error) {\n throw new Error(`Failed to get LangGraph agents: ${error}`);\n }\n}"],"mappings":";AAAA,OAAO,UAAU;AACjB,OAAO,QAAQ;;;ACef,eAAsB,mBAAmB,KAAa,iBAAyB;AAC7E,MAAI;AACF,UAAM,WAAW,MAAM;AAAA,MAAM,GAAG,GAAG;AAAA,MACjC;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACT,gBAAgB;AAAA,UAChB,aAAa;AAAA,QACf;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,OAAO;AAAA,UACP,QAAQ;AAAA,QACV,CAAC;AAAA,MACH;AAAA,IAAC;AAED,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B,SAAS,OAAO;AACd,UAAM,IAAI,MAAM,mCAAmC,KAAK,EAAE;AAAA,EAC5D;AACF;;;AD/BA,OAAO,cAAc;AAErB,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,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,mBAAmB,UAAU,YAAY,sBAAsB,OAAO;AACpF,sBAAgB;AAAA;AAChB,sBAAgB;AAAA;AAAA,IAClB,WAAW,YAAY,sBAAsB,SAAS,YAAY,oBAAoB,MAAM;AAC1F,sBAAgB,4BAA4B,YAAY,oBAAoB;AAAA;AAAA,IAC9E;AAGA,QAAI,MAAM,YAAY;AACpB,sBAAgB,sCAAsC,MAAM,UAAU;AAAA;AAAA,IACxE,WAAW,YAAY,oBAAoB,SAAS,YAAY,aAAa,SAAS;AACpF,sBAAgB;AAAA;AAAA,IAClB;AAEA,QAAI,YAAY,kBAAkB,WAAW;AAC3C,sBAAgB;AAAA;AAAA,IAClB;AAEA,QAAI,YAAY,wBAAwB,YAAY,iBAAiB;AACnE,YAAM,kBAAkB,MAAM,mBAAmB,YAAY,sBAAsB,YAAY,eAAe;AAC9G,UAAI,iBAAiB;AACrB,UAAI,gBAAgB,SAAS,GAAG;AAC9B,cAAM,EAAE,qBAAqB,IAAI,MAAM,SAAS,OAAO;AAAA,UACrD;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"],"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\"\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 // 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' && userAnswers.useCopilotCloud === 'No') {\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 (userAnswers.useCopilotCloud !== 'Yes' && userAnswers.crewType !== 'Crews') {\n newEnvValues += `NEXT_PUBLIC_COPILOTKIT_RUNTIME_URL=/api/copilotkit\\n`\n }\n\n if (userAnswers.crewFlowAgent === 'Starter') {\n newEnvValues += `NEXT_PUBLIC_COPILOTKIT_AGENT_NAME=sample_agent\\n`\n }\n\n if (userAnswers.langGraphPlatformUrl && userAnswers.langSmithApiKey) {\n const langGraphAgents = await getLangGraphAgents(userAnswers.langGraphPlatformUrl, userAnswers.langSmithApiKey);\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 {\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}"],"mappings":";AAAA,OAAO,UAAU;AACjB,OAAO,QAAQ;;;ACef,eAAsB,mBAAmB,KAAa,iBAAyB;AAC7E,MAAI;AACF,UAAM,WAAW,MAAM;AAAA,MAAM,GAAG,IAAI,KAAK,EAAE,QAAQ,OAAO,EAAE,CAAC;AAAA,MAC3D;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACT,gBAAgB;AAAA,UAChB,aAAa;AAAA,QACf;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,OAAO;AAAA,UACP,QAAQ;AAAA,QACV,CAAC;AAAA,MACH;AAAA,IAAC;AAED,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B,SAAS,OAAO;AACd,UAAM,IAAI,MAAM,mCAAmC,KAAK,EAAE;AAAA,EAC5D;AACF;;;AD/BA,OAAO,cAAc;AAErB,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,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,YAAY,oBAAoB,MAAM;AAC1F,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,YAAY,oBAAoB,SAAS,YAAY,aAAa,SAAS;AACpF,sBAAgB;AAAA;AAAA,IAClB;AAEA,QAAI,YAAY,kBAAkB,WAAW;AAC3C,sBAAgB;AAAA;AAAA,IAClB;AAEA,QAAI,YAAY,wBAAwB,YAAY,iBAAiB;AACnE,YAAM,kBAAkB,MAAM,mBAAmB,YAAY,sBAAsB,YAAY,eAAe;AAC9G,UAAI,iBAAiB;AACrB,UAAI,gBAAgB,SAAS,GAAG;AAC9B,cAAM,EAAE,qBAAqB,IAAI,MAAM,SAAS,OAAO;AAAA,UACrD;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":[]}
@@ -6,4 +6,5 @@ export { AgentTemplates, scaffoldAgent } from './agent.js';
6
6
  export { addCrewInputs } from './crew-inputs.js';
7
7
  import '../types/questions.js';
8
8
  import '@oclif/core/interfaces';
9
+ import 'zod';
9
10
  import 'ora';
@@ -2,17 +2,110 @@
2
2
  import spawn from "cross-spawn";
3
3
 
4
4
  // src/lib/init/types/questions.ts
5
+ import { z } from "zod";
5
6
  import { Flags } from "@oclif/core";
6
- var AGENT_FRAMEWORKS = ["CrewAI", "LangGraph", "None"];
7
+ var AGENT_FRAMEWORKS = ["CrewAI", "LangGraph"];
7
8
  var CREW_TYPES = ["Crews", "Flows"];
8
9
  var CHAT_COMPONENTS = ["CopilotChat", "CopilotSidebar", "Headless", "CopilotPopup"];
9
- var LANGGRAPH_AGENTS = ["Python Starter", "TypeScript Starter", "None"];
10
- var CREW_FLOW_TEMPLATES = ["Starter", "None"];
10
+ var LANGGRAPH_AGENTS = ["Python Starter", "TypeScript Starter"];
11
+ var CREW_FLOW_TEMPLATES = ["Starter"];
12
+ var YES_NO = ["Yes", "No"];
13
+ var sanitizers = {
14
+ // Remove trailing slash from URLs
15
+ url: (value) => {
16
+ if (!value) return value;
17
+ return value.trim().replace(/\/+$/, "");
18
+ },
19
+ // Trim whitespace from strings
20
+ trim: (value) => {
21
+ if (!value) return value;
22
+ return value.trim();
23
+ },
24
+ // Lowercase strings
25
+ lowercase: (value) => {
26
+ if (!value) return value;
27
+ return value.toLowerCase().trim();
28
+ },
29
+ // Clean API keys (remove whitespace)
30
+ apiKey: (value) => {
31
+ if (!value) return value;
32
+ return value.trim().replace(/\s/g, "");
33
+ }
34
+ };
35
+ var AgentFrameworkSchema = z.enum(AGENT_FRAMEWORKS);
36
+ var CrewTypeSchema = z.enum(CREW_TYPES);
37
+ var ChatComponentSchema = z.enum(CHAT_COMPONENTS);
38
+ var LangGraphAgentSchema = z.enum(LANGGRAPH_AGENTS);
39
+ var CrewFlowTemplateSchema = z.enum(CREW_FLOW_TEMPLATES);
40
+ var YesNoSchema = z.enum(YES_NO);
41
+ var UrlSchema = z.preprocess(
42
+ (val) => sanitizers.url(String(val)),
43
+ z.string().url("Please enter a valid URL").min(1, "URL is required")
44
+ );
45
+ var TokenSchema = z.preprocess(
46
+ (val) => sanitizers.trim(String(val)),
47
+ z.string().min(1, "Token is required")
48
+ );
49
+ var ApiKeySchema = z.preprocess(
50
+ (val) => sanitizers.apiKey(String(val)),
51
+ z.string().min(1, "API key is required")
52
+ );
53
+ var NameSchema = z.preprocess(
54
+ (val) => sanitizers.trim(String(val)),
55
+ z.string().min(1, "Name is required")
56
+ );
57
+ var ConfigSchema = z.object({
58
+ // Core fields
59
+ copilotKitVersion: z.string().optional(),
60
+ agentFramework: AgentFrameworkSchema,
61
+ chatUi: ChatComponentSchema.optional(),
62
+ // Yes/No fields
63
+ alreadyDeployed: YesNoSchema.optional(),
64
+ fastApiEnabled: YesNoSchema.optional(),
65
+ useCopilotCloud: YesNoSchema.optional(),
66
+ // LangGraph specific fields
67
+ langGraphAgent: LangGraphAgentSchema.optional(),
68
+ langGraphPlatform: YesNoSchema.optional(),
69
+ langGraphPlatformUrl: UrlSchema.optional(),
70
+ langGraphRemoteEndpointURL: UrlSchema.optional(),
71
+ // CrewAI specific fields
72
+ crewType: CrewTypeSchema.optional(),
73
+ crewName: NameSchema.optional(),
74
+ crewUrl: UrlSchema.optional(),
75
+ crewBearerToken: TokenSchema.optional(),
76
+ crewFlowAgent: CrewFlowTemplateSchema.optional(),
77
+ // API keys and tokens
78
+ copilotCloudPublicApiKey: z.string().optional(),
79
+ langSmithApiKey: ApiKeySchema.optional(),
80
+ llmToken: ApiKeySchema.optional()
81
+ }).refine(
82
+ (data) => {
83
+ if (data.agentFramework === "CrewAI" && data.crewType === "Crews") {
84
+ return !!data.crewUrl && !!data.crewBearerToken;
85
+ }
86
+ return true;
87
+ },
88
+ {
89
+ message: "Crew URL and bearer token are required for CrewAI Crews",
90
+ path: ["crewUrl", "crewBearerToken"]
91
+ }
92
+ ).refine(
93
+ (data) => {
94
+ if (data.agentFramework === "LangGraph" && data.alreadyDeployed === "Yes" && data.langGraphPlatform === "Yes") {
95
+ return !!data.langGraphPlatformUrl && !!data.langSmithApiKey;
96
+ }
97
+ return true;
98
+ },
99
+ {
100
+ message: "LangGraph Platform URL and LangSmith API key are required",
101
+ path: ["langGraphPlatformUrl", "langSmithApiKey"]
102
+ }
103
+ );
11
104
  var ConfigFlags = {
12
105
  copilotKitVersion: Flags.string({ description: "CopilotKit version to use (e.g. 1.7.0)" }),
13
106
  agentFramework: Flags.string({ description: "Agent framework to power your copilot", options: AGENT_FRAMEWORKS }),
14
- fastApiEnabled: Flags.string({ description: "Use FastAPI to serve your agent locally", options: ["Yes", "No"] }),
15
- useCopilotCloud: Flags.string({ description: "Use Copilot Cloud for production-ready hosting", options: ["Yes", "No"] }),
107
+ fastApiEnabled: Flags.string({ description: "Use FastAPI to serve your agent locally", options: YES_NO }),
108
+ useCopilotCloud: Flags.string({ description: "Use Copilot Cloud for production-ready hosting", options: YES_NO }),
16
109
  chatUi: Flags.string({ description: "Chat UI component to add to your app", options: CHAT_COMPONENTS }),
17
110
  langGraphAgent: Flags.string({ description: "LangGraph agent template to use", options: LANGGRAPH_AGENTS }),
18
111
  crewType: Flags.string({ description: "CrewAI implementation type", options: CREW_TYPES }),
@@ -25,14 +118,14 @@ var ConfigFlags = {
25
118
  };
26
119
 
27
120
  // src/lib/init/types/templates.ts
28
- var BASE_URL = "https://registry.copilotkit.ai/r";
121
+ var BASE_URL = "http://localhost:3002/r";
29
122
  var templateMapping = {
30
- "LangGraphPlatform": `${BASE_URL}/langgraph-platform-starter.json`,
123
+ "LangGraphPlatformRuntime": `${BASE_URL}/langgraph-platform-starter.json`,
31
124
  "RemoteEndpoint": `${BASE_URL}/remote-endpoint-starter.json`,
32
125
  "CrewEnterprise": [
33
126
  `${BASE_URL}/coagents-crew-starter.json`
34
127
  ],
35
- "LangGraphGeneric": `${BASE_URL}/generic-lg-starter.json`,
128
+ "LangGraphGeneric": `${BASE_URL}/generic-lg-starter-with-cloud.json`,
36
129
  "CrewFlowsStarter": [
37
130
  `${BASE_URL}/coagents-starter-ui.json`,
38
131
  `${BASE_URL}/agent-layout.json`,
@@ -52,28 +145,33 @@ var templateMapping = {
52
145
  async function scaffoldShadCN(userAnswers) {
53
146
  try {
54
147
  const components = [];
55
- if (userAnswers.agentFramework !== "None") {
56
- switch (userAnswers.agentFramework) {
57
- case "LangGraph":
58
- if (userAnswers.langGraphAgent && userAnswers.langGraphAgent !== "None") {
59
- components.push(...templateMapping.LangGraphStarter);
60
- } else {
61
- components.push(templateMapping.LangGraphGeneric);
62
- }
63
- break;
64
- case "CrewAI":
65
- if (userAnswers.crewType === "Crews") {
66
- components.push(...templateMapping.CrewEnterprise);
67
- } else if (userAnswers.crewFlowAgent) {
68
- components.push(...templateMapping.CrewFlowsStarter);
69
- } else {
70
- components.push(templateMapping.RemoteEndpoint);
148
+ switch (userAnswers.agentFramework) {
149
+ case "LangGraph":
150
+ if (userAnswers.langGraphAgent) {
151
+ components.push(...templateMapping.LangGraphStarter);
152
+ } else {
153
+ components.push(templateMapping.LangGraphGeneric);
154
+ if (userAnswers.useCopilotCloud !== "Yes") {
155
+ if (userAnswers.langGraphPlatform === "Yes") {
156
+ components.push(templateMapping.LangGraphPlatformRuntime);
157
+ } else {
158
+ components.push(templateMapping.RemoteEndpoint);
159
+ }
71
160
  }
72
- break;
73
- default:
161
+ }
162
+ break;
163
+ case "CrewAI":
164
+ if (userAnswers.crewType === "Crews") {
165
+ components.push(...templateMapping.CrewEnterprise);
166
+ } else if (userAnswers.crewFlowAgent) {
167
+ components.push(...templateMapping.CrewFlowsStarter);
168
+ } else {
74
169
  components.push(templateMapping.RemoteEndpoint);
75
- break;
76
- }
170
+ }
171
+ break;
172
+ default:
173
+ components.push(templateMapping.RemoteEndpoint);
174
+ break;
77
175
  }
78
176
  await new Promise((resolve) => setTimeout(resolve, 100));
79
177
  try {
@@ -100,7 +198,7 @@ import fs from "fs";
100
198
  async function getLangGraphAgents(url, langSmithApiKey) {
101
199
  try {
102
200
  const response = await fetch(
103
- `${url}/assistants/search`,
201
+ `${url.trim().replace(/\/$/, "")}/assistants/search`,
104
202
  {
105
203
  method: "POST",
106
204
  headers: {
@@ -145,13 +243,16 @@ async function scaffoldEnv(flags, userAnswers) {
145
243
  newEnvValues += `NEXT_PUBLIC_COPILOTKIT_AGENT_NAME=${userAnswers.crewName}
146
244
  `;
147
245
  }
148
- if (userAnswers.langGraphAgent !== "None" && userAnswers.langGraphPlatform !== "Yes") {
246
+ if (userAnswers.langGraphAgent) {
149
247
  newEnvValues += `NEXT_PUBLIC_COPILOTKIT_AGENT_NAME=sample_agent
150
248
  `;
151
249
  newEnvValues += `LANGGRAPH_DEPLOYMENT_URL=http://localhost:8123
152
250
  `;
153
251
  } else if (userAnswers.langGraphPlatform === "Yes" && userAnswers.useCopilotCloud === "No") {
154
252
  newEnvValues += `LANGGRAPH_DEPLOYMENT_URL=${userAnswers.langGraphPlatformUrl}
253
+ `;
254
+ } else if (userAnswers.langGraphRemoteEndpointURL) {
255
+ newEnvValues += `COPILOTKIT_REMOTE_ENDPOINT=${userAnswers.langGraphRemoteEndpointURL}
155
256
  `;
156
257
  }
157
258
  if (flags.runtimeUrl) {
@@ -349,7 +450,7 @@ import chalk3 from "chalk";
349
450
  import path3 from "path";
350
451
  import fs4 from "fs";
351
452
  async function scaffoldAgent(userAnswers) {
352
- if (userAnswers.agentFramework === "None" || userAnswers.agentFramework === "CrewAI" && userAnswers.crewType === "Crews" || userAnswers.agentFramework === "LangGraph" && (!userAnswers.langGraphAgent || userAnswers.langGraphAgent === "None")) {
453
+ if (userAnswers.agentFramework === "CrewAI" && userAnswers.crewType === "Crews" || userAnswers.agentFramework === "LangGraph" && !userAnswers.langGraphAgent) {
353
454
  return;
354
455
  }
355
456
  const spinner = ora2({
@@ -448,7 +549,7 @@ async function addCrewInputs(url, token) {
448
549
  }
449
550
  }
450
551
  async function getCrewInputs(url, token) {
451
- const response = await fetch(`${url}/inputs`, {
552
+ const response = await fetch(`${url.trim()}/inputs`, {
452
553
  headers: {
453
554
  Authorization: `Bearer ${token}`
454
555
  }