@bigfootai/bigfoot-types 5.4.270 → 5.4.272

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.
Files changed (111) hide show
  1. package/dist/block-activity.d.ts +17 -7
  2. package/dist/block-activity.d.ts.map +1 -1
  3. package/dist/block-activity.js +12 -0
  4. package/dist/block-activity.js.map +1 -1
  5. package/dist/block.d.ts +4 -2
  6. package/dist/block.d.ts.map +1 -1
  7. package/dist/block.js.map +1 -1
  8. package/dist/email.d.ts +1 -1
  9. package/dist/email.d.ts.map +1 -1
  10. package/dist/email.js.map +1 -1
  11. package/dist/execute-query.d.ts +9 -2
  12. package/dist/execute-query.d.ts.map +1 -1
  13. package/dist/execute-query.js +0 -1
  14. package/dist/execute-query.js.map +1 -1
  15. package/dist/external-id-link.d.ts +1 -1
  16. package/dist/external-id-link.d.ts.map +1 -1
  17. package/dist/field-value.d.ts +3 -2
  18. package/dist/field-value.d.ts.map +1 -1
  19. package/dist/field-value.js +2 -0
  20. package/dist/field-value.js.map +1 -1
  21. package/dist/installed-query.d.ts +12 -3
  22. package/dist/installed-query.d.ts.map +1 -1
  23. package/dist/installed-query.js +13 -4
  24. package/dist/installed-query.js.map +1 -1
  25. package/dist/metadata/providers/atlassian.d.ts +11 -7
  26. package/dist/metadata/providers/atlassian.d.ts.map +1 -1
  27. package/dist/metadata/providers/atlassian.js +86 -90
  28. package/dist/metadata/providers/atlassian.js.map +1 -1
  29. package/dist/metadata/providers/fathom.js +2 -2
  30. package/dist/metadata/providers/fathom.js.map +1 -1
  31. package/dist/metadata/providers/g2.js +1 -1
  32. package/dist/metadata/providers/g2.js.map +1 -1
  33. package/dist/metadata/providers/google.d.ts.map +1 -1
  34. package/dist/metadata/providers/google.js +7 -6
  35. package/dist/metadata/providers/google.js.map +1 -1
  36. package/dist/metadata/providers/granola.js +2 -2
  37. package/dist/metadata/providers/granola.js.map +1 -1
  38. package/dist/metadata/providers/hubspot.d.ts.map +1 -1
  39. package/dist/metadata/providers/hubspot.js +2 -1
  40. package/dist/metadata/providers/hubspot.js.map +1 -1
  41. package/dist/metadata/providers/index.d.ts +1 -0
  42. package/dist/metadata/providers/index.d.ts.map +1 -1
  43. package/dist/metadata/providers/index.js +1 -0
  44. package/dist/metadata/providers/index.js.map +1 -1
  45. package/dist/metadata/providers/linear.d.ts +20 -0
  46. package/dist/metadata/providers/linear.d.ts.map +1 -1
  47. package/dist/metadata/providers/linear.js +170 -3
  48. package/dist/metadata/providers/linear.js.map +1 -1
  49. package/dist/metadata/providers/linkedin.js +1 -1
  50. package/dist/metadata/providers/linkedin.js.map +1 -1
  51. package/dist/metadata/providers/noded.d.ts +1 -0
  52. package/dist/metadata/providers/noded.d.ts.map +1 -1
  53. package/dist/metadata/providers/noded.js +14 -2
  54. package/dist/metadata/providers/noded.js.map +1 -1
  55. package/dist/metadata/providers/salesforce.d.ts.map +1 -1
  56. package/dist/metadata/providers/salesforce.js +4 -2
  57. package/dist/metadata/providers/salesforce.js.map +1 -1
  58. package/dist/metadata/providers/slack.d.ts.map +1 -1
  59. package/dist/metadata/providers/slack.js +2 -1
  60. package/dist/metadata/providers/slack.js.map +1 -1
  61. package/dist/metadata/providers/zendesk.d.ts +4 -0
  62. package/dist/metadata/providers/zendesk.d.ts.map +1 -0
  63. package/dist/metadata/providers/zendesk.js +59 -0
  64. package/dist/metadata/providers/zendesk.js.map +1 -0
  65. package/dist/provider.d.ts +10 -0
  66. package/dist/provider.d.ts.map +1 -1
  67. package/dist/provider.js.map +1 -1
  68. package/dist/recommendation.d.ts +6 -1
  69. package/dist/recommendation.d.ts.map +1 -1
  70. package/dist/recommendation.js +3 -0
  71. package/dist/recommendation.js.map +1 -1
  72. package/dist/signal.d.ts +2 -1
  73. package/dist/signal.d.ts.map +1 -1
  74. package/dist/signal.js +1 -0
  75. package/dist/signal.js.map +1 -1
  76. package/dist/tag.d.ts +3 -3
  77. package/dist/tag.d.ts.map +1 -1
  78. package/dist/tag.js.map +1 -1
  79. package/dist/transcription-section.d.ts +1 -1
  80. package/dist/transcription-section.d.ts.map +1 -1
  81. package/dist/types.d.ts +17 -9
  82. package/dist/types.d.ts.map +1 -1
  83. package/dist/types.js +6 -2
  84. package/dist/types.js.map +1 -1
  85. package/package.json +2 -2
  86. package/src/block-activity.ts +26 -3
  87. package/src/block.ts +5 -2
  88. package/src/email.ts +1 -1
  89. package/src/execute-query.ts +8 -2
  90. package/src/external-id-link.ts +1 -1
  91. package/src/field-value.ts +3 -0
  92. package/src/installed-query.ts +13 -4
  93. package/src/metadata/providers/atlassian.ts +87 -90
  94. package/src/metadata/providers/fathom.ts +2 -2
  95. package/src/metadata/providers/g2.ts +1 -1
  96. package/src/metadata/providers/google.ts +7 -10
  97. package/src/metadata/providers/granola.ts +2 -2
  98. package/src/metadata/providers/hubspot.ts +2 -1
  99. package/src/metadata/providers/index.ts +1 -0
  100. package/src/metadata/providers/linear.ts +172 -3
  101. package/src/metadata/providers/linkedin.ts +1 -1
  102. package/src/metadata/providers/noded.ts +16 -2
  103. package/src/metadata/providers/salesforce.ts +4 -3
  104. package/src/metadata/providers/slack.ts +2 -1
  105. package/src/metadata/providers/zendesk.ts +61 -0
  106. package/src/provider.ts +10 -0
  107. package/src/recommendation.ts +9 -0
  108. package/src/signal.ts +2 -0
  109. package/src/tag.ts +3 -3
  110. package/src/transcription-section.ts +1 -1
  111. package/src/types.ts +19 -4
@@ -4,32 +4,34 @@ import { FieldVariation } from '../../field-variation.js';
4
4
  import type { Provider, ProviderApplication } from '../../provider.js';
5
5
  import type { TableMetadata } from '../../table-metadata.js';
6
6
  import { TagType } from '../../tag-type.js';
7
- import { TaskPriority } from '../../task-priority.js';
8
- import { TaskStatus } from '../../task-status.js';
9
7
 
10
8
  /**
11
- * Jira-specific Issue table. Field `name` values match Jira's REST API field keys
12
- * (https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/),
13
- * so the connector can read/write straight through with no name-translation table.
9
+ * After the dynamic-discovery refactor, the Jira connector emits one table per
10
+ * (project, issueType) scope with `metadataType: issue:{projectKey}:{issueTypeId}`,
11
+ * along with stable lookup tables for Projects, Users, Sprints, and Boards. Issue
12
+ * scopes vary per tenant so they can't be pre-listed here; the lookup tables can.
14
13
  *
15
- * Top-level Jira response fields (`key`, `id`) are named lowercase here so the
16
- * connector can detect them with a single small allowlist and pull from
17
- * `issue.key` / `issue.id` instead of `issue.fields.<name>`.
14
+ * The two pre-installed tables (`JiraProject`, `JiraUser`) mirror what
15
+ * `buildProjectTableMetadata()` and `buildUserTableMetadata()` return from
16
+ * bigfoot-atlassian/src/primitives/{project,user}.ts. Sprint and Board are only
17
+ * present on Jira-Software-enabled tenants, so they're discovered at sync time
18
+ * rather than pre-installed.
18
19
  */
19
- export const JiraIssue: TableMetadata = {
20
- label: 'Issue',
21
- description: 'Represents an issue or feature enhancement, which is a request to improve a product or service.',
22
- metadataType: 'issue',
23
- tasky: true,
24
- references: ['https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/'],
20
+ export const JiraProject: TableMetadata = {
21
+ label: 'Projects',
22
+ description: 'All Jira projects accessible to this connection.',
23
+ metadataType: 'project',
24
+ tagType: TagType.Topic,
25
+ tagSubType: 'project',
26
+ tasky: false,
27
+ references: ['https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-projects/'],
25
28
  fields: [
26
29
  {
27
30
  label: 'Key',
28
31
  name: 'key',
29
- description: 'A human-facing, unique identifier for the issue.',
30
- prompt: 'A human-facing, unique identifier for the issue.',
32
+ description: "The project's short key, e.g. 'PROJ'.",
33
+ prompt: "The project's short key, e.g. 'PROJ'.",
31
34
  fieldType: FieldType.Text,
32
- maximumCharacters: 255,
33
35
  readOnly: true,
34
36
  important: true,
35
37
  source: 'system',
@@ -37,12 +39,11 @@ export const JiraIssue: TableMetadata = {
37
39
  visible: true,
38
40
  },
39
41
  {
40
- label: 'Summary',
41
- name: 'summary',
42
- description: 'A summary description of the issue.',
43
- prompt: 'A summary description of the issue.',
42
+ label: 'Name',
43
+ name: 'name',
44
+ description: 'The display name of the project.',
45
+ prompt: 'The display name of the project.',
44
46
  fieldType: FieldType.Text,
45
- maximumCharacters: 255,
46
47
  readOnly: false,
47
48
  important: true,
48
49
  source: 'system',
@@ -50,49 +51,36 @@ export const JiraIssue: TableMetadata = {
50
51
  visible: true,
51
52
  },
52
53
  {
53
- label: 'Priority',
54
- name: 'priority',
55
- description: 'The priority of the issue.',
56
- prompt: 'The priority of the issue.',
57
- fieldType: FieldType.Select,
58
- readOnly: false,
59
- options: [
60
- { label: 'Highest', value: 'Highest', priority: TaskPriority.High },
61
- { label: 'High', value: 'High', priority: TaskPriority.High },
62
- { label: 'Medium', value: 'Medium', priority: TaskPriority.Medium },
63
- { label: 'Low', value: 'Low', priority: TaskPriority.Low },
64
- { label: 'Lowest', value: 'Lowest', priority: TaskPriority.Low },
65
- ],
66
- important: true,
67
- priority: true,
68
- source: 'system',
69
- visible: true,
70
- },
71
- {
72
- label: 'Status',
73
- name: 'status',
74
- description: 'The status of the issue.',
75
- prompt: 'The status of the issue.',
76
- fieldType: FieldType.Select,
77
- readOnly: false,
78
- options: [
79
- { label: 'To Do', value: 'To Do', status: TaskStatus.NotStarted },
80
- { label: 'In Progress', value: 'In Progress', status: TaskStatus.InProgress },
81
- { label: 'Done', value: 'Done', status: TaskStatus.Completed },
82
- ],
83
- important: true,
54
+ label: 'Project ID',
55
+ name: 'id',
56
+ description: 'The numeric project id assigned by Jira.',
57
+ prompt: 'The numeric project id assigned by Jira.',
58
+ fieldType: FieldType.Text,
59
+ readOnly: true,
84
60
  source: 'system',
85
- status: true,
61
+ status: false,
86
62
  visible: true,
87
63
  },
64
+ ],
65
+ classifiers: ['project', 'jira', 'workspace'],
66
+ threshold: 0,
67
+ };
68
+
69
+ export const JiraUser: TableMetadata = {
70
+ label: 'Users',
71
+ description: 'Atlassian accounts visible to this Jira connection.',
72
+ metadataType: 'user',
73
+ tagType: TagType.Person,
74
+ tagSubType: 'user',
75
+ tasky: false,
76
+ references: ['https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-user-search/'],
77
+ fields: [
88
78
  {
89
- label: 'Due Date',
90
- name: 'duedate',
91
- description: 'Date when the issue is expected to be completed.',
92
- prompt: 'Date when the issue is expected to be completed.',
93
- tagType: TagType.Date,
79
+ label: 'Display Name',
80
+ name: 'displayName',
81
+ description: 'The display name of the user.',
82
+ prompt: 'The display name of the user.',
94
83
  fieldType: FieldType.Text,
95
- fieldVariation: FieldVariation.Date,
96
84
  readOnly: false,
97
85
  important: true,
98
86
  source: 'system',
@@ -100,50 +88,42 @@ export const JiraIssue: TableMetadata = {
100
88
  visible: true,
101
89
  },
102
90
  {
103
- label: 'Project',
104
- name: 'project',
105
- description: 'Name of the project associated with this issue.',
106
- prompt: 'Name of the project associated with this issue.',
107
- tagType: TagType.Topic,
108
- tagSubType: 'project',
109
- fieldType: FieldType.Lookup,
91
+ label: 'Email',
92
+ name: 'emailAddress',
93
+ description: 'The email address of the user.',
94
+ prompt: 'The email address of the user.',
95
+ fieldType: FieldType.Text,
96
+ fieldVariation: FieldVariation.Email,
110
97
  readOnly: false,
111
- important: true,
112
98
  source: 'system',
113
99
  status: false,
114
100
  visible: true,
115
101
  },
116
102
  {
117
- label: 'Assignee',
118
- name: 'assignee',
119
- description: 'Name of the User who has been assigned to work on this issue.',
120
- prompt: 'Name of the User who has been assigned to work on this issue.',
121
- tagType: TagType.Person,
122
- tagSubType: 'user',
123
- fieldType: FieldType.Lookup,
124
- readOnly: false,
125
- important: true,
103
+ label: 'Account ID',
104
+ name: 'accountId',
105
+ description: 'The Atlassian accountId for this user.',
106
+ prompt: 'The Atlassian accountId for this user.',
107
+ fieldType: FieldType.Text,
108
+ readOnly: true,
126
109
  source: 'system',
127
110
  status: false,
128
111
  visible: true,
129
112
  },
130
113
  {
131
- label: 'Description',
132
- name: 'description',
133
- description: 'Text description of the issue.',
134
- prompt: 'Text description of the issue.',
135
- fieldType: FieldType.Text,
136
- fieldVariation: FieldVariation.Multi,
137
- maximumCharacters: 32000,
114
+ label: 'Active',
115
+ name: 'active',
116
+ description: 'Whether the user account is active.',
117
+ prompt: 'Whether the user account is active.',
118
+ fieldType: FieldType.Checkbox,
138
119
  readOnly: false,
139
- important: false,
140
120
  source: 'system',
141
121
  status: false,
142
122
  visible: true,
143
123
  },
144
124
  ],
145
- classifiers: ['product improvement', 'new feature', 'product enhancement', 'new capability'],
146
- threshold: 0.24,
125
+ classifiers: ['user', 'jira', 'atlassian account'],
126
+ threshold: 0,
147
127
  };
148
128
 
149
129
  export const AtlassianJira: ProviderApplication = {
@@ -156,9 +136,17 @@ export const AtlassianJira: ProviderApplication = {
156
136
  table: true,
157
137
  function: false,
158
138
  },
159
- linkSubscriptions: ['*.atlassian.net/browse/'],
139
+ // Jira tickets only — Confluence pages (under /wiki/) and other Atlassian surfaces on the same host fall through to website ingestion.
140
+ linkSubscriptions: ['^https://[^/]+\\.atlassian\\.net/browse/[A-Z][A-Z0-9]+-\\d+'],
160
141
  linkToExternalIdRegex: '([A-Z][A-Z0-9]+-\\d+)',
161
- recordTypeSubscriptions: ['noded.issue'],
142
+ // Only metadataTypes the connector can route statically belong here. After the
143
+ // dynamic-discovery refactor, issue scopes use `issue:{projectKey}:{issueTypeId}`
144
+ // and are installed per-tenant via the "App Fields" wizard (which calls
145
+ // installProviderTable), so they're NOT pre-subscribed. The bare canonical
146
+ // 'noded.issue' is intentionally absent — the connector's dispatcher would
147
+ // reject it (no `issue:` prefix → no handler match) on both /sync/metadata
148
+ // and /upsert/table.
149
+ recordTypeSubscriptions: [JiraProject.metadataType, JiraUser.metadataType],
162
150
  description: "Add Jira issue previews and monitor changes over time so you're always up-to-date.",
163
151
  iconUrl: 'https://connect-atlassian-dev.getnoded.ai/images/jira_logo.svg',
164
152
  label: 'Jira',
@@ -172,13 +160,20 @@ export const AtlassianJira: ProviderApplication = {
172
160
  tagType: TagType.Topic,
173
161
  tagSubType: 'project',
174
162
  metadataType: 'project',
163
+ requireExternalId: true,
164
+ recordTypeSubscriptions: [JiraProject.metadataType],
175
165
  },
176
166
  {
167
+ // 'reporter' and 'assignee' share the same underlying Jira user catalog,
168
+ // but the connector preserves the distinction so the insight handler can
169
+ // build `reporter IN (...)` vs `assignee IN (...)` JQL fragments.
177
170
  label: 'Reporter',
178
171
  blockType: BlockType.Record,
179
172
  tagType: TagType.Person,
180
173
  tagSubType: 'user',
181
174
  metadataType: 'reporter',
175
+ requireExternalId: true,
176
+ recordTypeSubscriptions: [JiraUser.metadataType],
182
177
  },
183
178
  {
184
179
  label: 'Assignee',
@@ -186,6 +181,8 @@ export const AtlassianJira: ProviderApplication = {
186
181
  tagType: TagType.Person,
187
182
  tagSubType: 'user',
188
183
  metadataType: 'assignee',
184
+ requireExternalId: true,
185
+ recordTypeSubscriptions: [JiraUser.metadataType],
189
186
  },
190
187
  ],
191
188
  };
@@ -202,5 +199,5 @@ export const Atlassian: Provider = {
202
199
  label: 'Atlassian',
203
200
  iconUrl: 'https://connect-atlassian-dev.getnoded.ai/images/atlassian_logo.png',
204
201
  promptMetadata: [],
205
- tableMetadata: [JiraIssue],
202
+ tableMetadata: [JiraProject, JiraUser],
206
203
  };
@@ -14,7 +14,7 @@ export const FathomNotes: ProviderApplication = {
14
14
  linkToExternalIdRegex: '/(d+)$/',
15
15
  recordTypeSubscriptions: [],
16
16
  description: 'Ingest call notes from Fathom as transcripts in Noded',
17
- iconUrl: '',
17
+ iconUrl: 'https://connect-fathom.getnoded.ai/images/logo.png',
18
18
  label: 'Fathom Notes',
19
19
  authentication: true,
20
20
  externalStorage: false,
@@ -32,6 +32,6 @@ export const Fathom: Provider = {
32
32
  instanceUrl: 'https://connect-fathom-dev.getnoded.ai',
33
33
  applications: [FathomNotes],
34
34
  label: 'Fathom',
35
- iconUrl: '',
35
+ iconUrl: 'https://connect-fathom.getnoded.ai/images/logo.png',
36
36
  promptMetadata: [],
37
37
  };
@@ -70,7 +70,7 @@ export const G2App: ProviderApplication = {
70
70
  table: false,
71
71
  function: false,
72
72
  },
73
- linkSubscriptions: ['https://www.g2.com'],
73
+ linkSubscriptions: [],
74
74
  linkToExternalIdRegex: '/(d+)$/',
75
75
  description: 'Add buyer intention insights to your Accounts.',
76
76
  iconUrl: 'https://connect-g2-dev.getnoded.ai/images/g2-icon.svg',
@@ -17,8 +17,7 @@ export const GoogleCalendar: ProviderApplication = {
17
17
  },
18
18
  linkSubscriptions: [],
19
19
  description: 'Bring your calendar into Noded to get up-to-the-minute insights on your day.',
20
- iconUrl:
21
- 'https://upload.wikimedia.org/wikipedia/commons/thumb/a/a5/Google_Calendar_icon_%282020%29.svg/240px-Google_Calendar_icon_%282020%29.svg.png',
20
+ iconUrl: 'https://connect-google-v2.getnoded.ai/images/calendar.svg',
22
21
  label: 'Google Calendar',
23
22
  recordTypeSubscriptions: [],
24
23
  authentication: true,
@@ -40,7 +39,7 @@ export const GoogleCalls: ProviderApplication = {
40
39
  linkToExternalIdRegex: '/(d+)$/',
41
40
  recordTypeSubscriptions: [],
42
41
  description: 'Ingest calls from Google Meet as notes in Noded',
43
- iconUrl: 'https://duckduckgo.com/i/c86cc1200a55fee4.png',
42
+ iconUrl: 'https://connect-google-v2.getnoded.ai/images/meet.svg',
44
43
  label: 'Google Meet',
45
44
  authentication: true,
46
45
  externalStorage: false,
@@ -58,12 +57,12 @@ export const GoogleDrive: ProviderApplication = {
58
57
  table: false,
59
58
  function: true,
60
59
  },
61
- linkSubscriptions: ['docs.google.com'],
60
+ // Drive documents only — Docs, Sheets, and Slides. Other docs.google.com surfaces (forms, drawings, etc.) fall through to website ingestion.
61
+ linkSubscriptions: ['^https://docs\\.google\\.com/(?:document|spreadsheets|presentation)/d/'],
62
62
  linkToExternalIdRegex: '/d/([a-zA-Z0-9_-]{33,})',
63
63
  description:
64
64
  "Add document previews and ingest your drive documents so they're easily searchable. Also exposes Slides-driven Agent Functions like Generate Presentation from Template.",
65
- iconUrl:
66
- 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/69/Google_Docs_Editors_2020_Logo.svg/872px-Google_Docs_Editors_2020_Logo.svg.png',
65
+ iconUrl: 'https://connect-google-v2.getnoded.ai/images/drive.svg',
67
66
  label: 'Google Drive',
68
67
  recordTypeSubscriptions: [],
69
68
  functionTypeSubscriptions: [
@@ -103,8 +102,7 @@ export const GoogleEmail: ProviderApplication = {
103
102
  emailComposerLink:
104
103
  'https://mail.google.com/mail/?view=cm&fs=1&to={{to,}}&cc={{cc,}}&bcc={{bcc,}}&su={{subject}}&body={{body}}',
105
104
  description: "Add Gmail links to generated emails. We don't have access to your inbox!",
106
- iconUrl:
107
- 'https://upload.wikimedia.org/wikipedia/commons/thumb/7/7e/Gmail_icon_%282020%29.svg/1024px-Gmail_icon_%282020%29.svg.png',
105
+ iconUrl: 'https://connect-google-v2.getnoded.ai/images/gmail.svg',
108
106
  label: 'Google Mail',
109
107
  authentication: false,
110
108
  externalStorage: false,
@@ -281,8 +279,7 @@ export const Google: Provider = {
281
279
  instanceUrl: 'https://connect-google-dev.noded.so',
282
280
  applications: [GoogleCalendar, GoogleCalls, GoogleDrive, GoogleEmail],
283
281
  label: 'Google',
284
- iconUrl:
285
- 'https://static.vecteezy.com/system/resources/previews/022/484/503/non_2x/google-lens-icon-logo-symbol-free-png.png',
282
+ iconUrl: 'https://connect-google-v2.getnoded.ai/images/google.svg',
286
283
  promptMetadata: [],
287
284
  functionMetadata: [GenerateSlidesFromTemplate, GenerateDocFromTemplate, GenerateSheetFromTemplate],
288
285
  };
@@ -14,7 +14,7 @@ export const GranolaNotes: ProviderApplication = {
14
14
  linkToExternalIdRegex: '/(d+)$/',
15
15
  recordTypeSubscriptions: [],
16
16
  description: 'Ingest meeting notes from Granola as transcripts in Noded',
17
- iconUrl: '',
17
+ iconUrl: 'https://connect-granola.getnoded.ai/images/logo.svg',
18
18
  label: 'Granola Notes',
19
19
  authentication: true,
20
20
  externalStorage: false,
@@ -32,6 +32,6 @@ export const Granola: Provider = {
32
32
  instanceUrl: 'https://connect-granola-dev.getnoded.ai',
33
33
  applications: [GranolaNotes],
34
34
  label: 'Granola',
35
- iconUrl: '',
35
+ iconUrl: 'https://connect-granola.getnoded.ai/images/logo.svg',
36
36
  promptMetadata: [],
37
37
  };
@@ -13,7 +13,8 @@ export const HubSpotCrm: ProviderApplication = {
13
13
  table: true,
14
14
  function: false,
15
15
  },
16
- linkSubscriptions: ['https://app.hubspot.com'],
16
+ // CRM record pages only (universal /record/ route covers Contacts, Companies, Deals, and custom objects). Reports, settings, marketing surfaces fall through to website ingestion.
17
+ linkSubscriptions: ['^https://app\\.hubspot\\.com/contacts/\\d+/record/'],
17
18
  linkToExternalIdRegex: '/(d+)$/',
18
19
  recordTypeSubscriptions: ['noded.opportunity', 'noded.case'],
19
20
  description: "Add Ticket and Deal previews and monitor changes over time so you're always up-to-date.",
@@ -13,4 +13,5 @@ export * from './microsoft.js';
13
13
  export * from './noded.js';
14
14
  export * from './salesforce.js';
15
15
  export * from './slack.js';
16
+ export * from './zendesk.js';
16
17
  export * from './zoom.js';
@@ -1,6 +1,168 @@
1
1
  import { BlockType } from '../../block-type.js';
2
+ import { FieldType } from '../../field-type.js';
3
+ import { FieldVariation } from '../../field-variation.js';
2
4
  import type { Provider, ProviderApplication } from '../../provider.js';
5
+ import type { TableMetadata } from '../../table-metadata.js';
3
6
  import { TagType } from '../../tag-type.js';
7
+ import { TaskPriority } from '../../task-priority.js';
8
+
9
+ /**
10
+ * The canonical Linear issue table. Modelled on the shared `noded.issue` table
11
+ * (tables/issue.ts) but specialised to Linear's own issue object: Linear's fixed
12
+ * 0–4 priority scale, and Status/Labels that are workflow-state and label sets
13
+ * scoped to a Linear team — so their options are left empty here and populated per
14
+ * team when the connector hydrates the table at sync time.
15
+ *
16
+ * Field `name`s are the contract with the connector (bigfoot-linear): its
17
+ * read/write resolvers key off these exact names, which match Linear's GraphQL
18
+ * Issue object (`title`, `assignee`, `state`, …). Keep them in sync with
19
+ * buildIssueFields() there. The user-facing `label` uses Linear's UI terminology
20
+ * (Key, Title, Assignee).
21
+ *
22
+ * metadataType is the bare `issue`: a dotless recordTypeSubscription resolves to
23
+ * this provider's own table, and the connector routes the bare type to the
24
+ * workspace's first team (its DEFAULT_ISSUE_METADATA_TYPE path). The team-scoped
25
+ * `issue:{teamId}` tables the connector discovers dynamically can't be pre-listed.
26
+ */
27
+ export const LinearIssue: TableMetadata = {
28
+ label: 'Issue',
29
+ description: 'A Linear issue — a unit of work such as a bug, task, or feature request tracked by a team.',
30
+ metadataType: 'issue',
31
+ tasky: true,
32
+ references: ['https://developers.linear.app/docs', 'https://studio.apollographql.com/public/Linear-API/'],
33
+ fields: [
34
+ {
35
+ label: 'Key',
36
+ name: 'identifier',
37
+ description: 'A human-facing, unique identifier for the issue (e.g. ENG-42).',
38
+ prompt: 'A human-facing, unique identifier for the issue (e.g. ENG-42).',
39
+ fieldType: FieldType.Text,
40
+ maximumCharacters: 255,
41
+ readOnly: true,
42
+ important: true,
43
+ source: 'system',
44
+ status: false,
45
+ visible: true,
46
+ },
47
+ {
48
+ label: 'Title',
49
+ name: 'title',
50
+ description: 'A summary description of the issue.',
51
+ prompt: 'A summary description of the issue.',
52
+ fieldType: FieldType.Text,
53
+ maximumCharacters: 255,
54
+ readOnly: false,
55
+ important: true,
56
+ source: 'system',
57
+ status: false,
58
+ visible: true,
59
+ },
60
+ {
61
+ label: 'Priority',
62
+ name: 'priority',
63
+ description: 'The priority of the issue.',
64
+ prompt: 'The priority of the issue.',
65
+ fieldType: FieldType.Select,
66
+ readOnly: false,
67
+ options: [
68
+ { label: 'No priority', value: '0', priority: TaskPriority.Low },
69
+ { label: 'Urgent', value: '1', priority: TaskPriority.High },
70
+ { label: 'High', value: '2', priority: TaskPriority.High },
71
+ { label: 'Normal', value: '3', priority: TaskPriority.Medium },
72
+ { label: 'Low', value: '4', priority: TaskPriority.Low },
73
+ ],
74
+ important: true,
75
+ priority: true,
76
+ source: 'system',
77
+ visible: true,
78
+ },
79
+ {
80
+ label: 'Status',
81
+ name: 'state',
82
+ description: 'The workflow state of the issue.',
83
+ prompt: 'The workflow state of the issue.',
84
+ fieldType: FieldType.Select,
85
+ readOnly: false,
86
+ options: [], // Linear workflow states are per-team; populated by the connector at sync time.
87
+ important: true,
88
+ source: 'system',
89
+ status: true,
90
+ visible: true,
91
+ },
92
+ {
93
+ label: 'Due Date',
94
+ name: 'dueDate',
95
+ description: 'Date when the issue is expected to be completed.',
96
+ prompt: 'Date when the issue is expected to be completed.',
97
+ tagType: TagType.Date,
98
+ fieldType: FieldType.Text,
99
+ fieldVariation: FieldVariation.Date,
100
+ readOnly: false,
101
+ important: true,
102
+ source: 'system',
103
+ status: false,
104
+ visible: true,
105
+ },
106
+ {
107
+ label: 'Project',
108
+ name: 'project',
109
+ description: 'Name of the project associated with this issue.',
110
+ prompt: 'Name of the project associated with this issue.',
111
+ tagType: TagType.Topic,
112
+ tagSubType: 'project',
113
+ fieldType: FieldType.Lookup,
114
+ readOnly: false,
115
+ important: true,
116
+ source: 'system',
117
+ status: false,
118
+ visible: true,
119
+ },
120
+ {
121
+ label: 'Assignee',
122
+ name: 'assignee',
123
+ description: 'The user assigned to work on this issue.',
124
+ prompt: 'The user assigned to work on this issue.',
125
+ tagType: TagType.Person,
126
+ tagSubType: 'user',
127
+ fieldType: FieldType.Lookup,
128
+ readOnly: false,
129
+ important: true,
130
+ source: 'system',
131
+ status: false,
132
+ visible: true,
133
+ },
134
+ {
135
+ label: 'Labels',
136
+ name: 'labels',
137
+ description: 'Labels applied to the issue.',
138
+ prompt: 'Labels applied to the issue.',
139
+ fieldType: FieldType.Select,
140
+ fieldVariation: FieldVariation.Multi,
141
+ readOnly: false,
142
+ options: [], // Linear labels are per-team; populated by the connector at sync time.
143
+ important: false,
144
+ source: 'system',
145
+ status: false,
146
+ visible: true,
147
+ },
148
+ {
149
+ label: 'Description',
150
+ name: 'description',
151
+ description: 'Text description of the issue.',
152
+ prompt: 'Text description of the issue.',
153
+ fieldType: FieldType.Text,
154
+ fieldVariation: FieldVariation.Multi,
155
+ maximumCharacters: 32000,
156
+ readOnly: false,
157
+ important: false,
158
+ source: 'system',
159
+ status: false,
160
+ visible: true,
161
+ },
162
+ ],
163
+ classifiers: ['product improvement', 'new feature', 'product enhancement', 'new capability'],
164
+ threshold: 0.24,
165
+ };
4
166
 
5
167
  export const LinearApp: ProviderApplication = {
6
168
  name: 'app',
@@ -12,9 +174,15 @@ export const LinearApp: ProviderApplication = {
12
174
  table: true,
13
175
  function: false,
14
176
  },
15
- linkSubscriptions: ['https://linear.app'],
16
- linkToExternalIdRegex: '/(d+)$/',
17
- recordTypeSubscriptions: ['noded.issue'],
177
+ // Issues only (canonical /<workspace>/issue/<TEAM-N> permalinks). Views, projects, and docs fall through to website ingestion.
178
+ linkSubscriptions: ['^https://linear\\.app/[^/]+/issue/[A-Z][A-Z0-9]+-\\d+'],
179
+ // Captures a Linear issue identifier (e.g. ENG-42) from a link — mirrors the
180
+ // capture group in the connector's issueUrlRegex. The previous '/(d+)$/' was a
181
+ // literal 'd' (not '\d'), slash-wrapped, so it never matched a Linear URL.
182
+ linkToExternalIdRegex: '([A-Za-z0-9]+-\\d+)',
183
+ // A dotless metadataType resolves to this provider's own tableMetadata (the
184
+ // LinearIssue table above), rather than the shared noded.issue table.
185
+ recordTypeSubscriptions: [LinearIssue.metadataType],
18
186
  description: "Add Issue previews and monitor changes over time so you're always up-to-date.",
19
187
  iconUrl: 'https://connect-linear-dev.noded.so/images/linear-company-icon.svg',
20
188
  label: 'Linear App',
@@ -51,4 +219,5 @@ export const Linear: Provider = {
51
219
  label: 'Linear',
52
220
  iconUrl: 'https://connect-linear-dev.noded.so/images/linear-company-icon.svg',
53
221
  promptMetadata: [],
222
+ tableMetadata: [LinearIssue],
54
223
  };
@@ -13,7 +13,7 @@ export const LinkedInSales: ProviderApplication = {
13
13
  table: false,
14
14
  function: false,
15
15
  },
16
- linkSubscriptions: ['www.linkedin.com'],
16
+ linkSubscriptions: [],
17
17
  linkToExternalIdRegex: '([a-zA-Z0-9]{15,18})(?=[^a-zA-Z0-9]|$)',
18
18
  recordTypeSubscriptions: [],
19
19
  description: 'Add links to profile and company pages to your tags.',
@@ -39,9 +39,23 @@ export const FieldMetadataARR: Field = {
39
39
  export const FieldMetadataDescription: Field = {
40
40
  label: 'Description',
41
41
  name: 'description',
42
- description: 'A description of the entity the tag represents',
42
+ description: 'A description of the organization',
43
43
  prompt:
44
- 'Provide a general, factual description of the entity the tag represents. This description should be a paragraph suitable for an overview and must NOT be based on or summarize the contents of the provided documents. Instead, it should reflect well-known, publicly available information about the entity itself. If you do not know, or cannot find this information, leave it blank.',
44
+ 'Provide a general, factual description of the company/organization. This description should be a paragraph suitable for an overview and must NOT be based on or summarize the contents of the provided documents. Instead, it should reflect well-known, publicly available information about the company itself. If you do not know, or cannot find this information, leave it blank.',
45
+ fieldType: FieldType.Text,
46
+ readOnly: false,
47
+ important: false,
48
+ source: 'system',
49
+ status: false,
50
+ visible: true,
51
+ };
52
+
53
+ export const FieldMetadataNews: Field = {
54
+ label: 'News',
55
+ name: 'news',
56
+ description: 'Recent news about the organization',
57
+ prompt:
58
+ 'Recent, important news items for this organization. You MUST gather this information using the web_search_preview tool. DO NOT use the provided documents to complete this field. Return as a Markdown bullet list, with a maximum of 10 items, ordered newest first. Each item must be a bullet point, with a link to the article with the date and title like "* [2025/07/30: Something happened in the news](https://news.website/article). If there are no recent news items, return empty. DO NOT return more than 10 items.',
45
59
  fieldType: FieldType.Text,
46
60
  readOnly: false,
47
61
  important: false,
@@ -207,7 +207,10 @@ export const SalesforceCrm: ProviderApplication = {
207
207
  table: true,
208
208
  function: false,
209
209
  },
210
- linkSubscriptions: ['*.lightning.force.com'],
210
+ linkSubscriptions: [
211
+ // Object record views only. The negative lookahead excludes Salesforce primitives we don't ingest (Reports, Dashboards, List Views, Folders) — those share the /lightning/r/ path with real objects but the provider service rejects them.
212
+ '^https://[^/]+\\.lightning\\.force\\.com/lightning/r/(?!Report/|Dashboard/|ListView/|Folder/)[A-Za-z0-9_]+/[a-zA-Z0-9]{15,18}',
213
+ ],
211
214
  linkToExternalIdRegex: '([a-zA-Z0-9]{15,18})(?=[^a-zA-Z0-9]|$)',
212
215
  queryTypeSubscriptions: [AccountQuery.metadataType],
213
216
  recordTypeSubscriptions: ['noded.opportunity', 'noded.case', Note.metadataType, Account.metadataType],
@@ -261,5 +264,3 @@ export const Salesforce: Provider = {
261
264
  tableMetadata: [Note, Account],
262
265
  queryMetadata: [AccountQuery],
263
266
  };
264
-
265
- console.log(JSON.stringify(Salesforce));
@@ -12,7 +12,8 @@ export const SlackPlatform: ProviderApplication = {
12
12
  table: false,
13
13
  function: false,
14
14
  },
15
- linkSubscriptions: ['*.slack.com/archives'],
15
+ // Message permalinks only — channel/thread roots and other Slack surfaces fall through to website ingestion.
16
+ linkSubscriptions: ['^https://[^/]+\\.slack\\.com/archives/[A-Z][A-Z0-9]+/p\\d+'],
16
17
  linkToExternalIdRegex: '([a-zA-Z0-9]{15,18})(?=[^a-zA-Z0-9]|$)',
17
18
  description: 'Collaborate with Slack and Noded together.',
18
19
  iconUrl: 'https://cdn4.iconfinder.com/data/icons/logos-and-brands/512/306_Slack_logo-512.png',