pi-extensions 0.1.17 → 0.1.20

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 CHANGED
@@ -6,7 +6,7 @@ Personal extensions for the [Pi coding agent](https://github.com/badlogic/pi-mon
6
6
 
7
7
  | Extension | Description |
8
8
  |-----------|-------------|
9
- | [/files](files-widget/) | In-terminal file browser and viewer widget. Navigate files, view diffs, select code, send comments to agent - without leaving Pi, and without interrupting your agent |
9
+ | [/readfiles](files-widget/) | In-terminal file browser and viewer widget. Navigate files, view diffs, select code, send comments to agent - without leaving Pi, and without interrupting your agent |
10
10
  | [tab-status](tab-status/) | Manage as many parallel sessions as your mind can handle. Terminal tab indicators for <br>✅ done / 🚧 stuck / 🛑 timed out |
11
11
  | [ralph-wiggum](ralph-wiggum/) | Run arbitrarily-long tasks without diluting model attention. Flat version without subagents like [ralph-loop](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/ralph-loop) |
12
12
  | [agent-guidance](agent-guidance/) | Switch between Claude/Codex/Gemini with model-specific guidance (CLAUDE.md, CODEX.md, GEMINI.md) |
@@ -15,6 +15,13 @@ Personal extensions for the [Pi coding agent](https://github.com/badlogic/pi-mon
15
15
  | [/code](code-actions/) | Pick code blocks or inline snippets from assistant messages to copy, insert, or run with `/code` |
16
16
  | [arcade](arcade/) | Play minigames while your tests run: 👾 sPIce-invaders, 👻 picman, 🏓 ping, 🧩 tetris, 🍄 mario-not |
17
17
 
18
+ ## Skills
19
+
20
+ | Skill | Description |
21
+ |-------|-------------|
22
+ | [pi-skill-creator](pi-skill-creator/) | Guidelines and templates for creating Pi skills. |
23
+ | [ralph-wiggum](ralph-wiggum/) | Skill instructions for long-running development loops. |
24
+
18
25
  ## Install (pi package manager)
19
26
 
20
27
  ```bash
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.3 - 2026-02-03
4
+
5
+ ### Changed
6
+ - Publish metadata refresh (no runtime changes).
7
+
3
8
  ## 0.1.2 - 2026-02-02
4
9
 
5
10
  ### Changed
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tmustier/pi-agent-guidance",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Loads provider-specific context files (CLAUDE.md, CODEX.md, GEMINI.md) based on current model.",
5
5
  "license": "MIT",
6
6
  "author": "Thomas Mustier",
@@ -1,5 +1,8 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.5 - 2026-02-03
4
+ - Add preview video metadata for the extension listing.
5
+
3
6
  ## 0.1.4 - 2026-01-26
4
7
  - Fix Tetris pieces locking automatically after landing.
5
8
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tmustier/pi-arcade",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Arcade minigames for the Pi coding agent.",
5
5
  "license": "MIT",
6
6
  "author": "Thomas Mustier",
@@ -21,6 +21,7 @@
21
21
  "ping.ts",
22
22
  "tetris.ts",
23
23
  "mario-not/mario-not.ts"
24
- ]
24
+ ],
25
+ "video": "https://raw.githubusercontent.com/tmustier/pi-extensions/main/arcade/assets/demo.mp4"
25
26
  }
26
27
  }
@@ -1,5 +1,8 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.4 - 2026-02-03
4
+ - Add preview image metadata for the extension listing.
5
+
3
6
  ## 0.1.2 - 2026-01-26
4
7
  - Add a src entry point so loading `code-actions/src` works with pi extension discovery.
5
8
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tmustier/pi-code-actions",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Pick code blocks or inline snippets from recent assistant messages to copy or insert.",
5
5
  "license": "MIT",
6
6
  "author": "Thomas Mustier",
@@ -17,6 +17,7 @@
17
17
  "pi": {
18
18
  "extensions": [
19
19
  "index.ts"
20
- ]
20
+ ],
21
+ "image": "https://github.com/user-attachments/assets/0dc10a64-d61f-4b56-9684-5e448c759385"
21
22
  }
22
23
  }
@@ -2,6 +2,11 @@
2
2
 
3
3
  All notable changes to this extension will be documented in this file.
4
4
 
5
+ ## [0.1.14] - 2026-02-03
6
+
7
+ ### Added
8
+ - Add preview video metadata for the extension listing.
9
+
5
10
  ## [0.1.13] - 2026-02-02
6
11
 
7
12
  ### Changed
@@ -14,7 +14,7 @@ In-terminal file browser and diff viewer widget for Pi. Navigate files, view dif
14
14
  pi install npm:@tmustier/pi-files-widget
15
15
  ```
16
16
 
17
- Required deps (needed for /files):
17
+ Required deps (needed for /readfiles):
18
18
 
19
19
  ```bash
20
20
  # macOS (Homebrew)
@@ -75,11 +75,11 @@ Then reference it in your settings:
75
75
  - `delta`: formatted diffs
76
76
  - `glow`: markdown rendering
77
77
 
78
- The `/files` browser requires these tools and will refuse to open until they are installed.
78
+ The `/readfiles` browser requires these tools and will refuse to open until they are installed.
79
79
 
80
80
  ## Commands
81
81
 
82
- - `/files` - open the file browser
82
+ - `/readfiles` - open the file browser
83
83
  - `/review` - open tuicr review flow
84
84
  - `/diff` - open critique (bunx critique)
85
85
 
@@ -127,4 +127,4 @@ If missing, `/review` or `/diff` will show a clear install prompt.
127
127
  - Folder LOCs are shown only when the folder is collapsed (expanded folders would duplicate counts).
128
128
  - Line counts load asynchronously; the header shows activity while counts are computed.
129
129
  - Large non-git folders load progressively and may show `[partial]` while loading in safe mode.
130
- - Git status refreshes every 3 seconds while `/files` is open.
130
+ - Git status refreshes every 3 seconds while `/readfiles` is open.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tmustier/pi-files-widget",
3
- "version": "0.1.13",
3
+ "version": "0.1.14",
4
4
  "description": "In-terminal file browser and viewer for Pi.",
5
5
  "license": "MIT",
6
6
  "author": "Thomas Mustier",
@@ -24,6 +24,7 @@
24
24
  "pi": {
25
25
  "extensions": [
26
26
  "index.ts"
27
- ]
27
+ ],
28
+ "video": "https://raw.githubusercontent.com/tmustier/pi-extensions/main/files-widget/demo.mp4"
28
29
  }
29
30
  }
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "pi-extensions",
3
- "version": "0.1.17",
3
+ "version": "0.1.20",
4
+ "license": "MIT",
4
5
  "private": false,
5
6
  "keywords": [
6
7
  "pi-package"
@@ -25,6 +26,7 @@
25
26
  "./ready-status/ready-status.ts"
26
27
  ],
27
28
  "skills": [
29
+ "./pi-skill-creator/SKILL.md",
28
30
  "./ralph-wiggum/SKILL.md"
29
31
  ]
30
32
  }
@@ -0,0 +1,11 @@
1
+ # Changelog
2
+
3
+ ## 0.2.0 - 2026-02-05
4
+ - Consolidate into standalone SKILL.md: remove references/ directory (design-patterns, workflows, output-patterns).
5
+ - Reframe directives as context throughout — add "Context over directives" principle.
6
+ - Add Activation principle (description is the sole trigger).
7
+ - Fold Pi-specific reference guidelines (one level deep, no duplication) into step 7.
8
+ - Clarify optional frontmatter fields, `disable-model-invocation`, and name rules.
9
+
10
+ ## 0.1.0 - 2026-02-05
11
+ - Initial release.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Thomas Mustier
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,6 @@
1
+ # pi-skill-creator
2
+
3
+ Guidelines and templates for creating Pi skills that follow the Agent Skills format.
4
+
5
+ ## Installation
6
+ `pi install npm:@tmustier/pi-skill-creator`
@@ -0,0 +1,139 @@
1
+ ---
2
+ name: pi-skill-creator
3
+ description: Create or update Pi skills (SKILL.md plus optional scripts, references, or assets). Use when someone asks to design a new Pi skill, refine an existing one, or structure skills for Pi discovery or packaging.
4
+ ---
5
+
6
+ # Pi Skill Creator
7
+
8
+ Provide guidance for creating effective Pi skills.
9
+
10
+ ## Principles
11
+
12
+ - **Conciseness**: the agent is already very capable - only domain-specific knowledge, workflows, and tooling it can't infer earn their token cost.
13
+ - **Progressive disclosure**: Pi loads skills in tiers - frontmatter (always in context), body (on trigger), bundled resources (on demand) - so splitting content across them keeps context lean.
14
+ - **Activation**: Pi decides whether to load a skill based solely on the frontmatter `description`. "When to use" information in the body comes too late.
15
+ - **Context over directives**: the agent makes better decisions when it understands why. For tasks requiring judgment, context like "X helps Y because Z" is more robust than instructions like "You MUST do X".
16
+
17
+ ## Pi Agent Skills format
18
+
19
+ - Required frontmatter: `name`, `description`. Directory name must equal `name`.
20
+ - Name rules: 1–64 chars, lowercase letters/digits/hyphens, no leading/trailing/consecutive hyphens.
21
+ - Optional frontmatter: `license`, `compatibility`, `metadata` (arbitrary key-value pairs for tooling), `allowed-tools` (restrict which tools the skill may invoke).
22
+ - `disable-model-invocation`: when set, Pi won't auto-trigger the skill; the user must invoke it explicitly with `/skill:name`.
23
+ - Paths are relative to the skill directory; `{baseDir}` placeholders are not supported.
24
+ - Skill locations: `~/.pi/agent/skills/`, `.pi/skills/`, `skills/` in a package, settings `skills`, or `--skill <path>`.
25
+
26
+ ## Recommended structure
27
+
28
+ ```
29
+ pi-skill/
30
+ ├── SKILL.md
31
+ ├── README.md # Optional: human summary + installation
32
+ ├── scripts/ # Optional executables
33
+ ├── references/ # Optional docs loaded on demand
34
+ └── assets/ # Optional templates/assets
35
+ ```
36
+
37
+ ## Workflow
38
+
39
+ ### 1) Clarify use cases
40
+
41
+ 2-4 concrete example requests usually suffice to scope triggers and functionality.
42
+
43
+ ### 2) Plan reusable resources
44
+
45
+ For each example, decide if you need:
46
+ - **scripts/** for deterministic tasks
47
+ - **references/** for long docs or schemas
48
+ - **assets/** for templates or boilerplate
49
+
50
+ ### 3) Create the skeleton
51
+
52
+ A skill needs a directory containing a SKILL.md. Only add resource sub-directories that are actually needed.
53
+
54
+ ```bash
55
+ mkdir -p ~/.pi/agent/skills/my-skill
56
+ touch ~/.pi/agent/skills/my-skill/SKILL.md
57
+ ```
58
+
59
+ ### 4) Optional: Write README.md (humans + installation)
60
+
61
+ If you plan to share the skill with humans, a README.md helps discovery and installation. If you have a README, installation info can live there to save space in SKILL.md.
62
+
63
+ ```markdown
64
+ # My Skill
65
+
66
+ Short summary for humans discovering the skill.
67
+
68
+ ## Installation
69
+ `pi install git:github.com/org/my-skill`
70
+ ```
71
+
72
+ ### 5) Write frontmatter
73
+
74
+ Use only the fields you need.
75
+
76
+ ```markdown
77
+ ---
78
+ name: my-skill
79
+ description: What it does + when to use it.
80
+ ---
81
+ ```
82
+
83
+ If you need to hide auto-invocation, set:
84
+
85
+ ```yaml
86
+ disable-model-invocation: true
87
+ ```
88
+
89
+ ### 6) Write the body
90
+
91
+ - Imperative phrasing works well for procedural instructions; context framing works better for guidance (see Principles).
92
+ - ~500 lines is a practical ceiling for SKILL.md; beyond that, split content into references.
93
+ - The agent won't know a reference file exists unless SKILL.md says when to read it.
94
+
95
+ ### 7) Add resources
96
+
97
+ SKILL.md is the agent's interface to the skill — usage examples and input/output descriptions let it call scripts without needing to understand internals.
98
+
99
+ - **scripts/**: usage examples in SKILL.md inform the agent how to call them; scripts should be executable.
100
+ - **references/**: a table of contents helps the agent navigate files longer than ~100 lines. References work best one level deep from SKILL.md, and each fact should live in one place (SKILL.md or a reference, not both).
101
+ - **assets/**: templates, boilerplate, or data used in final output — typically not loaded into context.
102
+
103
+ ### 8) Validate and test
104
+
105
+ - Run the validator script:
106
+
107
+ ```bash
108
+ scripts/validate_skill.py /path/to/my-skill
109
+ ```
110
+
111
+ - Load only the skill to spot warnings:
112
+
113
+ ```bash
114
+ pi --no-skills --skill /path/to/my-skill
115
+ ```
116
+
117
+ - Invoke it explicitly:
118
+
119
+ ```bash
120
+ /skill:my-skill
121
+ ```
122
+
123
+ - After edits, use `/reload`.
124
+
125
+ ### 9) Publish (optional)
126
+
127
+ To share beyond a single machine, publish as a Pi package (package.json-based, not a .skill archive).
128
+
129
+ - Add `package.json` with a `pi` manifest (or rely on the conventional `skills/` directory).
130
+ - Add `"keywords": ["pi-package"]` for discoverability.
131
+ - Publish to npm or host in git; install with `pi install <source>` and enable via `pi config` if needed.
132
+
133
+ ```json
134
+ {
135
+ "name": "my-pi-skills",
136
+ "keywords": ["pi-package"],
137
+ "pi": { "skills": ["./skills"] }
138
+ }
139
+ ```
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "@tmustier/pi-skill-creator",
3
+ "version": "0.2.0",
4
+ "description": "Skill-creation guidelines for Pi (Agent Skills format).",
5
+ "license": "MIT",
6
+ "author": "Thomas Mustier",
7
+ "keywords": [
8
+ "pi-package"
9
+ ],
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/tmustier/pi-extensions.git",
13
+ "directory": "pi-skill-creator"
14
+ },
15
+ "bugs": "https://github.com/tmustier/pi-extensions/issues",
16
+ "homepage": "https://github.com/tmustier/pi-extensions/tree/main/pi-skill-creator",
17
+ "pi": {
18
+ "skills": [
19
+ "SKILL.md"
20
+ ]
21
+ }
22
+ }
@@ -0,0 +1,208 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Validate a Pi skill directory for Agent Skills + README requirements.
4
+
5
+ Usage:
6
+ scripts/validate_skill.py <skill_directory>
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import re
12
+ import sys
13
+ from pathlib import Path
14
+
15
+ import yaml
16
+
17
+ MAX_NAME_LENGTH = 64
18
+ MAX_DESCRIPTION_LENGTH = 1024
19
+
20
+ ALLOWED_FRONTMATTER_FIELDS = {
21
+ "name",
22
+ "description",
23
+ "license",
24
+ "compatibility",
25
+ "metadata",
26
+ "allowed-tools",
27
+ "disable-model-invocation",
28
+ }
29
+
30
+ NAME_PATTERN = re.compile(r"^[a-z0-9-]+$")
31
+ FRONTMATTER_PATTERN = re.compile(r"^---\n(.*?)\n---", re.DOTALL)
32
+ INSTALLATION_HEADING = re.compile(r"^#{1,6}\s+installation\b", re.IGNORECASE)
33
+
34
+
35
+ def read_frontmatter(skill_md: Path) -> tuple[dict | None, str | None]:
36
+ content = skill_md.read_text()
37
+ if not content.startswith("---"):
38
+ return None, "No YAML frontmatter found"
39
+
40
+ match = FRONTMATTER_PATTERN.match(content)
41
+ if not match:
42
+ return None, "Invalid frontmatter format"
43
+
44
+ try:
45
+ frontmatter = yaml.safe_load(match.group(1))
46
+ except yaml.YAMLError as exc:
47
+ return None, f"Invalid YAML in frontmatter: {exc}"
48
+
49
+ if not isinstance(frontmatter, dict):
50
+ return None, "Frontmatter must be a YAML mapping"
51
+
52
+ return frontmatter, None
53
+
54
+
55
+ def validate_readme(readme_path: Path) -> tuple[list[str], list[str]]:
56
+ errors: list[str] = []
57
+ warnings: list[str] = []
58
+
59
+ if not readme_path.exists():
60
+ return ["README.md not found"], warnings
61
+
62
+ content = readme_path.read_text().strip()
63
+ if not content:
64
+ return ["README.md is empty"], warnings
65
+
66
+ lines = readme_path.read_text().splitlines()
67
+ installation_index = None
68
+ for idx, line in enumerate(lines):
69
+ if INSTALLATION_HEADING.match(line.strip()):
70
+ installation_index = idx
71
+ break
72
+
73
+ if installation_index is None:
74
+ errors.append("README.md is missing an Installation section")
75
+ else:
76
+ summary_lines = [
77
+ line.strip()
78
+ for line in lines[:installation_index]
79
+ if line.strip() and not line.strip().startswith("#")
80
+ ]
81
+ if not summary_lines:
82
+ warnings.append("README.md has no summary text before Installation")
83
+
84
+ return errors, warnings
85
+
86
+
87
+ def validate_frontmatter(frontmatter: dict, skill_dir: Path) -> tuple[list[str], list[str]]:
88
+ errors: list[str] = []
89
+ warnings: list[str] = []
90
+
91
+ keys = set(frontmatter.keys())
92
+ unknown = sorted(keys - ALLOWED_FRONTMATTER_FIELDS)
93
+ if unknown:
94
+ warnings.append(f"Unknown frontmatter field(s): {', '.join(unknown)}")
95
+
96
+ name = frontmatter.get("name")
97
+ if not isinstance(name, str) or not name.strip():
98
+ errors.append("Missing or invalid 'name' in frontmatter")
99
+ else:
100
+ normalized = name.strip()
101
+ parent_dir = skill_dir.name
102
+ if normalized != parent_dir:
103
+ errors.append(
104
+ f"Frontmatter name '{normalized}' does not match directory '{parent_dir}'"
105
+ )
106
+ if len(normalized) > MAX_NAME_LENGTH:
107
+ errors.append(
108
+ f"Name is too long ({len(normalized)}). Max {MAX_NAME_LENGTH}."
109
+ )
110
+ if not NAME_PATTERN.match(normalized):
111
+ errors.append(
112
+ "Name must be lowercase letters, digits, and hyphens only"
113
+ )
114
+ if normalized.startswith("-") or normalized.endswith("-"):
115
+ errors.append("Name must not start or end with a hyphen")
116
+ if "--" in normalized:
117
+ errors.append("Name must not contain consecutive hyphens")
118
+
119
+ description = frontmatter.get("description")
120
+ if not isinstance(description, str) or not description.strip():
121
+ errors.append("Missing or invalid 'description' in frontmatter")
122
+ else:
123
+ desc = description.strip()
124
+ if len(desc) > MAX_DESCRIPTION_LENGTH:
125
+ errors.append(
126
+ f"Description is too long ({len(desc)}). Max {MAX_DESCRIPTION_LENGTH}."
127
+ )
128
+
129
+ allowed_tools = frontmatter.get("allowed-tools")
130
+ if allowed_tools is not None and not isinstance(allowed_tools, str):
131
+ warnings.append("'allowed-tools' should be a space-delimited string")
132
+
133
+ compatibility = frontmatter.get("compatibility")
134
+ if compatibility is not None and not isinstance(compatibility, str):
135
+ warnings.append("'compatibility' should be a string")
136
+
137
+ license_value = frontmatter.get("license")
138
+ if license_value is not None and not isinstance(license_value, str):
139
+ warnings.append("'license' should be a string")
140
+
141
+ metadata = frontmatter.get("metadata")
142
+ if metadata is not None and not isinstance(metadata, dict):
143
+ warnings.append("'metadata' should be a mapping")
144
+
145
+ disable_invocation = frontmatter.get("disable-model-invocation")
146
+ if disable_invocation is not None and not isinstance(disable_invocation, bool):
147
+ warnings.append("'disable-model-invocation' should be a boolean")
148
+
149
+ return errors, warnings
150
+
151
+
152
+ def validate_skill(skill_path: Path) -> tuple[list[str], list[str]]:
153
+ errors: list[str] = []
154
+ warnings: list[str] = []
155
+
156
+ if not skill_path.exists():
157
+ return [f"Skill directory not found: {skill_path}"], warnings
158
+
159
+ if not skill_path.is_dir():
160
+ return [f"Skill path is not a directory: {skill_path}"], warnings
161
+
162
+ skill_md = skill_path / "SKILL.md"
163
+ if not skill_md.exists():
164
+ errors.append("SKILL.md not found")
165
+ return errors, warnings
166
+
167
+ frontmatter, frontmatter_error = read_frontmatter(skill_md)
168
+ if frontmatter_error:
169
+ errors.append(frontmatter_error)
170
+ return errors, warnings
171
+
172
+ fm_errors, fm_warnings = validate_frontmatter(frontmatter, skill_path)
173
+ errors.extend(fm_errors)
174
+ warnings.extend(fm_warnings)
175
+
176
+ readme_errors, readme_warnings = validate_readme(skill_path / "README.md")
177
+ errors.extend(readme_errors)
178
+ warnings.extend(readme_warnings)
179
+
180
+ return errors, warnings
181
+
182
+
183
+ def main() -> None:
184
+ if len(sys.argv) != 2:
185
+ print("Usage: scripts/validate_skill.py <skill_directory>")
186
+ sys.exit(1)
187
+
188
+ skill_path = Path(sys.argv[1]).resolve()
189
+ errors, warnings = validate_skill(skill_path)
190
+
191
+ if warnings:
192
+ print("Warnings:")
193
+ for warning in warnings:
194
+ print(f" - {warning}")
195
+ print()
196
+
197
+ if errors:
198
+ print("Errors:")
199
+ for error in errors:
200
+ print(f" - {error}")
201
+ sys.exit(1)
202
+
203
+ print("Skill is valid!")
204
+ sys.exit(0)
205
+
206
+
207
+ if __name__ == "__main__":
208
+ main()
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.5 - 2026-02-03
4
+
5
+ ### Added
6
+ - Add preview image metadata for the extension listing.
7
+
3
8
  ## 0.1.4 - 2026-02-02
4
9
 
5
10
  ### Changed
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tmustier/pi-ralph-wiggum",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Long-running agent loops for iterative development in Pi.",
5
5
  "license": "MIT",
6
6
  "author": "Thomas Mustier",
@@ -20,6 +20,7 @@
20
20
  ],
21
21
  "skills": [
22
22
  "SKILL.md"
23
- ]
23
+ ],
24
+ "image": "https://github.com/user-attachments/assets/68cdab11-76c6-4aed-9ea1-558cbb267ea6"
24
25
  }
25
26
  }
@@ -1,5 +1,8 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.2 - 2026-02-03
4
+ - Add preview image metadata for the extension listing.
5
+
3
6
  ## 0.1.1 - 2026-01-16
4
7
  - Fix crash on Pi v0.47+ caused by CustomEditor signature change.
5
8
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tmustier/pi-raw-paste",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "One-shot raw paste support for Pi (/paste).",
5
5
  "license": "MIT",
6
6
  "author": "Thomas Mustier",
@@ -17,6 +17,7 @@
17
17
  "pi": {
18
18
  "extensions": [
19
19
  "index.ts"
20
- ]
20
+ ],
21
+ "image": "https://github.com/user-attachments/assets/292c059a-8b06-40c2-abdd-795c0699336a"
21
22
  }
22
23
  }
@@ -1,5 +1,8 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.3 - 2026-02-03
4
+ - Add preview image metadata for the extension listing.
5
+
3
6
  ## 0.1.2 - 2026-01-26
4
7
  - Added note clarifying one active session per tab is tracked.
5
8
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tmustier/pi-tab-status",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Terminal tab status indicators for Pi sessions.",
5
5
  "license": "MIT",
6
6
  "author": "Thomas Mustier",
@@ -17,6 +17,7 @@
17
17
  "pi": {
18
18
  "extensions": [
19
19
  "tab-status.ts"
20
- ]
20
+ ],
21
+ "image": "https://raw.githubusercontent.com/tmustier/pi-extensions/main/tab-status/assets/tab-status.png"
21
22
  }
22
23
  }
@@ -1,5 +1,8 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.3 - 2026-02-03
4
+ - Add preview image metadata for the extension listing.
5
+
3
6
  ## 0.1.2 - 2026-01-13
4
7
  - Add loading spinner while parsing session files (Esc to cancel)
5
8
  - Make data loading async to keep UI responsive
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tmustier/pi-usage-extension",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Usage statistics dashboard for Pi sessions.",
5
5
  "license": "MIT",
6
6
  "author": "Thomas Mustier",
@@ -17,6 +17,7 @@
17
17
  "pi": {
18
18
  "extensions": [
19
19
  "index.ts"
20
- ]
20
+ ],
21
+ "image": "https://raw.githubusercontent.com/tmustier/pi-extensions/main/usage-extension/screenshot.png"
21
22
  }
22
23
  }