@kici-dev/compiler 0.8.0 → 0.9.0

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 (40) hide show
  1. package/dist/cli.js +4 -3
  2. package/dist/commands/docs.js +2 -2
  3. package/dist/commands/feedback.d.ts +23 -1
  4. package/dist/commands/feedback.js +86 -9
  5. package/dist/commands/index.d.ts +2 -2
  6. package/dist/commands/index.js +2 -2
  7. package/dist/commands/local.d.ts +4 -3
  8. package/dist/commands/local.js +5 -4
  9. package/dist/commands/report/identity.js +1 -1
  10. package/dist/commands/run-banner.d.ts +1 -1
  11. package/dist/commands/run-banner.js +1 -1
  12. package/dist/commands/verify-attestation.js +1 -1
  13. package/dist/llm-context/llms-architecture.txt +8 -6
  14. package/dist/llm-context/llms-cli-remote.txt +14 -11
  15. package/dist/llm-context/llms-cli.txt +2 -2
  16. package/dist/llm-context/llms-features-execution.txt +8 -8
  17. package/dist/llm-context/llms-features.txt +452 -133
  18. package/dist/llm-context/llms-full.txt +529 -190
  19. package/dist/llm-context/llms-getting-started.txt +32 -15
  20. package/dist/llm-context/llms-providers.txt +2 -2
  21. package/dist/llm-context/llms-sdk-runtime.txt +5 -2
  22. package/dist/llm-context/llms-sdk.txt +7 -12
  23. package/dist/llm-context/llms.txt +6 -5
  24. package/dist/local-plane/orchestrator-process.d.ts +4 -5
  25. package/dist/local-plane/orchestrator-process.js +2 -1
  26. package/dist/local-plane/plane-manager.js +2 -2
  27. package/dist/templates/agents-md.d.ts +1 -1
  28. package/dist/templates/agents-md.js +9 -7
  29. package/dist/templates/package-json.js +1 -1
  30. package/dist/templates/workflows/hello-world.ts +1 -1
  31. package/dist/templates/workflows/pr-checks.ts +2 -2
  32. package/dist/test-runner/job-executor.js +3 -2
  33. package/dist/types.d.ts +12 -35
  34. package/dist/types.js +2 -12
  35. package/dist/types.test-d.d.ts +2 -0
  36. package/dist/types.test-d.js +63 -0
  37. package/dist/workflows/hello-world.ts +1 -1
  38. package/dist/workflows/pr-checks.ts +2 -2
  39. package/package.json +15 -15
  40. package/sbom.spdx.json +1303 -1483
@@ -845,7 +845,7 @@ Each guide is split into two parts. **Part 1** gets you a green run against your
845
845
 
846
846
  ## Bring a coding agent
847
847
 
848
- Workflows are TypeScript, so a coding agent can write them. KiCI ships its docs in a form an agent reads directly: point yours at [llms.txt](https://kici.dev/docs/llms.txt), or pipe a task bundle straight into its context with `kici docs llm` (`kici docs llm sdk` for the authoring API, `kici docs llm patterns` for recipes). An agent briefed that way can scaffold your first workflow, compile it, and read the failure when it breaks.
848
+ Workflows are TypeScript, so a coding agent can write them. KiCI ships its docs in a form an agent reads directly: point yours at [llms.txt](https://kici.dev/llms.txt), or pipe a task bundle straight into its context with `kici docs llm` (`kici docs llm sdk` for the authoring API, `kici docs llm patterns` for recipes). An agent briefed that way can scaffold your first workflow, compile it, and read the failure when it breaks.
849
849
 
850
850
  If your agent finds that these docs promise something KiCI does not do, that is worth telling us — `kici feedback` prints how to report it, and [Reporting a discrepancy](https://docs.kici.dev/user/reporting-discrepancies/) is the full guide.
851
851
 
@@ -891,8 +891,10 @@ promised. You can report that.
891
891
  A human reader can use this page too. The rules below exist because the tracker
892
892
  is public and you are filing under someone else's GitHub identity.
893
893
 
894
- Run `kici feedback` to print this contract in your terminal, or
895
- `kici feedback --json` to read it as structured data.
894
+ Run `kici feedback` to print this contract in your terminal,
895
+ `kici feedback --json` to read it as structured data, or
896
+ `kici feedback --draft <file.json> --open` to turn a draft into the prefilled form
897
+ and open it.
896
898
 
897
899
  ## The rule, in one sentence
898
900
 
@@ -967,19 +969,20 @@ approval rule.
967
969
 
968
970
  ## What the report must carry
969
971
 
970
- Five things. A report missing any of them cannot be acted on:
972
+ A report missing any of these fields cannot be acted on:
971
973
 
972
974
  | Field | What it holds |
973
975
  | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
974
976
  | What the docs or CLI advertise | The exact claim, quoted, plus its source: a docs URL or the command whose `--help` says it. |
975
977
  | What actually happened | The real output or behaviour, quoted, with any error text. |
976
978
  | Minimal reproduction, including setup | Every step from an empty directory: the setup commands, a minimal synthetic workflow, and the exact command you ran. |
977
- | Version and environment | Output of `kici --version`, plus Node version and OS. |
979
+ | KiCI version | Output of `kici --version`. |
980
+ | Environment | Node version and OS. |
978
981
  | Why this is a discrepancy | One or two sentences ruling out the likely misreads — why the docs cannot be read to match what you observed. |
979
982
 
980
983
  The last field is the one agents skip, and it is the one that makes a report
981
984
  usable. "The docs say `--foo` exists and it does not" is a claim. "`--foo` is
982
- documented at <url>, and `kici bar --help` on 0.1.16 lists no such flag" is a
985
+ documented at <url>, and `kici bar --help` on the version I ran lists no such flag" is a
983
986
  finding someone can act on in one pass.
984
987
 
985
988
  Include setup steps whenever your reproduction needed any. A reproduction that
@@ -988,22 +991,36 @@ starts from state a maintainer cannot recreate is not a reproduction.
988
991
  ## Filing it
989
992
 
990
993
  The tracker is [kici-dev/kici-public](https://github.com/kici-dev/kici-public),
991
- and the form is **Agent report**:
994
+ and the form is **Agent report** (`agent_report.yml`). It is a GitHub issue
995
+ form, which only the browser can submit — `gh issue create` cannot fill it.
996
+ So you draft, and the person files.
992
997
 
993
- ```bash
994
- kici feedback --open
998
+ Write the draft as JSON, one key per field of the form (`kici feedback --json`
999
+ lists them under `draftFields`):
1000
+
1001
+ ```json
1002
+ {
1003
+ "title": "kici compile --check writes a lock file",
1004
+ "advertised": "https://docs.kici.dev/user/cli-reference/ says: `kici compile --check` type-checks without writing a lock file.",
1005
+ "observed": ".kici/kici.lock.json was written; mtime changed.",
1006
+ "reproduction": "$ mkdir /tmp/repro && cd /tmp/repro\n$ kici init\n$ kici compile --check",
1007
+ "version": "0.8.0",
1008
+ "environment": "Node 24.13.0, Ubuntu 24.04",
1009
+ "justification": "The sentence names --check as the no-write mode; no reading of it allows a write."
1010
+ }
995
1011
  ```
996
1012
 
997
- Draft the complete body first. Show it to the person you are working with —
998
- the whole body, not a summary of it. File only after they say yes:
1013
+ Then build the prefilled form:
999
1014
 
1000
1015
  ```bash
1001
- gh issue create --repo kici-dev/kici-public --template agent_report.yml
1016
+ kici feedback --draft draft.json --open
1002
1017
  ```
1003
1018
 
1004
- The form asks you to confirm the report was drafted by an agent and reviewed by
1005
- a person before filing. Answer honestly; it is what lets maintainers triage
1006
- agent-filed reports as a group.
1019
+ The command prints the form URL with every field filled in and, with
1020
+ `--open`, opens it. It reaches no network and files nothing. Show the person
1021
+ you are working with the whole draft — not a summary of it. They open the
1022
+ URL, read the prefilled form, tick the review boxes, and submit. File only
1023
+ after they say yes.
1007
1024
 
1008
1025
  If they say no, that is the end of it. Do not re-file the same finding in
1009
1026
  another form, and do not open it as a question instead.
@@ -758,8 +758,8 @@ kici-admin org-settings global-workflows deny-add \
758
758
  ```
759
759
 
760
760
  See [Global workflows](https://docs.kici.dev/architecture/global-workflows/) for the
761
- policy model (`isWorkflowRepoAllowed` + `isSourceRepoAllowed` +
762
- `isElevatedAccessAllowed`) and the cross-provider dispatch contract.
761
+ policy model (`isWorkflowRepoAllowed` + `isSourceRepoAllowed`) and the
762
+ cross-provider dispatch contract.
763
763
 
764
764
  ## Routing-key collisions
765
765
 
@@ -1543,13 +1543,15 @@ const deploy = job('deploy', {
1543
1543
 
1544
1544
  Request a short-lived OIDC ID token for the current job, bound to an `audience`. The token is a signed JWT whose identity claims (`repository`, `ref`, `sha`, `kici_run_id`, `kici_job_id`) are derived by your orchestrator from the run context — a step cannot spoof them. Use it to authenticate the build to an external service that trusts the orchestrator's OIDC issuer (for example, when generating build provenance).
1545
1545
 
1546
- The token also carries the event context a cloud trust policy needs to tell a fork pull request from a trusted push — `is_fork`, `head_repository`, `trust_tier`, `event_name`, and a pull-request-specific `sub`. See [ID-token claims and cloud trust policies](https://docs.kici.dev/user/provenance/#id-token-claims-and-cloud-trust-policies) for the full claim table and a worked AWS policy.
1546
+ The token also carries the event context a cloud trust policy needs to tell a fork pull request from a trusted push — `is_fork`, `head_repository`, `trust_tier`, `event_name`, and a pull-request-specific `sub`. See [ID-token claims and cloud trust policies](https://docs.kici.dev/user/oidc/#id-token-claims-and-cloud-trust-policies) for the full claim table and a worked AWS policy.
1547
1547
 
1548
1548
  ```typescript
1549
1549
  const publish = job('publish', {
1550
1550
  steps: [
1551
1551
  step('mint', async (ctx) => {
1552
- const { token, expiresIn } = await ctx.kici.oidc.token({ audience: 'sigstore' });
1552
+ const minted = await ctx.kici.oidc.token({ audience: 'sigstore' });
1553
+ if ('deferred' in minted) throw new Error(`ID token deferred: ${minted.code}`);
1554
+ const { token, expiresIn } = minted;
1553
1555
  ctx.log.info(`Got an ID token valid for ${expiresIn}s`);
1554
1556
  // Hand `token` to a tool that exchanges it with the trusting service.
1555
1557
  }),
@@ -1559,6 +1561,7 @@ const publish = job('publish', {
1559
1561
 
1560
1562
  **Behavior:**
1561
1563
 
1564
+ - The result is the minted token, or `{ deferred: true, code }` (`unavailable` | `failed`) when the orchestrator could not mint one right now. A step that exchanges the token fails on `deferred`; `ctx.attestProvenance` handles it by freezing the statement for later fulfilment.
1562
1565
  - The token is short-lived (about 10 minutes) and scoped to the current run and job.
1563
1566
  - The returned token value is automatically masked in step logs.
1564
1567
  - The step never holds signing credentials — the orchestrator mints and signs the token on the step's behalf from its own run records.
@@ -1051,9 +1051,8 @@ The throw is a `ChangedFilesUnavailableError` (exported from `@kici-dev/sdk`, ca
1051
1051
  ### evaluateRules(rules, context, label, onRuleResult?)
1052
1052
 
1053
1053
  The agent calls this on your behalf. A workflow does not call it. It lives on
1054
- `@kici-dev/sdk/internal`, outside semver, and stays exported from the root barrel as
1055
- `@deprecated` until v1.0.0 see [deprecations](https://docs.kici.dev/user/deprecations/). It is described here
1056
- because its return shape is what a rule's outcome looks like in the run log.
1054
+ `@kici-dev/sdk/internal`, outside semver, and is not exported from the root barrel. It is
1055
+ described here because its return shape is what a rule's outcome looks like in the run log.
1057
1056
 
1058
1057
  Evaluate an array of rules sequentially with fail-fast behavior. Stops on the first failure.
1059
1058
 
@@ -1306,9 +1305,8 @@ isDynamicFunction(matrix); // true if async function
1306
1305
  ### Matrix expansion utilities
1307
1306
 
1308
1307
  The agent expands a matrix for you. A workflow does not call these. They live on
1309
- `@kici-dev/sdk/internal`, outside semver, and stay exported from the root barrel as
1310
- `@deprecated` until v1.0.0 see [deprecations](https://docs.kici.dev/user/deprecations/). They are described
1311
- here because they define the combinations a matrix job actually produces.
1308
+ `@kici-dev/sdk/internal`, outside semver, and are not exported from the root barrel. They are
1309
+ described here because they define the combinations a matrix job actually produces.
1312
1310
 
1313
1311
  ```typescript
1314
1312
  import { expandMatrix, applyIncludeExclude } from '@kici-dev/sdk/internal';
@@ -1905,7 +1903,7 @@ Create a commit status trigger. Returns a frozen `StatusTriggerConfig`.
1905
1903
  function status(config?: StatusConfigInput): StatusTriggerConfig;
1906
1904
  ```
1907
1905
 
1908
- **Config options:** `contexts` (picomatch strings like 'ci/\*'), `states` (error/failure/pending/success), `description`
1906
+ **Config options:** `contexts` (glob patterns like 'ci/\*'), `states` (error/failure/pending/success), `description`
1909
1907
 
1910
1908
  ```typescript
1911
1909
  status(); // Any status
@@ -2531,11 +2529,8 @@ a `.result` proxy reads, build the step context your workflow body receives, eva
2531
2529
  rules, and expand its matrix. The agent drives all of it on your behalf.
2532
2530
 
2533
2531
  It is **not covered by semver** and may change shape in any release. Do not import it from
2534
- a workflow. Everything a workflow author needs is on the root entry point above.
2535
-
2536
- Those same symbols are also still exported from the root barrel, marked `@deprecated`, so
2537
- an older SDK in a repository keeps working. They are removed from the root at v1.0.0 — see
2538
- [deprecations](https://docs.kici.dev/user/deprecations/).
2532
+ a workflow. Everything a workflow author needs is on the root entry point above, and none
2533
+ of the runtime contract is exported there.
2539
2534
 
2540
2535
  ## See also
2541
2536
 
@@ -1,6 +1,6 @@
1
1
  # KiCI
2
2
 
3
- > KiCI is a TypeScript-native CI/CD workflow engine. Workflows are defined in TypeScript (not YAML), compiled into a portable lock file, and executed by self-hosted agents. The docs below cover the SDK, the CLI, workflow patterns, and the runtime architecture an LLM coding agent needs in order to author and test KiCI workflows.
3
+ > KiCI is a TypeScript-native CI/CD workflow engine. Workflows are defined in TypeScript (not YAML), compiled into a portable lock file, and executed by self-hosted agents. The docs below cover the SDK, the CLI, workflow patterns, and the runtime architecture an LLM coding agent needs to author and test KiCI workflows.
4
4
 
5
5
  The full markdown bundle of every page indexed here is available at https://docs.kici.dev/llms-full.txt.
6
6
 
@@ -10,16 +10,16 @@ Found a mismatch between what these docs advertise and what KiCI does? Read http
10
10
 
11
11
  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:
12
12
 
13
- - [getting-started](https://docs.kici.dev/llms-getting-started.txt) (65 KB) — Adopt KiCI: why it exists, how workflows execute, migrating from GitHub Actions, installing the SDK, and writing/compiling/testing your first workflow
13
+ - [getting-started](https://docs.kici.dev/llms-getting-started.txt) (66 KB) — Adopt KiCI: why it exists, how workflows execute, migrating from GitHub Actions, installing the SDK, and writing/compiling/testing your first workflow
14
14
  - [patterns](https://docs.kici.dev/llms-patterns.txt) (61 KB) — Copy-paste workflow recipes: triggers, conditionals, matrix, scheduling, integrations
15
15
  - [sdk](https://docs.kici.dev/llms-sdk.txt) (131 KB) — Core authoring API: workflow/job/step factories, triggers, rules, matrix, dynamic jobs, cross-job outputs
16
- - [sdk-runtime](https://docs.kici.dev/llms-sdk-runtime.txt) (115 KB) — Runtime and advanced authoring: step runtime context, event payloads, host fan-out, idempotent steps, caching, artifacts, waiting
16
+ - [sdk-runtime](https://docs.kici.dev/llms-sdk-runtime.txt) (116 KB) — Runtime and advanced authoring: step runtime context, event payloads, host fan-out, idempotent steps, caching, artifacts, waiting
17
17
  - [cli](https://docs.kici.dev/llms-cli.txt) (97 KB) — Running the CLI locally: compile, test, run local, hooks, lock-file drift, common failures
18
18
  - [cli-remote](https://docs.kici.dev/llms-cli-remote.txt) (111 KB) — Auth, org and orchestrator selection, runs, approvals, notifications, diagnostics, and the MCP server a coding agent connects to
19
- - [features](https://docs.kici.dev/llms-features.txt) (97 KB) — Deployment contexts, scoped secrets, private registries, approvals, provenance, dashboard and account access
19
+ - [features](https://docs.kici.dev/llms-features.txt) (112 KB) — Deployment contexts, scoped secrets, private registries, approvals, workload identity, provenance, dashboard and account access
20
20
  - [features-execution](https://docs.kici.dev/llms-features-execution.txt) (124 KB) — Concurrency, dynamic values, events, container jobs, environment variables, global workflows, idempotent steps
21
21
  - [providers](https://docs.kici.dev/llms-providers.txt) (35 KB) — Connecting sources: GitHub App, universal-git (Forgejo/Gitea/GitLab), local file://
22
- - [architecture](https://docs.kici.dev/llms-architecture.txt) (100 KB) — How the runtime works: three-tier relay model, data flows, configuration
22
+ - [architecture](https://docs.kici.dev/llms-architecture.txt) (101 KB) — How the runtime works: three-tier relay model, data flows, configuration
23
23
 
24
24
  ## Getting started
25
25
 
@@ -86,6 +86,7 @@ Each bundle below is a self-contained markdown file for one authoring task. Fetc
86
86
  - [Approval gates](https://docs.kici.dev/user/approvals/): Pause a workflow for human sign-off at step, job, or workflow granularity with approval
87
87
  - [Contexts](https://docs.kici.dev/user/contexts/): Configure deployment contexts with variables, secrets, and protection rules
88
88
  - [Dashboard](https://docs.kici.dev/user/dashboard/): Web UI for monitoring workflow runs, managing sources, secrets, and organization settings.
89
+ - [Workload identity with OIDC](https://docs.kici.dev/user/oidc/): Mint short-lived OIDC identity tokens in a step and exchange them with Cloudsmith, AWS, or any service that federates with your orchestrator
89
90
  - [Private npm registries](https://docs.kici.dev/user/private-registries/): Authenticate `npm install` against private registries (CodeArtifact, GitHub Packages, Verdaccio, …) from a workflow's `.kici/package.json`
90
91
  - [Build provenance and attestations](https://docs.kici.dev/user/provenance/): Generate and verify signed SLSA provenance for the artifacts your workflows build
91
92
  - [Secrets](https://docs.kici.dev/user/secrets/): How to access secrets in KiCI workflow steps
@@ -26,15 +26,14 @@ export interface SpawnOrchestratorOptions {
26
26
  * generated by the plane. Enables the orchestrator's local OIDC mint +
27
27
  * dev-signed provenance (issuer `kici-local`) in independent mode. Present in
28
28
  * the independent boot; omitted (with `attach`) in the hybrid boot, which
29
- * mints via the Platform relay instead.
29
+ * mints with the orchestrator's own signing key instead.
30
30
  */
31
31
  devIdentityKeyFile?: string;
32
32
  /**
33
33
  * When present, boot the orchestrator in HYBRID mode attached to the Platform
34
- * relay instead of independent mode. OIDC + attestation then mint via the
35
- * Platform (the local dev signer is never consulted the orchestrator's
36
- * `selectOidcMintRegistration` prefers the relay whenever a Platform
37
- * connection exists).
34
+ * relay instead of independent mode. OIDC + attestation then mint with the
35
+ * orchestrator's own signing key under its own issuer, exactly as a deployed
36
+ * orchestrator does (the local dev signer is never consulted).
38
37
  */
39
38
  attach?: {
40
39
  /** Orchestrator KICI_PLATFORM_URL — a ws(s)://…/ws relay URL. */
@@ -77,7 +77,8 @@ function spawnOrchestratorProcess(databaseUrl, opts) {
77
77
  modeEnv = {
78
78
  KICI_MODE: "hybrid",
79
79
  KICI_PLATFORM_URL: opts.attach.platformWsUrl,
80
- KICI_PLATFORM_TOKEN: opts.attach.platformToken
80
+ KICI_PLATFORM_TOKEN: opts.attach.platformToken,
81
+ KICI_ORCHESTRATOR_PROVENANCE_ISSUER: `http://127.0.0.1:${port}`
81
82
  };
82
83
  } else {
83
84
  entry = resolveStandaloneEntry();
@@ -19,8 +19,8 @@ import { generateKeyPairSync, randomBytes } from "node:crypto";
19
19
  */
20
20
  function currentBuildIdentity() {
21
21
  return {
22
- version: "0.8.0",
23
- buildCommit: "57712173f"
22
+ version: "0.9.0",
23
+ buildCommit: "69765a7ee"
24
24
  };
25
25
  }
26
26
  /**
@@ -4,5 +4,5 @@
4
4
  * picked up by Claude Code, Cursor, Aider, and other coding agents that scan
5
5
  * the working tree for an authoring context file.
6
6
  */
7
- export declare const agentsMdTemplate = "# KiCI workflow authoring guide\n\nThis project uses KiCI \u2014 a TypeScript-native CI/CD workflow engine \u2014 instead\nof YAML-based CI. Workflows live in `.kici/workflows/*.ts`, are compiled\ninto a portable lock file, and executed by self-hosted agents.\n\n## Where the API surface lives\n\n- Public SDK types: `node_modules/@kici-dev/sdk/dist/index.d.ts` \u2014 read this\n for the canonical signatures of `workflow`, `job`, `step`, `pr`,\n `push`, `schedule`, `rule`, `dynamicJob`, etc.\n- Bundled offline reference for coding agents: `kici docs llm` prints the\n full markdown documentation bundle to stdout. `kici docs llm --index`\n prints just the curated link index (llms.txt format).\n- Online docs:\n - <https://kici.dev/docs/> \u2014 published docs site.\n - <https://kici.dev/llms.txt> \u2014 curated index for LLM consumers.\n - <https://kici.dev/llms-full.txt> \u2014 full markdown bundle.\n - Key pages: `user/sdk-reference`, `user/workflow-patterns`,\n `user/testing-guide`, `user/hooks`, `user/secrets`.\n\n## The five core patterns\n\n1. **Push trigger** \u2014 `on: push({ branches: 'main' })`. Pair with `paths`\n to scope to subtrees.\n\n ```ts\n import { workflow, job, step, push } from '@kici-dev/sdk';\n\n export default workflow('build', {\n on: push({ branches: 'main' }),\n jobs: [\n job('build', {\n runsOn: 'kici:os:linux',\n steps: [step('install', async ({ $ }) => { await $`pnpm install`; })],\n }),\n ],\n });\n ```\n\n `kici:os:linux` targets any agent reporting that OS \u2014 every agent\n self-reports `kici:os:` / `kici:arch:` / `kici:host:`. Use a custom label\n (e.g. `'gpu'`, `'prod-pool'`) to target a specific agent pool your scaler\n defines.\n\n2. **PR + matrix** \u2014 `pr({ target: 'main' })` plus a matrix over node\n versions. The matrix expands at dispatch time.\n\n ```ts\n import { workflow, job, step, pr } from '@kici-dev/sdk';\n\n export default workflow('test-matrix', {\n on: pr({ target: 'main' }),\n jobs: [\n job('test', {\n runsOn: 'kici:os:linux',\n matrix: { node: ['20', '22', '24'] },\n steps: [\n step('test', async ({ $, matrix }) => {\n await $`echo testing on node ${matrix!.node}`;\n await $`pnpm install`;\n await $`pnpm test`;\n }),\n ],\n }),\n ],\n });\n ```\n\n3. **Lifecycle hooks** \u2014 `onFailure` / `onSuccess` / `onCancel` on a\n job or workflow run after the main steps in their own scope.\n\n4. **Secrets** \u2014 declared scopes resolve at dispatch:\n\n ```ts\n step('deploy', async ({ $, secrets }) => {\n await secrets.expose('DEPLOY_TOKEN');\n await $`./scripts/deploy.sh`;\n });\n ```\n\n Run `kici secrets list` to enumerate the contexts available for testing.\n\n5. **Dynamic jobs** \u2014 `dynamicJob` and `dynamicGroup` build the DAG at\n runtime from a step's outputs. Don't try to compute job names at top level;\n the lock file would be wrong.\n\n## Anti-patterns\n\n- **Do NOT write `.yml` / `.yaml` CI files** \u2014 KiCI replaces that entire\n layer. There is no compatibility shim.\n- **Do NOT `import` from any `@kici-dev/*` package's `/dist/...`\n subpath** \u2014 those are not part of the public API and break across versions.\n Import from the package root.\n- **Do NOT `await` outside step bodies.** The top-level workflow file is\n loaded by the compiler synchronously; async I/O at module scope means the\n lock file emits before it resolves and the workflow appears empty.\n- **Do NOT mutate shared variables between jobs.** Each job runs in its own\n agent process. Use `needs` + step outputs to thread values.\n- **Do NOT hand-edit `kici.lock.json`.** Regenerate it via `kici compile`.\n\n## Local commands a coding agent should run\n\n| Command | Purpose |\n| ------------------------------- | ------------------------------------------- |\n| `pnpm kici compile --check` | Validate workflow source without writing. |\n| `pnpm kici preview pr:open --debug` | Preview which workflows match an event. |\n| `pnpm kici run push --local` | Execute a workflow locally (this machine as an ephemeral agent). |\n| `pnpm kici docs llm` | Print the full LLM documentation bundle. |\n| `pnpm kici docs llm --index` | Print the curated link index. |\n\nIf `pnpm kici` isn't in scripts, fall back to `npx kici`.\n\n## Loop\n\n1. Read the SDK types from `node_modules/@kici-dev/sdk/dist/index.d.ts`.\n2. Pipe `kici docs llm` into the agent's context if it doesn't already have\n the full bundle.\n3. Edit a workflow under `.kici/workflows/`.\n4. Run `kici compile --check` (zero exit means valid).\n5. Run `kici preview <event>` to preview matching.\n6. Run `kici run <event> --local` to execute locally before pushing.\n";
7
+ export declare const agentsMdTemplate = "# KiCI workflow authoring guide\n\nThis project uses KiCI \u2014 a TypeScript-native CI/CD workflow engine \u2014 instead\nof YAML-based CI. Workflows live in `.kici/workflows/*.ts`, are compiled\ninto a portable lock file, and executed by self-hosted agents.\n\n## Where the API surface lives\n\n- Public SDK types: `node_modules/@kici-dev/sdk/dist/index.d.ts` \u2014 read this\n for the canonical signatures of `workflow`, `job`, `step`, `pr`,\n `push`, `schedule`, `rule`, `dynamicJob`, etc.\n- Bundled offline reference for coding agents: `kici docs llm` prints the\n curated link index (llms.txt format); `kici docs llm full` prints the\n complete markdown documentation bundle; `kici docs llm <topic>` prints one\n task bundle (`sdk`, `cli`, `patterns`, \u2026).\n- Online docs:\n - <https://docs.kici.dev/> \u2014 published docs site.\n - <https://kici.dev/llms.txt> \u2014 curated index for LLM consumers.\n - <https://kici.dev/llms-full.txt> \u2014 full markdown bundle.\n - Key pages: `user/sdk-reference`, `user/workflow-patterns`,\n `user/testing-guide`, `user/hooks`, `user/secrets`.\n\n## The five core patterns\n\n1. **Push trigger** \u2014 `on: push({ branches: 'main' })`. Pair with `paths`\n to scope to subtrees.\n\n ```ts\n import { workflow, job, step, push } from '@kici-dev/sdk';\n\n export default workflow('build', {\n on: push({ branches: 'main' }),\n jobs: [\n job('build', {\n runsOn: 'kici:os:linux',\n steps: [step('install', async ({ $ }) => { await $`pnpm install`; })],\n }),\n ],\n });\n ```\n\n `kici:os:linux` targets any agent reporting that OS \u2014 every agent\n self-reports `kici:os:` / `kici:arch:` / `kici:host:`. Use a custom label\n (e.g. `'gpu'`, `'prod-pool'`) to target a specific agent pool your scaler\n defines.\n\n2. **PR + matrix** \u2014 `pr({ target: 'main' })` plus a matrix over node\n versions. The matrix expands at dispatch time.\n\n ```ts\n import { workflow, job, step, pr } from '@kici-dev/sdk';\n\n export default workflow('test-matrix', {\n on: pr({ target: 'main' }),\n jobs: [\n job('test', {\n runsOn: 'kici:os:linux',\n matrix: { node: ['20', '22', '24'] },\n steps: [\n step('test', async ({ $, matrix }) => {\n await $`echo testing on node ${matrix!.node}`;\n await $`pnpm install`;\n await $`pnpm test`;\n }),\n ],\n }),\n ],\n });\n ```\n\n3. **Lifecycle hooks** \u2014 `onFailure` / `onSuccess` / `onCancel` on a\n job or workflow run after the main steps in their own scope.\n\n4. **Secrets** \u2014 declared scopes resolve at dispatch:\n\n ```ts\n step('deploy', async ({ $, secrets }) => {\n await secrets.expose('DEPLOY_TOKEN');\n await $`./scripts/deploy.sh`;\n });\n ```\n\n Run `kici secrets list` to enumerate the contexts available for testing.\n\n5. **Dynamic jobs** \u2014 `dynamicJob` and `dynamicGroup` build the DAG at\n runtime from a step's outputs. Don't try to compute job names at top level;\n the lock file would be wrong.\n\n## Anti-patterns\n\n- **Do NOT write `.yml` / `.yaml` CI files** \u2014 KiCI replaces that entire\n layer. There is no compatibility shim.\n- **Do NOT `import` from any `@kici-dev/*` package's `/dist/...`\n subpath** \u2014 those are not part of the public API and break across versions.\n Import from the package root.\n- **Do NOT `await` outside step bodies.** The top-level workflow file is\n loaded by the compiler synchronously; async I/O at module scope means the\n lock file emits before it resolves and the workflow appears empty.\n- **Do NOT mutate shared variables between jobs.** Each job runs in its own\n agent process. Use `needs` + step outputs to thread values.\n- **Do NOT hand-edit `kici.lock.json`.** Regenerate it via `kici compile`.\n\n## Local commands a coding agent should run\n\n| Command | Purpose |\n| ------------------------------- | ------------------------------------------- |\n| `pnpm kici compile --check` | Validate workflow source without writing. |\n| `pnpm kici preview pr:open --debug` | Preview which workflows match an event. |\n| `pnpm kici run push --local` | Execute a workflow locally (this machine as an ephemeral agent). |\n| `pnpm kici docs llm` | Print the curated link index (llms.txt). |\n| `pnpm kici docs llm full` | Print the full LLM documentation bundle. |\n| `pnpm kici docs llm sdk` | Print one task bundle (also `cli`, `patterns`, \u2026). |\n\nIf `pnpm kici` isn't in scripts, fall back to `npx kici`.\n\n## Loop\n\n1. Read the SDK types from `node_modules/@kici-dev/sdk/dist/index.d.ts`.\n2. Pipe `kici docs llm sdk` (or `kici docs llm full`) into the agent's context if\n it doesn't already have the authoring reference.\n3. Edit a workflow under `.kici/workflows/`.\n4. Run `kici compile --check` (zero exit means valid).\n5. Run `kici preview <event>` to preview matching.\n6. Run `kici run <event> --local` to execute locally before pushing.\n";
8
8
  //# sourceMappingURL=agents-md.d.ts.map
@@ -18,10 +18,11 @@ into a portable lock file, and executed by self-hosted agents.
18
18
  for the canonical signatures of \`workflow\`, \`job\`, \`step\`, \`pr\`,
19
19
  \`push\`, \`schedule\`, \`rule\`, \`dynamicJob\`, etc.
20
20
  - Bundled offline reference for coding agents: \`kici docs llm\` prints the
21
- full markdown documentation bundle to stdout. \`kici docs llm --index\`
22
- prints just the curated link index (llms.txt format).
21
+ curated link index (llms.txt format); \`kici docs llm full\` prints the
22
+ complete markdown documentation bundle; \`kici docs llm <topic>\` prints one
23
+ task bundle (\`sdk\`, \`cli\`, \`patterns\`, …).
23
24
  - Online docs:
24
- - <https://kici.dev/docs/> — published docs site.
25
+ - <https://docs.kici.dev/> — published docs site.
25
26
  - <https://kici.dev/llms.txt> — curated index for LLM consumers.
26
27
  - <https://kici.dev/llms-full.txt> — full markdown bundle.
27
28
  - Key pages: \`user/sdk-reference\`, \`user/workflow-patterns\`,
@@ -114,16 +115,17 @@ into a portable lock file, and executed by self-hosted agents.
114
115
  | \`pnpm kici compile --check\` | Validate workflow source without writing. |
115
116
  | \`pnpm kici preview pr:open --debug\` | Preview which workflows match an event. |
116
117
  | \`pnpm kici run push --local\` | Execute a workflow locally (this machine as an ephemeral agent). |
117
- | \`pnpm kici docs llm\` | Print the full LLM documentation bundle. |
118
- | \`pnpm kici docs llm --index\` | Print the curated link index. |
118
+ | \`pnpm kici docs llm\` | Print the curated link index (llms.txt). |
119
+ | \`pnpm kici docs llm full\` | Print the full LLM documentation bundle. |
120
+ | \`pnpm kici docs llm sdk\` | Print one task bundle (also \`cli\`, \`patterns\`, …). |
119
121
 
120
122
  If \`pnpm kici\` isn't in scripts, fall back to \`npx kici\`.
121
123
 
122
124
  ## Loop
123
125
 
124
126
  1. Read the SDK types from \`node_modules/@kici-dev/sdk/dist/index.d.ts\`.
125
- 2. Pipe \`kici docs llm\` into the agent's context if it doesn't already have
126
- the full bundle.
127
+ 2. Pipe \`kici docs llm sdk\` (or \`kici docs llm full\`) into the agent's context if
128
+ it doesn't already have the authoring reference.
127
129
  3. Edit a workflow under \`.kici/workflows/\`.
128
130
  4. Run \`kici compile --check\` (zero exit means valid).
129
131
  5. Run \`kici preview <event>\` to preview matching.
@@ -1,6 +1,6 @@
1
1
  import "../rolldown-runtime-ClRpJifh.js";
2
2
  //#region src/templates/package-json.ts
3
- const sdkVersion = "0.8.0";
3
+ const sdkVersion = "0.9.0";
4
4
  /**
5
5
  * The npm version spec the scaffold pins `@kici-dev/sdk` to.
6
6
  *
@@ -1,5 +1,5 @@
1
1
  // Hello World -- minimal push workflow
2
- // Docs: https://kici.dev/docs/sdk-reference
2
+ // Docs: https://docs.kici.dev/user/sdk-reference/
3
3
 
4
4
  import { workflow, job, step, push } from '@kici-dev/sdk';
5
5
 
@@ -1,6 +1,6 @@
1
1
  // PR Checks -- workflow with rules, dependencies, and multiple jobs
2
- // Docs: https://kici.dev/docs/sdk-reference
3
- // Patterns: https://kici.dev/docs/workflow-patterns
2
+ // Docs: https://docs.kici.dev/user/sdk-reference/
3
+ // Patterns: https://docs.kici.dev/user/workflow-patterns/
4
4
 
5
5
  import { workflow, job, step, pr, rule, skip, isEventType } from '@kici-dev/sdk';
6
6
 
@@ -12,13 +12,14 @@ import { setJobOutputsMap, setStepOutputsMap, setStepRefMap } from "@kici-dev/sd
12
12
  /**
13
13
  * Resolve SDK output setter functions from the workflow's module instance.
14
14
  * This ensures the output maps are set on the same SDK module that the
15
- * workflow code uses for .result proxy resolution and ctx.outputsOf().
15
+ * workflow code uses for .result proxy resolution and ctx.outputsOf(). The
16
+ * setters live only on the `@kici-dev/sdk/internal` subpath.
16
17
  *
17
18
  * Falls back to the compiler's own SDK import if dynamic resolution fails.
18
19
  */
19
20
  async function resolveSdkSetters(kiciDir) {
20
21
  if (kiciDir) try {
21
- const sdkPath = path.join(kiciDir, "node_modules", "@kici-dev", "sdk", "dist", "index.js");
22
+ const sdkPath = path.join(kiciDir, "node_modules", "@kici-dev", "sdk", "dist", "internal.js");
22
23
  const sdk = await import(pathToFileURL(sdkPath).href);
23
24
  return {
24
25
  setStepOutputsMap: sdk.setStepOutputsMap,
package/dist/types.d.ts CHANGED
@@ -8,7 +8,7 @@
8
8
  * v6 replaces job-level contexts with environment/env/concurrencyGroup.
9
9
  * v7 adds hook flags, step rules, gracePeriod, and workflow concurrency config.
10
10
  * v8 adds runsOn polymorphic type (string | string[] | selector) and excludeLabels.
11
- * v11 adds LockInlineValue type for pure function inline evaluation.
11
+ * v11 added an inline-expression value shape for dynamic fields, which is no longer parsed.
12
12
  * v15 adds per-job init config(s).
13
13
  * v17 widens per-job init to typed presets ('mise' / { mise }) and 'auto' detection.
14
14
  */
@@ -394,29 +394,6 @@ export interface LockParallelStep {
394
394
  export type LockStepEntry = LockStep | LockParallelStep;
395
395
  /** Type guard distinguishing a parallel group from an ordinary lock step. */
396
396
  export declare function isLockParallelStep(entry: LockStepEntry): entry is LockParallelStep;
397
- /**
398
- * Serialized inline expression for a dynamic env/context/concurrencyGroup
399
- * field, shaped as `{ _type: 'inline', expression: '(event) => ...' }`
400
- * alongside the existing 'static' and 'dynamic' discriminants.
401
- *
402
- * @deprecated Schema v11 inline expressions are no longer evaluated in the
403
- * orchestrator. Dynamic env/context/concurrencyGroup fields are resolved on the
404
- * eval agent's init-runner. The compiler no longer emits this type; readers keep
405
- * recognizing it only to defer an old lock's field to the init round. Removed at
406
- * the next major (v1.0.0).
407
- */
408
- export interface LockInlineValue {
409
- readonly _type: 'inline';
410
- readonly expression: string;
411
- }
412
- /**
413
- * Type guard for inline expression values.
414
- *
415
- * @deprecated See {@link LockInlineValue}. Retained only so a reader can
416
- * recognize an old lock's inline field and defer it to the eval agent's
417
- * init-runner. Removed at the next major (v1.0.0).
418
- */
419
- export declare function isLockInlineValue(value: unknown): value is LockInlineValue;
420
397
  /**
421
398
  * Static job in lock file.
422
399
  * Contains all orchestrator-readable information for scheduling.
@@ -500,21 +477,21 @@ export interface LockJob {
500
477
  };
501
478
  };
502
479
  /**
503
- * Bound contexts in merge order. Each entry is a static name or inline
504
- * expression (pure function); `dynamic` is set when it is a function resolved at
505
- * two-phase eval. Later entries override earlier ones on name collisions.
480
+ * Bound contexts in merge order. Each entry is a static name; `dynamic` is set
481
+ * when it is a function resolved on the eval agent's init-runner. Later entries
482
+ * override earlier ones on name collisions.
506
483
  */
507
484
  readonly contexts?: ReadonlyArray<{
508
- value: string | LockInlineValue;
485
+ value: string;
509
486
  dynamic: boolean;
510
487
  }>;
511
- /** Static environment variables or inline expression (pure function). */
512
- readonly env?: Record<string, string> | LockInlineValue;
513
- /** When true, env is dynamic (function) -- resolved at orchestrator two-phase eval or inline. */
488
+ /** Static environment variables. */
489
+ readonly env?: Record<string, string>;
490
+ /** When true, env is dynamic (function) -- resolved on the eval agent's init-runner. */
514
491
  readonly dynamicEnv?: boolean;
515
- /** Concurrency group name (static string) or inline expression (pure function). */
516
- readonly concurrencyGroup?: string | LockInlineValue;
517
- /** When true, concurrencyGroup is dynamic (function) -- resolved at orchestrator two-phase eval or inline. */
492
+ /** Concurrency group name (static string). */
493
+ readonly concurrencyGroup?: string;
494
+ /** When true, concurrencyGroup is dynamic (function) -- resolved on the eval agent's init-runner. */
518
495
  readonly dynamicConcurrencyGroup?: boolean;
519
496
  /** Whether this job has an onCancel hook. */
520
497
  readonly hasOnCancel?: boolean;
@@ -658,7 +635,7 @@ export interface LockWorkflow {
658
635
  * v6 replaces job-level contexts with environment/env/concurrencyGroup.
659
636
  * v7 adds hook flags, step rules, gracePeriod, and workflow concurrency config.
660
637
  * v8 adds runsOn polymorphic type (string | string[] | selector) and excludeLabels.
661
- * v11 adds LockInlineValue type for pure function inline evaluation.
638
+ * v11 added an inline-expression value shape for dynamic fields, which is no longer parsed.
662
639
  * v13 adds job-level and workflow-level timeout.
663
640
  * v34 adds LockWorkflow.hasFilter (workflow-level pre-dispatch filter predicate).
664
641
  */
package/dist/types.js CHANGED
@@ -11,7 +11,7 @@ import { BREAKING_FLOOR as BREAKING_FLOOR$1, SCHEMA_VERSION as SCHEMA_VERSION$1
11
11
  * v6 replaces job-level contexts with environment/env/concurrencyGroup.
12
12
  * v7 adds hook flags, step rules, gracePeriod, and workflow concurrency config.
13
13
  * v8 adds runsOn polymorphic type (string | string[] | selector) and excludeLabels.
14
- * v11 adds LockInlineValue type for pure function inline evaluation.
14
+ * v11 added an inline-expression value shape for dynamic fields, which is no longer parsed.
15
15
  * v15 adds per-job init config(s).
16
16
  * v17 widens per-job init to typed presets ('mise' / { mise }) and 'auto' detection.
17
17
  */
@@ -23,16 +23,6 @@ const BREAKING_FLOOR = BREAKING_FLOOR$1;
23
23
  function isLockParallelStep(entry) {
24
24
  return entry.kind === "parallel";
25
25
  }
26
- /**
27
- * Type guard for inline expression values.
28
- *
29
- * @deprecated See {@link LockInlineValue}. Retained only so a reader can
30
- * recognize an old lock's inline field and defer it to the eval agent's
31
- * init-runner. Removed at the next major (v1.0.0).
32
- */
33
- function isLockInlineValue(value) {
34
- return typeof value === "object" && value !== null && value._type === "inline";
35
- }
36
26
  /** Type guard for static jobs */
37
27
  function isLockStaticJob(job) {
38
28
  return job._type === "static";
@@ -42,6 +32,6 @@ function isLockDynamicJobFn(job) {
42
32
  return job._type === "dynamic";
43
33
  }
44
34
  //#endregion
45
- export { BREAKING_FLOOR, SCHEMA_VERSION, isLockDynamicJobFn, isLockInlineValue, isLockParallelStep, isLockStaticJob };
35
+ export { BREAKING_FLOOR, SCHEMA_VERSION, isLockDynamicJobFn, isLockParallelStep, isLockStaticJob };
46
36
 
47
37
  //# sourceMappingURL=types.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.test-d.d.ts.map
@@ -0,0 +1,63 @@
1
+ import "./rolldown-runtime-ClRpJifh.js";
2
+ import { describe, expectTypeOf, it } from "vitest";
3
+ //#region src/types.test-d.ts
4
+ /**
5
+ * The lock-file dynamic fields no longer admit the schema-v11 inline
6
+ * expression `{ _type: 'inline', expression }`. That object is itself a
7
+ * `Record<string, string>`, so the `env` axis is pinned by type identity rather
8
+ * than by an assignment the compiler would accept either way; the two string
9
+ * fields refuse the object outright.
10
+ */
11
+ describe("LockJob dynamic fields", () => {
12
+ it("refuses an inline expression as the concurrency group", () => {
13
+ expectTypeOf({
14
+ _type: "static",
15
+ name: "build",
16
+ steps: [],
17
+ needs: [],
18
+ concurrencyGroup: {
19
+ _type: "inline",
20
+ expression: "() => \"deploy\""
21
+ }
22
+ }).toBeObject();
23
+ });
24
+ it("refuses an inline expression as a context name", () => {
25
+ expectTypeOf({
26
+ _type: "static",
27
+ name: "build",
28
+ steps: [],
29
+ needs: [],
30
+ contexts: [{
31
+ value: {
32
+ _type: "inline",
33
+ expression: "() => \"prod\""
34
+ },
35
+ dynamic: false
36
+ }]
37
+ }).toBeObject();
38
+ });
39
+ it("types env as exactly a plain record", () => {
40
+ expectTypeOf().toEqualTypeOf();
41
+ });
42
+ it("accepts the static shapes", () => {
43
+ const job = {
44
+ _type: "static",
45
+ name: "build",
46
+ steps: [],
47
+ needs: [],
48
+ env: { NODE_ENV: "test" },
49
+ dynamicEnv: true,
50
+ concurrencyGroup: "deploy",
51
+ contexts: [{
52
+ value: "production",
53
+ dynamic: false
54
+ }]
55
+ };
56
+ expectTypeOf(job.env).toEqualTypeOf();
57
+ expectTypeOf(job.concurrencyGroup).toEqualTypeOf();
58
+ });
59
+ });
60
+ //#endregion
61
+ export {};
62
+
63
+ //# sourceMappingURL=types.test-d.js.map
@@ -1,5 +1,5 @@
1
1
  // Hello World -- minimal push workflow
2
- // Docs: https://kici.dev/docs/sdk-reference
2
+ // Docs: https://docs.kici.dev/user/sdk-reference/
3
3
 
4
4
  import { workflow, job, step, push } from '@kici-dev/sdk';
5
5
 
@@ -1,6 +1,6 @@
1
1
  // PR Checks -- workflow with rules, dependencies, and multiple jobs
2
- // Docs: https://kici.dev/docs/sdk-reference
3
- // Patterns: https://kici.dev/docs/workflow-patterns
2
+ // Docs: https://docs.kici.dev/user/sdk-reference/
3
+ // Patterns: https://docs.kici.dev/user/workflow-patterns/
4
4
 
5
5
  import { workflow, job, step, pr, rule, skip, isEventType } from '@kici-dev/sdk';
6
6