@cocorograph/hub-agent 0.8.24 → 0.8.25

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 CHANGED
@@ -62,9 +62,7 @@ hub-agent stop # 停止方法のヒント表示
62
62
  hub-agent install-service [--bin PATH]
63
63
  hub-agent uninstall-service
64
64
  hub-agent plugins list # ~/.hub/plugins/ から読み込み済プラグイン
65
- hub-agent plugins examples # repo 同梱の install 可能 example
66
- hub-agent plugins install <name> [--force]
67
- hub-agent plugins uninstall <name>
65
+ hub-agent plugins uninstall <name> # ~/.hub/plugins/<prio>-<name>/ を削除
68
66
  ```
69
67
 
70
68
  ## 設定ファイル
@@ -86,7 +84,8 @@ hub-agent/
86
84
  │ ├── config.mjs # ~/.hub/agent.json 管理
87
85
  │ ├── enroll.mjs # enrollment フロー
88
86
  │ ├── ws-client.mjs # outbound WSS + reconnect with jitter
89
- │ ├── pty-bridge.mjs # @lydell/node-pty 多重化 (fd leak 回避フォーク)
87
+ │ ├── claude-stream-bridge.mjs # Claude Agent SDK チャット中継
88
+ │ ├── codex-stream-bridge.mjs # Codex app-server チャット中継
90
89
  │ ├── tmux.mjs # tmux exec/list/create/kill
91
90
  │ ├── state.mjs # session status / context_pct 検知
92
91
  │ ├── skills.mjs # ~/.claude/skills 集計
@@ -98,7 +97,8 @@ hub-agent/
98
97
  │ ├── co.cocorograph.hub-agent.plist
99
98
  │ └── hub-agent.service
100
99
  ├── scripts/
101
- │ └── fix-node-pty-perms.mjs # @lydell/node-pty spawn-helper +x 修復 (postinstall)
100
+ │ ├── install.sh # ワンライナーセットアップ (macOS / Linux / WSL)
101
+ │ └── install.ps1 # Windows (WSL2 導入 + Task Scheduler 登録)
102
102
  └── test/
103
103
  ```
104
104
 
@@ -107,21 +107,22 @@ hub-agent/
107
107
  - [x] Sprint A: 仕様書 (Hub knowledge id=6080)
108
108
  - [x] Sprint B: Hub 側 enrollment API + WS endpoint 雛形
109
109
  - [x] Sprint C: 本リポジトリの雛形 + outbound WSS + hook system
110
- - [x] Sprint D: pty bridge
111
110
  - [x] Sprint E: tmux exec/list/create/kill 移植 + auto list UI
112
111
  - [x] Sprint F: Hub Browser↔Agent multiplex 中継
113
112
  - [x] Sprint G: Hub frontend /user/cockpit/{agents,terminal} ページ
114
113
  - [x] Sprint H: skills / state dot / usage badge リレー
115
114
  - [x] Sprint I: 接続復旧 (jitter + force reconnect + Celery stale 検知)
116
115
  - [x] Sprint J: 本リポジトリ publish 準備 + launchd/systemd 連携
117
- - [x] Sprint K: remote-ops プラグイン例 (`plugins/10-tailscale-remote/`)
118
116
 
119
- ## 同梱プラグイン
117
+ ## プラグイン
120
118
 
121
- - [`plugins/10-tailscale-remote`](./plugins/10-tailscale-remote/README.md) — 自宅
122
- Mac (hub-agent host) を会社 Mac (`remote_host`) の tmux に対する透過プロキシ化。
123
- `hub-agent plugins install 10-tailscale-remote` で `~/.hub/plugins/` にコピー、
124
- `config.json` を編集して restart で有効化
119
+ プラグインは利用者が `~/.hub/plugins/<prio>-<name>/plugin.mjs` を自分で置く運用です。
120
+ 置けば `plugins list` から読み込まれ、`plugins uninstall <prio>-<name>` で削除できます。
121
+
122
+ リポジトリ同梱の example プラグインはありません。唯一同梱していた
123
+ `plugins/10-tailscale-remote/` は pty spawn を横取りするプラグインで、pty 中継の撤去と
124
+ 同時に削除しました。同梱 example が 0 件になったため、それを配る `plugins examples` /
125
+ `plugins install` と `package.json` の `files` の `plugins/` も外しています。
125
126
 
126
127
  ## ライセンス
127
128
 
package/bin/hub-agent.mjs CHANGED
@@ -34,12 +34,8 @@ if (!process.env.LC_ALL) process.env.LC_ALL = "C.UTF-8"
34
34
  import { hasConfig, readConfig } from "../src/config.mjs"
35
35
  import { enroll } from "../src/enroll.mjs"
36
36
  import { resolveSyncTargets, syncBundleTargets } from "../src/hub-bundle.mjs"
37
- import {
38
- installPlugin,
39
- listInstallableExamples,
40
- uninstallPlugin,
41
- } from "../src/plugin-install.mjs"
42
37
  import { loadPlugins } from "../src/plugin-loader.mjs"
38
+ import { uninstallPlugin } from "../src/plugin-uninstall.mjs"
43
39
  import {
44
40
  installService,
45
41
  restartService,
@@ -264,6 +260,11 @@ program
264
260
  }
265
261
  })
266
262
 
263
+ // プラグインは利用者が `~/.hub/plugins/<prio>-<name>/` へ自分で配置する運用なので、
264
+ // CLI が提供するのは利用者配置分の管理 (list / uninstall) だけ。リポ同梱 example を配る
265
+ // `examples` / `install` は、唯一の example (`plugins/10-tailscale-remote/`) が pty spawn を
266
+ // 横取りするプラグインで pty 撤去と同時に削除され、同梱 example が 0 件になったため撤去した
267
+ // (あわせて package.json の files から `plugins/` を外している)。
267
268
  const plugins = program.command("plugins").description("プラグイン管理")
268
269
  plugins
269
270
  .command("list")
@@ -279,40 +280,9 @@ plugins
279
280
  }
280
281
  })
281
282
 
282
- plugins
283
- .command("examples")
284
- .description("リポ同梱の install 可能 example プラグイン一覧")
285
- .action(async () => {
286
- const list = await listInstallableExamples()
287
- if (list.length === 0) {
288
- console.log("(no examples bundled)")
289
- return
290
- }
291
- for (const name of list) {
292
- console.log(`- ${name}`)
293
- }
294
- })
295
-
296
- plugins
297
- .command("install <name>")
298
- .description("repo plugins/<name>/ を ~/.hub/plugins/<name>/ にコピー (config.json は温存)")
299
- .option("--force", "既存ディレクトリを上書きする")
300
- .action(async (name, opts) => {
301
- try {
302
- const r = await installPlugin(name, { force: !!opts.force })
303
- console.log(`installed: ${r.dest}`)
304
- console.log("次のステップ:")
305
- console.log(` $EDITOR ${r.dest}/config.json # 既存なら温存、新規なら example をコピー`)
306
- console.log(` hub-agent restart (launchctl kickstart / systemctl restart)`)
307
- } catch (err) {
308
- console.error(`plugins install failed: ${err.message}`)
309
- process.exit(1)
310
- }
311
- })
312
-
313
283
  plugins
314
284
  .command("uninstall <name>")
315
- .description("~/.hub/plugins/<name>/ を削除")
285
+ .description("~/.hub/plugins/<prio>-<name>/ を削除する")
316
286
  .action(async (name) => {
317
287
  try {
318
288
  const r = await uninstallPlugin(name)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cocorograph/hub-agent",
3
- "version": "0.8.24",
4
- "description": "Hub Hosted Cockpit のローカル常駐 agent。Hub と outbound WSS で接続し、ローカルの tmux/pty を中継する。",
3
+ "version": "0.8.25",
4
+ "description": "Hub Hosted Cockpit のローカル常駐 agent。Hub と outbound WSS で接続し、ローカルの Claude / Codex チャットと tmux セッションを中継する。",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",
7
7
  "private": false,
@@ -19,7 +19,6 @@
19
19
  "scripts": {
20
20
  "start": "node bin/hub-agent.mjs start",
21
21
  "test": "node --test test/*.test.mjs",
22
- "postinstall": "node scripts/fix-node-pty-perms.mjs",
23
22
  "check:publish-on-main": "node scripts/check-publish-on-main.mjs",
24
23
  "prepublishOnly": "node scripts/check-publish-on-main.mjs && npm test"
25
24
  },
@@ -28,13 +27,11 @@
28
27
  "src/",
29
28
  "scripts/",
30
29
  "templates/",
31
- "plugins/",
32
30
  "README.md",
33
31
  "LICENSE"
34
32
  ],
35
33
  "dependencies": {
36
34
  "@anthropic-ai/claude-agent-sdk": "^0.3.158",
37
- "@lydell/node-pty": "1.2.0-beta.12",
38
35
  "commander": "^12.1.0",
39
36
  "pino": "^9.0.0",
40
37
  "ws": "^8.18.0"
@@ -518,10 +518,10 @@ _install_node_lts_linux() {
518
518
  }
519
519
 
520
520
  # ネイティブアドオンのビルドに必要な make / g++ / python3 を導入する。
521
- # PTY backend は @lydell/node-pty に移行済みで全 OS の prebuild を同梱するため通常は
522
- # native ビルド不要だが、prebuild が当たらない環境では node-gyp rebuild に
523
- # フォールバックする。クリーンな Ubuntu には build-essential が無く
524
- # `gyp ERR! not found: make` で失敗する (WSL クリーン Ubuntu で発覚) ため保険で導入する。
521
+ # 現在の依存はすべて純 JS で通常は native ビルド不要だが、optional な native 依存
522
+ # (ws の bufferutil 等) が prebuild なしで拾われると node-gyp rebuild にフォールバック
523
+ # する。クリーンな Ubuntu には build-essential が無く `gyp ERR! not found: make` で
524
+ # 失敗する (WSL クリーン Ubuntu で発覚) ため保険で導入する。
525
525
  # macOS は Xcode CLT 前提なので何もしない。
526
526
  ensure_build_tools() {
527
527
  [[ "$(uname)" == "Darwin" ]] && return 0
@@ -812,7 +812,7 @@ macos_perm_guidance() {
812
812
  cat <<EOF
813
813
 
814
814
  📣 macOS の権限ダイアログについて
815
- hub-agent は tmux/pty を中継するため、初回起動時に macOS から
815
+ hub-agent は tmux セッションとローカルの CLI (Claude / Codex) を中継するため、初回起動時に macOS から
816
816
  「node がローカルネットワーク上の機器を検出することを求めています」
817
817
  「node がアクセシビリティを制御することを求めています」
818
818
  「node がほかのアプリからのデータへのアクセス権を求めています」
@@ -15,8 +15,7 @@
15
15
  * - これは Claude CLI の `claude --resume <id> -p "<msg>"` を毎ターン叩くのと同じ
16
16
  * モデルで、SDK の挙動と素直に噛み合う
17
17
  *
18
- * PtyBridge と並走させる設計。`pty.*` 系メッセージは無傷で、新規 `claude.*` のみ
19
- * 受け持つ。テスト時は SDK を `{ query }` shape で stub 注入する。
18
+ * `claude.*` 系メッセージを受け持つ。テスト時は SDK を `{ query }` shape で stub 注入する。
20
19
  */
21
20
  import { EventEmitter } from "node:events"
22
21
  import { randomUUID } from "node:crypto"
@@ -2427,7 +2426,7 @@ export class ClaudeStreamBridge extends EventEmitter {
2427
2426
  /**
2428
2427
  * 指定 cwd / session_id に紐づく SDK セッションを**即停止**する (T04784 TUI bind 用)。
2429
2428
  *
2430
- * TUI モードに切り替えた session は対話 TUI (tmux/PTY) の claude が write を担うため、
2429
+ * TUI モードに切り替えた session は tmux ペインの対話 claude が write を担うため、
2431
2430
  * SDK セッションを生かしたままだと同一 cwd の jsonl を二重ホストして競合する
2432
2431
  * (DESIGN.md C7)。soft-detach (7 日 resident) では止まらないので、ここで明示 close する。
2433
2432
  *
@@ -11,7 +11,7 @@
11
11
  * claude.input → input() (idle は turn/start、生成中は次ターン FIFO)
12
12
  * claude.interrupt → interrupt() (turn/interrupt)
13
13
  * claude.detach → detach() (TTL 付き graceful close)
14
- * (codex 固有) → keepalive() (閲覧中の生存シグナル。pty.resize 相当)
14
+ * (codex 固有) → keepalive() (閲覧中の生存シグナル)
15
15
  * claude.permission.reply → permissionReply() (client.respond/respondError)
16
16
  * claude.event (生 SDK イベント素通し) → 'event' (生 notification 素通し、同じ思想)
17
17
  * claude.permission.request → 'permission' (承認/入力要求の生 method+params 素通し)
package/src/hooks.mjs CHANGED
@@ -17,7 +17,6 @@
17
17
  export const HOOK_NAMES = Object.freeze([
18
18
  "onAgentStart",
19
19
  "onAgentStop",
20
- "interceptPtySpawn",
21
20
  "interceptTmuxExec",
22
21
  "interceptSessionCreate",
23
22
  "interceptSessionKill",
@@ -26,21 +25,6 @@ export const HOOK_NAMES = Object.freeze([
26
25
  "transformStatusDetection",
27
26
  ])
28
27
 
29
- /**
30
- * @typedef {Object} PtySpawnArgs
31
- * @property {string} sessionName
32
- * @property {number} cols
33
- * @property {number} rows
34
- * @property {Record<string, string>} env
35
- */
36
-
37
- /**
38
- * @typedef {Object} PtySpawnDecision
39
- * @property {string} command
40
- * @property {string[]} args
41
- * @property {Record<string, string>} [env]
42
- */
43
-
44
28
  /**
45
29
  * @typedef {Object} TmuxExecArgs
46
30
  * @property {string[]} args
@@ -60,7 +44,6 @@ export const HOOK_NAMES = Object.freeze([
60
44
  * @property {{
61
45
  * onAgentStart?: (ctx: HookContext) => Promise<void>,
62
46
  * onAgentStop?: (ctx: HookContext) => Promise<void>,
63
- * interceptPtySpawn?: (ctx: HookContext & PtySpawnArgs) => Promise<PtySpawnDecision | null>,
64
47
  * interceptTmuxExec?: (ctx: HookContext & TmuxExecArgs) => Promise<TmuxExecDecision | null>,
65
48
  * }} hooks
66
49
  */