@ascenda-one/gemini-hooks 0.1.20 → 0.1.22

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/dist/cli.js CHANGED
@@ -745,12 +745,12 @@ var require_payload = __commonJS({
745
745
  "use strict";
746
746
  Object.defineProperty(exports, "__esModule", { value: true });
747
747
  exports.mintIdempotencyKey = mintIdempotencyKey;
748
- exports.getString = getString2;
748
+ exports.getString = getString3;
749
749
  exports.getNumber = getNumber;
750
750
  exports.getNested = getNested;
751
751
  exports.getNestedString = getNestedString2;
752
752
  exports.getNestedNumber = getNestedNumber;
753
- exports.inferOutcome = inferOutcome2;
753
+ exports.inferOutcome = inferOutcome3;
754
754
  exports.outcomeForHook = outcomeForHook;
755
755
  exports.looksLikeCorrection = looksLikeCorrection2;
756
756
  var node_crypto_1 = __require("node:crypto");
@@ -761,7 +761,7 @@ var require_payload = __commonJS({
761
761
  throw new Error("idempotency key exceeds the wire limit");
762
762
  return key;
763
763
  }
764
- function getString2(input, keys) {
764
+ function getString3(input, keys) {
765
765
  for (const key of keys) {
766
766
  const value = input[key];
767
767
  if (typeof value === "string" && value.trim())
@@ -802,11 +802,11 @@ var require_payload = __commonJS({
802
802
  }
803
803
  return void 0;
804
804
  }
805
- function inferOutcome2(input) {
805
+ function inferOutcome3(input) {
806
806
  const exitCode = getNumber(input, ["exitCode", "exit_code", "status"]) ?? getNestedNumber(input, [["tool_response", "exitCode"], ["tool_response", "exit_code"], ["result", "exitCode"], ["result", "exit_code"]]);
807
807
  if (typeof exitCode === "number")
808
808
  return exitCode === 0 ? "success" : "failure";
809
- const error = getString2(input, ["error", "errorMessage"]) ?? getNestedString2(input, [["tool_response", "error"], ["result", "error"]]);
809
+ const error = getString3(input, ["error", "errorMessage"]) ?? getNestedString2(input, [["tool_response", "error"], ["result", "error"]]);
810
810
  if (error)
811
811
  return "failure";
812
812
  return "unknown";
@@ -1113,8 +1113,8 @@ var require_tokenStore = __commonJS({
1113
1113
  var fs = __importStar(__require("fs"));
1114
1114
  var os2 = __importStar(__require("os"));
1115
1115
  var path2 = __importStar(__require("path"));
1116
- function ascendaHome() {
1117
- return process.env.ASCENDA_HOME ?? path2.join(os2.homedir(), ".ascenda");
1116
+ function ascendaHome(home = os2.homedir()) {
1117
+ return process.env.ASCENDA_HOME ?? path2.join(home, ".ascenda");
1118
1118
  }
1119
1119
  function defaultTokenFilePath(toolInstallationId) {
1120
1120
  return path2.join(ascendaHome(), "tokens", sanitizeFilePart(toolInstallationId));
@@ -2397,10 +2397,10 @@ var require_salt = __commonJS({
2397
2397
  exports.hashWithMachineSalt = hashWithMachineSalt;
2398
2398
  var crypto = __importStar(__require("crypto"));
2399
2399
  var fs = __importStar(__require("fs"));
2400
- var os2 = __importStar(__require("os"));
2401
2400
  var path2 = __importStar(__require("path"));
2401
+ var tokenStore_1 = require_tokenStore();
2402
2402
  function machineSaltFilePath() {
2403
- return path2.join(os2.homedir(), ".ascenda", "salt");
2403
+ return path2.join((0, tokenStore_1.ascendaHome)(), "salt");
2404
2404
  }
2405
2405
  var cache = /* @__PURE__ */ new Map();
2406
2406
  function readOrCreateMachineSalt(saltFilePath = machineSaltFilePath()) {
@@ -3307,8 +3307,8 @@ var require_liveBus = __commonJS({
3307
3307
  Object.defineProperty(exports, "__esModule", { value: true });
3308
3308
  exports.liveBusSocketCandidates = liveBusSocketCandidates;
3309
3309
  exports.liveBusSocketPath = liveBusSocketPath;
3310
- exports.bucketPromptSize = bucketPromptSize;
3311
- exports.emitLiveSignal = emitLiveSignal;
3310
+ exports.bucketPromptSize = bucketPromptSize2;
3311
+ exports.emitLiveSignal = emitLiveSignal2;
3312
3312
  var fs = __importStar(__require("fs"));
3313
3313
  var net = __importStar(__require("net"));
3314
3314
  var os2 = __importStar(__require("os"));
@@ -3338,7 +3338,7 @@ var require_liveBus = __commonJS({
3338
3338
  }
3339
3339
  return candidates[0];
3340
3340
  }
3341
- function bucketPromptSize(text) {
3341
+ function bucketPromptSize2(text) {
3342
3342
  const length = typeof text === "string" ? text.length : 0;
3343
3343
  if (length <= 280)
3344
3344
  return "s";
@@ -3348,7 +3348,7 @@ var require_liveBus = __commonJS({
3348
3348
  return "l";
3349
3349
  return "xl";
3350
3350
  }
3351
- function emitLiveSignal(signal) {
3351
+ function emitLiveSignal2(signal) {
3352
3352
  return new Promise((resolve) => {
3353
3353
  let settled = false;
3354
3354
  const done = () => {
@@ -3742,7 +3742,7 @@ var require_out2 = __commonJS({
3742
3742
  });
3743
3743
 
3744
3744
  // src/cli.ts
3745
- var import_tool_kit2 = __toESM(require_out2(), 1);
3745
+ var import_tool_kit3 = __toESM(require_out2(), 1);
3746
3746
 
3747
3747
  // src/mapGeminiEvent.ts
3748
3748
  var import_tool_kit = __toESM(require_out2(), 1);
@@ -3832,6 +3832,27 @@ function withHost(metadata) {
3832
3832
  return { host: GEMINI_HOST, ...metadata };
3833
3833
  }
3834
3834
 
3835
+ // src/liveSignal.ts
3836
+ var import_tool_kit2 = __toESM(require_out2(), 1);
3837
+ function liveSignalFor(hookName, input) {
3838
+ switch (hookName) {
3839
+ case "BeforeAgent": {
3840
+ const prompt = (0, import_tool_kit2.getString)(input, ["prompt"]);
3841
+ return prompt === void 0 ? { event: "prompt_submitted" } : { event: "prompt_submitted", sizeBucket: (0, import_tool_kit2.bucketPromptSize)(prompt) };
3842
+ }
3843
+ case "BeforeTool":
3844
+ return { event: "tool_call" };
3845
+ case "AfterTool":
3846
+ return (0, import_tool_kit2.inferOutcome)(input) === "failure" ? { event: "tool_failure" } : void 0;
3847
+ case "PreCompress":
3848
+ return { event: "compaction" };
3849
+ case "AfterAgent":
3850
+ return { event: "stop" };
3851
+ default:
3852
+ return void 0;
3853
+ }
3854
+ }
3855
+
3835
3856
  // src/setup.ts
3836
3857
  import * as os from "os";
3837
3858
  import * as path from "path";
@@ -3861,8 +3882,8 @@ var SETUP = {
3861
3882
 
3862
3883
  // src/cli.ts
3863
3884
  async function main() {
3864
- if ((0, import_tool_kit2.isCliAgentManagementCommand)(process.argv[2])) {
3865
- managementExitCode = await (0, import_tool_kit2.runCliAgentSetup)(process.argv.slice(2), SETUP);
3885
+ if ((0, import_tool_kit3.isCliAgentManagementCommand)(process.argv[2])) {
3886
+ managementExitCode = await (0, import_tool_kit3.runCliAgentSetup)(process.argv.slice(2), SETUP);
3866
3887
  return;
3867
3888
  }
3868
3889
  const input = await readJsonFromStdin();
@@ -3873,9 +3894,10 @@ async function main() {
3873
3894
  }
3874
3895
  const sessionId = typeof input.session_id === "string" ? input.session_id : void 0;
3875
3896
  let turnDurationMs;
3876
- if (hookName === "BeforeAgent") (0, import_tool_kit2.recordTurnStart)(GEMINI_HOST, sessionId);
3877
- if (hookName === "AfterAgent") turnDurationMs = (0, import_tool_kit2.consumeTurnDurationMs)(GEMINI_HOST, sessionId);
3878
- await (0, import_tool_kit2.deliverHookEvents)(mapGeminiEvent(hookName, input, turnDurationMs), {
3897
+ if (hookName === "BeforeAgent") (0, import_tool_kit3.recordTurnStart)(GEMINI_HOST, sessionId);
3898
+ if (hookName === "AfterAgent") turnDurationMs = (0, import_tool_kit3.consumeTurnDurationMs)(GEMINI_HOST, sessionId);
3899
+ await emitLive(hookName, input, sessionId);
3900
+ await (0, import_tool_kit3.deliverHookEvents)(mapGeminiEvent(hookName, input, turnDurationMs), {
3879
3901
  toolType: ASCENDA_TOOL_TYPE,
3880
3902
  host: GEMINI_HOST,
3881
3903
  setupCommand: `npx ${SETUP.packageName} setup`,
@@ -3883,6 +3905,29 @@ async function main() {
3883
3905
  sessionId
3884
3906
  });
3885
3907
  }
3908
+ async function emitLive(hookName, input, sessionId) {
3909
+ const body = liveSignalFor(hookName, input);
3910
+ if (!body) return;
3911
+ try {
3912
+ await (0, import_tool_kit3.emitLiveSignal)({
3913
+ // This host's own name, not the shared `cli_agent` tool type the cloud
3914
+ // path files these events under. The app keys one decaying envelope per
3915
+ // `tool/session` pair, so reporting a value shared with the other CLI
3916
+ // adapters would fuse three different agents into one stream and make
3917
+ // the concurrency gauge under-count. `ASCENDA_TOOL_TYPE` is deliberately
3918
+ // *not* honoured here for the same reason: it is the cloud tool type,
3919
+ // and on this adapter that value is the shared one.
3920
+ tool: GEMINI_HOST,
3921
+ // Concurrent sessions must count as separate streams for the X gauge.
3922
+ // Without a session id every window collapses into one, so fall back to
3923
+ // this process's parent — still per-session in practice, since the hook
3924
+ // is spawned from the session process.
3925
+ session: sessionId ?? `ppid-${process.ppid}`,
3926
+ ...body
3927
+ });
3928
+ } catch {
3929
+ }
3930
+ }
3886
3931
  var managementExitCode;
3887
3932
  async function readJsonFromStdin() {
3888
3933
  const chunks = [];
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,2BAA2B,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACjJ,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAwC,MAAM,YAAY,CAAC;AAElG;;;;;;;;;GASG;AACH,KAAK,UAAU,IAAI;IACjB,IAAI,2BAA2B,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,kBAAkB,GAAG,MAAM,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QAC1E,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,iBAAiB,EAAE,CAAC;IACxC,MAAM,QAAQ,GAAG,CAAC,OAAO,KAAK,CAAC,eAAe,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAoC,CAAC;IAC1I,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,8HAA8H,CAAC,CAAC;QAC9I,OAAO;IACT,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;IAEtF,IAAI,cAAkC,CAAC;IACvC,IAAI,QAAQ,KAAK,aAAa;QAAE,eAAe,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IACxE,IAAI,QAAQ,KAAK,YAAY;QAAE,cAAc,GAAG,qBAAqB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAE9F,MAAM,iBAAiB,CAAC,cAAc,CAAC,QAAQ,EAAE,KAAK,EAAE,cAAc,CAAC,EAAE;QACvE,QAAQ,EAAE,iBAAiB;QAC3B,IAAI,EAAE,WAAW;QACjB,YAAY,EAAE,OAAO,KAAK,CAAC,WAAW,QAAQ;QAC9C,MAAM,EAAE,WAAW;QACnB,SAAS;KACV,CAAC,CAAC;AACL,CAAC;AAED,6EAA6E;AAC7E,IAAI,kBAAsC,CAAC;AAE3C,KAAK,UAAU,iBAAiB;IAC9B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACnE,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1D,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YAAE,OAAO,EAAE,CAAC;QAC9E,OAAO,MAAyB,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,IAAI,EAAE;KACH,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACf,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACxE,CAAC,CAAC;KACD,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,IAAI,CAAC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import { bucketPromptSize, getString, inferOutcome } from "@ascenda-one/tool-kit";
2
+ /**
3
+ * Maps Gemini CLI hooks onto the desktop waterline's much smaller vocabulary
4
+ * (`LiveBusEvent` in `@ascenda-one/tool-kit`;
5
+ * `docs/MACOS_LIVE_DEMAND_WATERLINE.md` in the app repo).
6
+ *
7
+ * This is **not** the telemetry mapping and shares nothing with
8
+ * `mapGeminiEvent`. That one feeds daily buckets read hours later; this one
9
+ * drives gauges, the Away Mode keep-awake assertion and the settle bell, all
10
+ * of which need to know only that agent work is happening right now.
11
+ *
12
+ * Deliberately partial, and deliberately leading-edge:
13
+ *
14
+ * - `BeforeAgent` is the turn's opening beat and `AfterAgent` its close, so
15
+ * they carry `prompt_submitted` and `stop`. Gemini's `SessionStart` and
16
+ * `SessionEnd` bracket a whole CLI run rather than a turn and add nothing
17
+ * the pair above does not already say; `SessionEnd` in particular would
18
+ * be a second `stop` immediately after the last `AfterAgent`, which the
19
+ * saver would draw as two session ends.
20
+ * - `BeforeTool`, not `AfterTool`, carries the cadence heartbeat, so the
21
+ * gauge rises as the agent starts rather than after it finishes.
22
+ * - `AfterTool` therefore speaks only when the call **failed**. Gemini has
23
+ * no separate failure hook, so the outcome is read off the payload the
24
+ * same way the telemetry mapper reads it.
25
+ * - `PreCompress` is Gemini's compaction.
26
+ * - `BeforeModel`/`AfterModel`/`BeforeToolSelection` fire per LLM round trip
27
+ * and are silent here for the same reason they are silent in the
28
+ * telemetry mapper: the tool hooks already carry that cadence, and these
29
+ * would multiply it several-fold.
30
+ *
31
+ * `undefined` means silence, which is the right answer for most hooks. An
32
+ * event the app cannot parse is worse than none, because it looks like it
33
+ * works.
34
+ */
35
+ export function liveSignalFor(hookName, input) {
36
+ switch (hookName) {
37
+ case "BeforeAgent": {
38
+ const prompt = getString(input, ["prompt"]);
39
+ // The bucket is computed here so only the bucket crosses the socket.
40
+ // Omitted when the payload carried no prompt: the aggregator falls
41
+ // back to its own middle attack height, which is a better reading than
42
+ // asserting a size we did not observe.
43
+ return prompt === undefined ? { event: "prompt_submitted" } : { event: "prompt_submitted", sizeBucket: bucketPromptSize(prompt) };
44
+ }
45
+ case "BeforeTool": return { event: "tool_call" };
46
+ case "AfterTool": return inferOutcome(input) === "failure" ? { event: "tool_failure" } : undefined;
47
+ case "PreCompress": return { event: "compaction" };
48
+ case "AfterAgent": return { event: "stop" };
49
+ default: return undefined;
50
+ }
51
+ }
52
+ /**
53
+ * `queued` is absent from every Gemini signal, and that is a measurement, not
54
+ * an omission. Gemini's hook payloads carry nothing that says a turn came out
55
+ * of the user's queue, and the field is tri-state precisely so a tool that
56
+ * cannot know says nothing rather than saying "no" (see `LiveBusSignal` and
57
+ * `LiveSignal.queued` in the app). Only the Claude Code adapter can answer.
58
+ */
59
+ //# sourceMappingURL=liveSignal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"liveSignal.js","sourceRoot":"","sources":["../src/liveSignal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAOlF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,UAAU,aAAa,CAAC,QAA6B,EAAE,KAAsB;IACjF,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,aAAa,CAAC,CAAC,CAAC;YACnB,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC5C,qEAAqE;YACrE,mEAAmE;YACnE,uEAAuE;YACvE,uCAAuC;YACvC,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;QACpI,CAAC;QACD,KAAK,YAAY,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;QACjD,KAAK,WAAW,CAAC,CAAC,OAAO,YAAY,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QACnG,KAAK,aAAa,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;QACnD,KAAK,YAAY,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAC5C,OAAO,CAAC,CAAC,OAAO,SAAS,CAAC;IAC5B,CAAC;AACH,CAAC;AAED;;;;;;GAMG"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "publishConfig": { "access": "public" },
3
3
  "name": "@ascenda-one/gemini-hooks",
4
- "version": "0.1.20",
4
+ "version": "0.1.22",
5
5
  "description": "Gemini CLI hooks adapter for Ascenda AI workload telemetry",
6
6
  "repository": {
7
7
  "type": "git",