From 001f3dc9f4ef70c1892ef356bbd359f9307a54c2 Mon Sep 17 00:00:00 2001 From: youdie006 Date: Wed, 22 Jul 2026 00:23:04 +0900 Subject: [PATCH 1/2] feat(skill): add a kit skill command to install the kit agent skill Coding agents learn kit only from flag-oriented --help. Add a kit skill command that installs an embedded SKILL.md - covering Kitfile authoring and the pack/tag/login/push/pull/unpack workflow - into the agent skills directories, reusing the existing --as-skill installer so it lands in .claude/skills, the shared .agents/skills, etc. The SKILL.md is go:embed'd so it always matches the installed kit version and works air-gapped. Scopes to the command only; publishing the skill as a ModelKit is left to a follow-up. Refs #1249. Signed-off-by: youdie006 --- cmd/root.go | 2 + docs/src/docs/cli/cli-reference.md | 59 ++++++++ pkg/cmd/skill/SKILL.md | 217 +++++++++++++++++++++++++++++ pkg/cmd/skill/cmd.go | 194 ++++++++++++++++++++++++++ pkg/cmd/skill/cmd_test.go | 106 ++++++++++++++ 5 files changed, 578 insertions(+) create mode 100644 pkg/cmd/skill/SKILL.md create mode 100644 pkg/cmd/skill/cmd.go create mode 100644 pkg/cmd/skill/cmd_test.go diff --git a/cmd/root.go b/cmd/root.go index cf3062b0..b209c45b 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -37,6 +37,7 @@ import ( "github.com/kitops-ml/kitops/pkg/cmd/pull" "github.com/kitops-ml/kitops/pkg/cmd/push" "github.com/kitops-ml/kitops/pkg/cmd/remove" + "github.com/kitops-ml/kitops/pkg/cmd/skill" "github.com/kitops-ml/kitops/pkg/cmd/tag" "github.com/kitops-ml/kitops/pkg/cmd/unpack" "github.com/kitops-ml/kitops/pkg/cmd/version" @@ -167,6 +168,7 @@ func addSubcommands(rootCmd *cobra.Command) { rootCmd.AddCommand(diff.DiffCommand()) rootCmd.AddCommand(kitimport.ImportCommand()) rootCmd.AddCommand(kitcache.CacheCommand()) + rootCmd.AddCommand(skill.SkillCommand()) } // Execute adds all child commands to the root command and sets flags appropriately. diff --git a/docs/src/docs/cli/cli-reference.md b/docs/src/docs/cli/cli-reference.md index 8f7a0ca9..b0c5b521 100644 --- a/docs/src/docs/cli/cli-reference.md +++ b/docs/src/docs/cli/cli-reference.md @@ -955,6 +955,65 @@ kit remove --remote --force my-registry.com/my-org/my-repo:my-tag -v, --verbose count Increase verbosity of output (use -vv for more) ``` +## kit skill + +Install the kit agent skill so AI agents can use the kit CLI + +### Synopsis + +Install a SKILL.md that teaches an AI agent how to use the kit CLI. + +The skill documents Kitfile authoring and the pack, tag, login, push, pull, and +unpack workflow. It is embedded in the kit binary, so it always matches the +installed kit version and works without network access. + +The skill is written into each agent's skills directory (for example +'.claude/skills' or the shared '.agents/skills'). Without --agents, kit +auto-discovers installed agents by checking their global config directories. +With --agents, specify agents as a comma-separated list (e.g. +--agents=claude-code,cursor). By default the skill is installed globally +(user-scoped); when -d is specified it is installed into that project +directory instead. + +``` +kit skill [flags] +``` + +### Examples + +``` +# Install the kit skill for auto-detected agents (user-scoped) +kit skill + +# Install for specific agents +kit skill --agents=claude-code,cursor + +# Install into a project directory +kit skill -d /path/to/project + +# Overwrite an existing installation +kit skill -o +``` + +### Options + +``` + -d, --dir string Install the skill into this project directory instead of globally (user-scoped) + --agents string Agents to install the skill for, as a comma-separated list (e.g. claude-code,cursor). Without a value, auto-discovers installed agents + -o, --overwrite Overwrite the skill if it already exists + -i, --ignore-existing Skip installation if the skill already exists + -h, --help help for skill +``` + +### Options inherited from parent commands + +``` + --config string Alternate path to root storage directory for CLI + --log-level string Log messages above specified level ('trace', 'debug', 'info', 'warn', 'error') (default 'info') (default "info") + --progress string Configure progress bars for longer operations (options: none, plain, fancy) (default "plain") + -v, --verbose count Increase verbosity of output (use -vv for more) +``` + ## kit tag Create a tag that refers to a modelkit diff --git a/pkg/cmd/skill/SKILL.md b/pkg/cmd/skill/SKILL.md new file mode 100644 index 00000000..2310b3f7 --- /dev/null +++ b/pkg/cmd/skill/SKILL.md @@ -0,0 +1,217 @@ +--- +name: kitops +description: >- + Package, version, share, and unpack AI/ML models as OCI-standard ModelKits + with the KitOps `kit` CLI. Use this skill when authoring a Kitfile or running + kit init, pack, tag, login, push, pull, or unpack. +license: Apache-2.0 +--- + +# Using the KitOps `kit` CLI + +KitOps packages models, datasets, code, docs, prompts, and MCP servers together +as a **ModelKit** — an OCI artifact you can store in any OCI registry. A ModelKit +is defined by a **Kitfile** (a YAML manifest) and built with `kit pack`. + +This skill documents the real behavior of the `kit` CLI. It was generated from +and ships with a specific `kit` version, so it always matches the installed +binary. Confirm anything not covered here with `kit --help`. + +## Core workflow + +``` +kit init # generate a Kitfile for a directory (optional starting point) +kit pack # build a ModelKit into local storage +kit tag SRC DST # add another reference to a local ModelKit +kit login # authenticate to a remote registry +kit push SRC # upload a ModelKit to a registry +kit pull REF # download a ModelKit into local storage +kit unpack REF # extract a ModelKit's contents onto disk +``` + +## Authoring a Kitfile + +The Kitfile is a YAML manifest, by default named `Kitfile` at the root of the +context directory. All `path` values are **relative to the context directory**; +absolute paths are rejected. Only local filesystem paths are allowed for `code`, +`datasets`, `docs`, `prompts`, and `mcpServers` paths; `model.path` also accepts +a ModelKit reference. No two layers may declare the same path. + +Sections: + +- `manifestVersion` (string): use `1.0.0`. Other values produce a warning and + are treated as `1.0.0`. +- `package`: `name`, `version`, `description`, `authors` (list of strings). +- `model` (object): `name`, `path`, `framework`, `format`, `version`, + `description`, `license` (SPDX id), `parts` (list of `name`/`path`/`type`, + e.g. LoRA weights), and `parameters` (arbitrary JSON-compatible YAML). +- `code` (list): each has `path`, `description`, `license`. +- `datasets` (list): each has `name`, `path`, `description`, `license`. A dataset + may instead reference a remote source via `remotePath` (an `s3://` URL, which + also requires `remoteHash`, or a ModelKit reference). +- `docs` (list): each has `path`, `description`. +- `prompts` (list): each has `path`, `description`. A prompt directory that + contains a `SKILL.md` can be installed as an agent skill (see `unpack`). +- `mcpServers` (list): each has `name` (required, unique) and `path` pointing to + a single `.mcpb` bundle file, plus `description`. + +Example: + +```yaml +manifestVersion: 1.0.0 +package: + name: mymodel + version: 1.0.0 + description: Sentiment classifier + authors: [Jane Doe] +code: + - path: src/ + description: Training and inference code + license: Apache-2.0 +datasets: + - name: training-set + path: data/train.csv + description: Labeled training data + license: CC-BY-4.0 +model: + name: sentiment-model + path: models/model.safetensors + framework: PyTorch + version: 1.0.0 + license: Apache-2.0 +``` + +Tip: `kit init ` inspects a directory and generates a starting Kitfile. +Useful flags: `--name`, `--desc`, `--author`, `--force` (overwrite an existing +Kitfile), and `--output` (`-` writes to stdout). `kit init --remote` +generates a Kitfile from a remote Hugging Face repository (with `--ref`). + +## pack — build a ModelKit + +`kit pack [flags] DIRECTORY` + +Builds a ModelKit from the Kitfile using `DIRECTORY` as the context, and stores +it in local storage. Relative paths in the Kitfile are resolved against +`DIRECTORY`. + +- `-f, --file` — path to the Kitfile (default: `Kitfile` in the context dir; use + `-` to read from stdin). +- `-t, --tag` — assign one or more tags, comma-separated: + `-t registry/repository:tag1,tag2`. +- `--compression` — `none` (default), `gzip`, `gzip-fastest`, or `zstd`. +- `--layer-format` — `tar` (default) or `raw`. + +``` +kit pack . +kit pack . -f ./Kitfile -t myregistry.com/myorg/mymodel:1.0.0 +``` + +## tag — add a reference + +`kit tag SOURCE_MODELKIT[:TAG] TARGET_MODELKIT[:TAG]` + +Adds a new reference to an existing local ModelKit. Both the source and target +must include a tag or digest. + +A full reference is `[HOST[:PORT]/][NAMESPACE/]REPOSITORY[:TAG]`. `HOST` defaults +to `localhost` when omitted. A `TAG` may use letters, digits, `_`, `.`, `-`, must +not start with `.` or `-`, and is at most 128 characters. + +``` +kit tag myregistry.com/myorg/mymodel:latest myregistry.com/myorg/mymodel:v1.0.0 +``` + +## login — authenticate + +`kit login [flags] [REGISTRY]` + +Authenticate before pushing or pulling from a private registry. + +- `-u, --username`, `-p, --password`, `--password-stdin`. + +``` +kit login myregistry.com -u myuser --password-stdin +``` + +## push — upload to a registry + +`kit push [flags] SOURCE [DESTINATION]` + +Uploads a local ModelKit to a remote registry. Without a `DESTINATION`, the +ModelKit must already be tagged with a full registry reference (a registry host +is required — you cannot push to `localhost`). With a `DESTINATION`, a locally +tagged ModelKit is pushed to that reference. + +``` +kit push myregistry.com/myorg/mymodel:1.0.0 +kit push mymodel:1.0.0 myregistry.com/myorg/mymodel:latest +``` + +## pull — download from a registry + +`kit pull [flags] registry/repository[:tag|@digest]` + +Downloads a ModelKit into local storage. A registry host is required (you cannot +pull from `localhost`). + +``` +kit pull myregistry.com/myorg/mymodel:1.0.0 +``` + +## unpack — extract contents to disk + +`kit unpack [flags] [registry/]repository[:tag|@digest]` + +Extracts a ModelKit's contents to the filesystem. Looks in local storage first, +then the remote registry. + +- `-d, --dir` — target directory (created if missing; default: current dir). +- `-f, --filter` — limit what is extracted, format `[types]:[filters]`, where + `types` is a comma-separated subset of `kitfile,model,datasets,code,docs,prompts,mcpservers`. + Repeatable; a layer is unpacked if it matches any filter. Example: + `--filter=model` or `--filter=datasets:my-dataset`. +- `-o, --overwrite` — overwrite existing files. +- `-i, --ignore-existing` — skip files that already exist. +- `--as-skill[=agent,...]` — install `SKILL.md` prompt layers as agent skills + instead of unpacking to their original paths. With no value, kit auto-detects + installed agents; otherwise pass a comma-separated list (e.g. + `--as-skill=claude-code,cursor`). Installs globally unless `-d` is given. + +``` +kit unpack myregistry.com/myorg/mymodel:1.0.0 -d ./unpacked +kit unpack myregistry.com/myorg/mymodel:1.0.0 --filter=model -o +``` + +## Other useful commands + +- `kit list` — list ModelKits in local storage (or a remote repository). +- `kit inspect REF` — print a ModelKit's manifest and config. +- `kit info REF` — show a ModelKit's Kitfile. +- `kit remove REF` — delete a ModelKit from local storage. +- `kit version` — print the installed kit version. + +## Common errors and how to resolve them + +- **"registry is required when pushing" / "...when pulling"** — the reference has + no registry host (it resolves to `localhost`). Use a full reference like + `myregistry.com/myorg/mymodel:tag`, and `kit tag` the local ModelKit first if + needed. +- **"No tag specified ... Using 'latest' as default"** — informational; kit + defaulted the reference to `:latest`. Specify a tag explicitly to avoid it. +- **"reference cannot include multiple tags"** — push/pull/unpack accept a single + reference. Split multiple tags into separate commands (or use `kit tag`). +- **"source/target ModelKit reference requires a tag or digest"** — `kit tag` + needs a `:tag` (or `@digest`) on both arguments. +- **Kitfile validation errors** (surface on pack/init) include: + - "absolute paths are not supported in a Kitfile" — make every `path` relative + to the context directory. + - "only local paths are permitted" — `code`/`datasets`/`docs`/`prompts` paths + must be local files or directories, not URLs. + - "... use the same path ..." — two layers point at the same path; each layer + needs a distinct path. + - "invalid path for mcpServer ...: path must point to a single .mcpb file" — an + `mcpServers` entry must reference one `.mcpb` bundle. + - "Unrecognized manifestVersion" — set `manifestVersion: 1.0.0`. +- **"Failed to pack model kit"** — a path in the Kitfile is missing or the Kitfile + itself was not found; verify `-f`/the context directory and that every `path` + exists. diff --git a/pkg/cmd/skill/cmd.go b/pkg/cmd/skill/cmd.go new file mode 100644 index 00000000..df76337c --- /dev/null +++ b/pkg/cmd/skill/cmd.go @@ -0,0 +1,194 @@ +// Copyright 2026 The KitOps Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +package skill + +import ( + "archive/tar" + _ "embed" + "fmt" + "path/filepath" + "strings" + + "github.com/kitops-ml/kitops/pkg/artifact" + libskill "github.com/kitops-ml/kitops/pkg/lib/skill" + "github.com/kitops-ml/kitops/pkg/output" + + "github.com/spf13/cobra" +) + +// embeddedSkillMD is the SKILL.md that teaches an AI agent how to use the kit +// CLI. It is embedded in the binary so it always matches the installed kit +// version and works without network access. +// +//go:embed SKILL.md +var embeddedSkillMD []byte + +// skillName is the directory name the skill is installed under, matching the +// "name" field in the embedded SKILL.md frontmatter. +const skillName = "kitops" + +const ( + shortDesc = `Install the kit agent skill so AI agents can use the kit CLI` + longDesc = `Install a SKILL.md that teaches an AI agent how to use the kit CLI. + +The skill documents Kitfile authoring and the pack, tag, login, push, pull, and +unpack workflow. It is embedded in the kit binary, so it always matches the +installed kit version and works without network access. + +The skill is written into each agent's skills directory (for example +'.claude/skills' or the shared '.agents/skills'). Without --agents, kit +auto-discovers installed agents by checking their global config directories. +With --agents, specify agents as a comma-separated list (e.g. +--agents=claude-code,cursor). By default the skill is installed globally +(user-scoped); when -d is specified it is installed into that project +directory instead.` + + example = `# Install the kit skill for auto-detected agents (user-scoped) +kit skill + +# Install for specific agents +kit skill --agents=claude-code,cursor + +# Install into a project directory +kit skill -d /path/to/project + +# Overwrite an existing installation +kit skill -o` +) + +type skillOptions struct { + projectDir string + agents string + overwrite bool + ignoreExisting bool +} + +// SkillCommand returns the `kit skill` cobra command. +func SkillCommand() *cobra.Command { + opts := &skillOptions{} + + cmd := &cobra.Command{ + Use: "skill [flags]", + Short: shortDesc, + Long: longDesc, + Example: example, + Args: cobra.NoArgs, + RunE: runCommand(opts), + } + + cmd.Flags().StringVarP(&opts.projectDir, "dir", "d", "", "Install the skill into this project directory instead of globally (user-scoped)") + cmd.Flags().StringVar(&opts.agents, "agents", "", "Agents to install the skill for, as a comma-separated list (e.g. claude-code,cursor). Without a value, auto-discovers installed agents") + cmd.Flags().BoolVarP(&opts.overwrite, "overwrite", "o", false, "Overwrite the skill if it already exists") + cmd.Flags().BoolVarP(&opts.ignoreExisting, "ignore-existing", "i", false, "Skip installation if the skill already exists") + cmd.Flags().SortFlags = false + + cmd.RegisterFlagCompletionFunc("agents", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return libskill.ValidAgentNames(), cobra.ShellCompDirectiveNoFileComp + }) + cmd.CompletionOptions.SetDefaultShellCompDirective(cobra.ShellCompDirectiveDefault) + return cmd +} + +func runCommand(opts *skillOptions) func(*cobra.Command, []string) error { + return func(cmd *cobra.Command, args []string) error { + agents, err := resolveAgents(opts.agents) + if err != nil { + return output.Fatalf("%s", err) + } + + // Only scope to a project directory when -d was explicitly provided; + // otherwise install globally (user-scoped), matching `kit unpack --as-skill`. + projectDir := "" + if cmd.Flags().Changed("dir") { + abs, err := filepath.Abs(opts.projectDir) + if err != nil { + return output.Fatalf("failed to resolve absolute path %s: %s", opts.projectDir, err) + } + projectDir = abs + } + + installOpts := &libskill.SkillInstallOptions{ + Agents: agents, + ProjectDir: projectDir, + Overwrite: opts.overwrite, + IgnoreExisting: opts.ignoreExisting, + } + + // Wrap the embedded SKILL.md as a single tar entry so the shared + // installer (used by `kit unpack --as-skill`) resolves the agent skills + // directories and writes the file. + entries := []libskill.TarEntry{ + { + Header: &tar.Header{ + Name: "SKILL.md", + Typeflag: tar.TypeReg, + Mode: 0644, + Size: int64(len(embeddedSkillMD)), + }, + Content: embeddedSkillMD, + }, + } + + result := libskill.InstallSkill(entries, skillName, artifact.Prompt{Path: "SKILL.md"}, installOpts) + for _, ar := range result.Agents { + switch { + case ar.Err != nil: + output.Infof("Failed to install skill '%s' for %s: %s", skillName, ar.Agent, ar.Err) + case ar.Skipped: + output.Infof("Skipped skill '%s' for %s: already exists (use -o to overwrite)", skillName, ar.Agent) + default: + output.Infof("Installed skill '%s' for %s → %s", skillName, ar.Agent, ar.Path) + } + } + + if result.HasErrors() { + return output.Fatalf("failed to install skill for %d agent(s)", len(result.Errors())) + } + return nil + } +} + +// resolveAgents mirrors `kit unpack --as-skill` agent resolution: an empty value +// auto-discovers installed agents, otherwise it parses and validates a +// comma-separated list of agent names. +func resolveAgents(value string) ([]string, error) { + value = strings.TrimSpace(value) + if value == "" { + detected, err := libskill.DetectInstalledAgents() + if err != nil { + return nil, fmt.Errorf("failed to detect installed agents: %w", err) + } + if len(detected) == 0 { + return nil, fmt.Errorf("no installed agents detected. Specify agents explicitly, e.g. --agents=claude-code,cursor") + } + output.Infof("Detected installed agents: %s", strings.Join(detected, ", ")) + return detected, nil + } + + var agents []string + for _, p := range strings.Split(value, ",") { + name := strings.TrimSpace(p) + if name == "" { + return nil, fmt.Errorf("invalid agent list: empty agent name in '%s'", value) + } + if !libskill.IsValidAgentName(name) { + return nil, fmt.Errorf("unknown agent '%s'. Valid agents: %s", name, strings.Join(libskill.ValidAgentNames(), ", ")) + } + agents = append(agents, name) + } + return agents, nil +} diff --git a/pkg/cmd/skill/cmd_test.go b/pkg/cmd/skill/cmd_test.go new file mode 100644 index 00000000..100a5128 --- /dev/null +++ b/pkg/cmd/skill/cmd_test.go @@ -0,0 +1,106 @@ +// Copyright 2026 The KitOps Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +package skill + +import ( + "bytes" + "os" + "path/filepath" + "testing" + + libskill "github.com/kitops-ml/kitops/pkg/lib/skill" +) + +// TestSkillCommand_InstallsEmbeddedSkill drives `kit skill` end-to-end for an +// explicit agent in a project directory and verifies the embedded SKILL.md is +// written to the expected agent skills directory with byte-identical content. +func TestSkillCommand_InstallsEmbeddedSkill(t *testing.T) { + tmpDir := t.TempDir() + + cmd := SkillCommand() + cmd.SetOut(&bytes.Buffer{}) + cmd.SetErr(&bytes.Buffer{}) + cmd.SetArgs([]string{"--dir", tmpDir, "--agents", "claude-code"}) + + if err := cmd.Execute(); err != nil { + t.Fatalf("kit skill failed: %v", err) + } + + // claude-code installs under .claude/skills; the skill directory name is the + // frontmatter name ("kitops"). + skillPath := filepath.Join(tmpDir, ".claude", "skills", skillName, "SKILL.md") + got, err := os.ReadFile(skillPath) + if err != nil { + t.Fatalf("reading installed skill: %v", err) + } + + if !bytes.Equal(got, embeddedSkillMD) { + t.Errorf("installed SKILL.md does not match embedded content (%d vs %d bytes)", len(got), len(embeddedSkillMD)) + } +} + +// TestSkillCommand_MultipleAgents verifies the skill lands in each requested +// agent's skills directory. +func TestSkillCommand_MultipleAgents(t *testing.T) { + tmpDir := t.TempDir() + + cmd := SkillCommand() + cmd.SetOut(&bytes.Buffer{}) + cmd.SetErr(&bytes.Buffer{}) + cmd.SetArgs([]string{"--dir", tmpDir, "--agents", "claude-code,windsurf"}) + + if err := cmd.Execute(); err != nil { + t.Fatalf("kit skill failed: %v", err) + } + + for _, sub := range []string{ + filepath.Join(".claude", "skills", skillName, "SKILL.md"), + filepath.Join(".windsurf", "skills", skillName, "SKILL.md"), + } { + if _, err := os.Stat(filepath.Join(tmpDir, sub)); err != nil { + t.Errorf("expected skill at %s: %v", sub, err) + } + } +} + +// TestSkillCommand_UnknownAgent verifies an invalid agent name is rejected. +func TestSkillCommand_UnknownAgent(t *testing.T) { + cmd := SkillCommand() + cmd.SetOut(&bytes.Buffer{}) + cmd.SetErr(&bytes.Buffer{}) + cmd.SetArgs([]string{"--dir", t.TempDir(), "--agents", "not-a-real-agent"}) + + if err := cmd.Execute(); err == nil { + t.Error("expected error for unknown agent, got nil") + } +} + +// TestEmbeddedSkillFrontmatter guards against drift between the skillName +// constant and the embedded SKILL.md frontmatter, and ensures the file is a +// valid agent skill doc (name + description present). +func TestEmbeddedSkillFrontmatter(t *testing.T) { + fm := libskill.ParseSkillFrontmatter(embeddedSkillMD) + if fm == nil { + t.Fatal("embedded SKILL.md has no parseable frontmatter") + } + if fm.Name != skillName { + t.Errorf("frontmatter name = %q, want %q (must match install dir)", fm.Name, skillName) + } + if fm.Description == "" { + t.Error("frontmatter description is empty") + } +} From 05a9a240649c2663711b507f6c0b811cf2bbc94e Mon Sep 17 00:00:00 2001 From: youdie006 Date: Thu, 23 Jul 2026 08:30:00 +0900 Subject: [PATCH 2/2] docs: drop regenerated cli-reference (served from HEAD, regen at release) Signed-off-by: youdie006 --- docs/src/docs/cli/cli-reference.md | 59 ------------------------------ 1 file changed, 59 deletions(-) diff --git a/docs/src/docs/cli/cli-reference.md b/docs/src/docs/cli/cli-reference.md index b0c5b521..8f7a0ca9 100644 --- a/docs/src/docs/cli/cli-reference.md +++ b/docs/src/docs/cli/cli-reference.md @@ -955,65 +955,6 @@ kit remove --remote --force my-registry.com/my-org/my-repo:my-tag -v, --verbose count Increase verbosity of output (use -vv for more) ``` -## kit skill - -Install the kit agent skill so AI agents can use the kit CLI - -### Synopsis - -Install a SKILL.md that teaches an AI agent how to use the kit CLI. - -The skill documents Kitfile authoring and the pack, tag, login, push, pull, and -unpack workflow. It is embedded in the kit binary, so it always matches the -installed kit version and works without network access. - -The skill is written into each agent's skills directory (for example -'.claude/skills' or the shared '.agents/skills'). Without --agents, kit -auto-discovers installed agents by checking their global config directories. -With --agents, specify agents as a comma-separated list (e.g. ---agents=claude-code,cursor). By default the skill is installed globally -(user-scoped); when -d is specified it is installed into that project -directory instead. - -``` -kit skill [flags] -``` - -### Examples - -``` -# Install the kit skill for auto-detected agents (user-scoped) -kit skill - -# Install for specific agents -kit skill --agents=claude-code,cursor - -# Install into a project directory -kit skill -d /path/to/project - -# Overwrite an existing installation -kit skill -o -``` - -### Options - -``` - -d, --dir string Install the skill into this project directory instead of globally (user-scoped) - --agents string Agents to install the skill for, as a comma-separated list (e.g. claude-code,cursor). Without a value, auto-discovers installed agents - -o, --overwrite Overwrite the skill if it already exists - -i, --ignore-existing Skip installation if the skill already exists - -h, --help help for skill -``` - -### Options inherited from parent commands - -``` - --config string Alternate path to root storage directory for CLI - --log-level string Log messages above specified level ('trace', 'debug', 'info', 'warn', 'error') (default 'info') (default "info") - --progress string Configure progress bars for longer operations (options: none, plain, fancy) (default "plain") - -v, --verbose count Increase verbosity of output (use -vv for more) -``` - ## kit tag Create a tag that refers to a modelkit