@pithosai/pithosai 1.0.0
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.md +456 -0
- package/dist/935.cjs +3 -0
- package/dist/cosai.cjs +725 -0
- package/dist/heartbeat.cjs +725 -0
- package/dist/mktai.cjs +725 -0
- package/dist/pithosai.cjs +725 -0
- package/dist/pmsai.cjs +725 -0
- package/dist/qasai.cjs +725 -0
- package/dist/rdsai.cjs +725 -0
- package/dist/render-markdown.cjs +20 -0
- package/dist/wrsai.cjs +725 -0
- package/package.json +75 -0
- package/patches/@mariozechner+pi-ai+0.52.7.patch +28 -0
package/README.md
ADDED
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
# Pithosai (pi-agent)
|
|
2
|
+
|
|
3
|
+
Pithosai is a CLI that implements code or projects from a natural-language request. Role prompts are loaded from the SQLite DB at runtime (with optional fallback to `.pithosai/<role>/*.md`). A project-local `.pithosai/` directory holds role-specific prompt files when used and persists conversation sessions under `.pithosai/sessions/`.
|
|
4
|
+
|
|
5
|
+
**Requirements:** Node.js (ESM), and a model provider — Cursor CLI (browser auth, no API key), DeepSeek API key, or OpenRouter API key.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Set up at least one model provider:
|
|
16
|
+
|
|
17
|
+
- **Cursor CLI** (recommended — no API key needed):
|
|
18
|
+
```bash
|
|
19
|
+
curl https://cursor.com/install -fsS | bash
|
|
20
|
+
cursor-agent login
|
|
21
|
+
export CURSOR_MODEL=auto # or: sonnet-4.6, opus-4.6, gpt-5.2
|
|
22
|
+
```
|
|
23
|
+
- **DeepSeek:** `export DEEPSEEK_API_KEY=sk-...`
|
|
24
|
+
- **OpenRouter:** `export OPENROUTER_API_KEY=sk-or-...`
|
|
25
|
+
|
|
26
|
+
Provider priority: `CURSOR_MODEL` / `--cursor` > `DEEPSEEK_API_KEY` > `OPENROUTER_API_KEY`.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Docker
|
|
31
|
+
|
|
32
|
+
If you want to build the Docker image, please git clone a new project from the repo, then run the following command:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
docker build --no-cache -t pithosai .
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Important:** Never share the project directory that is used by the non-Docker runtime.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Quick start
|
|
43
|
+
|
|
44
|
+
1. **Create a project**
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pithosai init
|
|
48
|
+
# or: pithosai init my-app --type js
|
|
49
|
+
# or: pithosai init ./backend --type ts --lang zh --role RD
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
This creates the target directory (if needed), scaffolds by project type (`--type js|ts|python`) and role (`--role RD|PM|QA|CO|SRE` and other template roles), creates `.pithosai/sessions/`, and writes `.settings.json` (lang, project, supportedRoles, tools). Role prompts are loaded from the SQLite DB at runtime; no prompt files are copied into the project by default. For PM, QA, CO, MKT, or SRE roles, a starter `rules/requirements.md` is created for you to fill in.
|
|
53
|
+
|
|
54
|
+
2. **Run a request**
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pithosai "Add a REST endpoint that returns the current time"
|
|
58
|
+
pithosai -C ./my-app "Run tests and fix failures"
|
|
59
|
+
pithosai "Refactor the auth module" --cursor # use Cursor models (auto)
|
|
60
|
+
pithosai --cursor sonnet-4.6 "Explain this codebase" # specific Cursor model
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
By default, after the agent replies you get an interactive session to type more requests. Type `exit` or `quit` to leave.
|
|
64
|
+
|
|
65
|
+
3. **Interactive-only mode (no initial request)**
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pithosai -i
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Terminal UI (TTY):** When both stdin and stdout are TTYs, the default run command uses **`@mariozechner/pi-tui`**: the **input area stays at the bottom** in a **boxed Editor** (no `You:` prefix on the prompt), **assistant output streams above**, and a **loading row** sits **just above the input box** while the model is working. When output hits the transcript, that row **switches to a simpler running indicator** (same idea as the stderr spinner in non-TUI mode) and **stays until the run finishes**, instead of disappearing immediately. While the TUI is up, **CWD/request banners and run status go through the transcript sink** (and the **log file** via the file-only logger), not raw stdout, so **extra `process.stdout` traffic does not paint over the full-screen layout**; **Ctrl+S** and **Ctrl+P** notices are **appended to the transcript** instead of raw stdout. **Run failures** (including guard timeouts), **dialog/plan `success: false` errors**, and **failed result previews** are **appended to the transcript in red** so they stay visible without corrupting the layout. Slash-command output, `/list` tables, and `/shell` results are drawn in the same transcript (multi-line `/list` output is split into real rows and the view **scrolls to the table header**; use the **mouse wheel**, **arrow keys**, **PgUp/PgDn**, or **Ctrl+U / Ctrl+F** (page) to scroll long output, **including while the agent is running** (**Ctrl+U/Ctrl+F** scroll the log instead of the editor’s usual line-edit shortcuts; **Ctrl+D** remains EOF / exit on an empty line). Set **`PITHOSAI_NO_TUI=1`** to use the classic readline **`You:`** line instead (e.g. scripts or SSH without a proper terminal).
|
|
72
|
+
|
|
73
|
+
In **`agent`** mode (default), prints CWD and short tips (full tools, task-scoped history in the local DB, `/new`, `/shell`, `/list`, `/show`, `/show-task [index]`, `/show-prompt`, **`/list-skill`**, **`/install-skill`**, **`/remove-skill`** — same behavior as `pithosai skills list`, `install`, and `remove` — keyboard controls), then prompts for input. **`dialog`** and **`plan`** show their own tips. After the banner, all three modes start the same input loop when interactive is enabled (plan keeps transcript output minimal until each plan file is written). **Tab** completes slash commands (e.g. `/list`, `/list-skill`, `/show`, `/show-prompt`, `/show-task`, `/install-skill`, `/remove-skill`) and `exit` / `quit` in both the pi-tui **Editor** prompt (dropdown + Enter to apply) and **readline** mode; **`/shell`** is only offered in **agent** mode. Typing **`/`** also opens the slash menu as you continue the command. The pause sub-prompt still uses readline **Tab** for `continue` / `c` and `exit` / `e`.
|
|
74
|
+
|
|
75
|
+
While an agent run is in progress, keyboard controls are available:
|
|
76
|
+
- `Ctrl+S` — stop current run and return to prompt
|
|
77
|
+
- `Ctrl+P` — pause current run and enter pause sub-prompt
|
|
78
|
+
- `continue` / `c` resumes with current request
|
|
79
|
+
- `exit` / `e` exits the CLI
|
|
80
|
+
- any other non-empty input replaces the pending request
|
|
81
|
+
|
|
82
|
+
4. **One-shot (no follow-up prompt)**
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
pithosai --no-interactive "One request only"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
5. **Run variant (`--mode`)**
|
|
89
|
+
|
|
90
|
+
The default command supports a run variant:
|
|
91
|
+
|
|
92
|
+
| Mode | Behavior |
|
|
93
|
+
|------|----------|
|
|
94
|
+
| `agent` (default) | Answer and use tools (implement, run commands via tools, etc.). |
|
|
95
|
+
| `dialog` | Answer-focused mode with **read-only tools only** (`read`, `list_files`, `read_pdf`, `web_fetch`, `web_search`, `proxy_downloader`, `read_email`). `/shell` is disabled; `/list`, `/select`, `/show`, `/show-prompt`, `/show-task [index]`, `/list-skill`, `/install-skill`, and `/remove-skill` still work. |
|
|
96
|
+
| `plan` | Writes the model reply only to `<slug>-plan.md` in the **project root** (`-C` / cwd). Same **read-only tools** as dialog; `/shell` is disabled. `/list`, `/select`, `/show`, `/show-prompt`, `/show-task [index]`, `/list-skill`, `/install-skill`, and `/remove-skill` work like dialog. With `-i`, the follow-up prompt runs another plan per line (output stays minimal in the UI until each run completes). |
|
|
97
|
+
|
|
98
|
+
**Note:** In `plan` mode the run uses a **discard output sink** by default, so you often will not see streamed tokens in the terminal until the model finishes (or times out). While waiting, a **spinner on stderr** shows progress; when anything writes to **stdout**, the line **switches to a lighter running spinner** (TTY) until the run completes, instead of being cleared immediately. On a non-TTY stderr, the spinner **stops** on first stdout as before. The default max run time is **30 minutes** (`AGENT_RUN_TIMEOUT_MS`); pass `--timeout <seconds>` for a shorter cap.
|
|
99
|
+
|
|
100
|
+
**Dialog / plan result preview:** After each run completes, **dialog** and **plan** open a full-screen terminal viewer built on **`@mariozechner/pi-tui`** (`Markdown` with the same themed styling as **pi** via **`@mariozechner/pi-coding-agent`**’s `getMarkdownTheme`): scroll with **↑↓** or **j**/**k**, **PgUp**/**PgDn** or **Ctrl+U**/**Ctrl+D**, **Home**/**End**, **gg** (top), or **G** (bottom); press **q**, **Esc**, or **Ctrl+C** to close. While the preview is open, the interactive agent TUI is suspended so those keys only affect the viewer. If stdin/stdout are not both TTY (e.g. CI), the raw markdown is printed to stdout instead. If you set `PITHOSAI_RESULT_BROWSER=chrome`, preview switches to the browser viewer implemented with Playwright and rendered as **WeChat-style HTML** (inline styles, same pipeline as the `markdown_to_html` tool with `forWechat: true`). In Chrome mode the page includes a **Copy markdown** button (copies the raw markdown via the Clipboard API, with a textarea fallback) and **Close** (closes the whole preview browser via Playwright, not only the tab—needed so Chrome does not keep an empty window after the last tab closes). Content is passed in memory via `page.setContent` (no temp file). The Chrome window is opened with **Chromium app mode** (`--app=about:blank` plus a few flags) using Playwright’s **`launchPersistentContext`** so the omnibox and tab strip stay hidden—plain `browser.newPage()` would open a normal Chrome window and ignore app mode. Only your page content and the in-page toolbar are shown (standard window title bar may still appear). Chrome mode defaults to **Google Chrome stable** (`channel: chrome`) and falls back to bundled Chromium if Chrome is missing (install with `npm run playwright:install` / `npx playwright install chromium`). To always use the bundled browser in Chrome mode, set `PITHOSAI_PLAYWRIGHT_CHANNEL=bundled`. Other channels (e.g. `msedge`, `chrome-beta`) are supported via the same variable. To disable preview (e.g. CI), set `PITHOSAI_SKIP_RESULT_BROWSER=1`.
|
|
101
|
+
|
|
102
|
+
In **`agent`** mode the model may call the **`playwright_view_markdown`** tool to open the same Playwright preview from **either** raw `markdown` **or** a project `path` to a `.md` file (exactly one of the two). The tool blocks until the user closes the preview window and respects `PITHOSAI_SKIP_RESULT_BROWSER` and `PITHOSAI_PLAYWRIGHT_CHANNEL`. It is **not** available in `dialog` / `plan` read-only toolsets.
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
pithosai --mode dialog "Explain this stack trace"
|
|
106
|
+
pithosai -C ./my-app --mode plan "Sprint plan for the API work"
|
|
107
|
+
pithosai -l zh --mode plan --timeout 120 "迭代计划"
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
6. **Shell commands in interactive mode**
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
pithosai -i
|
|
114
|
+
You: /shell ls -la
|
|
115
|
+
You: /shell git status
|
|
116
|
+
You: /shell npm test
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Prefix commands with `/shell` to execute shell commands directly.
|
|
120
|
+
|
|
121
|
+
The same prompt also supports **task-scoped commands** (conversation rows live in the local SQLite DB): `/list` lists persisted tasks as a markdown table (`index`, `task id`, `task title`, `description`, `createTime`); `/select <index>` selects the active task id, prints a selected-task line, and then shows current task stats (`/show`); `/show` prints current task stats; **`/show-prompt`** builds the system prompt for the current `--mode`, language, and role (same logic as `pithosai show-prompt`) and opens it in the same result viewer as dialog/plan, with the prompt body rendered as **markdown** (not a fenced code block); **`/show-task`** shows Q&A for the current task, and **`/show-task <index>`** shows Q&A for that persisted task index. Q&A and **`/show-prompt`** use the same configured result viewer (**pi-tui** terminal viewer by default, Playwright preview when `PITHOSAI_RESULT_BROWSER=chrome`); if `PITHOSAI_SKIP_RESULT_BROWSER=1`, markdown is printed to the terminal instead.
|
|
122
|
+
|
|
123
|
+
**Skill commands (ClawHub):** **`/list-skill`** lists installed skills under `.pithosai/skills` (like `pithosai skills list`). **`/install-skill`** with no name installs all remote skills from `clawhub list`; **`/install-skill <name>`** installs one skill; add **`--force`** to reinstall. **`/remove-skill <name>`** removes an installed skill (like `pithosai skills remove`). These use the same implementation as the `pithosai skills` CLI; `clawhub install` still uses inherited stdio when run from the REPL.
|
|
124
|
+
|
|
125
|
+
7. **Add another role**
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
pithosai add-role CO
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Creates `.pithosai/<role>/` if it does not exist and adds the role to `supportedRoles` in project settings. If `.pithosai/<role>/` already exists, the command returns without overwriting. Prompts are loaded from the SQLite DB at runtime (with file fallback). Use `-r CO` or project settings to select the role.
|
|
132
|
+
|
|
133
|
+
8. **Task mode (watch and process tasks from markdown)**
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
pithosai task --file prompts.md
|
|
137
|
+
pithosai task -C ./my-app --file prompts.md --model deepSeekCoder
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The task runner watches the task file and processes one task at a time (prioritizing `processing` tasks first, then `pending` tasks). During a running task:
|
|
141
|
+
- `Ctrl+S` stops the current task run
|
|
142
|
+
- `Ctrl+P` pauses and enters the same pause sub-prompt as interactive mode
|
|
143
|
+
- If you edit request text in pause sub-prompt, the resumed task run uses the edited text as the task request
|
|
144
|
+
|
|
145
|
+
9. **Memorize (role memory file from persisted tasks)**
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
pithosai memorize --start 2026-01-01 --end 2026-01-31 -r RD
|
|
149
|
+
pithosai -r PM memorize --start 2026-04-01 --end 2026-04-10 -C ./my-app
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Reads the local SQLite task store (`~/.pithosai/pithosai.db` unless `PITHOSAI_DB_PATH` is set), finds tasks where the **role** has persisted task messages whose timestamps fall in the inclusive date range, and writes **`.pithosai/<role>/memory.md`** with a short summary per task (title, status, contribution excerpt from assistant output, and a suggested improvement line). Dates are **YYYY-MM-DD** (whole UTC days) or full ISO datetimes. LLM summarization uses the same model selection as the default **`pithosai`** run: **`--reasoner`**, **`--chat`**, **`--cursor [model]`**, and optional **`--model <key>`** (same `KEY_TO_MODEL` keys as **`pithosai task`**). The optional LLM tightening step uses **Chinese** instructions when global **`--lang`** (or project **`lang`** in settings) is Chinese (`zh`…), and **English** otherwise. Use **`--no-llm`** or **`PITHOSAI_MEMORIZE_SKIP_LLM=1`** to write only the structured file without an LLM pass, or if the model is unavailable the command falls back to the structured markdown and prints a notice.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Role-specific commands
|
|
157
|
+
|
|
158
|
+
Besides `pithosai`, you can use role-specific entry points. Each one runs the same CLI with a default **role** (and, for some, the **chat** model). All support the same subcommands and options as `pithosai`.
|
|
159
|
+
|
|
160
|
+
| Command | Default role | Model | Use case |
|
|
161
|
+
|--------|----------------|-------|----------|
|
|
162
|
+
| **pithosai** | RD | Coder | General coding; implement from natural language. |
|
|
163
|
+
| **rdsai** | RD | Coder | Same as `pithosai`; RD (e.g. R&D) coding agent. |
|
|
164
|
+
| **pmsai** | PM | Chat | Product/project management; uses PM templates + chat model. |
|
|
165
|
+
| **qasai** | QA | Chat | QA; uses QA templates + chat model. |
|
|
166
|
+
| **cosai** | CO | Chat | CO role; uses CO templates + chat model. |
|
|
167
|
+
| **mktai** | MKT | Chat | Professional marketing (positioning, GTM, campaigns); uses MKT templates + chat model. |
|
|
168
|
+
|
|
169
|
+
Examples:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
rdsai "Refactor the auth module"
|
|
173
|
+
pmsai "Draft a sprint plan for the API work"
|
|
174
|
+
qasai "Generate test cases for the login flow"
|
|
175
|
+
cosai -i
|
|
176
|
+
mktai "Pressure-test our positioning vs two named competitors; output a matrix, proof gaps, and homepage narrative fixes"
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
You can still override role or model (e.g. `pmsai -r QA`, `qasai --reasoner`, or `rdsai --cursor`). Add a role's templates with `pithosai add-role PM` (or QA, CO, MKT, SRE, etc.) before using that role.
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Cursor CLI Integration
|
|
184
|
+
|
|
185
|
+
Use models from your Cursor subscription (Claude Sonnet/Opus, GPT-5.2, etc.) without separate API keys. Authentication is handled by the Cursor CLI's browser-based login.
|
|
186
|
+
|
|
187
|
+
**Setup (one-time):**
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# Install the Cursor agent CLI
|
|
191
|
+
curl https://cursor.com/install -fsS | bash
|
|
192
|
+
|
|
193
|
+
# Log in via browser
|
|
194
|
+
cursor-agent login
|
|
195
|
+
|
|
196
|
+
# Verify auth
|
|
197
|
+
cursor-agent status
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Usage:**
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
# Environment variable
|
|
204
|
+
export CURSOR_MODEL=auto
|
|
205
|
+
pithosai "Build a REST API"
|
|
206
|
+
|
|
207
|
+
# CLI flag (overrides env)
|
|
208
|
+
# Note: `--cursor` has an optional value. To avoid parsing the request as model id,
|
|
209
|
+
# put request before `--cursor`, or use `--` as separator.
|
|
210
|
+
pithosai "Explain this code" --cursor
|
|
211
|
+
pithosai --cursor -- "Explain this code"
|
|
212
|
+
pithosai --cursor sonnet-4.6 "Refactor auth module"
|
|
213
|
+
pithosai --cursor opus-4.6 "Design a database schema"
|
|
214
|
+
pithosai --cursor gpt-5.2 "Write unit tests"
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Available models:**
|
|
218
|
+
|
|
219
|
+
| Model id | Description |
|
|
220
|
+
|----------|-------------|
|
|
221
|
+
| `auto` | Cursor's default model selection |
|
|
222
|
+
| `sonnet-4.6` | Claude Sonnet 4.6 |
|
|
223
|
+
| `sonnet-4.6-thinking` | Claude Sonnet 4.6 with extended thinking |
|
|
224
|
+
| `opus-4.6` | Claude Opus 4.6 |
|
|
225
|
+
| `gpt-5.2` | GPT 5.2 |
|
|
226
|
+
|
|
227
|
+
Any model id supported by `cursor-agent --list-models` can be used; the above are pre-defined with metadata. Unknown ids are passed through to `cursor-agent` as-is.
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## Heartbeat
|
|
232
|
+
|
|
233
|
+
Heartbeat polls the role's email inbox for **task emails** (subjects starting with `task:` or `任务:`), enqueues them, and runs the agent on one task per tick. State (processed IDs and unprocessed queue) is stored in `~/.pithosai/heartbeat-state.json` and is keyed by role and optionally by project.
|
|
234
|
+
|
|
235
|
+
**Requirements:** The role must have IMAP/SMTP configured in `.settings.json` (see `roles.<role>.imap` and `roles.<role>.smtp`). After each task the agent sends a reply email: on success to the task sender; on failure to the support address (see `SUPPORT_EMAIL` below).
|
|
236
|
+
|
|
237
|
+
- **One tick (fetch + process one task, then exit):**
|
|
238
|
+
```bash
|
|
239
|
+
pithosai heartbeat --once
|
|
240
|
+
```
|
|
241
|
+
- **Continuous loop (poll every N seconds):**
|
|
242
|
+
```bash
|
|
243
|
+
pithosai heartbeat
|
|
244
|
+
pithosai heartbeat --interval 120
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
You can pass `-C`, `-r`, `-l`, `--reasoner`, `--chat`, `--cursor`, `--timeout`, etc. as with other commands. Programmatic API: `heartbeatTick(cwd, runOpts)` runs one tick and returns `{ processedCount, ranOne, unprocessedCount }`; `heartbeatLoop(cwd, opts)` runs the loop with `opts.intervalSeconds` (default 60).
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## Skills Management
|
|
252
|
+
|
|
253
|
+
Install, list, and remove AI skills from Clawhub AI. Skills are stored in `.pithosai/skills/` and can be used by agents via the `read_skill` tool. `clawhub install` output and install/list status messages are written to **stdout** / **stderr** in the terminal (not only to the log file).
|
|
254
|
+
|
|
255
|
+
**Requirements:** ScraperAPI account and API key (set as `SCRAPERAPI_API_KEY` environment variable).
|
|
256
|
+
|
|
257
|
+
- **Install skills:**
|
|
258
|
+
```bash
|
|
259
|
+
pithosai skills install
|
|
260
|
+
pithosai skills install greet --api-key your_key
|
|
261
|
+
pithosai skills install --force --url https://custom-skills.example.com
|
|
262
|
+
```
|
|
263
|
+
- **List installed skills:**
|
|
264
|
+
```bash
|
|
265
|
+
pithosai skills list
|
|
266
|
+
pithosai skills list -l zh
|
|
267
|
+
```
|
|
268
|
+
- **Remove skill:**
|
|
269
|
+
```bash
|
|
270
|
+
pithosai skills remove greet
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
See [Skills CLI Documentation](docs/SKILLS-CLI.md) for complete usage.
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## Skill Conversion
|
|
278
|
+
|
|
279
|
+
Automatically convert frequently used skills into permanent tools for better performance and reliability. The system monitors skill usage, analyzes patterns, and generates optimized tool implementations.
|
|
280
|
+
|
|
281
|
+
**Features:**
|
|
282
|
+
- **Usage Tracking**: Automatically records skill executions, parameters, and success rates
|
|
283
|
+
- **Pattern Analysis**: Identifies common parameter combinations and usage patterns
|
|
284
|
+
- **Smart Conversion**: Suggests when skills are ready for conversion based on usage statistics
|
|
285
|
+
- **Tool Generation**: Creates optimized JavaScript tools with proper parameter validation
|
|
286
|
+
- **Performance Boost**: Converted tools run 50-80% faster than skill-based execution
|
|
287
|
+
|
|
288
|
+
**Usage:**
|
|
289
|
+
|
|
290
|
+
- **List convertible skills:**
|
|
291
|
+
```bash
|
|
292
|
+
pithosai skill-convert list
|
|
293
|
+
pithosai skill-convert list --threshold 70
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
- **Convert a skill:**
|
|
297
|
+
```bash
|
|
298
|
+
pithosai skill-convert convert screenshot
|
|
299
|
+
pithosai skill-convert convert screenshot --dry-run # Preview conversion
|
|
300
|
+
pithosai skill-convert convert screenshot --force # Force re-conversion
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
- **View statistics:**
|
|
304
|
+
```bash
|
|
305
|
+
pithosai skill-convert stats
|
|
306
|
+
pithosai skill-convert stats --skill screenshot
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
- **Manage converted tools:**
|
|
310
|
+
```bash
|
|
311
|
+
pithosai skill-convert tools list
|
|
312
|
+
pithosai skill-convert tools remove screenshot_tool
|
|
313
|
+
pithosai skill-convert tools enable/disable screenshot_tool
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
- **Clear records:**
|
|
317
|
+
```bash
|
|
318
|
+
pithosai skill-convert clear screenshot
|
|
319
|
+
pithosai skill-convert clear --all
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
**How it works:**
|
|
323
|
+
1. When you use skills via `read_skill`, the system tracks each execution
|
|
324
|
+
2. After sufficient usage (minimum 3 successful executions), skills become eligible for conversion
|
|
325
|
+
3. The system analyzes parameter patterns and generates optimized tool code
|
|
326
|
+
4. Converted tools are stored in `.pithosai/custom-tools/` and automatically loaded
|
|
327
|
+
5. Future requests use the optimized tool instead of reading skill documentation
|
|
328
|
+
|
|
329
|
+
**Example workflow:**
|
|
330
|
+
```bash
|
|
331
|
+
# 1. Use a skill multiple times
|
|
332
|
+
pithosai "Take a screenshot of the terminal"
|
|
333
|
+
pithosai "Capture the browser window after 2 seconds"
|
|
334
|
+
pithosai "Take a screenshot of a specific region"
|
|
335
|
+
|
|
336
|
+
# 2. Check if it's ready for conversion
|
|
337
|
+
pithosai skill-convert list
|
|
338
|
+
|
|
339
|
+
# 3. Convert to permanent tool
|
|
340
|
+
pithosai skill-convert convert screenshot
|
|
341
|
+
|
|
342
|
+
# 4. Use the optimized tool directly
|
|
343
|
+
# (The agent will now use screenshot_tool instead of read_skill screenshot)
|
|
344
|
+
pithosai "Take another screenshot with delay"
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
See [Skill-to-Tool Design](docs/SKILL-TO-TOOL-DESIGN.md) for technical details.
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
## Shell Command
|
|
352
|
+
|
|
353
|
+
Execute shell commands directly or from interactive mode. Useful for file operations, git commands, and system tasks.
|
|
354
|
+
|
|
355
|
+
- **Standalone command:**
|
|
356
|
+
```bash
|
|
357
|
+
pithosai shell "ls -la"
|
|
358
|
+
pithosai shell "git status" --cwd ./my-project
|
|
359
|
+
pithosai shell "npm test" --timeout 60
|
|
360
|
+
pithosai shell --raw "echo hello"
|
|
361
|
+
```
|
|
362
|
+
- **Interactive mode:**
|
|
363
|
+
```
|
|
364
|
+
You: /shell ls -la
|
|
365
|
+
```
|
|
366
|
+
Use `/shell` prefix in interactive sessions to run shell commands.
|
|
367
|
+
|
|
368
|
+
See [Shell CLI Documentation](docs/SHELL-CLI.md) for complete usage.
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## Commands and options
|
|
373
|
+
|
|
374
|
+
| Command / option | Description |
|
|
375
|
+
|------------------|-------------|
|
|
376
|
+
| `pithosai [request]` | Run the agent for `request`. Omit to show help (or use `-i` for interactive mode). |
|
|
377
|
+
| `pithosai init [dir]` | Create project: scaffold by type/role, `.pithosai/sessions/`, and settings. Prompts loaded from SQLite at runtime. |
|
|
378
|
+
| `pithosai add-role <role>` | Add role: create `.pithosai/<role>/` if missing and update `supportedRoles`. |
|
|
379
|
+
| `pithosai skills` | Manage skills from Clawhub AI (install, list, remove). |
|
|
380
|
+
| `pithosai skill-convert` | Convert successful skills to permanent tools (monitor usage, analyze patterns, generate tools). |
|
|
381
|
+
| `pithosai shell <command>` | Execute shell commands with timeout and formatting. |
|
|
382
|
+
| `pithosai task` | Watch a task markdown file and process tasks sequentially (`processing` first, then `pending`). |
|
|
383
|
+
| `pithosai heartbeat` | Poll inbox for task emails (`task:...` / `任务:...`), enqueue and run one per tick. State in `~/.pithosai/heartbeat-state.json`. |
|
|
384
|
+
| `pithosai heartbeat --once` | Run one tick (fetch emails, process one task if any) then exit. |
|
|
385
|
+
| `pithosai heartbeat --interval <seconds>` | Poll interval in seconds (default: 60). |
|
|
386
|
+
| `pithosai show-prompt` | Display the system prompt that would be used for a run. Options: `--mode <agent|dialog|plan>`, `--raw` (show before truncation), `--truncated` (show truncated version). |
|
|
387
|
+
| `-i, --interactive` | Start in interactive mode without a request; load latest session and prompt. |
|
|
388
|
+
| `--no-interactive` | After running a request, do not prompt for more (one-shot). |
|
|
389
|
+
| `-C, --cwd <dir>` | Project directory (default: current directory). |
|
|
390
|
+
| `-l, --lang <lang>` | Language for prompts and init (e.g. `en`, `zh`). |
|
|
391
|
+
| `-r, --role <role>` | Role/template set (e.g. `RD`, `CO`). |
|
|
392
|
+
| `--timeout <seconds>` | Max agent run time (default: 1800). |
|
|
393
|
+
| `--cursor [model]` | Use Cursor CLI model (no API key; auth via `cursor-agent login`). Optional model: `auto`, `sonnet-4.6`, `opus-4.6`, `gpt-5.2`. If model is omitted, use `pithosai "<request>" --cursor` (or `--cursor -- "<request>"`) to avoid argument ambiguity. |
|
|
394
|
+
| `--reasoner` | Use DeepSeek Reasoner (thinking) model. |
|
|
395
|
+
| `--chat` | Use DeepSeek Chat model (general chat). |
|
|
396
|
+
| `--no-markdown` | Disable terminal markdown rendering and print plain text only. |
|
|
397
|
+
| `--skills-dir <dir>` | Directory for `read_skill` (default: `./.pithosai/skills` or `PITHOSAI_SKILLS_DIR`). |
|
|
398
|
+
| `--log-path <file>` | Log file path (default: `<project>/logs/pithosai.log`). |
|
|
399
|
+
|
|
400
|
+
---
|
|
401
|
+
|
|
402
|
+
## Environment variables
|
|
403
|
+
|
|
404
|
+
| Variable | Description |
|
|
405
|
+
|----------|-------------|
|
|
406
|
+
| `CURSOR_MODEL` | Cursor CLI model id (e.g. `auto`, `sonnet-4.6`, `opus-4.6`, `gpt-5.2`). No API key needed — uses `cursor-agent login` auth. |
|
|
407
|
+
| `CURSOR_AGENT_BIN` | Path to `cursor-agent` binary (default: `cursor-agent` on `PATH`). |
|
|
408
|
+
| `DEEPSEEK_API_KEY` | API key for DeepSeek (Coder / Chat / Reasoner). |
|
|
409
|
+
| `OPENROUTER_API_KEY` | API key when using OpenRouter. |
|
|
410
|
+
| `SCRAPERAPI_API_KEY` | API key for ScraperAPI (used by skills command and proxy downloader). |
|
|
411
|
+
| `PITHOSAI_TIMEOUT_MS` | Max run time in milliseconds (overrides `--timeout` when set). |
|
|
412
|
+
| `PITHOSAI_SKILLS_DIR` | Default skills directory for `read_skill`. |
|
|
413
|
+
| `PITHOSAI_RESULT_BROWSER` | Result viewer selection. Default: **pi-tui** full-screen markdown viewer. Set to `chrome` to use Playwright browser preview. |
|
|
414
|
+
| `PITHOSAI_PLAYWRIGHT_CHANNEL` | Playwright browser channel for Chrome preview mode (e.g. `chrome`, `msedge`, `chrome-beta`, `bundled`). |
|
|
415
|
+
| `PITHOSAI_SKIP_RESULT_BROWSER` | Set to `1` to skip result preview and print markdown in terminal instead. |
|
|
416
|
+
| `PITHOSAI_DEBUG_STREAM` | Set to `1` to log stream completion (for troubleshooting hangs). |
|
|
417
|
+
| `PITHOSAI_DEBUG_HOOKS` | Set to `1` to enable debug hook handlers (logging, performance, stats). |
|
|
418
|
+
| `PITHOSAI_SECURITY_HOOKS` | Set to `1` to enable security hook handlers (tool blocking, sensitive-info detection). |
|
|
419
|
+
| `PITHOSAI_BLOCKED_TOOLS` | Comma-separated list of tool names to block (requires `PITHOSAI_SECURITY_HOOKS=1`). |
|
|
420
|
+
| `PITHOSAI_DB_PATH` | Override SQLite database path (default: `~/.pithosai/pithosai.db`). |
|
|
421
|
+
| `SUPPORT_EMAIL` | When a heartbeat task fails, the failure reply is sent to this address instead of the customer. Default: `support@pithosai.com`. |
|
|
422
|
+
| `PITHOSAI_MAX_MESSAGE_TOKENS` | Max tokens for conversation messages before compression (defaults to model context minus reserved system tokens). |
|
|
423
|
+
| `PITHOSAI_MAX_HISTORY_MESSAGES` | Max number of recent messages kept before earlier history is dropped (default: 40). |
|
|
424
|
+
| `PITHOSAI_MIN_HISTORY_MESSAGES` | Minimum number of recent messages to keep when aggressively compacting history (default: 10). |
|
|
425
|
+
| `PITHOSAI_MAX_TOOL_RESULT_CHARS` | Max characters per tool result string before truncation (default: 8000). |
|
|
426
|
+
| `PITHOSAI_MIN_TOOL_RESULT_CHARS` | Minimum characters per tool result when aggressively truncating tool outputs (default: 2000). |
|
|
427
|
+
|
|
428
|
+
---
|
|
429
|
+
|
|
430
|
+
## Testing
|
|
431
|
+
|
|
432
|
+
Unit tests use [Vitest](https://vitest.dev/). Run all tests:
|
|
433
|
+
|
|
434
|
+
```bash
|
|
435
|
+
npm test
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
Tests cover prompts (loader, validator), agent event handlers (message-utils, chat, reasoner), skills (loader, read-skill tool), init (scaffold, templates, init/add-role), models (DeepSeek config, Cursor config, resolution), utils (paths, path-utils, sleep, logger), settings (read/write and merge), heartbeat, and agent tools (common, web, list-files, playwright-markdown-preview, playwright-view-tool, email).
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
## Docs
|
|
443
|
+
|
|
444
|
+
- [Changelog](CHANGELOG.md) - Release history ([Keep a Changelog](https://keepachangelog.com/) style).
|
|
445
|
+
- [Architecture](docs/ARCHITECTURE.md) - Layout, data flow, public API.
|
|
446
|
+
- [Configuration](docs/Configuration.md) - Global and project config files (`~/.pithosai/heartbeat-state.json`, `.pithosai/sessions`, `.pithosai/<role>` prompts). In **agent** mode, `.pithosai/<role>/TOOLS.md` (or `TOOLS-zh.md`) can list allowed tools under `# pi-agent-tools` and `# pithosai tools`; if those sections are missing or empty, the full toolset is used. **Dialog** / **plan** modes do not apply this filter.
|
|
447
|
+
- [Troubleshooting](docs/TROUBLESHOOTING.md) - Agent hangs, timeouts, stream debug.
|
|
448
|
+
- [Tools loop](docs/TOOLS-LOOP.md) - How the agent uses tools.
|
|
449
|
+
|
|
450
|
+
---
|
|
451
|
+
|
|
452
|
+
## License
|
|
453
|
+
|
|
454
|
+
ISC
|
|
455
|
+
|
|
456
|
+
Copyright © SHC lidh04@qq.com 2026
|
package/dist/935.cjs
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";exports.ids=["935"],exports.modules={117(t,e,i){i.d(e,{showMarkdownInPiTui:()=>a});var s=i(895),l=i(950),r=i(168);let h=!1;class n{constructor(t){const{terminal:e,tui:i,markdown:s,hintText:l,documentTitle:r,onClose:h}=t;this.terminal=e,this.tui=i,this._markdown=s,this.hintText=l,this.documentTitle=r?.trim()||"",this.onClose=h,this.scrollTop=0,this._fullLines=null,this._cachedWidth=null,this._ggAwaitingSecondG=!1,this._ggTimer=null}clearGgPrefixState(){null!=this._ggTimer&&(clearTimeout(this._ggTimer),this._ggTimer=null),this._ggAwaitingSecondG=!1}invalidate(){this._markdown.invalidate(),this._fullLines=null,this._cachedWidth=null}handleInput(t){let e=this.terminal.columns,i=Math.max(1,this.terminal.rows-!!this.documentTitle-1),s=Math.max(0,this._getFullLines(e).length-i);if((0,r.matchesKey)(t,"escape")||(0,r.matchesKey)(t,"esc")||(0,r.matchesKey)(t,"q")||(0,r.matchesKey)(t,"shift+q")||(0,r.matchesKey)(t,"ctrl+c")){this.clearGgPrefixState(),this.onClose();return}if((0,r.matchesKey)(t,"shift+g")){this.clearGgPrefixState(),this.scrollTop=s;return}if((0,r.matchesKey)(t,"g")){if(this._ggAwaitingSecondG){this.clearGgPrefixState(),this.scrollTop=0;return}this._ggAwaitingSecondG=!0,null!=this._ggTimer&&clearTimeout(this._ggTimer),this._ggTimer=setTimeout(()=>{this._ggTimer=null,this._ggAwaitingSecondG=!1},500);return}if(this.clearGgPrefixState(),(0,r.matchesKey)(t,"up")||(0,r.matchesKey)(t,"k")){this.scrollTop=Math.max(0,this.scrollTop-1);return}if((0,r.matchesKey)(t,"down")||(0,r.matchesKey)(t,"j")){this.scrollTop=Math.min(s,this.scrollTop+1);return}if((0,r.matchesKey)(t,"pageUp")||(0,r.matchesKey)(t,"ctrl+u")){this.scrollTop=Math.max(0,this.scrollTop-i);return}if((0,r.matchesKey)(t,"pageDown")||(0,r.matchesKey)(t,"ctrl+d")){this.scrollTop=Math.min(s,this.scrollTop+i);return}if((0,r.matchesKey)(t,"home")){this.scrollTop=0;return}if((0,r.matchesKey)(t,"end")){this.scrollTop=s;return}}_getFullLines(t){return this._fullLines&&this._cachedWidth===t||(this._cachedWidth=t,this._fullLines=this._markdown.render(t)),this._fullLines}render(t){let e=this.terminal.rows,i=this.documentTitle?[s.bold.cyan((0,r.truncateToWidth)(this.documentTitle,t))]:[],l=Math.max(1,e-i.length-1);null!=this._cachedWidth&&this._cachedWidth!==t&&this.invalidate();let h=this._getFullLines(t),n=Math.max(0,h.length-l);this.scrollTop=Math.min(this.scrollTop,n);let a=h.slice(this.scrollTop,this.scrollTop+l);for(;a.length<l;)a.push("");return[...i,...a,s.dim((0,r.truncateToWidth)(this.hintText,t))]}}async function a(t){let{markdown:e,t:i,documentTitle:s,tuiSession:a=null}=t;if(!e||"string"!=typeof e||!e.trim())return;if(!(process.stdout.isTTY&&process.stdin.isTTY))return void process.stdout.write(`${e}
|
|
3
|
+
`);let o=a&&"function"==typeof a.suspendForReadline&&"function"==typeof a.resumeFromReadline;o&&a.suspendForReadline();try{h||((0,l.CK)("dark"),h=!0);let t=(0,l.pd)(),a=new r.Markdown(e,1,1,t),o=i("cli.resultPreviewTerminalHint"),c=new r.ProcessTerminal,u=new r.TUI(c);u.setClearOnShrink(!0),await new Promise(t=>{let e,i=new n({terminal:c,tui:u,markdown:a,hintText:o,documentTitle:s,onClose:()=>{e?.clearGgPrefixState(),u.stop(),t()}});e=i;let l=new r.Container;l.addChild(i),u.addChild(l),u.setFocus(i),u.start(),u.requestRender(!0)})}finally{o&&a.resumeFromReadline()}}}};
|