1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
use clap::{Args, Subcommand};
#[derive(Debug, Args)]
pub(crate) struct SkillsArgs {
#[command(subcommand)]
pub command: SkillsCommand,
}
#[derive(Debug, Subcommand)]
pub(crate) enum SkillsCommand {
/// Show resolved skills in priority order, with collision warnings.
List(SkillsListArgs),
/// Dump the resolved SKILL.md plus bundled files and metadata for one skill.
Inspect(SkillsInspectArgs),
/// Run the metadata matcher against a prompt and show ranked candidates.
#[command(name = "match")]
Match(SkillsMatchArgs),
/// Resolve a git ref or local path into `.harn/skills-cache/` so the layered resolver picks it up.
Install(SkillsInstallArgs),
/// Scaffold a new SKILL.md bundle under `.harn/skills/<name>/`.
New(SkillsNewArgs),
}
#[derive(Debug, Args)]
pub(crate) struct SkillsListArgs {
/// Emit newline-delimited JSON (one record per skill) instead of a table.
#[arg(long)]
pub json: bool,
/// Optional path used to anchor manifest and project discovery (defaults to cwd).
#[arg(long = "from", value_name = "PATH")]
pub from: Option<String>,
/// Extra skill-discovery roots (repeatable). Same as `harn run --skill-dir`.
#[arg(long = "skill-dir", value_name = "PATH")]
pub skill_dir: Vec<String>,
/// Include shadowed (lower-priority) entries as well as the winners.
#[arg(long)]
pub all: bool,
}
#[derive(Debug, Args)]
pub(crate) struct SkillsInspectArgs {
/// Skill id to inspect (e.g. `deploy` or `acme/ops/deploy`).
pub name: String,
/// Emit JSON instead of a human-readable dump.
#[arg(long)]
pub json: bool,
/// Optional path used to anchor manifest and project discovery (defaults to cwd).
#[arg(long = "from", value_name = "PATH")]
pub from: Option<String>,
/// Extra skill-discovery roots (repeatable).
#[arg(long = "skill-dir", value_name = "PATH")]
pub skill_dir: Vec<String>,
}
#[derive(Debug, Args)]
pub(crate) struct SkillsMatchArgs {
/// Prompt text to score every discovered skill against.
pub query: String,
/// Top-N matches to display. Default 5.
#[arg(long, default_value_t = 5)]
pub top_n: usize,
/// Emit JSON instead of a ranked table.
#[arg(long)]
pub json: bool,
/// Simulate working-file path globs (repeatable).
#[arg(long = "working-file", value_name = "PATH")]
pub working_files: Vec<String>,
/// Optional path used to anchor manifest and project discovery.
#[arg(long = "from", value_name = "PATH")]
pub from: Option<String>,
/// Extra skill-discovery roots (repeatable).
#[arg(long = "skill-dir", value_name = "PATH")]
pub skill_dir: Vec<String>,
}
#[derive(Debug, Args)]
pub(crate) struct SkillsInstallArgs {
/// Spec: a git URL, `owner/repo`, or a local filesystem path.
pub spec: String,
/// Optional human name / directory label for the cached install.
#[arg(long)]
pub name: Option<String>,
/// Git tag or branch to pin (only applies to git specs).
#[arg(long)]
pub tag: Option<String>,
/// Optional namespace prefix registered with the installed skills.
#[arg(long)]
pub namespace: Option<String>,
}
#[derive(Debug, Args)]
pub(crate) struct SkillsNewArgs {
/// Skill identifier (used as the directory name and default `name:`).
pub name: String,
/// One-line `short:` card for the SKILL.md frontmatter.
#[arg(long)]
pub description: Option<String>,
/// Override the destination directory. Defaults to `.harn/skills/<name>/`.
#[arg(long = "dir", value_name = "PATH")]
pub dir: Option<String>,
/// Overwrite any existing files at the destination.
#[arg(long)]
pub force: bool,
}