Skip to content

feat(shell): /export — export a session to Markdown - #417

Merged
jexShain merged 1 commit into
AI-Shell-Team:mainfrom
jexShain:feat/export-session
Jul 29, 2026
Merged

feat(shell): /export — export a session to Markdown#417
jexShain merged 1 commit into
AI-Shell-Team:mainfrom
jexShain:feat/export-session

Conversation

@jexShain

@jexShain jexShain commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds the /export [md] built-in command: writes the current session to a Markdown file (aish-session-<short>.md) for postmortem or sharing.

Closes #411

What it does

  • Exports session metadata (uuid, model, api_base, created time, working dir), the full AI conversation (by role), and the command history as a table.
  • History-table cells escape |, newlines, and backticks so commands containing them render correctly.
  • A failed session-record or history fetch surfaces a localized error instead of silently exporting an empty file.

Scope

Self-contained: reuses the existing SessionStore::get_session / get_history and the existing session-state snapshot. No new persistence path, no other commands touched.

  • crates/aish-shell/src/app.rshandle_export_command + route.
  • crates/aish-shell/src/readline.rs/export popup entry.
  • crates/aish-i18n/locales/*shell.export.* + shell.slash.export (6 locales).

Verification

  • cargo clippy -p aish-shell --all-targets -- -D warnings clean.
  • slash_popup_commands tests pass (count + i18n descriptions).

Summary by CodeRabbit

  • New Features
    • Added an /export command to export the current session (conversation plus command history) as a Markdown file.
    • Accepts md or markdown format options and provides localized success and error messages.
  • Documentation
    • Added new localized help text and export workflow strings for /export in English, German, Spanish, French, Japanese, and Simplified Chinese.
  • Tests
    • Updated slash-command count expectations to include the new /export entry.

@github-actions

Copy link
Copy Markdown
Contributor

Thanks for the pull request. A maintainer will review it when available.

Please keep the PR focused, explain the why in the description, and make sure local checks pass before requesting review.

Contribution guide: https://github.com/AI-Shell-Team/aish/blob/main/CONTRIBUTING.md

@github-actions

Copy link
Copy Markdown
Contributor

This pull request description looks incomplete. Please update the missing sections below before review.

Missing items:

  • User-visible Changes
  • Compatibility
  • Testing
  • Change Type
  • Scope

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds /export [md] to export the current session, conversation snapshot, and command history as Markdown, with localized messages in six locales and updated slash-command count tests.

Changes

Session Markdown export

Layer / File(s) Summary
Command surface and localization
crates/aish-shell/src/readline.rs, crates/aish-shell/tests/slash_popup_commands.rs, crates/aish-i18n/locales/*
Registers /export, updates command-count assertions, and adds localized export help, templates, status messages, usage text, and errors.
Export workflow and file output
crates/aish-shell/src/app.rs
Routes /export, validates formats, loads session data and history, generates Markdown, and writes aish-session-<uuid_prefix>.md.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Shell
  participant SessionStore
  participant MarkdownFile
  User->>Shell: /export [md]
  Shell->>SessionStore: Load session and history
  SessionStore-->>Shell: Session data and history
  Shell->>MarkdownFile: Write Markdown export
  MarkdownFile-->>User: Report success or failure
Loading

Possibly related PRs

Suggested reviewers: f16shen

Poem

I’m a rabbit with Markdown to share,
/export hops through session air.
Chats and commands, neatly in rows,
Six tongues now tell where the archive goes.
Hop, write, done—what a tidy burrow!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly names the new /export shell feature and its Markdown export behavior.
Linked Issues check ✅ Passed The PR adds /export [md], exports metadata, conversation, and command history, and reports history/load failures.
Out of Scope Changes check ✅ Passed Changes stay within the export feature and its translations, tests, and command routing.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 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 `@crates/aish-shell/src/app.rs`:
- Around line 3416-3428: Update the history retrieval in the export flow around
store.get_history so it exports every command instead of limiting results to
10,000 entries. Page through all available rows or use an existing unbounded
store API, preserve the current error handling, and add coverage for sessions
containing more than 10,000 commands.
- Around line 3517-3540: Update the session export write flow around the
std::fs::write call so the generated file has owner-only permissions (0600) on
Unix. Ensure this is enforced for both newly created and existing/overwritten
files, while preserving the current success and write_failed reporting behavior.
🪄 Autofix (Beta)

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: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9fb27beb-4d15-4244-8eb6-d3ed58221344

📥 Commits

Reviewing files that changed from the base of the PR and between 78117a9 and 7348a22.

📒 Files selected for processing (9)
  • crates/aish-i18n/locales/de-DE.yaml
  • crates/aish-i18n/locales/en-US.yaml
  • crates/aish-i18n/locales/es-ES.yaml
  • crates/aish-i18n/locales/fr-FR.yaml
  • crates/aish-i18n/locales/ja-JP.yaml
  • crates/aish-i18n/locales/zh-CN.yaml
  • crates/aish-shell/src/app.rs
  • crates/aish-shell/src/readline.rs
  • crates/aish-shell/tests/slash_popup_commands.rs

Comment thread crates/aish-shell/src/app.rs Outdated
Comment thread crates/aish-shell/src/app.rs

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 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 `@crates/aish-i18n/locales/es-ES.yaml`:
- Line 573: Update handle_export_command to render shell.export.forked_label
with the session’s parent/fork source whenever a parent exists, so exported
Markdown includes the fork-source metadata; leave exports without a parent
unchanged.
🪄 Autofix (Beta)

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: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1293380a-a9f4-48a1-b70e-f91b649365fc

📥 Commits

Reviewing files that changed from the base of the PR and between 7348a22 and 285788c.

📒 Files selected for processing (9)
  • crates/aish-i18n/locales/de-DE.yaml
  • crates/aish-i18n/locales/en-US.yaml
  • crates/aish-i18n/locales/es-ES.yaml
  • crates/aish-i18n/locales/fr-FR.yaml
  • crates/aish-i18n/locales/ja-JP.yaml
  • crates/aish-i18n/locales/zh-CN.yaml
  • crates/aish-shell/src/app.rs
  • crates/aish-shell/src/readline.rs
  • crates/aish-shell/tests/slash_popup_commands.rs
🚧 Files skipped from review as they are similar to previous changes (8)
  • crates/aish-shell/src/readline.rs
  • crates/aish-shell/tests/slash_popup_commands.rs
  • crates/aish-i18n/locales/en-US.yaml
  • crates/aish-i18n/locales/zh-CN.yaml
  • crates/aish-i18n/locales/ja-JP.yaml
  • crates/aish-i18n/locales/de-DE.yaml
  • crates/aish-i18n/locales/fr-FR.yaml
  • crates/aish-shell/src/app.rs

session_label: "- **sesión**: `{uuid}`"
model_label: "- **modelo**: {model}"
api_base_label: "- **api_base**: {base}"
forked_label: "- **bifurcada de**: `{parent}`"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Render the fork-source metadata in the export handler.

shell.export.forked_label is defined here, but handle_export_command does not call this key or emit the session’s parent/fork source. The exported Markdown therefore omits metadata required by issue #411; render it when a parent exists.

🤖 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 `@crates/aish-i18n/locales/es-ES.yaml` at line 573, Update
handle_export_command to render shell.export.forked_label with the session’s
parent/fork source whenever a parent exists, so exported Markdown includes the
fork-source metadata; leave exports without a parent unchanged.

`/export [md]` writes the current session — metadata (uuid/model/api_base/
created/working dir), the AI conversation, and the command history table —
to `aish-session-<short>.md` for postmortem or sharing.

- History-table cells escape `|`, newlines, and backticks so commands
  containing them render correctly.
- A failed session-record or history fetch surfaces a localized error
  instead of silently exporting an empty file.

Reuses the existing SessionStore get_session/get_history and the session
state snapshot; no new persistence path.

Closes AI-Shell-Team#411
@jexShain
jexShain force-pushed the feat/export-session branch from 285788c to 38fd483 Compare July 29, 2026 08:25

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 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 `@crates/aish-i18n/locales/ja-JP.yaml`:
- Line 657: Add conditional fork-source metadata output in handle_export_command
using shell.export.forked_label and the session’s parent/fork source, so
exported Markdown includes it only when a parent exists.
🪄 Autofix (Beta)

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: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 24da020c-a08a-45d3-bcbe-56e6d9a22585

📥 Commits

Reviewing files that changed from the base of the PR and between 285788c and 38fd483.

📒 Files selected for processing (9)
  • crates/aish-i18n/locales/de-DE.yaml
  • crates/aish-i18n/locales/en-US.yaml
  • crates/aish-i18n/locales/es-ES.yaml
  • crates/aish-i18n/locales/fr-FR.yaml
  • crates/aish-i18n/locales/ja-JP.yaml
  • crates/aish-i18n/locales/zh-CN.yaml
  • crates/aish-shell/src/app.rs
  • crates/aish-shell/src/readline.rs
  • crates/aish-shell/tests/slash_popup_commands.rs
🚧 Files skipped from review as they are similar to previous changes (8)
  • crates/aish-shell/tests/slash_popup_commands.rs
  • crates/aish-shell/src/readline.rs
  • crates/aish-i18n/locales/en-US.yaml
  • crates/aish-i18n/locales/zh-CN.yaml
  • crates/aish-i18n/locales/es-ES.yaml
  • crates/aish-i18n/locales/de-DE.yaml
  • crates/aish-i18n/locales/fr-FR.yaml
  • crates/aish-shell/src/app.rs

session_label: "- **セッション**: `{uuid}`"
model_label: "- **モデル**: {model}"
api_base_label: "- **api_base**: {base}"
forked_label: "- **フォーク元**: `{parent}`"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Emit the fork source in the export.

handle_export_command in crates/aish-shell/src/app.rs:3495-3664 never reads shell.export.forked_label, so this translation is currently unused and exported Markdown omits the required fork-source metadata. Add the corresponding conditional output for the session’s parent/fork source.

🤖 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 `@crates/aish-i18n/locales/ja-JP.yaml` at line 657, Add conditional fork-source
metadata output in handle_export_command using shell.export.forked_label and the
session’s parent/fork source, so exported Markdown includes it only when a
parent exists.

@jexShain
jexShain merged commit 4820eed into AI-Shell-Team:main Jul 29, 2026
8 checks passed
@jexShain
jexShain deleted the feat/export-session branch July 29, 2026 09:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: /export 导出当前会话为 Markdown

1 participant