@howaboua/pi-pet 0.1.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/CHANGELOG.md +16 -0
- package/LICENSE +21 -0
- package/README.md +92 -0
- package/SECURITY.md +24 -0
- package/authoring/PET-GUIDE.md +65 -0
- package/authoring/hatch/HATCH-GUIDE.md +136 -0
- package/authoring/hatch/LICENSE.txt +201 -0
- package/authoring/hatch/NOTICE.md +5 -0
- package/authoring/hatch/pyproject.toml +8 -0
- package/authoring/hatch/references/animation-rows.md +29 -0
- package/authoring/hatch/references/final-assembly.md +67 -0
- package/authoring/hatch/references/look-directions.md +35 -0
- package/authoring/hatch/references/pet-contract.md +40 -0
- package/authoring/hatch/references/qa-rubric.md +34 -0
- package/authoring/hatch/references/reviewer-protocol.md +72 -0
- package/authoring/hatch/references/standard-assembly.md +21 -0
- package/authoring/hatch/references/visual-generation.md +59 -0
- package/authoring/hatch/scripts/approve_cardinals.py +110 -0
- package/authoring/hatch/scripts/assemble_extended_atlas.py +684 -0
- package/authoring/hatch/scripts/combine_direction_blind_verdicts.py +59 -0
- package/authoring/hatch/scripts/compose_atlas.py +171 -0
- package/authoring/hatch/scripts/compose_cardinal_anchor_strip.py +45 -0
- package/authoring/hatch/scripts/derive_running_left_from_running_right.py +164 -0
- package/authoring/hatch/scripts/despill_chroma_edges.py +312 -0
- package/authoring/hatch/scripts/extract_cardinal_anchors.py +153 -0
- package/authoring/hatch/scripts/extract_strip_frames.py +409 -0
- package/authoring/hatch/scripts/inspect_frames.py +278 -0
- package/authoring/hatch/scripts/make_contact_sheet.py +116 -0
- package/authoring/hatch/scripts/make_direction_blind_qa_sheet.py +179 -0
- package/authoring/hatch/scripts/make_direction_qa_sheet.py +172 -0
- package/authoring/hatch/scripts/measure_direction_continuity.py +201 -0
- package/authoring/hatch/scripts/prepare_pet_run.py +1207 -0
- package/authoring/hatch/scripts/render_animation_previews.py +80 -0
- package/authoring/hatch/scripts/validate_atlas.py +299 -0
- package/authoring/hatch/scripts/validate_direction_blind_verdicts.py +100 -0
- package/authoring/hatch/uv.lock +99 -0
- package/authoring/references/import-existing-pet.md +47 -0
- package/authoring/references/pet-format.md +88 -0
- package/changelog.ts +327 -0
- package/deploy/pi-pet-hyprland.conf +10 -0
- package/desktop/build.mjs +194 -0
- package/desktop/package-lock.json +887 -0
- package/desktop/package.json +16 -0
- package/dist/authoring/prepare.mjs +3 -0
- package/dist/authoring/rebuild.mjs +4 -0
- package/dist/authoring/validate.mjs +2 -0
- package/dist/desktop/main.mjs +5 -0
- package/dist/desktop/preload.cjs +1 -0
- package/dist/web/app.js +1 -0
- package/dist/web/catalog.json +1 -0
- package/dist/web/index.html +100 -0
- package/dist/web/manifest.webmanifest +16 -0
- package/dist/web/pet-icon.svg +6 -0
- package/dist/web/spritesheet.webp +0 -0
- package/dist/web/styles.css +592 -0
- package/docs/architecture.md +41 -0
- package/docs/pi-pet.png +0 -0
- package/docs/research.md +17 -0
- package/extensions/desktop-command.ts +249 -0
- package/extensions/desktop-config.ts +152 -0
- package/extensions/desktop-launcher.ts +380 -0
- package/extensions/gippity.ts +24 -0
- package/extensions/index.ts +110 -0
- package/extensions/remote-app.ts +61 -0
- package/package.json +101 -0
- package/pets/clawa/PET.md +27 -0
- package/pets/clawa/pet.json +7 -0
- package/pets/clawa/spritesheet.webp +0 -0
- package/pets/clawa/validation.json +808 -0
- package/src/desktop/attention.ts +87 -0
- package/src/desktop/bridge.ts +31 -0
- package/src/desktop/config.ts +145 -0
- package/src/desktop/cursor-provider.ts +150 -0
- package/src/desktop/main.ts +459 -0
- package/src/desktop/preload.ts +19 -0
- package/src/pet-image-size.ts +72 -0
- package/src/pet-loader.ts +278 -0
- package/src/pet-storage.ts +240 -0
- package/src/protocol/index.ts +81 -0
|
@@ -0,0 +1,592 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
color-scheme: dark;
|
|
3
|
+
--ink: #f6f1e7;
|
|
4
|
+
--muted: #aba89f;
|
|
5
|
+
--faint: #77776f;
|
|
6
|
+
--ground: #171815;
|
|
7
|
+
--panel: #20211d;
|
|
8
|
+
--line: #34352f;
|
|
9
|
+
--orange: #ff941f;
|
|
10
|
+
--orange-soft: #ffc06b;
|
|
11
|
+
--teal: #3ee5d2;
|
|
12
|
+
--danger: #ff726d;
|
|
13
|
+
--radius: 18px;
|
|
14
|
+
font-family: ui-rounded, "SF Pro Rounded", "Segoe UI", system-ui, sans-serif;
|
|
15
|
+
font-synthesis: none;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
* {
|
|
19
|
+
box-sizing: border-box;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
html,
|
|
23
|
+
body {
|
|
24
|
+
min-height: 100%;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
body {
|
|
28
|
+
margin: 0;
|
|
29
|
+
color: var(--ink);
|
|
30
|
+
background:
|
|
31
|
+
radial-gradient(circle at 28% 44%, rgba(255, 148, 31, 0.09), transparent 27rem),
|
|
32
|
+
linear-gradient(115deg, #191a17, var(--ground) 62%);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
button,
|
|
36
|
+
input,
|
|
37
|
+
select,
|
|
38
|
+
textarea {
|
|
39
|
+
font: inherit;
|
|
40
|
+
}
|
|
41
|
+
button,
|
|
42
|
+
select {
|
|
43
|
+
cursor: pointer;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.shell {
|
|
47
|
+
width: min(1180px, calc(100% - 48px));
|
|
48
|
+
min-height: 100vh;
|
|
49
|
+
margin: 0 auto;
|
|
50
|
+
padding: 28px 0 36px;
|
|
51
|
+
display: grid;
|
|
52
|
+
grid-template-rows: auto 1fr;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.masthead {
|
|
56
|
+
display: flex;
|
|
57
|
+
align-items: center;
|
|
58
|
+
justify-content: space-between;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.wordmark {
|
|
62
|
+
display: inline-flex;
|
|
63
|
+
align-items: baseline;
|
|
64
|
+
gap: 7px;
|
|
65
|
+
color: var(--ink);
|
|
66
|
+
text-decoration: none;
|
|
67
|
+
font-weight: 760;
|
|
68
|
+
letter-spacing: -0.04em;
|
|
69
|
+
font-size: 20px;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.wordmark-mark,
|
|
73
|
+
.dialog-mark {
|
|
74
|
+
color: var(--orange);
|
|
75
|
+
font-family: Georgia, serif;
|
|
76
|
+
font-weight: 700;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.connection {
|
|
80
|
+
display: inline-flex;
|
|
81
|
+
align-items: center;
|
|
82
|
+
gap: 8px;
|
|
83
|
+
color: var(--muted);
|
|
84
|
+
font-size: 13px;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.connection-dot {
|
|
88
|
+
width: 8px;
|
|
89
|
+
height: 8px;
|
|
90
|
+
border-radius: 50%;
|
|
91
|
+
background: var(--faint);
|
|
92
|
+
box-shadow: 0 0 0 4px rgba(119, 119, 111, 0.12);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.connection-dot.online {
|
|
96
|
+
background: var(--teal);
|
|
97
|
+
box-shadow:
|
|
98
|
+
0 0 0 4px rgba(62, 229, 210, 0.11),
|
|
99
|
+
0 0 16px rgba(62, 229, 210, 0.35);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.companion-layout {
|
|
103
|
+
align-self: center;
|
|
104
|
+
display: grid;
|
|
105
|
+
grid-template-columns: minmax(440px, 1.35fr) minmax(320px, 0.65fr);
|
|
106
|
+
align-items: center;
|
|
107
|
+
gap: clamp(44px, 8vw, 110px);
|
|
108
|
+
padding: 64px 0 30px;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.stage {
|
|
112
|
+
min-height: 560px;
|
|
113
|
+
position: relative;
|
|
114
|
+
display: grid;
|
|
115
|
+
place-items: center;
|
|
116
|
+
isolation: isolate;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.stage::before {
|
|
120
|
+
content: "";
|
|
121
|
+
position: absolute;
|
|
122
|
+
width: min(82%, 480px);
|
|
123
|
+
aspect-ratio: 1;
|
|
124
|
+
border-radius: 50%;
|
|
125
|
+
background: radial-gradient(circle, rgba(255, 148, 31, 0.12), rgba(255, 148, 31, 0.025) 49%, transparent 70%);
|
|
126
|
+
filter: blur(2px);
|
|
127
|
+
z-index: -2;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.stage::after {
|
|
131
|
+
content: "";
|
|
132
|
+
position: absolute;
|
|
133
|
+
width: 270px;
|
|
134
|
+
height: 34px;
|
|
135
|
+
bottom: 105px;
|
|
136
|
+
border-radius: 50%;
|
|
137
|
+
background: rgba(0, 0, 0, 0.26);
|
|
138
|
+
filter: blur(14px);
|
|
139
|
+
z-index: -1;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
#pet-canvas {
|
|
143
|
+
width: min(390px, 72vw);
|
|
144
|
+
height: auto;
|
|
145
|
+
aspect-ratio: 192 / 208;
|
|
146
|
+
image-rendering: auto;
|
|
147
|
+
filter: drop-shadow(0 20px 24px rgba(0, 0, 0, 0.24));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.pet-hit-area {
|
|
151
|
+
position: absolute;
|
|
152
|
+
width: min(330px, 62vw);
|
|
153
|
+
aspect-ratio: 1;
|
|
154
|
+
border: 0;
|
|
155
|
+
background: transparent;
|
|
156
|
+
border-radius: 48%;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.pet-hit-area:focus-visible {
|
|
160
|
+
outline: 2px solid var(--teal);
|
|
161
|
+
outline-offset: 10px;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.pointer-hint {
|
|
165
|
+
position: absolute;
|
|
166
|
+
bottom: 56px;
|
|
167
|
+
margin: 0;
|
|
168
|
+
color: var(--faint);
|
|
169
|
+
font-size: 12px;
|
|
170
|
+
letter-spacing: 0.02em;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.bubble {
|
|
174
|
+
position: absolute;
|
|
175
|
+
z-index: 4;
|
|
176
|
+
top: 18px;
|
|
177
|
+
left: 55%;
|
|
178
|
+
width: min(270px, 70%);
|
|
179
|
+
padding: 14px 16px;
|
|
180
|
+
color: #29251f;
|
|
181
|
+
background: #fff7e9;
|
|
182
|
+
border: 2px solid #1d1d1a;
|
|
183
|
+
border-radius: 18px 18px 18px 5px;
|
|
184
|
+
box-shadow: 5px 6px 0 #1d1d1a;
|
|
185
|
+
font-size: 14px;
|
|
186
|
+
line-height: 1.4;
|
|
187
|
+
animation: bubble-in 180ms ease-out;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.desktop-prompt {
|
|
191
|
+
display: none;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.console {
|
|
195
|
+
align-self: stretch;
|
|
196
|
+
padding: 12px 0;
|
|
197
|
+
display: flex;
|
|
198
|
+
flex-direction: column;
|
|
199
|
+
justify-content: center;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.console > section,
|
|
203
|
+
.identity {
|
|
204
|
+
padding: 23px 0;
|
|
205
|
+
border-bottom: 1px solid var(--line);
|
|
206
|
+
}
|
|
207
|
+
.console > section:last-child {
|
|
208
|
+
border-bottom: 0;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.eyebrow {
|
|
212
|
+
margin: 0 0 8px;
|
|
213
|
+
color: var(--orange-soft);
|
|
214
|
+
font-size: 11px;
|
|
215
|
+
font-weight: 760;
|
|
216
|
+
letter-spacing: 0.14em;
|
|
217
|
+
text-transform: uppercase;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
h1,
|
|
221
|
+
h2,
|
|
222
|
+
p {
|
|
223
|
+
margin-top: 0;
|
|
224
|
+
}
|
|
225
|
+
h1 {
|
|
226
|
+
margin-bottom: 10px;
|
|
227
|
+
font-size: clamp(38px, 5vw, 58px);
|
|
228
|
+
line-height: 0.94;
|
|
229
|
+
letter-spacing: -0.055em;
|
|
230
|
+
}
|
|
231
|
+
h2 {
|
|
232
|
+
margin: 0;
|
|
233
|
+
font-size: 13px;
|
|
234
|
+
letter-spacing: 0.01em;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.description {
|
|
238
|
+
max-width: 38ch;
|
|
239
|
+
margin-bottom: 0;
|
|
240
|
+
color: var(--muted);
|
|
241
|
+
font-size: 14px;
|
|
242
|
+
line-height: 1.55;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.section-heading {
|
|
246
|
+
display: flex;
|
|
247
|
+
justify-content: space-between;
|
|
248
|
+
align-items: baseline;
|
|
249
|
+
margin-bottom: 14px;
|
|
250
|
+
}
|
|
251
|
+
.quiet {
|
|
252
|
+
color: var(--faint);
|
|
253
|
+
font-size: 12px;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.current-state {
|
|
257
|
+
display: flex;
|
|
258
|
+
align-items: baseline;
|
|
259
|
+
gap: 12px;
|
|
260
|
+
min-width: 0;
|
|
261
|
+
}
|
|
262
|
+
.action-name {
|
|
263
|
+
color: var(--teal);
|
|
264
|
+
font-size: 21px;
|
|
265
|
+
font-weight: 740;
|
|
266
|
+
letter-spacing: -0.025em;
|
|
267
|
+
}
|
|
268
|
+
.action-note {
|
|
269
|
+
color: var(--muted);
|
|
270
|
+
font-size: 13px;
|
|
271
|
+
overflow: hidden;
|
|
272
|
+
text-overflow: ellipsis;
|
|
273
|
+
white-space: nowrap;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.text-button {
|
|
277
|
+
padding: 0;
|
|
278
|
+
color: var(--orange-soft);
|
|
279
|
+
border: 0;
|
|
280
|
+
background: transparent;
|
|
281
|
+
font-size: 12px;
|
|
282
|
+
}
|
|
283
|
+
.text-button:hover {
|
|
284
|
+
color: var(--ink);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.quick-actions {
|
|
288
|
+
display: flex;
|
|
289
|
+
flex-wrap: wrap;
|
|
290
|
+
gap: 7px;
|
|
291
|
+
margin-bottom: 13px;
|
|
292
|
+
}
|
|
293
|
+
.quick-actions button {
|
|
294
|
+
min-height: 34px;
|
|
295
|
+
padding: 6px 11px;
|
|
296
|
+
color: var(--muted);
|
|
297
|
+
border: 1px solid var(--line);
|
|
298
|
+
border-radius: 999px;
|
|
299
|
+
background: transparent;
|
|
300
|
+
font-size: 12px;
|
|
301
|
+
}
|
|
302
|
+
.quick-actions button:hover,
|
|
303
|
+
.quick-actions button:focus-visible {
|
|
304
|
+
color: var(--ink);
|
|
305
|
+
border-color: #65665d;
|
|
306
|
+
background: #292a25;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.select-label {
|
|
310
|
+
display: block;
|
|
311
|
+
margin-bottom: 6px;
|
|
312
|
+
color: var(--faint);
|
|
313
|
+
font-size: 11px;
|
|
314
|
+
}
|
|
315
|
+
select,
|
|
316
|
+
textarea {
|
|
317
|
+
width: 100%;
|
|
318
|
+
color: var(--ink);
|
|
319
|
+
border: 1px solid var(--line);
|
|
320
|
+
border-radius: 11px;
|
|
321
|
+
background: #1c1d1a;
|
|
322
|
+
outline: none;
|
|
323
|
+
}
|
|
324
|
+
select {
|
|
325
|
+
height: 40px;
|
|
326
|
+
padding: 0 10px;
|
|
327
|
+
}
|
|
328
|
+
textarea {
|
|
329
|
+
resize: vertical;
|
|
330
|
+
min-height: 78px;
|
|
331
|
+
padding: 11px 12px;
|
|
332
|
+
line-height: 1.45;
|
|
333
|
+
}
|
|
334
|
+
select:focus,
|
|
335
|
+
textarea:focus {
|
|
336
|
+
border-color: var(--teal);
|
|
337
|
+
box-shadow: 0 0 0 3px rgba(62, 229, 210, 0.1);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.prompt-section form {
|
|
341
|
+
display: grid;
|
|
342
|
+
gap: 9px;
|
|
343
|
+
}
|
|
344
|
+
.prompt-footer {
|
|
345
|
+
display: flex;
|
|
346
|
+
align-items: center;
|
|
347
|
+
justify-content: space-between;
|
|
348
|
+
gap: 12px;
|
|
349
|
+
}
|
|
350
|
+
.prompt-buttons {
|
|
351
|
+
display: flex;
|
|
352
|
+
align-items: center;
|
|
353
|
+
gap: 7px;
|
|
354
|
+
}
|
|
355
|
+
.prompt-feedback {
|
|
356
|
+
min-height: 18px;
|
|
357
|
+
color: var(--muted);
|
|
358
|
+
font-size: 12px;
|
|
359
|
+
}
|
|
360
|
+
.send-button {
|
|
361
|
+
min-height: 38px;
|
|
362
|
+
padding: 8px 16px;
|
|
363
|
+
color: #24170a;
|
|
364
|
+
border: 0;
|
|
365
|
+
border-radius: 10px;
|
|
366
|
+
background: var(--orange);
|
|
367
|
+
font-weight: 780;
|
|
368
|
+
font-size: 13px;
|
|
369
|
+
}
|
|
370
|
+
.send-button:hover {
|
|
371
|
+
background: #ffad4c;
|
|
372
|
+
}
|
|
373
|
+
.send-button:disabled,
|
|
374
|
+
.voice-button:disabled {
|
|
375
|
+
cursor: not-allowed;
|
|
376
|
+
opacity: 0.4;
|
|
377
|
+
}
|
|
378
|
+
.voice-button {
|
|
379
|
+
min-height: 38px;
|
|
380
|
+
padding: 8px 13px;
|
|
381
|
+
color: var(--orange-soft);
|
|
382
|
+
border: 1px solid var(--line);
|
|
383
|
+
border-radius: 10px;
|
|
384
|
+
background: transparent;
|
|
385
|
+
font-size: 12px;
|
|
386
|
+
font-weight: 700;
|
|
387
|
+
}
|
|
388
|
+
.voice-button:hover {
|
|
389
|
+
color: var(--ink);
|
|
390
|
+
border-color: #65665d;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
.sr-only {
|
|
394
|
+
position: absolute;
|
|
395
|
+
width: 1px;
|
|
396
|
+
height: 1px;
|
|
397
|
+
padding: 0;
|
|
398
|
+
margin: -1px;
|
|
399
|
+
overflow: hidden;
|
|
400
|
+
clip: rect(0, 0, 0, 0);
|
|
401
|
+
white-space: nowrap;
|
|
402
|
+
border: 0;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
@keyframes bubble-in {
|
|
406
|
+
from {
|
|
407
|
+
opacity: 0;
|
|
408
|
+
transform: translateY(8px) scale(0.96);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
@media (max-width: 820px) {
|
|
413
|
+
.shell {
|
|
414
|
+
width: min(100% - 30px, 620px);
|
|
415
|
+
}
|
|
416
|
+
.companion-layout {
|
|
417
|
+
grid-template-columns: 1fr;
|
|
418
|
+
gap: 0;
|
|
419
|
+
padding-top: 24px;
|
|
420
|
+
}
|
|
421
|
+
.stage {
|
|
422
|
+
min-height: 430px;
|
|
423
|
+
}
|
|
424
|
+
.stage::after {
|
|
425
|
+
bottom: 62px;
|
|
426
|
+
}
|
|
427
|
+
.pointer-hint {
|
|
428
|
+
bottom: 22px;
|
|
429
|
+
}
|
|
430
|
+
.bubble {
|
|
431
|
+
top: 0;
|
|
432
|
+
}
|
|
433
|
+
.console {
|
|
434
|
+
padding-top: 0;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
html.desktop-shell,
|
|
439
|
+
html.desktop-shell body {
|
|
440
|
+
width: 100%;
|
|
441
|
+
height: 100%;
|
|
442
|
+
min-height: 0;
|
|
443
|
+
overflow: hidden;
|
|
444
|
+
background: transparent;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
.desktop-shell .shell {
|
|
448
|
+
width: 100%;
|
|
449
|
+
height: 100%;
|
|
450
|
+
min-height: 0;
|
|
451
|
+
padding: 0;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
.desktop-shell .masthead,
|
|
455
|
+
.desktop-shell .console,
|
|
456
|
+
.desktop-shell .pointer-hint {
|
|
457
|
+
display: none;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
.desktop-shell .companion-layout {
|
|
461
|
+
display: block;
|
|
462
|
+
width: 100%;
|
|
463
|
+
height: 100%;
|
|
464
|
+
padding: 0;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
.desktop-shell .stage {
|
|
468
|
+
width: 100%;
|
|
469
|
+
height: 100%;
|
|
470
|
+
min-height: 0;
|
|
471
|
+
-webkit-app-region: drag;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
.desktop-shell .stage::before,
|
|
475
|
+
.desktop-shell .stage::after {
|
|
476
|
+
display: none;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
.desktop-shell #pet-canvas {
|
|
480
|
+
width: 100%;
|
|
481
|
+
height: 100%;
|
|
482
|
+
filter: drop-shadow(0 12px 10px rgba(0, 0, 0, 0.2));
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
.desktop-shell .pet-hit-area {
|
|
486
|
+
width: 82%;
|
|
487
|
+
-webkit-app-region: no-drag;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
.desktop-shell .bubble {
|
|
491
|
+
top: 8px;
|
|
492
|
+
right: 8px;
|
|
493
|
+
left: 8px;
|
|
494
|
+
width: auto;
|
|
495
|
+
padding: 9px 11px;
|
|
496
|
+
border-width: 1px;
|
|
497
|
+
border-radius: 13px 13px 13px 4px;
|
|
498
|
+
box-shadow: 3px 4px 0 #1d1d1a;
|
|
499
|
+
font-size: 12px;
|
|
500
|
+
-webkit-app-region: no-drag;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
.desktop-shell .desktop-prompt {
|
|
504
|
+
position: absolute;
|
|
505
|
+
z-index: 6;
|
|
506
|
+
right: 8px;
|
|
507
|
+
bottom: 8px;
|
|
508
|
+
left: 8px;
|
|
509
|
+
display: grid;
|
|
510
|
+
gap: 6px;
|
|
511
|
+
padding: 10px;
|
|
512
|
+
color: var(--ink);
|
|
513
|
+
border: 1px solid rgba(255, 192, 107, 0.55);
|
|
514
|
+
border-radius: 14px;
|
|
515
|
+
background: rgba(28, 29, 26, 0.96);
|
|
516
|
+
box-shadow: 0 12px 28px rgba(0, 0, 0, 0.38);
|
|
517
|
+
-webkit-app-region: no-drag;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
.desktop-shell .desktop-prompt[hidden] {
|
|
521
|
+
display: none;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
.desktop-prompt-heading,
|
|
525
|
+
.desktop-prompt-footer {
|
|
526
|
+
display: flex;
|
|
527
|
+
align-items: center;
|
|
528
|
+
justify-content: space-between;
|
|
529
|
+
gap: 8px;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
.desktop-prompt-heading label {
|
|
533
|
+
color: var(--orange-soft);
|
|
534
|
+
font-size: 11px;
|
|
535
|
+
font-weight: 760;
|
|
536
|
+
letter-spacing: 0.04em;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
.desktop-prompt-heading button {
|
|
540
|
+
width: 22px;
|
|
541
|
+
height: 22px;
|
|
542
|
+
padding: 0;
|
|
543
|
+
color: var(--muted);
|
|
544
|
+
border: 0;
|
|
545
|
+
background: transparent;
|
|
546
|
+
font-size: 18px;
|
|
547
|
+
line-height: 1;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
.desktop-shell .desktop-prompt textarea {
|
|
551
|
+
min-height: 50px;
|
|
552
|
+
max-height: 92px;
|
|
553
|
+
resize: none;
|
|
554
|
+
padding: 8px 9px;
|
|
555
|
+
border-color: #4a4b43;
|
|
556
|
+
border-radius: 9px;
|
|
557
|
+
font-size: 12px;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
.desktop-prompt-footer span {
|
|
561
|
+
min-width: 0;
|
|
562
|
+
overflow: hidden;
|
|
563
|
+
color: var(--muted);
|
|
564
|
+
font-size: 10px;
|
|
565
|
+
text-overflow: ellipsis;
|
|
566
|
+
white-space: nowrap;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
.desktop-prompt-footer button {
|
|
570
|
+
min-height: 28px;
|
|
571
|
+
padding: 5px 11px;
|
|
572
|
+
color: #24170a;
|
|
573
|
+
border: 0;
|
|
574
|
+
border-radius: 8px;
|
|
575
|
+
background: var(--orange);
|
|
576
|
+
font-size: 11px;
|
|
577
|
+
font-weight: 780;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
.desktop-prompt-footer .voice-button {
|
|
581
|
+
color: var(--orange-soft);
|
|
582
|
+
border: 1px solid #4a4b43;
|
|
583
|
+
background: transparent;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
.desktop-prompt-footer button:disabled {
|
|
587
|
+
opacity: 0.42;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
.desktop-shell.conversation-open #pet-canvas {
|
|
591
|
+
filter: drop-shadow(0 12px 10px rgba(0, 0, 0, 0.2)) brightness(0.86);
|
|
592
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
```mermaid
|
|
4
|
+
flowchart LR
|
|
5
|
+
Pi[Pi session] --> G[GipPity Control]
|
|
6
|
+
Pi --> Route[Folder device selection]
|
|
7
|
+
Route --> Local[Owned local Node child]
|
|
8
|
+
Route --> SSH[Owned SSH command]
|
|
9
|
+
Local --> Build[Versioned source + build in ~/.pi/agent/pi-pet]
|
|
10
|
+
SSH --> Build
|
|
11
|
+
Build --> Electron[Transparent Electron shell]
|
|
12
|
+
G --> SDK[GipPity Remote mini-SDK]
|
|
13
|
+
SDK --> Web[Pi Pet web miniapp]
|
|
14
|
+
Store[Durable pets + runs in Pi agent directory] --> Web
|
|
15
|
+
Web --> Browser[Browser or PWA]
|
|
16
|
+
Web --> Electron
|
|
17
|
+
Pet[Pi Pet extension: pet_show] --> G
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Ownership
|
|
21
|
+
|
|
22
|
+
- GipPity owns the HTTPS server, active Pi session, browser events, prompts, drafts, voice, reconnection, and namespaced static delivery under `/_gippity/apps/pi-pet/`.
|
|
23
|
+
- `extensions/` registers Pi Pet's built web root and one bounded reaction snapshot through GipPity's remote-app bridge. It also owns each folder-selected local or SSH device process for exactly the lifetime of that Pi session.
|
|
24
|
+
- `src/web/` owns catalog loading, canvas animation, pointer direction, local previews, prompt presentation, and voice controls. It uses only the hosted `GippityRemote` SDK.
|
|
25
|
+
- `src/desktop/` owns the transparent native window, local attention preferences, navigation confinement, and a cursor-only sandboxed preload.
|
|
26
|
+
- `src/protocol/` owns pet/catalog and reaction-state shapes.
|
|
27
|
+
- `src/pet-loader.ts` validates inert pet data and assets during builds.
|
|
28
|
+
- `src/pet-storage.ts` selects durable user pets from the Pi agent directory and falls back visibly to the bundled pet.
|
|
29
|
+
- `authoring/` is read on demand through free-form `/pet` requests; it is shipped as package data, not registered as an always-visible skill.
|
|
30
|
+
|
|
31
|
+
An attached device keeps Pi Pet at `~/.pi/agent/pi-pet` without installing an application. The direct local child or SSH command compares its build record with the version and source digest of the package loaded by Pi. A mismatch updates the source and runs npm install and build; a match starts the existing build directly. Closing its Pi owner closes Electron through an inherited pipe but leaves the source and build for the next Pi session.
|
|
32
|
+
|
|
33
|
+
## State flow
|
|
34
|
+
|
|
35
|
+
GipPity sends its retained `idle`, `working`, and `settled` activity plus ordinary Pi events. The miniapp maps them onto the pet's standard actions and derives waiting/failure presentation from tool events. Settled assistant text becomes one bounded temporary bubble.
|
|
36
|
+
|
|
37
|
+
`pet_show` publishes the latest explicit reaction through the in-process remote-app bridge. Its versioned state identifies the pet catalog and carries a revision, action, and optional note. GipPity broadcasts it as `app.state` and replays the snapshot to newly connected or reconnecting renderers whether or not Electron is attached. The browser SDK requires no pet-specific transport.
|
|
38
|
+
|
|
39
|
+
## Pet flow
|
|
40
|
+
|
|
41
|
+
The npm package's `pets/` directory contains templates. Authoring copies and modifies pets under `<pi-agent-directory>/pi-pet/pets/`, keeps generation evidence under `runs/`, and writes each validated miniapp under `web/<pet-id>/`. Global `config.json` selects the default pet; project `<config-directory>/pi-pet.json` may override it by ID without duplicating assets. The adjacent global `pi-pet.json` registers reusable device definitions, while the project config selects which devices receive sessions from that folder. On reload the extension serves the repository selection, global default, or bundled Clawa in that order and starts only the folder's selected devices. Invalid higher-precedence state is reported visibly.
|
package/docs/pi-pet.png
ADDED
|
Binary file
|
package/docs/research.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Pet evidence
|
|
2
|
+
|
|
3
|
+
## Atlas contract
|
|
4
|
+
|
|
5
|
+
The retained Clawa fixture establishes Pi Pet's Codex-v2 `1536x2288`, 8×11, `192x208` atlas: nine standard action rows, sixteen clockwise look directions, and the minimal `pet.json` package. Clawa's committed validation reports no errors or warnings.
|
|
6
|
+
|
|
7
|
+
OpenAI's public Hatch Pet skill confirms deterministic spritesheet creation, validation, visual QA, and `pet.json` packaging for the legacy 8×9 contract: <https://github.com/openai/skills/tree/main/skills/.curated/hatch-pet>
|
|
8
|
+
|
|
9
|
+
Codex issue #20863 documents that current animation timing, chaining, and activity triggers are hardcoded rather than pet-manifest driven: <https://github.com/openai/codex/issues/20863>
|
|
10
|
+
|
|
11
|
+
Codex issue #21657 requests click, hover, drag, and first-party action hooks, indicating those interaction APIs are not currently available: <https://github.com/openai/codex/issues/21657>
|
|
12
|
+
|
|
13
|
+
## Pi and GipPity integration
|
|
14
|
+
|
|
15
|
+
Pi's extension API provides lifecycle, tool, settlement, and user-message primitives. GipPity Remote already reduces those events into browser activity, carries complete bounded Pi events, accepts synchronized prompts, and owns realtime voice. Pi Pet therefore registers a static miniapp and reaction snapshot instead of reproducing those transports.
|
|
16
|
+
|
|
17
|
+
The browser-to-Pi prompt bridge and transparent desktop presentation are Pi/GipPity additions, not claims of Codex desktop parity.
|