@bitefoundry/retrieviewer 0.0.15 → 0.0.17
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/ASSET-PROVENANCE.md +13 -0
- package/ATTENTION-PAW.md +53 -0
- package/ATTENTION-WALL.md +58 -0
- package/ATTENTION.md +12 -1
- package/EMBEDDING.md +15 -9
- package/PUPPY-MEMORY.md +59 -0
- package/README.ko.md +7 -0
- package/README.md +8 -0
- package/RELEASING.md +34 -1
- package/integrations/stackbite/attention.mjs +20 -3
- package/package.json +19 -12
- package/pet-indexed-manifest.json +106 -0
- package/puppy-comfort-sprites.mjs +10 -4
- package/puppy-companion-comfort-q5.rvz +0 -0
- package/puppy-companion-comfort.json +818 -5
- package/puppy-companion-interactions-v3-q5.rvz +0 -0
- package/puppy-companion-life.mjs +11 -6
- package/puppy-frame-file.mjs +15 -0
- package/puppy-frame-indexed.mjs +78 -0
- package/puppy-frame-predictive.mjs +1 -1
- package/puppy-frame-store.mjs +6 -0
- package/puppy-motion-tables.generated.mjs +1 -1
- package/puppy-paper-actions-v9-q5.rvz +0 -0
- package/puppy-paper-approach-q5.rvz +0 -0
- package/puppy-paper-arrival-seat-q5.rvz +0 -0
- package/puppy-paper-behaviors-q5.rvz +0 -0
- package/puppy-paper-rear-gallop-q5.rvz +0 -0
- package/puppy-paper-seat-q5.rvz +0 -0
- package/puppy-paper.mjs +11 -3
- package/puppy-stride-tweens-q5.rvz +0 -0
- package/retrieviewer.d.mts +3 -3
- package/retrieviewer.mjs +22 -10
- package/puppy-companion-comfort-q5.bin.gz +0 -0
- package/puppy-companion-interactions-v3-q5.bin.gz +0 -0
- package/puppy-paper-actions-v9-q5.bin.gz +0 -0
- package/puppy-paper-approach-q5.bin.gz +0 -0
- package/puppy-paper-arrival-seat-q5.bin.gz +0 -0
- package/puppy-paper-behaviors-q5.bin.gz +0 -0
- package/puppy-paper-rear-gallop-q5.bin.gz +0 -0
- package/puppy-paper-seat-q5.bin.gz +0 -0
- package/puppy-stride-tweens-q5.bin.gz +0 -0
package/ASSET-PROVENANCE.md
CHANGED
|
@@ -102,6 +102,19 @@ records the exact36 source-key indices and `pixelBlending:false`. No new generat
|
|
|
102
102
|
or photographic input, asset family or attribution is added. Existing CC BY-SA4.0
|
|
103
103
|
terms and all non-watch pixels remain unchanged. See WATCH-REDRAW.md for the A/B.
|
|
104
104
|
|
|
105
|
+
Local attention-paw candidate2026-10-24 appends six built-in imagegen whole-body
|
|
106
|
+
keys to the existing comfort archive. Inputs were the existing licensed seated
|
|
107
|
+
puppy and a generated paw study; no new photographs were introduced. All45 old
|
|
108
|
+
comfort frames remain exact. ATTENTION-PAW.md records the source-sheet hash,
|
|
109
|
+
prompt specification, registration and byte costs. Existing attribution and
|
|
110
|
+
CC BY-SA4.0 terms apply; source sheets are excluded from npm.
|
|
111
|
+
|
|
112
|
+
Local standing-wall candidate2026-10-24 appends nine generated whole-body keys,
|
|
113
|
+
referenced only from the existing canonical puppy. All51 accepted comfort frames
|
|
114
|
+
remain exact. Source hash, prompt specification, common-scale registration and
|
|
115
|
+
costs are in ATTENTION-WALL.md. No new photo/video inputs or raw npm sheets;
|
|
116
|
+
existing attribution and CC BY-SA4.0 terms continue to apply.
|
|
117
|
+
|
|
105
118
|
Copyrightability of AI-generated expression, the precise derivative-work analysis,
|
|
106
119
|
and worldwide name clearance are not conclusively determined here. Existing
|
|
107
120
|
domestic trademark research records possible similar marks; owning an npm scope
|
package/ATTENTION-PAW.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Attention paw gesture
|
|
2
|
+
|
|
3
|
+
The notification sequence now approaches the user when necessary, sits facing
|
|
4
|
+
them, makes two gentle air scrapes with the viewer-left forepaw, lowers it, and
|
|
5
|
+
looks toward the pending item. This is one 1.88-second episode per accepted
|
|
6
|
+
notice. It does not add autonomous reminders or change which events qualify.
|
|
7
|
+
|
|
8
|
+
The viewer-right forepaw remains planted. Six whole-body grayscale keys share
|
|
9
|
+
one uniform scale and are translated to that support point. There are no
|
|
10
|
+
independently warped heads, legs, or body parts. The original seated frame is
|
|
11
|
+
reused exactly at both ends. Resolution, ball, treat, and tug interrupt through
|
|
12
|
+
an authored lowering path of at most 0.3 seconds from the last displayed key.
|
|
13
|
+
|
|
14
|
+
## Art and provenance
|
|
15
|
+
|
|
16
|
+
Generated with the built-in imagegen tool, using the existing canonical seated
|
|
17
|
+
puppy and an earlier generated paw study as references. No new photographs were
|
|
18
|
+
used. Existing art attribution and CC BY-SA 4.0 terms continue to apply; see
|
|
19
|
+
ASSET-PROVENANCE.md and ASSETS-LICENSE.md.
|
|
20
|
+
|
|
21
|
+
Final source: `dist/attention-paw-v2/source.png`.
|
|
22
|
+
SHA-256: `0c3b01952378cd7c0fd941f53e1c43ca5de73c63b3875e58d035b009508d693a`.
|
|
23
|
+
|
|
24
|
+
Prompt specification: a wide 3-by-2 sheet of six square, black-background cells;
|
|
25
|
+
the same fluffy golden-retriever puppy, face, bandana, seated proportions and
|
|
26
|
+
complete tail in every cell; one forepaw gently lifts, bends, reaches forward,
|
|
27
|
+
scrapes down through the air, retracts, and lowers; the opposite forepaw stays
|
|
28
|
+
planted; consistent fixed camera, floor, body scale, monochrome tonal fur and
|
|
29
|
+
clean empty margins. Earlier alternating-paw and tail-clipped studies were
|
|
30
|
+
rejected and are not runtime assets.
|
|
31
|
+
|
|
32
|
+
`tools/prepare-attention-art.mjs` and its Python companion extract and register
|
|
33
|
+
the six keys offline. They append to the existing comfort archive and verify
|
|
34
|
+
all 45 previous frames byte-for-byte. The source sheet and QA files are excluded
|
|
35
|
+
from the npm package. No generation service is used at runtime.
|
|
36
|
+
|
|
37
|
+
## Cost and verification
|
|
38
|
+
|
|
39
|
+
The compressed archive grows by 55,386 bytes (about 54 KiB). Node's compressed
|
|
40
|
+
pixel storage grows by 63,912 bytes (about 62 KiB), compared with the same codec
|
|
41
|
+
over the preserved 45-frame baseline. Selectively retaining the new keys in the
|
|
42
|
+
portable store costs about 137 KiB; this is different from the net archive
|
|
43
|
+
repacking delta. These are pixel-storage measurements, not total process RSS.
|
|
44
|
+
|
|
45
|
+
The sampler borrows the existing RGBA scratch and two-frame reconstruction
|
|
46
|
+
cache. No new runtime dependency, asset family, timer, or permanent decoded
|
|
47
|
+
animation cache is added. Dedicated tests check exact old pixels, planted root,
|
|
48
|
+
neutral bookends, bounded recovery, direct interactions and the public renderer.
|
|
49
|
+
|
|
50
|
+
The owner accepted this motion on2026-10-24 for release0.0.16, alongside the
|
|
51
|
+
standing wall variant. Windows npm-shim support is a separate compatibility fix
|
|
52
|
+
in that release. Completed-work alerts remain unsupported. The local preview
|
|
53
|
+
uses simulated pending items. Live companion restart remains user-controlled.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Standing wall scrabble
|
|
2
|
+
|
|
3
|
+
An additional attention variant: shift weight to the hindquarters, rise onto two
|
|
4
|
+
hind feet, brace both front paws against an implicit front glass plane, scrabble
|
|
5
|
+
quickly, then lower and sit. The complete authored episode lasts 2.2 seconds.
|
|
6
|
+
The glass is a visual metaphor, not detected window geometry or a new collision
|
|
7
|
+
system. No actual desktop content, wall or screen is inspected.
|
|
8
|
+
|
|
9
|
+
The gentle seated paw cue is preserved. Accepted notices alternate paw/wall
|
|
10
|
+
without consuming autonomy or fetch randomness. Hosts can request a fixed cue:
|
|
11
|
+
|
|
12
|
+
```js
|
|
13
|
+
pet.notify({kind:'input', gesture:'wall'}); // 'auto' (default), 'paw', 'wall'
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Repeated or rejected notices do not start another episode. If wall art is absent,
|
|
17
|
+
automatic mode keeps the prior behavior; an explicit wall request returns false.
|
|
18
|
+
Resolution, ball, treat and tug lower from the exact displayed key via an authored
|
|
19
|
+
path of at most 0.4 seconds. There is no mid-gesture teleport to a sitting frame.
|
|
20
|
+
|
|
21
|
+
## Art source
|
|
22
|
+
|
|
23
|
+
Built-in imagegen, canonical existing licensed seated puppy as the sole image
|
|
24
|
+
reference. No new photographs or video frames were used. The artwork retains
|
|
25
|
+
the existing attribution and CC BY-SA 4.0 lineage. Raw sheets are excluded from
|
|
26
|
+
npm. Source: `dist/attention-wall-v1/source.png`, SHA-256:
|
|
27
|
+
`ea1a8f2f4d3f4b897bec95bcd06b8a4d6cd81d083713b67857efac469707e4af`.
|
|
28
|
+
|
|
29
|
+
Prompt specification: the exact reference puppy, muzzle/ears/bandana/fur and age;
|
|
30
|
+
one 3-by-3 sheet of complete whole-body keys on black, a fixed front/slight
|
|
31
|
+
three-quarter camera, same world scale and floor in every cell, no drawn wall,
|
|
32
|
+
props or labels. Keys: seated weight shift, half-rise, upright braced on two rear
|
|
33
|
+
soles with both forepaws high, alternating forepaw scrapes with coupled shoulder
|
|
34
|
+
weight transfer, both paws high, knees bending/lowering, and low seated recovery.
|
|
35
|
+
Preserve chest/skull volume, full tail and toes; standing must be naturally taller
|
|
36
|
+
than sitting rather than resized into the seated bounding box.
|
|
37
|
+
|
|
38
|
+
Actual sheet: 1254 by 1254, split into nine 418-square cells. Offline preparation
|
|
39
|
+
uses one common scale (0.7572463768115942), whole-frame translation to the measured
|
|
40
|
+
lower paw-pair proxy, and no anatomical compositing or nonlinear warp. Proxy
|
|
41
|
+
registration is not animal motion capture. The exact old neutral is reused at
|
|
42
|
+
both ends. Existing 51 comfort frames, including the gentle paw cue, stay exact.
|
|
43
|
+
|
|
44
|
+
## Resource cost and checks
|
|
45
|
+
|
|
46
|
+
Nine extra keys extend the same comfort archive from 51 to 60 frames. Compressed
|
|
47
|
+
download increases 104,865 bytes (102.4 KiB); Node compressed pixel storage grows
|
|
48
|
+
117,578 bytes (114.8 KiB) with the same codec/baseline. These are payload figures,
|
|
49
|
+
not total RSS. No new RGBA scratch, timer, asset family, process or dependency.
|
|
50
|
+
|
|
51
|
+
Tests cover old pixel hashes, shared neutral, malformed recovery metadata,
|
|
52
|
+
unchanged world/projection, sole-proxy registration, every recovery phase,
|
|
53
|
+
variant choice and resolution/direct-play priority. Real public Braille frames
|
|
54
|
+
and the Aside preview were inspected. Raster audit has no structural errors;
|
|
55
|
+
its center-shift warnings describe the deliberate rise/lower and stance transfer
|
|
56
|
+
and require visual review rather than a looser threshold. The owner visually
|
|
57
|
+
accepted this motion and authorized release0.0.16 on2026-10-24. The user's running
|
|
58
|
+
companion is not automatically replaced by publication.
|
package/ATTENTION.md
CHANGED
|
@@ -42,6 +42,10 @@ Only the fixed read-only command `stackbite agent seats --output json`, at most
|
|
|
42
42
|
once every five seconds after the previous read finishes. StackBite revalidates
|
|
43
43
|
the inherited caller Seat/generation. The source requires a live Room binding;
|
|
44
44
|
launching from an unrelated terminal is refused rather than guessing credentials.
|
|
45
|
+
|
|
46
|
+
On Windows, a native executable or npm PowerShell launcher is resolved on PATH.
|
|
47
|
+
The launcher uses literal `-File` argv with closed stdin, without a shell command
|
|
48
|
+
string or execution-policy change. Unix retains the direct command.
|
|
45
49
|
No raw database, credential file, terminal transcript, screenshot, microphone,
|
|
46
50
|
clipboard, provider hook or browser session is read by Retrieviewer.
|
|
47
51
|
|
|
@@ -58,9 +62,16 @@ a remote server does not automatically give a local Windows pet remote access.
|
|
|
58
62
|
|
|
59
63
|
## Behavior and limits
|
|
60
64
|
|
|
65
|
+
Attention now has two authored gestures: a seated gentle paw and a standing
|
|
66
|
+
two-hind-foot glass scrabble. Automatic cues alternate; hosts can pass
|
|
67
|
+
`gesture:'paw'` or `gesture:'wall'` to `pet.notify`. See [wall motion](ATTENTION-WALL.md)
|
|
68
|
+
for support, recovery and measured costs. The preview's wall button forces that
|
|
69
|
+
variant using simulated input; it does not request a real approval.
|
|
70
|
+
|
|
61
71
|
- A new exact Room/Seat/generation/turn/request cues one connected attention episode:
|
|
62
72
|
brake/recover and face the user, approach using the existing world path if more
|
|
63
|
-
than 0.8 m from the near check-in point, then sit
|
|
73
|
+
than 0.8 m from the near check-in point, then sit, gently paw the air twice,
|
|
74
|
+
lower the paw and look left. See [paw motion and cost](ATTENTION-PAW.md). Near pets stay
|
|
64
75
|
in place. Resolution during approach brakes the obsolete journey naturally.
|
|
65
76
|
Left means the sidebar direction, not a detected button coordinate.
|
|
66
77
|
- The rule cue is accepted before optional inference starts. LLM latency, failure
|
package/EMBEDDING.md
CHANGED
|
@@ -52,10 +52,16 @@ Redirected stdout prints one plain frame and exits.
|
|
|
52
52
|
## Assets / original option
|
|
53
53
|
|
|
54
54
|
Default files resolve against the module URL, never cwd (lazy Node fs or browser
|
|
55
|
-
HTTP fetch). getPetAssetFiles(profile?) returns
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
HTTP fetch). getPetAssetFiles(profile?) returns 19 filenames: nine art archives
|
|
56
|
+
plus ten metadata files. Copy these unchanged for bundlers. The default Q5 files
|
|
57
|
+
use `.rvz`, an index followed by individually gzip-compressed crops. A custom
|
|
58
|
+
loader returns the original ArrayBuffer/typed bytes, without unpacking the archive.
|
|
59
|
+
|
|
60
|
+
Local Node hosts using the default loader read only the indices at creation and
|
|
61
|
+
read/decode requested crops synchronously into a two-frame cache per family.
|
|
62
|
+
There is no background loader or extra process. The final pet's `dispose()` closes
|
|
63
|
+
the shared files. Custom loaders and browsers use the portable memory-backed
|
|
64
|
+
store; they do not receive the local file-backed memory reduction.
|
|
59
65
|
|
|
60
66
|
```js
|
|
61
67
|
import {createPet,getPetAssetFiles} from '@bitefoundry/retrieviewer';
|
|
@@ -74,11 +80,11 @@ They are **not bundled** in the small distribution. For external original art,
|
|
|
74
80
|
copy getPetAssetFiles('original') from the workspace and supply loadAsset. Missing
|
|
75
81
|
originals fail clearly, never silently fall back.
|
|
76
82
|
|
|
77
|
-
Q5 is lossy quantization (max source
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
See [PUPPY-
|
|
83
|
+
Q5 is lossy quantization (max original-source pixel error 4/255). The indexed
|
|
84
|
+
repack is lossless relative to the approved Q5 art: all 2,401 logical frames and
|
|
85
|
+
their timing remain unchanged. The nine indexed archives total 19,326,068 bytes;
|
|
86
|
+
their indices total 54,040 bytes. No Three.js dependency runs in the pet core.
|
|
87
|
+
See [PUPPY-MEMORY.md](./PUPPY-MEMORY.md) for measured costs and host limitations.
|
|
82
88
|
|
|
83
89
|
## JSONL bridge (Python/Rust/other process hosts)
|
|
84
90
|
|
package/PUPPY-MEMORY.md
CHANGED
|
@@ -1,5 +1,64 @@
|
|
|
1
1
|
# Runtime weight and performance
|
|
2
2
|
|
|
3
|
+
## Indexed local art (local candidate, 2026-10-25)
|
|
4
|
+
|
|
5
|
+
The default local Node loader opens nine RVZ5 files and reads only 54,040 bytes
|
|
6
|
+
of indices (plus 20-byte header probes). Each file contains the exact approved
|
|
7
|
+
RVQ5 filtered rows, individually gzip-compressed offline at level 9. Frame access
|
|
8
|
+
reads and inflates one requested crop into the existing two-frame-per-family
|
|
9
|
+
cache. No artwork family is decompressed/recompressed during startup; no loader
|
|
10
|
+
thread, process, dependency, polling timer or persistent user cache is added.
|
|
11
|
+
Shared pets hold one set of file descriptors. Last disposal closes all nine;
|
|
12
|
+
partial startup failure closes previously opened files. Repeated disposal is safe.
|
|
13
|
+
|
|
14
|
+
All 2,401 logical source frames are pixel-identical, including duplicates and
|
|
15
|
+
random seeks. The indexed repack round-trips to byte-identical RVQ5 archives.
|
|
16
|
+
The 450-frame fetch replay retains the same trajectory and visible SHA256
|
|
17
|
+
`76d5ec6c58622f4330a277852e0d6cb16f4bf2f9fd118688d9ec97b35f80f6a8`.
|
|
18
|
+
Timing, contacts, physics, palettes, art resolution and behavior are unchanged.
|
|
19
|
+
|
|
20
|
+
Fresh-process Windows Node 24 samples, seed 731, 480x135 cells, the existing
|
|
21
|
+
`tools/benchmark-pet.mjs` workload. ArrayBuffers/RSS samples below use diagnostic
|
|
22
|
+
GC after native zlib-close callbacks; these are not desktop memory guarantees.
|
|
23
|
+
|
|
24
|
+
| Metric | Previous | Indexed |
|
|
25
|
+
|---|---:|---:|
|
|
26
|
+
| Initial load | 1,481ms | 17ms |
|
|
27
|
+
| Loaded ArrayBuffers | 21,122,810B | 206,439B |
|
|
28
|
+
| Rendered ArrayBuffers | 27,658,258B | 6,741,887B |
|
|
29
|
+
| Loaded process RSS | 92,504,064B | 66,420,736B |
|
|
30
|
+
| Rendered process RSS | 166,457,344B | 148,267,008B |
|
|
31
|
+
| Peak benchmark process RSS | 207,421,440B | 158,302,208B |
|
|
32
|
+
| Mean frame time | 4.04ms | 4.09ms |
|
|
33
|
+
| P95 frame time | 6.44ms | 6.80ms |
|
|
34
|
+
|
|
35
|
+
This is a RAM/startup tradeoff, not a smaller download: art bytes increase from
|
|
36
|
+
19,095,012 to 19,326,068 (about 1.2%) to allow independent crop reads. The npm
|
|
37
|
+
candidate is about 19.5MB versus 19.3MB; it contains only indexed Q5 art, not
|
|
38
|
+
duplicate legacy archives. Legacy source archives remain for authoring and exact
|
|
39
|
+
regression comparisons. `pet-indexed-manifest.json` describes the shipped format;
|
|
40
|
+
the older `pet-q5-manifest.json` describes its legacy source inputs.
|
|
41
|
+
|
|
42
|
+
Random-access storage adds synchronous small reads during rendering. The local
|
|
43
|
+
sample used OS-cached files; cold disks, network filesystems, antivirus and other
|
|
44
|
+
platforms can have different latency. Frame access validates gzip length/CRC and
|
|
45
|
+
filtered pixels on demand; headers, maps, crop bounds and offsets are validated
|
|
46
|
+
at opening. This differs from the old eager whole-archive pixel validation.
|
|
47
|
+
|
|
48
|
+
Browser/custom-loader compatibility is retained by restoring each indexed family
|
|
49
|
+
into the existing portable store during async creation. Those hosts do not get
|
|
50
|
+
the local file-backed RAM reduction. Actual Aside browser loading, Braille output
|
|
51
|
+
and a ball interaction were checked; no Node file module was requested there.
|
|
52
|
+
An isolated npm-installed Windows native check painted real frames, accepted the
|
|
53
|
+
native ball button and exited worker/painter cleanly. Its short Node sample was
|
|
54
|
+
73MiB RSS, with native-helper memory separate; it is not a peak or long-run budget.
|
|
55
|
+
No live Linux/macOS check was performed for this storage change.
|
|
56
|
+
|
|
57
|
+
Evidence: local `dist/indexed-art-{before,after}.json`,
|
|
58
|
+
`dist/indexed-art-tests.txt`, `dist/package-check-*/package-check.json` and
|
|
59
|
+
`dist/windows-overlay-qa/`. Rebuild/check deterministic archives with
|
|
60
|
+
`npm run bake:art-index` / `npm run check:art-index` in the source checkout.
|
|
61
|
+
|
|
3
62
|
## Held-pose invalidation (local candidate, 2026-10-24)
|
|
4
63
|
|
|
5
64
|
The desktop pump now asks `pet.needsFrame(viewport)` before rasterization. Only
|
package/README.ko.md
CHANGED
|
@@ -108,6 +108,13 @@ npm uninstall -g @bitefoundry/retrieviewer
|
|
|
108
108
|
|
|
109
109
|
## StackBite 알림
|
|
110
110
|
|
|
111
|
+
0.0.17은 기존 그림과 움직임을 유지하고, 기본 로컬 Node 실행에서 필요한 그림만
|
|
112
|
+
파일에서 읽어요. [메모리 측정 기록](PUPPY-MEMORY.md)을 참고하세요.
|
|
113
|
+
|
|
114
|
+
0.0.16은 앞발로 살살 부르기와 두 발로 서서 벽 박박 긁기를 번갈아 보여줘요.
|
|
115
|
+
홈페이지에서도 두 동작을 눌러볼 수 있어요. Windows의 npm 설치형 StackBite도
|
|
116
|
+
감시할 수 있게 했어요. 작업 완료 체크표시는 아직 알림 대상이 아니에요.
|
|
117
|
+
|
|
111
118
|
0.0.14부터 [승인·입력 대기 알림](ATTENTION.md)을 선택해서 켤 수 있어요.
|
|
112
119
|
0.0.15는 LLM을 기다리지 않고 알리고, Windows에 Seat 이름과 대기 종류를 표시해요.
|
|
113
120
|
강아지도 기존 그림으로 가까이 와서 알림 방향을 봐요. 이름은 외부로 보내지 않아요.
|
package/README.md
CHANGED
|
@@ -141,6 +141,14 @@ Version 0.0.15 alerts without waiting for the model, shows the Seat name and
|
|
|
141
141
|
pending kind locally on Windows, and lets the puppy approach before looking
|
|
142
142
|
toward the sidebar. It reuses existing artwork; names never enter model input.
|
|
143
143
|
|
|
144
|
+
Version 0.0.17 keeps the same artwork and motion while loading only requested
|
|
145
|
+
frames from disk in the default local Node host. See [memory measurements](PUPPY-MEMORY.md).
|
|
146
|
+
|
|
147
|
+
Version 0.0.16 adds two approved attention gestures: a gentle seated paw and a
|
|
148
|
+
standing two-paw glass scrabble. They alternate for new alerts; both are playable
|
|
149
|
+
in the website demo. Windows watching also supports npm's PowerShell launcher.
|
|
150
|
+
Completed-work checkmarks are not alert events yet.
|
|
151
|
+
|
|
144
152
|
After updating, run inside a live StackBite Seat on the display computer:
|
|
145
153
|
|
|
146
154
|
```sh
|
package/RELEASING.md
CHANGED
|
@@ -1,4 +1,37 @@
|
|
|
1
|
-
# Retrieviewer 0.0.
|
|
1
|
+
# Retrieviewer 0.0.17 release process
|
|
2
|
+
|
|
3
|
+
Current target: `@bitefoundry/retrieviewer@0.0.17`, public `latest`.
|
|
4
|
+
On 2026-10-25 the owner authorized publication of the indexed local-art update
|
|
5
|
+
and measurement of actual operating memory. Local Node hosts read only the art
|
|
6
|
+
indices at startup, then reconstruct requested crops from file-backed archives.
|
|
7
|
+
All 2,401 approved Q5 frames, timing and behavior remain unchanged. The browser
|
|
8
|
+
and custom-loader paths retain the compatible memory-backed representation.
|
|
9
|
+
No new dependency, background loader, process or persistent user cache is added.
|
|
10
|
+
|
|
11
|
+
Publish one fresh installed/native-tested tarball after Windows/Linux CI and
|
|
12
|
+
verify its registry integrity and a fresh registry consumer. Keep existing pets
|
|
13
|
+
running; measure only owned diagnostic windows and report Node and native-helper
|
|
14
|
+
working sets separately. No real approval, paid inference or user-window change
|
|
15
|
+
is needed for the measurement. Preserve all existing registry releases.
|
|
16
|
+
|
|
17
|
+
## Previous 0.0.16 scope (historical)
|
|
18
|
+
|
|
19
|
+
Current target: `@bitefoundry/retrieviewer@0.0.16`, public `latest`.
|
|
20
|
+
On2026-10-24 the owner accepted the gentle-paw and standing-wall gestures and
|
|
21
|
+
explicitly authorized merging, GitHub push, npm publication and website updates.
|
|
22
|
+
Both cues preserve the accepted puppy; automatic notifications alternate them.
|
|
23
|
+
Explicit host gesture selection and bilingual website demo buttons are included.
|
|
24
|
+
The same comfort archive gains15 keys; all45 pre-gesture keys remain exact.
|
|
25
|
+
Windows read-only watching resolves native executables or npm PowerShell shims
|
|
26
|
+
with literal argv and closed stdin. No shell string or execution-policy change.
|
|
27
|
+
|
|
28
|
+
Build/install one fresh exact tarball, run full tests and owned Windows checks,
|
|
29
|
+
push and wait for Windows/Linux CI, publish the same artifact, verify registry
|
|
30
|
+
integrity and a fresh consumer, and verify matching deployed Pages runtime bytes.
|
|
31
|
+
No StackBite patch, completed-work alerts, screen capture, saved API key, live-pet
|
|
32
|
+
restart or additional platform certification is part of this release.
|
|
33
|
+
|
|
34
|
+
## Previous 0.0.15 scope (historical)
|
|
2
35
|
|
|
3
36
|
Current target: `@bitefoundry/retrieviewer@0.0.15`, public `latest`.
|
|
4
37
|
On 2026-10-24 the owner authorized npm publication of the reviewed rule-first
|
|
@@ -2,10 +2,26 @@
|
|
|
2
2
|
// Uses StackBite's own binding validation; never reads its credential files.
|
|
3
3
|
import {execFile} from 'node:child_process';
|
|
4
4
|
import {promisify} from 'node:util';
|
|
5
|
+
import {stat} from 'node:fs/promises';
|
|
6
|
+
import {join,delimiter} from 'node:path';
|
|
5
7
|
import {validateAttentionSnapshot} from '../../retrieviewer-attention.mjs';
|
|
6
|
-
const
|
|
8
|
+
const run=promisify(execFile);
|
|
9
|
+
const execute=(command,args,options)=>{const pending=run(command,args,options);pending.child?.stdin?.end();return pending;};
|
|
7
10
|
const identifier=value=>typeof value==='string'&&/^[a-zA-Z0-9_.:-]{1,128}$/.test(value);
|
|
8
11
|
|
|
12
|
+
// Match npm's Windows PowerShell launcher without shell strings or execution-
|
|
13
|
+
// policy changes. Like the installer probe, close stdin so npm sees no pipeline.
|
|
14
|
+
export async function resolveStackBiteCommand({env=process.env,platform=process.platform}={}){
|
|
15
|
+
if(platform==='win32')for(const directory of (env.PATH??env.Path??'').split(delimiter).filter(Boolean)){
|
|
16
|
+
for(const extension of ['.exe','.ps1']){
|
|
17
|
+
const path=join(directory,'stackbite'+extension);
|
|
18
|
+
if(!(await stat(path).catch(()=>null))?.isFile())continue;
|
|
19
|
+
return extension==='.exe'?{command:path,prefix:[]}:{command:'powershell.exe',prefix:['-NoProfile','-NonInteractive','-File',path]};
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return {command:'stackbite',prefix:[]};
|
|
23
|
+
}
|
|
24
|
+
|
|
9
25
|
export function stackBiteBinding(env=process.env){
|
|
10
26
|
if(!identifier(env.STACKBITE_ROOM_ID)||!identifier(env.STACKBITE_SEAT_KEY)||!identifier(env.STACKBITE_SESSION_GENERATION)||!env.STACKBITE_STATE_DIR||!env.STACKBITE_ROOM_BRIDGE_URL)throw Error('Start desktop --watch stackbite inside a live StackBite Seat. No Room binding was found.');
|
|
11
27
|
return {roomId:env.STACKBITE_ROOM_ID};
|
|
@@ -33,14 +49,15 @@ export function projectStackBiteSeats(value,{roomId}={}){
|
|
|
33
49
|
}
|
|
34
50
|
return validateAttentionSnapshot({source:'stackbite',scope:roomId,items});
|
|
35
51
|
}
|
|
36
|
-
export function createStackBiteSource({env=process.env,exec=execute}={}){
|
|
52
|
+
export function createStackBiteSource({env=process.env,exec=execute,resolveCommand=()=>resolveStackBiteCommand({env})}={}){
|
|
37
53
|
const binding=stackBiteBinding(env);
|
|
38
54
|
const childEnv={...env};delete childEnv.OPENROUTER_API_KEY;
|
|
39
55
|
return {
|
|
40
56
|
async readSnapshot({signal}={}){
|
|
41
57
|
// Fixed argv, no shell, no input/click/report/approval command. The CLI checks
|
|
42
58
|
// that the inherited caller Seat/generation is still live on every read.
|
|
43
|
-
const {
|
|
59
|
+
const {command,prefix}=await resolveCommand();
|
|
60
|
+
const {stdout}=await exec(command,[...prefix,'agent','seats','--output','json'],{env:childEnv,signal,encoding:'utf8',windowsHide:true,timeout:4000,maxBuffer:262144});
|
|
44
61
|
return projectStackBiteSeats(JSON.parse(stdout),binding);
|
|
45
62
|
},
|
|
46
63
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bitefoundry/retrieviewer",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.17",
|
|
4
4
|
"description": "A fluffy Braille desktop pet for Windows and Linux X11, with experimental macOS support and an embeddable TUI engine.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"homepage": "https://bitefoundry.github.io/retrieviewer/",
|
|
@@ -90,6 +90,8 @@
|
|
|
90
90
|
"integrations/openrouter/brain.d.mts",
|
|
91
91
|
"BRAIN.md",
|
|
92
92
|
"ATTENTION.md",
|
|
93
|
+
"ATTENTION-PAW.md",
|
|
94
|
+
"ATTENTION-WALL.md",
|
|
93
95
|
"integrations/linux-overlay/overlay.py",
|
|
94
96
|
"integrations/linux-overlay/README.md",
|
|
95
97
|
"integrations/macos-overlay/overlay.jxa",
|
|
@@ -140,26 +142,29 @@
|
|
|
140
142
|
"puppy-continuous.mjs",
|
|
141
143
|
"puppy-zoomies.mjs",
|
|
142
144
|
"puppy-zoomies30.mjs",
|
|
143
|
-
"puppy-stride-tweens-q5.
|
|
145
|
+
"puppy-stride-tweens-q5.rvz",
|
|
144
146
|
"puppy-stride-meta.json",
|
|
145
147
|
"puppy-stable-meta.json",
|
|
146
|
-
"puppy-paper-rear-gallop-q5.
|
|
148
|
+
"puppy-paper-rear-gallop-q5.rvz",
|
|
147
149
|
"puppy-paper-rear-gallop.json",
|
|
148
|
-
"puppy-paper-approach-q5.
|
|
150
|
+
"puppy-paper-approach-q5.rvz",
|
|
149
151
|
"puppy-paper-approach.json",
|
|
150
|
-
"puppy-paper-seat-q5.
|
|
152
|
+
"puppy-paper-seat-q5.rvz",
|
|
151
153
|
"puppy-paper-seat.json",
|
|
152
|
-
"puppy-paper-arrival-seat-q5.
|
|
154
|
+
"puppy-paper-arrival-seat-q5.rvz",
|
|
153
155
|
"puppy-paper-arrival-seat.json",
|
|
154
|
-
"puppy-paper-behaviors-q5.
|
|
156
|
+
"puppy-paper-behaviors-q5.rvz",
|
|
155
157
|
"puppy-paper-behaviors.json",
|
|
156
|
-
"puppy-paper-actions-v9-q5.
|
|
158
|
+
"puppy-paper-actions-v9-q5.rvz",
|
|
157
159
|
"puppy-paper-actions-v9.json",
|
|
158
|
-
"puppy-companion-interactions-v3-q5.
|
|
160
|
+
"puppy-companion-interactions-v3-q5.rvz",
|
|
159
161
|
"puppy-companion-interactions-v3.json",
|
|
160
|
-
"puppy-companion-comfort-q5.
|
|
162
|
+
"puppy-companion-comfort-q5.rvz",
|
|
161
163
|
"puppy-companion-comfort.json",
|
|
162
|
-
"vendor/procedural-animals/LICENSE"
|
|
164
|
+
"vendor/procedural-animals/LICENSE",
|
|
165
|
+
"puppy-frame-indexed.mjs",
|
|
166
|
+
"puppy-frame-file.mjs",
|
|
167
|
+
"pet-indexed-manifest.json"
|
|
163
168
|
],
|
|
164
169
|
"scripts": {
|
|
165
170
|
"bake:motion": "node tools/bake-pet-motion.mjs",
|
|
@@ -171,7 +176,9 @@
|
|
|
171
176
|
"test": "node --test",
|
|
172
177
|
"test:package": "node check-pet-package.mjs",
|
|
173
178
|
"release:check": "npm run check:motion && node tools/check-release.mjs",
|
|
174
|
-
"prepublishOnly": "npm run release:check"
|
|
179
|
+
"prepublishOnly": "npm run release:check",
|
|
180
|
+
"bake:art-index": "node tools/index-pet-art.mjs",
|
|
181
|
+
"check:art-index": "node tools/index-pet-art.mjs --check"
|
|
175
182
|
},
|
|
176
183
|
"dependencies": {
|
|
177
184
|
"jsonc-parser": "3.3.1"
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"format": "RVZ5",
|
|
4
|
+
"pixels": "Exact approved RVQ5 rows; no quantization, frame removal or resampling",
|
|
5
|
+
"entries": [
|
|
6
|
+
{
|
|
7
|
+
"file": "puppy-stride-tweens-q5.rvz",
|
|
8
|
+
"bytes": 7643027,
|
|
9
|
+
"indexBytes": 19608,
|
|
10
|
+
"frames": 799,
|
|
11
|
+
"uniqueFrames": 683,
|
|
12
|
+
"sha256": "e049a3e5dbf2332620d881b8b484b1828dcc7aa3c9e636bf14358b3146458fd9",
|
|
13
|
+
"source": "puppy-stride-tweens-q5.bin.gz",
|
|
14
|
+
"sourceSha256": "abcc6f1825f09655f23e977c56e6790d27edd054c4c24be852c097fb575d6a4f",
|
|
15
|
+
"restoredRvq5Sha256": "eecf92fd402843bef43aa4b154db6eba999959dd16cd8e34c54e42c88eaade10"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"file": "puppy-paper-rear-gallop-q5.rvz",
|
|
19
|
+
"bytes": 1481295,
|
|
20
|
+
"indexBytes": 4100,
|
|
21
|
+
"frames": 162,
|
|
22
|
+
"uniqueFrames": 143,
|
|
23
|
+
"sha256": "fefa5949317e5afde1f5872f8ac43da95206a844cec1d90b27b2f31f32655ddd",
|
|
24
|
+
"source": "puppy-paper-rear-gallop-q5.bin.gz",
|
|
25
|
+
"sourceSha256": "ca731e1979a37ec2e005a80365e3b58358f640b8b26e7036b0e931940a7b1264",
|
|
26
|
+
"restoredRvq5Sha256": "fe96e31d30348cc7d1fc674f40778d2312c9d1b40c57e634dcc397a35cc5ccf4"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"file": "puppy-paper-approach-q5.rvz",
|
|
30
|
+
"bytes": 1462216,
|
|
31
|
+
"indexBytes": 4004,
|
|
32
|
+
"frames": 162,
|
|
33
|
+
"uniqueFrames": 139,
|
|
34
|
+
"sha256": "5f14d0c8f4b2a5a6f59be653cd6a9f3c0450260e0ae4e79074a0da5dc9f66821",
|
|
35
|
+
"source": "puppy-paper-approach-q5.bin.gz",
|
|
36
|
+
"sourceSha256": "17179d3ace7748f66ed3c5a61b5246d24ecd3570b350535bd2edc8cbf58304e6",
|
|
37
|
+
"restoredRvq5Sha256": "6f57a5f506eabea41c00f02738c8124a4ae8e05471bdcd76e0a6e9ed739ca1a3"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"file": "puppy-paper-seat-q5.rvz",
|
|
41
|
+
"bytes": 481353,
|
|
42
|
+
"indexBytes": 1400,
|
|
43
|
+
"frames": 51,
|
|
44
|
+
"uniqueFrames": 49,
|
|
45
|
+
"sha256": "569e943321eaad920f6915c4bd7c60f70571737c57a9407f3268ae7283565c4f",
|
|
46
|
+
"source": "puppy-paper-seat-q5.bin.gz",
|
|
47
|
+
"sourceSha256": "5480c994de0d034d70eff6ea86095f3722cf87bde72f364dd369b94b1ad66f84",
|
|
48
|
+
"restoredRvq5Sha256": "b21aa11039b314ed3dec96818e571d54b6102bd0bc1f76e0a99ceb6d2b5ae097"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"file": "puppy-paper-arrival-seat-q5.rvz",
|
|
52
|
+
"bytes": 492675,
|
|
53
|
+
"indexBytes": 1400,
|
|
54
|
+
"frames": 51,
|
|
55
|
+
"uniqueFrames": 49,
|
|
56
|
+
"sha256": "d69c7d59c99b6f12cebab4e92ec2aa137ba68efb56bb5d37cb52ea1b91d217a2",
|
|
57
|
+
"source": "puppy-paper-arrival-seat-q5.bin.gz",
|
|
58
|
+
"sourceSha256": "7effa0a2150e8ef9ed37d5b6cb10089672e0ce32599c06db21ad4769144bf246",
|
|
59
|
+
"restoredRvq5Sha256": "3b2ef9e322e625340c42a549f17165492cc14f724f4593bf298f67195677bb6e"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"file": "puppy-paper-behaviors-q5.rvz",
|
|
63
|
+
"bytes": 1288500,
|
|
64
|
+
"indexBytes": 3692,
|
|
65
|
+
"frames": 162,
|
|
66
|
+
"uniqueFrames": 126,
|
|
67
|
+
"sha256": "fac739a813a00bfd63294b3926b2463b60a2ab1a1b063b4ae02a053d2f925e8d",
|
|
68
|
+
"source": "puppy-paper-behaviors-q5.bin.gz",
|
|
69
|
+
"sourceSha256": "e4b79387aca974ceec74a02dc3f02780eb53d38af6ec9ebd69994de744b39716",
|
|
70
|
+
"restoredRvq5Sha256": "cb045558ca490436c5d6703f6468daba26f20ed76bc886e829787889253ccbb9"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"file": "puppy-paper-actions-v9-q5.rvz",
|
|
74
|
+
"bytes": 4691230,
|
|
75
|
+
"indexBytes": 13772,
|
|
76
|
+
"frames": 594,
|
|
77
|
+
"uniqueFrames": 474,
|
|
78
|
+
"sha256": "80621dbbdbd5272e9f4a40ac237f1d1f784a01456cdef48f2c10fdd45095f600",
|
|
79
|
+
"source": "puppy-paper-actions-v9-q5.bin.gz",
|
|
80
|
+
"sourceSha256": "abb4677468206c62937c0247dc4c5823e0a7c4a3a197da40194a08dd594aeef9",
|
|
81
|
+
"restoredRvq5Sha256": "615fb04961a38e592a661a20ad50fad45e1e4205e34198fa87a155ace966ea77"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"file": "puppy-companion-interactions-v3-q5.rvz",
|
|
85
|
+
"bytes": 1160887,
|
|
86
|
+
"indexBytes": 4436,
|
|
87
|
+
"frames": 360,
|
|
88
|
+
"uniqueFrames": 124,
|
|
89
|
+
"sha256": "237089d60d0350f08c4570c3379d44a6947d610b59c50856ed5f050d1debf420",
|
|
90
|
+
"source": "puppy-companion-interactions-v3-q5.bin.gz",
|
|
91
|
+
"sourceSha256": "8c7d24254f3f1e9fb85bff5ed1c7904fb4f111b0e47b57eee22dc094c18f3bf3",
|
|
92
|
+
"restoredRvq5Sha256": "5ebfc58c9cfeaf349d30bc65be2e4663f7a3b8be9f35ca5d6da323172624de7a"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"file": "puppy-companion-comfort-q5.rvz",
|
|
96
|
+
"bytes": 624885,
|
|
97
|
+
"indexBytes": 1628,
|
|
98
|
+
"frames": 60,
|
|
99
|
+
"uniqueFrames": 57,
|
|
100
|
+
"sha256": "9df13e0e4c5cd854e42aee595ee675eea716293e392d6e587145ffbaa74c5870",
|
|
101
|
+
"source": "puppy-companion-comfort-q5.bin.gz",
|
|
102
|
+
"sourceSha256": "57942c55e9c467d973a08f1e23804b0f756eaed46dddfe3aba7e7c3621996236",
|
|
103
|
+
"restoredRvq5Sha256": "5f598c2ba15212a73e88c02f0d189b20a74e46f2346f7dfbc3bca8c2d26fc66b"
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
}
|
|
@@ -6,7 +6,8 @@ export function comfortMotionKey(progress,motion){
|
|
|
6
6
|
while(key<motion.times.length-1&&age>=motion.times[key+1])key++;
|
|
7
7
|
return key;
|
|
8
8
|
}
|
|
9
|
-
export function comfortMotion(pose,info){return pose?.clip==='scramble'?info.scramble:pose?.clip==='pickup'?info.pickups?.[pose.view]:pose?.clip==='carry-trot'?info.carryTrot:pose?.clip==='carry-settle'?info.carryTrot?.settle:null;}
|
|
9
|
+
export function comfortMotion(pose,info){const attention=pose?.clip==='attention-paw'?info.attentionPaw:pose?.clip==='attention-wall'?info.attentionWall:null;return attention?(pose.release?attention.releases?.[pose.release.from]:attention):pose?.clip==='scramble'?info.scramble:pose?.clip==='pickup'?info.pickups?.[pose.view]:pose?.clip==='carry-trot'?info.carryTrot:pose?.clip==='carry-settle'?info.carryTrot?.settle:null;}
|
|
10
|
+
export const comfortProgress=pose=>pose.release?.progress??pose.progress;
|
|
10
11
|
function validateMotion(motion,count){
|
|
11
12
|
if(!motion||!Array.isArray(motion.frames)||!Array.isArray(motion.times)||motion.frames.length<2||motion.frames.length>32||motion.frames.length!==motion.times.length||motion.times[0]!==0||!Number.isFinite(motion.duration)||motion.duration<=0||motion.duration>3||(motion.cyclic?motion.times.at(-1)>=motion.duration:motion.times.at(-1)!==motion.duration)||motion.frames.some(i=>!Number.isInteger(i)||i<0||i>=count)||motion.times.some((t,i)=>!Number.isFinite(t)||(i&&t<=motion.times[i-1])))throw Error('Invalid fetch motion metadata');
|
|
12
13
|
if(!Array.isArray(motion.floorOffsets)||motion.floorOffsets.length!==motion.frames.length||motion.floorOffsets.some(v=>!Number.isFinite(v)||Math.abs(v)>64))throw Error('Invalid fetch floor metadata');
|
|
@@ -33,16 +34,21 @@ export function createComfortSpriteSampler(bytes,info,output){
|
|
|
33
34
|
}
|
|
34
35
|
if(info.version>=4){validateMotion(info.scramble,info.frames);for(const view of ['rear','front'])validateMotion(info.pickups?.[view],info.frames);}
|
|
35
36
|
if(info.version>=6){validateMotion(info.carryTrot,info.frames);validateMotion(info.carryTrot?.settle,info.frames);if(info.carryTrot.cyclic!==true||!info.carryTrot.mouth||!info.carryTrot.settle.mouth||!Array.isArray(info.carryTrot.feet)||info.carryTrot.feet.length!==info.carryTrot.frames.length||info.carryTrot.feet.some(list=>!Array.isArray(list)||list.some(f=>typeof f.id!=='string'||typeof f.stance!=='boolean'||![f.x,f.y].every(v=>Number.isFinite(v)&&v>=0&&v<320))))throw Error('Invalid carry metadata');}
|
|
37
|
+
for(const [motion,maxKeys,maxRecovery] of [[info.attentionPaw,8,.3],[info.attentionWall,12,.4]])if(motion){
|
|
38
|
+
validateMotion(motion,info.frames);
|
|
39
|
+
if(motion.frames[0]!==0||motion.frames.at(-1)!==0||!motion.releases||Object.keys(motion.releases).length>maxKeys)throw Error('Invalid attention endpoint');
|
|
40
|
+
for(const frame of new Set(motion.frames)){const exit=motion.releases[frame];validateMotion(exit,info.frames);if(exit.frames[0]!==frame||exit.frames.at(-1)!==0||exit.duration>maxRecovery)throw Error('Invalid attention recovery');}
|
|
41
|
+
}
|
|
36
42
|
if(output!==undefined&&(!(output instanceof Uint8ClampedArray)||output.length!==320*320*4))throw Error('Invalid comfort output');
|
|
37
43
|
const frames=grayFrameReader(bytes,320,320,info.frames);let rgba=output??null;
|
|
38
44
|
if(rgba)for(let i=3;i<rgba.length;i+=4)rgba[i]=255;
|
|
39
45
|
return pose=>{
|
|
40
|
-
if(!['tug','sleep','scramble','pickup','carry-trot','carry-settle'].includes(pose?.clip))throw Error('Invalid comfort clip');
|
|
46
|
+
if(!['tug','sleep','scramble','pickup','carry-trot','carry-settle','attention-paw','attention-wall'].includes(pose?.clip))throw Error('Invalid comfort clip');
|
|
41
47
|
if(!rgba){rgba=new Uint8ClampedArray(320*320*4);for(let i=3;i<rgba.length;i+=4)rgba[i]=255;}
|
|
42
48
|
let index;
|
|
43
|
-
if(['scramble','pickup','carry-trot','carry-settle'].includes(pose.clip)){
|
|
49
|
+
if(['scramble','pickup','carry-trot','carry-settle','attention-paw','attention-wall'].includes(pose.clip)){
|
|
44
50
|
const motion=comfortMotion(pose,info);if(!motion)throw Error('Invalid scramble/pickup pose');
|
|
45
|
-
index=motion.frames[comfortMotionKey(pose
|
|
51
|
+
index=motion.frames[comfortMotionKey(comfortProgress(pose),motion)];
|
|
46
52
|
}else index=pose.clip==='sleep'?info.sleep?.[pose.variant]:comfortFrameIndex(pose.progress,info);
|
|
47
53
|
if(!Number.isInteger(index))throw Error('Invalid sleep variant');
|
|
48
54
|
const frame=frames.getFrame(index),base=pose.base,blend=pose.blend??1;
|
|
Binary file
|