ltcai 0.1.20 → 0.1.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/CHANGELOG.md CHANGED
@@ -1,5 +1,138 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.23] - 2026-05-24
4
+
5
+ ### Discord 권한 알림 시스템
6
+
7
+ - **`GET /permissions/pending`** — 대기 중인 파일 접근 권한 요청 목록 (관리자)
8
+ - **`POST /permissions/approve/{token}`** — 권한 승인 (관리자 세션 또는 `LATTICEAI_PERMISSION_SECRET`)
9
+ - **`POST /permissions/deny/{token}`** — 권한 거부/취소
10
+ - **`GET /permissions/status/{token}`** — 승인 상태 폴링 (AI 에이전트용)
11
+ - 권한 토큰 기본값 `approved: False` — 명시적 승인 전까지 파일 접근 불가
12
+ - `~/.ltcai/permission_queue.json` — 서버가 기록, Claude Code Discord 플러그인이 읽어 알림 전송
13
+ - `LATTICEAI_PERMISSION_SECRET` 환경변수 — 모니터 스크립트가 세션 없이 approve/deny 호출 가능
14
+ - `perm_monitor.py` — 권한 목록 조회·승인·거부 CLI 도우미 (`list` / `approve TOKEN` / `deny TOKEN` / `discord-msg`)
15
+ - Discord에서 `승인 <토큰앞8자>` / `거부 <토큰앞8자>` 로 파일 접근 제어 가능
16
+
17
+ ### 리포지터리 UX 개선
18
+
19
+ - **영어 README** 전면 재작성 — 한국어는 접을 수 있는 `<details>` 섹션으로 이동
20
+ - **SVG 로고** 추가 (`docs/images/logo.svg`)
21
+ - **경쟁 제품 비교표** — Lattice AI vs Open WebUI · Continue.dev · GitHub Copilot
22
+ - **실제 UI 스크린샷 3장** — Chat UI · Admin Dashboard · Data Graph (Playwright 2x 캡처)
23
+ - **VS Code 익스텐션 카테고리** `Other` → `AI, Machine Learning, Chat, Other`
24
+ - **VS Code 익스텐션 키워드** 8개 → 16개 (copilot, apple-silicon, groq, graph-rag 등)
25
+ - **VS Code 익스텐션 README** 전면 재작성 (기능표, 비교표, 모델 목록)
26
+ - 구버전 `.tgz` / `.vsix` 빌드 파일 삭제
27
+
28
+ ### Release
29
+ - 배포 버전을 `0.1.23`으로 상향
30
+ - 대상 채널: `npm` · `PyPI` · `VS Code Marketplace` · `Open VSX`
31
+
32
+ ## [0.1.22] - 2026-05-24
33
+
34
+ ### 리포지터리 UX 개선 — 다운로드 유입 최적화
35
+
36
+ #### README 전면 재작성
37
+ - **영어 메인 문서** — 한국어는 접을 수 있는 `<details>` 섹션으로 이동 (국제 유입 대응)
38
+ - **SVG 로고 추가** (`docs/images/logo.svg`) — 인디고→시안 그라디언트 래티스 그리드 아이콘
39
+ - **경쟁 제품 비교표** — Lattice AI vs Open WebUI · Continue.dev · GitHub Copilot 10개 기준 비교
40
+ - **PyPI 월간 다운로드 수 배지** 추가 (신뢰도 지표)
41
+ - 기능 · 보안 · API · 트러블슈팅 섹션을 표(table) 형식으로 정리 (가독성 향상)
42
+
43
+ #### 실제 UI 스크린샷 자동 캡처
44
+ - `docs/images/screenshot-chat.png` — 웹 채팅 UI (사이드바, 모델/파이프라인/VPC 카드)
45
+ - `docs/images/screenshot-admin.png` — 어드민 대시보드 + Audit & Data Governance 섹션
46
+ - `docs/images/screenshot-graph.png` — Data Graph 시각화 (299 노드, 443 엣지)
47
+ - README 상단에 3단 그리드 스크린샷 테이블 추가
48
+ - `scripts/take_screenshots.js` — Playwright Chromium 헤드리스 캡처 스크립트 (2x 레티나)
49
+
50
+ #### VS Code 익스텐션 메타데이터 개선
51
+ - **카테고리** `Other` → `AI, Machine Learning, Chat, Other` (Marketplace 검색 노출 증가)
52
+ - **키워드** 8개 → 16개 추가 (`copilot`, `apple-silicon`, `groq`, `graph-rag` 등)
53
+ - **설명 문구** 구체화 — 핵심 차별점(MLX, MCP, Graph RAG, zero telemetry) 명시
54
+ - **익스텐션 README 전면 재작성** — 기능표 · 빠른 시작 · 단축키 · 지원 모델 · 설정 · 비교표 포함
55
+
56
+ #### 리포지터리 정리
57
+ - 루트 및 `vscode-extension/`의 구버전 `.tgz` / `.vsix` 빌드 파일 삭제
58
+
59
+ ### Release preparation
60
+
61
+ - 배포 버전을 `0.1.22`로 상향
62
+ - `package.json`
63
+ - `pyproject.toml`
64
+ - `vscode-extension/package.json`
65
+ - npm / PyPI / VS Code Marketplace / Open VSX 배포 전 빌드 산출물 생성
66
+
67
+ ### Verification
68
+
69
+ - Python compile check 통과
70
+ - unit tests 통과
71
+ - root npm package 생성
72
+ - Python wheel / sdist 생성
73
+ - VS Code / Open VSX용 VSIX 생성
74
+
75
+ ## [0.1.21] - 2026-05-24
76
+
77
+ ### Setup Wizard — 자동 설치 · 연결 · 검증 · 복구
78
+
79
+ - **구성요소 자동 감지** — Homebrew, Python, Git, Node/npm, Ollama, LM Studio, Tesseract, MLX 계열 탐지
80
+ - `COMMON_PATH_DIRS` 확장: `/opt/homebrew/bin`, `~/.local/bin`, `~/.latticeai/bin` 등 자동 포함
81
+ - `PACKAGE_MODULES` 맵으로 pip 패키지 → import 이름 변환 (mlx-lm, mlx-vlm, openai-whisper 등)
82
+ - **공식 다운로드 연결** — 자동 설치 실패 시 OS별 공식 페이지(`OFFICIAL_DOWNLOADS`) 자동 오픈
83
+ - **설치 완료 자동 감지** — binary / Python 모듈 재탐색 폴링으로 설치 완료 감지
84
+ - **환경 변수 / PATH 자동 세팅** — PATH 누락 디렉토리를 `.env`의 `LATTICEAI_EXTRA_PATH`에 자동 저장
85
+ - `_update_env_file()` 헬퍼로 `.env` 파일 안전 갱신 (중복 없이 key 업데이트)
86
+ - **동작 테스트** — binary는 `--version`, Python 패키지는 `import` smoke test
87
+ - **실패 시 자동 복구** — PATH 재보정, pip 재시도, brew 실패 시 공식 다운로드 fallback
88
+
89
+ ### 보안 강화 — 로컬 파일 접근 승인 시스템
90
+
91
+ - **토큰 기반 로컬 파일 승인** — `_local_permission_response()` / `_require_local_approval()`
92
+ - 5분(300초) TTL 만료 토큰으로 read / write / list 각 액션을 별도 승인
93
+ - write 승인 시 `content_hash`(SHA-256)로 내용 위변조 방지
94
+ - 만료 토큰 자동 정리(lazy GC)
95
+ - Discord permission monitor 또는 웹 UI 승인 후에만 토큰 활성화
96
+ - **로컬 파일 미리보기 보호** — `/local/serve`, `/tools/read_document`, `/tools/pdf_pages`도 서버 발급 approval token 없이는 로컬 절대 경로를 열지 않도록 변경
97
+ - **workspace 정적 노출 제거** — `/agent-files` `StaticFiles` mount 제거, 인증이 있는 다운로드 라우트만 사용
98
+ - **세션 토큰 저장 강화** — 로그인 응답 body에서 bearer token 제거, 웹 UI는 HttpOnly cookie 기반 인증만 사용
99
+ - `static/account.html`, `static/chat.html`, `static/admin.html`, `static/graph.html`의 `localStorage` 세션 토큰 의존 제거
100
+ - **loopback 감지** — `_host_is_loopback()` + `ipaddress` 표준 라이브러리로 네트워크 노출 여부 판단
101
+ - `REQUIRE_AUTH` 기본값: 퍼블릭 모드 또는 네트워크 노출 시 `true` 자동 적용
102
+ - `OPEN_REGISTRATION`: 네트워크 노출/퍼블릭 모드에서 기본 `false` (초대 코드 필요)
103
+ - **CORS 세밀 제어** — wildcard credential CORS 대신 `LATTICEAI_CORS_ALLOWED_ORIGINS` 환경변수로 허용 출처 추가 설정 가능
104
+ - **파일 자동 주입(opt-in)** — `LATTICEAI_AUTO_READ_CHAT_PATHS=true` 설정 시에만 채팅 메시지의 로컬 경로를 컨텍스트에 주입 (기본 OFF — 클라우드 모델 파일 누출 방지)
105
+
106
+ ### 어드민 대시보드 — Audit & Data Governance
107
+
108
+ - **감사 로그 섹션** — 사용자별 AI 사용량, 업로드 문서 수, 민감정보 감지, clear/delete 이벤트, 최근 감사 이벤트 표시
109
+ - **데이터 보존 정책** — `/clear`, `/clear_all`, 대화 삭제는 화면 정리만 수행; Data Graph / RAG / 감사 로그는 보존
110
+ - clear 동작을 `ClearEvent` 노드로 그래프에 기록 (언제 누가 clear 했는지 감사 추적)
111
+ - **민감정보 검사** — 문서 업로드 텍스트를 감사 로그에 기록
112
+
113
+ ### Graph RAG / Data Graph
114
+
115
+ - **한국어 단어 검색 개선** — 2글자 키워드(`문서`, `모델` 등) RAG 검색 누락 문제 수정
116
+ - **`graph.html` 독립 페이지 유지** — 채팅 사이드바 `Data Graph` 버튼으로 연결, New Chat 버튼은 대화 검색 아래로 이동
117
+
118
+ ### CLI / Node.js 래퍼
119
+
120
+ - `ltcai_cli.py` — `doctor` 명령어에 확장된 구성요소 탐지 통합
121
+ - `bin/ltcai.js` — Node.js 래퍼 PATH 보정 로직 개선
122
+
123
+ ### 테스트
124
+
125
+ - `tests/unit/test_security.py` — loopback 감지, 로컬 파일 접근 approval token, write content hash 검증 추가
126
+ - `tests/unit/test_setup_wizard.py` — 자동 설정 구성요소 감지와 PATH 보정 검증 추가
127
+
128
+ ### 환경변수 추가 (`.env.example`)
129
+
130
+ | 변수 | 기본값 | 설명 |
131
+ |------|--------|------|
132
+ | `LATTICEAI_AUTO_READ_CHAT_PATHS` | `false` | 채팅 메시지 내 로컬 경로 자동 주입 |
133
+ | `LATTICEAI_CORS_ALLOWED_ORIGINS` | `` | 추가 허용 CORS 출처 (콤마 구분) |
134
+ | `LATTICEAI_EXTRA_PATH` | `` | 추가 PATH 디렉토리 (Setup Wizard 자동 기록) |
135
+
3
136
  ## [0.1.20] - 2026-05-23
4
137
 
5
138
  ### Release
@@ -0,0 +1,33 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 60" width="240" height="60">
2
+ <defs>
3
+ <linearGradient id="g" x1="0%" y1="0%" x2="100%" y2="100%">
4
+ <stop offset="0%" style="stop-color:#6366f1"/>
5
+ <stop offset="100%" style="stop-color:#06b6d4"/>
6
+ </linearGradient>
7
+ </defs>
8
+ <!-- Lattice grid icon -->
9
+ <g transform="translate(8,10)">
10
+ <!-- dots -->
11
+ <circle cx="0" cy="0" r="3" fill="url(#g)" opacity="0.9"/>
12
+ <circle cx="16" cy="0" r="3" fill="url(#g)" opacity="0.9"/>
13
+ <circle cx="32" cy="0" r="3" fill="url(#g)" opacity="0.9"/>
14
+ <circle cx="0" cy="16" r="3" fill="url(#g)" opacity="0.9"/>
15
+ <circle cx="16" cy="16" r="4" fill="url(#g)"/>
16
+ <circle cx="32" cy="16" r="3" fill="url(#g)" opacity="0.9"/>
17
+ <circle cx="0" cy="32" r="3" fill="url(#g)" opacity="0.9"/>
18
+ <circle cx="16" cy="32" r="3" fill="url(#g)" opacity="0.9"/>
19
+ <circle cx="32" cy="32" r="3" fill="url(#g)" opacity="0.9"/>
20
+ <!-- lines -->
21
+ <line x1="0" y1="0" x2="32" y2="0" stroke="url(#g)" stroke-width="1.2" opacity="0.4"/>
22
+ <line x1="0" y1="16" x2="32" y2="16" stroke="url(#g)" stroke-width="1.2" opacity="0.4"/>
23
+ <line x1="0" y1="32" x2="32" y2="32" stroke="url(#g)" stroke-width="1.2" opacity="0.4"/>
24
+ <line x1="0" y1="0" x2="0" y2="32" stroke="url(#g)" stroke-width="1.2" opacity="0.4"/>
25
+ <line x1="16" y1="0" x2="16" y2="32" stroke="url(#g)" stroke-width="1.2" opacity="0.4"/>
26
+ <line x1="32" y1="0" x2="32" y2="32" stroke="url(#g)" stroke-width="1.2" opacity="0.4"/>
27
+ <!-- diagonals -->
28
+ <line x1="0" y1="0" x2="32" y2="32" stroke="url(#g)" stroke-width="1" opacity="0.25"/>
29
+ <line x1="32" y1="0" x2="0" y2="32" stroke="url(#g)" stroke-width="1" opacity="0.25"/>
30
+ </g>
31
+ <!-- Text -->
32
+ <text x="58" y="34" font-family="'SF Pro Display','Segoe UI',system-ui,sans-serif" font-size="26" font-weight="700" fill="url(#g)" letter-spacing="-0.5">Lattice AI</text>
33
+ </svg>
Binary file
Binary file
Binary file
package/ltcai_cli.py CHANGED
@@ -18,6 +18,32 @@ import urllib.request
18
18
  from pathlib import Path
19
19
 
20
20
 
21
+ def _load_env_file(path: Path) -> None:
22
+ if not path.exists():
23
+ return
24
+ for raw_line in path.read_text(encoding="utf-8").splitlines():
25
+ line = raw_line.strip()
26
+ if not line or line.startswith("#") or "=" not in line:
27
+ continue
28
+ key, value = line.split("=", 1)
29
+ key = key.strip()
30
+ value = value.strip().strip('"').strip("'")
31
+ if key and key not in os.environ:
32
+ os.environ[key] = value
33
+
34
+
35
+ def _apply_extra_path() -> None:
36
+ extra = os.getenv("LATTICEAI_EXTRA_PATH", "")
37
+ if not extra:
38
+ return
39
+ current = [p for p in os.environ.get("PATH", "").split(os.pathsep) if p]
40
+ for item in reversed([p for p in extra.split(os.pathsep) if p]):
41
+ expanded = str(Path(item).expanduser())
42
+ if Path(expanded).exists() and expanded not in current:
43
+ current.insert(0, expanded)
44
+ os.environ["PATH"] = os.pathsep.join(current)
45
+
46
+
21
47
  def _has_module(name: str) -> bool:
22
48
  return importlib.util.find_spec(name) is not None
23
49
 
@@ -200,6 +226,10 @@ def _start_tunnel(port: int) -> str | None:
200
226
  # ─────────────────────────────────────────────────────────────────────────────
201
227
 
202
228
  def main() -> None:
229
+ app_dir = Path(__file__).resolve().parent
230
+ _load_env_file(app_dir / ".env")
231
+ _apply_extra_path()
232
+
203
233
  parser = argparse.ArgumentParser(prog="LTCAI", description="Run the Lattice AI local server.")
204
234
  subparsers = parser.add_subparsers(dest="command")
205
235
  subparsers.add_parser("doctor", help="Check local runtime dependencies and configuration.")
@@ -216,7 +246,6 @@ def main() -> None:
216
246
  if args.command == "doctor":
217
247
  raise SystemExit(doctor())
218
248
 
219
- app_dir = Path(__file__).resolve().parent
220
249
  os.chdir(app_dir)
221
250
 
222
251
  # --tunnel forces 0.0.0.0 so cloudflared can reach the server
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ltcai",
3
- "version": "0.1.20",
3
+ "version": "0.1.23",
4
4
  "description": "Lattice AI local MLX/cloud LLM workspace server",
5
5
  "homepage": "https://github.com/TaeSooPark-PTS/LatticeAI#readme",
6
6
  "repository": {