@juejin-opensource/jusage 0.1.1-beta.8

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.
Files changed (36) hide show
  1. package/README.md +72 -0
  2. package/bin/jusage.js +2 -0
  3. package/dist/daemon.d.ts +12 -0
  4. package/dist/daemon.js +68 -0
  5. package/dist/dashboard/assets/antigravity-color-DgAQAdn3.svg +1 -0
  6. package/dist/dashboard/assets/click-idle-6pQvdt8N.png +0 -0
  7. package/dist/dashboard/assets/dashboard-CUazuH2T.js +55 -0
  8. package/dist/dashboard/assets/dashboard-QA2DxQpC.css +1 -0
  9. package/dist/dashboard/assets/download-BzFSswoC.js +1 -0
  10. package/dist/dashboard/assets/env-BKC5UKtr.js +1 -0
  11. package/dist/dashboard/assets/hawking-idle-C6M3ZvDm.png +0 -0
  12. package/dist/dashboard/assets/hermesagent-DUfTwIy7.svg +1 -0
  13. package/dist/dashboard/assets/index-1sV0Fo6m.js +143 -0
  14. package/dist/dashboard/assets/index-C1eSlCqF.css +1 -0
  15. package/dist/dashboard/assets/index-DcW6PDH-.js +1 -0
  16. package/dist/dashboard/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
  17. package/dist/dashboard/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
  18. package/dist/dashboard/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  19. package/dist/dashboard/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  20. package/dist/dashboard/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
  21. package/dist/dashboard/assets/qoder-color-CCjsVbDP.svg +1 -0
  22. package/dist/dashboard/assets/rank-DedRCNMw.js +16 -0
  23. package/dist/dashboard/assets/settings-jDmOMdkE.js +1 -0
  24. package/dist/dashboard/assets/yoyo-idle-DmXh5tLT.png +0 -0
  25. package/dist/dashboard/brand-logos/claude-code.svg +1 -0
  26. package/dist/dashboard/brand-logos/codex.svg +15 -0
  27. package/dist/dashboard/index.html +13 -0
  28. package/dist/index.d.ts +10 -0
  29. package/dist/index.js +486 -0
  30. package/dist/service-macos.d.ts +7 -0
  31. package/dist/service-macos.js +97 -0
  32. package/dist/service-windows.d.ts +6 -0
  33. package/dist/service-windows.js +50 -0
  34. package/dist/service.d.ts +3 -0
  35. package/dist/service.js +109 -0
  36. package/package.json +51 -0
@@ -0,0 +1,109 @@
1
+ import { platform } from 'node:os';
2
+ import { DEFAULT_DATA_DIR, DEFAULT_PORT, getRunningOwner, loadConfig, runtimeKindLabel, touchStatsSince, } from '@juejin-opensource/jusage-core';
3
+ import { clearPid, stopPid, waitForPid, } from './daemon.js';
4
+ import { isMacosAutostartRegistered, registerMacosAutostart, unregisterMacosAutostart, } from './service-macos.js';
5
+ import { isWindowsAutostartRegistered, registerWindowsAutostart, unregisterWindowsAutostart, } from './service-windows.js';
6
+ function assertSupportedPlatform() {
7
+ const p = platform();
8
+ if (p === 'darwin' || p === 'win32')
9
+ return p;
10
+ throw new Error(`jusage service 仅支持 macOS 与 Windows(当前: ${p})`);
11
+ }
12
+ async function isAutostartRegistered() {
13
+ const p = assertSupportedPlatform();
14
+ if (p === 'darwin')
15
+ return isMacosAutostartRegistered();
16
+ return isWindowsAutostartRegistered();
17
+ }
18
+ async function registerAutostart(cliBinPath, dataDir) {
19
+ const p = assertSupportedPlatform();
20
+ if (p === 'darwin') {
21
+ await registerMacosAutostart(cliBinPath, dataDir);
22
+ return;
23
+ }
24
+ await registerWindowsAutostart(cliBinPath, dataDir);
25
+ }
26
+ async function unregisterAutostart() {
27
+ const p = assertSupportedPlatform();
28
+ if (p === 'darwin') {
29
+ await unregisterMacosAutostart();
30
+ return;
31
+ }
32
+ await unregisterWindowsAutostart();
33
+ }
34
+ export async function cmdServiceStart(cliBinPath, daysAgo) {
35
+ assertSupportedPlatform();
36
+ const { dir, config } = await loadConfig();
37
+ // Seed statsSince before launchd starts `jusage start` (do not bake --days into plist).
38
+ await touchStatsSince(dir, config, daysAgo != null ? { daysAgo } : undefined);
39
+ const existing = await getRunningOwner(dir);
40
+ if (existing != null) {
41
+ // Already running: still ensure autostart is registered.
42
+ const who = runtimeKindLabel(existing.kind);
43
+ const registered = await isAutostartRegistered();
44
+ if (!registered) {
45
+ await registerAutostart(cliBinPath, dir);
46
+ console.log(`服务已在运行(${who} pid ${existing.pid}),已补注册开机自启`);
47
+ }
48
+ else {
49
+ console.log(`服务已在运行(${who} pid ${existing.pid})`);
50
+ }
51
+ if (existing.kind === 'desktop') {
52
+ console.log(' 提示: 当前 runtime owner 是桌面端,同步/上报由桌面负责');
53
+ console.log(' 如需浏览器面板,可另开终端执行 jusage start(观察模式,只读)');
54
+ }
55
+ console.log(` 面板: http://127.0.0.1:${config.serverPort || DEFAULT_PORT}`);
56
+ return;
57
+ }
58
+ await registerAutostart(cliBinPath, dir);
59
+ const pid = await waitForPid(dir);
60
+ if (pid == null) {
61
+ throw new Error('自启已注册,但进程未在预期时间内启动,请查看 ~/.ai-usage/logs/daemon.log');
62
+ }
63
+ const { config: refreshed } = await loadConfig(dir);
64
+ console.log(`✓ 服务已在后台启动 (pid ${pid})`);
65
+ console.log(` 面板: http://127.0.0.1:${refreshed.serverPort || DEFAULT_PORT}`);
66
+ console.log(` 数据: ${dir}`);
67
+ console.log(` 开机自启: 已注册`);
68
+ console.log(` 日志: ${dir}/logs/daemon.log`);
69
+ }
70
+ export async function cmdServiceStop() {
71
+ assertSupportedPlatform();
72
+ const { dir } = await loadConfig();
73
+ // Unregister first so KeepAlive / task restart cannot bring the process back.
74
+ await unregisterAutostart();
75
+ const owner = await getRunningOwner(dir);
76
+ if (owner != null) {
77
+ if (owner.kind === 'desktop') {
78
+ // Do not kill the Electron process; only clear CLI autostart above.
79
+ console.log(`✓ 开机自启已取消(当前 runtime owner 是桌面端 pid ${owner.pid},未结束桌面进程)`);
80
+ return;
81
+ }
82
+ const stopped = await stopPid(owner.pid);
83
+ if (!stopped) {
84
+ throw new Error(`无法停止进程 pid ${owner.pid}`);
85
+ }
86
+ }
87
+ await clearPid(dir);
88
+ console.log('✓ 服务已停止,开机自启已取消');
89
+ }
90
+ export async function cmdServiceStatus() {
91
+ assertSupportedPlatform();
92
+ const { dir, config } = await loadConfig();
93
+ const owner = await getRunningOwner(dir);
94
+ const registered = await isAutostartRegistered();
95
+ const port = config.serverPort || DEFAULT_PORT;
96
+ if (owner != null) {
97
+ console.log(`服务: 运行中(${runtimeKindLabel(owner.kind)} pid ${owner.pid})`);
98
+ }
99
+ else {
100
+ console.log('服务: 未运行');
101
+ }
102
+ console.log(`开机自启: ${registered ? '已注册' : '未注册'}`);
103
+ console.log(`面板: http://127.0.0.1:${port}`);
104
+ console.log(`数据: ${dir || DEFAULT_DATA_DIR}`);
105
+ console.log(`云端同步: ${config.juejin.enabled ? '已开启' : '未开启'} → ${config.juejin.apiUrl}`);
106
+ console.log(`上次同步: ${config.lastSyncAt ?? '从未'}`);
107
+ console.log(`上次上报: ${config.lastUploadAt ?? '从未'}`);
108
+ console.log(`日志: ${dir}/logs/daemon.log`);
109
+ }
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@juejin-opensource/jusage",
3
+ "version": "0.1.1-beta.8",
4
+ "description": "本地优先的 AI Agent Token 用量看板 CLI(采集 + 本地面板 + 可选云端上报)",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/juejin-cn/ai-usage.git",
10
+ "directory": "packages/cli"
11
+ },
12
+ "keywords": [
13
+ "ai",
14
+ "token",
15
+ "usage",
16
+ "claude",
17
+ "codex",
18
+ "cursor",
19
+ "cli"
20
+ ],
21
+ "bin": {
22
+ "jusage": "./bin/jusage.js"
23
+ },
24
+ "files": [
25
+ "bin",
26
+ "dist",
27
+ "package.json"
28
+ ],
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "dependencies": {
33
+ "@juejin-opensource/jusage-core": "0.1.1-beta.8"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "^22.13.10",
37
+ "typescript": "^5.8.2",
38
+ "@juejin-opensource/jusage-dashboard": "0.1.1-beta.8"
39
+ },
40
+ "engines": {
41
+ "node": ">=20"
42
+ },
43
+ "scripts": {
44
+ "build": "tsc -p tsconfig.json && node ./scripts/copy-dashboard.mjs",
45
+ "start": "node ./bin/jusage.js start",
46
+ "sync": "node ./bin/jusage.js sync",
47
+ "status": "node ./bin/jusage.js status",
48
+ "upload": "node ./bin/jusage.js upload",
49
+ "service": "node ./bin/jusage.js service"
50
+ }
51
+ }