pum-agent 0.2.8-beta.1 → 0.2.10-beta.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/README.md CHANGED
@@ -23,7 +23,7 @@ pum
23
23
  PUM opens the login panel automatically on the first start.
24
24
 
25
25
  > [!WARNING]
26
- > PUM can read, write, and delete files. Check mode adds deterministic policy checks and can enforce native Bash isolation on supported Linux and Windows hosts. Other tools, extensions, and external triggers still run in the PUM process boundary described below. Review the safeguards and prerequisites before using untrusted workspaces.
26
+ > PUM can read, write, and delete files. Check mode adds deterministic policy checks, and supported hosts can enforce native Bash isolation. The file-tool sandbox is a process-local path guard, not complete operating-system isolation. Review the safeguards before using untrusted workspaces.
27
27
 
28
28
  ## See PUM in action
29
29
 
@@ -46,7 +46,8 @@ The following screens are real OpenTUI renders captured through `tmux`. A local
46
46
  - **Prompt control:** Steer active work, answer model questionnaires, use an ownership-aware message cache, attach clipboard images, and resume sessions with metadata-rich history.
47
47
  - **External triggers:** Supervise background commands such as `gh run watch` and automatically wake the exact target agent when they exit.
48
48
  - **Provider choice:** Search the providers exposed by pi, or add an OpenAI-compatible custom endpoint.
49
- - **Optional safeguards:** Use strict, balanced, or ask Check mode, plus native Bash sandboxing through Bubblewrap or Windows CreateProcessInSandbox when available.
49
+ - **Filesystem boundary:** `read`, `write`, and `edit` stay inside the project and configured allowed roots. `apply_patch` stays project-local.
50
+ - **Optional safeguards:** Use strict, balanced, or ask Check mode for `bash`, `edit`, `apply_patch`, and external-trigger process proposals. Supported hosts can also use native Bash sandboxing through Bubblewrap or Windows CreateProcessInSandbox.
50
51
  - **Terminal-first appearance:** Nine themes, semantic color overrides, Unicode glyphs, and optional animation.
51
52
 
52
53
  PUM uses [pi](https://github.com/earendil-works/pi) for the agent loop and [OpenTUI](https://github.com/anomalyco/opentui) for rendering.
@@ -140,6 +141,8 @@ Set `PUM_DIR` to override PUM's complete configuration and data directory. Run `
140
141
  | `Ctrl+L` | Open the agent transcript selector |
141
142
  | `Shift+Tab` / `Ctrl+Shift+Tab` | Cycle through agent transcripts |
142
143
  | `Ctrl+H` | Open session history when the terminal reports the key distinctly |
144
+ | `Ctrl+N` | Open recent answers (News) |
145
+ | `n` / `p` in News | Jump to the answer / user prompt |
143
146
  | `Ctrl+End` | Scroll to the end of the selected transcript |
144
147
  | `Ctrl+P` | Open settings |
145
148
  | `Ctrl+T` | Open supervised external triggers |
@@ -147,7 +150,7 @@ Set `PUM_DIR` to override PUM's complete configuration and data directory. Run `
147
150
  | `Ctrl+C` | Clear the selected non-empty draft; on an empty draft, press twice to quit |
148
151
  | `?` | Show all controls when the prompt is empty |
149
152
 
150
- Useful commands include `/login`, `/history`, `/triggers`, `/check-path`, `/clear`, `/compress`, and `/worktree`.
153
+ Useful commands include `/login`, `/history`, `/news`, `/triggers`, `/check-path`, `/clear`, `/compress`, and `/worktree`.
151
154
 
152
155
  ### Copy transcript text
153
156
 
@@ -171,6 +174,20 @@ Reload the `tmux` configuration after this change. Use the terminal's Shift-drag
171
174
 
172
175
  PUM limits remote OSC 52 payloads to 100,000 Base64 characters. This limit prevents large selections from corrupting terminal output.
173
176
 
177
+ ### Recent answers (News)
178
+
179
+ Open the News popup with `Ctrl+N` or `/news`. It lists the final answers of user-initiated turns, newest first. Each entry shows the user prompt and any follow-up steers that produced the answer, above the answer itself.
180
+
181
+ - `←` / `→` — move between answers
182
+ - `n` — jump to the answer
183
+ - `p` — jump to the user prompt
184
+ - `Space` — toggle an answer between read and unread
185
+ - `c` — copy the current answer to the clipboard
186
+ - `Enter` — reply to the current answer with a quoted draft
187
+ - `Esc` — close the popup
188
+
189
+ PUM marks an answer read automatically only when a new user prompt follows it directly in the transcript. If anything else appears between the answer and the next prompt — a subagent message, a trigger event, a queued message, or an in-progress stream — the answer stays unread.
190
+
174
191
  ## Parallel subagents
175
192
 
176
193
  PUM runs up to 10 active subagents by default. Configure a limit from 1 through 25 in Settings. Only starting and running agents count toward the limit. Each subagent has these resources:
@@ -186,6 +203,8 @@ Use `Ctrl+L` to select an agent transcript. Input then goes to that agent. Finis
186
203
 
187
204
  The public `spawn_subagent` tool accepts `preview: true`. PUM then shows the exact child task before it creates any worktree or session. Press `Enter` to approve. An optional note becomes a separate visible user instruction to the new child. Press `Esc` to cancel without creating a child. Cancellation discards the preview note because no child exists. PUM preserves the existing parent transcript draft.
188
205
 
206
+ When the Sandbox setting is `Auto` or `Require`, `spawn_subagent` also accepts `readonly: true`. A readonly child can inspect files and run sandboxed inspection commands. PUM omits `write`, `edit`, `apply_patch`, child spawning, inter-agent delegation, process-starting trigger tools, and message-cache mutation tools from that child. The remaining tool guard blocks unknown or mutation-capable child paths. Worktree access is limited to `list` and `status`. Bash requires an enforced native sandbox, receives read-only project, `/check-path`, and managed Git metadata roots, and receives no network access. If native enforcement is unavailable, readonly Bash blocks instead of using the `Auto` direct fallback. PUM persists readonly state across resume. Sandbox `Off` removes the argument from live spawn tool schemas and rejects any explicit readonly spawn request.
207
+
189
208
  Press `↑` on an empty single-line prompt to recall the newest queued user-authored message for the selected transcript. PUM removes the message from the authoritative queue before restoring its text. PUM does not recall inter-agent, trigger, lifecycle, cache, delivered, or image-bearing messages.
190
209
 
191
210
  Idle notices report settled work cycles to the direct spawner. They are not completion notices. PUM acknowledges completion delivery only after the notice enters the parent session. Persisted completion intent and stable message identifiers let interrupted delivery resume without duplicate completion messages.
@@ -218,6 +237,17 @@ Trigger events target one exact main or retained child session. A missing sessio
218
237
 
219
238
  `apply_patch` supports add, update, delete, move, multiple files, and multiple hunks. PUM validates the full patch before changing files. It rejects traversal, absolute paths, escaping symlinks, path conflicts, and ambiguous context. A failed commit restores all touched files.
220
239
 
240
+ ### Filesystem sandbox
241
+
242
+ The process-local filesystem sandbox validates `read`, `write`, `edit`, and `apply_patch` before execution.
243
+
244
+ - Project paths and `/check-path` roots are allowed.
245
+ - Credential-sensitive paths are blocked.
246
+ - Symbolic links and junctions in tool paths are blocked.
247
+ - `apply_patch` remains project-local and keeps its atomic validation.
248
+
249
+ This boundary does not isolate `bash`, package scripts, extensions, or trigger processes from the operating system. Use a container, VM, or policy-controlled sandbox for stronger isolation.
250
+
221
251
  ### Check mode
222
252
 
223
253
  Select a Check mode profile in `Ctrl+P`. It applies to `bash`, `edit`, `apply_patch`, and external-trigger process execution:
@@ -228,7 +258,7 @@ Select a Check mode profile in `Ctrl+P`. It applies to `bash`, `edit`, `apply_pa
228
258
 
229
259
  Every active profile hard-blocks external writes, location changes, execution operands, ambiguous path access, escaping links, credential access, privilege escalation, persistence, remote-script execution, destructive Git operations, and broad deletion. Balanced permits explicit, deterministically classified, non-sensitive external reads. It accepts one direct `npm pack` only when lifecycle scripts are disabled, an explicit cache stays in an approved root, output stays in an approved root, and any package operand is one exact registry version. Balanced also accepts one direct `npm install` of one exact registry version only when `--ignore-scripts`, an approved `--prefix`, and an approved `--cache` are explicit. File, Git, URL, tag, range, composed, general install, and global-install forms remain blocked. These hard blocks cannot be overridden and do not open the popup. An explicit verifier `UNSAFE` verdict also blocks without a popup. The only publication exception is a deterministic match for direct main-agent `npm publish` or `npm dist-tag add`. The verifier category does not control this exception. The exception still requires explicit popup approval. Managed subagents cannot use it.
230
260
 
231
- Use `/check-path list`, `/check-path add <directory>`, `/check-path remove <directory>`, or `/check-path clear` to manage up to 16 additional directory roots for the current launch project. Bash, edit, and external-trigger checks can use these roots; `apply_patch` remains project-local. Added roots are canonicalized and remain subject to credential, traversal, symlink or junction, broad-deletion, and other hard blocks.
261
+ Use `/check-path list`, `/check-path add <directory>`, `/check-path remove <directory>`, or `/check-path clear` to manage up to 16 additional directory roots for the current launch project. The filesystem sandbox applies these roots to `read`, `write`, and `edit`. Bash, edit, and external-trigger checks also use these roots; `apply_patch` remains project-local. Added roots are canonicalized and remain subject to credential, traversal, symlink or junction, broad-deletion, and other hard blocks.
232
262
 
233
263
  For `edit` and `apply_patch`, PUM validates the complete proposed change before any mutation. Review data includes the unified diff, changed paths, line counts, sensitivity flags, project containment, and full-content SHA-256. Invalid, stale, malformed, escaping, or incompletely analyzed input blocks the call. Patch length alone does not block a valid Balanced call.
234
264
 
@@ -254,6 +284,8 @@ The override uses pi's `createBashTool` implementation and custom Bash operation
254
284
 
255
285
  External triggers preserve direct executable/argument boundaries and continue to use deterministic Check mode, but they are not routed through the native sandbox in this release. The trigger manager's synchronous spawn boundary does not carry the exact approved policy object into execution; silently recomputing a second process policy there would weaken approval identity. Trigger output, environment, limits, and process supervision remain unchanged.
256
286
 
287
+ The filesystem sandbox is a process-local path guard for `read`, `write`, `edit`, and `apply_patch`. It does not replace native Bash isolation and does not cover scripts, extensions, or trigger processes.
288
+
257
289
  Verifier prompts stay bounded. For an oversized Balanced review, PUM sends complete validation metadata, counts, findings, and SHA-256 digests. PUM does not send a raw prefix or suffix as if it were complete. Strict and Ask keep their fail-closed oversized-input behavior.
258
290
 
259
291
  ### Hosted web search
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pum-agent",
3
- "version": "0.2.8-beta.1",
3
+ "version": "0.2.10-beta.1",
4
4
  "description": "A compact terminal coding agent powered by pi and OpenTUI.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -17,6 +17,7 @@ export type AgentTreeRow = {
17
17
  id: string | null;
18
18
  name: string;
19
19
  status?: SubagentSnapshot["status"];
20
+ readonly?: boolean;
20
21
  depth: number;
21
22
  metadata?: StatusMetadataValues;
22
23
  };
@@ -36,7 +37,9 @@ export function agentSelectorRowLayout(
36
37
  const indent = Math.min(2 + row.depth * 2, Math.max(2, popupColumns - 12));
37
38
  // One column remains clear for the pinned scrollbar.
38
39
  const contentColumns = Math.max(1, popupColumns - indent - 1);
39
- const label = row.status ? `${row.name} · ${row.status}` : row.name;
40
+ const label = row.status
41
+ ? `${row.name}${row.readonly ? " · readonly" : ""} · ${row.status}`
42
+ : row.name;
40
43
  const minimumLabelWidth = Math.min(
41
44
  label.length,
42
45
  Math.max(8, Math.ceil(contentColumns * 0.45)),
@@ -73,6 +76,7 @@ export function buildAgentTree(agents: readonly SubagentSnapshot[]): AgentTreeRo
73
76
  id: agent.id,
74
77
  name: agent.name,
75
78
  status: agent.status,
79
+ readonly: agent.readonly === true,
76
80
  depth,
77
81
  metadata: {
78
82
  branch: agent.worktree.branch ?? null,
@@ -95,6 +99,7 @@ export function buildAgentTree(agents: readonly SubagentSnapshot[]): AgentTreeRo
95
99
  id: agent.id,
96
100
  name: agent.name,
97
101
  status: agent.status,
102
+ readonly: agent.readonly === true,
98
103
  depth: 1,
99
104
  metadata: {
100
105
  branch: agent.worktree.branch ?? null,