@scrymore/scry-deployer 0.11.1 → 0.11.2-nightly.20261004032624
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/package.json
CHANGED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# AT-16: install skills/scry-native-capture-setup from this checkout with `npx skills add` into a
|
|
3
|
+
# throwaway HOME and project, then check the skill landed and its SKILL.md frontmatter parses.
|
|
4
|
+
# Usage: bash scripts/check-skill-install.sh [skill-name] (default: scry-native-capture-setup)
|
|
5
|
+
# Also fails if the skill names the old epinnock/scry-node repo. Needs network for `npx skills` (npm registry) the first time. Never touches the real HOME or repo.
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
SKILL="${1:-scry-native-capture-setup}"
|
|
8
|
+
REPO="$(cd "$(dirname "$0")/.." && pwd)"
|
|
9
|
+
TMP="$(mktemp -d)"
|
|
10
|
+
trap 'rm -rf "$TMP"' EXIT
|
|
11
|
+
mkdir -p "$TMP/home" "$TMP/project"
|
|
12
|
+
git -C "$TMP/project" init -q .
|
|
13
|
+
|
|
14
|
+
# F14: the skill must name the canonical repo, never the old epinnock/ name.
|
|
15
|
+
if grep -rn "epinnock/scry-node" "$REPO/skills/$SKILL" >/dev/null 2>&1; then
|
|
16
|
+
echo "FAIL: skills/$SKILL still mentions epinnock/scry-node (use scryorg/scry-node)" >&2; exit 1
|
|
17
|
+
fi
|
|
18
|
+
grep -q "npx skills add scryorg/scry-node --skill $SKILL" "$REPO/skills/$SKILL/SKILL.md" \
|
|
19
|
+
|| { echo "FAIL: SKILL.md does not show 'npx skills add scryorg/scry-node --skill $SKILL'" >&2; exit 1; }
|
|
20
|
+
echo "canonical install command: npx skills add scryorg/scry-node --skill $SKILL (this script installs from the local checkout)"
|
|
21
|
+
|
|
22
|
+
echo "install: npx skills add $REPO --skill $SKILL (HOME=$TMP/home)"
|
|
23
|
+
(cd "$TMP/project" && HOME="$TMP/home" npx --yes skills add "$REPO" --skill "$SKILL" -y >"$TMP/install.log" 2>&1) \
|
|
24
|
+
|| { tail -20 "$TMP/install.log" >&2; echo "FAIL: skills add exited non-zero" >&2; exit 1; }
|
|
25
|
+
|
|
26
|
+
# The installer writes the canonical copy to .agents/skills/<name> and links Claude Code to it
|
|
27
|
+
# (other agents such as Amp get a rewritten copy under agent/skills; not checked here).
|
|
28
|
+
FOUND="$TMP/project/.agents/skills/$SKILL/SKILL.md"
|
|
29
|
+
[ -f "$FOUND" ] || { tail -20 "$TMP/install.log" >&2; echo "FAIL: .agents/skills/$SKILL/SKILL.md not found after install" >&2; exit 1; }
|
|
30
|
+
echo "landed: ${FOUND#"$TMP"/}"
|
|
31
|
+
[ -f "$TMP/project/.claude/skills/$SKILL/SKILL.md" ] || { echo "FAIL: Claude Code link .claude/skills/$SKILL missing" >&2; exit 1; }
|
|
32
|
+
echo "landed: project/.claude/skills/$SKILL/SKILL.md (Claude Code)"
|
|
33
|
+
|
|
34
|
+
# Only the requested skill may have been installed (no scry-setup riding along).
|
|
35
|
+
OTHERS="$(find "$TMP/project/.agents/skills" -mindepth 2 -maxdepth 2 -name SKILL.md ! -path "*/$SKILL/*" 2>/dev/null || true)"
|
|
36
|
+
[ -z "$OTHERS" ] || { echo "FAIL: unexpected extra skills installed: $OTHERS" >&2; exit 1; }
|
|
37
|
+
|
|
38
|
+
SKILL_MD="$FOUND" SKILL_NAME="$SKILL" node -e '
|
|
39
|
+
const fs = require("fs"), path = require("path");
|
|
40
|
+
const file = process.env.SKILL_MD, name = process.env.SKILL_NAME;
|
|
41
|
+
const text = fs.readFileSync(file, "utf8");
|
|
42
|
+
const m = /^---\r?\n([\s\S]*?)\r?\n---\r?\n/.exec(text);
|
|
43
|
+
if (!m) { console.error("FAIL: no YAML frontmatter"); process.exit(1); }
|
|
44
|
+
const fm = {};
|
|
45
|
+
for (const line of m[1].split(/\r?\n/)) { const k = /^([A-Za-z_-]+):\s*(.*)$/.exec(line); if (k) fm[k[1]] = k[2].trim(); }
|
|
46
|
+
if (fm.name !== name) { console.error(`FAIL: frontmatter name "${fm.name}" != "${name}"`); process.exit(1); }
|
|
47
|
+
if (!fm.description || fm.description.length < 40 || fm.description.length > 1024) { console.error("FAIL: description missing or outside 40..1024 chars"); process.exit(1); }
|
|
48
|
+
// every relative link in SKILL.md must resolve inside the installed skill
|
|
49
|
+
const dir = path.dirname(file), bad = [];
|
|
50
|
+
for (const l of text.matchAll(/\]\((?!https?:|#)([^)\s]+)\)/g)) if (!fs.existsSync(path.join(dir, l[1]))) bad.push(l[1]);
|
|
51
|
+
if (bad.length) { console.error("FAIL: broken relative links: " + bad.join(", ")); process.exit(1); }
|
|
52
|
+
const files = fs.readdirSync(dir, { recursive: true }).filter((f) => fs.statSync(path.join(dir, f)).isFile());
|
|
53
|
+
console.log(`frontmatter ok: name=${fm.name}, description ${fm.description.length} chars, ${files.length} files installed`);
|
|
54
|
+
'
|
|
55
|
+
echo "PASS: $SKILL installs and parses"
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Drift check: the skill's assets/ are copies of the Kettle sample apps (the sample apps are canonical).
|
|
3
|
+
# Usage: bash scripts/check-skill-sync.sh <scry-sample-ios dir> <scry-sample-android dir>
|
|
4
|
+
# Exit 0 = every copy matches its sample and the CI templates keep the G5 guards; 1 = drift (diff shown).
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
[ $# -eq 2 ] || { echo "usage: $0 <ios-sample-dir> <android-sample-dir>" >&2; exit 2; }
|
|
7
|
+
IOS="$1"; AND="$2"
|
|
8
|
+
ASSETS="$(cd "$(dirname "$0")/../skills/scry-native-capture-setup/assets" && pwd)"
|
|
9
|
+
AK="$AND/app/src"; fail=0
|
|
10
|
+
|
|
11
|
+
check() { # <asset> <sample file>
|
|
12
|
+
if [ ! -f "$2" ]; then echo "MISSING sample file: $2"; fail=1
|
|
13
|
+
elif diff -u "$2" "$ASSETS/$1" >"${TMPDIR:-/tmp}/skill-sync.diff"; then echo "ok $1 == $2"
|
|
14
|
+
else echo "DRIFT $1 differs from $2"; cat "${TMPDIR:-/tmp}/skill-sync.diff"; fail=1; fi
|
|
15
|
+
}
|
|
16
|
+
check ScryLaunch.swift "$IOS/Kettle/ScryLaunch.swift"
|
|
17
|
+
check ScryScreens.swift "$IOS/Kettle/ScryScreens.swift"
|
|
18
|
+
check capture-ios.sh "$IOS/scripts/capture.sh"
|
|
19
|
+
check make-scf.mjs "$IOS/scripts/make-scf.mjs"
|
|
20
|
+
check scry-capture-ios.yml "$IOS/.github/workflows/scry-capture.yml"
|
|
21
|
+
check ScryLaunch.kt "$(ls "$AK"/debug/java/*/*/*/ScryLaunch.kt 2>/dev/null | head -1)"
|
|
22
|
+
check ScryScreens.kt "$(ls "$AK"/debug/java/*/*/*/ScryScreens.kt 2>/dev/null | head -1)"
|
|
23
|
+
check ScryLaunch-release.kt "$(ls "$AK"/release/java/*/*/*/ScryLaunch.kt 2>/dev/null | head -1)"
|
|
24
|
+
check capture-android.sh "$AND/scripts/capture.sh"
|
|
25
|
+
check scry-capture-android.yml "$AND/.github/workflows/scry-capture.yml"
|
|
26
|
+
|
|
27
|
+
# make-scf.mjs is shared: the asset is the iOS version, a superset of the Android sample's (which lacks
|
|
28
|
+
# --tool-name and the kind comment). Only that difference is tolerated for the Android copy.
|
|
29
|
+
if diff "$AND/scripts/make-scf.mjs" "$ASSETS/make-scf.mjs" | grep -E '^[<>]' | grep -vE "tool-name|kind is|kind\" is|tool: \{ name|a component entry" >/dev/null; then
|
|
30
|
+
echo "DRIFT Android make-scf.mjs differs from the shared asset beyond --tool-name"; fail=1
|
|
31
|
+
else echo "ok make-scf.mjs: Android sample differs only by --tool-name / kind comment"; fi
|
|
32
|
+
|
|
33
|
+
# G5 on the CI templates: default branch only, no pull_request(_target), no self-hosted, key only on upload.
|
|
34
|
+
for y in scry-capture-ios.yml scry-capture-android.yml; do
|
|
35
|
+
f="$ASSETS/$y"
|
|
36
|
+
grep -Eq '^\s*(pull_request|pull_request_target)\s*:' "$f" && { echo "G5 FAIL $y: pull_request trigger"; fail=1; }
|
|
37
|
+
grep -qi 'self-hosted' "$f" && { echo "G5 FAIL $y: self-hosted"; fail=1; }
|
|
38
|
+
grep -q 'branches: \[main\]' "$f" || { echo "G5 FAIL $y: not limited to a branch"; fail=1; }
|
|
39
|
+
n="$(grep -c 'secrets\.' "$f")"; [ "$n" -eq 1 ] || { echo "G5 FAIL $y: secrets referenced $n times (want 1, the upload step)"; fail=1; }
|
|
40
|
+
done
|
|
41
|
+
[ "$fail" -eq 0 ] && echo "PASS: skill assets match the samples, CI guards intact" || { echo "FAIL: drift found" >&2; exit 1; }
|