trantor 0.17.43 → 0.17.45
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.
- package/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +3 -3
- package/bin/advise.mjs +64 -11
- package/bin/cli.mjs +1 -1
- package/bin/crew-runner.mjs +6 -0
- package/bin/crew.sh +4 -1
- package/bin/doctor.mjs +4 -0
- package/package.json +1 -1
- package/skills/crew/SKILL.md +30 -4
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"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, …)",
|
|
9
|
-
"version": "0.17.
|
|
9
|
+
"version": "0.17.45"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "trantor",
|
|
14
14
|
"source": "./",
|
|
15
|
-
"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,
|
|
16
|
-
"version": "0.17.
|
|
15
|
+
"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, GLM, 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.",
|
|
16
|
+
"version": "0.17.45",
|
|
17
17
|
"author": {
|
|
18
18
|
"name": "Sasha Bogojevic"
|
|
19
19
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "trantor",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.45",
|
|
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/README.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
### The hub-world for AI agent crews.
|
|
13
13
|
|
|
14
14
|
**One Advisor decides how your work runs — solo, cheap inline calls, or a live crew of
|
|
15
|
-
Claude Code, Codex,
|
|
15
|
+
Claude Code, Codex, GLM, Kimi & DeepSeek in their own terminal windows — routed by your
|
|
16
16
|
actual plans, supervised on a live + historical board you can scroll back through, learning
|
|
17
17
|
from every failure.**
|
|
18
18
|
|
|
@@ -134,7 +134,7 @@ project takes over with a full window (and a PreCompact hook does this automatic
|
|
|
134
134
|
(`solo | scrooge | crew | hybrid`), a routing table with a **reason per package**, why
|
|
135
135
|
that many seats ("seats follow the work, not the install list"), and a real-money estimate
|
|
136
136
|
with quota-pool accounting. You say go.
|
|
137
|
-
2. **Windows open.** `trantor up codex
|
|
137
|
+
2. **Windows open.** `trantor up codex kimi deepseek:deepseek opencode:zai-coding-plan` spawns one titled
|
|
138
138
|
terminal window per agent. `agent:model` pins a model; `agent:provider --difficulty hard`
|
|
139
139
|
picks the **best live model** for the work at spawn (capability × cost), enumerated from the
|
|
140
140
|
CLI itself — never a guessed endpoint. **Serialized and then verified on the bus** — the
|
|
@@ -194,7 +194,7 @@ Trantor's economics engine ([Scrooge](https://github.com/sashabogi/token-scrooge
|
|
|
194
194
|
automatically by `trantor setup`) knows model capabilities, per-1M costs, and keeps the
|
|
195
195
|
ledger; Trantor turns that into decisions:
|
|
196
196
|
|
|
197
|
-
- **Declare your plans once:** `trantor profile set claude=max codex=plus
|
|
197
|
+
- **Declare your plans once:** `trantor profile set claude=max codex=plus zai=coding-plan kimi=coding-plan deepseek=api`
|
|
198
198
|
- The Advisor routes by **your economics**: API-billed orchestrator → offload everything;
|
|
199
199
|
$20-tier plan → the crew *is* the only way a real build fits; max-tier → context horizon
|
|
200
200
|
decides. **Quota pooling**: one build spread across your separate subscription buckets —
|
package/bin/advise.mjs
CHANGED
|
@@ -19,12 +19,51 @@ import { pathToFileURL } from "node:url";
|
|
|
19
19
|
const H = homedir();
|
|
20
20
|
const read = (p, fb) => { try { return JSON.parse(readFileSync(p, "utf8")); } catch { return fb; } };
|
|
21
21
|
|
|
22
|
+
// ---- canonical crew roster (single source of truth, mirrors bin/doctor.mjs) ----
|
|
23
|
+
// Each token maps to: the CLI binary that must exist · the `trantor up` LAUNCH spec the
|
|
24
|
+
// orchestrator runs · the bus SESSION name (= spec's agent part) · the profile PROVIDER
|
|
25
|
+
// key that gates the seat and supplies the tier.
|
|
26
|
+
//
|
|
27
|
+
// GEMINI is deliberately ABSENT: Google retired the free Gemini CLI seat (2026-06-18), so
|
|
28
|
+
// even though the `gemini` binary is usually still on PATH, `gemini --yolo` crashes (exit 1)
|
|
29
|
+
// for everyone without a paid enterprise key. Its replacement seat is GLM via opencode.
|
|
30
|
+
// (Gemini still works as a Scrooge cheap-model via GEMINI_API_KEY — a separate path.) A
|
|
31
|
+
// paid-key holder can still force it with an explicit `trantor up gemini`; we just never
|
|
32
|
+
// auto-recommend a dead seat.
|
|
33
|
+
export const ROSTER = {
|
|
34
|
+
codex: { cli: "codex", launch: "codex", session: "codex", provider: "codex" },
|
|
35
|
+
kimi: { cli: "kimi", launch: "kimi", session: "kimi", provider: "kimi" },
|
|
36
|
+
deepseek: { cli: "opencode", launch: "deepseek:deepseek", session: "deepseek", provider: "deepseek" },
|
|
37
|
+
glm: { cli: "opencode", launch: "opencode:zai-coding-plan", session: "opencode", provider: "zai" },
|
|
38
|
+
// OpenRouter = the BYOM on-ramp: one key fronts hundreds of models (incl. vendors with no
|
|
39
|
+
// CLI of their own). Rides the opencode runner like glm/deepseek, but under its OWN bus label
|
|
40
|
+
// `openrouter` (distinct session, never collides with the glm `opencode` seat). The launcher
|
|
41
|
+
// live-selects the best OpenRouter model for the work's difficulty (or pin one:
|
|
42
|
+
// `openrouter:openrouter/<vendor>/<model>`). The model picked is what determines its strength,
|
|
43
|
+
// so it sits LAST in every CREW_PREF tier — a wildcard that fills once the proven native seats
|
|
44
|
+
// are taken, and the ONLY seat for a user who brought nothing but an OpenRouter key.
|
|
45
|
+
openrouter: { cli: "opencode", launch: "openrouter:openrouter", session: "openrouter", provider: "openrouter" },
|
|
46
|
+
};
|
|
47
|
+
|
|
22
48
|
export function loadWorld() {
|
|
23
49
|
const profile = read(join(H, ".agent-bus", "profile.json"), { providers: {} });
|
|
24
50
|
const registry = read(join(H, ".token-scrooge", "registry.json"), { models: {}, tasks: {} });
|
|
25
51
|
const caps = read(join(H, ".token-scrooge", "capabilities.json"), {});
|
|
26
52
|
const has = (c) => { try { execSync(`command -v ${c}`, { stdio: "ignore", shell: "/bin/sh" }); return true; } catch { return false; } };
|
|
27
|
-
const
|
|
53
|
+
const opencodeKey = (prov) => !!read(join(H, ".config", "opencode", "opencode.json"), {})?.provider?.[prov]?.options?.apiKey;
|
|
54
|
+
// a key the user already has for Scrooge counts too — the opencode runner sources these .env
|
|
55
|
+
// files, so OPENROUTER_API_KEY in ~/.token-scrooge/.env lights up the crew seat with no extra setup.
|
|
56
|
+
const envHasKey = (k) => !!process.env[k] || [join(H, ".token-scrooge", ".env"), join(H, ".agent-bus", ".env")]
|
|
57
|
+
.some(f => { try { return readFileSync(f, "utf8").includes(k); } catch { return false; } });
|
|
58
|
+
// a seat is available only if its CLI exists AND its provider is actually set up — a present
|
|
59
|
+
// binary with a dead/missing seat (gemini, or opencode with no provider key) must NOT be recommended.
|
|
60
|
+
const hasSeat = (tok) => {
|
|
61
|
+
const r = ROSTER[tok]; if (!r || !has(r.cli)) return false;
|
|
62
|
+
if (tok === "glm") return !!profile?.providers?.zai || opencodeKey("zai-coding-plan");
|
|
63
|
+
if (tok === "openrouter") return !!profile?.providers?.openrouter || opencodeKey("openrouter") || envHasKey("OPENROUTER_API_KEY");
|
|
64
|
+
return true;
|
|
65
|
+
};
|
|
66
|
+
const agents = Object.keys(ROSTER).filter(hasSeat);
|
|
28
67
|
return { profile, registry, caps, agents, scrooge: has("scrooge") };
|
|
29
68
|
}
|
|
30
69
|
|
|
@@ -42,8 +81,9 @@ export function scroogeModelFor(registry, caps, kind = "code", difficulty = "eas
|
|
|
42
81
|
|
|
43
82
|
// crude per-package token forecast (input+output through the executor)
|
|
44
83
|
const FORECAST = { easy: 0.3e6, medium: 1.5e6, hard: 6e6 }; // tokens
|
|
45
|
-
// crew agent preference per difficulty: frontier subs take hard, cheap takes easy
|
|
46
|
-
|
|
84
|
+
// crew agent preference per difficulty: frontier subs take hard, cheap takes easy.
|
|
85
|
+
// (gemini retired → its slot goes to glm, a strong coding-plan seat on $0 marginal quota.)
|
|
86
|
+
const CREW_PREF = { hard: ["codex", "glm", "kimi", "deepseek", "openrouter"], medium: ["kimi", "glm", "codex", "deepseek", "openrouter"], easy: ["deepseek", "kimi", "glm", "codex", "openrouter"] };
|
|
47
87
|
|
|
48
88
|
export function advise(input, world = loadWorld()) {
|
|
49
89
|
const { profile, registry, caps, agents, scrooge } = world;
|
|
@@ -82,19 +122,23 @@ export function advise(input, world = loadWorld()) {
|
|
|
82
122
|
if (p.owner === "self") return { ...p, executor: "orchestrator", pool: tierOf(profile, "claude"), reason: "architect-owned (foundation/integration doctrine) — the orchestrator keeps the shared contract in its own hands" };
|
|
83
123
|
if (mode === "solo") return { ...p, executor: "orchestrator", pool: tierOf(profile, "claude"), reason: "small enough to do inline" };
|
|
84
124
|
const pref = CREW_PREF[p.difficulty].filter(a => agents.includes(a));
|
|
85
|
-
const agent = pref.sort((a, b) => (used[a] || 0) - (used[b] || 0))[0] || "deepseek";
|
|
125
|
+
const agent = pref.sort((a, b) => (used[a] || 0) - (used[b] || 0))[0] || agents[0] || "deepseek";
|
|
86
126
|
used[agent] = (used[agent] || 0) + 1;
|
|
87
|
-
const pool = tierOf(profile, agent
|
|
127
|
+
const pool = tierOf(profile, ROSTER[agent]?.provider || agent);
|
|
88
128
|
let est = null;
|
|
89
129
|
if (pool === "api") { // deepseek API etc — estimate real $ via registry
|
|
90
130
|
const m = registry.models?.["deepseek-v4-flash"] || { cost_in: 0.14, cost_out: 0.28 };
|
|
91
131
|
est = +((FORECAST[p.difficulty] * 0.85 * m.cost_in + FORECAST[p.difficulty] * 0.15 * m.cost_out) / 1e6).toFixed(2);
|
|
92
132
|
}
|
|
93
|
-
|
|
133
|
+
let why_r = p.difficulty === "hard"
|
|
94
134
|
? `hard → strongest available coder (${agent}); its ${pool} pool means ${pool === "api" ? "real $ but cheapest capable" : "$0 marginal on existing quota"}`
|
|
95
135
|
: p.difficulty === "medium"
|
|
96
136
|
? `medium → solid mid-tier (${agent}) keeps frontier seats free for hard work; ${pool === "api" ? "metered" : "quota"} pool`
|
|
97
137
|
: `easy → cheapest seat (${agent})`;
|
|
138
|
+
// OpenRouter live-select ranks by COST only (the 335-model catalog has no capability scores
|
|
139
|
+
// yet — that's the capability-ingestion follow-up), so for HARD work it can land a cheap model.
|
|
140
|
+
// Flag it: pin a strong model explicitly (openrouter:openrouter/<vendor>/<model>) for hard work.
|
|
141
|
+
if (agent === "openrouter" && p.difficulty === "hard") why_r += ` — ⚠️ live-select ranks by cost; PIN a strong model (e.g. openrouter:openrouter/anthropic/claude-opus-latest) for hard work until capability data lands`;
|
|
98
142
|
return { ...p, executor: agent, pool, est_cost_usd: est, reason: why_r };
|
|
99
143
|
});
|
|
100
144
|
// crew-size rationale: seats are EMERGENT from the work, and we say so
|
|
@@ -120,17 +164,26 @@ export function advise(input, world = loadWorld()) {
|
|
|
120
164
|
// creation order — the architect substitutes real ids as it creates them.)
|
|
121
165
|
const selfPkgs = routing.filter(r => r.executor === "orchestrator");
|
|
122
166
|
const foundationIdx = selfPkgs.length ? [1] : [];
|
|
123
|
-
const cards = routing.map((r, i) =>
|
|
167
|
+
const cards = routing.map((r, i) => {
|
|
168
|
+
const seat = ROSTER[r.executor];
|
|
169
|
+
return {
|
|
124
170
|
order: i + 1, title: r.title, difficulty: r.difficulty,
|
|
125
|
-
|
|
126
|
-
//
|
|
127
|
-
|
|
171
|
+
// bus identity = the runner's session name (spec's agent part) — glm rides the `opencode`
|
|
172
|
+
// runner so its session/assignee is `opencode:<project>`, NOT `glm:<project>`.
|
|
173
|
+
assignee: r.executor === "scrooge" || r.executor === "orchestrator" ? undefined : `${seat?.session || r.executor}:<project>`,
|
|
174
|
+
// launch = the EXACT `trantor up` spec to spawn this seat; the orchestrator runs
|
|
175
|
+
// `trantor up <launch> --task <task> --difficulty <difficulty>`. Carrying it explicitly is
|
|
176
|
+
// what teaches the orchestrator the GLM path (`opencode:zai-coding-plan`) instead of guessing.
|
|
177
|
+
launch: ["scrooge", "orchestrator"].includes(r.executor) ? undefined : (seat?.launch || r.executor),
|
|
178
|
+
// "auto" = resolve a LIVE model at spawn (the launch spec already pins the provider; the
|
|
179
|
+
// runner picks the best live model for it). Was `<cli>-default` — a stale default.
|
|
128
180
|
model: r.model || (["scrooge", "orchestrator"].includes(r.executor) ? undefined : "auto"),
|
|
129
181
|
task: ["scrooge", "orchestrator"].includes(r.executor) ? undefined : r.kind,
|
|
130
182
|
via: r.executor === "scrooge" ? "relay_scrooge" : "relay_task_add",
|
|
131
183
|
deps_orders: r.executor === "orchestrator" && /integrat/i.test(r.title)
|
|
132
184
|
? routing.map((x, j) => j + 1).filter(j => j !== i + 1)
|
|
133
|
-
: (r.executor !== "orchestrator" ? foundationIdx.filter(f => f !== i + 1) : []) }
|
|
185
|
+
: (r.executor !== "orchestrator" ? foundationIdx.filter(f => f !== i + 1) : []) };
|
|
186
|
+
});
|
|
134
187
|
return { mode, why, crew, routing, routing_table_md: table, card_args: cards, est_api_cost_usd: apiCost, quota_pools: pools, summary, orchestrator_tier: orchTier, agents_available: agents };
|
|
135
188
|
}
|
|
136
189
|
|
package/bin/cli.mjs
CHANGED
|
@@ -49,7 +49,7 @@ switch (cmd) {
|
|
|
49
49
|
trantor doctor where do I stand? hub/plugin/CLIs/auth/keys/profile, with copy-paste fixes
|
|
50
50
|
trantor connect (re)wire every installed AI CLI to the bus
|
|
51
51
|
trantor profile declare your plans: trantor profile set claude=max codex=plus deepseek=api
|
|
52
|
-
trantor up … spawn a crew here: trantor up codex
|
|
52
|
+
trantor up … spawn a crew here: trantor up codex kimi deepseek:deepseek opencode:zai-coding-plan
|
|
53
53
|
trantor down tear the crew down (kills processes, closes windows, no dialogs)
|
|
54
54
|
trantor ui open the live dashboard (board + flow views)
|
|
55
55
|
trantor catchup "where are we?" — the continuous board + git, with a synthesized brief
|
package/bin/crew-runner.mjs
CHANGED
|
@@ -69,6 +69,12 @@ const CLI = {
|
|
|
69
69
|
next: `opencode run -c{M} "$(cat {P})"`, mflag: " -m ", env: join(homedir(), ".token-scrooge", ".env") },
|
|
70
70
|
opencode: { first: `opencode run{M} "$(cat {P})"`,
|
|
71
71
|
next: `opencode run -c{M} "$(cat {P})"`, mflag: " -m ", env: join(homedir(), ".token-scrooge", ".env") },
|
|
72
|
+
// OpenRouter rides the opencode CLI exactly like deepseek/glm, but under its OWN agent label so
|
|
73
|
+
// its bus identity is `openrouter:<project>` (RELAY_AGENT is set per-spawn) — never colliding with
|
|
74
|
+
// the glm `opencode` seat. Model ids come pre-qualified (`openrouter/<vendor>/<model>`). Sources
|
|
75
|
+
// the token-scrooge .env so an existing OPENROUTER_API_KEY authenticates with no extra wiring.
|
|
76
|
+
openrouter: { first: `opencode run{M} "$(cat {P})"`,
|
|
77
|
+
next: `opencode run -c{M} "$(cat {P})"`, mflag: " -m ", env: join(homedir(), ".token-scrooge", ".env") },
|
|
72
78
|
claude: { first: `claude{M} -p "$(cat {P})" --dangerously-skip-permissions`,
|
|
73
79
|
next: `claude -c{M} -p "$(cat {P})" --dangerously-skip-permissions`, mflag: " --model " },
|
|
74
80
|
};
|
package/bin/crew.sh
CHANGED
|
@@ -75,7 +75,7 @@ SCROOGE="$BUS_DIR/engine/bin/scrooge"
|
|
|
75
75
|
resolve_model() {
|
|
76
76
|
local agent="$1" provider="$2" task="$3" diff="$4" cands="" out=""
|
|
77
77
|
case "$agent" in
|
|
78
|
-
opencode|deepseek)
|
|
78
|
+
opencode|deepseek|openrouter)
|
|
79
79
|
cands="$(opencode models "$provider" 2>/dev/null | tr '\n' ' ')"
|
|
80
80
|
[ -n "$cands" ] || { echo "[crew] no live models via 'opencode models $provider' — CLI default" >&2; return 0; }
|
|
81
81
|
out="$(python3 "$SCROOGE" route --candidates "$cands" -t "$task" -d "$diff" --json 2>/dev/null)" ;;
|
|
@@ -133,6 +133,9 @@ spawn_grid() { # $@ = agents — (re)computes the grid for THIS batch and spawn
|
|
|
133
133
|
for SPEC in "$@"; do
|
|
134
134
|
AGENT="${SPEC%%:*}" # agent[:provider[/model]] — model rides in as CREW_MODEL
|
|
135
135
|
FIELD=""; [ "$SPEC" != "$AGENT" ] && FIELD="${SPEC#*:}"
|
|
136
|
+
# `trantor up openrouter` (no provider) → default the opencode provider to openrouter so it
|
|
137
|
+
# live-selects from the OpenRouter catalog instead of falling back to opencode's default model.
|
|
138
|
+
[ "$AGENT" = "openrouter" ] && [ -z "$FIELD" ] && FIELD="openrouter"
|
|
136
139
|
MODEL=""
|
|
137
140
|
if [ -n "$FIELD" ]; then
|
|
138
141
|
case "$FIELD" in
|
package/bin/doctor.mjs
CHANGED
|
@@ -61,6 +61,10 @@ const CLIS = [
|
|
|
61
61
|
{ name: "kimi", bin: "kimi", wired: () => !!read(join(H, ".kimi", "mcp.json"))?.mcpServers?.relay, auth: () => existsSync(join(H, ".kimi", "credentials")), login: "kimi → /login (Kimi account or Moonshot API key)" },
|
|
62
62
|
{ name: "deepseek (via opencode)", bin: "opencode", wired: () => !!read(join(H, ".config", "opencode", "opencode.json"))?.mcp?.relay, auth: () => !!process.env.DEEPSEEK_API_KEY || (existsSync(join(H, ".agent-bus", ".env")) && readFileSync(join(H, ".agent-bus", ".env"), "utf8").includes("DEEPSEEK_API_KEY")) || !!read(join(H, ".local", "share", "opencode", "auth.json")), login: `get a key at platform.deepseek.com, then: echo 'DEEPSEEK_API_KEY=sk-…' >> ~/.agent-bus/.env` },
|
|
63
63
|
{ name: "glm (via opencode · coding plan)", bin: "opencode", wired: () => !!read(join(H, ".config", "opencode", "opencode.json"))?.mcp?.relay, auth: () => !!read(join(H, ".config", "opencode", "opencode.json"))?.provider?.["zai-coding-plan"]?.options?.apiKey, login: `put your Z.ai coding-plan key at ~/.config/opencode/opencode.json → provider["zai-coding-plan"].options.apiKey, then seat: trantor up opencode:zai-coding-plan/glm-5.1` },
|
|
64
|
+
// OpenRouter — the BYOM on-ramp: ONE key fronts hundreds of models. Rides opencode; the same
|
|
65
|
+
// OPENROUTER_API_KEY Scrooge already uses authenticates the crew seat (the runner sources the
|
|
66
|
+
// .env files). Available the moment the key exists in env/opencode + declared `openrouter=api`.
|
|
67
|
+
{ name: "openrouter (via opencode · BYOM, hundreds of models)", bin: "opencode", wired: () => !!read(join(H, ".config", "opencode", "opencode.json"))?.mcp?.relay, auth: () => !!process.env.OPENROUTER_API_KEY || !!read(join(H, ".config", "opencode", "opencode.json"))?.provider?.openrouter?.options?.apiKey || [join(H, ".token-scrooge", ".env"), join(H, ".agent-bus", ".env")].some(f => { try { return readFileSync(f, "utf8").includes("OPENROUTER_API_KEY"); } catch { return false; } }), login: `get a key at openrouter.ai/keys, then: echo 'OPENROUTER_API_KEY=sk-or-…' >> ~/.agent-bus/.env && trantor profile set openrouter=api. Seat: trantor up openrouter (live-selects) or pin trantor up openrouter:openrouter/<vendor>/<model>` },
|
|
64
68
|
];
|
|
65
69
|
let installed = 0;
|
|
66
70
|
for (const c of CLIS) {
|
package/package.json
CHANGED
package/skills/crew/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: crew
|
|
3
|
-
description: Orchestrate a multi-agent build with Trantor — get an Advisor recommendation (solo/scrooge/crew/hybrid based on the user's plans and the work), fire up helper AI CLIs (Codex,
|
|
3
|
+
description: Orchestrate a multi-agent build with Trantor — get an Advisor recommendation (solo/scrooge/crew/hybrid based on the user's plans and the work), fire up helper AI CLIs (Codex, GLM, Kimi, DeepSeek) with pinned models in visible terminal windows, assign difficulty-tagged work over the bus, track it on the Kanban dashboard with a testing gate, delegate grunt to Scrooge, supervise actively, integrate, ship. Use when the user wants several AI agents building something together, says "fire up the crew/agents", "build it with trantor / with the crew", or asks to coordinate other coding CLIs on a task.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Trantor crew — the unified playbook (brain × body)
|
|
@@ -39,12 +39,38 @@ explicit EVENT/INTERFACE CONTRACT — cross-agent bugs come from contract drift.
|
|
|
39
39
|
3. Open the dashboard: `trantor ui` (or `open -na "Google Chrome" --args --new-window <hub-url>`)
|
|
40
40
|
|
|
41
41
|
## Phase 2 — fire up the crew (with the Advisor's models)
|
|
42
|
-
`
|
|
43
|
-
|
|
42
|
+
**Each crew card from `relay_advise` carries a `launch` spec — run it VERBATIM; never invent a
|
|
43
|
+
CLI invocation or run an agent "in a terminal" yourself.** Spawn every seat in one call:
|
|
44
|
+
`trantor up <launch> <launch> … --task <kind> --difficulty <diff>`. The live roster + the
|
|
45
|
+
EXACT launch spec per provider (do not improvise these):
|
|
46
|
+
|
|
47
|
+
| seat | launch spec | notes |
|
|
48
|
+
|---|---|---|
|
|
49
|
+
| Codex | `codex` (or `codex:gpt-5.5` to pin) | OpenAI CLI |
|
|
50
|
+
| Kimi | `kimi` | Moonshot coding-plan |
|
|
51
|
+
| DeepSeek | `deepseek:deepseek` | runs via opencode; `deepseek` alone = CLI default |
|
|
52
|
+
| **GLM (Z.ai)** | **`opencode:zai-coding-plan`** | **runs via opencode, NOT a bare `glm`/`zai` terminal command.** `opencode:zai-coding-plan/glm-5.2` pins a model; `opencode:zai-coding-plan` live-selects. |
|
|
53
|
+
| **OpenRouter (BYOM)** | **`openrouter`** | **the bring-your-own-model on-ramp — one key fronts hundreds of vendors (incl. ones with no CLI).** Bare `openrouter` live-selects the best OpenRouter model for the difficulty; pin one with `openrouter:openrouter/<vendor>/<model>`. Its own bus identity `openrouter:<project>` (never collides with the GLM `opencode` seat). |
|
|
54
|
+
|
|
55
|
+
`agent:provider` live-selects the best model now; `agent:provider/model` pins one. Example:
|
|
56
|
+
`trantor up codex kimi deepseek:deepseek opencode:zai-coding-plan --task code --difficulty hard`.
|
|
57
|
+
**Whatever the advisor's `launch` field says, run that verbatim** — the roster above is the menu,
|
|
58
|
+
but the advisor already picked the right seats and specs for THIS work (a user who's only brought
|
|
59
|
+
an OpenRouter key, for instance, gets `openrouter` for everything; one who brought five providers
|
|
60
|
+
gets a load-balanced spread). New providers a user brings (OpenRouter today; any opencode-supported
|
|
61
|
+
vendor next) appear automatically once declared via `trantor profile set <name>=api` + a key.
|
|
62
|
+
|
|
63
|
+
⚠️ **Gemini CLI is RETIRED (Google killed the free seat 2026-06-18).** The advisor no longer
|
|
64
|
+
offers it and you must NOT fire up `gemini` — `gemini --yolo` exits 1 and crash-loops on the
|
|
65
|
+
bus. Its replacement seat is **GLM via `opencode:zai-coding-plan`**. (Gemini still serves as a
|
|
66
|
+
Scrooge cheap-model via `GEMINI_API_KEY` — that's a separate, working path, not a crew seat.)
|
|
67
|
+
Only a holder of a paid Gemini enterprise key should ever `trantor up gemini`.
|
|
68
|
+
|
|
44
69
|
(If `trantor` isn't on PATH, the same launcher is `bash <plugin-root>/bin/crew.sh up …`.)
|
|
45
70
|
The launcher auto-wires configs, spawns serialized runner windows, then **VERIFIES each agent
|
|
46
71
|
on the bus with one retry**. READ ITS OUTPUT: it ends "crew verified" or "✗✗ CREW INCOMPLETE"
|
|
47
|
-
naming no-shows. **Never assign work to an unverified agent.** The bus is the truth.
|
|
72
|
+
naming no-shows. **Never assign work to an unverified agent.** The bus is the truth. If a seat
|
|
73
|
+
fails to verify, run `trantor doctor` — it shows each CLI's wired/auth state and the exact fix.
|
|
48
74
|
|
|
49
75
|
## Phase 3 — contracts over the bus
|
|
50
76
|
Build the shared foundation yourself first, then `relay_send` each agent its contract
|