@kici-dev/compiler 0.0.0 → 0.1.1

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 (221) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +1 -6
  3. package/dist/assets/api-TJJVHrjC.json +118 -0
  4. package/dist/assets/descriptor-BTtjzN9L.json +1382 -0
  5. package/dist/assets/package-BpQF9kR8.json +74 -0
  6. package/dist/assets/package-Ceo2h27X.json +89 -0
  7. package/dist/assets/source_context-D0atuL28.json +20 -0
  8. package/dist/assets/type-BFqO8SCZ.json +202 -0
  9. package/dist/auth/headless-detect.d.ts +14 -0
  10. package/dist/auth/headless-detect.js +25 -0
  11. package/dist/chunk-gOLHoazu.js +4 -0
  12. package/dist/cli.d.ts +3 -0
  13. package/dist/cli.js +193 -0
  14. package/dist/commands/cancel.d.ts +22 -0
  15. package/dist/commands/cancel.js +124 -0
  16. package/dist/commands/compile.d.ts +17 -0
  17. package/dist/commands/compile.js +99 -0
  18. package/dist/commands/docs.d.ts +26 -0
  19. package/dist/commands/docs.js +60 -0
  20. package/dist/commands/drain-worker.d.ts +19 -0
  21. package/dist/commands/drain-worker.js +45 -0
  22. package/dist/commands/endpoints.d.ts +53 -0
  23. package/dist/commands/endpoints.js +185 -0
  24. package/dist/commands/fixture.d.ts +14 -0
  25. package/dist/commands/fixture.js +104 -0
  26. package/dist/commands/hook.d.ts +20 -0
  27. package/dist/commands/hook.js +97 -0
  28. package/dist/commands/index.d.ts +33 -0
  29. package/dist/commands/index.js +20 -0
  30. package/dist/commands/init.d.ts +35 -0
  31. package/dist/commands/init.js +393 -0
  32. package/dist/commands/login.d.ts +23 -0
  33. package/dist/commands/login.js +144 -0
  34. package/dist/commands/logout.d.ts +18 -0
  35. package/dist/commands/logout.js +55 -0
  36. package/dist/commands/org.d.ts +27 -0
  37. package/dist/commands/org.js +126 -0
  38. package/dist/commands/run.d.ts +21 -0
  39. package/dist/commands/run.js +562 -0
  40. package/dist/commands/secrets-list.d.ts +16 -0
  41. package/dist/commands/secrets-list.js +85 -0
  42. package/dist/commands/status.d.ts +30 -0
  43. package/dist/commands/status.js +210 -0
  44. package/dist/commands/test.d.ts +61 -0
  45. package/dist/commands/test.js +220 -0
  46. package/dist/commands/types.d.ts +18 -0
  47. package/dist/commands/types.js +74 -0
  48. package/dist/commands/watch.d.ts +14 -0
  49. package/dist/commands/watch.js +97 -0
  50. package/dist/commands/workflows.d.ts +28 -0
  51. package/dist/commands/workflows.js +154 -0
  52. package/dist/comment-created.json +30 -0
  53. package/dist/create-branch.json +17 -0
  54. package/dist/delete-branch.json +15 -0
  55. package/dist/dispatch.json +15 -0
  56. package/dist/errors/capability-gap.d.ts +50 -0
  57. package/dist/errors/capability-gap.js +54 -0
  58. package/dist/errors/codes.d.ts +25 -0
  59. package/dist/errors/formatter.d.ts +32 -0
  60. package/dist/errors/formatter.js +35 -0
  61. package/dist/errors/index.d.ts +5 -0
  62. package/dist/errors/index.js +4 -0
  63. package/dist/execution/executor.d.ts +61 -0
  64. package/dist/execution/executor.js +230 -0
  65. package/dist/execution/index.d.ts +4 -0
  66. package/dist/execution/index.js +3 -0
  67. package/dist/execution/sdk-alias.d.ts +33 -0
  68. package/dist/execution/sdk-alias.js +102 -0
  69. package/dist/fixtures/compiler.d.ts +47 -0
  70. package/dist/fixtures/compiler.js +177 -0
  71. package/dist/fixtures/defaults/comment-created.json +30 -0
  72. package/dist/fixtures/defaults/create-branch.json +17 -0
  73. package/dist/fixtures/defaults/delete-branch.json +15 -0
  74. package/dist/fixtures/defaults/dispatch.json +15 -0
  75. package/dist/fixtures/defaults/fork.json +19 -0
  76. package/dist/fixtures/defaults/index.d.ts +16 -0
  77. package/dist/fixtures/defaults/index.js +105 -0
  78. package/dist/fixtures/defaults/index.ts +145 -0
  79. package/dist/fixtures/defaults/pr-closed.json +28 -0
  80. package/dist/fixtures/defaults/pr-opened.json +27 -0
  81. package/dist/fixtures/defaults/pr-reopened.json +27 -0
  82. package/dist/fixtures/defaults/pr-synchronize.json +27 -0
  83. package/dist/fixtures/defaults/push.json +16 -0
  84. package/dist/fixtures/defaults/release-published.json +23 -0
  85. package/dist/fixtures/defaults/review-comment-created.json +36 -0
  86. package/dist/fixtures/defaults/review-submitted.json +35 -0
  87. package/dist/fixtures/defaults/star-created.json +15 -0
  88. package/dist/fixtures/defaults/status.json +26 -0
  89. package/dist/fixtures/defaults/tag-push.json +20 -0
  90. package/dist/fixtures/defaults/watch-started.json +15 -0
  91. package/dist/fixtures/defaults/workflow-run-completed.json +23 -0
  92. package/dist/fork.json +19 -0
  93. package/dist/format.d.ts +5 -0
  94. package/dist/format.js +20 -0
  95. package/dist/generators/secrets-dts.d.ts +29 -0
  96. package/dist/generators/secrets-dts.js +67 -0
  97. package/dist/hooks/detector.d.ts +39 -0
  98. package/dist/hooks/detector.js +133 -0
  99. package/dist/hooks/index.d.ts +6 -0
  100. package/dist/hooks/index.js +5 -0
  101. package/dist/hooks/installer.d.ts +24 -0
  102. package/dist/hooks/installer.js +328 -0
  103. package/dist/hooks/templates.d.ts +26 -0
  104. package/dist/hooks/templates.js +63 -0
  105. package/dist/index.d.ts +12 -0
  106. package/dist/index.js +12 -0
  107. package/dist/llm-context/llms-full.txt +9974 -0
  108. package/dist/llm-context/llms.txt +61 -0
  109. package/dist/local-executor/dag-scheduler.d.ts +44 -0
  110. package/dist/local-executor/dag-scheduler.js +183 -0
  111. package/dist/local-executor/index.d.ts +23 -0
  112. package/dist/local-executor/index.js +309 -0
  113. package/dist/local-executor/job-runner.d.ts +40 -0
  114. package/dist/local-executor/job-runner.js +307 -0
  115. package/dist/local-executor/output-streamer.d.ts +31 -0
  116. package/dist/local-executor/output-streamer.js +166 -0
  117. package/dist/local-executor/payload-generator.d.ts +16 -0
  118. package/dist/local-executor/payload-generator.js +138 -0
  119. package/dist/local-executor/picker.d.ts +33 -0
  120. package/dist/local-executor/picker.js +109 -0
  121. package/dist/local-executor/secret-loader.d.ts +18 -0
  122. package/dist/local-executor/secret-loader.js +105 -0
  123. package/dist/local-executor/types.d.ts +80 -0
  124. package/dist/local-executor/types.js +2 -0
  125. package/dist/local-executor/workflow-lock.d.ts +81 -0
  126. package/dist/local-executor/workflow-lock.js +0 -0
  127. package/dist/lockfile/generator.d.ts +39 -0
  128. package/dist/lockfile/generator.js +688 -0
  129. package/dist/lockfile/hash-files.d.ts +14 -0
  130. package/dist/lockfile/hash-files.js +50 -0
  131. package/dist/lockfile/hasher.d.ts +36 -0
  132. package/dist/lockfile/hasher.js +46 -0
  133. package/dist/lockfile/index.d.ts +3 -0
  134. package/dist/lockfile/index.js +4 -0
  135. package/dist/lockfile/purity-analyzer.d.ts +25 -0
  136. package/dist/lockfile/purity-analyzer.js +204 -0
  137. package/dist/package-F7UXSDHW.json +74 -0
  138. package/dist/postinstall.d.ts +9 -0
  139. package/dist/postinstall.js +60 -0
  140. package/dist/pr-closed.json +28 -0
  141. package/dist/pr-opened.json +27 -0
  142. package/dist/pr-reopened.json +27 -0
  143. package/dist/pr-synchronize.json +27 -0
  144. package/dist/push.json +16 -0
  145. package/dist/release-published.json +23 -0
  146. package/dist/remote/client.d.ts +204 -0
  147. package/dist/remote/client.js +203 -0
  148. package/dist/remote/config.d.ts +54 -0
  149. package/dist/remote/config.js +92 -0
  150. package/dist/remote/encryption.d.ts +35 -0
  151. package/dist/remote/encryption.js +87 -0
  152. package/dist/remote/history.d.ts +91 -0
  153. package/dist/remote/history.js +146 -0
  154. package/dist/remote/oauth.d.ts +65 -0
  155. package/dist/remote/oauth.js +302 -0
  156. package/dist/remote/observer.d.ts +81 -0
  157. package/dist/remote/observer.js +174 -0
  158. package/dist/remote/output/json.d.ts +13 -0
  159. package/dist/remote/output/json.js +36 -0
  160. package/dist/remote/output/junit.d.ts +18 -0
  161. package/dist/remote/output/junit.js +50 -0
  162. package/dist/remote/output/streaming.d.ts +57 -0
  163. package/dist/remote/output/streaming.js +124 -0
  164. package/dist/remote/output/summary.d.ts +39 -0
  165. package/dist/remote/output/summary.js +99 -0
  166. package/dist/remote/uploader.d.ts +87 -0
  167. package/dist/remote/uploader.js +197 -0
  168. package/dist/review-comment-created.json +36 -0
  169. package/dist/review-submitted.json +35 -0
  170. package/dist/star-created.json +15 -0
  171. package/dist/status.json +26 -0
  172. package/dist/tag-push.json +20 -0
  173. package/dist/templates/agents-md.d.ts +8 -0
  174. package/dist/templates/agents-md.js +130 -0
  175. package/dist/templates/index.d.ts +43 -0
  176. package/dist/templates/index.js +48 -0
  177. package/dist/templates/package-json.d.ts +18 -0
  178. package/dist/templates/package-json.js +34 -0
  179. package/dist/templates/tsconfig-json.d.ts +9 -0
  180. package/dist/templates/tsconfig-json.js +26 -0
  181. package/dist/templates/workflows/hello-world.d.ts +2 -0
  182. package/dist/templates/workflows/hello-world.js +16 -0
  183. package/dist/templates/workflows/hello-world.ts +21 -0
  184. package/dist/templates/workflows/pr-checks.d.ts +2 -0
  185. package/dist/templates/workflows/pr-checks.js +40 -0
  186. package/dist/templates/workflows/pr-checks.ts +57 -0
  187. package/dist/test-runner/dry-run.d.ts +12 -0
  188. package/dist/test-runner/dry-run.js +66 -0
  189. package/dist/test-runner/event-types.d.ts +86 -0
  190. package/dist/test-runner/event-types.js +330 -0
  191. package/dist/test-runner/git-detector.d.ts +15 -0
  192. package/dist/test-runner/git-detector.js +30 -0
  193. package/dist/test-runner/index.d.ts +13 -0
  194. package/dist/test-runner/index.js +11 -0
  195. package/dist/test-runner/job-executor.d.ts +48 -0
  196. package/dist/test-runner/job-executor.js +245 -0
  197. package/dist/test-runner/output-formatter.d.ts +47 -0
  198. package/dist/test-runner/output-formatter.js +92 -0
  199. package/dist/test-runner/payload-builder.d.ts +20 -0
  200. package/dist/test-runner/payload-builder.js +216 -0
  201. package/dist/test-runner/rule-evaluator.d.ts +14 -0
  202. package/dist/test-runner/rule-evaluator.js +31 -0
  203. package/dist/test-runner/secrets-file.d.ts +24 -0
  204. package/dist/test-runner/secrets-file.js +62 -0
  205. package/dist/test-runner/step-context.d.ts +15 -0
  206. package/dist/test-runner/step-context.js +140 -0
  207. package/dist/test-runner/summary.d.ts +7 -0
  208. package/dist/types.d.ts +525 -0
  209. package/dist/types.js +33 -0
  210. package/dist/validation/index.d.ts +3 -0
  211. package/dist/validation/index.js +3 -0
  212. package/dist/validation/validator.d.ts +26 -0
  213. package/dist/validation/validator.js +164 -0
  214. package/dist/watch-started.json +15 -0
  215. package/dist/workflow-run-completed.json +23 -0
  216. package/dist/workflows/hello-world.ts +21 -0
  217. package/dist/workflows/pr-checks.ts +57 -0
  218. package/hack/postinstall.mjs +105 -0
  219. package/package.json +61 -5
  220. package/sbom.spdx.json +10997 -0
  221. package/index.js +0 -3
@@ -0,0 +1,109 @@
1
+ import "../chunk-gOLHoazu.js";
2
+ import { transformTriggers } from "../lockfile/generator.js";
3
+ import { parseEventArg, triggerSummary, triggerToEventArg } from "../test-runner/event-types.js";
4
+ import pc from "picocolors";
5
+ import { logger } from "@kici-dev/shared";
6
+ import { select } from "@inquirer/prompts";
7
+ //#region src/local-executor/picker.ts
8
+ /**
9
+ * Interactive workflow picker for `kici run local --pick`.
10
+ *
11
+ * Lists every workflow with a summary of its triggers, lets the user pick one
12
+ * (and a specific trigger when there are multiple), and returns the derived
13
+ * event arg plus workflow name. The caller feeds these back into the standard
14
+ * executeLocal pipeline so the run remains consistent with normal trigger
15
+ * matching.
16
+ */
17
+ var PickerCancelledError = class extends Error {
18
+ constructor(message) {
19
+ super(message);
20
+ this.name = "PickerCancelledError";
21
+ }
22
+ };
23
+ function workflowEntries(workflows) {
24
+ return workflows.map((w) => ({
25
+ name: w.name,
26
+ triggers: transformTriggers(w.on)
27
+ }));
28
+ }
29
+ function eventFamily(arg) {
30
+ return arg.toLowerCase().split(":")[0] ?? "";
31
+ }
32
+ function filterFamily(arg) {
33
+ try {
34
+ const parsed = parseEventArg(arg);
35
+ if (parsed.type === "pull_request") return "pr";
36
+ return parsed.type;
37
+ } catch {
38
+ return eventFamily(arg);
39
+ }
40
+ }
41
+ function triggerFamilies(trigger) {
42
+ const head = eventFamily(triggerToEventArg(trigger));
43
+ if (trigger._type === "generic_webhook") return ["webhook", "generic_webhook"];
44
+ if (trigger._type === "workflow_complete") return [head, "lifecycle"];
45
+ if (trigger._type === "job_complete") return [head, "lifecycle"];
46
+ return [head];
47
+ }
48
+ function isStdinTty() {
49
+ return Boolean(process.stdin.isTTY);
50
+ }
51
+ function printWorkflowList(entries) {
52
+ logger.info(pc.bold("Available workflows:"));
53
+ for (const entry of entries) {
54
+ const summaries = entry.triggers.map(triggerSummary).join(", ") || "(no triggers)";
55
+ logger.info(` ${pc.cyan(entry.name)} — ${summaries}`);
56
+ }
57
+ }
58
+ /**
59
+ * Run the interactive picker.
60
+ *
61
+ * @throws PickerCancelledError when stdin is not a TTY, when no eligible
62
+ * workflows exist, or when the user aborts one of the prompts.
63
+ */
64
+ async function runPicker(workflows, opts = {}) {
65
+ let entries = workflowEntries(workflows).filter((e) => e.triggers.length > 0);
66
+ if (opts.filterEvent) {
67
+ const family = filterFamily(opts.filterEvent);
68
+ entries = entries.filter((e) => e.triggers.some((t) => triggerFamilies(t).includes(family)));
69
+ }
70
+ if (entries.length === 0) throw new PickerCancelledError(opts.filterEvent ? `No workflows with triggers matching "${opts.filterEvent}". Remove the event arg or pass a different one.` : "No workflows with triggers available to pick.");
71
+ if (!isStdinTty()) {
72
+ printWorkflowList(entries);
73
+ throw new PickerCancelledError("Non-interactive environment: --pick requires a TTY. Pass --workflow <name> plus an event arg instead.");
74
+ }
75
+ let chosenWorkflow;
76
+ try {
77
+ const name = await select({
78
+ message: "Select a workflow to run",
79
+ choices: entries.map((e) => ({
80
+ name: `${e.name} — ${e.triggers.map(triggerSummary).join(", ")}`,
81
+ value: e.name
82
+ }))
83
+ });
84
+ chosenWorkflow = entries.find((e) => e.name === name);
85
+ } catch (err) {
86
+ throw new PickerCancelledError(`Picker cancelled: ${err instanceof Error ? err.message : String(err)}`);
87
+ }
88
+ let trigger;
89
+ if (chosenWorkflow.triggers.length === 1) trigger = chosenWorkflow.triggers[0];
90
+ else try {
91
+ trigger = await select({
92
+ message: `Select a trigger for "${chosenWorkflow.name}"`,
93
+ choices: chosenWorkflow.triggers.map((t) => ({
94
+ name: triggerSummary(t),
95
+ value: t
96
+ }))
97
+ });
98
+ } catch (err) {
99
+ throw new PickerCancelledError(`Picker cancelled: ${err instanceof Error ? err.message : String(err)}`);
100
+ }
101
+ return {
102
+ event: triggerToEventArg(trigger),
103
+ workflow: chosenWorkflow.name
104
+ };
105
+ }
106
+ //#endregion
107
+ export { PickerCancelledError, runPicker };
108
+
109
+ //# sourceMappingURL=picker.js.map
@@ -0,0 +1,18 @@
1
+ import type { ParsedSecrets } from '../test-runner/secrets-file.js';
2
+ /**
3
+ * Load secrets from multiple sources with merge precedence.
4
+ *
5
+ * Merge order (lowest to highest priority):
6
+ * 1. .kici/.secrets (INI-style, backward compat)
7
+ * 2. .kici/.env.local (dotenv format)
8
+ * 3. .kici/secrets.yaml (YAML with environment scopes, merged flat)
9
+ * 4. --env KEY=VALUE CLI flags
10
+ *
11
+ * Note: process.env is NOT merged here -- it's handled at step-context level.
12
+ *
13
+ * @param kiciDir - Path to the .kici directory
14
+ * @param envFlags - Optional --env KEY=VALUE flag values
15
+ * @returns Merged secrets with correct precedence
16
+ */
17
+ export declare function loadLocalSecrets(kiciDir: string, envFlags?: string[]): Promise<ParsedSecrets>;
18
+ //# sourceMappingURL=secret-loader.d.ts.map
@@ -0,0 +1,105 @@
1
+ import "../chunk-gOLHoazu.js";
2
+ import { loadSecretsFile } from "../test-runner/secrets-file.js";
3
+ import { readFile } from "node:fs/promises";
4
+ import path from "node:path";
5
+ import { parse } from "yaml";
6
+ //#region src/local-executor/secret-loader.ts
7
+ /**
8
+ * Parse a dotenv-style file (.env.local) into flat key-value pairs.
9
+ * Lines starting with # are comments. Blank lines are ignored.
10
+ */
11
+ function parseDotenv(content) {
12
+ const result = {};
13
+ for (const rawLine of content.split("\n")) {
14
+ const line = rawLine.trim();
15
+ if (line === "" || line.startsWith("#")) continue;
16
+ const eqIndex = line.indexOf("=");
17
+ if (eqIndex === -1) continue;
18
+ const key = line.slice(0, eqIndex).trim();
19
+ let value = line.slice(eqIndex + 1).trim();
20
+ if (value.length >= 2 && (value[0] === "\"" && value[value.length - 1] === "\"" || value[0] === "'" && value[value.length - 1] === "'")) value = value.slice(1, -1);
21
+ result[key] = value;
22
+ }
23
+ return result;
24
+ }
25
+ /**
26
+ * Parse a secrets.yaml file.
27
+ * Expected format: top-level keys are environment names, values are key-value maps.
28
+ * For local execution, all environments are merged flat (no environment resolution).
29
+ */
30
+ function parseSecretsYaml(content) {
31
+ const parsed = parse(content);
32
+ if (!parsed || typeof parsed !== "object") return {};
33
+ const result = {};
34
+ for (const [, envSecrets] of Object.entries(parsed)) if (envSecrets && typeof envSecrets === "object" && !Array.isArray(envSecrets)) {
35
+ for (const [key, value] of Object.entries(envSecrets)) if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") result[key] = String(value);
36
+ }
37
+ return result;
38
+ }
39
+ /**
40
+ * Parse --env KEY=VALUE flags into a flat map.
41
+ */
42
+ function parseEnvFlags(flags) {
43
+ const result = {};
44
+ for (const flag of flags) {
45
+ const eqIndex = flag.indexOf("=");
46
+ if (eqIndex === -1) continue;
47
+ const key = flag.slice(0, eqIndex).trim();
48
+ result[key] = flag.slice(eqIndex + 1);
49
+ }
50
+ return result;
51
+ }
52
+ /**
53
+ * Read a file, returning null if it doesn't exist.
54
+ */
55
+ async function readFileOrNull(filePath) {
56
+ try {
57
+ return await readFile(filePath, "utf-8");
58
+ } catch (err) {
59
+ if (err instanceof Error && "code" in err && err.code === "ENOENT") return null;
60
+ throw err;
61
+ }
62
+ }
63
+ /**
64
+ * Load secrets from multiple sources with merge precedence.
65
+ *
66
+ * Merge order (lowest to highest priority):
67
+ * 1. .kici/.secrets (INI-style, backward compat)
68
+ * 2. .kici/.env.local (dotenv format)
69
+ * 3. .kici/secrets.yaml (YAML with environment scopes, merged flat)
70
+ * 4. --env KEY=VALUE CLI flags
71
+ *
72
+ * Note: process.env is NOT merged here -- it's handled at step-context level.
73
+ *
74
+ * @param kiciDir - Path to the .kici directory
75
+ * @param envFlags - Optional --env KEY=VALUE flag values
76
+ * @returns Merged secrets with correct precedence
77
+ */
78
+ async function loadLocalSecrets(kiciDir, envFlags) {
79
+ const iniSecrets = await loadSecretsFile(kiciDir);
80
+ const flat = { ...iniSecrets.flat };
81
+ const contexts = {};
82
+ for (const [ctx, vals] of Object.entries(iniSecrets.contexts)) contexts[ctx] = { ...vals };
83
+ const envLocalContent = await readFileOrNull(path.join(kiciDir, ".env.local"));
84
+ if (envLocalContent !== null) {
85
+ const envLocalSecrets = parseDotenv(envLocalContent);
86
+ Object.assign(flat, envLocalSecrets);
87
+ }
88
+ const yamlContent = await readFileOrNull(path.join(kiciDir, "secrets.yaml"));
89
+ if (yamlContent !== null) {
90
+ const yamlSecrets = parseSecretsYaml(yamlContent);
91
+ Object.assign(flat, yamlSecrets);
92
+ }
93
+ if (envFlags && envFlags.length > 0) {
94
+ const flagSecrets = parseEnvFlags(envFlags);
95
+ Object.assign(flat, flagSecrets);
96
+ }
97
+ return {
98
+ flat,
99
+ contexts
100
+ };
101
+ }
102
+ //#endregion
103
+ export { loadLocalSecrets };
104
+
105
+ //# sourceMappingURL=secret-loader.js.map
@@ -0,0 +1,80 @@
1
+ import type { MatrixValues, Job } from '@kici-dev/sdk';
2
+ import type { JobResult } from '../test-runner/job-executor.js';
3
+ /**
4
+ * All CLI flags for `kici run local`.
5
+ */
6
+ export interface RunLocalOptions {
7
+ /** Positional arg: event type (e.g. 'push', 'pr:open'). Optional when `pick` is true. */
8
+ event?: string;
9
+ /** --pick / -p: interactive workflow picker (derives event arg from the selected trigger) */
10
+ pick?: boolean;
11
+ /** --workflow filter: run only matching workflow */
12
+ workflow?: string;
13
+ /** --job filter: run only matching job (includes transitive deps) */
14
+ job?: string;
15
+ /** --branch override: override detected git branch */
16
+ branch?: string;
17
+ /** --sha override: override detected git SHA */
18
+ sha?: string;
19
+ /** --payload path: explicit event payload JSON file */
20
+ payload?: string;
21
+ /** --concurrency: max parallel jobs (default: os.availableParallelism()) */
22
+ concurrency?: number;
23
+ /** --keep-going: continue after job failure (default: false) */
24
+ keepGoing?: boolean;
25
+ /** --container: use Podman isolation (default: false) */
26
+ container?: boolean;
27
+ /** --env KEY=VALUE overrides (repeatable) */
28
+ env?: string[];
29
+ /** --quiet: minimal output */
30
+ quiet?: boolean;
31
+ /** --json: JSON output format */
32
+ json?: boolean;
33
+ /** --junit: path for JUnit XML report */
34
+ junit?: string;
35
+ /** --files: override changed file paths (repeatable) */
36
+ files?: string[];
37
+ /** --debug: verbose debug output */
38
+ debug?: boolean;
39
+ /** --kici-dir: path to .kici directory */
40
+ kiciDir?: string;
41
+ }
42
+ /**
43
+ * A job after matrix expansion with resolved values.
44
+ */
45
+ export interface ResolvedJob {
46
+ /** Original job definition */
47
+ job: Job;
48
+ /** Expanded name (e.g. 'test (node-18, linux)') */
49
+ expandedName: string;
50
+ /** Matrix values for this expansion (empty object if no matrix) */
51
+ matrixValues: MatrixValues;
52
+ /** Resolved dependency names (expanded names of upstream jobs) */
53
+ resolvedNeeds: string[];
54
+ }
55
+ /**
56
+ * Result for a single job execution in local mode.
57
+ * Extends JobResult with matrix context and cancellation.
58
+ */
59
+ export interface LocalJobResult extends Omit<JobResult, 'status'> {
60
+ /** Job completion status (adds 'cancelled' to base JobResult statuses) */
61
+ status: 'success' | 'failure' | 'skipped' | 'cancelled';
62
+ /** Matrix values if this job was part of a matrix expansion */
63
+ matrixValues?: MatrixValues;
64
+ /** Whether this job was cancelled (e.g. by AbortSignal) */
65
+ cancelled?: boolean;
66
+ }
67
+ /**
68
+ * Result of executing a workflow locally.
69
+ */
70
+ export interface WorkflowExecutionResult {
71
+ /** Workflow name */
72
+ name: string;
73
+ /** Overall status */
74
+ status: 'success' | 'failure' | 'skipped';
75
+ /** Individual job results */
76
+ jobs: LocalJobResult[];
77
+ /** Total execution duration in milliseconds */
78
+ durationMs: number;
79
+ }
80
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,2 @@
1
+ import "../chunk-gOLHoazu.js";
2
+ export {};
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Workflow-level concurrency lock for `kici run local`.
3
+ *
4
+ * Enforces the SDK-declared `workflow.concurrency` block across concurrent
5
+ * `kici run local` invocations on the same machine and user. Mirrors the
6
+ * orchestrator semantics:
7
+ *
8
+ * - `group` callback evaluated against the simulated event, fails closed
9
+ * on throw via {@link ConcurrencyKeyEvaluationError} (the caller aborts the
10
+ * run rather than fall back to the workflow name).
11
+ * - `cancelInProgress: true` interrupts the holder via SIGTERM, escalates
12
+ * to SIGKILL after `KICI_LOCAL_LOCK_KILL_GRACE_MS` (default 30000ms).
13
+ * - Otherwise contention waits in FIFO order on the underlying file lock.
14
+ * - Stale locks (holder PID gone per `process.kill(pid, 0)`) are reclaimed.
15
+ *
16
+ * The lock primitive is `proper-lockfile` (atomic `mkdir` of a `.lock`
17
+ * directory next to the metadata sidecar). The lock identity is
18
+ * `sha256(workflowName + '\0' + groupKey)`, scoped to a per-user lock dir
19
+ * (`$XDG_RUNTIME_DIR/kici-local-locks/` on Linux, else
20
+ * `os.tmpdir()/kici-local-locks-<uid>/`).
21
+ */
22
+ import type { Workflow } from '@kici-dev/sdk';
23
+ /** Sidecar metadata persisted next to the lock dir for diagnostics + reclamation. */
24
+ export interface LockHolderMetadata {
25
+ pid: number;
26
+ startedAt: string;
27
+ workflowName: string;
28
+ groupKey: string;
29
+ hostname: string;
30
+ }
31
+ /** Handle returned by {@link acquireWorkflowLock}. Caller MUST invoke `release()` in a `finally`. */
32
+ export interface WorkflowLockHandle {
33
+ release(): Promise<void>;
34
+ }
35
+ export interface AcquireWorkflowLockOptions {
36
+ workflowName: string;
37
+ workflow: Workflow;
38
+ /** The simulated-event payload object passed as `groupCtx.event` to the user's group fn. */
39
+ event: Record<string, unknown>;
40
+ /** Branch derived from the simulated event for `groupCtx.branch`. */
41
+ branch: string;
42
+ debug?: boolean;
43
+ }
44
+ /**
45
+ * Thrown when the workflow's `concurrency.group()` function throws or rejects.
46
+ * The caller surfaces this as a workflow failure (it does NOT fall back to the
47
+ * workflow name as a key — fail-closed is the documented contract).
48
+ */
49
+ export declare class ConcurrencyKeyEvaluationError extends Error {
50
+ readonly cause?: Error;
51
+ readonly workflowName: string;
52
+ constructor(workflowName: string, cause: unknown);
53
+ }
54
+ /** Module-level stub for `process.kill`, swappable by tests via {@link __setKillFnForTesting}. */
55
+ type KillFn = (pid: number, signal?: string | number) => boolean;
56
+ /** Test-only: swap the kill function so unit tests don't actually signal real PIDs. */
57
+ export declare function __setKillFnForTesting(fn?: KillFn): void;
58
+ /**
59
+ * Resolve the per-user lock directory. Prefers `$XDG_RUNTIME_DIR/kici-local-locks/`
60
+ * (Linux per-user runtime dir, mode 0700), else `os.tmpdir()/kici-local-locks-<uid>/`.
61
+ *
62
+ * Created with `mode: 0o700`. Falls through silently to the tmpdir form on EACCES/EROFS.
63
+ */
64
+ export declare function resolveLockDir(): Promise<string>;
65
+ /**
66
+ * Evaluate the workflow's concurrency `group` function against the simulated event.
67
+ *
68
+ * Returns `null` when the workflow has no `concurrency` block. Throws
69
+ * {@link ConcurrencyKeyEvaluationError} when the group function throws or rejects.
70
+ */
71
+ export declare function resolveConcurrencyKey(workflow: Workflow, event: Record<string, unknown>, branch: string): Promise<string | null>;
72
+ /**
73
+ * Acquire the workflow-level concurrency lock for a `kici run local` invocation.
74
+ *
75
+ * Returns `null` immediately when the workflow has no `concurrency` block (no
76
+ * locking is performed). Otherwise blocks until the lock is held, then returns
77
+ * a handle whose `release()` MUST be invoked in a `finally`.
78
+ */
79
+ export declare function acquireWorkflowLock(opts: AcquireWorkflowLockOptions): Promise<WorkflowLockHandle | null>;
80
+ export {};
81
+ //# sourceMappingURL=workflow-lock.d.ts.map
@@ -0,0 +1,39 @@
1
+ import type { TriggerConfig } from '@kici-dev/sdk';
2
+ import { type LockFile, type LockTrigger, type WorkflowWithSource } from '../types.js';
3
+ /**
4
+ * Detect git repository root by running `git rev-parse --show-toplevel`.
5
+ * Falls back to cwd if not in a git repo.
6
+ *
7
+ * @returns Absolute path to git root, or cwd if not in git repo
8
+ */
9
+ export declare function detectGitRoot(): string;
10
+ /**
11
+ * Compute SHA-256 hash of the .kici/package-lock.json lockfile.
12
+ * Used as part of the dependency cache key.
13
+ *
14
+ * @param gitRoot - Absolute path to git repository root
15
+ * @returns Hex SHA-256 hash string, or null if no lockfile found in .kici/
16
+ */
17
+ export declare function computeLockfileHash(gitRoot: string): string | null;
18
+ /**
19
+ * Generate a lock file from validated workflows with source tracking.
20
+ *
21
+ * @param workflowsWithSource - Validated workflows with source info
22
+ * @returns Lock file ready for JSON serialization
23
+ */
24
+ export declare function generateLockFile(workflowsWithSource: WorkflowWithSource[]): LockFile;
25
+ /**
26
+ * Transform trigger configs to lock file format.
27
+ * Uses flatMap because push triggers with tags generate two lock triggers.
28
+ * Exported for reuse in the test runner's in-memory lock format conversion.
29
+ */
30
+ export declare function transformTriggers(triggers?: TriggerConfig[]): readonly LockTrigger[];
31
+ /**
32
+ * Serialize lock file to JSON string.
33
+ *
34
+ * @param lockFile - Lock file object
35
+ * @param pretty - Whether to pretty-print (default: true)
36
+ * @returns JSON string
37
+ */
38
+ export declare function serializeLockFile(lockFile: LockFile, pretty?: boolean): string;
39
+ //# sourceMappingURL=generator.d.ts.map