Repository navigation
Add visible cmux Pi subagents package - #9879
lawrencecchen wants to merge 1 commit into
Conversation
📝 WalkthroughWalkthroughAdded the Changescmux subagent workflow
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Agent
participant cmux
participant ChildAgent
participant ResultFile
Agent->>cmux: Create grouped child workspace
Agent->>ChildAgent: Start configured child process
ChildAgent->>ResultFile: Write ChildResult
Agent->>ResultFile: Poll or retrieve result
Agent->>cmux: Steer running child workspace
Possibly related PRs
Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (3 errors)
✅ Passed checks (22 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit c30ddee. Configure here.
| }, { deliverAs: "followUp", triggerTurn: true }); | ||
| }, POLL_MS); | ||
| watchers.set(record.id, timer); | ||
| } |
There was a problem hiding this comment.
Duplicate background completion delivery
Medium Severity
watchBackground uses setInterval with an async callback and only clears the timer after await readResult(...). Overlapping ticks can both observe the finished result and each call pi.sendMessage with triggerTurn: true, so the parent can receive duplicate completion follow-ups and start extra turns.
Reviewed by Cursor Bugbot for commit c30ddee. Configure here.
| clearTimeout(timer); | ||
| resolve(); | ||
| }, { once: true }); | ||
| }); |
There was a problem hiding this comment.
Abort listener leak while waiting
Low Severity
Each poll iteration in waitForResult registers a new abort listener on signal and only removes it when abort fires. On long foreground waits the listeners accumulate until the wait ends, creating an unnecessary leak for the lifetime of the signal.
Reviewed by Cursor Bugbot for commit c30ddee. Configure here.
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@pi-cmux-subagents/package.json`:
- Around line 28-38: Update the peerDependencies entries for
`@earendil-works/pi-coding-agent`, `@earendil-works/pi-tui`, and typebox from
unrestricted "*" ranges to the tested supported ranges matching their
devDependencies: ^0.81.0, ^0.81.0, and ^1.0.0 respectively.
In `@pi-cmux-subagents/src/cmux.ts`:
- Around line 61-74: Update the parent workspace resolution in the
identity-handling flow to use only caller.workspace_ref. Remove the
focused.workspace_ref and top-level workspace_ref fallbacks, while preserving
the existing error when caller.workspace_ref is absent so the operation fails
closed.
In `@pi-cmux-subagents/src/index.ts`:
- Around line 78-94: Hard-coded English user-facing content must be moved to
locale-specific APIs with matching entries in every supported catalog. Update
pi-cmux-subagents/src/index.ts lines 78-94 for Agent metadata and lines 96-228
for runtime, progress, result, and widget text; pi-cmux-subagents/package.json
line 4 for package metadata; pi-cmux-subagents/src/cmux.ts lines 14-15 and 44-46
for parse and command errors; pi-cmux-subagents/src/child.ts lines 13-21 and 36
for child metadata and completion text; and pi-cmux-subagents/README.md lines
1-93 for localized documentation sources and translations.
In `@pi-cmux-subagents/src/launch-child.mjs`:
- Around line 16-19: Update the readOnly tools definition in launch-child.mjs so
Explore, Plan, and reviewer receive only read-only tools; remove bash from their
allowlist while preserving the existing edit and write tools for non-read-only
agents.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 959c72e5-7ad4-4006-9966-53150a8d020b
⛔ Files ignored due to path filters (1)
pi-cmux-subagents/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (10)
pi-cmux-subagents/LICENSEpi-cmux-subagents/README.mdpi-cmux-subagents/package.jsonpi-cmux-subagents/src/child.tspi-cmux-subagents/src/cmux.tspi-cmux-subagents/src/index.tspi-cmux-subagents/src/launch-child.mjspi-cmux-subagents/src/types.tspi-cmux-subagents/test/cmux.test.tspi-cmux-subagents/tsconfig.json
| "peerDependencies": { | ||
| "@earendil-works/pi-coding-agent": "*", | ||
| "@earendil-works/pi-tui": "*", | ||
| "typebox": "*" | ||
| }, | ||
| "devDependencies": { | ||
| "@earendil-works/pi-coding-agent": "^0.81.0", | ||
| "@earendil-works/pi-tui": "^0.81.0", | ||
| "@types/node": "^24.0.0", | ||
| "typebox": "^1.0.0", | ||
| "typescript": "^5.9.0" |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
For @earendil-works/pi-coding-agentversion 0.81.0 and@earendil-works/pi-tui version 0.81.0, identify the minimum compatible versions for ExtensionAPI methods exec, registerTool, registerCommand, on, and sendMessage. Also verify TypeBox compatibility for version 1.0.0.
💡 Result:
For @earendil-works/pi-coding-agent version 0.81.0 and @earendil-works/pi-tui version 0.81.0, the ExtensionAPI methods exec, registerTool, registerCommand, on, and sendMessage are core parts of the extension system [1][2][3]. These methods have been established features in the Pi agent ecosystem and do not have specific "minimum compatible versions" listed for version 0.81.0, as they are inherent to the platform's API definition for these releases [4][5][6]. Developers are expected to use the ExtensionAPI interface provided in the current version [2][3]. Regarding TypeBox compatibility, version 0.81.0 of the @earendil-works/pi-coding-agent utilizes TypeBox for parameter validation in tools [1][7][3]. While specific compatibility for TypeBox 1.0.0 is not explicitly documented as a breaking change in the 0.81.0 release notes [5][8], current dependencies for recent versions of the agent (e.g., 0.84.1) include TypeBox ^1.3.7 [9]. It is recommended to use the version of TypeBox compatible with the agent's internal dependencies to ensure stability [9].
Citations:
- 1: https://pi.dev/docs/latest/extensions
- 2: https://badlogic-pi-mono.mintlify.app/api/coding-agent/extension-api
- 3: https://pt-act-pi-mono.mintlify.app/api/coding-agent/extensions
- 4: https://github.com/earendil-works/pi/releases/tag/v0.81.0
- 5: https://github.com/earendil-works/pi/blob/main/packages/coding-agent/CHANGELOG.md
- 6: https://github.com/earendil-works/pi/blob/main/packages/tui/CHANGELOG.md
- 7: https://github.com/earendil-works/pi/blob/v0.79.10/packages/coding-agent/docs/extensions.md
- 8: https://npmx.dev/package-changelog/@earendil-works/pi-coding-agent/v/0.74.0
- 9: https://registry.npmjs.org/@earendil-works/pi-coding-agent
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== candidate package files =="
fd -a 'package.json$' . | sed 's#^\./##' | grep -E '(pi-cmux-subagents|coding-agent|pi-tui|typebox)' || true
echo
echo "== pi-cmux-subagents package.json =="
if [ -f pi-cmux-subagents/package.json ]; then
cat -n pi-cmux-subagents/package.json
fi
echo
echo "== root/package workspace manifests mentioning pm dependency =="
rg -n '"`@earendil-works/pi`(-coding-agent|-tui)":"|peerDependencies|devDependencies' -S --glob 'package.json' .Repository: manaflow-ai/cmux
Length of output: 2262
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== imports and API uses in pi-cmux-subagents =="
rg -n "from ['\"](`@earendil-works/pi-`(coding-agent|tui)|typebox)[^'\"]*['\"]|registerTool|registerCommand|on\\(|sendMessage|exec\\(|typebox|Type\\.box|T\\.box" -S src test package.json 2>/dev/null || true
echo
echo "== package lock dependency pins if present =="
for f in package-lock.json npm-shrinkwrap.json yarn.lock pnpm-lock.yaml bun.lockb bun.lock; do
[ -f "$f" ] && echo "-- $f --" && rg -n "`@earendil-works/pi-`(coding-agent|tui)|typebox" "$f" -S || true
done
echo
echo "== changed files/stat =="
git diff --stat || true
git diff --name-only HEAD~1..HEAD 2>/dev/null || trueRepository: manaflow-ai/cmux
Length of output: 1159
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== pi-cmux-subagents source excerpt =="
wc -l pi-cmux-subagents/src/*.ts pi-cmux-subagents/src/*.mjs pi-cmux-subagents/test/*.test.ts 2>/dev/null || true
sed -n '1,220p' pi-cmux-subagents/src/index.ts pi-cmux-subagents/src/types.ts pi-cmux-subagents/src/child.ts pi-cmux-subagents/src/cmux.ts 2>/dev/null || true
sed -n '1,180p' pi-cmux-subagents/test/cmux.test.ts 2>/dev/null || true
echo
echo "== exact peer/dev/runtime dependency text =="
python3 - <<'PY'
import json
from pathlib import Path
p=Path('pi-cmux-subagents/package.json')
data=json.loads(p.read_text())
for sec in ['peerDependencies','devDependencies','dependencies']:
print(sec, data.get(sec))
PYRepository: manaflow-ai/cmux
Length of output: 12059
🌐 Web query:
@sinclair/typebox changelog 1.0.0 breaking changes registerTool parameters Type.Object
💡 Result:
In TypeBox 1.0.0, several structural changes occurred that distinguish it from the previous @sinclair/typebox 0.34.x series [1][2]. Regarding registerTool and Type.Object: The legacy TypeRegistry mechanism, which was used for custom type registration, was replaced in 1.0.0 [3]. While Type.Object remains a core primitive for defining objects, the internal architecture for how TypeBox handles type registration and validation has evolved to support more advanced, spec-compliant schema evaluation [3][4]. Users should consult the updated TypeSystem and TypeRegistry documentation within the official 1.0 documentation, as the API surface for extending TypeBox has been overhauled [3][5]. Key changes in 1.0.0 include: 1. Package Name and Ecosystem: The package is now published under the name typebox (rather than @sinclair/typebox) [1][2][6]. 2. ESM Only: TypeBox 1.0.0 is an ESM-only package [1][2][6]. While support for CommonJS was briefly removed, it was subsequently re-enabled in later 1.x minor versions (1.0.33+) to allow for easier migration [7]. 3. Pick and Omit Behavior: Type.Pick and Type.Omit now evaluate results into normalized Object types, rather than just traversing and selecting properties [3]. This ensures consistency with TypeScript's own evaluation of logical type expressions [7]. 4. Symbols: All symbols were removed from the codebase to improve type inference and compatibility across different module systems [1]. For detailed migration paths and specific API changes, the authoritative source is the 1.0.0 migration guide maintained in the official repository [3][8][9].
Citations:
- 1: Separate ESM and CJS type declarations break type inference sinclairzx81/typebox#1313
- 2: https://github.com/sinclairzx81/typebox
- 3: https://github.com/sinclairzx81/typebox/blob/main/changelog/1.0.0-migration.md
- 4: Are there any major improvements in v1.0 over v0.34.x? sinclairzx81/typebox#1501
- 5: https://www.npmjs.com/package/@sinclair/typebox
- 6: https://registry.npmjs.org/typebox
- 7:
Type.Omitno longer works on unions after upgrading to v1 sinclairzx81/typebox#1391 - 8: Migrate from @sinclair/typebox to typebox 1.0 elysiajs/elysia#1471
- 9: https://unpkg.com/typebox@1.1.1/readme.md
Constrain the peer dependency ranges.
The * peer ranges allow incompatible host versions to install this package, while development tests and generated lockfile pins target @earendil-works/pi-coding-agent/@earendil-works/pi-tui ^0.81.0 and typebox ^1.0.0. Set the peers to the tested supported range.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@pi-cmux-subagents/package.json` around lines 28 - 38, Update the
peerDependencies entries for `@earendil-works/pi-coding-agent`,
`@earendil-works/pi-tui`, and typebox from unrestricted "*" ranges to the tested
supported ranges matching their devDependencies: ^0.81.0, ^0.81.0, and ^1.0.0
respectively.
| const parentWorkspaceRef = nestedString(identity, [ | ||
| ["caller", "workspace_ref"], | ||
| ["focused", "workspace_ref"], | ||
| ]) ?? firstString(identity, ["workspace_ref"]); | ||
| if (!parentWorkspaceRef) { | ||
| throw new Error("cmux could not identify the parent workspace"); | ||
| } | ||
|
|
||
| const existingGroup = nestedString(identity, [ | ||
| ["caller", "workspace_group_ref"], | ||
| ["caller", "group_ref"], | ||
| ["focused", "workspace_group_ref"], | ||
| ["focused", "group_ref"], | ||
| ]) ?? firstString(identity, ["workspace_group_ref", "group_ref"]); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Run this inside a cmux-hosted Pi session where caller and focus can differ.
cmux --json identify | jq '{
caller,
focused,
workspace_ref,
workspace_group_ref,
group_ref
}'Repository: manaflow-ai/cmux
Length of output: 196
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Files:"
git ls-files | rg '(^|/)cmux\.ts$|pi-cmux-subagents' || true
echo
echo "pi-cmux-subagents/src/cmux.ts outline:"
ast-grep outline pi-cmux-subagents/src/cmux.ts || true
echo
echo "Relevant cmux.ts lines:"
cat -n pi-cmux-subagents/src/cmux.ts | sed -n '1,140p'Repository: manaflow-ai/cmux
Length of output: 6293
🌐 Web query:
cmux identify command caller focused workspace_ref group_ref documentation
💡 Result:
In cmux, the identify command is used to retrieve information about the current terminal context, including the topology of focused windows, workspaces, panes, and surfaces [1][2]. It is particularly useful for automation agents that need to resolve the current context or route actions relative to a specific "caller" anchor [2]. Key aspects of the identify command include: Context and Caller Resolution: When executed, cmux identify returns the currently focused topology [2]. It also includes "caller" context, which identifies the origin of the command [2]. You can use the --no-caller flag to omit this information from the output if desired [3][4]. Automation Anchors: The command supports caller overrides, allowing users to specify a workspace or surface anchor for the identification process (e.g., cmux identify --workspace workspace:2) [2]. This capability allows agents to perform actions relative to a known anchor rather than just the default focus [2]. Output Formats: The command provides structured output, commonly used in JSON format (cmux identify --json) for programmatic consumption [1][2]. Users can also control the output format using flags like --id-format to display either handles or UUIDs [2]. Workspace and Group References: While identify provides the broader context, cmux utilizes handles such as workspace_ref and group_ref to identify specific organizational units within the terminal [5][6]. A group_ref refers to a managed collection of workspaces (workspace groups), which can be listed, created, and manipulated via the cmux workspace-group subcommand namespace [7][8][6]. For further details on automation integration, refer to the official cmux CLI reference documentation [1][3].
Citations:
- 1: https://cmux.com/docs/api
- 2: https://github.com/manaflow-ai/cmux/blob/HEAD/skills/cmux/references/handles-and-identify.md
- 3: https://manaflow-ai-cmux.mintlify.app/automation/cli-reference
- 4: https://mintlify.wiki/manaflow-ai/cmux/automation/cli-reference
- 5: Add one-step grouped workspace creation #6657
- 6: Add named workspace groups to sidebar #2702
- 7: https://cmux.com/docs/workspace-groups
- 8: https://github.com/manaflow-ai/cmux/blob/27810b92/docs/workspace-groups.md
🌐 Web query:
manaflow-ai cmux caller context focused identity workspace_ref group_ref
💡 Result:
In the context of cmux—an open-source, Ghostty-based macOS terminal designed for AI coding agents [1][2]—these terms refer to concepts used to manage automation state, identify processes, and organize development environments [3][4]. Identity (Caller Context) cmux uses "caller context" and "identity" to allow AI agents and scripts to programmatically target the correct terminal environment [3][5]. When a command is run within a cmux terminal, the system automatically exposes environment variables—such as CMUX_WORKSPACE_ID and CMUX_SURFACE_ID—that serve as the "caller's identity" [6][7]. The cmux identify command is the primary tool used to resolve this context [4][8]. It returns a JSON object containing the current focused topology (window, workspace, pane, and surface) and the resolved caller identity [4][8]. Proper caller resolution is essential for agents to ensure that commands are executed in the intended workspace rather than defaulting to the operator's currently focused terminal [6][9]. Workspace_ref and Group_ref These are identifier formats used for deterministic targeting in the cmux CLI and API [4][10]. workspace_ref: A shorthand reference format (e.g., workspace:N) used to specify a particular workspace [4]. It is one of several handle types—alongside UUIDs and indices—that commands accept to perform operations like routing, monitoring, or management [4]. group_ref: An identifier (e.g., group:N) associated with "grouped workspaces" [10]. Recent updates to cmux allow for the creation and management of workspace groups, where group_ref and related parameters (like group_placement) enable agents to organize multiple workspaces into logical sets [10]. Summary of Key Concepts - Caller Context: The environment from which a command or agent originates, used to avoid ambiguity in multi-workspace/multi-agent setups [6][9]. - Identity: The combination of IDs (workspace, surface, etc.) that defines the state of a specific terminal segment [4][11]. - workspace_ref / group_ref: Deterministic handles that allow the cmux API to target specific workspaces or workspace groups for programmatic control [4][10].
Citations:
- 1: https://github.com/manaflow-ai/cmux
- 2: https://manaflow.com/
- 3: https://manaflow-ai-cmux.mintlify.app/automation/overview
- 4: https://github.com/manaflow-ai/cmux/blob/HEAD/skills/cmux/references/handles-and-identify.md
- 5: https://manaflow-ai-cmux.mintlify.app/automation/socket-api
- 6: daemon leaks focused workspace IDs in spawn env (CMUX_WORKSPACE_ID, CMUX_SURFACE_ID set to focused pane, not target spawn) #4920
- 7: https://www.mintlify.com/manaflow-ai/cmux/automation/environment-variables
- 8: https://cmux.com/docs/api
- 9: fix(cli): default workspace-scoped commands to the caller's workspace, not the focused one #6757
- 10: Add one-step grouped workspace creation #6657
- 11: system.identify cannot resolve caller identity by surface UUID alone #5554
🌐 Web query:
github manaflow-ai/cmux handles-and-identify.md caller workspace_ref focused
💡 Result:
In the context of the cmux project by manaflow-ai, the terms "caller" and "focused" (often seen within the workspace_ref and system.identify context) represent two distinct concepts used for routing commands and identifying the state of the terminal [1][2][3]. The handles-and-identify.md documentation explains that these identifiers allow for deterministic automation targeting [1]. 1. Caller: Refers to the specific entity (such as a workspace or surface) that initiated or is currently executing the command [1][4]. Automations and agents often need to route relative actions from a known "caller anchor" to ensure commands are executed in the correct context [1]. 2. Focused: Refers to the entity (window, workspace, pane, or surface) that is currently active or has input focus on the macOS desktop [2][3]. A common point of friction in cmux automation occurs when a command is dispatched to the "focused" entity instead of the "caller's" entity [4][5]. For instance, if an agent is running in a non-orchestrator workspace (the caller), but the user has manually focused a different workspace (the focused), commands might incorrectly execute in the focused workspace [4]. Developers and users can utilize cmux identify --json to inspect the difference between the caller's context and the currently focused state to troubleshoot these routing discrepancies [1][2][5].
Citations:
- 1: https://github.com/manaflow-ai/cmux/blob/HEAD/skills/cmux/references/handles-and-identify.md
- 2: https://mintlify.wiki/manaflow-ai/cmux/automation/socket-api
- 3: https://manaflow-ai-cmux.mintlify.app/automation/socket-api
- 4: __tmux-compat split-window targets focused workspace instead of caller's workspace #2551
- 5: Side panel toggle affects focused window instead of clicked window #1779
🌐 Web query:
repo:manaflow-ai/cmux caller workspace_ref nestedString firstString nestedString identity
💡 Result:
In the manaflow-ai/cmux codebase, the identifier firstString is a utility function used across several modules (such as CMUXCLI+AgentHookPayload.swift, CMUXCLI+AutoNaming.swift, and SessionIndexRegisteredAgents.swift) to safely extract and return the first non-empty string value from a dictionary given a list of potential keys [1][2][3]. The term nestedString does not appear as a standalone identifier or function in the codebase. Instead, logic involving "nested" dictionaries is handled by searching within sub-objects of the main input object [1]. Specifically, functions like extractClaudeHookSessionId or related parsing logic manually inspect nested dictionaries—often under keys like "notification", "data", "session", or "context"—before applying the firstString utility to those nested objects to find specific values [1]. Therefore, while there is no nestedString function, the pattern commonly involves: 1. Accessing a nested dictionary (e.g., object["notification"] as? [String: Any]) [1]. 2. Calling firstString(in: nestedObject, keys: [...]) to retrieve a value from that specific depth [1]. The workspace_ref appears in the context of cmux's workspace management (e.g., SSH sessions) [4][5], but it is not a direct argument or parameter associated with firstString [1][2][3]. The firstString function strictly accepts an object of type [String: Any] and an array of keys ([String]) [1][2][3].
Citations:
- 1: https://github.com/manaflow-ai/cmux/blob/main/CLI/CMUXCLI%2BAgentHookPayload.swift
- 2: https://github.com/manaflow-ai/cmux/blob/27810b92/Sources/SessionIndexRegisteredAgents.swift
- 3: https://github.com/manaflow-ai/cmux/blob/main/CLI/CMUXCLI%2BAutoNaming.swift
- 4: https://github.com/manaflow-ai/cmux
- 5: https://github.com/manaflow-ai/cmux/blob/main/README.md
🌐 Web query:
"workspace_ref" "caller" "cmux identify" "parent workspace"
💡 Result:
In cmux, the identifier workspace_ref is a short handle used to reference a specific workspace (e.g., workspace:1) [1][2][3]. When determining the parent or caller workspace of a process, cmux relies on a combination of environment variables and the cmux identify command [4][5][6]. To identify the workspace of a caller, you can use the following methods: Environment Variables: cmux automatically injects environment variables into terminal surfaces that identify their context [4][7]. The CMUX_WORKSPACE_ID environment variable contains the UUID of the workspace where the process was spawned [7]. Scripts and agents should check this variable to determine their caller context [5][7][6]. CLI Identification: The cmux identify --json command returns the current focused topology and includes caller information [2][6]. Specifically, the JSON output typically includes a caller block that provides the workspace_ref and workspace_id associated with the calling process [5][6]. Best Practices for Agents: 1. Prefer Caller Context: When building agents or automation, prioritize the caller's workspace (derived from CMUX_WORKSPACE_ID or cmux identify) over the visually focused workspace [8][5][6]. Relying on the focused workspace can be inaccurate because an agent might be executing in a background workspace while the user is actively viewing another [6]. 2. Validation: If CMUX_WORKSPACE_ID is present, it is the primary anchor for the workspace context [7]. 3. Handling Stale Context: Be aware that in some complex scenarios, such as moving a surface between workspaces, the environment variables might become stale [9]. In such cases, cmux identify provides a more robust way to resolve the current active topology [2][9]. For programmatic access via the Go client or similar integrations, you can interact with the cmux-tui socket to query the live topology directly [10].
Citations:
- 1: https://manaflow-ai-cmux.mintlify.app/cli/workspaces
- 2: https://github.com/manaflow-ai/cmux/blob/HEAD/skills/cmux/references/handles-and-identify.md
- 3: https://mintlify.wiki/manaflow-ai/cmux/cli/workspaces
- 4: https://cmux.com/docs/api
- 5: daemon leaks focused workspace IDs in spawn env (CMUX_WORKSPACE_ID, CMUX_SURFACE_ID set to focused pane, not target spawn) #4920
- 6: https://www.skills.sh/manaflow-ai/cmux/cmux-workspace
- 7: https://www.mintlify.com/manaflow-ai/cmux/automation/environment-variables
- 8: fix(cli): default workspace-scoped commands to the caller's workspace, not the focused one #6757
- 9: system.identify cannot resolve caller identity by surface UUID alone #5554
- 10: https://github.com/manaflow-ai/cmux/tree/main/cmux-tui/bindings/go
Use only caller context for the parent workspace.
cmux identify returns caller and focused as separate contexts. If caller.workspace_ref is absent, fail closed; do not fall back to focused.workspace_ref, workspace_ref, or any other identity. The current fallback can create or place a child workspace under a focused workspace that did not invoke Agent.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@pi-cmux-subagents/src/cmux.ts` around lines 61 - 74, Update the parent
workspace resolution in the identity-handling flow to use only
caller.workspace_ref. Remove the focused.workspace_ref and top-level
workspace_ref fallbacks, while preserving the existing error when
caller.workspace_ref is absent so the operation fails closed.
Sources: Coding guidelines, Path instructions
| pi.registerTool({ | ||
| name: "Agent", | ||
| label: "Visible cmux agent", | ||
| description: "Launch a focused Pi subagent in a visible cmux workspace. The parent and children are organized in one collapsible workspace group. Foreground calls wait for the result; background calls return immediately.", | ||
| promptSnippet: "Launch visible Pi subagents in grouped cmux workspaces", | ||
| promptGuidelines: [ | ||
| "Use Agent when delegated work benefits from a visible, independently steerable Pi session. Use run_in_background for parallel work.", | ||
| ], | ||
| parameters: Type.Object({ | ||
| subagent_type: Type.Union(AGENT_TYPES.map((name) => Type.Literal(name))), | ||
| prompt: Type.String({ description: "Self-contained task for the child agent" }), | ||
| description: Type.String({ description: "Short workspace title" }), | ||
| run_in_background: Type.Optional(Type.Boolean()), | ||
| model: Type.Optional(Type.String({ description: "Optional provider/model override" })), | ||
| thinking: Type.Optional(Type.String({ description: "Optional thinking level" })), | ||
| cwd: Type.Optional(Type.String({ description: "Working directory, defaults to the parent cwd" })), | ||
| }), |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
Add locale-specific sources for all new user-facing content.
The package adds hard-coded English tool metadata, errors, command output, package metadata, and documentation. Move static user-facing text to localized APIs and matching catalogs. Update every supported locale.
pi-cmux-subagents/src/index.ts#L78-L94: localize tool labels, descriptions, prompt guidance, and parameter descriptions.pi-cmux-subagents/package.json#L4-L4: provide locale-specific package metadata.pi-cmux-subagents/src/cmux.ts#L14-L15: localize the safe JSON parse-failure message.pi-cmux-subagents/src/cmux.ts#L44-L46: localize the safe cmux command-failure message.pi-cmux-subagents/src/child.ts#L13-L21: localize child tool metadata and prompt guidance.pi-cmux-subagents/src/child.ts#L36-L36: localize the completion message.pi-cmux-subagents/src/index.ts#L96-L228: localize runtime errors, progress messages, result messages, and command-widget text.pi-cmux-subagents/README.md#L1-L93: publish locale-specific documentation sources and translations.
📍 Affects 5 files
pi-cmux-subagents/src/index.ts#L78-L94(this comment)pi-cmux-subagents/package.json#L4-L4pi-cmux-subagents/src/cmux.ts#L14-L15pi-cmux-subagents/src/cmux.ts#L44-L46pi-cmux-subagents/src/child.ts#L13-L21pi-cmux-subagents/src/child.ts#L36-L36pi-cmux-subagents/src/index.ts#L96-L228pi-cmux-subagents/README.md#L1-L93
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@pi-cmux-subagents/src/index.ts` around lines 78 - 94, Hard-coded English
user-facing content must be moved to locale-specific APIs with matching entries
in every supported catalog. Update pi-cmux-subagents/src/index.ts lines 78-94
for Agent metadata and lines 96-228 for runtime, progress, result, and widget
text; pi-cmux-subagents/package.json line 4 for package metadata;
pi-cmux-subagents/src/cmux.ts lines 14-15 and 44-46 for parse and command
errors; pi-cmux-subagents/src/child.ts lines 13-21 and 36 for child metadata and
completion text; and pi-cmux-subagents/README.md lines 1-93 for localized
documentation sources and translations.
Sources: Coding guidelines, Path instructions
| const readOnly = new Set(["Explore", "Plan", "reviewer"]); | ||
| const tools = readOnly.has(config.agentType) | ||
| ? "read,bash,grep,find,ls,report_to_parent" | ||
| : "read,bash,grep,find,ls,edit,write,report_to_parent"; |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
In @earendil-works/pi-coding-agentversion 0.81.0, does addingbashto the--tools argument permit arbitrary shell commands and filesystem mutation? Is there a built-in read-only shell or command allowlist?
💡 Result:
In version 0.81.0 of @earendil-works/pi-coding-agent, adding bash to the --tools argument permits the agent to execute arbitrary shell commands on the host system with the same permissions as the user running the agent [1][2][3]. The bash tool is not sandboxed by default [1][3], and there is no built-in read-only shell command allowlist that restricts which commands can be executed when the bash tool is enabled [1][2]. To operate in a read-only context, the agent provides alternative tools such as read, grep, find, and ls, which are designed for codebase exploration without requiring the bash tool [4][5]. Users can achieve a read-only configuration by explicitly omitting bash from the --tools allowlist and instead specifying only the safe, read-only tools [4][6][5]. For example, the following command configures the agent for read-only exploration: pi --tools read,grep,find,ls -p "Review the code" The project does not offer a native mechanism to restrict the bash tool to a subset of commands [1]. If granular control over shell execution is required, users are advised to wrap the bash tool using the agent's extension API to implement a custom allowlist or filtering logic [2].
Citations:
- 1: https://agent-safehouse.dev/docs/agent-investigations/pi
- 2: https://petronellatech.com/blog/pi-dev-platform-review/
- 3: https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/security.md
- 4: https://registry.npmjs.org/@earendil-works/pi-coding-agent
- 5: Add read-only exploration tools (grep, find, ls) and --tools flag for restricted subagents earendil-works/pi#74
- 6: https://github.com/earendil-works/pi/blob/main/packages/coding-agent/README.md
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== locate launch-child.mjs =="
fd -a 'launch-child\.mjs$' . || true
echo "== file excerpt =="
if [ -f pi-cmux-subagents/src/launch-child.mjs ]; then
nl -ba pi-cmux-subagents/src/launch-child.mjs | sed -n '1,90p'
fi
echo "== search for readOnly/write/read-only/tool text =="
rg -n "readOnly|Read Only|read-only|read_only|agentType|agent-type|--tools|tools:|Explore|Plan|reviewer" -S . \
-g '!node_modules' -g '!dist' -g '!build' -g '!*.lock' -g '!package-lock.json' \
| sed -n '1,200p'Repository: manaflow-ai/cmux
Length of output: 301
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== file excerpt =="
if [ -f pi-cmux-subagents/src/launch-child.mjs ]; then
cat -n pi-cmux-subagents/src/launch-child.mjs | sed -n '1,90p'
fi
echo "== search for readOnly/write/read-only/tool text =="
rg -n "readOnly|Read Only|read-only|read_only|agentType|agent-type|--tools|tools:|Explore|Plan|reviewer" -S . \
-g '!node_modules' -g '!dist' -g '!build' -g '!*.lock' -g '!package-lock.json' \
| sed -n '1,200p' || trueRepository: manaflow-ai/cmux
Length of output: 27519
🌐 Web query:
site:packages.pi.dev @earendil-works/pi-coding-agent bash tools
💡 Result:
No exact packages.pi.dev result was found for that query.
Relevant matches:
@earendil-works/pi-coding-agentis Pi’s interactive coding-agent CLI. Its built-in tools includeread,bash,edit,write,grep,find, andls. (github.com)- The official Pi package catalog includes
pi-lean-ctx, which routesbash,read,grep,find, andlsthroughlean-ctx. (pi.dev) - Install the coding agent with:
(pi.dev)
npm install -g `@earendil-works/pi-coding-agent`
Citations:
- 1: https://github.com/earendil-works/pi?utm_source=openai
- 2: https://pi.dev/packages?utm_source=openai
- 3: https://pi.dev/news/2026/5/7/pi-has-a-new-home?utm_source=openai
🌐 Web query:
@earendil-works/pi coding agent bash tool shell command execute
💡 Result:
In the @earendil-works/pi coding agent, the bash tool is a built-in capability that allows the LLM to execute shell commands within the current working directory [1][2]. You can interact with the bash functionality in two primary ways: 1. Agent-led execution: By default, the agent is provided with the bash tool, allowing it to autonomously run commands to fulfill your requests [1][2]. 2. Manual interactive commands: You can trigger shell commands directly from the terminal interface [1][3]: - Use!command to execute a command and send its output back to the LLM for analysis [1][4]. - Use!!command to execute a command silently, without adding its output to the model context [1][4]. Technical Details: - Tool Definition: The bash tool is defined to execute commands in the project's working directory, returning stdout and stderr [5]. - Output Handling: To prevent context overflow, output is truncated if it exceeds default limits (saved to a temporary file if truncated) [5]. - Environment Variables: When the LLM executes bash commands, it receives session-specific metadata as environment variables, including PI_SESSION_ID, PI_PROVIDER, and PI_MODEL [6]. - Tool Configuration: You can manage tool availability via CLI flags [6][4]: - --tools (-t): Allowlist specific tools. - --exclude-tools (-xt): Disable specific tools. - --no-builtin-tools (-nbt): Disable all built-in tools. - --no-tools (-nt): Disable all tools entirely. The coding agent is distributed as an npm package (@earendil-works/pi-coding-agent) and can be installed globally via npm install -g --ignore-scripts @earendil-works/pi-coding-agent [1][2].
Citations:
- 1: https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/quickstart.md
- 2: https://www.npmjs.com/package/@earendil-works/pi-coding-agent
- 3: https://github.com/earendil-works/pi/tree/main/packages/coding-agent
- 4: https://github.com/earendil-works/pi/blob/v0.80.6/packages/coding-agent/docs/usage.md
- 5: https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/core/tools/bash.ts
- 6: https://github.com/earendil-works/pi/blob/main/packages/coding-agent/README.md
Remove bash from the read-only child tools.
Explore, Plan, and reviewer are defined as read-only, but their allowlist includes bash, which runs shell commands in the working directory and can mutate files. Use only read-only tools such as read,grep,find,ls, or wrap bash with an enforced read-only allowlist.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@pi-cmux-subagents/src/launch-child.mjs` around lines 16 - 19, Update the
readOnly tools definition in launch-child.mjs so Explore, Plan, and reviewer
receive only read-only tools; remove bash from their allowlist while preserving
the existing edit and write tools for non-read-only agents.
|
Superseded by a standalone pi-cmux-subagents repository and explicit pi-cmux launcher, per product direction. |


Summary
pi-cmux-subagents, a Pi package that launches real interactive child Pi sessions in cmux workspacesPi · <project>workspace group without stealing focusTesting
cd pi-cmux-subagents && npm testcd pi-cmux-subagents && npm run typecheckcd pi-cmux-subagents && npm audit --omit=devcd pi-cmux-subagents && npm pack --dry-runNeed help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Note
Medium Risk
New extension spawns
pichildren and can grantworkerfile-mutation tools; scope is isolated to cmux-hosted sessions but parallel agents increase blast radius for repo changes.Overview
Adds the
pi-cmux-subagentsPi package so delegated work runs as real interactive Pi sessions in cmux workspaces instead of hidden child processes.The parent extension registers
Agent,get_subagent_result, andsteer_subagent(Claude Code–style ergonomics).Agentcreates or reuses a collapsiblePi · <project>workspace group, opens unfocused child workspaces after the parent, and supports foreground waits orrun_in_backgroundwith automatic follow-up when a child finishes. Children use role types (Explore, Plan, reviewer, worker, general-purpose) with read-only vsedit/writetool sets, and hand back via a child-onlyreport_to_parenttool that atomically writesresult.jsonunder~/.pi/agent/cmux-subagents/. Steering uses cmuxsend+send-key enter. A/cmux-agentscommand shows a status widget.Includes
cmux.tshelpers (tested),launch-child.mjs, docs, MIT license, and npm packaging metadata.Reviewed by Cursor Bugbot for commit c30ddee. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by cubic
Adds
pi-cmux-subagents, a Pi package that runs subagents as visible cmux workspaces grouped under Pi · . Supports foreground/background runs, steering, and clean result handoffs without stealing focus.New Features
Agent,get_subagent_result,steer_subagent.Migration
pi-cmux-subagentswhen published).Written for commit c30ddee. Summary will update on new commits.
Summary by CodeRabbit
pi-cmux-subagents, enabling visible subagent execution in grouped cmux workspaces.