HAL 0.3.2: AI 연동 편의성 + 도구 기본 설정·승인 요청 — 공급자 프리셋(Claude·ChatGPT·Gemini·OpenRouter + 기타 OpenAI 호환, Gemini 자체 API 어댑터), 사전 준비 안내, OAuth 저장 직후 로그인 창 자동(완료 페이지 postMessage·닫기, Gemini Google 프리셋, OpenRouter PKCE 키 발급), CLI 로그인용 텍스트 셸(허용 명령만 PTY, 재인증, 입력 미저장, 미로그인 시 자동 열기), 연결별 도구 정책(기본 전부)·로컬 CLI 에 HAL MCP 설정 자동 주입·MCP 설정 스니펫, MCP 쓰기·고위험 호출은 승인 요청(제안)으로 + hal_action_status/hal_actions_pending, 개발 지시 v0.3.2(Oz)·docs/HAL-AI.md §7·VERSION_HISTORY 0.3.2 — test/hal-ai-032.test.mjs RED 0/6 → GREEN 6/6, 전체 27파일 189건 통과

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Claude Fable 5.1
2026-10-29 01:43:02 +00:00
parent ad96f0b986
commit 8a111bcb8b
21 changed files with 609 additions and 78 deletions
+50
View File
@@ -1,5 +1,55 @@
# VERSION_HISTORY
## 0.3.2 (2026-10-29)
- **작성자**: 개발 지시 — Oz(`Ariweb-Suitle_Dev-Order_v0.3.2.md`, 2026-10-29) · 구현 — Claude Fable 5.1(브랜치 `feature/hal-ai-convenience-v0.3.2`, 기준 main `ad96f0b` = 0.3.1). 커밋·push·`main` 병합·릴리스 빌드·bear `hal21.ariweb.net` HAL 배포까지 수행(아래 "배포").
- **이전 버전**: 0.3.1(2026-10-29, CLI 자동 탐색). 0.3.2 는 끝 번호를 올리는 HAL 개선 릴리스: AI 연동 편의성(사전 안내·OAuth 자동 진행·CLI 텍스트 셸·공급자 프리셋 4종 + 기타) + 도구 기본 설정·인증/승인 요청. HAL 에만 적용, 다른 모듈 변경 없음(배포하지 않음).
### 요구(사용자 요구 — 약화 없이 반영)
1. AI 연동 편의성: OAuth 연동 시 필요한 연동 화면을 자동으로 띄운다. CLI 로그인은 text shell 화면을 제공해 화면에서 필요한 작업을 하게 한다. 이 작업들이 자동으로 진행되고 사전에 필요한 작업 내용을 안내한다. API 연동은 Claude·ChatGPT·Gemini·OpenRouter 를 기본 서비스 업체로 선택할 수 있게 하고 그 밖의 API 서비스 업체 연동도 지원한다.
2. LLM·도구 연결 기본 설정과 인증: HAL 운영·관리용 도구와 스킬을 LLM 연동 시 즉시 쓸 수 있게 미리 설정해 제공하고, 인증·승인이 필요한 도구는 필요한 인증/승인을 요청할 수 있게 한다. 결과를 소스에 반영하고 `https://hal21.ariweb.net` 에 배포한다.
### 수정한 기존 기능
- `hal/ai/providers.mjs`: 공급자 프리셋 `PROVIDERS`(anthropic=Claude · openai=ChatGPT · gemini · openrouter · other · local-cli; `kind` 로 HTTP 형식 분기, `guide` 사전 안내, `oauthPreset`). **Gemini 어댑터**(`generateContent`, `systemInstruction`, `functionDeclarations`(대문자 type 스키마), `functionCall/functionResponse`, `usageMetadata`, 모델 목록 `models/` 접두어 제거, 인증 `x-goog-api-key`/Bearer). OpenRouter 는 OpenAI 호환 + `HTTP-Referer`/`X-Title`. `toolFormat()`. **MCP 설정 주입**(`mcpConfig(d)`): claude `--mcp-config <임시 파일> --strict-mcp-config --allowedTools mcp__hal`(실행 뒤 파일 삭제), codex `-c mcp_servers.hal.command/args/env`.
- `hal/ai/connections.mjs`: `other` 는 기본 주소 필수(`base_url_required`), OAuth 프리셋 채우기(gemini: Google authorize/token·scope·`access_type=offline`·`prompt=consent`; openrouter: `mode=openrouter_pkce` — state 를 callback_url 에 실어 보내고 `/api/v1/auth/keys` 로 키를 받아 Vault 에 Bearer 로 저장), 공개 객체 `providerKind`·`tools`·`toolsVia`, 도구 정책 `tools_json`(프리셋 검증, `unknown_tool`).
- `hal/ai/engine.mjs`: 연결별 도구 정책대로 선언·실행(꺼진 도구 호출은 실행 없이 오류 결과), 로컬 CLI 는 `mcp` 플래그, `proposeExternal`(외부 출처 승인 요청 → 통합 방 HAL 안내 + 제안 카드, `source`), 연결 없는 제안의 승인·거부 결과를 통합 방 안내로.
- `hal/ai/mcp.mjs`: 쓰기·고위험 `tools/call` → 승인 요청(`{approvalRequested, actionId, …}`, isError 아님). `hal/ai/tools.mjs`: `hal_action_status`·`hal_actions_pending`(읽기), `TOOL_PRESETS`(all·read_write·read_only·none), `toolDefs(format, only)`(gemini 형식 포함).
- 새 파일 `hal/ai/shell.mjs`: 텍스트 셸 세션(허용 명령표 `SHELL_COMMANDS`, 사전 안내 `SHELL_GUIDE`, `script -qfc` PTY, 운영자당 2개, 유휴 10분·최대 30분, 출력 256KB 메모리, 입력 미저장, 감사는 시작·종료만). `hal/deps.mjs`: `d.shell`.
- `hal/ai/routes.mjs`: `POST /connections` 응답 `next`(oauth → start 경로 / cli_check / test), 콜백 → `/ops/ai/oauth/done?ok=…`(완료 페이지: 팝업이면 `postMessage` + 닫기, 아니면 `/ops/ai?oauth=ok|fail`), `error=` 콜백도 완료 페이지로, `GET /ops/api/ai/mcp-config`, `GET /ops/api/ai/tools` 에 `presets`, 텍스트 셸 `GET/POST /ops/api/ai/shell`, `GET /:id?after=`, `POST /:id/input`, `DELETE /:id`(시작은 `requireRecent`), `providers[].guide/kind/defaultBase/oauthPreset`·`callbackUrl`.
- `hal/schema.mjs`: 마이그레이션 `hal_0007_ai_tools_policy`(`ai_connections.tools_json`, `ai_actions.source`).
- 화면(`hal/ui.mjs`·`ai-render.mjs`·`ai.js`·`ops.css`): 공급자 선택 6종, **사전 준비 안내** 상자(공급자·인증 방식별, 콜백 주소 표시), OAuth 저장 직후 팝업 자동 열기·완료 자동 확인, 로컬 CLI 저장 직후 탐색·로그인 확인 → 미로그인이면 **텍스트 셸** 자동 열기(출력 0.5초 갱신, Enter 전송, Ctrl+C, 종료), 셸 단추(claude/codex login·상태), **도구 정책** fieldset(프리셋 + 직접 선택 체크박스, 위험 등급별 모두 켜기/끄기), **MCP 설정** 절(Claude Code 명령·JSON, Codex TOML), 패널 상태 줄에 "승인 대기 N", 연결 표에 도구 프리셋·MCP 표시.
- 문서·버전: `docs/HAL-AI.md` §7, 개발 지시 v0.3.2, 0.3.2 표기(package.json·README·버전 검사 테스트).
### 고객 화면
- 변경 없음.
### 운영자 화면
- AI 연동: 공급자 고르면 사전 준비 안내가 바뀐다(키 발급 주소, OAuth 리디렉션 URI 등록 안내와 HAL 콜백 주소, CLI 로그인 절차). OAuth 연결은 저장하면 로그인 창이 자동으로 열리고 승인 뒤 스스로 닫히며 모델 확인까지 이어진다(팝업 차단 시 같은 창 이동). 로컬 CLI 연결은 저장하면 탐색·로그인 확인 → 미로그인이면 텍스트 셸(login)이 자동으로 열린다. 텍스트 셸 단추로 언제든 claude/codex login·상태를 실행할 수 있다. 도구 정책은 기본 "전부"이며 바꿀 수 있다. MCP 설정 절에서 외부 클라이언트용 설정을 복사한다.
- 채팅룸: 외부(MCP) 승인 요청이 통합 방에 HAL 안내 + 제안 카드로 올라오고 상태 줄에 "승인 대기 N" 이 보인다. 승인·거부 흐름은 0.3.0 과 같다(재인증, 고위험 3단계).
### 보안 결정
- 텍스트 셸은 임의 셸이 아니다: (tool, command 이름)만 받아 허용표의 인자 배열을 실행하고, 실행 파일은 탐색된 절대 경로. 시작은 재인증, 입력은 저장·감사하지 않음, 출력은 메모리만. HAL 환경 변수(Vault 키)는 넘기지 않는다.
- OAuth 완료 페이지는 외부 스크립트 없이 결과·연결 id 만 다루고 `postMessage` 는 같은 출처로만 보낸다. OpenRouter PKCE 로 받은 키는 Vault 에만. Google OAuth 는 client secret 을 서버→토큰 끝점에만.
- MCP 승인 요청은 인자를 서버가 다시 검증해 제안으로만 올린다(실행 없음). 승인 라우트·재인증·3단계 확인은 0.3.0 그대로. 도구 정책으로 꺼진 도구는 선언도 실행도 하지 않는다.
- Gemini 선언 스키마는 `additionalProperties` 를 뺀 OpenAPI 부분집합으로 변환하되 HAL 쪽 검증(`validateArgs`)은 원래 선언으로 한다(모르는 인자 거부 유지).
### 테스트
- RED(구현 전): 새 `test/hal-ai-032.test.mjs` **0/6**(공급자 gemini 없음 400 `bad_provider`, `/ops/api/ai/shell` 404, 도구 정책 없음, MCP 상태 도구 없음, 화면 문구 없음, 버전 0.3.1).
- GREEN: `test/hal-ai-032.test.mjs` **6/6** — 프리셋·안내·OpenRouter 기본 주소·기타 주소 필수·Gemini 모델 목록(x-goog-api-key)·generateContent 도구 왕복 / OAuth 생성 `next`·Google 프리셋(access_type=offline)·완료 페이지(opener postMessage·close·대체 이동)·실패 콜백·OpenRouter PKCE(callback_url 에 state, `/api/v1/auth/keys` 교환 → Vault, Bearer) / 텍스트 셸(재인증 403·임의 명령 400·`script` PTY 출력·입력 Enter·종료 코드·입력 미감사·목록·강제 종료·404) / 도구 정책(기본 all·프리셋 목록·read_only·custom 검증·선언 필터)·MCP 설정 API·claude `--mcp-config` 파일 내용·삭제·`--allowedTools mcp__hal`·정책 none 이면 미주입·codex `-c mcp_servers.hal.*` / MCP 승인 요청(제안·`hal_action_status`·`hal_actions_pending`·콘솔 제안 목록(source mcp)·통합 방 카드·재인증 403·승인 실행·결과 안내·고위험 3단계·거부) / 화면·버전·문서. 기존 `test/hal-ai.test.mjs` 12/12(0.3.0 의 "MCP 쓰기 도구는 isError" 기대를 "승인 요청(제안)"으로 갱신).
- targeted: `hal-ui` 7/7 · `hal-reauth-banner` 5/5 · `hal` 16/16 · `webmaker-visual-editor` 5/5. 전체 Suite `node test/run.mjs`: **27개 파일 실패 0, 189건 통과**. 변경 파일 secret-like 스캔 0건. 러너 임시 파일 미커밋.
### 배포(bear `hal21.ariweb.net`, HAL 만)
- 절차와 read-back 은 배포 뒤 이 절에 후속 커밋으로 기록한다.
### 알려진 제한
- Anthropic·OpenAI 는 공개 OAuth 클라이언트가 없어 OAuth 는 자체 중계가 있을 때만 쓴다(안내에 명시). Gemini OAuth 는 운영자가 Google Cloud 에서 OAuth 클라이언트를 만들어야 한다.
- 텍스트 셸은 로그인·로그아웃·상태·버전만 실행한다. 터미널 크기 변경(SIGWINCH)은 지원하지 않는다(100×30 고정).
- 로컬 CLI 의 MCP 도구는 Claude Code 2.1.312 / Codex 0.162.1 기준 인자(`--mcp-config`, `-c mcp_servers.*`)로 붙인다 — CLI 가 바뀌면 인자가 달라질 수 있다. 실제 운영 CLI 로의 MCP 도구 호출은 운영자가 로그인한 뒤 확인한다.
- 실제 브라우저에서 팝업·셸 모달 동작은 자동 테스트하지 않았다(순수 렌더러·API·완료 페이지 내용으로 검증).
### 미확정 정책값
- 텍스트 셸 유휴/최대 시간(10분/30분), 동시 세션 수(2), 출력 상한(256KB). OAuth state 만료(10분).
## 0.3.1 (2026-10-29)
- **작성자**: 개발 지시 — Oz(`Ariweb-Suitle_Dev-Order_v0.3.1.md`, 2026-10-29) · 구현 — Claude Fable 5.1(브랜치 `feature/hal-cli-discovery-v0.3.1`, 기준 main `0d3a0b8` = 0.3.0). 커밋·push·`main` 병합·릴리스 빌드·bear `hal21.ariweb.net` HAL 배포까지 수행(아래 "배포").