@directivegames/genesys.sdk 3.2.2

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 (181) hide show
  1. package/README.md +60 -0
  2. package/dist/src/asset-pack/eslint.config.js +43 -0
  3. package/dist/src/asset-pack/scripts/postinstall.js +64 -0
  4. package/dist/src/asset-pack/src/index.js +1 -0
  5. package/dist/src/core/cli.js +306 -0
  6. package/dist/src/core/common.js +324 -0
  7. package/dist/src/core/index.js +6 -0
  8. package/dist/src/core/tools/build-project.js +450 -0
  9. package/dist/src/core/tools/index.js +2 -0
  10. package/dist/src/core/tools/new-asset-pack.js +150 -0
  11. package/dist/src/core/tools/new-project.js +292 -0
  12. package/dist/src/core/types.js +1 -0
  13. package/dist/src/dependencies.js +82 -0
  14. package/dist/src/electron/IpcSerializableError.js +38 -0
  15. package/dist/src/electron/api.js +7 -0
  16. package/dist/src/electron/backend/actions.js +56 -0
  17. package/dist/src/electron/backend/handler.js +441 -0
  18. package/dist/src/electron/backend/logging.js +41 -0
  19. package/dist/src/electron/backend/main.js +315 -0
  20. package/dist/src/electron/backend/menu.js +208 -0
  21. package/dist/src/electron/backend/state.js +201 -0
  22. package/dist/src/electron/backend/tools/const.js +9 -0
  23. package/dist/src/electron/backend/tools/file-server.js +383 -0
  24. package/dist/src/electron/backend/tools/open-project.js +261 -0
  25. package/dist/src/electron/backend/window.js +161 -0
  26. package/dist/src/templates/eslint.config.js +43 -0
  27. package/dist/src/templates/scripts/genesys/build-project.js +42 -0
  28. package/dist/src/templates/scripts/genesys/calc-bounding-box.js +205 -0
  29. package/dist/src/templates/scripts/genesys/common.js +36 -0
  30. package/dist/src/templates/scripts/genesys/const.js +9 -0
  31. package/dist/src/templates/scripts/genesys/dev/dump-default-scene.js +8 -0
  32. package/dist/src/templates/scripts/genesys/dev/generate-manifest.js +116 -0
  33. package/dist/src/templates/scripts/genesys/dev/launcher.js +39 -0
  34. package/dist/src/templates/scripts/genesys/dev/storage-provider.js +188 -0
  35. package/dist/src/templates/scripts/genesys/dev/update-template-scenes.js +67 -0
  36. package/dist/src/templates/scripts/genesys/doc-server.js +12 -0
  37. package/dist/src/templates/scripts/genesys/genesys-mcp.js +413 -0
  38. package/dist/src/templates/scripts/genesys/mcp/doc-tools.js +70 -0
  39. package/dist/src/templates/scripts/genesys/mcp/editor-functions.js +123 -0
  40. package/dist/src/templates/scripts/genesys/mcp/editor-tools.js +51 -0
  41. package/dist/src/templates/scripts/genesys/mcp/get-scene-state.js +26 -0
  42. package/dist/src/templates/scripts/genesys/mcp/run-subprocess.js +23 -0
  43. package/dist/src/templates/scripts/genesys/mcp/search-actors.js +703 -0
  44. package/dist/src/templates/scripts/genesys/mcp/search-assets.js +296 -0
  45. package/dist/src/templates/scripts/genesys/mcp/utils.js +234 -0
  46. package/dist/src/templates/scripts/genesys/misc.js +32 -0
  47. package/dist/src/templates/scripts/genesys/mock.js +5 -0
  48. package/dist/src/templates/scripts/genesys/place-actors.js +112 -0
  49. package/dist/src/templates/scripts/genesys/post-install.js +25 -0
  50. package/dist/src/templates/scripts/genesys/remove-engine-comments.js +113 -0
  51. package/dist/src/templates/scripts/genesys/storageProvider.js +146 -0
  52. package/dist/src/templates/scripts/genesys/validate-prefabs.js +115 -0
  53. package/dist/src/templates/src/index.js +20 -0
  54. package/dist/src/templates/src/templates/firstPerson/src/auto-imports.js +1 -0
  55. package/dist/src/templates/src/templates/firstPerson/src/game.js +30 -0
  56. package/dist/src/templates/src/templates/firstPerson/src/player.js +60 -0
  57. package/dist/src/templates/src/templates/fps/src/auto-imports.js +1 -0
  58. package/dist/src/templates/src/templates/fps/src/game.js +30 -0
  59. package/dist/src/templates/src/templates/fps/src/player.js +64 -0
  60. package/dist/src/templates/src/templates/fps/src/weapon.js +62 -0
  61. package/dist/src/templates/src/templates/freeCamera/src/auto-imports.js +1 -0
  62. package/dist/src/templates/src/templates/freeCamera/src/game.js +30 -0
  63. package/dist/src/templates/src/templates/freeCamera/src/player.js +43 -0
  64. package/dist/src/templates/src/templates/sideScroller/src/auto-imports.js +1 -0
  65. package/dist/src/templates/src/templates/sideScroller/src/const.js +43 -0
  66. package/dist/src/templates/src/templates/sideScroller/src/game.js +103 -0
  67. package/dist/src/templates/src/templates/sideScroller/src/level-generator.js +249 -0
  68. package/dist/src/templates/src/templates/sideScroller/src/player.js +105 -0
  69. package/dist/src/templates/src/templates/thirdPerson/src/auto-imports.js +1 -0
  70. package/dist/src/templates/src/templates/thirdPerson/src/game.js +30 -0
  71. package/dist/src/templates/src/templates/thirdPerson/src/player.js +63 -0
  72. package/dist/src/templates/src/templates/vehicle/src/auto-imports.js +1 -0
  73. package/dist/src/templates/src/templates/vehicle/src/base-vehicle.js +122 -0
  74. package/dist/src/templates/src/templates/vehicle/src/game.js +33 -0
  75. package/dist/src/templates/src/templates/vehicle/src/mesh-vehicle.js +189 -0
  76. package/dist/src/templates/src/templates/vehicle/src/player.js +102 -0
  77. package/dist/src/templates/src/templates/vehicle/src/primitive-vehicle.js +259 -0
  78. package/dist/src/templates/src/templates/vehicle/src/ui-hints.js +100 -0
  79. package/dist/src/templates/src/templates/vr-game/src/auto-imports.js +1 -0
  80. package/dist/src/templates/src/templates/vr-game/src/game.js +55 -0
  81. package/dist/src/templates/src/templates/vr-game/src/sample-vr-actor.js +29 -0
  82. package/dist/src/templates/vite.config.js +46 -0
  83. package/package.json +176 -0
  84. package/scripts/post-install.ts +143 -0
  85. package/src/asset-pack/.gitattributes +89 -0
  86. package/src/asset-pack/eslint.config.js +45 -0
  87. package/src/asset-pack/gitignore +11 -0
  88. package/src/asset-pack/scripts/postinstall.ts +81 -0
  89. package/src/asset-pack/src/index.ts +0 -0
  90. package/src/asset-pack/tsconfig.json +34 -0
  91. package/src/templates/.cursor/mcp.json +20 -0
  92. package/src/templates/.cursorignore +2 -0
  93. package/src/templates/.gitattributes +89 -0
  94. package/src/templates/.vscode/settings.json +6 -0
  95. package/src/templates/AGENTS.md +86 -0
  96. package/src/templates/CLAUDE.md +1 -0
  97. package/src/templates/README.md +24 -0
  98. package/src/templates/eslint.config.js +45 -0
  99. package/src/templates/gitignore +11 -0
  100. package/src/templates/index.html +34 -0
  101. package/src/templates/pnpm-lock.yaml +3676 -0
  102. package/src/templates/scripts/genesys/build-project.ts +51 -0
  103. package/src/templates/scripts/genesys/calc-bounding-box.ts +272 -0
  104. package/src/templates/scripts/genesys/common.ts +46 -0
  105. package/src/templates/scripts/genesys/const.ts +9 -0
  106. package/src/templates/scripts/genesys/dev/dump-default-scene.ts +11 -0
  107. package/src/templates/scripts/genesys/dev/generate-manifest.ts +146 -0
  108. package/src/templates/scripts/genesys/dev/launcher.ts +46 -0
  109. package/src/templates/scripts/genesys/dev/storage-provider.ts +229 -0
  110. package/src/templates/scripts/genesys/dev/update-template-scenes.ts +84 -0
  111. package/src/templates/scripts/genesys/doc-server.ts +16 -0
  112. package/src/templates/scripts/genesys/genesys-mcp.ts +526 -0
  113. package/src/templates/scripts/genesys/mcp/doc-tools.ts +86 -0
  114. package/src/templates/scripts/genesys/mcp/editor-functions.ts +151 -0
  115. package/src/templates/scripts/genesys/mcp/editor-tools.ts +73 -0
  116. package/src/templates/scripts/genesys/mcp/get-scene-state.ts +35 -0
  117. package/src/templates/scripts/genesys/mcp/run-subprocess.ts +30 -0
  118. package/src/templates/scripts/genesys/mcp/search-actors.ts +858 -0
  119. package/src/templates/scripts/genesys/mcp/search-assets.ts +380 -0
  120. package/src/templates/scripts/genesys/mcp/utils.ts +281 -0
  121. package/src/templates/scripts/genesys/misc.ts +42 -0
  122. package/src/templates/scripts/genesys/mock.ts +6 -0
  123. package/src/templates/scripts/genesys/place-actors.ts +179 -0
  124. package/src/templates/scripts/genesys/post-install.ts +30 -0
  125. package/src/templates/scripts/genesys/prefab.schema.json +85 -0
  126. package/src/templates/scripts/genesys/remove-engine-comments.ts +135 -0
  127. package/src/templates/scripts/genesys/run-mcp-inspector.bat +5 -0
  128. package/src/templates/scripts/genesys/storageProvider.ts +182 -0
  129. package/src/templates/scripts/genesys/validate-prefabs.ts +138 -0
  130. package/src/templates/src/index.ts +22 -0
  131. package/src/templates/src/templates/firstPerson/assets/default.genesys-scene +166 -0
  132. package/src/templates/src/templates/firstPerson/src/auto-imports.ts +0 -0
  133. package/src/templates/src/templates/firstPerson/src/game.ts +39 -0
  134. package/src/templates/src/templates/firstPerson/src/player.ts +63 -0
  135. package/src/templates/src/templates/fps/assets/default.genesys-scene +9460 -0
  136. package/src/templates/src/templates/fps/assets/models/SM_Beam_400.glb +0 -0
  137. package/src/templates/src/templates/fps/assets/models/SM_ChamferCube.glb +0 -0
  138. package/src/templates/src/templates/fps/assets/models/SM_Floor_Thick_400x400.glb +0 -0
  139. package/src/templates/src/templates/fps/assets/models/SM_Floor_Thick_400x400_Orange.glb +0 -0
  140. package/src/templates/src/templates/fps/assets/models/SM_Floor_Thin_400x400.glb +0 -0
  141. package/src/templates/src/templates/fps/assets/models/SM_Floor_Thin_400x400_Orange.glb +0 -0
  142. package/src/templates/src/templates/fps/assets/models/SM_Ramp_400x400.glb +0 -0
  143. package/src/templates/src/templates/fps/assets/models/SM_Rifle.glb +0 -0
  144. package/src/templates/src/templates/fps/assets/models/SM_Wall_Thin_400x200.glb +0 -0
  145. package/src/templates/src/templates/fps/assets/models/SM_Wall_Thin_400x200_Orange.glb +0 -0
  146. package/src/templates/src/templates/fps/assets/models/SM_Wall_Thin_400x400.glb +0 -0
  147. package/src/templates/src/templates/fps/assets/models/SM_Wall_Thin_400x400_Orange.glb +0 -0
  148. package/src/templates/src/templates/fps/src/auto-imports.ts +0 -0
  149. package/src/templates/src/templates/fps/src/game.ts +39 -0
  150. package/src/templates/src/templates/fps/src/player.ts +69 -0
  151. package/src/templates/src/templates/fps/src/weapon.ts +54 -0
  152. package/src/templates/src/templates/freeCamera/assets/default.genesys-scene +166 -0
  153. package/src/templates/src/templates/freeCamera/src/auto-imports.ts +0 -0
  154. package/src/templates/src/templates/freeCamera/src/game.ts +39 -0
  155. package/src/templates/src/templates/freeCamera/src/player.ts +45 -0
  156. package/src/templates/src/templates/sideScroller/assets/default.genesys-scene +122 -0
  157. package/src/templates/src/templates/sideScroller/src/auto-imports.ts +0 -0
  158. package/src/templates/src/templates/sideScroller/src/const.ts +46 -0
  159. package/src/templates/src/templates/sideScroller/src/game.ts +122 -0
  160. package/src/templates/src/templates/sideScroller/src/level-generator.ts +361 -0
  161. package/src/templates/src/templates/sideScroller/src/player.ts +125 -0
  162. package/src/templates/src/templates/thirdPerson/assets/default.genesys-scene +166 -0
  163. package/src/templates/src/templates/thirdPerson/src/auto-imports.ts +0 -0
  164. package/src/templates/src/templates/thirdPerson/src/game.ts +39 -0
  165. package/src/templates/src/templates/thirdPerson/src/player.ts +61 -0
  166. package/src/templates/src/templates/vehicle/assets/default.genesys-scene +226 -0
  167. package/src/templates/src/templates/vehicle/assets/models/cyberTruck/chassis.glb +0 -0
  168. package/src/templates/src/templates/vehicle/assets/models/cyberTruck/wheel.glb +0 -0
  169. package/src/templates/src/templates/vehicle/src/auto-imports.ts +0 -0
  170. package/src/templates/src/templates/vehicle/src/base-vehicle.ts +145 -0
  171. package/src/templates/src/templates/vehicle/src/game.ts +43 -0
  172. package/src/templates/src/templates/vehicle/src/mesh-vehicle.ts +191 -0
  173. package/src/templates/src/templates/vehicle/src/player.ts +109 -0
  174. package/src/templates/src/templates/vehicle/src/primitive-vehicle.ts +266 -0
  175. package/src/templates/src/templates/vehicle/src/ui-hints.ts +101 -0
  176. package/src/templates/src/templates/vr-game/assets/default.genesys-scene +247 -0
  177. package/src/templates/src/templates/vr-game/src/auto-imports.ts +1 -0
  178. package/src/templates/src/templates/vr-game/src/game.ts +66 -0
  179. package/src/templates/src/templates/vr-game/src/sample-vr-actor.ts +26 -0
  180. package/src/templates/tsconfig.json +35 -0
  181. package/src/templates/vite.config.ts +52 -0
@@ -0,0 +1,6 @@
1
+ import { mockBrowserEnvironment as engineMock } from 'genesys.js';
2
+ import { JSDOM } from 'jsdom';
3
+
4
+ export function mockBrowserEnvironment() {
5
+ engineMock(JSDOM);
6
+ }
@@ -0,0 +1,179 @@
1
+ import * as ENGINE from 'genesys.js';
2
+ import * as THREE from 'three';
3
+
4
+ import { ThreeEulerSchema, ThreeVector3Schema } from './mcp/search-actors.js';
5
+ import { loadWorld, registerGameClassesIfAnyNotRegistered } from './mcp/utils.js';
6
+ import { mockBrowserEnvironment } from './mock.js';
7
+
8
+ import '../src/game.js';
9
+
10
+
11
+ mockBrowserEnvironment();
12
+
13
+ function convertConstructorParams(value: any): any {
14
+ // If not an object, return as is
15
+ if (!value || typeof value !== 'object') {
16
+ return value;
17
+ }
18
+
19
+ // Check if it's a Vector3
20
+ const vector3Result = ThreeVector3Schema.safeParse(value);
21
+ if (vector3Result.success) {
22
+ return new THREE.Vector3(
23
+ vector3Result.data.x,
24
+ vector3Result.data.y,
25
+ vector3Result.data.z
26
+ );
27
+ }
28
+
29
+ // Check if it's an Euler
30
+ const eulerResult = ThreeEulerSchema.safeParse(value);
31
+ if (eulerResult.success) {
32
+ return new THREE.Euler(
33
+ eulerResult.data.x,
34
+ eulerResult.data.y,
35
+ eulerResult.data.z
36
+ );
37
+ }
38
+
39
+ // Handle arrays
40
+ if (Array.isArray(value)) {
41
+ return value.map(convertConstructorParams);
42
+ }
43
+
44
+ // Handle objects
45
+ const result: Record<string, any> = {};
46
+ for (const [key, val] of Object.entries(value)) {
47
+ result[key] = convertConstructorParams(val);
48
+ }
49
+ return result;
50
+ }
51
+
52
+
53
+ export async function placePrimitive(args: {
54
+ sceneName: string;
55
+ primitiveActors: ENGINE.WorldCommands.PrimitiveActorArgs[];
56
+ }): Promise<string[]> {
57
+
58
+ using worldResource = await loadWorld(args.sceneName, { skipLoadingGLTF: true });
59
+
60
+ const actors = ENGINE.WorldCommands.placePrimitives({
61
+ world: worldResource.world,
62
+ primitiveActors: args.primitiveActors,
63
+ });
64
+
65
+ return actors.map(actor => actor.uuid);
66
+ }
67
+
68
+
69
+ export async function removeActors(args: {
70
+ sceneName: string;
71
+ actorIds: string[];
72
+ }) {
73
+ using worldResource = await loadWorld(args.sceneName, { skipLoadingGLTF: true });
74
+
75
+ ENGINE.WorldCommands.removeActorsByUuids({
76
+ world: worldResource.world,
77
+ actorIds: args.actorIds,
78
+ });
79
+ }
80
+
81
+ export async function addGltf(args: {
82
+ sceneName: string;
83
+ gltfs: ENGINE.WorldCommands.GltfArgs[];
84
+ }) {
85
+ using worldResource = await loadWorld(args.sceneName, { skipLoadingGLTF: true });
86
+
87
+ const actors = await ENGINE.WorldCommands.placeGltfs({
88
+ world: worldResource.world,
89
+ gltfs: args.gltfs
90
+ });
91
+
92
+ return actors.map(actor => actor.uuid);
93
+ }
94
+
95
+ export async function placePrefab(args: {
96
+ sceneName: string;
97
+ prefabs: ENGINE.WorldCommands.PrefabArgs[];
98
+ }) {
99
+ using worldResource = await loadWorld(args.sceneName, { skipLoadingGLTF: true });
100
+
101
+ const actors = await ENGINE.WorldCommands.placePrefabs({
102
+ world: worldResource.world,
103
+ prefabs: args.prefabs
104
+ });
105
+
106
+ return actors.map(actor => actor.uuid);
107
+ }
108
+
109
+ export async function placeJsClassActor(args: {
110
+ sceneName: string;
111
+ jsClasses: {
112
+ className: string;
113
+ constructorParams?: Record<string, any>[]
114
+ actorInfo?: ENGINE.WorldCommands.ActorMiscInfo;
115
+ }[]
116
+ }): Promise<string[]> {
117
+ await registerGameClassesIfAnyNotRegistered(
118
+ args.jsClasses.map(jsClass => jsClass.className)
119
+ );
120
+ using worldResource = await loadWorld(args.sceneName, { skipLoadingGLTF: true });
121
+
122
+ const actors: ENGINE.Actor[] = [];
123
+
124
+ for (const { className, constructorParams, actorInfo } of args.jsClasses) {
125
+ try {
126
+ // Convert constructor parameters if they exist
127
+ const convertedParams = constructorParams ? convertConstructorParams(constructorParams) : [];
128
+
129
+ const actor = ENGINE.ClassRegistry.constructObject(className, false, ...convertedParams);
130
+ if (actorInfo) {
131
+ Object.assign(actor.editorData, actorInfo);
132
+ }
133
+ actors.push(actor);
134
+ } catch (e) {
135
+ console.error(`Error constructing object ${className}`, e);
136
+ }
137
+ }
138
+
139
+ worldResource.world.addActors(...actors);
140
+ return actors.map(actor => actor.uuid);
141
+ }
142
+
143
+
144
+ export async function updateActors(args: {
145
+ sceneName: string;
146
+ actorsToUpdate: {
147
+ uuid: string;
148
+ transform?: ENGINE.WorldCommands.Transform;
149
+ actorInfo?: ENGINE.WorldCommands.ActorMiscInfo;
150
+ }[];
151
+ }): Promise<number> {
152
+ const readonly = args.actorsToUpdate.length == 0;
153
+ using worldResource = await loadWorld(args.sceneName, { readonly, skipLoadingGLTF: true });
154
+ let count = 0;
155
+
156
+ for (const { uuid, transform, actorInfo } of args.actorsToUpdate) {
157
+ const actor = worldResource.world.getActorByUuid(uuid);
158
+ if (!actor) {
159
+ continue;
160
+ }
161
+ if (transform) {
162
+ if (transform.position) {
163
+ actor.setWorldPosition(transform.position);
164
+ }
165
+ if (transform.rotation) {
166
+ actor.setWorldRotation(transform.rotation);
167
+ }
168
+ if (transform.scale) {
169
+ actor.setWorldScale(transform.scale);
170
+ }
171
+ if (actorInfo) {
172
+ Object.assign(actor.editorData, actorInfo);
173
+ }
174
+ }
175
+ count += 1;
176
+ }
177
+ return count;
178
+ }
179
+
@@ -0,0 +1,30 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+
4
+ import { getProjectRoot } from './common.js';
5
+
6
+
7
+ async function main() {
8
+ const engineInstallFolder = path.join(getProjectRoot(), 'node_modules/genesys.js');
9
+ if (!fs.existsSync(engineInstallFolder)) {
10
+ return;
11
+ }
12
+ const copiedEngineFolder = path.join(getProjectRoot(), '.engine');
13
+ if (fs.existsSync(copiedEngineFolder)) {
14
+ fs.rmdirSync(copiedEngineFolder, { recursive: true });
15
+ }
16
+ fs.mkdirSync(copiedEngineFolder, { recursive: true });
17
+
18
+ const foldersToCopy: string[] = [
19
+ 'games/examples',
20
+ 'src',
21
+ 'docs',
22
+ ];
23
+ for (const folder of foldersToCopy) {
24
+ const engineFolderPath = path.join(engineInstallFolder, folder);
25
+ const localFolderPath = path.join(copiedEngineFolder, folder);
26
+ fs.cpSync(engineFolderPath, localFolderPath, { recursive: true });
27
+ }
28
+ }
29
+
30
+ main();
@@ -0,0 +1,85 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft-07/schema",
3
+ "$id": "genesys.js.prefab.schema.json",
4
+ "type": "object",
5
+ "properties": {
6
+ "$version": {
7
+ "type": "integer"
8
+ },
9
+ "class": {
10
+ "$ref": "class_string"
11
+ },
12
+ "ctor": {
13
+ "$ref": "actor_ctor"
14
+ },
15
+ "properties": {
16
+ "$ref": "actor_properties"
17
+ }
18
+ },
19
+ "definitions": {
20
+ "actor_ctor": {
21
+ "type": "object",
22
+ "properties": {
23
+ "rootComponent": {
24
+ "$ref": "component"
25
+ }
26
+ }
27
+ },
28
+ "actor_properties": {
29
+ "type": "object"
30
+ },
31
+ "component_ctor": {
32
+ "type": "object"
33
+ },
34
+ "component_properties": {
35
+ "type": "object",
36
+ "properties": {
37
+ "position": {
38
+ "$ref": "type_vector3"
39
+ },
40
+ "rotation": {
41
+ "$ref": "type_euler"
42
+ },
43
+ "scale": {
44
+ "$ref": "type_euler"
45
+ }
46
+ }
47
+ },
48
+ "type_vector3": {
49
+ "type": "array",
50
+ "minItems": 4,
51
+ "maxItems": 4,
52
+ "examples": [[0, 0, 0, "v"]]
53
+ },
54
+ "type_euler": {
55
+ "type": "array",
56
+ "minItems": 4,
57
+ "maxItems": 4,
58
+ "examples": [[0, 0, 0, "e"]]
59
+ },
60
+ "component": {
61
+ "type": "object",
62
+ "properties": {
63
+ "class": {
64
+ "$ref": "class_string"
65
+ },
66
+ "ctor": {
67
+ "$ref": "component_ctor"
68
+ },
69
+ "properties": {
70
+ "$ref": "component_properties"
71
+ },
72
+ "children": {
73
+ "type": "array",
74
+ "items": {
75
+ "$ref": "component"
76
+ }
77
+ }
78
+ }
79
+ },
80
+ "class_string": {
81
+ "type": "string",
82
+ "pattern": "(GAME|ENGINE)\\..*"
83
+ }
84
+ }
85
+ }
@@ -0,0 +1,135 @@
1
+ #!/usr/bin/env tsx
2
+
3
+ import { readdir, readFile, stat, writeFile } from 'fs/promises';
4
+ import { join } from 'path';
5
+
6
+ /**
7
+ * Recursively finds all TypeScript files in a directory
8
+ */
9
+ async function findTsFiles(dir: string): Promise<string[]> {
10
+ const files: string[] = [];
11
+
12
+ try {
13
+ const entries = await readdir(dir);
14
+
15
+ for (const entry of entries) {
16
+ const fullPath = join(dir, entry);
17
+ const stats = await stat(fullPath);
18
+
19
+ if (stats.isDirectory()) {
20
+ const subFiles = await findTsFiles(fullPath);
21
+ files.push(...subFiles);
22
+ } else if (entry.endsWith('.ts') || entry.endsWith('.tsx')) {
23
+ files.push(fullPath);
24
+ }
25
+ }
26
+ } catch (error) {
27
+ console.warn(`Warning: Could not read directory ${dir}:`, error);
28
+ }
29
+
30
+ return files;
31
+ }
32
+
33
+ /**
34
+ * Removes comments from TypeScript code using regex
35
+ */
36
+ function removeComments(code: string): { cleaned: string; hadComments: boolean } {
37
+ const originalLength = code.length;
38
+
39
+ // Remove single-line comments (// comments)
40
+ // This regex handles // comments but preserves URLs and string literals
41
+ let cleaned = code.replace(/^(\s*)\/\/.*$/gm, '$1');
42
+
43
+ // Remove multi-line comments (/* ... */ and /** ... */)
44
+ // This regex handles nested quotes and preserves strings
45
+ cleaned = cleaned.replace(/\/\*[\s\S]*?\*\//g, '');
46
+
47
+ // Clean up multiple consecutive empty lines (replace with single empty line)
48
+ cleaned = cleaned.replace(/\n\s*\n\s*\n/g, '\n\n');
49
+
50
+ // Trim trailing whitespace on each line
51
+ cleaned = cleaned.replace(/[ \t]+$/gm, '');
52
+
53
+ const hadComments = cleaned.length !== originalLength || cleaned !== code;
54
+
55
+ return { cleaned, hadComments };
56
+ }
57
+
58
+ /**
59
+ * Removes comments from a TypeScript file
60
+ */
61
+ async function removeCommentsFromFile(filePath: string): Promise<boolean> {
62
+ try {
63
+ const content = await readFile(filePath, 'utf8');
64
+ const { cleaned, hadComments } = removeComments(content);
65
+
66
+ if (!hadComments) {
67
+ return false; // No comments to remove
68
+ }
69
+
70
+ await writeFile(filePath, cleaned, 'utf8');
71
+ return true;
72
+ } catch (error) {
73
+ console.error(`Error processing file ${filePath}:`, error);
74
+ return false;
75
+ }
76
+ }
77
+
78
+ async function main() {
79
+ const engineDir = '.engine';
80
+
81
+ console.log(`Searching for TypeScript files in ${engineDir}...`);
82
+ console.log(`Current working directory: ${process.cwd()}`);
83
+
84
+ try {
85
+ const tsFiles = await findTsFiles(engineDir);
86
+
87
+ console.log(`Found ${tsFiles.length} TypeScript files.`);
88
+ if (tsFiles.length > 0) {
89
+ console.log('First few files:');
90
+ tsFiles.slice(0, 5).forEach(file => console.log(` - ${file}`));
91
+ }
92
+
93
+ if (tsFiles.length === 0) {
94
+ console.log('No TypeScript files found in .engine folder.');
95
+ return;
96
+ }
97
+
98
+ let processedCount = 0;
99
+ let modifiedCount = 0;
100
+
101
+ for (const filePath of tsFiles) {
102
+ console.log(`Processing: ${filePath}`);
103
+
104
+ try {
105
+ const wasModified = await removeCommentsFromFile(filePath);
106
+ processedCount++;
107
+
108
+ if (wasModified) {
109
+ modifiedCount++;
110
+ console.log(' ✓ Comments removed');
111
+ } else {
112
+ console.log(' - No comments found');
113
+ }
114
+ } catch (error) {
115
+ console.error(` ✗ Error: ${error}`);
116
+ }
117
+ }
118
+
119
+ console.log('\nCompleted:');
120
+ console.log(`- Files processed: ${processedCount}`);
121
+ console.log(`- Files modified: ${modifiedCount}`);
122
+ console.log(`- Files skipped: ${processedCount - modifiedCount}`);
123
+
124
+ } catch (error) {
125
+ console.error('Error:', error);
126
+ process.exit(1);
127
+ }
128
+ }
129
+
130
+ // Always run main if this file is executed directly
131
+ main().catch((error) => {
132
+ console.error('Unexpected error:', error);
133
+ console.error('Stack trace:', error.stack);
134
+ process.exit(1);
135
+ });
@@ -0,0 +1,5 @@
1
+ pushd %~dp0
2
+ cd ..
3
+ set DANGEROUSLY_OMIT_AUTH=1
4
+ pnpm dlx @modelcontextprotocol/inspector pnpm dlx tsx ./scripts/genesys/genesys-mcp.ts
5
+ popd
@@ -0,0 +1,182 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+
4
+ import * as ENGINE from 'genesys.js';
5
+ import { AssetPath, AssetPathEncodeState } from 'genesys.js';
6
+
7
+ import { getProjectRoot } from './common.js';
8
+
9
+
10
+ export class StorageProvider implements ENGINE.IStorageProvider {
11
+ public async resolvePath(assetPath: AssetPath, expiry?: number): Promise<AssetPath> {
12
+ if (assetPath.isResolved()) {
13
+ return assetPath;
14
+ }
15
+
16
+ assetPath.resolvePath(this.getFullPath(assetPath.initialPath), AssetPathEncodeState.Decoded);
17
+ return assetPath;
18
+ }
19
+
20
+ public getFullPath(filePath: string): string {
21
+ let fullPath = filePath;
22
+ let rootPath = undefined;
23
+
24
+ if (filePath.startsWith(ENGINE.PROJECT_PATH_PREFIX)) {
25
+ filePath = filePath.slice(ENGINE.PROJECT_PATH_PREFIX.length);
26
+ rootPath = getProjectRoot();
27
+ }
28
+ else if (filePath.startsWith(ENGINE.ENGINE_PATH_PREFIX)) {
29
+ filePath = filePath.slice(ENGINE.ENGINE_PATH_PREFIX.length);
30
+ rootPath = path.join(getProjectRoot(), 'node_modules', 'genesys.js');
31
+ }
32
+
33
+ if (rootPath !== undefined) {
34
+ fullPath = AssetPath.join(rootPath, filePath);
35
+ }
36
+ return fullPath;
37
+ }
38
+
39
+ public async downloadFileAsBuffer(
40
+ assetPath: AssetPath,
41
+ ): Promise<ArrayBuffer> {
42
+ assetPath = await this.resolvePath(assetPath);
43
+ const fullPath = getResolvedPath(assetPath);
44
+ if (!fs.existsSync(fullPath)) {
45
+ return new ArrayBuffer(0);
46
+ }
47
+
48
+ const data = fs.readFileSync(fullPath);
49
+ const arrayBuffer = data.buffer.slice(
50
+ data.byteOffset,
51
+ data.byteOffset + data.byteLength
52
+ );
53
+ return arrayBuffer;
54
+ }
55
+
56
+ public async downloadFileAsJson<T>(assetPath: AssetPath): Promise<T> {
57
+ assetPath = await this.resolvePath(assetPath);
58
+ const fullPath = getResolvedPath(assetPath);
59
+ if (!fs.existsSync(fullPath)) {
60
+ return {} as T;
61
+ }
62
+ return JSON.parse(fs.readFileSync(fullPath, 'utf8'));
63
+ }
64
+
65
+ public async downloadFileAsText(assetPath: AssetPath): Promise<string> {
66
+ assetPath = await this.resolvePath(assetPath);
67
+ const fullPath = getResolvedPath(assetPath);
68
+ if (!fs.existsSync(fullPath)) {
69
+ return '';
70
+ }
71
+ return fs.readFileSync(fullPath, 'utf8');
72
+ }
73
+
74
+ public async exists(assetPath: AssetPath): Promise<boolean> {
75
+ assetPath = await this.resolvePath(assetPath);
76
+ const fullPath = getResolvedPath(assetPath);
77
+ return fs.existsSync(fullPath);
78
+ }
79
+
80
+ public async buildCurrentProject(runTsc: boolean): Promise<boolean> {
81
+ throw new Error('Not implemented');
82
+ }
83
+
84
+ public async uploadFile(assetPath: AssetPath, content: Blob | File | string | ArrayBuffer, options?: ENGINE.FileUploadOptions): Promise<{
85
+ path: string;
86
+ name: string;
87
+ }>
88
+ {
89
+ assetPath = await this.resolvePath(assetPath);
90
+ const fullPath = getResolvedPath(assetPath);
91
+ fs.mkdirSync(path.dirname(fullPath), { recursive: true });
92
+
93
+ if (typeof content === 'string') {
94
+ fs.writeFileSync(fullPath, content);
95
+ } else {
96
+ throw new Error(`Unsupported content type: ${typeof content}`);
97
+ }
98
+
99
+ return {
100
+ path: fullPath,
101
+ name: path.basename(fullPath)
102
+ };
103
+ }
104
+
105
+ public async deleteFile(assetPath: AssetPath): Promise<void> {
106
+ assetPath = await this.resolvePath(assetPath);
107
+ const fullPath = getResolvedPath(assetPath);
108
+ if (fs.existsSync(fullPath)) {
109
+ fs.unlinkSync(fullPath);
110
+ }
111
+ }
112
+
113
+ public async listFiles(assetPath: AssetPath, recursive?: boolean, includeHiddenFiles?: boolean): Promise<ENGINE.FileListResult> {
114
+ assetPath = await this.resolvePath(assetPath);
115
+ const fullPath = getResolvedPath(assetPath);
116
+
117
+ if (!fs.existsSync(fullPath)) {
118
+ return { files: [], directories: [] };
119
+ }
120
+
121
+ const files: ENGINE.FileItem[] = [];
122
+ const directories: ENGINE.FileItem[] = [];
123
+
124
+ const processDirectory = (dirPath: string, basePath: string = '') => {
125
+ const entries = fs.readdirSync(dirPath, { withFileTypes: true });
126
+
127
+ for (const entry of entries) {
128
+ // Skip hidden files if not requested
129
+ if (!includeHiddenFiles && entry.name.startsWith('.')) {
130
+ continue;
131
+ }
132
+
133
+ const fullEntryPath = path.join(dirPath, entry.name);
134
+ const relativePath = basePath ? path.join(basePath, entry.name) : entry.name;
135
+ const stats = fs.statSync(fullEntryPath);
136
+
137
+ const fileItem: ENGINE.FileItem = {
138
+ name: entry.name,
139
+ path: relativePath,
140
+ absolutePath: fullEntryPath,
141
+ size: stats.size,
142
+ modifiedTime: stats.mtime,
143
+ isDirectory: entry.isDirectory()
144
+ };
145
+
146
+ if (entry.isDirectory()) {
147
+ directories.push(fileItem);
148
+
149
+ // Recursively process subdirectories if requested
150
+ if (recursive) {
151
+ processDirectory(fullEntryPath, relativePath);
152
+ }
153
+ } else {
154
+ files.push(fileItem);
155
+ }
156
+ }
157
+ };
158
+
159
+ // Check if the path is a directory
160
+ const stats = fs.statSync(fullPath);
161
+ if (stats.isDirectory()) {
162
+ processDirectory(fullPath);
163
+ } else {
164
+ // If it's a file, return just that file
165
+ const fileItem: ENGINE.FileItem = {
166
+ name: path.basename(fullPath),
167
+ path: path.basename(fullPath),
168
+ absolutePath: fullPath,
169
+ size: stats.size,
170
+ modifiedTime: stats.mtime,
171
+ isDirectory: false
172
+ };
173
+ files.push(fileItem);
174
+ }
175
+
176
+ return { files, directories };
177
+ }
178
+ }
179
+
180
+ export function getResolvedPath(assetPath: ENGINE.AssetPath): string {
181
+ return assetPath.getResolvedPath(false);
182
+ }