clitrigger 0.1.14 → 0.1.16

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.
Files changed (79) hide show
  1. package/README.md +15 -4
  2. package/README_KR.md +15 -4
  3. package/bin/clitrigger.js +41 -4
  4. package/dist/client/assets/index-BldpDcSD.js +686 -0
  5. package/dist/client/assets/{index-BDEcscfu.css → index-CRSNebDI.css} +1 -1
  6. package/dist/client/index.html +2 -2
  7. package/dist/server/db/app-settings.d.ts +3 -0
  8. package/dist/server/db/app-settings.d.ts.map +1 -0
  9. package/dist/server/db/app-settings.js +16 -0
  10. package/dist/server/db/app-settings.js.map +1 -0
  11. package/dist/server/db/queries.d.ts +27 -3
  12. package/dist/server/db/queries.d.ts.map +1 -1
  13. package/dist/server/db/queries.js +25 -5
  14. package/dist/server/db/queries.js.map +1 -1
  15. package/dist/server/db/schema.d.ts.map +1 -1
  16. package/dist/server/db/schema.js +23 -0
  17. package/dist/server/db/schema.js.map +1 -1
  18. package/dist/server/index.d.ts.map +1 -1
  19. package/dist/server/index.js +4 -2
  20. package/dist/server/index.js.map +1 -1
  21. package/dist/server/routes/discussions.d.ts.map +1 -1
  22. package/dist/server/routes/discussions.js +1 -1
  23. package/dist/server/routes/discussions.js.map +1 -1
  24. package/dist/server/routes/memory.d.ts.map +1 -1
  25. package/dist/server/routes/memory.js +333 -0
  26. package/dist/server/routes/memory.js.map +1 -1
  27. package/dist/server/routes/sessions.d.ts.map +1 -1
  28. package/dist/server/routes/sessions.js +102 -3
  29. package/dist/server/routes/sessions.js.map +1 -1
  30. package/dist/server/routes/todos.js +2 -2
  31. package/dist/server/routes/todos.js.map +1 -1
  32. package/dist/server/routes/tunnel.d.ts.map +1 -1
  33. package/dist/server/routes/tunnel.js +37 -2
  34. package/dist/server/routes/tunnel.js.map +1 -1
  35. package/dist/server/services/discussion-orchestrator.d.ts.map +1 -1
  36. package/dist/server/services/discussion-orchestrator.js +2 -1
  37. package/dist/server/services/discussion-orchestrator.js.map +1 -1
  38. package/dist/server/services/memory-ingest.d.ts +4 -0
  39. package/dist/server/services/memory-ingest.d.ts.map +1 -1
  40. package/dist/server/services/memory-ingest.js +184 -21
  41. package/dist/server/services/memory-ingest.js.map +1 -1
  42. package/dist/server/services/memory-inject-hook.d.ts +3 -1
  43. package/dist/server/services/memory-inject-hook.d.ts.map +1 -1
  44. package/dist/server/services/memory-inject-hook.js +23 -3
  45. package/dist/server/services/memory-inject-hook.js.map +1 -1
  46. package/dist/server/services/memory-injector.d.ts +1 -1
  47. package/dist/server/services/memory-injector.d.ts.map +1 -1
  48. package/dist/server/services/memory-injector.js +18 -2
  49. package/dist/server/services/memory-injector.js.map +1 -1
  50. package/dist/server/services/memory-retriever.d.ts +16 -0
  51. package/dist/server/services/memory-retriever.d.ts.map +1 -0
  52. package/dist/server/services/memory-retriever.js +170 -0
  53. package/dist/server/services/memory-retriever.js.map +1 -0
  54. package/dist/server/services/orchestrator.d.ts.map +1 -1
  55. package/dist/server/services/orchestrator.js +2 -1
  56. package/dist/server/services/orchestrator.js.map +1 -1
  57. package/dist/server/services/session-manager.d.ts +22 -0
  58. package/dist/server/services/session-manager.d.ts.map +1 -1
  59. package/dist/server/services/session-manager.js +115 -3
  60. package/dist/server/services/session-manager.js.map +1 -1
  61. package/dist/server/services/tunnel-manager.d.ts +3 -1
  62. package/dist/server/services/tunnel-manager.d.ts.map +1 -1
  63. package/dist/server/services/tunnel-manager.js +18 -8
  64. package/dist/server/services/tunnel-manager.js.map +1 -1
  65. package/dist/server/services/wiki-exporter.d.ts +32 -0
  66. package/dist/server/services/wiki-exporter.d.ts.map +1 -0
  67. package/dist/server/services/wiki-exporter.js +430 -0
  68. package/dist/server/services/wiki-exporter.js.map +1 -0
  69. package/dist/server/services/wiki-index.d.ts +10 -0
  70. package/dist/server/services/wiki-index.d.ts.map +1 -0
  71. package/dist/server/services/wiki-index.js +100 -0
  72. package/dist/server/services/wiki-index.js.map +1 -0
  73. package/dist/server/websocket/index.d.ts.map +1 -1
  74. package/dist/server/websocket/index.js +8 -7
  75. package/dist/server/websocket/index.js.map +1 -1
  76. package/electron/main.cjs +224 -0
  77. package/electron/preload.cjs +3 -0
  78. package/package.json +58 -2
  79. package/dist/client/assets/index-uvmPjh-j.js +0 -654
package/README.md CHANGED
@@ -108,7 +108,7 @@ Every feature — Planner, Scheduler, worktree isolation, rate-limit auto-recove
108
108
  The **Harness** panel edits Claude / Gemini / Codex user config (settings, memory files, MCP servers) right in the browser — atomic writes with deep-merge preserve untouched fields, and a Codex `trustLevelMissing` warning surfaces when a project isn't trusted. Jira, GitHub, Notion integrations and gstack skill injection ship alongside as self-contained plugins. Two plugin categories — `external-service` (REST proxy + UI panel) and `execution-hook` (pre-execution hook into the orchestrator). Adding a new integration needs only a manifest and `registerPlugin()` call — no core code changes.
109
109
 
110
110
  ### Wiki (Karpathy LLM-Wiki Pattern)
111
- A per-project knowledge graph (nodes + typed edges) that you curate once and selectively inject into TODO and discussion prompts. Stop pasting the same domain context every run. Toggle between List and Graph views (`@xyflow/react` + dagre auto-layout, drag-to-connect edges, cycle guards on `precedes`/`refines`), pick `None` / `All` / `Selected` per task, preview the exact `<long_term_memory>` block before sending. CLI-agnostic — Claude, Gemini, and Codex all see identical context with no adapter changes.
111
+ A per-project knowledge graph (nodes + typed edges) that you curate once and selectively inject into TODO and discussion prompts. Stop pasting the same domain context every run. Toggle between List and Graph views (`@xyflow/react` + dagre auto-layout, drag-to-connect edges, cycle guards on `precedes`/`refines`), pick `None` / `All` / `Selected` / **`Auto`** per task — `Auto` runs a one-shot LLM retrieval right before each call to pick only the relevant entries, saving tokens. Preview the exact `<long_term_memory>` block (with char/token estimates) before sending; **export DB → `.clitrigger/wiki/<entity>/<slug>.md` Markdown** + Disk diff to keep the wiki alive in git or Obsidian. Lint surfaces duplicates / orphans / stale entries with inline fix actions (merge / delete / link); the Activity sub-tab logs ingest / lint / retrieve / merge events with severity. CLI-agnostic — Claude, Gemini, and Codex all see identical context with no adapter changes.
112
112
 
113
113
  ### Planner
114
114
  A lightweight task planner separate from TODOs — capture ideas, attach images, tag with colors, sort by any column. Convert any planner item into a TODO or a schedule in one click. Markdown export/import (status sections + GFM checkboxes + HTML-comment metadata) lets you move plans across machines or share via GitHub / Obsidian / any plain Markdown viewer. Drop a `.md` file onto the planner card to import.
@@ -122,7 +122,7 @@ A lightweight task planner separate from TODOs — capture ideas, attach images,
122
122
  Each TODO automatically gets its own git worktree. Claude / Gemini / Codex CLIs execute simultaneously in parallel. Dependency chains let you automatically trigger follow-up tasks and branch merges once prerequisites complete. Per-project worktree toggle plus per-TODO tri-state override (inherit / force-worktree / force-main) give you fine-grained control — main-branch tasks are automatically serialized to avoid conflicts. Drag-and-drop reordering and an iOS-style stack mode keep long task lists manageable.
123
123
 
124
124
  ### Interactive Sessions
125
- Long-lived interactive CLI sessions as first-class entities — bring up a Claude / Gemini / Codex session in a floating draggable window. **xterm.js rendering** shows ANSI colors, cursor control, and TUI box-drawing identically to a native terminal — no line-by-line scraping, no output mangling. PTY spawns at the exact viewport dimensions so Claude Code's welcome banner and menus render at the correct column width. Optional worktree isolation per session. Chat-mode log viewer classifies output into assistant / tool-use blocks for readability. Window geometry persists per session, survives tab navigation, and works on desktop and mobile (fullscreen on small screens).
125
+ Long-lived interactive CLI sessions as first-class entities — bring up a Claude / Gemini / Codex session in a floating draggable window. **VS Code-style window grouping and docking**: drag a tab onto another window for a 5-zone diamond (top/bottom/left/right/center) to either split into resizable panes or merge as tabs, plus **Aero-style edge snapping, sticky window-to-window snapping, and a minimize-to-dock-tray** flow — keeps multi-session screens tidy. **xterm.js rendering** shows ANSI colors, cursor control, and TUI box-drawing identically to a native terminal. PTY spawns at the exact viewport dimensions, with **per-session font size** (A−/A+ buttons or Ctrl/Cmd ±) for readability. Per-session wiki injection plus a **Send/Skip pre-flight banner** lets you review the auto-generated initial prompt before it hits the model. Inline edit button updates non-running sessions in place. iOS Safari mobile Hangul IME is composed via a client-side dubeolsik composer. Window geometry, group tree, and tab arrangement persist and survive tab navigation; works on desktop and mobile (fullscreen on small screens).
126
126
 
127
127
  ### Multi-Agent Discussion
128
128
  AI agents with different roles — architect, developer, reviewer — debate in rounds before implementation. The resulting design is far more robust than a single AI working in isolation. Agents flagged as **Implementers** (`can_implement`) can commit code during their regular turns, while a final implementation round stitches everything together. Auto-implement triggers the code-writing round automatically on consensus. Or hit **Send to Planner** on a finished discussion to have the transcript distilled into curated planner items via a one-shot LLM extraction — review and edit before persisting.
@@ -166,7 +166,7 @@ WebSocket-based real-time log streaming with two view modes — Chat mode render
166
166
  Select Claude / Gemini / Codex per project, per TODO, or per discussion agent. Strict sandbox mode restricts CLI file access to the worktree directory using each CLI's native sandboxing (Claude settings.json, Codex `--full-auto`, Gemini prompt-level restriction).
167
167
 
168
168
  ### Remote Access
169
- Access and control from anywhere via Cloudflare Tunnel. Browser notifications alert you when tasks or discussions complete, so you can walk away and come back.
169
+ Access and control from anywhere via Cloudflare Tunnel. Browser notifications alert you when tasks or discussions complete, so you can walk away and come back. **Route a named tunnel through your own domain** — set Tunnel Name + Custom Hostname in the sidebar ⚙ → Tunnel settings modal, and the displayed URL becomes `https://app.your-domain.com`, sidestepping the browser "dangerous site" warnings that hit `*.trycloudflare.com` / `*.cfargotunnel.com` by inheriting your domain's reputation.
170
170
 
171
171
  ### Favorites Launcher
172
172
  Register frequently-used external tools (executables, shell commands, URLs/folders) in a global Favorites section in the sidebar. Fire-and-forget one-click execution from anywhere in CLITrigger — reduces context-switching to the OS shell for environment setup, IDE launches, or external service access.
@@ -268,6 +268,17 @@ npm run start:tunnel
268
268
  # → Outputs https://xxxx.trycloudflare.com in the console
269
269
  ```
270
270
 
271
+ #### Route a named tunnel through your own domain (optional)
272
+
273
+ To avoid the "dangerous site" browser warnings on `*.trycloudflare.com` / `*.cfargotunnel.com`, point a named tunnel at your own domain. Either use the sidebar ⚙ → Tunnel settings modal (Tunnel Name + Custom Hostname), or the CLI:
274
+
275
+ ```bash
276
+ clitrigger config tunnel hostname app.your-domain.com
277
+ cloudflared tunnel route dns <tunnel-name> app.your-domain.com # one-time
278
+ ```
279
+
280
+ The displayed URL becomes `https://app.your-domain.com` and reputation tracks your domain.
281
+
271
282
  ---
272
283
 
273
284
  ## Documentation
@@ -275,7 +286,7 @@ npm run start:tunnel
275
286
  | Doc | Content |
276
287
  |-----|---------|
277
288
  | [SETUP.md](docs/SETUP.md) | Detailed installation and usage guide |
278
- | [CHANGELOG.md](docs/CHANGELOG.md) | Version history |
289
+ | [changelog/](docs/changelog/README.md) | Version history (per-date entries by month) |
279
290
  | [CICD.md](docs/CICD.md) | GitHub Actions CI/CD setup |
280
291
  | [TESTING.md](docs/TESTING.md) | Testing guide |
281
292
 
package/README_KR.md CHANGED
@@ -108,7 +108,7 @@ CLITrigger의 모든 기능 — Planner, Scheduler, 워크트리 격리, 한도
108
108
  **Harness** 패널에서는 Claude / Gemini / Codex의 사용자 설정(settings, 메모리 파일, MCP 서버)을 IDE를 열지 않고 브라우저에서 바로 편집한다 — atomic write + deep-merge로 손대지 않은 필드는 그대로 유지하고, 프로젝트가 trusted 목록에 없으면 Codex `trustLevelMissing` 경고가 노출된다. Jira, GitHub, Notion 연동과 gstack 스킬 주입도 동일하게 자가 완결형 플러그인으로 함께 제공된다. `external-service`(REST 프록시 + 패널 탭)와 `execution-hook`(오케스트레이터 사전 실행 훅) 두 카테고리를 지원한다. 새 통합을 추가하려면 매니페스트와 `registerPlugin()` 호출만 있으면 되고, 코어 코드를 건드릴 필요가 없다.
109
109
 
110
110
  ### 위키 (Karpathy LLM-Wiki 패턴)
111
- 프로젝트별로 한 번 정리해 두면 TODO와 토론 프롬프트에 골라 주입할 수 있는 노드+엣지 지식 그래프. 매번 같은 도메인 컨텍스트를 붙여넣을 필요가 없다. List / Graph 뷰 토글(`@xyflow/react` + dagre 자동 레이아웃, drag-to-connect 엣지, `precedes`/`refines` 관계는 cycle 차단), todo마다 `None` / `All` / `Selected` 모드 선택, 전송 전 `<long_term_memory>` 블록 미리보기까지. CLI-agnostic — Claude / Gemini / Codex 모두 동일한 컨텍스트를 받으며 어댑터 변경이 필요 없다.
111
+ 프로젝트별로 한 번 정리해 두면 TODO와 토론 프롬프트에 골라 주입할 수 있는 노드+엣지 지식 그래프. 매번 같은 도메인 컨텍스트를 붙여넣을 필요가 없다. List / Graph 뷰 토글(`@xyflow/react` + dagre 자동 레이아웃, drag-to-connect 엣지, `precedes`/`refines` 관계는 cycle 차단), todo마다 `None` / `All` / `Selected` / **`Auto`** 모드 선택 — `Auto`는 매 실행 직전 한 번의 LLM 호출로 관련 항목만 자동으로 골라 토큰을 절약한다. 전송 전 `<long_term_memory>` 블록을 char/token 추정치와 함께 미리볼 수 있고, **DB → `.clitrigger/wiki/<entity>/<slug>.md` Markdown 익스포트** + Disk diff로 git/Obsidian과 함께 살릴 수 있다. Lint는 중복/orphan/stale 항목에 인라인 fix 액션(merge / delete / link)을 제공하고, Activity 서브탭이 ingest / lint / retrieve / merge 이벤트를 시간순/severity로 보여준다. CLI-agnostic — Claude / Gemini / Codex 모두 동일한 컨텍스트를 받으며 어댑터 변경이 필요 없다.
112
112
 
113
113
  ### Planner (플래너)
114
114
  TODO와는 별개인 경량 작업 플래너 — 아이디어를 빠르게 적고, 이미지를 첨부하고, 색상 태그로 분류하고, 열 단위로 정렬할 수 있다. 플래너 항목을 한 번의 클릭으로 TODO나 예약 스케줄로 변환할 수 있다. Markdown Export / Import (status 섹션 + GFM 체크박스 + HTML 주석 메타데이터)로 다른 머신에 옮기거나 GitHub / Obsidian / 어떤 Markdown 뷰어에서도 그대로 열어볼 수 있고, `.md` 파일을 카드에 드래그하면 바로 Import된다.
@@ -122,7 +122,7 @@ TODO와는 별개인 경량 작업 플래너 — 아이디어를 빠르게 적
122
122
  TODO를 작성하면 각 작업마다 격리된 git worktree가 자동 생성된다. Claude / Gemini / Codex CLI가 동시에 병렬로 실행되며, 의존성 체인을 설정하면 선행 작업 완료 후 자동으로 후속 작업이 실행되고 브랜치 병합까지 처리된다. 프로젝트별 워크트리 토글에 더해 TODO별 3단계 오버라이드(상속 / 강제 워크트리 / 강제 메인)로 세밀한 제어가 가능하고, 메인 브랜치 작업은 자동 직렬화되어 충돌을 막는다. 드래그 앤 드롭으로 순서를 바꾸고, iOS 스타일 스택 모드로 긴 목록도 깔끔하게 관리할 수 있다.
123
123
 
124
124
  ### 인터랙티브 세션 (Sessions)
125
- 긴 생애주기의 인터랙티브 CLI 세션을 1급 엔티티로 관리 — Claude / Gemini / Codex 세션을 드래그 가능한 floating window에 띄운다. **xterm.js 렌더링**으로 ANSI 컬러, 커서 제어, TUI 박스 그리기까지 네이티브 터미널과 동일하게 표시된다 — 라인별 스크래핑이나 출력 손상이 없다. PTY가 정확한 viewport 크기로 spawn되어 Claude Code의 웰컴 배너와 메뉴가 올바른 수에서 렌더된다. 세션별 워크트리 격리 선택 가능. Window 위치와 크기는 세션마다 영속되고 전환 후에도 유지되며, 데스크톱과 모바일 모두 지원한다(작은 화면에서는 fullscreen). Chat 모드 로그 뷰어에서 출력을 assistant / tool-use 블록으로 분류해 가독성을 높인다.
125
+ 긴 생애주기의 인터랙티브 CLI 세션을 1급 엔티티로 관리 — Claude / Gemini / Codex 세션을 드래그 가능한 floating window에 띄운다. **VS Code 스타일 그룹화/도킹** 지원: 탭을 다른 윈도우로 드래그하면 5-zone 다이아몬드(top/bottom/left/right/center)로 분할 pane이나 탭 합치기가 가능하고, **Aero 스타일 엣지 스냅 + 윈도우 간 sticky 스냅 + dock tray 최소화**까지 — 멀티 세션 화면을 깔끔하게 정리할 수 있다. **xterm.js 렌더링**으로 ANSI 컬러, 커서 제어, TUI 박스 그리기까지 네이티브 터미널과 동일하게 표시된다. PTY가 정확한 viewport 크기로 spawn되고, **per-session 폰트 크기**(A−/A+ 또는 Ctrl/Cmd ±)로 가독성도 조절 가능. 세션별 위키 주입 모드와 **Send/Skip pre-flight** 배너로 자동 생성된 초기 프롬프트를 검토 명시적으로 보낼 있고, 인라인 편집 버튼으로 running이 아닌 세션은 자리에서 제목/CLI/모델/위키 주입 변경. iOS Safari 모바일은 한글 IME가 두벌식 composer로 정상 조립된다. Window 위치/크기/그룹 트리는 영속되고 탭 전환 후에도 살아남는다.
126
126
 
127
127
  ### 다중 AI 토론 (Discussion)
128
128
  아키텍트, 개발자, 리뷰어 등 역할이 다른 AI 에이전트들이 라운드 방식으로 토론한 뒤, 합의된 내용을 바탕으로 자동 구현까지 이어진다. 단일 AI의 판단보다 훨씬 검증된 설계 결과물이 나온다. **구현자(Implementer, `can_implement`)** 로 표시된 에이전트는 일반 턴에서도 코드를 커밋할 수 있고, 마지막 구현 라운드가 남은 작업을 정리해 마무리한다. 자동 구현(Auto-implement) 옵션을 켜면 토론 완료 즉시 코드 작성 라운드가 자동 실행된다. 완료된 토론에서 **Send to Planner** 버튼을 누르면 트랜스크립트를 한방 LLM 호출로 추출해 액션 아이템을 Planner로 영속한다 — 저장 전 항목별 편집 가능.
@@ -166,7 +166,7 @@ WebSocket으로 실행 로그를 실시간 스트리밍하며 두 가지 뷰를
166
166
  Claude / Gemini / Codex CLI를 프로젝트·TODO·토론 에이전트별로 선택한다. 엄격(strict) 샌드박스 모드에서는 각 CLI의 네이티브 샌드박싱(Claude `settings.json`, Codex `--full-auto`, Gemini 프롬프트 단 제한)을 사용해 파일 접근을 워크트리 디렉토리로 제한한다.
167
167
 
168
168
  ### 외부 접속
169
- Cloudflare Tunnel로 어디서든 폰·노트북으로 제어한다. 작업이나 토론이 완료되면 브라우저 알림이 울리므로, 자리를 비워도 상태를 놓치지 않는다.
169
+ Cloudflare Tunnel로 어디서든 폰·노트북으로 제어한다. 작업이나 토론이 완료되면 브라우저 알림이 울리므로, 자리를 비워도 상태를 놓치지 않는다. **Named Tunnel을 본인 도메인으로 라우팅**할 수 있어 — 사이드바 ⚙ → Tunnel 설정 모달에서 Tunnel Name + Custom Hostname을 입력하면 표시 URL이 `https://app.your-domain.com`으로 바뀌고, `*.trycloudflare.com` / `*.cfargotunnel.com`에서 발생하던 브라우저 "위험한 사이트" 경고를 본인 도메인 평판으로 회피할 수 있다.
170
170
 
171
171
  ### 즐겨찾기 런처 (Favorites)
172
172
  자주 쓰는 외부 도구(실행파일, 셸 명령어, URL/폴더)를 사이드바의 글로벌 Favorites 섹션에 등록해 두고 어디서든 한 번의 클릭으로 실행한다. 일-맡겨두기 모드라 OS 셸로 오갈 필요 없이 CLITrigger 내에서 환경 설정, IDE 실행, 외부 서비스 접근 등을 빠르게 수행할 수 있다.
@@ -268,6 +268,17 @@ npm run start:tunnel
268
268
  # → 콘솔에 https://xxxx.trycloudflare.com 출력
269
269
  ```
270
270
 
271
+ #### 본인 도메인으로 Named Tunnel 라우팅 (선택)
272
+
273
+ `*.trycloudflare.com` / `*.cfargotunnel.com`에 뜨는 브라우저 "위험한 사이트" 경고를 회피하려면 본인 도메인으로 라우팅한다. 사이드바 ⚙ → Tunnel 설정 모달에서 Tunnel Name + Custom Hostname 입력, 또는 CLI:
274
+
275
+ ```bash
276
+ clitrigger config tunnel hostname app.your-domain.com
277
+ cloudflared tunnel route dns <tunnel-name> app.your-domain.com # 한 번만 실행
278
+ ```
279
+
280
+ 표시 URL이 `https://app.your-domain.com`으로 바뀌고 도메인 평판이 본인 도메인으로 옮겨간다.
281
+
271
282
  ---
272
283
 
273
284
  ## 문서
@@ -275,7 +286,7 @@ npm run start:tunnel
275
286
  | 문서 | 내용 |
276
287
  |------|------|
277
288
  | [SETUP.md](docs/SETUP.md) | 상세 설치 및 사용 가이드 |
278
- | [CHANGELOG.md](docs/CHANGELOG.md) | 버전별 변경 이력 |
289
+ | [changelog/](docs/changelog/README.md) | 변경 이력 (월별 폴더 + 날짜별 파일) |
279
290
  | [CICD.md](docs/CICD.md) | GitHub Actions CI/CD 설정 |
280
291
  | [TESTING.md](docs/TESTING.md) | 테스트 가이드 |
281
292
 
package/bin/clitrigger.js CHANGED
@@ -67,6 +67,9 @@ async function startServer() {
67
67
  if (config.tunnelName) {
68
68
  process.env.TUNNEL_NAME = config.tunnelName;
69
69
  }
70
+ if (config.tunnelHostname) {
71
+ process.env.TUNNEL_HOSTNAME = config.tunnelHostname;
72
+ }
70
73
 
71
74
  // 서버 시작
72
75
  await import('../dist/server/index.js');
@@ -126,28 +129,58 @@ async function handleConfig(args) {
126
129
  } else if (args[0] === 'path') {
127
130
  console.log(CONFIG_DIR);
128
131
  } else if (args[0] === 'tunnel') {
132
+ const summary = () => {
133
+ const parts = [];
134
+ if (config.tunnelName) parts.push(`name: ${config.tunnelName}`);
135
+ if (config.tunnelHostname) parts.push(`hostname: ${config.tunnelHostname}`);
136
+ return parts.length ? ` (${parts.join(', ')})` : '';
137
+ };
138
+
129
139
  if (!args[1]) {
130
- console.log(`Tunnel: ${config.tunnel ? 'enabled' : 'disabled'}${config.tunnelName ? ` (name: ${config.tunnelName})` : ''}`);
140
+ console.log(`Tunnel: ${config.tunnel ? 'enabled' : 'disabled'}${summary()}`);
131
141
  return;
132
142
  }
133
143
  if (args[1] === 'on') {
134
144
  config.tunnel = true;
135
145
  if (args[2]) config.tunnelName = args[2];
136
146
  fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
137
- console.log(`Tunnel enabled.${config.tunnelName ? ` (name: ${config.tunnelName})` : ''}`);
147
+ console.log(`Tunnel enabled.${summary()}`);
138
148
  } else if (args[1] === 'off') {
139
149
  config.tunnel = false;
140
150
  delete config.tunnelName;
151
+ delete config.tunnelHostname;
141
152
  fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
142
153
  console.log('Tunnel disabled.');
154
+ } else if (args[1] === 'hostname') {
155
+ if (!args[2]) {
156
+ console.log(`Tunnel hostname: ${config.tunnelHostname || 'not set'}`);
157
+ return;
158
+ }
159
+ if (args[2] === 'clear') {
160
+ delete config.tunnelHostname;
161
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
162
+ console.log('Tunnel hostname cleared.');
163
+ return;
164
+ }
165
+ const hostname = args[2].trim().toLowerCase();
166
+ if (!/^([a-z0-9]([a-z0-9-]*[a-z0-9])?\.)+[a-z]{2,}$/i.test(hostname)
167
+ || hostname === 'localhost' || hostname === '127.0.0.1') {
168
+ console.log('Please enter a valid public domain (e.g. app.your-domain.com).');
169
+ process.exit(1);
170
+ }
171
+ config.tunnelHostname = hostname;
172
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
173
+ console.log(`Tunnel hostname set to ${hostname}.`);
143
174
  } else {
144
- console.log('Usage: clitrigger config tunnel [on [name] | off]');
175
+ console.log('Usage: clitrigger config tunnel [on [name] | off | hostname <host>|clear]');
145
176
  }
146
177
  } else {
147
178
  console.log(`Config (${CONFIG_FILE}):`);
148
179
  console.log(` Port: ${config.port || 3000}`);
149
180
  console.log(` Password: ${config.password ? 'set' : 'not set'}`);
150
- console.log(` Tunnel: ${config.tunnel ? 'enabled' : 'disabled'}${config.tunnelName ? ` (name: ${config.tunnelName})` : ''}`);
181
+ console.log(` Tunnel: ${config.tunnel ? 'enabled' : 'disabled'}`);
182
+ if (config.tunnelName) console.log(` Tunnel name: ${config.tunnelName}`);
183
+ if (config.tunnelHostname) console.log(` Tunnel hostname: ${config.tunnelHostname}`);
151
184
  }
152
185
  }
153
186
 
@@ -200,6 +233,10 @@ Usage:
200
233
  clitrigger config tunnel on Enable Cloudflare tunnel
201
234
  clitrigger config tunnel on <name> Enable named tunnel
202
235
  clitrigger config tunnel off Disable tunnel
236
+ clitrigger config tunnel hostname <host>
237
+ Set custom domain for named tunnel
238
+ clitrigger config tunnel hostname clear
239
+ Clear custom domain
203
240
  clitrigger config path Print config directory path
204
241
  clitrigger config clear Delete all config and data
205
242
  clitrigger --help Show this help