trantor 0.15.0 → 0.17.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.
@@ -1,19 +1,19 @@
1
1
  {
2
- "name": "agent-bus",
2
+ "name": "trantor",
3
3
  "owner": { "name": "Sasha Bogojevic", "email": "hello@hivedigitalllc.com" },
4
4
  "metadata": {
5
- "description": "Live message bus, presence, project Kanban + context-handoff for independent AI coding agents (Claude, Codex, Gemini, …)",
6
- "version": "0.14.0"
5
+ "description": "Trantor — the hub-world for AI agent crews: live message bus, presence, project Kanban/flow board + context-handoff for independent AI coding agents (Claude, Codex, Gemini, …)",
6
+ "version": "0.17.0"
7
7
  },
8
8
  "plugins": [
9
9
  {
10
- "name": "agent-bus",
10
+ "name": "trantor",
11
11
  "source": "./",
12
- "description": "Let independent AI coding sessions Claude Code, Codex, Gemini, any MCP agent talk to each other live: auto-register, see the live roster, message/coordinate, and watch it all on a project-grouped Kanban dashboard. Includes the relay MCP, a SessionStart auto-discovery hook, and a PreCompact context-handoff so a fresh session can take over a full window instead of compacting.",
13
- "version": "0.14.0",
12
+ "description": "The hub-world for AI agent crews. Say \"fire up the crew\" and Claude becomes the architect: a plan-aware Advisor routes the work (solo / cheap inline calls / live crew of Codex, Gemini, Kimi & DeepSeek in their own terminal windows), a Kanban/flow command center with a testing gate tracks it, and an economics brain (Scrooge) keeps the receipts. Includes the relay MCP, a SessionStart auto-discovery hook, and a PreCompact context-handoff so a fresh session can take over a full window instead of compacting.",
13
+ "version": "0.17.0",
14
14
  "author": { "name": "Sasha Bogojevic" },
15
15
  "category": "development",
16
- "keywords": ["multi-agent", "coordination", "mcp", "hooks", "kanban", "context-handoff", "message-bus", "claude-code", "codex", "gemini"]
16
+ "keywords": ["multi-agent", "agent-crew", "orchestration", "coordination", "mcp", "hooks", "kanban", "context-handoff", "message-bus", "claude-code", "codex", "gemini", "llm-routing"]
17
17
  }
18
18
  ]
19
19
  }
@@ -1,7 +1,7 @@
1
1
  {
2
- "name": "agent-bus",
3
- "version": "0.14.0",
4
- "description": "Live message bus, presence, project Kanban + crew orchestration for independent AI coding agents (Claude, Codex, Gemini, Kimi, DeepSeek)",
2
+ "name": "trantor",
3
+ "version": "0.17.0",
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": {
7
7
  "command": "node",
package/README.md CHANGED
@@ -35,7 +35,7 @@ Then give Claude Code (the orchestrator) the plugin:
35
35
 
36
36
  ```bash
37
37
  claude plugin marketplace add sashabogi/trantor
38
- claude plugin install agent-bus
38
+ claude plugin install trantor
39
39
  ```
40
40
 
41
41
  That's it. (Prefer source? `git clone https://github.com/sashabogi/trantor && cd trantor &&
@@ -53,7 +53,7 @@ core
53
53
  ✓ hub up at http://127.0.0.1:4477
54
54
  claude (the orchestrator)
55
55
  ✗ plugin not installed
56
- → claude plugin marketplace add sashabogi/trantor && claude plugin install agent-bus
56
+ → claude plugin marketplace add sashabogi/trantor && claude plugin install trantor
57
57
  crew CLIs (install any subset — seats follow the work)
58
58
  ✓ codex: wired to the bus
59
59
  ✗ codex: NOT authenticated — it will join the bus but fail on its first turn
@@ -63,12 +63,34 @@ the brain
63
63
  ✗ quota profile not set → trantor profile set claude=max codex=plus deepseek=api
64
64
  ```
65
65
 
66
- Fix the `→` lines (each CLI's own sign-in happens once, in that CLI), re-run `trantor doctor`
67
- until it's clean, then open a Claude session in any project and say **"fire up the crew."**
66
+ Fix the `→` lines (each CLI's own sign-in happens once, in that CLI) and re-run `trantor doctor`
67
+ until it's clean.
68
68
 
69
69
  Provider API keys (e.g. `DEEPSEEK_API_KEY`) live in one file: **`~/.agent-bus/.env`** — the
70
70
  crew runners source it automatically.
71
71
 
72
+ ## Your first build
73
+
74
+ Open Claude Code in the project you want built and say it in plain words:
75
+
76
+ > **fire up the crew** — build me a 2-player asteroids game with power-ups
77
+
78
+ Any phrasing works ("build it with the crew", "build this with trantor"), or invoke the
79
+ skill directly: **`/trantor:crew`**. Claude becomes the architect: it cuts the work into
80
+ difficulty-tagged packages, asks the Advisor, and shows you the routing table with a
81
+ real-money estimate **before spending anything**. You say go — terminal windows open, the
82
+ board fills, and you watch it live:
83
+
84
+ ```bash
85
+ trantor ui
86
+ ```
87
+
88
+ No crew CLIs installed yet? It still works — the Advisor routes the work `solo` or to cheap
89
+ inline `scrooge` calls instead of seats. Seats follow the work *and* what's actually installed.
90
+
91
+ Running low on context mid-build? Say **`/trantor:handoff`** — a fresh session in the same
92
+ project takes over with a full window (and a PreCompact hook does this automatically).
93
+
72
94
  ## What happens when you fire up a crew
73
95
 
74
96
  1. **The Advisor moment.** Your Claude cuts the work into difficulty-tagged packages, calls
@@ -183,8 +205,10 @@ Identity: `RELAY_SESSION` → `RELAY_AGENT:<project-folder>` → `<hostname>:<pr
183
205
  always-on/remote hub (private tailnet, or public with auth) is on the roadmap — never expose
184
206
  the hub publicly without auth.
185
207
 
186
- *Heritage note: Trantor grew out of **agent-bus** package internals still carry some
187
- `agent-bus`/`relay_*` identifiers; they migrate in one planned breaking release.*
208
+ *Heritage note: Trantor grew out of **agent-bus**. As of v0.17 the plugin and skills are
209
+ named `trantor` (formerly `agent-bus` if you installed before v0.17:
210
+ `claude plugin uninstall agent-bus && claude plugin marketplace update && claude plugin install trantor`).
211
+ The `relay_*` tool names and the `~/.agent-bus` state dir remain until a later release.*
188
212
 
189
213
  ## Honest limits
190
214
 
package/bin/cli.mjs CHANGED
@@ -48,6 +48,6 @@ switch (cmd) {
48
48
  trantor watch live bus feed in the terminal
49
49
 
50
50
  Claude Code plugin (the orchestrator side):
51
- claude plugin marketplace add sashabogi/trantor && claude plugin install agent-bus
51
+ claude plugin marketplace add sashabogi/trantor && claude plugin install trantor
52
52
  Docs: https://github.com/sashabogi/trantor`);
53
53
  }
package/bin/connect.mjs CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
- // agent-bus connect — wire every AI coding CLI on this machine to the bus, in one shot.
2
+ // trantor connect — wire every AI coding CLI on this machine to the bus, in one shot.
3
3
  //
4
4
  // node bin/connect.mjs # detect installed CLIs, patch each one's MCP config (idempotent)
5
5
  // node bin/connect.mjs --dry-run # show what would change, touch nothing
6
6
  //
7
7
  // Each CLI keeps its own MCP config file/format; this writes the one "relay" entry into each
8
8
  // (with a timestamped .bak backup the first time it changes a file). Claude Code is handled by
9
- // the plugin (claude plugin install agent-bus), so it's only verified here, not patched.
9
+ // the plugin (claude plugin install trantor), so it's only verified here, not patched.
10
10
  import { readFileSync, writeFileSync, existsSync, mkdirSync, copyFileSync } from "node:fs";
11
11
  import { join, dirname } from "node:path";
12
12
  import { homedir } from "node:os";
@@ -39,10 +39,10 @@ const relayEnv = (agent) => ({ RELAY_URL: URL_, RELAY_AGENT: agent });
39
39
 
40
40
  // ---- Claude Code: plugin handles it; verify only ----
41
41
  if (has("claude")) {
42
- let st = "plugin not detected — run: claude plugin marketplace add sashabogi/trantor && claude plugin install agent-bus";
42
+ let st = "plugin not detected — run: claude plugin marketplace add sashabogi/trantor && claude plugin install trantor";
43
43
  try {
44
44
  const s = JSON.parse(readFileSync(join(homedir(), ".claude", "settings.json"), "utf8"));
45
- if (Object.keys(s.enabledPlugins || {}).some(k => k.startsWith("agent-bus@"))) st = "plugin installed ✓";
45
+ if (Object.keys(s.enabledPlugins || {}).some(k => k.startsWith("trantor@") || k.startsWith("agent-bus@"))) st = "plugin installed ✓";
46
46
  } catch {}
47
47
  report("claude", st);
48
48
  }
@@ -53,7 +53,7 @@ if (has("codex")) {
53
53
  const cur = existsSync(p) ? readFileSync(p, "utf8") : "";
54
54
  if (cur.includes("[mcp_servers.relay]")) report("codex", "already wired");
55
55
  else {
56
- const block = `\n# agent-bus — auto-registers each Codex session on the bus + adds relay_* tools\n[mcp_servers.relay]\ncommand = "node"\nargs = ["${MCP}"]\nenv = { RELAY_URL = "${URL_}", RELAY_AGENT = "codex" }\n`;
56
+ const block = `\n# trantor — auto-registers each Codex session on the bus + adds relay_* tools\n[mcp_servers.relay]\ncommand = "node"\nargs = ["${MCP}"]\nenv = { RELAY_URL = "${URL_}", RELAY_AGENT = "codex" }\n`;
57
57
  if (!DRY) { if (existsSync(p)) backup(p); else mkdirSync(dirname(p), { recursive: true }); writeFileSync(p, cur + block); }
58
58
  report("codex", cur ? "wired" : "wired (new config)", p);
59
59
  }
@@ -88,7 +88,7 @@ if (has("opencode")) {
88
88
  }
89
89
 
90
90
  const found = out.length;
91
- console.log(`agent-bus connect${DRY ? " (dry run)" : ""} — hub: ${URL_}`);
91
+ console.log(`trantor connect${DRY ? " (dry run)" : ""} — hub: ${URL_}`);
92
92
  for (const r of out) console.log(` ${r.cli.padEnd(9)} ${r.status}${r.detail ? ` (${r.detail})` : ""}`);
93
93
  if (!found) console.log(" no supported CLIs found on PATH (claude, codex, gemini, kimi, opencode)");
94
94
  console.log(DRY ? "\nRun without --dry-run to apply." : "\nDone. New sessions of each CLI auto-join the bus.");
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // agent-bus crew runner — keeps a crew agent alive forever without burning tokens.
2
+ // trantor crew runner — keeps a crew agent alive forever without burning tokens.
3
3
  //
4
4
  // node crew-runner.mjs <agent> [project-dir]
5
5
  //
@@ -34,7 +34,7 @@ try { mkdirSync(LOGDIR, { recursive: true }); } catch {}
34
34
  let TURN = 0;
35
35
  const telemetry = (rec) => { try { appendFileSync(join(LOGDIR, `${AGENT}-${PROJ}.jsonl`), JSON.stringify(rec) + "\n"); } catch {} };
36
36
  const banner = (trigger) => {
37
- console.log(`\x1b[2J\x1b[H\x1b[48;5;236m\x1b[38;5;43m ◤ ${AGENT.toUpperCase()} ◢ agent-bus crew · ${PROJ} · turn ${TURN} · ${trigger}${MODEL ? ` · ${MODEL}` : ""} \x1b[0m\n`);
37
+ console.log(`\x1b[2J\x1b[H\x1b[48;5;236m\x1b[38;5;43m ◤ ${AGENT.toUpperCase()} ◢ trantor crew · ${PROJ} · turn ${TURN} · ${trigger}${MODEL ? ` · ${MODEL}` : ""} \x1b[0m\n`);
38
38
  };
39
39
 
40
40
  async function api(path, body) {
@@ -67,7 +67,7 @@ const CLI = {
67
67
  const cli = CLI[AGENT];
68
68
  if (!cli) { console.error(`unknown agent '${AGENT}' (known: ${Object.keys(CLI).join(", ")})`); process.exit(1); }
69
69
 
70
- const RULES = `Rules: you are ${SESSION} on the agent-bus crew. Work your assigned file(s), report on the bus (relay_send, <280 chars), move your Kanban card as you go (doing -> testing -> done; run the tests in 'testing', use 'failed' + a report if they break). When your work for THIS message is finished, END YOUR TURN — do NOT park, do NOT loop relay_wait; the runner waits for you and will wake you with the next message.`;
70
+ const RULES = `Rules: you are ${SESSION} on the trantor crew. Work your assigned file(s), report on the bus (relay_send, <280 chars), move your Kanban card as you go (doing -> testing -> done; run the tests in 'testing', use 'failed' + a report if they break). When your work for THIS message is finished, END YOUR TURN — do NOT park, do NOT loop relay_wait; the runner waits for you and will wake you with the next message.`;
71
71
 
72
72
  let sid = "";
73
73
  function runTurn(prompt, isFirst, trigger = "kickoff") {
package/bin/crew.sh CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/bin/bash
2
- # agent-bus crew launcher v2 — visible terminal windows that CANNOT silently die or silently fail.
2
+ # trantor crew launcher v2 — visible terminal windows that CANNOT silently die or silently fail.
3
3
  #
4
4
  # bin/crew.sh up codex gemini kimi deepseek # one window per agent, in the CURRENT project dir
5
5
  # bin/crew.sh down # kill crew processes + close windows (no dialogs)
@@ -91,7 +91,7 @@ spawn_grid() { # $@ = agents — (re)computes the grid for THIS batch and spawn
91
91
  osascript \
92
92
  -e 'tell application "Terminal"' \
93
93
  -e " set w to do script \"cd $DIR && clear && CREW_MODEL=$MODEL node $BUS_DIR/bin/crew-runner.mjs $AGENT $DIR\"" \
94
- -e " set custom title of w to \"$(echo "$AGENT" | tr '[:lower:]' '[:upper:]') — agent-bus crew\"" \
94
+ -e " set custom title of w to \"$(echo "$AGENT" | tr '[:lower:]' '[:upper:]') — trantor crew\"" \
95
95
  -e " set theWin to first window whose tabs contains w" \
96
96
  -e " set bounds of theWin to {$X1, $Y1, $(( X1 + CW )), $(( Y1 + CH ))}" \
97
97
  -e " return id of theWin" \
package/bin/doctor.mjs CHANGED
@@ -38,7 +38,7 @@ else {
38
38
  const st = read(join(H, ".claude", "settings.json")) || {};
39
39
  Object.keys(st.enabledPlugins || {}).some(k => k.startsWith("agent-bus@") || k.startsWith("trantor@"))
40
40
  ? ok("plugin installed")
41
- : warn("plugin not installed", "claude plugin marketplace add sashabogi/trantor && claude plugin install agent-bus");
41
+ : warn("plugin not installed", "claude plugin marketplace add sashabogi/trantor && claude plugin install trantor");
42
42
  }
43
43
 
44
44
  // crew CLIs: installed / wired / authenticated
@@ -1,5 +1,5 @@
1
1
  #!/bin/bash
2
- # agent-bus handoff prompt (macOS) — shown when a session hits its context limit.
2
+ # trantor handoff prompt (macOS) — shown when a session hits its context limit.
3
3
  # Asks the user, with a timeout, whether to open a FRESH same-agent session that takes
4
4
  # over via the handoff. Default (incl. timeout, or no UI) = open fresh. "Keep compacting" = skip.
5
5
  #
@@ -11,10 +11,10 @@ AGENT_CMD="${AGENT_CMD:-claude}"
11
11
  HERE="$(cd "$(dirname "$0")" && pwd)"
12
12
  NAME="$(basename "$DIR")"
13
13
 
14
- MSG="agent-bus — this session's context window is full ($NAME). Open a FRESH session to take over with a full window? It loads a handoff of this session. (The current session keeps compacting either way.)"
14
+ MSG="trantor — this session's context window is full ($NAME). Open a FRESH session to take over with a full window? It loads a handoff of this session. (The current session keeps compacting either way.)"
15
15
 
16
16
  # Best-effort timed dialog. On timeout, error, or no UI session -> empty -> we spawn (the default).
17
- CHOICE="$(osascript -e "button returned of (display dialog \"${MSG//\"/\\\"}\" buttons {\"Keep compacting\", \"Open fresh session\"} default button \"Open fresh session\" giving up after $TIMEOUT with title \"agent-bus\")" 2>/dev/null)"
17
+ CHOICE="$(osascript -e "button returned of (display dialog \"${MSG//\"/\\\"}\" buttons {\"Keep compacting\", \"Open fresh session\"} default button \"Open fresh session\" giving up after $TIMEOUT with title \"trantor\")" 2>/dev/null)"
18
18
 
19
19
  if [ "$CHOICE" != "Keep compacting" ]; then
20
20
  "$HERE/open-session.sh" "$DIR" "$AGENT_CMD"
package/bin/profile.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // agent-bus quota profile — declare what plan each provider runs on, once.
2
+ // trantor quota profile — declare what plan each provider runs on, once.
3
3
  // The Advisor uses this to pick execution modes (plans can't be detected reliably).
4
4
  //
5
5
  // node bin/profile.mjs # show current profile
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- // agent-bus statusline — prints a tiny live indicator for the agent's status bar:
3
- // 🟢 agent-bus · 3 live
2
+ // trantor statusline — prints a tiny live indicator for the agent's status bar:
3
+ // 🟢 trantor · 3 live
4
4
  // Claude Code: add to settings.json ->
5
- // "statusLine": { "type": "command", "command": "node /path/to/agent-bus/bin/statusline.mjs" }
5
+ // "statusLine": { "type": "command", "command": "node /path/to/trantor/bin/statusline.mjs" }
6
6
  // Reads session info as JSON on stdin (Claude Code convention); fast + fail-silent.
7
7
  import { readFileSync, existsSync } from "node:fs";
8
8
  import { join, basename } from "node:path";
@@ -22,9 +22,9 @@ async function main() {
22
22
  const r = await fetch(`${relayUrl()}/peers`, { signal: AbortSignal.timeout(800) });
23
23
  const { peers } = await r.json();
24
24
  const live = peers.filter(p => p.online && p.session !== me).length;
25
- process.stdout.write(`\x1b[38;5;43m● agent-bus\x1b[0m \x1b[2m· ${live} other${live === 1 ? "" : "s"} live\x1b[0m`);
25
+ process.stdout.write(`\x1b[38;5;43m● trantor\x1b[0m \x1b[2m· ${live} other${live === 1 ? "" : "s"} live\x1b[0m`);
26
26
  } catch {
27
- process.stdout.write(`\x1b[2m○ agent-bus offline\x1b[0m`); // hub unreachable
27
+ process.stdout.write(`\x1b[2m○ trantor offline\x1b[0m`); // hub unreachable
28
28
  }
29
29
  }
30
30
  main();
@@ -1,9 +1,9 @@
1
1
  {
2
- "//": "agent-bus for Gemini CLI — merge into ~/.gemini/settings.json (or a project .gemini/settings.json).",
2
+ "//": "trantor for Gemini CLI — merge into ~/.gemini/settings.json (or a project .gemini/settings.json).",
3
3
  "mcpServers": {
4
4
  "relay": {
5
5
  "command": "node",
6
- "args": ["REPLACE/WITH/ABSOLUTE/PATH/agent-bus/mcp.mjs"],
6
+ "args": ["REPLACE/WITH/ABSOLUTE/PATH/trantor/mcp.mjs"],
7
7
  "env": { "RELAY_URL": "http://127.0.0.1:4477", "RELAY_SESSION": "gemini:myproject" }
8
8
  }
9
9
  }
package/deploy/setup.sh CHANGED
@@ -16,10 +16,10 @@ if [ "$(uname)" = "Darwin" ]; then
16
16
  else
17
17
  echo "Linux: run the hub under systemd/tmux: RELAY_PORT=4477 node $REPO/hub.mjs"
18
18
  fi
19
- # the economics engine — part of Trantor, installed automatically (it IS the brain)
20
- if ! command -v scrooge >/dev/null 2>&1 && [ ! -x "$HOME/.local/bin/scrooge" ]; then
19
+ # the economics engine — vendored in engine/, installed automatically (it IS the brain)
20
+ if [ -f "$REPO/engine/install.sh" ]; then
21
21
  echo "▸ installing the economics engine (routing + cost ledger)…"
22
- curl -fsSL https://raw.githubusercontent.com/sashabogi/token-scrooge/main/install.sh | bash \
22
+ bash "$REPO/engine/install.sh" >/dev/null 2>&1 \
23
23
  && echo "✓ economics engine installed" \
24
24
  || echo " (engine install failed — Trantor still works; the Advisor runs without live pricing. Retry: trantor setup)"
25
25
  case ":$PATH:" in *":$HOME/.local/bin:"*) ;; *) echo " note: add ~/.local/bin to your PATH";; esac
@@ -28,4 +28,5 @@ node "$REPO/bin/connect.mjs"
28
28
  echo
29
29
  node "$REPO/bin/doctor.mjs" || true
30
30
  echo
31
- echo "Next: claude plugin marketplace add sashabogi/trantor && claude plugin install agent-bus"
31
+ echo "Next: claude plugin marketplace add sashabogi/trantor && claude plugin install trantor"
32
+ echo "Then: open Claude Code in any project and say \"fire up the crew\""
package/engine/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 sashabogi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,5 @@
1
+ # The Trantor economics engine
2
+ Capability-weighted cheap-model routing, the cost ledger, and per-model lessons.
3
+ Formerly the standalone `token-scrooge` (now archived); this directory is the canonical home.
4
+ Installed automatically by `trantor setup` (symlinks `engine/bin/*` into `~/.local/bin`).
5
+ Self-contained python3 (stdlib only). Data lives in `~/.token-scrooge/` (kept for compatibility).