@causyne/agent 0.0.0-stage → 1.10.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 (274) hide show
  1. package/LICENSE +102 -0
  2. package/README.md +31 -2
  3. package/SECURITY.md +24 -0
  4. package/bin/causyne.js +13 -0
  5. package/docs/ARCHITECTURE.md +63 -0
  6. package/docs/PROVENANCE.md +29 -0
  7. package/docs/SECURITY_REVIEW.md +89 -0
  8. package/docs/THIRD_PARTY_NOTICES.md +49 -0
  9. package/native-skills/ai-engineering/context-window-management/SKILL.md +43 -0
  10. package/native-skills/ai-engineering/llm-evaluation/SKILL.md +46 -0
  11. package/native-skills/ai-engineering/model-cost-and-latency/SKILL.md +46 -0
  12. package/native-skills/ai-engineering/prompt-construction/SKILL.md +42 -0
  13. package/native-skills/ai-engineering/retrieval-augmented-generation/SKILL.md +42 -0
  14. package/native-skills/ai-engineering/structured-output-and-schemas/SKILL.md +45 -0
  15. package/native-skills/ai-engineering/tool-calling-agents/SKILL.md +43 -0
  16. package/native-skills/android/app-performance-profiling/SKILL.md +42 -0
  17. package/native-skills/android/background-work-scheduling/SKILL.md +47 -0
  18. package/native-skills/android/compose-state-and-recomposition/SKILL.md +43 -0
  19. package/native-skills/android/gradle-build-configuration/SKILL.md +41 -0
  20. package/native-skills/android/lifecycle-and-leaks/SKILL.md +46 -0
  21. package/native-skills/android/play-store-release/SKILL.md +43 -0
  22. package/native-skills/android/room-and-persistence/SKILL.md +40 -0
  23. package/native-skills/backend/authentication-and-sessions/SKILL.md +45 -0
  24. package/native-skills/backend/background-jobs-and-queues/SKILL.md +42 -0
  25. package/native-skills/backend/caching-strategy/SKILL.md +44 -0
  26. package/native-skills/backend/graceful-shutdown/SKILL.md +42 -0
  27. package/native-skills/backend/rate-limiting-and-quotas/SKILL.md +40 -0
  28. package/native-skills/backend/rest-api-design/SKILL.md +40 -0
  29. package/native-skills/backend/webhook-delivery-and-receipt/SKILL.md +43 -0
  30. package/native-skills/cloud/cost-optimisation/SKILL.md +46 -0
  31. package/native-skills/cloud/iam-least-privilege/SKILL.md +43 -0
  32. package/native-skills/cloud/infrastructure-as-code/SKILL.md +43 -0
  33. package/native-skills/cloud/multi-region-and-failover/SKILL.md +43 -0
  34. package/native-skills/cloud/serverless-patterns/SKILL.md +47 -0
  35. package/native-skills/data/data-quality-monitoring/SKILL.md +51 -0
  36. package/native-skills/data/etl-pipeline-reliability/SKILL.md +43 -0
  37. package/native-skills/data/exploratory-analysis/SKILL.md +43 -0
  38. package/native-skills/data/metric-definition/SKILL.md +42 -0
  39. package/native-skills/data/notebook-to-production/SKILL.md +43 -0
  40. package/native-skills/database/backup-and-recovery/SKILL.md +43 -0
  41. package/native-skills/database/connection-pooling/SKILL.md +42 -0
  42. package/native-skills/database/data-integrity-and-constraints/SKILL.md +42 -0
  43. package/native-skills/database/query-optimisation/SKILL.md +38 -0
  44. package/native-skills/database/safe-migrations/SKILL.md +47 -0
  45. package/native-skills/database/schema-design/SKILL.md +38 -0
  46. package/native-skills/database/transactions-and-isolation/SKILL.md +41 -0
  47. package/native-skills/design/colour-system-construction/SKILL.md +38 -0
  48. package/native-skills/design/design-direction-brief/SKILL.md +41 -0
  49. package/native-skills/design/motion-and-transitions/SKILL.md +38 -0
  50. package/native-skills/design/responsive-strategy/SKILL.md +39 -0
  51. package/native-skills/design/spacing-and-rhythm/SKILL.md +38 -0
  52. package/native-skills/design/type-scale-and-hierarchy/SKILL.md +39 -0
  53. package/native-skills/design/visual-qa-loop/SKILL.md +42 -0
  54. package/native-skills/devops/docker-multi-stage-builds/SKILL.md +60 -0
  55. package/native-skills/devops/github-actions-ci/SKILL.md +60 -0
  56. package/native-skills/devops/incident-triage/SKILL.md +38 -0
  57. package/native-skills/devops/kubernetes-deployment-hardening/SKILL.md +64 -0
  58. package/native-skills/devops/observability-baseline/SKILL.md +38 -0
  59. package/native-skills/devops/secret-management/SKILL.md +40 -0
  60. package/native-skills/devops/terraform-state-and-modules/SKILL.md +36 -0
  61. package/native-skills/devops/zero-downtime-deploys/SKILL.md +40 -0
  62. package/native-skills/git/bisect-regression-hunt/SKILL.md +43 -0
  63. package/native-skills/git/branch-strategy/SKILL.md +39 -0
  64. package/native-skills/git/commit-hygiene/SKILL.md +41 -0
  65. package/native-skills/git/history-recovery/SKILL.md +44 -0
  66. package/native-skills/git/large-repository-surgery/SKILL.md +46 -0
  67. package/native-skills/git/merge-conflict-resolution/SKILL.md +42 -0
  68. package/native-skills/media/cinematic-3d-shot/SKILL.md +104 -0
  69. package/native-skills/mobile/app-startup-optimisation/SKILL.md +41 -0
  70. package/native-skills/mobile/cross-platform-tradeoffs/SKILL.md +42 -0
  71. package/native-skills/mobile/deep-linking/SKILL.md +39 -0
  72. package/native-skills/mobile/mobile-storage-security/SKILL.md +45 -0
  73. package/native-skills/mobile/offline-first-sync/SKILL.md +42 -0
  74. package/native-skills/mobile/push-notifications/SKILL.md +38 -0
  75. package/native-skills/performance/algorithmic-complexity/SKILL.md +43 -0
  76. package/native-skills/performance/concurrency-and-parallelism/SKILL.md +42 -0
  77. package/native-skills/performance/load-testing/SKILL.md +42 -0
  78. package/native-skills/performance/memory-and-leak-hunting/SKILL.md +41 -0
  79. package/native-skills/performance/network-and-payload-efficiency/SKILL.md +42 -0
  80. package/native-skills/performance/profiling-methodology/SKILL.md +46 -0
  81. package/native-skills/python/async-correctness/SKILL.md +40 -0
  82. package/native-skills/python/cli-tool-construction/SKILL.md +44 -0
  83. package/native-skills/python/data-processing-pipelines/SKILL.md +38 -0
  84. package/native-skills/python/environment-isolation/SKILL.md +41 -0
  85. package/native-skills/python/packaging-and-distribution/SKILL.md +56 -0
  86. package/native-skills/python/pytest-suite-design/SKILL.md +39 -0
  87. package/native-skills/python/type-hints-and-static-checking/SKILL.md +42 -0
  88. package/native-skills/security/authorization-model/SKILL.md +42 -0
  89. package/native-skills/security/crypto-usage/SKILL.md +48 -0
  90. package/native-skills/security/dependency-supply-chain/SKILL.md +42 -0
  91. package/native-skills/security/input-validation-and-injection/SKILL.md +44 -0
  92. package/native-skills/security/secure-file-uploads/SKILL.md +46 -0
  93. package/native-skills/security/security-headers-and-csp/SKILL.md +44 -0
  94. package/native-skills/security/threat-modelling/SKILL.md +46 -0
  95. package/native-skills/testing/end-to-end-test-stability/SKILL.md +42 -0
  96. package/native-skills/testing/property-based-testing/SKILL.md +46 -0
  97. package/native-skills/testing/regression-test-from-a-bug/SKILL.md +41 -0
  98. package/native-skills/testing/snapshot-and-visual-regression/SKILL.md +42 -0
  99. package/native-skills/testing/test-doubles-and-mocking/SKILL.md +43 -0
  100. package/native-skills/testing/test-strategy-and-pyramid/SKILL.md +39 -0
  101. package/native-skills/testing/writing-good-assertions/SKILL.md +42 -0
  102. package/native-skills/web/accessible-components/SKILL.md +45 -0
  103. package/native-skills/web/api-client-resilience/SKILL.md +39 -0
  104. package/native-skills/web/bundle-size-reduction/SKILL.md +38 -0
  105. package/native-skills/web/core-web-vitals/SKILL.md +40 -0
  106. package/native-skills/web/css-layout-systems/SKILL.md +41 -0
  107. package/native-skills/web/form-validation-ux/SKILL.md +39 -0
  108. package/native-skills/web/react-state-architecture/SKILL.md +41 -0
  109. package/native-skills/web/ssr-hydration-correctness/SKILL.md +45 -0
  110. package/package.json +68 -4
  111. package/src/agentLoop.js +2458 -0
  112. package/src/appChannel.js +109 -0
  113. package/src/approvalGrants.js +66 -0
  114. package/src/auditLog.js +52 -0
  115. package/src/autoUpdate.js +12 -0
  116. package/src/capabilities.js +36 -0
  117. package/src/checkpoints.js +1199 -0
  118. package/src/cliMode.js +638 -0
  119. package/src/commands.js +805 -0
  120. package/src/compiledSkills.js +540 -0
  121. package/src/config.js +130 -0
  122. package/src/contextManager.js +498 -0
  123. package/src/cortex/autoCondenser.js +192 -0
  124. package/src/cortex/provisioner.js +27 -0
  125. package/src/cortex/vectorDb.js +447 -0
  126. package/src/designPalettes.js +99 -0
  127. package/src/devMode.js +6 -0
  128. package/src/embodimentSession.js +180 -0
  129. package/src/entrypoint.js +194 -0
  130. package/src/execSafe.js +21 -0
  131. package/src/gitSnapshot.js +378 -0
  132. package/src/mcp/jsonRpc.js +165 -0
  133. package/src/mcp/mcpClient.js +136 -0
  134. package/src/mcp/mcpRegistry.js +207 -0
  135. package/src/memory.js +62 -0
  136. package/src/memoryManager.js +124 -0
  137. package/src/modelCatalogue.js +132 -0
  138. package/src/modelIds.js +42 -0
  139. package/src/modelRouter.js +145 -0
  140. package/src/outputStore.js +246 -0
  141. package/src/perception.js +124 -0
  142. package/src/planCache.js +437 -0
  143. package/src/procSignal.js +32 -0
  144. package/src/providers/anthropic.js +408 -0
  145. package/src/providers/base.js +328 -0
  146. package/src/providers/dashscope-byok.js +86 -0
  147. package/src/providers/deepseek.js +80 -0
  148. package/src/providers/factory.js +37 -0
  149. package/src/providers/gemini.js +346 -0
  150. package/src/providers/moonshot.js +73 -0
  151. package/src/providers/muse.js +169 -0
  152. package/src/providers/ollama.js +104 -0
  153. package/src/providers/openai-compatible.js +84 -0
  154. package/src/providers/openai.js +20 -0
  155. package/src/providers/qwen-byok.js +76 -0
  156. package/src/providers/xai.js +73 -0
  157. package/src/provisioning/capabilityConsent.js +24 -0
  158. package/src/provisioning/capabilityProvisioner.js +271 -0
  159. package/src/provisioning/capabilityTools.js +29 -0
  160. package/src/reporting.js +373 -0
  161. package/src/sandbox.js +529 -0
  162. package/src/sessionStore.js +279 -0
  163. package/src/skillsManager.js +288 -0
  164. package/src/slopDetector.js +307 -0
  165. package/src/taskBuffer.js +45 -0
  166. package/src/taskShape.js +241 -0
  167. package/src/textDiff.js +150 -0
  168. package/src/tokenTracker.js +560 -0
  169. package/src/tool-scripts/ax_snapshot.applescript +39 -0
  170. package/src/tool-scripts/ax_snapshot.ps1 +10 -0
  171. package/src/tool-scripts/desktop_act.applescript +58 -0
  172. package/src/tool-scripts/resolve_automator.py +119 -0
  173. package/src/toolPacks.js +524 -0
  174. package/src/tools/archive.js +63 -0
  175. package/src/tools/astryxOracle.js +78 -0
  176. package/src/tools/axSnapshot.js +165 -0
  177. package/src/tools/blenderAutomator.js +349 -0
  178. package/src/tools/browserAutomator.js +252 -0
  179. package/src/tools/checkSystemSpecs.js +64 -0
  180. package/src/tools/clipboard.js +36 -0
  181. package/src/tools/codeSearchAst.js +101 -0
  182. package/src/tools/codeSearcher.js +230 -0
  183. package/src/tools/codeTools.js +262 -0
  184. package/src/tools/codebaseSearch.js +75 -0
  185. package/src/tools/createSkill.js +129 -0
  186. package/src/tools/deferredMcpSearch.js +246 -0
  187. package/src/tools/desktopAct.js +208 -0
  188. package/src/tools/desktopOpen.js +34 -0
  189. package/src/tools/dynamicLoader.js +44 -0
  190. package/src/tools/executeProceduralMedia.js +93 -0
  191. package/src/tools/fsDelete.js +51 -0
  192. package/src/tools/fsEdit.js +105 -0
  193. package/src/tools/fsFind.js +128 -0
  194. package/src/tools/fsList.js +77 -0
  195. package/src/tools/fsMove.js +57 -0
  196. package/src/tools/fsRead.js +87 -0
  197. package/src/tools/fsSearch.js +198 -0
  198. package/src/tools/fsWrite.js +41 -0
  199. package/src/tools/gameAiBehaviorTree.js +208 -0
  200. package/src/tools/gameAnimationRig.js +194 -0
  201. package/src/tools/gameAssetFetcher.js +372 -0
  202. package/src/tools/gameAssetHarvester.js +210 -0
  203. package/src/tools/gameAudioSynth.js +267 -0
  204. package/src/tools/gameBuilder.js +886 -0
  205. package/src/tools/gameCanvasAudit.js +101 -0
  206. package/src/tools/gameCinematicSequencer.js +151 -0
  207. package/src/tools/gameDataForge.js +124 -0
  208. package/src/tools/gameDialogueTreeGen.js +166 -0
  209. package/src/tools/gameEconomyBalancer.js +161 -0
  210. package/src/tools/gameEntitySpawner.js +207 -0
  211. package/src/tools/gameLoreForge.js +153 -0
  212. package/src/tools/gameQuestArcBuilder.js +152 -0
  213. package/src/tools/gameSceneBuilder.js +158 -0
  214. package/src/tools/gameShaderForge.js +181 -0
  215. package/src/tools/gameTilemapGenerator.js +164 -0
  216. package/src/tools/gameUiHudBuilder.js +292 -0
  217. package/src/tools/gameVfxEmitterGen.js +108 -0
  218. package/src/tools/gameWebRuntimeInspector.js +91 -0
  219. package/src/tools/generateMediaViaApi.js +358 -0
  220. package/src/tools/gitExec.js +54 -0
  221. package/src/tools/godotAutomator.js +437 -0
  222. package/src/tools/manageLocalAiDependencies.js +220 -0
  223. package/src/tools/memoryWrite.js +99 -0
  224. package/src/tools/multiEdit.js +107 -0
  225. package/src/tools/palmierAutomator.js +104 -0
  226. package/src/tools/pdfReader.js +112 -0
  227. package/src/tools/persistentShell.js +148 -0
  228. package/src/tools/printer.js +316 -0
  229. package/src/tools/procTerm.js +91 -0
  230. package/src/tools/processList.js +52 -0
  231. package/src/tools/readNativeSkill.js +39 -0
  232. package/src/tools/registry.js +277 -0
  233. package/src/tools/resolveAutomator.js +102 -0
  234. package/src/tools/screenshot.js +75 -0
  235. package/src/tools/subagentOrchestrator.js +305 -0
  236. package/src/tools/sysRun.js +125 -0
  237. package/src/tools/todoWrite.js +75 -0
  238. package/src/tools/toolDispatch.js +127 -0
  239. package/src/tools/toolForge.js +124 -0
  240. package/src/tools/updatePlan.js +88 -0
  241. package/src/tools/viewImage.js +82 -0
  242. package/src/tools/visionInspector.js +154 -0
  243. package/src/tools/webFetch.js +74 -0
  244. package/src/tools/webSearch.js +82 -0
  245. package/src/tui/ask.js +164 -0
  246. package/src/tui/banner.js +158 -0
  247. package/src/tui/block.js +152 -0
  248. package/src/tui/chatRenderer.js +953 -0
  249. package/src/tui/completion.js +424 -0
  250. package/src/tui/dialogs.js +606 -0
  251. package/src/tui/diff.js +296 -0
  252. package/src/tui/history.js +135 -0
  253. package/src/tui/home.js +217 -0
  254. package/src/tui/invocation.js +105 -0
  255. package/src/tui/keys.js +443 -0
  256. package/src/tui/lineEditor.js +256 -0
  257. package/src/tui/overlay.js +256 -0
  258. package/src/tui/prompt.js +1258 -0
  259. package/src/tui/selectList.js +335 -0
  260. package/src/tui/stage.js +330 -0
  261. package/src/tui/stageSurface.js +609 -0
  262. package/src/tui/statusLine.js +254 -0
  263. package/src/tui/text.js +345 -0
  264. package/src/tui/theme.js +393 -0
  265. package/src/tui/toolDisplay.js +176 -0
  266. package/src/tui/transcript.js +235 -0
  267. package/src/tui/viewport.js +337 -0
  268. package/src/uncertainty.js +271 -0
  269. package/src/userSkills.js +265 -0
  270. package/src/utils/cli_ui.js +0 -0
  271. package/src/utils/inquirer.js +12 -0
  272. package/src/utils/paths.js +37 -0
  273. package/src/version.js +38 -0
  274. package/src/vfeTracker.js +220 -0
@@ -0,0 +1,208 @@
1
+ import fs from 'fs/promises';
2
+ import fsSync from 'fs';
3
+ import path from 'path';
4
+
5
+ export const gameAiBehaviorTree = {
6
+ schema: {
7
+ name: 'game.ai_behavior_tree',
8
+ description: 'Engineers NPC/Enemy AI state machines and behavior trees for Godot 4.x (`PatrolState`, `ChaseState`, `AttackState`, `BossPhaseController`) with line-of-sight raycasting and `NavigationAgent2D/3D` pathfinding generation.',
9
+ parameters: {
10
+ type: 'object',
11
+ properties: {
12
+ action: {
13
+ type: 'string',
14
+ enum: ['generate_enemy_ai_script', 'generate_boss_phase_controller', 'generate_navigation_setup'],
15
+ description: 'Action: generate_enemy_ai_script (standard patrol/chase/attack AI), generate_boss_phase_controller (multi-phase boss state machine), or generate_navigation_setup (NavigationAgent pathfinding snippet).'
16
+ },
17
+ entityName: {
18
+ type: 'string',
19
+ description: 'Name of the AI entity (`SkeletonWarrior`, `ShadowMage`, `BossNecromancer`).'
20
+ },
21
+ aiType: {
22
+ type: 'string',
23
+ enum: ['2d', '3d'],
24
+ description: 'Dimension of the AI entity (`2d` or `3d`).'
25
+ },
26
+ patrolSpeed: { type: 'number', description: 'Patrol movement speed (default 60.0).' },
27
+ chaseSpeed: { type: 'number', description: 'Chase movement speed (default 130.0).' },
28
+ attackRange: { type: 'number', description: 'Distance to trigger melee/ranged attack (default 45.0).' },
29
+ detectRange: { type: 'number', description: 'Distance to detect player and enter Chase (default 220.0).' },
30
+ outputPath: { type: 'string', description: 'Absolute path to save generated `.gd` script (`res://scripts/ai/BaseEnemyAI.gd`).' }
31
+ },
32
+ required: ['action', 'entityName']
33
+ }
34
+ },
35
+
36
+ async execute(args) {
37
+ try {
38
+ const { action, entityName, aiType = '2d', patrolSpeed = 60.0, chaseSpeed = 130.0, attackRange = 45.0, detectRange = 220.0, outputPath } = args;
39
+
40
+ if (action === 'generate_enemy_ai_script') {
41
+ const bodyClass = aiType === '3d' ? 'CharacterBody3D' : 'CharacterBody2D';
42
+ const vecType = aiType === '3d' ? 'Vector3' : 'Vector2';
43
+
44
+ const gdScript = `extends ${bodyClass}
45
+
46
+ # Generated by Sovereign Game Automation Studio (v1.3.12) - AI Behavior Tree
47
+ enum AIState { PATROL, CHASE, ATTACK, STUNNED, DEAD }
48
+
49
+ @export var max_hp: float = 100.0
50
+ @export var patrol_speed: float = ${patrolSpeed.toFixed(1)}
51
+ @export var chase_speed: float = ${chaseSpeed.toFixed(1)}
52
+ @export var detect_radius: float = ${detectRange.toFixed(1)}
53
+ @export var attack_radius: float = ${attackRange.toFixed(1)}
54
+
55
+ var current_hp: float
56
+ var current_state: AIState = AIState.PATROL
57
+ var target_player: Node = null
58
+ var patrol_direction: ${vecType} = ${aiType === '3d' ? 'Vector3(1, 0, 0)' : 'Vector2.RIGHT'}
59
+ var patrol_timer: float = 0.0
60
+
61
+ @onready var nav_agent = $NavigationAgent${aiType === '3d' ? '3D' : '2D'} if has_node("NavigationAgent${aiType === '3d' ? '3D' : '2D'}") else null
62
+ @onready var anim_player = $AnimationPlayer if has_node("AnimationPlayer") else null
63
+
64
+ func _ready() -> void:
65
+ \tcurrent_hp = max_hp
66
+ \ttarget_player = get_tree().get_first_node_in_group("player")
67
+ \tprint("[AI Ready] ${entityName} initialized in PATROL state.")
68
+
69
+ func _physics_process(delta: float) -> void:
70
+ \tif current_state == AIState.DEAD or current_state == AIState.STUNNED:
71
+ \t\treturn
72
+
73
+ \t# Check target distance
74
+ \tif is_instance_valid(target_player):
75
+ \t\tvar dist = global_position.distance_to(target_player.global_position)
76
+ \t\tif dist <= attack_radius:
77
+ \t\t\tchange_state(AIState.ATTACK)
78
+ \t\telif dist <= detect_radius:
79
+ \t\t\tchange_state(AIState.CHASE)
80
+ \t\telif current_state == AIState.CHASE and dist > detect_radius * 1.3:
81
+ \t\t\tchange_state(AIState.PATROL)
82
+
83
+ \tmatch current_state:
84
+ \t\tAIState.PATROL:
85
+ \t\t\t_process_patrol(delta)
86
+ \t\tAIState.CHASE:
87
+ \t\t\t_process_chase(delta)
88
+ \t\tAIState.ATTACK:
89
+ \t\t\t_process_attack(delta)
90
+
91
+ func _process_patrol(delta: float) -> void:
92
+ \tpatrol_timer += delta
93
+ \tif patrol_timer >= 3.0:
94
+ \t\tpatrol_timer = 0.0
95
+ \t\tpatrol_direction = -patrol_direction
96
+ \tvelocity = patrol_direction * patrol_speed
97
+ \tmove_and_slide()
98
+ \tif anim_player and anim_player.has_animation("walk"):
99
+ \t\tanim_player.play("walk")
100
+
101
+ func _process_chase(delta: float) -> void:
102
+ \tif not is_instance_valid(target_player):
103
+ \t\treturn
104
+ \tvar dir = (target_player.global_position - global_position).normalized()
105
+ \tif nav_agent and not nav_agent.is_navigation_finished():
106
+ \t\tnav_agent.target_position = target_player.global_position
107
+ \t\tdir = (nav_agent.get_next_path_position() - global_position).normalized()
108
+ \tvelocity = dir * chase_speed
109
+ \tmove_and_slide()
110
+ \tif anim_player and anim_player.has_animation("walk"):
111
+ \t\tanim_player.play("walk")
112
+
113
+ func _process_attack(delta: float) -> void:
114
+ \tvelocity = ${vecType}.ZERO
115
+ \tif anim_player and anim_player.has_animation("attack_slash") and not anim_player.is_playing():
116
+ \t\tanim_player.play("attack_slash")
117
+
118
+ func take_damage(amount: float) -> void:
119
+ \tif current_state == AIState.DEAD:
120
+ \t\treturn
121
+ \tcurrent_hp -= amount
122
+ \tprint("[AI Damage] ${entityName} took ", amount, " damage. HP remaining: ", current_hp)
123
+ \tif current_hp <= 0:
124
+ \t\tchange_state(AIState.DEAD)
125
+ \telse:
126
+ \t\tif anim_player and anim_player.has_animation("hit"):
127
+ \t\t\tanim_player.play("hit")
128
+
129
+ func change_state(new_state: AIState) -> void:
130
+ \tif current_state == new_state:
131
+ \t\treturn
132
+ \tcurrent_state = new_state
133
+ \tif current_state == AIState.DEAD:
134
+ \t\tvelocity = ${vecType}.ZERO
135
+ \t\tif anim_player and anim_player.has_animation("death"):
136
+ \t\t\tanim_player.play("death")
137
+ \t\tawait get_tree().create_timer(2.0).timeout
138
+ \t\tqueue_free()
139
+ `;
140
+
141
+ if (outputPath) {
142
+ await fs.mkdir(path.dirname(outputPath), { recursive: true });
143
+ await fs.writeFile(outputPath, gdScript, 'utf8');
144
+ }
145
+
146
+ return {
147
+ success: true,
148
+ output: JSON.stringify({
149
+ status: 'GENERATED_ENEMY_AI',
150
+ entity: entityName,
151
+ ai_type: aiType,
152
+ states_configured: ['PATROL', 'CHASE', 'ATTACK', 'STUNNED', 'DEAD'],
153
+ output_file: outputPath || 'Returned in payload',
154
+ script_snippet: gdScript.slice(0, 1000)
155
+ }, null, 2)
156
+ };
157
+ }
158
+
159
+ if (action === 'generate_boss_phase_controller') {
160
+ const bossScript = `extends CharacterBody2D
161
+
162
+ # Multi-Phase Boss Necromancer Controller (` + entityName + `)
163
+ enum BossPhase { PHASE_1_SPELLS, PHASE_2_SUMMONS, PHASE_3_ENRAGE, DEFEATED }
164
+
165
+ @export var max_hp: float = 800.0
166
+ var current_hp: float
167
+ var current_phase: BossPhase = BossPhase.PHASE_1_SPELLS
168
+
169
+ func _ready() -> void:
170
+ \tcurrent_hp = max_hp
171
+ \tprint("[Boss Ready] ", name, " entered PHASE_1_SPELLS (HP: ", max_hp, ")")
172
+
173
+ func take_damage(amount: float) -> void:
174
+ \tif current_phase == BossPhase.DEFEATED:
175
+ \t\treturn
176
+ \tcurrent_hp -= amount
177
+ \tvar hp_pct = current_hp / max_hp
178
+ \t
179
+ \tif hp_pct <= 0.35 and current_phase != BossPhase.PHASE_3_ENRAGE:
180
+ \t\tcurrent_phase = BossPhase.PHASE_3_ENRAGE
181
+ \t\tprint("[Boss Enrage] HP below 35%! Entering PHASE_3_ENRAGE!")
182
+ \t\t# Trigger boss_roar audio
183
+ \telif hp_pct <= 0.70 and current_phase == BossPhase.PHASE_1_SPELLS:
184
+ \t\tcurrent_phase = BossPhase.PHASE_2_SUMMONS
185
+ \t\tprint("[Boss Phase 2] HP below 70%! Summoning Skeletal Warriors!")
186
+ \t
187
+ \tif current_hp <= 0:
188
+ \t\tcurrent_phase = BossPhase.DEFEATED
189
+ \t\tprint("[Boss Defeated] ", name, " has fallen!")
190
+ \t\tqueue_free()
191
+ `;
192
+ return {
193
+ success: true,
194
+ output: JSON.stringify({
195
+ status: 'GENERATED_BOSS_CONTROLLER',
196
+ entity: entityName,
197
+ phases: ['PHASE_1_SPELLS', 'PHASE_2_SUMMONS', 'PHASE_3_ENRAGE', 'DEFEATED'],
198
+ script_snippet: bossScript
199
+ }, null, 2)
200
+ };
201
+ }
202
+
203
+ return { success: false, error: `Unknown action: ${action}` };
204
+ } catch (e) {
205
+ return { success: false, error: e.message };
206
+ }
207
+ }
208
+ };
@@ -0,0 +1,194 @@
1
+ import fs from 'fs/promises';
2
+ import fsSync from 'fs';
3
+ import path from 'path';
4
+
5
+ export const gameAnimationRig = {
6
+ schema: {
7
+ name: 'game.animation_rig',
8
+ description: 'Configures character rigging and animation setups for Godot 4.x. Supports 2D SpriteSheet animations (`AnimationPlayer`, `AnimatedSprite2D` frame slices) and 3D Skeletal rigs (`Skeleton3D`, `BoneAttachment3D`, `AnimationTree` state machines and 1D/2D blend spaces).',
9
+ parameters: {
10
+ type: 'object',
11
+ properties: {
12
+ action: {
13
+ type: 'string',
14
+ enum: ['rig_2d_spritesheet', 'rig_3d_skeleton', 'create_animation_tree', 'attach_weapon_bone'],
15
+ description: 'Action: rig_2d_spritesheet (setup 2D frame animation), rig_3d_skeleton (setup 3D bone bindings), create_animation_tree (build state machine/blend tree), or attach_weapon_bone (bind prop/sword to hand bone).'
16
+ },
17
+ characterName: {
18
+ type: 'string',
19
+ description: 'Name of the character node (`PlayerHero`, `SkeletonWarrior`, `BossNecromancer`).'
20
+ },
21
+ animationList: {
22
+ type: 'array',
23
+ items: {
24
+ type: 'object',
25
+ properties: {
26
+ anim_name: { type: 'string' },
27
+ loop: { type: 'boolean' },
28
+ fps: { type: 'number' },
29
+ frames: { type: 'array', items: { type: 'number' } }
30
+ }
31
+ },
32
+ description: 'List of animations (e.g. `idle`, `walk`, `attack_slash`, `hit`, `death`).'
33
+ },
34
+ spriteSheetPath: {
35
+ type: 'string',
36
+ description: 'Path to 2D texture sheet (`res://assets/2d/player_sheet.png`).'
37
+ },
38
+ hFrames: { type: 'number', description: 'Horizontal frames in sprite sheet.' },
39
+ vFrames: { type: 'number', description: 'Vertical frames in sprite sheet.' },
40
+ boneName: { type: 'string', description: 'Bone name for 3D attachment (`Hand_R`, `Spine`, `Head`).' },
41
+ propScenePath: { type: 'string', description: 'Path to prop scene to attach (`res://assets/3d/weapons/iron_sword.tscn`).' },
42
+ outputPath: { type: 'string', description: 'Output `.tscn` or `.tres` path to write the rigging definitions.' }
43
+ },
44
+ required: ['action', 'characterName']
45
+ }
46
+ },
47
+
48
+ async execute(args) {
49
+ try {
50
+ const { action, characterName, animationList = [], spriteSheetPath = 'res://assets/2d/hero.png', hFrames = 6, vFrames = 4, boneName = 'Hand_R', propScenePath = 'res://assets/3d/sword.tscn', outputPath } = args;
51
+
52
+ if (action === 'rig_2d_spritesheet') {
53
+ const anims = animationList.length > 0 ? animationList : [
54
+ { anim_name: 'idle', loop: true, fps: 8, frames: [0, 1, 2, 3] },
55
+ { anim_name: 'walk', loop: true, fps: 12, frames: [6, 7, 8, 9, 10, 11] },
56
+ { anim_name: 'attack_slash', loop: false, fps: 16, frames: [12, 13, 14, 15] },
57
+ { anim_name: 'hit', loop: false, fps: 10, frames: [18, 19] },
58
+ { anim_name: 'death', loop: false, fps: 8, frames: [20, 21, 22, 23] }
59
+ ];
60
+
61
+ // Generate Godot AnimationPlayer tracks for Sprite2D frame indexing
62
+ let animSubresources = '';
63
+ let animLibEntries = '';
64
+ let stepCount = 1;
65
+
66
+ for (const anim of anims) {
67
+ const duration = (anim.frames.length / (anim.fps || 10)).toFixed(3);
68
+ const loopMode = anim.loop ? '1' : '0';
69
+ const keys = anim.frames.map((f, idx) => `${(idx / (anim.fps || 10)).toFixed(3)}: ${f}`).join(', ');
70
+
71
+ animSubresources += `[sub_resource type="Animation" id="Animation_${stepCount}"]
72
+ resource_name = "${anim.anim_name}"
73
+ length = ${duration}
74
+ loop_mode = ${loopMode}
75
+ tracks/0/type = "value"
76
+ tracks/0/imported = false
77
+ tracks/0/enabled = true
78
+ tracks/0/path = NodePath("Sprite2D:frame")
79
+ tracks/0/interp = 1
80
+ tracks/0/loop_wrap = true
81
+ tracks/0/keys = {
82
+ "times": PackedFloat32Array(${anim.frames.map((_, idx) => (idx / (anim.fps || 10)).toFixed(3)).join(', ')}),
83
+ "transitions": PackedFloat32Array(${anim.frames.map(() => '1').join(', ')}),
84
+ "update": 1,
85
+ "values": [${anim.frames.join(', ')}]
86
+ }
87
+
88
+ `;
89
+ animLibEntries += `"${anim.anim_name}": SubResource("Animation_${stepCount}"),\n`;
90
+ stepCount++;
91
+ }
92
+
93
+ animSubresources += `[sub_resource type="AnimationLibrary" id="AnimationLibrary_rig"]
94
+ _data = {
95
+ ${animLibEntries.trim()}
96
+ }
97
+ `;
98
+
99
+ const sceneTree = `[gd_scene load_steps=${stepCount + 2} format=3]
100
+
101
+ [ext_resource type="Texture2D" path="${spriteSheetPath}" id="1_tex"]
102
+
103
+ ${animSubresources}
104
+ [node name="${characterName}" type="CharacterBody2D"]
105
+
106
+ [node name="Sprite2D" type="Sprite2D" parent="."]
107
+ texture = ExtResource("1_tex")
108
+ hframes = ${hFrames}
109
+ vframes = ${vFrames}
110
+
111
+ [node name="AnimationPlayer" type="AnimationPlayer" parent="."]
112
+ libraries = {
113
+ "": SubResource("AnimationLibrary_rig")
114
+ }
115
+ `;
116
+
117
+ if (outputPath) {
118
+ await fs.mkdir(path.dirname(outputPath), { recursive: true });
119
+ await fs.writeFile(outputPath, sceneTree, 'utf8');
120
+ }
121
+
122
+ return {
123
+ success: true,
124
+ output: JSON.stringify({
125
+ status: 'RIGGED_2D_SPRITESHEET',
126
+ character: characterName,
127
+ sprite_sheet: spriteSheetPath,
128
+ animations_configured: anims.map(a => a.anim_name),
129
+ output_file: outputPath || 'Returned in payload',
130
+ scene_snippet: sceneTree.slice(0, 1000)
131
+ }, null, 2)
132
+ };
133
+ }
134
+
135
+ if (action === 'create_animation_tree') {
136
+ const treeConfig = {
137
+ character: characterName,
138
+ tree_type: 'AnimationTree',
139
+ state_machine: {
140
+ states: ['Idle', 'Walk', 'AttackSlash', 'Hit', 'Death'],
141
+ transitions: [
142
+ { from: 'Idle', to: 'Walk', condition: 'is_moving' },
143
+ { from: 'Walk', to: 'Idle', condition: '!is_moving' },
144
+ { from: 'Idle', to: 'AttackSlash', condition: 'attack_trigger' },
145
+ { from: 'Walk', to: 'AttackSlash', condition: 'attack_trigger' },
146
+ { from: 'AttackSlash', to: 'Idle', condition: 'auto_finish' },
147
+ { from: 'Any', to: 'Hit', condition: 'take_damage' },
148
+ { from: 'Any', to: 'Death', condition: 'hp_zero' }
149
+ ]
150
+ },
151
+ gdscript_integration: `
152
+ # Paste into ${characterName}.gd
153
+ @onready var anim_tree: AnimationTree = $AnimationTree
154
+ @onready var state_machine = anim_tree.get("parameters/playback")
155
+
156
+ func _physics_process(delta: float) -> void:
157
+ \tvar velocity_length = velocity.length()
158
+ \tvar is_moving = velocity_length > 10.0
159
+ \tanim_tree.set("parameters/conditions/is_moving", is_moving)
160
+ \tanim_tree.set("parameters/conditions/not_moving", not is_moving)
161
+ `
162
+ };
163
+
164
+ return {
165
+ success: true,
166
+ output: JSON.stringify(treeConfig, null, 2)
167
+ };
168
+ }
169
+
170
+ if (action === 'attach_weapon_bone') {
171
+ const attachmentSnippet = `[node name="BoneAttachment_${boneName}" type="BoneAttachment3D" parent="Skeleton3D"]
172
+ bone_name = "${boneName}"
173
+
174
+ [node name="EquippedWeapon" parent="Skeleton3D/BoneAttachment_${boneName}" instance=ExtResource("${propScenePath}")]
175
+ position = Vector3(0, 0.1, 0)
176
+ rotation_degrees = Vector3(90, 0, 0)
177
+ `;
178
+ return {
179
+ success: true,
180
+ output: JSON.stringify({
181
+ status: 'ATTACHED_WEAPON_BONE',
182
+ bone: boneName,
183
+ prop: propScenePath,
184
+ scene_snippet: attachmentSnippet
185
+ }, null, 2)
186
+ };
187
+ }
188
+
189
+ return { success: false, error: `Unknown action: ${action}` };
190
+ } catch (e) {
191
+ return { success: false, error: e.message };
192
+ }
193
+ }
194
+ };