@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 +31 -0
- package/dist/adapter.d.ts +3 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +42 -0
- package/dist/adapter.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/mappings.d.ts +7 -0
- package/dist/mappings.d.ts.map +1 -0
- package/dist/mappings.js +85 -0
- package/dist/mappings.js.map +1 -0
- package/dist/normalizer.d.ts +46 -0
- package/dist/normalizer.d.ts.map +1 -0
- package/dist/normalizer.js +115 -0
- package/dist/normalizer.js.map +1 -0
- package/dist/renderer.d.ts +21 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/renderer.js +66 -0
- package/dist/renderer.js.map +1 -0
- package/dist/session-resolver.d.ts +29 -0
- package/dist/session-resolver.d.ts.map +1 -0
- package/dist/session-resolver.js +53 -0
- package/dist/session-resolver.js.map +1 -0
- package/package.json +40 -0
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 @@
|
|
|
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"}
|
package/dist/adapter.js
ADDED
|
@@ -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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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"}
|
package/dist/mappings.js
ADDED
|
@@ -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"}
|
package/dist/renderer.js
ADDED
|
@@ -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
|
+
}
|