@link-assistant/hive-mind 0.39.0

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 (63) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/LICENSE +24 -0
  3. package/README.md +769 -0
  4. package/package.json +58 -0
  5. package/src/agent.lib.mjs +705 -0
  6. package/src/agent.prompts.lib.mjs +196 -0
  7. package/src/buildUserMention.lib.mjs +71 -0
  8. package/src/claude-limits.lib.mjs +389 -0
  9. package/src/claude.lib.mjs +1445 -0
  10. package/src/claude.prompts.lib.mjs +203 -0
  11. package/src/codex.lib.mjs +552 -0
  12. package/src/codex.prompts.lib.mjs +194 -0
  13. package/src/config.lib.mjs +207 -0
  14. package/src/contributing-guidelines.lib.mjs +268 -0
  15. package/src/exit-handler.lib.mjs +205 -0
  16. package/src/git.lib.mjs +145 -0
  17. package/src/github-issue-creator.lib.mjs +246 -0
  18. package/src/github-linking.lib.mjs +152 -0
  19. package/src/github.batch.lib.mjs +272 -0
  20. package/src/github.graphql.lib.mjs +258 -0
  21. package/src/github.lib.mjs +1479 -0
  22. package/src/hive.config.lib.mjs +254 -0
  23. package/src/hive.mjs +1500 -0
  24. package/src/instrument.mjs +191 -0
  25. package/src/interactive-mode.lib.mjs +1000 -0
  26. package/src/lenv-reader.lib.mjs +206 -0
  27. package/src/lib.mjs +490 -0
  28. package/src/lino.lib.mjs +176 -0
  29. package/src/local-ci-checks.lib.mjs +324 -0
  30. package/src/memory-check.mjs +419 -0
  31. package/src/model-mapping.lib.mjs +145 -0
  32. package/src/model-validation.lib.mjs +278 -0
  33. package/src/opencode.lib.mjs +479 -0
  34. package/src/opencode.prompts.lib.mjs +194 -0
  35. package/src/protect-branch.mjs +159 -0
  36. package/src/review.mjs +433 -0
  37. package/src/reviewers-hive.mjs +643 -0
  38. package/src/sentry.lib.mjs +284 -0
  39. package/src/solve.auto-continue.lib.mjs +568 -0
  40. package/src/solve.auto-pr.lib.mjs +1374 -0
  41. package/src/solve.branch-errors.lib.mjs +341 -0
  42. package/src/solve.branch.lib.mjs +230 -0
  43. package/src/solve.config.lib.mjs +342 -0
  44. package/src/solve.error-handlers.lib.mjs +256 -0
  45. package/src/solve.execution.lib.mjs +291 -0
  46. package/src/solve.feedback.lib.mjs +436 -0
  47. package/src/solve.mjs +1128 -0
  48. package/src/solve.preparation.lib.mjs +210 -0
  49. package/src/solve.repo-setup.lib.mjs +114 -0
  50. package/src/solve.repository.lib.mjs +961 -0
  51. package/src/solve.results.lib.mjs +558 -0
  52. package/src/solve.session.lib.mjs +135 -0
  53. package/src/solve.validation.lib.mjs +325 -0
  54. package/src/solve.watch.lib.mjs +572 -0
  55. package/src/start-screen.mjs +324 -0
  56. package/src/task.mjs +308 -0
  57. package/src/telegram-bot.mjs +1481 -0
  58. package/src/telegram-markdown.lib.mjs +64 -0
  59. package/src/usage-limit.lib.mjs +218 -0
  60. package/src/version.lib.mjs +41 -0
  61. package/src/youtrack/solve.youtrack.lib.mjs +116 -0
  62. package/src/youtrack/youtrack-sync.mjs +219 -0
  63. package/src/youtrack/youtrack.lib.mjs +425 -0
@@ -0,0 +1,284 @@
1
+ // Sentry integration library for hive-mind
2
+ import { isSentryEnabled, captureException, captureMessage, startTransaction } from './instrument.mjs';
3
+
4
+ // Lazy import of Sentry to handle cases where it's not installed
5
+ let Sentry = null;
6
+ const getSentry = async () => {
7
+ if (!Sentry) {
8
+ try {
9
+ Sentry = await import('@sentry/node');
10
+ } catch {
11
+ // Sentry not installed, return null
12
+ return null;
13
+ }
14
+ }
15
+ return Sentry;
16
+ };
17
+
18
+ // Flag to track if Sentry should be disabled
19
+ let sentryDisabled = false;
20
+
21
+ /**
22
+ * Initialize Sentry integration
23
+ * This should be called early in the application lifecycle
24
+ * @param {Object} options - Configuration options
25
+ * @param {boolean} options.noSentry - Disable Sentry if true
26
+ * @param {boolean} options.debug - Enable debug mode
27
+ * @param {string} options.environment - Environment name (production, development, etc)
28
+ */
29
+ export const initializeSentry = async (options = {}) => {
30
+ // Check if --no-sentry flag is present
31
+ if (options.noSentry || process.argv.includes('--no-sentry')) {
32
+ sentryDisabled = true;
33
+ if (options.debug) {
34
+ console.log('ℹ️ Sentry is disabled via --no-sentry flag');
35
+ }
36
+ return;
37
+ }
38
+
39
+ // Sentry is already initialized in instrument.mjs
40
+ // This function is for additional runtime configuration
41
+ if (isSentryEnabled()) {
42
+ const sentry = await getSentry();
43
+ if (sentry) {
44
+ // Set user context if available
45
+ if (process.env.USER || process.env.USERNAME) {
46
+ sentry.setUser({
47
+ username: process.env.USER || process.env.USERNAME,
48
+ });
49
+ }
50
+
51
+ // Set additional tags
52
+ sentry.setTags({
53
+ node_version: process.version,
54
+ platform: process.platform,
55
+ arch: process.arch,
56
+ hive_mind_version: options.version || process.env.npm_package_version || 'unknown',
57
+ });
58
+
59
+ if (options.debug) {
60
+ console.log('✅ Sentry integration configured');
61
+ }
62
+ }
63
+ }
64
+ };
65
+
66
+ /**
67
+ * Wrap a function with Sentry error tracking
68
+ * @param {Function} fn - Function to wrap
69
+ * @param {string} name - Name of the operation
70
+ * @param {string} op - Operation type (default: 'task')
71
+ * @returns {Function} Wrapped function
72
+ */
73
+ export const withSentry = (fn, name, op = 'task') => {
74
+ return async (...args) => {
75
+ if (!isSentryEnabled() || sentryDisabled) {
76
+ return fn(...args);
77
+ }
78
+
79
+ const transaction = startTransaction(name, op);
80
+
81
+ try {
82
+ const result = await fn(...args);
83
+ transaction.setStatus('ok');
84
+ return result;
85
+ } catch (error) {
86
+ transaction.setStatus('internal_error');
87
+ captureException(error, {
88
+ operation: name,
89
+ args: args.length > 0 ? `${args.length} arguments` : 'no arguments',
90
+ });
91
+ throw error;
92
+ } finally {
93
+ // In Sentry v10, use end() instead of finish()
94
+ if (transaction.end) {
95
+ transaction.end();
96
+ } else if (transaction.finish) {
97
+ // Fallback for compatibility
98
+ transaction.finish();
99
+ }
100
+ }
101
+ };
102
+ };
103
+
104
+ /**
105
+ * Create a Sentry span for tracking a specific operation
106
+ * @param {string} name - Name of the span
107
+ * @param {Function} callback - Callback to execute within the span
108
+ * @returns {Promise} Result of the callback
109
+ */
110
+ export const withSpan = async (name, callback) => {
111
+ if (!isSentryEnabled() || sentryDisabled) {
112
+ return callback();
113
+ }
114
+
115
+ const sentry = await getSentry();
116
+ if (!sentry) {
117
+ return callback();
118
+ }
119
+
120
+ return sentry.startSpan({
121
+ name,
122
+ op: 'function',
123
+ }, async () => {
124
+ return callback();
125
+ });
126
+ };
127
+
128
+ /**
129
+ * Log a message to Sentry
130
+ * @param {string} message - Message to log
131
+ * @param {string} level - Log level (debug, info, warning, error, fatal)
132
+ * @param {Object} context - Additional context
133
+ */
134
+ export const logToSentry = (message, level = 'info', context = {}) => {
135
+ if (!isSentryEnabled() || sentryDisabled) {
136
+ return;
137
+ }
138
+
139
+ captureMessage(message, level, context);
140
+ };
141
+
142
+ /**
143
+ * Report an error to Sentry
144
+ * Use this for actual errors that indicate something went wrong
145
+ * @param {Error} error - Error to capture
146
+ * @param {Object} context - Additional context
147
+ */
148
+ export const reportError = (error, context = {}) => {
149
+ if (!isSentryEnabled() || sentryDisabled) {
150
+ return;
151
+ }
152
+
153
+ captureException(error, { ...context, level: 'error' });
154
+ };
155
+
156
+ /**
157
+ * Report a warning to Sentry
158
+ * Use this for non-critical issues that should be tracked but don't indicate failure
159
+ * @param {string|Error} warning - Warning message or error object
160
+ * @param {Object} context - Additional context
161
+ */
162
+ export const reportWarning = (warning, context = {}) => {
163
+ if (!isSentryEnabled() || sentryDisabled) {
164
+ return;
165
+ }
166
+
167
+ // Convert string warnings to Error objects for better stack traces
168
+ const warningError = typeof warning === 'string' ? new Error(warning) : warning;
169
+ captureException(warningError, { ...context, level: 'warning' });
170
+ };
171
+
172
+ /**
173
+ * Add breadcrumb for better error context
174
+ * @param {Object} breadcrumb - Breadcrumb data
175
+ */
176
+ export const addBreadcrumb = async (breadcrumb) => {
177
+ if (!isSentryEnabled() || sentryDisabled) {
178
+ return;
179
+ }
180
+
181
+ const sentry = await getSentry();
182
+ if (sentry) {
183
+ sentry.addBreadcrumb(breadcrumb);
184
+ }
185
+ };
186
+
187
+ /**
188
+ * Set user context for Sentry
189
+ * @param {Object} user - User data
190
+ */
191
+ export const setUserContext = async (user) => {
192
+ if (!isSentryEnabled() || sentryDisabled) {
193
+ return;
194
+ }
195
+
196
+ const sentry = await getSentry();
197
+ if (sentry) {
198
+ sentry.setUser(user);
199
+ }
200
+ };
201
+
202
+ /**
203
+ * Set extra context for Sentry
204
+ * @param {string} key - Context key
205
+ * @param {any} value - Context value
206
+ */
207
+ export const setExtraContext = async (key, value) => {
208
+ if (!isSentryEnabled() || sentryDisabled) {
209
+ return;
210
+ }
211
+
212
+ const sentry = await getSentry();
213
+ if (sentry) {
214
+ sentry.setExtra(key, value);
215
+ }
216
+ };
217
+
218
+ /**
219
+ * Set tags for Sentry
220
+ * @param {Object} tags - Tags to set
221
+ */
222
+ export const setTags = async (tags) => {
223
+ if (!isSentryEnabled() || sentryDisabled) {
224
+ return;
225
+ }
226
+
227
+ const sentry = await getSentry();
228
+ if (sentry) {
229
+ sentry.setTags(tags);
230
+ }
231
+ };
232
+
233
+ /**
234
+ * Flush Sentry events before exit
235
+ * @param {number} timeout - Timeout in milliseconds (default: 2000)
236
+ * @returns {Promise} Promise that resolves when flush is complete
237
+ */
238
+ export const flushSentry = async (timeout = 2000) => {
239
+ if (!isSentryEnabled() || sentryDisabled) {
240
+ return;
241
+ }
242
+
243
+ const sentry = await getSentry();
244
+ if (!sentry) {
245
+ return;
246
+ }
247
+
248
+ try {
249
+ await sentry.flush(timeout);
250
+ } catch (error) {
251
+ // Silently fail if flush fails
252
+ if (process.env.DEBUG === 'true') {
253
+ console.error('Failed to flush Sentry events:', error.message);
254
+ }
255
+ }
256
+ };
257
+
258
+ /**
259
+ * Close Sentry client
260
+ * @param {number} timeout - Timeout in milliseconds (default: 2000)
261
+ * @returns {Promise} Promise that resolves when close is complete
262
+ */
263
+ export const closeSentry = async (timeout = 2000) => {
264
+ if (!isSentryEnabled() || sentryDisabled) {
265
+ return;
266
+ }
267
+
268
+ const sentry = await getSentry();
269
+ if (!sentry) {
270
+ return;
271
+ }
272
+
273
+ try {
274
+ await sentry.close(timeout);
275
+ } catch (error) {
276
+ // Silently fail if close fails
277
+ if (process.env.DEBUG === 'true') {
278
+ console.error('Failed to close Sentry:', error.message);
279
+ }
280
+ }
281
+ };
282
+
283
+ // Export the Sentry check function
284
+ export { isSentryEnabled };