@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.
- package/LICENSE +21 -0
- package/README.md +397 -2
- package/Resources/Devices/roku.json +410 -0
- package/Resources/Devices/xbox-one.json +367 -0
- package/Resources/GameKit/NOTICE.md +63 -0
- package/Resources/GameKit/apple/LampPage.swift +1813 -0
- package/Resources/GameKit/apple/LampPlayer.swift +46 -0
- package/Resources/GameKit/apple/LampWebApp.swift +63 -0
- package/Resources/GameKit/apple/LampWebGame.swift +87 -0
- package/Resources/GameKit/apple/Native.swift +12 -0
- package/Resources/GameKit/build.sh +55 -0
- package/Resources/GameKit/lamp_game.h +116 -0
- package/Resources/GameKit/lamp_host.h +19 -0
- package/Resources/GameKit/lamp_kit.cpp +61 -0
- package/Resources/GameKit/lamp_sound.cpp +455 -0
- package/Resources/GameKit/lamp_xbox.cpp +374 -0
- package/Resources/GameKit/libraries/HandmadeMath.h +3940 -0
- package/Resources/GameKit/libraries/cgltf.h +7240 -0
- package/Resources/GameKit/libraries/dr_mp3.h +5430 -0
- package/Resources/GameKit/libraries/dr_wav.h +9209 -0
- package/Resources/GameKit/libraries/sokol_debugtext.h +4754 -0
- package/Resources/GameKit/libraries/sokol_gfx.h +29558 -0
- package/Resources/GameKit/libraries/sokol_gl.h +4538 -0
- package/Resources/GameKit/libraries/sokol_log.h +335 -0
- package/Resources/GameKit/libraries/sokol_shape.h +1531 -0
- package/Resources/GameKit/libraries/stb_image.h +7988 -0
- package/Resources/GameKit/libraries/stb_vorbis.c +5584 -0
- package/Resources/GameKit/page/lamp-live.js +672 -0
- package/Resources/GameKit/scaffold/Game/game.cpp +142 -0
- package/Resources/GameKit/scaffold/Game/scene.glsl +49 -0
- package/Resources/GameKit/scaffold-web/Web/game.js +31 -0
- package/Resources/GameKit/scaffold-web/Web/index.html +13 -0
- package/Resources/GameKit/scaffold-web/Web/making.js +33 -0
- package/Resources/GameKit/scaffold-web/Web/world.js +33 -0
- package/Resources/GameKit/web/lamp-game.js +3042 -0
- package/Resources/GameKit/web/lamp-phaser.js +128 -0
- package/Resources/WebHost/App.exe +0 -0
- package/Resources/WebHost/Microsoft.Web.WebView2.Core.dll +0 -0
- package/Resources/WebHost/WebView2-LICENSE.txt +27 -0
- package/Resources/WebHost/lamp_controllers.h +1506 -0
- package/Resources/WebHost/lamp_web_host.cpp +1173 -0
- package/Resources/WebLibraries/earlier.txt +318 -0
- package/Resources/WebLibraries/phaser/LICENSE.md +20 -0
- package/Resources/WebLibraries/phaser/NOTICE.md +2 -0
- package/Resources/WebLibraries/phaser/phaser.esm.min.js +1 -0
- package/Resources/WebLibraries/qrcode/LICENSE +21 -0
- package/Resources/WebLibraries/qrcode/NOTICE.md +4 -0
- package/Resources/WebLibraries/qrcode/qrcode.js +2297 -0
- package/Resources/WebLibraries/rapier/LICENSE +201 -0
- package/Resources/WebLibraries/rapier/NOTICE.md +3 -0
- package/Resources/WebLibraries/rapier/rapier.js +2 -0
- package/Resources/WebLibraries/three/LICENSE +21 -0
- package/Resources/WebLibraries/three/NOTICE.md +4 -0
- package/Resources/WebLibraries/three/addons/animation/AnimationClipCreator.js +168 -0
- package/Resources/WebLibraries/three/addons/animation/CCDIKSolver.js +607 -0
- package/Resources/WebLibraries/three/addons/controls/ArcballControls.js +3543 -0
- package/Resources/WebLibraries/three/addons/controls/DragControls.js +452 -0
- package/Resources/WebLibraries/three/addons/controls/FirstPersonControls.js +512 -0
- package/Resources/WebLibraries/three/addons/controls/FlyControls.js +384 -0
- package/Resources/WebLibraries/three/addons/controls/MapControls.js +116 -0
- package/Resources/WebLibraries/three/addons/controls/OrbitControls.js +1985 -0
- package/Resources/WebLibraries/three/addons/controls/PointerLockControls.js +264 -0
- package/Resources/WebLibraries/three/addons/controls/TrackballControls.js +1106 -0
- package/Resources/WebLibraries/three/addons/controls/TransformControls.js +2003 -0
- package/Resources/WebLibraries/three/addons/curves/CurveExtras.js +694 -0
- package/Resources/WebLibraries/three/addons/curves/NURBSCurve.js +169 -0
- package/Resources/WebLibraries/three/addons/curves/NURBSSurface.js +98 -0
- package/Resources/WebLibraries/three/addons/curves/NURBSUtils.js +532 -0
- package/Resources/WebLibraries/three/addons/curves/NURBSVolume.js +82 -0
- package/Resources/WebLibraries/three/addons/effects/AnaglyphEffect.js +274 -0
- package/Resources/WebLibraries/three/addons/effects/AsciiEffect.js +323 -0
- package/Resources/WebLibraries/three/addons/effects/OutlineEffect.js +489 -0
- package/Resources/WebLibraries/three/addons/effects/ParallaxBarrierEffect.js +155 -0
- package/Resources/WebLibraries/three/addons/effects/StereoEffect.js +91 -0
- package/Resources/WebLibraries/three/addons/environments/ColorEnvironment.js +59 -0
- package/Resources/WebLibraries/three/addons/environments/DebugEnvironment.js +102 -0
- package/Resources/WebLibraries/three/addons/environments/RoomEnvironment.js +185 -0
- package/Resources/WebLibraries/three/addons/geometries/BoxLineGeometry.js +92 -0
- package/Resources/WebLibraries/three/addons/geometries/ConvexGeometry.js +72 -0
- package/Resources/WebLibraries/three/addons/geometries/DecalGeometry.js +420 -0
- package/Resources/WebLibraries/three/addons/geometries/LoftGeometry.js +355 -0
- package/Resources/WebLibraries/three/addons/geometries/ParametricFunctions.js +100 -0
- package/Resources/WebLibraries/three/addons/geometries/ParametricGeometry.js +172 -0
- package/Resources/WebLibraries/three/addons/geometries/RoundedBoxGeometry.js +216 -0
- package/Resources/WebLibraries/three/addons/geometries/TeapotGeometry.js +689 -0
- package/Resources/WebLibraries/three/addons/geometries/TextGeometry.js +102 -0
- package/Resources/WebLibraries/three/addons/helpers/AnimationPathHelper.js +302 -0
- package/Resources/WebLibraries/three/addons/helpers/LightProbeGridHelper.js +166 -0
- package/Resources/WebLibraries/three/addons/helpers/LightProbeGridHelperWebGL.js +221 -0
- package/Resources/WebLibraries/three/addons/helpers/LightProbeHelper.js +166 -0
- package/Resources/WebLibraries/three/addons/helpers/LightProbeHelperGPU.js +102 -0
- package/Resources/WebLibraries/three/addons/helpers/OctreeHelper.js +109 -0
- package/Resources/WebLibraries/three/addons/helpers/PositionalAudioHelper.js +169 -0
- package/Resources/WebLibraries/three/addons/helpers/RapierHelper.js +59 -0
- package/Resources/WebLibraries/three/addons/helpers/RectAreaLightHelper.js +118 -0
- package/Resources/WebLibraries/three/addons/helpers/TextureHelper.js +265 -0
- package/Resources/WebLibraries/three/addons/helpers/TextureHelperGPU.js +214 -0
- package/Resources/WebLibraries/three/addons/helpers/VertexNormalsHelper.js +155 -0
- package/Resources/WebLibraries/three/addons/helpers/VertexTangentsHelper.js +133 -0
- package/Resources/WebLibraries/three/addons/helpers/ViewHelper.js +529 -0
- package/Resources/WebLibraries/three/addons/interactive/HTMLMesh.js +617 -0
- package/Resources/WebLibraries/three/addons/interactive/InteractiveGroup.js +224 -0
- package/Resources/WebLibraries/three/addons/interactive/SelectionBox.js +324 -0
- package/Resources/WebLibraries/three/addons/interactive/SelectionHelper.js +150 -0
- package/Resources/WebLibraries/three/addons/libs/fflate.module.js +2699 -0
- package/Resources/WebLibraries/three/addons/libs/lil-gui.module.min.js +8 -0
- package/Resources/WebLibraries/three/addons/libs/meshopt_decoder.module.js +196 -0
- package/Resources/WebLibraries/three/addons/libs/potpack.module.js +125 -0
- package/Resources/WebLibraries/three/addons/libs/stats.module.js +167 -0
- package/Resources/WebLibraries/three/addons/libs/tween.module.js +876 -0
- package/Resources/WebLibraries/three/addons/lighting/ClusteredLighting.js +153 -0
- package/Resources/WebLibraries/three/addons/lighting/DynamicLighting.js +82 -0
- package/Resources/WebLibraries/three/addons/lighting/LightMapper.js +295 -0
- package/Resources/WebLibraries/three/addons/lighting/LightProbeGrid.js +923 -0
- package/Resources/WebLibraries/three/addons/lighting/LightProbeGridUtils.js +107 -0
- package/Resources/WebLibraries/three/addons/lighting/LightProbeGridWebGL.js +846 -0
- package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGIConeTracer.js +243 -0
- package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGIIrradiance.js +43 -0
- package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGINode.js +617 -0
- package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGISceneCollector.js +793 -0
- package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGIVolume.js +1440 -0
- package/Resources/WebLibraries/three/addons/lights/LightProbeGenerator.js +337 -0
- package/Resources/WebLibraries/three/addons/lights/RectAreaLightTexturesLib.js +127 -0
- package/Resources/WebLibraries/three/addons/lights/RectAreaLightUniformsLib.js +40 -0
- package/Resources/WebLibraries/three/addons/lights/SunLight.js +100 -0
- package/Resources/WebLibraries/three/addons/lights/SunLightNode.js +56 -0
- package/Resources/WebLibraries/three/addons/lights/SunLightShadow.js +319 -0
- package/Resources/WebLibraries/three/addons/lights/SunShadowNode.js +312 -0
- package/Resources/WebLibraries/three/addons/lines/Line2.js +56 -0
- package/Resources/WebLibraries/three/addons/lines/LineGeometry.js +157 -0
- package/Resources/WebLibraries/three/addons/lines/LineMaterial.js +742 -0
- package/Resources/WebLibraries/three/addons/lines/LineSegments2.js +434 -0
- package/Resources/WebLibraries/three/addons/lines/LineSegmentsGeometry.js +298 -0
- package/Resources/WebLibraries/three/addons/lines/Wireframe.js +108 -0
- package/Resources/WebLibraries/three/addons/lines/WireframeGeometry2.js +49 -0
- package/Resources/WebLibraries/three/addons/lines/webgpu/Line2.js +46 -0
- package/Resources/WebLibraries/three/addons/lines/webgpu/LineSegments2.js +419 -0
- package/Resources/WebLibraries/three/addons/lines/webgpu/Wireframe.js +86 -0
- package/Resources/WebLibraries/three/addons/loaders/EXRLoader.js +3411 -0
- package/Resources/WebLibraries/three/addons/loaders/FBXLoader.js +4660 -0
- package/Resources/WebLibraries/three/addons/loaders/FontLoader.js +262 -0
- package/Resources/WebLibraries/three/addons/loaders/GLTFLoader.js +5006 -0
- package/Resources/WebLibraries/three/addons/loaders/HDRLoader.js +463 -0
- package/Resources/WebLibraries/three/addons/loaders/MTLLoader.js +601 -0
- package/Resources/WebLibraries/three/addons/loaders/OBJLoader.js +961 -0
- package/Resources/WebLibraries/three/addons/loaders/PLYLoader.js +992 -0
- package/Resources/WebLibraries/three/addons/loaders/RGBELoader.js +18 -0
- package/Resources/WebLibraries/three/addons/loaders/STLLoader.js +423 -0
- package/Resources/WebLibraries/three/addons/loaders/SVGLoader.js +3297 -0
- package/Resources/WebLibraries/three/addons/loaders/TGALoader.js +539 -0
- package/Resources/WebLibraries/three/addons/loaders/UltraHDRLoader.js +757 -0
- package/Resources/WebLibraries/three/addons/math/Capsule.js +159 -0
- package/Resources/WebLibraries/three/addons/math/ColorConverter.js +62 -0
- package/Resources/WebLibraries/three/addons/math/ColorSpaces.js +147 -0
- package/Resources/WebLibraries/three/addons/math/ConvexHull.js +1695 -0
- package/Resources/WebLibraries/three/addons/math/ImprovedNoise.js +88 -0
- package/Resources/WebLibraries/three/addons/math/Lut.js +317 -0
- package/Resources/WebLibraries/three/addons/math/MeshSurfaceSampler.js +315 -0
- package/Resources/WebLibraries/three/addons/math/OBB.js +535 -0
- package/Resources/WebLibraries/three/addons/math/Octree.js +825 -0
- package/Resources/WebLibraries/three/addons/math/SimplexNoise.js +470 -0
- package/Resources/WebLibraries/three/addons/misc/ConvexObjectBreaker.js +539 -0
- package/Resources/WebLibraries/three/addons/misc/GPUComputationRenderer.js +508 -0
- package/Resources/WebLibraries/three/addons/misc/Gyroscope.js +78 -0
- package/Resources/WebLibraries/three/addons/misc/MorphAnimMesh.js +119 -0
- package/Resources/WebLibraries/three/addons/misc/MorphBlendMesh.js +425 -0
- package/Resources/WebLibraries/three/addons/misc/ProgressiveLightMap.js +370 -0
- package/Resources/WebLibraries/three/addons/misc/ProgressiveLightMapGPU.js +322 -0
- package/Resources/WebLibraries/three/addons/misc/RollerCoaster.js +661 -0
- package/Resources/WebLibraries/three/addons/misc/Sculptor.js +1679 -0
- package/Resources/WebLibraries/three/addons/misc/SculptorMesh.js +1504 -0
- package/Resources/WebLibraries/three/addons/misc/SculptorTools.js +1180 -0
- package/Resources/WebLibraries/three/addons/misc/SculptorUtils.js +345 -0
- package/Resources/WebLibraries/three/addons/misc/TileCreasedNormalsPlugin.js +270 -0
- package/Resources/WebLibraries/three/addons/misc/TubePainter.js +611 -0
- package/Resources/WebLibraries/three/addons/misc/Volume.js +520 -0
- package/Resources/WebLibraries/three/addons/misc/VolumeSlice.js +275 -0
- package/Resources/WebLibraries/three/addons/modifiers/CurveModifier.js +374 -0
- package/Resources/WebLibraries/three/addons/modifiers/CurveModifierGPU.js +256 -0
- package/Resources/WebLibraries/three/addons/modifiers/EdgeSplitModifier.js +299 -0
- package/Resources/WebLibraries/three/addons/modifiers/TessellateModifier.js +340 -0
- package/Resources/WebLibraries/three/addons/objects/GroundedSkybox.js +69 -0
- package/Resources/WebLibraries/three/addons/objects/Lensflare.js +489 -0
- package/Resources/WebLibraries/three/addons/objects/LensflareMesh.js +376 -0
- package/Resources/WebLibraries/three/addons/objects/MarchingCubes.js +1261 -0
- package/Resources/WebLibraries/three/addons/objects/Reflector.js +390 -0
- package/Resources/WebLibraries/three/addons/objects/ReflectorForSSRPass.js +393 -0
- package/Resources/WebLibraries/three/addons/objects/Refractor.js +389 -0
- package/Resources/WebLibraries/three/addons/objects/ShadowMesh.js +130 -0
- package/Resources/WebLibraries/three/addons/objects/Sky.js +342 -0
- package/Resources/WebLibraries/three/addons/objects/SkyMesh.js +403 -0
- package/Resources/WebLibraries/three/addons/objects/Water.js +374 -0
- package/Resources/WebLibraries/three/addons/objects/Water2.js +403 -0
- package/Resources/WebLibraries/three/addons/objects/Water2Mesh.js +199 -0
- package/Resources/WebLibraries/three/addons/objects/WaterMesh.js +194 -0
- package/Resources/WebLibraries/three/addons/postprocessing/AfterimagePass.js +187 -0
- package/Resources/WebLibraries/three/addons/postprocessing/BloomPass.js +274 -0
- package/Resources/WebLibraries/three/addons/postprocessing/BokehPass.js +218 -0
- package/Resources/WebLibraries/three/addons/postprocessing/ClearPass.js +97 -0
- package/Resources/WebLibraries/three/addons/postprocessing/CubeTexturePass.js +146 -0
- package/Resources/WebLibraries/three/addons/postprocessing/DotScreenPass.js +114 -0
- package/Resources/WebLibraries/three/addons/postprocessing/EffectComposer.js +365 -0
- package/Resources/WebLibraries/three/addons/postprocessing/FXAAPass.js +40 -0
- package/Resources/WebLibraries/three/addons/postprocessing/FilmPass.js +113 -0
- package/Resources/WebLibraries/three/addons/postprocessing/GTAOPass.js +735 -0
- package/Resources/WebLibraries/three/addons/postprocessing/GlitchPass.js +177 -0
- package/Resources/WebLibraries/three/addons/postprocessing/HalftonePass.js +134 -0
- package/Resources/WebLibraries/three/addons/postprocessing/LUTPass.js +138 -0
- package/Resources/WebLibraries/three/addons/postprocessing/MaskPass.js +195 -0
- package/Resources/WebLibraries/three/addons/postprocessing/OutlinePass.js +776 -0
- package/Resources/WebLibraries/three/addons/postprocessing/OutputPass.js +148 -0
- package/Resources/WebLibraries/three/addons/postprocessing/Pass.js +191 -0
- package/Resources/WebLibraries/three/addons/postprocessing/RenderPass.js +193 -0
- package/Resources/WebLibraries/three/addons/postprocessing/RenderPixelatedPass.js +314 -0
- package/Resources/WebLibraries/three/addons/postprocessing/RenderTransitionPass.js +267 -0
- package/Resources/WebLibraries/three/addons/postprocessing/SAOPass.js +407 -0
- package/Resources/WebLibraries/three/addons/postprocessing/SMAAPass.js +230 -0
- package/Resources/WebLibraries/three/addons/postprocessing/SSAARenderPass.js +313 -0
- package/Resources/WebLibraries/three/addons/postprocessing/SSAOPass.js +527 -0
- package/Resources/WebLibraries/three/addons/postprocessing/SSRPass.js +858 -0
- package/Resources/WebLibraries/three/addons/postprocessing/SavePass.js +132 -0
- package/Resources/WebLibraries/three/addons/postprocessing/ShaderPass.js +135 -0
- package/Resources/WebLibraries/three/addons/postprocessing/TAARenderPass.js +243 -0
- package/Resources/WebLibraries/three/addons/postprocessing/TexturePass.js +131 -0
- package/Resources/WebLibraries/three/addons/postprocessing/UnrealBloomPass.js +541 -0
- package/Resources/WebLibraries/three/addons/shaders/ACESFilmicToneMappingShader.js +96 -0
- package/Resources/WebLibraries/three/addons/shaders/AfterimageShader.js +63 -0
- package/Resources/WebLibraries/three/addons/shaders/BasicShader.js +36 -0
- package/Resources/WebLibraries/three/addons/shaders/BleachBypassShader.js +68 -0
- package/Resources/WebLibraries/three/addons/shaders/BlendShader.js +56 -0
- package/Resources/WebLibraries/three/addons/shaders/BokehShader.js +151 -0
- package/Resources/WebLibraries/three/addons/shaders/BokehShader2.js +404 -0
- package/Resources/WebLibraries/three/addons/shaders/BrightnessContrastShader.js +62 -0
- package/Resources/WebLibraries/three/addons/shaders/ColorCorrectionShader.js +59 -0
- package/Resources/WebLibraries/three/addons/shaders/ColorifyShader.js +57 -0
- package/Resources/WebLibraries/three/addons/shaders/ConvolutionShader.js +74 -0
- package/Resources/WebLibraries/three/addons/shaders/CopyShader.js +52 -0
- package/Resources/WebLibraries/three/addons/shaders/DOFMipMapShader.js +63 -0
- package/Resources/WebLibraries/three/addons/shaders/DepthLimitedBlurShader.js +183 -0
- package/Resources/WebLibraries/three/addons/shaders/DigitalGlitch.js +104 -0
- package/Resources/WebLibraries/three/addons/shaders/DotScreenShader.js +75 -0
- package/Resources/WebLibraries/three/addons/shaders/ExposureShader.js +51 -0
- package/Resources/WebLibraries/three/addons/shaders/FXAAShader.js +298 -0
- package/Resources/WebLibraries/three/addons/shaders/FilmShader.js +73 -0
- package/Resources/WebLibraries/three/addons/shaders/FocusShader.js +94 -0
- package/Resources/WebLibraries/three/addons/shaders/FreiChenShader.js +103 -0
- package/Resources/WebLibraries/three/addons/shaders/GTAOShader.js +437 -0
- package/Resources/WebLibraries/three/addons/shaders/GammaCorrectionShader.js +52 -0
- package/Resources/WebLibraries/three/addons/shaders/HalftoneShader.js +332 -0
- package/Resources/WebLibraries/three/addons/shaders/HorizontalBlurShader.js +68 -0
- package/Resources/WebLibraries/three/addons/shaders/HorizontalTiltShiftShader.js +70 -0
- package/Resources/WebLibraries/three/addons/shaders/HueSaturationShader.js +74 -0
- package/Resources/WebLibraries/three/addons/shaders/KaleidoShader.js +65 -0
- package/Resources/WebLibraries/three/addons/shaders/LuminosityHighPassShader.js +68 -0
- package/Resources/WebLibraries/three/addons/shaders/LuminosityShader.js +54 -0
- package/Resources/WebLibraries/three/addons/shaders/MirrorShader.js +62 -0
- package/Resources/WebLibraries/three/addons/shaders/NormalMapShader.js +60 -0
- package/Resources/WebLibraries/three/addons/shaders/OutputShader.js +103 -0
- package/Resources/WebLibraries/three/addons/shaders/PoissonDenoiseShader.js +230 -0
- package/Resources/WebLibraries/three/addons/shaders/RGBShiftShader.js +61 -0
- package/Resources/WebLibraries/three/addons/shaders/SAOShader.js +201 -0
- package/Resources/WebLibraries/three/addons/shaders/SMAAShader.js +489 -0
- package/Resources/WebLibraries/three/addons/shaders/SSAOShader.js +331 -0
- package/Resources/WebLibraries/three/addons/shaders/SSRShader.js +396 -0
- package/Resources/WebLibraries/three/addons/shaders/SepiaShader.js +57 -0
- package/Resources/WebLibraries/three/addons/shaders/SobelOperatorShader.js +98 -0
- package/Resources/WebLibraries/three/addons/shaders/SubsurfaceScatteringShader.js +95 -0
- package/Resources/WebLibraries/three/addons/shaders/TechnicolorShader.js +51 -0
- package/Resources/WebLibraries/three/addons/shaders/ToonShader.js +349 -0
- package/Resources/WebLibraries/three/addons/shaders/TriangleBlurShader.js +79 -0
- package/Resources/WebLibraries/three/addons/shaders/UnpackDepthRGBAShader.js +60 -0
- package/Resources/WebLibraries/three/addons/shaders/VelocityShader.js +137 -0
- package/Resources/WebLibraries/three/addons/shaders/VerticalBlurShader.js +66 -0
- package/Resources/WebLibraries/three/addons/shaders/VerticalTiltShiftShader.js +70 -0
- package/Resources/WebLibraries/three/addons/shaders/VignetteShader.js +56 -0
- package/Resources/WebLibraries/three/addons/shaders/VolumeShader.js +285 -0
- package/Resources/WebLibraries/three/addons/shaders/WaterRefractionShader.js +106 -0
- package/Resources/WebLibraries/three/addons/textures/FlakesTexture.js +54 -0
- package/Resources/WebLibraries/three/addons/tsl/WebGLNodesHandler.js +607 -0
- package/Resources/WebLibraries/three/addons/tsl/display/AfterImageNode.js +256 -0
- package/Resources/WebLibraries/three/addons/tsl/display/AnaglyphPassNode.js +550 -0
- package/Resources/WebLibraries/three/addons/tsl/display/BilateralBlurNode.js +377 -0
- package/Resources/WebLibraries/three/addons/tsl/display/BleachBypass.js +33 -0
- package/Resources/WebLibraries/three/addons/tsl/display/BloomNode.js +599 -0
- package/Resources/WebLibraries/three/addons/tsl/display/CRT.js +150 -0
- package/Resources/WebLibraries/three/addons/tsl/display/ChromaticAberrationNode.js +163 -0
- package/Resources/WebLibraries/three/addons/tsl/display/DenoiseNode.js +354 -0
- package/Resources/WebLibraries/three/addons/tsl/display/DepthOfFieldNode.js +572 -0
- package/Resources/WebLibraries/three/addons/tsl/display/DotScreenNode.js +104 -0
- package/Resources/WebLibraries/three/addons/tsl/display/FSR1Node.js +481 -0
- package/Resources/WebLibraries/three/addons/tsl/display/FXAANode.js +357 -0
- package/Resources/WebLibraries/three/addons/tsl/display/FilmNode.js +101 -0
- package/Resources/WebLibraries/three/addons/tsl/display/GTAONode.js +727 -0
- package/Resources/WebLibraries/three/addons/tsl/display/GaussianBlurNode.js +412 -0
- package/Resources/WebLibraries/three/addons/tsl/display/GodraysNode.js +604 -0
- package/Resources/WebLibraries/three/addons/tsl/display/ImportanceSampledEnvironment.js +564 -0
- package/Resources/WebLibraries/three/addons/tsl/display/LensflareNode.js +282 -0
- package/Resources/WebLibraries/three/addons/tsl/display/Lut3DNode.js +109 -0
- package/Resources/WebLibraries/three/addons/tsl/display/MotionBlur.js +33 -0
- package/Resources/WebLibraries/three/addons/tsl/display/OITPassNode.js +341 -0
- package/Resources/WebLibraries/three/addons/tsl/display/OutlineNode.js +916 -0
- package/Resources/WebLibraries/three/addons/tsl/display/ParallaxBarrierPassNode.js +90 -0
- package/Resources/WebLibraries/three/addons/tsl/display/PixelationPassNode.js +227 -0
- package/Resources/WebLibraries/three/addons/tsl/display/RGBShiftNode.js +96 -0
- package/Resources/WebLibraries/three/addons/tsl/display/RecurrentDenoiseNode.js +812 -0
- package/Resources/WebLibraries/three/addons/tsl/display/RetroPassNode.js +263 -0
- package/Resources/WebLibraries/three/addons/tsl/display/SMAANode.js +729 -0
- package/Resources/WebLibraries/three/addons/tsl/display/SSAAPassNode.js +344 -0
- package/Resources/WebLibraries/three/addons/tsl/display/SSAONode.js +422 -0
- package/Resources/WebLibraries/three/addons/tsl/display/SSGINode.js +698 -0
- package/Resources/WebLibraries/three/addons/tsl/display/SSRNode.js +1430 -0
- package/Resources/WebLibraries/three/addons/tsl/display/SSSNode.js +479 -0
- package/Resources/WebLibraries/three/addons/tsl/display/Sepia.js +24 -0
- package/Resources/WebLibraries/three/addons/tsl/display/Shape.js +29 -0
- package/Resources/WebLibraries/three/addons/tsl/display/SharpenNode.js +284 -0
- package/Resources/WebLibraries/three/addons/tsl/display/SobelOperatorNode.js +168 -0
- package/Resources/WebLibraries/three/addons/tsl/display/StereoCompositePassNode.js +190 -0
- package/Resources/WebLibraries/three/addons/tsl/display/StereoPassNode.js +117 -0
- package/Resources/WebLibraries/three/addons/tsl/display/TAAUNode.js +700 -0
- package/Resources/WebLibraries/three/addons/tsl/display/TRAANode.js +609 -0
- package/Resources/WebLibraries/three/addons/tsl/display/TemporalReprojectNode.js +1024 -0
- package/Resources/WebLibraries/three/addons/tsl/display/TransitionNode.js +141 -0
- package/Resources/WebLibraries/three/addons/tsl/display/boxBlur.js +65 -0
- package/Resources/WebLibraries/three/addons/tsl/display/depthAwareBlend.js +80 -0
- package/Resources/WebLibraries/three/addons/tsl/display/depthAwareBlur.js +63 -0
- package/Resources/WebLibraries/three/addons/tsl/display/hashBlur.js +55 -0
- package/Resources/WebLibraries/three/addons/tsl/display/lensDirt.js +30 -0
- package/Resources/WebLibraries/three/addons/tsl/display/radialBlur.js +68 -0
- package/Resources/WebLibraries/three/addons/tsl/lighting/ClusteredLightsNode.js +994 -0
- package/Resources/WebLibraries/three/addons/tsl/lighting/DynamicLightsNode.js +201 -0
- package/Resources/WebLibraries/three/addons/tsl/lighting/LightProbeGridNode.js +183 -0
- package/Resources/WebLibraries/three/addons/tsl/lighting/data/AmbientLightDataNode.js +67 -0
- package/Resources/WebLibraries/three/addons/tsl/lighting/data/DirectionalLightDataNode.js +117 -0
- package/Resources/WebLibraries/three/addons/tsl/lighting/data/HemisphereLightDataNode.js +105 -0
- package/Resources/WebLibraries/three/addons/tsl/lighting/data/PointLightDataNode.js +140 -0
- package/Resources/WebLibraries/three/addons/tsl/lighting/data/SpotLightDataNode.js +167 -0
- package/Resources/WebLibraries/three/addons/tsl/math/Bayer.js +84 -0
- package/Resources/WebLibraries/three/addons/tsl/math/curlNoise.js +107 -0
- package/Resources/WebLibraries/three/addons/tsl/math/voronoiNoise.js +112 -0
- package/Resources/WebLibraries/three/addons/tsl/shadows/TileShadowNode.js +542 -0
- package/Resources/WebLibraries/three/addons/tsl/shadows/TileShadowNodeHelper.js +212 -0
- package/Resources/WebLibraries/three/addons/tsl/utils/GroundedSkybox.js +62 -0
- package/Resources/WebLibraries/three/addons/tsl/utils/RNoise.js +51 -0
- package/Resources/WebLibraries/three/addons/tsl/utils/Raymarching.js +70 -0
- package/Resources/WebLibraries/three/addons/tsl/utils/SoftParticles.js +53 -0
- package/Resources/WebLibraries/three/addons/tsl/utils/SpecularHelpers.js +302 -0
- package/Resources/WebLibraries/three/addons/tsl/utils/TAAUtils.js +184 -0
- package/Resources/WebLibraries/three/addons/utils/BufferGeometryUtils.js +1523 -0
- package/Resources/WebLibraries/three/addons/utils/CameraUtils.js +82 -0
- package/Resources/WebLibraries/three/addons/utils/ColorUtils.js +76 -0
- package/Resources/WebLibraries/three/addons/utils/GaussianSplatUtils.js +229 -0
- package/Resources/WebLibraries/three/addons/utils/GeometryCompressionUtils.js +547 -0
- package/Resources/WebLibraries/three/addons/utils/GeometryUtils.js +226 -0
- package/Resources/WebLibraries/three/addons/utils/LDrawUtils.js +211 -0
- package/Resources/WebLibraries/three/addons/utils/SceneOptimizer.js +459 -0
- package/Resources/WebLibraries/three/addons/utils/SceneUtils.js +363 -0
- package/Resources/WebLibraries/three/addons/utils/ShadowMapViewer.js +244 -0
- package/Resources/WebLibraries/three/addons/utils/ShadowMapViewerGPU.js +233 -0
- package/Resources/WebLibraries/three/addons/utils/SkeletonUtils.js +496 -0
- package/Resources/WebLibraries/three/addons/utils/SortUtils.js +175 -0
- package/Resources/WebLibraries/three/addons/utils/UVsDebug.js +173 -0
- package/Resources/WebLibraries/three/addons/utils/WebGLTextureUtils.js +115 -0
- package/Resources/WebLibraries/three/addons/utils/WebGPUTextureUtils.js +81 -0
- package/Resources/WebLibraries/three/addons/utils/WorkerPool.js +167 -0
- package/Resources/WebLibraries/three/addons/utils/unwrapUVs.js +865 -0
- package/Resources/WebLibraries/three/three.core.js +61162 -0
- package/Resources/WebLibraries/three/three.module.js +19537 -0
- package/Resources/WebLibraries/three/three.tsl.js +41903 -0
- package/Resources/WebLibraries/three/three.webgpu.js +53714 -0
- package/Resources/share-rules.json +64 -0
- package/Resources/skills/2d-game/SKILL.md +305 -0
- package/Resources/skills/3d-game/SKILL.md +274 -0
- package/Resources/skills/accounts/SKILL.md +41 -0
- package/Resources/skills/android-design/SKILL.md +159 -0
- package/Resources/skills/app-ai/SKILL.md +154 -0
- package/Resources/skills/app-intents/SKILL.md +31 -0
- package/Resources/skills/app-kinds/SKILL.md +122 -0
- package/Resources/skills/apple-watch/SKILL.md +43 -0
- package/Resources/skills/assets/SKILL.md +183 -0
- package/Resources/skills/building-blocks/SKILL.md +97 -0
- package/Resources/skills/device-control/SKILL.md +56 -0
- package/Resources/skills/device-integrations/SKILL.md +278 -0
- package/Resources/skills/finder-files/SKILL.md +19 -0
- package/Resources/skills/game/SKILL.md +416 -0
- package/Resources/skills/game-3d/SKILL.md +12 -0
- package/Resources/skills/game-art/SKILL.md +11 -0
- package/Resources/skills/game-feel/SKILL.md +13 -0
- package/Resources/skills/game-levels/SKILL.md +12 -0
- package/Resources/skills/game-live/SKILL.md +12 -0
- package/Resources/skills/game-physics/SKILL.md +13 -0
- package/Resources/skills/game-playtest/SKILL.md +26 -0
- package/Resources/skills/game-ui/SKILL.md +278 -0
- package/Resources/skills/github-projects/SKILL.md +62 -0
- package/Resources/skills/icloud-sync/SKILL.md +30 -0
- package/Resources/skills/iphone-hardware/SKILL.md +57 -0
- package/Resources/skills/iphone-widgets/SKILL.md +53 -0
- package/Resources/skills/lg-developer-mode/SKILL.md +152 -0
- package/Resources/skills/mac-widgets/SKILL.md +60 -0
- package/Resources/skills/maps/SKILL.md +8 -0
- package/Resources/skills/menu-bar/SKILL.md +36 -0
- package/Resources/skills/more-apps/SKILL.md +53 -0
- package/Resources/skills/phone-controllers/SKILL.md +79 -0
- package/Resources/skills/phone-pages/SKILL.md +173 -0
- package/Resources/skills/roku-developer-mode/SKILL.md +106 -0
- package/Resources/skills/scene-3d/SKILL.md +27 -0
- package/Resources/skills/scripting/SKILL.md +17 -0
- package/Resources/skills/share-extension/SKILL.md +22 -0
- package/Resources/skills/tv-design/SKILL.md +72 -0
- package/Resources/skills/web-app/SKILL.md +170 -0
- package/Resources/skills/web-game/SKILL.md +95 -0
- package/Resources/skills/web-or-native/SKILL.md +108 -0
- package/Resources/skills/wish-links/SKILL.md +156 -0
- package/THIRD_PARTY_NOTICES.md +170 -0
- package/cli/ai.mjs +237 -0
- package/cli/android.mjs +941 -0
- package/cli/app-ai.mjs +473 -0
- package/cli/browser.mjs +284 -0
- package/cli/calls.mjs +594 -0
- package/cli/dev.mjs +820 -0
- package/cli/devices.mjs +984 -0
- package/cli/lamp.mjs +1326 -0
- package/cli/lampapp.mjs +332 -0
- package/cli/lamps/android-host/LampPageGateway.kt +345 -0
- package/cli/lamps/android-host/app/build.gradle.kts +40 -0
- package/cli/lamps/android-host/build.gradle.kts +4 -0
- package/cli/lamps/android-host/game/AndroidManifest.xml +33 -0
- package/cli/lamps/android-host/game/MainActivity.kt +173 -0
- package/cli/lamps/android-host/gradle/libs.versions.toml +39 -0
- package/cli/lamps/android-host/gradle.properties +8 -0
- package/cli/lamps/android-host/page/AndroidManifest.xml +35 -0
- package/cli/lamps/android-host/page/MainActivity.kt +193 -0
- package/cli/lamps/android-host/settings.gradle.kts +30 -0
- package/cli/lamps/android-host/tools.json +43 -0
- package/cli/lamps/lamp-controllers.js +2 -0
- package/cli/lamps/lamp-for-games.js +6922 -0
- package/cli/lamps/lamp.js +7082 -0
- package/cli/lamps/mac-starter/.lamp/meta.json +1 -0
- package/cli/lamps/mac-starter/APP.md +12 -0
- package/cli/lamps/mac-starter/Package.swift +8 -0
- package/cli/lamps/mac-starter/Sources/App.swift +11 -0
- package/cli/lamps/mac-starter/Sources/ContentView.swift +17 -0
- package/cli/lamps/mac-starter/Sources/LampSupport.swift +18215 -0
- package/cli/lamps/mac-starter/build.sh +336 -0
- package/cli/lamps/mac-starter/gitignore +3 -0
- package/cli/lamps/mac-starter/lamp-starter.json +6 -0
- package/cli/lamps/web-starter/APP.md +8 -0
- package/cli/lamps/web-starter/app.js +1 -0
- package/cli/lamps/web-starter/index.html +17 -0
- package/cli/lamps/web-starter/lamp-starter.json +5 -0
- package/cli/lamps/web-starter/lamp.js +7082 -0
- package/cli/lamps/web-starter/style.css +25 -0
- package/cli/link.mjs +202 -0
- package/cli/local-ai.mjs +193 -0
- package/cli/mac.mjs +621 -0
- package/cli/mdns.mjs +205 -0
- package/cli/msix.mjs +413 -0
- package/cli/network.mjs +209 -0
- package/cli/openrouter.mjs +133 -0
- package/cli/outside.mjs +203 -0
- package/cli/page.js +317 -0
- package/cli/place.mjs +298 -0
- package/cli/png.mjs +184 -0
- package/cli/share.mjs +270 -0
- package/cli/skill/SKILL.md +280 -0
- package/cli/skills.mjs +71 -0
- package/cli/state.mjs +176 -0
- package/cli/update.mjs +162 -0
- package/package.json +20 -4
- package/site/lib/quota.js +59 -0
- 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
|
+
}
|