@oh-my-pi/pi-coding-agent 10.6.1 → 11.0.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.
- package/CHANGELOG.md +44 -0
- package/README.md +80 -79
- package/docs/compaction.md +182 -149
- package/docs/config-usage.md +141 -78
- package/docs/custom-tools.md +45 -16
- package/docs/extension-loading.md +56 -954
- package/docs/extensions.md +192 -51
- package/docs/hooks.md +109 -70
- package/docs/python-repl.md +52 -19
- package/docs/rpc.md +43 -19
- package/docs/sdk.md +270 -211
- package/docs/session-tree-plan.md +60 -417
- package/docs/session.md +104 -39
- package/docs/skills.md +59 -95
- package/docs/theme.md +139 -110
- package/docs/tree.md +42 -33
- package/docs/tui.md +226 -80
- package/package.json +8 -9
- package/src/capability/index.ts +3 -4
- package/src/cli/args.ts +4 -4
- package/src/cli/grep-cli.ts +1 -1
- package/src/commit/agentic/index.ts +4 -3
- package/src/commit/git/index.ts +2 -3
- package/src/commit/map-reduce/index.ts +2 -1
- package/src/config/prompt-templates.ts +2 -0
- package/src/config/settings-schema.ts +30 -7
- package/src/config/settings.ts +0 -14
- package/src/config.ts +2 -2
- package/src/discovery/agents.ts +36 -0
- package/src/discovery/index.ts +1 -0
- package/src/exa/mcp-client.ts +3 -3
- package/src/ipy/executor.ts +5 -7
- package/src/ipy/gateway-coordinator.ts +1 -1
- package/src/ipy/kernel.ts +20 -15
- package/src/ipy/prelude.py +1 -1
- package/src/ipy/runtime.ts +7 -6
- package/src/lsp/lspmux.ts +3 -3
- package/src/main.ts +6 -8
- package/src/mcp/tool-bridge.ts +19 -9
- package/src/modes/components/assistant-message.ts +2 -2
- package/src/modes/components/hook-editor.ts +4 -4
- package/src/modes/components/settings-defs.ts +37 -2
- package/src/modes/components/tool-execution.ts +7 -7
- package/src/modes/controllers/command-controller.ts +2 -2
- package/src/modes/controllers/event-controller.ts +4 -7
- package/src/modes/controllers/input-controller.ts +4 -4
- package/src/modes/controllers/selector-controller.ts +1 -0
- package/src/modes/interactive-mode.ts +3 -5
- package/src/modes/rpc/rpc-mode.ts +8 -9
- package/src/patch/index.ts +6 -6
- package/src/prompts/agents/explore.md +2 -2
- package/src/prompts/agents/frontmatter.md +5 -5
- package/src/prompts/agents/plan.md +3 -2
- package/src/prompts/agents/reviewer.md +1 -1
- package/src/prompts/system/system-prompt.md +1 -3
- package/src/sdk.ts +13 -9
- package/src/session/agent-session.ts +6 -4
- package/src/session/compaction/compaction.ts +3 -3
- package/src/session/session-manager.ts +8 -9
- package/src/ssh/connection-manager.ts +4 -4
- package/src/system-prompt.ts +2 -6
- package/src/task/agents.ts +1 -1
- package/src/task/executor.ts +31 -8
- package/src/task/index.ts +14 -35
- package/src/task/omp-command.ts +3 -1
- package/src/task/output-manager.ts +20 -6
- package/src/task/parallel.ts +3 -3
- package/src/task/render.ts +16 -2
- package/src/task/types.ts +13 -20
- package/src/task/worktree.ts +3 -3
- package/src/tools/ask.ts +3 -8
- package/src/tools/fetch.ts +2 -2
- package/src/tools/gemini-image.ts +5 -6
- package/src/tools/grep.ts +5 -5
- package/src/tools/index.ts +12 -5
- package/src/tools/read.ts +1 -1
- package/src/tools/todo-write.ts +2 -3
- package/src/utils/frontmatter.ts +1 -1
- package/src/utils/image-resize.ts +1 -1
- package/src/utils/timings.ts +3 -2
- package/src/web/scrapers/github.ts +2 -2
- package/src/web/scrapers/utils.ts +2 -3
- package/src/web/scrapers/youtube.ts +2 -3
- package/src/web/search/auth.ts +5 -6
- package/src/web/search/providers/anthropic.ts +3 -2
- package/src/utils/terminal-notify.ts +0 -37
package/docs/session.md
CHANGED
|
@@ -5,10 +5,12 @@ Sessions are stored as JSONL (JSON Lines) files. Each line is a JSON object with
|
|
|
5
5
|
## File Location
|
|
6
6
|
|
|
7
7
|
```
|
|
8
|
-
~/.omp/agent/sessions/--<
|
|
8
|
+
~/.omp/agent/sessions/--<cwd>--/<timestamp>_<sessionId>.jsonl
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Default base directory comes from `getAgentDir()` (overridable via `PI_CODING_AGENT_DIR`).
|
|
12
|
+
`<cwd>` is the working directory with the leading slash removed and `/`, `\`, `:` replaced by `-`.
|
|
13
|
+
`<timestamp>` is ISO-8601 with `:`/`.` replaced by `-`. `sessionId` is a snowflake hex string.
|
|
12
14
|
|
|
13
15
|
## Session Version
|
|
14
16
|
|
|
@@ -16,14 +18,16 @@ Sessions have a version field in the header:
|
|
|
16
18
|
|
|
17
19
|
- **Version 1**: Linear entry sequence (legacy, auto-migrated on load)
|
|
18
20
|
- **Version 2**: Tree structure with `id`/`parentId` linking
|
|
21
|
+
- **Version 3**: Renamed legacy `hookMessage` role to `custom`
|
|
19
22
|
|
|
20
|
-
Existing
|
|
23
|
+
Existing sessions are automatically migrated to the latest version when loaded.
|
|
21
24
|
|
|
22
25
|
## Type Definitions
|
|
23
26
|
|
|
24
|
-
- [`src/
|
|
25
|
-
- [`
|
|
26
|
-
- [`packages/
|
|
27
|
+
- [`src/session/session-manager.ts`](../src/session/session-manager.ts) - Session entry types and `SessionManager`
|
|
28
|
+
- [`src/session/messages.ts`](../src/session/messages.ts) - Custom message roles and LLM conversion
|
|
29
|
+
- [`packages/agent/src/types.ts`](../../agent/src/types.ts) - `AgentMessage`, `ThinkingLevel`
|
|
30
|
+
- [`packages/ai/src/types.ts`](../../ai/src/types.ts) - `Message`, content blocks, `Usage`, `ToolCall`
|
|
27
31
|
|
|
28
32
|
## Entry Base
|
|
29
33
|
|
|
@@ -32,7 +36,7 @@ All entries (except `SessionHeader`) extend `SessionEntryBase`:
|
|
|
32
36
|
```typescript
|
|
33
37
|
interface SessionEntryBase {
|
|
34
38
|
type: string;
|
|
35
|
-
id: string; // 8
|
|
39
|
+
id: string; // Short snowflake suffix (8 hex chars)
|
|
36
40
|
parentId: string | null; // Parent entry ID (null for first entry)
|
|
37
41
|
timestamp: string; // ISO timestamp
|
|
38
42
|
}
|
|
@@ -42,28 +46,39 @@ interface SessionEntryBase {
|
|
|
42
46
|
|
|
43
47
|
### SessionHeader
|
|
44
48
|
|
|
45
|
-
First line of the file. Metadata only, not part of the tree (no `id`/`parentId`).
|
|
49
|
+
First line of the file. Metadata only, not part of the tree (no `id`/`parentId`). `version` is absent in v1 sessions.
|
|
46
50
|
|
|
47
51
|
```json
|
|
48
|
-
{
|
|
52
|
+
{
|
|
53
|
+
"type": "session",
|
|
54
|
+
"version": 3,
|
|
55
|
+
"id": "a1b2c3d4e5f60001",
|
|
56
|
+
"timestamp": "2024-12-03T14:00:00.000Z",
|
|
57
|
+
"cwd": "/path/to/project",
|
|
58
|
+
"title": "Optional title"
|
|
59
|
+
}
|
|
49
60
|
```
|
|
50
61
|
|
|
51
|
-
For sessions with a parent (created via `/branch
|
|
62
|
+
For sessions with a parent (created via `/branch`, `newSession({ parentSession })`, or fork operations):
|
|
52
63
|
|
|
53
64
|
```json
|
|
54
65
|
{
|
|
55
66
|
"type": "session",
|
|
56
|
-
"version":
|
|
57
|
-
"id": "
|
|
67
|
+
"version": 3,
|
|
68
|
+
"id": "a1b2c3d4e5f60001",
|
|
58
69
|
"timestamp": "2024-12-03T14:00:00.000Z",
|
|
59
70
|
"cwd": "/path/to/project",
|
|
60
71
|
"parentSession": "/path/to/original/session.jsonl"
|
|
61
72
|
}
|
|
62
73
|
```
|
|
63
74
|
|
|
75
|
+
`parentSession` is an opaque string used for lineage tracking (typically a session file path).
|
|
76
|
+
|
|
64
77
|
### SessionMessageEntry
|
|
65
78
|
|
|
66
|
-
A message in the conversation. The `message` field contains an `AgentMessage
|
|
79
|
+
A message in the conversation. The `message` field contains an `AgentMessage`,
|
|
80
|
+
including base LLM messages plus coding-agent custom roles (bash/python execution,
|
|
81
|
+
custom/legacy `hookMessage` messages from v2 sessions, file mentions, etc.).
|
|
67
82
|
|
|
68
83
|
```json
|
|
69
84
|
{"type":"message","id":"a1b2c3d4","parentId":"prev1234","timestamp":"2024-12-03T14:00:01.000Z","message":{"role":"user","content":"Hello"}}
|
|
@@ -73,7 +88,7 @@ A message in the conversation. The `message` field contains an `AgentMessage`.
|
|
|
73
88
|
|
|
74
89
|
### ModelChangeEntry
|
|
75
90
|
|
|
76
|
-
Emitted when the user switches models mid-session.
|
|
91
|
+
Emitted when the user switches models mid-session. `model` is stored as `provider/modelId`.
|
|
77
92
|
|
|
78
93
|
```json
|
|
79
94
|
{
|
|
@@ -81,8 +96,8 @@ Emitted when the user switches models mid-session.
|
|
|
81
96
|
"id": "d4e5f6g7",
|
|
82
97
|
"parentId": "c3d4e5f6",
|
|
83
98
|
"timestamp": "2024-12-03T14:05:00.000Z",
|
|
84
|
-
"
|
|
85
|
-
"
|
|
99
|
+
"model": "openai/gpt-4o",
|
|
100
|
+
"role": "default"
|
|
86
101
|
}
|
|
87
102
|
```
|
|
88
103
|
|
|
@@ -100,6 +115,8 @@ Emitted when the user changes the thinking/reasoning level.
|
|
|
100
115
|
}
|
|
101
116
|
```
|
|
102
117
|
|
|
118
|
+
`thinkingLevel` matches `ThinkingLevel` from `packages/agent` (e.g., `off`, `minimal`, `low`, `medium`, `high`, `xhigh`).
|
|
119
|
+
|
|
103
120
|
### CompactionEntry
|
|
104
121
|
|
|
105
122
|
Created when context is compacted. Stores a summary of earlier messages.
|
|
@@ -111,19 +128,23 @@ Created when context is compacted. Stores a summary of earlier messages.
|
|
|
111
128
|
"parentId": "e5f6g7h8",
|
|
112
129
|
"timestamp": "2024-12-03T14:10:00.000Z",
|
|
113
130
|
"summary": "User discussed X, Y, Z...",
|
|
131
|
+
"shortSummary": "Quick recap...",
|
|
114
132
|
"firstKeptEntryId": "c3d4e5f6",
|
|
115
|
-
"tokensBefore": 50000
|
|
133
|
+
"tokensBefore": 50000,
|
|
134
|
+
"fromExtension": false
|
|
116
135
|
}
|
|
117
136
|
```
|
|
118
137
|
|
|
119
138
|
Optional fields:
|
|
120
139
|
|
|
121
|
-
- `details`: Compaction-implementation specific data (
|
|
122
|
-
- `
|
|
140
|
+
- `details`: Compaction-implementation specific data (extension data, version markers, etc.)
|
|
141
|
+
- `shortSummary`: Short-form summary for UI contexts
|
|
142
|
+
- `preserveData`: Hook/extension data to persist across compaction
|
|
143
|
+
- `fromExtension`: `true` if generated by an extension, `false`/`undefined` if pi-generated
|
|
123
144
|
|
|
124
145
|
### BranchSummaryEntry
|
|
125
146
|
|
|
126
|
-
Created when switching branches
|
|
147
|
+
Created when switching branches with an LLM-generated summary of the abandoned path. Captures context from the previous branch.
|
|
127
148
|
|
|
128
149
|
```json
|
|
129
150
|
{
|
|
@@ -136,14 +157,16 @@ Created when switching branches via `/tree` with an LLM generated summary of the
|
|
|
136
157
|
}
|
|
137
158
|
```
|
|
138
159
|
|
|
160
|
+
`fromId` is the branch point entry id; when branching from the root it is `"root"`.
|
|
161
|
+
|
|
139
162
|
Optional fields:
|
|
140
163
|
|
|
141
|
-
- `details`:
|
|
142
|
-
- `
|
|
164
|
+
- `details`: Extension-specific data (not sent to LLM)
|
|
165
|
+
- `fromExtension`: `true` if generated by an extension
|
|
143
166
|
|
|
144
167
|
### CustomEntry
|
|
145
168
|
|
|
146
|
-
|
|
169
|
+
Extension state persistence. Does NOT participate in LLM context.
|
|
147
170
|
|
|
148
171
|
```json
|
|
149
172
|
{
|
|
@@ -151,16 +174,16 @@ Hook state persistence. Does NOT participate in LLM context.
|
|
|
151
174
|
"id": "h8i9j0k1",
|
|
152
175
|
"parentId": "g7h8i9j0",
|
|
153
176
|
"timestamp": "2024-12-03T14:20:00.000Z",
|
|
154
|
-
"customType": "my-
|
|
177
|
+
"customType": "my-extension",
|
|
155
178
|
"data": { "count": 42 }
|
|
156
179
|
}
|
|
157
180
|
```
|
|
158
181
|
|
|
159
|
-
Use `customType` to identify your
|
|
182
|
+
Use `customType` to identify your extension's entries on reload.
|
|
160
183
|
|
|
161
184
|
### CustomMessageEntry
|
|
162
185
|
|
|
163
|
-
|
|
186
|
+
Extension-injected messages that DO participate in LLM context.
|
|
164
187
|
|
|
165
188
|
```json
|
|
166
189
|
{
|
|
@@ -168,7 +191,7 @@ Hook-injected messages that DO participate in LLM context.
|
|
|
168
191
|
"id": "i9j0k1l2",
|
|
169
192
|
"parentId": "h8i9j0k1",
|
|
170
193
|
"timestamp": "2024-12-03T14:25:00.000Z",
|
|
171
|
-
"customType": "my-
|
|
194
|
+
"customType": "my-extension",
|
|
172
195
|
"content": "Injected context...",
|
|
173
196
|
"display": true
|
|
174
197
|
}
|
|
@@ -177,8 +200,8 @@ Hook-injected messages that DO participate in LLM context.
|
|
|
177
200
|
Fields:
|
|
178
201
|
|
|
179
202
|
- `content`: String or `(TextContent | ImageContent)[]` (same as UserMessage)
|
|
180
|
-
- `display`: `true` = show in TUI with
|
|
181
|
-
- `details`: Optional
|
|
203
|
+
- `display`: `true` = show in TUI with distinct styling, `false` = hidden
|
|
204
|
+
- `details`: Optional extension-specific metadata (not sent to LLM)
|
|
182
205
|
|
|
183
206
|
### LabelEntry
|
|
184
207
|
|
|
@@ -197,6 +220,37 @@ User-defined bookmark/marker on an entry.
|
|
|
197
220
|
|
|
198
221
|
Set `label` to `undefined` to clear a label.
|
|
199
222
|
|
|
223
|
+
### TtsrInjectionEntry
|
|
224
|
+
|
|
225
|
+
Tracks which time-traveling stream rules were injected during the session.
|
|
226
|
+
|
|
227
|
+
```json
|
|
228
|
+
{
|
|
229
|
+
"type": "ttsr_injection",
|
|
230
|
+
"id": "k1l2m3n4",
|
|
231
|
+
"parentId": "j0k1l2m3",
|
|
232
|
+
"timestamp": "2024-12-03T14:31:00.000Z",
|
|
233
|
+
"injectedRules": ["rule-a", "rule-b"]
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### SessionInitEntry
|
|
238
|
+
|
|
239
|
+
Captures initial context for subagent sessions (debugging/replay). Not used in LLM context building.
|
|
240
|
+
|
|
241
|
+
```json
|
|
242
|
+
{
|
|
243
|
+
"type": "session_init",
|
|
244
|
+
"id": "l2m3n4o5",
|
|
245
|
+
"parentId": "k1l2m3n4",
|
|
246
|
+
"timestamp": "2024-12-03T14:32:00.000Z",
|
|
247
|
+
"systemPrompt": "...",
|
|
248
|
+
"task": "Initial task...",
|
|
249
|
+
"tools": ["bash", "read"],
|
|
250
|
+
"outputSchema": { "type": "object" }
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
200
254
|
## Tree Structure
|
|
201
255
|
|
|
202
256
|
Entries form a tree:
|
|
@@ -217,13 +271,15 @@ Entries form a tree:
|
|
|
217
271
|
`buildSessionContext()` walks from the current leaf to the root, producing the message list for the LLM:
|
|
218
272
|
|
|
219
273
|
1. Collects all entries on the path
|
|
220
|
-
2. Extracts current model
|
|
274
|
+
2. Extracts current model map, thinking level, and injected TTSR rules
|
|
221
275
|
3. If a `CompactionEntry` is on the path:
|
|
222
276
|
- Emits the summary first
|
|
223
277
|
- Then messages from `firstKeptEntryId` to compaction
|
|
224
278
|
- Then messages after compaction
|
|
225
279
|
4. Converts `BranchSummaryEntry` and `CustomMessageEntry` to appropriate message formats
|
|
226
280
|
|
|
281
|
+
Return value is a `SessionContext` containing `messages`, `models`, `thinkingLevel`, and `injectedTtsrRules`.
|
|
282
|
+
|
|
227
283
|
## Parsing Example
|
|
228
284
|
|
|
229
285
|
```typescript
|
|
@@ -231,7 +287,6 @@ const text = await Bun.file("session.jsonl").text();
|
|
|
231
287
|
const entries = Bun.JSONL.parse(text);
|
|
232
288
|
|
|
233
289
|
for (const entry of entries) {
|
|
234
|
-
|
|
235
290
|
switch (entry.type) {
|
|
236
291
|
case "session":
|
|
237
292
|
console.log(`Session v${entry.version ?? 1}: ${entry.id}`);
|
|
@@ -249,13 +304,19 @@ for (const entry of entries) {
|
|
|
249
304
|
console.log(`[${entry.id}] Custom (${entry.customType}): ${JSON.stringify(entry.data)}`);
|
|
250
305
|
break;
|
|
251
306
|
case "custom_message":
|
|
252
|
-
console.log(`[${entry.id}]
|
|
307
|
+
console.log(`[${entry.id}] Custom message (${entry.customType}): ${entry.content}`);
|
|
308
|
+
break;
|
|
309
|
+
case "ttsr_injection":
|
|
310
|
+
console.log(`[${entry.id}] TTSR rules: ${entry.injectedRules.join(", ")}`);
|
|
311
|
+
break;
|
|
312
|
+
case "session_init":
|
|
313
|
+
console.log(`[${entry.id}] Init: ${entry.tools.join(", ")}`);
|
|
253
314
|
break;
|
|
254
315
|
case "label":
|
|
255
316
|
console.log(`[${entry.id}] Label "${entry.label}" on ${entry.targetId}`);
|
|
256
317
|
break;
|
|
257
318
|
case "model_change":
|
|
258
|
-
console.log(`[${entry.id}] Model: ${entry.
|
|
319
|
+
console.log(`[${entry.id}] Model: ${entry.model} (${entry.role ?? "default"})`);
|
|
259
320
|
break;
|
|
260
321
|
case "thinking_level_change":
|
|
261
322
|
console.log(`[${entry.id}] Thinking: ${entry.thinkingLevel}`);
|
|
@@ -279,22 +340,26 @@ Key methods for working with sessions programmatically:
|
|
|
279
340
|
|
|
280
341
|
- `appendMessage(message)` - Add message
|
|
281
342
|
- `appendThinkingLevelChange(level)` - Record thinking change
|
|
282
|
-
- `appendModelChange(
|
|
283
|
-
- `
|
|
284
|
-
- `
|
|
285
|
-
- `
|
|
343
|
+
- `appendModelChange(model, role?)` - Record model change (`model` = `provider/modelId`)
|
|
344
|
+
- `appendSessionInit(init)` - Record initial subagent context
|
|
345
|
+
- `appendCompaction(summary, shortSummary, firstKeptEntryId, tokensBefore, details?, fromExtension?, preserveData?)`
|
|
346
|
+
- `appendCustomEntry(customType, data?)` - Extension state (not in context)
|
|
347
|
+
- `appendCustomMessageEntry(customType, content, display, details?)` - Extension message (in context)
|
|
348
|
+
- `appendTtsrInjection(ruleNames)` - Record injected TTSR rules
|
|
286
349
|
- `appendLabelChange(targetId, label)` - Set/clear label
|
|
287
350
|
|
|
288
351
|
### Tree Navigation
|
|
289
352
|
|
|
290
353
|
- `getLeafId()` - Current position
|
|
354
|
+
- `getLeafEntry()` - Current leaf entry
|
|
291
355
|
- `getEntry(id)` - Get entry by ID
|
|
292
|
-
- `
|
|
356
|
+
- `getBranch(fromId?)` - Walk from entry to root
|
|
293
357
|
- `getTree()` - Get full tree structure
|
|
294
358
|
- `getChildren(parentId)` - Get direct children
|
|
295
359
|
- `getLabel(id)` - Get label for entry
|
|
296
360
|
- `branch(entryId)` - Move leaf to earlier entry
|
|
297
|
-
- `branchWithSummary(entryId, summary, details?,
|
|
361
|
+
- `branchWithSummary(entryId | null, summary, details?, fromExtension?)` - Branch with context summary
|
|
362
|
+
- `resetLeaf()` - Move leaf to before first entry
|
|
298
363
|
|
|
299
364
|
### Context
|
|
300
365
|
|
package/docs/skills.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Skills are self-contained capability packages that the agent loads on-demand. A skill provides specialized workflows, setup instructions, helper scripts, and reference documentation for specific tasks.
|
|
6
6
|
|
|
7
|
-
OMP
|
|
7
|
+
OMP follows the [Agent Skills](https://agentskills.io/specification) SKILL.md format (YAML frontmatter + markdown body) and exposes skills via `skill://` URLs.
|
|
8
8
|
|
|
9
9
|
**Example use cases:**
|
|
10
10
|
- Web search and content extraction (Brave Search API)
|
|
@@ -87,99 +87,78 @@ cd /path/to/skill && npm install
|
|
|
87
87
|
|
|
88
88
|
### Frontmatter Fields
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
| Field | Required | Notes |
|
|
91
|
+
|-------|----------|-------|
|
|
92
|
+
| `name` | No | Defaults to the skill directory name. Use lowercase + hyphens for compatibility. |
|
|
93
|
+
| `description` | Yes (OMP/custom), recommended everywhere | Used for skill matching and shown in the system prompt. |
|
|
91
94
|
|
|
92
|
-
|
|
93
|
-
|-------|----------|-------------|
|
|
94
|
-
| `name` | Yes | Max 64 chars. Lowercase a-z, 0-9, hyphens only. Must match parent directory name. |
|
|
95
|
-
| `description` | Yes | Max 1024 chars. What the skill does and when to use it. |
|
|
96
|
-
| `license` | No | License name or reference to bundled license file. |
|
|
97
|
-
| `compatibility` | No | Max 500 chars. Environment requirements (system packages, network access, etc.). |
|
|
98
|
-
| `metadata` | No | Arbitrary key-value mapping for additional metadata. |
|
|
99
|
-
| `allowed-tools` | No | Space-delimited list of pre-approved tools (experimental). |
|
|
95
|
+
OMP ignores additional frontmatter fields, but other tooling may use them.
|
|
100
96
|
|
|
101
|
-
####
|
|
97
|
+
#### Naming Guidance
|
|
102
98
|
|
|
103
|
-
|
|
104
|
-
- Be 1-64 characters
|
|
105
|
-
- Contain only lowercase letters (a-z), numbers (0-9), and hyphens
|
|
106
|
-
- Not start or end with a hyphen
|
|
107
|
-
- Not contain consecutive hyphens (--)
|
|
108
|
-
- Match the parent directory name exactly
|
|
109
|
-
|
|
110
|
-
Valid: `pdf-processing`, `data-analysis`, `code-review`
|
|
111
|
-
Invalid: `PDF-Processing`, `-pdf`, `pdf--processing`
|
|
112
|
-
|
|
113
|
-
#### Description Best Practices
|
|
114
|
-
|
|
115
|
-
The `description` is critical. It determines when the agent loads the skill. Be specific about both what it does and when to use it.
|
|
116
|
-
|
|
117
|
-
Good:
|
|
118
|
-
```yaml
|
|
119
|
-
description: Extracts text and tables from PDF files, fills PDF forms, and merges multiple PDFs. Use when working with PDF documents or when the user mentions PDFs, forms, or document extraction.
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
Poor:
|
|
123
|
-
```yaml
|
|
124
|
-
description: Helps with PDFs.
|
|
125
|
-
```
|
|
99
|
+
OMP does not enforce naming rules, but skill names must match exactly for `skill://<name>` and `/skill:<name>` lookups. For cross-tool compatibility, keep names lowercase, hyphenated, and aligned with the directory name.
|
|
126
100
|
|
|
127
101
|
### File References
|
|
128
102
|
|
|
129
|
-
Use
|
|
103
|
+
Use `skill://` URLs to reference files inside a skill directory:
|
|
130
104
|
|
|
131
105
|
```markdown
|
|
132
|
-
|
|
106
|
+
Read the full skill:
|
|
107
|
+
\`\`\`
|
|
108
|
+
skill://my-skill
|
|
109
|
+
\`\`\`
|
|
133
110
|
|
|
134
|
-
|
|
135
|
-
\`\`\`
|
|
136
|
-
|
|
111
|
+
Read a reference file:
|
|
112
|
+
\`\`\`
|
|
113
|
+
skill://my-skill/references/api-reference.md
|
|
137
114
|
\`\`\`
|
|
138
115
|
```
|
|
139
116
|
|
|
140
117
|
## Skill Locations
|
|
141
118
|
|
|
142
|
-
Skills are discovered from these
|
|
119
|
+
Skills are discovered from these sources (first match wins on name collisions):
|
|
120
|
+
|
|
121
|
+
- OMP user: `~/.omp/agent/skills/<skill>/SKILL.md` (legacy alias: `~/.pi/agent/skills/...`)
|
|
122
|
+
- OMP project: `<cwd>/.omp/skills/<skill>/SKILL.md` (legacy alias: `<cwd>/.pi/skills/...`)
|
|
123
|
+
- Claude Code: `~/.claude/skills/<skill>/SKILL.md` and `<cwd>/.claude/skills/<skill>/SKILL.md`
|
|
124
|
+
- Agents standard: `~/.agents/skills/<skill>/SKILL.md`
|
|
125
|
+
- Codex CLI: `~/.codex/skills/<skill>/SKILL.md` and `<cwd>/.codex/skills/<skill>/SKILL.md`
|
|
126
|
+
- Custom directories from `skills.customDirectories` (scanned recursively)
|
|
143
127
|
|
|
144
|
-
|
|
145
|
-
2. `~/.claude/skills/*/SKILL.md` (Claude Code user, one level)
|
|
146
|
-
3. `<cwd>/.claude/skills/*/SKILL.md` (Claude Code project, one level)
|
|
147
|
-
4. `~/.omp/agent/skills/**/SKILL.md` (OMP user, recursive)
|
|
148
|
-
5. `<cwd>/.omp/skills/**/SKILL.md` (OMP project, recursive)
|
|
128
|
+
Discovery skips hidden directories and `node_modules`, and respects `.gitignore`, `.ignore`, and `.fdignore` rules.
|
|
149
129
|
|
|
150
130
|
## Configuration
|
|
151
131
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
}
|
|
132
|
+
Global settings live in `~/.omp/agent/config.yml` (migrated from legacy `settings.json`). Project overrides live in `<cwd>/.omp/settings.json` or `<cwd>/.pi/settings.json`.
|
|
133
|
+
|
|
134
|
+
```yaml
|
|
135
|
+
skills:
|
|
136
|
+
enabled: true
|
|
137
|
+
enableSkillCommands: true
|
|
138
|
+
enableCodexUser: true
|
|
139
|
+
enableClaudeUser: true
|
|
140
|
+
enableClaudeProject: true
|
|
141
|
+
enablePiUser: true
|
|
142
|
+
enablePiProject: true
|
|
143
|
+
customDirectories: []
|
|
144
|
+
ignoredSkills: []
|
|
145
|
+
includeSkills: []
|
|
168
146
|
```
|
|
169
147
|
|
|
170
148
|
| Setting | Default | Description |
|
|
171
149
|
|---------|---------|-------------|
|
|
172
150
|
| `enabled` | `true` | Master toggle for all skills |
|
|
151
|
+
| `enableSkillCommands` | `true` | Register `/skill:<name>` commands in interactive mode |
|
|
173
152
|
| `enableCodexUser` | `true` | Load from `~/.codex/skills/` |
|
|
174
153
|
| `enableClaudeUser` | `true` | Load from `~/.claude/skills/` |
|
|
175
154
|
| `enableClaudeProject` | `true` | Load from `<cwd>/.claude/skills/` |
|
|
176
|
-
| `
|
|
177
|
-
| `
|
|
178
|
-
| `customDirectories` | `[]` | Additional directories to scan (
|
|
179
|
-
| `ignoredSkills` | `[]` | Glob patterns to exclude (e.g., `
|
|
180
|
-
| `includeSkills` | `[]` | Glob patterns to include (empty = all
|
|
155
|
+
| `enablePiUser` | `true` | Load from `~/.omp/agent/skills/` (or `~/.pi/agent/skills/`) |
|
|
156
|
+
| `enablePiProject` | `true` | Load from `<cwd>/.omp/skills/` (or `<cwd>/.pi/skills/`) |
|
|
157
|
+
| `customDirectories` | `[]` | Additional directories to scan recursively (use absolute paths) |
|
|
158
|
+
| `ignoredSkills` | `[]` | Glob patterns to exclude (e.g., `"deprecated-*"`) |
|
|
159
|
+
| `includeSkills` | `[]` | Glob patterns to include (empty = all) |
|
|
181
160
|
|
|
182
|
-
**Note:** `ignoredSkills` takes precedence over both `includeSkills`
|
|
161
|
+
**Note:** `ignoredSkills` takes precedence over both `includeSkills` and the `--skills` CLI flag.
|
|
183
162
|
|
|
184
163
|
### CLI Filtering
|
|
185
164
|
|
|
@@ -200,25 +179,19 @@ This overrides the `includeSkills` setting for the current session.
|
|
|
200
179
|
|
|
201
180
|
## How Skills Work
|
|
202
181
|
|
|
203
|
-
1. At startup, omp scans skill locations and
|
|
204
|
-
2.
|
|
205
|
-
3. When a task matches, the agent
|
|
206
|
-
4.
|
|
182
|
+
1. At startup, omp scans enabled skill locations and filters them by settings and CLI flags.
|
|
183
|
+
2. If the `read` tool is available, skill names + descriptions are injected into the system prompt as XML.
|
|
184
|
+
3. When a task matches a skill, the agent loads it with `read skill://<name>` or `skill://<name>/<path>`.
|
|
185
|
+
4. When skills are preloaded (e.g., Task tool with explicit skills), their full contents are inlined under `<preloaded_skills>` and no `read` call is needed.
|
|
207
186
|
|
|
208
|
-
This is progressive disclosure: only descriptions are always in context, full instructions load on-demand.
|
|
187
|
+
This is progressive disclosure: only descriptions are always in context, full instructions load on-demand unless explicitly preloaded.
|
|
209
188
|
|
|
210
|
-
##
|
|
189
|
+
## Warnings
|
|
211
190
|
|
|
212
|
-
OMP
|
|
191
|
+
OMP emits warnings when:
|
|
213
192
|
|
|
214
|
-
-
|
|
215
|
-
-
|
|
216
|
-
- Name contains invalid characters
|
|
217
|
-
- Name starts/ends with hyphen or has consecutive hyphens
|
|
218
|
-
- Description missing or exceeds 1024 characters
|
|
219
|
-
- Unknown frontmatter fields
|
|
220
|
-
|
|
221
|
-
Name collisions (same name from different locations) warn and keep the first skill found.
|
|
193
|
+
- A skill directory or file cannot be read
|
|
194
|
+
- Two skills share the same name (the first loaded wins; later ones are skipped)
|
|
222
195
|
|
|
223
196
|
## Example: Web Search Skill
|
|
224
197
|
|
|
@@ -258,12 +231,6 @@ cd /path/to/brave-search && npm install
|
|
|
258
231
|
\`\`\`
|
|
259
232
|
```
|
|
260
233
|
|
|
261
|
-
## Compatibility
|
|
262
|
-
|
|
263
|
-
**Claude Code**: OMP reads skills from `~/.claude/skills/*/SKILL.md`. The `allowed-tools` and `model` frontmatter fields are ignored.
|
|
264
|
-
|
|
265
|
-
**Codex CLI**: OMP reads skills from `~/.codex/skills/` recursively. Hidden files/directories and symlinks are skipped.
|
|
266
|
-
|
|
267
234
|
## Skill Repositories
|
|
268
235
|
|
|
269
236
|
For inspiration and ready-to-use skills:
|
|
@@ -278,13 +245,10 @@ CLI:
|
|
|
278
245
|
omp --no-skills
|
|
279
246
|
```
|
|
280
247
|
|
|
281
|
-
Settings
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
"enabled": false
|
|
286
|
-
}
|
|
287
|
-
}
|
|
248
|
+
Settings:
|
|
249
|
+
```yaml
|
|
250
|
+
skills:
|
|
251
|
+
enabled: false
|
|
288
252
|
```
|
|
289
253
|
|
|
290
254
|
Use the granular `enable*` flags to disable individual sources (e.g., `enableClaudeUser: false` to skip `~/.claude/skills`).
|