@lucas_zaia/agent-voice 1.1.2 → 1.1.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lucas_zaia/agent-voice",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "description": "Make your coding agent talk to you: a smart speaker says when a long task finishes or when the agent needs you.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,7 +1,7 @@
1
1
  // Translates Codex CLI hook payloads into canonical events. Codex hooks share
2
- // Claude Code's shape; the differences are the event names, no ai-title in the
3
- // transcript (Codex calls its format unstable), and Stop wanting JSON back.
4
- import { existsSync } from 'node:fs';
2
+ // Claude Code's shape; the differences are the event names, session names living
3
+ // in Codex's session index, and Stop wanting JSON back.
4
+ import { existsSync, readFileSync } from 'node:fs';
5
5
  import { homedir } from 'node:os';
6
6
  import { join, dirname } from 'node:path';
7
7
  import { str, projectOf } from './common.js';
@@ -22,6 +22,8 @@ export function configFile(env = process.env, home = homedir()) {
22
22
 
23
23
  export const detect = (env = process.env, home = homedir()) => existsSync(dirname(configFile(env, home)));
24
24
 
25
+ export const sessionIndexFile = (env = process.env, home = homedir()) => join(dirname(configFile(env, home)), 'session_index.jsonl');
26
+
25
27
  // Codex treats non-JSON stdout from a Stop hook as invalid.
26
28
  export const hookReply = (sub) => (sub === 'stop' ? '{}' : '');
27
29
 
@@ -35,9 +37,37 @@ const MAPPING = {
35
37
  permission: ['needs_input', permissionText],
36
38
  };
37
39
 
38
- export function translate(sub, payload, home = homedir()) {
40
+ export function sessionName(sessionId, env = process.env, home = homedir()) {
41
+ const id = str(sessionId);
42
+ if (!id) return '';
43
+ try {
44
+ const lines = readFileSync(sessionIndexFile(env, home), 'utf8').split(/\r?\n/);
45
+ for (let i = lines.length - 1; i >= 0; i--) {
46
+ if (!lines[i].includes(id)) continue;
47
+ try {
48
+ const row = JSON.parse(lines[i]);
49
+ if (str(row.id) === id) return str(row.thread_name);
50
+ } catch {
51
+ return '';
52
+ }
53
+ }
54
+ } catch {
55
+ return '';
56
+ }
57
+ return '';
58
+ }
59
+
60
+ export function translate(sub, payload, home = homedir(), env = process.env) {
39
61
  if (!Object.hasOwn(MAPPING, sub)) return null;
40
62
  const p = payload && typeof payload === 'object' ? payload : {};
41
63
  const [type, text] = MAPPING[sub];
42
- return { type, agent: name, session_id: str(p.session_id), session_name: '', project: projectOf(p.cwd, home), text: text(p) };
64
+ const sessionId = str(p.session_id);
65
+ return {
66
+ type,
67
+ agent: name,
68
+ session_id: sessionId,
69
+ session_name: str(p.session_name) || str(p.thread_name) || sessionName(sessionId, env, home),
70
+ project: projectOf(p.cwd, home),
71
+ text: text(p),
72
+ };
43
73
  }
package/src/cli/notify.js CHANGED
@@ -48,7 +48,7 @@ export async function runNotify(args, { input = '', env = process.env, write = (
48
48
  if (reply) write(reply);
49
49
  let payload = {};
50
50
  try { payload = JSON.parse(input); } catch { /* garbage in: the core logs the incomplete event */ }
51
- const event = adapter.translate(sub, payload);
51
+ const event = adapter.translate(sub, payload, undefined, env);
52
52
  if (!event) return 0;
53
53
  await handle(event, createContext(env));
54
54
  } catch (e) {