Skip to content

Commit 17318e0

Browse files
committed
chore(tooling): support Chalk activation metadata
1 parent b6e1147 commit 17318e0

2 files changed

Lines changed: 177 additions & 9 deletions

File tree

scripts/init-skill.sh

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,19 @@ Required:
1313
Options:
1414
--owner <chalk|project> Skill owner (default: project)
1515
--version <x.y.z> Initial version (default: 1.0.0)
16-
--metadata-version <n> Frontmatter schema version (default: 1)
16+
--metadata-version <n> Frontmatter schema version (default: 2)
1717
--allowed-tools <text> Optional allowed-tools field
1818
--argument-hint <text> Optional argument-hint field
19+
--capabilities <text> Optional capability tags (comma-separated)
20+
--activation-intents <text> Optional trigger phrases (comma-separated)
21+
--activation-events <text> Optional event names (comma-separated)
22+
--activation-artifacts <text> Optional repo paths or globs (comma-separated)
23+
--risk-level <low|medium|high> Optional side-effect hint
1924
--path <dir> Root path for skills (default: skills)
2025
2126
Examples:
2227
scripts/init-skill.sh site-map --description "Create site maps from captured flow context" --owner chalk --allowed-tools "Read, Glob, Write"
28+
scripts/init-skill.sh create-adr --description "Create ADR docs when the user asks for architecture decisions" --owner chalk --capabilities "docs.create,architecture.adr" --activation-intents "create adr,write architecture decision" --activation-events "user-prompt" --activation-artifacts "docs/adr/**" --risk-level low
2329
scripts/init-skill.sh my-team-helper --description "Project helper skill" --owner project --path .chalk/skills
2430
USAGE
2531
}
@@ -38,10 +44,15 @@ NAME="$1"
3844
shift
3945
OWNER="project"
4046
VERSION="1.0.0"
41-
METADATA_VERSION="1"
47+
METADATA_VERSION="2"
4248
DESCRIPTION=""
4349
ALLOWED_TOOLS=""
4450
ARGUMENT_HINT=""
51+
CAPABILITIES=""
52+
ACTIVATION_INTENTS=""
53+
ACTIVATION_EVENTS=""
54+
ACTIVATION_ARTIFACTS=""
55+
RISK_LEVEL=""
4556
ROOT_PATH="skills"
4657

4758
while [[ $# -gt 0 ]]; do
@@ -70,6 +81,26 @@ while [[ $# -gt 0 ]]; do
7081
ARGUMENT_HINT="${2:-}"
7182
shift 2
7283
;;
84+
--capabilities)
85+
CAPABILITIES="${2:-}"
86+
shift 2
87+
;;
88+
--activation-intents)
89+
ACTIVATION_INTENTS="${2:-}"
90+
shift 2
91+
;;
92+
--activation-events)
93+
ACTIVATION_EVENTS="${2:-}"
94+
shift 2
95+
;;
96+
--activation-artifacts)
97+
ACTIVATION_ARTIFACTS="${2:-}"
98+
shift 2
99+
;;
100+
--risk-level)
101+
RISK_LEVEL="${2:-}"
102+
shift 2
103+
;;
73104
--path)
74105
ROOT_PATH="${2:-}"
75106
shift 2
@@ -111,6 +142,21 @@ if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
111142
exit 1
112143
fi
113144

145+
if [[ "$METADATA_VERSION" != "1" && "$METADATA_VERSION" != "2" ]]; then
146+
echo "ERROR: --metadata-version must be '1' or '2'"
147+
exit 1
148+
fi
149+
150+
if [[ -n "$RISK_LEVEL" && "$RISK_LEVEL" != "low" && "$RISK_LEVEL" != "medium" && "$RISK_LEVEL" != "high" ]]; then
151+
echo "ERROR: --risk-level must be one of low, medium, high"
152+
exit 1
153+
fi
154+
155+
if [[ "$METADATA_VERSION" != "2" && (-n "$CAPABILITIES" || -n "$ACTIVATION_INTENTS" || -n "$ACTIVATION_EVENTS" || -n "$ACTIVATION_ARTIFACTS" || -n "$RISK_LEVEL") ]]; then
156+
echo "ERROR: activation metadata requires --metadata-version 2"
157+
exit 1
158+
fi
159+
114160
SKILL_DIR="$ROOT_PATH/$NAME"
115161
SKILL_FILE="$SKILL_DIR/SKILL.md"
116162

@@ -134,6 +180,21 @@ mkdir -p "$SKILL_DIR"
134180
if [[ -n "$ARGUMENT_HINT" ]]; then
135181
echo "argument-hint: \"$ARGUMENT_HINT\""
136182
fi
183+
if [[ -n "$CAPABILITIES" ]]; then
184+
echo "capabilities: $CAPABILITIES"
185+
fi
186+
if [[ -n "$ACTIVATION_INTENTS" ]]; then
187+
echo "activation-intents: $ACTIVATION_INTENTS"
188+
fi
189+
if [[ -n "$ACTIVATION_EVENTS" ]]; then
190+
echo "activation-events: $ACTIVATION_EVENTS"
191+
fi
192+
if [[ -n "$ACTIVATION_ARTIFACTS" ]]; then
193+
echo "activation-artifacts: $ACTIVATION_ARTIFACTS"
194+
fi
195+
if [[ -n "$RISK_LEVEL" ]]; then
196+
echo "risk-level: $RISK_LEVEL"
197+
fi
137198
echo "---"
138199
echo
139200
echo "# $NAME"

scripts/validate-skills.sh

Lines changed: 114 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,80 @@ ROOT="${1:-skills}"
55
FAILED=0
66
COUNT=0
77

8+
trim() {
9+
printf '%s' "$1" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//'
10+
}
11+
12+
get_frontmatter_value() {
13+
local frontmatter="$1"
14+
local key="$2"
15+
printf '%s\n' "$frontmatter" | sed -n "s/^$key:[[:space:]]*//p" | head -n1 | sed 's/^"//;s/"$//'
16+
}
17+
18+
validate_csv_values() {
19+
local file="$1"
20+
local field="$2"
21+
local value="$3"
22+
local item
23+
local seen=0
24+
25+
IFS=',' read -r -a items <<< "$value"
26+
for item in "${items[@]}"; do
27+
item="$(trim "$item")"
28+
if [[ -z "$item" ]]; then
29+
echo "FAIL $file: $field contains an empty entry"
30+
FAILED=1
31+
continue
32+
fi
33+
seen=1
34+
done
35+
36+
if [[ "$seen" -eq 0 ]]; then
37+
echo "FAIL $file: $field must contain at least one value"
38+
FAILED=1
39+
fi
40+
}
41+
42+
validate_capabilities() {
43+
local file="$1"
44+
local value="$2"
45+
local capability
46+
47+
validate_csv_values "$file" "capabilities" "$value"
48+
49+
IFS=',' read -r -a items <<< "$value"
50+
for capability in "${items[@]}"; do
51+
capability="$(trim "$capability")"
52+
[[ -z "$capability" ]] && continue
53+
if [[ ! "$capability" =~ ^[a-z0-9]+([.-][a-z0-9]+)*$ ]]; then
54+
echo "FAIL $file: invalid capability '$capability'"
55+
FAILED=1
56+
fi
57+
done
58+
}
59+
60+
validate_activation_events() {
61+
local file="$1"
62+
local value="$2"
63+
local event
64+
65+
validate_csv_values "$file" "activation-events" "$value"
66+
67+
IFS=',' read -r -a items <<< "$value"
68+
for event in "${items[@]}"; do
69+
event="$(trim "$event")"
70+
[[ -z "$event" ]] && continue
71+
case "$event" in
72+
user-prompt|session-start|pre-tool-use|post-tool-use|pre-compact|session-end)
73+
;;
74+
*)
75+
echo "FAIL $file: unsupported activation event '$event'"
76+
FAILED=1
77+
;;
78+
esac
79+
done
80+
}
81+
882
if [[ ! -d "$ROOT" ]]; then
983
echo "ERROR: skills root not found: $ROOT"
1084
exit 1
@@ -22,11 +96,16 @@ for file in "$ROOT"/*/SKILL.md; do
2296
continue
2397
fi
2498

25-
name="$(printf '%s\n' "$frontmatter" | sed -n 's/^name:[[:space:]]*//p' | head -n1 | tr -d '"')"
26-
description="$(printf '%s\n' "$frontmatter" | sed -n 's/^description:[[:space:]]*//p' | head -n1 | tr -d '"')"
27-
owner="$(printf '%s\n' "$frontmatter" | sed -n 's/^owner:[[:space:]]*//p' | head -n1 | tr -d '"')"
28-
version="$(printf '%s\n' "$frontmatter" | sed -n 's/^version:[[:space:]]*//p' | head -n1 | tr -d '"')"
29-
metadata_version="$(printf '%s\n' "$frontmatter" | sed -n 's/^metadata-version:[[:space:]]*//p' | head -n1 | tr -d '"')"
99+
name="$(get_frontmatter_value "$frontmatter" "name")"
100+
description="$(get_frontmatter_value "$frontmatter" "description")"
101+
owner="$(get_frontmatter_value "$frontmatter" "owner")"
102+
version="$(get_frontmatter_value "$frontmatter" "version")"
103+
metadata_version="$(get_frontmatter_value "$frontmatter" "metadata-version")"
104+
capabilities="$(get_frontmatter_value "$frontmatter" "capabilities")"
105+
activation_intents="$(get_frontmatter_value "$frontmatter" "activation-intents")"
106+
activation_events="$(get_frontmatter_value "$frontmatter" "activation-events")"
107+
activation_artifacts="$(get_frontmatter_value "$frontmatter" "activation-artifacts")"
108+
risk_level="$(get_frontmatter_value "$frontmatter" "risk-level")"
30109

31110
if [[ -z "$name" || -z "$description" || -z "$owner" || -z "$version" || -z "$metadata_version" ]]; then
32111
echo "FAIL $file: missing one of required keys (name, description, owner, version, metadata-version)"
@@ -48,8 +127,8 @@ for file in "$ROOT"/*/SKILL.md; do
48127
FAILED=1
49128
fi
50129

51-
if [[ "$metadata_version" != "1" ]]; then
52-
echo "FAIL $file: metadata-version must be '1', got '$metadata_version'"
130+
if [[ "$metadata_version" != "1" && "$metadata_version" != "2" ]]; then
131+
echo "FAIL $file: metadata-version must be '1' or '2', got '$metadata_version'"
53132
FAILED=1
54133
fi
55134

@@ -63,6 +142,34 @@ for file in "$ROOT"/*/SKILL.md; do
63142
FAILED=1
64143
fi
65144

145+
if [[ "$metadata_version" == "1" && (-n "$capabilities" || -n "$activation_intents" || -n "$activation_events" || -n "$activation_artifacts" || -n "$risk_level") ]]; then
146+
echo "FAIL $file: activation metadata requires metadata-version '2'"
147+
FAILED=1
148+
fi
149+
150+
if [[ "$metadata_version" == "2" ]]; then
151+
if [[ -n "$capabilities" ]]; then
152+
validate_capabilities "$file" "$capabilities"
153+
fi
154+
155+
if [[ -n "$activation_intents" ]]; then
156+
validate_csv_values "$file" "activation-intents" "$activation_intents"
157+
fi
158+
159+
if [[ -n "$activation_events" ]]; then
160+
validate_activation_events "$file" "$activation_events"
161+
fi
162+
163+
if [[ -n "$activation_artifacts" ]]; then
164+
validate_csv_values "$file" "activation-artifacts" "$activation_artifacts"
165+
fi
166+
167+
if [[ -n "$risk_level" && "$risk_level" != "low" && "$risk_level" != "medium" && "$risk_level" != "high" ]]; then
168+
echo "FAIL $file: risk-level must be low, medium, or high"
169+
FAILED=1
170+
fi
171+
fi
172+
66173
done
67174

68175
# Enforce provider-agnostic skill packages.

0 commit comments

Comments
 (0)