barkdesk-notify 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 BarkDesk contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,122 @@
1
+ # barkdesk-notify
2
+
3
+ `barkdesk-notify` 是独立、跨平台的 Bark CLI。它通过 npm 发布,可在 Linux、macOS 和 Windows 上运行;安装后提供简短的 `notify` 命令。
4
+
5
+ 该 package 只连接你配置的 Bark Server,不需要安装 BarkDesk macOS App。
6
+
7
+ ## 安装
8
+
9
+ 需要 Node.js 20.9 或更高版本:
10
+
11
+ ```bash
12
+ npm install -g barkdesk-notify
13
+ notify --version
14
+ ```
15
+
16
+ 不全局安装也可以直接运行:
17
+
18
+ ```bash
19
+ npx barkdesk-notify "任务完成"
20
+ ```
21
+
22
+ ## 配置
23
+
24
+ 个人电脑可以写入本机配置文件:
25
+
26
+ ```bash
27
+ notify config set \
28
+ --server https://bark.example.com \
29
+ --device DEVICE_KEY
30
+
31
+ notify config test
32
+ notify config show
33
+ ```
34
+
35
+ 配置文件会使用仅限当前用户读取的权限。执行 `notify config path` 可以查看实际位置。
36
+
37
+ Linux 服务器、容器和 CI 推荐使用环境变量,不需要在磁盘中保存 Device Key:
38
+
39
+ ```bash
40
+ export BARK_SERVER=https://bark.example.com
41
+ export BARK_DEVICE_KEY=DEVICE_KEY
42
+ notify "部署完成"
43
+ ```
44
+
45
+ 支持的变量:
46
+
47
+ - `BARK_SERVER`
48
+ - `BARK_DEVICE_KEY` 或 `BARK_DEVICE_KEY_FILE`
49
+ - `BARK_USERNAME`
50
+ - `BARK_PASSWORD` 或 `BARK_PASSWORD_FILE`
51
+ - `BARK_GROUP`、`BARK_LEVEL`、`BARK_SOUND`、`BARK_ARCHIVE`
52
+ - `BARKDESK_CONFIG` 和 `BARKDESK_HISTORY`,用于修改默认文件位置
53
+
54
+ Basic Auth 密码也可以通过 stdin 保存,避免直接出现在 shell 历史中:
55
+
56
+ ```bash
57
+ printf '%s' "$BARK_PASSWORD" | \
58
+ notify config set --username USER --password-stdin
59
+ ```
60
+
61
+ ## 使用
62
+
63
+ ```bash
64
+ notify "任务执行完成"
65
+ notify -t "Build" "构建完成"
66
+ echo "备份完成" | notify -t "Server"
67
+
68
+ notify "服务不可用" --level critical --volume 8
69
+ notify "查看产物" --image https://example.com/result.png
70
+ notify "发布完成" --url https://example.com/releases/42
71
+ notify --markdown $'## Build\n\n**Success**'
72
+ ```
73
+
74
+ 等待命令结束后发送通知:
75
+
76
+ ```bash
77
+ notify run pnpm build
78
+ notify run -g deploy -- ./deploy.sh --production
79
+ ```
80
+
81
+ `notify run` 始终返回原命令的退出码。Bark 发送失败只会输出警告,不会把失败命令改成成功。
82
+
83
+ 查看 CLI 自己的本机历史:
84
+
85
+ ```bash
86
+ notify history
87
+ notify history --search deploy --limit 50
88
+ ```
89
+
90
+ CLI 历史与 BarkDesk macOS App 历史相互独立,不会跨设备或跨系统同步。
91
+
92
+ ## 自动发布 package
93
+
94
+ 正式版本由仓库根目录的 GitHub Actions Release workflow 发布。先更新 `cli/package.json` 的版本并且提交,然后创建完全一致的版本 tag:
95
+
96
+ ```bash
97
+ git tag v1.0.0
98
+ git push origin main v1.0.0
99
+ ```
100
+
101
+ workflow 会执行测试、生成 npm tarball、发布到 npm,并且把 tarball 与 macOS DMG 一起添加到对应的 GitHub Release。npm Trusted Publishing 是推荐方式;第一次发布也可以临时配置 `NPM_TOKEN` repository secret。
102
+
103
+ GitHub Release 中的 tarball 也可以直接安装,不经过 npm Registry:
104
+
105
+ ```bash
106
+ npm install -g \
107
+ https://github.com/i1mT/bark-notify/releases/download/v1.0.0/barkdesk-notify-1.0.0.tgz
108
+ ```
109
+
110
+ 手动发布仅用于维护或故障恢复。发布前需要确认 npm 账号、package 名称和版本,然后执行:
111
+
112
+ ```bash
113
+ npm ci
114
+ npm test
115
+ npm pack --dry-run
116
+ npm login
117
+ npm publish
118
+ ```
119
+
120
+ 不要把 npm token、Device Key、Bark Server 凭据或个人配置文件提交到仓库。
121
+
122
+ 项目采用 MIT License。BarkDesk 是第三方开源项目,与 Bark 官方项目没有隶属关系。
@@ -0,0 +1,12 @@
1
+ import { CliError, type BarkPayload, type ResolvedConfig, type SendOptions } from "./types.js";
2
+ export interface PushResult {
3
+ httpStatus: number;
4
+ response: unknown;
5
+ }
6
+ export declare function makePayload(options: SendOptions, config: ResolvedConfig): BarkPayload;
7
+ export declare function push(payload: BarkPayload, config: ResolvedConfig): Promise<PushResult>;
8
+ export declare function testConnection(config: ResolvedConfig): Promise<string[]>;
9
+ export declare class BarkHttpError extends CliError {
10
+ readonly status: number;
11
+ constructor(status: number, message: string);
12
+ }
@@ -0,0 +1,115 @@
1
+ import { Buffer } from "node:buffer";
2
+ import { CliError } from "./types.js";
3
+ export function makePayload(options, config) {
4
+ const body = options.message ?? options.markdown ?? "";
5
+ const payload = { device_key: config.deviceKey, body };
6
+ assign(payload, "title", options.title);
7
+ assign(payload, "subtitle", options.subtitle);
8
+ assign(payload, "markdown", options.markdown);
9
+ assign(payload, "level", options.level ?? config.level);
10
+ assign(payload, "volume", options.volume);
11
+ assign(payload, "badge", options.badge);
12
+ assign(payload, "copy", options.copy);
13
+ assign(payload, "sound", options.sound ?? config.sound);
14
+ assign(payload, "icon", options.icon);
15
+ assign(payload, "image", options.image);
16
+ assign(payload, "group", options.group ?? config.group);
17
+ assign(payload, "ttl", options.ttl);
18
+ assign(payload, "url", options.url);
19
+ assign(payload, "id", options.id);
20
+ if (options.call)
21
+ payload.call = "1";
22
+ if (options.autoCopy)
23
+ payload.autoCopy = "1";
24
+ if (options.archive ?? config.archive)
25
+ payload.isArchive = "1";
26
+ if (options.noAction)
27
+ payload.action = "none";
28
+ return payload;
29
+ }
30
+ export async function push(payload, config) {
31
+ const response = await barkFetch(config, "push", {
32
+ method: "POST",
33
+ headers: { "Content-Type": "application/json; charset=utf-8" },
34
+ body: JSON.stringify(payload),
35
+ });
36
+ const parsed = await parseResponse(response);
37
+ const barkCode = responseObject(parsed)?.code;
38
+ if (!response.ok || (typeof barkCode === "number" && barkCode !== 200)) {
39
+ throw new BarkHttpError(response.status, responseMessage(parsed));
40
+ }
41
+ return { httpStatus: response.status, response: parsed };
42
+ }
43
+ export async function testConnection(config) {
44
+ const results = [];
45
+ await expectSuccess(await barkFetch(config, "ping"));
46
+ results.push("✓ Server reachable");
47
+ try {
48
+ await expectSuccess(await barkFetch(config, "info"));
49
+ results.push("✓ Server info available");
50
+ }
51
+ catch (error) {
52
+ results.push(`! Server info unavailable: ${messageOf(error)}`);
53
+ }
54
+ try {
55
+ await expectSuccess(await barkFetch(config, `register/${encodeURIComponent(config.deviceKey)}`, {}, false));
56
+ results.push("✓ Device registered");
57
+ }
58
+ catch (error) {
59
+ results.push(`! Device check unavailable: ${messageOf(error)}`);
60
+ }
61
+ return results;
62
+ }
63
+ export class BarkHttpError extends CliError {
64
+ status;
65
+ constructor(status, message) {
66
+ super(`Bark returned HTTP ${status}: ${message}`);
67
+ this.status = status;
68
+ this.name = "BarkHttpError";
69
+ }
70
+ }
71
+ async function barkFetch(config, path, init = {}, authenticated = true) {
72
+ const headers = new Headers(init.headers);
73
+ headers.set("User-Agent", "barkdesk-notify/1.0");
74
+ if (authenticated && config.username && config.password) {
75
+ headers.set("Authorization", `Basic ${Buffer.from(`${config.username}:${config.password}`).toString("base64")}`);
76
+ }
77
+ try {
78
+ return await fetch(`${config.server}/${path}`, { ...init, headers, signal: AbortSignal.timeout(20_000) });
79
+ }
80
+ catch (error) {
81
+ throw new CliError(`Could not reach Bark Server: ${messageOf(error)}`);
82
+ }
83
+ }
84
+ async function expectSuccess(response) {
85
+ if (!response.ok)
86
+ throw new BarkHttpError(response.status, responseMessage(await parseResponse(response)));
87
+ }
88
+ async function parseResponse(response) {
89
+ const text = await response.text();
90
+ if (!text)
91
+ return {};
92
+ try {
93
+ return JSON.parse(text);
94
+ }
95
+ catch {
96
+ return text;
97
+ }
98
+ }
99
+ function responseObject(value) {
100
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : undefined;
101
+ }
102
+ function responseMessage(value) {
103
+ if (typeof value === "string")
104
+ return value;
105
+ const object = responseObject(value);
106
+ return typeof object?.message === "string" ? object.message : "Unknown response";
107
+ }
108
+ function assign(target, key, value) {
109
+ if (value !== undefined && value !== "")
110
+ target[key] = value;
111
+ }
112
+ function messageOf(error) {
113
+ return error instanceof Error ? error.message : String(error);
114
+ }
115
+ //# sourceMappingURL=bark.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bark.js","sourceRoot":"","sources":["../../src/bark.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,QAAQ,EAA2D,MAAM,YAAY,CAAC;AAO/F,MAAM,UAAU,WAAW,CAAC,OAAoB,EAAE,MAAsB;IACtE,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;IACvD,MAAM,OAAO,GAAgB,EAAE,UAAU,EAAE,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC;IACpE,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC;IACxD,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC;IACxD,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC;IACxD,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IAClC,IAAI,OAAO,CAAC,IAAI;QAAE,OAAO,CAAC,IAAI,GAAG,GAAG,CAAC;IACrC,IAAI,OAAO,CAAC,QAAQ;QAAE,OAAO,CAAC,QAAQ,GAAG,GAAG,CAAC;IAC7C,IAAI,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,CAAC,SAAS,GAAG,GAAG,CAAC;IAC/D,IAAI,OAAO,CAAC,QAAQ;QAAE,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC;IAC9C,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,OAAoB,EAAE,MAAsB;IACrE,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE;QAC/C,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,iCAAiC,EAAE;QAC9D,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;KAC9B,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC;IAC9C,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,GAAG,CAAC,EAAE,CAAC;QACvE,MAAM,IAAI,aAAa,CAAC,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AAC3D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAAsB;IACzD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,aAAa,CAAC,MAAM,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACrD,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACnC,IAAI,CAAC;QAAC,MAAM,aAAa,CAAC,MAAM,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IAAC,CAAC;IACtG,OAAO,KAAK,EAAE,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,8BAA8B,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAAC,CAAC;IACjF,IAAI,CAAC;QACH,MAAM,aAAa,CAAC,MAAM,SAAS,CAAC,MAAM,EAAE,YAAY,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;QAC5G,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,+BAA+B,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAAC,CAAC;IACpF,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,OAAO,aAAc,SAAQ,QAAQ;IACpB;IAArB,YAAqB,MAAc,EAAE,OAAe;QAClD,KAAK,CAAC,sBAAsB,MAAM,KAAK,OAAO,EAAE,CAAC,CAAC;QAD/B,WAAM,GAAN,MAAM,CAAQ;QAEjC,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAED,KAAK,UAAU,SAAS,CAAC,MAAsB,EAAE,IAAY,EAAE,OAAoB,EAAE,EAAE,aAAa,GAAG,IAAI;IACzG,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,qBAAqB,CAAC,CAAC;IACjD,IAAI,aAAa,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,SAAS,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACnH,CAAC;IACD,IAAI,CAAC;QACH,OAAO,MAAM,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,IAAI,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC5G,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,QAAQ,CAAC,gCAAgC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACzE,CAAC;AACH,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,QAAkB;IAC7C,IAAI,CAAC,QAAQ,CAAC,EAAE;QAAE,MAAM,IAAI,aAAa,CAAC,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC7G,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,QAAkB;IAC7C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,IAAI,CAAC;QAAC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;AACpE,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACpC,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAgC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7H,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACrC,OAAO,OAAO,MAAM,EAAE,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC;AACnF,CAAC;AAED,SAAS,MAAM,CAA8B,MAAmB,EAAE,GAAM,EAAE,KAAiC;IACzG,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;QAAE,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAC/D,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { type ResolvedConfig, type StoredConfig } from "./types.js";
2
+ export declare function getConfigPath(environment?: NodeJS.ProcessEnv): string;
3
+ export declare function loadStoredConfig(path?: string): Promise<StoredConfig>;
4
+ export declare function saveStoredConfig(config: StoredConfig, path?: string): Promise<void>;
5
+ export declare function resolveConfig(environment?: NodeJS.ProcessEnv): Promise<ResolvedConfig>;
6
+ export declare function validateConfig(config: ResolvedConfig): ResolvedConfig;
7
+ export declare function masked(value: string | undefined): string;
@@ -0,0 +1,103 @@
1
+ import { chmod, mkdir, readFile, rename, writeFile } from "node:fs/promises";
2
+ import { homedir, platform } from "node:os";
3
+ import { dirname, join } from "node:path";
4
+ import { randomUUID } from "node:crypto";
5
+ import { barkLevels, CliError } from "./types.js";
6
+ export function getConfigPath(environment = process.env) {
7
+ if (environment.BARKDESK_CONFIG)
8
+ return environment.BARKDESK_CONFIG;
9
+ const home = homedir();
10
+ if (platform() === "win32")
11
+ return join(environment.APPDATA ?? join(home, "AppData", "Roaming"), "BarkDesk", "config.json");
12
+ if (platform() === "darwin")
13
+ return join(home, "Library", "Application Support", "BarkDesk", "cli.json");
14
+ return join(environment.XDG_CONFIG_HOME ?? join(home, ".config"), "barkdesk", "config.json");
15
+ }
16
+ export async function loadStoredConfig(path = getConfigPath()) {
17
+ try {
18
+ const parsed = JSON.parse(await readFile(path, "utf8"));
19
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
20
+ throw new CliError(`Invalid configuration file: ${path}`);
21
+ return parsed;
22
+ }
23
+ catch (error) {
24
+ if (isErrorCode(error, "ENOENT"))
25
+ return {};
26
+ if (error instanceof SyntaxError)
27
+ throw new CliError(`Invalid JSON in configuration file: ${path}`);
28
+ throw error;
29
+ }
30
+ }
31
+ export async function saveStoredConfig(config, path = getConfigPath()) {
32
+ const directory = dirname(path);
33
+ await mkdir(directory, { recursive: true, mode: 0o700 });
34
+ const temporary = join(directory, `.config-${randomUUID()}.tmp`);
35
+ await writeFile(temporary, `${JSON.stringify(config, null, 2)}\n`, { mode: 0o600 });
36
+ await rename(temporary, path);
37
+ if (platform() !== "win32")
38
+ await chmod(path, 0o600);
39
+ }
40
+ export async function resolveConfig(environment = process.env) {
41
+ const stored = await loadStoredConfig(getConfigPath(environment));
42
+ const deviceFromFile = await secretFromFile(environment.BARK_DEVICE_KEY_FILE);
43
+ const passwordFromFile = await secretFromFile(environment.BARK_PASSWORD_FILE);
44
+ const rawLevel = environment.BARK_LEVEL ?? stored.level ?? "active";
45
+ if (!barkLevels.includes(rawLevel))
46
+ throw new CliError(`Invalid BARK_LEVEL: ${rawLevel}`);
47
+ const config = {
48
+ server: environment.BARK_SERVER ?? stored.server ?? "",
49
+ deviceKey: environment.BARK_DEVICE_KEY ?? deviceFromFile ?? stored.deviceKey ?? "",
50
+ group: environment.BARK_GROUP ?? stored.group ?? "terminal",
51
+ level: rawLevel,
52
+ archive: environment.BARK_ARCHIVE === undefined ? (stored.archive ?? true) : parseBoolean(environment.BARK_ARCHIVE, "BARK_ARCHIVE"),
53
+ };
54
+ const username = environment.BARK_USERNAME ?? stored.username;
55
+ const password = environment.BARK_PASSWORD ?? passwordFromFile ?? stored.password;
56
+ const sound = environment.BARK_SOUND ?? stored.sound;
57
+ if (username)
58
+ config.username = username;
59
+ if (password)
60
+ config.password = password;
61
+ if (sound)
62
+ config.sound = sound;
63
+ return validateConfig(config);
64
+ }
65
+ export function validateConfig(config) {
66
+ let url;
67
+ try {
68
+ url = new URL(config.server);
69
+ }
70
+ catch {
71
+ throw new CliError("Configure a valid Bark Server URL with notify config set --server URL");
72
+ }
73
+ if (!["http:", "https:"].includes(url.protocol) || !url.hostname) {
74
+ throw new CliError("Bark Server must use http:// or https://");
75
+ }
76
+ if (!config.deviceKey.trim())
77
+ throw new CliError("Configure a Device Key with notify config set --device KEY");
78
+ if ((config.username && !config.password) || (!config.username && config.password)) {
79
+ throw new CliError("Basic Auth requires both username and password");
80
+ }
81
+ return { ...config, server: config.server.replace(/\/+$/, ""), deviceKey: config.deviceKey.trim() };
82
+ }
83
+ export function masked(value) {
84
+ if (!value)
85
+ return "Not configured";
86
+ return `••••${value.slice(-4)}`;
87
+ }
88
+ async function secretFromFile(path) {
89
+ if (!path)
90
+ return undefined;
91
+ return (await readFile(path, "utf8")).trim();
92
+ }
93
+ function parseBoolean(value, name) {
94
+ if (["1", "true", "yes", "on"].includes(value.toLowerCase()))
95
+ return true;
96
+ if (["0", "false", "no", "off"].includes(value.toLowerCase()))
97
+ return false;
98
+ throw new CliError(`${name} must be true or false`);
99
+ }
100
+ function isErrorCode(error, code) {
101
+ return error instanceof Error && "code" in error && error.code === code;
102
+ }
103
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAA0D,MAAM,YAAY,CAAC;AAE1G,MAAM,UAAU,aAAa,CAAC,cAAiC,OAAO,CAAC,GAAG;IACxE,IAAI,WAAW,CAAC,eAAe;QAAE,OAAO,WAAW,CAAC,eAAe,CAAC;IACpE,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,IAAI,QAAQ,EAAE,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;IAC5H,IAAI,QAAQ,EAAE,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,qBAAqB,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;IACzG,OAAO,IAAI,CAAC,WAAW,CAAC,eAAe,IAAI,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;AAC/F,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAI,GAAG,aAAa,EAAE;IAC3D,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;QACjE,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YAAE,MAAM,IAAI,QAAQ,CAAC,+BAA+B,IAAI,EAAE,CAAC,CAAC;QAC9H,OAAO,MAAsB,CAAC;IAChC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC;YAAE,OAAO,EAAE,CAAC;QAC5C,IAAI,KAAK,YAAY,WAAW;YAAE,MAAM,IAAI,QAAQ,CAAC,uCAAuC,IAAI,EAAE,CAAC,CAAC;QACpG,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,MAAoB,EAAE,IAAI,GAAG,aAAa,EAAE;IACjF,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACzD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,UAAU,EAAE,MAAM,CAAC,CAAC;IACjE,MAAM,SAAS,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACpF,MAAM,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC9B,IAAI,QAAQ,EAAE,KAAK,OAAO;QAAE,MAAM,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,cAAiC,OAAO,CAAC,GAAG;IAC9E,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC;IAClE,MAAM,cAAc,GAAG,MAAM,cAAc,CAAC,WAAW,CAAC,oBAAoB,CAAC,CAAC;IAC9E,MAAM,gBAAgB,GAAG,MAAM,cAAc,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC;IAC9E,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,IAAI,MAAM,CAAC,KAAK,IAAI,QAAQ,CAAC;IACpE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,QAAqB,CAAC;QAAE,MAAM,IAAI,QAAQ,CAAC,uBAAuB,QAAQ,EAAE,CAAC,CAAC;IACvG,MAAM,MAAM,GAAmB;QAC7B,MAAM,EAAE,WAAW,CAAC,WAAW,IAAI,MAAM,CAAC,MAAM,IAAI,EAAE;QACtD,SAAS,EAAE,WAAW,CAAC,eAAe,IAAI,cAAc,IAAI,MAAM,CAAC,SAAS,IAAI,EAAE;QAClF,KAAK,EAAE,WAAW,CAAC,UAAU,IAAI,MAAM,CAAC,KAAK,IAAI,UAAU;QAC3D,KAAK,EAAE,QAAqB;QAC5B,OAAO,EAAE,WAAW,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,WAAW,CAAC,YAAY,EAAE,cAAc,CAAC;KACpI,CAAC;IACF,MAAM,QAAQ,GAAG,WAAW,CAAC,aAAa,IAAI,MAAM,CAAC,QAAQ,CAAC;IAC9D,MAAM,QAAQ,GAAG,WAAW,CAAC,aAAa,IAAI,gBAAgB,IAAI,MAAM,CAAC,QAAQ,CAAC;IAClF,MAAM,KAAK,GAAG,WAAW,CAAC,UAAU,IAAI,MAAM,CAAC,KAAK,CAAC;IACrD,IAAI,QAAQ;QAAE,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACzC,IAAI,QAAQ;QAAE,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACzC,IAAI,KAAK;QAAE,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;IAChC,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAsB;IACnD,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QAAC,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,MAAM,IAAI,QAAQ,CAAC,uEAAuE,CAAC,CAAC;IAAC,CAAC;IAC5I,IAAI,CAAE,CAAC,OAAO,EAAE,QAAQ,CAAc,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC/E,MAAM,IAAI,QAAQ,CAAC,0CAA0C,CAAC,CAAC;IACjE,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE;QAAE,MAAM,IAAI,QAAQ,CAAC,4DAA4D,CAAC,CAAC;IAC/G,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnF,MAAM,IAAI,QAAQ,CAAC,gDAAgD,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;AACtG,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,KAAyB;IAC9C,IAAI,CAAC,KAAK;QAAE,OAAO,gBAAgB,CAAC;IACpC,OAAO,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAClC,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,IAAwB;IACpD,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AAC/C,CAAC;AAED,SAAS,YAAY,CAAC,KAAa,EAAE,IAAY;IAC/C,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1E,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5E,MAAM,IAAI,QAAQ,CAAC,GAAG,IAAI,wBAAwB,CAAC,CAAC;AACtD,CAAC;AAED,SAAS,WAAW,CAAC,KAAc,EAAE,IAAY;IAC/C,OAAO,KAAK,YAAY,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC;AAC1E,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { HistoryRecord } from "./types.js";
2
+ export declare function getHistoryPath(environment?: NodeJS.ProcessEnv): string;
3
+ export declare function appendHistory(record: HistoryRecord, path?: string): Promise<void>;
4
+ export declare function readHistory(search: string | undefined, limit: number, path?: string): Promise<HistoryRecord[]>;
@@ -0,0 +1,54 @@
1
+ import { appendFile, chmod, mkdir, readFile, rename, stat, writeFile } from "node:fs/promises";
2
+ import { homedir, platform } from "node:os";
3
+ import { dirname, join } from "node:path";
4
+ import { randomUUID } from "node:crypto";
5
+ const maximumBytes = 1_000_000;
6
+ const retainedRecords = 1_000;
7
+ export function getHistoryPath(environment = process.env) {
8
+ if (environment.BARKDESK_HISTORY)
9
+ return environment.BARKDESK_HISTORY;
10
+ const home = homedir();
11
+ if (platform() === "win32")
12
+ return join(environment.LOCALAPPDATA ?? join(home, "AppData", "Local"), "BarkDesk", "history.jsonl");
13
+ if (platform() === "darwin")
14
+ return join(home, "Library", "Application Support", "BarkDesk", "CLI", "history.jsonl");
15
+ return join(environment.XDG_STATE_HOME ?? join(home, ".local", "state"), "barkdesk", "history.jsonl");
16
+ }
17
+ export async function appendHistory(record, path = getHistoryPath()) {
18
+ await mkdir(dirname(path), { recursive: true, mode: 0o700 });
19
+ await appendFile(path, `${JSON.stringify(record)}\n`, { mode: 0o600 });
20
+ if (platform() !== "win32")
21
+ await chmod(path, 0o600);
22
+ if ((await stat(path)).size > maximumBytes)
23
+ await compact(path);
24
+ }
25
+ export async function readHistory(search, limit, path = getHistoryPath()) {
26
+ let content;
27
+ try {
28
+ content = await readFile(path, "utf8");
29
+ }
30
+ catch (error) {
31
+ if (isErrorCode(error, "ENOENT"))
32
+ return [];
33
+ throw error;
34
+ }
35
+ const query = search?.toLowerCase();
36
+ return content.split("\n").filter(Boolean).flatMap((line) => {
37
+ try {
38
+ return [JSON.parse(line)];
39
+ }
40
+ catch {
41
+ return [];
42
+ }
43
+ }).filter((record) => !query || JSON.stringify(record).toLowerCase().includes(query)).slice(-limit).reverse();
44
+ }
45
+ async function compact(path) {
46
+ const records = await readHistory(undefined, retainedRecords, path);
47
+ const temporary = join(dirname(path), `.history-${randomUUID()}.tmp`);
48
+ await writeFile(temporary, records.reverse().map((record) => JSON.stringify(record)).join("\n") + "\n", { mode: 0o600 });
49
+ await rename(temporary, path);
50
+ }
51
+ function isErrorCode(error, code) {
52
+ return error instanceof Error && "code" in error && error.code === code;
53
+ }
54
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/history.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { run } from "./runner.js";
3
+ process.exitCode = await run(process.argv.slice(2));
4
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAElC,OAAO,CAAC,QAAQ,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type CliCommand, type SendOptions } from "./types.js";
2
+ export declare function emptySendOptions(): SendOptions;
3
+ export declare function parseArguments(arguments_: string[]): CliCommand;
@@ -0,0 +1,227 @@
1
+ import { barkLevels, CliError } from "./types.js";
2
+ export function emptySendOptions() {
3
+ return { call: false, autoCopy: false, noAction: false, quiet: false };
4
+ }
5
+ export function parseArguments(arguments_) {
6
+ const [first] = arguments_;
7
+ if (first === "help" || first === "--help" || first === "-h")
8
+ return { kind: "help" };
9
+ if (first === "version" || first === "--version")
10
+ return { kind: "version" };
11
+ if (first === "run")
12
+ return parseRun(arguments_.slice(1));
13
+ if (first === "config")
14
+ return parseConfig(arguments_.slice(1));
15
+ if (first === "history")
16
+ return parseHistory(arguments_.slice(1));
17
+ const result = parseSend(arguments_, false);
18
+ if (result.index !== arguments_.length)
19
+ usage(`Unexpected argument: ${arguments_[result.index]}`);
20
+ return { kind: "send", options: result.options };
21
+ }
22
+ function parseRun(arguments_) {
23
+ const result = parseSend(arguments_, true);
24
+ const command = arguments_.slice(result.index);
25
+ if (command.length === 0)
26
+ usage("notify run requires a command");
27
+ return { kind: "run", options: result.options, command };
28
+ }
29
+ function parseSend(arguments_, stopAtCommand) {
30
+ const options = emptySendOptions();
31
+ let index = 0;
32
+ while (index < arguments_.length) {
33
+ const argument = arguments_[index];
34
+ if (argument === "--") {
35
+ index += 1;
36
+ break;
37
+ }
38
+ if (stopAtCommand && !argument?.startsWith("-"))
39
+ break;
40
+ switch (argument) {
41
+ case "-m":
42
+ case "--message":
43
+ [options.message, index] = value(arguments_, index, argument);
44
+ break;
45
+ case "-t":
46
+ case "--title":
47
+ [options.title, index] = value(arguments_, index, argument);
48
+ break;
49
+ case "-s":
50
+ case "--subtitle":
51
+ [options.subtitle, index] = value(arguments_, index, argument);
52
+ break;
53
+ case "--markdown":
54
+ [options.markdown, index] = value(arguments_, index, argument);
55
+ break;
56
+ case "-g":
57
+ case "--group":
58
+ [options.group, index] = value(arguments_, index, argument);
59
+ break;
60
+ case "--level":
61
+ [options.level, index] = levelValue(arguments_, index, argument);
62
+ break;
63
+ case "--sound":
64
+ [options.sound, index] = value(arguments_, index, argument);
65
+ break;
66
+ case "--icon":
67
+ [options.icon, index] = value(arguments_, index, argument);
68
+ break;
69
+ case "--image":
70
+ [options.image, index] = value(arguments_, index, argument);
71
+ break;
72
+ case "--url":
73
+ [options.url, index] = value(arguments_, index, argument);
74
+ break;
75
+ case "--copy":
76
+ [options.copy, index] = value(arguments_, index, argument);
77
+ break;
78
+ case "--volume":
79
+ [options.volume, index] = integer(arguments_, index, argument, 0, 10);
80
+ break;
81
+ case "--badge":
82
+ [options.badge, index] = integer(arguments_, index, argument);
83
+ break;
84
+ case "--ttl":
85
+ [options.ttl, index] = integer(arguments_, index, argument, 1);
86
+ break;
87
+ case "--call":
88
+ options.call = true;
89
+ index += 1;
90
+ break;
91
+ case "--auto-copy":
92
+ options.autoCopy = true;
93
+ index += 1;
94
+ break;
95
+ case "--archive":
96
+ options.archive = true;
97
+ index += 1;
98
+ break;
99
+ case "--no-archive":
100
+ options.archive = false;
101
+ index += 1;
102
+ break;
103
+ case "--no-action":
104
+ options.noAction = true;
105
+ index += 1;
106
+ break;
107
+ case "--id":
108
+ [options.id, index] = value(arguments_, index, argument);
109
+ break;
110
+ case "-q":
111
+ case "--quiet":
112
+ options.quiet = true;
113
+ index += 1;
114
+ break;
115
+ default:
116
+ if (!stopAtCommand && argument && !argument.startsWith("-") && options.message === undefined) {
117
+ options.message = argument;
118
+ index += 1;
119
+ }
120
+ else if (stopAtCommand) {
121
+ return { options, index };
122
+ }
123
+ else {
124
+ usage(`Unknown option: ${argument}`);
125
+ }
126
+ }
127
+ }
128
+ return { options, index };
129
+ }
130
+ function parseConfig(arguments_) {
131
+ const action = arguments_[0] ?? "show";
132
+ if (action === "show")
133
+ return { kind: "config-show" };
134
+ if (action === "path")
135
+ return { kind: "config-path" };
136
+ if (action === "test")
137
+ return { kind: "config-test" };
138
+ if (action !== "set")
139
+ usage(`Unknown config command: ${action}`);
140
+ const updates = { noAuth: false, passwordStdin: false };
141
+ let index = 1;
142
+ while (index < arguments_.length) {
143
+ const argument = arguments_[index];
144
+ switch (argument) {
145
+ case "--server":
146
+ [updates.server, index] = value(arguments_, index, argument);
147
+ break;
148
+ case "--device":
149
+ [updates.deviceKey, index] = value(arguments_, index, argument);
150
+ break;
151
+ case "--group":
152
+ [updates.group, index] = value(arguments_, index, argument);
153
+ break;
154
+ case "--sound":
155
+ [updates.sound, index] = value(arguments_, index, argument);
156
+ break;
157
+ case "--username":
158
+ [updates.username, index] = value(arguments_, index, argument);
159
+ break;
160
+ case "--password":
161
+ [updates.password, index] = value(arguments_, index, argument);
162
+ break;
163
+ case "--level":
164
+ [updates.level, index] = levelValue(arguments_, index, argument);
165
+ break;
166
+ case "--archive":
167
+ updates.archive = true;
168
+ index += 1;
169
+ break;
170
+ case "--no-archive":
171
+ updates.archive = false;
172
+ index += 1;
173
+ break;
174
+ case "--no-auth":
175
+ updates.noAuth = true;
176
+ index += 1;
177
+ break;
178
+ case "--password-stdin":
179
+ updates.passwordStdin = true;
180
+ index += 1;
181
+ break;
182
+ default: usage(`Unknown config option: ${argument}`);
183
+ }
184
+ }
185
+ if (updates.password !== undefined && updates.passwordStdin)
186
+ usage("Use either --password or --password-stdin, not both");
187
+ return { kind: "config-set", updates };
188
+ }
189
+ function parseHistory(arguments_) {
190
+ let search;
191
+ let limit = 20;
192
+ let index = 0;
193
+ while (index < arguments_.length) {
194
+ const argument = arguments_[index];
195
+ if (argument === "--search")
196
+ [search, index] = value(arguments_, index, argument);
197
+ else if (argument === "--limit")
198
+ [limit, index] = integer(arguments_, index, argument, 1, 500);
199
+ else
200
+ usage(`Unknown history option: ${argument}`);
201
+ }
202
+ return search === undefined ? { kind: "history", limit } : { kind: "history", search, limit };
203
+ }
204
+ function value(arguments_, index, option) {
205
+ const result = arguments_[index + 1];
206
+ if (result === undefined)
207
+ usage(`${option} requires a value`);
208
+ return [result, index + 2];
209
+ }
210
+ function integer(arguments_, index, option, minimum, maximum) {
211
+ const [raw, next] = value(arguments_, index, option);
212
+ const result = Number(raw);
213
+ if (!Number.isInteger(result) || (minimum !== undefined && result < minimum) || (maximum !== undefined && result > maximum)) {
214
+ usage(`Invalid value for ${option}: ${raw}`);
215
+ }
216
+ return [result, next];
217
+ }
218
+ function levelValue(arguments_, index, option) {
219
+ const [raw, next] = value(arguments_, index, option);
220
+ if (!barkLevels.includes(raw))
221
+ usage(`Invalid level: ${raw}`);
222
+ return [raw, next];
223
+ }
224
+ function usage(message) {
225
+ throw new CliError(message, true);
226
+ }
227
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAyE,MAAM,YAAY,CAAC;AAEzH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,UAAoB;IACjD,MAAM,CAAC,KAAK,CAAC,GAAG,UAAU,CAAC;IAC3B,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACtF,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,WAAW;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC7E,IAAI,KAAK,KAAK,KAAK;QAAE,OAAO,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,IAAI,KAAK,KAAK,QAAQ;QAAE,OAAO,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAChE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,SAAS,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAC5C,IAAI,MAAM,CAAC,KAAK,KAAK,UAAU,CAAC,MAAM;QAAE,KAAK,CAAC,wBAAwB,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;AACnD,CAAC;AAED,SAAS,QAAQ,CAAC,UAAoB;IACpC,MAAM,MAAM,GAAG,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACjE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;AAC3D,CAAC;AAED,SAAS,SAAS,CAAC,UAAoB,EAAE,aAAsB;IAC7D,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;IACnC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,OAAO,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YAAC,KAAK,IAAI,CAAC,CAAC;YAAC,MAAM;QAAC,CAAC;QAC7C,IAAI,aAAa,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,GAAG,CAAC;YAAE,MAAM;QACvD,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,IAAI,CAAC;YAAC,KAAK,WAAW;gBAAE,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAAC,MAAM;YAClG,KAAK,IAAI,CAAC;YAAC,KAAK,SAAS;gBAAE,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAAC,MAAM;YAC9F,KAAK,IAAI,CAAC;YAAC,KAAK,YAAY;gBAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAAC,MAAM;YACpG,KAAK,YAAY;gBAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAAC,MAAM;YACzF,KAAK,IAAI,CAAC;YAAC,KAAK,SAAS;gBAAE,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAAC,MAAM;YAC9F,KAAK,SAAS;gBAAE,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,UAAU,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAAC,MAAM;YACxF,KAAK,SAAS;gBAAE,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAAC,MAAM;YACnF,KAAK,QAAQ;gBAAE,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAAC,MAAM;YACjF,KAAK,SAAS;gBAAE,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAAC,MAAM;YACnF,KAAK,OAAO;gBAAE,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAAC,MAAM;YAC/E,KAAK,QAAQ;gBAAE,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAAC,MAAM;YACjF,KAAK,UAAU;gBAAE,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;gBAAC,MAAM;YAC9F,KAAK,SAAS;gBAAE,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAAC,MAAM;YACrF,KAAK,OAAO;gBAAE,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;gBAAC,MAAM;YACpF,KAAK,QAAQ;gBAAE,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;gBAAC,KAAK,IAAI,CAAC,CAAC;gBAAC,MAAM;YACtD,KAAK,aAAa;gBAAE,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;gBAAC,KAAK,IAAI,CAAC,CAAC;gBAAC,MAAM;YAC/D,KAAK,WAAW;gBAAE,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;gBAAC,KAAK,IAAI,CAAC,CAAC;gBAAC,MAAM;YAC5D,KAAK,cAAc;gBAAE,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC;gBAAC,KAAK,IAAI,CAAC,CAAC;gBAAC,MAAM;YAChE,KAAK,aAAa;gBAAE,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;gBAAC,KAAK,IAAI,CAAC,CAAC;gBAAC,MAAM;YAC/D,KAAK,MAAM;gBAAE,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAAC,MAAM;YAC7E,KAAK,IAAI,CAAC;YAAC,KAAK,SAAS;gBAAE,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;gBAAC,KAAK,IAAI,CAAC,CAAC;gBAAC,MAAM;YACnE;gBACE,IAAI,CAAC,aAAa,IAAI,QAAQ,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;oBAC7F,OAAO,CAAC,OAAO,GAAG,QAAQ,CAAC;oBAC3B,KAAK,IAAI,CAAC,CAAC;gBACb,CAAC;qBAAM,IAAI,aAAa,EAAE,CAAC;oBACzB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;gBAC5B,CAAC;qBAAM,CAAC;oBACN,KAAK,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;gBACvC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC5B,CAAC;AAED,SAAS,WAAW,CAAC,UAAoB;IACvC,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC;IACvC,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;IACtD,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;IACtD,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;IACtD,IAAI,MAAM,KAAK,KAAK;QAAE,KAAK,CAAC,2BAA2B,MAAM,EAAE,CAAC,CAAC;IACjE,MAAM,OAAO,GAAkB,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;IACvE,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,OAAO,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QACnC,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,UAAU;gBAAE,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAAC,MAAM;YACrF,KAAK,UAAU;gBAAE,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAAC,MAAM;YACxF,KAAK,SAAS;gBAAE,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAAC,MAAM;YACnF,KAAK,SAAS;gBAAE,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAAC,MAAM;YACnF,KAAK,YAAY;gBAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAAC,MAAM;YACzF,KAAK,YAAY;gBAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAAC,MAAM;YACzF,KAAK,SAAS;gBAAE,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,UAAU,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAAC,MAAM;YACxF,KAAK,WAAW;gBAAE,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;gBAAC,KAAK,IAAI,CAAC,CAAC;gBAAC,MAAM;YAC5D,KAAK,cAAc;gBAAE,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC;gBAAC,KAAK,IAAI,CAAC,CAAC;gBAAC,MAAM;YAChE,KAAK,WAAW;gBAAE,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;gBAAC,KAAK,IAAI,CAAC,CAAC;gBAAC,MAAM;YAC3D,KAAK,kBAAkB;gBAAE,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;gBAAC,KAAK,IAAI,CAAC,CAAC;gBAAC,MAAM;YACzE,OAAO,CAAC,CAAC,KAAK,CAAC,0BAA0B,QAAQ,EAAE,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,IAAI,OAAO,CAAC,aAAa;QAAE,KAAK,CAAC,qDAAqD,CAAC,CAAC;IAC1H,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC;AACzC,CAAC;AAED,SAAS,YAAY,CAAC,UAAoB;IACxC,IAAI,MAA0B,CAAC;IAC/B,IAAI,KAAK,GAAG,EAAE,CAAC;IACf,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,OAAO,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,QAAQ,KAAK,UAAU;YAAE,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;aAC7E,IAAI,QAAQ,KAAK,SAAS;YAAE,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;;YAC1F,KAAK,CAAC,2BAA2B,QAAQ,EAAE,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAChG,CAAC;AAED,SAAS,KAAK,CAAC,UAAoB,EAAE,KAAa,EAAE,MAAc;IAChE,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IACrC,IAAI,MAAM,KAAK,SAAS;QAAE,KAAK,CAAC,GAAG,MAAM,mBAAmB,CAAC,CAAC;IAC9D,OAAO,CAAC,MAAM,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,OAAO,CAAC,UAAoB,EAAE,KAAa,EAAE,MAAc,EAAE,OAAgB,EAAE,OAAgB;IACtG,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;QAC5H,KAAK,CAAC,qBAAqB,MAAM,KAAK,GAAG,EAAE,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACxB,CAAC;AAED,SAAS,UAAU,CAAC,UAAoB,EAAE,KAAa,EAAE,MAAc;IACrE,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACrD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAgB,CAAC;QAAE,KAAK,CAAC,kBAAkB,GAAG,EAAE,CAAC,CAAC;IAC3E,OAAO,CAAC,GAAgB,EAAE,IAAI,CAAC,CAAC;AAClC,CAAC;AAED,SAAS,KAAK,CAAC,OAAe;IAC5B,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AACpC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function run(arguments_: string[]): Promise<number>;
2
+ export declare const helpText = "notify \u2014 send Bark notifications from Linux, macOS, or Windows\n\nUSAGE\n notify \"Message\"\n echo \"Message\" | notify -t \"Title\"\n notify run [notification options] -- command [arguments]\n notify config show|path|test|set [options]\n notify history [--search text] [--limit number]\n\nCOMMON OPTIONS\n -m, --message TEXT Notification body\n -t, --title TEXT Title\n -s, --subtitle TEXT Subtitle\n -g, --group TEXT Group\n --level LEVEL active, timeSensitive, passive, critical\n --sound NAME Bark sound\n --icon URL Custom icon\n --image URL Image attachment\n --url URL Open URL when tapped\n --markdown TEXT Markdown body\n --volume 0...10 Critical alert volume\n --badge NUMBER App badge\n --call Repeat ringtone\n --auto-copy Enable automatic copy\n --copy TEXT Copy action text\n --archive Archive in Bark\n --no-archive Do not archive in Bark\n --ttl SECONDS Archived-message lifetime\n --no-action Tapping performs no action\n -q, --quiet No success output\n\nCONFIGURATION\n notify config set --server URL --device KEY\n printf '%s' \"$BARK_PASSWORD\" | notify config set --username USER --password-stdin\n\nSERVER ENVIRONMENT\n BARK_SERVER, BARK_DEVICE_KEY, BARK_DEVICE_KEY_FILE\n BARK_USERNAME, BARK_PASSWORD, BARK_PASSWORD_FILE\n BARK_GROUP, BARK_LEVEL, BARK_SOUND, BARK_ARCHIVE\n";
@@ -0,0 +1,208 @@
1
+ import { constants } from "node:os";
2
+ import { spawn } from "node:child_process";
3
+ import { appendHistory, getHistoryPath, readHistory } from "./history.js";
4
+ import { getConfigPath, loadStoredConfig, masked, resolveConfig, saveStoredConfig } from "./config.js";
5
+ import { BarkHttpError, makePayload, push, testConnection } from "./bark.js";
6
+ import { parseArguments } from "./parser.js";
7
+ import { CliError } from "./types.js";
8
+ export async function run(arguments_) {
9
+ try {
10
+ return await execute(parseArguments(arguments_));
11
+ }
12
+ catch (error) {
13
+ process.stderr.write(`Error: ${messageOf(error)}\n`);
14
+ if (error instanceof CliError && error.showHelpHint)
15
+ process.stderr.write("Run 'notify --help' for usage.\n");
16
+ return 1;
17
+ }
18
+ }
19
+ async function execute(command) {
20
+ switch (command.kind) {
21
+ case "help":
22
+ console.log(helpText);
23
+ return 0;
24
+ case "version":
25
+ console.log("notify 1.0.0");
26
+ return 0;
27
+ case "config-show":
28
+ await showConfig();
29
+ return 0;
30
+ case "config-path":
31
+ console.log(getConfigPath());
32
+ return 0;
33
+ case "config-test":
34
+ for (const line of await testConnection(await resolveConfig()))
35
+ console.log(line);
36
+ return 0;
37
+ case "config-set":
38
+ await updateConfig(command.updates);
39
+ return 0;
40
+ case "history":
41
+ await showHistory(command.search, command.limit);
42
+ return 0;
43
+ case "send": return sendCommand(command.options);
44
+ case "run": return runCommand(command.options, command.command);
45
+ }
46
+ }
47
+ async function sendCommand(options) {
48
+ if (!options.message && !options.markdown && !process.stdin.isTTY)
49
+ options.message = (await readStandardInput()).trimEnd();
50
+ if (!(options.message ?? options.markdown ?? "").trim())
51
+ throw new CliError("Provide a message, use --message, or pipe text through stdin.", true);
52
+ await deliver(options, "send");
53
+ if (!options.quiet)
54
+ console.log("✓ Notification sent");
55
+ return 0;
56
+ }
57
+ async function runCommand(options, command) {
58
+ const start = Date.now();
59
+ const result = await spawnCommand(command);
60
+ const durationSeconds = (Date.now() - start) / 1000;
61
+ const succeeded = result.code === 0 && result.signal === null;
62
+ const exitCode = result.signal ? 128 + signalNumber(result.signal) : (result.code ?? 1);
63
+ const commandText = command.map(shellQuote).join(" ");
64
+ if (!options.title)
65
+ options.title = succeeded ? "Command completed" : "Command failed";
66
+ if (!options.message && !options.markdown) {
67
+ const exitLine = succeeded ? "" : `\nExit Code: ${exitCode}`;
68
+ options.message = `${succeeded ? "✅" : "❌"} ${options.title}\n\n${commandText}${exitLine}\nDuration: ${formatDuration(durationSeconds)}`;
69
+ }
70
+ if (!succeeded && !options.level)
71
+ options.level = "timeSensitive";
72
+ try {
73
+ await deliver(options, "run", { command: commandText, exitCode, durationSeconds });
74
+ if (!options.quiet)
75
+ console.log("✓ Command notification sent");
76
+ }
77
+ catch (error) {
78
+ process.stderr.write(`Warning: could not send notification: ${messageOf(error)}\n`);
79
+ }
80
+ return exitCode;
81
+ }
82
+ async function deliver(options, source, metadata = {}) {
83
+ const config = await resolveConfig();
84
+ const payload = makePayload(options, config);
85
+ const base = {
86
+ createdAt: new Date().toISOString(), source, body: payload.body,
87
+ ...(payload.title ? { title: payload.title } : {}),
88
+ ...(payload.group ? { group: payload.group } : {}), ...metadata,
89
+ };
90
+ try {
91
+ const result = await push(payload, config);
92
+ await appendHistory({ ...base, status: "success", httpStatus: result.httpStatus });
93
+ }
94
+ catch (error) {
95
+ const httpStatus = error instanceof BarkHttpError ? error.status : undefined;
96
+ await appendHistory({ ...base, status: "failure", ...(httpStatus ? { httpStatus } : {}), error: messageOf(error) });
97
+ throw error;
98
+ }
99
+ }
100
+ async function showConfig() {
101
+ const path = getConfigPath();
102
+ const stored = await loadStoredConfig(path);
103
+ console.log(`Config: ${path}`);
104
+ console.log(`Server: ${process.env.BARK_SERVER ?? stored.server ?? "Not configured"}`);
105
+ console.log(`Device: ${masked(process.env.BARK_DEVICE_KEY ?? stored.deviceKey)}`);
106
+ console.log(`Authentication: ${(process.env.BARK_USERNAME ?? stored.username) ? "basic" : "none"}`);
107
+ console.log(`Group: ${process.env.BARK_GROUP ?? stored.group ?? "terminal"}`);
108
+ console.log(`Level: ${process.env.BARK_LEVEL ?? stored.level ?? "active"}`);
109
+ console.log(`Sound: ${process.env.BARK_SOUND ?? stored.sound ?? "default"}`);
110
+ const archive = process.env.BARK_ARCHIVE?.toLowerCase();
111
+ const archivesByDefault = archive ? !["0", "false", "no", "off"].includes(archive) : (stored.archive ?? true);
112
+ console.log(`Archive: ${archivesByDefault ? "yes" : "no"}`);
113
+ console.log(`History: ${getHistoryPath()}`);
114
+ }
115
+ async function updateConfig(updates) {
116
+ const path = getConfigPath();
117
+ const current = await loadStoredConfig(path);
118
+ const next = { ...current };
119
+ for (const key of ["server", "deviceKey", "group", "level", "sound", "username", "password", "archive"]) {
120
+ const value = updates[key];
121
+ if (value !== undefined)
122
+ Object.assign(next, { [key]: value });
123
+ }
124
+ if (updates.passwordStdin)
125
+ next.password = (await readStandardInput()).trimEnd();
126
+ if (updates.noAuth) {
127
+ delete next.username;
128
+ delete next.password;
129
+ }
130
+ await saveStoredConfig(next, path);
131
+ console.log(`✓ Configuration saved to ${path}`);
132
+ }
133
+ async function showHistory(search, limit) {
134
+ const records = await readHistory(search, limit);
135
+ if (records.length === 0) {
136
+ console.log("No notification history.");
137
+ return;
138
+ }
139
+ for (const record of records) {
140
+ const heading = record.title || record.body.split("\n")[0] || "Notification";
141
+ console.log(`${record.status === "success" ? "✓" : "✗"} ${record.createdAt.replace("T", " ").slice(0, 19)} ${heading} [${record.source}]`);
142
+ }
143
+ }
144
+ function spawnCommand(command) {
145
+ return new Promise((resolve) => {
146
+ const child = spawn(command[0], command.slice(1), { stdio: "inherit", shell: false });
147
+ child.once("error", (error) => { process.stderr.write(`Command error: ${error.message}\n`); resolve({ code: 127, signal: null }); });
148
+ child.once("exit", (code, signal) => resolve({ code, signal }));
149
+ });
150
+ }
151
+ async function readStandardInput() {
152
+ const chunks = [];
153
+ for await (const chunk of process.stdin)
154
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
155
+ return Buffer.concat(chunks).toString("utf8");
156
+ }
157
+ function signalNumber(signal) { return constants.signals[signal] ?? 0; }
158
+ function messageOf(error) { return error instanceof Error ? error.message : String(error); }
159
+ function formatDuration(seconds) {
160
+ const total = Math.max(0, Math.round(seconds));
161
+ if (total >= 3600)
162
+ return `${Math.floor(total / 3600)}h ${Math.floor((total % 3600) / 60)}m ${total % 60}s`;
163
+ if (total >= 60)
164
+ return `${Math.floor(total / 60)}m ${total % 60}s`;
165
+ return `${total}s`;
166
+ }
167
+ function shellQuote(value) { return /^[\w./-]+$/.test(value) ? value : `'${value.replaceAll("'", "'\\''")}'`; }
168
+ export const helpText = `notify — send Bark notifications from Linux, macOS, or Windows
169
+
170
+ USAGE
171
+ notify "Message"
172
+ echo "Message" | notify -t "Title"
173
+ notify run [notification options] -- command [arguments]
174
+ notify config show|path|test|set [options]
175
+ notify history [--search text] [--limit number]
176
+
177
+ COMMON OPTIONS
178
+ -m, --message TEXT Notification body
179
+ -t, --title TEXT Title
180
+ -s, --subtitle TEXT Subtitle
181
+ -g, --group TEXT Group
182
+ --level LEVEL active, timeSensitive, passive, critical
183
+ --sound NAME Bark sound
184
+ --icon URL Custom icon
185
+ --image URL Image attachment
186
+ --url URL Open URL when tapped
187
+ --markdown TEXT Markdown body
188
+ --volume 0...10 Critical alert volume
189
+ --badge NUMBER App badge
190
+ --call Repeat ringtone
191
+ --auto-copy Enable automatic copy
192
+ --copy TEXT Copy action text
193
+ --archive Archive in Bark
194
+ --no-archive Do not archive in Bark
195
+ --ttl SECONDS Archived-message lifetime
196
+ --no-action Tapping performs no action
197
+ -q, --quiet No success output
198
+
199
+ CONFIGURATION
200
+ notify config set --server URL --device KEY
201
+ printf '%s' "$BARK_PASSWORD" | notify config set --username USER --password-stdin
202
+
203
+ SERVER ENVIRONMENT
204
+ BARK_SERVER, BARK_DEVICE_KEY, BARK_DEVICE_KEY_FILE
205
+ BARK_USERNAME, BARK_PASSWORD, BARK_PASSWORD_FILE
206
+ BARK_GROUP, BARK_LEVEL, BARK_SOUND, BARK_ARCHIVE
207
+ `;
208
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,112 @@
1
+ export declare const barkLevels: readonly ["active", "timeSensitive", "passive", "critical"];
2
+ export type BarkLevel = (typeof barkLevels)[number];
3
+ export interface StoredConfig {
4
+ server?: string;
5
+ deviceKey?: string;
6
+ username?: string;
7
+ password?: string;
8
+ group?: string;
9
+ level?: BarkLevel;
10
+ sound?: string;
11
+ archive?: boolean;
12
+ }
13
+ export interface ResolvedConfig {
14
+ server: string;
15
+ deviceKey: string;
16
+ username?: string;
17
+ password?: string;
18
+ group: string;
19
+ level: BarkLevel;
20
+ sound?: string;
21
+ archive: boolean;
22
+ }
23
+ export interface SendOptions {
24
+ message?: string;
25
+ title?: string;
26
+ subtitle?: string;
27
+ markdown?: string;
28
+ group?: string;
29
+ level?: BarkLevel;
30
+ sound?: string;
31
+ icon?: string;
32
+ image?: string;
33
+ url?: string;
34
+ copy?: string;
35
+ volume?: number;
36
+ badge?: number;
37
+ ttl?: number;
38
+ call: boolean;
39
+ autoCopy: boolean;
40
+ archive?: boolean;
41
+ noAction: boolean;
42
+ id?: string;
43
+ quiet: boolean;
44
+ }
45
+ export interface ConfigUpdates extends StoredConfig {
46
+ noAuth: boolean;
47
+ passwordStdin: boolean;
48
+ }
49
+ export type CliCommand = {
50
+ kind: "send";
51
+ options: SendOptions;
52
+ } | {
53
+ kind: "run";
54
+ options: SendOptions;
55
+ command: string[];
56
+ } | {
57
+ kind: "config-show";
58
+ } | {
59
+ kind: "config-path";
60
+ } | {
61
+ kind: "config-test";
62
+ } | {
63
+ kind: "config-set";
64
+ updates: ConfigUpdates;
65
+ } | {
66
+ kind: "history";
67
+ search?: string;
68
+ limit: number;
69
+ } | {
70
+ kind: "help";
71
+ } | {
72
+ kind: "version";
73
+ };
74
+ export interface BarkPayload {
75
+ device_key: string;
76
+ title?: string;
77
+ subtitle?: string;
78
+ body: string;
79
+ markdown?: string;
80
+ level?: BarkLevel;
81
+ volume?: number;
82
+ badge?: number;
83
+ call?: "1";
84
+ autoCopy?: "1";
85
+ copy?: string;
86
+ sound?: string;
87
+ icon?: string;
88
+ image?: string;
89
+ group?: string;
90
+ isArchive?: "1";
91
+ ttl?: number;
92
+ url?: string;
93
+ action?: "none";
94
+ id?: string;
95
+ }
96
+ export interface HistoryRecord {
97
+ createdAt: string;
98
+ status: "success" | "failure";
99
+ source: "send" | "run";
100
+ title?: string;
101
+ body: string;
102
+ group?: string;
103
+ httpStatus?: number;
104
+ error?: string;
105
+ command?: string;
106
+ exitCode?: number;
107
+ durationSeconds?: number;
108
+ }
109
+ export declare class CliError extends Error {
110
+ readonly showHelpHint: boolean;
111
+ constructor(message: string, showHelpHint?: boolean);
112
+ }
@@ -0,0 +1,10 @@
1
+ export const barkLevels = ["active", "timeSensitive", "passive", "critical"];
2
+ export class CliError extends Error {
3
+ showHelpHint;
4
+ constructor(message, showHelpHint = false) {
5
+ super(message);
6
+ this.showHelpHint = showHelpHint;
7
+ this.name = "CliError";
8
+ }
9
+ }
10
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,QAAQ,EAAE,eAAe,EAAE,SAAS,EAAE,UAAU,CAAU,CAAC;AAqGtF,MAAM,OAAO,QAAS,SAAQ,KAAK;IACK;IAAtC,YAAY,OAAe,EAAW,eAAe,KAAK;QACxD,KAAK,CAAC,OAAO,CAAC,CAAC;QADqB,iBAAY,GAAZ,YAAY,CAAQ;QAExD,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;CACF"}
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "barkdesk-notify",
3
+ "version": "1.0.1",
4
+ "description": "Cross-platform Bark CLI with a short notify command.",
5
+ "type": "module",
6
+ "bin": {
7
+ "notify": "dist/src/main.js"
8
+ },
9
+ "files": [
10
+ "dist/src",
11
+ "README.md",
12
+ "LICENSE"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc -p tsconfig.json",
16
+ "typecheck": "tsc -p tsconfig.json --noEmit",
17
+ "test": "npm run build && node --test dist/test/*.test.js",
18
+ "prepack": "npm run build"
19
+ },
20
+ "engines": {
21
+ "node": ">=20.9.0"
22
+ },
23
+ "keywords": [
24
+ "bark",
25
+ "notification",
26
+ "push",
27
+ "cli",
28
+ "notify"
29
+ ],
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/i1mT/bark-notify.git",
33
+ "directory": "cli"
34
+ },
35
+ "homepage": "https://github.com/i1mT/bark-notify#readme",
36
+ "bugs": {
37
+ "url": "https://github.com/i1mT/bark-notify/issues"
38
+ },
39
+ "license": "MIT",
40
+ "publishConfig": {
41
+ "access": "public"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^26.4.0",
45
+ "typescript": "^6.0.3"
46
+ }
47
+ }