pi-claude-supervisor 0.2.2 → 0.4.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 CHANGED
@@ -2,6 +2,25 @@
2
2
 
3
3
  All notable changes to this project will be documented here.
4
4
 
5
+ ## [0.4.0](https://github.com/btnalit/pi-claude-supervisor/compare/v0.3.0...v0.4.0) (2026-09-13)
6
+
7
+
8
+ ### Features
9
+
10
+ * add cross-process cwd leases and cancellable startup ([#17](https://github.com/btnalit/pi-claude-supervisor/issues/17)) ([448cbdb](https://github.com/btnalit/pi-claude-supervisor/commit/448cbdb4c6b5dd02b9ea07ba660d3689b7e2ace8))
11
+
12
+ ## [0.3.0](https://github.com/btnalit/pi-claude-supervisor/compare/v0.2.2...v0.3.0) (2026-09-13)
13
+
14
+
15
+ ### Features
16
+
17
+ * add safe tmux Claude worker transport ([1706153](https://github.com/btnalit/pi-claude-supervisor/commit/1706153289f9a6f7f9f59b2763ed98d061b79204))
18
+ * add cross-process canonical cwd leases and identity-bound tmux handoff
19
+ * make startup cancellation scoped per start and shutdown cleanup fail closed
20
+ * add cgroup-v2 required/auto/off policies with verified fallback cleanup
21
+ * harden owned/adopted tmux lifecycle, pane identity validation, and restart re-adoption
22
+ * validate real Claude Code 2.1.270 tmux multi-turn, pause/resume, and re-adoption behavior
23
+
5
24
  ## [0.2.2](https://github.com/btnalit/pi-claude-supervisor/compare/v0.2.1...v0.2.2) (2026-09-12)
6
25
 
7
26
 
@@ -35,11 +54,12 @@ All notable changes to this project will be documented here.
35
54
  - Deterministic Policy Gate and independent verification phase.
36
55
  - Minimal worker environment, argv-aware permission policy, watchdog timeouts and startup cleanup.
37
56
  - Opt-in Claude JSONL framing with duplicate-message suppression and transport Spike evidence for prompt, multi-turn and session resume.
57
+ - Opt-in tmux/PTY transport with private owned sessions, explicit existing-session adoption, human takeover and prompt-gated multi-line input.
38
58
  - Event-log sequence recovery and credential-shaped redaction.
39
59
  - Bounded output capture, stdin-write timeout, process-group cleanup retry and stop preemption.
40
60
  - Linux cgroup-v2 descendant cleanup, including a `setsid()` regression fixture, with required/auto modes.
41
61
  - Lifecycle event retry/order preservation, output restoration after log failure and shutdown cleanup retries.
42
- - Claude CLI 2.1.268 permission allow/deny and SIGTERM/SIGINT transport spike evidence.
62
+ - Historical Claude CLI 2.1.268 permission allow/deny and SIGTERM/SIGINT transport spike evidence; current release validation uses Claude CLI 2.1.270.
43
63
  - Event-driven JSONL `control_request`/`result`/exit events, permission responses, persistent Pi Decision Worker automation, bounded duplicate/turn handling, and outbound human-intervention webhooks.
44
64
  - Long-task defaults are now 100 automatic turns, 4 hours wall time and 20 minutes without output; Decision Worker API failures alert human operators directly instead of attempting an LLM fallback.
45
65
  - Automatic Decision Worker sessions now persist as Pi JSONL with a 0600 task registry. Unclean Pi restarts expose explicit `/supervise recover <task-id>` recovery; Claude work is not silently duplicated.
@@ -47,5 +67,5 @@ All notable changes to this project will be documented here.
47
67
 
48
68
  ### Limitations
49
69
 
50
- - PTY transport and cross-version Claude CLI permission/session semantics are out of scope for this pinned release; Claude JSONL support remains opt-in outside automatic mode. The installed 2.1.268 CLI is covered by local permission and signal spikes, while the cgroup startup-attachment window remains.
70
+ - tmux/PTY screen state is not Claude JSONL: trust, permission and ambiguous TUI states require human handling. Cross-version Claude CLI permission/session semantics remain outside the pinned compatibility claim. Historical permission and signal spikes use 2.1.268; current tmux validation uses 2.1.270, while the cgroup startup-attachment window remains.
51
71
  - No automatic merge, deployment, release or publication is implemented.
package/README.cn.md CHANGED
@@ -42,9 +42,9 @@ export PI_CLAUDE_SUPERVISOR_HUMAN_WEBHOOK_FORMAT=generic
42
42
  # export PI_CLAUDE_SUPERVISOR_HUMAN_WEBHOOK_SECRET='shared-secret'
43
43
  ```
44
44
 
45
- 自动模式会强制使用 `claude-jsonl`,通过 `result`、`control_request` 和进程
46
- `exit` 事件唤醒 Decision Worker;不会依赖 `/supervise poll` 轮询。本版本固定按已验证设备的
47
- Claude CLI `2.1.268` 运行,跨版本兼容性不在本轮范围内。
45
+ 自动模式默认使用 `claude-jsonl`,通过 `result`、`control_request` 和进程
46
+ `exit` 事件唤醒 Decision Worker;显式选择 tmux 时仍使用屏幕交互,不使用 JSONL 权限协议,也不会依赖 `/supervise poll` 轮询。本版本固定按已验证设备的
47
+ Claude CLI `2.1.270` 运行,跨版本兼容性不在本轮范围内。
48
48
 
49
49
  然后在 Pi 中使用:
50
50
 
@@ -84,6 +84,39 @@ Claude CLI `2.1.268` 运行,跨版本兼容性不在本轮范围内。
84
84
  再根据任务和仓库证据自动回答;无法确定时才升级人工。如需微信内闭环,需要另建带签名验证、
85
85
  一次性 action token 和重放保护的入站 callback 服务。
86
86
 
87
+ ### tmux/PTY 交互模式
88
+
89
+ 如果希望在可见的 Claude Code 终端中工作,可显式启用 tmux transport:
90
+
91
+ ```bash
92
+ export PI_CLAUDE_SUPERVISOR_TRANSPORT=tmux
93
+ export PI_CLAUDE_SUPERVISOR_WORKER='claude --permission-mode plan'
94
+ # 可选自动 Decision Worker(默认仍是人工模式):
95
+ # export PI_CLAUDE_SUPERVISOR_MODE=auto
96
+ # 接管非默认 tmux server 时可选:
97
+ # export PI_CLAUDE_SUPERVISOR_TMUX_SOCKET=/path/to/tmux.sock
98
+ ```
99
+
100
+ `/supervise start <task>` 会在私有 tmux server 中启动 Claude,并返回可复制的 attach 命令。
101
+ 可以在另一个终端 attach 到同一个 PTY,观察或人工输入。多行消息通过 tmux buffer 和 Enter
102
+ 发送,不会把消息拼接进 shell 命令;`pipe-pane` 记录原始输出,`capture-pane` 检测稳定的 Claude
103
+ 输入提示,并复用 watchdog、Decision Worker、审计和独立验收流程。
104
+
105
+ 如果 Claude 已由你在 tmux 中启动,可以显式接管且不会重放原始任务:
106
+
107
+ ```text
108
+ /supervise adopt-tmux <tmux-session-name> <task description>
109
+ ```
110
+
111
+ 接管会检查 cwd、pane 中的进程,并拒绝已有其他输出 pipe 的 pane;但不宣称拥有该 session。对被接管的 session,
112
+ `/supervise stop` 和 Pi 关闭只会断开监督,不会杀掉你的 tmux 窗口;需要关闭时请由你执行
113
+ `tmux kill-session`。`/supervise takeover <task-id>` 会暂停 Decision Worker 自动发送,只有
114
+ `/supervise resume-auto <task-id>` 才恢复。
115
+
116
+ PTY 屏幕文字不是 Claude JSONL。权限/信任对话框和无法确定的 TUI 状态必须升级人工,不能把
117
+ 屏幕文字当作结构化权限证据。普通终端里已经运行的 Claude 不能安全迁移进 tmux;`--resume`
118
+ 是读取历史的新进程,不是实时 attach。实时测试请使用 plan/read-only 参数。
119
+
87
120
  可以从不同工作目录启动多个任务会话;活动会话不能共享同一 cwd,建议每个任务使用独立 worktree:
88
121
 
89
122
  ```text
package/README.md CHANGED
@@ -97,6 +97,49 @@ Pass credentials through an explicit `WorkerStartInput.env` in an embedding
97
97
  integration. For the built-in command, opt in to named variables, for example
98
98
  `PI_CLAUDE_SUPERVISOR_WORKER_ENV=ANTHROPIC_API_KEY`.
99
99
 
100
+ ### tmux/PTY transport
101
+
102
+ For an interactive Claude Code window, opt in to the tmux transport:
103
+
104
+ ```bash
105
+ export PI_CLAUDE_SUPERVISOR_TRANSPORT=tmux
106
+ export PI_CLAUDE_SUPERVISOR_WORKER='claude --permission-mode plan'
107
+ # tmux does not support cgroup required mode; use cgroup mode auto/off.
108
+ # Optional automatic Decision Worker (manual mode is the default):
109
+ # export PI_CLAUDE_SUPERVISOR_MODE=auto
110
+ # Optional, only when adopting a non-default tmux server:
111
+ # export PI_CLAUDE_SUPERVISOR_TMUX_SOCKET=/path/to/tmux.sock
112
+ ```
113
+
114
+ `/supervise start <task>` starts Claude in a private tmux server and reports a
115
+ literal attach command. Use that command in another terminal to watch or
116
+ manually interact with the same PTY. The adapter sends multi-line input through
117
+ tmux buffers and Enter, never by interpolating the message into a shell command.
118
+ It records the PTY stream with `pipe-pane`, uses `capture-pane` to detect a
119
+ stable Claude input prompt, and feeds turn-completion events into the same
120
+ watchdog, Decision Worker, audit and verification paths as JSONL.
121
+
122
+ A session that you started yourself can be explicitly adopted without replaying
123
+ the task:
124
+
125
+ ```text
126
+ /supervise adopt-tmux <tmux-session-name> <task description>
127
+ ```
128
+
129
+ Adoption checks the session's working directory and pane command, and refuses a
130
+ pane that already has another output pipe. It does not claim ownership: `/supervise stop` and Pi shutdown detach supervision rather
131
+ than killing the user's tmux session. Use `tmux kill-session` yourself when the
132
+ adopted window should be closed. `/supervise takeover <task-id>` disables
133
+ automatic Decision Worker messages; resume them only with
134
+ `/supervise resume-auto <task-id>`.
135
+
136
+ PTY screen text is not Claude JSONL. Permission dialogs, trust prompts and
137
+ ambiguous TUI states are escalated to a human; tmux mode must not be treated as
138
+ structured permission evidence. A normal terminal Claude process cannot be
139
+ migrated into tmux, and `--resume` is historical recovery rather than live PTY
140
+ attach. Owned tmux sessions survive a Pi disconnect and require an explicit
141
+ `adopt-tmux` after restart. Use plan/read-only flags for live testing.
142
+
100
143
  ## Development
101
144
 
102
145
  ```bash
@@ -39,8 +39,9 @@ are also awaited during Pi shutdown.
39
39
 
40
40
  This is a control-boundary fixture and headless transport. It does not emulate a
41
41
  terminal. Manual compatibility mode remains `process-pipe`; automatic mode
42
- (`PI_CLAUDE_SUPERVISOR_MODE=auto`) forces Claude JSONL and uses the CLI contract
43
- validated by the fixed-version spike.
42
+ (`PI_CLAUDE_SUPERVISOR_MODE=auto`) defaults to Claude JSONL and uses the CLI
43
+ contract validated by the fixed-version spike; an explicit tmux transport remains
44
+ screen-based.
44
45
 
45
46
  A worker exit automatically triggers cleanup, and terminal status waits for
46
47
  that cleanup to be confirmed (or reports a cleanup error). On Linux the adapter
@@ -59,6 +60,47 @@ The Pi host installs graceful `SIGTERM`/`SIGINT` handlers, but `SIGSTOP` and
59
60
  `SIGKILL` cannot be handled; no orphan guarantee is claimed for those host-fatal
60
61
  signals.
61
62
 
63
+ ## tmux/PTY transport
64
+
65
+ `TmuxWorkerAdapter` is an explicit second transport, selected with
66
+ `PI_CLAUDE_SUPERVISOR_TRANSPORT=tmux`. Because tmux has no equivalent cgroup
67
+ containment boundary, `PI_CLAUDE_SUPERVISOR_CGROUP_MODE=required` is rejected
68
+ with this transport; use `auto`/`off` only when the tmux boundary is acceptable.
69
+ An owned worker gets a private tmux server/socket and executes the validated Claude command directly in the pane,
70
+ so its pane identity remains re-adoptable after a Pi restart. The worker
71
+ environment is supplied to the tmux server through the same least-privilege
72
+ environment builder; credentials are not copied into a file; credential-shaped
73
+ command arguments are rejected.
74
+ `load-buffer`, bracketed `paste-buffer` and `send-keys Enter` provide the input
75
+ boundary without interpolating a task into a shell command. C0/C1 terminal
76
+ control bytes are rejected; CRLF is normalized to a newline.
77
+
78
+ The transport has three deliberately separate observations:
79
+
80
+ - `pipe-pane` provides an append-only raw PTY log for output polling and audit;
81
+ - `capture-pane` provides a bounded screen snapshot used only for stable prompt
82
+ detection and human display;
83
+ - Claude's own transcript, when available, remains the structured history. The
84
+ screen is never relabeled as JSONL or permission evidence.
85
+
86
+ For an owned initial turn, the adapter emits a synthetic `turn_completed` only
87
+ after output activity and two stable input-prompt observations. Adopting an idle
88
+ prompt remains inactive and emits no synthetic completion. This is a liveness
89
+ signal, not proof that the task succeeded; the independent verifier remains
90
+ mandatory. Interactive dialogs,
91
+ trust prompts and ambiguous screens are not auto-approved. Human takeover sets a
92
+ Supervisor gate that stops automatic messages until `resume-auto`.
93
+
94
+ `/supervise adopt-tmux` is explicit and validates the pinned pane's cwd and
95
+ process identity before attaching. Every later input, capture and signal uses
96
+ that immutable pane target; a replacement process is refused. Adopted sessions
97
+ are not owned: stop and Pi shutdown detach rather than kill them. Tmux commands
98
+ and serialized input waits have bounded deadlines so shutdown cannot hang
99
+ forever. Sessions started by the adapter also survive a Pi disconnect, but
100
+ recovery after restart is explicit re-adoption; the extension never claims to
101
+ attach to an arbitrary non-tmux PTY. A normal Claude
102
+ `--resume` starts another process from history and is not a live PTY migration.
103
+
62
104
  ## State machine
63
105
 
64
106
  ```text
@@ -76,6 +118,34 @@ lifecycle event append fails after the state transition, it remains pending and
76
118
  is retried before the next lifecycle operation; output events restore their
77
119
  chunks for a lossless retry.
78
120
 
121
+ ### Cross-process cwd leases and startup cancellation
122
+
123
+ Every start and explicit recovery acquires an atomic lease in the shared lease
124
+ registry before spawning Claude. The default registry is
125
+ `~/.pi/agent/claude-supervisor/cwd-leases`; `PI_CLAUDE_SUPERVISOR_CWD_LEASE_DIR`
126
+ may point all Pi processes at an alternate shared directory. Canonical paths
127
+ conflict with both their parents and descendants, and the registry lock
128
+ serializes acquisition across independent Pi processes. A lease is released
129
+ only after the adapter confirms the worker and its descendant cleanup; an
130
+ unconfirmed lease left by a crashed Pi is intentionally retained and requires
131
+ operator verification/manual cleanup rather than unsafe automatic reclamation.
132
+ An explicitly adopted tmux session may hand off an existing lease only after
133
+ its owner identity is no longer live and its canonical cwd, tmux session/socket,
134
+ pane id, pane PID/start time, and pane command all match; ordinary starts
135
+ cannot consume another task's lease. If post-start worker identity registration
136
+ fails, owned workers are stopped before the lease is released; cleanup failure
137
+ retains both the worker and lease fail-closed. Explicit `stop` cleans owned tmux
138
+ sessions, while Pi shutdown detaches persistent sessions so they remain explicitly
139
+ re-adoptable.
140
+
141
+ Startup owns an `AbortController` and passes its signal to the adapter. A stop
142
+ or shutdown request aborts the controller and calls the adapter's out-of-band
143
+ startup cleanup without waiting behind the serialized start operation. Each
144
+ startup carries an opaque token, so cancelling one concurrent session cannot
145
+ abort another. Process and tmux adapters terminate or detach their startup
146
+ work, and the Supervisor rechecks cancellation before reporting `running`; a cancelled startup becomes
147
+ `stopped` and never reports a worker that was not cleanup-verified.
148
+
79
149
  ## Event log
80
150
 
81
151
  Events are JSONL with a monotonic sequence number, timestamp, task ID and worker
package/docs/releasing.md CHANGED
@@ -104,7 +104,8 @@ Major updates remain separate for explicit review. There is no blanket auto-merg
104
104
  A maintainer can retry an existing stable release from Actions:
105
105
 
106
106
  ```bash
107
- gh workflow run release.yml --ref main -f tag=v0.1.1
107
+ TAG=v0.3.0
108
+ gh workflow run release.yml --ref main -f tag="$TAG"
108
109
  ```
109
110
 
110
111
  The workflow verifies that the release tag is stable and belongs to `main`, then
package/docs/testing.md CHANGED
@@ -28,6 +28,12 @@ the published TypeScript source directly and there is no second runtime bundle.
28
28
  - `worker/process-adapter.test.ts`: spawn failure is observable, JSONL framing and
29
29
  idempotent duplicate suppression work, and a child does not remain indefinitely
30
30
  in a running state.
31
+ - `worker/tmux-adapter.test.ts`: an owned private tmux socket accepts multi-line
32
+ input, emits a stable-prompt turn event, preserves PTY output and cleans its
33
+ session on stop. It also verifies explicit idle startup does not submit a
34
+ blank turn, idle adoption emits no synthetic completion, adopted pipe
35
+ detachment permits re-adoption, and adopted stop preserves the user's
36
+ session.
31
37
  - `worker/environment.test.ts`: unrelated host credentials are excluded unless
32
38
  explicitly supplied.
33
39
  - `supervisor.test.ts`: the no-output watchdog stops a stalled worker, lifecycle event failures are retried, and output is restored when event persistence fails.
@@ -43,8 +49,11 @@ non-sensitive prompt, and prints protocol metadata rather than raw model output.
43
49
  It must not be added to the normal CI gate because authentication is an owner
44
50
  controlled prerequisite.
45
51
 
46
- The current fixtures validate one prompt, multiple turns, session resume,
52
+ The historical fixtures validate one prompt, multiple turns, session resume,
47
53
  permission allow/deny and SIGTERM/SIGINT behavior with Claude Code 2.1.268.
54
+ The current release validation uses Claude Code 2.1.270 at
55
+ `/home/yancao/.local/share/mise/installs/claude/2.1.270/claude`, including real
56
+ owned tmux turns, pause/resume, and restart re-adoption.
48
57
  The adapter regression suite also verifies event subscription, parsed
49
58
  `permission_request` events, and the exact nested `control_response` envelope.
50
59
  The automation spike additionally exercises a real Pi SDK Decision Worker with
@@ -64,10 +73,15 @@ npm run spike:signals
64
73
  npm run spike:automation
65
74
  SPIKE_AUTOMATION_PERMISSION=1 npm run spike:automation
66
75
  SPIKE_AUTOMATION_QUESTION=1 npm run spike:automation
76
+ PI_CLAUDE_SUPERVISOR_REAL_CLAUDE=1 npm run spike:tmux
67
77
  ```
68
78
 
69
- For this release, pin and record Claude Code `2.1.268` and its resolved
70
- executable path. Record:
79
+ The tmux spike is gated, authenticated, and excluded from normal CI. It uses
80
+ plan mode, records only protocol metadata, and verifies two real Claude turns,
81
+ pause/resume, owned detach, and identity-bound restart re-adoption.
82
+
83
+ For each release, pin and record the validated Claude Code version and resolved
84
+ executable path. For this release the validated version is `2.1.270`. Record:
71
85
 
72
86
  1. exact version and resolved executable path;
73
87
  2. license and source revision;
@@ -80,13 +94,24 @@ executable path. Record:
80
94
  A passing worker task is not sufficient. The independent verifier must repeat the
81
95
  relevant checks from a clean host perspective.
82
96
 
83
- Automatic mode is enabled with `PI_CLAUDE_SUPERVISOR_MODE=auto`; it forces JSONL
84
- and routes `result`, permission, and process-exit events to the persistent Pi
85
- Decision Worker. `process-pipe` remains the manual compatibility mode. Human
97
+ Automatic mode is enabled with `PI_CLAUDE_SUPERVISOR_MODE=auto`; it defaults to
98
+ JSONL and routes `result`, permission, and process-exit events to the persistent
99
+ Pi Decision Worker. An explicit `PI_CLAUDE_SUPERVISOR_TRANSPORT=tmux` selection
100
+ remains screen-based and does not use the JSONL permission protocol. `process-pipe` remains the manual compatibility mode. Human
86
101
  escalation is outbound-only through `PI_CLAUDE_SUPERVISOR_HUMAN_WEBHOOK_URL`;
87
102
  approval callbacks are deliberately not accepted without a separately
88
103
  authenticated endpoint.
89
104
 
105
+ The tmux transport is selected with `PI_CLAUDE_SUPERVISOR_TRANSPORT=tmux`. Before
106
+ release, manually verify: private-socket attach, multi-line paste, prompt
107
+ stability while Claude is busy, trust/permission dialog takeover, duplicate
108
+ send prevention, pane replacement refusal, pause/resume, owned-session stop,
109
+ adopted-session detach/re-adoption, bounded shutdown, and Pi shutdown without
110
+ closing an attached window. Use `--permission-mode plan`
111
+ and read-only tools for live Claude checks. Do not run JSONL and tmux control
112
+ against the same Claude process, and do not treat `capture-pane` text as a
113
+ structured permission response.
114
+
90
115
  ## Failure injection
91
116
 
92
117
  The automated adapter matrix covers external `SIGTERM`, `SIGINT`, `SIGKILL`,
@@ -8,7 +8,7 @@ without exposing credentials or allowing repository changes.
8
8
  ## Environment
9
9
 
10
10
  - Node: `v26.8.1` (declared package minimum remains `>=22.19`)
11
- - Claude Code: `2.1.268`
11
+ - Claude Code: `2.1.268` (historical headless probe; current release validation uses `2.1.270`)
12
12
  - Executable: resolved through `PATH` as `claude`
13
13
  - Working directory: `/home/yancao/Work`
14
14
  - Session persistence: disabled for the stateless fixture; enabled for the separate resume fixture
@@ -56,7 +56,7 @@ existing default remains generic `process-pipe`.
56
56
 
57
57
  ## Required follow-up
58
58
 
59
- Additional evidence was collected with Claude Code `2.1.268` using
59
+ Historical permission evidence was collected with Claude Code `2.1.268` using
60
60
  `--permission-prompt-tool stdio --permission-mode default --tools Bash`:
61
61
 
62
62
  - The CLI emitted `control_request` with `request.subtype=can_use_tool`,
@@ -72,7 +72,7 @@ Additional evidence was collected with Claude Code `2.1.268` using
72
72
  decision at the wrong envelope level is rejected as an invalid permission
73
73
  result.
74
74
 
75
- The exact signal fixture also passed for `2.1.268`: after `system/init`, a group
75
+ The exact signal fixture also passed for historical version `2.1.268`: after `system/init`, a group
76
76
  `SIGTERM` produced exit code `143` with no terminal result; group `SIGINT`
77
77
  produced exit code `0` and a terminal result with `terminal_reason=
78
78
  "aborted_streaming"` and `is_error=true`. The new adapter cgroup-v2 fixture
@@ -87,8 +87,8 @@ npm run spike:signals
87
87
  ```
88
88
 
89
89
  Remaining evidence is malformed/duplicate CLI input, no secret leakage in
90
- captured events, and the cgroup startup-attachment window. Release scope is
91
- pinned to Claude Code `2.1.268` on the validated device; cross-version
92
- portability is explicitly out of scope for this iteration. The adapter-level
93
- lifecycle track is now **GO** for the installed CLI and host; atomic OS process
94
- containment remains follow-up work.
90
+ captured events, and the cgroup startup-attachment window. The current release
91
+ also passed a real Claude Code `2.1.270` tmux validation: owned multi-turn
92
+ interaction, pause/resume, explicit detach, and identity-bound restart
93
+ re-adoption. The adapter-level lifecycle track is now **GO** for the installed
94
+ CLI and host; atomic OS process containment remains follow-up work.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-claude-supervisor",
3
- "version": "0.2.2",
3
+ "version": "0.4.0",
4
4
  "description": "A policy-gated Pi supervisor for observing and verifying Claude Code workers.",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -56,6 +56,7 @@
56
56
  "test:install": "node scripts/test-install.mjs",
57
57
  "test:pi": "node scripts/test-pi.mjs",
58
58
  "spike:transport": "node scripts/spike-claude-transport.mjs",
59
+ "spike:tmux": "node scripts/spike-claude-tmux.mjs",
59
60
  "spike:permissions": "node scripts/spike-claude-permissions.mjs",
60
61
  "spike:signals": "node scripts/spike-claude-signals.mjs",
61
62
  "spike:automation": "node scripts/spike-claude-automation.mjs",
package/src/config.ts CHANGED
@@ -1,13 +1,17 @@
1
1
  import { chmodSync, existsSync, readFileSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
3
  import { join } from "node:path";
4
+ import { redactSensitive } from "./redaction.ts";
4
5
 
5
6
  const allowed = new Set([
6
7
  "PI_CLAUDE_SUPERVISOR_MODE",
7
8
  "PI_CLAUDE_SUPERVISOR_AUTOMATION",
8
9
  "PI_CLAUDE_SUPERVISOR_TRANSPORT",
10
+ "PI_CLAUDE_SUPERVISOR_CGROUP_MODE",
11
+ "PI_CLAUDE_SUPERVISOR_TMUX_SOCKET",
9
12
  "PI_CLAUDE_SUPERVISOR_WORKER",
10
13
  "PI_CLAUDE_SUPERVISOR_STATE_DIR",
14
+ "PI_CLAUDE_SUPERVISOR_CWD_LEASE_DIR",
11
15
  "PI_CLAUDE_SUPERVISOR_WORKER_ENV",
12
16
  "PI_CLAUDE_SUPERVISOR_HUMAN_WEBHOOK_URL",
13
17
  "PI_CLAUDE_SUPERVISOR_HUMAN_WEBHOOK_FORMAT",
@@ -29,7 +33,7 @@ export function loadSupervisorEnvironment(): string | undefined {
29
33
  }
30
34
  return path;
31
35
  } catch (error) {
32
- console.error(`pi-claude-supervisor could not read env file ${path}: ${error instanceof Error ? error.message : String(error)}`);
36
+ console.error(`pi-claude-supervisor could not read env file ${String(redactSensitive(path))}: ${String(redactSensitive(error instanceof Error ? error.message : String(error)))}`);
33
37
  return undefined;
34
38
  }
35
39
  }