@dovocode/workstation 0.1.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 +75 -0
- package/dist/cli.js +42891 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +525 -0
- package/dist/index.js +1318 -0
- package/dist/index.js.map +1 -0
- package/package.json +59 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
type Platform = "darwin" | "linux";
|
|
2
|
+
type PackageManager = "mise" | "brew" | "brew-cask" | "apt" | "system";
|
|
3
|
+
/** Homebrew cask upgrade behavior. */
|
|
4
|
+
interface BrewCaskUpgradeOptions {
|
|
5
|
+
/** Include auto-updating casks and refresh their lock pins on each run. */
|
|
6
|
+
readonly greedy?: boolean;
|
|
7
|
+
/** Pass --force when upgrading a cask; does not by itself trigger an upgrade. */
|
|
8
|
+
readonly force?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/** Machine and path information passed to a configuration factory. */
|
|
11
|
+
interface Context {
|
|
12
|
+
/** Short hostname by default, or the exact `--machine` override. */
|
|
13
|
+
readonly machine: string;
|
|
14
|
+
/** Full operating-system hostname. */
|
|
15
|
+
readonly hostname: string;
|
|
16
|
+
/** Operating system detected on the executing machine. */
|
|
17
|
+
readonly platform: Platform;
|
|
18
|
+
/** Absolute home directory of the executing user. */
|
|
19
|
+
readonly home: string;
|
|
20
|
+
/** Absolute directory of the TypeScript entry point; imported fragments share this base. */
|
|
21
|
+
readonly configDir: string;
|
|
22
|
+
}
|
|
23
|
+
interface PackageResource {
|
|
24
|
+
readonly kind: "package";
|
|
25
|
+
readonly manager: PackageManager;
|
|
26
|
+
readonly name: string;
|
|
27
|
+
readonly version?: string;
|
|
28
|
+
readonly upgrade?: BrewCaskUpgradeOptions;
|
|
29
|
+
}
|
|
30
|
+
interface ResolvedPackageResource extends PackageResource {
|
|
31
|
+
/** Concrete version resolved into workstation.lock. */
|
|
32
|
+
readonly lockedVersion?: string;
|
|
33
|
+
}
|
|
34
|
+
interface SymlinkResource {
|
|
35
|
+
readonly kind: "symlink";
|
|
36
|
+
readonly source: string;
|
|
37
|
+
readonly target: string;
|
|
38
|
+
}
|
|
39
|
+
interface LaunchAgentResource {
|
|
40
|
+
readonly kind: "launch-agent";
|
|
41
|
+
readonly label: string;
|
|
42
|
+
readonly program: string;
|
|
43
|
+
readonly args?: readonly string[];
|
|
44
|
+
readonly environment?: Readonly<Record<string, string>>;
|
|
45
|
+
readonly runAtLoad?: boolean;
|
|
46
|
+
readonly keepAlive?: boolean;
|
|
47
|
+
readonly stdoutPath?: string;
|
|
48
|
+
readonly stderrPath?: string;
|
|
49
|
+
}
|
|
50
|
+
type StructuredFormat = "toml" | "yaml" | "json" | "jsonc" | "zsh" | "bash";
|
|
51
|
+
/** `overwrite` saves and replaces unmanaged files; `update` rejects unmanaged differences; `ignore` preserves existing targets. */
|
|
52
|
+
type IfExistsPolicy = "update" | "overwrite" | "ignore";
|
|
53
|
+
type ConfigValue = string | number | boolean | null | readonly ConfigValue[] | Readonly<{
|
|
54
|
+
[key: string]: ConfigValue;
|
|
55
|
+
}>;
|
|
56
|
+
interface GeneratedFileResource {
|
|
57
|
+
/** Pre-rendered JSONC from the typed builder. Used only with format jsonc. */
|
|
58
|
+
readonly renderedContent?: string;
|
|
59
|
+
readonly kind: "generated-file";
|
|
60
|
+
readonly target: string;
|
|
61
|
+
readonly format: StructuredFormat;
|
|
62
|
+
readonly value: ConfigValue;
|
|
63
|
+
readonly ifExists: IfExistsPolicy;
|
|
64
|
+
readonly mode?: number;
|
|
65
|
+
}
|
|
66
|
+
type SystemdScope = "user" | "system";
|
|
67
|
+
interface SystemdServiceResource {
|
|
68
|
+
readonly kind: "systemd-service";
|
|
69
|
+
readonly name: string;
|
|
70
|
+
readonly description?: string;
|
|
71
|
+
readonly program: string;
|
|
72
|
+
readonly args?: readonly string[];
|
|
73
|
+
readonly environment?: Readonly<Record<string, string>>;
|
|
74
|
+
readonly restart?: "no" | "on-failure" | "always";
|
|
75
|
+
readonly wantedBy?: string;
|
|
76
|
+
readonly scope: SystemdScope;
|
|
77
|
+
}
|
|
78
|
+
/** Run a program directly, without an implicit shell. Custom builds expand {source}, {output}, and {target}. */
|
|
79
|
+
interface CommandSpec {
|
|
80
|
+
readonly command: string;
|
|
81
|
+
readonly args?: readonly string[];
|
|
82
|
+
readonly cwd?: string;
|
|
83
|
+
readonly environment?: Readonly<Record<string, string>>;
|
|
84
|
+
}
|
|
85
|
+
/** A named direct command with a description shown by --list-tasks. */
|
|
86
|
+
interface TaskDefinition extends CommandSpec {
|
|
87
|
+
readonly description?: string;
|
|
88
|
+
}
|
|
89
|
+
interface CustomToolResource {
|
|
90
|
+
readonly kind: "custom-tool";
|
|
91
|
+
readonly name: string;
|
|
92
|
+
readonly source: string;
|
|
93
|
+
readonly sourceHash?: string;
|
|
94
|
+
readonly target: string;
|
|
95
|
+
readonly build: CommandSpec;
|
|
96
|
+
}
|
|
97
|
+
type Resource = PackageResource | SymlinkResource | LaunchAgentResource | GeneratedFileResource | SystemdServiceResource | CustomToolResource;
|
|
98
|
+
/** One resource or nested arrays. False, null, and undefined are ignored. */
|
|
99
|
+
type ResourceInput = Resource | readonly ResourceInput[] | false | null | undefined;
|
|
100
|
+
/** A composable configuration fragment. Prefer the exported helpers to constructing resources manually. */
|
|
101
|
+
interface ConfigDefinition {
|
|
102
|
+
/** Named commands executed explicitly with workstation <task>. */
|
|
103
|
+
readonly tasks?: Readonly<Record<string, TaskDefinition>>;
|
|
104
|
+
/** Alternate task names; alias chains are supported and cycles rejected. */
|
|
105
|
+
readonly aliases?: Readonly<Record<string, string>>;
|
|
106
|
+
/** Default package manager for tools.system on each platform. */
|
|
107
|
+
readonly managers?: Partial<Record<Platform, Exclude<PackageManager, "system">>>;
|
|
108
|
+
/** Shared resource declarations, evaluated in order. */
|
|
109
|
+
readonly resources?: ResourceInput;
|
|
110
|
+
/** Additional resources keyed by exact machine name. */
|
|
111
|
+
readonly machines?: Readonly<Record<string, ResourceInput>>;
|
|
112
|
+
/** Local ownership/backup state path. Defaults to ~/.local/state/workstation/state.json; do not commit it. */
|
|
113
|
+
readonly stateFile?: string;
|
|
114
|
+
}
|
|
115
|
+
/** A fragment, factory, or nested array of fragments; absent fragments are ignored. */
|
|
116
|
+
type ConfigInput = ConfigDefinition | ConfigFactory | readonly ConfigInput[] | false | null | undefined;
|
|
117
|
+
/** Compute a configuration fragment using the current machine context. */
|
|
118
|
+
type ConfigFactory = (context: Context) => ConfigInput;
|
|
119
|
+
/** Accepted default export from workstation.config.ts. */
|
|
120
|
+
type WorkstationConfig = ConfigInput;
|
|
121
|
+
interface ResolvedConfig {
|
|
122
|
+
readonly tasks?: Readonly<Record<string, TaskDefinition>>;
|
|
123
|
+
readonly aliases?: Readonly<Record<string, string>>;
|
|
124
|
+
readonly context: Context;
|
|
125
|
+
readonly resources: readonly ResolvedResource[];
|
|
126
|
+
readonly stateFile: string;
|
|
127
|
+
}
|
|
128
|
+
type ResolvedResource = ResolvedPackageResource | Exclude<Resource, PackageResource>;
|
|
129
|
+
type OriginalFile = {
|
|
130
|
+
readonly kind: "file";
|
|
131
|
+
readonly content: string;
|
|
132
|
+
readonly mode: number;
|
|
133
|
+
} | {
|
|
134
|
+
readonly kind: "symlink";
|
|
135
|
+
readonly target: string;
|
|
136
|
+
};
|
|
137
|
+
interface StateEntry {
|
|
138
|
+
readonly id: string;
|
|
139
|
+
readonly fingerprint: string;
|
|
140
|
+
readonly owned: boolean;
|
|
141
|
+
readonly resource: ResolvedResource;
|
|
142
|
+
readonly installedVersion?: string;
|
|
143
|
+
readonly installedHash?: string;
|
|
144
|
+
readonly originalFile?: OriginalFile;
|
|
145
|
+
}
|
|
146
|
+
interface WorkstationState {
|
|
147
|
+
readonly version: 1;
|
|
148
|
+
readonly machine: string;
|
|
149
|
+
readonly resources: Readonly<Record<string, StateEntry>>;
|
|
150
|
+
}
|
|
151
|
+
type ActionType = "create" | "adopt" | "update" | "remove" | "forget";
|
|
152
|
+
interface Action {
|
|
153
|
+
readonly type: ActionType;
|
|
154
|
+
readonly id: string;
|
|
155
|
+
readonly resource: ResolvedResource;
|
|
156
|
+
readonly previous?: StateEntry;
|
|
157
|
+
readonly reason: string;
|
|
158
|
+
}
|
|
159
|
+
interface CommandResult {
|
|
160
|
+
readonly exitCode: number;
|
|
161
|
+
readonly stdout: string;
|
|
162
|
+
readonly stderr: string;
|
|
163
|
+
}
|
|
164
|
+
/** Command execution boundary, replaceable in tests or embedded integrations. */
|
|
165
|
+
interface Runner {
|
|
166
|
+
/** Execute a command directly and return captured output and its exit code; spawn failures reject. */
|
|
167
|
+
run(command: string, args: readonly string[], options?: RunOptions): Promise<CommandResult>;
|
|
168
|
+
}
|
|
169
|
+
interface RunOptions {
|
|
170
|
+
readonly cwd?: string;
|
|
171
|
+
readonly environment?: Readonly<Record<string, string>>;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** A JSONC value with comments, ready to pass to files.jsonc. */
|
|
175
|
+
declare class JsoncDocument {
|
|
176
|
+
readonly content: string;
|
|
177
|
+
/** Store the rendered document text; callers construct documents through the builder commands. */
|
|
178
|
+
private constructor();
|
|
179
|
+
/** @internal Build from typed commands; arbitrary unvalidated JSONC is not accepted. */
|
|
180
|
+
static from(lines: readonly JsoncLine[]): JsoncDocument;
|
|
181
|
+
}
|
|
182
|
+
/** One JSONC builder instruction. Prefer the jsonc helpers to constructing instructions manually. */
|
|
183
|
+
type JsoncCommand = {
|
|
184
|
+
readonly kind: "comment";
|
|
185
|
+
readonly text: string;
|
|
186
|
+
} | {
|
|
187
|
+
readonly kind: "blank";
|
|
188
|
+
} | {
|
|
189
|
+
readonly kind: "value";
|
|
190
|
+
readonly content: string;
|
|
191
|
+
} | {
|
|
192
|
+
readonly kind: "property";
|
|
193
|
+
readonly name: string;
|
|
194
|
+
readonly content: string;
|
|
195
|
+
};
|
|
196
|
+
/** A builder command or nested group. Absent/disabled groups are ignored. */
|
|
197
|
+
type JsoncLine = JsoncCommand | JsoncDocument | readonly JsoncLine[] | false | null | undefined;
|
|
198
|
+
/** Compose JSONC line by line with comments; punctuation and escaping are generated. */
|
|
199
|
+
declare const jsonc: {
|
|
200
|
+
/** Join a document's comments and single root value, separating commands by newlines.
|
|
201
|
+
* @example jsonc.concat(jsonc.comment("Editor settings"), jsonc.object([jsonc.property("theme", "dark")]))
|
|
202
|
+
*/
|
|
203
|
+
concat(...lines: readonly JsoncLine[]): JsoncDocument;
|
|
204
|
+
/** Add a // comment. Each line of multiline text receives its own comment prefix. */
|
|
205
|
+
comment(text: string): JsoncCommand;
|
|
206
|
+
/** Insert an intentional empty line. */
|
|
207
|
+
blank(): JsoncCommand;
|
|
208
|
+
/** Add an object property. Values may be ordinary JSON data or a nested JSONC document. */
|
|
209
|
+
property(name: string, value: ConfigValue | JsoncDocument): JsoncCommand;
|
|
210
|
+
/** Add a JSON value, for example an array element or a primitive document root. */
|
|
211
|
+
value(value: ConfigValue | JsoncDocument): JsoncCommand;
|
|
212
|
+
/** Build an object from properties, comments, blank lines, and optional groups. */
|
|
213
|
+
object(lines: readonly JsoncLine[]): JsoncDocument;
|
|
214
|
+
/** Build an array from values, comments, blank lines, and optional groups. */
|
|
215
|
+
array(lines: readonly JsoncLine[]): JsoncDocument;
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
/** Declare a task command; arguments are passed directly without a shell.
|
|
219
|
+
* @example tasks: { test: task("pnpm", ["test"], { description: "Run tests" }) }
|
|
220
|
+
*/
|
|
221
|
+
declare function task(command: string, args?: readonly string[], options?: Omit<TaskDefinition, "command" | "args">): TaskDefinition;
|
|
222
|
+
|
|
223
|
+
/** Run one explicit task or alias, appending CLI arguments without shell interpolation. */
|
|
224
|
+
declare function runTask(config: ResolvedConfig, name: string, args: readonly string[], runner: Runner): Promise<CommandResult>;
|
|
225
|
+
|
|
226
|
+
/** Declare packages; installation happens when the Workstation CLI runs. */
|
|
227
|
+
declare const tools: {
|
|
228
|
+
/**
|
|
229
|
+
* Install mise tools. A list requests `latest`; a map accepts version selectors.
|
|
230
|
+
* @example tools.mise({ node: "lts", go: "1.27" })
|
|
231
|
+
*/
|
|
232
|
+
mise: (packages: readonly string[] | Readonly<Record<string, string>>) => PackageResource[];
|
|
233
|
+
/** Install Homebrew formulae (command-line packages). */
|
|
234
|
+
brew: (packages: readonly string[]) => PackageResource[];
|
|
235
|
+
/**
|
|
236
|
+
* Install macOS applications. Greedy casks refresh their lock pin each run.
|
|
237
|
+
* @example tools.brewCask(["ghostty"], { greedy: true, force: true })
|
|
238
|
+
*/
|
|
239
|
+
brewCask: (packages: readonly string[], upgrade?: BrewCaskUpgradeOptions) => PackageResource[];
|
|
240
|
+
/** Install Debian/Ubuntu packages through APT. Mutations request sudo. */
|
|
241
|
+
apt: (packages: readonly string[]) => PackageResource[];
|
|
242
|
+
/** Use the configured platform manager; defaults to Homebrew on macOS and APT on Linux. */
|
|
243
|
+
system: (packages: readonly string[]) => PackageResource[];
|
|
244
|
+
};
|
|
245
|
+
/**
|
|
246
|
+
* Link a config-relative source to a home-relative target. Absolute paths are supported.
|
|
247
|
+
* @example symlink("dotfiles/gitconfig", "~/.gitconfig")
|
|
248
|
+
*/
|
|
249
|
+
declare function symlink(source: string, target: string): SymlinkResource;
|
|
250
|
+
/**
|
|
251
|
+
* Declare a macOS user LaunchAgent. Use inside `darwin(...)`.
|
|
252
|
+
* @param label Unique launchd label, for example `dev.example.worker`.
|
|
253
|
+
*/
|
|
254
|
+
declare function launchAgent(label: string, options: Omit<LaunchAgentResource, "kind" | "label">): LaunchAgentResource;
|
|
255
|
+
/** Control how a generated file replaces existing content and its Unix permissions. */
|
|
256
|
+
interface GeneratedFileOptions {
|
|
257
|
+
/** Existing-file policy. Defaults to `overwrite`, with the original saved for restoration. */
|
|
258
|
+
readonly ifExists?: IfExistsPolicy;
|
|
259
|
+
/** Unix permissions as an octal number. Defaults to `0o644`; use `0o600` for private files. */
|
|
260
|
+
readonly mode?: number;
|
|
261
|
+
}
|
|
262
|
+
/** Generate structured files from ordinary TypeScript values. Targets resolve relative to home. */
|
|
263
|
+
declare const files: {
|
|
264
|
+
/**
|
|
265
|
+
* Generate TOML. Values must be representable in TOML (for example, no null).
|
|
266
|
+
* @example files.toml("~/.config/app/config.toml", { server: { port: 3000 } })
|
|
267
|
+
*/
|
|
268
|
+
toml: (target: string, value: ConfigValue, options?: GeneratedFileOptions) => GeneratedFileResource;
|
|
269
|
+
/** Generate YAML with the standard overwrite/restore policy. */
|
|
270
|
+
yaml: (target: string, value: ConfigValue, options?: GeneratedFileOptions) => GeneratedFileResource;
|
|
271
|
+
/**
|
|
272
|
+
* Generate formatted JSON.
|
|
273
|
+
* @example files.json("~/.config/app/config.json", { enabled: true })
|
|
274
|
+
*/
|
|
275
|
+
json: (target: string, value: ConfigValue, options?: GeneratedFileOptions) => GeneratedFileResource;
|
|
276
|
+
/** Generate JSONC from plain data or jsonc.concat/object commands with comments. */
|
|
277
|
+
jsonc: (target: string, value: ConfigValue | JsoncDocument, options?: GeneratedFileOptions) => GeneratedFileResource;
|
|
278
|
+
};
|
|
279
|
+
/**
|
|
280
|
+
* Declare a Linux systemd service. Defaults to user scope; system scope uses sudo.
|
|
281
|
+
* Use inside `linux(...)`. The `.service` suffix is added when omitted.
|
|
282
|
+
*/
|
|
283
|
+
declare function systemdService(name: string, options: Omit<SystemdServiceResource, "kind" | "name" | "scope"> & {
|
|
284
|
+
readonly scope?: SystemdServiceResource["scope"];
|
|
285
|
+
}): SystemdServiceResource;
|
|
286
|
+
/**
|
|
287
|
+
* Build a local source tree into an executable. Source changes trigger a rebuild.
|
|
288
|
+
* The build must write `{output}`; `{source}` and `{target}` are also available in arguments.
|
|
289
|
+
* @example customTool("hello", { source: "tools/hello", target: "~/.local/bin/hello", build: { command: "go", args: ["build", "-o", "{output}", "{source}"] } })
|
|
290
|
+
*/
|
|
291
|
+
declare function customTool(name: string, options: Omit<CustomToolResource, "kind" | "name" | "sourceHash">): CustomToolResource;
|
|
292
|
+
/** Include resources when a TypeScript condition is true. For config fragments, use platform/machine helpers. */
|
|
293
|
+
declare function when(condition: boolean, resources: ResourceInput): ResourceInput;
|
|
294
|
+
/**
|
|
295
|
+
* Define an entry point or imported fragment. Arrays and factories compose; false, null and undefined are ignored.
|
|
296
|
+
* Later declarations with the same resource ID win.
|
|
297
|
+
* @example export default defineConfig({ resources: [tools.mise({ node: "lts" })] })
|
|
298
|
+
*/
|
|
299
|
+
declare function defineConfig(config: WorkstationConfig): WorkstationConfig;
|
|
300
|
+
/** Define a configuration factory with typed access to machine, platform, home, and configDir. */
|
|
301
|
+
declare function configure(factory: ConfigFactory): ConfigFactory;
|
|
302
|
+
/**
|
|
303
|
+
* Include a configuration fragment only on macOS.
|
|
304
|
+
* @example defineConfig([common, darwin(macos)])
|
|
305
|
+
*/
|
|
306
|
+
declare function darwin(config: ConfigInput): ConfigFactory;
|
|
307
|
+
/** Include a configuration fragment only on Linux. */
|
|
308
|
+
declare function linux(config: ConfigInput): ConfigFactory;
|
|
309
|
+
/**
|
|
310
|
+
* Include a fragment for one or more exact machine names. Defaults to the short hostname; `--machine` overrides it.
|
|
311
|
+
* @example machine(["studio", "macbook"], sharedMacConfig)
|
|
312
|
+
*/
|
|
313
|
+
declare function machine(names: string | readonly string[], config: ConfigInput): ConfigFactory;
|
|
314
|
+
|
|
315
|
+
/** Supported shell rendering targets. */
|
|
316
|
+
type Shell = "zsh" | "bash";
|
|
317
|
+
/** A value expanded when the generated shell file runs, rather than during configuration loading. */
|
|
318
|
+
type ShellExpression = {
|
|
319
|
+
readonly kind: "variable";
|
|
320
|
+
readonly name: string;
|
|
321
|
+
} | {
|
|
322
|
+
readonly kind: "home";
|
|
323
|
+
readonly path: string;
|
|
324
|
+
} | {
|
|
325
|
+
readonly kind: "concat";
|
|
326
|
+
readonly values: readonly ShellValue[];
|
|
327
|
+
} | {
|
|
328
|
+
readonly kind: "capture";
|
|
329
|
+
readonly command: ShellCommand;
|
|
330
|
+
};
|
|
331
|
+
/** Plain strings are quoted literals. Use `shell.variable`, `shell.home`, or `shell.capture` for expansion. */
|
|
332
|
+
type ShellValue = string | ShellExpression;
|
|
333
|
+
/** A command plus individually quoted arguments; it is not executed while declaring configuration. */
|
|
334
|
+
interface ShellCommand {
|
|
335
|
+
readonly command: string;
|
|
336
|
+
readonly args?: readonly ShellValue[];
|
|
337
|
+
readonly stderr?: "inherit" | "ignore";
|
|
338
|
+
}
|
|
339
|
+
/** A condition evaluated by the generated shell script. */
|
|
340
|
+
type ShellCondition = {
|
|
341
|
+
readonly kind: "command-exists";
|
|
342
|
+
readonly command: string;
|
|
343
|
+
} | {
|
|
344
|
+
readonly kind: "executable" | "file" | "directory";
|
|
345
|
+
readonly path: ShellValue;
|
|
346
|
+
} | {
|
|
347
|
+
readonly kind: "empty" | "non-empty";
|
|
348
|
+
readonly value: ShellValue;
|
|
349
|
+
} | {
|
|
350
|
+
readonly kind: "and";
|
|
351
|
+
readonly conditions: readonly ShellCondition[];
|
|
352
|
+
} | {
|
|
353
|
+
readonly kind: "or";
|
|
354
|
+
readonly conditions: readonly ShellCondition[];
|
|
355
|
+
} | {
|
|
356
|
+
readonly kind: "not";
|
|
357
|
+
readonly condition: ShellCondition;
|
|
358
|
+
};
|
|
359
|
+
/** A statement in the portable Zsh/Bash declaration language. */
|
|
360
|
+
type ShellStatement = {
|
|
361
|
+
readonly kind: "export";
|
|
362
|
+
readonly name: string;
|
|
363
|
+
readonly value: ShellValue;
|
|
364
|
+
} | {
|
|
365
|
+
readonly kind: "assign";
|
|
366
|
+
readonly name: string;
|
|
367
|
+
readonly value: ShellValue;
|
|
368
|
+
} | {
|
|
369
|
+
readonly kind: "unset";
|
|
370
|
+
readonly names: readonly string[];
|
|
371
|
+
} | {
|
|
372
|
+
readonly kind: "prepend-path";
|
|
373
|
+
readonly values: readonly ShellValue[];
|
|
374
|
+
} | {
|
|
375
|
+
readonly kind: "alias";
|
|
376
|
+
readonly name: string;
|
|
377
|
+
readonly command: string;
|
|
378
|
+
} | {
|
|
379
|
+
readonly kind: "eval";
|
|
380
|
+
readonly command: ShellCommand;
|
|
381
|
+
} | {
|
|
382
|
+
readonly kind: "source";
|
|
383
|
+
readonly path: ShellValue;
|
|
384
|
+
readonly ifExists: boolean;
|
|
385
|
+
} | {
|
|
386
|
+
readonly kind: "if";
|
|
387
|
+
readonly condition: ShellCondition;
|
|
388
|
+
readonly statements: readonly ShellStatement[];
|
|
389
|
+
} | {
|
|
390
|
+
readonly kind: "zsh-setopt";
|
|
391
|
+
readonly options: readonly string[];
|
|
392
|
+
} | {
|
|
393
|
+
readonly kind: "raw";
|
|
394
|
+
readonly code: string;
|
|
395
|
+
};
|
|
396
|
+
/** Generated startup-file options. Defaults to overwrite and mode `0o644`. */
|
|
397
|
+
interface ShellFileOptions {
|
|
398
|
+
/** Defaults to overwrite; replaced originals are saved in local state for restoration. */
|
|
399
|
+
readonly ifExists?: IfExistsPolicy;
|
|
400
|
+
/** Unix permissions, for example `0o600`. */
|
|
401
|
+
readonly mode?: number;
|
|
402
|
+
}
|
|
403
|
+
/** Build shell statements without hand-written quoting. Helpers describe code; they do not execute commands. */
|
|
404
|
+
declare const shell: {
|
|
405
|
+
/**
|
|
406
|
+
* Reference a shell variable at runtime.
|
|
407
|
+
* @example shell.export("VISUAL", shell.variable("EDITOR"))
|
|
408
|
+
*/
|
|
409
|
+
variable(name: string): ShellExpression;
|
|
410
|
+
/**
|
|
411
|
+
* Expand a path under the shell's HOME at runtime.
|
|
412
|
+
* @example shell.home(".local/bin")
|
|
413
|
+
*/
|
|
414
|
+
home(path?: string): ShellExpression;
|
|
415
|
+
/** Join literals and expressions into one shell value. */
|
|
416
|
+
concat(...values: readonly ShellValue[]): ShellExpression;
|
|
417
|
+
/** Use a command's stdout as a value via command substitution. */
|
|
418
|
+
capture(command: ShellCommand): ShellExpression;
|
|
419
|
+
/** Describe a command and its arguments. Use `capture` for its output or `eval` for initialization code. */
|
|
420
|
+
command(command: string, args?: readonly ShellValue[], options?: Pick<ShellCommand, "stderr">): ShellCommand;
|
|
421
|
+
/** Set and export an environment variable. */
|
|
422
|
+
export(name: string, value: ShellValue): ShellStatement;
|
|
423
|
+
/** Set a shell variable without exporting it. */
|
|
424
|
+
assign(name: string, value: ShellValue): ShellStatement;
|
|
425
|
+
/** Remove one or more shell variables. */
|
|
426
|
+
unset(...names: readonly string[]): ShellStatement;
|
|
427
|
+
/**
|
|
428
|
+
* Prepend paths while retaining the current PATH.
|
|
429
|
+
* @example shell.prependPath(shell.home(".local/bin"))
|
|
430
|
+
*/
|
|
431
|
+
prependPath(...values: readonly ShellValue[]): ShellStatement;
|
|
432
|
+
/** Define an alias; its command text is interpreted when the alias runs. */
|
|
433
|
+
alias(name: string, command: string): ShellStatement;
|
|
434
|
+
/**
|
|
435
|
+
* Evaluate shell code printed by a command.
|
|
436
|
+
* @example shell.eval(shell.command("mise", ["activate", "zsh"]))
|
|
437
|
+
*/
|
|
438
|
+
eval(command: ShellCommand): ShellStatement;
|
|
439
|
+
/** Source another shell file. With `ifExists: true`, source only when readable. */
|
|
440
|
+
source(path: ShellValue, options?: {
|
|
441
|
+
readonly ifExists?: boolean;
|
|
442
|
+
}): ShellStatement;
|
|
443
|
+
/** Generate a shell-time conditional containing one or more statements. */
|
|
444
|
+
when(condition: ShellCondition, statements: readonly ShellStatement[]): ShellStatement;
|
|
445
|
+
/** Insert literal shell code without validation or quoting. Prefer typed helpers for ordinary statements. */
|
|
446
|
+
raw(code: string): ShellStatement;
|
|
447
|
+
/** Construct conditions evaluated when the shell starts. */
|
|
448
|
+
condition: {
|
|
449
|
+
/** Test whether a command is available on PATH. */
|
|
450
|
+
commandExists(command: string): ShellCondition;
|
|
451
|
+
/** Test whether a path is executable. */
|
|
452
|
+
executable(path: ShellValue): ShellCondition;
|
|
453
|
+
/** Test whether a path is a regular file. */
|
|
454
|
+
file(path: ShellValue): ShellCondition;
|
|
455
|
+
/** Test whether a path is a directory. */
|
|
456
|
+
directory(path: ShellValue): ShellCondition;
|
|
457
|
+
/** Test whether a value is empty. */
|
|
458
|
+
empty(value: ShellValue): ShellCondition;
|
|
459
|
+
/** Test whether a value is non-empty. */
|
|
460
|
+
nonEmpty(value: ShellValue): ShellCondition;
|
|
461
|
+
/** Combine conditions with shell AND. */
|
|
462
|
+
and(...conditions: readonly ShellCondition[]): ShellCondition;
|
|
463
|
+
/** Combine conditions with shell OR. */
|
|
464
|
+
or(...conditions: readonly ShellCondition[]): ShellCondition;
|
|
465
|
+
/** Negate a condition. */
|
|
466
|
+
not(condition: ShellCondition): ShellCondition;
|
|
467
|
+
};
|
|
468
|
+
};
|
|
469
|
+
/** Declare independent Zsh startup files. Each defaults to overwrite with original-file restoration. */
|
|
470
|
+
declare const zsh: {
|
|
471
|
+
/** Generate ~/.zshenv, read by every Zsh invocation. Keep this minimal. */
|
|
472
|
+
zshenv: (statements: readonly ShellStatement[], options?: ShellFileOptions) => GeneratedFileResource;
|
|
473
|
+
/** Generate ~/.zprofile for login-shell environment initialization. */
|
|
474
|
+
zprofile: (statements: readonly ShellStatement[], options?: ShellFileOptions) => GeneratedFileResource;
|
|
475
|
+
/** Generate ~/.zshrc for interactive aliases, prompts, and completion. */
|
|
476
|
+
zshrc: (statements: readonly ShellStatement[], options?: ShellFileOptions) => GeneratedFileResource;
|
|
477
|
+
/** Enable Zsh-only options using uppercase names. Cannot be rendered to Bash. */
|
|
478
|
+
setopt(...options: readonly string[]): ShellStatement;
|
|
479
|
+
};
|
|
480
|
+
/** Declare Bash startup files. Bash login shells read the first available profile file. */
|
|
481
|
+
declare const bash: {
|
|
482
|
+
/** Generate ~/.bashrc for interactive non-login shells. */
|
|
483
|
+
bashrc: (statements: readonly ShellStatement[], options?: ShellFileOptions) => GeneratedFileResource;
|
|
484
|
+
/** Generate ~/.bash_profile for Bash login shells; source ~/.bashrc explicitly if desired. */
|
|
485
|
+
bashProfile: (statements: readonly ShellStatement[], options?: ShellFileOptions) => GeneratedFileResource;
|
|
486
|
+
/** Generate ~/.profile using Bash syntax; use only where Bash will read it. */
|
|
487
|
+
profile: (statements: readonly ShellStatement[], options?: ShellFileOptions) => GeneratedFileResource;
|
|
488
|
+
};
|
|
489
|
+
/** Render statements to shell text without writing a file or running a command. */
|
|
490
|
+
declare function renderShell(statements: readonly ShellStatement[], target: Shell): string;
|
|
491
|
+
|
|
492
|
+
/** Stable ownership key. File-like resources share their destination as an identity. */
|
|
493
|
+
declare function resourceId(resource: ResolvedResource): string;
|
|
494
|
+
/** SHA-256 of a declaration with object keys ordered consistently. Array order remains meaningful. */
|
|
495
|
+
declare function fingerprint(resource: ResolvedResource): string;
|
|
496
|
+
|
|
497
|
+
/** Resolve an explicit entry path, or find workstation.config.ts in the current directory. */
|
|
498
|
+
declare function findConfig(explicit?: string): Promise<string>;
|
|
499
|
+
/** Load an absolute TypeScript entry path, evaluate fragments, and resolve paths without applying resources. */
|
|
500
|
+
declare function loadConfig(configPath: string, machineOverride?: string): Promise<ResolvedConfig>;
|
|
501
|
+
|
|
502
|
+
/** Return the resolved config.toml path beside the private ownership state. */
|
|
503
|
+
declare function manifestPath(config: ResolvedConfig): string;
|
|
504
|
+
/** Write resolved declarations atomically as a private TOML manifest. */
|
|
505
|
+
declare function writeManifest(path: string, config: ResolvedConfig): Promise<void>;
|
|
506
|
+
/** Read and validate a resolved manifest; reject unsupported schema versions. */
|
|
507
|
+
declare function readManifest(path: string): Promise<ResolvedConfig>;
|
|
508
|
+
|
|
509
|
+
interface LockedConfigResult {
|
|
510
|
+
readonly config: ResolvedConfig;
|
|
511
|
+
readonly path: string;
|
|
512
|
+
readonly changed: boolean;
|
|
513
|
+
}
|
|
514
|
+
/** Return the workstation.lock path beside the TypeScript entry point. */
|
|
515
|
+
declare function lockPath(configPath: string): string;
|
|
516
|
+
/** Resolve package pins and update the current machine's lock target; does not install resources. */
|
|
517
|
+
declare function lockConfig(configPath: string, config: ResolvedConfig, runner: Runner): Promise<LockedConfigResult>;
|
|
518
|
+
|
|
519
|
+
/** Run child processes directly, inheriting stdin and capturing stdout/stderr. No implicit shell is used. */
|
|
520
|
+
declare class ProcessRunner implements Runner {
|
|
521
|
+
/** Execute a command directly and return captured output and its exit code; spawn failures reject. */
|
|
522
|
+
run(command: string, args: readonly string[], options?: RunOptions): Promise<CommandResult>;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
export { type Action, type ActionType, type BrewCaskUpgradeOptions, type CommandResult, type CommandSpec, type ConfigDefinition, type ConfigFactory, type ConfigInput, type ConfigValue, type Context, type CustomToolResource, type GeneratedFileOptions, type GeneratedFileResource, type IfExistsPolicy, type JsoncCommand, JsoncDocument, type JsoncLine, type LaunchAgentResource, type LockedConfigResult, type OriginalFile, type PackageManager, type PackageResource, type Platform, ProcessRunner, type ResolvedConfig, type ResolvedPackageResource, type ResolvedResource, type Resource, type ResourceInput, type RunOptions, type Runner, type Shell, type ShellCommand, type ShellCondition, type ShellExpression, type ShellFileOptions, type ShellStatement, type ShellValue, type StateEntry, type StructuredFormat, type SymlinkResource, type SystemdScope, type SystemdServiceResource, type TaskDefinition, type WorkstationConfig, type WorkstationState, bash, configure, customTool, darwin, defineConfig, files, findConfig, fingerprint, jsonc, launchAgent, linux, loadConfig, lockConfig, lockPath, machine, manifestPath, readManifest, renderShell, resourceId, runTask, shell, symlink, systemdService, task, tools, when, writeManifest, zsh };
|