@uipath/skills 1.204.0 → 1.204.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.cursor-plugin/plugin.json +1 -1
- package/CODEOWNERS +12 -14
- package/package.json +1 -1
- package/skills/uipath-agents/references/coded/embedding-in-flows.md +1 -3
- package/skills/uipath-agents/references/coded/quickstart.md +0 -2
- package/skills/uipath-agents/references/lowcode/capabilities/inline-in-flow/inline-in-flow.md +10 -8
- package/skills/uipath-agents/references/lowcode/prompting/autonomous-agent-prompting-guide.md +1 -1
- package/skills/uipath-human-in-the-loop/SKILL.md +1 -3
- package/skills/uipath-human-in-the-loop/references/hitl-node-apptask.md +0 -2
- package/skills/uipath-human-in-the-loop/references/hitl-node-coded-action-app.md +0 -2
- package/skills/uipath-human-in-the-loop/references/hitl-node-quickform.md +2 -2
- package/skills/uipath-maestro-flow/.maintenance/README.md +265 -0
- package/skills/uipath-maestro-flow/.maintenance/check-all.sh +40 -0
- package/skills/uipath-maestro-flow/.maintenance/check-anchors.sh +101 -0
- package/skills/uipath-maestro-flow/.maintenance/check-depth.sh +132 -0
- package/skills/uipath-maestro-flow/.maintenance/check-link-text.sh +123 -0
- package/skills/uipath-maestro-flow/.maintenance/check-links.sh +73 -0
- package/skills/uipath-maestro-flow/.maintenance/check-orphans.sh +93 -0
- package/skills/uipath-maestro-flow/.maintenance/check-plugin-pairs.sh +39 -0
- package/skills/uipath-maestro-flow/.maintenance/check-template.sh +42 -0
- package/skills/uipath-maestro-flow/.maintenance/check-uip-commands.sh +270 -0
- package/skills/uipath-maestro-flow/.maintenance/check-versions.sh +160 -0
- package/skills/uipath-maestro-flow/SKILL.md +69 -886
- package/skills/uipath-maestro-flow/references/author/CAPABILITY.md +207 -0
- package/skills/uipath-maestro-flow/references/author/brownfield.md +91 -0
- package/skills/uipath-maestro-flow/references/author/editing-operations-cli.md +190 -0
- package/skills/uipath-maestro-flow/references/author/editing-operations-json.md +374 -0
- package/skills/uipath-maestro-flow/references/author/editing-operations.md +104 -0
- package/skills/uipath-maestro-flow/references/author/greenfield.md +420 -0
- package/skills/uipath-maestro-flow/references/author/planning-arch.md +364 -0
- package/skills/uipath-maestro-flow/references/author/planning-impl.md +291 -0
- package/skills/uipath-maestro-flow/references/author/plugins/agent/impl.md +237 -0
- package/skills/uipath-maestro-flow/references/author/plugins/agent/planning.md +97 -0
- package/skills/uipath-maestro-flow/references/author/plugins/agentic-process/impl.md +107 -0
- package/skills/uipath-maestro-flow/references/author/plugins/agentic-process/planning.md +61 -0
- package/skills/uipath-maestro-flow/references/author/plugins/api-workflow/impl.md +108 -0
- package/skills/uipath-maestro-flow/references/author/plugins/api-workflow/planning.md +60 -0
- package/skills/uipath-maestro-flow/references/author/plugins/batch-transform/impl.md +171 -0
- package/skills/uipath-maestro-flow/references/author/plugins/batch-transform/planning.md +72 -0
- package/skills/uipath-maestro-flow/references/author/plugins/connector/impl-inline.md +120 -0
- package/skills/uipath-maestro-flow/references/author/plugins/connector/impl.md +463 -0
- package/skills/uipath-maestro-flow/references/author/plugins/connector/planning.md +186 -0
- package/skills/uipath-maestro-flow/references/author/plugins/connector-trigger/impl.md +517 -0
- package/skills/uipath-maestro-flow/references/author/plugins/connector-trigger/planning.md +115 -0
- package/skills/uipath-maestro-flow/references/author/plugins/conversational-agent/impl.md +309 -0
- package/skills/uipath-maestro-flow/references/author/plugins/conversational-agent/planning.md +133 -0
- package/skills/uipath-maestro-flow/references/author/plugins/data-fabric/impl.md +428 -0
- package/skills/uipath-maestro-flow/references/author/plugins/data-fabric/planning.md +188 -0
- package/skills/uipath-maestro-flow/references/author/plugins/decision/impl.md +83 -0
- package/skills/uipath-maestro-flow/references/author/plugins/decision/planning.md +38 -0
- package/skills/uipath-maestro-flow/references/author/plugins/delay/impl.md +38 -0
- package/skills/uipath-maestro-flow/references/author/plugins/delay/planning.md +53 -0
- package/skills/uipath-maestro-flow/references/author/plugins/end/impl.md +56 -0
- package/skills/uipath-maestro-flow/references/author/plugins/end/planning.md +28 -0
- package/skills/uipath-maestro-flow/references/author/plugins/flow/impl.md +107 -0
- package/skills/uipath-maestro-flow/references/author/plugins/flow/planning.md +58 -0
- package/skills/uipath-maestro-flow/references/author/plugins/hitl/impl.md +181 -0
- package/skills/uipath-maestro-flow/references/author/plugins/hitl/planning.md +166 -0
- package/skills/uipath-maestro-flow/references/author/plugins/http/impl-connector.md +86 -0
- package/skills/uipath-maestro-flow/references/author/plugins/http/impl-manual.md +68 -0
- package/skills/uipath-maestro-flow/references/author/plugins/http/impl.md +173 -0
- package/skills/uipath-maestro-flow/references/author/plugins/http/planning.md +107 -0
- package/skills/uipath-maestro-flow/references/author/plugins/inline-agent/impl.md +540 -0
- package/skills/uipath-maestro-flow/references/author/plugins/inline-agent/planning.md +115 -0
- package/skills/uipath-maestro-flow/references/author/plugins/inline-voice-agent/impl.md +269 -0
- package/skills/uipath-maestro-flow/references/author/plugins/inline-voice-agent/planning.md +128 -0
- package/skills/uipath-maestro-flow/references/author/plugins/ixp/impl.md +424 -0
- package/skills/uipath-maestro-flow/references/author/plugins/ixp/planning.md +95 -0
- package/skills/uipath-maestro-flow/references/author/plugins/loop/impl.md +403 -0
- package/skills/uipath-maestro-flow/references/author/plugins/loop/planning.md +60 -0
- package/skills/uipath-maestro-flow/references/author/plugins/merge/impl.md +43 -0
- package/skills/uipath-maestro-flow/references/author/plugins/merge/planning.md +24 -0
- package/skills/uipath-maestro-flow/references/author/plugins/queue/impl.md +82 -0
- package/skills/uipath-maestro-flow/references/author/plugins/queue/planning.md +44 -0
- package/skills/uipath-maestro-flow/references/author/plugins/rpa/impl.md +117 -0
- package/skills/uipath-maestro-flow/references/author/plugins/rpa/planning.md +61 -0
- package/skills/uipath-maestro-flow/references/author/plugins/scheduled-trigger/impl.md +56 -0
- package/skills/uipath-maestro-flow/references/author/plugins/scheduled-trigger/planning.md +93 -0
- package/skills/uipath-maestro-flow/references/author/plugins/script/impl.md +98 -0
- package/skills/uipath-maestro-flow/references/author/plugins/script/planning.md +42 -0
- package/skills/uipath-maestro-flow/references/author/plugins/subflow/impl.md +164 -0
- package/skills/uipath-maestro-flow/references/author/plugins/subflow/planning.md +35 -0
- package/skills/uipath-maestro-flow/references/author/plugins/summarize/impl.md +189 -0
- package/skills/uipath-maestro-flow/references/author/plugins/summarize/planning.md +66 -0
- package/skills/uipath-maestro-flow/references/author/plugins/switch/impl.md +72 -0
- package/skills/uipath-maestro-flow/references/author/plugins/switch/planning.md +34 -0
- package/skills/uipath-maestro-flow/references/author/plugins/terminate/impl.md +48 -0
- package/skills/uipath-maestro-flow/references/author/plugins/terminate/planning.md +29 -0
- package/skills/uipath-maestro-flow/references/author/plugins/transform/impl.md +252 -0
- package/skills/uipath-maestro-flow/references/author/plugins/transform/planning.md +47 -0
- package/skills/uipath-maestro-flow/references/diagnose/CAPABILITY.md +73 -0
- package/skills/uipath-maestro-flow/references/diagnose/failure-modes.md +353 -0
- package/skills/uipath-maestro-flow/references/diagnose/troubleshooting-guide.md +174 -0
- package/skills/uipath-maestro-flow/references/evaluate/CAPABILITY.md +134 -0
- package/skills/uipath-maestro-flow/references/evaluate/commands-reference.md +376 -0
- package/skills/uipath-maestro-flow/references/evaluate/eval-sets-guide.md +227 -0
- package/skills/uipath-maestro-flow/references/evaluate/evaluators-guide.md +143 -0
- package/skills/uipath-maestro-flow/references/evaluate/running-guide.md +215 -0
- package/skills/uipath-maestro-flow/references/evaluate/upload-safety.md +94 -0
- package/skills/uipath-maestro-flow/references/operate/CAPABILITY.md +77 -0
- package/skills/uipath-maestro-flow/references/operate/manage.md +39 -0
- package/skills/uipath-maestro-flow/references/operate/run.md +121 -0
- package/skills/uipath-maestro-flow/references/operate/ship.md +57 -0
- package/skills/uipath-maestro-flow/references/shared/action-nodes.md +100 -0
- package/skills/uipath-maestro-flow/references/shared/cli-commands.md +269 -0
- package/skills/uipath-maestro-flow/references/shared/cli-conventions.md +178 -0
- package/skills/uipath-maestro-flow/references/shared/file-format.md +582 -0
- package/skills/uipath-maestro-flow/references/shared/node-output-wiring.md +86 -0
- package/skills/uipath-maestro-flow/references/shared/ux-narration-and-todos.md +113 -0
- package/skills/uipath-maestro-flow/references/shared/variables-and-expressions.md +787 -0
- package/skills/uipath-platform/references/integration-service/activities.md +2 -2
- package/skills/uipath-platform/references/integration-service/activity-generation.md +8 -1
- package/skills/uipath-platform/references/integration-service/triggers.md +1 -3
- package/version-manifest.json +1 -1
- package/skills/uipath-maestro-flow/examples/AquariumSafetyStop.flow.ts +0 -26
- package/skills/uipath-maestro-flow/examples/ArchiveCardExtract.flow.ts +0 -38
- package/skills/uipath-maestro-flow/examples/BakeOffEntryForm.flow.ts +0 -27
- package/skills/uipath-maestro-flow/examples/BeeHiveLedger.flow.ts +0 -61
- package/skills/uipath-maestro-flow/examples/BeltProgression.flow.ts +0 -53
- package/skills/uipath-maestro-flow/examples/BirdCountLookup.flow.ts +0 -24
- package/skills/uipath-maestro-flow/examples/ClubDirectory.flow.ts +0 -56
- package/skills/uipath-maestro-flow/examples/ConcertSoundcheck.flow.ts +0 -59
- package/skills/uipath-maestro-flow/examples/DoorbellLog.flow.ts +0 -45
- package/skills/uipath-maestro-flow/examples/FestivalMapScaffold.flow.ts +0 -22
- package/skills/uipath-maestro-flow/examples/FieldTripQuickForm.flow.ts +0 -45
- package/skills/uipath-maestro-flow/examples/FossilCatalogEnrich.flow.ts +0 -26
- package/skills/uipath-maestro-flow/examples/GallerySubmission.flow.ts +0 -67
- package/skills/uipath-maestro-flow/examples/GreenhouseWatering.flow.ts +0 -39
- package/skills/uipath-maestro-flow/examples/HarbourRadioLine.flow.ts +0 -31
- package/skills/uipath-maestro-flow/examples/HerbariumDispatch.flow.ts +0 -34
- package/skills/uipath-maestro-flow/examples/KilnReview.flow.ts +0 -38
- package/skills/uipath-maestro-flow/examples/LibraryDeskChat.flow.ts +0 -39
- package/skills/uipath-maestro-flow/examples/LighthouseSignal.flow.ts +0 -30
- package/skills/uipath-maestro-flow/examples/MeteorShowerPages.flow.ts +0 -39
- package/skills/uipath-maestro-flow/examples/NeighborhoodWalkPlanner.flow.ts +0 -27
- package/skills/uipath-maestro-flow/examples/ObservatorySeeing.flow.ts +0 -51
- package/skills/uipath-maestro-flow/examples/OralHistoryDigest.flow.ts +0 -31
- package/skills/uipath-maestro-flow/examples/PlanetariumConfirmation.flow.ts +0 -34
- package/skills/uipath-maestro-flow/examples/PlantNameAdvisor.flow.ts +0 -28
- package/skills/uipath-maestro-flow/examples/PostcardCaption.flow.ts +0 -44
- package/skills/uipath-maestro-flow/examples/PotteryStudioCallback.flow.ts +0 -41
- package/skills/uipath-maestro-flow/examples/RecipeScaler.flow.ts +0 -62
- package/skills/uipath-maestro-flow/examples/SeedPacketReader.flow.ts +0 -49
- package/skills/uipath-maestro-flow/examples/TideTableConverter.flow.ts +0 -35
- package/skills/uipath-maestro-flow/examples/TrailLogSummary.flow.ts +0 -75
- package/skills/uipath-maestro-flow/examples/WorkshopInventory.flow.ts +0 -27
- package/skills/uipath-maestro-flow/examples/bindings.json +0 -85
- package/skills/uipath-maestro-flow/references/CLI-LOOP.md +0 -309
- package/skills/uipath-maestro-flow/references/agent-resources.md +0 -74
- package/skills/uipath-maestro-flow/references/agent.md +0 -175
- package/skills/uipath-maestro-flow/references/agentic-process.md +0 -41
- package/skills/uipath-maestro-flow/references/api-workflow.md +0 -29
- package/skills/uipath-maestro-flow/references/author.md +0 -178
- package/skills/uipath-maestro-flow/references/batch-transform.md +0 -23
- package/skills/uipath-maestro-flow/references/bindings.md +0 -178
- package/skills/uipath-maestro-flow/references/branch.md +0 -18
- package/skills/uipath-maestro-flow/references/brownfield.md +0 -152
- package/skills/uipath-maestro-flow/references/connector-params.md +0 -624
- package/skills/uipath-maestro-flow/references/conversational.md +0 -77
- package/skills/uipath-maestro-flow/references/data-fabric.md +0 -268
- package/skills/uipath-maestro-flow/references/delay.md +0 -26
- package/skills/uipath-maestro-flow/references/diagnose.md +0 -141
- package/skills/uipath-maestro-flow/references/document-pipeline.md +0 -47
- package/skills/uipath-maestro-flow/references/error-handling.md +0 -75
- package/skills/uipath-maestro-flow/references/evaluate.md +0 -168
- package/skills/uipath-maestro-flow/references/event-trigger.md +0 -155
- package/skills/uipath-maestro-flow/references/form-trigger.md +0 -41
- package/skills/uipath-maestro-flow/references/hitl.md +0 -169
- package/skills/uipath-maestro-flow/references/http.md +0 -105
- package/skills/uipath-maestro-flow/references/inline-agent.md +0 -132
- package/skills/uipath-maestro-flow/references/ixp.md +0 -167
- package/skills/uipath-maestro-flow/references/loops.md +0 -77
- package/skills/uipath-maestro-flow/references/manual-trigger.md +0 -39
- package/skills/uipath-maestro-flow/references/operate.md +0 -204
- package/skills/uipath-maestro-flow/references/or-processes.md +0 -91
- package/skills/uipath-maestro-flow/references/parallel-merge.md +0 -21
- package/skills/uipath-maestro-flow/references/placeholder.md +0 -70
- package/skills/uipath-maestro-flow/references/published-function.md +0 -66
- package/skills/uipath-maestro-flow/references/queue.md +0 -53
- package/skills/uipath-maestro-flow/references/return.md +0 -20
- package/skills/uipath-maestro-flow/references/rpa-workflow.md +0 -27
- package/skills/uipath-maestro-flow/references/scheduled-trigger.md +0 -34
- package/skills/uipath-maestro-flow/references/script.md +0 -52
- package/skills/uipath-maestro-flow/references/subflow.md +0 -33
- package/skills/uipath-maestro-flow/references/summarize.md +0 -20
- package/skills/uipath-maestro-flow/references/switch.md +0 -20
- package/skills/uipath-maestro-flow/references/terminate.md +0 -22
- package/skills/uipath-maestro-flow/references/transform.md +0 -32
- package/skills/uipath-maestro-flow/references/voice.md +0 -70
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Verify every markdown anchor link (`[text](file.md#anchor)`) resolves to an actual heading in the target file.
|
|
3
|
+
# Usage: bash .maintenance/check-anchors.sh
|
|
4
|
+
# Output: BAD ANCHOR lines per failure, then "anchors_checked=N anchors_bad=M" summary.
|
|
5
|
+
#
|
|
6
|
+
# Skips:
|
|
7
|
+
# - links inside fenced code blocks (```...```)
|
|
8
|
+
# - links inside inline code spans (`...`)
|
|
9
|
+
# - links without a `#anchor` fragment
|
|
10
|
+
# - http(s):// links
|
|
11
|
+
# - slash-command links
|
|
12
|
+
# - same-file anchor-only links (#anchor without a path)
|
|
13
|
+
# - links to files that don't exist (those are caught by check-links.sh, not this checker)
|
|
14
|
+
#
|
|
15
|
+
# An anchor resolves if the target file supplies it either as a heading slug or as an
|
|
16
|
+
# explicit `<a id="...">` / `<a name="...">` tag (GitHub honors both).
|
|
17
|
+
#
|
|
18
|
+
# Slug rule (matches GitHub heading-anchor generation):
|
|
19
|
+
# 1. Lowercase the heading
|
|
20
|
+
# 2. Strip backtick, asterisk, underscore, and any non-alphanumeric/non-space/non-dash character
|
|
21
|
+
# 3. Replace each remaining space with `-`
|
|
22
|
+
# 4. Separator characters do not collapse
|
|
23
|
+
#
|
|
24
|
+
# See .maintenance/README.md for common gotchas.
|
|
25
|
+
|
|
26
|
+
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
27
|
+
cd "$ROOT" || exit 1
|
|
28
|
+
|
|
29
|
+
heading_anchors() {
|
|
30
|
+
/usr/bin/awk '
|
|
31
|
+
/^#{1,6} /{
|
|
32
|
+
sub(/^#+ /, "");
|
|
33
|
+
gsub(/[`*_]/, "");
|
|
34
|
+
anchor = tolower($0);
|
|
35
|
+
gsub(/[^a-z0-9 -]/, "", anchor);
|
|
36
|
+
gsub(/ /, "-", anchor);
|
|
37
|
+
print anchor;
|
|
38
|
+
}' "$1"
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
# Explicit anchor tags authored inline (e.g. `<a id="attachment-preflight"></a>`).
|
|
42
|
+
# Used where the link target is a paragraph or table row rather than a heading.
|
|
43
|
+
explicit_anchors() {
|
|
44
|
+
/usr/bin/grep -oE '<a[[:space:]]+(id|name)="[^"]+"' "$1" \
|
|
45
|
+
| /usr/bin/sed -E 's/.*="([^"]+)"/\1/'
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
target_anchors() {
|
|
49
|
+
heading_anchors "$1"
|
|
50
|
+
explicit_anchors "$1"
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
# Per-file: strip fenced code blocks and inline code spans, then extract links.
|
|
54
|
+
extract_links() {
|
|
55
|
+
/usr/bin/awk '
|
|
56
|
+
/^```/ { fenced = !fenced; next }
|
|
57
|
+
!fenced {
|
|
58
|
+
gsub(/`[^`]*`/, "", $0)
|
|
59
|
+
while (match($0, /\]\([^)]+\)/)) {
|
|
60
|
+
link = substr($0, RSTART, RLENGTH)
|
|
61
|
+
sub(/^\]\(/, "", link)
|
|
62
|
+
sub(/\)$/, "", link)
|
|
63
|
+
print link
|
|
64
|
+
$0 = substr($0, RSTART + RLENGTH)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
' "$1"
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
broken=0
|
|
71
|
+
checked=0
|
|
72
|
+
|
|
73
|
+
while IFS= read -r srcfile; do
|
|
74
|
+
while IFS= read -r raw; do
|
|
75
|
+
case "$raw" in
|
|
76
|
+
\#*) continue ;;
|
|
77
|
+
http*|/uipath*) continue ;;
|
|
78
|
+
esac
|
|
79
|
+
[[ "$raw" != *#* ]] && continue
|
|
80
|
+
target_path="${raw%%#*}"
|
|
81
|
+
anchor="${raw#*#}"
|
|
82
|
+
[ -z "$target_path" ] && continue
|
|
83
|
+
srcdir=$(/usr/bin/dirname "$srcfile")
|
|
84
|
+
full="$srcdir/$target_path"
|
|
85
|
+
resolved=$(cd "$(/usr/bin/dirname "$full")" 2>/dev/null && /bin/pwd)/$(/usr/bin/basename "$full")
|
|
86
|
+
[ ! -f "$resolved" ] && continue
|
|
87
|
+
checked=$((checked+1))
|
|
88
|
+
if target_anchors "$resolved" | /usr/bin/grep -qx -- "$anchor"; then
|
|
89
|
+
:
|
|
90
|
+
else
|
|
91
|
+
echo "BAD ANCHOR $srcfile -> $raw"
|
|
92
|
+
broken=$((broken+1))
|
|
93
|
+
fi
|
|
94
|
+
done < <(extract_links "$srcfile")
|
|
95
|
+
done < <(/usr/bin/find . -name "*.md" -type f)
|
|
96
|
+
|
|
97
|
+
echo ""
|
|
98
|
+
echo "anchors_checked=$checked anchors_bad=$broken"
|
|
99
|
+
|
|
100
|
+
[ "$broken" -gt 0 ] && exit 1
|
|
101
|
+
exit 0
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Verify every markdown file under references/ is reachable from SKILL.md within the configured max hops.
|
|
3
|
+
# Usage: bash .maintenance/check-depth.sh [MAX_HOPS]
|
|
4
|
+
# Default MAX_HOPS=2. Output per file: "DEPTH=N path/to/file.md" + summary.
|
|
5
|
+
#
|
|
6
|
+
# Counts BFS hops via outbound links. Folder links count as reachability for every file in the folder
|
|
7
|
+
# (per the convention documented in .maintenance/README.md — folder links satisfy practical reachability).
|
|
8
|
+
#
|
|
9
|
+
# Skips:
|
|
10
|
+
# - Links inside fenced code blocks (```...```)
|
|
11
|
+
# - Links inside inline code spans (`...`)
|
|
12
|
+
# - http(s):// links
|
|
13
|
+
# - Anchor-only links (#anchor)
|
|
14
|
+
# - Slash-command links (/uipath:..., /uipath-feedback)
|
|
15
|
+
#
|
|
16
|
+
# Exits non-zero if any file exceeds MAX_HOPS or is unreachable.
|
|
17
|
+
# Compatible with bash 3.2 (no associative arrays — uses tab-separated state files).
|
|
18
|
+
|
|
19
|
+
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
20
|
+
cd "$ROOT" || exit 1
|
|
21
|
+
|
|
22
|
+
MAX_HOPS="${1:-2}"
|
|
23
|
+
|
|
24
|
+
# State files: each line is "<depth>\t<absolute_path>"
|
|
25
|
+
visited=$(/usr/bin/mktemp)
|
|
26
|
+
frontier=$(/usr/bin/mktemp)
|
|
27
|
+
next_frontier=$(/usr/bin/mktemp)
|
|
28
|
+
trap 'rm -f "$visited" "$frontier" "$next_frontier"' EXIT
|
|
29
|
+
|
|
30
|
+
# Per-file: strip fenced code blocks and inline code spans, then extract links.
|
|
31
|
+
extract_links() {
|
|
32
|
+
/usr/bin/awk '
|
|
33
|
+
/^```/ { fenced = !fenced; next }
|
|
34
|
+
!fenced {
|
|
35
|
+
gsub(/`[^`]*`/, "", $0)
|
|
36
|
+
while (match($0, /\]\([^)]+\)/)) {
|
|
37
|
+
link = substr($0, RSTART, RLENGTH)
|
|
38
|
+
sub(/^\]\(/, "", link)
|
|
39
|
+
sub(/\)$/, "", link)
|
|
40
|
+
print link
|
|
41
|
+
$0 = substr($0, RSTART + RLENGTH)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
' "$1"
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
resolve_link() {
|
|
48
|
+
local from_file="$1"
|
|
49
|
+
local link="$2"
|
|
50
|
+
link="${link%%#*}"
|
|
51
|
+
[ -z "$link" ] && return 1
|
|
52
|
+
case "$link" in
|
|
53
|
+
http://*|https://*) return 1 ;;
|
|
54
|
+
/uipath:*|/uipath-feedback*) return 1 ;;
|
|
55
|
+
esac
|
|
56
|
+
local from_dir
|
|
57
|
+
from_dir=$(/usr/bin/dirname "$from_file")
|
|
58
|
+
local target="$from_dir/$link"
|
|
59
|
+
local resolved_dir
|
|
60
|
+
resolved_dir=$(cd "$(/usr/bin/dirname "$target")" 2>/dev/null && /bin/pwd)
|
|
61
|
+
[ -z "$resolved_dir" ] && return 1
|
|
62
|
+
echo "$resolved_dir/$(/usr/bin/basename "$target")"
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
is_visited() {
|
|
66
|
+
/usr/bin/grep -q " $1$" "$visited"
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
mark_visited() {
|
|
70
|
+
printf "%s\t%s\n" "$1" "$2" >> "$visited"
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
depth_of() {
|
|
74
|
+
/usr/bin/awk -F'\t' -v p="$1" '$2 == p { print $1; exit }' "$visited"
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
# Seed with SKILL.md at depth 0
|
|
78
|
+
mark_visited 0 "$ROOT/SKILL.md"
|
|
79
|
+
echo "$ROOT/SKILL.md" > "$frontier"
|
|
80
|
+
|
|
81
|
+
current_depth=0
|
|
82
|
+
while [ -s "$frontier" ] && [ "$current_depth" -lt "$MAX_HOPS" ]; do
|
|
83
|
+
: > "$next_frontier"
|
|
84
|
+
while IFS= read -r file; do
|
|
85
|
+
[ -z "$file" ] && continue
|
|
86
|
+
while IFS= read -r raw_link; do
|
|
87
|
+
target=$(resolve_link "$file" "$raw_link") || continue
|
|
88
|
+
[ -z "$target" ] && continue
|
|
89
|
+
if [ -d "$target" ]; then
|
|
90
|
+
while IFS= read -r f; do
|
|
91
|
+
[ -z "$f" ] && continue
|
|
92
|
+
if ! is_visited "$f"; then
|
|
93
|
+
mark_visited $((current_depth + 1)) "$f"
|
|
94
|
+
echo "$f" >> "$next_frontier"
|
|
95
|
+
fi
|
|
96
|
+
done < <(/usr/bin/find "$target" -name "*.md" -type f)
|
|
97
|
+
elif [ -f "$target" ]; then
|
|
98
|
+
if ! is_visited "$target"; then
|
|
99
|
+
mark_visited $((current_depth + 1)) "$target"
|
|
100
|
+
echo "$target" >> "$next_frontier"
|
|
101
|
+
fi
|
|
102
|
+
fi
|
|
103
|
+
done < <(extract_links "$file")
|
|
104
|
+
done < "$frontier"
|
|
105
|
+
/bin/cp "$next_frontier" "$frontier"
|
|
106
|
+
current_depth=$((current_depth + 1))
|
|
107
|
+
done
|
|
108
|
+
|
|
109
|
+
# Report — every .md under references/ should be visited within MAX_HOPS
|
|
110
|
+
total=0
|
|
111
|
+
unreachable=0
|
|
112
|
+
exceeded=0
|
|
113
|
+
while IFS= read -r f; do
|
|
114
|
+
[ -z "$f" ] && continue
|
|
115
|
+
total=$((total + 1))
|
|
116
|
+
d=$(depth_of "$f")
|
|
117
|
+
if [ -z "$d" ]; then
|
|
118
|
+
echo "UNREACHABLE ${f#$ROOT/}"
|
|
119
|
+
unreachable=$((unreachable + 1))
|
|
120
|
+
elif [ "$d" -gt "$MAX_HOPS" ]; then
|
|
121
|
+
echo "EXCEEDS_DEPTH ($d > $MAX_HOPS) ${f#$ROOT/}"
|
|
122
|
+
exceeded=$((exceeded + 1))
|
|
123
|
+
fi
|
|
124
|
+
done < <(/usr/bin/find "$ROOT/references" -name "*.md" -type f | /usr/bin/sort -u)
|
|
125
|
+
|
|
126
|
+
echo ""
|
|
127
|
+
echo "max_hops=$MAX_HOPS total_files=$total reachable_within=$((total - unreachable - exceeded)) unreachable=$unreachable exceeds_depth=$exceeded"
|
|
128
|
+
|
|
129
|
+
if [ "$unreachable" -gt 0 ] || [ "$exceeded" -gt 0 ]; then
|
|
130
|
+
exit 1
|
|
131
|
+
fi
|
|
132
|
+
exit 0
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Verify markdown link text agrees with link URL when text contains a file-like token.
|
|
3
|
+
# Usage: bash .maintenance/check-link-text.sh
|
|
4
|
+
# Output: BROKEN lines per failure, then "checked=N broken=M" summary.
|
|
5
|
+
#
|
|
6
|
+
# Failure modes (all hard failures):
|
|
7
|
+
# - basename-mismatch: text contains a file-like token whose basename != URL basename.
|
|
8
|
+
# - prefix-mismatch: basenames match but the directory prefix in the text doesn't match
|
|
9
|
+
# the URL's directory (and isn't a suffix of it). Catches misleading text like
|
|
10
|
+
# "operate/manage.md" pointing to "references/manage.md".
|
|
11
|
+
# - folder-url-but-text-is-file: URL ends with "/" but text claims a file.
|
|
12
|
+
#
|
|
13
|
+
# Skips:
|
|
14
|
+
# - links inside fenced code blocks (```...```)
|
|
15
|
+
# - links inside inline code spans (`...`)
|
|
16
|
+
# - http(s):// links
|
|
17
|
+
# - slash-command links (/uipath:..., /uipath-feedback)
|
|
18
|
+
# - same-file anchor-only links (#anchor)
|
|
19
|
+
# - image links ()
|
|
20
|
+
# - links whose text contains no file-like token
|
|
21
|
+
#
|
|
22
|
+
# File-like token regex: [A-Za-z0-9_./-]+\.(md|sh|json|js|ts|py|cs|xaml|flow|yaml|yml)
|
|
23
|
+
#
|
|
24
|
+
# Run from any directory; resolves to the skill root automatically.
|
|
25
|
+
|
|
26
|
+
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
27
|
+
cd "$ROOT" || exit 1
|
|
28
|
+
|
|
29
|
+
broken=0
|
|
30
|
+
checked=0
|
|
31
|
+
|
|
32
|
+
# Per-file: strip fenced code blocks and inline code spans, then emit "lineno<TAB>text<TAB>url"
|
|
33
|
+
# for every non-image link on every line.
|
|
34
|
+
extract_pairs() {
|
|
35
|
+
/usr/bin/awk '
|
|
36
|
+
/^```/ { fenced = !fenced; next }
|
|
37
|
+
!fenced {
|
|
38
|
+
lineno = NR
|
|
39
|
+
line = $0
|
|
40
|
+
gsub(/`[^`]*`/, "", line)
|
|
41
|
+
while (match(line, /\[[^]]*\]\([^)]+\)/)) {
|
|
42
|
+
m = substr(line, RSTART, RLENGTH)
|
|
43
|
+
# Skip image links: 
|
|
44
|
+
if (RSTART > 1 && substr(line, RSTART - 1, 1) == "!") {
|
|
45
|
+
line = substr(line, RSTART + RLENGTH)
|
|
46
|
+
continue
|
|
47
|
+
}
|
|
48
|
+
ti = index(m, "](")
|
|
49
|
+
text = substr(m, 2, ti - 2)
|
|
50
|
+
url = substr(m, ti + 2, length(m) - ti - 2)
|
|
51
|
+
printf "%d\t%s\t%s\n", lineno, text, url
|
|
52
|
+
line = substr(line, RSTART + RLENGTH)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
' "$1"
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
# Extract the first file-like token from a string. Empty if none found.
|
|
59
|
+
first_file_token() {
|
|
60
|
+
printf '%s' "$1" | /usr/bin/grep -oE '[A-Za-z0-9_./-]+\.(md|sh|json|js|ts|py|cs|xaml|flow|yaml|yml)' | /usr/bin/head -n1
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
while IFS= read -r srcfile; do
|
|
64
|
+
while IFS=$'\t' read -r lineno text url; do
|
|
65
|
+
[ -z "$url" ] && continue
|
|
66
|
+
|
|
67
|
+
case "$url" in
|
|
68
|
+
http://*|https://*) continue ;;
|
|
69
|
+
/uipath:*|/uipath-feedback*) continue ;;
|
|
70
|
+
\#*) continue ;;
|
|
71
|
+
esac
|
|
72
|
+
|
|
73
|
+
url_nofrag="${url%%#*}"
|
|
74
|
+
[ -z "$url_nofrag" ] && continue
|
|
75
|
+
|
|
76
|
+
text_token=$(first_file_token "$text")
|
|
77
|
+
[ -z "$text_token" ] && continue
|
|
78
|
+
|
|
79
|
+
checked=$((checked+1))
|
|
80
|
+
|
|
81
|
+
case "$url_nofrag" in
|
|
82
|
+
*/)
|
|
83
|
+
echo "BROKEN $srcfile:$lineno -> text=\"$text\" url=$url reason=folder-url-but-text-is-file"
|
|
84
|
+
broken=$((broken+1))
|
|
85
|
+
continue
|
|
86
|
+
;;
|
|
87
|
+
esac
|
|
88
|
+
|
|
89
|
+
text_base="${text_token##*/}"
|
|
90
|
+
url_base="${url_nofrag##*/}"
|
|
91
|
+
|
|
92
|
+
if [ "$text_base" != "$url_base" ]; then
|
|
93
|
+
echo "BROKEN $srcfile:$lineno -> text=\"$text\" url=$url reason=basename-mismatch"
|
|
94
|
+
broken=$((broken+1))
|
|
95
|
+
continue
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
# Basenames match. Check directory coherence.
|
|
99
|
+
text_dir="${text_token%/*}"
|
|
100
|
+
[ "$text_dir" = "$text_token" ] && text_dir=""
|
|
101
|
+
url_dir="${url_nofrag%/*}"
|
|
102
|
+
[ "$url_dir" = "$url_nofrag" ] && url_dir=""
|
|
103
|
+
|
|
104
|
+
if [ -n "$text_dir" ] && [ "$text_dir" != "$url_dir" ]; then
|
|
105
|
+
# Tolerate the case where the text directory is a suffix of the URL directory
|
|
106
|
+
# (e.g., text "author/greenfield.md" vs. url "references/author/greenfield.md").
|
|
107
|
+
mismatch=1
|
|
108
|
+
case "/$url_dir/" in
|
|
109
|
+
*/"$text_dir"/*) mismatch=0 ;;
|
|
110
|
+
esac
|
|
111
|
+
if [ "$mismatch" -eq 1 ]; then
|
|
112
|
+
echo "BROKEN $srcfile:$lineno -> text=\"$text\" url=$url reason=prefix-mismatch"
|
|
113
|
+
broken=$((broken+1))
|
|
114
|
+
fi
|
|
115
|
+
fi
|
|
116
|
+
done < <(extract_pairs "$srcfile")
|
|
117
|
+
done < <(/usr/bin/find . -name "*.md" -type f)
|
|
118
|
+
|
|
119
|
+
echo ""
|
|
120
|
+
echo "checked=$checked broken=$broken"
|
|
121
|
+
|
|
122
|
+
[ "$broken" -gt 0 ] && exit 1
|
|
123
|
+
exit 0
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Verify every markdown file-path link in the skill resolves to an existing file or directory.
|
|
3
|
+
# Usage: bash .maintenance/check-links.sh
|
|
4
|
+
# Output: BROKEN lines per failure, then "checked=N broken=M" summary.
|
|
5
|
+
#
|
|
6
|
+
# Skips:
|
|
7
|
+
# - links inside fenced code blocks (```...```)
|
|
8
|
+
# - links inside inline code spans (`...`)
|
|
9
|
+
# - http(s):// links
|
|
10
|
+
# - slash-command links (/uipath:..., /uipath-feedback)
|
|
11
|
+
# - same-file anchor-only links (#anchor)
|
|
12
|
+
#
|
|
13
|
+
# Accepts:
|
|
14
|
+
# - file links resolving to a file (-f)
|
|
15
|
+
# - folder links resolving to a directory (-d)
|
|
16
|
+
#
|
|
17
|
+
# Run from any directory; resolves to the skill root automatically.
|
|
18
|
+
|
|
19
|
+
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
20
|
+
cd "$ROOT" || exit 1
|
|
21
|
+
|
|
22
|
+
broken=0
|
|
23
|
+
checked=0
|
|
24
|
+
|
|
25
|
+
# Per-file: strip fenced code blocks and inline code spans, then extract links.
|
|
26
|
+
extract_links() {
|
|
27
|
+
/usr/bin/awk '
|
|
28
|
+
/^```/ { fenced = !fenced; next }
|
|
29
|
+
!fenced {
|
|
30
|
+
# Strip inline code spans: anything between two backticks
|
|
31
|
+
gsub(/`[^`]*`/, "", $0)
|
|
32
|
+
# Match all ](...) link targets on this line
|
|
33
|
+
while (match($0, /\]\([^)]+\)/)) {
|
|
34
|
+
link = substr($0, RSTART, RLENGTH)
|
|
35
|
+
sub(/^\]\(/, "", link)
|
|
36
|
+
sub(/\)$/, "", link)
|
|
37
|
+
print link
|
|
38
|
+
$0 = substr($0, RSTART + RLENGTH)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
' "$1"
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
while IFS= read -r srcfile; do
|
|
45
|
+
while IFS= read -r link; do
|
|
46
|
+
link="${link%%#*}"
|
|
47
|
+
[ -z "$link" ] && continue
|
|
48
|
+
case "$link" in
|
|
49
|
+
http://*|https://*) continue ;;
|
|
50
|
+
/uipath:*|/uipath-feedback*) continue ;;
|
|
51
|
+
esac
|
|
52
|
+
filedir=$(/usr/bin/dirname "$srcfile")
|
|
53
|
+
target="$filedir/$link"
|
|
54
|
+
resolved_dir=$(cd "$(/usr/bin/dirname "$target")" 2>/dev/null && /bin/pwd)
|
|
55
|
+
resolved_base=$(/usr/bin/basename "$target")
|
|
56
|
+
resolved="$resolved_dir/$resolved_base"
|
|
57
|
+
checked=$((checked+1))
|
|
58
|
+
if [ -f "$resolved" ] || [ -d "$resolved" ]; then
|
|
59
|
+
:
|
|
60
|
+
elif [ -d "$target" ]; then
|
|
61
|
+
:
|
|
62
|
+
else
|
|
63
|
+
echo "BROKEN $srcfile -> $link"
|
|
64
|
+
broken=$((broken+1))
|
|
65
|
+
fi
|
|
66
|
+
done < <(extract_links "$srcfile")
|
|
67
|
+
done < <(/usr/bin/find . -name "*.md" -type f)
|
|
68
|
+
|
|
69
|
+
echo ""
|
|
70
|
+
echo "checked=$checked broken=$broken"
|
|
71
|
+
|
|
72
|
+
[ "$broken" -gt 0 ] && exit 1
|
|
73
|
+
exit 0
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Find .md files under references/ that no other .md file links to.
|
|
3
|
+
# Usage: bash .maintenance/check-orphans.sh
|
|
4
|
+
# Output: ORPHAN lines per orphan, then "files_checked=N orphans=M" summary.
|
|
5
|
+
#
|
|
6
|
+
# Skips:
|
|
7
|
+
# - SKILL.md (the entry point — has no inbound links by design)
|
|
8
|
+
# - CAPABILITY.md files (linked from SKILL.md and peer indexes)
|
|
9
|
+
# - Links inside fenced code blocks (```...```)
|
|
10
|
+
# - Links inside inline code spans (`...`)
|
|
11
|
+
#
|
|
12
|
+
# A file is considered "linked to" if any other .md file references it via
|
|
13
|
+
# `[text](path)` or via a folder link (`[text](folder/)`) that resolves to its parent dir.
|
|
14
|
+
#
|
|
15
|
+
# Exits non-zero if any orphans found.
|
|
16
|
+
|
|
17
|
+
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
18
|
+
cd "$ROOT" || exit 1
|
|
19
|
+
|
|
20
|
+
# Per-file: strip fenced code blocks and inline code spans, then extract links.
|
|
21
|
+
extract_links() {
|
|
22
|
+
/usr/bin/awk '
|
|
23
|
+
/^```/ { fenced = !fenced; next }
|
|
24
|
+
!fenced {
|
|
25
|
+
gsub(/`[^`]*`/, "", $0)
|
|
26
|
+
while (match($0, /\]\([^)]+\)/)) {
|
|
27
|
+
link = substr($0, RSTART, RLENGTH)
|
|
28
|
+
sub(/^\]\(/, "", link)
|
|
29
|
+
sub(/\)$/, "", link)
|
|
30
|
+
print link
|
|
31
|
+
$0 = substr($0, RSTART + RLENGTH)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
' "$1"
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
resolve_link() {
|
|
38
|
+
local from_file="$1"
|
|
39
|
+
local link="$2"
|
|
40
|
+
link="${link%%#*}"
|
|
41
|
+
[ -z "$link" ] && return 1
|
|
42
|
+
case "$link" in
|
|
43
|
+
http://*|https://*) return 1 ;;
|
|
44
|
+
/uipath:*|/uipath-feedback*) return 1 ;;
|
|
45
|
+
esac
|
|
46
|
+
local from_dir
|
|
47
|
+
from_dir=$(/usr/bin/dirname "$from_file")
|
|
48
|
+
local target="$from_dir/$link"
|
|
49
|
+
local resolved_dir
|
|
50
|
+
resolved_dir=$(cd "$(/usr/bin/dirname "$target")" 2>/dev/null && /bin/pwd)
|
|
51
|
+
[ -z "$resolved_dir" ] && return 1
|
|
52
|
+
echo "$resolved_dir/$(/usr/bin/basename "$target")"
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
# Build the set of every .md path that any .md file links to (file links + folder links).
|
|
56
|
+
linked_set=$(/usr/bin/mktemp)
|
|
57
|
+
trap 'rm -f "$linked_set"' EXIT
|
|
58
|
+
|
|
59
|
+
while IFS= read -r srcfile; do
|
|
60
|
+
while IFS= read -r raw_link; do
|
|
61
|
+
target=$(resolve_link "$srcfile" "$raw_link") || continue
|
|
62
|
+
[ -z "$target" ] && continue
|
|
63
|
+
if [ -d "$target" ]; then
|
|
64
|
+
# Folder link → mark every .md inside as linked
|
|
65
|
+
/usr/bin/find "$target" -name "*.md" -type f >> "$linked_set"
|
|
66
|
+
elif [ -f "$target" ]; then
|
|
67
|
+
echo "$target" >> "$linked_set"
|
|
68
|
+
fi
|
|
69
|
+
done < <(extract_links "$srcfile")
|
|
70
|
+
done < <(/usr/bin/find . -name "*.md" -type f)
|
|
71
|
+
|
|
72
|
+
# Sort + dedupe linked set
|
|
73
|
+
sorted_linked=$(/usr/bin/sort -u "$linked_set")
|
|
74
|
+
|
|
75
|
+
# Check each .md under references/ — orphan if not in linked set, with exceptions.
|
|
76
|
+
orphans=0
|
|
77
|
+
checked=0
|
|
78
|
+
while IFS= read -r f; do
|
|
79
|
+
[ -z "$f" ] && continue
|
|
80
|
+
basename=$(/usr/bin/basename "$f")
|
|
81
|
+
[ "$basename" = "CAPABILITY.md" ] && continue
|
|
82
|
+
checked=$((checked + 1))
|
|
83
|
+
if ! echo "$sorted_linked" | /usr/bin/grep -qx "$f"; then
|
|
84
|
+
echo "ORPHAN ${f#$ROOT/}"
|
|
85
|
+
orphans=$((orphans + 1))
|
|
86
|
+
fi
|
|
87
|
+
done < <(/usr/bin/find "$ROOT/references" -name "*.md" -type f | /usr/bin/sort)
|
|
88
|
+
|
|
89
|
+
echo ""
|
|
90
|
+
echo "files_checked=$checked orphans=$orphans"
|
|
91
|
+
|
|
92
|
+
[ "$orphans" -gt 0 ] && exit 1
|
|
93
|
+
exit 0
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Verify every plugin folder under references/author/plugins/ has both
|
|
3
|
+
# `planning.md` and `impl.md` (the per-plugin convention from skill-structure.md).
|
|
4
|
+
# Usage: bash .maintenance/check-plugin-pairs.sh
|
|
5
|
+
# Output: MISSING lines per failure, then "plugins_checked=N missing_files=M" summary.
|
|
6
|
+
#
|
|
7
|
+
# Exits non-zero if any plugin folder is missing planning.md or impl.md.
|
|
8
|
+
|
|
9
|
+
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
10
|
+
cd "$ROOT" || exit 1
|
|
11
|
+
|
|
12
|
+
PLUGINS_DIR="$ROOT/references/author/plugins"
|
|
13
|
+
|
|
14
|
+
if [ ! -d "$PLUGINS_DIR" ]; then
|
|
15
|
+
echo "ERROR: plugins directory not found at $PLUGINS_DIR" >&2
|
|
16
|
+
exit 2
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
REQUIRED_FILES=("planning.md" "impl.md")
|
|
20
|
+
|
|
21
|
+
failures=0
|
|
22
|
+
checked=0
|
|
23
|
+
|
|
24
|
+
while IFS= read -r plugin_dir; do
|
|
25
|
+
[ -z "$plugin_dir" ] && continue
|
|
26
|
+
checked=$((checked + 1))
|
|
27
|
+
for required in "${REQUIRED_FILES[@]}"; do
|
|
28
|
+
if [ ! -f "$plugin_dir/$required" ]; then
|
|
29
|
+
echo "MISSING ${plugin_dir#$ROOT/}/$required"
|
|
30
|
+
failures=$((failures + 1))
|
|
31
|
+
fi
|
|
32
|
+
done
|
|
33
|
+
done < <(/usr/bin/find "$PLUGINS_DIR" -mindepth 1 -maxdepth 1 -type d | /usr/bin/sort)
|
|
34
|
+
|
|
35
|
+
echo ""
|
|
36
|
+
echo "plugins_checked=$checked missing_files=$failures"
|
|
37
|
+
|
|
38
|
+
[ "$failures" -gt 0 ] && exit 1
|
|
39
|
+
exit 0
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Verify each CAPABILITY.md follows the canonical 6-section template:
|
|
3
|
+
# 1. When to use this capability
|
|
4
|
+
# 2. Critical rules
|
|
5
|
+
# 3. Workflow
|
|
6
|
+
# 4. Common tasks
|
|
7
|
+
# 5. Anti-patterns
|
|
8
|
+
# 6. References
|
|
9
|
+
# Usage: bash .maintenance/check-template.sh
|
|
10
|
+
# Exits non-zero if any CAPABILITY.md is missing a required section.
|
|
11
|
+
|
|
12
|
+
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
13
|
+
cd "$ROOT" || exit 1
|
|
14
|
+
|
|
15
|
+
REQUIRED_SECTIONS=(
|
|
16
|
+
"When to use this capability"
|
|
17
|
+
"Critical rules"
|
|
18
|
+
"Workflow"
|
|
19
|
+
"Common tasks"
|
|
20
|
+
"Anti-patterns"
|
|
21
|
+
"References"
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
failures=0
|
|
25
|
+
checked=0
|
|
26
|
+
|
|
27
|
+
while IFS= read -r capfile; do
|
|
28
|
+
[ -z "$capfile" ] && continue
|
|
29
|
+
checked=$((checked + 1))
|
|
30
|
+
for section in "${REQUIRED_SECTIONS[@]}"; do
|
|
31
|
+
if ! /usr/bin/grep -qE "^## $section\$" "$capfile"; then
|
|
32
|
+
echo "MISSING_SECTION ${capfile#$ROOT/} -> ## $section"
|
|
33
|
+
failures=$((failures + 1))
|
|
34
|
+
fi
|
|
35
|
+
done
|
|
36
|
+
done < <(/usr/bin/find "$ROOT/references" -name "CAPABILITY.md" -type f | /usr/bin/sort)
|
|
37
|
+
|
|
38
|
+
echo ""
|
|
39
|
+
echo "capabilities_checked=$checked missing_sections=$failures"
|
|
40
|
+
|
|
41
|
+
[ "$failures" -gt 0 ] && exit 1
|
|
42
|
+
exit 0
|