pum-agent 0.1.0-beta.3 → 0.1.2-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
@@ -13,8 +13,17 @@ Plan, edit, run commands, review Markdown, and coordinate parallel Git worktrees
13
13
 
14
14
  </div>
15
15
 
16
+ ## Quick Start
17
+
18
+ ```bash
19
+ bun i -g pum-agent@beta
20
+ pum
21
+ ```
22
+
23
+ PUM opens the login panel automatically on the first start.
24
+
16
25
  > [!WARNING]
17
- > PUM can read, write, and delete files. PUM can also run shell commands without approval. Start PUM only inside a workspace where these actions are acceptable. Check mode adds a verifier, but it is not a sandbox.
26
+ > PUM can read, write, and delete files. PUM can also run commands and supervised trigger processes. Check mode can verify or ask about these operations, but it is not a sandbox. Start PUM only inside a workspace where these actions are acceptable.
18
27
 
19
28
  ## See PUM in action
20
29
 
@@ -33,10 +42,11 @@ The following screens are real OpenTUI renders captured through `tmux`. A local
33
42
 
34
43
  - **Compact terminal UI:** Streaming Markdown, syntax highlighting, thinking traces, tool rows, usage, cost, and Git status.
35
44
  - **Full coding loop:** Built-in `read`, `write`, `edit`, `bash`, and atomic `apply_patch` tools.
36
- - **Parallel subagents:** Persistent agents work in isolated Git worktrees and report to the main agent.
37
- - **Prompt control:** Steer active work, stash prompt batches, attach clipboard images, cancel turns, and resume sessions.
45
+ - **Parallel subagents:** Persistent agents work in isolated Git worktrees, communicate durably, and report lifecycle transitions to their direct spawners.
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
+ - **External triggers:** Supervise background commands such as `gh run watch` and automatically wake the exact target agent when they exit.
38
48
  - **Provider choice:** Use the login methods exposed by pi, or add an OpenAI-compatible custom endpoint.
39
- - **Optional safeguards:** Enable fail-closed Check mode for `bash`, `edit`, and `apply_patch` calls.
49
+ - **Optional safeguards:** Use strict, balanced, or ask Check mode for `bash`, `edit`, `apply_patch`, and external-trigger process proposals.
40
50
  - **Terminal-first appearance:** Nine themes, semantic color overrides, Unicode glyphs, and optional animation.
41
51
 
42
52
  PUM uses [pi](https://github.com/earendil-works/pi) for the agent loop and [OpenTUI](https://github.com/anomalyco/opentui) for rendering.
@@ -95,36 +105,71 @@ The package is named `pum-agent` because the bare `pum` name is already owned. T
95
105
  | `Shift+Tab` / `Ctrl+Shift+Tab` | Cycle through agent transcripts |
96
106
  | `Ctrl+H` | Open session history when the terminal reports the key distinctly |
97
107
  | `Ctrl+P` | Open settings |
108
+ | `Ctrl+T` | Open supervised external triggers |
98
109
  | `Esc` twice | Cancel the selected working agent |
99
- | `Ctrl+C` twice | Quit |
110
+ | `Ctrl+C` | Clear the selected non-empty draft; on an empty draft, press twice to quit |
100
111
  | `?` | Show all controls when the prompt is empty |
101
112
 
102
- Useful commands include `/login`, `/history`, `/clear`, `/compress`, and `/worktree`.
113
+ Useful commands include `/login`, `/history`, `/triggers`, `/clear`, `/compress`, and `/worktree`.
103
114
 
104
115
  ## Parallel subagents
105
116
 
106
- PUM can run up to five active subagents. Each subagent has these resources:
117
+ 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:
107
118
 
108
119
  - A persistent pi session
109
120
  - An isolated branch and worktree under `.pum/worktrees`
110
121
  - Its own transcript, draft, usage data, and cancellation state
111
122
  - Tools for progress messages and a single final completion report
112
123
 
113
- Select a range of stashed prompts and press `Enter`. The main agent can group related work and run independent groups in parallel. Successful managed merges remove the completed worktree and branch.
124
+ Select a range of stashed prompts and press `Enter`. The main agent can group related work and run independent groups in parallel. Successful managed merges remove the completed worktree and branch. A parent cannot finish, merge, or be removed until every retained descendant closes deepest-first.
114
125
 
115
126
  Use `Ctrl+L` to select an agent transcript. Input then goes to that agent. Finished or interrupted agents remain available until PUM merges or removes them.
116
127
 
128
+ Idle notices report settled work cycles to the direct spawner. They are not completion notices. PUM persists completion intent and delivery state so interrupted notification delivery can resume without duplicate completion messages.
129
+
117
130
  ## Tools and safeguards
118
131
 
132
+ ### Interactive questionnaires
133
+
134
+ The `questionnaire` tool asks one or more questions inside PUM's OpenTUI interface. Each question provides selectable options and a custom-answer field. Use arrow keys or `Tab` to move, `Enter` to select, and `Esc` to cancel.
135
+
136
+ PUM returns structured answers to the requesting main agent or managed child agent. Custom text stays outside React labels and session data until the user explicitly submits the answer.
137
+
138
+ ### Agent message cache
139
+
140
+ Main and managed child agents can list and read the current workspace message cache. Agent-created entries include exact ownership metadata.
141
+
142
+ Agents can add entries. An agent can delete only entries created by that exact agent. User-created and legacy entries remain user-owned.
143
+
144
+ The `message_cache_send` tool accepts stable entry IDs. Single entries use the selected agent delivery path. Multiple entries use main-agent worktree orchestration.
145
+
146
+ ### External triggers
147
+
148
+ The trigger tools create process-local supervised commands with an executable and argument array. Trigger definitions can be listed, inspected, paused, resumed, cancelled, run manually, or fired synthetically. Definitions disappear when PUM exits.
149
+
150
+ Use `Ctrl+T` or `/triggers` to inspect active definitions. PUM limits definitions, pending deliveries, output size, fire counts, repeat frequency, and lifetime. Output goes to a private temporary file and is removed after the triggered turn settles.
151
+
152
+ Trigger events target one exact main or retained child session. A missing session or child cancels its definitions instead of redirecting them. Check mode evaluates each process proposal without flattening its argument boundaries into shell text.
153
+
119
154
  ### Atomic `apply_patch`
120
155
 
121
156
  `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.
122
157
 
123
158
  ### Check mode
124
159
 
125
- Enable Check mode in `Ctrl+P`. PUM sends each proposed `bash`, `edit`, or `apply_patch` call to a separate verifier model. The verifier must return a clear `SAFE` decision. Errors, timeouts, unclear replies, and explicit rejections block the tool.
160
+ Select a Check mode profile in `Ctrl+P`. It applies to `bash`, `edit`, `apply_patch`, and external-trigger process execution:
126
161
 
127
- PUM caches only a narrow set of accepted read-only Git inspection commands. It never caches mutation checks. Check mode is off by default and does not replace isolation, backups, or code review.
162
+ - **Strict:** Run deterministic hard rules, then require a clear verifier approval.
163
+ - **Balanced:** Permit only narrow, recognized project-local operations after hard rules. Send all other calls to the verifier.
164
+ - **Ask:** Send ambiguous calls to the verifier. If the result stays unclear or the verifier fails, ask the user.
165
+
166
+ Every active profile hard-blocks project escape, escaping links, credential access, privilege escalation, persistence, remote-script execution, destructive Git operations, and broad deletion. These hard blocks cannot be overridden. An explicit verifier `UNSAFE` verdict also cannot be overridden.
167
+
168
+ For `edit` and `apply_patch`, PUM validates the proposed change and sends a unified diff, changed paths, line counts, sensitivity flags, and project containment. PUM does not mutate files before the decision. Invalid or stale edit context blocks the call.
169
+
170
+ Ask mode can allow an exact call once, for the current session, or for the current project. Project approvals match the tool, verifier model, project, and canonical complete input. Use **Clear approvals** in Settings to remove project approvals.
171
+
172
+ The verifier uses a structured decision schema. One unclear response can receive one adjudication under the shared 15-second watchdog. Strict and balanced block malformed replies, errors, aborts, and timeouts. Ask can present unresolved results to the user. Check mode is off by default and is not a sandbox.
128
173
 
129
174
  ### Hosted web search
130
175
 
@@ -167,6 +212,11 @@ Set `PUM_DIR` to override the complete PUM data directory.
167
212
  | `sessions/` | Main conversation sessions |
168
213
  | `subagents/` | Persistent subagent sessions |
169
214
  | `check-mode-cache.json` | Accepted checks for eligible read-only Git commands |
215
+ | `check-mode-approvals.json` | Exact project approvals created in Ask mode |
216
+
217
+ PUM preserves all stashed prompt occurrences. PUM also keeps the 100 most recent additional sent-history occurrences for each working directory.
218
+
219
+ Session history shows the latest sent user-message time, on-disk JSONL size, and known outgoing, incoming, and cache-read token counts. Corrupt or partially written session lines do not prevent the history popup from opening.
170
220
 
171
221
  PUM keeps this directory separate from pi's default configuration directory.
172
222
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pum-agent",
3
- "version": "0.1.0-beta.3",
3
+ "version": "0.1.2-beta.1",
4
4
  "description": "A compact terminal coding agent powered by pi and OpenTUI.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -82,7 +82,8 @@ export function usageFromEntries(
82
82
  ): AgentUsage {
83
83
  let result = emptyAgentUsage();
84
84
  for (const entry of entries) {
85
- const usage = entry?.type === "message" && entry.message?.role === "assistant"
85
+ const usage = entry?.type === "message"
86
+ && (entry.message?.role === "assistant" || entry.message?.role === "toolResult")
86
87
  ? entry.message.usage
87
88
  : (entry?.type === "compaction" || entry?.type === "branch_summary")
88
89
  ? entry.usage
package/src/animation.tsx CHANGED
@@ -318,11 +318,16 @@ export function markdownCaretContent(text: string, visible: boolean): string {
318
318
  return text + (visible ? CARET : CARET_PLACEHOLDER);
319
319
  }
320
320
 
321
+ export type MarkdownCaretBinding = {
322
+ ref: RefObject<MarkdownRenderable | null>;
323
+ content: string;
324
+ };
325
+
321
326
  /** Keep a blinking caret at the end of incrementally rendered Markdown. */
322
327
  export function useMarkdownCaret(
323
328
  text: string,
324
329
  active: boolean,
325
- ): RefObject<MarkdownRenderable | null> {
330
+ ): MarkdownCaretBinding {
326
331
  const ref = useRef<MarkdownRenderable>(null);
327
332
  const { subscribe, enabled } = useClock();
328
333
  const latest = useRef(text);
@@ -359,7 +364,12 @@ export function useMarkdownCaret(
359
364
  if (active) paint();
360
365
  }, [text, active, paint]);
361
366
 
362
- return ref;
367
+ // React applies this value in the same commit as each transcript delta.
368
+ // The direct frame writes only change the width-stable caret glyph.
369
+ return {
370
+ ref,
371
+ content: active ? markdownCaretContent(text, caretVisible.current) : text,
372
+ };
363
373
  }
364
374
 
365
375
  function ruleText(width: number, base: RGBA, hi: RGBA, head: number): StyledText {