deepline 0.3.102 → 0.3.104

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.102',
203
+ version: '0.3.104',
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: {
@@ -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
  {
@@ -699,6 +750,7 @@ export function presentProductNotification(input: {
699
750
  notificationType: string;
700
751
  payload: ProductNotificationFacts;
701
752
  trigger: ProductNotificationTrigger;
753
+ occurredAt?: number;
702
754
  }): ProductNotificationPresentation {
703
755
  const registration = PRODUCT_NOTIFICATION_TYPE_REGISTRY.find(
704
756
  (candidate) => candidate.id === input.notificationType,
@@ -709,7 +761,11 @@ export function presentProductNotification(input: {
709
761
  `No notification presentation exists for ${input.notificationType}.`,
710
762
  );
711
763
  }
712
- return present({ payload: input.payload, trigger: input.trigger });
764
+ return present({
765
+ payload: input.payload,
766
+ trigger: input.trigger,
767
+ occurredAt: input.occurredAt,
768
+ });
713
769
  }
714
770
 
715
771
  /** 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.102",
1301
+ version: "0.3.104",
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
@@ -42641,24 +42641,27 @@ var CapabilityDescription = class _CapabilityDescription {
42641
42641
  const canonicalUsd = numberValue(
42642
42642
  pricing.usdPerUnit ?? pricing.usd_per_unit
42643
42643
  );
42644
+ const billingSource = stringValue4(
42645
+ this.#catalogEntry.billingSource ?? this.#catalogEntry.billing_source
42646
+ );
42647
+ const billingSourceLabel = stringValue4(
42648
+ this.#catalogEntry.billingSourceLabel ?? this.#catalogEntry.billing_source_label
42649
+ );
42650
+ const isFree = billingSource === "free";
42644
42651
  return {
42645
42652
  pricingModel: pricingModel || null,
42646
42653
  unit: unit || null,
42647
- displayText: stringValue4(pricing.displayText ?? pricing.display_text),
42648
- summary: stringValue4(pricing.summary),
42654
+ displayText: isFree ? "Free" : stringValue4(pricing.displayText ?? pricing.display_text),
42655
+ summary: isFree ? null : stringValue4(pricing.summary),
42649
42656
  billingMode: stringValue4(
42650
42657
  legacyCost.billingMode ?? legacyCost.billing_mode
42651
42658
  ),
42652
- billingSource: stringValue4(
42653
- this.#catalogEntry.billingSource ?? this.#catalogEntry.billing_source
42654
- ),
42655
- billingSourceLabel: stringValue4(
42656
- this.#catalogEntry.billingSourceLabel ?? this.#catalogEntry.billing_source_label
42657
- ),
42658
- deeplineCreditsPerPricingUnit: canonicalCredits ?? numberValue(
42659
+ billingSource,
42660
+ billingSourceLabel,
42661
+ deeplineCreditsPerPricingUnit: isFree ? 0 : canonicalCredits ?? numberValue(
42659
42662
  this.#catalogEntry.deeplineCreditsPerPricingUnit ?? this.#catalogEntry.deepline_credits_per_pricing_unit
42660
42663
  ),
42661
- deeplineUsdPerPricingUnit: canonicalUsd ?? numberValue(
42664
+ deeplineUsdPerPricingUnit: isFree ? 0 : canonicalUsd ?? numberValue(
42662
42665
  this.#catalogEntry.deeplineUsdPerPricingUnit ?? this.#catalogEntry.deepline_usd_per_pricing_unit
42663
42666
  )
42664
42667
  };
@@ -43871,7 +43874,7 @@ function printToolPricingOnly(tool, requestedToolId, options = {}) {
43871
43874
  const contract = toolContractJsonForDescribe(tool, requestedToolId);
43872
43875
  const cost = isRecord12(contract.cost) ? contract.cost : {};
43873
43876
  const pricingModel = stringField2(cost, "pricingModel") || "unknown";
43874
- const billing = stringField2(cost, "billingMode") || stringField2(cost, "billingSourceLabel") || stringField2(cost, "billingSource") || "unknown";
43877
+ const billing = stringField2(cost, "billingSourceLabel") || stringField2(cost, "billingSource") || stringField2(cost, "billingMode") || "unknown";
43875
43878
  const explicitUnit = stringField2(cost, "unit");
43876
43879
  const unit = explicitUnit || (pricingModel === "per_page" ? "page" : pricingModel === "per_result" ? "result" : pricingModel === "fixed" ? "call" : pricingModel.replace(/^per_/, "") || "unit");
43877
43880
  const credits = numberField2(cost, "deeplineCreditsPerPricingUnit");
@@ -44144,6 +44147,9 @@ function listedToolDescription(tool) {
44144
44147
  }
44145
44148
  function formatListedToolCost(tool) {
44146
44149
  const record3 = tool;
44150
+ if (stringField2(record3, "billingSource", "billing_source") === "free") {
44151
+ return "Cost: Free";
44152
+ }
44147
44153
  const pricing = recordField2(record3, "pricing");
44148
44154
  const displayText = stringField2(pricing, "displayText", "display_text");
44149
44155
  return displayText ? `Cost: ${displayText}` : "";
@@ -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.102",
1274
+ version: "0.3.104",
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
@@ -42762,24 +42762,27 @@ var CapabilityDescription = class _CapabilityDescription {
42762
42762
  const canonicalUsd = numberValue(
42763
42763
  pricing.usdPerUnit ?? pricing.usd_per_unit
42764
42764
  );
42765
+ const billingSource = stringValue4(
42766
+ this.#catalogEntry.billingSource ?? this.#catalogEntry.billing_source
42767
+ );
42768
+ const billingSourceLabel = stringValue4(
42769
+ this.#catalogEntry.billingSourceLabel ?? this.#catalogEntry.billing_source_label
42770
+ );
42771
+ const isFree = billingSource === "free";
42765
42772
  return {
42766
42773
  pricingModel: pricingModel || null,
42767
42774
  unit: unit || null,
42768
- displayText: stringValue4(pricing.displayText ?? pricing.display_text),
42769
- summary: stringValue4(pricing.summary),
42775
+ displayText: isFree ? "Free" : stringValue4(pricing.displayText ?? pricing.display_text),
42776
+ summary: isFree ? null : stringValue4(pricing.summary),
42770
42777
  billingMode: stringValue4(
42771
42778
  legacyCost.billingMode ?? legacyCost.billing_mode
42772
42779
  ),
42773
- billingSource: stringValue4(
42774
- this.#catalogEntry.billingSource ?? this.#catalogEntry.billing_source
42775
- ),
42776
- billingSourceLabel: stringValue4(
42777
- this.#catalogEntry.billingSourceLabel ?? this.#catalogEntry.billing_source_label
42778
- ),
42779
- deeplineCreditsPerPricingUnit: canonicalCredits ?? numberValue(
42780
+ billingSource,
42781
+ billingSourceLabel,
42782
+ deeplineCreditsPerPricingUnit: isFree ? 0 : canonicalCredits ?? numberValue(
42780
42783
  this.#catalogEntry.deeplineCreditsPerPricingUnit ?? this.#catalogEntry.deepline_credits_per_pricing_unit
42781
42784
  ),
42782
- deeplineUsdPerPricingUnit: canonicalUsd ?? numberValue(
42785
+ deeplineUsdPerPricingUnit: isFree ? 0 : canonicalUsd ?? numberValue(
42783
42786
  this.#catalogEntry.deeplineUsdPerPricingUnit ?? this.#catalogEntry.deepline_usd_per_pricing_unit
42784
42787
  )
42785
42788
  };
@@ -43992,7 +43995,7 @@ function printToolPricingOnly(tool, requestedToolId, options = {}) {
43992
43995
  const contract = toolContractJsonForDescribe(tool, requestedToolId);
43993
43996
  const cost = isRecord12(contract.cost) ? contract.cost : {};
43994
43997
  const pricingModel = stringField2(cost, "pricingModel") || "unknown";
43995
- const billing = stringField2(cost, "billingMode") || stringField2(cost, "billingSourceLabel") || stringField2(cost, "billingSource") || "unknown";
43998
+ const billing = stringField2(cost, "billingSourceLabel") || stringField2(cost, "billingSource") || stringField2(cost, "billingMode") || "unknown";
43996
43999
  const explicitUnit = stringField2(cost, "unit");
43997
44000
  const unit = explicitUnit || (pricingModel === "per_page" ? "page" : pricingModel === "per_result" ? "result" : pricingModel === "fixed" ? "call" : pricingModel.replace(/^per_/, "") || "unit");
43998
44001
  const credits = numberField2(cost, "deeplineCreditsPerPricingUnit");
@@ -44265,6 +44268,9 @@ function listedToolDescription(tool) {
44265
44268
  }
44266
44269
  function formatListedToolCost(tool) {
44267
44270
  const record3 = tool;
44271
+ if (stringField2(record3, "billingSource", "billing_source") === "free") {
44272
+ return "Cost: Free";
44273
+ }
44268
44274
  const pricing = recordField2(record3, "pricing");
44269
44275
  const displayText = stringField2(pricing, "displayText", "display_text");
44270
44276
  return displayText ? `Cost: ${displayText}` : "";
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.102",
863
+ version: "0.3.104",
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.102",
771
+ version: "0.3.104",
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.102";
152
+ readonly version: "0.3.104";
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.102";
152
+ readonly version: "0.3.104";
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.102",
77
+ version: "0.3.104",
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.102",
51
+ version: "0.3.104",
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.102",
3
+ "version": "0.3.104",
4
4
  "description": "GTM data CLI and TypeScript SDK for coding agents",
5
5
  "license": "MIT",
6
6
  "homepage": "https://code.deepline.com",