Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 45 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,44 @@
# CorvidLabs Skills

Public, versioned operating knowledge for software agents working with CorvidLabs tools.
Each skill is a portable `SKILL.md`; Fledge provides safe repository-local installation,
status, update, and uninstall commands.
Each skill is a portable `SKILL.md`; Fledge provides safe installation (repository-local
or machine-global), status, update, and uninstall commands.

Product repositories remain authoritative for their own architecture, commands, and
generated Spec Sync material.

## Quick start

Install the catalog plugin, inspect it, and add only the skills a repository needs:
Install the catalog plugin, then add skills **one at a time** (there is no `install --all`).

**Minimal core — repository-local** (good default for a single project):

```sh
fledge plugins install CorvidLabs/skills
fledge skills list
fledge skills install agent-coordination --host codex
fledge skills install fledge-workflows --host codex
fledge skills status
```

**Minimal core — machine-global** (available to every project for that host agent):

```sh
fledge plugins install CorvidLabs/skills
fledge skills install agent-coordination --global --host claude
fledge skills install fledge-workflows --global --host claude
fledge skills status --global
```

Global installs land under `$HOME` (or `$CORVID_SKILLS_HOME` if set), for example
`~/.claude/skills/<skill>`, and are tracked in `~/.corvid-skills.json`. They do **not**
replace repository-local installs; a project can still install a different set with
`--repo` / default cwd.

Add product skills (`let`, `rune`, `augur`, `atlas`, …) only when that tool is actually used.
`update --all` (optionally with `--global`) refreshes skills that are already managed; it
does not install missing ones.

To pin a published catalog release, add its tag to the source, for example:

```sh
Expand Down Expand Up @@ -62,15 +83,15 @@ The skill content is agent-neutral Markdown. Any agent that can load a `SKILL.md
repository context can use it. Fledge currently provides automatic, collision-safe placement
for these hosts:

| Host | Repository-local destination | Automatic placement |
| --- | --- | --- |
| Codex | `.codex/skills/<skill>` | Yes |
| Claude | `.claude/skills/<skill>` | Yes |
| Cursor | `.cursor/skills/<skill>` | Yes |
| Gemini | `.gemini/skills/<skill>` | Yes |
| Grok | `.grok/skills/<skill>` | Yes |
| OpenAI | `.agents/skills/<skill>` | Yes |
| Other agents | Agent-defined | No; use the agent's documented skill path. |
| Host | Repo-local (`--repo` / cwd) | Machine-global (`--global`) | Automatic placement |
| --- | --- | --- | --- |
| Codex | `.codex/skills/<skill>` | `~/.codex/skills/<skill>` | Yes |
| Claude | `.claude/skills/<skill>` | `~/.claude/skills/<skill>` | Yes |
| Cursor | `.cursor/skills/<skill>` | `~/.cursor/skills/<skill>` | Yes |
| Gemini | `.gemini/skills/<skill>` | `~/.gemini/skills/<skill>` | Yes |
| Grok | `.grok/skills/<skill>` | `~/.grok/skills/<skill>` | Yes |
| OpenAI | `.agents/skills/<skill>` | `~/.agents/skills/<skill>` | Yes |
| Other agents | Agent-defined | Agent-defined | No; use the agent's documented skill path. |

Host placement does not translate private context or product-specific assumptions into a skill.
All catalog content and examples must remain usable from public CorvidLabs sources.
Expand All @@ -80,22 +101,23 @@ managed by that agent or by the user.
## Manage installed skills

Installs copy by default. Use `--link` only while developing this catalog locally.
Every placement is recorded in `.corvid-skills.json` with its source revision, mode,
destination, and content digest.
Every placement is recorded in `.corvid-skills.json` (repo root or `$HOME` for `--global`)
with its source revision, mode, destination, and content digest.

```sh
# Inspect human-readable or machine-readable state.
fledge skills status
fledge skills status --global
fledge skills status --json

# Preview, then update one skill or every managed skill.
fledge skills update augur --dry-run
fledge skills update --all --dry-run
fledge skills update --all
fledge skills update --all --global --dry-run
fledge skills update --all --global

# Preview, then remove one manifest-owned skill.
fledge skills uninstall augur --dry-run
fledge skills uninstall augur
fledge skills uninstall augur --global
Comment on lines 119 to +120

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preview the same scope before global uninstall

Following this documented preview-and-remove sequence checks the repository-local manifest during the dry run, but then removes the machine-global installation in the next command. When augur exists in both scopes, the preview provides no evidence about the copy that will actually be deleted; add --global to the dry-run command (or keep both commands repository-local).

Useful? React with 👍 / 👎.

```

`status` reports `current`, `legacy`, `modified`, or `missing`. A `legacy` OpenAI entry was
Expand Down Expand Up @@ -143,9 +165,13 @@ The direct installer is available for debugging or environments without plugin d
```sh
bin/corvid-skills list --json
bin/corvid-skills install agent-coordination --repo /path/to/project --host codex
bin/corvid-skills install agent-coordination --global --host claude
bin/corvid-skills status --repo /path/to/project --json
bin/corvid-skills status --global --json
bin/corvid-skills update agent-coordination --repo /path/to/project --dry-run
bin/corvid-skills update agent-coordination --global --dry-run
bin/corvid-skills uninstall agent-coordination --repo /path/to/project --dry-run
bin/corvid-skills uninstall agent-coordination --global --dry-run
```

## Design rules
Expand All @@ -154,4 +180,5 @@ bin/corvid-skills uninstall agent-coordination --repo /path/to/project --dry-run
- Verify real public commands before documenting them.
- Treat repository-local instructions as authoritative for that repository.
- Never include private paths, session content, secrets, user metadata, or private-repository assumptions.
- Make installation and lifecycle mutations explicit, manifest-owned, and repository-local.
- Make installation and lifecycle mutations explicit, manifest-owned, and scoped
(repository-local or machine-global)—never silent.
72 changes: 58 additions & 14 deletions bin/corvid-skills
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,21 @@ manifest_name=".corvid-skills.json"

usage() {
cat <<'EOF'
Manage shared CorvidLabs agent skills in one repository.
Manage shared CorvidLabs agent skills (repository-local or machine-global).

Usage:
fledge skills list [--json]
fledge skills install <skill> [--repo <path>] [--host <auto|codex|claude|cursor|gemini|grok|openai>] [--link] [--dry-run]
fledge skills status [--repo <path>] [--json]
fledge skills update <skill>|--all [--repo <path>] [--host <codex|claude|cursor|gemini|grok|openai>] [--dry-run]
fledge skills uninstall <skill> [--repo <path>] [--host <codex|claude|cursor|gemini|grok|openai>] [--dry-run]
fledge skills install <skill> [--repo <path>|--global] [--host <auto|codex|claude|cursor|gemini|grok|openai>] [--link] [--dry-run]
fledge skills status [--repo <path>|--global] [--json]
fledge skills update <skill>|--all [--repo <path>|--global] [--host <codex|claude|cursor|gemini|grok|openai>] [--dry-run]
fledge skills uninstall <skill> [--repo <path>|--global] [--host <codex|claude|cursor|gemini|grok|openai>] [--dry-run]

Install copies a selected skill into a repository-local agent directory and
records the exact source revision and content digest in .corvid-skills.json.
It never overwrites an existing directory.
Install copies (or links) a selected skill into either:
• a repository-local agent directory, or
• a machine-global host directory under $HOME (or $CORVID_SKILLS_HOME)

and records the exact source revision and content digest in .corvid-skills.json
(next to that target root). It never overwrites an existing directory.

Update and uninstall operate only on unmodified managed copies or exact manifest-owned links.
EOF
Expand Down Expand Up @@ -51,6 +54,33 @@ repository_root() {
git -C "$requested" rev-parse --show-toplevel 2>/dev/null || fail "not a Git repository: $requested"
}

# Machine-global install root. Override with CORVID_SKILLS_HOME for tests.
skills_home() {
local home="${CORVID_SKILLS_HOME:-${HOME:-}}"
[[ -n "$home" ]] || fail "HOME is unset; cannot use --global"
[[ -d "$home" ]] || fail "skills home is not a directory: $home"
printf '%s' "$home"
}

# Parent of host skills dir, e.g. .claude/skills -> .claude
host_agent_root() {
dirname "$(host_directory "$1")"
}

# Parse shared --repo / --global options. Sets: scope_root, is_global
# Remaining args are left in parse_remaining for the caller via a name ref pattern:
# resolve_target_from_flags is called after collecting flags into variables.
resolve_target_root() {
local is_global="$1"
local repo_arg="$2"
if [[ "$is_global" == "true" ]]; then
[[ "$repo_arg" == "." ]] || fail "--global cannot be combined with --repo"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject explicit --repo . with --global

When a caller explicitly supplies --repo . --global, repo_arg is indistinguishable from its default value, so this check passes and the command silently targets $HOME instead of rejecting the conflicting scope flags. For install, update, and uninstall, this can mutate machine-global skills when the caller intended repository-local operation; track whether --repo was provided rather than comparing its value with ..

Useful? React with 👍 / 👎.

skills_home
else
repository_root "$repo_arg"
fi
}

ensure_safe_install_paths() {
local repo="$1"
local destination_rel="$2"
Expand Down Expand Up @@ -123,7 +153,9 @@ resolve_host() {
local candidates=()
local host
for host in codex claude cursor gemini grok openai; do
[[ -d "$repo/$(host_directory "$host")" ]] && candidates+=("$host")
if [[ -d "$repo/$(host_directory "$host")" || -d "$repo/$(host_agent_root "$host")" ]]; then
candidates+=("$host")
fi
done
if [[ ${#candidates[@]} -eq 1 ]]; then
printf '%s' "${candidates[0]}"
Expand Down Expand Up @@ -458,10 +490,12 @@ install_skill() {
local host_arg="auto"
local link="false"
local dry_run="false"
local is_global="false"

while [[ $# -gt 0 ]]; do
case "$1" in
--repo) [[ $# -ge 2 ]] || fail "--repo needs a path"; repo_arg="$2"; shift 2 ;;
--global) is_global="true"; shift ;;
--host) [[ $# -ge 2 ]] || fail "--host needs a value"; host_arg="$2"; shift 2 ;;
--link) link="true"; shift ;;
--dry-run) dry_run="true"; shift ;;
Expand All @@ -471,7 +505,7 @@ install_skill() {

validate_skill_source "$skill"
local repo host destination destination_rel revision digest manifest
repo="$(repository_root "$repo_arg")"
repo="$(resolve_target_root "$is_global" "$repo_arg")"
host="$(resolve_host "$repo" "$host_arg")"
destination_rel="$(host_directory "$host")/$skill"
destination="$repo/$destination_rel"
Expand Down Expand Up @@ -515,9 +549,11 @@ update_skills() {
local repo_arg="."
local host_filter=""
local dry_run="false"
local is_global="false"
while [[ $# -gt 0 ]]; do
case "$1" in
--repo) [[ $# -ge 2 ]] || fail "--repo needs a path"; repo_arg="$2"; shift 2 ;;
--global) is_global="true"; shift ;;
--host) [[ $# -ge 2 ]] || fail "--host needs a value"; host_filter="$2"; shift 2 ;;
--dry-run) dry_run="true"; shift ;;
*) fail "unknown option: $1" ;;
Expand All @@ -528,7 +564,7 @@ update_skills() {
[[ -z "$host_filter" ]] || host_directory "$host_filter" >/dev/null

local repo manifest revision
repo="$(repository_root "$repo_arg")"
repo="$(resolve_target_root "$is_global" "$repo_arg")"
manifest="$repo/$manifest_name"
[[ -f "$manifest" && ! -L "$manifest" ]] || fail "managed-skills manifest not found: $manifest"
revision="$(git -C "$root_dir" rev-parse --verify HEAD 2>/dev/null || printf 'working-tree')"
Expand Down Expand Up @@ -607,9 +643,11 @@ uninstall_skill() {
local repo_arg="."
local host_filter=""
local dry_run="false"
local is_global="false"
while [[ $# -gt 0 ]]; do
case "$1" in
--repo) [[ $# -ge 2 ]] || fail "--repo needs a path"; repo_arg="$2"; shift 2 ;;
--global) is_global="true"; shift ;;
--host) [[ $# -ge 2 ]] || fail "--host needs a value"; host_filter="$2"; shift 2 ;;
--dry-run) dry_run="true"; shift ;;
*) fail "unknown option: $1" ;;
Expand All @@ -618,7 +656,7 @@ uninstall_skill() {
[[ -z "$host_filter" ]] || host_directory "$host_filter" >/dev/null

local repo manifest
repo="$(repository_root "$repo_arg")"
repo="$(resolve_target_root "$is_global" "$repo_arg")"
manifest="$repo/$manifest_name"
[[ -f "$manifest" && ! -L "$manifest" ]] || fail "managed-skills manifest not found: $manifest"
local manifest_output=""
Expand Down Expand Up @@ -683,22 +721,28 @@ uninstall_skill() {
status_skills() {
local repo_arg="."
local json="false"
local is_global="false"
while [[ $# -gt 0 ]]; do
case "$1" in
--repo) [[ $# -ge 2 ]] || fail "--repo needs a path"; repo_arg="$2"; shift 2 ;;
--global) is_global="true"; shift ;;
--json) json="true"; shift ;;
*) fail "unknown option: $1" ;;
esac
done
local repo manifest
repo="$(repository_root "$repo_arg")"
repo="$(resolve_target_root "$is_global" "$repo_arg")"
manifest="$repo/$manifest_name"
[[ ! -L "$manifest" ]] || fail "refusing symlinked manifest: $manifest"
if [[ ! -f "$manifest" ]]; then
if [[ "$json" == "true" ]]; then
printf '{"schema_version":1,"installs":[]}\n'
else
echo "No managed CorvidLabs skills are installed in $repo"
if [[ "$is_global" == "true" ]]; then
echo "No managed CorvidLabs skills are installed globally in $repo"
else
echo "No managed CorvidLabs skills are installed in $repo"
fi
fi
return
fi
Expand Down
72 changes: 62 additions & 10 deletions skills/agent-3md/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,77 @@ description: Validate, route, inspect, or run agent.3md manifests and typed tool

# Agent 3md

Let can locate an `agent.3md`; this skill validates and routes it. Treat the file as executable configuration.
An `agent.3md` is executable configuration: plane 0 is identity; other planes are skills
with triggers, typed inputs, optional `tool=` command templates, and dependency links.
Let can **locate** the file; this skill **validates, routes, and optionally runs** it.

## Validate and preview
## Install

CorvidLabs/agent-3md is **not** a Fledge plugin (no `fledge agent3md`). Use the library
or CLI below.

**TypeScript library** (embed):

```sh
npm install @corvidlabs/agent3md
# or: bun add @corvidlabs/agent3md
```

**CLI** (prefer current main; crates.io may lag for `run`/`--exec`):

The Rust CLI on GitHub main supports `manifest`, `skills`, `route`, `get`, `resolve`,
`validate`, and `run` (`--exec`). Published `cargo install agent3md` may ship only the
inspect/validate subset—verify `agent3md --help` after install.

```sh
# From a clone of CorvidLabs/agent-3md
cd /path/to/agent-3md
cargo install --path loaders/rust
# or without a global install:
bun run cli --help
```

Inside the agent-3md repo:

| Action | Command |
| --- | --- |
| Inspect / route / run | `bun run cli <cmd> …` |
| Validate | `bun run validate <file>` (not `bun run cli validate`) |
| Scaffold | `bun run cli new …` (TS-only) |


## Inspect without executing

```sh
cargo install agent3md
agent3md validate agent.3md
agent3md run agent.3md "<request>" key=value
agent3md manifest agent.3md
agent3md skills agent.3md
agent3md route agent.3md "<request>"
agent3md get agent.3md <skill-name>
agent3md resolve agent.3md <skill-name>
```

The default `run` prints the selected command without executing it. Inspect the matched route,
substituted values, quoting, working directory, and referenced paths before taking action.
If `validate` rejects a modern manifest after `cargo install agent3md` from crates.io, use
repo-local `bun run validate` or a git/`--path` install of the current loader—published
crates.io **0.1.0** still requires `model:` in frontmatter and does not ship `run`/`--exec`.

## Execute only when authorized
## Preview, then execute only when authorized

Confirm `run` exists in `agent3md --help` first:

```sh
# Route + fill tool template; print the command (does not run it)
agent3md run agent.3md "<request>" key=value

# Run the rendered command
agent3md run agent.3md "<request>" key=value --exec
```

Use `--exec` only when the rendered command is within the user's authorization. It does not bypass Fledge workflows,
repository policy, the sandbox, or external-write approval. Prefer `fledge run` for repository-declared tasks. Use the
`three-md` skill for general documents that are not executable agent manifests.
Repo-local equivalent: `bun run cli run agent.3md "<request>" key=value [--exec]`.

Inspect the matched skill, substituted values, quoting, working directory, and referenced
paths before `--exec`. `--exec` does not bypass Fledge workflows, repository policy, the
sandbox, or external-write approval. Prefer `fledge run` for repository-declared tasks.

Skills without a `tool=` attribute are playbook-only—follow them with the host's own tools.
Use the `three-md` skill for general `.3md` documents that are not agent manifests.
Loading