deepline 0.3.129 → 0.3.130

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.
@@ -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.129',
203
+ version: '0.3.130',
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: {
@@ -1,4 +1,5 @@
1
1
  import { withRuntimeSchedulerClient } from './/scheduler-backends/postgres-pool';
2
+ import { RUNTIME_CAPACITY_POLICY } from './/runtime-capacity-policy';
2
3
  import { isIsolatedRuntimeSchedulerSchema } from './/runtime-scheduler-topology';
3
4
 
4
5
  /** A single controller owns this fleet-wide sweep. Workers clean resources for
@@ -60,7 +61,9 @@ export function startDaytonaSandboxJanitor(
60
61
  {
61
62
  url: options.url,
62
63
  applicationName: 'deepline-daytona-janitor',
63
- maxClients: options.maxClients ?? 2,
64
+ maxClients:
65
+ options.maxClients ??
66
+ RUNTIME_CAPACITY_POLICY.runtimePostgres.schedulerPoolMaxClients,
64
67
  },
65
68
  (client) =>
66
69
  reapOrphanDaytonaSandboxes({
@@ -7,11 +7,15 @@
7
7
  * and tests cannot independently invent concurrency or timeout budgets.
8
8
  */
9
9
  export const RUNTIME_CAPACITY_POLICY = {
10
+ runtimePostgres: {
11
+ /** One process-local scheduler pool budget for every control-plane lane. */
12
+ schedulerPoolMaxClients: 2,
13
+ },
10
14
  absurd: {
11
15
  /** Warm floor for availability and deploy rollovers. */
12
16
  activeLaneMachines: 2,
13
- /** 32 Machines x 8 claim slots permits 256 concurrent launch/resume legs. */
14
- maxActiveLaneMachines: 32,
17
+ /** Keep worker pools and direct wake listeners below the shared DB budget. */
18
+ maxActiveLaneMachines: 8,
15
19
  workerSlotsPerMachine: 8,
16
20
  /** React within one control interval when a due backlog is not draining. */
17
21
  scaleUpQueueAgeMs: 1_000,
@@ -174,6 +178,16 @@ function nonNegativeNumber(value: number): number {
174
178
  }
175
179
 
176
180
  export function assertRuntimeCapacityPolicy(): void {
181
+ if (
182
+ !Number.isInteger(
183
+ RUNTIME_CAPACITY_POLICY.runtimePostgres.schedulerPoolMaxClients,
184
+ ) ||
185
+ RUNTIME_CAPACITY_POLICY.runtimePostgres.schedulerPoolMaxClients < 1
186
+ ) {
187
+ throw new Error(
188
+ 'Runtime scheduler pool client cap must be a positive integer.',
189
+ );
190
+ }
177
191
  if (
178
192
  !Number.isInteger(
179
193
  RUNTIME_CAPACITY_POLICY.sandboxAcquisition
@@ -75,6 +75,23 @@ export type AbsurdSchedulerBackendOptions = AbsurdSchedulerOptions & {
75
75
  queueSuffix?: string | null;
76
76
  };
77
77
 
78
+ const cancellationFlights = new Map<string, Promise<void>>();
79
+
80
+ function runCancellationSingleFlight(
81
+ key: string,
82
+ operation: () => Promise<void>,
83
+ ): Promise<void> {
84
+ const existing = cancellationFlights.get(key);
85
+ if (existing) return existing;
86
+ const flight = operation().finally(() => {
87
+ if (cancellationFlights.get(key) === flight) {
88
+ cancellationFlights.delete(key);
89
+ }
90
+ });
91
+ cancellationFlights.set(key, flight);
92
+ return flight;
93
+ }
94
+
78
95
  function recordAbsurdSubmitPhase(
79
96
  input: Pick<PlaySchedulerSubmitInput, 'runId' | 'playName' | 'graphHash'>,
80
97
  phase: string,
@@ -133,6 +150,7 @@ function absurdRunHandle(input: {
133
150
  const releaseId =
134
151
  input.releaseId?.trim() || absurdReleaseIdForSuffix(input.queueSuffix);
135
152
  const runsQueue = absurdQueueNameForRelease(releaseId);
153
+ const cancellationKey = `${poolOptions.url}::${effectiveOptions.schema ?? ''}::${input.runId}`;
136
154
 
137
155
  const cancelAbsurdTask = async () => {
138
156
  const taskId = await withRuntimeSchedulerClient(poolOptions, (client) =>
@@ -230,17 +248,19 @@ function absurdRunHandle(input: {
230
248
  runId: input.runId,
231
249
  initialState: input.initialState ?? undefined,
232
250
  cancel: async () => {
233
- const cleanup = cleanupPersistedRuntimeSandboxes();
234
- await Promise.all([delegate.cancel(), cancelAbsurdTask(), cleanup]);
251
+ await runCancellationSingleFlight(cancellationKey, async () => {
252
+ await delegate.cancel();
253
+ await cancelAbsurdTask();
254
+ await cleanupPersistedRuntimeSandboxes();
255
+ });
235
256
  },
236
257
  signal: async (payload) => {
237
258
  if (payload.kind === 'cancel') {
238
- const cleanup = cleanupPersistedRuntimeSandboxes();
239
- await Promise.all([
240
- delegate.signal(payload),
241
- cancelAbsurdTask(),
242
- cleanup,
243
- ]);
259
+ await runCancellationSingleFlight(cancellationKey, async () => {
260
+ await delegate.signal(payload);
261
+ await cancelAbsurdTask();
262
+ await cleanupPersistedRuntimeSandboxes();
263
+ });
244
264
  return;
245
265
  }
246
266
  if (payload.kind !== 'integration_event' || !payload.eventKey) {
@@ -33,6 +33,7 @@ import {
33
33
  PLAY_ADMISSION_MAX_ACQUIRE_QUEUE_WAIT_MS,
34
34
  } from '../admission-transport-policy';
35
35
  import { RUNTIME_RELIABILITY_POLICY } from '../runtime-reliability-policy';
36
+ import { RUNTIME_CAPACITY_POLICY } from '../runtime-capacity-policy';
36
37
  export {
37
38
  isRuntimeSchedulerCapacityError,
38
39
  parseRuntimeSchedulerCapacityError,
@@ -126,8 +127,8 @@ export function assertRuntimeSchedulerHotPathUrl(url: string): void {
126
127
  }
127
128
 
128
129
  export const RUNTIME_SCHEDULER_POOL_DEFAULTS = {
129
- /** Per-process client cap. Workers override via options; keep small on serverless. */
130
- maxClients: 8,
130
+ /** One shared per-process client cap for scheduler control-plane lanes. */
131
+ maxClients: RUNTIME_CAPACITY_POLICY.runtimePostgres.schedulerPoolMaxClients,
131
132
  /** Refuse to construct a pool above this — protects the shared PgBouncer/Postgres. */
132
133
  maxClientsHardCap: 32,
133
134
  /** Max time a caller waits for a pooled connection before erroring. */
@@ -163,7 +164,11 @@ export const RUNTIME_SCHEDULER_POOL_DEFAULTS = {
163
164
  * once. This shared cap keeps horizontally scaled workers and the receipt
164
165
  * gateway from consuming PgBouncer's global client budget independently.
165
166
  */
166
- export const RUNTIME_SCHEDULER_CONTROL_PLANE_MAX_CLIENTS = 2;
167
+ export const RUNTIME_SCHEDULER_CONTROL_PLANE_MAX_CLIENTS =
168
+ RUNTIME_CAPACITY_POLICY.runtimePostgres.schedulerPoolMaxClients;
169
+
170
+ export const RUNTIME_SCHEDULER_CANCEL_LOCK_TIMEOUT_MS = 2_000;
171
+ export const RUNTIME_SCHEDULER_CANCEL_STATEMENT_TIMEOUT_MS = 15_000;
167
172
 
168
173
  export type RuntimeSchedulerPoolOptions = {
169
174
  url: string;
@@ -188,6 +193,11 @@ export type RuntimeSchedulerPoolOptions = {
188
193
  maxAcquireQueueWaitMs?: number;
189
194
  };
190
195
 
196
+ export type RuntimeSchedulerOperationOptions = {
197
+ signal?: AbortSignal;
198
+ maxAttempts?: number;
199
+ };
200
+
191
201
  export type RuntimeSchedulerQueryClient = {
192
202
  query<Row extends Record<string, unknown> = Record<string, unknown>>(
193
203
  sql: string,
@@ -195,6 +205,22 @@ export type RuntimeSchedulerQueryClient = {
195
205
  ): Promise<{ rows: Row[] }>;
196
206
  };
197
207
 
208
+ export function isRuntimeSchedulerQueryCancellationError(
209
+ error: unknown,
210
+ ): boolean {
211
+ if (!error || typeof error !== 'object') return false;
212
+ if ((error as { code?: unknown }).code === '57014') return true;
213
+ const name = (error as { name?: unknown }).name;
214
+ if (name === 'TimeoutError' || name === 'AbortError') return true;
215
+ const message = (error as { message?: unknown }).message;
216
+ return (
217
+ typeof message === 'string' &&
218
+ /(?:statement timeout|canceling statement due to user request|query read timeout)/i.test(
219
+ message,
220
+ )
221
+ );
222
+ }
223
+
198
224
  export class RuntimeSchedulerCircuitOpenError extends Error {
199
225
  readonly code = 'RUNTIME_SCHEDULER_UNAVAILABLE';
200
226
 
@@ -738,11 +764,21 @@ export async function withRuntimeSchedulerClient<T>(
738
764
  phase: string;
739
765
  priority?: RuntimeSchedulerPoolPriority;
740
766
  },
741
- operationOptions: { signal?: AbortSignal } = {},
767
+ operationOptions: RuntimeSchedulerOperationOptions = {},
742
768
  ): Promise<T> {
743
769
  const signal = operationOptions.signal;
744
770
  throwIfSchedulerAborted(signal);
745
771
  const entry = getPoolEntry(options);
772
+ const maxAttempts = Math.max(
773
+ 1,
774
+ Math.min(
775
+ RUNTIME_SCHEDULER_POOL_DEFAULTS.retry.attempts,
776
+ Math.floor(
777
+ operationOptions.maxAttempts ??
778
+ RUNTIME_SCHEDULER_POOL_DEFAULTS.retry.attempts,
779
+ ),
780
+ ),
781
+ );
746
782
  const operationStartedAt = performance.now();
747
783
  const admissionStartedAt = performance.now();
748
784
  const releaseAdmission = await entry.admission.acquire(
@@ -753,11 +789,7 @@ export async function withRuntimeSchedulerClient<T>(
753
789
  let lastError: unknown = null;
754
790
  try {
755
791
  throwIfSchedulerAborted(signal);
756
- for (
757
- let attempt = 0;
758
- attempt < RUNTIME_SCHEDULER_POOL_DEFAULTS.retry.attempts;
759
- attempt += 1
760
- ) {
792
+ for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
761
793
  throwIfSchedulerAborted(signal);
762
794
  breakerGate(entry);
763
795
  if (entry.pool.waitingCount >= entry.maxAcquireQueueDepth) {
@@ -796,7 +828,7 @@ export async function withRuntimeSchedulerClient<T>(
796
828
  recordBreakerFailure(entry, error);
797
829
  entry.stats.connectionErrors += 1;
798
830
  lastError = error;
799
- if (attempt + 1 < RUNTIME_SCHEDULER_POOL_DEFAULTS.retry.attempts) {
831
+ if (attempt + 1 < maxAttempts) {
800
832
  entry.stats.retries += 1;
801
833
  await sleep(jitteredBackoffMs(attempt));
802
834
  throwIfSchedulerAborted(signal);
@@ -846,9 +878,18 @@ export async function withRuntimeSchedulerClient<T>(
846
878
  const queryStartedAt = performance.now();
847
879
  queryCount += 1;
848
880
  try {
849
- const queryResult = await poolClient.query(sql, params);
850
- throwIfSchedulerAborted(signal);
851
- return { rows: queryResult.rows };
881
+ try {
882
+ const queryResult = await poolClient.query(sql, params);
883
+ throwIfSchedulerAborted(signal);
884
+ return { rows: queryResult.rows };
885
+ } catch (error) {
886
+ if (isRuntimeSchedulerQueryCancellationError(error)) {
887
+ releasePoolClient(
888
+ error instanceof Error ? error : new Error(String(error)),
889
+ );
890
+ }
891
+ throw error;
892
+ }
852
893
  } finally {
853
894
  queryMs += performance.now() - queryStartedAt;
854
895
  }
@@ -914,6 +955,14 @@ export async function withRuntimeSchedulerClient<T>(
914
955
  error instanceof Error ? error.message : String(error),
915
956
  );
916
957
  }
958
+ if (isRuntimeSchedulerQueryCancellationError(error)) {
959
+ entry.stats.queryErrors += 1;
960
+ recordBreakerSuccess(entry);
961
+ releasePoolClient(
962
+ error instanceof Error ? error : new Error(String(error)),
963
+ );
964
+ throw error;
965
+ }
917
966
  if (isConnectionCategoryError(error)) {
918
967
  recordBreakerFailure(entry, error);
919
968
  entry.stats.connectionErrors += 1;
@@ -922,7 +971,7 @@ export async function withRuntimeSchedulerClient<T>(
922
971
  releasePoolClient(
923
972
  error instanceof Error ? error : new Error(String(error)),
924
973
  );
925
- if (attempt + 1 < RUNTIME_SCHEDULER_POOL_DEFAULTS.retry.attempts) {
974
+ if (attempt + 1 < maxAttempts) {
926
975
  entry.stats.retries += 1;
927
976
  await sleep(jitteredBackoffMs(attempt));
928
977
  throwIfSchedulerAborted(signal);
@@ -940,7 +989,7 @@ export async function withRuntimeSchedulerClient<T>(
940
989
  releasePoolClient(
941
990
  error instanceof Error ? error : new Error(String(error)),
942
991
  );
943
- if (attempt + 1 < RUNTIME_SCHEDULER_POOL_DEFAULTS.retry.attempts) {
992
+ if (attempt + 1 < maxAttempts) {
944
993
  entry.stats.retries += 1;
945
994
  await sleep(jitteredBackoffMs(attempt));
946
995
  throwIfSchedulerAborted(signal);
@@ -964,6 +1013,47 @@ export async function withRuntimeSchedulerClient<T>(
964
1013
  }
965
1014
  }
966
1015
 
1016
+ export async function withRuntimeSchedulerTransaction<T>(
1017
+ options: RuntimeSchedulerPoolOptions,
1018
+ timeouts: { lockTimeoutMs: number; statementTimeoutMs: number },
1019
+ fn: (client: RuntimeSchedulerQueryClient) => Promise<T>,
1020
+ trace?: {
1021
+ runId: string;
1022
+ phase: string;
1023
+ priority?: RuntimeSchedulerPoolPriority;
1024
+ },
1025
+ operationOptions: RuntimeSchedulerOperationOptions = {},
1026
+ ): Promise<T> {
1027
+ const lockTimeoutMs = Math.max(1, Math.floor(timeouts.lockTimeoutMs));
1028
+ const statementTimeoutMs = Math.max(
1029
+ lockTimeoutMs,
1030
+ Math.floor(timeouts.statementTimeoutMs),
1031
+ );
1032
+ return withRuntimeSchedulerClient(
1033
+ options,
1034
+ async (client) => {
1035
+ await client.query('BEGIN');
1036
+ try {
1037
+ await client.query(
1038
+ `SELECT set_config('lock_timeout', $1, true),
1039
+ set_config('statement_timeout', $2, true)`,
1040
+ [`${lockTimeoutMs}ms`, `${statementTimeoutMs}ms`],
1041
+ );
1042
+ const result = await fn(client);
1043
+ await client.query('COMMIT');
1044
+ return result;
1045
+ } catch (error) {
1046
+ if (!isRuntimeSchedulerQueryCancellationError(error)) {
1047
+ await client.query('ROLLBACK').catch(() => undefined);
1048
+ }
1049
+ throw error;
1050
+ }
1051
+ },
1052
+ trace,
1053
+ { ...operationOptions, maxAttempts: operationOptions.maxAttempts ?? 1 },
1054
+ );
1055
+ }
1056
+
967
1057
  export type RuntimeSchedulerPoolStats = {
968
1058
  url: string;
969
1059
  maxClients: number;
@@ -6,6 +6,9 @@ import {
6
6
  acquirePgNotifyHub,
7
7
  resolveWorkflowRuntimePostgresUrl,
8
8
  withRuntimeSchedulerClient,
9
+ withRuntimeSchedulerTransaction,
10
+ RUNTIME_SCHEDULER_CANCEL_LOCK_TIMEOUT_MS,
11
+ RUNTIME_SCHEDULER_CANCEL_STATEMENT_TIMEOUT_MS,
9
12
  type PgNotifyHub,
10
13
  type PgNotifyHubState,
11
14
  type RuntimeSchedulerPoolOptions,
@@ -16974,15 +16977,27 @@ export function postgresSchedulerRunHandle(
16974
16977
  },
16975
16978
  cancel: async () => {
16976
16979
  const poolOptions = resolve();
16977
- await withRuntimeSchedulerClient(poolOptions, (client) =>
16978
- cancelPostgresSchedulerRun(client, { runId }, options),
16980
+ await withRuntimeSchedulerTransaction(
16981
+ poolOptions,
16982
+ {
16983
+ lockTimeoutMs: RUNTIME_SCHEDULER_CANCEL_LOCK_TIMEOUT_MS,
16984
+ statementTimeoutMs: RUNTIME_SCHEDULER_CANCEL_STATEMENT_TIMEOUT_MS,
16985
+ },
16986
+ (client) => cancelPostgresSchedulerRun(client, { runId }, options),
16987
+ { runId, phase: 'cancel_run', priority: 'critical' },
16979
16988
  );
16980
16989
  },
16981
16990
  signal: async (payload) => {
16982
16991
  if (payload.kind === 'cancel') {
16983
16992
  const poolOptions = resolve();
16984
- await withRuntimeSchedulerClient(poolOptions, (client) =>
16985
- cancelPostgresSchedulerRun(client, { runId }, options),
16993
+ await withRuntimeSchedulerTransaction(
16994
+ poolOptions,
16995
+ {
16996
+ lockTimeoutMs: RUNTIME_SCHEDULER_CANCEL_LOCK_TIMEOUT_MS,
16997
+ statementTimeoutMs: RUNTIME_SCHEDULER_CANCEL_STATEMENT_TIMEOUT_MS,
16998
+ },
16999
+ (client) => cancelPostgresSchedulerRun(client, { runId }, options),
17000
+ { runId, phase: 'cancel_run', priority: 'critical' },
16986
17001
  );
16987
17002
  return;
16988
17003
  }
package/dist/cli/index.js CHANGED
@@ -3068,7 +3068,7 @@ var SDK_RELEASE = {
3068
3068
  // getters keep their established compatibility behavior.
3069
3069
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3070
3070
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3071
- version: "0.3.129",
3071
+ version: "0.3.130",
3072
3072
  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.",
3073
3073
  packageCapabilities: {
3074
3074
  updatePreferences: 1
@@ -3063,7 +3063,7 @@ var SDK_RELEASE = {
3063
3063
  // getters keep their established compatibility behavior.
3064
3064
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3065
3065
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3066
- version: "0.3.129",
3066
+ version: "0.3.130",
3067
3067
  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.",
3068
3068
  packageCapabilities: {
3069
3069
  updatePreferences: 1
package/dist/index.js CHANGED
@@ -864,7 +864,7 @@ var SDK_RELEASE = {
864
864
  // getters keep their established compatibility behavior.
865
865
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
866
866
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
867
- version: "0.3.129",
867
+ version: "0.3.130",
868
868
  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.",
869
869
  packageCapabilities: {
870
870
  updatePreferences: 1
package/dist/index.mjs CHANGED
@@ -768,7 +768,7 @@ var SDK_RELEASE = {
768
768
  // getters keep their established compatibility behavior.
769
769
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
770
770
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
771
- version: "0.3.129",
771
+ version: "0.3.130",
772
772
  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.",
773
773
  packageCapabilities: {
774
774
  updatePreferences: 1
@@ -149,7 +149,7 @@ type SdkRelease = {
149
149
  supportPolicy: SdkSupportPolicy;
150
150
  };
151
151
  declare const SDK_RELEASE: {
152
- readonly version: "0.3.129";
152
+ readonly version: "0.3.130";
153
153
  readonly 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.";
154
154
  readonly packageCapabilities: {
155
155
  readonly updatePreferences: 1;
package/dist/release.d.ts CHANGED
@@ -149,7 +149,7 @@ type SdkRelease = {
149
149
  supportPolicy: SdkSupportPolicy;
150
150
  };
151
151
  declare const SDK_RELEASE: {
152
- readonly version: "0.3.129";
152
+ readonly version: "0.3.130";
153
153
  readonly 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.";
154
154
  readonly packageCapabilities: {
155
155
  readonly updatePreferences: 1;
package/dist/release.js CHANGED
@@ -74,7 +74,7 @@ var SDK_RELEASE = {
74
74
  // getters keep their established compatibility behavior.
75
75
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
76
76
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
77
- version: "0.3.129",
77
+ version: "0.3.130",
78
78
  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.",
79
79
  packageCapabilities: {
80
80
  updatePreferences: 1
package/dist/release.mjs CHANGED
@@ -48,7 +48,7 @@ var SDK_RELEASE = {
48
48
  // getters keep their established compatibility behavior.
49
49
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
50
50
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
51
- version: "0.3.129",
51
+ version: "0.3.130",
52
52
  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.",
53
53
  packageCapabilities: {
54
54
  updatePreferences: 1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepline",
3
- "version": "0.3.129",
3
+ "version": "0.3.130",
4
4
  "description": "GTM data CLI and TypeScript SDK for coding agents",
5
5
  "license": "MIT",
6
6
  "homepage": "https://code.deepline.com",