deepline 0.3.110 → 0.3.112

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.
@@ -1,4 +1,5 @@
1
1
  import { iterateCursorPages } from './pagination.js';
2
+ import type { ToolResultBilling } from '../../shared_libs/plays/tool-result-types.js';
2
3
  /**
3
4
  * The main API client for interacting with the Deepline platform.
4
5
  *
@@ -583,7 +584,7 @@ export type ToolExecution<TData = unknown, TMeta = Record<string, unknown>> = {
583
584
  };
584
585
  extractedLists?: Record<string, unknown>;
585
586
  extractedValues?: Record<string, unknown>;
586
- billing?: Record<string, unknown>;
587
+ billing?: ToolResultBilling;
587
588
  [key: string]: unknown;
588
589
  };
589
590
 
@@ -303,6 +303,7 @@ export type {
303
303
  StepProgramResolver,
304
304
  StepResolver,
305
305
  ToolExecuteResult,
306
+ ToolResultBilling,
306
307
  ToolExecutionRequest,
307
308
  DeeplineEmailStatusGetterValue,
308
309
  DeeplineExtractorTarget,
@@ -268,6 +268,7 @@ export type {
268
268
  ToolExecuteResult,
269
269
  ToolExecuteResultAccessors,
270
270
  ToolExecuteResultBase,
271
+ ToolResultBilling,
271
272
  ToolResultEnvelope,
272
273
  ToolResultListAccessor,
273
274
  ToolResultTargetAccessor as ToolExtractedValue,
@@ -1546,6 +1547,7 @@ function toolExecutionEnvelopeToResult(
1546
1547
  source: 'live',
1547
1548
  },
1548
1549
  meta: isRecord(response.meta) ? response.meta : undefined,
1550
+ billing: response.billing,
1549
1551
  }),
1550
1552
  options,
1551
1553
  );
@@ -200,7 +200,7 @@ export const SDK_RELEASE = {
200
200
  // getters keep their established compatibility behavior.
201
201
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
202
202
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
203
- version: '0.3.110',
203
+ version: '0.3.112',
204
204
  updateSummary:
205
205
  'Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.',
206
206
  packageCapabilities: {
@@ -805,9 +805,9 @@
805
805
  "locator": "observe operational queue health",
806
806
  "owner": "reliability",
807
807
  "criticality": "critical",
808
- "purpose": "Measure every durable queue through the scheduler-neutral depth, age, flow, and DLQ contract.",
809
- "successDefinition": "Every cataloged queue publishes a complete measurement and the observer completes.",
810
- "failureDefinition": "The observer is missed/stuck, a queue is silently omitted, or snapshots cannot persist.",
808
+ "purpose": "Measure every Convex-owned durable queue through the scheduler-neutral depth, age, flow, and DLQ contract; Runtime Postgres/Absurd queues are published by their owning adapter.",
809
+ "successDefinition": "Every Convex-owned catalog queue publishes a complete measurement and the observer completes; external runtime queues publish through their owning adapter.",
810
+ "failureDefinition": "The observer is missed/stuck, a Convex-owned queue is silently omitted, or snapshots cannot persist.",
811
811
  "startGraceMs": 120000,
812
812
  "runTimeoutMs": 1800000,
813
813
  "failureAlert": "convex_action_wrapper",
@@ -5029,6 +5029,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
5029
5029
  toolResponse: execution.toolResponse,
5030
5030
  metadata: execution.metadata,
5031
5031
  meta: execution.meta,
5032
+ billing: execution.billing,
5032
5033
  requestInput: input.dispatchPayload,
5033
5034
  execution: toolExecutionMetadataForOutcome({
5034
5035
  kind: 'live',
@@ -5941,6 +5942,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
5941
5942
  result: unknown;
5942
5943
  metadata?: ToolResultMetadataInput | null;
5943
5944
  meta?: Record<string, unknown>;
5945
+ billing?: ParsedToolExecuteResponse['billing'];
5944
5946
  toolResponse?: {
5945
5947
  raw?: unknown;
5946
5948
  rawV2?: unknown;
@@ -5987,6 +5989,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
5987
5989
  (await this.resolveToolResultMetadata(input.toolId)),
5988
5990
  execution: input.execution,
5989
5991
  meta: input.meta,
5992
+ billing: input.billing,
5990
5993
  }),
5991
5994
  );
5992
5995
  }
@@ -10363,6 +10366,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
10363
10366
  toolResponse: execution.toolResponse,
10364
10367
  metadata: execution.metadata,
10365
10368
  meta: execution.meta,
10369
+ billing: execution.billing,
10366
10370
  requestInput: input,
10367
10371
  execution: toolExecutionMetadataForOutcome({
10368
10372
  kind: 'live',
@@ -12657,6 +12661,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
12657
12661
  toolResponse: execution.toolResponse,
12658
12662
  metadata: execution.metadata,
12659
12663
  meta: execution.meta,
12664
+ billing: execution.billing,
12660
12665
  requestInput: call.payload,
12661
12666
  execution: toolExecutionMetadataForOutcome({
12662
12667
  kind: 'live',
@@ -409,26 +409,26 @@ function absurdProjectionQuery(queueTable: string): string {
409
409
  FROM ${table}
410
410
  WHERE state = 'pending' AND available_at <= $1::timestamptz
411
411
  ORDER BY available_at, run_id
412
- LIMIT $2)
412
+ LIMIT $2::int)
413
413
  UNION ALL
414
414
  (SELECT 'delayed'::text, available_at
415
415
  FROM ${table}
416
416
  WHERE state = 'sleeping'
417
417
  ORDER BY available_at, run_id
418
- LIMIT $2)
418
+ LIMIT $2::int)
419
419
  UNION ALL
420
420
  (SELECT 'delayed'::text, available_at
421
421
  FROM ${table}
422
422
  WHERE state = 'pending' AND available_at > $1::timestamptz
423
423
  ORDER BY available_at, run_id
424
- LIMIT $2)
424
+ LIMIT $2::int)
425
425
  UNION ALL
426
426
  (SELECT 'in_flight'::text, coalesce(started_at, created_at)
427
427
  FROM ${table}
428
428
  WHERE state = 'running'
429
429
  AND (claim_expires_at IS NULL OR claim_expires_at > $1::timestamptz)
430
430
  ORDER BY available_at, run_id
431
- LIMIT $2)
431
+ LIMIT $2::int)
432
432
  UNION ALL
433
433
  (SELECT 'blocked'::text, coalesce(claim_expires_at, started_at, created_at)
434
434
  FROM ${table}
@@ -436,13 +436,13 @@ function absurdProjectionQuery(queueTable: string): string {
436
436
  AND claim_expires_at IS NOT NULL
437
437
  AND claim_expires_at <= $1::timestamptz
438
438
  ORDER BY claim_expires_at, run_id
439
- LIMIT $2)
439
+ LIMIT $2::int)
440
440
  UNION ALL
441
441
  (SELECT 'dead_lettered'::text, coalesce(failed_at, created_at)
442
442
  FROM ${table}
443
443
  WHERE state = 'failed'
444
444
  ORDER BY available_at, run_id
445
- LIMIT $2)
445
+ LIMIT $2::int)
446
446
  )
447
447
  SELECT
448
448
  least(count(*) FILTER (WHERE bucket = 'ready'), $3) AS ready,
@@ -493,13 +493,13 @@ function outboxProjectionQuery(schema: string): string {
493
493
  FROM ${table}
494
494
  WHERE delivered_at IS NULL AND failed_at IS NULL
495
495
  ORDER BY coalesce(next_attempt_at, created_at), created_at, event_id
496
- LIMIT $2
496
+ LIMIT $2::int
497
497
  ), dead_sample AS (
498
498
  SELECT 'dead_lettered'::text AS bucket, coalesce(failed_at, created_at) AS age_at
499
499
  FROM ${table}
500
500
  WHERE delivered_at IS NULL AND failed_at IS NOT NULL
501
501
  ORDER BY failed_at, event_id
502
- LIMIT $2
502
+ LIMIT $2::int
503
503
  ), sampled AS (
504
504
  SELECT * FROM pending_sample
505
505
  UNION ALL
@@ -556,7 +556,7 @@ function cleanupProjectionQuery(schema: string): string {
556
556
  FROM ${table}
557
557
  WHERE status <> 'deleted'
558
558
  ORDER BY available_at, created_at, provider, sandbox_id
559
- LIMIT $2
559
+ LIMIT $2::int
560
560
  )
561
561
  SELECT
562
562
  least(count(*) FILTER (WHERE bucket = 'ready'), $3) AS ready,
@@ -623,27 +623,34 @@ export async function readRuntimeQueueHealthFromClient(
623
623
  RUNTIME_QUEUE_HEALTH_MAX_ABSURD_QUEUES,
624
624
  ),
625
625
  );
626
- const requestedNames = input.absurdQueueNames?.length
627
- ? [
628
- ...new Set(
629
- input.absurdQueueNames.map((name) => name.trim()).filter(Boolean),
630
- ),
631
- ]
632
- : undefined;
626
+ // `undefined` deliberately means "inspect the registry" for diagnostics.
627
+ // An explicit empty list means the control plane found no live lanes; never
628
+ // turn that into a scan of historical queues.
629
+ const requestedNames =
630
+ input.absurdQueueNames === undefined
631
+ ? undefined
632
+ : [
633
+ ...new Set(
634
+ input.absurdQueueNames.map((name) => name.trim()).filter(Boolean),
635
+ ),
636
+ ];
633
637
  if (requestedNames && requestedNames.length > maxQueues) {
634
638
  throw new Error(
635
639
  `Requested ${requestedNames.length} Absurd queues, exceeding the ${maxQueues} queue health limit.`,
636
640
  );
637
641
  }
638
- const registry = requestedNames
639
- ? await client.query<{ queue_name: string }>(
640
- `SELECT queue_name FROM absurd.queues WHERE queue_name = ANY($1::text[]) ORDER BY queue_name LIMIT $2`,
641
- [requestedNames, maxQueues],
642
- )
643
- : await client.query<{ queue_name: string }>(
644
- `SELECT queue_name FROM absurd.queues ORDER BY queue_name LIMIT $1`,
645
- [maxQueues],
646
- );
642
+ const registry =
643
+ requestedNames?.length === 0
644
+ ? { rows: [] }
645
+ : requestedNames
646
+ ? await client.query<{ queue_name: string }>(
647
+ `SELECT queue_name FROM absurd.queues WHERE queue_name = ANY($1::text[]) ORDER BY queue_name LIMIT $2::int`,
648
+ [requestedNames, maxQueues],
649
+ )
650
+ : await client.query<{ queue_name: string }>(
651
+ `SELECT queue_name FROM absurd.queues ORDER BY queue_name LIMIT $1::int`,
652
+ [maxQueues],
653
+ );
647
654
  const queueNames = registry.rows.map((row) => row.queue_name);
648
655
  if (requestedNames) {
649
656
  const found = new Set(queueNames);
@@ -1,6 +1,7 @@
1
1
  export type {
2
2
  SerializedToolExecuteResult,
3
3
  ToolExecuteResult,
4
+ ToolResultBilling,
4
5
  ToolResultExecutionMetadata,
5
6
  ToolResultMetadata,
6
7
  ToolResultMetadataInput,
@@ -29,6 +30,7 @@ import {
29
30
  import type {
30
31
  SerializedToolExecuteResult,
31
32
  ToolExecuteResult,
33
+ ToolResultBilling,
32
34
  ToolResultExecutionMetadata,
33
35
  ToolResultExtractorDescriptor,
34
36
  ToolResultListAccessor,
@@ -215,6 +217,7 @@ export type ParsedToolExecuteResponse = {
215
217
  status: string;
216
218
  jobId?: string;
217
219
  meta?: Record<string, unknown>;
220
+ billing?: ToolResultBilling;
218
221
  toolResponse?: {
219
222
  raw?: unknown;
220
223
  rawV2?: unknown;
@@ -243,6 +246,7 @@ export function parseToolExecuteResponse(
243
246
  status,
244
247
  jobId: typeof body.job_id === 'string' ? body.job_id : undefined,
245
248
  meta: isRecord(body.meta) ? body.meta : undefined,
249
+ billing: isRecord(body.billing) ? body.billing : undefined,
246
250
  toolResponse: (() => {
247
251
  const output = parseV2ToolExecuteOutput(body);
248
252
  return output
@@ -1182,6 +1186,7 @@ export function createToolExecuteResult<TResult = unknown>(input: {
1182
1186
  metadata: ToolResultMetadataInput;
1183
1187
  execution: ToolResultExecutionMetadata;
1184
1188
  meta?: Record<string, unknown>;
1189
+ billing?: ToolResultBilling;
1185
1190
  response?: {
1186
1191
  rawV2?: unknown;
1187
1192
  view?: 'data' | 'rawV2';
@@ -1238,6 +1243,7 @@ export function createToolExecuteResult<TResult = unknown>(input: {
1238
1243
  status: input.status,
1239
1244
  ...(input.jobId ? { job_id: input.jobId } : {}),
1240
1245
  ...(input.meta ? { meta: input.meta } : {}),
1246
+ ...(input.billing ? { billing: input.billing } : {}),
1241
1247
  toolResponse,
1242
1248
  extractedValues,
1243
1249
  extractedLists,
@@ -1847,6 +1853,7 @@ export function serializeToolExecuteResult(
1847
1853
  status: value.status,
1848
1854
  ...(typeof value.job_id === 'string' ? { job_id: value.job_id } : {}),
1849
1855
  ...(isRecord(value.meta) ? { meta: value.meta } : {}),
1856
+ ...(isRecord(value.billing) ? { billing: value.billing } : {}),
1850
1857
  toolResponse: {
1851
1858
  rawV2,
1852
1859
  view,
@@ -1864,6 +1871,7 @@ export function serializeToolExecuteResult(
1864
1871
  status: value.status,
1865
1872
  ...(typeof value.job_id === 'string' ? { job_id: value.job_id } : {}),
1866
1873
  ...(isRecord(value.meta) ? { meta: value.meta } : {}),
1874
+ ...(isRecord(value.billing) ? { billing: value.billing } : {}),
1867
1875
  toolResponse: {
1868
1876
  raw: serializedRaw,
1869
1877
  ...(value.toolResponse.meta ? { meta: value.toolResponse.meta } : {}),
@@ -1926,6 +1934,7 @@ export function deserializeToolExecuteResult(
1926
1934
  metadata: value.metadata,
1927
1935
  execution: value.execution,
1928
1936
  meta: value.meta,
1937
+ billing: value.billing,
1929
1938
  }),
1930
1939
  value.targetValues,
1931
1940
  ),
@@ -1945,6 +1954,7 @@ export function deserializeToolExecuteResult(
1945
1954
  metadata: value.metadata,
1946
1955
  execution: value.execution,
1947
1956
  meta: value.meta,
1957
+ billing: value.billing,
1948
1958
  }),
1949
1959
  value.targetValues,
1950
1960
  ),
@@ -68,6 +68,7 @@ export type PlayDeploymentDoc = {
68
68
  results?: unknown;
69
69
  buildSeconds?: number;
70
70
  startedAt?: number;
71
+ promotedAt?: number;
71
72
  finishedAt?: number;
72
73
  error?: string;
73
74
  createdAt: number;
@@ -59,6 +59,8 @@ export type SerializedPlayDeployment = {
59
59
  error: string | null;
60
60
  createdAt: number;
61
61
  startedAt: number | null;
62
+ /** Set once the live-pointer flip committed; the status may still be in flight. */
63
+ promotedAt: number | null;
62
64
  finishedAt: number | null;
63
65
  };
64
66
 
@@ -82,6 +84,7 @@ export function serializePlayDeployment(
82
84
  error: deployment.error ?? null,
83
85
  createdAt: deployment.createdAt,
84
86
  startedAt: deployment.startedAt ?? null,
87
+ promotedAt: deployment.promotedAt ?? null,
85
88
  finishedAt: deployment.finishedAt ?? null,
86
89
  };
87
90
  }
@@ -2,6 +2,24 @@ import type { EmailStatusExtractorConfig } from './email-status';
2
2
  import type { DeeplineGetterValueMap } from './extractor-targets';
3
3
  import type { PlayDataset, SerializedPlayDataset } from './dataset';
4
4
 
5
+ /**
6
+ * Customer pricing reported by the execution API, never provider spend.
7
+ * `credits_charged` and `cost_usd` describe the price of the original call;
8
+ * they do not acknowledge durable handoff or wallet posting. Receipt replay
9
+ * preserves this observation and does not imply a new charge or fresher state.
10
+ */
11
+ export type ToolResultBilling = {
12
+ credits_charged?: number;
13
+ cost_usd?: number;
14
+ /** Missing on historical responses. Pending pricing has no final amount. */
15
+ pricing_status?: 'final' | 'pending';
16
+ settlement_status?: 'pending' | 'queued' | 'settled' | 'requires_recovery';
17
+ estimated_credits?: number;
18
+ estimated_cost_usd?: number;
19
+ /** Preserve additive public pricing details across runtime/deployment skew. */
20
+ [key: string]: unknown;
21
+ };
22
+
5
23
  export type ToolResultExecutionMetadata = {
6
24
  idempotent: true;
7
25
  cached: boolean;
@@ -81,6 +99,7 @@ export type SerializedToolExecuteResultV1 = {
81
99
  job_id?: string;
82
100
  /** Deepline-owned execution/result metadata. */
83
101
  meta?: Record<string, unknown>;
102
+ billing?: ToolResultBilling;
84
103
  toolResponse: {
85
104
  /**
86
105
  * Raw provider/tool data with declared row-list payloads clipped to bounded
@@ -139,6 +158,7 @@ export type ToolExecuteResultBase<
139
158
  job_id?: string;
140
159
  /** Deepline-owned execution/result metadata. */
141
160
  meta?: Record<string, unknown>;
161
+ billing?: ToolResultBilling;
142
162
  toolResponse: ToolResponseEnvelope<TResult, TMeta>;
143
163
  extractedValues: Record<string, ToolResultTargetAccessor>;
144
164
  extractedLists: Record<string, ToolResultListAccessor>;
package/dist/cli/index.js CHANGED
@@ -1298,7 +1298,7 @@ var SDK_RELEASE = {
1298
1298
  // getters keep their established compatibility behavior.
1299
1299
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
1300
1300
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
1301
- version: "0.3.110",
1301
+ version: "0.3.112",
1302
1302
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
1303
1303
  packageCapabilities: {
1304
1304
  updatePreferences: 1
@@ -37487,6 +37487,28 @@ async function handleDeploymentGet(id, options) {
37487
37487
  { json: options.json }
37488
37488
  );
37489
37489
  }
37490
+ async function handleDeploymentCancel(id, options) {
37491
+ const { http } = getAuthedHttpClient();
37492
+ const payload = await http.post(`/api/v2/deployments/${encodeURIComponent(id)}/cancel`, {});
37493
+ printCommandEnvelope(
37494
+ {
37495
+ cancelled: payload.cancelled,
37496
+ deployment: payload.deployment,
37497
+ render: {
37498
+ sections: [
37499
+ {
37500
+ title: payload.cancelled ? "cancelled" : "already cancelled",
37501
+ lines: [
37502
+ payload.deployment ? renderDeployment(payload.deployment) : `Deployment ${id} cancelled.`,
37503
+ "The build stops at its next step and nothing from it goes live."
37504
+ ]
37505
+ }
37506
+ ]
37507
+ }
37508
+ },
37509
+ { json: options.json }
37510
+ );
37511
+ }
37490
37512
  function registerGitCommands(program) {
37491
37513
  const git = program.command("git", { hidden: !cliFeatureEnabled(GIT_DEPLOY_FEATURE) }).alias("projects").description(
37492
37514
  "Git deploys: link repositories to this workspace and deploy plays on push."
@@ -37501,6 +37523,7 @@ Examples:
37501
37523
  deepline git set <id> --branch release
37502
37524
  deepline git unlink <id>
37503
37525
  deepline git deployments --repo <id>
37526
+ deepline git cancel <deployment-id>
37504
37527
  `
37505
37528
  );
37506
37529
  git.command("connect").description("Connect a GitHub installation (browser step).").option("--json", "Emit JSON output").action(async (options) => handleConnect(options));
@@ -37541,6 +37564,11 @@ Examples:
37541
37564
  git.command("deployments").description("Deployment history; pass an id for one deployment.").argument("[id]", "Deployment id (omit to list)").option("--repo <id>", "Filter to one repository link").option("--limit <n>", "Max rows (default 50)").option("--json", "Emit JSON output").action(
37542
37565
  async (id, options) => id ? handleDeploymentGet(id, options) : handleDeploymentsList(options)
37543
37566
  );
37567
+ git.command("cancel").description(
37568
+ "Cancel a queued or running deployment before its plays go live (admin)."
37569
+ ).argument("<id>", "Deployment id").option("--json", "Emit JSON output").action(
37570
+ async (id, options) => handleDeploymentCancel(id, options)
37571
+ );
37544
37572
  const deployments = program.command("deployments", { hidden: true });
37545
37573
  deployments.command("list").option("--project <id>", "Filter to one repository link").option("--limit <n>", "Max rows (default 50)").option("--json", "Emit JSON output").action(
37546
37574
  async (options) => handleDeploymentsList({ ...options, repo: options.project })
@@ -1271,7 +1271,7 @@ var SDK_RELEASE = {
1271
1271
  // getters keep their established compatibility behavior.
1272
1272
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
1273
1273
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
1274
- version: "0.3.110",
1274
+ version: "0.3.112",
1275
1275
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
1276
1276
  packageCapabilities: {
1277
1277
  updatePreferences: 1
@@ -37550,6 +37550,28 @@ async function handleDeploymentGet(id, options) {
37550
37550
  { json: options.json }
37551
37551
  );
37552
37552
  }
37553
+ async function handleDeploymentCancel(id, options) {
37554
+ const { http } = getAuthedHttpClient();
37555
+ const payload = await http.post(`/api/v2/deployments/${encodeURIComponent(id)}/cancel`, {});
37556
+ printCommandEnvelope(
37557
+ {
37558
+ cancelled: payload.cancelled,
37559
+ deployment: payload.deployment,
37560
+ render: {
37561
+ sections: [
37562
+ {
37563
+ title: payload.cancelled ? "cancelled" : "already cancelled",
37564
+ lines: [
37565
+ payload.deployment ? renderDeployment(payload.deployment) : `Deployment ${id} cancelled.`,
37566
+ "The build stops at its next step and nothing from it goes live."
37567
+ ]
37568
+ }
37569
+ ]
37570
+ }
37571
+ },
37572
+ { json: options.json }
37573
+ );
37574
+ }
37553
37575
  function registerGitCommands(program) {
37554
37576
  const git = program.command("git", { hidden: !cliFeatureEnabled(GIT_DEPLOY_FEATURE) }).alias("projects").description(
37555
37577
  "Git deploys: link repositories to this workspace and deploy plays on push."
@@ -37564,6 +37586,7 @@ Examples:
37564
37586
  deepline git set <id> --branch release
37565
37587
  deepline git unlink <id>
37566
37588
  deepline git deployments --repo <id>
37589
+ deepline git cancel <deployment-id>
37567
37590
  `
37568
37591
  );
37569
37592
  git.command("connect").description("Connect a GitHub installation (browser step).").option("--json", "Emit JSON output").action(async (options) => handleConnect(options));
@@ -37604,6 +37627,11 @@ Examples:
37604
37627
  git.command("deployments").description("Deployment history; pass an id for one deployment.").argument("[id]", "Deployment id (omit to list)").option("--repo <id>", "Filter to one repository link").option("--limit <n>", "Max rows (default 50)").option("--json", "Emit JSON output").action(
37605
37628
  async (id, options) => id ? handleDeploymentGet(id, options) : handleDeploymentsList(options)
37606
37629
  );
37630
+ git.command("cancel").description(
37631
+ "Cancel a queued or running deployment before its plays go live (admin)."
37632
+ ).argument("<id>", "Deployment id").option("--json", "Emit JSON output").action(
37633
+ async (id, options) => handleDeploymentCancel(id, options)
37634
+ );
37607
37635
  const deployments = program.command("deployments", { hidden: true });
37608
37636
  deployments.command("list").option("--project <id>", "Filter to one repository link").option("--limit <n>", "Max rows (default 50)").option("--json", "Emit JSON output").action(
37609
37637
  async (options) => handleDeploymentsList({ ...options, repo: options.project })