@kici-dev/compiler 0.1.22 → 0.1.24
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/cli.js +34 -10
- package/dist/commands/compile.d.ts +6 -0
- package/dist/commands/compile.js +6 -3
- package/dist/commands/docs.d.ts +8 -8
- package/dist/commands/docs.js +35 -16
- package/dist/commands/index.d.ts +4 -2
- package/dist/commands/index.js +3 -2
- package/dist/commands/init.js +2 -2
- package/dist/commands/org.js +2 -2
- package/dist/commands/pat.d.ts +27 -0
- package/dist/commands/pat.js +76 -0
- package/dist/commands/preview.d.ts +88 -0
- package/dist/commands/{test.js → preview.js} +15 -14
- package/dist/commands/run.d.ts +27 -2
- package/dist/commands/run.js +117 -18
- package/dist/commands/test.d.ts +4 -0
- package/dist/commands/types.d.ts +2 -0
- package/dist/commands/types.js +1 -1
- package/dist/commands/verify-attestation.d.ts +4 -1
- package/dist/commands/verify-attestation.js +26 -10
- package/dist/fixtures/describe-event.d.ts +6 -0
- package/dist/fixtures/describe-event.js +18 -0
- package/dist/fixtures/picker.d.ts +19 -0
- package/dist/fixtures/picker.js +64 -0
- package/dist/generators/secrets-dts.js +2 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/llm-context/llms-architecture.txt +1440 -0
- package/dist/llm-context/llms-cli.txt +2509 -0
- package/dist/llm-context/llms-features.txt +2491 -0
- package/dist/llm-context/llms-full.txt +1364 -361
- package/dist/llm-context/llms-getting-started.txt +519 -0
- package/dist/llm-context/llms-patterns.txt +1324 -0
- package/dist/llm-context/llms-providers.txt +805 -0
- package/dist/llm-context/llms-sdk.txt +3844 -0
- package/dist/llm-context/llms.txt +16 -1
- package/dist/local-executor/index.js +42 -4
- package/dist/local-executor/job-runner.d.ts +2 -0
- package/dist/local-executor/job-runner.js +38 -6
- package/dist/local-executor/types.d.ts +2 -0
- package/dist/lockfile/generator.d.ts +10 -2
- package/dist/lockfile/generator.js +112 -49
- package/dist/remote/history.d.ts +1 -1
- package/dist/remote/history.js +1 -1
- package/dist/remote/local-repo-identity.d.ts +32 -0
- package/dist/remote/local-repo-identity.js +74 -0
- package/dist/remote/platform-client.d.ts +6 -0
- package/dist/remote/prod-defaults.d.ts +8 -0
- package/dist/remote/prod-defaults.js +9 -1
- package/dist/remote/uploader.js +1 -0
- package/dist/templates/agents-md.d.ts +1 -1
- package/dist/templates/agents-md.js +2 -2
- package/dist/templates/package-json.js +1 -1
- package/dist/test-runner/rule-evaluator.d.ts +1 -1
- package/dist/test-runner/rule-evaluator.js +2 -1
- package/dist/test-runner/step-context.d.ts +1 -1
- package/dist/test-runner/step-context.js +8 -2
- package/dist/types.d.ts +38 -7
- package/dist/types.js +5 -1
- package/package.json +4 -7
- package/sbom.spdx.json +35 -35
package/dist/cli.js
CHANGED
|
@@ -7,7 +7,7 @@ import { realpathSync } from "node:fs";
|
|
|
7
7
|
import { Argument, Command, Option } from "commander";
|
|
8
8
|
import pc from "picocolors";
|
|
9
9
|
//#region src/cli.ts
|
|
10
|
-
const version = "0.1.
|
|
10
|
+
const version = "0.1.24";
|
|
11
11
|
/**
|
|
12
12
|
* Build the kici Commander program with every command registered. Exported so
|
|
13
13
|
* the surface registry can walk the real command tree without parsing argv (no
|
|
@@ -44,7 +44,7 @@ function buildProgram() {
|
|
|
44
44
|
await fixtureCommand(event, options);
|
|
45
45
|
});
|
|
46
46
|
const runCommand = program.command("run").description("Execute workflows locally or remotely");
|
|
47
|
-
runCommand.command("local").argument("[event]", "Event type (e.g., push, pr:open, schedule) — optional with --pick").description("Execute workflows locally without orchestrator infrastructure").option("-p, --pick", "Interactively pick a workflow and trigger to simulate", false).option("--workflow <name>", "Run only the specified workflow").option("--job <name>", "Run only the specified job (and its dependencies)").option("--branch <name>", "Override detected git branch").option("--sha <hash>", "Override detected git SHA").option("--payload <path>", "Path to explicit event payload JSON file").option("--concurrency <n>", "Max parallel jobs (default: CPU cores)", parseInt).option("--keep-going", "Continue after job failure", false).option("--container", "Use Podman container isolation", false).option("--env <KEY=VALUE>", "Environment variable override (repeatable)", (val, prev) => [...prev, val], []).option("--quiet", "Suppress streaming output", false).option("--json", "Output structured JSON result", false).option("--junit <path>", "Output JUnit XML result").option("--files <path>", "Override changed file paths (repeatable, default: git diff)", (val, prev) => [...prev, val], []).option("--debug", "Verbose internals", false).option("--kici-dir <path>", "Path to .kici directory", ".kici").option("--in-place", "Run against the real working directory instead of an isolated tmp checkout", false).option("--keep", "Always retain the isolated tmp checkout (default: keep only on failure)", false).option("--check", "Run in check mode: report drift, change nothing", false).option("--fail-on-drift", "In check mode, exit non-zero if any step reports drift", false).action(async (event, options) => {
|
|
47
|
+
runCommand.command("local").argument("[event]", "Event type (e.g., push, pr:open, schedule) — optional with --pick").description("Execute workflows locally without orchestrator infrastructure").option("-p, --pick", "Interactively pick a workflow and trigger to simulate", false).option("--workflow <name>", "Run only the specified workflow").option("--job <name>", "Run only the specified job (and its dependencies)").option("--branch <name>", "Override detected git branch").option("--sha <hash>", "Override detected git SHA").option("--payload <path>", "Path to explicit event payload JSON file").option("--concurrency <n>", "Max parallel jobs (default: CPU cores)", parseInt).option("--keep-going", "Continue after job failure", false).option("--container", "Use Podman container isolation", false).option("--env <KEY=VALUE>", "Environment variable override (repeatable)", (val, prev) => [...prev, val], []).option("--input <KEY=VALUE>", "Typed workflow-dispatch input (repeatable)", (val, prev) => [...prev, val], []).option("--quiet", "Suppress streaming output", false).option("--json", "Output structured JSON result", false).option("--junit <path>", "Output JUnit XML result").option("--files <path>", "Override changed file paths (repeatable, default: git diff)", (val, prev) => [...prev, val], []).option("--debug", "Verbose internals", false).option("--kici-dir <path>", "Path to .kici directory", ".kici").option("--in-place", "Run against the real working directory instead of an isolated tmp checkout", false).option("--keep", "Always retain the isolated tmp checkout (default: keep only on failure)", false).option("--check", "Run in check mode: report drift, change nothing", false).option("--fail-on-drift", "In check mode, exit non-zero if any step reports drift", false).action(async (event, options) => {
|
|
48
48
|
if (options.pick && options.workflow) {
|
|
49
49
|
console.error("Error: --pick is mutually exclusive with --workflow.");
|
|
50
50
|
process.exit(2);
|
|
@@ -78,6 +78,7 @@ function buildProgram() {
|
|
|
78
78
|
keepGoing: options.keepGoing,
|
|
79
79
|
container: options.container,
|
|
80
80
|
env: options.env,
|
|
81
|
+
inputs: options.input,
|
|
81
82
|
quiet: options.quiet,
|
|
82
83
|
json: options.json,
|
|
83
84
|
junit: options.junit,
|
|
@@ -89,7 +90,19 @@ function buildProgram() {
|
|
|
89
90
|
});
|
|
90
91
|
process.exit(success ? 0 : 1);
|
|
91
92
|
});
|
|
92
|
-
runCommand.command("remote").argument("[fixture]", "Fixture name or glob pattern (omit to list available)").description("Execute fixtures remotely via orchestrator").option("--workflow <name>", "Run a specific workflow directly (bypass triggers)").option("--all", "Run all available fixtures", false).option("--parallel", "Run matching fixtures concurrently", false).option("--no-wait", "Fire and forget (print runIds, don't stream)").option("--quiet", "Suppress output except final result", false).option("--json", "Output structured JSON result", false).option("--junit <path>", "Output JUnit XML result").option("--history", "Show recent run history", false).option("--routing-key <key>", "Override routing key for this run").option("--org <id>", "Target organization (overrides the active org)").option("--orchestrator <name>", "Target orchestrator cluster (overrides the per-org default)").option("--debug", "Verbose internals", false).option("--kici-dir <path>", "Path to .kici directory", ".kici").option("--context <ctx.key=value>", "Inject a namespaced context secret, uploaded encrypted to the orchestrator (repeatable)", (val, prev) => [...prev, val], []).option("--env <KEY=VALUE>", "Provide a per-run secret (repeatable); uploaded encrypted to the orchestrator", (val, prev) => [...prev, val], []).option("--check", "Run in check mode: report drift, change nothing", false).option("--fail-on-drift", "In check mode, exit non-zero if any step reports drift", false).option("--target <selector>", "Narrow runsOnAll jobs to hosts matching this label selector (repeatable, AND-combined)", (val, prev) => [...prev, val], []).option("--target-allow-empty", "A --target that narrows a runsOnAll job to zero hosts skips it instead of failing", false).option("--approve-all, --yes", "Auto-approve every approval gate this run holds on (run-scoped; eligibility still enforced)", false).action(async (fixture, options) => {
|
|
93
|
+
runCommand.command("remote").argument("[fixture]", "Fixture name or glob pattern (omit to list available)").description("Execute fixtures remotely via orchestrator").option("--workflow <name>", "Run a specific workflow directly (bypass triggers)").option("--all", "Run all available fixtures", false).option("-p, --pick", "Interactively pick fixtures to run", false).option("--parallel", "Run matching fixtures concurrently", false).option("--no-wait", "Fire and forget (print runIds, don't stream)").option("--quiet", "Suppress output except final result", false).option("--json", "Output structured JSON result", false).option("--junit <path>", "Output JUnit XML result").option("--history", "Show recent run history", false).option("--routing-key <key>", "Override routing key for this run").option("--org <id>", "Target organization (overrides the active org)").option("--orchestrator <name>", "Target orchestrator cluster (overrides the per-org default)").option("--debug", "Verbose internals", false).option("--kici-dir <path>", "Path to .kici directory", ".kici").option("--context <ctx.key=value>", "Inject a namespaced context secret, uploaded encrypted to the orchestrator (repeatable)", (val, prev) => [...prev, val], []).option("--env <KEY=VALUE>", "Provide a per-run secret (repeatable); uploaded encrypted to the orchestrator", (val, prev) => [...prev, val], []).option("--check", "Run in check mode: report drift, change nothing", false).option("--fail-on-drift", "In check mode, exit non-zero if any step reports drift", false).option("--target <selector>", "Narrow runsOnAll jobs to hosts matching this label selector (repeatable, AND-combined)", (val, prev) => [...prev, val], []).option("--target-allow-empty", "A --target that narrows a runsOnAll job to zero hosts skips it instead of failing", false).option("--input <KEY=VALUE>", "Typed workflow-dispatch input (repeatable)", (val, prev) => [...prev, val], []).option("--approve-all, --yes", "Auto-approve every approval gate this run holds on (run-scoped; eligibility still enforced)", false).action(async (fixture, options) => {
|
|
94
|
+
if (options.pick && fixture) {
|
|
95
|
+
console.error("Error: --pick selects fixtures interactively; do not also pass a fixture name.");
|
|
96
|
+
process.exit(2);
|
|
97
|
+
}
|
|
98
|
+
if (options.pick && options.all) {
|
|
99
|
+
console.error("Error: --pick is mutually exclusive with --all.");
|
|
100
|
+
process.exit(2);
|
|
101
|
+
}
|
|
102
|
+
if (options.pick && options.workflow) {
|
|
103
|
+
console.error("Error: --pick is mutually exclusive with --workflow.");
|
|
104
|
+
process.exit(2);
|
|
105
|
+
}
|
|
93
106
|
const { runRemoteCommand } = await import("./commands/index.js");
|
|
94
107
|
const { resolveCheckMode } = await import("./commands/check-mode.js");
|
|
95
108
|
let checkMode;
|
|
@@ -108,13 +121,14 @@ function buildProgram() {
|
|
|
108
121
|
envFlags: options.env,
|
|
109
122
|
targets: options.target,
|
|
110
123
|
targetAllowEmpty: options.targetAllowEmpty,
|
|
111
|
-
approveAll: options.approveAll
|
|
124
|
+
approveAll: options.approveAll,
|
|
125
|
+
inputs: options.input
|
|
112
126
|
});
|
|
113
127
|
process.exit(success ? 0 : 1);
|
|
114
128
|
});
|
|
115
|
-
program.command("
|
|
116
|
-
const {
|
|
117
|
-
const success = await
|
|
129
|
+
program.command("preview").argument("[event]", "Event type to preview (e.g., push, pr:open, schedule)").description("Preview which workflows match a trigger event (no execution)").option("--branch <name>", "Override target branch for trigger matching (default: main)").option("--sha <hash>", "Override commit SHA").option("--workflow <name>", "Filter to specific workflow in display").option("--job <name>", "Filter to specific job in display").option("--debug", "Verbose internals", false).option("--kici-dir <path>", "Path to .kici directory", ".kici").option("--files <path>", "Simulate changed file path for trigger matching (repeatable)", (val, prev) => [...prev, val], []).option("--secret <key=value>", "Inject flat secret (repeatable)", (val, prev) => [...prev, val], []).option("--context <ctx.key=value>", "Inject context secret (repeatable)", (val, prev) => [...prev, val], []).action(async (event, options) => {
|
|
130
|
+
const { previewCommand } = await import("./commands/index.js");
|
|
131
|
+
const success = await previewCommand(event, options);
|
|
118
132
|
process.exit(success ? 0 : 1);
|
|
119
133
|
});
|
|
120
134
|
program.command("init").description("Initialize .kici/ directory with default workflows").option("--force", "Overwrite existing .kici/ directory", false).option("--skip-install", "Create files without installing dependencies", false).option("--package-manager <npm|pnpm|yarn>", "Force a package manager for the install step (default: auto-detect)").option("--mjs", "JavaScript-only mode (no TypeScript, no dependencies)", false).option("--no-agents-md", "Skip writing .kici/AGENTS.md (LLM authoring context)").option("--private-registry <url>", "Scaffold a workflow registries: entry pointing at <url>").option("--private-registry-scope <scope>", "Optional npm package scope (e.g. @my-org) for the private registry").option("--private-registry-secret <ref>", "Qualified secret reference (env:NAME) the private registry token comes from", "production:NPM_TOKEN").addOption(new Option("--use-verdaccio-local").default(false).hideHelp()).action(async (options) => {
|
|
@@ -185,6 +199,16 @@ Environment variables:
|
|
|
185
199
|
const success = await secretsListCommand();
|
|
186
200
|
process.exit(success ? 0 : 1);
|
|
187
201
|
});
|
|
202
|
+
program.command("pat").description("Manage personal access tokens").command("create").description("Mint a personal access token (use --agent for a coding-agent token)").option("--name <name>", "Token name (defaults to the agent label)").option("--agent", "Mint an agent-kind PAT for the KiCI MCP server", false).option("--expires-in-days <n>", "Custom expiry in days", (v) => parseInt(v, 10)).action(async (options) => {
|
|
203
|
+
const { patCreateCommand } = await import("./commands/index.js");
|
|
204
|
+
const success = await patCreateCommand({
|
|
205
|
+
name: options.name,
|
|
206
|
+
agent: options.agent,
|
|
207
|
+
label: options.name,
|
|
208
|
+
expiresInDays: options.expiresInDays
|
|
209
|
+
});
|
|
210
|
+
process.exit(success ? 0 : 1);
|
|
211
|
+
});
|
|
188
212
|
const runsCommand = program.command("runs").description("Inspect and manage execution runs");
|
|
189
213
|
runsCommand.command("list").description("List execution runs (mirrors the dashboard Runs page)").option("--status <s>", "Filter by status").option("--workflow <w>", "Filter by workflow name").option("--branch <b>", "Filter by branch/ref").option("--repo <r>", "Filter by repository").option("--trigger <t>", "Filter by trigger type").option("--source <routingKey>", "Filter by source routing key").option("--since <ts>", "Only runs since (ISO-8601 or epoch ms)").option("--page <n>", "Page number", (v) => parseInt(v, 10)).option("--json", "Output raw JSON", false).action(async (options) => {
|
|
190
214
|
const { runsListCommand } = await import("./commands/index.js");
|
|
@@ -268,10 +292,10 @@ Environment variables:
|
|
|
268
292
|
const { docsCommand } = await import("./commands/index.js");
|
|
269
293
|
const success = await docsCommand({ open: options.open });
|
|
270
294
|
process.exit(success ? 0 : 1);
|
|
271
|
-
}).command("llm").description("Print
|
|
295
|
+
}).command("llm [topic]").description("Print KiCI LLM docs bundles. No topic prints the llms.txt index; <topic> prints a task bundle (e.g. sdk, cli, patterns, features, providers, architecture, getting-started); \"full\" prints the complete bundle.").option("--out <path>", "Write the bundle to a file instead of stdout").action(async (topic, options) => {
|
|
272
296
|
const { docsLlmCommand } = await import("./commands/index.js");
|
|
273
297
|
const success = await docsLlmCommand({
|
|
274
|
-
|
|
298
|
+
topic,
|
|
275
299
|
out: options.out
|
|
276
300
|
});
|
|
277
301
|
process.exit(success ? 0 : 1);
|
|
@@ -281,7 +305,7 @@ Environment variables:
|
|
|
281
305
|
const success = await drainWorkerCommand({ url: options.url });
|
|
282
306
|
process.exit(success ? 0 : 1);
|
|
283
307
|
});
|
|
284
|
-
program.command("verify-attestation").argument("[artifact]", "Artifact path to digest-check against the attestation subject (optional)").description("Verify a KiCI provenance attestation bundle offline").option("--bundle <path>", "Path or URL to the attestation bundle JSON").option("--trust-root <url-or-file>", "Trusted issuer URL, or a self-contained { issuer, jwks } file").option("--audience <aud>", "Expected token audience").option("--json", "Output structured JSON result", false).action(async (artifact, options) => {
|
|
308
|
+
program.command("verify-attestation").argument("[artifact]", "Artifact path to digest-check against the attestation subject (optional)").description("Verify a KiCI provenance attestation bundle offline").option("--bundle <path>", "Path or URL to the attestation bundle JSON").option("--trust-root <url-or-file>", "Trusted issuer URL, or a self-contained { issuer, jwks } file (default: hosted KiCI platform)").option("--audience <aud>", "Expected token audience").option("--json", "Output structured JSON result", false).action(async (artifact, options) => {
|
|
285
309
|
const { verifyAttestationCommand } = await import("./commands/index.js");
|
|
286
310
|
const success = await verifyAttestationCommand(artifact, options);
|
|
287
311
|
process.exit(success ? 0 : 1);
|
|
@@ -6,6 +6,12 @@ export interface CompileOptions {
|
|
|
6
6
|
check: boolean;
|
|
7
7
|
/** Verbose output */
|
|
8
8
|
verbose: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Suppress the success line on stdout (and the auto-types success line) so a
|
|
11
|
+
* caller emitting machine-readable output keeps stdout pure. Validation
|
|
12
|
+
* errors are still reported.
|
|
13
|
+
*/
|
|
14
|
+
quiet?: boolean;
|
|
9
15
|
}
|
|
10
16
|
/**
|
|
11
17
|
* Execute the compile command.
|
package/dist/commands/compile.js
CHANGED
|
@@ -76,7 +76,7 @@ async function compileCommand(options) {
|
|
|
76
76
|
const lockJson = serializeLockFile(generateLockFile(workflowsWithSource));
|
|
77
77
|
if (!options.check) {
|
|
78
78
|
await fs.writeFile(lockPath, lockJson, "utf-8");
|
|
79
|
-
logger.info(pc.green("✓") + ` Compiled workflows → .kici/kici.lock.json` + pc.dim(` (${workflowsWithSource.length} workflow${workflowsWithSource.length !== 1 ? "s" : ""})`));
|
|
79
|
+
if (!options.quiet) logger.info(pc.green("✓") + ` Compiled workflows → .kici/kici.lock.json` + pc.dim(` (${workflowsWithSource.length} workflow${workflowsWithSource.length !== 1 ? "s" : ""})`));
|
|
80
80
|
try {
|
|
81
81
|
const { loadGlobalConfig } = await import("../remote/config.js");
|
|
82
82
|
const config = await loadGlobalConfig();
|
|
@@ -84,12 +84,15 @@ async function compileCommand(options) {
|
|
|
84
84
|
const hasEndpoint = Boolean(config.platformEndpoint ?? config.endpoint);
|
|
85
85
|
if (hasToken && hasEndpoint && config.activeOrgId) {
|
|
86
86
|
const { typesCommand } = await import("./types.js");
|
|
87
|
-
await typesCommand({
|
|
87
|
+
await typesCommand({
|
|
88
|
+
kiciDir,
|
|
89
|
+
quiet: options.quiet
|
|
90
|
+
});
|
|
88
91
|
}
|
|
89
92
|
} catch {
|
|
90
93
|
logger.warn(pc.yellow("Could not refresh types (Platform unreachable). Compilation succeeded."));
|
|
91
94
|
}
|
|
92
|
-
} else logger.info(pc.green("✓") + ` Workflows are valid` + pc.dim(` (${workflowsWithSource.length} workflow${workflowsWithSource.length !== 1 ? "s" : ""})`));
|
|
95
|
+
} else if (!options.quiet) logger.info(pc.green("✓") + ` Workflows are valid` + pc.dim(` (${workflowsWithSource.length} workflow${workflowsWithSource.length !== 1 ? "s" : ""})`));
|
|
93
96
|
return true;
|
|
94
97
|
} catch (error) {
|
|
95
98
|
if (isCompilerError(error)) logger.error(formatError(error));
|
package/dist/commands/docs.d.ts
CHANGED
|
@@ -3,11 +3,11 @@ export interface DocsOptions {
|
|
|
3
3
|
open?: boolean;
|
|
4
4
|
}
|
|
5
5
|
export interface DocsLlmOptions {
|
|
6
|
-
/**
|
|
7
|
-
|
|
6
|
+
/** Task bundle id to print. Undefined → the llms.txt index; 'full' → llms-full.txt. */
|
|
7
|
+
topic?: string;
|
|
8
8
|
/** Override the bundled output destination (overrides default stdout). */
|
|
9
9
|
out?: string;
|
|
10
|
-
/** Override the directory holding llms
|
|
10
|
+
/** Override the directory holding the llms*.txt files (test seam). */
|
|
11
11
|
bundleDir?: string;
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
@@ -15,12 +15,12 @@ export interface DocsLlmOptions {
|
|
|
15
15
|
*/
|
|
16
16
|
export declare function docsCommand(options?: DocsOptions): Promise<boolean>;
|
|
17
17
|
/**
|
|
18
|
-
* Print
|
|
18
|
+
* Print a KiCI LLM docs bundle to stdout (or a file).
|
|
19
19
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* brief
|
|
20
|
+
* No topic prints the llms.txt index (a router listing every task bundle).
|
|
21
|
+
* A topic prints that task bundle (e.g. `sdk`, `cli`, `patterns`); `full`
|
|
22
|
+
* prints the everything-bundle. Pipe straight into a coding agent's context
|
|
23
|
+
* to brief it on KiCI authoring without an internet round-trip.
|
|
24
24
|
*/
|
|
25
25
|
export declare function docsLlmCommand(options?: DocsLlmOptions): Promise<boolean>;
|
|
26
26
|
//# sourceMappingURL=docs.d.ts.map
|
package/dist/commands/docs.js
CHANGED
|
@@ -2,12 +2,24 @@ import "../chunk-BTugEXQM.js";
|
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import pc from "picocolors";
|
|
5
|
-
import { readFile, writeFile } from "node:fs/promises";
|
|
5
|
+
import { readFile, readdir, writeFile } from "node:fs/promises";
|
|
6
6
|
import { logger, toErrorMessage } from "@kici-dev/core";
|
|
7
7
|
import open from "open";
|
|
8
8
|
//#region src/commands/docs.ts
|
|
9
9
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
10
|
const DOCS_HOME_URL = "https://kici.dev/docs/";
|
|
11
|
+
function bundleFilenameForTopic(topic) {
|
|
12
|
+
if (!topic) return "llms.txt";
|
|
13
|
+
if (topic === "full") return "llms-full.txt";
|
|
14
|
+
return `llms-${topic}.txt`;
|
|
15
|
+
}
|
|
16
|
+
async function availableTopics(bundleDir) {
|
|
17
|
+
try {
|
|
18
|
+
return [...(await readdir(bundleDir)).filter((n) => n.startsWith("llms-") && n.endsWith(".txt") && n !== "llms-full.txt").map((n) => n.slice(5, -4)).sort(), "full"];
|
|
19
|
+
} catch {
|
|
20
|
+
return ["full"];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
11
23
|
/**
|
|
12
24
|
* Open the published documentation site in the user's default browser.
|
|
13
25
|
*/
|
|
@@ -27,32 +39,39 @@ async function docsCommand(options = {}) {
|
|
|
27
39
|
}
|
|
28
40
|
}
|
|
29
41
|
/**
|
|
30
|
-
* Print
|
|
42
|
+
* Print a KiCI LLM docs bundle to stdout (or a file).
|
|
31
43
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* brief
|
|
44
|
+
* No topic prints the llms.txt index (a router listing every task bundle).
|
|
45
|
+
* A topic prints that task bundle (e.g. `sdk`, `cli`, `patterns`); `full`
|
|
46
|
+
* prints the everything-bundle. Pipe straight into a coding agent's context
|
|
47
|
+
* to brief it on KiCI authoring without an internet round-trip.
|
|
36
48
|
*/
|
|
37
49
|
async function docsLlmCommand(options = {}) {
|
|
38
|
-
const filename = options.
|
|
50
|
+
const filename = bundleFilenameForTopic(options.topic);
|
|
39
51
|
const bundleDir = options.bundleDir ?? path.join(__dirname, "..", "llm-context");
|
|
40
52
|
const bundlePath = path.join(bundleDir, filename);
|
|
53
|
+
let content;
|
|
41
54
|
try {
|
|
42
|
-
|
|
43
|
-
if (options.out) {
|
|
44
|
-
await writeFile(options.out, content, "utf-8");
|
|
45
|
-
logger.info(pc.gray(`Wrote ${filename} to ${options.out}`));
|
|
46
|
-
return true;
|
|
47
|
-
}
|
|
48
|
-
process.stdout.write(content);
|
|
49
|
-
if (!content.endsWith("\n")) process.stdout.write("\n");
|
|
50
|
-
return true;
|
|
55
|
+
content = await readFile(bundlePath, "utf-8");
|
|
51
56
|
} catch (error) {
|
|
57
|
+
if (options.topic && options.topic !== "full") {
|
|
58
|
+
const topics = await availableTopics(bundleDir);
|
|
59
|
+
logger.error(pc.red(`Unknown docs bundle "${options.topic}".`));
|
|
60
|
+
logger.info(pc.gray(`Available topics: ${topics.join(", ")} (no topic prints the index).`));
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
52
63
|
logger.error(pc.red(`Error reading bundled ${filename}: ${toErrorMessage(error)}`));
|
|
53
64
|
logger.info(pc.gray("The bundle ships with the @kici-dev/compiler package. If you built the package locally, run `pnpm build` in packages/compiler/."));
|
|
54
65
|
return false;
|
|
55
66
|
}
|
|
67
|
+
if (options.out) {
|
|
68
|
+
await writeFile(options.out, content, "utf-8");
|
|
69
|
+
logger.info(pc.gray(`Wrote ${filename} to ${options.out}`));
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
process.stdout.write(content);
|
|
73
|
+
if (!content.endsWith("\n")) process.stdout.write("\n");
|
|
74
|
+
return true;
|
|
56
75
|
}
|
|
57
76
|
//#endregion
|
|
58
77
|
export { docsCommand, docsLlmCommand };
|
package/dist/commands/index.d.ts
CHANGED
|
@@ -3,8 +3,8 @@ export type { CompileOptions } from './compile.js';
|
|
|
3
3
|
export { watchCommand } from './watch.js';
|
|
4
4
|
export { fixtureCommand } from './fixture.js';
|
|
5
5
|
export type { FixtureOptions } from './fixture.js';
|
|
6
|
-
export {
|
|
7
|
-
export type {
|
|
6
|
+
export { previewCommand, previewEvent } from './preview.js';
|
|
7
|
+
export type { PreviewOptions, RemoteRunOptions, RemoteRunResult } from './preview.js';
|
|
8
8
|
export { runLocalCommand, runRemoteCommand } from './run.js';
|
|
9
9
|
export { initCommand } from './init.js';
|
|
10
10
|
export type { InitOptions } from './init.js';
|
|
@@ -14,6 +14,8 @@ export { loginCommand } from './login.js';
|
|
|
14
14
|
export type { LoginOptions } from './login.js';
|
|
15
15
|
export { secretsListCommand } from './secrets-list.js';
|
|
16
16
|
export type { SecretsListOptions } from './secrets-list.js';
|
|
17
|
+
export { patCreateCommand } from './pat.js';
|
|
18
|
+
export type { PatCreateOptions } from './pat.js';
|
|
17
19
|
export { runsListCommand } from './runs/list.js';
|
|
18
20
|
export type { RunsListOptions } from './runs/list.js';
|
|
19
21
|
export { runsShowCommand } from './runs/show.js';
|
package/dist/commands/index.js
CHANGED
|
@@ -8,11 +8,12 @@ import { endpointsCommand } from "./endpoints.js";
|
|
|
8
8
|
import { fixtureCommand } from "./fixture.js";
|
|
9
9
|
import { hookInstallCommand } from "./hook.js";
|
|
10
10
|
import { watchCommand } from "./watch.js";
|
|
11
|
-
import {
|
|
11
|
+
import { previewCommand, previewEvent } from "./preview.js";
|
|
12
12
|
import { runLocalCommand, runRemoteCommand } from "./run.js";
|
|
13
13
|
import { initCommand } from "./init.js";
|
|
14
14
|
import { loginCommand } from "./login.js";
|
|
15
15
|
import { secretsListCommand } from "./secrets-list.js";
|
|
16
|
+
import { patCreateCommand } from "./pat.js";
|
|
16
17
|
import { runsListCommand } from "./runs/list.js";
|
|
17
18
|
import { runsShowCommand } from "./runs/show.js";
|
|
18
19
|
import { runsLogsCommand } from "./runs/logs.js";
|
|
@@ -25,4 +26,4 @@ import { logoutCommand } from "./logout.js";
|
|
|
25
26
|
import { rejectCommand } from "./reject.js";
|
|
26
27
|
import { workflowsListCommand } from "./workflows.js";
|
|
27
28
|
import { verifyAttestationCommand } from "./verify-attestation.js";
|
|
28
|
-
export { approveCommand, compileCommand, diagnosticsCommand, docsCommand, docsLlmCommand, drainWorkerCommand, endpointsCommand, fixtureCommand, hookInstallCommand, initCommand, loginCommand, logoutCommand, orchestratorsListCommand, orchestratorsUseCommand, orgCurrentCommand, orgListCommand, orgUseCommand, rejectCommand, runLocalCommand, runRemoteCommand, runsCancelCommand, runsListCommand, runsLogsCommand, runsRerunCommand, runsShowCommand, secretsListCommand,
|
|
29
|
+
export { approveCommand, compileCommand, diagnosticsCommand, docsCommand, docsLlmCommand, drainWorkerCommand, endpointsCommand, fixtureCommand, hookInstallCommand, initCommand, loginCommand, logoutCommand, orchestratorsListCommand, orchestratorsUseCommand, orgCurrentCommand, orgListCommand, orgUseCommand, patCreateCommand, previewCommand, previewEvent, rejectCommand, runLocalCommand, runRemoteCommand, runsCancelCommand, runsListCommand, runsLogsCommand, runsRerunCommand, runsShowCommand, secretsListCommand, typesCommand, verifyAttestationCommand, watchCommand, workflowsListCommand };
|
package/dist/commands/init.js
CHANGED
|
@@ -117,10 +117,10 @@ async function initCommand(options = {}) {
|
|
|
117
117
|
logger.info(pc.gray(" 1. Edit workflows in .kici/workflows/"));
|
|
118
118
|
if (options.mjs || options.skipInstall) {
|
|
119
119
|
logger.info(pc.gray(" 2. Run your package manager install in .kici/ to generate a lockfile"));
|
|
120
|
-
logger.info(pc.gray(" 3.
|
|
120
|
+
logger.info(pc.gray(" 3. Preview matching: kici preview push"));
|
|
121
121
|
logger.info(pc.gray(" 4. Commit .kici/ to your repository\n"));
|
|
122
122
|
} else {
|
|
123
|
-
logger.info(pc.gray(" 2.
|
|
123
|
+
logger.info(pc.gray(" 2. Preview matching: kici preview push"));
|
|
124
124
|
logger.info(pc.gray(" 3. Commit .kici/ to your repository\n"));
|
|
125
125
|
}
|
|
126
126
|
return true;
|
package/dist/commands/org.js
CHANGED
|
@@ -65,9 +65,9 @@ async function orgListCommand() {
|
|
|
65
65
|
const isActive = org.id === config.activeOrgId;
|
|
66
66
|
const marker = isActive ? pc.green("* ") : " ";
|
|
67
67
|
const name = isActive ? pc.bold(org.displayName) : org.displayName;
|
|
68
|
-
const
|
|
68
|
+
const ownership = pc.gray(`(${org.isOwner ? "owner" : "member"})`);
|
|
69
69
|
const id = pc.gray(org.id);
|
|
70
|
-
console.log(` ${marker}${name.padEnd(nameWidth)} ${
|
|
70
|
+
console.log(` ${marker}${name.padEnd(nameWidth)} ${ownership} ${id}`);
|
|
71
71
|
}
|
|
72
72
|
console.log("");
|
|
73
73
|
return true;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface PatCreateOptions {
|
|
2
|
+
/** Token name shown in the dashboard PAT list. Defaults to the agent label. */
|
|
3
|
+
name?: string;
|
|
4
|
+
/** Mint an agent-kind PAT (the only credential the developer MCP server accepts). */
|
|
5
|
+
agent?: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Agent label (required with `--agent`) — the human-set name recorded on every
|
|
8
|
+
* audit row the agent produces. Also used as the token name when `--name` is
|
|
9
|
+
* omitted.
|
|
10
|
+
*/
|
|
11
|
+
label?: string;
|
|
12
|
+
/** Custom expiry in days (server default: 120). */
|
|
13
|
+
expiresInDays?: number;
|
|
14
|
+
/** Injected fetch for tests. Defaults to the global fetch. */
|
|
15
|
+
fetchImpl?: typeof fetch;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Mint a personal access token under the logged-in user's identity.
|
|
19
|
+
*
|
|
20
|
+
* `kici pat create --agent --name <label>` mints an agent-kind PAT: it inherits
|
|
21
|
+
* the user's permissions (provenance only, no authority change), carries its
|
|
22
|
+
* label into every audit row, and is the credential a coding agent points the
|
|
23
|
+
* KiCI developer MCP server at. The token is printed once — there is no way to
|
|
24
|
+
* retrieve it later.
|
|
25
|
+
*/
|
|
26
|
+
export declare function patCreateCommand(options?: PatCreateOptions): Promise<boolean>;
|
|
27
|
+
//# sourceMappingURL=pat.d.ts.map
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import "../chunk-BTugEXQM.js";
|
|
2
|
+
import { loadGlobalConfig } from "../remote/config.js";
|
|
3
|
+
import pc from "picocolors";
|
|
4
|
+
import { toErrorMessage } from "@kici-dev/core";
|
|
5
|
+
import { PatKind } from "@kici-dev/engine";
|
|
6
|
+
//#region src/commands/pat.ts
|
|
7
|
+
/**
|
|
8
|
+
* Mint a personal access token under the logged-in user's identity.
|
|
9
|
+
*
|
|
10
|
+
* `kici pat create --agent --name <label>` mints an agent-kind PAT: it inherits
|
|
11
|
+
* the user's permissions (provenance only, no authority change), carries its
|
|
12
|
+
* label into every audit row, and is the credential a coding agent points the
|
|
13
|
+
* KiCI developer MCP server at. The token is printed once — there is no way to
|
|
14
|
+
* retrieve it later.
|
|
15
|
+
*/
|
|
16
|
+
async function patCreateCommand(options = {}) {
|
|
17
|
+
const doFetch = options.fetchImpl ?? fetch;
|
|
18
|
+
try {
|
|
19
|
+
const config = await loadGlobalConfig();
|
|
20
|
+
const token = config.pat ?? config.token;
|
|
21
|
+
const endpoint = config.platformEndpoint ?? config.endpoint;
|
|
22
|
+
if (!token || !endpoint) {
|
|
23
|
+
console.error(pc.red("Not logged in. Run `kici login` first."));
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
const kind = options.agent ? PatKind.enum.agent : PatKind.enum.user;
|
|
27
|
+
const label = options.label;
|
|
28
|
+
if (kind === PatKind.enum.agent && !label) {
|
|
29
|
+
console.error(pc.red("An agent PAT requires a label. Pass --name <label>."));
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
const name = options.name ?? label;
|
|
33
|
+
if (!name) {
|
|
34
|
+
console.error(pc.red("A token name is required. Pass --name <name>."));
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
const body = {
|
|
38
|
+
name,
|
|
39
|
+
kind
|
|
40
|
+
};
|
|
41
|
+
if (kind === PatKind.enum.agent) body.agentLabel = label;
|
|
42
|
+
if (options.expiresInDays !== void 0) body.expiresInDays = options.expiresInDays;
|
|
43
|
+
const res = await doFetch(`${endpoint.replace(/\/$/, "")}/api/v1/pats`, {
|
|
44
|
+
method: "POST",
|
|
45
|
+
headers: {
|
|
46
|
+
"Content-Type": "application/json",
|
|
47
|
+
Authorization: `Bearer ${token}`
|
|
48
|
+
},
|
|
49
|
+
body: JSON.stringify(body)
|
|
50
|
+
});
|
|
51
|
+
if (!res.ok) {
|
|
52
|
+
let detail;
|
|
53
|
+
try {
|
|
54
|
+
detail = (await res.json()).error;
|
|
55
|
+
} catch {}
|
|
56
|
+
console.error(pc.red(`Failed to create token (${res.status}): ${detail ?? "request failed"}`));
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
const created = await res.json();
|
|
60
|
+
console.log(pc.bold(kind === PatKind.enum.agent ? "\nAgent PAT created.\n" : "\nPAT created.\n"));
|
|
61
|
+
console.log(`${pc.gray("Name: ")}${created.name}`);
|
|
62
|
+
if (kind === PatKind.enum.agent) console.log(`${pc.gray("Agent: ")}${label}`);
|
|
63
|
+
console.log(`${pc.gray("Expires:")} ${created.expiresAt}`);
|
|
64
|
+
console.log(`\n${pc.gray("Token (shown once — save it now):")}`);
|
|
65
|
+
console.log(pc.cyan(created.token));
|
|
66
|
+
if (kind === PatKind.enum.agent) console.log(pc.gray("\nPoint your coding agent at the KiCI MCP server with this token as the Bearer credential."));
|
|
67
|
+
return true;
|
|
68
|
+
} catch (err) {
|
|
69
|
+
console.error(pc.red(`Failed to create token: ${toErrorMessage(err)}`));
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
//#endregion
|
|
74
|
+
export { patCreateCommand };
|
|
75
|
+
|
|
76
|
+
//# sourceMappingURL=pat.js.map
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { type PayloadOptions } from '../test-runner/payload-builder.js';
|
|
2
|
+
import { type CheckMode } from '@kici-dev/engine';
|
|
3
|
+
/** Options for the kici preview command (dry-run trigger preview) */
|
|
4
|
+
export interface PreviewOptions extends PayloadOptions {
|
|
5
|
+
/** Filter to specific workflow */
|
|
6
|
+
workflow?: string;
|
|
7
|
+
/** Filter to specific job */
|
|
8
|
+
job?: string;
|
|
9
|
+
/** Enable debug output */
|
|
10
|
+
debug?: boolean;
|
|
11
|
+
/** Path to .kici directory (defaults to .kici) */
|
|
12
|
+
kiciDir?: string;
|
|
13
|
+
/** Flat secret overrides: KEY=VALUE */
|
|
14
|
+
secret?: string[];
|
|
15
|
+
/** Context secret overrides: contextName.KEY=VALUE */
|
|
16
|
+
context?: string[];
|
|
17
|
+
}
|
|
18
|
+
/** Options for the kici run remote command */
|
|
19
|
+
export interface RemoteRunOptions extends PreviewOptions {
|
|
20
|
+
/** Run all available fixtures */
|
|
21
|
+
all?: boolean;
|
|
22
|
+
/** Interactively pick fixtures to run (multi-select checkbox). */
|
|
23
|
+
pick?: boolean;
|
|
24
|
+
/** Run matching fixtures concurrently */
|
|
25
|
+
parallel?: boolean;
|
|
26
|
+
/** Fire and forget (print runIds, don't stream) */
|
|
27
|
+
wait?: boolean;
|
|
28
|
+
/** Suppress output except final result */
|
|
29
|
+
quiet?: boolean;
|
|
30
|
+
/** Output structured JSON result */
|
|
31
|
+
json?: boolean;
|
|
32
|
+
/** Output JUnit XML result */
|
|
33
|
+
junit?: string;
|
|
34
|
+
/** Override routing key for this run */
|
|
35
|
+
routingKey?: string;
|
|
36
|
+
/** Show recent run history */
|
|
37
|
+
history?: boolean;
|
|
38
|
+
/** --env KEY=VALUE flag values, uploaded as per-run secrets. */
|
|
39
|
+
envFlags?: string[];
|
|
40
|
+
/** Target organization id (overrides config.activeOrgId). */
|
|
41
|
+
org?: string;
|
|
42
|
+
/** Target orchestrator cluster name (overrides the per-org default). */
|
|
43
|
+
orchestrator?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Run mode resolved from --check / --fail-on-drift, threaded onto the dispatch
|
|
46
|
+
* payload so the orchestrator runs the agent step loop in the requested mode.
|
|
47
|
+
* Defaults to `apply`.
|
|
48
|
+
*/
|
|
49
|
+
checkMode?: CheckMode;
|
|
50
|
+
/** `--target <selector>` values (repeatable), AND-combined into host narrowing. */
|
|
51
|
+
targets?: string[];
|
|
52
|
+
/** `--target-allow-empty`: a target that zeroes a runsOnAll job skips it instead of failing. */
|
|
53
|
+
targetAllowEmpty?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* `--approve-all` (alias `--yes`): auto-approve every approval gate this run
|
|
56
|
+
* holds on (run-scoped only — the run id this invocation dispatched). The
|
|
57
|
+
* operator must still be clause-eligible per hold; an ineligible hold blocks.
|
|
58
|
+
*/
|
|
59
|
+
approveAll?: boolean;
|
|
60
|
+
/** `--input KEY=VALUE` values (repeatable): typed workflow-dispatch inputs. */
|
|
61
|
+
inputs?: string[];
|
|
62
|
+
}
|
|
63
|
+
/** Result of a single remote fixture run */
|
|
64
|
+
export interface RemoteRunResult {
|
|
65
|
+
fixtureId: string;
|
|
66
|
+
runId: string;
|
|
67
|
+
status: 'accepted' | 'rejected' | 'success' | 'failed' | 'cancelled' | 'error';
|
|
68
|
+
reason?: string;
|
|
69
|
+
observeUrl?: string;
|
|
70
|
+
durationMs?: number;
|
|
71
|
+
jobs?: Array<{
|
|
72
|
+
name: string;
|
|
73
|
+
status: string;
|
|
74
|
+
durationMs?: number;
|
|
75
|
+
}>;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Main preview command entry point.
|
|
79
|
+
*
|
|
80
|
+
* `kici preview <event>` is a dry-run trigger preview only — it executes nothing.
|
|
81
|
+
* If the argument looks like a fixture name (not a known event type), prints a migration message.
|
|
82
|
+
*/
|
|
83
|
+
export declare function previewCommand(event: string | undefined, options: PreviewOptions): Promise<boolean>;
|
|
84
|
+
/**
|
|
85
|
+
* Local-only dry-run mode: compile workflows, match triggers, display what would execute.
|
|
86
|
+
*/
|
|
87
|
+
export declare function previewEvent(event: string, options: PreviewOptions): Promise<boolean>;
|
|
88
|
+
//# sourceMappingURL=preview.d.ts.map
|
|
@@ -9,30 +9,31 @@ import { loadSecretsFile } from "../test-runner/secrets-file.js";
|
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import pc from "picocolors";
|
|
11
11
|
import { readFile } from "node:fs/promises";
|
|
12
|
+
import { flattenStepInputs } from "@kici-dev/sdk";
|
|
12
13
|
import { logger, toErrorMessage } from "@kici-dev/core";
|
|
13
14
|
import { matchAllWorkflows } from "@kici-dev/engine";
|
|
14
15
|
import { normalizeRunsOnToMatchers } from "@kici-dev/engine/labels/compile";
|
|
15
|
-
//#region src/commands/
|
|
16
|
+
//#region src/commands/preview.ts
|
|
16
17
|
/**
|
|
17
|
-
* Main
|
|
18
|
+
* Main preview command entry point.
|
|
18
19
|
*
|
|
19
|
-
* `kici
|
|
20
|
+
* `kici preview <event>` is a dry-run trigger preview only — it executes nothing.
|
|
20
21
|
* If the argument looks like a fixture name (not a known event type), prints a migration message.
|
|
21
22
|
*/
|
|
22
|
-
async function
|
|
23
|
+
async function previewCommand(event, options) {
|
|
23
24
|
if (options.debug) {
|
|
24
25
|
process.env.KICI_DEBUG = "true";
|
|
25
26
|
logger.info(pc.gray("Debug mode enabled"));
|
|
26
27
|
}
|
|
27
28
|
try {
|
|
28
29
|
if (!event) {
|
|
29
|
-
logger.info(pc.bold("\nUsage: kici
|
|
30
|
+
logger.info(pc.bold("\nUsage: kici preview <event>\n"));
|
|
30
31
|
logger.info(pc.gray("Preview which workflows and jobs would run for a given event.\n"));
|
|
31
32
|
logger.info(pc.gray("Examples:"));
|
|
32
|
-
logger.info(pc.gray(" kici
|
|
33
|
-
logger.info(pc.gray(" kici
|
|
34
|
-
logger.info(pc.gray(" kici
|
|
35
|
-
logger.info(pc.gray(" kici
|
|
33
|
+
logger.info(pc.gray(" kici preview push"));
|
|
34
|
+
logger.info(pc.gray(" kici preview pr:open"));
|
|
35
|
+
logger.info(pc.gray(" kici preview schedule"));
|
|
36
|
+
logger.info(pc.gray(" kici preview lifecycle:workflow_complete\n"));
|
|
36
37
|
logger.info(pc.gray("For remote fixture execution, use: kici run remote [fixture] [options]"));
|
|
37
38
|
logger.info(pc.gray("For local workflow execution, use: kici run local <event> [options]\n"));
|
|
38
39
|
return true;
|
|
@@ -41,7 +42,7 @@ async function testCommand(event, options) {
|
|
|
41
42
|
logger.info(pc.yellow(`\nFixture-based testing has moved to \`kici run remote\`.\nRun \`kici run remote ${event}\` instead.\n`));
|
|
42
43
|
return false;
|
|
43
44
|
}
|
|
44
|
-
return await
|
|
45
|
+
return await previewEvent(event, options);
|
|
45
46
|
} catch (error) {
|
|
46
47
|
const message = toErrorMessage(error);
|
|
47
48
|
logger.error(pc.red(`\nError: ${message}\n`));
|
|
@@ -64,7 +65,7 @@ function isKnownEventArg(arg) {
|
|
|
64
65
|
/**
|
|
65
66
|
* Local-only dry-run mode: compile workflows, match triggers, display what would execute.
|
|
66
67
|
*/
|
|
67
|
-
async function
|
|
68
|
+
async function previewEvent(event, options) {
|
|
68
69
|
try {
|
|
69
70
|
const kiciDir = resolveKiciDir(options.kiciDir);
|
|
70
71
|
logger.info(pc.gray(`KiCI directory: ${kiciDir}`));
|
|
@@ -144,7 +145,7 @@ function workflowsToLockFormat(workflows) {
|
|
|
144
145
|
if ("group" in n) return `__group:${n.group}`;
|
|
145
146
|
return n.name;
|
|
146
147
|
}) ?? [],
|
|
147
|
-
steps: j.steps.map((s) => {
|
|
148
|
+
steps: flattenStepInputs(j.steps).map((s) => {
|
|
148
149
|
if (typeof s === "function") return {
|
|
149
150
|
name: "",
|
|
150
151
|
hasOutputs: false
|
|
@@ -213,6 +214,6 @@ async function loadTestSecrets(kiciDir, secretFlags, contextFlags) {
|
|
|
213
214
|
return secrets;
|
|
214
215
|
}
|
|
215
216
|
//#endregion
|
|
216
|
-
export {
|
|
217
|
+
export { previewCommand, previewEvent };
|
|
217
218
|
|
|
218
|
-
//# sourceMappingURL=
|
|
219
|
+
//# sourceMappingURL=preview.js.map
|