deepline 0.3.103 → 0.3.105

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.103',
203
+ version: '0.3.105',
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: {
@@ -32,6 +32,13 @@ export type PlayLaunchQueuePolicy = {
32
32
  sandboxCapacityMaxWaitSeconds: number | null;
33
33
  };
34
34
 
35
+ /**
36
+ * CLI/API launches are user-visible requests. Give a short capacity window so
37
+ * a temporary spike can clear, but never let an interactive run appear to
38
+ * succeed and then start charging much later without an explicit retry.
39
+ */
40
+ export const API_LAUNCH_CAPACITY_WAIT_SECONDS = 60;
41
+
35
42
  export function shouldTerminalizeSandboxCapacityRejection(input: {
36
43
  triggerSource?: PlayLaunchTriggerSource | null;
37
44
  submittedAtMs?: number | null;
@@ -68,13 +75,15 @@ export function resolvePlayLaunchQueuePolicy(
68
75
  case 'api':
69
76
  return {
70
77
  triggerSource: 'api',
71
- // A person waiting in the CLI/UI should get the next slot in their
72
- // own organization rather than sitting behind that org's automation.
73
- // The bounded deadline gives the caller a typed terminal outcome
74
- // instead of an indefinite watch.
78
+ // API/CLI callers need a bounded, user-visible outcome. A brief
79
+ // capacity window absorbs normal spikes; after that the run is
80
+ // terminalized with a typed queue-expired/capacity result rather than
81
+ // starting unexpectedly much later. The priority still lets manual
82
+ // work win the next slot within its organization without bypassing
83
+ // cross-org fairness.
75
84
  priority: 100,
76
- maxDelaySeconds: 10,
77
- sandboxCapacityMaxWaitSeconds: 0,
85
+ maxDelaySeconds: API_LAUNCH_CAPACITY_WAIT_SECONDS,
86
+ sandboxCapacityMaxWaitSeconds: API_LAUNCH_CAPACITY_WAIT_SECONDS,
78
87
  };
79
88
  case 'webhook':
80
89
  return {
@@ -82,8 +91,7 @@ export function resolvePlayLaunchQueuePolicy(
82
91
  priority: 0,
83
92
  // A 202 webhook response is a durable delivery promise. Capacity is
84
93
  // not a delivery failure: retain it until it executes, is explicitly
85
- // cancelled, or an operator terminalizes it. Interactive API launches
86
- // remain separately bounded above.
94
+ // cancelled, or an operator terminalizes it.
87
95
  maxDelaySeconds: null,
88
96
  sandboxCapacityMaxWaitSeconds: null,
89
97
  };
@@ -91,15 +99,21 @@ export function resolvePlayLaunchQueuePolicy(
91
99
  return {
92
100
  triggerSource: 'cron',
93
101
  priority: -10,
94
- maxDelaySeconds: 30 * 60,
95
- sandboxCapacityMaxWaitSeconds: 30 * 60,
102
+ // Scheduled automation is a durable customer intent. A capacity SEV
103
+ // must not silently discard a scheduled run; recovery/alerting owns
104
+ // platform-wide exhaustion and operators can cancel explicitly.
105
+ maxDelaySeconds: null,
106
+ sandboxCapacityMaxWaitSeconds: null,
96
107
  };
97
108
  case 'sql_listener':
98
109
  return {
99
110
  triggerSource: 'sql_listener',
100
111
  priority: -10,
101
- maxDelaySeconds: 30 * 60,
102
- sandboxCapacityMaxWaitSeconds: 30 * 60,
112
+ // SQL-listener automation has the same durable intent contract as
113
+ // cron. Capacity pressure is recoverable state, not a user-visible
114
+ // queue expiry.
115
+ maxDelaySeconds: null,
116
+ sandboxCapacityMaxWaitSeconds: null,
103
117
  };
104
118
  case 'async_child':
105
119
  return {
@@ -322,9 +322,9 @@ const HEARTBEAT_CLAIM_TIMEOUT_SECONDS = RUNTIME_CLAIM_LEASE_SECONDS;
322
322
  export const ABSURD_IDLE_POLL_INTERVAL_SECONDS = 30;
323
323
  /**
324
324
  * A direct LISTEN session is an optional latency optimization. When it is
325
- * unavailable, durable polling must still discover manual/API work before its
326
- * 10-second admission deadline. Keep enough margin for a pooled query, claim,
327
- * and scheduler receipt write.
325
+ * unavailable, durable polling should still discover newly accepted work
326
+ * promptly. Queue admission has source-specific deadlines, so a missed poll
327
+ * may add latency but must not invent a terminal result outside that policy.
328
328
  */
329
329
  export const ABSURD_WAKE_UNAVAILABLE_POLL_INTERVAL_MS = 1_000;
330
330
  /** Heartbeat throttle: keep the lease well ahead of expiry (leaseTimeout / 3). */
@@ -58,6 +58,8 @@ type ProductNotificationTypeCatalogMetadata = {
58
58
  | { kind: 'none' };
59
59
  };
60
60
 
61
+ export type ProductNotificationSeverity = 'success' | 'warning' | 'error';
62
+
61
63
  export type ProductNotificationPresentation = {
62
64
  title: string;
63
65
  summary: NotificationText;
@@ -65,6 +67,7 @@ export type ProductNotificationPresentation = {
65
67
  targetUrl: string;
66
68
  subjectKind: string;
67
69
  subjectId: string;
70
+ severity?: ProductNotificationSeverity;
68
71
  };
69
72
 
70
73
  type ProductNotificationRuleInput = {
@@ -96,6 +99,7 @@ type ProductNotificationRuleDefinition = {
96
99
  present?: (input: {
97
100
  payload: ProductNotificationFacts;
98
101
  trigger: ProductNotificationTrigger;
102
+ occurredAt?: number;
99
103
  }) => ProductNotificationPresentation;
100
104
  };
101
105
 
@@ -124,10 +128,49 @@ function validateFailedOutcome(trigger: ProductNotificationTrigger) {
124
128
  }
125
129
  }
126
130
 
131
+ function formatNotificationDate(value: number) {
132
+ const date = new Date(value);
133
+ return Number.isNaN(date.getTime())
134
+ ? null
135
+ : `${new Intl.DateTimeFormat('en-US', {
136
+ dateStyle: 'medium',
137
+ timeStyle: 'short',
138
+ timeZone: 'UTC',
139
+ }).format(date)} UTC`;
140
+ }
141
+
127
142
  function playRunPresentation(
128
143
  payload: ProductNotificationFacts,
129
144
  succeeded: boolean,
145
+ occurredAt?: number,
146
+ trigger?: ProductNotificationTrigger,
130
147
  ): ProductNotificationPresentation {
148
+ if (!succeeded) {
149
+ const failedAt =
150
+ typeof occurredAt === 'number'
151
+ ? formatNotificationDate(occurredAt)
152
+ : null;
153
+ return {
154
+ title: 'Play failed',
155
+ summary: [
156
+ 'Your play ',
157
+ { strong: String(payload.playName) },
158
+ ' needs attention. Details below.',
159
+ ],
160
+ details: [
161
+ ['Play ', { strong: String(payload.playName) }],
162
+ ...(failedAt ? [['Failed at ', failedAt] as const] : []),
163
+ ...(trigger?.kind === 'consecutive_outcomes'
164
+ ? [['Failures ', String(trigger.count)] as const]
165
+ : []),
166
+ ],
167
+ targetUrl: String(payload.targetUrl),
168
+ subjectKind: 'play',
169
+ subjectId: String(payload.playId),
170
+ severity: 'error',
171
+ };
172
+ }
173
+
131
174
  return {
132
175
  title: succeeded ? 'Play succeeded' : 'Play failed',
133
176
  summary: [
@@ -139,6 +182,7 @@ function playRunPresentation(
139
182
  targetUrl: String(payload.targetUrl),
140
183
  subjectKind: 'play',
141
184
  subjectId: String(payload.playId),
185
+ severity: succeeded ? 'success' : 'error',
142
186
  };
143
187
  }
144
188
 
@@ -157,6 +201,7 @@ function webhookDeliveryPresentation(
157
201
  targetUrl: String(payload.targetUrl),
158
202
  subjectKind: 'webhook',
159
203
  subjectId: String(payload.endpointId),
204
+ severity: succeeded ? 'success' : 'error',
160
205
  };
161
206
  }
162
207
 
@@ -230,6 +275,7 @@ const PRODUCT_NOTIFICATION_TYPE_REGISTRY = [
230
275
  targetUrl: String(payload.targetUrl),
231
276
  subjectKind: 'monitor',
232
277
  subjectId: String(payload.monitorId),
278
+ severity: 'error',
233
279
  }),
234
280
  },
235
281
  },
@@ -277,6 +323,7 @@ const PRODUCT_NOTIFICATION_TYPE_REGISTRY = [
277
323
  targetUrl: String(payload.targetUrl),
278
324
  subjectKind: 'play',
279
325
  subjectId: String(payload.playId),
326
+ severity: 'error',
280
327
  }),
281
328
  },
282
329
  },
@@ -345,6 +392,7 @@ const PRODUCT_NOTIFICATION_TYPE_REGISTRY = [
345
392
  targetUrl: String(payload.targetUrl),
346
393
  subjectKind: 'workspace',
347
394
  subjectId: String(payload.accountId),
395
+ severity: 'error',
348
396
  };
349
397
  },
350
398
  },
@@ -416,6 +464,7 @@ const PRODUCT_NOTIFICATION_TYPE_REGISTRY = [
416
464
  targetUrl: String(payload.targetUrl),
417
465
  subjectKind: 'workspace',
418
466
  subjectId: String(payload.accountId),
467
+ severity: 'warning',
419
468
  };
420
469
  },
421
470
  },
@@ -492,6 +541,7 @@ const PRODUCT_NOTIFICATION_TYPE_REGISTRY = [
492
541
  targetUrl: String(payload.targetUrl),
493
542
  subjectKind: 'workspace',
494
543
  subjectId: String(payload.accountId),
544
+ severity: 'warning',
495
545
  };
496
546
  },
497
547
  },
@@ -533,7 +583,8 @@ const PRODUCT_NOTIFICATION_TYPE_REGISTRY = [
533
583
  };
534
584
  },
535
585
  validate: validateFailedOutcome,
536
- present: ({ payload }) => playRunPresentation(payload, false),
586
+ present: ({ payload, trigger, occurredAt }) =>
587
+ playRunPresentation(payload, false, occurredAt, trigger),
537
588
  },
538
589
  },
539
590
  {
@@ -608,12 +659,16 @@ export type ProductNotificationTypeCatalogItem =
608
659
  export const PRODUCT_NOTIFICATION_MERGED_ROWS: readonly {
609
660
  key: string;
610
661
  name: string;
662
+ /** One sentence for the row, rather than each type's own description. */
663
+ description: string;
611
664
  category: ProductNotificationCategoryId;
612
665
  typeIds: readonly ConfigurableProductNotificationType[];
613
666
  }[] = [
614
667
  {
615
668
  key: 'out-of-credits',
616
669
  name: 'Out of credits',
670
+ description:
671
+ 'Notify when Deepline disables a resource because the workspace ran out of credits. Scheduled runs resume automatically once the workspace has enough credits.',
617
672
  category: 'credits',
618
673
  typeIds: [
619
674
  'monitor.disabled.insufficient_credits',
@@ -699,6 +754,7 @@ export function presentProductNotification(input: {
699
754
  notificationType: string;
700
755
  payload: ProductNotificationFacts;
701
756
  trigger: ProductNotificationTrigger;
757
+ occurredAt?: number;
702
758
  }): ProductNotificationPresentation {
703
759
  const registration = PRODUCT_NOTIFICATION_TYPE_REGISTRY.find(
704
760
  (candidate) => candidate.id === input.notificationType,
@@ -709,7 +765,11 @@ export function presentProductNotification(input: {
709
765
  `No notification presentation exists for ${input.notificationType}.`,
710
766
  );
711
767
  }
712
- return present({ payload: input.payload, trigger: input.trigger });
768
+ return present({
769
+ payload: input.payload,
770
+ trigger: input.trigger,
771
+ occurredAt: input.occurredAt,
772
+ });
713
773
  }
714
774
 
715
775
  /** Return a registered override for condition arming-state scope. */
@@ -31,10 +31,20 @@ type ProductNotificationEmailContent = {
31
31
  summary: NotificationText;
32
32
  details: NotificationText[];
33
33
  targetUrl?: string;
34
+ severity?: 'success' | 'warning' | 'error';
34
35
  };
35
36
 
36
37
  const MAX_RECIPIENTS = 50;
37
38
 
39
+ const SEVERITY_STYLE: Record<
40
+ NonNullable<ProductNotificationEmailContent['severity']>,
41
+ { bg: string; text: string; label: string }
42
+ > = {
43
+ success: { bg: '#ecfdf3', text: '#15803d', label: 'Success' },
44
+ warning: { bg: '#fffbeb', text: '#b45309', label: 'Warning' },
45
+ error: { bg: '#fef2f2', text: '#b91c1c', label: 'Error' },
46
+ };
47
+
38
48
  export function productNotificationEmailAddressVersion(email: string): string {
39
49
  const normalized = normalizeProductNotificationEmail(email);
40
50
  if (!normalized) throw new Error('Notification email address is invalid.');
@@ -81,6 +91,27 @@ function contentHtml(
81
91
  .join('');
82
92
  }
83
93
 
94
+ function detailHtml(
95
+ detail: NotificationText,
96
+ workspaceName: string | undefined,
97
+ borderBottom: boolean,
98
+ ): string {
99
+ const border = borderBottom ? ';border-bottom:1px solid #f0f0f0' : '';
100
+ if (
101
+ Array.isArray(detail) &&
102
+ detail.length === 2 &&
103
+ typeof detail[0] === 'string' &&
104
+ (typeof detail[1] === 'string' ||
105
+ (typeof detail[1] === 'object' &&
106
+ detail[1] !== null &&
107
+ 'strong' in detail[1]))
108
+ ) {
109
+ const value = typeof detail[1] === 'string' ? detail[1] : detail[1].strong;
110
+ return `<table role="presentation" width="100%" cellspacing="0" cellpadding="0"><tr><td style="padding:12px 0${border};font-size:14px;color:#0a0a0a">${escapeHtml(detail[0].trimEnd())}</td><td align="right" style="padding:12px 0${border};font-size:14px;color:#0a0a0a${typeof detail[1] === 'string' ? '' : ';font-weight:600'}">${escapeHtml(value)}</td></tr></table>`;
111
+ }
112
+ return `<p style="margin:0;padding:12px 0${border};font-size:14px;color:#0a0a0a">${contentHtml(detail, workspaceName)}</p>`;
113
+ }
114
+
84
115
  export function renderProductNotificationEmail(
85
116
  input: NotificationWorkspace & {
86
117
  groupKey: string;
@@ -134,38 +165,54 @@ export function renderProductNotificationEmail(
134
165
  notificationText(detail, input.workspaceName),
135
166
  ),
136
167
  '',
137
- `Manage notifications: ${settingsUrl}`,
168
+ `You are receiving this because of your Deepline notification settings: ${settingsUrl}`,
138
169
  ...(optOutUrl
139
170
  ? [`Unsubscribe from ${input.content.groupName} email: ${optOutUrl}`]
140
171
  : []),
141
172
  ].join('\n');
173
+ const severityStyle = input.content.severity
174
+ ? SEVERITY_STYLE[input.content.severity]
175
+ : null;
176
+ const severityBadge = severityStyle
177
+ ? `<span style="display:inline-block;padding:3px 10px;border-radius:999px;background:${severityStyle.bg};color:${severityStyle.text};font-size:12px;font-weight:600;letter-spacing:.02em">${escapeHtml(severityStyle.label)}</span>`
178
+ : '';
179
+ const detailCount = input.content.details.length;
142
180
  const html = [
143
- '<table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="background-color:#fff;color:#111827"><tr><td align="center" style="padding:32px 16px">',
144
- '<table role="presentation" width="600" cellspacing="0" cellpadding="0" style="width:100%;max-width:600px"><tr><td style="font-family:Arial,Helvetica,sans-serif;font-size:16px;line-height:1.5;text-align:left">',
145
- `<a href="${escapeHtml(logoUrl)}"><img src="https://code.deepline.com/brand/logo_full_dark.png" width="140" height="26" alt="Deepline" style="display:block;border:0;margin:0 0 32px"></a>`,
146
- `<h1 style="font-size:24px;line-height:1.25;font-weight:600;letter-spacing:-0.02em;margin:0 0 4px">${escapeHtml(input.content.title)}</h1>`,
147
- '<div style="padding-left:20px">',
148
- `<p style="margin:0 0 4px"><strong>Notification group:</strong> ${escapeHtml(input.content.groupName)}</p>`,
181
+ '<table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="background-color:#ffffff"><tr><td align="center" style="padding:48px 24px">',
182
+ '<table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="max-width:480px"><tr><td style="font-family:-apple-system,BlinkMacSystemFont,\'Segoe UI\',Roboto,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased">',
183
+ '<table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="margin:0 0 40px"><tr>',
184
+ `<td align="left" valign="middle"><a href="${escapeHtml(logoUrl)}" style="display:inline-block;text-decoration:none"><img src="https://code.deepline.com/brand/logo_full_dark.png" width="120" height="auto" alt="Deepline" style="display:block;border:0"></a></td>`,
185
+ `<td align="right" valign="middle">${severityBadge}</td>`,
186
+ '</tr></table>',
187
+ '<p style="margin:0 0 16px">',
188
+ `<span style="font-size:12px;color:#a3a3a3;letter-spacing:.06em;text-transform:uppercase">${escapeHtml(input.content.groupName)}</span>`,
189
+ '</p>',
190
+ `<h1 style="margin:0 0 8px;font-size:22px;font-weight:600;color:#0a0a0a;line-height:1.3;letter-spacing:-0.02em">${escapeHtml(input.content.title)}</h1>`,
191
+ `<p style="margin:0 0 24px;font-size:15px;line-height:1.6;color:#525252">${contentHtml(input.content.summary, input.workspaceName)}</p>`,
192
+ ...(detailCount > 0
193
+ ? [
194
+ '<table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="border:1px solid #e5e5e5;border-radius:10px;margin:0 0 28px"><tr><td style="padding:4px 18px">',
195
+ ...input.content.details.map((detail, index) =>
196
+ detailHtml(detail, input.workspaceName, index < detailCount - 1),
197
+ ),
198
+ '</td></tr></table>',
199
+ ]
200
+ : []),
149
201
  ...(targetUrl
150
202
  ? [
151
- `<p style="margin:0"><a href="${escapeHtml(targetUrl)}" style="color:#1919ff">Open Deepline</a></p>`,
203
+ '<table role="presentation" cellspacing="0" cellpadding="0" style="margin:0 0 32px"><tr>',
204
+ `<td style="background-color:#0a0a0a;border-radius:6px"><a href="${escapeHtml(targetUrl)}" style="display:inline-block;padding:12px 24px;font-size:14px;font-weight:500;color:#ffffff;text-decoration:none">Open Deepline</a></td>`,
205
+ '</tr></table>',
152
206
  ]
153
207
  : []),
154
- '</div>',
155
- '<div style="margin:24px 0;padding:20px;border:1px solid #1919ff;border-radius:8px;color:#111827;font-size:18px;line-height:1.5">',
156
- `<p style="margin:0">${contentHtml(input.content.summary, input.workspaceName)}</p>`,
157
- ...input.content.details.map(
158
- (detail) =>
159
- `<p style="margin:4px 0 0">${contentHtml(detail, input.workspaceName)}</p>`,
160
- ),
161
- '</div>',
162
- '<hr style="border:0;border-top:1px solid #e5e7eb;margin:32px 0 24px">',
163
- `<p style="color:#666;font-size:12px"><a href="${escapeHtml(settingsUrl)}" style="color:#666">Manage notifications</a></p>`,
208
+ '<div style="height:1px;background-color:#e5e5e5;margin:0 0 24px"></div>',
209
+ `<p style="margin:0;color:#a3a3a3;font-size:11px"><a href="${escapeHtml(settingsUrl)}" style="color:#a3a3a3;text-decoration:underline">You are receiving this because of your Deepline notification settings.</a>`,
164
210
  ...(optOutUrl
165
211
  ? [
166
- `<p style="color:#666;font-size:12px"><a href="${escapeHtml(optOutUrl)}">Unsubscribe from ${escapeHtml(input.content.groupName)} email</a></p>`,
212
+ `&nbsp;&middot;&nbsp;<a href="${escapeHtml(optOutUrl)}" style="color:#a3a3a3;text-decoration:underline">Unsubscribe from ${escapeHtml(input.content.groupName)} email</a>`,
167
213
  ]
168
214
  : []),
215
+ '</p>',
169
216
  '</td></tr></table></td></tr></table>',
170
217
  ].join('');
171
218
 
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.103",
1301
+ version: "0.3.105",
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
@@ -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.103",
1274
+ version: "0.3.105",
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
package/dist/index.d.mts CHANGED
@@ -359,6 +359,7 @@ type ProductNotificationTypeCatalogMetadata = {
359
359
  kind: 'none';
360
360
  };
361
361
  };
362
+ type ProductNotificationSeverity = 'success' | 'warning' | 'error';
362
363
  type ProductNotificationPresentation = {
363
364
  title: string;
364
365
  summary: NotificationText;
@@ -366,6 +367,7 @@ type ProductNotificationPresentation = {
366
367
  targetUrl: string;
367
368
  subjectKind: string;
368
369
  subjectId: string;
370
+ severity?: ProductNotificationSeverity;
369
371
  };
370
372
  type ProductNotificationRuleInput = {
371
373
  ruleKey: string;
@@ -417,6 +419,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
417
419
  readonly present: ({ payload }: {
418
420
  payload: ProductNotificationFacts;
419
421
  trigger: ProductNotificationTrigger;
422
+ occurredAt?: number;
420
423
  }) => {
421
424
  title: string;
422
425
  summary: (string | {
@@ -426,6 +429,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
426
429
  targetUrl: string;
427
430
  subjectKind: string;
428
431
  subjectId: string;
432
+ severity: "error";
429
433
  };
430
434
  };
431
435
  }, {
@@ -471,6 +475,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
471
475
  readonly present: ({ payload }: {
472
476
  payload: ProductNotificationFacts;
473
477
  trigger: ProductNotificationTrigger;
478
+ occurredAt?: number;
474
479
  }) => {
475
480
  title: string;
476
481
  summary: (string | {
@@ -480,6 +485,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
480
485
  targetUrl: string;
481
486
  subjectKind: string;
482
487
  subjectId: string;
488
+ severity: "error";
483
489
  };
484
490
  };
485
491
  }, {
@@ -522,6 +528,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
522
528
  readonly present: ({ payload }: {
523
529
  payload: ProductNotificationFacts;
524
530
  trigger: ProductNotificationTrigger;
531
+ occurredAt?: number;
525
532
  }) => {
526
533
  title: string;
527
534
  summary: (string | {
@@ -533,6 +540,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
533
540
  targetUrl: string;
534
541
  subjectKind: string;
535
542
  subjectId: string;
543
+ severity: "error";
536
544
  };
537
545
  };
538
546
  }, {
@@ -598,6 +606,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
598
606
  readonly present: ({ payload, trigger }: {
599
607
  payload: ProductNotificationFacts;
600
608
  trigger: ProductNotificationTrigger;
609
+ occurredAt?: number;
601
610
  }) => {
602
611
  title: string;
603
612
  summary: (string | {
@@ -609,6 +618,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
609
618
  targetUrl: string;
610
619
  subjectKind: string;
611
620
  subjectId: string;
621
+ severity: "warning";
612
622
  };
613
623
  };
614
624
  }, {
@@ -673,6 +683,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
673
683
  readonly present: ({ payload, trigger }: {
674
684
  payload: ProductNotificationFacts;
675
685
  trigger: ProductNotificationTrigger;
686
+ occurredAt?: number;
676
687
  }) => {
677
688
  title: string;
678
689
  summary: (string | {
@@ -684,6 +695,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
684
695
  targetUrl: string;
685
696
  subjectKind: string;
686
697
  subjectId: string;
698
+ severity: "warning";
687
699
  };
688
700
  };
689
701
  }, {
@@ -726,9 +738,10 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
726
738
  eventName: string;
727
739
  };
728
740
  readonly validate: typeof validateFailedOutcome;
729
- readonly present: ({ payload }: {
741
+ readonly present: ({ payload, trigger, occurredAt }: {
730
742
  payload: ProductNotificationFacts;
731
743
  trigger: ProductNotificationTrigger;
744
+ occurredAt?: number;
732
745
  }) => ProductNotificationPresentation;
733
746
  };
734
747
  }, {
@@ -764,6 +777,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
764
777
  readonly present: ({ payload }: {
765
778
  payload: ProductNotificationFacts;
766
779
  trigger: ProductNotificationTrigger;
780
+ occurredAt?: number;
767
781
  }) => ProductNotificationPresentation;
768
782
  };
769
783
  }, {
@@ -779,6 +793,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
779
793
  readonly present: ({ payload }: {
780
794
  payload: ProductNotificationFacts;
781
795
  trigger: ProductNotificationTrigger;
796
+ occurredAt?: number;
782
797
  }) => ProductNotificationPresentation;
783
798
  };
784
799
  }, {
@@ -793,6 +808,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
793
808
  readonly present: ({ payload }: {
794
809
  payload: ProductNotificationFacts;
795
810
  trigger: ProductNotificationTrigger;
811
+ occurredAt?: number;
796
812
  }) => ProductNotificationPresentation;
797
813
  };
798
814
  }];
package/dist/index.d.ts CHANGED
@@ -359,6 +359,7 @@ type ProductNotificationTypeCatalogMetadata = {
359
359
  kind: 'none';
360
360
  };
361
361
  };
362
+ type ProductNotificationSeverity = 'success' | 'warning' | 'error';
362
363
  type ProductNotificationPresentation = {
363
364
  title: string;
364
365
  summary: NotificationText;
@@ -366,6 +367,7 @@ type ProductNotificationPresentation = {
366
367
  targetUrl: string;
367
368
  subjectKind: string;
368
369
  subjectId: string;
370
+ severity?: ProductNotificationSeverity;
369
371
  };
370
372
  type ProductNotificationRuleInput = {
371
373
  ruleKey: string;
@@ -417,6 +419,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
417
419
  readonly present: ({ payload }: {
418
420
  payload: ProductNotificationFacts;
419
421
  trigger: ProductNotificationTrigger;
422
+ occurredAt?: number;
420
423
  }) => {
421
424
  title: string;
422
425
  summary: (string | {
@@ -426,6 +429,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
426
429
  targetUrl: string;
427
430
  subjectKind: string;
428
431
  subjectId: string;
432
+ severity: "error";
429
433
  };
430
434
  };
431
435
  }, {
@@ -471,6 +475,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
471
475
  readonly present: ({ payload }: {
472
476
  payload: ProductNotificationFacts;
473
477
  trigger: ProductNotificationTrigger;
478
+ occurredAt?: number;
474
479
  }) => {
475
480
  title: string;
476
481
  summary: (string | {
@@ -480,6 +485,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
480
485
  targetUrl: string;
481
486
  subjectKind: string;
482
487
  subjectId: string;
488
+ severity: "error";
483
489
  };
484
490
  };
485
491
  }, {
@@ -522,6 +528,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
522
528
  readonly present: ({ payload }: {
523
529
  payload: ProductNotificationFacts;
524
530
  trigger: ProductNotificationTrigger;
531
+ occurredAt?: number;
525
532
  }) => {
526
533
  title: string;
527
534
  summary: (string | {
@@ -533,6 +540,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
533
540
  targetUrl: string;
534
541
  subjectKind: string;
535
542
  subjectId: string;
543
+ severity: "error";
536
544
  };
537
545
  };
538
546
  }, {
@@ -598,6 +606,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
598
606
  readonly present: ({ payload, trigger }: {
599
607
  payload: ProductNotificationFacts;
600
608
  trigger: ProductNotificationTrigger;
609
+ occurredAt?: number;
601
610
  }) => {
602
611
  title: string;
603
612
  summary: (string | {
@@ -609,6 +618,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
609
618
  targetUrl: string;
610
619
  subjectKind: string;
611
620
  subjectId: string;
621
+ severity: "warning";
612
622
  };
613
623
  };
614
624
  }, {
@@ -673,6 +683,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
673
683
  readonly present: ({ payload, trigger }: {
674
684
  payload: ProductNotificationFacts;
675
685
  trigger: ProductNotificationTrigger;
686
+ occurredAt?: number;
676
687
  }) => {
677
688
  title: string;
678
689
  summary: (string | {
@@ -684,6 +695,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
684
695
  targetUrl: string;
685
696
  subjectKind: string;
686
697
  subjectId: string;
698
+ severity: "warning";
687
699
  };
688
700
  };
689
701
  }, {
@@ -726,9 +738,10 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
726
738
  eventName: string;
727
739
  };
728
740
  readonly validate: typeof validateFailedOutcome;
729
- readonly present: ({ payload }: {
741
+ readonly present: ({ payload, trigger, occurredAt }: {
730
742
  payload: ProductNotificationFacts;
731
743
  trigger: ProductNotificationTrigger;
744
+ occurredAt?: number;
732
745
  }) => ProductNotificationPresentation;
733
746
  };
734
747
  }, {
@@ -764,6 +777,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
764
777
  readonly present: ({ payload }: {
765
778
  payload: ProductNotificationFacts;
766
779
  trigger: ProductNotificationTrigger;
780
+ occurredAt?: number;
767
781
  }) => ProductNotificationPresentation;
768
782
  };
769
783
  }, {
@@ -779,6 +793,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
779
793
  readonly present: ({ payload }: {
780
794
  payload: ProductNotificationFacts;
781
795
  trigger: ProductNotificationTrigger;
796
+ occurredAt?: number;
782
797
  }) => ProductNotificationPresentation;
783
798
  };
784
799
  }, {
@@ -793,6 +808,7 @@ declare const PRODUCT_NOTIFICATION_TYPE_REGISTRY: readonly [{
793
808
  readonly present: ({ payload }: {
794
809
  payload: ProductNotificationFacts;
795
810
  trigger: ProductNotificationTrigger;
811
+ occurredAt?: number;
796
812
  }) => ProductNotificationPresentation;
797
813
  };
798
814
  }];
package/dist/index.js CHANGED
@@ -860,7 +860,7 @@ var SDK_RELEASE = {
860
860
  // getters keep their established compatibility behavior.
861
861
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
862
862
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
863
- version: "0.3.103",
863
+ version: "0.3.105",
864
864
  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.",
865
865
  packageCapabilities: {
866
866
  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.103",
771
+ version: "0.3.105",
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.103";
152
+ readonly version: "0.3.105";
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.103";
152
+ readonly version: "0.3.105";
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.103",
77
+ version: "0.3.105",
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.103",
51
+ version: "0.3.105",
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.103",
3
+ "version": "0.3.105",
4
4
  "description": "GTM data CLI and TypeScript SDK for coding agents",
5
5
  "license": "MIT",
6
6
  "homepage": "https://code.deepline.com",