pczzz 0.0.4 → 0.0.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.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 pcoff contributors
3
+ Copyright (c) 2026 pczzz contributors
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,33 +1,27 @@
1
- # pcoff
1
+ # pczzz
2
2
 
3
3
  定时关机命令行工具
4
4
 
5
5
  ## 安装
6
6
 
7
7
  ```bash
8
- npm install -g pcoff
8
+ npm install -g pczzz
9
9
  ```
10
10
 
11
- ## 使用
12
-
13
- ### 命令行直接指定时间
11
+ ## 用法
14
12
 
15
13
  ```bash
16
- pcoff 1s # 1 秒后关机
17
- pcoff 20m # 20 分钟后关机
18
- pcoff 1h # 1 小时后关机
19
- pcoff 1h30m # 组合单位:1 小时 30 分钟后
20
- pcoff 90 # 纯数字按秒计
21
- pcoff 30秒 # 中文单位也可以
14
+ pczzz 1s # 1 秒后关机
15
+ pczzz 20m # 20 分钟后关机
16
+ pczzz 1h # 1 小时后关机
17
+ pczzz 1h30m # 组合单位:1 小时 30 分钟后
18
+ pczzz 90 # 纯数字按秒计
19
+ pczzz 30秒 # 中文单位也可以
22
20
  ```
23
21
 
24
- 支持的单位:`s` 秒 / `m` 分钟 / `h` 小时 / `d` 天(以及 sec、min、hour、秒、分钟、小时等写法),可以自由组合(如 `1h30m`)。
25
-
26
- ### 交互式菜单
27
-
28
- 直接运行 `pcoff`(不带参数):
22
+ 或者不带参数执行 `pczzz`
29
23
 
30
- ```
24
+ ```bash
31
25
  你想多久关机?
32
26
  1. 30 秒
33
27
  2. 20 分钟
@@ -44,7 +38,7 @@ pcoff 30秒 # 中文单位也可以
44
38
  ### 取消关机
45
39
 
46
40
  ```bash
47
- pcoff cancel
41
+ pczzz cancel
48
42
  ```
49
43
 
50
44
  或在菜单中选择「取消当前关机」。
@@ -53,9 +47,9 @@ pcoff cancel
53
47
 
54
48
  ## 重复安排检测
55
49
 
56
- 安排新的关机前,pcoff 会检查是否已存在定时关机任务:
50
+ 安排新的关机前,pczzz 会检查是否已存在定时关机任务:
57
51
 
58
- 1. **自己的记录**(`~/.pcoff/task.json`):能显示确切的剩余时间,例如
52
+ 1. **自己的记录**(`~/.pczzz/task.json`):能显示确切的剩余时间,例如
59
53
  「当前已安排 1 小时 29 分钟 后关机(本工具于 23:01:35 设置)。要重新安排吗?(Y/N)」
60
54
  2. **系统级检测(仅 Windows)**:即使任务不是本工具设置的(比如手动执行过 `shutdown -s -t 3600`),也能检测到。Windows 在已有计划关机时再次执行 `shutdown` 会返回错误码 1190,据此弹出「要取消旧任务并重新安排吗?」的询问。外来任务拿不到剩余时间,只能提示存在。
61
55
 
@@ -66,18 +60,18 @@ pcoff cancel
66
60
  | 平台 | 精度 | 权限 | 说明 |
67
61
  | ------------- | ------ | ----------------------------- | ----------------------------------------------------- |
68
62
  | Windows | 秒级 | 无需管理员 | 完整支持,含系统级检测 |
69
- | macOS / Linux | 分钟级 | 需要 root(`sudo pcoff ...`) | `shutdown` 命令仅支持分钟;无系统级检测,依赖记录文件 |
63
+ | macOS / Linux | 分钟级 | 需要 root(`sudo pczzz ...`) | `shutdown` 命令仅支持分钟;无系统级检测,依赖记录文件 |
70
64
 
71
65
  ## 开发
72
66
 
73
67
  ```bash
74
68
  npm install
75
69
  npm run build # tsc 编译到 dist/
76
- npm test # 冒烟测试(PCOFF_DRY_RUN=1,不会真的关机)
77
- npm link # 本地全局试用 pcoff 命令
70
+ npm test # 冒烟测试(PCZZZ_DRY_RUN=1,不会真的关机)
71
+ npm link # 本地全局试用 pczzz 命令
78
72
  ```
79
73
 
80
- 测试钩子:`PCOFF_DRY_RUN=1` 跳过真实的 shutdown 调用;`PCOFF_HOME` 指定记录文件目录(默认 `~/.pcoff`)。
74
+ 测试钩子:`PCZZZ_DRY_RUN=1` 跳过真实的 shutdown 调用;`PCZZZ_HOME` 指定记录文件目录(默认 `~/.pczzz`)。
81
75
 
82
76
  ## 发布
83
77
 
package/dist/cli.js CHANGED
@@ -6,12 +6,12 @@ import { abortShutdown, scheduleShutdown } from './shutdown.js';
6
6
  import { Prompt } from './menu.js';
7
7
  import { bold, cyan, dim, green, red, yellow } from './ui.js';
8
8
  const { version: VERSION } = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
9
- const HELP = `pcoff — 定时关机小工具
9
+ const HELP = `pczzz — 定时关机小工具
10
10
 
11
11
  用法:
12
- pcoff 打开交互式菜单
13
- pcoff <时间> 指定时间后关机,例如: pcoff 30s
14
- pcoff cancel 取消当前已安排的定时关机
12
+ pczzz 打开交互式菜单
13
+ pczzz <时间> 指定时间后关机,例如: pczzz 30s
14
+ pczzz cancel 取消当前已安排的定时关机
15
15
 
16
16
  时间格式(可自由组合):
17
17
  30s 30 秒后 20m 20 分钟后 1h 1 小时后
@@ -24,15 +24,15 @@ const HELP = `pcoff — 定时关机小工具
24
24
 
25
25
  说明:
26
26
  · 关机计划由操作系统执行,退出本程序或关闭窗口不会取消它。
27
- · 取消方式: pcoff cancel,或菜单中的「取消当前关机」。
27
+ · 取消方式: pczzz cancel,或菜单中的「取消当前关机」。
28
28
  · Windows 完整支持(秒级精度,无需管理员权限)。
29
- · macOS / Linux: shutdown 需要 root 权限(sudo pcoff ...),且只能按分钟安排。`;
29
+ · macOS / Linux: shutdown 需要 root 权限(sudo pczzz ...),且只能按分钟安排。`;
30
30
  function fail(message) {
31
31
  console.error(message);
32
32
  process.exit(1);
33
33
  }
34
34
  function exitGracefully() {
35
- process.stdout.write('\n已退出。已设置的定时关机仍会执行;取消请运行 pcoff cancel。\n');
35
+ process.stdout.write('\n已退出。已设置的定时关机仍会执行;取消请运行 pczzz cancel。\n');
36
36
  process.exit(0);
37
37
  }
38
38
  /** 安排成功后的提示 + 倒计时。倒计时期间 Ctrl+C 随时退出,不影响系统层面的关机。 */
@@ -45,7 +45,7 @@ async function printScheduled(seconds) {
45
45
  console.log(yellow(`(记录文件写入失败,不影响已安排的关机:${err instanceof Error ? err.message : String(err)})`));
46
46
  }
47
47
  console.log(green(`✅ 已安排在本机 ${formatTimeOfDay(fireAt)} 自动关机(${formatDuration(seconds)} 后)。`));
48
- console.log(dim(' 关机由系统执行,关闭本窗口不影响;取消请运行 pcoff cancel。'));
48
+ console.log(dim(' 关机由系统执行,关闭本窗口不影响;取消请运行 pczzz cancel。'));
49
49
  startCountdown(seconds);
50
50
  }
51
51
  function startCountdown(seconds) {
@@ -68,7 +68,7 @@ function startCountdown(seconds) {
68
68
  * 返回 false 表示用户选择保留旧计划。
69
69
  *
70
70
  * 检测分两层:
71
- * 1. 记录文件(~/.pcoff/task.json):本工具自己设置的、尚未到期的任务,能给出剩余时间;
71
+ * 1. 记录文件(~/.pczzz/task.json):本工具自己设置的、尚未到期的任务,能给出剩余时间;
72
72
  * 2. Windows 系统探测:shutdown 若因错误码 1190 失败,说明系统里另有一个计划中的关机
73
73
  * (外来任务或重启后记录失效),此时询问用户是否取消旧的再排新的。
74
74
  */
@@ -78,7 +78,7 @@ async function scheduleWithCheck(prompt, seconds) {
78
78
  const remaining = Math.ceil((Date.parse(own.fireAt) - Date.now()) / 1000);
79
79
  const replace = await prompt.confirm(`当前已安排 ${bold(formatDuration(remaining))} 后关机(本工具于 ${formatTimeOfDay(new Date(own.createdAt))} 设置)。要重新安排吗?`);
80
80
  if (!replace) {
81
- console.log(dim('已保留原计划;取消请运行 pcoff cancel。'));
81
+ console.log(dim('已保留原计划;取消请运行 pczzz cancel。'));
82
82
  return false;
83
83
  }
84
84
  }
@@ -91,7 +91,7 @@ async function scheduleWithCheck(prompt, seconds) {
91
91
  if (!own) {
92
92
  const replace = await prompt.confirm('检测到系统已有一个定时关机任务(可能由其他方式设置,剩余时间未知)。要取消它并按新时间安排吗?');
93
93
  if (!replace) {
94
- console.log(dim('已保留现有计划;取消请运行 pcoff cancel。'));
94
+ console.log(dim('已保留现有计划;取消请运行 pczzz cancel。'));
95
95
  return false;
96
96
  }
97
97
  }
@@ -105,7 +105,7 @@ async function scheduleWithCheck(prompt, seconds) {
105
105
  }
106
106
  let message = red(`安排关机失败:${res.stderr || '未知错误'}`);
107
107
  if (process.platform !== 'win32' && /root|permission|permitt|not allowed/i.test(res.stderr)) {
108
- message += dim('\n(macOS/Linux 的 shutdown 需要 root 权限,可尝试:sudo pcoff ...)');
108
+ message += dim('\n(macOS/Linux 的 shutdown 需要 root 权限,可尝试:sudo pczzz ...)');
109
109
  }
110
110
  fail(message);
111
111
  }
@@ -167,7 +167,7 @@ async function main() {
167
167
  return;
168
168
  }
169
169
  if (argv.includes('-v') || argv.includes('--version')) {
170
- console.log(`pcoff v${VERSION}`);
170
+ console.log(`pczzz v${VERSION}`);
171
171
  return;
172
172
  }
173
173
  if (argv.includes('cancel') || argv.includes('-c')) {
@@ -181,11 +181,13 @@ async function main() {
181
181
  return;
182
182
  }
183
183
  if (argv.length > 1) {
184
- fail(red('参数太多,一次只接受一个时间。') + dim('\n用法:pcoff 30s / 20m / 1h;不带参数打开菜单;pcoff cancel 取消。'));
184
+ fail(red('参数太多,一次只接受一个时间。') +
185
+ dim('\n用法:pczzz 30s / 20m / 1h;不带参数打开菜单;pczzz cancel 取消。'));
185
186
  }
186
187
  const parsed = parseDuration(argv[0] ?? '');
187
188
  if (!parsed) {
188
- fail(red(`无法识别的时间:“${argv[0] ?? ''}”`) + dim('\n示例:30s / 20m / 1h / 1h30m;纯数字按秒计。详见 pcoff -h。'));
189
+ fail(red(`无法识别的时间:“${argv[0] ?? ''}”`) +
190
+ dim('\n示例:30s / 20m / 1h / 1h30m;纯数字按秒计。详见 pczzz -h。'));
189
191
  }
190
192
  if (parsed.totalSeconds < 1)
191
193
  fail(red('时间至少 1 秒。'));
package/dist/menu.js CHANGED
@@ -30,7 +30,7 @@ export class Prompt {
30
30
  });
31
31
  // readline 处于原始模式时 Ctrl+C 只会触发 'SIGINT' 事件,不会杀掉进程,需要自己接住
32
32
  this.rl.on('SIGINT', () => {
33
- stdout.write('\n已退出。已设置的定时关机仍会执行;取消请运行 pcoff cancel。\n');
33
+ stdout.write('\n已退出。已设置的定时关机仍会执行;取消请运行 pczzz cancel。\n');
34
34
  process.exit(0);
35
35
  });
36
36
  }
package/dist/shutdown.js CHANGED
@@ -31,12 +31,12 @@ function isAlreadyScheduled(code, stderr) {
31
31
  return Number(code) === WERR_SHUTDOWN_IS_SCHEDULED || stderr.includes('1190');
32
32
  }
33
33
  export async function scheduleShutdown(seconds) {
34
- if (process.env.PCOFF_DRY_RUN === '1') {
34
+ if (process.env.PCZZZ_DRY_RUN === '1') {
35
35
  return { ok: true, alreadyScheduled: false, stderr: '' };
36
36
  }
37
37
  try {
38
38
  if (process.platform === 'win32') {
39
- await exec('shutdown', ['/s', '/t', String(Math.round(seconds)), '/c', 'pcoff 定时关机'], {
39
+ await exec('shutdown', ['/s', '/t', String(Math.round(seconds)), '/c', 'pczzz 定时关机'], {
40
40
  windowsHide: true,
41
41
  encoding: 'buffer',
42
42
  });
@@ -54,7 +54,7 @@ export async function scheduleShutdown(seconds) {
54
54
  }
55
55
  }
56
56
  export async function abortShutdown() {
57
- if (process.env.PCOFF_DRY_RUN === '1') {
57
+ if (process.env.PCZZZ_DRY_RUN === '1') {
58
58
  return { ok: true, nothingPending: false, stderr: '' };
59
59
  }
60
60
  const args = process.platform === 'win32' ? ['/a'] : ['-c'];
package/dist/store.js CHANGED
@@ -2,7 +2,7 @@ import { promises as fs } from 'node:fs';
2
2
  import os from 'node:os';
3
3
  import path from 'node:path';
4
4
  function taskFile() {
5
- const base = process.env.PCOFF_HOME ?? path.join(os.homedir(), '.pcoff');
5
+ const base = process.env.PCZZZ_HOME ?? path.join(os.homedir(), '.pczzz');
6
6
  return path.join(base, 'task.json');
7
7
  }
8
8
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pczzz",
3
- "version": "0.0.4",
3
+ "version": "0.0.8",
4
4
  "description": "Timed shutdown command tool",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -14,6 +14,10 @@
14
14
  "files": [
15
15
  "dist"
16
16
  ],
17
+ "author": "chengxudong",
18
+ "publishConfig": {
19
+ "registry": "https://registry.npmjs.org/"
20
+ },
17
21
  "engines": {
18
22
  "node": ">=20"
19
23
  },