Skip to content

feat(slides): add history rollback shortcuts#1714

Open
liuxin-0319 wants to merge 2 commits into
mainfrom
feat/slides_revert
Open

feat(slides): add history rollback shortcuts#1714
liuxin-0319 wants to merge 2 commits 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 slide history commands to list XML history versions, revert to a chosen history_version_id, and check revert task status.
    • Expanded CLI help and updated reference docs with a guided, safer rollback workflow (including wiki link handling).
  • Bug Fixes
    • Added stricter argument validation for page size, history_version_id, wait timeout, and task id.
  • Tests
    • Introduced dry-run and gated end-to-end coverage for the full history list → revert → status workflow.

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5c42dbd1-0f59-4242-84e8-119992473f2e

📥 Commits

Reviewing files that changed from the base of the PR and between c0a961d and 40a828c.

📒 Files selected for processing (1)
  • shortcuts/slides/slides_history_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • shortcuts/slides/slides_history_test.go

📝 Walkthrough

Walkthrough

This PR adds three new slides CLI shortcuts for listing history, reverting to a history version, and checking revert status, along with shared validation/helpers, tests, and updated slide skill documentation.

Changes

Slides history shortcuts implementation and validation

Layer / File(s) Summary
Shared helpers and spec structs
shortcuts/slides/slides_history.go
Defines pagination, revert, and status spec structs and adds helpers for presentation parsing, input validation, API path construction, and wiki resolution.
+history-list shortcut and registration
shortcuts/slides/slides_history.go, shortcuts/slides/shortcuts.go
Implements the list shortcut’s dry-run and execute paths and adds the new history shortcuts to the exported shortcuts slice.
+history-revert shortcut
shortcuts/slides/slides_history.go
Implements the revert shortcut’s validation, dry-run request body, and execute path for posting a history revert request.
+history-revert-status shortcut
shortcuts/slides/slides_history.go
Implements the revert-status shortcut’s validation, dry-run request shape, and execute path for polling revert task state.
Unit tests for history shortcuts
shortcuts/slides/slides_history_test.go
Adds shortcut tests for declared scopes, validation errors, dry-run construction, wiki presentation resolution, and execute behavior with HTTP stubs.
Skill docs and history reference
skills/lark-slides/SKILL.md, skills/lark-slides/references/lark-slides-history.md
Updates the slide skill help text and rollback guidance, and adds a new history reference document covering list, revert, status, and verification steps.
E2E dry-run coverage
tests/cli_e2e/slides/slides_history_dryrun_test.go
Adds dry-run e2e coverage for the list, revert, and revert-status shortcuts plus the environment setup helper.
E2E history workflow
tests/cli_e2e/slides/slides_history_workflow_test.go
Adds the end-to-end workflow test that creates a presentation, replaces content, lists history, reverts a version, polls status, and verifies restored content, with XML and JSON payload helpers.

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: +history-list / +history-revert / +history-revert-status
    CLI->>CLI: validate args and build request data
    alt wiki presentation URL
        CLI->>Wiki: resolve wiki node
        Wiki-->>CLI: slides presentation token
    end
    alt +history-list
        CLI->>Slides: GET histories
        Slides-->>CLI: history list response
    else +history-revert
        CLI->>Slides: POST history/revert
        Slides-->>CLI: task_id and status
    else +history-revert-status
        CLI->>Slides: GET history/revert_status
        Slides-->>CLI: revert task status
    end
    CLI-->>User: raw API response
Loading

Possibly related PRs

  • larksuite/cli#389: Both PRs modify shortcuts/slides/shortcuts.go by extending the slides shortcut registration list.
  • larksuite/cli#1358: Both PRs add more slides CLI shortcut coverage in the same command registration area.

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 summary and tests, but it omits the template's 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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 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 79.50311% with 33 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.53%. Comparing base (462358a) to head (40a828c).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
shortcuts/slides/slides_history.go 81.01% 15 Missing and 15 partials ⚠️
shortcuts/slides/shortcuts.go 0.00% 3 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##             main    #1714    +/-   ##
========================================
  Coverage   74.52%   74.53%            
========================================
  Files         851      852     +1     
  Lines       87155    87316   +161     
========================================
+ Hits        64952    65080   +128     
- Misses      17231    17249    +18     
- Partials     4972     4987    +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@40a828cb5e1942d109e4ea24d59e66e7b03fdbde

🧩 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 on lines +106 to +128
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

f, stdout, _, _ := cmdutil.TestFactory(t, slidesTestConfig(t, ""))
err := runSlidesShortcut(t, f, stdout, tt.shortcut, tt.args)
if err == nil {
t.Fatal("expected validation error, got nil")
}
_, ok := errs.ProblemOf(err)
if !ok {
t.Fatalf("error is not typed: %T %v", err, err)
}
var validationErr *errs.ValidationError
if !errors.As(err, &validationErr) {
t.Fatalf("expected validation error, got %T: %v", err, err)
}
if validationErr.Param != tt.param {
t.Fatalf("param = %q, want %q (err: %v)", validationErr.Param, tt.param, err)
}
})
}
}

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 | 🟡 Minor | ⚡ Quick win

Validation tests don't assert category/subtype or cause preservation.

Per the coding guideline for **/*_test.go files, error-path tests should assert typed metadata via errs.ProblemOf covering category/subtype/param, plus cause preservation — not just message/param. Here, only Param is checked (via errors.As + ValidationError), and the errs.ProblemOf call at Line 115 is only used to confirm the error is typed (ok), without inspecting Category or Subtype. Cause preservation (errors.Is/errors.Unwrap) is also not asserted.

✅ Suggested strengthening
 			_, ok := errs.ProblemOf(err)
 			if !ok {
 				t.Fatalf("error is not typed: %T %v", err, err)
 			}
+			if problem, _ := errs.ProblemOf(err); problem.Category != errs.CategoryValidation {
+				t.Fatalf("category = %v, want validation", problem.Category)
+			}
 			var validationErr *errs.ValidationError
 			if !errors.As(err, &validationErr) {
 				t.Fatalf("expected validation error, got %T: %v", err, err)
 			}
 			if validationErr.Param != tt.param {
 				t.Fatalf("param = %q, want %q (err: %v)", validationErr.Param, tt.param, err)
 			}

Based on coding guidelines, **/*_test.go: "Error-path tests must assert typed metadata via errs.ProblemOf (category / subtype / param) and cause preservation, not message substrings alone".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
f, stdout, _, _ := cmdutil.TestFactory(t, slidesTestConfig(t, ""))
err := runSlidesShortcut(t, f, stdout, tt.shortcut, tt.args)
if err == nil {
t.Fatal("expected validation error, got nil")
}
_, ok := errs.ProblemOf(err)
if !ok {
t.Fatalf("error is not typed: %T %v", err, err)
}
var validationErr *errs.ValidationError
if !errors.As(err, &validationErr) {
t.Fatalf("expected validation error, got %T: %v", err, err)
}
if validationErr.Param != tt.param {
t.Fatalf("param = %q, want %q (err: %v)", validationErr.Param, tt.param, err)
}
})
}
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
f, stdout, _, _ := cmdutil.TestFactory(t, slidesTestConfig(t, ""))
err := runSlidesShortcut(t, f, stdout, tt.shortcut, tt.args)
if err == nil {
t.Fatal("expected validation error, got nil")
}
_, ok := errs.ProblemOf(err)
if !ok {
t.Fatalf("error is not typed: %T %v", err, err)
}
if problem, _ := errs.ProblemOf(err); problem.Category != errs.CategoryValidation {
t.Fatalf("category = %v, want validation", problem.Category)
}
var validationErr *errs.ValidationError
if !errors.As(err, &validationErr) {
t.Fatalf("expected validation error, got %T: %v", err, err)
}
if validationErr.Param != tt.param {
t.Fatalf("param = %q, want %q (err: %v)", validationErr.Param, tt.param, err)
}
})
}
}
🤖 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 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.

Source: Coding guidelines

Comment on lines +45 to +65
func validateSlidesHistoryPageSize(pageSize int) error {
if pageSize < 1 || pageSize > 20 {
return errs.NewValidationError(errs.SubtypeInvalidArgument, "invalid --page-size %d: must be between 1 and 20", pageSize).WithParam("--page-size")
}
return nil
}

func validateSlidesHistoryVersionID(historyVersionID string) error {
version, err := strconv.ParseInt(strings.TrimSpace(historyVersionID), 10, 64)
if err != nil || version <= 0 {
return errs.NewValidationError(errs.SubtypeInvalidArgument, "--history-version-id must be a positive integer string returned by slides +history-list").WithParam("--history-version-id")
}
return nil
}

func validateSlidesHistoryWaitTimeout(timeoutMs int) error {
if timeoutMs < 0 || timeoutMs > 30000 {
return errs.NewValidationError(errs.SubtypeInvalidArgument, "invalid --wait-timeout-ms %d: must be between 0 and 30000", timeoutMs).WithParam("--wait-timeout-ms")
}
return nil
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Move recovery guidance into .WithHint(...).

All three validators embed the "must be between X and Y" / "returned by slides +history-list" guidance directly in the error message instead of using .WithHint(...).

🔧 Proposed fix
 func validateSlidesHistoryPageSize(pageSize int) error {
 	if pageSize < 1 || pageSize > 20 {
-		return errs.NewValidationError(errs.SubtypeInvalidArgument, "invalid --page-size %d: must be between 1 and 20", pageSize).WithParam("--page-size")
+		return errs.NewValidationError(errs.SubtypeInvalidArgument, "invalid --page-size %d", pageSize).
+			WithParam("--page-size").
+			WithHint("must be between 1 and 20")
 	}
 	return nil
 }

 func validateSlidesHistoryVersionID(historyVersionID string) error {
 	version, err := strconv.ParseInt(strings.TrimSpace(historyVersionID), 10, 64)
 	if err != nil || version <= 0 {
-		return errs.NewValidationError(errs.SubtypeInvalidArgument, "--history-version-id must be a positive integer string returned by slides +history-list").WithParam("--history-version-id")
+		return errs.NewValidationError(errs.SubtypeInvalidArgument, "--history-version-id must be a positive integer string").
+			WithParam("--history-version-id").
+			WithHint("use the history_version_id returned by slides +history-list")
 	}
 	return nil
 }

 func validateSlidesHistoryWaitTimeout(timeoutMs int) error {
 	if timeoutMs < 0 || timeoutMs > 30000 {
-		return errs.NewValidationError(errs.SubtypeInvalidArgument, "invalid --wait-timeout-ms %d: must be between 0 and 30000", timeoutMs).WithParam("--wait-timeout-ms")
+		return errs.NewValidationError(errs.SubtypeInvalidArgument, "invalid --wait-timeout-ms %d", timeoutMs).
+			WithParam("--wait-timeout-ms").
+			WithHint("must be between 0 and 30000")
 	}
 	return nil
 }

As per coding guidelines: "param field in errors should only name the user input that actually failed; recovery guidance goes in .WithHint(...)".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func validateSlidesHistoryPageSize(pageSize int) error {
if pageSize < 1 || pageSize > 20 {
return errs.NewValidationError(errs.SubtypeInvalidArgument, "invalid --page-size %d: must be between 1 and 20", pageSize).WithParam("--page-size")
}
return nil
}
func validateSlidesHistoryVersionID(historyVersionID string) error {
version, err := strconv.ParseInt(strings.TrimSpace(historyVersionID), 10, 64)
if err != nil || version <= 0 {
return errs.NewValidationError(errs.SubtypeInvalidArgument, "--history-version-id must be a positive integer string returned by slides +history-list").WithParam("--history-version-id")
}
return nil
}
func validateSlidesHistoryWaitTimeout(timeoutMs int) error {
if timeoutMs < 0 || timeoutMs > 30000 {
return errs.NewValidationError(errs.SubtypeInvalidArgument, "invalid --wait-timeout-ms %d: must be between 0 and 30000", timeoutMs).WithParam("--wait-timeout-ms")
}
return nil
}
func validateSlidesHistoryPageSize(pageSize int) error {
if pageSize < 1 || pageSize > 20 {
return errs.NewValidationError(errs.SubtypeInvalidArgument, "invalid --page-size %d", pageSize).
WithParam("--page-size").
WithHint("must be between 1 and 20")
}
return nil
}
func validateSlidesHistoryVersionID(historyVersionID string) error {
version, err := strconv.ParseInt(strings.TrimSpace(historyVersionID), 10, 64)
if err != nil || version <= 0 {
return errs.NewValidationError(errs.SubtypeInvalidArgument, "--history-version-id must be a positive integer string").
WithParam("--history-version-id").
WithHint("use the history_version_id returned by slides +history-list")
}
return nil
}
func validateSlidesHistoryWaitTimeout(timeoutMs int) error {
if timeoutMs < 0 || timeoutMs > 30000 {
return errs.NewValidationError(errs.SubtypeInvalidArgument, "invalid --wait-timeout-ms %d", timeoutMs).
WithParam("--wait-timeout-ms").
WithHint("must be between 0 and 30000")
}
return nil
}
🤖 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.go` around lines 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.

Source: Coding guidelines

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.

1 participant