@kici-dev/compiler 0.1.27 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth/headless-detect.d.ts +14 -5
- package/dist/auth/headless-detect.js +50 -9
- package/dist/cli.js +120 -11
- package/dist/commands/compile.js +28 -4
- package/dist/commands/diagnostics.js +14 -2
- package/dist/commands/doctor.d.ts +64 -0
- package/dist/commands/doctor.js +413 -0
- package/dist/commands/endpoints.js +6 -0
- package/dist/commands/fixture.js +13 -0
- package/dist/commands/hook.js +3 -2
- package/dist/commands/index.d.ts +8 -0
- package/dist/commands/index.js +5 -1
- package/dist/commands/init-host-os.d.ts +34 -0
- package/dist/commands/init-host-os.js +44 -0
- package/dist/commands/init.d.ts +4 -0
- package/dist/commands/init.js +159 -36
- package/dist/commands/local.d.ts +28 -2
- package/dist/commands/local.js +74 -5
- package/dist/commands/login.js +1 -1
- package/dist/commands/notifications.d.ts +61 -0
- package/dist/commands/notifications.js +274 -0
- package/dist/commands/preview.js +8 -1
- package/dist/commands/run-routed.js +10 -1
- package/dist/commands/run.js +41 -12
- package/dist/commands/runs/artifacts/download.d.ts +24 -0
- package/dist/commands/runs/artifacts/download.js +154 -0
- package/dist/commands/runs/artifacts/list.d.ts +5 -0
- package/dist/commands/runs/artifacts/list.js +47 -0
- package/dist/commands/runs/cancel.js +2 -2
- package/dist/commands/runs/list.js +8 -2
- package/dist/commands/verify-attestation.d.ts +3 -1
- package/dist/commands/verify-attestation.js +18 -7
- package/dist/errors/formatter.d.ts +14 -1
- package/dist/errors/formatter.js +13 -3
- package/dist/errors/index.d.ts +2 -1
- package/dist/errors/index.js +3 -2
- package/dist/errors/source-location.d.ts +20 -0
- package/dist/errors/source-location.js +45 -0
- package/dist/execution/executor.js +25 -5
- package/dist/fixtures/defaults/index.js +2 -1
- package/dist/llm-context/llms-architecture.txt +48 -19
- package/dist/llm-context/llms-cli.txt +2461 -1582
- package/dist/llm-context/llms-features.txt +178 -106
- package/dist/llm-context/llms-full.txt +6124 -4423
- package/dist/llm-context/llms-getting-started.txt +306 -42
- package/dist/llm-context/llms-patterns.txt +13 -7
- package/dist/llm-context/llms-sdk-runtime.txt +2013 -0
- package/dist/llm-context/llms-sdk.txt +591 -2152
- package/dist/llm-context/llms.txt +30 -16
- package/dist/local-plane/orchestrator-process.d.ts +12 -7
- package/dist/local-plane/orchestrator-process.js +28 -14
- package/dist/local-plane/os-mismatch-hint.d.ts +16 -0
- package/dist/local-plane/os-mismatch-hint.js +34 -0
- package/dist/local-plane/plane-liveness.d.ts +68 -0
- package/dist/local-plane/plane-liveness.js +145 -0
- package/dist/local-plane/plane-manager.d.ts +60 -18
- package/dist/local-plane/plane-manager.js +210 -70
- package/dist/local-plane/plane-trigger.d.ts +13 -4
- package/dist/local-plane/plane-trigger.js +27 -14
- package/dist/local-plane/platform-attach.js +1 -5
- package/dist/local-plane/port-holder.d.ts +78 -0
- package/dist/local-plane/port-holder.js +227 -0
- package/dist/local-plane/postgres.d.ts +15 -3
- package/dist/local-plane/postgres.js +34 -12
- package/dist/local-plane/run-follow.d.ts +20 -0
- package/dist/local-plane/run-follow.js +51 -4
- package/dist/local-plane/scaler-config.d.ts +28 -14
- package/dist/local-plane/scaler-config.js +59 -41
- package/dist/local-plane/source-provider.js +4 -10
- package/dist/lockfile/generator.d.ts +14 -1
- package/dist/lockfile/generator.js +99 -33
- package/dist/lockfile/index.d.ts +3 -1
- package/dist/lockfile/index.js +3 -2
- package/dist/lockfile/purity-diagnostics.d.ts +31 -0
- package/dist/lockfile/purity-diagnostics.js +52 -0
- package/dist/postinstall.js +2 -1
- package/dist/remote/artifact-extract.d.ts +8 -0
- package/dist/remote/artifact-extract.js +58 -0
- package/dist/remote/config.d.ts +21 -3
- package/dist/remote/config.js +24 -5
- package/dist/remote/dashboard-client.d.ts +39 -2
- package/dist/remote/dashboard-client.js +47 -4
- package/dist/remote/fs-case.d.ts +21 -0
- package/dist/remote/fs-case.js +45 -0
- package/dist/remote/history.d.ts +9 -3
- package/dist/remote/history.js +79 -10
- package/dist/remote/local-repo-identity.d.ts +1 -1
- package/dist/remote/local-repo-identity.js +2 -1
- package/dist/remote/notifications-client.d.ts +149 -0
- package/dist/remote/notifications-client.js +103 -0
- package/dist/remote/oauth.d.ts +13 -0
- package/dist/remote/oauth.js +31 -5
- package/dist/remote/output/summary.js +76 -14
- package/dist/remote/render.js +30 -9
- package/dist/remote/uploader.js +5 -4
- package/dist/templates/agents-md.d.ts +1 -1
- package/dist/templates/agents-md.js +6 -6
- package/dist/templates/index.d.ts +1 -1
- package/dist/templates/index.js +2 -2
- package/dist/templates/package-json.d.ts +15 -0
- package/dist/templates/package-json.js +26 -5
- package/dist/test-runner/dry-run.d.ts +2 -1
- package/dist/test-runner/dry-run.js +18 -1
- package/dist/test-runner/event-types.d.ts +2 -0
- package/dist/test-runner/event-types.js +3 -0
- package/dist/test-runner/job-executor.d.ts +1 -0
- package/dist/test-runner/job-executor.js +81 -43
- package/dist/test-runner/output-formatter.d.ts +5 -2
- package/dist/test-runner/output-formatter.js +6 -4
- package/dist/test-runner/payload-builder.d.ts +7 -1
- package/dist/test-runner/payload-builder.js +11 -2
- package/dist/test-runner/rule-evaluator.d.ts +7 -3
- package/dist/test-runner/rule-evaluator.js +13 -12
- package/dist/test-runner/step-context.d.ts +23 -5
- package/dist/test-runner/step-context.js +28 -118
- package/dist/types.d.ts +21 -2
- package/dist/types.js +4 -2
- package/dist/validation/index.d.ts +2 -0
- package/dist/validation/index.js +2 -1
- package/dist/validation/typecheck.d.ts +28 -0
- package/dist/validation/typecheck.js +110 -0
- package/dist/validation/validator.d.ts +9 -4
- package/dist/validation/validator.js +38 -44
- package/package.json +12 -15
- package/sbom.spdx.json +1322 -1964
- package/dist/assets/api-TJJVHrjC.json +0 -118
- package/dist/assets/descriptor-BTtjzN9L.json +0 -1382
- package/dist/assets/package-BpQF9kR8.json +0 -74
- package/dist/assets/package-Ceo2h27X.json +0 -89
- package/dist/assets/source_context-D0atuL28.json +0 -20
- package/dist/assets/type-BFqO8SCZ.json +0 -202
- package/dist/commands/cancel.d.ts +0 -22
- package/dist/commands/detect-package-manager.d.ts +0 -42
- package/dist/commands/held-run-resolve.d.ts +0 -50
- package/dist/commands/status.d.ts +0 -34
- package/dist/commands/test.d.ts +0 -88
- package/dist/errors/codes.d.ts +0 -25
- package/dist/local-executor/dag-scheduler.d.ts +0 -44
- package/dist/local-executor/index.d.ts +0 -23
- package/dist/local-executor/job-runner.d.ts +0 -47
- package/dist/local-executor/materializer.d.ts +0 -44
- package/dist/local-executor/output-streamer.d.ts +0 -31
- package/dist/local-executor/payload-generator.d.ts +0 -16
- package/dist/local-executor/picker.d.ts +0 -33
- package/dist/local-executor/runs-on-display.d.ts +0 -9
- package/dist/local-executor/secret-loader.d.ts +0 -18
- package/dist/local-executor/to-event-payload.d.ts +0 -16
- package/dist/local-executor/types.d.ts +0 -93
- package/dist/local-executor/workflow-lock.d.ts +0 -82
- package/dist/package-F7UXSDHW.json +0 -74
- package/dist/remote/client.d.ts +0 -210
- package/dist/remote/observer.d.ts +0 -81
- package/dist/test-runner/summary.d.ts +0 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "../rolldown-runtime-ClRpJifh.js";
|
|
2
2
|
import { formatter } from "./output-formatter.js";
|
|
3
3
|
import { createStepContext } from "./step-context.js";
|
|
4
|
-
import { createRuleContext, evaluateRules as evaluateRulesWithFormatting } from "./rule-evaluator.js";
|
|
4
|
+
import { createRuleContext as createRuleContext$1, evaluateRules as evaluateRulesWithFormatting } from "./rule-evaluator.js";
|
|
5
5
|
import { localRunsOnString } from "./runs-on-display.js";
|
|
6
6
|
import { pathToFileURL } from "node:url";
|
|
7
7
|
import path from "node:path";
|
|
@@ -73,11 +73,23 @@ async function executeJob(job, workflowName, event, repoRoot, testSecrets, sdkSe
|
|
|
73
73
|
const stepResults = [];
|
|
74
74
|
let ruleResults;
|
|
75
75
|
if (job.rules && job.rules.length > 0) {
|
|
76
|
-
const ruleContext = createRuleContext(
|
|
76
|
+
const ruleContext = createRuleContext$1({
|
|
77
|
+
event,
|
|
78
|
+
changedFiles: event.changedFiles,
|
|
79
|
+
changedFilesStatus: event.changedFilesStatus ?? "fetched"
|
|
80
|
+
});
|
|
77
81
|
const ruleEval = await evaluateRulesWithFormatting(job.rules, ruleContext, job.name);
|
|
78
82
|
ruleResults = ruleEval.results;
|
|
79
83
|
if (!ruleEval.allPassed) {
|
|
80
84
|
const durationMs = Date.now() - startTime;
|
|
85
|
+
if (ruleEval.evaluationError) return {
|
|
86
|
+
name: job.name,
|
|
87
|
+
status: "failure",
|
|
88
|
+
durationMs,
|
|
89
|
+
steps: [],
|
|
90
|
+
ruleResults,
|
|
91
|
+
error: /* @__PURE__ */ new Error(`rule '${ruleEval.evaluationError.label}' errored: ${ruleEval.evaluationError.message}`)
|
|
92
|
+
};
|
|
81
93
|
return {
|
|
82
94
|
name: job.name,
|
|
83
95
|
status: "skipped",
|
|
@@ -93,51 +105,61 @@ async function executeJob(job, workflowName, event, repoRoot, testSecrets, sdkSe
|
|
|
93
105
|
setters.setStepRefMap(refMap);
|
|
94
106
|
setStepOutputsMap(outputsMap);
|
|
95
107
|
setStepRefMap(refMap);
|
|
96
|
-
const ctx = createStepContext({ name: workflowName }, {
|
|
108
|
+
const { ctx, dispose } = createStepContext({ name: workflowName }, {
|
|
97
109
|
name: job.name,
|
|
98
110
|
runsOn: localRunsOnString(job.runsOn)
|
|
99
111
|
}, repoRoot, void 0, void 0, testSecrets, void 0, event.payload, event.provider);
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
durationMs,
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
112
|
+
try {
|
|
113
|
+
let stepCounter = 0;
|
|
114
|
+
for (const stepOrFn of job.steps) {
|
|
115
|
+
let normalizedStep;
|
|
116
|
+
if (typeof stepOrFn === "function") {
|
|
117
|
+
stepCounter++;
|
|
118
|
+
const name = `step-${stepCounter}`;
|
|
119
|
+
refMap.set(stepOrFn, name);
|
|
120
|
+
normalizedStep = {
|
|
121
|
+
_tag: "Step",
|
|
122
|
+
name,
|
|
123
|
+
run: stepOrFn
|
|
124
|
+
};
|
|
125
|
+
} else {
|
|
126
|
+
normalizedStep = stepOrFn;
|
|
127
|
+
if (!normalizedStep.name) {
|
|
128
|
+
stepCounter++;
|
|
129
|
+
normalizedStep.name = `step-${stepCounter}`;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const result = await executeStep(normalizedStep, ctx, job.name);
|
|
133
|
+
if (result.status === "success" && result.outputs != null) outputsMap.set(normalizedStep.name, result.outputs);
|
|
134
|
+
stepResults.push(result);
|
|
135
|
+
if (result.status === "failure") {
|
|
136
|
+
const durationMs = Date.now() - startTime;
|
|
137
|
+
formatter.logJobFailure(job.name, durationMs, result.error);
|
|
138
|
+
return {
|
|
139
|
+
name: job.name,
|
|
140
|
+
status: "failure",
|
|
141
|
+
durationMs,
|
|
142
|
+
steps: stepResults,
|
|
143
|
+
ruleResults,
|
|
144
|
+
error: result.error
|
|
145
|
+
};
|
|
146
|
+
}
|
|
130
147
|
}
|
|
148
|
+
const durationMs = Date.now() - startTime;
|
|
149
|
+
formatter.logJobComplete(job.name, durationMs);
|
|
150
|
+
return {
|
|
151
|
+
name: job.name,
|
|
152
|
+
status: "success",
|
|
153
|
+
durationMs,
|
|
154
|
+
steps: stepResults,
|
|
155
|
+
ruleResults
|
|
156
|
+
};
|
|
157
|
+
} finally {
|
|
158
|
+
await dispose().catch((err) => {
|
|
159
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
160
|
+
logger.warn(`local job temp scope cleanup failed: ${message}`);
|
|
161
|
+
});
|
|
131
162
|
}
|
|
132
|
-
const durationMs = Date.now() - startTime;
|
|
133
|
-
formatter.logJobComplete(job.name, durationMs);
|
|
134
|
-
return {
|
|
135
|
-
name: job.name,
|
|
136
|
-
status: "success",
|
|
137
|
-
durationMs,
|
|
138
|
-
steps: stepResults,
|
|
139
|
-
ruleResults
|
|
140
|
-
};
|
|
141
163
|
}
|
|
142
164
|
/**
|
|
143
165
|
* Execute a workflow with parallel job execution.
|
|
@@ -149,11 +171,27 @@ async function executeWorkflow(workflow, event, repoRoot, testSecrets, kiciDir)
|
|
|
149
171
|
const sdkSetters = await resolveSdkSetters(kiciDir);
|
|
150
172
|
let ruleResults;
|
|
151
173
|
if (workflow.rules && workflow.rules.length > 0) {
|
|
152
|
-
const ruleContext = createRuleContext(
|
|
174
|
+
const ruleContext = createRuleContext$1({
|
|
175
|
+
event,
|
|
176
|
+
changedFiles: event.changedFiles,
|
|
177
|
+
changedFilesStatus: event.changedFilesStatus ?? "fetched"
|
|
178
|
+
});
|
|
153
179
|
const ruleEval = await evaluateRulesWithFormatting(workflow.rules, ruleContext, workflow.name);
|
|
154
180
|
ruleResults = ruleEval.results;
|
|
155
181
|
if (!ruleEval.allPassed) {
|
|
156
182
|
const durationMs = Date.now() - startTime;
|
|
183
|
+
if (ruleEval.evaluationError) {
|
|
184
|
+
const error = /* @__PURE__ */ new Error(`rule '${ruleEval.evaluationError.label}' errored: ${ruleEval.evaluationError.message}`);
|
|
185
|
+
logger.info(pc.red(`\n✗ Workflow failed: ${error.message}\n`));
|
|
186
|
+
return {
|
|
187
|
+
name: workflow.name,
|
|
188
|
+
status: "failure",
|
|
189
|
+
durationMs,
|
|
190
|
+
jobs: [],
|
|
191
|
+
ruleResults,
|
|
192
|
+
error
|
|
193
|
+
};
|
|
194
|
+
}
|
|
157
195
|
logger.info(pc.yellow(`\n⚠ Workflow skipped due to rule failure\n`));
|
|
158
196
|
return {
|
|
159
197
|
name: workflow.name,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RuleResult } from '@kici-dev/sdk';
|
|
1
2
|
type ColorFn = (text: string) => string;
|
|
2
3
|
/**
|
|
3
4
|
* Output formatter that prefixes messages with colored job labels.
|
|
@@ -38,9 +39,11 @@ declare class OutputFormatter {
|
|
|
38
39
|
*/
|
|
39
40
|
logJobFailure(jobName: string, durationMs: number, error: Error): void;
|
|
40
41
|
/**
|
|
41
|
-
* Log rule evaluation.
|
|
42
|
+
* Log rule evaluation. A rule whose `check()` threw carries an `error`; it
|
|
43
|
+
* prints `✗ errored: <message>` so the author sees the crash reason instead of
|
|
44
|
+
* a bare `✗ failed`. A clean pass/false prints `✓ passed` / `✗ failed`.
|
|
42
45
|
*/
|
|
43
|
-
logRuleResult(jobName: string,
|
|
46
|
+
logRuleResult(jobName: string, result: RuleResult): void;
|
|
44
47
|
}
|
|
45
48
|
export declare const formatter: OutputFormatter;
|
|
46
49
|
export {};
|
|
@@ -77,12 +77,14 @@ var OutputFormatter = class {
|
|
|
77
77
|
logger.error(color(`[${jobName}]`) + pc.red(` ✗ Failed: ${error.message}`) + pc.gray(` (${durationMs}ms)`));
|
|
78
78
|
}
|
|
79
79
|
/**
|
|
80
|
-
* Log rule evaluation.
|
|
80
|
+
* Log rule evaluation. A rule whose `check()` threw carries an `error`; it
|
|
81
|
+
* prints `✗ errored: <message>` so the author sees the crash reason instead of
|
|
82
|
+
* a bare `✗ failed`. A clean pass/false prints `✓ passed` / `✗ failed`.
|
|
81
83
|
*/
|
|
82
|
-
logRuleResult(jobName,
|
|
84
|
+
logRuleResult(jobName, result) {
|
|
83
85
|
const color = this.getJobColor(jobName);
|
|
84
|
-
const status = passed ? pc.green("✓ passed") : pc.red("✗ failed");
|
|
85
|
-
logger.info(color(`[${jobName}]`) + pc.gray(` rule "${
|
|
86
|
+
const status = result.error ? pc.red(`✗ errored: ${result.error}`) : result.passed ? pc.green("✓ passed") : pc.red("✗ failed");
|
|
87
|
+
logger.info(color(`[${jobName}]`) + pc.gray(` rule "${result.label}": `) + status);
|
|
86
88
|
}
|
|
87
89
|
};
|
|
88
90
|
const formatter = new OutputFormatter();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SimulatedEvent } from '@kici-dev/engine';
|
|
1
|
+
import type { SimulatedEvent, ChangedFilesStatus } from '@kici-dev/engine';
|
|
2
2
|
export interface PayloadOptions {
|
|
3
3
|
/** Path to custom fixture file */
|
|
4
4
|
payload?: string;
|
|
@@ -12,6 +12,12 @@ export interface PayloadOptions {
|
|
|
12
12
|
sha?: string;
|
|
13
13
|
/** Simulate changed file paths for onChangedFiles trigger matching */
|
|
14
14
|
files?: string[];
|
|
15
|
+
/**
|
|
16
|
+
* Simulate `changedFiles` availability for rule evaluation. Defaults to
|
|
17
|
+
* `'fetched'` (the author's file list is a genuine diff); set `'unavailable'`
|
|
18
|
+
* to test a rule's `ctx.changedFilesStatus` guard on a diff-less event.
|
|
19
|
+
*/
|
|
20
|
+
changedFilesStatus?: ChangedFilesStatus;
|
|
15
21
|
}
|
|
16
22
|
/**
|
|
17
23
|
* Build event payload from default fixture, custom file, and CLI overrides.
|
|
@@ -147,7 +147,8 @@ async function buildEventPayload(eventArg, options) {
|
|
|
147
147
|
payload: mergedPayload,
|
|
148
148
|
targetBranch,
|
|
149
149
|
sourceBranch,
|
|
150
|
-
changedFiles: options.files ?? []
|
|
150
|
+
changedFiles: options.files ?? [],
|
|
151
|
+
changedFilesStatus: options.changedFilesStatus ?? "fetched"
|
|
151
152
|
};
|
|
152
153
|
}
|
|
153
154
|
/**
|
|
@@ -157,6 +158,7 @@ function isInternalEventType(eventType) {
|
|
|
157
158
|
return [
|
|
158
159
|
"kici_event",
|
|
159
160
|
"workflow_complete",
|
|
161
|
+
"workflows_failed_batch",
|
|
160
162
|
"job_complete",
|
|
161
163
|
"generic_webhook",
|
|
162
164
|
"schedule",
|
|
@@ -182,6 +184,12 @@ async function buildInternalEventPayload(eventType, options) {
|
|
|
182
184
|
status: eventType.status
|
|
183
185
|
};
|
|
184
186
|
break;
|
|
187
|
+
case "workflows_failed_batch":
|
|
188
|
+
payload = {
|
|
189
|
+
total: 0,
|
|
190
|
+
runs: []
|
|
191
|
+
};
|
|
192
|
+
break;
|
|
185
193
|
case "job_complete":
|
|
186
194
|
payload = {
|
|
187
195
|
workflowName: eventType.workflowName,
|
|
@@ -207,7 +215,8 @@ async function buildInternalEventPayload(eventType, options) {
|
|
|
207
215
|
action: void 0,
|
|
208
216
|
payload,
|
|
209
217
|
targetBranch: "main",
|
|
210
|
-
changedFiles: options.files ?? []
|
|
218
|
+
changedFiles: options.files ?? [],
|
|
219
|
+
changedFilesStatus: options.changedFilesStatus ?? "fetched"
|
|
211
220
|
};
|
|
212
221
|
}
|
|
213
222
|
//#endregion
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import type { Rule, RuleContext,
|
|
1
|
+
import type { Rule, RuleContext, CreateRuleContextInput } from '@kici-dev/sdk';
|
|
2
2
|
import type { RuleEvaluationResult } from '@kici-dev/sdk';
|
|
3
3
|
/**
|
|
4
|
-
* Create RuleContext for rule evaluation.
|
|
4
|
+
* Create a RuleContext for `kici test` rule evaluation. Delegates to the shared
|
|
5
|
+
* SDK factory (single source of truth), defaulting `env` to the process
|
|
6
|
+
* environment — the test-runner exposes the developer's real env to rules — and
|
|
7
|
+
* `changedFilesStatus` to `'fetched'` so an author-supplied (or empty) test
|
|
8
|
+
* changeset is a genuine diff and `ctx.changedFiles` never throws.
|
|
5
9
|
*/
|
|
6
|
-
export declare function createRuleContext(
|
|
10
|
+
export declare function createRuleContext(input: CreateRuleContextInput): RuleContext;
|
|
7
11
|
/**
|
|
8
12
|
* Evaluate rules with formatting output.
|
|
9
13
|
* Wraps the SDK's evaluateRules() with a callback that logs each rule result.
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import "../rolldown-runtime-ClRpJifh.js";
|
|
2
2
|
import { formatter } from "./output-formatter.js";
|
|
3
|
-
import { evaluateRules } from "@kici-dev/sdk";
|
|
3
|
+
import { createRuleContext as createRuleContext$1, evaluateRules } from "@kici-dev/sdk";
|
|
4
4
|
import { initZx } from "@kici-dev/core";
|
|
5
|
-
import { $ } from "zx";
|
|
6
5
|
//#region src/test-runner/rule-evaluator.ts
|
|
7
6
|
initZx();
|
|
8
7
|
/**
|
|
9
|
-
* Create RuleContext for rule evaluation.
|
|
8
|
+
* Create a RuleContext for `kici test` rule evaluation. Delegates to the shared
|
|
9
|
+
* SDK factory (single source of truth), defaulting `env` to the process
|
|
10
|
+
* environment — the test-runner exposes the developer's real env to rules — and
|
|
11
|
+
* `changedFilesStatus` to `'fetched'` so an author-supplied (or empty) test
|
|
12
|
+
* changeset is a genuine diff and `ctx.changedFiles` never throws.
|
|
10
13
|
*/
|
|
11
|
-
function createRuleContext(
|
|
12
|
-
return {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
$
|
|
18
|
-
};
|
|
14
|
+
function createRuleContext(input) {
|
|
15
|
+
return createRuleContext$1({
|
|
16
|
+
...input,
|
|
17
|
+
env: input.env ?? { ...process.env },
|
|
18
|
+
changedFilesStatus: input.changedFilesStatus ?? "fetched"
|
|
19
|
+
});
|
|
19
20
|
}
|
|
20
21
|
/**
|
|
21
22
|
* Evaluate rules with formatting output.
|
|
@@ -23,7 +24,7 @@ function createRuleContext(event, changedFiles = [], dispatchInputs = {}) {
|
|
|
23
24
|
*/
|
|
24
25
|
async function evaluateRulesWithFormatting(rules, context, jobName) {
|
|
25
26
|
return evaluateRules(rules, context, jobName, (result) => {
|
|
26
|
-
formatter.logRuleResult(jobName, result
|
|
27
|
+
formatter.logRuleResult(jobName, result);
|
|
27
28
|
});
|
|
28
29
|
}
|
|
29
30
|
//#endregion
|
|
@@ -1,15 +1,33 @@
|
|
|
1
1
|
import type { StepContext, WorkflowInfo, JobInfo, MatrixValues } from '@kici-dev/sdk';
|
|
2
|
+
/** Handle returned by {@link createStepContext}. */
|
|
3
|
+
export interface LocalStepContext {
|
|
4
|
+
/** The built step context, threaded into every step of the job. */
|
|
5
|
+
ctx: StepContext;
|
|
6
|
+
/**
|
|
7
|
+
* Drain the job's temp scope (and secrets state). Call once at job end —
|
|
8
|
+
* success, failure, or throw — to reclaim every `ctx.mktemp`/`ctx.mktempFile`
|
|
9
|
+
* allocation the job made. Delegates to the shared builder's `dispose`.
|
|
10
|
+
*/
|
|
11
|
+
dispose: () => Promise<void>;
|
|
12
|
+
}
|
|
2
13
|
/**
|
|
3
14
|
* Create a step context for local test execution.
|
|
4
15
|
*
|
|
5
|
-
* `repoRoot` pins `ctx.$` to the workflow's repository root so steps running
|
|
6
|
-
*
|
|
16
|
+
* `repoRoot` pins `ctx.$` to the workflow's repository root so steps running via
|
|
17
|
+
* local-dispatch behave the same as on the agent path (see
|
|
7
18
|
* `packages/agent/src/execution/sandbox/workflow-runner.ts`). Without this,
|
|
8
|
-
* `ctx.$` would inherit `process.cwd()` — i.e. wherever the user invoked
|
|
9
|
-
*
|
|
19
|
+
* `ctx.$` would inherit `process.cwd()` — i.e. wherever the user invoked `kici`
|
|
20
|
+
* — which silently breaks any step that uses relative paths.
|
|
21
|
+
*
|
|
22
|
+
* This is a thin adapter over the shared `@kici-dev/sdk/testing` builder — the
|
|
23
|
+
* single source of truth for constructing a test step context — supplying the
|
|
24
|
+
* local runner's formatter-backed logger. The shared builder owns the
|
|
25
|
+
* job-scoped temp allocator backing `ctx.mktemp`/`ctx.mktempFile`; the returned
|
|
26
|
+
* `dispose` surfaces its drain so the caller (`executeJob`) can reclaim the
|
|
27
|
+
* job's temp dirs at job end rather than only via the exit backstop.
|
|
10
28
|
*/
|
|
11
29
|
export declare function createStepContext(workflowInfo: WorkflowInfo, jobInfo: JobInfo, repoRoot: string, inputs?: Record<string, unknown>, matrix?: MatrixValues, testSecrets?: {
|
|
12
30
|
flat: Record<string, string>;
|
|
13
31
|
contexts: Record<string, Record<string, string>>;
|
|
14
|
-
}, context?: string, rawPayload?: Record<string, unknown>, provider?: string, dispatchInputs?: Readonly<Record<string, string | number | boolean | null>>, signal?: AbortSignal):
|
|
32
|
+
}, context?: string, rawPayload?: Record<string, unknown>, provider?: string, dispatchInputs?: Readonly<Record<string, string | number | boolean | null>>, signal?: AbortSignal): LocalStepContext;
|
|
15
33
|
//# sourceMappingURL=step-context.d.ts.map
|
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
import "../rolldown-runtime-ClRpJifh.js";
|
|
2
2
|
import { formatter } from "./output-formatter.js";
|
|
3
|
-
import {
|
|
4
|
-
import { chmodSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
5
|
-
import { createStepSecrets, resolveJobOutputs, resolveStepOutputs } from "@kici-dev/sdk";
|
|
6
|
-
import { initZx } from "@kici-dev/core";
|
|
7
|
-
import { tmpdir } from "node:os";
|
|
8
|
-
import { $ } from "zx";
|
|
3
|
+
import { createTestStepContext } from "@kici-dev/sdk/testing";
|
|
9
4
|
//#region src/test-runner/step-context.ts
|
|
10
|
-
initZx();
|
|
11
5
|
/**
|
|
12
|
-
* Create a logger that prefixes output with job name.
|
|
6
|
+
* Create a logger that prefixes output with the job name.
|
|
13
7
|
*/
|
|
14
8
|
function createTestLogger(jobName) {
|
|
15
9
|
return {
|
|
@@ -36,121 +30,37 @@ function createTestLogger(jobName) {
|
|
|
36
30
|
/**
|
|
37
31
|
* Create a step context for local test execution.
|
|
38
32
|
*
|
|
39
|
-
* `repoRoot` pins `ctx.$` to the workflow's repository root so steps running
|
|
40
|
-
*
|
|
33
|
+
* `repoRoot` pins `ctx.$` to the workflow's repository root so steps running via
|
|
34
|
+
* local-dispatch behave the same as on the agent path (see
|
|
41
35
|
* `packages/agent/src/execution/sandbox/workflow-runner.ts`). Without this,
|
|
42
|
-
* `ctx.$` would inherit `process.cwd()` — i.e. wherever the user invoked
|
|
43
|
-
*
|
|
36
|
+
* `ctx.$` would inherit `process.cwd()` — i.e. wherever the user invoked `kici`
|
|
37
|
+
* — which silently breaks any step that uses relative paths.
|
|
38
|
+
*
|
|
39
|
+
* This is a thin adapter over the shared `@kici-dev/sdk/testing` builder — the
|
|
40
|
+
* single source of truth for constructing a test step context — supplying the
|
|
41
|
+
* local runner's formatter-backed logger. The shared builder owns the
|
|
42
|
+
* job-scoped temp allocator backing `ctx.mktemp`/`ctx.mktempFile`; the returned
|
|
43
|
+
* `dispose` surfaces its drain so the caller (`executeJob`) can reclaim the
|
|
44
|
+
* job's temp dirs at job end rather than only via the exit backstop.
|
|
44
45
|
*/
|
|
45
46
|
function createStepContext(workflowInfo, jobInfo, repoRoot, inputs = {}, matrix, testSecrets, context, rawPayload, provider, dispatchInputs = {}, signal = new AbortController().signal) {
|
|
46
|
-
const
|
|
47
|
-
const namespacedSecrets = testSecrets?.contexts ?? {};
|
|
48
|
-
const mergedFlat = { ...flat };
|
|
49
|
-
for (const contextSecrets of Object.values(namespacedSecrets)) Object.assign(mergedFlat, contextSecrets);
|
|
50
|
-
const env = { ...process.env };
|
|
51
|
-
const scoped$ = $({ cwd: repoRoot });
|
|
52
|
-
let tmpdirPath = null;
|
|
53
|
-
const exposedEnvVars = /* @__PURE__ */ new Set();
|
|
54
|
-
let mountCounter = 0;
|
|
55
|
-
let exitHandlerRegistered = false;
|
|
56
|
-
const onProcessExit = () => {
|
|
57
|
-
for (const envVar of exposedEnvVars) {
|
|
58
|
-
delete env[envVar];
|
|
59
|
-
delete process.env[envVar];
|
|
60
|
-
}
|
|
61
|
-
exposedEnvVars.clear();
|
|
62
|
-
if (tmpdirPath !== null) {
|
|
63
|
-
try {
|
|
64
|
-
rmSync(tmpdirPath, {
|
|
65
|
-
recursive: true,
|
|
66
|
-
force: true
|
|
67
|
-
});
|
|
68
|
-
} catch {}
|
|
69
|
-
tmpdirPath = null;
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
const secretsHandle = createStepSecrets(mergedFlat, env, void 0, {
|
|
73
|
-
host: {
|
|
74
|
-
async writeMountedFile(args) {
|
|
75
|
-
if (tmpdirPath === null) tmpdirPath = mkdtempSync(join(tmpdir(), "kici-secret-files-"));
|
|
76
|
-
if (!exitHandlerRegistered) {
|
|
77
|
-
process.once("exit", onProcessExit);
|
|
78
|
-
exitHandlerRegistered = true;
|
|
79
|
-
}
|
|
80
|
-
mountCounter += 1;
|
|
81
|
-
const filename = args.name ?? `secret-${mountCounter}`;
|
|
82
|
-
const filePath = join(tmpdirPath, filename);
|
|
83
|
-
writeFileSync(filePath, args.content);
|
|
84
|
-
chmodSync(filePath, args.mode);
|
|
85
|
-
return filePath;
|
|
86
|
-
},
|
|
87
|
-
trackExposedEnv(envVar) {
|
|
88
|
-
exposedEnvVars.add(envVar);
|
|
89
|
-
}
|
|
90
|
-
},
|
|
91
|
-
cleanup: async () => {
|
|
92
|
-
if (exitHandlerRegistered) {
|
|
93
|
-
process.off("exit", onProcessExit);
|
|
94
|
-
exitHandlerRegistered = false;
|
|
95
|
-
}
|
|
96
|
-
onProcessExit();
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
return {
|
|
100
|
-
$: scoped$,
|
|
101
|
-
log: createTestLogger(jobInfo.name),
|
|
102
|
-
signal,
|
|
103
|
-
env,
|
|
104
|
-
setEnv: (key, value) => {
|
|
105
|
-
env[key] = value;
|
|
106
|
-
process.env[key] = value;
|
|
107
|
-
},
|
|
108
|
-
addPath: (dir) => {
|
|
109
|
-
const updated = `${dir}:${env.PATH ?? process.env.PATH ?? ""}`;
|
|
110
|
-
env.PATH = updated;
|
|
111
|
-
process.env.PATH = updated;
|
|
112
|
-
},
|
|
113
|
-
inputs,
|
|
114
|
-
dispatchInputs,
|
|
47
|
+
const { ctx, dispose } = createTestStepContext({
|
|
115
48
|
workflow: workflowInfo,
|
|
116
49
|
job: jobInfo,
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
secrets:
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
},
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
},
|
|
132
|
-
setSecretOutput: () => {},
|
|
133
|
-
kici: {
|
|
134
|
-
infrastructure: { list: () => Promise.resolve({
|
|
135
|
-
scalers: [],
|
|
136
|
-
agents: []
|
|
137
|
-
}) },
|
|
138
|
-
inventory: {
|
|
139
|
-
query: () => Promise.resolve([]),
|
|
140
|
-
get: () => Promise.resolve(null)
|
|
141
|
-
},
|
|
142
|
-
oidc: { token: () => Promise.reject(/* @__PURE__ */ new Error("ctx.kici.oidc.token() is not available in the local test runner")) },
|
|
143
|
-
host: { requestReboot: () => Promise.reject(/* @__PURE__ */ new Error("ctx.kici.host.requestReboot() is not available in the local test runner")) },
|
|
144
|
-
bootstrap: {
|
|
145
|
-
ensureInitRunner: () => Promise.reject(/* @__PURE__ */ new Error("ctx.kici.bootstrap.ensureInitRunner() is not available in the local test runner")),
|
|
146
|
-
preBootSend: () => Promise.reject(/* @__PURE__ */ new Error("ctx.kici.bootstrap.preBootSend() is not available in the local test runner"))
|
|
147
|
-
}
|
|
148
|
-
},
|
|
149
|
-
cache: {
|
|
150
|
-
restore: async () => ({ hit: false }),
|
|
151
|
-
save: async () => {}
|
|
152
|
-
},
|
|
153
|
-
attestProvenance: () => Promise.reject(/* @__PURE__ */ new Error("ctx.attestProvenance() is not available in the local test runner"))
|
|
50
|
+
repoRoot,
|
|
51
|
+
inputs,
|
|
52
|
+
dispatchInputs,
|
|
53
|
+
signal,
|
|
54
|
+
log: createTestLogger(jobInfo.name),
|
|
55
|
+
secrets: testSecrets,
|
|
56
|
+
...matrix !== void 0 && { matrix },
|
|
57
|
+
...context !== void 0 && { context },
|
|
58
|
+
...rawPayload !== void 0 && { rawPayload },
|
|
59
|
+
...provider !== void 0 && { provider }
|
|
60
|
+
});
|
|
61
|
+
return {
|
|
62
|
+
ctx,
|
|
63
|
+
dispose
|
|
154
64
|
};
|
|
155
65
|
}
|
|
156
66
|
//#endregion
|
package/dist/types.d.ts
CHANGED
|
@@ -28,7 +28,9 @@ export interface LockApproval {
|
|
|
28
28
|
readonly when: 'always' | 'drift';
|
|
29
29
|
}
|
|
30
30
|
/** Schema version - re-exported from engine as single source of truth */
|
|
31
|
-
export declare const SCHEMA_VERSION:
|
|
31
|
+
export declare const SCHEMA_VERSION: 32;
|
|
32
|
+
/** Lock compatibility-window floor - re-exported from engine as single source of truth */
|
|
33
|
+
export declare const BREAKING_FLOOR: 30;
|
|
32
34
|
/**
|
|
33
35
|
* Source file reference with meaningful path.
|
|
34
36
|
* Format: file is relative path from git root, export uses hash syntax.
|
|
@@ -229,6 +231,17 @@ export interface LockWorkflowCompleteTrigger {
|
|
|
229
231
|
readonly status?: readonly string[];
|
|
230
232
|
readonly source?: string;
|
|
231
233
|
}
|
|
234
|
+
/**
|
|
235
|
+
* Workflows-failed-batch trigger in lock file.
|
|
236
|
+
* Accumulates failed workflow completions over a window and fires the
|
|
237
|
+
* subscribing workflow once per window with the batched run list.
|
|
238
|
+
*/
|
|
239
|
+
export interface LockWorkflowsFailedBatchTrigger {
|
|
240
|
+
readonly _type: 'workflows_failed_batch';
|
|
241
|
+
readonly accumulateFor: number;
|
|
242
|
+
readonly name?: string;
|
|
243
|
+
readonly source?: string;
|
|
244
|
+
}
|
|
232
245
|
/**
|
|
233
246
|
* Job completion trigger in lock file.
|
|
234
247
|
* Matches when a specific job within a workflow finishes execution.
|
|
@@ -289,7 +302,7 @@ export interface LockLifecycleTrigger {
|
|
|
289
302
|
readonly description?: string;
|
|
290
303
|
}
|
|
291
304
|
/** Union of all trigger types */
|
|
292
|
-
export type LockTrigger = LockPrTrigger | LockPushTrigger | LockTagTrigger | LockCommentTrigger | LockReviewTrigger | LockReviewCommentTrigger | LockReleaseTrigger | LockDispatchTrigger | LockCreateTrigger | LockDeleteTrigger | LockStatusTrigger | LockWorkflowRunTrigger | LockForkTrigger | LockStarTrigger | LockWatchTrigger | LockWebhookTrigger | LockKiciEventTrigger | LockWorkflowCompleteTrigger | LockJobCompleteTrigger | LockGenericWebhookTrigger | LockScheduleTrigger | LockLifecycleTrigger;
|
|
305
|
+
export type LockTrigger = LockPrTrigger | LockPushTrigger | LockTagTrigger | LockCommentTrigger | LockReviewTrigger | LockReviewCommentTrigger | LockReleaseTrigger | LockDispatchTrigger | LockCreateTrigger | LockDeleteTrigger | LockStatusTrigger | LockWorkflowRunTrigger | LockForkTrigger | LockStarTrigger | LockWatchTrigger | LockWebhookTrigger | LockKiciEventTrigger | LockWorkflowCompleteTrigger | LockWorkflowsFailedBatchTrigger | LockJobCompleteTrigger | LockGenericWebhookTrigger | LockScheduleTrigger | LockLifecycleTrigger;
|
|
293
306
|
/**
|
|
294
307
|
* Matrix configuration in lock file.
|
|
295
308
|
* Static matrices are expanded at orchestrator, dynamic at agent runtime.
|
|
@@ -592,6 +605,12 @@ export interface LockWorkflow {
|
|
|
592
605
|
*/
|
|
593
606
|
export interface LockFile {
|
|
594
607
|
readonly schemaVersion: typeof SCHEMA_VERSION;
|
|
608
|
+
/**
|
|
609
|
+
* Newest breaking schema version at emit time (`BREAKING_FLOOR`). Readers
|
|
610
|
+
* whose own SCHEMA_VERSION is below this must reject the lock. Mirrors the
|
|
611
|
+
* engine `LockFile.minReaderVersion` field.
|
|
612
|
+
*/
|
|
613
|
+
readonly minReaderVersion?: number;
|
|
595
614
|
readonly source: LockSource;
|
|
596
615
|
/** SHA-256 hash of the serialized lock file content (excluding this field). Changes only when workflows, triggers, jobs, or bundle hashes change. */
|
|
597
616
|
readonly contentHash: string;
|
package/dist/types.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "./rolldown-runtime-ClRpJifh.js";
|
|
2
|
-
import { SCHEMA_VERSION as SCHEMA_VERSION$1 } from "@kici-dev/engine";
|
|
2
|
+
import { BREAKING_FLOOR as BREAKING_FLOOR$1, SCHEMA_VERSION as SCHEMA_VERSION$1 } from "@kici-dev/engine";
|
|
3
3
|
//#region src/types.ts
|
|
4
4
|
/**
|
|
5
5
|
* Lock file schema version 11.
|
|
@@ -17,6 +17,8 @@ import { SCHEMA_VERSION as SCHEMA_VERSION$1 } from "@kici-dev/engine";
|
|
|
17
17
|
*/
|
|
18
18
|
/** Schema version - re-exported from engine as single source of truth */
|
|
19
19
|
const SCHEMA_VERSION = SCHEMA_VERSION$1;
|
|
20
|
+
/** Lock compatibility-window floor - re-exported from engine as single source of truth */
|
|
21
|
+
const BREAKING_FLOOR = BREAKING_FLOOR$1;
|
|
20
22
|
/** Type guard distinguishing a parallel group from an ordinary lock step. */
|
|
21
23
|
function isLockParallelStep(entry) {
|
|
22
24
|
return entry.kind === "parallel";
|
|
@@ -34,6 +36,6 @@ function isLockDynamicJobFn(job) {
|
|
|
34
36
|
return job._type === "dynamic";
|
|
35
37
|
}
|
|
36
38
|
//#endregion
|
|
37
|
-
export { SCHEMA_VERSION, isLockDynamicJobFn, isLockInlineValue, isLockParallelStep, isLockStaticJob };
|
|
39
|
+
export { BREAKING_FLOOR, SCHEMA_VERSION, isLockDynamicJobFn, isLockInlineValue, isLockParallelStep, isLockStaticJob };
|
|
38
40
|
|
|
39
41
|
//# sourceMappingURL=types.js.map
|
package/dist/validation/index.js
CHANGED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type CompilerError } from '../errors/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Result of the opt-in `tsc --noEmit` type-check pass.
|
|
4
|
+
*
|
|
5
|
+
* `ran: false` means the pass was skipped (no `tsconfig.json` — a
|
|
6
|
+
* JavaScript-only / `--mjs` workspace has no types to check). `ran: true` with
|
|
7
|
+
* an empty `errors` array means the sources type-check cleanly.
|
|
8
|
+
*/
|
|
9
|
+
export interface TypecheckResult {
|
|
10
|
+
ran: boolean;
|
|
11
|
+
errors: CompilerError[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Turn `tsc --noEmit --pretty false` output into located `E120` compiler errors.
|
|
15
|
+
* Handles both located diagnostics (`file(line,col): error TS…`) and global
|
|
16
|
+
* ones (`error TS…`, e.g. a bad tsconfig). Non-diagnostic noise lines are
|
|
17
|
+
* ignored. Paths are left as tsc emits them (kiciDir-relative), readable in the
|
|
18
|
+
* GNU error format.
|
|
19
|
+
*/
|
|
20
|
+
export declare function parseTscOutput(stdout: string): CompilerError[];
|
|
21
|
+
/**
|
|
22
|
+
* Run an opt-in `tsc --noEmit` type-check over the workflow sources in
|
|
23
|
+
* `kiciDir`. Skips (returns `ran: false`) when there is no `tsconfig.json`.
|
|
24
|
+
* Prefers the workspace-local `tsc` binary, falling back to `npx typescript`;
|
|
25
|
+
* returns a single `E121` when the compiler cannot be resolved.
|
|
26
|
+
*/
|
|
27
|
+
export declare function runTypecheck(kiciDir: string): Promise<TypecheckResult>;
|
|
28
|
+
//# sourceMappingURL=typecheck.d.ts.map
|