Skip to content

feat: support lark suite hybrid skills layout#1772

Open
Tantanz20020918 wants to merge 8 commits into
mainfrom
feat/lark-suite-skill
Open

feat: support lark suite hybrid skills layout#1772
Tantanz20020918 wants to merge 8 commits into
mainfrom
feat/lark-suite-skill

Conversation

@Tantanz20020918

@Tantanz20020918 Tantanz20020918 commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Summary

Add layout-aware official skill sync so users can keep the default flat separate layout or use hybrid to route non-flat Lark skills through lark-suite. The suite template is fetched from an isolated source and assembled from the actually installed official skills during update.

Changes

  • Add lark-cli update --skills-layout separate|hybrid and --flat-skills handling.
  • Persist layout, flat skill intent, official skill list, and user-deleted skills in skills-state.json.
  • Fetch lark-suite from the isolated skills source with GitHub fallback when hybrid layout is used.
  • Dynamically assemble lark-suite/references/subskills and generate suite routes from subskill descriptions.
  • Keep lark-shared available inside suite, and additionally at top level when hybrid keeps other flat skills.

Test Plan

  • go test ./internal/selfupdate ./internal/skillscheck ./cmd/update
  • go test ./internal/skillscheck -run TestSyncSkills_HybridCollectsNewOfficialSkillOnNextUpdate -count=1
  • Manual verification with test isolated skills source: hybrid install/update, lark-suite content, deleted flat skill, deleted suite subskill, and state updates

Related Issues

  • None

Summary by CodeRabbit

  • New Features
    • Added skills-sync options to choose layout (separate/hybrid) and optionally filter with --flat-skills.
    • Hybrid sync now assembles the suite automatically and persists the effective layout/flat selection for future updates.
    • Suite-based skill installation added with an automatic fallback retry for improved reliability.
  • Bug Fixes
    • Improved “already synced” and dedup behavior to correctly account for previously saved layout/flat settings.
    • Enhanced output details and failure hints to include effective layout and flat/filter context.
  • Documentation
    • Added guidance for the suite skill routing/usage behavior and its layout rules.

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

coderabbitai Bot commented Jul 7, 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 layout-aware skills syncing and persistence, suite installation and assembly, update-command layout flags and reporting, and lark-suite routing documentation.

Changes

Skills Layout Support

Layer / File(s) Summary
State and layout contracts
internal/skillscheck/state.go, internal/skillscheck/layout.go
Adds layout fields and helpers for state, layout normalization, flat-skills parsing, global-skill JSON parsing, and suite/layout utility functions.
Isolated suite installer
internal/selfupdate/updater.go, internal/selfupdate/updater_test.go
Adds isolated source URLs and InstallSuiteSkill() with fallback behavior, with tests covering expected args and retry flow.
Suite assembly and route rendering
isolated-skills/lark-suite/SKILL.md, internal/skillscheck/layout.go
Adds the lark-suite skill document and builds suite layout on disk, rewrites route placeholders, normalizes template text, parses skill descriptions, and copies/moves files for suite assembly.
Layout-aware sync pipeline
internal/skillscheck/sync.go, internal/skillscheck/sync_test.go
Extends sync planning and execution for separate/hybrid layouts, suite installation, persisted layout state, hybrid resolution, and supporting tests/helpers.
Update command wiring and reporting
cmd/update/update.go, cmd/update/update_test.go
Adds update flags and validation, threads layout inputs through sync calls, and expands status, summary, and hint output with layout-aware fields.

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

Possibly related PRs

  • larksuite/cli#965: Both touch the same skills-sync/state pipeline and persisted state handling.
  • larksuite/cli#1008: Both modify the core skills sync flow and state/sync orchestration in internal/skillscheck.
  • larksuite/cli#1042: This PR extends the state-based incremental sync flow introduced there with layout and flat-skills support.

Suggested labels: feature

Suggested reviewers: MaxHuang22, liangshuo-1, sang-neo03

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
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.
Title check ✅ Passed The title is concise and accurately reflects the main change: adding hybrid skills layout support for lark suite.
Description check ✅ Passed The description follows the required template and includes summary, changes, test plan, and related issues.
✨ 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/lark-suite-skill

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.

@codecov

codecov Bot commented Jul 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.83938% with 128 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.42%. Comparing base (a1506cd) to head (9ea42d1).
⚠️ Report is 9 commits behind head on main.

Files with missing lines Patch % Lines
internal/skillscheck/layout.go 67.08% 47 Missing and 31 partials ⚠️
internal/skillscheck/sync.go 58.82% 27 Missing and 8 partials ⚠️
cmd/update/update.go 88.46% 1 Missing and 5 partials ⚠️
internal/skillscheck/state.go 28.57% 5 Missing ⚠️
internal/selfupdate/updater.go 20.00% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1772      +/-   ##
==========================================
- Coverage   74.42%   74.42%   -0.01%     
==========================================
  Files         854      856       +2     
  Lines       88457    88926     +469     
==========================================
+ Hits        65832    66180     +348     
- Misses      17556    17629      +73     
- Partials     5069     5117      +48     

☔ 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 7, 2026

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

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

🧩 Skill update

npx skills add larksuite/cli#feat/lark-suite-skill -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: 4

🤖 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 `@cmd/update/update.go`:
- Around line 357-371: `validateSkillsLayoutOptions` currently returns early for
non-hybrid layouts, so `--flat-skills` is ignored when
`resolveSkillsSyncOptions` resolves to `separate`. Update this validation path
to detect when `opts.FlatSet` is true and `opts.FlatSkills` were provided
without `skillscheck.LayoutHybrid`, and return a validation error (or at least a
warning) instead of silently dropping the flag. Use
`validateSkillsLayoutOptions` and `resolveSkillsSyncOptions` as the main entry
points for the fix.

In `@internal/skillscheck/layout.go`:
- Around line 99-115: Route the directory traversal in listSuiteSubskills
through internal/vfs instead of calling os.ReadDir directly, so this logic can
be mocked in tests like the rest of the layout code. Add or use a vfs-backed
recursive directory listing helper to cover the missing WalkDir-style behavior,
then update listSuiteSubskills to use that abstraction while keeping the
existing filtering and sorting logic unchanged.

In `@internal/skillscheck/sync.go`:
- Around line 199-210: Consolidate the duplicate “newly-added official skills”
logic in SyncPlan generation so `newlyOfficialSkills` is the single source of
truth. Update the `SyncPlan` construction in `sync.go` (the branch around
`official`, `layout`, and `skippedDeleted`) to compute `newAddedOfficial` once
via `newlyOfficialSkills`, then reuse it when building `ToUpdate` and `Added`
instead of maintaining a separate inline previous-state comparison loop. Make
the same consolidation anywhere else in this flow that repeats the
hybrid/separate-layout official-skills diff logic so `SyncPlan` stays
consistent.

In `@isolated-skills/lark-suite/SKILL.md`:
- Around line 13-25: The `lark-suite` prompt is still telling the agent to
discover and read other skills’ SKILL.md files, which breaks skill isolation;
remove the cross-skill enumeration/discovery guidance from the suite routing
instructions and keep `lark-suite` limited to directing users to the appropriate
known `lark-*` sub-skill. Update the routing text in `lark-suite/SKILL.md` so it
no longer instructs reading unrelated peer skill manifests, and preserve only
the minimal handoff logic for selecting a sub-skill and relying on `lark-shared`
where applicable.
🪄 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: da095477-0fd1-49ad-a37e-e70fccaab18d

📥 Commits

Reviewing files that changed from the base of the PR and between f0b6f35 and f151ca9.

📒 Files selected for processing (9)
  • cmd/update/update.go
  • cmd/update/update_test.go
  • internal/selfupdate/updater.go
  • internal/selfupdate/updater_test.go
  • internal/skillscheck/layout.go
  • internal/skillscheck/state.go
  • internal/skillscheck/sync.go
  • internal/skillscheck/sync_test.go
  • isolated-skills/lark-suite/SKILL.md

Comment thread cmd/update/update.go
Comment on lines +357 to +371
func validateSkillsLayoutOptions(opts *UpdateOptions) errs.TypedError {
if _, ok := skillscheck.NormalizeLayout(opts.SkillsLayout); !ok {
return errs.NewValidationError(errs.SubtypeInvalidArgument, "--skills-layout must be one of separate or hybrid").WithParam("--skills-layout")
}
layout, flat := resolveSkillsSyncOptions(opts.SkillsLayout, opts.FlatSkills, opts.FlatSet)
if layout != skillscheck.LayoutHybrid {
return nil
}
for _, skill := range flat {
if skill == "lark-shared" {
return errs.NewValidationError(errs.SubtypeInvalidArgument, "lark-shared cannot be selected by --flat-skills; it is managed automatically for lark-suite compatibility").WithParam("--flat-skills")
}
}
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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

--flat-skills is silently ignored when layout isn't hybrid.

If a user passes --flat-skills foo without --skills-layout hybrid (and no prior hybrid state), resolveSkillsSyncOptions resolves layout to separate, and validateSkillsLayoutOptions returns nil at Line 363 without ever checking opts.FlatSet. The flag is silently dropped with no error or warning, which can surprise users on this high-risk-write command.

🐛 Proposed fix
 	layout, flat := resolveSkillsSyncOptions(opts.SkillsLayout, opts.FlatSkills, opts.FlatSet)
+	if opts.FlatSet && layout != skillscheck.LayoutHybrid {
+		return errs.NewValidationError(errs.SubtypeInvalidArgument, "--flat-skills requires --skills-layout hybrid (or a previously saved hybrid layout)").WithParam("--flat-skills")
+	}
 	if layout != skillscheck.LayoutHybrid {
 		return nil
 	}
📝 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 validateSkillsLayoutOptions(opts *UpdateOptions) errs.TypedError {
if _, ok := skillscheck.NormalizeLayout(opts.SkillsLayout); !ok {
return errs.NewValidationError(errs.SubtypeInvalidArgument, "--skills-layout must be one of separate or hybrid").WithParam("--skills-layout")
}
layout, flat := resolveSkillsSyncOptions(opts.SkillsLayout, opts.FlatSkills, opts.FlatSet)
if layout != skillscheck.LayoutHybrid {
return nil
}
for _, skill := range flat {
if skill == "lark-shared" {
return errs.NewValidationError(errs.SubtypeInvalidArgument, "lark-shared cannot be selected by --flat-skills; it is managed automatically for lark-suite compatibility").WithParam("--flat-skills")
}
}
return nil
}
func validateSkillsLayoutOptions(opts *UpdateOptions) errs.TypedError {
if _, ok := skillscheck.NormalizeLayout(opts.SkillsLayout); !ok {
return errs.NewValidationError(errs.SubtypeInvalidArgument, "--skills-layout must be one of separate or hybrid").WithParam("--skills-layout")
}
layout, flat := resolveSkillsSyncOptions(opts.SkillsLayout, opts.FlatSkills, opts.FlatSet)
if opts.FlatSet && layout != skillscheck.LayoutHybrid {
return errs.NewValidationError(errs.SubtypeInvalidArgument, "--flat-skills requires --skills-layout hybrid (or a previously saved hybrid layout)").WithParam("--flat-skills")
}
if layout != skillscheck.LayoutHybrid {
return nil
}
for _, skill := range flat {
if skill == "lark-shared" {
return errs.NewValidationError(errs.SubtypeInvalidArgument, "lark-shared cannot be selected by --flat-skills; it is managed automatically for lark-suite compatibility").WithParam("--flat-skills")
}
}
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 `@cmd/update/update.go` around lines 357 - 371, `validateSkillsLayoutOptions`
currently returns early for non-hybrid layouts, so `--flat-skills` is ignored
when `resolveSkillsSyncOptions` resolves to `separate`. Update this validation
path to detect when `opts.FlatSet` is true and `opts.FlatSkills` were provided
without `skillscheck.LayoutHybrid`, and return a validation error (or at least a
warning) instead of silently dropping the flag. Use
`validateSkillsLayoutOptions` and `resolveSkillsSyncOptions` as the main entry
points for the fix.

Comment thread internal/skillscheck/layout.go
Comment thread internal/skillscheck/sync.go
Comment thread isolated-skills/lark-suite/SKILL.md
Comment thread internal/skillscheck/layout.go Fixed
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

PR Quality Summary

CI did not complete successfully. Use the failed check links below to decide whether this PR needs a code change or a rerun.

Failed checks

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