@event4u/agent-config 2.23.0 → 2.24.0

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.
Files changed (58) hide show
  1. package/.agent-src/commands/video/from-script.md +123 -0
  2. package/.agent-src/commands/video/scene.md +92 -0
  3. package/.agent-src/commands/video/stitch.md +83 -0
  4. package/.agent-src/commands/video/storyboard.md +95 -0
  5. package/.agent-src/commands/video.md +59 -0
  6. package/.agent-src/personas/README.md +3 -0
  7. package/.agent-src/personas/ai-video-technical-director.md +81 -0
  8. package/.agent-src/personas/hollywood-director.md +99 -0
  9. package/.agent-src/personas/pixar-storyboard-artist.md +98 -0
  10. package/.agent-src/skills/character-consistency/SKILL.md +120 -0
  11. package/.agent-src/skills/motion-choreographer/SKILL.md +149 -0
  12. package/.agent-src/skills/pixar-storyteller/SKILL.md +107 -0
  13. package/.agent-src/skills/scene-expander/SKILL.md +122 -0
  14. package/.agent-src/skills/scene-expander/scene-blueprint.schema.yaml +108 -0
  15. package/.agent-src/skills/subagent-orchestration/SKILL.md +17 -15
  16. package/.agent-src/skills/video-director/SKILL.md +113 -0
  17. package/.agent-src/templates/agent-settings.md +19 -0
  18. package/.agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  19. package/.claude-plugin/marketplace.json +11 -1
  20. package/CHANGELOG.md +22 -0
  21. package/README.md +4 -4
  22. package/config/agent-settings.template.yml +28 -0
  23. package/docs/adrs/caveman/0001-default-off-until-bench.md +2 -2
  24. package/docs/adrs/cost/0001-hard-stop-hook.md +1 -1
  25. package/docs/adrs/smoke/0001-per-tier-smoke-scripts.md +2 -2
  26. package/docs/architecture.md +2 -2
  27. package/docs/catalog.md +14 -4
  28. package/docs/contracts/command-clusters.md +1 -0
  29. package/docs/contracts/compression-default-kill-criterion.md +1 -1
  30. package/docs/contracts/file-ownership-matrix.json +337 -0
  31. package/docs/getting-started.md +1 -1
  32. package/docs/parity/ruflo.md +3 -3
  33. package/package.json +1 -1
  34. package/scripts/ai-video/adapters/gemini-veo.sh +57 -0
  35. package/scripts/ai-video/adapters/higgsfield.sh +82 -0
  36. package/scripts/ai-video/adapters/kling.sh +54 -0
  37. package/scripts/ai-video/adapters/openai-images.sh +52 -0
  38. package/scripts/ai-video/adapters/sora.sh +54 -0
  39. package/scripts/ai-video/lib/adapter-common.sh +116 -0
  40. package/scripts/ai-video/lib/adapter-contract.md +163 -0
  41. package/scripts/ai-video/lib/fixtures/gemini-veo/result.json +1 -0
  42. package/scripts/ai-video/lib/fixtures/gemini-veo/scene-0001.mp4 +1 -0
  43. package/scripts/ai-video/lib/fixtures/higgsfield/result.json +1 -0
  44. package/scripts/ai-video/lib/fixtures/higgsfield/scene-0001.mp4 +1 -0
  45. package/scripts/ai-video/lib/fixtures/kling/result.json +1 -0
  46. package/scripts/ai-video/lib/fixtures/kling/scene-0001.mp4 +1 -0
  47. package/scripts/ai-video/lib/fixtures/openai-images/result.json +1 -0
  48. package/scripts/ai-video/lib/fixtures/openai-images/scene-0001.png +3 -0
  49. package/scripts/ai-video/lib/fixtures/sora/result.json +1 -0
  50. package/scripts/ai-video/lib/fixtures/sora/scene-0001.mp4 +1 -0
  51. package/scripts/ai-video/lib/load-config.sh +140 -0
  52. package/scripts/ai-video/lib/operator-pick.sh +119 -0
  53. package/scripts/ai-video/lib/parse-blueprint.sh +122 -0
  54. package/scripts/ai-video/lib/redact.sh +85 -0
  55. package/scripts/ai-video/lib/validate-deps.sh +132 -0
  56. package/scripts/ai-video/stitch.sh +154 -0
  57. package/scripts/ai-video/test-pipeline.sh +169 -0
  58. package/scripts/schemas/command.schema.json +8 -0
@@ -0,0 +1,169 @@
1
+ #!/usr/bin/env bash
2
+ # test-pipeline.sh — offline smoke test for /video:* against
3
+ # agents/ai-video/examples/banana-arc/. Dry-run only; no network.
4
+ #
5
+ # Asserts (per agents/roadmaps/ai-video-pipeline.md Phase 6 Step 3):
6
+ # 1. parse-blueprint.sh output matches the committed expected.json
7
+ # per scene (3 scenes, 3 tiers).
8
+ # 2. character.json descriptor tokens (silhouette, palette, wardrobe,
9
+ # prop) appear verbatim in each scene's prompt.subject — the
10
+ # load-bearing character-lock substring assertion.
11
+ # 3. audio.* branching is correct: scene 2 → enable_native_audio=true,
12
+ # scenes 1+3 → false.
13
+ # 4. native-audio-capable adapter (gemini-veo) advertises capability
14
+ # audio=native; non-audio adapter (openai-images) advertises
15
+ # audio=none; stitch.sh sees audio_embedded per scene.
16
+ # 5. stitch.sh dry-run returns the committed manifest's stitch_output
17
+ # path without invoking ffmpeg or any network.
18
+ # 6. visual regression: each scene's locked.png is non-empty + has
19
+ # PNG magic; pairwise NCC ≥ 0.95 when `compare` is available.
20
+ # When unavailable, asserts byte-identity (the three frames are
21
+ # committed identical for the offline path).
22
+ #
23
+ # Exit 0 = all assertions pass; 1 = at least one failure (counted +
24
+ # summarized at the end).
25
+
26
+ set -uo pipefail
27
+
28
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
29
+ ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
30
+ PROJECT="$ROOT/agents/ai-video/examples/banana-arc"
31
+
32
+ PASS=0
33
+ FAIL=0
34
+ FAILS=""
35
+
36
+ ok() { PASS=$((PASS+1)); printf ' ✅ %s\n' "$1"; }
37
+ fail() { FAIL=$((FAIL+1)); FAILS="$FAILS\n ❌ $1"; printf ' ❌ %s\n' "$1"; }
38
+
39
+ require() {
40
+ if command -v "$1" >/dev/null 2>&1; then return 0; fi
41
+ fail "required tool missing: $1"
42
+ return 1
43
+ }
44
+
45
+ require jq || exit 1
46
+
47
+ printf '\n== test-pipeline.sh — banana-arc golden run (offline) ==\n\n'
48
+
49
+ # ---------------------------------------------------------------- 1
50
+ printf '[1/6] parse-blueprint vs. expected.json\n'
51
+ SCENES="01-simple 02-dialogue-native-audio 03-edge-duration"
52
+ for s in $SCENES; do
53
+ actual="$(bash "$ROOT/scripts/ai-video/lib/parse-blueprint.sh" "$PROJECT/scenes/$s/blueprint.txt" 2>/dev/null \
54
+ | jq -S . 2>/dev/null || true)"
55
+ expected="$(jq -S . "$PROJECT/scenes/$s/expected.json" 2>/dev/null || true)"
56
+ if [ -z "$actual" ]; then
57
+ fail "$s: parse-blueprint produced no output"
58
+ elif [ "$actual" = "$expected" ]; then
59
+ ok "$s: parse-blueprint matches expected.json"
60
+ else
61
+ fail "$s: parse-blueprint mismatch (diff actual vs. expected.json)"
62
+ fi
63
+ done
64
+
65
+ # ---------------------------------------------------------------- 2
66
+ printf '\n[2/6] character.json descriptors verbatim in prompt.subject\n'
67
+ SILHOUETTE="$(jq -r '.characters[0].silhouette' "$PROJECT/character.json")"
68
+ PALETTE="$(jq -r '.characters[0].palette' "$PROJECT/character.json")"
69
+ WARDROBE="$(jq -r '.characters[0].wardrobe' "$PROJECT/character.json")"
70
+ PROP="$(jq -r '.characters[0].prop' "$PROJECT/character.json")"
71
+
72
+ for s in $SCENES; do
73
+ subj="$(jq -r '.prompt.subject' "$PROJECT/scenes/$s/expected.json")"
74
+ miss=""
75
+ case "$subj" in *"$SILHOUETTE"*) :;; *) miss="$miss silhouette";; esac
76
+ case "$subj" in *"$PALETTE"*) :;; *) miss="$miss palette";; esac
77
+ case "$subj" in *"$WARDROBE"*) :;; *) miss="$miss wardrobe";; esac
78
+ case "$subj" in *"$PROP"*) :;; *) miss="$miss prop";; esac
79
+ if [ -z "$miss" ]; then
80
+ ok "$s: silhouette + palette + wardrobe + prop verbatim in prompt.subject"
81
+ else
82
+ fail "$s: missing verbatim tokens in prompt.subject:$miss"
83
+ fi
84
+ done
85
+
86
+ # ---------------------------------------------------------------- 3
87
+ printf '\n[3/6] audio.* branching matches manifest\n'
88
+ for entry in 01-simple:false 02-dialogue-native-audio:true 03-edge-duration:false; do
89
+ s="${entry%%:*}"
90
+ want="${entry##*:}"
91
+ got="$(jq -r '.audio.enable_native_audio' "$PROJECT/scenes/$s/expected.json")"
92
+ manifest_got="$(jq -r --arg id "$s" '.scenes[] | select(.id==$id) | .audio_embedded' "$PROJECT/manifest.json")"
93
+ if [ "$got" = "$want" ] && [ "$manifest_got" = "$want" ]; then
94
+ ok "$s: enable_native_audio=$got, manifest.audio_embedded=$manifest_got"
95
+ else
96
+ fail "$s: audio branching drift (expected=$want, blueprint=$got, manifest=$manifest_got)"
97
+ fi
98
+ done
99
+
100
+ # ---------------------------------------------------------------- 4
101
+ printf '\n[4/6] adapter capability declarations\n'
102
+ declare_caps() {
103
+ local adapter="$1"; local expected="$2"
104
+ local out got
105
+ out="$(AIV_DRYRUN=true bash "$ROOT/scripts/ai-video/adapters/$adapter.sh" capability 2>/dev/null || true)"
106
+ got="$(printf '%s' "$out" | jq -r '.audio // empty' 2>/dev/null || true)"
107
+ if [ "$got" = "$expected" ]; then
108
+ ok "$adapter: capability.audio=$got"
109
+ else
110
+ fail "$adapter: capability mismatch (want audio=$expected, got: ${got:-<unparseable: $out>})"
111
+ fi
112
+ }
113
+ declare_caps gemini-veo "native"
114
+ declare_caps openai-images "none"
115
+ declare_caps sora "native"
116
+ declare_caps kling "none"
117
+
118
+ # ---------------------------------------------------------------- 5
119
+ printf '\n[5/6] stitch.sh dry-run returns manifest output path\n'
120
+ STITCH_OUT="$(jq -r '.stitch_output' "$PROJECT/manifest.json")"
121
+ stitch_log="$(AIV_DRYRUN=true bash "$ROOT/scripts/ai-video/stitch.sh" \
122
+ "$PROJECT/manifest.json" "$PROJECT/$STITCH_OUT" 2>&1 || true)"
123
+ case "$stitch_log" in
124
+ *"$STITCH_OUT"*) ok "stitch.sh dry-run referenced $STITCH_OUT";;
125
+ *) fail "stitch.sh dry-run did not reference $STITCH_OUT (log: $stitch_log)";;
126
+ esac
127
+
128
+ # ---------------------------------------------------------------- 6
129
+ printf '\n[6/6] visual regression (locked.png pairwise)\n'
130
+ PNG_MAGIC="$(printf '\x89PNG\r\n\x1a\n')"
131
+ prev=""
132
+ have_compare=0
133
+ command -v compare >/dev/null 2>&1 && have_compare=1
134
+ for s in $SCENES; do
135
+ f="$PROJECT/scenes/$s/fixtures/frames/locked.png"
136
+ if [ ! -s "$f" ]; then
137
+ fail "$s: locked.png missing or empty"
138
+ continue
139
+ fi
140
+ head -c 8 "$f" | od -An -c | tr -d ' \n' | grep -q '211PNG' \
141
+ && ok "$s: locked.png is a valid PNG ($(wc -c < "$f" | tr -d ' ') bytes)" \
142
+ || fail "$s: locked.png lacks PNG magic"
143
+ if [ -n "$prev" ]; then
144
+ if [ "$have_compare" -eq 1 ]; then
145
+ ncc="$(compare -metric NCC "$prev" "$f" null: 2>&1 || true)"
146
+ awk_ok="$(awk -v v="$ncc" 'BEGIN { exit !(v+0 >= 0.95) }' && echo yes || echo no)"
147
+ if [ "$awk_ok" = "yes" ]; then
148
+ ok "$s: NCC vs. previous = $ncc (≥ 0.95)"
149
+ else
150
+ fail "$s: NCC vs. previous = $ncc (< 0.95)"
151
+ fi
152
+ else
153
+ if cmp -s "$prev" "$f"; then
154
+ ok "$s: byte-identical to previous (compare unavailable; offline fallback)"
155
+ else
156
+ fail "$s: differs from previous frame and compare is unavailable"
157
+ fi
158
+ fi
159
+ fi
160
+ prev="$f"
161
+ done
162
+
163
+ # ----------------------------------------------------------------
164
+ printf '\n----------------\nresult: %d passed · %d failed\n' "$PASS" "$FAIL"
165
+ if [ "$FAIL" -gt 0 ]; then
166
+ printf '%b\n' "$FAILS"
167
+ exit 1
168
+ fi
169
+ exit 0
@@ -34,6 +34,14 @@
34
34
  "pattern": "^[a-z][a-z0-9-]*$"
35
35
  }
36
36
  },
37
+ "personas": {
38
+ "type": "array",
39
+ "items": {
40
+ "type": "string",
41
+ "pattern": "^[a-z][a-z0-9-]*$"
42
+ },
43
+ "description": "Personas this command invokes (see .agent-src.uncompressed/personas/). Mirrors `skills:`; each entry must match a persona slug."
44
+ },
37
45
  "cluster": {
38
46
  "type": "string",
39
47
  "pattern": "^[a-z][a-z0-9-]*$",