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

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
@@ -12,13 +12,15 @@ npm i -g @juejin-opensource/jusage
12
12
 
13
13
  ## 快速开始
14
14
 
15
- 推荐用后台服务启动(常驻,支持开机自启,macOS / Windows):
15
+ 推荐用后台服务启动(常驻,支持开机自启,macOS / Windows / Linux):
16
16
 
17
17
  ```bash
18
18
  jusage service start
19
19
  # 面板: http://127.0.0.1:8452
20
20
  ```
21
21
 
22
+ Linux 后台服务依赖 systemd 用户实例(`systemctl --user`)。无 systemd 时改用 `jusage start` 前台运行。
23
+
22
24
  首次启动会写入数据目录 `~/.ai-usage/`,尝试注册 Claude / Codex Hook,并同步本地用量。
23
25
 
24
26
  常用管理:
package/dist/daemon.d.ts CHANGED
@@ -1,9 +1,7 @@
1
- import { clearPid, getRunningOwner, getRunningPid, isPidAlive, pidFilePath, readPid, readRuntimeOwner, writePid, writeRuntimeOwner } from '@juejin-opensource/jusage-core';
2
- export { clearPid, getRunningOwner, getRunningPid, isPidAlive, pidFilePath, readPid, readRuntimeOwner, writePid, writeRuntimeOwner, };
1
+ import { clearPid, getRunningOwner, getRunningPid, isPidAlive, pidFilePath, readPid, readRuntimeOwner, stopPid, writePid, writeRuntimeOwner } from '@juejin-opensource/jusage-core';
2
+ export { clearPid, getRunningOwner, getRunningPid, isPidAlive, pidFilePath, readPid, readRuntimeOwner, stopPid, writePid, writeRuntimeOwner, };
3
3
  export declare function daemonLogPath(dataDir?: string): string;
4
4
  export declare function ensureDaemonLogDir(dataDir?: string): Promise<string>;
5
- /** Soft then hard kill. Returns true if the process is gone. */
6
- export declare function stopPid(pid: number, timeoutMs?: number): Promise<boolean>;
7
5
  /** True when local-api `/health` returns `{ ok: true }`. */
8
6
  export declare function probeLocalHealth(port: number): Promise<boolean>;
9
7
  export declare function waitForPid(dataDir?: string, timeoutMs?: number): Promise<number | null>;
package/dist/daemon.js CHANGED
@@ -2,8 +2,8 @@ import { spawnSync } from 'node:child_process';
2
2
  import { realpathSync } from 'node:fs';
3
3
  import { mkdir, readFile } from 'node:fs/promises';
4
4
  import { join } from 'node:path';
5
- import { DEFAULT_DATA_DIR, argsMatchRuntimeKind, logsDir, clearPid, getRunningOwner, getRunningPid, isPidAlive, pidFilePath, readPid, readProcessArgs, readRuntimeOwner, writePid, writeRuntimeOwner, } from '@juejin-opensource/jusage-core';
6
- export { clearPid, getRunningOwner, getRunningPid, isPidAlive, pidFilePath, readPid, readRuntimeOwner, writePid, writeRuntimeOwner, };
5
+ import { DEFAULT_DATA_DIR, argsMatchRuntimeKind, logsDir, clearPid, getRunningOwner, getRunningPid, isPidAlive, pidFilePath, readPid, readProcessArgs, readRuntimeOwner, stopPid, writePid, writeRuntimeOwner, } from '@juejin-opensource/jusage-core';
6
+ export { clearPid, getRunningOwner, getRunningPid, isPidAlive, pidFilePath, readPid, readRuntimeOwner, stopPid, writePid, writeRuntimeOwner, };
7
7
  export function daemonLogPath(dataDir = DEFAULT_DATA_DIR) {
8
8
  return join(logsDir(dataDir), 'daemon.log');
9
9
  }
@@ -12,39 +12,6 @@ export async function ensureDaemonLogDir(dataDir = DEFAULT_DATA_DIR) {
12
12
  await mkdir(dir, { recursive: true });
13
13
  return dir;
14
14
  }
15
- /** Soft then hard kill. Returns true if the process is gone. */
16
- export async function stopPid(pid, timeoutMs = 5000) {
17
- if (!isPidAlive(pid))
18
- return true;
19
- try {
20
- process.kill(pid, 'SIGTERM');
21
- }
22
- catch {
23
- return !isPidAlive(pid);
24
- }
25
- const deadline = Date.now() + timeoutMs;
26
- while (Date.now() < deadline) {
27
- if (!isPidAlive(pid))
28
- return true;
29
- await new Promise((r) => setTimeout(r, 100));
30
- }
31
- if (!isPidAlive(pid))
32
- return true;
33
- try {
34
- if (process.platform === 'win32') {
35
- const { spawnSync } = await import('node:child_process');
36
- spawnSync('taskkill', ['/PID', String(pid), '/T', '/F'], { stdio: 'ignore' });
37
- }
38
- else {
39
- process.kill(pid, 'SIGKILL');
40
- }
41
- }
42
- catch {
43
- // ignore
44
- }
45
- await new Promise((r) => setTimeout(r, 200));
46
- return !isPidAlive(pid);
47
- }
48
15
  async function readLivePid(dataDir) {
49
16
  // Do not go through getRunningOwner: a locale-mismatched startedAt would
50
17
  // delete the pid file the daemon just wrote, and this wait would never see it.
@@ -1 +1 @@
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-DUrAxTsQ.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};
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};