@kici-dev/compiler 0.1.26 → 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-banner.d.ts +6 -3
- package/dist/cli-banner.js +13 -5
- package/dist/cli.js +180 -48
- package/dist/commands/check-mode.d.ts +1 -1
- package/dist/commands/compile.js +31 -7
- 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 +13 -1
- package/dist/commands/index.js +10 -3
- 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 +160 -37
- package/dist/commands/local-trust-root.d.ts +6 -0
- package/dist/commands/local-trust-root.js +52 -0
- package/dist/commands/local.d.ts +65 -0
- package/dist/commands/local.js +206 -0
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.js +41 -1
- package/dist/commands/logout.js +7 -0
- package/dist/commands/notifications.d.ts +61 -0
- package/dist/commands/notifications.js +274 -0
- package/dist/commands/preview.js +9 -2
- package/dist/commands/run-banner.d.ts +31 -0
- package/dist/commands/run-banner.js +25 -0
- package/dist/commands/run-routed.d.ts +53 -0
- package/dist/commands/run-routed.js +185 -0
- package/dist/commands/run.d.ts +0 -17
- package/dist/commands/run.js +44 -58
- 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/secrets-list.d.ts +2 -2
- package/dist/commands/secrets-list.js +4 -4
- package/dist/commands/types.d.ts +3 -3
- package/dist/commands/types.js +4 -4
- 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 +32 -12
- package/dist/fixtures/defaults/index.js +2 -1
- package/dist/generators/secrets-dts.d.ts +9 -9
- package/dist/generators/secrets-dts.js +12 -12
- package/dist/llm-context/llms-architecture.txt +50 -21
- package/dist/llm-context/llms-cli.txt +2667 -1454
- package/dist/llm-context/llms-features.txt +484 -414
- package/dist/llm-context/llms-full.txt +6703 -4687
- package/dist/llm-context/llms-getting-started.txt +311 -55
- package/dist/llm-context/llms-patterns.txt +17 -29
- package/dist/llm-context/llms-providers.txt +10 -1
- package/dist/llm-context/llms-sdk-runtime.txt +2013 -0
- package/dist/llm-context/llms-sdk.txt +596 -2157
- package/dist/llm-context/llms.txt +31 -17
- package/dist/local-plane/orchestrator-process.d.ts +70 -0
- package/dist/local-plane/orchestrator-process.js +129 -0
- 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/paths.d.ts +39 -0
- package/dist/local-plane/paths.js +54 -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 +193 -0
- package/dist/local-plane/plane-manager.js +480 -0
- package/dist/local-plane/plane-seed.d.ts +76 -0
- package/dist/local-plane/plane-seed.js +59 -0
- package/dist/local-plane/plane-trigger.d.ts +71 -0
- package/dist/local-plane/plane-trigger.js +110 -0
- package/dist/local-plane/platform-attach.d.ts +53 -0
- package/dist/local-plane/platform-attach.js +107 -0
- 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 +56 -0
- package/dist/local-plane/postgres.js +187 -0
- package/dist/local-plane/resolve-plane.d.ts +37 -0
- package/dist/local-plane/resolve-plane.js +76 -0
- package/dist/local-plane/run-follow.d.ts +61 -0
- package/dist/local-plane/run-follow.js +151 -0
- package/dist/local-plane/scaler-config.d.ts +68 -0
- package/dist/local-plane/scaler-config.js +132 -0
- package/dist/local-plane/secret-seed.d.ts +59 -0
- package/dist/local-plane/secret-seed.js +112 -0
- package/dist/local-plane/source-provider.d.ts +43 -0
- package/dist/local-plane/source-provider.js +159 -0
- package/dist/local-plane/trusted-routing.d.ts +32 -0
- package/dist/local-plane/trusted-routing.js +47 -0
- package/dist/lockfile/generator.d.ts +14 -1
- package/dist/lockfile/generator.js +103 -37
- 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 +46 -9
- package/dist/remote/dashboard-client.js +54 -11
- 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/platform-client.d.ts +1 -1
- package/dist/remote/render.js +30 -9
- package/dist/{local-executor → remote}/secret-loader.d.ts +1 -1
- package/dist/{local-executor → remote}/secret-loader.js +4 -4
- package/dist/remote/secret-upload.d.ts +1 -1
- package/dist/remote/secret-upload.js +2 -2
- package/dist/remote/uploader.d.ts +1 -1
- package/dist/remote/uploader.js +7 -6
- package/dist/templates/agents-md.d.ts +1 -1
- package/dist/templates/agents-md.js +8 -8
- 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 +82 -44
- 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/{local-executor → test-runner}/runs-on-display.js +1 -1
- package/dist/test-runner/step-context.d.ts +23 -5
- package/dist/test-runner/step-context.js +29 -119
- package/dist/types.d.ts +26 -7
- 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 +13 -13
- package/sbom.spdx.json +9311 -1528
- 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/dag-scheduler.js +0 -183
- package/dist/local-executor/index.d.ts +0 -23
- package/dist/local-executor/index.js +0 -378
- package/dist/local-executor/job-runner.d.ts +0 -47
- package/dist/local-executor/job-runner.js +0 -411
- package/dist/local-executor/materializer.d.ts +0 -44
- package/dist/local-executor/materializer.js +0 -132
- package/dist/local-executor/output-streamer.d.ts +0 -31
- package/dist/local-executor/output-streamer.js +0 -168
- package/dist/local-executor/payload-generator.d.ts +0 -16
- package/dist/local-executor/payload-generator.js +0 -138
- package/dist/local-executor/picker.d.ts +0 -33
- package/dist/local-executor/picker.js +0 -109
- package/dist/local-executor/to-event-payload.d.ts +0 -16
- package/dist/local-executor/to-event-payload.js +0 -21
- package/dist/local-executor/types.d.ts +0 -93
- package/dist/local-executor/types.js +0 -2
- package/dist/local-executor/workflow-lock.d.ts +0 -82
- package/dist/local-executor/workflow-lock.js +0 -0
- 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
- /package/dist/{local-executor → test-runner}/runs-on-display.d.ts +0 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import "../rolldown-runtime-ClRpJifh.js";
|
|
2
|
+
import { analyzePurity } from "./purity-analyzer.js";
|
|
3
|
+
//#region src/lockfile/purity-diagnostics.ts
|
|
4
|
+
/** Which dynamic-value slot on a job carried the impure function. */
|
|
5
|
+
let DynamicValueField = /* @__PURE__ */ function(DynamicValueField) {
|
|
6
|
+
DynamicValueField["Context"] = "context";
|
|
7
|
+
DynamicValueField["Env"] = "env";
|
|
8
|
+
DynamicValueField["ConcurrencyGroup"] = "concurrencyGroup";
|
|
9
|
+
return DynamicValueField;
|
|
10
|
+
}({});
|
|
11
|
+
function pushIfImpure(out, fn, field, base) {
|
|
12
|
+
if (typeof fn !== "function") return;
|
|
13
|
+
const result = analyzePurity(fn.toString());
|
|
14
|
+
if (!result.pure) out.push({
|
|
15
|
+
...base,
|
|
16
|
+
field,
|
|
17
|
+
reason: result.reason ?? "unknown"
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Analyze a single static job's dynamic-value functions (context(s), env,
|
|
22
|
+
* concurrencyGroup) for impurity. Returns one warning per impure function.
|
|
23
|
+
*/
|
|
24
|
+
function analyzeJobPurity(job, workflowName, sourceFile) {
|
|
25
|
+
const out = [];
|
|
26
|
+
const base = {
|
|
27
|
+
workflowName,
|
|
28
|
+
sourceFile,
|
|
29
|
+
jobName: job.name
|
|
30
|
+
};
|
|
31
|
+
const contextRefs = job.contexts ?? (job.context !== void 0 ? [job.context] : void 0);
|
|
32
|
+
if (contextRefs) for (const ref of contextRefs) pushIfImpure(out, ref, "context", base);
|
|
33
|
+
pushIfImpure(out, job.env, "env", base);
|
|
34
|
+
pushIfImpure(out, job.concurrencyGroup, "concurrencyGroup", base);
|
|
35
|
+
return out;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Walk every workflow's static jobs and collect impurity warnings. Function-typed
|
|
39
|
+
* jobs (dynamic job generators) are skipped — their purity is analyzed at dispatch.
|
|
40
|
+
*/
|
|
41
|
+
function collectWorkflowPurityWarnings(workflows) {
|
|
42
|
+
const out = [];
|
|
43
|
+
for (const { workflow, source } of workflows) for (const job of workflow.jobs) {
|
|
44
|
+
if (typeof job === "function") continue;
|
|
45
|
+
out.push(...analyzeJobPurity(job, workflow.name, source.file));
|
|
46
|
+
}
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
50
|
+
export { DynamicValueField, analyzeJobPurity, collectWorkflowPurityWarnings };
|
|
51
|
+
|
|
52
|
+
//# sourceMappingURL=purity-diagnostics.js.map
|
package/dist/postinstall.js
CHANGED
|
@@ -4,6 +4,7 @@ import path from "node:path";
|
|
|
4
4
|
import { readFile } from "node:fs/promises";
|
|
5
5
|
import { spawn } from "node:child_process";
|
|
6
6
|
import { confirm } from "@inquirer/prompts";
|
|
7
|
+
import { isCiEnvironment } from "@kici-dev/core/ci-env";
|
|
7
8
|
//#region src/postinstall.ts
|
|
8
9
|
/**
|
|
9
10
|
* Post-install script for @kici-dev/compiler
|
|
@@ -33,7 +34,7 @@ async function detectDevelopmentMode() {
|
|
|
33
34
|
}
|
|
34
35
|
async function main() {
|
|
35
36
|
if (await detectDevelopmentMode()) return;
|
|
36
|
-
if (
|
|
37
|
+
if (isCiEnvironment() || !process.stdout.isTTY) return;
|
|
37
38
|
const fs = await import("node:fs/promises");
|
|
38
39
|
try {
|
|
39
40
|
await fs.access(".kici");
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Sub-directory of the destination that home-anchored entries land under. */
|
|
2
|
+
export declare const HOME_SUBDIR = "~home";
|
|
3
|
+
/**
|
|
4
|
+
* Extract an artifact tarball under `destDir`, relocating the anchor groups so
|
|
5
|
+
* nothing escapes the destination.
|
|
6
|
+
*/
|
|
7
|
+
export declare function extractArtifactTarball(tarball: Buffer, destDir: string): Promise<void>;
|
|
8
|
+
//# sourceMappingURL=artifact-extract.d.ts.map
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import "../rolldown-runtime-ClRpJifh.js";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { cp, mkdir, readdir } from "node:fs/promises";
|
|
4
|
+
import { HOME_ANCHOR, REPO_ANCHOR } from "@kici-dev/core";
|
|
5
|
+
import { Readable } from "node:stream";
|
|
6
|
+
import { pipeline } from "node:stream/promises";
|
|
7
|
+
import { x } from "tar";
|
|
8
|
+
import { makeTempDir } from "@kici-dev/core/tmp";
|
|
9
|
+
//#region src/remote/artifact-extract.ts
|
|
10
|
+
/**
|
|
11
|
+
* CLI-side artifact extraction.
|
|
12
|
+
*
|
|
13
|
+
* Artifact tarballs are packed by the cache packer, so entries are anchored as
|
|
14
|
+
* `__repo__/<rel>` (repo-root-relative) and `__home__/<rel>` (home-relative).
|
|
15
|
+
* The in-workflow extractor restores those groups to the real repo root / home
|
|
16
|
+
* dir; a CLI must NOT — that would scatter files across the user's filesystem.
|
|
17
|
+
* This helper lands everything under a single destination dir instead:
|
|
18
|
+
*
|
|
19
|
+
* `__repo__/<rel>` -> `<destDir>/<rel>`
|
|
20
|
+
* `__home__/<rel>` -> `<destDir>/~home/<rel>` (kept separate so a
|
|
21
|
+
* home-anchored file cannot clobber a repo-anchored one)
|
|
22
|
+
*
|
|
23
|
+
* Extraction goes through a scratch dir first and only relocates on success, so
|
|
24
|
+
* a failed extraction never leaves a half-written output directory.
|
|
25
|
+
*/
|
|
26
|
+
/** Sub-directory of the destination that home-anchored entries land under. */
|
|
27
|
+
const HOME_SUBDIR = "~home";
|
|
28
|
+
/**
|
|
29
|
+
* Extract an artifact tarball under `destDir`, relocating the anchor groups so
|
|
30
|
+
* nothing escapes the destination.
|
|
31
|
+
*/
|
|
32
|
+
async function extractArtifactTarball(tarball, destDir) {
|
|
33
|
+
const scratch = await makeTempDir("artifact-extract");
|
|
34
|
+
try {
|
|
35
|
+
await pipeline(Readable.from(tarball), x({
|
|
36
|
+
cwd: scratch.path,
|
|
37
|
+
gzip: true
|
|
38
|
+
}));
|
|
39
|
+
await mkdir(destDir, { recursive: true });
|
|
40
|
+
for (const top of await readdir(scratch.path)) {
|
|
41
|
+
const from = join(scratch.path, top);
|
|
42
|
+
if (top === REPO_ANCHOR) await relocateGroup(from, destDir);
|
|
43
|
+
else if (top === HOME_ANCHOR) await relocateGroup(from, join(destDir, HOME_SUBDIR));
|
|
44
|
+
else await cp(from, join(destDir, top), { recursive: true });
|
|
45
|
+
}
|
|
46
|
+
} finally {
|
|
47
|
+
await scratch.cleanup();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** Copy the contents of an anchor group dir into `into`, merging trees. */
|
|
51
|
+
async function relocateGroup(groupDir, into) {
|
|
52
|
+
await mkdir(into, { recursive: true });
|
|
53
|
+
for (const entry of await readdir(groupDir)) await cp(join(groupDir, entry), join(into, entry), { recursive: true });
|
|
54
|
+
}
|
|
55
|
+
//#endregion
|
|
56
|
+
export { HOME_SUBDIR, extractArtifactTarball };
|
|
57
|
+
|
|
58
|
+
//# sourceMappingURL=artifact-extract.js.map
|
package/dist/remote/config.d.ts
CHANGED
|
@@ -32,13 +32,31 @@ export interface GlobalConfig {
|
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
34
|
* Returns the global KiCI config directory path.
|
|
35
|
-
*
|
|
35
|
+
*
|
|
36
|
+
* Resolution order:
|
|
37
|
+
* 1. `KICI_CONFIG_DIR`, when set to a non-empty value.
|
|
38
|
+
* 2. A hard refusal when `KICI_TEST_ISOLATION` is present. A developer
|
|
39
|
+
* machine's `~/.kici/config` names a real endpoint and carries a live
|
|
40
|
+
* PAT, so a test process that reads it authenticates against whatever
|
|
41
|
+
* that config points at — in practice, production. Every test that needs
|
|
42
|
+
* a config must name its own isolated directory.
|
|
43
|
+
* 3. `~/.kici`.
|
|
44
|
+
*
|
|
45
|
+
* `KICI_TEST_ISOLATION` is set by this repository's own vitest configs, via
|
|
46
|
+
* `hack/lib/vitest-isolation.ts`. It is deliberately a KiCI-owned name rather
|
|
47
|
+
* than the runner's `VITEST`: `kici` is a compat-protected CLI, and `VITEST`
|
|
48
|
+
* is a third-party marker that propagates into spawned children, so keying off
|
|
49
|
+
* it would break a customer whose vitest test shells out to `kici`.
|
|
50
|
+
*
|
|
51
|
+
* `env` is injectable so this module's own tests can exercise every branch.
|
|
52
|
+
* It is NOT an opt-out: production call sites pass no argument and inherit the
|
|
53
|
+
* guard.
|
|
36
54
|
*/
|
|
37
|
-
export declare function getConfigDir(): string;
|
|
55
|
+
export declare function getConfigDir(env?: NodeJS.ProcessEnv): string;
|
|
38
56
|
/**
|
|
39
57
|
* Returns the path to the global config file (~/.kici/config).
|
|
40
58
|
*/
|
|
41
|
-
export declare function getConfigPath(): string;
|
|
59
|
+
export declare function getConfigPath(env?: NodeJS.ProcessEnv): string;
|
|
42
60
|
/**
|
|
43
61
|
* Load the global KiCI config from ~/.kici/config.
|
|
44
62
|
* Returns an empty object if the file does not exist.
|
package/dist/remote/config.js
CHANGED
|
@@ -30,17 +30,36 @@ function sanitizeConfig(raw) {
|
|
|
30
30
|
}
|
|
31
31
|
/**
|
|
32
32
|
* Returns the global KiCI config directory path.
|
|
33
|
-
*
|
|
33
|
+
*
|
|
34
|
+
* Resolution order:
|
|
35
|
+
* 1. `KICI_CONFIG_DIR`, when set to a non-empty value.
|
|
36
|
+
* 2. A hard refusal when `KICI_TEST_ISOLATION` is present. A developer
|
|
37
|
+
* machine's `~/.kici/config` names a real endpoint and carries a live
|
|
38
|
+
* PAT, so a test process that reads it authenticates against whatever
|
|
39
|
+
* that config points at — in practice, production. Every test that needs
|
|
40
|
+
* a config must name its own isolated directory.
|
|
41
|
+
* 3. `~/.kici`.
|
|
42
|
+
*
|
|
43
|
+
* `KICI_TEST_ISOLATION` is set by this repository's own vitest configs, via
|
|
44
|
+
* `hack/lib/vitest-isolation.ts`. It is deliberately a KiCI-owned name rather
|
|
45
|
+
* than the runner's `VITEST`: `kici` is a compat-protected CLI, and `VITEST`
|
|
46
|
+
* is a third-party marker that propagates into spawned children, so keying off
|
|
47
|
+
* it would break a customer whose vitest test shells out to `kici`.
|
|
48
|
+
*
|
|
49
|
+
* `env` is injectable so this module's own tests can exercise every branch.
|
|
50
|
+
* It is NOT an opt-out: production call sites pass no argument and inherit the
|
|
51
|
+
* guard.
|
|
34
52
|
*/
|
|
35
|
-
function getConfigDir() {
|
|
36
|
-
if (
|
|
53
|
+
function getConfigDir(env = process.env) {
|
|
54
|
+
if (env.KICI_CONFIG_DIR) return env.KICI_CONFIG_DIR;
|
|
55
|
+
if (env.KICI_TEST_ISOLATION) throw new Error("Refusing to read the ambient ~/.kici config from a test process. Set KICI_CONFIG_DIR to an isolated directory for this run — the developer machine config may point at production.");
|
|
37
56
|
return path.join(os.homedir(), ".kici");
|
|
38
57
|
}
|
|
39
58
|
/**
|
|
40
59
|
* Returns the path to the global config file (~/.kici/config).
|
|
41
60
|
*/
|
|
42
|
-
function getConfigPath() {
|
|
43
|
-
return path.join(getConfigDir(), "config");
|
|
61
|
+
function getConfigPath(env = process.env) {
|
|
62
|
+
return path.join(getConfigDir(env), "config");
|
|
44
63
|
}
|
|
45
64
|
/**
|
|
46
65
|
* Load the global KiCI config from ~/.kici/config.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* only place in the CLI that knows these routes.
|
|
5
5
|
*/
|
|
6
6
|
import { z } from 'zod';
|
|
7
|
-
import { type RunListResponse, type RunListItem, type DiagnosticsInfrastructureResponse, type DiagnosticsSummaryResponse, type DashboardRunDetailApiResponse, type DashboardStepLogsApiResponse, type RegistrationItem } from '@kici-dev/engine';
|
|
7
|
+
import { type ArtifactListItem, type RunListResponse, type RunListItem, type DiagnosticsInfrastructureResponse, type DiagnosticsSummaryResponse, type DashboardRunDetailApiResponse, type DashboardStepLogsApiResponse, type RegistrationItem } from '@kici-dev/engine';
|
|
8
8
|
import { type GlobalConfig } from './config.js';
|
|
9
9
|
export type DashboardErrorKind = 'not_logged_in' | 'no_active_org' | 'unauthorized' | 'forbidden' | 'not_found' | 'conflict' | 'cooldown' | 'orchestrator_offline' | 'http';
|
|
10
10
|
/** Typed error raised by every DashboardClient method on a non-2xx response. */
|
|
@@ -22,8 +22,21 @@ export interface RunsListFilters {
|
|
|
22
22
|
trigger?: string;
|
|
23
23
|
source?: string;
|
|
24
24
|
since?: string;
|
|
25
|
-
page
|
|
25
|
+
/** Opaque keyset cursor (from a prior page's `nextCursor`). Absent = first page. */
|
|
26
|
+
cursor?: string;
|
|
26
27
|
}
|
|
28
|
+
export declare const webhookActivitySchema: z.ZodObject<{
|
|
29
|
+
windowMinutes: z.ZodNumber;
|
|
30
|
+
received: z.ZodNumber;
|
|
31
|
+
delivered: z.ZodNumber;
|
|
32
|
+
edgeRejected: z.ZodNumber;
|
|
33
|
+
failed: z.ZodNumber;
|
|
34
|
+
matched: z.ZodOptional<z.ZodNumber>;
|
|
35
|
+
unmatched: z.ZodOptional<z.ZodNumber>;
|
|
36
|
+
lockfileMissing: z.ZodOptional<z.ZodNumber>;
|
|
37
|
+
orchestratorUnavailable: z.ZodBoolean;
|
|
38
|
+
}, z.core.$strip>;
|
|
39
|
+
export type WebhookActivity = z.infer<typeof webhookActivitySchema>;
|
|
27
40
|
/** Result of {@link DashboardClient.listRegistrations}. */
|
|
28
41
|
export interface RegistrationsListResult {
|
|
29
42
|
registrations: RegistrationItem[];
|
|
@@ -36,18 +49,26 @@ export interface RegistrationsListFilters {
|
|
|
36
49
|
repoIdentifier?: string;
|
|
37
50
|
}
|
|
38
51
|
/**
|
|
39
|
-
* A secret context (
|
|
52
|
+
* A secret context (context) as surfaced to the developer CLI's
|
|
40
53
|
* `secrets list` / `types` commands. The orchestrator returns the per-env
|
|
41
54
|
* secret key names (never values) when `includeSecrets` is requested.
|
|
42
55
|
*/
|
|
43
|
-
declare const
|
|
56
|
+
declare const contextContextSchema: z.ZodObject<{
|
|
44
57
|
name: z.ZodString;
|
|
45
58
|
enabled: z.ZodBoolean;
|
|
46
59
|
allowLocalExecution: z.ZodBoolean;
|
|
47
60
|
secretKeys: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
48
61
|
}, z.core.$strip>;
|
|
49
|
-
/** A secret context (
|
|
50
|
-
export type
|
|
62
|
+
/** A secret context (context) returned by {@link DashboardClient.listContexts}. */
|
|
63
|
+
export type ContextContext = z.infer<typeof contextContextSchema>;
|
|
64
|
+
/**
|
|
65
|
+
* Parsed shape of `GET /runs/:runId/artifacts` for the CLI. The per-artifact
|
|
66
|
+
* shape is reused from `@kici-dev/engine` so the CLI and the server cannot drift.
|
|
67
|
+
*/
|
|
68
|
+
export interface ArtifactsListResult {
|
|
69
|
+
artifacts: ArtifactListItem[];
|
|
70
|
+
downloadUrlExpiresInSeconds?: number;
|
|
71
|
+
}
|
|
51
72
|
export declare class DashboardClient {
|
|
52
73
|
private readonly endpoint;
|
|
53
74
|
private readonly token;
|
|
@@ -62,17 +83,33 @@ export declare class DashboardClient {
|
|
|
62
83
|
getJson(path: string): Promise<unknown>;
|
|
63
84
|
/** Generic POST helper used by typed methods (and tests). */
|
|
64
85
|
postJson(path: string, body?: unknown): Promise<unknown>;
|
|
86
|
+
/** Generic DELETE helper used by typed methods (and tests). */
|
|
87
|
+
deleteJson(path: string): Promise<unknown>;
|
|
65
88
|
getDiagnosticsSummary(): Promise<DiagnosticsSummaryResponse>;
|
|
66
89
|
getInfrastructure(): Promise<DiagnosticsInfrastructureResponse>;
|
|
67
90
|
listRuns(filters?: RunsListFilters): Promise<RunListResponse>;
|
|
68
91
|
getRun(runId: string): Promise<RunListItem>;
|
|
92
|
+
/**
|
|
93
|
+
* Fetch the org's recent webhook-activity counts. Returns null on ANY error
|
|
94
|
+
* (older Platform without the route, a network blip, an unexpected shape) so
|
|
95
|
+
* the `kici runs` empty-window hint degrades silently to today's output — the
|
|
96
|
+
* hint is a nicety, never a hard dependency.
|
|
97
|
+
*/
|
|
98
|
+
getWebhookActivity(windowMinutes?: number): Promise<WebhookActivity | null>;
|
|
69
99
|
getRunDetail(runId: string): Promise<DashboardRunDetailApiResponse>;
|
|
70
100
|
getStepLogs(runId: string, jobId: string, stepIndex: number): Promise<DashboardStepLogsApiResponse>;
|
|
101
|
+
/**
|
|
102
|
+
* List a run's artifacts (`GET /runs/:runId/artifacts`). Each entry carries a
|
|
103
|
+
* presigned `downloadUrl` minted by the customer's orchestrator; the Platform
|
|
104
|
+
* relays it without re-signing, so the artifact bytes never transit Platform.
|
|
105
|
+
*/
|
|
106
|
+
listArtifacts(runId: string): Promise<ArtifactsListResult>;
|
|
71
107
|
rerunRun(runId: string): Promise<{
|
|
72
108
|
newRunId: string;
|
|
73
109
|
}>;
|
|
74
110
|
cancelRun(runId: string, force: boolean): Promise<{
|
|
75
111
|
cancelledJobs?: number;
|
|
112
|
+
alreadyTerminal?: boolean;
|
|
76
113
|
}>;
|
|
77
114
|
cancelByBranch(branch: string): Promise<{
|
|
78
115
|
cancelledRuns?: number;
|
|
@@ -80,13 +117,13 @@ export declare class DashboardClient {
|
|
|
80
117
|
/** List the org's permanently registered workflows (GET /registrations). */
|
|
81
118
|
listRegistrations(filters?: RegistrationsListFilters): Promise<RegistrationsListResult>;
|
|
82
119
|
/**
|
|
83
|
-
* List the org's
|
|
120
|
+
* List the org's contexts as secret contexts (GET /contexts).
|
|
84
121
|
*
|
|
85
|
-
* Pass `includeSecrets` to have the orchestrator attach each
|
|
122
|
+
* Pass `includeSecrets` to have the orchestrator attach each context's
|
|
86
123
|
* reachable secret key names (never values). Used by `kici secrets list`
|
|
87
124
|
* and `kici types`.
|
|
88
125
|
*/
|
|
89
|
-
|
|
126
|
+
listContexts(includeSecrets?: boolean): Promise<ContextContext[]>;
|
|
90
127
|
}
|
|
91
128
|
export {};
|
|
92
129
|
//# sourceMappingURL=dashboard-client.d.ts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "../rolldown-runtime-ClRpJifh.js";
|
|
2
2
|
import { loadGlobalConfig } from "./config.js";
|
|
3
|
-
import { dashboardRunDetailApiResponseSchema, dashboardStepLogsApiResponseSchema, diagnosticsInfrastructureResponseSchema, diagnosticsSummaryResponseSchema, registrationItemSchema, runListItemSchema, runListResponseSchema } from "@kici-dev/engine";
|
|
3
|
+
import { artifactListItemSchema, dashboardRunDetailApiResponseSchema, dashboardStepLogsApiResponseSchema, diagnosticsInfrastructureResponseSchema, diagnosticsSummaryResponseSchema, registrationItemSchema, runListItemSchema, runListResponseSchema } from "@kici-dev/engine";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
//#region src/remote/dashboard-client.ts
|
|
6
6
|
/**
|
|
@@ -20,8 +20,22 @@ var DashboardClientError = class extends Error {
|
|
|
20
20
|
}
|
|
21
21
|
};
|
|
22
22
|
const singleRunSchema = z.object({ run: runListItemSchema });
|
|
23
|
+
const webhookActivitySchema = z.object({
|
|
24
|
+
windowMinutes: z.number(),
|
|
25
|
+
received: z.number(),
|
|
26
|
+
delivered: z.number(),
|
|
27
|
+
edgeRejected: z.number(),
|
|
28
|
+
failed: z.number(),
|
|
29
|
+
matched: z.number().optional(),
|
|
30
|
+
unmatched: z.number().optional(),
|
|
31
|
+
lockfileMissing: z.number().optional(),
|
|
32
|
+
orchestratorUnavailable: z.boolean()
|
|
33
|
+
});
|
|
23
34
|
const rerunResponseSchema = z.object({ newRunId: z.string() });
|
|
24
|
-
const cancelResponseSchema = z.object({
|
|
35
|
+
const cancelResponseSchema = z.object({
|
|
36
|
+
cancelledJobs: z.number().optional(),
|
|
37
|
+
alreadyTerminal: z.boolean().optional()
|
|
38
|
+
});
|
|
25
39
|
const cancelByBranchResponseSchema = z.object({ cancelledRuns: z.number().optional() });
|
|
26
40
|
const registrationsListSchema = z.object({
|
|
27
41
|
registrations: z.array(registrationItemSchema).default([]),
|
|
@@ -29,17 +43,21 @@ const registrationsListSchema = z.object({
|
|
|
29
43
|
registryUpdatedAt: z.string()
|
|
30
44
|
});
|
|
31
45
|
/**
|
|
32
|
-
* A secret context (
|
|
46
|
+
* A secret context (context) as surfaced to the developer CLI's
|
|
33
47
|
* `secrets list` / `types` commands. The orchestrator returns the per-env
|
|
34
48
|
* secret key names (never values) when `includeSecrets` is requested.
|
|
35
49
|
*/
|
|
36
|
-
const
|
|
50
|
+
const contextContextSchema = z.object({
|
|
37
51
|
name: z.string(),
|
|
38
52
|
enabled: z.boolean(),
|
|
39
53
|
allowLocalExecution: z.boolean(),
|
|
40
54
|
secretKeys: z.array(z.string()).default([])
|
|
41
55
|
});
|
|
42
|
-
const
|
|
56
|
+
const contextsListSchema = z.object({ contexts: z.array(contextContextSchema).default([]) });
|
|
57
|
+
const artifactsListResultSchema = z.object({
|
|
58
|
+
artifacts: z.array(artifactListItemSchema),
|
|
59
|
+
downloadUrlExpiresInSeconds: z.number().int().positive().optional()
|
|
60
|
+
});
|
|
43
61
|
const STATUS_ERROR_MAP = {
|
|
44
62
|
401: ["unauthorized", "Authentication failed. Run `kici login` to re-authenticate."],
|
|
45
63
|
403: ["forbidden", "Access denied."],
|
|
@@ -105,6 +123,10 @@ var DashboardClient = class DashboardClient {
|
|
|
105
123
|
async postJson(path, body) {
|
|
106
124
|
return this.request("POST", path, body);
|
|
107
125
|
}
|
|
126
|
+
/** Generic DELETE helper used by typed methods (and tests). */
|
|
127
|
+
async deleteJson(path) {
|
|
128
|
+
return this.request("DELETE", path);
|
|
129
|
+
}
|
|
108
130
|
async getDiagnosticsSummary() {
|
|
109
131
|
return diagnosticsSummaryResponseSchema.parse(await this.getJson("/diagnostics"));
|
|
110
132
|
}
|
|
@@ -120,19 +142,40 @@ var DashboardClient = class DashboardClient {
|
|
|
120
142
|
if (filters.trigger) qs.set("triggerType", filters.trigger);
|
|
121
143
|
if (filters.source) qs.set("source", filters.source);
|
|
122
144
|
if (filters.since) qs.set("since", filters.since);
|
|
123
|
-
if (filters.
|
|
145
|
+
if (filters.cursor) qs.set("cursor", filters.cursor);
|
|
124
146
|
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
125
147
|
return runListResponseSchema.parse(await this.getJson(`/runs${suffix}`));
|
|
126
148
|
}
|
|
127
149
|
async getRun(runId) {
|
|
128
150
|
return singleRunSchema.parse(await this.getJson(`/runs/${runId}`)).run;
|
|
129
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* Fetch the org's recent webhook-activity counts. Returns null on ANY error
|
|
154
|
+
* (older Platform without the route, a network blip, an unexpected shape) so
|
|
155
|
+
* the `kici runs` empty-window hint degrades silently to today's output — the
|
|
156
|
+
* hint is a nicety, never a hard dependency.
|
|
157
|
+
*/
|
|
158
|
+
async getWebhookActivity(windowMinutes = 60) {
|
|
159
|
+
try {
|
|
160
|
+
return webhookActivitySchema.parse(await this.getJson(`/webhook-activity?windowMinutes=${windowMinutes}`));
|
|
161
|
+
} catch {
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
130
165
|
async getRunDetail(runId) {
|
|
131
166
|
return dashboardRunDetailApiResponseSchema.parse(await this.getJson(`/runs/${runId}/detail`));
|
|
132
167
|
}
|
|
133
168
|
async getStepLogs(runId, jobId, stepIndex) {
|
|
134
169
|
return dashboardStepLogsApiResponseSchema.parse(await this.getJson(`/runs/${runId}/jobs/${jobId}/steps/${stepIndex}/logs`));
|
|
135
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* List a run's artifacts (`GET /runs/:runId/artifacts`). Each entry carries a
|
|
173
|
+
* presigned `downloadUrl` minted by the customer's orchestrator; the Platform
|
|
174
|
+
* relays it without re-signing, so the artifact bytes never transit Platform.
|
|
175
|
+
*/
|
|
176
|
+
async listArtifacts(runId) {
|
|
177
|
+
return artifactsListResultSchema.parse(await this.getJson(`/runs/${runId}/artifacts`));
|
|
178
|
+
}
|
|
136
179
|
async rerunRun(runId) {
|
|
137
180
|
return rerunResponseSchema.parse(await this.postJson(`/runs/${runId}/rerun`));
|
|
138
181
|
}
|
|
@@ -151,18 +194,18 @@ var DashboardClient = class DashboardClient {
|
|
|
151
194
|
return registrationsListSchema.parse(await this.getJson(`/registrations${suffix}`));
|
|
152
195
|
}
|
|
153
196
|
/**
|
|
154
|
-
* List the org's
|
|
197
|
+
* List the org's contexts as secret contexts (GET /contexts).
|
|
155
198
|
*
|
|
156
|
-
* Pass `includeSecrets` to have the orchestrator attach each
|
|
199
|
+
* Pass `includeSecrets` to have the orchestrator attach each context's
|
|
157
200
|
* reachable secret key names (never values). Used by `kici secrets list`
|
|
158
201
|
* and `kici types`.
|
|
159
202
|
*/
|
|
160
|
-
async
|
|
203
|
+
async listContexts(includeSecrets = false) {
|
|
161
204
|
const suffix = includeSecrets ? "?includeSecrets=true" : "";
|
|
162
|
-
return
|
|
205
|
+
return contextsListSchema.parse(await this.getJson(`/contexts${suffix}`)).contexts;
|
|
163
206
|
}
|
|
164
207
|
};
|
|
165
208
|
//#endregion
|
|
166
|
-
export { DashboardClient, DashboardClientError };
|
|
209
|
+
export { DashboardClient, DashboardClientError, webhookActivitySchema };
|
|
167
210
|
|
|
168
211
|
//# sourceMappingURL=dashboard-client.js.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Report whether `dir` lives on a filesystem that ignores case in path lookups.
|
|
3
|
+
*
|
|
4
|
+
* Case sensitivity is a property of the mounted filesystem, not of the platform
|
|
5
|
+
* — a Linux host can mount a case-insensitive volume and macOS can format a
|
|
6
|
+
* case-sensitive one — so it is measured rather than inferred: an empty file is
|
|
7
|
+
* written under a random name and the same name is stat'd upper-cased. The
|
|
8
|
+
* directory is created if it is missing, and the probe file is removed on every
|
|
9
|
+
* path, including a throw.
|
|
10
|
+
*
|
|
11
|
+
* Rejects whenever the probe cannot produce an answer: the probe file cannot be
|
|
12
|
+
* written, or the twin lookup fails for any reason other than the twin's
|
|
13
|
+
* absence. Only `ENOENT` means "case-sensitive" — a permission or I/O error says
|
|
14
|
+
* nothing about case folding, and reporting it as case-sensitive would let a
|
|
15
|
+
* colliding set overwrite itself, so it is surfaced to the caller instead.
|
|
16
|
+
*
|
|
17
|
+
* It is its own module so callers can be tested against both answers with a
|
|
18
|
+
* cross-module spy, rather than against whatever filesystem the test runs on.
|
|
19
|
+
*/
|
|
20
|
+
export declare function isCaseInsensitiveDir(dir: string): Promise<boolean>;
|
|
21
|
+
//# sourceMappingURL=fs-case.d.ts.map
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import "../rolldown-runtime-ClRpJifh.js";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { mkdir, rm, stat, writeFile } from "node:fs/promises";
|
|
4
|
+
import { randomUUID } from "node:crypto";
|
|
5
|
+
//#region src/remote/fs-case.ts
|
|
6
|
+
/** Filesystem case-sensitivity probe for a target output directory. */
|
|
7
|
+
/**
|
|
8
|
+
* Report whether `dir` lives on a filesystem that ignores case in path lookups.
|
|
9
|
+
*
|
|
10
|
+
* Case sensitivity is a property of the mounted filesystem, not of the platform
|
|
11
|
+
* — a Linux host can mount a case-insensitive volume and macOS can format a
|
|
12
|
+
* case-sensitive one — so it is measured rather than inferred: an empty file is
|
|
13
|
+
* written under a random name and the same name is stat'd upper-cased. The
|
|
14
|
+
* directory is created if it is missing, and the probe file is removed on every
|
|
15
|
+
* path, including a throw.
|
|
16
|
+
*
|
|
17
|
+
* Rejects whenever the probe cannot produce an answer: the probe file cannot be
|
|
18
|
+
* written, or the twin lookup fails for any reason other than the twin's
|
|
19
|
+
* absence. Only `ENOENT` means "case-sensitive" — a permission or I/O error says
|
|
20
|
+
* nothing about case folding, and reporting it as case-sensitive would let a
|
|
21
|
+
* colliding set overwrite itself, so it is surfaced to the caller instead.
|
|
22
|
+
*
|
|
23
|
+
* It is its own module so callers can be tested against both answers with a
|
|
24
|
+
* cross-module spy, rather than against whatever filesystem the test runs on.
|
|
25
|
+
*/
|
|
26
|
+
async function isCaseInsensitiveDir(dir) {
|
|
27
|
+
await mkdir(dir, { recursive: true });
|
|
28
|
+
const probe = `.kici-case-probe-${randomUUID()}`;
|
|
29
|
+
const twin = probe.toUpperCase();
|
|
30
|
+
const probePath = join(dir, probe);
|
|
31
|
+
await writeFile(probePath, "");
|
|
32
|
+
try {
|
|
33
|
+
await stat(join(dir, twin));
|
|
34
|
+
return true;
|
|
35
|
+
} catch (err) {
|
|
36
|
+
if (err?.code === "ENOENT") return false;
|
|
37
|
+
throw err;
|
|
38
|
+
} finally {
|
|
39
|
+
await rm(probePath, { force: true });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
export { isCaseInsensitiveDir };
|
|
44
|
+
|
|
45
|
+
//# sourceMappingURL=fs-case.js.map
|
package/dist/remote/history.d.ts
CHANGED
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
* can review past runs (kici run remote --history) and inspect specific runs
|
|
6
6
|
* (kici status <run-id>).
|
|
7
7
|
*/
|
|
8
|
-
|
|
9
|
-
type RunStatus = 'queued' | 'running' | 'success' | 'failed' | 'cancelled';
|
|
8
|
+
import { type CanonicalStatus } from '@kici-dev/engine';
|
|
10
9
|
/** A single run history entry */
|
|
11
10
|
export interface HistoryEntry {
|
|
12
11
|
/** Unique run identifier */
|
|
@@ -14,7 +13,7 @@ export interface HistoryEntry {
|
|
|
14
13
|
/** Fixture that was run */
|
|
15
14
|
fixtureId: string;
|
|
16
15
|
/** Current status of the run */
|
|
17
|
-
status:
|
|
16
|
+
status: CanonicalStatus;
|
|
18
17
|
/** ISO timestamp when the run started */
|
|
19
18
|
startedAt: string;
|
|
20
19
|
/** ISO timestamp when the run completed (if finished) */
|
|
@@ -87,5 +86,12 @@ export declare class RunHistory {
|
|
|
87
86
|
*/
|
|
88
87
|
private save;
|
|
89
88
|
}
|
|
89
|
+
/** The plain (uncoloured) width of a status cell, for column padding. */
|
|
90
|
+
export declare function statusLabelWidth(status: string): number;
|
|
91
|
+
/**
|
|
92
|
+
* Format a run status with its colour and short label. A status this CLI does
|
|
93
|
+
* not recognise — a history file written by a newer version — renders verbatim.
|
|
94
|
+
*/
|
|
95
|
+
export declare function formatStatus(status: string): string;
|
|
90
96
|
export {};
|
|
91
97
|
//# sourceMappingURL=history.d.ts.map
|