codex-token-tracker-nodejs16 0.2.1 → 0.2.2

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 CHANGED
@@ -7,6 +7,18 @@ and carries **the same version number**, because it is built from the same sourc
7
7
  application itself, see [that package's changelog](https://github.com/CharryLee0426/codex_team_token_tracker/blob/main/packages/menubar/CHANGELOG.md).
8
8
  Entries here cover only what is specific to the Node 16 build.
9
9
 
10
+ ## 0.2.2 — 2026-09-02
11
+
12
+ ### Fixed
13
+
14
+ - **Installing on Node 16 failed when Electron could not be downloaded.** Node 16's npm (8.x) aborts a
15
+ global install when an optional dependency's install script fails, and the retry reported
16
+ `Cannot find module …/codex-token-tracker-nodejs16/node_modules/electron/install.js`. Electron is no longer
17
+ an npm dependency of this package, nor is `menubar` (which pulled it in as a peer) — see the
18
+ [main changelog](https://github.com/CharryLee0426/codex_team_token_tracker/blob/main/packages/menubar/CHANGELOG.md)
19
+ for the mechanics. `npm install -g codex-token-tracker-nodejs16` now installs the same on every machine, and
20
+ the end-to-end test asserts that a plain install pulls in no `electron` package.
21
+
10
22
  ## 0.2.1 — 2026-09-02
11
23
 
12
24
  First release. Feature-identical to `codex-token-tracker` 0.2.1, installable on Node 16.8+.
package/README.md CHANGED
@@ -56,11 +56,17 @@ package back, the Node 16 support lives here:
56
56
 
57
57
  - **Node >= 16.8.** 16.8 is the first release undici's `fetch` supports; 16.20.2 is the last 16.x. Running an
58
58
  older Node prints a clear message instead of a syntax error.
59
- - **Electron is optional.** It is only needed for the menu bar UI, it brings its own modern Node, and it
60
- installs fine under Node 16 (`electron` itself requires only Node >= 12.20). Without a usable Electron or a
61
- display, the app automatically runs headless `codex-tracker agent`which does all the tracking and
62
- uploading. If your OS is too old for Electron 38, install an older one alongside it
63
- (`npm i -g electron@22`); the renderer is built for Chromium 108 so it still works.
59
+ - **Electron is not an npm dependency of this package.** Node 16's npm (8.x) aborts an entire global
60
+ install when an optional dependency's install script fails, so on a machine that could not reach GitHub
61
+ the tracker could not be installed at allnot even for headless use — and the retry died with
62
+ `Cannot find module …/node_modules/electron/install.js`. Since 0.2.2, `npm install -g` never runs
63
+ Electron's installer. On a machine with a display, the first `codex-tracker` (or `codex-tracker menubar`)
64
+ downloads the runtime itself — about 100 MB, once — into `~/.codex-tracker/electron/<version>/`, honouring
65
+ `ELECTRON_MIRROR` (for example `https://npmmirror.com/mirrors/electron/`) and `HTTPS_PROXY`. Without a
66
+ display the app runs headless — `codex-tracker agent` — which does all the tracking and uploading and never
67
+ touches Electron. If your OS is too old for Electron 38, install an older one alongside
68
+ (`npm i -g electron@22`): a globally installed `electron` is picked up first, and the renderer is built for
69
+ Chromium 108 so it still works.
64
70
  - **Hermes SQLite sources are skipped**, because they need `node:sqlite`. This is not a regression: that
65
71
  module only arrived in Node 22.5, so the Node 20 build skips them too.
66
72
  - **Self-update stays on this package.** `codex-tracker update` checks and installs
@@ -90,7 +96,7 @@ pnpm e2e:node16:gui # also downloads Electron (~100 MB) and launches the
90
96
  ```
91
97
 
92
98
  This does what a user does: builds a release, packs a tarball, installs it with **Node 16's own npm**
93
- under `--engine-strict`, and drives the installed binary on a real Node 16 — 35 checks across the
99
+ under `--engine-strict`, and drives the installed binary on a real Node 16 — 36 checks across the
94
100
  polyfill, the CLI surface, the self-updater and a headless agent cycle.
95
101
 
96
102
  The load-bearing assertion is **differential**: the same synthetic Codex fixtures are fed to both the
package/dist/cli.js CHANGED
@@ -1148,7 +1148,7 @@ var APP_VERSION, APP_CHANNEL, IS_DEV_BUILD;
1148
1148
  var init_version = __esm({
1149
1149
  "../menubar/src/version.ts"() {
1150
1150
  "use strict";
1151
- APP_VERSION = true ? "0.2.1" : "0.0.0-dev";
1151
+ APP_VERSION = true ? "0.2.2" : "0.0.0-dev";
1152
1152
  APP_CHANNEL = true ? "prod" : "dev";
1153
1153
  IS_DEV_BUILD = APP_CHANNEL === "dev";
1154
1154
  }
@@ -1498,9 +1498,9 @@ Options:
1498
1498
  cliVersion: "codex-token-tracker {version}",
1499
1499
  cliUnknownCommand: "Unknown command: {command}",
1500
1500
  cliNoDisplay: "No display detected \u2014 starting agent mode (run `codex-tracker menubar` on a desktop).",
1501
- cliNoElectron: "Electron is not installed (optional dependency) \u2014 starting agent mode.",
1501
+ cliNoElectron: "No Electron runtime available \u2014 starting agent mode.",
1502
1502
  cliDownloadingElectron: "Electron runtime not found \u2014 downloading it now (about 100 MB, one time)\u2026",
1503
- cliElectronDownloadFailed: "Electron download failed. Retry with `npm install -g codex-token-tracker --allow-scripts=electron` or `npm rebuild -g electron`; the headless `codex-tracker agent` works without it.",
1503
+ cliElectronDownloadFailed: "Electron download failed. Check the network (set ELECTRON_MIRROR, e.g. https://npmmirror.com/mirrors/electron/, or HTTPS_PROXY) and run `codex-tracker menubar` again; the headless `codex-tracker agent` works without Electron.",
1504
1504
  cliStartingMenubar: "Starting menu bar app\u2026",
1505
1505
  cliLoginStart: "Connecting this device to {dashboard}",
1506
1506
  cliLoginCode: "Your code: {code}",
@@ -1679,9 +1679,9 @@ var init_zh = __esm({
1679
1679
  cliVersion: "codex-token-tracker {version}",
1680
1680
  cliUnknownCommand: "\u672A\u77E5\u547D\u4EE4\uFF1A{command}",
1681
1681
  cliNoDisplay: "\u672A\u68C0\u6D4B\u5230\u663E\u793A\u73AF\u5883 \u2014 \u4EE5 agent \u6A21\u5F0F\u542F\u52A8\uFF08\u684C\u9762\u73AF\u5883\u8BF7\u8FD0\u884C `codex-tracker menubar`\uFF09\u3002",
1682
- cliNoElectron: "\u672A\u5B89\u88C5 Electron\uFF08\u53EF\u9009\u4F9D\u8D56\uFF09\u2014 \u4EE5 agent \u6A21\u5F0F\u542F\u52A8\u3002",
1682
+ cliNoElectron: "\u6CA1\u6709\u53EF\u7528\u7684 Electron \u8FD0\u884C\u65F6 \u2014 \u4EE5 agent \u6A21\u5F0F\u542F\u52A8\u3002",
1683
1683
  cliDownloadingElectron: "\u672A\u627E\u5230 Electron \u8FD0\u884C\u65F6\uFF0C\u6B63\u5728\u4E0B\u8F7D\uFF08\u7EA6 100 MB\uFF0C\u4EC5\u9700\u4E00\u6B21\uFF09\u2026",
1684
- cliElectronDownloadFailed: "Electron \u4E0B\u8F7D\u5931\u8D25\u3002\u53EF\u91CD\u8BD5 `npm install -g codex-token-tracker --allow-scripts=electron` \u6216 `npm rebuild -g electron`\uFF1B\u65E0\u754C\u9762\u7684 `codex-tracker agent` \u65E0\u9700 Electron\u3002",
1684
+ cliElectronDownloadFailed: "Electron \u4E0B\u8F7D\u5931\u8D25\u3002\u8BF7\u68C0\u67E5\u7F51\u7EDC\uFF08\u53EF\u8BBE\u7F6E ELECTRON_MIRROR\uFF0C\u4F8B\u5982 https://npmmirror.com/mirrors/electron/\uFF0C\u6216 HTTPS_PROXY\uFF09\u540E\u518D\u6B21\u8FD0\u884C `codex-tracker menubar`\uFF1B\u65E0\u754C\u9762\u7684 `codex-tracker agent` \u65E0\u9700 Electron\u3002",
1685
1685
  cliStartingMenubar: "\u6B63\u5728\u542F\u52A8\u83DC\u5355\u680F\u5E94\u7528\u2026",
1686
1686
  cliLoginStart: "\u6B63\u5728\u5C06\u672C\u8BBE\u5907\u8FDE\u63A5\u5230 {dashboard}",
1687
1687
  cliLoginCode: "\u4F60\u7684\u4EE3\u7801\uFF1A{code}",
@@ -8905,6 +8905,7 @@ var import_node_fs = __toESM(require("node:fs"));
8905
8905
  var import_node_os = __toESM(require("node:os"));
8906
8906
  var import_node_path = __toESM(require("node:path"));
8907
8907
  var import_node_child_process = require("node:child_process");
8908
+ var DEFAULT_ELECTRON_VERSION = true ? "38.8.6" : "38.8.6";
8908
8909
  function archName() {
8909
8910
  switch (process.arch) {
8910
8911
  case "x64":
@@ -9046,6 +9047,33 @@ async function installElectronBinary(pkgDir, log2) {
9046
9047
  import_node_fs.default.writeFileSync(import_node_path.default.join(pkgDir, "path.txt"), platformExecutablePath());
9047
9048
  return import_node_fs.default.existsSync(exe) ? exe : null;
9048
9049
  }
9050
+ function managedElectronDir(configHome, version2 = DEFAULT_ELECTRON_VERSION) {
9051
+ return import_node_path.default.join(configHome, "electron", version2);
9052
+ }
9053
+ function ensureManagedElectronDir(configHome, version2 = DEFAULT_ELECTRON_VERSION) {
9054
+ const dir = managedElectronDir(configHome, version2);
9055
+ const manifest = import_node_path.default.join(dir, "package.json");
9056
+ let current = null;
9057
+ try {
9058
+ current = JSON.parse(import_node_fs.default.readFileSync(manifest, "utf8")).version ?? null;
9059
+ } catch {
9060
+ }
9061
+ if (current !== version2) {
9062
+ import_node_fs.default.mkdirSync(dir, { recursive: true });
9063
+ import_node_fs.default.writeFileSync(manifest, JSON.stringify({ name: "electron", version: version2, private: true }, null, 2) + "\n");
9064
+ }
9065
+ return dir;
9066
+ }
9067
+ function binaryFromPackageDir(pkgDir) {
9068
+ try {
9069
+ const rel = import_node_fs.default.readFileSync(import_node_path.default.join(pkgDir, "path.txt"), "utf8").trim();
9070
+ if (!rel) return null;
9071
+ const exe = import_node_path.default.join(pkgDir, "dist", rel);
9072
+ return import_node_fs.default.existsSync(exe) ? exe : null;
9073
+ } catch {
9074
+ return null;
9075
+ }
9076
+ }
9049
9077
 
9050
9078
  // ../menubar/src/cli.ts
9051
9079
  init_src();
@@ -10899,10 +10927,10 @@ function applyDashboardFlag(flags) {
10899
10927
  function electronBinary() {
10900
10928
  try {
10901
10929
  const p = require("electron");
10902
- return typeof p === "string" && p && import_node_fs10.default.existsSync(p) ? p : null;
10930
+ if (typeof p === "string" && p && import_node_fs10.default.existsSync(p)) return p;
10903
10931
  } catch {
10904
- return null;
10905
10932
  }
10933
+ return binaryFromPackageDir(managedElectronDir(configDir()));
10906
10934
  }
10907
10935
  function electronPackageDir() {
10908
10936
  try {
@@ -10914,8 +10942,7 @@ function electronPackageDir() {
10914
10942
  async function ensureElectron() {
10915
10943
  const existing = electronBinary();
10916
10944
  if (existing) return existing;
10917
- const dir = electronPackageDir();
10918
- if (!dir) return null;
10945
+ const dir = electronPackageDir() ?? ensureManagedElectronDir(configDir());
10919
10946
  const t2 = makeT(lang());
10920
10947
  console.log(t2("cliDownloadingElectron"));
10921
10948
  const log2 = { info: (m) => console.log(m), error: (m) => console.error(m) };
package/dist/main.js CHANGED
@@ -6,6 +6,13 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __getProtoOf = Object.getPrototypeOf;
8
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __commonJS = (cb, mod) => function __require2() {
10
+ try {
11
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
12
+ } catch (e) {
13
+ throw mod = 0, e;
14
+ }
15
+ };
9
16
  var __copyProps = (to, from, except, desc) => {
10
17
  if (from && typeof from === "object" || typeof from === "function") {
11
18
  for (let key of __getOwnPropNames(from))
@@ -23,13 +30,691 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
23
30
  mod
24
31
  ));
25
32
 
33
+ // ../../node_modules/.pnpm/electron-positioner@4.1.0/node_modules/electron-positioner/index.js
34
+ var require_electron_positioner = __commonJS({
35
+ "../../node_modules/.pnpm/electron-positioner@4.1.0/node_modules/electron-positioner/index.js"(exports2, module2) {
36
+ "use strict";
37
+ module2.exports = class Positioner {
38
+ constructor(browserWindow) {
39
+ this.browserWindow = browserWindow;
40
+ this.electronScreen = require("electron").screen;
41
+ }
42
+ _getCoords(position, trayPosition) {
43
+ let screenSize = this._getScreenSize(trayPosition);
44
+ let windowSize = this._getWindowSize();
45
+ if (trayPosition === void 0) trayPosition = {};
46
+ let positions = {
47
+ trayLeft: {
48
+ x: Math.floor(trayPosition.x),
49
+ y: screenSize.y
50
+ },
51
+ trayBottomLeft: {
52
+ x: Math.floor(trayPosition.x),
53
+ y: Math.floor(screenSize.height - (windowSize[1] - screenSize.y))
54
+ },
55
+ trayRight: {
56
+ x: Math.floor(trayPosition.x - windowSize[0] + trayPosition.width),
57
+ y: screenSize.y
58
+ },
59
+ trayBottomRight: {
60
+ x: Math.floor(trayPosition.x - windowSize[0] + trayPosition.width),
61
+ y: Math.floor(screenSize.height - (windowSize[1] - screenSize.y))
62
+ },
63
+ trayCenter: {
64
+ x: Math.floor(trayPosition.x - windowSize[0] / 2 + trayPosition.width / 2),
65
+ y: screenSize.y
66
+ },
67
+ trayBottomCenter: {
68
+ x: Math.floor(trayPosition.x - windowSize[0] / 2 + trayPosition.width / 2),
69
+ y: Math.floor(screenSize.height - (windowSize[1] - screenSize.y))
70
+ },
71
+ topLeft: {
72
+ x: screenSize.x,
73
+ y: screenSize.y
74
+ },
75
+ topRight: {
76
+ x: Math.floor(screenSize.x + (screenSize.width - windowSize[0])),
77
+ y: screenSize.y
78
+ },
79
+ bottomLeft: {
80
+ x: screenSize.x,
81
+ y: Math.floor(screenSize.height - (windowSize[1] - screenSize.y))
82
+ },
83
+ bottomRight: {
84
+ x: Math.floor(screenSize.x + (screenSize.width - windowSize[0])),
85
+ y: Math.floor(screenSize.height - (windowSize[1] - screenSize.y))
86
+ },
87
+ topCenter: {
88
+ x: Math.floor(screenSize.x + (screenSize.width / 2 - windowSize[0] / 2)),
89
+ y: screenSize.y
90
+ },
91
+ bottomCenter: {
92
+ x: Math.floor(screenSize.x + (screenSize.width / 2 - windowSize[0] / 2)),
93
+ y: Math.floor(screenSize.height - (windowSize[1] - screenSize.y))
94
+ },
95
+ leftCenter: {
96
+ x: screenSize.x,
97
+ y: screenSize.y + Math.floor(screenSize.height / 2) - Math.floor(windowSize[1] / 2)
98
+ },
99
+ rightCenter: {
100
+ x: Math.floor(screenSize.x + (screenSize.width - windowSize[0])),
101
+ y: screenSize.y + Math.floor(screenSize.height / 2) - Math.floor(windowSize[1] / 2)
102
+ },
103
+ center: {
104
+ x: Math.floor(screenSize.x + (screenSize.width / 2 - windowSize[0] / 2)),
105
+ y: Math.floor((screenSize.height + screenSize.y) / 2 - windowSize[1] / 2)
106
+ }
107
+ };
108
+ if (position.substr(0, 4) === "tray") {
109
+ if (positions[position].x + windowSize[0] > screenSize.width + screenSize.x) {
110
+ return {
111
+ x: positions["topRight"].x,
112
+ y: positions[position].y
113
+ };
114
+ }
115
+ }
116
+ return positions[position];
117
+ }
118
+ _getWindowSize() {
119
+ return this.browserWindow.getSize();
120
+ }
121
+ _getScreenSize(trayPosition) {
122
+ if (trayPosition) {
123
+ return this.electronScreen.getDisplayMatching(trayPosition).workArea;
124
+ } else {
125
+ return this.electronScreen.getDisplayNearestPoint(this.electronScreen.getCursorScreenPoint()).workArea;
126
+ }
127
+ }
128
+ move(position, trayPos) {
129
+ var coords = this._getCoords(position, trayPos);
130
+ this.browserWindow.setPosition(coords.x, coords.y);
131
+ }
132
+ calculate(position, trayPos) {
133
+ var coords = this._getCoords(position, trayPos);
134
+ return {
135
+ x: coords.x,
136
+ y: coords.y
137
+ };
138
+ }
139
+ };
140
+ }
141
+ });
142
+
143
+ // ../../node_modules/.pnpm/menubar@9.5.3_electron@38.8.6/node_modules/menubar/lib/util/cleanOptions.js
144
+ var require_cleanOptions = __commonJS({
145
+ "../../node_modules/.pnpm/menubar@9.5.3_electron@38.8.6/node_modules/menubar/lib/util/cleanOptions.js"(exports2) {
146
+ "use strict";
147
+ var __assign = exports2 && exports2.__assign || function() {
148
+ __assign = Object.assign || function(t2) {
149
+ for (var s, i2 = 1, n = arguments.length; i2 < n; i2++) {
150
+ s = arguments[i2];
151
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
152
+ t2[p] = s[p];
153
+ }
154
+ return t2;
155
+ };
156
+ return __assign.apply(this, arguments);
157
+ };
158
+ var __importDefault = exports2 && exports2.__importDefault || function(mod) {
159
+ return mod && mod.__esModule ? mod : { "default": mod };
160
+ };
161
+ Object.defineProperty(exports2, "__esModule", { value: true });
162
+ exports2.cleanOptions = void 0;
163
+ var path_1 = __importDefault(require("path"));
164
+ var url_1 = __importDefault(require("url"));
165
+ var electron_1 = require("electron");
166
+ var DEFAULT_WINDOW_HEIGHT = 400;
167
+ var DEFAULT_WINDOW_WIDTH = 400;
168
+ function cleanOptions(opts) {
169
+ var options = __assign({}, opts);
170
+ if (options.activateWithApp === void 0) {
171
+ options.activateWithApp = true;
172
+ }
173
+ if (!options.dir) {
174
+ options.dir = electron_1.app.getAppPath();
175
+ }
176
+ if (!path_1.default.isAbsolute(options.dir)) {
177
+ options.dir = path_1.default.resolve(options.dir);
178
+ }
179
+ if (options.index === void 0) {
180
+ options.index = url_1.default.format({
181
+ pathname: path_1.default.join(options.dir, "index.html"),
182
+ protocol: "file:",
183
+ slashes: true
184
+ });
185
+ }
186
+ options.loadUrlOptions = options.loadUrlOptions || {};
187
+ options.tooltip = options.tooltip || "";
188
+ if (!options.browserWindow) {
189
+ options.browserWindow = {};
190
+ }
191
+ options.browserWindow.width = // Note: not using `options.browserWindow.width || DEFAULT_WINDOW_WIDTH` so
192
+ // that users can put a 0 width
193
+ options.browserWindow.width !== void 0 ? options.browserWindow.width : DEFAULT_WINDOW_WIDTH;
194
+ options.browserWindow.height = options.browserWindow.height !== void 0 ? options.browserWindow.height : DEFAULT_WINDOW_HEIGHT;
195
+ return options;
196
+ }
197
+ exports2.cleanOptions = cleanOptions;
198
+ }
199
+ });
200
+
201
+ // ../../node_modules/.pnpm/menubar@9.5.3_electron@38.8.6/node_modules/menubar/lib/util/getWindowPosition.js
202
+ var require_getWindowPosition = __commonJS({
203
+ "../../node_modules/.pnpm/menubar@9.5.3_electron@38.8.6/node_modules/menubar/lib/util/getWindowPosition.js"(exports2) {
204
+ "use strict";
205
+ Object.defineProperty(exports2, "__esModule", { value: true });
206
+ exports2.getWindowPosition = exports2.taskbarLocation = void 0;
207
+ var electron_1 = require("electron");
208
+ var isLinux = process.platform === "linux";
209
+ var trayToScreenRects = function(tray) {
210
+ var _a2 = electron_1.screen.getDisplayMatching(tray.getBounds()), workArea = _a2.workArea, screenBounds = _a2.bounds;
211
+ workArea.x -= screenBounds.x;
212
+ workArea.y -= screenBounds.y;
213
+ return [screenBounds, workArea];
214
+ };
215
+ function taskbarLocation(tray) {
216
+ var _a2 = trayToScreenRects(tray), screenBounds = _a2[0], workArea = _a2[1];
217
+ if (workArea.x > 0) {
218
+ if (isLinux && workArea.y > 0)
219
+ return "top";
220
+ return "left";
221
+ }
222
+ if (workArea.y > 0) {
223
+ return "top";
224
+ }
225
+ if (workArea.width < screenBounds.width) {
226
+ return "right";
227
+ }
228
+ return "bottom";
229
+ }
230
+ exports2.taskbarLocation = taskbarLocation;
231
+ function getWindowPosition(tray) {
232
+ switch (process.platform) {
233
+ // macOS
234
+ // Supports top taskbars
235
+ case "darwin":
236
+ return "trayCenter";
237
+ // Linux
238
+ // Windows
239
+ // Supports top/bottom/left/right taskbar
240
+ case "linux":
241
+ case "win32": {
242
+ var traySide = taskbarLocation(tray);
243
+ if (traySide === "top") {
244
+ return isLinux ? "topRight" : "trayCenter";
245
+ }
246
+ if (traySide === "bottom") {
247
+ return "bottomRight";
248
+ }
249
+ if (traySide === "left") {
250
+ return "bottomLeft";
251
+ }
252
+ if (traySide === "right") {
253
+ return "bottomRight";
254
+ }
255
+ }
256
+ }
257
+ return "topRight";
258
+ }
259
+ exports2.getWindowPosition = getWindowPosition;
260
+ }
261
+ });
262
+
263
+ // ../../node_modules/.pnpm/menubar@9.5.3_electron@38.8.6/node_modules/menubar/lib/Menubar.js
264
+ var require_Menubar = __commonJS({
265
+ "../../node_modules/.pnpm/menubar@9.5.3_electron@38.8.6/node_modules/menubar/lib/Menubar.js"(exports2) {
266
+ "use strict";
267
+ var __extends = exports2 && exports2.__extends || /* @__PURE__ */ (function() {
268
+ var extendStatics = function(d, b) {
269
+ extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) {
270
+ d2.__proto__ = b2;
271
+ } || function(d2, b2) {
272
+ for (var p in b2) if (Object.prototype.hasOwnProperty.call(b2, p)) d2[p] = b2[p];
273
+ };
274
+ return extendStatics(d, b);
275
+ };
276
+ return function(d, b) {
277
+ if (typeof b !== "function" && b !== null)
278
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
279
+ extendStatics(d, b);
280
+ function __() {
281
+ this.constructor = d;
282
+ }
283
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
284
+ };
285
+ })();
286
+ var __assign = exports2 && exports2.__assign || function() {
287
+ __assign = Object.assign || function(t2) {
288
+ for (var s, i2 = 1, n = arguments.length; i2 < n; i2++) {
289
+ s = arguments[i2];
290
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
291
+ t2[p] = s[p];
292
+ }
293
+ return t2;
294
+ };
295
+ return __assign.apply(this, arguments);
296
+ };
297
+ var __awaiter = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) {
298
+ function adopt(value) {
299
+ return value instanceof P ? value : new P(function(resolve) {
300
+ resolve(value);
301
+ });
302
+ }
303
+ return new (P || (P = Promise))(function(resolve, reject) {
304
+ function fulfilled(value) {
305
+ try {
306
+ step(generator.next(value));
307
+ } catch (e) {
308
+ reject(e);
309
+ }
310
+ }
311
+ function rejected(value) {
312
+ try {
313
+ step(generator["throw"](value));
314
+ } catch (e) {
315
+ reject(e);
316
+ }
317
+ }
318
+ function step(result) {
319
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
320
+ }
321
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
322
+ });
323
+ };
324
+ var __generator = exports2 && exports2.__generator || function(thisArg, body) {
325
+ var _ = { label: 0, sent: function() {
326
+ if (t2[0] & 1) throw t2[1];
327
+ return t2[1];
328
+ }, trys: [], ops: [] }, f, y, t2, g;
329
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
330
+ return this;
331
+ }), g;
332
+ function verb(n) {
333
+ return function(v2) {
334
+ return step([n, v2]);
335
+ };
336
+ }
337
+ function step(op) {
338
+ if (f) throw new TypeError("Generator is already executing.");
339
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
340
+ if (f = 1, y && (t2 = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t2 = y["return"]) && t2.call(y), 0) : y.next) && !(t2 = t2.call(y, op[1])).done) return t2;
341
+ if (y = 0, t2) op = [op[0] & 2, t2.value];
342
+ switch (op[0]) {
343
+ case 0:
344
+ case 1:
345
+ t2 = op;
346
+ break;
347
+ case 4:
348
+ _.label++;
349
+ return { value: op[1], done: false };
350
+ case 5:
351
+ _.label++;
352
+ y = op[1];
353
+ op = [0];
354
+ continue;
355
+ case 7:
356
+ op = _.ops.pop();
357
+ _.trys.pop();
358
+ continue;
359
+ default:
360
+ if (!(t2 = _.trys, t2 = t2.length > 0 && t2[t2.length - 1]) && (op[0] === 6 || op[0] === 2)) {
361
+ _ = 0;
362
+ continue;
363
+ }
364
+ if (op[0] === 3 && (!t2 || op[1] > t2[0] && op[1] < t2[3])) {
365
+ _.label = op[1];
366
+ break;
367
+ }
368
+ if (op[0] === 6 && _.label < t2[1]) {
369
+ _.label = t2[1];
370
+ t2 = op;
371
+ break;
372
+ }
373
+ if (t2 && _.label < t2[2]) {
374
+ _.label = t2[2];
375
+ _.ops.push(op);
376
+ break;
377
+ }
378
+ if (t2[2]) _.ops.pop();
379
+ _.trys.pop();
380
+ continue;
381
+ }
382
+ op = body.call(thisArg, _);
383
+ } catch (e) {
384
+ op = [6, e];
385
+ y = 0;
386
+ } finally {
387
+ f = t2 = 0;
388
+ }
389
+ if (op[0] & 5) throw op[1];
390
+ return { value: op[0] ? op[1] : void 0, done: true };
391
+ }
392
+ };
393
+ var __importDefault = exports2 && exports2.__importDefault || function(mod) {
394
+ return mod && mod.__esModule ? mod : { "default": mod };
395
+ };
396
+ Object.defineProperty(exports2, "__esModule", { value: true });
397
+ exports2.Menubar = void 0;
398
+ var events_1 = require("events");
399
+ var fs_1 = __importDefault(require("fs"));
400
+ var path_1 = __importDefault(require("path"));
401
+ var electron_1 = require("electron");
402
+ var electron_positioner_1 = __importDefault(require_electron_positioner());
403
+ var cleanOptions_1 = require_cleanOptions();
404
+ var getWindowPosition_1 = require_getWindowPosition();
405
+ var Menubar = (
406
+ /** @class */
407
+ (function(_super) {
408
+ __extends(Menubar2, _super);
409
+ function Menubar2(app2, options) {
410
+ var _this = _super.call(this) || this;
411
+ _this._blurTimeout = null;
412
+ _this._app = app2;
413
+ _this._options = (0, cleanOptions_1.cleanOptions)(options);
414
+ _this._isVisible = false;
415
+ if (app2.isReady()) {
416
+ process.nextTick(function() {
417
+ return _this.appReady().catch(function(err) {
418
+ return console.error("menubar: ", err);
419
+ });
420
+ });
421
+ } else {
422
+ app2.on("ready", function() {
423
+ _this.appReady().catch(function(err) {
424
+ return console.error("menubar: ", err);
425
+ });
426
+ });
427
+ }
428
+ return _this;
429
+ }
430
+ Object.defineProperty(Menubar2.prototype, "app", {
431
+ /**
432
+ * The Electron [App](https://electronjs.org/docs/api/app)
433
+ * instance.
434
+ */
435
+ get: function() {
436
+ return this._app;
437
+ },
438
+ enumerable: false,
439
+ configurable: true
440
+ });
441
+ Object.defineProperty(Menubar2.prototype, "positioner", {
442
+ /**
443
+ * The [electron-positioner](https://github.com/jenslind/electron-positioner)
444
+ * instance.
445
+ */
446
+ get: function() {
447
+ if (!this._positioner) {
448
+ throw new Error("Please access `this.positioner` after the `after-create-window` event has fired.");
449
+ }
450
+ return this._positioner;
451
+ },
452
+ enumerable: false,
453
+ configurable: true
454
+ });
455
+ Object.defineProperty(Menubar2.prototype, "tray", {
456
+ /**
457
+ * The Electron [Tray](https://electronjs.org/docs/api/tray) instance.
458
+ */
459
+ get: function() {
460
+ if (!this._tray) {
461
+ throw new Error("Please access `this.tray` after the `ready` event has fired.");
462
+ }
463
+ return this._tray;
464
+ },
465
+ enumerable: false,
466
+ configurable: true
467
+ });
468
+ Object.defineProperty(Menubar2.prototype, "window", {
469
+ /**
470
+ * The Electron [BrowserWindow](https://electronjs.org/docs/api/browser-window)
471
+ * instance, if it's present.
472
+ */
473
+ get: function() {
474
+ return this._browserWindow;
475
+ },
476
+ enumerable: false,
477
+ configurable: true
478
+ });
479
+ Menubar2.prototype.getOption = function(key) {
480
+ return this._options[key];
481
+ };
482
+ Menubar2.prototype.hideWindow = function() {
483
+ if (!this._browserWindow || !this._isVisible) {
484
+ return;
485
+ }
486
+ this.emit("hide");
487
+ this._browserWindow.hide();
488
+ this.emit("after-hide");
489
+ this._isVisible = false;
490
+ if (this._blurTimeout) {
491
+ clearTimeout(this._blurTimeout);
492
+ this._blurTimeout = null;
493
+ }
494
+ };
495
+ Menubar2.prototype.setOption = function(key, value) {
496
+ this._options[key] = value;
497
+ };
498
+ Menubar2.prototype.showWindow = function(trayPos) {
499
+ return __awaiter(this, void 0, void 0, function() {
500
+ var noBoundsPosition, position, x, y;
501
+ return __generator(this, function(_a2) {
502
+ switch (_a2.label) {
503
+ case 0:
504
+ if (!this.tray) {
505
+ throw new Error("Tray should have been instantiated by now");
506
+ }
507
+ if (!!this._browserWindow) return [3, 2];
508
+ return [4, this.createWindow()];
509
+ case 1:
510
+ _a2.sent();
511
+ _a2.label = 2;
512
+ case 2:
513
+ if (!this._browserWindow) {
514
+ throw new Error("Window has been initialized just above. qed.");
515
+ }
516
+ if (["win32", "linux"].includes(process.platform)) {
517
+ this._options.windowPosition = (0, getWindowPosition_1.getWindowPosition)(this.tray);
518
+ }
519
+ this.emit("show");
520
+ if (trayPos && trayPos.x !== 0) {
521
+ this._cachedBounds = trayPos;
522
+ } else if (this._cachedBounds) {
523
+ trayPos = this._cachedBounds;
524
+ } else if (this.tray.getBounds) {
525
+ trayPos = this.tray.getBounds();
526
+ }
527
+ noBoundsPosition = void 0;
528
+ if ((trayPos === void 0 || trayPos.x === 0) && this._options.windowPosition && this._options.windowPosition.startsWith("tray")) {
529
+ noBoundsPosition = process.platform === "win32" ? "bottomRight" : "topRight";
530
+ }
531
+ position = this.positioner.calculate(this._options.windowPosition || noBoundsPosition, trayPos);
532
+ x = this._options.browserWindow.x !== void 0 ? this._options.browserWindow.x : position.x;
533
+ y = this._options.browserWindow.y !== void 0 ? this._options.browserWindow.y : position.y;
534
+ this._browserWindow.setPosition(Math.round(x), Math.round(y));
535
+ this._browserWindow.show();
536
+ this._isVisible = true;
537
+ this.emit("after-show");
538
+ return [
539
+ 2
540
+ /*return*/
541
+ ];
542
+ }
543
+ });
544
+ });
545
+ };
546
+ Menubar2.prototype.appReady = function() {
547
+ return __awaiter(this, void 0, void 0, function() {
548
+ var trayImage, defaultClickEvent;
549
+ var _this = this;
550
+ return __generator(this, function(_a2) {
551
+ switch (_a2.label) {
552
+ case 0:
553
+ if (this.app.dock && !this._options.showDockIcon) {
554
+ this.app.dock.hide();
555
+ }
556
+ if (this._options.activateWithApp) {
557
+ this.app.on("activate", function(_event, hasVisibleWindows) {
558
+ if (!hasVisibleWindows) {
559
+ _this.showWindow().catch(console.error);
560
+ }
561
+ });
562
+ }
563
+ trayImage = this._options.icon || path_1.default.join(this._options.dir, "IconTemplate.png");
564
+ if (typeof trayImage === "string" && !fs_1.default.existsSync(trayImage)) {
565
+ trayImage = path_1.default.join(__dirname, "..", "assets", "IconTemplate.png");
566
+ }
567
+ defaultClickEvent = this._options.showOnRightClick ? "right-click" : "click";
568
+ this._tray = this._options.tray || new electron_1.Tray(trayImage);
569
+ if (!this.tray) {
570
+ throw new Error("Tray has been initialized above");
571
+ }
572
+ this.tray.on(defaultClickEvent, this.clicked.bind(this));
573
+ this.tray.on("double-click", this.clicked.bind(this));
574
+ this.tray.setToolTip(this._options.tooltip);
575
+ if (!this._options.windowPosition) {
576
+ this._options.windowPosition = (0, getWindowPosition_1.getWindowPosition)(this.tray);
577
+ }
578
+ if (!this._options.preloadWindow) return [3, 2];
579
+ return [4, this.createWindow()];
580
+ case 1:
581
+ _a2.sent();
582
+ _a2.label = 2;
583
+ case 2:
584
+ this.emit("ready");
585
+ return [
586
+ 2
587
+ /*return*/
588
+ ];
589
+ }
590
+ });
591
+ });
592
+ };
593
+ Menubar2.prototype.clicked = function(event, bounds) {
594
+ return __awaiter(this, void 0, void 0, function() {
595
+ return __generator(this, function(_a2) {
596
+ switch (_a2.label) {
597
+ case 0:
598
+ if (event && (event.shiftKey || event.ctrlKey || event.metaKey)) {
599
+ return [2, this.hideWindow()];
600
+ }
601
+ if (this._blurTimeout) {
602
+ clearInterval(this._blurTimeout);
603
+ }
604
+ if (this._browserWindow && this._isVisible) {
605
+ return [2, this.hideWindow()];
606
+ }
607
+ this._cachedBounds = bounds || this._cachedBounds;
608
+ return [4, this.showWindow(this._cachedBounds)];
609
+ case 1:
610
+ _a2.sent();
611
+ return [
612
+ 2
613
+ /*return*/
614
+ ];
615
+ }
616
+ });
617
+ });
618
+ };
619
+ Menubar2.prototype.createWindow = function() {
620
+ return __awaiter(this, void 0, void 0, function() {
621
+ var defaults;
622
+ var _this = this;
623
+ return __generator(this, function(_a2) {
624
+ switch (_a2.label) {
625
+ case 0:
626
+ this.emit("create-window");
627
+ defaults = {
628
+ show: false,
629
+ frame: false
630
+ // Remove window frame
631
+ };
632
+ this._browserWindow = new electron_1.BrowserWindow(__assign(__assign({}, defaults), this._options.browserWindow));
633
+ this._positioner = new electron_positioner_1.default(this._browserWindow);
634
+ this._browserWindow.on("blur", function() {
635
+ if (!_this._browserWindow) {
636
+ return;
637
+ }
638
+ _this._browserWindow.isAlwaysOnTop() ? _this.emit("focus-lost") : _this._blurTimeout = setTimeout(function() {
639
+ _this.hideWindow();
640
+ }, 100);
641
+ });
642
+ if (this._options.showOnAllWorkspaces !== false) {
643
+ this._browserWindow.setVisibleOnAllWorkspaces(true, {
644
+ skipTransformProcessType: true
645
+ // Avoid damaging the original visible state of app.dock
646
+ });
647
+ }
648
+ this._browserWindow.on("close", this.windowClear.bind(this));
649
+ this.emit("before-load");
650
+ if (!(this._options.index !== false)) return [3, 2];
651
+ return [4, this._browserWindow.loadURL(this._options.index, this._options.loadUrlOptions)];
652
+ case 1:
653
+ _a2.sent();
654
+ _a2.label = 2;
655
+ case 2:
656
+ this.emit("after-create-window");
657
+ return [
658
+ 2
659
+ /*return*/
660
+ ];
661
+ }
662
+ });
663
+ });
664
+ };
665
+ Menubar2.prototype.windowClear = function() {
666
+ this._browserWindow = void 0;
667
+ this.emit("after-close");
668
+ };
669
+ return Menubar2;
670
+ })(events_1.EventEmitter)
671
+ );
672
+ exports2.Menubar = Menubar;
673
+ }
674
+ });
675
+
676
+ // ../../node_modules/.pnpm/menubar@9.5.3_electron@38.8.6/node_modules/menubar/lib/index.js
677
+ var require_lib = __commonJS({
678
+ "../../node_modules/.pnpm/menubar@9.5.3_electron@38.8.6/node_modules/menubar/lib/index.js"(exports2) {
679
+ "use strict";
680
+ var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
681
+ if (k2 === void 0) k2 = k;
682
+ var desc = Object.getOwnPropertyDescriptor(m, k);
683
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
684
+ desc = { enumerable: true, get: function() {
685
+ return m[k];
686
+ } };
687
+ }
688
+ Object.defineProperty(o, k2, desc);
689
+ }) : (function(o, m, k, k2) {
690
+ if (k2 === void 0) k2 = k;
691
+ o[k2] = m[k];
692
+ }));
693
+ var __exportStar = exports2 && exports2.__exportStar || function(m, exports3) {
694
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
695
+ };
696
+ Object.defineProperty(exports2, "__esModule", { value: true });
697
+ exports2.menubar = exports2.Menubar = void 0;
698
+ var electron_1 = require("electron");
699
+ var Menubar_1 = require_Menubar();
700
+ Object.defineProperty(exports2, "Menubar", { enumerable: true, get: function() {
701
+ return Menubar_1.Menubar;
702
+ } });
703
+ __exportStar(require_getWindowPosition(), exports2);
704
+ function menubar2(options) {
705
+ return new Menubar_1.Menubar(electron_1.app, options);
706
+ }
707
+ exports2.menubar = menubar2;
708
+ }
709
+ });
710
+
26
711
  // ../menubar/src/main.ts
27
712
  var import_electron = require("electron");
28
713
  var import_node_fs9 = __toESM(require("node:fs"));
29
714
  var import_node_os7 = __toESM(require("node:os"));
30
715
  var import_node_path11 = __toESM(require("node:path"));
31
716
  var import_node_child_process4 = require("node:child_process");
32
- var import_menubar = require("menubar");
717
+ var import_menubar = __toESM(require_lib());
33
718
 
34
719
  // ../shared/src/usage.ts
35
720
  function emptyUsage() {
@@ -1049,7 +1734,7 @@ var import_node_os = __toESM(require("node:os"));
1049
1734
  var import_node_path = __toESM(require("node:path"));
1050
1735
 
1051
1736
  // ../menubar/src/version.ts
1052
- var APP_VERSION = true ? "0.2.1" : "0.0.0-dev";
1737
+ var APP_VERSION = true ? "0.2.2" : "0.0.0-dev";
1053
1738
  var APP_CHANNEL = true ? "prod" : "dev";
1054
1739
  var IS_DEV_BUILD = APP_CHANNEL === "dev";
1055
1740
  var APP_NAME = IS_DEV_BUILD ? "Codex Tracker (dev)" : "Codex Tracker";
@@ -1327,9 +2012,9 @@ Options:
1327
2012
  cliVersion: "codex-token-tracker {version}",
1328
2013
  cliUnknownCommand: "Unknown command: {command}",
1329
2014
  cliNoDisplay: "No display detected \u2014 starting agent mode (run `codex-tracker menubar` on a desktop).",
1330
- cliNoElectron: "Electron is not installed (optional dependency) \u2014 starting agent mode.",
2015
+ cliNoElectron: "No Electron runtime available \u2014 starting agent mode.",
1331
2016
  cliDownloadingElectron: "Electron runtime not found \u2014 downloading it now (about 100 MB, one time)\u2026",
1332
- cliElectronDownloadFailed: "Electron download failed. Retry with `npm install -g codex-token-tracker --allow-scripts=electron` or `npm rebuild -g electron`; the headless `codex-tracker agent` works without it.",
2017
+ cliElectronDownloadFailed: "Electron download failed. Check the network (set ELECTRON_MIRROR, e.g. https://npmmirror.com/mirrors/electron/, or HTTPS_PROXY) and run `codex-tracker menubar` again; the headless `codex-tracker agent` works without Electron.",
1333
2018
  cliStartingMenubar: "Starting menu bar app\u2026",
1334
2019
  cliLoginStart: "Connecting this device to {dashboard}",
1335
2020
  cliLoginCode: "Your code: {code}",
@@ -1502,9 +2187,9 @@ var zh = {
1502
2187
  cliVersion: "codex-token-tracker {version}",
1503
2188
  cliUnknownCommand: "\u672A\u77E5\u547D\u4EE4\uFF1A{command}",
1504
2189
  cliNoDisplay: "\u672A\u68C0\u6D4B\u5230\u663E\u793A\u73AF\u5883 \u2014 \u4EE5 agent \u6A21\u5F0F\u542F\u52A8\uFF08\u684C\u9762\u73AF\u5883\u8BF7\u8FD0\u884C `codex-tracker menubar`\uFF09\u3002",
1505
- cliNoElectron: "\u672A\u5B89\u88C5 Electron\uFF08\u53EF\u9009\u4F9D\u8D56\uFF09\u2014 \u4EE5 agent \u6A21\u5F0F\u542F\u52A8\u3002",
2190
+ cliNoElectron: "\u6CA1\u6709\u53EF\u7528\u7684 Electron \u8FD0\u884C\u65F6 \u2014 \u4EE5 agent \u6A21\u5F0F\u542F\u52A8\u3002",
1506
2191
  cliDownloadingElectron: "\u672A\u627E\u5230 Electron \u8FD0\u884C\u65F6\uFF0C\u6B63\u5728\u4E0B\u8F7D\uFF08\u7EA6 100 MB\uFF0C\u4EC5\u9700\u4E00\u6B21\uFF09\u2026",
1507
- cliElectronDownloadFailed: "Electron \u4E0B\u8F7D\u5931\u8D25\u3002\u53EF\u91CD\u8BD5 `npm install -g codex-token-tracker --allow-scripts=electron` \u6216 `npm rebuild -g electron`\uFF1B\u65E0\u754C\u9762\u7684 `codex-tracker agent` \u65E0\u9700 Electron\u3002",
2192
+ cliElectronDownloadFailed: "Electron \u4E0B\u8F7D\u5931\u8D25\u3002\u8BF7\u68C0\u67E5\u7F51\u7EDC\uFF08\u53EF\u8BBE\u7F6E ELECTRON_MIRROR\uFF0C\u4F8B\u5982 https://npmmirror.com/mirrors/electron/\uFF0C\u6216 HTTPS_PROXY\uFF09\u540E\u518D\u6B21\u8FD0\u884C `codex-tracker menubar`\uFF1B\u65E0\u754C\u9762\u7684 `codex-tracker agent` \u65E0\u9700 Electron\u3002",
1508
2193
  cliStartingMenubar: "\u6B63\u5728\u542F\u52A8\u83DC\u5355\u680F\u5E94\u7528\u2026",
1509
2194
  cliLoginStart: "\u6B63\u5728\u5C06\u672C\u8BBE\u5907\u8FDE\u63A5\u5230 {dashboard}",
1510
2195
  cliLoginCode: "\u4F60\u7684\u4EE3\u7801\uFF1A{code}",
@@ -4168,7 +4853,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require2 !== "undefined" ? requir
4168
4853
  if (typeof require2 !== "undefined") return require2.apply(this, arguments);
4169
4854
  throw Error('Dynamic require of "' + x + '" is not supported');
4170
4855
  });
4171
- var __commonJS = (cb, mod) => function __require2() {
4856
+ var __commonJS2 = (cb, mod) => function __require2() {
4172
4857
  return mod || (0, cb[__getOwnPropNames2(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
4173
4858
  };
4174
4859
  var __copyProps2 = (to, from, except, desc) => {
@@ -4187,7 +4872,7 @@ var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__
4187
4872
  isNodeMode || !mod || !mod.__esModule ? __defProp6(target, "default", { value: mod, enumerable: true }) : target,
4188
4873
  mod
4189
4874
  ));
4190
- var require_constants = __commonJS({
4875
+ var require_constants = __commonJS2({
4191
4876
  "../node_modules/.pnpm/ws@8.21.0_bufferutil@4.0.9/node_modules/ws/lib/constants.js"(exports2, module2) {
4192
4877
  "use strict";
4193
4878
  var BINARY_TYPES = ["nodebuffer", "arraybuffer", "fragments"];
@@ -4208,7 +4893,7 @@ var require_constants = __commonJS({
4208
4893
  };
4209
4894
  }
4210
4895
  });
4211
- var require_node_gyp_build = __commonJS({
4896
+ var require_node_gyp_build = __commonJS2({
4212
4897
  "../node_modules/.pnpm/node-gyp-build@4.8.4/node_modules/node-gyp-build/node-gyp-build.js"(exports2, module2) {
4213
4898
  var fs10 = __require("fs");
4214
4899
  var path12 = __require("path");
@@ -4375,7 +5060,7 @@ var require_node_gyp_build = __commonJS({
4375
5060
  load.compareTuples = compareTuples;
4376
5061
  }
4377
5062
  });
4378
- var require_node_gyp_build2 = __commonJS({
5063
+ var require_node_gyp_build2 = __commonJS2({
4379
5064
  "../node_modules/.pnpm/node-gyp-build@4.8.4/node_modules/node-gyp-build/index.js"(exports2, module2) {
4380
5065
  var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
4381
5066
  if (typeof runtimeRequire.addon === "function") {
@@ -4385,7 +5070,7 @@ var require_node_gyp_build2 = __commonJS({
4385
5070
  }
4386
5071
  }
4387
5072
  });
4388
- var require_fallback = __commonJS({
5073
+ var require_fallback = __commonJS2({
4389
5074
  "../node_modules/.pnpm/bufferutil@4.0.9/node_modules/bufferutil/fallback.js"(exports2, module2) {
4390
5075
  "use strict";
4391
5076
  var mask = (source, mask2, output, offset, length) => {
@@ -4402,7 +5087,7 @@ var require_fallback = __commonJS({
4402
5087
  module2.exports = { mask, unmask };
4403
5088
  }
4404
5089
  });
4405
- var require_bufferutil = __commonJS({
5090
+ var require_bufferutil = __commonJS2({
4406
5091
  "../node_modules/.pnpm/bufferutil@4.0.9/node_modules/bufferutil/index.js"(exports2, module2) {
4407
5092
  "use strict";
4408
5093
  try {
@@ -4412,7 +5097,7 @@ var require_bufferutil = __commonJS({
4412
5097
  }
4413
5098
  }
4414
5099
  });
4415
- var require_buffer_util = __commonJS({
5100
+ var require_buffer_util = __commonJS2({
4416
5101
  "../node_modules/.pnpm/ws@8.21.0_bufferutil@4.0.9/node_modules/ws/lib/buffer-util.js"(exports2, module2) {
4417
5102
  "use strict";
4418
5103
  var { EMPTY_BUFFER } = require_constants();
@@ -4485,7 +5170,7 @@ var require_buffer_util = __commonJS({
4485
5170
  }
4486
5171
  }
4487
5172
  });
4488
- var require_limiter = __commonJS({
5173
+ var require_limiter = __commonJS2({
4489
5174
  "../node_modules/.pnpm/ws@8.21.0_bufferutil@4.0.9/node_modules/ws/lib/limiter.js"(exports2, module2) {
4490
5175
  "use strict";
4491
5176
  var kDone = /* @__PURE__ */ Symbol("kDone");
@@ -4533,7 +5218,7 @@ var require_limiter = __commonJS({
4533
5218
  module2.exports = Limiter;
4534
5219
  }
4535
5220
  });
4536
- var require_permessage_deflate = __commonJS({
5221
+ var require_permessage_deflate = __commonJS2({
4537
5222
  "../node_modules/.pnpm/ws@8.21.0_bufferutil@4.0.9/node_modules/ws/lib/permessage-deflate.js"(exports2, module2) {
4538
5223
  "use strict";
4539
5224
  var zlib = __require("zlib");
@@ -4914,7 +5599,7 @@ var require_permessage_deflate = __commonJS({
4914
5599
  }
4915
5600
  }
4916
5601
  });
4917
- var require_validation = __commonJS({
5602
+ var require_validation = __commonJS2({
4918
5603
  "../node_modules/.pnpm/ws@8.21.0_bufferutil@4.0.9/node_modules/ws/lib/validation.js"(exports2, module2) {
4919
5604
  "use strict";
4920
5605
  var { isUtf8 } = __require("buffer");
@@ -5113,7 +5798,7 @@ var require_validation = __commonJS({
5113
5798
  }
5114
5799
  }
5115
5800
  });
5116
- var require_receiver = __commonJS({
5801
+ var require_receiver = __commonJS2({
5117
5802
  "../node_modules/.pnpm/ws@8.21.0_bufferutil@4.0.9/node_modules/ws/lib/receiver.js"(exports2, module2) {
5118
5803
  "use strict";
5119
5804
  var { Writable } = __require("stream");
@@ -5743,7 +6428,7 @@ var require_receiver = __commonJS({
5743
6428
  module2.exports = Receiver2;
5744
6429
  }
5745
6430
  });
5746
- var require_sender = __commonJS({
6431
+ var require_sender = __commonJS2({
5747
6432
  "../node_modules/.pnpm/ws@8.21.0_bufferutil@4.0.9/node_modules/ws/lib/sender.js"(exports2, module2) {
5748
6433
  "use strict";
5749
6434
  var { Duplex } = __require("stream");
@@ -6234,7 +6919,7 @@ var require_sender = __commonJS({
6234
6919
  }
6235
6920
  }
6236
6921
  });
6237
- var require_event_target = __commonJS({
6922
+ var require_event_target = __commonJS2({
6238
6923
  "../node_modules/.pnpm/ws@8.21.0_bufferutil@4.0.9/node_modules/ws/lib/event-target.js"(exports2, module2) {
6239
6924
  "use strict";
6240
6925
  var { kForOnEventAttribute, kListener } = require_constants();
@@ -6461,7 +7146,7 @@ var require_event_target = __commonJS({
6461
7146
  }
6462
7147
  }
6463
7148
  });
6464
- var require_extension = __commonJS({
7149
+ var require_extension = __commonJS2({
6465
7150
  "../node_modules/.pnpm/ws@8.21.0_bufferutil@4.0.9/node_modules/ws/lib/extension.js"(exports2, module2) {
6466
7151
  "use strict";
6467
7152
  var { tokenChars } = require_validation();
@@ -6612,7 +7297,7 @@ var require_extension = __commonJS({
6612
7297
  module2.exports = { format, parse };
6613
7298
  }
6614
7299
  });
6615
- var require_websocket = __commonJS({
7300
+ var require_websocket = __commonJS2({
6616
7301
  "../node_modules/.pnpm/ws@8.21.0_bufferutil@4.0.9/node_modules/ws/lib/websocket.js"(exports2, module2) {
6617
7302
  "use strict";
6618
7303
  var EventEmitter2 = __require("events");
@@ -7506,7 +8191,7 @@ var require_websocket = __commonJS({
7506
8191
  }
7507
8192
  }
7508
8193
  });
7509
- var require_stream = __commonJS({
8194
+ var require_stream = __commonJS2({
7510
8195
  "../node_modules/.pnpm/ws@8.21.0_bufferutil@4.0.9/node_modules/ws/lib/stream.js"(exports2, module2) {
7511
8196
  "use strict";
7512
8197
  var WebSocket2 = require_websocket();
@@ -7602,7 +8287,7 @@ var require_stream = __commonJS({
7602
8287
  module2.exports = createWebSocketStream2;
7603
8288
  }
7604
8289
  });
7605
- var require_subprotocol = __commonJS({
8290
+ var require_subprotocol = __commonJS2({
7606
8291
  "../node_modules/.pnpm/ws@8.21.0_bufferutil@4.0.9/node_modules/ws/lib/subprotocol.js"(exports2, module2) {
7607
8292
  "use strict";
7608
8293
  var { tokenChars } = require_validation();
@@ -7645,7 +8330,7 @@ var require_subprotocol = __commonJS({
7645
8330
  module2.exports = { parse };
7646
8331
  }
7647
8332
  });
7648
- var require_websocket_server = __commonJS({
8333
+ var require_websocket_server = __commonJS2({
7649
8334
  "../node_modules/.pnpm/ws@8.21.0_bufferutil@4.0.9/node_modules/ws/lib/websocket-server.js"(exports2, module2) {
7650
8335
  "use strict";
7651
8336
  var EventEmitter2 = __require("events");
@@ -13054,9 +13054,9 @@ Options:
13054
13054
  cliVersion: "codex-token-tracker {version}",
13055
13055
  cliUnknownCommand: "Unknown command: {command}",
13056
13056
  cliNoDisplay: "No display detected \u2014 starting agent mode (run `codex-tracker menubar` on a desktop).",
13057
- cliNoElectron: "Electron is not installed (optional dependency) \u2014 starting agent mode.",
13057
+ cliNoElectron: "No Electron runtime available \u2014 starting agent mode.",
13058
13058
  cliDownloadingElectron: "Electron runtime not found \u2014 downloading it now (about 100 MB, one time)\u2026",
13059
- cliElectronDownloadFailed: "Electron download failed. Retry with `npm install -g codex-token-tracker --allow-scripts=electron` or `npm rebuild -g electron`; the headless `codex-tracker agent` works without it.",
13059
+ cliElectronDownloadFailed: "Electron download failed. Check the network (set ELECTRON_MIRROR, e.g. https://npmmirror.com/mirrors/electron/, or HTTPS_PROXY) and run `codex-tracker menubar` again; the headless `codex-tracker agent` works without Electron.",
13060
13060
  cliStartingMenubar: "Starting menu bar app\u2026",
13061
13061
  cliLoginStart: "Connecting this device to {dashboard}",
13062
13062
  cliLoginCode: "Your code: {code}",
@@ -13229,9 +13229,9 @@ Options:
13229
13229
  cliVersion: "codex-token-tracker {version}",
13230
13230
  cliUnknownCommand: "\u672A\u77E5\u547D\u4EE4\uFF1A{command}",
13231
13231
  cliNoDisplay: "\u672A\u68C0\u6D4B\u5230\u663E\u793A\u73AF\u5883 \u2014 \u4EE5 agent \u6A21\u5F0F\u542F\u52A8\uFF08\u684C\u9762\u73AF\u5883\u8BF7\u8FD0\u884C `codex-tracker menubar`\uFF09\u3002",
13232
- cliNoElectron: "\u672A\u5B89\u88C5 Electron\uFF08\u53EF\u9009\u4F9D\u8D56\uFF09\u2014 \u4EE5 agent \u6A21\u5F0F\u542F\u52A8\u3002",
13232
+ cliNoElectron: "\u6CA1\u6709\u53EF\u7528\u7684 Electron \u8FD0\u884C\u65F6 \u2014 \u4EE5 agent \u6A21\u5F0F\u542F\u52A8\u3002",
13233
13233
  cliDownloadingElectron: "\u672A\u627E\u5230 Electron \u8FD0\u884C\u65F6\uFF0C\u6B63\u5728\u4E0B\u8F7D\uFF08\u7EA6 100 MB\uFF0C\u4EC5\u9700\u4E00\u6B21\uFF09\u2026",
13234
- cliElectronDownloadFailed: "Electron \u4E0B\u8F7D\u5931\u8D25\u3002\u53EF\u91CD\u8BD5 `npm install -g codex-token-tracker --allow-scripts=electron` \u6216 `npm rebuild -g electron`\uFF1B\u65E0\u754C\u9762\u7684 `codex-tracker agent` \u65E0\u9700 Electron\u3002",
13234
+ cliElectronDownloadFailed: "Electron \u4E0B\u8F7D\u5931\u8D25\u3002\u8BF7\u68C0\u67E5\u7F51\u7EDC\uFF08\u53EF\u8BBE\u7F6E ELECTRON_MIRROR\uFF0C\u4F8B\u5982 https://npmmirror.com/mirrors/electron/\uFF0C\u6216 HTTPS_PROXY\uFF09\u540E\u518D\u6B21\u8FD0\u884C `codex-tracker menubar`\uFF1B\u65E0\u754C\u9762\u7684 `codex-tracker agent` \u65E0\u9700 Electron\u3002",
13235
13235
  cliStartingMenubar: "\u6B63\u5728\u542F\u52A8\u83DC\u5355\u680F\u5E94\u7528\u2026",
13236
13236
  cliLoginStart: "\u6B63\u5728\u5C06\u672C\u8BBE\u5907\u8FDE\u63A5\u5230 {dashboard}",
13237
13237
  cliLoginCode: "\u4F60\u7684\u4EE3\u7801\uFF1A{code}",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-token-tracker-nodejs16",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Node.js 16 build of codex-token-tracker: menu bar / system tray app and headless agent that tracks OpenAI Codex token usage, cache hits, model mix and API-equivalent cost — and syncs it to your team dashboard.",
5
5
  "license": "MIT",
6
6
  "author": "Chen Li",
@@ -52,17 +52,14 @@
52
52
  "access": "public"
53
53
  },
54
54
  "dependencies": {
55
- "menubar": "^9.5.3",
56
55
  "undici": "^5.29.0"
57
56
  },
58
- "optionalDependencies": {
59
- "electron": "^38.8.6"
60
- },
61
57
  "devDependencies": {
62
58
  "@types/node": "^22.15.0",
63
59
  "@types/react": "^19.2.0",
64
60
  "@types/react-dom": "^19.2.0",
65
61
  "convex": "^1.45.0",
62
+ "electron": "^38.8.6",
66
63
  "esbuild": "^0.28.2",
67
64
  "react": "19.2.8",
68
65
  "react-dom": "19.2.8",