@shipfox/api-runners 12.0.0 → 12.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/.turbo/turbo-build.log +4 -4
  2. package/CHANGELOG.md +30 -0
  3. package/dist/config.d.ts +3 -0
  4. package/dist/config.d.ts.map +1 -1
  5. package/dist/config.js +24 -2
  6. package/dist/config.js.map +1 -1
  7. package/dist/core/errors.d.ts +4 -0
  8. package/dist/core/errors.d.ts.map +1 -1
  9. package/dist/core/errors.js +6 -0
  10. package/dist/core/errors.js.map +1 -1
  11. package/dist/core/index.d.ts +1 -1
  12. package/dist/core/index.d.ts.map +1 -1
  13. package/dist/core/index.js +1 -1
  14. package/dist/core/index.js.map +1 -1
  15. package/dist/core/rate-limit.d.ts.map +1 -1
  16. package/dist/core/runner-control-sessions.d.ts.map +1 -1
  17. package/dist/core/runner-control-sessions.js +23 -9
  18. package/dist/core/runner-control-sessions.js.map +1 -1
  19. package/dist/core/runner-instances.d.ts +1 -0
  20. package/dist/core/runner-instances.d.ts.map +1 -1
  21. package/dist/core/runner-instances.js.map +1 -1
  22. package/dist/core/runner-labels.d.ts +11 -0
  23. package/dist/core/runner-labels.d.ts.map +1 -0
  24. package/dist/core/runner-labels.js +41 -0
  25. package/dist/core/runner-labels.js.map +1 -0
  26. package/dist/core/runner-sessions.d.ts.map +1 -1
  27. package/dist/core/runner-sessions.js +5 -1
  28. package/dist/core/runner-sessions.js.map +1 -1
  29. package/dist/db/db.d.ts +64 -64
  30. package/dist/db/ephemeral-registration-tokens.d.ts.map +1 -1
  31. package/dist/db/ephemeral-registration-tokens.js +12 -2
  32. package/dist/db/ephemeral-registration-tokens.js.map +1 -1
  33. package/dist/db/reservations.d.ts.map +1 -1
  34. package/dist/db/reservations.js +15 -5
  35. package/dist/db/reservations.js.map +1 -1
  36. package/dist/db/runner-instances.d.ts +1 -0
  37. package/dist/db/runner-instances.d.ts.map +1 -1
  38. package/dist/db/runner-instances.js +6 -4
  39. package/dist/db/runner-instances.js.map +1 -1
  40. package/dist/db/runner-sessions.d.ts.map +1 -1
  41. package/dist/db/runner-sessions.js +12 -1
  42. package/dist/db/runner-sessions.js.map +1 -1
  43. package/dist/db/schema/admin-command-results.d.ts +1 -1
  44. package/dist/db/schema/ephemeral-registration-tokens.d.ts +1 -1
  45. package/dist/db/schema/manual-registration-tokens.d.ts +1 -1
  46. package/dist/db/schema/outbox.d.ts +1 -1
  47. package/dist/db/schema/pending-job-executions.d.ts +3 -3
  48. package/dist/db/schema/provisioner-capability-snapshots.d.ts +3 -3
  49. package/dist/db/schema/provisioner-tokens.d.ts +2 -2
  50. package/dist/db/schema/rate-limits.d.ts +1 -1
  51. package/dist/db/schema/reservations.d.ts +3 -3
  52. package/dist/db/schema/runner-activation-tokens.d.ts +1 -1
  53. package/dist/db/schema/runner-control-sessions.d.ts +2 -2
  54. package/dist/db/schema/runner-instances.d.ts +4 -4
  55. package/dist/db/schema/runner-instances.d.ts.map +1 -1
  56. package/dist/db/schema/runner-instances.js +1 -0
  57. package/dist/db/schema/runner-instances.js.map +1 -1
  58. package/dist/db/schema/runner-sessions.d.ts +4 -4
  59. package/dist/db/schema/running-job-executions.d.ts +5 -5
  60. package/dist/metrics/index.d.ts +2 -1
  61. package/dist/metrics/index.d.ts.map +1 -1
  62. package/dist/metrics/index.js +1 -1
  63. package/dist/metrics/index.js.map +1 -1
  64. package/dist/metrics/instance.d.ts +13 -8
  65. package/dist/metrics/instance.d.ts.map +1 -1
  66. package/dist/metrics/instance.js +8 -0
  67. package/dist/metrics/instance.js.map +1 -1
  68. package/dist/presentation/dto/admin-provisioner-token.d.ts +1 -1
  69. package/dist/presentation/dto/admin-provisioner-token.d.ts.map +1 -1
  70. package/dist/presentation/dto/admin-runner-instances.d.ts +2 -2
  71. package/dist/presentation/dto/admin-runner-instances.d.ts.map +1 -1
  72. package/dist/presentation/routes/poll-demand.d.ts.map +1 -1
  73. package/dist/presentation/routes/poll-demand.js +12 -6
  74. package/dist/presentation/routes/poll-demand.js.map +1 -1
  75. package/dist/presentation/routes/rate-limit.d.ts.map +1 -1
  76. package/dist/presentation/routes/register.d.ts.map +1 -1
  77. package/dist/presentation/routes/register.js +9 -1
  78. package/dist/presentation/routes/register.js.map +1 -1
  79. package/dist/presentation/routes/report-runner-instances.d.ts.map +1 -1
  80. package/dist/presentation/routes/report-runner-instances.js +1 -0
  81. package/dist/presentation/routes/report-runner-instances.js.map +1 -1
  82. package/dist/tsconfig.test.tsbuildinfo +1 -1
  83. package/drizzle/0004_huge_skreet.sql +1 -0
  84. package/drizzle/meta/0004_snapshot.json +2194 -0
  85. package/drizzle/meta/_journal.json +7 -0
  86. package/package.json +9 -9
  87. package/src/config.test.ts +81 -0
  88. package/src/config.ts +39 -2
  89. package/src/core/errors.ts +9 -0
  90. package/src/core/index.ts +1 -0
  91. package/src/core/runner-control-sessions.test.ts +239 -0
  92. package/src/core/runner-control-sessions.ts +29 -10
  93. package/src/core/runner-instances.ts +1 -0
  94. package/src/core/runner-labels.test.ts +53 -0
  95. package/src/core/runner-labels.ts +51 -0
  96. package/src/core/runner-sessions.test.ts +34 -1
  97. package/src/core/runner-sessions.ts +8 -1
  98. package/src/db/ephemeral-registration-tokens.ts +15 -1
  99. package/src/db/reservations.test.ts +169 -0
  100. package/src/db/reservations.ts +42 -8
  101. package/src/db/runner-instances.test.ts +45 -1
  102. package/src/db/runner-instances.ts +7 -2
  103. package/src/db/runner-sessions.ts +14 -1
  104. package/src/db/schema/runner-instances.ts +3 -0
  105. package/src/metrics/index.ts +2 -0
  106. package/src/metrics/instance.ts +18 -0
  107. package/src/presentation/routes/poll-demand.test.ts +99 -3
  108. package/src/presentation/routes/poll-demand.ts +18 -6
  109. package/src/presentation/routes/register.test.ts +116 -2
  110. package/src/presentation/routes/register.ts +7 -0
  111. package/src/presentation/routes/report-runner-instances.test.ts +33 -0
  112. package/src/presentation/routes/report-runner-instances.ts +1 -0
  113. package/src/presentation/routes/runner-enrollment.test.ts +65 -5
  114. package/src/temporal/activities/maintenance-activities.test.ts +24 -31
  115. package/test/env.ts +1 -0
  116. package/tsconfig.build.tsbuildinfo +1 -1
@@ -1,5 +1,8 @@
1
1
  import { and, asc, eq, gt, inArray, isNull, lt, notExists, or, sql } from 'drizzle-orm';
2
+ import { EmptyRunnerLabelsError } from '#core/errors.js';
3
+ import { sanitizeRunnerLabelsOrThrow } from '#core/runner-labels.js';
2
4
  import { db } from './db.js';
5
+ import { provisionerTokens } from './schema/provisioner-tokens.js';
3
6
  import { runnerActivationTokens } from './schema/runner-activation-tokens.js';
4
7
  import { runnerControlSessions } from './schema/runner-control-sessions.js';
5
8
  import { providerRunners } from './schema/runner-instances.js';
@@ -36,6 +39,14 @@ export async function createRunnerSessionConsumingActivationToken(params) {
36
39
  providerRunnerId: providerRunners.providerRunnerId
37
40
  }).from(runnerActivationTokens).innerJoin(providerRunners, eq(providerRunners.id, runnerActivationTokens.runnerInstanceId)).where(and(eq(runnerActivationTokens.id, params.activationTokenId), isNull(runnerActivationTokens.consumedAt), isNull(runnerActivationTokens.revokedAt), gt(runnerActivationTokens.expiresAt, sql`now()`), isNull(providerRunners.runnerSessionId))).limit(1).for('update');
38
41
  if (!token?.workspaceId || !token.providerRunnerId) throw new Error('Runner activation token is invalid, expired, or has already been used');
42
+ const [provisioner] = await tx.select({
43
+ scope: provisionerTokens.scope
44
+ }).from(provisionerTokens).where(eq(provisionerTokens.id, token.provisionerId)).limit(1);
45
+ const labels = sanitizeRunnerLabelsOrThrow(params.labels, {
46
+ scope: provisioner?.scope ?? 'workspace',
47
+ source: 'activation runner registration'
48
+ });
49
+ if (labels.length === 0) throw new EmptyRunnerLabelsError();
39
50
  const [session] = await tx.insert(runnerSessions).values({
40
51
  workspaceId: token.workspaceId,
41
52
  scope: 'workspace',
@@ -44,7 +55,7 @@ export async function createRunnerSessionConsumingActivationToken(params) {
44
55
  runnerInstanceId: token.runnerInstanceId,
45
56
  provisionerId: token.provisionerId,
46
57
  providerRunnerId: token.providerRunnerId,
47
- labels: params.labels,
58
+ labels,
48
59
  toolCapabilities: params.toolCapabilities ?? null,
49
60
  toolCapabilitiesReportedAt: params.toolCapabilities ? sql`now()` : null,
50
61
  maxClaims: 1,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/db/runner-sessions.ts"],"sourcesContent":["import type {RunnerToolCapabilitiesDto} from '@shipfox/api-runners-dto';\nimport {and, asc, eq, gt, inArray, isNull, lt, notExists, or, sql} from 'drizzle-orm';\nimport type {RunnerSession} from '#core/entities/runner-session.js';\nimport {db} from './db.js';\nimport {runnerActivationTokens} from './schema/runner-activation-tokens.js';\nimport {runnerControlSessions} from './schema/runner-control-sessions.js';\nimport {providerRunners} from './schema/runner-instances.js';\nimport {runnerSessions, toRunnerSession} from './schema/runner-sessions.js';\nimport {runningJobExecutions} from './schema/running-job-executions.js';\n\nexport interface CreateRunnerSessionParams {\n workspaceId: string;\n scope: 'workspace';\n registrationTokenId: string;\n labels: string[];\n toolCapabilities?: RunnerToolCapabilitiesDto | null;\n}\n\nexport async function createRunnerSession(\n params: CreateRunnerSessionParams,\n): Promise<RunnerSession> {\n const rows = await db()\n .insert(runnerSessions)\n .values({\n workspaceId: params.workspaceId,\n scope: params.scope,\n registrationTokenId: params.registrationTokenId,\n registrationTokenKind: 'manual',\n labels: params.labels,\n toolCapabilities: params.toolCapabilities ?? null,\n toolCapabilitiesReportedAt: params.toolCapabilities ? sql`now()` : null,\n maxClaims: null,\n claimsUsed: 0,\n })\n .returning();\n\n const row = rows[0];\n if (!row) throw new Error('Insert returned no rows');\n return toRunnerSession(row);\n}\n\nexport async function getRunnerSessionById(runnerSessionId: string): Promise<RunnerSession | null> {\n const rows = await db()\n .select()\n .from(runnerSessions)\n .where(eq(runnerSessions.id, runnerSessionId))\n .limit(1);\n\n const row = rows[0];\n return row ? toRunnerSession(row) : null;\n}\n\nexport async function createRunnerSessionConsumingActivationToken(params: {\n activationTokenId: string;\n labels: string[];\n toolCapabilities?: RunnerToolCapabilitiesDto | null;\n}) {\n return await db().transaction(async (tx) => {\n const [token] = await tx\n .select({\n id: runnerActivationTokens.id,\n runnerInstanceId: runnerActivationTokens.runnerInstanceId,\n workspaceId: providerRunners.workspaceId,\n provisionerId: providerRunners.provisionerId,\n providerRunnerId: providerRunners.providerRunnerId,\n })\n .from(runnerActivationTokens)\n .innerJoin(providerRunners, eq(providerRunners.id, runnerActivationTokens.runnerInstanceId))\n .where(\n and(\n eq(runnerActivationTokens.id, params.activationTokenId),\n isNull(runnerActivationTokens.consumedAt),\n isNull(runnerActivationTokens.revokedAt),\n gt(runnerActivationTokens.expiresAt, sql`now()`),\n isNull(providerRunners.runnerSessionId),\n ),\n )\n .limit(1)\n .for('update');\n if (!token?.workspaceId || !token.providerRunnerId)\n throw new Error('Runner activation token is invalid, expired, or has already been used');\n const [session] = await tx\n .insert(runnerSessions)\n .values({\n workspaceId: token.workspaceId,\n scope: 'workspace',\n registrationTokenId: token.id,\n registrationTokenKind: 'activation',\n runnerInstanceId: token.runnerInstanceId,\n provisionerId: token.provisionerId,\n providerRunnerId: token.providerRunnerId,\n labels: params.labels,\n toolCapabilities: params.toolCapabilities ?? null,\n toolCapabilitiesReportedAt: params.toolCapabilities ? sql`now()` : null,\n maxClaims: 1,\n claimsUsed: 0,\n })\n .returning();\n if (!session) throw new Error('Runner activation session insert returned no row');\n await tx\n .update(runnerActivationTokens)\n .set({consumedAt: sql`now()`, consumedSessionId: session.id})\n .where(eq(runnerActivationTokens.id, token.id));\n await tx\n .update(providerRunners)\n .set({runnerSessionId: session.id, updatedAt: sql`now()`})\n .where(\n and(\n eq(providerRunners.id, token.runnerInstanceId),\n isNull(providerRunners.runnerSessionId),\n ),\n );\n await tx\n .update(runnerControlSessions)\n .set({closedAt: sql`now()`, closeReason: 'activated'})\n .where(\n and(\n eq(runnerControlSessions.runnerInstanceId, token.runnerInstanceId),\n isNull(runnerControlSessions.closedAt),\n ),\n );\n return toRunnerSession(session);\n });\n}\n\nexport interface DeleteExpiredRunnerSessionsParams {\n manualRetentionDays: number;\n ephemeralRetentionDays: number;\n limit?: number;\n}\n\nexport async function deleteExpiredRunnerSessions(\n params: DeleteExpiredRunnerSessionsParams,\n): Promise<number> {\n const expiredIds = db()\n .select({id: runnerSessions.id})\n .from(runnerSessions)\n .where(\n and(\n or(\n and(\n eq(runnerSessions.registrationTokenKind, 'manual'),\n lt(\n runnerSessions.createdAt,\n sql`now() - (${params.manualRetentionDays} || ' days')::interval`,\n ),\n ),\n and(\n inArray(runnerSessions.registrationTokenKind, ['ephemeral', 'activation']),\n lt(\n runnerSessions.createdAt,\n sql`now() - (${params.ephemeralRetentionDays} || ' days')::interval`,\n ),\n ),\n ),\n notExists(\n db()\n .select({id: runningJobExecutions.id})\n .from(runningJobExecutions)\n .where(eq(runningJobExecutions.runnerSessionId, runnerSessions.id)),\n ),\n ),\n )\n .orderBy(asc(runnerSessions.createdAt), asc(runnerSessions.id))\n .limit(params.limit ?? 1000);\n\n const deleted = await db()\n .delete(runnerSessions)\n .where(inArray(runnerSessions.id, expiredIds))\n .returning({id: runnerSessions.id});\n\n return deleted.length;\n}\n"],"names":["and","asc","eq","gt","inArray","isNull","lt","notExists","or","sql","db","runnerActivationTokens","runnerControlSessions","providerRunners","runnerSessions","toRunnerSession","runningJobExecutions","createRunnerSession","params","rows","insert","values","workspaceId","scope","registrationTokenId","registrationTokenKind","labels","toolCapabilities","toolCapabilitiesReportedAt","maxClaims","claimsUsed","returning","row","Error","getRunnerSessionById","runnerSessionId","select","from","where","id","limit","createRunnerSessionConsumingActivationToken","transaction","tx","token","runnerInstanceId","provisionerId","providerRunnerId","innerJoin","activationTokenId","consumedAt","revokedAt","expiresAt","for","session","update","set","consumedSessionId","updatedAt","closedAt","closeReason","deleteExpiredRunnerSessions","expiredIds","createdAt","manualRetentionDays","ephemeralRetentionDays","orderBy","deleted","delete","length"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/db/runner-sessions.ts"],"sourcesContent":["import type {RunnerToolCapabilitiesDto} from '@shipfox/api-runners-dto';\nimport {and, asc, eq, gt, inArray, isNull, lt, notExists, or, sql} from 'drizzle-orm';\nimport type {RunnerSession} from '#core/entities/runner-session.js';\nimport {EmptyRunnerLabelsError} from '#core/errors.js';\nimport {sanitizeRunnerLabelsOrThrow} from '#core/runner-labels.js';\nimport {db} from './db.js';\nimport {provisionerTokens} from './schema/provisioner-tokens.js';\nimport {runnerActivationTokens} from './schema/runner-activation-tokens.js';\nimport {runnerControlSessions} from './schema/runner-control-sessions.js';\nimport {providerRunners} from './schema/runner-instances.js';\nimport {runnerSessions, toRunnerSession} from './schema/runner-sessions.js';\nimport {runningJobExecutions} from './schema/running-job-executions.js';\n\nexport interface CreateRunnerSessionParams {\n workspaceId: string;\n scope: 'workspace';\n registrationTokenId: string;\n labels: string[];\n toolCapabilities?: RunnerToolCapabilitiesDto | null;\n}\n\nexport async function createRunnerSession(\n params: CreateRunnerSessionParams,\n): Promise<RunnerSession> {\n const rows = await db()\n .insert(runnerSessions)\n .values({\n workspaceId: params.workspaceId,\n scope: params.scope,\n registrationTokenId: params.registrationTokenId,\n registrationTokenKind: 'manual',\n labels: params.labels,\n toolCapabilities: params.toolCapabilities ?? null,\n toolCapabilitiesReportedAt: params.toolCapabilities ? sql`now()` : null,\n maxClaims: null,\n claimsUsed: 0,\n })\n .returning();\n\n const row = rows[0];\n if (!row) throw new Error('Insert returned no rows');\n return toRunnerSession(row);\n}\n\nexport async function getRunnerSessionById(runnerSessionId: string): Promise<RunnerSession | null> {\n const rows = await db()\n .select()\n .from(runnerSessions)\n .where(eq(runnerSessions.id, runnerSessionId))\n .limit(1);\n\n const row = rows[0];\n return row ? toRunnerSession(row) : null;\n}\n\nexport async function createRunnerSessionConsumingActivationToken(params: {\n activationTokenId: string;\n labels: string[];\n toolCapabilities?: RunnerToolCapabilitiesDto | null;\n}) {\n return await db().transaction(async (tx) => {\n const [token] = await tx\n .select({\n id: runnerActivationTokens.id,\n runnerInstanceId: runnerActivationTokens.runnerInstanceId,\n workspaceId: providerRunners.workspaceId,\n provisionerId: providerRunners.provisionerId,\n providerRunnerId: providerRunners.providerRunnerId,\n })\n .from(runnerActivationTokens)\n .innerJoin(providerRunners, eq(providerRunners.id, runnerActivationTokens.runnerInstanceId))\n .where(\n and(\n eq(runnerActivationTokens.id, params.activationTokenId),\n isNull(runnerActivationTokens.consumedAt),\n isNull(runnerActivationTokens.revokedAt),\n gt(runnerActivationTokens.expiresAt, sql`now()`),\n isNull(providerRunners.runnerSessionId),\n ),\n )\n .limit(1)\n .for('update');\n if (!token?.workspaceId || !token.providerRunnerId)\n throw new Error('Runner activation token is invalid, expired, or has already been used');\n const [provisioner] = await tx\n .select({scope: provisionerTokens.scope})\n .from(provisionerTokens)\n .where(eq(provisionerTokens.id, token.provisionerId))\n .limit(1);\n const labels = sanitizeRunnerLabelsOrThrow(params.labels, {\n scope: provisioner?.scope ?? 'workspace',\n source: 'activation runner registration',\n });\n if (labels.length === 0) throw new EmptyRunnerLabelsError();\n const [session] = await tx\n .insert(runnerSessions)\n .values({\n workspaceId: token.workspaceId,\n scope: 'workspace',\n registrationTokenId: token.id,\n registrationTokenKind: 'activation',\n runnerInstanceId: token.runnerInstanceId,\n provisionerId: token.provisionerId,\n providerRunnerId: token.providerRunnerId,\n labels,\n toolCapabilities: params.toolCapabilities ?? null,\n toolCapabilitiesReportedAt: params.toolCapabilities ? sql`now()` : null,\n maxClaims: 1,\n claimsUsed: 0,\n })\n .returning();\n if (!session) throw new Error('Runner activation session insert returned no row');\n await tx\n .update(runnerActivationTokens)\n .set({consumedAt: sql`now()`, consumedSessionId: session.id})\n .where(eq(runnerActivationTokens.id, token.id));\n await tx\n .update(providerRunners)\n .set({runnerSessionId: session.id, updatedAt: sql`now()`})\n .where(\n and(\n eq(providerRunners.id, token.runnerInstanceId),\n isNull(providerRunners.runnerSessionId),\n ),\n );\n await tx\n .update(runnerControlSessions)\n .set({closedAt: sql`now()`, closeReason: 'activated'})\n .where(\n and(\n eq(runnerControlSessions.runnerInstanceId, token.runnerInstanceId),\n isNull(runnerControlSessions.closedAt),\n ),\n );\n return toRunnerSession(session);\n });\n}\n\nexport interface DeleteExpiredRunnerSessionsParams {\n manualRetentionDays: number;\n ephemeralRetentionDays: number;\n limit?: number;\n}\n\nexport async function deleteExpiredRunnerSessions(\n params: DeleteExpiredRunnerSessionsParams,\n): Promise<number> {\n const expiredIds = db()\n .select({id: runnerSessions.id})\n .from(runnerSessions)\n .where(\n and(\n or(\n and(\n eq(runnerSessions.registrationTokenKind, 'manual'),\n lt(\n runnerSessions.createdAt,\n sql`now() - (${params.manualRetentionDays} || ' days')::interval`,\n ),\n ),\n and(\n inArray(runnerSessions.registrationTokenKind, ['ephemeral', 'activation']),\n lt(\n runnerSessions.createdAt,\n sql`now() - (${params.ephemeralRetentionDays} || ' days')::interval`,\n ),\n ),\n ),\n notExists(\n db()\n .select({id: runningJobExecutions.id})\n .from(runningJobExecutions)\n .where(eq(runningJobExecutions.runnerSessionId, runnerSessions.id)),\n ),\n ),\n )\n .orderBy(asc(runnerSessions.createdAt), asc(runnerSessions.id))\n .limit(params.limit ?? 1000);\n\n const deleted = await db()\n .delete(runnerSessions)\n .where(inArray(runnerSessions.id, expiredIds))\n .returning({id: runnerSessions.id});\n\n return deleted.length;\n}\n"],"names":["and","asc","eq","gt","inArray","isNull","lt","notExists","or","sql","EmptyRunnerLabelsError","sanitizeRunnerLabelsOrThrow","db","provisionerTokens","runnerActivationTokens","runnerControlSessions","providerRunners","runnerSessions","toRunnerSession","runningJobExecutions","createRunnerSession","params","rows","insert","values","workspaceId","scope","registrationTokenId","registrationTokenKind","labels","toolCapabilities","toolCapabilitiesReportedAt","maxClaims","claimsUsed","returning","row","Error","getRunnerSessionById","runnerSessionId","select","from","where","id","limit","createRunnerSessionConsumingActivationToken","transaction","tx","token","runnerInstanceId","provisionerId","providerRunnerId","innerJoin","activationTokenId","consumedAt","revokedAt","expiresAt","for","provisioner","source","length","session","update","set","consumedSessionId","updatedAt","closedAt","closeReason","deleteExpiredRunnerSessions","expiredIds","createdAt","manualRetentionDays","ephemeralRetentionDays","orderBy","deleted","delete"],"mappings":"AACA,SAAQA,GAAG,EAAEC,GAAG,EAAEC,EAAE,EAAEC,EAAE,EAAEC,OAAO,EAAEC,MAAM,EAAEC,EAAE,EAAEC,SAAS,EAAEC,EAAE,EAAEC,GAAG,QAAO,cAAc;AAEtF,SAAQC,sBAAsB,QAAO,kBAAkB;AACvD,SAAQC,2BAA2B,QAAO,yBAAyB;AACnE,SAAQC,EAAE,QAAO,UAAU;AAC3B,SAAQC,iBAAiB,QAAO,iCAAiC;AACjE,SAAQC,sBAAsB,QAAO,uCAAuC;AAC5E,SAAQC,qBAAqB,QAAO,sCAAsC;AAC1E,SAAQC,eAAe,QAAO,+BAA+B;AAC7D,SAAQC,cAAc,EAAEC,eAAe,QAAO,8BAA8B;AAC5E,SAAQC,oBAAoB,QAAO,qCAAqC;AAUxE,OAAO,eAAeC,oBACpBC,MAAiC;IAEjC,MAAMC,OAAO,MAAMV,KAChBW,MAAM,CAACN,gBACPO,MAAM,CAAC;QACNC,aAAaJ,OAAOI,WAAW;QAC/BC,OAAOL,OAAOK,KAAK;QACnBC,qBAAqBN,OAAOM,mBAAmB;QAC/CC,uBAAuB;QACvBC,QAAQR,OAAOQ,MAAM;QACrBC,kBAAkBT,OAAOS,gBAAgB,IAAI;QAC7CC,4BAA4BV,OAAOS,gBAAgB,GAAGrB,GAAG,CAAC,KAAK,CAAC,GAAG;QACnEuB,WAAW;QACXC,YAAY;IACd,GACCC,SAAS;IAEZ,MAAMC,MAAMb,IAAI,CAAC,EAAE;IACnB,IAAI,CAACa,KAAK,MAAM,IAAIC,MAAM;IAC1B,OAAOlB,gBAAgBiB;AACzB;AAEA,OAAO,eAAeE,qBAAqBC,eAAuB;IAChE,MAAMhB,OAAO,MAAMV,KAChB2B,MAAM,GACNC,IAAI,CAACvB,gBACLwB,KAAK,CAACvC,GAAGe,eAAeyB,EAAE,EAAEJ,kBAC5BK,KAAK,CAAC;IAET,MAAMR,MAAMb,IAAI,CAAC,EAAE;IACnB,OAAOa,MAAMjB,gBAAgBiB,OAAO;AACtC;AAEA,OAAO,eAAeS,4CAA4CvB,MAIjE;IACC,OAAO,MAAMT,KAAKiC,WAAW,CAAC,OAAOC;QACnC,MAAM,CAACC,MAAM,GAAG,MAAMD,GACnBP,MAAM,CAAC;YACNG,IAAI5B,uBAAuB4B,EAAE;YAC7BM,kBAAkBlC,uBAAuBkC,gBAAgB;YACzDvB,aAAaT,gBAAgBS,WAAW;YACxCwB,eAAejC,gBAAgBiC,aAAa;YAC5CC,kBAAkBlC,gBAAgBkC,gBAAgB;QACpD,GACCV,IAAI,CAAC1B,wBACLqC,SAAS,CAACnC,iBAAiBd,GAAGc,gBAAgB0B,EAAE,EAAE5B,uBAAuBkC,gBAAgB,GACzFP,KAAK,CACJzC,IACEE,GAAGY,uBAAuB4B,EAAE,EAAErB,OAAO+B,iBAAiB,GACtD/C,OAAOS,uBAAuBuC,UAAU,GACxChD,OAAOS,uBAAuBwC,SAAS,GACvCnD,GAAGW,uBAAuByC,SAAS,EAAE9C,GAAG,CAAC,KAAK,CAAC,GAC/CJ,OAAOW,gBAAgBsB,eAAe,IAGzCK,KAAK,CAAC,GACNa,GAAG,CAAC;QACP,IAAI,CAACT,OAAOtB,eAAe,CAACsB,MAAMG,gBAAgB,EAChD,MAAM,IAAId,MAAM;QAClB,MAAM,CAACqB,YAAY,GAAG,MAAMX,GACzBP,MAAM,CAAC;YAACb,OAAOb,kBAAkBa,KAAK;QAAA,GACtCc,IAAI,CAAC3B,mBACL4B,KAAK,CAACvC,GAAGW,kBAAkB6B,EAAE,EAAEK,MAAME,aAAa,GAClDN,KAAK,CAAC;QACT,MAAMd,SAASlB,4BAA4BU,OAAOQ,MAAM,EAAE;YACxDH,OAAO+B,aAAa/B,SAAS;YAC7BgC,QAAQ;QACV;QACA,IAAI7B,OAAO8B,MAAM,KAAK,GAAG,MAAM,IAAIjD;QACnC,MAAM,CAACkD,QAAQ,GAAG,MAAMd,GACrBvB,MAAM,CAACN,gBACPO,MAAM,CAAC;YACNC,aAAasB,MAAMtB,WAAW;YAC9BC,OAAO;YACPC,qBAAqBoB,MAAML,EAAE;YAC7Bd,uBAAuB;YACvBoB,kBAAkBD,MAAMC,gBAAgB;YACxCC,eAAeF,MAAME,aAAa;YAClCC,kBAAkBH,MAAMG,gBAAgB;YACxCrB;YACAC,kBAAkBT,OAAOS,gBAAgB,IAAI;YAC7CC,4BAA4BV,OAAOS,gBAAgB,GAAGrB,GAAG,CAAC,KAAK,CAAC,GAAG;YACnEuB,WAAW;YACXC,YAAY;QACd,GACCC,SAAS;QACZ,IAAI,CAAC0B,SAAS,MAAM,IAAIxB,MAAM;QAC9B,MAAMU,GACHe,MAAM,CAAC/C,wBACPgD,GAAG,CAAC;YAACT,YAAY5C,GAAG,CAAC,KAAK,CAAC;YAAEsD,mBAAmBH,QAAQlB,EAAE;QAAA,GAC1DD,KAAK,CAACvC,GAAGY,uBAAuB4B,EAAE,EAAEK,MAAML,EAAE;QAC/C,MAAMI,GACHe,MAAM,CAAC7C,iBACP8C,GAAG,CAAC;YAACxB,iBAAiBsB,QAAQlB,EAAE;YAAEsB,WAAWvD,GAAG,CAAC,KAAK,CAAC;QAAA,GACvDgC,KAAK,CACJzC,IACEE,GAAGc,gBAAgB0B,EAAE,EAAEK,MAAMC,gBAAgB,GAC7C3C,OAAOW,gBAAgBsB,eAAe;QAG5C,MAAMQ,GACHe,MAAM,CAAC9C,uBACP+C,GAAG,CAAC;YAACG,UAAUxD,GAAG,CAAC,KAAK,CAAC;YAAEyD,aAAa;QAAW,GACnDzB,KAAK,CACJzC,IACEE,GAAGa,sBAAsBiC,gBAAgB,EAAED,MAAMC,gBAAgB,GACjE3C,OAAOU,sBAAsBkD,QAAQ;QAG3C,OAAO/C,gBAAgB0C;IACzB;AACF;AAQA,OAAO,eAAeO,4BACpB9C,MAAyC;IAEzC,MAAM+C,aAAaxD,KAChB2B,MAAM,CAAC;QAACG,IAAIzB,eAAeyB,EAAE;IAAA,GAC7BF,IAAI,CAACvB,gBACLwB,KAAK,CACJzC,IACEQ,GACER,IACEE,GAAGe,eAAeW,qBAAqB,EAAE,WACzCtB,GACEW,eAAeoD,SAAS,EACxB5D,GAAG,CAAC,SAAS,EAAEY,OAAOiD,mBAAmB,CAAC,sBAAsB,CAAC,IAGrEtE,IACEI,QAAQa,eAAeW,qBAAqB,EAAE;QAAC;QAAa;KAAa,GACzEtB,GACEW,eAAeoD,SAAS,EACxB5D,GAAG,CAAC,SAAS,EAAEY,OAAOkD,sBAAsB,CAAC,sBAAsB,CAAC,KAI1EhE,UACEK,KACG2B,MAAM,CAAC;QAACG,IAAIvB,qBAAqBuB,EAAE;IAAA,GACnCF,IAAI,CAACrB,sBACLsB,KAAK,CAACvC,GAAGiB,qBAAqBmB,eAAe,EAAErB,eAAeyB,EAAE,MAIxE8B,OAAO,CAACvE,IAAIgB,eAAeoD,SAAS,GAAGpE,IAAIgB,eAAeyB,EAAE,GAC5DC,KAAK,CAACtB,OAAOsB,KAAK,IAAI;IAEzB,MAAM8B,UAAU,MAAM7D,KACnB8D,MAAM,CAACzD,gBACPwB,KAAK,CAACrC,QAAQa,eAAeyB,EAAE,EAAE0B,aACjClC,SAAS,CAAC;QAACQ,IAAIzB,eAAeyB,EAAE;IAAA;IAEnC,OAAO+B,QAAQd,MAAM;AACvB"}
@@ -128,7 +128,7 @@ export declare const runnersAdminCommandResults: import("drizzle-orm/pg-core").P
128
128
  generated: undefined;
129
129
  }, {}, {}>;
130
130
  };
131
- dialect: "pg";
131
+ dialect: 'pg';
132
132
  }>;
133
133
  export type RunnersAdminCommandResultDb = typeof runnersAdminCommandResults.$inferSelect;
134
134
  //# sourceMappingURL=admin-command-results.d.ts.map
@@ -191,7 +191,7 @@ export declare const ephemeralRegistrationTokens: import("drizzle-orm/pg-core").
191
191
  generated: undefined;
192
192
  }, {}, {}>;
193
193
  };
194
- dialect: "pg";
194
+ dialect: 'pg';
195
195
  }>;
196
196
  export type EphemeralRegistrationTokenDb = typeof ephemeralRegistrationTokens.$inferSelect;
197
197
  export type EphemeralRegistrationTokenInsertDb = typeof ephemeralRegistrationTokens.$inferInsert;
@@ -157,7 +157,7 @@ export declare const manualRegistrationTokens: import("drizzle-orm/pg-core").PgT
157
157
  generated: undefined;
158
158
  }, {}, {}>;
159
159
  };
160
- dialect: "pg";
160
+ dialect: 'pg';
161
161
  }>;
162
162
  export type ManualRegistrationTokenDb = typeof manualRegistrationTokens.$inferSelect;
163
163
  export type ManualRegistrationTokenInsertDb = typeof manualRegistrationTokens.$inferInsert;
@@ -190,6 +190,6 @@ export declare const runnersOutbox: import("drizzle-orm/pg-core").PgTableWithCol
190
190
  generated: undefined;
191
191
  }, {}, {}>;
192
192
  };
193
- dialect: "pg";
193
+ dialect: 'pg';
194
194
  }>;
195
195
  //# sourceMappingURL=outbox.d.ts.map
@@ -156,8 +156,8 @@ export declare const pendingJobExecutions: import("drizzle-orm/pg-core").PgTable
156
156
  }, {}, {
157
157
  baseBuilder: import("drizzle-orm/pg-core").PgColumnBuilder<{
158
158
  name: "required_labels";
159
- dataType: "string";
160
- columnType: "PgText";
159
+ dataType: 'string';
160
+ columnType: 'PgText';
161
161
  data: string;
162
162
  enumValues: [string, ...string[]];
163
163
  driverParam: string;
@@ -182,7 +182,7 @@ export declare const pendingJobExecutions: import("drizzle-orm/pg-core").PgTable
182
182
  generated: undefined;
183
183
  }, {}, {}>;
184
184
  };
185
- dialect: "pg";
185
+ dialect: 'pg';
186
186
  }>;
187
187
  export type PendingJobExecutionDb = typeof pendingJobExecutions.$inferSelect;
188
188
  export type PendingJobExecutionInsertDb = typeof pendingJobExecutions.$inferInsert;
@@ -106,8 +106,8 @@ export declare const provisionerCapabilitySnapshots: import("drizzle-orm/pg-core
106
106
  }, {}, {
107
107
  baseBuilder: import("drizzle-orm/pg-core").PgColumnBuilder<{
108
108
  name: "labels";
109
- dataType: "string";
110
- columnType: "PgText";
109
+ dataType: 'string';
110
+ columnType: 'PgText';
111
111
  data: string;
112
112
  enumValues: [string, ...string[]];
113
113
  driverParam: string;
@@ -200,7 +200,7 @@ export declare const provisionerCapabilitySnapshots: import("drizzle-orm/pg-core
200
200
  generated: undefined;
201
201
  }, {}, {}>;
202
202
  };
203
- dialect: "pg";
203
+ dialect: 'pg';
204
204
  }>;
205
205
  export type ProvisionerCapabilitySnapshotDb = typeof provisionerCapabilitySnapshots.$inferSelect;
206
206
  export declare function toProvisionerCapabilitySnapshot(row: ProvisionerCapabilitySnapshotDb): ProvisionerCapabilitySnapshot;
@@ -26,7 +26,7 @@ export declare const provisionerTokens: import("drizzle-orm/pg-core").PgTableWit
26
26
  tableName: "provisioner_tokens";
27
27
  dataType: "string";
28
28
  columnType: "PgEnumColumn";
29
- data: "workspace" | "installation";
29
+ data: "installation" | "workspace";
30
30
  driverParam: string;
31
31
  notNull: true;
32
32
  hasDefault: false;
@@ -226,7 +226,7 @@ export declare const provisionerTokens: import("drizzle-orm/pg-core").PgTableWit
226
226
  generated: undefined;
227
227
  }, {}, {}>;
228
228
  };
229
- dialect: "pg";
229
+ dialect: 'pg';
230
230
  }>;
231
231
  export type ProvisionerTokenDb = typeof provisionerTokens.$inferSelect;
232
232
  export type ProvisionerTokenInsertDb = typeof provisionerTokens.$inferInsert;
@@ -139,7 +139,7 @@ export declare const runnersRateLimits: import("drizzle-orm/pg-core").PgTableWit
139
139
  generated: undefined;
140
140
  }, {}, {}>;
141
141
  };
142
- dialect: "pg";
142
+ dialect: 'pg';
143
143
  }>;
144
144
  export type RunnersRateLimitDb = typeof runnersRateLimits.$inferSelect;
145
145
  //# sourceMappingURL=rate-limits.d.ts.map
@@ -89,8 +89,8 @@ export declare const reservations: import("drizzle-orm/pg-core").PgTableWithColu
89
89
  }, {}, {
90
90
  baseBuilder: import("drizzle-orm/pg-core").PgColumnBuilder<{
91
91
  name: "required_labels";
92
- dataType: "string";
93
- columnType: "PgText";
92
+ dataType: 'string';
93
+ columnType: 'PgText';
94
94
  data: string;
95
95
  enumValues: [string, ...string[]];
96
96
  driverParam: string;
@@ -149,7 +149,7 @@ export declare const reservations: import("drizzle-orm/pg-core").PgTableWithColu
149
149
  generated: undefined;
150
150
  }, {}, {}>;
151
151
  };
152
- dialect: "pg";
152
+ dialect: 'pg';
153
153
  }>;
154
154
  export type ReservationDb = typeof reservations.$inferSelect;
155
155
  export type ReservationInsertDb = typeof reservations.$inferInsert;
@@ -156,6 +156,6 @@ export declare const runnerActivationTokens: import("drizzle-orm/pg-core").PgTab
156
156
  generated: undefined;
157
157
  }, {}, {}>;
158
158
  };
159
- dialect: "pg";
159
+ dialect: 'pg';
160
160
  }>;
161
161
  //# sourceMappingURL=runner-activation-tokens.d.ts.map
@@ -156,7 +156,7 @@ export declare const runnerBootstrapTokens: import("drizzle-orm/pg-core").PgTabl
156
156
  generated: undefined;
157
157
  }, {}, {}>;
158
158
  };
159
- dialect: "pg";
159
+ dialect: 'pg';
160
160
  }>;
161
161
  export declare const runnerControlSessions: import("drizzle-orm/pg-core").PgTableWithColumns<{
162
162
  name: "runner_control_sessions";
@@ -333,6 +333,6 @@ export declare const runnerControlSessions: import("drizzle-orm/pg-core").PgTabl
333
333
  generated: undefined;
334
334
  }, {}, {}>;
335
335
  };
336
- dialect: "pg";
336
+ dialect: 'pg';
337
337
  }>;
338
338
  //# sourceMappingURL=runner-control-sessions.d.ts.map
@@ -175,8 +175,8 @@ export declare const providerRunners: import("drizzle-orm/pg-core").PgTableWithC
175
175
  }, {}, {
176
176
  baseBuilder: import("drizzle-orm/pg-core").PgColumnBuilder<{
177
177
  name: "labels";
178
- dataType: "string";
179
- columnType: "PgText";
178
+ dataType: 'string';
179
+ columnType: 'PgText';
180
180
  data: string;
181
181
  enumValues: [string, ...string[]];
182
182
  driverParam: string;
@@ -188,7 +188,7 @@ export declare const providerRunners: import("drizzle-orm/pg-core").PgTableWithC
188
188
  tableName: "runner_instances";
189
189
  dataType: "string";
190
190
  columnType: "PgEnumColumn";
191
- data: "starting" | "running" | "stopping" | "stopped" | "failed" | "terminated";
191
+ data: "failed" | "running" | "starting" | "stopped" | "stopping" | "terminated";
192
192
  driverParam: string;
193
193
  notNull: true;
194
194
  hasDefault: false;
@@ -476,7 +476,7 @@ export declare const providerRunners: import("drizzle-orm/pg-core").PgTableWithC
476
476
  generated: undefined;
477
477
  }, {}, {}>;
478
478
  };
479
- dialect: "pg";
479
+ dialect: 'pg';
480
480
  }>;
481
481
  export type RunnerInstanceDb = typeof providerRunners.$inferSelect;
482
482
  export type RunnerInstanceInsertDb = typeof providerRunners.$inferInsert;
@@ -1 +1 @@
1
- {"version":3,"file":"runner-instances.d.ts","sourceRoot":"","sources":["../../../src/db/schema/runner-instances.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,mCAAmC,CAAC;AAGtE,eAAO,MAAM,uBAAuB,8GAOlC,CAAC;AAEH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqD3B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,OAAO,eAAe,CAAC,YAAY,CAAC;AACnE,MAAM,MAAM,sBAAsB,GAAG,OAAO,eAAe,CAAC,YAAY,CAAC;AAEzE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,gBAAgB,GAAG,cAAc,CAyBtE"}
1
+ {"version":3,"file":"runner-instances.d.ts","sourceRoot":"","sources":["../../../src/db/schema/runner-instances.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,mCAAmC,CAAC;AAGtE,eAAO,MAAM,uBAAuB,8GAOlC,CAAC;AAEH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwD3B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,OAAO,eAAe,CAAC,YAAY,CAAC;AACnE,MAAM,MAAM,sBAAsB,GAAG,OAAO,eAAe,CAAC,YAAY,CAAC;AAEzE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,gBAAgB,GAAG,cAAc,CAyBtE"}
@@ -65,6 +65,7 @@ export const providerRunners = pgTable('runner_instances', {
65
65
  index('runners_runner_instances_workspace_state_updated_idx').on(table.state, table.updatedAt),
66
66
  index('runners_runner_instances_stale_reaper_idx').on(table.state, table.updatedAt, table.reportedAt),
67
67
  index('runners_runner_instances_provisioner_intended_reservation_idx').on(table.provisionerId, table.intendedReservationId).where(sql`${table.intendedReservationId} is not null and ${table.reservationReleasedAt} is null`),
68
+ index('runners_runner_instances_intended_reservation_idx').on(table.intendedReservationId).where(sql`${table.intendedReservationId} is not null`),
68
69
  index('runners_runner_instances_provisioner_reservation_idx').on(table.provisionerId, table.reservationId).where(sql`${table.reservationId} is not null`),
69
70
  index('runners_runner_instances_active_template_counts_idx').on(table.provisionerId, table.state, table.templateKey).where(sql`"state" in ('starting', 'running') and "template_key" is not null`)
70
71
  ]);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/db/schema/runner-instances.ts"],"sourcesContent":["import type {RunnerToolCapabilitiesDto} from '@shipfox/api-runners-dto';\nimport {uuidv7PrimaryKey} from '@shipfox/node-drizzle';\nimport {sql} from 'drizzle-orm';\nimport {index, jsonb, pgEnum, text, timestamp, uniqueIndex, uuid} from 'drizzle-orm/pg-core';\nimport type {RunnerInstance} from '#core/entities/runner-instance.js';\nimport {pgTable} from './common.js';\n\nexport const providerRunnerStateEnum = pgEnum('runners_provider_runner_state', [\n 'starting',\n 'running',\n 'stopping',\n 'stopped',\n 'failed',\n 'terminated',\n]);\n\nexport const providerRunners = pgTable(\n 'runner_instances',\n {\n id: uuidv7PrimaryKey(),\n // Kept during the protocol migration for legacy workspace capacity. New capacity is owned\n // only by its provisioner and has no workspace assignment.\n workspaceId: uuid('workspace_id'),\n provisionerId: uuid('provisioner_id').notNull(),\n providerRunnerId: text('provider_runner_id'),\n intendedReservationId: uuid('intended_reservation_id'),\n reservationId: uuid('reservation_id'),\n assignedAt: timestamp('assigned_at', {withTimezone: true}),\n templateKey: text('template_key'),\n labels: text('labels').array().notNull().default([]),\n state: providerRunnerStateEnum('state').notNull(),\n reason: text('reason'),\n runnerSessionId: uuid('runner_session_id'),\n firstClaimedAt: timestamp('first_claimed_at', {withTimezone: true}),\n providerKind: text('provider_kind'),\n protocolVersion: text('protocol_version'),\n capabilities: jsonb('capabilities').$type<RunnerToolCapabilitiesDto | null>(),\n reportedAt: timestamp('reported_at', {withTimezone: true}).notNull(),\n startedAt: timestamp('started_at', {withTimezone: true}),\n stoppingAt: timestamp('stopping_at', {withTimezone: true}),\n stoppedAt: timestamp('stopped_at', {withTimezone: true}),\n failedAt: timestamp('failed_at', {withTimezone: true}),\n terminatedAt: timestamp('terminated_at', {withTimezone: true}),\n reservationReleasedAt: timestamp('reservation_released_at', {withTimezone: true}),\n createdAt: timestamp('created_at', {withTimezone: true}).notNull().defaultNow(),\n updatedAt: timestamp('updated_at', {withTimezone: true}).notNull().defaultNow(),\n },\n (table) => [\n uniqueIndex('runners_runner_instances_provisioner_runner_unique')\n .on(table.provisionerId, table.providerRunnerId)\n .where(sql`${table.providerRunnerId} is not null`),\n index('runners_runner_instances_workspace_state_updated_idx').on(table.state, table.updatedAt),\n index('runners_runner_instances_stale_reaper_idx').on(\n table.state,\n table.updatedAt,\n table.reportedAt,\n ),\n index('runners_runner_instances_provisioner_intended_reservation_idx')\n .on(table.provisionerId, table.intendedReservationId)\n .where(\n sql`${table.intendedReservationId} is not null and ${table.reservationReleasedAt} is null`,\n ),\n index('runners_runner_instances_provisioner_reservation_idx')\n .on(table.provisionerId, table.reservationId)\n .where(sql`${table.reservationId} is not null`),\n index('runners_runner_instances_active_template_counts_idx')\n .on(table.provisionerId, table.state, table.templateKey)\n .where(sql`\"state\" in ('starting', 'running') and \"template_key\" is not null`),\n ],\n);\n\nexport type RunnerInstanceDb = typeof providerRunners.$inferSelect;\nexport type RunnerInstanceInsertDb = typeof providerRunners.$inferInsert;\n\nexport function toRunnerInstance(row: RunnerInstanceDb): RunnerInstance {\n if (!row.providerRunnerId) throw new Error('Runner instance has no provider runner identity');\n return {\n id: row.id,\n workspaceId: row.workspaceId,\n provisionerId: row.provisionerId,\n providerRunnerId: row.providerRunnerId,\n reservationId: row.reservationId,\n assignedAt: row.assignedAt,\n templateKey: row.templateKey,\n labels: row.labels,\n state: row.state,\n reason: row.reason,\n runnerSessionId: row.runnerSessionId,\n providerKind: row.providerKind,\n reportedAt: row.reportedAt,\n startedAt: row.startedAt,\n stoppingAt: row.stoppingAt,\n stoppedAt: row.stoppedAt,\n failedAt: row.failedAt,\n terminatedAt: row.terminatedAt,\n reservationReleasedAt: row.reservationReleasedAt,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n"],"names":["uuidv7PrimaryKey","sql","index","jsonb","pgEnum","text","timestamp","uniqueIndex","uuid","pgTable","providerRunnerStateEnum","providerRunners","id","workspaceId","provisionerId","notNull","providerRunnerId","intendedReservationId","reservationId","assignedAt","withTimezone","templateKey","labels","array","default","state","reason","runnerSessionId","firstClaimedAt","providerKind","protocolVersion","capabilities","$type","reportedAt","startedAt","stoppingAt","stoppedAt","failedAt","terminatedAt","reservationReleasedAt","createdAt","defaultNow","updatedAt","table","on","where","toRunnerInstance","row","Error"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/db/schema/runner-instances.ts"],"sourcesContent":["import type {RunnerToolCapabilitiesDto} from '@shipfox/api-runners-dto';\nimport {uuidv7PrimaryKey} from '@shipfox/node-drizzle';\nimport {sql} from 'drizzle-orm';\nimport {index, jsonb, pgEnum, text, timestamp, uniqueIndex, uuid} from 'drizzle-orm/pg-core';\nimport type {RunnerInstance} from '#core/entities/runner-instance.js';\nimport {pgTable} from './common.js';\n\nexport const providerRunnerStateEnum = pgEnum('runners_provider_runner_state', [\n 'starting',\n 'running',\n 'stopping',\n 'stopped',\n 'failed',\n 'terminated',\n]);\n\nexport const providerRunners = pgTable(\n 'runner_instances',\n {\n id: uuidv7PrimaryKey(),\n // Kept during the protocol migration for legacy workspace capacity. New capacity is owned\n // only by its provisioner and has no workspace assignment.\n workspaceId: uuid('workspace_id'),\n provisionerId: uuid('provisioner_id').notNull(),\n providerRunnerId: text('provider_runner_id'),\n intendedReservationId: uuid('intended_reservation_id'),\n reservationId: uuid('reservation_id'),\n assignedAt: timestamp('assigned_at', {withTimezone: true}),\n templateKey: text('template_key'),\n labels: text('labels').array().notNull().default([]),\n state: providerRunnerStateEnum('state').notNull(),\n reason: text('reason'),\n runnerSessionId: uuid('runner_session_id'),\n firstClaimedAt: timestamp('first_claimed_at', {withTimezone: true}),\n providerKind: text('provider_kind'),\n protocolVersion: text('protocol_version'),\n capabilities: jsonb('capabilities').$type<RunnerToolCapabilitiesDto | null>(),\n reportedAt: timestamp('reported_at', {withTimezone: true}).notNull(),\n startedAt: timestamp('started_at', {withTimezone: true}),\n stoppingAt: timestamp('stopping_at', {withTimezone: true}),\n stoppedAt: timestamp('stopped_at', {withTimezone: true}),\n failedAt: timestamp('failed_at', {withTimezone: true}),\n terminatedAt: timestamp('terminated_at', {withTimezone: true}),\n reservationReleasedAt: timestamp('reservation_released_at', {withTimezone: true}),\n createdAt: timestamp('created_at', {withTimezone: true}).notNull().defaultNow(),\n updatedAt: timestamp('updated_at', {withTimezone: true}).notNull().defaultNow(),\n },\n (table) => [\n uniqueIndex('runners_runner_instances_provisioner_runner_unique')\n .on(table.provisionerId, table.providerRunnerId)\n .where(sql`${table.providerRunnerId} is not null`),\n index('runners_runner_instances_workspace_state_updated_idx').on(table.state, table.updatedAt),\n index('runners_runner_instances_stale_reaper_idx').on(\n table.state,\n table.updatedAt,\n table.reportedAt,\n ),\n index('runners_runner_instances_provisioner_intended_reservation_idx')\n .on(table.provisionerId, table.intendedReservationId)\n .where(\n sql`${table.intendedReservationId} is not null and ${table.reservationReleasedAt} is null`,\n ),\n index('runners_runner_instances_intended_reservation_idx')\n .on(table.intendedReservationId)\n .where(sql`${table.intendedReservationId} is not null`),\n index('runners_runner_instances_provisioner_reservation_idx')\n .on(table.provisionerId, table.reservationId)\n .where(sql`${table.reservationId} is not null`),\n index('runners_runner_instances_active_template_counts_idx')\n .on(table.provisionerId, table.state, table.templateKey)\n .where(sql`\"state\" in ('starting', 'running') and \"template_key\" is not null`),\n ],\n);\n\nexport type RunnerInstanceDb = typeof providerRunners.$inferSelect;\nexport type RunnerInstanceInsertDb = typeof providerRunners.$inferInsert;\n\nexport function toRunnerInstance(row: RunnerInstanceDb): RunnerInstance {\n if (!row.providerRunnerId) throw new Error('Runner instance has no provider runner identity');\n return {\n id: row.id,\n workspaceId: row.workspaceId,\n provisionerId: row.provisionerId,\n providerRunnerId: row.providerRunnerId,\n reservationId: row.reservationId,\n assignedAt: row.assignedAt,\n templateKey: row.templateKey,\n labels: row.labels,\n state: row.state,\n reason: row.reason,\n runnerSessionId: row.runnerSessionId,\n providerKind: row.providerKind,\n reportedAt: row.reportedAt,\n startedAt: row.startedAt,\n stoppingAt: row.stoppingAt,\n stoppedAt: row.stoppedAt,\n failedAt: row.failedAt,\n terminatedAt: row.terminatedAt,\n reservationReleasedAt: row.reservationReleasedAt,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n"],"names":["uuidv7PrimaryKey","sql","index","jsonb","pgEnum","text","timestamp","uniqueIndex","uuid","pgTable","providerRunnerStateEnum","providerRunners","id","workspaceId","provisionerId","notNull","providerRunnerId","intendedReservationId","reservationId","assignedAt","withTimezone","templateKey","labels","array","default","state","reason","runnerSessionId","firstClaimedAt","providerKind","protocolVersion","capabilities","$type","reportedAt","startedAt","stoppingAt","stoppedAt","failedAt","terminatedAt","reservationReleasedAt","createdAt","defaultNow","updatedAt","table","on","where","toRunnerInstance","row","Error"],"mappings":"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"}
@@ -78,7 +78,7 @@ export declare const runnerSessions: import("drizzle-orm/pg-core").PgTableWithCo
78
78
  tableName: "runner_sessions";
79
79
  dataType: "string";
80
80
  columnType: "PgEnumColumn";
81
- data: "manual" | "ephemeral" | "activation";
81
+ data: "activation" | "ephemeral" | "manual";
82
82
  driverParam: string;
83
83
  notNull: true;
84
84
  hasDefault: false;
@@ -176,8 +176,8 @@ export declare const runnerSessions: import("drizzle-orm/pg-core").PgTableWithCo
176
176
  }, {}, {
177
177
  baseBuilder: import("drizzle-orm/pg-core").PgColumnBuilder<{
178
178
  name: "labels";
179
- dataType: "string";
180
- columnType: "PgText";
179
+ dataType: 'string';
180
+ columnType: 'PgText';
181
181
  data: string;
182
182
  enumValues: [string, ...string[]];
183
183
  driverParam: string;
@@ -324,7 +324,7 @@ export declare const runnerSessions: import("drizzle-orm/pg-core").PgTableWithCo
324
324
  generated: undefined;
325
325
  }, {}, {}>;
326
326
  };
327
- dialect: "pg";
327
+ dialect: 'pg';
328
328
  }>;
329
329
  export type RunnerSessionDb = typeof runnerSessions.$inferSelect;
330
330
  export type RunnerSessionInsertDb = typeof runnerSessions.$inferInsert;
@@ -207,8 +207,8 @@ export declare const runningJobExecutions: import("drizzle-orm/pg-core").PgTable
207
207
  }, {}, {
208
208
  baseBuilder: import("drizzle-orm/pg-core").PgColumnBuilder<{
209
209
  name: "required_labels";
210
- dataType: "string";
211
- columnType: "PgText";
210
+ dataType: 'string';
211
+ columnType: 'PgText';
212
212
  data: string;
213
213
  enumValues: [string, ...string[]];
214
214
  driverParam: string;
@@ -250,8 +250,8 @@ export declare const runningJobExecutions: import("drizzle-orm/pg-core").PgTable
250
250
  }, {}, {
251
251
  baseBuilder: import("drizzle-orm/pg-core").PgColumnBuilder<{
252
252
  name: "runner_labels";
253
- dataType: "string";
254
- columnType: "PgText";
253
+ dataType: 'string';
254
+ columnType: 'PgText';
255
255
  data: string;
256
256
  enumValues: [string, ...string[]];
257
257
  driverParam: string;
@@ -327,7 +327,7 @@ export declare const runningJobExecutions: import("drizzle-orm/pg-core").PgTable
327
327
  generated: undefined;
328
328
  }, {}, {}>;
329
329
  };
330
- dialect: "pg";
330
+ dialect: 'pg';
331
331
  }>;
332
332
  export type RunningJobExecutionDb = typeof runningJobExecutions.$inferSelect;
333
333
  export type RunningJobExecutionInsertDb = typeof runningJobExecutions.$inferInsert;
@@ -1,3 +1,4 @@
1
- export { jobExecutionClaimedCount, jobExecutionEnqueuedCount, jobExecutionLeaseExpiredCount, providerRunnerAbsentTerminatedCount, providerRunnerCountDivergenceCount, providerRunnerReconcileCallCount, providerRunnerTerminateIntentHonoredCount, providerRunnerTerminateIntentIssuedCount, recordRunnersRateLimitCheck, recordRunnersRateLimitPruneFailure, } from './instance.js';
1
+ export type { RunnerReservationPromotionFailureReason } from './instance.js';
2
+ export { jobExecutionClaimedCount, jobExecutionEnqueuedCount, jobExecutionLeaseExpiredCount, providerRunnerAbsentTerminatedCount, providerRunnerCountDivergenceCount, providerRunnerReconcileCallCount, providerRunnerTerminateIntentHonoredCount, providerRunnerTerminateIntentIssuedCount, recordRunnerReservationPromotionFailure, recordRunnersRateLimitCheck, recordRunnersRateLimitPruneFailure, } from './instance.js';
2
3
  export { registerRunnersServiceMetrics } from './service.js';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/metrics/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,yBAAyB,EACzB,6BAA6B,EAC7B,mCAAmC,EACnC,kCAAkC,EAClC,gCAAgC,EAChC,yCAAyC,EACzC,wCAAwC,EACxC,2BAA2B,EAC3B,kCAAkC,GACnC,MAAM,eAAe,CAAC;AACvB,OAAO,EAAC,6BAA6B,EAAC,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/metrics/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAC,uCAAuC,EAAC,MAAM,eAAe,CAAC;AAC3E,OAAO,EACL,wBAAwB,EACxB,yBAAyB,EACzB,6BAA6B,EAC7B,mCAAmC,EACnC,kCAAkC,EAClC,gCAAgC,EAChC,yCAAyC,EACzC,wCAAwC,EACxC,uCAAuC,EACvC,2BAA2B,EAC3B,kCAAkC,GACnC,MAAM,eAAe,CAAC;AACvB,OAAO,EAAC,6BAA6B,EAAC,MAAM,cAAc,CAAC"}
@@ -1,4 +1,4 @@
1
- export { jobExecutionClaimedCount, jobExecutionEnqueuedCount, jobExecutionLeaseExpiredCount, providerRunnerAbsentTerminatedCount, providerRunnerCountDivergenceCount, providerRunnerReconcileCallCount, providerRunnerTerminateIntentHonoredCount, providerRunnerTerminateIntentIssuedCount, recordRunnersRateLimitCheck, recordRunnersRateLimitPruneFailure } from './instance.js';
1
+ export { jobExecutionClaimedCount, jobExecutionEnqueuedCount, jobExecutionLeaseExpiredCount, providerRunnerAbsentTerminatedCount, providerRunnerCountDivergenceCount, providerRunnerReconcileCallCount, providerRunnerTerminateIntentHonoredCount, providerRunnerTerminateIntentIssuedCount, recordRunnerReservationPromotionFailure, recordRunnersRateLimitCheck, recordRunnersRateLimitPruneFailure } from './instance.js';
2
2
  export { registerRunnersServiceMetrics } from './service.js';
3
3
 
4
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/metrics/index.ts"],"sourcesContent":["export {\n jobExecutionClaimedCount,\n jobExecutionEnqueuedCount,\n jobExecutionLeaseExpiredCount,\n providerRunnerAbsentTerminatedCount,\n providerRunnerCountDivergenceCount,\n providerRunnerReconcileCallCount,\n providerRunnerTerminateIntentHonoredCount,\n providerRunnerTerminateIntentIssuedCount,\n recordRunnersRateLimitCheck,\n recordRunnersRateLimitPruneFailure,\n} from './instance.js';\nexport {registerRunnersServiceMetrics} from './service.js';\n"],"names":["jobExecutionClaimedCount","jobExecutionEnqueuedCount","jobExecutionLeaseExpiredCount","providerRunnerAbsentTerminatedCount","providerRunnerCountDivergenceCount","providerRunnerReconcileCallCount","providerRunnerTerminateIntentHonoredCount","providerRunnerTerminateIntentIssuedCount","recordRunnersRateLimitCheck","recordRunnersRateLimitPruneFailure","registerRunnersServiceMetrics"],"mappings":"AAAA,SACEA,wBAAwB,EACxBC,yBAAyB,EACzBC,6BAA6B,EAC7BC,mCAAmC,EACnCC,kCAAkC,EAClCC,gCAAgC,EAChCC,yCAAyC,EACzCC,wCAAwC,EACxCC,2BAA2B,EAC3BC,kCAAkC,QAC7B,gBAAgB;AACvB,SAAQC,6BAA6B,QAAO,eAAe"}
1
+ {"version":3,"sources":["../../src/metrics/index.ts"],"sourcesContent":["export type {RunnerReservationPromotionFailureReason} from './instance.js';\nexport {\n jobExecutionClaimedCount,\n jobExecutionEnqueuedCount,\n jobExecutionLeaseExpiredCount,\n providerRunnerAbsentTerminatedCount,\n providerRunnerCountDivergenceCount,\n providerRunnerReconcileCallCount,\n providerRunnerTerminateIntentHonoredCount,\n providerRunnerTerminateIntentIssuedCount,\n recordRunnerReservationPromotionFailure,\n recordRunnersRateLimitCheck,\n recordRunnersRateLimitPruneFailure,\n} from './instance.js';\nexport {registerRunnersServiceMetrics} from './service.js';\n"],"names":["jobExecutionClaimedCount","jobExecutionEnqueuedCount","jobExecutionLeaseExpiredCount","providerRunnerAbsentTerminatedCount","providerRunnerCountDivergenceCount","providerRunnerReconcileCallCount","providerRunnerTerminateIntentHonoredCount","providerRunnerTerminateIntentIssuedCount","recordRunnerReservationPromotionFailure","recordRunnersRateLimitCheck","recordRunnersRateLimitPruneFailure","registerRunnersServiceMetrics"],"mappings":"AACA,SACEA,wBAAwB,EACxBC,yBAAyB,EACzBC,6BAA6B,EAC7BC,mCAAmC,EACnCC,kCAAkC,EAClCC,gCAAgC,EAChCC,yCAAyC,EACzCC,wCAAwC,EACxCC,uCAAuC,EACvCC,2BAA2B,EAC3BC,kCAAkC,QAC7B,gBAAgB;AACvB,SAAQC,6BAA6B,QAAO,eAAe"}
@@ -1,34 +1,39 @@
1
1
  export declare const jobExecutionEnqueuedCount: import("@shipfox/node-opentelemetry").Counter<Record<string, never>>;
2
2
  export declare const jobExecutionClaimedCount: import("@shipfox/node-opentelemetry").Counter<{
3
- outcome: "claimed" | "empty";
3
+ outcome: 'claimed' | 'empty';
4
4
  }>;
5
5
  export declare const jobExecutionLeaseExpiredCount: import("@shipfox/node-opentelemetry").Counter<Record<string, never>>;
6
6
  export declare const providerRunnerReportCount: import("@shipfox/node-opentelemetry").Counter<{
7
- state: "starting" | "running" | "stopping" | "stopped" | "failed" | "terminated";
7
+ state: 'starting' | 'running' | 'stopping' | 'stopped' | 'failed' | 'terminated';
8
8
  }>;
9
9
  export declare const runnerBootstrapExchangeCount: import("@shipfox/node-opentelemetry").Counter<{
10
- outcome: "accepted" | "rejected";
10
+ outcome: 'accepted' | 'rejected';
11
11
  }>;
12
12
  export declare const runnerControlHeartbeatCount: import("@shipfox/node-opentelemetry").Counter<Record<string, never>>;
13
13
  export declare const providerRunnerReapedCount: import("@shipfox/node-opentelemetry").Counter<Record<string, never>>;
14
14
  export declare const providerRunnerCountDivergenceCount: import("@shipfox/node-opentelemetry").Counter<{
15
15
  template_key?: string;
16
- state: "starting" | "running";
17
- direction: "backend-higher" | "advertised-higher";
16
+ state: 'starting' | 'running';
17
+ direction: 'backend-higher' | 'advertised-higher';
18
18
  }>;
19
19
  export declare const providerRunnerReconcileCallCount: import("@shipfox/node-opentelemetry").Counter<Record<string, never>>;
20
20
  export declare const providerRunnerAbsentTerminatedCount: import("@shipfox/node-opentelemetry").Counter<Record<string, never>>;
21
21
  export declare const providerRunnerTerminateIntentIssuedCount: import("@shipfox/node-opentelemetry").Counter<{
22
- surface: "poll-demand" | "reconcile";
23
- reason: "job-cancelled" | "terminal-state";
22
+ surface: 'poll-demand' | 'reconcile';
23
+ reason: 'job-cancelled' | 'terminal-state';
24
24
  }>;
25
25
  export declare const providerRunnerTerminateIntentHonoredCount: import("@shipfox/node-opentelemetry").Counter<{
26
- reason: "job-cancelled";
26
+ reason: 'job-cancelled';
27
27
  }>;
28
28
  export declare const reservationReleasedCount: import("@shipfox/node-opentelemetry").Counter<Record<string, never>>;
29
+ export type RunnerReservationPromotionFailureReason = 'reservation-expired' | 'reservation-not-found' | 'already-assigned' | 'not-assignable';
30
+ export declare const runnerReservationPromotionFailureCount: import("@shipfox/node-opentelemetry").Counter<{
31
+ reason: RunnerReservationPromotionFailureReason;
32
+ }>;
29
33
  export type RunnersRateLimitAction = 'provisioner-mint' | 'ephemeral-register';
30
34
  export type RunnersRateLimitScope = 'provisioner' | 'ephemeral-token';
31
35
  export type RunnersRateLimitOutcome = 'allowed' | 'blocked' | 'unavailable';
36
+ export declare function recordRunnerReservationPromotionFailure(reason: RunnerReservationPromotionFailureReason): void;
32
37
  export declare function recordRunnersRateLimitCheck(params: {
33
38
  action: RunnersRateLimitAction;
34
39
  scope: RunnersRateLimitScope;
@@ -1 +1 @@
1
- {"version":3,"file":"instance.d.ts","sourceRoot":"","sources":["../../src/metrics/instance.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,yBAAyB,sEAKrC,CAAC;AAEF,eAAO,MAAM,wBAAwB;aAAiC,SAAS,GAAG,OAAO;EAGxF,CAAC;AAEF,eAAO,MAAM,6BAA6B,sEAGzC,CAAC;AAEF,eAAO,MAAM,yBAAyB;WAC7B,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,YAAY;EAGhF,CAAC;AAEH,eAAO,MAAM,4BAA4B;aAC9B,UAAU,GAAG,UAAU;EAGhC,CAAC;AAEH,eAAO,MAAM,2BAA2B,sEAGvC,CAAC;AAEF,eAAO,MAAM,yBAAyB,sEAKrC,CAAC;AAEF,eAAO,MAAM,kCAAkC;mBAC9B,MAAM;WACd,UAAU,GAAG,SAAS;eAClB,gBAAgB,GAAG,mBAAmB;EAIjD,CAAC;AAEH,eAAO,MAAM,gCAAgC,sEAG5C,CAAC;AAEF,eAAO,MAAM,mCAAmC,sEAM/C,CAAC;AAEF,eAAO,MAAM,wCAAwC;aAC1C,aAAa,GAAG,WAAW;YAC5B,eAAe,GAAG,gBAAgB;EAG1C,CAAC;AAEH,eAAO,MAAM,yCAAyC;YAC5C,eAAe;EAGvB,CAAC;AAEH,eAAO,MAAM,wBAAwB,sEAGpC,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,kBAAkB,GAAG,oBAAoB,CAAC;AAC/E,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG,iBAAiB,CAAC;AACtE,MAAM,MAAM,uBAAuB,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,CAAC;AAsB5E,wBAAgB,2BAA2B,CAAC,MAAM,EAAE;IAClD,MAAM,EAAE,sBAAsB,CAAC;IAC/B,KAAK,EAAE,qBAAqB,CAAC;IAC7B,OAAO,EAAE,uBAAuB,CAAC;CAClC,GAAG,IAAI,CAQP;AAED,wBAAgB,kCAAkC,IAAI,IAAI,CAEzD"}
1
+ {"version":3,"file":"instance.d.ts","sourceRoot":"","sources":["../../src/metrics/instance.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,yBAAyB,sEAKrC,CAAC;AAEF,eAAO,MAAM,wBAAwB;aAAiC,SAAS,GAAG,OAAO;EAGxF,CAAC;AAEF,eAAO,MAAM,6BAA6B,sEAGzC,CAAC;AAEF,eAAO,MAAM,yBAAyB;WAC7B,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,YAAY;EAGhF,CAAC;AAEH,eAAO,MAAM,4BAA4B;aAC9B,UAAU,GAAG,UAAU;EAGhC,CAAC;AAEH,eAAO,MAAM,2BAA2B,sEAGvC,CAAC;AAEF,eAAO,MAAM,yBAAyB,sEAKrC,CAAC;AAEF,eAAO,MAAM,kCAAkC;mBAC9B,MAAM;WACd,UAAU,GAAG,SAAS;eAClB,gBAAgB,GAAG,mBAAmB;EAIjD,CAAC;AAEH,eAAO,MAAM,gCAAgC,sEAG5C,CAAC;AAEF,eAAO,MAAM,mCAAmC,sEAM/C,CAAC;AAEF,eAAO,MAAM,wCAAwC;aAC1C,aAAa,GAAG,WAAW;YAC5B,eAAe,GAAG,gBAAgB;EAG1C,CAAC;AAEH,eAAO,MAAM,yCAAyC;YAC5C,eAAe;EAGvB,CAAC;AAEH,eAAO,MAAM,wBAAwB,sEAGpC,CAAC;AAEF,MAAM,MAAM,uCAAuC,GAC/C,qBAAqB,GACrB,uBAAuB,GACvB,kBAAkB,GAClB,gBAAgB,CAAC;AAErB,eAAO,MAAM,sCAAsC;YACzC,uCAAuC;EAG/C,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,kBAAkB,GAAG,oBAAoB,CAAC;AAC/E,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG,iBAAiB,CAAC;AACtE,MAAM,MAAM,uBAAuB,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,CAAC;AAsB5E,wBAAgB,uCAAuC,CACrD,MAAM,EAAE,uCAAuC,GAC9C,IAAI,CAEN;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE;IAClD,MAAM,EAAE,sBAAsB,CAAC;IAC/B,KAAK,EAAE,qBAAqB,CAAC;IAC7B,OAAO,EAAE,uBAAuB,CAAC;CAClC,GAAG,IAAI,CAQP;AAED,wBAAgB,kCAAkC,IAAI,IAAI,CAEzD"}
@@ -39,6 +39,9 @@ export const providerRunnerTerminateIntentHonoredCount = meter.createCounter('ru
39
39
  export const reservationReleasedCount = meter.createCounter('runners_reservation_released', {
40
40
  description: 'Reservation units released from terminal provisioned runner reports'
41
41
  });
42
+ export const runnerReservationPromotionFailureCount = meter.createCounter('runners_reservation_promotion_failures', {
43
+ description: 'Runner reservation promotion failures during enrollment by reason'
44
+ });
42
45
  const rateLimitCheckCount = meter.createCounter('runners_rate_limit_checks', {
43
46
  description: 'Runners rate limit checks by action, scope, and outcome'
44
47
  });
@@ -52,6 +55,11 @@ function recordMetric(record) {
52
55
  // Metrics must not affect runner or provisioner request outcomes.
53
56
  }
54
57
  }
58
+ export function recordRunnerReservationPromotionFailure(reason) {
59
+ recordMetric(()=>runnerReservationPromotionFailureCount.add(1, {
60
+ reason
61
+ }));
62
+ }
55
63
  export function recordRunnersRateLimitCheck(params) {
56
64
  recordMetric(()=>rateLimitCheckCount.add(1, {
57
65
  action: params.action,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/metrics/instance.ts"],"sourcesContent":["import {instanceMetrics} from '@shipfox/node-opentelemetry';\n\nconst meter = instanceMetrics.getMeter('runners');\n\nexport const jobExecutionEnqueuedCount = meter.createCounter<Record<string, never>>(\n 'runners_job_execution_enqueued',\n {\n description: 'Job executions added to the pending queue',\n },\n);\n\nexport const jobExecutionClaimedCount = meter.createCounter<{outcome: 'claimed' | 'empty'}>(\n 'runners_job_execution_claimed',\n {description: 'Job execution claim attempts by outcome'},\n);\n\nexport const jobExecutionLeaseExpiredCount = meter.createCounter<Record<string, never>>(\n 'runners_job_execution_lease_expired',\n {description: 'Job execution leases reaped after passing the heartbeat threshold'},\n);\n\nexport const providerRunnerReportCount = meter.createCounter<{\n state: 'starting' | 'running' | 'stopping' | 'stopped' | 'failed' | 'terminated';\n}>('runners_provider_runner_reported', {\n description: 'Provisioned runner lifecycle reports accepted by state',\n});\n\nexport const runnerBootstrapExchangeCount = meter.createCounter<{\n outcome: 'accepted' | 'rejected';\n}>('runners_runner_bootstrap_exchange', {\n description: 'Runner bootstrap-token exchanges by outcome',\n});\n\nexport const runnerControlHeartbeatCount = meter.createCounter<Record<string, never>>(\n 'runners_runner_control_heartbeat',\n {description: 'Pre-workspace runner-control heartbeats accepted'},\n);\n\nexport const providerRunnerReapedCount = meter.createCounter<Record<string, never>>(\n 'runners_provider_runner_reaped',\n {\n description: 'Stale provisioned runners marked failed by backend maintenance',\n },\n);\n\nexport const providerRunnerCountDivergenceCount = meter.createCounter<{\n template_key?: string;\n state: 'starting' | 'running';\n direction: 'backend-higher' | 'advertised-higher';\n}>('runners_provider_runner_count_divergence', {\n description:\n 'Absolute difference between provisioner-advertised and backend-observed provisioned runner counts',\n});\n\nexport const providerRunnerReconcileCallCount = meter.createCounter<Record<string, never>>(\n 'runners_provider_runner_reconcile_called',\n {description: 'Provisioned runner reconcile calls completed successfully'},\n);\n\nexport const providerRunnerAbsentTerminatedCount = meter.createCounter<Record<string, never>>(\n 'runners_provider_runner_absent_terminated',\n {\n description:\n 'Owned provisioned runners marked terminated because they were absent from reconcile',\n },\n);\n\nexport const providerRunnerTerminateIntentIssuedCount = meter.createCounter<{\n surface: 'poll-demand' | 'reconcile';\n reason: 'job-cancelled' | 'terminal-state';\n}>('runners_provider_runner_terminate_intent_issued', {\n description: 'Provisioned runner terminate intents returned to provisioners',\n});\n\nexport const providerRunnerTerminateIntentHonoredCount = meter.createCounter<{\n reason: 'job-cancelled';\n}>('runners_provider_runner_terminate_intent_honored', {\n description: 'Provisioned runner terminate intents honored by first transition to terminated',\n});\n\nexport const reservationReleasedCount = meter.createCounter<Record<string, never>>(\n 'runners_reservation_released',\n {description: 'Reservation units released from terminal provisioned runner reports'},\n);\n\nexport type RunnersRateLimitAction = 'provisioner-mint' | 'ephemeral-register';\nexport type RunnersRateLimitScope = 'provisioner' | 'ephemeral-token';\nexport type RunnersRateLimitOutcome = 'allowed' | 'blocked' | 'unavailable';\n\nconst rateLimitCheckCount = meter.createCounter<{\n action: RunnersRateLimitAction;\n scope: RunnersRateLimitScope;\n outcome: RunnersRateLimitOutcome;\n}>('runners_rate_limit_checks', {\n description: 'Runners rate limit checks by action, scope, and outcome',\n});\n\nconst rateLimitPruneFailureCount = meter.createCounter('runners_rate_limit_prune_failures', {\n description: 'Runners rate limit prune failures',\n});\n\nfunction recordMetric(record: () => void): void {\n try {\n record();\n } catch {\n // Metrics must not affect runner or provisioner request outcomes.\n }\n}\n\nexport function recordRunnersRateLimitCheck(params: {\n action: RunnersRateLimitAction;\n scope: RunnersRateLimitScope;\n outcome: RunnersRateLimitOutcome;\n}): void {\n recordMetric(() =>\n rateLimitCheckCount.add(1, {\n action: params.action,\n scope: params.scope,\n outcome: params.outcome,\n }),\n );\n}\n\nexport function recordRunnersRateLimitPruneFailure(): void {\n recordMetric(() => rateLimitPruneFailureCount.add(1));\n}\n"],"names":["instanceMetrics","meter","getMeter","jobExecutionEnqueuedCount","createCounter","description","jobExecutionClaimedCount","jobExecutionLeaseExpiredCount","providerRunnerReportCount","runnerBootstrapExchangeCount","runnerControlHeartbeatCount","providerRunnerReapedCount","providerRunnerCountDivergenceCount","providerRunnerReconcileCallCount","providerRunnerAbsentTerminatedCount","providerRunnerTerminateIntentIssuedCount","providerRunnerTerminateIntentHonoredCount","reservationReleasedCount","rateLimitCheckCount","rateLimitPruneFailureCount","recordMetric","record","recordRunnersRateLimitCheck","params","add","action","scope","outcome","recordRunnersRateLimitPruneFailure"],"mappings":"AAAA,SAAQA,eAAe,QAAO,8BAA8B;AAE5D,MAAMC,QAAQD,gBAAgBE,QAAQ,CAAC;AAEvC,OAAO,MAAMC,4BAA4BF,MAAMG,aAAa,CAC1D,kCACA;IACEC,aAAa;AACf,GACA;AAEF,OAAO,MAAMC,2BAA2BL,MAAMG,aAAa,CACzD,iCACA;IAACC,aAAa;AAAyC,GACvD;AAEF,OAAO,MAAME,gCAAgCN,MAAMG,aAAa,CAC9D,uCACA;IAACC,aAAa;AAAmE,GACjF;AAEF,OAAO,MAAMG,4BAA4BP,MAAMG,aAAa,CAEzD,oCAAoC;IACrCC,aAAa;AACf,GAAG;AAEH,OAAO,MAAMI,+BAA+BR,MAAMG,aAAa,CAE5D,qCAAqC;IACtCC,aAAa;AACf,GAAG;AAEH,OAAO,MAAMK,8BAA8BT,MAAMG,aAAa,CAC5D,oCACA;IAACC,aAAa;AAAkD,GAChE;AAEF,OAAO,MAAMM,4BAA4BV,MAAMG,aAAa,CAC1D,kCACA;IACEC,aAAa;AACf,GACA;AAEF,OAAO,MAAMO,qCAAqCX,MAAMG,aAAa,CAIlE,4CAA4C;IAC7CC,aACE;AACJ,GAAG;AAEH,OAAO,MAAMQ,mCAAmCZ,MAAMG,aAAa,CACjE,4CACA;IAACC,aAAa;AAA2D,GACzE;AAEF,OAAO,MAAMS,sCAAsCb,MAAMG,aAAa,CACpE,6CACA;IACEC,aACE;AACJ,GACA;AAEF,OAAO,MAAMU,2CAA2Cd,MAAMG,aAAa,CAGxE,mDAAmD;IACpDC,aAAa;AACf,GAAG;AAEH,OAAO,MAAMW,4CAA4Cf,MAAMG,aAAa,CAEzE,oDAAoD;IACrDC,aAAa;AACf,GAAG;AAEH,OAAO,MAAMY,2BAA2BhB,MAAMG,aAAa,CACzD,gCACA;IAACC,aAAa;AAAqE,GACnF;AAMF,MAAMa,sBAAsBjB,MAAMG,aAAa,CAI5C,6BAA6B;IAC9BC,aAAa;AACf;AAEA,MAAMc,6BAA6BlB,MAAMG,aAAa,CAAC,qCAAqC;IAC1FC,aAAa;AACf;AAEA,SAASe,aAAaC,MAAkB;IACtC,IAAI;QACFA;IACF,EAAE,OAAM;IACN,kEAAkE;IACpE;AACF;AAEA,OAAO,SAASC,4BAA4BC,MAI3C;IACCH,aAAa,IACXF,oBAAoBM,GAAG,CAAC,GAAG;YACzBC,QAAQF,OAAOE,MAAM;YACrBC,OAAOH,OAAOG,KAAK;YACnBC,SAASJ,OAAOI,OAAO;QACzB;AAEJ;AAEA,OAAO,SAASC;IACdR,aAAa,IAAMD,2BAA2BK,GAAG,CAAC;AACpD"}
1
+ {"version":3,"sources":["../../src/metrics/instance.ts"],"sourcesContent":["import {instanceMetrics} from '@shipfox/node-opentelemetry';\n\nconst meter = instanceMetrics.getMeter('runners');\n\nexport const jobExecutionEnqueuedCount = meter.createCounter<Record<string, never>>(\n 'runners_job_execution_enqueued',\n {\n description: 'Job executions added to the pending queue',\n },\n);\n\nexport const jobExecutionClaimedCount = meter.createCounter<{outcome: 'claimed' | 'empty'}>(\n 'runners_job_execution_claimed',\n {description: 'Job execution claim attempts by outcome'},\n);\n\nexport const jobExecutionLeaseExpiredCount = meter.createCounter<Record<string, never>>(\n 'runners_job_execution_lease_expired',\n {description: 'Job execution leases reaped after passing the heartbeat threshold'},\n);\n\nexport const providerRunnerReportCount = meter.createCounter<{\n state: 'starting' | 'running' | 'stopping' | 'stopped' | 'failed' | 'terminated';\n}>('runners_provider_runner_reported', {\n description: 'Provisioned runner lifecycle reports accepted by state',\n});\n\nexport const runnerBootstrapExchangeCount = meter.createCounter<{\n outcome: 'accepted' | 'rejected';\n}>('runners_runner_bootstrap_exchange', {\n description: 'Runner bootstrap-token exchanges by outcome',\n});\n\nexport const runnerControlHeartbeatCount = meter.createCounter<Record<string, never>>(\n 'runners_runner_control_heartbeat',\n {description: 'Pre-workspace runner-control heartbeats accepted'},\n);\n\nexport const providerRunnerReapedCount = meter.createCounter<Record<string, never>>(\n 'runners_provider_runner_reaped',\n {\n description: 'Stale provisioned runners marked failed by backend maintenance',\n },\n);\n\nexport const providerRunnerCountDivergenceCount = meter.createCounter<{\n template_key?: string;\n state: 'starting' | 'running';\n direction: 'backend-higher' | 'advertised-higher';\n}>('runners_provider_runner_count_divergence', {\n description:\n 'Absolute difference between provisioner-advertised and backend-observed provisioned runner counts',\n});\n\nexport const providerRunnerReconcileCallCount = meter.createCounter<Record<string, never>>(\n 'runners_provider_runner_reconcile_called',\n {description: 'Provisioned runner reconcile calls completed successfully'},\n);\n\nexport const providerRunnerAbsentTerminatedCount = meter.createCounter<Record<string, never>>(\n 'runners_provider_runner_absent_terminated',\n {\n description:\n 'Owned provisioned runners marked terminated because they were absent from reconcile',\n },\n);\n\nexport const providerRunnerTerminateIntentIssuedCount = meter.createCounter<{\n surface: 'poll-demand' | 'reconcile';\n reason: 'job-cancelled' | 'terminal-state';\n}>('runners_provider_runner_terminate_intent_issued', {\n description: 'Provisioned runner terminate intents returned to provisioners',\n});\n\nexport const providerRunnerTerminateIntentHonoredCount = meter.createCounter<{\n reason: 'job-cancelled';\n}>('runners_provider_runner_terminate_intent_honored', {\n description: 'Provisioned runner terminate intents honored by first transition to terminated',\n});\n\nexport const reservationReleasedCount = meter.createCounter<Record<string, never>>(\n 'runners_reservation_released',\n {description: 'Reservation units released from terminal provisioned runner reports'},\n);\n\nexport type RunnerReservationPromotionFailureReason =\n | 'reservation-expired'\n | 'reservation-not-found'\n | 'already-assigned'\n | 'not-assignable';\n\nexport const runnerReservationPromotionFailureCount = meter.createCounter<{\n reason: RunnerReservationPromotionFailureReason;\n}>('runners_reservation_promotion_failures', {\n description: 'Runner reservation promotion failures during enrollment by reason',\n});\n\nexport type RunnersRateLimitAction = 'provisioner-mint' | 'ephemeral-register';\nexport type RunnersRateLimitScope = 'provisioner' | 'ephemeral-token';\nexport type RunnersRateLimitOutcome = 'allowed' | 'blocked' | 'unavailable';\n\nconst rateLimitCheckCount = meter.createCounter<{\n action: RunnersRateLimitAction;\n scope: RunnersRateLimitScope;\n outcome: RunnersRateLimitOutcome;\n}>('runners_rate_limit_checks', {\n description: 'Runners rate limit checks by action, scope, and outcome',\n});\n\nconst rateLimitPruneFailureCount = meter.createCounter('runners_rate_limit_prune_failures', {\n description: 'Runners rate limit prune failures',\n});\n\nfunction recordMetric(record: () => void): void {\n try {\n record();\n } catch {\n // Metrics must not affect runner or provisioner request outcomes.\n }\n}\n\nexport function recordRunnerReservationPromotionFailure(\n reason: RunnerReservationPromotionFailureReason,\n): void {\n recordMetric(() => runnerReservationPromotionFailureCount.add(1, {reason}));\n}\n\nexport function recordRunnersRateLimitCheck(params: {\n action: RunnersRateLimitAction;\n scope: RunnersRateLimitScope;\n outcome: RunnersRateLimitOutcome;\n}): void {\n recordMetric(() =>\n rateLimitCheckCount.add(1, {\n action: params.action,\n scope: params.scope,\n outcome: params.outcome,\n }),\n );\n}\n\nexport function recordRunnersRateLimitPruneFailure(): void {\n recordMetric(() => rateLimitPruneFailureCount.add(1));\n}\n"],"names":["instanceMetrics","meter","getMeter","jobExecutionEnqueuedCount","createCounter","description","jobExecutionClaimedCount","jobExecutionLeaseExpiredCount","providerRunnerReportCount","runnerBootstrapExchangeCount","runnerControlHeartbeatCount","providerRunnerReapedCount","providerRunnerCountDivergenceCount","providerRunnerReconcileCallCount","providerRunnerAbsentTerminatedCount","providerRunnerTerminateIntentIssuedCount","providerRunnerTerminateIntentHonoredCount","reservationReleasedCount","runnerReservationPromotionFailureCount","rateLimitCheckCount","rateLimitPruneFailureCount","recordMetric","record","recordRunnerReservationPromotionFailure","reason","add","recordRunnersRateLimitCheck","params","action","scope","outcome","recordRunnersRateLimitPruneFailure"],"mappings":"AAAA,SAAQA,eAAe,QAAO,8BAA8B;AAE5D,MAAMC,QAAQD,gBAAgBE,QAAQ,CAAC;AAEvC,OAAO,MAAMC,4BAA4BF,MAAMG,aAAa,CAC1D,kCACA;IACEC,aAAa;AACf,GACA;AAEF,OAAO,MAAMC,2BAA2BL,MAAMG,aAAa,CACzD,iCACA;IAACC,aAAa;AAAyC,GACvD;AAEF,OAAO,MAAME,gCAAgCN,MAAMG,aAAa,CAC9D,uCACA;IAACC,aAAa;AAAmE,GACjF;AAEF,OAAO,MAAMG,4BAA4BP,MAAMG,aAAa,CAEzD,oCAAoC;IACrCC,aAAa;AACf,GAAG;AAEH,OAAO,MAAMI,+BAA+BR,MAAMG,aAAa,CAE5D,qCAAqC;IACtCC,aAAa;AACf,GAAG;AAEH,OAAO,MAAMK,8BAA8BT,MAAMG,aAAa,CAC5D,oCACA;IAACC,aAAa;AAAkD,GAChE;AAEF,OAAO,MAAMM,4BAA4BV,MAAMG,aAAa,CAC1D,kCACA;IACEC,aAAa;AACf,GACA;AAEF,OAAO,MAAMO,qCAAqCX,MAAMG,aAAa,CAIlE,4CAA4C;IAC7CC,aACE;AACJ,GAAG;AAEH,OAAO,MAAMQ,mCAAmCZ,MAAMG,aAAa,CACjE,4CACA;IAACC,aAAa;AAA2D,GACzE;AAEF,OAAO,MAAMS,sCAAsCb,MAAMG,aAAa,CACpE,6CACA;IACEC,aACE;AACJ,GACA;AAEF,OAAO,MAAMU,2CAA2Cd,MAAMG,aAAa,CAGxE,mDAAmD;IACpDC,aAAa;AACf,GAAG;AAEH,OAAO,MAAMW,4CAA4Cf,MAAMG,aAAa,CAEzE,oDAAoD;IACrDC,aAAa;AACf,GAAG;AAEH,OAAO,MAAMY,2BAA2BhB,MAAMG,aAAa,CACzD,gCACA;IAACC,aAAa;AAAqE,GACnF;AAQF,OAAO,MAAMa,yCAAyCjB,MAAMG,aAAa,CAEtE,0CAA0C;IAC3CC,aAAa;AACf,GAAG;AAMH,MAAMc,sBAAsBlB,MAAMG,aAAa,CAI5C,6BAA6B;IAC9BC,aAAa;AACf;AAEA,MAAMe,6BAA6BnB,MAAMG,aAAa,CAAC,qCAAqC;IAC1FC,aAAa;AACf;AAEA,SAASgB,aAAaC,MAAkB;IACtC,IAAI;QACFA;IACF,EAAE,OAAM;IACN,kEAAkE;IACpE;AACF;AAEA,OAAO,SAASC,wCACdC,MAA+C;IAE/CH,aAAa,IAAMH,uCAAuCO,GAAG,CAAC,GAAG;YAACD;QAAM;AAC1E;AAEA,OAAO,SAASE,4BAA4BC,MAI3C;IACCN,aAAa,IACXF,oBAAoBM,GAAG,CAAC,GAAG;YACzBG,QAAQD,OAAOC,MAAM;YACrBC,OAAOF,OAAOE,KAAK;YACnBC,SAASH,OAAOG,OAAO;QACzB;AAEJ;AAEA,OAAO,SAASC;IACdV,aAAa,IAAMD,2BAA2BK,GAAG,CAAC;AACpD"}
@@ -1,7 +1,7 @@
1
1
  import type { ProvisionerToken } from '#core/entities/provisioner-token.js';
2
2
  export declare function toAdministratorProvisionerTokenDto(token: ProvisionerToken): {
3
3
  id: string;
4
- scope: "installation";
4
+ scope: 'installation';
5
5
  prefix: string;
6
6
  name: string | null;
7
7
  status: import("#core/provisioner-tokens.js").InstallationProvisionerTokenStatus;
@@ -1 +1 @@
1
- {"version":3,"file":"admin-provisioner-token.d.ts","sourceRoot":"","sources":["../../../src/presentation/dto/admin-provisioner-token.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,qCAAqC,CAAC;AAG1E,wBAAgB,kCAAkC,CAAC,KAAK,EAAE,gBAAgB;;;;;;;;;;;;;EAmBzE"}
1
+ {"version":3,"file":"admin-provisioner-token.d.ts","sourceRoot":"","sources":["../../../src/presentation/dto/admin-provisioner-token.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,qCAAqC,CAAC;AAG1E,wBAAgB,kCAAkC,CAAC,KAAK,EAAE,gBAAgB;IAMtE,EAAE;IACF,KAAK,EAAE,cAAc;IACrB,MAAM;IACN,IAAI;IACJ,MAAM;IACN,kBAAkB;IAClB,kBAAkB;IAClB,UAAU;IACV,UAAU;IACV,YAAY;IACZ,UAAU;IACV,UAAU;EAEb"}
@@ -4,7 +4,7 @@ export declare function toRunnerAdministratorInstanceDto(runner: RunnerAdministr
4
4
  lifecycle_state: import("#core/admin-runner-instances.js").RunnerAdministratorLifecycleState;
5
5
  compute_state: import("../../core/index.js").RunnerInstanceState;
6
6
  enrollment_state: import("#core/admin-runner-instances.js").RunnerAdministratorEnrollmentState;
7
- assignment_presence: "unassigned" | "assigned";
7
+ assignment_presence: "assigned" | "unassigned";
8
8
  assigned_workspace: {
9
9
  id: string;
10
10
  } | null;
@@ -15,7 +15,7 @@ export declare function toRunnerAdministratorInstanceDto(runner: RunnerAdministr
15
15
  closed_at: string | null;
16
16
  provisioner: {
17
17
  id: string;
18
- scope: "installation";
18
+ scope: 'installation';
19
19
  name: string | null;
20
20
  };
21
21
  reconciliation_status: import("#core/admin-runner-instances.js").RunnerAdministratorReconciliationStatus;
@@ -1 +1 @@
1
- {"version":3,"file":"admin-runner-instances.d.ts","sourceRoot":"","sources":["../../../src/presentation/dto/admin-runner-instances.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,2BAA2B,EAAC,MAAM,iCAAiC,CAAC;AAEjF,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,2BAA2B;;;;;;;;;;;;;;;;;;;;EAgBnF"}
1
+ {"version":3,"file":"admin-runner-instances.d.ts","sourceRoot":"","sources":["../../../src/presentation/dto/admin-runner-instances.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,2BAA2B,EAAC,MAAM,iCAAiC,CAAC;AAEjF,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,2BAA2B;IAEhF,EAAE;IACF,eAAe;IACf,aAAa;IACb,gBAAgB;IAChB,mBAAmB;IACnB,kBAAkB;;;IAClB,MAAM;IACN,UAAU;IACV,iBAAiB;IACjB,cAAc;IACd,SAAS;IACT,WAAW;;;;;IACX,qBAAqB;EAExB"}
@@ -1 +1 @@
1
- {"version":3,"file":"poll-demand.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/poll-demand.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAC,0BAA0B,EAAC,MAAM,+BAA+B,CAAC;AAe9E,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,0BAA+B,mDA4F7E;AAED,eAAO,MAAM,eAAe,iDAA0B,CAAC"}
1
+ {"version":3,"file":"poll-demand.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/poll-demand.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAC,0BAA0B,EAAC,MAAM,+BAA+B,CAAC;AAsB9E,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,0BAA+B,mDAgG7E;AAED,eAAO,MAAM,eAAe,iDAA0B,CAAC"}