open-claude-p 1.0.0 → 1.1.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/CHANGELOG.md ADDED
@@ -0,0 +1,187 @@
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.0] — 2026-05-18
11
+
12
+ `ocp` 1.1 reshapes the CLI defaults around the assumption that
13
+ **callers are programs, not humans**, and adds a JSONL-first
14
+ extraction path so PTY chrome can no longer leak into responses.
15
+
16
+ ### Added
17
+
18
+ - **JSONL-first response extraction.** `claude` writes the completed
19
+ assistant turn to `~/.claude/projects/<cwd>/<sid>.jsonl`. The driver
20
+ now reads that authoritative source first and falls back to
21
+ PTY-extracted text only when the JSONL is unavailable
22
+ (`--no-session-persistence`, missing file, etc.). Cleans up
23
+ statusline / HUD plugin / `[Pasted text #N]` leakage at the source.
24
+ Result: `diagnostics.textSource` is `"jsonl"` or `"pty"`,
25
+ `diagnostics.recoveredFromJsonl` is `true` when a PTY-side abort
26
+ was overridden by a successful JSONL read.
27
+ - **Paste-mode handling for large prompts.** New driver option
28
+ `pasteMode` (`auto` | `chunk` | `bracket` | `raw`) with env
29
+ `OCP_PASTE_MODE`. Prompts above `OCP_PASTE_THRESHOLD` bytes
30
+ (default 1024) are written in ~256-char chunks with brief delays
31
+ so the upstream TUI's paste detector does not coalesce them into
32
+ a `[Pasted text]` placeholder that swallows the trailing
33
+ carriage-return. New exported helper `writePromptToSession`.
34
+ - **Stall-cause detector.** New `src/diagnostics/stall-cause.js`
35
+ scans the captured PTY tail at abort time and returns a stable
36
+ machine-readable identifier (`mcp-auth-required`,
37
+ `trust-required`, `theme-picker`, `login-expired`,
38
+ `tool-permission`, `paste-not-submitted`) plus an actionable
39
+ English hint, surfaced as `detected: <kind>` on stderr.
40
+ - **`TUI_CHROME_PATTERNS` / `TUI_CHROME_INLINE_PATTERNS`** exported
41
+ from `open-claude-p/chat`. Line-anchored vs inline-fragment
42
+ pattern lists used by `cleanResponse`. External callers building
43
+ alternative scrubbers can reuse the list.
44
+ - **`OCP_NO_SESSION_PERSISTENCE` env binding** on the CLI. Previously
45
+ only the flag `--no-session-persistence` was honoured.
46
+ - **`OCP_DUMP_STALL=1` opt-in** for the PTY screen tail in abort
47
+ errors. The default suppresses the tail because it can echo the
48
+ caller's prompt (a real concern for RAG-injected prompts containing
49
+ user data).
50
+ - **`OCP_NO_AUTO_ACCEPT_TRUST=1` opt-out** for folder-trust
51
+ auto-accept.
52
+ - **`OCP_NO_SKIP_PERMS=1` opt-out** for the new default
53
+ `--dangerously-skip-permissions`.
54
+ - **CHANGELOG.md** (this file).
55
+ - **`ocp-sample` companion CLI.** Downloads the demo chat-UI app
56
+ (the `sample/` subtree) from the upstream git repo on demand so
57
+ the published tarball stays small. Subcommands `init` (clone +
58
+ npm install into a user-chosen directory), `start` (detached server
59
+ with PID/log file), `stop`, `status`. Pretty TTY output (braille
60
+ spinner, success/failure marks, end-of-init banner with the running
61
+ URL); auto-falls-back to plain text when `NO_COLOR=1` or stderr
62
+ isn't a TTY. Designed for npx-first use:
63
+ `npx -p open-claude-p ocp-sample init demo`.
64
+
65
+ ### Changed
66
+
67
+ - **`--dangerously-skip-permissions` is now the CLI default.**
68
+ Rationale: `ocp` is a non-interactive PTY automation surface. A
69
+ permission prompt that wants a human y/n hangs forever — every
70
+ Bash / Edit / Write / MCP call breaks without this flag. Library
71
+ callers (`createDriver` / `createChatClient`) keep the
72
+ conservative `false` default; only the `ocp` binary flips.
73
+ Pre-1.1 users with `OCP_DEFAULT_SKIP_PERMS=1` exported see no
74
+ change; the env is now a no-op.
75
+ - **Folder-trust dialog is auto-accepted by default.** Same
76
+ rationale: a `claude` dialog asking "Do you trust this folder?"
77
+ is unanswerable from PTY automation. Opt out via
78
+ `OCP_NO_AUTO_ACCEPT_TRUST=1`.
79
+ - **Abort completions no longer leak PTY noise.**
80
+ When `completionReason` is in
81
+ `{timeout, interactive-required, trust-required, cancelled, write-failed, upstream-exited}`:
82
+ - The `text` adapter writes nothing to stdout (was: accumulated
83
+ PTY junk).
84
+ - The `stream-json` adapter emits only `system/init` +
85
+ `result.subtype=error` (was: also an `assistant` frame with the
86
+ PTY-extracted blob).
87
+ - The `printStalledOutput` PTY tail is omitted by default
88
+ (was: emitted to stderr including the caller's prompt back-echo).
89
+ - **`cleanResponse` scrubs HUD chrome.** Additional patterns added
90
+ for claude-hud counters, MCP-auth banners, paste placeholders,
91
+ and `Context ░░░░ N%` meters. Inline fragments are removed
92
+ without dropping the surrounding line.
93
+ - **Permissive CLI defaults note in README** — `Recommended one-time
94
+ setup` reduced to "None required". The post-1.0 opt-in envs
95
+ (`OCP_AUTO_ACCEPT_TRUST=1`, `OCP_DEFAULT_SKIP_PERMS=1`) are now
96
+ effectively no-ops; users keep them in `~/.zshrc` without effect,
97
+ or remove them.
98
+
99
+ ### Fixed
100
+
101
+ - **macOS realpath in `~/.claude/projects/<encoded-cwd>/` lookup.**
102
+ Earlier versions used `path.resolve(cwd)` which is a string
103
+ operation that does not follow symlinks. On macOS `/var`, `/tmp`,
104
+ and other launchd-owned paths redirect to `/private/<…>`; `claude`
105
+ itself resolves symlinks when picking its JSONL directory, so the
106
+ driver was looking up a directory the upstream never wrote to.
107
+ Net effect: any session under a `/var/` or `/tmp/` cwd had its
108
+ session id capture fail silently, so `claudeSessionId` stayed
109
+ `null`, `--resume` was never threaded between turns, and every
110
+ call spawned a fresh conversation with no memory of the previous
111
+ one. Fixed via `realpath` in `src/index.js` (driver),
112
+ `src/chat/index.js` (`readSessionText`), and `src/print-mode.js`.
113
+ - **Stale daemon socket on launch.** A SIGKILL'd daemon left
114
+ `~/.ocp/d-*.sock` behind; the next launch's `server.listen` failed
115
+ with `EADDRINUSE` and the client gave up and fell back to direct
116
+ mode. The daemon now pre-unlinks the path before binding.
117
+ - **`readSessionText` strict-mode fallback.** When the caller passes
118
+ a `sessionId`, the function no longer scans neighbouring JSONLs in
119
+ the project dir on miss. Under concurrent load (another claude
120
+ session active in the same cwd, an editor's built-in agent, …)
121
+ the scan picked the most-recently-modified file and returned
122
+ someone else's transcript as the "model's response". Strict mode
123
+ returns `null` on miss instead.
124
+ - **GUI-app install of `ocp`.** The postinstall script rewrites the
125
+ shebang in `bin/cli.js` from `#!/usr/bin/env node` to the absolute
126
+ path of the node binary that ran the install (`process.execPath`).
127
+ Without this, launching `ocp` from a launchd-managed GUI process
128
+ (Electron, Tauri, native Cocoa) — which gets `/usr/bin:/bin` as
129
+ PATH and never sees nvm / homebrew node — fails with
130
+ `env: node: No such file or directory` before our code runs.
131
+ - **`stream-json` adapter** now opens with `system/init` even when
132
+ no session id was captured (regression-proofs consumer parsers
133
+ expecting the init line as the first event regardless of
134
+ completion outcome).
135
+
136
+ ### Security
137
+
138
+ - **Default CLI permission posture is permissive.** Documented
139
+ prominently in README under "Recommended one-time setup". The
140
+ flip is correct for personal workstations and controlled service
141
+ accounts whose prompts are authored by the operator, but the
142
+ CLI is unsafe to wire up to untrusted prompt input (public
143
+ chatbots, prompt-injection-prone RAG, …) without
144
+ `--allowed-tools`, `OCP_NO_SKIP_PERMS=1`, or per-call validation
145
+ on top.
146
+ - **`printStalledOutput` redacts prompt back-echo** when emitted.
147
+ When the captured PTY tail is included (now opt-in via
148
+ `OCP_DUMP_STALL=1` or `--debug`), lines that overlap the caller's
149
+ prompt by ≥24 characters are replaced with
150
+ `[prompt echo redacted]` so RAG context glued into the prompt
151
+ does not leak into error logs.
152
+
153
+ ---
154
+
155
+ ## [1.0.0] — 2026-XX-XX
156
+
157
+ Initial release.
158
+
159
+ ### Added
160
+
161
+ - `ocp` CLI binary — argv-compatible shim for `claude -p`. `-p` /
162
+ `--print` are implicit; `ocp "…"` is equivalent to
163
+ `claude -p "…"`.
164
+ - Output adapters: `text` (default), `json`, `stream-json` (NDJSON).
165
+ - Driver (`createDriver`, `runOneShot`) — node-pty-backed PTY layer
166
+ that drives the interactive `claude` CLI and parses the output
167
+ stream to produce headless-mode-equivalent results.
168
+ - Chat SDK (`createChatClient`) — high-level wrapper with
169
+ per-conversation state, file-backed transcript store, skill
170
+ invocation, and JSONL session-file extraction.
171
+ - Warm daemon under `~/.ocp/d-<hash>.sock` so subsequent calls in
172
+ the same cwd skip the 2.5 s PTY warmup. Idle timeout via
173
+ `OCP_DAEMON_IDLE_MS` (default 10 min).
174
+ - Hard timeout via `OCP_MAX_RESPONSE_MS` (default 24 h).
175
+ - First-response watchdog `OCP_FIRST_RESPONSE_MS` (default 20 s)
176
+ for fast `interactive-required` failure when an unrecognised
177
+ dialog blocks the prompt box.
178
+ - Folder-trust auto-accept opt-in via `OCP_AUTO_ACCEPT_TRUST=1`.
179
+ - Permission-bypass opt-in via `OCP_DEFAULT_SKIP_PERMS=1`.
180
+ - Default `--allowed-tools` pre-approval for `WebSearch` and
181
+ `WebFetch` (opt out: `OCP_NO_DEFAULT_TOOLS=1`).
182
+ - Default `--append-system-prompt` encouraging tool use (opt out:
183
+ `OCP_NO_DEFAULT_PROMPT=1`).
184
+ - Localised READMEs: Korean, Japanese, Chinese.
185
+
186
+ [1.1.0]: https://github.com/empty-user77/open-claude-p/releases/tag/v1.1.0
187
+ [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