@juejin-opensource/jusage 0.1.6-beta.0 → 0.1.7

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 (37) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -0
  3. package/dist/args.d.ts +20 -0
  4. package/dist/args.js +121 -0
  5. package/dist/daemon.d.ts +2 -2
  6. package/dist/daemon.js +8 -7
  7. package/dist/dashboard/assets/Check-C6Vp6SAU.js +1 -0
  8. package/dist/dashboard/assets/click-idle-CXAVCmiH.png +0 -0
  9. package/dist/dashboard/assets/dashboard-CW-mCwMR.js +55 -0
  10. package/dist/dashboard/assets/download-_xhCt7jY.js +1 -0
  11. package/dist/dashboard/assets/downloads-63AG5C_E.js +1 -0
  12. package/dist/dashboard/assets/hawking-idle-QoXt5bST.png +0 -0
  13. package/dist/dashboard/assets/index-3miiAdwH.js +143 -0
  14. package/dist/dashboard/assets/{index-I_ub2jqy.css → index-C1vokUY2.css} +1 -1
  15. package/dist/dashboard/assets/{index-C28OANM4.js → index-DikHz9Xg.js} +1 -1
  16. package/dist/dashboard/assets/{pricing-C1AgdgdM.js → pricing-Btfm94JM.js} +1 -1
  17. package/dist/dashboard/assets/rank-LoqZH6uK.js +16 -0
  18. package/dist/dashboard/assets/{settings-BA_UlPf3.js → settings-BzyD7YMM.js} +1 -1
  19. package/dist/dashboard/assets/useLocalStorage-C_Z-N_8Q.js +1 -0
  20. package/dist/dashboard/assets/yoyo-idle-DDvV3ieO.png +0 -0
  21. package/dist/dashboard/index.html +2 -2
  22. package/dist/index.d.ts +1 -10
  23. package/dist/index.js +21 -93
  24. package/dist/service-linux.js +6 -1
  25. package/dist/service.d.ts +4 -1
  26. package/dist/service.js +19 -8
  27. package/package.json +13 -13
  28. package/dist/dashboard/assets/ChevronDown-raqOGGZY.js +0 -1
  29. package/dist/dashboard/assets/click-idle-6pQvdt8N.png +0 -0
  30. package/dist/dashboard/assets/dashboard-2aS4UXAq.js +0 -55
  31. package/dist/dashboard/assets/download-w1_SlsVA.js +0 -1
  32. package/dist/dashboard/assets/downloads-DRt36RTZ.js +0 -1
  33. package/dist/dashboard/assets/env-Bahc-RuR.js +0 -1
  34. package/dist/dashboard/assets/hawking-idle-C6M3ZvDm.png +0 -0
  35. package/dist/dashboard/assets/index-DpG68XJd.js +0 -143
  36. package/dist/dashboard/assets/rank-DNpmekT1.js +0 -16
  37. package/dist/dashboard/assets/yoyo-idle-DmXh5tLT.png +0 -0
package/dist/service.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { platform } from 'node:os';
2
- import { DEFAULT_DATA_DIR, DEFAULT_PORT, getRunningOwner, loadConfig, runtimeKindLabel, touchStatsSince, } from '@juejin-opensource/jusage-core';
2
+ import { DEFAULT_DATA_DIR, DEFAULT_PORT, getRunningOwner, loadConfig, runtimeKindLabel, saveConfig, touchStatsSince, } from '@juejin-opensource/jusage-core';
3
3
  import { clearPid, daemonLogPath, readDaemonLogTail, stopPid, waitForServiceReady, } from './daemon.js';
4
+ import { DEFAULT_HOST, formatListenUrl } from './args.js';
4
5
  import { isLinuxAutostartRegistered, registerLinuxAutostart, unregisterLinuxAutostart, } from './service-linux.js';
5
6
  import { isMacosAutostartRegistered, registerMacosAutostart, unregisterMacosAutostart, } from './service-macos.js';
6
7
  import { isWindowsAutostartRegistered, registerWindowsAutostart, unregisterWindowsAutostart, } from './service-windows.js';
@@ -42,7 +43,7 @@ async function unregisterAutostart() {
42
43
  }
43
44
  await unregisterLinuxAutostart();
44
45
  }
45
- export async function cmdServiceStart(cliBinPath, daysAgo) {
46
+ export async function cmdServiceStart(cliBinPath, daysAgo, listen) {
46
47
  assertSupportedPlatform();
47
48
  const startedAt = Date.now();
48
49
  const waitTimer = setInterval(() => {
@@ -50,16 +51,23 @@ export async function cmdServiceStart(cliBinPath, daysAgo) {
50
51
  console.log(` 仍在等待检测中(已 ${elapsed}s)…`);
51
52
  }, 3_000);
52
53
  try {
53
- await cmdServiceStartBody(cliBinPath, daysAgo);
54
+ await cmdServiceStartBody(cliBinPath, daysAgo, listen);
54
55
  }
55
56
  finally {
56
57
  clearInterval(waitTimer);
57
58
  }
58
59
  }
59
- async function cmdServiceStartBody(cliBinPath, daysAgo) {
60
+ async function cmdServiceStartBody(cliBinPath, daysAgo, listen) {
60
61
  const { dir, config } = await loadConfig();
61
62
  // Seed statsSince before launchd starts `jusage start` (do not bake --days into plist).
62
63
  await touchStatsSince(dir, config, daysAgo != null ? { daysAgo } : undefined);
64
+ if (listen?.port != null)
65
+ config.serverPort = listen.port;
66
+ if (listen?.host != null)
67
+ config.serverHost = listen.host;
68
+ if (listen?.port != null || listen?.host != null) {
69
+ await saveConfig(dir, config);
70
+ }
63
71
  const existing = await getRunningOwner(dir);
64
72
  if (existing != null) {
65
73
  // Already running: still ensure autostart is registered.
@@ -76,12 +84,13 @@ async function cmdServiceStartBody(cliBinPath, daysAgo) {
76
84
  console.log(' 提示: 当前 runtime owner 是桌面端,同步/上报由桌面负责');
77
85
  console.log(' 如需浏览器面板,可另开终端执行 jusage start(观察模式,只读)');
78
86
  }
79
- console.log(` 面板: http://127.0.0.1:${config.serverPort || DEFAULT_PORT}`);
87
+ console.log(` 面板: ${formatListenUrl(config.serverHost || DEFAULT_HOST, config.serverPort || DEFAULT_PORT)}`);
80
88
  return;
81
89
  }
82
90
  await registerAutostart(cliBinPath, dir);
83
91
  const port = config.serverPort || DEFAULT_PORT;
84
- const ready = await waitForServiceReady(dir, port);
92
+ const host = config.serverHost || DEFAULT_HOST;
93
+ const ready = await waitForServiceReady(dir, port, host);
85
94
  if (ready.pid == null && !ready.health) {
86
95
  const logPath = daemonLogPath(dir);
87
96
  const tail = await readDaemonLogTail(dir);
@@ -90,13 +99,14 @@ async function cmdServiceStartBody(cliBinPath, daysAgo) {
90
99
  }
91
100
  const { config: refreshed } = await loadConfig(dir);
92
101
  const panelPort = refreshed.serverPort || DEFAULT_PORT;
102
+ const panelHost = refreshed.serverHost || DEFAULT_HOST;
93
103
  if (ready.pid != null) {
94
104
  console.log(`✓ 服务已在后台启动 (pid ${ready.pid})`);
95
105
  }
96
106
  else {
97
107
  console.log('✓ 服务已在后台启动(面板 /health 已就绪)');
98
108
  }
99
- console.log(` 面板: http://127.0.0.1:${panelPort}`);
109
+ console.log(` 面板: ${formatListenUrl(panelHost, panelPort)}`);
100
110
  console.log(` 数据: ${dir}`);
101
111
  console.log(` 开机自启: 已注册`);
102
112
  console.log(` 日志: ${dir}/logs/daemon.log`);
@@ -127,6 +137,7 @@ export async function cmdServiceStatus() {
127
137
  const owner = await getRunningOwner(dir);
128
138
  const registered = await isAutostartRegistered();
129
139
  const port = config.serverPort || DEFAULT_PORT;
140
+ const host = config.serverHost || DEFAULT_HOST;
130
141
  if (owner != null) {
131
142
  console.log(`服务: 运行中(${runtimeKindLabel(owner.kind)} pid ${owner.pid})`);
132
143
  }
@@ -134,7 +145,7 @@ export async function cmdServiceStatus() {
134
145
  console.log('服务: 未运行');
135
146
  }
136
147
  console.log(`开机自启: ${registered ? '已注册' : '未注册'}`);
137
- console.log(`面板: http://127.0.0.1:${port}`);
148
+ console.log(`面板: ${formatListenUrl(host, port)}`);
138
149
  console.log(`数据: ${dir || DEFAULT_DATA_DIR}`);
139
150
  console.log(`云端同步: ${config.juejin.enabled ? '已开启' : '未开启'} → ${config.juejin.apiUrl}`);
140
151
  console.log(`上次同步: ${config.lastSyncAt ?? '从未'}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juejin-opensource/jusage",
3
- "version": "0.1.6-beta.0",
3
+ "version": "0.1.7",
4
4
  "description": "Juejin AI Usage 统计 CLI:Token 用量明细追踪,本地记录、云端同步,内置用量看板。",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -33,6 +33,17 @@
33
33
  "publishConfig": {
34
34
  "access": "public"
35
35
  },
36
+ "dependencies": {
37
+ "@juejin-opensource/jusage-core": "0.1.7"
38
+ },
39
+ "devDependencies": {
40
+ "@types/node": "^22.13.10",
41
+ "typescript": "^5.8.2",
42
+ "@juejin-opensource/jusage-dashboard": "0.1.7"
43
+ },
44
+ "engines": {
45
+ "node": ">=20"
46
+ },
36
47
  "scripts": {
37
48
  "build": "tsc -p tsconfig.json && node ./scripts/copy-dashboard.mjs",
38
49
  "start": "node ./bin/jusage.js start",
@@ -41,16 +52,5 @@
41
52
  "upload": "node ./bin/jusage.js upload",
42
53
  "service": "node ./bin/jusage.js service",
43
54
  "test": "tsc -p tsconfig.json && node --test \"test/**/*.test.js\""
44
- },
45
- "dependencies": {
46
- "@juejin-opensource/jusage-core": "0.1.5"
47
- },
48
- "devDependencies": {
49
- "@juejin-opensource/jusage-dashboard": "workspace:*",
50
- "@types/node": "^22.13.10",
51
- "typescript": "^5.8.2"
52
- },
53
- "engines": {
54
- "node": ">=20"
55
55
  }
56
- }
56
+ }
@@ -1 +0,0 @@
1
- import{t as p,R as l,j as t,cc as v,r as s,cd as g,a9 as c,be as f,c8 as x,a7 as h,bQ as w,ce as u,cf as m,b4 as b}from"./index-DpG68XJd.js";const $=p({slots:{base:"popover",dialog:"popover__dialog",heading:"popover__heading",trigger:"popover__trigger"}}),n=s.createContext({}),d=({children:o,...r})=>{const a=l.useMemo(()=>$(),[]);return t.jsx(n,{value:{slots:a},children:t.jsx(v,{"data-slot":"popover-root",...r,children:o})})},j=({children:o,className:r,...a})=>{const{slots:e}=s.use(n);return t.jsx(n,{value:{slots:e},children:t.jsx(f,{value:{variant:"default"},children:t.jsx(x,{...a,className:h(r,e==null?void 0:e.base()),children:o})})})},C=({children:o,className:r,...a})=>{const e=t.jsx("svg",{"data-slot":"popover-overlay-arrow",fill:"none",height:"12",viewBox:"0 0 12 12",width:"12",xmlns:"http://www.w3.org/2000/svg",children:t.jsx("path",{d:"M0 0C5.48483 8 6.5 8 12 0Z"})}),i=l.isValidElement(o)?l.cloneElement(o,{"data-slot":"popover-overlay-arrow"}):e;return t.jsx(w,{"data-slot":"popover-overlay-arrow-group",...a,className:r,children:i})},P=({children:o,className:r,...a})=>{const{slots:e}=s.use(n);return t.jsx(u,{"data-slot":"popover-dialog",...a,className:c(e==null?void 0:e.dialog,r),children:o})},R=({children:o,className:r,...a})=>{const{slots:e}=s.use(n);return t.jsx(m,{children:t.jsx(b.div,{className:c(e==null?void 0:e.trigger,r),"data-slot":"popover-trigger",role:"button",...a,children:o})})},E=({children:o,className:r,...a})=>{const{slots:e}=s.use(n);return t.jsx(g,{slot:"title",...a,className:c(e==null?void 0:e.heading,r),children:o})},_=Object.assign(d,{Root:d,Trigger:R,Dialog:P,Arrow:C,Content:j,Heading:E}),A=o=>s.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",width:16,height:16,fill:"none",viewBox:"0 0 16 16"},o),s.createElement("path",{fill:"currentColor",fillRule:"evenodd",d:"M13.488 3.43a.75.75 0 0 1 .081 1.058l-6 7a.75.75 0 0 1-1.1.042l-3.5-3.5A.75.75 0 0 1 4.03 6.97l2.928 2.927 5.473-6.385a.75.75 0 0 1 1.057-.081",clipRule:"evenodd"})),M=o=>s.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",width:16,height:16,fill:"none",viewBox:"0 0 16 16"},o),s.createElement("path",{fill:"currentColor",fillRule:"evenodd",d:"M2.97 5.47a.75.75 0 0 1 1.06 0L8 9.44l3.97-3.97a.75.75 0 1 1 1.06 1.06l-4.5 4.5a.75.75 0 0 1-1.06 0l-4.5-4.5a.75.75 0 0 1 0-1.06",clipRule:"evenodd"}));export{M as C,_ as P,A as a};