pi-better-openai 0.1.12 → 0.1.14
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/README.md +1 -1
- package/index.ts +16 -11
- package/package.json +1 -1
- package/src/pets.ts +10 -1
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@ pi install npm:pi-better-openai
|
|
|
36
36
|
Codex pets are an OpenAI Codex app feature, so the floating overlay and pet picker are still controlled by Codex (`Settings → Appearance → Pets` or `/pet`). This extension can also render compatible custom pet spritesheets directly in pi's Better OpenAI footer.
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
|
-
/pets wake # render the selected pet, or
|
|
39
|
+
/pets wake # render the selected pet, or pick one if none is selected
|
|
40
40
|
/pets wake <slug> # render a specific ready pet
|
|
41
41
|
/pets select <slug> # select a ready pet without changing visibility
|
|
42
42
|
/pets tuck # hide it
|
package/index.ts
CHANGED
|
@@ -66,7 +66,7 @@ import {
|
|
|
66
66
|
listCodexPets,
|
|
67
67
|
nextAnimationFrameDelayMs,
|
|
68
68
|
PET_ANIMATION_ROWS,
|
|
69
|
-
|
|
69
|
+
deleteCodexPetKittyImage,
|
|
70
70
|
registerOpenAIPets,
|
|
71
71
|
renderCodexPetFrame,
|
|
72
72
|
resetCodexPetKittyCache,
|
|
@@ -79,7 +79,7 @@ const OPENAI_SETTINGS_COMMAND = "openai-settings";
|
|
|
79
79
|
const FLAG = "fast";
|
|
80
80
|
const PET_RESIZE_FREEZE_MS = 120;
|
|
81
81
|
const PET_RENDER_CACHE_LIMIT = 48;
|
|
82
|
-
const
|
|
82
|
+
const PET_EMPTY_VALUE = "not selected";
|
|
83
83
|
const SERVICE_TIER = "priority";
|
|
84
84
|
type SettingsPickerItem = {
|
|
85
85
|
id: string;
|
|
@@ -146,15 +146,15 @@ function petSizeCellsForPlacement(placement: PetPlacement, sizeCells: number): n
|
|
|
146
146
|
|
|
147
147
|
function readyPetPickerValues(pets: CodexPetPackage[]): string[] | undefined {
|
|
148
148
|
const readyPets = pets.filter((pet) => pet.hasSpritesheet);
|
|
149
|
-
return readyPets.length > 0 ?
|
|
149
|
+
return readyPets.length > 0 ? readyPets.map((pet) => pet.slug) : undefined;
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
function petConfigPickerValue(cfg: ResolvedConfig): string {
|
|
153
|
-
return cfg.pets.slug ||
|
|
153
|
+
return cfg.pets.slug || PET_EMPTY_VALUE;
|
|
154
154
|
}
|
|
155
155
|
|
|
156
156
|
function petSlugFromPickerValue(value: string): string {
|
|
157
|
-
return value ===
|
|
157
|
+
return value === PET_EMPTY_VALUE ? "" : value;
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
function petPickerLookupKey(value: string): string {
|
|
@@ -177,9 +177,14 @@ function petPickerDescription(cfg: ResolvedConfig, pets: CodexPetPackage[]): str
|
|
|
177
177
|
const readyPets = pets.filter((pet) => pet.hasSpritesheet);
|
|
178
178
|
if (readyPets.length === 0)
|
|
179
179
|
return "No ready custom pets found. Use /pets help to create one, then return here.";
|
|
180
|
-
|
|
180
|
+
if (!cfg.pets.slug) {
|
|
181
|
+
const firstPet = readyPets[0];
|
|
182
|
+
const lastPet = readyPets[readyPets.length - 1];
|
|
183
|
+
return `No pet selected. Enter/Space/→ selects ${firstPet.name}; ← selects ${lastPet.name}.`;
|
|
184
|
+
}
|
|
185
|
+
const selectedPet = findPickerPet(cfg.pets.slug, readyPets);
|
|
181
186
|
const selected = selectedPet
|
|
182
|
-
?
|
|
187
|
+
? `Selected: ${selectedPet.name} (${selectedPet.slug})`
|
|
183
188
|
: `Selected: ${cfg.pets.slug}`;
|
|
184
189
|
return `${selected}. Enter/Space/→ cycles pets; ← cycles back. Preview appears in the footer while this menu is open.`;
|
|
185
190
|
}
|
|
@@ -462,7 +467,7 @@ export default function betterOpenAI(pi: ExtensionAPI): void {
|
|
|
462
467
|
function takePetKittyCleanupSequence(): string {
|
|
463
468
|
if (pendingPetKittyCleanupImageIds.size === 0) return "";
|
|
464
469
|
const sequence = Array.from(pendingPetKittyCleanupImageIds)
|
|
465
|
-
.map((imageId) =>
|
|
470
|
+
.map((imageId) => deleteCodexPetKittyImage(imageId))
|
|
466
471
|
.join("");
|
|
467
472
|
pendingPetKittyCleanupImageIds.clear();
|
|
468
473
|
return sequence;
|
|
@@ -885,7 +890,7 @@ export default function betterOpenAI(pi: ExtensionAPI): void {
|
|
|
885
890
|
`Image enabled: ${cfg.image.enabled}`,
|
|
886
891
|
`Image default save: ${cfg.image.defaultSave}`,
|
|
887
892
|
`Pet enabled: ${cfg.pets.enabled}`,
|
|
888
|
-
`Pet slug: ${cfg.pets.slug ||
|
|
893
|
+
`Pet slug: ${cfg.pets.slug || PET_EMPTY_VALUE}`,
|
|
889
894
|
`Pet placement: ${cfg.pets.placement}`,
|
|
890
895
|
`Pet failed tool state: ${cfg.pets.failedToolState}`,
|
|
891
896
|
`Pet idle emotes: ${cfg.pets.idleEmotes} (${cfg.pets.idleEmoteIntervalMs}ms)`,
|
|
@@ -1477,7 +1482,7 @@ export default function betterOpenAI(pi: ExtensionAPI): void {
|
|
|
1477
1482
|
|
|
1478
1483
|
const next = writePetConfig(ctx, {
|
|
1479
1484
|
enabled: true,
|
|
1480
|
-
|
|
1485
|
+
slug: selectedPet.slug,
|
|
1481
1486
|
});
|
|
1482
1487
|
updateFooter(ctx);
|
|
1483
1488
|
await refreshPet(ctx, next, true);
|
|
@@ -1957,7 +1962,7 @@ export const _test = {
|
|
|
1957
1962
|
readRawConfig,
|
|
1958
1963
|
supportsFast,
|
|
1959
1964
|
combineInlinePetFooter,
|
|
1960
|
-
|
|
1965
|
+
PET_EMPTY_VALUE,
|
|
1961
1966
|
readyPetPickerValues,
|
|
1962
1967
|
petConfigPickerValue,
|
|
1963
1968
|
petSlugFromPickerValue,
|
package/package.json
CHANGED
package/src/pets.ts
CHANGED
|
@@ -415,6 +415,10 @@ export function deleteCodexPetKittyPlacement(imageId: number): string {
|
|
|
415
415
|
return `\x1b_Ga=d,d=i,i=${imageId},p=1,q=2\x1b\\`;
|
|
416
416
|
}
|
|
417
417
|
|
|
418
|
+
export function deleteCodexPetKittyImage(imageId: number): string {
|
|
419
|
+
return `\x1b_Ga=d,d=I,i=${imageId},q=2\x1b\\`;
|
|
420
|
+
}
|
|
421
|
+
|
|
418
422
|
function placeKittyImage(imageId: number, columns: number, rows: number): string {
|
|
419
423
|
return `\x1b_Ga=p,i=${imageId},p=1,c=${columns},r=${rows},q=2,C=1\x1b\\`;
|
|
420
424
|
}
|
|
@@ -467,7 +471,12 @@ function renderKittyPetFrame(
|
|
|
467
471
|
const upload = frame.kittyUploaded ? "" : encodeKittyRawRgba(frame, frameImageId);
|
|
468
472
|
frame.kittyUploaded = true;
|
|
469
473
|
previousKittyFrameByPlacement.set(options.imageId, frameImageId);
|
|
470
|
-
|
|
474
|
+
// Recent pi-tui versions automatically free Kitty image IDs they own on changed lines.
|
|
475
|
+
// Pet frames are managed here and intentionally reused across animation loops, so keep
|
|
476
|
+
// the first Kitty command pointed at a harmless footer-placement ID, not a frame ID.
|
|
477
|
+
const hostCleanupSentinel =
|
|
478
|
+
frameImageId !== options.imageId ? deleteCodexPetKittyPlacement(options.imageId) : "";
|
|
479
|
+
const sequence = `${hostCleanupSentinel}${deletePrevious}${deleteCurrent}${upload}${placeKittyImage(frameImageId, columns, rows)}`;
|
|
471
480
|
const lines: string[] = [];
|
|
472
481
|
for (let i = 0; i < rows - 1; i++) lines.push("");
|
|
473
482
|
const moveUp = rows > 1 ? `\x1b[${rows - 1}A` : "";
|