@kici-dev/compiler 0.1.26 → 0.1.27

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 (96) hide show
  1. package/dist/cli-banner.d.ts +6 -3
  2. package/dist/cli-banner.js +13 -5
  3. package/dist/cli.js +66 -43
  4. package/dist/commands/check-mode.d.ts +1 -1
  5. package/dist/commands/compile.js +3 -3
  6. package/dist/commands/index.d.ts +5 -1
  7. package/dist/commands/index.js +6 -3
  8. package/dist/commands/init.js +1 -1
  9. package/dist/commands/local-trust-root.d.ts +6 -0
  10. package/dist/commands/local-trust-root.js +52 -0
  11. package/dist/commands/local.d.ts +39 -0
  12. package/dist/commands/local.js +137 -0
  13. package/dist/commands/login.d.ts +2 -0
  14. package/dist/commands/login.js +40 -0
  15. package/dist/commands/logout.js +7 -0
  16. package/dist/commands/preview.js +1 -1
  17. package/dist/commands/run-banner.d.ts +31 -0
  18. package/dist/commands/run-banner.js +25 -0
  19. package/dist/commands/run-routed.d.ts +53 -0
  20. package/dist/commands/run-routed.js +176 -0
  21. package/dist/commands/run.d.ts +0 -17
  22. package/dist/commands/run.js +7 -50
  23. package/dist/commands/secrets-list.d.ts +2 -2
  24. package/dist/commands/secrets-list.js +4 -4
  25. package/dist/commands/types.d.ts +3 -3
  26. package/dist/commands/types.js +4 -4
  27. package/dist/execution/executor.js +7 -7
  28. package/dist/generators/secrets-dts.d.ts +9 -9
  29. package/dist/generators/secrets-dts.js +12 -12
  30. package/dist/llm-context/llms-architecture.txt +2 -2
  31. package/dist/llm-context/llms-cli.txt +674 -340
  32. package/dist/llm-context/llms-features.txt +334 -336
  33. package/dist/llm-context/llms-full.txt +1207 -892
  34. package/dist/llm-context/llms-getting-started.txt +7 -15
  35. package/dist/llm-context/llms-patterns.txt +5 -23
  36. package/dist/llm-context/llms-providers.txt +10 -1
  37. package/dist/llm-context/llms-sdk.txt +12 -12
  38. package/dist/llm-context/llms.txt +5 -5
  39. package/dist/local-executor/secret-loader.d.ts +1 -1
  40. package/dist/local-plane/orchestrator-process.d.ts +65 -0
  41. package/dist/local-plane/orchestrator-process.js +115 -0
  42. package/dist/local-plane/paths.d.ts +39 -0
  43. package/dist/local-plane/paths.js +54 -0
  44. package/dist/local-plane/plane-manager.d.ts +151 -0
  45. package/dist/local-plane/plane-manager.js +340 -0
  46. package/dist/local-plane/plane-seed.d.ts +76 -0
  47. package/dist/local-plane/plane-seed.js +59 -0
  48. package/dist/local-plane/plane-trigger.d.ts +62 -0
  49. package/dist/local-plane/plane-trigger.js +97 -0
  50. package/dist/local-plane/platform-attach.d.ts +53 -0
  51. package/dist/local-plane/platform-attach.js +111 -0
  52. package/dist/local-plane/postgres.d.ts +44 -0
  53. package/dist/local-plane/postgres.js +165 -0
  54. package/dist/local-plane/resolve-plane.d.ts +37 -0
  55. package/dist/local-plane/resolve-plane.js +76 -0
  56. package/dist/local-plane/run-follow.d.ts +41 -0
  57. package/dist/local-plane/run-follow.js +104 -0
  58. package/dist/local-plane/scaler-config.d.ts +54 -0
  59. package/dist/local-plane/scaler-config.js +114 -0
  60. package/dist/local-plane/secret-seed.d.ts +59 -0
  61. package/dist/local-plane/secret-seed.js +112 -0
  62. package/dist/local-plane/source-provider.d.ts +43 -0
  63. package/dist/local-plane/source-provider.js +165 -0
  64. package/dist/local-plane/trusted-routing.d.ts +32 -0
  65. package/dist/local-plane/trusted-routing.js +47 -0
  66. package/dist/lockfile/generator.js +7 -7
  67. package/dist/remote/dashboard-client.d.ts +7 -7
  68. package/dist/remote/dashboard-client.js +7 -7
  69. package/dist/remote/platform-client.d.ts +1 -1
  70. package/dist/remote/secret-loader.d.ts +18 -0
  71. package/dist/{local-executor → remote}/secret-loader.js +4 -4
  72. package/dist/remote/secret-upload.d.ts +1 -1
  73. package/dist/remote/secret-upload.js +2 -2
  74. package/dist/remote/uploader.d.ts +1 -1
  75. package/dist/remote/uploader.js +2 -2
  76. package/dist/templates/agents-md.d.ts +1 -1
  77. package/dist/templates/agents-md.js +2 -2
  78. package/dist/templates/package-json.js +1 -1
  79. package/dist/test-runner/job-executor.js +1 -1
  80. package/dist/test-runner/runs-on-display.d.ts +9 -0
  81. package/dist/{local-executor → test-runner}/runs-on-display.js +1 -1
  82. package/dist/test-runner/step-context.d.ts +1 -1
  83. package/dist/test-runner/step-context.js +2 -2
  84. package/dist/types.d.ts +6 -6
  85. package/package.json +7 -4
  86. package/sbom.spdx.json +9884 -1459
  87. package/dist/local-executor/dag-scheduler.js +0 -183
  88. package/dist/local-executor/index.js +0 -378
  89. package/dist/local-executor/job-runner.js +0 -411
  90. package/dist/local-executor/materializer.js +0 -132
  91. package/dist/local-executor/output-streamer.js +0 -168
  92. package/dist/local-executor/payload-generator.js +0 -138
  93. package/dist/local-executor/picker.js +0 -109
  94. package/dist/local-executor/to-event-payload.js +0 -21
  95. package/dist/local-executor/types.js +0 -2
  96. package/dist/local-executor/workflow-lock.js +0 -0
@@ -38,7 +38,7 @@ Guide to the KiCI web dashboard. Covers navigation (sidebar, org switcher, mobil
38
38
 
39
39
  How to run and write tests for KiCI workflows, including remote test execution with `kici run remote`, fixture-based testing, and overlay mode for uncommitted changes.
40
40
 
41
- ### [Environments](https://docs.kici.dev/user/environments/)
41
+ ### [Contexts](https://docs.kici.dev/user/contexts/)
42
42
 
43
43
  Configure deployment environments (staging, production, review/\*) with variables, scoped secrets, and protection rules. Covers the SDK API (`environment`, `env`, `concurrencyGroup` on jobs), the 8-layer variable merge precedence, protection rules (branch restrictions, required reviewers, wait timers, concurrency), dashboard management, type generation, and migration from the legacy contexts system.
44
44
 
@@ -277,21 +277,13 @@ Decision Summary:
277
277
 
278
278
  ## Run locally
279
279
 
280
- Execute matched workflows locally with `kici run local`:
280
+ Execute matched workflows locally with `kici run <event> --local`:
281
281
 
282
282
  ```bash
283
- npx kici run local pr:open
283
+ npx kici run pr:open --local
284
284
  ```
285
285
 
286
- This compiles, matches triggers, and runs all matched jobs with DAG-based parallel scheduling.
287
-
288
- If you do not want to remember the event arg, pass `--pick` (or `-p`) and pick from a list of workflows instead:
289
-
290
- ```bash
291
- npx kici run local --pick
292
- ```
293
-
294
- The picker lists each workflow with a summary of its declared triggers, derives the event arg for the one you choose, and runs it through the same pipeline.
286
+ This compiles, matches triggers, and runs all matched jobs on this machine — which joins as an ephemeral agent through the warm local dev plane — with DAG-based parallel scheduling.
295
287
 
296
288
  ## Workflow dependencies
297
289
 
@@ -416,14 +408,14 @@ Or add the flag to your root `package.json`:
416
408
 
417
409
  ## Authoring KiCI workflows with LLM coding agents
418
410
 
419
- KiCI is LLM-ready by design. Because workflows are real, typed TypeScript, coding agents reason over the SDK's `.d.ts` signatures instead of guessing a bespoke YAML DSL — and they verify their own pipelines with the same `kici preview` and `kici run local` loop you use, so there's no push-to-find-out round-trip. First-class agent context ships in the box, so an agent is briefed the moment it opens the project.
411
+ KiCI is LLM-ready by design. Because workflows are real, typed TypeScript, coding agents reason over the SDK's `.d.ts` signatures instead of guessing a bespoke YAML DSL — and they verify their own pipelines with the same `kici preview` and `kici run <event> --local` loop you use, so there's no push-to-find-out round-trip. First-class agent context ships in the box, so an agent is briefed the moment it opens the project.
420
412
 
421
413
  KiCI ships first-class context for LLM coding agents (Claude Code, Cursor, Aider, etc.). When you scaffold a project with `kici init`, the CLI writes `.kici/AGENTS.md`, a one-page briefing that tells the agent:
422
414
 
423
415
  - where the SDK type declarations live (`node_modules/@kici-dev/sdk/dist/index.d.ts`)
424
416
  - the five canonical authoring patterns with runnable examples
425
417
  - the anti-patterns that catch agents off-guard (no YAML, no `/dist/...` imports, no top-level `await`)
426
- - the local commands the agent should drive (`kici compile --check`, `kici preview`, `kici run local`, `kici docs llm`)
418
+ - the local commands the agent should drive (`kici compile --check`, `kici preview`, `kici run <event> --local`, `kici docs llm`)
427
419
 
428
420
  If you don't want the file, pass `--no-agents-md` to `kici init`, or delete the file afterwards — KiCI never reads it at runtime.
429
421
 
@@ -514,6 +506,6 @@ If you're not sure, pick Docker / Podman.
514
506
 
515
507
  ## Looking for the laptop-only path?
516
508
 
517
- Both quickstarts deploy a real orchestrator + agent. If you only want to write a workflow and dry-run it on your laptop with no infrastructure, [Getting started](https://docs.kici.dev/user/getting-started/) covers `kici preview` and `kici run local` instead.
509
+ Both quickstarts deploy a real orchestrator + agent. If you only want to write a workflow and dry-run it on your laptop with no infrastructure, [Getting started](https://docs.kici.dev/user/getting-started/) covers `kici preview` and `kici run <event> --local` instead.
518
510
 
519
511
  ---
@@ -194,7 +194,7 @@ Sometimes you want a workflow that does **not** fire on pushes, pull requests, t
194
194
 
195
195
  There are two ways to "explicitly invoke" a `dispatch()` workflow:
196
196
 
197
- 1. **Locally from your laptop**, with `kici run local dispatch` — no orchestrator, no agent, no webhook, nothing deployed. This is the only path while you haven't wired the repo to a deployed KiCI orchestrator.
197
+ 1. **Locally from your laptop**, with `kici run dispatch --local` — this machine joins as an ephemeral agent through the warm local dev plane, so no orchestrator deployment is required. This is the path to use while you haven't wired the repo to a deployed KiCI orchestrator.
198
198
  2. **Remotely**, if the repo is connected to a KiCI orchestrator via a GitHub App, by calling GitHub's repository-dispatch API: `curl -X POST -H "Authorization: token <PAT>" -H "Accept: application/vnd.github+json" https://api.github.com/repos/<owner>/<repo>/dispatches -d '{"event_type":"hello"}'`. GitHub fans the webhook out to the App, the orchestrator normalizes it into a KiCI `dispatch` event (see `packages/orchestrator/src/providers/github/normalizer.ts`), and the matched workflow runs.
199
199
 
200
200
  Note that GitHub's `workflow_dispatch` event (the "Run workflow" button / `/actions/workflows/.../dispatches` API) is GitHub-Actions-internal and is **not** delivered to KiCI. The SDK has no `workflowDispatch()` trigger. Only `repository_dispatch` reaches KiCI.
@@ -217,36 +217,18 @@ export default workflow('hello-world', {
217
217
  });
218
218
  ```
219
219
 
220
- Run it locally, without any orchestrator or agent infrastructure:
220
+ Run it locally, without any orchestrator deployment:
221
221
 
222
222
  ```bash
223
223
  npx kici compile # regenerate .kici/kici.lock.json
224
- npx kici run local dispatch
224
+ npx kici run dispatch --local
225
225
  ```
226
226
 
227
- `kici run local` compiles the workflow, matches triggers against a simulated `dispatch` event, and executes the matched jobs directly on your machine with DAG-based scheduling. No webhook, no GitHub, no deployed orchestrator involved. See [`kici run local`](https://docs.kici.dev/user/cli-reference/#kici-run-local) for options like `--job`, `--env`, `--json`, and `--junit`.
228
-
229
- ### Scoping to a single workflow
230
-
231
- Because `kici run local dispatch` matches **every** workflow that listens for a `dispatch` event, running it in a repo with several dispatch-triggered workflows will fire all of them. Narrow execution to one with `--workflow <name>`:
232
-
233
- ```bash
234
- npx kici run local dispatch --workflow hello-world
235
- ```
236
-
237
- `--workflow` is a post-match filter: the workflow still has to have a trigger that matches the event argument. If `hello-world` does not list a `dispatch()` trigger, the command reports `No workflow named "hello-world" matched the event` and exits successfully without running anything.
238
-
239
- If you do not want to memorise event args, use the interactive picker instead:
240
-
241
- ```bash
242
- npx kici run local --pick
243
- ```
244
-
245
- `--pick` (aliased as `-p`) lists every workflow alongside a compact summary of its triggers, lets you select one, and derives a matching event arg from the chosen trigger — so the execution still flows through the normal trigger-matching pipeline and "cannot produce an inconsistent run". Multi-trigger workflows show a second prompt for which trigger to simulate. `--pick` is mutually exclusive with `--workflow`; in a non-TTY shell it prints the workflow list and exits without running anything.
227
+ `kici run dispatch --local` compiles the workflow, matches triggers against a simulated `dispatch` event, and executes the matched jobs on this machine — which joins as an ephemeral agent through the warm local dev plane — with DAG-based scheduling. No webhook, no GitHub, no deployed orchestrator involved. See [`kici run <event> --local`](https://docs.kici.dev/user/cli-reference/#kici-run-event---local) for options like `--env`, `--in-place`, and `--offline`.
246
228
 
247
229
  ### Unfiltered vs typed `dispatch()`
248
230
 
249
- Leave `dispatch()` unfiltered while you drive it from `kici run local`. The CLI currently simulates a dispatch event with no event type (i.e. `action` is undefined), so a trigger defined as `dispatch({ types: ['deploy', 'rollback'] })` will not match `kici run local dispatch` — the typed form is intended for real `repository_dispatch` deliveries from the orchestrator.
231
+ Leave `dispatch()` unfiltered while you drive it from `kici run <event> --local`. The CLI simulates a dispatch event with no event type (i.e. `action` is undefined), so a trigger defined as `dispatch({ types: ['deploy', 'rollback'] })` will not match `kici run dispatch --local` — the typed form is intended for real `repository_dispatch` deliveries from the orchestrator.
250
232
 
251
233
  ## Conditional execution with rules
252
234
 
@@ -10,7 +10,9 @@ The **GitHub App** is KiCI's flagship source. A single App:
10
10
 
11
11
  1. receives `push`, `pull_request`, and related events from every repo it's installed on,
12
12
  2. clones repos with a short-lived installation token (no deploy key to manage),
13
- 3. posts workflow / job / step Check runs back to the pull request (see
13
+ 3. posts workflow / job / step Check runs back to the commit visible on
14
+ the commit view for a plain `push` and on the **Checks** tab of any pull
15
+ request that contains it (see
14
16
  [GitHub checks architecture](https://docs.kici.dev/architecture/webhooks/github-checks/)).
15
17
 
16
18
  You don't need an App for every scenario — if you only care about `push`
@@ -347,6 +349,13 @@ driven by the orchestrator's reporting module; no workflow
347
349
  configuration is required beyond installing the App with the
348
350
  `checks: write` permission.
349
351
 
352
+ Check runs are keyed to the head commit SHA, so they surface whether or
353
+ not a pull request exists: after a `push` you see the pass/fail directly
354
+ on the commit (a red ✗ / green ✓ next to the SHA in GitHub's commit list
355
+ and on the commit page), and the same checks roll up into the **Checks**
356
+ tab of any pull request that later includes the commit. A failing run is
357
+ therefore visible in GitHub itself without opening the KiCI dashboard.
358
+
350
359
  For architecture details see
351
360
  [GitHub checks architecture](https://docs.kici.dev/architecture/webhooks/github-checks/).
352
361
 
@@ -169,8 +169,8 @@ function workflow(name: string, options: WorkflowOptions): Workflow;
169
169
  | `options.rules` | `Rule[]` | no | Conditions that must pass for execution |
170
170
  | `options.description` | `string` | no | Human-readable description |
171
171
  | `options.hashFiles` | `string[]` | no | Extra repo-relative paths or globs mixed into the workflow content hash. Changes invalidate the source cache. |
172
- | `options.registries` | `Registry[]` | no | Private npm registries the agent authenticates against before `npm install`. Each `tokenSecret` uses qualified `<environment>:<secret>` syntax. |
173
- | `options.installEnv` | `string[]` | no | Qualified `<environment>:<secret>` refs projected as env vars onto the install subprocess (used with a customer-committed `.kici/.npmrc`). |
172
+ | `options.registries` | `Registry[]` | no | Private npm registries the agent authenticates against before `npm install`. Each `tokenSecret` uses qualified `<context>:<secret>` syntax. |
173
+ | `options.installEnv` | `string[]` | no | Qualified `<context>:<secret>` refs projected as env vars onto the install subprocess (used with a customer-committed `.kici/.npmrc`). |
174
174
  | `options.onCancel` | `HookInput` | no | Runs when the workflow is cancelled |
175
175
  | `options.cleanup` | `HookInput` | no | Always runs after the workflow (success, failure, or cancel) |
176
176
  | `options.onSuccess` | `HookInput` | no | Runs on workflow success |
@@ -721,7 +721,7 @@ step('fetch-token', {
721
721
  - **Timeout is per-attempt.** Each attempt gets the step's full `timeout` budget — a timed-out attempt counts as one failed attempt and is retried while attempts remain. The total wall-clock can therefore approach `maxAttempts * (timeout + delay)`, so keep `maxAttempts` and `maxDelayMs` sane (the job-level `timeout` still bounds the whole job).
722
722
  - **Retries exhaust before `continueOnError`.** A step with both retries first; only the _final_ failure is then softened to a warning by `continueOnError`.
723
723
 
724
- `retry` works identically under `kici run local` and on a remote agent, and applies to dynamically-generated job steps too. The `retryIf` predicate is an in-memory function: it is honored at execution time but never serialized into the lock file.
724
+ `retry` works identically under `kici run <event> --local` and on a remote agent, and applies to dynamically-generated job steps too. The `retryIf` predicate is an in-memory function: it is honored at execution time but never serialized into the lock file.
725
725
 
726
726
  > **Retry vs. wait-until-condition.** `retry` re-runs a step that _throws_. To poll until a condition becomes true (a port listening, a `/health` endpoint returning 200, a unit becoming active), use [`waitForStep`](https://docs.kici.dev/user/sdk/wait-for/) instead — it is purpose-built for declarative wait-for-condition with intervals, a timeout, and on-timeout handling.
727
727
 
@@ -807,7 +807,7 @@ const deploy = job('deploy', {
807
807
 
808
808
  **Important:** `needs` must be declared explicitly. Output chaining does not auto-infer dependencies -- you must list job dependencies in `needs` even if you access their outputs via `.result`.
809
809
 
810
- Cross-job output chaining works in both local execution (`kici run local`) and remote pipeline execution. The orchestrator's needs-aware dispatch scheduler guarantees upstream jobs reach a terminal state before downstream jobs dispatch, and upstream outputs are transported to the downstream agent sandbox via the `upstreamJobOutputs` field on `job.dispatch`. See [needs-scheduler](https://docs.kici.dev/architecture/execution/needs-scheduler/) for the full dispatch semantics.
810
+ Cross-job output chaining works in both local execution (`kici run <event> --local`) and remote pipeline execution. The orchestrator's needs-aware dispatch scheduler guarantees upstream jobs reach a terminal state before downstream jobs dispatch, and upstream outputs are transported to the downstream agent sandbox via the `upstreamJobOutputs` field on `job.dispatch`. See [needs-scheduler](https://docs.kici.dev/architecture/execution/needs-scheduler/) for the full dispatch semantics.
811
811
 
812
812
  ### Job dependencies (`needs`)
813
813
 
@@ -1548,7 +1548,7 @@ inside a fan-out job nests its concurrency inside each fan-out child.
1548
1548
  ## Local vs remote execution
1549
1549
 
1550
1550
  Run remotely (the orchestrator + agent), parallel children execute concurrently
1551
- and each surfaces as its own dashboard step. `kici run local` executes the same
1551
+ and each surfaces as its own dashboard step. `kici run <event> --local` executes the same
1552
1552
  children in array order in its single-process model — the results are identical,
1553
1553
  only the wall-clock and the live fail-fast cancellation differ. Use a remote run
1554
1554
  to observe the concurrent timeline.
@@ -1688,7 +1688,7 @@ Every variant carries the shared `EventBase` fields — `type`, `action`, `targe
1688
1688
 
1689
1689
  Matrix configurations expand a single job into multiple instances, one per parameter combination. Maximum 256 combinations.
1690
1690
 
1691
- Expansion happens at **dispatch time**: the orchestrator materializes the matrix into N execution jobs — one per combination, each dispatched to its own agent — before any job runs. Each instance receives its combination as `ctx.matrix`. This is identical whether the workflow runs via `kici run local` or remotely through a webhook trigger, and the dashboard groups the N instances under one parent node.
1691
+ Expansion happens at **dispatch time**: the orchestrator materializes the matrix into N execution jobs — one per combination, each dispatched to its own agent — before any job runs. Each instance receives its combination as `ctx.matrix`. This is identical whether the workflow runs via `kici run <event> --local` or remotely through a webhook trigger, and the dashboard groups the N instances under one parent node.
1692
1692
 
1693
1693
  ### Static array (single dimension)
1694
1694
 
@@ -1834,7 +1834,7 @@ step('collect', async ({ jobOutputs }) => {
1834
1834
  });
1835
1835
  ```
1836
1836
 
1837
- The downstream job waits for **all** matrix combinations to terminate before it dispatches. A non-matrix upstream keeps the flat outputs shape. The envelope is identical under `kici run local` and the remote path.
1837
+ The downstream job waits for **all** matrix combinations to terminate before it dispatches. A non-matrix upstream keeps the flat outputs shape. The envelope is identical under `kici run <event> --local` and the remote path.
1838
1838
 
1839
1839
  ### Matrix type guards
1840
1840
 
@@ -2758,14 +2758,14 @@ verify → view journey, including how to verify a bundle with `kici verify-atte
2758
2758
 
2759
2759
  Workflows access secrets through `ctx.secrets` on `StepContext`. Use `await ctx.secrets.get('KEY')` to retrieve a value (rejects with `SecretNotFoundError` if the key is missing, fail-fast on typos), `ctx.secrets.has('KEY')` for a synchronous existence check, and `await ctx.secrets.expose('KEY')` when you need the value as a `process.env` entry for a child process.
2760
2760
 
2761
- ### Declaring the secret environment
2761
+ ### Declaring the secret context
2762
2762
 
2763
- Each job picks its secret environment via the `environment` option on `job()`. The orchestrator resolves the environment's scoped-secret store at dispatch time, evaluates access rules, and sends the decrypted secrets to the agent:
2763
+ Each job picks its secret context via the `context` option on `job()`. The orchestrator resolves the context's scoped-secret store at dispatch time, evaluates access rules, and sends the decrypted secrets to the agent:
2764
2764
 
2765
2765
  ```typescript
2766
2766
  const deploy = job('deploy', {
2767
2767
  runsOn: 'linux',
2768
- environment: 'production',
2768
+ context: 'production',
2769
2769
  steps: [
2770
2770
  /* ... */
2771
2771
  ],
@@ -2777,11 +2777,11 @@ export default workflow('deploy', {
2777
2777
  });
2778
2778
  ```
2779
2779
 
2780
- `environment` accepts either a static string or an async function `(event) => string | Promise<string>` for dynamic resolution at trigger-evaluation time. The resolved environment's secrets are flattened into `ctx.secrets`.
2780
+ `context` accepts either a static string or an async function `(event) => string | Promise<string>` for dynamic resolution at trigger-evaluation time. The resolved context's secrets are flattened into `ctx.secrets`.
2781
2781
 
2782
2782
  ### Accessing secrets (ctx.secrets)
2783
2783
 
2784
- `ctx.secrets` provides flat access to the secrets resolved for the job's environment.
2784
+ `ctx.secrets` provides flat access to the secrets resolved for the job's context.
2785
2785
 
2786
2786
  ```typescript
2787
2787
  step('deploy', async ({ secrets }) => {
@@ -9,11 +9,11 @@ The full markdown bundle of every page indexed here is available at https://docs
9
9
  Each bundle below is a self-contained markdown file for one authoring task. Fetch only the one your task needs instead of the full bundle:
10
10
 
11
11
  - [getting-started](https://docs.kici.dev/llms-getting-started.txt) (25 KB) — Install the SDK, write your first workflow, compile and test locally
12
- - [patterns](https://docs.kici.dev/llms-patterns.txt) (49 KB) — Copy-paste workflow recipes: triggers, conditionals, matrix, scheduling, integrations
12
+ - [patterns](https://docs.kici.dev/llms-patterns.txt) (48 KB) — Copy-paste workflow recipes: triggers, conditionals, matrix, scheduling, integrations
13
13
  - [sdk](https://docs.kici.dev/llms-sdk.txt) (190 KB) — Authoring API: workflow/job/step factories, triggers, rules, matrix, runtime, caching
14
- - [cli](https://docs.kici.dev/llms-cli.txt) (136 KB) — Running the CLI: compile, test, run local/remote, auth, hooks, lock-file drift
15
- - [features](https://docs.kici.dev/llms-features.txt) (126 KB) — Workflow features: concurrency, environments, secrets, approvals, provenance, events
16
- - [providers](https://docs.kici.dev/llms-providers.txt) (36 KB) — Connecting sources: GitHub App, universal-git (Forgejo/Gitea/GitLab), local file://
14
+ - [cli](https://docs.kici.dev/llms-cli.txt) (135 KB) — Running the CLI: compile, test, run local/remote, auth, hooks, lock-file drift
15
+ - [features](https://docs.kici.dev/llms-features.txt) (125 KB) — Workflow features: concurrency, contexts, secrets, approvals, provenance, events
16
+ - [providers](https://docs.kici.dev/llms-providers.txt) (37 KB) — Connecting sources: GitHub App, universal-git (Forgejo/Gitea/GitLab), local file://
17
17
  - [architecture](https://docs.kici.dev/llms-architecture.txt) (87 KB) — How the runtime works: three-tier relay model, data flows, configuration
18
18
 
19
19
  ## Getting started
@@ -61,10 +61,10 @@ Each bundle below is a self-contained markdown file for one authoring task. Fetc
61
61
  - [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.
62
62
  - [Approval gates](https://docs.kici.dev/user/approvals/): Pause a workflow for human sign-off at step, job, or workflow granularity with approval
63
63
  - [Concurrency groups](https://docs.kici.dev/user/concurrency/): Control parallel execution with auto-cancel and queue modes
64
+ - [Contexts](https://docs.kici.dev/user/contexts/): Configure deployment contexts with variables, secrets, and protection rules
64
65
  - [Dashboard](https://docs.kici.dev/user/dashboard/): Web UI for monitoring workflow runs, managing sources, secrets, and organization settings.
65
66
  - [Dynamic values](https://docs.kici.dev/user/dynamic-values/)
66
67
  - [Environment variables](https://docs.kici.dev/user/env-vars/): KICI_* environment variable reference for the CLI
67
- - [Environments](https://docs.kici.dev/user/environments/): Configure deployment environments with variables, secrets, and protection rules
68
68
  - [Event system](https://docs.kici.dev/user/events/): How KiCI's event model works -- event types, the registration model, event matching, and circuit breaker protection
69
69
  - [Global workflows](https://docs.kici.dev/user/global-workflows/): Cross-repo workflows that run on events from any repo in the same org
70
70
  - [Idempotent steps and check mode](https://docs.kici.dev/user/idempotent-steps/): Declare desired state with a step check facet, then run in apply or --check preview mode
@@ -5,7 +5,7 @@ import type { ParsedSecrets } from '../test-runner/secrets-file.js';
5
5
  * Merge order (lowest to highest priority):
6
6
  * 1. .kici/.secrets (INI-style, backward compat)
7
7
  * 2. .kici/.env.local (dotenv format)
8
- * 3. .kici/secrets.yaml (YAML with environment scopes, merged flat)
8
+ * 3. .kici/secrets.yaml (YAML with context scopes, merged flat)
9
9
  * 4. --env KEY=VALUE CLI flags
10
10
  *
11
11
  * Note: process.env is NOT merged here -- it's handled at step-context level.
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Resolve a host address the plane's co-located bare-metal agent can reach for
3
+ * cache-blob fetches. The orchestrator refuses to hand a scaler a loopback
4
+ * storage URL (it assumes remote agents), so the plane advertises its first
5
+ * non-internal IPv4 (still this machine — the agent is co-located). Falls back
6
+ * to the hostname when no external interface is present.
7
+ */
8
+ export declare function resolveAgentReachableHost(): string;
9
+ /**
10
+ * Resolve the built `@kici-dev/orchestrator/standalone` entry the local plane
11
+ * launches in independent (offline) mode.
12
+ */
13
+ export declare function resolveStandaloneEntry(): string;
14
+ /**
15
+ * Resolve the built `@kici-dev/orchestrator/server` entry the local plane
16
+ * launches in hybrid (Platform-attached) mode.
17
+ */
18
+ export declare function resolveServerEntry(): string;
19
+ /** Single `/ready` probe against the local orchestrator. */
20
+ export declare function orchestratorReady(port: number): Promise<boolean>;
21
+ /** Options threading the plane's admin token + bare-metal scaler into the boot. */
22
+ export interface SpawnOrchestratorOptions {
23
+ /** Bootstrap admin token the CLI presents to the plane's admin API. */
24
+ adminToken: string;
25
+ /**
26
+ * Local master secret key (64 hex chars). Enables the orchestrator's secrets
27
+ * subsystem, which is what gates the admin API routes the CLI drives.
28
+ */
29
+ secretKey: string;
30
+ /** Path to the bare-metal scaler YAML (KICI_SCALER_CONFIG_PATH). */
31
+ scalerConfigFile: string;
32
+ /**
33
+ * Path to the dev-signed identity's EC P-256 private JWK (mode 0600), freshly
34
+ * generated by the plane. Enables the orchestrator's local OIDC mint +
35
+ * dev-signed provenance (issuer `kici-local`) in independent mode. Present in
36
+ * the independent boot; omitted (with `attach`) in the hybrid boot, which
37
+ * mints via the Platform relay instead.
38
+ */
39
+ devIdentityKeyFile?: string;
40
+ /**
41
+ * When present, boot the orchestrator in HYBRID mode attached to the Platform
42
+ * relay instead of independent mode. OIDC + attestation then mint via the
43
+ * Platform (the local dev signer is never consulted — the orchestrator's
44
+ * `selectOidcMintRegistration` prefers the relay whenever a Platform
45
+ * connection exists).
46
+ */
47
+ attach?: {
48
+ /** Orchestrator KICI_PLATFORM_URL — a ws(s)://…/ws relay URL. */
49
+ platformWsUrl: string;
50
+ /** Org-scoped orchestrator key (kici_ok_…) presented on WS auth. */
51
+ platformToken: string;
52
+ };
53
+ }
54
+ /**
55
+ * Spawn the orchestrator's standalone entry in independent mode against the
56
+ * local Postgres, detached, with stdout/stderr redirected to the plane log.
57
+ * Boots with a bootstrap admin token (so the CLI can drive the admin API) and a
58
+ * bare-metal scaler (so a dispatched job auto-spawns an ephemeral agent). Waits
59
+ * for `GET /ready` to report warm, then returns the child pid + port.
60
+ */
61
+ export declare function spawnOrchestrator(databaseUrl: string, opts: SpawnOrchestratorOptions): Promise<{
62
+ pid: number;
63
+ port: number;
64
+ }>;
65
+ //# sourceMappingURL=orchestrator-process.d.ts.map
@@ -0,0 +1,115 @@
1
+ import "../rolldown-runtime-ClRpJifh.js";
2
+ import { planePaths, planePorts } from "./paths.js";
3
+ import { createRequire } from "node:module";
4
+ import fs from "node:fs";
5
+ import { spawn } from "node:child_process";
6
+ import os from "node:os";
7
+ //#region src/local-plane/orchestrator-process.ts
8
+ /**
9
+ * Resolve a host address the plane's co-located bare-metal agent can reach for
10
+ * cache-blob fetches. The orchestrator refuses to hand a scaler a loopback
11
+ * storage URL (it assumes remote agents), so the plane advertises its first
12
+ * non-internal IPv4 (still this machine — the agent is co-located). Falls back
13
+ * to the hostname when no external interface is present.
14
+ */
15
+ function resolveAgentReachableHost() {
16
+ for (const addrs of Object.values(os.networkInterfaces())) for (const a of addrs ?? []) if (a.family === "IPv4" && !a.internal) return a.address;
17
+ return os.hostname();
18
+ }
19
+ /**
20
+ * Resolve the built `@kici-dev/orchestrator/standalone` entry the local plane
21
+ * launches in independent (offline) mode.
22
+ */
23
+ function resolveStandaloneEntry() {
24
+ return createRequire(import.meta.url).resolve("@kici-dev/orchestrator/standalone");
25
+ }
26
+ /**
27
+ * Resolve the built `@kici-dev/orchestrator/server` entry the local plane
28
+ * launches in hybrid (Platform-attached) mode.
29
+ */
30
+ function resolveServerEntry() {
31
+ return createRequire(import.meta.url).resolve("@kici-dev/orchestrator/server");
32
+ }
33
+ /** Single `/ready` probe against the local orchestrator. */
34
+ async function orchestratorReady(port) {
35
+ try {
36
+ return (await fetch(`http://127.0.0.1:${port}/ready`)).status === 200;
37
+ } catch {
38
+ return false;
39
+ }
40
+ }
41
+ /**
42
+ * Spawn the orchestrator's standalone entry in independent mode against the
43
+ * local Postgres, detached, with stdout/stderr redirected to the plane log.
44
+ * Boots with a bootstrap admin token (so the CLI can drive the admin API) and a
45
+ * bare-metal scaler (so a dispatched job auto-spawns an ephemeral agent). Waits
46
+ * for `GET /ready` to report warm, then returns the child pid + port.
47
+ */
48
+ async function spawnOrchestrator(databaseUrl, opts) {
49
+ const { orchestrator: port } = planePorts();
50
+ const { logFile, root, cacheDir } = planePaths();
51
+ fs.mkdirSync(root, { recursive: true });
52
+ fs.mkdirSync(cacheDir, { recursive: true });
53
+ const out = fs.openSync(logFile, "a");
54
+ const baseEnv = {};
55
+ for (const [key, value] of Object.entries(process.env)) if (!key.startsWith("KICI_")) baseEnv[key] = value;
56
+ const commonEnv = {
57
+ ...baseEnv,
58
+ KICI_PORT: String(port),
59
+ KICI_DATABASE_URL: databaseUrl,
60
+ KICI_AGENT_AUTH: "none",
61
+ KICI_AUTO_MIGRATE: "true",
62
+ KICI_DATA_DIR: root,
63
+ KICI_BOOTSTRAP_ADMIN_TOKEN: opts.adminToken,
64
+ KICI_SECRET_KEY: opts.secretKey,
65
+ KICI_SCALER_CONFIG_PATH: opts.scalerConfigFile,
66
+ KICI_WEBHOOK_PUBLIC_URL: `http://127.0.0.1:${port}`,
67
+ KICI_STORAGE_TYPE: "filesystem",
68
+ KICI_STORAGE_FS_PATH: cacheDir,
69
+ KICI_STORAGE_FS_BASE_URL: `http://${resolveAgentReachableHost()}:${port}`
70
+ };
71
+ let entry;
72
+ let modeEnv;
73
+ if (opts.attach) {
74
+ entry = resolveServerEntry();
75
+ modeEnv = {
76
+ KICI_MODE: "hybrid",
77
+ KICI_PLATFORM_URL: opts.attach.platformWsUrl,
78
+ KICI_PLATFORM_TOKEN: opts.attach.platformToken
79
+ };
80
+ } else {
81
+ entry = resolveStandaloneEntry();
82
+ modeEnv = {
83
+ KICI_MODE: "independent",
84
+ KICI_INDEPENDENT_SECRETS: "true",
85
+ KICI_INDEPENDENT_IDENTITY: "true",
86
+ KICI_DEV_IDENTITY_KEY_FILE: opts.devIdentityKeyFile,
87
+ KICI_PROVENANCE_ISSUER: "kici-local"
88
+ };
89
+ }
90
+ const child = spawn(process.execPath, [entry], {
91
+ detached: true,
92
+ stdio: [
93
+ "ignore",
94
+ out,
95
+ out
96
+ ],
97
+ env: {
98
+ ...commonEnv,
99
+ ...modeEnv
100
+ }
101
+ });
102
+ child.unref();
103
+ for (let i = 0; i < 120; i++) {
104
+ if (await orchestratorReady(port)) return {
105
+ pid: child.pid,
106
+ port
107
+ };
108
+ await new Promise((r) => setTimeout(r, 500));
109
+ }
110
+ throw new Error("local orchestrator did not become ready");
111
+ }
112
+ //#endregion
113
+ export { orchestratorReady, resolveAgentReachableHost, resolveServerEntry, resolveStandaloneEntry, spawnOrchestrator };
114
+
115
+ //# sourceMappingURL=orchestrator-process.js.map
@@ -0,0 +1,39 @@
1
+ /**
2
+ * On-disk layout version of the local dev plane. Bumped when the state-dir
3
+ * structure changes incompatibly, so a stamped plane from an older layout is
4
+ * recreated rather than reused.
5
+ */
6
+ export declare const PLANE_STAMP_VERSION = 3;
7
+ /**
8
+ * Root directory of the local dev plane's state, following the same
9
+ * `KICI_CONFIG_DIR` → `~/.kici` convention the rest of the CLI uses.
10
+ */
11
+ export declare function planeRoot(): string;
12
+ /**
13
+ * Absolute paths for every artefact the plane persists under its state root.
14
+ */
15
+ export declare function planePaths(): {
16
+ root: string;
17
+ pgData: string;
18
+ pidfile: string;
19
+ stampFile: string;
20
+ logFile: string;
21
+ socketDir: string;
22
+ adminTokenFile: string;
23
+ platformTokenFile: string;
24
+ attachmentFile: string;
25
+ secretKeyFile: string;
26
+ scalerConfigFile: string;
27
+ agentWrapperFile: string;
28
+ devIdentityDir: string;
29
+ cacheDir: string;
30
+ };
31
+ /**
32
+ * Fixed localhost ports for the plane's orchestrator (HTTP+WS) and Postgres.
33
+ * Overridable via `KICI_LOCAL_ORCH_PORT` / `KICI_LOCAL_PG_PORT`.
34
+ */
35
+ export declare function planePorts(): {
36
+ orchestrator: number;
37
+ postgres: number;
38
+ };
39
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1,54 @@
1
+ import "../rolldown-runtime-ClRpJifh.js";
2
+ import path from "node:path";
3
+ import os from "node:os";
4
+ //#region src/local-plane/paths.ts
5
+ /**
6
+ * On-disk layout version of the local dev plane. Bumped when the state-dir
7
+ * structure changes incompatibly, so a stamped plane from an older layout is
8
+ * recreated rather than reused.
9
+ */
10
+ const PLANE_STAMP_VERSION = 3;
11
+ /**
12
+ * Root directory of the local dev plane's state, following the same
13
+ * `KICI_CONFIG_DIR` → `~/.kici` convention the rest of the CLI uses.
14
+ */
15
+ function planeRoot() {
16
+ const base = process.env.KICI_CONFIG_DIR ?? path.join(os.homedir(), ".kici");
17
+ return path.join(base, "local");
18
+ }
19
+ /**
20
+ * Absolute paths for every artefact the plane persists under its state root.
21
+ */
22
+ function planePaths() {
23
+ const root = planeRoot();
24
+ return {
25
+ root,
26
+ pgData: path.join(root, "pgdata"),
27
+ pidfile: path.join(root, "plane.pid"),
28
+ stampFile: path.join(root, "stamp.json"),
29
+ logFile: path.join(root, "orchestrator.log"),
30
+ socketDir: path.join(root, "sock"),
31
+ adminTokenFile: path.join(root, "admin-token"),
32
+ platformTokenFile: path.join(root, "platform-token"),
33
+ attachmentFile: path.join(root, "attachment.json"),
34
+ secretKeyFile: path.join(root, "secret-key"),
35
+ scalerConfigFile: path.join(root, "scaler.yaml"),
36
+ agentWrapperFile: path.join(root, "agent-wrapper.sh"),
37
+ devIdentityDir: path.join(root, "dev-identity"),
38
+ cacheDir: path.join(root, "cache")
39
+ };
40
+ }
41
+ /**
42
+ * Fixed localhost ports for the plane's orchestrator (HTTP+WS) and Postgres.
43
+ * Overridable via `KICI_LOCAL_ORCH_PORT` / `KICI_LOCAL_PG_PORT`.
44
+ */
45
+ function planePorts() {
46
+ return {
47
+ orchestrator: Number(process.env.KICI_LOCAL_ORCH_PORT ?? 4319),
48
+ postgres: Number(process.env.KICI_LOCAL_PG_PORT ?? 45432)
49
+ };
50
+ }
51
+ //#endregion
52
+ export { PLANE_STAMP_VERSION, planePaths, planePorts, planeRoot };
53
+
54
+ //# sourceMappingURL=paths.js.map