feat(cli): export HAPI_SESSION_ID into wrapped agent env (self-targeting) (#1121)

* feat(cli): export HAPI_SESSION_ID into wrapped agent env

Publish the hub session id into process.env at session bootstrap so every
downstream agent spawn inherits it. HAPI runs one hub session per CLI process
(the runner forks a fresh hapi child per session; local is 1:1) and every
flavor's agent spawn derives its child env from process.env, so a single seam
covers claude / codex / cursor / gemini / opencode / kimi / grok / pi -
runner-spawned and local - plus future flavors, without touching each launcher.

Agents can read HAPI_SESSION_ID to self-target their own hub session over REST
or shell helpers without listing /api/sessions. Prefer the MCP display_image
tool for inline media when available; HAPI_SESSION_ID is the deterministic
fallback for non-MCP tooling.

Closes #1119

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(scripts): self-target hapi-display-image via HAPI_SESSION_ID

Teach the in-tree shell helper to use $HAPI_SESSION_ID for path-only /
self invocations: GET /api/sessions/:id directly instead of listing
/api/sessions. Explicit session prefixes keep the previous list path.

Gives #1119 a tangible now benefit - the tool that forced the wasteful
list-and-reverse-lookup dance no longer needs it inside a wrapped session.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(cli): defer HAPI_SESSION_ID export until lazy Codex materializes

The provisional lazy-session id was exported at bootstrap before the hub
row existed, so path-only self-targeting (GET /api/sessions/:id) could
404 while materialization was still pending. Export on onMaterialized
instead, and await materialize in buildHapiMcpBridge before starting the
MCP server / spawning Codex so the agent inherits an id the hub can
resolve (and so hapiMcpUrl is persisted, not only local pending state).

Addresses Codex review Major on #1121.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Debian <heavygee@oos-linux.in.lockhouse>
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
HeavyGee
2026-07-24 10:56:59 +08:00
committed by GitHub
co-authored by Cursor Debian
parent 0834dc098c
commit af8d160364
7 changed files with 270 additions and 22 deletions
+28
View File
@@ -0,0 +1,28 @@
/**
* Canonical env var name exported into the wrapped agent / CLI child process so
* it can self-target its own hub session (REST, shell helpers) without listing
* `/api/sessions`. See tiann/hapi#1119.
*/
export const HAPI_SESSION_ID_ENV = 'HAPI_SESSION_ID';
/**
* Publish the hub session id into `process.env` so every downstream agent spawn
* inherits it. HAPI runs one hub session per CLI process (the runner forks a
* fresh `hapi` child per session, and local invocations are 1:1), and every
* flavor's agent spawn derives its child env from `process.env` — so setting it
* here covers claude / codex / cursor / gemini / opencode / kimi / grok / pi at
* once, including future flavors, without touching each launcher.
*
* Prefer the MCP `display_image` tool for inline media when it is available;
* `HAPI_SESSION_ID` is the deterministic fallback for hub REST and shell tooling.
*
* For lazy Codex sessions the id must only be exported after the hub row is
* materialized — exporting the provisional id early makes GET /api/sessions/:id
* fail until materialize completes.
*/
export function exportHapiSessionEnv(sessionId: string): void {
if (!sessionId) {
return;
}
process.env[HAPI_SESSION_ID_ENV] = sessionId;
}