ast-mcp-server 0.11.1 → 0.12.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +35 -2
  2. package/README.md +32 -2
  3. package/SECURITY.md +1 -1
  4. package/dist/batch/schema.js +7 -16
  5. package/dist/compiler-worker-entry.js +51 -0
  6. package/dist/index.js +20 -120
  7. package/dist/server.js +2 -32
  8. package/dist/services/agent-targets.js +2 -14
  9. package/dist/services/compiler-worker-host.js +422 -0
  10. package/dist/services/compiler-worker-protocol.js +95 -0
  11. package/dist/services/diagnostics.js +55 -0
  12. package/dist/services/operations.js +3 -1
  13. package/dist/services/project.js +7 -0
  14. package/dist/services/public-errors.js +6 -3
  15. package/dist/services/runtime-logger.js +5 -0
  16. package/dist/services/runtime-policy.js +61 -0
  17. package/dist/tools/apply_operation.js +5 -2
  18. package/dist/tools/catalog.js +80 -0
  19. package/dist/tools/explore.js +5 -2
  20. package/dist/tools/find_references.js +5 -2
  21. package/dist/tools/find_test_candidates.js +5 -2
  22. package/dist/tools/get_diagnostics.js +36 -4
  23. package/dist/tools/get_file.js +5 -2
  24. package/dist/tools/get_impact.js +5 -2
  25. package/dist/tools/get_operation_preview.js +5 -2
  26. package/dist/tools/get_outline.js +5 -2
  27. package/dist/tools/get_project_status.js +5 -2
  28. package/dist/tools/get_symbol_source.js +5 -2
  29. package/dist/tools/list_files.js +5 -2
  30. package/dist/tools/rename_symbol.js +5 -2
  31. package/dist/tools/replace_symbol_body.js +5 -2
  32. package/dist/tools/scaffold_class.js +5 -2
  33. package/dist/tools/search_symbols.js +5 -2
  34. package/dist/worker-runtime.js +126 -0
  35. package/docs/support.md +22 -6
  36. package/package.json +3 -3
  37. package/skills/structural-code-editing/SKILL.md +14 -2
  38. package/skills/structural-code-editing/releases.json +17 -2
@@ -3,6 +3,7 @@ import { prepareScaffoldClass } from "../services/operations.js";
3
3
  import { createRequestContext } from "../services/request-context.js";
4
4
  import { createToolErrorContext, errorResult, structuredResult } from "./result.js";
5
5
  import { PreparedOperationOutputSchema, serializePreparedOperation } from "./operation-schema.js";
6
+ const TOOL_NAME = "ast_scaffold_class";
6
7
  const IdentifierSchema = z.string().min(1).max(200);
7
8
  const TypeTextSchema = z.string().min(1).max(10_000);
8
9
  const AccessSchema = z.enum(["public", "protected", "private"]);
@@ -111,7 +112,7 @@ export function registerScaffoldClass(server) {
111
112
  // The SDK compatibility overload exceeds TypeScript's instantiation depth for this schema.
112
113
  // Keep the complete runtime schema and isolate only the registrar type.
113
114
  const registerTool = server.registerTool.bind(server);
114
- registerTool("ast_scaffold_class", {
115
+ registerTool(TOOL_NAME, {
115
116
  title: "Prepare Class Scaffold",
116
117
  description: "Prepares a hash-bound new TypeScript class file without writing it. Each method body throws an explicit not-implemented error. Review the diff, then apply the returned operation_id and plan_hash with ast_apply_operation.",
117
118
  inputSchema: ScaffoldClassInputSchema,
@@ -141,7 +142,9 @@ export function registerScaffoldClass(server) {
141
142
  return structuredResult(structuredContent);
142
143
  }
143
144
  catch (error) {
144
- return errorResult(error, createToolErrorContext("ast_scaffold_class", args.project_root));
145
+ return errorResult(error, createToolErrorContext(TOOL_NAME, args.project_root));
145
146
  }
146
147
  });
147
148
  }
149
+ // prettier-ignore
150
+ export const toolDescriptor = Object.freeze({ name: TOOL_NAME, register: registerScaffoldClass, compatibility: "required", effect: "prepare", batch: "prepare", directOutputFormats: Object.freeze(["json"]) });
@@ -4,6 +4,7 @@ import { withProject, reportSymbolIndexFailure } from "../services/project.js";
4
4
  import { createRequestContext } from "../services/request-context.js";
5
5
  import { searchProjectSymbolsPage, searchProjectSymbolsPageWithIndex, } from "../services/symbols.js";
6
6
  import { createToolErrorContext, errorResult, formattedResult, ToolOutputFormatInputSchema, } from "./result.js";
7
+ const TOOL_NAME = "ast_search_symbols";
7
8
  const SEARCH_DEFAULT_LIMIT = 20;
8
9
  const SearchDetailSchema = z.enum(["selectors", "summary", "full"]).default("summary");
9
10
  const AstSearchSymbolsInputSchema = z.object({
@@ -77,7 +78,7 @@ function projectSymbols(detail, symbols) {
77
78
  return symbols.map(({ file, selector, kind }) => ({ file, selector, kind }));
78
79
  }
79
80
  export function registerSearchSymbols(server) {
80
- server.registerTool("ast_search_symbols", {
81
+ server.registerTool(TOOL_NAME, {
81
82
  title: "Search project symbols",
82
83
  description: "Ranks structural declarations and returns exact file/symbol selectors for downstream AST tools.",
83
84
  inputSchema: AstSearchSymbolsInputSchema,
@@ -108,7 +109,9 @@ export function registerSearchSymbols(server) {
108
109
  return formattedResult(outputSchema, structuredContent, output_format);
109
110
  }
110
111
  catch (error) {
111
- return errorResult(error, createToolErrorContext("ast_search_symbols", project_root));
112
+ return errorResult(error, createToolErrorContext(TOOL_NAME, project_root));
112
113
  }
113
114
  });
114
115
  }
116
+ // prettier-ignore
117
+ export const toolDescriptor = Object.freeze({ name: TOOL_NAME, register: registerSearchSymbols, compatibility: "required", effect: "read", batch: "read", directOutputFormats: Object.freeze(["json", "toon"]) });
@@ -0,0 +1,126 @@
1
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
2
+ import { createServer } from "./server.js";
3
+ import { beginProjectShutdown, closeDrainedProjectSessions, getProjectRuntimeShutdownSnapshot, prepareProjectRuntimeForStartup, waitForProjectCompletionCriticalOperationsToDrain, waitForProjectOperationsToDrain, } from "./services/project.js";
4
+ import { RuntimeActivityTracker } from "./services/runtime-activity.js";
5
+ import { readRuntimePolicy } from "./services/runtime-policy.js";
6
+ import { emitIncompleteShutdownEvent, ShutdownCoordinator, } from "./services/shutdown.js";
7
+ function emitShutdownFailureEvent() {
8
+ process.stderr.write(`${JSON.stringify({ event: "shutdown_failed", version: 1 })}\n`);
9
+ }
10
+ export async function runStdioServer(options = {}) {
11
+ if (options.server && !options.runtimeActivity) {
12
+ throw new Error("An injected MCP server requires its runtime activity tracker.");
13
+ }
14
+ prepareProjectRuntimeForStartup();
15
+ const runtimeActivity = options.runtimeActivity ?? new RuntimeActivityTracker();
16
+ runtimeActivity.prepareForStartup();
17
+ const server = options.server ?? createServer({ runtimeActivity });
18
+ const transport = options.transport ?? new StdioServerTransport();
19
+ const send = transport.send.bind(transport);
20
+ transport.send = (message, sendOptions) => runtimeActivity.trackSend(() => send(message, sendOptions));
21
+ const runtimePolicy = options.runtimePolicy ?? readRuntimePolicy();
22
+ const installProcessHandlers = options.installProcessHandlers ?? true;
23
+ const exit = options.exit ?? ((code) => process.exit(code));
24
+ const protocol = server.server;
25
+ const previousTransportClose = protocol.onclose;
26
+ let listenersInstalled = false;
27
+ let terminalHandlerInstalled = false;
28
+ const onSigint = () => requestFromRuntime("sigint");
29
+ const onSigterm = () => requestFromRuntime("sigterm");
30
+ const onStdinEnd = () => requestFromRuntime("stdin_eof");
31
+ const onStdinClose = () => requestFromRuntime("stdin_eof");
32
+ const onTransportClose = () => {
33
+ previousTransportClose?.();
34
+ requestFromRuntime("transport_closed");
35
+ };
36
+ const removeLifecycleListeners = () => {
37
+ if (listenersInstalled) {
38
+ process.off("SIGINT", onSigint);
39
+ process.off("SIGTERM", onSigterm);
40
+ process.stdin.off("end", onStdinEnd);
41
+ process.stdin.off("close", onStdinClose);
42
+ listenersInstalled = false;
43
+ }
44
+ if (protocol.onclose === onTransportClose)
45
+ protocol.onclose = previousTransportClose;
46
+ };
47
+ const coordinator = new ShutdownCoordinator({
48
+ drainTimeoutMs: runtimePolicy.shutdownDrainTimeoutMs,
49
+ stopAdmissionAndCancel: () => {
50
+ runtimeActivity.beginShutdown();
51
+ return beginProjectShutdown();
52
+ },
53
+ getDrainSnapshot: getProjectRuntimeShutdownSnapshot,
54
+ waitForDrain: async () => {
55
+ await Promise.all([waitForProjectOperationsToDrain(), runtimeActivity.waitForIdle()]);
56
+ },
57
+ waitForCompletionCriticalOperationsToDrain: waitForProjectCompletionCriticalOperationsToDrain,
58
+ closeMcp: async () => {
59
+ await server.close();
60
+ },
61
+ closeProjects: closeDrainedProjectSessions,
62
+ emitIncompleteShutdown: emitIncompleteShutdownEvent,
63
+ onCompletionCriticalWait: options.onCompletionCriticalWait,
64
+ });
65
+ let lifecycleCompletion;
66
+ function requestShutdown(trigger) {
67
+ lifecycleCompletion ??= coordinator.shutdown(trigger).finally(removeLifecycleListeners);
68
+ return lifecycleCompletion;
69
+ }
70
+ function requestFromRuntime(trigger) {
71
+ try {
72
+ options.onRuntimeTrigger?.(trigger);
73
+ }
74
+ catch {
75
+ // Runtime observation is non-authoritative and must never interrupt shutdown.
76
+ }
77
+ const completion = requestShutdown(trigger);
78
+ if (terminalHandlerInstalled)
79
+ return;
80
+ terminalHandlerInstalled = true;
81
+ void completion
82
+ .then((result) => {
83
+ if (result.state === "forced_noncritical")
84
+ exit(1);
85
+ })
86
+ .catch(() => {
87
+ emitShutdownFailureEvent();
88
+ exit(1);
89
+ });
90
+ }
91
+ protocol.onclose = onTransportClose;
92
+ if (installProcessHandlers) {
93
+ process.on("SIGINT", onSigint);
94
+ process.on("SIGTERM", onSigterm);
95
+ process.stdin.once("end", onStdinEnd);
96
+ process.stdin.once("close", onStdinClose);
97
+ listenersInstalled = true;
98
+ }
99
+ try {
100
+ await server.connect(transport);
101
+ }
102
+ catch (error) {
103
+ await requestShutdown("requested").catch(() => undefined);
104
+ throw error;
105
+ }
106
+ if (options.logStartup ?? true)
107
+ process.stderr.write("ast-mcp-server running over stdio.\n");
108
+ return Object.freeze({
109
+ shutdown: (trigger = "requested") => requestShutdown(trigger),
110
+ shutdownGraceMs: runtimePolicy.shutdownDrainTimeoutMs,
111
+ snapshot: () => {
112
+ const runtime = runtimeActivity.snapshot(), project = getProjectRuntimeShutdownSnapshot();
113
+ return Object.freeze({
114
+ runtime_admission: runtime.admission,
115
+ active_requests: runtime.active_requests,
116
+ active_sends: runtime.active_sends,
117
+ project_admission: project.admission,
118
+ session_count: project.session_count,
119
+ active_operations: project.active_operations,
120
+ queued_operations: project.queued_operations,
121
+ completion_critical_operations: project.completion_critical_operations,
122
+ mutation_history: project.mutation_history,
123
+ });
124
+ },
125
+ });
126
+ }
package/docs/support.md CHANGED
@@ -1,20 +1,20 @@
1
1
  # Support policy
2
2
 
3
- This document defines the supported platform, runtime, persistence, and operational boundary for published `ast-mcp-server` v0.10.0 and the local `0.11.1` recovery candidate.
3
+ This document defines the supported platform, runtime, persistence, and operational boundary for published `ast-mcp-server` v0.11.2 and the local `0.12.0` release candidate.
4
4
 
5
5
  ## Supported release target
6
6
 
7
7
  | Environment | Status | Contract |
8
8
  | ----------------------------------------------------------------------------- | ----------- | --------------------------------------------------------------------------------------------- |
9
9
  | Linux x64 with required GNU coreutils and procfs, Node.js 22.5.0 | Historical | Immutable v0.8.1 release evidence; not the runtime floor of the published or candidate lines. |
10
- | Linux x64 with required GNU coreutils and procfs, exact Node.js 22.13.0 | Supported | Published v0.10.0 and local 0.11.1 matrices, each bound to its own package and tree bytes. |
11
- | Linux x64 with required GNU coreutils and procfs, current Node.js 24 line | Supported | Published v0.10.0 and local 0.11.1 matrices, each bound to its own package and tree bytes. |
10
+ | Linux x64 with required GNU coreutils and procfs, exact Node.js 22.13.0 | Supported | Published v0.11.2 and local 0.12.0 matrices, each bound to its own package and tree bytes. |
11
+ | Linux x64 with required GNU coreutils and procfs, current Node.js 24 line | Supported | Published v0.11.2 and local 0.12.0 matrices, each bound to its own package and tree bytes. |
12
12
  | Other Linux architectures or systems without the required filesystem features | Unverified | Not supported until equivalent architecture, mutation, and filesystem-publication gates pass. |
13
13
  | macOS | Unverified | Not supported until equivalent filesystem, process, package, mutation, and canary gates pass. |
14
14
  | Windows | Unverified | Not supported until equivalent filesystem, process, package, mutation, and canary gates pass. |
15
15
  | Remote, untrusted, or multi-tenant service use | Unsupported | No network authentication, sandbox, or tenant-isolation boundary is provided. |
16
16
 
17
- The local `0.11.1` recovery candidate requires Node.js `>=22.13.0`; its matrix targets exact Node.js 22.13.0 and the governed Node.js 24 major. Published v0.10.0 retains its immutable `>=22.13.0` metadata and exact Node.js 22.13.0/24 release evidence. The earlier v0.8.1 Node.js 22.5.0/24 matrix remains historical evidence for those bytes only. A future runtime satisfying an engine range is not automatically a verified release target.
17
+ The local `0.12.0` release candidate requires Node.js `>=22.13.0`; its matrix targets exact Node.js 22.13.0 and the governed Node.js 24 major. Published v0.11.2 retains its immutable `>=22.13.0` metadata and exact Node.js 22.13.0/24 release evidence. The earlier v0.8.1 Node.js 22.5.0/24 matrix remains historical evidence for those bytes only. A future runtime satisfying an engine range is not automatically a verified release target.
18
18
 
19
19
  The checked-evidence freezer requires GNU coreutils 9.7 `mv` with `--update=none-fail`, `--no-copy`, and `--no-target-directory`. Managed setup-file mutation additionally requires that same `mv` with `--exchange`, GNU coreutils `ln -L -T`, procfs descriptor paths at `/proc/self/fd`, `O_DIRECTORY`, and `O_NOFOLLOW`. It fails closed when any verified Linux primitive is unavailable. Equivalent publication, exchange, descriptor-link, and descriptor-relative mutation semantics have not been verified on other operating systems or architectures.
20
20
 
@@ -32,9 +32,25 @@ The server does not provide:
32
32
 
33
33
  Operation locks coordinate cooperating same-user processes. They do not stop editors, network filesystems, or hostile same-user writers. Report-set freezer coordination likewise assumes cooperating same-UID processes and cannot defend checked evidence against a malicious process with the same filesystem authority. The freezer guarantees no-replace atomic visibility of the checked directory; it does not claim persistence across sudden power loss because parent-directory `fsync` durability is not established.
34
34
 
35
+ ## Optional supervised compiler worker
36
+
37
+ The default and rollback remain `AST_COMPILER_WORKER_MODE=in_process`. Explicit `supervised` mode keeps one lightweight stdio parent connected to one disposable compiler child per connection:
38
+
39
+ ```bash
40
+ AST_COMPILER_WORKER_MODE=supervised \
41
+ AST_COMPILER_WORKER_IDLE_TTL_MS=60000 \
42
+ ast-mcp-server
43
+ ```
44
+
45
+ The parent waits for `ready` before replaying bounded initialization state. Generation-affine forwarding and cancellation reject stale settlements and do not retry forwarded calls. Recycling requires stable parent and child quiescence; mutation history, live leases, and completion-critical work keep the child pinned. Parent death closes admission and permits only completion-critical drain before exit.
46
+
47
+ Set the TTL to `0` to disable recycling without removing the relay, or select `in_process` to remove the worker boundary. No shared daemon, pool, cross-client deduplication, default promotion, or automatic mutation-plan repair is provided.
48
+
49
+ The scoped Linux evidence passed on exact Node.js 22.13.0 and the governed Node.js 24 line: three parents each completed three load/idle/respawn cycles with at least 80% PSS-delta reclamation and no upward trend. Respawns retained the compiler fingerprint, recorded six SQLite hits, reused exactly 400 files, rebuilt zero, and returned equivalent reads. Diagnostics remained bounded and redacted, and parent-death inspection found zero orphan processes. These results do not establish support for macOS, Windows, or other Linux environments.
50
+
35
51
  ## Symbol-index persistence
36
52
 
37
- Published v0.10.0 and the local `0.11.1` recovery candidate select native SQLite when the persistence setting is absent or explicitly `enabled`; operators requiring no persistent index state must set `disabled` explicitly:
53
+ Published v0.11.2 and the local `0.12.0` release candidate select native SQLite when the persistence setting is absent or explicitly `enabled`; operators requiring no persistent index state must set `disabled` explicitly:
38
54
 
39
55
  ```bash
40
56
  AST_SYMBOL_INDEX_PERSISTENCE=disabled \
@@ -64,7 +80,7 @@ Both commands are bounded and path-free. Clear preflights the tree, refuses unsa
64
80
 
65
81
  ## Production-readiness acceptance
66
82
 
67
- The four retained Linux x64 production-readiness reports cover `ast-mcp-server` and `x-scraper` under Node.js 22.5.0 and Node.js 24 for package version 0.6.0, commit `2d0b21bbb80fae1acfca6a85d5891d87e68b59c1`, and tree `af931d49769fabdf06f623965a6cfe1f9afb8a81`. They are historical integration evidence only: they are not reattributed to v0.8.1, published-next v0.9.0 or v0.9.1, the local 0.9.2 candidate, published v0.10.0, published-next v0.11.0, or the local v0.11.1 recovery candidate. The exact 0.9.0 and 0.9.1 release matrices remain historical evidence for their immutable published-next bytes, the exact 0.9.2 matrix remains historical local-candidate evidence, the exact 0.10.0 matrix remains historical published-release evidence, and the exact 0.11.0 matrix remains historical evidence for its immutable published-next bytes before registry verification exposed verifier drift. A separate exact 0.11.1 release matrix is the recovery-candidate gate for current repository bytes under both supported runtime lines, including local-registry managed-asset verification; none of these matrices rebinds the older retained reports. MCP-PROD-404 remains normative for admission:
83
+ The four retained Linux x64 production-readiness reports cover `ast-mcp-server` and `x-scraper` under Node.js 22.5.0 and Node.js 24 for package version 0.6.0, commit `2d0b21bbb80fae1acfca6a85d5891d87e68b59c1`, and tree `af931d49769fabdf06f623965a6cfe1f9afb8a81`. They are historical integration evidence only: they are not reattributed to v0.8.1, published-next v0.9.0 or v0.9.1, the local 0.9.2 candidate, published v0.10.0, published-next v0.11.0 or v0.11.1, published v0.11.2, or the local v0.12.0 release candidate. The exact 0.9.0 and 0.9.1 release matrices remain historical evidence for their immutable published-next bytes, the exact 0.9.2 matrix remains historical local-candidate evidence, the exact 0.10.0 matrix remains historical published-release evidence, the exact 0.11.0 and 0.11.1 matrices remain historical evidence for their immutable published-next bytes before public-registry verification exposed their distinct verifier defects, and the exact 0.11.2 matrix remains historical published-release evidence. A separate exact 0.12.0 release matrix is the release-candidate gate for current repository bytes under both supported runtime lines, including bounded diagnostic aggregates, catalog-derived tool capability projections, and their independent release oracles; none of these matrices rebinds the older retained reports. MCP-PROD-404 remains normative for admission:
68
84
 
69
85
  - zero semantic mismatches across disabled, cold, warm, restart, and rollback reads;
70
86
  - byte-identical real-repository status and worktree trees;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ast-mcp-server",
3
- "version": "0.11.1",
3
+ "version": "0.12.0",
4
4
  "description": "Structural code MCP server and batch CLI for compact TypeScript/JavaScript reads and hash-bound AST edits.",
5
5
  "keywords": [
6
6
  "mcp",
@@ -49,7 +49,7 @@
49
49
  "scripts": {
50
50
  "build": "tsc",
51
51
  "typecheck": "tsc --noEmit && tsc -p tsconfig.test.json",
52
- "test": "vitest run",
52
+ "test": "vitest run --exclude test/supervised-worker.integration.test.ts && yarn build && vitest run test/supervised-worker.integration.test.ts --no-file-parallelism",
53
53
  "test:watch": "vitest",
54
54
  "test:mcp": "yarn build && node scripts/mcp-smoke.mjs",
55
55
  "test:lifecycle": "yarn build && node scripts/mcp-lifecycle-smoke.mjs",
@@ -97,5 +97,5 @@
97
97
  "typescript-eslint": "^8.65.0",
98
98
  "vitest": "^4.1.10"
99
99
  },
100
- "gitHead": "7aee46639d887a406c20c10fd66de7fa179d9e92"
100
+ "gitHead": "3991d0a74e672c6c4d3fbd1c8bbb1a60009515ec"
101
101
  }
@@ -4,7 +4,7 @@ description: "Trigger: navegar, analizar o editar TypeScript/JavaScript con el c
4
4
  license: "ISC"
5
5
  metadata:
6
6
  author: "yail"
7
- version: "4.5.0"
7
+ version: "4.6.0"
8
8
  hermes:
9
9
  tags: ["typescript", "javascript", "ast", "refactoring", "mcp"]
10
10
  homepage: "https://github.com/yailPeralta/ast-mcp-server"
@@ -18,7 +18,7 @@ Cargar este skill antes de navegar semánticamente, analizar impacto o referenci
18
18
 
19
19
  No forzar un roundtrip AST para Markdown, configuración, comentarios ni una edición textual trivial en un archivo ya conocido. Si las tools `ast_*` no están disponibles, declarar el fallback y no presentar búsquedas textuales como evidencia compiler-backed.
20
20
 
21
- The local 0.11.1 recovery candidate requires Node.js `>=22.13.0` and is verified with exact Node.js 22.13.0 plus the governed Node.js 24 line. Published v0.10.0 retains its immutable Node.js 22.13.0/24 release evidence.
21
+ The local 0.12.0 release candidate requires Node.js `>=22.13.0` and is verified with exact Node.js 22.13.0 plus the governed Node.js 24 line. Published v0.11.2 retains its immutable Node.js 22.13.0/24 release evidence.
22
22
 
23
23
  ## Hard Rules
24
24
 
@@ -29,6 +29,18 @@ The local 0.11.1 recovery candidate requires Node.js `>=22.13.0` and is verified
29
29
  - Nunca reconstruir postimages desde un diff; después del apply, ejecutar el gate canónico del proyecto.
30
30
  - Conservar `correlation_id` en errores públicos sin exponer source, paths absolutos, argumentos, environment, cache, stacks ni credenciales.
31
31
 
32
+ ## Diagnostic aggregates
33
+
34
+ `ast_get_diagnostics` keeps its existing response shape unless `include_aggregates: true` is requested. Enabled summaries cover the complete normalized snapshot, not only the selected raw page, and cap both code and file groups at 20.
35
+
36
+ For each dimension, `groups.length + omitted_group_count = total_group_count` and group counts sum to `covered_diagnostic_count`. Code coverage plus omitted diagnostics equals the total; file coverage additionally includes `unfiled_diagnostic_count`. File groups expose normalized project-relative paths only and may include paths absent from the raw page.
37
+
38
+ ## Contributor contract
39
+
40
+ Al agregar o modificar una tool, mantener schemas, metadata, annotations, handler, errores y serialización en su módulo. Exportar un descriptor congelado y ubicarlo deliberadamente en `src/tools/catalog.ts`; el catálogo solo admite hechos estáticos de efecto, batch, compatibilidad y formatos directos.
41
+
42
+ Las expectativas de `tools/list` deben seguir siendo independientes: revisar el inventario y metadata completos antes de actualizar sus hashes, sin importar ni derivar valores desde el catálogo.
43
+
32
44
  ## Decision Gates
33
45
 
34
46
  | Situación | Acción |
@@ -2,11 +2,11 @@
2
2
  "schema_version": 2,
3
3
  "algorithm": "sha256",
4
4
  "current": {
5
- "version": "4.5.0",
5
+ "version": "4.6.0",
6
6
  "files": [
7
7
  {
8
8
  "path": "SKILL.md",
9
- "sha256": "2729b30ff6b7344e6680c7ee02ab540bc6db9774ad7111f091cd356f8cc9d4ce"
9
+ "sha256": "d0048ffd9a585d00791540c6fa5e0bec91ff95b1448479678f85702e6b09be8a"
10
10
  },
11
11
  {
12
12
  "path": "references/operations.md",
@@ -79,6 +79,21 @@
79
79
  "version": "4.4.0",
80
80
  "sha256": "253b588c56d44c8f5565db3f33ce227d80c7c29aa6604d362844f44b1278385a",
81
81
  "npm_versions": ["0.10.0"]
82
+ },
83
+ {
84
+ "version": "4.5.0",
85
+ "sha256": "be757e8bd98733c7ee952d63a2805dcd9877becf651b4fcb6ab63d20f6546f21",
86
+ "npm_versions": ["0.11.0"]
87
+ },
88
+ {
89
+ "version": "4.5.0",
90
+ "sha256": "2729b30ff6b7344e6680c7ee02ab540bc6db9774ad7111f091cd356f8cc9d4ce",
91
+ "npm_versions": ["0.11.1"]
92
+ },
93
+ {
94
+ "version": "4.5.0",
95
+ "sha256": "18132b4b747d135e4ccfbca9e2190a9afb41e144cc06c31c5e6bc0f1571e11da",
96
+ "npm_versions": ["0.11.2"]
82
97
  }
83
98
  ]
84
99
  }