@skillsmith/core 0.11.5 → 0.11.6

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.
Files changed (94) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README.md +2 -2
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/src/api/client.d.ts.map +1 -1
  5. package/dist/src/api/client.js +5 -0
  6. package/dist/src/api/client.js.map +1 -1
  7. package/dist/src/api/client.test.js +39 -0
  8. package/dist/src/api/client.test.js.map +1 -1
  9. package/dist/src/compatibility/slugs.d.ts +7 -3
  10. package/dist/src/compatibility/slugs.d.ts.map +1 -1
  11. package/dist/src/compatibility/slugs.js +11 -4
  12. package/dist/src/compatibility/slugs.js.map +1 -1
  13. package/dist/src/db/drivers/sqljsDriver.d.ts +8 -0
  14. package/dist/src/db/drivers/sqljsDriver.d.ts.map +1 -1
  15. package/dist/src/db/drivers/sqljsDriver.js +24 -2
  16. package/dist/src/db/drivers/sqljsDriver.js.map +1 -1
  17. package/dist/src/db/migration-runner.d.ts.map +1 -1
  18. package/dist/src/db/migration-runner.js +23 -2
  19. package/dist/src/db/migration-runner.js.map +1 -1
  20. package/dist/src/db/schema.d.ts.map +1 -1
  21. package/dist/src/db/schema.js +29 -3
  22. package/dist/src/db/schema.js.map +1 -1
  23. package/dist/src/exports/services.d.ts +1 -0
  24. package/dist/src/exports/services.d.ts.map +1 -1
  25. package/dist/src/exports/services.js +5 -0
  26. package/dist/src/exports/services.js.map +1 -1
  27. package/dist/src/index.d.ts +1 -1
  28. package/dist/src/index.js +1 -1
  29. package/dist/src/install/index.d.ts +2 -2
  30. package/dist/src/install/index.d.ts.map +1 -1
  31. package/dist/src/install/index.js +1 -1
  32. package/dist/src/install/index.js.map +1 -1
  33. package/dist/src/install/paths.d.ts +155 -1
  34. package/dist/src/install/paths.d.ts.map +1 -1
  35. package/dist/src/install/paths.js +235 -1
  36. package/dist/src/install/paths.js.map +1 -1
  37. package/dist/src/install/paths.test.js +174 -2
  38. package/dist/src/install/paths.test.js.map +1 -1
  39. package/dist/src/services/context-words.d.ts +40 -0
  40. package/dist/src/services/context-words.d.ts.map +1 -0
  41. package/dist/src/services/context-words.js +178 -0
  42. package/dist/src/services/context-words.js.map +1 -0
  43. package/dist/src/services/context-words.test.d.ts +2 -0
  44. package/dist/src/services/context-words.test.d.ts.map +1 -0
  45. package/dist/src/services/context-words.test.js +94 -0
  46. package/dist/src/services/context-words.test.js.map +1 -0
  47. package/dist/src/services/skill-installation.content.d.ts +8 -0
  48. package/dist/src/services/skill-installation.content.d.ts.map +1 -1
  49. package/dist/src/services/skill-installation.content.js +2 -2
  50. package/dist/src/services/skill-installation.content.js.map +1 -1
  51. package/dist/src/services/skill-installation.helpers.d.ts.map +1 -1
  52. package/dist/src/services/skill-installation.helpers.js +24 -2
  53. package/dist/src/services/skill-installation.helpers.js.map +1 -1
  54. package/dist/src/services/skill-installation.helpers.test.js +76 -2
  55. package/dist/src/services/skill-installation.helpers.test.js.map +1 -1
  56. package/dist/src/services/skill-installation.io.d.ts +22 -1
  57. package/dist/src/services/skill-installation.io.d.ts.map +1 -1
  58. package/dist/src/services/skill-installation.io.js +36 -5
  59. package/dist/src/services/skill-installation.io.js.map +1 -1
  60. package/dist/src/services/skill-installation.service.d.ts +2 -0
  61. package/dist/src/services/skill-installation.service.d.ts.map +1 -1
  62. package/dist/src/services/skill-installation.service.js +4 -1
  63. package/dist/src/services/skill-installation.service.js.map +1 -1
  64. package/dist/src/services/skill-manifest.d.ts +21 -0
  65. package/dist/src/services/skill-manifest.d.ts.map +1 -1
  66. package/dist/src/services/skill-manifest.js +51 -6
  67. package/dist/src/services/skill-manifest.js.map +1 -1
  68. package/dist/src/services/skill-manifest.test.d.ts +2 -0
  69. package/dist/src/services/skill-manifest.test.d.ts.map +1 -0
  70. package/dist/src/services/skill-manifest.test.js +202 -0
  71. package/dist/src/services/skill-manifest.test.js.map +1 -0
  72. package/dist/src/types/skill.d.ts +10 -0
  73. package/dist/src/types/skill.d.ts.map +1 -1
  74. package/dist/src/types.d.ts +9 -5
  75. package/dist/src/types.d.ts.map +1 -1
  76. package/dist/tests/db/migration-runner-race.test.d.ts +2 -0
  77. package/dist/tests/db/migration-runner-race.test.d.ts.map +1 -0
  78. package/dist/tests/db/migration-runner-race.test.js +75 -0
  79. package/dist/tests/db/migration-runner-race.test.js.map +1 -0
  80. package/dist/tests/db/schema-async.test.js +37 -1
  81. package/dist/tests/db/schema-async.test.js.map +1 -1
  82. package/dist/tests/db/sqljsDriver.test.js +63 -1
  83. package/dist/tests/db/sqljsDriver.test.js.map +1 -1
  84. package/dist/tests/schema.test.js +43 -1
  85. package/dist/tests/schema.test.js.map +1 -1
  86. package/dist/tests/unit/services/skill-installation.io.client-agent-path.test.d.ts +34 -0
  87. package/dist/tests/unit/services/skill-installation.io.client-agent-path.test.d.ts.map +1 -0
  88. package/dist/tests/unit/services/skill-installation.io.client-agent-path.test.js +246 -0
  89. package/dist/tests/unit/services/skill-installation.io.client-agent-path.test.js.map +1 -0
  90. package/dist/tests/unit/services/skill-installation.service.companion-basedir.test.d.ts +17 -0
  91. package/dist/tests/unit/services/skill-installation.service.companion-basedir.test.d.ts.map +1 -0
  92. package/dist/tests/unit/services/skill-installation.service.companion-basedir.test.js +112 -0
  93. package/dist/tests/unit/services/skill-installation.service.companion-basedir.test.js.map +1 -0
  94. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,53 @@ All notable changes to `@skillsmith/core` are documented here.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## v0.11.6
8
+
9
+ - **Fix**: Harden manifest concurrency (uninstall lock, temp-file races) (#2331)
10
+ - **Fix**: code-review follow-up on the Antigravity `directory-package` companion-agent path (two BLOCKING findings). (1) `resolveCompanionAgentPath()` gains an explicit 3rd `baseDir` param (default `process.cwd()`) instead of letting Antigravity's relative `dir` resolve implicitly against whatever `process.cwd()` happens to be at the exact `fs` call that consumes the path — wrong for the long-running MCP server, whose cwd is fixed at launch and does not track the calling editor/agent's real project. `writeInstallFiles()` gains a matching optional `companionBaseDir` param, threaded through both its callers (`SkillInstallationService.install()` via a new `companionBaseDir` constructor param, and `installFromContent()`); the MCP `install_skill` tool gains an optional `cwd` input field passed through as `companionBaseDir` so a caller can supply its real project root. (2) `resolveCompanionAgentPath()`'s `directory-package` branch now rejects an unsafe `skillName` (`''`, `'.'`, `'..'`, or containing `/`/`\`) before building the path — `skillName` becomes its own path segment in this mode, so `'..'` would otherwise `path.join`-normalize outside the intended companion-agent directory. Not exploitable through either current caller (both already sanitize `skillName` upstream), but the function is exported/reusable with no validation of its own, so it now enforces the same "last line of defense" standard already applied to `skillNameFromSkillId()` (SMI-5982)
11
+ - **Feature**: `antigravity` is now a real `ClientId` (`install/paths.ts`) — `CLIENT_NATIVE_PATHS['antigravity'] = ~/.gemini/config/skills`, un-deferred from `compatibility/slugs.ts`'s `BROWSE_ONLY_SLUGS` (which now only contains `gemini`), and given its own `CLIENT_TO_COMPATIBILITY_SLUG` entry. `CompanionAgentTarget.fileMode` gains a second value, `'directory-package'` (Antigravity only today) — a per-skill subdirectory `<dir>/<skillName>/agent.md`, instead of every other client's flat `<dir>/<name>-suffix.md`; `resolveCompanionAgentPath()` is now mode-aware. Antigravity's companion-agent output is project-scoped (`.agents/agents/<name>/agent.md`, relative to the invocation directory) — this CLI has no existing global-vs-project install-mode distinction to hook into, confirmed by grep, so global scope (`~/.gemini/config/agents/`) is a fast-follow, not implemented here (SMI-5982)
12
+ - **Fix**: `writeInstallFiles()`'s rollback path could leave behind an orphaned, empty per-skill companion-agent directory when a new `directory-package`-mode install (Antigravity) failed partway through — every other client's agents dir is shared and pre-existing, so this hazard never applied to them. Cleanup uses a non-recursive `rmdir`, a safe no-op when the directory was never created or holds unexpected surviving content (SMI-5982)
13
+ - **Fix (BLOCKING, PR-review follow-up)**: the prior `resolveCompanionAgentPath()` fix's `baseDir: string = process.cwd()` default only closed the cwd-dependence bug for the ONE call site that happened to pass it explicitly (the MCP `install_skill` tool) — every other production `SkillInstallationService`/`installFromContent()` call site (7 more, audited via `grep -rn "new SkillInstallationService(" packages/`) still silently fell back to `process.cwd()`, including the private-registry `install` MCP action, which has no per-call cwd input to source a correct value from at all. `baseDir` is now **structurally required** (no default) whenever the target client's `CompanionAgentTarget.fileMode === 'directory-package'` — closing the bug class by construction for every current and future caller rather than by chasing individual call sites. `writeInstallFiles()`'s `companionBaseDir` param, `SkillInstallationService`'s constructor param, and `installFromContent()`'s param all lost their own `?? process.cwd()` fallbacks to match — an omitted value now flows through as `undefined` and fails closed with a diagnosable error (`sanitizeInstallError()`'s allowlist extended to surface it) instead of resolving against the wrong directory. The 4 CLI call sites that relied on the implicit default (`install`, `registry-install`, interactive `search`, `update`) now pass `companionBaseDir: process.cwd()` explicitly, restoring their exact prior behavior (SMI-5982)
14
+ - **Fix**: `ManifestManager` (`services/skill-manifest.ts`) had two concurrency gaps in the skill
15
+ manifest write path. `performUninstall()` (`skill-installation.helpers.ts`) loaded the manifest,
16
+ mutated an in-memory snapshot, and saved it back directly, bypassing the lock/`updateSafely()`
17
+ mechanism the install path uses — a concurrent update to an unrelated entry in that window could
18
+ be silently overwritten. `save()` also computed its temp filename from just the process id, so
19
+ two concurrent saves in the same process could collide on the same temp path. Uninstall now
20
+ routes its final mutation through `updateSafely()`, and both `save()` and the CLI's separate
21
+ manifest writer now suffix the temp filename with a random UUID, with best-effort cleanup on
22
+ failure. `load()` also now distinguishes a missing manifest file (returns empty, expected) from
23
+ one that exists but is corrupt/unreadable (throws, instead of silently returning empty and
24
+ risking a subsequent save erasing real state) (SMI-6007).
25
+ - **Fix**: `runMigrations()`/`runMigrationsSafe()` (`db/migration-runner.ts`) had an unguarded
26
+ concurrent-migration race — two processes opening the same fresh DB at the same time could both
27
+ read the same `currentVersion`, both apply the same migration, and the loser's plain
28
+ `INSERT INTO schema_version` throw `UNIQUE constraint failed: schema_version.version`. Both now
29
+ use `INSERT OR IGNORE`, matching the existing v1-stamp hardening in `initializeSchema()`
30
+ (`schema.ts`, SMI-4486) that was never extended to per-migration inserts. Found via a flaky
31
+ `startup-probe.test.ts` failure traced to a real production race, not test-only flakiness
32
+ (SMI-6003).
33
+ - **Changed (breaking)**: `SearchResponse.compatibilityHidden` renamed to
34
+ `compatibilityDeprioritized` — the compatibility filter is now a ranking signal, not a hard
35
+ exclusion (SMI-5929), so results are never actually "hidden" by it anymore; the renamed field is
36
+ precisely the count of other-tool-only results present on the *returned page*, not a corpus-wide
37
+ or pre-page count. `SearchOptions` gains a new optional `compatibility?: string[]` field —
38
+ `SkillsmithApiClient.search()` forwards it to the `skills-search` edge function as a
39
+ `compatibility` CSV query param (previously never sent by any caller), letting the API rank
40
+ results server-side, before the page is cut to the requested `limit`.
41
+ - **Fix**: companion-subagent files (the `-specialist.md` shim generated alongside an installed
42
+ skill) were always written to `~/.claude/agents/`, regardless of which client the skill itself
43
+ was installed for — a skill installed with `--client cursor` or `SKILLSMITH_CLIENT=cursor`
44
+ still got its companion subagent dropped into Claude Code's own agent directory instead of
45
+ Cursor's. New `COMPANION_AGENT_TARGETS` map (`@skillsmith/core/install/paths`) plus
46
+ `getCompanionAgentTarget()`/`resolveCompanionAgentDir()`/`resolveCompanionAgentPath()` give each
47
+ `ClientId` its own companion-agent directory and filename pattern, sourced from the same
48
+ evidence table already used for skill install paths; clients with no independently-verified
49
+ agents-dir convention default to today's existing `~/.claude/agents/` behavior rather than
50
+ guessing (GH #2161)
51
+ - **Fix**: new shared `extractContextWords()` (`services/context-words.ts`, exported from the package root) replaces a `.filter((w) => w.length > 3)` threshold both `@skillsmith/mcp-server`'s `skill_recommend` and `@skillsmith/cli`'s `recommend --context` used independently — it was silently dropping real short technical terms ("git", "ci", "aws", "sql", "k8s") from the recommendation stack, tripping the empty-stack guard even when usable context was supplied (SMI-5986)
52
+ - **Fix**: `SqlJsDatabaseAdapter.persist()` (`db/drivers/sqljsDriver.ts`) now writes the exported database buffer atomically — to a temp file, then `renameSync` over the target — instead of a direct `writeFileSync` that truncates the file before the new bytes land. A process kill mid-write (OOM, SIGKILL, machine sleep) could previously leave a 0-byte `skills.db` on disk. `openDatabaseAsync()` (`db/schema.ts`) also now distinguishes a genuinely empty/corrupt database (zero tables) from a real legacy import (has tables, just missing `schema_version`), failing loudly with remediation for the former instead of silently stamping `schema_version=1` and running every migration against a schema that was never created — which previously crashed server startup with an opaque `no such table: skills`/`no such table: cache` error and no actionable diagnostic (SMI-5997)
53
+
7
54
  ## v0.11.5
8
55
 
9
56
  - **Cadence**: Mechanical cadence alignment (no changes since v0.11.4).
package/README.md CHANGED
@@ -6,13 +6,13 @@ Part of Skillsmith: a lifecycle layer for agent skills across teams.
6
6
 
7
7
  ## Contents
8
8
 
9
- - [What's New](#whats-new-in-v0115)
9
+ - [What's New](#whats-new-in-v0116)
10
10
  - [Installation](#installation)
11
11
  - [Quick Start](#quick-start)
12
12
  - [Features](#features)
13
13
  - [Exports](#exports)
14
14
 
15
- ## What's New in v0.11.5
15
+ ## What's New in v0.11.6
16
16
 
17
17
  - **Security-status reporting unified**: CLI and MCP now derive security-scan status (pass/fail, risk score, findings count) from one shared `deriveSecuritySummaryFromApiSkill`/`deriveSecuritySummaryFromSkillRow`, instead of two independently-maintained copies that could disagree on the same skill.
18
18
  - **`skill_compare` reuses `get_skill`'s resolution**: new shared `resolveSkillApiFirst()` fixes compare only ever hitting the local SQLite cache (no longer kept in sync with the remote-first registry), which made real, searchable skills report "not found."