codex-quota-chip 0.0.0-stage → 0.1.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 CHANGED
@@ -1,3 +1,39 @@
1
- # Temporary Holding Version
1
+ # codex-quota-chip (npm wrapper)
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ 这是 [Codex Quota Chip](https://github.com/easerlee/codex-quota-chip) 的 npm 外壳。
4
+ **它不是 JavaScript 库** —— 本体是 C#/WPF 的 Windows 桌面程序,所以这个包做的事只有三件:
5
+
6
+ 1. 安装时从对应的 GitHub Release 下载自包含的 `CodexQuotaChip-<version>-win-x64.zip`;
7
+ 2. 用 `package.json` 里钉死的 sha256 校验,校验不过就拒绝解压;
8
+ 3. 解到包内 `vendor/`,然后 `codex-quota-chip` 这个命令把参数原样转给那个 exe。
9
+
10
+ ```sh
11
+ npm install -g codex-quota-chip
12
+
13
+ codex-quota-chip # 启动任务栏浮窗
14
+ codex-quota-chip --check # 打印状态目录 / codex 路径 / 停靠位置
15
+ codex-quota-chip --once # 读一次并打印 JSON
16
+ ```
17
+
18
+ 因为只有 Windows 构建,`package.json` 里限制为 `os: win32`,在别的系统上 npm 直接拒绝安装。
19
+ 想装真正的安装包/卸载脚本,用 GitHub Release 里的 zip,或者用 winget(见仓库首页)。
20
+
21
+ ## 卸载
22
+
23
+ ```sh
24
+ npm uninstall -g codex-quota-chip
25
+ ```
26
+
27
+ 程序自己的状态目录(`%LOCALAPPDATA%\CodexQuotaChip`)不会被 npm 删除;要一起清就用 Release
28
+ zip 里的 `uninstall.ps1 -Purge`,或手动删那个目录。
29
+
30
+ ## 发布(维护者)
31
+
32
+ `package.json` 的 `version` 必须和 GitHub Release 的 tag(`v<version>`)一致,`sha256`
33
+ 必须是该 Release 上 zip 的哈希,否则安装会被自己的校验拦下:
34
+
35
+ ```powershell
36
+ npm pack # 本地打 tarball,可先 --prefix 装到临时目录验证
37
+ npm login
38
+ npm publish
39
+ ```
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ // Launches the app that install.js unpacked, passing the arguments straight through, and exits
3
+ // with the same code. Run without arguments it starts the taskbar overlay.
4
+ 'use strict';
5
+
6
+ const { existsSync } = require('node:fs');
7
+ const { spawnSync } = require('node:child_process');
8
+ const path = require('node:path');
9
+
10
+ const exe = path.join(__dirname, '..', 'vendor', 'CodexQuotaChip.exe');
11
+ if (!existsSync(exe)) {
12
+ console.error('codex-quota-chip: the app is not unpacked yet - run "npm rebuild codex-quota-chip".');
13
+ process.exit(1);
14
+ }
15
+
16
+ const result = spawnSync(exe, process.argv.slice(2), { stdio: 'inherit' });
17
+ process.exit(result.status === null ? 1 : result.status);
package/package.json CHANGED
@@ -1,6 +1,46 @@
1
1
  {
2
2
  "name": "codex-quota-chip",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.1",
4
+ "description": "Windows 任务栏上的 Codex 额度浮窗:装上就有一条 5H/周额度条和右键账号面板",
5
+ "license": "MIT",
6
+ "author": "easerlee",
7
+ "homepage": "https://github.com/easerlee/codex-quota-chip",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/easerlee/codex-quota-chip.git",
11
+ "directory": "npm"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/easerlee/codex-quota-chip/issues"
15
+ },
16
+ "keywords": [
17
+ "codex",
18
+ "quota",
19
+ "usage",
20
+ "taskbar",
21
+ "windows",
22
+ "overlay",
23
+ "wpf"
24
+ ],
25
+ "os": [
26
+ "win32"
27
+ ],
28
+ "engines": {
29
+ "node": ">=18"
30
+ },
31
+ "bin": {
32
+ "codex-quota-chip": "bin/codex-quota-chip.js"
33
+ },
34
+ "scripts": {
35
+ "postinstall": "node scripts/install.js"
36
+ },
37
+ "files": [
38
+ "bin",
39
+ "scripts",
40
+ "README.md"
41
+ ],
42
+ "codexQuotaChip": {
43
+ "_comment": "sha256 of CodexQuotaChip-<version>-win-x64.zip on the matching GitHub release. Bump it together with version, or the install refuses to run the download.",
44
+ "sha256": "235bd163fb2f7c54178587ec87b07e1cac4b2527b979a3396fc33ecbafd62bd3"
45
+ }
46
+ }
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env node
2
+ // Downloads the Windows build from the GitHub release for this package's version, checks it
3
+ // against the sha256 pinned in package.json, and unpacks it next to this package.
4
+ //
5
+ // This is a wrapper, not a JavaScript library: the app is a C#/WPF executable. The download is
6
+ // verified before anything is extracted, and npm has no unzip of its own, so the extraction goes
7
+ // through PowerShell's Expand-Archive (this package only installs on Windows anyway).
8
+ 'use strict';
9
+
10
+ const { createHash } = require('node:crypto');
11
+ const { execFileSync } = require('node:child_process');
12
+ const { createWriteStream, existsSync, mkdirSync, rmSync, statSync } = require('node:fs');
13
+ const path = require('node:path');
14
+ const https = require('node:https');
15
+
16
+ const packageRoot = path.join(__dirname, '..');
17
+ const pkg = require(path.join(packageRoot, 'package.json'));
18
+ const version = pkg.version;
19
+ const asset = `CodexQuotaChip-${version}-win-x64.zip`;
20
+ const url = `https://github.com/easerlee/codex-quota-chip/releases/download/v${version}/${asset}`;
21
+ const expected = pkg.codexQuotaChip && pkg.codexQuotaChip.sha256;
22
+ const vendor = path.join(packageRoot, 'vendor');
23
+ const archive = path.join(vendor, asset);
24
+
25
+ function fail(message) {
26
+ console.error(`codex-quota-chip: ${message}`);
27
+ console.error('You can also install the app itself from https://github.com/easerlee/codex-quota-chip/releases');
28
+ process.exit(1);
29
+ }
30
+
31
+ function download(from, to, redirects = 0) {
32
+ return new Promise((resolve, reject) => {
33
+ if (redirects > 5) {
34
+ reject(new Error('too many redirects'));
35
+ return;
36
+ }
37
+
38
+ https
39
+ .get(from, { headers: { 'user-agent': 'codex-quota-chip-npm' } }, (response) => {
40
+ const status = response.statusCode || 0;
41
+ if (status >= 300 && status < 400 && response.headers.location) {
42
+ response.resume();
43
+ download(response.headers.location, to, redirects + 1).then(resolve, reject);
44
+ return;
45
+ }
46
+ if (status !== 200) {
47
+ response.resume();
48
+ reject(new Error(`${status} while downloading ${from}`));
49
+ return;
50
+ }
51
+
52
+ const file = createWriteStream(to);
53
+ response.pipe(file);
54
+ file.on('finish', () => file.close(resolve));
55
+ file.on('error', reject);
56
+ })
57
+ .on('error', reject);
58
+ });
59
+ }
60
+
61
+ function sha256(file) {
62
+ const hash = createHash('sha256');
63
+ hash.update(require('node:fs').readFileSync(file));
64
+ return hash.digest('hex');
65
+ }
66
+
67
+ async function main() {
68
+ if (process.platform !== 'win32') {
69
+ fail('this package only installs on Windows');
70
+ }
71
+
72
+ if (!expected || expected.length !== 64) {
73
+ fail('package.json carries no sha256 for the download; refusing to fetch it');
74
+ }
75
+
76
+ mkdirSync(vendor, { recursive: true });
77
+ console.log(`codex-quota-chip: downloading ${asset} (${version}) ...`);
78
+
79
+ try {
80
+ await download(url, archive);
81
+ } catch (error) {
82
+ fail(`download failed: ${error.message}`);
83
+ }
84
+
85
+ const actual = sha256(archive);
86
+ if (actual !== expected) {
87
+ rmSync(archive, { force: true });
88
+ fail(`checksum mismatch: expected ${expected}, got ${actual}`);
89
+ }
90
+
91
+ console.log('codex-quota-chip: checksum ok, unpacking ...');
92
+ try {
93
+ execFileSync(
94
+ 'powershell',
95
+ ['-NoProfile', '-NonInteractive', '-Command', `Expand-Archive -LiteralPath '${archive}' -DestinationPath '${vendor}' -Force`],
96
+ { stdio: 'inherit' }
97
+ );
98
+ } catch (error) {
99
+ fail(`could not unpack the archive: ${error.message}`);
100
+ }
101
+
102
+ const exe = path.join(vendor, 'CodexQuotaChip.exe');
103
+ if (!existsSync(exe) || statSync(exe).size === 0) {
104
+ fail('the archive did not contain CodexQuotaChip.exe');
105
+ }
106
+
107
+ rmSync(archive, { force: true });
108
+ console.log(`codex-quota-chip: ready - ${exe}`);
109
+ console.log('run "codex-quota-chip" to start it, or launch the exe directly.');
110
+ }
111
+
112
+ main().catch((error) => fail(error.message));