Skip to content

fix(cli): format structured commands in history export#12023

Merged
reneehuang1 merged 2 commits into
cline:mainfrom
morgan-coded:freshness/cline-11942
Jul 1, 2026
Merged

fix(cli): format structured commands in history export#12023
reneehuang1 merged 2 commits into
cline:mainfrom
morgan-coded:freshness/cline-11942

Conversation

@morgan-coded

Copy link
Copy Markdown
Contributor

History export could crash when a saved run_commands entry used the structured { command, args } form instead of a plain string.

This formats each command through the CLI's existing structured-command helper before escaping it, while string commands keep the same output path. I checked the focused history/helper tests, typecheck, Biome, SDK build, the full CLI unit suite with 784 tests passing, and the CLI build.

Fixes #11942

Copilot AI review requested due to automatic review settings July 1, 2026 07:26
@greptile-apps

greptile-apps Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a crash in the CLI history export when a run_commands tool entry uses the structured { command, args } object form instead of a plain string. The fix re-uses the already-existing formatStructuredCommand helper (newly exported) and routes each command element through it before HTML-escaping.

  • helpers.ts: formatStructuredCommand is promoted from private to exported; no logic changes.
  • export.ts: renderCommandsHTML accepts unknown[] instead of string[] and calls formatStructuredCommand on each element before passing to escapeHtml, preventing the crash.
  • history.test.ts: A regression test is added that confirms structured command objects are correctly serialised in the exported HTML.

Confidence Score: 5/5

Safe to merge — the change is narrowly scoped to the HTML export path and re-uses an already-tested helper.

The change touches only the display layer of history export. formatStructuredCommand already existed and was already tested; promoting it to exported and calling it from renderCommandsHTML is a minimal, correct fix. The escapeHtml call wraps the output of formatStructuredCommand, so the XSS surface is unchanged. The new regression test exercises the exact scenario that caused the crash.

No files require special attention.

Important Files Changed

Filename Overview
apps/cli/src/utils/helpers.ts Exports the previously private formatStructuredCommand helper so it can be reused in export.ts; no logic changes.
apps/cli/src/session/export.ts Widens renderCommandsHTML parameter from string[] to unknown[] and routes each element through formatStructuredCommand before HTML-escaping, fixing the crash on structured { command, args } entries.
apps/cli/src/commands/history.test.ts Adds a focused regression test that exercises the structured-command export path and asserts the formatted output appears in the HTML.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["renderCommandsHTML(commands: unknown[])"] --> B{"forEach command"}
    B --> C["formatStructuredCommand(cmd)"]
    C --> D{"typeof cmd"}
    D -->|string| E["return cmd as-is"]
    D -->|object with 'command' key| F["return 'command args...' joined"]
    D -->|other| G["return String(cmd)"]
    E --> H["escapeHtml(result)"]
    F --> H
    G --> H
    H --> I["Rendered HTML <code> block"]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A["renderCommandsHTML(commands: unknown[])"] --> B{"forEach command"}
    B --> C["formatStructuredCommand(cmd)"]
    C --> D{"typeof cmd"}
    D -->|string| E["return cmd as-is"]
    D -->|object with 'command' key| F["return 'command args...' joined"]
    D -->|other| G["return String(cmd)"]
    E --> H["escapeHtml(result)"]
    F --> H
    G --> H
    H --> I["Rendered HTML <code> block"]
Loading

Reviews (2): Last reviewed commit: "Merge branch 'main' into freshness/cline..." | Re-trigger Greptile

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a CLI history export crash when run_commands tool calls store commands as structured objects ({ command, args }) instead of plain strings, by formatting commands through the existing structured-command formatter before HTML-escaping.

Changes:

  • Exported formatStructuredCommand from the CLI helpers so it can be reused by history export.
  • Updated history export HTML rendering to accept run_commands entries containing structured command objects.
  • Added a regression test covering structured run_commands command objects in exported history HTML.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
apps/cli/src/utils/helpers.ts Exports the existing formatStructuredCommand helper for reuse outside the module.
apps/cli/src/session/export.ts Uses formatStructuredCommand() when rendering run_commands entries to prevent non-string crashes during escapeHtml().
apps/cli/src/commands/history.test.ts Adds coverage ensuring structured command objects export correctly (e.g. cmd /c dir).

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 17f0803e9d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/cli/src/session/export.ts

@abeatrix abeatrix left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@reneehuang1 reneehuang1 merged commit c09d54f into cline:main Jul 1, 2026
12 checks passed
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.

Error on exporting history: i.replace is not a function

4 participants