@kici-dev/compiler 0.7.0 → 0.8.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/cli.js +2 -2
- package/dist/commands/local.d.ts +9 -2
- package/dist/commands/local.js +14 -4
- package/dist/commands/report/identity.js +1 -1
- package/dist/commands/run-routed.js +3 -0
- package/dist/commands/run.js +5 -2
- package/dist/commands/runs/logs.js +3 -2
- package/dist/llm-context/llms-architecture.txt +1 -1
- package/dist/llm-context/llms-cli-remote.txt +13 -1
- package/dist/llm-context/llms-cli.txt +4 -2
- package/dist/llm-context/llms-features-execution.txt +1 -1
- package/dist/llm-context/llms-full.txt +32 -7
- package/dist/llm-context/llms-getting-started.txt +2 -2
- package/dist/llm-context/llms-sdk-runtime.txt +11 -0
- package/dist/llm-context/llms.txt +1 -1
- package/dist/local-plane/orchestrator-process.js +3 -0
- package/dist/local-plane/paths.d.ts +1 -0
- package/dist/local-plane/paths.js +1 -0
- package/dist/local-plane/plane-log.d.ts +27 -0
- package/dist/local-plane/plane-log.js +39 -0
- package/dist/local-plane/plane-manager.js +2 -2
- package/dist/local-plane/plane-trigger.d.ts +28 -0
- package/dist/local-plane/plane-trigger.js +57 -2
- package/dist/local-plane/postgres.js +9 -6
- package/dist/local-plane/run-follow.js +2 -1
- package/dist/remote/output/streaming.d.ts +12 -0
- package/dist/remote/output/streaming.js +20 -1
- package/dist/remote/platform-client.d.ts +2 -0
- package/dist/templates/package-json.d.ts +9 -7
- package/dist/templates/package-json.js +11 -9
- package/package.json +6 -6
- package/sbom.spdx.json +123 -123
package/dist/cli.js
CHANGED
|
@@ -7,7 +7,7 @@ import { realpathSync } from "node:fs";
|
|
|
7
7
|
import { Argument, Command } from "commander";
|
|
8
8
|
import pc from "picocolors";
|
|
9
9
|
//#region src/cli.ts
|
|
10
|
-
const version = "0.
|
|
10
|
+
const version = "0.8.0";
|
|
11
11
|
/**
|
|
12
12
|
* Top-level commands that were removed, mapped to their current equivalent.
|
|
13
13
|
* Consulted when the CLI hits an unknown command so the user gets a precise
|
|
@@ -312,7 +312,7 @@ Environment variables:
|
|
|
312
312
|
],
|
|
313
313
|
[
|
|
314
314
|
"logs",
|
|
315
|
-
"Print the local dev plane
|
|
315
|
+
"Print the local dev plane log paths and rotation policy",
|
|
316
316
|
"localLogsCommand"
|
|
317
317
|
],
|
|
318
318
|
[
|
package/dist/commands/local.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* orchestrator plus a local Postgres (embedded, with a podman fallback) that
|
|
6
6
|
* `kici run --local` dispatches through. `up` boots or reuses the plane,
|
|
7
7
|
* `status` reports it plus the control commands, `down` stops it, and `logs`
|
|
8
|
-
* prints the
|
|
8
|
+
* prints the plane log paths and rotation policy.
|
|
9
9
|
*/
|
|
10
10
|
import type { PlaneStatus, PlaneMode } from '../local-plane/plane-manager.js';
|
|
11
11
|
import type { PlaneState } from '../local-plane/plane-liveness.js';
|
|
@@ -52,7 +52,14 @@ export declare function localStatusCommand(options?: {
|
|
|
52
52
|
}): Promise<boolean>;
|
|
53
53
|
/** Stop the local dev plane, reporting success only once the port is released. */
|
|
54
54
|
export declare function localDownCommand(): Promise<boolean>;
|
|
55
|
-
/**
|
|
55
|
+
/**
|
|
56
|
+
* Print the local dev plane orchestrator log path, plus the rotation policy.
|
|
57
|
+
*
|
|
58
|
+
* The path is the only line this command writes to stdout — the policy note
|
|
59
|
+
* goes to stderr — so a caller reading stdout never has to strip prose from
|
|
60
|
+
* it. The CLI version banner still precedes it, as for every command, so
|
|
61
|
+
* `$(kici local logs)` is NOT a bare path: read the last stdout line.
|
|
62
|
+
*/
|
|
56
63
|
export declare function localLogsCommand(): Promise<boolean>;
|
|
57
64
|
/**
|
|
58
65
|
* Attach the local dev plane to the hosted Platform so `kici run --local` uses
|
package/dist/commands/local.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import "../rolldown-runtime-ClRpJifh.js";
|
|
2
2
|
import { loadGlobalConfig } from "../remote/config.js";
|
|
3
|
+
import "../local-plane/plane-log.js";
|
|
3
4
|
import { attachPlane, detachPlane, planeDown, planeLogPath, planeStatus } from "../local-plane/plane-manager.js";
|
|
4
5
|
import { resolvePlaneForRun } from "../local-plane/resolve-plane.js";
|
|
5
6
|
import pc from "picocolors";
|
|
@@ -12,14 +13,14 @@ import { toErrorMessage } from "@kici-dev/core";
|
|
|
12
13
|
* orchestrator plus a local Postgres (embedded, with a podman fallback) that
|
|
13
14
|
* `kici run --local` dispatches through. `up` boots or reuses the plane,
|
|
14
15
|
* `status` reports it plus the control commands, `down` stops it, and `logs`
|
|
15
|
-
* prints the
|
|
16
|
+
* prints the plane log paths and rotation policy.
|
|
16
17
|
*/
|
|
17
18
|
/** Print the control commands a user needs once the plane is running. */
|
|
18
19
|
function printControlHints() {
|
|
19
20
|
console.log("");
|
|
20
21
|
console.log(pc.dim("Control commands:"));
|
|
21
22
|
console.log(` ${pc.cyan("kici local status")} Show plane status`);
|
|
22
|
-
console.log(` ${pc.cyan("kici local logs")} Print the
|
|
23
|
+
console.log(` ${pc.cyan("kici local logs")} Print the plane log paths and rotation policy`);
|
|
23
24
|
console.log(` ${pc.cyan("kici local down")} Stop the plane`);
|
|
24
25
|
}
|
|
25
26
|
/**
|
|
@@ -147,9 +148,18 @@ async function localDownCommand() {
|
|
|
147
148
|
console.log(pc.green("✓") + " Local dev plane stopped.");
|
|
148
149
|
return true;
|
|
149
150
|
}
|
|
150
|
-
/**
|
|
151
|
+
/**
|
|
152
|
+
* Print the local dev plane orchestrator log path, plus the rotation policy.
|
|
153
|
+
*
|
|
154
|
+
* The path is the only line this command writes to stdout — the policy note
|
|
155
|
+
* goes to stderr — so a caller reading stdout never has to strip prose from
|
|
156
|
+
* it. The CLI version banner still precedes it, as for every command, so
|
|
157
|
+
* `$(kici local logs)` is NOT a bare path: read the last stdout line.
|
|
158
|
+
*/
|
|
151
159
|
async function localLogsCommand() {
|
|
152
|
-
|
|
160
|
+
const logFile = planeLogPath();
|
|
161
|
+
console.log(logFile);
|
|
162
|
+
console.error(pc.dim(`Rotated to ${logFile}.1 when it reaches 50 MB, at the next plane start. When the plane runs embedded PostgreSQL, its log sits beside it at ${logFile}.pg and rotates the same way.`));
|
|
153
163
|
return true;
|
|
154
164
|
}
|
|
155
165
|
/**
|
|
@@ -19,7 +19,7 @@ import { PROTOCOL_VERSION } from "@kici-dev/engine";
|
|
|
19
19
|
*/
|
|
20
20
|
function collectIdentity(probe) {
|
|
21
21
|
const identity = {
|
|
22
|
-
kiciCliVersion: "0.
|
|
22
|
+
kiciCliVersion: "0.8.0",
|
|
23
23
|
nodeVersion: process.version,
|
|
24
24
|
platform: process.platform,
|
|
25
25
|
arch: process.arch,
|
|
@@ -151,6 +151,9 @@ async function runRouted(options) {
|
|
|
151
151
|
action: dispatch.action,
|
|
152
152
|
clientPayload: dispatch.clientPayload
|
|
153
153
|
}
|
|
154
|
+
}, {
|
|
155
|
+
repoBasePath: workdir.dir,
|
|
156
|
+
logPath: planeLogPath()
|
|
154
157
|
});
|
|
155
158
|
if (!quiet) logger.info(pc.green(`Run started: ${runId}`));
|
|
156
159
|
const outcome = await followRun(plane.url, plane.adminToken, runId, {
|
package/dist/commands/run.js
CHANGED
|
@@ -9,6 +9,7 @@ import { buildEncryptedSecrets } from "../remote/secret-upload.js";
|
|
|
9
9
|
import { createOverlayTarball, getSizeWarning, uploadTarball } from "../remote/uploader.js";
|
|
10
10
|
import { formatJsonResult } from "../remote/output/json.js";
|
|
11
11
|
import { formatJunitResult } from "../remote/output/junit.js";
|
|
12
|
+
import { unwrapStoredLogLine } from "../remote/output/streaming.js";
|
|
12
13
|
import { formatErrorHighlight, formatMultiFixtureSummary, formatSummary } from "../remote/output/summary.js";
|
|
13
14
|
import { compileFixtures, filterFixtures } from "../fixtures/compiler.js";
|
|
14
15
|
import { describeEvent } from "../fixtures/describe-event.js";
|
|
@@ -500,7 +501,8 @@ async function pollRunToCompletion(ctx, runId, fixtureId, options) {
|
|
|
500
501
|
throw err;
|
|
501
502
|
}
|
|
502
503
|
runSeen = true;
|
|
503
|
-
for (const
|
|
504
|
+
for (const raw of logs.lines) {
|
|
505
|
+
const line = unwrapStoredLogLine(raw);
|
|
504
506
|
if (!options.quiet) process.stdout.write(line + "\n");
|
|
505
507
|
tailLines.push(line);
|
|
506
508
|
while (tailLines.length > MAX_TAIL) tailLines.shift();
|
|
@@ -585,7 +587,8 @@ function jobsFromStatus(status) {
|
|
|
585
587
|
if (!status) return [];
|
|
586
588
|
return status.jobs.map((j) => ({
|
|
587
589
|
name: j.jobName,
|
|
588
|
-
status: j.status
|
|
590
|
+
status: j.status,
|
|
591
|
+
...typeof j.durationMs === "number" && { durationMs: j.durationMs }
|
|
589
592
|
}));
|
|
590
593
|
}
|
|
591
594
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import "../../rolldown-runtime-ClRpJifh.js";
|
|
2
2
|
import { DashboardClient, DashboardClientError } from "../../remote/dashboard-client.js";
|
|
3
3
|
import { colorStatus } from "../../remote/render.js";
|
|
4
|
+
import { unwrapStoredLogLine } from "../../remote/output/streaming.js";
|
|
4
5
|
import pc from "picocolors";
|
|
5
6
|
import { logger, toErrorMessage } from "@kici-dev/core";
|
|
6
7
|
import { TERMINAL_RUN_STATES } from "@kici-dev/engine";
|
|
@@ -31,7 +32,7 @@ async function printAllLogs(client, runId, jobs, jobFilter) {
|
|
|
31
32
|
for (const j of selectJobs(jobs, jobFilter)) for (const s of j.steps ?? []) {
|
|
32
33
|
console.log(pc.bold(`\n=== ${j.jobName} › ${s.stepName} `) + colorStatus(s.status) + pc.bold(" ==="));
|
|
33
34
|
const logs = await client.getStepLogs(runId, j.jobId, s.stepIndex);
|
|
34
|
-
for (const line of logs.lines) console.log(line);
|
|
35
|
+
for (const line of logs.lines) console.log(unwrapStoredLogLine(line));
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
async function collectAllLogs(client, runId, jobs, jobFilter) {
|
|
@@ -50,7 +51,7 @@ async function followLogs(client, runId, jobFilter) {
|
|
|
50
51
|
const seen = printed[key] ?? 0;
|
|
51
52
|
if (logs.lines.length > seen) {
|
|
52
53
|
if (seen === 0) console.log(pc.bold(`\n=== ${j.jobName} › ${s.stepName} ===`));
|
|
53
|
-
for (const line of logs.lines.slice(seen)) console.log(line);
|
|
54
|
+
for (const line of logs.lines.slice(seen)) console.log(unwrapStoredLogLine(line));
|
|
54
55
|
printed[key] = logs.lines.length;
|
|
55
56
|
}
|
|
56
57
|
}
|
|
@@ -1465,7 +1465,7 @@ KiCI uses three WebSocket layers for real-time communication.
|
|
|
1465
1465
|
|
|
1466
1466
|
### Platform ↔ Orchestrator
|
|
1467
1467
|
|
|
1468
|
-
The orchestrator connects outbound to the Platform WebSocket endpoint. After authentication (API key validated via SHA-256 hash lookup), the connection is used for webhook relay, execution telemetry (events, status, logs), source registration, and peer discovery.
|
|
1468
|
+
The orchestrator connects outbound to the Platform WebSocket endpoint. After authentication (API key validated via SHA-256 hash lookup), the connection is used for webhook relay, execution telemetry (events, status, logs), source registration, and peer discovery. Peer discovery is matchmaking only: the Platform pushes a `peer.update` membership list to every orchestrator sharing a routing key, and the orchestrators then connect to each other directly. Inter-orchestrator traffic such as `job.reroute` never transits the Platform.
|
|
1469
1469
|
|
|
1470
1470
|
### Orchestrator ↔ Orchestrator (P2P)
|
|
1471
1471
|
|
|
@@ -761,7 +761,7 @@ In interactive mode (TTY), `kici init` prompts you to:
|
|
|
761
761
|
|
|
762
762
|
**Standalone vs workspace integration:** by default `kici init` scaffolds a self-contained `.kici/` with its own `package.json`. When run inside a pnpm, npm, or yarn workspace, it offers an **integrate** option (or pass `--workspace`): `.kici/` joins the workspace, `@kici-dev/sdk` is added to your workspace-root `package.json`, and your workflows can `import` your other workspace packages (e.g. shared build or deploy utilities). In this mode there is no `.kici/package.json` — the workspace root manages dependencies, and the root install resolves the SDK. Your workflows resolve sibling packages through the workspace-root `node_modules`: under npm and yarn every workspace member is hoisted there automatically, while pnpm links only your root's declared dependencies, so under pnpm add the package you want to import to your workspace-root `dependencies` (this is how KiCI's own repository imports its packages from workflows). Pass `--standalone` to force the self-contained layout even inside a workspace. In CI / non-interactive runs the default is standalone; use `--workspace` to opt in explicitly. `--workspace` and `--standalone` are mutually exclusive, and `--workspace` errors if no workspace is found at or above the current directory.
|
|
763
763
|
|
|
764
|
-
**Development mode:** When `KICI_DEV=true` or `package.json` has `"kici": { "development": true }`, the generated `package.json`
|
|
764
|
+
**Development mode:** When `KICI_DEV=true` or `package.json` has `"kici": { "development": true }`, the generated `package.json` pins `@kici-dev/sdk` to the `latest` dist-tag so npm resolves Verdaccio's newest prerelease build.
|
|
765
765
|
|
|
766
766
|
### kici org
|
|
767
767
|
|
|
@@ -1707,6 +1707,18 @@ Secrets are always sourced from your real `.kici/` directory, not from the isola
|
|
|
1707
1707
|
|
|
1708
1708
|
Pass `--in-place` to run against the real working directory instead — useful when you explicitly want in-tree execution. `--in-place` requires no git repository; the default isolated mode does, and fails with an actionable error pointing at `--in-place` when the directory is not a git repository.
|
|
1709
1709
|
|
|
1710
|
+
**If the trigger times out:**
|
|
1711
|
+
|
|
1712
|
+
The command waits up to 60 seconds for the local dev plane to create the run. If nothing appears in that window it stops and names the cause it read back from the plane:
|
|
1713
|
+
|
|
1714
|
+
| Message | What it means |
|
|
1715
|
+
| ------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1716
|
+
| `plane is not leader yet (election grace period)` | The plane had not finished electing itself. A single-machine plane elects within seconds; if it does not, read the plane log (`kici local logs`). |
|
|
1717
|
+
| `no kici.lock.json at <commit> in <path>` | The plane resolved no lock file for the commit the run packed, so nothing matched. Commit `.kici/kici.lock.json`, or make sure it is present in the working tree. |
|
|
1718
|
+
| `the plane recorded delivery <id> as "<status>"` | The plane processed the trigger and wrote down a terminal status for it without creating a run. The status names the stage that stopped. |
|
|
1719
|
+
| `no run appeared for delivery <id> — see <log>` | Neither the plane's cluster state nor its delivery record explained the timeout. The named log is the next place to look. |
|
|
1720
|
+
| `no run appeared for this trigger — the plane never accepted the webhook` | Every webhook POST came back without a delivery id, so the plane never queued the trigger. Check the plane is up (`kici local status`), then read the named log. |
|
|
1721
|
+
|
|
1710
1722
|
**Examples:**
|
|
1711
1723
|
|
|
1712
1724
|
```bash
|
|
@@ -1365,7 +1365,7 @@ Manage the **local dev plane** — the warm, per-user orchestrator (plus its own
|
|
|
1365
1365
|
kici local up [--offline | --connected] # Start, or reuse an already-running plane
|
|
1366
1366
|
kici local status [--json] # Port, pid, PostgreSQL backend, attachment mode, readiness
|
|
1367
1367
|
kici local down # Stop the orchestrator and its PostgreSQL, verifying the port is freed
|
|
1368
|
-
kici local logs # Print the
|
|
1368
|
+
kici local logs # Print the plane log paths and rotation policy
|
|
1369
1369
|
kici local attach # Attach to the Platform (hybrid mode)
|
|
1370
1370
|
kici local detach # Return the plane to offline (independent) mode
|
|
1371
1371
|
kici local trust-root <file> # Export the dev-signed trust root for offline verification
|
|
@@ -1382,6 +1382,8 @@ The plane runs in one of two modes:
|
|
|
1382
1382
|
|
|
1383
1383
|
`kici local status` reports a plane whose process is alive but whose readiness probe fails — for example when its PostgreSQL has stopped — as running but not ready, together with its readiness checks, rather than as not running. When the holder is a KiCI plane orchestrator that this config directory did not start — a plane belonging to another `KICI_CONFIG_DIR`, or one whose record here was lost — status names it as such rather than as not ready, since its readiness is never probed, and points at `kici local down`, which does reclaim it. When the port is held by a process that is not a KiCI plane orchestrator, `kici local status` names that holder instead and points at `KICI_LOCAL_ORCH_PORT`, because `kici local down` will not stop it.
|
|
1384
1384
|
|
|
1385
|
+
The plane writes its orchestrator log to `orchestrator.log` in its state directory and, when it runs embedded PostgreSQL, the PostgreSQL log to `orchestrator.log.pg` beside it. `kici local logs` prints their location. Each is rotated to a `.1` sibling when it reaches 50 MB, at the next plane start — the plane keeps the current log and one previous generation, so neither can grow without bound.
|
|
1386
|
+
|
|
1385
1387
|
Pass `--json` for machine-readable output. It prints one object and exits 0 for
|
|
1386
1388
|
every state, including when the plane is stopped — the state is in the payload,
|
|
1387
1389
|
not the exit code:
|
|
@@ -1674,7 +1676,7 @@ Synopsis: `kici local down`
|
|
|
1674
1676
|
|
|
1675
1677
|
### `kici local logs`
|
|
1676
1678
|
|
|
1677
|
-
Print the local dev plane
|
|
1679
|
+
Print the local dev plane log paths and rotation policy
|
|
1678
1680
|
|
|
1679
1681
|
Synopsis: `kici local logs`
|
|
1680
1682
|
|
|
@@ -607,7 +607,7 @@ The KiCI CLI reads the following environment variables to customize its behavior
|
|
|
607
607
|
|
|
608
608
|
| Variable | Description | Default |
|
|
609
609
|
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
|
|
610
|
-
| `KICI_DEV` | Enable development mode. When `true`,
|
|
610
|
+
| `KICI_DEV` | Enable development mode. When `true`, pins `@kici-dev/sdk` to the `latest` dist-tag (so a dev registry's prerelease build resolves) and skips npm version resolution. | unset |
|
|
611
611
|
| `KICI_DEV_REGISTRY` | npm registry the `@kici-dev` scope points at when `KICI_DEV` is set. `kici init` writes it into `.npmrc`; with no value it writes no `.npmrc`. | unset |
|
|
612
612
|
| `KICI_DEBUG` | Enable debug logging. When `true`, prints verbose diagnostics (SDK alias resolution, step-level debug logs, stack traces on errors). Equivalent to the `--debug` CLI flag. | unset |
|
|
613
613
|
|
|
@@ -590,7 +590,7 @@ Point to a local SDK checkout for IDE autocompletion:
|
|
|
590
590
|
{
|
|
591
591
|
"name": "my-project-kici",
|
|
592
592
|
"devDependencies": {
|
|
593
|
-
"@kici-dev/sdk": "
|
|
593
|
+
"@kici-dev/sdk": "latest"
|
|
594
594
|
},
|
|
595
595
|
"kici": {
|
|
596
596
|
"sdkPath": "../../packages/sdk"
|
|
@@ -602,7 +602,7 @@ The `sdkPath` field tells the compiler where to resolve TypeScript path mappings
|
|
|
602
602
|
|
|
603
603
|
### KICI_DEV environment variable
|
|
604
604
|
|
|
605
|
-
Set `KICI_DEV=true` to
|
|
605
|
+
Set `KICI_DEV=true` to pin the SDK to the `latest` dist-tag in generated files, which resolves prerelease builds from a local Verdaccio registry:
|
|
606
606
|
|
|
607
607
|
```bash
|
|
608
608
|
KICI_DEV=true npx kici init
|
|
@@ -6502,6 +6502,17 @@ interface StepContext<TInputs = Record<string, unknown>> {
|
|
|
6502
6502
|
provider?: string;
|
|
6503
6503
|
/** Whether this execution was triggered by `kici run remote` (developer-initiated remote run) */
|
|
6504
6504
|
isTestRun: boolean;
|
|
6505
|
+
/** The job's own checked-out repository (present for every job that checks out); `withWrite` opens a write window for it — see [Git credentials](https://docs.kici.dev/user/patterns/git-credentials/) */
|
|
6506
|
+
repo?: {
|
|
6507
|
+
identifier: string;
|
|
6508
|
+
path: string;
|
|
6509
|
+
ref?: string;
|
|
6510
|
+
sha?: string;
|
|
6511
|
+
withWrite(
|
|
6512
|
+
opts: { permissions?: Record<string, string>; credential?: string },
|
|
6513
|
+
fn: () => Promise<void>,
|
|
6514
|
+
): Promise<void>;
|
|
6515
|
+
};
|
|
6505
6516
|
/** Registering repo of a global workflow (undefined for non-global workflows) */
|
|
6506
6517
|
workflowRepo?: RepoInfo;
|
|
6507
6518
|
/** Repo where the triggering event occurred (undefined for non-global workflows) */
|
|
@@ -8573,7 +8584,7 @@ Manage the **local dev plane** — the warm, per-user orchestrator (plus its own
|
|
|
8573
8584
|
kici local up [--offline | --connected] # Start, or reuse an already-running plane
|
|
8574
8585
|
kici local status [--json] # Port, pid, PostgreSQL backend, attachment mode, readiness
|
|
8575
8586
|
kici local down # Stop the orchestrator and its PostgreSQL, verifying the port is freed
|
|
8576
|
-
kici local logs # Print the
|
|
8587
|
+
kici local logs # Print the plane log paths and rotation policy
|
|
8577
8588
|
kici local attach # Attach to the Platform (hybrid mode)
|
|
8578
8589
|
kici local detach # Return the plane to offline (independent) mode
|
|
8579
8590
|
kici local trust-root <file> # Export the dev-signed trust root for offline verification
|
|
@@ -8590,6 +8601,8 @@ The plane runs in one of two modes:
|
|
|
8590
8601
|
|
|
8591
8602
|
`kici local status` reports a plane whose process is alive but whose readiness probe fails — for example when its PostgreSQL has stopped — as running but not ready, together with its readiness checks, rather than as not running. When the holder is a KiCI plane orchestrator that this config directory did not start — a plane belonging to another `KICI_CONFIG_DIR`, or one whose record here was lost — status names it as such rather than as not ready, since its readiness is never probed, and points at `kici local down`, which does reclaim it. When the port is held by a process that is not a KiCI plane orchestrator, `kici local status` names that holder instead and points at `KICI_LOCAL_ORCH_PORT`, because `kici local down` will not stop it.
|
|
8592
8603
|
|
|
8604
|
+
The plane writes its orchestrator log to `orchestrator.log` in its state directory and, when it runs embedded PostgreSQL, the PostgreSQL log to `orchestrator.log.pg` beside it. `kici local logs` prints their location. Each is rotated to a `.1` sibling when it reaches 50 MB, at the next plane start — the plane keeps the current log and one previous generation, so neither can grow without bound.
|
|
8605
|
+
|
|
8593
8606
|
Pass `--json` for machine-readable output. It prints one object and exits 0 for
|
|
8594
8607
|
every state, including when the plane is stopped — the state is in the payload,
|
|
8595
8608
|
not the exit code:
|
|
@@ -8882,7 +8895,7 @@ Synopsis: `kici local down`
|
|
|
8882
8895
|
|
|
8883
8896
|
### `kici local logs`
|
|
8884
8897
|
|
|
8885
|
-
Print the local dev plane
|
|
8898
|
+
Print the local dev plane log paths and rotation policy
|
|
8886
8899
|
|
|
8887
8900
|
Synopsis: `kici local logs`
|
|
8888
8901
|
|
|
@@ -9747,7 +9760,7 @@ In interactive mode (TTY), `kici init` prompts you to:
|
|
|
9747
9760
|
|
|
9748
9761
|
**Standalone vs workspace integration:** by default `kici init` scaffolds a self-contained `.kici/` with its own `package.json`. When run inside a pnpm, npm, or yarn workspace, it offers an **integrate** option (or pass `--workspace`): `.kici/` joins the workspace, `@kici-dev/sdk` is added to your workspace-root `package.json`, and your workflows can `import` your other workspace packages (e.g. shared build or deploy utilities). In this mode there is no `.kici/package.json` — the workspace root manages dependencies, and the root install resolves the SDK. Your workflows resolve sibling packages through the workspace-root `node_modules`: under npm and yarn every workspace member is hoisted there automatically, while pnpm links only your root's declared dependencies, so under pnpm add the package you want to import to your workspace-root `dependencies` (this is how KiCI's own repository imports its packages from workflows). Pass `--standalone` to force the self-contained layout even inside a workspace. In CI / non-interactive runs the default is standalone; use `--workspace` to opt in explicitly. `--workspace` and `--standalone` are mutually exclusive, and `--workspace` errors if no workspace is found at or above the current directory.
|
|
9749
9762
|
|
|
9750
|
-
**Development mode:** When `KICI_DEV=true` or `package.json` has `"kici": { "development": true }`, the generated `package.json`
|
|
9763
|
+
**Development mode:** When `KICI_DEV=true` or `package.json` has `"kici": { "development": true }`, the generated `package.json` pins `@kici-dev/sdk` to the `latest` dist-tag so npm resolves Verdaccio's newest prerelease build.
|
|
9751
9764
|
|
|
9752
9765
|
### kici org
|
|
9753
9766
|
|
|
@@ -10693,6 +10706,18 @@ Secrets are always sourced from your real `.kici/` directory, not from the isola
|
|
|
10693
10706
|
|
|
10694
10707
|
Pass `--in-place` to run against the real working directory instead — useful when you explicitly want in-tree execution. `--in-place` requires no git repository; the default isolated mode does, and fails with an actionable error pointing at `--in-place` when the directory is not a git repository.
|
|
10695
10708
|
|
|
10709
|
+
**If the trigger times out:**
|
|
10710
|
+
|
|
10711
|
+
The command waits up to 60 seconds for the local dev plane to create the run. If nothing appears in that window it stops and names the cause it read back from the plane:
|
|
10712
|
+
|
|
10713
|
+
| Message | What it means |
|
|
10714
|
+
| ------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
10715
|
+
| `plane is not leader yet (election grace period)` | The plane had not finished electing itself. A single-machine plane elects within seconds; if it does not, read the plane log (`kici local logs`). |
|
|
10716
|
+
| `no kici.lock.json at <commit> in <path>` | The plane resolved no lock file for the commit the run packed, so nothing matched. Commit `.kici/kici.lock.json`, or make sure it is present in the working tree. |
|
|
10717
|
+
| `the plane recorded delivery <id> as "<status>"` | The plane processed the trigger and wrote down a terminal status for it without creating a run. The status names the stage that stopped. |
|
|
10718
|
+
| `no run appeared for delivery <id> — see <log>` | Neither the plane's cluster state nor its delivery record explained the timeout. The named log is the next place to look. |
|
|
10719
|
+
| `no run appeared for this trigger — the plane never accepted the webhook` | Every webhook POST came back without a delivery id, so the plane never queued the trigger. Check the plane is up (`kici local status`), then read the named log. |
|
|
10720
|
+
|
|
10696
10721
|
**Examples:**
|
|
10697
10722
|
|
|
10698
10723
|
```bash
|
|
@@ -13664,7 +13689,7 @@ The KiCI CLI reads the following environment variables to customize its behavior
|
|
|
13664
13689
|
|
|
13665
13690
|
| Variable | Description | Default |
|
|
13666
13691
|
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
|
|
13667
|
-
| `KICI_DEV` | Enable development mode. When `true`,
|
|
13692
|
+
| `KICI_DEV` | Enable development mode. When `true`, pins `@kici-dev/sdk` to the `latest` dist-tag (so a dev registry's prerelease build resolves) and skips npm version resolution. | unset |
|
|
13668
13693
|
| `KICI_DEV_REGISTRY` | npm registry the `@kici-dev` scope points at when `KICI_DEV` is set. `kici init` writes it into `.npmrc`; with no value it writes no `.npmrc`. | unset |
|
|
13669
13694
|
| `KICI_DEBUG` | Enable debug logging. When `true`, prints verbose diagnostics (SDK alias resolution, step-level debug logs, stack traces on errors). Equivalent to the `--debug` CLI flag. | unset |
|
|
13670
13695
|
|
|
@@ -17394,7 +17419,7 @@ KiCI uses three WebSocket layers for real-time communication.
|
|
|
17394
17419
|
|
|
17395
17420
|
### Platform ↔ Orchestrator
|
|
17396
17421
|
|
|
17397
|
-
The orchestrator connects outbound to the Platform WebSocket endpoint. After authentication (API key validated via SHA-256 hash lookup), the connection is used for webhook relay, execution telemetry (events, status, logs), source registration, and peer discovery.
|
|
17422
|
+
The orchestrator connects outbound to the Platform WebSocket endpoint. After authentication (API key validated via SHA-256 hash lookup), the connection is used for webhook relay, execution telemetry (events, status, logs), source registration, and peer discovery. Peer discovery is matchmaking only: the Platform pushes a `peer.update` membership list to every orchestrator sharing a routing key, and the orchestrators then connect to each other directly. Inter-orchestrator traffic such as `job.reroute` never transits the Platform.
|
|
17398
17423
|
|
|
17399
17424
|
### Orchestrator ↔ Orchestrator (P2P)
|
|
17400
17425
|
|
|
@@ -588,7 +588,7 @@ Point to a local SDK checkout for IDE autocompletion:
|
|
|
588
588
|
{
|
|
589
589
|
"name": "my-project-kici",
|
|
590
590
|
"devDependencies": {
|
|
591
|
-
"@kici-dev/sdk": "
|
|
591
|
+
"@kici-dev/sdk": "latest"
|
|
592
592
|
},
|
|
593
593
|
"kici": {
|
|
594
594
|
"sdkPath": "../../packages/sdk"
|
|
@@ -600,7 +600,7 @@ The `sdkPath` field tells the compiler where to resolve TypeScript path mappings
|
|
|
600
600
|
|
|
601
601
|
### KICI_DEV environment variable
|
|
602
602
|
|
|
603
|
-
Set `KICI_DEV=true` to
|
|
603
|
+
Set `KICI_DEV=true` to pin the SDK to the `latest` dist-tag in generated files, which resolves prerelease builds from a local Verdaccio registry:
|
|
604
604
|
|
|
605
605
|
```bash
|
|
606
606
|
KICI_DEV=true npx kici init
|
|
@@ -1332,6 +1332,17 @@ interface StepContext<TInputs = Record<string, unknown>> {
|
|
|
1332
1332
|
provider?: string;
|
|
1333
1333
|
/** Whether this execution was triggered by `kici run remote` (developer-initiated remote run) */
|
|
1334
1334
|
isTestRun: boolean;
|
|
1335
|
+
/** The job's own checked-out repository (present for every job that checks out); `withWrite` opens a write window for it — see [Git credentials](https://docs.kici.dev/user/patterns/git-credentials/) */
|
|
1336
|
+
repo?: {
|
|
1337
|
+
identifier: string;
|
|
1338
|
+
path: string;
|
|
1339
|
+
ref?: string;
|
|
1340
|
+
sha?: string;
|
|
1341
|
+
withWrite(
|
|
1342
|
+
opts: { permissions?: Record<string, string>; credential?: string },
|
|
1343
|
+
fn: () => Promise<void>,
|
|
1344
|
+
): Promise<void>;
|
|
1345
|
+
};
|
|
1335
1346
|
/** Registering repo of a global workflow (undefined for non-global workflows) */
|
|
1336
1347
|
workflowRepo?: RepoInfo;
|
|
1337
1348
|
/** Repo where the triggering event occurred (undefined for non-global workflows) */
|
|
@@ -15,7 +15,7 @@ Each bundle below is a self-contained markdown file for one authoring task. Fetc
|
|
|
15
15
|
- [sdk](https://docs.kici.dev/llms-sdk.txt) (131 KB) — Core authoring API: workflow/job/step factories, triggers, rules, matrix, dynamic jobs, cross-job outputs
|
|
16
16
|
- [sdk-runtime](https://docs.kici.dev/llms-sdk-runtime.txt) (115 KB) — Runtime and advanced authoring: step runtime context, event payloads, host fan-out, idempotent steps, caching, artifacts, waiting
|
|
17
17
|
- [cli](https://docs.kici.dev/llms-cli.txt) (97 KB) — Running the CLI locally: compile, test, run local, hooks, lock-file drift, common failures
|
|
18
|
-
- [cli-remote](https://docs.kici.dev/llms-cli-remote.txt) (
|
|
18
|
+
- [cli-remote](https://docs.kici.dev/llms-cli-remote.txt) (111 KB) — Auth, org and orchestrator selection, runs, approvals, notifications, diagnostics, and the MCP server a coding agent connects to
|
|
19
19
|
- [features](https://docs.kici.dev/llms-features.txt) (97 KB) — Deployment contexts, scoped secrets, private registries, approvals, provenance, dashboard and account access
|
|
20
20
|
- [features-execution](https://docs.kici.dev/llms-features-execution.txt) (124 KB) — Concurrency, dynamic values, events, container jobs, environment variables, global workflows, idempotent steps
|
|
21
21
|
- [providers](https://docs.kici.dev/llms-providers.txt) (35 KB) — Connecting sources: GitHub App, universal-git (Forgejo/Gitea/GitLab), local file://
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import "../rolldown-runtime-ClRpJifh.js";
|
|
2
2
|
import { planePaths, planePorts } from "./paths.js";
|
|
3
|
+
import { rotatePlaneLogIfOversized } from "./plane-log.js";
|
|
3
4
|
import { createRequire } from "node:module";
|
|
4
5
|
import fs from "node:fs";
|
|
5
6
|
import { spawn } from "node:child_process";
|
|
@@ -48,6 +49,7 @@ function spawnOrchestratorProcess(databaseUrl, opts) {
|
|
|
48
49
|
const { logFile, root, cacheDir } = planePaths();
|
|
49
50
|
fs.mkdirSync(root, { recursive: true });
|
|
50
51
|
fs.mkdirSync(cacheDir, { recursive: true });
|
|
52
|
+
rotatePlaneLogIfOversized(logFile);
|
|
51
53
|
const out = fs.openSync(logFile, "a");
|
|
52
54
|
const baseEnv = {};
|
|
53
55
|
for (const [key, value] of Object.entries(process.env)) if (!key.startsWith("KICI_")) baseEnv[key] = value;
|
|
@@ -58,6 +60,7 @@ function spawnOrchestratorProcess(databaseUrl, opts) {
|
|
|
58
60
|
KICI_AGENT_AUTH: "none",
|
|
59
61
|
KICI_HOST: "127.0.0.1",
|
|
60
62
|
KICI_AUTO_MIGRATE: "true",
|
|
63
|
+
KICI_CLUSTER_SINGLE_NODE: "true",
|
|
61
64
|
KICI_DATA_DIR: root,
|
|
62
65
|
KICI_BOOTSTRAP_ADMIN_TOKEN: opts.adminToken,
|
|
63
66
|
KICI_SECRET_KEY: opts.secretKey,
|
|
@@ -48,6 +48,7 @@ function planePaths() {
|
|
|
48
48
|
pidfile: path.join(root, "plane.pid"),
|
|
49
49
|
stampFile: path.join(root, "stamp.json"),
|
|
50
50
|
logFile: path.join(root, "orchestrator.log"),
|
|
51
|
+
pgLogFile: path.join(root, "orchestrator.log.pg"),
|
|
51
52
|
socketDir: path.join(root, "sock"),
|
|
52
53
|
adminTokenFile: path.join(root, "admin-token"),
|
|
53
54
|
platformTokenFile: path.join(root, "platform-token"),
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Size at which a local dev plane log is rotated on the next plane start.
|
|
3
|
+
*
|
|
4
|
+
* The plane's orchestrator writes one JSON line per request and per
|
|
5
|
+
* scheduled-job tick, and nothing truncates the file between boots, so an
|
|
6
|
+
* unrotated log grows without bound. 50 MB is roughly 200k lines — more history
|
|
7
|
+
* than a local debugging session reads.
|
|
8
|
+
*/
|
|
9
|
+
export declare const PLANE_LOG_MAX_BYTES: number;
|
|
10
|
+
/** The cap expressed in whole megabytes, for the messages that name it. */
|
|
11
|
+
export declare const PLANE_LOG_MAX_MB: number;
|
|
12
|
+
/**
|
|
13
|
+
* Rotate `file` to `<file>.1` once it reaches `PLANE_LOG_MAX_BYTES`, keeping two
|
|
14
|
+
* generations: any previous `.1` is discarded.
|
|
15
|
+
*
|
|
16
|
+
* Call this only where nothing holds the file open. A rename under a live
|
|
17
|
+
* writer leaves that writer appending to the renamed inode, so the live log
|
|
18
|
+
* would stay empty for the rest of the process's life.
|
|
19
|
+
*
|
|
20
|
+
* Every failure is swallowed on purpose. Both callers are on a plane-boot path:
|
|
21
|
+
* `startPlanePostgres` reads a throw as "embedded Postgres is unavailable" and
|
|
22
|
+
* silently falls back to a Podman container, and `spawnOrchestratorProcess`
|
|
23
|
+
* would fail the boot outright. A log that cannot be rotated must not cost the
|
|
24
|
+
* user their plane.
|
|
25
|
+
*/
|
|
26
|
+
export declare function rotatePlaneLogIfOversized(file: string): void;
|
|
27
|
+
//# sourceMappingURL=plane-log.d.ts.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import "../rolldown-runtime-ClRpJifh.js";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
//#region src/local-plane/plane-log.ts
|
|
4
|
+
/**
|
|
5
|
+
* Size at which a local dev plane log is rotated on the next plane start.
|
|
6
|
+
*
|
|
7
|
+
* The plane's orchestrator writes one JSON line per request and per
|
|
8
|
+
* scheduled-job tick, and nothing truncates the file between boots, so an
|
|
9
|
+
* unrotated log grows without bound. 50 MB is roughly 200k lines — more history
|
|
10
|
+
* than a local debugging session reads.
|
|
11
|
+
*/
|
|
12
|
+
const PLANE_LOG_MAX_BYTES = 52428800;
|
|
13
|
+
/** The cap expressed in whole megabytes, for the messages that name it. */
|
|
14
|
+
const PLANE_LOG_MAX_MB = PLANE_LOG_MAX_BYTES / 1048576;
|
|
15
|
+
/**
|
|
16
|
+
* Rotate `file` to `<file>.1` once it reaches `PLANE_LOG_MAX_BYTES`, keeping two
|
|
17
|
+
* generations: any previous `.1` is discarded.
|
|
18
|
+
*
|
|
19
|
+
* Call this only where nothing holds the file open. A rename under a live
|
|
20
|
+
* writer leaves that writer appending to the renamed inode, so the live log
|
|
21
|
+
* would stay empty for the rest of the process's life.
|
|
22
|
+
*
|
|
23
|
+
* Every failure is swallowed on purpose. Both callers are on a plane-boot path:
|
|
24
|
+
* `startPlanePostgres` reads a throw as "embedded Postgres is unavailable" and
|
|
25
|
+
* silently falls back to a Podman container, and `spawnOrchestratorProcess`
|
|
26
|
+
* would fail the boot outright. A log that cannot be rotated must not cost the
|
|
27
|
+
* user their plane.
|
|
28
|
+
*/
|
|
29
|
+
function rotatePlaneLogIfOversized(file) {
|
|
30
|
+
try {
|
|
31
|
+
if (fs.statSync(file).size < 52428800) return;
|
|
32
|
+
fs.rmSync(`${file}.1`, { force: true });
|
|
33
|
+
fs.renameSync(file, `${file}.1`);
|
|
34
|
+
} catch {}
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { PLANE_LOG_MAX_BYTES, PLANE_LOG_MAX_MB, rotatePlaneLogIfOversized };
|
|
38
|
+
|
|
39
|
+
//# sourceMappingURL=plane-log.js.map
|
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
* The source's bundle hot-reload is debounced, so a first trigger can land
|
|
12
12
|
* before the plane has registered the (re-pointed) local source. This resends
|
|
13
13
|
* the webhook after a grace window until a run appears or the timeout elapses.
|
|
14
|
+
* When the budget still runs out, the timeout is explained rather than merely
|
|
15
|
+
* reported: the plane's own Raft role and its event-log record for this
|
|
16
|
+
* delivery decide which cause is named.
|
|
14
17
|
*/
|
|
15
18
|
/** A minimal admin-read client (AdminApiClient.get) — injectable for tests. */
|
|
16
19
|
export interface RunDiscoveryClient {
|
|
@@ -58,7 +61,32 @@ export interface TriggerRunOptions {
|
|
|
58
61
|
pollIntervalMs?: number;
|
|
59
62
|
resendAfterMs?: number;
|
|
60
63
|
timeoutMs?: number;
|
|
64
|
+
/** Workdir the plane's local source points at — named in the lock-file diagnosis. */
|
|
65
|
+
repoBasePath?: string;
|
|
66
|
+
/** Plane log path — named when nothing else explains the timeout. */
|
|
67
|
+
logPath?: string;
|
|
61
68
|
}
|
|
69
|
+
/** What the diagnosis knows about the trigger that just timed out. */
|
|
70
|
+
export interface TriggerTimeoutContext {
|
|
71
|
+
/** Routing-key-scoped delivery id, or null when the plane never accepted the webhook. */
|
|
72
|
+
deliveryId: string | null;
|
|
73
|
+
orgId: string;
|
|
74
|
+
/** Commit the synthetic push carried (the workdir's overlay commit). */
|
|
75
|
+
sha: string;
|
|
76
|
+
/** Absolute path the plane's local source points at — the run's workdir. */
|
|
77
|
+
repoBasePath?: string;
|
|
78
|
+
/** Plane log path, named in the fallback so the developer has somewhere to look. */
|
|
79
|
+
logPath?: string;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Explain a trigger timeout in one line, from what the plane itself recorded.
|
|
83
|
+
*
|
|
84
|
+
* Ordered most-specific-first, and every branch is a fact read back off the
|
|
85
|
+
* plane rather than an inference: the Raft role it reports, then the status it
|
|
86
|
+
* wrote for THIS delivery, then the delivery id + log path so the developer has
|
|
87
|
+
* a thread to pull even when neither surface answered.
|
|
88
|
+
*/
|
|
89
|
+
export declare function diagnoseTriggerTimeout(client: RunDiscoveryClient, ctx: TriggerTimeoutContext): Promise<string>;
|
|
62
90
|
/**
|
|
63
91
|
* Trigger the run and resolve its runId. Sends the synthetic push, then polls
|
|
64
92
|
* the admin runs list filtered by this webhook's routing-key-scoped delivery id
|