pi-extensions 0.1.9
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/.ralph/import-cc-codex.md +31 -0
- package/.ralph/import-cc-codex.state.json +14 -0
- package/.ralph/mario-not-impl.md +69 -0
- package/.ralph/mario-not-impl.state.json +14 -0
- package/.ralph/mario-not-spec.md +163 -0
- package/.ralph/mario-not-spec.state.json +14 -0
- package/LICENSE +21 -0
- package/README.md +65 -0
- package/RELEASING.md +34 -0
- package/agent-guidance/CHANGELOG.md +4 -0
- package/agent-guidance/README.md +102 -0
- package/agent-guidance/agent-guidance.ts +147 -0
- package/agent-guidance/package.json +22 -0
- package/agent-guidance/setup.sh +75 -0
- package/agent-guidance/templates/CLAUDE.md +5 -0
- package/agent-guidance/templates/CODEX.md +92 -0
- package/agent-guidance/templates/GEMINI.md +5 -0
- package/arcade/CHANGELOG.md +4 -0
- package/arcade/README.md +85 -0
- package/arcade/assets/picman.png +0 -0
- package/arcade/assets/ping.png +0 -0
- package/arcade/assets/spice-invaders.png +0 -0
- package/arcade/assets/tetris.png +0 -0
- package/arcade/mario-not/README.md +30 -0
- package/arcade/mario-not/boss.js +103 -0
- package/arcade/mario-not/camera.js +59 -0
- package/arcade/mario-not/collision.js +91 -0
- package/arcade/mario-not/colors.js +36 -0
- package/arcade/mario-not/constants.js +97 -0
- package/arcade/mario-not/core.js +39 -0
- package/arcade/mario-not/death.js +77 -0
- package/arcade/mario-not/effects.js +84 -0
- package/arcade/mario-not/enemies.js +31 -0
- package/arcade/mario-not/engine.js +171 -0
- package/arcade/mario-not/fireballs.js +98 -0
- package/arcade/mario-not/items.js +24 -0
- package/arcade/mario-not/levels.js +403 -0
- package/arcade/mario-not/logic.js +104 -0
- package/arcade/mario-not/mario-not.ts +297 -0
- package/arcade/mario-not/player.js +244 -0
- package/arcade/mario-not/render.js +257 -0
- package/arcade/mario-not/spec.md +548 -0
- package/arcade/mario-not/state.js +246 -0
- package/arcade/mario-not/tests/e2e.test.js +855 -0
- package/arcade/mario-not/tests/engine.test.js +888 -0
- package/arcade/mario-not/tests/fixtures/story0-frame.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story1-camera.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story1-glyphs.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story10-item.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story11-hazards.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story12-used-block.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story13-pipes.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story14-goal.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story15-hud-narrow.txt +2 -0
- package/arcade/mario-not/tests/fixtures/story16-unknown-tile.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story17-mix.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story18-hud-score.txt +2 -0
- package/arcade/mario-not/tests/fixtures/story19-cue.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story2-enemy.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story20-camera-offset.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story21-hud-zero.txt +2 -0
- package/arcade/mario-not/tests/fixtures/story22-big-viewport.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story23-camera-negative.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story24-camera-width.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story25-camera-positive.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story26-hud-lives.txt +2 -0
- package/arcade/mario-not/tests/fixtures/story27-hud-coins.txt +2 -0
- package/arcade/mario-not/tests/fixtures/story28-item-viewport.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story29-enemy-viewport.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story3-hud.txt +2 -0
- package/arcade/mario-not/tests/fixtures/story30-hud-score.txt +2 -0
- package/arcade/mario-not/tests/fixtures/story31-particles-viewport.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story32-paused-frame.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story4-big.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story5-resume-hud.txt +2 -0
- package/arcade/mario-not/tests/fixtures/story6-particles.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story6-paused.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story7-powerup.txt +4 -0
- package/arcade/mario-not/tests/fixtures/story8-hud-time.txt +2 -0
- package/arcade/mario-not/tests/fixtures/story9-hud-level.txt +2 -0
- package/arcade/mario-not/tiles.js +79 -0
- package/arcade/mario-not/tsconfig.json +14 -0
- package/arcade/mario-not/types.js +225 -0
- package/arcade/package.json +26 -0
- package/arcade/picman.ts +328 -0
- package/arcade/ping.ts +594 -0
- package/arcade/spice-invaders.ts +1104 -0
- package/arcade/tetris.ts +662 -0
- package/code-actions/CHANGELOG.md +4 -0
- package/code-actions/README.md +65 -0
- package/code-actions/actions.ts +107 -0
- package/code-actions/index.ts +148 -0
- package/code-actions/package.json +22 -0
- package/code-actions/search.ts +79 -0
- package/code-actions/snippets.ts +179 -0
- package/code-actions/ui.ts +120 -0
- package/files-widget/CHANGELOG.md +90 -0
- package/files-widget/DESIGN.md +452 -0
- package/files-widget/README.md +122 -0
- package/files-widget/TODO.md +141 -0
- package/files-widget/browser.ts +922 -0
- package/files-widget/comment.ts +5 -0
- package/files-widget/constants.ts +18 -0
- package/files-widget/demo.svg +1 -0
- package/files-widget/file-tree.ts +224 -0
- package/files-widget/file-viewer.ts +93 -0
- package/files-widget/git.ts +107 -0
- package/files-widget/index.ts +140 -0
- package/files-widget/input-utils.ts +3 -0
- package/files-widget/package.json +22 -0
- package/files-widget/types.ts +28 -0
- package/files-widget/utils.ts +26 -0
- package/files-widget/viewer.ts +424 -0
- package/import-cc-codex/research/import-chats-from-other-agents.md +135 -0
- package/import-cc-codex/spec.md +79 -0
- package/package.json +29 -0
- package/ralph-wiggum/CHANGELOG.md +7 -0
- package/ralph-wiggum/README.md +96 -0
- package/ralph-wiggum/SKILL.md +73 -0
- package/ralph-wiggum/index.ts +792 -0
- package/ralph-wiggum/package.json +25 -0
- package/raw-paste/CHANGELOG.md +7 -0
- package/raw-paste/README.md +52 -0
- package/raw-paste/index.ts +112 -0
- package/raw-paste/package.json +22 -0
- package/tab-status/CHANGELOG.md +4 -0
- package/tab-status/README.md +61 -0
- package/tab-status/assets/tab-status.png +0 -0
- package/tab-status/package.json +22 -0
- package/tab-status/tab-status.ts +179 -0
- package/usage-extension/CHANGELOG.md +17 -0
- package/usage-extension/README.md +120 -0
- package/usage-extension/index.ts +628 -0
- package/usage-extension/package.json +22 -0
- package/usage-extension/screenshot.png +0 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const { createRng, makeLevel } = require("./core.js");
|
|
5
|
+
const { DEFAULT_CONFIG, START_LIVES, START_TIME, GAME_MODES } = require("./constants.js");
|
|
6
|
+
const { isSolidAt } = require("./tiles.js");
|
|
7
|
+
|
|
8
|
+
/** @typedef {import("./types").GameState} GameState */
|
|
9
|
+
/** @typedef {import("./types").SaveState} SaveState */
|
|
10
|
+
/** @typedef {import("./types").SnapshotState} SnapshotState */
|
|
11
|
+
|
|
12
|
+
/** @param {GameState} state @returns {SaveState} */
|
|
13
|
+
function saveState(state) {
|
|
14
|
+
return {
|
|
15
|
+
version: 1,
|
|
16
|
+
level: {
|
|
17
|
+
lines: state.level.tiles.map((row) => row.join("")),
|
|
18
|
+
},
|
|
19
|
+
player: {
|
|
20
|
+
x: round(state.player.x),
|
|
21
|
+
y: round(state.player.y),
|
|
22
|
+
vx: round(state.player.vx),
|
|
23
|
+
vy: round(state.player.vy),
|
|
24
|
+
facing: state.player.facing,
|
|
25
|
+
size: state.player.size,
|
|
26
|
+
invuln: round(state.player.invuln),
|
|
27
|
+
},
|
|
28
|
+
enemies: state.enemies.map((enemy) => ({
|
|
29
|
+
x: round(enemy.x),
|
|
30
|
+
y: round(enemy.y),
|
|
31
|
+
vx: round(enemy.vx),
|
|
32
|
+
vy: round(enemy.vy),
|
|
33
|
+
alive: enemy.alive,
|
|
34
|
+
})),
|
|
35
|
+
items: state.items.map((item) => ({
|
|
36
|
+
x: round(item.x),
|
|
37
|
+
y: round(item.y),
|
|
38
|
+
vx: round(item.vx),
|
|
39
|
+
vy: round(item.vy),
|
|
40
|
+
alive: item.alive,
|
|
41
|
+
})),
|
|
42
|
+
fireballs: state.fireballs.map((fb) => ({
|
|
43
|
+
x: round(fb.x),
|
|
44
|
+
y: round(fb.y),
|
|
45
|
+
vx: round(fb.vx),
|
|
46
|
+
vy: round(fb.vy),
|
|
47
|
+
alive: fb.alive,
|
|
48
|
+
pattern: fb.pattern,
|
|
49
|
+
startY: round(fb.startY),
|
|
50
|
+
})),
|
|
51
|
+
fireballSpawners: state.fireballSpawners.map((sp) => ({
|
|
52
|
+
x: sp.x,
|
|
53
|
+
y: sp.y,
|
|
54
|
+
timer: round(sp.timer),
|
|
55
|
+
interval: sp.interval,
|
|
56
|
+
direction: sp.direction,
|
|
57
|
+
})),
|
|
58
|
+
boss: state.boss ? {
|
|
59
|
+
x: round(state.boss.x),
|
|
60
|
+
y: round(state.boss.y),
|
|
61
|
+
vx: round(state.boss.vx),
|
|
62
|
+
vy: round(state.boss.vy),
|
|
63
|
+
alive: state.boss.alive,
|
|
64
|
+
health: state.boss.health,
|
|
65
|
+
maxHealth: state.boss.maxHealth,
|
|
66
|
+
invuln: round(state.boss.invuln),
|
|
67
|
+
onGround: state.boss.onGround,
|
|
68
|
+
} : null,
|
|
69
|
+
score: state.score,
|
|
70
|
+
coins: state.coins,
|
|
71
|
+
lives: state.lives,
|
|
72
|
+
time: round(state.time),
|
|
73
|
+
levelIndex: state.levelIndex,
|
|
74
|
+
mushroomSpawned: state.mushroomSpawned,
|
|
75
|
+
spawnX: round(state.spawnX),
|
|
76
|
+
spawnY: round(state.spawnY),
|
|
77
|
+
mode: state.mode,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @param {SaveState} save
|
|
83
|
+
* @param {{ config?: Partial<import("./types").Config> }} [options]
|
|
84
|
+
* @returns {GameState | null}
|
|
85
|
+
*/
|
|
86
|
+
function loadState(save, options) {
|
|
87
|
+
if (!save || save.version !== 1 || !save.level || !Array.isArray(save.level.lines)) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
const config = { ...DEFAULT_CONFIG, ...(options && options.config ? options.config : {}) };
|
|
91
|
+
const level = makeLevel(save.level.lines);
|
|
92
|
+
const spawnX = typeof save.spawnX === "number" ? save.spawnX : save.player.x;
|
|
93
|
+
const spawnY = typeof save.spawnY === "number" ? save.spawnY : save.player.y;
|
|
94
|
+
const mode = normalizeMode(save);
|
|
95
|
+
/** @type {GameState} */
|
|
96
|
+
const state = {
|
|
97
|
+
level,
|
|
98
|
+
rng: createRng(1),
|
|
99
|
+
config,
|
|
100
|
+
tick: 0,
|
|
101
|
+
score: save.score || 0,
|
|
102
|
+
coins: save.coins || 0,
|
|
103
|
+
lives: save.lives || START_LIVES,
|
|
104
|
+
time: typeof save.time === "number" ? save.time : START_TIME,
|
|
105
|
+
levelIndex: save.levelIndex || 1,
|
|
106
|
+
mushroomSpawned: !!save.mushroomSpawned,
|
|
107
|
+
mode,
|
|
108
|
+
cameraX: 0,
|
|
109
|
+
particles: [],
|
|
110
|
+
cue: null,
|
|
111
|
+
spawnX,
|
|
112
|
+
spawnY,
|
|
113
|
+
deathTimer: 0,
|
|
114
|
+
deathJumped: false,
|
|
115
|
+
player: {
|
|
116
|
+
x: save.player.x,
|
|
117
|
+
y: save.player.y,
|
|
118
|
+
vx: save.player.vx,
|
|
119
|
+
vy: save.player.vy,
|
|
120
|
+
facing: save.player.facing,
|
|
121
|
+
onGround: false,
|
|
122
|
+
size: save.player.size,
|
|
123
|
+
invuln: save.player.invuln,
|
|
124
|
+
},
|
|
125
|
+
enemies: save.enemies.map((enemy) => ({
|
|
126
|
+
x: enemy.x,
|
|
127
|
+
y: enemy.y,
|
|
128
|
+
vx: enemy.vx,
|
|
129
|
+
vy: enemy.vy,
|
|
130
|
+
alive: enemy.alive,
|
|
131
|
+
onGround: false,
|
|
132
|
+
})),
|
|
133
|
+
items: save.items.map((item) => ({
|
|
134
|
+
x: item.x,
|
|
135
|
+
y: item.y,
|
|
136
|
+
vx: item.vx,
|
|
137
|
+
vy: item.vy,
|
|
138
|
+
alive: item.alive,
|
|
139
|
+
onGround: false,
|
|
140
|
+
})),
|
|
141
|
+
fireballs: (save.fireballs || []).map((fb) => ({
|
|
142
|
+
x: fb.x,
|
|
143
|
+
y: fb.y,
|
|
144
|
+
vx: fb.vx,
|
|
145
|
+
vy: fb.vy,
|
|
146
|
+
alive: fb.alive,
|
|
147
|
+
pattern: fb.pattern,
|
|
148
|
+
startY: fb.startY,
|
|
149
|
+
})),
|
|
150
|
+
fireballSpawners: (save.fireballSpawners || []).map((sp) => ({
|
|
151
|
+
x: sp.x,
|
|
152
|
+
y: sp.y,
|
|
153
|
+
timer: sp.timer,
|
|
154
|
+
interval: sp.interval,
|
|
155
|
+
direction: sp.direction,
|
|
156
|
+
})),
|
|
157
|
+
boss: save.boss ? {
|
|
158
|
+
x: save.boss.x,
|
|
159
|
+
y: save.boss.y,
|
|
160
|
+
vx: save.boss.vx,
|
|
161
|
+
vy: save.boss.vy,
|
|
162
|
+
alive: save.boss.alive,
|
|
163
|
+
health: save.boss.health,
|
|
164
|
+
maxHealth: save.boss.maxHealth,
|
|
165
|
+
invuln: save.boss.invuln,
|
|
166
|
+
onGround: save.boss.onGround,
|
|
167
|
+
} : null,
|
|
168
|
+
};
|
|
169
|
+
state.player.onGround = isSolidAt(level, state.player.x, state.player.y + 1);
|
|
170
|
+
if (state.mode === GAME_MODES.gameOver) {
|
|
171
|
+
state.cue = { text: "GAME OVER", ttl: 0, persist: true };
|
|
172
|
+
} else if (state.mode === GAME_MODES.paused) {
|
|
173
|
+
state.cue = { text: "PAUSED", ttl: 0, persist: true };
|
|
174
|
+
} else if (state.mode === GAME_MODES.levelClear) {
|
|
175
|
+
state.cue = { text: "LEVEL CLEAR", ttl: 0, persist: true };
|
|
176
|
+
}
|
|
177
|
+
for (const enemy of state.enemies) {
|
|
178
|
+
enemy.onGround = isSolidAt(level, enemy.x, enemy.y + 1);
|
|
179
|
+
}
|
|
180
|
+
for (const item of state.items) {
|
|
181
|
+
item.onGround = isSolidAt(level, item.x, item.y + 1);
|
|
182
|
+
}
|
|
183
|
+
return state;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** @param {GameState} state @returns {SnapshotState} */
|
|
187
|
+
function snapshotState(state) {
|
|
188
|
+
return {
|
|
189
|
+
tick: state.tick,
|
|
190
|
+
score: state.score,
|
|
191
|
+
coins: state.coins,
|
|
192
|
+
lives: state.lives,
|
|
193
|
+
time: round(state.time),
|
|
194
|
+
levelIndex: state.levelIndex,
|
|
195
|
+
mushroomSpawned: state.mushroomSpawned,
|
|
196
|
+
mode: state.mode,
|
|
197
|
+
player: {
|
|
198
|
+
x: round(state.player.x),
|
|
199
|
+
y: round(state.player.y),
|
|
200
|
+
vx: round(state.player.vx),
|
|
201
|
+
vy: round(state.player.vy),
|
|
202
|
+
onGround: state.player.onGround,
|
|
203
|
+
facing: state.player.facing,
|
|
204
|
+
size: state.player.size,
|
|
205
|
+
invuln: round(state.player.invuln),
|
|
206
|
+
},
|
|
207
|
+
enemies: state.enemies.map((enemy) => ({
|
|
208
|
+
x: round(enemy.x),
|
|
209
|
+
y: round(enemy.y),
|
|
210
|
+
vx: round(enemy.vx),
|
|
211
|
+
vy: round(enemy.vy),
|
|
212
|
+
alive: enemy.alive,
|
|
213
|
+
})),
|
|
214
|
+
items: state.items.map((item) => ({
|
|
215
|
+
x: round(item.x),
|
|
216
|
+
y: round(item.y),
|
|
217
|
+
vx: round(item.vx),
|
|
218
|
+
vy: round(item.vy),
|
|
219
|
+
alive: item.alive,
|
|
220
|
+
onGround: item.onGround,
|
|
221
|
+
})),
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/** @param {SaveState} save @returns {"playing" | "paused" | "dead" | "level_clear" | "game_over" | "level_intro"} */
|
|
226
|
+
function normalizeMode(save) {
|
|
227
|
+
const mode = save.mode;
|
|
228
|
+
if (mode === GAME_MODES.playing || mode === GAME_MODES.paused || mode === GAME_MODES.dead || mode === GAME_MODES.levelClear || mode === GAME_MODES.gameOver || mode === GAME_MODES.levelIntro) {
|
|
229
|
+
return mode;
|
|
230
|
+
}
|
|
231
|
+
if (save.gameOver) return GAME_MODES.gameOver;
|
|
232
|
+
if (save.paused) return GAME_MODES.paused;
|
|
233
|
+
if (save.player && save.player.dead) return GAME_MODES.dead;
|
|
234
|
+
return GAME_MODES.playing;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/** @param {number} value @returns {number} */
|
|
238
|
+
function round(value) {
|
|
239
|
+
return Math.round(value * 1000) / 1000;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
module.exports = {
|
|
243
|
+
saveState,
|
|
244
|
+
loadState,
|
|
245
|
+
snapshotState,
|
|
246
|
+
};
|