@kici-dev/sdk 0.1.20 → 0.1.22
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/api-types.d.ts +36 -0
- package/dist/api-types.js +6 -1
- package/dist/approval.d.ts +25 -10
- package/dist/approval.js +18 -8
- package/dist/context.d.ts +9 -0
- package/dist/dynamic-group.d.ts +6 -4
- package/dist/dynamic-group.js +2 -12
- package/dist/host-restart.d.ts +58 -0
- package/dist/host-restart.js +63 -0
- package/dist/index.d.ts +7 -5
- package/dist/index.js +4 -3
- package/dist/job.js +1 -1
- package/dist/needs-context.d.ts +12 -5
- package/dist/needs-context.js +12 -4
- package/dist/step.d.ts +21 -1
- package/dist/step.js +8 -1
- package/dist/types.d.ts +77 -21
- package/dist/workflow.js +1 -1
- package/package.json +3 -3
- package/sbom.spdx.json +24 -24
package/dist/api-types.d.ts
CHANGED
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
* 2. Register the handler in the orchestrator's AgentApiRegistry
|
|
10
10
|
*/
|
|
11
11
|
import { type OidcTokenResult } from '@kici-dev/engine/protocol/messages/oidc-token-relay';
|
|
12
|
+
import type { HostInventoryEntry, InventorySelector } from '@kici-dev/engine';
|
|
12
13
|
export type { OidcTokenResult };
|
|
14
|
+
export type { HostInventoryEntry, InventorySelector };
|
|
13
15
|
export interface InfrastructureListResult {
|
|
14
16
|
scalers: Array<{
|
|
15
17
|
name: string;
|
|
@@ -42,11 +44,45 @@ export interface OidcApi {
|
|
|
42
44
|
audience: string;
|
|
43
45
|
}): Promise<OidcTokenResult>;
|
|
44
46
|
}
|
|
47
|
+
export interface InventoryApi {
|
|
48
|
+
/**
|
|
49
|
+
* Query the host roster of the caller's orchestrator cluster. Omit the
|
|
50
|
+
* selector ⇒ all hosts. Server-side filtering is label-based (reuses the
|
|
51
|
+
* runsOnAll glob/regex matchers); filter on `properties` client-side in the
|
|
52
|
+
* workflow. Available to steps and dynamic-job generators — a generator can
|
|
53
|
+
* fan out one job per matching host. The roster is live, so a dynamic-job
|
|
54
|
+
* generator inherits the same non-determinism contract as
|
|
55
|
+
* `infrastructure.list()`.
|
|
56
|
+
*/
|
|
57
|
+
query(selector?: InventorySelector): Promise<HostInventoryEntry[]>;
|
|
58
|
+
/** Look up one host by agent id; null when the host is not in the roster. */
|
|
59
|
+
get(agentId: string): Promise<HostInventoryEntry | null>;
|
|
60
|
+
}
|
|
61
|
+
export interface HostApi {
|
|
62
|
+
/**
|
|
63
|
+
* Signal the orchestrator that the host this job runs on is about to reboot,
|
|
64
|
+
* and resolve once the orchestrator acks (which sets a persisted
|
|
65
|
+
* reboot-pending flag holding the pinned post-restart job). After this
|
|
66
|
+
* resolves, the agent issues the OS reboot once the current step completes.
|
|
67
|
+
*
|
|
68
|
+
* Used by the SDK `restartHost()` step. `deadlineMs` overrides the
|
|
69
|
+
* orchestrator's default host-reboot deadline. Only meaningful inside a
|
|
70
|
+
* running job step on an agent; a local `kici run` rejects (no orchestrator
|
|
71
|
+
* to ack, and a local run cannot reboot a remote host).
|
|
72
|
+
*/
|
|
73
|
+
requestReboot(opts?: {
|
|
74
|
+
deadlineMs?: number;
|
|
75
|
+
}): Promise<void>;
|
|
76
|
+
}
|
|
45
77
|
export interface KiciApi {
|
|
46
78
|
/** Query orchestrator infrastructure (scalers, agents). */
|
|
47
79
|
infrastructure: InfrastructureApi;
|
|
80
|
+
/** Query the host roster / inventory (labels + typed properties). */
|
|
81
|
+
inventory: InventoryApi;
|
|
48
82
|
/** Request short-lived OIDC ID tokens for the current job (build provenance). */
|
|
49
83
|
oidc: OidcApi;
|
|
84
|
+
/** Host-lifecycle operations on the agent's own host (e.g. reboot). */
|
|
85
|
+
host: HostApi;
|
|
50
86
|
}
|
|
51
87
|
/**
|
|
52
88
|
* Low-level transport function used to implement KiciApi.
|
package/dist/api-types.js
CHANGED
|
@@ -26,13 +26,18 @@ import { OIDC_TOKEN_REQUEST_METHOD } from "@kici-dev/engine/protocol/messages/oi
|
|
|
26
26
|
function buildKiciApi(transport, jobCtx) {
|
|
27
27
|
return {
|
|
28
28
|
infrastructure: { list: () => transport("infrastructure.list", {}) },
|
|
29
|
+
inventory: {
|
|
30
|
+
query: (selector) => transport("inventory.query", { ...selector ?? {} }),
|
|
31
|
+
get: (agentId) => transport("inventory.get", { agentId })
|
|
32
|
+
},
|
|
29
33
|
oidc: { token: (opts) => {
|
|
30
34
|
if (!jobCtx) return Promise.reject(/* @__PURE__ */ new Error("ctx.kici.oidc.token() is only available inside a running job step"));
|
|
31
35
|
return transport(OIDC_TOKEN_REQUEST_METHOD, {
|
|
32
36
|
jobId: jobCtx.jobId,
|
|
33
37
|
audience: opts.audience
|
|
34
38
|
});
|
|
35
|
-
} }
|
|
39
|
+
} },
|
|
40
|
+
host: { requestReboot: (opts) => transport("host.requestReboot", { ...opts?.deadlineMs !== void 0 ? { deadlineMs: opts.deadlineMs } : {} }) }
|
|
36
41
|
};
|
|
37
42
|
}
|
|
38
43
|
//#endregion
|
package/dist/approval.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Workflow-author API for declaring a manual approval gate at step, job, or
|
|
3
|
-
* workflow level. The author writes `
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* workflow level. The author writes `approval`; the compiler normalizes it
|
|
4
|
+
* into the lock file's `approval` block, and the orchestrator turns it into a
|
|
5
|
+
* held element at dispatch time (for `when: 'always'`) or the agent turns it
|
|
6
|
+
* into a mid-step drift gate (for `when: 'drift'`).
|
|
6
7
|
*/
|
|
7
8
|
/** A single approver clause: any member of a team, or a specific user. */
|
|
8
9
|
export type ApproverClause = {
|
|
@@ -10,25 +11,39 @@ export type ApproverClause = {
|
|
|
10
11
|
} | {
|
|
11
12
|
user: string;
|
|
12
13
|
};
|
|
14
|
+
/**
|
|
15
|
+
* When the gate fires.
|
|
16
|
+
*
|
|
17
|
+
* - `always` (default) — gate BEFORE the element runs, with a static reason.
|
|
18
|
+
* Valid at step / job / workflow scope.
|
|
19
|
+
* - `drift` — gate BETWEEN a step's `check` and `run`, only when `check`
|
|
20
|
+
* returns drift in apply mode. Step-scope only; requires a `check` facet.
|
|
21
|
+
*/
|
|
22
|
+
export type ApprovalWhen = 'always' | 'drift';
|
|
13
23
|
/**
|
|
14
24
|
* Declarative approval requirement.
|
|
15
25
|
*
|
|
16
26
|
* - `true` — pause for ANY org member with the approval permission.
|
|
17
27
|
* - `ApproverClause[]` — a flat AND list (all clauses must be satisfied).
|
|
18
|
-
* - object form — clauses plus an optional human `reason
|
|
19
|
-
* `timeout` (seconds) that overrides the org-default expiry.
|
|
28
|
+
* - object form — clauses plus an optional `when`, a human `reason`, and a
|
|
29
|
+
* per-gate `timeout` (seconds) that overrides the org-default expiry.
|
|
20
30
|
*/
|
|
21
|
-
export type
|
|
22
|
-
|
|
31
|
+
export type ApprovalConfig = true | ApproverClause[] | {
|
|
32
|
+
when?: ApprovalWhen;
|
|
33
|
+
approvers?: ApproverClause[];
|
|
23
34
|
reason?: string;
|
|
24
35
|
timeout?: number;
|
|
25
36
|
};
|
|
26
37
|
/** The normalized shape written into the lock file. */
|
|
27
|
-
export interface
|
|
38
|
+
export interface NormalizedApproval {
|
|
28
39
|
clauses: ApproverClause[];
|
|
29
40
|
reason?: string;
|
|
30
41
|
timeoutSeconds?: number;
|
|
42
|
+
when: ApprovalWhen;
|
|
31
43
|
}
|
|
32
|
-
/**
|
|
33
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Normalize any `ApprovalConfig` form into
|
|
46
|
+
* `{ clauses, reason?, timeoutSeconds?, when }`. `when` defaults to `'always'`.
|
|
47
|
+
*/
|
|
48
|
+
export declare function normalizeApproval(c: ApprovalConfig): NormalizedApproval;
|
|
34
49
|
//# sourceMappingURL=approval.d.ts.map
|
package/dist/approval.js
CHANGED
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
import "./chunk-BTugEXQM.js";
|
|
2
2
|
//#region src/approval.ts
|
|
3
|
-
/**
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Normalize any `ApprovalConfig` form into
|
|
5
|
+
* `{ clauses, reason?, timeoutSeconds?, when }`. `when` defaults to `'always'`.
|
|
6
|
+
*/
|
|
7
|
+
function normalizeApproval(c) {
|
|
8
|
+
if (c === true) return {
|
|
9
|
+
clauses: [],
|
|
10
|
+
when: "always"
|
|
11
|
+
};
|
|
12
|
+
if (Array.isArray(c)) return {
|
|
13
|
+
clauses: c,
|
|
14
|
+
when: "always"
|
|
15
|
+
};
|
|
7
16
|
return {
|
|
8
|
-
clauses:
|
|
9
|
-
reason:
|
|
10
|
-
timeoutSeconds:
|
|
17
|
+
clauses: c.approvers ?? [],
|
|
18
|
+
...c.reason !== void 0 && { reason: c.reason },
|
|
19
|
+
...c.timeout !== void 0 && { timeoutSeconds: c.timeout },
|
|
20
|
+
when: c.when ?? "always"
|
|
11
21
|
};
|
|
12
22
|
}
|
|
13
23
|
//#endregion
|
|
14
|
-
export {
|
|
24
|
+
export { normalizeApproval };
|
|
15
25
|
|
|
16
26
|
//# sourceMappingURL=approval.js.map
|
package/dist/context.d.ts
CHANGED
|
@@ -261,6 +261,15 @@ export interface StepContext<TInputs = Record<string, unknown>> {
|
|
|
261
261
|
* the agent digests with SHA-256.
|
|
262
262
|
*/
|
|
263
263
|
attestProvenance(opts: import('./provenance-types.js').AttestProvenanceOptions): Promise<import('./provenance-types.js').AttestProvenanceResult>;
|
|
264
|
+
/**
|
|
265
|
+
* Upstream needs resolved for this job, keyed by upstream job or group name.
|
|
266
|
+
* `ctx.needs.<job>.result` is the upstream's outputs proxy and
|
|
267
|
+
* `ctx.needs.<job>.status` its terminal status (`success | failed | skipped |
|
|
268
|
+
* …`). A group / matrix / `runsOnAll` fan-out upstream is an ordered array of
|
|
269
|
+
* `{ name, result, status }`, one entry per child. Undefined for a job with no
|
|
270
|
+
* declared `needs`.
|
|
271
|
+
*/
|
|
272
|
+
needs?: import('./needs-context.js').NeedsContext;
|
|
264
273
|
}
|
|
265
274
|
export {};
|
|
266
275
|
//# sourceMappingURL=context.d.ts.map
|
package/dist/dynamic-group.d.ts
CHANGED
|
@@ -6,22 +6,24 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Usage in workflow definition:
|
|
8
8
|
* needs: [dynamicGroup('test-shards')]
|
|
9
|
-
* needs: [dynamicGroup('test-shards', {
|
|
9
|
+
* needs: [dynamicGroup('test-shards', { when: 'always' })]
|
|
10
10
|
*/
|
|
11
|
+
import type { NeedsWhenInput } from './types.js';
|
|
11
12
|
declare const DYNAMIC_GROUP_TAG: unique symbol;
|
|
12
13
|
export interface DynamicGroupRef {
|
|
13
14
|
readonly [DYNAMIC_GROUP_TAG]: true;
|
|
14
15
|
readonly group: string;
|
|
15
|
-
|
|
16
|
+
/** Run condition for the edge: keyword sugar or a raw upstream-status set. */
|
|
17
|
+
readonly when?: NeedsWhenInput;
|
|
16
18
|
}
|
|
17
19
|
/**
|
|
18
20
|
* Create a reference to a dynamic job group for use in a static job's `needs` array.
|
|
19
21
|
*
|
|
20
22
|
* @param name - The group name (must match the name used in `dynamicJob(name, fn)`)
|
|
21
|
-
* @param opts - Optional
|
|
23
|
+
* @param opts - Optional run condition for the edge
|
|
22
24
|
*/
|
|
23
25
|
export declare function dynamicGroup(name: string, opts?: {
|
|
24
|
-
|
|
26
|
+
when?: NeedsWhenInput;
|
|
25
27
|
}): DynamicGroupRef;
|
|
26
28
|
/** Type guard to check if a value is a DynamicGroupRef. */
|
|
27
29
|
export declare function isDynamicGroupRef(value: unknown): value is DynamicGroupRef;
|
package/dist/dynamic-group.js
CHANGED
|
@@ -1,27 +1,17 @@
|
|
|
1
1
|
import "./chunk-BTugEXQM.js";
|
|
2
2
|
//#region src/dynamic-group.ts
|
|
3
|
-
/**
|
|
4
|
-
* Dynamic group helpers for cross-domain needs.
|
|
5
|
-
*
|
|
6
|
-
* A DynamicGroupRef allows static jobs to declare a dependency on a dynamic
|
|
7
|
-
* job group by name, without knowing the concrete generated job names.
|
|
8
|
-
*
|
|
9
|
-
* Usage in workflow definition:
|
|
10
|
-
* needs: [dynamicGroup('test-shards')]
|
|
11
|
-
* needs: [dynamicGroup('test-shards', { ifFailed: 'run' })]
|
|
12
|
-
*/
|
|
13
3
|
const DYNAMIC_GROUP_TAG = Symbol.for("kici:dynamicGroup");
|
|
14
4
|
/**
|
|
15
5
|
* Create a reference to a dynamic job group for use in a static job's `needs` array.
|
|
16
6
|
*
|
|
17
7
|
* @param name - The group name (must match the name used in `dynamicJob(name, fn)`)
|
|
18
|
-
* @param opts - Optional
|
|
8
|
+
* @param opts - Optional run condition for the edge
|
|
19
9
|
*/
|
|
20
10
|
function dynamicGroup(name, opts) {
|
|
21
11
|
return {
|
|
22
12
|
[DYNAMIC_GROUP_TAG]: true,
|
|
23
13
|
group: name,
|
|
24
|
-
...opts?.
|
|
14
|
+
...opts?.when !== void 0 && { when: opts.when }
|
|
25
15
|
};
|
|
26
16
|
}
|
|
27
17
|
/** Type guard to check if a value is a DynamicGroupRef. */
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow-level host restart + wait-for-host-alive steps.
|
|
3
|
+
*
|
|
4
|
+
* KiCI agents run ON each host while executing a job, so a workflow can reboot
|
|
5
|
+
* the machine it runs on (the Ansible `reboot` + `wait_for_connection` pattern,
|
|
6
|
+
* adapted to KiCI's no-remote-exec model). The flow is job-boundary:
|
|
7
|
+
*
|
|
8
|
+
* - `restartHost()` is the LAST step of a "restart" job. It signals the
|
|
9
|
+
* orchestrator that this host is about to reboot (which holds the pinned
|
|
10
|
+
* post-restart job and treats the imminent disconnect as expected), reports
|
|
11
|
+
* success, and the agent issues the OS reboot once the step completes.
|
|
12
|
+
* - The post-restart work is a SEPARATE job pinned to the same host
|
|
13
|
+
* (`runsOn: [hostId]`) that `needs` the restart job. The orchestrator holds
|
|
14
|
+
* it until the host completes a reboot cycle, then dispatches it.
|
|
15
|
+
* - `waitForHostAlive(probe)` is the optional first step of that post-restart
|
|
16
|
+
* job: the "host is back" guarantee comes free from the pinned-hold (the job
|
|
17
|
+
* only dispatches after the agent reconnects); this step adds a
|
|
18
|
+
* service-readiness gate for hosts where "agent connected" ≠ "services ready".
|
|
19
|
+
*/
|
|
20
|
+
import type { Step } from './types.js';
|
|
21
|
+
export interface WaitForHostAliveOptions {
|
|
22
|
+
/** Step name surfaced in logs. Defaults to 'wait-for-host-alive'. */
|
|
23
|
+
name?: string;
|
|
24
|
+
/** Time between successive probe invocations, ms. Defaults to 3000. */
|
|
25
|
+
intervalMs?: number;
|
|
26
|
+
/** Total time budget for readiness, ms. Defaults to 300000 (5 min). */
|
|
27
|
+
timeoutMs?: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Optional first step of a post-restart job. Polls a readiness probe until it
|
|
31
|
+
* resolves (services back up after a reboot). The host being reconnected is
|
|
32
|
+
* already guaranteed by the pinned-hold; this gates on service readiness.
|
|
33
|
+
*
|
|
34
|
+
* A probe that throws/rejects keeps polling (the `waitFor` swallow-errors
|
|
35
|
+
* default — the "poll until healthy" pattern). Any non-null resolution means
|
|
36
|
+
* "ready". Exceeding `timeoutMs` fails the step ("services did not come up").
|
|
37
|
+
*/
|
|
38
|
+
export declare function waitForHostAlive(probe: () => Promise<unknown> | unknown, opts?: WaitForHostAliveOptions): Step<unknown>;
|
|
39
|
+
export interface RestartHostOptions {
|
|
40
|
+
/**
|
|
41
|
+
* Max time the orchestrator waits for the host to return after the reboot,
|
|
42
|
+
* ms. Defaults to the orchestrator's `KICI_HOST_REBOOT_DEADLINE_MS`.
|
|
43
|
+
*/
|
|
44
|
+
deadlineMs?: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Reboot the host this job runs on. MUST be the last step of a "restart" job;
|
|
48
|
+
* the post-restart work goes in a separate job that `needs` this one and is
|
|
49
|
+
* pinned to the same host (`runsOn: [hostId]`). The orchestrator holds that job
|
|
50
|
+
* until the host completes a reboot cycle, then dispatches it.
|
|
51
|
+
*
|
|
52
|
+
* The step signals the orchestrator (reboot-pending) and reports success; the
|
|
53
|
+
* agent issues the actual OS reboot after the step completes. Rebooting needs
|
|
54
|
+
* host privilege: if the OS reboot primitive is denied, the step fails with a
|
|
55
|
+
* clear privilege error and the orchestrator clears the reboot-pending flag.
|
|
56
|
+
*/
|
|
57
|
+
export declare function restartHost(opts?: RestartHostOptions): Step<void>;
|
|
58
|
+
//# sourceMappingURL=host-restart.d.ts.map
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import "./chunk-BTugEXQM.js";
|
|
2
|
+
import { step } from "./step.js";
|
|
3
|
+
import { waitForStep } from "./wait-for.js";
|
|
4
|
+
//#region src/host-restart.ts
|
|
5
|
+
/**
|
|
6
|
+
* Workflow-level host restart + wait-for-host-alive steps.
|
|
7
|
+
*
|
|
8
|
+
* KiCI agents run ON each host while executing a job, so a workflow can reboot
|
|
9
|
+
* the machine it runs on (the Ansible `reboot` + `wait_for_connection` pattern,
|
|
10
|
+
* adapted to KiCI's no-remote-exec model). The flow is job-boundary:
|
|
11
|
+
*
|
|
12
|
+
* - `restartHost()` is the LAST step of a "restart" job. It signals the
|
|
13
|
+
* orchestrator that this host is about to reboot (which holds the pinned
|
|
14
|
+
* post-restart job and treats the imminent disconnect as expected), reports
|
|
15
|
+
* success, and the agent issues the OS reboot once the step completes.
|
|
16
|
+
* - The post-restart work is a SEPARATE job pinned to the same host
|
|
17
|
+
* (`runsOn: [hostId]`) that `needs` the restart job. The orchestrator holds
|
|
18
|
+
* it until the host completes a reboot cycle, then dispatches it.
|
|
19
|
+
* - `waitForHostAlive(probe)` is the optional first step of that post-restart
|
|
20
|
+
* job: the "host is back" guarantee comes free from the pinned-hold (the job
|
|
21
|
+
* only dispatches after the agent reconnects); this step adds a
|
|
22
|
+
* service-readiness gate for hosts where "agent connected" ≠ "services ready".
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Optional first step of a post-restart job. Polls a readiness probe until it
|
|
26
|
+
* resolves (services back up after a reboot). The host being reconnected is
|
|
27
|
+
* already guaranteed by the pinned-hold; this gates on service readiness.
|
|
28
|
+
*
|
|
29
|
+
* A probe that throws/rejects keeps polling (the `waitFor` swallow-errors
|
|
30
|
+
* default — the "poll until healthy" pattern). Any non-null resolution means
|
|
31
|
+
* "ready". Exceeding `timeoutMs` fails the step ("services did not come up").
|
|
32
|
+
*/
|
|
33
|
+
function waitForHostAlive(probe, opts = {}) {
|
|
34
|
+
return waitForStep(opts.name ?? "wait-for-host-alive", {
|
|
35
|
+
check: async () => {
|
|
36
|
+
return await probe() ?? true;
|
|
37
|
+
},
|
|
38
|
+
intervalMs: opts.intervalMs ?? 3e3,
|
|
39
|
+
timeoutMs: opts.timeoutMs ?? 3e5
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Reboot the host this job runs on. MUST be the last step of a "restart" job;
|
|
44
|
+
* the post-restart work goes in a separate job that `needs` this one and is
|
|
45
|
+
* pinned to the same host (`runsOn: [hostId]`). The orchestrator holds that job
|
|
46
|
+
* until the host completes a reboot cycle, then dispatches it.
|
|
47
|
+
*
|
|
48
|
+
* The step signals the orchestrator (reboot-pending) and reports success; the
|
|
49
|
+
* agent issues the actual OS reboot after the step completes. Rebooting needs
|
|
50
|
+
* host privilege: if the OS reboot primitive is denied, the step fails with a
|
|
51
|
+
* clear privilege error and the orchestrator clears the reboot-pending flag.
|
|
52
|
+
*/
|
|
53
|
+
function restartHost(opts = {}) {
|
|
54
|
+
return step("restart-host", { run: async (ctx) => {
|
|
55
|
+
ctx.log.info("Requesting host reboot…");
|
|
56
|
+
await ctx.kici.host.requestReboot({ deadlineMs: opts.deadlineMs });
|
|
57
|
+
ctx.log.info("Reboot acknowledged; host will reboot after this step completes.");
|
|
58
|
+
} });
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
export { restartHost, waitForHostAlive };
|
|
62
|
+
|
|
63
|
+
//# sourceMappingURL=host-restart.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export { step } from './step.js';
|
|
2
2
|
export { job } from './job.js';
|
|
3
3
|
export { workflow } from './workflow.js';
|
|
4
|
-
export {
|
|
5
|
-
export type {
|
|
4
|
+
export { normalizeApproval } from './approval.js';
|
|
5
|
+
export type { ApprovalConfig, ApprovalWhen, ApproverClause, NormalizedApproval, } from './approval.js';
|
|
6
6
|
export { pr, push, tag, comment, review, reviewComment, release, dispatch, create, delete as delete, status, workflowRun, fork, star, watch, webhook, kiciEvent, workflowComplete, jobComplete, genericWebhook, schedule, lifecycle, } from './triggers/index.js';
|
|
7
7
|
export type { TriggerConfig, PrTriggerConfig, PushTriggerConfig, TagTriggerConfig, CommentTriggerConfig, ReviewTriggerConfig, ReviewCommentTriggerConfig, ReleaseTriggerConfig, DispatchTriggerConfig, CreateTriggerConfig, DeleteTriggerConfig, StatusTriggerConfig, WorkflowRunTriggerConfig, ForkTriggerConfig, StarTriggerConfig, WatchTriggerConfig, WebhookTriggerConfig, BranchPattern, BodyMatchPattern, PrEvent, PushEvent, PrConfigInput, PushConfigInput, TagConfigInput, CommentConfigInput, CommentAction, CommentSource, ReviewConfigInput, ReviewAction, ReviewState, ReviewCommentConfigInput, ReviewCommentAction, ReleaseConfigInput, ReleaseAction, DispatchConfigInput, CreateConfigInput, DeleteConfigInput, RefType, StatusConfigInput, StatusState, WorkflowRunConfigInput, WorkflowRunAction, ForkConfigInput, StarConfigInput, StarAction, WatchConfigInput, WatchAction, WebhookConfigInput, KiciEventConfigInput, KiciEventTriggerConfig, WorkflowCompleteConfigInput, WorkflowCompleteTriggerConfig, WorkflowCompleteStatus, JobCompleteConfigInput, JobCompleteTriggerConfig, JobCompleteStatus, GenericWebhookConfigInput, GenericWebhookTriggerConfig, GenericWebhookAuthMethod, GenericWebhookHmacAuth, GenericWebhookApiKeyAuth, GenericWebhookAuth, ScheduleConfigInput, ScheduleTriggerConfig, LifecycleEvent, LifecycleConfigInput, LifecycleTriggerConfig, } from './triggers/index.js';
|
|
8
8
|
export { onCancel, cleanup, onSuccess, onFailure, beforeStep, afterStep } from './hooks/index.js';
|
|
@@ -13,9 +13,9 @@ export { isEventType } from './rules/index.js';
|
|
|
13
13
|
export type { Rule, RuleContext, RuleCheckFn, RuleResult, EventPayload, RuleEvaluationResult, EventBase, PullRequestEventPayload, PushEventPayload, TagEventPayload, CommentEventPayload, ReviewEventPayload, ReviewCommentEventPayload, ReleaseEventPayload, DispatchEventPayload, CreateEventPayload, DeleteEventPayload, StatusEventPayload, WorkflowRunEventPayload, ForkEventPayload, StarEventPayload, WatchEventPayload, WebhookEventPayload, KiciEventPayload, WorkflowCompleteEventPayload, JobCompleteEventPayload, GenericWebhookEventPayload, ScheduleEventPayload, LifecycleEventPayload, GitHubRepository, GitHubUser, GitHubPullRequest, GitHubCommit, GitHubComment, GitHubReview, GitHubRelease, } from './rules/index.js';
|
|
14
14
|
export { validateDag } from './validation/index.js';
|
|
15
15
|
export type { DagNode, DagValidationResult } from './validation/index.js';
|
|
16
|
-
export type { SourceLocation, OutputProxy, Step, StepOptions, StepRunFn, BareStepFn, StepInput, OutputSchema, InferOutputs, Job, JobOptions, GenericInitConfig, MiseInitConfig, InitPreset, InitItem, InitConfig, ContainerConfig, RunsOnSelector, RunsOn, Workflow, WorkflowOptions, Registry, Trigger, DynamicJobFn, DynamicJobContext, JobOrFactory, } from './types.js';
|
|
16
|
+
export type { SourceLocation, OutputProxy, Step, StepOptions, StepOptionsBase, StepOptionsPlain, StepOptionsWithCheck, StepRunFn, BareStepFn, StepInput, OutputSchema, InferOutputs, Job, JobOptions, GenericInitConfig, MiseInitConfig, InitPreset, InitItem, InitConfig, ContainerConfig, RunsOnSelector, RunsOn, Workflow, WorkflowOptions, Registry, Trigger, DynamicJobFn, DynamicJobContext, JobOrFactory, } from './types.js';
|
|
17
17
|
export { isDynamicJobFn, dynamicJob, getDynamicJobGroup, getDynamicJobNeeds, DYNAMIC_JOB_GROUP_TAG, DYNAMIC_JOB_NEEDS_TAG, } from './types.js';
|
|
18
|
-
export type { TaggedDynamicJobFn, ResultAwareDynamicJobConfig, ResultAwareDynamicJobFn, DynamicJobNeed, } from './types.js';
|
|
18
|
+
export type { TaggedDynamicJobFn, ResultAwareDynamicJobConfig, ResultAwareDynamicJobFn, DynamicJobNeed, NeedsWhen, NeedsWhenInput, } from './types.js';
|
|
19
19
|
export { buildNeedsContext } from './needs-context.js';
|
|
20
20
|
export type { UpstreamSnapshot, NeedsContext, NeedEntry, GroupNeedEntry } from './needs-context.js';
|
|
21
21
|
export { CacheSpecSchema, normalizeCacheSpecs } from './cache-types.js';
|
|
@@ -28,7 +28,7 @@ export type { DynamicGroupRef } from './dynamic-group.js';
|
|
|
28
28
|
export type { StepContext, Logger, WorkflowInfo, JobInfo, AgentInfo, MatrixJobOutputs, HostJobOutputs, RepoInfo, StepSecretsTyped, KnownSecretKeys, } from './context.js';
|
|
29
29
|
export { isMatrixJobOutputs, isHostJobOutputs } from './context.js';
|
|
30
30
|
export { buildKiciApi } from './api-types.js';
|
|
31
|
-
export type { KiciApi, KiciApiTransport, InfrastructureApi, InfrastructureListResult, } from './api-types.js';
|
|
31
|
+
export type { KiciApi, KiciApiTransport, InfrastructureApi, InfrastructureListResult, InventoryApi, HostApi, HostInventoryEntry, InventorySelector, } from './api-types.js';
|
|
32
32
|
export { SecretNotFoundError } from './errors.js';
|
|
33
33
|
export { createStepSecrets } from './secrets.js';
|
|
34
34
|
export type { StepSecrets, TrackedStepSecrets, SecretMeta, SecretFileOptions, MountedFile, StepSecretsFileHost, StepSecretsFileWiring, StepSecretsHandle, StepSecretMountKind, StepSecretMountRecord, } from './secrets.js';
|
|
@@ -46,5 +46,7 @@ export { idempotent, idempotentStep } from './idempotent.js';
|
|
|
46
46
|
export type { IdempotentOptions, IdempotentResult } from './idempotent.js';
|
|
47
47
|
export { waitFor, waitForStep, WaitForTimeoutError } from './wait-for.js';
|
|
48
48
|
export type { WaitForOptions, WaitForResult } from './wait-for.js';
|
|
49
|
+
export { waitForHostAlive, restartHost } from './host-restart.js';
|
|
50
|
+
export type { WaitForHostAliveOptions, RestartHostOptions } from './host-restart.js';
|
|
49
51
|
export { z } from 'zod';
|
|
50
52
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "./chunk-BTugEXQM.js";
|
|
2
2
|
import { buildKiciApi } from "./api-types.js";
|
|
3
|
-
import {
|
|
3
|
+
import { normalizeApproval } from "./approval.js";
|
|
4
4
|
import { CacheSpecSchema, normalizeCacheSpecs } from "./cache-types.js";
|
|
5
5
|
import { isHostJobOutputs, isMatrixJobOutputs } from "./context.js";
|
|
6
6
|
import { DYNAMIC_GROUP_TAG, dynamicGroup, isDynamicGroupRef } from "./dynamic-group.js";
|
|
@@ -8,6 +8,8 @@ import { SecretNotFoundError } from "./errors.js";
|
|
|
8
8
|
import { fixture } from "./fixture.js";
|
|
9
9
|
import { createJobOutputProxy, createSnapshotOutputProxy, createStepOutputProxy, getJobOutputsMap, getStepOutputsMap, getStepRefMap, resolveJobOutputs, resolveStepOutputs, setJobOutputsMap, setStepOutputsMap, setStepRefMap } from "./outputs.js";
|
|
10
10
|
import { step } from "./step.js";
|
|
11
|
+
import { WaitForTimeoutError, waitFor, waitForStep } from "./wait-for.js";
|
|
12
|
+
import { restartHost, waitForHostAlive } from "./host-restart.js";
|
|
11
13
|
import { idempotent, idempotentStep } from "./idempotent.js";
|
|
12
14
|
import { job } from "./job.js";
|
|
13
15
|
import { workflow } from "./workflow.js";
|
|
@@ -50,6 +52,5 @@ import { applyIncludeExclude, expandMatrix } from "./matrix/expand.js";
|
|
|
50
52
|
import "./matrix/index.js";
|
|
51
53
|
import { defineEvent } from "./events/define-event.js";
|
|
52
54
|
import "./events/index.js";
|
|
53
|
-
import { WaitForTimeoutError, waitFor, waitForStep } from "./wait-for.js";
|
|
54
55
|
import { z } from "zod";
|
|
55
|
-
export { CacheSpecSchema, DYNAMIC_GROUP_TAG, DYNAMIC_JOB_GROUP_TAG, DYNAMIC_JOB_NEEDS_TAG, SecretNotFoundError, WaitForTimeoutError, afterStep, applyIncludeExclude, beforeStep, buildKiciApi, buildNeedsContext, cleanup, comment, create, createJobOutputProxy, createSnapshotOutputProxy, createStepOutputProxy, createStepSecrets, defineEvent, del as delete, dispatch, dynamicGroup, dynamicJob, evaluateRules, expandMatrix, fixture, fork, genericWebhook, getDynamicJobGroup, getDynamicJobNeeds, getJobOutputsMap, getStepOutputsMap, getStepRefMap, idempotent, idempotentStep, isDynamicFunction, isDynamicGroupRef, isDynamicJobFn, isEventType, isHostJobOutputs, isMatrixJobOutputs, isStaticArray, isStaticObject, job, jobComplete, kiciEvent, lifecycle,
|
|
56
|
+
export { CacheSpecSchema, DYNAMIC_GROUP_TAG, DYNAMIC_JOB_GROUP_TAG, DYNAMIC_JOB_NEEDS_TAG, SecretNotFoundError, WaitForTimeoutError, afterStep, applyIncludeExclude, beforeStep, buildKiciApi, buildNeedsContext, cleanup, comment, create, createJobOutputProxy, createSnapshotOutputProxy, createStepOutputProxy, createStepSecrets, defineEvent, del as delete, dispatch, dynamicGroup, dynamicJob, evaluateRules, expandMatrix, fixture, fork, genericWebhook, getDynamicJobGroup, getDynamicJobNeeds, getJobOutputsMap, getStepOutputsMap, getStepRefMap, idempotent, idempotentStep, isDynamicFunction, isDynamicGroupRef, isDynamicJobFn, isEventType, isHostJobOutputs, isMatrixJobOutputs, isStaticArray, isStaticObject, job, jobComplete, kiciEvent, lifecycle, normalizeApproval, normalizeCacheSpecs, onCancel, onFailure, onSuccess, pr, provenanceSubjectIsPath, push, release, resolveJobOutputs, resolveStepOutputs, restartHost, review, reviewComment, rule, schedule, setJobOutputsMap, setStepOutputsMap, setStepRefMap, skip, star, status, step, tag, validateDag, waitFor, waitForHostAlive, waitForStep, watch, webhook, workflow, workflowComplete, workflowRun, z };
|
package/dist/job.js
CHANGED
|
@@ -66,7 +66,7 @@ function job(nameOrOptions, maybeOptions) {
|
|
|
66
66
|
resources: options.resources,
|
|
67
67
|
init: options.init,
|
|
68
68
|
...options.cache !== void 0 && { cache: options.cache },
|
|
69
|
-
...options.
|
|
69
|
+
...options.approval !== void 0 && { approval: options.approval },
|
|
70
70
|
result: createJobOutputProxy(name)
|
|
71
71
|
};
|
|
72
72
|
}
|
package/dist/needs-context.d.ts
CHANGED
|
@@ -1,31 +1,38 @@
|
|
|
1
1
|
import type { OutputProxy, DynamicJobNeed } from './types.js';
|
|
2
|
+
import type { ExecutionJobStatus } from '@kici-dev/engine';
|
|
2
3
|
/**
|
|
3
|
-
* Frozen snapshot of upstream outputs, captured once at first eval of
|
|
4
|
-
* result-aware dynamic generator and replayed unchanged on re-eval.
|
|
4
|
+
* Frozen snapshot of upstream outputs + statuses, captured once at first eval of
|
|
5
|
+
* a result-aware dynamic generator and replayed unchanged on re-eval.
|
|
5
6
|
*
|
|
6
7
|
* - `jobs` maps an upstream job name to its outputs record.
|
|
7
8
|
* - `groups` maps a dynamic group name to its ordered member job names.
|
|
9
|
+
* - `statuses` maps an upstream job name to its terminal status. Absent entries
|
|
10
|
+
* default to `success` (the only status that satisfies a default needs edge,
|
|
11
|
+
* so an upstream resolved into the snapshot is success unless told otherwise).
|
|
8
12
|
*/
|
|
9
13
|
export interface UpstreamSnapshot {
|
|
10
14
|
jobs: Record<string, Record<string, unknown>>;
|
|
11
15
|
groups: Record<string, string[]>;
|
|
16
|
+
statuses?: Record<string, ExecutionJobStatus>;
|
|
12
17
|
}
|
|
13
18
|
/** One entry in the array exposed for a `dynamicGroup(...)` need. */
|
|
14
19
|
export interface GroupNeedEntry {
|
|
15
20
|
name: string;
|
|
16
21
|
result: OutputProxy<any>;
|
|
22
|
+
status: ExecutionJobStatus;
|
|
17
23
|
}
|
|
18
|
-
/** A single-job need exposes `{ result }`; a group need exposes an ordered array. */
|
|
24
|
+
/** A single-job need exposes `{ result, status }`; a group need exposes an ordered array. */
|
|
19
25
|
export type NeedEntry = {
|
|
20
26
|
result: OutputProxy<any>;
|
|
27
|
+
status: ExecutionJobStatus;
|
|
21
28
|
} | GroupNeedEntry[];
|
|
22
29
|
/** The resolved `ctx.needs` map keyed by job name or group name. */
|
|
23
30
|
export type NeedsContext = Record<string, NeedEntry>;
|
|
24
31
|
/**
|
|
25
32
|
* Resolve declared needs against a frozen snapshot into the `ctx.needs` map.
|
|
26
33
|
*
|
|
27
|
-
* - A single static/named-job need resolves to `{ result: <proxy over jobs[name]
|
|
28
|
-
* - A `dynamicGroup(...)` need resolves to an ordered array of `{ name, result }`,
|
|
34
|
+
* - A single static/named-job need resolves to `{ result: <proxy over jobs[name]>, status }`.
|
|
35
|
+
* - A `dynamicGroup(...)` need resolves to an ordered array of `{ name, result, status }`,
|
|
29
36
|
* one entry per group member in the snapshot's deterministic eval order.
|
|
30
37
|
*/
|
|
31
38
|
export declare function buildNeedsContext(snapshot: UpstreamSnapshot, declaredNeeds: ReadonlyArray<DynamicJobNeed>): NeedsContext;
|
package/dist/needs-context.js
CHANGED
|
@@ -19,11 +19,15 @@ function needKey(need) {
|
|
|
19
19
|
key: need.name
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
|
+
/** Read an upstream's terminal status from the snapshot, defaulting to success. */
|
|
23
|
+
function statusFor(snapshot, name) {
|
|
24
|
+
return snapshot.statuses?.[name] ?? "success";
|
|
25
|
+
}
|
|
22
26
|
/**
|
|
23
27
|
* Resolve declared needs against a frozen snapshot into the `ctx.needs` map.
|
|
24
28
|
*
|
|
25
|
-
* - A single static/named-job need resolves to `{ result: <proxy over jobs[name]
|
|
26
|
-
* - A `dynamicGroup(...)` need resolves to an ordered array of `{ name, result }`,
|
|
29
|
+
* - A single static/named-job need resolves to `{ result: <proxy over jobs[name]>, status }`.
|
|
30
|
+
* - A `dynamicGroup(...)` need resolves to an ordered array of `{ name, result, status }`,
|
|
27
31
|
* one entry per group member in the snapshot's deterministic eval order.
|
|
28
32
|
*/
|
|
29
33
|
function buildNeedsContext(snapshot, declaredNeeds) {
|
|
@@ -32,9 +36,13 @@ function buildNeedsContext(snapshot, declaredNeeds) {
|
|
|
32
36
|
const { kind, key } = needKey(need);
|
|
33
37
|
if (kind === "group") out[key] = (snapshot.groups[key] ?? []).map((name) => ({
|
|
34
38
|
name,
|
|
35
|
-
result: createSnapshotOutputProxy(name, snapshot.jobs[name])
|
|
39
|
+
result: createSnapshotOutputProxy(name, snapshot.jobs[name]),
|
|
40
|
+
status: statusFor(snapshot, name)
|
|
36
41
|
}));
|
|
37
|
-
else out[key] = {
|
|
42
|
+
else out[key] = {
|
|
43
|
+
result: createSnapshotOutputProxy(key, snapshot.jobs[key]),
|
|
44
|
+
status: statusFor(snapshot, key)
|
|
45
|
+
};
|
|
38
46
|
}
|
|
39
47
|
return out;
|
|
40
48
|
}
|
package/dist/step.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Step, StepOptions, StepRunFn } from './types.js';
|
|
1
|
+
import type { Step, StepOptions, StepOptionsWithCheck, StepRunFn } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Create an id-less step with just a run function.
|
|
4
4
|
* The compiler assigns a counter-based ID (step-1, step-2, etc.) at lock file generation.
|
|
@@ -47,4 +47,24 @@ export declare function step(name: string, run: StepRunFn): Step<void>;
|
|
|
47
47
|
* });
|
|
48
48
|
*/
|
|
49
49
|
export declare function step<TResult = void>(name: string, options: StepOptions<TResult>): Step<TResult>;
|
|
50
|
+
/**
|
|
51
|
+
* Create a named idempotent step with a check facet.
|
|
52
|
+
*
|
|
53
|
+
* `check` returns a drift value (or null when in sync); `run` becomes the apply
|
|
54
|
+
* function and receives that drift; `summarize` renders the drift for logs and
|
|
55
|
+
* the dashboard. `whenInSync` optionally produces the outputs when already in sync.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* const nginx = step('configure-nginx', {
|
|
59
|
+
* check: async (ctx) => (await inSync(ctx)) ? null : { want: DESIRED },
|
|
60
|
+
* summarize: (drift) => `would rewrite nginx.conf (${drift.want.length} bytes)`,
|
|
61
|
+
* run: async (ctx, drift) => { await writeConfig(drift.want); return { reloaded: true }; },
|
|
62
|
+
* whenInSync: async () => ({ reloaded: false }),
|
|
63
|
+
* });
|
|
64
|
+
*/
|
|
65
|
+
export declare function step<TResult = void, TDrift = unknown>(name: string, options: StepOptionsWithCheck<TResult, TDrift>): Step<TResult>;
|
|
66
|
+
/**
|
|
67
|
+
* Create an id-less idempotent step with a check facet.
|
|
68
|
+
*/
|
|
69
|
+
export declare function step<TResult = void, TDrift = unknown>(options: StepOptionsWithCheck<TResult, TDrift>): Step<TResult>;
|
|
50
70
|
//# sourceMappingURL=step.d.ts.map
|
package/dist/step.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import "./chunk-BTugEXQM.js";
|
|
2
|
+
import { normalizeApproval } from "./approval.js";
|
|
2
3
|
import { createStepOutputProxy } from "./outputs.js";
|
|
3
4
|
//#region src/step.ts
|
|
4
5
|
/**
|
|
@@ -58,18 +59,24 @@ function step(nameOrRunOrOptions, runOrOptions) {
|
|
|
58
59
|
name = "";
|
|
59
60
|
options = nameOrRunOrOptions;
|
|
60
61
|
}
|
|
62
|
+
if (options.check && !options.summarize) throw new Error("summarize is required when check is set");
|
|
63
|
+
if (options.approval !== void 0 && normalizeApproval(options.approval).when === "drift" && !options.check) throw new Error("approval.when \"drift\" requires a check facet");
|
|
61
64
|
return {
|
|
62
65
|
_tag: "Step",
|
|
63
66
|
name,
|
|
64
67
|
outputs: options.outputs,
|
|
65
68
|
run: options.run,
|
|
69
|
+
...options.check !== void 0 && { check: options.check },
|
|
70
|
+
...options.summarize !== void 0 && { summarize: options.summarize },
|
|
71
|
+
...options.drift !== void 0 && { drift: options.drift },
|
|
72
|
+
...options.whenInSync !== void 0 && { whenInSync: options.whenInSync },
|
|
66
73
|
continueOnError: options.continueOnError,
|
|
67
74
|
timeout: options.timeout,
|
|
68
75
|
...options.cache !== void 0 && { cache: options.cache },
|
|
69
76
|
rules: options.rules,
|
|
70
77
|
onCancel: options.onCancel,
|
|
71
78
|
cleanup: options.cleanup,
|
|
72
|
-
...options.
|
|
79
|
+
...options.approval !== void 0 && { approval: options.approval },
|
|
73
80
|
_sourceLocation,
|
|
74
81
|
result: createStepOutputProxy(name)
|
|
75
82
|
};
|
package/dist/types.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { z } from 'zod';
|
|
2
2
|
import type { $ as Shell } from 'zx';
|
|
3
|
-
import type { ResourceRequest, RunsOnAllInput, OnUnreachableMode } from '@kici-dev/engine';
|
|
3
|
+
import type { ResourceRequest, RunsOnAllInput, OnUnreachableMode, NeedsWhen, ExecutionJobStatus } from '@kici-dev/engine';
|
|
4
4
|
import type { StepContext, Logger } from './context.js';
|
|
5
5
|
import type { TriggerConfig } from './triggers/types.js';
|
|
6
6
|
import type { Rule } from './rules/types.js';
|
|
@@ -9,8 +9,15 @@ import type { HookInput } from './hooks/types.js';
|
|
|
9
9
|
import type { KiciApi } from './api-types.js';
|
|
10
10
|
import type { DynamicGroupRef } from './dynamic-group.js';
|
|
11
11
|
import type { EventPayload } from './events/event-payloads.js';
|
|
12
|
-
import type {
|
|
13
|
-
export type { ResourceRequest, ResourceSpec, RunsOnAllInput, OnUnreachableMode, } from '@kici-dev/engine';
|
|
12
|
+
import type { ApprovalConfig } from './approval.js';
|
|
13
|
+
export type { ResourceRequest, ResourceSpec, RunsOnAllInput, OnUnreachableMode, NeedsWhen, } from '@kici-dev/engine';
|
|
14
|
+
/**
|
|
15
|
+
* Author-facing run condition for a `needs` edge: keyword sugar
|
|
16
|
+
* (`'on-success'` | `'always'` | `'on-skip'` | `'on-failure'`) or a raw set of
|
|
17
|
+
* upstream terminal statuses. Resolved to a normalized status-set at compile
|
|
18
|
+
* time; the downstream runs when the upstream's terminal status is a member.
|
|
19
|
+
*/
|
|
20
|
+
export type NeedsWhenInput = NeedsWhen | ExecutionJobStatus[];
|
|
14
21
|
/** Source location captured at a step() call site. */
|
|
15
22
|
export interface SourceLocation {
|
|
16
23
|
readonly file: string;
|
|
@@ -41,7 +48,18 @@ export interface Step<TResult = void> {
|
|
|
41
48
|
readonly name: string;
|
|
42
49
|
/** Optional Zod schema for runtime output validation. */
|
|
43
50
|
readonly outputs?: OutputSchema;
|
|
44
|
-
readonly run: (ctx: StepContext) => Promise<TResult>;
|
|
51
|
+
readonly run: (ctx: StepContext, drift?: any) => Promise<TResult>;
|
|
52
|
+
/**
|
|
53
|
+
* Read-only inspection for an idempotent step. Returns a drift value when run()
|
|
54
|
+
* would change state, or null when the system is already in the desired state.
|
|
55
|
+
*/
|
|
56
|
+
readonly check?: (ctx: StepContext) => Promise<unknown | null>;
|
|
57
|
+
/** Required when check is set: human-readable, serializable summary of the drift. */
|
|
58
|
+
readonly summarize?: (drift: any) => string;
|
|
59
|
+
/** Optional Zod schema validating the drift value. */
|
|
60
|
+
readonly drift?: z.ZodTypeAny;
|
|
61
|
+
/** Optional: produces the step's outputs when check() returns null (already in sync). */
|
|
62
|
+
readonly whenInSync?: (ctx: StepContext) => Promise<TResult>;
|
|
45
63
|
/** When true, job proceeds even if this step fails (recorded as failed but not fatal). */
|
|
46
64
|
readonly continueOnError?: boolean;
|
|
47
65
|
/** Step-level timeout in milliseconds. Overrides the agent's default (30 minutes). */
|
|
@@ -54,8 +72,8 @@ export interface Step<TResult = void> {
|
|
|
54
72
|
readonly onCancel?: HookInput;
|
|
55
73
|
/** Always runs after step (success, failure, or cancel). */
|
|
56
74
|
readonly cleanup?: HookInput;
|
|
57
|
-
/** Pause for a manual human approval before this step
|
|
58
|
-
readonly
|
|
75
|
+
/** Pause for a manual human approval (before this step, or on drift). */
|
|
76
|
+
readonly approval?: ApprovalConfig;
|
|
59
77
|
/** Internal: source location captured at step() call site. Not part of public API. */
|
|
60
78
|
readonly _sourceLocation?: SourceLocation;
|
|
61
79
|
/**
|
|
@@ -77,11 +95,13 @@ export type BareStepFn<TResult = void> = (ctx: StepContext) => Promise<TResult>;
|
|
|
77
95
|
export type StepInput = Step<any> | BareStepFn<any>;
|
|
78
96
|
/** Options for step() factory - simple form (just async function) */
|
|
79
97
|
export type StepRunFn = (ctx: StepContext) => Promise<void>;
|
|
80
|
-
/**
|
|
81
|
-
|
|
98
|
+
/**
|
|
99
|
+
* Facets shared by both the plain and the check variant of {@link StepOptions}.
|
|
100
|
+
* These compose unchanged whether or not a step declares a `check` facet.
|
|
101
|
+
*/
|
|
102
|
+
export interface StepOptionsBase {
|
|
82
103
|
/** Optional Zod schema for runtime output validation. */
|
|
83
104
|
outputs?: OutputSchema;
|
|
84
|
-
run: (ctx: StepContext) => Promise<TResult>;
|
|
85
105
|
/** When true, job proceeds even if this step fails (recorded as failed but not fatal). */
|
|
86
106
|
continueOnError?: boolean;
|
|
87
107
|
/** Step-level timeout in milliseconds. Overrides the agent's default (30 minutes). */
|
|
@@ -94,9 +114,45 @@ export interface StepOptions<TResult = void> {
|
|
|
94
114
|
onCancel?: HookInput;
|
|
95
115
|
/** Always runs after step (success, failure, or cancel). */
|
|
96
116
|
cleanup?: HookInput;
|
|
97
|
-
/** Pause for a manual human approval before this step
|
|
98
|
-
|
|
117
|
+
/** Pause for a manual human approval (before this step, or on drift). */
|
|
118
|
+
approval?: ApprovalConfig;
|
|
99
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Plain step options: `run` takes only the context — the existing, fully
|
|
122
|
+
* backward-compatible shape. No `check` facet.
|
|
123
|
+
*/
|
|
124
|
+
export interface StepOptionsPlain<TResult = void> extends StepOptionsBase {
|
|
125
|
+
run: (ctx: StepContext) => Promise<TResult>;
|
|
126
|
+
check?: undefined;
|
|
127
|
+
summarize?: undefined;
|
|
128
|
+
drift?: undefined;
|
|
129
|
+
whenInSync?: undefined;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Idempotent-step options: `check` declares read-only inspection, `run` becomes
|
|
133
|
+
* the *apply* function and receives the drift value `check` returned. `summarize`
|
|
134
|
+
* is required. `whenInSync` optionally produces the outputs when already in sync.
|
|
135
|
+
*
|
|
136
|
+
* `TDrift` is independent of `TResult` — one output shape per step (whichever of
|
|
137
|
+
* `run` / `whenInSync` executes), and a separate drift shape that `check` returns.
|
|
138
|
+
*/
|
|
139
|
+
export interface StepOptionsWithCheck<TResult = void, TDrift = unknown> extends StepOptionsBase {
|
|
140
|
+
/** Read-only inspection. Returns drift when run() would change state, or null when in sync. */
|
|
141
|
+
check: (ctx: StepContext) => Promise<TDrift | null>;
|
|
142
|
+
/** Required when check is set: human-readable, serializable summary of the drift. */
|
|
143
|
+
summarize: (drift: TDrift) => string;
|
|
144
|
+
/** Optional Zod schema validating the drift value. */
|
|
145
|
+
drift?: z.ZodTypeAny;
|
|
146
|
+
/** Apply: runs only when check returned drift (apply mode); receives that drift. */
|
|
147
|
+
run: (ctx: StepContext, drift: TDrift) => Promise<TResult>;
|
|
148
|
+
/** Optional: produces the step's outputs when check returned null (already in sync). */
|
|
149
|
+
whenInSync?: (ctx: StepContext) => Promise<TResult>;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Options for step() factory - full form with outputs and generic return type.
|
|
153
|
+
* Either the plain shape (`run(ctx)`) or the idempotent shape (`check` + `run(ctx, drift)`).
|
|
154
|
+
*/
|
|
155
|
+
export type StepOptions<TResult = void, TDrift = unknown> = StepOptionsPlain<TResult> | StepOptionsWithCheck<TResult, TDrift>;
|
|
100
156
|
/** Trigger type (config objects returned by pr()/push() factory functions) */
|
|
101
157
|
export type Trigger = TriggerConfig;
|
|
102
158
|
/**
|
|
@@ -200,10 +256,10 @@ declare const DYNAMIC_JOB_NEEDS_TAG: unique symbol;
|
|
|
200
256
|
*/
|
|
201
257
|
export type DynamicJobNeed = Job | string | DynamicGroupRef | {
|
|
202
258
|
name: string;
|
|
203
|
-
|
|
259
|
+
when?: NeedsWhenInput;
|
|
204
260
|
} | {
|
|
205
261
|
group: string;
|
|
206
|
-
|
|
262
|
+
when?: NeedsWhenInput;
|
|
207
263
|
};
|
|
208
264
|
/**
|
|
209
265
|
* Options-object form of {@link dynamicJob}: a result-aware generator that is
|
|
@@ -342,10 +398,10 @@ export interface Job {
|
|
|
342
398
|
readonly steps: readonly StepInput[];
|
|
343
399
|
readonly needs?: ReadonlyArray<Job | string | DynamicGroupRef | {
|
|
344
400
|
name: string;
|
|
345
|
-
|
|
401
|
+
when?: NeedsWhenInput;
|
|
346
402
|
} | {
|
|
347
403
|
group: string;
|
|
348
|
-
|
|
404
|
+
when?: NeedsWhenInput;
|
|
349
405
|
}>;
|
|
350
406
|
/** Rules for conditional execution */
|
|
351
407
|
readonly rules?: Rule[];
|
|
@@ -408,7 +464,7 @@ export interface Job {
|
|
|
408
464
|
/** Declarative cache: restored before steps, saved after the job on key miss. */
|
|
409
465
|
readonly cache?: import('./cache-types.js').CacheInput;
|
|
410
466
|
/** Pause for a manual human approval before this job dispatches. */
|
|
411
|
-
readonly
|
|
467
|
+
readonly approval?: ApprovalConfig;
|
|
412
468
|
/**
|
|
413
469
|
* Type-safe proxy for accessing this job's outputs.
|
|
414
470
|
* For multi-step jobs: jobRef.result.stepName.field
|
|
@@ -461,10 +517,10 @@ export interface JobOptions {
|
|
|
461
517
|
run?: (ctx: StepContext) => Promise<any>;
|
|
462
518
|
needs?: Array<Job | string | DynamicGroupRef | {
|
|
463
519
|
name: string;
|
|
464
|
-
|
|
520
|
+
when?: NeedsWhenInput;
|
|
465
521
|
} | {
|
|
466
522
|
group: string;
|
|
467
|
-
|
|
523
|
+
when?: NeedsWhenInput;
|
|
468
524
|
}>;
|
|
469
525
|
/** Rules that must pass for job to execute */
|
|
470
526
|
rules?: Rule[];
|
|
@@ -542,7 +598,7 @@ export interface JobOptions {
|
|
|
542
598
|
/** Declarative cache: restored before steps, saved after the job on key miss. */
|
|
543
599
|
cache?: import('./cache-types.js').CacheInput;
|
|
544
600
|
/** Pause for a manual human approval before this job dispatches. */
|
|
545
|
-
|
|
601
|
+
approval?: ApprovalConfig;
|
|
546
602
|
}
|
|
547
603
|
/**
|
|
548
604
|
* Private npm registry declaration. Tells the agent to authenticate against
|
|
@@ -621,7 +677,7 @@ export interface Workflow {
|
|
|
621
677
|
readonly max?: number;
|
|
622
678
|
};
|
|
623
679
|
/** Pause for a manual human approval before the whole workflow dispatches. */
|
|
624
|
-
readonly
|
|
680
|
+
readonly approval?: ApprovalConfig;
|
|
625
681
|
}
|
|
626
682
|
/** Options for workflow() factory */
|
|
627
683
|
export interface WorkflowOptions {
|
|
@@ -674,7 +730,7 @@ export interface WorkflowOptions {
|
|
|
674
730
|
max?: number;
|
|
675
731
|
};
|
|
676
732
|
/** Pause for a manual human approval before the whole workflow dispatches. */
|
|
677
|
-
|
|
733
|
+
approval?: ApprovalConfig;
|
|
678
734
|
}
|
|
679
735
|
export type { TriggerConfig, PrTriggerConfig, PushTriggerConfig } from './triggers/types.js';
|
|
680
736
|
export type { Rule, RuleContext, RuleCheckFn, RuleResult } from './rules/types.js';
|
package/dist/workflow.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kici-dev/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.22",
|
|
4
4
|
"description": "TypeScript SDK for defining KiCI workflows. Import into `.kici/workflows/*.ts` to declare workflows, jobs, steps, triggers, rules, and matrix configurations.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ci",
|
|
@@ -49,8 +49,8 @@
|
|
|
49
49
|
"micromatch": "^4.0.8",
|
|
50
50
|
"zod": "^4.4.3",
|
|
51
51
|
"zx": "^8.8.5",
|
|
52
|
-
"@kici-dev/core": "0.1.
|
|
53
|
-
"@kici-dev/engine": "0.1.
|
|
52
|
+
"@kici-dev/core": "0.1.22",
|
|
53
|
+
"@kici-dev/engine": "0.1.22"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@types/micromatch": "^4.0.10"
|
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/sdk@0.1.
|
|
6
|
-
"documentNamespace": "https://kici.dev/sbom/%40kici-dev%2Fsdk/0.1.
|
|
5
|
+
"name": "@kici-dev/sdk@0.1.22",
|
|
6
|
+
"documentNamespace": "https://kici.dev/sbom/%40kici-dev%2Fsdk/0.1.22/fea982d5-064e-481c-8436-fbd07a92a3c8",
|
|
7
7
|
"creationInfo": {
|
|
8
|
-
"created": "2026-06-
|
|
8
|
+
"created": "2026-06-24T06:03:05Z",
|
|
9
9
|
"creators": [
|
|
10
10
|
"Tool: kici-sbom-generator"
|
|
11
11
|
]
|
|
@@ -146,9 +146,9 @@
|
|
|
146
146
|
"homepage": "https://ericsmekens.github.io/jsep/tree/master/packages/regex#readme"
|
|
147
147
|
},
|
|
148
148
|
{
|
|
149
|
-
"SPDXID": "SPDXRef-Package--kici-dev-core-0.1.
|
|
149
|
+
"SPDXID": "SPDXRef-Package--kici-dev-core-0.1.22",
|
|
150
150
|
"name": "@kici-dev/core",
|
|
151
|
-
"versionInfo": "0.1.
|
|
151
|
+
"versionInfo": "0.1.22",
|
|
152
152
|
"downloadLocation": "NOASSERTION",
|
|
153
153
|
"filesAnalyzed": false,
|
|
154
154
|
"licenseConcluded": "NOASSERTION",
|
|
@@ -159,16 +159,16 @@
|
|
|
159
159
|
{
|
|
160
160
|
"referenceCategory": "PACKAGE-MANAGER",
|
|
161
161
|
"referenceType": "purl",
|
|
162
|
-
"referenceLocator": "pkg:npm/%40kici-dev/core@0.1.
|
|
162
|
+
"referenceLocator": "pkg:npm/%40kici-dev/core@0.1.22"
|
|
163
163
|
}
|
|
164
164
|
],
|
|
165
165
|
"description": "Light shared utilities for the KiCI stack (logging, errors, formatting, crypto, zx init, the TypeScript ESM loader hook). No server-side dependencies.",
|
|
166
166
|
"homepage": "https://kici.dev"
|
|
167
167
|
},
|
|
168
168
|
{
|
|
169
|
-
"SPDXID": "SPDXRef-Package--kici-dev-engine-0.1.
|
|
169
|
+
"SPDXID": "SPDXRef-Package--kici-dev-engine-0.1.22",
|
|
170
170
|
"name": "@kici-dev/engine",
|
|
171
|
-
"versionInfo": "0.1.
|
|
171
|
+
"versionInfo": "0.1.22",
|
|
172
172
|
"downloadLocation": "NOASSERTION",
|
|
173
173
|
"filesAnalyzed": false,
|
|
174
174
|
"licenseConcluded": "NOASSERTION",
|
|
@@ -179,7 +179,7 @@
|
|
|
179
179
|
{
|
|
180
180
|
"referenceCategory": "PACKAGE-MANAGER",
|
|
181
181
|
"referenceType": "purl",
|
|
182
|
-
"referenceLocator": "pkg:npm/%40kici-dev/engine@0.1.
|
|
182
|
+
"referenceLocator": "pkg:npm/%40kici-dev/engine@0.1.22"
|
|
183
183
|
}
|
|
184
184
|
],
|
|
185
185
|
"description": "Shared business logic for the KiCI CI/CD stack: protocol, triggers, state machine, and provider interfaces used by the Platform relay, orchestrator, and compiler.",
|
|
@@ -188,7 +188,7 @@
|
|
|
188
188
|
{
|
|
189
189
|
"SPDXID": "SPDXRef-RootPackage",
|
|
190
190
|
"name": "@kici-dev/sdk",
|
|
191
|
-
"versionInfo": "0.1.
|
|
191
|
+
"versionInfo": "0.1.22",
|
|
192
192
|
"downloadLocation": "NOASSERTION",
|
|
193
193
|
"filesAnalyzed": false,
|
|
194
194
|
"licenseConcluded": "NOASSERTION",
|
|
@@ -199,7 +199,7 @@
|
|
|
199
199
|
{
|
|
200
200
|
"referenceCategory": "PACKAGE-MANAGER",
|
|
201
201
|
"referenceType": "purl",
|
|
202
|
-
"referenceLocator": "pkg:npm/%40kici-dev/sdk@0.1.
|
|
202
|
+
"referenceLocator": "pkg:npm/%40kici-dev/sdk@0.1.22"
|
|
203
203
|
}
|
|
204
204
|
],
|
|
205
205
|
"description": "TypeScript SDK for defining KiCI workflows. Import into `.kici/workflows/*.ts` to declare workflows, jobs, steps, triggers, rules, and matrix configurations.",
|
|
@@ -1584,68 +1584,68 @@
|
|
|
1584
1584
|
"relationshipType": "DEPENDS_ON"
|
|
1585
1585
|
},
|
|
1586
1586
|
{
|
|
1587
|
-
"spdxElementId": "SPDXRef-Package--kici-dev-core-0.1.
|
|
1587
|
+
"spdxElementId": "SPDXRef-Package--kici-dev-core-0.1.22",
|
|
1588
1588
|
"relatedSpdxElement": "SPDXRef-Package-oxc-transform-0.135.0",
|
|
1589
1589
|
"relationshipType": "DEPENDS_ON"
|
|
1590
1590
|
},
|
|
1591
1591
|
{
|
|
1592
|
-
"spdxElementId": "SPDXRef-Package--kici-dev-core-0.1.
|
|
1592
|
+
"spdxElementId": "SPDXRef-Package--kici-dev-core-0.1.22",
|
|
1593
1593
|
"relatedSpdxElement": "SPDXRef-Package-picocolors-1.1.1",
|
|
1594
1594
|
"relationshipType": "DEPENDS_ON"
|
|
1595
1595
|
},
|
|
1596
1596
|
{
|
|
1597
|
-
"spdxElementId": "SPDXRef-Package--kici-dev-core-0.1.
|
|
1597
|
+
"spdxElementId": "SPDXRef-Package--kici-dev-core-0.1.22",
|
|
1598
1598
|
"relatedSpdxElement": "SPDXRef-Package-winston-daily-rotate-file-5.0.0",
|
|
1599
1599
|
"relationshipType": "DEPENDS_ON"
|
|
1600
1600
|
},
|
|
1601
1601
|
{
|
|
1602
|
-
"spdxElementId": "SPDXRef-Package--kici-dev-core-0.1.
|
|
1602
|
+
"spdxElementId": "SPDXRef-Package--kici-dev-core-0.1.22",
|
|
1603
1603
|
"relatedSpdxElement": "SPDXRef-Package-winston-3.19.0",
|
|
1604
1604
|
"relationshipType": "DEPENDS_ON"
|
|
1605
1605
|
},
|
|
1606
1606
|
{
|
|
1607
|
-
"spdxElementId": "SPDXRef-Package--kici-dev-core-0.1.
|
|
1607
|
+
"spdxElementId": "SPDXRef-Package--kici-dev-core-0.1.22",
|
|
1608
1608
|
"relatedSpdxElement": "SPDXRef-Package-zod-4.4.3",
|
|
1609
1609
|
"relationshipType": "DEPENDS_ON"
|
|
1610
1610
|
},
|
|
1611
1611
|
{
|
|
1612
|
-
"spdxElementId": "SPDXRef-Package--kici-dev-core-0.1.
|
|
1612
|
+
"spdxElementId": "SPDXRef-Package--kici-dev-core-0.1.22",
|
|
1613
1613
|
"relatedSpdxElement": "SPDXRef-Package-zx-8.8.5",
|
|
1614
1614
|
"relationshipType": "DEPENDS_ON"
|
|
1615
1615
|
},
|
|
1616
1616
|
{
|
|
1617
|
-
"spdxElementId": "SPDXRef-Package--kici-dev-engine-0.1.
|
|
1617
|
+
"spdxElementId": "SPDXRef-Package--kici-dev-engine-0.1.22",
|
|
1618
1618
|
"relatedSpdxElement": "SPDXRef-Package-jose-6.2.3",
|
|
1619
1619
|
"relationshipType": "DEPENDS_ON"
|
|
1620
1620
|
},
|
|
1621
1621
|
{
|
|
1622
|
-
"spdxElementId": "SPDXRef-Package--kici-dev-engine-0.1.
|
|
1622
|
+
"spdxElementId": "SPDXRef-Package--kici-dev-engine-0.1.22",
|
|
1623
1623
|
"relatedSpdxElement": "SPDXRef-Package-jsonpath-plus-10.4.0",
|
|
1624
1624
|
"relationshipType": "DEPENDS_ON"
|
|
1625
1625
|
},
|
|
1626
1626
|
{
|
|
1627
|
-
"spdxElementId": "SPDXRef-Package--kici-dev-engine-0.1.
|
|
1627
|
+
"spdxElementId": "SPDXRef-Package--kici-dev-engine-0.1.22",
|
|
1628
1628
|
"relatedSpdxElement": "SPDXRef-Package-picomatch-4.0.4",
|
|
1629
1629
|
"relationshipType": "DEPENDS_ON"
|
|
1630
1630
|
},
|
|
1631
1631
|
{
|
|
1632
|
-
"spdxElementId": "SPDXRef-Package--kici-dev-engine-0.1.
|
|
1632
|
+
"spdxElementId": "SPDXRef-Package--kici-dev-engine-0.1.22",
|
|
1633
1633
|
"relatedSpdxElement": "SPDXRef-Package-safe-regex-2.1.1",
|
|
1634
1634
|
"relationshipType": "DEPENDS_ON"
|
|
1635
1635
|
},
|
|
1636
1636
|
{
|
|
1637
|
-
"spdxElementId": "SPDXRef-Package--kici-dev-engine-0.1.
|
|
1637
|
+
"spdxElementId": "SPDXRef-Package--kici-dev-engine-0.1.22",
|
|
1638
1638
|
"relatedSpdxElement": "SPDXRef-Package-zod-4.4.3",
|
|
1639
1639
|
"relationshipType": "DEPENDS_ON"
|
|
1640
1640
|
},
|
|
1641
1641
|
{
|
|
1642
1642
|
"spdxElementId": "SPDXRef-RootPackage",
|
|
1643
|
-
"relatedSpdxElement": "SPDXRef-Package--kici-dev-core-0.1.
|
|
1643
|
+
"relatedSpdxElement": "SPDXRef-Package--kici-dev-core-0.1.22",
|
|
1644
1644
|
"relationshipType": "DEPENDS_ON"
|
|
1645
1645
|
},
|
|
1646
1646
|
{
|
|
1647
1647
|
"spdxElementId": "SPDXRef-RootPackage",
|
|
1648
|
-
"relatedSpdxElement": "SPDXRef-Package--kici-dev-engine-0.1.
|
|
1648
|
+
"relatedSpdxElement": "SPDXRef-Package--kici-dev-engine-0.1.22",
|
|
1649
1649
|
"relationshipType": "DEPENDS_ON"
|
|
1650
1650
|
},
|
|
1651
1651
|
{
|