Skip to content

feat(slides): add history rollback shortcuts#1714

Merged
liuxin-0319 merged 1 commit into
mainfrom
feat/slides_revert
Jul 20, 2026
Merged

feat(slides): add history rollback shortcuts#1714
liuxin-0319 merged 1 commit into
mainfrom
feat/slides_revert

Conversation

@liuxin-0319

@liuxin-0319 liuxin-0319 commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add slides +history-list, slides +history-revert, and slides +history-revert-status shortcuts
  • support wiki URL resolution before calling Slides AI history OpenAPI endpoints
  • document safe history rollback workflow and add unit/E2E dry-run coverage

Tests

  • go test ./shortcuts/slides -run 'TestSlidesHistory'\n- go test ./tests/cli_e2e/slides -run 'TestSlidesHistoryDryRunE2E'\n\n## Notes\n- live workflow test is gated by LARK_SLIDES_HISTORY_E2E=1 and was not run in this PR flow\n

Summary by CodeRabbit

  • New Features
    • Added Slides history shortcuts: +history-list, +history-revert, and +history-revert-status, including wiki-backed presentation support.
  • Documentation
    • Expanded skill help and added lark-slides-history reference covering the rollback workflow and required history_version_id.
  • Bug Fixes
    • Improved input validation (pagination and history version constraints) and ensured revert requests omit wait_timeout_ms.
  • Tests
    • Added dry-run and gated end-to-end workflow coverage for list → revert → status, including wiki resolution and task status polling.

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds Slides CLI shortcuts for listing presentation history, reverting by history_version_id, and checking revert status. It includes wiki presentation resolution, validation, unit and end-to-end coverage, registration, and skill documentation.

Changes

Slides history shortcuts

Layer / File(s) Summary
Shared history request handling
shortcuts/slides/slides_history.go
Adds input parsing, scope enforcement, validation, request construction, and wiki presentation resolution.
History shortcut commands and registration
shortcuts/slides/slides_history.go, shortcuts/slides/shortcuts.go
Implements list, revert, and revert-status API calls and registers the shortcuts.
Shortcut behavior tests
shortcuts/slides/slides_history_test.go
Covers scopes, validation, dry-run requests, wiki resolution, and executed responses.
Skill history guidance
skills/lark-slides/SKILL.md, skills/lark-slides/references/lark-slides-history.md
Documents history selection, rollback, polling, response handling, and verification.
End-to-end history workflow coverage
tests/cli_e2e/slides/slides_history_*_test.go
Tests dry-run requests and a gated live workflow for creating, modifying, listing, reverting, polling, and verifying presentation history.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI as Slides CLI
    participant Wiki as Wiki API
    participant Slides as Slides API

    User->>CLI: Run history command
    CLI->>CLI: Validate arguments
    alt wiki presentation
        CLI->>Wiki: Resolve node
        Wiki-->>CLI: Return presentation token
    end
    alt List history
        CLI->>Slides: GET histories
        Slides-->>CLI: Return history entries
    else Revert history
        CLI->>Slides: POST history revert
        Slides-->>CLI: Return task status
    else Check revert status
        CLI->>Slides: GET revert status
        Slides-->>CLI: Return task status
    end
    CLI-->>User: Output API response
Loading

Possibly related PRs

Suggested labels: feature

Suggested reviewers: fangshuyu-768, liangshuo-1, vipercai

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding Slides history rollback shortcuts.
Description check ✅ Passed The description covers the change summary and verification, but it doesn't follow the template exactly and omits explicit Changes and Related Issues sections.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/slides_revert

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.

@github-actions github-actions Bot added the size/L Large or sensitive change across domains or core paths label Jul 2, 2026
@codecov

codecov Bot commented Jul 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 78.84615% with 33 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.00%. Comparing base (4084091) to head (deb3327).

Files with missing lines Patch % Lines
shortcuts/slides/slides_history.go 80.39% 15 Missing and 15 partials ⚠️
shortcuts/slides/shortcuts.go 0.00% 3 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##             main    #1714    +/-   ##
========================================
  Coverage   75.00%   75.00%            
========================================
  Files         898      899     +1     
  Lines       94912    95068   +156     
========================================
+ Hits        71184    71307   +123     
- Misses      18269    18287    +18     
- Partials     5459     5474    +15     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

npm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@deb33275e83931f94cc1a741cc6de6a406f82869

🧩 Skill update

npx skills add larksuite/cli#feat/slides_revert -y -g

@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

🧹 Nitpick comments (4)
tests/cli_e2e/slides/slides_history_dryrun_test.go (1)

46-59: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Zero-value assertion can't distinguish "field present as 0" from "field missing".

gjson.Get(stdout, "api.0.body.wait_timeout_ms").Int() returns 0 both when the field is present with value 0 and when the path doesn't exist. If the request struct ever adds omitempty on wait_timeout_ms (or the value is dropped some other way), this assertion would keep passing even though the field silently disappeared from the request body. Recommend also asserting .Exists() for this zero-value case.

🔧 Suggested strengthening
 assertion: func(t *testing.T, stdout string) {
 	require.Equal(t, "42", gjson.Get(stdout, "api.0.body.history_version_id").String(), stdout)
-	require.Equal(t, int64(0), gjson.Get(stdout, "api.0.body.wait_timeout_ms").Int(), stdout)
+	waitTimeout := gjson.Get(stdout, "api.0.body.wait_timeout_ms")
+	require.True(t, waitTimeout.Exists(), "wait_timeout_ms missing from body: %s", stdout)
+	require.Equal(t, int64(0), waitTimeout.Int(), stdout)
 },
🤖 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 `@tests/cli_e2e/slides/slides_history_dryrun_test.go` around lines 46 - 59,
Strengthen the zero-value check in the slides history dry-run test so it
verifies both presence and value of wait_timeout_ms. In the assertion for the
revert case, update the gjson-based check on stdout to confirm the path exists
before asserting it equals 0, using the existing assertion block in
slides_history_dryrun_test.go and the api.0.body.wait_timeout_ms field to keep
the test from passing if the field is omitted.
tests/cli_e2e/slides/slides_history_workflow_test.go (2)

20-28: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Tight 3-minute context budget vs. cumulative retry/wait timeouts risks flaky failures.

The shared ctx (line 27) has a 3-minute deadline and is passed to every RunCmd call in the test. The retry loops alone can consume up to 45s (history-list Eventually, line 138) + 30s (--wait-timeout-ms 30000 synchronous wait inside +history-revert, line 146) + 60s (revert-status Eventually, line 172) = 135s, leaving only ~45s of margin for +create, two api get fetches, +replace-pages, and the final api get fetch. If any step runs slower than usual, the shared ctx can expire mid-poll, causing RunCmd/require.NoError failures unrelated to the actual revert logic and producing misleading failure messages.

Consider increasing the ctx timeout (e.g., to 5 minutes) to give real margin over the sum of the retry/wait budgets, since this is an opt-in live E2E test where flakiness costs debugging time rather than CI throughput.

Also applies to: 116-173

🤖 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 `@tests/cli_e2e/slides/slides_history_workflow_test.go` around lines 20 - 28,
The shared timeout in TestSlides_HistoryWorkflow is too tight for the cumulative
retry and wait budgets used by the RunCmd steps, which can cause unrelated
context-deadline failures. Increase the context deadline created with
context.WithTimeout in TestSlides_HistoryWorkflow to give enough margin for all
eventual/retry waits, and keep using that ctx for the existing RunCmd and
require checks so the live E2E flow remains stable under slower conditions.

117-138: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Swallowed errors reduce debuggability on Eventually failure.

Both retry closures discard listErr/statusErr on failure paths (returning false without recording them). If the loop times out, the failure message only says "did not expose..."/"did not finish" without the underlying CLI error, making root-causing flaky runs harder. Consider capturing the last error/exit code and including it in the require.Eventually failure message.

Also applies to: 158-172

🤖 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 `@tests/cli_e2e/slides/slides_history_workflow_test.go` around lines 117 - 138,
The retry closures in the slide history workflow tests are swallowing CLI
failures, so `require.Eventually` times out without the underlying error
context. Update the `slides_history_workflow_test.go` logic around the `slides
+history-list` and related status checks to record the last
`listErr`/`statusErr` and non-zero exit code, then include that captured detail
in the final `require.Eventually` failure message. Use the existing
`require.Eventually` blocks and the `RunCmd` calls as the places to preserve and
surface the error for debugging.
shortcuts/slides/slides_history_test.go (1)

343-383: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding a negative test for wiki resolution to a non-slides node.

TestSlidesHistoryExecuteResolvesWikiPresentation only covers the happy path where obj_type == "slides". A test asserting the behavior when a wiki node resolves to a different obj_type (e.g., doc) would guard the resolution logic referenced in slides_history.go against regressions on this realistic user error path.

🤖 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 `@shortcuts/slides/slides_history_test.go` around lines 343 - 383, Add a
negative test around SlidesHistoryList wiki resolution to cover non-slides
nodes: extend the existing resolution flow in
TestSlidesHistoryExecuteResolvesWikiPresentation or add a sibling test that
stubs /open-apis/wiki/v2/spaces/get_node to return an obj_type other than
"slides" (for example "doc"), then verify runSlidesShortcut returns the expected
error and does not proceed to fetch histories. Use the SlidesHistoryList path
and the wiki node resolution logic in slides_history.go to locate the behavior
under test.
🤖 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 `@shortcuts/slides/slides_history_test.go`:
- Around line 106-128: The validation error test in the slides history suite
only checks that the error is typed and matches Param, but it does not verify
the full typed metadata or wrapped cause. Update the test cases in the
`runSlidesShortcut` loop to inspect the `errs.ProblemOf` result for `Category`,
`Subtype`, and `Param`, and add assertions that the original cause is preserved
with `errors.Is` and/or `errors.Unwrap`. Keep using `errs.ValidationError` and
`errs.ProblemOf` to locate the error shape, but strengthen the checks so the
error-path coverage matches the test guidelines.

In `@shortcuts/slides/slides_history.go`:
- Around line 45-65: The three validators in validateSlidesHistoryPageSize,
validateSlidesHistoryVersionID, and validateSlidesHistoryWaitTimeout are putting
recovery guidance into the main error text instead of using .WithHint(...).
Update each errs.NewValidationError call so the message only states the invalid
input and keep the user-facing guidance like the valid range or “returned by
slides +history-list” in a separate .WithHint(...) on the returned error.

---

Nitpick comments:
In `@shortcuts/slides/slides_history_test.go`:
- Around line 343-383: Add a negative test around SlidesHistoryList wiki
resolution to cover non-slides nodes: extend the existing resolution flow in
TestSlidesHistoryExecuteResolvesWikiPresentation or add a sibling test that
stubs /open-apis/wiki/v2/spaces/get_node to return an obj_type other than
"slides" (for example "doc"), then verify runSlidesShortcut returns the expected
error and does not proceed to fetch histories. Use the SlidesHistoryList path
and the wiki node resolution logic in slides_history.go to locate the behavior
under test.

In `@tests/cli_e2e/slides/slides_history_dryrun_test.go`:
- Around line 46-59: Strengthen the zero-value check in the slides history
dry-run test so it verifies both presence and value of wait_timeout_ms. In the
assertion for the revert case, update the gjson-based check on stdout to confirm
the path exists before asserting it equals 0, using the existing assertion block
in slides_history_dryrun_test.go and the api.0.body.wait_timeout_ms field to
keep the test from passing if the field is omitted.

In `@tests/cli_e2e/slides/slides_history_workflow_test.go`:
- Around line 20-28: The shared timeout in TestSlides_HistoryWorkflow is too
tight for the cumulative retry and wait budgets used by the RunCmd steps, which
can cause unrelated context-deadline failures. Increase the context deadline
created with context.WithTimeout in TestSlides_HistoryWorkflow to give enough
margin for all eventual/retry waits, and keep using that ctx for the existing
RunCmd and require checks so the live E2E flow remains stable under slower
conditions.
- Around line 117-138: The retry closures in the slide history workflow tests
are swallowing CLI failures, so `require.Eventually` times out without the
underlying error context. Update the `slides_history_workflow_test.go` logic
around the `slides +history-list` and related status checks to record the last
`listErr`/`statusErr` and non-zero exit code, then include that captured detail
in the final `require.Eventually` failure message. Use the existing
`require.Eventually` blocks and the `RunCmd` calls as the places to preserve and
surface the error for debugging.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: fd3fd404-7459-4fdb-bf02-e8803e08359e

📥 Commits

Reviewing files that changed from the base of the PR and between 462358a and c0a961d.

📒 Files selected for processing (7)
  • shortcuts/slides/shortcuts.go
  • shortcuts/slides/slides_history.go
  • shortcuts/slides/slides_history_test.go
  • skills/lark-slides/SKILL.md
  • skills/lark-slides/references/lark-slides-history.md
  • tests/cli_e2e/slides/slides_history_dryrun_test.go
  • tests/cli_e2e/slides/slides_history_workflow_test.go

Comment thread shortcuts/slides/slides_history_test.go
Comment thread shortcuts/slides/slides_history.go
@liuxin-0319
liuxin-0319 force-pushed the feat/slides_revert branch 2 times, most recently from d526aed to fd365a1 Compare July 13, 2026 13:34

@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 `@skills/lark-slides/references/lark-slides-history.md`:
- Around line 29-30: Clarify the edit_time representation in the history
matching guidance and examples. Update the instructions near the edit_time
matching references and the JSON return example so they consistently use one
format, or explicitly state that the CLI converts Unix timestamps to ISO 8601
for display while matching uses the original timestamp value.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5bb8a2ab-a9b1-401f-8b50-49df62a06a34

📥 Commits

Reviewing files that changed from the base of the PR and between d526aed and fd365a1.

📒 Files selected for processing (7)
  • shortcuts/slides/shortcuts.go
  • shortcuts/slides/slides_history.go
  • shortcuts/slides/slides_history_test.go
  • skills/lark-slides/SKILL.md
  • skills/lark-slides/references/lark-slides-history.md
  • tests/cli_e2e/slides/slides_history_dryrun_test.go
  • tests/cli_e2e/slides/slides_history_workflow_test.go
🚧 Files skipped from review as they are similar to previous changes (6)
  • shortcuts/slides/shortcuts.go
  • tests/cli_e2e/slides/slides_history_dryrun_test.go
  • skills/lark-slides/SKILL.md
  • tests/cli_e2e/slides/slides_history_workflow_test.go
  • shortcuts/slides/slides_history.go
  • shortcuts/slides/slides_history_test.go

Comment thread skills/lark-slides/references/lark-slides-history.md
@liuxin-0319
liuxin-0319 force-pushed the feat/slides_revert branch 3 times, most recently from 0a9d282 to 375c73c Compare July 20, 2026 06:07
Comment thread skills/lark-slides/references/lark-slides-history.md
fangshuyu-768
fangshuyu-768 previously approved these changes Jul 20, 2026
# Conflicts:
#	skills/lark-slides/SKILL.md
@liuxin-0319
liuxin-0319 merged commit ad4a6d6 into main Jul 20, 2026
26 checks passed
@liuxin-0319
liuxin-0319 deleted the feat/slides_revert branch July 20, 2026 14:27
@liangshuo-1 liangshuo-1 mentioned this pull request Jul 21, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/L Large or sensitive change across domains or core paths

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants