@kici-dev/orchestrator 0.1.15 → 0.1.17

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.
Files changed (94) hide show
  1. package/dist/agent/dispatcher.d.ts +18 -1
  2. package/dist/app.d.ts +25 -0
  3. package/dist/approvals/apply-decision.d.ts +70 -0
  4. package/dist/approvals/approval-resolver.d.ts +66 -0
  5. package/dist/approvals/step-approval-bridge.d.ts +72 -0
  6. package/dist/approvals/team-membership-lookup.d.ts +13 -0
  7. package/dist/cache/pending-inits.d.ts +5 -0
  8. package/dist/cache/user-cache.d.ts +1 -1
  9. package/dist/cli/api-client.d.ts +35 -0
  10. package/dist/cli/commands/firecracker/index.d.ts +11 -0
  11. package/dist/cli/commands/firecracker/provision.d.ts +13 -0
  12. package/dist/cli/commands/firecracker/teardown.d.ts +3 -0
  13. package/dist/cli/commands/firecracker/verify.d.ts +3 -0
  14. package/dist/cli/commands/local-hook.d.ts +15 -0
  15. package/dist/cli/commands/local-trigger.d.ts +24 -0
  16. package/dist/cli/commands/remote-source.d.ts +17 -0
  17. package/dist/cli/commands/scaler.d.ts +18 -0
  18. package/dist/cli/commands/shared/versioned-upgrade.d.ts +14 -0
  19. package/dist/cli/kici-admin.d.ts +23 -1
  20. package/dist/cli/service/image-digests.d.ts +21 -0
  21. package/dist/cli.js +4320 -490
  22. package/dist/cluster/peer-client.d.ts +23 -1
  23. package/dist/cluster/peer-handler.d.ts +9 -1
  24. package/dist/config.d.ts +0 -4
  25. package/dist/dashboard/handler.d.ts +26 -2
  26. package/dist/dashboard/needs-edges.d.ts +13 -0
  27. package/dist/db/migrations/033_org_settings_approval.d.ts +19 -0
  28. package/dist/db/migrations/034_held_runs_generalize.d.ts +24 -0
  29. package/dist/db/migrations/035_pending_workflow_contexts.d.ts +11 -0
  30. package/dist/db/migrations/036_attestations.d.ts +15 -0
  31. package/dist/db/migrations/037_generic_sources_provider_type_local.d.ts +19 -0
  32. package/dist/db/migrations/038_remote_sources.d.ts +14 -0
  33. package/dist/db/types.d.ts +135 -11
  34. package/dist/diagnostics/bundle-writer.d.ts +1 -17
  35. package/dist/diagnostics/checks/firecracker-network.d.ts +13 -0
  36. package/dist/diagnostics/checks/index.d.ts +2 -1
  37. package/dist/diagnostics/fleet-collector.d.ts +52 -0
  38. package/dist/diagnostics/fleet-constants.d.ts +8 -0
  39. package/dist/diagnostics/fleet-selection.d.ts +15 -0
  40. package/dist/diagnostics/fleet-topology.d.ts +47 -0
  41. package/dist/diagnostics/fleet-wiring.d.ts +60 -0
  42. package/dist/entry-helpers.d.ts +7 -29
  43. package/dist/environments/held-runs.d.ts +93 -1
  44. package/dist/firecracker/host-network.d.ts +83 -0
  45. package/dist/firecracker/persist.d.ts +14 -0
  46. package/dist/index.js +25 -6
  47. package/dist/metrics/prometheus.d.ts +4 -2
  48. package/dist/orchestrator-core.d.ts +57 -1
  49. package/dist/pipeline/dispatch-matched-workflow.d.ts +18 -1
  50. package/dist/pipeline/install-secrets-resolver.d.ts +32 -5
  51. package/dist/pipeline/needs-scheduler.d.ts +12 -10
  52. package/dist/pipeline/pending-workflow-context.d.ts +44 -0
  53. package/dist/pipeline/processor.d.ts +28 -4
  54. package/dist/pipeline/remote-source-store.d.ts +21 -0
  55. package/dist/pipeline/resume-workflow.d.ts +26 -0
  56. package/dist/providers/local/index.d.ts +33 -0
  57. package/dist/providers/local/local-source-config.d.ts +17 -0
  58. package/dist/providers/{internal → local}/lock-file-fetcher.d.ts +6 -6
  59. package/dist/providers/{internal → local}/normalizer.d.ts +28 -28
  60. package/dist/providers/{internal → local}/repo-url-builder.d.ts +6 -6
  61. package/dist/reporting/execution-tracker.d.ts +33 -0
  62. package/dist/routes/admin-events.d.ts +3 -4
  63. package/dist/routes/fleet.d.ts +20 -0
  64. package/dist/routes/uploads.d.ts +36 -26
  65. package/dist/scaler/config.d.ts +4 -2
  66. package/dist/scaler/disk-guard.d.ts +27 -0
  67. package/dist/scaler/firecracker-backend.d.ts +18 -0
  68. package/dist/scaler/manager.d.ts +6 -0
  69. package/dist/scaler/nftables.d.ts +4 -0
  70. package/dist/scaler/reap-orphans.d.ts +27 -0
  71. package/dist/scaler/types.d.ts +2 -0
  72. package/dist/server.js +26929 -23511
  73. package/dist/sources/build-platform-sources.d.ts +4 -2
  74. package/dist/stale-detector/stale-run-detector.d.ts +32 -1
  75. package/dist/standalone.js +16941 -15329
  76. package/dist/storage/filesystem.d.ts +2 -1
  77. package/dist/storage/s3.d.ts +2 -1
  78. package/dist/storage/types.d.ts +7 -0
  79. package/dist/webhook/generic-sources-listener.d.ts +4 -0
  80. package/dist/webhook/generic-sources.d.ts +37 -11
  81. package/dist/webhook/register-source-bundle.d.ts +14 -4
  82. package/dist/ws/agent-handler.d.ts +49 -0
  83. package/dist/ws/dashboard-dispatch-guard.d.ts +21 -0
  84. package/dist/ws/dashboard-env-handler.d.ts +47 -0
  85. package/dist/ws/fleet-agent-collector.d.ts +23 -0
  86. package/dist/ws/oidc-token-relay.d.ts +59 -0
  87. package/dist/ws/platform-client.d.ts +30 -1
  88. package/dist/ws/test-relay-handlers.d.ts +112 -0
  89. package/installer-image-digests.json +7 -0
  90. package/package.json +6 -5
  91. package/sbom.spdx.json +112 -57
  92. package/dist/providers/internal/index.d.ts +0 -32
  93. package/dist/routes/test-trigger.d.ts +0 -41
  94. package/dist/ws/observer-handler.d.ts +0 -42
@@ -55,6 +55,13 @@ export declare class Dispatcher {
55
55
  private readonly agentJobs;
56
56
  /** Reverse map: jobId -> agentId, for cancel-run lookups. */
57
57
  private readonly jobToAgent;
58
+ /**
59
+ * jobId -> runId for currently-tracked jobs. Populated alongside
60
+ * `jobToAgent`/`agentJobs` at dispatch time and cleared with them, so the
61
+ * provenance token relay can resolve a job's runId from the dispatcher's own
62
+ * state (`resolveOwnedJob`) rather than trusting an agent-asserted value.
63
+ */
64
+ private readonly jobRunIds;
58
65
  /**
59
66
  * Grace window for recently completed jobs.
60
67
  * Allows late messages (log.chunk, step.status) to be accepted for a short
@@ -296,7 +303,7 @@ export declare class Dispatcher {
296
303
  * reconnecting agent reporting the job in-flight means it had started,
297
304
  * so mark it started for disconnect triage.
298
305
  */
299
- restoreJobForAgent(agentId: string, jobId: string): void;
306
+ restoreJobForAgent(agentId: string, jobId: string, runId?: string): void;
300
307
  /**
301
308
  * Start a recovery timer for a job found in 'dispatched' state on startup.
302
309
  * Called by server.ts/standalone.ts to create recovery timers for jobs
@@ -349,6 +356,16 @@ export declare class Dispatcher {
349
356
  /** Remove expired entries from the completedJobs grace window map. */
350
357
  private cleanupExpiredGraceEntries;
351
358
  private trackJobForAgent;
359
+ /**
360
+ * Verify `agentId` currently owns `jobId`; if so, return the job's runId from
361
+ * the dispatcher's own tracking. Used by the provenance token relay so the
362
+ * orchestrator binds a minted token to a job the agent actually owns — the
363
+ * agent never asserts a runId. Returns `undefined` when the agent does not
364
+ * own the job (or the runId is no longer tracked).
365
+ */
366
+ resolveOwnedJob(agentId: string, jobId: string): {
367
+ runId: string;
368
+ } | undefined;
352
369
  /**
353
370
  * Cancel a queued job (mark as failed in the dispatch queue).
354
371
  * Used by the coordinator to clean up local fallback entries when a peer
package/dist/app.d.ts CHANGED
@@ -48,6 +48,8 @@ import type { PeerToPeerMessage } from '@kici-dev/engine';
48
48
  import type { AgentTokenStore } from './agent/token-store.js';
49
49
  import type { OwnershipTracker } from './agent/ownership-tracker.js';
50
50
  import type { ObserverRegistry } from './ws/observer-registry.js';
51
+ import type { FleetAgentCollector } from './ws/fleet-agent-collector.js';
52
+ import type { FleetTopology } from './diagnostics/fleet-topology.js';
51
53
  import type { TokenManager } from './secrets/token-manager.js';
52
54
  import type { SecretResolver } from './secrets/secret-resolver.js';
53
55
  import { type AdminRouteDeps } from './routes/admin.js';
@@ -68,6 +70,7 @@ import type { TrustStore } from './events/trust-store.js';
68
70
  import type { EnvironmentStore } from './environments/environment-store.js';
69
71
  import type { VariableStore } from './environments/variable-store.js';
70
72
  import type { HeldRunStore } from './environments/held-runs.js';
73
+ import type { StepApprovalBridge } from './approvals/step-approval-bridge.js';
71
74
  import type { ContributorCache } from './security/contributor-cache.js';
72
75
  import { AgentMetricsAggregator } from './metrics/agent-metrics-aggregator.js';
73
76
  /**
@@ -132,6 +135,11 @@ export interface AppDependencies {
132
135
  tokenStore?: AgentTokenStore;
133
136
  /** Job ownership tracker for validating agent messages. Optional — requires database. */
134
137
  ownershipTracker?: OwnershipTracker;
138
+ /**
139
+ * Orchestrator-scoped collector correlating fleet.logs.request with agents'
140
+ * chunked bundle responses. Shared with the fleet fan-out in orchestrator-core.
141
+ */
142
+ fleetAgentCollector?: FleetAgentCollector;
135
143
  /** Admin API route dependencies. Optional -- only mounted when secrets management is configured. */
136
144
  adminDeps?: AdminRouteDeps;
137
145
  /**
@@ -170,6 +178,8 @@ export interface AppDependencies {
170
178
  variableStore?: VariableStore;
171
179
  /** Held run store for persisting protection rule holds. Optional -- if not set, holds are not persisted. */
172
180
  heldRunStore?: HeldRunStore;
181
+ /** Step-approval bridge — opens step-scoped holds and relays their resolution back to the waiting agent. Optional. */
182
+ stepApprovalBridge?: StepApprovalBridge;
173
183
  /** Global workflow policy for org-level permission enforcement. Optional -- if not set, global workflows are dispatched without permission checks. */
174
184
  globalWorkflowPolicy?: GlobalWorkflowPolicy;
175
185
  /** Inbound webhook delivery log writer. Optional -- if not set, deliveries are not persisted to event_log. */
@@ -215,6 +225,21 @@ export interface AppDependencies {
215
225
  * can read the same store and Mimir gets agent metrics per-org.
216
226
  */
217
227
  agentMetricsAggregator?: AgentMetricsAggregator;
228
+ /**
229
+ * Fleet log-collection route backing. `getTopology` enumerates the cluster
230
+ * (no fan-out); `collectBundle` drives the recursive fan-out and returns the
231
+ * assembled ZIP. Mounted at /admin/fleet-topology + /admin/fleet-bundle.
232
+ */
233
+ fleetRoutes?: FleetRoutesDeps;
234
+ }
235
+ /** Backing for the /admin/fleet-* routes. */
236
+ export interface FleetRoutesDeps {
237
+ getTopology: () => FleetTopology;
238
+ collectBundle: (opts: {
239
+ selectors: string[];
240
+ logWindowHours?: number;
241
+ timeoutSeconds?: number;
242
+ }) => Promise<Buffer>;
218
243
  }
219
244
  /**
220
245
  * In-memory cache for step source locations extracted from lock files.
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Shared approve/reject applier — the single code path behind both the
3
+ * dashboard WS handler and the `kici` CLI HTTP route, so the authorization +
4
+ * resume story is identical regardless of the surface.
5
+ *
6
+ * Flow for an approve:
7
+ * 1. Load the hold + its recorded decisions.
8
+ * 2. Build the team-membership lookup and run `canApprove` (eligibility +
9
+ * self-approval gate). Ineligible actors are rejected with a clear reason.
10
+ * 3. Record the decision in `held_run_approvals`.
11
+ * 4. Re-evaluate. If all clauses are satisfied, `release()` the hold and
12
+ * resume the element (re-dispatch for job/workflow; the agent bridge for
13
+ * step scope — wired by the caller via `onStepRelease`).
14
+ *
15
+ * A reject records the decision and `reject()`s the hold (failing the element).
16
+ */
17
+ import { ApprovalDecision } from '@kici-dev/engine';
18
+ import type { HeldRunStore, ReleaseSignal } from '../environments/held-runs.js';
19
+ import { type TeamMembershipLookup } from './approval-resolver.js';
20
+ /** Outcome of applying a decision. */
21
+ export interface ApplyDecisionResult {
22
+ /** Whether the decision was accepted (recorded). */
23
+ accepted: boolean;
24
+ /** Human-readable status: 'released' | 'rejected' | 'pending' | 'ineligible' | 'not-found'. */
25
+ status: 'released' | 'rejected' | 'pending' | 'ineligible' | 'not-found';
26
+ /** When still pending, how many clauses remain unsatisfied. */
27
+ remainingClauses?: number;
28
+ /** When ineligible/not-found, a reason for the caller to surface. */
29
+ reason?: string;
30
+ /** The release signal, when the element was released (for the caller to resume). */
31
+ release?: ReleaseSignal;
32
+ }
33
+ /** Dependencies injected into `applyDecision` (testable in isolation). */
34
+ export interface ApplyDecisionDeps {
35
+ orgId: string;
36
+ store: HeldRunStore;
37
+ /** Team name → member user ids (from the Plan-1 trust-policy cache). */
38
+ teamMembershipLookup: TeamMembershipLookup;
39
+ /** Whether the run triggerer may self-approve (org_settings.allow_self_approval). */
40
+ allowSelfApproval: boolean;
41
+ /** Resolve the Keycloak sub of the user who triggered a run (for the self-approval gate). */
42
+ resolveTriggererSub: (runId: string) => Promise<string | undefined>;
43
+ /** Called when a job hold is released — re-dispatch the element. */
44
+ onJobRelease: (signal: ReleaseSignal) => Promise<void>;
45
+ /** Called when a step hold is released — notify the waiting agent (approved). */
46
+ onStepRelease?: (signal: ReleaseSignal) => Promise<void>;
47
+ /**
48
+ * Called when a workflow-scoped hold is released (install gate approved) —
49
+ * rebuild the dispatch context and resume the workflow from the install gate.
50
+ */
51
+ onWorkflowRelease?: (signal: ReleaseSignal) => Promise<void>;
52
+ /**
53
+ * Called when a step-scoped hold is rejected — notify the waiting agent so it
54
+ * fails the step instead of blocking until expiry. Carries the holdId.
55
+ */
56
+ onStepReject?: (heldRunId: string, reason?: string) => Promise<void> | void;
57
+ /**
58
+ * Called when a workflow-scoped hold is rejected (install gate rejected) —
59
+ * cancel the run and drop the pending workflow context. Carries the runId.
60
+ */
61
+ onWorkflowReject?: (runId: string) => Promise<void>;
62
+ }
63
+ /** Apply a single approve/reject decision to a hold. */
64
+ export declare function applyDecision(deps: ApplyDecisionDeps, args: {
65
+ heldRunId: string;
66
+ actorSub: string;
67
+ decision: ApprovalDecision;
68
+ reason?: string;
69
+ }): Promise<ApplyDecisionResult>;
70
+ //# sourceMappingURL=apply-decision.d.ts.map
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Pure approval-clause evaluator. No DB access, no I/O — given a requirement,
3
+ * a team-membership lookup, the recorded decisions, and (for eligibility) the
4
+ * run's triggerer + the self-approval policy, it answers:
5
+ *
6
+ * - `evaluate` — is the requirement satisfied (all clauses ANDed), and was it
7
+ * rejected (any single reject decision)?
8
+ * - `canApprove` — may a given actor cast an approve decision right now?
9
+ *
10
+ * Both the dashboard handler and the CLI HTTP route funnel through these so the
11
+ * authorization story is identical regardless of the surface.
12
+ */
13
+ import type { ApprovalRequirement, ApproverClause } from '@kici-dev/engine';
14
+ /** A team name → set of member user ids (Keycloak subs). */
15
+ export type TeamMembershipLookup = (team: string) => Set<string>;
16
+ /** One recorded decision row (subset of `held_run_approvals`). */
17
+ export interface RecordedDecision {
18
+ approver_user_id: string;
19
+ decision: 'approve' | 'reject';
20
+ }
21
+ /** Per-clause satisfaction detail for attribution + dashboard progress. */
22
+ export interface PerClauseResult {
23
+ clause: ApproverClause;
24
+ satisfied: boolean;
25
+ /** The approver who satisfied this clause, if any. */
26
+ by?: string;
27
+ }
28
+ export interface EvaluationResult {
29
+ /** All clauses satisfied (AND). For empty clauses: any single approve. */
30
+ satisfied: boolean;
31
+ /** Any reject decision present → the element is rejected. */
32
+ rejected: boolean;
33
+ perClause: PerClauseResult[];
34
+ }
35
+ /**
36
+ * Is a single clause satisfied by any approve decision whose approver is
37
+ * eligible for the clause? Reject decisions never satisfy.
38
+ */
39
+ export declare function isClauseSatisfied(clause: ApproverClause, decisions: RecordedDecision[], lookup: TeamMembershipLookup): boolean;
40
+ /** Does an actor satisfy/qualify for a clause (team membership or exact user)? */
41
+ export declare function isActorEligibleForClause(actorSub: string, clause: ApproverClause, lookup: TeamMembershipLookup): boolean;
42
+ /**
43
+ * Evaluate a requirement against the recorded decisions.
44
+ *
45
+ * - A single reject decision sets `rejected` (the caller fails the element).
46
+ * - Empty clauses ⇒ satisfied by ANY single approve decision.
47
+ * - Non-empty clauses ⇒ satisfied iff every clause is satisfied (AND).
48
+ */
49
+ export declare function evaluate(requirement: ApprovalRequirement, decisions: RecordedDecision[], lookup: TeamMembershipLookup): EvaluationResult;
50
+ export interface CanApproveContext {
51
+ /** The Keycloak sub of the user who triggered the run. */
52
+ triggererSub: string;
53
+ /** Whether the triggerer may self-approve their own held elements. */
54
+ allowSelfApproval: boolean;
55
+ }
56
+ /**
57
+ * May `actorSub` cast an approve decision on this requirement right now?
58
+ *
59
+ * - Self-approval gate: when `allowSelfApproval` is false and the actor is the
60
+ * run's triggerer, they may never approve.
61
+ * - Eligibility: the actor must qualify for at least one still-UNSATISFIED
62
+ * clause. (Approving a clause that is already satisfied adds nothing.) For an
63
+ * empty-clause requirement, any non-triggerer-blocked actor qualifies.
64
+ */
65
+ export declare function canApprove(actorSub: string, requirement: ApprovalRequirement, decisions: RecordedDecision[], lookup: TeamMembershipLookup, ctx: CanApproveContext): boolean;
66
+ //# sourceMappingURL=approval-resolver.d.ts.map
@@ -0,0 +1,72 @@
1
+ import type { HeldRunStore } from '../environments/held-runs.js';
2
+ import type { AccessLogWriter } from '../audit/access-log.js';
3
+ /** Outcome relayed back to the waiting agent. */
4
+ export type StepApprovalOutcome = 'approved' | 'rejected' | 'expired';
5
+ /** Arguments to open a step-scoped approval hold. */
6
+ export interface StepApprovalRequest {
7
+ agentId: string;
8
+ runId: string;
9
+ jobId: string;
10
+ stepIndex: number;
11
+ stepName: string;
12
+ clauses: Array<{
13
+ team: string;
14
+ } | {
15
+ user: string;
16
+ }>;
17
+ reason: string;
18
+ /** Per-gate timeout (seconds); falls back to the org default. */
19
+ timeoutSeconds?: number;
20
+ }
21
+ /** Dependencies injected into the bridge. */
22
+ export interface StepApprovalBridgeDeps {
23
+ store: HeldRunStore;
24
+ /**
25
+ * Resolve the orchestrator's tenant org id (same value the dashboard handler
26
+ * uses to read held_runs). A function because the org is resolved post-auth
27
+ * for sourceless orchestrators.
28
+ */
29
+ resolveOrgId: () => string;
30
+ /** Resolve the authoritative approval expiry (seconds) for an org. */
31
+ resolveExpirySeconds: (orgId: string) => Promise<number>;
32
+ /**
33
+ * Access-log writer for the orchestrator audit stream. Optional -- if not
34
+ * set, the step-hold creation audit row (`held_run.request`) is skipped.
35
+ */
36
+ accessLogWriter?: AccessLogWriter;
37
+ /** Routing key recorded on the audit row. Optional. */
38
+ routingKey?: string | null;
39
+ }
40
+ /**
41
+ * Owns the step-scoped held_runs rows and the map from holdId → the waiting
42
+ * agent's resolver. The only place that opens a step hold and the only place
43
+ * that settles a step-scoped wait.
44
+ */
45
+ export declare class StepApprovalBridge {
46
+ private readonly deps;
47
+ private readonly pending;
48
+ constructor(deps: StepApprovalBridgeDeps);
49
+ /**
50
+ * Create a step-scoped hold and return a promise that settles when the hold
51
+ * is approved / rejected / expired (via {@link resolve}).
52
+ */
53
+ request(req: StepApprovalRequest): Promise<{
54
+ outcome: StepApprovalOutcome;
55
+ reason?: string;
56
+ }>;
57
+ /**
58
+ * Settle a step-scoped wait. Called by the approve/reject applier
59
+ * (`onStepRelease`) and by the stale detector (`expired`). A no-op when no
60
+ * agent is waiting on the hold (e.g. the agent already disconnected).
61
+ */
62
+ resolve(holdId: string, outcome: StepApprovalOutcome, reason?: string): boolean;
63
+ /**
64
+ * Reject every pending wait for a disconnected agent. The held_runs rows are
65
+ * left as-is (the stale detector will expire them) — only the in-memory
66
+ * resolver is dropped so the handler's relayed `ws.send` is skipped.
67
+ */
68
+ failAgent(agentId: string): void;
69
+ /** Number of in-flight step-approval waits (test/diagnostics). */
70
+ size(): number;
71
+ }
72
+ //# sourceMappingURL=step-approval-bridge.d.ts.map
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Read-only lookup over the team memberships pushed from the Platform via
3
+ * `trust_policy.update`. The orchestrator has no identity store, so this is the
4
+ * only source of "who is in team X" — the approval resolver uses it to satisfy
5
+ * `{team}` approver clauses.
6
+ */
7
+ export interface TeamMembershipLookup {
8
+ /** Returns the set of member user ids for a team name (empty if unknown). */
9
+ getTeamMembers(name: string): Set<string>;
10
+ }
11
+ /** A lookup backed by no teams — the default before any push arrives. */
12
+ export declare const EMPTY_TEAM_MEMBERSHIP_LOOKUP: TeamMembershipLookup;
13
+ //# sourceMappingURL=team-membership-lookup.d.ts.map
@@ -12,6 +12,11 @@ export interface InitResult {
12
12
  environmentName?: string;
13
13
  env?: Record<string, string>;
14
14
  concurrencyGroup?: string;
15
+ /**
16
+ * Resolved matrix combinations when the target job's matrix is a dynamic
17
+ * function. The dispatch path re-materializes these into N execution jobs.
18
+ */
19
+ matrixValues?: Array<Record<string, string | undefined>>;
15
20
  }
16
21
  export declare class PendingInitTracker extends PendingTracker<InitResult> {
17
22
  constructor();
@@ -110,7 +110,7 @@ export declare class UserCache {
110
110
  tempKey?: string;
111
111
  }): Promise<void>;
112
112
  private readHash;
113
- /** Evict oldest entries for the org until total tarball size <= the per-org quota. */
113
+ /** Evict least-recently-used entries for the org until total tarball size <= the per-org quota. */
114
114
  private enforceQuota;
115
115
  }
116
116
  //# sourceMappingURL=user-cache.d.ts.map
@@ -5,6 +5,19 @@
5
5
  * All methods are thin wrappers around fetch() that handle JSON serialization,
6
6
  * error formatting, and URL construction.
7
7
  */
8
+ /** A node in the fleet topology returned by GET /admin/fleet-topology. */
9
+ export interface FleetTopologyNodeResponse {
10
+ kind: 'orchestrator' | 'agent';
11
+ id: string;
12
+ role?: 'coordinator' | 'worker';
13
+ hostname?: string;
14
+ labels: Record<string, string>;
15
+ parentId: string | null;
16
+ }
17
+ /** Response shape for GET /admin/fleet-topology. */
18
+ export interface FleetTopologyResponse {
19
+ nodes: FleetTopologyNodeResponse[];
20
+ }
8
21
  /**
9
22
  * Universal-git configuration shape carried in `git_config` on
10
23
  * generic_webhook_sources. Matches `UniversalGitConfigSchema` in
@@ -12,6 +25,14 @@
12
25
  * avoid a cross-package import in the CLI wire type.
13
26
  */
14
27
  export type GenericSourceGitConfigPayload = Record<string, unknown>;
28
+ /**
29
+ * Wire shape for a local filesystem source's config (`{ repoBasePath, cloneUrlBase? }`).
30
+ * Matches `LocalSourceConfigSchema` in `providers/local/local-source-config.ts`.
31
+ */
32
+ export interface GenericSourceLocalConfigPayload {
33
+ repoBasePath: string;
34
+ cloneUrlBase?: string;
35
+ }
15
36
  /**
16
37
  * Response shape for generic webhook sources from the admin API.
17
38
  */
@@ -71,6 +92,17 @@ export declare class AdminApiClient {
71
92
  * Public GET request returning raw response text.
72
93
  */
73
94
  getText(path: string): Promise<string>;
95
+ /** Enumerate the cluster topology for `debug-bundle --fleet --list` / `--pick`. */
96
+ getFleetTopology(): Promise<FleetTopologyResponse>;
97
+ /**
98
+ * Drive the fleet fan-out and write the assembled ZIP to `outPath`. The
99
+ * response is an octet-stream, so it is read as bytes rather than parsed JSON.
100
+ */
101
+ downloadFleetBundle(body: {
102
+ selectors: string[];
103
+ logWindowHours?: number;
104
+ timeoutSeconds?: number;
105
+ }, outPath: string): Promise<void>;
74
106
  listScopes(orgId: string): Promise<{
75
107
  scopes: string[];
76
108
  }>;
@@ -110,6 +142,7 @@ export declare class AdminApiClient {
110
142
  rateLimitRpm?: number;
111
143
  providerType?: string;
112
144
  gitConfig?: GenericSourceGitConfigPayload;
145
+ localConfig?: GenericSourceLocalConfigPayload;
113
146
  }): Promise<{
114
147
  source: GenericSourceResponse;
115
148
  }>;
@@ -135,6 +168,8 @@ export declare class AdminApiClient {
135
168
  providerType?: string;
136
169
  /** `null` clears the config; omit to leave unchanged. */
137
170
  gitConfig?: GenericSourceGitConfigPayload | null;
171
+ /** `null` clears the config; omit to leave unchanged. */
172
+ localConfig?: GenericSourceLocalConfigPayload | null;
138
173
  }): Promise<{
139
174
  source: GenericSourceResponse;
140
175
  }>;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * `kici-admin firecracker` command group.
3
+ *
4
+ * Local host-networking ops for the orchestrator's Firecracker scaler:
5
+ * provision/verify/teardown the per-coordinator bridge + nft table, with
6
+ * --persist for reboot survival. These run directly on the host (privileged
7
+ * `ip`/`nft`/`systemctl`) and do NOT use the admin HTTP client.
8
+ */
9
+ import type { Command } from 'commander';
10
+ export declare function registerFirecrackerCommands(program: Command): void;
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,13 @@
1
+ import type { Command } from 'commander';
2
+ import { type FirecrackerBridgeConfig } from '../../../firecracker/host-network.js';
3
+ export interface ProvisionOptions {
4
+ bridge: string;
5
+ cidr?: string;
6
+ table?: string;
7
+ hostIface?: string;
8
+ persist?: boolean;
9
+ sudo?: boolean;
10
+ }
11
+ export declare function optionsToConfig(opts: ProvisionOptions): FirecrackerBridgeConfig;
12
+ export declare function registerProvision(group: Command): void;
13
+ //# sourceMappingURL=provision.d.ts.map
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerTeardown(group: Command): void;
3
+ //# sourceMappingURL=teardown.d.ts.map
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerVerify(group: Command): void;
3
+ //# sourceMappingURL=verify.d.ts.map
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Render the post-receive hook script. For each pushed ref the hook calls
3
+ * `kici-admin source trigger-local <id> --ref <ref> --sha <new> --base-url <url>`,
4
+ * so a push to any branch dispatches a run for that ref.
5
+ */
6
+ export declare function renderPostReceiveHook(opts: {
7
+ sourceId: string;
8
+ baseUrl: string;
9
+ }): string;
10
+ /**
11
+ * Write the rendered hook into the repo's `.git/hooks/post-receive` and make it
12
+ * executable. Throws when the path is not a git repo (no `.git/hooks` dir).
13
+ */
14
+ export declare function installPostReceiveHook(repoPath: string, script: string): string;
15
+ //# sourceMappingURL=local-hook.d.ts.map
@@ -0,0 +1,24 @@
1
+ export interface LocalTriggerInput {
2
+ orgId: string;
3
+ sourceId: string;
4
+ repoFullName: string;
5
+ event: 'push' | 'pull_request';
6
+ ref: string;
7
+ sha: string;
8
+ defaultBranch: string;
9
+ }
10
+ export interface LocalTriggerRequest {
11
+ path: string;
12
+ headers: Record<string, string>;
13
+ body: string;
14
+ }
15
+ /** Build the GitHub-shaped webhook request the local provider normalizer expects. */
16
+ export declare function buildLocalTriggerRequest(input: LocalTriggerInput): LocalTriggerRequest;
17
+ /** Read HEAD ref + sha from a local git repo (used when the operator omits --ref/--sha). */
18
+ export declare function readRepoHead(repoPath: string): {
19
+ ref: string;
20
+ sha: string;
21
+ };
22
+ /** POST the trigger request to the orchestrator base URL. Returns the HTTP status. */
23
+ export declare function sendLocalTrigger(baseUrl: string, req: LocalTriggerRequest): Promise<number>;
24
+ //# sourceMappingURL=local-trigger.d.ts.map
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Remote-source inspection command for kici-admin.
3
+ *
4
+ * Subcommand namespace: `kici-admin remote-source show`.
5
+ *
6
+ * The remote-source anchor (`remote_sources` table) maps the deterministic
7
+ * routing key `remote:<orgId>` to the orchestrator's canonical org id so a
8
+ * Platform-relayed `kici run remote` resolves the real tenant. It is
9
+ * auto-provisioned on Platform auth; this command lets an operator inspect or
10
+ * confirm the row when debugging org-anchor issues on a hidden orchestrator.
11
+ *
12
+ * Reads the orchestrator DB directly (on-host operator inspection), so it stays
13
+ * usable even when Platform is unreachable.
14
+ */
15
+ import type { Command } from 'commander';
16
+ export declare function registerRemoteSourceCommands(program: Command): void;
17
+ //# sourceMappingURL=remote-source.d.ts.map
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Standalone scaler maintenance commands for kici-admin.
3
+ *
4
+ * scaler reap-orphans Free leaked Firecracker/container resources WITHOUT a
5
+ * running orchestrator (recovery for a wedged node whose
6
+ * data disk is full).
7
+ *
8
+ * This command loads the orchestrator's LOCAL config (no HTTP admin API, no DB)
9
+ * and runs the liveness-driven reaper. It is the sanctioned operator path for
10
+ * the ENOSPC bootstrap deadlock: when the data disk is 100% full the
11
+ * orchestrator crash-loops before its in-process orphan sweep can run, so a
12
+ * tool that frees disk WITHOUT the orchestrator is required.
13
+ */
14
+ import type { Command } from 'commander';
15
+ /** Probe the local orchestrator /health endpoint. Healthy => it reaps itself. */
16
+ export declare function isOrchestratorHealthy(port: number, basePath: string): Promise<boolean>;
17
+ export declare function registerScalerCommands(program: Command): void;
18
+ //# sourceMappingURL=scaler.d.ts.map
@@ -85,6 +85,20 @@ export declare function getInstallBase(platform: ServicePlatform, name: string):
85
85
  * 5. Update symlink (Unix) or service registration (Windows)
86
86
  * 6. Start service
87
87
  */
88
+ /**
89
+ * Resolve the target version for an npm-source upgrade (no --from/--url).
90
+ *
91
+ * The npm-source flow assumes the operator already ran
92
+ * `npm install -g @kici-dev/<pkg>@<version>`, which overwrites the global
93
+ * package in place. The running `kici-admin` binary is therefore the new
94
+ * version, and `running` is its self-reported version. We default the target
95
+ * to it, or validate an explicitly-passed --version matches — a mismatch means
96
+ * the npm install did not actually update the global binary.
97
+ */
98
+ export declare function resolveNpmSourceVersion(opts: {
99
+ requested: string | undefined;
100
+ running: string;
101
+ }): string;
88
102
  export declare function performVersionedUpgrade(component: UpgradeComponent, opts: VersionedUpgradeOptions): Promise<void>;
89
103
  export {};
90
104
  //# sourceMappingURL=versioned-upgrade.d.ts.map
@@ -9,5 +9,27 @@
9
9
  * --url / -u Orchestrator URL (env: KICI_ADMIN_URL, default: http://localhost:8080)
10
10
  * --token / -t Admin API token (env: KICI_ADMIN_TOKEN, required)
11
11
  */
12
- export {};
12
+ import { Command } from 'commander';
13
+ /**
14
+ * Build the kici-admin Commander program with every command group registered.
15
+ * Exported so the surface registry can walk the real command tree without
16
+ * parsing argv (no action runs during a tree walk, so `getClient` is
17
+ * constructed but never invoked).
18
+ */
19
+ export declare function buildProgram(): Command;
20
+ /** Build the program and parse argv — the bin-shim entry point. */
21
+ export declare function runCli(argv?: string[]): void;
22
+ /**
23
+ * Canonicalize a path through any symlinks, falling back to a plain `resolve`
24
+ * when the target does not exist on disk. The entry-point guard compares the
25
+ * invoked script path against this module's own path; both sides must be fully
26
+ * canonicalized or a symlinked invocation path silently fails the match. The
27
+ * canonical example is the light-package launcher running
28
+ * `node /tmp/.../kici-admin.cjs` on macOS, where `/tmp` is a symlink to
29
+ * `/private/tmp`: `process.argv[1]` keeps the `/tmp` form while the bundle's
30
+ * `import.meta.url` resolves to the real `/private/tmp` path, so an
31
+ * un-canonicalized comparison is always false and the CLI exits 0 without
32
+ * running any command.
33
+ */
34
+ export declare function canonicalize(p: string): string;
13
35
  //# sourceMappingURL=kici-admin.d.ts.map
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Resolves the customer installer's image reference from the digest record
3
+ * shipped with this package (installer-image-digests.json at the package root).
4
+ *
5
+ * Emits a manifest-list-digest-pinned ref so a `docker`/`podman pull` verifies
6
+ * the image hash — a registry that serves substituted bits fails the pull. When
7
+ * the record is missing (a dev tree that never ran a release) or lacks the
8
+ * image, falls back to the moving `:latest` tag and warns.
9
+ *
10
+ * The record resolves relative to this module's directory and works for both
11
+ * layouts: the source tree (`src/cli/service/` → the JSON is three dirs up at
12
+ * the package root) and the single-file bundle (`dist/cli.js` → one dir up).
13
+ */
14
+ /**
15
+ * Resolve `quay.io/kici-dev/<name>:<version>@sha256:<digest>` for an installer
16
+ * image. Falls back to `:latest` (with a warning) when no recorded digest exists.
17
+ */
18
+ export declare function resolveImageRef(name: string, opts?: {
19
+ filePath?: string;
20
+ }): string;
21
+ //# sourceMappingURL=image-digests.d.ts.map