@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.
- package/dist/cli-banner.d.ts +6 -3
- package/dist/cli-banner.js +13 -5
- package/dist/cli.js +66 -43
- package/dist/commands/check-mode.d.ts +1 -1
- package/dist/commands/compile.js +3 -3
- package/dist/commands/index.d.ts +5 -1
- package/dist/commands/index.js +6 -3
- package/dist/commands/init.js +1 -1
- package/dist/commands/local-trust-root.d.ts +6 -0
- package/dist/commands/local-trust-root.js +52 -0
- package/dist/commands/local.d.ts +39 -0
- package/dist/commands/local.js +137 -0
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.js +40 -0
- package/dist/commands/logout.js +7 -0
- package/dist/commands/preview.js +1 -1
- package/dist/commands/run-banner.d.ts +31 -0
- package/dist/commands/run-banner.js +25 -0
- package/dist/commands/run-routed.d.ts +53 -0
- package/dist/commands/run-routed.js +176 -0
- package/dist/commands/run.d.ts +0 -17
- package/dist/commands/run.js +7 -50
- package/dist/commands/secrets-list.d.ts +2 -2
- package/dist/commands/secrets-list.js +4 -4
- package/dist/commands/types.d.ts +3 -3
- package/dist/commands/types.js +4 -4
- package/dist/execution/executor.js +7 -7
- package/dist/generators/secrets-dts.d.ts +9 -9
- package/dist/generators/secrets-dts.js +12 -12
- package/dist/llm-context/llms-architecture.txt +2 -2
- package/dist/llm-context/llms-cli.txt +674 -340
- package/dist/llm-context/llms-features.txt +334 -336
- package/dist/llm-context/llms-full.txt +1207 -892
- package/dist/llm-context/llms-getting-started.txt +7 -15
- package/dist/llm-context/llms-patterns.txt +5 -23
- package/dist/llm-context/llms-providers.txt +10 -1
- package/dist/llm-context/llms-sdk.txt +12 -12
- package/dist/llm-context/llms.txt +5 -5
- package/dist/local-executor/secret-loader.d.ts +1 -1
- package/dist/local-plane/orchestrator-process.d.ts +65 -0
- package/dist/local-plane/orchestrator-process.js +115 -0
- package/dist/local-plane/paths.d.ts +39 -0
- package/dist/local-plane/paths.js +54 -0
- package/dist/local-plane/plane-manager.d.ts +151 -0
- package/dist/local-plane/plane-manager.js +340 -0
- package/dist/local-plane/plane-seed.d.ts +76 -0
- package/dist/local-plane/plane-seed.js +59 -0
- package/dist/local-plane/plane-trigger.d.ts +62 -0
- package/dist/local-plane/plane-trigger.js +97 -0
- package/dist/local-plane/platform-attach.d.ts +53 -0
- package/dist/local-plane/platform-attach.js +111 -0
- package/dist/local-plane/postgres.d.ts +44 -0
- package/dist/local-plane/postgres.js +165 -0
- package/dist/local-plane/resolve-plane.d.ts +37 -0
- package/dist/local-plane/resolve-plane.js +76 -0
- package/dist/local-plane/run-follow.d.ts +41 -0
- package/dist/local-plane/run-follow.js +104 -0
- package/dist/local-plane/scaler-config.d.ts +54 -0
- package/dist/local-plane/scaler-config.js +114 -0
- package/dist/local-plane/secret-seed.d.ts +59 -0
- package/dist/local-plane/secret-seed.js +112 -0
- package/dist/local-plane/source-provider.d.ts +43 -0
- package/dist/local-plane/source-provider.js +165 -0
- package/dist/local-plane/trusted-routing.d.ts +32 -0
- package/dist/local-plane/trusted-routing.js +47 -0
- package/dist/lockfile/generator.js +7 -7
- package/dist/remote/dashboard-client.d.ts +7 -7
- package/dist/remote/dashboard-client.js +7 -7
- package/dist/remote/platform-client.d.ts +1 -1
- package/dist/remote/secret-loader.d.ts +18 -0
- package/dist/{local-executor → remote}/secret-loader.js +4 -4
- package/dist/remote/secret-upload.d.ts +1 -1
- package/dist/remote/secret-upload.js +2 -2
- package/dist/remote/uploader.d.ts +1 -1
- package/dist/remote/uploader.js +2 -2
- package/dist/templates/agents-md.d.ts +1 -1
- package/dist/templates/agents-md.js +2 -2
- package/dist/templates/package-json.js +1 -1
- package/dist/test-runner/job-executor.js +1 -1
- package/dist/test-runner/runs-on-display.d.ts +9 -0
- package/dist/{local-executor → test-runner}/runs-on-display.js +1 -1
- package/dist/test-runner/step-context.d.ts +1 -1
- package/dist/test-runner/step-context.js +2 -2
- package/dist/types.d.ts +6 -6
- package/package.json +7 -4
- package/sbom.spdx.json +9884 -1459
- package/dist/local-executor/dag-scheduler.js +0 -183
- package/dist/local-executor/index.js +0 -378
- package/dist/local-executor/job-runner.js +0 -411
- package/dist/local-executor/materializer.js +0 -132
- package/dist/local-executor/output-streamer.js +0 -168
- package/dist/local-executor/payload-generator.js +0 -138
- package/dist/local-executor/picker.js +0 -109
- package/dist/local-executor/to-event-payload.js +0 -21
- package/dist/local-executor/types.js +0 -2
- 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
|
-
### [
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 `<
|
|
173
|
-
| `options.installEnv` | `string[]` | no | Qualified `<
|
|
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
|
|
2761
|
+
### Declaring the secret context
|
|
2762
2762
|
|
|
2763
|
-
Each job picks its secret
|
|
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
|
-
|
|
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
|
-
`
|
|
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
|
|
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) (
|
|
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) (
|
|
15
|
-
- [features](https://docs.kici.dev/llms-features.txt) (
|
|
16
|
-
- [providers](https://docs.kici.dev/llms-providers.txt) (
|
|
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
|
|
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
|