@a5c-ai/hooks-mux-adapter-gemini 5.0.1-staging.048a6d1f

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,29 @@
1
+ # @a5c-ai/hooks-mux-adapter-gemini
2
+
3
+ Gemini CLI harness adapter for hooks-mux.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @a5c-ai/hooks-mux-adapter-gemini @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
+ normalizeGemini,
19
+ renderGeminiOutput,
20
+ } from "@a5c-ai/hooks-mux-adapter-gemini";
21
+ ```
22
+
23
+ The package exposes Gemini-specific normalization, phase mappings, rendering helpers, and session-resolution utilities for the hooks-mux execution pipeline.
24
+
25
+ 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.
26
+
27
+ ## License
28
+
29
+ MIT © a5c-ai
@@ -0,0 +1,13 @@
1
+ import type { AdapterCapabilities } from '@a5c-ai/hooks-mux-core';
2
+ /**
3
+ * Creates the Gemini CLI adapter capability descriptor.
4
+ *
5
+ * Gemini CLI is a shell-hook harness with derived session IDs
6
+ * (from GEMINI_SESSION_ID env or workspace-based derivation),
7
+ * wrapper-only env persistence, and support for blocking, asking,
8
+ * and tool input mutation.
9
+ *
10
+ * Spec section 17.3.
11
+ */
12
+ export declare function createAdapter(): AdapterCapabilities;
13
+ //# 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;AAElE;;;;;;;;;GASG;AACH,wBAAgB,aAAa,IAAI,mBAAmB,CAoBnD"}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createAdapter = createAdapter;
4
+ /**
5
+ * Creates the Gemini CLI adapter capability descriptor.
6
+ *
7
+ * Gemini CLI is a shell-hook harness with derived session IDs
8
+ * (from GEMINI_SESSION_ID env or workspace-based derivation),
9
+ * wrapper-only env persistence, and support for blocking, asking,
10
+ * and tool input mutation.
11
+ *
12
+ * Spec section 17.3.
13
+ */
14
+ function createAdapter() {
15
+ return {
16
+ name: 'gemini',
17
+ family: 'shell-hook',
18
+ sessionIdQuality: 'derived',
19
+ supportsOrderedFanout: true,
20
+ supportsNativeAdditionalContext: true,
21
+ supportsBlock: true,
22
+ supportsAsk: true,
23
+ supportsToolInputMutation: true,
24
+ supportsToolResultMutation: false,
25
+ supportsPersistedEnv: false,
26
+ envPersistenceMode: 'wrapper_only',
27
+ toolInterceptionScope: 'all',
28
+ notes: [
29
+ 'BeforeToolSelection has union-style aggregation',
30
+ 'Logs must go to stderr; final JSON to stdout only',
31
+ 'Session ID derived from GEMINI_SESSION_ID env or workspace + timestamp',
32
+ ],
33
+ };
34
+ }
35
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":";;AAYA,sCAoBC;AA9BD;;;;;;;;;GASG;AACH,SAAgB,aAAa;IAC3B,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,YAAY;QACpB,gBAAgB,EAAE,SAAS;QAC3B,qBAAqB,EAAE,IAAI;QAC3B,+BAA+B,EAAE,IAAI;QACrC,aAAa,EAAE,IAAI;QACnB,WAAW,EAAE,IAAI;QACjB,yBAAyB,EAAE,IAAI;QAC/B,0BAA0B,EAAE,KAAK;QACjC,oBAAoB,EAAE,KAAK;QAC3B,kBAAkB,EAAE,cAAc;QAClC,qBAAqB,EAAE,KAAK;QAC5B,KAAK,EAAE;YACL,iDAAiD;YACjD,mDAAmD;YACnD,wEAAwE;SACzE;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ export { createAdapter } from './adapter';
2
+ export { GEMINI_PHASE_MAPPINGS, getGeminiPhaseMapping, getSupportedPhases } from './mappings';
3
+ export { normalizeGemini, parseStdin, buildExecutionContext, buildPayload } from './normalizer';
4
+ export { renderGeminiOutput, emitOutput, logToStderr } from './renderer';
5
+ export { resolveSessionId, deriveSessionId } from './session-resolver';
6
+ export type { GeminiStdinBase, GeminiSessionStartPayload, GeminiBeforeToolSelectionPayload, GeminiBeforeModelPayload, GeminiAfterModelPayload, GeminiBeforeAgentPayload, GeminiAfterAgentPayload, GeminiBeforeToolPayload, GeminiAfterToolPayload, } from './normalizer';
7
+ export type { GeminiBeforeToolSelectionOutput, GeminiBeforeModelOutput, GeminiAfterModelOutput, GeminiBeforeAgentOutput, GeminiAfterAgentOutput, GeminiBeforeToolOutput, GeminiAfterToolOutput, GeminiSessionStartOutput, } from './renderer';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAC9F,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAChG,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGvE,YAAY,EACV,eAAe,EACf,yBAAyB,EACzB,gCAAgC,EAChC,wBAAwB,EACxB,uBAAuB,EACvB,wBAAwB,EACxB,uBAAuB,EACvB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,cAAc,CAAC;AAEtB,YAAY,EACV,+BAA+B,EAC/B,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deriveSessionId = exports.resolveSessionId = exports.logToStderr = exports.emitOutput = exports.renderGeminiOutput = exports.buildPayload = exports.buildExecutionContext = exports.parseStdin = exports.normalizeGemini = exports.getSupportedPhases = exports.getGeminiPhaseMapping = exports.GEMINI_PHASE_MAPPINGS = exports.createAdapter = void 0;
4
+ var adapter_1 = require("./adapter");
5
+ Object.defineProperty(exports, "createAdapter", { enumerable: true, get: function () { return adapter_1.createAdapter; } });
6
+ var mappings_1 = require("./mappings");
7
+ Object.defineProperty(exports, "GEMINI_PHASE_MAPPINGS", { enumerable: true, get: function () { return mappings_1.GEMINI_PHASE_MAPPINGS; } });
8
+ Object.defineProperty(exports, "getGeminiPhaseMapping", { enumerable: true, get: function () { return mappings_1.getGeminiPhaseMapping; } });
9
+ Object.defineProperty(exports, "getSupportedPhases", { enumerable: true, get: function () { return mappings_1.getSupportedPhases; } });
10
+ var normalizer_1 = require("./normalizer");
11
+ Object.defineProperty(exports, "normalizeGemini", { enumerable: true, get: function () { return normalizer_1.normalizeGemini; } });
12
+ Object.defineProperty(exports, "parseStdin", { enumerable: true, get: function () { return normalizer_1.parseStdin; } });
13
+ Object.defineProperty(exports, "buildExecutionContext", { enumerable: true, get: function () { return normalizer_1.buildExecutionContext; } });
14
+ Object.defineProperty(exports, "buildPayload", { enumerable: true, get: function () { return normalizer_1.buildPayload; } });
15
+ var renderer_1 = require("./renderer");
16
+ Object.defineProperty(exports, "renderGeminiOutput", { enumerable: true, get: function () { return renderer_1.renderGeminiOutput; } });
17
+ Object.defineProperty(exports, "emitOutput", { enumerable: true, get: function () { return renderer_1.emitOutput; } });
18
+ Object.defineProperty(exports, "logToStderr", { enumerable: true, get: function () { return renderer_1.logToStderr; } });
19
+ var session_resolver_1 = require("./session-resolver");
20
+ Object.defineProperty(exports, "resolveSessionId", { enumerable: true, get: function () { return session_resolver_1.resolveSessionId; } });
21
+ Object.defineProperty(exports, "deriveSessionId", { enumerable: true, get: function () { return session_resolver_1.deriveSessionId; } });
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,qCAA0C;AAAjC,wGAAA,aAAa,OAAA;AACtB,uCAA8F;AAArF,iHAAA,qBAAqB,OAAA;AAAE,iHAAA,qBAAqB,OAAA;AAAE,8GAAA,kBAAkB,OAAA;AACzE,2CAAgG;AAAvF,6GAAA,eAAe,OAAA;AAAE,wGAAA,UAAU,OAAA;AAAE,mHAAA,qBAAqB,OAAA;AAAE,0GAAA,YAAY,OAAA;AACzE,uCAAyE;AAAhE,8GAAA,kBAAkB,OAAA;AAAE,sGAAA,UAAU,OAAA;AAAE,uGAAA,WAAW,OAAA;AACpD,uDAAuE;AAA9D,oHAAA,gBAAgB,OAAA;AAAE,mHAAA,eAAe,OAAA"}
@@ -0,0 +1,21 @@
1
+ import type { PhaseMapping } from '@a5c-ai/hooks-mux-core';
2
+ /**
3
+ * Gemini CLI native event name to canonical phase mappings.
4
+ *
5
+ * Gemini CLI hook events cover a richer lifecycle than some other harnesses,
6
+ * including planner, model, and agent-level events:
7
+ * SessionStart, SessionEnd, BeforeToolSelection, BeforeModel, AfterModel,
8
+ * BeforeAgent, AfterAgent, BeforeTool, AfterTool
9
+ *
10
+ * Spec section 8.2 / 17.3.
11
+ */
12
+ export declare const GEMINI_PHASE_MAPPINGS: PhaseMapping[];
13
+ /**
14
+ * Look up the phase mapping for a given Gemini native event name.
15
+ */
16
+ export declare function getGeminiPhaseMapping(nativeEventName: string): PhaseMapping | undefined;
17
+ /**
18
+ * Get all canonical phases supported by the Gemini adapter.
19
+ */
20
+ export declare function getSupportedPhases(): string[];
21
+ //# 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;AAE3D;;;;;;;;;GASG;AACH,eAAO,MAAM,qBAAqB,EAAE,YAAY,EA+F/C,CAAC;AAEF;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,eAAe,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAEvF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CAE7C"}
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GEMINI_PHASE_MAPPINGS = void 0;
4
+ exports.getGeminiPhaseMapping = getGeminiPhaseMapping;
5
+ exports.getSupportedPhases = getSupportedPhases;
6
+ /**
7
+ * Gemini CLI native event name to canonical phase mappings.
8
+ *
9
+ * Gemini CLI hook events cover a richer lifecycle than some other harnesses,
10
+ * including planner, model, and agent-level events:
11
+ * SessionStart, SessionEnd, BeforeToolSelection, BeforeModel, AfterModel,
12
+ * BeforeAgent, AfterAgent, BeforeTool, AfterTool
13
+ *
14
+ * Spec section 8.2 / 17.3.
15
+ */
16
+ exports.GEMINI_PHASE_MAPPINGS = [
17
+ // --- Session lifecycle ---
18
+ {
19
+ canonicalPhase: 'session.start',
20
+ nativeHook: 'SessionStart',
21
+ supportLevel: 'native',
22
+ blockCapability: false,
23
+ mutationCapability: false,
24
+ scope: 'session',
25
+ notes: 'Fires when the Gemini CLI session begins.',
26
+ },
27
+ {
28
+ canonicalPhase: 'session.end',
29
+ nativeHook: 'SessionEnd',
30
+ supportLevel: 'native',
31
+ blockCapability: false,
32
+ mutationCapability: false,
33
+ scope: 'session',
34
+ notes: 'Observer-only; fires when session is torn down.',
35
+ },
36
+ // --- Planner lifecycle ---
37
+ {
38
+ canonicalPhase: 'planner.before_tool_selection',
39
+ nativeHook: 'BeforeToolSelection',
40
+ supportLevel: 'native',
41
+ blockCapability: true,
42
+ mutationCapability: true,
43
+ scope: 'planner',
44
+ notes: 'Union-style aggregation: multiple hooks return tool subsets that are unioned. ' +
45
+ 'Can influence which tools are available for the current turn.',
46
+ },
47
+ // --- Model lifecycle ---
48
+ {
49
+ canonicalPhase: 'model.before_request',
50
+ nativeHook: 'BeforeModel',
51
+ supportLevel: 'native',
52
+ blockCapability: true,
53
+ mutationCapability: true,
54
+ scope: 'model',
55
+ notes: 'Fires before the model request is sent. Can mutate the request payload.',
56
+ },
57
+ {
58
+ canonicalPhase: 'model.after_response',
59
+ nativeHook: 'AfterModel',
60
+ supportLevel: 'native',
61
+ blockCapability: false,
62
+ mutationCapability: false,
63
+ scope: 'model',
64
+ notes: 'Observer-only; fires after model response is received.',
65
+ },
66
+ // --- Turn / agent lifecycle ---
67
+ {
68
+ canonicalPhase: 'turn.before_agent',
69
+ nativeHook: 'BeforeAgent',
70
+ supportLevel: 'native',
71
+ blockCapability: true,
72
+ mutationCapability: false,
73
+ scope: 'turn',
74
+ notes: 'Fires before the agent turn begins. Can block execution.',
75
+ },
76
+ {
77
+ canonicalPhase: 'turn.after_agent',
78
+ nativeHook: 'AfterAgent',
79
+ supportLevel: 'native',
80
+ blockCapability: true,
81
+ mutationCapability: false,
82
+ scope: 'turn',
83
+ notes: 'Fires after the agent turn completes. Can continue session ' +
84
+ 'by providing a follow-up prompt.',
85
+ },
86
+ // --- Tool lifecycle ---
87
+ {
88
+ canonicalPhase: 'tool.before',
89
+ nativeHook: 'BeforeTool',
90
+ supportLevel: 'native',
91
+ blockCapability: true,
92
+ mutationCapability: true,
93
+ scope: 'tool',
94
+ notes: 'Fires before tool execution. Can block (deny) or mutate tool input.',
95
+ },
96
+ {
97
+ canonicalPhase: 'tool.after',
98
+ nativeHook: 'AfterTool',
99
+ supportLevel: 'native',
100
+ blockCapability: false,
101
+ mutationCapability: false,
102
+ scope: 'tool',
103
+ notes: 'Observer-only post-tool hook.',
104
+ },
105
+ ];
106
+ /**
107
+ * Look up the phase mapping for a given Gemini native event name.
108
+ */
109
+ function getGeminiPhaseMapping(nativeEventName) {
110
+ return exports.GEMINI_PHASE_MAPPINGS.find((m) => m.nativeHook === nativeEventName);
111
+ }
112
+ /**
113
+ * Get all canonical phases supported by the Gemini adapter.
114
+ */
115
+ function getSupportedPhases() {
116
+ return exports.GEMINI_PHASE_MAPPINGS.map((m) => m.canonicalPhase);
117
+ }
118
+ //# sourceMappingURL=mappings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mappings.js","sourceRoot":"","sources":["../src/mappings.ts"],"names":[],"mappings":";;;AAgHA,sDAEC;AAKD,gDAEC;AAvHD;;;;;;;;;GASG;AACU,QAAA,qBAAqB,GAAmB;IACnD,4BAA4B;IAC5B;QACE,cAAc,EAAE,eAAe;QAC/B,UAAU,EAAE,cAAc;QAC1B,YAAY,EAAE,QAAQ;QACtB,eAAe,EAAE,KAAK;QACtB,kBAAkB,EAAE,KAAK;QACzB,KAAK,EAAE,SAAS;QAChB,KAAK,EAAE,2CAA2C;KACnD;IACD;QACE,cAAc,EAAE,aAAa;QAC7B,UAAU,EAAE,YAAY;QACxB,YAAY,EAAE,QAAQ;QACtB,eAAe,EAAE,KAAK;QACtB,kBAAkB,EAAE,KAAK;QACzB,KAAK,EAAE,SAAS;QAChB,KAAK,EAAE,iDAAiD;KACzD;IAED,4BAA4B;IAC5B;QACE,cAAc,EAAE,+BAA+B;QAC/C,UAAU,EAAE,qBAAqB;QACjC,YAAY,EAAE,QAAQ;QACtB,eAAe,EAAE,IAAI;QACrB,kBAAkB,EAAE,IAAI;QACxB,KAAK,EAAE,SAAS;QAChB,KAAK,EACH,gFAAgF;YAChF,+DAA+D;KAClE;IAED,0BAA0B;IAC1B;QACE,cAAc,EAAE,sBAAsB;QACtC,UAAU,EAAE,aAAa;QACzB,YAAY,EAAE,QAAQ;QACtB,eAAe,EAAE,IAAI;QACrB,kBAAkB,EAAE,IAAI;QACxB,KAAK,EAAE,OAAO;QACd,KAAK,EAAE,yEAAyE;KACjF;IACD;QACE,cAAc,EAAE,sBAAsB;QACtC,UAAU,EAAE,YAAY;QACxB,YAAY,EAAE,QAAQ;QACtB,eAAe,EAAE,KAAK;QACtB,kBAAkB,EAAE,KAAK;QACzB,KAAK,EAAE,OAAO;QACd,KAAK,EAAE,wDAAwD;KAChE;IAED,iCAAiC;IACjC;QACE,cAAc,EAAE,mBAAmB;QACnC,UAAU,EAAE,aAAa;QACzB,YAAY,EAAE,QAAQ;QACtB,eAAe,EAAE,IAAI;QACrB,kBAAkB,EAAE,KAAK;QACzB,KAAK,EAAE,MAAM;QACb,KAAK,EAAE,0DAA0D;KAClE;IACD;QACE,cAAc,EAAE,kBAAkB;QAClC,UAAU,EAAE,YAAY;QACxB,YAAY,EAAE,QAAQ;QACtB,eAAe,EAAE,IAAI;QACrB,kBAAkB,EAAE,KAAK;QACzB,KAAK,EAAE,MAAM;QACb,KAAK,EACH,6DAA6D;YAC7D,kCAAkC;KACrC;IAED,yBAAyB;IACzB;QACE,cAAc,EAAE,aAAa;QAC7B,UAAU,EAAE,YAAY;QACxB,YAAY,EAAE,QAAQ;QACtB,eAAe,EAAE,IAAI;QACrB,kBAAkB,EAAE,IAAI;QACxB,KAAK,EAAE,MAAM;QACb,KAAK,EAAE,qEAAqE;KAC7E;IACD;QACE,cAAc,EAAE,YAAY;QAC5B,UAAU,EAAE,WAAW;QACvB,YAAY,EAAE,QAAQ;QACtB,eAAe,EAAE,KAAK;QACtB,kBAAkB,EAAE,KAAK;QACzB,KAAK,EAAE,MAAM;QACb,KAAK,EAAE,+BAA+B;KACvC;CACF,CAAC;AAEF;;GAEG;AACH,SAAgB,qBAAqB,CAAC,eAAuB;IAC3D,OAAO,6BAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,eAAe,CAAC,CAAC;AAC7E,CAAC;AAED;;GAEG;AACH,SAAgB,kBAAkB;IAChC,OAAO,6BAAqB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;AAC5D,CAAC"}
@@ -0,0 +1,100 @@
1
+ import type { UnifiedHookEvent, UnifiedExecutionContext } from '@a5c-ai/hooks-mux-core';
2
+ /**
3
+ * Gemini CLI stdin JSON payload shapes.
4
+ *
5
+ * Gemini CLI passes hook input as JSON on stdin with fields varying by event type.
6
+ */
7
+ /** Common fields present across most Gemini hook events. */
8
+ export interface GeminiStdinBase {
9
+ /** Workspace or project directory. */
10
+ cwd?: string;
11
+ /** Model identifier. */
12
+ model?: string;
13
+ /** Extension path for the calling extension. */
14
+ extensionPath?: string;
15
+ [key: string]: unknown;
16
+ }
17
+ /** SessionStart-specific fields. */
18
+ export interface GeminiSessionStartPayload extends GeminiStdinBase {
19
+ /** Initial user prompt if available. */
20
+ prompt?: string;
21
+ }
22
+ /** BeforeToolSelection-specific fields. */
23
+ export interface GeminiBeforeToolSelectionPayload extends GeminiStdinBase {
24
+ /** List of available tool names. */
25
+ availableTools?: string[];
26
+ /** The user prompt or current context driving tool selection. */
27
+ prompt?: string;
28
+ }
29
+ /** BeforeModel-specific fields. */
30
+ export interface GeminiBeforeModelPayload extends GeminiStdinBase {
31
+ /** The request about to be sent to the model. */
32
+ request?: unknown;
33
+ /** Messages in the conversation so far. */
34
+ messages?: unknown[];
35
+ }
36
+ /** AfterModel-specific fields. */
37
+ export interface GeminiAfterModelPayload extends GeminiStdinBase {
38
+ /** The model's response. */
39
+ response?: unknown;
40
+ /** Token usage information. */
41
+ usage?: {
42
+ promptTokens?: number;
43
+ completionTokens?: number;
44
+ totalTokens?: number;
45
+ };
46
+ }
47
+ /** BeforeAgent-specific fields. */
48
+ export interface GeminiBeforeAgentPayload extends GeminiStdinBase {
49
+ /** The prompt that will drive the agent turn. */
50
+ prompt?: string;
51
+ }
52
+ /** AfterAgent-specific fields. */
53
+ export interface GeminiAfterAgentPayload extends GeminiStdinBase {
54
+ /** The agent's last output message. */
55
+ lastMessage?: string;
56
+ /** Reason the agent turn ended. */
57
+ reason?: string;
58
+ }
59
+ /** BeforeTool-specific fields. */
60
+ export interface GeminiBeforeToolPayload extends GeminiStdinBase {
61
+ /** Name of the tool being executed. */
62
+ toolName?: string;
63
+ /** Input arguments for the tool. */
64
+ toolInput?: unknown;
65
+ /** Tool call identifier. */
66
+ toolCallId?: string;
67
+ }
68
+ /** AfterTool-specific fields. */
69
+ export interface GeminiAfterToolPayload extends GeminiStdinBase {
70
+ /** Name of the tool that was executed. */
71
+ toolName?: string;
72
+ /** Input arguments for the tool. */
73
+ toolInput?: unknown;
74
+ /** Tool execution result. */
75
+ toolResult?: unknown;
76
+ /** Tool call identifier. */
77
+ toolCallId?: string;
78
+ }
79
+ /**
80
+ * Parse raw stdin input (string or object) into a structured object.
81
+ */
82
+ export declare function parseStdin(raw: unknown): Record<string, unknown>;
83
+ /**
84
+ * Build a UnifiedExecutionContext from a Gemini stdin payload and environment.
85
+ */
86
+ export declare function buildExecutionContext(stdinData: Record<string, unknown>, nativeEventName: string, env: Record<string, string>): UnifiedExecutionContext;
87
+ /**
88
+ * Build the payload portion of the unified event from Gemini stdin data.
89
+ * Extracts event-specific fields into the normalized payload.
90
+ */
91
+ export declare function buildPayload(nativeEventName: string, stdinData: Record<string, unknown>): Record<string, unknown>;
92
+ /**
93
+ * Normalize a Gemini CLI hook invocation into a UnifiedHookEvent.
94
+ *
95
+ * @param nativeEventName - The Gemini event name (e.g. 'BeforeToolSelection', 'AfterAgent').
96
+ * @param rawStdin - Raw stdin content (string or parsed object).
97
+ * @param env - Environment variables at invocation time.
98
+ */
99
+ export declare function normalizeGemini(nativeEventName: string, rawStdin: unknown, env?: Record<string, string>): UnifiedHookEvent;
100
+ //# sourceMappingURL=normalizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizer.d.ts","sourceRoot":"","sources":["../src/normalizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,179 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseStdin = parseStdin;
4
+ exports.buildExecutionContext = buildExecutionContext;
5
+ exports.buildPayload = buildPayload;
6
+ exports.normalizeGemini = normalizeGemini;
7
+ const mappings_1 = require("./mappings");
8
+ const session_resolver_1 = require("./session-resolver");
9
+ /**
10
+ * Parse raw stdin input (string or object) into a structured object.
11
+ */
12
+ function parseStdin(raw) {
13
+ if (raw == null) {
14
+ return {};
15
+ }
16
+ if (typeof raw === 'string') {
17
+ try {
18
+ const parsed = JSON.parse(raw);
19
+ if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
20
+ return parsed;
21
+ }
22
+ return { raw: parsed };
23
+ }
24
+ catch {
25
+ return { raw };
26
+ }
27
+ }
28
+ if (typeof raw === 'object' && !Array.isArray(raw)) {
29
+ return raw;
30
+ }
31
+ return { raw };
32
+ }
33
+ /**
34
+ * Build a UnifiedExecutionContext from a Gemini stdin payload and environment.
35
+ */
36
+ function buildExecutionContext(stdinData, nativeEventName, env) {
37
+ const persistedEnv = {};
38
+ const contextVars = {};
39
+ for (const [key, value] of Object.entries(env)) {
40
+ if (key.startsWith('HOOKS_PROXY_PERSIST_')) {
41
+ persistedEnv[key] = value;
42
+ }
43
+ }
44
+ const sessionId = (0, session_resolver_1.resolveSessionId)(stdinData, env);
45
+ return {
46
+ sessionId,
47
+ turnId: env['HOOKS_PROXY_TURN_ID'] ?? null,
48
+ conversationId: env['HOOKS_PROXY_CONVERSATION_ID'] ?? null,
49
+ adapter: 'gemini',
50
+ cwd: stdinData.cwd ?? env['PWD'] ?? null,
51
+ worktree: env['HOOKS_PROXY_WORKTREE'] ?? null,
52
+ transcriptPath: null,
53
+ source: null,
54
+ model: stdinData.model ?? env['HOOKS_PROXY_MODEL'] ?? null,
55
+ agentType: null,
56
+ permissionMode: null,
57
+ toolName: stdinData.toolName ?? null,
58
+ toolCallId: stdinData.toolCallId ?? null,
59
+ nativeEventName,
60
+ rawEventScope: null,
61
+ persistedEnv,
62
+ contextVars,
63
+ metadata: {
64
+ ...(stdinData.extensionPath != null ? { extensionPath: stdinData.extensionPath } : {}),
65
+ },
66
+ };
67
+ }
68
+ /**
69
+ * Build the payload portion of the unified event from Gemini stdin data.
70
+ * Extracts event-specific fields into the normalized payload.
71
+ */
72
+ function buildPayload(nativeEventName, stdinData) {
73
+ const payload = {};
74
+ switch (nativeEventName) {
75
+ case 'SessionStart':
76
+ if (stdinData.prompt != null)
77
+ payload.initialPrompt = stdinData.prompt;
78
+ break;
79
+ case 'SessionEnd':
80
+ // No event-specific fields beyond common ones
81
+ break;
82
+ case 'BeforeToolSelection':
83
+ if (stdinData.availableTools != null)
84
+ payload.availableTools = stdinData.availableTools;
85
+ if (stdinData.prompt != null)
86
+ payload.prompt = stdinData.prompt;
87
+ break;
88
+ case 'BeforeModel':
89
+ if (stdinData.request != null)
90
+ payload.llmRequest = stdinData.request;
91
+ if (stdinData.messages != null)
92
+ payload.messages = stdinData.messages;
93
+ break;
94
+ case 'AfterModel':
95
+ if (stdinData.response != null)
96
+ payload.llmResponse = stdinData.response;
97
+ if (stdinData.usage != null)
98
+ payload.usage = stdinData.usage;
99
+ break;
100
+ case 'BeforeAgent':
101
+ if (stdinData.prompt != null)
102
+ payload.prompt = stdinData.prompt;
103
+ break;
104
+ case 'AfterAgent':
105
+ if (stdinData.lastMessage != null)
106
+ payload.lastAssistantMessage = stdinData.lastMessage;
107
+ if (stdinData.reason != null)
108
+ payload.reason = stdinData.reason;
109
+ break;
110
+ case 'BeforeTool':
111
+ if (stdinData.toolName != null)
112
+ payload.toolName = stdinData.toolName;
113
+ if (stdinData.toolInput != null)
114
+ payload.toolInput = stdinData.toolInput;
115
+ if (stdinData.toolCallId != null)
116
+ payload.toolCallId = stdinData.toolCallId;
117
+ break;
118
+ case 'AfterTool':
119
+ if (stdinData.toolName != null)
120
+ payload.toolName = stdinData.toolName;
121
+ if (stdinData.toolInput != null)
122
+ payload.toolInput = stdinData.toolInput;
123
+ if (stdinData.toolResult != null)
124
+ payload.toolResponse = stdinData.toolResult;
125
+ if (stdinData.toolCallId != null)
126
+ payload.toolCallId = stdinData.toolCallId;
127
+ break;
128
+ default:
129
+ // Unknown event: pass through all non-common fields
130
+ for (const [key, value] of Object.entries(stdinData)) {
131
+ if (!['cwd', 'model', 'extensionPath'].includes(key)) {
132
+ payload[key] = value;
133
+ }
134
+ }
135
+ break;
136
+ }
137
+ return payload;
138
+ }
139
+ /**
140
+ * Normalize a Gemini CLI hook invocation into a UnifiedHookEvent.
141
+ *
142
+ * @param nativeEventName - The Gemini event name (e.g. 'BeforeToolSelection', 'AfterAgent').
143
+ * @param rawStdin - Raw stdin content (string or parsed object).
144
+ * @param env - Environment variables at invocation time.
145
+ */
146
+ function normalizeGemini(nativeEventName, rawStdin, env = {}) {
147
+ const stdinData = parseStdin(rawStdin);
148
+ const mapping = (0, mappings_1.getGeminiPhaseMapping)(nativeEventName);
149
+ const phase = mapping?.canonicalPhase ?? 'unknown';
150
+ const supportLevel = mapping?.supportLevel ?? 'unsupported';
151
+ const execution = buildExecutionContext(stdinData, nativeEventName, env);
152
+ const payload = buildPayload(nativeEventName, stdinData);
153
+ // Split env into input and persisted buckets
154
+ const inputEnv = {};
155
+ const persistedEnv = {};
156
+ for (const [key, value] of Object.entries(env)) {
157
+ if (key.startsWith('HOOKS_PROXY_PERSIST_')) {
158
+ persistedEnv[key] = value;
159
+ }
160
+ else if (key.startsWith('HOOKS_PROXY_')) {
161
+ inputEnv[key] = value;
162
+ }
163
+ }
164
+ return {
165
+ version: 'a5c.hooks.v1',
166
+ adapter: 'gemini',
167
+ phase,
168
+ rawEventName: nativeEventName,
169
+ supportLevel,
170
+ execution,
171
+ payload,
172
+ env: {
173
+ input: inputEnv,
174
+ persisted: persistedEnv,
175
+ },
176
+ raw: rawStdin,
177
+ };
178
+ }
179
+ //# 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,94 @@
1
+ import type { UnifiedHookResult } from '@a5c-ai/hooks-mux-core';
2
+ /**
3
+ * Gemini CLI native hook output formats.
4
+ *
5
+ * Gemini CLI hooks communicate results via JSON on stdout only.
6
+ * All diagnostic/log output MUST go to stderr.
7
+ */
8
+ /** BeforeToolSelection hook output: tool filtering via union aggregation. */
9
+ export interface GeminiBeforeToolSelectionOutput {
10
+ /** Tools to include — unioned across multiple hook responses. */
11
+ selectedTools?: string[];
12
+ /** Additional context to inject. */
13
+ additionalContext?: string;
14
+ }
15
+ /** BeforeModel hook output: request mutation. */
16
+ export interface GeminiBeforeModelOutput {
17
+ /** System message to prepend or inject. */
18
+ systemMessage?: string;
19
+ /** Additional context to inject. */
20
+ additionalContext?: string;
21
+ /** Whether to block the model request entirely. */
22
+ block?: boolean;
23
+ /** Reason for blocking. */
24
+ reason?: string;
25
+ }
26
+ /** AfterModel hook output. */
27
+ export interface GeminiAfterModelOutput {
28
+ /** Additional context to inject. */
29
+ additionalContext?: string;
30
+ }
31
+ /** BeforeAgent hook output. */
32
+ export interface GeminiBeforeAgentOutput {
33
+ /** Additional context to inject. */
34
+ additionalContext?: string;
35
+ /** Whether to block the agent turn. */
36
+ block?: boolean;
37
+ /** Reason for blocking. */
38
+ reason?: string;
39
+ }
40
+ /** AfterAgent hook output: continuation control. */
41
+ export interface GeminiAfterAgentOutput {
42
+ /** If true, continue the session with a follow-up. */
43
+ continueSession?: boolean;
44
+ /** Follow-up prompt to inject if continuing. */
45
+ followUpMessage?: string;
46
+ /** Additional context to inject. */
47
+ additionalContext?: string;
48
+ /** Reason for the decision. */
49
+ reason?: string;
50
+ }
51
+ /** BeforeTool hook output: permission and mutation. */
52
+ export interface GeminiBeforeToolOutput {
53
+ /** Permission decision. */
54
+ decision?: 'allow' | 'deny';
55
+ /** Reason for the decision. */
56
+ reason?: string;
57
+ /** Mutated tool input (replaces original). */
58
+ toolInput?: unknown;
59
+ /** Additional context to inject. */
60
+ additionalContext?: string;
61
+ }
62
+ /** AfterTool hook output. */
63
+ export interface GeminiAfterToolOutput {
64
+ /** Additional context to inject. */
65
+ additionalContext?: string;
66
+ }
67
+ /** SessionStart hook output. */
68
+ export interface GeminiSessionStartOutput {
69
+ /** Additional context to inject. */
70
+ additionalContext?: string;
71
+ }
72
+ /**
73
+ * Render a UnifiedHookResult back to Gemini's native JSON output format.
74
+ *
75
+ * Output JSON goes to stdout. Any diagnostic or log output must go to stderr
76
+ * (handled by the caller, not here).
77
+ *
78
+ * @param result - The unified hook result from handler execution.
79
+ * @param nativeEventName - The original Gemini event name.
80
+ * @returns The native JSON output to write to stdout.
81
+ */
82
+ export declare function renderGeminiOutput(result: UnifiedHookResult, nativeEventName: string): Record<string, unknown>;
83
+ /**
84
+ * Write JSON output to stdout and log message to stderr.
85
+ *
86
+ * Gemini CLI requires that only the final JSON result goes to stdout.
87
+ * All diagnostic messages must go to stderr.
88
+ */
89
+ export declare function emitOutput(output: Record<string, unknown>, log?: string): void;
90
+ /**
91
+ * Write a log/diagnostic message to stderr (never stdout).
92
+ */
93
+ export declare function logToStderr(message: string): void;
94
+ //# 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,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE;;;;;GAKG;AAEH,6EAA6E;AAC7E,MAAM,WAAW,+BAA+B;IAC9C,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,oCAAoC;IACpC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,iDAAiD;AACjD,MAAM,WAAW,uBAAuB;IACtC,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oCAAoC;IACpC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mDAAmD;IACnD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,2BAA2B;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,8BAA8B;AAC9B,MAAM,WAAW,sBAAsB;IACrC,oCAAoC;IACpC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,+BAA+B;AAC/B,MAAM,WAAW,uBAAuB;IACtC,oCAAoC;IACpC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,uCAAuC;IACvC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,2BAA2B;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,oDAAoD;AACpD,MAAM,WAAW,sBAAsB;IACrC,sDAAsD;IACtD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oCAAoC;IACpC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,+BAA+B;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,uDAAuD;AACvD,MAAM,WAAW,sBAAsB;IACrC,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,+BAA+B;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oCAAoC;IACpC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,6BAA6B;AAC7B,MAAM,WAAW,qBAAqB;IACpC,oCAAoC;IACpC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,gCAAgC;AAChC,MAAM,WAAW,wBAAwB;IACvC,oCAAoC;IACpC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,iBAAiB,EACzB,eAAe,EAAE,MAAM,GACtB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAqBzB;AAqJD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAK9E;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEjD"}
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderGeminiOutput = renderGeminiOutput;
4
+ exports.emitOutput = emitOutput;
5
+ exports.logToStderr = logToStderr;
6
+ /**
7
+ * Render a UnifiedHookResult back to Gemini's native JSON output format.
8
+ *
9
+ * Output JSON goes to stdout. Any diagnostic or log output must go to stderr
10
+ * (handled by the caller, not here).
11
+ *
12
+ * @param result - The unified hook result from handler execution.
13
+ * @param nativeEventName - The original Gemini event name.
14
+ * @returns The native JSON output to write to stdout.
15
+ */
16
+ function renderGeminiOutput(result, nativeEventName) {
17
+ switch (nativeEventName) {
18
+ case 'BeforeToolSelection':
19
+ return renderBeforeToolSelectionOutput(result);
20
+ case 'BeforeModel':
21
+ return renderBeforeModelOutput(result);
22
+ case 'AfterModel':
23
+ return renderAfterModelOutput(result);
24
+ case 'BeforeAgent':
25
+ return renderBeforeAgentOutput(result);
26
+ case 'AfterAgent':
27
+ return renderAfterAgentOutput(result);
28
+ case 'BeforeTool':
29
+ return renderBeforeToolOutput(result);
30
+ case 'AfterTool':
31
+ return renderAfterToolOutput(result);
32
+ case 'SessionStart':
33
+ return renderSessionStartOutput(result);
34
+ default:
35
+ return renderGenericOutput(result);
36
+ }
37
+ }
38
+ function renderBeforeToolSelectionOutput(result) {
39
+ const output = {};
40
+ // toolMutation for BeforeToolSelection carries the selected tool list
41
+ if (result.toolMutation?.value != null && Array.isArray(result.toolMutation.value)) {
42
+ output.selectedTools = result.toolMutation.value;
43
+ }
44
+ if (result.additionalContext != null) {
45
+ output.additionalContext = result.additionalContext;
46
+ }
47
+ return output;
48
+ }
49
+ function renderBeforeModelOutput(result) {
50
+ const output = {};
51
+ if (result.systemMessage != null) {
52
+ output.systemMessage = result.systemMessage;
53
+ }
54
+ if (result.additionalContext != null) {
55
+ output.additionalContext = result.additionalContext;
56
+ }
57
+ if (result.decision === 'deny') {
58
+ output.block = true;
59
+ if (result.reason != null) {
60
+ output.reason = result.reason;
61
+ }
62
+ }
63
+ return output;
64
+ }
65
+ function renderAfterModelOutput(result) {
66
+ const output = {};
67
+ if (result.additionalContext != null) {
68
+ output.additionalContext = result.additionalContext;
69
+ }
70
+ return output;
71
+ }
72
+ function renderBeforeAgentOutput(result) {
73
+ const output = {};
74
+ if (result.additionalContext != null) {
75
+ output.additionalContext = result.additionalContext;
76
+ }
77
+ if (result.decision === 'deny') {
78
+ output.block = true;
79
+ if (result.reason != null) {
80
+ output.reason = result.reason;
81
+ }
82
+ }
83
+ return output;
84
+ }
85
+ function renderAfterAgentOutput(result) {
86
+ const output = {};
87
+ if (result.continueSession != null) {
88
+ output.continueSession = result.continueSession;
89
+ }
90
+ if (result.followUpMessage != null) {
91
+ output.followUpMessage = result.followUpMessage;
92
+ }
93
+ if (result.additionalContext != null) {
94
+ output.additionalContext = result.additionalContext;
95
+ }
96
+ if (result.stopReason != null) {
97
+ output.reason = result.stopReason;
98
+ }
99
+ else if (result.reason != null) {
100
+ output.reason = result.reason;
101
+ }
102
+ return output;
103
+ }
104
+ function renderBeforeToolOutput(result) {
105
+ const output = {};
106
+ if (result.decision === 'allow') {
107
+ output.decision = 'allow';
108
+ }
109
+ else if (result.decision === 'deny') {
110
+ output.decision = 'deny';
111
+ }
112
+ // 'ask', 'continue', 'noop' produce no decision — Gemini defaults to allow
113
+ if (result.reason != null) {
114
+ output.reason = result.reason;
115
+ }
116
+ // Tool input mutation
117
+ if (result.toolMutation?.value != null) {
118
+ output.toolInput = result.toolMutation.value;
119
+ }
120
+ if (result.additionalContext != null) {
121
+ output.additionalContext = result.additionalContext;
122
+ }
123
+ return output;
124
+ }
125
+ function renderAfterToolOutput(result) {
126
+ const output = {};
127
+ if (result.additionalContext != null) {
128
+ output.additionalContext = result.additionalContext;
129
+ }
130
+ return output;
131
+ }
132
+ function renderSessionStartOutput(result) {
133
+ const output = {};
134
+ if (result.additionalContext != null) {
135
+ output.additionalContext = result.additionalContext;
136
+ }
137
+ return output;
138
+ }
139
+ function renderGenericOutput(result) {
140
+ const output = {};
141
+ if (result.additionalContext != null) {
142
+ output.additionalContext = result.additionalContext;
143
+ }
144
+ return output;
145
+ }
146
+ /**
147
+ * Write JSON output to stdout and log message to stderr.
148
+ *
149
+ * Gemini CLI requires that only the final JSON result goes to stdout.
150
+ * All diagnostic messages must go to stderr.
151
+ */
152
+ function emitOutput(output, log) {
153
+ if (log != null) {
154
+ process.stderr.write(log + '\n');
155
+ }
156
+ process.stdout.write(JSON.stringify(output) + '\n');
157
+ }
158
+ /**
159
+ * Write a log/diagnostic message to stderr (never stdout).
160
+ */
161
+ function logToStderr(message) {
162
+ process.stderr.write(message + '\n');
163
+ }
164
+ //# sourceMappingURL=renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Resolve a session ID for Gemini CLI.
3
+ *
4
+ * Gemini CLI does not provide a native session ID on stdin.
5
+ * The session ID is derived from available signals:
6
+ *
7
+ * 1. Explicit env: AGENT_SESSION_ID or HOOKS_PROXY_SESSION_ID
8
+ * 2. Gemini-specific env: GEMINI_SESSION_ID
9
+ * 3. Derived from workspace (cwd) + a date-bucket to avoid accidental
10
+ * cross-session merging while keeping the ID stable within a session window.
11
+ *
12
+ * Spec section 9.2 — session ID quality: 'derived'.
13
+ */
14
+ export declare function resolveSessionId(stdinData: Record<string, unknown>, env: Record<string, string>): string | null;
15
+ /**
16
+ * Derive a deterministic session ID from the workspace directory.
17
+ *
18
+ * Uses a 15-minute time bucket so that hooks fired within the same
19
+ * working session are grouped together, while separate launches
20
+ * in different time windows get different IDs.
21
+ *
22
+ * The bucket window is intentionally coarse to keep the same session ID
23
+ * stable across rapid hook invocations within a single CLI session.
24
+ */
25
+ export declare function deriveSessionId(cwd: string): string;
26
+ //# 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":"AAEA;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC1B,MAAM,GAAG,IAAI,CAqBf;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMnD"}
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.resolveSessionId = resolveSessionId;
37
+ exports.deriveSessionId = deriveSessionId;
38
+ const crypto = __importStar(require("crypto"));
39
+ /**
40
+ * Resolve a session ID for Gemini CLI.
41
+ *
42
+ * Gemini CLI does not provide a native session ID on stdin.
43
+ * The session ID is derived from available signals:
44
+ *
45
+ * 1. Explicit env: AGENT_SESSION_ID or HOOKS_PROXY_SESSION_ID
46
+ * 2. Gemini-specific env: GEMINI_SESSION_ID
47
+ * 3. Derived from workspace (cwd) + a date-bucket to avoid accidental
48
+ * cross-session merging while keeping the ID stable within a session window.
49
+ *
50
+ * Spec section 9.2 — session ID quality: 'derived'.
51
+ */
52
+ function resolveSessionId(stdinData, env) {
53
+ // 1. Explicit session ID from env (highest priority)
54
+ if (env['AGENT_SESSION_ID']) {
55
+ return env['AGENT_SESSION_ID'];
56
+ }
57
+ if (env['HOOKS_PROXY_SESSION_ID']) {
58
+ return env['HOOKS_PROXY_SESSION_ID'];
59
+ }
60
+ // 2. Gemini-specific session env
61
+ if (env['GEMINI_SESSION_ID']) {
62
+ return env['GEMINI_SESSION_ID'];
63
+ }
64
+ // 3. Derive from workspace + date bucket
65
+ const cwd = stdinData.cwd ?? env['PWD'] ?? null;
66
+ if (cwd != null) {
67
+ return deriveSessionId(cwd);
68
+ }
69
+ return null;
70
+ }
71
+ /**
72
+ * Derive a deterministic session ID from the workspace directory.
73
+ *
74
+ * Uses a 15-minute time bucket so that hooks fired within the same
75
+ * working session are grouped together, while separate launches
76
+ * in different time windows get different IDs.
77
+ *
78
+ * The bucket window is intentionally coarse to keep the same session ID
79
+ * stable across rapid hook invocations within a single CLI session.
80
+ */
81
+ function deriveSessionId(cwd) {
82
+ const bucketMs = 15 * 60 * 1000; // 15 minutes
83
+ const timeBucket = Math.floor(Date.now() / bucketMs);
84
+ const input = `gemini:${cwd}:${timeBucket}`;
85
+ const hash = crypto.createHash('sha256').update(input).digest('hex').slice(0, 16);
86
+ return `gemini-derived-${hash}`;
87
+ }
88
+ //# sourceMappingURL=session-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-resolver.js","sourceRoot":"","sources":["../src/session-resolver.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAeA,4CAwBC;AAYD,0CAMC;AAzDD,+CAAiC;AAEjC;;;;;;;;;;;;GAYG;AACH,SAAgB,gBAAgB,CAC9B,SAAkC,EAClC,GAA2B;IAE3B,qDAAqD;IACrD,IAAI,GAAG,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC5B,OAAO,GAAG,CAAC,kBAAkB,CAAC,CAAC;IACjC,CAAC;IACD,IAAI,GAAG,CAAC,wBAAwB,CAAC,EAAE,CAAC;QAClC,OAAO,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACvC,CAAC;IAED,iCAAiC;IACjC,IAAI,GAAG,CAAC,mBAAmB,CAAC,EAAE,CAAC;QAC7B,OAAO,GAAG,CAAC,mBAAmB,CAAC,CAAC;IAClC,CAAC;IAED,yCAAyC;IACzC,MAAM,GAAG,GAAI,SAAS,CAAC,GAA0B,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;IACxE,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;QAChB,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;GASG;AACH,SAAgB,eAAe,CAAC,GAAW;IACzC,MAAM,QAAQ,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;IAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,CAAC;IACrD,MAAM,KAAK,GAAG,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC;IAC5C,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAClF,OAAO,kBAAkB,IAAI,EAAE,CAAC;AAClC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@a5c-ai/hooks-mux-adapter-gemini",
3
+ "version": "5.0.1-staging.048a6d1f",
4
+ "description": "Gemini CLI 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-gemini"
16
+ },
17
+ "homepage": "https://github.com/a5c-ai/babysitter/tree/main/packages/hooks-mux/adapter-gemini#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.048a6d1f"
34
+ },
35
+ "devDependencies": {
36
+ "typescript": "^5.7.0",
37
+ "vitest": "^3.0.0",
38
+ "rimraf": "^6.0.0"
39
+ }
40
+ }