@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,230 @@
1
+ import "../chunk-gOLHoazu.js";
2
+ import { compilerError } from "../errors/formatter.js";
3
+ import "../errors/index.js";
4
+ import { existsSync } from "node:fs";
5
+ import fs from "node:fs/promises";
6
+ import path from "node:path";
7
+ import { pathToFileURL } from "node:url";
8
+ //#region src/execution/executor.ts
9
+ /**
10
+ * Load a TypeScript workflow/config module by direct dynamic import.
11
+ *
12
+ * Relies on the shared `@kici-dev/shared/ts-loader-hook` ESM loader hook
13
+ * registered by `packages/kici/bin/kici.js` (the same hook the agent registers
14
+ * in its sandbox process). No Rolldown bundling: host-repo imports and
15
+ * transitive deps with dynamic import() resolve via Node's normal ESM loader
16
+ * against the workspace's node_modules — the same module graph any other
17
+ * `npx tsx` invocation would see. This keeps ops-style workflows (which
18
+ * import repo-local modules like scripts/lib/*) working the same as minimal
19
+ * workflows that only touch @kici-dev/sdk.
20
+ */
21
+ async function loadModule(entryPoint, errorContext) {
22
+ let hashBundleSource;
23
+ try {
24
+ hashBundleSource = await fs.readFile(entryPoint, "utf-8");
25
+ } catch {}
26
+ try {
27
+ return {
28
+ module: await import(pathToFileURL(entryPoint).href + `?t=${Date.now()}`),
29
+ hashBundleSource
30
+ };
31
+ } catch (err) {
32
+ const message = err.message ?? "Failed to load module";
33
+ throw compilerError("E003", `Failed to load ${errorContext.fileLabel} module: ${message}`, {
34
+ location: {
35
+ file: errorContext.filePath,
36
+ line: 1,
37
+ column: 1
38
+ },
39
+ suggestion: `Check for TypeScript or runtime errors in your ${errorContext.fileLabel}. Make sure you invoke the workflow via the kici CLI (the bin shim registers the oxc-transform loader hook that handles TS files).`
40
+ });
41
+ }
42
+ }
43
+ /**
44
+ * Execute a TypeScript config file and extract workflow definitions.
45
+ *
46
+ * Process:
47
+ * 1. Read TypeScript source from disk
48
+ * 2. Transform to ESM JavaScript via rolldown (in-memory)
49
+ * 3. Write temp file for Node.js dynamic import (required by ESM spec)
50
+ * 4. Dynamic import the compiled module
51
+ * 5. Extract and return workflow definitions
52
+ * 6. Clean up temp file
53
+ *
54
+ * @param configPath - Path to workflow file (relative or absolute)
55
+ * @returns Workflows exported from the config
56
+ * @throws CompilerError on file not found, TypeScript errors, or missing exports
57
+ */
58
+ async function executeConfig(configPath) {
59
+ const absolutePath = path.resolve(configPath);
60
+ try {
61
+ await fs.access(absolutePath);
62
+ } catch {
63
+ throw compilerError("E001", `Config file not found: ${absolutePath}`, { suggestion: "Ensure workflow files exist in .kici/workflows/" });
64
+ }
65
+ try {
66
+ await fs.readFile(absolutePath, "utf-8");
67
+ } catch {
68
+ throw compilerError("E001", `Failed to read config file: ${absolutePath}`, { suggestion: "Check file permissions" });
69
+ }
70
+ const { module, hashBundleSource } = await loadModule(absolutePath, {
71
+ fileLabel: "config file",
72
+ filePath: absolutePath
73
+ });
74
+ return {
75
+ workflows: extractWorkflows(module, absolutePath, hashBundleSource),
76
+ configPath: absolutePath
77
+ };
78
+ }
79
+ /**
80
+ * Extract workflow definitions from a module's exports with source tracking.
81
+ *
82
+ * Supports:
83
+ * - Default export: single workflow or array of workflows
84
+ * - Named exports: any export that is a Workflow object
85
+ *
86
+ * @param module - The imported module
87
+ * @param filePath - Absolute path to the source file
88
+ * @returns Array of WorkflowWithSource objects
89
+ */
90
+ function extractWorkflows(module, filePath, bundleSource) {
91
+ const workflows = [];
92
+ if (module.default) {
93
+ const defaultExport = module.default;
94
+ if (isWorkflow(defaultExport)) workflows.push({
95
+ workflow: defaultExport,
96
+ source: {
97
+ file: filePath,
98
+ exportName: "default"
99
+ },
100
+ bundleSource
101
+ });
102
+ else if (Array.isArray(defaultExport)) defaultExport.forEach((item, index) => {
103
+ if (isWorkflow(item)) workflows.push({
104
+ workflow: item,
105
+ source: {
106
+ file: filePath,
107
+ exportName: "default",
108
+ arrayIndex: index
109
+ },
110
+ bundleSource
111
+ });
112
+ });
113
+ }
114
+ for (const [key, value] of Object.entries(module)) {
115
+ if (key === "default") continue;
116
+ if (isWorkflow(value)) workflows.push({
117
+ workflow: value,
118
+ source: {
119
+ file: filePath,
120
+ exportName: key
121
+ },
122
+ bundleSource
123
+ });
124
+ }
125
+ if (workflows.length === 0) throw compilerError("E004", "Config does not export any workflows", {
126
+ location: {
127
+ file: filePath,
128
+ line: 1,
129
+ column: 1
130
+ },
131
+ suggestion: "Export a workflow using: export default workflow(\"name\", { ... }) or export const myWorkflow = workflow(...)"
132
+ });
133
+ return workflows;
134
+ }
135
+ /**
136
+ * Type guard to check if a value is a Workflow object.
137
+ * Uses _tag discriminant from SDK.
138
+ */
139
+ function isWorkflow(value) {
140
+ return typeof value === "object" && value !== null && "_tag" in value && value._tag === "Workflow";
141
+ }
142
+ /**
143
+ * Resolve the .kici directory path, handling the case where the user
144
+ * is already inside the .kici directory (or a subdirectory of it).
145
+ *
146
+ * Resolution order:
147
+ * 1. If the resolved path has a workflows/ subdirectory, use it directly
148
+ * 2. If CWD itself is named .kici and has workflows/, use CWD
149
+ * 3. Fall through to the original resolved path (downstream code will error)
150
+ *
151
+ * @param kiciDir - Path to .kici directory (defaults to '.kici')
152
+ * @returns Absolute path to the .kici directory
153
+ */
154
+ function resolveKiciDir(kiciDir) {
155
+ const raw = kiciDir ?? ".kici";
156
+ const resolved = path.resolve(raw);
157
+ if (existsSync(path.join(resolved, "workflows"))) return resolved;
158
+ if (raw === ".kici") {
159
+ const cwd = process.cwd();
160
+ if (path.basename(cwd) === ".kici" && existsSync(path.join(cwd, "workflows"))) return cwd;
161
+ }
162
+ return resolved;
163
+ }
164
+ /**
165
+ * Discover and execute all workflow files from .kici/workflows/ directory.
166
+ *
167
+ * Process:
168
+ * 1. Locate .kici/workflows/ directory (defaults to .kici relative to cwd)
169
+ * 2. Find all *.ts files in the directory
170
+ * 3. Execute each file to extract workflow definitions
171
+ * 4. Collect and return all workflows
172
+ *
173
+ * @param kiciDir - Path to .kici directory (defaults to '.kici' relative to cwd)
174
+ * @returns Discovery result with all workflows and directory paths
175
+ * @throws CompilerError if .kici/workflows/ doesn't exist or no workflows found
176
+ */
177
+ async function discoverWorkflows(kiciDir) {
178
+ const absoluteKiciDir = resolveKiciDir(kiciDir);
179
+ const workflowDir = path.join(absoluteKiciDir, "workflows");
180
+ try {
181
+ 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" });
182
+ } catch (err) {
183
+ if (err.code === "ENOENT") throw compilerError("E001", `.kici/workflows/ directory not found: ${workflowDir}`, { suggestion: "Run \"kici init\" to create the .kici/workflows/ directory" });
184
+ throw err;
185
+ }
186
+ let files;
187
+ try {
188
+ files = (await fs.readdir(workflowDir, { withFileTypes: true })).filter((entry) => entry.isFile() && entry.name.endsWith(".ts")).map((entry) => path.join(workflowDir, entry.name));
189
+ } catch {
190
+ throw compilerError("E001", `Failed to read .kici/workflows/ directory: ${workflowDir}`, { suggestion: "Check directory permissions" });
191
+ }
192
+ if (files.length === 0) throw compilerError("E001", "No workflow files found in .kici/workflows/", { suggestion: "Add *.ts workflow files to .kici/workflows/ or run \"kici init\"" });
193
+ const allWorkflows = [];
194
+ for (const file of files) {
195
+ const result = await executeWorkflowFile(file);
196
+ allWorkflows.push(...result.workflows);
197
+ }
198
+ if (allWorkflows.length === 0) throw compilerError("E004", "No workflows exported from .kici/workflows/ files", { suggestion: "Ensure your workflow files export workflows using: export const myWorkflow = workflow(...)" });
199
+ return {
200
+ workflows: allWorkflows,
201
+ workflowDir,
202
+ kiciDir: absoluteKiciDir
203
+ };
204
+ }
205
+ /**
206
+ * Execute a single workflow file and extract workflow definitions.
207
+ * Similar to executeConfig but for individual workflow files.
208
+ *
209
+ * @param filePath - Absolute path to workflow file
210
+ * @returns Execution result with workflows from this file
211
+ */
212
+ async function executeWorkflowFile(filePath) {
213
+ try {
214
+ await fs.access(filePath);
215
+ } catch {
216
+ throw compilerError("E001", `Failed to read workflow file: ${filePath}`, { suggestion: "Check file permissions" });
217
+ }
218
+ const { module, hashBundleSource } = await loadModule(filePath, {
219
+ fileLabel: "workflow file",
220
+ filePath
221
+ });
222
+ return {
223
+ workflows: extractWorkflows(module, filePath, hashBundleSource),
224
+ configPath: filePath
225
+ };
226
+ }
227
+ //#endregion
228
+ export { discoverWorkflows, executeConfig, resolveKiciDir };
229
+
230
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1,4 @@
1
+ export { executeConfig, discoverWorkflows, resolveKiciDir } from './executor.js';
2
+ export type { ExecutionResult, DiscoveryResult } from './executor.js';
3
+ export type { WorkflowSourceInfo, WorkflowWithSource } from '../types.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,3 @@
1
+ import "../chunk-gOLHoazu.js";
2
+ import { discoverWorkflows, executeConfig, resolveKiciDir } from "./executor.js";
3
+ export { discoverWorkflows, executeConfig, resolveKiciDir };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * SDK aliasing for development mode
3
+ *
4
+ * Enables automatic aliasing of @kici-dev/sdk imports to a local development repository when:
5
+ * 1. sdkPath is configured in .kici/package.json
6
+ * 2. Current project is NOT the kici development repo itself
7
+ *
8
+ * This allows developers to test SDK changes in real-time without publishing or manual linking.
9
+ */
10
+ /**
11
+ * Get rolldown alias configuration for SDK development mode.
12
+ *
13
+ * Returns alias mapping if:
14
+ * - sdkPath is configured in .kici/package.json
15
+ * - Current project is NOT the kici repo itself
16
+ * - SDK build exists at configured path
17
+ *
18
+ * @returns Alias config for rolldown (empty object if aliasing disabled)
19
+ */
20
+ export declare function getSdkAliasConfig(): Promise<Record<string, string>>;
21
+ /**
22
+ * Get TypeScript path mappings for IDE support.
23
+ *
24
+ * Returns path mapping configuration to include in tsconfig.json:
25
+ * - Points @kici-dev/sdk to local source for autocomplete
26
+ * - Only if sdkPath is configured and valid
27
+ *
28
+ * @returns TypeScript paths config, or null if not applicable
29
+ */
30
+ export declare function getTypeScriptPaths(): Promise<{
31
+ '@kici-dev/sdk': [string];
32
+ } | null>;
33
+ //# sourceMappingURL=sdk-alias.d.ts.map
@@ -0,0 +1,102 @@
1
+ import "../chunk-gOLHoazu.js";
2
+ import { existsSync } from "node:fs";
3
+ import { readFile } from "node:fs/promises";
4
+ import path from "node:path";
5
+ import { logger } from "@kici-dev/shared";
6
+ //#region src/execution/sdk-alias.ts
7
+ /**
8
+ * SDK aliasing for development mode
9
+ *
10
+ * Enables automatic aliasing of @kici-dev/sdk imports to a local development repository when:
11
+ * 1. sdkPath is configured in .kici/package.json
12
+ * 2. Current project is NOT the kici development repo itself
13
+ *
14
+ * This allows developers to test SDK changes in real-time without publishing or manual linking.
15
+ */
16
+ /**
17
+ * Get rolldown alias configuration for SDK development mode.
18
+ *
19
+ * Returns alias mapping if:
20
+ * - sdkPath is configured in .kici/package.json
21
+ * - Current project is NOT the kici repo itself
22
+ * - SDK build exists at configured path
23
+ *
24
+ * @returns Alias config for rolldown (empty object if aliasing disabled)
25
+ */
26
+ async function getSdkAliasConfig() {
27
+ const basePath = await getSdkPathFromPackageJson();
28
+ if (!basePath) return {};
29
+ if (await isInKiciRepo()) {
30
+ if (process.env.KICI_DEBUG === "true") logger.warn("[kici] SDK aliasing disabled: running inside kici development repo");
31
+ return {};
32
+ }
33
+ const sdkPath = resolveAndValidateSdkPath(basePath);
34
+ if (!sdkPath) return {};
35
+ logger.warn(`[kici] Development mode: using local SDK from ${path.dirname(path.dirname(sdkPath))}`);
36
+ return { "@kici-dev/sdk": sdkPath };
37
+ }
38
+ /**
39
+ * Read sdkPath from .kici/package.json configuration.
40
+ *
41
+ * @returns Absolute path to SDK repo, or null if not configured
42
+ */
43
+ async function getSdkPathFromPackageJson() {
44
+ try {
45
+ const content = await readFile(path.resolve(process.cwd(), ".kici", "package.json"), "utf-8");
46
+ const sdkPath = JSON.parse(content).kici?.sdkPath;
47
+ if (!sdkPath) return null;
48
+ return path.resolve(sdkPath);
49
+ } catch {
50
+ return null;
51
+ }
52
+ }
53
+ /**
54
+ * Check if current project is the kici development repository.
55
+ *
56
+ * Checks if root package.json has kici.development flag set to true.
57
+ *
58
+ * @returns true if running inside kici repo
59
+ */
60
+ async function isInKiciRepo() {
61
+ try {
62
+ const content = await readFile(path.resolve(process.cwd(), "package.json"), "utf-8");
63
+ return JSON.parse(content).kici?.development === true;
64
+ } catch {
65
+ return false;
66
+ }
67
+ }
68
+ /**
69
+ * Resolve and validate the SDK dist path from a base kici repo path.
70
+ *
71
+ * @returns Absolute path to SDK dist/index.js, or null if not found
72
+ */
73
+ function resolveAndValidateSdkPath(basePath) {
74
+ const sdkPath = path.resolve(basePath, "packages/sdk/dist/index.js");
75
+ if (!existsSync(sdkPath)) {
76
+ logger.warn("[kici] sdkPath configured but SDK not found at path");
77
+ logger.warn(`[kici] Expected: ${sdkPath}`);
78
+ logger.warn("[kici] Hint: run \"pnpm build\" in the kici repo");
79
+ return null;
80
+ }
81
+ if (process.env.KICI_DEBUG === "true") logger.warn(`[kici] SDK alias resolved to: ${sdkPath}`);
82
+ return sdkPath;
83
+ }
84
+ /**
85
+ * Get TypeScript path mappings for IDE support.
86
+ *
87
+ * Returns path mapping configuration to include in tsconfig.json:
88
+ * - Points @kici-dev/sdk to local source for autocomplete
89
+ * - Only if sdkPath is configured and valid
90
+ *
91
+ * @returns TypeScript paths config, or null if not applicable
92
+ */
93
+ async function getTypeScriptPaths() {
94
+ const basePath = await getSdkPathFromPackageJson();
95
+ if (!basePath) return null;
96
+ if (await isInKiciRepo()) return null;
97
+ return { "@kici-dev/sdk": [path.resolve(basePath, "packages/sdk/src/index.ts")] };
98
+ }
99
+ //#endregion
100
+ export { getSdkAliasConfig, getTypeScriptPaths };
101
+
102
+ //# sourceMappingURL=sdk-alias.js.map
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Fixture auto-compilation pipeline.
3
+ *
4
+ * Discovers and dynamic-imports Fixture exports from `.kici/tests/*.ts` files.
5
+ * TypeScript transformation is handled by the shared oxc-transform ESM loader
6
+ * hook registered by the kici CLI bin (`@kici-dev/shared/ts-loader-hook`),
7
+ * which is the same hook the agent registers. Fixture files are imported in
8
+ * place so Node resolves `@kici-dev/sdk` from the customer's
9
+ * `.kici/node_modules/` — no temp files, no Rolldown bundle step.
10
+ */
11
+ import type { Fixture } from '@kici-dev/sdk';
12
+ /** A compiled fixture with source tracking */
13
+ export interface CompiledFixture {
14
+ /** Fixture ID */
15
+ id: string;
16
+ /** Absolute path to the source file */
17
+ sourceFile: string;
18
+ /** Resolved fixture definition */
19
+ fixture: Fixture;
20
+ }
21
+ /**
22
+ * Discover fixture files in the tests directory.
23
+ *
24
+ * Scans recursively for `*.ts` files.
25
+ * Returns empty array if directory doesn't exist (not an error).
26
+ */
27
+ export declare function discoverFixtureFiles(testsDir: string): Promise<string[]>;
28
+ /**
29
+ * Compile and extract fixtures from all `.kici/tests/*.ts` files.
30
+ *
31
+ * Process:
32
+ * 1. Discover fixture files.
33
+ * 2. Dynamic-import each `.ts` file (transformed on the fly by the shared
34
+ * oxc-transform ESM loader hook registered by the kici CLI bin).
35
+ * 3. Extract Fixture exports.
36
+ * 4. Resolve async factory fixtures.
37
+ * 5. Validate no duplicate fixture IDs.
38
+ */
39
+ export declare function compileFixtures(testsDir: string): Promise<CompiledFixture[]>;
40
+ /**
41
+ * Filter compiled fixtures by pattern.
42
+ *
43
+ * - Exact match on fixture ID
44
+ * - Glob pattern matching via picomatch
45
+ */
46
+ export declare function filterFixtures(fixtures: CompiledFixture[], pattern: string): CompiledFixture[];
47
+ //# sourceMappingURL=compiler.d.ts.map
@@ -0,0 +1,177 @@
1
+ import "../chunk-gOLHoazu.js";
2
+ import fs from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { fileURLToPath, pathToFileURL } from "node:url";
5
+ import picomatch from "picomatch";
6
+ //#region src/fixtures/compiler.ts
7
+ /**
8
+ * Fixture auto-compilation pipeline.
9
+ *
10
+ * Discovers and dynamic-imports Fixture exports from `.kici/tests/*.ts` files.
11
+ * TypeScript transformation is handled by the shared oxc-transform ESM loader
12
+ * hook registered by the kici CLI bin (`@kici-dev/shared/ts-loader-hook`),
13
+ * which is the same hook the agent registers. Fixture files are imported in
14
+ * place so Node resolves `@kici-dev/sdk` from the customer's
15
+ * `.kici/node_modules/` — no temp files, no Rolldown bundle step.
16
+ */
17
+ /**
18
+ * Discover fixture files in the tests directory.
19
+ *
20
+ * Scans recursively for `*.ts` files.
21
+ * Returns empty array if directory doesn't exist (not an error).
22
+ */
23
+ async function discoverFixtureFiles(testsDir) {
24
+ const absoluteDir = path.resolve(testsDir);
25
+ try {
26
+ if (!(await fs.stat(absoluteDir)).isDirectory()) return [];
27
+ } catch {
28
+ return [];
29
+ }
30
+ return (await scanDirectory(absoluteDir)).sort();
31
+ }
32
+ async function scanDirectory(dir) {
33
+ const entries = await fs.readdir(dir, { withFileTypes: true });
34
+ const results = [];
35
+ for (const entry of entries) {
36
+ const fullPath = path.join(dir, entry.name);
37
+ if (entry.isDirectory()) {
38
+ const nested = await scanDirectory(fullPath);
39
+ results.push(...nested);
40
+ } else if (entry.isFile() && entry.name.endsWith(".ts") && !entry.name.endsWith(".d.ts")) results.push(fullPath);
41
+ }
42
+ return results;
43
+ }
44
+ /**
45
+ * Compile and extract fixtures from all `.kici/tests/*.ts` files.
46
+ *
47
+ * Process:
48
+ * 1. Discover fixture files.
49
+ * 2. Dynamic-import each `.ts` file (transformed on the fly by the shared
50
+ * oxc-transform ESM loader hook registered by the kici CLI bin).
51
+ * 3. Extract Fixture exports.
52
+ * 4. Resolve async factory fixtures.
53
+ * 5. Validate no duplicate fixture IDs.
54
+ */
55
+ async function compileFixtures(testsDir) {
56
+ const files = await discoverFixtureFiles(testsDir);
57
+ if (files.length === 0) return [];
58
+ const allFixtures = [];
59
+ for (const file of files) {
60
+ const fixtures = await loadFixtureFile(file);
61
+ allFixtures.push(...fixtures);
62
+ }
63
+ const seenIds = /* @__PURE__ */ new Map();
64
+ for (const cf of allFixtures) {
65
+ const existing = seenIds.get(cf.id);
66
+ if (existing) throw new Error(`Duplicate fixture ID "${cf.id}" found in:\n - ${existing}\n - ${cf.sourceFile}`);
67
+ seenIds.set(cf.id, cf.sourceFile);
68
+ }
69
+ return allFixtures;
70
+ }
71
+ async function loadFixtureFile(filePath) {
72
+ const createdLinks = await ensureRuntimeSymlinks(filePath);
73
+ let mod;
74
+ try {
75
+ mod = await import(pathToFileURL(filePath).href + `?t=${Date.now()}`);
76
+ } catch (err) {
77
+ throw new Error(`Failed to load fixture module ${filePath}: ${err.message}`);
78
+ } finally {
79
+ for (const link of createdLinks.reverse()) await fs.rm(link, {
80
+ recursive: true,
81
+ force: true
82
+ }).catch(() => {});
83
+ }
84
+ const fixtures = [];
85
+ for (const [key, value] of Object.entries(mod)) {
86
+ if (key === "default") continue;
87
+ if (isFixture(value)) {
88
+ const resolved = await resolveFixture(value);
89
+ fixtures.push({
90
+ id: resolved.id,
91
+ sourceFile: filePath,
92
+ fixture: resolved
93
+ });
94
+ }
95
+ }
96
+ return fixtures;
97
+ }
98
+ const RUNTIME_PACKAGES = [
99
+ "@kici-dev/sdk",
100
+ "zx",
101
+ "@kici-dev/shared"
102
+ ];
103
+ async function ensureRuntimeSymlinks(filePath) {
104
+ const created = [];
105
+ let nodeModulesDir = await findNearestNodeModules(path.dirname(filePath));
106
+ if (!nodeModulesDir) {
107
+ nodeModulesDir = path.join(path.dirname(filePath), "node_modules");
108
+ await fs.mkdir(nodeModulesDir, { recursive: true });
109
+ created.push(nodeModulesDir);
110
+ }
111
+ for (const pkg of RUNTIME_PACKAGES) {
112
+ const linkPath = path.join(nodeModulesDir, pkg);
113
+ try {
114
+ await fs.access(linkPath);
115
+ continue;
116
+ } catch {}
117
+ try {
118
+ const pkgDir = await findPackageRoot(fileURLToPath(import.meta.resolve(pkg)));
119
+ const linkParent = path.dirname(linkPath);
120
+ if (linkParent !== nodeModulesDir) await fs.mkdir(linkParent, { recursive: true });
121
+ await fs.symlink(pkgDir, linkPath);
122
+ created.push(linkPath);
123
+ } catch {}
124
+ }
125
+ return created;
126
+ }
127
+ async function findNearestNodeModules(startDir) {
128
+ let dir = startDir;
129
+ while (dir !== path.dirname(dir)) {
130
+ const nm = path.join(dir, "node_modules");
131
+ try {
132
+ if ((await fs.stat(nm)).isDirectory()) return nm;
133
+ } catch {}
134
+ dir = path.dirname(dir);
135
+ }
136
+ }
137
+ async function findPackageRoot(filePath) {
138
+ let dir = path.dirname(filePath);
139
+ while (dir !== path.dirname(dir)) try {
140
+ await fs.access(path.join(dir, "package.json"));
141
+ return dir;
142
+ } catch {
143
+ dir = path.dirname(dir);
144
+ }
145
+ return path.dirname(filePath);
146
+ }
147
+ function isFixture(value) {
148
+ if (typeof value !== "object" || value === null) return false;
149
+ const obj = value;
150
+ return typeof obj.id === "string" && obj.id.length > 0 && (typeof obj.options === "object" || typeof obj.options === "function") && obj.options !== null;
151
+ }
152
+ async function resolveFixture(fixture) {
153
+ if (typeof fixture.options === "function") {
154
+ const resolved = await fixture.options();
155
+ return Object.freeze({
156
+ id: fixture.id,
157
+ options: Object.freeze(resolved)
158
+ });
159
+ }
160
+ return fixture;
161
+ }
162
+ /**
163
+ * Filter compiled fixtures by pattern.
164
+ *
165
+ * - Exact match on fixture ID
166
+ * - Glob pattern matching via picomatch
167
+ */
168
+ function filterFixtures(fixtures, pattern) {
169
+ const exact = fixtures.find((f) => f.id === pattern);
170
+ if (exact) return [exact];
171
+ const isMatch = picomatch(pattern);
172
+ return fixtures.filter((f) => isMatch(f.id)).sort((a, b) => a.id.localeCompare(b.id));
173
+ }
174
+ //#endregion
175
+ export { compileFixtures, discoverFixtureFiles, filterFixtures };
176
+
177
+ //# sourceMappingURL=compiler.js.map
@@ -0,0 +1,30 @@
1
+ {
2
+ "action": "created",
3
+ "comment": {
4
+ "id": 1,
5
+ "body": "Looks good to me!",
6
+ "user": {
7
+ "login": "test-user"
8
+ },
9
+ "created_at": "2026-01-01T00:00:00Z"
10
+ },
11
+ "issue": {
12
+ "number": 42,
13
+ "title": "Test issue",
14
+ "state": "open",
15
+ "pull_request": {
16
+ "url": "https://api.github.com/repos/test-org/test-repo/pulls/42"
17
+ }
18
+ },
19
+ "repository": {
20
+ "name": "test-repo",
21
+ "full_name": "test-org/test-repo",
22
+ "owner": {
23
+ "login": "test-org"
24
+ },
25
+ "default_branch": "main"
26
+ },
27
+ "sender": {
28
+ "login": "test-user"
29
+ }
30
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "ref": "feature/new",
3
+ "ref_type": "branch",
4
+ "master_branch": "main",
5
+ "description": null,
6
+ "repository": {
7
+ "name": "test-repo",
8
+ "full_name": "test-org/test-repo",
9
+ "owner": {
10
+ "login": "test-org"
11
+ },
12
+ "default_branch": "main"
13
+ },
14
+ "sender": {
15
+ "login": "test-user"
16
+ }
17
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "ref": "feature/old",
3
+ "ref_type": "branch",
4
+ "repository": {
5
+ "name": "test-repo",
6
+ "full_name": "test-org/test-repo",
7
+ "owner": {
8
+ "login": "test-org"
9
+ },
10
+ "default_branch": "main"
11
+ },
12
+ "sender": {
13
+ "login": "test-user"
14
+ }
15
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "action": "deploy",
3
+ "client_payload": {},
4
+ "repository": {
5
+ "name": "test-repo",
6
+ "full_name": "test-org/test-repo",
7
+ "owner": {
8
+ "login": "test-org"
9
+ },
10
+ "default_branch": "main"
11
+ },
12
+ "sender": {
13
+ "login": "test-user"
14
+ }
15
+ }