@domsync/win32-arm64 1.0.1 → 1.2.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 +116 -58
- package/domsync.exe +0 -0
- package/package.json +20 -1
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# domsync
|
|
2
2
|
|
|
3
|
-
`domsync` keeps
|
|
3
|
+
`domsync` keeps local sectioned domain lists in sync with OpenClash/Mihomo rule-provider files on your servers. One config lists any number of servers, and each server lists any number of **pairs**: one local domain list and one provider file. For every pair `domsync` reads the local list and the provider file over SSH, merges them (the local entries win, provider-only domains go into an `other` section), validates everything, then atomically rewrites each file that changed and optionally runs per-server post-write commands.
|
|
4
4
|
|
|
5
|
-
It never silently rewrites anything it cannot parse: an ambiguous local file or a malformed provider line stops
|
|
5
|
+
Pairs are independent: a dead server or a broken pair is reported and the rest still run. It never silently rewrites anything it cannot parse: an ambiguous local file or a malformed provider line stops that pair before a single byte is written.
|
|
6
6
|
|
|
7
|
-
**Not supported in v1:** homeproxy, subscription URLs or any remote source other than the current provider file, SSH password authentication, `ProxyJump`, a fallback to the system `ssh`, IDN domains (use punycode), and cryptographic verification of updates inside the CLI. There is no daemon, watcher or scheduler; run `domsync` from cron or by hand.
|
|
7
|
+
**Not supported in v1:** homeproxy, subscription URLs or any remote source other than the current provider file, SSH password authentication, `ProxyJump`, a fallback to the system `ssh`, IDN domains (use punycode), and cryptographic verification of updates inside the CLI. One local list cannot be shared by two pairs (cross-sync), servers and pairs cannot be selected on the command line, and execution is sequential. There is no daemon, watcher or scheduler; run `domsync` from cron or by hand.
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
@@ -22,6 +22,14 @@ npm (macOS, Linux and Windows):
|
|
|
22
22
|
npm i -g @domsync/cli
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
+
Go (any platform with a Go toolchain, built from source):
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
go install github.com/neiromaster/domsync/cmd/domsync@latest
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`go install` places the binary in `$GOBIN` (or `$HOME/go/bin`). The toolchain version is pinned in `go.mod`.
|
|
32
|
+
|
|
25
33
|
Install script (macOS and Linux):
|
|
26
34
|
|
|
27
35
|
```sh
|
|
@@ -34,46 +42,48 @@ The script downloads the release archive and `checksums.txt`, verifies the SHA-2
|
|
|
34
42
|
|
|
35
43
|
```sh
|
|
36
44
|
cp domsync.example.yaml domsync.yaml
|
|
37
|
-
|
|
45
|
+
mkdir -p domains
|
|
46
|
+
cat > domains/media.txt <<'EOF'
|
|
38
47
|
[media]
|
|
39
48
|
+.example.com
|
|
40
49
|
+.example.net
|
|
41
|
-
|
|
42
|
-
|
|
50
|
+
EOF
|
|
51
|
+
cat > domains/ai.txt <<'EOF'
|
|
52
|
+
[ai]
|
|
43
53
|
+.example.org
|
|
44
54
|
EOF
|
|
45
55
|
```
|
|
46
56
|
|
|
47
|
-
Edit `domsync.yaml
|
|
57
|
+
Edit `domsync.yaml`: in the `router` server set `host`, `user`, `ssh_key` and the `target` of each file. The example also lists a second server, `vps-1`, to show the shape; delete that entry or fix its settings before running. Set `enabled: false` instead to park it. Make sure each server's host key is already in `known_hosts`, then run:
|
|
48
58
|
|
|
49
59
|
```sh
|
|
50
60
|
domsync
|
|
51
61
|
```
|
|
52
62
|
|
|
53
|
-
The config is looked up in this order: `--config <path>`, the `DOMSYNC_CONFIG` environment variable, then `./domsync.yaml` in the current directory. Relative paths inside the config (`
|
|
63
|
+
The config is looked up in this order: `--config <path>`, the `DOMSYNC_CONFIG` environment variable, then `./domsync.yaml` in the current directory. Relative paths inside the config (`servers[].ssh_key`, `servers[].known_hosts`, `servers[].files[].source`, `logging.file`) are resolved against the config file's directory; `~` and `~/...` are expanded to your home directory.
|
|
54
64
|
|
|
55
|
-
A first run needs
|
|
65
|
+
A first run needs each server's host key in `known_hosts`. If it is missing, the error includes the SHA-256 fingerprint and the exact `ssh-keyscan -H ... >> ~/.ssh/known_hosts` command to add it.
|
|
56
66
|
|
|
57
67
|
## OpenClash provider
|
|
58
68
|
|
|
59
|
-
Add
|
|
69
|
+
Add one provider per synced file to the OpenClash configuration:
|
|
60
70
|
|
|
61
71
|
```yaml
|
|
62
72
|
rule-providers:
|
|
63
|
-
|
|
73
|
+
media:
|
|
64
74
|
type: file
|
|
65
75
|
behavior: domain
|
|
66
76
|
format: text
|
|
67
|
-
path: ./rule_provider/
|
|
77
|
+
path: ./rule_provider/media.txt
|
|
68
78
|
```
|
|
69
79
|
|
|
70
80
|
`format: text` is **mandatory**. Without it Mihomo parses the file as YAML, the provider ends up empty, and OpenClash gives no error.
|
|
71
81
|
|
|
72
|
-
`target
|
|
82
|
+
Each pair's `target` in `domsync.yaml` is the absolute path of the same file; OpenClash keeps provider files under `/etc/openclash/rule_provider/`.
|
|
73
83
|
|
|
74
84
|
`/etc/init.d/openclash reload` does **not** re-read provider files. Use `restart`, which is why the example config's post-write command is `/etc/init.d/openclash restart`. Any other command that genuinely reloads providers works too.
|
|
75
85
|
|
|
76
|
-
In the provider file, `# [section]` lines are comments for humans only: Mihomo ignores lines starting with `#` or `//`. domsync writes section headers only in that commented form, because a bare `[media]` line would be accepted by Mihomo as a literal domain and silently inflate the rule count. Comments are never preserved from the
|
|
86
|
+
In the provider file, `# [section]` lines are comments for humans only: Mihomo ignores lines starting with `#` or `//`. domsync writes section headers only in that commented form, because a bare `[media]` line would be accepted by Mihomo as a literal domain and silently inflate the rule count. Comments are never preserved from the server: the file is regenerated from the local state.
|
|
77
87
|
|
|
78
88
|
## Local file format
|
|
79
89
|
|
|
@@ -92,9 +102,9 @@ In the provider file, `# [section]` lines are comments for humans only: Mihomo i
|
|
|
92
102
|
|
|
93
103
|
### Sections
|
|
94
104
|
|
|
95
|
-
A section header is `[name]` on its own line, optionally with surrounding whitespace. Names must be non-empty, at most 64 characters, free of control characters, and unique. Section order follows first appearance in the local file, but the `
|
|
105
|
+
A section header is `[name]` on its own line, optionally with surrounding whitespace. Names must be non-empty, at most 64 characters, free of control characters, and unique. Section order follows first appearance in the local file, but the pair's `other_section` section (default `other`) is always rendered last. Empty sections are dropped, together with their comments.
|
|
96
106
|
|
|
97
|
-
A file with no section headers is a flat list and stays flat; in that case no `other` section is ever created, even if
|
|
107
|
+
A file with no section headers is a flat list and stays flat; in that case no `other` section is ever created, even if provider-only domains are adopted.
|
|
98
108
|
|
|
99
109
|
### Patterns
|
|
100
110
|
|
|
@@ -120,10 +130,10 @@ Rules enforced by the parser:
|
|
|
120
130
|
|
|
121
131
|
A leading `-` is the only structural marker: `-` followed by any valid pattern is a deletion directive. A `+` or `*` inside the pattern is Mihomo syntax, not a sign.
|
|
122
132
|
|
|
123
|
-
- `-pattern` with no positive entry for the same pattern **deletes** it from the
|
|
124
|
-
- `-pattern` plus a positive entry for the same pattern in a **different** section **moves** it to that section. On the
|
|
133
|
+
- `-pattern` with no positive entry for the same pattern **deletes** it from the provider file and from the local snapshot.
|
|
134
|
+
- `-pattern` plus a positive entry for the same pattern in a **different** section **moves** it to that section. On the server only the section comment changes.
|
|
125
135
|
- `-pattern` and a positive entry in the **same** section is redundant: the positive entry wins and a warning is printed. With `--strict` it is an error.
|
|
126
|
-
- A `-pattern` that exists neither locally nor
|
|
136
|
+
- A `-pattern` that exists neither locally nor in the provider file produces a warning; `--strict` turns it into an error.
|
|
127
137
|
|
|
128
138
|
To delete a domain that still has a positive line, remove that positive line and add `-pattern`. While the positive line remains, domsync treats the pair as a move, not a deletion.
|
|
129
139
|
|
|
@@ -131,7 +141,7 @@ After a successful sync the `-` lines disappear from the local file: the domain
|
|
|
131
141
|
|
|
132
142
|
### Comments
|
|
133
143
|
|
|
134
|
-
- `#` at the start of a line is a comment. Comments are local-only: they are kept in the local snapshot and are never written to the
|
|
144
|
+
- `#` at the start of a line is a comment. Comments are local-only: they are kept in the local snapshot and are never written to the provider file.
|
|
135
145
|
- Comments attach to the current section and are rendered immediately after that section's header, in their original order. Comments before the first section stay at the top of the file.
|
|
136
146
|
- Inline comments are invalid. The line `+.example.com # note` is a validation error; put the note on its own line.
|
|
137
147
|
- `//` is not a local comment. A local line starting with `//` is a pattern and is rejected.
|
|
@@ -139,64 +149,103 @@ After a successful sync the `-` lines disappear from the local file: the domain
|
|
|
139
149
|
|
|
140
150
|
### Output rules
|
|
141
151
|
|
|
142
|
-
Within each section, patterns are sorted; section order is otherwise preserved; the `other_section` is last. The local file is rewritten as a snapshot of the merged state, comments included. When the local file has sections, the
|
|
152
|
+
Within each section, patterns are sorted; section order is otherwise preserved; the `other_section` is last. The local file is rewritten as a snapshot of the merged state, comments included. When the local file has sections, the provider file contains `# [section]` headers followed by the same sorted patterns; a flat local file produces a flat provider file. Provider-only domains are added to `other_section`; if the local file already has that section it is reused, so a second one is never created.
|
|
143
153
|
|
|
144
|
-
A missing local file is treated as an empty list, so the first run bootstraps the local snapshot from the
|
|
154
|
+
A missing local file is treated as an empty list, so the first run bootstraps the local snapshot from the provider file: every provider-only domain is adopted and written locally. An empty local file with an empty provider file is a no-op. A plan whose final list would be empty while the provider file is not is an error: domsync refuses to wipe the provider file.
|
|
145
155
|
|
|
146
|
-
|
|
156
|
+
Concurrent runs are refused. A run holds an exclusive lock on `<config-path>.domsync.lock` next to the config file from the moment the configuration is loaded until every write and post-write command has finished, so a cron job and a manual run cannot interleave their reads and writes. One lock covers the whole config, so two different configs can run at the same time. The lock file stays on disk after the run; the lock itself is released by the operating system when the process exits, including after a crash.
|
|
147
157
|
|
|
148
|
-
|
|
158
|
+
### Provider file validation
|
|
159
|
+
|
|
160
|
+
When reading the provider file from a server, domsync ignores blank lines and lines starting with `#` or `//`. Every other line must be a valid pattern; otherwise that pair fails with the file, line number and offending text, and nothing is written for it. Duplicate patterns are collapsed. A bare `[media]` header on the server is therefore an error, not a domain.
|
|
149
161
|
|
|
150
162
|
## Configuration reference
|
|
151
163
|
|
|
152
164
|
YAML parsing is strict: unknown fields, multiple YAML documents and an empty file are errors.
|
|
153
165
|
|
|
166
|
+
Top-level keys:
|
|
167
|
+
|
|
154
168
|
| Key | Type | Default | Meaning |
|
|
155
169
|
|---|---|---|---|
|
|
156
|
-
| `version` | integer | required | Must be `1
|
|
157
|
-
| `
|
|
158
|
-
| `target.host` | string | required | Router host name or address. |
|
|
159
|
-
| `target.port` | integer | `22` | SSH port (1-65535). |
|
|
160
|
-
| `target.user` | string | required | SSH user. |
|
|
161
|
-
| `target.ssh_key` | path | empty | Private key (ed25519, ecdsa or rsa). If empty, `SSH_AUTH_SOCK` must provide an agent. Both are used when available. |
|
|
162
|
-
| `target.known_hosts` | path | `~/.ssh/known_hosts` | Must already exist and be a regular file. |
|
|
163
|
-
| `target.path` | string | required | Absolute path of the provider file on the router; a trailing `/` is rejected. |
|
|
164
|
-
| `target.other_section` | string | `other` | Section that receives router-only domains. |
|
|
165
|
-
| `target.mode` | string | `0644` | Octal permissions for the written provider file, at most `0777`. Quote it in YAML. |
|
|
166
|
-
| `target.backup` | boolean | `true` | Copy the previous provider file to the backup path before replacing it. |
|
|
167
|
-
| `target.backup_suffix` | string | `.domsync.bak` | Suffix appended to `target.path` for the backup file. |
|
|
168
|
-
| `target.post_write.run` | string | `on_change` | When to run `target.post_write.commands`: `on_change`, `always` or `never`. |
|
|
169
|
-
| `target.post_write.timeout` | duration string | `120s` | Timeout for each command. See the note below. |
|
|
170
|
-
| `target.post_write.commands` | list of strings | empty | Commands run sequentially over the existing SSH connection. |
|
|
170
|
+
| `version` | integer | required | Must be `2`; a `version: 1` config is rejected. |
|
|
171
|
+
| `servers` | list | required | One or more servers; at least one entry. |
|
|
171
172
|
| `update.check` | boolean | `true` | Check GitHub for a newer release at launch. `--no-update-check` overrides it. |
|
|
172
|
-
| `logging.file` | path | empty (disabled) | When set, one summary line is appended on
|
|
173
|
+
| `logging.file` | path | empty (disabled) | When set, one summary line is appended on every non-dry-run run that reaches the end, including runs with failed pairs or servers. |
|
|
174
|
+
|
|
175
|
+
Server keys:
|
|
176
|
+
|
|
177
|
+
| Key | Type | Default | Meaning |
|
|
178
|
+
|---|---|---|---|
|
|
179
|
+
| `name` | string | required | Unique across servers, `[a-z0-9][a-z0-9_-]*`, at most 32 characters. Used in reports and logs. |
|
|
180
|
+
| `enabled` | boolean | `true` | `false` skips the server entirely, `validate` included. See below. |
|
|
181
|
+
| `host` | string | required | Server host name or address. |
|
|
182
|
+
| `port` | integer | `22` | SSH port (1-65535). |
|
|
183
|
+
| `user` | string | required | SSH user. |
|
|
184
|
+
| `ssh_key` | path | empty | Private key (ed25519, ecdsa or rsa). If empty, `SSH_AUTH_SOCK` must provide an agent. Both are used when available. |
|
|
185
|
+
| `known_hosts` | path | `~/.ssh/known_hosts` | Must already exist and be a regular file. |
|
|
186
|
+
| `post_write.run` | string | `on_change` | When to run `post_write.commands`: `on_change`, `always` or `never`. |
|
|
187
|
+
| `post_write.timeout` | duration string | `120s` | Timeout for each command. See the note below. |
|
|
188
|
+
| `post_write.commands` | list of strings | empty | Commands run sequentially over the existing SSH connection, after the server's pairs. |
|
|
189
|
+
| `files` | list | required | One or more pairs; at least one entry, even when the server is disabled. |
|
|
190
|
+
|
|
191
|
+
File (pair) keys:
|
|
192
|
+
|
|
193
|
+
| Key | Type | Default | Meaning |
|
|
194
|
+
|---|---|---|---|
|
|
195
|
+
| `source` | path | required in version 2 | Local domain list, resolved relative to the config file. A regular file or absent; absent means an empty list. Must be unique across the whole config. |
|
|
196
|
+
| `target` | string | required | Absolute path of the provider file on that server; a trailing `/` is rejected. Must be unique within the server; the same target on two servers is fine. |
|
|
197
|
+
| `other_section` | string | `other` | Section that receives provider-only domains. |
|
|
198
|
+
| `mode` | string | `0644` | Octal permissions for the written provider file, between `0001` and `0777`. Quote it in YAML. |
|
|
199
|
+
| `backup` | boolean | `true` | Copy the previous provider file to the backup path before replacing it. |
|
|
200
|
+
| `backup_suffix` | string | `.domsync.bak` | Suffix appended to `target` for the backup file. |
|
|
173
201
|
|
|
174
|
-
`target.
|
|
202
|
+
Two pairs may not share a `source` (resolved absolute path): both would rewrite it, so the config is rejected naming both positions. Two pairs on the same server may not share a `target`; the same path on two different servers is fine. Relative paths resolve against the config file's directory and `~` expands to your home, as described in Quick start.
|
|
175
203
|
|
|
176
|
-
|
|
177
|
-
|
|
204
|
+
`post_write.run` values:
|
|
205
|
+
|
|
206
|
+
- `on_change` - run the commands when at least one pair on this server changed something, on the server or locally.
|
|
207
|
+
- `always` - run them after every non-dry-run sync of the server, including a run with no changes and a run in which a pair failed.
|
|
178
208
|
- `never` - never run them.
|
|
179
209
|
|
|
180
|
-
`--dry-run` never runs commands, and
|
|
210
|
+
`--dry-run` never runs commands, and a server whose connection failed runs none. A command failure is recorded and does not undo any write; the sequence stops at the first failing command.
|
|
211
|
+
|
|
212
|
+
`enabled: false` parks a server: `sync` and `validate` skip it entirely, and the report marks it `skipped`. Every shape check still applies to a disabled server — required fields, name syntax and uniqueness, `port`, `mode`, `other_section`, `post_write.run`, absolute `target`, unique `source` across the whole config, and unique `target` within the server — so a typo in a parked server is a config error, not a surprise on the day it is switched on. Only filesystem and environment checks are skipped: `ssh_key` exists, `known_hosts` exists, `SSH_AUTH_SOCK` when `ssh_key` is empty, and `source` being a regular file or absent. That makes `enabled: false` a legitimate way to park a server whose key is not on this machine yet.
|
|
181
213
|
|
|
182
214
|
**The command timeout cannot be disabled.** `timeout` applies to each command separately. A value of `0s` is treated as "unset" and replaced by the built-in default of `120s`; negative values are rejected. Choose a large finite value if a command legitimately runs long.
|
|
183
215
|
|
|
184
216
|
**Host keys are always verified.** This is true for key-file authentication and for ssh-agent authentication alike. There is no trust-on-first-use mode.
|
|
185
217
|
|
|
186
|
-
Config validation runs before SSH is dialled: a missing key file, a missing `known_hosts`,
|
|
218
|
+
Config validation runs before SSH is dialled: a missing key file, a missing `known_hosts`, an empty `ssh_key` with `SSH_AUTH_SOCK` unset, or a `source` that is not a regular file fails with exit code 1 before any connection is attempted. Disabled servers are exempt from these filesystem checks.
|
|
219
|
+
|
|
220
|
+
## Validation
|
|
221
|
+
|
|
222
|
+
`domsync validate` loads the configuration, walks every enabled server's pairs and parses each local list without opening an SSH connection. It covers everything `domsync` checks before dialling — the config schema, path resolution, cross-pair uniqueness, the existence of each server's `ssh_key` and `known_hosts`, and every local list's syntax — and nothing that needs a server. Disabled servers are skipped and reported as `skipped`.
|
|
223
|
+
|
|
224
|
+
Validation continues past a broken pair: it is reported and the remaining pairs are still checked.
|
|
225
|
+
|
|
226
|
+
```sh
|
|
227
|
+
domsync validate
|
|
228
|
+
domsync --json validate
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Exit codes follow the table below: `1` for a configuration or read error and `2` for an invalid local list. When several pairs fail, the exit code is the code of the first failure in config order (server order, then file order).
|
|
232
|
+
|
|
233
|
+
With `--json` the output is one object with `ok` and `servers`; each server carries `name`, `ok`, `skipped` and `files`, and each file carries `source`, `ok`, `total`, `sections` and, on failure, an `error` object with the exit code and message. A config-level error produces `ok: false` with an `error` object and exits 1 before any pair is examined. Without `--json` the human output prints the resolved config path, then a block per server (`name`, then each local file with its counts) and the usual summary line (`domsync: N доменов, M секций`); a failed file prints `ошибка: ...`.
|
|
187
234
|
|
|
188
235
|
## Exit codes
|
|
189
236
|
|
|
190
237
|
| Code | Meaning |
|
|
191
238
|
|---|---|
|
|
192
239
|
| `0` | Success, including "no changes". Also `--help` and `--version`. |
|
|
193
|
-
| `1` | Usage or configuration error, local file read/write error,
|
|
194
|
-
| `2` | Validation error in
|
|
240
|
+
| `1` | Usage or configuration error, local file read/write error, log write error, or another run holding the config lock. |
|
|
241
|
+
| `2` | Validation error in a local list or a provider file, including `--strict` warnings, and an empty final list. |
|
|
195
242
|
| `3` | SSH connection, authentication, host-key or remote read/write/verify error. |
|
|
196
243
|
| `4` | Update error, including the Homebrew/npm refusal. |
|
|
197
244
|
| `5` | A post-write command failed (non-zero exit or transport error). |
|
|
198
245
|
|
|
199
|
-
|
|
246
|
+
When several things fail, the exit code is the code of the first failure in execution order: server order, then file order. A server that cannot be dialled counts at its own position, before its pairs, so a connection error beats a later pair failure. A failure in one pair or one server never stops the rest.
|
|
247
|
+
|
|
248
|
+
`--strict` only promotes local warnings (deletion target not found, redundant `+`/`-` in one section) to errors, and fails only that pair. Problems in a provider file are always errors, and a failed launch-time update check never changes the sync exit code.
|
|
200
249
|
|
|
201
250
|
## Updates
|
|
202
251
|
|
|
@@ -228,30 +277,35 @@ So update those installs with `brew upgrade --cask domsync` or `npm i -g @domsyn
|
|
|
228
277
|
|
|
229
278
|
## Output
|
|
230
279
|
|
|
231
|
-
The default human report is Russian and looks like this for a run that changed
|
|
280
|
+
The default human report is Russian and looks like this for a run that changed one pair:
|
|
232
281
|
|
|
233
282
|
```text
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
283
|
+
router (192.168.1.1)
|
|
284
|
+
domains/media.txt → /etc/openclash/rule_provider/media.txt
|
|
285
|
+
роутер: +2 −1, записан, бэкап /etc/openclash/rule_provider/media.txt.domsync.bak
|
|
286
|
+
локально: +1, перемещён 1
|
|
287
|
+
domains/ai.txt → /etc/openclash/rule_provider/ai.txt: без изменений
|
|
288
|
+
команда: /etc/init.d/openclash restart — ok, 0.8s
|
|
289
|
+
vps-1: пропущен (disabled)
|
|
290
|
+
domsync: 42 домена, 7 секций
|
|
238
291
|
```
|
|
239
292
|
|
|
240
|
-
-
|
|
293
|
+
- Each server block starts with its name and host, followed by one line per pair. A skipped server is a single `name: пропущен (disabled)` line; a server that failed to connect prints its name and the error, with the number of pairs that were not attempted.
|
|
294
|
+
- A pair with no changes on either side stays on one line with `без изменений`; a failed pair prints `ошибка: <message>` on its own line.
|
|
241
295
|
- `роутер` and `локально` show added and removed counts with the U+2212 minus sign. The router line adds `записан` only when the file was actually written, and the backup path when a backup was made; the local line adds `перемещён N` for moved patterns.
|
|
242
|
-
-
|
|
296
|
+
- The final line reports the total number of domains and non-empty sections across every pair that ran. A successful run without changes says `domsync: изменений нет (N доменов, M секций)`.
|
|
243
297
|
- With `--dry-run`, each changed file is marked `будет записан (dry-run)`.
|
|
244
298
|
- Command results are `ok, <duration>` or `ошибка <exit code>`; a transport failure prints `ошибка: <message>`.
|
|
245
299
|
- Warnings print as `предупреждение: <message>`.
|
|
246
300
|
|
|
247
|
-
`--dry-run` still connects to
|
|
301
|
+
`--dry-run` still connects to every enabled server and reads the current provider files; it skips both writes and all commands. It is not an offline mode.
|
|
248
302
|
|
|
249
|
-
- `--json` writes a single JSON object to stdout; errors after argument parsing are JSON as well.
|
|
303
|
+
- `--json` writes a single JSON object to stdout; errors after argument parsing are JSON as well. Top-level fields are `ok`, `changed`, `dry_run`, `total`, `sections`, `servers`, `warnings`, `update` and `error`; each server carries `name`, `host`, `ok`, `changed`, `skipped`, `skipped_pairs`, `files`, `commands` and `error`; each file carries `source`, `target`, `ok`, `changed`, `total`, `sections`, `router`, `local`, `warnings` and `error`.
|
|
250
304
|
- `--quiet` prints only errors; `--verbose` adds update-check failures to the warnings; `--strict` treats local warnings as errors.
|
|
251
305
|
|
|
252
306
|
## Security
|
|
253
307
|
|
|
254
|
-
- **Strict host key checking.** Every connection verifies the
|
|
308
|
+
- **Strict host key checking.** Every connection verifies the server key against `known_hosts` using `golang.org/x/crypto/ssh/knownhosts`, whether authentication uses a key file or the ssh-agent. An unknown key aborts with its SHA-256 fingerprint and a `ssh-keyscan` hint; a changed key aborts naming both the presented and the expected fingerprints. TOFU does not exist in v1. The host key type is negotiated from the algorithms recorded for the host in `known_hosts`, so a host with only one recorded key type is not rejected merely because the server also offers another.
|
|
255
309
|
- **Updates in v1 rely on SHA-256 only.** The binary checks the downloaded archive against `checksums.txt` from the release and extracts only the expected executable, rejecting path traversal. GoReleaser also publishes a cosign keyless signature bundle (`checksums.txt.sigstore.json`) and GitHub build attestations; these are for manual verification, not checked by the CLI. To verify a release by hand:
|
|
256
310
|
|
|
257
311
|
```sh
|
|
@@ -296,6 +350,10 @@ Tagging `v*` runs `.github/workflows/release.yml`. Maintainers need:
|
|
|
296
350
|
|
|
297
351
|
GoReleaser builds the archives, `checksums.txt`, the cosign bundle and SBOMs, publishes the GitHub release and the Homebrew cask; the release workflow adds build provenance attestations and then publishes the npm packages.
|
|
298
352
|
|
|
353
|
+
## Contributing
|
|
354
|
+
|
|
355
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for the development setup, commit conventions and the pull request workflow. Report vulnerabilities privately as described in [SECURITY.md](SECURITY.md).
|
|
356
|
+
|
|
299
357
|
## License
|
|
300
358
|
|
|
301
359
|
MIT
|
package/domsync.exe
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1 +1,20 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"name": "@domsync/win32-arm64",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"packageManager": "npm@11.5.1+sha512.232e6f5d9e799bcb486920b3e9ba907fdf96e576cf7e8c9446c8162e33a416096a1d37a9e910d9a918f6b1f606791c99bc6bb61ee2569b496ec74af13d0dbd95",
|
|
5
|
+
"os": "win32",
|
|
6
|
+
"cpu": "arm64",
|
|
7
|
+
"files": [
|
|
8
|
+
"domsync",
|
|
9
|
+
"domsync.exe"
|
|
10
|
+
],
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/neiromaster/domsync.git"
|
|
15
|
+
},
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"provenance": true,
|
|
18
|
+
"access": "public"
|
|
19
|
+
}
|
|
20
|
+
}
|