@kici-dev/orchestrator 0.1.5 → 0.1.7

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.
@@ -134,6 +134,15 @@ var init_config$5 = __esmMin((() => {
134
134
  * behavior). Trailing slash optional.
135
135
  */
136
136
  dashboardUrl: z.string().optional(),
137
+ /**
138
+ * Public base URL at which this orchestrator's own webhook ingress is
139
+ * reachable (independent/hybrid self-serve generic webhooks:
140
+ * `<base>/webhook/<customerId>/generic/<sourceId>`). Used by
141
+ * `kici-admin source add` to print a generic source's webhook URL. GitHub-App
142
+ * ingress is Platform-relayed, so GitHub URLs come from the Platform's
143
+ * `source.register.ack`, not this value. Trailing slash optional.
144
+ */
145
+ webhookPublicUrl: z.string().optional(),
137
146
  databaseUrl: z.string().default(""),
138
147
  lockfileCacheMax: z.coerce.number().default(500),
139
148
  lockfileCacheTtlMs: z.coerce.number().default(36e5),
@@ -326,6 +335,7 @@ var init_config$5 = __esmMin((() => {
326
335
  platformUrl: "KICI_PLATFORM_URL",
327
336
  platformToken: "KICI_PLATFORM_TOKEN",
328
337
  dashboardUrl: "KICI_DASHBOARD_URL",
338
+ webhookPublicUrl: "KICI_WEBHOOK_PUBLIC_URL",
329
339
  databaseUrl: "KICI_DATABASE_URL",
330
340
  cacheStorageType: "KICI_STORAGE_TYPE",
331
341
  cacheStoragePath: "KICI_STORAGE_PATH",
@@ -1028,7 +1038,7 @@ var init_peer_client = __esmMin((() => {
1028
1038
  init_peer_crypto();
1029
1039
  init_peer_credentials();
1030
1040
  logger$85 = createLogger({ prefix: "peer-client" });
1031
- SOFTWARE_VERSION$1 = "0.1.5";
1041
+ SOFTWARE_VERSION$1 = "0.1.7";
1032
1042
  PeerClient$1 = class {
1033
1043
  ws = null;
1034
1044
  _state = "disconnected";
@@ -2491,7 +2501,7 @@ var init_peer_handler = __esmMin((() => {
2491
2501
  init_peer_crypto();
2492
2502
  init_join_token();
2493
2503
  logger$84 = createLogger({ prefix: "peer-handler" });
2494
- SOFTWARE_VERSION = "0.1.5";
2504
+ SOFTWARE_VERSION = "0.1.7";
2495
2505
  RATE_LIMIT_MAX = 5;
2496
2506
  RATE_LIMIT_WINDOW_MS = 6e4;
2497
2507
  }));
@@ -3125,7 +3135,7 @@ var init_coordinator = __esmMin((() => {
3125
3135
  peerRegistry;
3126
3136
  dispatcher;
3127
3137
  executionTracker;
3128
- commitStatusReporter;
3138
+ checkRunReporter;
3129
3139
  getPeerClient;
3130
3140
  sendAndWaitAckViaHandler;
3131
3141
  sendToPeerViaHandler;
@@ -3147,7 +3157,7 @@ var init_coordinator = __esmMin((() => {
3147
3157
  this.peerRegistry = deps.peerRegistry;
3148
3158
  this.dispatcher = deps.dispatcher;
3149
3159
  this.executionTracker = deps.executionTracker;
3150
- this.commitStatusReporter = deps.commitStatusReporter;
3160
+ this.checkRunReporter = deps.checkRunReporter;
3151
3161
  this.getPeerClient = deps.getPeerClient;
3152
3162
  this.sendAndWaitAckViaHandler = deps.sendAndWaitAckViaHandler;
3153
3163
  this.sendToPeerViaHandler = deps.sendToPeerViaHandler;
@@ -3270,10 +3280,10 @@ var init_coordinator = __esmMin((() => {
3270
3280
  const repoIdentifier = (msg.repoUrl ?? "").replace(/\.git$/, "").replace(/^https?:\/\/[^/]+\//, "").replace(/^[^/]+@[^:]+:/, "") || "";
3271
3281
  const providerContext = msg.providerContext ?? {};
3272
3282
  const installationId = typeof providerContext.installationId === "number" ? providerContext.installationId : void 0;
3273
- if (this.commitStatusReporter && repoIdentifier && msg.sha) {
3283
+ if (this.checkRunReporter && repoIdentifier && msg.sha) {
3274
3284
  const [owner, repo] = repoIdentifier.split("/");
3275
3285
  if (owner && repo) try {
3276
- await this.commitStatusReporter.setPendingAwait({
3286
+ await this.checkRunReporter.setPendingAwait({
3277
3287
  provider: msg.provider ?? "",
3278
3288
  owner,
3279
3289
  repo,
@@ -9760,7 +9770,7 @@ var init_check_run_summary = __esmMin((() => {
9760
9770
  ];
9761
9771
  }));
9762
9772
  //#endregion
9763
- //#region src/reporting/commit-status.ts
9773
+ //#region src/reporting/check-run-reporter.ts
9764
9774
  /**
9765
9775
  * GitHub check run integration module.
9766
9776
  *
@@ -9775,7 +9785,7 @@ var init_check_run_summary = __esmMin((() => {
9775
9785
  * Check run IDs are tracked in-memory after creation so that subsequent
9776
9786
  * updates (job complete, workflow complete) can reference them via checks.update().
9777
9787
  *
9778
- * Enriched output (Phase 14):
9788
+ * Enriched output:
9779
9789
  * - Live step progress with checklist-style updates (debounced at 5s)
9780
9790
  * - Failed check runs include step names, error messages, exit codes, and log context
9781
9791
  * - Check run annotations link failures to step source locations in workflow files (.kici/workflows/*.ts)
@@ -9785,7 +9795,7 @@ var init_check_run_summary = __esmMin((() => {
9785
9795
  * Note: The engine-level CheckStatusPoster interface (packages/engine/src/provider/check-status-poster.ts)
9786
9796
  * provides a provider-agnostic API for posting security-related check statuses (holds, approvals,
9787
9797
  * workflow modifications). The GitHub implementation is at packages/orchestrator/src/providers/github/check-status-poster.ts.
9788
- * This CommitStatusReporter handles execution lifecycle checks (queued, in_progress, completed per job/workflow).
9798
+ * This CheckRunReporter handles execution lifecycle checks (queued, in_progress, completed per job/workflow).
9789
9799
  * Future cleanup may unify both under CheckStatusPoster, but they serve different purposes today.
9790
9800
  */
9791
9801
  /**
@@ -9807,14 +9817,14 @@ function buildJobFailureDescription(data) {
9807
9817
  if (data.error) return `Job error: ${data.error}`;
9808
9818
  return "Job failed";
9809
9819
  }
9810
- var logger$70, PROGRESS_DEBOUNCE_MS, CommitStatusReporter;
9811
- var init_commit_status = __esmMin((() => {
9820
+ var logger$70, PROGRESS_DEBOUNCE_MS, CheckRunReporter;
9821
+ var init_check_run_reporter = __esmMin((() => {
9812
9822
  init_auth();
9813
9823
  init_prometheus();
9814
9824
  init_check_run_summary();
9815
- logger$70 = createLogger({ prefix: "commit-status" });
9825
+ logger$70 = createLogger({ prefix: "check-run-reporter" });
9816
9826
  PROGRESS_DEBOUNCE_MS = 5e3;
9817
- CommitStatusReporter = class {
9827
+ CheckRunReporter = class {
9818
9828
  /**
9819
9829
  * L1 cache: composite key → check run ID.
9820
9830
  *
@@ -10069,7 +10079,7 @@ var init_commit_status = __esmMin((() => {
10069
10079
  */
10070
10080
  async recoverState() {
10071
10081
  if (!this.deps.trackingStore) return;
10072
- logger$70.info("CommitStatusReporter recovered (DB-backed state lookups enabled)");
10082
+ logger$70.info("CheckRunReporter recovered (DB-backed state lookups enabled)");
10073
10083
  }
10074
10084
  /** Track a check run key associated with a runId for later cleanup. */
10075
10085
  trackRunKey(runId, key) {
@@ -13358,10 +13368,29 @@ function createSourceRoutes(deps) {
13358
13368
  privateKey,
13359
13369
  webhookSecret
13360
13370
  });
13371
+ let webhookUrl = null;
13372
+ let webhookNote;
13373
+ if (deps.resolveSourceWebhookUrl) try {
13374
+ const resolved = await deps.resolveSourceWebhookUrl({
13375
+ routingKey: source.routing_key,
13376
+ provider,
13377
+ sourceId: source.id
13378
+ });
13379
+ webhookUrl = resolved.webhookUrl;
13380
+ webhookNote = resolved.webhookNote;
13381
+ } catch (err) {
13382
+ logger$63.warn("Failed to resolve webhook URL for added source", {
13383
+ routingKey: source.routing_key,
13384
+ error: toErrorMessage(err)
13385
+ });
13386
+ webhookNote = "resolve-failed";
13387
+ }
13361
13388
  return c.json({
13362
13389
  routingKey: source.routing_key,
13363
13390
  id: source.id,
13364
- name: source.name
13391
+ name: source.name,
13392
+ webhookUrl,
13393
+ ...webhookNote && { webhookNote }
13365
13394
  }, 201);
13366
13395
  } catch (err) {
13367
13396
  logger$63.error("Failed to add source", { error: toErrorMessage(err) });
@@ -17742,7 +17771,10 @@ function createAdminRoutes(deps) {
17742
17771
  return handleError$3(c, err);
17743
17772
  }
17744
17773
  });
17745
- if (deps.sourceStore) app.route("/api/v1/admin", createSourceRoutes({ sourceStore: deps.sourceStore }));
17774
+ if (deps.sourceStore) app.route("/api/v1/admin", createSourceRoutes({
17775
+ sourceStore: deps.sourceStore,
17776
+ resolveSourceWebhookUrl: deps.resolveSourceWebhookUrl
17777
+ }));
17746
17778
  if (deps.db && deps.pool) app.route("/api/v1/admin", createDbRoutes({
17747
17779
  db: deps.db,
17748
17780
  pool: deps.pool
@@ -21504,14 +21536,14 @@ var init_admin_config = __esmMin((() => {
21504
21536
  function createHealthRoutes$1(deps = {}) {
21505
21537
  return createHealthRoutes({
21506
21538
  livenessInfo: () => ({
21507
- version: "0.1.5",
21508
- buildDate: "2026-05-25T13:18:39.135Z",
21509
- buildCommit: "600c43faa",
21510
- sdkVersion: "0.1.5",
21539
+ version: "0.1.7",
21540
+ buildDate: "2026-05-26T13:18:35.789Z",
21541
+ buildCommit: "4c0abe030",
21542
+ sdkVersion: "0.1.7",
21511
21543
  sdkBundleHash: "675aafe4de03e677785ef2794d8f34951b14e2bd1e6f0ea825953d6c2abfe128",
21512
- sharedVersion: "0.1.5",
21513
- sharedBundleHash: "12d8f17547ef0a63c0d54c59d918eefb5c5ad16d44c3b4d7fce081d23fe44a7a",
21514
- engineVersion: "0.1.5",
21544
+ sharedVersion: "0.1.7",
21545
+ sharedBundleHash: "36a23a454fd75ec35f258d39f254543ec0451c6b543fe3618ce427e6e6369aae",
21546
+ engineVersion: "0.1.7",
21515
21547
  engineBundleHash: "b704538612ec796a5668765bd55e0eaeaf1bad8a2afa508f9e20ad7b9eb61d21"
21516
21548
  }),
21517
21549
  readinessCheck: deps.db ? async () => {
@@ -21546,7 +21578,7 @@ function createCapabilitiesRoutes() {
21546
21578
  const app = new Hono();
21547
21579
  app.get("/api/v1/capabilities", (c) => {
21548
21580
  const manifest = {
21549
- orchestratorVersion: "0.1.5",
21581
+ orchestratorVersion: "0.1.7",
21550
21582
  protocolVersion: PROTOCOL_VERSION,
21551
21583
  minProtocolVersion: MIN_PROTOCOL_VERSION
21552
21584
  };
@@ -23036,7 +23068,7 @@ async function mintCloneTokenForReroute(args) {
23036
23068
  /**
23037
23069
  * Build the wrapped dispatcher, overlay info with effective routing/provider,
23038
23070
  * persist the webhook payload, fire source-location callbacks, and post the
23039
- * pending commit-status check. Pure side-effects + a typed result bag for
23071
+ * pending check-run check. Pure side-effects + a typed result bag for
23040
23072
  * downstream phases.
23041
23073
  */
23042
23074
  async function setupDispatchContext(ctx) {
@@ -23087,10 +23119,10 @@ async function setupDispatchContext(ctx) {
23087
23119
  const locs = job.steps.map((s) => s.sourceLocation);
23088
23120
  if (locs.some((l) => l !== void 0)) deps.onSourceLocationsExtracted(workflow.name, job.name, locs);
23089
23121
  }
23090
- if (deps.commitStatusReporter) {
23122
+ if (deps.checkRunReporter) {
23091
23123
  const [owner, repo] = repoIdentifier.split("/");
23092
23124
  const jobNames = workflow.jobs.filter(isLockStaticJob).map((j) => j.name);
23093
- await deps.commitStatusReporter.setPendingAwait({
23125
+ await deps.checkRunReporter.setPendingAwait({
23094
23126
  provider: info.provider,
23095
23127
  owner,
23096
23128
  repo,
@@ -23242,9 +23274,9 @@ async function runBuildJob(args) {
23242
23274
  let rejected = false;
23243
23275
  let error;
23244
23276
  const coalescingKey = `${contentHash || "none"}:${lockfileHash || "none"}`;
23245
- if (deps.commitStatusReporter) {
23277
+ if (deps.checkRunReporter) {
23246
23278
  const [owner, repo] = repoIdentifier.split("/");
23247
- deps.commitStatusReporter.setBuildPending({
23279
+ deps.checkRunReporter.setBuildPending({
23248
23280
  provider: setup.info.provider,
23249
23281
  owner,
23250
23282
  repo,
@@ -23313,9 +23345,9 @@ async function runBuildJob(args) {
23313
23345
  async function recordBuildFailure(args) {
23314
23346
  const { ctx, setup, buildJobTrackedEarly, err, buildJobId } = args;
23315
23347
  const { deps, workflow, repoIdentifier, credentials, event, ref, runId } = ctx;
23316
- if (deps.commitStatusReporter) {
23348
+ if (deps.checkRunReporter) {
23317
23349
  const [owner, repo] = repoIdentifier.split("/");
23318
- deps.commitStatusReporter.setBuildComplete({
23350
+ deps.checkRunReporter.setBuildComplete({
23319
23351
  provider: setup.info.provider,
23320
23352
  owner,
23321
23353
  repo,
@@ -23355,9 +23387,9 @@ async function recordBuildFailure(args) {
23355
23387
  async function readPostBuildCacheUrls(args) {
23356
23388
  const { ctx, setup, contentHash, lockfileHash, targetPlatform, targetArch } = args;
23357
23389
  const { deps, workflow, repoIdentifier, credentials, ref, runId } = ctx;
23358
- if (deps.commitStatusReporter) {
23390
+ if (deps.checkRunReporter) {
23359
23391
  const [owner, repo] = repoIdentifier.split("/");
23360
- deps.commitStatusReporter.setBuildComplete({
23392
+ deps.checkRunReporter.setBuildComplete({
23361
23393
  provider: setup.info.provider,
23362
23394
  owner,
23363
23395
  repo,
@@ -27317,7 +27349,7 @@ function createApp(deps) {
27317
27349
  sourceCache: deps.sourceCache,
27318
27350
  depCache: deps.depCache,
27319
27351
  cacheStorage: deps.cacheStorage,
27320
- onJobStatus: deps.platformClient || deps.executionTracker || deps.commitStatusReporter || deps.pendingBuilds || deps.pendingInits ? (_agentId, msg) => {
27352
+ onJobStatus: deps.platformClient || deps.executionTracker || deps.checkRunReporter || deps.pendingBuilds || deps.pendingInits ? (_agentId, msg) => {
27321
27353
  if (deps.pendingBuilds && deps.pendingBuilds.has(msg.jobId)) {
27322
27354
  if (msg.state === ExecutionJobStatus.enum.success && msg.data?.buildComplete) deps.pendingBuilds.resolve(msg.jobId);
27323
27355
  else if (msg.state === ExecutionJobStatus.enum.failed || msg.state === ExecutionJobStatus.enum.cancelled) deps.pendingBuilds.reject(msg.jobId, new Error(msg.data?.error ?? `Build ${msg.state}`));
@@ -27349,13 +27381,13 @@ function createApp(deps) {
27349
27381
  },
27350
27382
  timestamp: msg.timestamp
27351
27383
  });
27352
- if (deps.commitStatusReporter && deps.executionTracker && (msg.state === ExecutionJobStatus.enum.success || msg.state === ExecutionJobStatus.enum.failed || msg.state === ExecutionJobStatus.enum.cancelled)) {
27384
+ if (deps.checkRunReporter && deps.executionTracker && (msg.state === ExecutionJobStatus.enum.success || msg.state === ExecutionJobStatus.enum.failed || msg.state === ExecutionJobStatus.enum.cancelled)) {
27353
27385
  const execContext = deps.executionTracker.getExecutionContext(msg.runId);
27354
27386
  if (execContext) {
27355
27387
  const [owner, repo] = execContext.repoIdentifier.split("/");
27356
27388
  let description;
27357
27389
  if (msg.state === ExecutionJobStatus.enum.failed && msg.data) description = buildJobFailureDescription(msg.data);
27358
- deps.commitStatusReporter.updateJobStatus({
27390
+ deps.checkRunReporter.updateJobStatus({
27359
27391
  provider: execContext.provider,
27360
27392
  owner,
27361
27393
  repo,
@@ -27406,11 +27438,11 @@ function createApp(deps) {
27406
27438
  } : msg.data;
27407
27439
  deps.executionTracker.onStepStatus(msg.runId, msg.jobId, msg.stepIndex, msg.stepName, msg.state, msg.timestamp, data, msg.logBytesStreamed);
27408
27440
  }
27409
- if (deps.commitStatusReporter && deps.executionTracker) {
27441
+ if (deps.checkRunReporter && deps.executionTracker) {
27410
27442
  const execContext = deps.executionTracker.getExecutionContext(msg.runId);
27411
27443
  if (execContext) {
27412
27444
  const [owner, repo] = execContext.repoIdentifier.split("/");
27413
- deps.commitStatusReporter.updateStepProgress({
27445
+ deps.checkRunReporter.updateStepProgress({
27414
27446
  provider: execContext.provider,
27415
27447
  owner,
27416
27448
  repo,
@@ -27704,7 +27736,7 @@ function createApp(deps) {
27704
27736
  pendingBuilds: deps.pendingBuilds,
27705
27737
  pendingInits: deps.pendingInits,
27706
27738
  pendingDynamics: deps.pendingDynamics,
27707
- commitStatusReporter: deps.commitStatusReporter,
27739
+ checkRunReporter: deps.checkRunReporter,
27708
27740
  executionTracker: deps.executionTracker,
27709
27741
  onSourceLocationsExtracted,
27710
27742
  eventRouter: deps.eventRouter,
@@ -27745,7 +27777,8 @@ function createApp(deps) {
27745
27777
  }));
27746
27778
  if (deps.adminDeps) app.route("", createAdminRoutes({
27747
27779
  ...deps.adminDeps,
27748
- accessLog: deps.accessLogWriter
27780
+ accessLog: deps.accessLogWriter,
27781
+ resolveSourceWebhookUrl: deps.resolveSourceWebhookUrl
27749
27782
  }));
27750
27783
  if (deps.genericSourceManager && deps.trustStore && deps.adminDeps) app.route("", createAdminEventRoutes({
27751
27784
  sourceManager: deps.genericSourceManager,
@@ -27802,7 +27835,7 @@ function createApp(deps) {
27802
27835
  lockFileCache: deps.lockFileCache,
27803
27836
  dispatcher: deps.dispatcher,
27804
27837
  executionTracker: deps.executionTracker,
27805
- commitStatusReporter: deps.commitStatusReporter,
27838
+ checkRunReporter: deps.checkRunReporter,
27806
27839
  sourceCache: deps.sourceCache,
27807
27840
  buildCoordinator: deps.buildCoordinator,
27808
27841
  depCache: deps.depCache,
@@ -27959,7 +27992,7 @@ var init_app = __esmMin((() => {
27959
27992
  init_blob_routes();
27960
27993
  init_agent_api_registry();
27961
27994
  init_server_options();
27962
- init_commit_status();
27995
+ init_check_run_reporter();
27963
27996
  init_agent_handler();
27964
27997
  init_observer_handler();
27965
27998
  init_test_trigger();
@@ -35170,7 +35203,7 @@ var init_stale_run_detector = __esmMin((() => {
35170
35203
  StaleRunDetector = class {
35171
35204
  db;
35172
35205
  executionTracker;
35173
- commitStatusReporter;
35206
+ checkRunReporter;
35174
35207
  scalerManager;
35175
35208
  dispatcher;
35176
35209
  registry;
@@ -35181,7 +35214,7 @@ var init_stale_run_detector = __esmMin((() => {
35181
35214
  constructor(deps) {
35182
35215
  this.db = deps.db;
35183
35216
  this.executionTracker = deps.executionTracker;
35184
- this.commitStatusReporter = deps.commitStatusReporter;
35217
+ this.checkRunReporter = deps.checkRunReporter;
35185
35218
  this.scalerManager = deps.scalerManager;
35186
35219
  this.dispatcher = deps.dispatcher;
35187
35220
  this.registry = deps.registry;
@@ -35403,11 +35436,11 @@ var init_stale_run_detector = __esmMin((() => {
35403
35436
  });
35404
35437
  markedCount++;
35405
35438
  staleRunsDetectedTotal.add(1);
35406
- if (this.commitStatusReporter) {
35439
+ if (this.checkRunReporter) {
35407
35440
  const [owner, repo] = entry.repo_identifier.split("/");
35408
35441
  const providerCtx = typeof entry.provider_context === "string" ? JSON.parse(entry.provider_context) : entry.provider_context ?? {};
35409
35442
  const installationId = typeof providerCtx.installationId === "number" ? providerCtx.installationId : void 0;
35410
- this.commitStatusReporter.updateJobStatus({
35443
+ this.checkRunReporter.updateJobStatus({
35411
35444
  provider: entry.provider,
35412
35445
  owner,
35413
35446
  repo,
@@ -35465,11 +35498,11 @@ var init_stale_run_detector = __esmMin((() => {
35465
35498
  });
35466
35499
  await this.executionTracker.cancelStepsForJob(job.run_id, job.job_id, errorMessage);
35467
35500
  affectedRunIds.add(job.run_id);
35468
- if (this.commitStatusReporter) {
35501
+ if (this.checkRunReporter) {
35469
35502
  const [owner, repo] = job.repo_identifier.split("/");
35470
35503
  const providerCtx = typeof job.provider_context === "string" ? JSON.parse(job.provider_context) : job.provider_context ?? {};
35471
35504
  const installationId = typeof providerCtx.installationId === "number" ? providerCtx.installationId : void 0;
35472
- this.commitStatusReporter.updateJobStatus({
35505
+ this.checkRunReporter.updateJobStatus({
35473
35506
  provider: job.provider,
35474
35507
  owner,
35475
35508
  repo,
@@ -36559,10 +36592,27 @@ var init_source_manager = __esmMin((() => {
36559
36592
  currentSources = [];
36560
36593
  debounceTimer = null;
36561
36594
  debounceMs;
36595
+ /**
36596
+ * Change callback. Stored in a mutable field (not read off `opts`) so a
36597
+ * mode-specific hook can rewire it after construction — the platform-mode
36598
+ * boot wires it to push the full source list to the Platform via
36599
+ * `platformClient.updateSources()`. Defaults to the (possibly no-op) value
36600
+ * passed at construction.
36601
+ */
36602
+ onSourcesChanged;
36562
36603
  constructor(opts) {
36563
36604
  this.opts = opts;
36564
36605
  this.registry = new ProviderRegistry();
36565
36606
  this.debounceMs = opts.debounceMs ?? 200;
36607
+ this.onSourcesChanged = opts.onSourcesChanged;
36608
+ }
36609
+ /**
36610
+ * Replace the change callback after construction. The SourceManager is built
36611
+ * early (before the Platform client exists); the platform-mode boot calls
36612
+ * this once the client is ready so live source changes propagate upstream.
36613
+ */
36614
+ setOnSourcesChanged(cb) {
36615
+ this.onSourcesChanged = cb;
36566
36616
  }
36567
36617
  /** Get current ProviderRegistry (rebuilt on each reload). */
36568
36618
  getRegistry() {
@@ -36637,7 +36687,7 @@ var init_source_manager = __esmMin((() => {
36637
36687
  added: diff.added.length,
36638
36688
  removed: diff.removed.length
36639
36689
  });
36640
- if (diff.added.length > 0 || diff.removed.length > 0) this.opts.onSourcesChanged(diff);
36690
+ if (diff.added.length > 0 || diff.removed.length > 0) this.onSourcesChanged(diff);
36641
36691
  }
36642
36692
  /**
36643
36693
  * Build a ProviderBundle for a source with decrypted secrets.
@@ -39537,9 +39587,19 @@ var init_generic_sources_listener = __esmMin((() => {
39537
39587
  pending = /* @__PURE__ */ new Set();
39538
39588
  debounceTimer = null;
39539
39589
  debounceMs;
39590
+ /**
39591
+ * Drain-applied-change callback. Mutable so the platform-mode boot can wire
39592
+ * it after the Platform client exists (this listener is constructed before).
39593
+ */
39594
+ onChange;
39540
39595
  constructor(opts) {
39541
39596
  this.opts = opts;
39542
39597
  this.debounceMs = opts.debounceMs ?? 200;
39598
+ this.onChange = opts.onChange;
39599
+ }
39600
+ /** Replace the drain-applied-change callback after construction. */
39601
+ setOnChange(cb) {
39602
+ this.onChange = cb;
39543
39603
  }
39544
39604
  /** Open the dedicated client and subscribe. Cold-boot bundle
39545
39605
  * registration is handled by the orchestrator-core startup loop
@@ -39585,6 +39645,7 @@ var init_generic_sources_listener = __esmMin((() => {
39585
39645
  async drain() {
39586
39646
  const keys = Array.from(this.pending);
39587
39647
  this.pending.clear();
39648
+ let appliedChange = false;
39588
39649
  for (const routingKey of keys) try {
39589
39650
  const row = await this.opts.sourceManager.getByRoutingKey(routingKey);
39590
39651
  if (!row) {
@@ -39593,6 +39654,7 @@ var init_generic_sources_listener = __esmMin((() => {
39593
39654
  routingKey,
39594
39655
  removed
39595
39656
  });
39657
+ appliedChange = true;
39596
39658
  continue;
39597
39659
  }
39598
39660
  this.opts.providerRegistry.unregister(routingKey);
@@ -39601,12 +39663,14 @@ var init_generic_sources_listener = __esmMin((() => {
39601
39663
  config: this.opts.config,
39602
39664
  secretResolver: this.opts.secretResolver
39603
39665
  });
39666
+ appliedChange = true;
39604
39667
  } catch (err) {
39605
39668
  logger$8.error("Failed to apply generic-source change", {
39606
39669
  routingKey,
39607
39670
  error: toErrorMessage(err)
39608
39671
  });
39609
39672
  }
39673
+ if (appliedChange) this.onChange?.();
39610
39674
  }
39611
39675
  };
39612
39676
  }));
@@ -41353,7 +41417,7 @@ function buildOnEventMatched(dispatcherRef, executionTracker, providerRegistryRe
41353
41417
  }
41354
41418
  };
41355
41419
  }
41356
- function initializeCluster(config, db, agentRegistry, dispatcher, executionTracker, commitStatusReporter, cacheStorage, scalerManager, registrationIndex, cronScheduler, configReloaderRef, localConfigVersionRef, stepLogBuffer, eventRetryScannerRef) {
41420
+ function initializeCluster(config, db, agentRegistry, dispatcher, executionTracker, checkRunReporter, cacheStorage, scalerManager, registrationIndex, cronScheduler, configReloaderRef, localConfigVersionRef, stepLogBuffer, eventRetryScannerRef) {
41357
41421
  const peerClients = /* @__PURE__ */ new Map();
41358
41422
  const getLocalInventory = () => ({
41359
41423
  instanceId: config.instanceId,
@@ -41457,7 +41521,7 @@ function initializeCluster(config, db, agentRegistry, dispatcher, executionTrack
41457
41521
  peerRegistry,
41458
41522
  dispatcher,
41459
41523
  executionTracker,
41460
- commitStatusReporter,
41524
+ checkRunReporter,
41461
41525
  getPeerClient: (instanceId) => peerClients.get(instanceId),
41462
41526
  sendAndWaitAckViaHandler: (targetId, msg, timeoutMs) => peerHandlerObj?.sendAndWaitAck(targetId, msg, timeoutMs) ?? Promise.resolve(false),
41463
41527
  sendToPeerViaHandler: (targetId, msg) => peerHandlerObj?.sendToPeer(targetId, msg) ?? false
@@ -41667,7 +41731,7 @@ async function bootstrapOrchestrator$1(config, hooks, options) {
41667
41731
  const stepLogBuffer = new StepLogBuffer();
41668
41732
  const sourceLocationStore = new SourceLocationStore();
41669
41733
  const checkRunTrackingStore = new CheckRunTrackingStore(db);
41670
- const commitStatusReporter = new CommitStatusReporter({
41734
+ const checkRunReporter = new CheckRunReporter({
41671
41735
  providerRegistry,
41672
41736
  stepLogBuffer,
41673
41737
  trackingStore: checkRunTrackingStore,
@@ -41714,7 +41778,7 @@ async function bootstrapOrchestrator$1(config, hooks, options) {
41714
41778
  });
41715
41779
  });
41716
41780
  const [owner, repo] = context.repoIdentifier.split("/");
41717
- commitStatusReporter.updateWorkflowStatus({
41781
+ checkRunReporter.updateWorkflowStatus({
41718
41782
  provider: context.provider,
41719
41783
  owner,
41720
41784
  repo,
@@ -41764,7 +41828,7 @@ async function bootstrapOrchestrator$1(config, hooks, options) {
41764
41828
  orgId: trackerExtras?.orgId,
41765
41829
  onRunPruned: (runId) => {
41766
41830
  stepLogBuffer.cleanup(runId);
41767
- commitStatusReporter.cleanupRun(runId);
41831
+ checkRunReporter.cleanupRun(runId);
41768
41832
  },
41769
41833
  onWorkflowComplete: (data) => {
41770
41834
  if (!eventEmitter) return;
@@ -41870,7 +41934,7 @@ async function bootstrapOrchestrator$1(config, hooks, options) {
41870
41934
  if (pgSecretStore) {
41871
41935
  providerRegistry = await sourceManager.start();
41872
41936
  providerRegistryRef.current = providerRegistry;
41873
- commitStatusReporter.updateRegistry(providerRegistry);
41937
+ checkRunReporter.updateRegistry(providerRegistry);
41874
41938
  const registeredKeys = providerRegistry.getRoutingKeys();
41875
41939
  if (registeredKeys.length > 0) logger$2.info("Provider registry built from sources", { routingKeys: registeredKeys });
41876
41940
  else logger$2.info("No sources configured yet (orchestrator can start with zero sources)");
@@ -42017,7 +42081,7 @@ async function bootstrapOrchestrator$1(config, hooks, options) {
42017
42081
  ttl: config.lockfileCacheTtlMs
42018
42082
  });
42019
42083
  const configReloaderRef = { current: null };
42020
- const cluster = initializeCluster(config, db, agentRegistry, dispatcher, executionTracker, commitStatusReporter, cacheStorage, scalerManager, registrationIndex, cronScheduler, configReloaderRef, localConfigVersionRef, stepLogBuffer, eventRetryScannerRef);
42084
+ const cluster = initializeCluster(config, db, agentRegistry, dispatcher, executionTracker, checkRunReporter, cacheStorage, scalerManager, registrationIndex, cronScheduler, configReloaderRef, localConfigVersionRef, stepLogBuffer, eventRetryScannerRef);
42021
42085
  coordinatorRef.current = cluster.coordinator;
42022
42086
  if (adminDeps) adminDeps.broadcastAgentTokenRevoke = cluster.broadcastAgentTokenRevoke;
42023
42087
  let masterKeyForStore = null;
@@ -42056,7 +42120,7 @@ async function bootstrapOrchestrator$1(config, hooks, options) {
42056
42120
  pendingBuilds,
42057
42121
  pendingInits,
42058
42122
  pendingDynamics,
42059
- commitStatusReporter,
42123
+ checkRunReporter,
42060
42124
  stepLogBuffer,
42061
42125
  sourceLocationStore,
42062
42126
  logStorage,
@@ -42092,6 +42156,7 @@ async function bootstrapOrchestrator$1(config, hooks, options) {
42092
42156
  localConfigVersion: localConfigVersionRef.value,
42093
42157
  sourceStore,
42094
42158
  sourceManager,
42159
+ genericSourcesChangeListener,
42095
42160
  eventLogWriter,
42096
42161
  accessLogWriter,
42097
42162
  coldStore: coldStoreSingleton,
@@ -42143,7 +42208,7 @@ async function bootstrapOrchestrator$1(config, hooks, options) {
42143
42208
  await sourceManager.reload();
42144
42209
  providerRegistry = sourceManager.getRegistry();
42145
42210
  providerRegistryRef.current = providerRegistry;
42146
- commitStatusReporter.updateRegistry(providerRegistry);
42211
+ checkRunReporter.updateRegistry(providerRegistry);
42147
42212
  logger$2.info("Provider registry reloaded from sources", { routingKeys: providerRegistry.getRoutingKeys() });
42148
42213
  }),
42149
42214
  onScalerReload: scalerManager ? async () => {
@@ -42244,7 +42309,7 @@ async function bootstrapOrchestrator$1(config, hooks, options) {
42244
42309
  pendingBuilds,
42245
42310
  pendingInits,
42246
42311
  pendingDynamics,
42247
- commitStatusReporter,
42312
+ checkRunReporter,
42248
42313
  executionTracker,
42249
42314
  logWriter,
42250
42315
  stepLogBuffer,
@@ -42298,7 +42363,7 @@ async function bootstrapOrchestrator$1(config, hooks, options) {
42298
42363
  const staleRunDetector = new StaleRunDetector({
42299
42364
  db,
42300
42365
  executionTracker,
42301
- commitStatusReporter,
42366
+ checkRunReporter,
42302
42367
  scalerManager: scalerManager ?? void 0,
42303
42368
  dispatcher,
42304
42369
  registry: agentRegistry,
@@ -42505,7 +42570,7 @@ var init_orchestrator_core = __esmMin((() => {
42505
42570
  init_scaler();
42506
42571
  init_storage();
42507
42572
  init_cache();
42508
- init_commit_status();
42573
+ init_check_run_reporter();
42509
42574
  init_check_run_tracking_store();
42510
42575
  init_scaler_state_store();
42511
42576
  init_processor();
@@ -43640,13 +43705,13 @@ var init_worker_core = __esmMin((() => {
43640
43705
  init_agent_handler();
43641
43706
  init_worker_status();
43642
43707
  init_agent_heartbeat();
43643
- ORCHESTRATOR_VERSION$1 = "0.1.5";
43644
- WORKER_BUILD_COMMIT = "600c43faa";
43645
- WORKER_SDK_VERSION = "0.1.5";
43708
+ ORCHESTRATOR_VERSION$1 = "0.1.7";
43709
+ WORKER_BUILD_COMMIT = "4c0abe030";
43710
+ WORKER_SDK_VERSION = "0.1.7";
43646
43711
  WORKER_SDK_BUNDLE_HASH = "675aafe4de03e677785ef2794d8f34951b14e2bd1e6f0ea825953d6c2abfe128";
43647
- WORKER_SHARED_VERSION = "0.1.5";
43648
- WORKER_SHARED_BUNDLE_HASH = "12d8f17547ef0a63c0d54c59d918eefb5c5ad16d44c3b4d7fce081d23fe44a7a";
43649
- WORKER_ENGINE_VERSION = "0.1.5";
43712
+ WORKER_SHARED_VERSION = "0.1.7";
43713
+ WORKER_SHARED_BUNDLE_HASH = "36a23a454fd75ec35f258d39f254543ec0451c6b543fe3618ce427e6e6369aae";
43714
+ WORKER_ENGINE_VERSION = "0.1.7";
43650
43715
  WORKER_ENGINE_BUNDLE_HASH = "b704538612ec796a5668765bd55e0eaeaf1bad8a2afa508f9e20ad7b9eb61d21";
43651
43716
  logger$1 = createLogger({ prefix: "worker" });
43652
43717
  DRAIN_TIMEOUT_MS = 3e5;
@@ -43671,13 +43736,13 @@ var init_worker_core = __esmMin((() => {
43671
43736
  * Graceful shutdown:
43672
43737
  * agent WS -> heartbeat -> HTTP -> DB
43673
43738
  */
43674
- const ORCHESTRATOR_VERSION = "0.1.5";
43675
- const BUILD_COMMIT = "600c43faa";
43676
- const SDK_VERSION = "0.1.5";
43739
+ const ORCHESTRATOR_VERSION = "0.1.7";
43740
+ const BUILD_COMMIT = "4c0abe030";
43741
+ const SDK_VERSION = "0.1.7";
43677
43742
  const SDK_BUNDLE_HASH = "675aafe4de03e677785ef2794d8f34951b14e2bd1e6f0ea825953d6c2abfe128";
43678
- const SHARED_VERSION = "0.1.5";
43679
- const SHARED_BUNDLE_HASH = "12d8f17547ef0a63c0d54c59d918eefb5c5ad16d44c3b4d7fce081d23fe44a7a";
43680
- const ENGINE_VERSION = "0.1.5";
43743
+ const SHARED_VERSION = "0.1.7";
43744
+ const SHARED_BUNDLE_HASH = "36a23a454fd75ec35f258d39f254543ec0451c6b543fe3618ce427e6e6369aae";
43745
+ const ENGINE_VERSION = "0.1.7";
43681
43746
  const ENGINE_BUNDLE_HASH = "b704538612ec796a5668765bd55e0eaeaf1bad8a2afa508f9e20ad7b9eb61d21";
43682
43747
  const otelSdk = initTelemetry({
43683
43748
  serviceName: "kici-orchestrator",
@@ -43807,12 +43872,18 @@ await guardStartup(logger, async () => {
43807
43872
  client.connect();
43808
43873
  }
43809
43874
  return {
43810
- appDepsExtras: {},
43875
+ appDepsExtras: { resolveSourceWebhookUrl: async (params) => params.provider === "github" ? {
43876
+ webhookUrl: null,
43877
+ webhookNote: "github-ingress-platform-only"
43878
+ } : {
43879
+ webhookUrl: null,
43880
+ webhookNote: "unsupported-provider"
43881
+ } },
43811
43882
  configReloaderExtras: { onProviderChange: async (_newConfig, _oldConfig, s) => {
43812
43883
  await s.sourceManager.reload();
43813
43884
  const newRegistry = s.sourceManager.getRegistry();
43814
43885
  s.providerRegistry = newRegistry;
43815
- s.commitStatusReporter.updateRegistry(newRegistry);
43886
+ s.checkRunReporter.updateRegistry(newRegistry);
43816
43887
  logger.info("Provider registry reloaded from sources (standalone)", { routingKeys: newRegistry.getRoutingKeys() });
43817
43888
  } },
43818
43889
  shutdownExtras: [],
@@ -53,6 +53,14 @@ export interface GenericSourcesChangeListenerOptions {
53
53
  secretResolver: SecretResolver | null;
54
54
  /** Coalesce window for rapid NOTIFYs against the same row. Default 200 ms. */
55
55
  debounceMs?: number;
56
+ /**
57
+ * Invoked once per drain pass that applied at least one change. The
58
+ * platform-mode boot wires this to re-push the full source list to the
59
+ * Platform (`platformClient.updateSources()`) so a generic source added /
60
+ * removed at runtime reaches the Platform's `webhook_sources` immediately,
61
+ * not just the local registry.
62
+ */
63
+ onChange?: () => void;
56
64
  }
57
65
  export declare class GenericSourcesChangeListener {
58
66
  private readonly opts;
@@ -60,7 +68,14 @@ export declare class GenericSourcesChangeListener {
60
68
  private readonly pending;
61
69
  private debounceTimer;
62
70
  private readonly debounceMs;
71
+ /**
72
+ * Drain-applied-change callback. Mutable so the platform-mode boot can wire
73
+ * it after the Platform client exists (this listener is constructed before).
74
+ */
75
+ private onChange?;
63
76
  constructor(opts: GenericSourcesChangeListenerOptions);
77
+ /** Replace the drain-applied-change callback after construction. */
78
+ setOnChange(cb: () => void): void;
64
79
  /** Open the dedicated client and subscribe. Cold-boot bundle
65
80
  * registration is handled by the orchestrator-core startup loop
66
81
  * via the same helper; this listener only services warm-path