@kici-dev/sdk 0.1.22 → 0.1.24
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 +8 -1
- package/dist/context.d.ts +22 -2
- package/dist/fanout-context.d.ts +21 -0
- package/dist/fanout-context.js +2 -0
- package/dist/fixture.d.ts +3 -3
- package/dist/fixture.js +1 -1
- package/dist/idempotent.d.ts +32 -1
- package/dist/idempotent.js +26 -1
- package/dist/index.d.ts +9 -6
- package/dist/index.js +5 -3
- package/dist/job.js +7 -1
- package/dist/parallel.d.ts +40 -0
- package/dist/parallel.js +37 -0
- package/dist/rules/index.d.ts +1 -1
- package/dist/rules/index.js +2 -2
- package/dist/rules/rule.d.ts +20 -0
- package/dist/rules/rule.js +27 -1
- package/dist/rules/types.d.ts +9 -0
- package/dist/secrets.d.ts +1 -1
- package/dist/step.js +18 -0
- package/dist/triggers/dispatch-inputs.d.ts +32 -0
- package/dist/triggers/dispatch-inputs.js +21 -0
- package/dist/triggers/dispatch.js +5 -1
- package/dist/triggers/index.d.ts +3 -1
- package/dist/triggers/index.js +2 -1
- package/dist/triggers/schedule.d.ts +3 -0
- package/dist/triggers/schedule.js +8 -1
- package/dist/triggers/types.d.ts +32 -0
- package/dist/types.d.ts +79 -4
- package/package.json +3 -3
- package/sbom.spdx.json +24 -24
package/dist/api-types.d.ts
CHANGED
|
@@ -74,6 +74,40 @@ export interface HostApi {
|
|
|
74
74
|
deadlineMs?: number;
|
|
75
75
|
}): Promise<void>;
|
|
76
76
|
}
|
|
77
|
+
export interface BootstrapApi {
|
|
78
|
+
/**
|
|
79
|
+
* Bring up a temporary privileged init-runner on a declared-but-un-agented
|
|
80
|
+
* host over SSH, so it auto-enrolls as a short-lived `kici:init` agent. The
|
|
81
|
+
* step calling this must run on an agent holding the
|
|
82
|
+
* `kici:capability:ssh-transport` capability (the orchestrator refuses
|
|
83
|
+
* otherwise). No-op (`broughtUp: false`) when the target already has a live
|
|
84
|
+
* agent. Each bring-up is access-logged.
|
|
85
|
+
*
|
|
86
|
+
* The target's reach metadata + the bring-up SSH key (a scoped secret) are
|
|
87
|
+
* resolved server-side from the host roster — the workflow author supplies
|
|
88
|
+
* only the target agent id.
|
|
89
|
+
*/
|
|
90
|
+
ensureInitRunner(targetAgentId: string): Promise<{
|
|
91
|
+
broughtUp: boolean;
|
|
92
|
+
}>;
|
|
93
|
+
/**
|
|
94
|
+
* Ship an input to a host's pre-boot SSH channel (e.g. a LUKS passphrase to
|
|
95
|
+
* a dropbear/initramfs `cryptroot-unlock` prompt on port 2222). Generic
|
|
96
|
+
* "pipe stdin to a forced-command endpoint"; the unlock recipe is
|
|
97
|
+
* per-host-passphrase → `preBootSend` → `waitForHostAlive`. Same
|
|
98
|
+
* `kici:capability:ssh-transport` gate + access-log as `ensureInitRunner`.
|
|
99
|
+
*
|
|
100
|
+
* `inputSecret` is a scoped-secret ref (`scope/key`) the orchestrator
|
|
101
|
+
* resolves server-side; the plaintext never passes through the workflow.
|
|
102
|
+
* Success is the send completing (the session drops as the box boots) —
|
|
103
|
+
* compose `restartHost`/host-alive waits to confirm the boot.
|
|
104
|
+
*/
|
|
105
|
+
preBootSend(targetAgentId: string, opts: {
|
|
106
|
+
inputSecret: string;
|
|
107
|
+
port?: number;
|
|
108
|
+
command?: string;
|
|
109
|
+
}): Promise<void>;
|
|
110
|
+
}
|
|
77
111
|
export interface KiciApi {
|
|
78
112
|
/** Query orchestrator infrastructure (scalers, agents). */
|
|
79
113
|
infrastructure: InfrastructureApi;
|
|
@@ -83,6 +117,8 @@ export interface KiciApi {
|
|
|
83
117
|
oidc: OidcApi;
|
|
84
118
|
/** Host-lifecycle operations on the agent's own host (e.g. reboot). */
|
|
85
119
|
host: HostApi;
|
|
120
|
+
/** Fresh-box bootstrap bring-up (init-runner over SSH, pre-boot unlock). */
|
|
121
|
+
bootstrap: BootstrapApi;
|
|
86
122
|
}
|
|
87
123
|
/**
|
|
88
124
|
* Low-level transport function used to implement KiciApi.
|
package/dist/api-types.js
CHANGED
|
@@ -37,7 +37,14 @@ function buildKiciApi(transport, jobCtx) {
|
|
|
37
37
|
audience: opts.audience
|
|
38
38
|
});
|
|
39
39
|
} },
|
|
40
|
-
host: { requestReboot: (opts) => transport("host.requestReboot", { ...opts?.deadlineMs !== void 0 ? { deadlineMs: opts.deadlineMs } : {} }) }
|
|
40
|
+
host: { requestReboot: (opts) => transport("host.requestReboot", { ...opts?.deadlineMs !== void 0 ? { deadlineMs: opts.deadlineMs } : {} }) },
|
|
41
|
+
bootstrap: {
|
|
42
|
+
ensureInitRunner: (targetAgentId) => transport("kici.ensureInitRunner", { targetAgentId }),
|
|
43
|
+
preBootSend: (targetAgentId, opts) => transport("kici.preBootSend", {
|
|
44
|
+
targetAgentId,
|
|
45
|
+
...opts
|
|
46
|
+
})
|
|
47
|
+
}
|
|
41
48
|
};
|
|
42
49
|
}
|
|
43
50
|
//#endregion
|
package/dist/context.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { MatrixValues } from './matrix/types.js';
|
|
|
3
3
|
import type { EventEmitOptions } from './events/types.js';
|
|
4
4
|
import type { StepSecrets } from './secrets.js';
|
|
5
5
|
import type { KiciApi } from './api-types.js';
|
|
6
|
+
import type { FanoutPosition } from './fanout-context.js';
|
|
6
7
|
/** Logger interface for step execution */
|
|
7
8
|
export interface Logger {
|
|
8
9
|
info(message: string, ...args: unknown[]): void;
|
|
@@ -113,8 +114,21 @@ export interface StepContext<TInputs = Record<string, unknown>> {
|
|
|
113
114
|
setEnv(key: string, value: string): void;
|
|
114
115
|
/** Prepend a directory to PATH, visible to this step and all subsequent steps. */
|
|
115
116
|
addPath(dir: string): void;
|
|
117
|
+
/**
|
|
118
|
+
* Aborted when this step should stop early — the job is being cancelled, the
|
|
119
|
+
* job-level timeout fired, or (in a `parallel()` group) a sibling failed under
|
|
120
|
+
* fail-fast. Pass it to `fetch`, `ctx.$`, timers, or any cancellable async work
|
|
121
|
+
* to cooperatively unwind. Unaborted for a normally-running step.
|
|
122
|
+
*/
|
|
123
|
+
signal: AbortSignal;
|
|
116
124
|
/** Typed inputs from dependencies */
|
|
117
125
|
inputs: TInputs;
|
|
126
|
+
/**
|
|
127
|
+
* Operator-supplied, validated + coerced workflow-dispatch inputs (from `dispatch({ inputs })`).
|
|
128
|
+
* Distinct from `inputs` (typed outputs from `needs` dependencies). Empty when none declared.
|
|
129
|
+
* Prefer the typed `defineDispatchInputs(...).from(ctx)` accessor for per-key types.
|
|
130
|
+
*/
|
|
131
|
+
dispatchInputs: Readonly<Record<string, string | number | boolean | null>>;
|
|
118
132
|
/** Current workflow metadata */
|
|
119
133
|
workflow: WorkflowInfo;
|
|
120
134
|
/** Current job metadata */
|
|
@@ -137,10 +151,16 @@ export interface StepContext<TInputs = Record<string, unknown>> {
|
|
|
137
151
|
* platform, arch). Set only for jobs that use `runsOnAll`. Undefined otherwise.
|
|
138
152
|
*/
|
|
139
153
|
agent?: AgentInfo;
|
|
154
|
+
/**
|
|
155
|
+
* Position of this child within its fan-out (a `runsOnAll` host or a matrix
|
|
156
|
+
* combination), deterministically ordered (host: by `agentId`; matrix: by
|
|
157
|
+
* variant label). Undefined on a non-fan-out job.
|
|
158
|
+
*/
|
|
159
|
+
fanout?: FanoutPosition;
|
|
140
160
|
/**
|
|
141
161
|
* Raw webhook payload from the git provider.
|
|
142
162
|
* Contains the full, unmodified payload as received from the webhook.
|
|
143
|
-
* In local
|
|
163
|
+
* In local preview/run mode (`kici preview` / `kici run local`), contains the simulated payload.
|
|
144
164
|
* Use this for provider-specific data not covered by normalized fields.
|
|
145
165
|
*/
|
|
146
166
|
rawPayload?: Record<string, unknown>;
|
|
@@ -151,7 +171,7 @@ export interface StepContext<TInputs = Record<string, unknown>> {
|
|
|
151
171
|
*/
|
|
152
172
|
provider?: string;
|
|
153
173
|
/**
|
|
154
|
-
* Whether this execution was triggered by `kici
|
|
174
|
+
* Whether this execution was triggered by `kici run remote` (developer-initiated remote run).
|
|
155
175
|
* Use to conditionally skip destructive operations in test mode.
|
|
156
176
|
* Defaults to false for backward compatibility.
|
|
157
177
|
*/
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic position of a fan-out child within its fan-out.
|
|
3
|
+
*
|
|
4
|
+
* A fan-out child is one of:
|
|
5
|
+
* - a `runsOnAll` host execution (one pinned execution per matching roster host), or
|
|
6
|
+
* - a matrix combination (one execution per expanded combination).
|
|
7
|
+
*
|
|
8
|
+
* The order is deterministic: host fan-out is sorted by `agentId`, matrix fan-out by
|
|
9
|
+
* its variant label, so `first` is always reproducible across re-runs.
|
|
10
|
+
*/
|
|
11
|
+
export interface FanoutPosition {
|
|
12
|
+
/** 0-based position in the deterministically-ordered fan-out. */
|
|
13
|
+
index: number;
|
|
14
|
+
/** Number of children in this fan-out. */
|
|
15
|
+
total: number;
|
|
16
|
+
/** Whether this is the first child (`index === 0`). */
|
|
17
|
+
first: boolean;
|
|
18
|
+
/** Whether this is the last child (`index === total - 1`). */
|
|
19
|
+
last: boolean;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=fanout-context.d.ts.map
|
package/dist/fixture.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Fixture factory for defining test event replicas.
|
|
3
3
|
*
|
|
4
4
|
* Fixtures declare which trigger event to simulate when running
|
|
5
|
-
* `kici
|
|
5
|
+
* `kici run remote <name>`. They are event replicas (not assertions) --
|
|
6
6
|
* pass/fail is determined by the pipeline execution.
|
|
7
7
|
*/
|
|
8
8
|
import type { TriggerConfig } from './triggers/types.js';
|
|
@@ -25,7 +25,7 @@ export interface FixtureOptions {
|
|
|
25
25
|
}
|
|
26
26
|
/** Resolved fixture definition */
|
|
27
27
|
export interface Fixture {
|
|
28
|
-
/** Unique fixture ID used in `kici
|
|
28
|
+
/** Unique fixture ID used in `kici run remote <name>` */
|
|
29
29
|
readonly id: string;
|
|
30
30
|
/** Fixture options (plain object or async factory function) */
|
|
31
31
|
readonly options: FixtureOptions | (() => FixtureOptions | Promise<FixtureOptions>);
|
|
@@ -33,7 +33,7 @@ export interface Fixture {
|
|
|
33
33
|
/**
|
|
34
34
|
* Create a test fixture definition.
|
|
35
35
|
*
|
|
36
|
-
* @param id - Unique fixture ID (no whitespace allowed, used in `kici
|
|
36
|
+
* @param id - Unique fixture ID (no whitespace allowed, used in `kici run remote <name>`)
|
|
37
37
|
* @param options - Fixture configuration or async factory function
|
|
38
38
|
* @returns Frozen fixture definition
|
|
39
39
|
*
|
package/dist/fixture.js
CHANGED
|
@@ -3,7 +3,7 @@ import "./chunk-BTugEXQM.js";
|
|
|
3
3
|
/**
|
|
4
4
|
* Create a test fixture definition.
|
|
5
5
|
*
|
|
6
|
-
* @param id - Unique fixture ID (no whitespace allowed, used in `kici
|
|
6
|
+
* @param id - Unique fixture ID (no whitespace allowed, used in `kici run remote <name>`)
|
|
7
7
|
* @param options - Fixture configuration or async factory function
|
|
8
8
|
* @returns Frozen fixture definition
|
|
9
9
|
*
|
package/dist/idempotent.d.ts
CHANGED
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
* whose run function executes `idempotent(...)` and propagates ctx.log
|
|
22
22
|
* into the runner's status sink.
|
|
23
23
|
*/
|
|
24
|
-
import type { Step } from './types.js';
|
|
24
|
+
import type { Step, StepOptionsBase } from './types.js';
|
|
25
|
+
import type { StepContext } from './context.js';
|
|
25
26
|
export interface IdempotentOptions<TDrift, TInSync = void, TApplied = void> {
|
|
26
27
|
/** Optional name surfaced in status lines and error messages. */
|
|
27
28
|
name?: string;
|
|
@@ -68,4 +69,34 @@ export declare function idempotent<TDrift, TInSync = void, TApplied = void>(opts
|
|
|
68
69
|
* The step's typed return value is the IdempotentResult union.
|
|
69
70
|
*/
|
|
70
71
|
export declare function idempotentStep<TDrift, TInSync = void, TApplied = void>(name: string, opts: Omit<IdempotentOptions<TDrift, TInSync, TApplied>, 'name' | 'log'>): Step<IdempotentResult<TDrift, TInSync, TApplied>>;
|
|
72
|
+
/**
|
|
73
|
+
* Options for {@link checkStep}. The same shape as `idempotentStep`'s options,
|
|
74
|
+
* except `apply` and `whenInSync` receive `ctx` first (matching the `step()`
|
|
75
|
+
* check facet's `run(ctx, drift)` form) so the apply logic has access to
|
|
76
|
+
* `ctx.$` / `ctx.log` / `ctx.secrets`. The remaining `StepOptionsBase`
|
|
77
|
+
* passthroughs (`continueOnError`, `timeout`, `rules`, `outputs`, `retry`, …)
|
|
78
|
+
* are forwarded to the underlying step.
|
|
79
|
+
*/
|
|
80
|
+
export interface CheckStepOptions<TDrift, TInSync = void, TApplied = void> extends Omit<StepOptionsBase, 'onCancel' | 'cleanup' | 'approval'> {
|
|
81
|
+
/** Read-only inspection: drift if apply would change state, or null if in sync. */
|
|
82
|
+
check: (ctx: StepContext) => Promise<TDrift | null>;
|
|
83
|
+
/** Brings the system to the desired state. Runs only in apply mode (skipped under `kici run --check`). */
|
|
84
|
+
apply: (ctx: StepContext, drift: TDrift) => Promise<TApplied>;
|
|
85
|
+
/** Required: human-readable summary of what apply() would do; shown in check-mode drift output. */
|
|
86
|
+
summarize: (drift: TDrift) => string;
|
|
87
|
+
/** Runs when check() returns null (already in sync). */
|
|
88
|
+
whenInSync?: (ctx: StepContext) => Promise<TInSync>;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Factory returning a check-facet SDK Step — the check-mode-aware sibling of
|
|
92
|
+
* {@link idempotentStep}. Unlike `idempotentStep` (which always applies on
|
|
93
|
+
* drift), a `checkStep` respects the run-level check mode: `kici run --check`
|
|
94
|
+
* reports the drift and skips `apply`, while apply mode applies it.
|
|
95
|
+
*
|
|
96
|
+
* It desugars to the `step()` check facet
|
|
97
|
+
* (`run: (ctx, drift) => apply(ctx, drift)`), so it inherits the agent
|
|
98
|
+
* step-loop and local-executor check-mode drive for free — no engine, agent,
|
|
99
|
+
* orchestrator, or lockfile change.
|
|
100
|
+
*/
|
|
101
|
+
export declare function checkStep<TDrift, TInSync = void, TApplied = void>(name: string, options: CheckStepOptions<TDrift, TInSync, TApplied>): Step<TApplied | TInSync>;
|
|
71
102
|
//# sourceMappingURL=idempotent.d.ts.map
|
package/dist/idempotent.js
CHANGED
|
@@ -71,7 +71,32 @@ function idempotentStep(name, opts) {
|
|
|
71
71
|
log: (line) => ctx.log.info(line)
|
|
72
72
|
}) });
|
|
73
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Factory returning a check-facet SDK Step — the check-mode-aware sibling of
|
|
76
|
+
* {@link idempotentStep}. Unlike `idempotentStep` (which always applies on
|
|
77
|
+
* drift), a `checkStep` respects the run-level check mode: `kici run --check`
|
|
78
|
+
* reports the drift and skips `apply`, while apply mode applies it.
|
|
79
|
+
*
|
|
80
|
+
* It desugars to the `step()` check facet
|
|
81
|
+
* (`run: (ctx, drift) => apply(ctx, drift)`), so it inherits the agent
|
|
82
|
+
* step-loop and local-executor check-mode drive for free — no engine, agent,
|
|
83
|
+
* orchestrator, or lockfile change.
|
|
84
|
+
*/
|
|
85
|
+
function checkStep(name, options) {
|
|
86
|
+
return step(name, {
|
|
87
|
+
check: options.check,
|
|
88
|
+
summarize: options.summarize,
|
|
89
|
+
run: (ctx, drift) => options.apply(ctx, drift),
|
|
90
|
+
...options.whenInSync && { whenInSync: options.whenInSync },
|
|
91
|
+
...options.outputs !== void 0 && { outputs: options.outputs },
|
|
92
|
+
...options.continueOnError !== void 0 && { continueOnError: options.continueOnError },
|
|
93
|
+
...options.timeout !== void 0 && { timeout: options.timeout },
|
|
94
|
+
...options.retry !== void 0 && { retry: options.retry },
|
|
95
|
+
...options.cache !== void 0 && { cache: options.cache },
|
|
96
|
+
...options.rules !== void 0 && { rules: options.rules }
|
|
97
|
+
});
|
|
98
|
+
}
|
|
74
99
|
//#endregion
|
|
75
|
-
export { idempotent, idempotentStep };
|
|
100
|
+
export { checkStep, idempotent, idempotentStep };
|
|
76
101
|
|
|
77
102
|
//# sourceMappingURL=idempotent.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
export { step } from './step.js';
|
|
2
2
|
export { job } from './job.js';
|
|
3
3
|
export { workflow } from './workflow.js';
|
|
4
|
+
export { parallel, isParallelGroup, flattenStepInputs } from './parallel.js';
|
|
5
|
+
export type { ParallelGroup, ParallelOptions } from './parallel.js';
|
|
4
6
|
export { normalizeApproval } from './approval.js';
|
|
5
7
|
export type { ApprovalConfig, ApprovalWhen, ApproverClause, NormalizedApproval, } from './approval.js';
|
|
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
|
-
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
|
+
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, defineDispatchInputs, } from './triggers/index.js';
|
|
9
|
+
export type { DefinedDispatchInputs, InferDispatchInputs, DispatchInputsMap, 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
10
|
export { onCancel, cleanup, onSuccess, onFailure, beforeStep, afterStep } from './hooks/index.js';
|
|
9
11
|
export type { HookConfig, HookFn, HookInput, HookContext, OutcomeMetadata } from './hooks/index.js';
|
|
10
|
-
export { rule, skip } from './rules/index.js';
|
|
12
|
+
export { rule, skip, onlyOnFirstHost, onlyOnLastHost, onlyOnFanoutIndex } from './rules/index.js';
|
|
11
13
|
export { evaluateRules } from './rules/index.js';
|
|
12
14
|
export { isEventType } from './rules/index.js';
|
|
13
15
|
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
16
|
export { validateDag } from './validation/index.js';
|
|
15
17
|
export type { DagNode, DagValidationResult } from './validation/index.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';
|
|
18
|
+
export type { SourceLocation, OutputProxy, Step, StepOptions, StepOptionsBase, StepOptionsPlain, StepOptionsWithCheck, StepRunFn, RetryConfig, NormalizedRetry, BareStepFn, StepInput, OutputSchema, InferOutputs, Job, JobOptions, GenericInitConfig, MiseInitConfig, InitPreset, InitItem, InitConfig, ContainerConfig, RunsOnSelector, RunsOn, RunsOnPick, Workflow, WorkflowOptions, Registry, Trigger, DynamicJobFn, DynamicJobContext, JobOrFactory, } from './types.js';
|
|
17
19
|
export { isDynamicJobFn, dynamicJob, getDynamicJobGroup, getDynamicJobNeeds, DYNAMIC_JOB_GROUP_TAG, DYNAMIC_JOB_NEEDS_TAG, } from './types.js';
|
|
18
20
|
export type { TaggedDynamicJobFn, ResultAwareDynamicJobConfig, ResultAwareDynamicJobFn, DynamicJobNeed, NeedsWhen, NeedsWhenInput, } from './types.js';
|
|
19
21
|
export { buildNeedsContext } from './needs-context.js';
|
|
@@ -27,6 +29,7 @@ export { dynamicGroup, isDynamicGroupRef, DYNAMIC_GROUP_TAG } from './dynamic-gr
|
|
|
27
29
|
export type { DynamicGroupRef } from './dynamic-group.js';
|
|
28
30
|
export type { StepContext, Logger, WorkflowInfo, JobInfo, AgentInfo, MatrixJobOutputs, HostJobOutputs, RepoInfo, StepSecretsTyped, KnownSecretKeys, } from './context.js';
|
|
29
31
|
export { isMatrixJobOutputs, isHostJobOutputs } from './context.js';
|
|
32
|
+
export type { FanoutPosition } from './fanout-context.js';
|
|
30
33
|
export { buildKiciApi } from './api-types.js';
|
|
31
34
|
export type { KiciApi, KiciApiTransport, InfrastructureApi, InfrastructureListResult, InventoryApi, HostApi, HostInventoryEntry, InventorySelector, } from './api-types.js';
|
|
32
35
|
export { SecretNotFoundError } from './errors.js';
|
|
@@ -42,8 +45,8 @@ export type { EventDefinition } from './events/index.js';
|
|
|
42
45
|
export type { EventEmitOptions } from './events/index.js';
|
|
43
46
|
export { fixture } from './fixture.js';
|
|
44
47
|
export type { Fixture, FixtureOptions } from './fixture.js';
|
|
45
|
-
export { idempotent, idempotentStep } from './idempotent.js';
|
|
46
|
-
export type { IdempotentOptions, IdempotentResult } from './idempotent.js';
|
|
48
|
+
export { idempotent, idempotentStep, checkStep } from './idempotent.js';
|
|
49
|
+
export type { IdempotentOptions, IdempotentResult, CheckStepOptions } from './idempotent.js';
|
|
47
50
|
export { waitFor, waitForStep, WaitForTimeoutError } from './wait-for.js';
|
|
48
51
|
export type { WaitForOptions, WaitForResult } from './wait-for.js';
|
|
49
52
|
export { waitForHostAlive, restartHost } from './host-restart.js';
|
package/dist/index.js
CHANGED
|
@@ -10,9 +10,10 @@ import { createJobOutputProxy, createSnapshotOutputProxy, createStepOutputProxy,
|
|
|
10
10
|
import { step } from "./step.js";
|
|
11
11
|
import { WaitForTimeoutError, waitFor, waitForStep } from "./wait-for.js";
|
|
12
12
|
import { restartHost, waitForHostAlive } from "./host-restart.js";
|
|
13
|
-
import { idempotent, idempotentStep } from "./idempotent.js";
|
|
13
|
+
import { checkStep, idempotent, idempotentStep } from "./idempotent.js";
|
|
14
14
|
import { job } from "./job.js";
|
|
15
15
|
import { workflow } from "./workflow.js";
|
|
16
|
+
import { flattenStepInputs, isParallelGroup, parallel } from "./parallel.js";
|
|
16
17
|
import { pr } from "./triggers/pr.js";
|
|
17
18
|
import { push } from "./triggers/push.js";
|
|
18
19
|
import { tag } from "./triggers/tag.js";
|
|
@@ -35,9 +36,10 @@ import { jobComplete } from "./triggers/job-complete.js";
|
|
|
35
36
|
import { genericWebhook } from "./triggers/generic-webhook.js";
|
|
36
37
|
import { schedule } from "./triggers/schedule.js";
|
|
37
38
|
import { lifecycle } from "./triggers/lifecycle.js";
|
|
39
|
+
import { defineDispatchInputs } from "./triggers/dispatch-inputs.js";
|
|
38
40
|
import "./triggers/index.js";
|
|
39
41
|
import { afterStep, beforeStep, cleanup, onCancel, onFailure, onSuccess } from "./hooks/index.js";
|
|
40
|
-
import { rule, skip } from "./rules/rule.js";
|
|
42
|
+
import { onlyOnFanoutIndex, onlyOnFirstHost, onlyOnLastHost, rule, skip } from "./rules/rule.js";
|
|
41
43
|
import { evaluateRules } from "./rules/evaluator.js";
|
|
42
44
|
import { isEventType } from "./events/event-payloads.js";
|
|
43
45
|
import "./rules/index.js";
|
|
@@ -53,4 +55,4 @@ import "./matrix/index.js";
|
|
|
53
55
|
import { defineEvent } from "./events/define-event.js";
|
|
54
56
|
import "./events/index.js";
|
|
55
57
|
import { z } from "zod";
|
|
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 };
|
|
58
|
+
export { CacheSpecSchema, DYNAMIC_GROUP_TAG, DYNAMIC_JOB_GROUP_TAG, DYNAMIC_JOB_NEEDS_TAG, SecretNotFoundError, WaitForTimeoutError, afterStep, applyIncludeExclude, beforeStep, buildKiciApi, buildNeedsContext, checkStep, cleanup, comment, create, createJobOutputProxy, createSnapshotOutputProxy, createStepOutputProxy, createStepSecrets, defineDispatchInputs, defineEvent, del as delete, dispatch, dynamicGroup, dynamicJob, evaluateRules, expandMatrix, fixture, flattenStepInputs, fork, genericWebhook, getDynamicJobGroup, getDynamicJobNeeds, getJobOutputsMap, getStepOutputsMap, getStepRefMap, idempotent, idempotentStep, isDynamicFunction, isDynamicGroupRef, isDynamicJobFn, isEventType, isHostJobOutputs, isMatrixJobOutputs, isParallelGroup, isStaticArray, isStaticObject, job, jobComplete, kiciEvent, lifecycle, normalizeApproval, normalizeCacheSpecs, onCancel, onFailure, onSuccess, onlyOnFanoutIndex, onlyOnFirstHost, onlyOnLastHost, parallel, 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
|
@@ -32,15 +32,20 @@ function job(nameOrOptions, maybeOptions) {
|
|
|
32
32
|
steps = [options.run];
|
|
33
33
|
}
|
|
34
34
|
validateInit(options.init, name);
|
|
35
|
+
const firstEnv = options.environments?.[0];
|
|
36
|
+
const concurrencyGroup = options.concurrencyGroup ?? (typeof firstEnv === "string" ? firstEnv : void 0);
|
|
37
|
+
if (options.environment !== void 0 && options.environments !== void 0) throw new Error(`job('${name}'): environment and environments are mutually exclusive — use one`);
|
|
35
38
|
if (options.runsOn !== void 0 && options.runsOnAll !== void 0) throw new Error(`job('${name}'): runsOn and runsOnAll are mutually exclusive`);
|
|
36
39
|
if (options.runsOn === void 0 && options.runsOnAll === void 0) throw new Error(`job('${name}'): one of runsOn or runsOnAll is required`);
|
|
37
40
|
if (options.onUnreachable !== void 0 && options.runsOnAll === void 0) console.warn(`[kici] job('${name}'): onUnreachable is ignored without runsOnAll`);
|
|
41
|
+
if (options.includeUninitialized !== void 0 && options.runsOnAll === void 0) console.warn(`[kici] job('${name}'): includeUninitialized is ignored without runsOnAll`);
|
|
38
42
|
return {
|
|
39
43
|
_tag: "Job",
|
|
40
44
|
name,
|
|
41
45
|
...options.runsOn !== void 0 && { runsOn: options.runsOn },
|
|
42
46
|
...options.runsOnAll !== void 0 && { runsOnAll: options.runsOnAll },
|
|
43
47
|
...options.onUnreachable !== void 0 && { onUnreachable: options.onUnreachable },
|
|
48
|
+
...options.includeUninitialized !== void 0 && { includeUninitialized: options.includeUninitialized },
|
|
44
49
|
...options.maxParallel !== void 0 && { maxParallel: options.maxParallel },
|
|
45
50
|
...options.failFast !== void 0 && { failFast: options.failFast },
|
|
46
51
|
steps,
|
|
@@ -53,8 +58,9 @@ function job(nameOrOptions, maybeOptions) {
|
|
|
53
58
|
checkout: options.checkout,
|
|
54
59
|
container: options.container,
|
|
55
60
|
environment: options.environment,
|
|
61
|
+
environments: options.environments,
|
|
56
62
|
env: options.env,
|
|
57
|
-
concurrencyGroup
|
|
63
|
+
concurrencyGroup,
|
|
58
64
|
onCancel: options.onCancel,
|
|
59
65
|
cleanup: options.cleanup,
|
|
60
66
|
onSuccess: options.onSuccess,
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Step, BareStepFn, StepInput } from './types.js';
|
|
2
|
+
/** A flat step entry: a step or bare function, never a parallel group. */
|
|
3
|
+
export type FlatStepInput = Step<any> | BareStepFn<any>;
|
|
4
|
+
/**
|
|
5
|
+
* A concurrent group of steps with a join barrier. Each child runs concurrently
|
|
6
|
+
* and surfaces as its own observable dashboard step (own logs, status, timing).
|
|
7
|
+
* Execution continues past the group only once every child has settled.
|
|
8
|
+
*/
|
|
9
|
+
export interface ParallelGroup {
|
|
10
|
+
readonly _tag: 'ParallelGroup';
|
|
11
|
+
/** Optional group label shown on the dashboard band. */
|
|
12
|
+
readonly name?: string;
|
|
13
|
+
/** When the first child fails, cancel in-flight siblings (default `true`). */
|
|
14
|
+
readonly failFast: boolean;
|
|
15
|
+
/** Maximum children running at once; queued children show `pending`. */
|
|
16
|
+
readonly maxParallel?: number;
|
|
17
|
+
readonly steps: readonly StepInput[];
|
|
18
|
+
}
|
|
19
|
+
export interface ParallelOptions {
|
|
20
|
+
readonly failFast?: boolean;
|
|
21
|
+
readonly maxParallel?: number;
|
|
22
|
+
readonly name?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Run `steps` concurrently with a join barrier; each child is its own
|
|
26
|
+
* observable step. A `parallel()` group's `failFast`/`maxParallel` nest inside
|
|
27
|
+
* the job-level fan-out scopes — they govern only this step group.
|
|
28
|
+
*/
|
|
29
|
+
export declare function parallel(steps: StepInput[], opts?: ParallelOptions): ParallelGroup;
|
|
30
|
+
/** Type guard distinguishing a `ParallelGroup` from a step or bare function. */
|
|
31
|
+
export declare function isParallelGroup(x: unknown): x is ParallelGroup;
|
|
32
|
+
/**
|
|
33
|
+
* Flatten a job's `steps` into a flat list where each parallel group's children
|
|
34
|
+
* are inlined in array order (the group wrapper is dropped). Used by single-
|
|
35
|
+
* process consumers (the local executor and dry-run preview) that surface each
|
|
36
|
+
* child as its own step but do not run a concurrent scheduler; the concurrent
|
|
37
|
+
* agent path expands groups into observable concurrent tasks instead.
|
|
38
|
+
*/
|
|
39
|
+
export declare function flattenStepInputs(steps: readonly StepInput[]): FlatStepInput[];
|
|
40
|
+
//# sourceMappingURL=parallel.d.ts.map
|
package/dist/parallel.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import "./chunk-BTugEXQM.js";
|
|
2
|
+
//#region src/parallel.ts
|
|
3
|
+
/**
|
|
4
|
+
* Run `steps` concurrently with a join barrier; each child is its own
|
|
5
|
+
* observable step. A `parallel()` group's `failFast`/`maxParallel` nest inside
|
|
6
|
+
* the job-level fan-out scopes — they govern only this step group.
|
|
7
|
+
*/
|
|
8
|
+
function parallel(steps, opts = {}) {
|
|
9
|
+
return {
|
|
10
|
+
_tag: "ParallelGroup",
|
|
11
|
+
name: opts.name,
|
|
12
|
+
failFast: opts.failFast ?? true,
|
|
13
|
+
maxParallel: opts.maxParallel,
|
|
14
|
+
steps
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/** Type guard distinguishing a `ParallelGroup` from a step or bare function. */
|
|
18
|
+
function isParallelGroup(x) {
|
|
19
|
+
return typeof x === "object" && x !== null && x._tag === "ParallelGroup";
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Flatten a job's `steps` into a flat list where each parallel group's children
|
|
23
|
+
* are inlined in array order (the group wrapper is dropped). Used by single-
|
|
24
|
+
* process consumers (the local executor and dry-run preview) that surface each
|
|
25
|
+
* child as its own step but do not run a concurrent scheduler; the concurrent
|
|
26
|
+
* agent path expands groups into observable concurrent tasks instead.
|
|
27
|
+
*/
|
|
28
|
+
function flattenStepInputs(steps) {
|
|
29
|
+
const flat = [];
|
|
30
|
+
for (const entry of steps) if (isParallelGroup(entry)) flat.push(...entry.steps);
|
|
31
|
+
else flat.push(entry);
|
|
32
|
+
return flat;
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { flattenStepInputs, isParallelGroup, parallel };
|
|
36
|
+
|
|
37
|
+
//# sourceMappingURL=parallel.js.map
|
package/dist/rules/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { rule, skip } from './rule.js';
|
|
1
|
+
export { rule, skip, onlyOnFirstHost, onlyOnLastHost, onlyOnFanoutIndex } from './rule.js';
|
|
2
2
|
export { evaluateRules, type RuleEvaluationResult } from './evaluator.js';
|
|
3
3
|
export type { Rule, RuleCheckFn, RuleContext, RuleResult, EventPayload } from './types.js';
|
|
4
4
|
export { isEventType } from '../events/event-payloads.js';
|
package/dist/rules/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "../chunk-BTugEXQM.js";
|
|
2
|
-
import { rule, skip } from "./rule.js";
|
|
2
|
+
import { onlyOnFanoutIndex, onlyOnFirstHost, onlyOnLastHost, rule, skip } from "./rule.js";
|
|
3
3
|
import { evaluateRules } from "./evaluator.js";
|
|
4
4
|
import { isEventType } from "../events/event-payloads.js";
|
|
5
|
-
export { evaluateRules, isEventType, rule, skip };
|
|
5
|
+
export { evaluateRules, isEventType, onlyOnFanoutIndex, onlyOnFirstHost, onlyOnLastHost, rule, skip };
|
package/dist/rules/rule.d.ts
CHANGED
|
@@ -31,4 +31,24 @@ export declare function rule(label: string, check: RuleCheckFn): Rule;
|
|
|
31
31
|
* });
|
|
32
32
|
*/
|
|
33
33
|
export declare function skip(label: string, check: RuleCheckFn): Rule;
|
|
34
|
+
/**
|
|
35
|
+
* Run a step only on the first fan-out child (the lowest-`agentId` host, or the
|
|
36
|
+
* first matrix variant). KiCI's `run_once`-on-the-first-host primitive.
|
|
37
|
+
*
|
|
38
|
+
* A non-fan-out job is treated as a single implicit child at index 0, so a step
|
|
39
|
+
* gated this way runs normally there (there is exactly one host, which is first).
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* step('enable sync mode', async (ctx) => { ... }, { rules: [onlyOnFirstHost()] })
|
|
43
|
+
*/
|
|
44
|
+
export declare function onlyOnFirstHost(): Rule;
|
|
45
|
+
/**
|
|
46
|
+
* Run a step only on the last fan-out child. Runs normally when not fanned out.
|
|
47
|
+
*/
|
|
48
|
+
export declare function onlyOnLastHost(): Rule;
|
|
49
|
+
/**
|
|
50
|
+
* Run a step only on the fan-out child at index `n`. A non-fan-out job is the
|
|
51
|
+
* implicit child at index 0, so `onlyOnFanoutIndex(0)` runs normally there.
|
|
52
|
+
*/
|
|
53
|
+
export declare function onlyOnFanoutIndex(n: number): Rule;
|
|
34
54
|
//# sourceMappingURL=rule.d.ts.map
|
package/dist/rules/rule.js
CHANGED
|
@@ -31,7 +31,33 @@ function skip(label, check) {
|
|
|
31
31
|
check: async (ctx) => !await check(ctx)
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Run a step only on the first fan-out child (the lowest-`agentId` host, or the
|
|
36
|
+
* first matrix variant). KiCI's `run_once`-on-the-first-host primitive.
|
|
37
|
+
*
|
|
38
|
+
* A non-fan-out job is treated as a single implicit child at index 0, so a step
|
|
39
|
+
* gated this way runs normally there (there is exactly one host, which is first).
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* step('enable sync mode', async (ctx) => { ... }, { rules: [onlyOnFirstHost()] })
|
|
43
|
+
*/
|
|
44
|
+
function onlyOnFirstHost() {
|
|
45
|
+
return rule("fanout: first host only", (ctx) => ctx.fanout === void 0 || ctx.fanout.first);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Run a step only on the last fan-out child. Runs normally when not fanned out.
|
|
49
|
+
*/
|
|
50
|
+
function onlyOnLastHost() {
|
|
51
|
+
return rule("fanout: last host only", (ctx) => ctx.fanout === void 0 || ctx.fanout.last);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Run a step only on the fan-out child at index `n`. A non-fan-out job is the
|
|
55
|
+
* implicit child at index 0, so `onlyOnFanoutIndex(0)` runs normally there.
|
|
56
|
+
*/
|
|
57
|
+
function onlyOnFanoutIndex(n) {
|
|
58
|
+
return rule(`fanout: index ${n} only`, (ctx) => (ctx.fanout?.index ?? 0) === n);
|
|
59
|
+
}
|
|
34
60
|
//#endregion
|
|
35
|
-
export { rule, skip };
|
|
61
|
+
export { onlyOnFanoutIndex, onlyOnFirstHost, onlyOnLastHost, rule, skip };
|
|
36
62
|
|
|
37
63
|
//# sourceMappingURL=rule.js.map
|
package/dist/rules/types.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { $ as Shell } from 'zx';
|
|
2
2
|
import type { EventPayload } from '../events/event-payloads.js';
|
|
3
|
+
import type { FanoutPosition } from '../fanout-context.js';
|
|
3
4
|
export type { EventPayload } from '../events/event-payloads.js';
|
|
4
5
|
/**
|
|
5
6
|
* Context passed to rule check functions.
|
|
@@ -12,6 +13,14 @@ export interface RuleContext {
|
|
|
12
13
|
changedFiles: string[];
|
|
13
14
|
/** Environment variables */
|
|
14
15
|
env: Record<string, string | undefined>;
|
|
16
|
+
/** Operator-supplied, validated + coerced workflow-dispatch inputs. Empty when none declared. */
|
|
17
|
+
dispatchInputs: Readonly<Record<string, string | number | boolean | null>>;
|
|
18
|
+
/**
|
|
19
|
+
* Position of this child within its fan-out (a `runsOnAll` host or a matrix
|
|
20
|
+
* combination); undefined on a non-fan-out job. Read by the run-once rule
|
|
21
|
+
* helpers (`onlyOnFirstHost` / `onlyOnLastHost` / `onlyOnFanoutIndex`).
|
|
22
|
+
*/
|
|
23
|
+
fanout?: FanoutPosition;
|
|
15
24
|
/** zx shell executor for running commands */
|
|
16
25
|
$: typeof Shell;
|
|
17
26
|
}
|
package/dist/secrets.d.ts
CHANGED
|
@@ -48,7 +48,7 @@ export interface MountedFile {
|
|
|
48
48
|
*
|
|
49
49
|
* The SDK owns the public surface (`mountFile` / `exposeFile`) but defers
|
|
50
50
|
* disk and `process.env` operations to the agent so the SDK stays free of
|
|
51
|
-
* any `node:fs` / `node:os` imports. Local
|
|
51
|
+
* any `node:fs` / `node:os` imports. Local preview/run mode (`kici preview` / `kici run local`) plugs
|
|
52
52
|
* in the same adapter shape against `os.tmpdir()`.
|
|
53
53
|
*/
|
|
54
54
|
export interface StepSecretsFileHost {
|
package/dist/step.js
CHANGED
|
@@ -3,6 +3,22 @@ import { normalizeApproval } from "./approval.js";
|
|
|
3
3
|
import { createStepOutputProxy } from "./outputs.js";
|
|
4
4
|
//#region src/step.ts
|
|
5
5
|
/**
|
|
6
|
+
* Fill retry defaults and expand the `retry: N` shorthand into a
|
|
7
|
+
* {@link NormalizedRetry}. `retryIf` is carried through unchanged (it is
|
|
8
|
+
* execution-only and never serialized).
|
|
9
|
+
*/
|
|
10
|
+
function normalizeRetry(retry) {
|
|
11
|
+
if (retry === void 0) return void 0;
|
|
12
|
+
const cfg = typeof retry === "number" ? { maxAttempts: retry } : retry;
|
|
13
|
+
return {
|
|
14
|
+
maxAttempts: cfg.maxAttempts,
|
|
15
|
+
delayMs: cfg.delayMs ?? 1e3,
|
|
16
|
+
backoff: cfg.backoff ?? "exponential",
|
|
17
|
+
maxDelayMs: cfg.maxDelayMs ?? 3e4,
|
|
18
|
+
...cfg.retryIf && { retryIf: cfg.retryIf }
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
6
22
|
* Capture the call-site source location of step() using the V8 stack trace API.
|
|
7
23
|
* Uses Error.captureStackTrace with the `step` function as the constructor argument
|
|
8
24
|
* so the stack starts from step()'s caller.
|
|
@@ -61,6 +77,7 @@ function step(nameOrRunOrOptions, runOrOptions) {
|
|
|
61
77
|
}
|
|
62
78
|
if (options.check && !options.summarize) throw new Error("summarize is required when check is set");
|
|
63
79
|
if (options.approval !== void 0 && normalizeApproval(options.approval).when === "drift" && !options.check) throw new Error("approval.when \"drift\" requires a check facet");
|
|
80
|
+
const retry = normalizeRetry(options.retry);
|
|
64
81
|
return {
|
|
65
82
|
_tag: "Step",
|
|
66
83
|
name,
|
|
@@ -72,6 +89,7 @@ function step(nameOrRunOrOptions, runOrOptions) {
|
|
|
72
89
|
...options.whenInSync !== void 0 && { whenInSync: options.whenInSync },
|
|
73
90
|
continueOnError: options.continueOnError,
|
|
74
91
|
timeout: options.timeout,
|
|
92
|
+
...retry !== void 0 && { retry },
|
|
75
93
|
...options.cache !== void 0 && { cache: options.cache },
|
|
76
94
|
rules: options.rules,
|
|
77
95
|
onCancel: options.onCancel,
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
import type { DispatchInputsMap } from './types.js';
|
|
3
|
+
/** The per-key inferred output type of a declared dispatch-inputs map. */
|
|
4
|
+
export type InferDispatchInputs<TMap extends DispatchInputsMap> = {
|
|
5
|
+
[K in keyof TMap]: z.infer<TMap[K]>;
|
|
6
|
+
};
|
|
7
|
+
/** A context that may carry validated, coerced dispatch inputs. */
|
|
8
|
+
interface DispatchInputsCarrier {
|
|
9
|
+
dispatchInputs?: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* A branded handle returned by `defineDispatchInputs`. It is accepted directly
|
|
13
|
+
* by `dispatch({ inputs })` and exposes typed `.from(ctx)` / `.fromRule(ctx)`
|
|
14
|
+
* readers over `ctx.dispatchInputs`, typed per declared key.
|
|
15
|
+
*/
|
|
16
|
+
export interface DefinedDispatchInputs<TMap extends DispatchInputsMap> {
|
|
17
|
+
readonly __kiciDispatchInputs: true;
|
|
18
|
+
readonly map: TMap;
|
|
19
|
+
/** Read the validated, coerced dispatch inputs from a step context, typed per declared key. */
|
|
20
|
+
from(ctx: DispatchInputsCarrier): InferDispatchInputs<TMap>;
|
|
21
|
+
/** Same, from a rule context. */
|
|
22
|
+
fromRule(ctx: DispatchInputsCarrier): InferDispatchInputs<TMap>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Declare a typed workflow-dispatch inputs map once and get back a handle that
|
|
26
|
+
* both `dispatch({ inputs })` accepts and exposes a typed `.from(ctx)` reader —
|
|
27
|
+
* no double type annotation. Type safety comes via Standard-Schema inference
|
|
28
|
+
* (Zod 4 implements `~standard`), without a builder-generics refactor.
|
|
29
|
+
*/
|
|
30
|
+
export declare function defineDispatchInputs<TMap extends DispatchInputsMap>(map: TMap): DefinedDispatchInputs<TMap>;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=dispatch-inputs.d.ts.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import "../chunk-BTugEXQM.js";
|
|
2
|
+
//#region src/triggers/dispatch-inputs.ts
|
|
3
|
+
/**
|
|
4
|
+
* Declare a typed workflow-dispatch inputs map once and get back a handle that
|
|
5
|
+
* both `dispatch({ inputs })` accepts and exposes a typed `.from(ctx)` reader —
|
|
6
|
+
* no double type annotation. Type safety comes via Standard-Schema inference
|
|
7
|
+
* (Zod 4 implements `~standard`), without a builder-generics refactor.
|
|
8
|
+
*/
|
|
9
|
+
function defineDispatchInputs(map) {
|
|
10
|
+
const read = (ctx) => ctx.dispatchInputs ?? {};
|
|
11
|
+
return Object.freeze({
|
|
12
|
+
__kiciDispatchInputs: true,
|
|
13
|
+
map: Object.freeze({ ...map }),
|
|
14
|
+
from: read,
|
|
15
|
+
fromRule: read
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export { defineDispatchInputs };
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=dispatch-inputs.js.map
|
|
@@ -13,11 +13,15 @@ import { asArray, toBranchPattern } from "./types.js";
|
|
|
13
13
|
*/
|
|
14
14
|
function dispatch(config) {
|
|
15
15
|
const repos = config?.repos ? asArray(config.repos).map(toBranchPattern) : [];
|
|
16
|
+
const rawInputs = config?.inputs;
|
|
17
|
+
let inputsMap;
|
|
18
|
+
if (rawInputs) inputsMap = "__kiciDispatchInputs" in rawInputs ? rawInputs.map : rawInputs;
|
|
16
19
|
const result = {
|
|
17
20
|
_tag: "DispatchTrigger",
|
|
18
21
|
types: Object.freeze(config?.types ? [...config.types] : []),
|
|
19
22
|
repos: Object.freeze([...repos]),
|
|
20
|
-
...config?.description !== void 0 && { description: config.description }
|
|
23
|
+
...config?.description !== void 0 && { description: config.description },
|
|
24
|
+
...inputsMap && { inputs: Object.freeze({ ...inputsMap }) }
|
|
21
25
|
};
|
|
22
26
|
return Object.freeze(result);
|
|
23
27
|
}
|
package/dist/triggers/index.d.ts
CHANGED
|
@@ -23,6 +23,8 @@ export { jobComplete } from './job-complete.js';
|
|
|
23
23
|
export { genericWebhook } from './generic-webhook.js';
|
|
24
24
|
export { schedule } from './schedule.js';
|
|
25
25
|
export { lifecycle } from './lifecycle.js';
|
|
26
|
-
export
|
|
26
|
+
export { defineDispatchInputs } from './dispatch-inputs.js';
|
|
27
|
+
export type { DefinedDispatchInputs, InferDispatchInputs } from './dispatch-inputs.js';
|
|
28
|
+
export type { DispatchInputsMap, BranchPattern, BodyMatchPattern, PrEvent, PushEvent, PrTriggerConfig, PushTriggerConfig, TagTriggerConfig, CommentTriggerConfig, ReviewTriggerConfig, ReviewCommentTriggerConfig, ReleaseTriggerConfig, DispatchTriggerConfig, CreateTriggerConfig, DeleteTriggerConfig, StatusTriggerConfig, WorkflowRunTriggerConfig, ForkTriggerConfig, StarTriggerConfig, WatchTriggerConfig, WebhookTriggerConfig, TriggerConfig, 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 './types.js';
|
|
27
29
|
export { DEFAULT_PR_EVENTS, toBranchPattern } from './types.js';
|
|
28
30
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/triggers/index.js
CHANGED
|
@@ -22,4 +22,5 @@ import { jobComplete } from "./job-complete.js";
|
|
|
22
22
|
import { genericWebhook } from "./generic-webhook.js";
|
|
23
23
|
import { schedule } from "./schedule.js";
|
|
24
24
|
import { lifecycle } from "./lifecycle.js";
|
|
25
|
-
|
|
25
|
+
import { defineDispatchInputs } from "./dispatch-inputs.js";
|
|
26
|
+
export { DEFAULT_PR_EVENTS, comment, create, defineDispatchInputs, del as delete, dispatch, fork, genericWebhook, jobComplete, kiciEvent, lifecycle, pr, push, release, review, reviewComment, schedule, star, status, tag, toBranchPattern, watch, webhook, workflowComplete, workflowRun };
|
|
@@ -15,6 +15,9 @@ import type { ScheduleConfigInput, ScheduleTriggerConfig } from './types.js';
|
|
|
15
15
|
*
|
|
16
16
|
* // Run weekly on Monday at 9am in a specific timezone
|
|
17
17
|
* schedule({ cron: '0 9 * * 1', timezone: 'America/New_York' })
|
|
18
|
+
*
|
|
19
|
+
* // Daily at midnight UTC, with a defaults-only input
|
|
20
|
+
* schedule({ cron: '0 0 * * *', inputs: { mode: z.enum(['full', 'quick']).default('full') } })
|
|
18
21
|
*/
|
|
19
22
|
export declare function schedule(config: ScheduleConfigInput): ScheduleTriggerConfig;
|
|
20
23
|
//# sourceMappingURL=schedule.d.ts.map
|
|
@@ -12,14 +12,21 @@ import "../chunk-BTugEXQM.js";
|
|
|
12
12
|
*
|
|
13
13
|
* // Run weekly on Monday at 9am in a specific timezone
|
|
14
14
|
* schedule({ cron: '0 9 * * 1', timezone: 'America/New_York' })
|
|
15
|
+
*
|
|
16
|
+
* // Daily at midnight UTC, with a defaults-only input
|
|
17
|
+
* schedule({ cron: '0 0 * * *', inputs: { mode: z.enum(['full', 'quick']).default('full') } })
|
|
15
18
|
*/
|
|
16
19
|
function schedule(config) {
|
|
17
20
|
if (!config.cron || config.cron.trim() === "") throw new Error("schedule() requires a non-empty cron expression");
|
|
21
|
+
const rawInputs = config.inputs;
|
|
22
|
+
let inputsMap;
|
|
23
|
+
if (rawInputs) inputsMap = "__kiciDispatchInputs" in rawInputs ? rawInputs.map : rawInputs;
|
|
18
24
|
const result = {
|
|
19
25
|
_tag: "ScheduleTrigger",
|
|
20
26
|
cron: config.cron,
|
|
21
27
|
timezone: config.timezone ?? "UTC",
|
|
22
|
-
...config.description !== void 0 && { description: config.description }
|
|
28
|
+
...config.description !== void 0 && { description: config.description },
|
|
29
|
+
...inputsMap && { inputs: Object.freeze({ ...inputsMap }) }
|
|
23
30
|
};
|
|
24
31
|
return Object.freeze(result);
|
|
25
32
|
}
|
package/dist/triggers/types.d.ts
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
* Trigger types and interfaces for pr() and push() trigger helpers.
|
|
3
3
|
* Supports both glob patterns and regex patterns for branch/path matching.
|
|
4
4
|
*/
|
|
5
|
+
import type { z } from 'zod';
|
|
6
|
+
/**
|
|
7
|
+
* A declared map of typed workflow-dispatch inputs: `{ name: ZodSchema }`.
|
|
8
|
+
* Each schema must fall within the closed dispatch-input subset (extracted by
|
|
9
|
+
* the compiler) — z.string/number/boolean/enum/literal plus
|
|
10
|
+
* .optional/.nullable/.default/.min/.max/.regex/.int.
|
|
11
|
+
*/
|
|
12
|
+
export type DispatchInputsMap = Record<string, z.ZodType>;
|
|
5
13
|
/**
|
|
6
14
|
* Branch pattern - discriminated union supporting both glob and regex patterns.
|
|
7
15
|
* Glob patterns use micromatch syntax, regex patterns use standard JS regex.
|
|
@@ -165,6 +173,8 @@ export interface DispatchTriggerConfig {
|
|
|
165
173
|
readonly types: readonly string[];
|
|
166
174
|
readonly repos: readonly BranchPattern[];
|
|
167
175
|
readonly description?: string;
|
|
176
|
+
/** Declared, typed workflow-dispatch inputs (frozen `{ name: ZodSchema }`). */
|
|
177
|
+
readonly inputs?: DispatchInputsMap;
|
|
168
178
|
}
|
|
169
179
|
/**
|
|
170
180
|
* Input configuration for dispatch() factory function.
|
|
@@ -173,6 +183,16 @@ export interface DispatchConfigInput {
|
|
|
173
183
|
readonly types?: string[];
|
|
174
184
|
readonly repos?: string | RegExp | (string | RegExp)[];
|
|
175
185
|
readonly description?: string;
|
|
186
|
+
/**
|
|
187
|
+
* Typed workflow-dispatch inputs. Accepts a bare `{ name: ZodSchema }` map or
|
|
188
|
+
* a `defineDispatchInputs(...)` branded handle (which also exposes a typed
|
|
189
|
+
* `.from(ctx)` accessor). The compiler validates each schema against the
|
|
190
|
+
* closed dispatch-input subset.
|
|
191
|
+
*/
|
|
192
|
+
readonly inputs?: DispatchInputsMap | {
|
|
193
|
+
readonly __kiciDispatchInputs: true;
|
|
194
|
+
readonly map: DispatchInputsMap;
|
|
195
|
+
};
|
|
176
196
|
}
|
|
177
197
|
export type RefType = 'branch' | 'tag';
|
|
178
198
|
/**
|
|
@@ -439,6 +459,16 @@ export interface ScheduleConfigInput {
|
|
|
439
459
|
readonly cron: string;
|
|
440
460
|
readonly timezone?: string;
|
|
441
461
|
readonly description?: string;
|
|
462
|
+
/**
|
|
463
|
+
* Typed schedule inputs (defaults-only — no operator overrides on a fire).
|
|
464
|
+
* Accepts a bare `{ name: ZodSchema }` map or a `defineDispatchInputs(...)`
|
|
465
|
+
* branded handle. Each input must declare a `.default()` or be `.optional()`
|
|
466
|
+
* (enforced at compile time).
|
|
467
|
+
*/
|
|
468
|
+
readonly inputs?: DispatchInputsMap | {
|
|
469
|
+
readonly __kiciDispatchInputs: true;
|
|
470
|
+
readonly map: DispatchInputsMap;
|
|
471
|
+
};
|
|
442
472
|
}
|
|
443
473
|
/**
|
|
444
474
|
* Configuration for a schedule trigger.
|
|
@@ -448,6 +478,8 @@ export interface ScheduleTriggerConfig {
|
|
|
448
478
|
readonly cron: string;
|
|
449
479
|
readonly timezone: string;
|
|
450
480
|
readonly description?: string;
|
|
481
|
+
/** Declared, typed schedule inputs (frozen `{ name: ZodSchema }`). */
|
|
482
|
+
readonly inputs?: DispatchInputsMap;
|
|
451
483
|
}
|
|
452
484
|
/**
|
|
453
485
|
* Lifecycle event types for cross-workflow orchestration.
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { z } from 'zod';
|
|
2
2
|
import type { $ as Shell } from 'zx';
|
|
3
|
+
import type { RetryBackoff } from '@kici-dev/core';
|
|
3
4
|
import type { ResourceRequest, RunsOnAllInput, OnUnreachableMode, NeedsWhen, ExecutionJobStatus } from '@kici-dev/engine';
|
|
4
5
|
import type { StepContext, Logger } from './context.js';
|
|
5
6
|
import type { TriggerConfig } from './triggers/types.js';
|
|
@@ -64,6 +65,8 @@ export interface Step<TResult = void> {
|
|
|
64
65
|
readonly continueOnError?: boolean;
|
|
65
66
|
/** Step-level timeout in milliseconds. Overrides the agent's default (30 minutes). */
|
|
66
67
|
readonly timeout?: number;
|
|
68
|
+
/** Normalized retry policy (defaults filled, shorthand expanded). `retryIf` is execution-only. */
|
|
69
|
+
readonly retry?: NormalizedRetry;
|
|
67
70
|
/** Declarative cache: restored before this step, saved after on key miss. */
|
|
68
71
|
readonly cache?: import('./cache-types.js').CacheInput;
|
|
69
72
|
/** Step-level conditional rules (evaluated agent-side). */
|
|
@@ -90,11 +93,38 @@ export interface Step<TResult = void> {
|
|
|
90
93
|
export type BareStepFn<TResult = void> = (ctx: StepContext) => Promise<TResult>;
|
|
91
94
|
/**
|
|
92
95
|
* Union type for items accepted in a job's steps array.
|
|
93
|
-
* Accepts
|
|
96
|
+
* Accepts Step objects, bare async functions, and concurrent parallel groups.
|
|
94
97
|
*/
|
|
95
|
-
export type StepInput = Step<any> | BareStepFn<any
|
|
98
|
+
export type StepInput = Step<any> | BareStepFn<any> | import('./parallel.js').ParallelGroup;
|
|
96
99
|
/** Options for step() factory - simple form (just async function) */
|
|
97
100
|
export type StepRunFn = (ctx: StepContext) => Promise<void>;
|
|
101
|
+
/**
|
|
102
|
+
* Author-supplied retry policy for a step. A thrown attempt is re-run while
|
|
103
|
+
* attempts remain and `retryIf(err)` is true.
|
|
104
|
+
*/
|
|
105
|
+
export interface RetryConfig {
|
|
106
|
+
/** Total attempts incl. the first; `maxAttempts: 3` ⇒ up to 3 runs. Must be >= 1. */
|
|
107
|
+
maxAttempts: number;
|
|
108
|
+
/** Base delay between attempts, ms. Default 1000. */
|
|
109
|
+
delayMs?: number;
|
|
110
|
+
/** Delay growth. Default 'exponential'. */
|
|
111
|
+
backoff?: RetryBackoff;
|
|
112
|
+
/** Cap for exponential backoff, ms. Default 30000. */
|
|
113
|
+
maxDelayMs?: number;
|
|
114
|
+
/** Retry only when this returns true for the thrown error. Default: retry on any throw. */
|
|
115
|
+
retryIf?: (err: unknown) => boolean;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Retry policy with defaults filled in, carried on the built {@link Step}.
|
|
119
|
+
* `retryIf` rides along on the in-memory step (it is never serialized).
|
|
120
|
+
*/
|
|
121
|
+
export interface NormalizedRetry {
|
|
122
|
+
maxAttempts: number;
|
|
123
|
+
delayMs: number;
|
|
124
|
+
backoff: RetryBackoff;
|
|
125
|
+
maxDelayMs: number;
|
|
126
|
+
retryIf?: (err: unknown) => boolean;
|
|
127
|
+
}
|
|
98
128
|
/**
|
|
99
129
|
* Facets shared by both the plain and the check variant of {@link StepOptions}.
|
|
100
130
|
* These compose unchanged whether or not a step declares a `check` facet.
|
|
@@ -106,6 +136,8 @@ export interface StepOptionsBase {
|
|
|
106
136
|
continueOnError?: boolean;
|
|
107
137
|
/** Step-level timeout in milliseconds. Overrides the agent's default (30 minutes). */
|
|
108
138
|
timeout?: number;
|
|
139
|
+
/** Retry policy: re-run a thrown step with backoff. `retry: N` ⇒ `{ maxAttempts: N }`. */
|
|
140
|
+
retry?: number | RetryConfig;
|
|
109
141
|
/** Declarative cache: restored before this step, saved after on key miss. */
|
|
110
142
|
cache?: import('./cache-types.js').CacheInput;
|
|
111
143
|
/** Step-level conditional rules (evaluated agent-side). */
|
|
@@ -361,7 +393,21 @@ export type InitConfig = InitItem | InitItem[] | 'auto' | false;
|
|
|
361
393
|
export interface RunsOnSelector {
|
|
362
394
|
labels: string | RegExp | (string | RegExp)[];
|
|
363
395
|
exclude?: string | RegExp | (string | RegExp)[];
|
|
396
|
+
/**
|
|
397
|
+
* How to pick the single agent when more than one matches.
|
|
398
|
+
*
|
|
399
|
+
* - `'deterministic'` (default) — sort matching candidates by `agentId` and
|
|
400
|
+
* pick the lowest, so a run-once-on-one-host job (a migration, a dump) lands
|
|
401
|
+
* on the same host across re-runs. Can hot-spot equivalent agents.
|
|
402
|
+
* - `'any'` — pick any available agent (load spread). Opt out of determinism
|
|
403
|
+
* for jobs that don't need a stable host.
|
|
404
|
+
*
|
|
405
|
+
* The string / array shorthand `runsOn` forms imply `'deterministic'` too.
|
|
406
|
+
*/
|
|
407
|
+
pick?: RunsOnPick;
|
|
364
408
|
}
|
|
409
|
+
/** Single-agent selection policy when multiple agents match a `runsOn` selector. */
|
|
410
|
+
export type RunsOnPick = 'deterministic' | 'any';
|
|
365
411
|
/**
|
|
366
412
|
* Polymorphic runsOn type: string shorthand, array shorthand, or full selector object.
|
|
367
413
|
* - `'kici:os:linux'` — single label shorthand (targets any linux agent)
|
|
@@ -391,6 +437,14 @@ export interface Job {
|
|
|
391
437
|
readonly runsOnAll?: RunsOnAllInput;
|
|
392
438
|
/** Failure policy for unreachable durable hosts when using `runsOnAll`. */
|
|
393
439
|
readonly onUnreachable?: OnUnreachableMode;
|
|
440
|
+
/**
|
|
441
|
+
* Widen a `runsOnAll` fan-out to declared-but-un-agented hosts: each matching
|
|
442
|
+
* host that has no live agent gets a temporary init-runner brought up over SSH
|
|
443
|
+
* and its steps run on it (fresh-box bootstrap convergence). Already-live hosts
|
|
444
|
+
* run on their own agent. Default `false` (only live hosts run). Only
|
|
445
|
+
* meaningful alongside `runsOnAll`.
|
|
446
|
+
*/
|
|
447
|
+
readonly includeUninitialized?: boolean;
|
|
394
448
|
/** Fan-out concurrency width (sliding window; `1` = serial). Applies to matrix and `runsOnAll`. */
|
|
395
449
|
readonly maxParallel?: number;
|
|
396
450
|
/** Halt the fan-out on first child failure, skipping the remainder. Default `false`. */
|
|
@@ -419,9 +473,16 @@ export interface Job {
|
|
|
419
473
|
readonly container?: string | ContainerConfig;
|
|
420
474
|
/** Deployment environment for this job. String for static, or a function of the normalized event envelope for dynamic (resolved at orchestrator two-phase eval). */
|
|
421
475
|
readonly environment?: string | ((event: EventPayload) => string | Promise<string>);
|
|
476
|
+
/**
|
|
477
|
+
* Deployment environments for this job, in merge order (later entries override
|
|
478
|
+
* earlier on name collisions). Mutually exclusive with `environment`. Each entry
|
|
479
|
+
* is a static name or a function of the event (dynamic, resolved per element at
|
|
480
|
+
* two-phase eval).
|
|
481
|
+
*/
|
|
482
|
+
readonly environments?: readonly (string | ((event: EventPayload) => string | Promise<string>))[];
|
|
422
483
|
/** Environment variables. Static object or a function of the normalized event envelope (resolved at orchestrator two-phase eval). */
|
|
423
484
|
readonly env?: Record<string, string> | ((event: EventPayload) => Record<string, string> | Promise<Record<string, string>>);
|
|
424
|
-
/** Concurrency group name. Defaults to environment name if not set. String or a function of the normalized event envelope. */
|
|
485
|
+
/** Concurrency group name. Defaults to the first bound environment's name if not set. String or a function of the normalized event envelope. */
|
|
425
486
|
readonly concurrencyGroup?: string | ((event: EventPayload) => string | Promise<string>);
|
|
426
487
|
/** Runs on cancellation. */
|
|
427
488
|
readonly onCancel?: HookInput;
|
|
@@ -491,6 +552,13 @@ export interface JobOptions {
|
|
|
491
552
|
* pinned child and waits. Only meaningful alongside `runsOnAll`.
|
|
492
553
|
*/
|
|
493
554
|
onUnreachable?: OnUnreachableMode;
|
|
555
|
+
/**
|
|
556
|
+
* Widen a `runsOnAll` fan-out to declared-but-un-agented hosts: a matching host
|
|
557
|
+
* with no live agent gets a temporary init-runner brought up over SSH and its
|
|
558
|
+
* steps run on it (fresh-box bootstrap convergence); already-live hosts run on
|
|
559
|
+
* their own agent. Default `false`. Only meaningful alongside `runsOnAll`.
|
|
560
|
+
*/
|
|
561
|
+
includeUninitialized?: boolean;
|
|
494
562
|
/**
|
|
495
563
|
* Fan-out concurrency width: the maximum number of fan-out children (matrix
|
|
496
564
|
* combinations or `runsOnAll` hosts) that run at once. A sliding window —
|
|
@@ -553,9 +621,16 @@ export interface JobOptions {
|
|
|
553
621
|
container?: string | ContainerConfig;
|
|
554
622
|
/** Deployment environment for this job. String for static, or a function of the normalized event envelope for dynamic (resolved at orchestrator two-phase eval). */
|
|
555
623
|
environment?: string | ((event: EventPayload) => string | Promise<string>);
|
|
624
|
+
/**
|
|
625
|
+
* Deployment environments for this job, in merge order (later entries override
|
|
626
|
+
* earlier on name collisions). Mutually exclusive with `environment`. Each entry
|
|
627
|
+
* is a static name or a function of the event (dynamic, resolved per element at
|
|
628
|
+
* two-phase eval).
|
|
629
|
+
*/
|
|
630
|
+
environments?: (string | ((event: EventPayload) => string | Promise<string>))[];
|
|
556
631
|
/** Environment variables. Static object or a function of the normalized event envelope (resolved at orchestrator two-phase eval). */
|
|
557
632
|
env?: Record<string, string> | ((event: EventPayload) => Record<string, string> | Promise<Record<string, string>>);
|
|
558
|
-
/** Concurrency group name. Defaults to environment name if not set. String or a function of the normalized event envelope. */
|
|
633
|
+
/** Concurrency group name. Defaults to the first bound environment's name if not set. String or a function of the normalized event envelope. */
|
|
559
634
|
concurrencyGroup?: string | ((event: EventPayload) => string | Promise<string>);
|
|
560
635
|
/** Runs on cancellation. */
|
|
561
636
|
onCancel?: HookInput;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kici-dev/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.24",
|
|
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.24",
|
|
53
|
+
"@kici-dev/engine": "0.1.24"
|
|
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.24",
|
|
6
|
+
"documentNamespace": "https://kici.dev/sbom/%40kici-dev%2Fsdk/0.1.24/5d1c0e54-b629-4883-86a2-1959def49eaa",
|
|
7
7
|
"creationInfo": {
|
|
8
|
-
"created": "2026-06-
|
|
8
|
+
"created": "2026-06-28T16:24:27Z",
|
|
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.24",
|
|
150
150
|
"name": "@kici-dev/core",
|
|
151
|
-
"versionInfo": "0.1.
|
|
151
|
+
"versionInfo": "0.1.24",
|
|
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.24"
|
|
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.24",
|
|
170
170
|
"name": "@kici-dev/engine",
|
|
171
|
-
"versionInfo": "0.1.
|
|
171
|
+
"versionInfo": "0.1.24",
|
|
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.24"
|
|
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.24",
|
|
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.24"
|
|
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.24",
|
|
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.24",
|
|
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.24",
|
|
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.24",
|
|
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.24",
|
|
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.24",
|
|
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.24",
|
|
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.24",
|
|
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.24",
|
|
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.24",
|
|
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.24",
|
|
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.24",
|
|
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.24",
|
|
1649
1649
|
"relationshipType": "DEPENDS_ON"
|
|
1650
1650
|
},
|
|
1651
1651
|
{
|