@codyswann/lisa 2.160.0 → 2.162.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 (180) hide show
  1. package/.agents/plugins/marketplace.json +12 -0
  2. package/.claude-plugin/marketplace.json +24 -0
  3. package/dist/codex/plugin-marketplace-installer.d.ts.map +1 -1
  4. package/dist/codex/plugin-marketplace-installer.js +2 -0
  5. package/dist/codex/plugin-marketplace-installer.js.map +1 -1
  6. package/dist/configs/eslint/harper-fabric.js +2 -2
  7. package/dist/configs/eslint/harper-fabric.js.map +1 -1
  8. package/dist/configs/eslint/index.d.ts +2 -0
  9. package/dist/configs/eslint/index.d.ts.map +1 -1
  10. package/dist/configs/eslint/index.js +2 -0
  11. package/dist/configs/eslint/index.js.map +1 -1
  12. package/dist/configs/eslint/phaser.d.ts +29 -0
  13. package/dist/configs/eslint/phaser.d.ts.map +1 -0
  14. package/dist/configs/eslint/phaser.js +87 -0
  15. package/dist/configs/eslint/phaser.js.map +1 -0
  16. package/dist/configs/vitest/index.d.ts +3 -2
  17. package/dist/configs/vitest/index.d.ts.map +1 -1
  18. package/dist/configs/vitest/index.js +3 -2
  19. package/dist/configs/vitest/index.js.map +1 -1
  20. package/dist/configs/vitest/phaser.d.ts +29 -0
  21. package/dist/configs/vitest/phaser.d.ts.map +1 -0
  22. package/dist/configs/vitest/phaser.js +36 -0
  23. package/dist/configs/vitest/phaser.js.map +1 -0
  24. package/dist/core/config.d.ts +1 -1
  25. package/dist/core/config.d.ts.map +1 -1
  26. package/dist/core/config.js +2 -0
  27. package/dist/core/config.js.map +1 -1
  28. package/dist/detection/detectors/phaser.d.ts +15 -0
  29. package/dist/detection/detectors/phaser.d.ts.map +1 -0
  30. package/dist/detection/detectors/phaser.js +24 -0
  31. package/dist/detection/detectors/phaser.js.map +1 -0
  32. package/dist/detection/index.d.ts.map +1 -1
  33. package/dist/detection/index.js +2 -0
  34. package/dist/detection/index.js.map +1 -1
  35. package/dist/migrations/reconcile-claude-stack-plugins.d.ts.map +1 -1
  36. package/dist/migrations/reconcile-claude-stack-plugins.js +1 -0
  37. package/dist/migrations/reconcile-claude-stack-plugins.js.map +1 -1
  38. package/dist/strategies/package-lisa.d.ts.map +1 -1
  39. package/dist/strategies/package-lisa.js +4 -0
  40. package/dist/strategies/package-lisa.js.map +1 -1
  41. package/harper-fabric/copy-contents/.prettierignore +4 -1
  42. package/harper-fabric/copy-overwrite/knip.json +2 -1
  43. package/harper-fabric/copy-overwrite/tsconfig.eslint.json +2 -1
  44. package/harper-fabric/merge/.oxlintrc.json +2 -1
  45. package/oxlint/harper-fabric.json +2 -1
  46. package/oxlint/phaser.json +11 -0
  47. package/package.json +7 -2
  48. package/phaser/copy-contents/.prettierignore +7 -0
  49. package/phaser/copy-overwrite/.github/workflows/ci.yml +23 -0
  50. package/phaser/copy-overwrite/eslint.config.ts +38 -0
  51. package/phaser/copy-overwrite/knip.json +17 -0
  52. package/phaser/copy-overwrite/tsconfig.eslint.json +20 -0
  53. package/phaser/copy-overwrite/tsconfig.json +7 -0
  54. package/phaser/copy-overwrite/vitest.config.ts +30 -0
  55. package/phaser/deletions.json +3 -0
  56. package/phaser/merge/.claude/settings.json +34 -0
  57. package/phaser/merge/.oxlintrc.json +16 -0
  58. package/phaser/package-lisa/package.lisa.json +73 -0
  59. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  60. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  61. package/plugins/lisa-agy/plugin.json +1 -1
  62. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  63. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  64. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  65. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  66. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  67. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  68. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  69. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  70. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  71. package/plugins/lisa-expo-agy/plugin.json +1 -1
  72. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  73. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  74. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +12 -1
  75. package/plugins/lisa-harper-fabric/.codex-plugin/hooks.json +11 -0
  76. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  77. package/plugins/lisa-harper-fabric/generated-artifact-globs.txt +4 -0
  78. package/plugins/lisa-harper-fabric/hooks/block-generated-artifact-edits.sh +72 -0
  79. package/plugins/lisa-harper-fabric-agy/generated-artifact-globs.txt +4 -0
  80. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  81. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +12 -1
  82. package/plugins/lisa-harper-fabric-copilot/generated-artifact-globs.txt +4 -0
  83. package/plugins/lisa-harper-fabric-copilot/hooks/block-generated-artifact-edits.sh +72 -0
  84. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  85. package/plugins/lisa-harper-fabric-cursor/generated-artifact-globs.txt +4 -0
  86. package/plugins/lisa-harper-fabric-cursor/hooks/block-generated-artifact-edits.sh +72 -0
  87. package/plugins/lisa-harper-fabric-cursor/hooks/hooks.json +11 -0
  88. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  89. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  90. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  91. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  92. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  93. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  94. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  95. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  96. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  97. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  98. package/plugins/lisa-phaser/.claude-plugin/plugin.json +35 -0
  99. package/plugins/lisa-phaser/.codex-plugin/hooks.json +26 -0
  100. package/plugins/lisa-phaser/.codex-plugin/plugin.json +30 -0
  101. package/plugins/lisa-phaser/hooks/inject-rules.sh +16 -0
  102. package/plugins/lisa-phaser/rules/phaser.md +59 -0
  103. package/plugins/lisa-phaser/skills/phaser-assets/SKILL.md +96 -0
  104. package/plugins/lisa-phaser/skills/phaser-assets/agents/openai.yaml +4 -0
  105. package/plugins/lisa-phaser/skills/phaser-gameobjects/SKILL.md +94 -0
  106. package/plugins/lisa-phaser/skills/phaser-gameobjects/agents/openai.yaml +4 -0
  107. package/plugins/lisa-phaser/skills/phaser-physics/SKILL.md +86 -0
  108. package/plugins/lisa-phaser/skills/phaser-physics/agents/openai.yaml +4 -0
  109. package/plugins/lisa-phaser/skills/phaser-project-structure/SKILL.md +89 -0
  110. package/plugins/lisa-phaser/skills/phaser-project-structure/agents/openai.yaml +4 -0
  111. package/plugins/lisa-phaser/skills/phaser-rendering/SKILL.md +89 -0
  112. package/plugins/lisa-phaser/skills/phaser-rendering/agents/openai.yaml +4 -0
  113. package/plugins/lisa-phaser/skills/phaser-scenes/SKILL.md +86 -0
  114. package/plugins/lisa-phaser/skills/phaser-scenes/agents/openai.yaml +4 -0
  115. package/plugins/lisa-phaser/skills/phaser-testing/SKILL.md +99 -0
  116. package/plugins/lisa-phaser/skills/phaser-testing/agents/openai.yaml +4 -0
  117. package/plugins/lisa-phaser/skills/phaser-v3-migration/SKILL.md +81 -0
  118. package/plugins/lisa-phaser/skills/phaser-v3-migration/agents/openai.yaml +4 -0
  119. package/plugins/lisa-phaser-agy/plugin.json +11 -0
  120. package/plugins/lisa-phaser-agy/skills/phaser-assets/SKILL.md +96 -0
  121. package/plugins/lisa-phaser-agy/skills/phaser-gameobjects/SKILL.md +94 -0
  122. package/plugins/lisa-phaser-agy/skills/phaser-physics/SKILL.md +86 -0
  123. package/plugins/lisa-phaser-agy/skills/phaser-project-structure/SKILL.md +89 -0
  124. package/plugins/lisa-phaser-agy/skills/phaser-rendering/SKILL.md +89 -0
  125. package/plugins/lisa-phaser-agy/skills/phaser-scenes/SKILL.md +86 -0
  126. package/plugins/lisa-phaser-agy/skills/phaser-testing/SKILL.md +99 -0
  127. package/plugins/lisa-phaser-agy/skills/phaser-v3-migration/SKILL.md +81 -0
  128. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +24 -0
  129. package/plugins/lisa-phaser-copilot/hooks/inject-rules.sh +16 -0
  130. package/plugins/lisa-phaser-copilot/rules/phaser.md +59 -0
  131. package/plugins/lisa-phaser-copilot/skills/phaser-assets/SKILL.md +96 -0
  132. package/plugins/lisa-phaser-copilot/skills/phaser-gameobjects/SKILL.md +94 -0
  133. package/plugins/lisa-phaser-copilot/skills/phaser-physics/SKILL.md +86 -0
  134. package/plugins/lisa-phaser-copilot/skills/phaser-project-structure/SKILL.md +89 -0
  135. package/plugins/lisa-phaser-copilot/skills/phaser-rendering/SKILL.md +89 -0
  136. package/plugins/lisa-phaser-copilot/skills/phaser-scenes/SKILL.md +86 -0
  137. package/plugins/lisa-phaser-copilot/skills/phaser-testing/SKILL.md +99 -0
  138. package/plugins/lisa-phaser-copilot/skills/phaser-v3-migration/SKILL.md +81 -0
  139. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +11 -0
  140. package/plugins/lisa-phaser-cursor/rules/phaser.mdc +64 -0
  141. package/plugins/lisa-phaser-cursor/skills/phaser-assets/SKILL.md +96 -0
  142. package/plugins/lisa-phaser-cursor/skills/phaser-gameobjects/SKILL.md +94 -0
  143. package/plugins/lisa-phaser-cursor/skills/phaser-physics/SKILL.md +86 -0
  144. package/plugins/lisa-phaser-cursor/skills/phaser-project-structure/SKILL.md +89 -0
  145. package/plugins/lisa-phaser-cursor/skills/phaser-rendering/SKILL.md +89 -0
  146. package/plugins/lisa-phaser-cursor/skills/phaser-scenes/SKILL.md +86 -0
  147. package/plugins/lisa-phaser-cursor/skills/phaser-testing/SKILL.md +99 -0
  148. package/plugins/lisa-phaser-cursor/skills/phaser-v3-migration/SKILL.md +81 -0
  149. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  150. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  151. package/plugins/lisa-rails-agy/plugin.json +1 -1
  152. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  153. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  154. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  155. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  156. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  157. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  158. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  159. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  160. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  161. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  162. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  163. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  164. package/plugins/src/harper-fabric/.claude-plugin/plugin.json +8 -0
  165. package/plugins/src/harper-fabric/generated-artifact-globs.txt +4 -0
  166. package/plugins/src/harper-fabric/hooks/block-generated-artifact-edits.sh +72 -0
  167. package/plugins/src/phaser/.claude-plugin/plugin.json +15 -0
  168. package/plugins/src/phaser/hooks/inject-rules.sh +16 -0
  169. package/plugins/src/phaser/rules/phaser.md +59 -0
  170. package/plugins/src/phaser/skills/phaser-assets/SKILL.md +96 -0
  171. package/plugins/src/phaser/skills/phaser-gameobjects/SKILL.md +94 -0
  172. package/plugins/src/phaser/skills/phaser-physics/SKILL.md +86 -0
  173. package/plugins/src/phaser/skills/phaser-project-structure/SKILL.md +89 -0
  174. package/plugins/src/phaser/skills/phaser-rendering/SKILL.md +89 -0
  175. package/plugins/src/phaser/skills/phaser-scenes/SKILL.md +86 -0
  176. package/plugins/src/phaser/skills/phaser-testing/SKILL.md +99 -0
  177. package/plugins/src/phaser/skills/phaser-v3-migration/SKILL.md +81 -0
  178. package/scripts/build-plugins.sh +1 -1
  179. package/tsconfig/harper-fabric.json +3 -1
  180. package/tsconfig/phaser.json +14 -0
@@ -0,0 +1,4 @@
1
+ harper-app/resources.js
2
+ harper-app/resource-*.js
3
+ harper-app/web/**
4
+ harper-app/lib/**
@@ -0,0 +1,72 @@
1
+ #!/bin/bash
2
+ # This file is managed by Lisa.
3
+ # Do not edit directly - changes will be overwritten on the next `lisa` run.
4
+
5
+ # PreToolUse hook: block Write/Edit/MultiEdit on generated Harper deploy
6
+ # artifacts. Harper/Fabric projects build these files from TypeScript under
7
+ # src/, so direct edits are overwritten by the next build and usually ship as
8
+ # no-op fixes.
9
+ # Reference: https://docs.claude.com/en/docs/claude-code/hooks
10
+ # Exit code 2 blocks the tool call and surfaces stderr to Claude.
11
+
12
+ JSON_INPUT=$(cat)
13
+
14
+ command -v jq >/dev/null 2>&1 || exit 0
15
+
16
+ FILE_PATH=$(printf '%s' "$JSON_INPUT" | jq -r '.tool_input.file_path // empty')
17
+ [ -n "$FILE_PATH" ] || exit 0
18
+
19
+ PLUGIN_ROOT=${CLAUDE_PLUGIN_ROOT:-}
20
+ if [ -z "$PLUGIN_ROOT" ]; then
21
+ PLUGIN_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
22
+ fi
23
+ GLOBS_FILE="$PLUGIN_ROOT/generated-artifact-globs.txt"
24
+ [ -f "$GLOBS_FILE" ] || exit 0
25
+
26
+ normalize_path() {
27
+ local path="$1"
28
+ path="${path#./}"
29
+ printf '%s' "$path"
30
+ }
31
+
32
+ matches_glob() {
33
+ local file="$1"
34
+ local glob="$2"
35
+
36
+ if [ "${glob: -3}" = "/**" ]; then
37
+ local dir="${glob%/**}"
38
+ case "$file" in
39
+ "$dir"/* | */"$dir"/*) return 0 ;;
40
+ esac
41
+ return 1
42
+ fi
43
+
44
+ case "$file" in
45
+ $glob | */$glob) return 0 ;;
46
+ esac
47
+
48
+ return 1
49
+ }
50
+
51
+ NORMALIZED_FILE=$(normalize_path "$FILE_PATH")
52
+
53
+ while IFS= read -r glob || [ -n "$glob" ]; do
54
+ [ -n "$glob" ] || continue
55
+ case "$glob" in \#*) continue ;; esac
56
+
57
+ if matches_glob "$NORMALIZED_FILE" "$glob"; then
58
+ cat >&2 <<MSG
59
+ Blocked: direct edit to generated Harper/Fabric artifact.
60
+
61
+ File: $FILE_PATH
62
+ Matched generated artifact pattern: $glob
63
+
64
+ TypeScript under src/ is the source of truth for Harper resources, web assets,
65
+ and shared libraries. Change the matching TypeScript source under src/ and run
66
+ the project build to regenerate harper-app outputs.
67
+ MSG
68
+ exit 2
69
+ fi
70
+ done <"$GLOBS_FILE"
71
+
72
+ exit 0
@@ -0,0 +1,4 @@
1
+ harper-app/resources.js
2
+ harper-app/resource-*.js
3
+ harper-app/web/**
4
+ harper-app/lib/**
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.160.0",
3
+ "version": "2.162.0",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.160.0",
3
+ "version": "2.162.0",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -9,6 +9,17 @@
9
9
  "lisa-typescript"
10
10
  ],
11
11
  "hooks": {
12
+ "preToolUse": [
13
+ {
14
+ "matcher": "Write|Edit|MultiEdit",
15
+ "hooks": [
16
+ {
17
+ "type": "command",
18
+ "command": "${CLAUDE_PLUGIN_ROOT}/hooks/block-generated-artifact-edits.sh"
19
+ }
20
+ ]
21
+ }
22
+ ],
12
23
  "sessionStart": [
13
24
  {
14
25
  "matcher": "",
@@ -0,0 +1,4 @@
1
+ harper-app/resources.js
2
+ harper-app/resource-*.js
3
+ harper-app/web/**
4
+ harper-app/lib/**
@@ -0,0 +1,72 @@
1
+ #!/bin/bash
2
+ # This file is managed by Lisa.
3
+ # Do not edit directly - changes will be overwritten on the next `lisa` run.
4
+
5
+ # PreToolUse hook: block Write/Edit/MultiEdit on generated Harper deploy
6
+ # artifacts. Harper/Fabric projects build these files from TypeScript under
7
+ # src/, so direct edits are overwritten by the next build and usually ship as
8
+ # no-op fixes.
9
+ # Reference: https://docs.claude.com/en/docs/claude-code/hooks
10
+ # Exit code 2 blocks the tool call and surfaces stderr to Claude.
11
+
12
+ JSON_INPUT=$(cat)
13
+
14
+ command -v jq >/dev/null 2>&1 || exit 0
15
+
16
+ FILE_PATH=$(printf '%s' "$JSON_INPUT" | jq -r '.tool_input.file_path // empty')
17
+ [ -n "$FILE_PATH" ] || exit 0
18
+
19
+ PLUGIN_ROOT=${CLAUDE_PLUGIN_ROOT:-}
20
+ if [ -z "$PLUGIN_ROOT" ]; then
21
+ PLUGIN_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
22
+ fi
23
+ GLOBS_FILE="$PLUGIN_ROOT/generated-artifact-globs.txt"
24
+ [ -f "$GLOBS_FILE" ] || exit 0
25
+
26
+ normalize_path() {
27
+ local path="$1"
28
+ path="${path#./}"
29
+ printf '%s' "$path"
30
+ }
31
+
32
+ matches_glob() {
33
+ local file="$1"
34
+ local glob="$2"
35
+
36
+ if [ "${glob: -3}" = "/**" ]; then
37
+ local dir="${glob%/**}"
38
+ case "$file" in
39
+ "$dir"/* | */"$dir"/*) return 0 ;;
40
+ esac
41
+ return 1
42
+ fi
43
+
44
+ case "$file" in
45
+ $glob | */$glob) return 0 ;;
46
+ esac
47
+
48
+ return 1
49
+ }
50
+
51
+ NORMALIZED_FILE=$(normalize_path "$FILE_PATH")
52
+
53
+ while IFS= read -r glob || [ -n "$glob" ]; do
54
+ [ -n "$glob" ] || continue
55
+ case "$glob" in \#*) continue ;; esac
56
+
57
+ if matches_glob "$NORMALIZED_FILE" "$glob"; then
58
+ cat >&2 <<MSG
59
+ Blocked: direct edit to generated Harper/Fabric artifact.
60
+
61
+ File: $FILE_PATH
62
+ Matched generated artifact pattern: $glob
63
+
64
+ TypeScript under src/ is the source of truth for Harper resources, web assets,
65
+ and shared libraries. Change the matching TypeScript source under src/ and run
66
+ the project build to regenerate harper-app outputs.
67
+ MSG
68
+ exit 2
69
+ fi
70
+ done <"$GLOBS_FILE"
71
+
72
+ exit 0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.160.0",
3
+ "version": "2.162.0",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -0,0 +1,4 @@
1
+ harper-app/resources.js
2
+ harper-app/resource-*.js
3
+ harper-app/web/**
4
+ harper-app/lib/**
@@ -0,0 +1,72 @@
1
+ #!/bin/bash
2
+ # This file is managed by Lisa.
3
+ # Do not edit directly - changes will be overwritten on the next `lisa` run.
4
+
5
+ # PreToolUse hook: block Write/Edit/MultiEdit on generated Harper deploy
6
+ # artifacts. Harper/Fabric projects build these files from TypeScript under
7
+ # src/, so direct edits are overwritten by the next build and usually ship as
8
+ # no-op fixes.
9
+ # Reference: https://docs.claude.com/en/docs/claude-code/hooks
10
+ # Exit code 2 blocks the tool call and surfaces stderr to Claude.
11
+
12
+ JSON_INPUT=$(cat)
13
+
14
+ command -v jq >/dev/null 2>&1 || exit 0
15
+
16
+ FILE_PATH=$(printf '%s' "$JSON_INPUT" | jq -r '.tool_input.file_path // empty')
17
+ [ -n "$FILE_PATH" ] || exit 0
18
+
19
+ PLUGIN_ROOT=${CLAUDE_PLUGIN_ROOT:-}
20
+ if [ -z "$PLUGIN_ROOT" ]; then
21
+ PLUGIN_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
22
+ fi
23
+ GLOBS_FILE="$PLUGIN_ROOT/generated-artifact-globs.txt"
24
+ [ -f "$GLOBS_FILE" ] || exit 0
25
+
26
+ normalize_path() {
27
+ local path="$1"
28
+ path="${path#./}"
29
+ printf '%s' "$path"
30
+ }
31
+
32
+ matches_glob() {
33
+ local file="$1"
34
+ local glob="$2"
35
+
36
+ if [ "${glob: -3}" = "/**" ]; then
37
+ local dir="${glob%/**}"
38
+ case "$file" in
39
+ "$dir"/* | */"$dir"/*) return 0 ;;
40
+ esac
41
+ return 1
42
+ fi
43
+
44
+ case "$file" in
45
+ $glob | */$glob) return 0 ;;
46
+ esac
47
+
48
+ return 1
49
+ }
50
+
51
+ NORMALIZED_FILE=$(normalize_path "$FILE_PATH")
52
+
53
+ while IFS= read -r glob || [ -n "$glob" ]; do
54
+ [ -n "$glob" ] || continue
55
+ case "$glob" in \#*) continue ;; esac
56
+
57
+ if matches_glob "$NORMALIZED_FILE" "$glob"; then
58
+ cat >&2 <<MSG
59
+ Blocked: direct edit to generated Harper/Fabric artifact.
60
+
61
+ File: $FILE_PATH
62
+ Matched generated artifact pattern: $glob
63
+
64
+ TypeScript under src/ is the source of truth for Harper resources, web assets,
65
+ and shared libraries. Change the matching TypeScript source under src/ and run
66
+ the project build to regenerate harper-app outputs.
67
+ MSG
68
+ exit 2
69
+ fi
70
+ done <"$GLOBS_FILE"
71
+
72
+ exit 0
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 1,
3
+ "hooks": {
4
+ "preToolUse": [
5
+ {
6
+ "command": "${CURSOR_PLUGIN_ROOT}/hooks/block-generated-artifact-edits.sh",
7
+ "matcher": "Write|Edit|MultiEdit"
8
+ }
9
+ ]
10
+ }
11
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.160.0",
3
+ "version": "2.162.0",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.160.0",
3
+ "version": "2.162.0",
4
4
  "description": "NestJS-specific skills and migration write-protection hooks.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.160.0",
3
+ "version": "2.162.0",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.160.0",
3
+ "version": "2.162.0",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.160.0",
3
+ "version": "2.162.0",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.160.0",
3
+ "version": "2.162.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.160.0",
3
+ "version": "2.162.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.160.0",
3
+ "version": "2.162.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.160.0",
3
+ "version": "2.162.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.160.0",
3
+ "version": "2.162.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "lisa-phaser",
3
+ "version": "2.162.0",
4
+ "description": "Phaser 4 game-development rules for TypeScript projects",
5
+ "author": {
6
+ "name": "Cody Swann"
7
+ },
8
+ "dependencies": [
9
+ "lisa-typescript"
10
+ ],
11
+ "hooks": {
12
+ "SessionStart": [
13
+ {
14
+ "matcher": "",
15
+ "hooks": [
16
+ {
17
+ "type": "command",
18
+ "command": "${CLAUDE_PLUGIN_ROOT}/hooks/inject-rules.sh"
19
+ }
20
+ ]
21
+ }
22
+ ],
23
+ "SubagentStart": [
24
+ {
25
+ "matcher": "",
26
+ "hooks": [
27
+ {
28
+ "type": "command",
29
+ "command": "${CLAUDE_PLUGIN_ROOT}/hooks/inject-rules.sh"
30
+ }
31
+ ]
32
+ }
33
+ ]
34
+ }
35
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "hooks": {
3
+ "SessionStart": [
4
+ {
5
+ "matcher": "",
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "${PLUGIN_ROOT}/hooks/inject-rules.sh"
10
+ }
11
+ ]
12
+ }
13
+ ],
14
+ "SubagentStart": [
15
+ {
16
+ "matcher": "",
17
+ "hooks": [
18
+ {
19
+ "type": "command",
20
+ "command": "${PLUGIN_ROOT}/hooks/inject-rules.sh"
21
+ }
22
+ ]
23
+ }
24
+ ]
25
+ }
26
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "lisa-phaser",
3
+ "version": "2.162.0",
4
+ "description": "Phaser 4 game-development rules for TypeScript projects",
5
+ "author": {
6
+ "name": "Cody Swann"
7
+ },
8
+ "keywords": [
9
+ "lisa"
10
+ ],
11
+ "dependencies": [
12
+ "lisa-typescript"
13
+ ],
14
+ "skills": "./skills/",
15
+ "hooks": "./.codex-plugin/hooks.json",
16
+ "interface": {
17
+ "displayName": "lisa-phaser",
18
+ "shortDescription": "Phaser 4 game-development rules for TypeScript projects",
19
+ "longDescription": "Phaser 4 game-development rules for TypeScript projects",
20
+ "developerName": "Cody Swann",
21
+ "category": "Coding",
22
+ "capabilities": [
23
+ "Interactive",
24
+ "Write"
25
+ ],
26
+ "defaultPrompt": [
27
+ "Use lisa-phaser"
28
+ ]
29
+ }
30
+ }
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env bash
2
+ # Reads all .md files from the plugin's rules/ directory and injects them
3
+ # into Claude context at session/subagent start.
4
+ set -euo pipefail
5
+
6
+ ROOT="${CLAUDE_PLUGIN_ROOT:-${CODEX_PLUGIN_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}}"
7
+ RULES_DIR="$ROOT/rules"
8
+
9
+ [ -d "$RULES_DIR" ] || exit 0
10
+
11
+ for rule in "$RULES_DIR"/*.md; do
12
+ [ -f "$rule" ] || continue
13
+ printf '\n<lisa-phaser-rule path="%s">\n' "$rule"
14
+ cat "$rule"
15
+ printf '\n</lisa-phaser-rule>\n'
16
+ done
@@ -0,0 +1,59 @@
1
+ # Phaser 4 Project Rules
2
+
3
+ This is a **Phaser 4** (v4.1+ "Salusa") TypeScript game project. Phaser 4 is the
4
+ only supported target — never introduce Phaser 3 idioms. The lint config enforces
5
+ the bans below; do not disable those rules, fix the code.
6
+
7
+ ## Phaser 4 Only — Banned v3 Idioms
8
+
9
+ - **No pipelines.** `setPipeline` / `setPostPipeline` / `resetPipeline` are gone.
10
+ Custom rendering is a **RenderNode** (registered via `render.renderNodes` in the
11
+ game config); post-processing is a **Filter** (`gameObject.filters` /
12
+ `camera.filters`). See the `phaser-rendering` skill.
13
+ - **No preFX/postFX.** The v3 FX controllers were replaced by the unified Filter
14
+ system. `BitmapMask` → `Mask` filter.
15
+ - **No `setTintFill`/`tintFill`.** Use `setTint()` + `setTintMode(Phaser.TintModes.FILL)`.
16
+ - **No `Phaser.Geom.Point`** (removed — use `Phaser.Math.Vector2`) and **no
17
+ `Phaser.Struct.Set/Map`** (removed — use native `Set`/`Map`).
18
+ - **No raw WebGL calls.** External GL work goes through the `Extern` game object.
19
+ - **No `setPipeline('Light2D')`.** Lighting is `gameObject.setLighting(true)`.
20
+
21
+ ## Architecture
22
+
23
+ - **One scene class per file** under `src/scenes/`, named after the scene key.
24
+ The scene flow is `Boot → Preloader → MainMenu → Game` (plus overlays). Boot
25
+ loads only what the Preloader needs; the Preloader loads everything else.
26
+ - **Pure game logic lives outside scenes** in `src/logic/` (or `src/core/`) with
27
+ **no `phaser` imports** — plain TypeScript functions and classes that take and
28
+ return data. Scenes are thin orchestrators that wire logic to GameObjects.
29
+ This is what makes the game unit-testable; see the `phaser-testing` skill.
30
+ - **Asset keys are typed constants** in `src/assets.ts` — never inline magic
31
+ strings for texture/audio/animation keys. Load via asset-pack manifests
32
+ (`this.load.pack`), not ad-hoc `load.image` lists scattered across scenes.
33
+
34
+ ## Determinism
35
+
36
+ - **No `Math.random()` in game code.** Use the scene-seeded
37
+ `Phaser.Math.RandomDataGenerator` (`Phaser.Math.RND` or a local instance with
38
+ an explicit seed) so replays and tests are reproducible.
39
+ - Arcade physics keeps its v4 default `fixedStep: true`. Do not switch physics to
40
+ variable step to "fix" a tunneling bug — fix the body/velocity configuration.
41
+
42
+ ## Performance
43
+
44
+ - **No allocations in `update()`.** No `new`, array literals, closures, or
45
+ `.filter/.map` chains in per-frame paths — hoist scratch objects, reuse vectors.
46
+ - **Pool, don't churn.** Bullets, enemies, particles, and pickups come from
47
+ `Group` pools (`get`/`killAndHide`), never `new`/`destroy` per spawn.
48
+ - **Mass rendering uses the GPU layers.** Large static/animated sprite fields →
49
+ `SpriteGPULayer`; large tile maps → `TilemapGPULayer`. Texture atlases (PCT
50
+ where possible) over loose images — see the `phaser-assets` skill.
51
+ - Target WebGL; the Canvas renderer is deprecated in v4 and only acceptable as an
52
+ explicit, documented fallback decision.
53
+
54
+ ## Verification
55
+
56
+ Before reporting any change complete: run `bun run typecheck`, `bun run test`,
57
+ and `bun run build`. For changes that affect rendering or input, verify in the
58
+ real browser — `bun run dev` plus a Playwright check (the game boots, the canvas
59
+ renders, no console errors). A green typecheck alone is not proof a game works.
@@ -0,0 +1,96 @@
1
+ ---
2
+ name: phaser-assets
3
+ description: This skill should be used when loading or organizing assets in a Phaser 4 game — the Loader (images, texture atlases, spritesheets, audio, fonts), asset-pack manifests via this.load.pack, the new PCT compact atlas format (load.atlasPCT), typed asset keys, and where files live in the Vite project. Use it when adding any asset, restructuring loading, fixing a missing-texture/green-square bug, or optimizing load size. Pairs with phaser-project-structure, phaser-scenes, and phaser-gameobjects.
4
+ ---
5
+
6
+ # Phaser 4 Assets and Loading
7
+
8
+ ## Overview
9
+
10
+ All runtime assets live under `public/assets/` (served verbatim by Vite — never
11
+ `import` game assets through the bundler) and are loaded by Phaser's Loader in a
12
+ scene's `preload()`. The opinionated pattern: **one asset-pack manifest, loaded
13
+ by the Preloader, with every key defined as a typed constant.**
14
+
15
+ ## Asset packs (the default loading strategy)
16
+
17
+ A pack is a JSON manifest the Loader consumes wholesale:
18
+
19
+ ```json
20
+ {
21
+ "main": {
22
+ "files": [
23
+ { "type": "atlasPCT", "key": "game-atlas", "url": "atlases/game.pct" },
24
+ { "type": "image", "key": "background", "url": "images/background.png" },
25
+ { "type": "audio", "key": "sfx-jump", "url": ["audio/jump.ogg", "audio/jump.m4a"] },
26
+ { "type": "spritesheet", "key": "explosion", "url": "sheets/explosion.png",
27
+ "frameConfig": { "frameWidth": 64, "frameHeight": 64 } }
28
+ ]
29
+ }
30
+ }
31
+ ```
32
+
33
+ ```ts
34
+ // Preloader.preload()
35
+ this.load.pack("game-pack", "assets/pack.json");
36
+ ```
37
+
38
+ Why packs: loading is declared in one reviewable file instead of scattered
39
+ `load.*` calls; adding an asset never touches scene code beyond using the key.
40
+
41
+ ## Texture atlases — the rule, not the suggestion
42
+
43
+ Individual images break sprite batching. Everything that renders together ships
44
+ in an atlas:
45
+
46
+ - **PCT (Phaser Compact Texture)** is the preferred v4 atlas format —
47
+ `this.load.atlasPCT(key, url)` — its manifests are 90–95% smaller than the
48
+ JSON-hash equivalent. JSON/XML/Unity/multi-atlas loaders still exist for
49
+ third-party toolchains.
50
+ - Spritesheets (`load.spritesheet`) are acceptable only for uniform-grid
51
+ animation strips; anything else is an atlas.
52
+
53
+ ## Audio
54
+
55
+ - Provide at least two encodings (`.ogg` + `.m4a`) in the url array; Phaser
56
+ picks the first the browser can play.
57
+ - Web Audio is the default manager; it unlocks on first user gesture — never
58
+ autoplay sound before input (it will silently fail and "work on my machine").
59
+ - Use audio sprites (`load.audioSprite`) for large sets of short SFX.
60
+
61
+ ## Typed keys
62
+
63
+ Every key lives in `src/assets.ts`:
64
+
65
+ ```ts
66
+ export const Tex = { GameAtlas: "game-atlas", Background: "background" } as const;
67
+ export const Sfx = { Jump: "sfx-jump" } as const;
68
+ export const SceneKeys = { Boot: "Boot", Preloader: "Preloader", Game: "Game" } as const;
69
+ ```
70
+
71
+ Scenes use `Tex.GameAtlas`, never `"game-atlas"` inline. A bad inline key fails
72
+ at runtime as a green square or silent missing audio; a bad constant fails in
73
+ review and in tests that assert the pack manifest covers every constant.
74
+
75
+ ## Loading UX and failure handling
76
+
77
+ - The Preloader binds `this.load.on("progress", …)` to a progress bar built from
78
+ Boot-loaded art ([[phaser-project-structure]]).
79
+ - Handle `loaderror`: `this.load.on(Phaser.Loader.Events.FILE_LOAD_ERROR, …)` —
80
+ log the key and URL; a missing asset must fail loudly in dev, not render as a
81
+ placeholder in production.
82
+
83
+ ## Project conventions
84
+
85
+ - `public/assets/` subdirs: `atlases/`, `images/`, `audio/`, `sheets/`, `fonts/`,
86
+ plus `pack.json` at the root of `assets/`.
87
+ - Generated atlas files (PCT/JSON + PNG pages) are build inputs, committed to the
88
+ repo; their source art lives wherever the art pipeline keeps it.
89
+ - A test should assert that every key constant in `src/assets.ts` appears in
90
+ `pack.json` (cheap manifest-coverage check; see [[phaser-testing]]).
91
+
92
+ ## Verification
93
+
94
+ Asset changes are verified by booting the game and watching the network panel /
95
+ console: every file 200s, no `FILE_LOAD_ERROR`, and the new asset visibly renders
96
+ or audibly plays in the scene that uses it.
@@ -0,0 +1,4 @@
1
+ display_name: "Phaser Assets"
2
+ short_description: "loading or organizing assets in a Phaser 4 game — the Loader (images, texture atlases, spritesheets, audio, fonts), asset-pack manifests…"
3
+ default_prompt:
4
+ - "Use $phaser-assets: loading or organizing assets in a Phaser 4 game — the Loader (images, texture atlases, spritesheets, audio, fonts), asset-pack manifests…."