cli-jaw 1.0.0 → 1.0.3
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/README.ko.md +21 -6
- package/README.md +108 -56
- package/README.zh-CN.md +21 -6
- package/dist/bin/commands/serve.js +1 -0
- package/dist/bin/commands/serve.js.map +1 -1
- package/dist/lib/quota-copilot.js +22 -6
- package/dist/lib/quota-copilot.js.map +1 -1
- package/dist/server.js +11 -4
- package/dist/server.js.map +1 -1
- package/dist/src/agent/spawn.js +73 -7
- package/dist/src/agent/spawn.js.map +1 -1
- package/dist/src/browser/connection.js +3 -0
- package/dist/src/browser/connection.js.map +1 -1
- package/dist/src/cli/acp-client.js +15 -12
- package/dist/src/cli/acp-client.js.map +1 -1
- package/dist/src/cli/commands.js +2 -1
- package/dist/src/cli/commands.js.map +1 -1
- package/dist/src/cli/handlers.js +22 -0
- package/dist/src/cli/handlers.js.map +1 -1
- package/dist/src/orchestrator/distribute.js +18 -1
- package/dist/src/orchestrator/distribute.js.map +1 -1
- package/dist/src/orchestrator/pipeline.js +51 -5
- package/dist/src/orchestrator/pipeline.js.map +1 -1
- package/dist/src/telegram/bot.js +29 -3
- package/dist/src/telegram/bot.js.map +1 -1
- package/package.json +1 -1
- package/public/dist/bundle.js +30 -30
- package/public/dist/bundle.js.map +4 -4
- package/public/js/cjk-fix.ts +38 -0
- package/public/js/features/chat.ts +4 -2
- package/public/js/render.ts +3 -1
- package/public/locales/en.json +4 -0
- package/public/locales/ko.json +4 -0
package/README.ko.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
*Claude, Codex, Gemini... 이제 번갈아 쓰지 마세요.*
|
|
8
8
|
|
|
9
|
-
[](#-테스트)
|
|
10
10
|
[](https://typescriptlang.org)
|
|
11
11
|
[](https://nodejs.org)
|
|
12
12
|
[](LICENSE)
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
[English](README.md) / **한국어** / [中文](README.zh-CN.md)
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
<video src="https://github.com/user-attachments/assets/a7cf17c9-bfb3-44f0-b7fd-d001a39643fd" autoplay loop muted playsinline width="100%"></video>
|
|
18
18
|
|
|
19
19
|
</div>
|
|
20
20
|
|
|
@@ -79,9 +79,10 @@ gemini # Google Gemini — 첫 실행 시 인증
|
|
|
79
79
|
## CLI-JAW란 무엇인가요?
|
|
80
80
|
|
|
81
81
|
CLI-JAW는 내 컴퓨터에 상주하며 이미 익숙한 인터페이스인 **웹, 터미널, 텔레그램**에서 작동하는 **개인용 AI 비서**입니다. 궁금한 것을 묻고, 작업을 위임하고, 워크플로우를 자동화하세요.
|
|
82
|
+

|
|
82
83
|
|
|
83
|
-
> 💬 *"오늘 일정 정리해줘"* → 텔레그램으로 바로 정리해서 보내줘요
|
|
84
|
-
> 💬 *"이 모듈 리팩토링하고 테스트도 짜줘"* → 서브에이전트가 알아서, 커피 한 잔 하고 오면 돼요
|
|
84
|
+
> 💬 *"오늘 일정 정리해줘"* → 텔레그램으로 바로 정리해서 보내줘요
|
|
85
|
+
> 💬 *"이 모듈 리팩토링하고 테스트도 짜줘"* → 서브에이전트가 알아서, 커피 한 잔 하고 오면 돼요
|
|
85
86
|
> 💬 *"저 PDF 다운받아서 핵심만 노션에 정리해"* → 브라우저 + 노션 스킬 조합으로 뚝딱
|
|
86
87
|
|
|
87
88
|
단일 모델만을 사용하는 기존 비서들과 달리, CLI-JAW는 5개의 AI 엔진(Claude, Codex, Gemini, OpenCode, Copilot)을 공식 CLI를 통해 오케스트레이션하여 모든 제공업체의 장점을 통합된 경험으로 제공합니다. 하나의 엔진 사용량이 초과되면 자동으로 다음 엔진으로 전환됩니다. 107개의 내장 스킬이 브라우저 자동화부터 문서 생성까지 모든 것을 처리합니다.
|
|
@@ -93,7 +94,7 @@ CLI-JAW는 내 컴퓨터에 상주하며 이미 익숙한 인터페이스인 **
|
|
|
93
94
|
| ⚡ **멀티 에이전트 자동 전환(Fallback)** | 엔진 하나가 멈춰도 걱정 없습니다. 다음 엔진이 즉시 이어받아 중단 없는 작업이 가능합니다. |
|
|
94
95
|
| 🎭 **오케스트레이션 기반 성능 극대화** | 복잡한 작업은 전문화된 서브 에이전트에게 분산시켜 처리량을 극대화합니다. |
|
|
95
96
|
| 📦 **107개의 내장 스킬** | 브라우저 자동화, 문서 생성, 텔레그램 연동, 영구 메모리 등 설치 즉시 사용 가능한 기능들을 제공합니다. |
|
|
96
|
-
| 🖥️ **크로스 플랫폼** | macOS, Linux, Windows
|
|
97
|
+
| 🖥️ **크로스 플랫폼** | macOS, Linux, Windows — ENOENT-safe CLI 스폰, 자동 감지, `.cmd` shim 지원, 네이티브 설치 전부 크로스플랫폼 동작. |
|
|
97
98
|
|
|
98
99
|

|
|
99
100
|
|
|
@@ -343,6 +344,19 @@ jaw --home ~/my-project launchd --port 3458 # 프로젝트 → 포트 3458
|
|
|
343
344
|
|
|
344
345
|
---
|
|
345
346
|
|
|
347
|
+
## 🐳 Docker — 컨테이너 격리
|
|
348
|
+
|
|
349
|
+
보안 격리를 위해 Docker 컨테이너에서 실행 — AI 에이전트가 호스트 파일에 접근 불가.
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
docker compose up -d # → http://localhost:3457
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
> 자세한 내용은 [English README](README.md#-docker--container-isolation) 참고.
|
|
356
|
+
> `Dockerfile` (npm 배포판) / `Dockerfile.dev` (로컬 소스) 두 가지 제공.
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
346
360
|
## 🛠️ 개발
|
|
347
361
|
|
|
348
362
|
<details>
|
|
@@ -386,7 +400,7 @@ src/
|
|
|
386
400
|
## 🧪 테스트
|
|
387
401
|
|
|
388
402
|
<details>
|
|
389
|
-
<summary>
|
|
403
|
+
<summary>445 pass · 1 skipped · 외부 의존성 0</summary>
|
|
390
404
|
|
|
391
405
|
```bash
|
|
392
406
|
npm test
|
|
@@ -415,6 +429,7 @@ npm test
|
|
|
415
429
|
| `doctor`에서 CLI 누락 표시 | 해당 CLI 미설치 | `npm i -g @anthropic-ai/claude-code` 등 설치 |
|
|
416
430
|
| 포트 3457 사용 중 | 다른 프로세스가 점유 | `PORT=4000 jaw serve` 또는 기존 프로세스 종료 |
|
|
417
431
|
| 텔레그램 봇 무반응 | 토큰 미설정 또는 Chat ID 누락 | `jaw init --telegram-token ...` 재실행 |
|
|
432
|
+
| 텔레그램 ✓✓ 지연 표시 | Telegram 서버 측 전달 확인 타이밍 | 정상 동작 — 서버 부하에 따라 수 분 걸릴 수 있음. 버그 아님 |
|
|
418
433
|
| `npm install -g` 권한 오류 | 글로벌 디렉토리 권한 문제 | `sudo npm i -g cli-jaw` 또는 [nvm](https://github.com/nvm-sh/nvm) 사용 권장 |
|
|
419
434
|
| 빌드 실패 (`tsc` 에러) | Node 22 미만 버전 | `node -v` 확인 → 22 이상으로 업그레이드 |
|
|
420
435
|
| 메모리가 세션 간 유지 안 됨 | `~/.cli-jaw/memory/` 디렉토리 없음 | `jaw init` 재실행하면 자동 생성 |
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
*One assistant. Five brains. Always on.*
|
|
8
8
|
|
|
9
|
-
[](#-tests)
|
|
10
10
|
[](https://typescriptlang.org)
|
|
11
11
|
[](https://nodejs.org)
|
|
12
12
|
[](LICENSE)
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
**English** / [한국어](README.ko.md) / [中文](README.zh-CN.md)
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
<video src="https://github.com/user-attachments/assets/a7cf17c9-bfb3-44f0-b7fd-d001a39643fd" autoplay loop muted playsinline width="100%"></video>
|
|
18
18
|
|
|
19
19
|
</div>
|
|
20
20
|
|
|
@@ -76,25 +76,25 @@ Check what's ready: `jaw doctor`
|
|
|
76
76
|
|
|
77
77
|
---
|
|
78
78
|
|
|
79
|
-
|
|
80
79
|
## What is CLI-JAW?
|
|
81
80
|
|
|
82
81
|
CLI-JAW is a **personal AI assistant** that lives on your machine and works from the interfaces you already use — **Web, Terminal, and Telegram**. Ask it anything, delegate tasks, automate your workflows.
|
|
82
|
+

|
|
83
83
|
|
|
84
|
-
> 💬 *"Summarize today's schedule"* → answer on Telegram
|
|
85
|
-
> 💬 *"Refactor this module and write tests"* → sub-agents handle it while you grab coffee
|
|
84
|
+
> 💬 *"Summarize today's schedule"* → answer on Telegram
|
|
85
|
+
> 💬 *"Refactor this module and write tests"* → sub-agents handle it while you grab coffee
|
|
86
86
|
> 💬 *"Download that PDF and put the key points in Notion"* → browser + Notion skill, done
|
|
87
87
|
|
|
88
88
|
Unlike single-model assistants, CLI-JAW orchestrates **5 AI engines** (Claude, Codex, Gemini, OpenCode, Copilot) through their official CLIs — giving you the best of every provider in one unified experience. If one engine is busy, it automatically falls back to the next. 107 built-in skills handle everything from browser automation to document generation.
|
|
89
89
|
|
|
90
|
-
|
|
|
91
|
-
|
|
|
92
|
-
|
|
|
93
|
-
|
|
|
94
|
-
|
|
|
95
|
-
|
|
|
96
|
-
|
|
|
97
|
-
|
|
|
90
|
+
| | Why CLI-JAW? |
|
|
91
|
+
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
|
|
92
|
+
| 🛡️**TOS-Safe** | Uses official CLIs only — no API key scraping, no reverse engineering, no ban risk. |
|
|
93
|
+
| 🤖**Verified Agent Tools** | 5 battle-tested coding agents (Claude, Codex, Gemini, OpenCode, Copilot) under one roof. |
|
|
94
|
+
| ⚡**Multi-Agent Fallback** | One engine down? The next picks up automatically. Zero downtime. |
|
|
95
|
+
| 🎭**Orchestrated Performance** | Complex tasks split across specialized sub-agents for maximum throughput. |
|
|
96
|
+
| 📦**107 Built-in Skills** | Browser automation, document generation, Telegram, memory — ready out of the box. |
|
|
97
|
+
| 🖥️**Cross-Platform** | macOS, Linux, Windows — ENOENT-safe CLI spawn, auto-detection,`.cmd` shim support, and native install all work across platforms. |
|
|
98
98
|
|
|
99
99
|

|
|
100
100
|
|
|
@@ -113,7 +113,7 @@ graph LR
|
|
|
113
113
|
JAW -->|inject| SK["📦 Skills"]
|
|
114
114
|
JAW -->|control| BR["🌐 Chrome"]
|
|
115
115
|
JAW -->|send| TG["📱 Telegram"]
|
|
116
|
-
|
|
116
|
+
|
|
117
117
|
style JAW fill:#f5e6d3,stroke:#d4a574,stroke-width:2px,color:#5c4033
|
|
118
118
|
```
|
|
119
119
|
|
|
@@ -128,7 +128,6 @@ graph LR
|
|
|
128
128
|
- 🔍 **Web search** — Real-time information via MCP tools.
|
|
129
129
|
- ⏰ **Heartbeat jobs** — Schedule recurring tasks that run automatically.
|
|
130
130
|
|
|
131
|
-
|
|
132
131
|
---
|
|
133
132
|
|
|
134
133
|
## 📦 Skill System
|
|
@@ -138,26 +137,26 @@ graph LR
|
|
|
138
137
|
<details>
|
|
139
138
|
<summary>View all skills</summary>
|
|
140
139
|
|
|
141
|
-
| Tier
|
|
142
|
-
|
|
|
143
|
-
| **Active Skills** | 17
|
|
144
|
-
| **Reference Skills** | 90
|
|
140
|
+
| Tier | Count | How it works |
|
|
141
|
+
| -------------------------- | :---: | --------------------------------------------------------- |
|
|
142
|
+
| **Active Skills** | 17 | Auto-injected into every AI prompt. Always available. |
|
|
143
|
+
| **Reference Skills** | 90 | AI reads them on-demand when you ask for a relevant task. |
|
|
145
144
|
|
|
146
145
|
#### Active Skills (always on)
|
|
147
146
|
|
|
148
|
-
| Skill
|
|
149
|
-
|
|
|
150
|
-
| `browser`
|
|
151
|
-
| `github`
|
|
152
|
-
| `notion`
|
|
153
|
-
| `memory`
|
|
154
|
-
| `telegram-send`
|
|
155
|
-
| `vision-click`
|
|
156
|
-
| `imagegen`
|
|
157
|
-
| `pdf` / `docx` / `xlsx`
|
|
158
|
-
| `screen-capture`
|
|
159
|
-
| `openai-docs`
|
|
160
|
-
| `dev` / `dev-frontend` / `dev-backend` / `dev-data` / `dev-testing` | Development guidelines for sub-agents
|
|
147
|
+
| Skill | What it does |
|
|
148
|
+
| ----------------------------------------------------------------------------- | ---------------------------------------------------------- |
|
|
149
|
+
| `browser` | Chrome automation — snapshot, click, navigate, screenshot |
|
|
150
|
+
| `github` | Issues, PRs, CI, code review via `gh` CLI |
|
|
151
|
+
| `notion` | Create/manage Notion pages and databases |
|
|
152
|
+
| `memory` | Persistent long-term memory across sessions |
|
|
153
|
+
| `telegram-send` | Send photos, documents, voice messages to Telegram |
|
|
154
|
+
| `vision-click` | Screenshot → AI finds coordinates → clicks (one command) |
|
|
155
|
+
| `imagegen` | Generate/edit images via OpenAI Image API |
|
|
156
|
+
| `pdf` / `docx` / `xlsx` | Read, create, edit office documents |
|
|
157
|
+
| `screen-capture` | macOS screenshot and camera capture |
|
|
158
|
+
| `openai-docs` | Up-to-date OpenAI API documentation |
|
|
159
|
+
| `dev` / `dev-frontend` / `dev-backend` / `dev-data` / `dev-testing` | Development guidelines for sub-agents |
|
|
161
160
|
|
|
162
161
|
#### Reference Skills (on-demand)
|
|
163
162
|
|
|
@@ -189,6 +188,7 @@ Your assistant isn't tied to your desk. Chat from anywhere via Telegram:
|
|
|
189
188
|
</details>
|
|
190
189
|
|
|
191
190
|
**What you can do from Telegram:**
|
|
191
|
+
|
|
192
192
|
- 💬 Chat with your assistant (any of 5 AI engines)
|
|
193
193
|
- 🎤 Send voice messages (auto-transcribed)
|
|
194
194
|
- 📎 Send files and photos for processing
|
|
@@ -196,6 +196,7 @@ Your assistant isn't tied to your desk. Chat from anywhere via Telegram:
|
|
|
196
196
|
- 🔄 Switch AI engines on the fly
|
|
197
197
|
|
|
198
198
|
**What your assistant sends back:**
|
|
199
|
+
|
|
199
200
|
- AI responses with markdown formatting
|
|
200
201
|
- Generated images, PDFs, documents
|
|
201
202
|
- Scheduled task results (heartbeat jobs)
|
|
@@ -216,18 +217,18 @@ For complex tasks, your assistant delegates work to specialized sub-agents:
|
|
|
216
217
|
```mermaid
|
|
217
218
|
graph TD
|
|
218
219
|
USER["👤 Your Request"] --> TRIAGE["🔍 Triage — Simple or Complex?"]
|
|
219
|
-
|
|
220
|
+
|
|
220
221
|
TRIAGE -->|Simple| DIRECT["⚡ Direct Response"]
|
|
221
222
|
TRIAGE -->|Complex| PLAN["📝 Planning"]
|
|
222
|
-
|
|
223
|
+
|
|
223
224
|
PLAN --> FE["🎨 Frontend"]
|
|
224
225
|
PLAN --> BE["⚙️ Backend"]
|
|
225
226
|
PLAN --> DATA["📊 Data"]
|
|
226
|
-
|
|
227
|
+
|
|
227
228
|
FE --> GATE["🚪 Gate Review"]
|
|
228
229
|
BE --> GATE
|
|
229
230
|
DATA --> GATE
|
|
230
|
-
|
|
231
|
+
|
|
231
232
|
GATE -->|Pass| NEXT["✅ Done"]
|
|
232
233
|
GATE -->|Fail| RETRY["🔄 Debug & Retry"]
|
|
233
234
|
|
|
@@ -256,7 +257,7 @@ graph LR
|
|
|
256
257
|
MJ -->|auto-sync| OC["OpenCode"]
|
|
257
258
|
MJ -->|auto-sync| CP["Copilot"]
|
|
258
259
|
MJ -->|auto-sync| AG["Antigravity"]
|
|
259
|
-
|
|
260
|
+
|
|
260
261
|
style MJ fill:#f5e6d3,stroke:#d4a574,stroke-width:2px,color:#5c4033
|
|
261
262
|
```
|
|
262
263
|
|
|
@@ -304,13 +305,13 @@ jaw --home ~/my-project launchd --port 3458 # project → port 3458
|
|
|
304
305
|
|
|
305
306
|
Each instance is fully independent — different working directory, different memory, different MCP config. Perfect for separating work/personal contexts or per-project AI setups.
|
|
306
307
|
|
|
307
|
-
| Flag / Env
|
|
308
|
-
|
|
|
308
|
+
| Flag / Env | What it does |
|
|
309
|
+
| ----------------------- | ----------------------------------------- |
|
|
309
310
|
| `--home <path>` | Use a custom home directory for this run |
|
|
310
|
-
| `--home=<path>` | Same, with `=` syntax
|
|
311
|
+
| `--home=<path>` | Same, with `=` syntax |
|
|
311
312
|
| `CLI_JAW_HOME=<path>` | Set via environment variable |
|
|
312
313
|
| `jaw clone <target>` | Clone current instance to a new directory |
|
|
313
|
-
| `--port <port>` | Custom port for `serve` / `launchd`
|
|
314
|
+
| `--port <port>` | Custom port for `serve` / `launchd` |
|
|
314
315
|
|
|
315
316
|
---
|
|
316
317
|
|
|
@@ -321,13 +322,13 @@ Each CLI comes with preconfigured presets, but you can type **any model ID** dir
|
|
|
321
322
|
<details>
|
|
322
323
|
<summary>View all presets</summary>
|
|
323
324
|
|
|
324
|
-
| CLI
|
|
325
|
-
|
|
|
325
|
+
| CLI | Default | Notable Models |
|
|
326
|
+
| ------------------ | ---------------------------- | ----------------------------------------------- |
|
|
326
327
|
| **Claude** | `claude-sonnet-4-6` | opus-4-6, haiku-4-5, extended thinking variants |
|
|
327
328
|
| **Codex** | `gpt-5.3-codex` | spark, 5.2, 5.1-max, 5.1-mini |
|
|
328
329
|
| **Gemini** | `gemini-2.5-pro` | 3.0-pro-preview, 3-flash-preview, 2.5-flash |
|
|
329
|
-
| **OpenCode** | `claude-opus-4-6-thinking` | 🆓 big-pickle, GLM-5, MiniMax, Kimi, GPT-5-Nano
|
|
330
|
-
| **Copilot** | `gpt-4.1` 🆓
|
|
330
|
+
| **OpenCode** | `claude-opus-4-6-thinking` | 🆓 big-pickle, GLM-5, MiniMax, Kimi, GPT-5-Nano |
|
|
331
|
+
| **Copilot** | `gpt-4.1` 🆓 | 🆓 gpt-5-mini, claude-sonnet-4.6, opus-4.6 |
|
|
331
332
|
|
|
332
333
|
</details>
|
|
333
334
|
|
|
@@ -335,6 +336,56 @@ Each CLI comes with preconfigured presets, but you can type **any model ID** dir
|
|
|
335
336
|
|
|
336
337
|
---
|
|
337
338
|
|
|
339
|
+
## 🐳 Docker — Container Isolation
|
|
340
|
+
|
|
341
|
+
Run CLI-JAW in a Docker container for **security isolation** — AI agents cannot access host files.
|
|
342
|
+
|
|
343
|
+
```bash
|
|
344
|
+
# Quick start (after npm publish)
|
|
345
|
+
docker compose up -d
|
|
346
|
+
# → http://localhost:3457
|
|
347
|
+
|
|
348
|
+
# Or build manually
|
|
349
|
+
docker build -t cli-jaw .
|
|
350
|
+
docker run -d -p 3457:3457 --env-file .env --name jaw cli-jaw
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
<details>
|
|
354
|
+
<summary>📋 Docker details</summary>
|
|
355
|
+
|
|
356
|
+
**Two Dockerfiles:**
|
|
357
|
+
|
|
358
|
+
| File | Purpose | Use Case |
|
|
359
|
+
| ------------------ | -------------------------- | ----------------------- |
|
|
360
|
+
| `Dockerfile` | Installs from npm registry | Production / deployment |
|
|
361
|
+
| `Dockerfile.dev` | Builds from local source | Development / testing |
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
# Dev build (local source)
|
|
365
|
+
docker build -f Dockerfile.dev -t cli-jaw:dev .
|
|
366
|
+
docker run -d -p 3457:3457 --env-file .env cli-jaw:dev
|
|
367
|
+
|
|
368
|
+
# Pin version for CI
|
|
369
|
+
docker build --build-arg CLI_JAW_VERSION=1.0.1 -t cli-jaw:1.0.1 .
|
|
370
|
+
|
|
371
|
+
# If Chromium sandbox fails in your environment
|
|
372
|
+
docker run -e CHROME_NO_SANDBOX=1 -p 3457:3457 cli-jaw
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
**Security:**
|
|
376
|
+
|
|
377
|
+
- Non-root `jaw` user — Chromium sandbox enabled by default
|
|
378
|
+
- No `ipc: host` or `seccomp=unconfined` — full container isolation
|
|
379
|
+
- `--no-sandbox` only via explicit `CHROME_NO_SANDBOX=1` opt-in
|
|
380
|
+
- Build-time feature guard prevents outdated image deployment
|
|
381
|
+
|
|
382
|
+
**Volumes:** Data persists in `jaw-data` named volume (`/home/jaw/.cli-jaw`).
|
|
383
|
+
To use existing host config: `-v ~/.cli-jaw:/home/jaw/.cli-jaw`
|
|
384
|
+
|
|
385
|
+
</details>
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
338
389
|
## 🛠️ Development
|
|
339
390
|
|
|
340
391
|
<details>
|
|
@@ -378,7 +429,7 @@ src/
|
|
|
378
429
|
## 🧪 Tests
|
|
379
430
|
|
|
380
431
|
<details>
|
|
381
|
-
<summary>
|
|
432
|
+
<summary>445 pass · 1 skipped · zero external dependencies</summary>
|
|
382
433
|
|
|
383
434
|
```bash
|
|
384
435
|
npm test
|
|
@@ -392,8 +443,8 @@ All tests run via `tsx --test` (native Node.js test runner + TypeScript).
|
|
|
392
443
|
|
|
393
444
|
## 📖 Documentation
|
|
394
445
|
|
|
395
|
-
| Document
|
|
396
|
-
|
|
|
446
|
+
| Document | What's inside |
|
|
447
|
+
| ------------------------------------ | ----------------------------------------------------- |
|
|
397
448
|
| [ARCHITECTURE.md](docs/ARCHITECTURE.md) | System design, module graph, REST API (40+ endpoints) |
|
|
398
449
|
| [TESTS.md](TESTS.md) | Test coverage and test plan |
|
|
399
450
|
|
|
@@ -404,15 +455,16 @@ All tests run via `tsx --test` (native Node.js test runner + TypeScript).
|
|
|
404
455
|
<details>
|
|
405
456
|
<summary>Common issues</summary>
|
|
406
457
|
|
|
407
|
-
| Problem
|
|
408
|
-
|
|
|
409
|
-
| `cli-jaw: command not found` | Run `npm install -g cli-jaw` again. Check `npm bin -g` is in your `$PATH`.
|
|
410
|
-
| `Error: node version` | Upgrade to Node.js ≥ 22
|
|
411
|
-
| Agent timeout / no response
|
|
458
|
+
| Problem | Solution |
|
|
459
|
+
| ------------------------------ | --------------------------------------------------------------------------------------------- |
|
|
460
|
+
| `cli-jaw: command not found` | Run `npm install -g cli-jaw` again. Check `npm bin -g` is in your `$PATH`. |
|
|
461
|
+
| `Error: node version` | Upgrade to Node.js ≥ 22:`nvm install 22` or download from [nodejs.org](https://nodejs.org) |
|
|
462
|
+
| Agent timeout / no response | Run `jaw doctor` to check CLI auth. Re-authenticate with `claude auth` / `codex login`. |
|
|
412
463
|
| `EADDRINUSE: port 3457` | Another instance is running. Stop it or use `jaw serve --port 3458`. |
|
|
413
|
-
| Telegram bot not responding
|
|
414
|
-
|
|
|
415
|
-
|
|
|
464
|
+
| Telegram bot not responding | Check token with `jaw doctor`. Ensure `jaw serve` is running. |
|
|
465
|
+
| Telegram ✓✓ delayed | Normal — Telegram server-side delivery ack can take a few minutes under load. Not a bug. |
|
|
466
|
+
| Skills not loading | Run `jaw skill reset` then `jaw mcp sync`. |
|
|
467
|
+
| Browser commands fail | Install Chrome/Chromium. Run `jaw browser start` first. |
|
|
416
468
|
|
|
417
469
|
</details>
|
|
418
470
|
|
package/README.zh-CN.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
*Claude、Codex、Gemini... 从此告别来回切换。*
|
|
8
8
|
|
|
9
|
-
[](#-测试)
|
|
10
10
|
[](https://typescriptlang.org)
|
|
11
11
|
[](https://nodejs.org)
|
|
12
12
|
[](LICENSE)
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
[English](README.md) / [한국어](README.ko.md) / **中文**
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
<video src="https://github.com/user-attachments/assets/a7cf17c9-bfb3-44f0-b7fd-d001a39643fd" autoplay loop muted playsinline width="100%"></video>
|
|
18
18
|
|
|
19
19
|
</div>
|
|
20
20
|
|
|
@@ -79,9 +79,10 @@ gemini # Google Gemini — 首次运行触发认证
|
|
|
79
79
|
## CLI-JAW 是什么?
|
|
80
80
|
|
|
81
81
|
CLI-JAW 是驻留在您本地机器上的**专属 AI 助手**,并在您熟悉的界面中运行 — **网页、终端和 Telegram**。您可以向它提出任何问题、委派任务或是自动化您的工作流。
|
|
82
|
+

|
|
82
83
|
|
|
83
|
-
> 💬 *"帮我整理一下今天的日程"* → 直接在 Telegram 上收到整理好的结果
|
|
84
|
-
> 💬 *"重构这个模块,顺便写好测试"* → 子 Agent 搞定,你喝杯咖啡回来就行
|
|
84
|
+
> 💬 *"帮我整理一下今天的日程"* → 直接在 Telegram 上收到整理好的结果
|
|
85
|
+
> 💬 *"重构这个模块,顺便写好测试"* → 子 Agent 搞定,你喝杯咖啡回来就行
|
|
85
86
|
> 💬 *"把那个 PDF 下载下来,关键信息放到 Notion 里"* → 浏览器 + Notion 技能组合,搞定
|
|
86
87
|
|
|
87
88
|
与单一模型的助手不同,CLI-JAW 通过官方 CLI 命令行工具对 **5 大 AI 引擎**(Claude、Codex、Gemini、OpenCode、Copilot)进行编排 — 为您提供各大供应商最优势的能力及统一的体验。当一个引擎处于繁忙状态时,它会自动无缝切换至下一个。107 个内置技能可处理从浏览器自动化到文档生成的所有事务。
|
|
@@ -93,7 +94,7 @@ CLI-JAW 是驻留在您本地机器上的**专属 AI 助手**,并在您熟悉
|
|
|
93
94
|
| ⚡ **多模型自动回退 (Fallback)** | 单一引擎发生故障?下一个立即接管。确保零停机。 |
|
|
94
95
|
| 🎭 **基于编排的性能优化** | 复杂的任务会被拆分给专业的子智能体,以实现效率最大化。 |
|
|
95
96
|
| 📦 **107 个内置技能** | 浏览器自动化、文档生成、Telegram 通知、持久化记忆 — 开箱即用。 |
|
|
96
|
-
| 🖥️ **跨平台支持** | macOS、Linux、Windows
|
|
97
|
+
| 🖥️ **跨平台支持** | macOS、Linux、Windows — ENOENT-safe CLI 启动、自动检测、`.cmd` 支持,跨平台原生运行。 |
|
|
97
98
|
|
|
98
99
|

|
|
99
100
|
|
|
@@ -343,6 +344,19 @@ jaw --home ~/my-project launchd --port 3458 # 项目 → 端口 3458
|
|
|
343
344
|
|
|
344
345
|
---
|
|
345
346
|
|
|
347
|
+
## 🐳 Docker — 容器隔离
|
|
348
|
+
|
|
349
|
+
在 Docker 容器中运行以实现安全隔离 — AI 代理无法访问主机文件。
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
docker compose up -d # → http://localhost:3457
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
> 详细信息请参阅 [English README](README.md#-docker--container-isolation)。
|
|
356
|
+
> 提供 `Dockerfile`(npm 发布版)和 `Dockerfile.dev`(本地源码构建)两种方式。
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
346
360
|
## 🛠️ 开发
|
|
347
361
|
|
|
348
362
|
<details>
|
|
@@ -386,7 +400,7 @@ src/
|
|
|
386
400
|
## 🧪 测试
|
|
387
401
|
|
|
388
402
|
<details>
|
|
389
|
-
<summary>
|
|
403
|
+
<summary>445 pass · 1 skipped · 零外部依赖</summary>
|
|
390
404
|
|
|
391
405
|
```bash
|
|
392
406
|
npm test
|
|
@@ -415,6 +429,7 @@ npm test
|
|
|
415
429
|
| `doctor` 显示 CLI 缺失 | 对应 CLI 未安装 | 按提示安装,如 `npm i -g @anthropic-ai/claude-code` |
|
|
416
430
|
| 端口 3457 被占用 | 其他进程占用了端口 | 改用 `PORT=4000 jaw serve` 或终止占用进程 |
|
|
417
431
|
| Telegram 机器人无响应 | Token 未配置或缺少 Chat ID | 重新运行 `jaw init --telegram-token ...` |
|
|
432
|
+
| Telegram ✓✓ 延迟显示 | Telegram 服务器端交付确认时序 | 正常行为 — 服务器负载较高时可能延迟数分钟,非 Bug |
|
|
418
433
|
| `npm install -g` 权限错误 | 全局目录权限不足 | 使用 `sudo npm i -g cli-jaw` 或推荐 [nvm](https://github.com/nvm-sh/nvm) |
|
|
419
434
|
| 构建失败(`tsc` 报错) | Node 版本低于 22 | `node -v` 检查 → 升级至 22+ |
|
|
420
435
|
| 会话间记忆未保留 | `~/.cli-jaw/memory/` 目录缺失 | 重新运行 `jaw init` 自动创建 |
|
|
@@ -11,6 +11,7 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
|
11
11
|
const projectRoot = join(__dirname, '..', '..');
|
|
12
12
|
const { values } = parseArgs({
|
|
13
13
|
args: process.argv.slice(3),
|
|
14
|
+
allowNegative: true,
|
|
14
15
|
options: {
|
|
15
16
|
port: { type: 'string', default: process.env.PORT || '3457' },
|
|
16
17
|
host: { type: 'string', default: '0.0.0.0' },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../../bin/commands/serve.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../../bin/commands/serve.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,14 +6,30 @@ let _cachedToken = null;
|
|
|
6
6
|
function getCopilotToken() {
|
|
7
7
|
if (_cachedToken)
|
|
8
8
|
return _cachedToken;
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
// ─── DIFF-D: env-first fallback (cross-platform) ───
|
|
10
|
+
const envToken = process.env.COPILOT_GITHUB_TOKEN ||
|
|
11
|
+
process.env.GH_TOKEN ||
|
|
12
|
+
process.env.GITHUB_TOKEN;
|
|
13
|
+
if (envToken) {
|
|
14
|
+
_cachedToken = envToken;
|
|
15
|
+
return _cachedToken;
|
|
11
16
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
// macOS only: Keychain lookup
|
|
18
|
+
if (process.platform === 'darwin') {
|
|
19
|
+
try {
|
|
20
|
+
_cachedToken = execSync('security find-generic-password -s "copilot-cli" -w', { encoding: 'utf8', timeout: 5000 }).trim();
|
|
21
|
+
}
|
|
22
|
+
catch (e) {
|
|
23
|
+
console.warn('[quota-copilot] keychain read failed:', e.message?.split('\n')[0]);
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
return _cachedToken || null;
|
|
27
|
+
}
|
|
28
|
+
// win32/linux: no keychain CLI — rely on env tokens above
|
|
29
|
+
if (process.env.DEBUG) {
|
|
30
|
+
console.info(`[quota-copilot] token lookup skipped on ${process.platform} (set COPILOT_GITHUB_TOKEN or GH_TOKEN)`);
|
|
15
31
|
}
|
|
16
|
-
return
|
|
32
|
+
return null;
|
|
17
33
|
}
|
|
18
34
|
export async function fetchCopilotQuota() {
|
|
19
35
|
const token = getCopilotToken();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quota-copilot.js","sourceRoot":"","sources":["../../lib/quota-copilot.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,qDAAqD;AACrD,sDAAsD;AAEtD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,IAAI,YAAY,GAAkB,IAAI,CAAC;AAEvC,SAAS,eAAe;IACpB,IAAI,YAAY;QAAE,OAAO,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"quota-copilot.js","sourceRoot":"","sources":["../../lib/quota-copilot.ts"],"names":[],"mappings":"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"}
|
package/dist/server.js
CHANGED
|
@@ -22,7 +22,7 @@ import { mergeSettingsPatch } from './src/core/settings-merge.js';
|
|
|
22
22
|
import { setWss, broadcast } from './src/core/bus.js';
|
|
23
23
|
import * as memory from './src/memory/memory.js';
|
|
24
24
|
import { loadLocales, t, normalizeLocale } from './src/core/i18n.js';
|
|
25
|
-
import { JAW_HOME, PROMPTS_DIR, DB_PATH, SKILLS_DIR, SKILLS_REF_DIR, settings, loadSettings, saveSettings, replaceSettings, ensureDirs, runMigration, loadHeartbeatFile, saveHeartbeatFile, detectAllCli, } from './src/core/config.js';
|
|
25
|
+
import { JAW_HOME, PROMPTS_DIR, DB_PATH, SKILLS_DIR, SKILLS_REF_DIR, settings, loadSettings, saveSettings, replaceSettings, ensureDirs, runMigration, loadHeartbeatFile, saveHeartbeatFile, detectAllCli, APP_VERSION, } from './src/core/config.js';
|
|
26
26
|
import { db, getSession, updateSession, getMessages, getMessagesWithTrace, clearMessages, getMemory, upsertMemory, deleteMemory, getEmployees, insertEmployee, deleteEmployee, } from './src/core/db.js';
|
|
27
27
|
import { initPromptFiles, getMemoryDir, regenerateB, A2_PATH, HEARTBEAT_PATH, getMergedSkills, } from './src/prompt/builder.js';
|
|
28
28
|
import { activeProcess, killAllAgents, messageQueue, saveUpload, memoryFlushCounter, resetFallbackState, } from './src/agent/spawn.js';
|
|
@@ -237,7 +237,7 @@ function applySettingsPatch(rawPatch = {}, { restartTelegram = false } = {}) {
|
|
|
237
237
|
}
|
|
238
238
|
}
|
|
239
239
|
if (restartTelegram && hasTelegramUpdate)
|
|
240
|
-
initTelegram();
|
|
240
|
+
void initTelegram();
|
|
241
241
|
return settings;
|
|
242
242
|
}
|
|
243
243
|
function seedDefaultEmployees({ reset = false, notify = false } = {}) {
|
|
@@ -265,6 +265,7 @@ function makeWebCommandCtx(req, localeOverride = null) {
|
|
|
265
265
|
resetEmployees: () => seedDefaultEmployees({ reset: true, notify: true }),
|
|
266
266
|
});
|
|
267
267
|
}
|
|
268
|
+
app.get('/api/health', (_req, res) => res.json({ ok: true, version: APP_VERSION, uptime: process.uptime() }));
|
|
268
269
|
app.get('/api/session', (_, res) => ok(res, getSession(), getSession()));
|
|
269
270
|
app.get('/api/messages', (req, res) => {
|
|
270
271
|
const includeTrace = ['1', 'true', 'yes'].includes(String(req.query.includeTrace || '').toLowerCase());
|
|
@@ -748,10 +749,16 @@ app.get('/api/i18n/:lang', (req, res) => {
|
|
|
748
749
|
// ─── Start ───────────────────────────────────────────
|
|
749
750
|
watchHeartbeatFile();
|
|
750
751
|
// ─── Graceful Shutdown ──────────────────────────────
|
|
751
|
-
['SIGTERM', 'SIGINT'].forEach(sig => process.on(sig, () => {
|
|
752
|
+
['SIGTERM', 'SIGINT'].forEach(sig => process.on(sig, async () => {
|
|
752
753
|
console.log(`\n[server] ${sig} received, shutting down...`);
|
|
753
754
|
stopHeartbeat();
|
|
754
755
|
killAllAgents('shutdown');
|
|
756
|
+
if (telegramBot) {
|
|
757
|
+
try {
|
|
758
|
+
await telegramBot.stop();
|
|
759
|
+
}
|
|
760
|
+
catch { }
|
|
761
|
+
}
|
|
755
762
|
wss.close();
|
|
756
763
|
server.close(() => {
|
|
757
764
|
console.log('[server] closed');
|
|
@@ -804,7 +811,7 @@ server.listen(PORT, () => {
|
|
|
804
811
|
catch (e) {
|
|
805
812
|
console.error('[mcp-init]', e.message);
|
|
806
813
|
}
|
|
807
|
-
initTelegram();
|
|
814
|
+
void initTelegram();
|
|
808
815
|
startHeartbeat();
|
|
809
816
|
// ─── Seed default employees if none exist ────────
|
|
810
817
|
const seeded = seedDefaultEmployees();
|