@kici-dev/compiler 0.1.25 → 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
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Always-on startup banner for a routed `kici run --local` invocation. States
3
+ * the selected plane, where the agent runs, the secret + identity source, the
4
+ * control commands, and the flags that force a different behavior — so a
5
+ * developer always knows which plane a run used and why (design §5).
6
+ *
7
+ * Three variants:
8
+ * - `offline` — independent plane, local secrets, dev-signed identity.
9
+ * - `attached` — hybrid plane, real Platform-minted OIDC + attestation.
10
+ * - `fallback` — wanted attached but the Platform was unreachable, so the run
11
+ * fell back to offline; a LOUD first line makes the degradation obvious.
12
+ */
13
+ export type RunBannerMode = 'offline' | 'attached' | 'fallback';
14
+ export interface RunBannerInput {
15
+ mode: RunBannerMode;
16
+ /** Plane orchestrator URL (surfaced on the control line). */
17
+ planeUrl: string;
18
+ /** Org id (attached variant). */
19
+ orgId?: string;
20
+ /** Why the run fell back to offline (fallback variant). */
21
+ fallbackReason?: string;
22
+ /**
23
+ * Trusted fleet-agent profile (`--trusted`): the run routes to the trusted
24
+ * label set, so steps see the ambient host env (minus the agent's own KiCI
25
+ * identity secrets). Surfaced as a loud line so a trusted run is never silent.
26
+ */
27
+ trusted?: boolean;
28
+ }
29
+ /** Render the boxed run banner as a plain (uncolored) multi-line string. */
30
+ export declare function renderRunBanner(input: RunBannerInput): string;
31
+ //# sourceMappingURL=run-banner.d.ts.map
@@ -0,0 +1,25 @@
1
+ import "../rolldown-runtime-ClRpJifh.js";
2
+ //#region src/commands/run-banner.ts
3
+ /** Render the boxed run banner as a plain (uncolored) multi-line string. */
4
+ function renderRunBanner(input) {
5
+ const title = input.mode === "attached" ? "kici run --local (connected)" : "kici run --local";
6
+ const rows = [];
7
+ if (input.mode === "fallback") rows.push(["⚠", `Platform unreachable — fell back to OFFLINE${input.fallbackReason ? ` (${input.fallbackReason})` : ""}`]);
8
+ if (input.mode === "attached") rows.push(["plane", "local dev orchestrator (hybrid, attached)"], ["agent", "this machine (bare-metal)"], ["secrets", `REAL scoped${input.orgId ? ` (org: ${input.orgId})` : ""}`], ["identity", "real Platform OIDC + attestation"], ["control", `kici local status | logs | detach (${input.planeUrl})`], ["force", "--offline (local plane) · --in-place (ambient)"]);
9
+ else rows.push(["plane", "local dev orchestrator (independent, offline)"], ["agent", "this machine (bare-metal)"], ["secrets", "LOCAL files (.kici/.secrets, .env.local, --env)"], ["identity", "DEV-SIGNED (iss=kici-local — NOT prod)"], ["control", `kici local status | logs | down (${input.planeUrl})`], ["force", "--connected (attach to Platform) · --in-place (ambient)"]);
10
+ if (input.trusted) rows.push(["execution", "TRUSTED — host env passthrough (NOT sandboxed)"]);
11
+ const labelWidth = Math.max(...rows.map(([label]) => label.length));
12
+ const bodyLines = rows.map(([label, value]) => `${(label + ":").padEnd(labelWidth + 1)} ${value}`);
13
+ const contentWidth = Math.max(title.length + 2, ...bodyLines.map((l) => l.length));
14
+ const top = `┌ ${title} ${"─".repeat(Math.max(0, contentWidth - title.length))}┐`;
15
+ const bottom = `└${"─".repeat(contentWidth + 2)}┘`;
16
+ return [
17
+ top,
18
+ ...bodyLines.map((l) => `│ ${l.padEnd(contentWidth)} │`),
19
+ bottom
20
+ ].join("\n");
21
+ }
22
+ //#endregion
23
+ export { renderRunBanner };
24
+
25
+ //# sourceMappingURL=run-banner.js.map
@@ -0,0 +1,53 @@
1
+ /**
2
+ * `kici run --local [event]` — a real routed dispatch with this machine as the
3
+ * ephemeral agent, through the warm local dev plane. In this phase only the
4
+ * offline (independent) plane is wired; Platform attachment (`--connected` /
5
+ * auto-select hybrid) lands with the attachment work.
6
+ *
7
+ * The offline path reuses the real orchestrator + agent pipeline end-to-end, so
8
+ * the execution parity dividend (emit / cache / needs / parallel / `KICI_SOURCE_*`)
9
+ * holds by construction — there is no second engine.
10
+ */
11
+ export interface RunRoutedOptions {
12
+ event?: string;
13
+ local?: boolean;
14
+ offline?: boolean;
15
+ connected?: boolean;
16
+ inPlace?: boolean;
17
+ /**
18
+ * Trusted fleet-agent profile: route this run to the plane's trusted label
19
+ * set so steps run with the ambient host env passed through (minus the
20
+ * agent's own KiCI identity secrets). Selects a PRE-CONFIGURED trusted scaler
21
+ * label set by appending the `self-hosted` routing label to the run's job
22
+ * `runsOn` — it never injects `KICI_TRUSTED_ENV` onto a dispatch payload.
23
+ */
24
+ trusted?: boolean;
25
+ /** Flat per-run secrets (`--env KEY=VALUE`); delivery lands with the secret path. */
26
+ env?: string[];
27
+ /**
28
+ * Path to a dispatch payload JSON `{ action?, client_payload? }`. Only read
29
+ * when the event is `dispatch`: `action` becomes the dispatch `types` matcher
30
+ * key and `client_payload` reaches the workflow. This is how `packages/ci`
31
+ * targets a single `dispatch()` workflow (e.g. deploy-stg) on the routed path.
32
+ */
33
+ payload?: string;
34
+ kiciDir?: string;
35
+ quiet?: boolean;
36
+ debug?: boolean;
37
+ }
38
+ /**
39
+ * Entry point for the action-bearing `kici run`. Validates the routing flags and
40
+ * drives the offline routed run. Returns true on run success.
41
+ */
42
+ export declare function runRoutedCommand(options: RunRoutedOptions): Promise<boolean>;
43
+ /**
44
+ * Read a dispatch payload file `{ action?, client_payload? }`. Returns the
45
+ * action + client_payload the routed dispatch trigger carries. An absent
46
+ * `--payload` yields an empty action (a bare `dispatch()` workflow still
47
+ * matches); a present file is parsed as JSON.
48
+ */
49
+ export declare function readDispatchPayload(payloadPath?: string): {
50
+ action?: string;
51
+ clientPayload?: unknown;
52
+ };
53
+ //# sourceMappingURL=run-routed.d.ts.map
@@ -0,0 +1,176 @@
1
+ import "../rolldown-runtime-ClRpJifh.js";
2
+ import { resolveKiciDir } from "../execution/executor.js";
3
+ import "../execution/index.js";
4
+ import { formatSummary } from "../remote/output/summary.js";
5
+ import { IN_PLACE_ROUTING_LABEL, TRUSTED_ROUTING_LABEL } from "../local-plane/scaler-config.js";
6
+ import { ensureLocalSource } from "../local-plane/plane-seed.js";
7
+ import { triggerRun } from "../local-plane/plane-trigger.js";
8
+ import { resolvePlaneForRun } from "../local-plane/resolve-plane.js";
9
+ import { followRun } from "../local-plane/run-follow.js";
10
+ import { seedLocalSecrets } from "../local-plane/secret-seed.js";
11
+ import { resolveWorkdir } from "../local-plane/source-provider.js";
12
+ import { injectRunsOnLabel } from "../local-plane/trusted-routing.js";
13
+ import { compileCommand } from "./compile.js";
14
+ import { withStdoutOnStderr } from "./run.js";
15
+ import { renderRunBanner } from "./run-banner.js";
16
+ import path from "node:path";
17
+ import { readFileSync } from "node:fs";
18
+ import pc from "picocolors";
19
+ import { logger, toErrorMessage } from "@kici-dev/core";
20
+ //#region src/commands/run-routed.ts
21
+ /**
22
+ * `kici run --local [event]` — a real routed dispatch with this machine as the
23
+ * ephemeral agent, through the warm local dev plane. In this phase only the
24
+ * offline (independent) plane is wired; Platform attachment (`--connected` /
25
+ * auto-select hybrid) lands with the attachment work.
26
+ *
27
+ * The offline path reuses the real orchestrator + agent pipeline end-to-end, so
28
+ * the execution parity dividend (emit / cache / needs / parallel / `KICI_SOURCE_*`)
29
+ * holds by construction — there is no second engine.
30
+ */
31
+ /**
32
+ * Entry point for the action-bearing `kici run`. Validates the routing flags and
33
+ * drives the offline routed run. Returns true on run success.
34
+ */
35
+ async function runRoutedCommand(options) {
36
+ if (options.debug) process.env.KICI_DEBUG = "true";
37
+ if (!options.local) {
38
+ logger.error(pc.red("kici run (connected cloud run) is not yet available. Use `kici run --local` for a routed run on this machine, or `kici run remote <fixture>` for the fixture path."));
39
+ return false;
40
+ }
41
+ if (!options.event) {
42
+ logger.error(pc.red("Provide an event to run, e.g. `kici run --local push`."));
43
+ return false;
44
+ }
45
+ return runRouted({
46
+ ...options,
47
+ event: options.event
48
+ });
49
+ }
50
+ /**
51
+ * Read a dispatch payload file `{ action?, client_payload? }`. Returns the
52
+ * action + client_payload the routed dispatch trigger carries. An absent
53
+ * `--payload` yields an empty action (a bare `dispatch()` workflow still
54
+ * matches); a present file is parsed as JSON.
55
+ */
56
+ function readDispatchPayload(payloadPath) {
57
+ if (!payloadPath) return {};
58
+ const raw = JSON.parse(readFileSync(payloadPath, "utf-8"));
59
+ return {
60
+ action: raw.action,
61
+ clientPayload: raw.client_payload
62
+ };
63
+ }
64
+ /** Drive the full routed run against the warm local plane (offline or attached). */
65
+ async function runRouted(options) {
66
+ const quiet = Boolean(options.quiet);
67
+ const kiciDir = resolveKiciDir(options.kiciDir);
68
+ const repoRoot = path.resolve(kiciDir, "..");
69
+ if (!(quiet ? await withStdoutOnStderr(() => compileCommand({
70
+ kiciDir,
71
+ check: false,
72
+ verbose: options.debug ?? false,
73
+ quiet: true
74
+ })) : await compileCommand({
75
+ kiciDir,
76
+ check: false,
77
+ verbose: options.debug ?? false
78
+ }))) return false;
79
+ let cleanup;
80
+ const restoreLocks = [];
81
+ try {
82
+ if (!quiet) logger.info(pc.dim("Starting the local dev plane…"));
83
+ const resolved = await resolvePlaneForRun({
84
+ offline: options.offline,
85
+ connected: options.connected
86
+ });
87
+ if ("error" in resolved) {
88
+ logger.error(pc.red(resolved.error));
89
+ return false;
90
+ }
91
+ const plane = resolved.plane;
92
+ if (!plane.url || !plane.adminToken) {
93
+ logger.error(pc.red("Local dev plane did not report a URL + admin token."));
94
+ return false;
95
+ }
96
+ const trusted = Boolean(options.trusted);
97
+ if (!quiet) logger.info(renderRunBanner(resolved.kind === "attached" ? {
98
+ mode: "attached",
99
+ planeUrl: plane.url,
100
+ orgId: resolved.orgId,
101
+ trusted
102
+ } : resolved.kind === "fallback" ? {
103
+ mode: "fallback",
104
+ planeUrl: plane.url,
105
+ fallbackReason: resolved.reason,
106
+ trusted
107
+ } : {
108
+ mode: "offline",
109
+ planeUrl: plane.url,
110
+ trusted
111
+ }));
112
+ const workdir = await resolveWorkdir({
113
+ inPlace: Boolean(options.inPlace),
114
+ repoRoot
115
+ });
116
+ cleanup = workdir.cleanup;
117
+ if (trusted) {
118
+ const lockPath = path.join(workdir.dir, ".kici", "kici.lock.json");
119
+ restoreLocks.push(injectRunsOnLabel(lockPath, TRUSTED_ROUTING_LABEL).restore);
120
+ if (options.inPlace) restoreLocks.push(injectRunsOnLabel(lockPath, IN_PLACE_ROUTING_LABEL).restore);
121
+ }
122
+ const seeded = await ensureLocalSource(plane.url, plane.adminToken, {
123
+ repoDir: workdir.dir,
124
+ inPlace: Boolean(options.inPlace)
125
+ });
126
+ const seededSecrets = await seedLocalSecrets(plane.url, plane.adminToken, {
127
+ orgId: seeded.orgId,
128
+ kiciDir
129
+ });
130
+ if (!quiet && seededSecrets.contexts.length > 0) logger.info(pc.dim(`Seeded ${seededSecrets.secretCount} local secret(s) across ${seededSecrets.contexts.length} context(s): ${seededSecrets.contexts.join(", ")}`));
131
+ if (!quiet) logger.info(pc.dim(`Triggering ${options.event} …`));
132
+ const dispatch = options.event === "dispatch" ? readDispatchPayload(options.payload) : void 0;
133
+ const runId = await triggerRun(plane.url, plane.adminToken, {
134
+ orgId: seeded.orgId,
135
+ sourceId: seeded.sourceName,
136
+ repoFullName: ".",
137
+ event: options.event === "dispatch" ? "dispatch" : options.event === "pull_request" ? "pull_request" : "push",
138
+ ref: workdir.ref,
139
+ sha: workdir.sha,
140
+ defaultBranch: workdir.branch,
141
+ ...dispatch && {
142
+ action: dispatch.action,
143
+ clientPayload: dispatch.clientPayload
144
+ }
145
+ });
146
+ if (!quiet) logger.info(pc.green(`Run started: ${runId}`));
147
+ const outcome = await followRun(plane.url, plane.adminToken, runId, {
148
+ quiet,
149
+ onLine: (line) => process.stdout.write(line + "\n")
150
+ });
151
+ if (!quiet) {
152
+ const result = {
153
+ fixtureId: options.event,
154
+ runId,
155
+ status: outcome.status === "success" ? "success" : "failed",
156
+ totalDurationMs: 0,
157
+ jobs: outcome.jobs
158
+ };
159
+ process.stdout.write("\n" + formatSummary(result) + "\n");
160
+ }
161
+ return outcome.status === "success";
162
+ } catch (error) {
163
+ logger.error(pc.red(`\nError: ${toErrorMessage(error)}\n`));
164
+ if (options.debug && error instanceof Error && error.stack) logger.error(pc.gray(error.stack));
165
+ return false;
166
+ } finally {
167
+ for (const restore of restoreLocks.reverse()) try {
168
+ restore();
169
+ } catch {}
170
+ if (cleanup) await cleanup().catch(() => void 0);
171
+ }
172
+ }
173
+ //#endregion
174
+ export { readDispatchPayload, runRoutedCommand };
175
+
176
+ //# sourceMappingURL=run-routed.js.map
@@ -1,15 +1,5 @@
1
1
  import { type HostTargetSelector, type InputsDescriptorMap } from '@kici-dev/engine';
2
- import type { RunLocalOptions } from '../local-executor/types.js';
3
2
  import type { RemoteRunOptions } from './preview.js';
4
- /**
5
- * Print a usage block for `kici run local` when the event argument is missing.
6
- *
7
- * Mirrors the discoverable help `kici preview` prints for a missing event: a
8
- * bold synopsis line, a one-line description, and a few concrete event
9
- * examples. The caller exits non-zero after printing — a missing event is a
10
- * usage error, unlike `kici preview` which treats no-event as help.
11
- */
12
- export declare function printRunLocalUsage(): void;
13
3
  /**
14
4
  * Compile `--target` selector strings into a {@link HostTargetSelector}. Each
15
5
  * string becomes one AND value (its own include set); repeated values
@@ -42,13 +32,6 @@ export declare function buildDispatchInputs(pairs: string[], descriptor: InputsD
42
32
  * stderr regardless.
43
33
  */
44
34
  export declare function withStdoutOnStderr<T>(fn: () => Promise<T>): Promise<T>;
45
- /**
46
- * Run a workflow locally using the local executor.
47
- * Thin wrapper that delegates to executeLocal from local-executor.
48
- *
49
- * Exit codes: 0 = success, 1 = job failure, 2 = config/compilation error
50
- */
51
- export declare function runLocalCommand(options: RunLocalOptions): Promise<boolean>;
52
35
  /**
53
36
  * Run fixtures remotely, routed through the Platform.
54
37
  */
@@ -10,11 +10,11 @@ import { createOverlayTarball, getSizeWarning, uploadTarball } from "../remote/u
10
10
  import { formatJsonResult } from "../remote/output/json.js";
11
11
  import { formatJunitResult } from "../remote/output/junit.js";
12
12
  import { formatErrorHighlight, formatMultiFixtureSummary, formatSummary } from "../remote/output/summary.js";
13
- import { compileCommand } from "./compile.js";
14
13
  import { compileFixtures, filterFixtures } from "../fixtures/compiler.js";
15
14
  import { describeEvent } from "../fixtures/describe-event.js";
16
15
  import { FixturePickerCancelledError, runFixturePicker } from "../fixtures/picker.js";
17
16
  import { listHeldRunsForRun, resolveHeldRunContext } from "./held-run-client.js";
17
+ import { compileCommand } from "./compile.js";
18
18
  import { handleNewHolds } from "./run-hold-watch.js";
19
19
  import path from "node:path";
20
20
  import pc from "picocolors";
@@ -24,24 +24,6 @@ import { coerceDispatchInputs, parseInputPairs } from "@kici-dev/engine";
24
24
  import { normalizeRunsOnToMatchers } from "@kici-dev/engine/labels/compile";
25
25
  import { confirm } from "@inquirer/prompts";
26
26
  //#region src/commands/run.ts
27
- /**
28
- * Print a usage block for `kici run local` when the event argument is missing.
29
- *
30
- * Mirrors the discoverable help `kici preview` prints for a missing event: a
31
- * bold synopsis line, a one-line description, and a few concrete event
32
- * examples. The caller exits non-zero after printing — a missing event is a
33
- * usage error, unlike `kici preview` which treats no-event as help.
34
- */
35
- function printRunLocalUsage() {
36
- logger.info(pc.bold("\nUsage: kici run local <event> [options]\n"));
37
- logger.info(pc.gray("Execute workflows locally for a given event, without orchestrator infrastructure.\n"));
38
- logger.info(pc.gray("Examples:"));
39
- logger.info(pc.gray(" kici run local push"));
40
- logger.info(pc.gray(" kici run local pr:open"));
41
- logger.info(pc.gray(" kici run local schedule"));
42
- logger.info(pc.gray(" kici run local lifecycle:workflow_complete\n"));
43
- logger.info(pc.gray("Or pick a workflow interactively: kici run local --pick\n"));
44
- }
45
27
  /** Terminal run statuses returned by the Platform run-status snapshot. */
46
28
  const TERMINAL_STATUSES = /* @__PURE__ */ new Set([
47
29
  "success",
@@ -127,11 +109,11 @@ async function withStdoutOnStderr(fn) {
127
109
  }
128
110
  }
129
111
  /**
130
- * Recompile `.kici/workflows` → `kici.lock.json` before a remote run, mirroring
131
- * `kici run local`. The orchestrator matches triggers and dispatches against the
132
- * inline lock, so a stale lock would route an edited or newly-added workflow
133
- * incorrectly. Returns false on a compile/validation error so the caller can
134
- * abort before any upload or dispatch.
112
+ * Recompile `.kici/workflows` → `kici.lock.json` before a remote run. The
113
+ * orchestrator matches triggers and dispatches against the inline lock, so a
114
+ * stale lock would route an edited or newly-added workflow incorrectly. Returns
115
+ * false on a compile/validation error so the caller can abort before any upload
116
+ * or dispatch.
135
117
  */
136
118
  async function compileBeforeRemoteRun(options) {
137
119
  const pureStdout = Boolean(options.json || options.quiet);
@@ -144,31 +126,6 @@ async function compileBeforeRemoteRun(options) {
144
126
  return pureStdout ? withStdoutOnStderr(compile) : compile();
145
127
  }
146
128
  /**
147
- * Run a workflow locally using the local executor.
148
- * Thin wrapper that delegates to executeLocal from local-executor.
149
- *
150
- * Exit codes: 0 = success, 1 = job failure, 2 = config/compilation error
151
- */
152
- async function runLocalCommand(options) {
153
- if (options.debug) {
154
- process.env.KICI_DEBUG = "true";
155
- if (!options.quiet) logger.info(pc.gray("Debug mode enabled"));
156
- }
157
- try {
158
- const { executeLocal } = await import("../local-executor/index.js");
159
- return await executeLocal(options);
160
- } catch (error) {
161
- if (error instanceof Error && (error.message.includes("Cannot find module") || error.message.includes("ERR_MODULE_NOT_FOUND"))) {
162
- logger.error(pc.red("Local executor not yet available. The local execution engine is under development."));
163
- return false;
164
- }
165
- const message = toErrorMessage(error);
166
- logger.error(pc.red(`\nError: ${message}\n`));
167
- if (options.debug && error instanceof Error && error.stack) logger.error(pc.gray(error.stack));
168
- return false;
169
- }
170
- }
171
- /**
172
129
  * Run fixtures remotely, routed through the Platform.
173
130
  */
174
131
  async function runRemoteCommand(fixture, options) {
@@ -694,6 +651,6 @@ function displayRemoteResults(results) {
694
651
  logger.info("");
695
652
  }
696
653
  //#endregion
697
- export { buildDispatchInputs, buildTargetSelector, lookupDispatchInputsDescriptor, printRunLocalUsage, runLocalCommand, runRemoteCommand, withStdoutOnStderr };
654
+ export { buildDispatchInputs, buildTargetSelector, lookupDispatchInputsDescriptor, runRemoteCommand, withStdoutOnStderr };
698
655
 
699
656
  //# sourceMappingURL=run.js.map
@@ -5,8 +5,8 @@ export interface SecretsListOptions {
5
5
  /**
6
6
  * List test-available secret contexts through the Platform.
7
7
  *
8
- * Calls GET /api/v1/orgs/:orgId/environments?includeSecrets=true (relayed to
9
- * the org's orchestrator), filters to environments with
8
+ * Calls GET /api/v1/orgs/:orgId/contexts?includeSecrets=true (relayed to
9
+ * the org's orchestrator), filters to contexts with
10
10
  * allowLocalExecution=true, and displays a table of names, key names, and
11
11
  * flags. Values are never exposed -- only key names.
12
12
  */
@@ -6,17 +6,17 @@ import { toErrorMessage } from "@kici-dev/core";
6
6
  /**
7
7
  * List test-available secret contexts through the Platform.
8
8
  *
9
- * Calls GET /api/v1/orgs/:orgId/environments?includeSecrets=true (relayed to
10
- * the org's orchestrator), filters to environments with
9
+ * Calls GET /api/v1/orgs/:orgId/contexts?includeSecrets=true (relayed to
10
+ * the org's orchestrator), filters to contexts with
11
11
  * allowLocalExecution=true, and displays a table of names, key names, and
12
12
  * flags. Values are never exposed -- only key names.
13
13
  */
14
14
  async function secretsListCommand(_options = {}) {
15
15
  try {
16
- const contexts = (await (await DashboardClient.load()).listEnvironments(true)).filter((e) => e.allowLocalExecution);
16
+ const contexts = (await (await DashboardClient.load()).listContexts(true)).filter((e) => e.allowLocalExecution);
17
17
  if (contexts.length === 0) {
18
18
  console.log(pc.yellow("No test-available secret contexts found."));
19
- console.log(pc.gray("Enable test runs (allowLocalExecution) on an environment to make its secrets available for test runs."));
19
+ console.log(pc.gray("Enable test runs (allowLocalExecution) on a context to make its secrets available for test runs."));
20
20
  return true;
21
21
  }
22
22
  renderContextTable(contexts);
@@ -5,11 +5,11 @@ export interface TypesOptions {
5
5
  quiet?: boolean;
6
6
  }
7
7
  /**
8
- * Generate TypeScript declarations for environment secrets.
8
+ * Generate TypeScript declarations for context secrets.
9
9
  *
10
- * Fetches environment metadata (with secret key names) through the Platform
10
+ * Fetches context metadata (with secret key names) through the Platform
11
11
  * and generates .kici/types/secrets.d.ts with module augmentation for
12
- * KnownSecretKeys and EnvironmentSecrets.
12
+ * KnownSecretKeys and ContextSecrets.
13
13
  *
14
14
  * @param options - Command options
15
15
  * @returns true on success, false on error
@@ -8,11 +8,11 @@ import fs from "node:fs/promises";
8
8
  import { toErrorMessage } from "@kici-dev/core";
9
9
  //#region src/commands/types.ts
10
10
  /**
11
- * Generate TypeScript declarations for environment secrets.
11
+ * Generate TypeScript declarations for context secrets.
12
12
  *
13
- * Fetches environment metadata (with secret key names) through the Platform
13
+ * Fetches context metadata (with secret key names) through the Platform
14
14
  * and generates .kici/types/secrets.d.ts with module augmentation for
15
- * KnownSecretKeys and EnvironmentSecrets.
15
+ * KnownSecretKeys and ContextSecrets.
16
16
  *
17
17
  * @param options - Command options
18
18
  * @returns true on success, false on error
@@ -21,7 +21,7 @@ async function typesCommand(options = {}) {
21
21
  try {
22
22
  const config = await loadGlobalConfig();
23
23
  const dtsContent = generateSecretsDts({
24
- environments: (await DashboardClient.fromConfig(config).listEnvironments(true)).map((e) => ({
24
+ contexts: (await DashboardClient.fromConfig(config).listContexts(true)).map((e) => ({
25
25
  name: e.name,
26
26
  keys: e.secretKeys ?? []
27
27
  })),
@@ -5,7 +5,7 @@ import { ensureTsLoaderHook } from "./ts-loader.js";
5
5
  import { pathToFileURL } from "node:url";
6
6
  import path from "node:path";
7
7
  import { existsSync } from "node:fs";
8
- import fs from "node:fs/promises";
8
+ import fs$1 from "node:fs/promises";
9
9
  //#region src/execution/executor.ts
10
10
  /**
11
11
  * Load a TypeScript workflow/config module by direct dynamic import.
@@ -23,7 +23,7 @@ import fs from "node:fs/promises";
23
23
  async function loadModule(entryPoint, errorContext) {
24
24
  let hashBundleSource;
25
25
  try {
26
- hashBundleSource = await fs.readFile(entryPoint, "utf-8");
26
+ hashBundleSource = await fs$1.readFile(entryPoint, "utf-8");
27
27
  } catch {}
28
28
  try {
29
29
  ensureTsLoaderHook();
@@ -60,12 +60,12 @@ async function loadModule(entryPoint, errorContext) {
60
60
  async function executeConfig(configPath) {
61
61
  const absolutePath = path.resolve(configPath);
62
62
  try {
63
- await fs.access(absolutePath);
63
+ await fs$1.access(absolutePath);
64
64
  } catch {
65
65
  throw compilerError("E001", `Config file not found: ${absolutePath}`, { suggestion: "Ensure workflow files exist in .kici/workflows/" });
66
66
  }
67
67
  try {
68
- await fs.readFile(absolutePath, "utf-8");
68
+ await fs$1.readFile(absolutePath, "utf-8");
69
69
  } catch {
70
70
  throw compilerError("E001", `Failed to read config file: ${absolutePath}`, { suggestion: "Check file permissions" });
71
71
  }
@@ -180,14 +180,14 @@ async function discoverWorkflows(kiciDir) {
180
180
  const absoluteKiciDir = resolveKiciDir(kiciDir);
181
181
  const workflowDir = path.join(absoluteKiciDir, "workflows");
182
182
  try {
183
- if (!(await fs.stat(workflowDir)).isDirectory()) throw compilerError("E001", `.kici/workflows/ is not a directory: ${workflowDir}`, { suggestion: "Run \"kici init\" to create the .kici/workflows/ directory" });
183
+ if (!(await fs$1.stat(workflowDir)).isDirectory()) throw compilerError("E001", `.kici/workflows/ is not a directory: ${workflowDir}`, { suggestion: "Run \"kici init\" to create the .kici/workflows/ directory" });
184
184
  } catch (err) {
185
185
  if (err.code === "ENOENT") throw compilerError("E001", `.kici/workflows/ directory not found: ${workflowDir}`, { suggestion: "Run \"kici init\" to create the .kici/workflows/ directory" });
186
186
  throw err;
187
187
  }
188
188
  let files;
189
189
  try {
190
- files = (await fs.readdir(workflowDir, { withFileTypes: true })).filter((entry) => entry.isFile() && entry.name.endsWith(".ts")).map((entry) => path.join(workflowDir, entry.name));
190
+ files = (await fs$1.readdir(workflowDir, { withFileTypes: true })).filter((entry) => entry.isFile() && entry.name.endsWith(".ts")).map((entry) => path.join(workflowDir, entry.name));
191
191
  } catch {
192
192
  throw compilerError("E001", `Failed to read .kici/workflows/ directory: ${workflowDir}`, { suggestion: "Check directory permissions" });
193
193
  }
@@ -213,7 +213,7 @@ async function discoverWorkflows(kiciDir) {
213
213
  */
214
214
  async function executeWorkflowFile(filePath) {
215
215
  try {
216
- await fs.access(filePath);
216
+ await fs$1.access(filePath);
217
217
  } catch {
218
218
  throw compilerError("E001", `Failed to read workflow file: ${filePath}`, { suggestion: "Check file permissions" });
219
219
  }
@@ -1,27 +1,27 @@
1
1
  /**
2
- * .d.ts generator for environment secret type augmentation.
2
+ * .d.ts generator for context secret type augmentation.
3
3
  *
4
4
  * Produces a TypeScript declaration file that augments @kici-dev/sdk's
5
- * KnownSecretKeys and EnvironmentSecrets interfaces, enabling compile-time
5
+ * KnownSecretKeys and ContextSecrets interfaces, enabling compile-time
6
6
  * autocomplete and type checking for `ctx.secrets.get()` and `ctx.secrets.expose()`
7
- * key names per environment.
7
+ * key names per context.
8
8
  */
9
- export interface EnvironmentMetadata {
9
+ export interface ContextMetadata {
10
10
  name: string;
11
11
  keys: string[];
12
12
  }
13
13
  interface GenerateSecretsDtsOptions {
14
- environments: EnvironmentMetadata[];
14
+ contexts: ContextMetadata[];
15
15
  endpoint: string;
16
16
  generatedAt: Date;
17
17
  }
18
18
  /**
19
- * Generate a .d.ts string from environment metadata.
19
+ * Generate a .d.ts string from context metadata.
20
20
  *
21
- * The output augments @kici-dev/sdk's KnownSecretKeys and EnvironmentSecrets
22
- * interfaces, enabling compile-time autocomplete for secret keys per environment.
21
+ * The output augments @kici-dev/sdk's KnownSecretKeys and ContextSecrets
22
+ * interfaces, enabling compile-time autocomplete for secret keys per context.
23
23
  *
24
- * @param options - Environment metadata, endpoint URL, and generation timestamp
24
+ * @param options - Context metadata, endpoint URL, and generation timestamp
25
25
  * @returns The .d.ts file content as a string
26
26
  */
27
27
  export declare function generateSecretsDts(options: GenerateSecretsDtsOptions): string;
@@ -13,11 +13,11 @@ function formatProperty(name) {
13
13
  return isValidIdentifier(name) ? name : `'${escapeQuotes(name)}'`;
14
14
  }
15
15
  /**
16
- * Build a map of key -> list of environment names that provide it.
16
+ * Build a map of key -> list of context names that provide it.
17
17
  */
18
- function buildKeySourceMap(environments) {
18
+ function buildKeySourceMap(contexts) {
19
19
  const map = /* @__PURE__ */ new Map();
20
- for (const env of environments) for (const key of env.keys) {
20
+ for (const env of contexts) for (const key of env.keys) {
21
21
  const sources = map.get(key);
22
22
  if (sources) sources.push(env.name);
23
23
  else map.set(key, [env.name]);
@@ -25,16 +25,16 @@ function buildKeySourceMap(environments) {
25
25
  return map;
26
26
  }
27
27
  /**
28
- * Generate a .d.ts string from environment metadata.
28
+ * Generate a .d.ts string from context metadata.
29
29
  *
30
- * The output augments @kici-dev/sdk's KnownSecretKeys and EnvironmentSecrets
31
- * interfaces, enabling compile-time autocomplete for secret keys per environment.
30
+ * The output augments @kici-dev/sdk's KnownSecretKeys and ContextSecrets
31
+ * interfaces, enabling compile-time autocomplete for secret keys per context.
32
32
  *
33
- * @param options - Environment metadata, endpoint URL, and generation timestamp
33
+ * @param options - Context metadata, endpoint URL, and generation timestamp
34
34
  * @returns The .d.ts file content as a string
35
35
  */
36
36
  function generateSecretsDts(options) {
37
- const { environments, endpoint, generatedAt } = options;
37
+ const { contexts, endpoint, generatedAt } = options;
38
38
  const lines = [];
39
39
  lines.push("// @generated by kici types -- DO NOT EDIT");
40
40
  lines.push(`// Source: ${endpoint}`);
@@ -42,16 +42,16 @@ function generateSecretsDts(options) {
42
42
  lines.push("// Run `kici types` to refresh");
43
43
  lines.push("");
44
44
  lines.push("declare module '@kici-dev/sdk' {");
45
- const keySourceMap = buildKeySourceMap(environments);
45
+ const keySourceMap = buildKeySourceMap(contexts);
46
46
  lines.push(" interface KnownSecretKeys {");
47
47
  for (const [key, sources] of keySourceMap) {
48
- lines.push(` /** From environment: ${sources.join(", ")} */`);
48
+ lines.push(` /** From context: ${sources.join(", ")} */`);
49
49
  lines.push(` ${formatProperty(key)}: string;`);
50
50
  }
51
51
  lines.push(" }");
52
52
  lines.push("");
53
- lines.push(" interface EnvironmentSecrets {");
54
- for (const env of environments) if (env.keys.length === 0) lines.push(` ${formatProperty(env.name)}: never;`);
53
+ lines.push(" interface ContextSecrets {");
54
+ for (const env of contexts) if (env.keys.length === 0) lines.push(` ${formatProperty(env.name)}: never;`);
55
55
  else {
56
56
  const keyUnion = env.keys.map((k) => `'${escapeQuotes(k)}'`).join(" | ");
57
57
  lines.push(` ${formatProperty(env.name)}: ${keyUnion};`);