trantor 0.17.61 → 0.17.62
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/plugin.json +1 -1
- package/README.md +6 -1
- package/bin/app.mjs +93 -0
- package/bin/cli.mjs +3 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "trantor",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.62",
|
|
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
|
@@ -51,7 +51,7 @@ heartbeats, inbox delivery, handoff/baton pass, sub-agent cards):
|
|
|
51
51
|
"relay": {
|
|
52
52
|
"command": "node",
|
|
53
53
|
"args": ["<absolute-path-to-trantor>/mcp.mjs"],
|
|
54
|
-
"env": { "RELAY_URL": "http://127.0.0.1:4477", "RELAY_AGENT": "kimi" },
|
|
54
|
+
"env": { "RELAY_URL": "http://127.0.0.1:4477", "RELAY_AGENT": "kimi-orch" },
|
|
55
55
|
"startupTimeoutMs": 15000,
|
|
56
56
|
"toolTimeoutMs": 150000
|
|
57
57
|
}
|
|
@@ -68,6 +68,11 @@ runs your live checkout, so the relay server itself never goes stale. Invoke the
|
|
|
68
68
|
`/skill:crew`, `/skill:handoff`, `/skill:research`. Set `TRANTOR_DEBUG_HOOKS=1` on the `kimi`
|
|
69
69
|
process to dump raw hook payloads to `~/.agent-bus/kimi-hook-debug.jsonl`.
|
|
70
70
|
|
|
71
|
+
The orchestrator's bus identity is `kimi-orch:<project>` — deliberately distinct from `kimi:<project>`,
|
|
72
|
+
which belongs to a kimi CREW SEAT (`trantor up kimi`). Same doctrine as the openrouter seat label:
|
|
73
|
+
one bus peer per role, so an orchestrator and its own kimi seat never share a heartbeat, inbox, or
|
|
74
|
+
card attribution.
|
|
75
|
+
|
|
71
76
|
That's it. (Prefer source? `git clone https://github.com/sashabogi/trantor && cd trantor &&
|
|
72
77
|
npm install && bash deploy/setup.sh` — identical result.)
|
|
73
78
|
|
package/bin/app.mjs
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// trantor app — install/update the Trantor DESKTOP APP (Tauri) from GitHub Releases.
|
|
3
|
+
//
|
|
4
|
+
// The npm package deliberately does NOT ship desktop/ (a 6MB DMG has no business in node_modules);
|
|
5
|
+
// the app travels as a GitHub Release asset instead. This command is the whole distribution story
|
|
6
|
+
// for a teammate: `npm i -g trantor && trantor app install` → latest DMG lands in /Applications.
|
|
7
|
+
//
|
|
8
|
+
// trantor app status: installed version vs latest release
|
|
9
|
+
// trantor app install download the latest release DMG and install to /Applications
|
|
10
|
+
// trantor app update same as install (re-pulls whatever is latest)
|
|
11
|
+
//
|
|
12
|
+
// Release side (maintainer): build the DMG (cd desktop && npm run tauri build), then
|
|
13
|
+
// gh release create app-v<ver> desktop/src-tauri/target/release/bundle/dmg/Trantor_<ver>_aarch64.dmg
|
|
14
|
+
// Any release whose assets include a Trantor_*.dmg is an app release; the newest one wins, so app
|
|
15
|
+
// releases interleave freely with code (npm) releases.
|
|
16
|
+
import { execFileSync } from "node:child_process";
|
|
17
|
+
import { createWriteStream, existsSync, rmSync } from "node:fs";
|
|
18
|
+
import { Readable } from "node:stream";
|
|
19
|
+
import { pipeline } from "node:stream/promises";
|
|
20
|
+
import { join } from "node:path";
|
|
21
|
+
import { tmpdir } from "node:os";
|
|
22
|
+
|
|
23
|
+
const REPO = "sashabogi/trantor";
|
|
24
|
+
const APP = "/Applications/Trantor.app";
|
|
25
|
+
const ARCH_TAG = process.arch === "arm64" ? "aarch64" : "x64";
|
|
26
|
+
const cmd = process.argv[2] || "status";
|
|
27
|
+
|
|
28
|
+
if (process.platform !== "darwin") { console.error("trantor app: the desktop app is macOS-only for now"); process.exit(1); }
|
|
29
|
+
if (!["status", "install", "update"].includes(cmd)) {
|
|
30
|
+
console.error("usage: trantor app [status|install|update]"); process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function sh(file, args) { return execFileSync(file, args, { encoding: "utf8" }); }
|
|
34
|
+
|
|
35
|
+
function installedVersion() {
|
|
36
|
+
try { return sh("plutil", ["-extract", "CFBundleShortVersionString", "raw", join(APP, "Contents/Info.plist")]).trim(); }
|
|
37
|
+
catch { return ""; }
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Newest release carrying a Trantor DMG for this arch (falls back to any Trantor DMG — old
|
|
41
|
+
// releases may predate multi-arch naming). GITHUB_TOKEN is honored but not required (public repo).
|
|
42
|
+
async function latestAppRelease() {
|
|
43
|
+
const headers = { accept: "application/vnd.github+json", "user-agent": "trantor-app" };
|
|
44
|
+
if (process.env.GITHUB_TOKEN) headers.authorization = `Bearer ${process.env.GITHUB_TOKEN}`;
|
|
45
|
+
const r = await fetch(`https://api.github.com/repos/${REPO}/releases?per_page=30`, { headers, signal: AbortSignal.timeout(15000) });
|
|
46
|
+
if (!r.ok) throw new Error(`GitHub API ${r.status} — ${(await r.text()).slice(0, 200)}`);
|
|
47
|
+
const isDmg = a => /^Trantor[_-].*\.dmg$/.test(a.name);
|
|
48
|
+
for (const rel of await r.json()) {
|
|
49
|
+
const assets = (rel.assets || []).filter(isDmg);
|
|
50
|
+
if (!assets.length) continue;
|
|
51
|
+
const asset = assets.find(a => a.name.includes(`_${ARCH_TAG}`)) || assets[0];
|
|
52
|
+
if (!asset.name.includes(`_${ARCH_TAG}`)) console.error(`⚠ no ${ARCH_TAG} build in ${rel.tag_name} — using ${asset.name} (may not run on this Mac)`);
|
|
53
|
+
const version = (asset.name.match(/[_-]([0-9]+(?:\.[0-9]+)*)[_-]/) || [])[1] || rel.tag_name.replace(/^app-v?|^v/, "");
|
|
54
|
+
return { tag: rel.tag_name, version, asset };
|
|
55
|
+
}
|
|
56
|
+
throw new Error("no release with a Trantor DMG asset found");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const rel = await latestAppRelease().catch(e => { console.error(`trantor app: ${e.message}`); process.exit(1); });
|
|
60
|
+
const have = installedVersion();
|
|
61
|
+
|
|
62
|
+
if (cmd === "status") {
|
|
63
|
+
console.log(`installed: ${have ? `${have} (${APP})` : "not installed"}`);
|
|
64
|
+
console.log(`latest: ${rel.version} (${rel.tag} · ${rel.asset.name})`);
|
|
65
|
+
console.log(have === rel.version ? "up to date." : `run \`trantor app install\` to get ${rel.version}.`);
|
|
66
|
+
process.exit(0);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
console.log(`↓ ${rel.asset.name} (${(rel.asset.size / 1e6).toFixed(1)}MB) from ${rel.tag}…`);
|
|
70
|
+
const dmg = join(tmpdir(), rel.asset.name);
|
|
71
|
+
const dl = await fetch(rel.asset.browser_download_url, { headers: { "user-agent": "trantor-app" }, signal: AbortSignal.timeout(300000) });
|
|
72
|
+
if (!dl.ok || !dl.body) { console.error(`download failed: HTTP ${dl.status}`); process.exit(1); }
|
|
73
|
+
await pipeline(Readable.fromWeb(dl.body), createWriteStream(dmg));
|
|
74
|
+
|
|
75
|
+
let mount = "";
|
|
76
|
+
try {
|
|
77
|
+
// -nobrowse keeps the volume out of Finder; mount point is the last tab-field of the last line.
|
|
78
|
+
const out = sh("hdiutil", ["attach", "-nobrowse", "-readonly", dmg]);
|
|
79
|
+
mount = (out.trim().split("\n").pop() || "").split("\t").pop().trim();
|
|
80
|
+
const src = join(mount, "Trantor.app");
|
|
81
|
+
if (!mount.startsWith("/Volumes/") || !existsSync(src)) throw new Error(`unexpected DMG layout (mount: ${mount || "none"})`);
|
|
82
|
+
if (existsSync(APP)) { console.log(`replacing ${APP} (was ${have || "unknown"})`); rmSync(APP, { recursive: true, force: true }); }
|
|
83
|
+
sh("ditto", [src, APP]);
|
|
84
|
+
// The download carries quarantine; the user explicitly asked for this install — clear it so
|
|
85
|
+
// Gatekeeper doesn't refuse the unsigned build on first launch.
|
|
86
|
+
try { sh("xattr", ["-dr", "com.apple.quarantine", APP]); } catch {}
|
|
87
|
+
console.log(`✓ Trantor.app ${installedVersion() || rel.version} installed → ${APP}`);
|
|
88
|
+
} catch (e) {
|
|
89
|
+
console.error(`install failed: ${e.message}`); process.exitCode = 1;
|
|
90
|
+
} finally {
|
|
91
|
+
if (mount) try { sh("hdiutil", ["detach", mount, "-quiet"]); } catch {}
|
|
92
|
+
try { rmSync(dmg, { force: true }); } catch {}
|
|
93
|
+
}
|
package/bin/cli.mjs
CHANGED
|
@@ -72,6 +72,7 @@ switch (cmd) {
|
|
|
72
72
|
case "policy": run("bin/policy.mjs"); break;
|
|
73
73
|
case "inbox": run("bin/inbox.mjs"); break;
|
|
74
74
|
case "duty": run("bin/duty.mjs"); break;
|
|
75
|
+
case "app": run("bin/app.mjs"); break;
|
|
75
76
|
case "identity": {
|
|
76
77
|
const { load, publicView, generate, keyPath } = await import(join(ROOT, "lib/identity.mjs"));
|
|
77
78
|
const sub = args[0], name = args[1] || "human";
|
|
@@ -153,7 +154,9 @@ switch (cmd) {
|
|
|
153
154
|
trantor models browse live models behind each seat + the router's pick per difficulty
|
|
154
155
|
trantor up … spawn a crew here: trantor up codex kimi deepseek:deepseek glm:zai-coding-plan
|
|
155
156
|
trantor down tear the crew down (kills processes, closes windows, no dialogs)
|
|
157
|
+
trantor prune drop dead crew-window tracking rows (ghost workspaces/panes) without spawning anything
|
|
156
158
|
trantor ui open the live dashboard (board + flow views)
|
|
159
|
+
trantor app the DESKTOP app: status | install | update — pulls the latest DMG from GitHub Releases
|
|
157
160
|
trantor catchup "where are we?" — the continuous board + git, with a synthesized brief
|
|
158
161
|
trantor agents what this session's sub-agents did (task · returned? · files written · survived on disk) — [<sessionId>] [--json]
|
|
159
162
|
trantor gates verification gates: "must verify before shipping" claims that survive handoffs — [--all] [--json]
|