@kici-dev/orchestrator 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,6 +20,8 @@ export declare class VariableStore {
20
20
  deleteVar(orgId: string, contextId: string, key: string): Promise<void>;
21
21
  /** List source overrides for a specific source (routing key). */
22
22
  listSourceOverrides(orgId: string, contextId: string, routingKey: string): Promise<ContextSourceOverride[]>;
23
+ /** List every source override in a context, across all routing keys. */
24
+ listAllSourceOverrides(orgId: string, contextId: string): Promise<ContextSourceOverride[]>;
23
25
  /** Upsert a source override. */
24
26
  setSourceOverride(orgId: string, contextId: string, routingKey: string, key: string, value: string): Promise<void>;
25
27
  /** Delete a source override. */
package/dist/index.js CHANGED
@@ -2509,6 +2509,32 @@ var AdminApiClient = class {
2509
2509
  return this.request("DELETE", `/api/v1/admin/secrets/${encodeURIComponent(orgId)}/${encodeURIComponent(scope)}/${encodeURIComponent(key)}`);
2510
2510
  }
2511
2511
  /**
2512
+ * Create an empty secret scope. A `<backend>:` qualifier selects the
2513
+ * backend; an unqualified scope targets the PG backend. Creating a scope
2514
+ * that already exists succeeds and changes nothing.
2515
+ */
2516
+ async createScope(orgId, scope) {
2517
+ return this.request("POST", "/api/v1/admin/secrets/scopes", {
2518
+ orgId,
2519
+ scope
2520
+ });
2521
+ }
2522
+ /**
2523
+ * Rename a secret scope inside its backend. The route refuses a move between
2524
+ * backends and a rename onto a scope that already exists.
2525
+ */
2526
+ async renameScope(orgId, oldScope, newScope) {
2527
+ return this.request("PUT", "/api/v1/admin/secrets/scopes/rename", {
2528
+ orgId,
2529
+ oldScope,
2530
+ newScope
2531
+ });
2532
+ }
2533
+ /** Delete a secret scope and every secret in it. */
2534
+ async deleteScope(orgId, scope) {
2535
+ return this.request("DELETE", `/api/v1/admin/secrets/scopes/${encodeURIComponent(orgId)}/${encodeURIComponent(scope)}`);
2536
+ }
2537
+ /**
2512
2538
  * Create (or upsert) a deployment context. `allowLocalExecution` lets
2513
2539
  * CLI-initiated / local runs resolve secrets through this context.
2514
2540
  */
@@ -11,6 +11,12 @@
11
11
  * GET /api/v1/admin/contexts/:name/variables?orgId=<id> — list org-level variables
12
12
  * PUT /api/v1/admin/contexts/:name/variables/:key?orgId=<id> — upsert variable
13
13
  * DELETE /api/v1/admin/contexts/:name/variables/:key?orgId=<id> — delete variable
14
+ * GET /api/v1/admin/contexts/:name/source-overrides?orgId=<id>[&routingKey=<k>]
15
+ * — list per-source overrides
16
+ * PUT /api/v1/admin/contexts/:name/source-overrides/:routingKey/:key?orgId=<id>
17
+ * — upsert a source override
18
+ * DELETE /api/v1/admin/contexts/:name/source-overrides/:routingKey/:key?orgId=<id>
19
+ * — delete a source override
14
20
  *
15
21
  * Backs the `kici-admin context` dual-mode CLI. Offline (direct-DB) mode
16
22
  * bypasses this router entirely — the CLI calls `*Direct` helpers from
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Admin API routes for workflow registration management.
3
3
  *
4
- * Provides endpoints for listing, inspecting, refreshing, and deleting
5
- * workflow registrations. All routes are protected by Bearer token
4
+ * Provides endpoints for listing, inspecting, refreshing, disabling and
5
+ * deleting workflow registrations. All routes are protected by Bearer token
6
6
  * authentication via the existing admin auth middleware pattern.
7
7
  */
8
8
  import { Hono } from 'hono';
@@ -32,7 +32,7 @@ export declare class AuditLogger {
32
32
  * engine's `shouldRecordSecretResolve` helper) since they're written
33
33
  * once per JOB-step secret resolution and dwarf every other action's
34
34
  * volume. Denied resolves and every other action (`setSecret`,
35
- * `deleteSecret`, `rotateKey`, `secret-outputs.reveal`) bypass the
35
+ * `deleteSecret`, the scope writes, `rotateKey`, `secret-outputs.reveal`) bypass the
36
36
  * sampler — they are transactional with the mutation and must always
37
37
  * land.
38
38
  *
package/dist/server.js CHANGED
@@ -43533,6 +43533,10 @@ var init_variable_store = __esmMin((() => {
43533
43533
  async listSourceOverrides(orgId, contextId, routingKey) {
43534
43534
  return this.db.selectFrom("context_source_overrides").selectAll().where("org_id", "=", orgId).where("context_id", "=", contextId).where("routing_key", "=", routingKey).execute();
43535
43535
  }
43536
+ /** List every source override in a context, across all routing keys. */
43537
+ async listAllSourceOverrides(orgId, contextId) {
43538
+ return this.db.selectFrom("context_source_overrides").selectAll().where("org_id", "=", orgId).where("context_id", "=", contextId).orderBy("routing_key", "asc").orderBy("key", "asc").execute();
43539
+ }
43536
43540
  /** Upsert a source override. */
43537
43541
  async setSourceOverride(orgId, contextId, routingKey, key, value) {
43538
43542
  await this.db.insertInto("context_source_overrides").values({
@@ -43596,6 +43600,12 @@ var init_variable_store = __esmMin((() => {
43596
43600
  * GET /api/v1/admin/contexts/:name/variables?orgId=<id> — list org-level variables
43597
43601
  * PUT /api/v1/admin/contexts/:name/variables/:key?orgId=<id> — upsert variable
43598
43602
  * DELETE /api/v1/admin/contexts/:name/variables/:key?orgId=<id> — delete variable
43603
+ * GET /api/v1/admin/contexts/:name/source-overrides?orgId=<id>[&routingKey=<k>]
43604
+ * — list per-source overrides
43605
+ * PUT /api/v1/admin/contexts/:name/source-overrides/:routingKey/:key?orgId=<id>
43606
+ * — upsert a source override
43607
+ * DELETE /api/v1/admin/contexts/:name/source-overrides/:routingKey/:key?orgId=<id>
43608
+ * — delete a source override
43599
43609
  *
43600
43610
  * Backs the `kici-admin context` dual-mode CLI. Offline (direct-DB) mode
43601
43611
  * bypasses this router entirely — the CLI calls `*Direct` helpers from
@@ -43925,13 +43935,86 @@ function createAdminContextRoutes(deps) {
43925
43935
  return handleError$5(c, err);
43926
43936
  }
43927
43937
  });
43938
+ registerSourceOverrideRoutes(app, deps, envStore, variableStore);
43928
43939
  return app;
43929
43940
  }
43941
+ /**
43942
+ * Per-source variable overrides — the operator path for the dashboard's
43943
+ * `contexts.source_overrides.*` writes. The context is addressed by name with
43944
+ * `?orgId=`, like the variable routes; the stores key it by id.
43945
+ */
43946
+ function registerSourceOverrideRoutes(app, deps, envStore, variableStore) {
43947
+ app.get("/contexts/:name/source-overrides", async (c) => {
43948
+ try {
43949
+ deps.rbac.requirePermission(c.get("role"), "secret.read");
43950
+ const orgId = c.req.query("orgId");
43951
+ const routingKey = c.req.query("routingKey");
43952
+ const name = c.req.param("name");
43953
+ if (!orgId) return c.json({ error: "orgId required" }, 400);
43954
+ const env = await envStore.getByName(orgId, name);
43955
+ if (!env) return c.json({ error: `context not found (org=${orgId}, name=${name})` }, 404);
43956
+ const overrides = routingKey ? await variableStore.listSourceOverrides(orgId, env.id, routingKey) : await variableStore.listAllSourceOverrides(orgId, env.id);
43957
+ return c.json({ overrides: overrides.map((o) => ({
43958
+ routing_key: o.routing_key,
43959
+ key: o.key,
43960
+ value: o.value,
43961
+ updated_at: o.updated_at
43962
+ })) });
43963
+ } catch (err) {
43964
+ return handleError$5(c, err);
43965
+ }
43966
+ });
43967
+ app.put("/contexts/:name/source-overrides/:routingKey/:key", async (c) => {
43968
+ try {
43969
+ deps.rbac.requirePermission(c.get("role"), "secret.write");
43970
+ const body = setSourceOverrideSchema.parse(await c.req.json());
43971
+ const orgId = c.req.query("orgId");
43972
+ const name = c.req.param("name");
43973
+ const routingKey = c.req.param("routingKey");
43974
+ const key = c.req.param("key");
43975
+ if (!orgId) return c.json({ error: "orgId required" }, 400);
43976
+ const env = await envStore.getByName(orgId, name);
43977
+ if (!env) return c.json({ error: `context not found (org=${orgId}, name=${name})` }, 404);
43978
+ await variableStore.setSourceOverride(orgId, env.id, routingKey, key, body.value);
43979
+ logger$90.info("context source override set", {
43980
+ orgId,
43981
+ context: name,
43982
+ routingKey,
43983
+ key
43984
+ });
43985
+ return c.json({ set: true });
43986
+ } catch (err) {
43987
+ return handleError$5(c, err);
43988
+ }
43989
+ });
43990
+ app.delete("/contexts/:name/source-overrides/:routingKey/:key", async (c) => {
43991
+ try {
43992
+ deps.rbac.requirePermission(c.get("role"), "secret.delete");
43993
+ const orgId = c.req.query("orgId");
43994
+ const name = c.req.param("name");
43995
+ const routingKey = c.req.param("routingKey");
43996
+ const key = c.req.param("key");
43997
+ if (!orgId) return c.json({ error: "orgId required" }, 400);
43998
+ const env = await envStore.getByName(orgId, name);
43999
+ if (!env) return c.json({ error: `context not found (org=${orgId}, name=${name})` }, 404);
44000
+ await variableStore.deleteSourceOverride(orgId, env.id, routingKey, key);
44001
+ logger$90.info("context source override deleted", {
44002
+ orgId,
44003
+ context: name,
44004
+ routingKey,
44005
+ key
44006
+ });
44007
+ return c.json({ deleted: true });
44008
+ } catch (err) {
44009
+ return handleError$5(c, err);
44010
+ }
44011
+ });
44012
+ }
43930
44013
  function handleError$5(c, err) {
43931
44014
  logger$90.error("admin-contexts route failed", { error: toErrorMessage(err) });
43932
44015
  return handleAdminError(c, err, logger$90);
43933
44016
  }
43934
- var logger$90, repoPatternsSchema, createContextSchema, bindSchema, setPolicySchema, createTemplateSchema, setVariableSchema;
44017
+ var logger$90, repoPatternsSchema, createContextSchema, bindSchema, setPolicySchema, createTemplateSchema, setVariableSchema, setSourceOverrideSchema;
43935
44018
  var init_admin_contexts = __esmMin((() => {
43936
44019
  init_context_store();
43937
44020
  init_binding_store();
@@ -43987,6 +44070,7 @@ var init_admin_contexts = __esmMin((() => {
43987
44070
  value: z.string(),
43988
44071
  locked: z.boolean().optional()
43989
44072
  });
44073
+ setSourceOverrideSchema = z.object({ value: z.string() });
43990
44074
  }));
43991
44075
  //#endregion
43992
44076
  //#region src/routes/admin-queue-execution.ts
@@ -44424,6 +44508,18 @@ function createAdminRoutes(deps) {
44424
44508
  if (scopeError) return c.json({ error: scopeError }, 400);
44425
44509
  if (!resolved.store.createScope) return c.json({ error: `Backend '${resolved.backendName}' does not support scope creation` }, 400);
44426
44510
  await resolved.store.createScope(parsed.orgId, resolved.path);
44511
+ await deps.auditLogger.log({
44512
+ action: "createScope",
44513
+ contextName: parsed.scope,
44514
+ routingKey: null,
44515
+ secretKeys: null,
44516
+ outcome: "allowed",
44517
+ runId: null,
44518
+ jobId: null,
44519
+ userId: c.get("userId"),
44520
+ role: c.get("role"),
44521
+ metadata: { orgId: parsed.orgId }
44522
+ });
44427
44523
  return c.json({ created: true }, 200);
44428
44524
  } catch (err) {
44429
44525
  return handleError$3(c, err);
@@ -44448,6 +44544,21 @@ function createAdminRoutes(deps) {
44448
44544
  if (scopeError) return c.json({ error: scopeError }, 400);
44449
44545
  if (!from.store.renameScope) return c.json({ error: `Backend '${from.backendName}' does not support scope rename` }, 400);
44450
44546
  await from.store.renameScope(parsed.orgId, from.path, to.path);
44547
+ await deps.auditLogger.log({
44548
+ action: "renameScope",
44549
+ contextName: parsed.oldScope,
44550
+ routingKey: null,
44551
+ secretKeys: null,
44552
+ outcome: "allowed",
44553
+ runId: null,
44554
+ jobId: null,
44555
+ userId: c.get("userId"),
44556
+ role: c.get("role"),
44557
+ metadata: {
44558
+ orgId: parsed.orgId,
44559
+ newScope: parsed.newScope
44560
+ }
44561
+ });
44451
44562
  return c.json({ renamed: true }, 200);
44452
44563
  } catch (err) {
44453
44564
  return handleError$3(c, err);
@@ -44463,6 +44574,18 @@ function createAdminRoutes(deps) {
44463
44574
  const resolved = await routeScope(scope);
44464
44575
  if (!resolved.store.deleteScope) return c.json({ error: `Backend '${resolved.backendName}' does not support scope deletion` }, 400);
44465
44576
  await resolved.store.deleteScope(orgId, resolved.path);
44577
+ await deps.auditLogger.log({
44578
+ action: "deleteScope",
44579
+ contextName: scope,
44580
+ routingKey: null,
44581
+ secretKeys: null,
44582
+ outcome: "allowed",
44583
+ runId: null,
44584
+ jobId: null,
44585
+ userId: c.get("userId"),
44586
+ role: c.get("role"),
44587
+ metadata: { orgId }
44588
+ });
44466
44589
  return c.json({ deleted: true }, 200);
44467
44590
  } catch (err) {
44468
44591
  return handleError$3(c, err);
@@ -46897,8 +47020,8 @@ var init_satisfiability = __esmMin((() => {
46897
47020
  /**
46898
47021
  * Admin API routes for workflow registration management.
46899
47022
  *
46900
- * Provides endpoints for listing, inspecting, refreshing, and deleting
46901
- * workflow registrations. All routes are protected by Bearer token
47023
+ * Provides endpoints for listing, inspecting, refreshing, disabling and
47024
+ * deleting workflow registrations. All routes are protected by Bearer token
46902
47025
  * authentication via the existing admin auth middleware pattern.
46903
47026
  */
46904
47027
  /**
@@ -47031,6 +47154,31 @@ function createAdminRegistrationRoutes(deps) {
47031
47154
  return handleError$1(c, err);
47032
47155
  }
47033
47156
  });
47157
+ app.patch("/api/v1/admin/registrations/:id/disable", async (c) => {
47158
+ try {
47159
+ deps.rbac.requirePermission(c.get("role"), "context.update");
47160
+ const id = c.req.param("id");
47161
+ const parsed = disableSchema.parse(await c.req.json());
47162
+ const existing = await deps.registrationStore.getById(id);
47163
+ if (!existing) return c.json({ error: "Registration not found" }, 404);
47164
+ const denied = enforceRoutingKeyScope(c, existing.routing_key);
47165
+ if (denied) return denied;
47166
+ if (!await deps.registrationStore.setDisabled(id, parsed.disabled)) return c.json({ error: "Registration not found" }, 404);
47167
+ const registryVersion = await deps.registrationStore.bumpVersion();
47168
+ await deps.registrationIndex.refreshIfNeeded(registryVersion);
47169
+ logger$82.info("Registration disabled flag set", {
47170
+ id,
47171
+ disabled: parsed.disabled,
47172
+ registryVersion
47173
+ });
47174
+ return c.json({
47175
+ disabled: parsed.disabled,
47176
+ registryVersion
47177
+ }, 200);
47178
+ } catch (err) {
47179
+ return handleError$1(c, err);
47180
+ }
47181
+ });
47034
47182
  app.delete("/api/v1/admin/registrations/:id", async (c) => {
47035
47183
  try {
47036
47184
  deps.rbac.requirePermission(c.get("role"), "context.delete");
@@ -47059,7 +47207,7 @@ function createAdminRegistrationRoutes(deps) {
47059
47207
  function handleError$1(c, err) {
47060
47208
  return handleAdminError(c, err, logger$82);
47061
47209
  }
47062
- var logger$82, refreshSchema, registerManualSchema;
47210
+ var logger$82, refreshSchema, disableSchema, registerManualSchema;
47063
47211
  var init_admin_registrations = __esmMin((() => {
47064
47212
  init_context_store();
47065
47213
  init_satisfiability();
@@ -47071,6 +47219,7 @@ var init_admin_registrations = __esmMin((() => {
47071
47219
  routingKey: z.string().min(1),
47072
47220
  repoIdentifier: z.string().min(1)
47073
47221
  });
47222
+ disableSchema = z.object({ disabled: z.boolean() });
47074
47223
  registerManualSchema = z.object({
47075
47224
  lockFileContents: z.string().min(1),
47076
47225
  repoIdentifier: z.string().min(1),
@@ -49272,14 +49421,14 @@ var init_admin_config = __esmMin((() => {
49272
49421
  function createHealthRoutes$1(deps = {}) {
49273
49422
  return createHealthRoutes({
49274
49423
  livenessInfo: () => ({
49275
- version: "0.10.0",
49276
- buildDate: "2026-09-25T02:21:19.808Z",
49277
- buildCommit: "4a01d4919",
49278
- sdkVersion: "0.10.0",
49424
+ version: "0.11.0",
49425
+ buildDate: "2026-09-25T15:27:17.455Z",
49426
+ buildCommit: "399bc9f6b",
49427
+ sdkVersion: "0.11.0",
49279
49428
  sdkBundleHash: "b012bd8bace3df9e574252bf290c652bc39766da617acf51729a08586756266d",
49280
- sharedVersion: "0.10.0",
49429
+ sharedVersion: "0.11.0",
49281
49430
  sharedBundleHash: "c43dafa78ecdfdff530b94f7f0629d297ce9d9ed71b06b3cb893db87b00aaea7",
49282
- engineVersion: "0.10.0",
49431
+ engineVersion: "0.11.0",
49283
49432
  engineBundleHash: "0253acfa2150e263bde9698a0d8e95950cd1d94d95ae5ac3b94180bd9f139d0a"
49284
49433
  }),
49285
49434
  readinessCheck: deps.db ? async () => {
@@ -49315,7 +49464,7 @@ function createCapabilitiesRoutes() {
49315
49464
  const app = new Hono();
49316
49465
  app.get("/api/v1/capabilities", (c) => {
49317
49466
  const manifest = {
49318
- orchestratorVersion: "0.10.0",
49467
+ orchestratorVersion: "0.11.0",
49319
49468
  protocolVersion: PROTOCOL_VERSION,
49320
49469
  minProtocolVersion: MIN_PROTOCOL_VERSION
49321
49470
  };
@@ -60311,7 +60460,7 @@ var init_app = __esmMin((() => {
60311
60460
  init_log_chunk_sink();
60312
60461
  init_agent_metrics_aggregator();
60313
60462
  logger$59 = createLogger({ prefix: "app" });
60314
- ORCHESTRATOR_VERSION$2 = "0.10.0";
60463
+ ORCHESTRATOR_VERSION$2 = "0.11.0";
60315
60464
  SourceLocationStore = class {
60316
60465
  cache = /* @__PURE__ */ new Map();
60317
60466
  key(workflowName, jobName) {
@@ -68650,7 +68799,7 @@ var logger$45, SOFTWARE_VERSION$1, PeerClient$1;
68650
68799
  var init_peer_client = __esmMin((() => {
68651
68800
  init_peer_crypto();
68652
68801
  logger$45 = createLogger({ prefix: "peer-client" });
68653
- SOFTWARE_VERSION$1 = "0.10.0";
68802
+ SOFTWARE_VERSION$1 = "0.11.0";
68654
68803
  PeerClient$1 = class {
68655
68804
  ws = null;
68656
68805
  _state = "disconnected";
@@ -70664,7 +70813,7 @@ var init_peer_handler = __esmMin((() => {
70664
70813
  init_peer_crypto();
70665
70814
  init_join_token();
70666
70815
  logger$43 = createLogger({ prefix: "peer-handler" });
70667
- SOFTWARE_VERSION = "0.10.0";
70816
+ SOFTWARE_VERSION = "0.11.0";
70668
70817
  RATE_LIMIT_MAX = 5;
70669
70818
  RATE_LIMIT_WINDOW_MS = 6e4;
70670
70819
  }));
@@ -73079,7 +73228,7 @@ var init_audit_logger = __esmMin((() => {
73079
73228
  * engine's `shouldRecordSecretResolve` helper) since they're written
73080
73229
  * once per JOB-step secret resolution and dwarf every other action's
73081
73230
  * volume. Denied resolves and every other action (`setSecret`,
73082
- * `deleteSecret`, `rotateKey`, `secret-outputs.reveal`) bypass the
73231
+ * `deleteSecret`, the scope writes, `rotateKey`, `secret-outputs.reveal`) bypass the
73083
73232
  * sampler — they are transactional with the mutation and must always
73084
73233
  * land.
73085
73234
  *
@@ -99595,13 +99744,13 @@ var init_worker_core = __esmMin((() => {
99595
99744
  init_worker_outbox_relay();
99596
99745
  init_reroute_dispatch();
99597
99746
  init_app_on_error();
99598
- ORCHESTRATOR_VERSION$1 = "0.10.0";
99599
- WORKER_BUILD_COMMIT = "4a01d4919";
99600
- WORKER_SDK_VERSION = "0.10.0";
99747
+ ORCHESTRATOR_VERSION$1 = "0.11.0";
99748
+ WORKER_BUILD_COMMIT = "399bc9f6b";
99749
+ WORKER_SDK_VERSION = "0.11.0";
99601
99750
  WORKER_SDK_BUNDLE_HASH = "b012bd8bace3df9e574252bf290c652bc39766da617acf51729a08586756266d";
99602
- WORKER_SHARED_VERSION = "0.10.0";
99751
+ WORKER_SHARED_VERSION = "0.11.0";
99603
99752
  WORKER_SHARED_BUNDLE_HASH = "c43dafa78ecdfdff530b94f7f0629d297ce9d9ed71b06b3cb893db87b00aaea7";
99604
- WORKER_ENGINE_VERSION = "0.10.0";
99753
+ WORKER_ENGINE_VERSION = "0.11.0";
99605
99754
  WORKER_ENGINE_BUNDLE_HASH = "0253acfa2150e263bde9698a0d8e95950cd1d94d95ae5ac3b94180bd9f139d0a";
99606
99755
  logger$2 = createLogger({ prefix: "worker" });
99607
99756
  DRAIN_TIMEOUT_MS = 3e5;
@@ -99629,13 +99778,13 @@ init_processor();
99629
99778
  init_verify_inbound();
99630
99779
  init_ingest_overflow_types();
99631
99780
  init_scope_routing();
99632
- const ORCHESTRATOR_VERSION = "0.10.0";
99633
- const BUILD_COMMIT = "4a01d4919";
99634
- const SDK_VERSION = "0.10.0";
99781
+ const ORCHESTRATOR_VERSION = "0.11.0";
99782
+ const BUILD_COMMIT = "399bc9f6b";
99783
+ const SDK_VERSION = "0.11.0";
99635
99784
  const SDK_BUNDLE_HASH = "b012bd8bace3df9e574252bf290c652bc39766da617acf51729a08586756266d";
99636
- const SHARED_VERSION = "0.10.0";
99785
+ const SHARED_VERSION = "0.11.0";
99637
99786
  const SHARED_BUNDLE_HASH = "c43dafa78ecdfdff530b94f7f0629d297ce9d9ed71b06b3cb893db87b00aaea7";
99638
- const ENGINE_VERSION = "0.10.0";
99787
+ const ENGINE_VERSION = "0.11.0";
99639
99788
  const ENGINE_BUNDLE_HASH = "0253acfa2150e263bde9698a0d8e95950cd1d94d95ae5ac3b94180bd9f139d0a";
99640
99789
  const otelSdk = initTelemetry({
99641
99790
  serviceName: "kici-orchestrator",