open-claude-p 1.0.0 → 1.1.1

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/CHANGELOG.md ADDED
@@ -0,0 +1,260 @@
1
+ # Changelog
2
+
3
+ All notable changes to **open-claude-p** are documented here.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ---
9
+
10
+ ## [1.1.1] — 2026-05-19
11
+
12
+ Post-1.1.0 fixes driven by Cosmica integration testing. Several of
13
+ these are essentially the 1.1.0 release "actually working" — the
14
+ 1.1.0 surface was correct on paper but a handful of subtle parser
15
+ and default-value bugs kept the new behaviour from landing in
16
+ practice.
17
+
18
+ ### Fixed
19
+
20
+ - **Trust dialog auto-accept regressed silently for two distinct
21
+ reasons.**
22
+ - The driver's `❯` chevron pattern matched both the real input
23
+ box and the trust dialog's "currently-selected" row
24
+ (`❯ 1. Yes, I trust this folder`). `prompt-box-shown` fired
25
+ on the dialog row, the await chain proceeded to the prompt
26
+ write, and the trailing `\r` confirmed whichever option was
27
+ highlighted — silently dropping the user message. Pattern is
28
+ now `/^[❯›❮‹](?:$|\s(?!\d+\.\s))/` and a write-time guard
29
+ refuses to send when `dialogState` is in a blocked state.
30
+ - The trust dialog text is rendered with cursor-positioning
31
+ escapes between words rather than real space bytes; after the
32
+ ANSI strip the buffer reads `Quicksafetycheck` (no spaces) and
33
+ the `/Quick safety check/i` pattern never matched. Result: the
34
+ dialog rendered in ~250 ms but the watcher never fired, the
35
+ driver fell back to writing the prompt after
36
+ `OCP_PROMPT_BOX_WAIT_MS`, and the trailing CR confirmed "Yes"
37
+ in the still-open dialog. The watcher now strips ANSI before
38
+ pattern-matching and the patterns accept `\s*` between every
39
+ word.
40
+ - **`OCP_PROMPT_BOX_WAIT_MS` default 6 s → 30 s.** Environments
41
+ with many MCP servers or plugins need 8–25 s before the input
42
+ box renders. 6 s was tripping the timeout before claude had
43
+ even shown the trust dialog. Short-circuited the moment
44
+ `prompt-box-shown` fires, so the common-case latency is
45
+ unchanged.
46
+ - **`dangerouslySkipPermissions` is now ON by default across
47
+ EVERY surface** — not just the CLI. The 1.1.0 commit only
48
+ flipped the CLI's default and left `createDriver().runOneShot()`
49
+ and `createChatClient()` on the pre-1.1 `false`, so anything
50
+ using the SDK directly (the bundled sample chat, third-party
51
+ wrappers) still hung on the first tool call. Sample server's
52
+ redundant env-gate is dropped accordingly.
53
+ - **End-of-reply marker no longer flagged as
54
+ "prompt-injection".** The 1.0/1.1 instruction text used the
55
+ word "token": `Append the literal token ⟦OCP_END:xxx⟧ ...`.
56
+ The model's safety classifier treated "include this token in
57
+ your reply" as an access-token / API-key exfiltration attempt
58
+ and sometimes appended a `prompt injection attempt detected`
59
+ warning to the user-facing reply. Reworded to "end-of-reply
60
+ marker" and framed as `ocp wrapper's plumbing` so claude
61
+ recognises it as harness infrastructure rather than hostile
62
+ injection.
63
+
64
+ ### Changed
65
+
66
+ - **postinstall skips the shebang rewrite when running inside a
67
+ git checkout** (detected by the presence of `.git/` next to
68
+ `package.json`). The rewrite is meant for end-user installs from
69
+ the npm tarball; in a dev `git clone + npm link` setup it
70
+ otherwise overwrote `#!/usr/bin/env node` with the developer's
71
+ absolute node path on every `npm install` / `npm test`, showing
72
+ up as a noisy working-tree diff. Consumer installs unaffected.
73
+
74
+ ---
75
+
76
+ ## [1.1.0] — 2026-05-18
77
+
78
+ `ocp` 1.1 reshapes the CLI defaults around the assumption that
79
+ **callers are programs, not humans**, and adds a JSONL-first
80
+ extraction path so PTY chrome can no longer leak into responses.
81
+
82
+ ### Added
83
+
84
+ - **JSONL-first response extraction.** `claude` writes the completed
85
+ assistant turn to `~/.claude/projects/<cwd>/<sid>.jsonl`. The driver
86
+ now reads that authoritative source first and falls back to
87
+ PTY-extracted text only when the JSONL is unavailable
88
+ (`--no-session-persistence`, missing file, etc.). Cleans up
89
+ statusline / HUD plugin / `[Pasted text #N]` leakage at the source.
90
+ Result: `diagnostics.textSource` is `"jsonl"` or `"pty"`,
91
+ `diagnostics.recoveredFromJsonl` is `true` when a PTY-side abort
92
+ was overridden by a successful JSONL read.
93
+ - **Paste-mode handling for large prompts.** New driver option
94
+ `pasteMode` (`auto` | `chunk` | `bracket` | `raw`) with env
95
+ `OCP_PASTE_MODE`. Prompts above `OCP_PASTE_THRESHOLD` bytes
96
+ (default 1024) are written in ~256-char chunks with brief delays
97
+ so the upstream TUI's paste detector does not coalesce them into
98
+ a `[Pasted text]` placeholder that swallows the trailing
99
+ carriage-return. New exported helper `writePromptToSession`.
100
+ - **Stall-cause detector.** New `src/diagnostics/stall-cause.js`
101
+ scans the captured PTY tail at abort time and returns a stable
102
+ machine-readable identifier (`mcp-auth-required`,
103
+ `trust-required`, `theme-picker`, `login-expired`,
104
+ `tool-permission`, `paste-not-submitted`) plus an actionable
105
+ English hint, surfaced as `detected: <kind>` on stderr.
106
+ - **`TUI_CHROME_PATTERNS` / `TUI_CHROME_INLINE_PATTERNS`** exported
107
+ from `open-claude-p/chat`. Line-anchored vs inline-fragment
108
+ pattern lists used by `cleanResponse`. External callers building
109
+ alternative scrubbers can reuse the list.
110
+ - **`OCP_NO_SESSION_PERSISTENCE` env binding** on the CLI. Previously
111
+ only the flag `--no-session-persistence` was honoured.
112
+ - **`OCP_DUMP_STALL=1` opt-in** for the PTY screen tail in abort
113
+ errors. The default suppresses the tail because it can echo the
114
+ caller's prompt (a real concern for RAG-injected prompts containing
115
+ user data).
116
+ - **`OCP_NO_AUTO_ACCEPT_TRUST=1` opt-out** for folder-trust
117
+ auto-accept.
118
+ - **`OCP_NO_SKIP_PERMS=1` opt-out** for the new default
119
+ `--dangerously-skip-permissions`.
120
+ - **CHANGELOG.md** (this file).
121
+ - **`ocp-sample` companion CLI.** Downloads the demo chat-UI app
122
+ (the `sample/` subtree) from the upstream git repo on demand so
123
+ the published tarball stays small. Subcommands `init` (clone +
124
+ npm install into a user-chosen directory), `start` (detached server
125
+ with PID/log file), `stop`, `status`. Pretty TTY output (braille
126
+ spinner, success/failure marks, end-of-init banner with the running
127
+ URL); auto-falls-back to plain text when `NO_COLOR=1` or stderr
128
+ isn't a TTY. Designed for npx-first use:
129
+ `npx -p open-claude-p ocp-sample init demo`.
130
+
131
+ ### Changed
132
+
133
+ - **`--dangerously-skip-permissions` / `dangerouslySkipPermissions`
134
+ is now the default ON across EVERY surface** — `ocp` CLI,
135
+ `createDriver().runOneShot()`, `createChatClient()`, and the
136
+ `sample/` server. Rationale: `ocp` is a PTY automation library; an
137
+ interactive permission prompt that wants a human y/n hangs forever
138
+ — every Bash / Edit / Write / MCP / WebSearch call breaks without
139
+ this flag. The pre-1.1 library default of `false` was the cause
140
+ of nearly every "the SDK silently hangs on tool use" report.
141
+ Opt out per surface:
142
+ - CLI: `OCP_NO_SKIP_PERMS=1` (env)
143
+ - `createChatClient({ dangerouslySkipPermissions: false })`
144
+ - `runOneShot({ dangerouslySkipPermissions: false })`
145
+ Pre-1.1 users with `OCP_DEFAULT_SKIP_PERMS=1` exported see no
146
+ change; the env is now a no-op.
147
+ - **Folder-trust dialog is auto-accepted by default.** Same
148
+ rationale: a `claude` dialog asking "Do you trust this folder?"
149
+ is unanswerable from PTY automation. Opt out via
150
+ `OCP_NO_AUTO_ACCEPT_TRUST=1`.
151
+ - **Abort completions no longer leak PTY noise.**
152
+ When `completionReason` is in
153
+ `{timeout, interactive-required, trust-required, cancelled, write-failed, upstream-exited}`:
154
+ - The `text` adapter writes nothing to stdout (was: accumulated
155
+ PTY junk).
156
+ - The `stream-json` adapter emits only `system/init` +
157
+ `result.subtype=error` (was: also an `assistant` frame with the
158
+ PTY-extracted blob).
159
+ - The `printStalledOutput` PTY tail is omitted by default
160
+ (was: emitted to stderr including the caller's prompt back-echo).
161
+ - **`cleanResponse` scrubs HUD chrome.** Additional patterns added
162
+ for claude-hud counters, MCP-auth banners, paste placeholders,
163
+ and `Context ░░░░ N%` meters. Inline fragments are removed
164
+ without dropping the surrounding line.
165
+ - **Permissive CLI defaults note in README** — `Recommended one-time
166
+ setup` reduced to "None required". The post-1.0 opt-in envs
167
+ (`OCP_AUTO_ACCEPT_TRUST=1`, `OCP_DEFAULT_SKIP_PERMS=1`) are now
168
+ effectively no-ops; users keep them in `~/.zshrc` without effect,
169
+ or remove them.
170
+
171
+ ### Fixed
172
+
173
+ - **macOS realpath in `~/.claude/projects/<encoded-cwd>/` lookup.**
174
+ Earlier versions used `path.resolve(cwd)` which is a string
175
+ operation that does not follow symlinks. On macOS `/var`, `/tmp`,
176
+ and other launchd-owned paths redirect to `/private/<…>`; `claude`
177
+ itself resolves symlinks when picking its JSONL directory, so the
178
+ driver was looking up a directory the upstream never wrote to.
179
+ Net effect: any session under a `/var/` or `/tmp/` cwd had its
180
+ session id capture fail silently, so `claudeSessionId` stayed
181
+ `null`, `--resume` was never threaded between turns, and every
182
+ call spawned a fresh conversation with no memory of the previous
183
+ one. Fixed via `realpath` in `src/index.js` (driver),
184
+ `src/chat/index.js` (`readSessionText`), and `src/print-mode.js`.
185
+ - **Stale daemon socket on launch.** A SIGKILL'd daemon left
186
+ `~/.ocp/d-*.sock` behind; the next launch's `server.listen` failed
187
+ with `EADDRINUSE` and the client gave up and fell back to direct
188
+ mode. The daemon now pre-unlinks the path before binding.
189
+ - **`readSessionText` strict-mode fallback.** When the caller passes
190
+ a `sessionId`, the function no longer scans neighbouring JSONLs in
191
+ the project dir on miss. Under concurrent load (another claude
192
+ session active in the same cwd, an editor's built-in agent, …)
193
+ the scan picked the most-recently-modified file and returned
194
+ someone else's transcript as the "model's response". Strict mode
195
+ returns `null` on miss instead.
196
+ - **GUI-app install of `ocp`.** The postinstall script rewrites the
197
+ shebang in `bin/cli.js` from `#!/usr/bin/env node` to the absolute
198
+ path of the node binary that ran the install (`process.execPath`).
199
+ Without this, launching `ocp` from a launchd-managed GUI process
200
+ (Electron, Tauri, native Cocoa) — which gets `/usr/bin:/bin` as
201
+ PATH and never sees nvm / homebrew node — fails with
202
+ `env: node: No such file or directory` before our code runs.
203
+ - **`stream-json` adapter** now opens with `system/init` even when
204
+ no session id was captured (regression-proofs consumer parsers
205
+ expecting the init line as the first event regardless of
206
+ completion outcome).
207
+
208
+ ### Security
209
+
210
+ - **Default CLI permission posture is permissive.** Documented
211
+ prominently in README under "Recommended one-time setup". The
212
+ flip is correct for personal workstations and controlled service
213
+ accounts whose prompts are authored by the operator, but the
214
+ CLI is unsafe to wire up to untrusted prompt input (public
215
+ chatbots, prompt-injection-prone RAG, …) without
216
+ `--allowed-tools`, `OCP_NO_SKIP_PERMS=1`, or per-call validation
217
+ on top.
218
+ - **`printStalledOutput` redacts prompt back-echo** when emitted.
219
+ When the captured PTY tail is included (now opt-in via
220
+ `OCP_DUMP_STALL=1` or `--debug`), lines that overlap the caller's
221
+ prompt by ≥24 characters are replaced with
222
+ `[prompt echo redacted]` so RAG context glued into the prompt
223
+ does not leak into error logs.
224
+
225
+ ---
226
+
227
+ ## [1.0.0] — 2026-XX-XX
228
+
229
+ Initial release.
230
+
231
+ ### Added
232
+
233
+ - `ocp` CLI binary — argv-compatible shim for `claude -p`. `-p` /
234
+ `--print` are implicit; `ocp "…"` is equivalent to
235
+ `claude -p "…"`.
236
+ - Output adapters: `text` (default), `json`, `stream-json` (NDJSON).
237
+ - Driver (`createDriver`, `runOneShot`) — node-pty-backed PTY layer
238
+ that drives the interactive `claude` CLI and parses the output
239
+ stream to produce headless-mode-equivalent results.
240
+ - Chat SDK (`createChatClient`) — high-level wrapper with
241
+ per-conversation state, file-backed transcript store, skill
242
+ invocation, and JSONL session-file extraction.
243
+ - Warm daemon under `~/.ocp/d-<hash>.sock` so subsequent calls in
244
+ the same cwd skip the 2.5 s PTY warmup. Idle timeout via
245
+ `OCP_DAEMON_IDLE_MS` (default 10 min).
246
+ - Hard timeout via `OCP_MAX_RESPONSE_MS` (default 24 h).
247
+ - First-response watchdog `OCP_FIRST_RESPONSE_MS` (default 20 s)
248
+ for fast `interactive-required` failure when an unrecognised
249
+ dialog blocks the prompt box.
250
+ - Folder-trust auto-accept opt-in via `OCP_AUTO_ACCEPT_TRUST=1`.
251
+ - Permission-bypass opt-in via `OCP_DEFAULT_SKIP_PERMS=1`.
252
+ - Default `--allowed-tools` pre-approval for `WebSearch` and
253
+ `WebFetch` (opt out: `OCP_NO_DEFAULT_TOOLS=1`).
254
+ - Default `--append-system-prompt` encouraging tool use (opt out:
255
+ `OCP_NO_DEFAULT_PROMPT=1`).
256
+ - Localised READMEs: Korean, Japanese, Chinese.
257
+
258
+ [1.1.1]: https://github.com/empty-user77/open-claude-p/releases/tag/v1.1.1
259
+ [1.1.0]: https://github.com/empty-user77/open-claude-p/releases/tag/v1.1.0
260
+ [1.0.0]: https://github.com/empty-user77/open-claude-p/releases/tag/v1.0.0
package/README.ja.md CHANGED
@@ -14,11 +14,15 @@
14
14
 
15
15
  > **核心的な違い**:`claude -p` は Claude Code の非対話モードで内部 API を通じて動作しますが、特定のプラン/環境では使用できません。`open-claude-p` は実際の TUI クライアントを PTY で実行し、出力ストリームを解析することで同じ結果を得ます。
16
16
 
17
+ **バージョン履歴**: [CHANGELOG.md](./CHANGELOG.md) を参照。
18
+
17
19
  ---
18
20
 
19
21
  ## 目次
20
22
 
21
23
  - [インストール](#インストール)
24
+ - [推奨ワンタイム設定](#推奨ワンタイム設定)
25
+ - [`claude -p` との既知の差分](#claude--p-との既知の差分)
22
26
  - [CLI の使い方](#cli-の使い方)
23
27
  - [デーモン(セッション持続)](#デーモンセッション持続)
24
28
  - [ライブラリ API](#ライブラリ-api)
@@ -68,6 +72,88 @@ claude --version
68
72
 
69
73
  ---
70
74
 
75
+ ## 推奨ワンタイム設定
76
+
77
+ **1.1+ では不要です。** CLI のデフォルトは既に permissive:
78
+ フォルダ信頼ダイアログの自動承認 ON、`--dangerously-skip-permissions` ON。
79
+ `npm install -g open-claude-p` の後、そのまま `ocp "..."` が動きます。
80
+
81
+ claude の通常のパーミッションプロンプトを戻したい場合(PTY 自動化では
82
+ 答えられないので全てのツール呼び出しが hang します)、opt-out 環境変数で
83
+ 無効化:
84
+
85
+ ```bash
86
+ export OCP_NO_AUTO_ACCEPT_TRUST=1 # "Do you trust this folder?" ダイアログで abort
87
+ export OCP_NO_SKIP_PERMS=1 # claude の通常パーミッションプロンプトを復元
88
+ ```
89
+
90
+ > ⚠️ デフォルト CLI 設定では、`ocp "…"` 呼び出し 1 回でプロンプトの内容に
91
+ > 従って Bash、Write、Edit などのツールを確認なしで実行できます。個人の
92
+ > ワークステーションや、運用者がプロンプトを直接書く管理されたサービス
93
+ > アカウントには適切ですが、**信頼できない入力**(公開チャットボット、
94
+ > プロンプトインジェクションを受けやすい RAG など)がプロンプトに混ざる
95
+ > 環境では絶対にそのまま使わないでください。`--allowed-tools`、
96
+ > `OCP_NO_SKIP_PERMS=1`、または呼び出しごとの検証で表面を絞ってください。
97
+ >
98
+ > ライブラリのデフォルト(`createDriver` / `createChatClient`)は引き続き
99
+ > 保守的 — ライブラリ呼び出し元が明示的に権限スキップを opt-in します。
100
+
101
+ 全環境変数一覧は [docs/cli-reference.md](./docs/cli-reference.md) 参照。
102
+
103
+ ---
104
+
105
+ ## `claude -p` との既知の差分
106
+
107
+ `ocp` は argv 互換の shim であり、`claude -p` とバイト単位で同一の出力を
108
+ 保証するわけではありません。同じフラグでも以下のケースでは動作が異なるため、
109
+ コンシューマパイプラインに統合する際は事前に考慮してください:
110
+
111
+ - **`~/.claude.json` の状態に敏感.** PTY レイヤーは spawn ごとに完全な
112
+ TUI バナーを描画するため、"1 MCP server needs auth · /mcp" や
113
+ "auto mode unavailable"、プラグイン更新通知なども表示されます。
114
+ `claude -p` はこういうのは描画しませんが、`ocp` は通り抜けるだけです
115
+ (`⏺` か spinner イベントが見えるまで待機)。通知が多いと
116
+ first-response latency が `OCP_FIRST_RESPONSE_MS`(デフォルト 20s)を
117
+ 超えて spurious な `interactive-required` abort が出ることがあります。
118
+ env を増やすか、使わない MCP/プラグインを `~/.claude.json` から
119
+ 削除してください。
120
+
121
+ - **1KB 超のプロンプトは chunked write 経路.** 単一の多 KB write は claude
122
+ の paste 検出を起動し、末尾の CR が paste content として消費されて
123
+ プロンプトが永遠に送信されない回帰がありました。1.1+ では約 256 文字
124
+ 単位で短い delay 付き chunked write — 50–500 ms の追加 latency。
125
+ 以前の動作が必要なら `OCP_PASTE_MODE=raw`、TUI 入力ボックス自体を回避
126
+ したいなら `--input-format=stream-json`。
127
+
128
+ - **セッション永続化はデフォルト ON.** 各ターンで `~/.claude/projects/<encoded-cwd>/`
129
+ に JSONL セッションファイルを書きます。サーバ側で毎ターン会話履歴を
130
+ 再構築するステートレス統合では `OCP_NO_SESSION_PERSISTENCE=1`
131
+ (または `--no-session-persistence`)で無効化してください。無効化しないと
132
+ dead JSONL が溜まり `--continue` の探索が無関係な隣接ファイルを掴むことが
133
+ あります。
134
+
135
+ - **デーモンは呼び出し元終了後も残る.** `~/.ocp/d-<hash>.sock` でデーモンが
136
+ detach され、同じ cwd の次回呼び出しが 2.5s warmup をスキップ。
137
+ `OCP_DAEMON_IDLE_MS`(デフォルト 10 分)で idle 時に自動終了。
138
+ 「子プロセスは親と一緒に死ぬべき」と期待するコンシューマアプリは
139
+ `OCP_NO_DAEMON=1` か idle タイムアウトを短くしてください。
140
+
141
+ - **Print mode(`--print-mode` / `OCP_PRINT_MODE=1`)のみ PTY を完全に
142
+ バイパス** し、実質 `claude --print` + argv pass-through。MCP サーバ、
143
+ ツール権限プロンプト、その他あらゆるインタラクティブ surface は使えません
144
+ — fallback や upstream parity テスト用途のみ。
145
+
146
+ - **Abort 時、出力アダプタは PTY ノイズを通さない.** completionReason が
147
+ `timeout` / `interactive-required` / `trust-required` / `cancelled` /
148
+ `write-failed` / `upstream-exited` のいずれかなら、`text`・`stream-json`
149
+ アダプタは累積された PTY コンテンツをモデル応答として emit しません。
150
+ `stream-json` は `result.subtype=error` + `completion=<reason>` のみを
151
+ emit、短い stderr エラーメッセージに `detected: <kind>` のヒントを出力。
152
+ `claude -p` は黙って失敗するか手元のテキストを echo していた部分とは
153
+ 異なります。
154
+
155
+ ---
156
+
71
157
  ## CLI の使い方
72
158
 
73
159
  このパッケージは単一バイナリ **`ocp`** をインストールします。
@@ -493,7 +579,26 @@ const nextPrompt = `前の回答:${result.text}\n\n次のステップに進ん
493
579
 
494
580
  ## 環境変数
495
581
 
496
- ### ドライバーオプション
582
+ ### よく使うもの
583
+
584
+ | 変数 | 説明 |
585
+ |------|------|
586
+ | `OCP_NO_AUTO_ACCEPT_TRUST=1` | 1.1 デフォルト(フォルダ信頼の自動承認)を無効化。ダイアログが出たら abort させたいとき。 |
587
+ | `OCP_NO_SKIP_PERMS=1` | 1.1 CLI デフォルト(`--dangerously-skip-permissions`)を無効化。claude の通常の権限プロンプトが復活しますが、PTY 自動化では答えられず全ツール呼び出しが hang します。 |
588
+ | `OCP_NO_SESSION_PERSISTENCE=1` | ターンごとの JSONL セッションファイル書き込みを無効化。毎ターンサーバ側で履歴を再構築するステートレス統合用。 |
589
+ | `OCP_NO_LIVE=1` | stderr のライブスピナーを無効化 |
590
+ | `OCP_NO_META=1` | 末尾の meta フッター(`⏱ … · 🔧 …`)を非表示 |
591
+ | `OCP_NO_DAEMON=1` | 毎回新しい PTY(warm デーモンを使わない) |
592
+ | `OCP_DAEMON_IDLE_MS` | warm デーモンが呼び出しの間に生き残る時間。デフォルト `600000`(10 分)。 |
593
+ | `OCP_MAX_RESPONSE_MS` | ハードタイムアウト、デフォルト `86400000`(24 時間) |
594
+ | `OCP_FIRST_RESPONSE_MS` | プロンプト送信後 N ms 以内に進展がなければ fail-fast、デフォルト `20000` |
595
+ | `OCP_PROMPT_BOX_WAIT_MS` | 入力 chevron(`❯`) の出現を待つ最大時間、デフォルト `15000`(heavy hook/MCP ロード時は増やす) |
596
+ | `OCP_PASTE_MODE` | 大きいプロンプトを TUI に送る方法:`auto`(デフォルト、しきい値超で chunked)、`chunk`(常に chunk)、`bracket`(xterm bracketed paste マーカー)、`raw`(1.1 以前の atomic write) |
597
+ | `OCP_PASTE_THRESHOLD` | `auto` モードでの chunked write 発動バイト数しきい値。デフォルト `1024` |
598
+ | `OCP_DUMP_STALL=1` | abort stderr メッセージに PTY 画面 tail を含める。デフォルトでは含めません(呼び出し側プロンプトが echo される可能性のため opt-in)。 |
599
+ | `OCP_CLAUDE_BIN` | upstream `claude` バイナリのパス、デフォルト `'claude'` |
600
+
601
+ ### ドライバーオプション(ライブラリ呼び出し元向け)
497
602
 
498
603
  | 変数 | 対応オプション | デフォルト |
499
604
  |------|-------------|-----------|
@@ -502,7 +607,6 @@ const nextPrompt = `前の回答:${result.text}\n\n次のステップに進ん
502
607
  | `OCP_REUSE_WARMUP_MS` | `reuseWarmupMs` | `200` |
503
608
  | `OCP_IDLE_MS` | `idleMs` | `1500` |
504
609
  | `OCP_PRE_IDLE_MS` | `preIdleMs` | `8000` |
505
- | `OCP_MAX_RESPONSE_MS` | `maxResponseMs` | `60000` |
506
610
  | `OCP_POOL_SIZE` | `poolSize` | `0` |
507
611
  | `OCP_POOL_MAX_AGE_MS` | `poolMaxAgeMs` | `600000` |
508
612
 
@@ -560,114 +664,80 @@ OCP_NO_DAEMON=1 ocp "一度だけ実行"
560
664
 
561
665
  ## サンプルアプリ
562
666
 
563
- `sample/` ディレクトリには ocp を使って構築した Web ベースのチャット UI が含まれています。
667
+ `open-claude-p/chat` を使った小さな Web チャット UI です。ソースは
668
+ upstream の git repo の `sample/` 配下にあり、**npm tarball には
669
+ バンドルされません** — 代わりにパッケージが `ocp-sample` というコンパニオン
670
+ CLI を一緒に配布し、必要なときにオンデマンドでダウンロードします。これにより
671
+ publish された install を軽量に保ちつつ、デモは 1 行で試せます。
564
672
 
565
- ### 実行
673
+ ### クイックスタート
566
674
 
567
675
  ```bash
568
- cd sample
569
- node server.js
570
- # → http://localhost:3000
571
- ```
572
-
573
- ### サンプルアプリの構造
676
+ npm install -g open-claude-p # 1 回だけ
677
+ ocp-sample init demo # ダウンロード + npm install
678
+ cd demo
679
+ ocp-sample start # → http://localhost:3000
574
680
 
575
- ```
576
- sample/
577
- server.js Express サーバー — ocp ドライバーをラップ、SSE ストリーミング
578
- data/
579
- conversations.json 会話履歴(自動生成)
580
- public/
581
- index.html チャット UI
582
- app.js クライアントサイド JavaScript
583
- style.css スタイルシート
681
+ # 終わったら:
682
+ ocp-sample stop
584
683
  ```
585
684
 
586
- ### サンプルサーバー API
685
+ ### `init` の動作
587
686
 
588
- | エンドポイント | メソッド | 説明 |
589
- |------------|--------|------|
590
- | `/api/conversations` | GET | 会話一覧 |
591
- | `/api/conversations/:id` | GET | 会話詳細(全メッセージ) |
592
- | `/api/conversations/:id` | DELETE | 会話を削除 |
593
- | `/api/chat` | POST | メッセージ送信(SSE ストリーミング) |
594
- | `/api/monitor` | GET | PTY イベントモニター(SSE) |
595
- | `/api/skills` | GET | `~/.claude/skills/` のスキル一覧 |
596
- | `/api/processes` | GET | 進行中のリクエスト一覧(`id`、`prompt`、`elapsedMs`) |
597
- | `/api/processes/:id` | DELETE | 特定のリクエストを中断(`all` で全て中断) |
687
+ 1. upstream repo を一時ディレクトリに shallow-clone。
688
+ 2. `sample/` サブツリーを `./<name>/`(デフォルト `./ocp-sample/`)にコピー。
689
+ 3. コピーされた `package.json` dev `"open-claude-p": "file:.."` dep
690
+ を実際の semver 範囲に書き換え この CLI 自身のバージョンに pin する
691
+ ので `ocp-sample` scaffold したデモは常に同梱バージョンと一致します。
692
+ 4. `npm install --no-audit --no-fund` を実行。
693
+ 5. `npm link open-claude-p` を試行 グローバル link が無ければ silent
694
+ no-op、ある場合は registry のコピー代わりにローカル dev ソースを link
695
+ で使います。
598
696
 
599
- ### `/api/chat` SSE イベント
697
+ ### サブコマンド
600
698
 
601
- チャットリクエスト(`POST /api/chat`)は Server-Sent Events でレスポンスをストリーミングします:
699
+ | コマンド | 説明 |
700
+ |----------|------|
701
+ | `ocp-sample init [name]` | `./<name>/`(デフォルト `ocp-sample`)にデモをダウンロード + install。ディレクトリが存在して空でない場合は拒否。 |
702
+ | `ocp-sample start [--port=N]` | CWD から `node server.js` を detached で起動。PID を `.ocp-sample.pid` に、stdout/stderr を `.ocp-sample.log` に append。`PORT` env でも指定可。 |
703
+ | `ocp-sample stop` | 実行中の PID に SIGTERM(5 秒猶予の後 SIGKILL)。 |
704
+ | `ocp-sample status` | `running` / `stopped` + PID + URL を出力。 |
602
705
 
603
- ```js
604
- // クライアントリクエスト
605
- const resp = await fetch('/api/chat', {
606
- method: 'POST',
607
- headers: { 'Content-Type': 'application/json' },
608
- body: JSON.stringify({
609
- message: '東京の天気を教えて',
610
- conversationId: null, // null で新しい会話を開始
611
- skillName: 'my-skill', // オプション:~/.claude/skills/ のスキル名
612
- }),
613
- });
706
+ ### cwd に作られるファイル
614
707
 
615
- // SSE イベントの種類
616
- { type: 'spinner', label: 'Searching the web...' } // 処理中の状態
617
- { type: 'text', text: 'こんにちは...' } // ストリーミングテキスト(チャンク)
618
- { type: 'error', error: 'エラーメッセージ' } // エラー
619
- {
620
- type: 'done',
621
- conversationId: 'uuid', // 会話 ID(保存済み)
622
- text: '完全な最終レスポンス', // 完全な最終テキスト(JSONL からのクリーンな markdown)
623
- isNew: true, // 新しい会話かどうか
624
- meta: {
625
- elapsedMs: 4200, // 経過時間(ms)
626
- inputTokens: 1500, // 入力トークン(キャッシュ含む)
627
- outputTokens: 320, // 出力トークン
628
- costUsd: 0.0042, // コスト(USD)
629
- tools: ['WebSearch'], // 使用したツール
630
- }
631
- }
708
+ ```
709
+ demo/
710
+ ├── .ocp-sample.pid 実行中サーバの PID(start が書き込み、stop が削除)
711
+ ├── .ocp-sample.log detach されたサーバの stdout/stderr(append)
712
+ ├── server.js Express + ocp/chat
713
+ ├── package.json
714
+ ├── public/ 静的チャット UI(index.html, app.js, style.css)
715
+ └── node_modules/ `npm install` の結果
632
716
  ```
633
717
 
634
- ### サンプルの Markdown パース
635
-
636
- サンプルアプリ(`sample/public/app.js`)は `renderMarkdown()` 関数を通じて `result.text` を HTML に変換します。
637
-
638
- **このパースコードはサンプル専用です。** 実際のプロジェクトでは:
639
- - Web:`marked`、`markdown-it` など
640
- - ターミナル:`cli-markdown`、`terminal-link` など
641
- - React:`react-markdown`
642
- - LLM 入力:そのまま使用
643
-
644
- ### プロセスマネージャー(`ocp-ps`)
645
-
646
- サンプルアプリには `/api/processes` API を使って進行中のリクエストを一覧表示・キャンセルできる CLI ツールが含まれています。
647
-
648
- ```bash
649
- cd sample
718
+ ### 環境変数
650
719
 
651
- node ocp-ps.js # 進行中のリクエスト一覧
652
- node ocp-ps.js kill <id> # 特定のリクエストを中断
653
- node ocp-ps.js kill all # 全て中断
654
- node ocp-ps.js watch # 1 秒ごとに自動更新
655
- ```
720
+ | 変数 | 効果 |
721
+ |------|------|
722
+ | `PORT` | `start` のデフォルトポート(3000)を変更。`--port=N` と同じ。 |
723
+ | `NO_COLOR=1` | ANSI 色とスピナーを無効化 — CI やログ取得に有用。 |
724
+ | `OCP_SAMPLE_NO_TTY=1` | `NO_COLOR=1` と同じ。 |
725
+ | `OCP_SAMPLE_REPO` | `init` が clone する upstream git URL を変更。テスト用。 |
656
726
 
657
- > **注意**:`ocp-ps` はサンプルアプリの HTTP API(`/api/processes`)を使うサンプル実装です。
658
- > ocp ライブラリを使って独自のサーバーを構築する際は、同じパターンでプロセス管理 API を実装できます。
727
+ ### デモが見せる機能
659
728
 
660
- ### スキル呼び出し(`/スキル名`)
729
+ デモは意図的に小さく作られていますが、ほとんどのコンシューマアプリが必要と
730
+ する SDK の部分を実際に通過させています:
661
731
 
662
- チャット入力欄で `/` を入力すると `~/.claude/skills/` のスキルがドロップダウンで表示されます。
732
+ - **会話の永続化** `chat.send` + `~/.claude/projects/<cwd>/<sid>.jsonl`
733
+ - **SSE ストリーミング** — `assistant-text` / `spinner` / `done` をブラウザへ
734
+ - **スキル呼び出し** — `/<skill-name>` を打つと `~/.claude/skills/` の `SKILL.md` を注入
735
+ - **プロセス管理** — 進行中のリクエスト一覧・abort を `/api/processes` 経由で
736
+ - **Markdown レンダリング** — チャットバブルで fenced code、見出し、リストなどを処理する小さいクライアントサイドレンダラ
663
737
 
664
- ```
665
- ユーザー入力:/my-skill この PRD を分析して関連リポジトリを見つけて
666
-
667
- サーバー:SKILL.md の内容を appendSystemPrompt として注入
668
-
669
- Claude:スキルの指示に従って実行
670
- ```
738
+ `init` 後の `demo/server.js` を見ると全 surface があります — 「Express
739
+ アプリに `open-claude-p/chat` をラップする方法」 の正式な参考実装として
740
+ 扱ってください。
671
741
 
672
742
  ---
673
743