@kici-dev/compiler 0.1.27 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth/headless-detect.d.ts +14 -5
- package/dist/auth/headless-detect.js +50 -9
- package/dist/cli.js +120 -11
- package/dist/commands/compile.js +28 -4
- package/dist/commands/diagnostics.js +14 -2
- package/dist/commands/doctor.d.ts +64 -0
- package/dist/commands/doctor.js +413 -0
- package/dist/commands/endpoints.js +6 -0
- package/dist/commands/fixture.js +13 -0
- package/dist/commands/hook.js +3 -2
- package/dist/commands/index.d.ts +8 -0
- package/dist/commands/index.js +5 -1
- package/dist/commands/init-host-os.d.ts +34 -0
- package/dist/commands/init-host-os.js +44 -0
- package/dist/commands/init.d.ts +4 -0
- package/dist/commands/init.js +159 -36
- package/dist/commands/local.d.ts +28 -2
- package/dist/commands/local.js +74 -5
- package/dist/commands/login.js +1 -1
- package/dist/commands/notifications.d.ts +61 -0
- package/dist/commands/notifications.js +274 -0
- package/dist/commands/preview.js +8 -1
- package/dist/commands/run-routed.js +10 -1
- package/dist/commands/run.js +41 -12
- package/dist/commands/runs/artifacts/download.d.ts +24 -0
- package/dist/commands/runs/artifacts/download.js +154 -0
- package/dist/commands/runs/artifacts/list.d.ts +5 -0
- package/dist/commands/runs/artifacts/list.js +47 -0
- package/dist/commands/runs/cancel.js +2 -2
- package/dist/commands/runs/list.js +8 -2
- package/dist/commands/verify-attestation.d.ts +3 -1
- package/dist/commands/verify-attestation.js +18 -7
- package/dist/errors/formatter.d.ts +14 -1
- package/dist/errors/formatter.js +13 -3
- package/dist/errors/index.d.ts +2 -1
- package/dist/errors/index.js +3 -2
- package/dist/errors/source-location.d.ts +20 -0
- package/dist/errors/source-location.js +45 -0
- package/dist/execution/executor.js +25 -5
- package/dist/fixtures/defaults/index.js +2 -1
- package/dist/llm-context/llms-architecture.txt +48 -19
- package/dist/llm-context/llms-cli.txt +2461 -1582
- package/dist/llm-context/llms-features.txt +178 -106
- package/dist/llm-context/llms-full.txt +6124 -4423
- package/dist/llm-context/llms-getting-started.txt +306 -42
- package/dist/llm-context/llms-patterns.txt +13 -7
- package/dist/llm-context/llms-sdk-runtime.txt +2013 -0
- package/dist/llm-context/llms-sdk.txt +591 -2152
- package/dist/llm-context/llms.txt +30 -16
- package/dist/local-plane/orchestrator-process.d.ts +12 -7
- package/dist/local-plane/orchestrator-process.js +28 -14
- package/dist/local-plane/os-mismatch-hint.d.ts +16 -0
- package/dist/local-plane/os-mismatch-hint.js +34 -0
- package/dist/local-plane/plane-liveness.d.ts +68 -0
- package/dist/local-plane/plane-liveness.js +145 -0
- package/dist/local-plane/plane-manager.d.ts +60 -18
- package/dist/local-plane/plane-manager.js +210 -70
- package/dist/local-plane/plane-trigger.d.ts +13 -4
- package/dist/local-plane/plane-trigger.js +27 -14
- package/dist/local-plane/platform-attach.js +1 -5
- package/dist/local-plane/port-holder.d.ts +78 -0
- package/dist/local-plane/port-holder.js +227 -0
- package/dist/local-plane/postgres.d.ts +15 -3
- package/dist/local-plane/postgres.js +34 -12
- package/dist/local-plane/run-follow.d.ts +20 -0
- package/dist/local-plane/run-follow.js +51 -4
- package/dist/local-plane/scaler-config.d.ts +28 -14
- package/dist/local-plane/scaler-config.js +59 -41
- package/dist/local-plane/source-provider.js +4 -10
- package/dist/lockfile/generator.d.ts +14 -1
- package/dist/lockfile/generator.js +99 -33
- package/dist/lockfile/index.d.ts +3 -1
- package/dist/lockfile/index.js +3 -2
- package/dist/lockfile/purity-diagnostics.d.ts +31 -0
- package/dist/lockfile/purity-diagnostics.js +52 -0
- package/dist/postinstall.js +2 -1
- package/dist/remote/artifact-extract.d.ts +8 -0
- package/dist/remote/artifact-extract.js +58 -0
- package/dist/remote/config.d.ts +21 -3
- package/dist/remote/config.js +24 -5
- package/dist/remote/dashboard-client.d.ts +39 -2
- package/dist/remote/dashboard-client.js +47 -4
- package/dist/remote/fs-case.d.ts +21 -0
- package/dist/remote/fs-case.js +45 -0
- package/dist/remote/history.d.ts +9 -3
- package/dist/remote/history.js +79 -10
- package/dist/remote/local-repo-identity.d.ts +1 -1
- package/dist/remote/local-repo-identity.js +2 -1
- package/dist/remote/notifications-client.d.ts +149 -0
- package/dist/remote/notifications-client.js +103 -0
- package/dist/remote/oauth.d.ts +13 -0
- package/dist/remote/oauth.js +31 -5
- package/dist/remote/output/summary.js +76 -14
- package/dist/remote/render.js +30 -9
- package/dist/remote/uploader.js +5 -4
- package/dist/templates/agents-md.d.ts +1 -1
- package/dist/templates/agents-md.js +6 -6
- package/dist/templates/index.d.ts +1 -1
- package/dist/templates/index.js +2 -2
- package/dist/templates/package-json.d.ts +15 -0
- package/dist/templates/package-json.js +26 -5
- package/dist/test-runner/dry-run.d.ts +2 -1
- package/dist/test-runner/dry-run.js +18 -1
- package/dist/test-runner/event-types.d.ts +2 -0
- package/dist/test-runner/event-types.js +3 -0
- package/dist/test-runner/job-executor.d.ts +1 -0
- package/dist/test-runner/job-executor.js +81 -43
- package/dist/test-runner/output-formatter.d.ts +5 -2
- package/dist/test-runner/output-formatter.js +6 -4
- package/dist/test-runner/payload-builder.d.ts +7 -1
- package/dist/test-runner/payload-builder.js +11 -2
- package/dist/test-runner/rule-evaluator.d.ts +7 -3
- package/dist/test-runner/rule-evaluator.js +13 -12
- package/dist/test-runner/step-context.d.ts +23 -5
- package/dist/test-runner/step-context.js +28 -118
- package/dist/types.d.ts +21 -2
- package/dist/types.js +4 -2
- package/dist/validation/index.d.ts +2 -0
- package/dist/validation/index.js +2 -1
- package/dist/validation/typecheck.d.ts +28 -0
- package/dist/validation/typecheck.js +110 -0
- package/dist/validation/validator.d.ts +9 -4
- package/dist/validation/validator.js +38 -44
- package/package.json +12 -15
- package/sbom.spdx.json +1322 -1964
- package/dist/assets/api-TJJVHrjC.json +0 -118
- package/dist/assets/descriptor-BTtjzN9L.json +0 -1382
- package/dist/assets/package-BpQF9kR8.json +0 -74
- package/dist/assets/package-Ceo2h27X.json +0 -89
- package/dist/assets/source_context-D0atuL28.json +0 -20
- package/dist/assets/type-BFqO8SCZ.json +0 -202
- package/dist/commands/cancel.d.ts +0 -22
- package/dist/commands/detect-package-manager.d.ts +0 -42
- package/dist/commands/held-run-resolve.d.ts +0 -50
- package/dist/commands/status.d.ts +0 -34
- package/dist/commands/test.d.ts +0 -88
- package/dist/errors/codes.d.ts +0 -25
- package/dist/local-executor/dag-scheduler.d.ts +0 -44
- package/dist/local-executor/index.d.ts +0 -23
- package/dist/local-executor/job-runner.d.ts +0 -47
- package/dist/local-executor/materializer.d.ts +0 -44
- package/dist/local-executor/output-streamer.d.ts +0 -31
- package/dist/local-executor/payload-generator.d.ts +0 -16
- package/dist/local-executor/picker.d.ts +0 -33
- package/dist/local-executor/runs-on-display.d.ts +0 -9
- package/dist/local-executor/secret-loader.d.ts +0 -18
- package/dist/local-executor/to-event-payload.d.ts +0 -16
- package/dist/local-executor/types.d.ts +0 -93
- package/dist/local-executor/workflow-lock.d.ts +0 -82
- package/dist/package-F7UXSDHW.json +0 -74
- package/dist/remote/client.d.ts +0 -210
- package/dist/remote/observer.d.ts +0 -81
- package/dist/test-runner/summary.d.ts +0 -7
|
@@ -8,19 +8,23 @@ The full markdown bundle of every page indexed here is available at https://docs
|
|
|
8
8
|
|
|
9
9
|
Each bundle below is a self-contained markdown file for one authoring task. Fetch only the one your task needs instead of the full bundle:
|
|
10
10
|
|
|
11
|
-
- [getting-started](https://docs.kici.dev/llms-getting-started.txt) (
|
|
12
|
-
- [patterns](https://docs.kici.dev/llms-patterns.txt) (
|
|
13
|
-
- [sdk](https://docs.kici.dev/llms-sdk.txt) (
|
|
14
|
-
- [
|
|
15
|
-
- [
|
|
11
|
+
- [getting-started](https://docs.kici.dev/llms-getting-started.txt) (51 KB) — Adopt KiCI: why it exists, how workflows execute, migrating from GitHub Actions, installing the SDK, and writing/compiling/testing your first workflow
|
|
12
|
+
- [patterns](https://docs.kici.dev/llms-patterns.txt) (49 KB) — Copy-paste workflow recipes: triggers, conditionals, matrix, scheduling, integrations
|
|
13
|
+
- [sdk](https://docs.kici.dev/llms-sdk.txt) (110 KB) — Core authoring API: workflow/job/step factories, triggers, rules, matrix, dynamic jobs, cross-job outputs
|
|
14
|
+
- [sdk-runtime](https://docs.kici.dev/llms-sdk-runtime.txt) (112 KB) — Runtime and advanced authoring: step runtime context, event payloads, host fan-out, idempotent steps, caching, artifacts, waiting
|
|
15
|
+
- [cli](https://docs.kici.dev/llms-cli.txt) (185 KB) — Running the CLI: compile, test, run local/remote, auth, hooks, lock-file drift
|
|
16
|
+
- [features](https://docs.kici.dev/llms-features.txt) (135 KB) — Workflow features: concurrency, contexts, secrets, approvals, provenance, events
|
|
16
17
|
- [providers](https://docs.kici.dev/llms-providers.txt) (37 KB) — Connecting sources: GitHub App, universal-git (Forgejo/Gitea/GitLab), local file://
|
|
17
|
-
- [architecture](https://docs.kici.dev/llms-architecture.txt) (
|
|
18
|
+
- [architecture](https://docs.kici.dev/llms-architecture.txt) (92 KB) — How the runtime works: three-tier relay model, data flows, configuration
|
|
18
19
|
|
|
19
20
|
## Getting started
|
|
20
21
|
|
|
21
|
-
- [User guide](https://docs.kici.dev/user/): Writing and testing CI/CD workflows in TypeScript
|
|
22
|
+
- [User guide](https://docs.kici.dev/user/): Writing and testing CI/CD workflows in TypeScript, running on infrastructure you control
|
|
23
|
+
- [How your workflow code executes](https://docs.kici.dev/user/execution-model/): When and where your workflow TypeScript runs — compile time, orchestrator time, and agent time
|
|
22
24
|
- [Getting started with workflows](https://docs.kici.dev/user/getting-started/): Install the SDK, write your first workflow, compile and test locally
|
|
25
|
+
- [Migrating from GitHub Actions](https://docs.kici.dev/user/migrating-from-github-actions/): Map GitHub Actions concepts to KiCI, translate a real workflow side-by-side, and see what has no equivalent yet
|
|
23
26
|
- [5-minute quickstart](https://docs.kici.dev/user/quickstart/): Stand up a KiCI orchestrator + agent and run your first workflow
|
|
27
|
+
- [Why KiCI](https://docs.kici.dev/user/why-kici/): The case for running CI on infrastructure you control, with typed TypeScript workflows you test locally
|
|
24
28
|
|
|
25
29
|
## Workflow patterns
|
|
26
30
|
|
|
@@ -31,30 +35,40 @@ Each bundle below is a self-contained markdown file for one authoring task. Fetc
|
|
|
31
35
|
- [Pattern reference](https://docs.kici.dev/user/patterns/reference/): Step context, examples repository, GitHub check run output — cross-cutting reference for all patterns
|
|
32
36
|
- [Scheduling & event patterns](https://docs.kici.dev/user/patterns/scheduling-and-events/): Nightly cron, workflow-complete-triggered deploys, custom event chaining
|
|
33
37
|
|
|
34
|
-
## SDK reference
|
|
38
|
+
## SDK reference: core
|
|
35
39
|
|
|
36
|
-
- [Caching](https://docs.kici.dev/user/sdk/caching/): Cache files and directories across runs with declarative job/step cache or the imperative ctx.cache API
|
|
37
40
|
- [SDK reference: core](https://docs.kici.dev/user/sdk/core/): Factory functions (workflow, job, step) and authoring patterns: needs, output chaining, dynamic groups
|
|
38
|
-
- [Event payload reference](https://docs.kici.dev/user/sdk/event-payloads/): Generated schema of the normalized event envelope passed to rules and dynamic functions.
|
|
39
|
-
- [SDK reference: idempotent](https://docs.kici.dev/user/sdk/idempotent/): Idempotent helpers for declarative check / apply patterns inside workflow steps
|
|
40
41
|
- [SDK reference: parallel](https://docs.kici.dev/user/sdk/parallel/): Run independent steps concurrently within a single job, each as its own observable step
|
|
41
42
|
- [SDK reference: rules, matrix, dynamic jobs](https://docs.kici.dev/user/sdk/rules-matrix-dynamic/): rule(), skip(), matrix builds (static + dynamic), and dynamicJob / dynamicGroup
|
|
43
|
+
- [SDK reference: triggers](https://docs.kici.dev/user/sdk/triggers/): GitHub event triggers, kiciEvent, workflowComplete, workflowsFailedBatch, jobComplete, genericWebhook, schedule, lifecycle
|
|
44
|
+
- [SDK reference: validation & events](https://docs.kici.dev/user/sdk/validation-events/): validateDag(), event definitions, and event emission
|
|
45
|
+
- [SDK reference](https://docs.kici.dev/user/sdk-reference/): Complete API reference for @kici-dev/sdk -- workflows, jobs, steps, triggers, rules, matrix, validation, runtime
|
|
46
|
+
|
|
47
|
+
## SDK reference: runtime and advanced
|
|
48
|
+
|
|
49
|
+
- [Artifacts](https://docs.kici.dev/user/sdk/artifacts/): Share named, durable build outputs between jobs of a run and download them from the run page with ctx.artifacts
|
|
50
|
+
- [Caching](https://docs.kici.dev/user/sdk/caching/): Cache files and directories across runs with declarative job/step cache or the imperative ctx.cache API
|
|
51
|
+
- [Event payload reference](https://docs.kici.dev/user/sdk/event-payloads/): Generated schema of the normalized event envelope passed to rules and dynamic functions.
|
|
52
|
+
- [SDK reference: idempotent](https://docs.kici.dev/user/sdk/idempotent/): Idempotent helpers for declarative check / apply patterns inside workflow steps
|
|
42
53
|
- [SDK reference: runsOnAll host fan-out](https://docs.kici.dev/user/sdk/runs-on-all/): Fan one job out to every matching connected host, one pinned execution per host
|
|
43
54
|
- [SDK reference: runtime](https://docs.kici.dev/user/sdk/runtime/): Types index, StepContext, secrets, fixtures
|
|
44
|
-
- [SDK reference:
|
|
45
|
-
- [SDK reference: validation & events](https://docs.kici.dev/user/sdk/validation-events/): validateDag(), event definitions, and event emission
|
|
55
|
+
- [SDK reference: temp directories](https://docs.kici.dev/user/sdk/temp-directories/): Allocate job-scoped scratch dirs and files with ctx.mktemp() / ctx.mktempFile()
|
|
46
56
|
- [SDK reference: waitFor](https://docs.kici.dev/user/sdk/wait-for/): Polling helpers for steps that pause until an external condition becomes true
|
|
47
|
-
- [SDK reference](https://docs.kici.dev/user/sdk-reference/): Complete API reference for @kici-dev/sdk -- workflows, jobs, steps, triggers, rules, matrix, validation, runtime
|
|
48
57
|
|
|
49
58
|
## CLI and authoring
|
|
50
59
|
|
|
51
60
|
- [Drive KiCI from your coding agent](https://docs.kici.dev/user/ai-agents/): Point a coding agent at KiCI's MCP server and let it trigger, read, and re-run your CI under your own identity.
|
|
52
61
|
- [CLI authentication](https://docs.kici.dev/user/cli-auth/): Authenticate the KiCI CLI with browser OAuth, device flow, or API key paste
|
|
53
|
-
- [CLI reference](https://docs.kici.dev/user/cli-reference/): All CLI commands: compile,
|
|
62
|
+
- [CLI reference](https://docs.kici.dev/user/cli-reference/): All CLI commands: compile, preview, local, fixture, types, workflows, hook, docs, run, runs, approve, reject, login, logout, init, org, pat, secrets, admin, orchestrators, endpoints, notifications, verify-attestation, diagnostics, doctor
|
|
63
|
+
- [Common failures](https://docs.kici.dev/user/common-failures/): Symptom-to-fix reference for the failures workflow authors hit most — no jobs dispatched, lock-file drift, missing webhooks, and agents that won't connect
|
|
54
64
|
- [Lifecycle hooks](https://docs.kici.dev/user/hooks/): SDK hook API for cancel, cleanup, success, failure, and step-level callbacks
|
|
55
65
|
- [Lock file and workflow drift](https://docs.kici.dev/user/lock-file-and-drift/): Keep the lock file in sync with your workflow source and avoid drift
|
|
56
66
|
- [Testing guide](https://docs.kici.dev/user/testing-guide/): Running remote test fixtures with kici run remote
|
|
57
67
|
- [Workflow patterns](https://docs.kici.dev/user/workflow-patterns/): Common patterns: monorepo builds, conditional jobs, dynamic matrices, generic webhooks, scheduling
|
|
68
|
+
- [kici: account & org](https://docs.kici.dev/user/cli/account-and-org/): Login, org selection, personal access tokens, secrets, and admin
|
|
69
|
+
- [kici: authoring & local dev](https://docs.kici.dev/user/cli/authoring-and-local/): Compile, preview, local execution, fixtures, types, workflows, hooks, and docs
|
|
70
|
+
- [kici: notifications & diagnostics](https://docs.kici.dev/user/cli/notifications-and-diagnostics/): Notification channels, attestation verification, and diagnostics
|
|
71
|
+
- [kici: runs & approvals](https://docs.kici.dev/user/cli/runs-and-approvals/): Run push and inspection plus approval / rejection of held runs
|
|
58
72
|
|
|
59
73
|
## Workflow features
|
|
60
74
|
|
|
@@ -64,7 +78,7 @@ Each bundle below is a self-contained markdown file for one authoring task. Fetc
|
|
|
64
78
|
- [Contexts](https://docs.kici.dev/user/contexts/): Configure deployment contexts with variables, secrets, and protection rules
|
|
65
79
|
- [Dashboard](https://docs.kici.dev/user/dashboard/): Web UI for monitoring workflow runs, managing sources, secrets, and organization settings.
|
|
66
80
|
- [Dynamic values](https://docs.kici.dev/user/dynamic-values/)
|
|
67
|
-
- [Environment variables](https://docs.kici.dev/user/env-vars/):
|
|
81
|
+
- [Environment variables](https://docs.kici.dev/user/env-vars/): Environment variable reference for the CLI
|
|
68
82
|
- [Event system](https://docs.kici.dev/user/events/): How KiCI's event model works -- event types, the registration model, event matching, and circuit breaker protection
|
|
69
83
|
- [Global workflows](https://docs.kici.dev/user/global-workflows/): Cross-repo workflows that run on events from any repo in the same org
|
|
70
84
|
- [Idempotent steps and check mode](https://docs.kici.dev/user/idempotent-steps/): Declare desired state with a step check facet, then run in apply or --check preview mode
|
|
@@ -52,14 +52,19 @@ export interface SpawnOrchestratorOptions {
|
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
|
-
* Spawn the orchestrator
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
55
|
+
* Spawn the orchestrator entry against the local Postgres, detached, with
|
|
56
|
+
* stdout/stderr redirected to the plane log, and return immediately. Boots with
|
|
57
|
+
* a bootstrap admin token (so the CLI can drive the admin API) and a bare-metal
|
|
58
|
+
* scaler (so a dispatched job auto-spawns an ephemeral agent).
|
|
59
|
+
*
|
|
60
|
+
* Returning before the process is ready is deliberate: it lets the caller record
|
|
61
|
+
* the pid on disk BEFORE the readiness wait, so a wait that fails or a CLI that
|
|
62
|
+
* dies mid-boot cannot leave a running orchestrator that nothing can identify.
|
|
60
63
|
*/
|
|
61
|
-
export declare function
|
|
64
|
+
export declare function spawnOrchestratorProcess(databaseUrl: string, opts: SpawnOrchestratorOptions): {
|
|
62
65
|
pid: number;
|
|
63
66
|
port: number;
|
|
64
|
-
}
|
|
67
|
+
};
|
|
68
|
+
/** Poll `/ready` until the orchestrator serves, or throw once the attempts run out. */
|
|
69
|
+
export declare function awaitOrchestratorReady(port: number, attempts?: number, intervalMs?: number): Promise<void>;
|
|
65
70
|
//# sourceMappingURL=orchestrator-process.d.ts.map
|
|
@@ -30,22 +30,32 @@ function resolveStandaloneEntry() {
|
|
|
30
30
|
function resolveServerEntry() {
|
|
31
31
|
return createRequire(import.meta.url).resolve("@kici-dev/orchestrator/server");
|
|
32
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Cap on one readiness probe. Generous enough for a server still warming up,
|
|
35
|
+
* bounded so a socket that accepts and then goes silent cannot stall the poll
|
|
36
|
+
* for the HTTP client's own multi-minute default — which would make
|
|
37
|
+
* `awaitOrchestratorReady`'s attempt budget meaningless.
|
|
38
|
+
*/
|
|
39
|
+
const READY_PROBE_TIMEOUT_MS = 5e3;
|
|
33
40
|
/** Single `/ready` probe against the local orchestrator. */
|
|
34
41
|
async function orchestratorReady(port) {
|
|
35
42
|
try {
|
|
36
|
-
return (await fetch(`http://127.0.0.1:${port}/ready
|
|
43
|
+
return (await fetch(`http://127.0.0.1:${port}/ready`, { signal: AbortSignal.timeout(READY_PROBE_TIMEOUT_MS) })).status === 200;
|
|
37
44
|
} catch {
|
|
38
45
|
return false;
|
|
39
46
|
}
|
|
40
47
|
}
|
|
41
48
|
/**
|
|
42
|
-
* Spawn the orchestrator
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
49
|
+
* Spawn the orchestrator entry against the local Postgres, detached, with
|
|
50
|
+
* stdout/stderr redirected to the plane log, and return immediately. Boots with
|
|
51
|
+
* a bootstrap admin token (so the CLI can drive the admin API) and a bare-metal
|
|
52
|
+
* scaler (so a dispatched job auto-spawns an ephemeral agent).
|
|
53
|
+
*
|
|
54
|
+
* Returning before the process is ready is deliberate: it lets the caller record
|
|
55
|
+
* the pid on disk BEFORE the readiness wait, so a wait that fails or a CLI that
|
|
56
|
+
* dies mid-boot cannot leave a running orchestrator that nothing can identify.
|
|
47
57
|
*/
|
|
48
|
-
|
|
58
|
+
function spawnOrchestratorProcess(databaseUrl, opts) {
|
|
49
59
|
const { orchestrator: port } = planePorts();
|
|
50
60
|
const { logFile, root, cacheDir } = planePaths();
|
|
51
61
|
fs.mkdirSync(root, { recursive: true });
|
|
@@ -100,16 +110,20 @@ async function spawnOrchestrator(databaseUrl, opts) {
|
|
|
100
110
|
}
|
|
101
111
|
});
|
|
102
112
|
child.unref();
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
113
|
+
return {
|
|
114
|
+
pid: child.pid,
|
|
115
|
+
port
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/** Poll `/ready` until the orchestrator serves, or throw once the attempts run out. */
|
|
119
|
+
async function awaitOrchestratorReady(port, attempts = 120, intervalMs = 500) {
|
|
120
|
+
for (let i = 0; i < attempts; i++) {
|
|
121
|
+
if (await orchestratorReady(port)) return;
|
|
122
|
+
await new Promise((r) => setTimeout(r, intervalMs));
|
|
109
123
|
}
|
|
110
124
|
throw new Error("local orchestrator did not become ready");
|
|
111
125
|
}
|
|
112
126
|
//#endregion
|
|
113
|
-
export { orchestratorReady, resolveAgentReachableHost, resolveServerEntry, resolveStandaloneEntry,
|
|
127
|
+
export { awaitOrchestratorReady, orchestratorReady, resolveAgentReachableHost, resolveServerEntry, resolveStandaloneEntry, spawnOrchestratorProcess };
|
|
114
128
|
|
|
115
129
|
//# sourceMappingURL=orchestrator-process.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detect when a routed local run cannot match the host OS.
|
|
3
|
+
*
|
|
4
|
+
* The local dev plane satisfies the host's own `kici:os:*` label (the scaler
|
|
5
|
+
* injects the host's derived OS labels into its bare-metal label sets). A job
|
|
6
|
+
* that requests a DIFFERENT OS than the host — e.g. a workflow authored on Linux
|
|
7
|
+
* run on a Mac — matches no local backend and dispatches nothing. This surfaces
|
|
8
|
+
* that as an honest hint instead of a silent "nothing happened".
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* One hint per job whose `runsOn` requires a `kici:os:*` label the host does not
|
|
12
|
+
* provide. Empty when every job either omits an OS selector or requests the
|
|
13
|
+
* host's own OS.
|
|
14
|
+
*/
|
|
15
|
+
export declare function detectOsMismatchHints(lock: unknown, platform: string, arch: string): string[];
|
|
16
|
+
//# sourceMappingURL=os-mismatch-hint.d.ts.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import "../rolldown-runtime-ClRpJifh.js";
|
|
2
|
+
import { deriveOsArchLabels } from "@kici-dev/engine";
|
|
3
|
+
//#region src/local-plane/os-mismatch-hint.ts
|
|
4
|
+
/**
|
|
5
|
+
* Detect when a routed local run cannot match the host OS.
|
|
6
|
+
*
|
|
7
|
+
* The local dev plane satisfies the host's own `kici:os:*` label (the scaler
|
|
8
|
+
* injects the host's derived OS labels into its bare-metal label sets). A job
|
|
9
|
+
* that requests a DIFFERENT OS than the host — e.g. a workflow authored on Linux
|
|
10
|
+
* run on a Mac — matches no local backend and dispatches nothing. This surfaces
|
|
11
|
+
* that as an honest hint instead of a silent "nothing happened".
|
|
12
|
+
*/
|
|
13
|
+
const OS_LABEL_PREFIX = "kici:os:";
|
|
14
|
+
/**
|
|
15
|
+
* One hint per job whose `runsOn` requires a `kici:os:*` label the host does not
|
|
16
|
+
* provide. Empty when every job either omits an OS selector or requests the
|
|
17
|
+
* host's own OS.
|
|
18
|
+
*/
|
|
19
|
+
function detectOsMismatchHints(lock, platform, arch) {
|
|
20
|
+
const hostOsLabels = new Set(deriveOsArchLabels(platform, arch).filter((l) => l.startsWith(OS_LABEL_PREFIX)));
|
|
21
|
+
const hostPrimary = [...hostOsLabels][0] ?? `${OS_LABEL_PREFIX}${platform}`;
|
|
22
|
+
const hints = [];
|
|
23
|
+
for (const workflow of lock.workflows ?? []) for (const job of workflow.jobs ?? []) {
|
|
24
|
+
const requestedOs = (job.runsOn ?? []).filter((m) => m.kind === "exact" && m.value?.startsWith(OS_LABEL_PREFIX)).map((m) => m.value);
|
|
25
|
+
if (requestedOs.length === 0) continue;
|
|
26
|
+
if (requestedOs.some((l) => hostOsLabels.has(l))) continue;
|
|
27
|
+
hints.push(`Job '${job.name ?? "job"}' wants ${requestedOs.join(", ")} but this host is ${platform} — nothing will dispatch locally. Retry with ${hostPrimary} or edit the job's runsOn in .kici/workflows/.`);
|
|
28
|
+
}
|
|
29
|
+
return hints;
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { detectOsMismatchHints };
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=os-mismatch-hint.js.map
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/** The stamp fields classification needs. Structural, to avoid an import cycle with plane-manager. */
|
|
2
|
+
export interface StampIdentity {
|
|
3
|
+
orchestratorPid: number;
|
|
4
|
+
port: number;
|
|
5
|
+
}
|
|
6
|
+
/** The `/health` fields that identify a KiCI orchestrator. */
|
|
7
|
+
export interface KiciHealth {
|
|
8
|
+
uptime: number;
|
|
9
|
+
version?: string;
|
|
10
|
+
buildCommit?: string;
|
|
11
|
+
}
|
|
12
|
+
export type PlaneState = 'stopped' | 'ready' | 'unready' | 'foreign-kici' | 'foreign-unknown';
|
|
13
|
+
export type PlaneClassification = {
|
|
14
|
+
kind: 'free';
|
|
15
|
+
} | {
|
|
16
|
+
kind: 'ours-ready';
|
|
17
|
+
pid: number;
|
|
18
|
+
} | {
|
|
19
|
+
kind: 'ours-unready';
|
|
20
|
+
pid: number;
|
|
21
|
+
checks: Record<string, boolean>;
|
|
22
|
+
} | {
|
|
23
|
+
kind: 'foreign-kici';
|
|
24
|
+
pid: number | null;
|
|
25
|
+
health: KiciHealth;
|
|
26
|
+
} | {
|
|
27
|
+
kind: 'foreign-unknown';
|
|
28
|
+
pid: number | null;
|
|
29
|
+
};
|
|
30
|
+
export interface PlaneProbes {
|
|
31
|
+
isPortFree(port: number): Promise<boolean>;
|
|
32
|
+
findPortHolderPid(port: number): Promise<number | null>;
|
|
33
|
+
/** The parsed `/health` body, or null when it did not answer in time. */
|
|
34
|
+
fetchHealth(port: number): Promise<unknown>;
|
|
35
|
+
fetchReady(port: number): Promise<{
|
|
36
|
+
ok: boolean;
|
|
37
|
+
checks: Record<string, boolean>;
|
|
38
|
+
}>;
|
|
39
|
+
isPidAlive(pid: number): boolean;
|
|
40
|
+
}
|
|
41
|
+
export interface ReclaimResult {
|
|
42
|
+
freed: boolean;
|
|
43
|
+
killedPid?: number;
|
|
44
|
+
error?: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Whether a `/health` body came from a KiCI orchestrator. The build-fingerprint
|
|
48
|
+
* fields are the discriminator: an `ok` status alone is far too common to
|
|
49
|
+
* justify signalling the process that produced it.
|
|
50
|
+
*/
|
|
51
|
+
export declare function isKiciOrchestratorHealth(body: unknown): body is KiciHealth;
|
|
52
|
+
/** The state label a classification reports to the operator. */
|
|
53
|
+
export declare function planeStateOf(c: PlaneClassification): PlaneState;
|
|
54
|
+
/** The holder pid a classification carries, when it has one. */
|
|
55
|
+
export declare function classificationPid(c: PlaneClassification): number | null;
|
|
56
|
+
/**
|
|
57
|
+
* Decide what, if anything, is holding the plane port and whether it is ours.
|
|
58
|
+
*
|
|
59
|
+
* `stamp` is the on-disk record of the plane this config dir booted; a null
|
|
60
|
+
* stamp means nothing here booted the holder, so any live holder is foreign.
|
|
61
|
+
*/
|
|
62
|
+
export declare function classifyPlane(port: number, stamp: StampIdentity | null, probes?: Partial<PlaneProbes>): Promise<PlaneClassification>;
|
|
63
|
+
/**
|
|
64
|
+
* Free the plane port, if it is ours or another KiCI plane orchestrator. A
|
|
65
|
+
* holder that does not identify as one is reported and left strictly alone.
|
|
66
|
+
*/
|
|
67
|
+
export declare function reclaimPlanePort(port: number, c: PlaneClassification): Promise<ReclaimResult>;
|
|
68
|
+
//# sourceMappingURL=plane-liveness.d.ts.map
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import "../rolldown-runtime-ClRpJifh.js";
|
|
2
|
+
import { findPortHolderPid, isPortFree, terminatePid, waitForPortFree } from "./port-holder.js";
|
|
3
|
+
//#region src/local-plane/plane-liveness.ts
|
|
4
|
+
/**
|
|
5
|
+
* One answer to "is a local dev plane running", shared by up, down, and status.
|
|
6
|
+
*
|
|
7
|
+
* Ownership is decided by pid identity — the process actually holding the port
|
|
8
|
+
* versus the pid the stamp names — not by whether a stamp file exists. That is
|
|
9
|
+
* what keeps the three commands consistent: a plane nobody stamped is foreign to
|
|
10
|
+
* all of them, rather than invisible to two and adoptable by the third.
|
|
11
|
+
*
|
|
12
|
+
* Every external effect arrives through `PlaneProbes`, so the policy here is
|
|
13
|
+
* exercised without a subprocess or a socket.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Cap on each loopback probe. The holder these probes exist to diagnose is
|
|
17
|
+
* frequently wedged, and a socket that accepts a connection but never answers
|
|
18
|
+
* would otherwise hang the CLI for the HTTP client's own multi-minute default —
|
|
19
|
+
* turning `kici local status` into the hang it is meant to explain. A holder
|
|
20
|
+
* that cannot answer loopback within this window is treated as not answering.
|
|
21
|
+
*/
|
|
22
|
+
const PROBE_TIMEOUT_MS = 2e3;
|
|
23
|
+
const defaultProbes = {
|
|
24
|
+
isPortFree,
|
|
25
|
+
findPortHolderPid,
|
|
26
|
+
async fetchHealth(port) {
|
|
27
|
+
try {
|
|
28
|
+
const r = await fetch(`http://127.0.0.1:${port}/health`, { signal: AbortSignal.timeout(PROBE_TIMEOUT_MS) });
|
|
29
|
+
if (!r.ok) return null;
|
|
30
|
+
return await r.json();
|
|
31
|
+
} catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
async fetchReady(port) {
|
|
36
|
+
try {
|
|
37
|
+
const r = await fetch(`http://127.0.0.1:${port}/ready`, { signal: AbortSignal.timeout(PROBE_TIMEOUT_MS) });
|
|
38
|
+
const body = await r.json().catch(() => ({}));
|
|
39
|
+
return {
|
|
40
|
+
ok: r.status === 200,
|
|
41
|
+
checks: body.checks ?? {}
|
|
42
|
+
};
|
|
43
|
+
} catch {
|
|
44
|
+
return {
|
|
45
|
+
ok: false,
|
|
46
|
+
checks: {}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
isPidAlive(pid) {
|
|
51
|
+
try {
|
|
52
|
+
process.kill(pid, 0);
|
|
53
|
+
return true;
|
|
54
|
+
} catch {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Whether a `/health` body came from a KiCI orchestrator. The build-fingerprint
|
|
61
|
+
* fields are the discriminator: an `ok` status alone is far too common to
|
|
62
|
+
* justify signalling the process that produced it.
|
|
63
|
+
*/
|
|
64
|
+
function isKiciOrchestratorHealth(body) {
|
|
65
|
+
if (typeof body !== "object" || body === null) return false;
|
|
66
|
+
const b = body;
|
|
67
|
+
return b.status === "ok" && typeof b.uptime === "number" && "sdkBundleHash" in b && "engineBundleHash" in b;
|
|
68
|
+
}
|
|
69
|
+
/** The state label a classification reports to the operator. */
|
|
70
|
+
function planeStateOf(c) {
|
|
71
|
+
switch (c.kind) {
|
|
72
|
+
case "free": return "stopped";
|
|
73
|
+
case "ours-ready": return "ready";
|
|
74
|
+
case "ours-unready": return "unready";
|
|
75
|
+
case "foreign-kici": return "foreign-kici";
|
|
76
|
+
case "foreign-unknown": return "foreign-unknown";
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/** The holder pid a classification carries, when it has one. */
|
|
80
|
+
function classificationPid(c) {
|
|
81
|
+
return "pid" in c ? c.pid : null;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Decide what, if anything, is holding the plane port and whether it is ours.
|
|
85
|
+
*
|
|
86
|
+
* `stamp` is the on-disk record of the plane this config dir booted; a null
|
|
87
|
+
* stamp means nothing here booted the holder, so any live holder is foreign.
|
|
88
|
+
*/
|
|
89
|
+
async function classifyPlane(port, stamp, probes = {}) {
|
|
90
|
+
const p = {
|
|
91
|
+
...defaultProbes,
|
|
92
|
+
...probes
|
|
93
|
+
};
|
|
94
|
+
if (await p.isPortFree(port)) return { kind: "free" };
|
|
95
|
+
const holderPid = await p.findPortHolderPid(port);
|
|
96
|
+
if ((holderPid !== null ? stamp !== null && holderPid === stamp.orchestratorPid : stamp !== null && p.isPidAlive(stamp.orchestratorPid)) && stamp !== null) {
|
|
97
|
+
const ready = await p.fetchReady(port);
|
|
98
|
+
return ready.ok ? {
|
|
99
|
+
kind: "ours-ready",
|
|
100
|
+
pid: stamp.orchestratorPid
|
|
101
|
+
} : {
|
|
102
|
+
kind: "ours-unready",
|
|
103
|
+
pid: stamp.orchestratorPid,
|
|
104
|
+
checks: ready.checks
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
const health = await p.fetchHealth(port);
|
|
108
|
+
return isKiciOrchestratorHealth(health) ? {
|
|
109
|
+
kind: "foreign-kici",
|
|
110
|
+
pid: holderPid,
|
|
111
|
+
health
|
|
112
|
+
} : {
|
|
113
|
+
kind: "foreign-unknown",
|
|
114
|
+
pid: holderPid
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Free the plane port, if it is ours or another KiCI plane orchestrator. A
|
|
119
|
+
* holder that does not identify as one is reported and left strictly alone.
|
|
120
|
+
*/
|
|
121
|
+
async function reclaimPlanePort(port, c) {
|
|
122
|
+
if (c.kind === "free") return { freed: true };
|
|
123
|
+
if (c.kind === "foreign-unknown") return {
|
|
124
|
+
freed: false,
|
|
125
|
+
error: `port ${port} is held by a process that is not a KiCI plane orchestrator${c.pid === null ? "" : ` (pid ${c.pid})`} — refusing to stop it`
|
|
126
|
+
};
|
|
127
|
+
const pid = classificationPid(c);
|
|
128
|
+
if (pid === null) return {
|
|
129
|
+
freed: false,
|
|
130
|
+
error: `port ${port} is held by a KiCI plane orchestrator whose pid could not be determined`
|
|
131
|
+
};
|
|
132
|
+
await terminatePid(pid);
|
|
133
|
+
return await waitForPortFree(port) ? {
|
|
134
|
+
freed: true,
|
|
135
|
+
killedPid: pid
|
|
136
|
+
} : {
|
|
137
|
+
freed: false,
|
|
138
|
+
killedPid: pid,
|
|
139
|
+
error: `port ${port} is still held after stopping pid ${pid}`
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
//#endregion
|
|
143
|
+
export { classificationPid, classifyPlane, isKiciOrchestratorHealth, planeStateOf, reclaimPlanePort };
|
|
144
|
+
|
|
145
|
+
//# sourceMappingURL=plane-liveness.js.map
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
import { type PlaneState } from './plane-liveness.js';
|
|
2
|
+
/**
|
|
3
|
+
* The current CLI build's identity — semver plus git build commit — read at
|
|
4
|
+
* call time from the Rolldown-injected build constants (`scripts/build-ts.mjs`).
|
|
5
|
+
* Read on each call rather than captured in a module const so unit tests can
|
|
6
|
+
* inject the constants via `globalThis`. Falls back to `0.0.0` / `unknown` when
|
|
7
|
+
* running from source (unbuilt tree / vitest), where the defines are absent.
|
|
8
|
+
*/
|
|
9
|
+
export declare function currentBuildIdentity(): {
|
|
10
|
+
version: string;
|
|
11
|
+
buildCommit: string;
|
|
12
|
+
};
|
|
1
13
|
/** Whether the plane runs offline (independent) or attached to the Platform (hybrid). */
|
|
2
14
|
export type PlaneMode = 'independent' | 'hybrid';
|
|
3
15
|
/**
|
|
@@ -21,12 +33,19 @@ export interface PlaneStamp {
|
|
|
21
33
|
port: number;
|
|
22
34
|
pgKind: 'embedded' | 'podman';
|
|
23
35
|
kiciVersion: string;
|
|
36
|
+
/** Git build commit of the CLI that booted this plane (see planeBuildIsStale). */
|
|
37
|
+
buildCommit: string;
|
|
24
38
|
stampVersion: number;
|
|
25
39
|
/** Offline (independent) vs attached (hybrid). Absent (legacy) reads as independent. */
|
|
26
40
|
mode?: PlaneMode;
|
|
27
41
|
}
|
|
28
42
|
export interface PlaneStatus {
|
|
43
|
+
/** True only when the plane is serving — a live-but-unready plane is false. */
|
|
29
44
|
running: boolean;
|
|
45
|
+
/** Liveness of the plane port: stopped, serving, live-but-not-serving, or held by someone else. */
|
|
46
|
+
state: PlaneState;
|
|
47
|
+
/** Failing `/ready` checks, when the plane is live but not serving. */
|
|
48
|
+
checks?: Record<string, boolean>;
|
|
30
49
|
pid?: number;
|
|
31
50
|
port?: number;
|
|
32
51
|
pgKind?: 'embedded' | 'podman';
|
|
@@ -89,9 +108,29 @@ export declare function devIdentityPublicJwkFile(): string;
|
|
|
89
108
|
* orchestrator via KICI_DEV_IDENTITY_KEY_FILE.
|
|
90
109
|
*/
|
|
91
110
|
export declare function readOrCreateDevIdentity(): string;
|
|
111
|
+
/** Remove the plane's on-disk record (pidfile + stamp). */
|
|
112
|
+
export declare function clearStamp(): void;
|
|
113
|
+
/**
|
|
114
|
+
* Whether a running plane described by `existing` was booted from a different
|
|
115
|
+
* CLI build than the current one — a semver bump OR a git-commit change (the
|
|
116
|
+
* latter covers intermediate staging/E2E commits that share a semver). Returns
|
|
117
|
+
* false when there is no stamp, or when the current build has no concrete
|
|
118
|
+
* identity (`buildCommit === 'unknown'`, i.e. running from source / a test),
|
|
119
|
+
* so a source-context `planeUp` never reboots a healthy plane spuriously. An
|
|
120
|
+
* old stamp with no `buildCommit` field reads as `undefined` and therefore
|
|
121
|
+
* triggers a one-time reboot on the first upgrade past this feature.
|
|
122
|
+
*/
|
|
123
|
+
export declare function planeBuildIsStale(existing: PlaneStamp | null): boolean;
|
|
92
124
|
/** Absolute path of the plane orchestrator's log file. */
|
|
93
125
|
export declare function planeLogPath(): string;
|
|
94
|
-
/**
|
|
126
|
+
/**
|
|
127
|
+
* Read the plane's current status from whatever holds the plane port.
|
|
128
|
+
*
|
|
129
|
+
* `running` means "serving": a live orchestrator whose `/ready` fails is
|
|
130
|
+
* reported as `unready`, with the failing checks, rather than as stopped —
|
|
131
|
+
* inferring "not running" from an unready probe hides a process that still owns
|
|
132
|
+
* the port.
|
|
133
|
+
*/
|
|
95
134
|
export declare function planeStatus(): Promise<PlaneStatus>;
|
|
96
135
|
/** Attach parameters for a hybrid plane boot (see attachPlane). */
|
|
97
136
|
export interface PlaneUpAttach {
|
|
@@ -106,28 +145,31 @@ export interface PlaneUpOptions {
|
|
|
106
145
|
attach?: PlaneUpAttach;
|
|
107
146
|
}
|
|
108
147
|
/**
|
|
109
|
-
* Start (or reuse) the local dev plane. Idempotent: a healthy running plane
|
|
110
|
-
* **whose stamped mode matches the requested mode
|
|
111
|
-
*
|
|
112
|
-
* the orchestrator are booted
|
|
148
|
+
* Start (or reuse) the local dev plane. Idempotent: a healthy running plane this
|
|
149
|
+
* config dir stamped, **whose stamped mode matches the requested mode**, is
|
|
150
|
+
* returned as-is. Otherwise the port is reclaimed if it is another KiCI plane,
|
|
151
|
+
* and Postgres + the orchestrator are booted with a fresh stamp + pidfile. When
|
|
113
152
|
* `attach` is present the orchestrator boots hybrid against the Platform relay;
|
|
114
|
-
* otherwise it boots independent with the dev-signed identity.
|
|
153
|
+
* otherwise it boots independent with the dev-signed identity. Throws when the
|
|
154
|
+
* port is held by a process that is not a KiCI plane orchestrator.
|
|
115
155
|
*/
|
|
116
156
|
export declare function planeUp(opts?: PlaneUpOptions): Promise<PlaneStatus>;
|
|
157
|
+
/** Outcome of a teardown attempt. `stopped` is true only when the port is verified free. */
|
|
158
|
+
export interface PlaneDownResult {
|
|
159
|
+
stopped: boolean;
|
|
160
|
+
port: number;
|
|
161
|
+
holderPid?: number;
|
|
162
|
+
reason?: string;
|
|
163
|
+
}
|
|
117
164
|
/**
|
|
118
|
-
* Stop the local dev plane
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Poll until process `pid` has exited (SIGTERM already sent), escalating to
|
|
126
|
-
* SIGKILL if it outlives the grace period, so the caller can rely on the
|
|
127
|
-
* listening socket being released once this resolves. `process.kill(pid, 0)`
|
|
128
|
-
* throws `ESRCH` once the process is gone.
|
|
165
|
+
* Stop the local dev plane and confirm the port was released.
|
|
166
|
+
*
|
|
167
|
+
* Teardown is reconstructed from whatever holds the port, not only from the
|
|
168
|
+
* stamp: a plane this config dir never stamped still occupies the port and is
|
|
169
|
+
* still ours to stop. The pidfile and stamp are cleared only once the port is
|
|
170
|
+
* verified free, so a survivor never loses the pid that identifies it.
|
|
129
171
|
*/
|
|
130
|
-
export declare function
|
|
172
|
+
export declare function planeDown(): Promise<PlaneDownResult>;
|
|
131
173
|
/**
|
|
132
174
|
* Attach the local dev plane to the hosted Platform: mint an org-scoped
|
|
133
175
|
* orchestrator key with the logged-in PAT, then (re)boot the plane hybrid
|