@matyah00/openpi 0.1.2 → 0.1.4
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/LICENSE +21 -0
- package/README.md +335 -73
- package/extensions/commands.ts +8 -43
- package/extensions/lib/markdown.ts +27 -0
- package/extensions/system-select.ts +6 -16
- package/package.json +2 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 haytamAroui
|
|
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.
|
package/README.md
CHANGED
|
@@ -1,14 +1,54 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<h1>OpenPi</h1>
|
|
3
|
+
<p><strong>A Pi-native command, skill, agent, workflow, and theme pack for serious coding sessions.</strong></p>
|
|
4
|
+
<p>
|
|
5
|
+
<a href="https://www.npmjs.com/package/@matyah00/openpi"><img src="https://img.shields.io/npm/v/@matyah00/openpi.svg" alt="npm version"></a>
|
|
6
|
+
<a href="https://github.com/haytamAroui/OpenPi/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="license"></a>
|
|
7
|
+
<a href="https://github.com/haytamAroui/OpenPi"><img src="https://img.shields.io/badge/Pi-native-111827" alt="Pi native"></a>
|
|
8
|
+
<a href="https://www.npmjs.com/package/@matyah00/openpi"><img src="https://img.shields.io/badge/install-pi%20install%20npm%3A%40matyah00%2Fopenpi-0f766e" alt="Pi install"></a>
|
|
9
|
+
</p>
|
|
10
|
+
<p>
|
|
11
|
+
<a href="#the-core-idea">Core Idea</a>
|
|
12
|
+
<a href="#install">Install</a>
|
|
13
|
+
<a href="#quick-start">Quick Start</a>
|
|
14
|
+
<a href="#what-you-get">What You Get</a>
|
|
15
|
+
<a href="#profiles">Profiles</a>
|
|
16
|
+
<a href="#commands">Commands</a>
|
|
17
|
+
<a href="#agent-workflows">Agents</a>
|
|
18
|
+
<a href="#tooling">Tools</a>
|
|
19
|
+
<a href="#architecture">Architecture</a>
|
|
20
|
+
</p>
|
|
21
|
+
</div>
|
|
2
22
|
|
|
3
|
-
|
|
23
|
+
---
|
|
4
24
|
|
|
5
|
-
|
|
25
|
+
## The Core Idea
|
|
26
|
+
|
|
27
|
+
**OpenPi turns Pi into a richer engineering environment without copying another assistant's file layout.**
|
|
28
|
+
|
|
29
|
+
It uses Pi-owned package surfaces:
|
|
6
30
|
|
|
7
31
|
- `prompts/*.md` for slash-command prompt templates
|
|
8
32
|
- `skills/*/SKILL.md` for Pi skills
|
|
9
|
-
- `agents/*.md` for
|
|
10
|
-
- `
|
|
11
|
-
- `
|
|
33
|
+
- `agents/*.md` for specialist role prompts
|
|
34
|
+
- `extensions/*.ts` for native Pi commands, tools, profile switching, themes, and workflow orchestration
|
|
35
|
+
- `themes/*.json` for terminal UI themes
|
|
36
|
+
|
|
37
|
+
```text
|
|
38
|
+
Plain Pi session OpenPi session
|
|
39
|
+
|
|
40
|
+
Manual project scan /prime and /explore orient the session
|
|
41
|
+
Ad hoc planning /spec, /clarify, /blueprint, /debate
|
|
42
|
+
One long assistant context spawn_agents delegates to role agents
|
|
43
|
+
Manual grep/tree work project_tree and code_search_batch
|
|
44
|
+
Manual safety checks secret_scan, env_scan, ghost_test_scan
|
|
45
|
+
Lost session reasoning /snapshot, goal_state, write_snapshot
|
|
46
|
+
One profile for every task /openpi use <profile>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
OpenPi is not a project template. It is a reusable Pi package you install once and activate per project or globally.
|
|
50
|
+
|
|
51
|
+
---
|
|
12
52
|
|
|
13
53
|
## Install
|
|
14
54
|
|
|
@@ -22,96 +62,318 @@ For Pi:
|
|
|
22
62
|
pi install npm:@matyah00/openpi
|
|
23
63
|
```
|
|
24
64
|
|
|
25
|
-
Restart Pi after install
|
|
65
|
+
Restart Pi after install, then activate a profile:
|
|
66
|
+
|
|
67
|
+
```text
|
|
68
|
+
/openpi use full
|
|
69
|
+
/reload
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The npm names `openpi` and `open-pi` are blocked by npm's package-name similarity policy, so the public npm package is:
|
|
73
|
+
|
|
74
|
+
```text
|
|
75
|
+
@matyah00/openpi
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Quick Start
|
|
81
|
+
|
|
82
|
+
```text
|
|
83
|
+
/openpi list show every profile
|
|
84
|
+
/openpi use commands enable prompt commands and core tools
|
|
85
|
+
/openpi use workflow enable /add, /fix, /review and spawn_agents
|
|
86
|
+
/openpi use guard enable security, dependency, and ship gates
|
|
87
|
+
/openpi use full enable the broad OpenPi surface
|
|
88
|
+
/openpi clear remove OpenPi-managed extensions
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Use `--global` to install the selected profile into your global Pi settings:
|
|
92
|
+
|
|
93
|
+
```text
|
|
94
|
+
/openpi use full --global
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Profiles update `.pi/settings.json`. Run `/reload` or restart Pi after switching.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## What You Get
|
|
102
|
+
|
|
103
|
+
```text
|
|
104
|
+
OpenPi
|
|
105
|
+
13 profiles choose a focused runtime surface per task
|
|
106
|
+
19 prompt commands /prime, /blueprint, /deep, /ship, /parallel, ...
|
|
107
|
+
36 agent prompts planner, reviewer, tester, security-auditor, Pi experts
|
|
108
|
+
7 skills ultrathink, test-first, security-guard, bowser, ...
|
|
109
|
+
11 themes tokyo-night, rose-pine, gruvbox, nord, dracula, ...
|
|
110
|
+
Native tools search, audit, state, snapshot, dispatch, chains
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
OpenPi is designed around one practical rule: load only the surface you need.
|
|
114
|
+
|
|
115
|
+
| Need | Profile | What it adds |
|
|
116
|
+
|------|---------|--------------|
|
|
117
|
+
| Slash commands | `commands` | Prompt commands, search tools, state tools, theme switching |
|
|
118
|
+
| Explore a repo | `explore` | Tree/search/discovery workflows |
|
|
119
|
+
| Implement work | `workflow` | `/add`, `/fix`, `/review`, `spawn_agents` |
|
|
120
|
+
| Pre-ship safety | `guard` | Security, dependency, environment, and test-integrity tools |
|
|
121
|
+
| Focused UI | `focus` | Minimal Pi UI plus theme defaults |
|
|
122
|
+
| Session purpose | `purpose` | Keeps task purpose visible while working |
|
|
123
|
+
| Metrics | `metrics` | Model, context, branch, token, cost, and tool counters |
|
|
124
|
+
| Personas | `system` | Switch active system persona from bundled agents |
|
|
125
|
+
| Teams | `team` | Dispatcher-only role team with `dispatch_agent` |
|
|
126
|
+
| Chains | `chain` | Sequential workflow runner with `run_chain` |
|
|
127
|
+
| Everything | `full` | Commands, workflow, safety, metrics, personas, teams, chains |
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Commands
|
|
132
|
+
|
|
133
|
+
OpenPi prompt commands are markdown templates with frontmatter metadata. They are loaded from the package and can be extended by project-local `.pi/prompts/*.md`.
|
|
134
|
+
|
|
135
|
+
### Planning and reasoning
|
|
136
|
+
|
|
137
|
+
| Command | Purpose |
|
|
138
|
+
|---------|---------|
|
|
139
|
+
| `/prime` | Load project orientation before work |
|
|
140
|
+
| `/spec` | Turn a vague feature into a structured spec |
|
|
141
|
+
| `/clarify` | Ask focused clarification questions before coding |
|
|
142
|
+
| `/blueprint` | Build an implementation blueprint before risky work |
|
|
143
|
+
| `/debate` | Run adversarial decision analysis for tradeoffs |
|
|
144
|
+
| `/deep` | Use deeper evidence-led reasoning for hard bugs or architecture |
|
|
145
|
+
| `/plan-team` | Create a team-oriented implementation plan |
|
|
146
|
+
|
|
147
|
+
### Discovery and state
|
|
148
|
+
|
|
149
|
+
| Command | Purpose |
|
|
150
|
+
|---------|---------|
|
|
151
|
+
| `/explore` | Map relevant files and code paths |
|
|
152
|
+
| `/goal` | Manage durable task goals in `.pi/memory/goals.md` |
|
|
153
|
+
| `/snapshot` | Save a continuation checkpoint before compaction |
|
|
154
|
+
| `/compress` | Compress current task context into a handoff brief |
|
|
155
|
+
| `/commands` | List loaded OpenPi and project prompt commands |
|
|
156
|
+
| `/command:status` | Show command loader status and collisions |
|
|
157
|
+
|
|
158
|
+
### Quality and release
|
|
159
|
+
|
|
160
|
+
| Command | Purpose |
|
|
161
|
+
|---------|---------|
|
|
162
|
+
| `/code-review` | Review code or changes for bugs and missing tests |
|
|
163
|
+
| `/test` | Select or design focused validation |
|
|
164
|
+
| `/validate` | Run targeted validation for current work |
|
|
165
|
+
| `/deps` | Audit dependency manifests, lockfiles, pins, and update risk |
|
|
166
|
+
| `/ghost-test` | Detect vacuous tests and reward-hacking test patterns |
|
|
167
|
+
| `/sentinel` | Read-only security and environment safety scan |
|
|
168
|
+
| `/ship` | Pre-ship gate for tests, security, dependency risk, and git readiness |
|
|
169
|
+
| `/parallel` | Plan safe parallel work with ownership checks |
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Agent Workflows
|
|
174
|
+
|
|
175
|
+
The `workflow` profile adds high-level commands that prompt Pi to use role agents and verification steps.
|
|
176
|
+
|
|
177
|
+
```text
|
|
178
|
+
/add <feature> discover files -> plan -> edit -> test -> review
|
|
179
|
+
/fix <bug> reproduce/inspect -> plan -> patch -> validate -> review
|
|
180
|
+
/review [scope] read-only review over diff or requested scope
|
|
181
|
+
/openpi-agents list available role agents
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
OpenPi role agents include:
|
|
185
|
+
|
|
186
|
+
| Agent | Role |
|
|
187
|
+
|-------|------|
|
|
188
|
+
| `file-picker` | Finds relevant files and line ranges before edits |
|
|
189
|
+
| `planner` | Produces scoped implementation plans |
|
|
190
|
+
| `editor` | Performs isolated edits when the plan is clear |
|
|
191
|
+
| `tester` | Selects and runs targeted validation |
|
|
192
|
+
| `reviewer` | Reviews diffs for bugs, regressions, and missing tests |
|
|
193
|
+
| `security-auditor` | Checks secrets, risky automation, and security-sensitive changes |
|
|
194
|
+
| `problem-architect` | Turns ambiguous work into a concrete team spec |
|
|
195
|
+
| `spec-reviewer` | Challenges unclear requirements before implementation |
|
|
196
|
+
| `ship-guard` | Reviews release readiness |
|
|
197
|
+
| `red-team` | Challenges plans and assumptions |
|
|
198
|
+
|
|
199
|
+
The `spawn_agents` tool can run agents sequentially or in parallel as isolated Pi subprocesses. It returns structured outputs: files, line ranges, commands, exact validation output, findings, and assumptions.
|
|
200
|
+
|
|
201
|
+
---
|
|
26
202
|
|
|
27
|
-
|
|
28
|
-
similarity policy, so this package uses the public scoped name
|
|
29
|
-
`@matyah00/openpi`.
|
|
203
|
+
## Team and Chain Modes
|
|
30
204
|
|
|
31
|
-
|
|
205
|
+
OpenPi has two orchestration modes for larger work.
|
|
32
206
|
|
|
33
|
-
|
|
207
|
+
### Team dispatcher
|
|
34
208
|
|
|
35
209
|
```text
|
|
36
|
-
/openpi use commands
|
|
37
|
-
/openpi use explore
|
|
38
|
-
/openpi use guard
|
|
39
|
-
/openpi use workflow
|
|
40
|
-
/openpi use system
|
|
41
210
|
/openpi use team
|
|
211
|
+
/agents-list
|
|
212
|
+
/agents-team guard
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
The `team` profile registers `dispatch_agent` and uses teams from `agents/teams.yaml`, including:
|
|
216
|
+
|
|
217
|
+
| Team | Agents |
|
|
218
|
+
|------|--------|
|
|
219
|
+
| `research` | scout, directory-lister, glob-matcher, code-searcher, librarian, documenter, red-team |
|
|
220
|
+
| `validation` | tester, basher, reviewer |
|
|
221
|
+
| `guard` | security-auditor, rule-verifier, ship-guard, spec-reviewer |
|
|
222
|
+
| `frontend` | scout, frontend, reviewer |
|
|
223
|
+
| `backend` | scout, backend, reviewer |
|
|
224
|
+
| `pi-pi` | Pi package, extension, skill, prompt, config, theme, TUI, CLI, and keybinding experts |
|
|
225
|
+
|
|
226
|
+
### Chain runner
|
|
227
|
+
|
|
228
|
+
```text
|
|
42
229
|
/openpi use chain
|
|
43
|
-
/
|
|
44
|
-
/openpi clear
|
|
230
|
+
/chain-list
|
|
45
231
|
```
|
|
46
232
|
|
|
47
|
-
|
|
48
|
-
Run `/reload` or restart Pi after changing profiles.
|
|
233
|
+
The `chain` profile registers `run_chain` for sequential workflows from `agents/agent-chain.yaml`:
|
|
49
234
|
|
|
50
|
-
|
|
235
|
+
| Chain | Flow |
|
|
236
|
+
|-------|------|
|
|
237
|
+
| `plan-build-review` | planner -> builder -> reviewer |
|
|
238
|
+
| `research-plan` | scout -> red-team -> planner |
|
|
239
|
+
| `deep-explore` | directory-lister -> code-searcher -> thinker |
|
|
240
|
+
| `evidence-validate` | code-searcher -> tester -> reviewer |
|
|
241
|
+
| `spec-to-plan` | problem-architect -> spec-reviewer -> planner |
|
|
242
|
+
| `ship-gate` | security-auditor -> ship-guard -> reviewer |
|
|
243
|
+
| `pi-package-design` | Pi experts -> planner |
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## Tooling
|
|
248
|
+
|
|
249
|
+
OpenPi registers native Pi tools through profiles.
|
|
250
|
+
|
|
251
|
+
| Tool | Purpose |
|
|
252
|
+
|------|---------|
|
|
253
|
+
| `project_tree` | Return a scoped project tree with ignore handling |
|
|
254
|
+
| `code_search_batch` | Run multiple code searches in one call |
|
|
255
|
+
| `env_scan` | Detect stack, package managers, scripts, and environment clues |
|
|
256
|
+
| `secret_scan` | Search for common secret and credential patterns |
|
|
257
|
+
| `ghost_test_scan` | Find weak, vacuous, or reward-hacked tests |
|
|
258
|
+
| `dependency_inventory` | Summarize dependency manifests and lockfiles |
|
|
259
|
+
| `session_state` | Read current session state |
|
|
260
|
+
| `goal_state` | Read goal memory state |
|
|
261
|
+
| `write_snapshot` | Write a continuation snapshot |
|
|
262
|
+
| `parallel_safety_check` | Check file ownership overlap before parallel work |
|
|
263
|
+
| `spawn_agents` | Run role agents as isolated Pi subprocesses |
|
|
264
|
+
| `dispatch_agent` | Dispatch to the active specialist team |
|
|
265
|
+
| `run_chain` | Run a named sequential agent chain |
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Skills
|
|
270
|
+
|
|
271
|
+
OpenPi ships focused Pi skills:
|
|
272
|
+
|
|
273
|
+
| Skill | Use it for |
|
|
274
|
+
|-------|------------|
|
|
275
|
+
| `ultrathink` | Hard debugging, architecture tradeoffs, root-cause analysis |
|
|
276
|
+
| `test-first` | Production code, bug fixes, refactors, validation planning |
|
|
277
|
+
| `security-guard` | Credentials, env files, external code, automation, deploy risk |
|
|
278
|
+
| `spec-driven` | Vague requirements, unclear features, acceptance criteria |
|
|
279
|
+
| `session-continuity` | Long context, resuming, stopping, compaction handoffs |
|
|
280
|
+
| `env-scanner` | Unknown repos, setup issues, stack detection |
|
|
281
|
+
| `bowser` | Playwright-powered browser automation and UI testing |
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## Themes and UI Profiles
|
|
51
286
|
|
|
52
|
-
|
|
287
|
+
OpenPi includes 11 bundled themes:
|
|
53
288
|
|
|
54
289
|
```text
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
/
|
|
64
|
-
/
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
290
|
+
catppuccin-mocha cyberpunk dracula everforest gruvbox
|
|
291
|
+
midnight-ocean nord ocean-breeze rose-pine
|
|
292
|
+
synthwave tokyo-night
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
Use the theme profile or the `full` profile, then:
|
|
296
|
+
|
|
297
|
+
```text
|
|
298
|
+
/theme
|
|
299
|
+
/theme tokyo-night
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
UI-oriented profiles:
|
|
303
|
+
|
|
304
|
+
| Profile | Purpose |
|
|
305
|
+
|---------|---------|
|
|
306
|
+
| `focus` | Minimal, distraction-free Pi UI |
|
|
307
|
+
| `metrics` | Status bar and usage metrics |
|
|
308
|
+
| `tool-widget` | Live per-tool usage counts |
|
|
309
|
+
| `purpose` | Session purpose gate and visible task focus |
|
|
310
|
+
| `safety` | Damage-control rules and actionable blocked-tool feedback |
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## Architecture
|
|
315
|
+
|
|
316
|
+
OpenPi is a package, not a project scaffold.
|
|
77
317
|
|
|
78
318
|
```text
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
write_snapshot
|
|
88
|
-
parallel_safety_check
|
|
319
|
+
@matyah00/openpi
|
|
320
|
+
package.json Pi package manifest
|
|
321
|
+
prompts/ prompt commands
|
|
322
|
+
skills/ Pi skills
|
|
323
|
+
agents/ role agents, teams, chains
|
|
324
|
+
extensions/ native Pi extensions and tools
|
|
325
|
+
themes/ terminal UI themes
|
|
326
|
+
damage-control-rules.yaml safety feedback rules
|
|
89
327
|
```
|
|
90
328
|
|
|
91
|
-
|
|
329
|
+
The activation flow is explicit:
|
|
92
330
|
|
|
93
331
|
```text
|
|
94
|
-
|
|
95
|
-
/
|
|
96
|
-
/
|
|
97
|
-
/
|
|
332
|
+
1. Install package with Pi
|
|
333
|
+
2. Run /openpi use <profile>
|
|
334
|
+
3. OpenPi writes selected extension paths into .pi/settings.json
|
|
335
|
+
4. Run /reload or restart Pi
|
|
336
|
+
5. Use only the commands/tools for that profile
|
|
98
337
|
```
|
|
99
338
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
339
|
+
This keeps OpenPi portable across projects. You can add project-specific prompts and agents in `.pi/prompts` and `.pi/agents`; OpenPi will load them alongside the bundled resources where the active profile supports it.
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
## Why It Is Different
|
|
105
344
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
345
|
+
| Without OpenPi | With OpenPi |
|
|
346
|
+
|----------------|-------------|
|
|
347
|
+
| One generic assistant flow | Profiles for planning, workflow, guard, team, chain, UI |
|
|
348
|
+
| Manual project discovery | `/explore`, `project_tree`, `code_search_batch` |
|
|
349
|
+
| Vague implementation prompts | `/spec`, `/clarify`, `/blueprint`, `problem-architect` |
|
|
350
|
+
| Manual review discipline | `/review`, `reviewer`, `ship-guard`, `ghost_test_scan` |
|
|
351
|
+
| One large context | `spawn_agents`, `dispatch_agent`, `run_chain` |
|
|
352
|
+
| Repeated session loss | `/snapshot`, `write_snapshot`, `goal_state` |
|
|
353
|
+
| Ad hoc security checks | `secret_scan`, `/sentinel`, `security-guard` |
|
|
354
|
+
| Same UI for every task | focus, metrics, purpose, tool-widget, safety profiles |
|
|
109
355
|
|
|
110
|
-
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
## Verified
|
|
359
|
+
|
|
360
|
+
Before publish, the package is checked with:
|
|
361
|
+
|
|
362
|
+
```bash
|
|
363
|
+
npm pack --dry-run
|
|
364
|
+
npx tsc --noEmit
|
|
365
|
+
npm install @matyah00/openpi@latest --dry-run
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
Current npm package:
|
|
369
|
+
|
|
370
|
+
```bash
|
|
371
|
+
npm i @matyah00/openpi
|
|
372
|
+
pi install npm:@matyah00/openpi
|
|
373
|
+
```
|
|
111
374
|
|
|
112
|
-
|
|
375
|
+
---
|
|
113
376
|
|
|
114
|
-
|
|
115
|
-
`dispatch_agent` to delegate work to the selected team.
|
|
377
|
+
## License
|
|
116
378
|
|
|
117
|
-
|
|
379
|
+
MIT - [haytamAroui](https://github.com/haytamAroui)
|
package/extensions/commands.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { ExtensionAPI } from "@
|
|
1
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
3
3
|
import { basename, join } from "node:path";
|
|
4
4
|
import { bundledPromptsDir } from "./lib/packagePaths.ts";
|
|
5
|
+
import { arrayField, parseMarkdownFrontmatter, stringField } from "./lib/markdown.ts";
|
|
5
6
|
|
|
6
7
|
type CommandDef = {
|
|
7
8
|
name: string;
|
|
@@ -12,42 +13,6 @@ type CommandDef = {
|
|
|
12
13
|
source: string;
|
|
13
14
|
};
|
|
14
15
|
|
|
15
|
-
function parseFrontmatter(raw: string): { fields: Record<string, string | string[]>; body: string } {
|
|
16
|
-
const match = raw.match(/^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/);
|
|
17
|
-
if (!match) return { fields: {}, body: raw };
|
|
18
|
-
|
|
19
|
-
const fields: Record<string, string | string[]> = {};
|
|
20
|
-
let currentListKey = "";
|
|
21
|
-
for (const line of match[1].split("\n")) {
|
|
22
|
-
const listMatch = line.match(/^\s+-\s+(.+)$/);
|
|
23
|
-
if (listMatch && currentListKey) {
|
|
24
|
-
const existing = fields[currentListKey];
|
|
25
|
-
fields[currentListKey] = Array.isArray(existing) ? [...existing, listMatch[1].trim()] : [listMatch[1].trim()];
|
|
26
|
-
continue;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const idx = line.indexOf(":");
|
|
30
|
-
if (idx > 0) {
|
|
31
|
-
const key = line.slice(0, idx).trim();
|
|
32
|
-
const value = line.slice(idx + 1).trim();
|
|
33
|
-
currentListKey = key;
|
|
34
|
-
fields[key] = value;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return { fields, body: match[2].trim() };
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function stringField(value: string | string[] | undefined): string {
|
|
42
|
-
return typeof value === "string" ? value : "";
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function arrayField(value: string | string[] | undefined): string[] {
|
|
46
|
-
if (Array.isArray(value)) return value;
|
|
47
|
-
if (typeof value === "string" && value.trim()) return value.split(",").map((item) => item.trim()).filter(Boolean);
|
|
48
|
-
return [];
|
|
49
|
-
}
|
|
50
|
-
|
|
51
16
|
function expandArgs(template: string, args: string): string {
|
|
52
17
|
const parts = args.split(/\s+/).filter(Boolean);
|
|
53
18
|
let result = template.replace(/\$ARGUMENTS|\$@/g, args);
|
|
@@ -64,13 +29,13 @@ function scanPromptDir(dir: string, source: string): CommandDef[] {
|
|
|
64
29
|
for (const file of readdirSync(dir)) {
|
|
65
30
|
if (!file.endsWith(".md")) continue;
|
|
66
31
|
const raw = readFileSync(join(dir, file), "utf-8");
|
|
67
|
-
const {
|
|
32
|
+
const { frontmatter, body } = parseMarkdownFrontmatter(raw);
|
|
68
33
|
const firstLine = body.split("\n").find((line) => line.trim())?.trim() || "";
|
|
69
34
|
commands.push({
|
|
70
|
-
name: stringField(
|
|
71
|
-
description: stringField(
|
|
72
|
-
category: stringField(
|
|
73
|
-
aliases: arrayField(
|
|
35
|
+
name: stringField(frontmatter.name) || basename(file, ".md"),
|
|
36
|
+
description: stringField(frontmatter.description) || firstLine.slice(0, 120),
|
|
37
|
+
category: stringField(frontmatter.category) || "general",
|
|
38
|
+
aliases: arrayField(frontmatter.aliases),
|
|
74
39
|
body,
|
|
75
40
|
source,
|
|
76
41
|
});
|
|
@@ -82,8 +47,8 @@ function scanPromptDir(dir: string, source: string): CommandDef[] {
|
|
|
82
47
|
export default function (pi: ExtensionAPI) {
|
|
83
48
|
const cwd = process.cwd();
|
|
84
49
|
const commands = [
|
|
85
|
-
...scanPromptDir(bundledPromptsDir, "openpi"),
|
|
86
50
|
...scanPromptDir(join(cwd, ".pi", "prompts"), ".pi"),
|
|
51
|
+
...scanPromptDir(bundledPromptsDir, "openpi"),
|
|
87
52
|
];
|
|
88
53
|
const byName = new Map<string, CommandDef>();
|
|
89
54
|
const aliases = new Map<string, string>();
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { parse as parseYaml } from "yaml";
|
|
2
|
+
|
|
3
|
+
export type FrontmatterValue = string | string[] | number | boolean | null | undefined;
|
|
4
|
+
|
|
5
|
+
export function parseMarkdownFrontmatter<T extends Record<string, FrontmatterValue> = Record<string, FrontmatterValue>>(
|
|
6
|
+
raw: string,
|
|
7
|
+
): { frontmatter: T; body: string } {
|
|
8
|
+
const match = raw.match(/^---\s*\r?\n([\s\S]*?)\r?\n---\s*\r?\n([\s\S]*)$/);
|
|
9
|
+
if (!match) return { frontmatter: {} as T, body: raw };
|
|
10
|
+
|
|
11
|
+
const parsed = parseYaml(match[1]);
|
|
12
|
+
const frontmatter = parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
13
|
+
? parsed as T
|
|
14
|
+
: {} as T;
|
|
15
|
+
|
|
16
|
+
return { frontmatter, body: match[2].trim() };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function stringField(value: FrontmatterValue): string {
|
|
20
|
+
return typeof value === "string" ? value : "";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function arrayField(value: FrontmatterValue): string[] {
|
|
24
|
+
if (Array.isArray(value)) return value.filter((item): item is string => typeof item === "string");
|
|
25
|
+
if (typeof value === "string" && value.trim()) return value.split(",").map((item) => item.trim()).filter(Boolean);
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type { ExtensionAPI } from "@
|
|
1
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { basename, join } from "node:path";
|
|
5
5
|
import { bundledAgentsDir, bundledPiPiAgentsDir } from "./lib/packagePaths.ts";
|
|
6
|
+
import { arrayField, parseMarkdownFrontmatter, stringField } from "./lib/markdown.ts";
|
|
6
7
|
|
|
7
8
|
type AgentDef = {
|
|
8
9
|
name: string;
|
|
@@ -12,28 +13,17 @@ type AgentDef = {
|
|
|
12
13
|
source: string;
|
|
13
14
|
};
|
|
14
15
|
|
|
15
|
-
function parseFrontmatter(raw: string): { fields: Record<string, string>; body: string } {
|
|
16
|
-
const match = raw.match(/^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/);
|
|
17
|
-
if (!match) return { fields: {}, body: raw };
|
|
18
|
-
const fields: Record<string, string> = {};
|
|
19
|
-
for (const line of match[1].split("\n")) {
|
|
20
|
-
const idx = line.indexOf(":");
|
|
21
|
-
if (idx > 0) fields[line.slice(0, idx).trim()] = line.slice(idx + 1).trim();
|
|
22
|
-
}
|
|
23
|
-
return { fields, body: match[2] };
|
|
24
|
-
}
|
|
25
|
-
|
|
26
16
|
function scanAgents(dir: string, source: string): AgentDef[] {
|
|
27
17
|
if (!existsSync(dir)) return [];
|
|
28
18
|
const agents: AgentDef[] = [];
|
|
29
19
|
for (const file of readdirSync(dir)) {
|
|
30
20
|
if (!file.endsWith(".md")) continue;
|
|
31
21
|
const raw = readFileSync(join(dir, file), "utf-8");
|
|
32
|
-
const {
|
|
22
|
+
const { frontmatter, body } = parseMarkdownFrontmatter(raw);
|
|
33
23
|
agents.push({
|
|
34
|
-
name:
|
|
35
|
-
description:
|
|
36
|
-
tools:
|
|
24
|
+
name: stringField(frontmatter.name) || basename(file, ".md"),
|
|
25
|
+
description: stringField(frontmatter.description),
|
|
26
|
+
tools: arrayField(frontmatter.tools),
|
|
37
27
|
body: body.trim(),
|
|
38
28
|
source,
|
|
39
29
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matyah00/openpi",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Pi-native commands, skills, agents, and workflows.",
|
|
6
6
|
"keywords": [
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"themes",
|
|
29
29
|
"types",
|
|
30
30
|
"damage-control-rules.yaml",
|
|
31
|
+
"LICENSE",
|
|
31
32
|
"README.md",
|
|
32
33
|
"tsconfig.json"
|
|
33
34
|
],
|