@vibetasks/cli 0.5.2 → 0.5.4

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.
@@ -0,0 +1,134 @@
1
+ // src/utils/clipboard-monitor.ts
2
+ import {
3
+ parseError,
4
+ generateErrorTaskTitle
5
+ } from "@vibetasks/shared";
6
+ var clipboardy = null;
7
+ async function getClipboardy() {
8
+ if (!clipboardy) {
9
+ clipboardy = await import("clipboardy");
10
+ }
11
+ return clipboardy;
12
+ }
13
+ function detectError(text) {
14
+ return parseError(text, "clipboard");
15
+ }
16
+ function getErrorSummary(error) {
17
+ if (!error) return "Unknown error";
18
+ return generateErrorTaskTitle(error);
19
+ }
20
+ function formatErrorForNotes(error) {
21
+ if (!error) return "";
22
+ const lines = [];
23
+ lines.push(`## Error Details`);
24
+ lines.push("");
25
+ if (error.error_type) {
26
+ lines.push(`**Type:** ${error.error_type}`);
27
+ }
28
+ if (error.category) {
29
+ lines.push(`**Category:** ${error.category}`);
30
+ }
31
+ if (error.message) {
32
+ lines.push(`**Message:** ${error.message}`);
33
+ }
34
+ if (error.code) {
35
+ lines.push(`**Code:** ${error.code}`);
36
+ }
37
+ if (error.file_path) {
38
+ lines.push(`**File:** \`${error.file_path}\``);
39
+ if (error.line_number) {
40
+ lines.push(`**Line:** ${error.line_number}${error.column ? `:${error.column}` : ""}`);
41
+ }
42
+ }
43
+ if (error.suggestion) {
44
+ lines.push("");
45
+ lines.push(`### Suggestion`);
46
+ lines.push(error.suggestion);
47
+ }
48
+ if (error.stack_trace) {
49
+ lines.push("");
50
+ lines.push(`### Stack Trace`);
51
+ lines.push("```");
52
+ lines.push(error.stack_trace);
53
+ lines.push("```");
54
+ }
55
+ lines.push("");
56
+ lines.push(`### Raw Error`);
57
+ lines.push("```");
58
+ const rawLines = error.raw_text.split("\n");
59
+ if (rawLines.length > 30) {
60
+ lines.push(rawLines.slice(0, 30).join("\n"));
61
+ lines.push(`... (${rawLines.length - 30} more lines)`);
62
+ } else {
63
+ lines.push(error.raw_text);
64
+ }
65
+ lines.push("```");
66
+ return lines.join("\n");
67
+ }
68
+ function createClipboardMonitor(options) {
69
+ const interval = options.interval || 1e3;
70
+ const minLength = options.minLength || 20;
71
+ let running = false;
72
+ let lastClipboardContent = "";
73
+ let intervalId = null;
74
+ const checkClipboard = async () => {
75
+ try {
76
+ const clipboard = await getClipboardy();
77
+ const content = await clipboard.default.read();
78
+ if (content === lastClipboardContent || content.length < minLength) {
79
+ return;
80
+ }
81
+ lastClipboardContent = content;
82
+ const error = detectError(content);
83
+ if (error) {
84
+ options.onError(error);
85
+ }
86
+ } catch {
87
+ }
88
+ };
89
+ return {
90
+ start: async () => {
91
+ if (running) return;
92
+ await getClipboardy();
93
+ try {
94
+ const clipboard = await getClipboardy();
95
+ lastClipboardContent = await clipboard.default.read();
96
+ } catch {
97
+ lastClipboardContent = "";
98
+ }
99
+ running = true;
100
+ options.onStart?.();
101
+ intervalId = setInterval(checkClipboard, interval);
102
+ },
103
+ stop: () => {
104
+ if (!running) return;
105
+ running = false;
106
+ if (intervalId) {
107
+ clearInterval(intervalId);
108
+ intervalId = null;
109
+ }
110
+ options.onStop?.();
111
+ },
112
+ isRunning: () => running
113
+ };
114
+ }
115
+ async function readClipboard() {
116
+ const clipboard = await getClipboardy();
117
+ return clipboard.default.read();
118
+ }
119
+ async function checkClipboardForError() {
120
+ try {
121
+ const content = await readClipboard();
122
+ return detectError(content);
123
+ } catch {
124
+ return null;
125
+ }
126
+ }
127
+
128
+ export {
129
+ detectError,
130
+ getErrorSummary,
131
+ formatErrorForNotes,
132
+ createClipboardMonitor,
133
+ checkClipboardForError
134
+ };
@@ -3,13 +3,14 @@ import {
3
3
  detectError,
4
4
  formatErrorForNotes,
5
5
  getErrorSummary
6
- } from "../chunk-PZF4VRDG.js";
6
+ } from "../chunk-S3G6KYGP.js";
7
7
  import {
8
8
  daemonConfigManager
9
9
  } from "../chunk-2KRLRG4G.js";
10
10
 
11
11
  // src/daemon-worker.ts
12
12
  import { AuthManager, TaskOperations } from "@vibetasks/core";
13
+ import { generateErrorTaskTitle } from "@vibetasks/shared";
13
14
  function log(message, level = "info") {
14
15
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
15
16
  const prefix = level === "error" ? "[ERROR]" : level === "warn" ? "[WARN]" : "[INFO]";
@@ -104,7 +105,7 @@ async function handleShortcutTriggered(config) {
104
105
  await showNotification("VibeTasks", "No error detected in clipboard", "info");
105
106
  return;
106
107
  }
107
- log(`Error detected: ${error.type} - ${error.message.substring(0, 50)}...`);
108
+ log(`Error detected: ${error.error_type || "Unknown"} - ${(error.message || "").substring(0, 50)}...`);
108
109
  const summary = getErrorSummary(error);
109
110
  await showNotification(
110
111
  "VibeTasks: Error Detected",
@@ -139,45 +140,22 @@ async function showNotification(title, message, type = "info", duration) {
139
140
  log(`Failed to show notification: ${error.message}`, "warn");
140
141
  }
141
142
  }
142
- function generateTaskTitle(error) {
143
- const prefixes = {
144
- nodejs: "Fix",
145
- npm: "Resolve npm",
146
- expo: "Fix Expo",
147
- "react-native": "Fix RN",
148
- webpack: "Fix build",
149
- typescript: "Fix TS",
150
- python: "Fix Python",
151
- generic: "Fix"
152
- };
153
- const prefix = prefixes[error.category] || "Fix";
154
- let title = `${prefix} ${error.type}`;
155
- if (error.message && error.message.length < 60) {
156
- title += `: ${error.message}`;
157
- } else if (error.message) {
158
- const shortMessage = error.message.split(/[.!?\n]/)[0].trim();
159
- if (shortMessage.length < 60) {
160
- title += `: ${shortMessage}`;
161
- }
162
- }
163
- if (title.length > 120) {
164
- title = title.substring(0, 117) + "...";
165
- }
166
- return title;
167
- }
168
143
  async function createTaskFromError(error) {
169
144
  try {
170
145
  const authManager = new AuthManager();
171
146
  const taskOps = await TaskOperations.fromAuthManager(authManager);
172
- const title = generateTaskTitle(error);
147
+ const title = generateErrorTaskTitle(error);
173
148
  const notes = formatErrorForNotes(error);
149
+ const category = error.category || "general";
174
150
  const task = await taskOps.createTask({
175
151
  title,
176
152
  notes,
177
153
  notes_format: "markdown",
178
- priority: error.category === "typescript" ? "medium" : "high",
154
+ priority: category === "typescript" ? "medium" : "high",
179
155
  created_by: "ai",
180
- status: "todo"
156
+ status: "todo",
157
+ source_type: "cli",
158
+ error_context: error
181
159
  });
182
160
  log(`Task created: ${task.id}`);
183
161
  await showNotification(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibetasks/cli",
3
- "version": "0.5.2",
3
+ "version": "0.5.4",
4
4
  "description": "VibeTasks CLI - Lightning-fast task management from your terminal. Works with Claude Code, Cursor, and all AI coding tools.",
5
5
  "author": "Vyas",
6
6
  "license": "MIT",
@@ -45,8 +45,8 @@
45
45
  "typecheck": "tsc --noEmit"
46
46
  },
47
47
  "dependencies": {
48
- "@vibetasks/core": "^0.5.2",
49
- "@vibetasks/shared": "^1.2.2",
48
+ "@vibetasks/core": "^0.5.4",
49
+ "@vibetasks/shared": "^1.3.1",
50
50
  "commander": "^11.1.0",
51
51
  "chalk": "^5.3.0",
52
52
  "ora": "^8.0.1",
@@ -1,430 +0,0 @@
1
- // src/utils/clipboard-monitor.ts
2
- var clipboardy = null;
3
- async function getClipboardy() {
4
- if (!clipboardy) {
5
- clipboardy = await import("clipboardy");
6
- }
7
- return clipboardy;
8
- }
9
- var nodeJsPatterns = {
10
- name: "Node.js Errors",
11
- category: "nodejs",
12
- patterns: [
13
- /^(Error|TypeError|ReferenceError|SyntaxError|RangeError|EvalError|URIError):\s*.+/m,
14
- /^\s+at\s+.+\(.+:\d+:\d+\)/m,
15
- /^Uncaught\s+(Error|TypeError|ReferenceError):/m,
16
- /^UnhandledPromiseRejectionWarning:/m,
17
- /^node:internal\//m
18
- ],
19
- extractInfo: (text) => {
20
- const errorMatch = text.match(
21
- /^(Error|TypeError|ReferenceError|SyntaxError|RangeError|EvalError|URIError):\s*(.+)/m
22
- );
23
- if (!errorMatch) return null;
24
- const stackMatch = text.match(/at\s+(?:.+\s+)?\((.+):(\d+):(\d+)\)/);
25
- const file = stackMatch?.[1];
26
- const line = stackMatch ? parseInt(stackMatch[2], 10) : void 0;
27
- const column = stackMatch ? parseInt(stackMatch[3], 10) : void 0;
28
- const stackLines = text.split("\n").filter((l) => l.trim().startsWith("at "));
29
- const stack = stackLines.length > 0 ? stackLines.join("\n") : void 0;
30
- return {
31
- type: errorMatch[1],
32
- category: "nodejs",
33
- message: errorMatch[2].trim(),
34
- stack,
35
- file,
36
- line,
37
- column,
38
- rawText: text
39
- };
40
- }
41
- };
42
- var npmPatterns = {
43
- name: "npm Errors",
44
- category: "npm",
45
- patterns: [
46
- /npm ERR!/,
47
- /npm WARN/,
48
- /ERESOLVE/,
49
- /E404/,
50
- /ENOENT/,
51
- /EPERM/,
52
- /EACCES/,
53
- /peer dep missing/i,
54
- /Could not resolve dependency/
55
- ],
56
- extractInfo: (text) => {
57
- const codeMatch = text.match(/npm ERR! code\s+(\w+)/);
58
- const code = codeMatch?.[1];
59
- const summaryMatch = text.match(/npm ERR!\s+(.+)/);
60
- const message = summaryMatch?.[1] || "npm error detected";
61
- if (text.includes("ERESOLVE")) {
62
- const conflictMatch = text.match(/Conflicting peer dependency:\s*(.+)/);
63
- return {
64
- type: "ERESOLVE",
65
- category: "npm",
66
- message: conflictMatch?.[1] || "Dependency resolution conflict",
67
- code: "ERESOLVE",
68
- suggestion: "Try: npm install --legacy-peer-deps or npm install --force",
69
- rawText: text
70
- };
71
- }
72
- if (text.includes("E404") || text.includes("404 Not Found")) {
73
- const packageMatch = text.match(/Not Found.*?:\s*(.+)/);
74
- return {
75
- type: "E404",
76
- category: "npm",
77
- message: `Package not found: ${packageMatch?.[1] || "unknown"}`,
78
- code: "E404",
79
- suggestion: "Check package name spelling or registry configuration",
80
- rawText: text
81
- };
82
- }
83
- return {
84
- type: "npm error",
85
- category: "npm",
86
- message,
87
- code,
88
- rawText: text
89
- };
90
- }
91
- };
92
- var expoPatterns = {
93
- name: "Expo/React Native Errors",
94
- category: "expo",
95
- patterns: [
96
- /Error:\s*Unable to resolve module/,
97
- /Metro Bundler/i,
98
- /BUNDLE\s+.*failed/i,
99
- /Red Box/i,
100
- /Invariant Violation/,
101
- /Native module.+cannot be null/,
102
- /Cannot read property.+of undefined/,
103
- /expo-.*error/i,
104
- /RCTFatalException/,
105
- /ExceptionsManager/
106
- ],
107
- extractInfo: (text) => {
108
- const moduleMatch = text.match(/Unable to resolve module\s+['"]?([^'"]+)['"]?/);
109
- if (moduleMatch) {
110
- return {
111
- type: "ModuleResolutionError",
112
- category: "expo",
113
- message: `Cannot find module: ${moduleMatch[1]}`,
114
- suggestion: `Try: npx expo install ${moduleMatch[1]}`,
115
- rawText: text
116
- };
117
- }
118
- const invariantMatch = text.match(/Invariant Violation:\s*(.+)/);
119
- if (invariantMatch) {
120
- return {
121
- type: "InvariantViolation",
122
- category: "expo",
123
- message: invariantMatch[1].trim(),
124
- rawText: text
125
- };
126
- }
127
- const nativeMatch = text.match(/Native module\s+['"]?([^'"]+)['"]?\s+cannot be null/);
128
- if (nativeMatch) {
129
- return {
130
- type: "NativeModuleError",
131
- category: "expo",
132
- message: `Native module missing: ${nativeMatch[1]}`,
133
- suggestion: "Try: npx expo prebuild --clean && npx expo run:ios/android",
134
- rawText: text
135
- };
136
- }
137
- if (text.includes("BUNDLE") && text.includes("failed")) {
138
- return {
139
- type: "BundleError",
140
- category: "expo",
141
- message: "Metro bundler failed to build",
142
- suggestion: "Try: npx expo start -c (clear cache)",
143
- rawText: text
144
- };
145
- }
146
- return {
147
- type: "ExpoError",
148
- category: "expo",
149
- message: "Expo/React Native error detected",
150
- rawText: text
151
- };
152
- }
153
- };
154
- var webpackPatterns = {
155
- name: "Webpack/Build Errors",
156
- category: "webpack",
157
- patterns: [
158
- /Module not found:\s*Error/,
159
- /ModuleNotFoundError/,
160
- /ERROR in\s+/,
161
- /webpack.*error/i,
162
- /Failed to compile/i,
163
- /Module build failed/,
164
- /Syntax error in/i,
165
- /Can't resolve/,
166
- /You may need an appropriate loader/
167
- ],
168
- extractInfo: (text) => {
169
- const moduleMatch = text.match(/Can't resolve\s+['"]?([^'"]+)['"]?/);
170
- if (moduleMatch) {
171
- return {
172
- type: "ModuleNotFound",
173
- category: "webpack",
174
- message: `Cannot resolve: ${moduleMatch[1]}`,
175
- suggestion: `Try: npm install ${moduleMatch[1]}`,
176
- rawText: text
177
- };
178
- }
179
- const fileMatch = text.match(/ERROR in\s+(.+):(\d+):(\d+)/);
180
- if (fileMatch) {
181
- return {
182
- type: "WebpackError",
183
- category: "webpack",
184
- message: "Build error",
185
- file: fileMatch[1],
186
- line: parseInt(fileMatch[2], 10),
187
- column: parseInt(fileMatch[3], 10),
188
- rawText: text
189
- };
190
- }
191
- if (text.includes("appropriate loader")) {
192
- const extensionMatch = text.match(/\.(\w+)(?:\?|$)/);
193
- return {
194
- type: "LoaderError",
195
- category: "webpack",
196
- message: `Missing loader for .${extensionMatch?.[1] || "unknown"} files`,
197
- suggestion: "Check webpack.config.js for missing loaders",
198
- rawText: text
199
- };
200
- }
201
- return {
202
- type: "WebpackError",
203
- category: "webpack",
204
- message: "Webpack build error detected",
205
- rawText: text
206
- };
207
- }
208
- };
209
- var typescriptPatterns = {
210
- name: "TypeScript Errors",
211
- category: "typescript",
212
- patterns: [
213
- /TS\d+:/,
214
- /error TS\d+/,
215
- /Type '.+' is not assignable to type/,
216
- /Property '.+' does not exist on type/,
217
- /Cannot find module '.+' or its corresponding type declarations/,
218
- /Argument of type '.+' is not assignable/,
219
- /Object is possibly 'undefined'/,
220
- /Object is possibly 'null'/
221
- ],
222
- extractInfo: (text) => {
223
- const codeMatch = text.match(/TS(\d+)/);
224
- const code = codeMatch ? `TS${codeMatch[1]}` : void 0;
225
- const fileMatch = text.match(/(.+\.tsx?)\((\d+),(\d+)\)/);
226
- const file = fileMatch?.[1];
227
- const line = fileMatch ? parseInt(fileMatch[2], 10) : void 0;
228
- const column = fileMatch ? parseInt(fileMatch[3], 10) : void 0;
229
- const messageMatch = text.match(/error TS\d+:\s*(.+)/);
230
- const message = messageMatch?.[1] || "TypeScript error detected";
231
- return {
232
- type: "TypeScriptError",
233
- category: "typescript",
234
- message,
235
- code,
236
- file,
237
- line,
238
- column,
239
- rawText: text
240
- };
241
- }
242
- };
243
- var pythonPatterns = {
244
- name: "Python Errors",
245
- category: "python",
246
- patterns: [
247
- /Traceback \(most recent call last\)/,
248
- /^\s+File ".+", line \d+/m,
249
- /^(NameError|TypeError|ValueError|KeyError|AttributeError|ImportError|ModuleNotFoundError|SyntaxError|IndentationError|IndexError|ZeroDivisionError|FileNotFoundError):/m,
250
- /raise\s+\w+Error/
251
- ],
252
- extractInfo: (text) => {
253
- if (!text.includes("Traceback")) {
254
- const errorMatch2 = text.match(
255
- /^(NameError|TypeError|ValueError|KeyError|AttributeError|ImportError|ModuleNotFoundError|SyntaxError|IndentationError|IndexError|ZeroDivisionError|FileNotFoundError):\s*(.+)/m
256
- );
257
- if (errorMatch2) {
258
- return {
259
- type: errorMatch2[1],
260
- category: "python",
261
- message: errorMatch2[2].trim(),
262
- rawText: text
263
- };
264
- }
265
- return null;
266
- }
267
- const lines = text.split("\n").filter((l) => l.trim());
268
- const lastLine = lines[lines.length - 1];
269
- const errorMatch = lastLine.match(/^(\w+Error):\s*(.+)/);
270
- const fileMatch = text.match(/File "(.+)", line (\d+)/);
271
- const file = fileMatch?.[1];
272
- const line = fileMatch ? parseInt(fileMatch[2], 10) : void 0;
273
- const stackLines = text.split("\n").filter((l) => l.trim().startsWith("File "));
274
- const stack = stackLines.join("\n");
275
- return {
276
- type: errorMatch?.[1] || "PythonError",
277
- category: "python",
278
- message: errorMatch?.[2] || "Python error detected",
279
- stack,
280
- file,
281
- line,
282
- rawText: text
283
- };
284
- }
285
- };
286
- var ALL_PATTERNS = [
287
- nodeJsPatterns,
288
- npmPatterns,
289
- expoPatterns,
290
- webpackPatterns,
291
- typescriptPatterns,
292
- pythonPatterns
293
- ];
294
- function detectError(text) {
295
- if (!text || text.length < 10) return null;
296
- for (const pattern of ALL_PATTERNS) {
297
- const hasMatch = pattern.patterns.some((p) => p.test(text));
298
- if (hasMatch) {
299
- const info = pattern.extractInfo(text);
300
- if (info) return info;
301
- }
302
- }
303
- return null;
304
- }
305
- function getErrorSummary(error) {
306
- const parts = [];
307
- parts.push(`[${error.category.toUpperCase()}]`);
308
- parts.push(error.type);
309
- if (error.message.length > 80) {
310
- parts.push(error.message.substring(0, 77) + "...");
311
- } else {
312
- parts.push(error.message);
313
- }
314
- if (error.file) {
315
- const shortFile = error.file.split(/[/\\]/).slice(-2).join("/");
316
- parts.push(`@ ${shortFile}`);
317
- if (error.line) {
318
- parts[parts.length - 1] += `:${error.line}`;
319
- }
320
- }
321
- return parts.join(" ");
322
- }
323
- function formatErrorForNotes(error) {
324
- const lines = [];
325
- lines.push(`## Error Details`);
326
- lines.push("");
327
- lines.push(`**Type:** ${error.type}`);
328
- lines.push(`**Category:** ${error.category}`);
329
- lines.push(`**Message:** ${error.message}`);
330
- if (error.code) {
331
- lines.push(`**Code:** ${error.code}`);
332
- }
333
- if (error.file) {
334
- lines.push(`**File:** \`${error.file}\``);
335
- if (error.line) {
336
- lines.push(`**Line:** ${error.line}${error.column ? `:${error.column}` : ""}`);
337
- }
338
- }
339
- if (error.suggestion) {
340
- lines.push("");
341
- lines.push(`### Suggestion`);
342
- lines.push(error.suggestion);
343
- }
344
- if (error.stack) {
345
- lines.push("");
346
- lines.push(`### Stack Trace`);
347
- lines.push("```");
348
- lines.push(error.stack);
349
- lines.push("```");
350
- }
351
- lines.push("");
352
- lines.push(`### Raw Error`);
353
- lines.push("```");
354
- const rawLines = error.rawText.split("\n");
355
- if (rawLines.length > 30) {
356
- lines.push(rawLines.slice(0, 30).join("\n"));
357
- lines.push(`... (${rawLines.length - 30} more lines)`);
358
- } else {
359
- lines.push(error.rawText);
360
- }
361
- lines.push("```");
362
- return lines.join("\n");
363
- }
364
- function createClipboardMonitor(options) {
365
- const interval = options.interval || 1e3;
366
- const minLength = options.minLength || 20;
367
- let running = false;
368
- let lastClipboardContent = "";
369
- let intervalId = null;
370
- const checkClipboard = async () => {
371
- try {
372
- const clipboard = await getClipboardy();
373
- const content = await clipboard.default.read();
374
- if (content === lastClipboardContent || content.length < minLength) {
375
- return;
376
- }
377
- lastClipboardContent = content;
378
- const error = detectError(content);
379
- if (error) {
380
- options.onError(error);
381
- }
382
- } catch {
383
- }
384
- };
385
- return {
386
- start: async () => {
387
- if (running) return;
388
- await getClipboardy();
389
- try {
390
- const clipboard = await getClipboardy();
391
- lastClipboardContent = await clipboard.default.read();
392
- } catch {
393
- lastClipboardContent = "";
394
- }
395
- running = true;
396
- options.onStart?.();
397
- intervalId = setInterval(checkClipboard, interval);
398
- },
399
- stop: () => {
400
- if (!running) return;
401
- running = false;
402
- if (intervalId) {
403
- clearInterval(intervalId);
404
- intervalId = null;
405
- }
406
- options.onStop?.();
407
- },
408
- isRunning: () => running
409
- };
410
- }
411
- async function readClipboard() {
412
- const clipboard = await getClipboardy();
413
- return clipboard.default.read();
414
- }
415
- async function checkClipboardForError() {
416
- try {
417
- const content = await readClipboard();
418
- return detectError(content);
419
- } catch {
420
- return null;
421
- }
422
- }
423
-
424
- export {
425
- detectError,
426
- getErrorSummary,
427
- formatErrorForNotes,
428
- createClipboardMonitor,
429
- checkClipboardForError
430
- };