@a5c-ai/hooks-mux-adapter-hermes 5.0.1-staging.334ab59e3

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 ADDED
@@ -0,0 +1,31 @@
1
+ # @a5c-ai/hooks-mux-adapter-hermes
2
+
3
+ Hermes harness adapter for hooks-mux.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @a5c-ai/hooks-mux-adapter-hermes @a5c-ai/hooks-mux-core
9
+ ```
10
+
11
+ This package ships the built adapter runtime in `dist/` and this package README for npm publish-surface auditing.
12
+
13
+ ## Usage
14
+
15
+ ```ts
16
+ import {
17
+ createAdapter,
18
+ normalizeHermesEvent,
19
+ renderHermesOutput,
20
+ } from "@a5c-ai/hooks-mux-adapter-hermes";
21
+ ```
22
+
23
+ The package exposes Hermes-specific normalization, phase mappings, rendering helpers, and session-resolution utilities for the hooks-mux execution pipeline.
24
+
25
+ Hermes has a single `onEvent` native hook that is non-blocking and post-direction only. It cannot block or deny tool calls.
26
+
27
+ See [`packages/hooks-mux/README.md`](../README.md) for the workspace overview and `packages/hooks-mux/docs/adapter-integration-guide.md` for end-to-end integration guidance.
28
+
29
+ ## License
30
+
31
+ MIT (c) a5c-ai
@@ -0,0 +1,3 @@
1
+ import type { AdapterCapabilities } from '@a5c-ai/hooks-mux-core';
2
+ export declare function createAdapter(name?: string): AdapterCapabilities;
3
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAiBlE,wBAAgB,aAAa,CAAC,IAAI,GAAE,MAA6B,GAAG,mBAAmB,CAuBtF"}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createAdapter = createAdapter;
4
+ const agent_catalog_1 = require("@a5c-ai/agent-catalog");
5
+ /**
6
+ * Creates the Hermes adapter with its capability metadata.
7
+ *
8
+ * Reads capability data from the Atlas graph via the agent-catalog.
9
+ * Falls back to hardcoded defaults if the catalog is unavailable.
10
+ *
11
+ * Hermes has a single `onEvent` native hook that is non-blocking
12
+ * and post-direction only. It cannot block, ask, or mutate tool
13
+ * inputs/results.
14
+ *
15
+ * Spec section 17.2.
16
+ */
17
+ const DEFAULT_ADAPTER_NAME = 'hermes';
18
+ function createAdapter(name = DEFAULT_ADAPTER_NAME) {
19
+ const target = (0, agent_catalog_1.getPluginTargetDescriptor)(name);
20
+ return {
21
+ name,
22
+ family: target?.hooksMuxFamily ?? 'shell-hook',
23
+ sessionIdQuality: target?.sessionIdQuality ?? 'native',
24
+ supportsOrderedFanout: target?.supportsOrderedFanout ?? false,
25
+ supportsNativeAdditionalContext: target?.supportsNativeAdditionalContext ?? false,
26
+ supportsBlock: target?.supportsBlock ?? false,
27
+ supportsAsk: target?.supportsAsk ?? false,
28
+ supportsToolInputMutation: target?.supportsToolInputMutation ?? false,
29
+ supportsToolResultMutation: target?.supportsToolResultMutation ?? false,
30
+ supportsPersistedEnv: target?.supportsPersistedEnv ?? false,
31
+ envPersistenceMode: target?.envPersistenceMode ?? 'wrapper_only',
32
+ toolInterceptionScope: target?.toolInterceptionScope ?? 'none',
33
+ notes: [
34
+ 'single onEvent hook, non-blocking',
35
+ 'cannot block or deny tool calls',
36
+ 'post-direction only (tool.after)',
37
+ 'session ID from HERMES_SESSION env var',
38
+ 'config in ~/.hermes/cli-config.yaml',
39
+ ],
40
+ };
41
+ }
42
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":";;AAiBA,sCAuBC;AAvCD,yDAAkE;AAElE;;;;;;;;;;;GAWG;AACH,MAAM,oBAAoB,GAAG,QAAQ,CAAC;AAEtC,SAAgB,aAAa,CAAC,OAAe,oBAAoB;IAC/D,MAAM,MAAM,GAAG,IAAA,yCAAyB,EAAC,IAAI,CAAC,CAAC;IAC/C,OAAO;QACL,IAAI;QACJ,MAAM,EAAG,MAAM,EAAE,cAAgD,IAAI,YAAY;QACjF,gBAAgB,EAAG,MAAM,EAAE,gBAA4D,IAAI,QAAQ;QACnG,qBAAqB,EAAE,MAAM,EAAE,qBAAqB,IAAI,KAAK;QAC7D,+BAA+B,EAAE,MAAM,EAAE,+BAA+B,IAAI,KAAK;QACjF,aAAa,EAAE,MAAM,EAAE,aAAa,IAAI,KAAK;QAC7C,WAAW,EAAE,MAAM,EAAE,WAAW,IAAI,KAAK;QACzC,yBAAyB,EAAE,MAAM,EAAE,yBAAyB,IAAI,KAAK;QACrE,0BAA0B,EAAE,MAAM,EAAE,0BAA0B,IAAI,KAAK;QACvE,oBAAoB,EAAE,MAAM,EAAE,oBAAoB,IAAI,KAAK;QAC3D,kBAAkB,EAAG,MAAM,EAAE,kBAAgE,IAAI,cAAc;QAC/G,qBAAqB,EAAG,MAAM,EAAE,qBAAsE,IAAI,MAAM;QAChH,KAAK,EAAE;YACL,mCAAmC;YACnC,iCAAiC;YACjC,kCAAkC;YAClC,wCAAwC;YACxC,qCAAqC;SACtC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ export { createAdapter } from './adapter';
2
+ export { HERMES_PHASE_MAPPINGS, findMapping } from './mappings';
3
+ export { normalizeHermesEvent, normalizeHermesEvent as normalizeForInvoke, setAdapterName, parseStdin, extractSessionId, extractInnerPayload, ADAPTER_NAME, } from './normalizer';
4
+ export type { HermesEventPayload, } from './normalizer';
5
+ export { renderHermesOutput, renderHermesOutput as renderForInvoke, isFieldSupportedForEvent, } from './renderer';
6
+ export { resolveSessionId, isValidSessionId } from './session-resolver';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG1C,OAAO,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGhE,OAAO,EACL,oBAAoB,EACpB,oBAAoB,IAAI,kBAAkB,EAC1C,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,GACb,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,kBAAkB,GACnB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,kBAAkB,EAClB,kBAAkB,IAAI,eAAe,EACrC,wBAAwB,GACzB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isValidSessionId = exports.resolveSessionId = exports.isFieldSupportedForEvent = exports.renderForInvoke = exports.renderHermesOutput = exports.ADAPTER_NAME = exports.extractInnerPayload = exports.extractSessionId = exports.parseStdin = exports.setAdapterName = exports.normalizeForInvoke = exports.normalizeHermesEvent = exports.findMapping = exports.HERMES_PHASE_MAPPINGS = exports.createAdapter = void 0;
4
+ // Adapter capabilities
5
+ var adapter_1 = require("./adapter");
6
+ Object.defineProperty(exports, "createAdapter", { enumerable: true, get: function () { return adapter_1.createAdapter; } });
7
+ // Phase mappings
8
+ var mappings_1 = require("./mappings");
9
+ Object.defineProperty(exports, "HERMES_PHASE_MAPPINGS", { enumerable: true, get: function () { return mappings_1.HERMES_PHASE_MAPPINGS; } });
10
+ Object.defineProperty(exports, "findMapping", { enumerable: true, get: function () { return mappings_1.findMapping; } });
11
+ // Normalizer
12
+ var normalizer_1 = require("./normalizer");
13
+ Object.defineProperty(exports, "normalizeHermesEvent", { enumerable: true, get: function () { return normalizer_1.normalizeHermesEvent; } });
14
+ Object.defineProperty(exports, "normalizeForInvoke", { enumerable: true, get: function () { return normalizer_1.normalizeHermesEvent; } });
15
+ Object.defineProperty(exports, "setAdapterName", { enumerable: true, get: function () { return normalizer_1.setAdapterName; } });
16
+ Object.defineProperty(exports, "parseStdin", { enumerable: true, get: function () { return normalizer_1.parseStdin; } });
17
+ Object.defineProperty(exports, "extractSessionId", { enumerable: true, get: function () { return normalizer_1.extractSessionId; } });
18
+ Object.defineProperty(exports, "extractInnerPayload", { enumerable: true, get: function () { return normalizer_1.extractInnerPayload; } });
19
+ Object.defineProperty(exports, "ADAPTER_NAME", { enumerable: true, get: function () { return normalizer_1.ADAPTER_NAME; } });
20
+ // Renderer
21
+ var renderer_1 = require("./renderer");
22
+ Object.defineProperty(exports, "renderHermesOutput", { enumerable: true, get: function () { return renderer_1.renderHermesOutput; } });
23
+ Object.defineProperty(exports, "renderForInvoke", { enumerable: true, get: function () { return renderer_1.renderHermesOutput; } });
24
+ Object.defineProperty(exports, "isFieldSupportedForEvent", { enumerable: true, get: function () { return renderer_1.isFieldSupportedForEvent; } });
25
+ // Session resolver
26
+ var session_resolver_1 = require("./session-resolver");
27
+ Object.defineProperty(exports, "resolveSessionId", { enumerable: true, get: function () { return session_resolver_1.resolveSessionId; } });
28
+ Object.defineProperty(exports, "isValidSessionId", { enumerable: true, get: function () { return session_resolver_1.isValidSessionId; } });
29
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,uBAAuB;AACvB,qCAA0C;AAAjC,wGAAA,aAAa,OAAA;AAEtB,iBAAiB;AACjB,uCAAgE;AAAvD,iHAAA,qBAAqB,OAAA;AAAE,uGAAA,WAAW,OAAA;AAE3C,aAAa;AACb,2CAQsB;AAPpB,kHAAA,oBAAoB,OAAA;AACpB,gHAAA,oBAAoB,OAAsB;AAC1C,4GAAA,cAAc,OAAA;AACd,wGAAA,UAAU,OAAA;AACV,8GAAA,gBAAgB,OAAA;AAChB,iHAAA,mBAAmB,OAAA;AACnB,0GAAA,YAAY,OAAA;AAMd,WAAW;AACX,uCAIoB;AAHlB,8GAAA,kBAAkB,OAAA;AAClB,2GAAA,kBAAkB,OAAmB;AACrC,oHAAA,wBAAwB,OAAA;AAG1B,mBAAmB;AACnB,uDAAwE;AAA/D,oHAAA,gBAAgB,OAAA;AAAE,oHAAA,gBAAgB,OAAA"}
@@ -0,0 +1,7 @@
1
+ import type { PhaseMapping } from '@a5c-ai/hooks-mux-core';
2
+ export declare const HERMES_PHASE_MAPPINGS: PhaseMapping[];
3
+ /**
4
+ * Quick lookup from native event name to phase mapping.
5
+ */
6
+ export declare function findMapping(nativeEventName: string): PhaseMapping | undefined;
7
+ //# sourceMappingURL=mappings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mappings.d.ts","sourceRoot":"","sources":["../src/mappings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAgF3D,eAAO,MAAM,qBAAqB,EAAE,YAAY,EAAuB,CAAC;AAExE;;GAEG;AACH,wBAAgB,WAAW,CAAC,eAAe,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAE7E"}
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HERMES_PHASE_MAPPINGS = void 0;
4
+ exports.findMapping = findMapping;
5
+ const agent_catalog_1 = require("@a5c-ai/agent-catalog");
6
+ /**
7
+ * Hermes native event to canonical phase mapping table.
8
+ *
9
+ * Hermes has a single `onEvent` native hook that maps to the
10
+ * `tool.after` canonical phase. It is non-blocking and does not
11
+ * support mutation.
12
+ *
13
+ * Phase mappings are built from the Atlas graph HookMapping records
14
+ * via the agent-catalog. Falls back to hardcoded defaults if the
15
+ * catalog is unavailable.
16
+ *
17
+ * Spec section 17.2.
18
+ */
19
+ const SUPPORT_LEVEL_MAP = {
20
+ supported: 'native',
21
+ native: 'native',
22
+ lossy: 'lossy',
23
+ emulated: 'emulated',
24
+ unsupported: 'unsupported',
25
+ };
26
+ /**
27
+ * Hardcoded fallback mapping for the single Hermes onEvent hook.
28
+ * Used when the catalog is unavailable.
29
+ */
30
+ const HERMES_FALLBACK_MAPPINGS = [
31
+ {
32
+ canonicalPhase: 'tool.after',
33
+ nativeHook: 'onEvent',
34
+ supportLevel: 'native',
35
+ blockCapability: false,
36
+ mutationCapability: false,
37
+ scope: 'turn',
38
+ notes: 'Hermes single onEvent hook, non-blocking post-direction.',
39
+ },
40
+ ];
41
+ function hookMappingToPhaseMapping(mapping) {
42
+ if (!mapping.canonicalPhase)
43
+ return null;
44
+ return {
45
+ canonicalPhase: mapping.canonicalPhase,
46
+ nativeHook: mapping.nativeName,
47
+ supportLevel: SUPPORT_LEVEL_MAP[mapping.supportLevel] ?? (mapping.requiresRuntimeHooks ? 'native' : 'lossy'),
48
+ blockCapability: mapping.blockCapability ?? false,
49
+ mutationCapability: mapping.mutationCapability ?? false,
50
+ scope: (mapping.scope ?? 'turn'),
51
+ };
52
+ }
53
+ function buildFromCatalog() {
54
+ let mappings;
55
+ try {
56
+ mappings = (0, agent_catalog_1.listHookMappingsByAdapterFamily)('hermes');
57
+ }
58
+ catch {
59
+ return HERMES_FALLBACK_MAPPINGS;
60
+ }
61
+ if (mappings.length === 0) {
62
+ return HERMES_FALLBACK_MAPPINGS;
63
+ }
64
+ const phaseMappings = mappings
65
+ .map(hookMappingToPhaseMapping)
66
+ .filter((m) => m !== null);
67
+ if (phaseMappings.length === 0) {
68
+ return HERMES_FALLBACK_MAPPINGS;
69
+ }
70
+ const seen = new Set();
71
+ return phaseMappings.filter((m) => {
72
+ if (seen.has(m.nativeHook))
73
+ return false;
74
+ seen.add(m.nativeHook);
75
+ return true;
76
+ });
77
+ }
78
+ exports.HERMES_PHASE_MAPPINGS = buildFromCatalog();
79
+ /**
80
+ * Quick lookup from native event name to phase mapping.
81
+ */
82
+ function findMapping(nativeEventName) {
83
+ return exports.HERMES_PHASE_MAPPINGS.find((m) => m.nativeHook === nativeEventName);
84
+ }
85
+ //# sourceMappingURL=mappings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mappings.js","sourceRoot":"","sources":["../src/mappings.ts"],"names":[],"mappings":";;;AAqFA,kCAEC;AAtFD,yDAAwE;AAGxE;;;;;;;;;;;;GAYG;AAEH,MAAM,iBAAiB,GAAiD;IACtE,SAAS,EAAE,QAAQ;IACnB,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,UAAU;IACpB,WAAW,EAAE,aAAa;CAC3B,CAAC;AAEF;;;GAGG;AACH,MAAM,wBAAwB,GAAmB;IAC/C;QACE,cAAc,EAAE,YAAY;QAC5B,UAAU,EAAE,SAAS;QACrB,YAAY,EAAE,QAAQ;QACtB,eAAe,EAAE,KAAK;QACtB,kBAAkB,EAAE,KAAK;QACzB,KAAK,EAAE,MAAM;QACb,KAAK,EAAE,0DAA0D;KAClE;CACF,CAAC;AAEF,SAAS,yBAAyB,CAAC,OAA8B;IAC/D,IAAI,CAAC,OAAO,CAAC,cAAc;QAAE,OAAO,IAAI,CAAC;IACzC,OAAO;QACL,cAAc,EAAE,OAAO,CAAC,cAAgD;QACxE,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,YAAY,EAAE,iBAAiB,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;QAC5G,eAAe,EAAE,OAAO,CAAC,eAAe,IAAI,KAAK;QACjD,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,IAAI,KAAK;QACvD,KAAK,EAAE,CAAC,OAAO,CAAC,KAAK,IAAI,MAAM,CAA0B;KAC1D,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB;IACvB,IAAI,QAAiC,CAAC;IACtC,IAAI,CAAC;QACH,QAAQ,GAAG,IAAA,+CAA+B,EAAC,QAAQ,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,wBAAwB,CAAC;IAClC,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,wBAAwB,CAAC;IAClC,CAAC;IACD,MAAM,aAAa,GAAG,QAAQ;SAC3B,GAAG,CAAC,yBAAyB,CAAC;SAC9B,MAAM,CAAC,CAAC,CAAC,EAAqB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;IAEhD,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,wBAAwB,CAAC;IAClC,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QAChC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC;YAAE,OAAO,KAAK,CAAC;QACzC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAEY,QAAA,qBAAqB,GAAmB,gBAAgB,EAAE,CAAC;AAExE;;GAEG;AACH,SAAgB,WAAW,CAAC,eAAuB;IACjD,OAAO,6BAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,eAAe,CAAC,CAAC;AAC7E,CAAC"}
@@ -0,0 +1,46 @@
1
+ import { type UnifiedHookEvent } from '@a5c-ai/hooks-mux-core';
2
+ /** The default adapter identifier used in all normalized events. */
3
+ export declare const ADAPTER_NAME = "hermes";
4
+ /** Override the adapter name used in normalized events. */
5
+ export declare function setAdapterName(name: string): void;
6
+ /**
7
+ * Shape of a Hermes onEvent stdin payload.
8
+ * Hermes delivers a single `{ event, payload }` JSON object on stdin.
9
+ * Fields may be absent or null -- fail open per spec 17.2.
10
+ */
11
+ export interface HermesEventPayload {
12
+ event?: string;
13
+ payload?: Record<string, unknown>;
14
+ [key: string]: unknown;
15
+ }
16
+ /**
17
+ * Parse raw stdin input into a typed object.
18
+ * Hermes hooks receive JSON on stdin in the shape `{ event: string, payload: object }`.
19
+ * If parsing fails, return empty object (fail-open per spec 17.2).
20
+ */
21
+ export declare function parseStdin(raw: unknown): Record<string, unknown>;
22
+ /**
23
+ * Extract the inner payload from the Hermes `{ event, payload }` envelope.
24
+ * Returns the payload object, or the raw parsed object if no envelope found.
25
+ */
26
+ export declare function extractInnerPayload(parsed: Record<string, unknown>): Record<string, unknown>;
27
+ /**
28
+ * Extract session ID from environment variables.
29
+ * Hermes does not provide a session_id in stdin; instead it uses the
30
+ * HERMES_SESSION env var.
31
+ */
32
+ export declare function extractSessionId(env: Record<string, string>): string | null;
33
+ /**
34
+ * Normalize a raw Hermes hook invocation into a UnifiedHookEvent.
35
+ *
36
+ * Hermes has a single `onEvent` native hook. The stdin payload is a
37
+ * JSON object with `{ event: string, payload: object }`. The `event`
38
+ * field describes the kind of event, and `payload` contains the event
39
+ * data. Session identity comes from the HERMES_SESSION env var.
40
+ *
41
+ * @param rawEventName - The native Hermes event name (always 'onEvent')
42
+ * @param stdinPayload - Raw stdin content (string or parsed object)
43
+ * @param env - Environment variables at invocation time
44
+ */
45
+ export declare function normalizeHermesEvent(rawEventName: string, stdinPayload: unknown, env?: Record<string, string>): UnifiedHookEvent;
46
+ //# sourceMappingURL=normalizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizer.d.ts","sourceRoot":"","sources":["../src/normalizer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,gBAAgB,EAAyB,MAAM,wBAAwB,CAAC;AAGtG,oEAAoE;AACpE,eAAO,MAAM,YAAY,WAAW,CAAC;AAKrC,2DAA2D;AAC3D,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAEjD;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiBhE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAK5F;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,GAAG,IAAI,CAM3E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,OAAO,EACrB,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAC/B,gBAAgB,CA2ClB"}
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ADAPTER_NAME = void 0;
4
+ exports.setAdapterName = setAdapterName;
5
+ exports.parseStdin = parseStdin;
6
+ exports.extractInnerPayload = extractInnerPayload;
7
+ exports.extractSessionId = extractSessionId;
8
+ exports.normalizeHermesEvent = normalizeHermesEvent;
9
+ const hooks_mux_core_1 = require("@a5c-ai/hooks-mux-core");
10
+ const mappings_1 = require("./mappings");
11
+ /** The default adapter identifier used in all normalized events. */
12
+ exports.ADAPTER_NAME = 'hermes';
13
+ /** The mutable adapter name, defaulting to the Hermes adapter identity. */
14
+ let _adapterName = exports.ADAPTER_NAME;
15
+ /** Override the adapter name used in normalized events. */
16
+ function setAdapterName(name) {
17
+ _adapterName = name;
18
+ }
19
+ /**
20
+ * Parse raw stdin input into a typed object.
21
+ * Hermes hooks receive JSON on stdin in the shape `{ event: string, payload: object }`.
22
+ * If parsing fails, return empty object (fail-open per spec 17.2).
23
+ */
24
+ function parseStdin(raw) {
25
+ if (raw == null)
26
+ return {};
27
+ if (typeof raw === 'string') {
28
+ try {
29
+ const parsed = JSON.parse(raw);
30
+ if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
31
+ return parsed;
32
+ }
33
+ }
34
+ catch {
35
+ // fail open
36
+ }
37
+ return {};
38
+ }
39
+ if (typeof raw === 'object' && !Array.isArray(raw)) {
40
+ return raw;
41
+ }
42
+ return {};
43
+ }
44
+ /**
45
+ * Extract the inner payload from the Hermes `{ event, payload }` envelope.
46
+ * Returns the payload object, or the raw parsed object if no envelope found.
47
+ */
48
+ function extractInnerPayload(parsed) {
49
+ if (typeof parsed['payload'] === 'object' && parsed['payload'] !== null && !Array.isArray(parsed['payload'])) {
50
+ return parsed['payload'];
51
+ }
52
+ return parsed;
53
+ }
54
+ /**
55
+ * Extract session ID from environment variables.
56
+ * Hermes does not provide a session_id in stdin; instead it uses the
57
+ * HERMES_SESSION env var.
58
+ */
59
+ function extractSessionId(env) {
60
+ const hermesSession = env['HERMES_SESSION'];
61
+ if (typeof hermesSession === 'string' && hermesSession.length > 0) {
62
+ return hermesSession;
63
+ }
64
+ return null;
65
+ }
66
+ /**
67
+ * Normalize a raw Hermes hook invocation into a UnifiedHookEvent.
68
+ *
69
+ * Hermes has a single `onEvent` native hook. The stdin payload is a
70
+ * JSON object with `{ event: string, payload: object }`. The `event`
71
+ * field describes the kind of event, and `payload` contains the event
72
+ * data. Session identity comes from the HERMES_SESSION env var.
73
+ *
74
+ * @param rawEventName - The native Hermes event name (always 'onEvent')
75
+ * @param stdinPayload - Raw stdin content (string or parsed object)
76
+ * @param env - Environment variables at invocation time
77
+ */
78
+ function normalizeHermesEvent(rawEventName, stdinPayload, env = {}) {
79
+ const parsed = parseStdin(stdinPayload);
80
+ const innerPayload = extractInnerPayload(parsed);
81
+ // Enrich env with Hermes-specific fields
82
+ const enrichedEnv = { ...env };
83
+ // Session ID comes from env, not stdin
84
+ const sessionId = extractSessionId(enrichedEnv);
85
+ if (sessionId && !enrichedEnv['HOOKS_PROXY_SESSION_ID']) {
86
+ enrichedEnv['HOOKS_PROXY_SESSION_ID'] = sessionId;
87
+ }
88
+ // Extract common fields from inner payload
89
+ if (typeof innerPayload['cwd'] === 'string' && !enrichedEnv['HOOKS_PROXY_CWD']) {
90
+ enrichedEnv['HOOKS_PROXY_CWD'] = innerPayload['cwd'];
91
+ }
92
+ if (typeof innerPayload['model'] === 'string' && !enrichedEnv['HOOKS_PROXY_MODEL']) {
93
+ enrichedEnv['HOOKS_PROXY_MODEL'] = innerPayload['model'];
94
+ }
95
+ // Extract tool metadata if present in inner payload
96
+ if (typeof innerPayload['tool_name'] === 'string') {
97
+ if (!enrichedEnv['HOOKS_PROXY_TOOL_NAME']) {
98
+ enrichedEnv['HOOKS_PROXY_TOOL_NAME'] = innerPayload['tool_name'];
99
+ }
100
+ }
101
+ if (typeof innerPayload['tool_call_id'] === 'string') {
102
+ if (!enrichedEnv['HOOKS_PROXY_TOOL_CALL_ID']) {
103
+ enrichedEnv['HOOKS_PROXY_TOOL_CALL_ID'] = innerPayload['tool_call_id'];
104
+ }
105
+ }
106
+ const options = {
107
+ adapter: _adapterName,
108
+ rawEventName,
109
+ stdinPayload: parsed,
110
+ env: enrichedEnv,
111
+ adapterMappings: mappings_1.HERMES_PHASE_MAPPINGS,
112
+ };
113
+ return (0, hooks_mux_core_1.normalizeEvent)(options);
114
+ }
115
+ //# sourceMappingURL=normalizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizer.js","sourceRoot":"","sources":["../src/normalizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { MergedExecutionResult } from '@a5c-ai/hooks-mux-core';
2
+ /**
3
+ * Render a merged execution result into Hermes-native output JSON.
4
+ *
5
+ * Only includes the `reason` field for the onEvent hook. All other
6
+ * fields are silently dropped since Hermes is non-blocking and cannot
7
+ * act on decisions, mutations, or blocking directives.
8
+ *
9
+ * @param mergedResult - The merged result from multi-hook fan-out
10
+ * @param nativeEventName - The original Hermes event name (always 'onEvent')
11
+ * @returns Hermes-native output object, and list of dropped fields
12
+ */
13
+ export declare function renderHermesOutput(mergedResult: MergedExecutionResult, nativeEventName: string): {
14
+ output: Record<string, unknown>;
15
+ droppedFields: string[];
16
+ };
17
+ /**
18
+ * Check whether a given output field is supported for a native event.
19
+ */
20
+ export declare function isFieldSupportedForEvent(field: string, nativeEventName: string): boolean;
21
+ //# sourceMappingURL=renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAuBpE;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,qBAAqB,EACnC,eAAe,EAAE,MAAM,GACtB;IAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,aAAa,EAAE,MAAM,EAAE,CAAA;CAAE,CA0B9D;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAGxF"}
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderHermesOutput = renderHermesOutput;
4
+ exports.isFieldSupportedForEvent = isFieldSupportedForEvent;
5
+ /**
6
+ * Hermes native output fields that are supported per event type.
7
+ *
8
+ * Hermes is a non-blocking, post-direction-only adapter with a single
9
+ * `onEvent` hook. Output is minimal -- only the `reason` field is
10
+ * meaningful. Hermes cannot block, deny, mutate, or suppress tool calls.
11
+ *
12
+ * All decision, mutation, and blocking fields are dropped since
13
+ * Hermes has no mechanism to act on them.
14
+ */
15
+ /** Output fields supported on the onEvent hook. */
16
+ const ON_EVENT_FIELDS = new Set([
17
+ 'reason',
18
+ ]);
19
+ /** Map native event names to their supported output field sets. */
20
+ const SUPPORTED_FIELDS_BY_EVENT = {
21
+ onEvent: ON_EVENT_FIELDS,
22
+ };
23
+ /**
24
+ * Render a merged execution result into Hermes-native output JSON.
25
+ *
26
+ * Only includes the `reason` field for the onEvent hook. All other
27
+ * fields are silently dropped since Hermes is non-blocking and cannot
28
+ * act on decisions, mutations, or blocking directives.
29
+ *
30
+ * @param mergedResult - The merged result from multi-hook fan-out
31
+ * @param nativeEventName - The original Hermes event name (always 'onEvent')
32
+ * @returns Hermes-native output object, and list of dropped fields
33
+ */
34
+ function renderHermesOutput(mergedResult, nativeEventName) {
35
+ const supportedFields = SUPPORTED_FIELDS_BY_EVENT[nativeEventName] ?? new Set();
36
+ const output = {};
37
+ const droppedFields = [];
38
+ // Candidate output fields from the merged result
39
+ const candidates = [
40
+ { key: 'decision', value: mergedResult.decision, isEmpty: mergedResult.decision === 'noop' },
41
+ { key: 'reason', value: mergedResult.reason, isEmpty: !mergedResult.reason },
42
+ { key: 'systemMessage', value: mergedResult.systemMessage, isEmpty: !mergedResult.systemMessage },
43
+ { key: 'continueSession', value: mergedResult.continueSession, isEmpty: mergedResult.continueSession === true },
44
+ { key: 'stopReason', value: mergedResult.stopReason, isEmpty: !mergedResult.stopReason },
45
+ { key: 'suppressOutput', value: mergedResult.suppressOutput, isEmpty: !mergedResult.suppressOutput },
46
+ ];
47
+ for (const candidate of candidates) {
48
+ if (candidate.isEmpty)
49
+ continue;
50
+ if (supportedFields.has(candidate.key)) {
51
+ output[candidate.key] = candidate.value;
52
+ }
53
+ else {
54
+ droppedFields.push(candidate.key);
55
+ }
56
+ }
57
+ return { output, droppedFields };
58
+ }
59
+ /**
60
+ * Check whether a given output field is supported for a native event.
61
+ */
62
+ function isFieldSupportedForEvent(field, nativeEventName) {
63
+ const supported = SUPPORTED_FIELDS_BY_EVENT[nativeEventName];
64
+ return supported ? supported.has(field) : false;
65
+ }
66
+ //# sourceMappingURL=renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":";;AAkCA,gDA6BC;AAKD,4DAGC;AArED;;;;;;;;;GASG;AAEH,mDAAmD;AACnD,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;IAC9B,QAAQ;CACT,CAAC,CAAC;AAEH,mEAAmE;AACnE,MAAM,yBAAyB,GAAgC;IAC7D,OAAO,EAAE,eAAe;CACzB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,SAAgB,kBAAkB,CAChC,YAAmC,EACnC,eAAuB;IAEvB,MAAM,eAAe,GAAG,yBAAyB,CAAC,eAAe,CAAC,IAAI,IAAI,GAAG,EAAU,CAAC;IACxF,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,MAAM,aAAa,GAAa,EAAE,CAAC;IAEnC,iDAAiD;IACjD,MAAM,UAAU,GAA6D;QAC3E,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,YAAY,CAAC,QAAQ,KAAK,MAAM,EAAE;QAC5F,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE;QAC5E,EAAE,GAAG,EAAE,eAAe,EAAE,KAAK,EAAE,YAAY,CAAC,aAAa,EAAE,OAAO,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE;QACjG,EAAE,GAAG,EAAE,iBAAiB,EAAE,KAAK,EAAE,YAAY,CAAC,eAAe,EAAE,OAAO,EAAE,YAAY,CAAC,eAAe,KAAK,IAAI,EAAE;QAC/G,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE;QACxF,EAAE,GAAG,EAAE,gBAAgB,EAAE,KAAK,EAAE,YAAY,CAAC,cAAc,EAAE,OAAO,EAAE,CAAC,YAAY,CAAC,cAAc,EAAE;KACrG,CAAC;IAEF,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,SAAS,CAAC,OAAO;YAAE,SAAS;QAEhC,IAAI,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;YACvC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC;QAC1C,CAAC;aAAM,CAAC;YACN,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,SAAgB,wBAAwB,CAAC,KAAa,EAAE,eAAuB;IAC7E,MAAM,SAAS,GAAG,yBAAyB,CAAC,eAAe,CAAC,CAAC;IAC7D,OAAO,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAClD,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Resolve session ID from Hermes hook invocation context.
3
+ *
4
+ * Hermes provides session identity via the HERMES_SESSION env var,
5
+ * giving it 'native' sessionIdQuality in the capability model.
6
+ *
7
+ * Resolution precedence (per spec 9.2):
8
+ * 1. Explicit AGENT_SESSION_ID env var (cross-adapter override)
9
+ * 2. HERMES_SESSION env var (Hermes-native)
10
+ * 3. HERMES_RUN_ID env var (Hermes run-scoped fallback)
11
+ * 4. null (no session; caller decides fallback)
12
+ */
13
+ /**
14
+ * Extract session ID from Hermes environment and optional stdin payload.
15
+ *
16
+ * Unlike Codex, Hermes does not embed session_id in the stdin payload.
17
+ * Session identity is purely environment-driven.
18
+ *
19
+ * @param stdinPayload - Parsed stdin JSON from Hermes hook (unused for session, kept for API symmetry)
20
+ * @param env - Environment variables at invocation time
21
+ * @returns Resolved session ID or null
22
+ */
23
+ export declare function resolveSessionId(stdinPayload: Record<string, unknown>, env?: Record<string, string>): string | null;
24
+ /**
25
+ * Validate that a session ID looks reasonable.
26
+ * Hermes session IDs are typically opaque strings from the runtime.
27
+ */
28
+ export declare function isValidSessionId(sessionId: string): boolean;
29
+ //# sourceMappingURL=session-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-resolver.d.ts","sourceRoot":"","sources":["../src/session-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAC/B,MAAM,GAAG,IAAI,CAoBf;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAG3D"}
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ /**
3
+ * Resolve session ID from Hermes hook invocation context.
4
+ *
5
+ * Hermes provides session identity via the HERMES_SESSION env var,
6
+ * giving it 'native' sessionIdQuality in the capability model.
7
+ *
8
+ * Resolution precedence (per spec 9.2):
9
+ * 1. Explicit AGENT_SESSION_ID env var (cross-adapter override)
10
+ * 2. HERMES_SESSION env var (Hermes-native)
11
+ * 3. HERMES_RUN_ID env var (Hermes run-scoped fallback)
12
+ * 4. null (no session; caller decides fallback)
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.resolveSessionId = resolveSessionId;
16
+ exports.isValidSessionId = isValidSessionId;
17
+ /**
18
+ * Extract session ID from Hermes environment and optional stdin payload.
19
+ *
20
+ * Unlike Codex, Hermes does not embed session_id in the stdin payload.
21
+ * Session identity is purely environment-driven.
22
+ *
23
+ * @param stdinPayload - Parsed stdin JSON from Hermes hook (unused for session, kept for API symmetry)
24
+ * @param env - Environment variables at invocation time
25
+ * @returns Resolved session ID or null
26
+ */
27
+ function resolveSessionId(stdinPayload, env = {}) {
28
+ // Priority 1: explicit cross-adapter env override
29
+ const explicit = env['AGENT_SESSION_ID'];
30
+ if (typeof explicit === 'string' && explicit.length > 0) {
31
+ return explicit;
32
+ }
33
+ // Priority 2: Hermes-native session env var
34
+ const hermesSession = env['HERMES_SESSION'];
35
+ if (typeof hermesSession === 'string' && hermesSession.length > 0) {
36
+ return hermesSession;
37
+ }
38
+ // Priority 3: Hermes run ID fallback
39
+ const hermesRunId = env['HERMES_RUN_ID'];
40
+ if (typeof hermesRunId === 'string' && hermesRunId.length > 0) {
41
+ return hermesRunId;
42
+ }
43
+ return null;
44
+ }
45
+ /**
46
+ * Validate that a session ID looks reasonable.
47
+ * Hermes session IDs are typically opaque strings from the runtime.
48
+ */
49
+ function isValidSessionId(sessionId) {
50
+ // Accept non-empty strings of reasonable length
51
+ return sessionId.length > 0 && sessionId.length <= 256;
52
+ }
53
+ //# sourceMappingURL=session-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-resolver.js","sourceRoot":"","sources":["../src/session-resolver.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;AAYH,4CAuBC;AAMD,4CAGC;AA1CD;;;;;;;;;GASG;AACH,SAAgB,gBAAgB,CAC9B,YAAqC,EACrC,MAA8B,EAAE;IAEhC,kDAAkD;IAClD,MAAM,QAAQ,GAAG,GAAG,CAAC,kBAAkB,CAAC,CAAC;IACzC,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,4CAA4C;IAC5C,MAAM,aAAa,GAAG,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC5C,IAAI,OAAO,aAAa,KAAK,QAAQ,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClE,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,qCAAqC;IACrC,MAAM,WAAW,GAAG,GAAG,CAAC,eAAe,CAAC,CAAC;IACzC,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9D,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,SAAgB,gBAAgB,CAAC,SAAiB;IAChD,gDAAgD;IAChD,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC,MAAM,IAAI,GAAG,CAAC;AACzD,CAAC"}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@a5c-ai/hooks-mux-adapter-hermes",
3
+ "version": "5.0.1-staging.334ab59e3",
4
+ "description": "Hermes harness adapter for the hooks-mux system",
5
+ "license": "MIT",
6
+ "type": "commonjs",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "publishConfig": {
10
+ "access": "public"
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/a5c-ai/babysitter.git",
15
+ "directory": "packages/hooks-mux/adapter-hermes"
16
+ },
17
+ "homepage": "https://github.com/a5c-ai/babysitter/tree/main/packages/hooks-mux/adapter-hermes#readme",
18
+ "bugs": {
19
+ "url": "https://github.com/a5c-ai/babysitter/issues"
20
+ },
21
+ "files": [
22
+ "dist",
23
+ "README.md"
24
+ ],
25
+ "scripts": {
26
+ "build": "tsc -p tsconfig.json",
27
+ "clean": "rimraf dist",
28
+ "lint": "eslint \"src/**/*.ts\" --max-warnings=0",
29
+ "test": "vitest run",
30
+ "test:watch": "vitest"
31
+ },
32
+ "dependencies": {
33
+ "@a5c-ai/hooks-mux-core": "5.0.1-staging.334ab59e3"
34
+ },
35
+ "devDependencies": {
36
+ "typescript": "^5.7.0",
37
+ "vitest": "^3.0.0",
38
+ "rimraf": "^6.0.0"
39
+ }
40
+ }