copilotkit 0.0.15 → 0.0.16

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 (43) 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.d.ts +1 -0
  6. package/dist/commands/init.js +227 -146
  7. package/dist/commands/init.js.map +1 -1
  8. package/dist/commands/login.js +1 -1
  9. package/dist/commands/login.js.map +1 -1
  10. package/dist/commands/logout.js +1 -1
  11. package/dist/commands/logout.js.map +1 -1
  12. package/dist/lib/init/index.d.ts +3 -2
  13. package/dist/lib/init/index.js +178 -99
  14. package/dist/lib/init/index.js.map +1 -1
  15. package/dist/lib/init/questions.js +92 -47
  16. package/dist/lib/init/questions.js.map +1 -1
  17. package/dist/lib/init/scaffold/agent.d.ts +19 -0
  18. package/dist/lib/init/scaffold/agent.js +161 -0
  19. package/dist/lib/init/scaffold/agent.js.map +1 -0
  20. package/dist/lib/init/scaffold/env.js +4 -2
  21. package/dist/lib/init/scaffold/env.js.map +1 -1
  22. package/dist/lib/init/scaffold/github.d.ts +1 -4
  23. package/dist/lib/init/scaffold/github.js +1 -46
  24. package/dist/lib/init/scaffold/github.js.map +1 -1
  25. package/dist/lib/init/scaffold/index.d.ts +2 -1
  26. package/dist/lib/init/scaffold/index.js +96 -54
  27. package/dist/lib/init/scaffold/index.js.map +1 -1
  28. package/dist/lib/init/scaffold/shadcn.js +15 -6
  29. package/dist/lib/init/scaffold/shadcn.js.map +1 -1
  30. package/dist/lib/init/types/index.d.ts +1 -1
  31. package/dist/lib/init/types/index.js +12 -2
  32. package/dist/lib/init/types/index.js.map +1 -1
  33. package/dist/lib/init/types/questions.d.ts +7 -2
  34. package/dist/lib/init/types/questions.js +4 -1
  35. package/dist/lib/init/types/questions.js.map +1 -1
  36. package/dist/lib/init/types/templates.d.ts +11 -2
  37. package/dist/lib/init/types/templates.js +8 -1
  38. package/dist/lib/init/types/templates.js.map +1 -1
  39. package/dist/utils/version.d.ts +1 -1
  40. package/dist/utils/version.js +1 -1
  41. package/dist/utils/version.js.map +1 -1
  42. package/oclif.manifest.json +12 -1
  43. package/package.json +1 -1
@@ -4,6 +4,7 @@ var AGENT_FRAMEWORKS = ["CrewAI", "LangGraph", "None"];
4
4
  var CREW_TYPES = ["Crews", "Flows"];
5
5
  var CHAT_COMPONENTS = ["CopilotChat", "CopilotSidebar", "Headless", "CopilotPopup"];
6
6
  var LANGGRAPH_AGENTS = ["Python Starter", "TypeScript Starter", "None"];
7
+ var CREW_FLOW_TEMPLATES = ["Starter", "None"];
7
8
  var ConfigFlags = {
8
9
  copilotKitVersion: Flags.string({ description: "CopilotKit version to use (e.g. 1.7.0)" }),
9
10
  agentFramework: Flags.string({ description: "Agent framework to power your copilot", options: AGENT_FRAMEWORKS }),
@@ -16,7 +17,8 @@ var ConfigFlags = {
16
17
  crewUrl: Flags.string({ description: "URL endpoint for your CrewAI agent" }),
17
18
  crewBearerToken: Flags.string({ description: "Bearer token for CrewAI authentication" }),
18
19
  langSmithApiKey: Flags.string({ description: "LangSmith API key for LangGraph observability" }),
19
- llmToken: Flags.string({ description: "API key for your preferred LLM provider" })
20
+ llmToken: Flags.string({ description: "API key for your preferred LLM provider" }),
21
+ crewFlowAgent: Flags.string({ description: "CrewAI Flow template to use", options: CREW_FLOW_TEMPLATES })
20
22
  };
21
23
 
22
24
  // src/lib/init/types/templates.ts
@@ -24,7 +26,14 @@ var BASE_URL = "http://registry.copilotkit.ai/r";
24
26
  var templateMapping = {
25
27
  "LangGraphPlatform": `${BASE_URL}/langgraph-platform-starter.json`,
26
28
  "RemoteEndpoint": `${BASE_URL}/remote-endpoint-starter.json`,
27
- "CrewEnterprise": `${BASE_URL}/agent-layout.json`,
29
+ "CrewEnterprise": [
30
+ `${BASE_URL}/coagents-crew-starter.json`
31
+ ],
32
+ "CrewFlowsStarter": [
33
+ `${BASE_URL}/coagents-starter-ui.json`,
34
+ `${BASE_URL}/agent-layout.json`,
35
+ `${BASE_URL}/remote-endpoint.json`
36
+ ],
28
37
  "Standard": `${BASE_URL}/standard-starter.json`,
29
38
  "CopilotChat": `${BASE_URL}/chat.json`,
30
39
  "CopilotPopup": `${BASE_URL}/popup.json`,
@@ -48,10 +57,11 @@ var questions = [
48
57
  choices: Array.from(CREW_TYPES),
49
58
  when: (answers) => answers.agentFramework === "CrewAI"
50
59
  },
60
+ // CrewAI Crews specific questions - shown when CrewAI Crews selected
51
61
  {
52
62
  type: "input",
53
63
  name: "crewName",
54
- message: "\u{1F465} What would you like to name your crew?",
64
+ message: "\u{1F465} What would you like to name your crew? (can be anything)",
55
65
  when: (answers) => answers.agentFramework === "CrewAI" && answers.crewType === "Crews",
56
66
  default: "MyCopilotCrew"
57
67
  },
@@ -65,66 +75,101 @@ var questions = [
65
75
  type: "input",
66
76
  name: "crewBearerToken",
67
77
  message: "\u{1F511} Enter your Crew authentication token:",
68
- when: (answers) => answers.agentFramework === "CrewAI" && answers.crewType === "Crews"
69
- },
70
- // LangGraph specific questions - shown when LangGraph selected
71
- {
72
- type: "yes/no",
73
- name: "alreadyDeployed",
74
- message: "\u{1F680} Is your LangGraph agent already deployed?",
75
- when: (answers) => answers.agentFramework === "LangGraph"
76
- },
77
- {
78
- type: "yes/no",
79
- name: "langGraphPlatform",
80
- message: "\u{1F99C}\u{1F517} Is it hosted on LangGraph Platform?",
81
- when: (answers) => answers.agentFramework === "LangGraph" && answers.alreadyDeployed === "Yes"
82
- },
83
- {
84
- type: "input",
85
- name: "langGraphPlatformUrl",
86
- message: "\u{1F99C}\u{1F517} Enter your LangGraph platform URL:",
87
- when: (answers) => answers.agentFramework === "LangGraph" && answers.alreadyDeployed === "Yes" && answers.langGraphPlatform === "Yes"
88
- },
89
- {
90
- type: "input",
91
- name: "langGraphRemoteEndpointURL",
92
- message: "\u{1F50C} Enter your LangGraph endpoint URL:",
93
- when: (answers) => answers.agentFramework === "LangGraph" && answers.alreadyDeployed === "Yes" && answers.langGraphPlatform === "No"
78
+ when: (answers) => answers.agentFramework === "CrewAI" && answers.crewType === "Crews",
79
+ sensitive: true
94
80
  },
81
+ // CrewAI Flows specific questions - shown when CrewAI Flows selected
95
82
  {
96
83
  type: "select",
97
- name: "langGraphAgent",
98
- message: "\u{1F4E6} Choose a LangGraph starter template:",
99
- choices: Array.from(LANGGRAPH_AGENTS),
100
- when: (answers) => answers.agentFramework === "LangGraph" && answers.alreadyDeployed === "No"
101
- },
102
- {
103
- type: "input",
104
- name: "langSmithApiKey",
105
- message: "\u{1F99C}\u{1F517} Enter your LangSmith API key (required by LangGraph Platform) :",
106
- when: (answers) => answers.agentFramework === "LangGraph" && answers.alreadyDeployed === "No"
84
+ name: "crewFlowAgent",
85
+ message: "\u{1F4E6} Choose a CrewAI Flow Template",
86
+ choices: Array.from(CREW_FLOW_TEMPLATES),
87
+ when: (answers) => answers.agentFramework === "CrewAI" && answers.crewType === "Flows"
107
88
  },
89
+ // LangGraph specific questions - shown when LangGraph selected
90
+ // {
91
+ // type: 'yes/no',
92
+ // name: 'alreadyDeployed',
93
+ // message: '🚀 Is your LangGraph agent already deployed?',
94
+ // when: (answers) => answers.agentFramework === 'LangGraph',
95
+ // },
96
+ // {
97
+ // type: 'yes/no',
98
+ // name: 'langGraphPlatform',
99
+ // message: '🦜🔗 Is it hosted on LangGraph Platform?',
100
+ // when: (answers) =>
101
+ // answers.agentFramework === 'LangGraph' &&
102
+ // answers.alreadyDeployed === 'Yes',
103
+ // },
104
+ // {
105
+ // type: 'input',
106
+ // name: 'langGraphPlatformUrl',
107
+ // message: '🦜🔗 Enter your LangGraph platform URL:',
108
+ // when: (answers) =>
109
+ // answers.agentFramework === 'LangGraph' &&
110
+ // answers.alreadyDeployed === 'Yes' &&
111
+ // answers.langGraphPlatform === 'Yes',
112
+ // },
113
+ // {
114
+ // type: 'input',
115
+ // name: 'langGraphRemoteEndpointURL',
116
+ // message: '🔌 Enter your LangGraph endpoint URL:',
117
+ // when: (answers) =>
118
+ // answers.agentFramework === 'LangGraph' &&
119
+ // answers.alreadyDeployed === 'Yes' &&
120
+ // answers.langGraphPlatform === 'No',
121
+ // },
122
+ // {
123
+ // type: 'select',
124
+ // name: 'langGraphAgent',
125
+ // message: '📦 Choose a LangGraph starter template:',
126
+ // choices: Array.from(LANGGRAPH_AGENTS),
127
+ // when: (answers) =>
128
+ // answers.agentFramework === 'LangGraph' &&
129
+ // answers.alreadyDeployed === 'No',
130
+ // },
131
+ // {
132
+ // type: 'input',
133
+ // name: 'langSmithApiKey',
134
+ // message: '🦜🔗 Enter your LangSmith API key (required by LangGraph Platform) :',
135
+ // when: (answers) =>
136
+ // answers.agentFramework === 'LangGraph' &&
137
+ // answers.alreadyDeployed === 'No',
138
+ // sensitive: true,
139
+ // },
108
140
  // Deployment options
109
141
  {
110
142
  type: "yes/no",
111
143
  name: "useCopilotCloud",
112
144
  message: "\u{1FA81} Deploy with Copilot Cloud? (recommended for production)",
113
- when: (answers) => !(answers.agentFramework === "CrewAI" && answers.crewType === "Crews")
114
- },
115
- {
116
- type: "yes/no",
117
- name: "fastApiEnabled",
118
- message: "\u26A1 Set up a FastAPI server for local development?",
119
- when: (answers) => answers.agentFramework === "LangGraph" && answers.alreadyDeployed === "No" && answers.langGraphAgent === "Python Starter" && answers.useCopilotCloud !== "Yes"
145
+ when: (answers) => !(answers.agentFramework === "CrewAI" && answers.crewType === "Crews") && answers.agentFramework !== "LangGraph"
120
146
  },
147
+ // {
148
+ // type: 'yes/no',
149
+ // name: 'fastApiEnabled',
150
+ // message: '⚡ Set up a FastAPI server for local development?',
151
+ // when: (answers) =>
152
+ // answers.agentFramework === 'LangGraph' &&
153
+ // answers.alreadyDeployed === 'No' &&
154
+ // answers.langGraphAgent === 'Python Starter' &&
155
+ // answers.useCopilotCloud !== 'Yes',
156
+ // },
121
157
  // UI components - always shown last
122
158
  {
123
159
  type: "select",
124
160
  name: "chatUi",
125
161
  message: "\u{1F4AC} Select a UI component for your copilot:",
126
162
  choices: Array.from(CHAT_COMPONENTS),
127
- default: "CopilotChat"
163
+ default: "CopilotChat",
164
+ when: (answers) => answers.agentFramework === "None"
165
+ },
166
+ {
167
+ type: "input",
168
+ name: "llmToken",
169
+ message: "\u{1F511} Enter your OpenAI API key (required for agent functionality):",
170
+ when: (answers) => answers.agentFramework !== "LangGraph" && // (answers.agentFramework === 'LangGraph' && answers.alreadyDeployed === 'No') ||
171
+ (answers.agentFramework === "CrewAI" && answers.crewType === "Flows"),
172
+ sensitive: true
128
173
  }
129
174
  ];
130
175
  export {
@@ -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}\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// 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\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\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}","export type ChatTemplate = \n \"CopilotChat\" |\n \"CopilotPopup\" |\n \"CopilotSidebar\"\n\nexport type StarterTemplate = \n \"LangGraphPlatform\" |\n \"RemoteEndpoint\" |\n \"Standard\" |\n \"CrewEnterprise\"\n\nexport type Template = ChatTemplate | StarterTemplate\n\nconst BASE_URL = \"http://registry.copilotkit.ai/r\"\n\nexport const templateMapping: Record<Template, string> = {\n \"LangGraphPlatform\": `${BASE_URL}/langgraph-platform-starter.json`,\n \"RemoteEndpoint\": `${BASE_URL}/remote-endpoint-starter.json`,\n \"CrewEnterprise\": `${BASE_URL}/agent-layout.json`,\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} 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: '📋 Select CrewAI implementation type:',\n choices: Array.from(CREW_TYPES),\n when: (answers) => answers.agentFramework === 'CrewAI',\n },\n {\n type: 'input',\n name: 'crewName',\n message: '👥 What would you like to name your crew?',\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 API endpoint:',\n when: (answers) => answers.agentFramework === 'CrewAI' && answers.crewType === 'Crews',\n },\n {\n type: 'input',\n name: 'crewBearerToken',\n message: '🔑 Enter your Crew authentication token:',\n when: (answers) => answers.agentFramework === 'CrewAI' && answers.crewType === 'Crews',\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 on LangGraph Platform?',\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.alreadyDeployed === 'No',\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 },\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 },\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 { 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 = \"http://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 \"CrewFlowsStarter\": [\n `${BASE_URL}/coagents-starter-ui.json`,\n `${BASE_URL}/agent-layout.json`,\n `${BASE_URL}/remote-endpoint.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: '📋 Select CrewAI implementation type:',\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 API endpoint:',\n when: (answers) => answers.agentFramework === 'CrewAI' && answers.crewType === 'Crews',\n },\n {\n type: 'input',\n name: 'crewBearerToken',\n message: '🔑 Enter your Crew authentication 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 on LangGraph Platform?',\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.alreadyDeployed === 'No',\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.agentFramework !== 'LangGraph',\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' &&\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":[]}
@@ -0,0 +1,19 @@
1
+ import { Config } from '../types/questions.js';
2
+ import '@oclif/core/interfaces';
3
+
4
+ declare function scaffoldAgent(userAnswers: Config): Promise<void>;
5
+ declare const AgentTemplates: {
6
+ LangGraph: {
7
+ Starter: {
8
+ Python: string;
9
+ TypeScript: string;
10
+ };
11
+ };
12
+ CrewAI: {
13
+ Flows: {
14
+ Starter: string;
15
+ };
16
+ };
17
+ };
18
+
19
+ export { AgentTemplates, scaffoldAgent };
@@ -0,0 +1,161 @@
1
+ // src/lib/init/scaffold/agent.ts
2
+ import ora from "ora";
3
+ import chalk2 from "chalk";
4
+
5
+ // src/lib/init/scaffold/github.ts
6
+ import { execSync } from "child_process";
7
+ import * as fs from "fs";
8
+ import * as path from "path";
9
+ import * as os from "os";
10
+ import chalk from "chalk";
11
+ async function cloneGitHubSubdirectory(githubUrl, destinationPath, spinner) {
12
+ try {
13
+ const { owner, repo, branch, subdirectoryPath } = parseGitHubUrl(githubUrl);
14
+ spinner.text = chalk.cyan(`Cloning from ${owner}/${repo}...`);
15
+ return await sparseCheckout(owner, repo, branch, subdirectoryPath, destinationPath, spinner);
16
+ } catch (error) {
17
+ spinner.text = chalk.red(`Failed to clone from GitHub: ${error}`);
18
+ return false;
19
+ }
20
+ }
21
+ async function sparseCheckout(owner, repo, branch, subdirectoryPath, destinationPath, spinner) {
22
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "copilotkit-sparse-"));
23
+ try {
24
+ spinner.text = chalk.cyan("Creating temporary workspace...");
25
+ execSync("git init", { cwd: tempDir, stdio: "pipe" });
26
+ 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);
30
+ spinner.text = chalk.cyan("Downloading agent files...");
31
+ execSync(`git pull origin ${branch} --depth=1`, { cwd: tempDir, stdio: "pipe" });
32
+ const sourcePath = path.join(tempDir, subdirectoryPath);
33
+ if (!fs.existsSync(sourcePath)) {
34
+ throw new Error(`Subdirectory '${subdirectoryPath}' not found in the repository.`);
35
+ }
36
+ fs.mkdirSync(destinationPath, { recursive: true });
37
+ spinner.text = chalk.cyan("Installing agent files...");
38
+ await copyDirectoryAsync(sourcePath, destinationPath);
39
+ return true;
40
+ } finally {
41
+ try {
42
+ fs.rmSync(tempDir, { recursive: true, force: true });
43
+ } catch (error) {
44
+ console.warn(`Failed to clean up temporary directory: ${error}`);
45
+ }
46
+ }
47
+ }
48
+ async function copyDirectoryAsync(source, destination) {
49
+ if (!fs.existsSync(destination)) {
50
+ fs.mkdirSync(destination, { recursive: true });
51
+ }
52
+ const entries = fs.readdirSync(source, { withFileTypes: true });
53
+ for (const entry of entries) {
54
+ const srcPath = path.join(source, entry.name);
55
+ const destPath = path.join(destination, entry.name);
56
+ if (entry.isDirectory()) {
57
+ await copyDirectoryAsync(srcPath, destPath);
58
+ } else {
59
+ fs.copyFileSync(srcPath, destPath);
60
+ }
61
+ if (entries.length > 10) {
62
+ await new Promise((resolve) => setTimeout(resolve, 1));
63
+ }
64
+ }
65
+ }
66
+ function parseGitHubUrl(githubUrl) {
67
+ const url = new URL(githubUrl);
68
+ if (url.hostname !== "github.com") {
69
+ throw new Error("Only GitHub URLs are supported");
70
+ }
71
+ const pathParts = url.pathname.split("/").filter(Boolean);
72
+ if (pathParts.length < 2) {
73
+ throw new Error("Invalid GitHub URL format");
74
+ }
75
+ const owner = pathParts[0];
76
+ const repo = pathParts[1];
77
+ let branch = "main";
78
+ let subdirectoryPath = "";
79
+ if (pathParts.length > 3 && (pathParts[2] === "tree" || pathParts[2] === "blob")) {
80
+ branch = pathParts[3];
81
+ subdirectoryPath = pathParts.slice(4).join("/");
82
+ }
83
+ return { owner, repo, branch, subdirectoryPath };
84
+ }
85
+
86
+ // src/lib/init/scaffold/agent.ts
87
+ import path2 from "path";
88
+ import fs2 from "fs";
89
+ async function scaffoldAgent(userAnswers) {
90
+ if (userAnswers.agentFramework === "None" || userAnswers.agentFramework === "CrewAI" && userAnswers.crewType === "Crews" || userAnswers.agentFramework === "LangGraph" && (!userAnswers.langGraphAgent || userAnswers.langGraphAgent === "None")) {
91
+ return;
92
+ }
93
+ const spinner = ora({
94
+ text: chalk2.cyan("Setting up AI agent..."),
95
+ color: "cyan"
96
+ }).start();
97
+ let template = "";
98
+ switch (userAnswers.agentFramework) {
99
+ case "LangGraph":
100
+ if (userAnswers.langGraphAgent === "Python Starter") {
101
+ template = AgentTemplates.LangGraph.Starter.Python;
102
+ } else {
103
+ template = AgentTemplates.LangGraph.Starter.TypeScript;
104
+ }
105
+ break;
106
+ case "CrewAI":
107
+ if (userAnswers.crewFlowAgent === "Starter") {
108
+ template = AgentTemplates.CrewAI.Flows.Starter;
109
+ }
110
+ break;
111
+ }
112
+ if (!template) {
113
+ spinner.fail(chalk2.red("Failed to determine agent template"));
114
+ throw new Error("Failed to determine agent template");
115
+ }
116
+ const agentDir = path2.join(process.cwd(), "agent");
117
+ try {
118
+ await cloneGitHubSubdirectory(
119
+ template,
120
+ agentDir,
121
+ spinner
122
+ );
123
+ spinner.text = chalk2.cyan("Creating agent environment variables...");
124
+ let envContent = "";
125
+ if (userAnswers.llmToken) {
126
+ envContent += `OPENAI_API_KEY=${userAnswers.llmToken}
127
+ `;
128
+ }
129
+ if (userAnswers.agentFramework === "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
+ } catch (error) {
139
+ spinner.fail(chalk2.red("Failed to clone agent template"));
140
+ throw error;
141
+ }
142
+ spinner.succeed(chalk2.green(`${userAnswers.agentFramework} agent cloned successfully`));
143
+ }
144
+ var AgentTemplates = {
145
+ LangGraph: {
146
+ Starter: {
147
+ Python: "https://github.com/CopilotKit/CopilotKit/tree/main/examples/coagents-starter/agent-py",
148
+ TypeScript: "https://github.com/CopilotKit/CopilotKit/tree/main/examples/coagents-starter/agent-js"
149
+ }
150
+ },
151
+ CrewAI: {
152
+ Flows: {
153
+ Starter: "https://github.com/CopilotKit/CopilotKit/tree/main/examples/coagents-starter-crewai-flows/agent-py"
154
+ }
155
+ }
156
+ };
157
+ export {
158
+ AgentTemplates,
159
+ scaffoldAgent
160
+ };
161
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +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(chalk.green(`${userAnswers.agentFramework} agent cloned successfully`));\n}\n\nexport const AgentTemplates = {\n LangGraph: {\n Starter: {\n Python: 'https://github.com/CopilotKit/CopilotKit/tree/main/examples/coagents-starter/agent-py',\n TypeScript: 'https://github.com/CopilotKit/CopilotKit/tree/main/examples/coagents-starter/agent-js',\n }\n },\n CrewAI: {\n Flows: {\n Starter: 'https://github.com/CopilotKit/CopilotKit/tree/main/examples/coagents-starter-crewai-flows/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"]}
@@ -25,7 +25,7 @@ async function scaffoldEnv(flags, userAnswers) {
25
25
  varsAdded = true;
26
26
  }
27
27
  if (userAnswers.langSmithApiKey) {
28
- newEnvValues += `LANG_SMITH_API_KEY=${userAnswers.langSmithApiKey}
28
+ newEnvValues += `LANGSMITH_API_KEY=${userAnswers.langSmithApiKey}
29
29
  `;
30
30
  spinner.text = chalk.cyan("Adding LangSmith API key...");
31
31
  varsAdded = true;
@@ -33,7 +33,9 @@ async function scaffoldEnv(flags, userAnswers) {
33
33
  if (userAnswers.llmToken) {
34
34
  newEnvValues += `LLM_TOKEN=${userAnswers.llmToken}
35
35
  `;
36
- spinner.text = chalk.cyan("Adding LLM token...");
36
+ newEnvValues += `OPENAI_API_KEY=${userAnswers.llmToken}
37
+ `;
38
+ spinner.text = chalk.cyan("Adding OpenAI API key...");
37
39
  varsAdded = true;
38
40
  }
39
41
  if (userAnswers.crewName) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/init/scaffold/env.ts"],"sourcesContent":["import path from \"path\"\nimport fs from \"fs\"\nimport { Config } from \"../types/index.js\"\nimport chalk from \"chalk\"\nimport ora from \"ora\"\n\nexport async function scaffoldEnv(flags: any, userAnswers: Config) {\n const spinner = ora({\n text: chalk.cyan('Configuring environment variables...'),\n color: 'cyan'\n }).start();\n\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 spinner.text = chalk.cyan('Created .env file...');\n } else {\n spinner.text = chalk.cyan('Updating existing .env file...');\n }\n \n // Build environment variables based on user selections\n let newEnvValues = ''\n let varsAdded = false;\n \n // Copilot Cloud API key\n if (userAnswers.copilotCloudPublicApiKey) {\n newEnvValues += `NEXT_PUBLIC_COPILOT_API_KEY=${userAnswers.copilotCloudPublicApiKey}\\n`\n spinner.text = chalk.cyan('Adding Copilot Cloud API key...');\n varsAdded = true;\n }\n \n // LangSmith API key (for LangGraph)\n if (userAnswers.langSmithApiKey) {\n newEnvValues += `LANG_SMITH_API_KEY=${userAnswers.langSmithApiKey}\\n`\n spinner.text = chalk.cyan('Adding LangSmith API key...');\n varsAdded = true;\n }\n \n // LLM API key\n if (userAnswers.llmToken) {\n newEnvValues += `LLM_TOKEN=${userAnswers.llmToken}\\n`\n spinner.text = chalk.cyan('Adding LLM token...');\n varsAdded = true;\n }\n \n // CrewAI name\n if (userAnswers.crewName) {\n newEnvValues += `NEXT_PUBLIC_COPILOTKIT_AGENT_NAME=${userAnswers.crewName}\\n`\n spinner.text = chalk.cyan('Adding Crew agent name...');\n varsAdded = true;\n }\n \n // Runtime URL if provided via flags\n if (flags.runtimeUrl) {\n newEnvValues += `NEXT_PUBLIC_COPILOTKIT_RUNTIME_URL=${flags.runtimeUrl}\\n`\n spinner.text = chalk.cyan('Adding runtime URL...');\n varsAdded = true;\n }\n \n if (!varsAdded) {\n spinner.text = chalk.cyan('No environment variables needed...');\n }\n \n // Append the variables to the .env file\n if (newEnvValues) {\n fs.appendFileSync(envFile, newEnvValues)\n spinner.succeed(chalk('Environment variables configured successfully'));\n } else {\n spinner.info(chalk.yellow('No environment variables were added'));\n }\n } catch (error) {\n spinner.fail(chalk.red('Failed to update environment variables'));\n throw error;\n }\n}\n"],"mappings":";AAAA,OAAO,UAAU;AACjB,OAAO,QAAQ;AAEf,OAAO,WAAW;AAClB,OAAO,SAAS;AAEhB,eAAsB,YAAY,OAAY,aAAqB;AACjE,QAAM,UAAU,IAAI;AAAA,IAClB,MAAM,MAAM,KAAK,sCAAsC;AAAA,IACvD,OAAO;AAAA,EACT,CAAC,EAAE,MAAM;AAET,MAAI;AAEF,UAAM,UAAU,KAAK,KAAK,QAAQ,IAAI,GAAG,MAAM;AAG/C,QAAI,CAAC,GAAG,WAAW,OAAO,GAAG;AAC3B,SAAG,cAAc,SAAS,IAAI,MAAM;AACpC,cAAQ,OAAO,MAAM,KAAK,sBAAsB;AAAA,IAClD,OAAO;AACL,cAAQ,OAAO,MAAM,KAAK,gCAAgC;AAAA,IAC5D;AAGA,QAAI,eAAe;AACnB,QAAI,YAAY;AAGhB,QAAI,YAAY,0BAA0B;AACxC,sBAAgB,+BAA+B,YAAY,wBAAwB;AAAA;AACnF,cAAQ,OAAO,MAAM,KAAK,iCAAiC;AAC3D,kBAAY;AAAA,IACd;AAGA,QAAI,YAAY,iBAAiB;AAC/B,sBAAgB,sBAAsB,YAAY,eAAe;AAAA;AACjE,cAAQ,OAAO,MAAM,KAAK,6BAA6B;AACvD,kBAAY;AAAA,IACd;AAGA,QAAI,YAAY,UAAU;AACxB,sBAAgB,aAAa,YAAY,QAAQ;AAAA;AACjD,cAAQ,OAAO,MAAM,KAAK,qBAAqB;AAC/C,kBAAY;AAAA,IACd;AAGA,QAAI,YAAY,UAAU;AACxB,sBAAgB,qCAAqC,YAAY,QAAQ;AAAA;AACzE,cAAQ,OAAO,MAAM,KAAK,2BAA2B;AACrD,kBAAY;AAAA,IACd;AAGA,QAAI,MAAM,YAAY;AACpB,sBAAgB,sCAAsC,MAAM,UAAU;AAAA;AACtE,cAAQ,OAAO,MAAM,KAAK,uBAAuB;AACjD,kBAAY;AAAA,IACd;AAEA,QAAI,CAAC,WAAW;AACd,cAAQ,OAAO,MAAM,KAAK,oCAAoC;AAAA,IAChE;AAGA,QAAI,cAAc;AAChB,SAAG,eAAe,SAAS,YAAY;AACvC,cAAQ,QAAQ,MAAM,+CAA+C,CAAC;AAAA,IACxE,OAAO;AACL,cAAQ,KAAK,MAAM,OAAO,qCAAqC,CAAC;AAAA,IAClE;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,KAAK,MAAM,IAAI,wCAAwC,CAAC;AAChE,UAAM;AAAA,EACR;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../src/lib/init/scaffold/env.ts"],"sourcesContent":["import path from \"path\"\nimport fs from \"fs\"\nimport { Config } from \"../types/index.js\"\nimport chalk from \"chalk\"\nimport ora from \"ora\"\n\nexport async function scaffoldEnv(flags: any, userAnswers: Config) {\n const spinner = ora({\n text: chalk.cyan('Configuring environment variables...'),\n color: 'cyan'\n }).start();\n\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 spinner.text = chalk.cyan('Created .env file...');\n } else {\n spinner.text = chalk.cyan('Updating existing .env file...');\n }\n \n // Build environment variables based on user selections\n let newEnvValues = ''\n let varsAdded = false;\n \n // Copilot Cloud API key\n if (userAnswers.copilotCloudPublicApiKey) {\n newEnvValues += `NEXT_PUBLIC_COPILOT_API_KEY=${userAnswers.copilotCloudPublicApiKey}\\n`\n spinner.text = chalk.cyan('Adding Copilot Cloud API key...');\n varsAdded = true;\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 spinner.text = chalk.cyan('Adding LangSmith API key...');\n varsAdded = true;\n }\n \n // LLM API key - set as both LLM_TOKEN and OPENAI_API_KEY for compatibility\n if (userAnswers.llmToken) {\n newEnvValues += `LLM_TOKEN=${userAnswers.llmToken}\\n`\n newEnvValues += `OPENAI_API_KEY=${userAnswers.llmToken}\\n`\n spinner.text = chalk.cyan('Adding OpenAI API key...');\n varsAdded = true;\n }\n \n // CrewAI name\n if (userAnswers.crewName) {\n newEnvValues += `NEXT_PUBLIC_COPILOTKIT_AGENT_NAME=${userAnswers.crewName}\\n`\n spinner.text = chalk.cyan('Adding Crew agent name...');\n varsAdded = true;\n }\n \n // Runtime URL if provided via flags\n if (flags.runtimeUrl) {\n newEnvValues += `NEXT_PUBLIC_COPILOTKIT_RUNTIME_URL=${flags.runtimeUrl}\\n`\n spinner.text = chalk.cyan('Adding runtime URL...');\n varsAdded = true;\n }\n \n if (!varsAdded) {\n spinner.text = chalk.cyan('No environment variables needed...');\n }\n \n // Append the variables to the .env file\n if (newEnvValues) {\n fs.appendFileSync(envFile, newEnvValues)\n spinner.succeed(chalk('Environment variables configured successfully'));\n } else {\n spinner.info(chalk.yellow('No environment variables were added'));\n }\n } catch (error) {\n spinner.fail(chalk.red('Failed to update environment variables'));\n throw error;\n }\n}\n"],"mappings":";AAAA,OAAO,UAAU;AACjB,OAAO,QAAQ;AAEf,OAAO,WAAW;AAClB,OAAO,SAAS;AAEhB,eAAsB,YAAY,OAAY,aAAqB;AACjE,QAAM,UAAU,IAAI;AAAA,IAClB,MAAM,MAAM,KAAK,sCAAsC;AAAA,IACvD,OAAO;AAAA,EACT,CAAC,EAAE,MAAM;AAET,MAAI;AAEF,UAAM,UAAU,KAAK,KAAK,QAAQ,IAAI,GAAG,MAAM;AAG/C,QAAI,CAAC,GAAG,WAAW,OAAO,GAAG;AAC3B,SAAG,cAAc,SAAS,IAAI,MAAM;AACpC,cAAQ,OAAO,MAAM,KAAK,sBAAsB;AAAA,IAClD,OAAO;AACL,cAAQ,OAAO,MAAM,KAAK,gCAAgC;AAAA,IAC5D;AAGA,QAAI,eAAe;AACnB,QAAI,YAAY;AAGhB,QAAI,YAAY,0BAA0B;AACxC,sBAAgB,+BAA+B,YAAY,wBAAwB;AAAA;AACnF,cAAQ,OAAO,MAAM,KAAK,iCAAiC;AAC3D,kBAAY;AAAA,IACd;AAGA,QAAI,YAAY,iBAAiB;AAE/B,sBAAgB,qBAAqB,YAAY,eAAe;AAAA;AAChE,cAAQ,OAAO,MAAM,KAAK,6BAA6B;AACvD,kBAAY;AAAA,IACd;AAGA,QAAI,YAAY,UAAU;AACxB,sBAAgB,aAAa,YAAY,QAAQ;AAAA;AACjD,sBAAgB,kBAAkB,YAAY,QAAQ;AAAA;AACtD,cAAQ,OAAO,MAAM,KAAK,0BAA0B;AACpD,kBAAY;AAAA,IACd;AAGA,QAAI,YAAY,UAAU;AACxB,sBAAgB,qCAAqC,YAAY,QAAQ;AAAA;AACzE,cAAQ,OAAO,MAAM,KAAK,2BAA2B;AACrD,kBAAY;AAAA,IACd;AAGA,QAAI,MAAM,YAAY;AACpB,sBAAgB,sCAAsC,MAAM,UAAU;AAAA;AACtE,cAAQ,OAAO,MAAM,KAAK,uBAAuB;AACjD,kBAAY;AAAA,IACd;AAEA,QAAI,CAAC,WAAW;AACd,cAAQ,OAAO,MAAM,KAAK,oCAAoC;AAAA,IAChE;AAGA,QAAI,cAAc;AAChB,SAAG,eAAe,SAAS,YAAY;AACvC,cAAQ,QAAQ,MAAM,+CAA+C,CAAC;AAAA,IACxE,OAAO;AACL,cAAQ,KAAK,MAAM,OAAO,qCAAqC,CAAC;AAAA,IAClE;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,KAAK,MAAM,IAAI,wCAAwC,CAAC;AAChE,UAAM;AAAA,EACR;AACF;","names":[]}
@@ -1,8 +1,5 @@
1
- import { Config } from '../types/questions.js';
2
1
  import { Ora } from 'ora';
3
- import '@oclif/core/interfaces';
4
2
 
5
- declare function scaffoldAgent(userAnswers: Config): Promise<void>;
6
3
  /**
7
4
  * Clones a specific subdirectory from a GitHub repository
8
5
  *
@@ -17,4 +14,4 @@ declare function cloneGitHubSubdirectory(githubUrl: string, destinationPath: str
17
14
  */
18
15
  declare function isValidGitHubUrl(url: string): boolean;
19
16
 
20
- export { cloneGitHubSubdirectory, isValidGitHubUrl, scaffoldAgent };
17
+ export { cloneGitHubSubdirectory, isValidGitHubUrl };
@@ -4,50 +4,6 @@ import * as fs from "fs";
4
4
  import * as path from "path";
5
5
  import * as os from "os";
6
6
  import chalk from "chalk";
7
- import ora from "ora";
8
- async function scaffoldAgent(userAnswers) {
9
- if (userAnswers.agentFramework === "None" || userAnswers.agentFramework === "CrewAI" && userAnswers.crewType === "Crews" || userAnswers.agentFramework === "LangGraph" && (!userAnswers.langGraphAgent || userAnswers.langGraphAgent === "None")) {
10
- return;
11
- }
12
- const spinner = ora({
13
- text: chalk.cyan("Setting up AI agent..."),
14
- color: "cyan"
15
- }).start();
16
- try {
17
- if (userAnswers.agentFramework === "LangGraph") {
18
- switch (userAnswers.langGraphAgent) {
19
- case "Python Starter":
20
- spinner.text = chalk.cyan("Setting up Python LangGraph agent...");
21
- await new Promise((resolve) => setTimeout(resolve, 50));
22
- await cloneGitHubSubdirectory(
23
- "https://github.com/CopilotKit/CopilotKit/tree/main/examples/coagents-starter/agent-py",
24
- path.join(process.cwd(), "agent"),
25
- spinner
26
- );
27
- break;
28
- case "TypeScript Starter":
29
- spinner.text = chalk.cyan("Setting up TypeScript LangGraph agent...");
30
- await new Promise((resolve) => setTimeout(resolve, 50));
31
- await cloneGitHubSubdirectory(
32
- "https://github.com/CopilotKit/CopilotKit/tree/main/examples/coagents-starter/agent-js",
33
- path.join(process.cwd(), "agent"),
34
- spinner
35
- );
36
- break;
37
- default:
38
- break;
39
- }
40
- } else if (userAnswers.agentFramework === "CrewAI" && userAnswers.crewType === "Flows") {
41
- spinner.text = chalk.cyan("Setting up CrewAI Flows agent...");
42
- await new Promise((resolve) => setTimeout(resolve, 50));
43
- spinner.info(chalk.yellow("CrewAI Flows support is coming soon..."));
44
- }
45
- spinner.succeed(chalk.green("AI agent setup complete"));
46
- } catch (error) {
47
- spinner.fail(chalk.red("Failed to set up AI agent"));
48
- throw error;
49
- }
50
- }
51
7
  async function cloneGitHubSubdirectory(githubUrl, destinationPath, spinner) {
52
8
  try {
53
9
  const { owner, repo, branch, subdirectoryPath } = parseGitHubUrl(githubUrl);
@@ -132,7 +88,6 @@ function isValidGitHubUrl(url) {
132
88
  }
133
89
  export {
134
90
  cloneGitHubSubdirectory,
135
- isValidGitHubUrl,
136
- scaffoldAgent
91
+ isValidGitHubUrl
137
92
  };
138
93
  //# sourceMappingURL=github.js.map
@@ -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\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 try {\n if (userAnswers.agentFramework === 'LangGraph') {\n switch (userAnswers.langGraphAgent) {\n case 'Python Starter':\n spinner.text = chalk.cyan('Setting up Python LangGraph agent...');\n await new Promise(resolve => setTimeout(resolve, 50));\n \n await cloneGitHubSubdirectory(\n 'https://github.com/CopilotKit/CopilotKit/tree/main/examples/coagents-starter/agent-py', \n path.join(process.cwd(), 'agent'),\n spinner\n );\n break;\n \n case 'TypeScript Starter':\n spinner.text = chalk.cyan('Setting up TypeScript LangGraph agent...');\n await new Promise(resolve => setTimeout(resolve, 50));\n \n await cloneGitHubSubdirectory(\n 'https://github.com/CopilotKit/CopilotKit/tree/main/examples/coagents-starter/agent-js', \n path.join(process.cwd(), 'agent'),\n spinner\n );\n break;\n \n default:\n break;\n }\n } else if (userAnswers.agentFramework === 'CrewAI' && userAnswers.crewType === 'Flows') {\n spinner.text = chalk.cyan('Setting up CrewAI Flows agent...');\n await new Promise(resolve => setTimeout(resolve, 50));\n \n // CrewAI local flows scaffolding would go here when implemented\n spinner.info(chalk.yellow('CrewAI Flows support is coming soon...'));\n }\n \n spinner.succeed(chalk.green('AI agent setup complete'));\n } catch (error) {\n spinner.fail(chalk.red('Failed to set up AI agent'));\n throw error;\n }\n}\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":[]}
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' && \n parsedUrl.pathname.split('/').filter(Boolean).length >= 2;\n } catch {\n return false;\n }\n}\n"],"mappings":"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","names":[]}