galaxy-code 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.bundle.js +78 -349
- package/package.json +1 -1
package/dist/cli.bundle.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
2
|
+
var xt=Object.defineProperty;var i=(r,e)=>xt(r,"name",{value:e,configurable:!0});import Nn from"react";import{render as $n}from"ink";import Dn from"meow";import{config as wt}from"dotenv";import{fileURLToPath as Ct}from"node:url";import{dirname as Tt,join as bt}from"node:path";var Et=Ct(import.meta.url),vt=Tt(Et),_t=process.stdout.write,St=process.stderr.write,At=console.log,It=console.info;process.stdout.write=()=>!0;process.stderr.write=()=>!0;console.log=()=>{};console.info=()=>{};wt({path:bt(vt,"..",".env"),debug:!1,override:!1});process.stdout.write=_t;process.stderr.write=St;console.log=At;console.info=It;import ne from"node:process";import _,{useMemo as it,useState as B,useEffect as rn}from"react";import{Box as N,Static as sn,Text as j,useApp as an,useInput as cn}from"ink";import ln from"ink-text-input";import pn from"ink-spinner";import un from"figlet";import{GoogleGenAI as Ht,Type as F}from"@google/genai";import{Ollama as kt}from"ollama";var W=class{static{i(this,"OllamaConnection")}ollama;model="deepseek-v3.1:671b-cloud";constructor(e){this.model=e?.model??this.model;let t=e?.host??"https://ollama.com",n=t==="https://ollama.com"||t.includes("ollama.com"),o=e?.apiKey;this.ollama=new kt({host:t,headers:n?{Authorization:"Bearer "+o}:{}})}async generate(e){return await this.ollama.generate({model:e.model||this.model,prompt:e.prompt,system:e.system,stream:!1})}async chat(e){return(await this.ollama.chat({model:this.model,messages:[{role:"user",content:e}],stream:!1})).message.content}async chatWithTools(e){return await this.ollama.chat({model:e.model,messages:e.messages,tools:e.tools,stream:!1})}};var Ge=`You are an EXPERT BUSINESS ANALYST for IT projects.
|
|
3
3
|
|
|
4
4
|
# Your Role:
|
|
5
5
|
Analyze user requests and create COMPREHENSIVE project specifications including:
|
|
@@ -141,272 +141,23 @@ CRITICAL:
|
|
|
141
141
|
- COMPREHENSIVE MVP features
|
|
142
142
|
- Use user's language throughout
|
|
143
143
|
- SPECIFIC technical recommendations
|
|
144
|
-
- Realistic feature prioritization`;var
|
|
144
|
+
- Realistic feature prioritization`;var me=class{static{i(this,"BAITAnalyzer")}ollama=null;model="gpt-oss:120b-cloud";constructor(){}getConnection(){return this.ollama||(this.ollama=new W({model:this.model})),this.ollama}async analyze(e,t){let n=`User Request: ${e}`;t&&(n+=`
|
|
145
145
|
|
|
146
146
|
Additional Context:
|
|
147
|
-
${t}`);let o=await this.getConnection().generate({prompt:n,system:
|
|
147
|
+
${t}`);let o=await this.getConnection().generate({prompt:n,system:Ge,model:this.model}),s=this.extractJSON(o.response);if(!s)throw new Error("Failed to extract JSON from BA analysis response");return JSON.parse(s)}extractJSON(e){let t=e.trim();t=t.replace(/```json\s*/g,""),t=t.replace(/```\s*/g,"");let n=t.indexOf("{");if(n===-1)return null;let o=0,s=!1,a=!1;for(let l=n;l<t.length;l++){let u=t[l];if(a){a=!1;continue}if(u==="\\"){a=!0;continue}if(u==='"'&&!a){s=!s;continue}if(!s){if(u==="{")o++;else if(u==="}"&&(o--,o===0))return t.substring(n,l+1)}}return null}};import{exec as Pt}from"child_process";import{promisify as Ot}from"util";import de from"fs/promises";import _e from"path";var Nt=Ot(Pt),ge=class{static{i(this,"CommandRunner")}async runCommand(e,t,n=18e4){try{let{stdout:o,stderr:s}=await Nt(e,{cwd:t,timeout:n,maxBuffer:10485760});return{stdout:o,stderr:s,exitCode:0,command:e}}catch(o){return{stdout:o.stdout||"",stderr:o.stderr||o.message,exitCode:o.code||1,command:e}}}async detectTestCommand(e){try{let t=_e.join(e,"package.json"),n=await de.readFile(t,"utf-8"),o=JSON.parse(n);if(o.scripts?.test)return o.scripts.test;let s=await this.detectPackageManager(e);return s==="bun"?"bun test":s==="pnpm"?"pnpm test":s==="yarn"?"yarn test":"npm test"}catch{return null}}async detectDevCommand(e){try{let t=_e.join(e,"package.json"),n=await de.readFile(t,"utf-8"),o=JSON.parse(n);if(o.scripts?.dev)return o.scripts.dev;if(o.scripts?.start)return o.scripts.start;let s=await this.detectPackageManager(e);return s==="bun"?"bun run dev":s==="pnpm"?"pnpm dev":s==="yarn"?"yarn dev":"npm run dev"}catch{return null}}async detectBuildCommand(e){try{let t=_e.join(e,"package.json"),n=await de.readFile(t,"utf-8");if(JSON.parse(n).scripts?.build){let s=await this.detectPackageManager(e);return s==="bun"?"bun run build":s==="pnpm"?"pnpm build":s==="yarn"?"yarn build":"npm run build"}return null}catch{return null}}async detectPackageManager(e){try{let t=await de.readdir(e);return t.includes("bun.lockb")?"bun":t.includes("pnpm-lock.yaml")?"pnpm":t.includes("yarn.lock")?"yarn":"npm"}catch{return"bun"}}async installDependencies(e){let t=await this.detectPackageManager(e),n=t==="npm"?"npm install":t==="yarn"?"yarn install":t==="pnpm"?"pnpm install":"bun install";return this.runCommand(n,e,18e4)}};import{exec as $t}from"child_process";import{promisify as Dt}from"util";var fe=Dt($t),ye=class{static{i(this,"DocumentParser")}async parseDocument(e,t){try{switch(t){case"pdf":return await this.parsePDF(e);case"docx":return await this.parseDOCX(e);case"xlsx":return await this.parseXLSX(e);default:throw new Error(`Unsupported document type: ${t}`)}}catch(n){return`Failed to parse document: ${n.message}`}}async parsePDF(e){try{let{stdout:t}=await fe(`pdftotext "${e}" -`,{timeout:3e4,maxBuffer:10485760});return t||"No text content found in PDF"}catch(t){if(t.message.includes("command not found"))return"PDF parsing requires pdftotext (install: apt-get install poppler-utils)";throw t}}async parseDOCX(e){try{let{stdout:t}=await fe(`pandoc "${e}" -t plain`,{timeout:3e4,maxBuffer:10485760});return t||"No text content found in DOCX"}catch(t){if(t.message.includes("command not found"))return"DOCX parsing requires pandoc (install: apt-get install pandoc)";throw t}}async parseXLSX(e){try{let{stdout:t}=await fe(`ssconvert "${e}" fd://1`,{timeout:3e4,maxBuffer:10485760});return t||"No content found in XLSX"}catch(t){if(t.message.includes("command not found"))return"XLSX parsing requires ssconvert (install: apt-get install gnumeric)";throw t}}async checkDependencies(){let e=i(async t=>{try{return await fe(`which ${t}`,{timeout:1e3}),!0}catch{return!1}},"checkCommand");return{pdf:await e("pdftotext"),docx:await e("pandoc"),xlsx:await e("ssconvert")}}};import G from"fs/promises";import J from"path";import{exec as Ut}from"child_process";import{promisify as Lt}from"util";import se from"os";var Y=Lt(Ut),he=class{static{i(this,"FileOperations")}async readFile(e){try{return await G.readFile(e,"utf-8")}catch(t){throw new Error(`Failed to read file ${e}: ${t.message}`)}}async writeFile(e,t){try{let n=!1,o;try{o=await G.readFile(e,"utf-8")}catch{n=!0}await G.mkdir(J.dirname(e),{recursive:!0}),await G.writeFile(e,t,"utf-8");let s=t.split(`
|
|
148
148
|
`),a=o?o.split(`
|
|
149
|
-
`):[],
|
|
150
|
-
`).filter(Boolean)}else return(await
|
|
151
|
-
`).filter(Boolean)}}catch{return[]}}async getFileDiff(e){try{let{stdout:t}=await
|
|
152
|
-
`)}else{let{stdout:t}=await
|
|
153
|
-
|
|
154
|
-
# Working Directory: ${process.cwd()}
|
|
155
|
-
|
|
156
|
-
# Your Role
|
|
157
|
-
Analyze user request and create actionable execution plan with 3-7 steps.
|
|
158
|
-
|
|
159
|
-
# Input
|
|
160
|
-
User Context: Simple description of what to build/implement
|
|
161
|
-
Example: "Create a todo app with Next.js" or "Add authentication to existing app"
|
|
162
|
-
|
|
163
|
-
# Output Schema
|
|
164
|
-
Output ONLY valid JSON (no markdown, no \`\`\`json wrapper):
|
|
165
|
-
|
|
166
|
-
\`\`\`json
|
|
167
|
-
{
|
|
168
|
-
"summary": "Brief plan description",
|
|
169
|
-
"steps": [
|
|
170
|
-
{
|
|
171
|
-
"step": 1,
|
|
172
|
-
"action": "Clear action description",
|
|
173
|
-
"tool": "tool_name",
|
|
174
|
-
"reasoning": "Why this step"
|
|
175
|
-
}
|
|
176
|
-
],
|
|
177
|
-
"estimatedTime": "quick|medium|long"
|
|
178
|
-
}
|
|
179
|
-
\`\`\`
|
|
180
|
-
|
|
181
|
-
# Available Tools
|
|
182
|
-
|
|
183
|
-
**project_init:**
|
|
184
|
-
- command_run: Execute shell commands (npx create-*, npm init, git commands)
|
|
185
|
-
- install_dependencies: Install packages from package.json
|
|
186
|
-
|
|
187
|
-
**code_operations:**
|
|
188
|
-
- file_tree: View project structure
|
|
189
|
-
- file_read: Read file contents
|
|
190
|
-
- file_write: Create/update files
|
|
191
|
-
- file_delete: Remove files
|
|
192
|
-
|
|
193
|
-
**testing:**
|
|
194
|
-
- test_run: Execute test suite (only if System Context: Test Planning=ON)
|
|
195
|
-
|
|
196
|
-
**version_control:**
|
|
197
|
-
- git_commit: Commit changes with conventional message
|
|
198
|
-
|
|
199
|
-
# Planning Strategy
|
|
200
|
-
|
|
201
|
-
## NEW Projects
|
|
202
|
-
\`\`\`
|
|
203
|
-
1. command_run: Initialize project (create-next-app, create-vite, etc.)
|
|
204
|
-
2. install_dependencies: Add required packages
|
|
205
|
-
3. file_write: Core pages/components
|
|
206
|
-
4. file_write: Additional features
|
|
207
|
-
5. test_run: Run tests (if Test Planning=ON)
|
|
208
|
-
6. git_commit: Save implementation
|
|
209
|
-
\`\`\`
|
|
210
|
-
|
|
211
|
-
## ADD Features (Existing)
|
|
212
|
-
\`\`\`
|
|
213
|
-
1. file_tree: Understand structure
|
|
214
|
-
2. file_read: Check existing code (if needed)
|
|
215
|
-
3. install_dependencies: Add new packages (if needed)
|
|
216
|
-
4. file_write: Implement feature
|
|
217
|
-
5. test_run: Verify changes (if Test Planning=ON)
|
|
218
|
-
6. git_commit: Save changes
|
|
219
|
-
\`\`\`
|
|
220
|
-
|
|
221
|
-
# Planning Rules
|
|
222
|
-
|
|
223
|
-
1. **Step Count**: 3-7 steps (balance detail vs simplicity)
|
|
224
|
-
2. **Logical Order**: Setup \u2192 Dependencies \u2192 Implementation \u2192 Testing \u2192 Commit
|
|
225
|
-
3. **System Context** (optional in input):
|
|
226
|
-
- Test Planning=ON \u2192 Include test_run step
|
|
227
|
-
- Test Planning=OFF \u2192 Skip test_run step
|
|
228
|
-
4. **Time Estimates**:
|
|
229
|
-
- quick: 1-3 steps (<30min)
|
|
230
|
-
- medium: 4-6 steps (30min-2h)
|
|
231
|
-
- long: 7+ steps (>2h)
|
|
232
|
-
|
|
233
|
-
# Example 1: NEW Project
|
|
234
|
-
|
|
235
|
-
Input:
|
|
236
|
-
\`\`\`
|
|
237
|
-
User Context: Create a todo app with Next.js and TypeScript
|
|
238
|
-
\`\`\`
|
|
239
|
-
|
|
240
|
-
Output:
|
|
241
|
-
\`\`\`json
|
|
242
|
-
{
|
|
243
|
-
"summary": "Build Next.js todo app with TypeScript",
|
|
244
|
-
"steps": [
|
|
245
|
-
{
|
|
246
|
-
"step": 1,
|
|
247
|
-
"action": "Initialize Next.js project with TypeScript",
|
|
248
|
-
"tool": "command_run",
|
|
249
|
-
"reasoning": "Setup project foundation"
|
|
250
|
-
},
|
|
251
|
-
{
|
|
252
|
-
"step": 2,
|
|
253
|
-
"action": "Create TodoList component with CRUD operations",
|
|
254
|
-
"tool": "file_write",
|
|
255
|
-
"reasoning": "Core todo functionality"
|
|
256
|
-
},
|
|
257
|
-
{
|
|
258
|
-
"step": 3,
|
|
259
|
-
"action": "Create TodoItem component with state management",
|
|
260
|
-
"tool": "file_write",
|
|
261
|
-
"reasoning": "Individual todo UI and logic"
|
|
262
|
-
},
|
|
263
|
-
{
|
|
264
|
-
"step": 4,
|
|
265
|
-
"action": "Create main page integrating TodoList",
|
|
266
|
-
"tool": "file_write",
|
|
267
|
-
"reasoning": "App entry point"
|
|
268
|
-
},
|
|
269
|
-
{
|
|
270
|
-
"step": 5,
|
|
271
|
-
"action": "Commit changes: 'feat: initial todo app'",
|
|
272
|
-
"tool": "git_commit",
|
|
273
|
-
"reasoning": "Save implementation"
|
|
274
|
-
}
|
|
275
|
-
],
|
|
276
|
-
"estimatedTime": "medium"
|
|
277
|
-
}
|
|
278
|
-
\`\`\`
|
|
279
|
-
|
|
280
|
-
# Example 2: ADD Feature
|
|
281
|
-
|
|
282
|
-
Input:
|
|
283
|
-
\`\`\`
|
|
284
|
-
User Context: Add user authentication to existing Express app
|
|
285
|
-
\`\`\`
|
|
286
|
-
|
|
287
|
-
Output:
|
|
288
|
-
\`\`\`json
|
|
289
|
-
{
|
|
290
|
-
"summary": "Add JWT authentication to Express app",
|
|
291
|
-
"steps": [
|
|
292
|
-
{
|
|
293
|
-
"step": 1,
|
|
294
|
-
"action": "Check existing project structure",
|
|
295
|
-
"tool": "file_tree",
|
|
296
|
-
"reasoning": "Understand current architecture"
|
|
297
|
-
},
|
|
298
|
-
{
|
|
299
|
-
"step": 2,
|
|
300
|
-
"action": "Install JWT and bcrypt packages",
|
|
301
|
-
"tool": "install_dependencies",
|
|
302
|
-
"reasoning": "Required for authentication"
|
|
303
|
-
},
|
|
304
|
-
{
|
|
305
|
-
"step": 3,
|
|
306
|
-
"action": "Create User model and authentication routes",
|
|
307
|
-
"tool": "file_write",
|
|
308
|
-
"reasoning": "Backend auth logic"
|
|
309
|
-
},
|
|
310
|
-
{
|
|
311
|
-
"step": 4,
|
|
312
|
-
"action": "Create authentication middleware",
|
|
313
|
-
"tool": "file_write",
|
|
314
|
-
"reasoning": "Route protection"
|
|
315
|
-
},
|
|
316
|
-
{
|
|
317
|
-
"step": 5,
|
|
318
|
-
"action": "Run tests for auth flow",
|
|
319
|
-
"tool": "test_run",
|
|
320
|
-
"reasoning": "Verify implementation (if Test Planning=ON)"
|
|
321
|
-
},
|
|
322
|
-
{
|
|
323
|
-
"step": 6,
|
|
324
|
-
"action": "Commit changes: 'feat: add JWT authentication'",
|
|
325
|
-
"tool": "git_commit",
|
|
326
|
-
"reasoning": "Save feature"
|
|
327
|
-
}
|
|
328
|
-
],
|
|
329
|
-
"estimatedTime": "medium"
|
|
330
|
-
}
|
|
331
|
-
\`\`\`
|
|
332
|
-
|
|
333
|
-
# Critical Reminders
|
|
334
|
-
- **JSON Only**: Start with { and end with } (no markdown wrappers)
|
|
335
|
-
- **English Only**: All text fields in English
|
|
336
|
-
- **Be Specific**: Clear action descriptions (not "implement feature", but "Create TodoList component")
|
|
337
|
-
- **Realistic Steps**: Don't over-plan (3-7 steps max)
|
|
338
|
-
- **Tool Correctness**: Use appropriate tool for each step
|
|
339
|
-
- **Test Conditional**: Only include test_run if Test Planning=ON in input`,"planningSystemPrompt");var de=class{static{i(this,"PlanningAgent")}gemini=null;model="gemini-2.5-flash";constructor(){}getConnection(e){if(!this.gemini){let t=process.env.GOOGLE_AI_API_KEY||process.env.GEMINI_API_KEY;if(!t)throw new Error("PlanningAgent requires GOOGLE_AI_API_KEY or GEMINI_API_KEY in environment variables");this.gemini=new W({type:"gemini",model:this.model,apiKey:t},e)}return this.gemini}async generatePlan(e,t){try{let n=`User Context: ${e}`;if(t){let c=t.ba_it_analyze_response.result;n+=`
|
|
340
|
-
|
|
341
|
-
BA Analysis:
|
|
342
|
-
${JSON.stringify({type:c.type,projectName:c.projectName,coreFeatures:c.coreFeatures.map(u=>u.name),technicalStack:c.technicalStack},null,2)}`}let o=Oe(),s=await this.getConnection(o).generate({prompt:n}),a=this.extractJSON(s.text);return a?JSON.parse(a):this.createFallbackPlan(e)}catch{return this.createFallbackPlan(e)}}extractJSON(e){let t=e.trim();t=t.replace(/```json\s*/g,""),t=t.replace(/```\s*/g,"");let n=t.indexOf("{");if(n===-1)return null;let o=0,s=!1,a=!1;for(let p=n;p<t.length;p++){let c=t[p];if(a){a=!1;continue}if(c==="\\"){a=!0;continue}if(c==='"'&&!a){s=!s;continue}if(!s){if(c==="{")o++;else if(c==="}"&&(o--,o===0))return t.substring(n,p+1)}}return null}createFallbackPlan(e){return{summary:"Basic implementation plan",steps:[{step:1,action:"Check project structure",status:"pending",tool:"file_tree",reasoning:"Understand existing codebase"},{step:2,action:`Implement: ${e}`,status:"pending",tool:"file_write",reasoning:"Create necessary files"},{step:3,action:"Test implementation",status:"pending",tool:"test_run",reasoning:"Verify functionality"}],estimatedTime:"medium"}}};var me=class{static{i(this,"CodeGenerateAgent")}ollama=null;model="qwen3-coder:480b-cloud";constructor(){}getConnection(){return this.ollama||(this.ollama=new U({model:this.model})),this.ollama}async execute(e){try{let t=this.buildSystemPrompt(),n=this.buildUserPrompt(e),o=await this.getConnection().generate({prompt:n,system:t,model:this.model}),s=this.parseActionPlan(o.response);return{step:e.step,featureName:e.featureName,actions:s}}catch{return{step:e.step,featureName:e.featureName,actions:[]}}}buildSystemPrompt(){return`You are an EXPERT CODE GENERATION PLANNER.
|
|
343
|
-
|
|
344
|
-
# Your Mission:
|
|
345
|
-
Generate a detailed action plan for implementing a feature. You do NOT execute - only plan.
|
|
346
|
-
|
|
347
|
-
# Available Actions:
|
|
348
|
-
1. read_file - Read existing file for context
|
|
349
|
-
2. write_file - Create/update a file
|
|
350
|
-
3. run_command - Execute shell command
|
|
351
|
-
4. search_files - Search for pattern in files
|
|
352
|
-
|
|
353
|
-
# Planning Guidelines:
|
|
354
|
-
1. Start by reading relevant existing files
|
|
355
|
-
2. Plan all necessary file writes (components, APIs, types, tests, etc.)
|
|
356
|
-
3. Include dependency installations if needed
|
|
357
|
-
4. Be thorough - include ALL files needed
|
|
358
|
-
|
|
359
|
-
# Code Quality Requirements:
|
|
360
|
-
- Production-ready, no TODOs or placeholders
|
|
361
|
-
- Full file content, not snippets
|
|
362
|
-
- Proper imports and exports
|
|
363
|
-
- Type safety (TypeScript)
|
|
364
|
-
- Error handling
|
|
365
|
-
- Comments for complex logic
|
|
366
|
-
- Follow framework best practices
|
|
367
|
-
|
|
368
|
-
# Output Format (VALID JSON ARRAY):
|
|
369
|
-
[
|
|
370
|
-
{"action": "read_file", "path": "package.json"},
|
|
371
|
-
{"action": "write_file", "path": "components/Feature.tsx", "content": "full content here"},
|
|
372
|
-
{"action": "write_file", "path": "api/feature.ts", "content": "full content here"},
|
|
373
|
-
{"action": "run_command", "command": "npm install new-package"}
|
|
374
|
-
]
|
|
375
|
-
|
|
376
|
-
CRITICAL:
|
|
377
|
-
- Output ONLY the JSON array, nothing else. Start with [ and end with ]
|
|
378
|
-
- Include full file content in "content" field, not placeholders`}buildUserPrompt(e){let t=`# Feature Implementation Plan Request
|
|
379
|
-
|
|
380
|
-
**Feature**: ${e.featureName}
|
|
381
|
-
**Description**: ${e.featureDescription}
|
|
382
|
-
**Priority**: ${e.priority}
|
|
383
|
-
|
|
384
|
-
## Technical Stack:
|
|
385
|
-
${JSON.stringify(e.technicalStack,null,2)}
|
|
386
|
-
`;return e.userStories&&e.userStories.length>0&&(t+=`
|
|
387
|
-
## User Stories:
|
|
388
|
-
`,e.userStories.forEach(n=>{t+=`- As ${n.as}, I want ${n.want}, so that ${n.so}
|
|
389
|
-
`})),e.dataModel&&e.dataModel.length>0&&(t+=`
|
|
390
|
-
## Data Model:
|
|
391
|
-
${JSON.stringify(e.dataModel,null,2)}
|
|
392
|
-
`),e.apiEndpoints&&e.apiEndpoints.length>0&&(t+=`
|
|
393
|
-
## API Endpoints:
|
|
394
|
-
`,e.apiEndpoints.forEach(n=>{t+=`- ${n.method} ${n.path}: ${n.description}
|
|
395
|
-
`})),e.acceptanceCriteria&&e.acceptanceCriteria.length>0&&(t+=`
|
|
396
|
-
## Acceptance Criteria:
|
|
397
|
-
`,e.acceptanceCriteria.forEach((n,o)=>{t+=`${o+1}. ${n}
|
|
398
|
-
`})),t+=`
|
|
399
|
-
## Working Directory: ${process.cwd()}
|
|
400
|
-
|
|
401
|
-
Generate the action plan as JSON array to implement this feature completely.`,t}parseActionPlan(e){let t=e.trim();t=t.replace(/```json\s*/g,""),t=t.replace(/```\s*/g,"");let n=t.indexOf("["),o=t.lastIndexOf("]");if(n===-1||o===-1)return console.warn("Invalid action plan format - no JSON array found"),[];let s=t.substring(n,o+1);try{return JSON.parse(s).filter(p=>p.action==="read_file"||p.action==="write_file"||p.action==="run_command"||p.action==="search_files")}catch(a){return console.warn(`Failed to parse action plan: ${a}`),[]}}};import{EventEmitter as _t}from"events";var Ce=class extends _t{static{i(this,"ToolEventEmitter")}constructor(){super(),this.setMaxListeners(100)}emitToolExecution(e){let t={...e,timestamp:Date.now()};this.emit("tool-execution",t)}onToolExecution(e){return this.on("tool-execution",e),()=>this.off("tool-execution",e)}},B=new Ce;var ge=class{static{i(this,"PlanDisplay")}displayPlan(e){B.emitToolExecution({toolName:"plan_display",content:JSON.stringify(e),status:"success"});let t=`\u{1F4CB} Execution Plan: ${e.summary}
|
|
149
|
+
`):[],l=0,u=0;if(n)l=s.length;else{u=a.length,l=s.length;let m=new Set(a),d=new Set(s),w=a.filter(E=>!d.has(E)),h=s.filter(E=>!m.has(E));u=w.length,l=h.length}return{isNewFile:n,oldContent:o,newContent:t,linesAdded:l,linesRemoved:u,path:e}}catch(n){throw new Error(`Failed to write file ${e}: ${n.message}`)}}async listFiles(e,t=!1){try{if(t)if(se.platform()==="win32"){let n=[],s=i(async a=>{if(!(n.length>=500))try{let l=await G.readdir(a,{withFileTypes:!0});for(let u of l){if(n.length>=500)break;let m=J.join(a,u.name);if(u.isDirectory()){let d=u.name.toLowerCase();if(d==="node_modules"||d===".git"||d==="dist"||d==="build")continue;await s(m)}else{let d=m.toLowerCase();!d.includes("node_modules")&&!d.includes(".git")&&!d.includes("dist")&&!d.includes("build")&&n.push(m)}}}catch{}},"walk");return await s(e),n.slice(0,500)}else{let{stdout:n}=await Y(`find "${e}" -type f -not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/dist/*" -not -path "*/build/*" | head -500`,{timeout:1e4});return n.trim().split(`
|
|
150
|
+
`).filter(Boolean)}else return(await G.readdir(e,{withFileTypes:!0})).filter(o=>o.isFile()).map(o=>J.join(e,o.name))}catch(n){throw new Error(`Failed to list files in ${e}: ${n.message}`)}}async searchFiles(e,t){try{if(se.platform()==="win32"){let n=[],s=i(async a=>{if(!(n.length>=100))try{let l=await G.readdir(a,{withFileTypes:!0});for(let u of l){if(n.length>=100)break;let m=J.join(a,u.name);if(u.isDirectory()){let d=u.name.toLowerCase();if(d==="node_modules"||d===".git"||d==="dist"||d==="build")continue;await s(m)}else{let d=J.extname(u.name).toLowerCase();if([".ts",".js",".tsx",".jsx",".json"].includes(d))try{(await G.readFile(m,"utf-8")).includes(t)&&n.push(m)}catch{}}}}catch{}},"searchInDirectory");return await s(e),n.slice(0,100)}else{let{stdout:n}=await Y(`grep -r "${t}" "${e}" --include="*.ts" --include="*.js" --include="*.tsx" --include="*.jsx" --include="*.json" --exclude-dir="node_modules" --exclude-dir=".git" --exclude-dir="dist" -l | head -100`,{timeout:1e4});return n.trim().split(`
|
|
151
|
+
`).filter(Boolean)}}catch{return[]}}async getFileDiff(e){try{let{stdout:t}=await Y(`git diff "${e}"`,{timeout:5e3});return t||"No changes"}catch(t){return`Not a git repository or file doesn't exist: ${t.message}`}}async applyPatch(e,t){try{let n=se.tmpdir(),o=J.join(n,`patch-${Date.now()}.patch`);await G.writeFile(o,t),se.platform()==="win32"?await Y(`patch "${e}" < "${o}"`,{timeout:5e3}):await Y(`patch "${e}" < "${o}"`,{timeout:5e3}),await G.unlink(o)}catch(n){throw new Error(`Failed to apply patch: ${n.message}`)}}async getFileTree(e){try{if(se.platform()==="win32"){let n=i(async(s,a=0)=>{if(a>3)return[];let l=[];try{let u=await G.readdir(s,{withFileTypes:!0});for(let m of u){let d=" ".repeat(a),w=m.name.toLowerCase();if(!(w==="node_modules"||w===".git"||w==="dist"||w==="build"||w===".venv"||w==="venv"||w==="ios"||w==="android"||w===".expo"))if(m.isDirectory()){l.push(`${d}${m.name}/`);let h=await n(J.join(s,m.name),a+1);l.push(...h)}else l.push(`${d}${m.name}`)}}catch{}return l},"buildTree");return(await n(e)).join(`
|
|
152
|
+
`)}else{let{stdout:t}=await Y(`tree -L 3 -I "node_modules|.git|dist|build|.venv|venv|ios|android|.expo" -a --charset ascii "${e}" 2>/dev/null || find "${e}" -maxdepth 3 -not -path "*/node_modules/*" -not -path "*/.git/*" | head -500`,{timeout:2e4});return t}}catch(t){return`Failed to generate file tree: ${t.message}`}}};import{exec as jt}from"child_process";import{promisify as Gt}from"util";var M=Gt(jt),xe=class{static{i(this,"GitOperations")}async getStatus(e){try{let{stdout:t}=await M("git status --short",{cwd:e,timeout:5e3});return t||"Working tree clean"}catch(t){return`Not a git repository: ${t.message}`}}async commit(e,t){try{await M("git add .",{cwd:e,timeout:5e3});let{stdout:n}=await M(`git commit -m "${t.replace(/"/g,'\\"')}"`,{cwd:e,timeout:1e4});return n}catch(n){return`Commit failed: ${n.message}`}}async push(e,t="origin",n){try{let o=n?` ${n}`:"",{stdout:s}=await M(`git push ${t}${o}`,{cwd:e,timeout:3e4});return s}catch(o){return`Push failed: ${o.message}`}}async pull(e,t="origin",n){try{let o=n?` ${n}`:"",{stdout:s}=await M(`git pull ${t}${o}`,{cwd:e,timeout:3e4});return s}catch(o){return`Pull failed: ${o.message}`}}async getDiff(e,t){try{let n=t?` "${t}"`:"",{stdout:o}=await M(`git diff${n}`,{cwd:e,timeout:1e4});return o||"No changes"}catch(n){return`Diff failed: ${n.message}`}}async getLog(e,t=10){try{let{stdout:n}=await M(`git log --oneline -${t}`,{cwd:e,timeout:5e3});return n}catch(n){return`Log failed: ${n.message}`}}async listBranches(e){try{let{stdout:t}=await M("git branch -a",{cwd:e,timeout:5e3});return t}catch(t){return`Branch list failed: ${t.message}`}}async createBranch(e,t){try{let{stdout:n}=await M(`git checkout -b "${t}"`,{cwd:e,timeout:5e3});return n}catch(n){return`Branch creation failed: ${n.message}`}}async switchBranch(e,t){try{let{stdout:n}=await M(`git checkout "${t}"`,{cwd:e,timeout:5e3});return n}catch(n){return`Branch switch failed: ${n.message}`}}};var we=class{static{i(this,"PlanDisplay")}displayPlan(e){let t=`\u{1F4CB} Execution Plan: ${e.summary}
|
|
402
153
|
`;return t+=`Estimated Time: ${e.estimatedTime||"medium"}
|
|
403
154
|
|
|
404
155
|
`,e.steps.forEach(n=>{let o=n.status==="completed"?"\u2705":n.status==="failed"?"\u274C":n.status==="in-progress"?"\u26A1":"\u23F3";t+=`${o} Step ${n.step}: ${n.action}
|
|
405
|
-
`}),t}updateProgress(e){
|
|
156
|
+
`}),t}updateProgress(e){let n=`${e.status==="completed"?"\u2705":e.status==="failed"?"\u274C":e.status==="in-progress"?"\u26A1":"\u23F3"} Step ${e.step}: ${e.status}
|
|
406
157
|
`;return e.message&&(n+=` ${e.message}
|
|
407
158
|
`),e.filesCreated&&e.filesCreated.length>0&&(n+=` \u{1F4DD} Files created: ${e.filesCreated.join(", ")}
|
|
408
159
|
`),e.commandsRun&&e.commandsRun.length>0&&(n+=` \u{1F527} Commands run: ${e.commandsRun.join(", ")}
|
|
409
|
-
`),n}};import{execa as
|
|
160
|
+
`),n}};import{execa as Me}from"execa";import{existsSync as ie}from"node:fs";import{join as Q,resolve as Z,isAbsolute as Fe}from"node:path";var Mt="https://unpkg.com/galaxy-design@latest/dist/registry.json",ae="https://galaxy-design.vercel.app",Ce={data:null,timestamp:0},Ft=300*1e3;function Se(r){return ie(Q(r,"yarn.lock"))?"yarn":ie(Q(r,"pnpm-lock.yaml"))?"pnpm":ie(Q(r,"bun.lockb"))?"bun":(ie(Q(r,"package-lock.json")),"npm")}i(Se,"detectPackageManager");function Ae(r){switch(r){case"yarn":return"yarn";case"bun":return"bunx";case"pnpm":return"pnpm";default:return"npx"}}i(Ae,"getPackageManagerExecCommand");function ee(r){let e=r;for(;e!=="/"&&e!==".";){if(ie(Q(e,"package.json")))return e;let t=Q(e,"..");if(t===e)break;e=t}return r}i(ee,"findProjectRoot");async function Te(){let r=Date.now();if(Ce.data&&r-Ce.timestamp<Ft)return Ce.data;try{let e={Accept:"application/vnd.github.v3.raw"},t=process.env.GITHUB_TOKEN;t&&(e.Authorization=`Bearer ${t}`);let n=await fetch(Mt,{headers:e});if(!n.ok)throw new Error(`Failed to fetch registry: ${n.statusText}`);let o=await n.json();return Ce={data:o,timestamp:r},o}catch(e){throw new Error(`Failed to fetch Galaxy UI registry: ${e instanceof Error?e.message:"Unknown error"}`)}}i(Te,"fetchRegistry");async function Re(r){let e=await Te(),t=Object.entries(e.components).map(([o,s])=>({name:o,description:s.description,category:s.type,docsUrl:`${ae}/components/${o}`})),n=r?.category&&r.category!=="all"?t.filter(o=>o.category===r.category):t;return{total:n.length,components:n}}i(Re,"galaxyUIListComponents");async function Be(r){let e=await Te(),t=r.query.toLowerCase(),n=Object.entries(e.components).map(([o,s])=>{let a=o.toLowerCase().includes(t),l=s.description.toLowerCase().includes(t),u=s.type.toLowerCase().includes(t),m="low";a?m="high":u?m="medium":l&&(m="low");let d=a||l||u;return{name:o,description:s.description,category:s.type,docsUrl:`${ae}/components/${o}`,relevance:m,isMatch:d}}).filter(o=>o.isMatch).sort((o,s)=>{let a={high:0,medium:1,low:2};return a[o.relevance]-a[s.relevance]});return{total:n.length,components:n}}i(Be,"galaxyUISearchComponents");async function He(r){let t=(await Te()).components[r.name];if(!t)throw new Error(`Component "${r.name}" not found. Use galaxy_ui_list_components or galaxy_ui_search_components to find available components.`);let n=`${ae}/components/${r.name}`,o=r.framework?`${n}?framework=${r.framework}`:void 0,s=r.cwd?ee(r.cwd)||r.cwd:ee(process.cwd())||process.cwd(),a=Se(s),l=Ae(a);return{name:r.name,description:t.description,category:t.type,dependencies:t.dependencies||[],peerDependencies:t.peerDependencies||[],docsUrl:n,docsUrlFramework:o,installCommand:`${l} galaxy-design add ${r.name}`}}i(He,"galaxyUIGetComponent");async function qe(r){let e=await Te(),t=new Map;for(let[o,s]of Object.entries(e.components)){let a=s.type;t.has(a)||t.set(a,[]),t.get(a).push(o)}return{categories:Array.from(t.entries()).map(([o,s])=>({name:o,count:s.length,components:s.sort()})).sort((o,s)=>s.count-o.count)}}i(qe,"galaxyUIGetCategories");async function We(r){try{let e=r.cwd?ee(r.cwd)||r.cwd:ee(process.cwd())||process.cwd(),t=Se(e),n=Ae(t),o=["galaxy-design","add",...r.components];if(r.cwd){let a=Fe(r.cwd)?Z(r.cwd):Z(process.cwd(),r.cwd),l=Z(e);a!==l&&o.push("--cwd",r.cwd)}let s=await Me(n,o,{cwd:e,stderr:"pipe",stdout:"pipe"});return{success:!0,message:`Successfully added components: ${r.components.join(", ")}`,output:s.stdout}}catch(e){let t=e;return{success:!1,message:`Failed to add components: ${r.components.join(", ")}`,output:t.stderr||t.stdout||"Unknown error"}}}i(We,"galaxyUIAddComponents");async function Je(r){try{let e=r?.cwd?ee(r.cwd)||r.cwd:ee(process.cwd())||process.cwd(),t=Se(e),n=Ae(t),o=["galaxy-design@latest","init","--yes"];if(r?.cwd){let a=Fe(r.cwd)?Z(r.cwd):Z(process.cwd(),r.cwd),l=Z(e);a!==l&&o.push("--cwd",r.cwd)}r?.skipPrompts&&o.push("--skip-prompts");let s=await Me(n,o,{cwd:e,stderr:"pipe",stdout:"pipe"});return{success:!0,message:`Successfully initialized Galaxy UI with ${t}`,output:s.stdout}}catch(e){let t=e;return{success:!1,message:"Failed to initialize Galaxy UI",output:t.stderr||t.stdout||"Unknown error"}}}i(Je,"galaxyUIInit");function Xe(r){if(r?.component){let t=r.language==="vi"?"/vi":"";return{url:`${ae}${t}/components/${r.component}`,description:`Documentation for ${r.component} component`}}let e=r?.language==="vi"?"/vi":"";return{url:`${ae}${e}`,description:"Galaxy UI CLI Documentation"}}i(Xe,"galaxyUIGetDocsUrl");import{existsSync as Ve,readFileSync as Ke}from"node:fs";import{join as ze}from"node:path";var be=class{static{i(this,"GalaxyDesignChecker")}async checkIntegration(e){try{let t=ze(e,"components.json");if(!Ve(t))return{isIntegrated:!1,error:"components.json file not found"};let n=Ke(t,"utf-8"),o=JSON.parse(n);if(!o.framework)return{isIntegrated:!1,error:"framework field not found in components.json"};let s=o.components?Object.keys(o.components):[];return{isIntegrated:!0,framework:o.framework,components:s}}catch(t){return{isIntegrated:!1,error:t instanceof Error?t.message:"Unknown error"}}}async getComponentDetails(e){try{let t=ze(e,"components.json");if(!Ve(t))return{components:[],total:0};let n=Ke(t,"utf-8"),o=JSON.parse(n);if(!o.components)return{components:[],total:0};let s=Object.entries(o.components).map(([a,l])=>({name:a,version:l.version,path:l.path}));return{components:s,total:s.length}}catch{return{components:[],total:0}}}};import{EventEmitter as Bt}from"events";var Ie=class extends Bt{static{i(this,"ToolEventEmitter")}constructor(){super(),this.setMaxListeners(100)}emitToolExecution(e){let t={...e,timestamp:Date.now()};this.emit("tool-execution",t)}onToolExecution(e){return this.on("tool-execution",e),()=>this.off("tool-execution",e)}},X=new Ie;var L=class{static{i(this,"ToolRegistry")}tools=new Map;fileOps=new he;gitOps=new xe;commandRunner=new ge;baAnalyzer=new me;documentParser=new ye;galaxyDesignChecker=new be;planDisplay=new we;constructor(){this.registerAllTools()}registerAllTools(){this.register({name:"file_read",description:"Read content of a file",inputSchema:{type:"object",properties:{path:{type:"string",description:"File path to read"}},required:["path"]},execute:i(async e=>await this.fileOps.readFile(e.path),"execute")}),this.register({name:"file_write",description:"Write content to a file (creates directories if needed)",inputSchema:{type:"object",properties:{path:{type:"string",description:"File path to write"},content:{type:"string",description:"Content to write"}},required:["path","content"]},execute:i(async e=>{let t=await this.fileOps.writeFile(e.path,e.content);return JSON.stringify(t)},"execute")}),this.register({name:"file_list",description:"List files in a directory",inputSchema:{type:"object",properties:{path:{type:"string",description:"Directory path"},recursive:{type:"boolean",description:"Recursive listing",default:!1}},required:["path"]},execute:i(async e=>(await this.fileOps.listFiles(e.path,e.recursive)).join(`
|
|
410
161
|
`),"execute")}),this.register({name:"file_search",description:"Search for pattern in files",inputSchema:{type:"object",properties:{path:{type:"string",description:"Directory to search in"},pattern:{type:"string",description:"Pattern to search for"}},required:["path","pattern"]},execute:i(async e=>(await this.fileOps.searchFiles(e.path,e.pattern)).join(`
|
|
411
162
|
`)||"No matches found","execute")}),this.register({name:"file_tree",description:"Get file tree structure of a directory",inputSchema:{type:"object",properties:{path:{type:"string",description:"Directory path"}},required:["path"]},execute:i(async e=>await this.fileOps.getFileTree(e.path),"execute")}),this.register({name:"git_status",description:"Get git status of repository",inputSchema:{type:"object",properties:{cwd:{type:"string",description:"Working directory"}},required:["cwd"]},execute:i(async e=>await this.gitOps.getStatus(e.cwd||process.cwd()),"execute")}),this.register({name:"git_commit",description:"Commit changes with message",inputSchema:{type:"object",properties:{cwd:{type:"string",description:"Working directory"},message:{type:"string",description:"Commit message"}},required:["cwd","message"]},execute:i(async e=>await this.gitOps.commit(e.cwd||process.cwd(),e.message),"execute")}),this.register({name:"git_push",description:"Push commits to remote",inputSchema:{type:"object",properties:{cwd:{type:"string",description:"Working directory"},remote:{type:"string",description:"Remote name",default:"origin"},branch:{type:"string",description:"Branch name (optional)"}},required:["cwd"]},execute:i(async e=>await this.gitOps.push(e.cwd||process.cwd(),e.remote||"origin",e.branch),"execute")}),this.register({name:"git_pull",description:"Pull changes from remote",inputSchema:{type:"object",properties:{cwd:{type:"string",description:"Working directory"},remote:{type:"string",description:"Remote name",default:"origin"},branch:{type:"string",description:"Branch name (optional)"}},required:["cwd"]},execute:i(async e=>await this.gitOps.pull(e.cwd||process.cwd(),e.remote||"origin",e.branch),"execute")}),this.register({name:"git_diff",description:"Show git diff",inputSchema:{type:"object",properties:{cwd:{type:"string",description:"Working directory"},file:{type:"string",description:"Specific file (optional)"}},required:["cwd"]},execute:i(async e=>await this.gitOps.getDiff(e.cwd||process.cwd(),e.file),"execute")}),this.register({name:"git_log",description:"Show git commit history",inputSchema:{type:"object",properties:{cwd:{type:"string",description:"Working directory"},limit:{type:"number",description:"Number of commits",default:10}},required:["cwd"]},execute:i(async e=>await this.gitOps.getLog(e.cwd||process.cwd(),e.limit||10),"execute")}),this.register({name:"git_branches",description:"List all branches",inputSchema:{type:"object",properties:{cwd:{type:"string",description:"Working directory"}},required:["cwd"]},execute:i(async e=>await this.gitOps.listBranches(e.cwd||process.cwd()),"execute")}),this.register({name:"command_run",description:"Run a shell command",inputSchema:{type:"object",properties:{command:{type:"string",description:"Command to execute"},cwd:{type:"string",description:"Working directory"},timeout:{type:"number",description:"Timeout in ms",default:6e4}},required:["command","cwd"]},execute:i(async e=>{let t=await this.commandRunner.runCommand(e.command,e.cwd||process.cwd(),e.timeout||6e4);return`stdout:
|
|
412
163
|
${t.stdout}
|
|
@@ -420,10 +171,10 @@ ${n.stderr}`},"execute")}),this.register({name:"install_dependencies",descriptio
|
|
|
420
171
|
${t.stdout}
|
|
421
172
|
|
|
422
173
|
Errors:
|
|
423
|
-
${t.stderr}`},"execute")}),this.register({name:"ba_it_analyze",description:"Business Analyst for IT projects. Analyzes user requirements and creates comprehensive project specifications with features, tech stack, user stories, data model, and recommendations.",inputSchema:{type:"object",properties:{userRequest:{type:"string",description:"User's project request or requirement"},context:{type:"string",description:"Additional context about the project (optional)"}},required:["userRequest"]},execute:i(async e=>await this.baAnalyzer.analyze(e.userRequest,e.context),"execute")}),this.register({name:"document_parse",description:"Parse document and extract text. Supports: pdf, docx, xlsx (auto-detected from file extension)",inputSchema:{type:"object",properties:{path:{type:"string",description:"Document file path"},type:{type:"string",description:"Type: pdf, docx, xlsx (optional, auto-detected)"}},required:["path"]},execute:i(async e=>{let t=e.type?.toLowerCase();if(!t){let n=e.path.split(".").pop()?.toLowerCase();t=(n==="doc"?"docx":n==="xls"?"xlsx":n)||"docx"}return["pdf","docx","xlsx"].includes(t||"")?await this.documentParser.parseDocument(e.path,t):`Error: Unsupported document type "${t}". Supported: PDF, DOCX, XLSX`},"execute")}),this.register({name:"plan_display",description:"Display execution plans and progress updates. Emits events via EventEmitter for UI tracking.",inputSchema:{type:"object",properties:{summary:{type:"string",description:"Plan summary"},steps:{type:"array",description:"Plan steps",items:{type:"object",properties:{step:{type:"number"},action:{type:"string"},status:{type:"string"},
|
|
174
|
+
${t.stderr}`},"execute")}),this.register({name:"ba_it_analyze",description:"Business Analyst for IT projects. Analyzes user requirements and creates comprehensive project specifications with features, tech stack, user stories, data model, and recommendations.",inputSchema:{type:"object",properties:{userRequest:{type:"string",description:"User's project request or requirement"},context:{type:"string",description:"Additional context about the project (optional)"}},required:["userRequest"]},execute:i(async e=>await this.baAnalyzer.analyze(e.userRequest,e.context),"execute")}),this.register({name:"document_parse",description:"Parse document and extract text. Supports: pdf, docx, xlsx (auto-detected from file extension)",inputSchema:{type:"object",properties:{path:{type:"string",description:"Document file path"},type:{type:"string",description:"Type: pdf, docx, xlsx (optional, auto-detected)"}},required:["path"]},execute:i(async e=>{let t=e.type?.toLowerCase();if(!t){let n=e.path.split(".").pop()?.toLowerCase();t=(n==="doc"?"docx":n==="xls"?"xlsx":n)||"docx"}return["pdf","docx","xlsx"].includes(t||"")?await this.documentParser.parseDocument(e.path,t):`Error: Unsupported document type "${t}". Supported: PDF, DOCX, XLSX`},"execute")}),this.register({name:"plan_display",description:"Display execution plans and progress updates. Emits events via EventEmitter for UI tracking.",inputSchema:{type:"object",properties:{summary:{type:"string",description:"Plan summary"},steps:{type:"array",description:"Plan steps",items:{type:"object",properties:{step:{type:"number"},action:{type:"string"},status:{type:"string"},reasoning:{type:"string"}},required:["step","action","status"]}},estimatedTime:{type:"string",description:"Estimated time: quick|medium|long"}},required:["summary","steps"]},execute:i(async e=>this.planDisplay.displayPlan(e),"execute")}),this.register({name:"progress_update",description:"Update progress for execution steps. Emits events via EventEmitter for UI tracking.",inputSchema:{type:"object",properties:{step:{type:"number",description:"Step number"},status:{type:"string",description:"Step status: pending, in-progress, completed, failed"},message:{type:"string",description:"Optional status message"},filesCreated:{type:"array",description:"List of files created in this step",items:{type:"string"}},commandsRun:{type:"array",description:"List of commands executed in this step",items:{type:"string"}}},required:["step","status"]},execute:i(async e=>this.planDisplay.updateProgress(e),"execute")}),this.register({name:"galaxy_design_check",description:"Check if Galaxy Design (Galaxy UI) is integrated in the project. Verifies components.json file and framework field.",inputSchema:{type:"object",properties:{cwd:{type:"string",description:"Project directory"}},required:["cwd"]},execute:i(async e=>{let t=await this.galaxyDesignChecker.checkIntegration(e.cwd||process.cwd());return JSON.stringify(t,null,2)},"execute")}),this.register({name:"galaxy_design_component_details",description:"Get detailed information about integrated Galaxy Design (Galaxy UI) components.",inputSchema:{type:"object",properties:{cwd:{type:"string",description:"Project directory"}},required:["cwd"]},execute:i(async e=>{let t=await this.galaxyDesignChecker.getComponentDetails(e.cwd||process.cwd());return JSON.stringify(t,null,2)},"execute")}),this.register({name:"galaxy_ui_list",description:"List all Galaxy UI components. Optional filter by category: form, layout, navigation, interactive, overlay, data-display, utility",inputSchema:{type:"object",properties:{category:{type:"string",description:"Filter by category: form, layout, navigation, interactive, overlay, data-display, utility, all"}}},execute:i(async e=>{let t=await Re(e);return JSON.stringify(t,null,2)},"execute")}),this.register({name:"galaxy_ui_search",description:"Search Galaxy Desgin (Galaxy UI) components by keyword in name, description, or category",inputSchema:{type:"object",properties:{query:{type:"string",description:"Search query"}},required:["query"]},execute:i(async e=>{let t=await Be(e);return JSON.stringify(t,null,2)},"execute")}),this.register({name:"galaxy_ui_get_component",description:"Get detailed information about a specific Galaxy Desgin (Galaxy UI) component including dependencies, docs URL, and install command",inputSchema:{type:"object",properties:{name:{type:"string",description:"Component name"},framework:{type:"string",description:"Framework: vue, react, angular, flutter, react native"}},required:["name"]},execute:i(async e=>{let t=await He(e);return JSON.stringify(t,null,2)},"execute")}),this.register({name:"galaxy_ui_categories",description:"Get all Galaxy Desgin (Galaxy UI) component categories with component counts",inputSchema:{type:"object",properties:{}},execute:i(async()=>{let e=await qe();return JSON.stringify(e,null,2)},"execute")}),this.register({name:"galaxy_ui_add",description:"Add Galaxy Desgin (Galaxy UI) components to the project. Automatically detects and uses the project's package manager (npm, yarn, bun, pnpm)",inputSchema:{type:"object",properties:{components:{type:"array",description:"Array of component names to add",items:{type:"string"}},cwd:{type:"string",description:"Working directory (optional)"}},required:["components"]},execute:i(async e=>{let t=await We(e);return JSON.stringify(t,null,2)},"execute")}),this.register({name:"galaxy_ui_init",description:"Initialize Galaxy Desgin (Galaxy UI) in the project. Automatically detects and uses the project's package manager (npm, yarn, bun, pnpm). Also automatically installs Tailwind CSS v3 dependencies.",inputSchema:{type:"object",properties:{cwd:{type:"string",description:"Working directory (optional)"},skipPrompts:{type:"boolean",description:"Skip prompts and use defaults (optional)"}}},execute:i(async e=>{let t=await Je(e);return JSON.stringify(t,null,2)},"execute")}),this.register({name:"galaxy_ui_docs",description:"Get documentation URL for Galaxy Desgin (Galaxy UI) components or main documentation",inputSchema:{type:"object",properties:{component:{type:"string",description:"Component name (optional)"},language:{type:"string",description:"Language: en or vi (optional)"}}},execute:i(async e=>{let t=Xe(e);return JSON.stringify(t,null,2)},"execute")})}register(e){if(this.tools.has(e.name))throw new Error(`Tool with name "${e.name}" is already registered.`);this.tools.set(e.name,e)}get(e){return this.tools.get(e)}list(){return[...this.tools.values()]}getToolsContext(e){return`Available Tools:
|
|
424
175
|
${e.map(n=>this.tools.get(n)).map(n=>`- ${n?.name}: ${n?.description}`).join(`
|
|
425
176
|
`)}
|
|
426
|
-
`}getToolsByNames(e){return e?.map(t=>this.tools.get(t)).filter(t=>t!==void 0)||[...this.tools.values()]}async executeTool(e,t){let n=this.tools.get(e);if(!n)throw new Error(`Tool "${e}" not found in registry`);try{let o={},s=await n.execute(t,o),a=typeof s=="string"?s:JSON.stringify(s);return
|
|
177
|
+
`}getToolsByNames(e){return e?.map(t=>this.tools.get(t)).filter(t=>t!==void 0)||[...this.tools.values()]}async executeTool(e,t){let n=this.tools.get(e);if(!n)throw new Error(`Tool "${e}" not found in registry`);try{let o={},s=await n.execute(t,o),a=typeof s=="string"?s:JSON.stringify(s);return X.emitToolExecution({toolName:e,content:a,status:"success",toolInfo:{toolName:e,args:t,result:s}}),s}catch(o){let s=o instanceof Error?o.message:String(o);throw X.emitToolExecution({toolName:e,content:`Error: ${s}`,status:"error",error:s,toolInfo:{toolName:e,args:t}}),o}}},Ye=new L;var qt="gemini-2.5-flash",V=class{static{i(this,"GeminiConnection")}client;apiKey;chatSession;systemInstruction;model;toolsRegistry=Ye;constructor(e,t){this.apiKey=e?.apiKey,this.model=e?.model??"gemini-2.5-flash",this.client=new Ht({apiKey:this.apiKey}),this.systemInstruction=t,this.initChat()}initChat(){this.chatSession=this.client.chats.create({model:this.model,config:{systemInstruction:this.systemInstruction,tools:[{functionDeclarations:this.getToolDeclarations()}],temperature:.7,thinkingConfig:{thinkingBudget:0}}})}async generate(e){let t=await this.client.models.generateContent({model:qt,contents:e.prompt});return{text:t.text??"",raw:t}}async chat(e,t){if(!this.chatSession)throw new Error("Chat session is not initialized.");let n=e,o,s=0,a=15;for(;n&&s<a;)if(s++,o=await this.chatSession.sendMessage({message:n}),o.functionCalls&&o.functionCalls.length>0){let l=[];for(let u of o.functionCalls)try{let m=u.name||"unknown",d=u.args||{},w=await this.toolsRegistry.executeTool(m,d),h=typeof w=="string"?w:JSON.stringify(w);t&&t("tool",h,m,{toolName:m,args:d,result:w}),l.push({functionResponse:{name:u.name,response:{result:h}}})}catch(m){let d=m instanceof Error?m.message:String(m);if(t){let w={toolName:u.name||"unknown",args:u.args||{},result:`\u274C Error: ${d}`};t("tool",`\u274C Error: ${d}`,u.name,w)}l.push({functionResponse:{name:u.name,response:{error:d}}})}n=l}else return o.text??"";if(s>=a)throw console.warn(`\u26A0\uFE0F Max iterations (${a}) reached. This may indicate:`),console.warn(" - Too many sequential tool calls"),console.warn(" - AI stuck in a reasoning loop"),console.warn(" - Consider reviewing system prompt or tool definitions"),new Error(`Max iterations (${a}) reached`);return""}getToolDeclarations(){return this.toolsRegistry.list().map(t=>this.convertToFunctionDeclaration(t))}convertToFunctionDeclaration(e){return{name:e.name,description:e.description,parameters:this.convertSchemaToGeminiSchema(e.inputSchema)}}convertSchemaToGeminiSchema(e){if(!e)return{type:F.OBJECT,properties:{}};let t={type:F.OBJECT,properties:{}};if(e.properties){t.properties={};for(let[n,o]of Object.entries(e.properties)){let s=o;t.properties[n]=this.convertPropertyToGeminiSchema(s)}}return e.required&&(t.required=e.required),t}convertPropertyToGeminiSchema(e){let t={type:this.mapTypeToGemini(e.type),description:e.description||""};if(e.type==="object"&&e.properties){t.properties={};for(let[n,o]of Object.entries(e.properties))t.properties[n]=this.convertPropertyToGeminiSchema(o);e.required&&(t.required=e.required)}return e.type==="array"&&(e.items&&typeof e.items=="object"?t.items=this.convertPropertyToGeminiSchema(e.items):t.items={type:F.STRING,description:""}),t}mapTypeToGemini(e){return{string:F.STRING,number:F.NUMBER,integer:F.INTEGER,boolean:F.BOOLEAN,object:F.OBJECT,array:F.ARRAY}[e.toLowerCase()]||F.STRING}};import Wt from"@anthropic-ai/sdk";var Ee=class{static{i(this,"ClaudeConnection")}client;model;conversationHistory=[];conversationHistoryWithTools=[];systemPrompt;toolsRegistry=new L;constructor(e,t){let n=e?.apiKey;this.client=new Wt({apiKey:n}),this.model=e?.model||"claude-sonnet-4.5-20250929",this.systemPrompt=t}async chat(e){this.conversationHistory.push({role:"user",content:e});try{let t=await this.client.messages.create({model:this.model,max_tokens:8192,system:this.systemPrompt,messages:this.conversationHistory}),n=t.content[0]?.type==="text"?t.content[0].text:"";return this.conversationHistory.push({role:"assistant",content:n}),n}catch(t){throw console.error("Claude API Error:",t),t}}async*chatStream(e){this.conversationHistory.push({role:"user",content:e});try{let t=await this.client.messages.create({model:this.model,max_tokens:8192,system:this.systemPrompt,messages:this.conversationHistory,stream:!0}),n="";for await(let o of t)if(o.type==="content_block_delta"&&o.delta.type==="text_delta"){let s=o.delta.text||"";n+=s,yield s}this.conversationHistory.push({role:"assistant",content:n})}catch(t){throw console.error("Claude Stream Error:",t),t}}async generate(e,t){try{let n=await this.client.messages.create({model:this.model,max_tokens:8192,system:t||this.systemPrompt,messages:[{role:"user",content:e}]});return n.content[0]?.type==="text"?n.content[0].text:""}catch(n){throw console.error("Claude Generate Error:",n),n}}clearHistory(){this.conversationHistory=[]}getHistory(){return[...this.conversationHistory]}setSystemPrompt(e){this.systemPrompt=e}getModel(){return this.model}setModel(e){this.model=e}async chatWithTools(e,t,n){this.conversationHistoryWithTools.push({role:"user",content:e});let o=0,s=100;for(;o<s;){o++;let a=await this.client.messages.create({model:this.model,max_tokens:8192,system:this.systemPrompt,messages:this.conversationHistoryWithTools,tools:t});if(a.stop_reason!=="tool_use")return this.conversationHistoryWithTools.push({role:"assistant",content:a.content}),a.content.find(m=>m.type==="text")?.text||"";this.conversationHistoryWithTools.push({role:"assistant",content:a.content});let l=[];for(let u of a.content)if(u.type==="tool_use"){let m=u,d=m.name,w=m.input;if(d==="plan_task"||d==="progress_reporter")try{let h=await this.toolsRegistry.executeTool(d,w),E=typeof h=="string"?h:JSON.stringify(h);l.push({type:"tool_result",tool_use_id:m.id,content:E})}catch(h){let E=h instanceof Error?h.message:String(h);l.push({type:"tool_result",tool_use_id:m.id,content:`Error: ${E}`,is_error:!0})}else try{let h=await this.toolsRegistry.executeTool(d,w),E=typeof h=="string"?h:JSON.stringify(h);if(n){let I=!E.startsWith("\u274C");n("tool",E,d,{success:I,output:E})}l.push({type:"tool_result",tool_use_id:m.id,content:E})}catch(h){let E=h instanceof Error?h.message:String(h);n&&n("tool",`\u274C Error: ${E}`,d,{success:!1,error:E}),l.push({type:"tool_result",tool_use_id:m.id,content:`Error: ${E}`,is_error:!0})}}this.conversationHistoryWithTools.push({role:"user",content:l})}return console.warn(`\u26A0\uFE0F Safety limit (${s}) reached in Claude tool loop.`),"Maximum iteration limit reached. Please try again."}clearToolHistory(){this.conversationHistoryWithTools=[]}};function te(r){return`You are Galaxy AI - software development expert by kevinbui.
|
|
427
178
|
|
|
428
179
|
# Response Language
|
|
429
180
|
**Match user's language exactly** (detect from their input)
|
|
@@ -433,98 +184,76 @@ ${r}
|
|
|
433
184
|
|
|
434
185
|
# Planning & Execution Workflow
|
|
435
186
|
|
|
436
|
-
##
|
|
437
|
-
|
|
187
|
+
## Always Plan First
|
|
188
|
+
For every task, ALWAYS create and display an execution plan before starting implementation.
|
|
438
189
|
|
|
439
190
|
## Execution Loop
|
|
440
191
|
\`\`\`
|
|
441
192
|
1. Analyze user request and create execution plan
|
|
442
193
|
2. Display plan using plan_display tool
|
|
443
194
|
3. Execute each step with appropriate tools
|
|
444
|
-
4. Update progress using progress_update tool
|
|
195
|
+
4. Update progress using progress_update tool AFTER completing each PLAN STEP
|
|
445
196
|
5. All steps complete \u2192 Done
|
|
446
197
|
\`\`\`
|
|
447
198
|
|
|
448
199
|
## Plan Display and Progress Update
|
|
449
|
-
**YOU MUST display plan using plan_display tool and update progress using progress_update tool.**
|
|
200
|
+
**YOU MUST always display plan using plan_display tool and update progress using progress_update tool.**
|
|
450
201
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
Step 3: progress_update({step: 1, status: "completed"})
|
|
456
|
-
Step 4: file_write({path: "components/TodoList.tsx", content: "..."})
|
|
457
|
-
Step 5: progress_update({step: 2, status: "completed"})
|
|
458
|
-
\`\`\`
|
|
202
|
+
### When to call progress_update:
|
|
203
|
+
- \u2705 Call progress_update ONCE after completing ALL tools for a PLAN STEP
|
|
204
|
+
- \u274C DO NOT call progress_update after each individual tool
|
|
205
|
+
- \u2705 Each progress_update corresponds to exactly ONE plan step
|
|
459
206
|
|
|
460
|
-
|
|
461
|
-
\`\`\`
|
|
462
|
-
Step 1: command_run(...) \u274C Missing plan display and progress update
|
|
463
|
-
Step 2: file_write(...) \u274C Missing plan display and progress update
|
|
464
|
-
\`\`\`
|
|
207
|
+
# Galaxy Design (Galaxy UI) Integration Rules
|
|
465
208
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
209
|
+
When user requests Galaxy Design (Galaxy UI) integration:
|
|
210
|
+
- \u2705 ALWAYS use Galaxy UI tools for integration and component management
|
|
211
|
+
- \u274C NEVER use direct npm/yarn commands like "npm install @galaxy-design/react"
|
|
212
|
+
- For NEW projects: Call galaxy_ui_init \u2192 galaxy_ui_categories \u2192 galaxy_ui_list \u2192 galaxy_ui_add
|
|
213
|
+
- For EXISTING projects: Check integration with galaxy_design_check \u2192 Use appropriate Galaxy UI tools
|
|
469
214
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
\`\`\`
|
|
215
|
+
# Core Rules
|
|
216
|
+
- **Plan First**: ALWAYS create and display execution plan before implementation
|
|
217
|
+
- **Progress Tracking**: Call progress_update ONCE per PLAN STEP (not per tool)
|
|
218
|
+
- **Code Quality**: TypeScript preferred, clean, maintainable, error handling
|
|
219
|
+
- **Git** (if enabled): Conventional commits at logical checkpoints
|
|
220
|
+
- **Testing** (if enabled): Run after changes, fix failures
|
|
221
|
+
- **Error Handling**: Analyze \u2192 Try alternative approach \u2192 Explain
|
|
478
222
|
|
|
479
|
-
|
|
223
|
+
Remember: Plan first \u2192 Execute step by step \u2192 Track progress per plan step \u2192 Build complete app!
|
|
224
|
+
`}i(te,"buildUniversalAgentPrompt");var ce=class{static{i(this,"ClaudeAgent")}connection;toolsRegistry=new L;toolNames=["file_read","file_write","file_tree","file_list","file_search","git_status","git_commit","git_push","git_pull","git_diff","git_log","git_branches","command_run","install_dependencies","test_run","document_parse","plan_display","progress_update","galaxy_ui_list","galaxy_ui_search","galaxy_ui_get_component","galaxy_ui_categories","galaxy_ui_add","galaxy_ui_init","galaxy_ui_docs"];constructor(e){let t=this.toolsRegistry.getToolsContext(this.toolNames),n=te(t);this.connection=new Ee(e,n)}getAnthropicTools(){return this.toolsRegistry.getToolsByNames(this.toolNames).map(t=>({name:t.name,description:t.description,input_schema:t.inputSchema}))}async handleUserInput(e,t,n,o=0){try{let a=t?`[System Context: Git=${t.gitEnabled?"ON":"OFF"}, Test Planning=${t.testEnabled?"ON":"OFF"}]
|
|
480
225
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
2. \u2705 Check result \u2192 Success? \u2192 STOP \u2192 Continue to file creation
|
|
484
|
-
3. \u274C DON'T retry with different flags
|
|
485
|
-
4. \u274C NEVER use "cd" - working directory managed automatically
|
|
486
|
-
5. \u274C NEVER execute in /tmp or outside project
|
|
226
|
+
${e}`:e;n&&n("user",a);let l=await this.connection.chatWithTools(a,this.getAnthropicTools(),n);return n&&n("assistant",l),{content:l||"(No response)"}}catch(a){if(o<3){let l=Math.pow(2,o)*1e3;return await new Promise(u=>setTimeout(u,l)),await this.handleUserInput("Continued",t,n,o+1)}throw new Error(`Agent failed after 3 retries: ${a instanceof Error?a.message:String(a)}`)}}clearHistory(){this.connection.clearHistory(),this.connection.clearToolHistory()}};var K=class{static{i(this,"OllamaAgent")}connection;model;toolsRegistry=new L;conversationHistory=[];systemPrompt;config;TOKEN_LIMIT=262144;TOKEN_THRESHOLD=.8;DEFAULT_GEMINI_API_KEY="AIzaSyBUHDmR-RkEqqQTGofX92hXeXeULxBUHGw";toolNames=["file_read","file_write","file_tree","file_list","file_search","git_status","git_commit","git_push","git_pull","git_diff","git_log","git_branches","command_run","install_dependencies","test_run","plan_display","progress_update","galaxy_ui_list","galaxy_ui_search","galaxy_ui_get_component","galaxy_ui_categories","galaxy_ui_add","galaxy_ui_init","galaxy_ui_docs","galaxy_design_check"];constructor(e){this.config=e,this.model=e?.model||"deepseek-v3.1:671b-cloud",this.connection=new W(e);let t=this.toolsRegistry.getToolsContext(this.toolNames);this.systemPrompt=te(t)}getOllamaTools(){return this.toolsRegistry.getToolsByNames(this.toolNames).map(t=>({type:"function",function:{name:t.name,description:t.description,parameters:t.inputSchema}}))}async summarizeContext(){try{let e=this.conversationHistory.filter(u=>u.role==="user"),t=e.length>0?e[e.length-1]?.content:"Unknown request",n=this.extractCurrentPlan(),o=`
|
|
227
|
+
Please summarize the following conversation context for an AI coding assistant. Be concise but comprehensive.
|
|
487
228
|
|
|
488
|
-
|
|
229
|
+
Latest user request: ${t}
|
|
489
230
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
1. Display plan using plan_display tool
|
|
493
|
-
2. command_run: Setup with ALL flags \u2192 ONCE
|
|
494
|
-
3. file_write: Pages, components, configs
|
|
495
|
-
4. progress_update: After each major step
|
|
496
|
-
5. Done: Complete functional app
|
|
497
|
-
\`\`\`
|
|
231
|
+
Current execution plan:
|
|
232
|
+
${n}
|
|
498
233
|
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
1. Display plan using plan_display tool
|
|
502
|
-
2. file_tree: Understand structure
|
|
503
|
-
3. file_read: Check current code
|
|
504
|
-
4. file_write: New/updated files
|
|
505
|
-
5. command_run: Install deps (--yes)
|
|
506
|
-
6. progress_update: After each major step
|
|
507
|
-
7. Done
|
|
508
|
-
\`\`\`
|
|
234
|
+
Work progress so far:
|
|
235
|
+
${this.extractWorkProgress()}
|
|
509
236
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
- **FEATURE**: "Add/Fix/Update" + mentions existing/current
|
|
237
|
+
Current task status:
|
|
238
|
+
${this.extractCurrentStatus()}
|
|
513
239
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
240
|
+
Please provide a concise summary that includes:
|
|
241
|
+
1. Latest user request
|
|
242
|
+
2. Current execution plan with step details
|
|
243
|
+
3. What has been accomplished so far
|
|
244
|
+
4. Current task in progress
|
|
245
|
+
5. Next steps needed
|
|
520
246
|
|
|
521
|
-
|
|
247
|
+
Keep it under 500 words and focus on the most important technical details.
|
|
248
|
+
`,s={apiKey:this.DEFAULT_GEMINI_API_KEY,model:"gemini-2.5-flash",type:"gemini"};return(await new V(s).generate({prompt:o})).text}catch{return this.simpleSummarize()}}simpleSummarize(){return"Previous conversation context (summarized due to length). Recent activity includes planning and progress updates."}extractCurrentPlan(){let e=this.conversationHistory.filter(o=>typeof o.content=="string"&&o.content.includes("plan_display")).slice(-1);if(e.length===0)return"No plan has been displayed yet.";let t=e[0],n=typeof t?.content=="string"?t.content:JSON.stringify(t?.content);try{let o=n.match(/\{.*\}/s);if(o){let s=JSON.parse(o[0]);if(s.steps&&Array.isArray(s.steps))return s.steps.map(a=>`Step ${a.step}: ${a.action} [${a.status||"pending"}]`).join(`
|
|
249
|
+
`)}}catch{return`Plan details: ${n.substring(0,200)}...`}return`Plan details: ${n.substring(0,200)}...`}extractWorkProgress(){let e=this.conversationHistory.filter(t=>t.role==="tool").slice(-5);return e.length===0?"No work progress recorded yet.":e.map((t,n)=>{let o=typeof t.content=="string"?t.content:JSON.stringify(t.content),s=o.length>100?o.substring(0,100)+"...":o;return`${n+1}. ${s}`}).join(`
|
|
250
|
+
`)}extractCurrentStatus(){let e=this.conversationHistory.filter(s=>typeof s.content=="string"&&s.content.includes("plan_display")).slice(-1),t=this.conversationHistory.filter(s=>typeof s.content=="string"&&s.content.includes("progress_update")).slice(-3),n=e.length>0?"Plan has been displayed.":"No plan displayed yet.",o=t.length>0?`Recent progress updates: ${t.length} updates`:"No progress updates yet.";return`${n} ${o}`}async handleUserInput(e,t,n,o=0){try{let a=t?`[System Context: Git=${t.gitEnabled?"ON":"OFF"}, Test Planning=${t.testEnabled?"ON":"OFF"}]
|
|
522
251
|
|
|
523
|
-
${e}`:e;
|
|
252
|
+
${e}`:e;this.conversationHistory.push({role:"user",content:a});let l=await this.connection.chatWithTools({model:this.model,messages:[{role:"system",content:this.systemPrompt},...this.conversationHistory],tools:this.getOllamaTools(),stream:!1}),u=1e3,m=0;for(;l.message.tool_calls&&m<u;){l.message.content!==""&&X.emitToolExecution({toolName:"assistant_response",content:JSON.stringify(l.message.content),status:"success",toolInfo:{toolName:"assistant_response"}}),m++;let w=l.message.tool_calls;this.conversationHistory.push({role:"assistant",content:l.message.content||"",tool_calls:w});for(let h of w){let E=h.function.name,I=h.function.arguments;if(E==="plan_display"||E==="progress_update")try{let v=await this.toolsRegistry.executeTool(E,I),O=typeof v=="string"?v:JSON.stringify(v);this.conversationHistory.push({role:"tool",content:O}),E==="plan_display"&&this.conversationHistory.push({role:"user",content:'\u26A0\uFE0F CRITICAL: Now execute EACH step in the plan. After completing EACH step, you MUST call progress_update({step: N, status: "completed"|"failed"}). Start with step 1.'})}catch(v){let O=v instanceof Error?v.message:String(v);this.conversationHistory.push({role:"tool",content:`Error: ${O}`})}else try{let v=await this.toolsRegistry.executeTool(E,I),O=typeof v=="string"?v:JSON.stringify(v);this.conversationHistory.push({role:"tool",content:O}),this.conversationHistory.push({role:"user",content:"\u26A0\uFE0F MANDATORY: If the tool you just executed was part of a plan step, you MUST immediately call progress_update with the step number and status (completed/failed). Do NOT skip this step."})}catch(v){let O=v instanceof Error?v.message:String(v);this.conversationHistory.push({role:"tool",content:`Error: ${O}`}),this.conversationHistory.push({role:"user",content:'\u26A0\uFE0F MANDATORY: The tool execution failed. You MUST call progress_update with status="failed" for this step.'})}}l=await this.connection.chatWithTools({model:this.model,messages:[{role:"system",content:this.systemPrompt},...this.conversationHistory],tools:this.getOllamaTools(),stream:!1})}let d=l.message.content||"";return this.conversationHistory.push({role:"assistant",content:d}),{content:d}}catch(a){if(this.isTokenLimitError(a))try{let l=await this.summarizeContext();if(this.clearHistory(),this.conversationHistory.push({role:"system",content:`Previous conversation context summary due to token limit: ${l}
|
|
524
253
|
|
|
525
|
-
|
|
254
|
+
Please continue with the user's request based on this context.`}),o<3)return await this.handleUserInput(e,t,n,o+1)}catch(l){console.error("Failed to summarize context:",l)}if(o<3)return this.conversationHistory.length>0&&this.conversationHistory[this.conversationHistory.length-1]?.role==="user"&&this.conversationHistory.pop(),await new Promise(l=>setTimeout(l,1e5)),await this.handleUserInput(e,t,n,o+1);throw new Error(`\u0110ang b\u1ECB l\u1ED7i. H\xE3y th\u1EED l\u1EA1i sau: ${a instanceof Error?a.message:String(a)}`)}}isTokenLimitError(e){if(!e)return!1;if(e.status_code===400&&typeof e.message=="string"&&e.message.includes("prompt too long"))return!0;if(typeof e=="string")try{let n=JSON.parse(e);return n.status_code===400&&typeof n.message=="string"&&n.message.includes("prompt too long")}catch{}let t=e instanceof Error?e.message:String(e);return t.includes("prompt too long")||t.includes("token limit")}clearHistory(){this.conversationHistory=[]}getHistory(){return[...this.conversationHistory]}setModel(e){this.model=e,this.connection=new W({model:e})}getModel(){return this.model}};var le=class{static{i(this,"GeminiAgent")}connection;toolsRegistry=new L;conversationHistory=[];systemPrompt;toolNames=["file_read","file_write","file_tree","file_list","file_search","git_status","git_commit","git_push","git_pull","git_diff","git_log","git_branches","command_run","install_dependencies","test_run","document_parse","plan_display","progress_update","galaxy_ui_list","galaxy_ui_search","galaxy_ui_get_component","galaxy_ui_categories","galaxy_ui_add","galaxy_ui_init","galaxy_ui_docs"];constructor(e){let t=this.toolsRegistry.getToolsContext(this.toolNames);this.systemPrompt=te(t),this.connection=new V(e,this.systemPrompt)}async handleUserInput(e,t,n,o=0){try{let a=t?`[System Context: Git=${t.gitEnabled?"ON":"OFF"}, Test Planning=${t.testEnabled?"ON":"OFF"}]
|
|
526
255
|
|
|
527
|
-
${e}`:e;this.conversationHistory.push({role:"user",content:a}),n&&n("user",a);let
|
|
256
|
+
${e}`:e;this.conversationHistory.push({role:"user",content:a}),n&&n("user",a);let l=i((m,d,w,h)=>{if(n&&m==="tool"&&w){if(w==="plan_display"||w==="progress_update")return;let E=!d.startsWith("\u274C");n("tool",d,w,{success:E,output:h?.result||d})}},"geminiCallback"),u=await this.connection.chat(a,l);return this.conversationHistory.push({role:"assistant",content:u}),n&&n("assistant",u),{content:u||"(No response)"}}catch(a){if(o<3){this.conversationHistory.length>0&&this.conversationHistory[this.conversationHistory.length-1]?.role==="user"&&this.conversationHistory.pop();let l=Math.pow(2,o)*1e3;return await new Promise(u=>setTimeout(u,l)),await this.handleUserInput("Continued",t,n,o+1)}throw new Error(`Agent failed after 3 retries: ${a instanceof Error?a.message:String(a)}`)}}clearHistory(){this.conversationHistory=[],"clearHistory"in this.connection&&typeof this.connection.clearHistory=="function"&&this.connection.clearHistory()}getHistory(){return[...this.conversationHistory]}};import q from"node:fs";import pe from"node:path";import ke from"node:os";import{execSync as Pe}from"node:child_process";var Oe=class{static{i(this,"ConfigManager")}configPath;config;constructor(){this.configPath=this.getConfigPath(),this.config=this.loadConfig()}getConfigDir(){let e=ke.homedir();switch(ke.platform()){case"darwin":case"linux":return pe.join(e,".galaxy");case"win32":return pe.join(e,"AppData","Local","Galaxy");default:return pe.join(e,".galaxy")}}getConfigPath(){return pe.join(this.getConfigDir(),"config.json")}getDefaultConfig(){return{agent:[{type:"manual"}],git:!0,test:!0,autoUpdate:{enabled:!0,checkOnStartup:!0,silent:!1,maxAttempts:3,timeout:3e3,skipVersions:[],lastChecked:null,lastAttemptedVersion:null}}}loadConfig(){try{if(!q.existsSync(this.configPath))return console.log("\u{1F4DD} Creating default config at:",this.configPath),this.createDefaultConfig();let e=q.readFileSync(this.configPath,"utf-8"),t=JSON.parse(e);return this.validateConfig(t)}catch(e){return console.warn("\u26A0\uFE0F Failed to load config, using defaults:",e instanceof Error?e.message:String(e)),this.getDefaultConfig()}}validateConfig(e){let t=this.getDefaultConfig(),n=t.agent;e.agent&&Array.isArray(e.agent)&&(n=e.agent);let o={...t.autoUpdate,...e.autoUpdate||{}};return{agent:n,git:e.git??t.git,test:e.test??t.test,autoUpdate:o}}createDefaultConfig(){let e=this.getDefaultConfig();try{let t=this.getConfigDir();q.existsSync(t)||q.mkdirSync(t,{recursive:!0}),q.writeFileSync(this.configPath,JSON.stringify(e,null,2),"utf-8"),console.log("\u2705 Created default config file"),console.log("\u{1F4C1} Location:",this.configPath),console.log(""),console.log("You can customize settings by editing this file."),console.log("")}catch(t){console.error("\u274C Failed to create config file:",t instanceof Error?t.message:String(t))}return e}saveConfig(){try{let e=this.getConfigDir();q.existsSync(e)||q.mkdirSync(e,{recursive:!0}),q.writeFileSync(this.configPath,JSON.stringify(this.config,null,2),"utf-8")}catch(e){console.error("\u274C Failed to save config:",e instanceof Error?e.message:String(e))}}getMergedConfig(e={}){if(!this.config.agent||!Array.isArray(this.config.agent)||this.config.agent.length===0)return{model:"manual",git:e.git??this.config.git,test:e.test??this.config.test,agent:[],error:'Hi\u1EC7n t\u1EA1i ch\u01B0a c\xF3 agent n\xE0o \u0111\u01B0\u1EE3c c\u1EA5u h\xECnh. Vui l\xF2ng g\xF5 "galaxy --config" \u0111\u1EC3 xem file config v\xE0 th\xEAm agent.'};let t=this.config.agent.find(o=>o.type==="manual")??this.config.agent[0];if(!t)return{model:"manual",git:e.git??this.config.git,test:e.test??this.config.test,agent:this.config.agent,error:"Kh\xF4ng t\xECm th\u1EA5y agent h\u1EE3p l\u1EC7. Vui l\xF2ng ki\u1EC3m tra l\u1EA1i file c\u1EA5u h\xECnh."};let n=this.validateAgent(t);return n.error?{model:t.type,git:e.git??this.config.git,test:e.test??this.config.test,agent:this.config.agent,error:n.error}:{model:t.type,git:e.git??this.config.git,test:e.test??this.config.test,agent:this.config.agent}}validateAgent(e){if(e.type==="manual")return e.apiKey?{valid:!0}:{valid:!1,error:`Mode Manual c\u1EA7n API Key. Vui l\xF2ng:
|
|
528
257
|
1. G\xF5 /config \u0111\u1EC3 m\u1EDF folder c\u1EA5u h\xECnh
|
|
529
258
|
2. Th\xEAm "apiKey": "your-api-key" v\xE0o agent type "manual"
|
|
530
259
|
3. Tho\xE1t CLI v\xE0 v\xE0o l\u1EA1i \u0111\u1EC3 nh\u1EADn API Key.`};if(e.type==="claude"&&!e.apiKey)return{valid:!1,error:`Hi\u1EC7n t\u1EA1i b\u1EA1n ch\u01B0a th\xEAm apikey cho model ${e.type}. Vui l\xF2ng:
|
|
@@ -536,28 +265,28 @@ ${e}`:e;this.conversationHistory.push({role:"user",content:a}),n&&n("user",a);le
|
|
|
536
265
|
3. Tho\xE1t CLI v\xE0 v\xE0o l\u1EA1i \u0111\u1EC3 nh\u1EADn API Key.`};if(e.type==="ollama"){if(!e.host)return{valid:!1,error:'Hi\u1EC7n t\u1EA1i b\u1EA1n ch\u01B0a c\xE0i \u0111\u1EB7t host cho Ollama. Vui l\xF2ng g\xF5 "galaxy --config" \u0111\u1EC3 xem file config v\xE0 th\xEAm host (v\xED d\u1EE5: "http://localhost:11434").'};if((e.host==="https://ollama.com"||e.host.includes("ollama.com"))&&!e.apiKey)return{valid:!1,error:`Hi\u1EC7n t\u1EA1i b\u1EA1n ch\u01B0a th\xEAm apikey cho model ollama. Vui l\xF2ng:
|
|
537
266
|
1. G\xF5 /config \u0111\u1EC3 m\u1EDF folder c\u1EA5u h\xECnh
|
|
538
267
|
2. Th\xEAm "apiKey": "your-api-key" v\xE0o agent type "ollama"
|
|
539
|
-
3. Tho\xE1t CLI v\xE0 v\xE0o l\u1EA1i \u0111\u1EC3 nh\u1EADn API Key.`}}return{valid:!0}}updateConfig(e){this.config={...this.config,...e},this.saveConfig()}getConfig(){return{...this.config}}getConfigFilePath(){return this.configPath}resetConfig(){this.config=this.getDefaultConfig(),this.saveConfig(),console.log("\u2705 Config reset to defaults")}openConfigFolder(){let e=
|
|
268
|
+
3. Tho\xE1t CLI v\xE0 v\xE0o l\u1EA1i \u0111\u1EC3 nh\u1EADn API Key.`}}return{valid:!0}}updateConfig(e){this.config={...this.config,...e},this.saveConfig()}getConfig(){return{...this.config}}getConfigFilePath(){return this.configPath}resetConfig(){this.config=this.getDefaultConfig(),this.saveConfig(),console.log("\u2705 Config reset to defaults")}openConfigFolder(){let e=pe.dirname(this.configPath);try{let t=ke.platform();t==="darwin"?Pe(`open "${e}"`):t==="win32"?Pe(`start "" "${e}"`):Pe(`xdg-open "${e}"`),console.log("\u2705 Opened config folder")}catch{console.log("\u274C Could not open folder automatically. Please open it manually.")}}displayConfig(){console.log(""),console.log("\u{1F4CA} Current Galaxy Configuration:"),console.log("\u2501".repeat(50)),console.log("\u{1F4C1} Config file:",this.configPath),console.log(""),console.log("Settings:"),console.log(" Agents:"),this.config.agent.forEach((e,t)=>{console.log(` ${t+1}. Type: ${e.type}${e.model?` | Model: ${e.model}`:""}`)}),console.log(" Git:",this.config.git?"ON":"OFF"),console.log(" Test:",this.config.test?"ON":"OFF"),console.log("\u2501".repeat(50)),console.log(""),this.openConfigFolder()}},R=new Oe;import p from"react";import{Box as S,Text as y}from"ink";import c from"react";import{Box as b,Text as g}from"ink";function Qe(r){try{let e=JSON.parse(r);if(!e.components||!Array.isArray(e.components))return c.createElement(g,null,r);let t={};e.components.forEach(o=>{let s=o.category||"uncategorized";t[s]||(t[s]=[]),t[s].push(o)});let n=Object.entries(t);return c.createElement(b,{flexDirection:"column"},c.createElement(g,{bold:!0,color:"cyan"},"\u{1F4E6} Galaxy UI Components ",c.createElement(g,{color:"gray"},`(${e.total} total)`)),n.map(([o,s])=>c.createElement(b,{key:o,flexDirection:"column",marginTop:1},c.createElement(g,{bold:!0,color:"yellow"},o," ",c.createElement(g,{color:"gray"},`(${s.length})`)),c.createElement(b,{flexDirection:"column",marginLeft:2},s.map((a,l)=>c.createElement(b,{key:l,marginBottom:0},c.createElement(g,{color:"green"},"\u2022"),c.createElement(g,{color:"white",bold:!0}," ",a.name),c.createElement(g,{color:"gray"},` - ${a.description}`)))))))}catch{return c.createElement(g,null,r)}}i(Qe,"formatGalaxyUIListComponents");function Ze(r){try{let e=JSON.parse(r);return!e.components||!Array.isArray(e.components)?c.createElement(g,null,r):c.createElement(b,{flexDirection:"column"},c.createElement(g,{bold:!0,color:"cyan"},"\u{1F50D} Galaxy UI Search Results ",c.createElement(g,{color:"gray"},`(${e.total} found)`)),c.createElement(b,{flexDirection:"column",marginTop:1},e.components.map((t,n)=>{let o=t.relevance==="high"?"green":t.relevance==="medium"?"yellow":"gray";return c.createElement(b,{key:n,flexDirection:"column",marginBottom:1},c.createElement(b,null,c.createElement(g,{color:o},`[${t.relevance.toUpperCase()}]`),c.createElement(g,{color:"white",bold:!0}," ",t.name),c.createElement(g,{color:"gray"},` (${t.category})`)),c.createElement(b,{marginLeft:2},c.createElement(g,{color:"gray"},t.description)),c.createElement(b,{marginLeft:2},c.createElement(g,{color:"blue",dimColor:!0},t.docsUrl)))})))}catch{return c.createElement(g,null,r)}}i(Ze,"formatGalaxyUISearchComponents");function et(r){try{let e=JSON.parse(r);return c.createElement(b,{flexDirection:"column"},c.createElement(g,{bold:!0,color:"cyan"},"\u{1F4C4} Component Details: ",c.createElement(g,{color:"white"},e.name)),c.createElement(b,{marginTop:1,flexDirection:"column"},c.createElement(b,null,c.createElement(g,{color:"yellow"},"Category: "),c.createElement(g,{color:"white"},e.category)),c.createElement(b,{marginTop:1},c.createElement(g,{color:"yellow"},"Description: "),c.createElement(g,{color:"white"},e.description)),e.dependencies&&e.dependencies.length>0&&c.createElement(b,{marginTop:1,flexDirection:"column"},c.createElement(g,{color:"yellow"},"Dependencies:"),c.createElement(b,{marginLeft:2,flexDirection:"column"},e.dependencies.map((t,n)=>c.createElement(g,{key:n,color:"green"},`+ ${t}`)))),e.peerDependencies&&e.peerDependencies.length>0&&c.createElement(b,{marginTop:1,flexDirection:"column"},c.createElement(g,{color:"yellow"},"Peer Dependencies:"),c.createElement(b,{marginLeft:2,flexDirection:"column"},e.peerDependencies.map((t,n)=>c.createElement(g,{key:n,color:"blue"},`~ ${t}`)))),c.createElement(b,{marginTop:1},c.createElement(g,{color:"yellow"},"Install Command: "),c.createElement(g,{color:"white"},e.installCommand)),c.createElement(b,{marginTop:1,flexDirection:"column"},c.createElement(g,{color:"yellow"},"Documentation:"),c.createElement(b,{marginLeft:2},e.docsUrlFramework?c.createElement(b,{flexDirection:"column"},c.createElement(g,{color:"blue",dimColor:!0},e.docsUrl),c.createElement(g,{color:"blue",dimColor:!0},e.docsUrlFramework)):c.createElement(g,{color:"blue",dimColor:!0},e.docsUrl)))))}catch{return c.createElement(g,null,r)}}i(et,"formatGalaxyUIGetComponent");function tt(r){try{let e=JSON.parse(r);return!e.categories||!Array.isArray(e.categories)?c.createElement(g,null,r):c.createElement(b,{flexDirection:"column"},c.createElement(g,{bold:!0,color:"cyan"},"\u{1F4C2} Galaxy UI Categories"),c.createElement(b,{flexDirection:"column",marginTop:1},e.categories.map((t,n)=>c.createElement(b,{key:n,marginBottom:1},c.createElement(g,{color:"white",bold:!0},t.name),c.createElement(g,{color:"gray"},` (${t.count} components)`),c.createElement(b,{marginLeft:2,flexDirection:"column",marginTop:0},t.components.map((o,s)=>c.createElement(g,{key:s,color:"green"},`\u2022 ${o}`)))))))}catch{return c.createElement(g,null,r)}}i(tt,"formatGalaxyUIGetCategories");function nt(r){try{let e=JSON.parse(r),t=e.success?"green":"red",n=e.success?"\u2705":"\u274C";return c.createElement(b,{flexDirection:"column"},c.createElement(g,{bold:!0,color:"cyan"},"\u{1F4E5} Add Galaxy UI Components"),c.createElement(b,{marginTop:1},c.createElement(g,{color:t},`${n} ${e.message}`)),e.output&&c.createElement(b,{marginTop:1,flexDirection:"column"},c.createElement(g,{color:"yellow"},"Output:"),c.createElement(b,{borderStyle:"round",borderColor:"gray",paddingX:1,marginLeft:2,flexDirection:"column"},c.createElement(g,{color:"white"},e.output))))}catch{return c.createElement(g,null,r)}}i(nt,"formatGalaxyUIAddComponents");function ot(r){try{let e=JSON.parse(r),t=e.success?"green":"red",n=e.success?"\u2705":"\u274C";return c.createElement(b,{flexDirection:"column"},c.createElement(g,{bold:!0,color:"cyan"},"\u{1F680} Initialize Galaxy UI"),c.createElement(b,{marginTop:1},c.createElement(g,{color:t},`${n} ${e.message}`)),e.output&&c.createElement(b,{marginTop:1,flexDirection:"column"},c.createElement(g,{color:"yellow"},"Output:"),c.createElement(b,{borderStyle:"round",borderColor:"gray",paddingX:1,marginLeft:2,flexDirection:"column"},c.createElement(g,{color:"white"},e.output))))}catch{return c.createElement(g,null,r)}}i(ot,"formatGalaxyUIInit");function rt(r){try{let e=JSON.parse(r);return c.createElement(b,{flexDirection:"column"},c.createElement(g,{bold:!0,color:"cyan"},"\u{1F4D8} Galaxy UI Documentation"),c.createElement(b,{marginTop:1},c.createElement(g,{color:"yellow"},"Description: "),c.createElement(g,{color:"white"},e.description)),c.createElement(b,{marginTop:1},c.createElement(g,{color:"yellow"},"URL: "),c.createElement(g,{color:"blue",dimColor:!0},e.url)))}catch{return c.createElement(g,null,r)}}i(rt,"formatGalaxyUIGetDocsUrl");var Jt=i(()=>{let r=process.stdout?.columns;return typeof r=="number"&&Number.isFinite(r)?r:80},"getTerminalWidth"),ve=i((r,e)=>r.length<=e?r:r.slice(0,e-3)+"...","truncateLine");var Xt=i((r="")=>{let e=r.replaceAll(/\"/g,"").split("\\n");return p.createElement(S,{flexDirection:"column"},e.map((t,n)=>p.createElement(y,{key:n},t)))},"formatTextWithNewlines");function Vt(r,e){let t=r.split(`
|
|
540
269
|
`),n=e.split(`
|
|
541
|
-
`),o=[],s=0,a=0;for(;s<t.length||a<n.length;){let
|
|
542
|
-
`),
|
|
543
|
-
`)
|
|
544
|
-
`).filter(
|
|
545
|
-
`).length),
|
|
546
|
-
`).length,linesRemoved:0,path:e.args.path}
|
|
547
|
-
`),
|
|
548
|
-
`).filter(
|
|
549
|
-
`));return;case"clear":s([{id:"banner"}]),
|
|
550
|
-
`))}return;case"pwd":
|
|
551
|
-
`))}return;case"mode":{if(
|
|
552
|
-
|
|
553
|
-
Using Orchestrator Agent with full tool access.`):
|
|
554
|
-
|
|
555
|
-
Direct chat mode - no tools available.`);return}let
|
|
556
|
-
Valid modes: ${
|
|
557
|
-
Please add it using /config command.`);return}
|
|
558
|
-
\u{1F504} Conversation cleared`)}return;case"git":if(
|
|
559
|
-
\u{1F4C4} Config file: ${
|
|
560
|
-
sudo npm install -g galaxy-code@${r}`}:{success:!1,error:`C\u1EADp nh\u1EADt th\u1EA5t b\u1EA1i: ${t.message}`}:{success:!1,error:"C\u1EADp nh\u1EADt th\u1EA5t b\u1EA1i v\u1EDBi l\u1ED7i kh\xF4ng x\xE1c \u0111\u1ECBnh"}}}i(
|
|
270
|
+
`),o=[],s=0,a=0;for(;s<t.length||a<n.length;){let l=t[s],u=n[a];l===u?(o.push({type:"context",oldLineNum:s+1,newLineNum:a+1,content:l||""}),s++,a++):s<t.length&&l!==void 0&&!n.includes(l)?(o.push({type:"remove",oldLineNum:s+1,content:l||""}),s++):a<n.length&&u!==void 0&&!t.includes(u)?(o.push({type:"add",newLineNum:a+1,content:u||""}),a++):(s<t.length&&(o.push({type:"remove",oldLineNum:s+1,content:l||""}),s++),a<n.length&&(o.push({type:"add",newLineNum:a+1,content:u||""}),a++))}return o}i(Vt,"generateDiff");function Kt(r,e=2){let t=[],n=0;for(;n<r.length;){let o=r[n];if(o&&o.type!=="context")t.push(o),n++;else{let s=n,a=n;for(;a<r.length&&r[a]?.type==="context";)a++;let l=a-s;if(l<=e*2)for(let u=s;u<a;u++)r[u]&&t.push(r[u]);else{for(let m=s;m<s+e;m++)r[m]&&t.push(r[m]);let u=l-e*2;t.push({type:"context",content:`... ${u} unchanged lines ...`});for(let m=a-e;m<a;m++)r[m]&&t.push(r[m])}n=a}}return t}i(Kt,"compressDiff");function zt(r,e){let t=r.split(`
|
|
271
|
+
`),n=[],o=1;for(let s=0;s<t.length;s++){let a=t[s]||"";if(a.startsWith("---")||a.startsWith("+++")){n.push(p.createElement(S,{key:s},p.createElement(y,{bold:!0,color:"cyan"},a)));continue}if(a.startsWith("@@")){n.push(p.createElement(S,{key:s},p.createElement(y,{bold:!0,color:"magenta"},a)));continue}if(a.startsWith("-")){n.push(p.createElement(S,{key:s},p.createElement(y,{dimColor:!0},String(o).padStart(4," ")),p.createElement(y,{color:"red"},` ${a}`))),o++;continue}if(a.startsWith("+")){n.push(p.createElement(S,{key:s},p.createElement(y,{dimColor:!0},String(o).padStart(4," ")),p.createElement(y,{color:"green"},` ${a}`))),o++;continue}n.push(p.createElement(S,{key:s},p.createElement(y,{dimColor:!0},String(o).padStart(4," ")),p.createElement(y,null,` ${a}`))),o++}return p.createElement(S,{flexDirection:"column"},e&&p.createElement(y,{bold:!0,color:"yellow"},`\u{1F4DD} ${e}`),n)}i(zt,"formatDiff");function Yt(r){let e=/```(\w+)?\n([\s\S]*?)```/g,t=[],n=0,o,s=0;for(;(o=e.exec(r))!==null;){o.index>n&&t.push(p.createElement(y,{key:`text-${s}`},r.slice(n,o.index)));let a=o[1]||"text",l=o[2];t.push(p.createElement(S,{key:`code-${s}`,flexDirection:"column",borderStyle:"round",borderColor:"gray",paddingX:1},p.createElement(y,{dimColor:!0},a),p.createElement(y,{color:"cyan"},l))),n=o.index+o[0].length,s++}return n<r.length&&t.push(p.createElement(y,{key:`text-${s}`},r.slice(n))),p.createElement(S,{flexDirection:"column"},t)}i(Yt,"formatCode");var Qt=i((r,e)=>{let t=0,n="current directory";return e?.args?.path&&(n=e?.args.path),r&&(t=r.split(`
|
|
272
|
+
`).filter(s=>{let a=s.trim();return a&&!a.startsWith("Failed")}).length),p.createElement(S,{flexDirection:"column"},p.createElement(y,{bold:!0,color:"cyan"},"\u{1F4C1} LIST DIRECTORY ",p.createElement(y,{color:"gray"},"(",n,")")),p.createElement(S,{marginLeft:1},p.createElement(y,{color:"green"},"\u21B3 Listed ",t," items.")))},"formatFileTree"),Zt=i(r=>{let e=r.split(`
|
|
273
|
+
`).filter(t=>t.trim()!=="");return p.createElement(S,{flexDirection:"column"},p.createElement(y,{bold:!0,color:"yellow"},"\u{1F4C4} File List Results:"),e.map((t,n)=>p.createElement(S,{key:n,marginLeft:2},p.createElement(y,{color:"green"},"\u{1F4C4} ",t))))},"formatFileListAsPlanning"),en=i((r,e)=>{let t=0,n="file";if(e?.args?.path){let o=e.args.path.split("/");n=o[o.length-1]||e.args.path}return r&&(t=r.split(`
|
|
274
|
+
`).length),p.createElement(S,{flexDirection:"column"},p.createElement(y,{bold:!0,color:"cyan"},"\u{1F4C4} READ ",p.createElement(y,{color:"gray"},"(",n,")")),p.createElement(S,{marginLeft:1},p.createElement(y,{color:"green"},"\u21B3 Read ",t," lines.")))},"formatFileRead"),tn=i((r,e)=>{let t="file",n=null;try{n=JSON.parse(r)}catch{if(e?.args?.content){let h=typeof e.args.content=="string"?e.args.content:JSON.stringify(e.args.content);n={isNewFile:!0,newContent:h,linesAdded:h.split(`
|
|
275
|
+
`).length,linesRemoved:0,path:e.args.path}}}if(!n)return p.createElement(y,{wrap:"wrap"},r);if(n.path){let h=n.path.split("/");t=h[h.length-1]||n.path}let{isNewFile:o,oldContent:s,newContent:a,linesAdded:l,linesRemoved:u}=n,m=o?`Succeeded. File created. (+${l} added)`:`Succeeded. File edited. (+${l} added, -${u} removed)`,d=Jt(),w=d-15;if(o){let h=[],E=a.split(`
|
|
276
|
+
`),I=10;return(E.length>I?E.slice(0,I):E).forEach((O,$)=>{let k=ve(O,w);h.push(p.createElement(S,{key:$},p.createElement(y,{dimColor:!0},String($+1).padStart(4," ")),p.createElement(y,{color:"green"},` + ${k}`)))}),E.length>I&&h.push(p.createElement(S,{key:"truncated"},p.createElement(y,{dimColor:!0},"... (",E.length-I," more lines)"))),p.createElement(S,{flexDirection:"column",width:d-2},p.createElement(y,{bold:!0,color:"cyan"},"\u{1F4DD} APPLY PATCH ",p.createElement(y,{color:"gray"},"(",t,")")),p.createElement(S,{marginLeft:1,marginBottom:1},p.createElement(y,{color:"green"},"\u21B3 ",m)),p.createElement(S,{flexDirection:"column",borderStyle:"round",borderColor:"gray",paddingX:1,paddingY:0,width:d-4},h))}else{let h=Vt(s||"",a),E=Kt(h,2),I=[];return E.forEach((v,O)=>{if(v.content.startsWith("...")&&v.content.includes("unchanged"))I.push(p.createElement(S,{key:O},p.createElement(y,{dimColor:!0},v.content)));else if(v.type==="add"){let $=ve(v.content,w);I.push(p.createElement(S,{key:O},p.createElement(y,{dimColor:!0}," ".padStart(4," ")),p.createElement(y,{dimColor:!0},"|"),p.createElement(y,{dimColor:!0},String(v.newLineNum).padStart(4," ")),p.createElement(y,{color:"green"},` + ${$}`)))}else if(v.type==="remove"){let $=ve(v.content,w);I.push(p.createElement(S,{key:O},p.createElement(y,{dimColor:!0},String(v.oldLineNum).padStart(4," ")),p.createElement(y,{dimColor:!0},"|"),p.createElement(y,{dimColor:!0}," ".padStart(4," ")),p.createElement(y,{color:"red"},` - ${$}`)))}else{let $=ve(v.content,w);I.push(p.createElement(S,{key:O},p.createElement(y,{dimColor:!0},String(v.oldLineNum).padStart(4," ")),p.createElement(y,{dimColor:!0},"|"),p.createElement(y,{dimColor:!0},String(v.newLineNum).padStart(4," ")),p.createElement(y,null,` ${$}`)))}}),I.length>30&&(I.splice(30),I.push(p.createElement(S,{key:"truncated"},p.createElement(y,{dimColor:!0},"... (diff truncated for display)")))),p.createElement(S,{flexDirection:"column",width:d-2},p.createElement(y,{bold:!0,color:"cyan"},"\u{1F4DD} APPLY PATCH ",p.createElement(y,{color:"gray"},"(",t,")")),p.createElement(S,{marginLeft:1,marginBottom:1},p.createElement(y,{color:"green"},"\u21B3 ",m)),p.createElement(S,{flexDirection:"column",borderStyle:"round",borderColor:"gray",paddingX:1,paddingY:0,width:d-4},I))}},"formatFileWrite"),nn=i((r,e)=>{let t=!0,n=0,o="command";if(e?.args?.command&&(o=e.args.command),r){let u=r.match(/stdout:\n([\s\S]*?)\n\nstderr:/),m=r.match(/stderr:\n([\s\S]*)/);if(u&&u[1]&&(n=u[1].split(`
|
|
277
|
+
`).filter(w=>w.trim()).length),m&&m[1]){let d=m[1].trim();d&&d.toLowerCase().includes("error")&&(t=!1)}(r.toLowerCase().includes("command not found")||r.toLowerCase().includes("no such file")||r.toLowerCase().includes("permission denied"))&&(t=!1)}return p.createElement(S,{flexDirection:"column"},p.createElement(y,{bold:!0,color:"cyan"},"\u26A1 EXECUTE ",p.createElement(y,{color:"gray"},"(",o,")")),p.createElement(S,{marginLeft:1},p.createElement(y,{color:t?"green":"red"},"\u21B3 ",t?"\u2713":"\u2717"," ",t?"Success":"Failed",". Output: ",n," lines.")))},"formatCommandRun"),on=i(r=>r?r.replace(/^galaxy:/,""):"","normalizeToolName");function st(r,e,t){let n=on(e),o=typeof r=="string"?r:JSON.stringify(r,null,2);switch(n){case"file_tree":return Qt(o,t);case"file_list":return Zt(o,t);case"file_read":return en(o,t);case"file_write":return tn(o,t);case"command_run":return nn(o,t);case"plan_task":return null;case"progress_reporter":return null;case"plan_display":return null;case"progress_update":return null;case"galaxy_ui_list":return Qe(o);case"galaxy_ui_search":return Ze(o);case"galaxy_ui_get_component":return et(o);case"galaxy_ui_categories":return tt(o);case"galaxy_ui_add":return nt(o);case"galaxy_ui_init":return ot(o);case"galaxy_ui_docs":return rt(o);case"diff":return zt(o,e);case"code":return Yt(o);case"assistant_response":return Xt(o);default:return null}}i(st,"formatMessage");var at="0.1.8",mn=i(()=>{let r=ne.stdout?.columns;return typeof r=="number"&&Number.isFinite(r)?r:80},"getTerminalWidth"),dn=i((r,e)=>{let t=r.replace(/\s+$/u,"");if(!t)return"";let n=Math.max(0,Math.floor((e-t.length)/2));return`${" ".repeat(n)}${t}`},"centerLine"),gn=i(r=>{let e=mn(),t=r.model;return[{id:"version",text:at},{id:"hints",text:"ENTER to send \u2022 \\ + ENTER for a new line "},{id:"cwd",text:`Current folder: ${ne.cwd()}`},{id:"config",text:`Agent=${t} Git=${r.git?"ON":"OFF"} Test=${r.test?"ON":"OFF"}`}].map(o=>({id:o.id,text:dn(o.text,e-50)}))},"getInforLines"),fn=un.textSync("GALAXY",{font:"Standard",horizontalLayout:"default",verticalLayout:"default"});function Ne({config:r}){let{exit:e}=an(),[t,n]=B(""),[o,s]=B([{id:"banner"},...r.error?[{id:"config-error",author:"system",content:`\u26A0\uFE0F ${r.error}`,timestamp:Date.now()}]:[]]),[a,l]=B(!1),[u,m]=B([]),[d,w]=B([]),[h,E]=B([]),[I,v]=B(-1),[O,$]=B(0),[k,oe]=B(r),yt=gn(k),re=it(()=>{if(k.model==="manual"){let x=k.agent.find(C=>C.type==="manual");return new K({type:"ollama",model:"qwen3-coder:480b-cloud",host:"https://ollama.com",apiKey:x?.apiKey})}let f=k.agent.find(x=>x.type===k.model);if(!f)return null;switch(k.model){case"claude":return new ce(f);case"ollama":return new K(f);case"gemini":return new le(f);default:return null}},[k.model,k.agent]),Ue=it(()=>[{command:"/help",description:"Hi\u1EC3n th\u1ECB danh s\xE1ch l\u1EC7nh"},{command:"/exit",description:"Tho\xE1t kh\u1ECFi Galaxy CLI"},{command:"/clear",description:"X\xF3a l\u1ECBch s\u1EED h\u1ED9i tho\u1EA1i hi\u1EC7n t\u1EA1i"},{command:"/history",description:"Xem danh s\xE1ch 10 input g\u1EA7n nh\u1EA5t"},{command:"/pwd",description:"Hi\u1EC3n th\u1ECB th\u01B0 m\u1EE5c l\xE0m vi\u1EC7c hi\u1EC7n t\u1EA1i"},{command:"/information",description:"Hi\u1EC3n th\u1ECB th\xF4ng tin h\u1EC7 th\u1ED1ng"},{command:"/git",description:"B\u1EADt/t\u1EAFt git operations (/git true|false)"},{command:"/test",description:"B\u1EADt/t\u1EAFt test planning (/test true|false)"},{command:"/mode",description:"Ch\u1ECDn agent mode (/mode claude|gemini|ollama|manual)"},{command:"/config",description:"M\u1EDF th\u01B0 m\u1EE5c ch\u1EE9a file c\u1EA5u h\xECnh"}],[]);rn(()=>{let f=X.onToolExecution(x=>{if(x.toolName==="plan_display")try{let T=x.toolInfo.args;if(T.steps&&Array.isArray(T.steps)){let P=T.steps.map((D,H)=>({step:D.step,action:D.action,status:H===0?"in-progress":"pending"}));w(P)}}catch{}if(x.toolName==="progress_update")try{let T=x.toolInfo.args,P=T.step,D=T.status,H=D==="completed"?"completed":D==="failed"?"failed":"in-progress";w(U=>U.map(z=>z.step===P?{...z,status:H}:D==="completed"&&z.step===P+1&&z.status==="pending"?{...z,status:"in-progress"}:z))}catch{}let C={id:`tool-${Date.now()}-${Math.random()}`,author:"tool",toolName:x.toolName,content:x.content,toolInfo:x.toolInfo,timestamp:x.timestamp};s(T=>[...T,C])});return()=>{f()}},[]);let ht=i(f=>{let[x,...C]=f.slice(1).split(/\s+/);switch(x){case"exit":A("system","Goodbye!"),e();return;case"help":A("system",["Danh s\xE1ch l\u1EC7nh:",...Ue.map(T=>`${T.command.padEnd(15," ")} ${T.description}`)].join(`
|
|
278
|
+
`));return;case"clear":s([{id:"banner"}]),w([]),re&&"clearHistory"in re&&re.clearHistory(),A("system","\u2705 Cleared conversation and progress");return;case"history":if(h.length===0){A("system","No history yet.");return}{let P=[...h].slice(-10).reverse().map((D,H)=>`${H+1}. ${D.replace(/\n/g," ")}`);A("system",["Recent inputs:",...P].join(`
|
|
279
|
+
`))}return;case"pwd":A("system",`Working directory: ${ne.cwd()}`);return;case"information":{let T=k.model;A("system",["\u{1F4CA} System Information:","Name: Galaxy CLI",`Version: ${at}`,`Current Project: ${ne.cwd()}`,`Agent Mode: ${T}`,`Git Operations: ${k.git?"ON":"OFF"}`,`Testing: ${k.test?"ON":"OFF"}`].join(`
|
|
280
|
+
`))}return;case"mode":{if(C.length===0){let U=k.model;k.model==="manual"?A("system",`\u{1F916} Agent Mode: ${U}
|
|
281
|
+
|
|
282
|
+
Using Orchestrator Agent with full tool access.`):A("system",`\u{1F916} Agent Mode: ${U}
|
|
283
|
+
|
|
284
|
+
Direct chat mode - no tools available.`);return}let T=C[0]?.toLowerCase()??"",P=["claude","gemini","ollama","manual"];if(!i(U=>P.includes(U),"isValidMode")(T)){A("system",`\u274C Invalid mode: ${T}
|
|
285
|
+
Valid modes: ${P.join(", ")}`);return}if(!k.agent.find(U=>U.type===T)){A("system",`\u274C Agent config for "${T}" not found in config file.
|
|
286
|
+
Please add it using /config command.`);return}oe(U=>({...U,model:T})),s([{id:"banner"}]),w([]),A("system",`\u2705 Switched to ${T} mode
|
|
287
|
+
\u{1F504} Conversation cleared`)}return;case"git":if(C.length===0){A("system",`Git operations are currently ${k.git?"ON":"OFF"}`);return}{let T=C[0]?.toLowerCase()??"";T==="true"||T==="on"?(oe(P=>({...P,git:!0})),A("system","\u2705 Git operations enabled")):T==="false"||T==="off"?(oe(P=>({...P,git:!1})),A("system","\u274C Git operations disabled")):A("system","Usage: /git true|false")}return;case"test":if(C.length===0){A("system",`Testing is currently ${k.test?"ON":"OFF"}`);return}{let T=C[0]?.toLowerCase()??"";T==="true"||T==="on"?(oe(P=>({...P,test:!0})),A("system","\u2705 Test planning enabled")):T==="false"||T==="off"?(oe(P=>({...P,test:!1})),A("system","\u274C Test planning disabled")):A("system","Usage: /test true|false")}return;case"config":{let T=R.getConfigFilePath();R.openConfigFolder(),A("system",`\u{1F4C2} Config directory opened
|
|
288
|
+
\u{1F4C4} Config file: ${T}`)}return;default:A("system",`Unknown command: /${x}${C.length?" "+C.join(" "):""}`)}},"handleCommand"),Le=i(async f=>{if(a)return;let x=f.trim();if(x){if(x.startsWith("/")){n(""),ht(x);return}A("user",x),l(!0),n(""),E(C=>[...C,x]),v(-1);try{let C="";if(!re)throw new Error("Agent connection not initialized");C=(await re.handleUserInput(x,{gitEnabled:k.git,testEnabled:k.test},A)).content,d.every(P=>P.status==="completed")&&A("planing","Planning completed.","plan_display",{args:d}),C&&(w([]),A("assistant",C))}catch(C){A("system",`\u274C Error: ${C instanceof Error?C.message:String(C)}`)}finally{l(!1)}}},"handleSubmit");cn((f,x)=>{if(x.ctrl&&f==="c"&&e(),u.length>0&&t.startsWith("/")){x.upArrow||x.shift&&x.tab?$(C=>(C-1+u.length)%u.length):x.downArrow||x.tab?$(C=>(C+1)%u.length):(x.escape||x.return)&&(m([]),$(0));return}if(h.length>0&&!t.startsWith("/")){if(x.upArrow){let C=I===-1?h.length-1:Math.max(0,I-1);v(C),n(h[C]||"")}else if(x.downArrow){if(I===-1)return;let C=I+1;C>=h.length?(v(-1),n("")):(v(C),n(h[C]||""))}}});let A=i((f,x,C,T)=>{let P={id:`${Date.now()}-${f}-${Math.random().toString(16).slice(2)}`,author:f,content:x,toolName:C,toolInfo:T,timestamp:Date.now()};if(f==="tool"&&C==="plan_display"){let D=x.map((H,U)=>({...H,status:U===0?"in-progress":"pending"}));w(D)}else s(D=>[...D,P])},"appendMessage"),je=d.find(f=>f.status==="in-progress");return _.createElement(_.Fragment,null,_.createElement(sn,{items:o},f=>f.author==="user"?_.createElement(N,{key:f.id,flexDirection:"row",marginTop:1},_.createElement(j,{color:"red"},`> ${f.content}`)):f.author==="assistant"?_.createElement(N,{key:f.id,flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"blue",paddingX:1,paddingY:0},_.createElement(j,null,f.content)):f.author==="tool"?_.createElement(N,{key:f.id,flexDirection:"row",marginTop:1},st(f.content||"",f.toolName,f.toolInfo)):f.author==="system"?_.createElement(N,{key:f.id,flexDirection:"row",marginTop:1},_.createElement(j,{color:"gray"},`\u2699 ${f.content}`)):_.createElement(N,{borderColor:"cyan",borderStyle:"round",flexDirection:"row",key:"banner-box",width:ne.stdout.columns},_.createElement(N,{flexDirection:"column"},_.createElement(j,{color:"cyan"},fn)),_.createElement(N,{borderLeft:!0,borderLeftColor:"cyan",flexDirection:"column",marginLeft:2,marginTop:1},yt.map(x=>_.createElement(j,{key:x.id,dimColor:!0},x.text))))),k.model==="manual"&&d.length>0&&_.createElement(N,{flexDirection:"column",paddingTop:1,paddingBottom:1},je&&_.createElement(N,{marginBottom:1},_.createElement(j,{bold:!0,color:"cyan"},"\u26A1 ",je.action)),d.map(f=>{let x=f.status==="completed"?"\u2611":f.status==="in-progress"?"\u2699":f.status==="failed"?"\u274C":"\u2610",C=f.status==="completed"?"green":f.status==="in-progress"?"cyan":f.status==="failed"?"red":"gray";return _.createElement(N,{key:f.step},_.createElement(j,{color:C},x," Step ",f.step,": ",f.action))})),_.createElement(N,{flexDirection:"row",paddingTop:1,width:ne.stdout.columns},a?_.createElement(j,null,_.createElement(j,{color:"cyan"},_.createElement(pn,{type:"dots"}))," Thinking..."):null),_.createElement(N,{borderColor:"green",borderStyle:"round",flexDirection:"column",marginTop:1},_.createElement(N,{alignItems:"center",flexDirection:"row"},_.createElement(j,{color:"green"},"> "),_.createElement(ln,{value:t,showCursor:!a,onChange:a?()=>{}:f=>{if(n(f),f.startsWith("/")){let x=f.toLowerCase(),C=Ue.filter(T=>T.command.toLowerCase().startsWith(x));m(C),$(0)}else m([]),$(0)},onSubmit:a?()=>{}:f=>{if(f.trim().startsWith("/")&&u.length>0){let C=u[O]??u[0];Le(C?.command||"");return}Le(f)},placeholder:a?"Processing... (input disabled)":"Type and press Enter to send"}))),u.length>0&&_.createElement(N,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"gray"},u.map((f,x)=>_.createElement(N,{key:f.command,paddingX:1,paddingY:0,flexDirection:"row"},_.createElement(j,{color:x===O?"cyan":void 0},f.command.padEnd(15," ")),_.createElement(j,{dimColor:!0},f.description)))))}i(Ne,"App");import yn from"semver";import{readFileSync as hn}from"node:fs";import{fileURLToPath as xn}from"node:url";import{dirname as wn,join as Cn}from"node:path";var Tn=xn(import.meta.url),bn=wn(Tn);function En(){try{let r=Cn(bn,"../package.json");return JSON.parse(hn(r,"utf-8")).version}catch{return"0.1.0"}}i(En,"getCurrentVersion");async function vn(r="galaxy-code",e=3e3){try{let t=new AbortController,n=setTimeout(()=>{t.abort()},e),o=await fetch(`https://registry.npmjs.org/${r}/latest`,{signal:t.signal,headers:{Accept:"application/json"}});return clearTimeout(n),o.ok?(await o.json()).version:null}catch(t){return t instanceof Error&&t.name!=="AbortError"&&console.debug("Failed to fetch latest version:",t.message),null}}i(vn,"fetchLatestVersion");async function ct(r=3e3){try{let e=En(),t=await vn("galaxy-code",r);if(!t)return null;let n=yn.gt(t,e);return{hasUpdate:n,currentVersion:e,latestVersion:t,updateAvailable:n}}catch(e){return console.debug("Error checking for update:",e),null}}i(ct,"checkForUpdate");function lt(r,e){return e.includes(r)}i(lt,"shouldSkipVersion");import{execSync as _n,spawn as Sn}from"node:child_process";import{existsSync as $e,writeFileSync as An,unlinkSync as In}from"node:fs";import{tmpdir as pt}from"node:os";import{join as ut}from"node:path";function kn(){let r=ut(pt(),"galaxy-code-update.lock");return An(r,Date.now().toString()),r}i(kn,"createLockFile");function De(r){try{$e(r)&&In(r)}catch{}}i(De,"removeLockFile");function Pn(){let r=ut(pt(),"galaxy-code-update.lock");if(!$e(r))return!1;try{let e=Number.parseInt($e(r)?"":"0",10),t=Date.now(),n=300*1e3;return t-e>n?(De(r),!1):!0}catch{return!1}}i(Pn,"isUpdateInProgress");function On(r){let e=r.message.toLowerCase();return e.includes("eacces")||e.includes("permission")||e.includes("eperm")}i(On,"isPermissionError");async function mt(r){if(Pn())return{success:!1,error:"\u0110ang c\xF3 process kh\xE1c \u0111ang c\u1EADp nh\u1EADt..."};let e=kn();try{let t=`npm install -g galaxy-code@${r}`;return _n(t,{stdio:"pipe",timeout:6e4}),De(e),{success:!0,needsRestart:!0}}catch(t){return De(e),t instanceof Error?On(t)?{success:!1,error:`C\u1EA7n quy\u1EC1n admin \u0111\u1EC3 c\u1EADp nh\u1EADt. Vui l\xF2ng ch\u1EA1y:
|
|
289
|
+
sudo npm install -g galaxy-code@${r}`}:{success:!1,error:`C\u1EADp nh\u1EADt th\u1EA5t b\u1EA1i: ${t.message}`}:{success:!1,error:"C\u1EADp nh\u1EADt th\u1EA5t b\u1EA1i v\u1EDBi l\u1ED7i kh\xF4ng x\xE1c \u0111\u1ECBnh"}}}i(mt,"performUpdate");function dt(){let r=process.argv.slice(2);Sn("galaxy-code",r,{detached:!0,stdio:"inherit"}).unref(),process.exit(0)}i(dt,"restartCLI");function gt(r){console.log(""),console.log(`\u2705 \u0110\xE3 c\u1EADp nh\u1EADt l\xEAn phi\xEAn b\u1EA3n ${r} th\xE0nh c\xF4ng!`),console.log("")}i(gt,"showUpdateSuccess");function ft(r){console.log(""),console.log("\u26A0\uFE0F Kh\xF4ng th\u1EC3 c\u1EADp nh\u1EADt t\u1EF1 \u0111\u1ED9ng"),console.log(r),console.log(""),console.log("\u0110ang ti\u1EBFp t\u1EE5c v\u1EDBi phi\xEAn b\u1EA3n hi\u1EC7n t\u1EA1i..."),console.log("")}i(ft,"showUpdateError");var ue=Dn(`
|
|
561
290
|
C\xE1ch s\u1EED d\u1EE5ng
|
|
562
291
|
$ galaxy [t\xF9y ch\u1ECDn]
|
|
563
292
|
|
|
@@ -585,4 +314,4 @@ Please add it using /config command.`);return}z(N=>({...N,model:w})),s([{id:"ban
|
|
|
585
314
|
|
|
586
315
|
Th\u1EE9 t\u1EF1 \u01B0u ti\xEAn: Tham s\u1ED1 CLI > config.json > m\u1EB7c \u0111\u1ECBnh
|
|
587
316
|
|
|
588
|
-
`,{importMeta:import.meta,flags:{git:{type:"boolean"},test:{type:"boolean"},config:{type:"boolean",default:!1},resetConfig:{type:"boolean",default:!1},dev:{type:"boolean",default:!1},noAutoUpdate:{type:"boolean",default:!1}}});async function
|
|
317
|
+
`,{importMeta:import.meta,flags:{git:{type:"boolean"},test:{type:"boolean"},config:{type:"boolean",default:!1},resetConfig:{type:"boolean",default:!1},dev:{type:"boolean",default:!1},noAutoUpdate:{type:"boolean",default:!1}}});async function Un(){let r=R.getConfig(),e=r.autoUpdate;if(!e.enabled||!e.checkOnStartup||ue.flags.noAutoUpdate)return!1;try{let t=await ct(e.timeout);if(!t||!t.hasUpdate||lt(t.latestVersion,e.skipVersions))return!1;e.silent||(console.log(""),console.log(`\u{1F680} Ph\xE1t hi\u1EC7n phi\xEAn b\u1EA3n m\u1EDBi ${t.latestVersion}, \u0111ang c\u1EADp nh\u1EADt...`),console.log(""));let n=await mt(t.latestVersion);if(n.success){if(gt(t.latestVersion),R.updateConfig({...r,autoUpdate:{...e,lastChecked:Date.now(),lastAttemptedVersion:t.latestVersion}}),n.needsRestart)return dt(),!0}else n.error&&ft(n.error)}catch(t){console.debug("Auto-update failed:",t)}return!1}i(Un,"handleAutoUpdate");(async()=>{if(ue.flags.config&&(R.displayConfig(),process.exit(0)),ue.flags.resetConfig&&(R.resetConfig(),process.exit(0)),await Un())return;let e=R.getMergedConfig({git:ue.flags.git,test:ue.flags.test});$n(Nn.createElement(Ne,{config:e}))})();
|
package/package.json
CHANGED