local-skills-mcp 1.0.0 → 1.0.2

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/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
4
4
 
5
+ ## <small>1.0.2 (2026-08-24)</small>
6
+
7
+ - fix: remove SIGINT listener on close, and collapse the duplicated changelog (#108) ([ab657dc](https://github.com/kdpa-llc/local-skills-mcp/commit/ab657dc)), closes [#108](https://github.com/kdpa-llc/local-skills-mcp/issues/108)
8
+
9
+ ## <small>1.0.1 (2026-08-24)</small>
10
+
11
+ - fix(deps): regenerate the lockfile so npm ci works on Node 22 (#107) ([31bd1c1](https://github.com/kdpa-llc/local-skills-mcp/commit/31bd1c1)), closes [#107](https://github.com/kdpa-llc/local-skills-mcp/issues/107)
12
+
5
13
  ## 1.0.0 (2026-08-20)
6
14
 
7
15
  - feat!: signal the Node.js 22 requirement and make "!" mark a breaking change ([599a0fd](https://github.com/kdpa-llc/local-skills-mcp/commit/599a0fd)), closes [#98](https://github.com/kdpa-llc/local-skills-mcp/issues/98) [#98](https://github.com/kdpa-llc/local-skills-mcp/issues/98) [#98](https://github.com/kdpa-llc/local-skills-mcp/issues/98)
@@ -151,25 +159,11 @@ Claude-Session: https://claude.ai/code/session_015oP5dZ2WxDSSSpMoRtbASi
151
159
  - chore(deps-dev): bump the development-dependencies group with 2 updates (#37) ([6ce77d2](https://github.com/kdpa-llc/local-skills-mcp/commit/6ce77d2)), closes [#37](https://github.com/kdpa-llc/local-skills-mcp/issues/37)
152
160
  - docs: replace hardcoded values with dynamic references (#20) ([45a8d80](https://github.com/kdpa-llc/local-skills-mcp/commit/45a8d80)), closes [#20](https://github.com/kdpa-llc/local-skills-mcp/issues/20) [#20](https://github.com/kdpa-llc/local-skills-mcp/issues/20)
153
161
 
154
- # Changelog
155
-
156
- All notable changes to this project will be documented in this file.
157
-
158
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
159
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
160
-
161
- ## [Unreleased]
162
-
163
- ### Added
164
-
165
- - Package built-in skills directory as base default for all MCP instances
166
- - Self-documenting capabilities: `local-skills-mcp-usage`, `local-skills-mcp-guide`, and `skill-creator` skills
167
- - Skills are now available immediately after installation with zero configuration
168
-
169
- ### Changed
162
+ ## Earlier history
170
163
 
171
- - Directory aggregation priority updated to include package built-in skills as lowest priority (first in list)
172
- - Updated documentation to reflect new built-in skills feature
164
+ Entries below predate semantic-release taking over this file. They are kept
165
+ verbatim; the `[Unreleased]` block that used to sit here described the
166
+ built-in skills feature, which shipped in 0.2.0 and is covered above.
173
167
 
174
168
  ## [0.1.0] - 2025-11-01
175
169
 
package/dist/index.d.ts CHANGED
@@ -103,6 +103,29 @@ export declare class LocalSkillsServer {
103
103
  */
104
104
  constructor(skillsDirs?: string[]);
105
105
  private setupErrorHandling;
106
+ /**
107
+ * SIGINT handler, kept as a stable reference so {@link close} can remove it.
108
+ *
109
+ * Registering an inline listener per instance leaked one listener per server
110
+ * that was ever constructed: nothing removed them, so a process creating
111
+ * several servers — every test run — walked into
112
+ * MaxListenersExceededWarning.
113
+ */
114
+ private readonly handleSigint;
115
+ /**
116
+ * Close the server and set the exit status, without calling process.exit().
117
+ *
118
+ * close() removes the SIGINT listener and closes the transport, leaving
119
+ * nothing to hold the event loop, so the process ends on its own with this
120
+ * status. Forcing the exit truncates whatever else is still unwinding, and
121
+ * is untestable here: process.exit() inside a fire-and-forget handler
122
+ * escapes any spy a test installs, because the handler returns before the
123
+ * promise settles. Vitest then reports "process.exit unexpectedly called"
124
+ * and fails the run even though every test passed.
125
+ *
126
+ * Returned so callers - and tests - can await the shutdown deterministically.
127
+ */
128
+ shutdown(): Promise<void>;
106
129
  private setupHandlers;
107
130
  private handleValidateSkill;
108
131
  private handleEvaluateSkill;
package/dist/index.js CHANGED
@@ -195,11 +195,41 @@ export class LocalSkillsServer {
195
195
  this.server.onerror = (error) => {
196
196
  console.error("[MCP Error]", error);
197
197
  };
198
- // eslint-disable-next-line @typescript-eslint/no-misused-promises
199
- process.on("SIGINT", async () => {
200
- await this.server.close();
201
- process.exit(0);
202
- });
198
+ process.on("SIGINT", this.handleSigint);
199
+ }
200
+ /**
201
+ * SIGINT handler, kept as a stable reference so {@link close} can remove it.
202
+ *
203
+ * Registering an inline listener per instance leaked one listener per server
204
+ * that was ever constructed: nothing removed them, so a process creating
205
+ * several servers — every test run — walked into
206
+ * MaxListenersExceededWarning.
207
+ */
208
+ handleSigint = () => {
209
+ void this.shutdown();
210
+ };
211
+ /**
212
+ * Close the server and set the exit status, without calling process.exit().
213
+ *
214
+ * close() removes the SIGINT listener and closes the transport, leaving
215
+ * nothing to hold the event loop, so the process ends on its own with this
216
+ * status. Forcing the exit truncates whatever else is still unwinding, and
217
+ * is untestable here: process.exit() inside a fire-and-forget handler
218
+ * escapes any spy a test installs, because the handler returns before the
219
+ * promise settles. Vitest then reports "process.exit unexpectedly called"
220
+ * and fails the run even though every test passed.
221
+ *
222
+ * Returned so callers - and tests - can await the shutdown deterministically.
223
+ */
224
+ async shutdown() {
225
+ try {
226
+ await this.close();
227
+ process.exitCode = 0;
228
+ }
229
+ catch (error) {
230
+ console.error("[MCP Error] Failed to close cleanly", error);
231
+ process.exitCode = 1;
232
+ }
203
233
  }
204
234
  setupHandlers() {
205
235
  // List available tools (dynamically generated to include current skill list)
@@ -460,6 +490,9 @@ export class LocalSkillsServer {
460
490
  * ```
461
491
  */
462
492
  async close() {
493
+ // Drop the signal handler first so repeated construct/close cycles do not
494
+ // accumulate listeners on the process.
495
+ process.off("SIGINT", this.handleSigint);
463
496
  await this.server.close();
464
497
  // Allow time for all handles to be released (important on Windows)
465
498
  await new Promise((resolve) => setTimeout(resolve, 100));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "local-skills-mcp",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Universal MCP server enabling any LLM or AI agent to utilize expert skills from your local filesystem. Reduces context consumption through lazy loading - only skill names visible initially, full content loads on-demand. Works with Claude, Cline, custom agents, and any MCP-compatible client.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",