Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,19 @@ Codex 작업은 설치된 스킬과 플러그인을 사용합니다. 에이전
첨부 파일, API 응답을 캐시하지 않습니다. 공개 호스팅, macOS·iOS 네이티브 실행 파일,
앱 자체의 계정 관리는 이번 구현 범위에 포함하지 않습니다.

공통 화면은 메신저형 에이전트 목록, 모바일 목록·대화 전환, 파일 선택·붙여넣기 큐를 제공합니다. [구현·검증 범위](docs/plans/codex-ui/010_implementation.md)와 [Electron 실행 안내](packages/lina-desktop/README.md)를 참고하세요. 실제 모델·다른 OS 연결 검증은 소스 테스트와 구분합니다.

## 디렉터리 구성

- `packages/lina-codex`: Codex RPC, 세션 상태 반영, 권한, 작업 상태의 영속 관리.
- `packages/lina-opencodex`: Hub 탐색, 모델 선택, 보조 추론.
- `packages/lina-core`: 대화·요청의 영속 처리 규약, 원문 보관, 컨텍스트 저장.
- `packages/lina-history`: 비공개 체크포인트 명세, 데이터 객체, 검증, 복구 준비.
- `packages/lina-runtime`: 앱·에이전트 집합 컨트롤러와 Codex 실행 구성.
- `packages/lina-web`: 브라우저 작업 화면과 동일 출처 게이트웨이.
- `packages/lina-client`: 공통 대화 상태·명령·초안·탐색 계약.
- `packages/lina-ui`: 웹과 Electron이 함께 사용하는 화면과 디자인 토큰.
- `packages/lina-web`: 동일 출처 게이트웨이와 웹/PWA 자산.
- `packages/lina-desktop`: 동봉 화면과 제한된 서버 연결을 제공하는 Electron 앱.
- `packages/lina-memory`: 내장·Honcho 메모리와 접근 범위를 제한한 OpenViking 파일 클라이언트.
- `packages/lina-channels`: 채널 연동.
- `data/personas`: 작성된 페르소나와 출처 기록.
Expand Down
31 changes: 31 additions & 0 deletions THIRD_PARTY_NOTICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,34 @@ Apache-2.0 to the extent of the rights held. That statement covers the identifie
assets; it does not relicense external software or imply rights in other images.
[The publication checklist](docs/PUBLICATION.md) tracks artifact notices, source
privacy review, and the separate activation steps.


## shadcn/ui component source

The UI components in `packages/lina-ui/client/components/ui/` adapt the
Base UI `base-nova` registry patterns retrieved on 2026-09-07 from
https://ui.shadcn.com/r/styles/base-nova/. Lina replaces Tailwind classes with
its shared semantic CSS tokens and keeps named exports. Base UI and React
remain pinned package dependencies in `packages/lina-ui/package.json`.

MIT License

Copyright (c) 2023 shadcn

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
274 changes: 274 additions & 0 deletions bun.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/PLANNING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

| 기획 | 문서 | 현재 상태 |
| --- | --- | --- |
| Codex 디자인 언어, Electron과 웹 공통 화면 | [UI 개편](plans/codex-ui/001_ui_plan.md), [Electron](plans/codex-ui/004_electron_stack.md), [디자인 기준](../packages/lina-web/DESIGN.md) | 방향 확정, UI 전면 개편과 Electron 패키징은 후속 구현 |
| Codex 디자인 언어, Electron과 웹 공통 화면 | [UI 개편](plans/codex-ui/001_ui_plan.md), [Electron](plans/codex-ui/004_electron_stack.md), [디자인 기준](../packages/lina-web/DESIGN.md) | 공통 화면·토큰·Electron 동봉 빌드 구현. [검증 범위](plans/codex-ui/010_implementation.md) |
| 메신저형 에이전트 목록과 모바일 탐색 | [에이전트 목록](plans/codex-ui/006_agent_list_mobile.md), [작업 목록 배치](plans/codex-ui/007_sidebar_comparison.md) | 기본 한 목록 열, 넓은 창의 선택적 작업 열, 모바일 전체 화면 전환 |
| 연속 메시지와 중간 사용자 입력 | [대화 전달](plans/codex-ui/002_conversation_delivery.md) | 공개된 발화와 미공개 후보를 나누는 엔진·저장 계약 설계 |
| 이미지·파일 붙여넣기 | [첨부 계획](plans/codex-ui/003_clipboard_attachment.md) | 공통 첨부 큐와 플랫폼별 검증이 필요한 계획 |
| 이미지·파일 붙여넣기 | [첨부 계획](plans/codex-ui/003_clipboard_attachment.md) | 파일 선택·붙여넣기 공통 큐 구현, Chromium 검증. 다른 OS·브라우저는 별도 검증 |
| 전용 컴퓨터의 공통 계약 | [컴퓨터·실행·입력 소유권](plans/platform/001_runtime_contracts.md) | API·저장 계약 제안, 독립 GUI 입력은 아직 미검증 |
| 프로바이더 선택과 로컬 모델 큐레이션 | [모델 온보딩](plans/platform/005_model_onboarding.md) | 제시 순서·큐레이션 요구 보존, 현재 연결은 Codex + OpenCodex |
| 설치 구성과 전체 상태 버전관리 | [리팩터링 요구](plans/platform/008_refactor_preparation.md) | 홈·패키지 분리·로컬 체크포인트 구현, 자동 이력·선택 복원·외부 내보내기는 후속 |
Expand Down
2 changes: 2 additions & 0 deletions docs/plans/codex-ui/001_ui_plan.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Lina UI 개편 계획

> 구현 전 설계와 당시 코드 조사 기록입니다. 현재 구현·검증·남은 연결은 [구현 기록](010_implementation.md)을 따릅니다.

상태: 제품 설계. Electron·메신저형 목록·연속 발화는 후속 구현이며 현재 기능은 [기획 목록](../../PLANNING.md)을 따른다.

**Codex의 디자인 언어를 전면 채택하고, 에이전트와의 지속 대화를 탐색의 중심에 둡니다.** 화면을 바꿔도 대화·초안·작업이 이어져야 합니다. 근거와 코드 확보 범위는 [조사 문서](000_source_research.md)에 정리했습니다. 데스크톱은 Electron, 웹/PWA는 같은 렌더러를 사용합니다. [스택과 전환 계획](004_electron_stack.md), [디자인 적용 기준](005_codex_design_language.md)이 각각 구현 경계와 시각 검수의 기준입니다.
Expand Down
2 changes: 2 additions & 0 deletions docs/plans/codex-ui/003_clipboard_attachment.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# 이미지·파일 붙여넣기 첨부

> 구현 전 설계와 당시 코드 조사 기록입니다. 현재 구현·검증·남은 연결은 [구현 기록](010_implementation.md)을 따릅니다.

2026-09-07 사용자 피드백 5 반영. 기획과 현재 코드 검사만 수행했습니다. 실제 OS 클립보드를 사용한 브라우저·모바일 검증은 아직 수행하지 않았습니다.

## 1. 현재 지원 범위
Expand Down
2 changes: 2 additions & 0 deletions docs/plans/codex-ui/004_electron_stack.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Electron과 웹 공통 스택

> 구현 전 설계와 당시 코드 조사 기록입니다. 현재 구현·검증·남은 연결은 [구현 기록](010_implementation.md)을 따릅니다.

2026-09-07 사용자 선택 반영. 데스크톱은 Electron으로 정하고, 웹은 동일한 화면 코드를 브라우저에서 실행합니다. 이번 변경은 스택·전환 기획이며 패키지 설치나 앱 구현을 수행한 것은 아닙니다.

## 1. 스택 결정
Expand Down
2 changes: 2 additions & 0 deletions docs/plans/codex-ui/006_agent_list_mobile.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# 에이전트 목록과 모바일 탐색

> 구현 전 설계와 당시 코드 조사 기록입니다. 현재 구현·검증·남은 연결은 [구현 기록](010_implementation.md)을 따릅니다.

2026-09-07 추가 피드백 반영. 사용자는 Telegram·Grok Bot·카카오톡처럼 익숙한 에이전트 선택 경험과 모바일 전환을 요청했습니다. Codex의 색·타이포·입력창·메뉴 규칙 안에 메신저형 목록과 탐색을 적용합니다. 이 문서는 기획이며 앱 구현 결과가 아닙니다.

## 1. 변경하는 결정
Expand Down
2 changes: 2 additions & 0 deletions docs/plans/codex-ui/007_sidebar_comparison.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# 에이전트와 Codex 작업 목록 배치 비교

> 구현 전 설계와 당시 코드 조사 기록입니다. 현재 구현·검증·남은 연결은 [구현 기록](010_implementation.md)을 따릅니다.

2026-09-07. 사용자는 사이드바를 위아래로 나눌지, 작업용 열을 추가할지 비교해 달라고 요청했습니다. 아래 권장안은 메신저형 에이전트 목록과 모바일 전환을 함께 고려한 설계 판단입니다. 아직 구현·사용성 시험 결과는 없습니다.

## 1. 권장안
Expand Down
134 changes: 134 additions & 0 deletions docs/plans/codex-ui/010_implementation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# UI 및 데스크톱 구현·검증

웹과 Electron이 같은 화면을 사용하도록 분리하고, 에이전트 중심 탐색과
Codex 계열 디자인을 적용했다. 기존 대화·설정·온보딩을 유지하면서 모바일
전환, 파일 붙여넣기, 작업 보기와 데스크톱 연결을 구현했다.

## 구현 범위

| 소유 패키지 | 책임 |
| --- | --- |
| `lina-client` | 대화 상태·연결·프로토콜, 에이전트 요약, 초안·읽기 위치, 첨부 큐, 탐색 |
| `lina-ui` | 공통 renderer, 디자인 토큰, React/Base UI 컴포넌트와 기존 컨트롤러 연결 |
| `lina-web` | 동일 출처 게이트웨이, 공통 화면의 production 빌드와 웹/PWA 자산 |
| `lina-desktop` | 동봉 renderer, 제한된 loopback broker, 프로필·세션 격리와 OS 연결 경계 |

에이전트 목록은 이름·최근 대화·시간·읽지 않음·확인 요청·진행 상태를 표시한다.
목록 필터와 순서를 유지하며 대상을 바꿔도 초안·첨부·읽기 위치가 섞이지 않는다.
요약은 저장된 공개 대화에서 읽고, 목록 조회만으로 실행 엔진을 열지 않는다.

화면은 중립 표면·공통 글자·간격·버튼·아이콘 크기를 쓴다. React 19.2.8,
React DOM 19.2.8, Base UI 1.8.0을 추가했다. shadcn base-nova의 Button,
Avatar, DropdownMenu, Tabs, Combobox 구성을 Lina 토큰/CSS로 조정했다.
[소스 출처](../../../packages/lina-ui/SOURCES.md)와
[포함 라이선스](../../../packages/lina-ui/THIRD_PARTY_LICENSES.txt)를 보존한다.
Tailwind나 별도 웹 서버는 추가하지 않았다.

React는 각 view host 안의 컨트롤을 소유한다. 기존 대화·입력기·첨부 큐는
기존 컨트롤러가 계속 소유한다. 목록 알림, 메뉴 동작, 설정 탭, 모델 검색은
명시적 메서드/콜백으로 연결한다. 모델 설정 컨트롤러에는 콤보박스 팩토리를
주입해 서버 테스트에 브라우저 타입이 섞이지 않게 했다.

모바일은 에이전트 목록 → 대화 → 뒤로가기 흐름을 제공한다. 상단 사이드바
아이콘은 접기만 담당한다. 작업 탭 안의 이름 있는 `나란히 보기` 버튼이 별도
작업 열을 열고, 같은 버튼이 `나란히 보기 종료`로 바뀐다. 실제 남는 폭이
부족하면 이 선택지를 숨긴다. 목록·필터·초안과 키보드 포커스를 보존한다.

파일 선택과 붙여넣기는 같은 큐를 쓴다. PNG의 clipboard items/files가 다른
메타데이터를 내놓아도 중복 업로드하지 않는다. 실패 시 명시적으로 재시도하며,
준비되지 않은 첨부를 빼고 전송하거나 붙여넣기만으로 자동 전송하지 않는다.

## 데스크톱

Electron 44.2.0, Forge CLI/ZIP maker 8.0.0-alpha.10을 추가했다. 선택한 Forge
버전은 설치된 중첩 의존성까지 감사했다. 앱은 실행 엔진을 시작하지 않고
독립적으로 실행 중인 Lina 웹 게이트웨이에 연결한다.

같은 production renderer를 ASAR에 동봉한다. main의 loopback broker는 임시
HttpOnly 인증, 정확한 Host/Origin, 메서드·경로 허용 목록과 프로필의 서버
바인딩을 확인한다. renderer에는 Node 권한을 주지 않고 preload도 제한한다.
프로필과 세션 경로를 별도로 지정할 수 있다. 인증 실패 중 TCP reset과 창 닫기
취소의 연결 유지도 회귀 검사했다. [실행·패키징 안내](../../../packages/lina-desktop/README.md).

## 화면 증거

아래 PNG는 합성 데이터로 실제 웹 UI를 실행해 캡처한 결과다. 개인 대화,
실모델 출력이나 Electron GUI 실행 증거가 아니다. 화면 안의 로고·아이콘은
저장소의 기존 UI 자산이며, 모의 대화·프로필은 QA fixture가 제공한다.

![데스크톱](010_ui_desktop.png)

![모바일 에이전트 목록](010_ui_mobile.png)

![역할별 모델 검색](010_ui_models.png)

![작업 나란히 보기](010_ui_task_layout.png)

## 검증

`dev`의 이미지 엔진 변경까지 통합한 PR 후보에서 `bun test` 1,495개가
통과했다. `bun run typecheck`, `bun run lint`, `bun run ci:validate`,
`bun run ci:build`, `bun scripts/ci/audit.ts`와 전체 Git 기록 비밀정보 검사도
통과했다. 실제 Chromium 전체 앱 시나리오 11개와 작업 보기 UX를 재검증했다.
CI 상태는 PR의 Verification 기록을 따른다.

| 실제 UI 검사 | 증명한 범위 |
| --- | --- |
| `ui-desktop.mjs` | A→B→A 초안·첨부·읽기 위치, PNG 붙여넣기→업로드→명시적 전송→재조회, 한글 Undo, 작업 복원, 모바일·실패 복구 |
| `ui-navigation-regressions.mjs` | 모바일 뒤로가기·검색, 늦은 선택 취소, 저장소 차단·연결 단절 중 읽기 위치 |
| `ui-agent-list.mjs` | 목록 노드/포커스, 터치 취소, 표시 우선순위, 아바타 실패, 오류 알림 복구 |
| `ui-settings-islands.mjs` | 탭 방향·키보드·패널 유지, 테마 저장/시스템 변경과 저장소 실패 |
| `ui-model-combobox.mjs` | 검색·선택·disabled, Escape, dialog 내부 표시, 폭/스크롤/하단 배치, 실제 설정 저장 계약 |
| `ui-components.mjs` | 메뉴 키보드 진입, 이동, Tab/Shift+Tab, Escape, 반복 클릭, 바깥 클릭과 dialog 포커스 |
| `ui-task-layout.mjs` | 작업 탭의 보기 선택, 상태 이름, 실제 가용 폭, 모바일, 재배치와 복원 |
| `ui-design.mjs` | 320/390/768/1024/1440px, 버튼 정렬, 설정 탭과 다크/라이트 표면·잘림 |

메뉴 Tab 종료와 PNG 중복 첨부처럼 브라우저에서 발견한 오류는 실패를 먼저
기록하고 고쳤다. Bun의 minify만으로 React 개발 코드가 포함되는 오류도
production 정의와 자산 테스트로 막았다. 의존성/소스 라이선스는 JS에 포함해
웹과 Electron 양쪽 결과물에 보존한다.

Linux ZIP을 생성했고 세 QA 서버의 JS/CSS/theme이 ASAR의 동봉 자산과
바이트 단위로 일치했다. rendererVersion은 `8b7f0710d8fa18e241fa`다.
ZIP은 로컬 빌드 산출물이며 이 PR이 릴리스로 배포하지 않는다.

## 격리와 재현

Bun과 별도로 Playwright/Chromium이 준비된 개발 환경에서 저장소 루트 기준으로
실행한다. 실제 사용자 서버 대신 합성 fixture를 사용한다.

```sh
# 별도 터미널: 루트/DB/첨부를 새 임시 디렉터리에 만드는 검증 서버
LINA_QA_WEB_PORT=18140 LINA_QA_UPSTREAM_PORT=18142 \
bun packages/lina-web/test/fixtures/ui-desktop.ts

LINA_QA_URL=http://127.0.0.1:18140 node scripts/qa/ui-desktop.mjs
LINA_QA_URL=http://127.0.0.1:18140 node scripts/qa/ui-navigation-regressions.mjs
LINA_QA_URL=http://127.0.0.1:18140 node scripts/qa/ui-components.mjs
LINA_QA_URL=http://127.0.0.1:18140 node scripts/qa/ui-task-layout.mjs
bun scripts/qa/ui-agent-list.mjs
bun scripts/qa/ui-settings-islands.mjs
bun scripts/qa/ui-model-combobox.mjs
```

Playwright 모듈과 실행 파일은 `LINA_QA_PLAYWRIGHT_MODULE`, `LINA_QA_CHROMIUM`,
결과 디렉터리는 `LINA_QA_OUTPUT`으로 지정한다. `LINA_QA_FIRST_USER=1` fixture와
`LINA_QA_INTRO_URL`로 처음 시작 화면을 검증할 수 있다. 화면 캡처용 모의 대화는
`LINA_QA_PRESENTATION=1`로 선택한다. 작업이 시작한 검증 서버는 종료했다.

## 남은 검증과 연결

- Electron GUI는 호스트 sandbox 조건 때문에 미검증이다. 정상 sandbox 환경의
GUI·재시작·OS 파일 대화상자·알림·프로토콜 실행을 확인해야 한다.
- macOS/Windows 패키징·서명, 업데이트 배포, 물리 모바일 IME/OS 파일 복사는
별도 검증 범위다. Linux ZIP 생성은 출시/설치 검증을 뜻하지 않는다.
- 이미지 엔진의 `dev` 변경을 공통 renderer에 통합했다. 모의 생성·편집 결과가
세션 소유권을 유지한 320×200 미리보기로 표시되는 흐름을 확인했다. 엔진 내부를
수정하지 않았고 외부 provider 호출은 0회다. 실제 서비스의 생성·편집 품질과
세계관 엔진의 최종 연결은 이 검증으로 주장하지 않는다.
- 연속 발화·중간 입력의 엔진 정책은 [별도 설계](002_conversation_delivery.md)다.
- 기존 `render.ts ↔ attachments.ts` 참조는 남아 있다. 새 컴포넌트 경로는
순환하지 않으며, 기존 첨부 렌더링의 추가 분리는 이번 범위에 포함하지 않았다.

PR 공개와 dev/main 머지, 배포는 별도 작업이다. 이 변경은 사용자 데이터나
실행 중 서비스를 변경하지 않는다.
Binary file added docs/plans/codex-ui/010_ui_desktop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions docs/plans/codex-ui/010_ui_evidence.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"capturedAt": "2026-09-07",
"kind": "actual web screenshots with synthetic fixture data",
"baseCommit": "cd74c89",
"rendererVersion": "8b7f0710d8fa18e241fa",
"screenshots": {
"010_ui_desktop.png": "ec0275c03bd92c888974ec49063e5194cb6709283be7344307fb0ecb79631e8b",
"010_ui_mobile.png": "da6b03621ca3c1dbe2fa3eca7b63190be9d0ddd61381e71f22bc816b9b100b53",
"010_ui_models.png": "d56dc4752bb01ac371c1696c082e32d2a79c70946c0521b3c0b1080bfec9e38b",
"010_ui_task_layout.png": "afb5b56c106c9f24df435c7f3c1d38c26ef0c06af5b1ff85010a41dba3a9adb8"
},
"externalProviderCalls": 0,
"electronGuiVerified": false
}
Binary file added docs/plans/codex-ui/010_ui_mobile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/plans/codex-ui/010_ui_models.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/plans/codex-ui/010_ui_task_layout.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
],
"scripts": {
"test": "bun test",
"typecheck": "tsc --noEmit -p tsconfig.json && tsc --noEmit -p packages/lina-web/client/tsconfig.json",
"typecheck": "tsc --noEmit -p tsconfig.json && tsc --noEmit -p packages/lina-ui/client/tsconfig.json && bun run --cwd packages/lina-desktop typecheck",
"lint": "biome check .",
"lint:fix": "biome check --write .",
"ci:validate": "bun scripts/ci/validate.ts",
Expand Down
7 changes: 7 additions & 0 deletions packages/lina-client/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "@lina/client",
"version": "0.1.0",
"private": true,
"type": "module",
"license": "Apache-2.0"
}
Loading
Loading