@event4u/agent-switch 1.0.2 → 1.3.0
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/dist/gui-launch.js +107 -70
- package/dist/index.js +47 -4
- package/dist/updates.js +110 -0
- package/package.json +2 -5
package/dist/gui-launch.js
CHANGED
|
@@ -1,91 +1,128 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `agent-switch gui` — launch the desktop tray GUI.
|
|
3
3
|
*
|
|
4
|
-
* The GUI is a native (Tauri) binary
|
|
5
|
-
* prebuilt
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* without the Gatekeeper / SmartScreen "unverified developer" block.
|
|
4
|
+
* The GUI is a native (Tauri) binary. Rather than ship it through npm, this
|
|
5
|
+
* downloads the prebuilt artifact from the matching GitHub Release on first
|
|
6
|
+
* use, caches it under ~/.agent-switch/gui/<version>/, and launches it. A
|
|
7
|
+
* release-downloaded, cached binary avoids the browser-download Gatekeeper
|
|
8
|
+
* quarantine, and reuses the artifacts the release already publishes.
|
|
10
9
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* Per platform the release carries a runnable artifact:
|
|
11
|
+
* - macOS: `*.app.tar.gz` (the .app bundle) → extract, `open`.
|
|
12
|
+
* - Linux: `*.AppImage` → chmod +x, run.
|
|
13
|
+
* - Windows: `*-setup.exe` (NSIS installer) → run (installs; no portable exe).
|
|
14
|
+
*
|
|
15
|
+
* The platform→asset resolution is pure and tested; download/extract/launch
|
|
16
|
+
* touch the filesystem + network.
|
|
13
17
|
*/
|
|
14
|
-
import { spawn } from "node:child_process";
|
|
15
|
-
import { createRequire } from "node:module";
|
|
18
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
16
19
|
import * as fs from "node:fs";
|
|
20
|
+
import * as os from "node:os";
|
|
17
21
|
import * as path from "node:path";
|
|
18
|
-
|
|
19
|
-
/** The
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
import { fileURLToPath } from "node:url";
|
|
23
|
+
/** The repo whose GitHub Releases carry the GUI artifacts. */
|
|
24
|
+
const UPDATE_REPO = "event4u-app/agent-switch";
|
|
25
|
+
const CACHE_ROOT = path.join(os.homedir(), ".agent-switch", "gui");
|
|
26
|
+
/** The running CLI's version, from the package's own package.json. */
|
|
27
|
+
function currentVersion() {
|
|
28
|
+
try {
|
|
29
|
+
const pkg = path.join(path.dirname(fileURLToPath(import.meta.url)), "..", "package.json");
|
|
30
|
+
return JSON.parse(fs.readFileSync(pkg, "utf8")).version ?? "0.0.0";
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return "0.0.0";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/** The release-asset pattern + handling for the host platform+arch, or null
|
|
37
|
+
* when unsupported. Pure. */
|
|
38
|
+
export function guiAssetSpec(platform = process.platform, arch = process.arch) {
|
|
23
39
|
if (platform === "darwin")
|
|
24
|
-
return "
|
|
25
|
-
if (platform === "win32" && arch === "x64")
|
|
26
|
-
return "@event4u/agent-switch-win32-x64";
|
|
40
|
+
return { match: /\.app\.tar\.gz$/, kind: "app" };
|
|
27
41
|
if (platform === "linux" && arch === "x64")
|
|
28
|
-
return "
|
|
42
|
+
return { match: /\.AppImage$/i, kind: "appimage" };
|
|
43
|
+
if (platform === "win32" && arch === "x64")
|
|
44
|
+
return { match: /-setup\.exe$/i, kind: "win-setup" };
|
|
29
45
|
return null;
|
|
30
46
|
}
|
|
31
|
-
/**
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
47
|
+
/** Program + args to launch a prepared artifact. Pure. */
|
|
48
|
+
export function guiLaunchArgv(kind, target) {
|
|
49
|
+
if (kind === "app")
|
|
50
|
+
return { program: "open", args: ["-n", target] };
|
|
51
|
+
return { program: target, args: [] }; // AppImage runs directly; win-setup runs the installer
|
|
52
|
+
}
|
|
53
|
+
/** Find a matching GUI asset on the release for `version`, falling back to the
|
|
54
|
+
* latest release. Returns null when neither has one. */
|
|
55
|
+
async function findAsset(version, match) {
|
|
56
|
+
const headers = { Accept: "application/vnd.github+json", "User-Agent": "@event4u/agent-switch gui-launch" };
|
|
57
|
+
for (const ref of [`tags/${version}`, "latest"]) {
|
|
58
|
+
let res;
|
|
59
|
+
try {
|
|
60
|
+
res = await fetch(`https://api.github.com/repos/${UPDATE_REPO}/releases/${ref}`, { headers });
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (!res.ok)
|
|
66
|
+
continue;
|
|
67
|
+
const rel = (await res.json());
|
|
68
|
+
const a = (rel.assets ?? []).find((x) => match.test(x.name));
|
|
69
|
+
if (a)
|
|
70
|
+
return { name: a.name, url: a.browser_download_url };
|
|
71
|
+
}
|
|
40
72
|
return null;
|
|
41
73
|
}
|
|
42
|
-
/**
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
74
|
+
/** Download `url` to `dest` (follows redirects via global fetch). */
|
|
75
|
+
async function download(url, dest) {
|
|
76
|
+
const res = await fetch(url, { headers: { "User-Agent": "@event4u/agent-switch gui-launch" } });
|
|
77
|
+
if (!res.ok)
|
|
78
|
+
throw new Error(`download failed: ${res.status} ${url}`);
|
|
79
|
+
const buf = Buffer.from(await res.arrayBuffer());
|
|
80
|
+
fs.writeFileSync(dest, buf);
|
|
49
81
|
}
|
|
50
|
-
/**
|
|
51
|
-
*
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
82
|
+
/** Ensure the GUI artifact for the host is downloaded + prepared under the
|
|
83
|
+
* version cache, and return the path to launch. */
|
|
84
|
+
async function ensureGuiArtifact(spec) {
|
|
85
|
+
const version = currentVersion();
|
|
86
|
+
const dir = path.join(CACHE_ROOT, version);
|
|
87
|
+
const launchName = spec.kind === "app" ? "agent-switch.app" : spec.kind === "appimage" ? "agent-switch.AppImage" : "agent-switch-setup.exe";
|
|
88
|
+
const launchPath = path.join(dir, launchName);
|
|
89
|
+
if (fs.existsSync(launchPath))
|
|
90
|
+
return launchPath; // already cached
|
|
91
|
+
const asset = await findAsset(version, spec.match);
|
|
92
|
+
if (!asset) {
|
|
93
|
+
throw new Error(`no GUI artifact for ${process.platform}/${process.arch} on the ${version} (or latest) release.\n` +
|
|
94
|
+
`Download an installer from https://github.com/${UPDATE_REPO}/releases instead.`);
|
|
60
95
|
}
|
|
61
|
-
|
|
62
|
-
|
|
96
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
97
|
+
console.log(`Downloading the GUI (${asset.name})…`);
|
|
98
|
+
if (spec.kind === "app") {
|
|
99
|
+
const tgz = path.join(dir, "app.tar.gz");
|
|
100
|
+
await download(asset.url, tgz);
|
|
101
|
+
// Extract the .app bundle, then locate it (the tarball name may vary).
|
|
102
|
+
const r = spawnSync("tar", ["-xzf", tgz, "-C", dir], { encoding: "utf8" });
|
|
103
|
+
if (r.status !== 0)
|
|
104
|
+
throw new Error(`extract failed: ${r.stderr || r.status}`);
|
|
105
|
+
fs.rmSync(tgz, { force: true });
|
|
106
|
+
const appDir = fs.readdirSync(dir).find((n) => n.endsWith(".app"));
|
|
107
|
+
if (!appDir)
|
|
108
|
+
throw new Error("extracted archive contained no .app bundle");
|
|
109
|
+
if (appDir !== launchName)
|
|
110
|
+
fs.renameSync(path.join(dir, appDir), launchPath);
|
|
111
|
+
return launchPath;
|
|
63
112
|
}
|
|
64
|
-
|
|
65
|
-
|
|
113
|
+
await download(asset.url, launchPath);
|
|
114
|
+
if (spec.kind === "appimage")
|
|
115
|
+
fs.chmodSync(launchPath, 0o755);
|
|
116
|
+
return launchPath;
|
|
66
117
|
}
|
|
67
|
-
/** Launch the desktop GUI
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
throw new Error(`the desktop GUI has no prebuilt binary for ${process.platform}/${process.arch} — build it from source with \`task gui:build\`.`);
|
|
73
|
-
}
|
|
74
|
-
const artifact = resolveGuiArtifact();
|
|
75
|
-
if (!artifact) {
|
|
76
|
-
throw new Error(`GUI binary not found — the platform package "${pkg}" is not installed.\n` +
|
|
77
|
-
`Reinstall the CLI so npm pulls it: \`npm install -g @event4u/agent-switch\`.`);
|
|
78
|
-
}
|
|
79
|
-
// On POSIX the raw binary needs the executable bit (npm can drop it).
|
|
80
|
-
if (process.platform !== "win32" && process.platform !== "darwin") {
|
|
81
|
-
try {
|
|
82
|
-
fs.chmodSync(artifact, 0o755);
|
|
83
|
-
}
|
|
84
|
-
catch {
|
|
85
|
-
/* best-effort */
|
|
86
|
-
}
|
|
118
|
+
/** Launch the desktop GUI (downloading + caching it on first use). */
|
|
119
|
+
export async function launchGui() {
|
|
120
|
+
const spec = guiAssetSpec();
|
|
121
|
+
if (!spec) {
|
|
122
|
+
throw new Error(`the desktop GUI has no prebuilt artifact for ${process.platform}/${process.arch} — build it from source with \`task gui:build\`.`);
|
|
87
123
|
}
|
|
88
|
-
const
|
|
124
|
+
const target = await ensureGuiArtifact(spec);
|
|
125
|
+
const { program, args } = guiLaunchArgv(spec.kind, target);
|
|
89
126
|
const child = spawn(program, args, { detached: true, stdio: "ignore" });
|
|
90
127
|
child.unref();
|
|
91
128
|
}
|
package/dist/index.js
CHANGED
|
@@ -24,6 +24,7 @@ import { applySharing, removeSharing, syncSharing, sharedLinkHealth } from "./sh
|
|
|
24
24
|
import { detectShell, shellenvScript } from "./shellenv.js";
|
|
25
25
|
import { runDoctor } from "./doctor.js";
|
|
26
26
|
import { launchGui } from "./gui-launch.js";
|
|
27
|
+
import { checkForUpdate, selfUpdate } from "./updates.js";
|
|
27
28
|
import { mappingRows, pruneMappings, removeMapping, resolveMapping, setMapping, } from "./mappings.js";
|
|
28
29
|
import { accessTokenOf, checkAuth, fetchProfile, fetchUsage, liveSessionPids, readProfileCredential, } from "./api.js";
|
|
29
30
|
import { formatSnapshot, parseUsage } from "./usage.js";
|
|
@@ -1525,17 +1526,53 @@ function cmdNotifications(sub, json = false) {
|
|
|
1525
1526
|
}
|
|
1526
1527
|
/** Launch a registered GUI app on a profile, isolated (macOS). Profile: an
|
|
1527
1528
|
* explicit positional name, else the active profile for the app's provider. */
|
|
1528
|
-
function cmdGui() {
|
|
1529
|
-
// Launch the tray/menubar GUI
|
|
1530
|
-
//
|
|
1529
|
+
async function cmdGui() {
|
|
1530
|
+
// Launch the tray/menubar GUI — downloads its prebuilt artifact from the
|
|
1531
|
+
// matching GitHub Release on first use, then caches it (see gui-launch.ts).
|
|
1531
1532
|
try {
|
|
1532
|
-
launchGui();
|
|
1533
|
+
await launchGui();
|
|
1533
1534
|
console.log("Launched the agent-switch GUI.");
|
|
1534
1535
|
}
|
|
1535
1536
|
catch (err) {
|
|
1536
1537
|
die(String(err?.message ?? err));
|
|
1537
1538
|
}
|
|
1538
1539
|
}
|
|
1540
|
+
/** `agent-switch check-update` — compare the running version against the latest
|
|
1541
|
+
* GitHub release (read-only; the same check the GUI runs). */
|
|
1542
|
+
async function cmdCheckUpdate(json = false) {
|
|
1543
|
+
const c = await checkForUpdate();
|
|
1544
|
+
if (json) {
|
|
1545
|
+
console.log(JSON.stringify(c));
|
|
1546
|
+
return;
|
|
1547
|
+
}
|
|
1548
|
+
switch (c.kind) {
|
|
1549
|
+
case "uptodate":
|
|
1550
|
+
console.log(`agent-switch ${c.current} — up to date (latest ${c.latest}).`);
|
|
1551
|
+
break;
|
|
1552
|
+
case "available":
|
|
1553
|
+
console.log(`Update available: ${c.current} → ${c.release.tag}\n ${c.release.url}\n Run \`agent-switch update\` to install it.`);
|
|
1554
|
+
break;
|
|
1555
|
+
case "no-releases":
|
|
1556
|
+
console.log(`agent-switch ${c.current} — no releases published yet.`);
|
|
1557
|
+
break;
|
|
1558
|
+
case "error":
|
|
1559
|
+
console.log(`agent-switch ${c.current} — update check failed: ${c.message}`);
|
|
1560
|
+
break;
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1563
|
+
/** `agent-switch update` — self-update to the latest published version via npm. */
|
|
1564
|
+
async function cmdUpdate() {
|
|
1565
|
+
const c = await checkForUpdate();
|
|
1566
|
+
if (c.kind === "uptodate")
|
|
1567
|
+
return void console.log(`Already on the latest version (${c.current}).`);
|
|
1568
|
+
if (c.kind === "no-releases")
|
|
1569
|
+
return void console.log("No releases published yet — nothing to update to.");
|
|
1570
|
+
if (c.kind === "available")
|
|
1571
|
+
console.log(`Updating ${c.current} → ${c.release.tag} via npm…`);
|
|
1572
|
+
else
|
|
1573
|
+
console.log(`Update check failed (${c.message}); attempting \`npm install\` anyway…`);
|
|
1574
|
+
process.exit(selfUpdate());
|
|
1575
|
+
}
|
|
1539
1576
|
function cmdOpen(appId, name) {
|
|
1540
1577
|
if (!appId)
|
|
1541
1578
|
die("usage: agent-switch open <app> [profile] (see `agent-switch apps`)");
|
|
@@ -1599,6 +1636,8 @@ Provider defaults to claude; pass --provider codex|antigravity for the others.
|
|
|
1599
1636
|
agent-switch rename <old> <new> [--provider P] rename a profile (name & keep its tag)
|
|
1600
1637
|
agent-switch providers enable|disable|status [--provider P] [--surface cli|ui] enable/disable a provider (default: Claude + Codex)
|
|
1601
1638
|
agent-switch gui launch the tray/menubar GUI (bundled via npm)
|
|
1639
|
+
agent-switch check-update [--json] check GitHub Releases for a newer version
|
|
1640
|
+
agent-switch update self-update to the latest version (via npm)
|
|
1602
1641
|
agent-switch apps list launchable GUI apps (macOS)
|
|
1603
1642
|
agent-switch open <app> [profile] launch a GUI app on a profile, isolated (macOS)
|
|
1604
1643
|
agent-switch shellenv [--shell zsh|bash|fish|powershell] shell integration
|
|
@@ -1643,6 +1682,10 @@ async function main() {
|
|
|
1643
1682
|
case "rename": return cmdRename(providerId, positional[0], positional[1]);
|
|
1644
1683
|
case "providers": return cmdProviders(providerId, providerExplicit, positional[0], flags);
|
|
1645
1684
|
case "gui": return cmdGui();
|
|
1685
|
+
case "update":
|
|
1686
|
+
case "upgrade": return cmdUpdate();
|
|
1687
|
+
case "check-update":
|
|
1688
|
+
case "check-updates": return cmdCheckUpdate(!!flags.json);
|
|
1646
1689
|
case "open": return cmdOpen(positional[0], positional[1]);
|
|
1647
1690
|
case "apps": return cmdApps(!!flags.json);
|
|
1648
1691
|
case "notify": return cmdNotify(flags);
|
package/dist/updates.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI update check + self-update.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the GUI's update logic (gui/src/updates.ts): the same version math
|
|
5
|
+
* and GitHub `/releases/latest` parsing, but for the CLI — the running version
|
|
6
|
+
* comes from the package's own package.json, the fetch uses Node's global
|
|
7
|
+
* `fetch`, and `selfUpdate` reinstalls the npm package.
|
|
8
|
+
*
|
|
9
|
+
* The version/parse helpers are pure and unit-tested; only currentVersion,
|
|
10
|
+
* fetchLatestRelease, and selfUpdate touch the outside world.
|
|
11
|
+
*/
|
|
12
|
+
import { spawnSync } from "node:child_process";
|
|
13
|
+
import * as fs from "node:fs";
|
|
14
|
+
import * as path from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
/** The published npm package + the repo whose GitHub Releases are the update source. */
|
|
17
|
+
export const PACKAGE_NAME = "@event4u/agent-switch";
|
|
18
|
+
export const UPDATE_REPO = "event4u-app/agent-switch";
|
|
19
|
+
/** Parse a version tag (`v1.2.3`, `1.2.3`, `1.2`) into numeric components. A
|
|
20
|
+
* leading `v`/`V` and any pre-release/build suffix are stripped; non-numeric
|
|
21
|
+
* components collapse to 0 so a malformed tag can never throw. */
|
|
22
|
+
export function parseVersion(tag) {
|
|
23
|
+
const core = String(tag).trim().replace(/^[vV]/, "").split(/[-+]/, 1)[0];
|
|
24
|
+
return core.split(".").map((p) => {
|
|
25
|
+
const n = Number.parseInt(p, 10);
|
|
26
|
+
return Number.isFinite(n) ? n : 0;
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/** Compare two version tags: -1 (a<b), 0 (equal), 1 (a>b). */
|
|
30
|
+
export function compareVersions(a, b) {
|
|
31
|
+
const pa = parseVersion(a);
|
|
32
|
+
const pb = parseVersion(b);
|
|
33
|
+
const len = Math.max(pa.length, pb.length);
|
|
34
|
+
for (let i = 0; i < len; i++) {
|
|
35
|
+
const x = pa[i] ?? 0;
|
|
36
|
+
const y = pb[i] ?? 0;
|
|
37
|
+
if (x > y)
|
|
38
|
+
return 1;
|
|
39
|
+
if (x < y)
|
|
40
|
+
return -1;
|
|
41
|
+
}
|
|
42
|
+
return 0;
|
|
43
|
+
}
|
|
44
|
+
/** True when `latest` is strictly newer than `current`. */
|
|
45
|
+
export function isNewer(latest, current) {
|
|
46
|
+
return compareVersions(latest, current) > 0;
|
|
47
|
+
}
|
|
48
|
+
/** Reshape a raw GitHub `releases/latest` payload into {@link ReleaseInfo}, or
|
|
49
|
+
* null for a draft/prerelease or a payload without a tag. Pure — no network. */
|
|
50
|
+
export function parseRelease(raw) {
|
|
51
|
+
if (!raw || typeof raw !== "object")
|
|
52
|
+
return null;
|
|
53
|
+
const r = raw;
|
|
54
|
+
if (r.draft === true || r.prerelease === true)
|
|
55
|
+
return null;
|
|
56
|
+
const tag = typeof r.tag_name === "string" ? r.tag_name : "";
|
|
57
|
+
if (!tag)
|
|
58
|
+
return null;
|
|
59
|
+
return {
|
|
60
|
+
tag,
|
|
61
|
+
name: typeof r.name === "string" && r.name ? r.name : tag,
|
|
62
|
+
url: typeof r.html_url === "string" ? r.html_url : `https://github.com/${UPDATE_REPO}/releases`,
|
|
63
|
+
notes: typeof r.body === "string" ? r.body : "",
|
|
64
|
+
publishedAt: typeof r.published_at === "string" ? r.published_at : "",
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/** The running CLI's version, from the package's own package.json (one level up
|
|
68
|
+
* from the compiled dist/). "0.0.0" if unreadable so callers never crash. */
|
|
69
|
+
export function currentVersion() {
|
|
70
|
+
try {
|
|
71
|
+
const pkg = path.join(path.dirname(fileURLToPath(import.meta.url)), "..", "package.json");
|
|
72
|
+
return JSON.parse(fs.readFileSync(pkg, "utf8")).version ?? "0.0.0";
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return "0.0.0";
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/** Latest published release, or null when the repo has none yet (404). Throws
|
|
79
|
+
* on other network/HTTP failures so the caller can surface them. */
|
|
80
|
+
export async function fetchLatestRelease(repo = UPDATE_REPO) {
|
|
81
|
+
const res = await fetch(`https://api.github.com/repos/${repo}/releases/latest`, {
|
|
82
|
+
headers: { Accept: "application/vnd.github+json", "User-Agent": `${PACKAGE_NAME} cli-updater` },
|
|
83
|
+
});
|
|
84
|
+
if (res.status === 404)
|
|
85
|
+
return null;
|
|
86
|
+
if (!res.ok)
|
|
87
|
+
throw new Error(`GitHub API returned ${res.status}`);
|
|
88
|
+
return parseRelease(await res.json());
|
|
89
|
+
}
|
|
90
|
+
/** Read the current version, fetch the latest release, classify. Never throws. */
|
|
91
|
+
export async function checkForUpdate(repo = UPDATE_REPO) {
|
|
92
|
+
const current = currentVersion();
|
|
93
|
+
try {
|
|
94
|
+
const release = await fetchLatestRelease(repo);
|
|
95
|
+
if (!release)
|
|
96
|
+
return { kind: "no-releases", current };
|
|
97
|
+
if (isNewer(release.tag, current))
|
|
98
|
+
return { kind: "available", current, release };
|
|
99
|
+
return { kind: "uptodate", current, latest: release.tag };
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
return { kind: "error", current, message: e instanceof Error ? e.message : String(e) };
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/** Self-update: reinstall the npm package at @latest (global). Streams npm's
|
|
106
|
+
* own output; returns its exit code (0 = success). */
|
|
107
|
+
export function selfUpdate() {
|
|
108
|
+
const r = spawnSync("npm", ["install", "-g", `${PACKAGE_NAME}@latest`], { stdio: "inherit" });
|
|
109
|
+
return r.status ?? 1;
|
|
110
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@event4u/agent-switch",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Switch between multiple Claude Code accounts on macOS, Linux, and Windows via isolated CLAUDE_CONFIG_DIR profiles",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -31,9 +31,6 @@
|
|
|
31
31
|
"typescript": "^5.9.3"
|
|
32
32
|
},
|
|
33
33
|
"optionalDependencies": {
|
|
34
|
-
"playwright": "^1.49.0"
|
|
35
|
-
"@event4u/agent-switch-darwin": "1.0.2",
|
|
36
|
-
"@event4u/agent-switch-linux-x64": "1.0.2",
|
|
37
|
-
"@event4u/agent-switch-win32-x64": "1.0.2"
|
|
34
|
+
"playwright": "^1.49.0"
|
|
38
35
|
}
|
|
39
36
|
}
|