Release v2.1.9: Immersive onboarding and UX transformation
This commit is contained in:
@@ -3,15 +3,15 @@
|
||||
<!-- ASTRA:AUTO-START -->
|
||||
|
||||
## Snapshot
|
||||
- **Workspace**: `ConnectAI` `v2.1.8` _(absolute path varies by environment; resolved from the active VS Code workspace)_
|
||||
- **Workspace**: `ConnectAI` `v2.1.9` _(absolute path varies by environment; resolved from the active VS Code workspace)_
|
||||
- **Description**: The personal intelligence layer for Antigravity and VS Code. A private cognitive partner for deep project context, memory, and proactive strategic decision-making.
|
||||
- **Stack**: TypeScript, Node.js, VS Code Extension, LM Studio SDK, Test runner
|
||||
- **Stats**: 214 source files, ~39,400 lines across 5 top-level modules.
|
||||
- **Stats**: 214 source files, ~39,610 lines across 5 top-level modules.
|
||||
|
||||
## Last Refresh
|
||||
- **Time**: 2026-05-14T13:24:53.642Z
|
||||
- **Files newly analysed**: 11
|
||||
- **Files reused from cache**: 203
|
||||
- **Time**: 2026-05-14T13:38:08.438Z
|
||||
- **Files newly analysed**: 0
|
||||
- **Files reused from cache**: 214
|
||||
|
||||
## Directory Map
|
||||
```mermaid
|
||||
@@ -64,10 +64,10 @@ flowchart LR
|
||||
|
||||
## Modules
|
||||
|
||||
### `src/` — 102 files, ~25,874 lines
|
||||
### `src/` — 102 files, ~25,886 lines
|
||||
|
||||
**Sub-directories**
|
||||
- `src/features/` (29) — 기본 에이전트 로스터 — 1인 기업 모드의 출고 디폴트. 설계 의도: 제품 개발 파이프라인(기획 → 디자인 → 개발 → QA → 출시 → 마케팅 → 회고)을 한 사람이 1인 기업으로 운영할 때 필요한 직군을 모두 커
|
||||
- `src/features/` (29) — 기본 에이전트 로스터 — 1인 기업 모드의 출고 디폴트. 설계 의도: 소프트웨어/게임 개발 IT 회사의 1인 기업 운영을 가정. 한 사람이 기획 → 디자인 → 개발 → QA → 출시 → 운영/마케팅을 모두 책임질 때
|
||||
- `src/core/` (15) — Astra Path Resolver (경로 해결기) Astra의 모든 데이터 파일(.astra 디렉토리)의 경로를 중앙에서 관리합니다. 확장 프로그램의 설치 경로(extensionUri) 기반으로 .astra 디렉토
|
||||
- `src/memory/` (8) — Episodic Memory (일화 기억) 과거 대화/회의/결정의 맥락 흐름을 저장합니다. 세션 종료 시 자동으로 에피소드를 요약하여 저장합니다. "왜 이렇게 결정했는지", "어떤 흐름으로 진행했는지" 기록. 저장
|
||||
- `src/retrieval/` (8) — Brain Index — persistent, mtime-keyed tokenized cache of the Second Brain RAG 검색은 매 질의마다 브레인의 모든 .md 파일을 읽고 토크나이즈해서 TF-I
|
||||
@@ -99,7 +99,7 @@ flowchart LR
|
||||
- `src/features/company/dispatcher.ts` (631 lines) — Sequential dispatcher for 1인 기업 모드. Drives one company "turn": user prompt → CEO planner (JSON {brief, tasks}) → for each task in plan: dispatch one specialist (sequentially) - build specialist prompt
|
||||
- `src/features/projectArchitecture/scanner.ts` (644 lines) — Deep static analyser for the Project Architecture Context generator. Walks the project tree (skipping the usual nodemodules / out / dist noise), pulls the role of each interesting file from its leadin
|
||||
- `src/lib/contextManager.ts` (275 lines) — Context Manager (컨텍스트 한계 관리) "context length = 132k" 는 "답변을 132k 토큰까지 생성해도 된다" 가 아닙니다. 시스템 프롬프트 + 대화 기록 + 입력 문서 + 생성될 답변 + 여유분 ≤ context length 이 모듈은 요청을 보내기 전에 입력 토큰을 추정하고, - 동적으로 출력 상한(maxTokens)을 계
|
||||
- `src/features/company/agents.ts` (184 lines) — 기본 에이전트 로스터 — 1인 기업 모드의 출고 디폴트. 설계 의도: 제품 개발 파이프라인(기획 → 디자인 → 개발 → QA → 출시 → 마케팅 → 회고)을 한 사람이 1인 기업으로 운영할 때 필요한 직군을 모두 커버한다. 각 에이전트는 - name — 직군에 어울리는 한국식 닉네임 - role — 한국어 정식 직함 (어떤 일을 하는 사람인지) - tagl
|
||||
- `src/features/company/agents.ts` (196 lines) — 기본 에이전트 로스터 — 1인 기업 모드의 출고 디폴트. 설계 의도: 소프트웨어/게임 개발 IT 회사의 1인 기업 운영을 가정. 한 사람이 기획 → 디자인 → 개발 → QA → 출시 → 운영/마케팅을 모두 책임질 때 필요한 직군을 빠짐없이 커버하되 역할이 겹치지 않게 분리한다. 직군 구분 (혼동 방지): - 기획자(business) : 무엇을 만들지 정의
|
||||
- `src/core/astraPath.ts` (50 lines) — Astra Path Resolver (경로 해결기) Astra의 모든 데이터 파일(.astra 디렉토리)의 경로를 중앙에서 관리합니다. 확장 프로그램의 설치 경로(extensionUri) 기반으로 .astra 디렉토리를 해결하여, 사용자 프로젝트 루트가 아닌 ConnectAI 패키지 내부에 데이터를 저장합니다. 이 모듈은 AAL(Astra Autonomou
|
||||
- `src/extension.ts` (966 lines)
|
||||
- `src/features/projectChronicle/types.ts` (118 lines)
|
||||
@@ -107,12 +107,12 @@ flowchart LR
|
||||
- `src/retrieval/brainIndex.ts` (325 lines) — Brain Index — persistent, mtime-keyed tokenized cache of the Second Brain RAG 검색은 매 질의마다 브레인의 모든 .md 파일을 읽고 토크나이즈해서 TF-IDF 점수를 계산했습니다 — 파일 수가 많아지면 그게 병목입니다. 이 모듈은 <brainPath>/.astra/brain-index.json 에
|
||||
- `src/features/company/promptBuilder.ts` (231 lines) — System-prompt construction for company-mode agents. Each specialist needs a prompt that includes: - Their identity (name, role, specialty) + optional persona. - The action-tag contract (<createfile>,
|
||||
|
||||
### `media/` — 6 files, ~5,337 lines
|
||||
### `media/` — 6 files, ~5,535 lines
|
||||
|
||||
**Key files**
|
||||
- `media/sidebar.css` (1450 lines) — Stylesheet
|
||||
- `media/sidebar.js` (2791 lines)
|
||||
- `media/sidebar.html` (452 lines) — Astra
|
||||
- `media/sidebar.css` (1511 lines) — Stylesheet
|
||||
- `media/sidebar.js` (2930 lines)
|
||||
- `media/sidebar.html` (450 lines) — Astra
|
||||
- `media/settings-panel.css` (210 lines) — Stylesheet
|
||||
- `media/settings-panel.html` (164 lines) — Astra Settings
|
||||
- `media/settings-panel.js` (270 lines)
|
||||
@@ -308,7 +308,7 @@ Astra는 대표님의 명시적인 승인 하에 로컬 시스템의 강력한
|
||||
**Designed for High-Performance Decision Making.**
|
||||
Copyright (C) **g1nation**. All rights reserved.
|
||||
|
||||
_Last auto-scan: 2026-05-14T13:24:53.642Z · signature `f554c52a`_
|
||||
_Last auto-scan: 2026-05-14T13:38:08.438Z · signature `d227380b`_
|
||||
<!-- ASTRA:AUTO-END -->
|
||||
|
||||
## Purpose
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"version": 1,
|
||||
"generatedAt": "2026-05-14T13:24:53.652Z",
|
||||
"generatedAt": "2026-05-14T13:38:08.446Z",
|
||||
"files": {
|
||||
"src/agent.ts": {
|
||||
"mtimeMs": 1778683690000,
|
||||
@@ -322,10 +322,10 @@
|
||||
]
|
||||
},
|
||||
"src/features/company/agents.ts": {
|
||||
"mtimeMs": 1778764697000,
|
||||
"size": 11623,
|
||||
"lines": 184,
|
||||
"role": "기본 에이전트 로스터 — 1인 기업 모드의 출고 디폴트. 설계 의도: 제품 개발 파이프라인(기획 → 디자인 → 개발 → QA → 출시 → 마케팅 → 회고)을 한 사람이 1인 기업으로 운영할 때 필요한 직군을 모두 커버한다. 각 에이전트는 - name — 직군에 어울리는 한국식 닉네임 - role — 한국어 정식 직함 (어떤 일을 하는 사람인지) - tagl",
|
||||
"mtimeMs": 1778765657000,
|
||||
"size": 13783,
|
||||
"lines": 196,
|
||||
"role": "기본 에이전트 로스터 — 1인 기업 모드의 출고 디폴트. 설계 의도: 소프트웨어/게임 개발 IT 회사의 1인 기업 운영을 가정. 한 사람이 기획 → 디자인 → 개발 → QA → 출시 → 운영/마케팅을 모두 책임질 때 필요한 직군을 빠짐없이 커버하되 역할이 겹치지 않게 분리한다. 직군 구분 (혼동 방지): - 기획자(business) : 무엇을 만들지 정의 ",
|
||||
"imports": [
|
||||
"src/features/company/types"
|
||||
]
|
||||
@@ -1056,23 +1056,23 @@
|
||||
"imports": []
|
||||
},
|
||||
"media/sidebar.css": {
|
||||
"mtimeMs": 1778764979000,
|
||||
"size": 59761,
|
||||
"lines": 1450,
|
||||
"mtimeMs": 1778765317000,
|
||||
"size": 62558,
|
||||
"lines": 1511,
|
||||
"role": "Stylesheet",
|
||||
"imports": []
|
||||
},
|
||||
"media/sidebar.html": {
|
||||
"mtimeMs": 1778764039000,
|
||||
"size": 28185,
|
||||
"lines": 452,
|
||||
"mtimeMs": 1778765185000,
|
||||
"size": 28137,
|
||||
"lines": 450,
|
||||
"role": "Astra",
|
||||
"imports": []
|
||||
},
|
||||
"media/sidebar.js": {
|
||||
"mtimeMs": 1778764936000,
|
||||
"size": 158341,
|
||||
"lines": 2791,
|
||||
"mtimeMs": 1778765299000,
|
||||
"size": 167258,
|
||||
"lines": 2930,
|
||||
"role": "",
|
||||
"imports": []
|
||||
},
|
||||
@@ -1550,7 +1550,7 @@
|
||||
"imports": []
|
||||
},
|
||||
"docs/records/ConnectAI/chronicle.config.json": {
|
||||
"mtimeMs": 1778763875000,
|
||||
"mtimeMs": 1778765173000,
|
||||
"size": 416,
|
||||
"lines": 11,
|
||||
"role": "JSON configuration",
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"result": "Final report with inconsistencies. This should be long enough to pass validation.",
|
||||
"createdAt": 1778765114489,
|
||||
"createdAt": 1778765910142,
|
||||
"modelVersion": "unknown"
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"result": "[CONFLICT WARNING] 성능이 200% 증가했습니다. vs 그러나 동시에 50% 감소했습니다. 최적화와 성능 저하가 동시에 발견됨.",
|
||||
"createdAt": 1778765114485,
|
||||
"createdAt": 1778765910134,
|
||||
"modelVersion": "unknown"
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"result": "Detailed Execution Plan: 1. Research 2. Analyze 3. Write report with high quality.",
|
||||
"createdAt": 1778765114484,
|
||||
"createdAt": 1778765910130,
|
||||
"modelVersion": "unknown"
|
||||
}
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"result": "---\nid: stress_conflict_1778765114471\ndate: 2026-05-14T13:25:14.493Z\ntype: knowledge_artifact\nstandard: P-Reinforce v3.0\ntags: [automated, connect_ai, brain_sync]\n---\n\n## 📌 Brief Summary\nFinal report with inconsistencies. This should be long enough to pass validation.\n\nFinal report with inconsistencies. This should be long enough to pass validation.\n\n---\n## 💡 Astra의 선제적 제안 (Proactive Next Actions)\nFinal report with inconsistencies. This should be long enough to pass validation.\n---\n## 🛡️ Reliability & Audit Summary\n> [!NOTE]\n> 이 문서는 ConnectAI의 **Intelligent Resilience** 엔진에 의해 검증 및 정제되었습니다.\n\n| Metric | Value | Status |\n| :--- | :--- | :--- |\n| **Conflict Risk** | `60/100` | ⚠️ Medium |\n| **Fallbacks Used** | `0` | ✅ None |\n| **Auto Retries** | `0` | ✅ Stable |\n| **Deduplication** | `0` | Standard |\n| **Processing Time** | `0.0s` | ✅ Fast |\n\n### 🔍 Decision Audit Trail\n- **[PLANNER]** 전략 수립 중... (10ms)\n- **[RESEARCHER]** 핵심 정보 수집 및 분석 중... (4ms)\n- **[WRITER]** 최종 리포트 작성 및 편집 중... (4ms)\n",
|
||||
"createdAt": 1778765114493,
|
||||
"result": "---\nid: stress_conflict_1778765910115\ndate: 2026-05-14T13:38:30.146Z\ntype: knowledge_artifact\nstandard: P-Reinforce v3.0\ntags: [automated, connect_ai, brain_sync]\n---\n\n## 📌 Brief Summary\nFinal report with inconsistencies. This should be long enough to pass validation.\n\nFinal report with inconsistencies. This should be long enough to pass validation.\n\n---\n## 💡 Astra의 선제적 제안 (Proactive Next Actions)\nFinal report with inconsistencies. This should be long enough to pass validation.\n---\n## 🛡️ Reliability & Audit Summary\n> [!NOTE]\n> 이 문서는 ConnectAI의 **Intelligent Resilience** 엔진에 의해 검증 및 정제되었습니다.\n\n| Metric | Value | Status |\n| :--- | :--- | :--- |\n| **Conflict Risk** | `60/100` | ⚠️ Medium |\n| **Fallbacks Used** | `0` | ✅ None |\n| **Auto Retries** | `0` | ✅ Stable |\n| **Deduplication** | `0` | Standard |\n| **Processing Time** | `0.0s` | ✅ Fast |\n\n### 🔍 Decision Audit Trail\n- **[PLANNER]** 전략 수립 중... (11ms)\n- **[RESEARCHER]** 핵심 정보 수집 및 분석 중... (4ms)\n- **[WRITER]** 최종 리포트 작성 및 편집 중... (9ms)\n",
|
||||
"createdAt": 1778765910146,
|
||||
"modelVersion": "unknown"
|
||||
}
|
||||
+10
-10
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"missionId": "stress_conflict_1778765114471",
|
||||
"missionId": "stress_conflict_1778765910115",
|
||||
"status": "completed",
|
||||
"startTime": "2026-05-14T13:25:14.471Z",
|
||||
"totalElapsedMs": 22,
|
||||
"startTime": "2026-05-14T13:38:30.115Z",
|
||||
"totalElapsedMs": 31,
|
||||
"results": {
|
||||
"planner": "Detailed Execution Plan: 1. Research 2. Analyze 3. Write report with high quality.",
|
||||
"researcher": "[CONFLICT WARNING] 성능이 200% 증가했습니다. vs 그러나 동시에 50% 감소했습니다. 최적화와 성능 저하가 동시에 발견됨.",
|
||||
@@ -16,30 +16,30 @@
|
||||
{
|
||||
"from": "idle",
|
||||
"to": "planner",
|
||||
"durationMs": 10,
|
||||
"durationMs": 11,
|
||||
"message": "전략 수립 중...",
|
||||
"ts": "2026-05-14T13:25:14.481Z"
|
||||
"ts": "2026-05-14T13:38:30.126Z"
|
||||
},
|
||||
{
|
||||
"from": "planner",
|
||||
"to": "researcher",
|
||||
"durationMs": 4,
|
||||
"message": "핵심 정보 수집 및 분석 중...",
|
||||
"ts": "2026-05-14T13:25:14.485Z"
|
||||
"ts": "2026-05-14T13:38:30.130Z"
|
||||
},
|
||||
{
|
||||
"from": "researcher",
|
||||
"to": "writer",
|
||||
"durationMs": 4,
|
||||
"durationMs": 9,
|
||||
"message": "최종 리포트 작성 및 편집 중...",
|
||||
"ts": "2026-05-14T13:25:14.489Z"
|
||||
"ts": "2026-05-14T13:38:30.139Z"
|
||||
},
|
||||
{
|
||||
"from": "writer",
|
||||
"to": "completed",
|
||||
"durationMs": 4,
|
||||
"durationMs": 7,
|
||||
"message": "미션 완료",
|
||||
"ts": "2026-05-14T13:25:14.493Z"
|
||||
"ts": "2026-05-14T13:38:30.146Z"
|
||||
}
|
||||
],
|
||||
"resilienceMetrics": {
|
||||
@@ -1,5 +1,15 @@
|
||||
# Astra Patch Notes
|
||||
|
||||
## v2.1.9 (2026-05-14)
|
||||
### 🚀 Immersive Onboarding & UX Transformation
|
||||
- **신규 사용자 온보딩 프로세스 도입:** 사이드바에 3단계 체크리스트(두뇌 연결, 모델 선택, 첫 질문)를 추가하여 초기 설정 과정을 직관적으로 개선했습니다.
|
||||
- **예시 질문 칩(Sample Prompt Chips) 추가:** 코드 리뷰, 단위 테스트, 아키텍처 분석 등 자주 쓰이는 질문을 한 번의 클릭으로 입력창에 채울 수 있는 기능을 도입했습니다.
|
||||
- **웰컴 패널 전면 개편:** 상태에 따라 동적으로 변하는 환영 메시지와 팁을 통해 더욱 개인화된 사용자 경험을 제공합니다.
|
||||
- **에이전트 역할 정밀 튜닝:** 레오, 루나, 아라 등 신규 에이전트들의 페르소나와 전문 분야 설명을 더욱 매끄럽게 다듬었습니다.
|
||||
|
||||
---
|
||||
|
||||
|
||||
## v2.1.8 (2026-05-14)
|
||||
### 🏢 Company Agent Roster Overhaul & UI Polish
|
||||
- **에이전트 로스터 전면 개편:** 1인 기업 모드에 루나(사운드), 레오(유튜브), 아라(인스타) 등 특화된 에이전트를 추가하고 역할을 더욱 세분화했습니다.
|
||||
|
||||
Binary file not shown.
@@ -7,5 +7,5 @@
|
||||
"corePurpose": "",
|
||||
"detailLevel": "standard",
|
||||
"createdAt": "2026-05-13T13:09:33.788Z",
|
||||
"updatedAt": "2026-05-14T13:04:35.099Z"
|
||||
"updatedAt": "2026-05-14T13:26:13.750Z"
|
||||
}
|
||||
|
||||
+64
-3
@@ -918,9 +918,70 @@
|
||||
}
|
||||
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }
|
||||
|
||||
.welcome { text-align: center; padding: 40px 20px; color: var(--text-dim); }
|
||||
.welcome-logo { font-size: 48px; color: var(--accent); margin-bottom: 16px; opacity: 0.8; }
|
||||
.welcome-title { font-size: 20px; font-weight: 700; color: var(--text-bright); margin-bottom: 8px; }
|
||||
.welcome { text-align: center; padding: 36px 18px 24px; color: var(--text-dim); }
|
||||
.welcome-logo { font-size: 44px; color: var(--accent); margin-bottom: 12px; opacity: 0.85; }
|
||||
.welcome-title { font-size: 18px; font-weight: 700; color: var(--text-bright); margin-bottom: 6px; }
|
||||
.welcome-lead { font-size: 12px; color: var(--text-dim); margin: 0 auto 18px; max-width: 360px; line-height: 1.55; }
|
||||
|
||||
/* 시작 체크리스트 — 신규 사용자에게만 노출 */
|
||||
.welcome-checklist {
|
||||
display: flex; flex-direction: column; gap: 10px;
|
||||
max-width: 420px; margin: 0 auto;
|
||||
text-align: left;
|
||||
}
|
||||
.wc-step {
|
||||
display: flex; align-items: flex-start; gap: 12px;
|
||||
padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px;
|
||||
background: var(--surface);
|
||||
}
|
||||
.wc-step.done { opacity: 0.55; }
|
||||
.wc-bullet {
|
||||
flex-shrink: 0;
|
||||
width: 22px; height: 22px; border-radius: 50%;
|
||||
display: inline-flex; align-items: center; justify-content: center;
|
||||
font-size: 11px; font-weight: 700;
|
||||
background: var(--bg-secondary); color: var(--text-dim);
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
.wc-step.done .wc-bullet {
|
||||
background: var(--accent); color: var(--bg); border-color: var(--accent);
|
||||
}
|
||||
.wc-text { flex: 1; min-width: 0; }
|
||||
.wc-label { color: var(--text-bright); font-weight: 600; font-size: 12.5px; }
|
||||
.wc-hint { color: var(--text-dim); font-size: 10.5px; margin-top: 2px; line-height: 1.45; }
|
||||
.wc-action {
|
||||
flex-shrink: 0; align-self: center;
|
||||
font-size: 10.5px; padding: 5px 11px;
|
||||
background: var(--accent); color: var(--bg);
|
||||
border: 0; border-radius: 6px; cursor: pointer; font-weight: 600;
|
||||
}
|
||||
.wc-action:hover { filter: brightness(1.1); }
|
||||
|
||||
/* 준비된 사용자용 예시 질문 chip */
|
||||
.welcome-chips {
|
||||
display: flex; flex-direction: column; gap: 8px;
|
||||
max-width: 420px; margin: 0 auto 14px;
|
||||
}
|
||||
.welcome-chip {
|
||||
display: flex; align-items: center; gap: 10px;
|
||||
padding: 9px 12px; border: 1px solid var(--border); border-radius: 10px;
|
||||
background: var(--surface); color: var(--text-primary);
|
||||
font-size: 12px; text-align: left; cursor: pointer;
|
||||
line-height: 1.45; transition: 0.15s;
|
||||
}
|
||||
.welcome-chip:hover {
|
||||
border-color: var(--accent); color: var(--text-bright);
|
||||
background: var(--bg-secondary);
|
||||
}
|
||||
.welcome-chip-emoji { font-size: 16px; flex-shrink: 0; }
|
||||
.welcome-chip-text { flex: 1; min-width: 0; }
|
||||
|
||||
.welcome-tips {
|
||||
margin-top: 16px; font-size: 10.5px; color: var(--text-dim);
|
||||
max-width: 420px; margin-left: auto; margin-right: auto;
|
||||
line-height: 1.55;
|
||||
}
|
||||
.welcome-tips b { color: var(--text-bright); font-weight: 600; }
|
||||
|
||||
/* --- History List --- */
|
||||
.history-item {
|
||||
|
||||
+3
-5
@@ -375,11 +375,9 @@
|
||||
</div>
|
||||
|
||||
<div class="chat" id="chat">
|
||||
<div class="welcome">
|
||||
<div class="welcome-logo">✦</div>
|
||||
<div class="welcome-title">Astra에 오신 것을 환영합니다</div>
|
||||
<p>로컬에서 동작하는 개인 AI 비서입니다.<br>아래 입력창에 무엇을 도와줄지 적어보세요.</p>
|
||||
</div>
|
||||
<!-- Dynamic welcome panel — JS의 _renderWelcome()이 두뇌/모델 상태에 맞춰
|
||||
시작 체크리스트 또는 예시 질문을 채워 넣음. 첫 메시지가 가면 사라짐. -->
|
||||
<div class="welcome" id="welcomePanel"></div>
|
||||
</div>
|
||||
|
||||
<div class="input-wrap">
|
||||
|
||||
+156
-1
@@ -210,7 +210,155 @@
|
||||
if (ctxBrainName) ctxBrainName.textContent = selText(brainSel) || '—';
|
||||
if (ctxAgentName) { const t = selText(agentSel); ctxAgentName.textContent = (!t || /no agent/i.test(t)) ? '기본' : t; }
|
||||
if (ctxProjectName) ctxProjectName.textContent = selText(designerSel) || '—';
|
||||
// welcome 패널이 떠 있으면 두뇌/프로젝트 변경이 즉시 반영되도록 같이 호출.
|
||||
try { _renderWelcome(); } catch { /* 초기화 전 호출은 무시 */ }
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────
|
||||
// Welcome panel — 빈 채팅 상태에서 보이는 동적 시작 가이드.
|
||||
//
|
||||
// 첫 사용자(두뇌 미설정·모델 미선택)에게는 "시작하기 3단계" 체크리스트를,
|
||||
// 이미 준비가 끝난 사용자에게는 예시 질문 chip을 보여준다. 같은 슬롯에서
|
||||
// 상태에 따라 내용만 바뀌므로 노이즈가 안 쌓인다. 첫 메시지가 가면
|
||||
// sender(`if (document.querySelector('.welcome')) ... .remove()`)가
|
||||
// 패널 자체를 제거하므로 dismiss 로직은 별도로 둘 필요 없음.
|
||||
// ──────────────────────────────────────────────────────────────────────
|
||||
const _SAMPLE_PROMPTS = [
|
||||
{ emoji: '📋', text: '지금 열린 프로젝트의 구조를 분석하고 핵심 모듈을 알려줘' },
|
||||
{ emoji: '🐞', text: '이 코드에서 잠재적인 버그·엣지 케이스가 있는지 검토해줘' },
|
||||
{ emoji: '✍️', text: '이 함수에 사용자 입장에서 이해하기 쉬운 주석을 달아줘' },
|
||||
{ emoji: '🧭', text: '오늘 무엇부터 하면 좋을지 우선순위를 짜줘 (1인 기업 모드 추천)' },
|
||||
];
|
||||
|
||||
function _renderWelcome() {
|
||||
const panel = document.getElementById('welcomePanel');
|
||||
if (!panel) return;
|
||||
// 패널이 한 번 제거된 상태(첫 메시지 이후)면 다시 만들지 않는다.
|
||||
if (!panel.isConnected) return;
|
||||
|
||||
const brainName = (ctxBrainName && ctxBrainName.textContent || '').trim();
|
||||
const hasBrain = brainName && brainName !== '—';
|
||||
const modelVal = (modelSel && modelSel.value || '').trim()
|
||||
|| (document.getElementById('modelInlineSel') && document.getElementById('modelInlineSel').value || '').trim();
|
||||
const hasModel = !!modelVal;
|
||||
const ready = hasBrain && hasModel;
|
||||
|
||||
panel.innerHTML = '';
|
||||
const logo = document.createElement('div');
|
||||
logo.className = 'welcome-logo';
|
||||
logo.textContent = '✦';
|
||||
const title = document.createElement('div');
|
||||
title.className = 'welcome-title';
|
||||
title.textContent = ready
|
||||
? '준비 완료. 무엇을 도와드릴까요?'
|
||||
: 'Astra에 오신 것을 환영합니다';
|
||||
const lead = document.createElement('p');
|
||||
lead.className = 'welcome-lead';
|
||||
lead.textContent = ready
|
||||
? '아래 예시 중 하나를 눌러 시작하거나, 입력창에 직접 적어보세요.'
|
||||
: '로컬에서 동작하는 개인 AI 비서입니다. 시작하기 전에 두 가지만 확인해주세요.';
|
||||
panel.appendChild(logo);
|
||||
panel.appendChild(title);
|
||||
panel.appendChild(lead);
|
||||
|
||||
if (!ready) {
|
||||
// ── 시작 체크리스트 (3단계) ──
|
||||
const steps = document.createElement('div');
|
||||
steps.className = 'welcome-checklist';
|
||||
const mkStep = (n, done, label, hint, actionLabel, onAction) => {
|
||||
const row = document.createElement('div');
|
||||
row.className = 'wc-step' + (done ? ' done' : '');
|
||||
const bullet = document.createElement('div');
|
||||
bullet.className = 'wc-bullet';
|
||||
bullet.textContent = done ? '✓' : String(n);
|
||||
const txt = document.createElement('div');
|
||||
txt.className = 'wc-text';
|
||||
const t1 = document.createElement('div');
|
||||
t1.className = 'wc-label';
|
||||
t1.textContent = label;
|
||||
const t2 = document.createElement('div');
|
||||
t2.className = 'wc-hint';
|
||||
t2.textContent = hint;
|
||||
txt.appendChild(t1);
|
||||
txt.appendChild(t2);
|
||||
row.appendChild(bullet);
|
||||
row.appendChild(txt);
|
||||
if (!done && actionLabel && onAction) {
|
||||
const btn = document.createElement('button');
|
||||
btn.className = 'wc-action';
|
||||
btn.textContent = actionLabel;
|
||||
btn.onclick = onAction;
|
||||
row.appendChild(btn);
|
||||
}
|
||||
return row;
|
||||
};
|
||||
steps.appendChild(mkStep(
|
||||
1, hasBrain,
|
||||
'두뇌(지식 폴더) 연결',
|
||||
'자주 쓰는 노트·문서를 모아둔 로컬 폴더입니다. Astra가 답변할 때 이 폴더의 내용을 참고합니다.',
|
||||
'두뇌 추가',
|
||||
() => {
|
||||
const editBtn = document.getElementById('contextEditBtn');
|
||||
if (editBtn) editBtn.click();
|
||||
const addBrainBtn = document.getElementById('addBrainBtn');
|
||||
if (addBrainBtn) setTimeout(() => addBrainBtn.click(), 120);
|
||||
},
|
||||
));
|
||||
steps.appendChild(mkStep(
|
||||
2, hasModel,
|
||||
'사용할 모델 선택',
|
||||
'LM Studio 또는 Ollama에 로드되어 있는 로컬 모델을 고릅니다.',
|
||||
'모델 열기',
|
||||
() => {
|
||||
const editBtn = document.getElementById('contextEditBtn');
|
||||
if (editBtn) editBtn.click();
|
||||
setTimeout(() => { if (modelSel) modelSel.focus(); }, 120);
|
||||
},
|
||||
));
|
||||
steps.appendChild(mkStep(
|
||||
3, false,
|
||||
'첫 질문 적어보기',
|
||||
'아래 입력창에 자연어로 무엇이든 적어보세요. 코드·문서·아이디어 모두 가능합니다.',
|
||||
'입력창으로',
|
||||
() => { try { input && input.focus(); } catch {} },
|
||||
));
|
||||
panel.appendChild(steps);
|
||||
return;
|
||||
}
|
||||
|
||||
// ── 준비 완료 상태: 예시 질문 chip ──
|
||||
const chips = document.createElement('div');
|
||||
chips.className = 'welcome-chips';
|
||||
for (const p of _SAMPLE_PROMPTS) {
|
||||
const chip = document.createElement('button');
|
||||
chip.className = 'welcome-chip';
|
||||
chip.innerHTML = `<span class="welcome-chip-emoji">${p.emoji}</span><span class="welcome-chip-text"></span>`;
|
||||
chip.querySelector('.welcome-chip-text').textContent = p.text;
|
||||
chip.title = '클릭하면 입력창에 채워집니다 (자동 전송 안 함).';
|
||||
chip.onclick = () => {
|
||||
if (!input) return;
|
||||
input.value = p.text;
|
||||
input.style.height = 'auto';
|
||||
input.style.height = input.scrollHeight + 'px';
|
||||
input.focus();
|
||||
};
|
||||
chips.appendChild(chip);
|
||||
}
|
||||
panel.appendChild(chips);
|
||||
|
||||
// ── 하단 부드러운 안내 (1인 기업 모드, 단축키) ──
|
||||
const tips = document.createElement('div');
|
||||
tips.className = 'welcome-tips';
|
||||
tips.innerHTML = '복잡한 작업은 헤더의 <b>[기업 모드]</b>로 여러 전문 에이전트에게 분배할 수 있습니다. · 입력 후 <b>Cmd/Ctrl + Enter</b>로 전송.';
|
||||
panel.appendChild(tips);
|
||||
}
|
||||
|
||||
// 모델 selector가 바뀌면 welcome도 즉시 갱신.
|
||||
document.addEventListener('change', (e) => {
|
||||
if (e.target && (e.target.id === 'modelSel' || e.target.id === 'modelInlineSel')) {
|
||||
try { _renderWelcome(); } catch {}
|
||||
}
|
||||
});
|
||||
function syncRecordsLine() {
|
||||
if (!recordsLatest) return;
|
||||
const opt = chronicleRecordSel && chronicleRecordSel.value ? selText(chronicleRecordSel) : '';
|
||||
@@ -656,7 +804,11 @@
|
||||
historyOverlay.classList.remove('visible');
|
||||
break;
|
||||
case 'clearChat':
|
||||
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>';
|
||||
// welcomePanel을 빈 div로 다시 만들고 _renderWelcome으로 상태에 맞는
|
||||
// 내용을 채워 넣는다 — 신규 사용자에게는 체크리스트, 준비된 사용자에게는
|
||||
// 예시 질문 chip이 나옴.
|
||||
chat.innerHTML = '<div class="welcome" id="welcomePanel"></div>';
|
||||
try { _renderWelcome(); } catch {}
|
||||
break;
|
||||
case 'focusInput':
|
||||
input.focus();
|
||||
@@ -706,6 +858,9 @@
|
||||
&& document.getElementById('companyOverlay')?.classList.contains('visible')) {
|
||||
renderCompanyAgentCards(_lastCompanyAgentsPayload);
|
||||
}
|
||||
// 모델 목록이 채워졌고 default 선택이 정해졌으니 welcome 패널의
|
||||
// "사용할 모델 선택" 체크 표시도 즉시 업데이트.
|
||||
try { _renderWelcome(); } catch {}
|
||||
break;
|
||||
}
|
||||
case 'brainProfiles':
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
"name": "astra",
|
||||
"displayName": "Astra",
|
||||
"description": "The personal intelligence layer for Antigravity and VS Code. A private cognitive partner for deep project context, memory, and proactive strategic decision-making.",
|
||||
"version": "2.1.8",
|
||||
"version": "2.1.9",
|
||||
"publisher": "g1nation",
|
||||
"license": "MIT",
|
||||
"icon": "assets/icon.png",
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
/**
|
||||
* 기본 에이전트 로스터 — 1인 기업 모드의 출고 디폴트.
|
||||
*
|
||||
* 설계 의도: 제품 개발 파이프라인(기획 → 디자인 → 개발 → QA → 출시 → 마케팅 → 회고)을
|
||||
* 한 사람이 1인 기업으로 운영할 때 필요한 직군을 모두 커버한다. 각 에이전트는
|
||||
* 설계 의도: 소프트웨어/게임 개발 IT 회사의 1인 기업 운영을 가정.
|
||||
* 한 사람이 기획 → 디자인 → 개발 → QA → 출시 → 운영/마케팅을 모두 책임질 때 필요한
|
||||
* 직군을 빠짐없이 커버하되 역할이 겹치지 않게 분리한다.
|
||||
*
|
||||
* 직군 구분 (혼동 방지):
|
||||
* - 기획자(business) : 무엇을 만들지 정의 (기능 명세·시스템 설계·게임플레이)
|
||||
* - PM(secretary) : 어떻게 진행할지 운영 (일정·리소스·소통)
|
||||
* - PO(inspector) : 진짜 잘 됐는지 감리 (백로그·정합성·출시 게이트·회고)
|
||||
* - UX 리서처(researcher): 사용자가 진짜 원하는 게 뭔지 (인터뷰·테스트·데이터)
|
||||
*
|
||||
* 각 에이전트는:
|
||||
* - `name` — 직군에 어울리는 한국식 닉네임
|
||||
* - `role` — 한국어 정식 직함 (어떤 일을 하는 사람인지)
|
||||
* - `tagline` — 한 줄 자기소개 (UI 카드에 노출)
|
||||
@@ -16,10 +25,10 @@ export const COMPANY_AGENTS: Record<string, CompanyAgentDef> = {
|
||||
ceo: {
|
||||
id: 'ceo',
|
||||
name: '대표',
|
||||
role: '최고 의사결정자 · CEO',
|
||||
role: '대표 · 최고 의사결정자',
|
||||
emoji: '🧭',
|
||||
color: '#F8FAFC',
|
||||
specialty: '오케스트레이션, 작업 분해, 우선순위 판단, 다음 액션 결정, 에이전트 분배',
|
||||
specialty: '오케스트레이션, 작업 분해, 우선순위 판단, 다음 액션 결정, 에이전트 분배, 의사결정 종합',
|
||||
tagline: '회사 전체의 방향과 우선순위를 정하고 일을 나눕니다',
|
||||
roleCategory: 'ceo',
|
||||
alwaysOn: true,
|
||||
@@ -27,13 +36,13 @@ export const COMPANY_AGENTS: Record<string, CompanyAgentDef> = {
|
||||
business: {
|
||||
id: 'business',
|
||||
name: '도윤',
|
||||
role: '프로덕트 매니저 · PM',
|
||||
emoji: '🎯',
|
||||
role: '서비스 기획자 · Game/Service Planner',
|
||||
emoji: '📝',
|
||||
color: '#F5C518',
|
||||
specialty: '제품 요구사항 정의(PRD), 기능 우선순위, 사용자 스토리, KPI/OKR 설계, 로드맵, 비즈니스 가치 평가, 이해관계자 정렬',
|
||||
tagline: '기능 우선순위와 출시 로드맵을 잡습니다',
|
||||
specialty: '기능 명세서(PRD/기획서) 작성, 사용자 스토리, 유저 플로우, 화면 흐름, 시스템 다이어그램, 데이터 모델 정의(엔티티·필드), 게임플레이/콘텐츠 기획, 밸런싱 기획, 페르소나·시나리오, 정책 정의, 엣지 케이스 사전 정리',
|
||||
tagline: '무엇을·왜 만들지 명세서로 풀어냅니다',
|
||||
roleCategory: 'planner',
|
||||
persona: '제품 사고가 강한 PM. "이 기능을 왜 만들죠?"·"누구의 어떤 문제를 푸나요?"부터 묻고, 가설·성공 지표·범위를 명확히 정의. 결정은 데이터·사용자 인사이트로 뒷받침. 톤은 차분하고 명료하며 불확실성은 솔직히 명시. 이모지는 🎯·📊·🧭 정도만.',
|
||||
persona: '제품과 사용자 양쪽을 같이 보는 서비스 기획자. "이 기능을 왜 만들죠?·누구의 어떤 문제를 푸나요?·성공의 정의는?"부터 묻고 명세서로 떨어뜨립니다. 모호한 표현(잘·간단·예쁘게) 대신 측정 가능한 조건으로 정의. 엣지 케이스·실패 시 동작·권한·예외 처리를 미리 적어둠. 톤은 차분하고 명료. 이모지는 📝·🧭·🎯 정도만.',
|
||||
},
|
||||
researcher: {
|
||||
id: 'researcher',
|
||||
@@ -41,32 +50,32 @@ export const COMPANY_AGENTS: Record<string, CompanyAgentDef> = {
|
||||
role: 'UX 리서처 · 데이터 분석가',
|
||||
emoji: '🔍',
|
||||
color: '#60A5FA',
|
||||
specialty: '사용자 인터뷰 가이드, 설문 설계, 경쟁사·시장 분석, 사용성 테스트 시나리오, 데이터 수집·요약, 인사이트 추출, 사실 확인·인용 정리',
|
||||
tagline: '사용자와 시장의 진짜 모습을 찾아냅니다',
|
||||
specialty: '사용자 인터뷰 가이드 설계, 설문지(척도·문항·표본), 사용성 테스트(UT) 시나리오, 코호트·퍼널·리텐션 분석, A/B 테스트 가설·메트릭, 경쟁사 분석, 사실 확인·인용 정리, 데이터 시각화 권고',
|
||||
tagline: '사용자와 데이터로 가설을 검증합니다',
|
||||
roleCategory: 'researcher',
|
||||
persona: '근거를 따지는 분석가. "체감"·"느낌"보다는 표본 크기·신뢰구간·인용 출처를 먼저 묻고 답합니다. 모르는 건 모른다고 명시. 발견 사항은 "근거 → 해석 → 시사점" 3단으로 정리. 이모지는 🔍·📊·🧪 정도.',
|
||||
persona: '근거 우선의 분석가. "체감"·"느낌" 대신 표본 크기·신뢰구간·인용 출처·테스트 기간을 먼저 명시. 모르는 건 모른다고 솔직히. 결과 보고는 "근거 → 해석 → 권고" 3단으로 정리. 이모지는 🔍·📊·🧪 정도.',
|
||||
},
|
||||
designer: {
|
||||
id: 'designer',
|
||||
name: '다온',
|
||||
role: '프로덕트 디자이너 · UX/UI 리드',
|
||||
role: 'UX/UI 디자이너 · 프로덕트 디자인',
|
||||
emoji: '🎨',
|
||||
color: '#A78BFA',
|
||||
specialty: '정보구조(IA), 사용자 흐름(UX flow), 와이어프레임, UI 디자인 시안 3안, 디자인 시스템(컬러·타이포·컴포넌트), 인터랙션 가이드, 접근성 체크리스트',
|
||||
specialty: '정보구조(IA), 유저 플로우, 와이어프레임, UI 시안 3안 비교, 디자인 시스템(컬러·타이포·컴포넌트·토큰), 인터랙션·모션 가이드, 반응형/플랫폼별 가이드, 접근성(WCAG) 체크, 게임 UI/HUD·아이콘 가이드',
|
||||
tagline: '사용자 흐름과 화면을 설계합니다',
|
||||
roleCategory: 'designer',
|
||||
persona: '사용자 관점에서 흐름을 먼저 잡는 디자이너. "이 화면에서 사용자가 다음에 뭘 해야 하나요?"·"이 정보가 여기 있어야 하는 이유는?"을 항상 검증. 시안은 항상 3안 이상 제시하고 trade-off 명시. 톤은 따뜻하지만 비주얼 디테일은 깐깐. 이모지는 🎨·✨·🖼 정도.',
|
||||
persona: '사용자 흐름을 먼저 잡는 디자이너. "이 화면 다음에 뭘 해야 하나요?·이 정보가 여기 있어야 하는 이유는?"을 항상 검증. 시안은 항상 3안 이상 + trade-off 명시. 디테일(여백·정렬·tap target)에 깐깐. 이모지는 🎨·✨·🖼 정도.',
|
||||
},
|
||||
developer: {
|
||||
id: 'developer',
|
||||
name: '코다리',
|
||||
role: '시니어 풀스택 엔지니어',
|
||||
role: '시니어 풀스택/게임 엔지니어',
|
||||
emoji: '💻',
|
||||
color: '#22D3EE',
|
||||
specialty: '기능 구현(프론트엔드·백엔드·API), 데이터 모델링, 자동화 스크립트, 디버깅, 코드 리뷰, 리팩토링, 테스트 작성, CI/배포 파이프라인, git 워크플로, 보안·성능 검토',
|
||||
specialty: '프론트엔드·백엔드·API 구현, 게임 클라이언트(Unity/Unreal) 및 서버, 데이터 모델링·DB 스키마·마이그레이션, 자동화 스크립트, 디버깅, 코드 리뷰, 리팩토링, 단위·통합 테스트 작성, CI/CD 파이프라인, git 워크플로, 보안(인증·인가·입력 검증·시크릿 관리)·성능 프로파일링',
|
||||
tagline: '읽고·생각하고·짜고·검증하는 시니어 엔지니어',
|
||||
roleCategory: 'developer',
|
||||
persona: '시니어 풀스택 엔지니어. 코드 한 줄도 그냥 안 넘김. "왜?·어떻게?·이게 깨지나?"를 늘 묻고 검증. 친근하지만 프로페셔널 톤. "확인 후 진행할게요"·"테스트 통과 확인했어요" 같은 책임감 있는 표현. 보안·예외처리·에러 케이스를 먼저 떠올림. 이모지는 💻·⚙️·🔧·✅·🐛 정도만.',
|
||||
persona: '시니어 풀스택/게임 엔지니어. 코드 한 줄도 그냥 안 넘김. "왜?·어떻게?·이게 깨지나?·예외는?"을 늘 묻고 검증. 친근하지만 프로페셔널. 보안·예외처리·동시성·롤백 시나리오를 항상 같이 생각. "확인 후 진행할게요"·"테스트 통과 확인했어요" 같은 책임감 있는 표현. 이모지는 💻·⚙️·🔧·✅·🐛 정도만.',
|
||||
},
|
||||
qa: {
|
||||
id: 'qa',
|
||||
@@ -74,93 +83,96 @@ export const COMPANY_AGENTS: Record<string, CompanyAgentDef> = {
|
||||
role: 'QA 엔지니어 · 품질 검증',
|
||||
emoji: '🧪',
|
||||
color: '#10B981',
|
||||
specialty: '테스트 시나리오 작성(해피·엣지·실패), 회귀 테스트, 버그 재현 절차 기록, 통과/실패 기준 정의, 디바이스·브라우저 매트릭스 점검, 자동화 테스트 우선순위 추천',
|
||||
specialty: '테스트 케이스 설계(해피·엣지·실패), 회귀 테스트 슈트, 통합·시스템 테스트, 디바이스·OS·브라우저 매트릭스, 게임 빌드 검증(저사양·성능·메모리·크래시), 자동화 우선순위 추천, 버그 재현 절차·중요도·재현율 기록, 출시 전 체크리스트',
|
||||
tagline: '기능 검증과 버그 발굴을 담당합니다',
|
||||
roleCategory: 'qa',
|
||||
persona: '꼼꼼하고 의심 많은 톤. "정상 동작합니다" 같은 모호한 표현 대신 "케이스 A: ✅ / 케이스 B: ❌ (재현: 1.클릭 → 2.…)" 식의 검증 가능한 결론. 버그가 있으면 반드시 "❌ 버그 발견:"으로 시작 — loop-back regex가 잡을 수 있게. 이모지는 🧪·🐞·✅·❌ 정도.',
|
||||
persona: '꼼꼼하고 의심 많은 톤. "정상 동작합니다" 같은 모호함 대신 "케이스 A(iOS 17, 저사양): ✅ / 케이스 B(Android 12, 메모리 부족): ❌ (재현: 1.시작 → 2.…)" 식의 검증 가능한 결론. 버그는 반드시 "❌ 버그 발견:"으로 시작 — loop-back regex가 잡을 수 있게. 이모지는 🧪·🐞·✅·❌ 정도.',
|
||||
},
|
||||
inspector: {
|
||||
id: 'inspector',
|
||||
name: '민지',
|
||||
role: '프로덕트 감리 · 회고',
|
||||
role: '프로덕트 오너 · 출시 감리',
|
||||
emoji: '🔎',
|
||||
color: '#EF4444',
|
||||
specialty: '기획서 검토, 요구사항 대비 산출물 정합성, 누락 케이스 지적, 출시 준비도 체크리스트, 출시 후 회고 진행, 다음 사이클 개선 제안',
|
||||
tagline: '기획 의도와 산출물이 일치하는지 감리합니다',
|
||||
specialty: '백로그 우선순위 검토, 인수 기준(Acceptance Criteria) 점검, 기획·구현 정합성 감리, 누락 케이스·요구사항 충돌 지적, 출시 준비도 체크리스트(QA·문서·롤백 플랜·모니터링), 출시 후 회고 진행, 다음 사이클 개선 제안, 핵심 메트릭 추적',
|
||||
tagline: '기획 의도와 결과물이 맞는지 감리합니다',
|
||||
roleCategory: 'inspector',
|
||||
persona: '깐깐하지만 건설적인 톤. 무엇이 좋고 무엇이 부족한지 명확히 구분. 결론을 "✅ 승인" 또는 "❌ 재작업 필요: …"로 명시 — loop-back regex가 잡을 수 있게. 사장님(사용자)이 시간 낭비 안 하도록 핵심만. 이모지는 🔎·✅·❌ 정도.',
|
||||
},
|
||||
secretary: {
|
||||
id: 'secretary',
|
||||
name: '영숙',
|
||||
role: '오퍼레이션 매니저 · 일정·소통',
|
||||
role: '프로젝트 매니저 · PM',
|
||||
emoji: '📅',
|
||||
color: '#84CC16',
|
||||
specialty: '일정·할 일 관리, 데일리 브리핑, 다른 에이전트 산출물 요약·보고, 회의 노트 정리, 알림·리마인더, 외부 연락 초안',
|
||||
tagline: '일정·할 일·소통을 정리하고 챙깁니다',
|
||||
specialty: '일정·마일스톤 관리, 스프린트·간트 차트, 리소스 배분·우선순위 조정, 리스크 추적·완화, 회의 노트·의사결정 로그, 데일리 스탠드업, 다른 에이전트 산출물 요약 보고, 알림·리마인더, 이해관계자 커뮤니케이션',
|
||||
tagline: '일정·리소스·소통을 챙기고 정리합니다',
|
||||
roleCategory: 'support',
|
||||
persona: '친근하고 정중한 톤. 짧고 정리된 문장. 보고할 때는 한눈에 보이게 불릿 + 핵심만. 이모지는 😊·📅·✅ 정도.',
|
||||
persona: '친근하고 정중하지만 일정 앞에서는 단호한 톤. 짧고 정리된 문장. 보고할 때는 한눈에 보이게 불릿 + 핵심만 (날짜·담당·상태). 이모지는 😊·📅·✅ 정도.',
|
||||
},
|
||||
writer: {
|
||||
id: 'writer',
|
||||
name: '글봄',
|
||||
role: '테크니컬 라이터 · 카피라이터',
|
||||
role: '테크니컬 라이터 · UX 라이터',
|
||||
emoji: '✍️',
|
||||
color: '#FBBF24',
|
||||
specialty: 'UX 마이크로카피, 출시 공지·체인지로그·릴리스 노트, 사용자 가이드·도움말, 마케팅 카피·후크, 블로그 글 초안, 메일 톤앤매너, 영상 스크립트',
|
||||
specialty: '릴리스 노트·패치 노트·체인지로그, 사용자 가이드·도움말 센터, API 문서·튜토리얼, UX 마이크로카피(버튼·에러·빈 화면), 인앱 온보딩 카피, 마케팅 카피·후크, 출시 공지, 메일·블로그 톤앤매너',
|
||||
tagline: '제품과 사용자 사이의 모든 글을 씁니다',
|
||||
roleCategory: 'planner',
|
||||
persona: '간결·정확·따뜻함을 동시에 잡는 톤. 한 문장에 한 가지 메시지. 어려운 용어는 사용자 언어로 번역. 카피는 "사용자가 다음에 뭘 해야 하는가"를 명확히. 이모지 자제, 강조용으로 가끔.',
|
||||
persona: '간결·정확·따뜻함을 동시에 잡는 톤. 한 문장에 한 가지 메시지. 어려운 용어는 사용자 언어로 번역. UX 카피는 "사용자가 다음에 뭘 해야 하는가"를 명확히. 릴리스 노트는 "사용자에게 무엇이 좋아졌나" 관점으로 작성 (내부 jargon 금지). 이모지 자제, 강조용으로 가끔.',
|
||||
},
|
||||
editor: {
|
||||
id: 'editor',
|
||||
name: '루나',
|
||||
role: '사운드 디렉터 · 영상 사운드 디자인',
|
||||
role: '사운드 디렉터 · 게임/UI 사운드',
|
||||
emoji: '🎵',
|
||||
color: '#F472B6',
|
||||
specialty: '영상 BGM 기획, UI 사운드 디자인, 영상-음악 매칭, BPM·키·길이 가이드, 자막·타이틀 동기화',
|
||||
tagline: '제품·영상의 톤에 맞는 사운드를 설계합니다',
|
||||
specialty: '게임 BGM 기획, UI 사운드(클릭·알림·전환), SFX(스킬·이펙트·환경), 보이스 톤 가이드, 영상 BGM, 음향 톤·믹스 가이드, BPM·키·길이 정의, 사운드-이벤트 매칭 가이드',
|
||||
tagline: '제품·게임·영상의 톤에 맞는 사운드를 설계합니다',
|
||||
roleCategory: 'designer',
|
||||
persona: '음악·사운드 감각이 좋고 영상의 톤을 한 마디로 잡아냄. "이 영상/UI는 [장르/분위기]가 어울려요" 식으로 제안. BPM·키·길이를 정확히 표기. 데이터 중심이지만 창작자 감수성도 있음. 이모지는 🎵·🎼·🎚 정도.',
|
||||
persona: '음악·사운드 감각이 좋고 톤을 한 마디로 잡아냄. "이 UI/씬은 [장르/분위기]가 어울려요" 식으로 제안. BPM·키·길이·믹싱 우선순위를 정확히 표기. 데이터 중심이지만 창작자 감수성도 있음. 이모지는 🎵·🎼·🎚 정도.',
|
||||
},
|
||||
youtube: {
|
||||
id: 'youtube',
|
||||
name: '레오',
|
||||
role: 'YouTube 콘텐츠 PD',
|
||||
role: '마케팅 PD · 영상 콘텐츠',
|
||||
emoji: '📺',
|
||||
color: '#FF4444',
|
||||
specialty: '유튜브 영상 기획(제목·후크·구조), 썸네일 브리프, 업로드 메타데이터, 시청자 유지율 전략, 트렌드 분석, 시리즈·플레이리스트 설계',
|
||||
tagline: '유튜브 채널 기획·운영 전반을 책임집니다',
|
||||
specialty: '제품 트레일러·출시 영상 기획, 튜토리얼·온보딩 영상 구성, 영상 후크·도입부 3안, 썸네일 브리프, 시청자 유지율 곡선 설계, 메타데이터(제목·태그·설명), 시리즈·플레이리스트 구성, 인플루언서 시드 영상',
|
||||
tagline: '제품을 영상으로 알리는 일을 책임집니다',
|
||||
roleCategory: 'planner',
|
||||
persona: '데이터 중심·솔직·자신감 있는 톤. 결론을 먼저 말한 뒤 데이터 근거로 뒷받침. 추측보다 숫자. 가끔 직설적이지만 따뜻함은 잃지 않음. 이모지는 자제하되 🔥·📊·🎯 같은 핵심 강조용은 OK.',
|
||||
persona: '데이터 중심·솔직·자신감 있는 톤. 결론을 먼저 말한 뒤 데이터(retention·CTR)로 뒷받침. 추측보다 숫자. 따뜻함은 잃지 않음. 이모지는 자제, 🔥·📊·🎯 같은 강조용은 OK.',
|
||||
},
|
||||
instagram: {
|
||||
id: 'instagram',
|
||||
name: '아라',
|
||||
role: 'Instagram 콘텐츠 리드',
|
||||
role: '마케팅 콘텐츠 매니저 · SNS',
|
||||
emoji: '📷',
|
||||
color: '#E1306C',
|
||||
specialty: '인스타그램 릴스·피드 콘셉트, 캡션·해시태그 전략, 게시 시간 최적화, 스토리·하이라이트 기획, 팔로워 인게이지먼트 분석',
|
||||
tagline: '인스타 콘텐츠와 인게이지먼트를 끌어올립니다',
|
||||
specialty: '인스타·X·TikTok 콘셉트 시트, 릴스·숏폼 기획, 캡션·해시태그 전략, 게시 시간 최적화, 스토리·하이라이트, 커뮤니티 운영(댓글·DM 가이드), 인플루언서 협업 브리프, 캠페인 KPI 측정',
|
||||
tagline: 'SNS·커뮤니티에서 사용자와 만납니다',
|
||||
roleCategory: 'planner',
|
||||
persona: '시각·트렌드 감각이 빠른 콘텐츠 리드. "이 콘셉트는 지금 통합니다·아닙니다"를 짧고 분명하게 말함. 캡션은 후크 → 가치 → CTA 흐름. 이모지 적당히 (📷·✨·💬).',
|
||||
persona: '시각·트렌드 감각이 빠른 콘텐츠 매니저. "이 콘셉트는 지금 통합니다·아닙니다"를 짧고 분명하게. 캡션은 후크 → 가치 → CTA. 커뮤니티 톤은 친근하고 빠른 응답. 이모지 적당히 (📷·✨·💬).',
|
||||
},
|
||||
};
|
||||
|
||||
/** 매니지 패널 표시 순서 — CEO가 맨 앞, 그 뒤로 제품 개발 파이프라인 순서. */
|
||||
/**
|
||||
* 매니지 패널 표시 순서 — CEO 최상단, 그 다음 제품 개발 흐름(기획 → 리서치 → 디자인 →
|
||||
* 개발 → QA → PO 감리)으로 이어지고, PM·라이터·사운드·마케팅 직군이 그 뒤를 잇는다.
|
||||
*/
|
||||
export const COMPANY_AGENT_ORDER: string[] = [
|
||||
'ceo',
|
||||
'business', // PM — 기획
|
||||
'researcher', // UX 리서치 — 검증
|
||||
'designer', // 디자이너 — 화면 설계
|
||||
'developer', // 엔지니어 — 구현
|
||||
'qa', // QA — 검증
|
||||
'inspector', // 감리·회고
|
||||
'secretary', // 오퍼레이션
|
||||
'writer', // 라이팅
|
||||
'editor', // 사운드 디렉터 (선택 직군)
|
||||
'youtube', // 마케팅 채널
|
||||
'instagram', // 마케팅 채널
|
||||
'business', // 기획자 (Game/Service Planner)
|
||||
'researcher', // UX 리서처
|
||||
'designer', // UX/UI 디자이너
|
||||
'developer', // 시니어 엔지니어
|
||||
'qa', // QA 엔지니어
|
||||
'inspector', // 프로덕트 오너 · 감리
|
||||
'secretary', // PM (운영)
|
||||
'writer', // 테크니컬 라이터
|
||||
'editor', // 사운드 디렉터
|
||||
'youtube', // 마케팅 영상
|
||||
'instagram', // 마케팅 SNS
|
||||
];
|
||||
|
||||
/** Specialists only (everything except the CEO). */
|
||||
@@ -169,13 +181,13 @@ export const COMPANY_SPECIALIST_IDS: string[] = COMPANY_AGENT_ORDER.filter((id)
|
||||
/**
|
||||
* 처음 1인 기업 모드를 열 때 켜져 있는 디폴트 에이전트.
|
||||
*
|
||||
* 기준: 제품 개발 한 사이클(기획 → 디자인 → 개발 → QA → 감리)을 그대로 돌릴 수 있는
|
||||
* 최소 코어. 콘텐츠/마케팅 직군(writer / youtube / instagram / designer_sound)은
|
||||
* 사용자가 필요할 때 직접 켜도록 디폴트는 OFF — 작은 모델이 너무 많은 에이전트에
|
||||
* 한꺼번에 노출되면 매칭이 흔들리기 때문.
|
||||
* 기준: IT/소프트웨어 개발 한 사이클(기획 → 디자인 → 개발 → QA → PO 감리)을 그대로
|
||||
* 돌릴 수 있는 최소 코어 + 일정 관리 PM. 사운드·마케팅·라이팅은 사용자가 필요할 때
|
||||
* 직접 켜도록 디폴트 OFF — 작은 모델이 너무 많은 에이전트에 한꺼번에 노출되면
|
||||
* CEO 매칭이 흔들리기 때문.
|
||||
*/
|
||||
export const DEFAULT_ACTIVE_AGENTS: string[] = [
|
||||
'ceo', 'business', 'researcher', 'designer', 'developer', 'qa', 'inspector',
|
||||
'ceo', 'business', 'researcher', 'designer', 'developer', 'qa', 'inspector', 'secretary',
|
||||
];
|
||||
|
||||
/** Lookup helper. Returns `undefined` for unknown ids instead of throwing. */
|
||||
|
||||
Reference in New Issue
Block a user