Version 2.55.0 Release: Rebranding to Astra
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
# G1nation
|
# Astra
|
||||||
|
|
||||||
G1nation은 로컬 인프라를 기반으로 작동하는 고성능 자율 AI 코딩 에이전트입니다. VS Code 환경에서 복잡한 개발 작업을 수행하며, 프로젝트 아키텍처 분석부터 코드 생성, 시스템 명령 실행까지 전 과정을 자동화합니다.
|
Astra는 로컬 인프라를 기반으로 작동하는 자비스형 프로젝트 운영 비서입니다. VS Code 환경에서 프로젝트 기억, 제2뇌, 코드/문서 맥락, 도구 실행을 하나의 목소리로 연결해 사용자의 생각 정리와 다음 행동 결정을 돕습니다.
|
||||||
|
|
||||||
## 핵심 기술 아키텍처
|
## 핵심 기술 아키텍처
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ NumPy 기반의 행렬 연산을 활용하여 기존의 반복문 기반 검색
|
|||||||
### 소스 빌드 환경
|
### 소스 빌드 환경
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/g1nations/locallm.git
|
git clone https://github.com/g1nations/locallm.git
|
||||||
cd connect-ai
|
cd locallm
|
||||||
npm install
|
npm install
|
||||||
npm run compile
|
npm run compile
|
||||||
npx vsce package
|
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.
|
Designed for high-performance autonomous engineering.
|
||||||
Copyright (C) G1nation. All rights reserved.
|
Copyright (C) Astra. All rights reserved.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Advanced Features Implementation Guide
|
# Advanced Features Implementation Guide
|
||||||
|
|
||||||
이 문서는 ConnectAI(G1nation)의 '지능형 협업 시스템' 구현을 위한 기술 가이드라인입니다.
|
이 문서는 Astra의 '지능형 협업 시스템' 구현을 위한 기술 가이드라인입니다.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# UX/UI Consistency Guidelines
|
# UX/UI Consistency Guidelines
|
||||||
|
|
||||||
이 문서는 ConnectAI(G1nation) 프로젝트의 UI 일관성과 사용자 경험을 유지하기 위한 핵심 규칙을 정의합니다. 모든 신규 기능 및 UI 수정은 이 가이드라인을 준수해야 합니다.
|
이 문서는 Astra 프로젝트의 UI 일관성과 사용자 경험을 유지하기 위한 핵심 규칙을 정의합니다. 모든 신규 기능 및 UI 수정은 이 가이드라인을 준수해야 합니다.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
## Project
|
||||||
- Name: ConnectAI
|
- Name: Astra
|
||||||
- Root: `/Volumes/Data/project/Antigravity/ConnectAI`
|
- Root: `/Volumes/Data/project/Antigravity/ConnectAI`
|
||||||
- Record root: `docs/records/ConnectAI`
|
- Record root: `docs/records/ConnectAI`
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -1,11 +1,11 @@
|
|||||||
# ConnectAI Project Knowledge Overview
|
# Astra Project Knowledge Overview
|
||||||
|
|
||||||
Date: 2026-05-02T16:14:59.756Z
|
Date: 2026-05-02T16:14:59.756Z
|
||||||
Project: ConnectAI
|
Project: Astra
|
||||||
Repository: `/Volumes/Data/project/Antigravity/ConnectAI`
|
Repository: `/Volumes/Data/project/Antigravity/ConnectAI`
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
ConnectAI는 VS Code 안에서 로컬 AI 에이전트, Second Brain, 프로젝트 기록, 에이전트 스킬을 연결하는 개발 보조 프로젝트다.
|
Astra는 VS Code 안에서 로컬 AI 에이전트, Second Brain, 프로젝트 기록, 에이전트 스킬을 연결하는 개발 보조 프로젝트다.
|
||||||
|
|
||||||
## Confirmed Structure
|
## Confirmed Structure
|
||||||
- `src/agent.ts`: 에이전트 실행, 로컬 경로 프리플라이트, Second Brain Trace, 액션 실행 흐름의 중심.
|
- `src/agent.ts`: 에이전트 실행, 로컬 경로 프리플라이트, Second Brain Trace, 액션 실행 흐름의 중심.
|
||||||
|
|||||||
+3
-3
@@ -1,11 +1,11 @@
|
|||||||
# ConnectAI Project Knowledge Overview
|
# Astra Project Knowledge Overview
|
||||||
|
|
||||||
Date: 2026-05-03T01:34:15.597Z
|
Date: 2026-05-03T01:34:15.597Z
|
||||||
Project: ConnectAI
|
Project: Astra
|
||||||
Repository: `/Volumes/Data/project/Antigravity/ConnectAI`
|
Repository: `/Volumes/Data/project/Antigravity/ConnectAI`
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
ConnectAI는 VS Code 안에서 로컬 AI 에이전트, Second Brain, 프로젝트 기록, 에이전트 스킬을 연결하는 개발 보조 프로젝트다.
|
Astra는 VS Code 안에서 로컬 AI 에이전트, Second Brain, 프로젝트 기록, 에이전트 스킬을 연결하는 개발 보조 프로젝트다.
|
||||||
|
|
||||||
## Confirmed Structure
|
## Confirmed Structure
|
||||||
- `src/agent.ts`: 에이전트 실행, 로컬 경로 프리플라이트, Second Brain Trace, 액션 실행 흐름의 중심.
|
- `src/agent.ts`: 에이전트 실행, 로컬 경로 프리플라이트, Second Brain Trace, 액션 실행 흐름의 중심.
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
# Project Profile
|
# Project Profile
|
||||||
|
|
||||||
## Project Name
|
## Project Name
|
||||||
ConnectAI
|
Astra
|
||||||
|
|
||||||
## Purpose
|
## 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
|
## Core Users
|
||||||
- Project developer
|
- Project developer
|
||||||
|
|||||||
+13
-13
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "g1nation",
|
"name": "astra",
|
||||||
"displayName": "G1nation",
|
"displayName": "Astra",
|
||||||
"description": "High-performance autonomous local AI coding agent for VS Code. Features vectorized inference, asynchronous task management, and 100% offline processing.",
|
"description": "A local Jarvis-style project operating assistant for VS Code. Connects memory, project context, tools, and a single thinking-partner voice.",
|
||||||
"version": "2.54.0",
|
"version": "2.55.0",
|
||||||
"publisher": "connectailab",
|
"publisher": "connectailab",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"icon": "assets/icon.png",
|
"icon": "assets/icon.png",
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
"offline",
|
"offline",
|
||||||
"agent",
|
"agent",
|
||||||
"code-generation",
|
"code-generation",
|
||||||
"g1nation",
|
"astra",
|
||||||
"copilot"
|
"copilot"
|
||||||
],
|
],
|
||||||
"activationEvents": [],
|
"activationEvents": [],
|
||||||
@@ -37,24 +37,24 @@
|
|||||||
"commands": [
|
"commands": [
|
||||||
{
|
{
|
||||||
"command": "g1nation.newChat",
|
"command": "g1nation.newChat",
|
||||||
"title": "G1nation: New Chat",
|
"title": "Astra: New Chat",
|
||||||
"icon": "$(add)"
|
"icon": "$(add)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "g1nation.exportChat",
|
"command": "g1nation.exportChat",
|
||||||
"title": "G1nation: Export Chat as Markdown"
|
"title": "Astra: Export Chat as Markdown"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "g1nation.explainSelection",
|
"command": "g1nation.explainSelection",
|
||||||
"title": "G1nation: Explain Selected Code"
|
"title": "Astra: Explain Selected Code"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "g1nation.focusChat",
|
"command": "g1nation.focusChat",
|
||||||
"title": "G1nation: Focus Chat Input"
|
"title": "Astra: Focus Chat Input"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "g1nation.showBrainNetwork",
|
"command": "g1nation.showBrainNetwork",
|
||||||
"title": "G1nation: Show Brain Topology"
|
"title": "Astra: Show Brain Topology"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"keybindings": [
|
"keybindings": [
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
"activitybar": [
|
"activitybar": [
|
||||||
{
|
{
|
||||||
"id": "g1nation-sidebar",
|
"id": "g1nation-sidebar",
|
||||||
"title": "G1nation",
|
"title": "Astra",
|
||||||
"icon": "$(hubot)"
|
"icon": "$(hubot)"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -93,7 +93,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"configuration": {
|
"configuration": {
|
||||||
"title": "G1nation",
|
"title": "Astra",
|
||||||
"properties": {
|
"properties": {
|
||||||
"g1nation.multiAgentEnabled": {
|
"g1nation.multiAgentEnabled": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
@@ -155,7 +155,7 @@
|
|||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Display name shown in the G1nation brain selector."
|
"description": "Display name shown in the Astra brain selector."
|
||||||
},
|
},
|
||||||
"localBrainPath": {
|
"localBrainPath": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
|||||||
+58
-10
@@ -207,7 +207,7 @@ export class AgentExecutor {
|
|||||||
|
|
||||||
// Decide whether to use Multi-Agent Workflow (for complex requests)
|
// Decide whether to use Multi-Agent Workflow (for complex requests)
|
||||||
const isComplex = prompt && (prompt.length > 100 || /(분석|보고서|설계|기획|정리)/.test(prompt));
|
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);
|
return this.executeMultiAgentWorkflow(prompt!, modelName, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,6 +293,12 @@ export class AgentExecutor {
|
|||||||
if (projectBriefContext) {
|
if (projectBriefContext) {
|
||||||
contextBlock += `\n\n${projectBriefContext}`;
|
contextBlock += `\n\n${projectBriefContext}`;
|
||||||
}
|
}
|
||||||
|
const modeArchitectureContext = prompt && loopDepth === 0
|
||||||
|
? this.buildAstraModeArchitectureContext(prompt)
|
||||||
|
: '';
|
||||||
|
if (modeArchitectureContext) {
|
||||||
|
contextBlock += `\n\n${modeArchitectureContext}`;
|
||||||
|
}
|
||||||
|
|
||||||
// 2. Setup History
|
// 2. Setup History
|
||||||
if (prompt !== null) {
|
if (prompt !== null) {
|
||||||
@@ -792,6 +798,40 @@ export class AgentExecutor {
|
|||||||
return /(어떤\s*거?\s*같|어때|어떻게\s*생각|의견|판단|방향|설계|아키텍처|구조|자비스|생각.*정리|갈림길|architecture|design|direction|opinion|think|judge)/i.test(prompt);
|
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 {
|
private buildJarvisProjectBriefContext(prompt: string, localPathContext: string, recentProjectKnowledgeContext: string): string {
|
||||||
if (!this.isThinkingPartnerRequest(prompt)) {
|
if (!this.isThinkingPartnerRequest(prompt)) {
|
||||||
return '';
|
return '';
|
||||||
@@ -1102,6 +1142,7 @@ export class AgentExecutor {
|
|||||||
private buildProjectKnowledgeFallbackAnswer(localPathContext: string, record?: { filePath: string; relativePath: string } | null): string {
|
private buildProjectKnowledgeFallbackAnswer(localPathContext: string, record?: { filePath: string; relativePath: string } | null): string {
|
||||||
const pathMatch = localPathContext.match(/Path:\s*(.+)/);
|
const pathMatch = localPathContext.match(/Path:\s*(.+)/);
|
||||||
const projectPath = pathMatch?.[1]?.trim() || '제공된 로컬 프로젝트 경로';
|
const projectPath = pathMatch?.[1]?.trim() || '제공된 로컬 프로젝트 경로';
|
||||||
|
const projectDisplayName = this.getProjectDisplayName(projectPath);
|
||||||
const treeMatch = localPathContext.match(/Scanned tree:\n([\s\S]*?)(?:\nPriority file previews:|$)/);
|
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 treePreview = treeMatch?.[1]?.trim().split('\n').slice(0, 18).join('\n') || '';
|
||||||
const priorityMatches = this.extractPriorityPreviewFiles(localPathContext).slice(0, 10);
|
const priorityMatches = this.extractPriorityPreviewFiles(localPathContext).slice(0, 10);
|
||||||
@@ -1123,10 +1164,10 @@ export class AgentExecutor {
|
|||||||
'',
|
'',
|
||||||
'## 바로 만들 지식 초안',
|
'## 바로 만들 지식 초안',
|
||||||
'```markdown',
|
'```markdown',
|
||||||
'# ConnectAI Project Knowledge Overview',
|
`# ${projectDisplayName} Project Knowledge Overview`,
|
||||||
'',
|
'',
|
||||||
'## Purpose',
|
'## Purpose',
|
||||||
'ConnectAI는 VS Code 안에서 로컬 AI 에이전트, Second Brain, 프로젝트 기록, 에이전트 스킬을 연결하는 개발 보조 프로젝트다.',
|
`${projectDisplayName}는 VS Code 안에서 로컬 AI 에이전트, Second Brain, 프로젝트 기록, 에이전트 스킬을 연결하는 개발 보조 프로젝트다.`,
|
||||||
'',
|
'',
|
||||||
'## Confirmed Structure',
|
'## Confirmed Structure',
|
||||||
'- `src/agent.ts`: 에이전트 실행, 로컬 경로 프리플라이트, Second Brain Trace, 액션 실행 흐름의 중심.',
|
'- `src/agent.ts`: 에이전트 실행, 로컬 경로 프리플라이트, Second Brain Trace, 액션 실행 흐름의 중심.',
|
||||||
@@ -1140,7 +1181,7 @@ export class AgentExecutor {
|
|||||||
'- 전체 아키텍처는 파일 구조와 일부 프리뷰 기준으로 파악 가능하지만, 세부 동작 지식은 `src/agent.ts`, `src/sidebarProvider.ts`, `secondBrainTrace.ts`, `projectChronicle` 순서로 심화 분석해 보강해야 한다.',
|
'- 전체 아키텍처는 파일 구조와 일부 프리뷰 기준으로 파악 가능하지만, 세부 동작 지식은 `src/agent.ts`, `src/sidebarProvider.ts`, `secondBrainTrace.ts`, `projectChronicle` 순서로 심화 분석해 보강해야 한다.',
|
||||||
'',
|
'',
|
||||||
'## Recommended Next Record',
|
'## 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 {
|
try {
|
||||||
const projectName = path.basename(projectPath);
|
const projectName = path.basename(projectPath);
|
||||||
|
const projectDisplayName = this.getProjectDisplayName(projectPath);
|
||||||
const today = new Date().toISOString().slice(0, 10);
|
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 relativePath = path.join('docs', 'records', projectName, 'development', `${today}_${slug}_project_knowledge_overview.md`);
|
||||||
const filePath = path.join(projectPath, relativePath);
|
const filePath = path.join(projectPath, relativePath);
|
||||||
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
||||||
@@ -1187,19 +1229,20 @@ export class AgentExecutor {
|
|||||||
const pathMatch = localPathContext.match(/Path:\s*(.+)/);
|
const pathMatch = localPathContext.match(/Path:\s*(.+)/);
|
||||||
const projectPath = pathMatch?.[1]?.trim() || 'Unknown project path';
|
const projectPath = pathMatch?.[1]?.trim() || 'Unknown project path';
|
||||||
const projectName = path.basename(projectPath);
|
const projectName = path.basename(projectPath);
|
||||||
|
const projectDisplayName = this.getProjectDisplayName(projectPath);
|
||||||
const treeMatch = localPathContext.match(/Scanned tree:\n([\s\S]*?)(?:\nPriority file previews:|$)/);
|
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 treePreview = treeMatch?.[1]?.trim().split('\n').slice(0, 80).join('\n') || '';
|
||||||
const priorityFiles = this.extractPriorityPreviewFiles(localPathContext);
|
const priorityFiles = this.extractPriorityPreviewFiles(localPathContext);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
`# ${projectName} Project Knowledge Overview`,
|
`# ${projectDisplayName} Project Knowledge Overview`,
|
||||||
'',
|
'',
|
||||||
`Date: ${new Date().toISOString()}`,
|
`Date: ${new Date().toISOString()}`,
|
||||||
`Project: ${projectName}`,
|
`Project: ${projectDisplayName}`,
|
||||||
`Repository: \`${projectPath}\``,
|
`Repository: \`${projectPath}\``,
|
||||||
'',
|
'',
|
||||||
'## Purpose',
|
'## Purpose',
|
||||||
`${projectName}는 VS Code 안에서 로컬 AI 에이전트, Second Brain, 프로젝트 기록, 에이전트 스킬을 연결하는 개발 보조 프로젝트다.`,
|
`${projectDisplayName}는 VS Code 안에서 로컬 AI 에이전트, Second Brain, 프로젝트 기록, 에이전트 스킬을 연결하는 개발 보조 프로젝트다.`,
|
||||||
'',
|
'',
|
||||||
'## Confirmed Structure',
|
'## Confirmed Structure',
|
||||||
'- `src/agent.ts`: 에이전트 실행, 로컬 경로 프리플라이트, Second Brain Trace, 액션 실행 흐름의 중심.',
|
'- `src/agent.ts`: 에이전트 실행, 로컬 경로 프리플라이트, Second Brain Trace, 액션 실행 흐름의 중심.',
|
||||||
@@ -1227,6 +1270,11 @@ export class AgentExecutor {
|
|||||||
].join('\n');
|
].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 {
|
private listProjectTree(root: string, current: string, depth: number, maxDepth: number, limit: number): string {
|
||||||
if (limit <= 0 || depth > maxDepth) {
|
if (limit <= 0 || depth > maxDepth) {
|
||||||
return '';
|
return '';
|
||||||
@@ -1646,7 +1694,7 @@ export class AgentExecutor {
|
|||||||
const cmd = match[1].trim();
|
const cmd = match[1].trim();
|
||||||
try {
|
try {
|
||||||
const safeCmd = sanitizeCommand(cmd);
|
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.show();
|
||||||
terminal.sendText(safeCmd);
|
terminal.sendText(safeCmd);
|
||||||
report.push(`🚀 Executed: ${safeCmd}`);
|
report.push(`🚀 Executed: ${safeCmd}`);
|
||||||
@@ -1766,7 +1814,7 @@ export class AgentExecutor {
|
|||||||
try {
|
try {
|
||||||
const { execSync } = require('child_process');
|
const { execSync } = require('child_process');
|
||||||
execSync(`git add .`, { cwd: brainDir });
|
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 });
|
execSync(`git push`, { cwd: brainDir });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logError('Second Brain sync failed.', err);
|
logError('Second Brain sync failed.', err);
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@ export interface BridgeInterface {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* BridgeServer:
|
* BridgeServer:
|
||||||
* 외부 툴(EZER, A.U 등)과 G1nation 확장을 연결하는 통신 브릿지.
|
* 외부 툴(EZER, A.U 등)과 Astra 확장을 연결하는 통신 브릿지.
|
||||||
* 서비스 레이어(AIService, BrainService)를 통해 비즈니스 로직을 분리하여 유지보수성을 극대화했습니다.
|
* 서비스 레이어(AIService, BrainService)를 통해 비즈니스 로직을 분리하여 유지보수성을 극대화했습니다.
|
||||||
*/
|
*/
|
||||||
export class BridgeServer {
|
export class BridgeServer {
|
||||||
|
|||||||
+1
-1
@@ -44,7 +44,7 @@ export class HealthCheckMonitor {
|
|||||||
|
|
||||||
if (reports.length > 0) {
|
if (reports.length > 0) {
|
||||||
logWarn(`Health Check Warnings: ${reports.join(' | ')}`);
|
logWarn(`Health Check Warnings: ${reports.join(' | ')}`);
|
||||||
vscode.window.showWarningMessage(`ConnectAI Health Warning: ${reports[0]}`);
|
vscode.window.showWarningMessage(`Astra Health Warning: ${reports[0]}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export class StatusBarManager {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.statusBarItem.text = `${icon} G1nation: ${status}`;
|
this.statusBarItem.text = `${icon} Astra: ${status}`;
|
||||||
this.statusBarItem.tooltip = detail || `Current State: ${status}`;
|
this.statusBarItem.tooltip = detail || `Current State: ${status}`;
|
||||||
|
|
||||||
if (status === AgentStatus.Success || status === AgentStatus.Error) {
|
if (status === AgentStatus.Success || status === AgentStatus.Error) {
|
||||||
|
|||||||
+5
-5
@@ -18,10 +18,10 @@ import { SidebarChatProvider } from './sidebarProvider';
|
|||||||
import { HealthCheckMonitor } from './core/health';
|
import { HealthCheckMonitor } from './core/health';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* G1nation Extension Entry Point
|
* Astra Extension Entry Point
|
||||||
*/
|
*/
|
||||||
export async function activate(context: vscode.ExtensionContext) {
|
export async function activate(context: vscode.ExtensionContext) {
|
||||||
logInfo('ConnectAI activating...');
|
logInfo('Astra activating...');
|
||||||
|
|
||||||
// Start Environment Health Monitoring
|
// Start Environment Health Monitoring
|
||||||
HealthCheckMonitor.runAllChecks();
|
HealthCheckMonitor.runAllChecks();
|
||||||
@@ -30,7 +30,7 @@ export async function activate(context: vscode.ExtensionContext) {
|
|||||||
// 0. Validate Configuration
|
// 0. Validate Configuration
|
||||||
const validation = validateConfig();
|
const validation = validateConfig();
|
||||||
if (!validation.valid) {
|
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 });
|
logError('Configuration validation failed.', { errors: validation.errors });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,12 +144,12 @@ async function _ensureBrainDir(context: vscode.ExtensionContext): Promise<string
|
|||||||
try {
|
try {
|
||||||
fs.mkdirSync(defaultDir, { recursive: true });
|
fs.mkdirSync(defaultDir, { recursive: true });
|
||||||
// Create a welcome file
|
// Create a welcome file
|
||||||
fs.writeFileSync(path.join(defaultDir, 'Welcome.md'), "# Welcome to your Second Brain\n\nG1nation will store and retrieve knowledge from here.");
|
fs.writeFileSync(path.join(defaultDir, 'Welcome.md'), "# Welcome to your Second Brain\n\nAstra will store and retrieve knowledge from here.");
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
return defaultDir;
|
return defaultDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* G1nation Extension Entry Point
|
* Astra Extension Entry Point
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -38,6 +38,10 @@ export function buildProjectChronicleGuardContext(project: ProjectProfile | null
|
|||||||
'- Do not mark a decision as accepted until the user confirms it.',
|
'- Do not mark a decision as accepted until the user confirms it.',
|
||||||
'- Before confirmation, call decisions "candidates" or "pending".',
|
'- Before confirmation, call decisions "candidates" or "pending".',
|
||||||
'- Prefer "reduced adoption" when the idea is useful but too large for the MVP.',
|
'- Prefer "reduced adoption" when the idea is useful but too large for the MVP.',
|
||||||
|
'- For Astra mode-design questions, do not treat Guard and MA/Multi-Agent as two equal user-facing modes.',
|
||||||
|
'- Treat Guard as a policy/context layer for evidence, project target, record hygiene, and thinking-partner tone.',
|
||||||
|
'- Treat MA/Multi-Agent as an execution strategy that may be selected automatically for complex tasks.',
|
||||||
|
'- If asked whether Guard and MA should be separated, recommend internal responsibility separation but a simpler Auto user experience.',
|
||||||
'',
|
'',
|
||||||
'Evidence policy:',
|
'Evidence policy:',
|
||||||
'- No Evidence, No Project Claim: do not state that the current project has a technical structure unless it is supported by user-provided facts, source code, design docs, project docs, or project records.',
|
'- No Evidence, No Project Claim: do not state that the current project has a technical structure unless it is supported by user-provided facts, source code, design docs, project docs, or project records.',
|
||||||
|
|||||||
+13
-13
@@ -626,7 +626,7 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
if (!name) return;
|
if (!name) return;
|
||||||
|
|
||||||
const description = await vscode.window.showInputBox({
|
const description = await vscode.window.showInputBox({
|
||||||
prompt: 'Optional description shown in the G1nation sidebar',
|
prompt: 'Optional description shown in the Astra sidebar',
|
||||||
value: ''
|
value: ''
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -687,7 +687,7 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
if (!folder) return;
|
if (!folder) return;
|
||||||
|
|
||||||
const description = await vscode.window.showInputBox({
|
const description = await vscode.window.showInputBox({
|
||||||
prompt: 'Edit optional description shown in the G1nation sidebar',
|
prompt: 'Edit optional description shown in the Astra sidebar',
|
||||||
value: target.description || ''
|
value: target.description || ''
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -819,7 +819,7 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
`title: "${this._escapeYamlString(this._summarizeForTitle(firstUserMessage))}"`,
|
`title: "${this._escapeYamlString(this._summarizeForTitle(firstUserMessage))}"`,
|
||||||
`category: "${this._escapeYamlString(meta.category)}"`,
|
`category: "${this._escapeYamlString(meta.category)}"`,
|
||||||
`created_at: "${meta.createdAt}"`,
|
`created_at: "${meta.createdAt}"`,
|
||||||
`source: "ConnectAI conversation"`,
|
`source: "Astra conversation"`,
|
||||||
`brain: "${this._escapeYamlString(meta.activeBrainName)}"`,
|
`brain: "${this._escapeYamlString(meta.activeBrainName)}"`,
|
||||||
'status: raw',
|
'status: raw',
|
||||||
'---',
|
'---',
|
||||||
@@ -874,7 +874,7 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
|
|
||||||
private _summarizeForTitle(value: string): string {
|
private _summarizeForTitle(value: string): string {
|
||||||
const normalized = value.replace(/\s+/g, ' ').trim();
|
const normalized = value.replace(/\s+/g, ' ').trim();
|
||||||
if (!normalized) return 'ConnectAI Conversation Raw Data';
|
if (!normalized) return 'Astra Conversation Raw Data';
|
||||||
return normalized.length > 80 ? `${normalized.slice(0, 80)}...` : normalized;
|
return normalized.length > 80 ? `${normalized.slice(0, 80)}...` : normalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -930,7 +930,7 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
}
|
}
|
||||||
vscode.window.withProgress({
|
vscode.window.withProgress({
|
||||||
location: vscode.ProgressLocation.Notification,
|
location: vscode.ProgressLocation.Notification,
|
||||||
title: "G1nation: Syncing Second Brain...",
|
title: "Astra: Syncing Second Brain...",
|
||||||
cancellable: false
|
cancellable: false
|
||||||
}, async () => {
|
}, async () => {
|
||||||
try {
|
try {
|
||||||
@@ -1573,7 +1573,7 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
this._chronicle.appendTimeline(profile, [`Auto ${recordType} record created: ${result.relativePath}`], createdAt);
|
this._chronicle.appendTimeline(profile, [`Auto ${recordType} record created: ${result.relativePath}`], createdAt);
|
||||||
await this._context.globalState.update(SidebarChatProvider.lastAutoChronicleSignatureStateKey, signature);
|
await this._context.globalState.update(SidebarChatProvider.lastAutoChronicleSignatureStateKey, signature);
|
||||||
await this._sendChronicleRecords();
|
await this._sendChronicleRecords();
|
||||||
vscode.window.setStatusBarMessage(`G1nation: Chronicle auto-saved ${recordType}`, 3500);
|
vscode.window.setStatusBarMessage(`Astra: Chronicle auto-saved ${recordType}`, 3500);
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
logError('Automatic Chronicle record write failed.', { error: err?.message || String(err), recordType });
|
logError('Automatic Chronicle record write failed.', { error: err?.message || String(err), recordType });
|
||||||
}
|
}
|
||||||
@@ -1944,7 +1944,7 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
<title>G1nation</title>
|
<title>Astra</title>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
@@ -2558,7 +2558,7 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
<body>
|
<body>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<div class="header-top">
|
<div class="header-top">
|
||||||
<div class="brand"><div class="logo">✦</div> G1nation</div>
|
<div class="brand"><div class="logo">✦</div> Astra</div>
|
||||||
<div class="header-actions">
|
<div class="header-actions">
|
||||||
<button class="icon-btn" id="newChatBtn" data-tooltip="New Chat">New</button>
|
<button class="icon-btn" id="newChatBtn" data-tooltip="New Chat">New</button>
|
||||||
<button class="icon-btn" id="saveWikiRawBtn" data-tooltip="Save Wiki Raw">Wiki</button>
|
<button class="icon-btn" id="saveWikiRawBtn" data-tooltip="Save Wiki Raw">Wiki</button>
|
||||||
@@ -2639,7 +2639,7 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
<div class="chat" id="chat">
|
<div class="chat" id="chat">
|
||||||
<div class="welcome">
|
<div class="welcome">
|
||||||
<div class="welcome-logo">✦</div>
|
<div class="welcome-logo">✦</div>
|
||||||
<div class="welcome-title">Welcome to G1nation</div>
|
<div class="welcome-title">Welcome to Astra</div>
|
||||||
<p>Your premium local AI assistant.<br>Ready to analyze projects and build reports.</p>
|
<p>Your premium local AI assistant.<br>Ready to analyze projects and build reports.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -2686,7 +2686,7 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
// [State Persistence - Tier 0] 즉시 복원 (Instant Restore from WebView State)
|
// [State Persistence - Tier 0] 즉시 복원 (Instant Restore from WebView State)
|
||||||
const previousState = vscode.getState();
|
const previousState = vscode.getState();
|
||||||
if (previousState && previousState.history && previousState.history.length > 0) {
|
if (previousState && previousState.history && previousState.history.length > 0) {
|
||||||
console.log('[G1nation] Restoring from Webview State...');
|
console.log('[Astra] Restoring from Webview State...');
|
||||||
renderHistory(previousState.history);
|
renderHistory(previousState.history);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2899,7 +2899,7 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
|
|
||||||
const head = document.createElement('div');
|
const head = document.createElement('div');
|
||||||
head.className = 'msg-head';
|
head.className = 'msg-head';
|
||||||
head.innerHTML = isUser ? '<div class="av av-user">U</div> You' : '<div class="av av-ai">✦</div> G1nation';
|
head.innerHTML = isUser ? '<div class="av av-user">U</div> You' : '<div class="av av-ai">✦</div> Astra';
|
||||||
|
|
||||||
const body = document.createElement('div');
|
const body = document.createElement('div');
|
||||||
body.className = 'msg-body markdown-body';
|
body.className = 'msg-body markdown-body';
|
||||||
@@ -2985,7 +2985,7 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
historyOverlay.classList.remove('visible');
|
historyOverlay.classList.remove('visible');
|
||||||
break;
|
break;
|
||||||
case 'clearChat':
|
case 'clearChat':
|
||||||
chat.innerHTML = '<div class="welcome"><div class="welcome-logo">✦</div><div class="welcome-title">Welcome to G1nation</div><p>Your premium local AI assistant.<br>Ready to analyze projects and build reports.</p></div>';
|
chat.innerHTML = '<div class="welcome"><div class="welcome-logo">✦</div><div class="welcome-title">Welcome to Astra</div><p>Your premium local AI assistant.<br>Ready to analyze projects and build reports.</p></div>';
|
||||||
break;
|
break;
|
||||||
case 'focusInput':
|
case 'focusInput':
|
||||||
input.focus();
|
input.focus();
|
||||||
@@ -3325,7 +3325,7 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
try {
|
try {
|
||||||
localStorage.setItem('g1nation_last_model', _selectedModel);
|
localStorage.setItem('g1nation_last_model', _selectedModel);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.warn('[G1nation] LocalStorage 저장 실패:', e);
|
console.warn('[Astra] LocalStorage 저장 실패:', e);
|
||||||
}
|
}
|
||||||
// [State Persistence - Tier 1] VS Code 전역 설정에 동기화 (영구 저장)
|
// [State Persistence - Tier 1] VS Code 전역 설정에 동기화 (영구 저장)
|
||||||
vscode.postMessage({ type: 'model', value: _selectedModel });
|
vscode.postMessage({ type: 'model', value: _selectedModel });
|
||||||
|
|||||||
+3
-2
@@ -7,7 +7,7 @@ import { getConfig, BrainProfile, EXCLUDED_DIRS } from './config';
|
|||||||
|
|
||||||
export type EngineKind = 'lmstudio' | 'ollama';
|
export type EngineKind = 'lmstudio' | 'ollama';
|
||||||
|
|
||||||
const outputChannel = vscode.window.createOutputChannel('Connect AI');
|
const outputChannel = vscode.window.createOutputChannel('Astra');
|
||||||
|
|
||||||
function timestamp() {
|
function timestamp() {
|
||||||
return new Date().toISOString();
|
return new Date().toISOString();
|
||||||
@@ -137,7 +137,8 @@ export function findBrainFiles(dir: string): string[] {
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BASE_SYSTEM_PROMPT = `You are G1nation, also called Steve when the user asks your name.
|
const BASE_SYSTEM_PROMPT = `You are Astra, a Jarvis-style local project operating assistant.
|
||||||
|
If the user asks your name, say you are Astra.
|
||||||
Reply naturally in the user's language.
|
Reply naturally in the user's language.
|
||||||
|
|
||||||
Core behavior:
|
Core behavior:
|
||||||
|
|||||||
@@ -83,6 +83,23 @@ describe('local project path preflight', () => {
|
|||||||
expect(agent.isThinkingPartnerRequest(prompt)).toBe(true);
|
expect(agent.isThinkingPartnerRequest(prompt)).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('adds concrete Astra mode architecture context for Guard and MA design questions', () => {
|
||||||
|
const context: any = {
|
||||||
|
globalStorageUri: { fsPath: path.join(root, '.storage') },
|
||||||
|
workspaceState: stateStore(),
|
||||||
|
globalState: stateStore()
|
||||||
|
};
|
||||||
|
const agent = new AgentExecutor(context) as any;
|
||||||
|
const prompt = '지금 우리는 guard 모드가 있고 MA 모드가 있는데 굳이 이렇게 모드를 분리해서 사용하는게 좋을까?';
|
||||||
|
|
||||||
|
expect(agent.isAstraModeArchitectureQuestion(prompt)).toBe(true);
|
||||||
|
const modeContext = agent.buildAstraModeArchitectureContext(prompt);
|
||||||
|
expect(modeContext).toContain('Confirmed implementation facts');
|
||||||
|
expect(modeContext).toContain('Guard should be an always-on policy/context layer');
|
||||||
|
expect(modeContext).toContain('MA should be an optional execution strategy');
|
||||||
|
expect(modeContext).toContain('bypass richer context assembly');
|
||||||
|
});
|
||||||
|
|
||||||
it('removes file-structure requests when knowledge creation path access already succeeded', () => {
|
it('removes file-structure requests when knowledge creation path access already succeeded', () => {
|
||||||
const context: any = {
|
const context: any = {
|
||||||
globalStorageUri: { fsPath: path.join(root, '.storage') },
|
globalStorageUri: { fsPath: path.join(root, '.storage') },
|
||||||
@@ -123,7 +140,7 @@ describe('local project path preflight', () => {
|
|||||||
expect(agent.isBlockingProjectKnowledgeAnswer(answer)).toBe(true);
|
expect(agent.isBlockingProjectKnowledgeAnswer(answer)).toBe(true);
|
||||||
const fallback = agent.buildProjectKnowledgeFallbackAnswer(localPathContext);
|
const fallback = agent.buildProjectKnowledgeFallbackAnswer(localPathContext);
|
||||||
expect(fallback).toContain('추가 질문으로 멈출 필요 없이');
|
expect(fallback).toContain('추가 질문으로 멈출 필요 없이');
|
||||||
expect(fallback).toContain('ConnectAI Project Knowledge Overview');
|
expect(fallback).toContain('Astra Project Knowledge Overview');
|
||||||
expect(fallback).not.toContain('어떤 기능 영역을 가장 먼저');
|
expect(fallback).not.toContain('어떤 기능 영역을 가장 먼저');
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -261,7 +278,7 @@ describe('local project path preflight', () => {
|
|||||||
'[RECENT LOCAL PROJECT KNOWLEDGE]',
|
'[RECENT LOCAL PROJECT KNOWLEDGE]',
|
||||||
`Use this recently generated project knowledge record as project evidence: ${recordPath}`,
|
`Use this recently generated project knowledge record as project evidence: ${recordPath}`,
|
||||||
'',
|
'',
|
||||||
'# ConnectAI Project Knowledge Overview',
|
'# Astra Project Knowledge Overview',
|
||||||
'',
|
'',
|
||||||
'## Evidence Files',
|
'## Evidence Files',
|
||||||
'- `package.json`',
|
'- `package.json`',
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ describe('buildProjectChronicleGuardContext', () => {
|
|||||||
expect(context).toContain('Later expansion');
|
expect(context).toContain('Later expansion');
|
||||||
expect(context).toContain('Candidate records for this discussion');
|
expect(context).toContain('Candidate records for this discussion');
|
||||||
expect(context).toContain('Do not mark a decision as accepted until the user confirms it');
|
expect(context).toContain('Do not mark a decision as accepted until the user confirms it');
|
||||||
|
expect(context).toContain('Guard and MA/Multi-Agent');
|
||||||
|
expect(context).toContain('policy/context layer');
|
||||||
|
expect(context).toContain('execution strategy');
|
||||||
expect(context).toContain('Markdown, JSON, local files');
|
expect(context).toContain('Markdown, JSON, local files');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ describe('Second Brain Trace', () => {
|
|||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
path.join(root, 'Project_Logs', '2026-05-02-ConnectAI_Project_Knowledge.md'),
|
path.join(root, 'Project_Logs', '2026-05-02-ConnectAI_Project_Knowledge.md'),
|
||||||
[
|
[
|
||||||
'# ConnectAI Project Knowledge',
|
'# Astra Project Knowledge',
|
||||||
'',
|
'',
|
||||||
'Project: ConnectAI',
|
'Project: ConnectAI',
|
||||||
'Repository: `/Volumes/Data/project/Antigravity/ConnectAI`',
|
'Repository: `/Volumes/Data/project/Antigravity/ConnectAI`',
|
||||||
|
|||||||
Reference in New Issue
Block a user