omnish 1.6.4 → 1.6.5
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/CHANGELOG.md +12 -0
- package/README.md +74 -72
- package/config.example.json +17 -0
- package/dist/board-employee-run.mjs +69 -0
- package/dist/index.js +460 -284
- package/dist/ui/assets/{index-DxXW0CWH.js → index-aUJGrxrr.js} +1 -1
- package/dist/ui/index.html +1 -1
- package/package.json +6 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Dev tooling:** Prettier with root [`.prettierrc.json`](.prettierrc.json); run `pnpm format` or `pnpm format:check` before submitting PRs (CI enforces format check).
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- **Documentation search (chat):** `/docs search` → **`/s q`** (shorthand **`/s`**, full form **`/search`**). List, show, and follow moved to `/s` / `/search`. Legacy **`/docs`**, **`/help search`**, and **`omnish docs`** still work. Host CLI: **`omnish search q`**.
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- **`omnish start`:** start the gateway in the background by default (pairs with **`omnish stop`**). Foreground: **`omnish start -f`**. **`omnish run`** stays foreground unless **`-d`** is passed.
|
|
21
|
+
|
|
10
22
|
## [1.6.2] - 2026-05-23
|
|
11
23
|
|
|
12
24
|
### Security
|
package/README.md
CHANGED
|
@@ -18,10 +18,10 @@
|
|
|
18
18
|
|
|
19
19
|
<p align="center"><em>Inbox and shell, linked — deterministic, local execution.</em></p>
|
|
20
20
|
|
|
21
|
-
|
|
|
22
|
-
|
|
21
|
+
| WhatsApp | Telegram |
|
|
22
|
+
| :------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------: |
|
|
23
23
|
| <img src="https://omnish.dev/media/omnish_whatsapp_mockup.png" alt="WhatsApp" width="340" /> | <img src="https://omnish.dev/media/omnish_telegram_mockup.png" alt="Telegram" width="340" /> |
|
|
24
|
-
|
|
|
24
|
+
| DM surface you already use | Same gateway pattern via bot DM |
|
|
25
25
|
|
|
26
26
|
---
|
|
27
27
|
|
|
@@ -53,22 +53,23 @@ No AI or agent layer — direct `bash -c` for sync jobs; PTY uses your configure
|
|
|
53
53
|
|
|
54
54
|
**Multi-host cluster (optional, chat-driven):** with **`clusterEnabled`**, link the same WhatsApp number to several machines (multi-device). Each allowlisted **sender** picks one machine to talk to with **`/c use <label-or-id>`** (or **`/c here`** to bind to the local machine); only the bound machine answers that sender's normal traffic. Two controllers can independently bind to two different machines without affecting each other. Pre-seed defaults in **`clusterSenderBindings`**. There is **no shared file**, no Syncthing — coordination flows through the WhatsApp chat itself via an invisible footer on each reply. See [docs/features/cluster-and-chat-config.md](docs/features/cluster-and-chat-config.md).
|
|
55
55
|
|
|
56
|
-
**Background gateway:** **`omnish
|
|
56
|
+
**Background gateway:** **`omnish start`** (background by default) and **`omnish stop`** work on **Linux, macOS, and Windows** (detached run + pidfile). Same detached behavior: **`omnish run -d`**. From an allowlisted chat, **`/service`** shows status, install hints, and logs; optional **`/service install`** after **`/config set serviceInstallFromChat true`**. For **login/boot**, see [Background gateway and start on boot](docs/guides/background-and-boot.md) and [Service from chat](docs/features/service-from-chat.md).
|
|
57
57
|
|
|
58
58
|
**Config from chat:** `/config show`, `/config get`, `/config set` for a whitelist of `config.json` keys (same trust as shell). See the same doc.
|
|
59
59
|
|
|
60
60
|
## Running in the background and on boot
|
|
61
61
|
|
|
62
|
-
- **`omnish
|
|
62
|
+
- **`omnish start`** — starts detached by default; logs append to **`--log-file`** (default: `<data>/logs/gateway.log`); PID in **`<data>/gateway.pid`**.
|
|
63
|
+
- **`omnish run -d`** (or **`--background`**) — same detached launch; **`omnish run`** alone stays in the foreground.
|
|
63
64
|
- **`omnish stop`** — reads the pidfile and stops the process (**SIGTERM** on Unix; on Windows **`taskkill`** is used if signaling fails).
|
|
64
65
|
|
|
65
66
|
Full steps for systemd, launchd, and Task Scheduler — **[docs/guides/background-and-boot.md](docs/guides/background-and-boot.md)**.
|
|
66
67
|
|
|
67
|
-
| OS
|
|
68
|
-
|
|
69
|
-
| Linux
|
|
70
|
-
| macOS
|
|
71
|
-
| Windows | Task Scheduler or import — [contrib/omnish-windows-task.xml](contrib/omnish-windows-task.xml); NSSM / WinSW advanced
|
|
68
|
+
| OS | Boot / auto-restart |
|
|
69
|
+
| ------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
|
70
|
+
| Linux | User systemd unit — [contrib/omnish.service](contrib/omnish.service), **`loginctl enable-linger`** if needed |
|
|
71
|
+
| macOS | LaunchAgent — [contrib/dev.omnish.gateway.plist](contrib/dev.omnish.gateway.plist), **`launchctl bootstrap`** / **`kickstart`** |
|
|
72
|
+
| Windows | Task Scheduler or import — [contrib/omnish-windows-task.xml](contrib/omnish-windows-task.xml); NSSM / WinSW advanced |
|
|
72
73
|
|
|
73
74
|
## Data directory
|
|
74
75
|
|
|
@@ -86,13 +87,13 @@ Per-chat shell cwd is in `sessions.json`; **user shortcuts** are stored in `shor
|
|
|
86
87
|
|
|
87
88
|
Each **chat** (WhatsApp DM / Telegram DM) has its own shortcut map on disk (`shortcuts.json`).
|
|
88
89
|
|
|
89
|
-
| Action
|
|
90
|
-
|
|
91
|
-
| Add / overwrite | `/shortcut add kidsync !cd ../../kidsync`
|
|
92
|
-
| List
|
|
93
|
-
| Show
|
|
94
|
-
| Remove
|
|
95
|
-
| Help
|
|
90
|
+
| Action | Example |
|
|
91
|
+
| --------------- | ---------------------------------------------------------------------------- |
|
|
92
|
+
| Add / overwrite | `/shortcut add kidsync !cd ../../kidsync` |
|
|
93
|
+
| List | `/shortcut list` or `/shortcuts` |
|
|
94
|
+
| Show | `/shortcut show kidsync` |
|
|
95
|
+
| Remove | `/shortcut remove kidsync` |
|
|
96
|
+
| Help | `/shortcut help` — aliases: `/alias …`, `/aliases …` (same as `/shortcut …`) |
|
|
96
97
|
|
|
97
98
|
**Invoke:** send **`!kidsync`** or **`/kidsync`** (bare name), or **`!kidsync <text…>`** / **`/kidsync <text…>`** when the body contains **`$OMNISH_INPUT`**. The saved line runs once; if it is a standalone `!cd …`, the session working directory updates like a normal sync `cd`. Shortcut bodies are **not** expanded again (no nesting).
|
|
98
99
|
|
|
@@ -152,24 +153,24 @@ Output is **debounced** (`appsFlushMs`, default 300 ms), **throttled** (`appsMin
|
|
|
152
153
|
|
|
153
154
|
### `/apps` cheat sheet
|
|
154
155
|
|
|
155
|
-
| Command
|
|
156
|
-
|
|
157
|
-
| `/apps start <name> <cmd…>`
|
|
158
|
-
| `/apps attach <name>`
|
|
159
|
-
| `/apps detach`
|
|
160
|
-
| `/apps list`
|
|
161
|
-
| `/apps info <name>` / `/apps get <name>`
|
|
162
|
-
| `/apps send <name> <text>`
|
|
163
|
-
| `>name text`
|
|
164
|
-
| `/apps key <name> KEY[,KEY…]`
|
|
165
|
-
| `/apps tail <name> [lines]`
|
|
166
|
-
| `/apps since <name>`
|
|
167
|
-
| `/apps mute <name>` / `/apps unmute <name>` | Pause / resume streaming to the chat (log still grows).
|
|
168
|
-
| `/apps raw <name> on\|off`
|
|
169
|
-
| `/apps resize <name> <cols> <rows>`
|
|
170
|
-
| `/apps stop <name>`
|
|
171
|
-
| `/apps kill <name>`
|
|
172
|
-
| `/apps rm <name>`
|
|
156
|
+
| Command | Action |
|
|
157
|
+
| ------------------------------------------- | ----------------------------------------------------------------------------- |
|
|
158
|
+
| `/apps start <name> <cmd…>` | Spawn app session in session cwd; **auto-attaches** `<name>`. |
|
|
159
|
+
| `/apps attach <name>` | Focus plain DMs on that running session. |
|
|
160
|
+
| `/apps detach` | Clear focus. |
|
|
161
|
+
| `/apps list` | Sessions for this chat; `*` marks focus. Shows `attached: …` or `(no focus)`. |
|
|
162
|
+
| `/apps info <name>` / `/apps get <name>` | Cmd, cwd, env key count, terminal size, ring bytes, log path/size, mute/raw. |
|
|
163
|
+
| `/apps send <name> <text>` | Write `text` + newline (no attach). |
|
|
164
|
+
| `>name text` | Same as `/apps send`. |
|
|
165
|
+
| `/apps key <name> KEY[,KEY…]` | Special keys: `Enter`, `Tab`, `Esc`, arrows, `^C`, `ctrl+d`, `\x1b`, … |
|
|
166
|
+
| `/apps tail <name> [lines]` | Last _lines_ of log (default `appsLogTailLines`). |
|
|
167
|
+
| `/apps since <name>` | New log bytes since your last `/apps since` for that name. |
|
|
168
|
+
| `/apps mute <name>` / `/apps unmute <name>` | Pause / resume streaming to the chat (log still grows). |
|
|
169
|
+
| `/apps raw <name> on\|off` | Keep ANSI in streamed messages when `on`. |
|
|
170
|
+
| `/apps resize <name> <cols> <rows>` | Resize terminal. |
|
|
171
|
+
| `/apps stop <name>` | SIGTERM; SIGKILL after 5 s if still alive. |
|
|
172
|
+
| `/apps kill <name>` | SIGKILL immediately. |
|
|
173
|
+
| `/apps rm <name>` | Only after the process has **exited**; removes metadata + log file. |
|
|
173
174
|
|
|
174
175
|
To send a literal `!`, `/`, or `>` to the attached program, use **`/apps send <name> …`** or **`>name …`**.
|
|
175
176
|
|
|
@@ -187,21 +188,22 @@ To send a literal `!`, `/`, or `>` to the attached program, use **`/apps send <n
|
|
|
187
188
|
|
|
188
189
|
## CLI
|
|
189
190
|
|
|
190
|
-
| Command
|
|
191
|
-
|
|
192
|
-
| `omnish link` / `link --force`
|
|
193
|
-
| `omnish run`
|
|
194
|
-
| `omnish
|
|
195
|
-
| `omnish
|
|
196
|
-
| `omnish
|
|
197
|
-
| `omnish
|
|
198
|
-
| `omnish
|
|
199
|
-
| `omnish allow
|
|
200
|
-
| `omnish
|
|
201
|
-
| `omnish
|
|
202
|
-
| `omnish
|
|
203
|
-
| `omnish
|
|
204
|
-
| `omnish
|
|
191
|
+
| Command | Description |
|
|
192
|
+
| ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
193
|
+
| `omnish link` / `link --force` | Print QR; save session under `<data-dir>/auth/` (`--force` deletes old auth first). Telegram token mode: `omnish link --tg <token>` (alias: `--telegram`). |
|
|
194
|
+
| `omnish run` | Start gateway in foreground; background: `omnish run -d [--log-file <path>]`. |
|
|
195
|
+
| `omnish start` | Start gateway in background (same as `run -d`); `-f` for foreground. Pair with `stop`. |
|
|
196
|
+
| `omnish stop` | Stop a background gateway (`start` or `run -d`; uses `<data-dir>/gateway.pid`) |
|
|
197
|
+
| `omnish i` / `interactive` | Chat-equivalent REPL on your terminal; **`omnish i --help`** · [interactive-cli.md](docs/guides/interactive-cli.md) |
|
|
198
|
+
| `omnish service …` | Service status, logs, install/uninstall (same trust gate as **`/service`** in chat) |
|
|
199
|
+
| `omnish logout` | Delete saved WhatsApp session |
|
|
200
|
+
| `omnish allow +1555...` | Add WhatsApp number to allowlist |
|
|
201
|
+
| `omnish allow tg:<id>` | Add Telegram user id |
|
|
202
|
+
| `omnish deny …` | Remove allowlist entry |
|
|
203
|
+
| `omnish status [--check-updates]` | Data dir, auth, allowlists, jobs, cluster (if enabled); optional live npm/update check |
|
|
204
|
+
| `omnish commands` | Print chat command help on the host terminal (`/help` equivalent) + `/config`-editable keys |
|
|
205
|
+
| `omnish security [--json]` | Local security posture report (`--json` for scripts; non-zero exit on error findings) |
|
|
206
|
+
| `omnish cluster [status \| use <sender> <label-or-id>]` | Show cluster state or seed a sender → machine binding |
|
|
205
207
|
|
|
206
208
|
Config: `<data-dir>/config.json` (see [config.example.json](config.example.json)). Use `omnish status` for the resolved path.
|
|
207
209
|
|
|
@@ -243,28 +245,28 @@ What to expect:
|
|
|
243
245
|
|
|
244
246
|
Index and curated paths: **[docs/README.md](docs/README.md)**.
|
|
245
247
|
|
|
246
|
-
| Topic
|
|
247
|
-
|
|
248
|
-
| Vision — local first, product direction
|
|
249
|
-
| Docker gateway (reference compose)
|
|
250
|
-
| Interactive terminal (`omnish i`, `/sendto` multi-target)
|
|
251
|
-
| Configuration (`config.json`)
|
|
252
|
-
| Browser setup UI (`omnish ui`)
|
|
253
|
-
| Cluster roster + `/config` from chat
|
|
254
|
-
| Interactive sessions (`/apps`)
|
|
255
|
-
| Background jobs
|
|
256
|
-
| Webhook receiver (CI/CD notifications)
|
|
257
|
-
| Message routing
|
|
258
|
-
| Security
|
|
259
|
-
| User guide
|
|
260
|
-
| Documentation search (`/
|
|
261
|
-
| System agents + `/run`
|
|
262
|
-
| MCP IDE spike (experimental)
|
|
263
|
-
| Telegram
|
|
264
|
-
| Send/receive files (`/send` selectors, `/sendto` destinations) | [docs/files-send-receive.md](docs/files-send-receive.md)
|
|
265
|
-
| Troubleshooting
|
|
266
|
-
| Implementation / contributors
|
|
267
|
-
| Architecture (legacy)
|
|
248
|
+
| Topic | Doc |
|
|
249
|
+
| -------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
|
|
250
|
+
| Vision — local first, product direction | [docs/vision.md](docs/vision.md) |
|
|
251
|
+
| Docker gateway (reference compose) | [docs/guides/docker-gateway-golden-path.md](docs/guides/docker-gateway-golden-path.md) |
|
|
252
|
+
| Interactive terminal (`omnish i`, `/sendto` multi-target) | [docs/guides/interactive-cli.md](docs/guides/interactive-cli.md) |
|
|
253
|
+
| Configuration (`config.json`) | [docs/guides/configuration.md](docs/guides/configuration.md) |
|
|
254
|
+
| Browser setup UI (`omnish ui`) | [docs/guides/ui.md](docs/guides/ui.md) |
|
|
255
|
+
| Cluster roster + `/config` from chat | [docs/features/cluster-and-chat-config.md](docs/features/cluster-and-chat-config.md) |
|
|
256
|
+
| Interactive sessions (`/apps`) | [docs/features/sessions.md](docs/features/sessions.md) |
|
|
257
|
+
| Background jobs | [docs/features/background-jobs.md](docs/features/background-jobs.md) |
|
|
258
|
+
| Webhook receiver (CI/CD notifications) | [docs/features/webhook-receiver.md](docs/features/webhook-receiver.md) |
|
|
259
|
+
| Message routing | [docs/architecture/routing.md](docs/architecture/routing.md) |
|
|
260
|
+
| Security | [docs/architecture/security.md](docs/architecture/security.md) |
|
|
261
|
+
| User guide | [docs/guides/user-guide.md](docs/guides/user-guide.md) |
|
|
262
|
+
| Documentation search (`/s`, `omnish search`) | [docs/features/docs-search-from-chat.md](docs/features/docs-search-from-chat.md) |
|
|
263
|
+
| System agents + `/run` | [docs/guides/system-agents-and-run.md](docs/guides/system-agents-and-run.md) |
|
|
264
|
+
| MCP IDE spike (experimental) | [contrib/mcp-spike/README.md](contrib/mcp-spike/README.md) |
|
|
265
|
+
| Telegram | [docs/telegram-integration-notes.md](docs/telegram-integration-notes.md) |
|
|
266
|
+
| Send/receive files (`/send` selectors, `/sendto` destinations) | [docs/files-send-receive.md](docs/files-send-receive.md) |
|
|
267
|
+
| Troubleshooting | [docs/advanced/troubleshooting.md](docs/advanced/troubleshooting.md) |
|
|
268
|
+
| Implementation / contributors | [docs/advanced/implementation.md](docs/advanced/implementation.md) |
|
|
269
|
+
| Architecture (legacy) | [docs/architecture-and-implementation.md](docs/architecture-and-implementation.md) |
|
|
268
270
|
|
|
269
271
|
## Troubleshooting
|
|
270
272
|
|
package/config.example.json
CHANGED
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"recipesMaxTaskChars": 100000,
|
|
33
33
|
"recipesMacroDefaultCommand": "claude -p \"$OMNISH_TASK\"",
|
|
34
34
|
"recipesRunAttach": false,
|
|
35
|
+
"recipesNotifyEnabled": true,
|
|
35
36
|
"clusterEnabled": false,
|
|
36
37
|
"clusterLabel": "",
|
|
37
38
|
"clusterRole": "secondary",
|
|
@@ -48,6 +49,10 @@
|
|
|
48
49
|
"chatLlmMaxOutputChars": 24000,
|
|
49
50
|
"chatLlmNeedsTty": false,
|
|
50
51
|
"chatLlmWorkDir": "",
|
|
52
|
+
"chatAgentEnabled": false,
|
|
53
|
+
"chatAgentCommand": "",
|
|
54
|
+
"chatAgentPerPeer": true,
|
|
55
|
+
"chatAgentMaxQueue": 64,
|
|
51
56
|
"tunnelEnabled": false,
|
|
52
57
|
"tunnelRelayUrl": "https://tunnel.omnish.dev",
|
|
53
58
|
"platformToken": "",
|
|
@@ -57,6 +62,18 @@
|
|
|
57
62
|
"watchDebounceMs": 2000,
|
|
58
63
|
"watchMaxEventsPerMinute": 30,
|
|
59
64
|
"watchAutoRestore": true,
|
|
65
|
+
"boardCoordinatorEnabled": true,
|
|
66
|
+
"boardCoordinatorIntervalMs": 5000,
|
|
67
|
+
"boardMaxRework": 3,
|
|
68
|
+
"boardNotifyProgress": "milestones",
|
|
69
|
+
"boardNotifyJobStatus": true,
|
|
70
|
+
"boardPrimaryAgent": "",
|
|
71
|
+
"boardAgentPermissionMode": "safe",
|
|
72
|
+
"boardCoordinatorAgentEnabled": false,
|
|
73
|
+
"boardCoordinatorAgentCommand": "",
|
|
74
|
+
"boardCoordinatorFinetuneEnabled": false,
|
|
75
|
+
"boardSkillResearchEnabled": true,
|
|
76
|
+
"boardFeedbackReminderEnabled": false,
|
|
60
77
|
"mediaSendFiles": true,
|
|
61
78
|
"mediaUrlAutoDl": true,
|
|
62
79
|
"mediaInstallFromChat": false,
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Mandatory employee harness — runs inner agent CLI after omnish seeds work-plan.json.
|
|
4
|
+
* Usage: node board-employee-run.mjs "<innerCommand>"
|
|
5
|
+
*/
|
|
6
|
+
import { spawnSync } from "node:child_process";
|
|
7
|
+
import fs from "node:fs";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
|
|
10
|
+
const innerCommand = process.argv[2];
|
|
11
|
+
if (!innerCommand || !innerCommand.trim()) {
|
|
12
|
+
console.error("board-employee-run: missing inner command argument");
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const workDir = process.env.OMNISH_JOB_WORKDIR;
|
|
17
|
+
const jobId = process.env.OMNISH_JOB_ID;
|
|
18
|
+
const specialist =
|
|
19
|
+
process.env.OMNISH_BOARD_SPECIALIST ?? process.env.OMNISH_JOB_ASSIGNEE ?? "employee";
|
|
20
|
+
|
|
21
|
+
if (!workDir || !jobId) {
|
|
22
|
+
console.error("board-employee-run: OMNISH_JOB_WORKDIR and OMNISH_JOB_ID required");
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const planPath = path.join(workDir, "work-plan.json");
|
|
27
|
+
if (!fs.existsSync(planPath)) {
|
|
28
|
+
console.error("board-employee-run: work-plan.json missing (harness should have seeded it)");
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const shell = process.env.SHELL || "/bin/bash";
|
|
33
|
+
const result = spawnSync(shell, ["-lc", innerCommand], {
|
|
34
|
+
cwd: process.cwd(),
|
|
35
|
+
env: process.env,
|
|
36
|
+
encoding: "utf8",
|
|
37
|
+
maxBuffer: 32 * 1024 * 1024,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const reportPath = path.join(workDir, "report.json");
|
|
41
|
+
if (!fs.existsSync(reportPath)) {
|
|
42
|
+
const exitCode = result.status ?? 1;
|
|
43
|
+
const summary =
|
|
44
|
+
result.signal != null
|
|
45
|
+
? `Harness: inner command signaled ${result.signal}`
|
|
46
|
+
: `Harness: inner command exited ${exitCode}; no report.json`;
|
|
47
|
+
const doc = {
|
|
48
|
+
jobId,
|
|
49
|
+
specialist,
|
|
50
|
+
summary,
|
|
51
|
+
stepsCompleted: [],
|
|
52
|
+
artifacts: ["work-plan.json"],
|
|
53
|
+
exitCode,
|
|
54
|
+
blockers: result.stderr?.trim()
|
|
55
|
+
? [result.stderr.trim().slice(0, 500)]
|
|
56
|
+
: ["no report.json from inner command"],
|
|
57
|
+
selfAssessment: "Did not complete core handoff contract.",
|
|
58
|
+
workPlanPath: "work-plan.json",
|
|
59
|
+
planFollowed: false,
|
|
60
|
+
communicationSummary: "Harness stub — inner command did not complete handoff.",
|
|
61
|
+
handoffMessage: "No handoff message from inner command.",
|
|
62
|
+
};
|
|
63
|
+
fs.writeFileSync(reportPath, JSON.stringify(doc, null, 2) + "\n", { mode: 0o600 });
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (result.status !== 0) {
|
|
67
|
+
process.exit(result.status ?? 1);
|
|
68
|
+
}
|
|
69
|
+
process.exit(0);
|