@lampdotdev/lamp 0.0.0-stage → 0.36.2-nightly.16

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 (470) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +397 -2
  3. package/Resources/Devices/roku.json +410 -0
  4. package/Resources/Devices/xbox-one.json +367 -0
  5. package/Resources/GameKit/NOTICE.md +63 -0
  6. package/Resources/GameKit/apple/LampPage.swift +1813 -0
  7. package/Resources/GameKit/apple/LampPlayer.swift +46 -0
  8. package/Resources/GameKit/apple/LampWebApp.swift +63 -0
  9. package/Resources/GameKit/apple/LampWebGame.swift +87 -0
  10. package/Resources/GameKit/apple/Native.swift +12 -0
  11. package/Resources/GameKit/build.sh +55 -0
  12. package/Resources/GameKit/lamp_game.h +116 -0
  13. package/Resources/GameKit/lamp_host.h +19 -0
  14. package/Resources/GameKit/lamp_kit.cpp +61 -0
  15. package/Resources/GameKit/lamp_sound.cpp +455 -0
  16. package/Resources/GameKit/lamp_xbox.cpp +374 -0
  17. package/Resources/GameKit/libraries/HandmadeMath.h +3940 -0
  18. package/Resources/GameKit/libraries/cgltf.h +7240 -0
  19. package/Resources/GameKit/libraries/dr_mp3.h +5430 -0
  20. package/Resources/GameKit/libraries/dr_wav.h +9209 -0
  21. package/Resources/GameKit/libraries/sokol_debugtext.h +4754 -0
  22. package/Resources/GameKit/libraries/sokol_gfx.h +29558 -0
  23. package/Resources/GameKit/libraries/sokol_gl.h +4538 -0
  24. package/Resources/GameKit/libraries/sokol_log.h +335 -0
  25. package/Resources/GameKit/libraries/sokol_shape.h +1531 -0
  26. package/Resources/GameKit/libraries/stb_image.h +7988 -0
  27. package/Resources/GameKit/libraries/stb_vorbis.c +5584 -0
  28. package/Resources/GameKit/page/lamp-live.js +672 -0
  29. package/Resources/GameKit/scaffold/Game/game.cpp +142 -0
  30. package/Resources/GameKit/scaffold/Game/scene.glsl +49 -0
  31. package/Resources/GameKit/scaffold-web/Web/game.js +31 -0
  32. package/Resources/GameKit/scaffold-web/Web/index.html +13 -0
  33. package/Resources/GameKit/scaffold-web/Web/making.js +33 -0
  34. package/Resources/GameKit/scaffold-web/Web/world.js +33 -0
  35. package/Resources/GameKit/web/lamp-game.js +3042 -0
  36. package/Resources/GameKit/web/lamp-phaser.js +128 -0
  37. package/Resources/WebHost/App.exe +0 -0
  38. package/Resources/WebHost/Microsoft.Web.WebView2.Core.dll +0 -0
  39. package/Resources/WebHost/WebView2-LICENSE.txt +27 -0
  40. package/Resources/WebHost/lamp_controllers.h +1506 -0
  41. package/Resources/WebHost/lamp_web_host.cpp +1173 -0
  42. package/Resources/WebLibraries/earlier.txt +318 -0
  43. package/Resources/WebLibraries/phaser/LICENSE.md +20 -0
  44. package/Resources/WebLibraries/phaser/NOTICE.md +2 -0
  45. package/Resources/WebLibraries/phaser/phaser.esm.min.js +1 -0
  46. package/Resources/WebLibraries/qrcode/LICENSE +21 -0
  47. package/Resources/WebLibraries/qrcode/NOTICE.md +4 -0
  48. package/Resources/WebLibraries/qrcode/qrcode.js +2297 -0
  49. package/Resources/WebLibraries/rapier/LICENSE +201 -0
  50. package/Resources/WebLibraries/rapier/NOTICE.md +3 -0
  51. package/Resources/WebLibraries/rapier/rapier.js +2 -0
  52. package/Resources/WebLibraries/three/LICENSE +21 -0
  53. package/Resources/WebLibraries/three/NOTICE.md +4 -0
  54. package/Resources/WebLibraries/three/addons/animation/AnimationClipCreator.js +168 -0
  55. package/Resources/WebLibraries/three/addons/animation/CCDIKSolver.js +607 -0
  56. package/Resources/WebLibraries/three/addons/controls/ArcballControls.js +3543 -0
  57. package/Resources/WebLibraries/three/addons/controls/DragControls.js +452 -0
  58. package/Resources/WebLibraries/three/addons/controls/FirstPersonControls.js +512 -0
  59. package/Resources/WebLibraries/three/addons/controls/FlyControls.js +384 -0
  60. package/Resources/WebLibraries/three/addons/controls/MapControls.js +116 -0
  61. package/Resources/WebLibraries/three/addons/controls/OrbitControls.js +1985 -0
  62. package/Resources/WebLibraries/three/addons/controls/PointerLockControls.js +264 -0
  63. package/Resources/WebLibraries/three/addons/controls/TrackballControls.js +1106 -0
  64. package/Resources/WebLibraries/three/addons/controls/TransformControls.js +2003 -0
  65. package/Resources/WebLibraries/three/addons/curves/CurveExtras.js +694 -0
  66. package/Resources/WebLibraries/three/addons/curves/NURBSCurve.js +169 -0
  67. package/Resources/WebLibraries/three/addons/curves/NURBSSurface.js +98 -0
  68. package/Resources/WebLibraries/three/addons/curves/NURBSUtils.js +532 -0
  69. package/Resources/WebLibraries/three/addons/curves/NURBSVolume.js +82 -0
  70. package/Resources/WebLibraries/three/addons/effects/AnaglyphEffect.js +274 -0
  71. package/Resources/WebLibraries/three/addons/effects/AsciiEffect.js +323 -0
  72. package/Resources/WebLibraries/three/addons/effects/OutlineEffect.js +489 -0
  73. package/Resources/WebLibraries/three/addons/effects/ParallaxBarrierEffect.js +155 -0
  74. package/Resources/WebLibraries/three/addons/effects/StereoEffect.js +91 -0
  75. package/Resources/WebLibraries/three/addons/environments/ColorEnvironment.js +59 -0
  76. package/Resources/WebLibraries/three/addons/environments/DebugEnvironment.js +102 -0
  77. package/Resources/WebLibraries/three/addons/environments/RoomEnvironment.js +185 -0
  78. package/Resources/WebLibraries/three/addons/geometries/BoxLineGeometry.js +92 -0
  79. package/Resources/WebLibraries/three/addons/geometries/ConvexGeometry.js +72 -0
  80. package/Resources/WebLibraries/three/addons/geometries/DecalGeometry.js +420 -0
  81. package/Resources/WebLibraries/three/addons/geometries/LoftGeometry.js +355 -0
  82. package/Resources/WebLibraries/three/addons/geometries/ParametricFunctions.js +100 -0
  83. package/Resources/WebLibraries/three/addons/geometries/ParametricGeometry.js +172 -0
  84. package/Resources/WebLibraries/three/addons/geometries/RoundedBoxGeometry.js +216 -0
  85. package/Resources/WebLibraries/three/addons/geometries/TeapotGeometry.js +689 -0
  86. package/Resources/WebLibraries/three/addons/geometries/TextGeometry.js +102 -0
  87. package/Resources/WebLibraries/three/addons/helpers/AnimationPathHelper.js +302 -0
  88. package/Resources/WebLibraries/three/addons/helpers/LightProbeGridHelper.js +166 -0
  89. package/Resources/WebLibraries/three/addons/helpers/LightProbeGridHelperWebGL.js +221 -0
  90. package/Resources/WebLibraries/three/addons/helpers/LightProbeHelper.js +166 -0
  91. package/Resources/WebLibraries/three/addons/helpers/LightProbeHelperGPU.js +102 -0
  92. package/Resources/WebLibraries/three/addons/helpers/OctreeHelper.js +109 -0
  93. package/Resources/WebLibraries/three/addons/helpers/PositionalAudioHelper.js +169 -0
  94. package/Resources/WebLibraries/three/addons/helpers/RapierHelper.js +59 -0
  95. package/Resources/WebLibraries/three/addons/helpers/RectAreaLightHelper.js +118 -0
  96. package/Resources/WebLibraries/three/addons/helpers/TextureHelper.js +265 -0
  97. package/Resources/WebLibraries/three/addons/helpers/TextureHelperGPU.js +214 -0
  98. package/Resources/WebLibraries/three/addons/helpers/VertexNormalsHelper.js +155 -0
  99. package/Resources/WebLibraries/three/addons/helpers/VertexTangentsHelper.js +133 -0
  100. package/Resources/WebLibraries/three/addons/helpers/ViewHelper.js +529 -0
  101. package/Resources/WebLibraries/three/addons/interactive/HTMLMesh.js +617 -0
  102. package/Resources/WebLibraries/three/addons/interactive/InteractiveGroup.js +224 -0
  103. package/Resources/WebLibraries/three/addons/interactive/SelectionBox.js +324 -0
  104. package/Resources/WebLibraries/three/addons/interactive/SelectionHelper.js +150 -0
  105. package/Resources/WebLibraries/three/addons/libs/fflate.module.js +2699 -0
  106. package/Resources/WebLibraries/three/addons/libs/lil-gui.module.min.js +8 -0
  107. package/Resources/WebLibraries/three/addons/libs/meshopt_decoder.module.js +196 -0
  108. package/Resources/WebLibraries/three/addons/libs/potpack.module.js +125 -0
  109. package/Resources/WebLibraries/three/addons/libs/stats.module.js +167 -0
  110. package/Resources/WebLibraries/three/addons/libs/tween.module.js +876 -0
  111. package/Resources/WebLibraries/three/addons/lighting/ClusteredLighting.js +153 -0
  112. package/Resources/WebLibraries/three/addons/lighting/DynamicLighting.js +82 -0
  113. package/Resources/WebLibraries/three/addons/lighting/LightMapper.js +295 -0
  114. package/Resources/WebLibraries/three/addons/lighting/LightProbeGrid.js +923 -0
  115. package/Resources/WebLibraries/three/addons/lighting/LightProbeGridUtils.js +107 -0
  116. package/Resources/WebLibraries/three/addons/lighting/LightProbeGridWebGL.js +846 -0
  117. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGIConeTracer.js +243 -0
  118. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGIIrradiance.js +43 -0
  119. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGINode.js +617 -0
  120. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGISceneCollector.js +793 -0
  121. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGIVolume.js +1440 -0
  122. package/Resources/WebLibraries/three/addons/lights/LightProbeGenerator.js +337 -0
  123. package/Resources/WebLibraries/three/addons/lights/RectAreaLightTexturesLib.js +127 -0
  124. package/Resources/WebLibraries/three/addons/lights/RectAreaLightUniformsLib.js +40 -0
  125. package/Resources/WebLibraries/three/addons/lights/SunLight.js +100 -0
  126. package/Resources/WebLibraries/three/addons/lights/SunLightNode.js +56 -0
  127. package/Resources/WebLibraries/three/addons/lights/SunLightShadow.js +319 -0
  128. package/Resources/WebLibraries/three/addons/lights/SunShadowNode.js +312 -0
  129. package/Resources/WebLibraries/three/addons/lines/Line2.js +56 -0
  130. package/Resources/WebLibraries/three/addons/lines/LineGeometry.js +157 -0
  131. package/Resources/WebLibraries/three/addons/lines/LineMaterial.js +742 -0
  132. package/Resources/WebLibraries/three/addons/lines/LineSegments2.js +434 -0
  133. package/Resources/WebLibraries/three/addons/lines/LineSegmentsGeometry.js +298 -0
  134. package/Resources/WebLibraries/three/addons/lines/Wireframe.js +108 -0
  135. package/Resources/WebLibraries/three/addons/lines/WireframeGeometry2.js +49 -0
  136. package/Resources/WebLibraries/three/addons/lines/webgpu/Line2.js +46 -0
  137. package/Resources/WebLibraries/three/addons/lines/webgpu/LineSegments2.js +419 -0
  138. package/Resources/WebLibraries/three/addons/lines/webgpu/Wireframe.js +86 -0
  139. package/Resources/WebLibraries/three/addons/loaders/EXRLoader.js +3411 -0
  140. package/Resources/WebLibraries/three/addons/loaders/FBXLoader.js +4660 -0
  141. package/Resources/WebLibraries/three/addons/loaders/FontLoader.js +262 -0
  142. package/Resources/WebLibraries/three/addons/loaders/GLTFLoader.js +5006 -0
  143. package/Resources/WebLibraries/three/addons/loaders/HDRLoader.js +463 -0
  144. package/Resources/WebLibraries/three/addons/loaders/MTLLoader.js +601 -0
  145. package/Resources/WebLibraries/three/addons/loaders/OBJLoader.js +961 -0
  146. package/Resources/WebLibraries/three/addons/loaders/PLYLoader.js +992 -0
  147. package/Resources/WebLibraries/three/addons/loaders/RGBELoader.js +18 -0
  148. package/Resources/WebLibraries/three/addons/loaders/STLLoader.js +423 -0
  149. package/Resources/WebLibraries/three/addons/loaders/SVGLoader.js +3297 -0
  150. package/Resources/WebLibraries/three/addons/loaders/TGALoader.js +539 -0
  151. package/Resources/WebLibraries/three/addons/loaders/UltraHDRLoader.js +757 -0
  152. package/Resources/WebLibraries/three/addons/math/Capsule.js +159 -0
  153. package/Resources/WebLibraries/three/addons/math/ColorConverter.js +62 -0
  154. package/Resources/WebLibraries/three/addons/math/ColorSpaces.js +147 -0
  155. package/Resources/WebLibraries/three/addons/math/ConvexHull.js +1695 -0
  156. package/Resources/WebLibraries/three/addons/math/ImprovedNoise.js +88 -0
  157. package/Resources/WebLibraries/three/addons/math/Lut.js +317 -0
  158. package/Resources/WebLibraries/three/addons/math/MeshSurfaceSampler.js +315 -0
  159. package/Resources/WebLibraries/three/addons/math/OBB.js +535 -0
  160. package/Resources/WebLibraries/three/addons/math/Octree.js +825 -0
  161. package/Resources/WebLibraries/three/addons/math/SimplexNoise.js +470 -0
  162. package/Resources/WebLibraries/three/addons/misc/ConvexObjectBreaker.js +539 -0
  163. package/Resources/WebLibraries/three/addons/misc/GPUComputationRenderer.js +508 -0
  164. package/Resources/WebLibraries/three/addons/misc/Gyroscope.js +78 -0
  165. package/Resources/WebLibraries/three/addons/misc/MorphAnimMesh.js +119 -0
  166. package/Resources/WebLibraries/three/addons/misc/MorphBlendMesh.js +425 -0
  167. package/Resources/WebLibraries/three/addons/misc/ProgressiveLightMap.js +370 -0
  168. package/Resources/WebLibraries/three/addons/misc/ProgressiveLightMapGPU.js +322 -0
  169. package/Resources/WebLibraries/three/addons/misc/RollerCoaster.js +661 -0
  170. package/Resources/WebLibraries/three/addons/misc/Sculptor.js +1679 -0
  171. package/Resources/WebLibraries/three/addons/misc/SculptorMesh.js +1504 -0
  172. package/Resources/WebLibraries/three/addons/misc/SculptorTools.js +1180 -0
  173. package/Resources/WebLibraries/three/addons/misc/SculptorUtils.js +345 -0
  174. package/Resources/WebLibraries/three/addons/misc/TileCreasedNormalsPlugin.js +270 -0
  175. package/Resources/WebLibraries/three/addons/misc/TubePainter.js +611 -0
  176. package/Resources/WebLibraries/three/addons/misc/Volume.js +520 -0
  177. package/Resources/WebLibraries/three/addons/misc/VolumeSlice.js +275 -0
  178. package/Resources/WebLibraries/three/addons/modifiers/CurveModifier.js +374 -0
  179. package/Resources/WebLibraries/three/addons/modifiers/CurveModifierGPU.js +256 -0
  180. package/Resources/WebLibraries/three/addons/modifiers/EdgeSplitModifier.js +299 -0
  181. package/Resources/WebLibraries/three/addons/modifiers/TessellateModifier.js +340 -0
  182. package/Resources/WebLibraries/three/addons/objects/GroundedSkybox.js +69 -0
  183. package/Resources/WebLibraries/three/addons/objects/Lensflare.js +489 -0
  184. package/Resources/WebLibraries/three/addons/objects/LensflareMesh.js +376 -0
  185. package/Resources/WebLibraries/three/addons/objects/MarchingCubes.js +1261 -0
  186. package/Resources/WebLibraries/three/addons/objects/Reflector.js +390 -0
  187. package/Resources/WebLibraries/three/addons/objects/ReflectorForSSRPass.js +393 -0
  188. package/Resources/WebLibraries/three/addons/objects/Refractor.js +389 -0
  189. package/Resources/WebLibraries/three/addons/objects/ShadowMesh.js +130 -0
  190. package/Resources/WebLibraries/three/addons/objects/Sky.js +342 -0
  191. package/Resources/WebLibraries/three/addons/objects/SkyMesh.js +403 -0
  192. package/Resources/WebLibraries/three/addons/objects/Water.js +374 -0
  193. package/Resources/WebLibraries/three/addons/objects/Water2.js +403 -0
  194. package/Resources/WebLibraries/three/addons/objects/Water2Mesh.js +199 -0
  195. package/Resources/WebLibraries/three/addons/objects/WaterMesh.js +194 -0
  196. package/Resources/WebLibraries/three/addons/postprocessing/AfterimagePass.js +187 -0
  197. package/Resources/WebLibraries/three/addons/postprocessing/BloomPass.js +274 -0
  198. package/Resources/WebLibraries/three/addons/postprocessing/BokehPass.js +218 -0
  199. package/Resources/WebLibraries/three/addons/postprocessing/ClearPass.js +97 -0
  200. package/Resources/WebLibraries/three/addons/postprocessing/CubeTexturePass.js +146 -0
  201. package/Resources/WebLibraries/three/addons/postprocessing/DotScreenPass.js +114 -0
  202. package/Resources/WebLibraries/three/addons/postprocessing/EffectComposer.js +365 -0
  203. package/Resources/WebLibraries/three/addons/postprocessing/FXAAPass.js +40 -0
  204. package/Resources/WebLibraries/three/addons/postprocessing/FilmPass.js +113 -0
  205. package/Resources/WebLibraries/three/addons/postprocessing/GTAOPass.js +735 -0
  206. package/Resources/WebLibraries/three/addons/postprocessing/GlitchPass.js +177 -0
  207. package/Resources/WebLibraries/three/addons/postprocessing/HalftonePass.js +134 -0
  208. package/Resources/WebLibraries/three/addons/postprocessing/LUTPass.js +138 -0
  209. package/Resources/WebLibraries/three/addons/postprocessing/MaskPass.js +195 -0
  210. package/Resources/WebLibraries/three/addons/postprocessing/OutlinePass.js +776 -0
  211. package/Resources/WebLibraries/three/addons/postprocessing/OutputPass.js +148 -0
  212. package/Resources/WebLibraries/three/addons/postprocessing/Pass.js +191 -0
  213. package/Resources/WebLibraries/three/addons/postprocessing/RenderPass.js +193 -0
  214. package/Resources/WebLibraries/three/addons/postprocessing/RenderPixelatedPass.js +314 -0
  215. package/Resources/WebLibraries/three/addons/postprocessing/RenderTransitionPass.js +267 -0
  216. package/Resources/WebLibraries/three/addons/postprocessing/SAOPass.js +407 -0
  217. package/Resources/WebLibraries/three/addons/postprocessing/SMAAPass.js +230 -0
  218. package/Resources/WebLibraries/three/addons/postprocessing/SSAARenderPass.js +313 -0
  219. package/Resources/WebLibraries/three/addons/postprocessing/SSAOPass.js +527 -0
  220. package/Resources/WebLibraries/three/addons/postprocessing/SSRPass.js +858 -0
  221. package/Resources/WebLibraries/three/addons/postprocessing/SavePass.js +132 -0
  222. package/Resources/WebLibraries/three/addons/postprocessing/ShaderPass.js +135 -0
  223. package/Resources/WebLibraries/three/addons/postprocessing/TAARenderPass.js +243 -0
  224. package/Resources/WebLibraries/three/addons/postprocessing/TexturePass.js +131 -0
  225. package/Resources/WebLibraries/three/addons/postprocessing/UnrealBloomPass.js +541 -0
  226. package/Resources/WebLibraries/three/addons/shaders/ACESFilmicToneMappingShader.js +96 -0
  227. package/Resources/WebLibraries/three/addons/shaders/AfterimageShader.js +63 -0
  228. package/Resources/WebLibraries/three/addons/shaders/BasicShader.js +36 -0
  229. package/Resources/WebLibraries/three/addons/shaders/BleachBypassShader.js +68 -0
  230. package/Resources/WebLibraries/three/addons/shaders/BlendShader.js +56 -0
  231. package/Resources/WebLibraries/three/addons/shaders/BokehShader.js +151 -0
  232. package/Resources/WebLibraries/three/addons/shaders/BokehShader2.js +404 -0
  233. package/Resources/WebLibraries/three/addons/shaders/BrightnessContrastShader.js +62 -0
  234. package/Resources/WebLibraries/three/addons/shaders/ColorCorrectionShader.js +59 -0
  235. package/Resources/WebLibraries/three/addons/shaders/ColorifyShader.js +57 -0
  236. package/Resources/WebLibraries/three/addons/shaders/ConvolutionShader.js +74 -0
  237. package/Resources/WebLibraries/three/addons/shaders/CopyShader.js +52 -0
  238. package/Resources/WebLibraries/three/addons/shaders/DOFMipMapShader.js +63 -0
  239. package/Resources/WebLibraries/three/addons/shaders/DepthLimitedBlurShader.js +183 -0
  240. package/Resources/WebLibraries/three/addons/shaders/DigitalGlitch.js +104 -0
  241. package/Resources/WebLibraries/three/addons/shaders/DotScreenShader.js +75 -0
  242. package/Resources/WebLibraries/three/addons/shaders/ExposureShader.js +51 -0
  243. package/Resources/WebLibraries/three/addons/shaders/FXAAShader.js +298 -0
  244. package/Resources/WebLibraries/three/addons/shaders/FilmShader.js +73 -0
  245. package/Resources/WebLibraries/three/addons/shaders/FocusShader.js +94 -0
  246. package/Resources/WebLibraries/three/addons/shaders/FreiChenShader.js +103 -0
  247. package/Resources/WebLibraries/three/addons/shaders/GTAOShader.js +437 -0
  248. package/Resources/WebLibraries/three/addons/shaders/GammaCorrectionShader.js +52 -0
  249. package/Resources/WebLibraries/three/addons/shaders/HalftoneShader.js +332 -0
  250. package/Resources/WebLibraries/three/addons/shaders/HorizontalBlurShader.js +68 -0
  251. package/Resources/WebLibraries/three/addons/shaders/HorizontalTiltShiftShader.js +70 -0
  252. package/Resources/WebLibraries/three/addons/shaders/HueSaturationShader.js +74 -0
  253. package/Resources/WebLibraries/three/addons/shaders/KaleidoShader.js +65 -0
  254. package/Resources/WebLibraries/three/addons/shaders/LuminosityHighPassShader.js +68 -0
  255. package/Resources/WebLibraries/three/addons/shaders/LuminosityShader.js +54 -0
  256. package/Resources/WebLibraries/three/addons/shaders/MirrorShader.js +62 -0
  257. package/Resources/WebLibraries/three/addons/shaders/NormalMapShader.js +60 -0
  258. package/Resources/WebLibraries/three/addons/shaders/OutputShader.js +103 -0
  259. package/Resources/WebLibraries/three/addons/shaders/PoissonDenoiseShader.js +230 -0
  260. package/Resources/WebLibraries/three/addons/shaders/RGBShiftShader.js +61 -0
  261. package/Resources/WebLibraries/three/addons/shaders/SAOShader.js +201 -0
  262. package/Resources/WebLibraries/three/addons/shaders/SMAAShader.js +489 -0
  263. package/Resources/WebLibraries/three/addons/shaders/SSAOShader.js +331 -0
  264. package/Resources/WebLibraries/three/addons/shaders/SSRShader.js +396 -0
  265. package/Resources/WebLibraries/three/addons/shaders/SepiaShader.js +57 -0
  266. package/Resources/WebLibraries/three/addons/shaders/SobelOperatorShader.js +98 -0
  267. package/Resources/WebLibraries/three/addons/shaders/SubsurfaceScatteringShader.js +95 -0
  268. package/Resources/WebLibraries/three/addons/shaders/TechnicolorShader.js +51 -0
  269. package/Resources/WebLibraries/three/addons/shaders/ToonShader.js +349 -0
  270. package/Resources/WebLibraries/three/addons/shaders/TriangleBlurShader.js +79 -0
  271. package/Resources/WebLibraries/three/addons/shaders/UnpackDepthRGBAShader.js +60 -0
  272. package/Resources/WebLibraries/three/addons/shaders/VelocityShader.js +137 -0
  273. package/Resources/WebLibraries/three/addons/shaders/VerticalBlurShader.js +66 -0
  274. package/Resources/WebLibraries/three/addons/shaders/VerticalTiltShiftShader.js +70 -0
  275. package/Resources/WebLibraries/three/addons/shaders/VignetteShader.js +56 -0
  276. package/Resources/WebLibraries/three/addons/shaders/VolumeShader.js +285 -0
  277. package/Resources/WebLibraries/three/addons/shaders/WaterRefractionShader.js +106 -0
  278. package/Resources/WebLibraries/three/addons/textures/FlakesTexture.js +54 -0
  279. package/Resources/WebLibraries/three/addons/tsl/WebGLNodesHandler.js +607 -0
  280. package/Resources/WebLibraries/three/addons/tsl/display/AfterImageNode.js +256 -0
  281. package/Resources/WebLibraries/three/addons/tsl/display/AnaglyphPassNode.js +550 -0
  282. package/Resources/WebLibraries/three/addons/tsl/display/BilateralBlurNode.js +377 -0
  283. package/Resources/WebLibraries/three/addons/tsl/display/BleachBypass.js +33 -0
  284. package/Resources/WebLibraries/three/addons/tsl/display/BloomNode.js +599 -0
  285. package/Resources/WebLibraries/three/addons/tsl/display/CRT.js +150 -0
  286. package/Resources/WebLibraries/three/addons/tsl/display/ChromaticAberrationNode.js +163 -0
  287. package/Resources/WebLibraries/three/addons/tsl/display/DenoiseNode.js +354 -0
  288. package/Resources/WebLibraries/three/addons/tsl/display/DepthOfFieldNode.js +572 -0
  289. package/Resources/WebLibraries/three/addons/tsl/display/DotScreenNode.js +104 -0
  290. package/Resources/WebLibraries/three/addons/tsl/display/FSR1Node.js +481 -0
  291. package/Resources/WebLibraries/three/addons/tsl/display/FXAANode.js +357 -0
  292. package/Resources/WebLibraries/three/addons/tsl/display/FilmNode.js +101 -0
  293. package/Resources/WebLibraries/three/addons/tsl/display/GTAONode.js +727 -0
  294. package/Resources/WebLibraries/three/addons/tsl/display/GaussianBlurNode.js +412 -0
  295. package/Resources/WebLibraries/three/addons/tsl/display/GodraysNode.js +604 -0
  296. package/Resources/WebLibraries/three/addons/tsl/display/ImportanceSampledEnvironment.js +564 -0
  297. package/Resources/WebLibraries/three/addons/tsl/display/LensflareNode.js +282 -0
  298. package/Resources/WebLibraries/three/addons/tsl/display/Lut3DNode.js +109 -0
  299. package/Resources/WebLibraries/three/addons/tsl/display/MotionBlur.js +33 -0
  300. package/Resources/WebLibraries/three/addons/tsl/display/OITPassNode.js +341 -0
  301. package/Resources/WebLibraries/three/addons/tsl/display/OutlineNode.js +916 -0
  302. package/Resources/WebLibraries/three/addons/tsl/display/ParallaxBarrierPassNode.js +90 -0
  303. package/Resources/WebLibraries/three/addons/tsl/display/PixelationPassNode.js +227 -0
  304. package/Resources/WebLibraries/three/addons/tsl/display/RGBShiftNode.js +96 -0
  305. package/Resources/WebLibraries/three/addons/tsl/display/RecurrentDenoiseNode.js +812 -0
  306. package/Resources/WebLibraries/three/addons/tsl/display/RetroPassNode.js +263 -0
  307. package/Resources/WebLibraries/three/addons/tsl/display/SMAANode.js +729 -0
  308. package/Resources/WebLibraries/three/addons/tsl/display/SSAAPassNode.js +344 -0
  309. package/Resources/WebLibraries/three/addons/tsl/display/SSAONode.js +422 -0
  310. package/Resources/WebLibraries/three/addons/tsl/display/SSGINode.js +698 -0
  311. package/Resources/WebLibraries/three/addons/tsl/display/SSRNode.js +1430 -0
  312. package/Resources/WebLibraries/three/addons/tsl/display/SSSNode.js +479 -0
  313. package/Resources/WebLibraries/three/addons/tsl/display/Sepia.js +24 -0
  314. package/Resources/WebLibraries/three/addons/tsl/display/Shape.js +29 -0
  315. package/Resources/WebLibraries/three/addons/tsl/display/SharpenNode.js +284 -0
  316. package/Resources/WebLibraries/three/addons/tsl/display/SobelOperatorNode.js +168 -0
  317. package/Resources/WebLibraries/three/addons/tsl/display/StereoCompositePassNode.js +190 -0
  318. package/Resources/WebLibraries/three/addons/tsl/display/StereoPassNode.js +117 -0
  319. package/Resources/WebLibraries/three/addons/tsl/display/TAAUNode.js +700 -0
  320. package/Resources/WebLibraries/three/addons/tsl/display/TRAANode.js +609 -0
  321. package/Resources/WebLibraries/three/addons/tsl/display/TemporalReprojectNode.js +1024 -0
  322. package/Resources/WebLibraries/three/addons/tsl/display/TransitionNode.js +141 -0
  323. package/Resources/WebLibraries/three/addons/tsl/display/boxBlur.js +65 -0
  324. package/Resources/WebLibraries/three/addons/tsl/display/depthAwareBlend.js +80 -0
  325. package/Resources/WebLibraries/three/addons/tsl/display/depthAwareBlur.js +63 -0
  326. package/Resources/WebLibraries/three/addons/tsl/display/hashBlur.js +55 -0
  327. package/Resources/WebLibraries/three/addons/tsl/display/lensDirt.js +30 -0
  328. package/Resources/WebLibraries/three/addons/tsl/display/radialBlur.js +68 -0
  329. package/Resources/WebLibraries/three/addons/tsl/lighting/ClusteredLightsNode.js +994 -0
  330. package/Resources/WebLibraries/three/addons/tsl/lighting/DynamicLightsNode.js +201 -0
  331. package/Resources/WebLibraries/three/addons/tsl/lighting/LightProbeGridNode.js +183 -0
  332. package/Resources/WebLibraries/three/addons/tsl/lighting/data/AmbientLightDataNode.js +67 -0
  333. package/Resources/WebLibraries/three/addons/tsl/lighting/data/DirectionalLightDataNode.js +117 -0
  334. package/Resources/WebLibraries/three/addons/tsl/lighting/data/HemisphereLightDataNode.js +105 -0
  335. package/Resources/WebLibraries/three/addons/tsl/lighting/data/PointLightDataNode.js +140 -0
  336. package/Resources/WebLibraries/three/addons/tsl/lighting/data/SpotLightDataNode.js +167 -0
  337. package/Resources/WebLibraries/three/addons/tsl/math/Bayer.js +84 -0
  338. package/Resources/WebLibraries/three/addons/tsl/math/curlNoise.js +107 -0
  339. package/Resources/WebLibraries/three/addons/tsl/math/voronoiNoise.js +112 -0
  340. package/Resources/WebLibraries/three/addons/tsl/shadows/TileShadowNode.js +542 -0
  341. package/Resources/WebLibraries/three/addons/tsl/shadows/TileShadowNodeHelper.js +212 -0
  342. package/Resources/WebLibraries/three/addons/tsl/utils/GroundedSkybox.js +62 -0
  343. package/Resources/WebLibraries/three/addons/tsl/utils/RNoise.js +51 -0
  344. package/Resources/WebLibraries/three/addons/tsl/utils/Raymarching.js +70 -0
  345. package/Resources/WebLibraries/three/addons/tsl/utils/SoftParticles.js +53 -0
  346. package/Resources/WebLibraries/three/addons/tsl/utils/SpecularHelpers.js +302 -0
  347. package/Resources/WebLibraries/three/addons/tsl/utils/TAAUtils.js +184 -0
  348. package/Resources/WebLibraries/three/addons/utils/BufferGeometryUtils.js +1523 -0
  349. package/Resources/WebLibraries/three/addons/utils/CameraUtils.js +82 -0
  350. package/Resources/WebLibraries/three/addons/utils/ColorUtils.js +76 -0
  351. package/Resources/WebLibraries/three/addons/utils/GaussianSplatUtils.js +229 -0
  352. package/Resources/WebLibraries/three/addons/utils/GeometryCompressionUtils.js +547 -0
  353. package/Resources/WebLibraries/three/addons/utils/GeometryUtils.js +226 -0
  354. package/Resources/WebLibraries/three/addons/utils/LDrawUtils.js +211 -0
  355. package/Resources/WebLibraries/three/addons/utils/SceneOptimizer.js +459 -0
  356. package/Resources/WebLibraries/three/addons/utils/SceneUtils.js +363 -0
  357. package/Resources/WebLibraries/three/addons/utils/ShadowMapViewer.js +244 -0
  358. package/Resources/WebLibraries/three/addons/utils/ShadowMapViewerGPU.js +233 -0
  359. package/Resources/WebLibraries/three/addons/utils/SkeletonUtils.js +496 -0
  360. package/Resources/WebLibraries/three/addons/utils/SortUtils.js +175 -0
  361. package/Resources/WebLibraries/three/addons/utils/UVsDebug.js +173 -0
  362. package/Resources/WebLibraries/three/addons/utils/WebGLTextureUtils.js +115 -0
  363. package/Resources/WebLibraries/three/addons/utils/WebGPUTextureUtils.js +81 -0
  364. package/Resources/WebLibraries/three/addons/utils/WorkerPool.js +167 -0
  365. package/Resources/WebLibraries/three/addons/utils/unwrapUVs.js +865 -0
  366. package/Resources/WebLibraries/three/three.core.js +61162 -0
  367. package/Resources/WebLibraries/three/three.module.js +19537 -0
  368. package/Resources/WebLibraries/three/three.tsl.js +41903 -0
  369. package/Resources/WebLibraries/three/three.webgpu.js +53714 -0
  370. package/Resources/share-rules.json +64 -0
  371. package/Resources/skills/2d-game/SKILL.md +305 -0
  372. package/Resources/skills/3d-game/SKILL.md +274 -0
  373. package/Resources/skills/accounts/SKILL.md +41 -0
  374. package/Resources/skills/android-design/SKILL.md +159 -0
  375. package/Resources/skills/app-ai/SKILL.md +154 -0
  376. package/Resources/skills/app-intents/SKILL.md +31 -0
  377. package/Resources/skills/app-kinds/SKILL.md +122 -0
  378. package/Resources/skills/apple-watch/SKILL.md +43 -0
  379. package/Resources/skills/assets/SKILL.md +183 -0
  380. package/Resources/skills/building-blocks/SKILL.md +97 -0
  381. package/Resources/skills/device-control/SKILL.md +56 -0
  382. package/Resources/skills/device-integrations/SKILL.md +278 -0
  383. package/Resources/skills/finder-files/SKILL.md +19 -0
  384. package/Resources/skills/game/SKILL.md +416 -0
  385. package/Resources/skills/game-3d/SKILL.md +12 -0
  386. package/Resources/skills/game-art/SKILL.md +11 -0
  387. package/Resources/skills/game-feel/SKILL.md +13 -0
  388. package/Resources/skills/game-levels/SKILL.md +12 -0
  389. package/Resources/skills/game-live/SKILL.md +12 -0
  390. package/Resources/skills/game-physics/SKILL.md +13 -0
  391. package/Resources/skills/game-playtest/SKILL.md +26 -0
  392. package/Resources/skills/game-ui/SKILL.md +278 -0
  393. package/Resources/skills/github-projects/SKILL.md +62 -0
  394. package/Resources/skills/icloud-sync/SKILL.md +30 -0
  395. package/Resources/skills/iphone-hardware/SKILL.md +57 -0
  396. package/Resources/skills/iphone-widgets/SKILL.md +53 -0
  397. package/Resources/skills/lg-developer-mode/SKILL.md +152 -0
  398. package/Resources/skills/mac-widgets/SKILL.md +60 -0
  399. package/Resources/skills/maps/SKILL.md +8 -0
  400. package/Resources/skills/menu-bar/SKILL.md +36 -0
  401. package/Resources/skills/more-apps/SKILL.md +53 -0
  402. package/Resources/skills/phone-controllers/SKILL.md +79 -0
  403. package/Resources/skills/phone-pages/SKILL.md +173 -0
  404. package/Resources/skills/roku-developer-mode/SKILL.md +106 -0
  405. package/Resources/skills/scene-3d/SKILL.md +27 -0
  406. package/Resources/skills/scripting/SKILL.md +17 -0
  407. package/Resources/skills/share-extension/SKILL.md +22 -0
  408. package/Resources/skills/tv-design/SKILL.md +72 -0
  409. package/Resources/skills/web-app/SKILL.md +170 -0
  410. package/Resources/skills/web-game/SKILL.md +95 -0
  411. package/Resources/skills/web-or-native/SKILL.md +108 -0
  412. package/Resources/skills/wish-links/SKILL.md +156 -0
  413. package/THIRD_PARTY_NOTICES.md +170 -0
  414. package/cli/ai.mjs +237 -0
  415. package/cli/android.mjs +941 -0
  416. package/cli/app-ai.mjs +473 -0
  417. package/cli/browser.mjs +284 -0
  418. package/cli/calls.mjs +594 -0
  419. package/cli/dev.mjs +820 -0
  420. package/cli/devices.mjs +984 -0
  421. package/cli/lamp.mjs +1326 -0
  422. package/cli/lampapp.mjs +332 -0
  423. package/cli/lamps/android-host/LampPageGateway.kt +345 -0
  424. package/cli/lamps/android-host/app/build.gradle.kts +40 -0
  425. package/cli/lamps/android-host/build.gradle.kts +4 -0
  426. package/cli/lamps/android-host/game/AndroidManifest.xml +33 -0
  427. package/cli/lamps/android-host/game/MainActivity.kt +173 -0
  428. package/cli/lamps/android-host/gradle/libs.versions.toml +39 -0
  429. package/cli/lamps/android-host/gradle.properties +8 -0
  430. package/cli/lamps/android-host/page/AndroidManifest.xml +35 -0
  431. package/cli/lamps/android-host/page/MainActivity.kt +193 -0
  432. package/cli/lamps/android-host/settings.gradle.kts +30 -0
  433. package/cli/lamps/android-host/tools.json +43 -0
  434. package/cli/lamps/lamp-controllers.js +2 -0
  435. package/cli/lamps/lamp-for-games.js +6922 -0
  436. package/cli/lamps/lamp.js +7082 -0
  437. package/cli/lamps/mac-starter/.lamp/meta.json +1 -0
  438. package/cli/lamps/mac-starter/APP.md +12 -0
  439. package/cli/lamps/mac-starter/Package.swift +8 -0
  440. package/cli/lamps/mac-starter/Sources/App.swift +11 -0
  441. package/cli/lamps/mac-starter/Sources/ContentView.swift +17 -0
  442. package/cli/lamps/mac-starter/Sources/LampSupport.swift +18215 -0
  443. package/cli/lamps/mac-starter/build.sh +336 -0
  444. package/cli/lamps/mac-starter/gitignore +3 -0
  445. package/cli/lamps/mac-starter/lamp-starter.json +6 -0
  446. package/cli/lamps/web-starter/APP.md +8 -0
  447. package/cli/lamps/web-starter/app.js +1 -0
  448. package/cli/lamps/web-starter/index.html +17 -0
  449. package/cli/lamps/web-starter/lamp-starter.json +5 -0
  450. package/cli/lamps/web-starter/lamp.js +7082 -0
  451. package/cli/lamps/web-starter/style.css +25 -0
  452. package/cli/link.mjs +202 -0
  453. package/cli/local-ai.mjs +193 -0
  454. package/cli/mac.mjs +621 -0
  455. package/cli/mdns.mjs +205 -0
  456. package/cli/msix.mjs +413 -0
  457. package/cli/network.mjs +209 -0
  458. package/cli/openrouter.mjs +133 -0
  459. package/cli/outside.mjs +203 -0
  460. package/cli/page.js +317 -0
  461. package/cli/place.mjs +298 -0
  462. package/cli/png.mjs +184 -0
  463. package/cli/share.mjs +270 -0
  464. package/cli/skill/SKILL.md +280 -0
  465. package/cli/skills.mjs +71 -0
  466. package/cli/state.mjs +176 -0
  467. package/cli/update.mjs +162 -0
  468. package/package.json +20 -4
  469. package/site/lib/quota.js +59 -0
  470. package/site/lib/shared-wishes.js +1727 -0
@@ -0,0 +1,280 @@
1
+ ---
2
+ name: lamp
3
+ description: Make, run, see and try an app with lamp's command line - a web app, a web game, or a Mac app Lamp made in Swift. Use when the person asks for a new web game, or when working in a folder made with Lamp (a page beside lamp-game.js or in Web/, or Package.swift with build.sh and Sources/LampSupport.swift) or in a plain site's folder and they ask to change the app, to see it, or to check that a change works. Every saved change goes into the open app, and a game keeps the player's place.
4
+ ---
5
+
6
+ # Working on an app with lamp
7
+
8
+ `{{lamp}}` runs the page in the app's folder and puts each change into it while it's open. Save a file and the change
9
+ goes in. Never build, restart or reload anything for a change.
10
+
11
+ Run the commands from the app's folder, or give the folder after the command (`{{lamp}} look path/to/app`).
12
+
13
+ Most of this is about an app that is a web page: a web game, a web app, a plain site. An app Lamp made that way has
14
+ the page in `Web/`, beside the Swift of the app around it, which stays as it is. An app whose own screens are Swift
15
+ is a Mac app: "A Mac app" below says what's different for one.
16
+
17
+ ## A new game
18
+
19
+ `{{lamp}} new path/to/folder --name "Its Name"` makes a new web game's folder from Lamp's starting files: the game
20
+ runtime (`lamp-game.js`), three.js and Phaser, `APP.md`, and a page that shows a card until the game replaces it. The
21
+ page is at the top of the folder: what Lamp's skills call `Web/` is the folder itself.
22
+
23
+ Before writing, read Lamp's `web-game` and `game-feel` skills, which are for every game, and `game-playtest` when
24
+ you're asked to play it; "Lamp's skills" below says what in them is Lamp's app's doing. The card's `game.js`,
25
+ `world.js` and `making.js` are yours to replace, as `web-game` says.
26
+
27
+ The card is a small game of its own, and the runtime keeps what it registered (a state called `play`, a camera)
28
+ through a change, as it would the player's place. So write the whole game before the first look, and make that look
29
+ with `--reopen` (`{{lamp}} look --reopen`): the game then opens from its beginning, not from the card's. If you
30
+ looked earlier, `--reopen` puts it right.
31
+
32
+ ## A new web app
33
+
34
+ `{{lamp}} new path/to/folder --web --name "Its Name"` makes a new web app's page from Lamp's starting files:
35
+ `index.html`, `style.css` and `app.js`, which are yours to write, `APP.md`, and `lamp.js`, Lamp's building blocks for
36
+ a page (saved data with `LampStore`, the app's files and more). Read Lamp's `web-app` skill before writing it, and
37
+ the comments in `lamp.js` for how each block is used; never edit `lamp.js`. Its AI (`LampAI`: ask, act, decide) is
38
+ answered by lamp itself on this Mac, with the person's own Claude Code or Codex (or OpenRouter, with their key in `OPENROUTER_API_KEY`), in every page lamp runs here (`dev`,
39
+ `open`, `look`, `use`); pictures and hearing need Lamp's app. Shared on lamp.dev, it's answered on the computer the page is played on while Lamp is open there or `{{lamp}} ai` runs there in a terminal, once the person allows that page. Never put a key or a model provider's address in the page. A page that wants none of Lamp's needs no starting files: write its
40
+ `index.html` in an empty folder.
41
+
42
+ ## A Mac app
43
+
44
+ A folder with `Package.swift`, `build.sh` and `Sources/LampSupport.swift` and no page is a Mac app Lamp made in
45
+ Swift. `{{lamp}} new path/to/folder --mac --name "Its Name"` makes a new one: Lamp's building blocks, and a card it
46
+ shows until its code in `Sources/` is written. The same commands work on it, with these differences:
47
+
48
+ - **Lamp's building blocks** are what the app is made with: saved data, AI, windows, the menu bar and the rest.
49
+ `{{lamp}} blocks` lists them with what each is for, and `{{lamp}} blocks LampStore` says how one is used: read the
50
+ ones the app needs before writing it. Lamp's `building-blocks` and `app-kinds` skills say which to reach for and
51
+ how such an app is laid out; where a skill points to rules of Lamp's own that aren't here (a base design), use
52
+ your judgment.
53
+ - **A change is a build.** Each save to the app's code builds it again, a few seconds for a small change, and opens
54
+ it again: what was typed or open in it is gone, so change first and try after. `look` waits for the build.
55
+ - **`look`** answers pictures of the app's windows (taken by the app itself, so nothing is asked of the person),
56
+ what it printed, and when it didn't build, the compiler's errors with their file and line: the app is then as it
57
+ was before the change. It answers the screen as text too once the app has been in front with the Mac unlocked;
58
+ without it, aim by the picture, whose points are the points to click. `look --reopen` quits the app and opens it
59
+ again first, as `{{lamp}} reload` does.
60
+ - **`use`** takes `click` (a point of the picture, or a name or id from the screen as text: `{{lamp}} use click "Add"`),
61
+ `type`, `key` (`return`, `escape`, `cmd+a`…), `drag`, `scroll` and `wait`. It brings the app to the front. Only
62
+ when asked to try it.
63
+ - **What you add while trying it is the app's real saved data**, kept under the app's own name in the person's
64
+ Application Support: take it out again, or tell them it's there.
65
+ - **The app stays open** when you finish, as the person's to use. `{{lamp}} stop` quits it, when they only wanted it
66
+ checked.
67
+ - **Lamp's own files** are `Sources/LampSupport.swift`, `build.sh` and `Package.swift`: never edit any of them.
68
+ - **A change into the open app, without reopening it**, is Lamp's app's: when the person has Lamp open and wants that,
69
+ `{{lamp}} open --in-lamp` gives the app to it (Lamp shows them its review the first time). From then on `look`, `dev`
70
+ and `reload` say how each change went in (live, held for their Reload, reopened, not built), and the person tries it
71
+ there, and `use` tries the app Lamp has open, in plain sight. `{{lamp}} open --here` has lamp run its own copy again.
72
+ - **Not here:** the app's AI (`LampAI`), and a link to one on lamp.dev (its Lamp app file is here: see "A Lamp app
73
+ file"). Those
74
+ are Lamp's app's: say so rather than working around it. What the app keeps secret (`LampSecrets`) is kept for it.
75
+
76
+ ## A game that's already there
77
+
78
+ A web game from somewhere else runs as it is: every command here works on it, each change opens its page again from
79
+ the start, and `look` can't know when it has finished loading. Putting it on Lamp's runtime is what lets it take
80
+ changes while it's played and say when it's really playing. `{{lamp}} init` puts Lamp's own files beside its page and
81
+ changes none of the page's; taking the runtime up in the game's code is the work. It goes in steps, each worth having
82
+ by itself:
83
+
84
+ 1. **The runtime runs the game's loop** (`game()` in place of the game's own), with its renderer kept and the
85
+ player's place given and taken back. A change then runs the game's code again in place, where before it opened
86
+ the page again. A page laid out at the window's size that reads its own keys and touches says so to `game()`:
87
+ the options are in `lamp-game.js`'s comments on the frame.
88
+ 2. **The modules that get tuned accept their changes**, and those go in live.
89
+ 3. **What's slow to build is kept**, so running the code again doesn't build it again.
90
+
91
+ Lamp's `game-live` skill says how each is done (its "A game from before this, or one brought in" is step 1), and
92
+ `lamp-game.js`'s comments are the whole interface: read those, not `web-game`, which is for a new game. A game
93
+ brought in reads its own input until its code reads the runtime's, so try it with keys, not Lamp's controller.
94
+
95
+ Where Lamp's `github-projects` skill has Lamp's app keep the project's credit and licenses (`lampify`), nothing does
96
+ here: keep its license file, its copyright headers and its author's credit on screen yourself.
97
+
98
+ ## The loop
99
+
100
+ 1. **Show the person the app** once, when you start, unless they don't want to watch: `{{lamp}} open`. It opens a
101
+ window they can use and play in while you work, and returns at once.
102
+ 2. **Change the files.** First say what you're changing, in a few words of theirs: `{{lamp}} changing "Rain on the
103
+ roads"`. Do it before every change, however small: the app shows it on the card it puts up as the change goes in,
104
+ and without it the card says only that it's updating. It stands until you say something new.
105
+ 3. **Look**: `{{lamp}} look`. It waits for the change to go in, then answers how it went, a picture of the page (a
106
+ file: read it; the last forty are kept), the screen as text, and the errors and the log since your last look. Look
107
+ after every change, and read the errors and the picture before saying it works. `{{lamp}} look --reopen` opens the
108
+ page again from its beginning first, a game with its saves kept: what someone opening it sees. `--size 900x600`
109
+ looks at it as a window of that size shows it, for a layout that has to hold at any shape (with no window open).
110
+ When the answer says lamp found no Chrome, Edge, Brave or Chromium, there's no picture and `use` can't play the
111
+ page: tell the person, since only they can install one.
112
+
113
+ Nothing has to be running first. With no window open, `look` runs the app itself in a copy of the page nobody sees,
114
+ opened from the files as they are, so the first look has no changes to report. The copy goes on running between
115
+ commands, as a window would: what you clicked and typed is still there, and a game's clock doesn't wait for you. It
116
+ closes by itself ten minutes after you last used it: there's nothing to stop when you finish.
117
+
118
+ ## Trying it
119
+
120
+ Only when the person asks you to try, play or test the app: a request to change it is made and looked at, not played.
121
+
122
+ - `{{lamp}} use click "Add"` clicks a control by its name in the screen as text, and `{{lamp}} use click 640 400` a
123
+ point of the picture, for what has no name there (a canvas, a drawing). The answer names what the click landed on.
124
+ - `{{lamp}} use type hello` types into whatever has the keyboard: click a field first.
125
+ - `{{lamp}} use key w 2` holds a key for two seconds (a letter, a digit, `space`, `enter`, `escape`, `up`, `left`…),
126
+ and `w+d` holds two at once.
127
+ - `{{lamp}} use drag 400 300 700 300` presses at one point, moves to the other and lets go.
128
+ - `{{lamp}} use scroll 600` scrolls down, and up with a negative number. A look shows only what's in the window.
129
+ - `{{lamp}} use wait 3` waits, for something that takes time: thirty seconds at most, so wait again for longer.
130
+
131
+ Several moves go in one command with `then` between them, one after another with nothing in between and one look at
132
+ the end: `{{lamp}} use click 640 400 then key w 3 then key w+d 2`. Play anything with a clock that way, a whole
133
+ stretch of it to a command, and end the stretch on the game's pause when it has one (`… then button menu`): the game
134
+ runs on while you read a picture. Where a canvas is drawn at another size than it's shown, the screen as text says
135
+ how a point of the game is found in the picture.
136
+
137
+ A game on Lamp's runtime is played with Lamp's own controller, as Lamp's game skills say (`use_app`'s `stick` and
138
+ `button`):
139
+
140
+ - `{{lamp}} use stick left 1 0 2` holds the left stick to the right for two seconds: `left` or `right`, then x and y
141
+ from -1 to 1, right and up being 1. A button named after the seconds is held with it (`… 2 a`).
142
+ - `{{lamp}} use button a` presses a button, `a 1.5` holds it, and `a+rt` holds two: `a`, `b`, `x`, `y`, `lb`, `rb`,
143
+ the triggers `lt` and `rt`, `menu`, `view`, `up`, `down`, `left`, `right`.
144
+
145
+ It's the first player's controller, from wherever the game is. It isn't a controller plugged in, so the game's
146
+ prompts go on naming keys. If the person plays meanwhile they have it back at once and the answer says so: the game
147
+ is theirs until they ask again. A key works in a game here too.
148
+
149
+ Each answers with a look. With the window open it happens in the person's own window, where they see it.
150
+
151
+ ## How a change went in
152
+
153
+ `look` says one of these for each change since the last look:
154
+
155
+ - **live**: swapped in while the page ran. Nothing was lost.
156
+ - **reran**: the game's code ran again, with the player where they were. In a small game that takes a moment, and
157
+ is as good as live.
158
+ - **reopened**: the page opened again. A game opens from the player's place. A plain page always takes a change this
159
+ way and starts over: what was typed or counted in it is gone, so change first and try after.
160
+ - **held**: the change waits, and the page shows the person a Reload to apply button. Either it waits for a pause in
161
+ the game (the end of a round, a menu), and goes in by itself then: a later look says so. Or for that button, because
162
+ the page must open again for it: `{{lamp}} reload` presses it, so with a window open ask the person first.
163
+
164
+ The reason given after one names the file that changed, where an `accept()` would have taken the change, and the
165
+ module it's loaded through. A game that takes changes live is written for it. When a change won't go in, needs Reload
166
+ or loses the player's place, read Lamp's `game-live` skill before working around it.
167
+
168
+ ## A Lamp app file
169
+
170
+ A folder with `lamp-app.json` at its top (or in `.lamp-wish/`) is an app in Lamp's format, from GitHub or a shared file:
171
+ every command here works on a web app, a game, a screen or a Mac app in one, and says so for a kind it doesn't run.
172
+
173
+ - `{{lamp}} unpack Name.lampapp` unpacks a Lamp app file (what Lamp's Share… makes) into a new folder beside it, with
174
+ Lamp's own files put in, and says how to see it.
175
+ - `{{lamp}} export` makes the app's Lamp app file beside its folder, for the person to send or open in Lamp: only when
176
+ they ask. It's refused when something in the app is shaped like a key, or a license its credits name is gone; when
177
+ it uses work that came with no license, ask the person before `--anyway`.
178
+
179
+ ## Sharing it
180
+
181
+ Only when the person asks: a link is public, and anyone who has it can play the page.
182
+
183
+ - Start with `{{lamp}} share --preview`: it says what would go and sends nothing. Show the person, and share only once they
184
+ say so.
185
+ - **A web app or game of Lamp's own** (its folder is in Lamp's) is shared here like any other page, whether Lamp is open
186
+ or not, to the link Lamp already has for it, and `ideas` and `unshare` work on that link too. Run `{{lamp}} share` with
187
+ no words of your own (it keeps the link's), and give `--line`, `--by` or `--asks "a|b"` only for what the person
188
+ wants changed.
189
+ - **Any other app of Lamp's** (a Mac or iPhone app, a wish of several; the preview says it's going through Lamp) is
190
+ shared by Lamp, which must be open, filled as its Share Link card fills itself: its words, the questions and what's new
191
+ Lamp writes, its file, its GitHub release. Give `--notes "What's new|And more"` and the rest only for what the person
192
+ wants changed. Its ideas and taking it down are on Lamp's Share Link card.
193
+ - **Any other page:** `{{lamp}} share --words "What it is, in a sentence or a few"` puts it on lamp.dev and answers its
194
+ link. `--line` is a line under its name, `--asks "Found a bug?|What's missing?"` what the box under the page asks
195
+ people, and `--by "Their Name"` who it's by, when they want another name than the one it goes out with (the name they last
196
+ gave, or Lamp's, or their name on this computer, which the share says). A link goes under the person's username on
197
+ lamp.dev (`lamp.dev/<username>/<app>`) once they have one: the first time you share, ask them which username they want
198
+ and their email, and run `{{lamp}} account <username> --email <theirs>`; they confirm it from the email, and the link
199
+ moves there at its next share. `{{lamp}} account` says which they're signed in as. A page that's logging errors
200
+ isn't shared until they're put right. Again, after changes, it sends the page as it is now to the same link, with the
201
+ same words unless you give new ones.
202
+ - `{{lamp}} ideas` lists what people playing it have sent, each with the address of a picture of the app as they saw
203
+ it when they kept one in: look at it before building the idea. Once one is in the game and the game shared again,
204
+ `{{lamp}} ideas in <number>` says so, and whoever asked to hear is written to; `{{lamp}} ideas dismiss <number>` lets
205
+ one go. Words after the number are a note to whoever sent it, shown on the link's page and put in that email: write
206
+ one only when the person asks you to answer them, in their words. Senders can answer by email: `{{lamp}} ideas` shows
207
+ what's been said under each idea, and those they've answered; `{{lamp}} ideas reply <number> <words>` answers again,
208
+ and `{{lamp}} ideas done <number>` leaves one without a word. `{{lamp}} ideas --earlier` lists those seen to. `{{lamp}} ideas email <address>` sends new ideas and replies to the
209
+ person's own address too, once they confirm it from the email it sends (`off` stops them): only with an address
210
+ they gave you.
211
+ - `{{lamp}} unshare` takes the link down.
212
+
213
+ Tell the person the link, and that it's public.
214
+
215
+ ## On the person's Xbox
216
+
217
+ A page goes on an Xbox in Developer Mode, in Lamp's own host for the console's browser: the same files, played with
218
+ the console's controller. Only when the person asks for it there, and only on a device they set up.
219
+
220
+ - `{{lamp}} devices` lists the devices set up with lamp and those found on the network. One only found may not be
221
+ theirs: never put anything on it.
222
+ - Setting one up asks for the console's Device Portal password, which only the person types. Ask them to run
223
+ `{{lamp}} devices add` in a terminal themselves; never ask for the password, and never type one.
224
+ - `{{lamp}} open --on xbox` packages the page as it is now, installs it and opens it on the console, in place of the
225
+ copy that was there. A change isn't live there: put the page on again once it works on this computer.
226
+ - `{{lamp}} look --on xbox` is the console's screen as a picture, whether the app is open there, and what it logged
227
+ there. A game on Lamp's runtime logs how many frames a second it gets: that, never this computer's, says how it
228
+ runs on the console.
229
+ - You can't press the controller there. Try the game in its window here (`stick`, `button`), where it's the same
230
+ code, and tell the person what's left for them to try with the controller in their hands.
231
+ - `{{lamp}} stop --on xbox` ends it, and `{{lamp}} remove --on xbox` takes it off the console.
232
+
233
+ ## On Android
234
+
235
+ A page goes on Android in Lamp's own Android app around it: the same files, on a phone, a tablet or a TV. It needs a
236
+ Mac with Android's tools, which `{{lamp}} devices` says are there or not. If they aren't, ask the person to run
237
+ `{{lamp}} devices add android` in a terminal themselves: it downloads Google's tools and accepts Google's terms for
238
+ them, which is theirs to do.
239
+
240
+ - `{{lamp}} open --on android` builds the app and opens it in lamp's Android emulator, a phone in a window on the Mac;
241
+ `--on android-tv` is its TV emulator. Use these when the person asks to see it on Android.
242
+ - For a check of your own, add `--hidden`: the emulator starts with no window and no sound, and
243
+ `{{lamp}} stop --on android` closes it when you're done. Don't leave one running.
244
+ - A phone, tablet or TV of the person's goes by its name (`{{lamp}} devices` lists those plugged in with USB debugging
245
+ on): only when they ask for it there. If it says to allow debugging, that's a tap on the device's own screen, theirs.
246
+ - `{{lamp}} look --on android` is the device's screen as a picture, whether the app is open, and what the page logged
247
+ there: a game on Lamp's runtime logs how many frames a second it gets.
248
+ - `{{lamp}} use --on android click <x> <y>` taps a point of that picture; `drag`, `type`, `key` and `button` work too,
249
+ one key or button at a time, with no stick. A game shows touch controls until a controller's button is pressed.
250
+ - A change isn't live there: `{{lamp}} open --on android` again builds and installs it, in a few seconds.
251
+ - `{{lamp}} remove --on android` takes it off.
252
+
253
+ ## Lamp's skills
254
+
255
+ An app Lamp made (its page loads `lamp.js`) is built from Lamp's own building blocks, and Lamp has guidance for each
256
+ kind of work on one: a new web game, 3D, how a game feels, a web app's page. `{{lamp}} skills game` lists those about a
257
+ word, `{{lamp}} skills` all of them, and `{{lamp}} skill <name>` prints one. Read the ones that fit before changing what
258
+ they cover: they are the one place that says which building blocks to use and how.
259
+
260
+ Those skills are written for Lamp's app, which builds the game, opens it and looks at it for you when your turn
261
+ ends, and so tells you to write and finish without looking or playing. Nothing does that here: you look after every
262
+ change, as above, and that comes first. Where one names a tool of Lamp's:
263
+
264
+ - `look_at_app` is `{{lamp}} look`, and its `reopen` is `--reopen`. There's no `motion`: look twice.
265
+ - `use_app` is `{{lamp}} use`, one move to each of its actions. A control on the page is clicked at its point from the
266
+ screen as text, not by an id.
267
+ - `read_skill` is `{{lamp}} skill <name>`, and `make_app_for` is `{{lamp}} new`, for a web game only.
268
+ - `delete_file` is deleting the file, and putting a change in needs no tool.
269
+ - `assets`, `make_art` and `lampify` aren't here: make what's needed in code, or say what's missing.
270
+
271
+ A plain site, on neither `lamp.js` nor Lamp's runtime, uses none of them: skip the skills there.
272
+
273
+ ## Rules
274
+
275
+ - Lamp's own files in the folder are rewritten by Lamp, so read them and never edit them: `lamp.js`, `lamp-game.js`,
276
+ `lamp-phaser.js`, `lamp-controllers.js`, and the `three/` and `phaser/` folders.
277
+ - The page's whole log is the file `look` names.
278
+ - lamp runs the page in a browser on this computer, and puts it on an Xbox ("On the person's Xbox") and on Android
279
+ ("On Android"). iPhones, Samsung and LG TVs,
280
+ and whatever needs Lamp's Mac app around the page, aren't here: say so rather than working around it.
package/cli/skills.mjs ADDED
@@ -0,0 +1,71 @@
1
+ // Lamp's skills as `lamp skill` prints them: read from Lamp's own folder (Resources/skills), and put together the way
2
+ // Lamp's app puts them together (`Skills.parse`, `Skills.assembled`, `Skills.section`). A skill made of sections of
3
+ // others names them in its frontmatter ("game#Fun; game-ui#Proof") and has them put where its body says
4
+ // `{{sections}}`, so each section is written in one place.
5
+
6
+ import { existsSync, readdirSync, readFileSync } from "node:fs";
7
+ import { dirname, join } from "node:path";
8
+ import { fileURLToPath } from "node:url";
9
+ import { RESOURCES } from "./state.mjs";
10
+
11
+ export const SKILLS = join(RESOURCES, "skills");
12
+
13
+ /** A SKILL.md: frontmatter between `---` lines, a field a line, then the instructions. */
14
+ function parse(text) {
15
+ const lines = text.split("\n");
16
+ const close = lines.indexOf("---", 1);
17
+ if (lines[0] !== "---" || close < 0) return null;
18
+ const fields = {};
19
+ for (const line of lines.slice(1, close)) {
20
+ const colon = line.indexOf(":");
21
+ if (colon > 0) fields[line.slice(0, colon).trim()] = line.slice(colon + 1).trim();
22
+ }
23
+ if (!fields.name || !fields.description) return null;
24
+ return { name: fields.name, description: fields.description, sections: fields.sections ?? null, body: lines.slice(close + 1).join("\n").trim() };
25
+ }
26
+
27
+ /** One section of a skill, as "skill#Heading": its heading, made a second-level one, and what's under it. */
28
+ function section(name, skills) {
29
+ const at = name.indexOf("#");
30
+ const source = at < 0 ? null : skills.get(name.slice(0, at))?.body;
31
+ if (source == null) return null;
32
+ const title = name.slice(at + 1), lines = source.split("\n");
33
+ // A line of a code block is never a heading, whatever it starts with.
34
+ let fenced = false;
35
+ const headings = [];
36
+ lines.forEach((line, index) => {
37
+ if (line.startsWith("```")) { fenced = !fenced; return; }
38
+ const marks = /^(#+) /.exec(line);
39
+ if (!fenced && marks) headings.push({ index, level: marks[1].length, title: line.slice(marks[1].length).trim() });
40
+ });
41
+ if (!title) {
42
+ // The text before the skill's first section.
43
+ const first = headings.find((heading) => heading.level === 1), second = headings.find((heading) => heading.level === 2);
44
+ const start = first ? first.index + 1 : 0, end = second ? second.index : lines.length;
45
+ return lines.slice(start, Math.max(start, end)).join("\n").trim() || null;
46
+ }
47
+ const found = headings.findIndex((heading) => heading.title === title && heading.level > 1);
48
+ if (found < 0) return null;
49
+ const heading = headings[found], next = headings.slice(found + 1).find((later) => later.level <= heading.level);
50
+ return `## ${heading.title}\n\n${lines.slice(heading.index + 1, next ? next.index : lines.length).join("\n").trim()}`;
51
+ }
52
+
53
+ /** Every skill by name, each as Lamp's app hands it over. Empty when Lamp's skills aren't beside this copy of lamp. */
54
+ export function allSkills() {
55
+ const skills = new Map();
56
+ if (!existsSync(SKILLS)) return skills;
57
+ for (const entry of readdirSync(SKILLS, { withFileTypes: true })) {
58
+ if (!entry.isDirectory()) continue;
59
+ let skill = null;
60
+ try { skill = parse(readFileSync(join(SKILLS, entry.name, "SKILL.md"), "utf8")); } catch {}
61
+ if (skill) skills.set(skill.name, skill);
62
+ }
63
+ // Sections come from the skills as they're written, never from one already put together.
64
+ const written = new Map(skills);
65
+ for (const skill of written.values()) {
66
+ if (!skill.sections) continue;
67
+ const text = skill.sections.split(";").map((name) => name.trim()).filter(Boolean).map((name) => section(name, written)).filter(Boolean).join("\n\n");
68
+ skills.set(skill.name, { ...skill, body: skill.body.includes("{{sections}}") ? skill.body.replaceAll("{{sections}}", text) : `${skill.body}\n\n${text}` });
69
+ }
70
+ return skills;
71
+ }
package/cli/state.mjs ADDED
@@ -0,0 +1,176 @@
1
+ // Where a folder's page is, where lamp keeps what it needs for it, and how one lamp command finds the server another
2
+ // started for the same folder.
3
+
4
+ import { createHash } from "node:crypto";
5
+ import { existsSync, statSync, readFileSync, readdirSync, realpathSync } from "node:fs";
6
+ import { homedir } from "node:os";
7
+ import { basename, dirname, join, resolve } from "node:path";
8
+ import { fileURLToPath } from "node:url";
9
+
10
+ /**
11
+ * Where Lamp's own resources are (its game kit, libraries, skills, device integrations): the repository's Resources/
12
+ * beside cli/, or in Lamp's app, the bundle's Resources, which holds this copy of lamp in its cli/ (build.sh).
13
+ */
14
+ export const RESOURCES = (() => {
15
+ const cli = dirname(fileURLToPath(import.meta.url));
16
+ const repository = join(cli, "..", "Resources");
17
+ return existsSync(join(repository, "GameKit")) ? repository : join(cli, "..");
18
+ })();
19
+
20
+ /** Something the person or agent can put right, said in plain words and shown without a stack. */
21
+ export class Problem extends Error {}
22
+
23
+ /** The runtime whose presence makes a page a game's (`GamePage.runtimeFile`). */
24
+ export const RUNTIME_FILE = "lamp-game.js";
25
+ // The app's notes, at the top of its page: what it is and how it's made, for whoever works on it. Never part of the
26
+ // page: saving it changes nothing a page runs, and a shared page goes without it.
27
+ export const NOTES_FILE = "APP.md";
28
+
29
+ /**
30
+ * How the folder is laid out: an app Lamp made keeps its page in Web/, and any other folder with an index.html is a
31
+ * plain site whose page is the folder itself.
32
+ */
33
+ export function layoutOf(given) {
34
+ let folder = resolve(given);
35
+ if (!existsSync(folder) || !statSync(folder).isDirectory()) throw new Problem(`${folder} isn't a folder`);
36
+ folder = realpathSync(folder);
37
+ const root = [join(folder, "Web"), folder].find((candidate) => existsSync(join(candidate, "index.html")));
38
+ if (!root) throw new Problem(`${folder} has no page: no Web/index.html and no index.html`);
39
+ return { folder, root, lamps: root !== folder, game: existsSync(join(root, RUNTIME_FILE)) };
40
+ }
41
+
42
+ /**
43
+ * What Lamp's own record in the folder says it is (`lamp-app.json`, which an app Lamp shared or put on GitHub carries
44
+ * at its top, or a site in `.lamp-wish/`): its kind (`platform`), its name and the wish's other apps (`parts`). Null in
45
+ * a folder without one.
46
+ */
47
+ export function manifestOf(folder) {
48
+ for (const at of ["lamp-app.json", join(".lamp-wish", "lamp-app.json")]) {
49
+ try {
50
+ const said = JSON.parse(readFileSync(join(folder, at), "utf8"));
51
+ if (said && typeof said === "object" && !Array.isArray(said)) return said;
52
+ } catch {}
53
+ }
54
+ return null;
55
+ }
56
+
57
+ /** Whether some Swift of the app's own imports RealityKit (`Template.importsRealityKit`), which Lamp builds a scene around. */
58
+ function importsRealityKit(folder) {
59
+ let entries;
60
+ try { entries = readdirSync(folder, { withFileTypes: true }); } catch { return false; }
61
+ return entries.some((entry) => entry.isDirectory() ? importsRealityKit(join(folder, entry.name))
62
+ : entry.name.endsWith(".swift") && entry.name !== "LampSupport.swift" && entry.name !== "LampScene.swift"
63
+ && /^\s*(@\w+\s+)?import\s+RealityKit\b/m.test(readFileSync(join(folder, entry.name), "utf8")));
64
+ }
65
+
66
+ /**
67
+ * The newest Lamp app format this lamp reads (`Sharing.formatVersion`, which CLIFilesTests holds it to): a folder in a
68
+ * newer one was made by a newer Lamp, laid out in a way this lamp may misread.
69
+ */
70
+ export const FORMAT = 12;
71
+
72
+ // The kinds Lamp makes that lamp doesn't build or run, in the words a person knows them by (`Platform`'s kinds).
73
+ const ELSEWHERE = {
74
+ iphone: "an iPhone app", universal: "an app for both the Mac and the iPhone", android: "an Android app",
75
+ "android-tv": "an Android TV app", tv: "a TV app", device: "an app for a device through its integration",
76
+ };
77
+
78
+ /**
79
+ * What the folder is to lamp: a page (as `layoutOf` reads it), or an app Lamp made in Swift for the Mac (its code in
80
+ * Sources/; `missing` lists Lamp's own files it lacks, which a shared file never carries and lamp writes before it
81
+ * builds). A folder in Lamp's format is read by what its `lamp-app.json` says it is: a web app, a game or a screen is
82
+ * its page (a game Lamp made has the Mac app around its page too), a Mac app its code, and a kind lamp doesn't run, or
83
+ * a wish of several apps, is said so rather than taken for another.
84
+ */
85
+ export function projectOf(given) {
86
+ const folder = resolve(given);
87
+ if (!existsSync(folder) || !statSync(folder).isDirectory()) throw new Problem(`${folder} isn't a folder`);
88
+ const real = realpathSync(folder);
89
+ const hasPage = [join(real, "Web"), real].some((candidate) => existsSync(join(candidate, "index.html")));
90
+ const owned = ["Package.swift", "build.sh", join("Sources", "LampSupport.swift")];
91
+ const manifest = manifestOf(real);
92
+ if (manifest) {
93
+ if (Number.isInteger(manifest.format) && manifest.format > FORMAT) throw new Problem(`${real} was made by a newer Lamp than this lamp knows (its format is ${manifest.format}): update lamp, or open it in Lamp's app`);
94
+ const parts = Array.isArray(manifest.parts) ? manifest.parts.length : 0;
95
+ if (parts) throw new Problem(`${real} is a wish of ${parts + 1} apps, and lamp works on one app in a folder: open it in Lamp's app`);
96
+ const kind = typeof manifest.platform === "string" ? manifest.platform : "mac";
97
+ if (ELSEWHERE[kind]) throw new Problem(`${real} is ${ELSEWHERE[kind]}, which lamp doesn't build or run: open it in Lamp's app`);
98
+ if (["web-app", "game", "screen"].includes(kind)) {
99
+ if (!hasPage) throw new Problem(kind === "game" ? `${real} is a game written in C++, which lamp doesn't run: open it in Lamp's app` : `${real} has no page: no Web/index.html and no index.html`);
100
+ return { kind: "page", ...layoutOf(real) };
101
+ }
102
+ if (kind === "mac") {
103
+ if (!existsSync(join(real, "Sources"))) throw new Problem(`${real} is a Mac app with no code: no Sources/`);
104
+ const missing = owned.filter((path) => !existsSync(join(real, path)));
105
+ // Lamp's starting files build an app alone: a widget, a share extension or a 3D scene is built with files of
106
+ // Lamp's that only its app writes (`Template.writeSwiftOwnedFiles`).
107
+ const more = missing.length && (["Widget", "Share"].find((extra) => existsSync(join(real, extra))) ?? (importsRealityKit(join(real, "Sources")) ? "a 3D scene" : null));
108
+ if (more) throw new Problem(`${real} is a Mac app with ${more.includes(" ") ? more : `a ${more === "Widget" ? "widget" : "share extension"}`}, which only Lamp's app builds from a shared file: open it in Lamp's app first`);
109
+ return { kind: "mac", folder: real, missing };
110
+ }
111
+ throw new Problem(`${real} is a kind of app this lamp doesn't know ("${kind}"): a newer Lamp made it`);
112
+ }
113
+ if (hasPage) return { kind: "page", ...layoutOf(real) };
114
+ if (existsSync(join(real, "Package.swift")) && existsSync(join(real, "build.sh")) && existsSync(join(real, "Sources"))) return { kind: "mac", folder: real, missing: [] };
115
+ throw new Problem(`${real} has no page (no Web/index.html and no index.html), and isn't a Mac app Lamp made (no Package.swift with its build.sh, and no lamp-app.json)`);
116
+ }
117
+
118
+ /**
119
+ * Where lamp keeps what it needs for a folder: the browser's own files (so a game's saves last from one run to the
120
+ * next), the picture of the last look, and which server is running. Outside the folder, so nothing of lamp's is
121
+ * published or committed with a plain site.
122
+ */
123
+ export function stateOf(folder) {
124
+ const home = process.env.LAMP_DEV_HOME || join(homedir(), ".lamp", "dev");
125
+ const name = basename(folder).replace(/[^\w.-]+/g, "-").slice(0, 40) || "app";
126
+ return join(home, `${name}-${hashOf(folder).slice(0, 8)}`);
127
+ }
128
+
129
+ const hashOf = (folder) => createHash("sha256").update(folder).digest("hex");
130
+
131
+ /**
132
+ * The port a folder's page is first served on: its own, from its path, so two apps run side by side and each keeps
133
+ * its address (a game's saves belong to the address) from the first run on.
134
+ */
135
+ export const firstPortOf = (folder) => 4400 + (parseInt(hashOf(folder).slice(0, 6), 16) % 500);
136
+
137
+ /**
138
+ * The page's log, with the rest of lamp's state: lamp writes nothing in the app's folder, which may be one Lamp's app
139
+ * is running too, with a log of its own where an app made by Lamp keeps it.
140
+ */
141
+ export function logFileOf(layout) {
142
+ return join(stateOf(layout.folder), "log.txt");
143
+ }
144
+
145
+ export const serverFileOf = (folder) => join(stateOf(folder), "server.json");
146
+
147
+ /** Asks a running server something only lamp's own commands may ask: they hold the token it wrote for them. */
148
+ export async function ask(server, path, body, { timeout = 10_000 } = {}) {
149
+ let answer;
150
+ try {
151
+ answer = await fetch(`http://127.0.0.1:${server.port}/__lamp/cli/${path}`, {
152
+ method: body === undefined ? "GET" : "POST",
153
+ headers: { "x-lamp-token": server.token, "content-type": "application/json" },
154
+ body: body === undefined ? undefined : JSON.stringify(body),
155
+ signal: AbortSignal.timeout(timeout),
156
+ });
157
+ } catch (error) {
158
+ throw new Problem(error.name === "TimeoutError" ? "lamp dev didn't answer in time" : "lamp dev isn't running for this folder");
159
+ }
160
+ const said = await answer.json().catch(() => null);
161
+ if (!answer.ok) throw new Problem(said?.problem || `lamp dev answered ${answer.status}`);
162
+ return said;
163
+ }
164
+
165
+ /**
166
+ * The server running for this folder, if one is: what it wrote when it started, checked by asking it. `own` is one a
167
+ * lamp command started for itself that has no window open: a `lamp dev` run by hand takes its place.
168
+ */
169
+ export async function running(folder) {
170
+ let server;
171
+ try { server = JSON.parse(readFileSync(serverFileOf(folder), "utf8")); } catch { return null; }
172
+ try {
173
+ const hello = await ask(server, "hello", undefined, { timeout: 1500 });
174
+ return hello.folder === folder ? { ...server, url: hello.url, own: !!hello.own } : null;
175
+ } catch { return null; }
176
+ }