@kici-dev/sdk 0.1.13 → 0.1.15

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/README.md CHANGED
@@ -1 +1,19 @@
1
- TBD
1
+ # @kici-dev/sdk
2
+
3
+ TypeScript SDK for defining KiCI workflows. Import it in `.kici/workflows/*.ts` to declare workflows, jobs, steps, triggers, rules, and matrix configurations — with full type safety and editor autocomplete.
4
+
5
+ Part of [KiCI](https://kici.dev) — CI/CD workflows as TypeScript code: author them with full language power, dry-run them locally, and run them on your own infrastructure.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install --save-dev @kici-dev/sdk
11
+ ```
12
+
13
+ Usually installed for you by `kici init`.
14
+
15
+ ## Links
16
+
17
+ - Documentation: <https://docs.kici.dev/user/sdk/core/>
18
+ - Source: <https://github.com/kici-dev/kici-public/tree/main/packages/sdk>
19
+ - License: Apache-2.0
@@ -0,0 +1,47 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Declarative + imperative cache specification.
4
+ *
5
+ * `key` is the immutable cache key — the first save under an exact key wins;
6
+ * re-saving the same exact key is a no-op. `paths` are the files/dirs to
7
+ * archive (repo-root-relative or `~`-prefixed). `restoreKeys` are ordered
8
+ * prefix fallbacks tried (newest matching entry wins) when the exact key
9
+ * misses on restore.
10
+ */
11
+ export interface CacheSpec {
12
+ /** Exact cache key. First save wins; re-saving an existing key is a no-op. */
13
+ key: string;
14
+ /** Files/directories to cache. Repo-root-relative or `~`-prefixed. */
15
+ paths: string[];
16
+ /** Ordered prefix fallbacks for partial restore; newest matching entry wins. */
17
+ restoreKeys?: string[];
18
+ }
19
+ /** Zod schema validating a CacheSpec at compile/serialize time. */
20
+ export declare const CacheSpecSchema: z.ZodObject<{
21
+ key: z.ZodString;
22
+ paths: z.ZodArray<z.ZodString>;
23
+ restoreKeys: z.ZodOptional<z.ZodArray<z.ZodString>>;
24
+ }, z.core.$strip>;
25
+ /** Declarative cache field shape: one spec or many. */
26
+ export type CacheInput = CacheSpec | CacheSpec[];
27
+ /** Coerce the declarative `cache` field into an array (empty when unset). */
28
+ export declare function normalizeCacheSpecs(input: CacheInput | undefined): CacheSpec[];
29
+ /** Result of an imperative cache restore. */
30
+ export interface CacheRestoreResult {
31
+ /** Whether any entry (exact key or a restoreKeys prefix match) was restored. */
32
+ hit: boolean;
33
+ /** The key that actually matched (exact key or the matched prefix entry's full key). */
34
+ matchedKey?: string;
35
+ }
36
+ /**
37
+ * Imperative cache API exposed on `StepContext` as `ctx.cache`.
38
+ *
39
+ * `restore` tries the exact `key`, then each `restoreKeys` prefix in order
40
+ * (newest matching entry wins). `save` is immutable — the first save under an
41
+ * exact key wins and re-saving an existing key is a no-op.
42
+ */
43
+ export interface CacheApi {
44
+ restore(spec: CacheSpec): Promise<CacheRestoreResult>;
45
+ save(spec: CacheSpec): Promise<void>;
46
+ }
47
+ //# sourceMappingURL=cache-types.d.ts.map
@@ -0,0 +1,18 @@
1
+ import "./chunk-gOLHoazu.js";
2
+ import { z } from "zod";
3
+ //#region src/cache-types.ts
4
+ /** Zod schema validating a CacheSpec at compile/serialize time. */
5
+ const CacheSpecSchema = z.object({
6
+ key: z.string().min(1, "cache key must be non-empty"),
7
+ paths: z.array(z.string().min(1)).min(1, "cache paths must be non-empty"),
8
+ restoreKeys: z.array(z.string().min(1)).optional()
9
+ });
10
+ /** Coerce the declarative `cache` field into an array (empty when unset). */
11
+ function normalizeCacheSpecs(input) {
12
+ if (input === void 0) return [];
13
+ return Array.isArray(input) ? input : [input];
14
+ }
15
+ //#endregion
16
+ export { CacheSpecSchema, normalizeCacheSpecs };
17
+
18
+ //# sourceMappingURL=cache-types.js.map
package/dist/context.d.ts CHANGED
@@ -180,6 +180,14 @@ export interface StepContext<TInputs = Record<string, unknown>> {
180
180
  setSecretOutput(key: string, value: string): void;
181
181
  /** Typed KiCI API — orchestrator queries over WS (e.g., kici.infrastructure.list()) */
182
182
  kici: KiciApi;
183
+ /**
184
+ * Imperative cache API for fine-grained control.
185
+ *
186
+ * `ctx.cache.restore(spec)` restores from object storage (exact key, then
187
+ * restoreKeys prefix fallback). `ctx.cache.save(spec)` archives `spec.paths`
188
+ * under `spec.key` (immutable — first save wins). Scoped per org + ref.
189
+ */
190
+ cache: import('./cache-types.js').CacheApi;
183
191
  }
184
192
  export {};
185
193
  //# sourceMappingURL=context.d.ts.map
@@ -364,9 +364,20 @@ export interface RerunEventPayload extends EventBase {
364
364
  export interface ManualScheduleEventPayload extends EventBase {
365
365
  type: 'manual_schedule';
366
366
  }
367
- /** Fallback for unknown/future event types. */
367
+ /**
368
+ * Compile-time fallback member of the {@link EventPayload} union for event
369
+ * types not yet modeled here.
370
+ *
371
+ * Its `type` is the literal `'unknown'` (not `string`) so that the union stays
372
+ * a *proper* discriminated union — a non-literal discriminant would collapse
373
+ * narrowing on `event.type` for every other member. At runtime, an event of an
374
+ * unmodeled kind still carries its real type string in `event.type`; this
375
+ * interface only governs how TypeScript narrows it. Code that must handle
376
+ * arbitrary future types can compare the raw value via `String(event.type) ===
377
+ * '...'`, or use the {@link isEventType} guard for the known types.
378
+ */
368
379
  export interface UnknownEventPayload extends EventBase {
369
- type: string;
380
+ type: 'unknown';
370
381
  }
371
382
  /**
372
383
  * Typed event payload — discriminated union over the `type` field.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=event-payloads.test-d.d.ts.map
@@ -0,0 +1,32 @@
1
+ import "../chunk-gOLHoazu.js";
2
+ import { describe, expectTypeOf, it } from "vitest";
3
+ //#region src/events/event-payloads.test-d.ts
4
+ describe("EventPayload narrowing", () => {
5
+ it("narrows to the per-type payload shape on event.type", () => {
6
+ const handle = (event) => {
7
+ if (event.type === "pull_request") {
8
+ expectTypeOf(event).toEqualTypeOf();
9
+ expectTypeOf(event.payload.pull_request.number).toBeNumber();
10
+ }
11
+ };
12
+ expectTypeOf(handle).toBeFunction();
13
+ });
14
+ it("exposes a literal-union discriminant (not string)", () => {
15
+ expectTypeOf().toEqualTypeOf();
16
+ });
17
+ it("job dynamic functions accept EventPayload-param functions", () => {
18
+ expectTypeOf().toMatchTypeOf();
19
+ expectTypeOf().toMatchTypeOf();
20
+ expectTypeOf().toMatchTypeOf();
21
+ });
22
+ it("workflow concurrency.group ctx carries the EventPayload envelope", () => {
23
+ expectTypeOf().toEqualTypeOf();
24
+ });
25
+ it("DynamicJobContext.ctx.event is the EventPayload envelope (optional)", () => {
26
+ expectTypeOf().toEqualTypeOf();
27
+ });
28
+ });
29
+ //#endregion
30
+ export {};
31
+
32
+ //# sourceMappingURL=event-payloads.test-d.js.map
@@ -1,6 +1,6 @@
1
1
  import "./chunk-gOLHoazu.js";
2
2
  import { step } from "./step.js";
3
- import { runIdempotentStep } from "@kici-dev/shared/idempotency";
3
+ import { runIdempotentStep } from "@kici-dev/core/idempotency";
4
4
  //#region src/idempotent.ts
5
5
  /**
6
6
  * SDK idempotency helpers for workflow authors.
package/dist/index.d.ts CHANGED
@@ -11,9 +11,12 @@ export { isEventType } from './rules/index.js';
11
11
  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';
12
12
  export { validateDag } from './validation/index.js';
13
13
  export type { DagNode, DagValidationResult } from './validation/index.js';
14
- export type { SourceLocation, OutputProxy, Step, StepOptions, StepRunFn, BareStepFn, StepInput, OutputSchema, InferOutputs, Job, JobOptions, ContainerConfig, RunsOnSelector, RunsOn, Workflow, WorkflowOptions, Registry, Trigger, DynamicJobFn, DynamicJobContext, JobOrFactory, } from './types.js';
14
+ export type { SourceLocation, OutputProxy, Step, StepOptions, StepRunFn, BareStepFn, StepInput, OutputSchema, InferOutputs, Job, JobOptions, GenericInitConfig, ContainerConfig, RunsOnSelector, RunsOn, Workflow, WorkflowOptions, Registry, Trigger, DynamicJobFn, DynamicJobContext, JobOrFactory, } from './types.js';
15
15
  export { isDynamicJobFn, dynamicJob, getDynamicJobGroup, DYNAMIC_JOB_GROUP_TAG } from './types.js';
16
16
  export type { TaggedDynamicJobFn } from './types.js';
17
+ export { CacheSpecSchema, normalizeCacheSpecs } from './cache-types.js';
18
+ export type { CacheSpec, CacheInput } from './cache-types.js';
19
+ export type { CacheRestoreResult, CacheApi } from './cache-types.js';
17
20
  export { dynamicGroup, isDynamicGroupRef, DYNAMIC_GROUP_TAG } from './dynamic-group.js';
18
21
  export type { DynamicGroupRef } from './dynamic-group.js';
19
22
  export type { StepContext, Logger, WorkflowInfo, JobInfo, RepoInfo, StepSecretsTyped, KnownSecretKeys, } from './context.js';
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import "./chunk-gOLHoazu.js";
2
2
  import { buildKiciApi } from "./api-types.js";
3
+ import { CacheSpecSchema, normalizeCacheSpecs } from "./cache-types.js";
3
4
  import { DYNAMIC_GROUP_TAG, dynamicGroup, isDynamicGroupRef } from "./dynamic-group.js";
4
5
  import { SecretNotFoundError } from "./errors.js";
5
6
  import { fixture } from "./fixture.js";
@@ -47,4 +48,4 @@ import { defineEvent } from "./events/define-event.js";
47
48
  import "./events/index.js";
48
49
  import { WaitForTimeoutError, waitFor, waitForStep } from "./wait-for.js";
49
50
  import { z } from "zod";
50
- export { DYNAMIC_GROUP_TAG, DYNAMIC_JOB_GROUP_TAG, SecretNotFoundError, WaitForTimeoutError, afterStep, applyIncludeExclude, beforeStep, buildKiciApi, cleanup, comment, create, createJobOutputProxy, createStepOutputProxy, createStepSecrets, defineEvent, del as delete, dispatch, dynamicGroup, dynamicJob, evaluateRules, expandMatrix, fixture, fork, genericWebhook, getDynamicJobGroup, getJobOutputsMap, getStepOutputsMap, getStepRefMap, idempotent, idempotentStep, isDynamicFunction, isDynamicGroupRef, isDynamicJobFn, isEventType, isStaticArray, isStaticObject, job, jobComplete, kiciEvent, lifecycle, onCancel, onFailure, onSuccess, pr, push, release, resolveJobOutputs, resolveStepOutputs, review, reviewComment, rule, schedule, setJobOutputsMap, setStepOutputsMap, setStepRefMap, skip, star, status, step, tag, validateDag, waitFor, waitForStep, watch, webhook, workflow, workflowComplete, workflowRun, z };
51
+ export { CacheSpecSchema, DYNAMIC_GROUP_TAG, DYNAMIC_JOB_GROUP_TAG, SecretNotFoundError, WaitForTimeoutError, afterStep, applyIncludeExclude, beforeStep, buildKiciApi, cleanup, comment, create, createJobOutputProxy, createStepOutputProxy, createStepSecrets, defineEvent, del as delete, dispatch, dynamicGroup, dynamicJob, evaluateRules, expandMatrix, fixture, fork, genericWebhook, getDynamicJobGroup, getJobOutputsMap, getStepOutputsMap, getStepRefMap, idempotent, idempotentStep, isDynamicFunction, isDynamicGroupRef, isDynamicJobFn, isEventType, isStaticArray, isStaticObject, job, jobComplete, kiciEvent, lifecycle, normalizeCacheSpecs, onCancel, onFailure, onSuccess, pr, push, release, resolveJobOutputs, resolveStepOutputs, review, reviewComment, rule, schedule, setJobOutputsMap, setStepOutputsMap, setStepRefMap, skip, star, status, step, tag, validateDag, waitFor, waitForStep, watch, webhook, workflow, workflowComplete, workflowRun, z };
package/dist/job.js CHANGED
@@ -3,6 +3,17 @@ import { createJobOutputProxy } from "./outputs.js";
3
3
  import { randomUUID } from "node:crypto";
4
4
  //#region src/job.ts
5
5
  /**
6
+ * Validate a job's `init` config. `undefined` / `false` are no-ops; every
7
+ * remaining spec (one, or each element of an array) must carry a non-empty
8
+ * `run` command. Throws with the offending index when validation fails.
9
+ */
10
+ function validateInit(init, jobName) {
11
+ if (init === void 0 || init === false) return;
12
+ (Array.isArray(init) ? init : [init]).forEach((spec, i) => {
13
+ if (typeof spec.run !== "string" || spec.run.trim().length === 0) throw new Error(`job('${jobName}'): init[${i}].run must be a non-empty command`);
14
+ });
15
+ }
16
+ /**
6
17
  * Implementation of job() factory.
7
18
  */
8
19
  function job(nameOrOptions, maybeOptions) {
@@ -13,6 +24,7 @@ function job(nameOrOptions, maybeOptions) {
13
24
  if (options.steps && options.steps.length > 0) throw new Error("job() cannot have both \"run\" and \"steps\" -- use one or the other");
14
25
  steps = [options.run];
15
26
  }
27
+ validateInit(options.init, name);
16
28
  return {
17
29
  _tag: "Job",
18
30
  name,
@@ -36,7 +48,10 @@ function job(nameOrOptions, maybeOptions) {
36
48
  beforeStep: options.beforeStep,
37
49
  afterStep: options.afterStep,
38
50
  gracePeriod: options.gracePeriod,
51
+ timeout: options.timeout,
39
52
  resources: options.resources,
53
+ init: options.init,
54
+ ...options.cache !== void 0 && { cache: options.cache },
40
55
  result: createJobOutputProxy(name)
41
56
  };
42
57
  }
@@ -1,5 +1,5 @@
1
1
  import "../chunk-gOLHoazu.js";
2
- import { toErrorMessage } from "@kici-dev/shared";
2
+ import { toErrorMessage } from "@kici-dev/core";
3
3
  //#region src/rules/evaluator.ts
4
4
  /**
5
5
  * Evaluate rules sequentially with fail-fast behavior.
package/dist/step.js CHANGED
@@ -65,6 +65,7 @@ function step(nameOrRunOrOptions, runOrOptions) {
65
65
  run: options.run,
66
66
  continueOnError: options.continueOnError,
67
67
  timeout: options.timeout,
68
+ ...options.cache !== void 0 && { cache: options.cache },
68
69
  rules: options.rules,
69
70
  onCancel: options.onCancel,
70
71
  cleanup: options.cleanup,
package/dist/types.d.ts CHANGED
@@ -8,6 +8,7 @@ import type { Matrix, MatrixInclude, MatrixExclude } from './matrix/types.js';
8
8
  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
+ import type { EventPayload } from './events/event-payloads.js';
11
12
  export type { ResourceRequest, ResourceSpec } from '@kici-dev/engine';
12
13
  /** Source location captured at a step() call site. */
13
14
  export interface SourceLocation {
@@ -44,6 +45,8 @@ export interface Step<TResult = void> {
44
45
  readonly continueOnError?: boolean;
45
46
  /** Step-level timeout in milliseconds. Overrides the agent's default (30 minutes). */
46
47
  readonly timeout?: number;
48
+ /** Declarative cache: restored before this step, saved after on key miss. */
49
+ readonly cache?: import('./cache-types.js').CacheInput;
47
50
  /** Step-level conditional rules (evaluated agent-side). */
48
51
  readonly rules?: Rule[];
49
52
  /** Runs on cancellation. */
@@ -80,6 +83,8 @@ export interface StepOptions<TResult = void> {
80
83
  continueOnError?: boolean;
81
84
  /** Step-level timeout in milliseconds. Overrides the agent's default (30 minutes). */
82
85
  timeout?: number;
86
+ /** Declarative cache: restored before this step, saved after on key miss. */
87
+ cache?: import('./cache-types.js').CacheInput;
83
88
  /** Step-level conditional rules (evaluated agent-side). */
84
89
  rules?: Rule[];
85
90
  /** Runs on cancellation. */
@@ -114,7 +119,8 @@ export interface DynamicJobContext {
114
119
  workflow: {
115
120
  name: string;
116
121
  };
117
- event?: Record<string, unknown>;
122
+ /** Normalized event envelope that triggered this run. */
123
+ event?: EventPayload;
118
124
  };
119
125
  /** Structured logger */
120
126
  log: Logger;
@@ -176,6 +182,29 @@ export interface ContainerConfig {
176
182
  /** Additional environment variables for the container */
177
183
  env?: Record<string, string>;
178
184
  }
185
+ /**
186
+ * Generic per-job initialization config. Runs a hand-written command after the
187
+ * repo is cloned and before the job's steps execute, so a repo-declared
188
+ * toolchain (mise, a custom setup script, …) is provisioned and put on the
189
+ * step environment's PATH.
190
+ *
191
+ * The command writes env it wants visible to later steps to the file at
192
+ * `$KICI_ENV` (one `KEY=value` line each) and PATH additions to `$KICI_PATH`
193
+ * (one directory per line) — the agent reads both after the command and applies
194
+ * the delta to every subsequent step.
195
+ */
196
+ export interface GenericInitConfig {
197
+ /** Command run after clone, before steps. Runs in the job's sandbox at the clone root. */
198
+ run: string;
199
+ /** Shell used to run `run`. Defaults to 'bash'. */
200
+ shell?: string;
201
+ /** Cache spec for binaries the command fetches/installs (restored before, saved after on key miss). */
202
+ cache?: import('./cache-types.js').CacheSpec;
203
+ /** Max wall-clock for this init command in ms. Reuses the step/job timeout semantics. */
204
+ timeout?: number;
205
+ /** Static environment variables available to the command. */
206
+ env?: Record<string, string>;
207
+ }
179
208
  /**
180
209
  * Structured runsOn selector with required and excluded labels.
181
210
  * Used when jobs need to target specific agents while excluding others.
@@ -226,12 +255,12 @@ export interface Job {
226
255
  readonly checkout?: boolean;
227
256
  /** Docker image for job execution. All steps run inside the container. */
228
257
  readonly container?: string | ContainerConfig;
229
- /** Deployment environment for this job. String for static, async function for dynamic (resolved at orchestrator two-phase eval). */
230
- readonly environment?: string | ((event: Record<string, unknown>) => string | Promise<string>);
231
- /** Environment variables. Static object or async function (resolved at orchestrator two-phase eval). */
232
- readonly env?: Record<string, string> | ((event: Record<string, unknown>) => Record<string, string> | Promise<Record<string, string>>);
233
- /** Concurrency group name. Defaults to environment name if not set. String or async function. */
234
- readonly concurrencyGroup?: string | ((event: Record<string, unknown>) => string | Promise<string>);
258
+ /** Deployment environment for this job. String for static, or a function of the normalized event envelope for dynamic (resolved at orchestrator two-phase eval). */
259
+ readonly environment?: string | ((event: EventPayload) => string | Promise<string>);
260
+ /** Environment variables. Static object or a function of the normalized event envelope (resolved at orchestrator two-phase eval). */
261
+ readonly env?: Record<string, string> | ((event: EventPayload) => Record<string, string> | Promise<Record<string, string>>);
262
+ /** Concurrency group name. Defaults to environment name if not set. String or a function of the normalized event envelope. */
263
+ readonly concurrencyGroup?: string | ((event: EventPayload) => string | Promise<string>);
235
264
  /** Runs on cancellation. */
236
265
  readonly onCancel?: HookInput;
237
266
  /** Always runs after job (success, failure, or cancel). */
@@ -246,6 +275,8 @@ export interface Job {
246
275
  readonly afterStep?: HookInput;
247
276
  /** Seconds before SIGKILL after SIGTERM during cancellation. */
248
277
  readonly gracePeriod?: number;
278
+ /** Total job wall-clock timeout in milliseconds (init + all steps + hooks). On breach the job is aborted and reported timed out. Agent-enforced. Independent of step-level timeout. */
279
+ readonly timeout?: number;
249
280
  /**
250
281
  * Resource request and limit for this job. Used by the scaler to enforce
251
282
  * per-scaler / per-orchestrator / per-machine caps and the kernel-side limits
@@ -260,6 +291,14 @@ export interface Job {
260
291
  * toward the agent-count cap.
261
292
  */
262
293
  readonly resources?: ResourceRequest;
294
+ /**
295
+ * Per-job initialization. Runs after clone, before steps.
296
+ * - A `GenericInitConfig` (or array, run in order) provisions a toolchain.
297
+ * - `false` is an explicit opt-out (reserved for the future auto-detect layer).
298
+ */
299
+ readonly init?: GenericInitConfig | GenericInitConfig[] | false;
300
+ /** Declarative cache: restored before steps, saved after the job on key miss. */
301
+ readonly cache?: import('./cache-types.js').CacheInput;
263
302
  /**
264
303
  * Type-safe proxy for accessing this job's outputs.
265
304
  * For multi-step jobs: jobRef.result.stepName.field
@@ -317,12 +356,12 @@ export interface JobOptions {
317
356
  * When set, all steps run inside the container.
318
357
  */
319
358
  container?: string | ContainerConfig;
320
- /** Deployment environment for this job. String for static, async function for dynamic (resolved at orchestrator two-phase eval). */
321
- environment?: string | ((event: Record<string, unknown>) => string | Promise<string>);
322
- /** Environment variables. Static object or async function (resolved at orchestrator two-phase eval). */
323
- env?: Record<string, string> | ((event: Record<string, unknown>) => Record<string, string> | Promise<Record<string, string>>);
324
- /** Concurrency group name. Defaults to environment name if not set. String or async function. */
325
- concurrencyGroup?: string | ((event: Record<string, unknown>) => string | Promise<string>);
359
+ /** Deployment environment for this job. String for static, or a function of the normalized event envelope for dynamic (resolved at orchestrator two-phase eval). */
360
+ environment?: string | ((event: EventPayload) => string | Promise<string>);
361
+ /** Environment variables. Static object or a function of the normalized event envelope (resolved at orchestrator two-phase eval). */
362
+ env?: Record<string, string> | ((event: EventPayload) => Record<string, string> | Promise<Record<string, string>>);
363
+ /** Concurrency group name. Defaults to environment name if not set. String or a function of the normalized event envelope. */
364
+ concurrencyGroup?: string | ((event: EventPayload) => string | Promise<string>);
326
365
  /** Runs on cancellation. */
327
366
  onCancel?: HookInput;
328
367
  /** Always runs after job (success, failure, or cancel). */
@@ -337,6 +376,8 @@ export interface JobOptions {
337
376
  afterStep?: HookInput;
338
377
  /** Seconds before SIGKILL after SIGTERM during cancellation. */
339
378
  gracePeriod?: number;
379
+ /** Total job wall-clock timeout in milliseconds (init + all steps + hooks). On breach the job is aborted and reported timed out. Agent-enforced. Independent of step-level timeout. */
380
+ timeout?: number;
340
381
  /**
341
382
  * Resource request and limit for this job. Used by the scaler to enforce
342
383
  * per-scaler / per-orchestrator / per-machine caps and the kernel-side limits
@@ -351,6 +392,14 @@ export interface JobOptions {
351
392
  * toward the agent-count cap.
352
393
  */
353
394
  resources?: ResourceRequest;
395
+ /**
396
+ * Per-job initialization. Runs after clone, before steps.
397
+ * - A `GenericInitConfig` (or array, run in order) provisions a toolchain.
398
+ * - `false` is an explicit opt-out (reserved for the future auto-detect layer).
399
+ */
400
+ init?: GenericInitConfig | GenericInitConfig[] | false;
401
+ /** Declarative cache: restored before steps, saved after the job on key miss. */
402
+ cache?: import('./cache-types.js').CacheInput;
354
403
  }
355
404
  /**
356
405
  * Private npm registry declaration. Tells the agent to authenticate against
@@ -409,6 +458,8 @@ export interface Workflow {
409
458
  * prefix is stripped for the env-var name).
410
459
  */
411
460
  readonly installEnv?: readonly string[];
461
+ /** Whole-run wall-clock timeout in milliseconds across all jobs. On breach the orchestrator cancels outstanding/queued jobs and marks the run timed out. Orchestrator-enforced. Independent of job-level timeout. */
462
+ readonly timeout?: number;
412
463
  /** Runs on cancellation. */
413
464
  readonly onCancel?: HookInput;
414
465
  /** Always runs after workflow (success, failure, or cancel). */
@@ -421,7 +472,7 @@ export interface Workflow {
421
472
  readonly concurrency?: {
422
473
  readonly group: (ctx: {
423
474
  branch: string;
424
- event: Record<string, unknown>;
475
+ event: EventPayload;
425
476
  }) => string;
426
477
  readonly cancelInProgress?: boolean;
427
478
  readonly max?: number;
@@ -458,6 +509,8 @@ export interface WorkflowOptions {
458
509
  * exposed to the install subprocess under the `<secret-name>` key.
459
510
  */
460
511
  installEnv?: string[];
512
+ /** Whole-run wall-clock timeout in milliseconds across all jobs. On breach the orchestrator cancels outstanding/queued jobs and marks the run timed out. Orchestrator-enforced. Independent of job-level timeout. */
513
+ timeout?: number;
461
514
  /** Runs on cancellation. */
462
515
  onCancel?: HookInput;
463
516
  /** Always runs after workflow (success, failure, or cancel). */
@@ -470,7 +523,7 @@ export interface WorkflowOptions {
470
523
  concurrency?: {
471
524
  group: (ctx: {
472
525
  branch: string;
473
- event: Record<string, unknown>;
526
+ event: EventPayload;
474
527
  }) => string;
475
528
  cancelInProgress?: boolean;
476
529
  max?: number;
package/dist/workflow.js CHANGED
@@ -70,6 +70,7 @@ function workflow(name, options) {
70
70
  hashFiles: options.hashFiles,
71
71
  registries: options.registries,
72
72
  installEnv: options.installEnv,
73
+ timeout: options.timeout,
73
74
  onCancel: options.onCancel,
74
75
  cleanup: options.cleanup,
75
76
  onSuccess: options.onSuccess,
package/package.json CHANGED
@@ -1,18 +1,22 @@
1
1
  {
2
2
  "name": "@kici-dev/sdk",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
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
- "kici",
7
6
  "ci",
8
- "cd",
9
- "ci-cd",
7
+ "cicd",
8
+ "continuous-integration",
10
9
  "typescript",
11
- "workflows",
12
- "devops",
10
+ "workflow",
13
11
  "sdk",
14
- "dsl"
12
+ "pipeline"
15
13
  ],
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/kici-dev/kici-public.git",
17
+ "directory": "packages/sdk"
18
+ },
19
+ "bugs": "https://github.com/kici-dev/kici-public/issues",
16
20
  "homepage": "https://kici.dev",
17
21
  "author": {
18
22
  "name": "KiCI",
@@ -46,8 +50,8 @@
46
50
  "micromatch": "^4.0.8",
47
51
  "zod": "^4.3.6",
48
52
  "zx": "^8.8.5",
49
- "@kici-dev/engine": "0.1.13",
50
- "@kici-dev/shared": "0.1.13"
53
+ "@kici-dev/core": "0.1.15",
54
+ "@kici-dev/engine": "0.1.15"
51
55
  },
52
56
  "devDependencies": {
53
57
  "@types/micromatch": "^4.0.10"