trantor 0.18.69 → 0.18.70

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trantor",
3
- "version": "0.18.69",
3
+ "version": "0.18.70",
4
4
  "description": "Trantor — the hub-world for AI agent crews: live message bus, presence, project Kanban/flow board + crew orchestration for independent AI coding agents (Claude, Codex, Gemini, Kimi, DeepSeek)",
5
5
  "mcpServers": {
6
6
  "relay": {
package/bin/baton.mjs CHANGED
@@ -3,12 +3,12 @@
3
3
  // a whole-session handoff (auto-summary + verbatim in-flight tail), opens a fresh self-announcing
4
4
  // session, and closes THIS window once it takes over. Run from inside the session you want to hand
5
5
  // off. (The richer MODEL-authored handoff is the /trantor:handoff skill.)
6
- import { readdirSync, statSync, fstatSync } from "node:fs";
6
+ import { readdirSync, statSync } from "node:fs";
7
7
  import { join, basename, dirname } from "node:path";
8
8
  import { homedir } from "node:os";
9
9
  import { spawn } from "node:child_process";
10
10
  import { fileURLToPath } from "node:url";
11
- import { writeHandoff, spawnBaton, resolveHandoffSurface, armBaton, contextUsage, controllingTty, turnInFlight, armMaxMs, sessionProcessState } from "../hooks/lib/handoff.mjs";
11
+ import { writeHandoff, spawnBaton, resolveHandoffSurface, armBaton, contextUsage, controllingTty, turnInFlight, armMaxMs, sessionProcessState, stdinCarriesMarkdown } from "../hooks/lib/handoff.mjs";
12
12
 
13
13
  // #6074: the skill path (write-handoff.mjs) and this CLI path must share ONE resolution of which
14
14
  // project this is and where the session lives. Both call resolveHandoffSurface; the name comes
@@ -22,18 +22,11 @@ const project = resolved.project;
22
22
  // cwd that cd'd somewhere else: a handoff record must carry the transcript it was written from.
23
23
  const sessionDir = resolved.projectDir;
24
24
 
25
- // Model-authored handoffs ride THIS binary too (`trantor handoff` — always the global install's
26
- // CURRENT code, never the plugin-cache copy a session booted with, the stale-0.18.20 bug). A piped
27
- // stdin (a heredoc, a cat, `<<HANDOFF`) means "here is the handoff markdown" — exactly the skill's
28
- // contract — so forward to write-handoff.mjs in the SAME package (same version, same resolution)
29
- // and exit with its status. --latest forwards too. A true pipe is a FIFO; a TTY and /dev/null are
30
- // character devices, so a plain `trantor handoff` typed at a prompt (or run by a hook with stdin
31
- // at /dev/null) keeps the auto-summary behavior. Detection must NOT be `!process.stdin.isTTY` —
32
- // that misreads /dev/null as a handoff and errors where auto-summary used to work.
33
- function stdinIsPipe() {
34
- try { return fstatSync(0).isFIFO(); } catch { return false; }
35
- }
36
- if (stdinIsPipe() || process.argv.includes("--latest")) {
25
+ // Model-authored handoffs ride THIS binary too — always the global install's CURRENT code, never
26
+ // the plugin-cache copy a session booted with (the stale-0.18.20 bug). Markdown on stdin means
27
+ // "here is the handoff", so forward to write-handoff.mjs in the SAME package; --latest forwards too.
28
+ // What counts as markdown, and why /dev/null must not: stdinCarriesMarkdown in hooks/lib (#8459).
29
+ if (stdinCarriesMarkdown() || process.argv.includes("--latest")) {
37
30
  const helper = join(dirname(fileURLToPath(import.meta.url)), "write-handoff.mjs");
38
31
  const child = spawn(process.execPath, [helper, ...process.argv.slice(2)], { stdio: ["inherit", "inherit", "inherit"] });
39
32
  child.on("exit", (c) => process.exit(c ?? 1));
@@ -64,12 +57,10 @@ function autoBaton() {
64
57
  // The transcript's filename IS the writing session's id — record it, or an orchestrator-thread
65
58
  // handoff carries no writer and the baton-hold + map-follow logic in sessionstart.mjs can't fire.
66
59
  const sessionId = transcript ? basename(transcript, ".jsonl") : "";
67
- // #6528: WHO pulled the trigger. A TTY stdin means a human typed `trantor handoff` at a prompt;
68
- // the app chain (lib.rs handoff_now) and hooks spawn this binary with piped stdio. The operator's
69
- // own typed command keeps the storm-guard bypass (force:true — "manual = intentional"); every
70
- // invoked path goes through the boundary gate and the hub's storm guard like any auto handoff.
71
- // --reason rides through from the app (`--reason clicked|countdown|unattended`) so the RECORD
72
- // finally names the real trigger instead of laundering every banner fire into "manual-cli".
60
+ // #6528: WHO pulled the trigger. A TTY stdin is a human typing it; the app chain (handoff_now)
61
+ // and hooks spawn this with piped stdio. Only the typed command keeps the storm-guard bypass
62
+ // (manual = intentional); every invoked path goes through the boundary gate like an auto handoff.
63
+ // --reason rides through from the app so the record names the real trigger, not "manual-cli".
73
64
  const reasonArg = (() => {
74
65
  const i = process.argv.indexOf("--reason");
75
66
  const v = i >= 0 ? String(process.argv[i + 1] || "").trim() : "";
@@ -888,6 +888,14 @@ export function pathsReadIn(transcriptPath, paths) {
888
888
  return { read, missed: want.filter(p => !read.includes(p)) };
889
889
  }
890
890
 
891
+ /** Markdown on stdin, or a bare `trantor handoff`? A heredoc is a TEMP FILE, not a FIFO, and an
892
+ * isFIFO()-only check discarded the model's handoff while printing "handoff armed" (#8459).
893
+ * Character devices stay out: that is the TTY and the /dev/null a hook runs with.
894
+ */
895
+ export function stdinCarriesMarkdown(fd = 0) {
896
+ try { const st = fstatSync(fd); return st.isFIFO() || st.isFile(); } catch { return false; }
897
+ }
898
+
891
899
  // The self-announcing fresh session command (single-quoted so it survives osascript→shell un-escaped).
892
900
  // Brevity is the point, but #8162 found it had become permission not to READ: the summary is injected
893
901
  // at SessionStart, so a 3-sentence recap is producible without opening a file. The order is now
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trantor",
3
- "version": "0.18.69",
3
+ "version": "0.18.70",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "trantor": "bin/cli.mjs"