@gamecrate/cli 1.0.0 → 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.
@@ -18,6 +18,15 @@ export declare const Exit: {
18
18
  readonly Interrupted: 130;
19
19
  };
20
20
  export type ExitCode = (typeof Exit)[keyof typeof Exit];
21
+ export type ExitReason = 'exited' | 'marker' | 'marker-timeout' | 'stopped' | 'window-closed' | 'timeout'
22
+ /** The run never reached docker: staging, a pull or a build failed. */
23
+ | 'failed';
24
+ export interface LaunchResult {
25
+ code: number;
26
+ reason: ExitReason;
27
+ }
28
+ /** 130 means runContainer caught a signal and stopped the container, not that the game died. */
29
+ export declare function reasonFor(code: number): ExitReason;
21
30
  /** Every failure the tool raises deliberately. Anything else is a bug. */
22
31
  export declare class GamecrateError extends Error {
23
32
  readonly code: ExitCode;
@@ -26,7 +35,7 @@ export declare class GamecrateError extends Error {
26
35
  }
27
36
  /** Collected and reported together, so one run surfaces every problem at once. */
28
37
  export interface Problem {
29
- /** JSON Pointer into profiles.json, or a file path, or a mod id. */
38
+ /** JSON Pointer into the global config, or a file path, or a mod id. */
30
39
  where: string;
31
40
  message: string;
32
41
  /** Populated by did-you-mean matching where it applies. */
@@ -101,6 +110,11 @@ export interface ScanRoot {
101
110
  export interface LibraryEntry {
102
111
  workshop?: number;
103
112
  path?: string;
113
+ git?: string;
114
+ branch?: string;
115
+ tag?: string;
116
+ commit?: string;
117
+ subdir?: string;
104
118
  }
105
119
  /** Matches a family of mods by pattern instead of naming each one. */
106
120
  export interface DynamicModEntry {
@@ -138,6 +152,12 @@ export interface ProfileConfig {
138
152
  alias?: string;
139
153
  /** Extra names this profile answers to, so one entry covers several spellings. */
140
154
  aliases?: string[];
155
+ /** A one-line note for `gamecrate list`. Never read by the launcher. */
156
+ description?: string;
157
+ /** Launch defaults for this profile. The matching --no-* flag overrides each one. */
158
+ detach?: boolean;
159
+ replace?: boolean;
160
+ build?: BuildPolicy;
141
161
  }
142
162
  export interface GameConfig {
143
163
  gameFiles: GameFilesSpec;
@@ -220,6 +240,11 @@ export interface ModRecord {
220
240
  };
221
241
  /** Which scanRoot produced it, for the precedence ladder. */
222
242
  rootIndex: number;
243
+ /**
244
+ * The clone directory's mtime. Source-cache records only, which is what keeps it from
245
+ * reordering a user's checkout against anything.
246
+ */
247
+ clonedAt?: number;
223
248
  }
224
249
  export type WorktreeSource = 'flag' | 'env' | 'cwd' | 'ref';
225
250
  export interface WorktreeRequest {
@@ -381,9 +406,52 @@ export interface ParsedArgs {
381
406
  noStaleCheck: boolean;
382
407
  /** Stops whatever holds this profile+instance, then launches. Never refuses. */
383
408
  replace: boolean;
409
+ /** Runs in the background: this process forks a supervisor and returns the prompt. */
410
+ detach: boolean;
411
+ /** One-run overrides. Only these turn the matching boolean back off. */
412
+ noDetach: boolean;
413
+ noReplace: boolean;
414
+ /** Set on the forked supervisor only. Never a config key, never in help. */
415
+ supervised: boolean;
416
+ /** `-f`: keep printing as the run writes, instead of dumping what is there. */
417
+ follow: boolean;
418
+ /** The write verb under `mods`. Unset means the read verb. */
419
+ subverb?: 'add' | 'rm' | 'sync';
420
+ /** Where `mods add` pulls the mod from. */
421
+ source?: {
422
+ kind: 'path';
423
+ value: string;
424
+ } | {
425
+ kind: 'workshop';
426
+ value: number;
427
+ } | {
428
+ kind: 'git';
429
+ url: string;
430
+ ref?: {
431
+ kind: 'branch' | 'tag' | 'commit';
432
+ value: string;
433
+ };
434
+ subdir?: string;
435
+ };
436
+ /** Which config file a write lands in. */
437
+ target?: 'global' | 'project';
438
+ /** Overwrite an existing entry instead of refusing. */
439
+ force?: boolean;
384
440
  rest: string[];
385
441
  }
386
- export type ProjectDefaults = Partial<Omit<ParsedArgs, 'subcommand' | 'cleanTier' | 'yes' | 'help' | 'rest'>>;
442
+ export type ProjectDefaults = Partial<Omit<ParsedArgs, 'subcommand' | 'cleanTier' | 'yes' | 'help' | 'rest' | 'profile' | 'supervised' | 'noDetach' | 'noReplace' | 'follow' | 'subverb' | 'source' | 'target' | 'force'>> & {
443
+ /** Replaces the old `profile:` key. Falls back to the first entry in `profiles`. */
444
+ defaultProfile?: string;
445
+ /** Validated by validateConfig after the splice, not here. */
446
+ profiles?: Record<string, unknown>;
447
+ settings?: Record<string, unknown>;
448
+ /** Spliced per id over games.<game>.library, so a repo pin replaces a global one whole. */
449
+ library?: Record<string, unknown>;
450
+ /** Profile keys in source order. Object.keys sorts integer-like names to the front. */
451
+ profileOrder?: string[];
452
+ /** The file these came from. Four suffixes are legal, so output must not guess the name. */
453
+ configPath?: string;
454
+ };
387
455
  /** Names that can never be a game or profile key. Enforced at config load. */
388
456
  export declare const RESERVED_NAMES: readonly string[];
389
457
  export declare const NAME_PATTERN: RegExp;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gamecrate/cli",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "Run a modded game in a container, with mods resolved from your local checkouts.",
5
5
  "license": "MIT",
6
6
  "type": "module",