switchboard-fyi 0.2.0 → 0.2.1
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/CHANGELOG.md +9 -0
- package/bin/switchboard.mjs +55 -44
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,15 @@
|
|
|
3
3
|
All notable Switchboard CLI changes are recorded here. Keep this file in sync
|
|
4
4
|
with the hosted release notes at `https://www.switchboard.fyi/release/latest`.
|
|
5
5
|
|
|
6
|
+
## 0.2.1 - 2026-05-26
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
|
|
10
|
+
- Require `switchboard login` before local routing, observe mode, dashboard,
|
|
11
|
+
install, uninstall, settings, and difficulty mapping commands do any work.
|
|
12
|
+
- Updated the signed-out home and status screens to point users toward login
|
|
13
|
+
instead of showing local routing stats or enabled actions.
|
|
14
|
+
|
|
6
15
|
## 0.2.0 - 2026-05-26
|
|
7
16
|
|
|
8
17
|
### Changed
|
package/bin/switchboard.mjs
CHANGED
|
@@ -516,6 +516,7 @@ async function runCodex(argv) {
|
|
|
516
516
|
return runRealHarnessDirect("codex", codexBinary, argv, {
|
|
517
517
|
env: directHarnessEnv(),
|
|
518
518
|
});
|
|
519
|
+
requireSwitchboardAuth();
|
|
519
520
|
const observeMode =
|
|
520
521
|
requestedObserve ||
|
|
521
522
|
activeState.mode === "observe";
|
|
@@ -726,6 +727,7 @@ async function runClaude(argv) {
|
|
|
726
727
|
return runRealHarnessDirect("claude", claudeBinary, argv, {
|
|
727
728
|
env: directClaudeEnv(),
|
|
728
729
|
});
|
|
730
|
+
requireSwitchboardAuth();
|
|
729
731
|
const observeMode =
|
|
730
732
|
requestedObserve ||
|
|
731
733
|
activeState.mode === "observe";
|
|
@@ -2142,6 +2144,7 @@ function renderHarnessEffortChoices(harness, model, value, active = false) {
|
|
|
2142
2144
|
}
|
|
2143
2145
|
|
|
2144
2146
|
async function showHarnessSettingsScreen(harness) {
|
|
2147
|
+
requireSwitchboardAuth();
|
|
2145
2148
|
const config = ensureConfigFile();
|
|
2146
2149
|
const levels = [...DIFFICULTY_LEVELS].sort((a, b) => b - a);
|
|
2147
2150
|
const models = harnessModelOptions(harness);
|
|
@@ -2301,6 +2304,7 @@ function showDifficulty(argv = []) {
|
|
|
2301
2304
|
return;
|
|
2302
2305
|
}
|
|
2303
2306
|
if (action !== "set") throw new Error(`Unknown difficulty command: ${action}`);
|
|
2307
|
+
requireSwitchboardAuth();
|
|
2304
2308
|
const harness = assertHarness(argv.shift());
|
|
2305
2309
|
const level = Number(argv.shift() || "");
|
|
2306
2310
|
const model = String(argv.shift() || "").trim();
|
|
@@ -2762,6 +2766,13 @@ function authToken() {
|
|
|
2762
2766
|
return process.env.SWITCHBOARD_API_TOKEN || readAuth()?.token || "";
|
|
2763
2767
|
}
|
|
2764
2768
|
|
|
2769
|
+
const SIGN_IN_REQUIRED_MESSAGE = "Not logged in. Run `switchboard login` first.";
|
|
2770
|
+
|
|
2771
|
+
function requireSwitchboardAuth() {
|
|
2772
|
+
if (authToken()) return;
|
|
2773
|
+
throw new Error(SIGN_IN_REQUIRED_MESSAGE);
|
|
2774
|
+
}
|
|
2775
|
+
|
|
2765
2776
|
const ACCOUNT_CACHE_TTL_MS = 30_000;
|
|
2766
2777
|
const HOME_ACCOUNT_REFRESH_TIMEOUT_MS = 5000;
|
|
2767
2778
|
let _balanceCache = null;
|
|
@@ -3990,13 +4001,15 @@ function switchboardAccountCard() {
|
|
|
3990
4001
|
}
|
|
3991
4002
|
|
|
3992
4003
|
function homeMenuOptions(installed, install = installSnapshot()) {
|
|
4004
|
+
const loggedIn = Boolean(authToken());
|
|
3993
4005
|
const harnessCard = (key, displayName) => {
|
|
3994
4006
|
const info = install.harnesses[key] || {};
|
|
3995
4007
|
const present = Boolean(installed[key] || info.realAvailable);
|
|
3996
4008
|
const installedShim = Boolean(info.installed);
|
|
3997
4009
|
const active = activeHarnessState(key);
|
|
3998
|
-
const
|
|
3999
|
-
const
|
|
4010
|
+
const signInDescription = `sign in first to use ${displayName}`;
|
|
4011
|
+
const startDisabled = active.active || !loggedIn;
|
|
4012
|
+
const observeDisabled = active.active || !loggedIn;
|
|
4000
4013
|
|
|
4001
4014
|
let tag, tagTone;
|
|
4002
4015
|
if (active.mode === "live") {
|
|
@@ -4021,12 +4034,20 @@ function homeMenuOptions(installed, install = installSnapshot()) {
|
|
|
4021
4034
|
if (installedShim) {
|
|
4022
4035
|
opts.push({
|
|
4023
4036
|
type: "card-row",
|
|
4024
|
-
content: ` ${dim(
|
|
4037
|
+
content: ` ${dim(
|
|
4038
|
+
loggedIn
|
|
4039
|
+
? `switchboard is ready for ${displayName}`
|
|
4040
|
+
: `sign in before using switchboard for ${displayName}`,
|
|
4041
|
+
)}`,
|
|
4025
4042
|
});
|
|
4026
4043
|
} else if (present) {
|
|
4027
4044
|
opts.push({
|
|
4028
4045
|
type: "card-row",
|
|
4029
|
-
content: ` ${dim(
|
|
4046
|
+
content: ` ${dim(
|
|
4047
|
+
loggedIn
|
|
4048
|
+
? `${displayName} is on your computer but not connected to switchboard yet`
|
|
4049
|
+
: `${displayName} is on your computer — sign in before connecting switchboard`,
|
|
4050
|
+
)}`,
|
|
4030
4051
|
});
|
|
4031
4052
|
} else {
|
|
4032
4053
|
opts.push({
|
|
@@ -4040,38 +4061,50 @@ function homeMenuOptions(installed, install = installSnapshot()) {
|
|
|
4040
4061
|
opts.push({
|
|
4041
4062
|
label: "set up",
|
|
4042
4063
|
value: `${key}-install`,
|
|
4043
|
-
disabled: !present,
|
|
4044
|
-
description: present
|
|
4045
|
-
? `
|
|
4046
|
-
:
|
|
4064
|
+
disabled: !present || !loggedIn,
|
|
4065
|
+
description: !present
|
|
4066
|
+
? `install ${displayName} on your computer first`
|
|
4067
|
+
: loggedIn
|
|
4068
|
+
? `connect switchboard for ${displayName}`
|
|
4069
|
+
: `sign in first to set up ${displayName}`,
|
|
4047
4070
|
});
|
|
4048
4071
|
} else {
|
|
4049
4072
|
opts.push(
|
|
4050
4073
|
{
|
|
4051
4074
|
label: "start",
|
|
4052
4075
|
value: `${key}-start`,
|
|
4053
|
-
description:
|
|
4054
|
-
?
|
|
4055
|
-
:
|
|
4076
|
+
description: !loggedIn
|
|
4077
|
+
? signInDescription
|
|
4078
|
+
: active.active
|
|
4079
|
+
? `close the other window first`
|
|
4080
|
+
: `turn on switchboard for ${displayName}`,
|
|
4056
4081
|
disabled: startDisabled,
|
|
4057
4082
|
},
|
|
4058
4083
|
{
|
|
4059
4084
|
label: "observe",
|
|
4060
4085
|
value: `${key}-observe`,
|
|
4061
|
-
description:
|
|
4062
|
-
?
|
|
4063
|
-
:
|
|
4086
|
+
description: !loggedIn
|
|
4087
|
+
? signInDescription
|
|
4088
|
+
: active.active
|
|
4089
|
+
? `close the other window first`
|
|
4090
|
+
: `watch ${displayName} without changing anything`,
|
|
4064
4091
|
disabled: observeDisabled,
|
|
4065
4092
|
},
|
|
4066
4093
|
{
|
|
4067
4094
|
label: "settings",
|
|
4068
4095
|
value: `${key}-settings`,
|
|
4069
|
-
description:
|
|
4096
|
+
description: loggedIn
|
|
4097
|
+
? `edit ${displayName} difficulty mappings`
|
|
4098
|
+
: `sign in first to edit ${displayName} settings`,
|
|
4099
|
+
disabled: !loggedIn,
|
|
4070
4100
|
},
|
|
4071
4101
|
{
|
|
4072
4102
|
label: "uninstall",
|
|
4073
4103
|
value: `${key}-uninstall`,
|
|
4074
|
-
description:
|
|
4104
|
+
description: loggedIn
|
|
4105
|
+
? `remove switchboard for ${displayName}`
|
|
4106
|
+
: `sign in first to change ${displayName} setup`,
|
|
4107
|
+
disabled: !loggedIn,
|
|
4075
4108
|
},
|
|
4076
4109
|
);
|
|
4077
4110
|
}
|
|
@@ -4130,6 +4163,7 @@ async function showActiveDashboard(
|
|
|
4130
4163
|
activeMode = "live",
|
|
4131
4164
|
options = {},
|
|
4132
4165
|
) {
|
|
4166
|
+
requireSwitchboardAuth();
|
|
4133
4167
|
const targets = dashboardTargets(argv);
|
|
4134
4168
|
const claim = claimActiveHarnesses(targets, activeMode);
|
|
4135
4169
|
if (claim.conflicts.length) {
|
|
@@ -4447,6 +4481,7 @@ function showInstall(argv = []) {
|
|
|
4447
4481
|
"Switchboard install currently supports macOS and Linux. Windows shims are not available in this release.",
|
|
4448
4482
|
);
|
|
4449
4483
|
}
|
|
4484
|
+
requireSwitchboardAuth();
|
|
4450
4485
|
const noShellRc = argv.includes("--no-shell-rc");
|
|
4451
4486
|
const forceShellRc = argv.includes("--shell-rc");
|
|
4452
4487
|
const verbose =
|
|
@@ -4480,8 +4515,7 @@ function showInstall(argv = []) {
|
|
|
4480
4515
|
);
|
|
4481
4516
|
}
|
|
4482
4517
|
|
|
4483
|
-
|
|
4484
|
-
if (!noShellRc || forceShellRc) shellRc = ensureShellPathBlock();
|
|
4518
|
+
if (!noShellRc || forceShellRc) ensureShellPathBlock();
|
|
4485
4519
|
|
|
4486
4520
|
console.log(`✓ Switchboard installed`);
|
|
4487
4521
|
for (const { harness } of installed) {
|
|
@@ -4490,14 +4524,6 @@ function showInstall(argv = []) {
|
|
|
4490
4524
|
for (const item of skipped) {
|
|
4491
4525
|
console.log(` ○ ${harnessLabel(item.harness)} not found`);
|
|
4492
4526
|
}
|
|
4493
|
-
console.log("");
|
|
4494
|
-
if (noShellRc && !forceShellRc) {
|
|
4495
|
-
console.log("Run this once in your shell:");
|
|
4496
|
-
console.log(` export PATH=${shellQuote(shimDir())}:$PATH`);
|
|
4497
|
-
} else if (shellRc) {
|
|
4498
|
-
console.log("Open a new terminal, then use:");
|
|
4499
|
-
console.log(` ${installed.map(({ entry }) => entry.command).join(" ")}`);
|
|
4500
|
-
}
|
|
4501
4527
|
ensureProcessPathHasShimDir();
|
|
4502
4528
|
if (verbose) {
|
|
4503
4529
|
console.log("");
|
|
@@ -4538,12 +4564,6 @@ function showUninstall(argv = []) {
|
|
|
4538
4564
|
for (const harness of removed) {
|
|
4539
4565
|
console.log(` ✓ ${harnessLabel(harness)}`);
|
|
4540
4566
|
}
|
|
4541
|
-
console.log("");
|
|
4542
|
-
console.log(
|
|
4543
|
-
anyInstalled
|
|
4544
|
-
? "Remaining installed tools still use Switchboard."
|
|
4545
|
-
: "Your tools now run normally.",
|
|
4546
|
-
);
|
|
4547
4567
|
if (verbose) {
|
|
4548
4568
|
console.log("");
|
|
4549
4569
|
printInstallSummary({ verbose: true });
|
|
@@ -5234,18 +5254,7 @@ function renderStatusStrip(
|
|
|
5234
5254
|
statLines = [` ${dim("checking account route stats…")}`];
|
|
5235
5255
|
}
|
|
5236
5256
|
} else {
|
|
5237
|
-
|
|
5238
|
-
const totalReq = snapshot.rows.length;
|
|
5239
|
-
const hasTraffic = totalReq > 0;
|
|
5240
|
-
statLines = hasTraffic
|
|
5241
|
-
? [
|
|
5242
|
-
statRow("local requests", compactNumber(totalReq)),
|
|
5243
|
-
statRow(
|
|
5244
|
-
"local tokens processed",
|
|
5245
|
-
compactNumber(snapshot.processedTokens),
|
|
5246
|
-
),
|
|
5247
|
-
]
|
|
5248
|
-
: [` ${dim("no routes yet — sign in and start routing")}`];
|
|
5257
|
+
statLines = [` ${dim("sign in to start routing with switchboard")}`];
|
|
5249
5258
|
}
|
|
5250
5259
|
|
|
5251
5260
|
let identityLine = "";
|
|
@@ -6706,11 +6715,13 @@ function routeTaskDisplay(row) {
|
|
|
6706
6715
|
}
|
|
6707
6716
|
|
|
6708
6717
|
async function showDashboard(argv, options = {}) {
|
|
6718
|
+
requireSwitchboardAuth();
|
|
6709
6719
|
const harness = parseHarnessScope(argv);
|
|
6710
6720
|
console.log(renderDashboard(harness));
|
|
6711
6721
|
}
|
|
6712
6722
|
|
|
6713
6723
|
async function showDashboardSession(argv, options = {}) {
|
|
6724
|
+
requireSwitchboardAuth();
|
|
6714
6725
|
const harness = parseHarnessScope(argv);
|
|
6715
6726
|
const exitOnClose = options.exitOnClose !== false;
|
|
6716
6727
|
const sessionStart = new Date().toISOString();
|