Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/tidy-rivers-smile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"hunkdiff": minor
---

Add `HUNK_RUNTIME_DIR` as an override for session runtime state and credentials, ahead of `XDG_RUNTIME_DIR`.
5 changes: 3 additions & 2 deletions docs/session-broker-sdk.md
Original file line number Diff line number Diff line change
Expand Up @@ -583,8 +583,9 @@ of becoming a second restart owner. Daemons too old to retire while idle, or hun
require manual termination. Preservation means paths, selectors, outputs, and automatic credential
discovery for upgraded clients—not interoperability with pre-authentication binaries.

Hunk's fixed-endpoint Phase-1 credential store uses a home-local `.hunk` parent when
`XDG_RUNTIME_DIR` is unavailable, rather than a predictable name in a shared temporary directory.
Hunk's fixed-endpoint Phase-1 credential store uses `HUNK_RUNTIME_DIR` when set, then
`XDG_RUNTIME_DIR`, and otherwise a home-local `.hunk` parent rather than a predictable name in a
shared temporary directory.
It inherits the current user's ACL when it creates the `hunk-mcp/security-v1` directory
on Windows and rejects symbolic-link redirection. Node does not
provide a portable owner/DACL or general reparse-point inspection API, so this integration cannot
Expand Down
2 changes: 1 addition & 1 deletion packages/hunk/src/session/broker/brokerLauncher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ function safeRuntimeToken(value: string) {
}

function resolveRuntimeBaseDir(env: NodeJS.ProcessEnv = process.env) {
const configured = env.XDG_RUNTIME_DIR?.trim();
const configured = env.HUNK_RUNTIME_DIR?.trim() || env.XDG_RUNTIME_DIR?.trim();
if (configured) return configured;
// Unix temporary directories are commonly shared across users. Keep the fallback beneath the
// current home directory instead of a predictable shared-/tmp name another account can pre-own.
Expand Down
14 changes: 14 additions & 0 deletions packages/hunk/src/session/broker/credentials.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,20 @@ describe("Hunk session broker credential store", () => {
expect(callerFile).not.toContain("hunk-review-capability");
});

test("uses HUNK_RUNTIME_DIR ahead of XDG_RUNTIME_DIR for credentials", async () => {
const env = isolatedEnv();
const override = mkdtempSync(join(tmpdir(), "hunk-runtime-override-"));
roots.push(override);
env.HUNK_RUNTIME_DIR = override;

await loadOrCreateHunkSessionBrokerCredentials({ env });

expect(lstatSync(join(override, "hunk-mcp", "security-v1", "caller.json")).isFile()).toBe(
true,
);
expect(() => lstatSync(join(env.XDG_RUNTIME_DIR!, "hunk-mcp"))).toThrow();
});

test("adopts one complete winner under concurrent first use", async () => {
const env = isolatedEnv();
const results = await Promise.all(
Expand Down