@solidrt/cli 0.0.40 → 0.0.42
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/package.json +7 -7
- package/scaffold/AGENTS.md +19 -12
- package/scaffold/package.json +4 -4
- package/src/commands/mcp.ts +3 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solidrt/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.42",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Antoine van Wel",
|
|
6
6
|
"type": "module",
|
|
@@ -28,17 +28,17 @@
|
|
|
28
28
|
"zod": "^4.4.3"
|
|
29
29
|
},
|
|
30
30
|
"optionalDependencies": {
|
|
31
|
-
"@solidrt/darwin-arm64": "0.0.
|
|
32
|
-
"@solidrt/linux-arm64-gnu": "0.0.
|
|
33
|
-
"@solidrt/linux-x64-gnu": "0.0.
|
|
34
|
-
"@solidrt/win32-x64-msvc": "0.0.
|
|
31
|
+
"@solidrt/darwin-arm64": "0.0.42",
|
|
32
|
+
"@solidrt/linux-arm64-gnu": "0.0.42",
|
|
33
|
+
"@solidrt/linux-x64-gnu": "0.0.42",
|
|
34
|
+
"@solidrt/win32-x64-msvc": "0.0.42"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@solidrt/core": "0.0.
|
|
37
|
+
"@solidrt/core": "0.0.42",
|
|
38
38
|
"typescript": "^7"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@solidrt/flux-types": "0.0.
|
|
41
|
+
"@solidrt/flux-types": "0.0.42",
|
|
42
42
|
"@types/babel__core": "^7.20.5",
|
|
43
43
|
"@types/bun": "latest"
|
|
44
44
|
}
|
package/scaffold/AGENTS.md
CHANGED
|
@@ -140,9 +140,11 @@ nearly free. That holds on desktop and on current mobile hardware; "Where GPU
|
|
|
140
140
|
work stops being free" below is where it does not. Rules, in order of leverage:
|
|
141
141
|
|
|
142
142
|
1. Continuous effects (snow, particles, animated backgrounds) belong in a
|
|
143
|
-
fragment shader:
|
|
144
|
-
params={{
|
|
145
|
-
|
|
143
|
+
fragment shader: createShaderTexture (from @solidrt/core/gpu) + `<texture
|
|
144
|
+
params={{ uTime }}>` (the shader declares `uniform float uTime;` itself -
|
|
145
|
+
the preamble declares only what the runtime fills). The whole effect then
|
|
146
|
+
costs one setProperty per frame - the uTime write - regardless of visual
|
|
147
|
+
complexity. Shader output
|
|
146
148
|
must be premultiplied alpha (white flakes are `vec4(vec3(a), a)`);
|
|
147
149
|
straight alpha (`vec4(1,1,1,a)`) composites as opaque white. A source that
|
|
148
150
|
starts with `#version 300 es` is compiled exactly as written - no preamble
|
|
@@ -155,15 +157,18 @@ work stops being free" below is where it does not. Rules, in order of leverage:
|
|
|
155
157
|
`vec3 iResolution` needs no splitting into scalars. To combine several
|
|
156
158
|
GPU passes, stack `<texture>` elements and set `blendMode` (e.g. a base
|
|
157
159
|
pass plus an additive `blendMode="plus"` pass) rather than writing a
|
|
158
|
-
compositing shader. Within one pipeline draw,
|
|
160
|
+
compositing shader. Within one pipeline draw, createPipelineTexture's
|
|
159
161
|
`blend: "add"` accumulates overlapping geometry additively (soft point
|
|
160
162
|
splats, glow) - pair it with `depthWrite: false` when depth-tested;
|
|
161
|
-
neither option implies the other.
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
163
|
+
neither option implies the other. A pipeline's own vertex stage writes
|
|
164
|
+
into a y-down clip space: `gl_Position` y = -1 is the top row of the
|
|
165
|
+
target and +1 the bottom, so camera-up geometry must negate y (or fold
|
|
166
|
+
the flip into its projection) or it draws upside down. Sampling is a
|
|
167
|
+
create-time option on every texture: `{ filter: "nearest" }` for
|
|
168
|
+
hard-pixel upscaling (render a small target, display it big - the
|
|
169
|
+
retro/pixel-art path) and `{ wrap: "repeat" }` to tile outside 0..1 in
|
|
170
|
+
shaders; the defaults are linear and clamp, and the choice applies both
|
|
171
|
+
on screen and to shaders sampling the texture.
|
|
167
172
|
2. Reduce setProperty calls wherever possible: one path string rebuilt per
|
|
168
173
|
frame beats N elements with N animated positions; a shader beats the path
|
|
169
174
|
string. get_stats' setPropsPerFrame is the counter to watch.
|
|
@@ -345,8 +350,10 @@ flag: `"args": [..., "mcp", "--port", "N"]`.
|
|
|
345
350
|
- console.log + get_logs is your primary probe into runtime state. For state
|
|
346
351
|
you will want repeatedly (a pose, a mode, a counter), bind a debug key that
|
|
347
352
|
logs it and read it back via get_logs.
|
|
348
|
-
- Key events
|
|
349
|
-
|
|
353
|
+
- Key events start at the focused node and bubble to the window root; with
|
|
354
|
+
nothing focused they go to the window root alone. So a debug key bound via
|
|
355
|
+
`<window onKeyDown>` always fires (unless a focused component consumes the
|
|
356
|
+
key with stopPropagation, as TextInput does for editing keys). `key` and
|
|
350
357
|
`code` are W3C KeyboardEvent values, so arrow keys arrive as "ArrowLeft"/
|
|
351
358
|
"ArrowRight"/"ArrowUp"/"ArrowDown" (not "Left"), alongside "Enter",
|
|
352
359
|
"Escape", "a".
|
package/scaffold/package.json
CHANGED
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
"android": "srt client --android"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@solidrt/core": "0.0.
|
|
13
|
-
"@solidrt/components": "0.0.
|
|
12
|
+
"@solidrt/core": "0.0.42",
|
|
13
|
+
"@solidrt/components": "0.0.42"
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
|
-
"@solidrt/cli": "0.0.
|
|
17
|
-
"@solidrt/flux-types": "0.0.
|
|
16
|
+
"@solidrt/cli": "0.0.42",
|
|
17
|
+
"@solidrt/flux-types": "0.0.42",
|
|
18
18
|
"typescript": "^7"
|
|
19
19
|
}
|
|
20
20
|
}
|
package/src/commands/mcp.ts
CHANGED
|
@@ -103,7 +103,7 @@ let TOOLS: {
|
|
|
103
103
|
name: "get_stats",
|
|
104
104
|
readOnly: true,
|
|
105
105
|
description:
|
|
106
|
-
"Performance statistics from a running app client: fps, CPU%, memory, smoothed JS/layout/paint/hover frame times (ms), setProperty writes per frame, demand-gate reuse/skip counts per second, and live texture count. Layout-activity counters cover the last full rebuild, raw: nodes (live node count, mounted AND detached), mountedNodes/orphanNodes (live at query time: nodes reachable from the root vs not - orphans growing at a stable tree shape mean an unmount leak; absent when no engine is running), measureCalls (text measures; mostly cache hits, cheap), paraShapes (paragraphs actually shaped; the expensive signal - high layoutMs with near-zero paraShapes means the cost is not text shaping), dirtiedNodes (layout caches cleared by property writes since the previous rebuild; how much of the tree a write burst invalidated), cacheGets/cacheHits (layout-cache lookups during the rebuild; a hit on a container skips its whole subtree, so a healthy incremental rebuild shows a near-100% hit rate - a low rate at scale means the layout cache is being defeated). GPU-side health, read live at query time (absent when no engine is running): rasterQueue (raster commands sent but not yet executed; stuck nonzero means the raster thread is backlogged - the state where fps and frameMs go blind because no frames complete), idleTicks (cumulative idle frame signals emitted while the GPU had nothing queued; idleTicks racing while rasterQueue sits nonzero would mean the idle-tick gate is broken), fenceTimeouts (cumulative present-fence waits that expired instead of signaling - each one is a frame where the GPU was over budget for 100ms+ and one-frame-in-flight pacing was lost; zero on a healthy machine, climbing means the GPU is the bottleneck right now).",
|
|
106
|
+
"Performance statistics from a running app client: fps, CPU%, memory, smoothed JS/layout/paint/hover frame times (ms), setProperty writes per frame, demand-gate reuse/skip counts per second, and live texture count. Layout-activity counters cover the last full rebuild, raw: nodes (live node count, mounted AND detached), mountedNodes/orphanNodes (live at query time: nodes reachable from the root vs not - orphans growing at a stable tree shape mean an unmount leak; absent when no engine is running), measureCalls (text measures; mostly cache hits, cheap), paraShapes (paragraphs actually shaped; the expensive signal - high layoutMs with near-zero paraShapes means the cost is not text shaping), dirtiedNodes (layout caches cleared by property writes since the previous rebuild; how much of the tree a write burst invalidated), cacheGets/cacheHits (layout-cache lookups during the rebuild; a hit on a container skips its whole subtree, so a healthy incremental rebuild shows a near-100% hit rate - a low rate at scale means the layout cache is being defeated). GPU-side health, read live at query time (absent when no engine is running): rasterQueue (raster commands sent but not yet executed; stuck nonzero means the raster thread is backlogged - the state where fps and frameMs go blind because no frames complete), idleTicks (cumulative idle frame signals emitted while the GPU had nothing queued; idleTicks racing while rasterQueue sits nonzero would mean the idle-tick gate is broken), fenceTimeouts (cumulative present-fence waits that expired instead of signaling - each one is a frame where the GPU was over budget for 100ms+ and one-frame-in-flight pacing was lost; zero on a healthy machine, climbing means the GPU is the bottleneck right now), gpuPasses/gpuPassMs (cumulative shader/pipeline target renders on the raster thread and the wall time they took in whole ms - diff two queries to get a rate; passes racing far ahead of frames means redundant target re-renders, the failure mode where fps and frameMs look healthy while the raster thread drowns; the ms figure is raster-thread occupancy issuing the passes, not GPU-side duration), rasterCmdMs (cumulative wall time in whole ms the raster thread spent executing non-frame commands - texture uploads, readbacks, offscreen rasterizations, shader compiles, param writes and the target re-renders they trigger; the work frameMs never sees, so rasterCmdMs growing much faster than frames are presented means the raster thread is drowning in side work even if every counter above looks calm).",
|
|
107
107
|
inputSchema: { client: CLIENT_ARG },
|
|
108
108
|
},
|
|
109
109
|
{
|
|
@@ -151,14 +151,14 @@ let TOOLS: {
|
|
|
151
151
|
name: "get_gpu_resources",
|
|
152
152
|
readOnly: true,
|
|
153
153
|
description:
|
|
154
|
-
"Inventory of a running app client's GPU resources: textures (id, size, whether a shader renders into it), vertex buffers (id, byteLength), and shader/pipeline targets (output textureId, kind, bufferId, topology, drawCount, depth, attribute layout, bound sampler texture ids, current uniform values - the most recent writes, which the next frame or readback draws with). Use it when the render tree is just a <texture> leaf and the interesting state lives behind it; follow up with get_texture or get_buffer to see contents.",
|
|
154
|
+
"Inventory of a running app client's GPU resources: textures (id, size, whether a shader renders into it), vertex buffers (id, byteLength), and shader/pipeline targets (output textureId, kind, bufferId, topology, drawCount plus firstVertex/instanceCount when off their 0/1 defaults, depth, attribute layout, bound sampler texture ids, current uniform values - the most recent writes, which the next frame or readback draws with - plus passes/passMs, cumulative per-target render count and raster-thread wall time in whole ms: when get_stats shows gpuPasses running hot, these attribute the cost to the specific target). Use it when the render tree is just a <texture> leaf and the interesting state lives behind it; follow up with get_texture or get_buffer to see contents.",
|
|
155
155
|
inputSchema: { client: CLIENT_ARG },
|
|
156
156
|
},
|
|
157
157
|
{
|
|
158
158
|
name: "get_texture",
|
|
159
159
|
readOnly: true,
|
|
160
160
|
description:
|
|
161
|
-
"Read back any GPU texture from a running app client as a PNG, by texture id (from get_gpu_resources, or the id returned by createImage/
|
|
161
|
+
"Read back any GPU texture from a running app client as a PNG, by texture id (from get_gpu_resources, or the id returned by createImage/createShaderTexture/createPipelineTexture in app code). Works on sampled textures (atlases, data textures) and shader/pipeline render targets alike, without needing a frame: a render target reads as its current output, with any pending params, geometry or sampled-input changes resolved first. Pass x/y/width/height to crop, e.g. one tile of an atlas.",
|
|
162
162
|
inputSchema: {
|
|
163
163
|
id: z.number().int().describe("Texture id, from get_gpu_resources"),
|
|
164
164
|
x: z.number().int().describe("Crop rect left edge in texture pixels (requires y, width, height)").optional(),
|