@owlmeans/agent-skills 0.1.14 → 0.1.16-rc.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/README.md +24 -0
- package/agent-meta/instructions/agent-memory.instructions.md +4 -0
- package/agent-meta/instructions/memory-promotion.instructions.md +53 -9
- package/agent-meta/instructions/memory-recompact.instructions.md +2 -1
- package/agent-meta/instructions/self-education.instructions.md +18 -2
- package/agent-meta/instructions/skill-authoring.instructions.md +5 -1
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/agent-memory/SKILL.md +4 -0
- package/agent-meta/skills/memory-promotion/SKILL.md +53 -9
- package/agent-meta/skills/memory-recompact/SKILL.md +2 -1
- package/agent-meta/skills/self-education/SKILL.md +17 -2
- package/agent-meta/skills/skill-authoring/SKILL.md +6 -2
- package/build/llm/index.d.ts +13 -0
- package/build/llm/index.d.ts.map +1 -0
- package/build/llm/index.js +13 -0
- package/build/llm/index.js.map +1 -0
- package/build/llm/manifest.d.ts +29 -0
- package/build/llm/manifest.d.ts.map +1 -0
- package/build/llm/manifest.js +58 -0
- package/build/llm/manifest.js.map +1 -0
- package/build/llm/plugin.d.ts +17 -0
- package/build/llm/plugin.d.ts.map +1 -0
- package/build/llm/plugin.js +115 -0
- package/build/llm/plugin.js.map +1 -0
- package/build/llm/resolve.d.ts +4 -0
- package/build/llm/resolve.d.ts.map +1 -0
- package/build/llm/resolve.js +145 -0
- package/build/llm/resolve.js.map +1 -0
- package/build/llm/types.d.ts +59 -0
- package/build/llm/types.d.ts.map +1 -0
- package/build/llm/types.js +3 -0
- package/build/llm/types.js.map +1 -0
- package/package.json +23 -1
- package/src/llm/index.ts +13 -0
- package/src/llm/manifest.ts +74 -0
- package/src/llm/plugin.ts +133 -0
- package/src/llm/resolve.ts +180 -0
- package/src/llm/types.ts +71 -0
- package/tests/llm-plugin.test.ts +158 -0
package/README.md
CHANGED
|
@@ -90,3 +90,27 @@ The embedded files are version-matched to this package release. Do not edit them
|
|
|
90
90
|
directly — they are regenerated on each publish. To contribute guidance edits,
|
|
91
91
|
open a PR against the source monorepo.
|
|
92
92
|
<!-- owlmeans:agent-guidance:end -->
|
|
93
|
+
|
|
94
|
+
## Package skills in a prompt (`@owlmeans/agent-skills/llm`)
|
|
95
|
+
|
|
96
|
+
`owlmeansPackagesPlugin(options)` notices which `@owlmeans/*` packages a request mentions
|
|
97
|
+
and loads their published skills into the `Packages` block. Everything a package documents
|
|
98
|
+
is loaded — there is no relevance filtering, by design.
|
|
99
|
+
|
|
100
|
+
Resolution order per package: the host's `LlmFileProvider` (the only path that sees a
|
|
101
|
+
sandbox or remote workspace) → an installed copy under `node_modules` → the canonical
|
|
102
|
+
repository over HTTPS. Every failure is a miss, never a throw. Results, including misses,
|
|
103
|
+
are cached per plugin instance.
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
ctx.prompts().use(owlmeansPackagesPlugin({
|
|
107
|
+
files: () => ctx.files(), // tried first
|
|
108
|
+
exclude: ['@owlmeans/llm'], // already covered by the static Skills block
|
|
109
|
+
fetch: false, // air-gapped: skip the repository fallback
|
|
110
|
+
}))
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The manifest deliberately carries no git ref — version-matching comes from shipping the
|
|
114
|
+
copy inside the tarball, so for a package that is NOT installed the ref is a plugin option
|
|
115
|
+
(`ref`, default `main`).
|
|
116
|
+
|
|
@@ -137,3 +137,7 @@ Fact-shaped ("what is true") stays here. Procedure-shaped ("to do X, do Y") beco
|
|
|
137
137
|
instruction/skill — follow `.github/instructions/memory-promotion.instructions.md` where present,
|
|
138
138
|
otherwise the skill-authoring guidance. Repeated use of a node to *perform* tasks, and over-cap
|
|
139
139
|
nodes full of steps, are promotion triggers.
|
|
140
|
+
|
|
141
|
+
Promotion is a **rewrite, never a move**: never paste node text into an instruction. "Record the
|
|
142
|
+
rule, not the story" and the size caps above bind instruction bodies at least as tightly as they
|
|
143
|
+
bind nodes (memory-promotion instruction → Distillation).
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "Promote procedure-shaped or hot memory into skills/instructions — triggers (procedure test, promote? flags, over-cap), update-vs-create rule, post-promotion pointer state. Apply when converting memory content into guidance files or when a promote? flag appears in a memory node."
|
|
2
|
+
description: "Promote procedure-shaped or hot memory into skills/instructions — triggers (procedure test, promote? flags, over-cap), the mandatory distillation rewrite, update-vs-create rule, post-promotion pointer state. Apply when converting memory content into guidance files or when a promote? flag appears in a memory node."
|
|
3
3
|
applyTo: "**/.agents/memory/**, **/.claude/skills/**, **/.github/instructions/**"
|
|
4
4
|
scope: general
|
|
5
5
|
---
|
|
@@ -11,6 +11,9 @@ Memory holds **facts**; **procedures** belong in instructions/skills, where they
|
|
|
11
11
|
stop consuming memory-read cycles. Promotion is how the store stays compact and the harness
|
|
12
12
|
teaches itself.
|
|
13
13
|
|
|
14
|
+
Promotion is a **rewrite, never a move**. Memory text pasted into an instruction is the single
|
|
15
|
+
most common way this harness degrades — see Distillation below.
|
|
16
|
+
|
|
14
17
|
## Triggers
|
|
15
18
|
|
|
16
19
|
- **Procedure shape**: the content answers *how to do X* — ordered steps, imperative verbs,
|
|
@@ -27,7 +30,44 @@ teaches itself.
|
|
|
27
30
|
|
|
28
31
|
Procedure-shaped answers *how to do X*: ordered steps, imperative verbs, commands, action tables.
|
|
29
32
|
Fact-shaped answers *what is true*: declarative structure, invariants, symptom→cause pairs.
|
|
30
|
-
Mixed entries split — the fact stays in the node, the "then do"
|
|
33
|
+
Mixed entries split — the fact stays in the node, the "then do" is distilled into a rule in the
|
|
34
|
+
instruction.
|
|
35
|
+
|
|
36
|
+
## Distillation (mandatory)
|
|
37
|
+
|
|
38
|
+
**Never paste memory text into an instruction.** A promoted line leaves the node as prose about a
|
|
39
|
+
past occurrence and enters the instruction as **one general rule**: *when this applies → do this
|
|
40
|
+
→ or this breaks*, stated so it holds next time rather than describing last time.
|
|
41
|
+
|
|
42
|
+
| Strip | Keep |
|
|
43
|
+
|---|---|
|
|
44
|
+
| dates, phase/status markers, "COMPLETE", "landed" | the condition that makes the rule apply |
|
|
45
|
+
| versions, image tags, SHAs — unless the rule turns on the version | the step to take |
|
|
46
|
+
| "was X, now Y", "the former X was removed" | the failure it prevents |
|
|
47
|
+
| who did it, attempt sequences, incident narrative | the recognition fingerprint (symptom) |
|
|
48
|
+
| point-in-time inventories, counts, snapshots | |
|
|
49
|
+
|
|
50
|
+
Before (memory): "2026-07-05 — the control-board git card was removed; the dialog now owns all
|
|
51
|
+
git actions."
|
|
52
|
+
After (rule): "Git actions live in the git dialog; the control board holds none."
|
|
53
|
+
|
|
54
|
+
Before (memory): "Phase 3 (COMPLETE, 2026-06-13): added the init-container build, publisher
|
|
55
|
+
`src/build.ts`, kephemeral v0.1.5."
|
|
56
|
+
After (rule): "Production images build in an init container driven by `publisher/src/build.ts`."
|
|
57
|
+
|
|
58
|
+
**If the rule cannot be stated without saying when it happened, it is not promotable** — it stays
|
|
59
|
+
a memory fact, or it is dropped.
|
|
60
|
+
|
|
61
|
+
### Budget
|
|
62
|
+
|
|
63
|
+
A promotion normally adds **1–5 lines** to an existing instruction, and a single rule is ≤ 3 lines.
|
|
64
|
+
A whole new section, or more text added than the node lost, means the content was moved rather than
|
|
65
|
+
distilled — redo it.
|
|
66
|
+
|
|
67
|
+
An instruction may legitimately run long when it maps a large subsystem, so length alone is not the
|
|
68
|
+
test: **every line must be a rule, a contract, or a pointer.** A section that reads as the story of
|
|
69
|
+
how the code got there is pollution at any length. "Record the rule, not the story"
|
|
70
|
+
(`agent-memory.instructions.md`) binds instruction bodies at least as tightly as it binds nodes.
|
|
31
71
|
|
|
32
72
|
## Flagging (how content earns promotion)
|
|
33
73
|
|
|
@@ -45,18 +85,22 @@ even partially; keep both twins in sync. Create a NEW pair only when:
|
|
|
45
85
|
re-encountered ` → promote?` flag);
|
|
46
86
|
- (c) an external technology required internet docs and has no governing instruction.
|
|
47
87
|
|
|
48
|
-
New instructions multiply lookup cost — compactness applies to the guidance population
|
|
88
|
+
New instructions multiply lookup cost — compactness applies to the guidance population *and* to
|
|
89
|
+
each instruction's body.
|
|
49
90
|
|
|
50
91
|
## Procedure
|
|
51
92
|
|
|
52
93
|
1. Collect the flagged / procedure-shaped memory lines.
|
|
53
|
-
2.
|
|
94
|
+
2. **Distill** each into a general rule (section above). Not optional — skipping it is the
|
|
95
|
+
failure mode this instruction exists to prevent.
|
|
96
|
+
3. Author or extend the `.github/instructions/<name>.instructions.md` and its
|
|
54
97
|
`.claude/skills/<name>/SKILL.md` twin, following the repo's skill-authoring / create-skill
|
|
55
|
-
conventions.
|
|
56
|
-
|
|
57
|
-
4.
|
|
58
|
-
5.
|
|
59
|
-
6.
|
|
98
|
+
conventions. Where an existing rule already covers the ground, **rewrite that rule in place**;
|
|
99
|
+
append only when nothing covers it.
|
|
100
|
+
4. Shrink the node: delete the source lines; leave one pointer line (format below).
|
|
101
|
+
5. Remove the ` → promote?` flags.
|
|
102
|
+
6. Update the node's index hook if its main value moved; bump `updated:`.
|
|
103
|
+
7. Report per the Reporting rule.
|
|
60
104
|
|
|
61
105
|
## Post-promotion state
|
|
62
106
|
|
|
@@ -40,7 +40,8 @@ For each old file or section:
|
|
|
40
40
|
3. On conflict between records, the version consistent with **current code** wins — check the
|
|
41
41
|
code, don't average.
|
|
42
42
|
4. Procedure-shaped survivors do not enter nodes — route them to
|
|
43
|
-
`.github/instructions/memory-promotion.instructions.md`.
|
|
43
|
+
`.github/instructions/memory-promotion.instructions.md`. Routing means distilling them into
|
|
44
|
+
general rules, never handing the text over verbatim.
|
|
44
45
|
|
|
45
46
|
## Legacy-store merge (migration)
|
|
46
47
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "Mandatory post-development skill/instruction updating — after adding or changing functionality,
|
|
2
|
+
description: "Mandatory post-development skill/instruction updating — after adding or changing functionality, rewrite touched project guidance as current rules (never as change notes), note external-doc findings in the governing instruction, or add instructions for new subsystems/technologies; required before the completion report when development started from an agreed plan. Apply when editing skills or instruction files after development."
|
|
3
3
|
applyTo: "**/.claude/skills/**, **/.github/instructions/**"
|
|
4
4
|
scope: general
|
|
5
5
|
---
|
|
@@ -28,7 +28,23 @@ For each area the work touched:
|
|
|
28
28
|
1. Which existing instruction/skill covers it? (Check `.github/instructions/` +
|
|
29
29
|
`.claude/skills/`.)
|
|
30
30
|
2. Do its commands, paths, APIs, and behavior claims still hold after the change?
|
|
31
|
-
3. Fix in place —
|
|
31
|
+
3. Fix in place — rewrite the affected lines so they describe current behavior; never append a
|
|
32
|
+
note about what this change did. Keep the instruction and its skill twin in sync.
|
|
33
|
+
|
|
34
|
+
## Shape of an update
|
|
35
|
+
|
|
36
|
+
Instructions and skills state **current rules, not what changed**. Every edit is a rewrite in
|
|
37
|
+
place of the affected lines.
|
|
38
|
+
|
|
39
|
+
Never write into an instruction or skill: dated bulletins ("2026-07-05 — …"), phase or migration
|
|
40
|
+
status ("Phase 3 complete", "migration done", "landed"), "formerly X, now Y", incident
|
|
41
|
+
narratives, fixed-bug logs, or point-in-time inventories. If a line only makes sense to someone
|
|
42
|
+
who watched the change happen, it does not belong in guidance — the rule it taught does, stated
|
|
43
|
+
timelessly. Facts too specific to generalize go to `.agents/memory/`
|
|
44
|
+
(`.github/instructions/agent-memory.instructions.md`); the rewrite recipe is
|
|
45
|
+
`.github/instructions/memory-promotion.instructions.md` → Distillation.
|
|
46
|
+
|
|
47
|
+
Test: a finished instruction reads as though the feature was always this way.
|
|
32
48
|
|
|
33
49
|
## Non-project instructions
|
|
34
50
|
|
|
@@ -55,8 +55,12 @@ Cross-reference related guidance by name.
|
|
|
55
55
|
specific to this project's history. See the agent-memory instruction; promotion triggers live
|
|
56
56
|
in the memory-promotion instruction.
|
|
57
57
|
|
|
58
|
+
Never paste memory text into guidance. Memory content enters an instruction or skill only as a
|
|
59
|
+
restated general rule — trigger, step, and the failure it prevents, with dates, phase/status
|
|
60
|
+
markers, versions and incident narrative stripped (memory-promotion instruction → Distillation).
|
|
61
|
+
|
|
58
62
|
## After adding a skill
|
|
59
63
|
|
|
60
|
-
If it
|
|
64
|
+
If it distilled memory content into rules, shrink the source `.agents/memory/` node to a pointer line
|
|
61
65
|
(memory-promotion instruction) — the memory index does not list skills. Reference it from
|
|
62
66
|
`.github/copilot-instructions.md` / `CLAUDE.md` if it should be discoverable every session.
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"package": "@owlmeans/agent-skills",
|
|
4
|
-
"version": "0.1.
|
|
5
|
-
"generatedAt": "2026-08-
|
|
4
|
+
"version": "0.1.16-rc.0",
|
|
5
|
+
"generatedAt": "2026-08-11T14:02:34.977Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -136,3 +136,7 @@ each repo — fan every fix out to all copies; verify with `diff`. Correct re-ru
|
|
|
136
136
|
Fact-shaped ("what is true") stays here. Procedure-shaped ("to do X, do Y") becomes a skill —
|
|
137
137
|
follow `memory-promotion` where present, otherwise `skill-authoring`. Repeated use of a node to
|
|
138
138
|
*perform* tasks, and over-cap nodes full of steps, are promotion triggers.
|
|
139
|
+
|
|
140
|
+
Promotion is a **rewrite, never a move**: never paste node text into a skill. "Record the rule,
|
|
141
|
+
not the story" and the size caps above bind skill bodies at least as tightly as they bind nodes
|
|
142
|
+
(`memory-promotion` → Distillation).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: memory-promotion
|
|
3
|
-
description: Transform procedure-shaped or repeatedly-used memory into skills and instructions — the procedure-shape test, promote? repeated-touch flags, over-cap trigger, update-vs-create decision, and the post-promotion pointer state. Use when memory content reads as "how to", when a promote? flag is encountered again, or during recompaction.
|
|
3
|
+
description: Transform procedure-shaped or repeatedly-used memory into skills and instructions — the procedure-shape test, the mandatory distillation rewrite, promote? repeated-touch flags, over-cap trigger, update-vs-create decision, and the post-promotion pointer state. Use when memory content reads as "how to", when a promote? flag is encountered again, when writing memory-derived content into a skill, or during recompaction.
|
|
4
4
|
user-invocable: true
|
|
5
5
|
scope: general
|
|
6
6
|
---
|
|
@@ -12,6 +12,9 @@ Memory holds **facts**; **procedures** belong in skills/instructions, where they
|
|
|
12
12
|
stop consuming memory-read cycles. Promotion is how the store stays compact and the harness
|
|
13
13
|
teaches itself.
|
|
14
14
|
|
|
15
|
+
Promotion is a **rewrite, never a move**. Memory text pasted into a skill is the single most
|
|
16
|
+
common way this harness degrades — see Distillation below.
|
|
17
|
+
|
|
15
18
|
## Triggers
|
|
16
19
|
|
|
17
20
|
- **Procedure shape**: the content answers *how to do X* — ordered steps, imperative verbs,
|
|
@@ -28,7 +31,44 @@ teaches itself.
|
|
|
28
31
|
|
|
29
32
|
Procedure-shaped answers *how to do X*: ordered steps, imperative verbs, commands, action tables.
|
|
30
33
|
Fact-shaped answers *what is true*: declarative structure, invariants, symptom→cause pairs.
|
|
31
|
-
Mixed entries split — the fact stays in the node, the "then do"
|
|
34
|
+
Mixed entries split — the fact stays in the node, the "then do" is distilled into a rule in the
|
|
35
|
+
skill.
|
|
36
|
+
|
|
37
|
+
## Distillation (mandatory)
|
|
38
|
+
|
|
39
|
+
**Never paste memory text into a skill.** A promoted line leaves the node as prose about a past
|
|
40
|
+
occurrence and enters the skill as **one general rule**: *when this applies → do this → or this
|
|
41
|
+
breaks*, stated so it holds next time rather than describing last time.
|
|
42
|
+
|
|
43
|
+
| Strip | Keep |
|
|
44
|
+
|---|---|
|
|
45
|
+
| dates, phase/status markers, "COMPLETE", "landed" | the condition that makes the rule apply |
|
|
46
|
+
| versions, image tags, SHAs — unless the rule turns on the version | the step to take |
|
|
47
|
+
| "was X, now Y", "the former X was removed" | the failure it prevents |
|
|
48
|
+
| who did it, attempt sequences, incident narrative | the recognition fingerprint (symptom) |
|
|
49
|
+
| point-in-time inventories, counts, snapshots | |
|
|
50
|
+
|
|
51
|
+
Before (memory): "2026-07-05 — the control-board git card was removed; the dialog now owns all
|
|
52
|
+
git actions."
|
|
53
|
+
After (rule): "Git actions live in the git dialog; the control board holds none."
|
|
54
|
+
|
|
55
|
+
Before (memory): "Phase 3 (COMPLETE, 2026-06-13): added the init-container build, publisher
|
|
56
|
+
`src/build.ts`, kephemeral v0.1.5."
|
|
57
|
+
After (rule): "Production images build in an init container driven by `publisher/src/build.ts`."
|
|
58
|
+
|
|
59
|
+
**If the rule cannot be stated without saying when it happened, it is not promotable** — it stays
|
|
60
|
+
a memory fact, or it is dropped.
|
|
61
|
+
|
|
62
|
+
### Budget
|
|
63
|
+
|
|
64
|
+
A promotion normally adds **1–5 lines** to an existing skill, and a single rule is ≤ 3 lines. A
|
|
65
|
+
whole new section, or more text added than the node lost, means the content was moved rather than
|
|
66
|
+
distilled — redo it.
|
|
67
|
+
|
|
68
|
+
A skill may legitimately run long when it maps a large subsystem, so length alone is not the test:
|
|
69
|
+
**every line must be a rule, a contract, or a pointer.** A section that reads as the story of how
|
|
70
|
+
the code got there is pollution at any length. "Record the rule, not the story" (`agent-memory`)
|
|
71
|
+
binds skill bodies at least as tightly as it binds nodes.
|
|
32
72
|
|
|
33
73
|
## Flagging (how content earns promotion)
|
|
34
74
|
|
|
@@ -46,17 +86,21 @@ even partially; keep both twins in sync. Create a NEW pair only when:
|
|
|
46
86
|
re-encountered ` → promote?` flag);
|
|
47
87
|
- (c) an external technology required internet docs and has no governing skill.
|
|
48
88
|
|
|
49
|
-
New skills multiply lookup cost — compactness applies to the skill population
|
|
89
|
+
New skills multiply lookup cost — compactness applies to the skill population *and* to each
|
|
90
|
+
skill's body.
|
|
50
91
|
|
|
51
92
|
## Procedure
|
|
52
93
|
|
|
53
94
|
1. Collect the flagged / procedure-shaped memory lines.
|
|
54
|
-
2.
|
|
55
|
-
|
|
56
|
-
3.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
95
|
+
2. **Distill** each into a general rule (section above). Not optional — skipping it is the
|
|
96
|
+
failure mode this skill exists to prevent.
|
|
97
|
+
3. Author or extend the SKILL.md and its `.github/instructions/<name>.instructions.md` twin,
|
|
98
|
+
following the repo's `skill-authoring` or `create-skill` conventions. Where an existing rule
|
|
99
|
+
already covers the ground, **rewrite that rule in place**; append only when nothing covers it.
|
|
100
|
+
4. Shrink the node: delete the source lines; leave one pointer line (format below).
|
|
101
|
+
5. Remove the ` → promote?` flags.
|
|
102
|
+
6. Update the node's index hook if its main value moved; bump `updated:`.
|
|
103
|
+
7. Report per the Reporting rule.
|
|
60
104
|
|
|
61
105
|
## Post-promotion state
|
|
62
106
|
|
|
@@ -39,7 +39,8 @@ For each old file or section:
|
|
|
39
39
|
genuinely in-flight state → `Status`, dated).
|
|
40
40
|
3. On conflict between records, the version consistent with **current code** wins — check the
|
|
41
41
|
code, don't average.
|
|
42
|
-
4. Procedure-shaped survivors do not enter nodes — route them to `memory-promotion`.
|
|
42
|
+
4. Procedure-shaped survivors do not enter nodes — route them to `memory-promotion`. Routing
|
|
43
|
+
means distilling them into general rules, never handing the text over verbatim.
|
|
43
44
|
|
|
44
45
|
## Legacy-store merge (migration)
|
|
45
46
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: self-education
|
|
3
|
-
description: Mandatory post-development guidance updating — after functionality is added or changed,
|
|
3
|
+
description: Mandatory post-development guidance updating — after functionality is added or changed, rewrite the project skills/instructions the work touched as current rules (never as change notes), record external-doc findings (URL + gist) in the governing skill, or add skills/instructions for new subsystems and technologies. Required before the completion report whenever development started from a plan agreed with the agent.
|
|
4
4
|
user-invocable: true
|
|
5
5
|
scope: general
|
|
6
6
|
---
|
|
@@ -29,7 +29,22 @@ For each area the work touched:
|
|
|
29
29
|
1. Which existing skill/instruction covers it? (Check `.claude/skills/` +
|
|
30
30
|
`.github/instructions/`.)
|
|
31
31
|
2. Do its commands, paths, APIs, and behavior claims still hold after the change?
|
|
32
|
-
3. Fix in place —
|
|
32
|
+
3. Fix in place — rewrite the affected lines so they describe current behavior; never append a
|
|
33
|
+
note about what this change did. Keep the skill and its instruction twin in sync.
|
|
34
|
+
|
|
35
|
+
## Shape of an update
|
|
36
|
+
|
|
37
|
+
Skills and instructions state **current rules, not what changed**. Every edit is a rewrite in
|
|
38
|
+
place of the affected lines.
|
|
39
|
+
|
|
40
|
+
Never write into a skill or instruction: dated bulletins ("2026-07-05 — …"), phase or migration
|
|
41
|
+
status ("Phase 3 complete", "migration done", "landed"), "formerly X, now Y", incident
|
|
42
|
+
narratives, fixed-bug logs, or point-in-time inventories. If a line only makes sense to someone
|
|
43
|
+
who watched the change happen, it does not belong in guidance — the rule it taught does, stated
|
|
44
|
+
timelessly. Facts too specific to generalize go to `.agents/memory/` (`agent-memory`); the
|
|
45
|
+
rewrite recipe is `memory-promotion` → Distillation.
|
|
46
|
+
|
|
47
|
+
Test: a finished skill reads as though the feature was always this way.
|
|
33
48
|
|
|
34
49
|
## Non-project skills
|
|
35
50
|
|
|
@@ -71,10 +71,14 @@ skill").
|
|
|
71
71
|
If you find yourself writing "last time we…", that is memory. If you are writing "to do X, do Y",
|
|
72
72
|
that is a skill.
|
|
73
73
|
|
|
74
|
+
Never paste memory text into a skill. Memory content enters guidance only as a restated general
|
|
75
|
+
rule — trigger, step, and the failure it prevents, with dates, phase/status markers, versions and
|
|
76
|
+
incident narrative stripped (`memory-promotion` → Distillation).
|
|
77
|
+
|
|
74
78
|
## After adding a skill
|
|
75
79
|
|
|
76
80
|
1. If it replaces an ad-hoc `.claude/<topic>.md`, remove that file.
|
|
77
|
-
2. If it
|
|
78
|
-
(`memory-promotion`) — the memory index does not list skills.
|
|
81
|
+
2. If it distilled memory content into rules, shrink the source `.agents/memory/` node to a
|
|
82
|
+
pointer line (`memory-promotion`) — the memory index does not list skills.
|
|
79
83
|
3. Reference it from `CLAUDE.md` / `.github/copilot-instructions.md` if it should be discoverable
|
|
80
84
|
every session.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The LLM-facing half of this package: a prompt plugin that turns a mention of an
|
|
3
|
+
* `@owlmeans/*` package in a prompt into that package's published skills.
|
|
4
|
+
*
|
|
5
|
+
* Deliberately NOT re-exported from the package index. The installer CLI has no runtime
|
|
6
|
+
* dependencies and must keep it that way; this entry point resolves `@owlmeans/llm` and
|
|
7
|
+
* `@owlmeans/llm-common`, which only a consumer already using the LLM layer will have.
|
|
8
|
+
*/
|
|
9
|
+
export * from './types.js';
|
|
10
|
+
export * from './manifest.js';
|
|
11
|
+
export * from './resolve.js';
|
|
12
|
+
export * from './plugin.js';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/llm/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The LLM-facing half of this package: a prompt plugin that turns a mention of an
|
|
3
|
+
* `@owlmeans/*` package in a prompt into that package's published skills.
|
|
4
|
+
*
|
|
5
|
+
* Deliberately NOT re-exported from the package index. The installer CLI has no runtime
|
|
6
|
+
* dependencies and must keep it that way; this entry point resolves `@owlmeans/llm` and
|
|
7
|
+
* `@owlmeans/llm-common`, which only a consumer already using the LLM layer will have.
|
|
8
|
+
*/
|
|
9
|
+
export * from './types.js';
|
|
10
|
+
export * from './manifest.js';
|
|
11
|
+
export * from './resolve.js';
|
|
12
|
+
export * from './plugin.js';
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/llm/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { SkillDefinition } from '@owlmeans/llm-common';
|
|
2
|
+
import type { Manifest, ManifestEntry } from '../discover.js';
|
|
3
|
+
/** `@owlmeans/foo` → `foo`; the repo lays packages out under their unscoped name. */
|
|
4
|
+
export declare const unscoped: (packageName: string) => string;
|
|
5
|
+
export declare const parseManifest: (raw: string) => Manifest | null;
|
|
6
|
+
/**
|
|
7
|
+
* Strip the YAML frontmatter and the generated-file banner from an embedded SKILL.md.
|
|
8
|
+
*
|
|
9
|
+
* Both are installer bookkeeping — `name`, `description`, `applyTo`, "do not edit". Sent
|
|
10
|
+
* to a model they are pure noise in the most expensive part of the prompt, and the
|
|
11
|
+
* "do not edit" line actively misleads it about what it is being shown.
|
|
12
|
+
*/
|
|
13
|
+
export declare const stripMeta: (content: string) => string;
|
|
14
|
+
/**
|
|
15
|
+
* Skill entries worth loading, in a deterministic order.
|
|
16
|
+
*
|
|
17
|
+
* Instruction entries are dropped: they are the Copilot twin of the same knowledge, so
|
|
18
|
+
* including both would double the token cost of every package for no added information.
|
|
19
|
+
*/
|
|
20
|
+
export declare const skillEntries: (manifest: Manifest, categories: readonly string[]) => ManifestEntry[];
|
|
21
|
+
/**
|
|
22
|
+
* Turn one embedded skill file into a definition bound to the `Packages` block.
|
|
23
|
+
*
|
|
24
|
+
* The alias is namespaced by package so two packages documenting the same concept cannot
|
|
25
|
+
* collide in the registry, and the order weight is pushed past the default so package
|
|
26
|
+
* knowledge always renders after whatever the host declared itself.
|
|
27
|
+
*/
|
|
28
|
+
export declare const toSkill: (packageName: string, entry: ManifestEntry, body: string) => SkillDefinition;
|
|
29
|
+
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/llm/manifest.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAE7D,qFAAqF;AACrF,eAAO,MAAM,QAAQ,GAAI,aAAa,MAAM,KAAG,MACE,CAAA;AAEjD,eAAO,MAAM,aAAa,GAAI,KAAK,MAAM,KAAG,QAAQ,GAAG,IAUtD,CAAA;AAID;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,GAAI,SAAS,MAAM,KAAG,MAW3C,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GACvB,UAAU,QAAQ,EAClB,YAAY,SAAS,MAAM,EAAE,KAC5B,aAAa,EAGmD,CAAA;AAEnE;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,GAClB,aAAa,MAAM,EACnB,OAAO,aAAa,EACpB,MAAM,MAAM,KACX,eAMD,CAAA"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { DEFAULT_SKILL_ORDER, PromptBlock } from '@owlmeans/llm-common';
|
|
2
|
+
/** `@owlmeans/foo` → `foo`; the repo lays packages out under their unscoped name. */
|
|
3
|
+
export const unscoped = (packageName) => packageName.slice(packageName.indexOf('/') + 1);
|
|
4
|
+
export const parseManifest = (raw) => {
|
|
5
|
+
try {
|
|
6
|
+
const manifest = JSON.parse(raw);
|
|
7
|
+
if (typeof manifest.schemaVersion !== 'number' || !Array.isArray(manifest.entries)) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
return manifest;
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
const BANNER = /^<!--\s*AUTO-GENERATED[^>]*-->\s*/;
|
|
17
|
+
/**
|
|
18
|
+
* Strip the YAML frontmatter and the generated-file banner from an embedded SKILL.md.
|
|
19
|
+
*
|
|
20
|
+
* Both are installer bookkeeping — `name`, `description`, `applyTo`, "do not edit". Sent
|
|
21
|
+
* to a model they are pure noise in the most expensive part of the prompt, and the
|
|
22
|
+
* "do not edit" line actively misleads it about what it is being shown.
|
|
23
|
+
*/
|
|
24
|
+
export const stripMeta = (content) => {
|
|
25
|
+
let body = content.replace(/^/, '');
|
|
26
|
+
if (body.startsWith('---')) {
|
|
27
|
+
const end = body.indexOf('\n---', 3);
|
|
28
|
+
if (end >= 0) {
|
|
29
|
+
const after = body.indexOf('\n', end + 1);
|
|
30
|
+
body = after >= 0 ? body.slice(after + 1) : '';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return body.replace(BANNER, '').trim();
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Skill entries worth loading, in a deterministic order.
|
|
37
|
+
*
|
|
38
|
+
* Instruction entries are dropped: they are the Copilot twin of the same knowledge, so
|
|
39
|
+
* including both would double the token cost of every package for no added information.
|
|
40
|
+
*/
|
|
41
|
+
export const skillEntries = (manifest, categories) => manifest.entries
|
|
42
|
+
.filter(entry => entry.kind === 'skill' && categories.includes(entry.category))
|
|
43
|
+
.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
44
|
+
/**
|
|
45
|
+
* Turn one embedded skill file into a definition bound to the `Packages` block.
|
|
46
|
+
*
|
|
47
|
+
* The alias is namespaced by package so two packages documenting the same concept cannot
|
|
48
|
+
* collide in the registry, and the order weight is pushed past the default so package
|
|
49
|
+
* knowledge always renders after whatever the host declared itself.
|
|
50
|
+
*/
|
|
51
|
+
export const toSkill = (packageName, entry, body) => ({
|
|
52
|
+
alias: `${packageName}#${entry.name}`,
|
|
53
|
+
title: `${packageName} — ${entry.name}`,
|
|
54
|
+
body,
|
|
55
|
+
block: PromptBlock.Packages,
|
|
56
|
+
order: DEFAULT_SKILL_ORDER + 1,
|
|
57
|
+
});
|
|
58
|
+
//# sourceMappingURL=manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/llm/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAIvE,qFAAqF;AACrF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,WAAmB,EAAU,EAAE,CACtD,WAAW,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;AAEjD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,GAAW,EAAmB,EAAE;IAC5D,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAA;QAC5C,IAAI,OAAO,QAAQ,CAAC,aAAa,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACnF,OAAO,IAAI,CAAA;QACb,CAAC;QACD,OAAO,QAAQ,CAAA;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC,CAAA;AAED,MAAM,MAAM,GAAG,mCAAmC,CAAA;AAElD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,OAAe,EAAU,EAAE;IACnD,IAAI,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;IACpC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;QACpC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;YACb,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,GAAG,CAAC,CAAC,CAAA;YACzC,IAAI,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QAChD,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;AACxC,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,QAAkB,EAClB,UAA6B,EACZ,EAAE,CACnB,QAAQ,CAAC,OAAO;KACb,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;KAC9E,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAEnE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CACrB,WAAmB,EACnB,KAAoB,EACpB,IAAY,EACK,EAAE,CAAC,CAAC;IACrB,KAAK,EAAE,GAAG,WAAW,IAAI,KAAK,CAAC,IAAI,EAAE;IACrC,KAAK,EAAE,GAAG,WAAW,MAAM,KAAK,CAAC,IAAI,EAAE;IACvC,IAAI;IACJ,KAAK,EAAE,WAAW,CAAC,QAAQ;IAC3B,KAAK,EAAE,mBAAmB,GAAG,CAAC;CAC/B,CAAC,CAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { LlmPromptPlugin } from '@owlmeans/llm';
|
|
2
|
+
import type { PackageSkillsOptions } from './types.js';
|
|
3
|
+
export declare const PACKAGE_SKILLS_PLUGIN = "owlmeans-packages";
|
|
4
|
+
/**
|
|
5
|
+
* A prompt plugin that notices which `@owlmeans/*` packages a request talks about and
|
|
6
|
+
* loads their published skills into the system prompt.
|
|
7
|
+
*
|
|
8
|
+
* Everything the package documents is loaded — there is no relevance filtering, by
|
|
9
|
+
* design: choosing a subset would need a judgement the model is better placed to make
|
|
10
|
+
* than a regex, and a partial answer about an API is worse than none.
|
|
11
|
+
*
|
|
12
|
+
* The result lands in the `Packages` block, which sits behind its own cache breakpoint.
|
|
13
|
+
* That is the whole reason the block exists: what a request mentions changes call to
|
|
14
|
+
* call, and it must not shift a single byte of the role and skills every call shares.
|
|
15
|
+
*/
|
|
16
|
+
export declare const owlmeansPackagesPlugin: (options?: PackageSkillsOptions) => LlmPromptPlugin;
|
|
17
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/llm/plugin.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAiB,MAAM,eAAe,CAAA;AAGnE,OAAO,KAAK,EAAiB,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAErE,eAAO,MAAM,qBAAqB,sBAAsB,CAAA;AAuBxD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,GAAI,UAAS,oBAAyB,KAAG,eA0F3E,CAAA"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { PromptBlock, resolveFileProvider } from '@owlmeans/llm-common';
|
|
2
|
+
import { renderSkill } from '@owlmeans/llm/prompt';
|
|
3
|
+
import { loadPackageSkills } from './resolve.js';
|
|
4
|
+
import { OWLMEANS_SCOPE } from './types.js';
|
|
5
|
+
export const PACKAGE_SKILLS_PLUGIN = 'owlmeans-packages';
|
|
6
|
+
const DEFAULT_MAX_PACKAGES = 5;
|
|
7
|
+
const DEFAULT_CATEGORIES = ['package-specific', 'multi-package'];
|
|
8
|
+
const escape = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
9
|
+
const textOf = (content) => {
|
|
10
|
+
if (typeof content === 'string') {
|
|
11
|
+
return content;
|
|
12
|
+
}
|
|
13
|
+
if (Array.isArray(content)) {
|
|
14
|
+
return content
|
|
15
|
+
.map(part => {
|
|
16
|
+
const text = part.text;
|
|
17
|
+
return typeof text === 'string' ? text : '';
|
|
18
|
+
})
|
|
19
|
+
.join('\n');
|
|
20
|
+
}
|
|
21
|
+
return '';
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* A prompt plugin that notices which `@owlmeans/*` packages a request talks about and
|
|
25
|
+
* loads their published skills into the system prompt.
|
|
26
|
+
*
|
|
27
|
+
* Everything the package documents is loaded — there is no relevance filtering, by
|
|
28
|
+
* design: choosing a subset would need a judgement the model is better placed to make
|
|
29
|
+
* than a regex, and a partial answer about an API is worse than none.
|
|
30
|
+
*
|
|
31
|
+
* The result lands in the `Packages` block, which sits behind its own cache breakpoint.
|
|
32
|
+
* That is the whole reason the block exists: what a request mentions changes call to
|
|
33
|
+
* call, and it must not shift a single byte of the role and skills every call shares.
|
|
34
|
+
*/
|
|
35
|
+
export const owlmeansPackagesPlugin = (options = {}) => {
|
|
36
|
+
const scopes = options.scopes ?? [OWLMEANS_SCOPE];
|
|
37
|
+
// No dots and no trailing hyphen, so `@owlmeans/llm.` yields `@owlmeans/llm` — prose
|
|
38
|
+
// and code both end package names with punctuation.
|
|
39
|
+
const pattern = new RegExp(`(?:${scopes.map(escape).join('|')})\\/[a-z0-9](?:[a-z0-9-]*[a-z0-9])?`, 'g');
|
|
40
|
+
const exclude = options.exclude ?? [];
|
|
41
|
+
const maxPackages = options.maxPackages ?? DEFAULT_MAX_PACKAGES;
|
|
42
|
+
const categories = options.categories ?? [...DEFAULT_CATEGORIES];
|
|
43
|
+
/**
|
|
44
|
+
* Resolved packages, negatives included. Without caching the misses, a prompt that
|
|
45
|
+
* mentions a package which does not publish skills would hit GitHub on every call.
|
|
46
|
+
*/
|
|
47
|
+
const cache = new Map();
|
|
48
|
+
/**
|
|
49
|
+
* Per-provider caches, keyed by the provider INSTANCE.
|
|
50
|
+
*
|
|
51
|
+
* A host's file provider is usually per-project (a sandbox, a slot, one checkout), so
|
|
52
|
+
* two executions can resolve the same package name to different content. Sharing one
|
|
53
|
+
* cache across them would serve project A's skills to project B. A `WeakMap` keeps the
|
|
54
|
+
* entries alive exactly as long as the provider is.
|
|
55
|
+
*/
|
|
56
|
+
const perProvider = new WeakMap();
|
|
57
|
+
const load = (packageName, ctx) => {
|
|
58
|
+
// The context's provider is the specific one — it sees the project this call is
|
|
59
|
+
// actually about. The constructor option is the fallback for a host that wires one
|
|
60
|
+
// globally. Without this, a per-execution provider was never consulted at all.
|
|
61
|
+
const provider = resolveFileProvider(ctx.files) ?? resolveFileProvider(options.files);
|
|
62
|
+
const store = provider != null
|
|
63
|
+
? perProvider.get(provider) ?? (() => {
|
|
64
|
+
const fresh = new Map();
|
|
65
|
+
perProvider.set(provider, fresh);
|
|
66
|
+
return fresh;
|
|
67
|
+
})()
|
|
68
|
+
: cache;
|
|
69
|
+
const pending = store.get(packageName);
|
|
70
|
+
if (pending != null) {
|
|
71
|
+
return pending;
|
|
72
|
+
}
|
|
73
|
+
const promise = loadPackageSkills(packageName, { ...options, files: provider }, categories);
|
|
74
|
+
store.set(packageName, promise);
|
|
75
|
+
return promise;
|
|
76
|
+
};
|
|
77
|
+
const detect = (ctx) => {
|
|
78
|
+
const found = new Set();
|
|
79
|
+
for (const message of ctx.messages) {
|
|
80
|
+
const text = textOf(message.content);
|
|
81
|
+
if (text === '') {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
for (const match of text.matchAll(pattern)) {
|
|
85
|
+
found.add(match[0]);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Alphabetical, not first-seen: two prompts that mention the same packages in a
|
|
89
|
+
// different order must still produce the same bytes.
|
|
90
|
+
return [...found]
|
|
91
|
+
.filter(name => !exclude.includes(name))
|
|
92
|
+
.sort()
|
|
93
|
+
.slice(0, maxPackages);
|
|
94
|
+
};
|
|
95
|
+
return {
|
|
96
|
+
alias: PACKAGE_SKILLS_PLUGIN,
|
|
97
|
+
order: 50,
|
|
98
|
+
inspect: async (ctx) => {
|
|
99
|
+
const names = detect(ctx);
|
|
100
|
+
if (names.length === 0) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const resolved = await Promise.all(names.map(name => load(name, ctx)));
|
|
104
|
+
for (const found of resolved) {
|
|
105
|
+
if (found == null) {
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
for (const skill of found.skills) {
|
|
109
|
+
ctx.add(PromptBlock.Packages, renderSkill(skill));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
//# sourceMappingURL=plugin.js.map
|