@penvhq/cli 0.3.2 → 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.
package/dist/index.d.cts CHANGED
@@ -1,14 +1,15 @@
1
1
  import * as citty from 'citty';
2
- import { Sink, Provider, ParameterRef, Scope, RotationMechanism, RotationState } from '@penvhq/core';
2
+ import { ProjectionProvider, Provider, ParameterRef, Scope, AnyProvider, RotationMechanism, RotationState } from '@penvhq/core';
3
3
 
4
4
  /**
5
5
  * A check reports one of four verdicts. `unknown` — a check that ran but could
6
6
  * not reach a verdict — is never rendered as a pass: "I looked and found nothing
7
7
  * wrong" and "I could not look" are opposite situations with opposite remedies,
8
- * and a write-only sink makes most of what doctor can say the second kind.
8
+ * and a value-withholding destination makes most of what doctor can say the
9
+ * second kind.
9
10
  */
10
11
  type DoctorSeverity = "pass" | "warning" | "failure" | "unknown";
11
- type DoctorCheck = "schema" | "missing" | "declared" | "weak" | "unused" | "unscoped-fallback" | "plaintext-secret" | "public-secret" | "encryption" | "rotation-overdue" | "rotation-stuck" | "provider-value-drift" | "provider" | "sink-unreachable" | "sink-name-drift" | "sink-manual-edit" | "sink-value-drift";
12
+ type DoctorCheck = "schema" | "missing" | "declared" | "weak" | "unused" | "unscoped-fallback" | "plaintext-secret" | "public-secret" | "encryption" | "rotation-overdue" | "rotation-stuck" | "provider-value-drift" | "provider" | "projection-unreachable" | "projection-name-drift" | "projection-manual-edit" | "projection-value-drift" | "environment-flag-shadow";
12
13
  interface DoctorFinding {
13
14
  readonly check: DoctorCheck;
14
15
  readonly severity: DoctorSeverity;
@@ -27,13 +28,15 @@ interface DoctorReport {
27
28
  interface DoctorOptions {
28
29
  readonly cwd: string;
29
30
  readonly environment?: string;
30
- /** Injected in tests: the sink to check against. Defaults to the one the config declares. */
31
- readonly sink?: Sink;
31
+ /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */
32
+ readonly envFlags?: readonly string[];
33
+ /** Injected in tests: the projection-holding destination to check against. Defaults to the one the config declares. */
34
+ readonly projection?: ProjectionProvider;
32
35
  /**
33
36
  * Injected in tests: the source-of-truth provider to compare the local tree
34
37
  * against. Defaults to the one the config declares (`sourceProviderFor`).
35
- * Mirrors `sink`, for the same reason — the drift checks stay driveable without
36
- * a live backend.
38
+ * Mirrors `projection`, for the same reason — the drift checks stay driveable
39
+ * without a live backend.
37
40
  */
38
41
  readonly source?: Provider;
39
42
  /** Injected in tests: the wall-clock reading the rotation clocks are read against. Defaults to now. */
@@ -97,6 +100,12 @@ declare function runDecrypt(options: ResealOptions): Promise<ResealResult>;
97
100
  * A value is never invented: a blank answer skips the parameter, because the
98
101
  * silent value reaching runtime is the failure penv exists to delete, and a
99
102
  * placeholder written here is exactly that value by a friendlier route.
103
+ *
104
+ * Optional parameters — `.optional()`, `.default()` — are asked too, after the
105
+ * required gaps, tagged so the reader knows an answer is an override and Enter
106
+ * keeps what the schema declared. Skipping them silently was the old behavior,
107
+ * and it hid a real choice: a schema default reaching runtime is legal, but the
108
+ * user who never heard the question never chose it.
100
109
  */
101
110
  /** One question `fill` puts to the user: which parameter, in which environment. */
102
111
  interface FillPrompt {
@@ -108,11 +117,21 @@ interface FillPrompt {
108
117
  * v1 does not, and the drift carries no meta, so this is `false` today.
109
118
  */
110
119
  readonly secret: boolean;
120
+ /**
121
+ * Whether the schema excuses absence — `.optional()`, `.default()`. An answer
122
+ * writes an override; a blank one leaves the schema's own behavior in place,
123
+ * which is a kept default rather than a lingering gap.
124
+ */
125
+ readonly optional: boolean;
126
+ /** What the schema falls back to, rendered for display, when it declares one penv can read. */
127
+ readonly defaultValue?: string;
111
128
  readonly description?: string;
112
129
  }
113
130
  interface FillOptions {
114
131
  readonly cwd: string;
115
132
  readonly environment?: string;
133
+ /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */
134
+ readonly envFlags?: readonly string[];
116
135
  /**
117
136
  * How a value is obtained for one prompt. `undefined` or an empty answer skips
118
137
  * the parameter — the readline half lives only in the wrapper, so `runFill`
@@ -131,6 +150,12 @@ interface FillResult {
131
150
  }>;
132
151
  /** The parameters a blank answer left for later — never written as an empty value. */
133
152
  readonly skipped: readonly string[];
153
+ /**
154
+ * The optional parameters a blank answer left to the schema. Not `skipped`:
155
+ * a skipped parameter is still a gap, and one of these is a decision — the
156
+ * schema's default (or declared absence) is the value, on purpose.
157
+ */
158
+ readonly kept: readonly string[];
134
159
  /**
135
160
  * The declared keys no filename reaches (`apiURL`, a reserved token). `fill`
136
161
  * cannot ask for a value it could never write, so it carries the rename remedy
@@ -156,6 +181,8 @@ declare function renderFill(result: FillResult): string[];
156
181
  interface GenerateOptions {
157
182
  readonly cwd: string;
158
183
  readonly environment?: string;
184
+ /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */
185
+ readonly envFlags?: readonly string[];
159
186
  /** Where to write, absolute or relative to `cwd`. Defaults to `.env` at the project root. */
160
187
  readonly out?: string;
161
188
  /** Permits sealed values to be written into the artifact as plaintext. */
@@ -335,14 +362,34 @@ interface UndeclaredDrift {
335
362
  /** The generated variable, which is the name the application would have read. */
336
363
  readonly variable: string;
337
364
  }
365
+ /**
366
+ * A parameter the schema declares but does not require — `.optional()`,
367
+ * `.default()`, and their kin — that the tree has no value for. Not drift in the
368
+ * verdict sense: absence here is a state the schema itself blessed, so `doctor`
369
+ * and `watch` say nothing about it. It is measured for `fill`, whose reader is
370
+ * deciding what to write, and for whom "the schema would take an override here"
371
+ * is exactly the kind of fact a silent skip would hide.
372
+ */
373
+ interface OptionalDrift {
374
+ /** The parameter id, or the dotted schema path when no filename could reach it. */
375
+ readonly subject: string;
376
+ /** Absent when no filename reaches this key — an override `penv set` cannot write. */
377
+ readonly ref?: ParameterRef;
378
+ /** What the schema falls back to, rendered for display, when it declares one this module can read. */
379
+ readonly defaultValue?: string;
380
+ /** The rename that must precede any override, for the key no filename reaches. */
381
+ readonly remedy: string;
382
+ }
338
383
  /**
339
384
  * The distance between `.penv/env.ts` and the tree, in both directions. Named
340
385
  * `declared`/`undeclared` for the side that has it, not for a verdict: neither
341
- * direction is by itself an error, and only `validate` decides that.
386
+ * direction is by itself an error, and only `validate` decides that. `optional`
387
+ * is the deliberately verdict-free third list — see {@link OptionalDrift}.
342
388
  */
343
389
  interface DriftReport {
344
390
  readonly declared: readonly DeclaredDrift[];
345
391
  readonly undeclared: readonly UndeclaredDrift[];
392
+ readonly optional: readonly OptionalDrift[];
346
393
  }
347
394
 
348
395
  type ValidateIssueKind = "config" | "reserved" | "collision" | "schema" | "undecryptable";
@@ -370,6 +417,8 @@ interface ValidateResult {
370
417
  interface ValidateOptions {
371
418
  readonly cwd: string;
372
419
  readonly environment?: string;
420
+ /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */
421
+ readonly envFlags?: readonly string[];
373
422
  }
374
423
  declare function runValidate(options: ValidateOptions): Promise<ValidateResult>;
375
424
 
@@ -516,26 +565,13 @@ interface MoveResult {
516
565
  declare function runMove(options: MoveOptions): Promise<MoveResult>;
517
566
  declare function renderMove(result: MoveResult): string[];
518
567
 
519
- /**
520
- * `penv pull` — materialise the local `.penv` tree from an environment's
521
- * source-of-truth provider. It is the inverse of the deploy-time injection most
522
- * stacks already have: instead of reading the tree to feed a backend, it reads
523
- * the backend to feed the tree.
524
- *
525
- * It only means anything when the environment declares a real backend
526
- * (`vault`, `mock`): those hold the truth somewhere penv does not edit in place,
527
- * and pulling copies it down so every other command — which reads the local tree
528
- * — sees it. An environment with no separate `providers` entry has the local
529
- * tree *as* its source of truth, so a pull would be the tree copying onto
530
- * itself; that degenerate case is reported as nothing to do, never a self-copy.
531
- *
532
- * Values cross verbatim. They are opaque envelope strings the source holds and
533
- * penv does not open here — a sealed value stays sealed, byte-for-byte, so the
534
- * key that opens it never has to be present to pull it.
535
- */
536
568
  interface PullOptions {
537
569
  readonly cwd: string;
538
570
  readonly environment?: string;
571
+ /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */
572
+ readonly envFlags?: readonly string[];
573
+ /** Injected in tests: the source provider. Defaults to the one the config declares. */
574
+ readonly source?: AnyProvider;
539
575
  }
540
576
  interface PullResult {
541
577
  readonly environment: string;
@@ -553,6 +589,12 @@ interface PullResult {
553
589
  readonly meta: number;
554
590
  /** Distinct parameters the pull touched, at any scope. */
555
591
  readonly refs: number;
592
+ /**
593
+ * True when the source declares `readsValues: false`: names and meta came
594
+ * down, values stayed absent — the destination never returns one, and the
595
+ * pull says so rather than dressing emptiness as freshness.
596
+ */
597
+ readonly valuesUnreadable?: boolean;
556
598
  }
557
599
  declare function runPull(options: PullOptions): Promise<PullResult>;
558
600
  declare function renderPull(result: PullResult): string[];
@@ -562,22 +604,41 @@ declare const LAST_PUSHED_KEY = "lastPushedAt";
562
604
  interface PushOptions {
563
605
  readonly cwd: string;
564
606
  readonly environment?: string;
607
+ /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */
608
+ readonly envFlags?: readonly string[];
565
609
  /** Permits sealed values to be decrypted locally and pushed as plaintext for the destination to re-seal. */
566
610
  readonly allowDecrypt?: boolean;
567
- /** Injected in tests: the sink to push to. Defaults to the one the config declares. */
568
- readonly sink?: Sink;
611
+ /** One-shot destination override: a provider package name. Nothing is persisted. */
612
+ readonly destination?: string;
613
+ /** The destination-side place, when `destination` needs one — `--location`. */
614
+ readonly location?: string;
615
+ /** Pre-approves creating a missing destination-side target (`--yes`). */
616
+ readonly yes?: boolean;
617
+ /** Injected in tests: the destination provider. Defaults to the one the config (or `--destination`) declares. */
618
+ readonly provider?: AnyProvider;
619
+ /** Injected in tests: answers the create-target question. Defaults to a terminal prompt. */
620
+ readonly confirm?: (question: string) => Promise<boolean>;
569
621
  /** Injected in tests: the wall-clock reading recorded in meta. Defaults to now. */
570
622
  readonly now?: string;
571
623
  }
572
624
  interface PushResult {
573
625
  readonly environment: string;
574
- /** The `owner/repo` targeted, when the config named one. */
575
- readonly repo: string | undefined;
626
+ /** The destination provider's type — its package name. */
627
+ readonly destination: string;
628
+ /** What the destination holds, which decided what crossed. */
629
+ readonly mode: "records" | "projection";
630
+ /** The `location` targeted, when one was declared. */
631
+ readonly location: string | undefined;
632
+ /** Values sent — resolved secrets for a projection, value files for records. */
576
633
  readonly pushed: number;
634
+ /** Meta records mirrored. Records mode only. */
635
+ readonly meta: number;
577
636
  readonly repositorySecrets: number;
578
637
  readonly environmentSecrets: number;
579
638
  /** How many were sealed and crossed as plaintext for the destination to re-seal. */
580
639
  readonly decrypted: number;
640
+ /** True when the destination-side target was created by this push, on approval. */
641
+ readonly createdTarget: boolean;
581
642
  }
582
643
  declare function runPush(options: PushOptions): Promise<PushResult>;
583
644
  declare function renderPush(result: PushResult): string[];
package/dist/index.d.ts CHANGED
@@ -1,14 +1,15 @@
1
1
  import * as citty from 'citty';
2
- import { Sink, Provider, ParameterRef, Scope, RotationMechanism, RotationState } from '@penvhq/core';
2
+ import { ProjectionProvider, Provider, ParameterRef, Scope, AnyProvider, RotationMechanism, RotationState } from '@penvhq/core';
3
3
 
4
4
  /**
5
5
  * A check reports one of four verdicts. `unknown` — a check that ran but could
6
6
  * not reach a verdict — is never rendered as a pass: "I looked and found nothing
7
7
  * wrong" and "I could not look" are opposite situations with opposite remedies,
8
- * and a write-only sink makes most of what doctor can say the second kind.
8
+ * and a value-withholding destination makes most of what doctor can say the
9
+ * second kind.
9
10
  */
10
11
  type DoctorSeverity = "pass" | "warning" | "failure" | "unknown";
11
- type DoctorCheck = "schema" | "missing" | "declared" | "weak" | "unused" | "unscoped-fallback" | "plaintext-secret" | "public-secret" | "encryption" | "rotation-overdue" | "rotation-stuck" | "provider-value-drift" | "provider" | "sink-unreachable" | "sink-name-drift" | "sink-manual-edit" | "sink-value-drift";
12
+ type DoctorCheck = "schema" | "missing" | "declared" | "weak" | "unused" | "unscoped-fallback" | "plaintext-secret" | "public-secret" | "encryption" | "rotation-overdue" | "rotation-stuck" | "provider-value-drift" | "provider" | "projection-unreachable" | "projection-name-drift" | "projection-manual-edit" | "projection-value-drift" | "environment-flag-shadow";
12
13
  interface DoctorFinding {
13
14
  readonly check: DoctorCheck;
14
15
  readonly severity: DoctorSeverity;
@@ -27,13 +28,15 @@ interface DoctorReport {
27
28
  interface DoctorOptions {
28
29
  readonly cwd: string;
29
30
  readonly environment?: string;
30
- /** Injected in tests: the sink to check against. Defaults to the one the config declares. */
31
- readonly sink?: Sink;
31
+ /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */
32
+ readonly envFlags?: readonly string[];
33
+ /** Injected in tests: the projection-holding destination to check against. Defaults to the one the config declares. */
34
+ readonly projection?: ProjectionProvider;
32
35
  /**
33
36
  * Injected in tests: the source-of-truth provider to compare the local tree
34
37
  * against. Defaults to the one the config declares (`sourceProviderFor`).
35
- * Mirrors `sink`, for the same reason — the drift checks stay driveable without
36
- * a live backend.
38
+ * Mirrors `projection`, for the same reason — the drift checks stay driveable
39
+ * without a live backend.
37
40
  */
38
41
  readonly source?: Provider;
39
42
  /** Injected in tests: the wall-clock reading the rotation clocks are read against. Defaults to now. */
@@ -97,6 +100,12 @@ declare function runDecrypt(options: ResealOptions): Promise<ResealResult>;
97
100
  * A value is never invented: a blank answer skips the parameter, because the
98
101
  * silent value reaching runtime is the failure penv exists to delete, and a
99
102
  * placeholder written here is exactly that value by a friendlier route.
103
+ *
104
+ * Optional parameters — `.optional()`, `.default()` — are asked too, after the
105
+ * required gaps, tagged so the reader knows an answer is an override and Enter
106
+ * keeps what the schema declared. Skipping them silently was the old behavior,
107
+ * and it hid a real choice: a schema default reaching runtime is legal, but the
108
+ * user who never heard the question never chose it.
100
109
  */
101
110
  /** One question `fill` puts to the user: which parameter, in which environment. */
102
111
  interface FillPrompt {
@@ -108,11 +117,21 @@ interface FillPrompt {
108
117
  * v1 does not, and the drift carries no meta, so this is `false` today.
109
118
  */
110
119
  readonly secret: boolean;
120
+ /**
121
+ * Whether the schema excuses absence — `.optional()`, `.default()`. An answer
122
+ * writes an override; a blank one leaves the schema's own behavior in place,
123
+ * which is a kept default rather than a lingering gap.
124
+ */
125
+ readonly optional: boolean;
126
+ /** What the schema falls back to, rendered for display, when it declares one penv can read. */
127
+ readonly defaultValue?: string;
111
128
  readonly description?: string;
112
129
  }
113
130
  interface FillOptions {
114
131
  readonly cwd: string;
115
132
  readonly environment?: string;
133
+ /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */
134
+ readonly envFlags?: readonly string[];
116
135
  /**
117
136
  * How a value is obtained for one prompt. `undefined` or an empty answer skips
118
137
  * the parameter — the readline half lives only in the wrapper, so `runFill`
@@ -131,6 +150,12 @@ interface FillResult {
131
150
  }>;
132
151
  /** The parameters a blank answer left for later — never written as an empty value. */
133
152
  readonly skipped: readonly string[];
153
+ /**
154
+ * The optional parameters a blank answer left to the schema. Not `skipped`:
155
+ * a skipped parameter is still a gap, and one of these is a decision — the
156
+ * schema's default (or declared absence) is the value, on purpose.
157
+ */
158
+ readonly kept: readonly string[];
134
159
  /**
135
160
  * The declared keys no filename reaches (`apiURL`, a reserved token). `fill`
136
161
  * cannot ask for a value it could never write, so it carries the rename remedy
@@ -156,6 +181,8 @@ declare function renderFill(result: FillResult): string[];
156
181
  interface GenerateOptions {
157
182
  readonly cwd: string;
158
183
  readonly environment?: string;
184
+ /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */
185
+ readonly envFlags?: readonly string[];
159
186
  /** Where to write, absolute or relative to `cwd`. Defaults to `.env` at the project root. */
160
187
  readonly out?: string;
161
188
  /** Permits sealed values to be written into the artifact as plaintext. */
@@ -335,14 +362,34 @@ interface UndeclaredDrift {
335
362
  /** The generated variable, which is the name the application would have read. */
336
363
  readonly variable: string;
337
364
  }
365
+ /**
366
+ * A parameter the schema declares but does not require — `.optional()`,
367
+ * `.default()`, and their kin — that the tree has no value for. Not drift in the
368
+ * verdict sense: absence here is a state the schema itself blessed, so `doctor`
369
+ * and `watch` say nothing about it. It is measured for `fill`, whose reader is
370
+ * deciding what to write, and for whom "the schema would take an override here"
371
+ * is exactly the kind of fact a silent skip would hide.
372
+ */
373
+ interface OptionalDrift {
374
+ /** The parameter id, or the dotted schema path when no filename could reach it. */
375
+ readonly subject: string;
376
+ /** Absent when no filename reaches this key — an override `penv set` cannot write. */
377
+ readonly ref?: ParameterRef;
378
+ /** What the schema falls back to, rendered for display, when it declares one this module can read. */
379
+ readonly defaultValue?: string;
380
+ /** The rename that must precede any override, for the key no filename reaches. */
381
+ readonly remedy: string;
382
+ }
338
383
  /**
339
384
  * The distance between `.penv/env.ts` and the tree, in both directions. Named
340
385
  * `declared`/`undeclared` for the side that has it, not for a verdict: neither
341
- * direction is by itself an error, and only `validate` decides that.
386
+ * direction is by itself an error, and only `validate` decides that. `optional`
387
+ * is the deliberately verdict-free third list — see {@link OptionalDrift}.
342
388
  */
343
389
  interface DriftReport {
344
390
  readonly declared: readonly DeclaredDrift[];
345
391
  readonly undeclared: readonly UndeclaredDrift[];
392
+ readonly optional: readonly OptionalDrift[];
346
393
  }
347
394
 
348
395
  type ValidateIssueKind = "config" | "reserved" | "collision" | "schema" | "undecryptable";
@@ -370,6 +417,8 @@ interface ValidateResult {
370
417
  interface ValidateOptions {
371
418
  readonly cwd: string;
372
419
  readonly environment?: string;
420
+ /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */
421
+ readonly envFlags?: readonly string[];
373
422
  }
374
423
  declare function runValidate(options: ValidateOptions): Promise<ValidateResult>;
375
424
 
@@ -516,26 +565,13 @@ interface MoveResult {
516
565
  declare function runMove(options: MoveOptions): Promise<MoveResult>;
517
566
  declare function renderMove(result: MoveResult): string[];
518
567
 
519
- /**
520
- * `penv pull` — materialise the local `.penv` tree from an environment's
521
- * source-of-truth provider. It is the inverse of the deploy-time injection most
522
- * stacks already have: instead of reading the tree to feed a backend, it reads
523
- * the backend to feed the tree.
524
- *
525
- * It only means anything when the environment declares a real backend
526
- * (`vault`, `mock`): those hold the truth somewhere penv does not edit in place,
527
- * and pulling copies it down so every other command — which reads the local tree
528
- * — sees it. An environment with no separate `providers` entry has the local
529
- * tree *as* its source of truth, so a pull would be the tree copying onto
530
- * itself; that degenerate case is reported as nothing to do, never a self-copy.
531
- *
532
- * Values cross verbatim. They are opaque envelope strings the source holds and
533
- * penv does not open here — a sealed value stays sealed, byte-for-byte, so the
534
- * key that opens it never has to be present to pull it.
535
- */
536
568
  interface PullOptions {
537
569
  readonly cwd: string;
538
570
  readonly environment?: string;
571
+ /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */
572
+ readonly envFlags?: readonly string[];
573
+ /** Injected in tests: the source provider. Defaults to the one the config declares. */
574
+ readonly source?: AnyProvider;
539
575
  }
540
576
  interface PullResult {
541
577
  readonly environment: string;
@@ -553,6 +589,12 @@ interface PullResult {
553
589
  readonly meta: number;
554
590
  /** Distinct parameters the pull touched, at any scope. */
555
591
  readonly refs: number;
592
+ /**
593
+ * True when the source declares `readsValues: false`: names and meta came
594
+ * down, values stayed absent — the destination never returns one, and the
595
+ * pull says so rather than dressing emptiness as freshness.
596
+ */
597
+ readonly valuesUnreadable?: boolean;
556
598
  }
557
599
  declare function runPull(options: PullOptions): Promise<PullResult>;
558
600
  declare function renderPull(result: PullResult): string[];
@@ -562,22 +604,41 @@ declare const LAST_PUSHED_KEY = "lastPushedAt";
562
604
  interface PushOptions {
563
605
  readonly cwd: string;
564
606
  readonly environment?: string;
607
+ /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */
608
+ readonly envFlags?: readonly string[];
565
609
  /** Permits sealed values to be decrypted locally and pushed as plaintext for the destination to re-seal. */
566
610
  readonly allowDecrypt?: boolean;
567
- /** Injected in tests: the sink to push to. Defaults to the one the config declares. */
568
- readonly sink?: Sink;
611
+ /** One-shot destination override: a provider package name. Nothing is persisted. */
612
+ readonly destination?: string;
613
+ /** The destination-side place, when `destination` needs one — `--location`. */
614
+ readonly location?: string;
615
+ /** Pre-approves creating a missing destination-side target (`--yes`). */
616
+ readonly yes?: boolean;
617
+ /** Injected in tests: the destination provider. Defaults to the one the config (or `--destination`) declares. */
618
+ readonly provider?: AnyProvider;
619
+ /** Injected in tests: answers the create-target question. Defaults to a terminal prompt. */
620
+ readonly confirm?: (question: string) => Promise<boolean>;
569
621
  /** Injected in tests: the wall-clock reading recorded in meta. Defaults to now. */
570
622
  readonly now?: string;
571
623
  }
572
624
  interface PushResult {
573
625
  readonly environment: string;
574
- /** The `owner/repo` targeted, when the config named one. */
575
- readonly repo: string | undefined;
626
+ /** The destination provider's type — its package name. */
627
+ readonly destination: string;
628
+ /** What the destination holds, which decided what crossed. */
629
+ readonly mode: "records" | "projection";
630
+ /** The `location` targeted, when one was declared. */
631
+ readonly location: string | undefined;
632
+ /** Values sent — resolved secrets for a projection, value files for records. */
576
633
  readonly pushed: number;
634
+ /** Meta records mirrored. Records mode only. */
635
+ readonly meta: number;
577
636
  readonly repositorySecrets: number;
578
637
  readonly environmentSecrets: number;
579
638
  /** How many were sealed and crossed as plaintext for the destination to re-seal. */
580
639
  readonly decrypted: number;
640
+ /** True when the destination-side target was created by this push, on approval. */
641
+ readonly createdTarget: boolean;
581
642
  }
582
643
  declare function runPush(options: PushOptions): Promise<PushResult>;
583
644
  declare function renderPush(result: PushResult): string[];