@kici-dev/shared 0.1.0 → 0.1.1

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.
@@ -6,15 +6,17 @@
6
6
  * npm, git remotes, DNS, TF state, workflow step side effects) is wrapped
7
7
  * as an IdempotentStep whose check() returns a typed drift value or null.
8
8
  * Null means the system is already in the desired state — the runner
9
- * silently skips. A non-null drift means apply() would change state — the
10
- * runner asks the caller's confirm() before invoking apply(), unless yes
11
- * or dryRun overrides are set.
9
+ * silently skips, optionally invoking whenInSync() to surface the
10
+ * already-satisfied resource (e.g. an existing resource id). A non-null
11
+ * drift means apply() would change state — the runner asks the caller's
12
+ * confirm() before invoking apply(), unless yes or dryRun overrides are
13
+ * set. apply() returns the typed result of the change for the caller.
12
14
  *
13
15
  * The runner has no UI dependency. CLI consumers pass an inquirer-backed
14
16
  * confirm; future SDK / agent consumers pass their own policy function.
15
17
  * See `.claude/rules/idempotency.md` for the full rule and adopters.
16
18
  */
17
- export interface IdempotentStep<TDrift> {
19
+ export interface IdempotentStep<TDrift, TInSync = void, TApplied = void> {
18
20
  /** Human-readable name; appears in logs and the confirm prompt. */
19
21
  name: string;
20
22
  /** Read-only inspection. Returns drift value if apply() would change
@@ -22,8 +24,15 @@ export interface IdempotentStep<TDrift> {
22
24
  check: () => Promise<TDrift | null>;
23
25
  /** Multi-line description of what apply() would do, given drift. */
24
26
  summarize: (drift: TDrift) => string;
25
- /** Destructive action that brings the system into the desired state. */
26
- apply: (drift: TDrift) => Promise<void>;
27
+ /** Destructive action that brings the system into the desired state.
28
+ * Its return value is surfaced in StepResult.result on the 'applied'
29
+ * outcome. */
30
+ apply: (drift: TDrift) => Promise<TApplied>;
31
+ /** Optional: runs when check() returns null. Use this to fetch the
32
+ * already-satisfied resource (e.g. read the existing id when a
33
+ * create-if-missing was already done). Return value is surfaced in
34
+ * StepResult.result on the 'skipped' outcome. */
35
+ whenInSync?: () => Promise<TInSync>;
27
36
  }
28
37
  export type ConfirmFn = (message: string) => Promise<boolean>;
29
38
  export interface RunOptions {
@@ -38,9 +47,22 @@ export interface RunOptions {
38
47
  log?: (line: string) => void;
39
48
  }
40
49
  export type StepOutcome = 'skipped' | 'applied' | 'declined' | 'dry-run';
41
- export interface StepResult<TDrift> {
42
- outcome: StepOutcome;
43
- drift: TDrift | null;
44
- }
45
- export declare function runIdempotentStep<TDrift>(step: IdempotentStep<TDrift>, opts?: RunOptions): Promise<StepResult<TDrift>>;
50
+ export type StepResult<TDrift, TInSync = void, TApplied = void> = {
51
+ outcome: 'skipped';
52
+ drift: null;
53
+ result: TInSync;
54
+ } | {
55
+ outcome: 'applied';
56
+ drift: TDrift;
57
+ result: TApplied;
58
+ } | {
59
+ outcome: 'declined';
60
+ drift: TDrift;
61
+ result: undefined;
62
+ } | {
63
+ outcome: 'dry-run';
64
+ drift: TDrift;
65
+ result: undefined;
66
+ };
67
+ export declare function runIdempotentStep<TDrift, TInSync = void, TApplied = void>(step: IdempotentStep<TDrift, TInSync, TApplied>, opts?: RunOptions): Promise<StepResult<TDrift, TInSync, TApplied>>;
46
68
  //# sourceMappingURL=idempotency.d.ts.map
@@ -7,7 +7,8 @@ async function runIdempotentStep(step, opts = {}) {
7
7
  log(`✓ ${step.name} — in sync, skipping`);
8
8
  return {
9
9
  outcome: "skipped",
10
- drift: null
10
+ drift: null,
11
+ result: step.whenInSync ? await step.whenInSync() : void 0
11
12
  };
12
13
  }
13
14
  log(`! ${step.name} — drift detected:`);
@@ -16,7 +17,8 @@ async function runIdempotentStep(step, opts = {}) {
16
17
  log(` (dry-run; would apply)`);
17
18
  return {
18
19
  outcome: "dry-run",
19
- drift
20
+ drift,
21
+ result: void 0
20
22
  };
21
23
  }
22
24
  let approved;
@@ -29,14 +31,16 @@ async function runIdempotentStep(step, opts = {}) {
29
31
  log(` declined; skipping`);
30
32
  return {
31
33
  outcome: "declined",
32
- drift
34
+ drift,
35
+ result: void 0
33
36
  };
34
37
  }
35
- await step.apply(drift);
38
+ const appliedResult = await step.apply(drift);
36
39
  log(`✓ ${step.name} — applied`);
37
40
  return {
38
41
  outcome: "applied",
39
- drift
42
+ drift,
43
+ result: appliedResult
40
44
  };
41
45
  }
42
46
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kici-dev/shared",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Shared utilities for the KiCI CI/CD stack — logging, zx setup, crypto, telemetry, health and metrics routes. No business logic.",
5
5
  "keywords": [
6
6
  "kici",
package/sbom.spdx.json CHANGED
@@ -2,10 +2,10 @@
2
2
  "spdxVersion": "SPDX-2.3",
3
3
  "dataLicense": "CC0-1.0",
4
4
  "SPDXID": "SPDXRef-DOCUMENT",
5
- "name": "@kici-dev/shared@0.1.0",
6
- "documentNamespace": "https://kici.dev/sbom/%40kici-dev%2Fshared/0.1.0/d7d8e1f4-f421-4d0d-9f00-fe6277039666",
5
+ "name": "@kici-dev/shared@0.1.1",
6
+ "documentNamespace": "https://kici.dev/sbom/%40kici-dev%2Fshared/0.1.1/bd4bcbb3-7e13-4f91-ad31-2784d6022448",
7
7
  "creationInfo": {
8
- "created": "2026-05-15T06:06:45Z",
8
+ "created": "2026-05-15T10:53:08Z",
9
9
  "creators": [
10
10
  "Tool: kici-sbom-generator"
11
11
  ]
@@ -947,7 +947,7 @@
947
947
  {
948
948
  "SPDXID": "SPDXRef-RootPackage",
949
949
  "name": "@kici-dev/shared",
950
- "versionInfo": "0.1.0",
950
+ "versionInfo": "0.1.1",
951
951
  "downloadLocation": "NOASSERTION",
952
952
  "filesAnalyzed": false,
953
953
  "licenseConcluded": "NOASSERTION",
@@ -958,7 +958,7 @@
958
958
  {
959
959
  "referenceCategory": "PACKAGE-MANAGER",
960
960
  "referenceType": "purl",
961
- "referenceLocator": "pkg:npm/%40kici-dev/shared@0.1.0"
961
+ "referenceLocator": "pkg:npm/%40kici-dev/shared@0.1.1"
962
962
  }
963
963
  ],
964
964
  "description": "Shared utilities for the KiCI CI/CD stack — logging, zx setup, crypto, telemetry, health and metrics routes. No business logic.",