@triflux/core 10.31.0 → 10.32.0

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.
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { argv, exit, stdin, stdout } from "node:process";
4
+ import { pathToFileURL } from "node:url";
5
+ import { drainPendingSynapse as defaultDrainPendingSynapse } from "../hub/team/synapse-http.mjs";
6
+ import {
7
+ heartbeatInteractiveSession as defaultHeartbeatInteractiveSession,
8
+ registerInteractiveSession as defaultRegisterInteractiveSession,
9
+ } from "./session-start-fast.mjs";
10
+
11
+ // hub-ensure is loaded lazily so the byte-identical packages/core mirror of this
12
+ // file loads cleanly. packages/core mirrors scripts/lib only (not scripts/*), so a
13
+ // static `../scripts/hub-ensure.mjs` import would make the core copy throw
14
+ // ERR_MODULE_NOT_FOUND at load time. The core copy is published-but-dormant — the
15
+ // live codex hook always runs from the installed triflux package where the path
16
+ // resolves. This mirrors session-start-fast.mjs's dynamic script-import pattern.
17
+ async function defaultHubEnsureRun(stdinData) {
18
+ const { run } = await import(
19
+ new URL("../scripts/hub-ensure.mjs", import.meta.url).href
20
+ );
21
+ return run(stdinData);
22
+ }
23
+
24
+ function parsePayload(stdinData) {
25
+ try {
26
+ const raw = typeof stdinData === "string" ? stdinData : "";
27
+ return raw.trim()
28
+ ? { ok: true, payload: JSON.parse(raw) }
29
+ : { ok: false, payload: {} };
30
+ } catch {
31
+ return { ok: false, payload: {} };
32
+ }
33
+ }
34
+
35
+ function normalizeMode(mode, payload) {
36
+ const direct = String(mode || "")
37
+ .trim()
38
+ .toLowerCase();
39
+ if (direct === "register" || direct === "heartbeat") return direct;
40
+
41
+ const eventName = String(payload?.hook_event_name || "")
42
+ .trim()
43
+ .toLowerCase()
44
+ .replace(/-/g, "_");
45
+ if (eventName === "session_start" || eventName === "sessionstart") {
46
+ return "register";
47
+ }
48
+ if (eventName === "user_prompt_submit" || eventName === "userpromptsubmit") {
49
+ return "heartbeat";
50
+ }
51
+ return "";
52
+ }
53
+
54
+ export async function runCodexSessionHook(stdinData, opts = {}) {
55
+ const output = "{}\n";
56
+ const parsed = parsePayload(stdinData);
57
+ const mode = parsed.ok
58
+ ? normalizeMode(opts.argvMode ?? argv[2], parsed.payload)
59
+ : "";
60
+ const hubEnsureRun = opts.hubEnsureRun || defaultHubEnsureRun;
61
+ const registerInteractiveSession =
62
+ opts.registerInteractiveSession || defaultRegisterInteractiveSession;
63
+ const heartbeatInteractiveSession =
64
+ opts.heartbeatInteractiveSession || defaultHeartbeatInteractiveSession;
65
+ const drainPendingSynapse =
66
+ opts.drainPendingSynapse || defaultDrainPendingSynapse;
67
+
68
+ try {
69
+ if (mode === "register") {
70
+ try {
71
+ await hubEnsureRun(stdinData);
72
+ } catch {}
73
+ try {
74
+ registerInteractiveSession(stdinData);
75
+ } catch {}
76
+ try {
77
+ await drainPendingSynapse(1000);
78
+ } catch {}
79
+ } else if (mode === "heartbeat") {
80
+ try {
81
+ heartbeatInteractiveSession(stdinData);
82
+ } catch {}
83
+ try {
84
+ await drainPendingSynapse(500);
85
+ } catch {}
86
+ }
87
+ } catch {
88
+ // Codex session hooks are observational and must never block the session.
89
+ }
90
+
91
+ if (opts.writeStdout !== false) {
92
+ stdout.write(output);
93
+ }
94
+ return output;
95
+ }
96
+
97
+ function readStdin() {
98
+ return new Promise((resolve) => {
99
+ let data = "";
100
+ stdin.setEncoding("utf8");
101
+ stdin.on("data", (chunk) => {
102
+ data += chunk;
103
+ });
104
+ stdin.on("end", () => resolve(data));
105
+ stdin.on("error", () => resolve(data));
106
+ });
107
+ }
108
+
109
+ if (argv[1] && import.meta.url === pathToFileURL(argv[1]).href) {
110
+ const stdinData = await readStdin();
111
+ await runCodexSessionHook(stdinData);
112
+ exit(0);
113
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@triflux/core",
3
- "version": "10.31.0",
3
+ "version": "10.32.0",
4
4
  "description": "triflux core — CLI routing, pipeline, adapters. Zero native dependencies.",
5
5
  "type": "module",
6
6
  "main": "hub/index.mjs",