paratix 0.4.0 → 0.5.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.
@@ -0,0 +1,1392 @@
1
+ import { M as Module } from './types-BPzPHfax.js';
2
+
3
+ /**
4
+ * Modules for Debian/Ubuntu-specific apt configuration.
5
+ *
6
+ * Provides four apt-specific helpers:
7
+ * - `debconf` — pre-seed debconf answers for non-interactive installs
8
+ * - `distUpgrade` — run `apt-get dist-upgrade` with full dependency resolution
9
+ * - `key` — import a GPG key into `/etc/apt/keyrings/`
10
+ * - `repository` — add a PPA or custom `.list` source file
11
+ *
12
+ * For installing, removing and upgrading packages use the distro-agnostic
13
+ * `package` module instead.
14
+ *
15
+ * @see pkg
16
+ */
17
+ declare const apt: {
18
+ /**
19
+ * Set debconf selections for a package so that installs/upgrades
20
+ * can proceed non-interactively with the desired answers.
21
+ *
22
+ * @param packageName - The package name whose debconf questions to pre-seed.
23
+ * @param selections - A map of `question -> value` entries where the key is
24
+ * the full debconf question name (e.g. `"postfix/main_mailer_type"`).
25
+ * @returns A Module that applies the debconf selections.
26
+ *
27
+ * @example
28
+ * apt.debconf("postfix", {
29
+ * "postfix/main_mailer_type": "Internet Site",
30
+ * "postfix/mailname": "example.com",
31
+ * })
32
+ */
33
+ debconf(packageName: string, selections: Record<string, string>): Module;
34
+ /**
35
+ * Run `apt-get update && apt-get dist-upgrade` once per dated flag.
36
+ * Performs a full distribution upgrade with dependency resolution.
37
+ *
38
+ * @param date - A date string used as the idempotency key (e.g. `"2024-01-15"`).
39
+ * @returns A Module that performs the dist-upgrade.
40
+ */
41
+ distUpgrade(date: string): Module;
42
+ /**
43
+ * Import a GPG key into `/etc/apt/keyrings/` for use with signed repositories.
44
+ * @param name - Key file name (without `.gpg` extension).
45
+ * @param url - URL to download the key from.
46
+ * @param options - Required trust anchor for the downloaded key.
47
+ * @param options.fingerprint - Expected OpenPGP fingerprint of the repository key.
48
+ * @returns A Module that imports the GPG key.
49
+ */
50
+ key(name: string, url: string, options: {
51
+ fingerprint: string;
52
+ }): Module;
53
+ /**
54
+ * Add an apt repository source, either as a PPA or a custom source line.
55
+ *
56
+ * **PPA form**: pass `"ppa:user/name"` as the first argument (no `source`).
57
+ * Uses `add-apt-repository` internally.
58
+ *
59
+ * **Standard form**: pass a name and a deb source line. The source is
60
+ * written to `/etc/apt/sources.list.d/<name>.list`. The `signed-by` option
61
+ * is automatically derived from `name` (pointing to
62
+ * `/etc/apt/keyrings/<name>.gpg`) unless overridden.
63
+ *
64
+ * @param nameOrPpa - Repository name or PPA identifier (e.g. `"ppa:user/name"`).
65
+ * @param source - The deb source line (omit for PPA form).
66
+ * @param options - Optional settings.
67
+ * @param options.signedBy - Override the key name used for `signed-by`
68
+ * (`false` to disable auto-derivation, a string to use a different key name).
69
+ * @returns A Module that configures the repository.
70
+ *
71
+ * @example
72
+ * // PPA form
73
+ * apt.repository("ppa:ondrej/php")
74
+ *
75
+ * @example
76
+ * // Standard form – signed-by is auto-derived from "nodejs"
77
+ * apt.repository(
78
+ * "nodejs",
79
+ * "deb https://deb.nodesource.com/node_20.x nodistro main",
80
+ * )
81
+ *
82
+ * @example
83
+ * // Standard form with signed-by disabled
84
+ * apt.repository(
85
+ * "internal",
86
+ * "deb [arch=amd64] https://packages.example.com stable main",
87
+ * { signedBy: false },
88
+ * )
89
+ */
90
+ repository(nameOrPpa: string, source?: string, options?: {
91
+ signedBy?: false | string;
92
+ }): Module;
93
+ };
94
+
95
+ /**
96
+ * Modules for managing archive extraction on the remote host.
97
+ */
98
+ declare const archive: {
99
+ /**
100
+ * Extract an archive to a destination directory on the remote host.
101
+ *
102
+ * Supports tar, tar.gz, tgz, tar.bz2, tar.xz, and zip formats.
103
+ * Uses a marker file with SHA256 checksum for idempotency.
104
+ *
105
+ * @param source - Path to the archive (remote path, or local path when upload is true).
106
+ * @param destination - The destination directory on the remote host.
107
+ * @param options - Optional settings.
108
+ * @param options.owner - Run chown -R after extraction.
109
+ * @param options.upload - Upload a local file to the remote host before extracting.
110
+ * @returns A Module that manages the archive extraction.
111
+ */
112
+ extract(source: string, destination: string, options?: {
113
+ owner?: string;
114
+ upload?: boolean;
115
+ }): Module;
116
+ };
117
+
118
+ /**
119
+ * Modules for running arbitrary shell commands on the remote host.
120
+ */
121
+ declare const command: {
122
+ /**
123
+ * Run an arbitrary shell command on the remote host.
124
+ *
125
+ * By default the module always applies (no idempotency). Provide `options.check`
126
+ * with a shell expression that exits `0` when the desired state is already
127
+ * present -- in that case the command is skipped.
128
+ *
129
+ * @param cmd - The shell command to execute.
130
+ * @param options - Optional configuration for the command.
131
+ * @param options.check - An optional shell expression used as the idempotency guard.
132
+ * If it exits `0`, the command is considered already done.
133
+ * @param options.name - An optional display name shown in the run output.
134
+ * @param options.secrets - Secret values that must be redacted from command output.
135
+ * @returns A Module that executes the shell command.
136
+ *
137
+ * @example
138
+ * command.shell("curl -fsSL https://example.com/install.sh | bash", {
139
+ * check: "which my-tool",
140
+ * name: "install my-tool",
141
+ * })
142
+ */
143
+ shell(cmd: string, options?: {
144
+ check?: string;
145
+ name?: string;
146
+ secrets?: string[];
147
+ }): Module;
148
+ };
149
+
150
+ type ComposeRuntime = "docker" | "podman";
151
+ /**
152
+ * Modules for managing Docker Compose / Podman Compose stacks on a remote host.
153
+ *
154
+ * All methods auto-detect the container runtime (`docker` or `podman`) unless
155
+ * an explicit `runtime` option is provided.
156
+ */
157
+ declare const compose: {
158
+ /**
159
+ * Ensure a compose-file is present at `<projectDirectory>/compose.yml`.
160
+ *
161
+ * Provide either `src` (a local file path to upload) or `content` (a string
162
+ * to write). The check phase compares the remote file content with the
163
+ * desired content and skips the apply if they match.
164
+ *
165
+ * @param options - Configuration for the compose file.
166
+ * @param options.projectDirectory - The project directory on the remote host.
167
+ * @param options.src - Local file path to upload as `compose.yml`.
168
+ * @param options.content - String content to write as `compose.yml`.
169
+ * @param options.runtime - Explicit container runtime override.
170
+ * @returns A Module that ensures the compose file is present and valid.
171
+ */
172
+ config(options: {
173
+ content?: string;
174
+ projectDirectory: string;
175
+ runtime?: ComposeRuntime;
176
+ src?: string;
177
+ }): Module;
178
+ /**
179
+ * Tear down all containers in the compose stack. Optionally remove volumes.
180
+ *
181
+ * @param options - Configuration for the down operation.
182
+ * @param options.projectDirectory - The project directory on the remote host.
183
+ * @param options.volumes - When `true`, also remove named volumes.
184
+ * @param options.runtime - Explicit container runtime override.
185
+ * @returns A Module that ensures all containers are stopped and removed.
186
+ */
187
+ down(options: {
188
+ projectDirectory: string;
189
+ runtime?: ComposeRuntime;
190
+ volumes?: boolean;
191
+ }): Module;
192
+ /**
193
+ * Pull the latest images for all services in the compose stack.
194
+ * Signal-style: always applies since an efficient up-to-date check is not
195
+ * feasible.
196
+ *
197
+ * @param options - Configuration for the pull operation.
198
+ * @param options.projectDirectory - The project directory on the remote host.
199
+ * @param options.runtime - Explicit container runtime override.
200
+ * @returns A Module that pulls the latest images.
201
+ */
202
+ pull(options: {
203
+ projectDirectory: string;
204
+ runtime?: ComposeRuntime;
205
+ }): Module;
206
+ /**
207
+ * Restart all containers by running `down` followed by `up -d`.
208
+ * Signal-style: always applies.
209
+ *
210
+ * @param options - Configuration for the restart operation.
211
+ * @param options.projectDirectory - The project directory on the remote host.
212
+ * @param options.runtime - Explicit container runtime override.
213
+ * @returns A Module that restarts the compose stack.
214
+ */
215
+ restart(options: {
216
+ projectDirectory: string;
217
+ runtime?: ComposeRuntime;
218
+ }): Module;
219
+ /**
220
+ * Generate and write a systemd service unit that manages the compose stack
221
+ * via `ExecStart` / `ExecStop`.
222
+ *
223
+ * The service name defaults to `compose-<basename(projectDirectory)>` when not
224
+ * explicitly provided.
225
+ *
226
+ * @param options - Configuration for the systemd unit.
227
+ * @param options.detached - When true, use `compose up -d`; otherwise start attached.
228
+ * @param options.projectDirectory - The project directory on the remote host.
229
+ * @param options.name - Optional service name (without `.service` suffix).
230
+ * @param options.runtime - Explicit container runtime override.
231
+ * @returns A Module that ensures the systemd unit file is present and up-to-date.
232
+ */
233
+ systemd(options: {
234
+ detached?: boolean;
235
+ name?: string;
236
+ projectDirectory: string;
237
+ runtime?: ComposeRuntime;
238
+ }): Module;
239
+ /**
240
+ * Ensure all services in the compose stack are running.
241
+ *
242
+ * The check phase inspects each container's state via `ps --format json`
243
+ * and only skips when every service reports `"running"`.
244
+ *
245
+ * @param options - Configuration for the up operation.
246
+ * @param options.projectDirectory - The project directory on the remote host.
247
+ * @param options.services - Optional list of specific services to start.
248
+ * @param options.runtime - Explicit container runtime override.
249
+ * @returns A Module that ensures the compose stack is up.
250
+ */
251
+ up(options: {
252
+ projectDirectory: string;
253
+ runtime?: ComposeRuntime;
254
+ services?: string[];
255
+ }): Module;
256
+ };
257
+
258
+ /** Options for `cron.job`. */
259
+ type CronJobOptions = {
260
+ /** The crontab line to manage (e.g. `"0 * * * * /usr/bin/backup"`). */
261
+ job: string;
262
+ /** Whether the job should be `"present"` or `"absent"`. Defaults to `"present"`. */
263
+ state?: "absent" | "present";
264
+ };
265
+ /**
266
+ * Modules for managing cron jobs in user crontabs.
267
+ *
268
+ * Each managed entry is identified by a `# paratix: <name>` marker comment
269
+ * written on the line directly above the job line, making all changes
270
+ * idempotent and safely repeatable.
271
+ */
272
+ declare const cron: {
273
+ /**
274
+ * Ensure a cron job is present in (or absent from) a user's crontab.
275
+ *
276
+ * Each managed entry is tracked via a `# paratix: <name>` marker comment
277
+ * placed on the line directly above the job line. When the marker already
278
+ * exists, the job line is updated in place. When `state` is `"absent"`,
279
+ * both the marker and the job line are removed.
280
+ *
281
+ * @param user - The target user whose crontab is managed.
282
+ * @param name - Unique identifier for this cron job, used in the marker line.
283
+ * @param options - Job content and desired state.
284
+ * @param options.job - The crontab line to manage (e.g. `"0 * * * * /usr/bin/backup"`).
285
+ * @param options.state - Whether the job should be `"present"` or `"absent"`. Defaults to `"present"`.
286
+ * @returns A Module that manages the cron job entry.
287
+ */
288
+ job(user: string, name: string, options: CronJobOptions): Module;
289
+ };
290
+
291
+ /**
292
+ * Options shared by all download methods.
293
+ */
294
+ type BaseDownloadOptions = {
295
+ /** Allow unencrypted `http://` downloads explicitly. */
296
+ allowInsecureHttp?: boolean;
297
+ /** Explicitly opt out of integrity verification for trusted sources. */
298
+ allowUnverifiedDownload?: boolean;
299
+ /** Group owner to set on the downloaded file via `chown`. */
300
+ group?: string;
301
+ /** File mode to set via `chmod` (e.g. `"0755"`). */
302
+ mode?: string;
303
+ /** User owner to set on the downloaded file via `chown`. */
304
+ owner?: string;
305
+ /** Expected SHA-256 hex digest for integrity verification. */
306
+ sha256?: string;
307
+ };
308
+ /**
309
+ * Modules for downloading files to remote servers via `curl`.
310
+ */
311
+ declare const download: {
312
+ /**
313
+ * Download a release asset from a GitHub repository.
314
+ *
315
+ * Builds the download URL from the repository, tag, and asset name. For
316
+ * private repositories, provide a `token` which is sent as an
317
+ * `Authorization` header.
318
+ *
319
+ * Idempotency follows the same rules as {@link download.url}: SHA-256
320
+ * comparison when a digest is given, otherwise file-existence check.
321
+ *
322
+ * @param destination - Absolute path on the remote server where the asset is saved.
323
+ * @param options - Repository coordinates and optional download settings.
324
+ * @param options.repo - GitHub repository in `owner/repo` format (e.g. `"hashicorp/terraform"`).
325
+ * @param options.tag - Release tag (e.g. `"v1.5.0"`).
326
+ * @param options.asset - GitHub release asset filename (e.g. `"terraform_1.5.0_linux_amd64.zip"`).
327
+ * @param options.token - GitHub Personal Access Token for private repositories.
328
+ * @param options.sha256 - Expected SHA-256 hex digest for integrity verification.
329
+ * @param options.allowUnverifiedDownload - Explicitly opt out of integrity verification.
330
+ * @param options.mode - File mode to set via `chmod` (e.g. `"0755"`).
331
+ * @param options.owner - User owner to set on the downloaded file via `chown`.
332
+ * @param options.group - Group owner to set on the downloaded file via `chown`.
333
+ * @returns A Module that manages the GitHub release download.
334
+ */
335
+ github(destination: string, options: {
336
+ /** GitHub release asset filename (e.g. `"terraform_1.5.0_linux_amd64.zip"`). */
337
+ asset: string;
338
+ /** GitHub repository in `owner/repo` format (e.g. `"hashicorp/terraform"`). */
339
+ repo: string;
340
+ /** Release tag (e.g. `"v1.5.0"`). */
341
+ tag: string;
342
+ /** GitHub Personal Access Token for private repositories. */
343
+ token?: string;
344
+ } & BaseDownloadOptions): Module;
345
+ /**
346
+ * Download a large file that should only be fetched once.
347
+ *
348
+ * Tracks whether the download has been performed by writing a flag file
349
+ * under `/var/lib/paratix/flags/`. The flag name is derived from a SHA-256
350
+ * hash of the URL. When `sha256` is provided, the check additionally verifies
351
+ * the remote file's digest, and the downloaded file is verified after transfer.
352
+ *
353
+ * @param destination - Absolute path on the remote server where the file is saved.
354
+ * @param url - The URL to download from.
355
+ * @param options - Optional settings for ownership, permissions, and headers.
356
+ * @param options.allowInsecureHttp - Allow unencrypted `http://` downloads explicitly.
357
+ * @param options.group - Group owner to set on the downloaded file via `chown`.
358
+ * @param options.mode - File mode to set via `chmod` (e.g. `"0755"`).
359
+ * @param options.owner - User owner to set on the downloaded file via `chown`.
360
+ * @param options.sha256 - Expected SHA-256 hex digest for integrity verification.
361
+ * @param options.allowUnverifiedDownload - Explicitly opt out of integrity verification.
362
+ * @param options.headers - Additional HTTP headers sent with the curl request.
363
+ * @returns A Module that manages the large file download.
364
+ */
365
+ large(destination: string, url: string, options?: {
366
+ /** Allow unencrypted `http://` downloads explicitly. */
367
+ allowInsecureHttp?: boolean;
368
+ /** Explicitly opt out of integrity verification for trusted sources. */
369
+ allowUnverifiedDownload?: boolean;
370
+ /** Group owner to set on the downloaded file via `chown`. */
371
+ group?: string;
372
+ /** Additional HTTP headers sent with the curl request. */
373
+ headers?: Record<string, string>;
374
+ /** File mode to set via `chmod` (e.g. `"0755"`). */
375
+ mode?: string;
376
+ /** User owner to set on the downloaded file via `chown`. */
377
+ owner?: string;
378
+ /** Expected SHA-256 hex digest for integrity verification. */
379
+ sha256?: string;
380
+ }): Module;
381
+ /**
382
+ * Download a file from a URL to the remote server via `curl -fsSL`.
383
+ *
384
+ * Idempotency is determined by SHA-256 comparison (when `sha256` is
385
+ * provided), file existence (when no digest is given), or skipped entirely
386
+ * when `force` is `true`.
387
+ *
388
+ * @param destination - Absolute path on the remote server where the file is saved.
389
+ * @param url - The URL to download from.
390
+ * @param options - Optional settings for integrity, ownership, and headers.
391
+ * @param options.allowUnverifiedDownload - Explicitly opt out of integrity verification.
392
+ * @returns A Module that manages the file download.
393
+ */
394
+ url(destination: string, url: string, options?: {
395
+ /** Allow unencrypted `http://` downloads explicitly. */
396
+ allowInsecureHttp?: boolean;
397
+ /** Explicitly opt out of integrity verification for trusted sources. */
398
+ allowUnverifiedDownload?: boolean;
399
+ /** Force re-download even if the file already exists. */
400
+ force?: boolean;
401
+ /** Additional HTTP headers sent with the curl request. */
402
+ headers?: Record<string, string>;
403
+ } & BaseDownloadOptions): Module;
404
+ };
405
+
406
+ /** Options for the {@link block} module. */
407
+ type BlockOptions = {
408
+ /** The desired content between the markers. */
409
+ content: string;
410
+ /** Unique identifier for the managed block. Used in the marker comment lines. */
411
+ name: string;
412
+ /** Comment prefix for the marker lines (default `"#"`). */
413
+ prefix?: string;
414
+ };
415
+ /**
416
+ * Concatenate local fragment files and write the result to the remote host.
417
+ * The file is only transferred when the remote SHA-256 differs from the
418
+ * combined local fragments.
419
+ *
420
+ * @param remotePath - Destination path on the remote host.
421
+ * @param fragments - Array of local file paths whose contents are concatenated.
422
+ * @param options - Optional file attributes.
423
+ * @param options.mode - Optional chmod mode string (e.g. `"0644"`).
424
+ * @param options.owner - Optional chown owner string (e.g. `"www-data:www-data"`).
425
+ * @returns A Module that assembles the fragments on the remote host.
426
+ */
427
+ declare function assemble(remotePath: string, fragments: string[], options?: {
428
+ mode?: string;
429
+ owner?: string;
430
+ }): Module;
431
+ /**
432
+ * Ensure a managed block of text is present in a remote file.
433
+ * The block is delimited by marker comments of the form
434
+ * `<prefix> BEGIN paratix: <name>` / `<prefix> END paratix: <name>`.
435
+ * If the markers are not yet present, the block is appended to the file.
436
+ * If the markers already exist, the content between them is replaced in place.
437
+ *
438
+ * @param remotePath - Path to the file on the remote host.
439
+ * @param options - Block configuration.
440
+ * @param options.content - The desired content between the begin and end markers.
441
+ * @param options.name - Unique identifier for the managed block, used in the marker lines.
442
+ * @param options.prefix - Comment prefix for the marker lines (default `"#"`).
443
+ * @returns A Module that ensures the block is present with the correct content.
444
+ */
445
+ declare function block(remotePath: string, options: BlockOptions): Module;
446
+ /**
447
+ * Set file or directory ownership and permissions on the remote host.
448
+ * Only the attributes specified in `options` are checked and applied.
449
+ *
450
+ * @param remotePath - Path to the file or directory on the remote host.
451
+ * @param options - Attributes to enforce.
452
+ * @param options.group - Optional group name.
453
+ * @param options.mode - Optional chmod mode string (e.g. `"0644"`).
454
+ * @param options.owner - Optional owner name.
455
+ * @returns A Module that ensures the properties match.
456
+ */
457
+ declare function properties(remotePath: string, options: {
458
+ group?: string;
459
+ mode?: string;
460
+ owner?: string;
461
+ }): Module;
462
+ /**
463
+ * Replace all occurrences of a regex pattern in a remote file.
464
+ * `check` uses `grep -E` to detect whether the pattern still exists in the file.
465
+ * `apply` reads the file, performs the replacement in TypeScript and writes it back.
466
+ *
467
+ * @param remotePath - Path to the file on the remote host.
468
+ * @param pattern - Extended regex pattern to match.
469
+ * @param replacement - Replacement string.
470
+ * @returns A Module that performs the substitution.
471
+ */
472
+ declare function replace(remotePath: string, pattern: string, replacement: string): Module;
473
+ /**
474
+ * Read metadata about a remote file via `stat`.
475
+ * This is a read-only module: `check` always reports `"needs-apply"` so the runner
476
+ * invokes `apply`, which populates the result's `meta` map with the following keys:
477
+ * - `file.stat.size` — file size in bytes
478
+ * - `file.stat.mode` — octal permission bits (e.g. `"644"`)
479
+ * - `file.stat.owner` — owning user name
480
+ * - `file.stat.group` — owning group name
481
+ * - `file.stat.type` — file type string (e.g. `"regular file"`, `"directory"`)
482
+ * - `file.stat.mtime` — last modification time as a Unix timestamp string
483
+ *
484
+ * @param remotePath - Path to the file on the remote host.
485
+ * @returns A Module that reads file metadata into `result.meta`.
486
+ */
487
+ declare function stat(remotePath: string): Module;
488
+
489
+ /**
490
+ * Modules for managing remote files and directories.
491
+ *
492
+ * Idempotency is enforced via SHA-256 checksums for file content and
493
+ * existence checks for directories and individual lines.
494
+ */
495
+ declare const file: {
496
+ /**
497
+ * Ensure a remote path does not exist, removing it recursively if present.
498
+ *
499
+ * @param remotePath - Path to remove on the remote host.
500
+ * @returns A Module that ensures the path is absent.
501
+ */
502
+ absent(remotePath: string): Module;
503
+ assemble: typeof assemble;
504
+ block: typeof block;
505
+ chmod(remotePath: string, mode: string): Module;
506
+ chown(remotePath: string, owner: string): Module;
507
+ /**
508
+ * Upload a local file to the remote host.
509
+ * The file is only transferred when the remote SHA-256 differs from the local one.
510
+ *
511
+ * @param remotePath - Destination path on the remote host.
512
+ * @param localPath - Source path on the local filesystem.
513
+ * @param options - Optional file attributes.
514
+ * @param options.mode - Optional chmod mode string (e.g. `"0644"`).
515
+ * @param options.owner - Optional chown owner string (e.g. `"www-data:www-data"`).
516
+ * @returns A Module that copies the file to the remote host.
517
+ */
518
+ copy(remotePath: string, localPath: string, options?: {
519
+ mode?: string;
520
+ owner?: string;
521
+ }): Module;
522
+ /**
523
+ * Ensure a remote directory exists, creating it recursively if needed.
524
+ *
525
+ * @param remotePath - Path of the directory to create on the remote host.
526
+ * @param options - Optional directory attributes.
527
+ * @param options.mode - Optional chmod mode string.
528
+ * @param options.owner - Optional chown owner string.
529
+ * @returns A Module that ensures the directory exists.
530
+ */
531
+ directory(remotePath: string, options?: {
532
+ mode?: string;
533
+ owner?: string;
534
+ }): Module;
535
+ /**
536
+ * Ensure a specific line is present in a remote file.
537
+ * When `options.match` is provided, the first line matching the regex is replaced
538
+ * with the new `line` value instead of appending.
539
+ *
540
+ * @param remotePath - Path to the file on the remote host.
541
+ * @param line - The exact line content to ensure is present.
542
+ * @param options - Optional match configuration.
543
+ * @param options.match - A regex pattern; when matched, the line is replaced rather than appended.
544
+ * @returns A Module that ensures the line is present.
545
+ */
546
+ line(remotePath: string, line: string, options?: {
547
+ match?: string;
548
+ }): Module;
549
+ properties: typeof properties;
550
+ replace: typeof replace;
551
+ stat: typeof stat;
552
+ /**
553
+ * Render a local template file with env values and write the result to the remote host.
554
+ * Uses SHA-256 comparison of the rendered output to avoid unnecessary writes.
555
+ *
556
+ * @param remotePath - Destination path on the remote host.
557
+ * @param templatePath - Path to the local template file containing `{{key}}` placeholders.
558
+ * @param options - Optional file attributes.
559
+ * @param options.mode - Optional chmod mode string.
560
+ * @param options.owner - Optional chown owner string.
561
+ * @param options.strict - When `true`, every template placeholder must use an explicit modifier.
562
+ * @returns A Module that renders and writes the template.
563
+ */
564
+ template(remotePath: string, templatePath: string, options?: {
565
+ mode?: string;
566
+ owner?: string;
567
+ strict?: boolean;
568
+ }): Module;
569
+ };
570
+
571
+ /**
572
+ * Modules for managing Git repositories on the remote host.
573
+ */
574
+ declare const git: {
575
+ /**
576
+ * Ensure a Git repository is cloned to the given destination and optionally
577
+ * checked out at a specific ref (branch, tag, or commit).
578
+ *
579
+ * If the destination directory does not yet contain a `.git` folder, the
580
+ * repository is cloned from scratch. If it already exists, the repository is
581
+ * updated instead (fetch + checkout + reset). When no `ref` is specified, a
582
+ * plain `git pull` is performed on an existing clone.
583
+ *
584
+ * @param repo - The repository URL to clone.
585
+ * @param destination - The destination path on the remote host.
586
+ * @param options - Optional settings.
587
+ * @param options.ref - A branch, tag, or commit SHA to check out.
588
+ * @returns A Module that manages the cloned repository.
589
+ */
590
+ clone(repo: string, destination: string, options?: {
591
+ ref?: string;
592
+ }): Module;
593
+ };
594
+
595
+ /**
596
+ * Modules for managing Linux groups.
597
+ */
598
+ declare const group: {
599
+ /**
600
+ * Ensure a group does not exist. Removes it via `groupdel` if present.
601
+ *
602
+ * @param name - The group name to remove.
603
+ * @returns A Module that ensures the group is absent.
604
+ */
605
+ absent(name: string): Module;
606
+ /**
607
+ * Ensure a group exists. Creates it via `groupadd` if absent.
608
+ *
609
+ * @param name - The group name.
610
+ * @param options - Optional group configuration.
611
+ * @param options.gid - Desired numeric GID.
612
+ * @returns A Module that ensures the group is present.
613
+ */
614
+ present(name: string, options?: {
615
+ gid?: number;
616
+ }): Module;
617
+ };
618
+
619
+ /**
620
+ * Modules for managing the system hostname.
621
+ */
622
+ declare const hostname: {
623
+ /**
624
+ * Set the system hostname via `hostnamectl set-hostname`.
625
+ * Checks the current hostname first and skips the command when it already matches.
626
+ *
627
+ * @param name - The desired hostname.
628
+ * @returns A Module that sets the hostname.
629
+ */
630
+ set(name: string): Module;
631
+ };
632
+
633
+ /**
634
+ * Modules for managing filesystem mounts and `/etc/fstab` entries on a remote host.
635
+ */
636
+ declare const mount: {
637
+ /**
638
+ * Ensure a mountpoint is not mounted. Optionally removes the `/etc/fstab` entry.
639
+ *
640
+ * The check phase verifies both whether the path is currently mounted and, when
641
+ * `persist` is `true`, whether a corresponding fstab entry exists. The apply
642
+ * phase always returns `"changed"` even if only one of the two conditions required
643
+ * action.
644
+ *
645
+ * @param options - Configuration for unmounting.
646
+ * @param options.path - The mountpoint to unmount.
647
+ * @param options.persist - When `true` (default), also remove the fstab entry.
648
+ * @returns A Module that ensures the mountpoint is absent.
649
+ */
650
+ absent(options: {
651
+ path: string;
652
+ persist?: boolean;
653
+ }): Module;
654
+ /**
655
+ * Ensure a filesystem is mounted at the given path. Creates the mountpoint
656
+ * directory if it does not exist. Optionally persists the mount in `/etc/fstab`.
657
+ *
658
+ * The check phase verifies that the mountpoint is active (via `findmnt`) and,
659
+ * when `persist` is `true`, that the fstab entry matches the desired line
660
+ * exactly. It does **not** compare the currently mounted source, filesystem
661
+ * type, or options against the desired values — a remount is only triggered
662
+ * when the mountpoint is absent entirely.
663
+ *
664
+ * @param options - Configuration for the mount.
665
+ * @param options.fstype - The filesystem type (e.g. `"ext4"`, `"tmpfs"`, `"nfs"`).
666
+ * @param options.opts - Mount options string (e.g. `"noexec,nosuid,nodev,size=512m"`).
667
+ * @param options.path - The mountpoint path.
668
+ * @param options.persist - When `true` (default), add or update the fstab entry.
669
+ * @param options.src - The device or virtual filesystem source (e.g. `"tmpfs"`, `"/dev/sdb1"`).
670
+ * @returns A Module that ensures the filesystem is mounted.
671
+ */
672
+ present(options: {
673
+ fstype: string;
674
+ opts: string;
675
+ path: string;
676
+ persist?: boolean;
677
+ src: string;
678
+ }): Module;
679
+ };
680
+
681
+ /** Wait-for condition and timing options. */
682
+ type WaitForOptions = {
683
+ /** String that must appear in `file` for the condition to be satisfied. Requires `file`. */
684
+ contains?: string;
685
+ /** Absolute path to a file whose existence (or content) is checked. */
686
+ file?: string;
687
+ /** Host address used for port checks (default: `"127.0.0.1"`). */
688
+ host?: string;
689
+ /** Poll interval in milliseconds between condition checks (default: `2000`). */
690
+ interval?: number;
691
+ /** TCP port to probe with `nc -z`. */
692
+ port?: number;
693
+ /** Maximum time in milliseconds to wait before failing (default: `60000`). */
694
+ timeout?: number;
695
+ };
696
+
697
+ /** Interface configuration options shared by Netplan and networkd builders. */
698
+ type InterfaceOptions = {
699
+ addresses?: string[];
700
+ dhcp?: boolean;
701
+ gateway?: string;
702
+ nameservers?: string[];
703
+ };
704
+ /**
705
+ * Modules for managing network configuration on the remote host.
706
+ */
707
+ declare const net: {
708
+ /**
709
+ * Manage entries in /etc/hosts.
710
+ *
711
+ * @param ip - The IP address for the hosts entry.
712
+ * @param hostnames - One or more hostnames to associate with the IP.
713
+ * @param options - Optional settings.
714
+ * @param options.state - Whether the entry should be "present" (default) or "absent".
715
+ * @returns A Module that manages the hosts entry.
716
+ */
717
+ hosts(ip: string, hostnames: string[], options?: {
718
+ state?: "absent" | "present";
719
+ }): Module;
720
+ /**
721
+ * Configure a network interface via Netplan (when available) or systemd-networkd.
722
+ *
723
+ * @param name - The interface name (e.g. "eth0").
724
+ * @param options - Network configuration options.
725
+ * @returns A Module that manages the interface configuration.
726
+ */
727
+ interface(name: string, options: InterfaceOptions): Module;
728
+ /**
729
+ * Check that an HTTP endpoint returns the expected status code and/or body.
730
+ *
731
+ * @param url - The URL to request.
732
+ * @param options - Optional request settings.
733
+ * @param options.body - Expected string in the response body.
734
+ * @param options.headers - Additional HTTP headers.
735
+ * @param options.method - HTTP method (default: `"GET"`).
736
+ * @param options.status - Expected HTTP status code (default: `200`).
737
+ * @returns A Module that checks the HTTP endpoint.
738
+ */
739
+ request(url: string, options?: {
740
+ body?: string;
741
+ headers?: Record<string, string>;
742
+ method?: string;
743
+ status?: number;
744
+ }): Module;
745
+ /**
746
+ * Manage /etc/resolv.conf (nameservers and search domains).
747
+ *
748
+ * @param options - Resolver configuration.
749
+ * @param options.nameservers - List of nameserver IP addresses.
750
+ * @param options.search - Optional list of DNS search domains.
751
+ * @returns A Module that manages /etc/resolv.conf.
752
+ */
753
+ resolv(options: {
754
+ nameservers: string[];
755
+ search?: string[];
756
+ }): Module;
757
+ /**
758
+ * Manage persistent static routes via `ip route` and a systemd-networkd drop-in.
759
+ *
760
+ * @param destination - The route destination (e.g. "10.0.0.0/24").
761
+ * @param gateway - The gateway IP address.
762
+ * @param options - Optional settings.
763
+ * @param options.device - The network device to use (e.g. "eth0").
764
+ * @param options.state - Whether the route should be "present" (default) or "absent".
765
+ * @returns A Module that manages the static route.
766
+ */
767
+ route(destination: string, gateway: string, options?: {
768
+ device?: string;
769
+ state?: "absent" | "present";
770
+ }): Module;
771
+ /**
772
+ * Wait for a condition to become true on the remote host.
773
+ *
774
+ * @param options - Wait condition and timing options.
775
+ * @returns A Module that waits for the condition.
776
+ */
777
+ waitFor(options: WaitForOptions): Module;
778
+ };
779
+
780
+ /**
781
+ * Modules for resolving secrets from 1Password on the local controller.
782
+ */
783
+ declare const op: {
784
+ /**
785
+ * Resolve 1Password secret references into environment values.
786
+ *
787
+ * Regular references are resolved in bulk via `op inject`.
788
+ * References ending in `/one-time-password` or `/otp` are resolved individually
789
+ * via `op read` and returned as lazy functions that compute a fresh TOTP code
790
+ * on each call.
791
+ *
792
+ * This module runs locally (`local: true`) and never touches the remote host.
793
+ * `check` always returns `"needs-apply"` so the runner executes `apply`
794
+ * unconditionally and propagates the resolved meta values.
795
+ * If any CLI call fails the module returns `{ status: "failed", error }`.
796
+ *
797
+ * @param references - A map of logical names to 1Password secret references
798
+ * (e.g. `op://vault/item/field`). References ending in `/one-time-password`
799
+ * or `/otp` are treated as TOTP sources.
800
+ * @returns A Module that resolves the references and emits them as meta values.
801
+ *
802
+ * @example
803
+ * ```ts
804
+ * op.resolve({
805
+ * DB_PASSWORD: "op://prod/database/password",
806
+ * API_TOKEN: "op://prod/api/credential",
807
+ * MFA_CODE: "op://prod/authenticator/one-time-password",
808
+ * })
809
+ * ```
810
+ */
811
+ resolve(references: Record<string, string>): Module;
812
+ };
813
+
814
+ /**
815
+ * Distro-agnostic package management module.
816
+ *
817
+ * Automatically detects the system package manager (apt, dnf, yum, apk)
818
+ * and delegates to the appropriate commands. All methods are idempotent.
819
+ *
820
+ * For Debian/Ubuntu-specific configuration (debconf pre-seeding, GPG keys,
821
+ * apt repositories) use the `apt` module instead.
822
+ *
823
+ * @example
824
+ * // Install packages
825
+ * pkg.installed("git", "curl")
826
+ *
827
+ * @example
828
+ * // Refresh package lists and upgrade all packages on a specific date
829
+ * pkg.update("2024-01-15")
830
+ * pkg.upgrade("2024-01-15")
831
+ */
832
+ declare const pkg: {
833
+ /**
834
+ * Ensure the given packages are not installed.
835
+ *
836
+ * The check phase queries the package database for each package individually;
837
+ * the remove command is only executed when at least one package is present.
838
+ *
839
+ * @param packages - One or more package names to remove.
840
+ * @returns A Module that removes the packages if any are present.
841
+ *
842
+ * @example
843
+ * pkg.absent("vim", "nano")
844
+ */
845
+ absent(...packages: string[]): Module;
846
+ /**
847
+ * Ensure the given packages are installed.
848
+ *
849
+ * The check phase queries the package database for each package individually;
850
+ * the install command is only executed when at least one package is missing.
851
+ *
852
+ * @param packages - One or more package names to install.
853
+ * @returns A Module that installs missing packages.
854
+ *
855
+ * @example
856
+ * pkg.installed("git", "curl", "unzip")
857
+ */
858
+ installed(...packages: string[]): Module;
859
+ /**
860
+ * Refresh the package manager's package lists once per dated flag.
861
+ *
862
+ * A flag file at `${FLAGS_DIRECTORY}/package-update-<date>` is created after
863
+ * a successful run. On the next run the flag is detected and the module
864
+ * reports `"ok"` without running the update again. Changing `date` to a new
865
+ * value invalidates all previous flags for this operation.
866
+ *
867
+ * @param date - A date string used as the idempotency key (e.g. `"2024-01-15"`).
868
+ * @returns A Module that refreshes package lists.
869
+ *
870
+ * @example
871
+ * pkg.update("2024-01-15")
872
+ */
873
+ update(date: string): Module;
874
+ /**
875
+ * Upgrade all installed packages once per dated flag.
876
+ *
877
+ * A flag file at `${FLAGS_DIRECTORY}/package-upgrade-<date>` is created after
878
+ * a successful run. On the next run the flag is detected and the module
879
+ * reports `"ok"` without running the upgrade again. Changing `date` to a new
880
+ * value invalidates all previous flags for this operation.
881
+ *
882
+ * On apt systems this runs `apt-get update && apt-get upgrade -y` (not
883
+ * `dist-upgrade`); use `apt.distUpgrade` for full dependency resolution.
884
+ *
885
+ * @param date - A date string used as the idempotency key (e.g. `"2024-01-15"`).
886
+ * @returns A Module that upgrades all packages.
887
+ *
888
+ * @example
889
+ * pkg.upgrade("2024-01-15")
890
+ *
891
+ * @see apt.distUpgrade
892
+ */
893
+ upgrade(date: string): Module;
894
+ };
895
+
896
+ type QuadletAutoUpdate = "local" | "registry";
897
+ type QuadletRestartPolicy = "always" | "no" | "on-abnormal" | "on-abort" | "on-failure" | "on-success" | "on-watchdog";
898
+ type QuadletContainerOptions = {
899
+ autoUpdate?: QuadletAutoUpdate;
900
+ containerName?: string;
901
+ description?: string;
902
+ environment?: Record<string, string>;
903
+ exec?: string[];
904
+ image: string;
905
+ name: string;
906
+ networks?: string[];
907
+ podmanArgs?: string[];
908
+ publishPorts?: string[];
909
+ restart?: QuadletRestartPolicy;
910
+ volumes?: string[];
911
+ wantedBy?: string;
912
+ };
913
+ /**
914
+ * Modules for managing Podman Quadlet definitions.
915
+ *
916
+ * The first V1 method writes `.container` files under `/etc/containers/systemd`
917
+ * and reloads systemd when content changes. Resulting services can be managed
918
+ * via the regular `service.*(...)` modules.
919
+ */
920
+ declare const quadlet: {
921
+ /**
922
+ * Write a Podman Quadlet `.container` definition and reload systemd when it changes.
923
+ *
924
+ * The resulting generated service can be controlled with `service.enabled(name)`
925
+ * and `service.running(name)`.
926
+ *
927
+ * @param options - Configuration for the Quadlet container definition.
928
+ * @param options.name - Quadlet base name without `.container`.
929
+ * @param options.image - Container image reference.
930
+ * @param options.description - Optional systemd unit description.
931
+ * @param options.containerName - Optional explicit Podman container name.
932
+ * @param options.autoUpdate - Optional Podman auto-update policy.
933
+ * @param options.environment - Optional environment variables.
934
+ * @param options.exec - Optional command and arguments for `Exec=`.
935
+ * @param options.networks - Optional `Network=` entries.
936
+ * @param options.podmanArgs - Optional `PodmanArgs=` entries.
937
+ * @param options.publishPorts - Optional `PublishPort=` entries.
938
+ * @param options.restart - Optional `Restart=` policy in the `[Container]` section.
939
+ * @param options.volumes - Optional `Volume=` entries.
940
+ * @param options.wantedBy - Optional install target. Defaults to `multi-user.target`.
941
+ * @returns A Module that ensures the Quadlet file is present and up to date.
942
+ */
943
+ container(options: QuadletContainerOptions): Module;
944
+ };
945
+
946
+ /**
947
+ * Options for the {@link releaseUpgrade.upgrade} module.
948
+ */
949
+ type ReleaseUpgradeOptions = {
950
+ /**
951
+ * When `true`, only check whether an upgrade is available without applying
952
+ * any changes. The module returns `"ok"` regardless of what is found.
953
+ */
954
+ dryRun?: boolean;
955
+ /**
956
+ * Optional async function to resolve the new host address after the
957
+ * post-upgrade reboot. Useful when the server's IP address may change
958
+ * (e.g. DHCP or cloud environments). The resolved value is emitted as
959
+ * `system.host` meta so the runner can reconnect to the correct address.
960
+ */
961
+ resolveHost?: () => Promise<string>;
962
+ };
963
+ /**
964
+ * Modules for upgrading the operating system to the next major release.
965
+ *
966
+ * Supports Ubuntu (via `do-release-upgrade`) and Debian (via sources.list
967
+ * rewrite + `apt-get full-upgrade`). After a successful upgrade the module
968
+ * signals the runner to reboot and optionally reconnect to a new host address
969
+ * via the `system.reboot` / `system.host` meta keys.
970
+ */
971
+ declare const releaseUpgrade: {
972
+ /**
973
+ * Upgrade the remote host to the next major OS release.
974
+ *
975
+ * The distribution is auto-detected from `/etc/os-release`. Ubuntu hosts
976
+ * are upgraded with `do-release-upgrade`; Debian hosts are upgraded by
977
+ * rewriting apt sources to the current stable suite and running
978
+ * `apt-get full-upgrade`.
979
+ *
980
+ * The `check` phase returns `"needs-apply"` when an upgrade is available
981
+ * (Ubuntu: `do-release-upgrade -c` exits 0; Debian: current codename differs
982
+ * from stable codename) and `"ok"` when the host is already up to date.
983
+ *
984
+ * @param options - Optional settings.
985
+ * @param options.dryRun - When `true`, only inspect whether an upgrade is
986
+ * available without modifying the system.
987
+ * @param options.resolveHost - Async callback invoked after the upgrade to
988
+ * determine the new host address before the runner reconnects.
989
+ * @returns A Module that performs the OS release upgrade.
990
+ *
991
+ * @example
992
+ * // Simple upgrade — auto-detect distro and apply
993
+ * releaseUpgrade.upgrade()
994
+ *
995
+ * @example
996
+ * // Dry-run: check availability without making changes
997
+ * releaseUpgrade.upgrade({ dryRun: true })
998
+ *
999
+ * @example
1000
+ * // Resolve the new host address after reboot (e.g. dynamic DNS or DHCP)
1001
+ * releaseUpgrade.upgrade({
1002
+ * resolveHost: async () => {
1003
+ * const ip = await myDns.resolve("my-server.example.com")
1004
+ * return ip
1005
+ * },
1006
+ * })
1007
+ */
1008
+ upgrade(options?: ReleaseUpgradeOptions): Module;
1009
+ };
1010
+
1011
+ type SyncOptions = {
1012
+ /** Permission mode applied via `--chmod`, e.g. `"Du=rwx,go=rx,Fu=rw,go=r"`. */
1013
+ chmod?: string;
1014
+ /** Remove files on the remote that are absent from the source (`--delete`). */
1015
+ delete?: boolean;
1016
+ /** Absolute destination path on the remote host. */
1017
+ dest: string;
1018
+ /** Patterns passed to rsync `--exclude` in order, applied after includes. */
1019
+ exclude?: string[];
1020
+ /** Group name for `--chown`; defaults to `owner` when only `owner` is set. */
1021
+ group?: string;
1022
+ /** Patterns passed to rsync `--include` in order, applied before excludes. */
1023
+ include?: string[];
1024
+ /** Owner name for `--chown`. */
1025
+ owner?: string;
1026
+ /** Local source path (file or directory) to synchronize. */
1027
+ src: string;
1028
+ /**
1029
+ * SSH `StrictHostKeyChecking` option passed to the `-o` flag.
1030
+ *
1031
+ * Defaults to `"yes"`. Use `"accept-new"` for explicit TOFU when first-time
1032
+ * connections must be auto-accepted, or `"no"` to disable checking entirely
1033
+ * (not recommended for production).
1034
+ */
1035
+ strictHostKeyChecking?: "accept-new" | "no" | "off" | "yes";
1036
+ };
1037
+ /**
1038
+ * Modules for synchronizing files to a remote host using rsync.
1039
+ */
1040
+ declare const rsync: {
1041
+ /**
1042
+ * Synchronize a local path to a remote destination using rsync over SSH.
1043
+ *
1044
+ * The `check` phase runs rsync with `--dry-run` and reports `needs-apply`
1045
+ * when the itemized output is non-empty. The `apply` phase returns
1046
+ * `"changed"` when rsync reports transferred items, or `"ok"` when the
1047
+ * destination was already in sync.
1048
+ *
1049
+ * @param options - Sync configuration including source, destination, and optional filters.
1050
+ * @returns A Module that manages the rsync synchronization.
1051
+ *
1052
+ * @example
1053
+ * ```ts
1054
+ * rsync.sync({
1055
+ * src: "./dist/",
1056
+ * dest: "/var/www/app",
1057
+ * delete: true,
1058
+ * exclude: ["*.map"],
1059
+ * owner: "www-data",
1060
+ * })
1061
+ * ```
1062
+ *
1063
+ * @example Enforce strict host-key checking for a host that is already known:
1064
+ * ```ts
1065
+ * rsync.sync({
1066
+ * src: "./dist/",
1067
+ * dest: "/var/www/app",
1068
+ * strictHostKeyChecking: "yes",
1069
+ * })
1070
+ * ```
1071
+ */
1072
+ sync(options: SyncOptions): Module;
1073
+ };
1074
+
1075
+ /**
1076
+ * Modules for executing scripts on the remote host.
1077
+ */
1078
+ declare const script: {
1079
+ /**
1080
+ * Upload and run a local script on the remote host exactly once.
1081
+ * Idempotency is tracked via a versioned flag file; bumping the version
1082
+ * causes the script to run again.
1083
+ *
1084
+ * @param name - A unique identifier for this script execution (alphanumeric, dots, hyphens, underscores).
1085
+ * @param localPath - Path to the script on the local filesystem.
1086
+ * @param options - Optional settings.
1087
+ * @param options.args - Arguments to pass to the script (each element is shell-quoted).
1088
+ * @param options.version - Version string for the flag file (default: `"1"`).
1089
+ * @returns A Module that manages the one-time script execution.
1090
+ */
1091
+ once(name: string, localPath: string, options?: {
1092
+ args?: string[];
1093
+ version?: string;
1094
+ }): Module;
1095
+ };
1096
+
1097
+ /**
1098
+ * Modules for managing systemd services.
1099
+ *
1100
+ * State-checking methods (`running`, `stopped`, `enabled`, `disabled`) are
1101
+ * idempotent. Signal-style methods (`restart`, `reload`) always apply.
1102
+ */
1103
+ declare const service: {
1104
+ /**
1105
+ * Ensure a systemd service is disabled and will not start on boot.
1106
+ * @param name - The systemd unit name.
1107
+ * @returns A Module that ensures the service is disabled.
1108
+ */
1109
+ disabled(name: string): Module;
1110
+ /**
1111
+ * Ensure a systemd service is enabled to start on boot.
1112
+ * @param name - The systemd unit name.
1113
+ * @returns A Module that ensures the service is enabled.
1114
+ */
1115
+ enabled(name: string): Module;
1116
+ /**
1117
+ * Collect status information for all systemd services and expose them as
1118
+ * meta entries. Does not change anything on the server.
1119
+ * @returns A Module that gathers service facts into `service.<name>` meta keys.
1120
+ */
1121
+ facts(): Module;
1122
+ /**
1123
+ * Reload a systemd service. Intended as a recipe signal -- always applies.
1124
+ * @param name - The systemd unit name.
1125
+ * @returns A Module that reloads the service.
1126
+ */
1127
+ reload(name: string): Module;
1128
+ /**
1129
+ * Restart a systemd service. Intended as a recipe signal -- always applies.
1130
+ * @param name - The systemd unit name.
1131
+ * @returns A Module that restarts the service.
1132
+ */
1133
+ restart(name: string): Module;
1134
+ /**
1135
+ * Ensure a systemd service is running. Starts the service if inactive.
1136
+ * @param name - The systemd unit name (e.g. `"nginx"`).
1137
+ * @returns A Module that ensures the service is running.
1138
+ */
1139
+ running(name: string): Module;
1140
+ /**
1141
+ * Ensure a systemd service is stopped. Stops the service if active.
1142
+ * @param name - The systemd unit name.
1143
+ * @returns A Module that ensures the service is stopped.
1144
+ */
1145
+ stopped(name: string): Module;
1146
+ };
1147
+
1148
+ type KnownHostsOptions = {
1149
+ expectedFingerprint?: string;
1150
+ port?: number;
1151
+ publicKey?: string;
1152
+ state?: "absent" | "present";
1153
+ };
1154
+ /**
1155
+ * Modules for managing SSH client-side resources such as known hosts
1156
+ * and authorized keys.
1157
+ */
1158
+ declare const ssh: {
1159
+ /**
1160
+ * Ensure a public key is present in (or absent from) a user's `authorized_keys` file.
1161
+ *
1162
+ * When `state` is `"present"` (the default), the key is appended if missing and the
1163
+ * `.ssh` directory and `authorized_keys` file are created with correct ownership
1164
+ * and permissions. When `state` is `"absent"`, the matching line is removed.
1165
+ *
1166
+ * @param user - The target user whose `authorized_keys` file is managed.
1167
+ * @param key - The full public key string (e.g. `"ssh-ed25519 AAAA... comment"`).
1168
+ * @param options - Optional settings.
1169
+ * @param options.state - Whether the key should be `"present"` or `"absent"`. Defaults to `"present"`.
1170
+ * @returns A Module that manages the authorized key entry.
1171
+ */
1172
+ authorizedKeys(user: string, key: string, options?: {
1173
+ state?: "absent" | "present";
1174
+ }): Module;
1175
+ /**
1176
+ * Ensure a host is present in (or absent from) the connecting user's `~/.ssh/known_hosts`.
1177
+ *
1178
+ * When `state` is `"present"` (the default), the host's public keys are fetched
1179
+ * via `ssh-keyscan` and appended to `~/.ssh/known_hosts`. When `state` is
1180
+ * `"absent"`, the host entry is removed via `ssh-keygen -R`.
1181
+ *
1182
+ * @param host - The hostname or IP address to manage.
1183
+ * @param options - Optional settings.
1184
+ * @param options.state - Whether the host should be `"present"` or `"absent"`. Defaults to `"present"`.
1185
+ * @returns A Module that manages the known hosts entry.
1186
+ */
1187
+ knownHosts(host: string, options?: KnownHostsOptions): Module;
1188
+ };
1189
+
1190
+ /**
1191
+ * Modules for managing the OpenSSH daemon configuration (`/etc/ssh/sshd_config`).
1192
+ * All methods restart or reload `sshd` after applying changes.
1193
+ */
1194
+ declare const sshd: {
1195
+ /**
1196
+ * Apply one or more key-value settings to `sshd_config`.
1197
+ * Existing directives are updated in-place; missing directives are appended.
1198
+ *
1199
+ * @param settings - A map of sshd_config directive names to their desired values
1200
+ * (e.g. `{ PasswordAuthentication: "no" }`).
1201
+ * @returns A Module that applies the sshd configuration settings.
1202
+ */
1203
+ config(settings: Record<string, string>): Module;
1204
+ /**
1205
+ * Set the SSH daemon listen port.
1206
+ * Updates the `Port` directive in `sshd_config` and restarts `sshd`.
1207
+ * The new port is exported as `sshd.port` in the module result meta so
1208
+ * the runner can reconnect on the updated port.
1209
+ *
1210
+ * @param targetPort - The port number sshd should listen on.
1211
+ * @returns A Module that sets the sshd listen port.
1212
+ */
1213
+ port(targetPort: number): Module;
1214
+ };
1215
+
1216
+ /**
1217
+ * Modules for managing kernel parameters via sysctl on the remote host.
1218
+ */
1219
+ declare const sysctl: {
1220
+ /**
1221
+ * Set a sysctl kernel parameter and persist it across reboots.
1222
+ *
1223
+ * The live value is applied immediately via `sysctl -w` and a configuration
1224
+ * file is written to `/etc/sysctl.d/99-paratix-<sanitized-key>.conf` for
1225
+ * persistence.
1226
+ *
1227
+ * When `state` is `"absent"`, the persistence file is removed but the live
1228
+ * value is not reverted (a reboot will restore the default).
1229
+ *
1230
+ * @param key - The sysctl key (e.g. "net.ipv4.ip_forward").
1231
+ * @param value - The desired value (e.g. "1").
1232
+ * @param options - Optional settings.
1233
+ * @param options.state - Whether the parameter should be "present" (default) or "absent".
1234
+ * @returns A Module that manages the sysctl parameter.
1235
+ */
1236
+ set(key: string, value: string, options?: {
1237
+ state?: "absent" | "present";
1238
+ }): Module;
1239
+ };
1240
+
1241
+ /**
1242
+ * Options for the reboot module.
1243
+ */
1244
+ type RebootOptions = {
1245
+ /**
1246
+ * Optional async function to resolve the new host address after a reboot.
1247
+ * Useful when the server's IP address may change (e.g. DHCP or cloud environments).
1248
+ */
1249
+ resolveHost?: () => Promise<string>;
1250
+ };
1251
+ /**
1252
+ * Modules for managing system-level operations.
1253
+ */
1254
+ declare const system: {
1255
+ /**
1256
+ * Collect system facts (OS, architecture, hostname, kernel, RAM, CPU, IPs, disk).
1257
+ * Always applies because it is informational and should always report.
1258
+ *
1259
+ * All gathered values are emitted as `system.*` meta keys.
1260
+ *
1261
+ * @returns A Module that collects system facts.
1262
+ */
1263
+ facts(): Module;
1264
+ /**
1265
+ * Reboot the remote system via `shutdown -r now`.
1266
+ * Always applies because a reboot is an imperative action.
1267
+ *
1268
+ * When `resolveHost` is provided, the resolved address is emitted as
1269
+ * `system.host` meta so the runner can update the SSH connection.
1270
+ * The `system.reboot` meta signal is always set to `"true"`.
1271
+ *
1272
+ * @param options - Optional settings including a host resolver.
1273
+ * @returns A Module that reboots the system.
1274
+ */
1275
+ reboot(options?: RebootOptions): Module;
1276
+ /**
1277
+ * Read the system uptime in seconds from `/proc/uptime`.
1278
+ * Always applies because it is informational and should always report.
1279
+ *
1280
+ * The uptime value is emitted as `system.uptime` meta.
1281
+ *
1282
+ * @returns A Module that reads the system uptime.
1283
+ */
1284
+ uptime(): Module;
1285
+ };
1286
+
1287
+ /**
1288
+ * Modules for managing systemd unit files and unit masking.
1289
+ *
1290
+ * The `unit` method writes unit files with idempotent checks and triggers a daemon-reload
1291
+ * on change. `masked` and `unmasked` control unit masking state.
1292
+ * `daemonReload` is a signal-style method that always applies.
1293
+ */
1294
+ declare const systemd: {
1295
+ /**
1296
+ * Reload the systemd manager configuration. Intended as a recipe signal --
1297
+ * always applies.
1298
+ * @returns A Module that runs `systemctl daemon-reload`.
1299
+ */
1300
+ daemonReload(): Module;
1301
+ /**
1302
+ * Ensure a systemd unit is masked and cannot be started.
1303
+ * @param name - The systemd unit name (e.g. `"apt-daily.timer"`).
1304
+ * @returns A Module that ensures the unit is masked.
1305
+ */
1306
+ masked(name: string): Module;
1307
+ /**
1308
+ * Write a systemd unit file to `/etc/systemd/system/` and reload the
1309
+ * daemon configuration when the content changes.
1310
+ *
1311
+ * The check phase compares the remote file content with the desired
1312
+ * content string. Apply writes the file and runs `systemctl daemon-reload`.
1313
+ *
1314
+ * @param name - Unit file name (e.g. `"my-app.service"` or `"backup.timer"`).
1315
+ * @param content - The full unit file content.
1316
+ * @returns A Module that ensures the unit file is present with the given content.
1317
+ */
1318
+ unit(name: string, content: string): Module;
1319
+ /**
1320
+ * Ensure a systemd unit is unmasked and can be started normally.
1321
+ * @param name - The systemd unit name (e.g. `"apt-daily.timer"`).
1322
+ * @returns A Module that ensures the unit is unmasked.
1323
+ */
1324
+ unmasked(name: string): Module;
1325
+ };
1326
+
1327
+ /**
1328
+ * Modules for managing the UFW (Uncomplicated Firewall) on Debian/Ubuntu hosts.
1329
+ */
1330
+ declare const ufw: {
1331
+ /**
1332
+ * Ensure UFW is inactive. If UFW is not installed, this is treated as already satisfied.
1333
+ *
1334
+ * @returns A Module that ensures UFW is disabled.
1335
+ */
1336
+ disabled(): Module;
1337
+ /**
1338
+ * Ensure UFW is active. Enables the firewall non-interactively if not already running.
1339
+ *
1340
+ * @returns A Module that ensures UFW is enabled.
1341
+ */
1342
+ enabled(): Module;
1343
+ /**
1344
+ * Add an allow or deny rule for one or more ports.
1345
+ * The check phase reads `ufw status` and verifies the expected rule is present.
1346
+ *
1347
+ * @param action - Whether to `"allow"` or `"deny"` traffic on the given ports.
1348
+ * @param ports - A single port number or an array of port numbers.
1349
+ * @returns A Module that manages UFW rules.
1350
+ */
1351
+ rule(action: "allow" | "deny", ports: number | number[]): Module;
1352
+ };
1353
+
1354
+ type UserOptions = {
1355
+ groups?: string[];
1356
+ home?: string;
1357
+ password?: string;
1358
+ shell?: string;
1359
+ uid?: number;
1360
+ };
1361
+ /**
1362
+ * Modules for managing Linux user accounts.
1363
+ */
1364
+ declare const user: {
1365
+ /**
1366
+ * Ensure a user account does not exist. Removes the account via `userdel`.
1367
+ *
1368
+ * @param name - The username to remove.
1369
+ * @param options - Optional removal configuration.
1370
+ * @param options.removeHome - When `true`, also delete the user's home directory.
1371
+ * @returns A Module that ensures the user account is absent.
1372
+ */
1373
+ absent(name: string, options?: {
1374
+ removeHome?: boolean;
1375
+ }): Module;
1376
+ /**
1377
+ * Ensure a user account exists. Creates the account if absent, or runs
1378
+ * `usermod` to update attributes if the user already exists.
1379
+ *
1380
+ * @param name - The username.
1381
+ * @param options - Optional user account configuration.
1382
+ * @param options.uid - Desired numeric UID.
1383
+ * @param options.shell - Login shell path (e.g. `"/bin/bash"`).
1384
+ * @param options.home - Home directory path.
1385
+ * @param options.groups - Supplementary groups to add the user to.
1386
+ * @param options.password - Pre-hashed password (e.g. SHA-512 `$6$...`) set via `chpasswd -e`.
1387
+ * @returns A Module that ensures the user account is present.
1388
+ */
1389
+ present(name: string, options?: UserOptions): Module;
1390
+ };
1391
+
1392
+ export { apt as a, archive as b, command as c, compose as d, cron as e, download as f, file as g, git as h, group as i, hostname as j, rsync as k, service as l, mount as m, net as n, op as o, pkg as p, quadlet as q, releaseUpgrade as r, script as s, ssh as t, sshd as u, sysctl as v, system as w, systemd as x, ufw as y, user as z };