tokentracker-cli 0.96.0 → 0.96.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/README.md +2 -0
- package/README.zh-CN.md +1 -1
- package/dashboard/dist/assets/{AchievementBadge-Bb2ljquW.js → AchievementBadge-DKyElm0T.js} +1 -1
- package/dashboard/dist/assets/{AchievementsPage-ByUP2x8a.js → AchievementsPage-BvCx3wND.js} +2 -2
- package/dashboard/dist/assets/{AchievementsSection-_L6sCLTw.js → AchievementsSection-DN69LzXX.js} +1 -1
- package/dashboard/dist/assets/{BadgeDetailModal-B9n_-45B.js → BadgeDetailModal-DGiKdZfz.js} +1 -1
- package/dashboard/dist/assets/{BotAnimated-lWmg-aZg.js → BotAnimated-zN8rH7_K.js} +1 -1
- package/dashboard/dist/assets/{Card-aSp259T0.js → Card-COWo-ClV.js} +1 -1
- package/dashboard/dist/assets/{ClawdAnimated-Cy-XaTXW.js → ClawdAnimated-BWsB7Eat.js} +2 -2
- package/dashboard/dist/assets/{CommandPalette-CNwtKCUm.js → CommandPalette-BfvIwuoJ.js} +1 -1
- package/dashboard/dist/assets/{CommunityStatsModal-DJSezaPV.js → CommunityStatsModal-BQWg7R_y.js} +1 -1
- package/dashboard/dist/assets/{ConfirmModal-CVjmhZd6.js → ConfirmModal-C7ABSI-O.js} +1 -1
- package/dashboard/dist/assets/{Controls-BIj6yVxE.js → Controls-vMzEZzej.js} +1 -1
- package/dashboard/dist/assets/DashboardPage-QBhbCMZF.js +1 -0
- package/dashboard/dist/assets/{DevicePage-ptsI2fZc.js → DevicePage-3ejUBLWM.js} +1 -1
- package/dashboard/dist/assets/{DialogClose-D1pLoZ56.js → DialogClose-D_dvtfGV.js} +1 -1
- package/dashboard/dist/assets/DialogDescription-ryGYdQjX.js +1 -0
- package/dashboard/dist/assets/{DialogTitle-DfSBUjWf.js → DialogTitle-_ahf0z8b.js} +1 -1
- package/dashboard/dist/assets/{FadeIn-DBn4L_BV.js → FadeIn-D7Jcfz1N.js} +1 -1
- package/dashboard/dist/assets/{HeaderGithubStar-EJLBwEqp.js → HeaderGithubStar-D--Rx5BS.js} +1 -1
- package/dashboard/dist/assets/{HoverTooltip-DaSrZhYd.js → HoverTooltip-n1W0z3Wr.js} +1 -1
- package/dashboard/dist/assets/{IpCheckPage-diQTVaYt.js → IpCheckPage-D202tl9B.js} +1 -1
- package/dashboard/dist/assets/{LandingPage-BqCxjwar.js → LandingPage-D6yL2EZo.js} +2 -2
- package/dashboard/dist/assets/{LeaderboardAvatar-CQImCsPN.js → LeaderboardAvatar-ChFg2mtA.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardPage-D2ZDUi_O.js → LeaderboardPage-BXHwGs8r.js} +2 -2
- package/dashboard/dist/assets/{LeaderboardProfileModal-DHvADX1d.js → LeaderboardProfileModal-B5LoOpCk.js} +3 -3
- package/dashboard/dist/assets/{LeaderboardProfilePage-CJsedB28.js → LeaderboardProfilePage-jsukhRz8.js} +1 -1
- package/dashboard/dist/assets/{LimitsPage-CAwff24b.js → LimitsPage-PvqkOOwp.js} +1 -1
- package/dashboard/dist/assets/{LocalOnlyNotice-Cmnvu9tI.js → LocalOnlyNotice-Du0lz657.js} +1 -1
- package/dashboard/dist/assets/{LoginCard-BQmKkD7X.js → LoginCard-BFEX9x7-.js} +1 -1
- package/dashboard/dist/assets/{LoginModal-2oPROePZ.js → LoginModal-DqC7_d35.js} +1 -1
- package/dashboard/dist/assets/{LoginPage-aqdUJoQK.js → LoginPage-Dzx8N7HE.js} +1 -1
- package/dashboard/dist/assets/{PetPage-Bn3p_o5r.js → PetPage-CNlWHF4z.js} +1 -1
- package/dashboard/dist/assets/{PopoverPopup-DXD_YdiB.js → PopoverPopup-D9jadD3j.js} +1 -1
- package/dashboard/dist/assets/{ProviderIcon-BZZ45-gY.js → ProviderIcon-Caz5PuAm.js} +1 -1
- package/dashboard/dist/assets/{ResetPasswordPage-Bn5ITiHQ.js → ResetPasswordPage-x_GR79sR.js} +1 -1
- package/dashboard/dist/assets/{SegmentedControl-hGXboQZy.js → SegmentedControl-BxDiDV4R.js} +1 -1
- package/dashboard/dist/assets/{Select-BP8aVRZ1.js → Select-B5o-1sEl.js} +1 -1
- package/dashboard/dist/assets/{SelectItemText-Odx47kND.js → SelectItemText-CiA6L7Wk.js} +1 -1
- package/dashboard/dist/assets/{ServiceStatusPage-DUueam0N.js → ServiceStatusPage-BVQuVdjg.js} +1 -1
- package/dashboard/dist/assets/{SessionsPage-BA9IFqQ1.js → SessionsPage-DE39wNIO.js} +1 -1
- package/dashboard/dist/assets/SettingsPage-DJrb_fsK.js +2 -0
- package/dashboard/dist/assets/{SkillsPage-Ds2vH_PG.js → SkillsPage-COk-YQQ5.js} +1 -1
- package/dashboard/dist/assets/{TokenGalaxy-CWBR4jnB.js → TokenGalaxy-BPM779Wb.js} +1 -1
- package/dashboard/dist/assets/{ToolbarRootContext-Bmg56vYz.js → ToolbarRootContext-CozJT6Vs.js} +1 -1
- package/dashboard/dist/assets/{TrendMonitor-BQzcllvg.js → TrendMonitor-BkNy-o1D.js} +1 -1
- package/dashboard/dist/assets/{WidgetsPage-Bu3tHDjO.js → WidgetsPage-Bpg6H-ZB.js} +1 -1
- package/dashboard/dist/assets/{WrappedPage-BrAMJhgy.js → WrappedPage-C6-NM-RO.js} +1 -1
- package/dashboard/dist/assets/__vite-browser-external-BGnq8Ebm.js +45 -0
- package/dashboard/dist/assets/__vite-browser-external-CvMMIjhi.css +1 -0
- package/dashboard/dist/assets/{agent-logos-B8lT-HcI.js → agent-logos-DpbkRqXT.js} +1 -1
- package/dashboard/dist/assets/{arrow-up-right-rpBCOTg2.js → arrow-up-right-BjOtWUVs.js} +1 -1
- package/dashboard/dist/assets/{check-DIKw7TYH.js → check-BlxnX5jZ.js} +1 -1
- package/dashboard/dist/assets/{composite-_NeXO0lv.js → composite-Dxmivlk4.js} +1 -1
- package/dashboard/dist/assets/{copy-CsfAtL7P.js → copy-CIsWjLY5.js} +1 -1
- package/dashboard/dist/assets/{download-DM1W9pIW.js → download-QDaQbQdd.js} +1 -1
- package/dashboard/dist/assets/{external-link-CwbuMbeQ.js → external-link-DPV4VU3m.js} +1 -1
- package/dashboard/dist/assets/{flame-DcYbLdhE.js → flame-B_X-7VNp.js} +1 -1
- package/dashboard/dist/assets/{format-tokens-CEvr3dNy.js → format-tokens-DEx2TJj8.js} +1 -1
- package/dashboard/dist/assets/{icons-DaGMVsJ5.js → icons-983RyGSl.js} +1 -1
- package/dashboard/dist/assets/{index-BVVLPj3N.js → index-BONYA8HZ.js} +1 -1
- package/dashboard/dist/assets/{index-ChZkJjpk.js → index-Cjs5stC0.js} +1 -1
- package/dashboard/dist/assets/{index-T7OjmEuX.js → index-qtonw_x4.js} +1 -1
- package/dashboard/dist/assets/{info-CAjN3dX4.js → info-DpVOhXZI.js} +1 -1
- package/dashboard/dist/assets/{limits-providers-jn7Yln_V.js → limits-providers-BUoquSA-.js} +1 -1
- package/dashboard/dist/assets/{link-2-DaWH2Tyc.js → link-2-CBro-upz.js} +1 -1
- package/dashboard/dist/assets/{loader-circle-CnF8qPi1.js → loader-circle-wYFdSyOd.js} +1 -1
- package/dashboard/dist/assets/{maximize-2-B-2Pnj6g.js → maximize-2-DhTyQ4ly.js} +1 -1
- package/dashboard/dist/assets/{modifiers.esm-BoDOvUKl.js → modifiers.esm-CPljwVhN.js} +1 -1
- package/dashboard/dist/assets/{monitor-smartphone-DDgwxG_E.js → monitor-smartphone-D_wr-HOR.js} +1 -1
- package/dashboard/dist/assets/{plus-DIc1YUWB.js → plus-BNjfkBEF.js} +1 -1
- package/dashboard/dist/assets/{provider-display-yeNsVCO_.js → provider-display-BOBtUyFi.js} +1 -1
- package/dashboard/dist/assets/{react-DZqS6YTX.js → react-yHv9MTUA.js} +1 -1
- package/dashboard/dist/assets/{search-D6tEppYJ.js → search-Dfak92ZA.js} +1 -1
- package/dashboard/dist/assets/{skills-api-vsA1rc1Z.js → skills-api-By2PdNa1.js} +1 -1
- package/dashboard/dist/assets/{sortable.esm-DDCnS1HI.js → sortable.esm-B9xy66_v.js} +1 -1
- package/dashboard/dist/assets/{store-Crne4DqF.js → store-oQZR4d9M.js} +1 -1
- package/dashboard/dist/assets/{terminal-Ca7dkLMF.js → terminal-pbXWBmZM.js} +1 -1
- package/dashboard/dist/assets/{trash-2-CjEAS5ic.js → trash-2-CboDPwbW.js} +1 -1
- package/dashboard/dist/assets/{use-community-stats-BHx2YxyK.js → use-community-stats-D6HTdnHq.js} +1 -1
- package/dashboard/dist/assets/{use-latest-request-guard-BLGbXQdf.js → use-latest-request-guard-hwSr9Cam.js} +1 -1
- package/dashboard/dist/assets/{use-limits-display-prefs-DBkAp6ob.js → use-limits-display-prefs-B-pbwUS8.js} +1 -1
- package/dashboard/dist/assets/{use-ordered-list-BTfW5M9u.js → use-ordered-list-OtfOqrNb.js} +1 -1
- package/dashboard/dist/assets/use-reduced-motion-DGXcZBX3.js +1 -0
- package/dashboard/dist/assets/{use-session-efficiency-pref-DBmd-MqH.js → use-session-efficiency-pref-BScvtS8F.js} +1 -1
- package/dashboard/dist/assets/{use-transform-Bp5XrwaQ.js → use-transform-Cy1ykjEs.js} +1 -1
- package/dashboard/dist/assets/{use-usage-limits-BmqRcyhH.js → use-usage-limits-CSMb2zYW.js} +1 -1
- package/dashboard/dist/assets/{useCurrency-B0YsRDj-.js → useCurrency-VqF3cy1C.js} +1 -1
- package/dashboard/dist/assets/{useTokenFormat-PP3D0Ket.js → useTokenFormat-Cgub4MXu.js} +1 -1
- package/dashboard/dist/assets/{zap-BVOm1aBH.js → zap-DStzvQJI.js} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/dashboard/dist/ip-check.html +2 -2
- package/dashboard/dist/leaderboard.html +2 -2
- package/dashboard/dist/share.html +2 -2
- package/package.json +1 -1
- package/src/commands/status.js +4 -4
- package/src/commands/sync.js +5 -3
- package/src/lib/ark-agent-plan-limits.js +4 -3
- package/src/lib/ark-coding-plan-limits.js +6 -8
- package/src/lib/command-runner.js +13 -0
- package/src/lib/local-api.js +3 -0
- package/src/lib/pricing/seed-snapshot.json +1 -1
- package/src/lib/rollout.js +17 -5
- package/src/lib/usage-limits.js +111 -13
- package/dashboard/dist/assets/DashboardPage-BjYZLmqQ.js +0 -1
- package/dashboard/dist/assets/DialogDescription-KY7X94CG.js +0 -1
- package/dashboard/dist/assets/SettingsPage-DLOHHB4f.js +0 -2
- package/dashboard/dist/assets/__vite-browser-external-4IGm4Djn.js +0 -45
- package/dashboard/dist/assets/__vite-browser-external-CCMdjCX2.css +0 -1
- package/dashboard/dist/assets/use-reduced-motion-D_kUnDs4.js +0 -1
package/src/lib/rollout.js
CHANGED
|
@@ -5841,17 +5841,21 @@ function resolveQoderCnProjectsDir({ home = os.homedir(), env = process.env, pla
|
|
|
5841
5841
|
? path.resolve(env.QODER_CN_PROJECTS_DIR.trim())
|
|
5842
5842
|
: null;
|
|
5843
5843
|
if (override) return override;
|
|
5844
|
-
//
|
|
5845
|
-
//
|
|
5844
|
+
// The new CN app (com.qodercn.app.stable, 2026-08+) keeps its sessions in
|
|
5845
|
+
// ~/.qoder-cn/projects — a sibling of the international ~/.qoder, not a
|
|
5846
|
+
// shared directory. Pointing CN at ~/.qoder/projects made the "CN dir
|
|
5847
|
+
// diverges from international" guards in sync.js/status.js always false,
|
|
5848
|
+
// so new-version CN JSONL usage was silently never parsed (and on
|
|
5849
|
+
// international-only installs would have double-counted under qoder-cn).
|
|
5846
5850
|
if (platform === "win32" && !env.QODER_CN_PROJECTS_DIR) {
|
|
5847
5851
|
const discoverWslHome = deps.discoverWslHome || wsl.discoverWslHome;
|
|
5848
|
-
const wslRoot = wsl.shouldProbeWsl(env) ? discoverWslHome(".qoder", { ...deps, env }) : null;
|
|
5852
|
+
const wslRoot = wsl.shouldProbeWsl(env) ? discoverWslHome(".qoder-cn", { ...deps, env }) : null;
|
|
5849
5853
|
if (wslRoot) {
|
|
5850
5854
|
const wslProjects = path.join(wslRoot, "projects");
|
|
5851
5855
|
if ((deps.existsSync || fssync.existsSync)(wslProjects)) return wslProjects;
|
|
5852
5856
|
}
|
|
5853
5857
|
}
|
|
5854
|
-
return path.join(home, ".qoder", "projects");
|
|
5858
|
+
return path.join(home, ".qoder-cn", "projects");
|
|
5855
5859
|
}
|
|
5856
5860
|
|
|
5857
5861
|
async function listQoderNewSessionFiles(projectsDir) {
|
|
@@ -5876,7 +5880,15 @@ async function listQoderNewSessionFiles(projectsDir) {
|
|
|
5876
5880
|
function qoderNewModelFromRecord(record) {
|
|
5877
5881
|
const msgModel = record?.message?.model;
|
|
5878
5882
|
const direct = typeof msgModel === "string" ? msgModel.trim() : "";
|
|
5879
|
-
|
|
5883
|
+
// CN BYOK routes embed an install-local provider UUID in the model id
|
|
5884
|
+
// ("qoder-custom-<uuid>/glm-5.3-flash"). Keep the bare model id so bucket
|
|
5885
|
+
// keys stay stable across reinstalls and don't fragment per user; official
|
|
5886
|
+
// ids (e.g. "qmodel_38max") have no prefix and pass through unchanged.
|
|
5887
|
+
const stripped = direct.replace(
|
|
5888
|
+
/^qoder-custom-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\//i,
|
|
5889
|
+
"",
|
|
5890
|
+
);
|
|
5891
|
+
return normalizeModelInput(stripped) || "qoder-agent";
|
|
5880
5892
|
}
|
|
5881
5893
|
|
|
5882
5894
|
function qoderNewMessageKey(record, filePath, lineIndex = 0) {
|
package/src/lib/usage-limits.js
CHANGED
|
@@ -2167,10 +2167,19 @@ async function detectAntigravityProcess({
|
|
|
2167
2167
|
);
|
|
2168
2168
|
processes = parseWindowsProcesses(result?.stdout);
|
|
2169
2169
|
} else {
|
|
2170
|
-
|
|
2170
|
+
let result = await runCommand(commandRunner, "/bin/ps", ["-ax", "-o", "pid=,command="], {
|
|
2171
2171
|
timeout: timeoutMs,
|
|
2172
2172
|
signal,
|
|
2173
2173
|
});
|
|
2174
|
+
const isSpawnFailure = result?.error
|
|
2175
|
+
&& result.error.code !== "ETIMEDOUT"
|
|
2176
|
+
&& result.error.name !== "AbortError";
|
|
2177
|
+
if (isSpawnFailure && !result?.stdout) {
|
|
2178
|
+
result = await runCommand(commandRunner, "ps", ["-ax", "-o", "pid=,command="], {
|
|
2179
|
+
timeout: timeoutMs,
|
|
2180
|
+
signal,
|
|
2181
|
+
});
|
|
2182
|
+
}
|
|
2174
2183
|
processes = String(result?.stdout || "")
|
|
2175
2184
|
.split("\n")
|
|
2176
2185
|
.map(parseProcessLine)
|
|
@@ -2633,10 +2642,70 @@ function parseWindowsListeningPorts(output, pid) {
|
|
|
2633
2642
|
return Array.from(ports).sort((a, b) => a - b);
|
|
2634
2643
|
}
|
|
2635
2644
|
|
|
2645
|
+
function parseLinuxProcListeningPorts(pid, { procRoot = "/proc" } = {}) {
|
|
2646
|
+
const numPid = Number(pid);
|
|
2647
|
+
if (!Number.isFinite(numPid) || numPid <= 0) return [];
|
|
2648
|
+
const inodes = new Set();
|
|
2649
|
+
try {
|
|
2650
|
+
const fds = fs.readdirSync(path.join(procRoot, String(numPid), "fd"));
|
|
2651
|
+
for (const fd of fds) {
|
|
2652
|
+
try {
|
|
2653
|
+
const link = fs.readlinkSync(path.join(procRoot, String(numPid), "fd", fd));
|
|
2654
|
+
const m = link.match(/^socket:\[(\d+)\]$/);
|
|
2655
|
+
if (m) inodes.add(m[1]);
|
|
2656
|
+
} catch {}
|
|
2657
|
+
}
|
|
2658
|
+
} catch {
|
|
2659
|
+
return [];
|
|
2660
|
+
}
|
|
2661
|
+
if (inodes.size === 0) return [];
|
|
2662
|
+
|
|
2663
|
+
const ports = new Set();
|
|
2664
|
+
for (const table of [path.join(procRoot, "net", "tcp"), path.join(procRoot, "net", "tcp6")]) {
|
|
2665
|
+
try {
|
|
2666
|
+
const content = fs.readFileSync(table, "utf8");
|
|
2667
|
+
for (const line of content.split("\n")) {
|
|
2668
|
+
const parts = line.trim().split(/\s+/);
|
|
2669
|
+
if (parts.length > 9 && parts[3] === "0A") {
|
|
2670
|
+
const inode = parts[9];
|
|
2671
|
+
if (inodes.has(inode)) {
|
|
2672
|
+
const portHex = parts[1]?.split(":")[1];
|
|
2673
|
+
if (portHex) {
|
|
2674
|
+
const port = parseInt(portHex, 16);
|
|
2675
|
+
if (Number.isInteger(port) && port > 0 && port <= 65535) {
|
|
2676
|
+
ports.add(port);
|
|
2677
|
+
}
|
|
2678
|
+
}
|
|
2679
|
+
}
|
|
2680
|
+
}
|
|
2681
|
+
}
|
|
2682
|
+
} catch {}
|
|
2683
|
+
}
|
|
2684
|
+
return Array.from(ports).sort((a, b) => a - b);
|
|
2685
|
+
}
|
|
2686
|
+
|
|
2687
|
+
function parseSsListeningPorts(output, pid) {
|
|
2688
|
+
const ports = new Set();
|
|
2689
|
+
const pidPattern = pid ? new RegExp(`\\bpid=${pid}\\b`) : null;
|
|
2690
|
+
for (const line of String(output || "").split("\n")) {
|
|
2691
|
+
if (!line.includes("LISTEN")) continue;
|
|
2692
|
+
if (pidPattern && !pidPattern.test(line)) continue;
|
|
2693
|
+
const match = line.match(/:(\d+)\s+/);
|
|
2694
|
+
if (match) {
|
|
2695
|
+
const port = Number(match[1]);
|
|
2696
|
+
if (Number.isInteger(port) && port > 0 && port <= 65535) {
|
|
2697
|
+
ports.add(port);
|
|
2698
|
+
}
|
|
2699
|
+
}
|
|
2700
|
+
}
|
|
2701
|
+
return Array.from(ports).sort((a, b) => a - b);
|
|
2702
|
+
}
|
|
2703
|
+
|
|
2636
2704
|
async function listAntigravityPorts(pid, {
|
|
2637
2705
|
commandRunner,
|
|
2638
2706
|
platform = process.platform,
|
|
2639
2707
|
timeoutMs = ANTIGRAVITY_PROCESS_SCAN_TIMEOUT_MS,
|
|
2708
|
+
procRoot = "/proc",
|
|
2640
2709
|
signal,
|
|
2641
2710
|
} = {}) {
|
|
2642
2711
|
if (platform === "win32") {
|
|
@@ -2652,21 +2721,48 @@ async function listAntigravityPorts(pid, {
|
|
|
2652
2721
|
}
|
|
2653
2722
|
return ports;
|
|
2654
2723
|
}
|
|
2724
|
+
|
|
2725
|
+
// On Linux, try procfs first when no mock command runner is provided (zero-spawn, no dependencies).
|
|
2726
|
+
if (platform === "linux" && !commandRunner) {
|
|
2727
|
+
const procPorts = parseLinuxProcListeningPorts(pid, { procRoot });
|
|
2728
|
+
if (procPorts.length > 0) return procPorts;
|
|
2729
|
+
}
|
|
2730
|
+
|
|
2655
2731
|
const lsof = await resolveLsofBinary({ commandRunner });
|
|
2656
|
-
if (
|
|
2657
|
-
|
|
2732
|
+
if (lsof) {
|
|
2733
|
+
const result = await runCommand(
|
|
2734
|
+
commandRunner,
|
|
2735
|
+
lsof,
|
|
2736
|
+
["-nP", "-iTCP", "-sTCP:LISTEN", "-a", "-p", String(pid)],
|
|
2737
|
+
{ timeout: timeoutMs, signal },
|
|
2738
|
+
);
|
|
2739
|
+
const ports = parseListeningPorts(result?.stdout);
|
|
2740
|
+
if (ports.length > 0) return ports;
|
|
2658
2741
|
}
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2742
|
+
|
|
2743
|
+
// On Linux, fall back to procfs (honoring procRoot) or ss if lsof is absent or yielded no ports.
|
|
2744
|
+
if (platform === "linux") {
|
|
2745
|
+
const procPorts = parseLinuxProcListeningPorts(pid, { procRoot });
|
|
2746
|
+
if (procPorts.length > 0) return procPorts;
|
|
2747
|
+
|
|
2748
|
+
const ss = await whichBinary("ss", { commandRunner });
|
|
2749
|
+
if (ss) {
|
|
2750
|
+
const result = await runCommand(
|
|
2751
|
+
commandRunner,
|
|
2752
|
+
ss,
|
|
2753
|
+
["-H", "-tlpn"],
|
|
2754
|
+
{ timeout: timeoutMs, signal },
|
|
2755
|
+
);
|
|
2756
|
+
const ssPorts = parseSsListeningPorts(result?.stdout, pid);
|
|
2757
|
+
if (ssPorts.length > 0) return ssPorts;
|
|
2758
|
+
}
|
|
2759
|
+
}
|
|
2760
|
+
|
|
2761
|
+
if (!lsof && platform !== "linux") {
|
|
2762
|
+
throw new Error("Antigravity port detection needs lsof. Install it, then retry.");
|
|
2668
2763
|
}
|
|
2669
|
-
|
|
2764
|
+
|
|
2765
|
+
throw new Error("Antigravity is running but not exposing ports yet. Try again in a few seconds.");
|
|
2670
2766
|
}
|
|
2671
2767
|
|
|
2672
2768
|
function antigravityDefaultBody() {
|
|
@@ -3969,6 +4065,8 @@ module.exports = {
|
|
|
3969
4065
|
loadAntigravityCredentials,
|
|
3970
4066
|
parseListeningPorts,
|
|
3971
4067
|
parseWindowsListeningPorts,
|
|
4068
|
+
parseLinuxProcListeningPorts,
|
|
4069
|
+
parseSsListeningPorts,
|
|
3972
4070
|
listAntigravityPorts,
|
|
3973
4071
|
detectAntigravityProcess,
|
|
3974
4072
|
fetchAntigravityLimits,
|