opencode-skills-doctor 0.9.1 → 0.9.4

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 CHANGED
@@ -35,7 +35,7 @@
35
35
 
36
36
  - [The 30-second version](#the-30-second-version) · [Privacy](#privacy-local-only-no-data-collection)
37
37
  - [See it](#see-it) · [How it works](#how-it-works) · [Quick start](#quick-start)
38
- - [Install](#install) · [Commands](#commands) · [Works where you work](#works-where-you-work)
38
+ - [Install](#install) · [Use it in CI](#use-it-in-ci-github-action) · [Commands](#commands) · [Works where you work](#works-where-you-work)
39
39
  - [Why it is safe](#why-it-is-safe) · [Development](#development)
40
40
 
41
41
  ## The 30-second version
@@ -138,6 +138,46 @@ npx -y opencode-skills-doctor mcp
138
138
 
139
139
  Nothing to configure for **skills discovery**: it reads `.opencode/skills`, `.claude/skills`, `.agents/skills`, `.grok/skills`, `.cursor/skills`, `.hermes/skills`, `.kimi-code/skills`, `.dsh/skills` (plus `$DSH_HOME`) and their user-level equivalents. See the [full reference](docs/REFERENCE.md) for OpenCode 1.x, DSH YAML, Codex TOML and Claude Code details.
140
140
 
141
+ ## Use it in CI (GitHub Action)
142
+
143
+ A composite action ships in this repo: no install step, no runtime dependencies —
144
+ it runs the checked-out code directly.
145
+
146
+ ```yaml
147
+ name: skills
148
+ on: [push, pull_request]
149
+
150
+ permissions:
151
+ contents: read
152
+ pull-requests: write # only needed for `comment: true`
153
+
154
+ jobs:
155
+ audit:
156
+ runs-on: ubuntu-latest
157
+ steps:
158
+ - uses: actions/checkout@v4
159
+ - uses: wangyuchen5110/opencodeplugginprogram@v0.9.4
160
+ with:
161
+ budget: "1200"
162
+ fail-on: warn # error | warn | never
163
+ html: skills-report.html # written and uploaded as an artifact
164
+ comment: "true" # post the summary on the PR
165
+ ```
166
+
167
+ It writes a summary to the job page, uploads the HTML report, optionally comments
168
+ on the pull request, and fails the job according to `fail-on`.
169
+
170
+ | Input | Default | Purpose |
171
+ |---|---|---|
172
+ | `root` | `.` | Directory to audit |
173
+ | `budget` | `1200` | Description tokens paid per model step |
174
+ | `fail-on` | `error` | Fail on `error`, `warn`, or `never` |
175
+ | `extra-args` | — | Extra `check` flags, e.g. `--no-global` |
176
+ | `html` | — | HTML report path; uploaded as an artifact when set |
177
+ | `comment` | `false` | Post/append the summary as a pull request comment |
178
+
179
+ Outputs: `exit-code`, `error-count`, `warning-count`, `advertised-tokens`.
180
+
141
181
  ## Commands
142
182
 
143
183
  | Command | What it does |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-skills-doctor",
3
- "version": "0.9.1",
3
+ "version": "0.9.4",
4
4
  "description": "Audit, fix and update agent skills: token cost, broken references, shadowed duplicates, HTML reports, catalog sync. CLI, OpenCode plugin, MCP server; works with OpenCode, Claude Code, Codex, Grok CLI, Cursor, Hermes Agent, Kimi Code and DeepSeek Harness.",
5
5
  "type": "module",
6
6
  "exports": {
package/src/desktop.mjs CHANGED
@@ -21,8 +21,10 @@ export function desktopCandidates(platform = process.platform, env = process.env
21
21
  return ["/usr/bin/opencode-desktop", "/usr/local/bin/opencode-desktop", "/opt/OpenCode/opencode-desktop", "/opt/opencode-desktop/opencode-desktop"]
22
22
  }
23
23
 
24
- function asarPathFor(exe) {
25
- if (process.platform === "darwin" || exe.includes(".app")) {
24
+ function asarPathFor(exe, platform = process.platform) {
25
+ // Callers may probe another platform (tests, cross-platform tooling), so use
26
+ // the requested platform instead of the host one.
27
+ if (platform === "darwin" || exe.includes(".app")) {
26
28
  return path.join(path.dirname(path.dirname(path.dirname(path.dirname(exe)))), "Resources", "app.asar")
27
29
  }
28
30
  return path.join(path.dirname(exe), "resources", "app.asar")
@@ -71,8 +73,9 @@ export function readAsarVersion(asarFile) {
71
73
  export function detectDesktop({ platform = process.platform, env = process.env, home = os.homedir() } = {}) {
72
74
  for (const exe of desktopCandidates(platform, env, home)) {
73
75
  if (!fs.existsSync(exe)) continue
74
- const version = readAsarVersion(asarPathFor(exe))
75
- return { installed: true, exe, version, asar: asarPathFor(exe) }
76
+ const asar = asarPathFor(exe, platform)
77
+ const version = readAsarVersion(asar)
78
+ return { installed: true, exe, version, asar }
76
79
  }
77
80
  return { installed: false, exe: null, version: null, asar: null }
78
81
  }