feat(kyberforge): execute the plugin→APM conversion #95
@@ -149,7 +149,7 @@ repos:
|
|||||||
description: Ensure SKILL.md files have required frontmatter fields
|
description: Ensure SKILL.md files have required frontmatter fields
|
||||||
entry: bash
|
entry: bash
|
||||||
language: system
|
language: system
|
||||||
files: 'SKILL\.md$'
|
files: '^plugins/[^/]+/\.apm/skills/[^/]+/SKILL\.md$'
|
||||||
args:
|
args:
|
||||||
- -c
|
- -c
|
||||||
- |
|
- |
|
||||||
|
|||||||
@@ -117,12 +117,17 @@ sync_hooks_json() {
|
|||||||
printf '%s\n' "$(cat "$src")" >"$dst"
|
printf '%s\n' "$(cat "$src")" >"$dst"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Runs entirely inside a backgrounded subshell (see the dispatch loop below), so
|
||||||
|
# FAIL here is that subshell's own copy -- it never touches the parent's FAIL
|
||||||
|
# and must be handed back via status_file instead.
|
||||||
sync_one() {
|
sync_one() {
|
||||||
local plugin_dir="${1%/}"
|
local plugin_dir="${1%/}" status_file="$2"
|
||||||
local apm_dir="$plugin_dir/.apm"
|
local apm_dir="$plugin_dir/.apm"
|
||||||
|
FAIL=0
|
||||||
|
|
||||||
if [[ ! -d "$apm_dir" ]]; then
|
if [[ ! -d "$apm_dir" ]]; then
|
||||||
echo "SKIP $plugin_dir: no .apm/ directory" >&2
|
echo "SKIP $plugin_dir: no .apm/ directory" >&2
|
||||||
|
echo "$FAIL" >"$status_file"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -140,6 +145,7 @@ sync_one() {
|
|||||||
sed 's/^/ /' "$pack_log" >&2
|
sed 's/^/ /' "$pack_log" >&2
|
||||||
rm -f "$pack_log"
|
rm -f "$pack_log"
|
||||||
FAIL=1
|
FAIL=1
|
||||||
|
echo "$FAIL" >"$status_file"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
rm -f "$pack_log"
|
rm -f "$pack_log"
|
||||||
@@ -148,6 +154,7 @@ sync_one() {
|
|||||||
if [[ -z "$bundle_dir" ]]; then
|
if [[ -z "$bundle_dir" ]]; then
|
||||||
echo "FAIL $plugin_dir: apm pack produced no bundle directory under $scratch" >&2
|
echo "FAIL $plugin_dir: apm pack produced no bundle directory under $scratch" >&2
|
||||||
FAIL=1
|
FAIL=1
|
||||||
|
echo "$FAIL" >"$status_file"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -156,10 +163,26 @@ sync_one() {
|
|||||||
sync_dir "$plugin_dir" "$bundle_dir" "$d"
|
sync_dir "$plugin_dir" "$bundle_dir" "$d"
|
||||||
done
|
done
|
||||||
sync_hooks_json "$plugin_dir" "$bundle_dir"
|
sync_hooks_json "$plugin_dir" "$bundle_dir"
|
||||||
|
echo "$FAIL" >"$status_file"
|
||||||
}
|
}
|
||||||
|
|
||||||
for plugin_dir in "$@"; do
|
# Each plugin's `apm pack` is an independent CLI invocation dominated by fixed
|
||||||
sync_one "$plugin_dir"
|
# process-startup cost, not by per-plugin work -- run them concurrently rather
|
||||||
|
# than paying that startup cost N times serially. Output is buffered per plugin
|
||||||
|
# (not streamed) so concurrent DRIFT/FAIL messages from different plugins never
|
||||||
|
# interleave; it's flushed in stable $@ order once every job has finished.
|
||||||
|
declare -a plugin_dirs=("$@")
|
||||||
|
for plugin_dir in "${plugin_dirs[@]}"; do
|
||||||
|
name="$(basename "${plugin_dir%/}")"
|
||||||
|
(sync_one "$plugin_dir" "$SCRATCH_ROOT/$name.status") >"$SCRATCH_ROOT/$name.log" 2>&1 &
|
||||||
|
done
|
||||||
|
wait
|
||||||
|
|
||||||
|
for plugin_dir in "${plugin_dirs[@]}"; do
|
||||||
|
name="$(basename "${plugin_dir%/}")"
|
||||||
|
cat "$SCRATCH_ROOT/$name.log" >&2
|
||||||
|
status="$(cat "$SCRATCH_ROOT/$name.status" 2>/dev/null || echo 1)"
|
||||||
|
[[ "$status" -ne 0 ]] && FAIL=1
|
||||||
done
|
done
|
||||||
|
|
||||||
if [[ "$FAIL" -ne 0 ]]; then
|
if [[ "$FAIL" -ne 0 ]]; then
|
||||||
|
|||||||
Reference in New Issue
Block a user