Skip to content

feat(coding-agent): preview bash-skill commands as bash in collapsed cells - #1911

Merged
xeophon merged 7 commits into
mainfrom
snimu/bash-skill-preview
Sep 1, 2026
Merged

feat(coding-agent): preview bash-skill commands as bash in collapsed cells#1911
xeophon merged 7 commits into
mainfrom
snimu/bash-skill-preview

Conversation

@snimu

@snimu snimu commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

In the interactive TUI, a python cell that runs a shell command through the bash skill collapses to a line like python · r = await bash('…') - the command string is erased by the long-string redaction in the preview descriptor, and even short commands show the python wrapper instead of the command. Repeated bash-skill calls are indistinguishable (screenshot case: three consecutive python · r = await bash('…') lines).

The fix

%%bash cells already have the right treatment: routed through previewBashCommand, labeled bash, bash-highlighted, salient-command descriptor. This PR extends that to bash-skill calls: after the python scorer picks the preview line, if that line is a bash(...) / await bash(...) / x = await bash(...) call whose first argument is a plain string literal (single-, double-, or triple-quoted; raw strings included), the literal is extracted and previewed via the existing previewBashCommand:

✓ bash · git status --porcelain · ↑ 2 lines · 21ms
  • One extraction function + one regex in code-preview.ts; no component changes (ipython-cell.ts already labels from preview.language).
  • The extracted command flows through the same descriptor/redaction path as %%bash cells (secrets stay redacted; verified with export/token/password cases).
  • Non-literal arguments (variables, f-strings, concatenation) and escaped-quote literals that cannot be cut safely fall back to the current python preview - extraction never shows a command that differs from what ran.
  • Match is anchored to the scorer-chosen line; trailing arguments (bash(cmd, timeout=...)) are tolerated.

Tests

Five focused cases in code-preview.test.ts: literal routing (short + >=160-char command with kwarg, proving the redaction-erasure is gone), triple-quoted multi-line body, non-literal fallback (variable + f-string), non-literal-first-argument/escaped-quote fallback (including the grep -n \")\" mis-cut guard), and scorer coexistence with other code. The routing assertions were proven red against the pre-fix preview.

Linear: ENG-5802


Note

Low Risk
UI-only preview heuristics in code-preview.ts with conservative fallbacks; extracted commands reuse existing bash redaction paths.

Overview
Collapsed ipython cells that invoke the bash skill with a plain string literal now show bash · <command> (via previewBashCommand) instead of a generic python · await bash('…') line where long commands were truncated or redacted.

previewPythonCode detects bash(...) / await bash(...) on the scorer’s preview line, parses the first argument with a small Python string-literal scanner (single/double/triple quotes, raw strings, common escapes), and falls back to the existing Python preview when the argument isn’t a safe literal (variables, f-strings, concatenation, unclosed strings, or escapes like \x/\b that aren’t evaluated). redactNoise also redacts Authorization: headers in preview text so curl-style bash-skill calls stay safe.

Tests cover routing, literal evaluation, fallbacks, and docstring false positives; no TUI component changes.

Reviewed by Cursor Bugbot for commit 2402762. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Preview bash(...) skill calls as bash in collapsed ipython cells

  • When an ipython cell invokes bash("...") with a standalone quoted string literal, previewPythonCode now returns a bash-language preview (bash · <command>) instead of the Python wrapper. The new extractBashSkillCommand helper uses BASH_SKILL_CALL_PATTERN to locate the call and scanPythonStringLiteral to decode the literal, rejecting unterminated strings, unsupported escapes, or non-literal first arguments.
  • Adds endsInsideMultilineString so bash-like text inside an open triple-quoted Python string is not misinterpreted as a bash call.
  • redactNoise now redacts Authorization: header values (including optional Bearer prefix) from preview text.
  • Behavioral Change: previewPythonCode in code-preview.ts gains new code paths; cells that previously previewed as Python may now preview as bash when they match the pattern. redactNoise additionally strips Authorization tokens that were previously visible in previews.

Macroscope summarized 2402762.

snimu added 3 commits August 30, 2026 19:53
…bash

In the collapsed ipython cell line, python cells like r = await bash('git status')
now render as bash · git status instead of the python wrapper (which redactNoise
erased entirely for commands >=160 chars). Literal-first-arg bash() calls on the
scorer-chosen line are routed through previewBashCommand, matching %%bash cells.
Non-literal arguments keep the python preview.

ENG-5802
…action

previewIpythonCode must keep the python preview when the quoted literal
is not the whole first argument (string concatenation, escaped quotes).
The existing tests let a mutant that drops the comma/paren-after-close-
quote guard survive; this pins the fallback behavior.
Comment thread packages/coding-agent/src/core/tools/code-preview.ts Outdated
Comment thread packages/coding-agent/src/core/tools/code-preview.ts Outdated
snimu added 3 commits August 31, 2026 10:29
…nside strings

Replace the regex-tail + indexOf extraction with a small python
string-literal scanner: backslash consumes the next char (raw-string
rule included), cooked strings unescape standard sequences, and an
unterminated scan falls back to the python preview. The preview now
shows the evaluated command (real newlines, unescaped quotes) instead
of raw source text, and triple-quoted literals with escaped quotes can
no longer be mis-cut.

Reuse the scanner to detect when the scorer's chosen line sits inside
an unterminated triple-quoted string opened earlier; skip bash-skill
extraction there so string text like a docstring never previews as a
bash command that did not run.
…ction

Killer tests for three surviving mutants: raw-string backslash handling
(raw close at backslash-quote), the closed-and-reopened multiline gate
state, and unclosed-literal extraction of a partial value.
Comment thread packages/coding-agent/src/core/tools/code-preview.ts
@sethkarten

Copy link
Copy Markdown
Contributor

One issue before approval: the new Authorization: redaction only handles Bearer as a two-part value. Other valid schemes leave the credential visible. For example, Authorization: Basic dXNlcjpwYXNz becomes Authorization: <redacted> dXNlcjpwYXNz, and Authorization: ApiKey secret has the same problem.

Please redact the complete authorization-header value through the closing quote or line, and add behavioral coverage for Basic and another non-Bearer scheme through the bash preview path.

Minor cleanup while touching the PR: please rewrite the changelog in the required user-facing past-tense form, for example: Fixed collapsed IPython cells that invoke the bash skill to preview the command instead of the Python wrapper.

@snimu
snimu requested a review from xeophon September 1, 2026 10:30
@xeophon
xeophon merged commit 71c0108 into main Sep 1, 2026
23 checks passed
@xeophon
xeophon deleted the snimu/bash-skill-preview branch September 1, 2026 10:39
olety added a commit to oneiron-dev/prime-agent that referenced this pull request Sep 1, 2026
Takes upstream's event-driven supervisor roster ledger + push (PrimeIntellect-ai#1897, PrimeIntellect-ai#1900),
direct TUI<->worker transport (ENG-5817), daemon startup/recovery hardening
(PrimeIntellect-ai#1929, PrimeIntellect-ai#1909), single-dump kernel snapshots (PrimeIntellect-ai#1945), empty-draft eviction
(PrimeIntellect-ai#1946), rlm_child_update suppression (PrimeIntellect-ai#1944), bash-skill preview (PrimeIntellect-ai#1911).

Fork laws re-expressed on the roster architecture:
- stable-target follow-up honesty kept (capability proof via worker hello,
  target_unavailable never not_found when ownership unproven)
- schema revision 26 (union of fork rev-24 stable-target + upstream
  rev-24/25 roster+transport); digest minted by the repo's own algorithm
- summary freshness reuse + single-flight + staleness + root-omission
  rejection restored on upstream's refresh pull
- adoption/recovery never fails a live worker on a slow or root-omitting
  catalog: get_state root seed + stale mark + bounded background rehydration
- repl.py keeps fork prune-on-aggregate-overflow
- delete handlers keep fork persistence reporting; eviction fence test keeps
  the stronger two-worker contention variant

Known test debt (deferred to post-Wave cleanup per owner): roster-era fixture
migrations in daemon-supervisor-monitor (2), plus un-triaged failures in
package-command-paths, agent-session-recursion, daemon-runtime-stress,
4600-supervisor-singleton, 4603-worker-recovery, 4606-update-restart-
coordinator, agents-view-roster. Production laws preserved; failures are
fixture-era artifacts or mechanism assertions to rewrite.
ketema added a commit to ketema/prime-agent that referenced this pull request Sep 1, 2026
- Direct session transport between TUI and worker (ENG-5817, PrimeIntellect-ai#1926)
- Event-driven supervisor agent roster with push subscriptions (PrimeIntellect-ai#1897, PrimeIntellect-ai#1900, PrimeIntellect-ai#1895)
- Hardened daemon startup, recovery ownership, and worker launch diagnostics (PrimeIntellect-ai#1929, PrimeIntellect-ai#1918)
- Python REPL runtime single-dump snapshots and bash preview tool (PrimeIntellect-ai#1945, PrimeIntellect-ai#1911)
- Non-blocking RLM subagent deletion and snapshot update suppression (PrimeIntellect-ai#1954, PrimeIntellect-ai#1944)
- Saved catalog loading on Agents View open (PrimeIntellect-ai#1960)
- Advanced Anthropic prompt caching marker across tool results (PrimeIntellect-ai#1927)
- TUI process replacement on update and empty draft eviction (PrimeIntellect-ai#1631, PrimeIntellect-ai#1946, PrimeIntellect-ai#1920)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants