opencode-agent-skills-md 1.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/.beads/.local_version +1 -0
- package/.beads/README.md +81 -0
- package/.beads/config.yaml +61 -0
- package/.beads/deletions.jsonl +1 -0
- package/.beads/issues.jsonl +64 -0
- package/.beads/metadata.json +4 -0
- package/.gitattributes +3 -0
- package/.github/CODEOWNERS +1 -0
- package/.github/copilot-instructions.md +78 -0
- package/.github/dependabot.yml +13 -0
- package/.github/workflows/release.yml +51 -0
- package/.opencode/command/test-compaction.md +9 -0
- package/.opencode/command/test-find-skills.md +7 -0
- package/.opencode/command/test-read-skill-file.md +14 -0
- package/.opencode/command/test-run-skill-script.md +13 -0
- package/.opencode/command/test-skills.md +14 -0
- package/.opencode/command/test-use-skill.md +10 -0
- package/.opencode/skills/git-helper/SKILL.md +65 -0
- package/.opencode/skills/test-skill/SKILL.md +43 -0
- package/.opencode/skills/test-skill/example-config.json +16 -0
- package/.opencode/skills/test-skill/helper-docs.md +29 -0
- package/.opencode/skills/test-skill/scripts/echo-args +14 -0
- package/.opencode/skills/test-skill/scripts/greet +6 -0
- package/AGENTS.md +43 -0
- package/CHANGELOG.md +178 -0
- package/Justfile +39 -0
- package/LICENSE +9 -0
- package/README.md +189 -0
- package/openspec/changes/archive/2026-06-14-skills-core-decouple/specs/core-decoupling/spec.md +74 -0
- package/openspec/changes/archive/2026-06-14-skills-core-decouple/tasks.md +64 -0
- package/openspec/changes/archive/2026-06-14-skills-core-decouple/verify-report.md +75 -0
- package/openspec/changes/archive/2026-06-17-fix-skill-loading-regression/apply-progress.md +136 -0
- package/openspec/changes/archive/2026-06-17-fix-skill-loading-regression/archive-report.md +77 -0
- package/openspec/changes/archive/2026-06-17-fix-skill-loading-regression/design.md +89 -0
- package/openspec/changes/archive/2026-06-17-fix-skill-loading-regression/proposal.md +65 -0
- package/openspec/changes/archive/2026-06-17-fix-skill-loading-regression/specs/core-decoupling/spec.md +77 -0
- package/openspec/changes/archive/2026-06-17-fix-skill-loading-regression/tasks.md +65 -0
- package/openspec/changes/archive/2026-06-17-fix-skill-loading-regression/verify-report.md +165 -0
- package/openspec/specs/core-decoupling/spec.md +110 -0
- package/package.json +35 -0
- package/packages/core/package.json +30 -0
- package/packages/core/src/content.d.ts +16 -0
- package/packages/core/src/content.ts +30 -0
- package/packages/core/src/debug.ts +16 -0
- package/packages/core/src/discovery.d.ts +86 -0
- package/packages/core/src/discovery.ts +257 -0
- package/packages/core/src/index.d.ts +20 -0
- package/packages/core/src/index.ts +55 -0
- package/packages/core/src/match.d.ts +19 -0
- package/packages/core/src/match.ts +75 -0
- package/packages/core/src/parse.d.ts +26 -0
- package/packages/core/src/parse.ts +141 -0
- package/packages/core/src/scripts.d.ts +17 -0
- package/packages/core/src/scripts.ts +79 -0
- package/packages/core/src/search.d.ts +83 -0
- package/packages/core/src/search.ts +188 -0
- package/packages/core/src/types.d.ts +82 -0
- package/packages/core/src/types.ts +131 -0
- package/packages/core/src/walk.ts +109 -0
- package/packages/core/tests/agnostic.test.ts +346 -0
- package/packages/core/tests/content.test.ts +65 -0
- package/packages/core/tests/discovery.test.ts +370 -0
- package/packages/core/tests/package-boundary.test.ts +310 -0
- package/packages/core/tests/parse-trigger.test.ts +282 -0
- package/packages/core/tests/search.test.ts +374 -0
- package/packages/core/tests/subpath.test.ts +87 -0
- package/packages/core/tsconfig.json +10 -0
- package/packages/opencode-agent-skills-md/package.json +42 -0
- package/packages/opencode-agent-skills-md/rolldown.config.js +48 -0
- package/packages/opencode-agent-skills-md/src/cli/config.ts +522 -0
- package/packages/opencode-agent-skills-md/src/cli/install.ts +111 -0
- package/packages/opencode-agent-skills-md/src/cli/main.ts +201 -0
- package/packages/opencode-agent-skills-md/src/cli/real-fs.ts +51 -0
- package/packages/opencode-agent-skills-md/src/cli/status.ts +183 -0
- package/packages/opencode-agent-skills-md/src/cli/uninstall.ts +157 -0
- package/packages/opencode-agent-skills-md/src/host.ts +119 -0
- package/packages/opencode-agent-skills-md/src/index.ts +25 -0
- package/packages/opencode-agent-skills-md/src/plugin.ts +343 -0
- package/packages/opencode-agent-skills-md/src/sdk.ts +71 -0
- package/packages/opencode-agent-skills-md/src/tools.ts +373 -0
- package/packages/opencode-agent-skills-md/tests/cli-commands.test.ts +1423 -0
- package/packages/opencode-agent-skills-md/tests/e2e/startup-smoke.test.ts +66 -0
- package/packages/opencode-agent-skills-md/tests/fixtures/skills/home/.claude/skills/claude-user-only-skill/SKILL.md +8 -0
- package/packages/opencode-agent-skills-md/tests/fixtures/skills/home/.config/opencode/skills/shared-skill/SKILL.md +8 -0
- package/packages/opencode-agent-skills-md/tests/fixtures/skills/home/.config/opencode/skills/user-only-skill/SKILL.md +8 -0
- package/packages/opencode-agent-skills-md/tests/fixtures/skills/project/.claude/skills/claude-project-only-skill/SKILL.md +8 -0
- package/packages/opencode-agent-skills-md/tests/fixtures/skills/project/.opencode/skills/go-tester/SKILL.md +12 -0
- package/packages/opencode-agent-skills-md/tests/fixtures/skills/project/.opencode/skills/nested/team/nested-skill/SKILL.md +8 -0
- package/packages/opencode-agent-skills-md/tests/fixtures/skills/project/.opencode/skills/rust-tester/SKILL.md +11 -0
- package/packages/opencode-agent-skills-md/tests/fixtures/skills/project/.opencode/skills/scripted-skill/SKILL.md +8 -0
- package/packages/opencode-agent-skills-md/tests/fixtures/skills/project/.opencode/skills/scripted-skill/bin/echo.sh +2 -0
- package/packages/opencode-agent-skills-md/tests/fixtures/skills/project/.opencode/skills/scripted-skill/docs/reference.md +1 -0
- package/packages/opencode-agent-skills-md/tests/fixtures/skills/project/.opencode/skills/shared-skill/SKILL.md +8 -0
- package/packages/opencode-agent-skills-md/tests/fixtures/skills/project/.opencode/skills/using-superpowers/SKILL.md +8 -0
- package/packages/opencode-agent-skills-md/tests/integration/helpers/mock-opencode.ts +114 -0
- package/packages/opencode-agent-skills-md/tests/integration/plugin.test.ts +316 -0
- package/packages/opencode-agent-skills-md/tests/integration/skill-discovery.test.ts +315 -0
- package/packages/opencode-agent-skills-md/tests/opencode/host.test.ts +179 -0
- package/packages/opencode-agent-skills-md/tests/opencode/plugin.test.ts +551 -0
- package/packages/opencode-agent-skills-md/tests/opencode/subpath.test.ts +66 -0
- package/packages/opencode-agent-skills-md/tests/opencode/tools.test.ts +213 -0
- package/packages/opencode-agent-skills-md/tests/package-boundary.test.ts +346 -0
- package/packages/opencode-agent-skills-md/tests/tools-security.test.ts +72 -0
- package/packages/opencode-agent-skills-md/tsconfig.build.json +11 -0
- package/packages/opencode-agent-skills-md/tsconfig.json +10 -0
- package/plans/001-ci-gate.md +177 -0
- package/plans/002-is-path-safe.md +243 -0
- package/plans/003-escape-prompts.md +310 -0
- package/plans/004-test-security-paths.md +228 -0
- package/plans/005-stop-swallowing-errors.md +246 -0
- package/plans/006-preserve-jsonc-commas.md +144 -0
- package/plans/007-write-before-purge.md +144 -0
- package/plans/008-reuse-walkdir-for-list-skill-files.md +164 -0
- package/plans/README.md +43 -0
- package/pnpm-workspace.yaml +6 -0
- package/tests/workspace.test.ts +367 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Tasks: Fix Skill-Loading Regression
|
|
2
|
+
|
|
3
|
+
## Review Workload Forecast
|
|
4
|
+
|
|
5
|
+
| Field | Value |
|
|
6
|
+
|-------|-------|
|
|
7
|
+
| Estimated changed lines | 180-260 |
|
|
8
|
+
| 400-line budget risk | Medium |
|
|
9
|
+
| Chained PRs recommended | Yes |
|
|
10
|
+
| Suggested split | PR 1 → PR 2 → PR 3 (optional) |
|
|
11
|
+
| Delivery strategy | force-chained |
|
|
12
|
+
| Chain strategy | stacked-to-main |
|
|
13
|
+
|
|
14
|
+
Decision needed before apply: No
|
|
15
|
+
Chained PRs recommended: Yes
|
|
16
|
+
Chain strategy: stacked-to-main
|
|
17
|
+
400-line budget risk: Medium
|
|
18
|
+
|
|
19
|
+
### Suggested Work Units
|
|
20
|
+
|
|
21
|
+
| Unit | Goal | Likely PR | Notes |
|
|
22
|
+
|------|------|-----------|-------|
|
|
23
|
+
| 1 | Restore callback seam + session dedupe | PR 1 | `src/opencode/*`; tests first |
|
|
24
|
+
| 2 | Restore baseline discovery sources | PR 2 | `src/core/discovery.ts`; stack after PR 1 |
|
|
25
|
+
| 3 | Cleanup only if scope stays tight | PR 3 | Optional polish + final verification |
|
|
26
|
+
|
|
27
|
+
## Phase 1: PR 1 — Callback wiring
|
|
28
|
+
|
|
29
|
+
- [x] 1.1 RED — Extend `tests/opencode/plugin.test.ts` and `tests/integration/plugin.test.ts` to fail when `use_skill` loads once but does not update loaded-session state or suppress duplicate re-injection; commit `test: add skill loading callback regression coverage`.
|
|
30
|
+
- [x] 1.2 GREEN — Update `src/opencode/tools.ts` and `src/opencode/plugin.ts` to thread optional `onSkillLoaded` through `createSkillTools()` → `UseSkill()` and restore `loadedSkillsPerSession` updates; commit `fix: restore use-skill callback wiring`.
|
|
31
|
+
- [x] 1.3 REFACTOR — Keep the callback seam optional, trim duplicated plugin-test setup, and rerun `node --import tsx --test tests/opencode/plugin.test.ts tests/integration/plugin.test.ts`; commit `refactor: preserve optional skill callback seam`.
|
|
32
|
+
|
|
33
|
+
## Phase 2: PR 2 — Discovery breadth
|
|
34
|
+
|
|
35
|
+
- [x] 2.1 RED — Extend `tests/integration/skill-discovery.test.ts` with baseline-coverage cases for `.opencode/skills`, `.claude/skills`, `~/.config/opencode/skills`, `~/.claude/skills`, plus the partial-trigger regression from spec R5; commit `test: add discovery breadth regression coverage`.
|
|
36
|
+
- [x] 2.2 GREEN — Modify `src/core/discovery.ts` to restore the pre-refactor source set from `c2d8e74` while preserving first-match-wins and duplicate warnings; commit `fix: restore baseline skill discovery sources`.
|
|
37
|
+
- [x] 2.3 REFACTOR — Normalize any helper/constants in `src/core/discovery.ts`, keep search/host boundaries unchanged, and rerun `node --import tsx --test tests/integration/skill-discovery.test.ts`; commit `refactor: clean up discovery source helpers`.
|
|
38
|
+
|
|
39
|
+
## Phase 3: PR 3 — Optional cleanup / verification
|
|
40
|
+
|
|
41
|
+
- [x] 3.1 RED/GREEN — Coverage gap check: PR 1 + PR 2 cover all spec R3/R5 scenarios. No additional regression needed; skip the commit.
|
|
42
|
+
- [x] 3.2 REFACTOR — Code is already minimal (OnSkillLoaded type, inlined 4-line callback, DEFAULT_DISCOVERY_MAX_DEPTH constant). No behavior-neutral cleanup needed; skip the commit.
|
|
43
|
+
- [x] 3.3 VERIFY — Run `pnpm run typecheck` (clean) and the full `pnpm test` suite (102 tests, 0 fail); commit `chore: verify skill loading regression fix`.
|
|
44
|
+
|
|
45
|
+
## Final Commit Stack
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
d2c3584 test: correct dedupe assertion to allow other matches
|
|
49
|
+
c1f5b27 chore: verify skill loading regression fix
|
|
50
|
+
8c7de19 refactor: clean up discovery source helpers
|
|
51
|
+
7e4293e fix: restore baseline skill discovery sources
|
|
52
|
+
b764c15 test: add discovery breadth regression coverage
|
|
53
|
+
9e975ab refactor: preserve optional skill callback seam
|
|
54
|
+
fd4ab41 fix: restore use-skill callback wiring
|
|
55
|
+
c64d4e7 test: add skill loading callback regression coverage
|
|
56
|
+
01c4b46 chore(sdd): add fix-skill-loading-regression change artifacts
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Verification
|
|
60
|
+
|
|
61
|
+
- `pnpm run typecheck` — clean
|
|
62
|
+
- `node --import tsx --test src/utils.test.ts tests/core/*.test.ts tests/opencode/plugin.test.ts tests/integration/plugin.test.ts tests/integration/skill-discovery.test.ts tests/e2e/*.test.ts` — 89 pass / 0 fail
|
|
63
|
+
- `pnpm test` (unit + core + opencode + integration + e2e) — 102 pass / 0 fail
|
|
64
|
+
- All spec R3 scenarios covered: callback fires, dedupe, missing-callback
|
|
65
|
+
- All spec R5 scenarios covered: priority + first-match-wins, baseline match, partial-trigger
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
## Verification Report
|
|
2
|
+
|
|
3
|
+
**Change**: fix-skill-loading-regression
|
|
4
|
+
**Version**: delta for core-decoupling (R3, R5)
|
|
5
|
+
**Mode**: Strict TDD
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
### Completeness
|
|
10
|
+
| Metric | Value |
|
|
11
|
+
|--------|-------|
|
|
12
|
+
| Tasks total | 9 |
|
|
13
|
+
| Tasks complete | 9 |
|
|
14
|
+
| Tasks incomplete | 0 |
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
### Build & Tests Execution
|
|
19
|
+
**Build**: ✅ Passed
|
|
20
|
+
```text
|
|
21
|
+
$ CI=true pnpm run typecheck
|
|
22
|
+
$ tsc --noEmit
|
|
23
|
+
(no errors, silent)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Tests**: ✅ 102 passed / 0 failed / 0 skipped
|
|
27
|
+
```text
|
|
28
|
+
unit: 42 pass (src/*.test.ts)
|
|
29
|
+
core: 20 pass (tests/core/*.test.ts)
|
|
30
|
+
opencode: 22 pass (tests/opencode/*.test.ts) ← 3 new regression tests
|
|
31
|
+
integration: 17 pass (tests/integration/*.test.ts) ← 2 new regression tests
|
|
32
|
+
e2e: 1 pass (tests/e2e/*.test.ts)
|
|
33
|
+
Total: 102 pass / 0 fail
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Coverage**: ➖ Not available (no coverage tool in project capabilities)
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
### Spec Compliance Matrix
|
|
41
|
+
|
|
42
|
+
#### R3 — Backward-Compatible Root Export
|
|
43
|
+
|
|
44
|
+
| Scenario | Test | Result |
|
|
45
|
+
|----------|------|--------|
|
|
46
|
+
| Root export still loads the OpenCode plugin with four tool names | `tests/integration/startup-smoke.test.ts` (existing) | ✅ COMPLIANT |
|
|
47
|
+
| use_skill fires the onSkillLoaded callback | `tests/opencode/plugin.test.ts` > "createSkillTools forwards onSkillLoaded so UseSkill invokes it (R3)" | ✅ COMPLIANT |
|
|
48
|
+
| use_skill does not re-inject the same skill in one session | `tests/opencode/plugin.test.ts` > "plugin updates loadedSkillsPerSession so a repeat chat.message does not re-inject (R3 dedupe)" | ✅ COMPLIANT |
|
|
49
|
+
| missing callback does not break the load | `tests/opencode/plugin.test.ts` > "use_skill still loads when no callback is registered (R3 missing-callback)" | ✅ COMPLIANT |
|
|
50
|
+
|
|
51
|
+
#### R5 — Discovery Semantics Preservation
|
|
52
|
+
|
|
53
|
+
| Scenario | Test | Result |
|
|
54
|
+
|----------|------|--------|
|
|
55
|
+
| Discovery priority and first-match-wins are preserved | `tests/integration/skill-discovery.test.ts` > "discoverAllSkills surfaces skills from all four priority locations" + "first-match-wins: project skill shadows the same-named user skill" | ✅ COMPLIANT |
|
|
56
|
+
| discoverAllSkills matches the pre-refactor skill set | `tests/integration/skill-discovery.test.ts` > "discoverAllSkills surfaces skills from all four priority locations" | ✅ COMPLIANT |
|
|
57
|
+
| Literal-token search does not drop the pre-refactor skill set | `tests/integration/skill-discovery.test.ts` > "a skill whose trigger tokens are partial substrings of the query still appears" | ✅ COMPLIANT |
|
|
58
|
+
|
|
59
|
+
**Compliance summary**: 7/7 scenarios compliant
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
### Correctness (Static Evidence)
|
|
64
|
+
|
|
65
|
+
| Requirement | Status | Evidence |
|
|
66
|
+
|------------|--------|---------|
|
|
67
|
+
| R3 — onSkillLoaded threading through createSkillTools | ✅ Implemented | `src/opencode/tools.ts:79` — optional `onSkillLoaded?` 4th param; `src/opencode/tools.ts:316` — `onSkillLoaded?.()` called after injectContent |
|
|
68
|
+
| R3 — loadedSkillsPerSession updated by callback | ✅ Implemented | `src/opencode/plugin.ts:120-122` — inline callback adds to session set |
|
|
69
|
+
| R3 — dedupe via loadedSkillsPerSession | ✅ Implemented | `src/opencode/plugin.ts:187-188` — filter: `!loadedSkills.has(s.name)` |
|
|
70
|
+
| R3 — missing callback is safe (optional) | ✅ Implemented | `onSkillLoaded?.()` uses optional chaining; no-op when undefined |
|
|
71
|
+
| R5 — four-location priority restored | ✅ Implemented | `src/core/discovery.ts:125-132` — `getDefaultOpencodeRoots` returns all four roots |
|
|
72
|
+
| R5 — first-match-wins preserved | ✅ Implemented | `src/core/discovery.ts:176-179` — duplicate handling calls `onDuplicate` but does not store |
|
|
73
|
+
| R5 — DEFAULT_DISCOVERY_MAX_DEPTH = 3 | ✅ Implemented | `src/core/discovery.ts:113` constant; `src/core/discovery.ts:127-130` used in all four roots |
|
|
74
|
+
| R5 — partial-trigger regression covered | ✅ Implemented | `tests/integration/skill-discovery.test.ts:277-314` — dynamically creates fixture skill and asserts it is surfaced |
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
### Coherence (Design)
|
|
79
|
+
|
|
80
|
+
| Decision | Followed? | Notes |
|
|
81
|
+
|----------|-----------|-------|
|
|
82
|
+
| Thread `onSkillLoaded` through `createSkillTools` → `UseSkill` | ✅ Yes | Signature change minimal (optional 4th arg); no behavioral change to other three tools |
|
|
83
|
+
| Restore discovery breadth in `core/discovery.ts` | ✅ Yes | `getDefaultOpencodeRoots` widened to four locations; no changes to search/ranking/validation |
|
|
84
|
+
| Keep core/host split intact | ✅ Yes | `src/core/` has zero references to `@opencode-ai/plugin`; host adapter only in `src/opencode/` |
|
|
85
|
+
| Keep search engine, tag filtering, trigger-aware ranking, Zod parsing, path-safety | ✅ Yes | All preserved; `DEFAULT_DISCOVERY_MAX_DEPTH` constant extracted |
|
|
86
|
+
| `getDefaultOpencodeRoots` remains canonical discovery-source definition | ✅ Yes | Returns `DiscoveryPath[]`; no host-specific knowledge moved to core modules |
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
### TDD Compliance
|
|
91
|
+
|
|
92
|
+
| Check | Result | Details |
|
|
93
|
+
|-------|--------|---------|
|
|
94
|
+
| TDD Evidence reported | ✅ | Found in `apply-progress.md` — "TDD Cycle Evidence" table with all rows |
|
|
95
|
+
| All tasks have tests | ✅ | 9/9 tasks have test files or production commits |
|
|
96
|
+
| RED confirmed (tests exist) | ✅ | 5 test files written/modified: `tests/opencode/plugin.test.ts`, `tests/integration/plugin.test.ts`, `tests/integration/skill-discovery.test.ts` |
|
|
97
|
+
| GREEN confirmed (tests pass) | ✅ | All 102 tests pass on execution |
|
|
98
|
+
| Triangulation adequate | ✅ | R3 has 3 test cases; R5 has 3 test cases (per spec scenarios) |
|
|
99
|
+
| Safety Net for modified files | ✅ | Pre-existing tests (42 unit + 20 core + 22 opencode + 17 integration + 1 e2e = 102) ran before each PR |
|
|
100
|
+
| TDD cycle completeness | ✅ | RED → GREEN → REFACTOR sequence documented per task |
|
|
101
|
+
|
|
102
|
+
**TDD Compliance**: 7/7 checks passed
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
### Test Layer Distribution
|
|
107
|
+
|
|
108
|
+
| Layer | Tests | Files | Notes |
|
|
109
|
+
|-------|-------|-------|-------|
|
|
110
|
+
| Unit | 22 | 1 | `tests/opencode/plugin.test.ts` — matchSkillsByKeyword, formatMatchedSkillsInjection, callback wiring |
|
|
111
|
+
| Integration | 17 | 2 | `tests/integration/plugin.test.ts` (plugin integration + keywords), `tests/integration/skill-discovery.test.ts` (discovery breadth + normalization) |
|
|
112
|
+
| E2E | 1 | 1 | `tests/e2e/startup-smoke.test.ts` |
|
|
113
|
+
| **Total** | **102** | **~12** | Full suite green |
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
### Changed File Coverage
|
|
118
|
+
|
|
119
|
+
| File | Lines (Δ) | Test Count | Coverage |
|
|
120
|
+
|------|-----------|------------|----------|
|
|
121
|
+
| `src/opencode/tools.ts` | +18/-3 | 3 regression tests | ⚠️ Low (no per-file coverage tool) |
|
|
122
|
+
| `src/opencode/plugin.ts` | +7/-6 | 2 regression tests | ⚠️ Low (no per-file coverage tool) |
|
|
123
|
+
| `src/core/discovery.ts` | +8/-5 | 4 regression tests | ⚠️ Low (no per-file coverage tool) |
|
|
124
|
+
|
|
125
|
+
**Average changed file coverage**: ➖ Not available (no coverage tool detected)
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
### Assertion Quality
|
|
130
|
+
|
|
131
|
+
| File | Line | Assertion | Issue | Severity |
|
|
132
|
+
|------|------|-----------|-------|----------|
|
|
133
|
+
| — | — | — | — | — |
|
|
134
|
+
|
|
135
|
+
**Assertion quality**: ✅ All assertions verify real behavior (no tautologies, no ghost loops, no smoke-only tests)
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
### Issues Found
|
|
140
|
+
|
|
141
|
+
**CRITICAL**: None
|
|
142
|
+
**WARNING**: None
|
|
143
|
+
**SUGGESTION**: None
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
### Notable Observations
|
|
148
|
+
|
|
149
|
+
1. **Dedupe assertion nuance**: The dedupe tests correctly assert that the *loaded* skill is *filtered out* of `<skill-evaluation-required>` injections — not that zero injections fire (other skills may match the same query tokens). This is the correct regression target per the apply-progress discovery log.
|
|
150
|
+
|
|
151
|
+
2. **maxDepth deviation from c2d8e74 baseline**: Pre-refactor `c2d8e74` used `maxDepth: 1` for Claude-side roots; commit `12de52a` widened to 3 deliberately. The JSDoc in `discovery.ts` now documents this intentionally and the regression net locks `maxDepth: 3` in place.
|
|
152
|
+
|
|
153
|
+
3. **Plugin/marketplace discovery out of scope**: The `c2d8e74` baseline also surfaced `~/.claude/plugins/cache/` and `~/.claude/plugins/marketplaces/`. The proposal correctly scoped this fix to the four standard locations only.
|
|
154
|
+
|
|
155
|
+
4. **Callback already existed in UseSkill**: `UseSkill` already accepted `onSkillLoaded?` before the fix. `createSkillTools` simply never accepted or forwarded it. The fix is a minimal 2-line production code change.
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
### Verdict
|
|
160
|
+
|
|
161
|
+
**PASS**
|
|
162
|
+
|
|
163
|
+
All 9 tasks complete. All 7 spec scenarios have covering tests that pass. All 3 design decisions are implemented correctly and coherently. Typecheck clean; 102/102 tests green. Strict TDD protocol was followed (RED → GREEN → REFACTOR per task). No critical issues, warnings, or suggestions.
|
|
164
|
+
|
|
165
|
+
**Next recommended**: sdd-archive
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Core Decoupling Specification
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
This spec defines the boundary between the portable core skills engine and the OpenCode-specific adapter in the `opencode-agent-skills-md` package. It guarantees that the core is reusable by any host while OpenCode users see no behavior change. This domain is introduced by the `skills-core-decouple` change; there is no prior baseline to delta against, so this file is the initial full definition.
|
|
6
|
+
|
|
7
|
+
## Requirements
|
|
8
|
+
|
|
9
|
+
### Requirement: Core Module Independence (R1)
|
|
10
|
+
|
|
11
|
+
The `src/core/**` module graph SHALL contain zero runtime imports from `@opencode-ai/plugin`. A static import walk (AST or regex over the compiled dependency graph of `src/core/**`) SHALL fail the build if any such import is detected.
|
|
12
|
+
|
|
13
|
+
### Requirement: Boundary Interface Location (R2)
|
|
14
|
+
|
|
15
|
+
The interfaces `SkillHostClient` and `SkillHostSession` SHALL be declared in `src/core/types.ts`. The concrete OpenCode implementation of those interfaces SHALL exist only in `src/opencode/host.ts`. No other module SHALL contain a concrete implementation of either interface.
|
|
16
|
+
|
|
17
|
+
### Requirement: Backward-Compatible Root Export (R3)
|
|
18
|
+
|
|
19
|
+
Importing `opencode-agent-skills-md` (the package root) SHALL return the OpenCode plugin with the same shape and behavior as before this change. The four tool names (`use_skill`, `read_skill_file`, `run_skill_script`, `get_available_skills`) SHALL resolve. Additionally, `use_skill` SHALL visibly load a skill: the `onSkillLoaded` callback registered with `createSkillTools` SHALL fire exactly once per successful load per session, the loaded skill's `SKILL.md` content SHALL be injected into the agent context exactly once per session per skill, and the host SHALL observe the loaded-skill state update (TUI icon visible). The callback SHALL be threaded from `src/opencode/plugin.ts` → `createSkillTools` → `UseSkill`.
|
|
20
|
+
|
|
21
|
+
### Requirement: Framework-Agnostic Subpath Export (R4)
|
|
22
|
+
|
|
23
|
+
Importing `opencode-agent-skills-md/core` SHALL resolve to the core modules only. A smoke import of the subpath SHALL NOT trigger any side effect, top-level await, or transitive import from `@opencode-ai/plugin`.
|
|
24
|
+
|
|
25
|
+
### Requirement: Discovery Semantics Preservation (R5)
|
|
26
|
+
|
|
27
|
+
When the OpenCode adapter delegates to the core's `discoverAllSkills()`, the adapter SHALL observe the same four-location priority and first-match-wins semantics defined by the existing skill behavior. The set of skills surfaced for the baseline fixture locations SHALL match the set surfaced by pre-refactor commit `c2d8e74`. An integration test that mirrors `tests/integration/*` SHALL pass against the new boundary.
|
|
28
|
+
|
|
29
|
+
### Requirement: Public Surface Freeze (R6)
|
|
30
|
+
|
|
31
|
+
The four tool names, their parameter shapes, and their user-visible error messages SHALL remain unchanged. Existing tests under `tests/integration/*` and `tests/e2e/*` SHALL pass without modification.
|
|
32
|
+
|
|
33
|
+
## Scenarios
|
|
34
|
+
|
|
35
|
+
### Scenario: core is decoupled from the OpenCode SDK
|
|
36
|
+
|
|
37
|
+
- GIVEN the `src/core/**` module graph is fully composed
|
|
38
|
+
- WHEN a static import walk scans every file in that graph for `from "@opencode-ai/plugin"`
|
|
39
|
+
- THEN zero matches are reported
|
|
40
|
+
- AND the test `tests/core/agnostic.test.ts` passes
|
|
41
|
+
|
|
42
|
+
### Scenario: opencode host is the only concrete implementation
|
|
43
|
+
|
|
44
|
+
- GIVEN the interfaces `SkillHostClient` and `SkillHostSession` exist in `src/core/types.ts`
|
|
45
|
+
- WHEN the codebase is searched for classes or factories that implement either interface
|
|
46
|
+
- THEN exactly one match exists, located in `src/opencode/host.ts`
|
|
47
|
+
|
|
48
|
+
#### Scenario: root export still loads the OpenCode plugin
|
|
49
|
+
|
|
50
|
+
- GIVEN a consumer imports the package via its root export
|
|
51
|
+
- WHEN the consumer resolves the four tool names from the returned plugin object
|
|
52
|
+
- THEN all four tool names (`use_skill`, `read_skill_file`, `run_skill_script`, `get_available_skills`) are present
|
|
53
|
+
- AND the test-skill load assertion in `tests/integration/startup-smoke.test.ts` passes
|
|
54
|
+
|
|
55
|
+
#### Scenario: use_skill fires the onSkillLoaded callback
|
|
56
|
+
|
|
57
|
+
- GIVEN the host registered an `onSkillLoaded` callback via `createSkillTools`
|
|
58
|
+
- WHEN the agent calls `use_skill("test-skill")` on an unloaded skill
|
|
59
|
+
- THEN the callback is invoked exactly once with the loaded skill identifier
|
|
60
|
+
- AND the loaded skill's `SKILL.md` content is present in the agent context
|
|
61
|
+
- AND the host's loaded-skill state reflects the new skill
|
|
62
|
+
|
|
63
|
+
#### Scenario: use_skill does not re-inject the same skill in one session
|
|
64
|
+
|
|
65
|
+
- GIVEN the agent has already loaded a given skill via `use_skill` in the current session
|
|
66
|
+
- WHEN the agent calls `use_skill` with the same skill name again in the same session
|
|
67
|
+
- THEN `onSkillLoaded` is NOT re-fired for that skill
|
|
68
|
+
- AND the `SKILL.md` content is NOT re-injected into the context
|
|
69
|
+
|
|
70
|
+
#### Scenario: missing callback does not break the load
|
|
71
|
+
|
|
72
|
+
- GIVEN no `onSkillLoaded` is registered with `createSkillTools`
|
|
73
|
+
- WHEN the agent calls `use_skill("any-skill")`
|
|
74
|
+
- THEN the skill still loads and `SKILL.md` content is injected
|
|
75
|
+
- AND no thrown error or unhandled rejection occurs
|
|
76
|
+
|
|
77
|
+
### Scenario: subpath export does not pull in the OpenCode SDK
|
|
78
|
+
|
|
79
|
+
- GIVEN a consumer imports `opencode-agent-skills-md/core` in a fresh process
|
|
80
|
+
- WHEN the import resolves and the module graph is recorded
|
|
81
|
+
- THEN no module under `node_modules/@opencode-ai/plugin` appears in the resolved graph
|
|
82
|
+
- AND no side effect from the SDK runs at import time
|
|
83
|
+
|
|
84
|
+
#### Scenario: discovery priority and first-match-wins are preserved
|
|
85
|
+
|
|
86
|
+
- GIVEN skill fixtures exist under `.opencode/skills/`, `.claude/skills/`, `~/.config/opencode/skills/`, and `~/.claude/skills/`
|
|
87
|
+
- WHEN the OpenCode adapter calls `discoverAllSkills()`
|
|
88
|
+
- THEN the returned list follows the four-location priority
|
|
89
|
+
- AND duplicate skill names resolve to the first matching location
|
|
90
|
+
- AND the new integration test in `tests/core/` passes
|
|
91
|
+
|
|
92
|
+
#### Scenario: discoverAllSkills matches the pre-refactor skill set
|
|
93
|
+
|
|
94
|
+
- GIVEN the same fixture tree used by pre-refactor commit `c2d8e74`
|
|
95
|
+
- WHEN the OpenCode adapter calls `discoverAllSkills()`
|
|
96
|
+
- THEN every skill the baseline surfaced is also surfaced now
|
|
97
|
+
- AND no skill the baseline surfaced is missing from the result
|
|
98
|
+
|
|
99
|
+
#### Scenario: literal-token search does not drop the pre-refactor skill set
|
|
100
|
+
|
|
101
|
+
- GIVEN a skill whose trigger tokens are partial substrings of the user's query (not exact match)
|
|
102
|
+
- WHEN the user searches via the literal-token path in `discoverAllSkills()`
|
|
103
|
+
- THEN that skill appears in the result
|
|
104
|
+
- AND the four-location priority remains consistent with first-match-wins
|
|
105
|
+
|
|
106
|
+
### Scenario: public tool surface is unchanged
|
|
107
|
+
|
|
108
|
+
- GIVEN the refactor is complete and `pnpm run typecheck` is clean
|
|
109
|
+
- WHEN `pnpm test` runs the existing `tests/integration/*` and `tests/e2e/*` suites
|
|
110
|
+
- THEN all existing assertions on tool names, parameter shapes, and error messages continue to pass without modification
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "opencode-agent-skills-md",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "pnpm workspace root for opencode-agent-skills-md. The user-facing OpenCode plugin lives at packages/opencode-agent-skills-md and the portable engine at packages/core. This manifest exists only to wire the workspace — it has no exports of its own; consumers install one of the workspace packages directly.",
|
|
6
|
+
"author": "Josh Thomas <josh@joshthomas.dev>",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/MetalbolicX/opencode-agent-skills-md.git"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"opencode",
|
|
14
|
+
"plugin",
|
|
15
|
+
"skills",
|
|
16
|
+
"agent",
|
|
17
|
+
"ai"
|
|
18
|
+
],
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=18.0.0"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/node": "^25.9.1",
|
|
24
|
+
"tsx": "^4.22.3",
|
|
25
|
+
"typescript": "^6.0.3",
|
|
26
|
+
"opencode-agent-skills-md": "0.7.0",
|
|
27
|
+
"opencode-agent-skills-md-core": "0.0.0"
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "pnpm -r --workspace-concurrency=1 run build",
|
|
31
|
+
"test": "pnpm -r --no-bail --workspace-concurrency=1 test && node --import tsx --test tests/workspace.test.ts",
|
|
32
|
+
"test:workspace": "node --import tsx --test tests/workspace.test.ts",
|
|
33
|
+
"typecheck": "pnpm -r --workspace-concurrency=1 run typecheck"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "opencode-agent-skills-md-core",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"description": "Portable skills engine for opencode-agent-skills-md. Host-agnostic discovery, parsing, search, and host-boundary contracts.",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "src/index.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./src/index.ts",
|
|
11
|
+
"import": "./src/index.ts",
|
|
12
|
+
"default": "./src/index.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"src"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"test": "node --import tsx --test \"tests/**/*.test.ts\"",
|
|
20
|
+
"typecheck": "tsc --noEmit"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"yaml": "^2.9.0"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/node": "^25.9.1",
|
|
27
|
+
"tsx": "^4.22.3",
|
|
28
|
+
"typescript": "^6.0.3"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content formatting helpers for skill listings and synthetic injections.
|
|
3
|
+
*
|
|
4
|
+
* Pure functions: string assembly only, no host dependencies.
|
|
5
|
+
*/
|
|
6
|
+
import type { Skill } from "./types";
|
|
7
|
+
/**
|
|
8
|
+
* Format a list of skills as the inner bullet block used inside the
|
|
9
|
+
* `<available-skills>` synthetic injection.
|
|
10
|
+
*/
|
|
11
|
+
export declare function formatSkillListing(skills: Skill[]): string;
|
|
12
|
+
/**
|
|
13
|
+
* Render the full `<available-skills>...</available-skills>` block that the
|
|
14
|
+
* host injects into a session on startup and after compaction.
|
|
15
|
+
*/
|
|
16
|
+
export declare function renderAvailableSkillsBlock(skills: Skill[]): string;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content formatting helpers for skill listings and synthetic injections.
|
|
3
|
+
*
|
|
4
|
+
* Pure functions: string assembly only, no host dependencies.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { Skill } from "./types";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Format a list of skills as the inner bullet block used inside the
|
|
11
|
+
* `<available-skills>` synthetic injection.
|
|
12
|
+
*/
|
|
13
|
+
export const formatSkillListing = (skills: Skill[]): string => {
|
|
14
|
+
return skills
|
|
15
|
+
.map((s) => `- ${s.name}: ${s.description}`)
|
|
16
|
+
.join("\n");
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Render the full `<available-skills>...</available-skills>` block that the
|
|
21
|
+
* host injects into a session on startup and after compaction.
|
|
22
|
+
*/
|
|
23
|
+
export const renderAvailableSkillsBlock = (skills: Skill[]): string => {
|
|
24
|
+
const skillsList = formatSkillListing(skills);
|
|
25
|
+
return `<available-skills>
|
|
26
|
+
Use the use_skill, read_skill_file, run_skill_script, and get_available_skills tools to work with skills.
|
|
27
|
+
|
|
28
|
+
${skillsList}
|
|
29
|
+
</available-skills>`;
|
|
30
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Debug-gated logging for bare `catch {}` blocks.
|
|
3
|
+
*
|
|
4
|
+
* Bare catches stay silent by default so malformed payloads and parse
|
|
5
|
+
* errors never surface as user-visible noise. Setting
|
|
6
|
+
* `OPENCODE_AGENT_SKILLS_DEBUG=1` makes the diagnostic context appear on
|
|
7
|
+
* stderr so developers can trace why a fallback fired.
|
|
8
|
+
*
|
|
9
|
+
* The env var is checked on every call (not cached at module load) so
|
|
10
|
+
* tests can toggle it without re-importing the module.
|
|
11
|
+
*/
|
|
12
|
+
export const debugLog = (...args: unknown[]): void => {
|
|
13
|
+
if (!process.env.OPENCODE_AGENT_SKILLS_DEBUG) return;
|
|
14
|
+
// eslint-disable-next-line no-console
|
|
15
|
+
console.error("[opencode-agent-skills-md]", ...args);
|
|
16
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill discovery across filesystem roots.
|
|
3
|
+
*
|
|
4
|
+
* The core never hard-codes a host's directory layout. Callers pass the list
|
|
5
|
+
* of discovery roots; the default `getDefaultOpencodeRoots` reproduces the
|
|
6
|
+
* legacy OpenCode priority order. PR2 will call `discoverAllSkills` from the
|
|
7
|
+
* OpenCode host adapter with the same default.
|
|
8
|
+
*/
|
|
9
|
+
import type { DiscoveryPath, FileDiscoveryResult, LabeledDiscoveryResult, Skill, SkillLabel } from "./types";
|
|
10
|
+
/**
|
|
11
|
+
* Check if a file exists in a directory and return path info.
|
|
12
|
+
*
|
|
13
|
+
* @param directory - Directory to check
|
|
14
|
+
* @param relativePath - Relative path to use in result (caller-specific)
|
|
15
|
+
* @param filename - Name of file to look for (e.g., 'SKILL.md')
|
|
16
|
+
* @returns Path info if file exists, null otherwise
|
|
17
|
+
*/
|
|
18
|
+
export declare function findFile(directory: string, relativePath: string, filename: string): Promise<FileDiscoveryResult | null>;
|
|
19
|
+
/**
|
|
20
|
+
* Recursively find SKILL.md files in a directory.
|
|
21
|
+
*
|
|
22
|
+
* The base directory itself is checked first: a SKILL.md placed at the root
|
|
23
|
+
* of a discovery root is returned with `relativePath = ""` and wins the
|
|
24
|
+
* shadowing tie-break over same-name skills in subdirectories (first found
|
|
25
|
+
* wins in `discoverAllSkills`).
|
|
26
|
+
*/
|
|
27
|
+
export declare function findSkillsRecursive(baseDir: string, label: SkillLabel, maxDepth?: number): Promise<LabeledDiscoveryResult[]>;
|
|
28
|
+
/**
|
|
29
|
+
* Default discovery roots matching the pre-refactor OpenCode priority order
|
|
30
|
+
* (see commit `c2d8e74`, `src/skills.ts#discoverAllSkills`):
|
|
31
|
+
* 1. .opencode/skills/ (project - OpenCode)
|
|
32
|
+
* 2. .claude/skills/ (project - Claude)
|
|
33
|
+
* 3. ~/.config/opencode/skills/ (user - OpenCode)
|
|
34
|
+
* 4. ~/.claude/skills/ (user - Claude)
|
|
35
|
+
*
|
|
36
|
+
* No shadowing - unique names only. First match wins, duplicates are warned.
|
|
37
|
+
*/
|
|
38
|
+
export declare function getDefaultOpencodeRoots(directory: string): DiscoveryPath[];
|
|
39
|
+
/**
|
|
40
|
+
* Default callback for shadowed skill names. Emits a `console.warn` that
|
|
41
|
+
* identifies the surviving (existing) skill and the duplicate that was
|
|
42
|
+
* skipped. Hosts can override by passing `onDuplicate` to `discoverAllSkills`.
|
|
43
|
+
*
|
|
44
|
+
* @internal - exported for testing
|
|
45
|
+
*/
|
|
46
|
+
export declare const defaultOnDuplicate: (existing: Skill, duplicate: Skill) => void;
|
|
47
|
+
/**
|
|
48
|
+
* Discover all skills from the provided roots.
|
|
49
|
+
*
|
|
50
|
+
* @param directory - Project directory (used to build the default roots).
|
|
51
|
+
* @param roots - Discovery roots. Defaults to the OpenCode priority order
|
|
52
|
+
* via `getDefaultOpencodeRoots(directory)`. Hosts pass an explicit list to
|
|
53
|
+
* override the layout.
|
|
54
|
+
* @param onDuplicate - Optional callback invoked when two roots produce a
|
|
55
|
+
* skill with the same `name`. Defaults to `console.warn` via
|
|
56
|
+
* `defaultOnDuplicate`. The first-discovered skill wins; the duplicate
|
|
57
|
+
* (second one encountered) is passed to the callback but never stored.
|
|
58
|
+
*/
|
|
59
|
+
export declare function discoverAllSkills(directory: string, roots?: DiscoveryPath[], onDuplicate?: (existing: Skill, duplicate: Skill) => void): Promise<Map<string, Skill>>;
|
|
60
|
+
/**
|
|
61
|
+
* Resolve a skill by name, handling namespace prefixes.
|
|
62
|
+
* Supports: "skill-name", "project:skill-name", "user:skill-name", etc.
|
|
63
|
+
*/
|
|
64
|
+
export declare function resolveSkill(skillName: string, skillsByName: Map<string, Skill>): Skill | null;
|
|
65
|
+
/**
|
|
66
|
+
* Recursively list all files in a directory, returning relative paths.
|
|
67
|
+
* Excludes SKILL.md since it's already loaded as the main content.
|
|
68
|
+
*/
|
|
69
|
+
export declare function listSkillFiles(skillPath: string, maxDepth?: number): Promise<string[]>;
|
|
70
|
+
/**
|
|
71
|
+
* Get summaries of all available skills (name, description, trigger).
|
|
72
|
+
* Used by preflight LLM call to evaluate which skills are relevant and
|
|
73
|
+
* by the plugin's keyword matcher to rank matched skills.
|
|
74
|
+
*
|
|
75
|
+
* The `trigger` frontmatter key (PR 2 of `trigger-aware-skill-discovery`)
|
|
76
|
+
* is threaded through so the keyword matcher can apply the 1.5x trigger
|
|
77
|
+
* tier and the targeted outputs can render trigger text.
|
|
78
|
+
*
|
|
79
|
+
* @param directory - Project directory to discover skills from
|
|
80
|
+
* @returns Array of skill summaries
|
|
81
|
+
*/
|
|
82
|
+
export declare function getSkillSummaries(directory: string): Promise<Array<{
|
|
83
|
+
name: string;
|
|
84
|
+
description: string;
|
|
85
|
+
trigger?: string;
|
|
86
|
+
}>>;
|