feat: add skills command to read embedded skill content#1318
Conversation
Add a top-level `lark-cli skills` meta command group that reads skill content compiled into the binary at build time via go:embed, so the content an AI agent reads always matches the running CLI version. It is an additional, version-consistent source and a fallback for when skills are not installed or are stale; it does not replace or thin the on-disk skills. Commands: - `skills list` lists every embedded skill with name, description, and the frontmatter metadata block. - `skills list <name>` / `skills list <name>/<sub>` list one directory layer (ls-style, no recursion); entries are skill-prefixed paths that can be fed straight back to `read`. - `skills read <name>` prints the skill's SKILL.md and appends a one-line tip steering the model to fetch reference files via this command. - `skills read <name> <path>` / `skills read <name>/<path>` print any file under the skill directory (no tip). - `--json` wraps output in an envelope; on the main SKILL.md it carries a separate `guidance` field instead of merging the tip into content. Implementation: - skills/ is embedded from the repo-root package main (go:embed cannot cross parent dirs) and injected into cmd/skill via a package variable, avoiding any change to cmd.Execute's signature. - internal/skillcontent is pure logic over an injected fs.FS; reference reads and directory listings share one path-traversal guard that rejects absolute paths, "..", and "..\\" escapes. - Errors are typed (validation -> exit 2, file_io -> exit 5); rejected paths never write anything to stdout. Risk is set per leaf subcommand (read); the group carries none, matching the config/service command groups. The commands need no auth (local embed reads only).
Squashes the review-response iteration on top of the initial skills command. - Inject the embedded tree via an init() calling cmd.SetEmbeddedSkillContent (no cmd/skill package global, no panic; tests inject through the Factory). main.go stays self-contained so the single-file preview build (go build ./main.go) still compiles. - Surface the frontmatter version field in `skills list`. - Use typed structs for the list and read JSON envelopes. - Scope the read guidance tip to the skill's own files, route cross-skill "../lark-foo/..." references back through `skills read`, and emit it on stderr in raw mode (stdout stays byte-identical to SKILL.md) and in a guidance field under --json. - Share one path splitter (skillcontent.SplitArg) between read and list. - Skip top-level directories without a SKILL.md in List(). - Add usage examples to `skills list` and `skills read`. - Isolate config state in the command test helper. - Slim the embed to agent-readable content (SKILL.md + references/, plus lark-whiteboard's routes/ and scenes/), excluding machine-resource assets/ and scripts/: release binary 26.7 -> 23.4 MB, no change to what the commands serve.
- Fix stale comments referencing cmd.WithSkillContent (renamed to SetEmbeddedSkillContent in the earlier refactor); Execute takes no options, so the override path is the package-level setter called before Execute. - Drop the unreproducible absolute binary-size figures, keeping only the ~3.3 MB saved delta (absolute size depends on build/ldflags). - Scope the skills Long help to agent-readable content (SKILL.md + references); assets/ and scripts/ are not embedded, so "stays in sync" is not unconditional. - Trim comment density to the house style: keep only the load-bearing WHY (preview-build constraint, raw-stdout byte-purity, the path.Clean backslash guard, the --json no-op, the cross-skill ../ rewrite), drop doc comments that merely restate names/signatures. Change-Id: I5ddaa3d399522e00708944b0396a140bac6fcc56
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (7)
📝 WalkthroughWalkthroughThis PR adds a complete embedded skills system to the CLI: a reader library that enumerates and serves skill content with YAML frontmatter parsing, CLI commands to list and read skills with JSON and raw output modes, and compile-time embedding wiring that bundles skill files into the binary. ChangesEmbedded Skills Content and CLI Commands
Sequence Diagram(s)sequenceDiagram
participant CLI as User CLI
participant Cmd as Skill Command
participant Reader as skillcontent.Reader
participant Output as stdout/stderr
CLI->>Cmd: skills list [name[/path]]
Cmd->>Reader: List() or ListPath()
Reader-->>Cmd: SkillInfo[] or DirEntry[]
Cmd->>Output: JSON envelope
CLI->>Cmd: skills read <name>[/<path>]
Cmd->>Reader: ReadSkill() or ReadReference()
Reader-->>Cmd: []byte content
Cmd->>Output: Raw bytes or JSON envelope + guidance
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1318 +/- ##
==========================================
+ Coverage 71.14% 71.20% +0.06%
==========================================
Files 685 688 +3
Lines 65770 65997 +227
==========================================
+ Hits 46793 46996 +203
- Misses 15326 15340 +14
- Partials 3651 3661 +10 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
🚀 PR Preview Install Guide🧰 CLI updatenpm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@6ba9912bd215dba55e2c683f0ed48c089b0cdc64🧩 Skill updatenpx skills add larksuite/cli#feat/skill-content-read -y -g |
Summary
Re-homes #1277 into the upstream repo (it originated from a fork) and cherry-picks it onto the current
main. Original feature by @dc-bytedance — the two original commits are preserved; a follow-up commit applies the review feedback.Adds a
lark-cli skillscommand group that reads skill content compiled into the binary at build time viago:embed, giving AI agents a version-consistent source — and a fallback for when on-disk skills are missing or stale. It does not replace or thin the on-disk skills.Changes
skills_embed.go(package main)://go:embedof each skill'sSKILL.md+references/(plus lark-whiteboard'sroutes//scenes/), excluding machine-resource dirs (assets/,scripts/). Aninit()injects the tree viacmd.SetEmbeddedSkillContent, keepingmain.goself-contained so the single-file preview build still compiles.internal/skillcontent/reader.go: pure logic over an injectedfs.FS—List,ListPath(one-layer, ls-style),ReadSkill,ReadReference, with a shared path-traversal guard.cmd/skill/skill.go: theskillsgroup —list(catalog, or one-layer listing of<name>/<name>/<sub>) andread(<name>,<name> <path>, or<name>/<path>). Typed errors (validation → exit 2, file_io → exit 5); raw stdout stays byte-identical to the file, guidance goes to stderr.cmd/build.go;Factory.SkillContentfield added.Follow-up commit (review fixes)
cmd.WithSkillContent→SetEmbeddedSkillContent(Executetakes no options; the override path is the package-level setter).skillshelp text to agent-readable content (assets//scripts/are not embedded, so "stays in sync" is not unconditional).Test Plan
go build ./...(rc=0 on currentmain)go test ./internal/skillcontent/... ./cmd/skill/...gofmtcleanskills list,skills read <skill>,read <skill> <path>; error paths (read no-such-skill, traversal../../etc/passwd) exit 2 with empty stdoutSupersedes #1277.
Summary by CodeRabbit
Release Notes
New Features
skillscommand group with two subcommands:skills list— view available skills and directory contents with JSON output supportskills read— retrieve skill documentation and reference files in raw or JSON formatTests