aigpu 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +85 -0
- package/bin/aigpu.js +15 -0
- package/client.d.ts +15 -0
- package/dist/agent-tools.d.ts +61 -0
- package/dist/agent-tools.d.ts.map +1 -0
- package/dist/agent-tools.js +107 -0
- package/dist/agent-tools.js.map +1 -0
- package/dist/agent.d.ts +56 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +243 -0
- package/dist/agent.js.map +1 -0
- package/dist/api-types.d.ts +56 -0
- package/dist/api-types.d.ts.map +1 -0
- package/dist/api-types.js +2 -0
- package/dist/api-types.js.map +1 -0
- package/dist/bind-cache.d.ts +19 -0
- package/dist/bind-cache.d.ts.map +1 -0
- package/dist/bind-cache.js +43 -0
- package/dist/bind-cache.js.map +1 -0
- package/dist/bundle.d.ts +30 -0
- package/dist/bundle.d.ts.map +1 -0
- package/dist/bundle.js +127 -0
- package/dist/bundle.js.map +1 -0
- package/dist/claim-validation-encode.d.ts +14 -0
- package/dist/claim-validation-encode.d.ts.map +1 -0
- package/dist/claim-validation-encode.js +28 -0
- package/dist/claim-validation-encode.js.map +1 -0
- package/dist/claim-validation.d.ts +73 -0
- package/dist/claim-validation.d.ts.map +1 -0
- package/dist/claim-validation.js +135 -0
- package/dist/claim-validation.js.map +1 -0
- package/dist/cli/bin/aigpu.js +101 -0
- package/dist/cli/lib/check/run.js +153 -0
- package/dist/cli/lib/docs/commands/cat.js +12 -0
- package/dist/cli/lib/docs/commands/find.js +180 -0
- package/dist/cli/lib/docs/commands/grep.js +49 -0
- package/dist/cli/lib/docs/commands/ls.js +41 -0
- package/dist/cli/lib/docs/commands/path.js +12 -0
- package/dist/cli/lib/docs/commands/resolve.js +41 -0
- package/dist/cli/lib/docs/commands/shared.js +13 -0
- package/dist/cli/lib/docs/commands/symbols.js +25 -0
- package/dist/cli/lib/docs/errors.js +8 -0
- package/dist/cli/lib/docs/generate/check-drift.js +61 -0
- package/dist/cli/lib/docs/generate/cli.js +12 -0
- package/dist/cli/lib/docs/generate/generate.js +113 -0
- package/dist/cli/lib/docs/generate/manifest.js +218 -0
- package/dist/cli/lib/docs/generate/skill.js +150 -0
- package/dist/cli/lib/docs/help.js +21 -0
- package/dist/cli/lib/docs/index.js +62 -0
- package/dist/cli/lib/docs/model.js +7 -0
- package/dist/cli/lib/docs/run.js +24 -0
- package/dist/cli/lib/docs/service.js +119 -0
- package/dist/cli/lib/doctor/run.js +236 -0
- package/dist/cli/lib/examples/errors.js +13 -0
- package/dist/cli/lib/examples/hashing.js +9 -0
- package/dist/cli/lib/examples/help.js +13 -0
- package/dist/cli/lib/examples/local-source.js +142 -0
- package/dist/cli/lib/examples/paths.js +12 -0
- package/dist/cli/lib/examples/pull.js +58 -0
- package/dist/cli/lib/examples/run.js +71 -0
- package/dist/cli/lib/examples/search.js +6 -0
- package/dist/cli/lib/examples/service.js +118 -0
- package/dist/cli/lib/generated/docs-manifest.generated.js +4758 -0
- package/dist/cli/lib/install-dawn/run.js +24 -0
- package/dist/cli/lib/install-software-renderer/run.js +17 -0
- package/dist/cli/lib/mcp/http.js +93 -0
- package/dist/cli/lib/mcp/server.js +258 -0
- package/dist/cli/lib/mcp/stdio.js +34 -0
- package/dist/cli/lib/snapshot/png.js +62 -0
- package/dist/cli/lib/snapshot/render.js +22 -0
- package/dist/cli/lib/snapshot/run.js +79 -0
- package/dist/cli/lib/snapshot/shaders.js +11 -0
- package/dist/cli/package.json +4 -0
- package/dist/client.d.ts +12 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +2 -0
- package/dist/client.js.map +1 -0
- package/dist/clock.d.ts +26 -0
- package/dist/clock.d.ts.map +1 -0
- package/dist/clock.js +50 -0
- package/dist/clock.js.map +1 -0
- package/dist/compute.d.ts +41 -0
- package/dist/compute.d.ts.map +1 -0
- package/dist/compute.js +132 -0
- package/dist/compute.js.map +1 -0
- package/dist/core/render-bundle.d.ts +30 -0
- package/dist/core/render-bundle.d.ts.map +1 -0
- package/dist/core/render-bundle.js +39 -0
- package/dist/core/render-bundle.js.map +1 -0
- package/dist/core/storage-buffer.d.ts +81 -0
- package/dist/core/storage-buffer.d.ts.map +1 -0
- package/dist/core/storage-buffer.js +91 -0
- package/dist/core/storage-buffer.js.map +1 -0
- package/dist/core/structured-uniform.d.ts +33 -0
- package/dist/core/structured-uniform.d.ts.map +1 -0
- package/dist/core/structured-uniform.js +110 -0
- package/dist/core/structured-uniform.js.map +1 -0
- package/dist/core/uniform-pool-internals.d.ts +12 -0
- package/dist/core/uniform-pool-internals.d.ts.map +1 -0
- package/dist/core/uniform-pool-internals.js +24 -0
- package/dist/core/uniform-pool-internals.js.map +1 -0
- package/dist/core/uniform-pool-types.d.ts +22 -0
- package/dist/core/uniform-pool-types.d.ts.map +1 -0
- package/dist/core/uniform-pool-types.js +2 -0
- package/dist/core/uniform-pool-types.js.map +1 -0
- package/dist/core/uniform-pool.d.ts +22 -0
- package/dist/core/uniform-pool.d.ts.map +1 -0
- package/dist/core/uniform-pool.js +128 -0
- package/dist/core/uniform-pool.js.map +1 -0
- package/dist/core/uniform.d.ts +55 -0
- package/dist/core/uniform.d.ts.map +1 -0
- package/dist/core/uniform.js +64 -0
- package/dist/core/uniform.js.map +1 -0
- package/dist/core/wgsl-alignment.d.ts +24 -0
- package/dist/core/wgsl-alignment.d.ts.map +1 -0
- package/dist/core/wgsl-alignment.js +81 -0
- package/dist/core/wgsl-alignment.js.map +1 -0
- package/dist/core.d.ts +13 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +7 -0
- package/dist/core.js.map +1 -0
- package/dist/dom.d.ts +37 -0
- package/dist/dom.d.ts.map +1 -0
- package/dist/dom.js +81 -0
- package/dist/dom.js.map +1 -0
- package/dist/draw-protocols.d.ts +36 -0
- package/dist/draw-protocols.d.ts.map +1 -0
- package/dist/draw-protocols.js +10 -0
- package/dist/draw-protocols.js.map +1 -0
- package/dist/draw.d.ts +248 -0
- package/dist/draw.d.ts.map +1 -0
- package/dist/draw.js +890 -0
- package/dist/draw.js.map +1 -0
- package/dist/effect.d.ts +53 -0
- package/dist/effect.d.ts.map +1 -0
- package/dist/effect.js +75 -0
- package/dist/effect.js.map +1 -0
- package/dist/entry-metadata.d.ts +16 -0
- package/dist/entry-metadata.d.ts.map +1 -0
- package/dist/entry-metadata.js +27 -0
- package/dist/entry-metadata.js.map +1 -0
- package/dist/errors.d.ts +96 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +616 -0
- package/dist/errors.js.map +1 -0
- package/dist/frame-protocols.d.ts +107 -0
- package/dist/frame-protocols.d.ts.map +1 -0
- package/dist/frame-protocols.js +20 -0
- package/dist/frame-protocols.js.map +1 -0
- package/dist/frame-state.d.ts +32 -0
- package/dist/frame-state.d.ts.map +1 -0
- package/dist/frame-state.js +62 -0
- package/dist/frame-state.js.map +1 -0
- package/dist/frame.d.ts +127 -0
- package/dist/frame.d.ts.map +1 -0
- package/dist/frame.js +645 -0
- package/dist/frame.js.map +1 -0
- package/dist/group-claim.d.ts +9 -0
- package/dist/group-claim.d.ts.map +1 -0
- package/dist/group-claim.js +7 -0
- package/dist/group-claim.js.map +1 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/indirect.d.ts +39 -0
- package/dist/indirect.d.ts.map +1 -0
- package/dist/indirect.js +61 -0
- package/dist/indirect.js.map +1 -0
- package/dist/init-from-device.d.ts +11 -0
- package/dist/init-from-device.d.ts.map +1 -0
- package/dist/init-from-device.js +56 -0
- package/dist/init-from-device.js.map +1 -0
- package/dist/init.d.ts +12 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +7 -0
- package/dist/init.js.map +1 -0
- package/dist/kernel.d.ts +104 -0
- package/dist/kernel.d.ts.map +1 -0
- package/dist/kernel.js +151 -0
- package/dist/kernel.js.map +1 -0
- package/dist/lifecycle.d.ts +10 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle.js +21 -0
- package/dist/lifecycle.js.map +1 -0
- package/dist/live-kernel.d.ts +48 -0
- package/dist/live-kernel.d.ts.map +1 -0
- package/dist/live-kernel.js +67 -0
- package/dist/live-kernel.js.map +1 -0
- package/dist/mock.d.ts +42 -0
- package/dist/mock.d.ts.map +1 -0
- package/dist/mock.js +29 -0
- package/dist/mock.js.map +1 -0
- package/dist/node.d.ts +48 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +36 -0
- package/dist/node.js.map +1 -0
- package/dist/ping-pong.d.ts +19 -0
- package/dist/ping-pong.d.ts.map +1 -0
- package/dist/ping-pong.js +67 -0
- package/dist/ping-pong.js.map +1 -0
- package/dist/pipeline-store.d.ts +89 -0
- package/dist/pipeline-store.d.ts.map +1 -0
- package/dist/pipeline-store.js +366 -0
- package/dist/pipeline-store.js.map +1 -0
- package/dist/query-ring.d.ts +91 -0
- package/dist/query-ring.d.ts.map +1 -0
- package/dist/query-ring.js +178 -0
- package/dist/query-ring.js.map +1 -0
- package/dist/render-service.d.ts +23 -0
- package/dist/render-service.d.ts.map +1 -0
- package/dist/render-service.js +37 -0
- package/dist/render-service.js.map +1 -0
- package/dist/sampler.d.ts +19 -0
- package/dist/sampler.d.ts.map +1 -0
- package/dist/sampler.js +46 -0
- package/dist/sampler.js.map +1 -0
- package/dist/scene/camera.d.ts +91 -0
- package/dist/scene/camera.d.ts.map +1 -0
- package/dist/scene/camera.js +221 -0
- package/dist/scene/camera.js.map +1 -0
- package/dist/scene/geometries.d.ts +26 -0
- package/dist/scene/geometries.d.ts.map +1 -0
- package/dist/scene/geometries.js +26 -0
- package/dist/scene/geometries.js.map +1 -0
- package/dist/scene/geometry-descriptor.d.ts +120 -0
- package/dist/scene/geometry-descriptor.d.ts.map +1 -0
- package/dist/scene/geometry-descriptor.js +378 -0
- package/dist/scene/geometry-descriptor.js.map +1 -0
- package/dist/scene/geometry-recipe.d.ts +41 -0
- package/dist/scene/geometry-recipe.d.ts.map +1 -0
- package/dist/scene/geometry-recipe.js +40 -0
- package/dist/scene/geometry-recipe.js.map +1 -0
- package/dist/scene/geometry-src/camera-math.d.ts +6 -0
- package/dist/scene/geometry-src/camera-math.d.ts.map +1 -0
- package/dist/scene/geometry-src/camera-math.js +47 -0
- package/dist/scene/geometry-src/camera-math.js.map +1 -0
- package/dist/scene/geometry-src/camera.d.ts +10 -0
- package/dist/scene/geometry-src/camera.d.ts.map +1 -0
- package/dist/scene/geometry-src/camera.js +2 -0
- package/dist/scene/geometry-src/camera.js.map +1 -0
- package/dist/scene/geometry-src/capsule-data.d.ts +10 -0
- package/dist/scene/geometry-src/capsule-data.d.ts.map +1 -0
- package/dist/scene/geometry-src/capsule-data.js +61 -0
- package/dist/scene/geometry-src/capsule-data.js.map +1 -0
- package/dist/scene/geometry-src/cone-data.d.ts +13 -0
- package/dist/scene/geometry-src/cone-data.d.ts.map +1 -0
- package/dist/scene/geometry-src/cone-data.js +52 -0
- package/dist/scene/geometry-src/cone-data.js.map +1 -0
- package/dist/scene/geometry-src/cylinder-data.d.ts +14 -0
- package/dist/scene/geometry-src/cylinder-data.d.ts.map +1 -0
- package/dist/scene/geometry-src/cylinder-data.js +58 -0
- package/dist/scene/geometry-src/cylinder-data.js.map +1 -0
- package/dist/scene/geometry-src/deg-to-rad.d.ts +2 -0
- package/dist/scene/geometry-src/deg-to-rad.d.ts.map +1 -0
- package/dist/scene/geometry-src/deg-to-rad.js +4 -0
- package/dist/scene/geometry-src/deg-to-rad.js.map +1 -0
- package/dist/scene/geometry-src/disk-data.d.ts +12 -0
- package/dist/scene/geometry-src/disk-data.d.ts.map +1 -0
- package/dist/scene/geometry-src/disk-data.js +21 -0
- package/dist/scene/geometry-src/disk-data.js.map +1 -0
- package/dist/scene/geometry-src/errors.d.ts +3 -0
- package/dist/scene/geometry-src/errors.d.ts.map +1 -0
- package/dist/scene/geometry-src/errors.js +5 -0
- package/dist/scene/geometry-src/errors.js.map +1 -0
- package/dist/scene/geometry-src/icosphere-data.d.ts +8 -0
- package/dist/scene/geometry-src/icosphere-data.d.ts.map +1 -0
- package/dist/scene/geometry-src/icosphere-data.js +58 -0
- package/dist/scene/geometry-src/icosphere-data.js.map +1 -0
- package/dist/scene/geometry-src/index.d.ts +36 -0
- package/dist/scene/geometry-src/index.d.ts.map +1 -0
- package/dist/scene/geometry-src/index.js +21 -0
- package/dist/scene/geometry-src/index.js.map +1 -0
- package/dist/scene/geometry-src/mesh-box.d.ts +8 -0
- package/dist/scene/geometry-src/mesh-box.d.ts.map +1 -0
- package/dist/scene/geometry-src/mesh-box.js +57 -0
- package/dist/scene/geometry-src/mesh-box.js.map +1 -0
- package/dist/scene/geometry-src/mesh-cache.d.ts +4 -0
- package/dist/scene/geometry-src/mesh-cache.d.ts.map +1 -0
- package/dist/scene/geometry-src/mesh-cache.js +14 -0
- package/dist/scene/geometry-src/mesh-cache.js.map +1 -0
- package/dist/scene/geometry-src/mesh-capsule.d.ts +14 -0
- package/dist/scene/geometry-src/mesh-capsule.d.ts.map +1 -0
- package/dist/scene/geometry-src/mesh-capsule.js +52 -0
- package/dist/scene/geometry-src/mesh-capsule.js.map +1 -0
- package/dist/scene/geometry-src/mesh-cone.d.ts +16 -0
- package/dist/scene/geometry-src/mesh-cone.d.ts.map +1 -0
- package/dist/scene/geometry-src/mesh-cone.js +54 -0
- package/dist/scene/geometry-src/mesh-cone.js.map +1 -0
- package/dist/scene/geometry-src/mesh-cylinder.d.ts +18 -0
- package/dist/scene/geometry-src/mesh-cylinder.d.ts.map +1 -0
- package/dist/scene/geometry-src/mesh-cylinder.js +67 -0
- package/dist/scene/geometry-src/mesh-cylinder.js.map +1 -0
- package/dist/scene/geometry-src/mesh-disk.d.ts +11 -0
- package/dist/scene/geometry-src/mesh-disk.d.ts.map +1 -0
- package/dist/scene/geometry-src/mesh-disk.js +45 -0
- package/dist/scene/geometry-src/mesh-disk.js.map +1 -0
- package/dist/scene/geometry-src/mesh-dodecahedron.d.ts +4 -0
- package/dist/scene/geometry-src/mesh-dodecahedron.d.ts.map +1 -0
- package/dist/scene/geometry-src/mesh-dodecahedron.js +10 -0
- package/dist/scene/geometry-src/mesh-dodecahedron.js.map +1 -0
- package/dist/scene/geometry-src/mesh-fullscreen-quad.d.ts +7 -0
- package/dist/scene/geometry-src/mesh-fullscreen-quad.d.ts.map +1 -0
- package/dist/scene/geometry-src/mesh-fullscreen-quad.js +39 -0
- package/dist/scene/geometry-src/mesh-fullscreen-quad.js.map +1 -0
- package/dist/scene/geometry-src/mesh-icosahedron.d.ts +4 -0
- package/dist/scene/geometry-src/mesh-icosahedron.d.ts.map +1 -0
- package/dist/scene/geometry-src/mesh-icosahedron.js +10 -0
- package/dist/scene/geometry-src/mesh-icosahedron.js.map +1 -0
- package/dist/scene/geometry-src/mesh-icosphere.d.ts +11 -0
- package/dist/scene/geometry-src/mesh-icosphere.d.ts.map +1 -0
- package/dist/scene/geometry-src/mesh-icosphere.js +47 -0
- package/dist/scene/geometry-src/mesh-icosphere.js.map +1 -0
- package/dist/scene/geometry-src/mesh-octahedron.d.ts +4 -0
- package/dist/scene/geometry-src/mesh-octahedron.d.ts.map +1 -0
- package/dist/scene/geometry-src/mesh-octahedron.js +10 -0
- package/dist/scene/geometry-src/mesh-octahedron.js.map +1 -0
- package/dist/scene/geometry-src/mesh-plane.d.ts +13 -0
- package/dist/scene/geometry-src/mesh-plane.d.ts.map +1 -0
- package/dist/scene/geometry-src/mesh-plane.js +51 -0
- package/dist/scene/geometry-src/mesh-plane.js.map +1 -0
- package/dist/scene/geometry-src/mesh-ring.d.ts +12 -0
- package/dist/scene/geometry-src/mesh-ring.d.ts.map +1 -0
- package/dist/scene/geometry-src/mesh-ring.js +47 -0
- package/dist/scene/geometry-src/mesh-ring.js.map +1 -0
- package/dist/scene/geometry-src/mesh-sphere.d.ts +10 -0
- package/dist/scene/geometry-src/mesh-sphere.d.ts.map +1 -0
- package/dist/scene/geometry-src/mesh-sphere.js +51 -0
- package/dist/scene/geometry-src/mesh-sphere.js.map +1 -0
- package/dist/scene/geometry-src/mesh-tetrahedron.d.ts +5 -0
- package/dist/scene/geometry-src/mesh-tetrahedron.d.ts.map +1 -0
- package/dist/scene/geometry-src/mesh-tetrahedron.js +10 -0
- package/dist/scene/geometry-src/mesh-tetrahedron.js.map +1 -0
- package/dist/scene/geometry-src/mesh-torus.d.ts +17 -0
- package/dist/scene/geometry-src/mesh-torus.d.ts.map +1 -0
- package/dist/scene/geometry-src/mesh-torus.js +56 -0
- package/dist/scene/geometry-src/mesh-torus.js.map +1 -0
- package/dist/scene/geometry-src/mesh-types.d.ts +38 -0
- package/dist/scene/geometry-src/mesh-types.d.ts.map +1 -0
- package/dist/scene/geometry-src/mesh-types.js +2 -0
- package/dist/scene/geometry-src/mesh-types.js.map +1 -0
- package/dist/scene/geometry-src/mesh.d.ts +61 -0
- package/dist/scene/geometry-src/mesh.d.ts.map +1 -0
- package/dist/scene/geometry-src/mesh.js +49 -0
- package/dist/scene/geometry-src/mesh.js.map +1 -0
- package/dist/scene/geometry-src/orthographic-camera.d.ts +14 -0
- package/dist/scene/geometry-src/orthographic-camera.d.ts.map +1 -0
- package/dist/scene/geometry-src/orthographic-camera.js +9 -0
- package/dist/scene/geometry-src/orthographic-camera.js.map +1 -0
- package/dist/scene/geometry-src/perspective-camera.d.ts +12 -0
- package/dist/scene/geometry-src/perspective-camera.d.ts.map +1 -0
- package/dist/scene/geometry-src/perspective-camera.js +9 -0
- package/dist/scene/geometry-src/perspective-camera.js.map +1 -0
- package/dist/scene/geometry-src/plane-data.d.ts +12 -0
- package/dist/scene/geometry-src/plane-data.d.ts.map +1 -0
- package/dist/scene/geometry-src/plane-data.js +25 -0
- package/dist/scene/geometry-src/plane-data.js.map +1 -0
- package/dist/scene/geometry-src/polyhedron-data.d.ts +7 -0
- package/dist/scene/geometry-src/polyhedron-data.d.ts.map +1 -0
- package/dist/scene/geometry-src/polyhedron-data.js +42 -0
- package/dist/scene/geometry-src/polyhedron-data.js.map +1 -0
- package/dist/scene/geometry-src/polyhedron-mesh.d.ts +10 -0
- package/dist/scene/geometry-src/polyhedron-mesh.d.ts.map +1 -0
- package/dist/scene/geometry-src/polyhedron-mesh.js +37 -0
- package/dist/scene/geometry-src/polyhedron-mesh.js.map +1 -0
- package/dist/scene/geometry-src/polyhedron-seeds.d.ts +6 -0
- package/dist/scene/geometry-src/polyhedron-seeds.d.ts.map +1 -0
- package/dist/scene/geometry-src/polyhedron-seeds.js +51 -0
- package/dist/scene/geometry-src/polyhedron-seeds.js.map +1 -0
- package/dist/scene/geometry-src/primitive-data-utils.d.ts +9 -0
- package/dist/scene/geometry-src/primitive-data-utils.d.ts.map +1 -0
- package/dist/scene/geometry-src/primitive-data-utils.js +36 -0
- package/dist/scene/geometry-src/primitive-data-utils.js.map +1 -0
- package/dist/scene/geometry-src/ring-data.d.ts +13 -0
- package/dist/scene/geometry-src/ring-data.d.ts.map +1 -0
- package/dist/scene/geometry-src/ring-data.js +24 -0
- package/dist/scene/geometry-src/ring-data.js.map +1 -0
- package/dist/scene/geometry-src/sphere-data.d.ts +11 -0
- package/dist/scene/geometry-src/sphere-data.d.ts.map +1 -0
- package/dist/scene/geometry-src/sphere-data.js +31 -0
- package/dist/scene/geometry-src/sphere-data.js.map +1 -0
- package/dist/scene/geometry-src/srgb.d.ts +5 -0
- package/dist/scene/geometry-src/srgb.d.ts.map +1 -0
- package/dist/scene/geometry-src/srgb.js +23 -0
- package/dist/scene/geometry-src/srgb.js.map +1 -0
- package/dist/scene/geometry-src/torus-data.d.ts +11 -0
- package/dist/scene/geometry-src/torus-data.d.ts.map +1 -0
- package/dist/scene/geometry-src/torus-data.js +38 -0
- package/dist/scene/geometry-src/torus-data.js.map +1 -0
- package/dist/scene/geometry-src/vertex-layout.d.ts +2 -0
- package/dist/scene/geometry-src/vertex-layout.d.ts.map +1 -0
- package/dist/scene/geometry-src/vertex-layout.js +2 -0
- package/dist/scene/geometry-src/vertex-layout.js.map +1 -0
- package/dist/scene/geometry.d.ts +70 -0
- package/dist/scene/geometry.d.ts.map +1 -0
- package/dist/scene/geometry.js +71 -0
- package/dist/scene/geometry.js.map +1 -0
- package/dist/scene/orbit.d.ts +9 -0
- package/dist/scene/orbit.d.ts.map +1 -0
- package/dist/scene/orbit.js +15 -0
- package/dist/scene/orbit.js.map +1 -0
- package/dist/scene/tree/errors.d.ts +4 -0
- package/dist/scene/tree/errors.d.ts.map +1 -0
- package/dist/scene/tree/errors.js +19 -0
- package/dist/scene/tree/errors.js.map +1 -0
- package/dist/scene/tree/light.d.ts +42 -0
- package/dist/scene/tree/light.d.ts.map +1 -0
- package/dist/scene/tree/light.js +102 -0
- package/dist/scene/tree/light.js.map +1 -0
- package/dist/scene/tree/material.d.ts +79 -0
- package/dist/scene/tree/material.d.ts.map +1 -0
- package/dist/scene/tree/material.js +117 -0
- package/dist/scene/tree/material.js.map +1 -0
- package/dist/scene/tree/math.d.ts +26 -0
- package/dist/scene/tree/math.d.ts.map +1 -0
- package/dist/scene/tree/math.js +217 -0
- package/dist/scene/tree/math.js.map +1 -0
- package/dist/scene/tree/mesh-node.d.ts +17 -0
- package/dist/scene/tree/mesh-node.d.ts.map +1 -0
- package/dist/scene/tree/mesh-node.js +24 -0
- package/dist/scene/tree/mesh-node.js.map +1 -0
- package/dist/scene/tree/node.d.ts +70 -0
- package/dist/scene/tree/node.d.ts.map +1 -0
- package/dist/scene/tree/node.js +220 -0
- package/dist/scene/tree/node.js.map +1 -0
- package/dist/scene/tree/orbit-controls.d.ts +69 -0
- package/dist/scene/tree/orbit-controls.d.ts.map +1 -0
- package/dist/scene/tree/orbit-controls.js +226 -0
- package/dist/scene/tree/orbit-controls.js.map +1 -0
- package/dist/scene.d.ts +21 -0
- package/dist/scene.d.ts.map +1 -0
- package/dist/scene.js +11 -0
- package/dist/scene.js.map +1 -0
- package/dist/set-core.d.ts +50 -0
- package/dist/set-core.d.ts.map +1 -0
- package/dist/set-core.js +268 -0
- package/dist/set-core.js.map +1 -0
- package/dist/set-layouts.d.ts +20 -0
- package/dist/set-layouts.d.ts.map +1 -0
- package/dist/set-layouts.js +103 -0
- package/dist/set-layouts.js.map +1 -0
- package/dist/set-packing.d.ts +4 -0
- package/dist/set-packing.d.ts.map +1 -0
- package/dist/set-packing.js +82 -0
- package/dist/set-packing.js.map +1 -0
- package/dist/set-resources.d.ts +20 -0
- package/dist/set-resources.d.ts.map +1 -0
- package/dist/set-resources.js +140 -0
- package/dist/set-resources.js.map +1 -0
- package/dist/shader-source.d.ts +4 -0
- package/dist/shader-source.d.ts.map +1 -0
- package/dist/shader-source.js +21 -0
- package/dist/shader-source.js.map +1 -0
- package/dist/storage.d.ts +38 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +76 -0
- package/dist/storage.js.map +1 -0
- package/dist/surface.d.ts +89 -0
- package/dist/surface.d.ts.map +1 -0
- package/dist/surface.js +243 -0
- package/dist/surface.js.map +1 -0
- package/dist/target-offscreen.d.ts +41 -0
- package/dist/target-offscreen.d.ts.map +1 -0
- package/dist/target-offscreen.js +115 -0
- package/dist/target-offscreen.js.map +1 -0
- package/dist/target-utils.d.ts +37 -0
- package/dist/target-utils.d.ts.map +1 -0
- package/dist/target-utils.js +103 -0
- package/dist/target-utils.js.map +1 -0
- package/dist/target.d.ts +65 -0
- package/dist/target.d.ts.map +1 -0
- package/dist/target.js +2 -0
- package/dist/target.js.map +1 -0
- package/dist/timer.d.ts +78 -0
- package/dist/timer.d.ts.map +1 -0
- package/dist/timer.js +261 -0
- package/dist/timer.js.map +1 -0
- package/dist/uniforms-layout.d.ts +8 -0
- package/dist/uniforms-layout.d.ts.map +1 -0
- package/dist/uniforms-layout.js +84 -0
- package/dist/uniforms-layout.js.map +1 -0
- package/dist/uniforms.d.ts +43 -0
- package/dist/uniforms.d.ts.map +1 -0
- package/dist/uniforms.js +176 -0
- package/dist/uniforms.js.map +1 -0
- package/dist/visibility.d.ts +118 -0
- package/dist/visibility.d.ts.map +1 -0
- package/dist/visibility.js +290 -0
- package/dist/visibility.js.map +1 -0
- package/package.json +131 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { mkdtempSync, readdirSync, readFileSync, rmSync, statSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { dirname, join, relative, resolve } from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { computeStamp, generateDocs } from "./generate.js";
|
|
7
|
+
|
|
8
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const root = resolve(here, "../../../../..");
|
|
10
|
+
const committedSkillDir = resolve(root, "skills/aigpu");
|
|
11
|
+
const committedManifestOut = resolve(root, "packages/aigpu-cli/lib/generated/docs-manifest.generated.js");
|
|
12
|
+
const scratch = mkdtempSync(join(tmpdir(), "aigpu-skill-drift-"));
|
|
13
|
+
const freshSkillDir = join(scratch, "skill");
|
|
14
|
+
const freshManifestOut = join(scratch, "manifest.js");
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
generateDocs({ root, skillDir: freshSkillDir, manifestOut: freshManifestOut, stamp: computeStamp(root) });
|
|
18
|
+
const issues = [];
|
|
19
|
+
if (read(committedManifestOut) !== read(freshManifestOut)) issues.push(`docs manifest differs: ${relative(root, committedManifestOut)}`);
|
|
20
|
+
const committed = files(committedSkillDir);
|
|
21
|
+
const fresh = files(freshSkillDir);
|
|
22
|
+
for (const path of fresh) if (!committed.has(path)) issues.push(`missing skill file: skills/aigpu/${path}`);
|
|
23
|
+
for (const path of committed) if (!fresh.has(path)) issues.push(`stale skill file: skills/aigpu/${path}`);
|
|
24
|
+
for (const path of committed) {
|
|
25
|
+
if (!fresh.has(path)) continue;
|
|
26
|
+
const left = normalizeStamp(path, read(join(committedSkillDir, path)));
|
|
27
|
+
const right = normalizeStamp(path, read(join(freshSkillDir, path)));
|
|
28
|
+
if (left !== right) issues.push(`skill content differs: skills/aigpu/${path}`);
|
|
29
|
+
}
|
|
30
|
+
if (issues.length) {
|
|
31
|
+
console.error("AIGpu docs or skill output is out of date. Run `pnpm --dir packages/aigpu-cli generate:docs`.");
|
|
32
|
+
for (const issue of issues) console.error(` - ${issue}`);
|
|
33
|
+
process.exitCode = 1;
|
|
34
|
+
} else {
|
|
35
|
+
console.log("AIGpu docs manifest and skill are current.");
|
|
36
|
+
}
|
|
37
|
+
} finally {
|
|
38
|
+
rmSync(scratch, { recursive: true, force: true });
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function files(directory) {
|
|
42
|
+
const result = new Set();
|
|
43
|
+
const walk = (current) => {
|
|
44
|
+
for (const entry of readdirSync(current, { withFileTypes: true })) {
|
|
45
|
+
const path = join(current, entry.name);
|
|
46
|
+
if (entry.isDirectory()) walk(path);
|
|
47
|
+
else result.add(relative(directory, path));
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
if (statSync(directory).isDirectory()) walk(directory);
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function read(path) {
|
|
55
|
+
try { return readFileSync(path, "utf8"); } catch { return null; }
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function normalizeStamp(path, content) {
|
|
59
|
+
if (path !== "SKILL.md" || content === null) return content;
|
|
60
|
+
return content.replace(/^(gitSha|generatedAt): .*$/gmu, "$1: <stamp>");
|
|
61
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { computeStamp, generateDocs } from "./generate.js";
|
|
5
|
+
|
|
6
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const root = resolve(here, "../../../../..");
|
|
8
|
+
const manifestOut = resolve(root, "packages/aigpu-cli/lib/generated/docs-manifest.generated.js");
|
|
9
|
+
const skillDir = resolve(root, "skills/aigpu");
|
|
10
|
+
const { manifest } = generateDocs({ root, skillDir, manifestOut, stamp: computeStamp(root) });
|
|
11
|
+
const guideCount = manifest.records.filter((record) => record.kind === "guide").length;
|
|
12
|
+
console.log(`docs: ${manifest.records.length} records (${guideCount} guides) → manifest + skill at ${skillDir}`);
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// Shared core for one docs-generation run: builds the manifest from docs/allowlist.txt +
|
|
2
|
+
// docs/topics, then writes the manifest + skill mirror. Used by both cli.js (writes into the
|
|
3
|
+
// repo's committed skills/aigpu) and check-drift.js (writes into a scratch temp dir so it can diff
|
|
4
|
+
// against the committed copy without touching the working tree).
|
|
5
|
+
import { execSync } from "node:child_process";
|
|
6
|
+
import {
|
|
7
|
+
existsSync,
|
|
8
|
+
mkdirSync,
|
|
9
|
+
readFileSync,
|
|
10
|
+
readdirSync,
|
|
11
|
+
renameSync,
|
|
12
|
+
rmdirSync,
|
|
13
|
+
rmSync,
|
|
14
|
+
writeFileSync,
|
|
15
|
+
} from "node:fs";
|
|
16
|
+
import { dirname, resolve } from "node:path";
|
|
17
|
+
import { createManifest, serializeManifest } from "./manifest.js";
|
|
18
|
+
import { buildSkill } from "./skill.js";
|
|
19
|
+
|
|
20
|
+
// Writes are atomic (temp file in the same directory, then rename) because this generator runs
|
|
21
|
+
// as `prepack` for both packages/aigpu and packages/aigpu-api. `npm pack` and the docs tests can
|
|
22
|
+
// therefore run it concurrently, and a half-written file would be read by whichever sibling is
|
|
23
|
+
// mid-run. Temp names carry the pid so two runs never collide on one temp path.
|
|
24
|
+
const TEMP_SUFFIX = /\.\d+\.tmp$/u;
|
|
25
|
+
|
|
26
|
+
function writeAtomic(outPath, content) {
|
|
27
|
+
mkdirSync(dirname(outPath), { recursive: true });
|
|
28
|
+
const temp = `${outPath}.${process.pid}.tmp`;
|
|
29
|
+
writeFileSync(temp, content);
|
|
30
|
+
renameSync(temp, outPath);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Regenerate in place and then prune, NOT wipe-and-rebuild: a recursive wipe of this tree races
|
|
34
|
+
// concurrent runs (rimraf fails with ENOTEMPTY when a sibling recreates a file mid-walk, and
|
|
35
|
+
// readers briefly see no docs at all). Writing every file first and only then deleting what the
|
|
36
|
+
// manifest no longer produces keeps the "no stale files" guarantee while making concurrent runs
|
|
37
|
+
// idempotent instead of destructive. Depth-first so directories are considered after their
|
|
38
|
+
// contents.
|
|
39
|
+
function prune(dir, expected) {
|
|
40
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
41
|
+
const full = resolve(dir, entry.name);
|
|
42
|
+
if (entry.isDirectory()) {
|
|
43
|
+
prune(full, expected);
|
|
44
|
+
try {
|
|
45
|
+
rmdirSync(full);
|
|
46
|
+
} catch {}
|
|
47
|
+
} else if (!expected.has(full) && !TEMP_SUFFIX.test(entry.name)) {
|
|
48
|
+
rmSync(full, { force: true });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Frontmatter stamp for the generated SKILL.md: the aigpu package version + the commit + date this
|
|
55
|
+
* generation ran from, so a stale installed skill is detectable in the frontmatter by a human or
|
|
56
|
+
* an agent without diffing anything. gitSha/generatedAt are intentionally volatile — they change on
|
|
57
|
+
* every run by design — so check-drift.js normalizes them away before comparing; a stamp-only
|
|
58
|
+
* difference between two generations is never reported as drift.
|
|
59
|
+
*/
|
|
60
|
+
export function computeStamp(root) {
|
|
61
|
+
// NB: the public "aigpu" package (what `npx -y aigpu` runs) lives at packages/aigpu-api — the
|
|
62
|
+
// "packages/aigpu" directory is the (private) @aigpu/cli package that hosts this generator.
|
|
63
|
+
let aigpuVersion = "unknown";
|
|
64
|
+
try {
|
|
65
|
+
aigpuVersion = JSON.parse(readFileSync(resolve(root, "packages/aigpu-api/package.json"), "utf8")).version;
|
|
66
|
+
} catch {}
|
|
67
|
+
|
|
68
|
+
let gitSha = "unknown";
|
|
69
|
+
try {
|
|
70
|
+
gitSha = execSync("git rev-parse HEAD", { cwd: root, stdio: ["ignore", "pipe", "ignore"] })
|
|
71
|
+
.toString()
|
|
72
|
+
.trim();
|
|
73
|
+
} catch {}
|
|
74
|
+
|
|
75
|
+
return { aigpuVersion, gitSha, generatedAt: new Date().toISOString() };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function loadManifest(root) {
|
|
79
|
+
const allowlistPath = resolve(root, "docs/allowlist.txt");
|
|
80
|
+
const topicsDir = resolve(root, "docs/topics");
|
|
81
|
+
// Guide docs (conceptual topics) are auto-discovered from docs/topics — no allowlist entry needed.
|
|
82
|
+
const guides = existsSync(topicsDir)
|
|
83
|
+
? readdirSync(topicsDir)
|
|
84
|
+
.filter((file) => file.endsWith(".docs.md"))
|
|
85
|
+
.sort()
|
|
86
|
+
.map((file) => `docs/topics/${file}`)
|
|
87
|
+
: [];
|
|
88
|
+
|
|
89
|
+
return createManifest(readFileSync(allowlistPath, "utf8"), {
|
|
90
|
+
exists: (path) => existsSync(resolve(root, path)),
|
|
91
|
+
read: (path) => readFileSync(resolve(root, path), "utf8"),
|
|
92
|
+
guides,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Runs one full generation: manifest + skill mirror (SKILL.md router + references/<doc>), written
|
|
98
|
+
* to the given output paths. Returns the manifest so callers can log stats.
|
|
99
|
+
*/
|
|
100
|
+
export function generateDocs({ root, skillDir, manifestOut, stamp }) {
|
|
101
|
+
const manifest = loadManifest(root);
|
|
102
|
+
writeAtomic(manifestOut, `export const docsManifest = ${serializeManifest(manifest)};`);
|
|
103
|
+
|
|
104
|
+
const expected = new Set();
|
|
105
|
+
for (const [relativePath, content] of buildSkill(manifest, stamp)) {
|
|
106
|
+
const outPath = resolve(skillDir, relativePath);
|
|
107
|
+
expected.add(outPath);
|
|
108
|
+
writeAtomic(outPath, content);
|
|
109
|
+
}
|
|
110
|
+
if (existsSync(skillDir)) prune(skillDir, expected);
|
|
111
|
+
|
|
112
|
+
return { manifest };
|
|
113
|
+
}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { MANIFEST_VERSION } from "../model.js";
|
|
3
|
+
|
|
4
|
+
export function parseAllowlist(text) {
|
|
5
|
+
return text.split(/\r?\n/u).map((line) => line.trim()).filter(Boolean).map((line) => {
|
|
6
|
+
const [packageName, symbol, repoPath, ...extra] = line.split(/\s+/u);
|
|
7
|
+
if (!packageName || !symbol || !repoPath || extra.length > 0) throw new Error(`Invalid allowlist line: ${line}`);
|
|
8
|
+
return { package: packageName, symbol, repoPath };
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function virtualPathFor(entry) {
|
|
13
|
+
return `/${entry.package}/${entry.repoPath.split("/").at(-1)}`;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Guide docs are conceptual topics (not tied to an exported symbol). They live under the synthetic
|
|
17
|
+
// "guides" package; the symbol is the file slug so `aigpu docs cat <slug>` resolves.
|
|
18
|
+
export function guideEntryFor(repoPath) {
|
|
19
|
+
const file = repoPath.split("/").at(-1);
|
|
20
|
+
return { package: "guides", symbol: file.replace(/\.docs\.md$/u, ""), repoPath };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function guideVirtualPathFor(repoPath) {
|
|
24
|
+
return `/guides/${repoPath.split("/").at(-1)}`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Builds the docs manifest from the allowlist (per-symbol API docs) and an optional list of guide
|
|
29
|
+
* doc paths (conceptual topics under docs/topics). Every record carries a `kind` ("api" | "guide").
|
|
30
|
+
*/
|
|
31
|
+
export function createManifest(allowlistText, options = {}) {
|
|
32
|
+
const read = options.read ?? ((path) => readFileSync(path, "utf8"));
|
|
33
|
+
const exists = options.exists ?? (() => true);
|
|
34
|
+
const load = (repoPath) => {
|
|
35
|
+
if (!exists(repoPath)) throw new Error(`Missing docs file: ${repoPath}`);
|
|
36
|
+
return read(repoPath).replace(/\r\n/gu, "\n");
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const apiRecords = parseAllowlist(allowlistText).map((entry) => enrichRecord({
|
|
40
|
+
...entry,
|
|
41
|
+
kind: "api",
|
|
42
|
+
virtualPath: virtualPathFor(entry),
|
|
43
|
+
content: load(entry.repoPath),
|
|
44
|
+
}));
|
|
45
|
+
|
|
46
|
+
const guideRecords = (options.guides ?? []).map((repoPath) => enrichRecord({
|
|
47
|
+
...guideEntryFor(repoPath),
|
|
48
|
+
kind: "guide",
|
|
49
|
+
virtualPath: guideVirtualPathFor(repoPath),
|
|
50
|
+
content: load(repoPath),
|
|
51
|
+
}));
|
|
52
|
+
|
|
53
|
+
const records = withUniqueAnchors([...apiRecords, ...guideRecords].sort(compareRecord));
|
|
54
|
+
return { schemaVersion: MANIFEST_VERSION, generatedFrom: "docs/allowlist.txt + docs/topics", records };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function serializeManifest(manifest) {
|
|
58
|
+
return `${JSON.stringify(manifest, null, 2)}\n`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function enrichRecord(record) {
|
|
62
|
+
const { body, frontmatter } = parseFrontmatter(record.content);
|
|
63
|
+
const topic = topicForRecord(record);
|
|
64
|
+
const topicTitle = frontmatter.title ?? firstHeading(body) ?? titleFromSlug(topic);
|
|
65
|
+
const anchor = headingAnchorForSymbol(body, record.symbol) ?? slugifyHeading(record.symbol);
|
|
66
|
+
const section = sectionForAnchor(body, anchor) ?? body;
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
...record,
|
|
70
|
+
summary: frontmatter.summary ?? firstParagraph(section) ?? firstParagraph(body) ?? "",
|
|
71
|
+
snippet: firstCodeBlock(section) ?? firstCodeBlock(body) ?? "",
|
|
72
|
+
anchor,
|
|
73
|
+
topic,
|
|
74
|
+
topicTitle,
|
|
75
|
+
...(frontmatter.keywords === undefined ? {} : { keywords: parseKeywords(frontmatter.keywords) }),
|
|
76
|
+
...(frontmatter.order === undefined ? {} : { order: parseOrder(frontmatter.order, record.repoPath) }),
|
|
77
|
+
...(frontmatter.websitePath === undefined ? {} : { websitePath: parseWebsitePath(frontmatter.websitePath, record.repoPath) }),
|
|
78
|
+
symbolKind: frontmatter.symbolKind ?? inferSymbolKind(record.symbol),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function parseFrontmatter(markdown) {
|
|
83
|
+
const match = markdown.match(/^---\n([\s\S]*?)\n---\n?/u);
|
|
84
|
+
if (!match) return { body: markdown, frontmatter: {} };
|
|
85
|
+
const frontmatter = {};
|
|
86
|
+
for (const line of match[1].split("\n")) {
|
|
87
|
+
const item = line.match(/^([A-Za-z][A-Za-z0-9_-]*)\s*:\s*(.*)$/u);
|
|
88
|
+
if (!item) continue;
|
|
89
|
+
const [, key, rawValue] = item;
|
|
90
|
+
frontmatter[key] = rawValue.trim().replace(/^['"]|['"]$/gu, "");
|
|
91
|
+
}
|
|
92
|
+
return { body: markdown.slice(match[0].length), frontmatter };
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Comma-separated search phrases a doc claims for `aigpu docs find`. They exist so a guide can own
|
|
96
|
+
// the words an agent types ("modern bundlers", "wgsl loader", "declare module") even when the body words
|
|
97
|
+
// differ from the query.
|
|
98
|
+
function parseKeywords(value) {
|
|
99
|
+
return [...new Set(value.split(",").map((keyword) => keyword.trim().toLowerCase()).filter(Boolean))];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function parseOrder(value, repoPath) {
|
|
103
|
+
if (!/^-?\d+(?:\.\d+)?$/u.test(value)) {
|
|
104
|
+
throw new Error(`Invalid numeric order in ${repoPath}: ${value}`);
|
|
105
|
+
}
|
|
106
|
+
const order = Number(value);
|
|
107
|
+
if (!Number.isFinite(order)) throw new Error(`Invalid numeric order in ${repoPath}: ${value}`);
|
|
108
|
+
return order;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function parseWebsitePath(value, repoPath) {
|
|
112
|
+
if (!/^\/[a-z0-9]+(?:-[a-z0-9]+)*(?:\/[a-z0-9]+(?:-[a-z0-9]+)*)*$/u.test(value)) {
|
|
113
|
+
throw new Error(`Invalid website path in ${repoPath}: ${value}`);
|
|
114
|
+
}
|
|
115
|
+
return value;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function topicForRecord(record) {
|
|
119
|
+
return topicForRepoPath(record.repoPath);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function topicForRepoPath(repoPath) {
|
|
123
|
+
const parts = repoPath.split("/");
|
|
124
|
+
const file = parts.at(-1);
|
|
125
|
+
if (file === "index.docs.md") return parts.at(-2);
|
|
126
|
+
return file.replace(/\.docs\.md$/u, "");
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function firstHeading(markdown) {
|
|
130
|
+
return markdown.match(/^#\s+(.+)$/mu)?.[1]?.trim();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function titleFromSlug(slug) {
|
|
134
|
+
return slug.split(/[-_]/u).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function headingAnchorForSymbol(markdown, symbol) {
|
|
138
|
+
const symbolSlug = slugifyHeading(symbol);
|
|
139
|
+
const entry = headingEntries(markdown).find((heading) => heading.text === symbol || slugifyHeading(heading.text) === symbolSlug);
|
|
140
|
+
return entry?.anchor ?? null;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function sectionForAnchor(markdown, anchor) {
|
|
144
|
+
const headings = headingEntries(markdown);
|
|
145
|
+
const current = headings.find((heading) => heading.anchor === anchor);
|
|
146
|
+
if (!current) return null;
|
|
147
|
+
const next = headings.find((heading) => heading.index > current.index && heading.level <= current.level);
|
|
148
|
+
return markdown.slice(current.index, next?.index ?? markdown.length);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function headingEntries(markdown) {
|
|
152
|
+
const counts = new Map();
|
|
153
|
+
return [...markdown.matchAll(/^(#{1,6})\s+(.+)$/gmu)].map((match) => {
|
|
154
|
+
const baseAnchor = slugifyHeading(match[2]);
|
|
155
|
+
const count = counts.get(baseAnchor) ?? 0;
|
|
156
|
+
counts.set(baseAnchor, count + 1);
|
|
157
|
+
return {
|
|
158
|
+
level: match[1].length,
|
|
159
|
+
text: match[2].trim(),
|
|
160
|
+
index: match.index ?? 0,
|
|
161
|
+
anchor: count === 0 ? baseAnchor : `${baseAnchor}-${count + 1}`,
|
|
162
|
+
};
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function firstParagraph(markdown) {
|
|
167
|
+
const withoutHeading = markdown.replace(/^#{1,6}\s+.+$/mu, "");
|
|
168
|
+
for (const block of withoutHeading.split(/\n{2,}/u)) {
|
|
169
|
+
const paragraph = block.trim();
|
|
170
|
+
if (!paragraph) continue;
|
|
171
|
+
if (/^(#{1,6}\s+|```|\||-|\*|>|<)/u.test(paragraph)) continue;
|
|
172
|
+
return paragraph.replace(/\s+/gu, " ");
|
|
173
|
+
}
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function firstCodeBlock(markdown) {
|
|
178
|
+
const match = markdown.match(/```[^\n]*\n([\s\S]*?)```/u);
|
|
179
|
+
return match?.[1]?.trim() ?? null;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function inferSymbolKind(symbol) {
|
|
183
|
+
if (/Options$/u.test(symbol)) return "options";
|
|
184
|
+
if (/^[a-z]/u.test(symbol)) return "function";
|
|
185
|
+
if (/^(Gpu|Device|Buffer|Texture|Queue|EditableMesh)$/u.test(symbol)) return "class";
|
|
186
|
+
return "type";
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function withUniqueAnchors(records) {
|
|
190
|
+
const seenByTopic = new Map();
|
|
191
|
+
return records.map((record) => {
|
|
192
|
+
const key = `${record.package}\0${record.repoPath}`;
|
|
193
|
+
const seen = seenByTopic.get(key) ?? new Map();
|
|
194
|
+
const count = seen.get(record.anchor) ?? 0;
|
|
195
|
+
seen.set(record.anchor, count + 1);
|
|
196
|
+
seenByTopic.set(key, seen);
|
|
197
|
+
|
|
198
|
+
if (count === 0) return record;
|
|
199
|
+
return { ...record, anchor: `${record.anchor}-${count + 1}` };
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export function slugifyHeading(value) {
|
|
204
|
+
return value
|
|
205
|
+
.toLowerCase()
|
|
206
|
+
.trim()
|
|
207
|
+
.replace(/[^a-z0-9\s-]/gu, "")
|
|
208
|
+
.replace(/\s+/gu, "-")
|
|
209
|
+
.replace(/-+/gu, "-");
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function escapeRegExp(value) {
|
|
213
|
+
return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function compareRecord(a, b) {
|
|
217
|
+
return `${a.package}\0${a.symbol}\0${a.repoPath}`.localeCompare(`${b.package}\0${b.symbol}\0${b.repoPath}`);
|
|
218
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// Renders a Claude-style skill (SKILL.md router + references/<doc>, one file per doc) from the docs
|
|
2
|
+
// manifest. Same source of truth as the `aigpu docs` CLI — this is just a static, loadable mirror.
|
|
3
|
+
// The router stays small on purpose: it lists the guides + an API index and tells the agent to load
|
|
4
|
+
// one doc at a time (via references/ or the CLI), instead of reading everything.
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @param {object} manifest
|
|
8
|
+
* @param {{ aigpuVersion: string, gitSha: string, generatedAt: string }} [stamp] - Frontmatter stamp
|
|
9
|
+
* for SKILL.md (aigpu package version + generation commit + date). Optional so callers that only
|
|
10
|
+
* care about the reference files (e.g. unit tests) can omit it; the CLI and drift-check always
|
|
11
|
+
* pass one.
|
|
12
|
+
* @returns {Map<string, string>} relative skill path → file content
|
|
13
|
+
*/
|
|
14
|
+
export function buildSkill(manifest, stamp) {
|
|
15
|
+
const docs = uniqueDocs(manifest.records);
|
|
16
|
+
const files = new Map();
|
|
17
|
+
for (const doc of docs) {
|
|
18
|
+
files.set(`references${doc.virtualPath}`, referenceFile(doc));
|
|
19
|
+
}
|
|
20
|
+
files.set("SKILL.md", router(docs, stamp));
|
|
21
|
+
return files;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Many allowlist symbols can map to the same .docs.md; collapse to one reference per file and keep
|
|
25
|
+
// the list of symbols it documents.
|
|
26
|
+
function uniqueDocs(records) {
|
|
27
|
+
const byPath = new Map();
|
|
28
|
+
for (const record of records) {
|
|
29
|
+
const existing = byPath.get(record.virtualPath);
|
|
30
|
+
if (existing) {
|
|
31
|
+
existing.symbols.push(record.symbol);
|
|
32
|
+
} else {
|
|
33
|
+
byPath.set(record.virtualPath, { ...record, symbols: [record.symbol] });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return [...byPath.values()];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function referenceFile(doc) {
|
|
40
|
+
const provenance = `> Source: \`${doc.virtualPath}\` — generated by \`aigpu generate:docs\`. Edit the source .docs.md, not this file.\n\n`;
|
|
41
|
+
return provenance + doc.content.trimEnd() + "\n";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function router(docs, stamp) {
|
|
45
|
+
const guides = docs.filter((d) => d.kind === "guide");
|
|
46
|
+
const concepts = guides.filter((d) => d.symbol.startsWith("concepts-")).sort(byOrderThenSymbol);
|
|
47
|
+
const cliGuides = guides.filter((d) => d.symbol === "cli");
|
|
48
|
+
const performanceGuides = guides.filter((d) => !d.symbol.startsWith("concepts-") && d.symbol !== "cli").sort(bySymbol);
|
|
49
|
+
const api = docs.filter((d) => d.kind === "api");
|
|
50
|
+
const packages = [...new Set(api.map((d) => d.package))].sort();
|
|
51
|
+
const symbolCount = api.reduce((n, d) => n + d.symbols.length, 0);
|
|
52
|
+
|
|
53
|
+
const out = [
|
|
54
|
+
"---",
|
|
55
|
+
"name: aigpu",
|
|
56
|
+
"description: >-",
|
|
57
|
+
" Build and optimize WebGPU apps with the aigpu package and entrypoints aigpu/node,",
|
|
58
|
+
" aigpu/mock, aigpu/scene, and aigpu/client. Use @aigpu/render/inspect, /utils, /edit,",
|
|
59
|
+
" and /perf only as slim tooling subpaths. Bundles performance guides and the API",
|
|
60
|
+
" reference; load one doc at a time.",
|
|
61
|
+
// Stamp: lets a human or agent tell a stale installed skill in one glance. gitSha/generatedAt
|
|
62
|
+
// are volatile by design (change on every regeneration) — check-drift.js normalizes them away
|
|
63
|
+
// before diffing, so they never cause a false drift failure on their own.
|
|
64
|
+
...(stamp
|
|
65
|
+
? [`aigpuVersion: ${stamp.aigpuVersion}`, `gitSha: ${stamp.gitSha}`, `generatedAt: ${stamp.generatedAt}`]
|
|
66
|
+
: []),
|
|
67
|
+
"---",
|
|
68
|
+
"",
|
|
69
|
+
"# aigpu",
|
|
70
|
+
"",
|
|
71
|
+
"Generated from the aigpu `.docs.md` source. Each entry maps to a file in `references/` and to a",
|
|
72
|
+
"doc you can load on demand with the CLI — **load only what you need, don't read the whole skill**:",
|
|
73
|
+
"",
|
|
74
|
+
"aigpu is layered: aigpu/core (thin WebGPU wrappers) → aigpu (main API with WGSL reflection) → aigpu/scene (geometry/camera helpers). Lower layers are always accessible and interoperable.",
|
|
75
|
+
"",
|
|
76
|
+
"Glossary: **Surface** means a canvas-backed render target (swapchain) created with `surface(gpu, canvas)`; do not confuse it with the general phrase ‘API surface’.",
|
|
77
|
+
"",
|
|
78
|
+
"```sh",
|
|
79
|
+
"npx -y aigpu docs find <query> # search doc paths + symbols",
|
|
80
|
+
"npx -y aigpu docs grep -i <term> # search doc CONTENT",
|
|
81
|
+
"npx -y aigpu docs cat <symbol> # print one doc, e.g. `cat Frame`, `cat performance-model`",
|
|
82
|
+
"```",
|
|
83
|
+
"",
|
|
84
|
+
"## Core concepts",
|
|
85
|
+
"",
|
|
86
|
+
];
|
|
87
|
+
for (const guide of concepts) {
|
|
88
|
+
out.push(`- **${guide.topicTitle}** — ${summarize(guide.content)} \`references${guide.virtualPath}\``);
|
|
89
|
+
}
|
|
90
|
+
out.push("");
|
|
91
|
+
out.push("## CLI reference");
|
|
92
|
+
out.push("");
|
|
93
|
+
for (const guide of cliGuides) {
|
|
94
|
+
out.push(`- **${guide.topicTitle}** — ${guide.summary || summarize(guide.content)} \`references${guide.virtualPath}\``);
|
|
95
|
+
}
|
|
96
|
+
out.push("");
|
|
97
|
+
out.push("## Performance guides");
|
|
98
|
+
out.push("");
|
|
99
|
+
out.push("Writing or optimizing a shader? Read **performance-model** first, then the rest as needed.");
|
|
100
|
+
out.push("");
|
|
101
|
+
for (const guide of performanceGuides) {
|
|
102
|
+
out.push(`- **${guide.topicTitle}** — ${summarize(guide.content)} \`references${guide.virtualPath}\``);
|
|
103
|
+
}
|
|
104
|
+
out.push("");
|
|
105
|
+
out.push("## API reference");
|
|
106
|
+
out.push("");
|
|
107
|
+
out.push(`${symbolCount} symbols across ${packages.length} packages — open \`references/<package>/<file>\` or \`npx -y aigpu docs cat <symbol>\`:`);
|
|
108
|
+
out.push("");
|
|
109
|
+
for (const pkg of packages) {
|
|
110
|
+
const symbols = api
|
|
111
|
+
.filter((d) => d.package === pkg)
|
|
112
|
+
.flatMap((d) => d.symbols)
|
|
113
|
+
.sort((a, b) => a.localeCompare(b));
|
|
114
|
+
out.push(`- \`${pkg}\` — ${symbols.join(", ")}`);
|
|
115
|
+
}
|
|
116
|
+
out.push("");
|
|
117
|
+
return out.join("\n");
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function summarize(content) {
|
|
121
|
+
// Collect the first prose paragraph (sentences may wrap across source lines), skipping frontmatter,
|
|
122
|
+
// headings and blockquotes, then take its first sentence.
|
|
123
|
+
const body = content.replace(/^---\n[\s\S]*?\n---\n?/u, "");
|
|
124
|
+
let paragraph = "";
|
|
125
|
+
for (const raw of body.split("\n")) {
|
|
126
|
+
const line = raw.trim();
|
|
127
|
+
if (line.startsWith("#") || line.startsWith(">")) continue;
|
|
128
|
+
if (!line) {
|
|
129
|
+
if (paragraph) break;
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
paragraph = paragraph ? `${paragraph} ${line}` : line;
|
|
133
|
+
}
|
|
134
|
+
const plain = paragraph
|
|
135
|
+
.replace(/\[([^\]]+)\]\([^)]*\)/gu, "$1") // [text](url) -> text
|
|
136
|
+
.replace(/\*\*/gu, "")
|
|
137
|
+
.replace(/`/gu, "")
|
|
138
|
+
.replace(/\s+/gu, " ");
|
|
139
|
+
const sentence = plain.match(/^(.*?\.)(?:\s|$)/u);
|
|
140
|
+
const text = sentence ? sentence[1] : plain;
|
|
141
|
+
return text.length > 150 ? `${text.slice(0, 147).trimEnd()}…` : text;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function byOrderThenSymbol(a, b) {
|
|
145
|
+
return (a.order ?? Number.POSITIVE_INFINITY) - (b.order ?? Number.POSITIVE_INFINITY) || bySymbol(a, b);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function bySymbol(a, b) {
|
|
149
|
+
return a.symbol.localeCompare(b.symbol);
|
|
150
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export const docsHelp = `Usage: aigpu docs <command> [args] [flags]
|
|
2
|
+
|
|
3
|
+
Start here: aigpu docs cat getting-started.md (the guide for using the latest API correctly)
|
|
4
|
+
|
|
5
|
+
Commands:
|
|
6
|
+
ls [path] List packages or docs under a virtual path
|
|
7
|
+
cat <path|symbol> Print docs by virtual path or unique symbol
|
|
8
|
+
grep [-i] [--package <pkg>] <pattern>
|
|
9
|
+
Search docs content; case-sensitive unless -i is used
|
|
10
|
+
find <query> Find docs by name, keyword, or phrase (all words must match)
|
|
11
|
+
path <symbol|path> Resolve a symbol or virtual path for shell usage
|
|
12
|
+
symbols List indexed symbols
|
|
13
|
+
help Show this help
|
|
14
|
+
|
|
15
|
+
Examples:
|
|
16
|
+
aigpu docs cat getting-started.md
|
|
17
|
+
aigpu docs ls /guides
|
|
18
|
+
aigpu docs ls
|
|
19
|
+
aigpu docs cat /@aigpu/core/Buffer.docs.md
|
|
20
|
+
aigpu docs grep -i --package @aigpu/wgsl minify
|
|
21
|
+
aigpu docs path Buffer`;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { docsManifest } from "../generated/docs-manifest.generated.js";
|
|
2
|
+
|
|
3
|
+
export function loadManifest() {
|
|
4
|
+
return docsManifest;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function buildIndex(manifest = loadManifest()) {
|
|
8
|
+
const paths = new Map();
|
|
9
|
+
const symbols = new Map();
|
|
10
|
+
const packages = new Set();
|
|
11
|
+
for (const record of manifest.records) {
|
|
12
|
+
packages.add(record.package);
|
|
13
|
+
push(paths, record.virtualPath, record);
|
|
14
|
+
push(symbols, record.symbol, record);
|
|
15
|
+
}
|
|
16
|
+
return { records: manifest.records, packages: [...packages].sort(comparePackage), paths, symbols };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function resolveSymbol(index, symbol) {
|
|
20
|
+
const records = index.symbols.get(symbol);
|
|
21
|
+
if (!records || records.length === 0) return undefined;
|
|
22
|
+
const unique = uniqueByPath(records);
|
|
23
|
+
return unique.length === 1 ? unique[0] : unique;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function resolvePath(index, path) {
|
|
27
|
+
return uniqueByPath(index.paths.get(normalizePath(path)) ?? []);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function uniqueByPath(records) {
|
|
31
|
+
return [...new Map(records.map((record) => [record.virtualPath, record])).values()];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function normalizePath(path) {
|
|
35
|
+
if (path === "/") return path;
|
|
36
|
+
return path.endsWith("/") ? path.slice(0, -1) : path;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// The repo's declared "what matters most" curation ladder. Exported so `docs find`'s ranking and
|
|
40
|
+
// `docs ls`'s package ordering share one source of truth instead of drifting apart.
|
|
41
|
+
export function packageRank(name) {
|
|
42
|
+
if (name === "guides") return 0;
|
|
43
|
+
if (name === "aigpu") return 1;
|
|
44
|
+
if (name === "aigpu/scene") return 2;
|
|
45
|
+
if (name === "aigpu/core") return 3;
|
|
46
|
+
if (name === "@aigpu/wgsl") return 4;
|
|
47
|
+
if (name === "@aigpu/wgsl/runtime") return 5;
|
|
48
|
+
if (name.startsWith("@aigpu/wgsl/loader-")) return 6;
|
|
49
|
+
if (name.startsWith("@aigpu/wgsl-std/")) return 7;
|
|
50
|
+
if (name.startsWith("@aigpu/render/")) return 8;
|
|
51
|
+
return 9;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function comparePackage(left, right) {
|
|
55
|
+
return packageRank(left) - packageRank(right) || left.localeCompare(right);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function push(map, key, value) {
|
|
59
|
+
const values = map.get(key) ?? [];
|
|
60
|
+
values.push(value);
|
|
61
|
+
map.set(key, values);
|
|
62
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export const MANIFEST_VERSION = 3;
|
|
2
|
+
|
|
3
|
+
/** @typedef {"api" | "guide"} DocsKind */
|
|
4
|
+
/** @typedef {"class" | "function" | "type" | "options"} DocsSymbolKind */
|
|
5
|
+
/** @typedef {{ package: string, symbol: string, repoPath: string, virtualPath: string, content: string, kind: DocsKind, summary: string, snippet: string, anchor: string, topic: string, topicTitle: string, symbolKind: DocsSymbolKind, keywords?: string[] }} DocsRecord */
|
|
6
|
+
/** @typedef {{ schemaVersion: 3, generatedFrom: string, records: DocsRecord[] }} DocsManifest */
|
|
7
|
+
/** @typedef {{ records: DocsRecord[], packages: string[], paths: Map<string, DocsRecord[]>, symbols: Map<string, DocsRecord[]> }} DocsIndex */
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { catCommand } from "./commands/cat.js";
|
|
2
|
+
import { findCommand } from "./commands/find.js";
|
|
3
|
+
import { grepCommand } from "./commands/grep.js";
|
|
4
|
+
import { lsCommand } from "./commands/ls.js";
|
|
5
|
+
import { pathCommand } from "./commands/path.js";
|
|
6
|
+
import { fail, ok } from "./commands/shared.js";
|
|
7
|
+
import { symbolsCommand } from "./commands/symbols.js";
|
|
8
|
+
import { docsHelp } from "./help.js";
|
|
9
|
+
import { buildIndex } from "./index.js";
|
|
10
|
+
|
|
11
|
+
export function runDocs(args) {
|
|
12
|
+
const [command, ...rest] = args;
|
|
13
|
+
if (!command || command === "help" || command === "--help" || command === "-h") return ok(docsHelp);
|
|
14
|
+
const index = buildIndex();
|
|
15
|
+
switch (command) {
|
|
16
|
+
case "ls": return lsCommand(index, rest);
|
|
17
|
+
case "cat": return catCommand(index, rest);
|
|
18
|
+
case "grep": return grepCommand(index, rest);
|
|
19
|
+
case "find": return findCommand(index, rest);
|
|
20
|
+
case "path": return pathCommand(index, rest);
|
|
21
|
+
case "symbols": return symbolsCommand(index, rest);
|
|
22
|
+
default: return fail(`Unknown docs command: ${command}\n\n${docsHelp}`);
|
|
23
|
+
}
|
|
24
|
+
}
|