@sleds/cli 0.1.7 → 0.1.11
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/README.md +1 -1
- package/dist/sleds.mjs +160 -23
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ SLEDS sits in front of Claude Code. It meters what you spend, sizes a job before
|
|
|
12
12
|
npx @sleds/cli init --signup
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
No org?
|
|
15
|
+
No org? `--signup` asks: just you, or your team. Just you is your email plus your own Anthropic API key. SLEDS checks the key, stores it encrypted, and it's the only key your seat ever spends. Your team is a work email and a team name — you become its owner; a platform key is optional (a Team plan without one still gets seat tracking, hold and hand-off at a wall). If your team already runs SLEDS, use the seat token your admin gave you instead:
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
18
|
npx @sleds/cli init --token sled_…
|
package/dist/sleds.mjs
CHANGED
|
@@ -305,8 +305,36 @@ var parseConfig = (raw) => {
|
|
|
305
305
|
cfg.schedule = schedule;
|
|
306
306
|
if (raw.priorStatusLine !== undefined)
|
|
307
307
|
cfg.priorStatusLine = raw.priorStatusLine;
|
|
308
|
+
if (raw.wiring === "seat-first" || raw.wiring === "proxy-always")
|
|
309
|
+
cfg.wiring = raw.wiring;
|
|
310
|
+
const org = parseOrgInfo(raw.org);
|
|
311
|
+
if (org)
|
|
312
|
+
cfg.org = org;
|
|
308
313
|
return cfg;
|
|
309
314
|
};
|
|
315
|
+
var parseOrgInfo = (raw) => {
|
|
316
|
+
if (!isObject2(raw) || !isObject2(raw.capabilities))
|
|
317
|
+
return;
|
|
318
|
+
const name = optString(raw.name);
|
|
319
|
+
const slug = optString(raw.slug);
|
|
320
|
+
const plan = raw.plan;
|
|
321
|
+
const c = raw.capabilities;
|
|
322
|
+
const src = c.upstreamSource;
|
|
323
|
+
if (name === undefined || slug === undefined || plan !== "team" && plan !== "enterprise" && plan !== "api" && plan !== "individual" || src !== "own" && src !== "shared" && src !== "none")
|
|
324
|
+
return;
|
|
325
|
+
return {
|
|
326
|
+
name,
|
|
327
|
+
slug,
|
|
328
|
+
plan,
|
|
329
|
+
capabilities: {
|
|
330
|
+
upstreamKey: c.upstreamKey === true,
|
|
331
|
+
adminKey: c.adminKey === true,
|
|
332
|
+
seats: c.seats !== false,
|
|
333
|
+
upstreamSource: src
|
|
334
|
+
},
|
|
335
|
+
mode: raw.mode === "proxy-always" ? "proxy-always" : "seat-first"
|
|
336
|
+
};
|
|
337
|
+
};
|
|
310
338
|
var readConfig = (home) => {
|
|
311
339
|
const p = configPath(home);
|
|
312
340
|
if (!existsSync2(p))
|
|
@@ -830,6 +858,8 @@ var postJson = async (o, path, body) => {
|
|
|
830
858
|
var postSeatWindow = (o, w) => postJson(o, "/proxy/seat", seatWindowBody(w));
|
|
831
859
|
var postSeatWall = (o, input) => postJson(o, "/proxy/seat-wall", input);
|
|
832
860
|
var SEAT_WALL_LINE = "Seat limit hit. sleds on --until-reset to continue on the org key.";
|
|
861
|
+
var SEAT_WALL_LINE_NO_KEY = "Seat limit hit. Hold until the reset, or /sled 5 to hand off — this org has no platform key to switch to.";
|
|
862
|
+
var seatWallLine = (hasUpstreamKey) => hasUpstreamKey ? SEAT_WALL_LINE : SEAT_WALL_LINE_NO_KEY;
|
|
833
863
|
var readStdin = (timeoutMs, stdin = process.stdin) => new Promise((resolve3) => {
|
|
834
864
|
if (stdin.isTTY) {
|
|
835
865
|
resolve3("");
|
|
@@ -1350,8 +1380,11 @@ When the proxy is active it answers a walled request with its options. The user
|
|
|
1350
1380
|
/sled 3 run overnight at half price
|
|
1351
1381
|
/sled 4 switch to a cheaper model for the rest of the session (offered when one saves ≥15%)
|
|
1352
1382
|
/sled 5 hand off to an idle coworker, or park for the team (offered on a team of two or more)
|
|
1383
|
+
/sled 6 defer to reset: the job runs itself when the seat resets — same model, done in minutes, full price (offered when the wall has a reset and the org has a key)
|
|
1353
1384
|
\`\`\`
|
|
1354
1385
|
|
|
1386
|
+
A hand-off carries a brief (the packet): what, note, cost so far, how to pick it up. The \`handoffs\` MCP tool and the dashboard's Jobs page show it; read it before taking one.
|
|
1387
|
+
|
|
1355
1388
|
## Window reset
|
|
1356
1389
|
|
|
1357
1390
|
When the user mentions their window has reset, or the deadline shown by \`sleds status\` has passed:
|
|
@@ -1364,7 +1397,7 @@ then restart \`claude\`. Settings go back to exactly what they were.
|
|
|
1364
1397
|
|
|
1365
1398
|
## Check
|
|
1366
1399
|
|
|
1367
|
-
\`sleds status\` — on/off, since, reverts at, proxy health, wall mode.
|
|
1400
|
+
\`sleds status\` — on/off, since, reverts at, proxy health, wall mode, and the org's shape (\`Org:\` / \`Wiring:\`). An org with no platform key runs seat-first and its walls offer hold (\`/sled 2\`) and hand-off (\`/sled 5\`) only — continue, overnight and switch need a key an admin adds on the dashboard.
|
|
1368
1401
|
|
|
1369
1402
|
The status line's \`seat wk 52% · 5h 12%\` is the user's own Pro/Max window as Claude Code reports it (weekly, then 5-hour); \`window\` is the org key's headroom through the proxy. At \`wk 100%\` the answer is \`sleds on --until-reset\`.
|
|
1370
1403
|
|
|
@@ -1472,11 +1505,17 @@ var promptStdin = (question) => new Promise((resolve6) => {
|
|
|
1472
1505
|
});
|
|
1473
1506
|
});
|
|
1474
1507
|
async function signupIndividual(proxyUrl, email, credential, fetchFn = fetch) {
|
|
1508
|
+
return signupRequest(proxyUrl, { email, apiKey: credential }, fetchFn);
|
|
1509
|
+
}
|
|
1510
|
+
async function signupTeam(proxyUrl, email, team, credential, fetchFn = fetch) {
|
|
1511
|
+
return signupRequest(proxyUrl, { email, team, ...credential ? { apiKey: credential } : {} }, fetchFn);
|
|
1512
|
+
}
|
|
1513
|
+
async function signupRequest(proxyUrl, payload, fetchFn) {
|
|
1475
1514
|
try {
|
|
1476
1515
|
const res = await fetchFn(`${proxyUrl}/signup`, {
|
|
1477
1516
|
method: "POST",
|
|
1478
1517
|
headers: { "content-type": "application/json" },
|
|
1479
|
-
body: JSON.stringify(
|
|
1518
|
+
body: JSON.stringify(payload),
|
|
1480
1519
|
signal: AbortSignal.timeout(20000)
|
|
1481
1520
|
});
|
|
1482
1521
|
const body = await res.json().catch(() => ({}));
|
|
@@ -1497,6 +1536,9 @@ var SIGNUP_REASONS = {
|
|
|
1497
1536
|
key_rejected: "Anthropic did not accept that API key. Check it at console.anthropic.com → API keys.",
|
|
1498
1537
|
rate_limited: "too many signups from this network in the last hour. Try again later.",
|
|
1499
1538
|
not_configured: "the proxy is not set up for self-serve signup yet.",
|
|
1539
|
+
team: "the team needs a name (2–80 characters).",
|
|
1540
|
+
personal_email: "a team needs a work email — that domain is a personal mailbox. Sign up as an individual instead, or use your company address.",
|
|
1541
|
+
org_exists: "someone at your company already set up SLEDS. Ask them for a seat (Members → invite, Admin → Mint a seat) and run `sleds init --token …`.",
|
|
1500
1542
|
unavailable: "the proxy could not reach its control plane. Try again in a moment.",
|
|
1501
1543
|
unreachable: "could not reach the proxy."
|
|
1502
1544
|
};
|
|
@@ -1522,6 +1564,20 @@ function normalizeProxyUrl(raw) {
|
|
|
1522
1564
|
return null;
|
|
1523
1565
|
}
|
|
1524
1566
|
}
|
|
1567
|
+
async function fetchOrgInfo(url, token, fetchFn = fetch) {
|
|
1568
|
+
try {
|
|
1569
|
+
const res = await fetchFn(`${url}/proxy/meter`, {
|
|
1570
|
+
headers: { authorization: `Bearer ${token}` },
|
|
1571
|
+
signal: AbortSignal.timeout(1e4)
|
|
1572
|
+
});
|
|
1573
|
+
if (!res.ok)
|
|
1574
|
+
return null;
|
|
1575
|
+
const body = await res.json();
|
|
1576
|
+
return body.org?.capabilities ? body.org : null;
|
|
1577
|
+
} catch {
|
|
1578
|
+
return null;
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1525
1581
|
async function probeProxy(url, fetchFn = fetch, opts = {}) {
|
|
1526
1582
|
const tries = opts.tries ?? 2;
|
|
1527
1583
|
const timeoutMs = opts.timeoutMs ?? 1e4;
|
|
@@ -1553,18 +1609,40 @@ var resolveToken = async (o) => {
|
|
|
1553
1609
|
const url = normalizeProxyUrl(o.url ?? env.SLEDS_PROXY_URL ?? DEFAULT_PROXY_URL);
|
|
1554
1610
|
if (!url)
|
|
1555
1611
|
return null;
|
|
1556
|
-
const
|
|
1612
|
+
const log = o.log ?? console.log;
|
|
1613
|
+
const err = o.error ?? console.error;
|
|
1614
|
+
let team = o.team?.trim() || null;
|
|
1615
|
+
if (team === null && !o.email) {
|
|
1616
|
+
const which = (await o.prompt("Set up SLEDS for (1) just you, or (2) your team? [1/2]: ")).trim();
|
|
1617
|
+
if (which === "2") {
|
|
1618
|
+
team = (await o.prompt("Team name (e.g. your company): ")).trim();
|
|
1619
|
+
if (!team)
|
|
1620
|
+
return null;
|
|
1621
|
+
}
|
|
1622
|
+
}
|
|
1623
|
+
const email = (o.email ?? await o.prompt(team ? "Your work email: " : "Your email: ")).trim();
|
|
1557
1624
|
if (!email.includes("@"))
|
|
1558
1625
|
return null;
|
|
1626
|
+
if (team) {
|
|
1627
|
+
const credential2 = (await o.prompt("Your organization's Anthropic API key, if you have one (sk-ant-…; press enter to skip — a Team plan without one still works, walls offer hold and hand-off): ")).trim();
|
|
1628
|
+
const r2 = await signupTeam(url, email, team, credential2 || null, o.fetchFn);
|
|
1629
|
+
if (!r2.ok) {
|
|
1630
|
+
err(signupFailureText(r2));
|
|
1631
|
+
return null;
|
|
1632
|
+
}
|
|
1633
|
+
log(`Created ${team} with you as owner (${email}).${credential2 ? " Your platform key is stored encrypted as the org's upstream key." : " No platform key yet — add one on the dashboard (Admin → Keys) to unlock continue / overnight / switch at a wall."}`);
|
|
1634
|
+
log("Invite your team on the dashboard (Members → invite by email, Admin → Mint a seat); each person runs `sleds init --token …`.");
|
|
1635
|
+
return { token: r2.token, source: "signup" };
|
|
1636
|
+
}
|
|
1559
1637
|
const credential = (await o.prompt("Your Anthropic API key (sk-ant-…, stored encrypted, spends only your account): ")).trim();
|
|
1560
1638
|
if (!credential)
|
|
1561
1639
|
return null;
|
|
1562
1640
|
const r = await signupIndividual(url, email, credential, o.fetchFn);
|
|
1563
1641
|
if (!r.ok) {
|
|
1564
|
-
(
|
|
1642
|
+
err(signupFailureText(r));
|
|
1565
1643
|
return null;
|
|
1566
1644
|
}
|
|
1567
|
-
|
|
1645
|
+
log(r.created ? `Created your individual seat (${email}). Your key is stored encrypted and is the only key this seat spends.` : `Re-issued your individual seat (${email}); the previous token is revoked.`);
|
|
1568
1646
|
return { token: r.token, source: "signup" };
|
|
1569
1647
|
};
|
|
1570
1648
|
var init = async (o) => {
|
|
@@ -1594,12 +1672,19 @@ var init = async (o) => {
|
|
|
1594
1672
|
return 2;
|
|
1595
1673
|
}
|
|
1596
1674
|
const wrote = [];
|
|
1675
|
+
const org = await fetchOrgInfo(url, resolved.token, o.fetchFn);
|
|
1676
|
+
const wiring = o.proxyAlways ? "proxy-always" : o.seatFirst ? "seat-first" : org?.mode ?? "proxy-always";
|
|
1677
|
+
if (wiring === "proxy-always" && org && !org.capabilities.upstreamKey) {
|
|
1678
|
+
error(`${org.name} has no platform key for the proxy to forward with; --proxy-always would break every request. Using seat-first.`);
|
|
1679
|
+
}
|
|
1680
|
+
const finalWiring = wiring === "proxy-always" && org && !org.capabilities.upstreamKey ? "seat-first" : wiring;
|
|
1597
1681
|
if (backupSettings(o.home))
|
|
1598
1682
|
wrote.push(`backed up settings to ${backupPath(o.home)}`);
|
|
1599
|
-
const
|
|
1600
|
-
const
|
|
1683
|
+
const current = readSettings(o.home);
|
|
1684
|
+
const wired = finalWiring === "proxy-always" ? applyProxy(current, { url, token: resolved.token }) : removeProxy(current);
|
|
1685
|
+
const statusLine = applyStatusLine(wired, o.statusLineCommand ?? sledsCommand("statusline", o.home, o.env));
|
|
1601
1686
|
writeSettings(o.home, statusLine.settings);
|
|
1602
|
-
wrote.push(`set env.ANTHROPIC_BASE_URL and env.ANTHROPIC_AUTH_TOKEN in ${settingsPath(o.home)}`);
|
|
1687
|
+
wrote.push(finalWiring === "proxy-always" ? `set env.ANTHROPIC_BASE_URL and env.ANTHROPIC_AUTH_TOKEN in ${settingsPath(o.home)} (everything through the proxy)` : `left Claude Code on your seat (no ANTHROPIC_BASE_URL in ${settingsPath(o.home)}); \`sleds on\` switches to the proxy at a wall`);
|
|
1603
1688
|
wrote.push(statusLine.prior === undefined ? `set statusLine in ${settingsPath(o.home)}` : `set statusLine in ${settingsPath(o.home)} (previous one kept for uninstall)`);
|
|
1604
1689
|
hooks2({
|
|
1605
1690
|
home: o.home,
|
|
@@ -1619,20 +1704,37 @@ var init = async (o) => {
|
|
|
1619
1704
|
...prior,
|
|
1620
1705
|
token: resolved.token,
|
|
1621
1706
|
proxyUrl: url,
|
|
1707
|
+
wiring: finalWiring,
|
|
1708
|
+
...org ? { org } : {},
|
|
1622
1709
|
...statusLine.prior !== undefined ? { priorStatusLine: statusLine.prior } : {}
|
|
1623
1710
|
});
|
|
1624
1711
|
wrote.push(`saved token and proxy URL to ${configPath(o.home)} (0600)`);
|
|
1625
1712
|
mkdirSync6(skillDir(o.home), { recursive: true });
|
|
1626
1713
|
writeFileSync6(skillPath(o.home), SKILL_MD);
|
|
1627
1714
|
wrote.push(`installed skill at ${skillPath(o.home)}`);
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
log(
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1715
|
+
const orgLine = org ? `${org.name} · ${org.plan}${org.capabilities.upstreamKey ? ` · ${org.capabilities.upstreamSource === "own" ? "org key" : "shared key"}` : " · no platform key"}` : "org unknown (proxy did not answer /proxy/meter)";
|
|
1716
|
+
if (finalWiring === "proxy-always") {
|
|
1717
|
+
log(`Claude Code now runs through SLEDS on the org key. (${orgLine})`);
|
|
1718
|
+
log("");
|
|
1719
|
+
for (const w of wrote)
|
|
1720
|
+
log(` ${w}`);
|
|
1721
|
+
log("");
|
|
1722
|
+
log(`Every request goes to ${url} and is metered to this seat. Run \`sleds status\` to check.`);
|
|
1723
|
+
log("The status line shows your meter: spend today, seat limits, window, allowance, queued jobs.");
|
|
1724
|
+
log("Prefer your seat first? `sleds init --seat-first` leaves Claude Code on it and switches only at a wall.");
|
|
1725
|
+
} else {
|
|
1726
|
+
log(`SLEDS is watching your seat. Nothing changes until a wall. (${orgLine})`);
|
|
1727
|
+
log("");
|
|
1728
|
+
for (const w of wrote)
|
|
1729
|
+
log(` ${w}`);
|
|
1730
|
+
log("");
|
|
1731
|
+
log("Claude Code keeps running on your seat; the status line reports its quota to SLEDS on every turn.");
|
|
1732
|
+
if (org && !org.capabilities.upstreamKey) {
|
|
1733
|
+
log("This org has no platform key, so at a wall the choices are hold until reset or hand off to a teammate. An admin can add a key on the dashboard to unlock continue / overnight / switch.");
|
|
1734
|
+
} else {
|
|
1735
|
+
log("At a wall: `sleds on --until-reset +5h` (or /sled 1) switches to the org key through the proxy until the reset; `sleds off` puts you back.");
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1636
1738
|
return 0;
|
|
1637
1739
|
};
|
|
1638
1740
|
|
|
@@ -1992,8 +2094,17 @@ async function handoffsTool(deps) {
|
|
|
1992
2094
|
if (handoffs.length === 0)
|
|
1993
2095
|
return { text: "No open hand-offs on your team. Park one with the handoff tool." };
|
|
1994
2096
|
const now = (deps.now ?? Date.now)();
|
|
1995
|
-
|
|
1996
|
-
|
|
2097
|
+
const packets = handoffs.map((h) => str2(h.packet)).filter((p) => Boolean(p)).join(`
|
|
2098
|
+
|
|
2099
|
+
---
|
|
2100
|
+
|
|
2101
|
+
`);
|
|
2102
|
+
return {
|
|
2103
|
+
text: [handoffLines(handoffs, now).slice(1).join(`
|
|
2104
|
+
`), packets ? `
|
|
2105
|
+
${packets}` : ""].join(`
|
|
2106
|
+
`)
|
|
2107
|
+
};
|
|
1997
2108
|
}
|
|
1998
2109
|
async function handoffTool(deps, args) {
|
|
1999
2110
|
if (!meterSource(deps.home))
|
|
@@ -2312,6 +2423,10 @@ var on = (o) => {
|
|
|
2312
2423
|
error("Saved token is not a sled_ token. Run `sleds init --token <sled_…>`.");
|
|
2313
2424
|
return 2;
|
|
2314
2425
|
}
|
|
2426
|
+
if (cfg.org && !cfg.org.capabilities.upstreamKey) {
|
|
2427
|
+
error(`${cfg.org.name} has no platform key, so there is no org key to switch to. Hold until the reset, or hand off with /sled 5. An admin can add a key on the dashboard.`);
|
|
2428
|
+
return 2;
|
|
2429
|
+
}
|
|
2315
2430
|
const url = (o.url ?? cfg.proxyUrl ?? env.SLEDS_PROXY_URL ?? DEFAULT_PROXY_URL2).replace(/\/+$/, "");
|
|
2316
2431
|
let untilResetMs;
|
|
2317
2432
|
if (o.untilReset !== undefined) {
|
|
@@ -2407,10 +2522,11 @@ var seatEvent = async (o) => {
|
|
|
2407
2522
|
if (week && week.resetsAt > now)
|
|
2408
2523
|
writeSeatState(o.home, { ...state, lastWallResetsAt: week.resetsAt });
|
|
2409
2524
|
} catch {}
|
|
2410
|
-
|
|
2525
|
+
const line = seatWallLine(readConfig(o.home).org?.capabilities.upstreamKey !== false);
|
|
2526
|
+
log(line);
|
|
2411
2527
|
if ((o.platform ?? process.platform) === "darwin" && o.exec) {
|
|
2412
2528
|
try {
|
|
2413
|
-
o.exec("osascript", osascriptArgs(NOTIFICATION_TITLE,
|
|
2529
|
+
o.exec("osascript", osascriptArgs(NOTIFICATION_TITLE, line));
|
|
2414
2530
|
} catch {}
|
|
2415
2531
|
}
|
|
2416
2532
|
return 0;
|
|
@@ -3107,6 +3223,10 @@ var formatStatus = (s) => {
|
|
|
3107
3223
|
}
|
|
3108
3224
|
if (s.email)
|
|
3109
3225
|
lines.push(row2("Seat:", s.email));
|
|
3226
|
+
if (s.org)
|
|
3227
|
+
lines.push(row2("Org:", `${s.org.name} · ${s.org.plan} · ${s.org.upstream === "none" ? "no platform key (walls: hold or hand off)" : s.org.upstream === "own" ? "org key" : "shared key"}`));
|
|
3228
|
+
if (s.wiring)
|
|
3229
|
+
lines.push(row2("Wiring:", s.wiring === "seat-first" ? "seat-first — Claude Code on your seat; the proxy only after `sleds on`" : "proxy-always — every request through the proxy"));
|
|
3110
3230
|
if (s.mode === "off") {
|
|
3111
3231
|
lines.push(s.pointed ? "Claude Code is pointed at the proxy by settings.json (set by `sleds init`)." : "Claude Code is on your seat. Hit a limit? `sleds on --until-reset +5h`.");
|
|
3112
3232
|
}
|
|
@@ -3138,6 +3258,14 @@ var status = async (o) => {
|
|
|
3138
3258
|
info.tokenMasked = maskToken(token);
|
|
3139
3259
|
if (cfg.email)
|
|
3140
3260
|
info.email = cfg.email;
|
|
3261
|
+
if (cfg.wiring)
|
|
3262
|
+
info.wiring = cfg.wiring;
|
|
3263
|
+
if (cfg.org)
|
|
3264
|
+
info.org = {
|
|
3265
|
+
name: cfg.org.name,
|
|
3266
|
+
plan: cfg.org.plan,
|
|
3267
|
+
upstream: cfg.org.capabilities.upstreamSource
|
|
3268
|
+
};
|
|
3141
3269
|
if (cfg.reason)
|
|
3142
3270
|
info.reason = cfg.reason;
|
|
3143
3271
|
if (o.tz)
|
|
@@ -3294,9 +3422,14 @@ commands:
|
|
|
3294
3422
|
--token <sled_\u2026> seat token (else SLEDS_TOKEN, ~/.sleds-token, or prompt)
|
|
3295
3423
|
--url <proxy-url> proxy base URL (else SLEDS_PROXY_URL, default ${DEFAULT_PROXY_URL})
|
|
3296
3424
|
--no-probe skip the /healthz check of the proxy URL
|
|
3425
|
+
--seat-first keep Claude Code on your seat; the proxy only at a wall (default for seat plans)
|
|
3426
|
+
--proxy-always every request through the proxy on the org key (default for API-plan orgs)
|
|
3297
3427
|
--non-interactive never prompt; exit 2 if no token is available
|
|
3298
|
-
--signup no org? create
|
|
3299
|
-
|
|
3428
|
+
--signup no org? create one: (1) just you \u2014 your email + your own Anthropic
|
|
3429
|
+
API key (validated, stored encrypted, the only key it spends), or
|
|
3430
|
+
(2) your team \u2014 work email + team name, platform key optional
|
|
3431
|
+
--team "<name>" with --signup: create the team org (you become its owner)
|
|
3432
|
+
--email <you@work.com> with --signup: skip the email prompt
|
|
3300
3433
|
on Hit a limit on your seat? Switch Claude Code to the org key through the proxy.
|
|
3301
3434
|
--until-reset <when> revert at this time: +5h, +90m, or an ISO timestamp
|
|
3302
3435
|
--reason "<text>" note shown by \`sleds status\`
|
|
@@ -3384,7 +3517,11 @@ var main = async (argv) => {
|
|
|
3384
3517
|
url: stringFlag(flags, "url"),
|
|
3385
3518
|
nonInteractive: flags["non-interactive"] === true,
|
|
3386
3519
|
signup: flags.signup === true,
|
|
3520
|
+
team: typeof flags.team === "string" ? flags.team : undefined,
|
|
3521
|
+
email: typeof flags.email === "string" ? flags.email : undefined,
|
|
3387
3522
|
noProbe: flags["no-probe"] === true,
|
|
3523
|
+
proxyAlways: flags["proxy-always"] === true,
|
|
3524
|
+
seatFirst: flags["seat-first"] === true,
|
|
3388
3525
|
prompt: promptStdin,
|
|
3389
3526
|
statusLineCommand: statusLineCommand(sledsArgv()),
|
|
3390
3527
|
seatEventCommand: seatEventCommand(sledsArgv()),
|
|
@@ -3435,7 +3572,7 @@ var main = async (argv) => {
|
|
|
3435
3572
|
case "version":
|
|
3436
3573
|
case "--version":
|
|
3437
3574
|
case "-v":
|
|
3438
|
-
console.log(`sleds ${"0.1.
|
|
3575
|
+
console.log(`sleds ${"0.1.11"}`);
|
|
3439
3576
|
return 0;
|
|
3440
3577
|
default:
|
|
3441
3578
|
console.error(`unknown command: ${cmd}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sleds/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"description": "SLEDS CLI — the cost and limits of AI agent work, decided at the wall. Point Claude Code at a SLEDS proxy; estimate before you run; hold, switch model, or run overnight when you hit a limit.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|