opencode-agent-skills-md 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +770 -0
- package/dist/plugin.mjs +1138 -0
- package/dist/src/cli/config.d.ts +144 -0
- package/dist/src/cli/install.d.ts +33 -0
- package/dist/src/cli/main.d.ts +11 -0
- package/dist/src/cli/real-fs.d.ts +6 -0
- package/dist/src/cli/status.d.ts +34 -0
- package/dist/src/cli/uninstall.d.ts +22 -0
- package/dist/src/host.d.ts +51 -0
- package/dist/src/index.d.ts +17 -0
- package/dist/src/plugin.d.ts +35 -0
- package/dist/src/sdk.d.ts +51 -0
- package/dist/src/tools.d.ts +86 -0
- package/package.json +48 -18
- package/.beads/.local_version +0 -1
- package/.beads/README.md +0 -81
- package/.beads/config.yaml +0 -61
- package/.beads/deletions.jsonl +0 -1
- package/.beads/issues.jsonl +0 -64
- package/.beads/metadata.json +0 -4
- package/.gitattributes +0 -3
- package/.github/CODEOWNERS +0 -1
- package/.github/copilot-instructions.md +0 -78
- package/.github/dependabot.yml +0 -13
- package/.github/workflows/release.yml +0 -51
- package/.opencode/command/test-compaction.md +0 -9
- package/.opencode/command/test-find-skills.md +0 -7
- package/.opencode/command/test-read-skill-file.md +0 -14
- package/.opencode/command/test-run-skill-script.md +0 -13
- package/.opencode/command/test-skills.md +0 -14
- package/.opencode/command/test-use-skill.md +0 -10
- package/.opencode/skills/git-helper/SKILL.md +0 -65
- package/.opencode/skills/test-skill/SKILL.md +0 -43
- package/.opencode/skills/test-skill/example-config.json +0 -16
- package/.opencode/skills/test-skill/helper-docs.md +0 -29
- package/.opencode/skills/test-skill/scripts/echo-args +0 -14
- package/.opencode/skills/test-skill/scripts/greet +0 -6
- package/AGENTS.md +0 -43
- package/CHANGELOG.md +0 -178
- package/Justfile +0 -39
- package/README.md +0 -220
- package/openspec/changes/archive/2026-06-14-skills-core-decouple/specs/core-decoupling/spec.md +0 -74
- package/openspec/changes/archive/2026-06-14-skills-core-decouple/tasks.md +0 -64
- package/openspec/changes/archive/2026-06-14-skills-core-decouple/verify-report.md +0 -75
- package/openspec/changes/archive/2026-06-17-fix-skill-loading-regression/apply-progress.md +0 -136
- package/openspec/changes/archive/2026-06-17-fix-skill-loading-regression/archive-report.md +0 -77
- package/openspec/changes/archive/2026-06-17-fix-skill-loading-regression/design.md +0 -89
- package/openspec/changes/archive/2026-06-17-fix-skill-loading-regression/proposal.md +0 -65
- package/openspec/changes/archive/2026-06-17-fix-skill-loading-regression/specs/core-decoupling/spec.md +0 -77
- package/openspec/changes/archive/2026-06-17-fix-skill-loading-regression/tasks.md +0 -65
- package/openspec/changes/archive/2026-06-17-fix-skill-loading-regression/verify-report.md +0 -165
- package/openspec/specs/core-decoupling/spec.md +0 -110
- package/packages/core/package.json +0 -30
- package/packages/core/src/content.d.ts +0 -16
- package/packages/core/src/content.ts +0 -30
- package/packages/core/src/debug.ts +0 -16
- package/packages/core/src/discovery.d.ts +0 -86
- package/packages/core/src/discovery.ts +0 -257
- package/packages/core/src/index.d.ts +0 -20
- package/packages/core/src/index.ts +0 -55
- package/packages/core/src/match.d.ts +0 -19
- package/packages/core/src/match.ts +0 -75
- package/packages/core/src/parse.d.ts +0 -26
- package/packages/core/src/parse.ts +0 -141
- package/packages/core/src/scripts.d.ts +0 -17
- package/packages/core/src/scripts.ts +0 -79
- package/packages/core/src/search.d.ts +0 -83
- package/packages/core/src/search.ts +0 -188
- package/packages/core/src/types.d.ts +0 -82
- package/packages/core/src/types.ts +0 -131
- package/packages/core/src/walk.ts +0 -109
- package/packages/core/tests/agnostic.test.ts +0 -346
- package/packages/core/tests/content.test.ts +0 -65
- package/packages/core/tests/discovery.test.ts +0 -370
- package/packages/core/tests/package-boundary.test.ts +0 -310
- package/packages/core/tests/parse-trigger.test.ts +0 -282
- package/packages/core/tests/search.test.ts +0 -374
- package/packages/core/tests/subpath.test.ts +0 -87
- package/packages/core/tsconfig.json +0 -10
- package/packages/opencode-agent-skills-md/package.json +0 -66
- package/packages/opencode-agent-skills-md/rolldown.config.js +0 -47
- package/packages/opencode-agent-skills-md/tests/cli-commands.test.ts +0 -1423
- package/packages/opencode-agent-skills-md/tests/e2e/startup-smoke.test.ts +0 -66
- package/packages/opencode-agent-skills-md/tests/fixtures/skills/home/.claude/skills/claude-user-only-skill/SKILL.md +0 -8
- package/packages/opencode-agent-skills-md/tests/fixtures/skills/home/.config/opencode/skills/shared-skill/SKILL.md +0 -8
- package/packages/opencode-agent-skills-md/tests/fixtures/skills/home/.config/opencode/skills/user-only-skill/SKILL.md +0 -8
- package/packages/opencode-agent-skills-md/tests/fixtures/skills/project/.claude/skills/claude-project-only-skill/SKILL.md +0 -8
- package/packages/opencode-agent-skills-md/tests/fixtures/skills/project/.opencode/skills/go-tester/SKILL.md +0 -12
- package/packages/opencode-agent-skills-md/tests/fixtures/skills/project/.opencode/skills/nested/team/nested-skill/SKILL.md +0 -8
- package/packages/opencode-agent-skills-md/tests/fixtures/skills/project/.opencode/skills/rust-tester/SKILL.md +0 -11
- package/packages/opencode-agent-skills-md/tests/fixtures/skills/project/.opencode/skills/scripted-skill/SKILL.md +0 -8
- package/packages/opencode-agent-skills-md/tests/fixtures/skills/project/.opencode/skills/scripted-skill/bin/echo.sh +0 -2
- package/packages/opencode-agent-skills-md/tests/fixtures/skills/project/.opencode/skills/scripted-skill/docs/reference.md +0 -1
- package/packages/opencode-agent-skills-md/tests/fixtures/skills/project/.opencode/skills/shared-skill/SKILL.md +0 -8
- package/packages/opencode-agent-skills-md/tests/fixtures/skills/project/.opencode/skills/using-superpowers/SKILL.md +0 -8
- package/packages/opencode-agent-skills-md/tests/integration/helpers/mock-opencode.ts +0 -114
- package/packages/opencode-agent-skills-md/tests/integration/plugin.test.ts +0 -316
- package/packages/opencode-agent-skills-md/tests/integration/skill-discovery.test.ts +0 -315
- package/packages/opencode-agent-skills-md/tests/opencode/host.test.ts +0 -179
- package/packages/opencode-agent-skills-md/tests/opencode/plugin.test.ts +0 -551
- package/packages/opencode-agent-skills-md/tests/opencode/subpath.test.ts +0 -66
- package/packages/opencode-agent-skills-md/tests/opencode/tools.test.ts +0 -213
- package/packages/opencode-agent-skills-md/tests/package-boundary.test.ts +0 -345
- package/packages/opencode-agent-skills-md/tests/tools-security.test.ts +0 -72
- package/packages/opencode-agent-skills-md/tsconfig.build.json +0 -11
- package/packages/opencode-agent-skills-md/tsconfig.json +0 -10
- package/plans/001-ci-gate.md +0 -177
- package/plans/002-is-path-safe.md +0 -243
- package/plans/003-escape-prompts.md +0 -310
- package/plans/004-test-security-paths.md +0 -228
- package/plans/005-stop-swallowing-errors.md +0 -246
- package/plans/006-preserve-jsonc-commas.md +0 -144
- package/plans/007-write-before-purge.md +0 -144
- package/plans/008-reuse-walkdir-for-list-skill-files.md +0 -164
- package/plans/README.md +0 -43
- package/pnpm-workspace.yaml +0 -6
- package/tests/workspace.test.ts +0 -367
- package/tsconfig.json +0 -15
- /package/{packages/opencode-agent-skills-md/src → src}/cli/config.ts +0 -0
- /package/{packages/opencode-agent-skills-md/src → src}/cli/install.ts +0 -0
- /package/{packages/opencode-agent-skills-md/src → src}/cli/main.ts +0 -0
- /package/{packages/opencode-agent-skills-md/src → src}/cli/real-fs.ts +0 -0
- /package/{packages/opencode-agent-skills-md/src → src}/cli/status.ts +0 -0
- /package/{packages/opencode-agent-skills-md/src → src}/cli/uninstall.ts +0 -0
- /package/{packages/opencode-agent-skills-md/src → src}/host.ts +0 -0
- /package/{packages/opencode-agent-skills-md/src → src}/index.ts +0 -0
- /package/{packages/opencode-agent-skills-md/src → src}/plugin.ts +0 -0
- /package/{packages/opencode-agent-skills-md/src → src}/sdk.ts +0 -0
- /package/{packages/opencode-agent-skills-md/src → src}/tools.ts +0 -0
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
# Plan 005: Surface swallowed discovery and parse errors
|
|
2
|
-
|
|
3
|
-
> **Executor instructions**: Follow this plan step by step. Run every
|
|
4
|
-
> verification command and confirm the expected result before moving to the
|
|
5
|
-
> next step. If anything in the "STOP conditions" section occurs, stop and
|
|
6
|
-
> report — do not improvise. When done, update the status row for this plan
|
|
7
|
-
> in `plans/README.md`.
|
|
8
|
-
>
|
|
9
|
-
> **Drift check (run first)**: `git diff --stat fb45791..HEAD -- packages/core/src/discovery.ts packages/core/src/parse.ts packages/opencode-agent-skills-md/src/host.ts`
|
|
10
|
-
> If any in-scope file changed since this plan was written, compare the
|
|
11
|
-
> "Current state" excerpts against the live code before proceeding; on a
|
|
12
|
-
> mismatch, treat it as a STOP condition.
|
|
13
|
-
|
|
14
|
-
## Status
|
|
15
|
-
|
|
16
|
-
- **Priority**: P2
|
|
17
|
-
- **Effort**: S
|
|
18
|
-
- **Risk**: LOW
|
|
19
|
-
- **Depends on**: none
|
|
20
|
-
- **Category**: correctness
|
|
21
|
-
- **Planned at**: commit `fb45791`, 2026-06-29
|
|
22
|
-
|
|
23
|
-
## Why this matters
|
|
24
|
-
|
|
25
|
-
Four locations in the core and host packages silently swallow filesystem and
|
|
26
|
-
parse errors with bare `catch {}` blocks. When a discovery root is
|
|
27
|
-
inaccessible (permission denied), a SKILL.md file is corrupted, or a session
|
|
28
|
-
context lookup fails, the failure produces no diagnostic output. Users see
|
|
29
|
-
"no skills found" with no path to debug. Adding `debugLog` calls in these
|
|
30
|
-
catch blocks makes failures discoverable when
|
|
31
|
-
`OPENCODE_AGENT_SKILLS_DEBUG=1` is set, without changing the current
|
|
32
|
-
graceful-degradation behavior.
|
|
33
|
-
|
|
34
|
-
## Current state
|
|
35
|
-
|
|
36
|
-
### 1. `packages/core/src/discovery.ts:87` — outer catch in `findSkillsRecursive`
|
|
37
|
-
|
|
38
|
-
```ts
|
|
39
|
-
} catch { }
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
This wraps the entire `fs.access` + `walkDir` call. If `baseDir` exists but
|
|
43
|
-
is unreadable, the error is invisible.
|
|
44
|
-
|
|
45
|
-
### 2. `packages/core/src/discovery.ts:219` — inner catch in `listSkillFiles`
|
|
46
|
-
|
|
47
|
-
```ts
|
|
48
|
-
} catch { }
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
This wraps `fs.stat` per entry. If a file in the skill directory can't be
|
|
52
|
-
stat'd, the entry is silently skipped.
|
|
53
|
-
|
|
54
|
-
### 3. `packages/core/src/parse.ts:91` — catch on `fs.readFile`
|
|
55
|
-
|
|
56
|
-
```ts
|
|
57
|
-
const content = await fs.readFile(skillPath, 'utf-8').catch(() => null);
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
If a SKILL.md can't be read, returns `null` with no diagnostic.
|
|
61
|
-
|
|
62
|
-
Note: `parse.ts:107` (`try { parseYamlFrontmatter(...) } catch { return null; }`)
|
|
63
|
-
is excluded — `parseYamlFrontmatter` already logs errors via `debugLog` at
|
|
64
|
-
`parse.ts:38`.
|
|
65
|
-
|
|
66
|
-
### 4. `packages/opencode-agent-skills-md/src/host.ts:97` — catch in `getSessionContext`
|
|
67
|
-
|
|
68
|
-
```ts
|
|
69
|
-
} catch {
|
|
70
|
-
// Fall through to undefined - mirrors the legacy behaviour
|
|
71
|
-
}
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
If the session lookup fails, the error is swallowed. This is important for
|
|
75
|
-
privacy (session data should not leak in error messages), but a debug log
|
|
76
|
-
is safe.
|
|
77
|
-
|
|
78
|
-
Excluded by design:
|
|
79
|
-
- `walk.ts:100-103` per-entry isolation is documented as intentional.
|
|
80
|
-
- `parse.ts:25-26` YAML fallback to `{}` is documented as intentional.
|
|
81
|
-
- `discovery.ts:165-168` duplicate skill handling is documented as intentional.
|
|
82
|
-
|
|
83
|
-
Conventions:
|
|
84
|
-
- `debugLog` is imported in `discovery.ts` (not yet, but `parse.ts` imports it)
|
|
85
|
-
- The import is `import { debugLog } from "./debug"` from `packages/core/src/`
|
|
86
|
-
|
|
87
|
-
## Commands you will need
|
|
88
|
-
|
|
89
|
-
| Purpose | Command | Expected on success |
|
|
90
|
-
|-----------|--------------------------|---------------------|
|
|
91
|
-
| Typecheck | `pnpm run typecheck` | exit 0, no errors |
|
|
92
|
-
| Tests | `pnpm test` | all pass |
|
|
93
|
-
|
|
94
|
-
## Scope
|
|
95
|
-
|
|
96
|
-
**In scope** (the only files you should modify):
|
|
97
|
-
- `packages/core/src/discovery.ts` — add `debugLog` import and calls in catch blocks
|
|
98
|
-
- `packages/core/src/parse.ts` — add `debugLog` to the `readFile` catch at line 91
|
|
99
|
-
- `packages/opencode-agent-skills-md/src/host.ts` — add `debugLog` to the `getSessionContext` catch at line 97
|
|
100
|
-
|
|
101
|
-
**Out of scope** (do NOT touch):
|
|
102
|
-
- `walk.ts` — per-entry isolation is by-design
|
|
103
|
-
- `parse.ts` YAML error handling — already logs via `debugLog`
|
|
104
|
-
- `packages/core/src/scripts.ts` — catches there are intentional
|
|
105
|
-
- Any test files — the existing tests must pass unchanged
|
|
106
|
-
|
|
107
|
-
## Git workflow
|
|
108
|
-
|
|
109
|
-
- Branch: `advisor/005-stop-swallowing-errors`
|
|
110
|
-
- Commit per file (or single commit for all three)
|
|
111
|
-
- Do NOT push or open a PR unless instructed.
|
|
112
|
-
|
|
113
|
-
## Steps
|
|
114
|
-
|
|
115
|
-
### Step 1: Add `debugLog` imports where missing
|
|
116
|
-
|
|
117
|
-
Check which files already import `debugLog`:
|
|
118
|
-
|
|
119
|
-
- `packages/core/src/discovery.ts` — does NOT import `debugLog`. Add:
|
|
120
|
-
```ts
|
|
121
|
-
import { debugLog } from "./debug";
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
- `packages/core/src/parse.ts` — ALREADY imports `debugLog` at line 12. No change needed.
|
|
125
|
-
|
|
126
|
-
- `packages/opencode-agent-skills-md/src/host.ts` — does NOT import `debugLog`. Add:
|
|
127
|
-
```ts
|
|
128
|
-
import { debugLog } from "opencode-agent-skills-md-core";
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
### Step 2: Add `debugLog` to `findSkillsRecursive` catch in `discovery.ts:87`
|
|
132
|
-
|
|
133
|
-
Old:
|
|
134
|
-
```ts
|
|
135
|
-
} catch { }
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
New:
|
|
139
|
-
```ts
|
|
140
|
-
} catch (error) {
|
|
141
|
-
debugLog("findSkillsRecursive: cannot access baseDir", baseDir, error);
|
|
142
|
-
}
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
**Verify**: `grep -A2 'debugLog.*findSkillsRecursive' packages/core/src/discovery.ts` → matches
|
|
146
|
-
|
|
147
|
-
### Step 3: Add `debugLog` to `listSkillFiles` stat error in `discovery.ts:219`
|
|
148
|
-
|
|
149
|
-
Old:
|
|
150
|
-
```ts
|
|
151
|
-
} catch { }
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
New:
|
|
155
|
-
```ts
|
|
156
|
-
} catch (error) {
|
|
157
|
-
debugLog("listSkillFiles: cannot stat", fullPath, error);
|
|
158
|
-
}
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
**Verify**: `grep -A2 'debugLog.*listSkillFiles' packages/core/src/discovery.ts` → matches
|
|
162
|
-
|
|
163
|
-
### Step 4: Add `debugLog` to `parseSkillFile` file read in `parse.ts:91`
|
|
164
|
-
|
|
165
|
-
Old:
|
|
166
|
-
```ts
|
|
167
|
-
const content = await fs.readFile(skillPath, 'utf-8').catch(() => null);
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
New:
|
|
171
|
-
```ts
|
|
172
|
-
const content = await fs.readFile(skillPath, 'utf-8').catch((error) => {
|
|
173
|
-
debugLog("parseSkillFile: cannot read", skillPath, error);
|
|
174
|
-
return null;
|
|
175
|
-
});
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
**Verify**: `grep -A3 'parseSkillFile.*cannot read' packages/core/src/parse.ts` → matches
|
|
179
|
-
|
|
180
|
-
### Step 5: Add `debugLog` to `getSessionContext` catch in `host.ts:97`
|
|
181
|
-
|
|
182
|
-
Old:
|
|
183
|
-
```ts
|
|
184
|
-
} catch {
|
|
185
|
-
// Fall through to undefined - mirrors the legacy behaviour
|
|
186
|
-
}
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
New:
|
|
190
|
-
```ts
|
|
191
|
-
} catch (error) {
|
|
192
|
-
debugLog("getSessionContext: session lookup failed", sessionID, error);
|
|
193
|
-
// Fall through to undefined - mirrors the legacy behaviour
|
|
194
|
-
}
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
**Verify**: `grep 'debugLog.*getSessionContext' packages/opencode-agent-skills-md/src/host.ts` → matches
|
|
198
|
-
|
|
199
|
-
### Step 6: Typecheck
|
|
200
|
-
|
|
201
|
-
**Verify**: `pnpm run typecheck` → exit 0, no errors
|
|
202
|
-
|
|
203
|
-
### Step 7: Run tests
|
|
204
|
-
|
|
205
|
-
**Verify**: `pnpm test` → exit 0, all tests pass
|
|
206
|
-
|
|
207
|
-
## Test plan
|
|
208
|
-
|
|
209
|
-
No new tests needed — the `debugLog` function is gated behind
|
|
210
|
-
`OPENCODE_AGENT_SKILLS_DEBUG` and has no side effects when not set.
|
|
211
|
-
Existing tests that exercise the error paths will continue to pass
|
|
212
|
-
(same behavior) but will now log when the env var is set.
|
|
213
|
-
|
|
214
|
-
To manually verify, run with debug logging:
|
|
215
|
-
```bash
|
|
216
|
-
OPENCODE_AGENT_SKILLS_DEBUG=true pnpm test 2>&1 | grep '\[opencode-agent-skills-md\]'
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
## Done criteria
|
|
220
|
-
|
|
221
|
-
Machine-checkable. ALL must hold:
|
|
222
|
-
|
|
223
|
-
- [ ] `packages/core/src/discovery.ts` imports `debugLog` and calls it in both catch blocks with context
|
|
224
|
-
- [ ] `packages/core/src/parse.ts` logs via `debugLog` when `readFile` fails for a SKILL.md
|
|
225
|
-
- [ ] `packages/opencode-agent-skills-md/src/host.ts` imports `debugLog` and calls it in the `getSessionContext` catch
|
|
226
|
-
- [ ] `pnpm run typecheck` exits 0
|
|
227
|
-
- [ ] `pnpm test` exits 0
|
|
228
|
-
- [ ] No files outside the in-scope list are modified (`git status`)
|
|
229
|
-
- [ ] `plans/README.md` status row updated
|
|
230
|
-
|
|
231
|
-
## STOP conditions
|
|
232
|
-
|
|
233
|
-
Stop and report back (do not improvise) if:
|
|
234
|
-
|
|
235
|
-
- The import path for `debugLog` differs between the core and plugin packages (it does: core uses `"./debug"`, plugin uses `"opencode-agent-skills-md-core"`).
|
|
236
|
-
- A step's verification fails twice after a reasonable fix attempt.
|
|
237
|
-
- The fix appears to require touching an out-of-scope file.
|
|
238
|
-
- Adding `error` to the log output leaks any sensitive information (in `host.ts`, the `error` may contain session data — log only the error type, not the full error object).
|
|
239
|
-
|
|
240
|
-
## Maintenance notes
|
|
241
|
-
|
|
242
|
-
- If a more structured logging system replaces `debugLog` in the future,
|
|
243
|
-
these catch blocks will emit through the new system automatically.
|
|
244
|
-
- The `host.ts` catch in `getSessionContext` should avoid logging the full
|
|
245
|
-
error object if it might contain session payload data. If unsure, log
|
|
246
|
-
only `(error as Error).name` and `(error as Error).message`.
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
# Plan 006: Preserve commas inside JSONC string values
|
|
2
|
-
|
|
3
|
-
> **Executor instructions**: Follow this plan step by step. Run every
|
|
4
|
-
> verification command before moving on. If a STOP condition occurs, stop
|
|
5
|
-
> and report instead of improvising. When done, update the status row for
|
|
6
|
-
> this plan in `plans/README.md`.
|
|
7
|
-
>
|
|
8
|
-
> **Drift check (run first)**:
|
|
9
|
-
> `git diff --stat 9c57cb0..HEAD -- packages/opencode-agent-skills-md/src/cli/config.ts packages/opencode-agent-skills-md/tests/cli-commands.test.ts`
|
|
10
|
-
> If any in-scope file changed since this plan was written, compare the
|
|
11
|
-
> Current state excerpts below against live code first. Any mismatch is a
|
|
12
|
-
> STOP condition.
|
|
13
|
-
|
|
14
|
-
## Status
|
|
15
|
-
|
|
16
|
-
- **Priority**: P1
|
|
17
|
-
- **Effort**: S
|
|
18
|
-
- **Risk**: LOW
|
|
19
|
-
- **Depends on**: none
|
|
20
|
-
- **Category**: bug
|
|
21
|
-
- **Planned at**: commit `9c57cb0`, 2026-07-03
|
|
22
|
-
|
|
23
|
-
## Why this matters
|
|
24
|
-
|
|
25
|
-
`parseJsonc()` currently strips trailing commas with a regex applied to the
|
|
26
|
-
entire post-comment text. That regex does not respect string boundaries, so a
|
|
27
|
-
valid string value containing `,}` or `,]` is silently mutated before
|
|
28
|
-
`JSON.parse()` runs. This is a real data-corruption bug in the CLI config
|
|
29
|
-
loader, and the fix is narrow.
|
|
30
|
-
|
|
31
|
-
## Current state
|
|
32
|
-
|
|
33
|
-
- `packages/opencode-agent-skills-md/src/cli/config.ts` — CLI config parsing helpers used by install, uninstall, status, and doctor.
|
|
34
|
-
- `packages/opencode-agent-skills-md/tests/cli-commands.test.ts` — existing characterization tests for `parseJsonc()` and other CLI helpers.
|
|
35
|
-
|
|
36
|
-
Relevant excerpts:
|
|
37
|
-
|
|
38
|
-
- `packages/opencode-agent-skills-md/src/cli/config.ts:204-255`
|
|
39
|
-
- `stripJsoncComments()` already tracks `inString` and `escaped` while removing comments.
|
|
40
|
-
- It ends with: `return out.replace(/,(\s*[}\]])/g, "$1");`
|
|
41
|
-
- `packages/opencode-agent-skills-md/tests/cli-commands.test.ts:272-319`
|
|
42
|
-
- Existing tests cover empty input, comments, escaped quotes, and ordinary trailing commas.
|
|
43
|
-
- There is no test proving commas inside string literals survive unchanged.
|
|
44
|
-
|
|
45
|
-
Conventions to match:
|
|
46
|
-
|
|
47
|
-
- CLI helper tests live in `packages/opencode-agent-skills-md/tests/cli-commands.test.ts`.
|
|
48
|
-
- Keep the implementation minimal and local; do not introduce a new parser dependency.
|
|
49
|
-
- Preserve the current graceful behavior: comments are stripped, trailing commas still work, malformed JSON still throws.
|
|
50
|
-
|
|
51
|
-
## Commands you will need
|
|
52
|
-
|
|
53
|
-
| Purpose | Command | Expected on success |
|
|
54
|
-
|---|---|---|
|
|
55
|
-
| Typecheck | `pnpm run typecheck` | exit 0 |
|
|
56
|
-
| Targeted tests | `pnpm -F opencode-agent-skills-md exec node --import tsx --test tests/cli-commands.test.ts` | all pass |
|
|
57
|
-
| Full tests | `pnpm test` | all pass |
|
|
58
|
-
|
|
59
|
-
## Scope
|
|
60
|
-
|
|
61
|
-
**In scope** (the only files you should modify):
|
|
62
|
-
- `packages/opencode-agent-skills-md/src/cli/config.ts`
|
|
63
|
-
- `packages/opencode-agent-skills-md/tests/cli-commands.test.ts`
|
|
64
|
-
|
|
65
|
-
**Out of scope**:
|
|
66
|
-
- Any CLI command behavior beyond config parsing correctness
|
|
67
|
-
- Any release workflow or docs change
|
|
68
|
-
- Any new dependency
|
|
69
|
-
|
|
70
|
-
## Git workflow
|
|
71
|
-
|
|
72
|
-
- Branch: `advisor/006-preserve-jsonc-commas`
|
|
73
|
-
- Commit style: conventional commits, for example `fix(cli): preserve commas inside JSONC strings`
|
|
74
|
-
- Do NOT push or open a PR unless instructed
|
|
75
|
-
|
|
76
|
-
## Steps
|
|
77
|
-
|
|
78
|
-
### Step 1: Add a failing regression test for string-preservation
|
|
79
|
-
|
|
80
|
-
Extend `describe("parseJsonc", ...)` in `packages/opencode-agent-skills-md/tests/cli-commands.test.ts`.
|
|
81
|
-
|
|
82
|
-
Add at least these cases:
|
|
83
|
-
|
|
84
|
-
- A string containing `,}` such as `{"doc":"keep ,} inside string","plugin":["a",],}`
|
|
85
|
-
- A string containing `,]` such as `{"doc":"keep ,] inside string","list":[1,2,],}`
|
|
86
|
-
- A nested mixed case with both string patterns and structural trailing commas
|
|
87
|
-
|
|
88
|
-
The assertions must prove both:
|
|
89
|
-
- trailing commas are still removed structurally
|
|
90
|
-
- string content is unchanged byte-for-byte
|
|
91
|
-
|
|
92
|
-
**Verify**: `pnpm -F opencode-agent-skills-md exec node --import tsx --test tests/cli-commands.test.ts` → the new test fails before the fix
|
|
93
|
-
|
|
94
|
-
### Step 2: Replace regex-based trailing-comma stripping with a string-aware pass
|
|
95
|
-
|
|
96
|
-
Modify `stripJsoncComments()` in `packages/opencode-agent-skills-md/src/cli/config.ts`.
|
|
97
|
-
|
|
98
|
-
Target shape:
|
|
99
|
-
|
|
100
|
-
- Keep the existing comment-stripping loop
|
|
101
|
-
- Replace the final regex with a second character-by-character pass (or fold it inline)
|
|
102
|
-
- Track `inString` and `escaped` state
|
|
103
|
-
- Remove commas only when the next non-whitespace token is `}` or `]` and the parser is not inside a string literal
|
|
104
|
-
|
|
105
|
-
Do not change `parseJsonc()` public behavior.
|
|
106
|
-
|
|
107
|
-
**Verify**: `pnpm -F opencode-agent-skills-md exec node --import tsx --test tests/cli-commands.test.ts` → all tests pass
|
|
108
|
-
|
|
109
|
-
### Step 3: Run repo verification
|
|
110
|
-
|
|
111
|
-
**Verify**:
|
|
112
|
-
- `pnpm run typecheck` → exit 0
|
|
113
|
-
- `pnpm test` → exit 0
|
|
114
|
-
- `git status --short` → only the two in-scope files plus `plans/README.md`
|
|
115
|
-
|
|
116
|
-
## Test plan
|
|
117
|
-
|
|
118
|
-
Extend `packages/opencode-agent-skills-md/tests/cli-commands.test.ts` inside the existing `describe("parseJsonc", ...)`. Model new cases after the existing block at lines 272-319. Cover:
|
|
119
|
-
- happy path trailing comma removal still works
|
|
120
|
-
- regression: `,}` inside a string is preserved
|
|
121
|
-
- regression: `,]` inside a string is preserved
|
|
122
|
-
- nested mixed case with both strings and structural trailing commas
|
|
123
|
-
|
|
124
|
-
## Done criteria
|
|
125
|
-
|
|
126
|
-
- [ ] `parseJsonc()` preserves commas inside string literals
|
|
127
|
-
- [ ] Existing trailing-comma behavior still works
|
|
128
|
-
- [ ] `pnpm run typecheck` exits 0
|
|
129
|
-
- [ ] `pnpm test` exits 0
|
|
130
|
-
- [ ] No files outside scope are modified
|
|
131
|
-
- [ ] `plans/README.md` status row updated
|
|
132
|
-
|
|
133
|
-
## STOP conditions
|
|
134
|
-
|
|
135
|
-
Stop and report back (do not improvise) if:
|
|
136
|
-
- The `parseJsonc` implementation no longer ends in a regex-based trailing comma removal step.
|
|
137
|
-
- Fixing the bug appears to require a new parser dependency.
|
|
138
|
-
- The regression test cannot be made to fail before the implementation change.
|
|
139
|
-
- Verification fails twice after a reasonable fix attempt.
|
|
140
|
-
|
|
141
|
-
## Maintenance notes
|
|
142
|
-
|
|
143
|
-
- Keep this logic near `stripJsoncComments()`; splitting into many helpers is unnecessary unless the function becomes unreadable.
|
|
144
|
-
- Future changes to config parsing should always add regression tests for string-boundary handling.
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
# Plan 007: Write config before purging plugin-owned directories
|
|
2
|
-
|
|
3
|
-
> **Executor instructions**: Follow this plan step by step. Run every
|
|
4
|
-
> verification command before moving on. If a STOP condition occurs, stop
|
|
5
|
-
> and report instead of improvising. When done, update the status row for
|
|
6
|
-
> this plan in `plans/README.md`.
|
|
7
|
-
>
|
|
8
|
-
> **Drift check (run first)**:
|
|
9
|
-
> `git diff --stat 9c57cb0..HEAD -- packages/opencode-agent-skills-md/src/cli/uninstall.ts packages/opencode-agent-skills-md/tests/cli-commands.test.ts`
|
|
10
|
-
> If any in-scope file changed since this plan was written, compare the
|
|
11
|
-
> Current state excerpts below against live code first. Any mismatch is a
|
|
12
|
-
> STOP condition.
|
|
13
|
-
|
|
14
|
-
## Status
|
|
15
|
-
|
|
16
|
-
- **Priority**: P1
|
|
17
|
-
- **Effort**: S
|
|
18
|
-
- **Risk**: LOW
|
|
19
|
-
- **Depends on**: none
|
|
20
|
-
- **Category**: bug
|
|
21
|
-
- **Planned at**: commit `9c57cb0`, 2026-07-03
|
|
22
|
-
|
|
23
|
-
## Why this matters
|
|
24
|
-
|
|
25
|
-
`runUninstall({ purge: true })` currently deletes the plugin cache/config
|
|
26
|
-
directories before it attempts the config write. If the later write fails, the
|
|
27
|
-
global OpenCode config can still claim the plugin is installed while the
|
|
28
|
-
plugin-owned directories are already gone. The bug is about operation ordering.
|
|
29
|
-
|
|
30
|
-
## Current state
|
|
31
|
-
|
|
32
|
-
- `packages/opencode-agent-skills-md/src/cli/uninstall.ts` — uninstall command implementation
|
|
33
|
-
- `packages/opencode-agent-skills-md/tests/cli-commands.test.ts` — existing uninstall coverage with in-memory `CliFs`
|
|
34
|
-
|
|
35
|
-
Relevant excerpts:
|
|
36
|
-
|
|
37
|
-
- `packages/opencode-agent-skills-md/src/cli/uninstall.ts:98-110`
|
|
38
|
-
- purge candidates are computed and, for real `--purge`, deleted before the no-op/write path
|
|
39
|
-
- `packages/opencode-agent-skills-md/src/cli/uninstall.ts:145-149`
|
|
40
|
-
- config backup and `writeAtomically()` happen later
|
|
41
|
-
- `packages/opencode-agent-skills-md/tests/cli-commands.test.ts:1048-1065`
|
|
42
|
-
- existing `--purge (real)` test only asserts the command returns `wrote`; there is no regression test for a config-write failure after purge begins
|
|
43
|
-
- `packages/opencode-agent-skills-md/tests/cli-commands.test.ts:70-156`
|
|
44
|
-
- `createMemoryFs()` supports failure injection for `write` and `rename`
|
|
45
|
-
|
|
46
|
-
Conventions to match:
|
|
47
|
-
|
|
48
|
-
- Keep `purgeDir()` best-effort
|
|
49
|
-
- Preserve `--dry-run` output and current return shapes
|
|
50
|
-
- Reorder operations instead of adding rollback machinery
|
|
51
|
-
|
|
52
|
-
## Commands you will need
|
|
53
|
-
|
|
54
|
-
| Purpose | Command | Expected on success |
|
|
55
|
-
|---|---|---|
|
|
56
|
-
| Typecheck | `pnpm run typecheck` | exit 0 |
|
|
57
|
-
| Targeted tests | `pnpm -F opencode-agent-skills-md exec node --import tsx --test tests/cli-commands.test.ts` | all pass |
|
|
58
|
-
| Full tests | `pnpm test` | all pass |
|
|
59
|
-
|
|
60
|
-
## Scope
|
|
61
|
-
|
|
62
|
-
**In scope** (the only files you should modify):
|
|
63
|
-
- `packages/opencode-agent-skills-md/src/cli/uninstall.ts`
|
|
64
|
-
- `packages/opencode-agent-skills-md/tests/cli-commands.test.ts`
|
|
65
|
-
|
|
66
|
-
**Out of scope**:
|
|
67
|
-
- Install command behavior
|
|
68
|
-
- Purge path redesign or rollback framework
|
|
69
|
-
- Any changes to `CliFs` shape
|
|
70
|
-
|
|
71
|
-
## Git workflow
|
|
72
|
-
|
|
73
|
-
- Branch: `advisor/007-write-before-purge`
|
|
74
|
-
- Commit style: conventional commits, for example `fix(cli): write uninstall config before purge`
|
|
75
|
-
- Do NOT push or open a PR unless instructed
|
|
76
|
-
|
|
77
|
-
## Steps
|
|
78
|
-
|
|
79
|
-
### Step 1: Add a regression test for write-failure ordering
|
|
80
|
-
|
|
81
|
-
Extend `describe("runUninstall", ...)` in `packages/opencode-agent-skills-md/tests/cli-commands.test.ts`.
|
|
82
|
-
|
|
83
|
-
Add a test that:
|
|
84
|
-
|
|
85
|
-
- starts with a config containing the plugin entry
|
|
86
|
-
- injects a write or rename failure via `setFailNext()`
|
|
87
|
-
- calls `runUninstall({ purge: true }, ...)`
|
|
88
|
-
- asserts the thrown error propagates
|
|
89
|
-
- asserts the original config file content is unchanged
|
|
90
|
-
|
|
91
|
-
Because the purge path uses `node:fs.rmSync` directly, do not assert real directory deletion in the in-memory FS. The point is to pin that the config write must be attempted before purge side effects happen.
|
|
92
|
-
|
|
93
|
-
**Verify**: `pnpm -F opencode-agent-skills-md exec node --import tsx --test tests/cli-commands.test.ts` → the new test fails before the reorder
|
|
94
|
-
|
|
95
|
-
### Step 2: Reorder `runUninstall()` side effects
|
|
96
|
-
|
|
97
|
-
Modify `packages/opencode-agent-skills-md/src/cli/uninstall.ts`.
|
|
98
|
-
|
|
99
|
-
Target shape:
|
|
100
|
-
|
|
101
|
-
- Keep dry-run planning unchanged
|
|
102
|
-
- Keep no-op handling unchanged
|
|
103
|
-
- Build the post-uninstall config object as today
|
|
104
|
-
- If config removal is needed, do backup + atomic write first
|
|
105
|
-
- Only after a successful write, perform best-effort purge of plugin-owned dirs
|
|
106
|
-
|
|
107
|
-
Do not add fallback writes, retries, or rollback code.
|
|
108
|
-
|
|
109
|
-
**Verify**: `pnpm -F opencode-agent-skills-md exec node --import tsx --test tests/cli-commands.test.ts` → all tests pass
|
|
110
|
-
|
|
111
|
-
### Step 3: Run repo verification
|
|
112
|
-
|
|
113
|
-
**Verify**:
|
|
114
|
-
- `pnpm run typecheck` → exit 0
|
|
115
|
-
- `pnpm test` → exit 0
|
|
116
|
-
- `git status --short` → only the two in-scope files plus `plans/README.md`
|
|
117
|
-
|
|
118
|
-
## Test plan
|
|
119
|
-
|
|
120
|
-
Extend `packages/opencode-agent-skills-md/tests/cli-commands.test.ts`. Model after existing uninstall tests and the existing write-failure helpers. Cover:
|
|
121
|
-
- regression: `purge: true` plus write failure leaves config unchanged
|
|
122
|
-
- existing `--dry-run` and success paths remain green
|
|
123
|
-
|
|
124
|
-
## Done criteria
|
|
125
|
-
|
|
126
|
-
- [ ] `runUninstall()` writes config before purging
|
|
127
|
-
- [ ] Write failure leaves the config intact
|
|
128
|
-
- [ ] `pnpm run typecheck` exits 0
|
|
129
|
-
- [ ] `pnpm test` exits 0
|
|
130
|
-
- [ ] No files outside scope are modified
|
|
131
|
-
- [ ] `plans/README.md` status row updated
|
|
132
|
-
|
|
133
|
-
## STOP conditions
|
|
134
|
-
|
|
135
|
-
Stop and report back (do not improvise) if:
|
|
136
|
-
- `runUninstall()` no longer has a distinct write phase and purge phase.
|
|
137
|
-
- The regression requires changing `CliFs` or adding a purge abstraction.
|
|
138
|
-
- The fix appears to require changing public return types or console output format.
|
|
139
|
-
- Verification fails twice after a reasonable fix attempt.
|
|
140
|
-
|
|
141
|
-
## Maintenance notes
|
|
142
|
-
|
|
143
|
-
- Purge remains best-effort by design; the important invariant is that config state is committed first.
|
|
144
|
-
- If uninstall ever gains transactional semantics later, revisit install/uninstall symmetry together rather than expanding this fix.
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
# Plan 008: Reuse the shared walker in `listSkillFiles`
|
|
2
|
-
|
|
3
|
-
> **Executor instructions**: Follow this plan step by step. Run every
|
|
4
|
-
> verification command before moving on. If a STOP condition occurs, stop
|
|
5
|
-
> and report instead of improvising. When done, update the status row for
|
|
6
|
-
> this plan in `plans/README.md`.
|
|
7
|
-
>
|
|
8
|
-
> **Drift check (run first)**:
|
|
9
|
-
> `git diff --stat 9c57cb0..HEAD -- packages/core/src/discovery.ts packages/core/src/walk.ts packages/core/tests/discovery.test.ts`
|
|
10
|
-
> If any in-scope file changed since this plan was written, compare the
|
|
11
|
-
> Current state excerpts below against live code first. Any mismatch is a
|
|
12
|
-
> STOP condition.
|
|
13
|
-
|
|
14
|
-
## Status
|
|
15
|
-
|
|
16
|
-
- **Priority**: P2
|
|
17
|
-
- **Effort**: S
|
|
18
|
-
- **Risk**: LOW
|
|
19
|
-
- **Depends on**: none
|
|
20
|
-
- **Category**: tech-debt
|
|
21
|
-
- **Planned at**: commit `9c57cb0`, 2026-07-03
|
|
22
|
-
|
|
23
|
-
## Why this matters
|
|
24
|
-
|
|
25
|
-
`listSkillFiles()` reimplements recursive traversal instead of using the shared
|
|
26
|
-
`walkDir()` utility that already defines the repo's skip rules and
|
|
27
|
-
error-isolation behavior. That duplication means `listSkillFiles()` can descend
|
|
28
|
-
into hidden directories, `.git`, and `node_modules`, and it pays an extra
|
|
29
|
-
`stat()` per entry. The fix is a small consolidation onto the existing
|
|
30
|
-
abstraction.
|
|
31
|
-
|
|
32
|
-
## Current state
|
|
33
|
-
|
|
34
|
-
- `packages/core/src/discovery.ts` — skill discovery helpers, including `listSkillFiles()`
|
|
35
|
-
- `packages/core/src/walk.ts` — shared recursive walker already used by `findSkillsRecursive()` and `findScripts()`
|
|
36
|
-
- `packages/core/tests/discovery.test.ts` — existing walker/discovery tests; no direct `listSkillFiles()` coverage
|
|
37
|
-
|
|
38
|
-
Relevant excerpts:
|
|
39
|
-
|
|
40
|
-
- `packages/core/src/discovery.ts:202-233`
|
|
41
|
-
- `listSkillFiles()` uses a private `recurse()` function
|
|
42
|
-
- calls `fs.readdir(..., { withFileTypes: true })`
|
|
43
|
-
- then immediately calls `fs.stat(fullPath)` for every entry
|
|
44
|
-
- does not apply `walkDir()` skip rules
|
|
45
|
-
- `packages/core/src/walk.ts:4-16`
|
|
46
|
-
- `walkDir()` owns shared traversal rules: hidden dirs, `node_modules`, `.git` are skipped
|
|
47
|
-
- per-entry failures are isolated
|
|
48
|
-
- `packages/core/tests/discovery.test.ts:82-161`
|
|
49
|
-
- direct tests already pin `walkDir()` skip behavior
|
|
50
|
-
- `packages/core/tests/discovery.test.ts:163-252`
|
|
51
|
-
- `findSkillsRecursive()` already proves the walker-based pattern
|
|
52
|
-
|
|
53
|
-
Conventions to match:
|
|
54
|
-
|
|
55
|
-
- Keep the core package host-agnostic and dependency-free
|
|
56
|
-
- Prefer the smallest correct refactor
|
|
57
|
-
- Preserve sorted output and graceful handling of missing directories
|
|
58
|
-
|
|
59
|
-
## Commands you will need
|
|
60
|
-
|
|
61
|
-
| Purpose | Command | Expected on success |
|
|
62
|
-
|---|---|---|
|
|
63
|
-
| Typecheck | `pnpm run typecheck` | exit 0 |
|
|
64
|
-
| Targeted tests | `pnpm -F opencode-agent-skills-md-core exec node --import tsx --test tests/discovery.test.ts` | all pass |
|
|
65
|
-
| Full tests | `pnpm test` | all pass |
|
|
66
|
-
|
|
67
|
-
## Scope
|
|
68
|
-
|
|
69
|
-
**In scope** (the only files you should modify):
|
|
70
|
-
- `packages/core/src/discovery.ts`
|
|
71
|
-
- `packages/core/tests/discovery.test.ts`
|
|
72
|
-
|
|
73
|
-
**Out of scope**:
|
|
74
|
-
- `packages/core/src/walk.ts` behavior changes
|
|
75
|
-
- `findScripts()` performance cleanup
|
|
76
|
-
- Plugin package source changes
|
|
77
|
-
|
|
78
|
-
## Git workflow
|
|
79
|
-
|
|
80
|
-
- Branch: `advisor/008-reuse-walkdir-for-list-skill-files`
|
|
81
|
-
- Commit style: conventional commits, for example `refactor(core): reuse walkDir in listSkillFiles`
|
|
82
|
-
- Do NOT push or open a PR unless instructed
|
|
83
|
-
|
|
84
|
-
## Steps
|
|
85
|
-
|
|
86
|
-
### Step 1: Add direct characterization tests for `listSkillFiles()`
|
|
87
|
-
|
|
88
|
-
Extend `packages/core/tests/discovery.test.ts` with a dedicated `describe("listSkillFiles", ...)`.
|
|
89
|
-
|
|
90
|
-
Build a temp skill tree that includes:
|
|
91
|
-
- `SKILL.md`
|
|
92
|
-
- visible nested files that should be returned
|
|
93
|
-
- `.hidden/`
|
|
94
|
-
- `node_modules/`
|
|
95
|
-
- `.git/`
|
|
96
|
-
- a nested depth boundary case
|
|
97
|
-
|
|
98
|
-
Assert:
|
|
99
|
-
- `SKILL.md` is excluded
|
|
100
|
-
- visible files are returned as sorted relative paths
|
|
101
|
-
- hidden, `.git`, and `node_modules` contents are not returned
|
|
102
|
-
- missing base directory returns `[]`
|
|
103
|
-
|
|
104
|
-
Model setup style after the existing `walkDir` and `findSkillsRecursive` tests.
|
|
105
|
-
|
|
106
|
-
**Verify**: `pnpm -F opencode-agent-skills-md-core exec node --import tsx --test tests/discovery.test.ts` → the new tests fail before the refactor
|
|
107
|
-
|
|
108
|
-
### Step 2: Rewrite `listSkillFiles()` onto `walkDir()`
|
|
109
|
-
|
|
110
|
-
Modify `packages/core/src/discovery.ts`.
|
|
111
|
-
|
|
112
|
-
Target shape:
|
|
113
|
-
|
|
114
|
-
- import and reuse `walkDir()` instead of the bespoke `recurse()` implementation
|
|
115
|
-
- in the visitor:
|
|
116
|
-
- ignore directories
|
|
117
|
-
- ignore `SKILL.md`
|
|
118
|
-
- compute relative paths from `skillPath`
|
|
119
|
-
- push file paths only for visible files the walker surfaces
|
|
120
|
-
- keep sorted return order
|
|
121
|
-
- preserve graceful behavior when `skillPath` does not exist
|
|
122
|
-
|
|
123
|
-
Do not change other discovery helpers in this plan.
|
|
124
|
-
|
|
125
|
-
**Verify**: `pnpm -F opencode-agent-skills-md-core exec node --import tsx --test tests/discovery.test.ts` → all tests pass
|
|
126
|
-
|
|
127
|
-
### Step 3: Run repo verification
|
|
128
|
-
|
|
129
|
-
**Verify**:
|
|
130
|
-
- `pnpm run typecheck` → exit 0
|
|
131
|
-
- `pnpm test` → exit 0
|
|
132
|
-
- `git status --short` → only the two in-scope files plus `plans/README.md`
|
|
133
|
-
|
|
134
|
-
## Test plan
|
|
135
|
-
|
|
136
|
-
Extend `packages/core/tests/discovery.test.ts`. Reuse the same temp-directory style already used by `walkDir` / `findSkillsRecursive`. Cover:
|
|
137
|
-
- sorted visible file listing
|
|
138
|
-
- exclusion of `SKILL.md`
|
|
139
|
-
- exclusion of hidden, `.git`, and `node_modules`
|
|
140
|
-
- missing directory returns `[]`
|
|
141
|
-
- maxDepth still limits traversal
|
|
142
|
-
|
|
143
|
-
## Done criteria
|
|
144
|
-
|
|
145
|
-
- [ ] `listSkillFiles()` reuses `walkDir()`
|
|
146
|
-
- [ ] `listSkillFiles()` no longer has custom recursive traversal
|
|
147
|
-
- [ ] Direct tests cover skip rules and `SKILL.md` exclusion
|
|
148
|
-
- [ ] `pnpm run typecheck` exits 0
|
|
149
|
-
- [ ] `pnpm test` exits 0
|
|
150
|
-
- [ ] No files outside scope are modified
|
|
151
|
-
- [ ] `plans/README.md` status row updated
|
|
152
|
-
|
|
153
|
-
## STOP conditions
|
|
154
|
-
|
|
155
|
-
Stop and report back (do not improvise) if:
|
|
156
|
-
- `listSkillFiles()` has already been moved out of `discovery.ts`
|
|
157
|
-
- Reusing `walkDir()` would require changing `walkDir()` semantics
|
|
158
|
-
- The characterization tests cannot be made to fail before the refactor
|
|
159
|
-
- Verification fails twice after a reasonable fix attempt.
|
|
160
|
-
|
|
161
|
-
## Maintenance notes
|
|
162
|
-
|
|
163
|
-
- If `findScripts()` later gets the same consolidation or perf cleanup, do that as a separate plan.
|
|
164
|
-
- Keep `walkDir()` as the single source of truth for shared traversal rules; avoid reintroducing bespoke recursion.
|