deepline 0.3.15 → 0.3.16

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.
@@ -192,7 +192,7 @@ export const SDK_RELEASE = {
192
192
  // 0.3.0 introduces raw-v2: complete scrubbed provider responses are
193
193
  // available at toolResponse.rawV2 while toolResponse.raw and all declared
194
194
  // getters keep their established compatibility behavior.
195
- version: '0.3.15',
195
+ version: '0.3.16',
196
196
  updateSummary:
197
197
  'New raw-v2 tool responses preserve complete scrubbed provider envelopes at toolResponse.rawV2, including JSON:API included resources, links, cursors, and totals. Existing toolResponse.raw and declared getters keep working unchanged.',
198
198
  contracts: {
@@ -75,6 +75,67 @@ export function defaultProductNotificationEventTypes(): ProductNotificationEvent
75
75
  }
76
76
 
77
77
  export const PRODUCT_NOTIFICATION_DESTINATION_KINDS = ['slack'] as const;
78
+ /**
79
+ * The legacy settings API predates named notification rules. Its shortcuts
80
+ * operate on this deterministic compatibility rule when more than one Slack
81
+ * notification exists.
82
+ */
83
+ export const LEGACY_SLACK_NOTIFICATION_NAME = 'Slack notifications';
84
+ export const PRODUCT_NOTIFICATION_LEGACY_SELECTION_ERROR_CODE =
85
+ 'PRODUCT_NOTIFICATION_LEGACY_SELECTION_AMBIGUOUS';
86
+
87
+ export type LegacySlackNotificationDestination = {
88
+ kind: string;
89
+ name: string;
90
+ archivedAt?: number;
91
+ };
92
+
93
+ export class ProductNotificationLegacySelectionError extends Error {
94
+ constructor(message: string) {
95
+ super(message);
96
+ this.name = 'ProductNotificationLegacySelectionError';
97
+ }
98
+ }
99
+
100
+ export function isProductNotificationLegacySelectionError(
101
+ error: unknown,
102
+ ): boolean {
103
+ if (!error || typeof error !== 'object' || !('data' in error)) return false;
104
+ const data = (error as { data?: unknown }).data;
105
+ return (
106
+ typeof data === 'object' &&
107
+ data !== null &&
108
+ (data as { code?: unknown }).code ===
109
+ PRODUCT_NOTIFICATION_LEGACY_SELECTION_ERROR_CODE
110
+ );
111
+ }
112
+
113
+ /**
114
+ * Resolve the singleton target for the legacy settings API without ever
115
+ * silently choosing one of several named notification rules.
116
+ */
117
+ export function resolveLegacySlackNotification<
118
+ T extends LegacySlackNotificationDestination,
119
+ >(destinations: readonly T[]): T | null {
120
+ const slackDestinations = destinations.filter(
121
+ (destination) =>
122
+ destination.kind === 'slack' && destination.archivedAt === undefined,
123
+ );
124
+ const canonical = slackDestinations.filter(
125
+ (destination) => destination.name === LEGACY_SLACK_NOTIFICATION_NAME,
126
+ );
127
+ if (canonical.length === 1) return canonical[0]!;
128
+ if (canonical.length > 1) {
129
+ throw new ProductNotificationLegacySelectionError(
130
+ `More than one \"${LEGACY_SLACK_NOTIFICATION_NAME}\" Slack notification exists. Use the named notification API to choose one.`,
131
+ );
132
+ }
133
+ if (slackDestinations.length <= 1) return slackDestinations[0] ?? null;
134
+ throw new ProductNotificationLegacySelectionError(
135
+ 'More than one Slack notification is configured. Use the named notification API to choose one.',
136
+ );
137
+ }
138
+
78
139
  export const PRODUCT_NOTIFICATION_SLACK_OAUTH_SCOPES = [
79
140
  'channels:read',
80
141
  'chat:write',
package/dist/cli/index.js CHANGED
@@ -1047,7 +1047,7 @@ var SDK_RELEASE = {
1047
1047
  // 0.3.0 introduces raw-v2: complete scrubbed provider responses are
1048
1048
  // available at toolResponse.rawV2 while toolResponse.raw and all declared
1049
1049
  // getters keep their established compatibility behavior.
1050
- version: "0.3.15",
1050
+ version: "0.3.16",
1051
1051
  updateSummary: "New raw-v2 tool responses preserve complete scrubbed provider envelopes at toolResponse.rawV2, including JSON:API included resources, links, cursors, and totals. Existing toolResponse.raw and declared getters keep working unchanged.",
1052
1052
  contracts: {
1053
1053
  api: {
@@ -1904,6 +1904,31 @@ var PRODUCT_NOTIFICATION_EVENT_CATALOG = [
1904
1904
  var PRODUCT_NOTIFICATION_EVENT_TYPE_SET = new Set(
1905
1905
  PRODUCT_NOTIFICATION_EVENT_CATALOG.map((event) => event.id)
1906
1906
  );
1907
+ var LEGACY_SLACK_NOTIFICATION_NAME = "Slack notifications";
1908
+ var ProductNotificationLegacySelectionError = class extends Error {
1909
+ constructor(message) {
1910
+ super(message);
1911
+ this.name = "ProductNotificationLegacySelectionError";
1912
+ }
1913
+ };
1914
+ function resolveLegacySlackNotification(destinations) {
1915
+ const slackDestinations = destinations.filter(
1916
+ (destination) => destination.kind === "slack" && destination.archivedAt === void 0
1917
+ );
1918
+ const canonical = slackDestinations.filter(
1919
+ (destination) => destination.name === LEGACY_SLACK_NOTIFICATION_NAME
1920
+ );
1921
+ if (canonical.length === 1) return canonical[0];
1922
+ if (canonical.length > 1) {
1923
+ throw new ProductNotificationLegacySelectionError(
1924
+ `More than one "${LEGACY_SLACK_NOTIFICATION_NAME}" Slack notification exists. Use the named notification API to choose one.`
1925
+ );
1926
+ }
1927
+ if (slackDestinations.length <= 1) return slackDestinations[0] ?? null;
1928
+ throw new ProductNotificationLegacySelectionError(
1929
+ "More than one Slack notification is configured. Use the named notification API to choose one."
1930
+ );
1931
+ }
1907
1932
  var PRODUCT_NOTIFICATION_SLACK_OAUTH_SCOPES = [
1908
1933
  "channels:read",
1909
1934
  "chat:write",
@@ -36093,11 +36118,23 @@ var eventHelp = PRODUCT_NOTIFICATION_EVENT_CATALOG.map(
36093
36118
  (event) => ` ${event.id.padEnd(28)} ${event.description}`
36094
36119
  ).join("\n");
36095
36120
  function slackDestination(settings) {
36096
- return settings.destinations.find((entry) => entry.kind === "slack");
36121
+ const destinations = settings.destinations.map(
36122
+ (entry) => ({
36123
+ ...entry,
36124
+ kind: typeof entry.kind === "string" ? entry.kind : "",
36125
+ name: typeof entry.name === "string" ? entry.name : "",
36126
+ archivedAt: typeof entry.archivedAt === "number" ? entry.archivedAt : void 0
36127
+ })
36128
+ );
36129
+ return resolveLegacySlackNotification(
36130
+ destinations
36131
+ );
36097
36132
  }
36098
- function eventLines(settings) {
36133
+ function eventLines(settings, destinationId) {
36099
36134
  const enabled = new Map(
36100
- settings.subscriptions.map((entry) => [entry.eventType, entry.enabled])
36135
+ settings.subscriptions.filter(
36136
+ (entry) => !destinationId || entry.destinationId === destinationId
36137
+ ).map((entry) => [entry.eventType, entry.enabled])
36101
36138
  );
36102
36139
  return settings.catalog.map(
36103
36140
  (event) => `${event.id}: ${enabled.get(event.id) === true ? "enabled" : "disabled"} \u2014 ${event.description}`
@@ -36115,6 +36152,7 @@ function requireCatalogEvent(settings, eventType) {
36115
36152
  async function printSettings(options) {
36116
36153
  const settings = await new DeeplineClient().getNotificationSettings();
36117
36154
  const slack = slackDestination(settings);
36155
+ const destinationId = typeof slack?._id === "string" ? slack._id : void 0;
36118
36156
  printCommandEnvelope(
36119
36157
  {
36120
36158
  settings,
@@ -36128,7 +36166,10 @@ async function printSettings(options) {
36128
36166
  ...slack.lastErrorMessage ? [`issue: ${String(slack.lastErrorMessage)}`] : []
36129
36167
  ] : ["Not configured."]
36130
36168
  },
36131
- { title: "subscriptions", lines: eventLines(settings) },
36169
+ {
36170
+ title: "subscriptions",
36171
+ lines: eventLines(settings, destinationId)
36172
+ },
36132
36173
  {
36133
36174
  title: "dead letter queue",
36134
36175
  lines: [
@@ -36317,12 +36358,19 @@ ${eventHelp}
36317
36358
  );
36318
36359
  subscriptions.command("list").description("List every supported event and its current state.").option("--json", "Emit JSON output").action(async (options) => {
36319
36360
  const current = await new DeeplineClient().getNotificationSettings();
36361
+ const destination = slackDestination(current);
36362
+ const destinationId = typeof destination?._id === "string" ? destination._id : void 0;
36320
36363
  printCommandEnvelope(
36321
36364
  {
36322
36365
  catalog: current.catalog,
36323
36366
  subscriptions: current.subscriptions,
36324
36367
  render: {
36325
- sections: [{ title: "subscriptions", lines: eventLines(current) }]
36368
+ sections: [
36369
+ {
36370
+ title: "subscriptions",
36371
+ lines: eventLines(current, destinationId)
36372
+ }
36373
+ ]
36326
36374
  }
36327
36375
  },
36328
36376
  { json: options.json }
@@ -36331,8 +36379,10 @@ ${eventHelp}
36331
36379
  subscriptions.command("describe").description("Describe one event from the shared product catalog.").argument("<event>", "Event ID; run subscriptions list to enumerate").option("--json", "Emit JSON output").action(async (eventType, options) => {
36332
36380
  const current = await new DeeplineClient().getNotificationSettings();
36333
36381
  const event = requireCatalogEvent(current, eventType);
36382
+ const destination = slackDestination(current);
36383
+ const destinationId = typeof destination?._id === "string" ? destination._id : void 0;
36334
36384
  const subscription = current.subscriptions.find(
36335
- (entry) => entry.eventType === event.id
36385
+ (entry) => entry.eventType === event.id && (!destinationId || entry.destinationId === destinationId)
36336
36386
  );
36337
36387
  printCommandEnvelope(
36338
36388
  {
@@ -1033,7 +1033,7 @@ var SDK_RELEASE = {
1033
1033
  // 0.3.0 introduces raw-v2: complete scrubbed provider responses are
1034
1034
  // available at toolResponse.rawV2 while toolResponse.raw and all declared
1035
1035
  // getters keep their established compatibility behavior.
1036
- version: "0.3.15",
1036
+ version: "0.3.16",
1037
1037
  updateSummary: "New raw-v2 tool responses preserve complete scrubbed provider envelopes at toolResponse.rawV2, including JSON:API included resources, links, cursors, and totals. Existing toolResponse.raw and declared getters keep working unchanged.",
1038
1038
  contracts: {
1039
1039
  api: {
@@ -1890,6 +1890,31 @@ var PRODUCT_NOTIFICATION_EVENT_CATALOG = [
1890
1890
  var PRODUCT_NOTIFICATION_EVENT_TYPE_SET = new Set(
1891
1891
  PRODUCT_NOTIFICATION_EVENT_CATALOG.map((event) => event.id)
1892
1892
  );
1893
+ var LEGACY_SLACK_NOTIFICATION_NAME = "Slack notifications";
1894
+ var ProductNotificationLegacySelectionError = class extends Error {
1895
+ constructor(message) {
1896
+ super(message);
1897
+ this.name = "ProductNotificationLegacySelectionError";
1898
+ }
1899
+ };
1900
+ function resolveLegacySlackNotification(destinations) {
1901
+ const slackDestinations = destinations.filter(
1902
+ (destination) => destination.kind === "slack" && destination.archivedAt === void 0
1903
+ );
1904
+ const canonical = slackDestinations.filter(
1905
+ (destination) => destination.name === LEGACY_SLACK_NOTIFICATION_NAME
1906
+ );
1907
+ if (canonical.length === 1) return canonical[0];
1908
+ if (canonical.length > 1) {
1909
+ throw new ProductNotificationLegacySelectionError(
1910
+ `More than one "${LEGACY_SLACK_NOTIFICATION_NAME}" Slack notification exists. Use the named notification API to choose one.`
1911
+ );
1912
+ }
1913
+ if (slackDestinations.length <= 1) return slackDestinations[0] ?? null;
1914
+ throw new ProductNotificationLegacySelectionError(
1915
+ "More than one Slack notification is configured. Use the named notification API to choose one."
1916
+ );
1917
+ }
1893
1918
  var PRODUCT_NOTIFICATION_SLACK_OAUTH_SCOPES = [
1894
1919
  "channels:read",
1895
1920
  "chat:write",
@@ -36171,11 +36196,23 @@ var eventHelp = PRODUCT_NOTIFICATION_EVENT_CATALOG.map(
36171
36196
  (event) => ` ${event.id.padEnd(28)} ${event.description}`
36172
36197
  ).join("\n");
36173
36198
  function slackDestination(settings) {
36174
- return settings.destinations.find((entry) => entry.kind === "slack");
36199
+ const destinations = settings.destinations.map(
36200
+ (entry) => ({
36201
+ ...entry,
36202
+ kind: typeof entry.kind === "string" ? entry.kind : "",
36203
+ name: typeof entry.name === "string" ? entry.name : "",
36204
+ archivedAt: typeof entry.archivedAt === "number" ? entry.archivedAt : void 0
36205
+ })
36206
+ );
36207
+ return resolveLegacySlackNotification(
36208
+ destinations
36209
+ );
36175
36210
  }
36176
- function eventLines(settings) {
36211
+ function eventLines(settings, destinationId) {
36177
36212
  const enabled = new Map(
36178
- settings.subscriptions.map((entry) => [entry.eventType, entry.enabled])
36213
+ settings.subscriptions.filter(
36214
+ (entry) => !destinationId || entry.destinationId === destinationId
36215
+ ).map((entry) => [entry.eventType, entry.enabled])
36179
36216
  );
36180
36217
  return settings.catalog.map(
36181
36218
  (event) => `${event.id}: ${enabled.get(event.id) === true ? "enabled" : "disabled"} \u2014 ${event.description}`
@@ -36193,6 +36230,7 @@ function requireCatalogEvent(settings, eventType) {
36193
36230
  async function printSettings(options) {
36194
36231
  const settings = await new DeeplineClient().getNotificationSettings();
36195
36232
  const slack = slackDestination(settings);
36233
+ const destinationId = typeof slack?._id === "string" ? slack._id : void 0;
36196
36234
  printCommandEnvelope(
36197
36235
  {
36198
36236
  settings,
@@ -36206,7 +36244,10 @@ async function printSettings(options) {
36206
36244
  ...slack.lastErrorMessage ? [`issue: ${String(slack.lastErrorMessage)}`] : []
36207
36245
  ] : ["Not configured."]
36208
36246
  },
36209
- { title: "subscriptions", lines: eventLines(settings) },
36247
+ {
36248
+ title: "subscriptions",
36249
+ lines: eventLines(settings, destinationId)
36250
+ },
36210
36251
  {
36211
36252
  title: "dead letter queue",
36212
36253
  lines: [
@@ -36395,12 +36436,19 @@ ${eventHelp}
36395
36436
  );
36396
36437
  subscriptions.command("list").description("List every supported event and its current state.").option("--json", "Emit JSON output").action(async (options) => {
36397
36438
  const current = await new DeeplineClient().getNotificationSettings();
36439
+ const destination = slackDestination(current);
36440
+ const destinationId = typeof destination?._id === "string" ? destination._id : void 0;
36398
36441
  printCommandEnvelope(
36399
36442
  {
36400
36443
  catalog: current.catalog,
36401
36444
  subscriptions: current.subscriptions,
36402
36445
  render: {
36403
- sections: [{ title: "subscriptions", lines: eventLines(current) }]
36446
+ sections: [
36447
+ {
36448
+ title: "subscriptions",
36449
+ lines: eventLines(current, destinationId)
36450
+ }
36451
+ ]
36404
36452
  }
36405
36453
  },
36406
36454
  { json: options.json }
@@ -36409,8 +36457,10 @@ ${eventHelp}
36409
36457
  subscriptions.command("describe").description("Describe one event from the shared product catalog.").argument("<event>", "Event ID; run subscriptions list to enumerate").option("--json", "Emit JSON output").action(async (eventType, options) => {
36410
36458
  const current = await new DeeplineClient().getNotificationSettings();
36411
36459
  const event = requireCatalogEvent(current, eventType);
36460
+ const destination = slackDestination(current);
36461
+ const destinationId = typeof destination?._id === "string" ? destination._id : void 0;
36412
36462
  const subscription = current.subscriptions.find(
36413
- (entry) => entry.eventType === event.id
36463
+ (entry) => entry.eventType === event.id && (!destinationId || entry.destinationId === destinationId)
36414
36464
  );
36415
36465
  printCommandEnvelope(
36416
36466
  {
package/dist/index.js CHANGED
@@ -783,7 +783,7 @@ var SDK_RELEASE = {
783
783
  // 0.3.0 introduces raw-v2: complete scrubbed provider responses are
784
784
  // available at toolResponse.rawV2 while toolResponse.raw and all declared
785
785
  // getters keep their established compatibility behavior.
786
- version: "0.3.15",
786
+ version: "0.3.16",
787
787
  updateSummary: "New raw-v2 tool responses preserve complete scrubbed provider envelopes at toolResponse.rawV2, including JSON:API included resources, links, cursors, and totals. Existing toolResponse.raw and declared getters keep working unchanged.",
788
788
  contracts: {
789
789
  api: {
package/dist/index.mjs CHANGED
@@ -706,7 +706,7 @@ var SDK_RELEASE = {
706
706
  // 0.3.0 introduces raw-v2: complete scrubbed provider responses are
707
707
  // available at toolResponse.rawV2 while toolResponse.raw and all declared
708
708
  // getters keep their established compatibility behavior.
709
- version: "0.3.15",
709
+ version: "0.3.16",
710
710
  updateSummary: "New raw-v2 tool responses preserve complete scrubbed provider envelopes at toolResponse.rawV2, including JSON:API included resources, links, cursors, and totals. Existing toolResponse.raw and declared getters keep working unchanged.",
711
711
  contracts: {
712
712
  api: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepline",
3
- "version": "0.3.15",
3
+ "version": "0.3.16",
4
4
  "description": "GTM data CLI and TypeScript SDK for coding agents",
5
5
  "license": "MIT",
6
6
  "homepage": "https://code.deepline.com",