@oh-my-pi/cli 0.1.0

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.
Files changed (89) hide show
  1. package/.github/workflows/ci.yml +32 -0
  2. package/.github/workflows/publish.yml +42 -0
  3. package/CHECK.md +352 -0
  4. package/README.md +224 -0
  5. package/biome.json +29 -0
  6. package/bun.lock +50 -0
  7. package/dist/cli.d.ts +3 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +3941 -0
  10. package/dist/commands/create.d.ts +9 -0
  11. package/dist/commands/create.d.ts.map +1 -0
  12. package/dist/commands/doctor.d.ts +10 -0
  13. package/dist/commands/doctor.d.ts.map +1 -0
  14. package/dist/commands/enable.d.ts +13 -0
  15. package/dist/commands/enable.d.ts.map +1 -0
  16. package/dist/commands/info.d.ts +9 -0
  17. package/dist/commands/info.d.ts.map +1 -0
  18. package/dist/commands/init.d.ts +8 -0
  19. package/dist/commands/init.d.ts.map +1 -0
  20. package/dist/commands/install.d.ts +13 -0
  21. package/dist/commands/install.d.ts.map +1 -0
  22. package/dist/commands/link.d.ts +10 -0
  23. package/dist/commands/link.d.ts.map +1 -0
  24. package/dist/commands/list.d.ts +9 -0
  25. package/dist/commands/list.d.ts.map +1 -0
  26. package/dist/commands/outdated.d.ts +9 -0
  27. package/dist/commands/outdated.d.ts.map +1 -0
  28. package/dist/commands/search.d.ts +9 -0
  29. package/dist/commands/search.d.ts.map +1 -0
  30. package/dist/commands/uninstall.d.ts +9 -0
  31. package/dist/commands/uninstall.d.ts.map +1 -0
  32. package/dist/commands/update.d.ts +9 -0
  33. package/dist/commands/update.d.ts.map +1 -0
  34. package/dist/commands/why.d.ts +9 -0
  35. package/dist/commands/why.d.ts.map +1 -0
  36. package/dist/conflicts.d.ts +21 -0
  37. package/dist/conflicts.d.ts.map +1 -0
  38. package/dist/index.d.ts +20 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/manifest.d.ts +81 -0
  41. package/dist/manifest.d.ts.map +1 -0
  42. package/dist/migrate.d.ts +9 -0
  43. package/dist/migrate.d.ts.map +1 -0
  44. package/dist/npm.d.ts +77 -0
  45. package/dist/npm.d.ts.map +1 -0
  46. package/dist/paths.d.ts +27 -0
  47. package/dist/paths.d.ts.map +1 -0
  48. package/dist/symlinks.d.ts +33 -0
  49. package/dist/symlinks.d.ts.map +1 -0
  50. package/package.json +36 -0
  51. package/plugins/metal-theme/README.md +13 -0
  52. package/plugins/metal-theme/omp.json +8 -0
  53. package/plugins/metal-theme/package.json +14 -0
  54. package/plugins/metal-theme/themes/metal.json +79 -0
  55. package/plugins/subagents/README.md +25 -0
  56. package/plugins/subagents/agents/explore.md +71 -0
  57. package/plugins/subagents/agents/planner.md +51 -0
  58. package/plugins/subagents/agents/reviewer.md +53 -0
  59. package/plugins/subagents/agents/task.md +46 -0
  60. package/plugins/subagents/commands/architect-plan.md +9 -0
  61. package/plugins/subagents/commands/implement-with-critic.md +10 -0
  62. package/plugins/subagents/commands/implement.md +10 -0
  63. package/plugins/subagents/omp.json +15 -0
  64. package/plugins/subagents/package.json +21 -0
  65. package/plugins/subagents/tools/task/index.ts +1019 -0
  66. package/scripts/bump-version.sh +52 -0
  67. package/scripts/publish.sh +35 -0
  68. package/src/cli.ts +167 -0
  69. package/src/commands/create.ts +153 -0
  70. package/src/commands/doctor.ts +217 -0
  71. package/src/commands/enable.ts +105 -0
  72. package/src/commands/info.ts +84 -0
  73. package/src/commands/init.ts +42 -0
  74. package/src/commands/install.ts +327 -0
  75. package/src/commands/link.ts +108 -0
  76. package/src/commands/list.ts +71 -0
  77. package/src/commands/outdated.ts +76 -0
  78. package/src/commands/search.ts +60 -0
  79. package/src/commands/uninstall.ts +73 -0
  80. package/src/commands/update.ts +112 -0
  81. package/src/commands/why.ts +105 -0
  82. package/src/conflicts.ts +84 -0
  83. package/src/index.ts +53 -0
  84. package/src/manifest.ts +212 -0
  85. package/src/migrate.ts +181 -0
  86. package/src/npm.ts +150 -0
  87. package/src/paths.ts +72 -0
  88. package/src/symlinks.ts +199 -0
  89. package/tsconfig.json +24 -0
@@ -0,0 +1,32 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ build:
11
+ runs-on: ubuntu-latest
12
+
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - uses: oven-sh/setup-bun@v2
17
+ with:
18
+ bun-version: latest
19
+
20
+ - name: Install dependencies
21
+ run: bun install
22
+
23
+ - name: Check (lint + typecheck)
24
+ run: bun run check
25
+
26
+ - name: Build
27
+ run: bun run build
28
+
29
+ - name: Test CLI
30
+ run: |
31
+ bun dist/cli.js --version
32
+ bun dist/cli.js --help
@@ -0,0 +1,42 @@
1
+ name: Publish
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ jobs:
9
+ publish:
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ contents: read
13
+ id-token: write
14
+
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - uses: oven-sh/setup-bun@v2
19
+ with:
20
+ bun-version: latest
21
+
22
+ - uses: actions/setup-node@v4
23
+ with:
24
+ node-version: '20'
25
+ registry-url: 'https://registry.npmjs.org'
26
+
27
+ - name: Install dependencies
28
+ run: bun install
29
+
30
+ - name: Build
31
+ run: bun run build
32
+
33
+ - name: Publish @oh-my-pi/cli
34
+ run: npm publish --access public --provenance
35
+
36
+ - name: Publish @oh-my-pi/subagents
37
+ working-directory: plugins/subagents
38
+ run: npm publish --access public --provenance
39
+
40
+ - name: Publish @oh-my-pi/metal-theme
41
+ working-directory: plugins/metal-theme
42
+ run: npm publish --access public --provenance
package/CHECK.md ADDED
@@ -0,0 +1,352 @@
1
+ # Implementation Review Checklist
2
+
3
+ Review the oh-my-pi implementation against these requirements. For each item, verify it works correctly and check the listed edge cases.
4
+
5
+ ---
6
+
7
+ ## 1. Install Command (`omp install`)
8
+
9
+ ### Core functionality
10
+ - [ ] `omp install pkg-name` installs from npm
11
+ - [ ] `omp install pkg@version` respects version specifier
12
+ - [ ] `omp install @scope/pkg` handles scoped packages
13
+ - [ ] `omp install ./path` copies local directory
14
+ - [ ] `omp install ~/path` expands home directory
15
+ - [ ] `omp install` (no args) installs from plugins.json
16
+ - [ ] Creates symlinks for each `omp.install` entry
17
+
18
+ ### Edge cases
19
+ - [ ] Package not found on npm → clear error message
20
+ - [ ] Invalid version specifier → graceful failure
21
+ - [ ] Local path doesn't exist → error before any changes
22
+ - [ ] `omp.install` has missing source file → skip with warning, continue others
23
+ - [ ] Circular dependencies between plugins → handled without infinite loop
24
+ - [ ] Nested dependencies with omp field → all get symlinked
25
+ - [ ] Package has no `omp` field → installs but no symlinks (warning?)
26
+ - [ ] Network failure mid-install → rollback partial install
27
+ - [ ] Disk full → appropriate error
28
+ - [ ] Symlink target directory doesn't exist → creates parent dirs
29
+ - [ ] `omp install` with empty plugins.json → helpful message
30
+
31
+ ### Flags
32
+ - [ ] `--global` installs to ~/.pi/plugins/
33
+ - [ ] `--save` adds to plugins.json
34
+ - [ ] `--save-dev` adds to devDependencies
35
+ - [ ] `--force` overwrites conflicts without prompting
36
+ - [ ] `--json` outputs JSON format
37
+
38
+ ---
39
+
40
+ ## 2. Conflict Detection
41
+
42
+ ### Core functionality
43
+ - [ ] Detects when two plugins install to same destination
44
+ - [ ] Interactive prompt offers choices: plugin1, plugin2, abort
45
+ - [ ] User can select which plugin wins
46
+ - [ ] Abort rolls back the install
47
+
48
+ ### Edge cases
49
+ - [ ] Three+ plugins with same destination → all listed
50
+ - [ ] Conflict with already-installed plugin → prompt before npm install
51
+ - [ ] Conflict within same plugin's install array (duplicate dest) → error
52
+ - [ ] `--force` skips all prompts → overwrites
53
+ - [ ] Non-interactive terminal (CI) → fail or use --force
54
+
55
+ ---
56
+
57
+ ## 3. Uninstall Command (`omp uninstall`)
58
+
59
+ ### Core functionality
60
+ - [ ] `omp uninstall pkg` removes package
61
+ - [ ] Removes all symlinks from `omp.install`
62
+ - [ ] Removes from package.json/plugins.json
63
+
64
+ ### Edge cases
65
+ - [ ] Plugin not installed → clear error
66
+ - [ ] Symlink already deleted manually → graceful (ENOENT ignored)
67
+ - [ ] Symlink replaced by real file → remove anyway or warn?
68
+ - [ ] Plugin has dependencies that other plugins also use → don't break them
69
+ - [ ] Partial uninstall (some symlinks fail) → report what failed
70
+
71
+ ---
72
+
73
+ ## 4. Update Command (`omp update`)
74
+
75
+ ### Core functionality
76
+ - [ ] `omp update` updates all plugins
77
+ - [ ] `omp update pkg` updates specific plugin
78
+ - [ ] Respects semver ranges from plugins.json
79
+ - [ ] Re-creates symlinks after update
80
+
81
+ ### Edge cases
82
+ - [ ] Package already at latest → no-op with message
83
+ - [ ] Major version available but range is `^` → doesn't update
84
+ - [ ] Package removed from npm → error handling
85
+ - [ ] Update changes `omp.install` entries → old symlinks removed, new created
86
+ - [ ] Linked (dev) plugins → skipped with message
87
+
88
+ ---
89
+
90
+ ## 5. List Command (`omp list`)
91
+
92
+ ### Core functionality
93
+ - [ ] Shows all installed plugins
94
+ - [ ] Shows version for each
95
+ - [ ] Shows (linked) badge for dev plugins
96
+
97
+ ### Edge cases
98
+ - [ ] No plugins installed → helpful message
99
+ - [ ] Plugin in plugins.json but not in node_modules → show as broken
100
+ - [ ] Corrupt package.json → graceful error
101
+ - [ ] `--json` output is valid JSON
102
+
103
+ ---
104
+
105
+ ## 6. Link Command (`omp link`)
106
+
107
+ ### Core functionality
108
+ - [ ] `omp link ./path` creates symlink to source directory
109
+ - [ ] Marks as linked in manifest
110
+ - [ ] Creates symlinks from `omp.install`
111
+
112
+ ### Edge cases
113
+ - [ ] Path doesn't exist → error
114
+ - [ ] Path has no package.json → uses directory name, creates minimal
115
+ - [ ] Path has omp.json (legacy) → converts to package.json format
116
+ - [ ] Already linked → re-link or error?
117
+ - [ ] `-n, --name` overrides plugin name
118
+ - [ ] Linked plugin updated externally → symlinks still work
119
+
120
+ ---
121
+
122
+ ## 7. Init Command (`omp init`)
123
+
124
+ ### Core functionality
125
+ - [ ] Creates `.pi/plugins.json` in current directory
126
+ - [ ] Correct initial structure: `{ "plugins": {}, "disabled": [] }`
127
+
128
+ ### Edge cases
129
+ - [ ] File already exists → error unless `--force`
130
+ - [ ] `.pi/` directory doesn't exist → creates it
131
+ - [ ] No write permission → clear error
132
+
133
+ ---
134
+
135
+ ## 8. Search Command (`omp search`)
136
+
137
+ ### Core functionality
138
+ - [ ] `omp search query` searches npm for `keywords:omp-plugin`
139
+ - [ ] Shows name, version, description
140
+
141
+ ### Edge cases
142
+ - [ ] No results → helpful message
143
+ - [ ] npm registry unavailable → timeout with error
144
+ - [ ] Very long description → truncated
145
+ - [ ] `--limit` respected
146
+ - [ ] Special characters in query → properly escaped
147
+
148
+ ---
149
+
150
+ ## 9. Info Command (`omp info`)
151
+
152
+ ### Core functionality
153
+ - [ ] `omp info pkg` shows package details
154
+ - [ ] Shows: name, version, description, dependencies, omp.install entries
155
+
156
+ ### Edge cases
157
+ - [ ] Package not found → clear error
158
+ - [ ] Package exists but no omp field → show warning
159
+ - [ ] `--versions` shows available versions
160
+ - [ ] `--json` valid JSON output
161
+
162
+ ---
163
+
164
+ ## 10. Outdated Command (`omp outdated`)
165
+
166
+ ### Core functionality
167
+ - [ ] Lists plugins with newer versions available
168
+ - [ ] Shows current, wanted, latest columns
169
+
170
+ ### Edge cases
171
+ - [ ] All up to date → "All plugins up to date"
172
+ - [ ] npm outdated returns exit code 1 → still parses output
173
+ - [ ] Plugin not on npm anymore → shown as error row
174
+ - [ ] Linked plugins → excluded from check
175
+
176
+ ---
177
+
178
+ ## 11. Doctor Command (`omp doctor`)
179
+
180
+ ### Core functionality
181
+ - [ ] Checks for broken symlinks
182
+ - [ ] Checks for conflicts
183
+ - [ ] Reports missing dependencies
184
+
185
+ ### Edge cases
186
+ - [ ] No issues → "All good"
187
+ - [ ] Symlink target deleted → reported as broken
188
+ - [ ] Symlink replaced by real file → reported
189
+ - [ ] `--fix` repairs broken symlinks
190
+ - [ ] `--fix` can't fix conflict → reports
191
+
192
+ ---
193
+
194
+ ## 12. Create Command (`omp create`)
195
+
196
+ ### Core functionality
197
+ - [ ] `omp create my-plugin` scaffolds new plugin
198
+ - [ ] Creates package.json with omp field
199
+ - [ ] Creates directory structure
200
+
201
+ ### Edge cases
202
+ - [ ] Directory already exists → error
203
+ - [ ] Invalid plugin name (spaces, special chars) → normalized or error
204
+ - [ ] `--description` sets description
205
+ - [ ] `--author` sets author
206
+
207
+ ---
208
+
209
+ ## 13. Why Command (`omp why`)
210
+
211
+ ### Core functionality
212
+ - [ ] `omp why agent/themes/dark.json` shows which plugin installed it
213
+ - [ ] Shows plugin name and source path
214
+
215
+ ### Edge cases
216
+ - [ ] File not installed by any plugin → "Not installed by omp"
217
+ - [ ] File is manually created (not symlink) → detect and report
218
+ - [ ] Relative vs absolute path → both work
219
+ - [ ] File doesn't exist → appropriate error
220
+
221
+ ---
222
+
223
+ ## 14. Enable/Disable Commands
224
+
225
+ ### Core functionality
226
+ - [ ] `omp disable pkg` removes symlinks, keeps in node_modules
227
+ - [ ] `omp enable pkg` restores symlinks
228
+ - [ ] Disabled list persisted
229
+
230
+ ### Edge cases
231
+ - [ ] Disable already-disabled → no-op or error
232
+ - [ ] Enable not-disabled → no-op
233
+ - [ ] Enable not-installed → error
234
+ - [ ] Symlinks manually restored → enable detects and handles
235
+
236
+ ---
237
+
238
+ ## 15. Project-Local vs Global
239
+
240
+ ### Core functionality
241
+ - [ ] Default is global (~/.pi/)
242
+ - [ ] With `.pi/plugins.json` in cwd, uses project-local
243
+ - [ ] `--global` forces global even with local config
244
+ - [ ] Symlinks go to correct location per scope
245
+
246
+ ### Edge cases
247
+ - [ ] Nested projects (parent and child have .pi/) → uses closest
248
+ - [ ] Project-local install then run from parent dir → correct behavior
249
+ - [ ] Same plugin installed globally and locally → local takes precedence?
250
+
251
+ ---
252
+
253
+ ## 16. Migration (`omp migrate`)
254
+
255
+ ### Core functionality
256
+ - [ ] Detects legacy manifest.json
257
+ - [ ] Converts to package.json format
258
+ - [ ] Preserves all plugin info
259
+ - [ ] Re-creates symlinks
260
+
261
+ ### Edge cases
262
+ - [ ] No legacy manifest → "Nothing to migrate"
263
+ - [ ] Partial migration (some plugins fail) → reports
264
+ - [ ] Legacy plugin source gone → reports but continues
265
+ - [ ] Backup of manifest.json created
266
+
267
+ ---
268
+
269
+ ## 17. Lock File
270
+
271
+ ### Core functionality
272
+ - [ ] package-lock.json generated for global
273
+ - [ ] plugins-lock.json generated for project-local
274
+ - [ ] Reproducible installs with lock file
275
+
276
+ ### Edge cases
277
+ - [ ] Lock file corrupt → regenerate with warning
278
+ - [ ] Lock file deleted → works but warns about reproducibility
279
+
280
+ ---
281
+
282
+ ## 18. Symlinks Module
283
+
284
+ ### Core functionality
285
+ - [ ] Creates symlinks correctly
286
+ - [ ] Removes symlinks on uninstall
287
+ - [ ] Validates symlink health
288
+
289
+ ### Edge cases
290
+ - [ ] **BUG CHECK: Project-local uses correct base path (.pi/ not ~/.pi/)**
291
+ - [ ] Destination is a directory → symlink whole directory
292
+ - [ ] Destination is a file → symlink file
293
+ - [ ] Parent directories created recursively
294
+ - [ ] Windows compatibility (if applicable) → use junctions or requires admin
295
+
296
+ ---
297
+
298
+ ## 19. npm Module
299
+
300
+ ### Core functionality
301
+ - [ ] npm install works with prefix
302
+ - [ ] npm info fetches package data
303
+ - [ ] npm search returns results
304
+ - [ ] npm outdated parsed correctly
305
+
306
+ ### Edge cases
307
+ - [ ] npm not installed → clear error
308
+ - [ ] npm version too old → check and warn
309
+ - [ ] Private registry → respects .npmrc
310
+ - [ ] Scoped package with private registry → works
311
+
312
+ ---
313
+
314
+ ## 20. General Edge Cases
315
+
316
+ ### Error handling
317
+ - [ ] All commands have try/catch at top level
318
+ - [ ] Errors include actionable messages
319
+ - [ ] Stack traces hidden unless DEBUG
320
+
321
+ ### Permissions
322
+ - [ ] No sudo required for ~/.pi
323
+ - [ ] Handles permission denied gracefully
324
+ - [ ] Doesn't follow symlinks outside allowed paths (security)
325
+
326
+ ### Concurrency
327
+ - [ ] Two `omp install` at once → lock file prevents corruption
328
+ - [ ] Interrupted install → recoverable state
329
+
330
+ ### Unicode/i18n
331
+ - [ ] Plugin names with unicode → handled
332
+ - [ ] Paths with spaces → quoted correctly
333
+ - [ ] Paths with unicode → work on all platforms
334
+
335
+ ---
336
+
337
+ ## Verification Steps
338
+
339
+ For each section above:
340
+ 1. Read the relevant source file
341
+ 2. Trace the code path for the happy case
342
+ 3. Check each edge case is handled
343
+ 4. Note any missing error handling
344
+ 5. Run the command if possible to verify
345
+
346
+ Report findings as:
347
+ ```
348
+ ## [Command Name]
349
+ ✓ Working: [list of working features]
350
+ ✗ Missing: [list of unimplemented features]
351
+ ⚠ Issues: [list of bugs or edge cases not handled]
352
+ ```
package/README.md ADDED
@@ -0,0 +1,224 @@
1
+ # Oh My Pi (omp)
2
+
3
+ Plugin manager for pi configuration. Like oh-my-zsh, but for pi.
4
+
5
+ **v1.0 - npm-Native Architecture**
6
+
7
+ Plugins are npm packages with an `omp` field in package.json. Discover plugins via npm, install with semver, and enjoy a familiar package management experience.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install -g @oh-my-pi/cli
13
+ ```
14
+
15
+ ## Quick Start
16
+
17
+ ```bash
18
+ # Search for plugins
19
+ omp search agents
20
+
21
+ # Install a plugin
22
+ omp install @oh-my-pi/subagents
23
+
24
+ # List installed plugins
25
+ omp list
26
+
27
+ # Check for updates
28
+ omp outdated
29
+
30
+ # Update all plugins
31
+ omp update
32
+ ```
33
+
34
+ ## Commands
35
+
36
+ ### Core Commands
37
+
38
+ | Command | Description |
39
+ |----------------------|--------------------------------------------------------|
40
+ | `omp install [pkg...]` | Install plugin(s). No args = install from plugins.json |
41
+ | `omp uninstall <pkg>` | Remove plugin and its symlinks |
42
+ | `omp update [pkg]` | Update to latest within semver range |
43
+ | `omp list` | Show installed plugins |
44
+ | `omp link <path>` | Symlink local plugin (dev mode) |
45
+
46
+ ### Discovery & Info
47
+
48
+ | Command | Description |
49
+ |------------------------|--------------------------------------------|
50
+ | `omp search <query>` | Search npm for omp-plugin keyword |
51
+ | `omp info <pkg>` | Show plugin details before install |
52
+ | `omp outdated` | List plugins with newer versions |
53
+
54
+ ### Maintenance
55
+
56
+ | Command | Description |
57
+ |--------------------------|------------------------------------------|
58
+ | `omp init` | Create .pi/plugins.json in current project |
59
+ | `omp doctor` | Check for broken symlinks, conflicts |
60
+ | `omp why <file>` | Show which plugin installed a file |
61
+ | `omp enable/disable <pkg>` | Toggle plugin without uninstall |
62
+
63
+ ### Plugin Development
64
+
65
+ | Command | Description |
66
+ |--------------------|--------------------------------|
67
+ | `omp create <name>`| Scaffold new plugin from template |
68
+ | `omp link <path>` | Symlink local plugin for dev |
69
+
70
+ ### Flags
71
+
72
+ - `--global / -g`: Install to ~/.pi (default)
73
+ - `--save / -S`: Add to plugins.json
74
+ - `--json`: Machine-readable output
75
+ - `--force`: Overwrite conflicts
76
+
77
+ ## Plugin Format
78
+
79
+ Plugins are npm packages with an `omp` field in package.json:
80
+
81
+ ```json
82
+ {
83
+ "name": "@oh-my-pi/subagents",
84
+ "version": "1.0.0",
85
+ "description": "Task delegation agents for pi-agent",
86
+ "keywords": ["omp-plugin", "agents"],
87
+ "omp": {
88
+ "install": [
89
+ { "src": "agents/task.md", "dest": "agent/agents/task.md" },
90
+ { "src": "tools/task/", "dest": "agent/tools/task/" }
91
+ ]
92
+ },
93
+ "files": ["agents", "tools"]
94
+ }
95
+ ```
96
+
97
+ ### Convention
98
+
99
+ - Include `omp-plugin` keyword for discoverability
100
+ - No namespace required (but `omp-` prefix is recommended)
101
+ - Use semver for versioning
102
+
103
+ ## Directory Structure
104
+
105
+ ### Global (default)
106
+
107
+ ```
108
+ ~/.pi/
109
+ ├── plugins/
110
+ │ ├── node_modules/ # npm-managed
111
+ │ │ ├── @oh-my-pi/subagents/
112
+ │ │ └── @oh-my-pi/metal-theme/
113
+ │ ├── package.json # Global plugin manifest
114
+ │ └── package-lock.json # Lock file
115
+ ├── agent/ # Symlink targets
116
+ │ ├── agents/
117
+ │ ├── tools/
118
+ │ ├── themes/
119
+ │ └── commands/
120
+ ```
121
+
122
+ ### Project-Local
123
+
124
+ ```
125
+ .pi/
126
+ ├── plugins.json # Project plugin config
127
+ ├── plugins-lock.json # Lock file
128
+ └── node_modules/ # Project-scoped installs
129
+ └── omp-my-plugin/
130
+ ```
131
+
132
+ Project plugins.json:
133
+ ```json
134
+ {
135
+ "plugins": {
136
+ "@oh-my-pi/subagents": "^2.0.0",
137
+ "@oh-my-pi/metal-theme": "^1.0.0"
138
+ }
139
+ }
140
+ ```
141
+
142
+ ## Install Flow
143
+
144
+ ```bash
145
+ omp install @oh-my-pi/subagents
146
+ ```
147
+
148
+ 1. Resolve version from npm registry
149
+ 2. Check for conflicts (same dest from different plugins)
150
+ 3. `npm install --prefix ~/.pi/plugins omp-subagents`
151
+ 4. Read package.json → omp.install
152
+ 5. For each {src, dest}: symlink to ~/.pi/{dest}
153
+ 6. Recursively process dependencies with omp field
154
+ 7. Update package.json
155
+
156
+ ### Conflict Detection
157
+
158
+ ```
159
+ ⚠ Conflict: omp-dark-theme and omp-nord-theme both install agent/themes/dark.json
160
+ Choose: [1] dark-theme [2] nord-theme [3] abort
161
+ ```
162
+
163
+ ## Creating Plugins
164
+
165
+ ```bash
166
+ omp create my-plugin
167
+ ```
168
+
169
+ Creates:
170
+ ```
171
+ omp-my-plugin/
172
+ ├── package.json
173
+ ├── README.md
174
+ ├── agents/
175
+ │ └── example.md
176
+ ├── tools/
177
+ ├── themes/
178
+ └── commands/
179
+ ```
180
+
181
+ ### Publishing
182
+
183
+ 1. Create a package with an `omp` field in package.json
184
+ 2. Add `omp-plugin` to keywords
185
+ 3. Publish to npm: `npm publish`
186
+ 4. Users install with: `omp install your-package-name`
187
+
188
+ ## Migration from v0.x
189
+
190
+ If you have plugins installed with the old manifest.json format:
191
+
192
+ ```bash
193
+ omp migrate
194
+ ```
195
+
196
+ This will:
197
+ 1. Convert manifest.json → package.json format
198
+ 2. Move plugins to node_modules structure
199
+ 3. Re-create symlinks
200
+ 4. Archive old manifest.json
201
+
202
+ ## Bundled Example Plugins
203
+
204
+ This package includes example plugins in the `plugins/` directory:
205
+
206
+ - **@oh-my-pi/subagents** - Task delegation system with specialized subagents
207
+ - **@oh-my-pi/metal-theme** - Metal theme for pi
208
+
209
+ Install bundled plugins:
210
+ ```bash
211
+ # After npm install -g @oh-my-pi/cli
212
+ omp install $(npm root -g)/@oh-my-pi/cli/plugins/subagents
213
+ omp install $(npm root -g)/@oh-my-pi/cli/plugins/metal-theme
214
+ ```
215
+
216
+ Or link for development:
217
+ ```bash
218
+ omp link ./plugins/subagents
219
+ omp link ./plugins/metal-theme
220
+ ```
221
+
222
+ ## License
223
+
224
+ MIT
package/biome.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "$schema": "https://biomejs.dev/schemas/2.3.5/schema.json",
3
+ "linter": {
4
+ "enabled": true,
5
+ "rules": {
6
+ "recommended": true,
7
+ "style": {
8
+ "noNonNullAssertion": "off",
9
+ "useConst": "error",
10
+ "useNodejsImportProtocol": "off"
11
+ },
12
+ "suspicious": {
13
+ "noExplicitAny": "off",
14
+ "noControlCharactersInRegex": "off",
15
+ "noEmptyInterface": "off"
16
+ }
17
+ }
18
+ },
19
+ "formatter": {
20
+ "enabled": true,
21
+ "formatWithErrors": false,
22
+ "indentStyle": "tab",
23
+ "indentWidth": 3,
24
+ "lineWidth": 120
25
+ },
26
+ "files": {
27
+ "includes": ["src/**/*.ts", "!**/node_modules/**/*"]
28
+ }
29
+ }