From a5f3e383d48a0f3709a3f19114699323df664979 Mon Sep 17 00:00:00 2001 From: g1nation Date: Sun, 3 May 2026 20:40:40 +0900 Subject: [PATCH] Version 2.55.0 Release: Rebranding to Astra --- README.md | 10 +-- .../Advanced_Features_Implementation_Guide.md | 2 +- docs/UX_UI_Consistency_Guidelines.md | 2 +- docs/records/ConnectAI/README.md | 6 +- ...02_connectai_project_knowledge_overview.md | 6 +- ...03_connectai_project_knowledge_overview.md | 6 +- docs/records/ConnectAI/project-profile.md | 4 +- package.json | 26 +++---- src/agent.ts | 68 ++++++++++++++++--- src/bridge.ts | 2 +- src/core/health.ts | 2 +- src/core/statusBar.ts | 2 +- src/extension.ts | 10 +-- src/features/projectChronicle/guardPrompt.ts | 4 ++ src/sidebarProvider.ts | 26 +++---- src/utils.ts | 5 +- tests/localPathPreflight.test.ts | 21 +++++- tests/projectChronicleGuardPrompt.test.ts | 3 + tests/secondBrainTrace.test.ts | 2 +- 19 files changed, 140 insertions(+), 67 deletions(-) diff --git a/README.md b/README.md index 3bd08e7..65584a9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# G1nation +# Astra -G1nation은 로컬 인프라를 기반으로 작동하는 고성능 자율 AI 코딩 에이전트입니다. VS Code 환경에서 복잡한 개발 작업을 수행하며, 프로젝트 아키텍처 분석부터 코드 생성, 시스템 명령 실행까지 전 과정을 자동화합니다. +Astra는 로컬 인프라를 기반으로 작동하는 자비스형 프로젝트 운영 비서입니다. VS Code 환경에서 프로젝트 기억, 제2뇌, 코드/문서 맥락, 도구 실행을 하나의 목소리로 연결해 사용자의 생각 정리와 다음 행동 결정을 돕습니다. ## 핵심 기술 아키텍처 @@ -35,7 +35,7 @@ NumPy 기반의 행렬 연산을 활용하여 기존의 반복문 기반 검색 ### 소스 빌드 환경 ```bash git clone https://github.com/g1nations/locallm.git -cd connect-ai +cd locallm npm install npm run compile npx vsce package @@ -43,7 +43,7 @@ npx vsce package ## 데이터 보안 및 개인정보 보호 -G1nation은 100% 로컬 추론 환경에서 작동하도록 설계되었습니다. +Astra는 100% 로컬 추론 환경에서 작동하도록 설계되었습니다. - 모든 연산은 사용자 로컬 머신의 자원을 사용하여 처리됩니다. - 코드 및 지식 데이터는 외부 클라우드 서버로 전송되지 않습니다. @@ -51,4 +51,4 @@ G1nation은 100% 로컬 추론 환경에서 작동하도록 설계되었습니 --- Designed for high-performance autonomous engineering. -Copyright (C) G1nation. All rights reserved. +Copyright (C) Astra. All rights reserved. diff --git a/docs/Advanced_Features_Implementation_Guide.md b/docs/Advanced_Features_Implementation_Guide.md index d24a162..793ba99 100644 --- a/docs/Advanced_Features_Implementation_Guide.md +++ b/docs/Advanced_Features_Implementation_Guide.md @@ -1,6 +1,6 @@ # Advanced Features Implementation Guide -이 문서는 ConnectAI(G1nation)의 '지능형 협업 시스템' 구현을 위한 기술 가이드라인입니다. +이 문서는 Astra의 '지능형 협업 시스템' 구현을 위한 기술 가이드라인입니다. --- diff --git a/docs/UX_UI_Consistency_Guidelines.md b/docs/UX_UI_Consistency_Guidelines.md index dcc9f47..14506ee 100644 --- a/docs/UX_UI_Consistency_Guidelines.md +++ b/docs/UX_UI_Consistency_Guidelines.md @@ -1,6 +1,6 @@ # UX/UI Consistency Guidelines -이 문서는 ConnectAI(G1nation) 프로젝트의 UI 일관성과 사용자 경험을 유지하기 위한 핵심 규칙을 정의합니다. 모든 신규 기능 및 UI 수정은 이 가이드라인을 준수해야 합니다. +이 문서는 Astra 프로젝트의 UI 일관성과 사용자 경험을 유지하기 위한 핵심 규칙을 정의합니다. 모든 신규 기능 및 UI 수정은 이 가이드라인을 준수해야 합니다. --- diff --git a/docs/records/ConnectAI/README.md b/docs/records/ConnectAI/README.md index 38d3d95..de44b55 100644 --- a/docs/records/ConnectAI/README.md +++ b/docs/records/ConnectAI/README.md @@ -1,9 +1,9 @@ -# ConnectAI Project Chronicle Records +# Astra Project Chronicle Records -This folder stores planning, decision, development, bug, and retrospective records for ConnectAI. +This folder stores planning, decision, development, bug, and retrospective records for Astra. ## Project -- Name: ConnectAI +- Name: Astra - Root: `/Volumes/Data/project/Antigravity/ConnectAI` - Record root: `docs/records/ConnectAI` diff --git a/docs/records/ConnectAI/development/2026-05-02_connectai_project_knowledge_overview.md b/docs/records/ConnectAI/development/2026-05-02_connectai_project_knowledge_overview.md index 6e4e436..d430c34 100644 --- a/docs/records/ConnectAI/development/2026-05-02_connectai_project_knowledge_overview.md +++ b/docs/records/ConnectAI/development/2026-05-02_connectai_project_knowledge_overview.md @@ -1,11 +1,11 @@ -# ConnectAI Project Knowledge Overview +# Astra Project Knowledge Overview Date: 2026-05-02T16:14:59.756Z -Project: ConnectAI +Project: Astra Repository: `/Volumes/Data/project/Antigravity/ConnectAI` ## Purpose -ConnectAI는 VS Code 안에서 로컬 AI 에이전트, Second Brain, 프로젝트 기록, 에이전트 스킬을 연결하는 개발 보조 프로젝트다. +Astra는 VS Code 안에서 로컬 AI 에이전트, Second Brain, 프로젝트 기록, 에이전트 스킬을 연결하는 개발 보조 프로젝트다. ## Confirmed Structure - `src/agent.ts`: 에이전트 실행, 로컬 경로 프리플라이트, Second Brain Trace, 액션 실행 흐름의 중심. diff --git a/docs/records/ConnectAI/development/2026-05-03_connectai_project_knowledge_overview.md b/docs/records/ConnectAI/development/2026-05-03_connectai_project_knowledge_overview.md index debe28f..fea6bd9 100644 --- a/docs/records/ConnectAI/development/2026-05-03_connectai_project_knowledge_overview.md +++ b/docs/records/ConnectAI/development/2026-05-03_connectai_project_knowledge_overview.md @@ -1,11 +1,11 @@ -# ConnectAI Project Knowledge Overview +# Astra Project Knowledge Overview Date: 2026-05-03T01:34:15.597Z -Project: ConnectAI +Project: Astra Repository: `/Volumes/Data/project/Antigravity/ConnectAI` ## Purpose -ConnectAI는 VS Code 안에서 로컬 AI 에이전트, Second Brain, 프로젝트 기록, 에이전트 스킬을 연결하는 개발 보조 프로젝트다. +Astra는 VS Code 안에서 로컬 AI 에이전트, Second Brain, 프로젝트 기록, 에이전트 스킬을 연결하는 개발 보조 프로젝트다. ## Confirmed Structure - `src/agent.ts`: 에이전트 실행, 로컬 경로 프리플라이트, Second Brain Trace, 액션 실행 흐름의 중심. diff --git a/docs/records/ConnectAI/project-profile.md b/docs/records/ConnectAI/project-profile.md index 8c1ac8c..dff81b5 100644 --- a/docs/records/ConnectAI/project-profile.md +++ b/docs/records/ConnectAI/project-profile.md @@ -1,10 +1,10 @@ # Project Profile ## Project Name -ConnectAI +Astra ## Purpose -Provide a local AI assistant experience inside VS Code with chat, local knowledge, agent skills, and project-oriented development support. +Provide a Jarvis-style local project operating assistant inside VS Code with chat, local knowledge, agent skills, and project-oriented development support. ## Core Users - Project developer diff --git a/package.json b/package.json index 7d35c5a..c9d8a8f 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { - "name": "g1nation", - "displayName": "G1nation", - "description": "High-performance autonomous local AI coding agent for VS Code. Features vectorized inference, asynchronous task management, and 100% offline processing.", - "version": "2.54.0", + "name": "astra", + "displayName": "Astra", + "description": "A local Jarvis-style project operating assistant for VS Code. Connects memory, project context, tools, and a single thinking-partner voice.", + "version": "2.55.0", "publisher": "connectailab", "license": "MIT", "icon": "assets/icon.png", @@ -28,7 +28,7 @@ "offline", "agent", "code-generation", - "g1nation", + "astra", "copilot" ], "activationEvents": [], @@ -37,24 +37,24 @@ "commands": [ { "command": "g1nation.newChat", - "title": "G1nation: New Chat", + "title": "Astra: New Chat", "icon": "$(add)" }, { "command": "g1nation.exportChat", - "title": "G1nation: Export Chat as Markdown" + "title": "Astra: Export Chat as Markdown" }, { "command": "g1nation.explainSelection", - "title": "G1nation: Explain Selected Code" + "title": "Astra: Explain Selected Code" }, { "command": "g1nation.focusChat", - "title": "G1nation: Focus Chat Input" + "title": "Astra: Focus Chat Input" }, { "command": "g1nation.showBrainNetwork", - "title": "G1nation: Show Brain Topology" + "title": "Astra: Show Brain Topology" } ], "keybindings": [ @@ -77,7 +77,7 @@ "activitybar": [ { "id": "g1nation-sidebar", - "title": "G1nation", + "title": "Astra", "icon": "$(hubot)" } ] @@ -93,7 +93,7 @@ ] }, "configuration": { - "title": "G1nation", + "title": "Astra", "properties": { "g1nation.multiAgentEnabled": { "type": "boolean", @@ -155,7 +155,7 @@ }, "name": { "type": "string", - "description": "Display name shown in the G1nation brain selector." + "description": "Display name shown in the Astra brain selector." }, "localBrainPath": { "type": "string", diff --git a/src/agent.ts b/src/agent.ts index a7e5499..c8fe6cb 100644 --- a/src/agent.ts +++ b/src/agent.ts @@ -207,7 +207,7 @@ export class AgentExecutor { // Decide whether to use Multi-Agent Workflow (for complex requests) const isComplex = prompt && (prompt.length > 100 || /(분석|보고서|설계|기획|정리)/.test(prompt)); - if (isComplex && loopDepth === 0 && multiAgentEnabled) { + if (isComplex && loopDepth === 0 && multiAgentEnabled && !this.isAstraModeArchitectureQuestion(prompt)) { return this.executeMultiAgentWorkflow(prompt!, modelName, options); } @@ -293,6 +293,12 @@ export class AgentExecutor { if (projectBriefContext) { contextBlock += `\n\n${projectBriefContext}`; } + const modeArchitectureContext = prompt && loopDepth === 0 + ? this.buildAstraModeArchitectureContext(prompt) + : ''; + if (modeArchitectureContext) { + contextBlock += `\n\n${modeArchitectureContext}`; + } // 2. Setup History if (prompt !== null) { @@ -792,6 +798,40 @@ export class AgentExecutor { return /(어떤\s*거?\s*같|어때|어떻게\s*생각|의견|판단|방향|설계|아키텍처|구조|자비스|생각.*정리|갈림길|architecture|design|direction|opinion|think|judge)/i.test(prompt); } + private isAstraModeArchitectureQuestion(prompt: string): boolean { + const mentionsGuard = /\bguard\b|가드|Guard|Chronicle Guard|Project Chronicle/i.test(prompt); + const mentionsMultiAgent = /\bMA\b|multi[-\s]?agent|멀티\s*에이전트|다중\s*에이전트|Planner|Researcher|Writer/i.test(prompt); + const asksDecision = /(분리|통합|모드|사용|좋을까|맞을까|구조|설계|아키텍처|의견|판단|어때|어떤\s*거?\s*같|separate|combine|mode|architecture|design|opinion)/i.test(prompt); + return asksDecision && mentionsGuard && mentionsMultiAgent; + } + + private buildAstraModeArchitectureContext(prompt: string): string { + if (!this.isAstraModeArchitectureQuestion(prompt)) { + return ''; + } + + return [ + '[ASTRA MODE ARCHITECTURE DECISION CONTEXT]', + 'The user is asking about Astra itself, specifically whether Guard mode and MA/Multi-Agent mode should remain separate.', + '', + 'Confirmed implementation facts from the current codebase:', + '- Guard is currently exposed as a sidebar toggle, but it defaults to enabled in the webview UI.', + '- Guard context is built by buildProjectChronicleGuardContext(activeProject) and passed into AgentExecutor as designerContext.', + '- In the normal single-agent path, designerContext is injected into the system prompt as [PROJECT CHRONICLE GUARD].', + '- In the Multi-Agent path, designerContext is appended as Project Chronicle Guard context for the workflow manager.', + '- Multi-Agent is controlled by the g1nation.multiAgentEnabled config and is only used for complex prompts.', + '- Current risk: when Multi-Agent starts, it returns early before the normal path builds local project preflight, Second Brain Trace, recent project knowledge context, and thinking-partner context.', + '', + 'Product decision guidance:', + '- Do not treat Guard and MA as two equal user-facing modes.', + '- Guard should be an always-on policy/context layer: project target, evidence discipline, record hygiene, tone, and decision logging.', + '- MA should be an optional execution strategy chosen automatically for genuinely complex tasks.', + '- Recommended UX: hide or de-emphasize the Guard toggle, show it as Auto/On by default, and let Astra route between single-agent and MA internally.', + '- Recommended answer: give a clear verdict that separating them as peer modes is not ideal; separate them internally by responsibility instead.', + '- Mention the concrete risk that MA can currently bypass richer context assembly, so unifying the context preparation before routing is the next engineering step.' + ].join('\n'); + } + private buildJarvisProjectBriefContext(prompt: string, localPathContext: string, recentProjectKnowledgeContext: string): string { if (!this.isThinkingPartnerRequest(prompt)) { return ''; @@ -1102,6 +1142,7 @@ export class AgentExecutor { private buildProjectKnowledgeFallbackAnswer(localPathContext: string, record?: { filePath: string; relativePath: string } | null): string { const pathMatch = localPathContext.match(/Path:\s*(.+)/); const projectPath = pathMatch?.[1]?.trim() || '제공된 로컬 프로젝트 경로'; + const projectDisplayName = this.getProjectDisplayName(projectPath); const treeMatch = localPathContext.match(/Scanned tree:\n([\s\S]*?)(?:\nPriority file previews:|$)/); const treePreview = treeMatch?.[1]?.trim().split('\n').slice(0, 18).join('\n') || ''; const priorityMatches = this.extractPriorityPreviewFiles(localPathContext).slice(0, 10); @@ -1123,10 +1164,10 @@ export class AgentExecutor { '', '## 바로 만들 지식 초안', '```markdown', - '# ConnectAI Project Knowledge Overview', + `# ${projectDisplayName} Project Knowledge Overview`, '', '## Purpose', - 'ConnectAI는 VS Code 안에서 로컬 AI 에이전트, Second Brain, 프로젝트 기록, 에이전트 스킬을 연결하는 개발 보조 프로젝트다.', + `${projectDisplayName}는 VS Code 안에서 로컬 AI 에이전트, Second Brain, 프로젝트 기록, 에이전트 스킬을 연결하는 개발 보조 프로젝트다.`, '', '## Confirmed Structure', '- `src/agent.ts`: 에이전트 실행, 로컬 경로 프리플라이트, Second Brain Trace, 액션 실행 흐름의 중심.', @@ -1140,7 +1181,7 @@ export class AgentExecutor { '- 전체 아키텍처는 파일 구조와 일부 프리뷰 기준으로 파악 가능하지만, 세부 동작 지식은 `src/agent.ts`, `src/sidebarProvider.ts`, `secondBrainTrace.ts`, `projectChronicle` 순서로 심화 분석해 보강해야 한다.', '', '## Recommended Next Record', - '- `docs/records/ConnectAI/development/YYYY-MM-DD_connectai_project_knowledge_overview.md`', + `- \`docs/records/${path.basename(projectPath)}/development/YYYY-MM-DD_${projectDisplayName.toLowerCase()}_project_knowledge_overview.md\``, '```', '', '## 다음 액션', @@ -1170,8 +1211,9 @@ export class AgentExecutor { try { const projectName = path.basename(projectPath); + const projectDisplayName = this.getProjectDisplayName(projectPath); const today = new Date().toISOString().slice(0, 10); - const slug = projectName.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '') || 'project'; + const slug = projectDisplayName.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '') || 'project'; const relativePath = path.join('docs', 'records', projectName, 'development', `${today}_${slug}_project_knowledge_overview.md`); const filePath = path.join(projectPath, relativePath); fs.mkdirSync(path.dirname(filePath), { recursive: true }); @@ -1187,19 +1229,20 @@ export class AgentExecutor { const pathMatch = localPathContext.match(/Path:\s*(.+)/); const projectPath = pathMatch?.[1]?.trim() || 'Unknown project path'; const projectName = path.basename(projectPath); + const projectDisplayName = this.getProjectDisplayName(projectPath); const treeMatch = localPathContext.match(/Scanned tree:\n([\s\S]*?)(?:\nPriority file previews:|$)/); const treePreview = treeMatch?.[1]?.trim().split('\n').slice(0, 80).join('\n') || ''; const priorityFiles = this.extractPriorityPreviewFiles(localPathContext); return [ - `# ${projectName} Project Knowledge Overview`, + `# ${projectDisplayName} Project Knowledge Overview`, '', `Date: ${new Date().toISOString()}`, - `Project: ${projectName}`, + `Project: ${projectDisplayName}`, `Repository: \`${projectPath}\``, '', '## Purpose', - `${projectName}는 VS Code 안에서 로컬 AI 에이전트, Second Brain, 프로젝트 기록, 에이전트 스킬을 연결하는 개발 보조 프로젝트다.`, + `${projectDisplayName}는 VS Code 안에서 로컬 AI 에이전트, Second Brain, 프로젝트 기록, 에이전트 스킬을 연결하는 개발 보조 프로젝트다.`, '', '## Confirmed Structure', '- `src/agent.ts`: 에이전트 실행, 로컬 경로 프리플라이트, Second Brain Trace, 액션 실행 흐름의 중심.', @@ -1227,6 +1270,11 @@ export class AgentExecutor { ].join('\n'); } + private getProjectDisplayName(projectPath: string): string { + const projectName = path.basename(projectPath); + return /^connectai$/i.test(projectName) ? 'Astra' : projectName; + } + private listProjectTree(root: string, current: string, depth: number, maxDepth: number, limit: number): string { if (limit <= 0 || depth > maxDepth) { return ''; @@ -1646,7 +1694,7 @@ export class AgentExecutor { const cmd = match[1].trim(); try { const safeCmd = sanitizeCommand(cmd); - const terminal = vscode.window.terminals.find(t => t.name === 'G1nation Terminal') || vscode.window.createTerminal({ name: 'G1nation Terminal', cwd: rootPath }); + const terminal = vscode.window.terminals.find(t => t.name === 'Astra Terminal') || vscode.window.createTerminal({ name: 'Astra Terminal', cwd: rootPath }); terminal.show(); terminal.sendText(safeCmd); report.push(`🚀 Executed: ${safeCmd}`); @@ -1766,7 +1814,7 @@ export class AgentExecutor { try { const { execSync } = require('child_process'); execSync(`git add .`, { cwd: brainDir }); - execSync(`git commit -m "[G1nation] Knowledge Update"`, { cwd: brainDir }); + execSync(`git commit -m "[Astra] Knowledge Update"`, { cwd: brainDir }); execSync(`git push`, { cwd: brainDir }); } catch (err) { logError('Second Brain sync failed.', err); diff --git a/src/bridge.ts b/src/bridge.ts index 9151e32..0996400 100644 --- a/src/bridge.ts +++ b/src/bridge.ts @@ -20,7 +20,7 @@ export interface BridgeInterface { /** * BridgeServer: - * 외부 툴(EZER, A.U 등)과 G1nation 확장을 연결하는 통신 브릿지. + * 외부 툴(EZER, A.U 등)과 Astra 확장을 연결하는 통신 브릿지. * 서비스 레이어(AIService, BrainService)를 통해 비즈니스 로직을 분리하여 유지보수성을 극대화했습니다. */ export class BridgeServer { diff --git a/src/core/health.ts b/src/core/health.ts index b7fe5b2..f7c10ca 100644 --- a/src/core/health.ts +++ b/src/core/health.ts @@ -44,7 +44,7 @@ export class HealthCheckMonitor { if (reports.length > 0) { logWarn(`Health Check Warnings: ${reports.join(' | ')}`); - vscode.window.showWarningMessage(`ConnectAI Health Warning: ${reports[0]}`); + vscode.window.showWarningMessage(`Astra Health Warning: ${reports[0]}`); } return { diff --git a/src/core/statusBar.ts b/src/core/statusBar.ts index 0fbc9e4..eb0c081 100644 --- a/src/core/statusBar.ts +++ b/src/core/statusBar.ts @@ -43,7 +43,7 @@ export class StatusBarManager { break; } - this.statusBarItem.text = `${icon} G1nation: ${status}`; + this.statusBarItem.text = `${icon} Astra: ${status}`; this.statusBarItem.tooltip = detail || `Current State: ${status}`; if (status === AgentStatus.Success || status === AgentStatus.Error) { diff --git a/src/extension.ts b/src/extension.ts index d3cd76c..245bb26 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -18,10 +18,10 @@ import { SidebarChatProvider } from './sidebarProvider'; import { HealthCheckMonitor } from './core/health'; /** - * G1nation Extension Entry Point + * Astra Extension Entry Point */ export async function activate(context: vscode.ExtensionContext) { - logInfo('ConnectAI activating...'); + logInfo('Astra activating...'); // Start Environment Health Monitoring HealthCheckMonitor.runAllChecks(); @@ -30,7 +30,7 @@ export async function activate(context: vscode.ExtensionContext) { // 0. Validate Configuration const validation = validateConfig(); if (!validation.valid) { - vscode.window.showErrorMessage(`G1nation Configuration Error: ${validation.errors.join(' ')}`); + vscode.window.showErrorMessage(`Astra Configuration Error: ${validation.errors.join(' ')}`); logError('Configuration validation failed.', { errors: validation.errors }); } @@ -144,12 +144,12 @@ async function _ensureBrainDir(context: vscode.ExtensionContext): Promise 80 ? `${normalized.slice(0, 80)}...` : normalized; } @@ -930,7 +930,7 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn } vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, - title: "G1nation: Syncing Second Brain...", + title: "Astra: Syncing Second Brain...", cancellable: false }, async () => { try { @@ -1573,7 +1573,7 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn this._chronicle.appendTimeline(profile, [`Auto ${recordType} record created: ${result.relativePath}`], createdAt); await this._context.globalState.update(SidebarChatProvider.lastAutoChronicleSignatureStateKey, signature); await this._sendChronicleRecords(); - vscode.window.setStatusBarMessage(`G1nation: Chronicle auto-saved ${recordType}`, 3500); + vscode.window.setStatusBarMessage(`Astra: Chronicle auto-saved ${recordType}`, 3500); } catch (err: any) { logError('Automatic Chronicle record write failed.', { error: err?.message || String(err), recordType }); } @@ -1944,7 +1944,7 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn - G1nation + Astra