@causyne/agent 0.0.0-stage → 1.10.1
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/LICENSE +102 -0
- package/README.md +31 -2
- package/SECURITY.md +24 -0
- package/bin/causyne.js +13 -0
- package/docs/ARCHITECTURE.md +63 -0
- package/docs/PROVENANCE.md +29 -0
- package/docs/SECURITY_REVIEW.md +89 -0
- package/docs/THIRD_PARTY_NOTICES.md +49 -0
- package/native-skills/ai-engineering/context-window-management/SKILL.md +43 -0
- package/native-skills/ai-engineering/llm-evaluation/SKILL.md +46 -0
- package/native-skills/ai-engineering/model-cost-and-latency/SKILL.md +46 -0
- package/native-skills/ai-engineering/prompt-construction/SKILL.md +42 -0
- package/native-skills/ai-engineering/retrieval-augmented-generation/SKILL.md +42 -0
- package/native-skills/ai-engineering/structured-output-and-schemas/SKILL.md +45 -0
- package/native-skills/ai-engineering/tool-calling-agents/SKILL.md +43 -0
- package/native-skills/android/app-performance-profiling/SKILL.md +42 -0
- package/native-skills/android/background-work-scheduling/SKILL.md +47 -0
- package/native-skills/android/compose-state-and-recomposition/SKILL.md +43 -0
- package/native-skills/android/gradle-build-configuration/SKILL.md +41 -0
- package/native-skills/android/lifecycle-and-leaks/SKILL.md +46 -0
- package/native-skills/android/play-store-release/SKILL.md +43 -0
- package/native-skills/android/room-and-persistence/SKILL.md +40 -0
- package/native-skills/backend/authentication-and-sessions/SKILL.md +45 -0
- package/native-skills/backend/background-jobs-and-queues/SKILL.md +42 -0
- package/native-skills/backend/caching-strategy/SKILL.md +44 -0
- package/native-skills/backend/graceful-shutdown/SKILL.md +42 -0
- package/native-skills/backend/rate-limiting-and-quotas/SKILL.md +40 -0
- package/native-skills/backend/rest-api-design/SKILL.md +40 -0
- package/native-skills/backend/webhook-delivery-and-receipt/SKILL.md +43 -0
- package/native-skills/cloud/cost-optimisation/SKILL.md +46 -0
- package/native-skills/cloud/iam-least-privilege/SKILL.md +43 -0
- package/native-skills/cloud/infrastructure-as-code/SKILL.md +43 -0
- package/native-skills/cloud/multi-region-and-failover/SKILL.md +43 -0
- package/native-skills/cloud/serverless-patterns/SKILL.md +47 -0
- package/native-skills/data/data-quality-monitoring/SKILL.md +51 -0
- package/native-skills/data/etl-pipeline-reliability/SKILL.md +43 -0
- package/native-skills/data/exploratory-analysis/SKILL.md +43 -0
- package/native-skills/data/metric-definition/SKILL.md +42 -0
- package/native-skills/data/notebook-to-production/SKILL.md +43 -0
- package/native-skills/database/backup-and-recovery/SKILL.md +43 -0
- package/native-skills/database/connection-pooling/SKILL.md +42 -0
- package/native-skills/database/data-integrity-and-constraints/SKILL.md +42 -0
- package/native-skills/database/query-optimisation/SKILL.md +38 -0
- package/native-skills/database/safe-migrations/SKILL.md +47 -0
- package/native-skills/database/schema-design/SKILL.md +38 -0
- package/native-skills/database/transactions-and-isolation/SKILL.md +41 -0
- package/native-skills/design/colour-system-construction/SKILL.md +38 -0
- package/native-skills/design/design-direction-brief/SKILL.md +41 -0
- package/native-skills/design/motion-and-transitions/SKILL.md +38 -0
- package/native-skills/design/responsive-strategy/SKILL.md +39 -0
- package/native-skills/design/spacing-and-rhythm/SKILL.md +38 -0
- package/native-skills/design/type-scale-and-hierarchy/SKILL.md +39 -0
- package/native-skills/design/visual-qa-loop/SKILL.md +42 -0
- package/native-skills/devops/docker-multi-stage-builds/SKILL.md +60 -0
- package/native-skills/devops/github-actions-ci/SKILL.md +60 -0
- package/native-skills/devops/incident-triage/SKILL.md +38 -0
- package/native-skills/devops/kubernetes-deployment-hardening/SKILL.md +64 -0
- package/native-skills/devops/observability-baseline/SKILL.md +38 -0
- package/native-skills/devops/secret-management/SKILL.md +40 -0
- package/native-skills/devops/terraform-state-and-modules/SKILL.md +36 -0
- package/native-skills/devops/zero-downtime-deploys/SKILL.md +40 -0
- package/native-skills/git/bisect-regression-hunt/SKILL.md +43 -0
- package/native-skills/git/branch-strategy/SKILL.md +39 -0
- package/native-skills/git/commit-hygiene/SKILL.md +41 -0
- package/native-skills/git/history-recovery/SKILL.md +44 -0
- package/native-skills/git/large-repository-surgery/SKILL.md +46 -0
- package/native-skills/git/merge-conflict-resolution/SKILL.md +42 -0
- package/native-skills/media/cinematic-3d-shot/SKILL.md +104 -0
- package/native-skills/mobile/app-startup-optimisation/SKILL.md +41 -0
- package/native-skills/mobile/cross-platform-tradeoffs/SKILL.md +42 -0
- package/native-skills/mobile/deep-linking/SKILL.md +39 -0
- package/native-skills/mobile/mobile-storage-security/SKILL.md +45 -0
- package/native-skills/mobile/offline-first-sync/SKILL.md +42 -0
- package/native-skills/mobile/push-notifications/SKILL.md +38 -0
- package/native-skills/performance/algorithmic-complexity/SKILL.md +43 -0
- package/native-skills/performance/concurrency-and-parallelism/SKILL.md +42 -0
- package/native-skills/performance/load-testing/SKILL.md +42 -0
- package/native-skills/performance/memory-and-leak-hunting/SKILL.md +41 -0
- package/native-skills/performance/network-and-payload-efficiency/SKILL.md +42 -0
- package/native-skills/performance/profiling-methodology/SKILL.md +46 -0
- package/native-skills/python/async-correctness/SKILL.md +40 -0
- package/native-skills/python/cli-tool-construction/SKILL.md +44 -0
- package/native-skills/python/data-processing-pipelines/SKILL.md +38 -0
- package/native-skills/python/environment-isolation/SKILL.md +41 -0
- package/native-skills/python/packaging-and-distribution/SKILL.md +56 -0
- package/native-skills/python/pytest-suite-design/SKILL.md +39 -0
- package/native-skills/python/type-hints-and-static-checking/SKILL.md +42 -0
- package/native-skills/security/authorization-model/SKILL.md +42 -0
- package/native-skills/security/crypto-usage/SKILL.md +48 -0
- package/native-skills/security/dependency-supply-chain/SKILL.md +42 -0
- package/native-skills/security/input-validation-and-injection/SKILL.md +44 -0
- package/native-skills/security/secure-file-uploads/SKILL.md +46 -0
- package/native-skills/security/security-headers-and-csp/SKILL.md +44 -0
- package/native-skills/security/threat-modelling/SKILL.md +46 -0
- package/native-skills/testing/end-to-end-test-stability/SKILL.md +42 -0
- package/native-skills/testing/property-based-testing/SKILL.md +46 -0
- package/native-skills/testing/regression-test-from-a-bug/SKILL.md +41 -0
- package/native-skills/testing/snapshot-and-visual-regression/SKILL.md +42 -0
- package/native-skills/testing/test-doubles-and-mocking/SKILL.md +43 -0
- package/native-skills/testing/test-strategy-and-pyramid/SKILL.md +39 -0
- package/native-skills/testing/writing-good-assertions/SKILL.md +42 -0
- package/native-skills/web/accessible-components/SKILL.md +45 -0
- package/native-skills/web/api-client-resilience/SKILL.md +39 -0
- package/native-skills/web/bundle-size-reduction/SKILL.md +38 -0
- package/native-skills/web/core-web-vitals/SKILL.md +40 -0
- package/native-skills/web/css-layout-systems/SKILL.md +41 -0
- package/native-skills/web/form-validation-ux/SKILL.md +39 -0
- package/native-skills/web/react-state-architecture/SKILL.md +41 -0
- package/native-skills/web/ssr-hydration-correctness/SKILL.md +45 -0
- package/package.json +68 -4
- package/src/agentLoop.js +2458 -0
- package/src/appChannel.js +109 -0
- package/src/approvalGrants.js +66 -0
- package/src/auditLog.js +52 -0
- package/src/autoUpdate.js +12 -0
- package/src/capabilities.js +36 -0
- package/src/checkpoints.js +1199 -0
- package/src/cliMode.js +638 -0
- package/src/commands.js +805 -0
- package/src/compiledSkills.js +540 -0
- package/src/config.js +130 -0
- package/src/contextManager.js +498 -0
- package/src/cortex/autoCondenser.js +192 -0
- package/src/cortex/provisioner.js +27 -0
- package/src/cortex/vectorDb.js +447 -0
- package/src/designPalettes.js +99 -0
- package/src/devMode.js +6 -0
- package/src/embodimentSession.js +180 -0
- package/src/entrypoint.js +194 -0
- package/src/execSafe.js +21 -0
- package/src/gitSnapshot.js +378 -0
- package/src/mcp/jsonRpc.js +165 -0
- package/src/mcp/mcpClient.js +136 -0
- package/src/mcp/mcpRegistry.js +207 -0
- package/src/memory.js +62 -0
- package/src/memoryManager.js +124 -0
- package/src/modelCatalogue.js +132 -0
- package/src/modelIds.js +42 -0
- package/src/modelRouter.js +145 -0
- package/src/outputStore.js +246 -0
- package/src/perception.js +124 -0
- package/src/planCache.js +437 -0
- package/src/procSignal.js +32 -0
- package/src/providers/anthropic.js +408 -0
- package/src/providers/base.js +328 -0
- package/src/providers/dashscope-byok.js +86 -0
- package/src/providers/deepseek.js +80 -0
- package/src/providers/factory.js +37 -0
- package/src/providers/gemini.js +346 -0
- package/src/providers/moonshot.js +73 -0
- package/src/providers/muse.js +169 -0
- package/src/providers/ollama.js +104 -0
- package/src/providers/openai-compatible.js +84 -0
- package/src/providers/openai.js +20 -0
- package/src/providers/qwen-byok.js +76 -0
- package/src/providers/xai.js +73 -0
- package/src/provisioning/capabilityConsent.js +24 -0
- package/src/provisioning/capabilityProvisioner.js +271 -0
- package/src/provisioning/capabilityTools.js +29 -0
- package/src/reporting.js +373 -0
- package/src/sandbox.js +529 -0
- package/src/sessionStore.js +279 -0
- package/src/skillsManager.js +288 -0
- package/src/slopDetector.js +307 -0
- package/src/taskBuffer.js +45 -0
- package/src/taskShape.js +241 -0
- package/src/textDiff.js +150 -0
- package/src/tokenTracker.js +560 -0
- package/src/tool-scripts/ax_snapshot.applescript +39 -0
- package/src/tool-scripts/ax_snapshot.ps1 +10 -0
- package/src/tool-scripts/desktop_act.applescript +58 -0
- package/src/tool-scripts/resolve_automator.py +119 -0
- package/src/toolPacks.js +524 -0
- package/src/tools/archive.js +63 -0
- package/src/tools/astryxOracle.js +78 -0
- package/src/tools/axSnapshot.js +165 -0
- package/src/tools/blenderAutomator.js +349 -0
- package/src/tools/browserAutomator.js +252 -0
- package/src/tools/checkSystemSpecs.js +64 -0
- package/src/tools/clipboard.js +36 -0
- package/src/tools/codeSearchAst.js +101 -0
- package/src/tools/codeSearcher.js +230 -0
- package/src/tools/codeTools.js +262 -0
- package/src/tools/codebaseSearch.js +75 -0
- package/src/tools/createSkill.js +129 -0
- package/src/tools/deferredMcpSearch.js +246 -0
- package/src/tools/desktopAct.js +208 -0
- package/src/tools/desktopOpen.js +34 -0
- package/src/tools/dynamicLoader.js +44 -0
- package/src/tools/executeProceduralMedia.js +93 -0
- package/src/tools/fsDelete.js +51 -0
- package/src/tools/fsEdit.js +105 -0
- package/src/tools/fsFind.js +128 -0
- package/src/tools/fsList.js +77 -0
- package/src/tools/fsMove.js +57 -0
- package/src/tools/fsRead.js +87 -0
- package/src/tools/fsSearch.js +198 -0
- package/src/tools/fsWrite.js +41 -0
- package/src/tools/gameAiBehaviorTree.js +208 -0
- package/src/tools/gameAnimationRig.js +194 -0
- package/src/tools/gameAssetFetcher.js +372 -0
- package/src/tools/gameAssetHarvester.js +210 -0
- package/src/tools/gameAudioSynth.js +267 -0
- package/src/tools/gameBuilder.js +886 -0
- package/src/tools/gameCanvasAudit.js +101 -0
- package/src/tools/gameCinematicSequencer.js +151 -0
- package/src/tools/gameDataForge.js +124 -0
- package/src/tools/gameDialogueTreeGen.js +166 -0
- package/src/tools/gameEconomyBalancer.js +161 -0
- package/src/tools/gameEntitySpawner.js +207 -0
- package/src/tools/gameLoreForge.js +153 -0
- package/src/tools/gameQuestArcBuilder.js +152 -0
- package/src/tools/gameSceneBuilder.js +158 -0
- package/src/tools/gameShaderForge.js +181 -0
- package/src/tools/gameTilemapGenerator.js +164 -0
- package/src/tools/gameUiHudBuilder.js +292 -0
- package/src/tools/gameVfxEmitterGen.js +108 -0
- package/src/tools/gameWebRuntimeInspector.js +91 -0
- package/src/tools/generateMediaViaApi.js +358 -0
- package/src/tools/gitExec.js +54 -0
- package/src/tools/godotAutomator.js +437 -0
- package/src/tools/manageLocalAiDependencies.js +220 -0
- package/src/tools/memoryWrite.js +99 -0
- package/src/tools/multiEdit.js +107 -0
- package/src/tools/palmierAutomator.js +104 -0
- package/src/tools/pdfReader.js +112 -0
- package/src/tools/persistentShell.js +148 -0
- package/src/tools/printer.js +316 -0
- package/src/tools/procTerm.js +91 -0
- package/src/tools/processList.js +52 -0
- package/src/tools/readNativeSkill.js +39 -0
- package/src/tools/registry.js +277 -0
- package/src/tools/resolveAutomator.js +102 -0
- package/src/tools/screenshot.js +75 -0
- package/src/tools/subagentOrchestrator.js +305 -0
- package/src/tools/sysRun.js +125 -0
- package/src/tools/todoWrite.js +75 -0
- package/src/tools/toolDispatch.js +127 -0
- package/src/tools/toolForge.js +124 -0
- package/src/tools/updatePlan.js +88 -0
- package/src/tools/viewImage.js +82 -0
- package/src/tools/visionInspector.js +154 -0
- package/src/tools/webFetch.js +74 -0
- package/src/tools/webSearch.js +82 -0
- package/src/tui/ask.js +164 -0
- package/src/tui/banner.js +158 -0
- package/src/tui/block.js +152 -0
- package/src/tui/chatRenderer.js +953 -0
- package/src/tui/completion.js +424 -0
- package/src/tui/dialogs.js +606 -0
- package/src/tui/diff.js +296 -0
- package/src/tui/history.js +135 -0
- package/src/tui/home.js +217 -0
- package/src/tui/invocation.js +105 -0
- package/src/tui/keys.js +443 -0
- package/src/tui/lineEditor.js +256 -0
- package/src/tui/overlay.js +256 -0
- package/src/tui/prompt.js +1258 -0
- package/src/tui/selectList.js +335 -0
- package/src/tui/stage.js +330 -0
- package/src/tui/stageSurface.js +609 -0
- package/src/tui/statusLine.js +254 -0
- package/src/tui/text.js +345 -0
- package/src/tui/theme.js +393 -0
- package/src/tui/toolDisplay.js +176 -0
- package/src/tui/transcript.js +235 -0
- package/src/tui/viewport.js +337 -0
- package/src/uncertainty.js +271 -0
- package/src/userSkills.js +265 -0
- package/src/utils/cli_ui.js +0 -0
- package/src/utils/inquirer.js +12 -0
- package/src/utils/paths.js +37 -0
- package/src/version.js +38 -0
- package/src/vfeTracker.js +220 -0
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import fsSync from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
|
|
5
|
+
export const gameUiHudBuilder = {
|
|
6
|
+
schema: {
|
|
7
|
+
name: 'game.ui_hud_builder',
|
|
8
|
+
description: 'Constructs responsive UI/HUD scenes for Godot 4.x (`MainMenu.tscn`, `HUD.tscn` with player health/stamina bars, `InventoryGrid.tscn`, `DialogueBox.tscn`, `ShopMenu.tscn`, and `QuestLog.tscn`). Includes anchored layouts (`Control`) and signal bindings (`button_up`, `item_selected`).',
|
|
9
|
+
parameters: {
|
|
10
|
+
type: 'object',
|
|
11
|
+
properties: {
|
|
12
|
+
action: {
|
|
13
|
+
type: 'string',
|
|
14
|
+
enum: ['build_hud', 'build_main_menu', 'build_dialogue_box', 'build_inventory_grid', 'build_shop_menu', 'save_ui_scene'],
|
|
15
|
+
description: 'Action: build_hud (health/stamina overlay), build_main_menu (start/options/quit buttons), build_dialogue_box (NPC text panel), build_inventory_grid (item slots container), build_shop_menu (trade interface), or save_ui_scene (write .tscn to disk).'
|
|
16
|
+
},
|
|
17
|
+
uiName: {
|
|
18
|
+
type: 'string',
|
|
19
|
+
description: 'Name of the UI node (`PlayerHUD`, `MainMenu`, `DialogueUI`).'
|
|
20
|
+
},
|
|
21
|
+
gameTitle: {
|
|
22
|
+
type: 'string',
|
|
23
|
+
description: 'Title for MainMenu (`Chronicles of Aetheria`, `Cyberpunk Highway 3D`).'
|
|
24
|
+
},
|
|
25
|
+
hasStaminaBar: { type: 'boolean', description: 'Include stamina bar in HUD (default true).' },
|
|
26
|
+
inventorySlots: { type: 'number', description: 'Number of inventory grid slots (default 24).' },
|
|
27
|
+
outputPath: { type: 'string', description: 'Absolute or res:// path to save `.tscn` (`res://scenes/ui/HUD.tscn`).' }
|
|
28
|
+
},
|
|
29
|
+
required: ['action']
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
async execute(args) {
|
|
34
|
+
try {
|
|
35
|
+
const { action, uiName = 'GameUI', gameTitle = 'Chronicles of Aetheria', hasStaminaBar = true, inventorySlots = 24, outputPath } = args;
|
|
36
|
+
|
|
37
|
+
if (action === 'build_hud' || (action === 'save_ui_scene' && uiName.includes('HUD'))) {
|
|
38
|
+
const hudContent = `[gd_scene load_steps=2 format=3]
|
|
39
|
+
|
|
40
|
+
[node name="${uiName}" type="CanvasLayer"]
|
|
41
|
+
|
|
42
|
+
[node name="Control" type="Control" parent="."]
|
|
43
|
+
layout_mode = 3
|
|
44
|
+
anchors_preset = 15
|
|
45
|
+
anchor_right = 1.0
|
|
46
|
+
anchor_bottom = 1.0
|
|
47
|
+
grow_horizontal = 2
|
|
48
|
+
grow_vertical = 2
|
|
49
|
+
|
|
50
|
+
[node name="MarginContainer" type="MarginContainer" parent="Control"]
|
|
51
|
+
layout_mode = 0
|
|
52
|
+
offset_left = 24.0
|
|
53
|
+
offset_top = 24.0
|
|
54
|
+
offset_right = 264.0
|
|
55
|
+
offset_bottom = 104.0
|
|
56
|
+
|
|
57
|
+
[node name="VBoxContainer" type="VBoxContainer" parent="Control/MarginContainer"]
|
|
58
|
+
layout_mode = 2
|
|
59
|
+
theme_override_constants/separation = 8
|
|
60
|
+
|
|
61
|
+
[node name="HealthBar" type="ProgressBar" parent="Control/MarginContainer/VBoxContainer"]
|
|
62
|
+
layout_mode = 2
|
|
63
|
+
value = 100.0
|
|
64
|
+
show_percentage = false
|
|
65
|
+
|
|
66
|
+
[node name="Label" type="Label" parent="Control/MarginContainer/VBoxContainer/HealthBar"]
|
|
67
|
+
layout_mode = 1
|
|
68
|
+
anchors_preset = 8
|
|
69
|
+
anchor_left = 0.5
|
|
70
|
+
anchor_top = 0.5
|
|
71
|
+
anchor_right = 0.5
|
|
72
|
+
anchor_bottom = 0.5
|
|
73
|
+
offset_left = -20.0
|
|
74
|
+
offset_top = -11.5
|
|
75
|
+
offset_right = 20.0
|
|
76
|
+
offset_bottom = 11.5
|
|
77
|
+
grow_horizontal = 2
|
|
78
|
+
grow_vertical = 2
|
|
79
|
+
text = "100 / 100"
|
|
80
|
+
horizontal_alignment = 1
|
|
81
|
+
|
|
82
|
+
${hasStaminaBar ? `[node name="StaminaBar" type="ProgressBar" parent="Control/MarginContainer/VBoxContainer"]
|
|
83
|
+
layout_mode = 2
|
|
84
|
+
value = 100.0
|
|
85
|
+
show_percentage = false` : ''}
|
|
86
|
+
|
|
87
|
+
[node name="GoldLabel" type="Label" parent="Control/MarginContainer"]
|
|
88
|
+
layout_mode = 2
|
|
89
|
+
size_flags_vertical = 8
|
|
90
|
+
text = "Gold: 0"
|
|
91
|
+
`;
|
|
92
|
+
if (outputPath || action === 'save_ui_scene') {
|
|
93
|
+
const finalPath = outputPath || path.join(process.cwd(), '.tmp_causyne_3d', `${uiName}.tscn`);
|
|
94
|
+
await fs.mkdir(path.dirname(finalPath), { recursive: true });
|
|
95
|
+
await fs.writeFile(finalPath, hudContent, 'utf8');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
success: true,
|
|
100
|
+
output: JSON.stringify({
|
|
101
|
+
status: 'BUILT_HUD',
|
|
102
|
+
ui_name: uiName,
|
|
103
|
+
has_stamina: hasStaminaBar,
|
|
104
|
+
output_file: outputPath || 'Returned in payload',
|
|
105
|
+
snippet: hudContent.slice(0, 800)
|
|
106
|
+
}, null, 2)
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (action === 'build_main_menu') {
|
|
111
|
+
const menuContent = `[gd_scene format=3]
|
|
112
|
+
|
|
113
|
+
[node name="${uiName}" type="Control"]
|
|
114
|
+
layout_mode = 3
|
|
115
|
+
anchors_preset = 15
|
|
116
|
+
anchor_right = 1.0
|
|
117
|
+
anchor_bottom = 1.0
|
|
118
|
+
grow_horizontal = 2
|
|
119
|
+
grow_vertical = 2
|
|
120
|
+
|
|
121
|
+
[node name="Background" type="ColorRect" parent="."]
|
|
122
|
+
layout_mode = 1
|
|
123
|
+
anchors_preset = 15
|
|
124
|
+
anchor_right = 1.0
|
|
125
|
+
anchor_bottom = 1.0
|
|
126
|
+
grow_horizontal = 2
|
|
127
|
+
grow_vertical = 2
|
|
128
|
+
color = Color(0.08, 0.08, 0.12, 1)
|
|
129
|
+
|
|
130
|
+
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
|
131
|
+
layout_mode = 1
|
|
132
|
+
anchors_preset = 8
|
|
133
|
+
anchor_left = 0.5
|
|
134
|
+
anchor_top = 0.5
|
|
135
|
+
anchor_right = 0.5
|
|
136
|
+
anchor_bottom = 0.5
|
|
137
|
+
offset_left = -160.0
|
|
138
|
+
offset_top = -120.0
|
|
139
|
+
offset_right = 160.0
|
|
140
|
+
offset_bottom = 120.0
|
|
141
|
+
grow_horizontal = 2
|
|
142
|
+
grow_vertical = 2
|
|
143
|
+
theme_override_constants/separation = 16
|
|
144
|
+
|
|
145
|
+
[node name="TitleLabel" type="Label" parent="VBoxContainer"]
|
|
146
|
+
layout_mode = 2
|
|
147
|
+
theme_override_font_sizes/font_size = 36
|
|
148
|
+
text = "${gameTitle}"
|
|
149
|
+
horizontal_alignment = 1
|
|
150
|
+
|
|
151
|
+
[node name="StartButton" type="Button" parent="VBoxContainer"]
|
|
152
|
+
layout_mode = 2
|
|
153
|
+
text = "Start Game"
|
|
154
|
+
|
|
155
|
+
[node name="OptionsButton" type="Button" parent="VBoxContainer"]
|
|
156
|
+
layout_mode = 2
|
|
157
|
+
text = "Options"
|
|
158
|
+
|
|
159
|
+
[node name="QuitButton" type="Button" parent="VBoxContainer"]
|
|
160
|
+
layout_mode = 2
|
|
161
|
+
text = "Quit"
|
|
162
|
+
`;
|
|
163
|
+
if (outputPath) {
|
|
164
|
+
await fs.mkdir(path.dirname(outputPath), { recursive: true });
|
|
165
|
+
await fs.writeFile(outputPath, menuContent, 'utf8');
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return {
|
|
169
|
+
success: true,
|
|
170
|
+
output: JSON.stringify({
|
|
171
|
+
status: 'BUILT_MAIN_MENU',
|
|
172
|
+
ui_name: uiName,
|
|
173
|
+
game_title: gameTitle,
|
|
174
|
+
output_file: outputPath || 'Returned in payload',
|
|
175
|
+
snippet: menuContent.slice(0, 800)
|
|
176
|
+
}, null, 2)
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (action === 'build_dialogue_box') {
|
|
181
|
+
const boxContent = `[gd_scene format=3]
|
|
182
|
+
|
|
183
|
+
[node name="${uiName}" type="CanvasLayer"]
|
|
184
|
+
|
|
185
|
+
[node name="Panel" type="Panel" parent="."]
|
|
186
|
+
anchors_preset = 12
|
|
187
|
+
anchor_top = 1.0
|
|
188
|
+
anchor_right = 1.0
|
|
189
|
+
anchor_bottom = 1.0
|
|
190
|
+
offset_top = -160.0
|
|
191
|
+
grow_horizontal = 2
|
|
192
|
+
grow_vertical = 0
|
|
193
|
+
|
|
194
|
+
[node name="MarginContainer" type="MarginContainer" parent="Panel"]
|
|
195
|
+
layout_mode = 1
|
|
196
|
+
anchors_preset = 15
|
|
197
|
+
anchor_right = 1.0
|
|
198
|
+
anchor_bottom = 1.0
|
|
199
|
+
grow_horizontal = 2
|
|
200
|
+
grow_vertical = 2
|
|
201
|
+
theme_override_constants/margin_left = 20
|
|
202
|
+
theme_override_constants/margin_top = 16
|
|
203
|
+
theme_override_constants/margin_right = 20
|
|
204
|
+
theme_override_constants/margin_bottom = 16
|
|
205
|
+
|
|
206
|
+
[node name="VBoxContainer" type="VBoxContainer" parent="Panel/MarginContainer"]
|
|
207
|
+
layout_mode = 2
|
|
208
|
+
|
|
209
|
+
[node name="NPCNameLabel" type="Label" parent="Panel/MarginContainer/VBoxContainer"]
|
|
210
|
+
layout_mode = 2
|
|
211
|
+
theme_override_font_sizes/font_size = 20
|
|
212
|
+
text = "NPC Name"
|
|
213
|
+
|
|
214
|
+
[node name="DialogueText" type="RichTextLabel" parent="Panel/MarginContainer/VBoxContainer"]
|
|
215
|
+
layout_mode = 2
|
|
216
|
+
size_flags_vertical = 3
|
|
217
|
+
text = "Dialogue text goes here..."
|
|
218
|
+
|
|
219
|
+
[node name="ChoicesBox" type="HBoxContainer" parent="Panel/MarginContainer/VBoxContainer"]
|
|
220
|
+
layout_mode = 2
|
|
221
|
+
`;
|
|
222
|
+
if (outputPath) {
|
|
223
|
+
await fs.mkdir(path.dirname(outputPath), { recursive: true });
|
|
224
|
+
await fs.writeFile(outputPath, boxContent, 'utf8');
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return {
|
|
228
|
+
success: true,
|
|
229
|
+
output: JSON.stringify({
|
|
230
|
+
status: 'BUILT_DIALOGUE_BOX',
|
|
231
|
+
ui_name: uiName,
|
|
232
|
+
output_file: outputPath || 'Returned in payload',
|
|
233
|
+
snippet: boxContent.slice(0, 800)
|
|
234
|
+
}, null, 2)
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (action === 'build_inventory_grid') {
|
|
239
|
+
const gridContent = `[gd_scene format=3]
|
|
240
|
+
|
|
241
|
+
[node name="${uiName}" type="Control"]
|
|
242
|
+
layout_mode = 3
|
|
243
|
+
anchors_preset = 15
|
|
244
|
+
anchor_right = 1.0
|
|
245
|
+
anchor_bottom = 1.0
|
|
246
|
+
grow_horizontal = 2
|
|
247
|
+
grow_vertical = 2
|
|
248
|
+
|
|
249
|
+
[node name="GridContainer" type="GridContainer" parent="."]
|
|
250
|
+
layout_mode = 1
|
|
251
|
+
anchors_preset = 8
|
|
252
|
+
anchor_left = 0.5
|
|
253
|
+
anchor_top = 0.5
|
|
254
|
+
anchor_right = 0.5
|
|
255
|
+
anchor_bottom = 0.5
|
|
256
|
+
offset_left = -240.0
|
|
257
|
+
offset_top = -180.0
|
|
258
|
+
offset_right = 240.0
|
|
259
|
+
offset_bottom = 180.0
|
|
260
|
+
grow_horizontal = 2
|
|
261
|
+
grow_vertical = 2
|
|
262
|
+
columns = 6
|
|
263
|
+
# Inventory grid slots count: ${inventorySlots}
|
|
264
|
+
`;
|
|
265
|
+
if (outputPath) {
|
|
266
|
+
await fs.mkdir(path.dirname(outputPath), { recursive: true });
|
|
267
|
+
await fs.writeFile(outputPath, gridContent, 'utf8');
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return {
|
|
271
|
+
success: true,
|
|
272
|
+
output: JSON.stringify({
|
|
273
|
+
status: 'BUILT_INVENTORY_GRID',
|
|
274
|
+
slots: inventorySlots,
|
|
275
|
+
output_file: outputPath || 'Returned in payload'
|
|
276
|
+
}, null, 2)
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (action === 'build_shop_menu') {
|
|
281
|
+
return {
|
|
282
|
+
success: true,
|
|
283
|
+
output: JSON.stringify({ status: 'BUILT_SHOP_MENU', ui_name: uiName }, null, 2)
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
return { success: false, error: `Unknown action: ${action}` };
|
|
288
|
+
} catch (e) {
|
|
289
|
+
return { success: false, error: e.message };
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import fsSync from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
|
|
5
|
+
export const gameVfxEmitterGen = {
|
|
6
|
+
schema: {
|
|
7
|
+
name: 'game.vfx_emitter_gen',
|
|
8
|
+
description: 'Generates procedural `GPUParticles2D/3D` particle systems (spells, fire, smoke, laser sparks, explosions, floating aura, dust) with custom `ParticleProcessMaterial` configurations and pre-baked sub-resources.',
|
|
9
|
+
parameters: {
|
|
10
|
+
type: 'object',
|
|
11
|
+
properties: {
|
|
12
|
+
action: {
|
|
13
|
+
type: 'string',
|
|
14
|
+
enum: ['generate_emitter', 'create_vfx_preset', 'save_vfx_scene'],
|
|
15
|
+
description: 'Action: generate_emitter (create GPUParticles node snippet), create_vfx_preset (get ParticleProcessMaterial data), or save_vfx_scene (write `.tscn` file).'
|
|
16
|
+
},
|
|
17
|
+
effectType: {
|
|
18
|
+
type: 'string',
|
|
19
|
+
enum: ['spell_sparkle', 'raging_fire', 'toxic_smoke', 'explosion_burst', 'laser_sparks', 'healing_aura', 'speed_lines'],
|
|
20
|
+
description: 'Preset visual effect type.'
|
|
21
|
+
},
|
|
22
|
+
emitterDimension: {
|
|
23
|
+
type: 'string',
|
|
24
|
+
enum: ['2d', '3d'],
|
|
25
|
+
description: 'Dimension (`2d` or `3d`).'
|
|
26
|
+
},
|
|
27
|
+
amount: { type: 'number', description: 'Number of emitted particles (default 64).' },
|
|
28
|
+
lifetime: { type: 'number', description: 'Particle lifetime in seconds (default 1.2s).' },
|
|
29
|
+
colorHex: { type: 'string', description: 'Base color hex (`#ff006e`, `#3a86ff`, `#fb5607`).' },
|
|
30
|
+
outputPath: { type: 'string', description: 'Path to save `.tscn` file (`res://scenes/vfx/fire.tscn`).' }
|
|
31
|
+
},
|
|
32
|
+
required: ['action', 'effectType']
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
async execute(args) {
|
|
37
|
+
try {
|
|
38
|
+
const { action, effectType, emitterDimension = '2d', amount = 64, lifetime = 1.2, colorHex = '#ff006e', outputPath } = args;
|
|
39
|
+
|
|
40
|
+
if (action === 'generate_emitter' || action === 'save_vfx_scene') {
|
|
41
|
+
const nodeClass = emitterDimension === '3d' ? 'GPUParticles3D' : 'GPUParticles2D';
|
|
42
|
+
const gravity = effectType === 'toxic_smoke' || effectType === 'healing_aura' ? 'Vector3(0, 98, 0)' : 'Vector3(0, -98, 0)';
|
|
43
|
+
const explosiveness = effectType === 'explosion_burst' || effectType === 'laser_sparks' ? '0.85' : '0.1';
|
|
44
|
+
|
|
45
|
+
const materialResource = `[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_vfx"]
|
|
46
|
+
emission_shape = 1
|
|
47
|
+
emission_sphere_radius = ${effectType === 'healing_aura' ? '30.0' : '10.0'}
|
|
48
|
+
direction = Vector3(0, 1, 0)
|
|
49
|
+
spread = ${effectType === 'explosion_burst' ? '180.0' : '45.0'}
|
|
50
|
+
gravity = ${gravity}
|
|
51
|
+
initial_velocity_min = ${effectType === 'explosion_burst' ? '120.0' : '30.0'}
|
|
52
|
+
initial_velocity_max = ${effectType === 'explosion_burst' ? '250.0' : '80.0'}
|
|
53
|
+
scale_min = 2.0
|
|
54
|
+
scale_max = 6.0
|
|
55
|
+
color = Color(${colorHex})
|
|
56
|
+
`;
|
|
57
|
+
|
|
58
|
+
const sceneContent = `[gd_scene load_steps=2 format=3]
|
|
59
|
+
|
|
60
|
+
${materialResource}
|
|
61
|
+
[node name="VFX_${effectType}" type="${nodeClass}"]
|
|
62
|
+
amount = ${amount}
|
|
63
|
+
lifetime = ${lifetime}
|
|
64
|
+
explosiveness = ${explosiveness}
|
|
65
|
+
process_material = SubResource("ParticleProcessMaterial_vfx")
|
|
66
|
+
`;
|
|
67
|
+
|
|
68
|
+
if (outputPath || action === 'save_vfx_scene') {
|
|
69
|
+
const finalPath = outputPath || path.join(process.cwd(), '.tmp_causyne_3d', `vfx_${effectType}.tscn`);
|
|
70
|
+
await fs.mkdir(path.dirname(finalPath), { recursive: true });
|
|
71
|
+
await fs.writeFile(finalPath, sceneContent, 'utf8');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
success: true,
|
|
76
|
+
output: JSON.stringify({
|
|
77
|
+
status: 'GENERATED_VFX_EMITTER',
|
|
78
|
+
effect_type: effectType,
|
|
79
|
+
dimension: emitterDimension,
|
|
80
|
+
amount: amount,
|
|
81
|
+
lifetime: lifetime,
|
|
82
|
+
output_file: outputPath || 'Returned in payload',
|
|
83
|
+
scene_snippet: sceneContent.slice(0, 800)
|
|
84
|
+
}, null, 2)
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (action === 'create_vfx_preset') {
|
|
89
|
+
return {
|
|
90
|
+
success: true,
|
|
91
|
+
output: JSON.stringify({
|
|
92
|
+
preset: effectType,
|
|
93
|
+
dimension: emitterDimension,
|
|
94
|
+
material_properties: {
|
|
95
|
+
spread: effectType === 'explosion_burst' ? 180 : 45,
|
|
96
|
+
gravity: effectType === 'toxic_smoke' ? [0, 98, 0] : [0, -98, 0],
|
|
97
|
+
initial_velocity: [30, 150]
|
|
98
|
+
}
|
|
99
|
+
}, null, 2)
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return { success: false, error: `Unknown action: ${action}` };
|
|
104
|
+
} catch (e) {
|
|
105
|
+
return { success: false, error: e.message };
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import util from 'util';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { ensureCapability, loadCapabilityPackage } from '../provisioning/capabilityProvisioner.js';
|
|
4
|
+
|
|
5
|
+
export const gameWebRuntimeInspector = {
|
|
6
|
+
schema: {
|
|
7
|
+
name: 'game_web_runtime_inspector',
|
|
8
|
+
description: 'Runs a headless Chromium quality gate to verify game runtime stability. Checks for JS exceptions and FPS. Mandatory in Stage 7 of the Sovereign Game Cascade.',
|
|
9
|
+
parameters: {
|
|
10
|
+
type: 'object',
|
|
11
|
+
properties: {
|
|
12
|
+
url: {
|
|
13
|
+
type: 'string',
|
|
14
|
+
description: 'The URL or local file path to the HTML game.'
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
required: ['url']
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
execute: async (args) => {
|
|
21
|
+
let { url } = args;
|
|
22
|
+
if (!url) return { success: false, error: 'URL is required' };
|
|
23
|
+
|
|
24
|
+
if (url.startsWith('/')) {
|
|
25
|
+
url = 'file://' + url;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
const vision = await ensureCapability('vision');
|
|
30
|
+
if (!vision.ok) return { success: false, error: vision.reason, requiresConsent: vision.requiresConsent };
|
|
31
|
+
// loadCapabilityPackage already unwraps a default export; this file uses
|
|
32
|
+
// the namespace shape below, so keep it wrapped.
|
|
33
|
+
const puppeteer = { default: await loadCapabilityPackage('puppeteer-core') };
|
|
34
|
+
|
|
35
|
+
const browser = await puppeteer.default.launch({
|
|
36
|
+
executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
|
|
37
|
+
headless: 'new',
|
|
38
|
+
args: ['--no-sandbox', '--disable-setuid-sandbox', '--autoplay-policy=no-user-gesture-required']
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const page = await browser.newPage();
|
|
42
|
+
|
|
43
|
+
const errors = [];
|
|
44
|
+
page.on('pageerror', err => {
|
|
45
|
+
errors.push(err.toString());
|
|
46
|
+
});
|
|
47
|
+
page.on('console', msg => {
|
|
48
|
+
if (msg.type() === 'error') {
|
|
49
|
+
errors.push(msg.text());
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
await page.goto(url, { waitUntil: 'load', timeout: 15000 }).catch(e => {
|
|
54
|
+
errors.push("Goto timeout or error: " + e.message);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Inject FPS counter
|
|
58
|
+
const fpsResult = await page.evaluate(() => {
|
|
59
|
+
return new Promise((resolve) => {
|
|
60
|
+
let frames = 0;
|
|
61
|
+
let startTime = performance.now();
|
|
62
|
+
const loop = () => {
|
|
63
|
+
frames++;
|
|
64
|
+
if (performance.now() - startTime < 3000) {
|
|
65
|
+
requestAnimationFrame(loop);
|
|
66
|
+
} else {
|
|
67
|
+
resolve(frames / 3); // Average FPS over 3 seconds
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
requestAnimationFrame(loop);
|
|
71
|
+
});
|
|
72
|
+
}).catch(e => {
|
|
73
|
+
errors.push("FPS Evaluate error: " + e.message);
|
|
74
|
+
return 0;
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
await browser.close();
|
|
78
|
+
|
|
79
|
+
const status = (errors.length === 0 && fpsResult >= 30) ? 'HEALTHY' : 'UNHEALTHY';
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
status: status,
|
|
83
|
+
mean_fps: Math.round(fpsResult * 10) / 10,
|
|
84
|
+
console_errors: errors
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
} catch (e) {
|
|
88
|
+
return { success: false, error: 'Runtime Inspector crashed: ' + e.message };
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
};
|