understanding-prime-env 0.1.0 → 0.1.2
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 +10 -0
- package/package.json +1 -1
- package/skills/understand-environment/SKILL.md +87 -316
package/README.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# understanding-prime-env
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/understanding-prime-env)
|
|
4
|
+
[](https://www.npmjs.com/package/understanding-prime-env)
|
|
5
|
+
|
|
3
6
|
A skill that generates a rich, self-contained HTML report explaining any [Prime Intellect verifiers](https://github.com/PrimeIntellect-ai/verifiers) environment.
|
|
4
7
|
|
|
5
8
|
Run it from inside any environment folder and get an instant visual breakdown of:
|
|
@@ -93,3 +96,10 @@ open environment_overview.html
|
|
|
93
96
|
|
|
94
97
|
- Node.js ≥ 16 (for the installer)
|
|
95
98
|
- A verifiers environment directory to analyze
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Links
|
|
103
|
+
|
|
104
|
+
- [npm package](https://www.npmjs.com/package/understanding-prime-env)
|
|
105
|
+
- [GitHub repository](https://github.com/Vidit-Ostwal/understanding-prime-env)
|
package/package.json
CHANGED
|
@@ -7,392 +7,163 @@ description: Generate a rich, self-contained HTML report that fully explains a P
|
|
|
7
7
|
|
|
8
8
|
## Goal
|
|
9
9
|
|
|
10
|
-
Produce a single self-contained HTML file (`environment_overview.html`) that gives
|
|
10
|
+
Produce a single self-contained HTML file (`environment_overview.html`) that gives a first-timer — someone who has never seen this environment — a clear answer to one question in under 2 minutes: **"What does the model get asked to do, and how does it get scored?"**
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Read **every `.py` file** in the current directory. Also read `pyproject.toml` and `README.md` if they exist. Do not skip helper files — reward logic is often split across modules (e.g. `*_checks.py`, `*_prompts.py`).
|
|
15
|
-
|
|
16
|
-
Extract these four things:
|
|
17
|
-
|
|
18
|
-
### 1. Dataset / Task Prompts
|
|
19
|
-
- What prompts or tasks does the environment feed to the model?
|
|
20
|
-
- If the environment imports a `PROMPTS` list, a HuggingFace dataset, or any structured prompt-building function, surface the actual content (or a representative sample of ≤10 rows).
|
|
21
|
-
- If real data is too large or not local, synthesize 3–5 realistic example rows that match the prompt schema exactly.
|
|
22
|
-
- Show the full message structure: `system` (if any), `user` content, and what fields accompany each row (e.g. `answer`, `info`, `checks`).
|
|
23
|
-
|
|
24
|
-
### 2. Configuration Parameters
|
|
25
|
-
- Find every parameter exposed by `load_environment(...)`, `TasksetConfig`, `HarnessConfig`, or `EnvConfig`.
|
|
26
|
-
- For each: name, type, default value, and a plain-English description of what it controls.
|
|
27
|
-
- Flag parameters that have significant behavioral impact (e.g. change scoring mode, enable/disable reward components).
|
|
28
|
-
|
|
29
|
-
### 3. Reward Functions & Scoring Logic
|
|
30
|
-
- List every reward and metric function (`@vf.reward`, `@vf.metric`, functions passed to `Rubric`, reward methods on `Taskset`).
|
|
31
|
-
- For each: name, weight (if any), what it measures, scoring range (0–1, float, etc.).
|
|
32
|
-
- Show the **composite reward formula** if multiple rewards are combined.
|
|
33
|
-
- If a judge LLM is used, state the model, the abbreviated judge prompt, and what it returns.
|
|
34
|
-
|
|
35
|
-
### 4. Rollout Logic — What Gets Judged
|
|
36
|
-
- What the model sees, how many turns, what tools or sandbox it has access to, what it's expected to produce.
|
|
37
|
-
- What signals are measured: visible constraints, hidden signals, group monitors, etc.
|
|
38
|
-
- The full scoring pipeline in plain English: "Model is given X, produces Y, then Z is checked, W is judged by a model, final score = …"
|
|
12
|
+
The output is a single screen (no scrolling), three tabs. That's it.
|
|
39
13
|
|
|
40
14
|
---
|
|
41
15
|
|
|
42
|
-
## Step
|
|
43
|
-
|
|
44
|
-
Write a single **self-contained** HTML file to `./environment_overview.html`. No external CDN dependencies whatsoever — all CSS, JS, fonts, and icons must be inline.
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
|
|
48
|
-
### Design Direction: "Research Notebook"
|
|
49
|
-
|
|
50
|
-
The aesthetic is a **premium research notebook** — crisp, information-dense, and scholarly, with a living interactive layer. Light mode is the default; it should feel like a beautifully typeset technical paper. Dark mode shifts to Prime Intellect's signature deep-space palette.
|
|
51
|
-
|
|
52
|
-
**The one thing someone will remember**: The animated rollout pipeline — glowing nodes connected by flowing dashed lines, showing exactly what happens to a prompt step-by-step.
|
|
53
|
-
|
|
54
|
-
---
|
|
55
|
-
|
|
56
|
-
### Theme System
|
|
57
|
-
|
|
58
|
-
Implement a **light/dark toggle** using a single `data-theme` attribute on `<html>`. All colors must be CSS custom properties so the toggle is a single attribute swap with a smooth `transition: background 0.3s, color 0.3s` on every element.
|
|
59
|
-
|
|
60
|
-
**Light theme (default):**
|
|
61
|
-
```
|
|
62
|
-
--bg-page: #f8f7f4 /* warm off-white, like laid paper */
|
|
63
|
-
--bg-card: #ffffff
|
|
64
|
-
--bg-card-hover: #faf9ff /* barely-there purple tint on hover */
|
|
65
|
-
--bg-code: #f3f0ff /* very light purple wash for code */
|
|
66
|
-
--border: #e5e1f0 /* soft lavender border */
|
|
67
|
-
--border-strong: #c4b8e8
|
|
68
|
-
--text-primary: #1a1523 /* near-black with purple undertone */
|
|
69
|
-
--text-secondary:#4a4560
|
|
70
|
-
--text-muted: #8b82a8
|
|
71
|
-
--accent: #a855f7 /* PI purple */
|
|
72
|
-
--accent-dark: #7c3aed
|
|
73
|
-
--accent-glow: rgba(168,85,247,0.15)
|
|
74
|
-
--green: #16a34a
|
|
75
|
-
--red: #dc2626
|
|
76
|
-
--yellow: #ca8a04
|
|
77
|
-
--shadow-sm: 0 1px 3px rgba(120,80,180,0.08), 0 1px 2px rgba(120,80,180,0.05)
|
|
78
|
-
--shadow-md: 0 4px 16px rgba(120,80,180,0.10), 0 2px 6px rgba(120,80,180,0.06)
|
|
79
|
-
--shadow-lg: 0 12px 40px rgba(120,80,180,0.14)
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
**Dark theme** (`[data-theme="dark"]`):
|
|
83
|
-
```
|
|
84
|
-
--bg-page: #0f0f1a
|
|
85
|
-
--bg-card: #161627
|
|
86
|
-
--bg-card-hover: #1c1c35
|
|
87
|
-
--bg-code: #1a1a30
|
|
88
|
-
--border: #2a2a4a
|
|
89
|
-
--border-strong: #3d3d6b
|
|
90
|
-
--text-primary: #e2e8f0
|
|
91
|
-
--text-secondary:#b8b0d0
|
|
92
|
-
--text-muted: #6b6890
|
|
93
|
-
--accent: #a855f7
|
|
94
|
-
--accent-dark: #c084fc
|
|
95
|
-
--accent-glow: rgba(168,85,247,0.20)
|
|
96
|
-
--green: #22c55e
|
|
97
|
-
--red: #ef4444
|
|
98
|
-
--yellow: #eab308
|
|
99
|
-
--shadow-sm: 0 1px 3px rgba(0,0,0,0.4)
|
|
100
|
-
--shadow-md: 0 4px 16px rgba(0,0,0,0.5)
|
|
101
|
-
--shadow-lg: 0 12px 40px rgba(0,0,0,0.6)
|
|
102
|
-
```
|
|
16
|
+
## Step 1 — Read the source
|
|
103
17
|
|
|
104
|
-
|
|
18
|
+
Read **every `.py` file** in the current directory. Also read `pyproject.toml` and `README.md` if they exist. Do not skip helper files — reward logic is often split across modules (e.g. `*_checks.py`, `*_prompts.py`).
|
|
105
19
|
|
|
106
|
-
|
|
20
|
+
Extract only these three things:
|
|
107
21
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
font-family: -apple-system, 'Helvetica Neue', Arial, sans-serif; /* body prose */
|
|
113
|
-
```
|
|
22
|
+
### 1. Dataset — what does the model see?
|
|
23
|
+
- Find 1–2 real example prompts from the source (a `PROMPTS` list, HuggingFace dataset, or prompt-building function).
|
|
24
|
+
- If real data is unavailable, synthesize 1–2 examples that match the prompt schema exactly.
|
|
25
|
+
- Extract only the **user-facing prompt text** — what the model actually reads. No metadata, no field schemas, no accompanying fields.
|
|
114
26
|
|
|
115
|
-
|
|
27
|
+
### 2. Rollout — what is the sequence of events?
|
|
28
|
+
- Identify the 4–5 steps that happen during a single rollout: what the model receives, what it produces, what tools or sandbox it has (if any), and what happens at scoring time.
|
|
29
|
+
- Write each step as a short label (2–5 words) and a one-line description.
|
|
116
30
|
|
|
117
|
-
|
|
118
|
-
-
|
|
119
|
-
-
|
|
120
|
-
-
|
|
121
|
-
- Captions/labels: `0.75rem`, uppercase, letter-spacing `0.08em`
|
|
122
|
-
- Code: `0.85rem`
|
|
31
|
+
### 3. Rewards — how does scoring work?
|
|
32
|
+
- List every reward function (`@vf.reward`, functions passed to `Rubric`, reward methods on `Taskset`).
|
|
33
|
+
- For each: its name and one sentence describing what it measures.
|
|
34
|
+
- If multiple rewards combine into a final score, extract the exact formula (e.g. `R = (1 - hw) × visible + hw × hidden`).
|
|
123
35
|
|
|
124
36
|
---
|
|
125
37
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
```
|
|
129
|
-
┌─────────────────────────────────────────────────────┐
|
|
130
|
-
│ STICKY NAV [logo] [sections...] [theme toggle] │
|
|
131
|
-
├─────────────────────────────────────────────────────┤
|
|
132
|
-
│ HERO HEADER (full-width, gradient mesh background) │
|
|
133
|
-
│ env name + description + stat badges │
|
|
134
|
-
├─────────┬───────────────────────────────────────────┤
|
|
135
|
-
│ │ ROLLOUT PIPELINE (animated, full-width) │
|
|
136
|
-
│ SIDE ├───────────────────────────────────────────┤
|
|
137
|
-
│ TOC │ DATASET EXAMPLES (card carousel/tabs) │
|
|
138
|
-
│ (sticky│───────────────────────────────────────────┤
|
|
139
|
-
│ left │ REWARD & SCORING (score bars + formula) │
|
|
140
|
-
│ on ├───────────────────────────────────────────┤
|
|
141
|
-
│ desktop│ CONFIGURATION (grouped param table) │
|
|
142
|
-
│ ) ├───────────────────────────────────────────┤
|
|
143
|
-
│ │ QUICK START (terminal-style code block) │
|
|
144
|
-
│ ├───────────────────────────────────────────┤
|
|
145
|
-
│ │ FILE MAP (visual tree) │
|
|
146
|
-
└─────────┴───────────────────────────────────────────┘
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
On mobile (< 768px): sidebar collapses, single column.
|
|
150
|
-
|
|
151
|
-
---
|
|
152
|
-
|
|
153
|
-
### Component Specs
|
|
154
|
-
|
|
155
|
-
#### Sticky Navigation Bar
|
|
156
|
-
- Height: 52px, `backdrop-filter: blur(12px)`, `background: rgba(var(--bg-page-rgb), 0.85)`
|
|
157
|
-
- Left: `⬡ PI` monogram in accent color + env name in muted text
|
|
158
|
-
- Center: anchor links to each section — underline slides in on hover
|
|
159
|
-
- Right: **theme toggle** — a pill switch (`☀ / ☾`) with CSS transition. Clicking it toggles `data-theme="dark"` on `<html>` and persists to `localStorage`
|
|
160
|
-
- On scroll past hero, nav gains `box-shadow: var(--shadow-sm)`
|
|
38
|
+
## Step 2 — Generate the HTML
|
|
161
39
|
|
|
162
|
-
|
|
163
|
-
- Background: a CSS mesh gradient that shifts between `--bg-page` and a very subtle purple wash. In light mode: `radial-gradient(ellipse at 20% 50%, rgba(168,85,247,0.07) 0%, transparent 60%), radial-gradient(ellipse at 80% 20%, rgba(124,58,237,0.05) 0%, transparent 50%)`. In dark mode, increase opacity to 0.15/0.12.
|
|
164
|
-
- Top-left: `⬡ Prime Intellect` in `0.75rem` caps + accent color
|
|
165
|
-
- Environment name: large serif, with a thin purple underline that animates in (width 0→100%) on page load using a CSS keyframe
|
|
166
|
-
- One-sentence description beneath in secondary text
|
|
167
|
-
- Stat badges row: pill chips showing environment type, reward count, dataset size, turns. Each chip: `background: var(--accent-glow)`, `border: 1px solid var(--accent)`, `color: var(--accent)`, `font-size: 0.75rem`, `border-radius: 99px`, `padding: 3px 12px`
|
|
40
|
+
Write a single self-contained HTML file to `./environment_overview.html`. No external CDN dependencies — all CSS and JS inline.
|
|
168
41
|
|
|
169
|
-
|
|
170
|
-
This is the centerpiece section. Render it as an SVG or pure CSS/HTML flow diagram.
|
|
42
|
+
### Design
|
|
171
43
|
|
|
172
|
-
|
|
44
|
+
**Light theme default, dark toggle in the top-right corner.**
|
|
173
45
|
|
|
174
46
|
```
|
|
175
|
-
|
|
47
|
+
Light: bg #f8f7f4 · card #ffffff · border #e5e1f0
|
|
48
|
+
text #1a1523 · muted #8b82a8 · accent #a855f7
|
|
49
|
+
Dark: bg #0f0f1a · card #161627 · border #2a2a4a
|
|
50
|
+
text #e2e8f0 · muted #6b6890 · accent #a855f7
|
|
176
51
|
```
|
|
177
52
|
|
|
178
|
-
|
|
179
|
-
- Rounded rectangle, `background: var(--bg-card)`, `border: 2px solid var(--border)`
|
|
180
|
-
- Icon (use Unicode/emoji: 📋 🤖 💬 ⚖️ 🎯) + label + 1-line description from the actual env
|
|
181
|
-
- On hover: `border-color: var(--accent)`, subtle `box-shadow: 0 0 0 3px var(--accent-glow)`
|
|
182
|
-
|
|
183
|
-
Connecting lines: SVG `<line>` or CSS `border-top: 2px dashed var(--border-strong)` with an animated flow:
|
|
184
|
-
```css
|
|
185
|
-
@keyframes flow {
|
|
186
|
-
from { stroke-dashoffset: 20; }
|
|
187
|
-
to { stroke-dashoffset: 0; }
|
|
188
|
-
}
|
|
189
|
-
/* apply: animation: flow 1s linear infinite; */
|
|
190
|
-
```
|
|
53
|
+
All colors as CSS custom properties on `:root` and `[data-theme="dark"]`. Toggle swaps the attribute; `localStorage` persists the choice.
|
|
191
54
|
|
|
192
|
-
|
|
55
|
+
Typography: Georgia/serif for the env name; `-apple-system, Helvetica Neue, sans-serif` for everything else; `ui-monospace, Fira Code, monospace` for code and formulas. No Inter, no Roboto.
|
|
193
56
|
|
|
194
|
-
|
|
57
|
+
### Structure
|
|
195
58
|
|
|
196
|
-
|
|
197
|
-
- Tab strip at top: "Example 1", "Example 2", … (up to 5 tabs). Active tab: `border-bottom: 2px solid var(--accent)`, accent color text
|
|
198
|
-
- Each tab panel: a card showing the prompt content, then metadata chips for accompanying fields
|
|
199
|
-
- Prompt content: monospace block with subtle `background: var(--bg-code)`, `border-left: 3px solid var(--accent)`, `padding: 12px 16px`
|
|
200
|
-
- If the prompt has format constraints (e.g. "must not contain letter g"), highlight those phrases with `background: rgba(168,85,247,0.15)`, `border-radius: 3px`
|
|
201
|
-
- Copy button: top-right of each code block, shows "Copied!" with checkmark on click (pure JS)
|
|
59
|
+
The entire page fits on one screen without scrolling. Layout:
|
|
202
60
|
|
|
203
|
-
#### Reward & Scoring
|
|
204
|
-
For each reward function, render a **reward card**:
|
|
205
61
|
```
|
|
206
62
|
┌─────────────────────────────────────────────┐
|
|
207
|
-
│
|
|
208
|
-
│
|
|
209
|
-
|
|
63
|
+
│ env name (large, serif) [☀/☾ toggle]│
|
|
64
|
+
│ one-sentence description │
|
|
65
|
+
├─────────────────────────────────────────────┤
|
|
66
|
+
│ [ Dataset ] [ Rollout ] [ Rewards ] │
|
|
67
|
+
├─────────────────────────────────────────────┤
|
|
68
|
+
│ │
|
|
69
|
+
│ tab content (no scroll) │
|
|
210
70
|
│ │
|
|
211
|
-
│ Score range [████████░░] 0.0 → 1.0 │
|
|
212
|
-
│ Type: deterministic · Returns: float │
|
|
213
71
|
└─────────────────────────────────────────────┘
|
|
214
72
|
```
|
|
215
73
|
|
|
216
|
-
|
|
74
|
+
### Tab 1 — Dataset
|
|
217
75
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
│ + hidden_weight × hidden │
|
|
223
|
-
└───────────────────────────────────────────────────┘
|
|
224
|
-
```
|
|
225
|
-
Style: `background: var(--accent-glow)`, `border: 1px solid var(--accent)`, `border-radius: 8px`, `padding: 16px 20px`, monospace formula text in accent color.
|
|
76
|
+
Show 1–2 example prompts in a clean monospace block:
|
|
77
|
+
- `background: var(--bg-code)`, `border-left: 3px solid var(--accent)`, `padding: 12px 16px`, `border-radius: 0 6px 6px 0`
|
|
78
|
+
- If there are 2 examples, a subtle "Example 1 / 2" toggle (two small buttons, no full tab strip)
|
|
79
|
+
- Nothing else on this tab — no labels, no field names, no copy button
|
|
226
80
|
|
|
227
|
-
|
|
81
|
+
### Tab 2 — Rollout
|
|
228
82
|
|
|
229
|
-
|
|
230
|
-
Group parameters by `[Taskset]` / `[Harness]` / `[Top-level]` with a small section label.
|
|
83
|
+
A static horizontal pipeline: 4–5 boxes connected by `→` arrows.
|
|
231
84
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
- `Default`: monospace, muted
|
|
236
|
-
- `Description`: normal prose
|
|
85
|
+
```
|
|
86
|
+
[ Prompt ] → [ Model ] → [ Response ] → [ Scoring ] → [ Score ]
|
|
87
|
+
```
|
|
237
88
|
|
|
238
|
-
|
|
89
|
+
Each box:
|
|
90
|
+
- `background: var(--bg-card)`, `border: 1.5px solid var(--border)`, `border-radius: 8px`, `padding: 10px 16px`
|
|
91
|
+
- **Bold label** (2–4 words) on top
|
|
92
|
+
- One-line description beneath in muted text, `font-size: 0.8rem`
|
|
93
|
+
- On hover: `border-color: var(--accent)`
|
|
239
94
|
|
|
240
|
-
|
|
95
|
+
Arrows: plain `→` character in muted color between boxes. No SVG, no animation.
|
|
241
96
|
|
|
242
|
-
|
|
243
|
-
A terminal-style window:
|
|
244
|
-
- Header bar: three colored dots (red/yellow/green `●●●`) + title "bash" in muted text
|
|
245
|
-
- Body: `background: #1a1a2e` (always dark, regardless of theme — this is a terminal), `color: #e2e8f0`
|
|
246
|
-
- Commands: lines prefixed with `$ ` in accent color; actual command in white
|
|
247
|
-
- Comments: muted color
|
|
248
|
-
- Copy-all button top-right
|
|
97
|
+
Layout: `display: flex; align-items: center; gap: 8px; flex-wrap: wrap` so it reflows gracefully on smaller screens.
|
|
249
98
|
|
|
250
|
-
|
|
251
|
-
A visual file tree using box-drawing characters in a monospace block:
|
|
252
|
-
```
|
|
253
|
-
environments/ifeval_goblin/
|
|
254
|
-
├── ifeval_goblin.py — Main environment, config classes, taskset
|
|
255
|
-
├── ifeval_goblin_checks.py — Format constraint checkers
|
|
256
|
-
├── ifeval_goblin_prompts.py — PROMPTS list (64 task definitions)
|
|
257
|
-
└── pyproject.toml — Dependencies and eval defaults
|
|
258
|
-
```
|
|
259
|
-
Style: `background: var(--bg-code)`, `border-radius: 8px`, `padding: 20px`, monospace, muted text with filename in primary color.
|
|
260
|
-
|
|
261
|
-
#### Collapsible Sections
|
|
262
|
-
Every `<section>` has a toggle header. Clicking it smoothly expands/collapses:
|
|
263
|
-
```css
|
|
264
|
-
.section-body {
|
|
265
|
-
display: grid;
|
|
266
|
-
grid-template-rows: 1fr;
|
|
267
|
-
transition: grid-template-rows 0.3s ease;
|
|
268
|
-
}
|
|
269
|
-
.section-body.collapsed {
|
|
270
|
-
grid-template-rows: 0fr;
|
|
271
|
-
}
|
|
272
|
-
.section-body > .inner { overflow: hidden; }
|
|
273
|
-
```
|
|
274
|
-
The section heading shows a `▾` / `▸` chevron that rotates with `transition: transform 0.3s`.
|
|
99
|
+
### Tab 3 — Rewards
|
|
275
100
|
|
|
276
|
-
|
|
277
|
-
For Python code snippets, apply a minimal tokenizer via JS after DOM load:
|
|
278
|
-
- Keywords (`def`, `class`, `import`, `from`, `return`, `if`, `async`, `await`, `True`, `False`, `None`): wrap in `<span style="color: var(--accent)">`
|
|
279
|
-
- Strings (`"..."`, `'...'`, `"""..."""`): `color: var(--green)`
|
|
280
|
-
- Comments (`# ...`): `color: var(--text-muted); font-style: italic`
|
|
281
|
-
- Numbers: `color: var(--yellow)`
|
|
282
|
-
- Decorator (`@...`): `color: var(--accent-dark)`
|
|
101
|
+
A clean list. For each reward function:
|
|
283
102
|
|
|
284
|
-
#### Footer
|
|
285
103
|
```
|
|
286
|
-
|
|
104
|
+
reward_name
|
|
105
|
+
One sentence describing what it measures.
|
|
287
106
|
```
|
|
288
|
-
Small, centered, `color: var(--text-muted)`, `font-size: 0.75rem`. Separator line above using `border-top: 1px solid var(--border)`.
|
|
289
|
-
|
|
290
|
-
---
|
|
291
107
|
|
|
292
|
-
|
|
108
|
+
- Name: monospace, accent color, `font-size: 0.9rem`
|
|
109
|
+
- Description: normal prose, secondary text color, `font-size: 0.875rem`
|
|
110
|
+
- Separated by a thin `border-bottom: 1px solid var(--border)`
|
|
293
111
|
|
|
294
|
-
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
112
|
+
If there is a composite formula, show it below the list in a single styled block:
|
|
113
|
+
```
|
|
114
|
+
background: var(--accent-glow) /* rgba(168,85,247,0.10) */
|
|
115
|
+
border: 1px solid var(--accent)
|
|
116
|
+
border-radius: 6px
|
|
117
|
+
padding: 12px 16px
|
|
118
|
+
font-family: monospace
|
|
119
|
+
color: var(--accent)
|
|
299
120
|
```
|
|
300
121
|
|
|
301
|
-
|
|
302
|
-
1. **Page load**: Hero title underline grows left-to-right (600ms ease-out, 200ms delay)
|
|
303
|
-
2. **Stagger fade-in**: Pipeline nodes slide up 12px + fade in, 100ms stagger per node
|
|
304
|
-
3. **Score bars**: Width grows from 0 to final value (800ms ease-out, triggered when section scrolls into view via `IntersectionObserver`)
|
|
305
|
-
4. **Flow lines**: Dashed SVG/CSS lines have continuous `stroke-dashoffset` animation
|
|
306
|
-
5. **Theme toggle**: Smooth 300ms transition on all color properties
|
|
307
|
-
6. **Tab switch**: Content fades in at 150ms
|
|
308
|
-
7. **Section collapse**: Grid row height transition (300ms)
|
|
309
|
-
8. **Copy button**: Brief scale pulse (0.95 → 1.0) + text change
|
|
122
|
+
Nothing else on this tab — no weights, no score bars, no judge details.
|
|
310
123
|
|
|
311
|
-
|
|
124
|
+
### Theme Toggle
|
|
312
125
|
|
|
313
|
-
|
|
126
|
+
A small pill button, top-right of the header. Shows `☀` in dark mode, `☾` in light mode.
|
|
314
127
|
|
|
315
128
|
```js
|
|
316
|
-
// Theme toggle
|
|
317
|
-
const toggle = document.getElementById('theme-toggle');
|
|
318
129
|
const root = document.documentElement;
|
|
130
|
+
const btn = document.getElementById('theme-toggle');
|
|
319
131
|
const saved = localStorage.getItem('pi-theme');
|
|
320
132
|
if (saved) root.setAttribute('data-theme', saved);
|
|
321
|
-
|
|
133
|
+
btn.addEventListener('click', () => {
|
|
322
134
|
const next = root.getAttribute('data-theme') === 'dark' ? 'light' : 'dark';
|
|
323
135
|
root.setAttribute('data-theme', next);
|
|
324
136
|
localStorage.setItem('pi-theme', next);
|
|
325
137
|
});
|
|
138
|
+
```
|
|
326
139
|
|
|
327
|
-
|
|
328
|
-
const observer = new IntersectionObserver((entries) => {
|
|
329
|
-
entries.forEach(e => {
|
|
330
|
-
if (e.isIntersecting) {
|
|
331
|
-
e.target.style.width = e.target.dataset.target;
|
|
332
|
-
observer.unobserve(e.target);
|
|
333
|
-
}
|
|
334
|
-
});
|
|
335
|
-
}, { threshold: 0.3 });
|
|
336
|
-
document.querySelectorAll('.score-bar-fill').forEach(el => observer.observe(el));
|
|
337
|
-
|
|
338
|
-
// Copy buttons
|
|
339
|
-
document.querySelectorAll('.copy-btn').forEach(btn => {
|
|
340
|
-
btn.addEventListener('click', () => {
|
|
341
|
-
navigator.clipboard.writeText(btn.closest('.code-block').querySelector('code').innerText);
|
|
342
|
-
btn.textContent = '✓ Copied';
|
|
343
|
-
setTimeout(() => btn.textContent = 'Copy', 1800);
|
|
344
|
-
});
|
|
345
|
-
});
|
|
140
|
+
### Tab Switching
|
|
346
141
|
|
|
347
|
-
|
|
142
|
+
```js
|
|
348
143
|
document.querySelectorAll('.tab-btn').forEach(btn => {
|
|
349
144
|
btn.addEventListener('click', () => {
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
group.querySelectorAll('.tab-panel').forEach(p => p.classList.remove('active'));
|
|
145
|
+
document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
|
|
146
|
+
document.querySelectorAll('.tab-panel').forEach(p => p.classList.remove('active'));
|
|
353
147
|
btn.classList.add('active');
|
|
354
|
-
|
|
355
|
-
});
|
|
356
|
-
});
|
|
357
|
-
|
|
358
|
-
// Collapsible sections
|
|
359
|
-
document.querySelectorAll('.section-header').forEach(header => {
|
|
360
|
-
header.addEventListener('click', () => {
|
|
361
|
-
const body = header.nextElementSibling;
|
|
362
|
-
const chevron = header.querySelector('.chevron');
|
|
363
|
-
body.classList.toggle('collapsed');
|
|
364
|
-
chevron.style.transform = body.classList.contains('collapsed') ? 'rotate(-90deg)' : 'rotate(0deg)';
|
|
148
|
+
document.getElementById(btn.dataset.tab).classList.add('active');
|
|
365
149
|
});
|
|
366
150
|
});
|
|
367
|
-
|
|
368
|
-
// Active nav highlight on scroll
|
|
369
|
-
const sections = document.querySelectorAll('section[id]');
|
|
370
|
-
const navLinks = document.querySelectorAll('.nav-link');
|
|
371
|
-
const scrollObserver = new IntersectionObserver((entries) => {
|
|
372
|
-
entries.forEach(e => {
|
|
373
|
-
if (e.isIntersecting) {
|
|
374
|
-
navLinks.forEach(l => l.classList.remove('active'));
|
|
375
|
-
document.querySelector(`.nav-link[href="#${e.target.id}"]`)?.classList.add('active');
|
|
376
|
-
}
|
|
377
|
-
});
|
|
378
|
-
}, { rootMargin: '-40% 0px -55% 0px' });
|
|
379
|
-
sections.forEach(s => scrollObserver.observe(s));
|
|
380
151
|
```
|
|
381
152
|
|
|
153
|
+
Active tab style: `border-bottom: 2px solid var(--accent)`, accent color text. Inactive: muted text, no border.
|
|
154
|
+
|
|
382
155
|
---
|
|
383
156
|
|
|
384
157
|
## Step 3 — Confirm and report
|
|
385
158
|
|
|
386
159
|
After writing the file, tell the user:
|
|
387
|
-
- The full path
|
|
388
|
-
-
|
|
389
|
-
|
|
390
|
-
If any section couldn't be filled because the information wasn't in the source, say so explicitly — never hallucinate reward weights, defaults, or dataset contents.
|
|
160
|
+
- The full path and `open environment_overview.html` command
|
|
161
|
+
- Two sentences: what the environment does and how it scores
|
|
391
162
|
|
|
392
163
|
## Anti-patterns
|
|
393
164
|
|
|
394
|
-
- Do not
|
|
395
|
-
- Do not
|
|
396
|
-
- Do not
|
|
397
|
-
- Do not
|
|
398
|
-
-
|
|
165
|
+
- Do not add config parameters, file maps, quick-start commands, or any section beyond the three tabs
|
|
166
|
+
- Do not add animations, score bars, copy buttons, or collapsible sections
|
|
167
|
+
- Do not hallucinate reward weights, defaults, or prompt content not found in the source
|
|
168
|
+
- Do not skip helper modules — they often contain the core scoring logic
|
|
169
|
+
- If content would cause scrolling within a tab, cut it further
|