@hasna/terminal 2.3.2 → 3.0.1

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 (50) hide show
  1. package/dist/ai.js +56 -82
  2. package/dist/cache.js +3 -2
  3. package/dist/cli.js +1 -1
  4. package/dist/compression.js +8 -30
  5. package/dist/context-hints.js +20 -10
  6. package/dist/diff-cache.js +1 -1
  7. package/dist/discover.js +1 -1
  8. package/dist/economy.js +37 -5
  9. package/dist/expand-store.js +7 -1
  10. package/dist/mcp/server.js +44 -68
  11. package/dist/output-processor.js +10 -7
  12. package/dist/providers/anthropic.js +6 -2
  13. package/dist/providers/cerebras.js +6 -93
  14. package/dist/providers/groq.js +6 -93
  15. package/dist/providers/index.js +85 -36
  16. package/dist/providers/openai-compat.js +93 -0
  17. package/dist/providers/xai.js +6 -93
  18. package/dist/tokens.js +17 -0
  19. package/dist/tool-profiles.js +9 -2
  20. package/package.json +1 -1
  21. package/src/ai.ts +60 -90
  22. package/src/cache.ts +3 -2
  23. package/src/cli.tsx +1 -1
  24. package/src/compression.ts +8 -35
  25. package/src/context-hints.ts +20 -10
  26. package/src/diff-cache.ts +1 -1
  27. package/src/discover.ts +1 -1
  28. package/src/economy.ts +37 -5
  29. package/src/expand-store.ts +8 -1
  30. package/src/mcp/server.ts +45 -73
  31. package/src/output-processor.ts +11 -8
  32. package/src/providers/anthropic.ts +6 -2
  33. package/src/providers/base.ts +2 -0
  34. package/src/providers/cerebras.ts +6 -105
  35. package/src/providers/groq.ts +6 -105
  36. package/src/providers/index.ts +84 -33
  37. package/src/providers/openai-compat.ts +109 -0
  38. package/src/providers/xai.ts +6 -105
  39. package/src/tokens.ts +18 -0
  40. package/src/tool-profiles.ts +9 -2
  41. package/src/compression.test.ts +0 -49
  42. package/src/output-router.ts +0 -56
  43. package/src/parsers/base.ts +0 -72
  44. package/src/parsers/build.ts +0 -73
  45. package/src/parsers/errors.ts +0 -107
  46. package/src/parsers/files.ts +0 -91
  47. package/src/parsers/git.ts +0 -101
  48. package/src/parsers/index.ts +0 -66
  49. package/src/parsers/parsers.test.ts +0 -153
  50. package/src/parsers/tests.ts +0 -98
@@ -1,98 +0,0 @@
1
- // Parser for test runner output (jest, vitest, bun test, pytest, go test)
2
-
3
- import type { Parser, TestResult } from "./base.js";
4
-
5
- export const testParser: Parser<TestResult> = {
6
- name: "test",
7
-
8
- detect(command: string, output: string): boolean {
9
- if (/\b(jest|vitest|bun\s+test|pytest|go\s+test|mocha|ava|tap)\b/.test(command)) return true;
10
- if (/\b(npm|bun|pnpm|yarn)\s+(run\s+)?test\b/.test(command)) return true;
11
- // Detect by output patterns
12
- return /Tests:\s+\d+/.test(output) || /\d+\s+(passing|passed|failed)/.test(output) || /PASS|FAIL/.test(output);
13
- },
14
-
15
- parse(_command: string, output: string): TestResult {
16
- const failures: { test: string; error: string }[] = [];
17
- let passed = 0, failed = 0, skipped = 0, duration: string | undefined;
18
-
19
- // Jest/Vitest style: Tests: 5 passed, 2 failed, 7 total
20
- const jestMatch = output.match(/Tests:\s+(?:(\d+)\s+passed)?[,\s]*(?:(\d+)\s+failed)?[,\s]*(?:(\d+)\s+skipped)?[,\s]*(\d+)\s+total/);
21
- if (jestMatch) {
22
- passed = parseInt(jestMatch[1] ?? "0");
23
- failed = parseInt(jestMatch[2] ?? "0");
24
- skipped = parseInt(jestMatch[3] ?? "0");
25
- }
26
-
27
- // Bun test style: 5 pass, 2 fail
28
- const bunMatch = output.match(/(\d+)\s+pass.*?(\d+)\s+fail/);
29
- if (!jestMatch && bunMatch) {
30
- passed = parseInt(bunMatch[1]);
31
- failed = parseInt(bunMatch[2]);
32
- }
33
-
34
- // Pytest style: 5 passed, 2 failed
35
- const pytestMatch = output.match(/(\d+)\s+passed(?:.*?(\d+)\s+failed)?/);
36
- if (!jestMatch && !bunMatch && pytestMatch) {
37
- passed = parseInt(pytestMatch[1]);
38
- failed = parseInt(pytestMatch[2] ?? "0");
39
- }
40
-
41
- // Go test: ok/FAIL + count
42
- const goPassMatch = output.match(/ok\s+\S+\s+([\d.]+s)/);
43
- const goFailMatch = output.match(/FAIL\s+\S+/);
44
- if (!jestMatch && !bunMatch && !pytestMatch && (goPassMatch || goFailMatch)) {
45
- const passLines = (output.match(/--- PASS/g) || []).length;
46
- const failLines = (output.match(/--- FAIL/g) || []).length;
47
- passed = passLines;
48
- failed = failLines;
49
- if (goPassMatch) duration = goPassMatch[1];
50
- }
51
-
52
- // Duration
53
- const timeMatch = output.match(/Time:\s+([\d.]+\s*(?:s|ms|m))/i) || output.match(/in\s+([\d.]+\s*(?:s|ms|m))/i);
54
- if (timeMatch) duration = timeMatch[1];
55
-
56
- // Extract failure details: lines starting with FAIL or ✗ or ×
57
- const lines = output.split("\n");
58
- let capturingFailure = false;
59
- let currentTest = "";
60
- let currentError: string[] = [];
61
-
62
- for (const line of lines) {
63
- const failMatch = line.match(/(?:FAIL|✗|×|✕)\s+(.+)/);
64
- if (failMatch) {
65
- if (capturingFailure && currentTest) {
66
- failures.push({ test: currentTest, error: currentError.join("\n").trim() });
67
- }
68
- currentTest = failMatch[1].trim();
69
- currentError = [];
70
- capturingFailure = true;
71
- continue;
72
- }
73
-
74
- if (capturingFailure) {
75
- if (line.match(/^(PASS|✓|✔|FAIL|✗|×|✕)\s/) || line.match(/^Tests:|^\d+ pass/)) {
76
- failures.push({ test: currentTest, error: currentError.join("\n").trim() });
77
- capturingFailure = false;
78
- currentTest = "";
79
- currentError = [];
80
- } else {
81
- currentError.push(line);
82
- }
83
- }
84
- }
85
- if (capturingFailure && currentTest) {
86
- failures.push({ test: currentTest, error: currentError.join("\n").trim() });
87
- }
88
-
89
- return {
90
- passed,
91
- failed,
92
- skipped,
93
- total: passed + failed + skipped,
94
- duration,
95
- failures,
96
- };
97
- },
98
- };