@kici-dev/orchestrator 0.0.0 → 0.1.1
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/LICENSE +661 -0
- package/README.md +1 -6
- package/dist/__test-helpers__/mock-db.d.ts +103 -0
- package/dist/__test-helpers__/mock-ws.d.ts +13 -0
- package/dist/agent/dispatcher.d.ts +231 -0
- package/dist/agent/ownership-tracker.d.ts +46 -0
- package/dist/agent/registry.d.ts +255 -0
- package/dist/agent/token-store.d.ts +96 -0
- package/dist/app.d.ts +234 -0
- package/dist/audit/access-log.d.ts +92 -0
- package/dist/audit/sampling-rate-limiter.d.ts +41 -0
- package/dist/cache/build-coordinator.d.ts +42 -0
- package/dist/cache/dep-cache.d.ts +51 -0
- package/dist/cache/index.d.ts +16 -0
- package/dist/cache/pending-builds.d.ts +14 -0
- package/dist/cache/pending-dynamics.d.ts +15 -0
- package/dist/cache/pending-inits.d.ts +19 -0
- package/dist/cache/pending-tracker.d.ts +65 -0
- package/dist/cache/source-cache.d.ts +30 -0
- package/dist/cli/api-client.d.ts +411 -0
- package/dist/cli/commands/access-log.d.ts +30 -0
- package/dist/cli/commands/agent-service/index.d.ts +15 -0
- package/dist/cli/commands/agent-service/install.d.ts +9 -0
- package/dist/cli/commands/agent-service/logs.d.ts +9 -0
- package/dist/cli/commands/agent-service/restart.d.ts +8 -0
- package/dist/cli/commands/agent-service/start.d.ts +8 -0
- package/dist/cli/commands/agent-service/status.d.ts +10 -0
- package/dist/cli/commands/agent-service/stop.d.ts +8 -0
- package/dist/cli/commands/agent-service/uninstall.d.ts +9 -0
- package/dist/cli/commands/agent-service/upgrade.d.ts +11 -0
- package/dist/cli/commands/agent.d.ts +10 -0
- package/dist/cli/commands/api-key.d.ts +12 -0
- package/dist/cli/commands/audit.d.ts +9 -0
- package/dist/cli/commands/backend.d.ts +17 -0
- package/dist/cli/commands/cold-store-impl.d.ts +101 -0
- package/dist/cli/commands/cold-store.d.ts +30 -0
- package/dist/cli/commands/config.d.ts +16 -0
- package/dist/cli/commands/db.d.ts +19 -0
- package/dist/cli/commands/debug-bundle.d.ts +16 -0
- package/dist/cli/commands/diagnose.d.ts +15 -0
- package/dist/cli/commands/environment.d.ts +24 -0
- package/dist/cli/commands/event-dlq.d.ts +19 -0
- package/dist/cli/commands/event-log.d.ts +27 -0
- package/dist/cli/commands/event.d.ts +4 -0
- package/dist/cli/commands/execution.d.ts +17 -0
- package/dist/cli/commands/inspect-bundle.d.ts +16 -0
- package/dist/cli/commands/maintenance.d.ts +4 -0
- package/dist/cli/commands/orchestrator-service/index.d.ts +12 -0
- package/dist/cli/commands/orchestrator-service/install.d.ts +10 -0
- package/dist/cli/commands/orchestrator-service/logs.d.ts +10 -0
- package/dist/cli/commands/orchestrator-service/restart.d.ts +8 -0
- package/dist/cli/commands/orchestrator-service/start.d.ts +8 -0
- package/dist/cli/commands/orchestrator-service/status.d.ts +10 -0
- package/dist/cli/commands/orchestrator-service/stop.d.ts +8 -0
- package/dist/cli/commands/orchestrator-service/uninstall.d.ts +9 -0
- package/dist/cli/commands/orchestrator-service/upgrade.d.ts +12 -0
- package/dist/cli/commands/org-settings.d.ts +17 -0
- package/dist/cli/commands/peer.d.ts +13 -0
- package/dist/cli/commands/queue.d.ts +16 -0
- package/dist/cli/commands/registration.d.ts +18 -0
- package/dist/cli/commands/rotate.d.ts +9 -0
- package/dist/cli/commands/runs.d.ts +34 -0
- package/dist/cli/commands/secret.d.ts +12 -0
- package/dist/cli/commands/shared/db.d.ts +16 -0
- package/dist/cli/commands/shared/versioned-upgrade.d.ts +38 -0
- package/dist/cli/commands/source.d.ts +24 -0
- package/dist/cli/commands/token.d.ts +10 -0
- package/dist/cli/commands/workflow.d.ts +31 -0
- package/dist/cli/join.d.ts +14 -0
- package/dist/cli/kici-admin.d.ts +13 -0
- package/dist/cli/lazy-deps/cache.d.ts +17 -0
- package/dist/cli/lazy-deps/downloader.d.ts +33 -0
- package/dist/cli/lazy-deps/registry.d.ts +43 -0
- package/dist/cli/service/compose.d.ts +25 -0
- package/dist/cli/service/index.d.ts +24 -0
- package/dist/cli/service/launchd.d.ts +34 -0
- package/dist/cli/service/platform-detect.d.ts +59 -0
- package/dist/cli/service/systemd.d.ts +41 -0
- package/dist/cli/service/types.d.ts +91 -0
- package/dist/cli/service/windows.d.ts +20 -0
- package/dist/cli/wizard/agent-wizard.d.ts +24 -0
- package/dist/cli/wizard/orchestrator-wizard.d.ts +38 -0
- package/dist/cli/wizard/prompts.d.ts +23 -0
- package/dist/cli.js +11435 -0
- package/dist/cluster/cluster-identity.d.ts +59 -0
- package/dist/cluster/coordinator.d.ts +204 -0
- package/dist/cluster/health-api.d.ts +30 -0
- package/dist/cluster/index.d.ts +24 -0
- package/dist/cluster/join-client.d.ts +75 -0
- package/dist/cluster/join-handler.d.ts +58 -0
- package/dist/cluster/join-token.d.ts +94 -0
- package/dist/cluster/orphan-recovery.d.ts +67 -0
- package/dist/cluster/peer-client.d.ts +190 -0
- package/dist/cluster/peer-credentials.d.ts +108 -0
- package/dist/cluster/peer-crypto.d.ts +57 -0
- package/dist/cluster/peer-handler.d.ts +97 -0
- package/dist/cluster/peer-registry.d.ts +186 -0
- package/dist/cluster/raft-state.d.ts +36 -0
- package/dist/cluster/raft.d.ts +140 -0
- package/dist/cold-store/load-access-log-range.d.ts +73 -0
- package/dist/cold-store/load-event-log-range.d.ts +62 -0
- package/dist/cold-store/load-secret-audit-log-range.d.ts +38 -0
- package/dist/cold-store/orchestrator-cold-store.d.ts +58 -0
- package/dist/cold-store/tables/access-log.d.ts +80 -0
- package/dist/cold-store/tables/event-log.d.ts +70 -0
- package/dist/cold-store/tables/execution-jobs.d.ts +63 -0
- package/dist/cold-store/tables/execution-runs.d.ts +81 -0
- package/dist/cold-store/tables/execution-steps.d.ts +65 -0
- package/dist/cold-store/tables/secret-audit-log.d.ts +77 -0
- package/dist/concurrency/dispatch-next-queued.d.ts +63 -0
- package/dist/concurrency/group-tracker.d.ts +51 -0
- package/dist/concurrency/index.d.ts +3 -0
- package/dist/concurrency/queue-manager.d.ts +68 -0
- package/dist/concurrency/waiters.d.ts +58 -0
- package/dist/config/encryption.d.ts +82 -0
- package/dist/config/env-overlay.d.ts +45 -0
- package/dist/config/index.d.ts +16 -0
- package/dist/config/loader.d.ts +26 -0
- package/dist/config/reload.d.ts +113 -0
- package/dist/config/resolver.d.ts +47 -0
- package/dist/config/schema.d.ts +210 -0
- package/dist/config/shared-store.d.ts +142 -0
- package/dist/config/types.d.ts +218 -0
- package/dist/config.d.ts +249 -0
- package/dist/cron/cron-scheduler.d.ts +78 -0
- package/dist/cron/cron-store.d.ts +38 -0
- package/dist/dashboard/handler.d.ts +243 -0
- package/dist/db/client.d.ts +13 -0
- package/dist/db/migration-provider.d.ts +9 -0
- package/dist/db/migrations/001_initial.d.ts +8 -0
- package/dist/db/migrations/002_config_versions_key_version.d.ts +16 -0
- package/dist/db/migrations/003_access_log.d.ts +26 -0
- package/dist/db/migrations/004_rename_bundle_to_source.d.ts +19 -0
- package/dist/db/migrations/005_cold_store_chunk_counter.d.ts +19 -0
- package/dist/db/migrations/006_runs_jobs_steps_archived_at.d.ts +38 -0
- package/dist/db/migrations/007_audit_logs_archived_at.d.ts +42 -0
- package/dist/db/migrations/008_event_log_archived_at.d.ts +40 -0
- package/dist/db/migrations/009_access_log_trigram.d.ts +15 -0
- package/dist/db/migrations/010_cold_store_chunks.d.ts +34 -0
- package/dist/db/migrations/011_drop_source_secrets_notify.d.ts +21 -0
- package/dist/db/migrations/012_peer_credentials_active_uniq.d.ts +28 -0
- package/dist/db/migrations/013_execution_log_bytes.d.ts +21 -0
- package/dist/db/migrations/014_kici_events_lease_retry.d.ts +36 -0
- package/dist/db/migrations/015_org_settings_customer_scoped.d.ts +30 -0
- package/dist/db/migrations/016_org_settings_allow_http_npm.d.ts +15 -0
- package/dist/db/migrations/017_org_id_widen.d.ts +4 -0
- package/dist/db/migrations/018_org_id_prefix_backfill.d.ts +4 -0
- package/dist/db/migrator.d.ts +32 -0
- package/dist/db/types.d.ts +1266 -0
- package/dist/diagnostics/bundle-reader.d.ts +48 -0
- package/dist/diagnostics/bundle-writer.d.ts +57 -0
- package/dist/diagnostics/checks/agents.d.ts +10 -0
- package/dist/diagnostics/checks/certs.d.ts +9 -0
- package/dist/diagnostics/checks/config.d.ts +10 -0
- package/dist/diagnostics/checks/db.d.ts +9 -0
- package/dist/diagnostics/checks/disk.d.ts +9 -0
- package/dist/diagnostics/checks/index.d.ts +17 -0
- package/dist/diagnostics/checks/ws.d.ts +9 -0
- package/dist/diagnostics/index.d.ts +13 -0
- package/dist/diagnostics/runner.d.ts +23 -0
- package/dist/diagnostics/types.d.ts +38 -0
- package/dist/entry-helpers.d.ts +93 -0
- package/dist/environments/binding-store.d.ts +27 -0
- package/dist/environments/environment-store.d.ts +74 -0
- package/dist/environments/held-runs.d.ts +64 -0
- package/dist/environments/index.d.ts +10 -0
- package/dist/environments/protection/branch-gate.d.ts +5 -0
- package/dist/environments/protection/concurrency-gate.d.ts +7 -0
- package/dist/environments/protection/pipeline.d.ts +18 -0
- package/dist/environments/protection/reviewer-gate.d.ts +7 -0
- package/dist/environments/protection/trust-gate.d.ts +7 -0
- package/dist/environments/protection/wait-timer-gate.d.ts +7 -0
- package/dist/environments/variable-store.d.ts +39 -0
- package/dist/events/circuit-breaker.d.ts +33 -0
- package/dist/events/event-emitter.d.ts +55 -0
- package/dist/events/event-retry-scanner.d.ts +52 -0
- package/dist/events/event-router.d.ts +183 -0
- package/dist/events/event-store.d.ts +157 -0
- package/dist/events/trust-store.d.ts +54 -0
- package/dist/events/types.d.ts +61 -0
- package/dist/helpers/ip-extraction.d.ts +29 -0
- package/dist/helpers/rate-limiter.d.ts +23 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +772 -0
- package/dist/lockfile-cache.d.ts +39 -0
- package/dist/metrics/agent-metrics-aggregator.d.ts +116 -0
- package/dist/metrics/metrics-reporter.d.ts +40 -0
- package/dist/metrics/prometheus.d.ts +261 -0
- package/dist/metrics/scheduled-jobs.d.ts +20 -0
- package/dist/orchestrator-core.d.ts +193 -0
- package/dist/pipeline/dispatch-matched-workflow.d.ts +102 -0
- package/dist/pipeline/inline-eval.d.ts +28 -0
- package/dist/pipeline/install-secrets-resolver.d.ts +73 -0
- package/dist/pipeline/manual-schedule.d.ts +21 -0
- package/dist/pipeline/needs-scheduler.d.ts +85 -0
- package/dist/pipeline/process-webhook.d.ts +38 -0
- package/dist/pipeline/processor.d.ts +326 -0
- package/dist/pipeline/rerun.d.ts +79 -0
- package/dist/pipeline/test-pipeline.d.ts +110 -0
- package/dist/provider-registry.d.ts +122 -0
- package/dist/providers/generic/index.d.ts +23 -0
- package/dist/providers/generic/normalizer.d.ts +112 -0
- package/dist/providers/generic/verification.d.ts +47 -0
- package/dist/providers/github/auth.d.ts +60 -0
- package/dist/providers/github/changed-files.d.ts +51 -0
- package/dist/providers/github/check-status-poster.d.ts +35 -0
- package/dist/providers/github/contributor-resolver.d.ts +30 -0
- package/dist/providers/github/index.d.ts +20 -0
- package/dist/providers/github/lock-file.d.ts +32 -0
- package/dist/providers/github/normalizer.d.ts +103 -0
- package/dist/providers/github/repo-url.d.ts +35 -0
- package/dist/providers/internal/index.d.ts +32 -0
- package/dist/providers/internal/lock-file-fetcher.d.ts +34 -0
- package/dist/providers/internal/normalizer.d.ts +89 -0
- package/dist/providers/internal/repo-url-builder.d.ts +42 -0
- package/dist/providers/universal-git/changed-files.d.ts +42 -0
- package/dist/providers/universal-git/clone-token.d.ts +83 -0
- package/dist/providers/universal-git/config.d.ts +192 -0
- package/dist/providers/universal-git/index.d.ts +55 -0
- package/dist/providers/universal-git/lock-file.d.ts +71 -0
- package/dist/providers/universal-git/normalizer.d.ts +90 -0
- package/dist/providers/universal-git/repo-url.d.ts +50 -0
- package/dist/providers/universal-git/ssh-auth.d.ts +94 -0
- package/dist/queue/bootstrap.d.ts +50 -0
- package/dist/queue/cleanup.d.ts +41 -0
- package/dist/queue/depth-refresher.d.ts +65 -0
- package/dist/queue/job-queue.d.ts +343 -0
- package/dist/queue/scheduled-job.d.ts +91 -0
- package/dist/registration/extractor.d.ts +44 -0
- package/dist/registration/registration-index.d.ts +162 -0
- package/dist/registration/registration-store.d.ts +111 -0
- package/dist/reporting/check-run-summary.d.ts +102 -0
- package/dist/reporting/commit-status.d.ts +382 -0
- package/dist/reporting/execution-tracker.d.ts +538 -0
- package/dist/reporting/fs-log-storage.d.ts +41 -0
- package/dist/reporting/log-pull-handler.d.ts +35 -0
- package/dist/reporting/log-storage.d.ts +70 -0
- package/dist/reporting/log-writer.d.ts +45 -0
- package/dist/reporting/s3-log-storage.d.ts +42 -0
- package/dist/reporting/step-log-buffer.d.ts +57 -0
- package/dist/routes/admin-access-log.d.ts +34 -0
- package/dist/routes/admin-backends.d.ts +28 -0
- package/dist/routes/admin-config.d.ts +57 -0
- package/dist/routes/admin-db.d.ts +20 -0
- package/dist/routes/admin-environments.d.ts +42 -0
- package/dist/routes/admin-errors.d.ts +4 -0
- package/dist/routes/admin-event-dlq.d.ts +39 -0
- package/dist/routes/admin-event-log.d.ts +42 -0
- package/dist/routes/admin-events.d.ts +46 -0
- package/dist/routes/admin-maintenance.d.ts +22 -0
- package/dist/routes/admin-org-settings.d.ts +29 -0
- package/dist/routes/admin-queue-execution.d.ts +27 -0
- package/dist/routes/admin-registrations.d.ts +37 -0
- package/dist/routes/admin-runs.d.ts +57 -0
- package/dist/routes/admin-scheduled-jobs.d.ts +36 -0
- package/dist/routes/admin-sources.d.ts +18 -0
- package/dist/routes/admin.d.ts +103 -0
- package/dist/routes/capabilities.d.ts +24 -0
- package/dist/routes/diagnostics.d.ts +16 -0
- package/dist/routes/health.d.ts +20 -0
- package/dist/routes/test-trigger.d.ts +41 -0
- package/dist/routes/uploads.d.ts +38 -0
- package/dist/routes/webhooks.d.ts +36 -0
- package/dist/scaler/bare-metal-backend.d.ts +107 -0
- package/dist/scaler/config.d.ts +303 -0
- package/dist/scaler/container-backend.d.ts +125 -0
- package/dist/scaler/file-tail.d.ts +23 -0
- package/dist/scaler/firecracker-api.d.ts +100 -0
- package/dist/scaler/firecracker-backend.d.ts +263 -0
- package/dist/scaler/index.d.ts +24 -0
- package/dist/scaler/ip-allocator.d.ts +177 -0
- package/dist/scaler/label-matcher.d.ts +73 -0
- package/dist/scaler/log-forwarder.d.ts +54 -0
- package/dist/scaler/machine-ledger.d.ts +160 -0
- package/dist/scaler/manager.d.ts +338 -0
- package/dist/scaler/nftables.d.ts +85 -0
- package/dist/scaler/types.d.ts +388 -0
- package/dist/scaler/warm-pool.d.ts +81 -0
- package/dist/secrets/audit-logger.d.ts +65 -0
- package/dist/secrets/backend-health.d.ts +60 -0
- package/dist/secrets/backend-registry.d.ts +68 -0
- package/dist/secrets/backend-sync.d.ts +40 -0
- package/dist/secrets/cleanup.d.ts +40 -0
- package/dist/secrets/config.d.ts +51 -0
- package/dist/secrets/crypto.d.ts +49 -0
- package/dist/secrets/ephemeral-keys.d.ts +49 -0
- package/dist/secrets/index.d.ts +17 -0
- package/dist/secrets/pg-secret-store.d.ts +105 -0
- package/dist/secrets/rbac.d.ts +47 -0
- package/dist/secrets/secret-output-store.d.ts +46 -0
- package/dist/secrets/secret-resolver.d.ts +137 -0
- package/dist/secrets/source-credentials.d.ts +61 -0
- package/dist/secrets/token-manager.d.ts +63 -0
- package/dist/secrets/vault-secret-store.d.ts +85 -0
- package/dist/security/comment-handler.d.ts +67 -0
- package/dist/security/contributor-cache.d.ts +75 -0
- package/dist/security/global-workflow-policy.d.ts +72 -0
- package/dist/security/lock-source.d.ts +34 -0
- package/dist/security/trust-resolver.d.ts +108 -0
- package/dist/security/workflow-diff.d.ts +26 -0
- package/dist/server.d.ts +17 -0
- package/dist/server.js +48055 -0
- package/dist/sources/index.d.ts +10 -0
- package/dist/sources/source-manager.d.ts +63 -0
- package/dist/sources/source-store.d.ts +79 -0
- package/dist/sources/source-validator.d.ts +16 -0
- package/dist/stale-detector/stale-run-detector.d.ts +109 -0
- package/dist/standalone.d.ts +20 -0
- package/dist/standalone.js +41546 -0
- package/dist/storage/blob-routes.d.ts +20 -0
- package/dist/storage/filesystem.d.ts +60 -0
- package/dist/storage/index.d.ts +20 -0
- package/dist/storage/s3.d.ts +68 -0
- package/dist/storage/sign-url.d.ts +45 -0
- package/dist/storage/types.d.ts +98 -0
- package/dist/webhook/dedup.d.ts +44 -0
- package/dist/webhook/event-log.d.ts +83 -0
- package/dist/webhook/generic-sources.d.ts +169 -0
- package/dist/webhook/handler.d.ts +23 -0
- package/dist/webhook/relay-buffer.d.ts +96 -0
- package/dist/webhook/verify-inbound.d.ts +78 -0
- package/dist/worker/in-memory-execution-tracker.d.ts +94 -0
- package/dist/worker/in-memory-job-queue.d.ts +74 -0
- package/dist/worker/static-agent-token-store.d.ts +58 -0
- package/dist/worker/worker-status.d.ts +36 -0
- package/dist/worker-core.d.ts +74 -0
- package/dist/ws/agent-api-registry.d.ts +49 -0
- package/dist/ws/agent-handler.d.ts +176 -0
- package/dist/ws/agent-heartbeat.d.ts +45 -0
- package/dist/ws/dashboard-backends-handler.d.ts +51 -0
- package/dist/ws/dashboard-diagnostics-handler.d.ts +56 -0
- package/dist/ws/dashboard-env-handler.d.ts +107 -0
- package/dist/ws/dashboard-global-workflows-handler.d.ts +72 -0
- package/dist/ws/dashboard-registrations-handler.d.ts +84 -0
- package/dist/ws/event-buffer.d.ts +16 -0
- package/dist/ws/observer-handler.d.ts +42 -0
- package/dist/ws/observer-registry.d.ts +88 -0
- package/dist/ws/platform-client.d.ts +270 -0
- package/dist/ws/server-options.d.ts +15 -0
- package/package.json +87 -6
- package/sbom.spdx.json +14370 -0
- package/index.js +0 -3
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orchestrator configuration.
|
|
3
|
+
*
|
|
4
|
+
* This is a thin backward-compatible wrapper around the new config resolution
|
|
5
|
+
* chain (config/resolver.ts). It preserves the existing synchronous loadConfig()
|
|
6
|
+
* API so that no other files need changing.
|
|
7
|
+
*
|
|
8
|
+
* The new config system lives in config/ and supports:
|
|
9
|
+
* - YAML config files (config/loader.ts)
|
|
10
|
+
* - Shared DB config store (config/shared-store.ts)
|
|
11
|
+
* - 4-layer resolution: env > YAML > DB > defaults (config/resolver.ts)
|
|
12
|
+
* - KICI_ env var mapping (config/env-overlay.ts)
|
|
13
|
+
*
|
|
14
|
+
* Provider configuration (GitHub Apps, etc.) is managed via the `sources` table
|
|
15
|
+
* and PgSecretStore, not through config. See SourceStore and SourceManager.
|
|
16
|
+
*/
|
|
17
|
+
import { z } from 'zod';
|
|
18
|
+
declare const configSchema: z.ZodObject<{
|
|
19
|
+
mode: z.ZodDefault<z.ZodEnum<{
|
|
20
|
+
platform: "platform";
|
|
21
|
+
hybrid: "hybrid";
|
|
22
|
+
independent: "independent";
|
|
23
|
+
}>>;
|
|
24
|
+
port: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
25
|
+
basePath: z.ZodDefault<z.ZodString>;
|
|
26
|
+
tlsCertPath: z.ZodOptional<z.ZodString>;
|
|
27
|
+
platformUrl: z.ZodOptional<z.ZodString>;
|
|
28
|
+
platformToken: z.ZodOptional<z.ZodString>;
|
|
29
|
+
dashboardUrl: z.ZodOptional<z.ZodString>;
|
|
30
|
+
databaseUrl: z.ZodDefault<z.ZodString>;
|
|
31
|
+
lockfileCacheMax: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
32
|
+
lockfileCacheTtlMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
33
|
+
queueMaxDepth: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
34
|
+
queueTimeoutMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
35
|
+
queueBackpressureThreshold: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
36
|
+
workerConcurrency: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
37
|
+
concurrencyWaitTimeoutMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
38
|
+
cacheStorageType: z.ZodOptional<z.ZodEnum<{
|
|
39
|
+
s3: "s3";
|
|
40
|
+
filesystem: "filesystem";
|
|
41
|
+
}>>;
|
|
42
|
+
cacheStoragePath: z.ZodOptional<z.ZodString>;
|
|
43
|
+
cacheStorageS3Bucket: z.ZodOptional<z.ZodString>;
|
|
44
|
+
cacheStorageS3Prefix: z.ZodDefault<z.ZodString>;
|
|
45
|
+
cacheStorageS3Region: z.ZodOptional<z.ZodString>;
|
|
46
|
+
cacheStorageS3Endpoint: z.ZodOptional<z.ZodString>;
|
|
47
|
+
cacheStorageS3ExternalEndpoint: z.ZodOptional<z.ZodString>;
|
|
48
|
+
cacheStorageS3ForcePathStyle: z.ZodOptional<z.ZodPipe<z.ZodEnum<{
|
|
49
|
+
true: "true";
|
|
50
|
+
false: "false";
|
|
51
|
+
}>, z.ZodTransform<boolean, "true" | "false">>>;
|
|
52
|
+
cacheStorageFsPath: z.ZodOptional<z.ZodString>;
|
|
53
|
+
cacheStorageFsBaseUrl: z.ZodOptional<z.ZodString>;
|
|
54
|
+
logStorageS3Bucket: z.ZodOptional<z.ZodString>;
|
|
55
|
+
cacheTtlDays: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
56
|
+
cacheBuildTimeoutMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
57
|
+
cacheMaxTarballBytes: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
58
|
+
webhookPayloadDir: z.ZodOptional<z.ZodString>;
|
|
59
|
+
scalerConfigPath: z.ZodOptional<z.ZodString>;
|
|
60
|
+
scalerConfigDir: z.ZodOptional<z.ZodString>;
|
|
61
|
+
machineLedgerDir: z.ZodOptional<z.ZodString>;
|
|
62
|
+
staleDetectorScanIntervalMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
63
|
+
staleDetectorThresholdMultiplier: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
64
|
+
jobHeartbeatIntervalMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
65
|
+
secretKey: z.ZodOptional<z.ZodString>;
|
|
66
|
+
secretKeyFile: z.ZodOptional<z.ZodString>;
|
|
67
|
+
secretKeyOld: z.ZodOptional<z.ZodString>;
|
|
68
|
+
secretKeyFileOld: z.ZodOptional<z.ZodString>;
|
|
69
|
+
bootstrapAdminToken: z.ZodOptional<z.ZodString>;
|
|
70
|
+
pgCustomerSecrets: z.ZodPipe<z.ZodDefault<z.ZodEnum<{
|
|
71
|
+
true: "true";
|
|
72
|
+
false: "false";
|
|
73
|
+
}>>, z.ZodTransform<boolean, "true" | "false">>;
|
|
74
|
+
agentAuth: z.ZodDefault<z.ZodEnum<{
|
|
75
|
+
token: "token";
|
|
76
|
+
none: "none";
|
|
77
|
+
}>>;
|
|
78
|
+
agentTokenTtlMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
79
|
+
eventRouterMaxChainDepth: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
80
|
+
eventRouterRateLimitPerWorkflowPerMinute: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
81
|
+
eventRouterEventTtlSeconds: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
82
|
+
eventRouterCleanupIntervalMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
83
|
+
eventRouterMaxDispatchAttempts: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
84
|
+
eventRouterLeaseDurationMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
85
|
+
eventRouterRetryBaseBackoffMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
86
|
+
eventRouterRetryMaxBackoffMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
87
|
+
eventRouterRetryScanIntervalMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
88
|
+
eventLogMaxPayloadBytes: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
89
|
+
logLevel: z.ZodDefault<z.ZodEnum<{
|
|
90
|
+
error: "error";
|
|
91
|
+
debug: "debug";
|
|
92
|
+
info: "info";
|
|
93
|
+
warn: "warn";
|
|
94
|
+
}>>;
|
|
95
|
+
nodeEnv: z.ZodDefault<z.ZodEnum<{
|
|
96
|
+
development: "development";
|
|
97
|
+
production: "production";
|
|
98
|
+
test: "test";
|
|
99
|
+
}>>;
|
|
100
|
+
internalProviderRepoPath: z.ZodOptional<z.ZodString>;
|
|
101
|
+
internalProviderCloneUrl: z.ZodOptional<z.ZodString>;
|
|
102
|
+
autoMigrate: z.ZodPipe<z.ZodDefault<z.ZodString>, z.ZodTransform<boolean, string>>;
|
|
103
|
+
agentMaxReconnectDelayMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
104
|
+
skipS3SentinelValidation: z.ZodPipe<z.ZodDefault<z.ZodString>, z.ZodTransform<boolean, string>>;
|
|
105
|
+
otelExporterOtlpEndpoint: z.ZodOptional<z.ZodString>;
|
|
106
|
+
cluster: z.ZodPrefault<z.ZodObject<{
|
|
107
|
+
instanceId: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
108
|
+
address: z.ZodOptional<z.ZodString>;
|
|
109
|
+
joinToken: z.ZodOptional<z.ZodString>;
|
|
110
|
+
credentialFile: z.ZodDefault<z.ZodString>;
|
|
111
|
+
autoRotateCredentials: z.ZodDefault<z.ZodBoolean>;
|
|
112
|
+
peers: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<string[], string | undefined>>;
|
|
113
|
+
raftElectionTimeoutMinMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
114
|
+
raftElectionTimeoutMaxMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
115
|
+
raftHeartbeatMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
116
|
+
peerHeartbeatIntervalMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
117
|
+
peerMaxReconnectDelayMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
118
|
+
role: z.ZodDefault<z.ZodEnum<{
|
|
119
|
+
coordinator: "coordinator";
|
|
120
|
+
worker: "worker";
|
|
121
|
+
}>>;
|
|
122
|
+
coordinatorUrl: z.ZodOptional<z.ZodString>;
|
|
123
|
+
coordinatorUrls: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<string[], string | undefined>>;
|
|
124
|
+
peerStaleTimeoutMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
125
|
+
electionGracePeriodMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
126
|
+
singleNode: z.ZodPipe<z.ZodDefault<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>, z.ZodTransform<boolean, string | boolean>>;
|
|
127
|
+
trustedProxies: z.ZodPipe<z.ZodDefault<z.ZodString>, z.ZodTransform<string[], string>>;
|
|
128
|
+
}, z.core.$strip>>;
|
|
129
|
+
}, z.core.$strip>;
|
|
130
|
+
/**
|
|
131
|
+
* App configuration type. Includes computed instanceId for multi-instance support.
|
|
132
|
+
*
|
|
133
|
+
* Provider configuration (GitHub Apps) is now managed via the sources table
|
|
134
|
+
* and SourceManager, not through config.
|
|
135
|
+
*/
|
|
136
|
+
export type AppConfig = z.infer<typeof configSchema> & {
|
|
137
|
+
/** Unique identifier for this orchestrator instance, generated at startup */
|
|
138
|
+
instanceId: string;
|
|
139
|
+
/** Object storage settings (populated from legacy env vars or SharedConfig) */
|
|
140
|
+
storage?: {
|
|
141
|
+
type?: 's3' | 'filesystem';
|
|
142
|
+
bucket?: string;
|
|
143
|
+
prefix?: string;
|
|
144
|
+
region?: string;
|
|
145
|
+
endpoint?: string;
|
|
146
|
+
externalEndpoint?: string;
|
|
147
|
+
forcePathStyle?: boolean;
|
|
148
|
+
logBucket?: string;
|
|
149
|
+
/** Filesystem backend: absolute base directory for cached blobs. */
|
|
150
|
+
fsBasePath?: string;
|
|
151
|
+
/** Filesystem backend: base URL the agent uses to reach this orchestrator. */
|
|
152
|
+
fsBaseUrl?: string;
|
|
153
|
+
};
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Env-var definition for the orchestrator. Exported so the docs generator and
|
|
157
|
+
* the deploy-stg pre-validator can re-parse without going through process.env.
|
|
158
|
+
*
|
|
159
|
+
* Note: passes the inner `baseSchema` (a ZodObject) so describe() can walk
|
|
160
|
+
* `.shape`, but uses the outer `configSchema` (with .superRefine) as the parser
|
|
161
|
+
* so cross-field rules still fire.
|
|
162
|
+
*/
|
|
163
|
+
export declare const envDef: import("@kici-dev/shared/env").DefineEnvResult<{
|
|
164
|
+
mode: "platform" | "hybrid" | "independent";
|
|
165
|
+
port: number;
|
|
166
|
+
basePath: string;
|
|
167
|
+
databaseUrl: string;
|
|
168
|
+
lockfileCacheMax: number;
|
|
169
|
+
lockfileCacheTtlMs: number;
|
|
170
|
+
queueMaxDepth: number;
|
|
171
|
+
queueTimeoutMs: number;
|
|
172
|
+
queueBackpressureThreshold: number;
|
|
173
|
+
workerConcurrency: number;
|
|
174
|
+
concurrencyWaitTimeoutMs: number;
|
|
175
|
+
cacheStorageS3Prefix: string;
|
|
176
|
+
cacheTtlDays: number;
|
|
177
|
+
cacheBuildTimeoutMs: number;
|
|
178
|
+
cacheMaxTarballBytes: number;
|
|
179
|
+
staleDetectorScanIntervalMs: number;
|
|
180
|
+
staleDetectorThresholdMultiplier: number;
|
|
181
|
+
jobHeartbeatIntervalMs: number;
|
|
182
|
+
pgCustomerSecrets: boolean;
|
|
183
|
+
agentAuth: "token" | "none";
|
|
184
|
+
agentTokenTtlMs: number;
|
|
185
|
+
eventRouterMaxChainDepth: number;
|
|
186
|
+
eventRouterRateLimitPerWorkflowPerMinute: number;
|
|
187
|
+
eventRouterEventTtlSeconds: number;
|
|
188
|
+
eventRouterCleanupIntervalMs: number;
|
|
189
|
+
eventRouterMaxDispatchAttempts: number;
|
|
190
|
+
eventRouterLeaseDurationMs: number;
|
|
191
|
+
eventRouterRetryBaseBackoffMs: number;
|
|
192
|
+
eventRouterRetryMaxBackoffMs: number;
|
|
193
|
+
eventRouterRetryScanIntervalMs: number;
|
|
194
|
+
eventLogMaxPayloadBytes: number;
|
|
195
|
+
logLevel: "error" | "debug" | "info" | "warn";
|
|
196
|
+
nodeEnv: "development" | "production" | "test";
|
|
197
|
+
autoMigrate: boolean;
|
|
198
|
+
agentMaxReconnectDelayMs: number;
|
|
199
|
+
skipS3SentinelValidation: boolean;
|
|
200
|
+
cluster: {
|
|
201
|
+
instanceId: string;
|
|
202
|
+
credentialFile: string;
|
|
203
|
+
autoRotateCredentials: boolean;
|
|
204
|
+
peers: string[];
|
|
205
|
+
raftElectionTimeoutMinMs: number;
|
|
206
|
+
raftElectionTimeoutMaxMs: number;
|
|
207
|
+
raftHeartbeatMs: number;
|
|
208
|
+
peerHeartbeatIntervalMs: number;
|
|
209
|
+
peerMaxReconnectDelayMs: number;
|
|
210
|
+
role: "coordinator" | "worker";
|
|
211
|
+
coordinatorUrls: string[];
|
|
212
|
+
peerStaleTimeoutMs: number;
|
|
213
|
+
electionGracePeriodMs: number;
|
|
214
|
+
singleNode: boolean;
|
|
215
|
+
trustedProxies: string[];
|
|
216
|
+
address?: string | undefined;
|
|
217
|
+
joinToken?: string | undefined;
|
|
218
|
+
coordinatorUrl?: string | undefined;
|
|
219
|
+
};
|
|
220
|
+
tlsCertPath?: string | undefined;
|
|
221
|
+
platformUrl?: string | undefined;
|
|
222
|
+
platformToken?: string | undefined;
|
|
223
|
+
dashboardUrl?: string | undefined;
|
|
224
|
+
cacheStorageType?: "s3" | "filesystem" | undefined;
|
|
225
|
+
cacheStoragePath?: string | undefined;
|
|
226
|
+
cacheStorageS3Bucket?: string | undefined;
|
|
227
|
+
cacheStorageS3Region?: string | undefined;
|
|
228
|
+
cacheStorageS3Endpoint?: string | undefined;
|
|
229
|
+
cacheStorageS3ExternalEndpoint?: string | undefined;
|
|
230
|
+
cacheStorageS3ForcePathStyle?: boolean | undefined;
|
|
231
|
+
cacheStorageFsPath?: string | undefined;
|
|
232
|
+
cacheStorageFsBaseUrl?: string | undefined;
|
|
233
|
+
logStorageS3Bucket?: string | undefined;
|
|
234
|
+
webhookPayloadDir?: string | undefined;
|
|
235
|
+
scalerConfigPath?: string | undefined;
|
|
236
|
+
scalerConfigDir?: string | undefined;
|
|
237
|
+
machineLedgerDir?: string | undefined;
|
|
238
|
+
secretKey?: string | undefined;
|
|
239
|
+
secretKeyFile?: string | undefined;
|
|
240
|
+
secretKeyOld?: string | undefined;
|
|
241
|
+
secretKeyFileOld?: string | undefined;
|
|
242
|
+
bootstrapAdminToken?: string | undefined;
|
|
243
|
+
internalProviderRepoPath?: string | undefined;
|
|
244
|
+
internalProviderCloneUrl?: string | undefined;
|
|
245
|
+
otelExporterOtlpEndpoint?: string | undefined;
|
|
246
|
+
}>;
|
|
247
|
+
export declare function loadConfig(): AppConfig;
|
|
248
|
+
export {};
|
|
249
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { Kysely } from 'kysely';
|
|
2
|
+
import type { Database } from '../db/types.js';
|
|
3
|
+
import type { RegistrationIndex } from '../registration/registration-index.js';
|
|
4
|
+
import type { EventRouter } from '../events/event-router.js';
|
|
5
|
+
import type { CronStore } from './cron-store.js';
|
|
6
|
+
interface CronSchedulerOptions {
|
|
7
|
+
db: Kysely<Database>;
|
|
8
|
+
registrationIndex: RegistrationIndex;
|
|
9
|
+
cronStore: CronStore;
|
|
10
|
+
eventRouter: EventRouter;
|
|
11
|
+
evaluationIntervalMs?: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Raft-leader-only cron evaluator.
|
|
15
|
+
*
|
|
16
|
+
* Only the current Raft leader evaluates cron schedules. On becoming leader,
|
|
17
|
+
* loads the last-fired cache from the DB, recovers missed schedules (fires
|
|
18
|
+
* once per schedule), then starts periodic evaluation.
|
|
19
|
+
*
|
|
20
|
+
* On losing leadership, stops evaluation immediately.
|
|
21
|
+
*
|
|
22
|
+
* Atomicity: each fire wraps `cronStore.tryClaimFire` and
|
|
23
|
+
* `eventRouter.emitInTx` in a single Postgres transaction. `pg_notify`
|
|
24
|
+
* inside that tx is queued by Postgres until commit, so a rollback discards
|
|
25
|
+
* both the `cron_last_fired` write AND the listener notification together.
|
|
26
|
+
* This closes the previous silent-loss window where a crash between claim
|
|
27
|
+
* and emit advanced `last_fired_at` without persisting an event row.
|
|
28
|
+
*/
|
|
29
|
+
export declare class CronScheduler {
|
|
30
|
+
private readonly db;
|
|
31
|
+
private readonly registrationIndex;
|
|
32
|
+
private readonly cronStore;
|
|
33
|
+
private readonly eventRouter;
|
|
34
|
+
private readonly evaluationIntervalMs;
|
|
35
|
+
private timer;
|
|
36
|
+
private isLeader;
|
|
37
|
+
private lastFiredCache;
|
|
38
|
+
constructor(options: CronSchedulerOptions);
|
|
39
|
+
/**
|
|
40
|
+
* Called when this orchestrator becomes the Raft leader.
|
|
41
|
+
* Loads last-fired cache, recovers missed schedules, starts periodic evaluation.
|
|
42
|
+
*/
|
|
43
|
+
onBecomeLeader(): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Called when this orchestrator loses Raft leadership.
|
|
46
|
+
* Stops the evaluation timer immediately.
|
|
47
|
+
*/
|
|
48
|
+
onLoseLeadership(): void;
|
|
49
|
+
/**
|
|
50
|
+
* Stop the scheduler entirely. Clears timer and resets leader state.
|
|
51
|
+
*/
|
|
52
|
+
stop(): void;
|
|
53
|
+
/**
|
|
54
|
+
* Reload the last-fired cache from the database.
|
|
55
|
+
* Called after registration changes as defense-in-depth to ensure
|
|
56
|
+
* the in-memory cache stays current even if registration IDs change.
|
|
57
|
+
*/
|
|
58
|
+
refreshCache(): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Evaluate all cron schedules and fire those that are due.
|
|
61
|
+
*
|
|
62
|
+
* For each schedule: uses croner to compute the most recent past scheduled
|
|
63
|
+
* time. If that time is after the last-fired-at (or no last-fired exists),
|
|
64
|
+
* fires the schedule.
|
|
65
|
+
*/
|
|
66
|
+
evaluate(): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* Recover missed schedules after becoming leader.
|
|
69
|
+
* Same logic as evaluate() but logs recovery context.
|
|
70
|
+
*/
|
|
71
|
+
private recoverMissedSchedules;
|
|
72
|
+
/**
|
|
73
|
+
* Evaluate a single registration and fire if due.
|
|
74
|
+
*/
|
|
75
|
+
private evaluateRegistration;
|
|
76
|
+
}
|
|
77
|
+
export {};
|
|
78
|
+
//# sourceMappingURL=cron-scheduler.d.ts.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Kysely, Transaction } from 'kysely';
|
|
2
|
+
import type { Database } from '../db/types.js';
|
|
3
|
+
type DbExecutor = Kysely<Database> | Transaction<Database>;
|
|
4
|
+
/**
|
|
5
|
+
* DB persistence for cron last-fired tracking.
|
|
6
|
+
*
|
|
7
|
+
* Tracks the last time each cron-triggered workflow registration was fired.
|
|
8
|
+
* Used by CronScheduler for fire-once-on-recovery after leader transitions.
|
|
9
|
+
* Uses upsert (INSERT ON CONFLICT UPDATE) for atomic idempotent writes.
|
|
10
|
+
*/
|
|
11
|
+
export declare class CronStore {
|
|
12
|
+
private readonly db;
|
|
13
|
+
constructor(db: Kysely<Database>);
|
|
14
|
+
/**
|
|
15
|
+
* Atomically claim a cron fire: only succeeds if no other orchestrator has
|
|
16
|
+
* already fired this registration at a time >= firedAt.
|
|
17
|
+
*
|
|
18
|
+
* Uses INSERT ... ON CONFLICT with a WHERE guard so the upsert only writes
|
|
19
|
+
* when `last_fired_at < firedAt` (or the row doesn't exist yet).
|
|
20
|
+
*
|
|
21
|
+
* Accepts an optional executor (Kysely DB handle or Transaction). The cron
|
|
22
|
+
* fire path passes a Transaction so the claim and the subsequent
|
|
23
|
+
* `kici_events` insert + `pg_notify` commit atomically — closing the
|
|
24
|
+
* "claim succeeds but emit fails" silent-loss window that existed when
|
|
25
|
+
* these were separate transactions.
|
|
26
|
+
*
|
|
27
|
+
* Returns true if this call won the race (the fire should proceed).
|
|
28
|
+
* Returns false if another node already recorded a fire >= firedAt.
|
|
29
|
+
*/
|
|
30
|
+
tryClaimFire(registrationId: string, firedAt: Date, executor?: DbExecutor): Promise<boolean>;
|
|
31
|
+
/**
|
|
32
|
+
* Get all last-fired records as a Map<registrationId, lastFiredAt>.
|
|
33
|
+
* Used for bulk loading during leader recovery.
|
|
34
|
+
*/
|
|
35
|
+
getAll(): Promise<Map<string, Date>>;
|
|
36
|
+
}
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=cron-store.d.ts.map
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dashboard handler for the orchestrator.
|
|
3
|
+
*
|
|
4
|
+
* Responds to dashboard.* and run.* WS messages from Platform by querying the local
|
|
5
|
+
* execution_jobs and execution_steps tables and reading logs from LogStorage.
|
|
6
|
+
*
|
|
7
|
+
* Supported messages:
|
|
8
|
+
* - dashboard.run.detail: returns jobs with nested steps for a run
|
|
9
|
+
* - dashboard.step.logs: returns log lines for a specific step
|
|
10
|
+
* - dashboard.payload: returns the original webhook payload for a run
|
|
11
|
+
* - run.rerun.request: re-runs a completed workflow run
|
|
12
|
+
* - run.cancel.request: cancels a running workflow run
|
|
13
|
+
*/
|
|
14
|
+
import type { Kysely } from 'kysely';
|
|
15
|
+
import { type ColdStore } from '@kici-dev/shared';
|
|
16
|
+
import type { DashboardRunDetailRequest, DashboardStepLogsRequest, DashboardPayloadRequest, DashboardOrchLogsRequest, DashboardEventLogListRequest, DashboardEventLogDetailRequest, DashboardEventLogPayloadStreamRequest, DashboardAccessLogListRequest, RunRerunRequest, RunCancelRequest, ManualScheduleRequest } from '@kici-dev/engine';
|
|
17
|
+
import type { Database } from '../db/types.js';
|
|
18
|
+
import type { LogStorage } from '../reporting/log-storage.js';
|
|
19
|
+
import type { AccessLogWriter } from '../audit/access-log.js';
|
|
20
|
+
interface DashboardHandlerDeps {
|
|
21
|
+
db: Kysely<Database>;
|
|
22
|
+
logStorage: LogStorage;
|
|
23
|
+
/** Send a response message back to Platform over the WS connection. */
|
|
24
|
+
send: (msg: unknown) => void;
|
|
25
|
+
/** This orchestrator's instance ID, included in job detail responses. */
|
|
26
|
+
orchestratorId?: string;
|
|
27
|
+
/** Access log writer — records one row per read / mutation with actor attribution. */
|
|
28
|
+
accessLog?: AccessLogWriter;
|
|
29
|
+
/** Org ID for access_log rows (null when the orchestrator isn't org-scoped). */
|
|
30
|
+
orgId?: string | null;
|
|
31
|
+
/** Routing key for access_log rows (null when not run-scoped). */
|
|
32
|
+
routingKey?: string | null;
|
|
33
|
+
/**
|
|
34
|
+
* Long-lived cold-store handle for read fallback. When set, run /
|
|
35
|
+
* job / step lookups fall through to S3 if the row has aged out of
|
|
36
|
+
* PG. `null` means the orchestrator is running without cold-store
|
|
37
|
+
* configured — handler then returns its pre-Phase-C behavior.
|
|
38
|
+
*/
|
|
39
|
+
coldStore?: ColdStore | null;
|
|
40
|
+
/**
|
|
41
|
+
* Callback for handling re-run requests.
|
|
42
|
+
* Returns { newRunId } on success or throws on failure.
|
|
43
|
+
*
|
|
44
|
+
* Phase F — `routingKey` is forwarded from the Platform (read from
|
|
45
|
+
* Platform's denormalized `execution_runs.routing_key`) so the
|
|
46
|
+
* orchestrator can probe its cold-store under the right tenant
|
|
47
|
+
* prefix when the run row is missing from PG. Optional for back-
|
|
48
|
+
* compat with mixed deploys; absent means the orchestrator falls
|
|
49
|
+
* back to the legacy "no PG row → throw" path.
|
|
50
|
+
*/
|
|
51
|
+
onRerun: (runId: string, triggeredBy: string | null, routingKey?: string) => Promise<{
|
|
52
|
+
newRunId: string;
|
|
53
|
+
}>;
|
|
54
|
+
/**
|
|
55
|
+
* Callback for handling cancel requests.
|
|
56
|
+
* Returns { cancelledJobs } on success or throws on failure.
|
|
57
|
+
* The force flag indicates whether to force-cancel (SIGKILL, skip hooks).
|
|
58
|
+
*/
|
|
59
|
+
onCancel: (runId: string, cancelledBy: string | null, force?: boolean) => Promise<{
|
|
60
|
+
cancelledJobs: number;
|
|
61
|
+
}>;
|
|
62
|
+
/**
|
|
63
|
+
* Callback for handling manual schedule trigger requests.
|
|
64
|
+
* Returns { newRunId } on success or throws on failure.
|
|
65
|
+
*/
|
|
66
|
+
onManualSchedule: (registrationId: string, triggeredBy: string | null) => Promise<{
|
|
67
|
+
newRunId: string;
|
|
68
|
+
}>;
|
|
69
|
+
}
|
|
70
|
+
export declare class DashboardHandler {
|
|
71
|
+
private readonly db;
|
|
72
|
+
private readonly logStorage;
|
|
73
|
+
private readonly send;
|
|
74
|
+
private readonly orchestratorId;
|
|
75
|
+
private readonly accessLog;
|
|
76
|
+
private orgId;
|
|
77
|
+
private routingKey;
|
|
78
|
+
private readonly onRerun;
|
|
79
|
+
private readonly onCancel;
|
|
80
|
+
private readonly onManualSchedule;
|
|
81
|
+
private readonly coldStore;
|
|
82
|
+
constructor(deps: DashboardHandlerDeps);
|
|
83
|
+
/**
|
|
84
|
+
* Update the bound orgId + routingKey. Called from server.ts after resolving
|
|
85
|
+
* the single tenant org from the `sources` / `generic_webhook_sources` table.
|
|
86
|
+
*
|
|
87
|
+
* NOTE: this binding is the **fallback** for `recordAccess`. Run-targeted
|
|
88
|
+
* handlers resolve the run-owning org per-request via `resolveOrgForRun`;
|
|
89
|
+
* the bound pair is consulted only when the per-target lookup yields no
|
|
90
|
+
* result (e.g. cold-archived run, deleted source). On a multi-tenant
|
|
91
|
+
* orchestrator the bound pair is non-deterministic (server.ts:937-955
|
|
92
|
+
* picks the first row from a `LIMIT 1` query with no `ORDER BY`), so it
|
|
93
|
+
* MUST NOT be the source of truth for `access_log.org_id`.
|
|
94
|
+
*/
|
|
95
|
+
setOrgContext(orgId: string | null, routingKey: string | null): void;
|
|
96
|
+
/**
|
|
97
|
+
* Resolve the run-owning org from `execution_runs.routing_key` plus a
|
|
98
|
+
* sources/generic_webhook_sources lookup on that routing key. Returns
|
|
99
|
+
* `null` when the run row is missing (e.g. cold-archived) so the caller
|
|
100
|
+
* can fall back to the handler-bound context.
|
|
101
|
+
*
|
|
102
|
+
* Returns `{ orgId, routingKey }` where either field can be null:
|
|
103
|
+
* - `routingKey` is non-null whenever the PG run row was found, even if
|
|
104
|
+
* the source row has since been deleted (best-effort attribution).
|
|
105
|
+
* - `orgId` is null only when the routing key has no matching source row.
|
|
106
|
+
*/
|
|
107
|
+
private resolveOrgForRun;
|
|
108
|
+
/**
|
|
109
|
+
* Resolve the org owning a routing key by consulting both source tables
|
|
110
|
+
* (GitHub-app `sources` first, then `generic_webhook_sources`). Used
|
|
111
|
+
* directly for `handleRerunRequest` (which gets a `routingKey` hint from
|
|
112
|
+
* Platform — Phase F denormalization) and indirectly via
|
|
113
|
+
* `resolveOrgForRun`.
|
|
114
|
+
*/
|
|
115
|
+
private resolveOrgForRoutingKey;
|
|
116
|
+
/**
|
|
117
|
+
* Resolve the org from a `workflow_registrations` row. Returns null when
|
|
118
|
+
* the registration is missing (caller falls back to bound context).
|
|
119
|
+
*/
|
|
120
|
+
private resolveOrgForRegistration;
|
|
121
|
+
/**
|
|
122
|
+
* Apply a per-target resolution result, falling back to the handler-bound
|
|
123
|
+
* orgId / routingKey when the resolution is null or its individual fields
|
|
124
|
+
* are null. This is the merge point that makes the bound context a
|
|
125
|
+
* fallback rather than the source of truth.
|
|
126
|
+
*/
|
|
127
|
+
private contextOrFallback;
|
|
128
|
+
/**
|
|
129
|
+
* Write an access_log row for a handler invocation. The caller resolves
|
|
130
|
+
* the run-owning org via `resolveOrgForRun` (or the registration / event-
|
|
131
|
+
* log equivalents) and threads it in here so each row carries the org
|
|
132
|
+
* that owns the target — not the handler-bound (multi-tenant: non-
|
|
133
|
+
* deterministic) pair. Best-effort; the writer swallows failures.
|
|
134
|
+
*/
|
|
135
|
+
private recordAccess;
|
|
136
|
+
/**
|
|
137
|
+
* Handle a dashboard.run.detail request.
|
|
138
|
+
* Queries execution_jobs and execution_steps for the given runId,
|
|
139
|
+
* builds a nested job/step tree, and sends the response.
|
|
140
|
+
*/
|
|
141
|
+
handleRunDetail(msg: DashboardRunDetailRequest): Promise<void>;
|
|
142
|
+
/**
|
|
143
|
+
* Handle a dashboard.step.logs request.
|
|
144
|
+
* Looks up the step's log_path and reads content from LogStorage.
|
|
145
|
+
*/
|
|
146
|
+
handleStepLogs(msg: DashboardStepLogsRequest): Promise<void>;
|
|
147
|
+
/**
|
|
148
|
+
* Handle a dashboard.payload request.
|
|
149
|
+
* Reads the webhook payload from log storage for the given runId.
|
|
150
|
+
*/
|
|
151
|
+
handlePayload(msg: DashboardPayloadRequest): Promise<void>;
|
|
152
|
+
/**
|
|
153
|
+
* Handle a dashboard.orch.logs request.
|
|
154
|
+
* Reads orchestration + provisioning log files from LogStorage for the given run/job.
|
|
155
|
+
* Provisioning logs are returned with phase "provisioning" so the dashboard can
|
|
156
|
+
* render them in a separate collapsible section.
|
|
157
|
+
*/
|
|
158
|
+
handleOrchLogs(msg: DashboardOrchLogsRequest): Promise<void>;
|
|
159
|
+
/**
|
|
160
|
+
* Handle a run.rerun.request.
|
|
161
|
+
* Delegates to the onRerun callback which invokes handleRerun from the rerun module.
|
|
162
|
+
*
|
|
163
|
+
* Resolution: prefer `msg.routingKey` (Phase F denormalization hint from
|
|
164
|
+
* Platform — `execution_runs.routing_key` mirror). The hint is the ONLY
|
|
165
|
+
* org context we have when the run row has been cold-archived out of PG,
|
|
166
|
+
* so consult sources/generic_webhook_sources directly. If the hint is
|
|
167
|
+
* absent, fall back to `resolveOrgForRun` against the warm PG row.
|
|
168
|
+
*/
|
|
169
|
+
handleRerunRequest(msg: RunRerunRequest): Promise<void>;
|
|
170
|
+
/**
|
|
171
|
+
* Handle a run.cancel.request.
|
|
172
|
+
* Delegates to the onCancel callback which sends job.cancel to agents.
|
|
173
|
+
*/
|
|
174
|
+
handleCancelRequest(msg: RunCancelRequest): Promise<void>;
|
|
175
|
+
/**
|
|
176
|
+
* Handle a dashboard.event-log.list request.
|
|
177
|
+
*
|
|
178
|
+
* Returns a paginated page of inbound webhook delivery rows owned by this
|
|
179
|
+
* orchestrator (`event_log` table) for the given org. Pagination uses an
|
|
180
|
+
* opaque cursor (received_at + id) so concurrent inserts don't shift pages.
|
|
181
|
+
*
|
|
182
|
+
* Filters: routingKey, event, status, fromTimestamp/toTimestamp,
|
|
183
|
+
* deliveryId substring. All optional.
|
|
184
|
+
*/
|
|
185
|
+
handleEventLogList(msg: DashboardEventLogListRequest): Promise<void>;
|
|
186
|
+
/**
|
|
187
|
+
* Handle a dashboard.access-log.list request.
|
|
188
|
+
*
|
|
189
|
+
* Returns a paginated page of access_log rows for the given org. Used by
|
|
190
|
+
* the dashboard "Data access" tab to show who read what (and when).
|
|
191
|
+
*
|
|
192
|
+
* Every filter is optional; the orchestrator scopes on orgId then applies
|
|
193
|
+
* each supplied filter independently. Records its own access_log row
|
|
194
|
+
* under action='access_log.list.read' so there's a meta-audit of who
|
|
195
|
+
* looked at the audit log.
|
|
196
|
+
*/
|
|
197
|
+
handleAccessLogList(msg: DashboardAccessLogListRequest): Promise<void>;
|
|
198
|
+
/**
|
|
199
|
+
* Handle a dashboard.event-log.detail request.
|
|
200
|
+
*
|
|
201
|
+
* Returns the metadata row only — the webhook body bytes stream over a
|
|
202
|
+
* separate chunked-WS path (`handleEventLogPayloadStream` below) so
|
|
203
|
+
* Platform never holds the full body in memory and the dashboard can
|
|
204
|
+
* render progress as bytes arrive. When `payload_omitted=true` the row's
|
|
205
|
+
* `payloadOmitted`/`payloadOmittedReason` fields tell the dashboard to
|
|
206
|
+
* skip issuing a stream request.
|
|
207
|
+
*/
|
|
208
|
+
handleEventLogDetail(msg: DashboardEventLogDetailRequest): Promise<void>;
|
|
209
|
+
/**
|
|
210
|
+
* Handle a dashboard.event-log.payload.stream request.
|
|
211
|
+
*
|
|
212
|
+
* Reads the gzipped body from LogStorage, decompresses it, slices the
|
|
213
|
+
* decompressed bytes into 64 KiB chunks, base64-encodes each, and emits a
|
|
214
|
+
* sequence of `dashboard.event-log.payload.chunk` messages. The first
|
|
215
|
+
* chunk carries `totalBytes`; the last chunk carries `isLast=true`.
|
|
216
|
+
*
|
|
217
|
+
* The single audit row (`event_log.payload.read`) is written at the start
|
|
218
|
+
* of the stream — outcome `allowed` when the row exists and the body
|
|
219
|
+
* begins streaming, `not_found` / `denied` when the request resolves to
|
|
220
|
+
* an empty/error stream. Per-chunk audits would inflate the access-log
|
|
221
|
+
* volume without adding attribution detail.
|
|
222
|
+
*
|
|
223
|
+
* Pacing: a `setImmediate` yield between sends keeps the WS connection
|
|
224
|
+
* from saturating. For a 5 MB cap (the wishlist's worst case) this means
|
|
225
|
+
* ~80 yields per stream — negligible.
|
|
226
|
+
*/
|
|
227
|
+
handleEventLogPayloadStream(msg: DashboardEventLogPayloadStreamRequest): Promise<void>;
|
|
228
|
+
/**
|
|
229
|
+
* Handle a run.manual_schedule.request.
|
|
230
|
+
* Delegates to the onManualSchedule callback which invokes handleManualSchedule.
|
|
231
|
+
*/
|
|
232
|
+
handleManualScheduleRequest(msg: ManualScheduleRequest): Promise<void>;
|
|
233
|
+
/**
|
|
234
|
+
* Phase C cold-store fallback: fetch the run + its jobs + its steps
|
|
235
|
+
* from S3 when the PG copy has been archived. Bounded scan: stops at
|
|
236
|
+
* the warm cutoff (older entries don't exist in cold-store yet by
|
|
237
|
+
* construction). Each row is filtered by `run_id` because chunks
|
|
238
|
+
* span multiple runs.
|
|
239
|
+
*/
|
|
240
|
+
private fetchArchivedRunDetail;
|
|
241
|
+
}
|
|
242
|
+
export {};
|
|
243
|
+
//# sourceMappingURL=handler.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import pg from 'pg';
|
|
2
|
+
import { Kysely } from 'kysely';
|
|
3
|
+
import { createPool as _createPool } from '@kici-dev/shared';
|
|
4
|
+
import type { Database } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Create PostgreSQL connection pool.
|
|
7
|
+
*/
|
|
8
|
+
export declare const createPool: typeof _createPool;
|
|
9
|
+
/**
|
|
10
|
+
* Create Kysely database instance typed to the orchestrator schema.
|
|
11
|
+
*/
|
|
12
|
+
export declare function createDb(pool: pg.Pool): Kysely<Database>;
|
|
13
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static migration provider for bundled builds.
|
|
3
|
+
*
|
|
4
|
+
* Rolldown doesn't support dynamic `import()` of migration files at runtime,
|
|
5
|
+
* so we statically import all migrations and provide them to Kysely's Migrator.
|
|
6
|
+
*/
|
|
7
|
+
import type { MigrationProvider } from 'kysely/migration';
|
|
8
|
+
export declare function createMigrationProvider(): MigrationProvider;
|
|
9
|
+
//# sourceMappingURL=migration-provider.d.ts.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
export declare function up(db: Kysely<any>): Promise<void>;
|
|
3
|
+
/**
|
|
4
|
+
* Rollback drops everything created above. Uses CASCADE on table drops to cut
|
|
5
|
+
* through the FK graph without relying on exact topological order.
|
|
6
|
+
*/
|
|
7
|
+
export declare function down(db: Kysely<any>): Promise<void>;
|
|
8
|
+
//# sourceMappingURL=001_initial.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Add key_version column to config_versions so that sensitive-field encryption
|
|
4
|
+
* can be rotated via `kici-admin rotate-key`.
|
|
5
|
+
*
|
|
6
|
+
* Existing rows are backfilled to 1 via the DEFAULT clause (every historical
|
|
7
|
+
* row was encrypted under the first master-key generation). After rotation,
|
|
8
|
+
* `SharedConfigStore` writes the next integer (MAX(key_version) + 1) and
|
|
9
|
+
* stores the active generation alongside the ciphertext.
|
|
10
|
+
*
|
|
11
|
+
* No index is needed: rotation does a full-table scan; reads are by
|
|
12
|
+
* `version` primary key and never filter on `key_version`.
|
|
13
|
+
*/
|
|
14
|
+
export declare function up(db: Kysely<any>): Promise<void>;
|
|
15
|
+
export declare function down(db: Kysely<any>): Promise<void>;
|
|
16
|
+
//# sourceMappingURL=002_config_versions_key_version.d.ts.map
|