@kici-dev/compiler 0.1.14 → 0.1.16

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.
Files changed (68) hide show
  1. package/README.md +21 -1
  2. package/dist/cli.d.ts +9 -1
  3. package/dist/cli.js +213 -179
  4. package/dist/commands/approve.d.ts +23 -0
  5. package/dist/commands/approve.js +46 -0
  6. package/dist/commands/compile.js +1 -1
  7. package/dist/commands/docs.js +2 -2
  8. package/dist/commands/endpoints.js +1 -1
  9. package/dist/commands/held-run-client.d.ts +26 -0
  10. package/dist/commands/held-run-client.js +98 -0
  11. package/dist/commands/held-run-resolve.d.ts +45 -0
  12. package/dist/commands/held-run-resolve.js +53 -0
  13. package/dist/commands/hook.js +1 -1
  14. package/dist/commands/index.d.ts +4 -0
  15. package/dist/commands/index.js +3 -1
  16. package/dist/commands/init.js +1 -1
  17. package/dist/commands/login.js +4 -15
  18. package/dist/commands/reject.d.ts +25 -0
  19. package/dist/commands/reject.js +49 -0
  20. package/dist/commands/run.js +13 -2
  21. package/dist/commands/secrets-list.js +1 -1
  22. package/dist/commands/status.js +1 -1
  23. package/dist/commands/test.d.ts +2 -0
  24. package/dist/commands/test.js +1 -1
  25. package/dist/commands/types.js +1 -1
  26. package/dist/commands/watch.js +1 -1
  27. package/dist/execution/executor.js +2 -2
  28. package/dist/execution/sdk-alias.js +1 -1
  29. package/dist/fixtures/compiler.js +2 -2
  30. package/dist/fixtures/defaults/index.js +2 -2
  31. package/dist/hooks/detector.js +1 -1
  32. package/dist/hooks/installer.js +1 -1
  33. package/dist/index.d.ts +1 -1
  34. package/dist/llm-context/llms-full.txt +1141 -349
  35. package/dist/llm-context/llms.txt +4 -2
  36. package/dist/local-executor/index.js +5 -4
  37. package/dist/local-executor/job-runner.js +3 -5
  38. package/dist/local-executor/materializer.d.ts +5 -0
  39. package/dist/local-executor/materializer.js +23 -2
  40. package/dist/local-executor/secret-loader.js +1 -1
  41. package/dist/local-executor/to-event-payload.d.ts +16 -0
  42. package/dist/local-executor/to-event-payload.js +21 -0
  43. package/dist/local-executor/workflow-lock.d.ts +4 -3
  44. package/dist/local-executor/workflow-lock.js +0 -0
  45. package/dist/lockfile/generator.js +22 -5
  46. package/dist/lockfile/hash-files.js +1 -1
  47. package/dist/postinstall.js +1 -1
  48. package/dist/remote/client.d.ts +4 -0
  49. package/dist/remote/config.js +1 -1
  50. package/dist/remote/history.js +1 -1
  51. package/dist/remote/prod-defaults.d.ts +18 -0
  52. package/dist/remote/prod-defaults.js +23 -0
  53. package/dist/remote/secret-upload.d.ts +20 -0
  54. package/dist/remote/secret-upload.js +58 -0
  55. package/dist/remote/uploader.js +1 -1
  56. package/dist/templates/index.js +1 -1
  57. package/dist/templates/package-json.js +1 -1
  58. package/dist/templates/workflows/pr-checks.js +3 -2
  59. package/dist/templates/workflows/pr-checks.ts +4 -2
  60. package/dist/test-runner/git-detector.js +1 -1
  61. package/dist/test-runner/job-executor.js +2 -2
  62. package/dist/test-runner/secrets-file.js +1 -1
  63. package/dist/test-runner/step-context.js +6 -2
  64. package/dist/types.d.ts +33 -2
  65. package/dist/types.js +1 -0
  66. package/dist/workflows/pr-checks.ts +4 -2
  67. package/package.json +13 -9
  68. package/sbom.spdx.json +34 -34
@@ -7,7 +7,7 @@ The full markdown bundle of every page indexed here is available at https://docs
7
7
  ## Getting started
8
8
 
9
9
  - [User guide](https://docs.kici.dev/user/): Writing and testing CI/CD workflows in TypeScript
10
- - [Getting started with KiCI](https://docs.kici.dev/user/getting-started/): Install the SDK, write your first workflow, compile and test locally
10
+ - [Getting started with workflows](https://docs.kici.dev/user/getting-started/): Install the SDK, write your first workflow, compile and test locally
11
11
  - [5-minute quickstart](https://docs.kici.dev/user/quickstart/): Stand up a KiCI orchestrator + agent and run your first workflow
12
12
 
13
13
  ## Workflow patterns
@@ -20,7 +20,9 @@ The full markdown bundle of every page indexed here is available at https://docs
20
20
 
21
21
  ## SDK reference
22
22
 
23
+ - [Caching](https://docs.kici.dev/user/sdk/caching/): Cache files and directories across runs with declarative job/step cache or the imperative ctx.cache API
23
24
  - [SDK reference: core](https://docs.kici.dev/user/sdk/core/): Factory functions (workflow, job, step) and authoring patterns: needs, output chaining, dynamic groups
25
+ - [Event payload reference](https://docs.kici.dev/user/sdk/event-payloads/): Generated schema of the normalized event envelope passed to rules and dynamic functions.
24
26
  - [SDK reference: idempotent](https://docs.kici.dev/user/sdk/idempotent/): Idempotent helpers for declarative check / apply patterns inside workflow steps
25
27
  - [SDK reference: rules, matrix, dynamic jobs](https://docs.kici.dev/user/sdk/rules-matrix-dynamic/): rule(), skip(), matrix builds (static + dynamic), and dynamicJob / dynamicGroup
26
28
  - [SDK reference: runtime](https://docs.kici.dev/user/sdk/runtime/): Types index, StepContext, secrets, fixtures
@@ -40,6 +42,7 @@ The full markdown bundle of every page indexed here is available at https://docs
40
42
 
41
43
  ## Workflow features
42
44
 
45
+ - [Account and sign-in](https://docs.kici.dev/user/account-and-login/): How your KiCI account relates to sign-in methods, and how to change the way you sign in.
43
46
  - [Concurrency groups](https://docs.kici.dev/user/concurrency/): Control parallel execution with auto-cancel and queue modes
44
47
  - [Dashboard](https://docs.kici.dev/user/dashboard/)
45
48
  - [Dynamic values](https://docs.kici.dev/user/dynamic-values/)
@@ -58,5 +61,4 @@ The full markdown bundle of every page indexed here is available at https://docs
58
61
  ## Architecture overview
59
62
 
60
63
  - [Data flows](https://docs.kici.dev/architecture/data-flows/): End-to-end data flows through the KiCI three-tier architecture
61
- - [Design decisions](https://docs.kici.dev/architecture/design-decisions/): Why KiCI's architecture is shaped the way it is
62
64
  - [Architecture overview](https://docs.kici.dev/architecture/overview/): Three-tier relay model, package structure, and component responsibilities
@@ -2,18 +2,18 @@ import "../chunk-gOLHoazu.js";
2
2
  import { discoverWorkflows, resolveKiciDir } from "../execution/executor.js";
3
3
  import "../execution/index.js";
4
4
  import { transformTriggers } from "../lockfile/generator.js";
5
+ import { loadLocalSecrets } from "./secret-loader.js";
5
6
  import { executeDag, resolveJobFilter } from "./dag-scheduler.js";
6
7
  import { compileCommand } from "../commands/compile.js";
7
- import { loadLocalSecrets } from "./secret-loader.js";
8
8
  import { generateEventPayload } from "./payload-generator.js";
9
9
  import { executeResolvedJob, resolveJobs } from "./job-runner.js";
10
10
  import { displayLocalSummary, formatLocalJsonResult, formatLocalJunitResult } from "./output-streamer.js";
11
11
  import { PickerCancelledError, runPicker } from "./picker.js";
12
- import { materializeCheckout } from "./materializer.js";
12
+ import { gcStaleRunCheckouts, materializeCheckout } from "./materializer.js";
13
13
  import { ConcurrencyKeyEvaluationError, acquireWorkflowLock } from "./workflow-lock.js";
14
+ import path from "node:path";
14
15
  import pc from "picocolors";
15
16
  import { writeFile } from "node:fs/promises";
16
- import path from "node:path";
17
17
  import { logger } from "@kici-dev/core";
18
18
  import { matchAllWorkflows } from "@kici-dev/engine";
19
19
  import os from "node:os";
@@ -107,7 +107,7 @@ async function runOneMatchedWorkflow(workflow, ctx) {
107
107
  lockHandle = await acquireWorkflowLock({
108
108
  workflowName: workflow.name,
109
109
  workflow,
110
- event: event.payload,
110
+ event,
111
111
  branch: deriveBranchForGroupCtx(event),
112
112
  debug: options.debug
113
113
  });
@@ -272,6 +272,7 @@ async function executeLocal(options) {
272
272
  let materialized = null;
273
273
  let execDir = repoRoot;
274
274
  if (!options.inPlace) {
275
+ await gcStaleRunCheckouts(process.env.KICI_RUN_DIR ?? os.tmpdir());
275
276
  materialized = await materializeCheckout(repoRoot, { runDir: process.env.KICI_RUN_DIR });
276
277
  execDir = materialized.path;
277
278
  logger.info(pc.gray(`running in ${execDir}`));
@@ -3,8 +3,9 @@ import { ensureTsLoaderHook } from "../execution/ts-loader.js";
3
3
  import { formatter } from "../test-runner/output-formatter.js";
4
4
  import { createStepContext } from "../test-runner/step-context.js";
5
5
  import { createRuleContext, evaluateRules as evaluateRulesWithFormatting } from "../test-runner/rule-evaluator.js";
6
- import path from "node:path";
6
+ import { toEventPayload } from "./to-event-payload.js";
7
7
  import { pathToFileURL } from "node:url";
8
+ import path from "node:path";
8
9
  import { applyIncludeExclude, expandMatrix, isDynamicJobFn, setJobOutputsMap, setStepOutputsMap, setStepRefMap } from "@kici-dev/sdk";
9
10
  //#region src/local-executor/job-runner.ts
10
11
  /**
@@ -72,10 +73,7 @@ async function resolveJobs(workflow, event) {
72
73
  $: (await import("zx")).$,
73
74
  ctx: {
74
75
  workflow: { name: workflow.name },
75
- event: {
76
- type: event.type,
77
- ...event.payload
78
- }
76
+ event: toEventPayload(event)
79
77
  },
80
78
  log: {
81
79
  info: () => {},
@@ -36,4 +36,9 @@ export interface MaterializeOptions {
36
36
  * @throws If `repoRoot` is not inside a git work tree
37
37
  */
38
38
  export declare function materializeCheckout(repoRoot: string, opts?: MaterializeOptions): Promise<MaterializedCheckout>;
39
+ /**
40
+ * Collect stale retained checkouts under the run base. Invoked on every
41
+ * `kici run local`; never throws (the GC must not break the run).
42
+ */
43
+ export declare function gcStaleRunCheckouts(base: string): Promise<string[]>;
39
44
  //# sourceMappingURL=materializer.d.ts.map
@@ -1,10 +1,12 @@
1
1
  import "../chunk-gOLHoazu.js";
2
2
  import { selectOverlayFiles } from "../remote/uploader.js";
3
- import fs from "node:fs/promises";
4
3
  import path from "node:path";
4
+ import fs from "node:fs/promises";
5
+ import { logger } from "@kici-dev/core";
5
6
  import { execSync } from "node:child_process";
6
7
  import os from "node:os";
7
8
  import { randomBytes } from "node:crypto";
9
+ import { gcStaleTmpDirs } from "@kici-dev/core/tmp-gc";
8
10
  //#region src/local-executor/materializer.ts
9
11
  /**
10
12
  * Materialize an isolated tmp checkout of the repo for `kici run local`.
@@ -52,6 +54,25 @@ async function materializeCheckout(repoRoot, opts) {
52
54
  };
53
55
  }
54
56
  /**
57
+ * Checkouts retained for inspection (failed runs, --keep) stay around this
58
+ * long before the next `kici run local` invocation collects them.
59
+ */
60
+ const RUN_CHECKOUT_GC_MAX_AGE_MS = 4320 * 60 * 1e3;
61
+ /** Matches the kici-run-<6 hex> dirs materializeCheckout creates — nothing else. */
62
+ const RUN_CHECKOUT_PATTERN = /^kici-run-[0-9a-f]{6}$/;
63
+ /**
64
+ * Collect stale retained checkouts under the run base. Invoked on every
65
+ * `kici run local`; never throws (the GC must not break the run).
66
+ */
67
+ async function gcStaleRunCheckouts(base) {
68
+ return gcStaleTmpDirs({
69
+ base,
70
+ pattern: RUN_CHECKOUT_PATTERN,
71
+ maxAgeMs: RUN_CHECKOUT_GC_MAX_AGE_MS,
72
+ log: (m) => logger.debug(m)
73
+ });
74
+ }
75
+ /**
55
76
  * Throw an actionable error if `repoRoot` is not a git work tree.
56
77
  */
57
78
  function requireGitRepo(repoRoot) {
@@ -106,6 +127,6 @@ function shellQuote(value) {
106
127
  return `'${value.replace(/'/g, `'\\''`)}'`;
107
128
  }
108
129
  //#endregion
109
- export { materializeCheckout };
130
+ export { gcStaleRunCheckouts, materializeCheckout };
110
131
 
111
132
  //# sourceMappingURL=materializer.js.map
@@ -1,7 +1,7 @@
1
1
  import "../chunk-gOLHoazu.js";
2
2
  import { loadSecretsFile } from "../test-runner/secrets-file.js";
3
- import { readFile } from "node:fs/promises";
4
3
  import path from "node:path";
4
+ import { readFile } from "node:fs/promises";
5
5
  import { parse } from "yaml";
6
6
  //#region src/local-executor/secret-loader.ts
7
7
  /**
@@ -0,0 +1,16 @@
1
+ import type { SimulatedEvent } from '@kici-dev/engine';
2
+ import type { EventPayload } from '@kici-dev/sdk';
3
+ /**
4
+ * Map a {@link SimulatedEvent} into the normalized SDK {@link EventPayload}
5
+ * envelope that every user-authored dynamic function (dynamic job generators,
6
+ * `concurrency.group()`) receives as its `event` argument.
7
+ *
8
+ * `SimulatedEvent` already carries the normalized fields (`type`, `action`,
9
+ * `targetBranch`, …) alongside the raw provider body under `payload`, so the
10
+ * single cast at this boundary is a deliberate type assertion over a
11
+ * structurally-identical value: it asserts the discriminated-union view
12
+ * without reshaping anything. Raw provider fields stay nested under
13
+ * `payload.<field>`; normalized fields live at the top level.
14
+ */
15
+ export declare function toEventPayload(event: SimulatedEvent): EventPayload;
16
+ //# sourceMappingURL=to-event-payload.d.ts.map
@@ -0,0 +1,21 @@
1
+ import "../chunk-gOLHoazu.js";
2
+ //#region src/local-executor/to-event-payload.ts
3
+ /**
4
+ * Map a {@link SimulatedEvent} into the normalized SDK {@link EventPayload}
5
+ * envelope that every user-authored dynamic function (dynamic job generators,
6
+ * `concurrency.group()`) receives as its `event` argument.
7
+ *
8
+ * `SimulatedEvent` already carries the normalized fields (`type`, `action`,
9
+ * `targetBranch`, …) alongside the raw provider body under `payload`, so the
10
+ * single cast at this boundary is a deliberate type assertion over a
11
+ * structurally-identical value: it asserts the discriminated-union view
12
+ * without reshaping anything. Raw provider fields stay nested under
13
+ * `payload.<field>`; normalized fields live at the top level.
14
+ */
15
+ function toEventPayload(event) {
16
+ return event;
17
+ }
18
+ //#endregion
19
+ export { toEventPayload };
20
+
21
+ //# sourceMappingURL=to-event-payload.js.map
@@ -20,6 +20,7 @@
20
20
  * `os.tmpdir()/kici-local-locks-<uid>/`).
21
21
  */
22
22
  import type { Workflow } from '@kici-dev/sdk';
23
+ import type { SimulatedEvent } from '@kici-dev/engine';
23
24
  /** Sidecar metadata persisted next to the lock dir for diagnostics + reclamation. */
24
25
  export interface LockHolderMetadata {
25
26
  pid: number;
@@ -35,8 +36,8 @@ export interface WorkflowLockHandle {
35
36
  export interface AcquireWorkflowLockOptions {
36
37
  workflowName: string;
37
38
  workflow: Workflow;
38
- /** The simulated-event payload object passed as `groupCtx.event` to the user's group fn. */
39
- event: Record<string, unknown>;
39
+ /** The simulated event mapped to the normalized envelope passed as `groupCtx.event`. */
40
+ event: SimulatedEvent;
40
41
  /** Branch derived from the simulated event for `groupCtx.branch`. */
41
42
  branch: string;
42
43
  debug?: boolean;
@@ -68,7 +69,7 @@ export declare function resolveLockDir(): Promise<string>;
68
69
  * Returns `null` when the workflow has no `concurrency` block. Throws
69
70
  * {@link ConcurrencyKeyEvaluationError} when the group function throws or rejects.
70
71
  */
71
- export declare function resolveConcurrencyKey(workflow: Workflow, event: Record<string, unknown>, branch: string): Promise<string | null>;
72
+ export declare function resolveConcurrencyKey(workflow: Workflow, event: SimulatedEvent, branch: string): Promise<string | null>;
72
73
  /**
73
74
  * Acquire the workflow-level concurrency lock for a `kici run local` invocation.
74
75
  *
@@ -3,9 +3,9 @@ import { SCHEMA_VERSION as SCHEMA_VERSION$1 } from "../types.js";
3
3
  import { computeContentHash } from "./hasher.js";
4
4
  import { resolveHashFiles } from "./hash-files.js";
5
5
  import { analyzePurity } from "./purity-analyzer.js";
6
- import { readFileSync } from "node:fs";
7
6
  import path from "node:path";
8
- import { getDynamicJobGroup, isDynamicFunction, isDynamicGroupRef, isDynamicJobFn, isStaticArray, isStaticObject } from "@kici-dev/sdk";
7
+ import { readFileSync } from "node:fs";
8
+ import { getDynamicJobGroup, isDynamicFunction, isDynamicGroupRef, isDynamicJobFn, isStaticArray, isStaticObject, normalizeCacheSpecs, normalizeRequireApproval } from "@kici-dev/sdk";
9
9
  import { sha256 } from "@kici-dev/core";
10
10
  import { PackageManager, detectPackageManagerSync } from "@kici-dev/core/package-manager";
11
11
  import { validateResourceRequest } from "@kici-dev/engine";
@@ -151,7 +151,9 @@ function transformWorkflow(workflow, sourceFile, exportRef, bundleSource, gitRoo
151
151
  hasGroup: !!workflow.concurrency.group,
152
152
  ...workflow.concurrency.cancelInProgress !== void 0 && { cancelInProgress: workflow.concurrency.cancelInProgress },
153
153
  ...workflow.concurrency.max !== void 0 && { max: workflow.concurrency.max }
154
- } }
154
+ } },
155
+ ...workflow.timeout !== void 0 && { timeout: workflow.timeout },
156
+ ...workflow.requireApproval !== void 0 && { approval: toLockApproval(workflow.requireApproval) }
155
157
  };
156
158
  }
157
159
  /**
@@ -528,6 +530,7 @@ function transformJob(job, configPath, index, gitRoot, uuidToName) {
528
530
  rules: job.rules ? transformRules(job.rules, configPath, index) : void 0,
529
531
  description: job.description,
530
532
  ...job.checkout !== void 0 && { checkout: job.checkout },
533
+ ...job.cache !== void 0 && { cache: normalizeCacheSpecs(job.cache) },
531
534
  ...job.container !== void 0 && { container: job.container },
532
535
  ...environmentFields,
533
536
  ...envFields,
@@ -539,7 +542,10 @@ function transformJob(job, configPath, index, gitRoot, uuidToName) {
539
542
  ...job.beforeStep !== void 0 && { hasBeforeStep: true },
540
543
  ...job.afterStep !== void 0 && { hasAfterStep: true },
541
544
  ...job.gracePeriod !== void 0 && { gracePeriod: job.gracePeriod },
542
- ...job.resources !== void 0 && { resources: job.resources }
545
+ ...job.timeout !== void 0 && { timeout: job.timeout },
546
+ ...job.resources !== void 0 && { resources: job.resources },
547
+ ...job.init !== void 0 && { init: job.init },
548
+ ...job.requireApproval !== void 0 && { approval: toLockApproval(job.requireApproval) }
543
549
  };
544
550
  }
545
551
  /**
@@ -587,6 +593,15 @@ function resolveNeedsForLock(needs, uuidToName) {
587
593
  * Assigns counter-based IDs to unnamed steps (bare functions and id-less steps).
588
594
  * Counter only increments for unnamed entries; named steps keep their names.
589
595
  */
596
+ /** Map an SDK `requireApproval` to the normalized lock `approval` block. */
597
+ function toLockApproval(r) {
598
+ const n = normalizeRequireApproval(r);
599
+ return {
600
+ clauses: n.clauses,
601
+ ...n.reason !== void 0 && { reason: n.reason },
602
+ ...n.timeoutSeconds !== void 0 && { timeoutSeconds: n.timeoutSeconds }
603
+ };
604
+ }
590
605
  function transformSteps(steps, gitRoot) {
591
606
  let stepCounter = 0;
592
607
  return steps.map((stepOrFn) => {
@@ -603,6 +618,7 @@ function transformSteps(steps, gitRoot) {
603
618
  hasOutputs: !!step.outputs && Object.keys(step.outputs).length > 0,
604
619
  ...step.continueOnError !== void 0 && { continueOnError: step.continueOnError },
605
620
  ...step.timeout !== void 0 && { timeout: step.timeout },
621
+ ...step.cache !== void 0 && { cache: normalizeCacheSpecs(step.cache) },
606
622
  ...step._sourceLocation && { sourceLocation: {
607
623
  file: makeRelativePath(step._sourceLocation.file, gitRoot),
608
624
  line: step._sourceLocation.line,
@@ -613,7 +629,8 @@ function transformSteps(steps, gitRoot) {
613
629
  rules: transformRules(step.rules, makeRelativePath(step._sourceLocation?.file ?? "", gitRoot))
614
630
  },
615
631
  ...step.onCancel !== void 0 && { hasOnCancel: true },
616
- ...step.cleanup !== void 0 && { hasCleanup: true }
632
+ ...step.cleanup !== void 0 && { hasCleanup: true },
633
+ ...step.requireApproval !== void 0 && { approval: toLockApproval(step.requireApproval) }
617
634
  };
618
635
  });
619
636
  }
@@ -1,6 +1,6 @@
1
1
  import "../chunk-gOLHoazu.js";
2
- import { readFileSync } from "node:fs";
3
2
  import path from "node:path";
3
+ import { readFileSync } from "node:fs";
4
4
  import fg from "fast-glob";
5
5
  //#region src/lockfile/hash-files.ts
6
6
  /**
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import "./chunk-gOLHoazu.js";
3
- import { readFile } from "node:fs/promises";
4
3
  import path from "node:path";
4
+ import { readFile } from "node:fs/promises";
5
5
  import { spawn } from "node:child_process";
6
6
  import { confirm } from "@inquirer/prompts";
7
7
  //#region src/postinstall.ts
@@ -33,6 +33,10 @@ export interface TestTriggerInput {
33
33
  /** CLI's ephemeral public key (base64, SPKI/DER) for overlay decryption */
34
34
  cliPublicKey?: string;
35
35
  secrets?: Record<string, string>;
36
+ /** Base64 X25519+AES-GCM blob of the developer's local secrets ({flat, contexts}). */
37
+ encryptedSecrets?: string;
38
+ /** Base64 ephemeral CLI public key that encrypted `encryptedSecrets`. */
39
+ encryptedSecretsKey?: string;
36
40
  workflowName?: string;
37
41
  /** JSON-stringified lock file content for repos with no remote. */
38
42
  inlineLockFile?: string;
@@ -1,6 +1,6 @@
1
1
  import "../chunk-gOLHoazu.js";
2
- import fs from "node:fs/promises";
3
2
  import path from "node:path";
3
+ import fs from "node:fs/promises";
4
4
  import os from "node:os";
5
5
  //#region src/remote/config.ts
6
6
  const VALID_CONNECTION_MODES = ["platform", "direct"];
@@ -1,9 +1,9 @@
1
1
  import "../chunk-gOLHoazu.js";
2
2
  import { formatRelativeTime } from "../format.js";
3
3
  import { getConfigDir } from "./config.js";
4
+ import path from "node:path";
4
5
  import pc from "picocolors";
5
6
  import fs from "node:fs/promises";
6
- import path from "node:path";
7
7
  import { formatDuration } from "@kici-dev/core";
8
8
  import picomatch from "picomatch";
9
9
  //#region src/remote/history.ts
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Production defaults for the `kici login` OAuth flow. When the matching
3
+ * env var (or the `--platform-endpoint` flag) is unset, login resolves
4
+ * these so a developer targeting the hosted KiCI Platform authenticates
5
+ * with no setup. Setting the env var overrides the default — staging E2E
6
+ * and self-hosted Platforms depend on that override path.
7
+ *
8
+ * Resolution is login-local: these are read into locals in `oauthLogin`,
9
+ * never written back into `process.env`, so the orchestrator's separate
10
+ * `wss://…/ws` meaning of `KICI_PLATFORM_URL` is unaffected.
11
+ */
12
+ /** Platform API base URL — login POSTs to `${value}/api/v1/cli/exchange-token`. */
13
+ export declare const PROD_PLATFORM_URL = "https://api.kici.dev";
14
+ /** OIDC issuer for the hosted Platform's Keycloak realm. */
15
+ export declare const PROD_OIDC_ISSUER = "https://auth.kici.dev/realms/kici-internal";
16
+ /** Public OIDC client id registered for the `kici` CLI. */
17
+ export declare const PROD_OIDC_CLIENT_ID = "kici-cli";
18
+ //# sourceMappingURL=prod-defaults.d.ts.map
@@ -0,0 +1,23 @@
1
+ import "../chunk-gOLHoazu.js";
2
+ //#region src/remote/prod-defaults.ts
3
+ /**
4
+ * Production defaults for the `kici login` OAuth flow. When the matching
5
+ * env var (or the `--platform-endpoint` flag) is unset, login resolves
6
+ * these so a developer targeting the hosted KiCI Platform authenticates
7
+ * with no setup. Setting the env var overrides the default — staging E2E
8
+ * and self-hosted Platforms depend on that override path.
9
+ *
10
+ * Resolution is login-local: these are read into locals in `oauthLogin`,
11
+ * never written back into `process.env`, so the orchestrator's separate
12
+ * `wss://…/ws` meaning of `KICI_PLATFORM_URL` is unaffected.
13
+ */
14
+ /** Platform API base URL — login POSTs to `${value}/api/v1/cli/exchange-token`. */
15
+ const PROD_PLATFORM_URL = "https://api.kici.dev";
16
+ /** OIDC issuer for the hosted Platform's Keycloak realm. */
17
+ const PROD_OIDC_ISSUER = "https://auth.kici.dev/realms/kici-internal";
18
+ /** Public OIDC client id registered for the `kici` CLI. */
19
+ const PROD_OIDC_CLIENT_ID = "kici-cli";
20
+ //#endregion
21
+ export { PROD_OIDC_CLIENT_ID, PROD_OIDC_ISSUER, PROD_PLATFORM_URL };
22
+
23
+ //# sourceMappingURL=prod-defaults.js.map
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Parse `--context ctx.key=value` flag values into a nested
3
+ * `{ context: { key: value } }` map. The first `.` splits the context name
4
+ * from `key=value`; the first `=` splits key from value (values may contain
5
+ * `=`). Malformed entries (missing `.` or `=`, empty context/key) are skipped.
6
+ */
7
+ export declare function parseContextFlags(flags: string[] | undefined): Record<string, Record<string, string>>;
8
+ /**
9
+ * Load the developer's local secrets (same sources as `kici run local`: the
10
+ * `.kici` secret files plus `--env` flat flags) and `--context` namespaced
11
+ * flags, and encrypt them to the orchestrator's per-upload X25519 public key.
12
+ * `--context` values override `.kici/.secrets` file contexts for the same key.
13
+ * Returns the base64 ciphertext and the ephemeral CLI public key the
14
+ * orchestrator needs to decrypt, or null when there is nothing to send.
15
+ */
16
+ export declare function buildEncryptedSecrets(kiciDir: string, envFlags: string[] | undefined, contextFlags: string[] | undefined, orchestratorPublicKeyB64: string): Promise<{
17
+ encryptedSecrets: string;
18
+ cliPublicKey: string;
19
+ } | null>;
20
+ //# sourceMappingURL=secret-upload.d.ts.map
@@ -0,0 +1,58 @@
1
+ import "../chunk-gOLHoazu.js";
2
+ import { loadLocalSecrets } from "../local-executor/secret-loader.js";
3
+ import { encryptJson } from "@kici-dev/core";
4
+ //#region src/remote/secret-upload.ts
5
+ /**
6
+ * Parse `--context ctx.key=value` flag values into a nested
7
+ * `{ context: { key: value } }` map. The first `.` splits the context name
8
+ * from `key=value`; the first `=` splits key from value (values may contain
9
+ * `=`). Malformed entries (missing `.` or `=`, empty context/key) are skipped.
10
+ */
11
+ function parseContextFlags(flags) {
12
+ const contexts = {};
13
+ for (const flag of flags ?? []) {
14
+ const dotIndex = flag.indexOf(".");
15
+ if (dotIndex === -1) continue;
16
+ const contextName = flag.slice(0, dotIndex).trim();
17
+ const rest = flag.slice(dotIndex + 1);
18
+ const eqIndex = rest.indexOf("=");
19
+ if (eqIndex === -1) continue;
20
+ const key = rest.slice(0, eqIndex).trim();
21
+ const value = rest.slice(eqIndex + 1).trim();
22
+ if (!contextName || !key) continue;
23
+ (contexts[contextName] ??= {})[key] = value;
24
+ }
25
+ return contexts;
26
+ }
27
+ /**
28
+ * Load the developer's local secrets (same sources as `kici run local`: the
29
+ * `.kici` secret files plus `--env` flat flags) and `--context` namespaced
30
+ * flags, and encrypt them to the orchestrator's per-upload X25519 public key.
31
+ * `--context` values override `.kici/.secrets` file contexts for the same key.
32
+ * Returns the base64 ciphertext and the ephemeral CLI public key the
33
+ * orchestrator needs to decrypt, or null when there is nothing to send.
34
+ */
35
+ async function buildEncryptedSecrets(kiciDir, envFlags, contextFlags, orchestratorPublicKeyB64) {
36
+ const local = await loadLocalSecrets(kiciDir, envFlags);
37
+ const contexts = {};
38
+ for (const [ctxName, vals] of Object.entries(local.contexts)) contexts[ctxName] = { ...vals };
39
+ for (const [ctxName, vals] of Object.entries(parseContextFlags(contextFlags))) contexts[ctxName] = {
40
+ ...contexts[ctxName] ?? {},
41
+ ...vals
42
+ };
43
+ const hasFlat = Object.keys(local.flat).length > 0;
44
+ const hasContexts = Object.values(contexts).some((c) => Object.keys(c).length > 0);
45
+ if (!hasFlat && !hasContexts) return null;
46
+ const { ciphertextB64, senderPublicKeyB64 } = encryptJson({
47
+ flat: local.flat,
48
+ contexts
49
+ }, Buffer.from(orchestratorPublicKeyB64, "base64"));
50
+ return {
51
+ encryptedSecrets: ciphertextB64,
52
+ cliPublicKey: senderPublicKeyB64
53
+ };
54
+ }
55
+ //#endregion
56
+ export { buildEncryptedSecrets, parseContextFlags };
57
+
58
+ //# sourceMappingURL=secret-upload.js.map
@@ -1,7 +1,7 @@
1
1
  import "../chunk-gOLHoazu.js";
2
2
  import { encryptTarball } from "./encryption.js";
3
- import fs from "node:fs/promises";
4
3
  import path from "node:path";
4
+ import fs from "node:fs/promises";
5
5
  import { formatBytes, sha256, sha256File } from "@kici-dev/core";
6
6
  import { execSync } from "node:child_process";
7
7
  import os from "node:os";
@@ -4,8 +4,8 @@ import { helloWorldWorkflow } from "./workflows/hello-world.js";
4
4
  import { prChecksWorkflow } from "./workflows/pr-checks.js";
5
5
  import { tsconfigTemplate } from "./tsconfig-json.js";
6
6
  import { generatePackageJson } from "./package-json.js";
7
- import path from "node:path";
8
7
  import { fileURLToPath } from "node:url";
8
+ import path from "node:path";
9
9
  //#region src/templates/index.ts
10
10
  /**
11
11
  * Template aggregator for kici init command
@@ -1,6 +1,6 @@
1
1
  import "../chunk-gOLHoazu.js";
2
2
  //#region src/templates/package-json.ts
3
- const sdkVersion = "0.1.14";
3
+ const sdkVersion = "0.1.16";
4
4
  /**
5
5
  * Generate package.json content for .kici/ directory
6
6
  *
@@ -1,5 +1,5 @@
1
1
  import "../../chunk-gOLHoazu.js";
2
- import { job, pr, rule, skip, step, workflow } from "@kici-dev/sdk";
2
+ import { isEventType, job, pr, rule, skip, step, workflow } from "@kici-dev/sdk";
3
3
  //#region src/templates/workflows/pr-checks.ts
4
4
  const prChecksWorkflow = workflow("pr-checks", {
5
5
  on: pr({
@@ -7,7 +7,8 @@ const prChecksWorkflow = workflow("pr-checks", {
7
7
  paths: ["src/**"]
8
8
  }),
9
9
  rules: [skip("skip-draft-prs", async (ctx) => {
10
- return ctx.event.pull_request?.draft === true;
10
+ if (!isEventType(ctx.event, "pull_request")) return false;
11
+ return ctx.event.payload.pull_request.draft === true;
11
12
  }), rule("require-src-changes", async (ctx) => {
12
13
  return ctx.changedFiles.some((file) => file.startsWith("src/"));
13
14
  })],
@@ -2,7 +2,7 @@
2
2
  // Docs: https://kici.dev/docs/sdk-reference
3
3
  // Patterns: https://kici.dev/docs/workflow-patterns
4
4
 
5
- import { workflow, job, step, pr, rule, skip } from '@kici-dev/sdk';
5
+ import { workflow, job, step, pr, rule, skip, isEventType } from '@kici-dev/sdk';
6
6
 
7
7
  export const prChecksWorkflow = workflow('pr-checks', {
8
8
  // Trigger: pr() matches pull request events
@@ -13,7 +13,9 @@ export const prChecksWorkflow = workflow('pr-checks', {
13
13
  // skip() = skip if true, rule() = run only if true
14
14
  rules: [
15
15
  skip('skip-draft-prs', async (ctx) => {
16
- return (ctx.event as any).pull_request?.draft === true;
16
+ // Raw provider fields live under `ctx.event.payload`; narrow first for typing.
17
+ if (!isEventType(ctx.event, 'pull_request')) return false;
18
+ return ctx.event.payload.pull_request.draft === true;
17
19
  }),
18
20
 
19
21
  rule('require-src-changes', async (ctx) => {
@@ -1,6 +1,6 @@
1
1
  import "../chunk-gOLHoazu.js";
2
- import { readFile } from "node:fs/promises";
3
2
  import path from "node:path";
3
+ import { readFile } from "node:fs/promises";
4
4
  //#region src/test-runner/git-detector.ts
5
5
  /**
6
6
  * Auto-detect repository information from .git/config
@@ -2,9 +2,9 @@ import "../chunk-gOLHoazu.js";
2
2
  import { formatter } from "./output-formatter.js";
3
3
  import { createStepContext } from "./step-context.js";
4
4
  import { createRuleContext, evaluateRules as evaluateRulesWithFormatting } from "./rule-evaluator.js";
5
- import pc from "picocolors";
6
- import path from "node:path";
7
5
  import { pathToFileURL } from "node:url";
6
+ import path from "node:path";
7
+ import pc from "picocolors";
8
8
  import { setJobOutputsMap, setStepOutputsMap, setStepRefMap } from "@kici-dev/sdk";
9
9
  import { logger } from "@kici-dev/core";
10
10
  //#region src/test-runner/job-executor.ts
@@ -1,6 +1,6 @@
1
1
  import "../chunk-gOLHoazu.js";
2
- import { readFile } from "node:fs/promises";
3
2
  import path from "node:path";
3
+ import { readFile } from "node:fs/promises";
4
4
  //#region src/test-runner/secrets-file.ts
5
5
  /**
6
6
  * Parse an INI-style secrets file content.
@@ -1,7 +1,7 @@
1
1
  import "../chunk-gOLHoazu.js";
2
2
  import { formatter } from "./output-formatter.js";
3
- import { chmodSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
4
3
  import { join } from "node:path";
4
+ import { chmodSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
5
5
  import { createStepSecrets, resolveJobOutputs, resolveStepOutputs } from "@kici-dev/sdk";
6
6
  import { initZx } from "@kici-dev/core";
7
7
  import { tmpdir } from "node:os";
@@ -131,7 +131,11 @@ function createStepContext(workflowInfo, jobInfo, repoRoot, inputs = {}, matrix,
131
131
  kici: { infrastructure: { list: () => Promise.resolve({
132
132
  scalers: [],
133
133
  agents: []
134
- }) } }
134
+ }) } },
135
+ cache: {
136
+ restore: async () => ({ hit: false }),
137
+ save: async () => {}
138
+ }
135
139
  };
136
140
  }
137
141
  //#endregion