trantor 0.17.78 → 0.17.79
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.17.
|
|
3
|
+
"version": "0.17.79",
|
|
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
|
@@ -283,7 +283,8 @@ Crew output is gated mechanically, too: `bin/slop-gate.mjs` runs the vendored
|
|
|
283
283
|
[anti-slop](https://github.com/dmmulroy/anti-slop) Oxlint rules over an agent's **changed files
|
|
284
284
|
only** — unexplained type assertions, `unknown` laundering, runtime `typeof`, Reflect tricks and
|
|
285
285
|
friends fail the card before it can reach done, while legacy debt burns down on its own card
|
|
286
|
-
instead of blocking everyone.
|
|
286
|
+
instead of blocking everyone. A surface that has paid its debt off stays paid: `desktop/src` is at
|
|
287
|
+
zero and `npm test` now lints it in full (`node bin/slop-gate.mjs --surface desktop/src`).
|
|
287
288
|
|
|
288
289
|
## The brain — plan-aware economics
|
|
289
290
|
|
package/bin/models.mjs
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { execSync } from "node:child_process";
|
|
8
8
|
import { dirname, join } from "node:path";
|
|
9
9
|
import { homedir } from "node:os";
|
|
10
|
-
import { existsSync } from "node:fs";
|
|
10
|
+
import { existsSync, statSync } from "node:fs";
|
|
11
11
|
import { pathToFileURL, fileURLToPath } from "node:url";
|
|
12
12
|
import { buildRoster, loadWorld } from "./advise.mjs";
|
|
13
13
|
|
|
@@ -57,7 +57,10 @@ function detail(name) {
|
|
|
57
57
|
if (existsSync(SCROOGE) || has("scrooge")) {
|
|
58
58
|
console.log(`\n${C.gold}router picks (code task):${C.off}`);
|
|
59
59
|
for (const d of ["easy", "medium", "hard"]) console.log(` ${d.padEnd(7)} → ${routePick(models, d)}`);
|
|
60
|
-
|
|
60
|
+
const caps = join(H, ".token-scrooge", "capabilities.json");
|
|
61
|
+
// only nag when the scores are missing or older than the weekly refresh allows for
|
|
62
|
+
const ageDays = existsSync(caps) ? (Date.now() - statSync(caps).mtimeMs) / 86400e3 : Infinity;
|
|
63
|
+
if (ageDays > 9) console.log(`${C.dim}(scores ${ageDays === Infinity ? "missing" : `${Math.floor(ageDays)}d old`} — run scrooge-capabilities to (re)score the catalog for accurate difficulty routing)${C.off}`);
|
|
61
64
|
}
|
|
62
65
|
}
|
|
63
66
|
|
package/bin/slop-gate.mjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
// node bin/slop-gate.mjs # lint changed + untracked lintable files (the crew gate)
|
|
5
5
|
// node bin/slop-gate.mjs --all # lint the whole configured surface (advisory audit)
|
|
6
|
+
// node bin/slop-gate.mjs --surface desktop/src # lint ONE paid-off surface in full (hard gate in npm test)
|
|
6
7
|
//
|
|
7
8
|
// The rules are the vendored dmmulroy/anti-slop set (tools/oxlint/anti-slop — ours to tune):
|
|
8
9
|
// they mechanically reject low-evidence AI patterns — unexplained type assertions, unknown
|
|
@@ -13,6 +14,10 @@
|
|
|
13
14
|
import { execSync, spawnSync } from "node:child_process";
|
|
14
15
|
|
|
15
16
|
const ALL = process.argv.includes("--all");
|
|
17
|
+
// A surface that has burned its debt down to zero (desktop/src, #4798) is gated in FULL, not by
|
|
18
|
+
// diff: the whole point of paying it off is that it stays paid. npm test runs this.
|
|
19
|
+
const SURFACE_AT = process.argv.indexOf("--surface");
|
|
20
|
+
const SURFACE = SURFACE_AT > -1 ? process.argv[SURFACE_AT + 1] : null;
|
|
16
21
|
const LINTABLE = /\.(ts|tsx|mts|cts|js|jsx|mjs|cjs)$/;
|
|
17
22
|
|
|
18
23
|
function sh(cmd) {
|
|
@@ -21,7 +26,9 @@ function sh(cmd) {
|
|
|
21
26
|
}
|
|
22
27
|
|
|
23
28
|
let args;
|
|
24
|
-
if (
|
|
29
|
+
if (SURFACE) {
|
|
30
|
+
args = [SURFACE];
|
|
31
|
+
} else if (ALL) {
|
|
25
32
|
args = ["."];
|
|
26
33
|
} else {
|
|
27
34
|
const changed = sh("git diff --name-only HEAD");
|
|
@@ -40,9 +47,10 @@ const hits = out.split("\n").filter(l => /error\s+anti-slop\(/.test(l));
|
|
|
40
47
|
|
|
41
48
|
if (hits.length) {
|
|
42
49
|
console.log(hits.join("\n"));
|
|
43
|
-
|
|
50
|
+
const where = SURFACE ? `in ${SURFACE} (a zero-debt surface — keep it at zero)` : "in your changes";
|
|
51
|
+
console.log(`\nslop-gate: ${hits.length} anti-slop error(s) ${where} — fix them (or state the SAFETY invariant) before moving the card to testing.`);
|
|
44
52
|
process.exit(1);
|
|
45
53
|
}
|
|
46
54
|
const warnings = out.split("\n").filter(l => /\bwarning\b/.test(l)).length;
|
|
47
|
-
console.log(`slop-gate: clean${warnings ? ` (${warnings} advisory warning(s) — not gating)` : ""}.`);
|
|
55
|
+
console.log(`slop-gate${SURFACE ? ` (${SURFACE})` : ""}: clean${warnings ? ` (${warnings} advisory warning(s) — not gating)` : ""}.`);
|
|
48
56
|
process.exit(0);
|
|
Binary file
|
|
@@ -22,7 +22,7 @@ Usage: scrooge-capabilities # refresh from AA (+OpenRouter), show a
|
|
|
22
22
|
scrooge-capabilities --dry-run # fetch + match, print, but don't write
|
|
23
23
|
Exit: 0 updated · 1 nothing fetched (no key / network) · 2 error.
|
|
24
24
|
"""
|
|
25
|
-
import sys, os, json, argparse, math, urllib.request, urllib.error
|
|
25
|
+
import sys, os, json, argparse, math, time, urllib.request, urllib.error
|
|
26
26
|
|
|
27
27
|
HOME = os.path.expanduser("~")
|
|
28
28
|
SCROOGE_DIR = os.environ.get("SCROOGE_HOME", os.path.join(HOME, ".token-scrooge"))
|
|
@@ -56,10 +56,21 @@ def load_env_file(path):
|
|
|
56
56
|
except Exception:
|
|
57
57
|
pass
|
|
58
58
|
|
|
59
|
-
def http_get_json(url, headers, timeout=30):
|
|
59
|
+
def http_get_json(url, headers, timeout=30, retries=(5, 20, 60)):
|
|
60
|
+
# the weekly launchd run can land while the Mac has no network yet (2026-08-17: DNS error,
|
|
61
|
+
# scores went a week stale) -- back off and retry on connection failures, not on HTTP errors
|
|
60
62
|
req = urllib.request.Request(url, headers=headers, method="GET")
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
for i, wait in enumerate(list(retries) + [None]):
|
|
64
|
+
try:
|
|
65
|
+
with urllib.request.urlopen(req, timeout=timeout) as r:
|
|
66
|
+
return json.loads(r.read().decode())
|
|
67
|
+
except urllib.error.HTTPError:
|
|
68
|
+
raise
|
|
69
|
+
except (urllib.error.URLError, OSError) as e:
|
|
70
|
+
if wait is None:
|
|
71
|
+
raise
|
|
72
|
+
sys.stderr.write(WARN(" network: %s -- retry %d in %ds\n" % (str(e)[:60], i + 1, wait)))
|
|
73
|
+
time.sleep(wait)
|
|
63
74
|
|
|
64
75
|
def norm(s):
|
|
65
76
|
return s.lower().replace(".", "-").replace("_", "-")
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "trantor",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.79",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"trantor": "bin/cli.mjs"
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"zod": "^4.4.3"
|
|
12
12
|
},
|
|
13
13
|
"scripts": {
|
|
14
|
-
"test": "node test.mjs && node test-scenarios.mjs && node test-failure.mjs && node test-redelivery.mjs && node test-handoff.mjs && node test-agents.mjs && node test-update.mjs && node test-handoff-guard.mjs && node test-balances.mjs && node test-subagent-cost.mjs && node test-inbox.mjs && node test-inflight.mjs && node test-notify.mjs && node test-focus.mjs && node test-cardlog.mjs && node test-relay-note.mjs && node test-reaper.mjs && node test-events.mjs && node test-proposals.mjs && node test-scrub.mjs && node test-store-delta.mjs && node test-claims.mjs && node test-adopt.mjs && node test-summarize.mjs && node test-identity-core.mjs && node test-identity.mjs && node test-identity-instances.mjs && node test-duty.mjs && node test-discovery.mjs && node test-doctor.mjs && node test-splitbrain.mjs && node test-overseer.mjs && node test-overseer-lib.mjs && node test-overseer-warn.mjs && node test-provider-keys.mjs && node test-inbox-delivery.mjs && node test-hub-routing.mjs && node test-hook-routing.mjs && node test-relay-wait.mjs && node test-dsh-seat.mjs && node test-kimi-bridge.mjs && node test-kimi-events.mjs && python3 engine/test-routing.py && node test-reconcile.mjs && node test-resources.mjs && node test-patrol.mjs && node test-bridge.mjs && bash test-crew.sh"
|
|
14
|
+
"test": "node bin/slop-gate.mjs --surface desktop/src && node test.mjs && node test-scenarios.mjs && node test-failure.mjs && node test-redelivery.mjs && node test-handoff.mjs && node test-agents.mjs && node test-update.mjs && node test-handoff-guard.mjs && node test-balances.mjs && node test-subagent-cost.mjs && node test-inbox.mjs && node test-inflight.mjs && node test-notify.mjs && node test-focus.mjs && node test-cardlog.mjs && node test-relay-note.mjs && node test-reaper.mjs && node test-events.mjs && node test-proposals.mjs && node test-scrub.mjs && node test-store-delta.mjs && node test-claims.mjs && node test-adopt.mjs && node test-summarize.mjs && node test-identity-core.mjs && node test-identity.mjs && node test-identity-instances.mjs && node test-duty.mjs && node test-discovery.mjs && node test-doctor.mjs && node test-splitbrain.mjs && node test-overseer.mjs && node test-overseer-lib.mjs && node test-overseer-warn.mjs && node test-provider-keys.mjs && node test-inbox-delivery.mjs && node test-hub-routing.mjs && node test-hook-routing.mjs && node test-relay-wait.mjs && node test-dsh-seat.mjs && node test-kimi-bridge.mjs && node test-kimi-events.mjs && python3 engine/test-routing.py && node test-reconcile.mjs && node test-resources.mjs && node test-patrol.mjs && node test-bridge.mjs && bash test-crew.sh"
|
|
15
15
|
},
|
|
16
16
|
"description": "The hub-world for AI agent crews \u2014 orchestrate Claude Code, Codex, GLM, Kimi, DeepSeek & any OpenRouter model as live crews with a plan-aware Advisor, a Kanban/flow command center, a testing gate, and an economics brain (Scrooge).",
|
|
17
17
|
"files": [
|