diff --git a/packages/cli/bin/tps.ts b/packages/cli/bin/tps.ts index 0ea2f96..c2e33bf 100755 --- a/packages/cli/bin/tps.ts +++ b/packages/cli/bin/tps.ts @@ -843,7 +843,7 @@ async function main() { const action = rest[0] as "init" | "start" | "stop" | "status" | "log" | undefined; const valid = ["init", "start", "stop", "status", "log"]; if (!action || !valid.includes(action)) { - console.error("Usage:\n tps branch init [--listen ] [--host ] [--transport ws|tcp]\n tps branch start\n tps branch stop\n tps branch status\n tps branch log [--lines N] [--follow]"); + console.error("Usage:\n tps branch init [--listen ] [--host ] [--transport ws|tcp] [--agent ]\n tps branch start\n tps branch stop\n tps branch status\n tps branch log [--lines N] [--follow]"); process.exit(1); } const { runBranch } = await import("../src/commands/branch.js"); @@ -852,6 +852,7 @@ async function main() { port: typeof cli.flags.listen === "number" ? Number(cli.flags.listen) : undefined, host: cli.flags.host, transport: cli.flags.transport === "tcp" ? "tcp" : cli.flags.transport === "ws" ? "ws" : undefined, + agent: cli.flags.agent, force: cli.flags.force, lines: typeof cli.flags.lines === "number" ? Number(cli.flags.lines) : undefined, follow: !!cli.flags.follow, diff --git a/packages/cli/src/commands/branch.ts b/packages/cli/src/commands/branch.ts index d06178f..1786392 100644 --- a/packages/cli/src/commands/branch.ts +++ b/packages/cli/src/commands/branch.ts @@ -21,6 +21,7 @@ export interface BranchArgs { port?: number; host?: string; transport?: "ws" | "tcp"; + agent?: string; force?: boolean; lines?: number; follow?: boolean; @@ -63,7 +64,7 @@ function processAlive(pid: number): boolean { } } -function writeBranchConf(port: number, host: string, transport: "ws" | "tcp", agentsDir?: string): void { +export function writeBranchConf(port: number, host: string, transport: "ws" | "tcp", agentsDir?: string, agentId?: string): void { writeFileSync( confPath(), JSON.stringify( @@ -72,6 +73,7 @@ function writeBranchConf(port: number, host: string, transport: "ws" | "tcp", ag host, transport, agentsDir, + agentId, createdAt: new Date().toISOString(), }, null, @@ -81,7 +83,7 @@ function writeBranchConf(port: number, host: string, transport: "ws" | "tcp", ag ); } -function readBranchConf(): { port: number; host: string; transport: "ws" | "tcp"; agentsDir?: string } { +function readBranchConf(): { port: number; host: string; transport: "ws" | "tcp"; agentsDir?: string; agentId?: string } { const p = confPath(); if (!existsSync(p)) throw new Error("branch.conf.json not found. Run `tps branch init` first."); const raw = JSON.parse(readFileSync(p, "utf-8")); @@ -90,7 +92,8 @@ function readBranchConf(): { port: number; host: string; transport: "ws" | "tcp" port: Number(raw.port), host: String(raw.host || ""), transport: t, - agentsDir: raw.agentsDir ? String(raw.agentsDir) : undefined + agentsDir: raw.agentsDir ? String(raw.agentsDir) : undefined, + agentId: raw.agentId ? String(raw.agentId) : undefined }; } @@ -125,7 +128,11 @@ async function runInit(args: BranchArgs): Promise { const port = args.port ?? 6458; const advertiseHost = args.host ?? hostname(); const transport = args.transport ?? "ws"; - writeBranchConf(port, advertiseHost, transport, undefined); + // agentId resolves the maildir for branch-delivered messages. Default to + // the value at runBranch start time (TPS_AGENT_ID env → conf.agentId → + // hostname). Persisting at init time lets `tps branch start` pick it up + // without re-setting TPS_AGENT_ID in the environment. + writeBranchConf(port, advertiseHost, transport, undefined, args.agent); const pubkeyB64 = Buffer.from(kp.encryption.publicKey).toString("base64url"); const sigPubkeyB64 = Buffer.from(kp.signing.publicKey).toString("base64url"); diff --git a/packages/cli/test/branch.test.ts b/packages/cli/test/branch.test.ts index 34bc71c..b832eb3 100644 --- a/packages/cli/test/branch.test.ts +++ b/packages/cli/test/branch.test.ts @@ -2,7 +2,8 @@ import { describe, test, expect, beforeEach, afterEach } from "bun:test"; import { mkdtempSync, rmSync, existsSync, writeFileSync, mkdirSync } from "node:fs"; import { join } from "node:path"; import { tmpdir } from "node:os"; -import { buildJoinToken, isAlreadyJoined } from "../src/commands/branch.js"; +import { readFileSync } from "node:fs"; +import { buildJoinToken, isAlreadyJoined, writeBranchConf } from "../src/commands/branch.js"; describe("tps branch init", () => { let tmpDir: string; @@ -57,6 +58,32 @@ describe("tps branch init", () => { writeFileSync(join(dir, "host.json"), JSON.stringify({ hostId: "existing" })); expect(isAlreadyJoined(dir)).toBe(true); }); + + test("writeBranchConf persists agentId when --agent supplied (ops-hs19)", () => { + process.env.TPS_ROOT = tmpDir; + try { + writeBranchConf(33744, "localhost", "ws", undefined, "reed"); + const conf = JSON.parse(readFileSync(join(tmpDir, "branch.conf.json"), "utf-8")); + expect(conf.agentId).toBe("reed"); + expect(conf.port).toBe(33744); + expect(conf.host).toBe("localhost"); + expect(conf.transport).toBe("ws"); + } finally { + delete process.env.TPS_ROOT; + } + }); + + test("writeBranchConf omits agentId when not supplied (back-compat)", () => { + process.env.TPS_ROOT = tmpDir; + try { + writeBranchConf(6458, "tps-host", "ws"); + const conf = JSON.parse(readFileSync(join(tmpDir, "branch.conf.json"), "utf-8")); + expect(conf.agentId).toBeUndefined(); + expect(conf.port).toBe(6458); + } finally { + delete process.env.TPS_ROOT; + } + }); }); describe("MSG_JOIN_COMPLETE", () => {