@travisennis/acai 0.0.1 → 0.0.2

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 (323) hide show
  1. package/README.md +3 -4
  2. package/dist/commands/health-command.d.ts +2 -0
  3. package/dist/commands/health-command.js +59 -0
  4. package/dist/commands/manager.js +2 -0
  5. package/dist/commands/paste-command.d.ts +1 -1
  6. package/dist/commands/paste-command.js +155 -11
  7. package/dist/commands/reset-command.js +1 -0
  8. package/dist/index.js +1 -1
  9. package/dist/models/openrouter-provider.d.ts +4 -1
  10. package/dist/models/openrouter-provider.js +46 -4
  11. package/dist/models/providers.d.ts +1 -1
  12. package/dist/prompts/manager.d.ts +1 -0
  13. package/dist/prompts/manager.js +10 -0
  14. package/dist/prompts.js +8 -6
  15. package/dist/repl.js +49 -26
  16. package/dist/terminal/formatting.d.ts +16 -5
  17. package/dist/terminal/formatting.js +40 -6
  18. package/dist/terminal/index.d.ts +1 -1
  19. package/dist/terminal/index.js +54 -14
  20. package/dist/terminal/markdown.js +0 -1
  21. package/dist/terminal/supports-color.d.ts +16 -0
  22. package/dist/terminal/supports-color.js +121 -0
  23. package/dist/terminal/supports-hyperlinks.d.ts +7 -0
  24. package/dist/terminal/supports-hyperlinks.js +98 -0
  25. package/dist/tools/bash.js +95 -117
  26. package/dist/tools/code-interpreter.js +11 -1
  27. package/dist/tools/command-validation.d.ts +7 -3
  28. package/dist/tools/command-validation.js +67 -23
  29. package/dist/tools/delete-file.d.ts +4 -1
  30. package/dist/tools/delete-file.js +47 -3
  31. package/dist/tools/git-utils.d.ts +6 -0
  32. package/dist/tools/git-utils.js +89 -12
  33. package/dist/tools/grep.d.ts +20 -0
  34. package/dist/tools/grep.js +128 -40
  35. package/dist/tools/index.d.ts +2 -18
  36. package/dist/tools/index.js +4 -18
  37. package/package.json +30 -20
  38. package/.acai/acai.json +0 -9
  39. package/.acai/prompts/add-openrouter-model.md +0 -13
  40. package/.acai/prompts/project-status.md +0 -4
  41. package/.acai/prompts/update-architecture-document.md +0 -9
  42. package/.acai/rules/learned-rules.md +0 -9
  43. package/.ai/docs/available-tools.txt +0 -3
  44. package/.ai/docs/cognitive_complexity_refactoring_progress.md +0 -65
  45. package/.ai/docs/deleted_tools.md +0 -168
  46. package/.ai/docs/deleted_tools_88ced9ef.md +0 -56
  47. package/.ai/docs/image-pasting.md +0 -46
  48. package/.ai/docs/initialize-app.md +0 -117
  49. package/.ai/docs/issue-4-plan.md +0 -44
  50. package/.ai/docs/marked-renderer-debug.md +0 -15
  51. package/.ai/docs/marked-renderer-refactor-plan.md +0 -64
  52. package/.ai/docs/memory-use-cases.md +0 -55
  53. package/.ai/docs/prompt-consistency.md +0 -31
  54. package/.ai/docs/refactoring-tools.md +0 -98
  55. package/.ai/docs/system-prompt-update.md +0 -174
  56. package/.ai/docs/system_prompt.txt +0 -210
  57. package/.ai/docs/tasks.md +0 -49
  58. package/.ai/plan.md +0 -131
  59. package/.ai/prompt.md +0 -1
  60. package/.ai/scripts/fetch_models.js +0 -27
  61. package/.ai/scripts/generateSystemPrompt.ts +0 -15
  62. package/.ai/scripts/list-tools.mjs +0 -4
  63. package/.ai/scripts/p5_geometric_shapes.js +0 -149
  64. package/.husky/commit-msg +0 -1
  65. package/.husky/pre-commit +0 -3
  66. package/.husky/pre-push +0 -1
  67. package/.ignore +0 -4
  68. package/AGENTS.md +0 -25
  69. package/ARCHITECTURE.md +0 -304
  70. package/TODO.md +0 -2
  71. package/biome.json +0 -61
  72. package/commitlint.config.js +0 -3
  73. package/dist/source/cli.d.ts +0 -19
  74. package/dist/source/cli.js +0 -116
  75. package/dist/source/commands/application-log-command.d.ts +0 -2
  76. package/dist/source/commands/application-log-command.js +0 -43
  77. package/dist/source/commands/clear-command.d.ts +0 -2
  78. package/dist/source/commands/clear-command.js +0 -12
  79. package/dist/source/commands/compact-command.d.ts +0 -2
  80. package/dist/source/commands/compact-command.js +0 -51
  81. package/dist/source/commands/copy-command.d.ts +0 -2
  82. package/dist/source/commands/copy-command.js +0 -51
  83. package/dist/source/commands/edit-command.d.ts +0 -2
  84. package/dist/source/commands/edit-command.js +0 -53
  85. package/dist/source/commands/edit-prompt-command.d.ts +0 -2
  86. package/dist/source/commands/edit-prompt-command.js +0 -25
  87. package/dist/source/commands/exit-command.d.ts +0 -2
  88. package/dist/source/commands/exit-command.js +0 -14
  89. package/dist/source/commands/files-command.d.ts +0 -2
  90. package/dist/source/commands/files-command.js +0 -63
  91. package/dist/source/commands/generate-rules-command.d.ts +0 -2
  92. package/dist/source/commands/generate-rules-command.js +0 -61
  93. package/dist/source/commands/help-command.d.ts +0 -2
  94. package/dist/source/commands/help-command.js +0 -19
  95. package/dist/source/commands/init-command.d.ts +0 -2
  96. package/dist/source/commands/init-command.js +0 -40
  97. package/dist/source/commands/last-log-command.d.ts +0 -2
  98. package/dist/source/commands/last-log-command.js +0 -76
  99. package/dist/source/commands/manager.d.ts +0 -22
  100. package/dist/source/commands/manager.js +0 -123
  101. package/dist/source/commands/model-command.d.ts +0 -2
  102. package/dist/source/commands/model-command.js +0 -84
  103. package/dist/source/commands/paste-command.d.ts +0 -2
  104. package/dist/source/commands/paste-command.js +0 -40
  105. package/dist/source/commands/prompt-command.d.ts +0 -2
  106. package/dist/source/commands/prompt-command.js +0 -111
  107. package/dist/source/commands/reset-command.d.ts +0 -2
  108. package/dist/source/commands/reset-command.js +0 -16
  109. package/dist/source/commands/rules-command.d.ts +0 -2
  110. package/dist/source/commands/rules-command.js +0 -68
  111. package/dist/source/commands/save-command.d.ts +0 -2
  112. package/dist/source/commands/save-command.js +0 -14
  113. package/dist/source/commands/types.d.ts +0 -26
  114. package/dist/source/commands/types.js +0 -1
  115. package/dist/source/commands/usage-command.d.ts +0 -2
  116. package/dist/source/commands/usage-command.js +0 -21
  117. package/dist/source/config.d.ts +0 -60
  118. package/dist/source/config.js +0 -193
  119. package/dist/source/conversation-analyzer.d.ts +0 -10
  120. package/dist/source/conversation-analyzer.js +0 -88
  121. package/dist/source/dedent.d.ts +0 -3
  122. package/dist/source/dedent.js +0 -38
  123. package/dist/source/formatting.d.ts +0 -17
  124. package/dist/source/formatting.js +0 -103
  125. package/dist/source/index.d.ts +0 -18
  126. package/dist/source/index.js +0 -213
  127. package/dist/source/logger.d.ts +0 -2
  128. package/dist/source/logger.js +0 -24
  129. package/dist/source/mentions.d.ts +0 -9
  130. package/dist/source/mentions.js +0 -182
  131. package/dist/source/messages.d.ts +0 -69
  132. package/dist/source/messages.js +0 -261
  133. package/dist/source/middleware/audit-message.d.ts +0 -5
  134. package/dist/source/middleware/audit-message.js +0 -95
  135. package/dist/source/middleware/index.d.ts +0 -2
  136. package/dist/source/middleware/index.js +0 -2
  137. package/dist/source/middleware/rate-limit.d.ts +0 -4
  138. package/dist/source/middleware/rate-limit.js +0 -17
  139. package/dist/source/models/ai-config.d.ts +0 -12
  140. package/dist/source/models/ai-config.js +0 -87
  141. package/dist/source/models/anthropic-provider.d.ts +0 -25
  142. package/dist/source/models/anthropic-provider.js +0 -184
  143. package/dist/source/models/deepseek-provider.d.ts +0 -20
  144. package/dist/source/models/deepseek-provider.js +0 -42
  145. package/dist/source/models/google-provider.d.ts +0 -19
  146. package/dist/source/models/google-provider.js +0 -56
  147. package/dist/source/models/manager.d.ts +0 -15
  148. package/dist/source/models/manager.js +0 -48
  149. package/dist/source/models/openai-provider.d.ts +0 -22
  150. package/dist/source/models/openai-provider.js +0 -70
  151. package/dist/source/models/openrouter-provider.d.ts +0 -36
  152. package/dist/source/models/openrouter-provider.js +0 -276
  153. package/dist/source/models/providers.d.ts +0 -33
  154. package/dist/source/models/providers.js +0 -116
  155. package/dist/source/models/xai-provider.d.ts +0 -20
  156. package/dist/source/models/xai-provider.js +0 -47
  157. package/dist/source/parsing.d.ts +0 -2
  158. package/dist/source/parsing.js +0 -18
  159. package/dist/source/prompts/manager.d.ts +0 -19
  160. package/dist/source/prompts/manager.js +0 -71
  161. package/dist/source/prompts.d.ts +0 -4
  162. package/dist/source/prompts.js +0 -158
  163. package/dist/source/repl-prompt.d.ts +0 -14
  164. package/dist/source/repl-prompt.js +0 -147
  165. package/dist/source/repl.d.ts +0 -27
  166. package/dist/source/repl.js +0 -431
  167. package/dist/source/terminal/formatting.d.ts +0 -37
  168. package/dist/source/terminal/formatting.js +0 -106
  169. package/dist/source/terminal/index.d.ts +0 -94
  170. package/dist/source/terminal/index.js +0 -420
  171. package/dist/source/terminal/markdown-utils.d.ts +0 -2
  172. package/dist/source/terminal/markdown-utils.js +0 -81
  173. package/dist/source/terminal/markdown.d.ts +0 -1
  174. package/dist/source/terminal/markdown.js +0 -111
  175. package/dist/source/terminal/types.d.ts +0 -71
  176. package/dist/source/terminal/types.js +0 -1
  177. package/dist/source/terminal-output.d.ts +0 -8
  178. package/dist/source/terminal-output.js +0 -213
  179. package/dist/source/terminal-output.test.d.ts +0 -8
  180. package/dist/source/terminal-output.test.js +0 -213
  181. package/dist/source/token-tracker.d.ts +0 -14
  182. package/dist/source/token-tracker.js +0 -53
  183. package/dist/source/token-utils.d.ts +0 -7
  184. package/dist/source/token-utils.js +0 -13
  185. package/dist/source/tools/agent.d.ts +0 -17
  186. package/dist/source/tools/agent.js +0 -87
  187. package/dist/source/tools/bash.d.ts +0 -19
  188. package/dist/source/tools/bash.js +0 -294
  189. package/dist/source/tools/code-interpreter.d.ts +0 -12
  190. package/dist/source/tools/code-interpreter.js +0 -131
  191. package/dist/source/tools/command-validation.d.ts +0 -8
  192. package/dist/source/tools/command-validation.js +0 -69
  193. package/dist/source/tools/delete-file.d.ts +0 -12
  194. package/dist/source/tools/delete-file.js +0 -56
  195. package/dist/source/tools/directory-tree.d.ts +0 -12
  196. package/dist/source/tools/directory-tree.js +0 -38
  197. package/dist/source/tools/edit-file.d.ts +0 -19
  198. package/dist/source/tools/edit-file.js +0 -107
  199. package/dist/source/tools/filesystem-utils.d.ts +0 -22
  200. package/dist/source/tools/filesystem-utils.js +0 -191
  201. package/dist/source/tools/git-utils.d.ts +0 -14
  202. package/dist/source/tools/git-utils.js +0 -64
  203. package/dist/source/tools/grep.d.ts +0 -17
  204. package/dist/source/tools/grep.js +0 -138
  205. package/dist/source/tools/index.d.ts +0 -161
  206. package/dist/source/tools/index.js +0 -209
  207. package/dist/source/tools/memory-read.d.ts +0 -13
  208. package/dist/source/tools/memory-read.js +0 -135
  209. package/dist/source/tools/memory-write.d.ts +0 -12
  210. package/dist/source/tools/memory-write.js +0 -83
  211. package/dist/source/tools/move-file.d.ts +0 -13
  212. package/dist/source/tools/move-file.js +0 -44
  213. package/dist/source/tools/read-file.d.ts +0 -17
  214. package/dist/source/tools/read-file.js +0 -86
  215. package/dist/source/tools/read-multiple-files.d.ts +0 -14
  216. package/dist/source/tools/read-multiple-files.js +0 -55
  217. package/dist/source/tools/save-file.d.ts +0 -17
  218. package/dist/source/tools/save-file.js +0 -98
  219. package/dist/source/tools/think.d.ts +0 -11
  220. package/dist/source/tools/think.js +0 -45
  221. package/dist/source/tools/types.d.ts +0 -29
  222. package/dist/source/tools/types.js +0 -14
  223. package/dist/source/tools/web-fetch.d.ts +0 -47
  224. package/dist/source/tools/web-fetch.js +0 -246
  225. package/dist/source/tools/web-search.d.ts +0 -13
  226. package/dist/source/tools/web-search.js +0 -80
  227. package/dist/source/utils/process.d.ts +0 -36
  228. package/dist/source/utils/process.js +0 -75
  229. package/dist/source/version.d.ts +0 -1
  230. package/dist/source/version.js +0 -21
  231. package/dist/terminal-output.d.ts +0 -8
  232. package/dist/terminal-output.js +0 -213
  233. package/dist/tools/memory-read.d.ts +0 -13
  234. package/dist/tools/memory-read.js +0 -135
  235. package/dist/tools/memory-write.d.ts +0 -12
  236. package/dist/tools/memory-write.js +0 -83
  237. package/knip.json +0 -5
  238. package/source/cli.ts +0 -172
  239. package/source/commands/application-log-command.ts +0 -53
  240. package/source/commands/clear-command.ts +0 -14
  241. package/source/commands/compact-command.ts +0 -64
  242. package/source/commands/copy-command.ts +0 -55
  243. package/source/commands/edit-command.ts +0 -63
  244. package/source/commands/edit-prompt-command.ts +0 -31
  245. package/source/commands/exit-command.ts +0 -18
  246. package/source/commands/files-command.ts +0 -85
  247. package/source/commands/generate-rules-command.ts +0 -82
  248. package/source/commands/help-command.ts +0 -27
  249. package/source/commands/init-command.ts +0 -48
  250. package/source/commands/last-log-command.ts +0 -88
  251. package/source/commands/manager.ts +0 -151
  252. package/source/commands/model-command.ts +0 -123
  253. package/source/commands/paste-command.ts +0 -62
  254. package/source/commands/prompt-command.ts +0 -150
  255. package/source/commands/reset-command.ts +0 -22
  256. package/source/commands/rules-command.ts +0 -76
  257. package/source/commands/save-command.ts +0 -20
  258. package/source/commands/types.ts +0 -28
  259. package/source/commands/usage-command.ts +0 -26
  260. package/source/config.ts +0 -223
  261. package/source/conversation-analyzer.ts +0 -115
  262. package/source/dedent.ts +0 -53
  263. package/source/formatting.ts +0 -132
  264. package/source/index.ts +0 -240
  265. package/source/logger.ts +0 -29
  266. package/source/mentions.ts +0 -227
  267. package/source/messages.ts +0 -360
  268. package/source/middleware/audit-message.ts +0 -133
  269. package/source/middleware/index.ts +0 -2
  270. package/source/middleware/rate-limit.ts +0 -24
  271. package/source/models/ai-config.ts +0 -109
  272. package/source/models/anthropic-provider.ts +0 -199
  273. package/source/models/deepseek-provider.ts +0 -53
  274. package/source/models/google-provider.ts +0 -68
  275. package/source/models/manager.ts +0 -84
  276. package/source/models/openai-provider.ts +0 -81
  277. package/source/models/openrouter-provider.ts +0 -288
  278. package/source/models/providers.ts +0 -197
  279. package/source/models/xai-provider.ts +0 -59
  280. package/source/parsing.ts +0 -20
  281. package/source/prompts/manager.ts +0 -90
  282. package/source/prompts.ts +0 -172
  283. package/source/repl-prompt.ts +0 -196
  284. package/source/repl.ts +0 -572
  285. package/source/terminal/formatting.ts +0 -121
  286. package/source/terminal/index.ts +0 -518
  287. package/source/terminal/markdown-utils.ts +0 -89
  288. package/source/terminal/markdown.ts +0 -155
  289. package/source/terminal/types.ts +0 -84
  290. package/source/terminal-output.test.ts +0 -266
  291. package/source/token-tracker.ts +0 -78
  292. package/source/token-utils.ts +0 -17
  293. package/source/tools/agent.ts +0 -107
  294. package/source/tools/bash.ts +0 -367
  295. package/source/tools/code-interpreter.ts +0 -172
  296. package/source/tools/command-validation.ts +0 -81
  297. package/source/tools/delete-file.ts +0 -71
  298. package/source/tools/directory-tree.ts +0 -54
  299. package/source/tools/edit-file.ts +0 -155
  300. package/source/tools/filesystem-utils.ts +0 -265
  301. package/source/tools/git-utils.ts +0 -70
  302. package/source/tools/grep.ts +0 -184
  303. package/source/tools/index.ts +0 -278
  304. package/source/tools/memory-read.ts +0 -174
  305. package/source/tools/memory-write.ts +0 -105
  306. package/source/tools/move-file.ts +0 -59
  307. package/source/tools/read-file.ts +0 -129
  308. package/source/tools/read-multiple-files.ts +0 -80
  309. package/source/tools/save-file.ts +0 -147
  310. package/source/tools/think.ts +0 -51
  311. package/source/tools/types.ts +0 -58
  312. package/source/tools/web-fetch.ts +0 -327
  313. package/source/tools/web-search.ts +0 -101
  314. package/source/utils/process.ts +0 -121
  315. package/source/version.ts +0 -21
  316. package/test/commands/copy-command.test.ts +0 -69
  317. package/test/config.test.ts +0 -200
  318. package/test/terminal/markdown-utils.test.ts +0 -124
  319. package/test/tools/bash-tool.test.ts +0 -58
  320. package/test/tools/code-interpreter.test.ts +0 -91
  321. package/test/tools/command-validation.test.ts +0 -48
  322. package/tsconfig.build.json +0 -9
  323. package/tsconfig.json +0 -30
@@ -1,518 +0,0 @@
1
- /**
2
- * Terminal Interface Module
3
- *
4
- * Provides a user interface for interacting with Claude Code in the terminal.
5
- * Handles input/output, formatting, and display.
6
- */
7
-
8
- import chalk, { type ChalkInstance } from "chalk";
9
- import Table from "cli-table3";
10
- import ora from "ora";
11
- import wrapAnsi from "wrap-ansi";
12
- import { logger } from "../logger.ts";
13
- import { getPackageVersion } from "../version.ts";
14
- import {
15
- clearTerminal,
16
- getTerminalSize,
17
- setTerminalTitle,
18
- link as terminalLink,
19
- } from "./formatting.ts";
20
- import { applyMarkdown } from "./markdown.ts";
21
- import type { SpinnerInstance, TerminalConfig } from "./types.ts";
22
-
23
- /**
24
- * Initialize the terminal interface
25
- */
26
- export function initTerminal(config: Partial<TerminalConfig> = {}): Terminal {
27
- logger.debug("Initializing terminal interface");
28
-
29
- const terminalConfig: TerminalConfig = {
30
- theme: config.theme || "system",
31
- useColors: config.useColors !== false,
32
- showProgressIndicators: config.showProgressIndicators !== false,
33
- codeHighlighting: config.codeHighlighting !== false,
34
- maxHeight: config.maxHeight,
35
- maxWidth: config.maxWidth,
36
- };
37
-
38
- const terminal = new Terminal(terminalConfig);
39
-
40
- try {
41
- // Detect terminal capabilities
42
- terminal.detectCapabilities();
43
-
44
- return terminal;
45
- } catch (error) {
46
- logger.warn(error, "Error initializing terminal interface:");
47
-
48
- // Return a basic terminal interface even if there was an error
49
- return terminal;
50
- }
51
- }
52
-
53
- /**
54
- * Terminal class for handling user interaction
55
- */
56
- export class Terminal {
57
- private config: TerminalConfig;
58
- private activeSpinners: Map<string, SpinnerInstance> = new Map();
59
- private terminalWidth: number;
60
- private terminalHeight: number;
61
- private isInteractive: boolean;
62
-
63
- constructor(config: TerminalConfig) {
64
- this.config = config;
65
-
66
- // Get initial terminal size
67
- const { rows, columns } = getTerminalSize();
68
- this.terminalHeight = config.maxHeight || rows;
69
- this.terminalWidth = config.maxWidth || columns;
70
-
71
- // Assume interactive by default
72
- this.isInteractive = process.stdout.isTTY && process.stdin.isTTY;
73
-
74
- // Listen for terminal resize events
75
- process.stdout.on("resize", () => {
76
- const { rows, columns } = getTerminalSize();
77
- this.terminalHeight = config.maxHeight || rows;
78
- this.terminalWidth = config.maxWidth || columns;
79
- logger.debug(`Terminal resized to ${columns}x${rows}`);
80
- });
81
- }
82
-
83
- /**
84
- * Detect terminal capabilities
85
- */
86
- detectCapabilities() {
87
- // Check if the terminal is interactive
88
- this.isInteractive = Boolean(process.stdout.isTTY && process.stdin.isTTY);
89
-
90
- logger.debug(
91
- {
92
- isInteractive: this.isInteractive,
93
- colorSupport: this.config.useColors ? "yes" : "no",
94
- size: `${this.terminalWidth}x${this.terminalHeight}`,
95
- },
96
- "Terminal capabilities detected",
97
- );
98
- }
99
-
100
- setTitle(title: string) {
101
- setTerminalTitle(title);
102
- }
103
-
104
- getLogo(): string {
105
- return `
106
- █████╗ ██████╗ █████╗ ██╗
107
- ██╔══██╗██╔════╝██╔══██╗██║
108
- ███████║██║ ███████║██║
109
- ██╔══██║██║ ██╔══██║██║
110
- ██║ ██║╚██████╗██║ ██║██║
111
- ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚═╝
112
- `;
113
- }
114
-
115
- /**
116
- * Display the welcome message
117
- */
118
- displayWelcome(): void {
119
- this.clear();
120
-
121
- const version = getPackageVersion();
122
-
123
- this.writeln(chalk.magenta(this.getLogo()));
124
- this.lineBreak();
125
- this.writeln(chalk.magenta("Greetings! I am acai."));
126
- this.writeln(chalk.gray(` Version ${version}`));
127
- this.lineBreak();
128
-
129
- this.writeln(
130
- chalk.white(` Type ${chalk.cyan("/help")} to see available commands.`),
131
- );
132
- this.writeln(
133
- chalk.white(
134
- " You can ask acai to explain code, fix issues, or perform tasks.",
135
- ),
136
- );
137
- this.writeln(
138
- chalk.white(
139
- ` Example: "${chalk.italic("Please analyze this codebase and explain its structure.")}"`,
140
- ),
141
- );
142
- this.writeln(chalk.dim(" Use Ctrl+C to interrupt acai and exit."));
143
-
144
- this.lineBreak();
145
-
146
- this.writeln(
147
- chalk.yellow(`The current working directory is ${process.cwd()}`),
148
- );
149
-
150
- this.lineBreak();
151
- }
152
-
153
- /**
154
- * Clear the terminal screen
155
- */
156
- clear(): void {
157
- if (this.isInteractive) {
158
- clearTerminal();
159
- }
160
- }
161
-
162
- /**
163
- * Display formatted content
164
- */
165
- display(content: string, wrap = false): void {
166
- this.writeln(this.formatMarkdown(content, wrap));
167
- }
168
-
169
- /**
170
- * Display a message with emphasis
171
- */
172
- emphasize(message: string): void {
173
- if (this.config.useColors) {
174
- this.writeln(chalk.cyan.bold(message));
175
- } else {
176
- this.writeln(message.toUpperCase());
177
- }
178
- }
179
-
180
- /**
181
- * Display an informational message
182
- */
183
- info(message: string): void {
184
- if (this.config.useColors) {
185
- this.writeln(chalk.blue(`ℹ ${message}`));
186
- } else {
187
- this.writeln(`INFO: ${message}`);
188
- }
189
- }
190
-
191
- /**
192
- * Display a success message
193
- */
194
- success(message: string): void {
195
- if (this.config.useColors) {
196
- this.writeln(chalk.green(`✓ ${message}`));
197
- } else {
198
- this.writeln(`SUCCESS: ${message}`);
199
- }
200
- }
201
-
202
- /**
203
- * Display a warning message
204
- */
205
- warn(message: string): void {
206
- if (this.config.useColors) {
207
- this.writeln(chalk.yellow(`⚠ ${message}`));
208
- } else {
209
- this.writeln(`WARNING: ${message}`);
210
- }
211
- }
212
-
213
- /**
214
- * Display an error message
215
- */
216
- error(message: string): void {
217
- if (this.config.useColors) {
218
- this.writeln(chalk.red(`✗ ${message}`));
219
- } else {
220
- this.writeln(`ERROR: ${message}`);
221
- }
222
- }
223
-
224
- /**
225
- * Emits an alert.
226
- */
227
- alert(): void {
228
- if (!this.isInteractive) {
229
- return;
230
- }
231
-
232
- const t = "acai";
233
- const b = "";
234
- try {
235
- process.stdout.write("\x07");
236
- const esc = "\u001b";
237
- const bel = "\u0007";
238
- const safe = (s: string) =>
239
- s.replaceAll("\u0007", "").replaceAll("\u001b", "");
240
- const payload = `${esc}]777;notify;${safe(t)};${safe(b)}${bel}`;
241
- process.stdout.write(payload);
242
- } catch (err) {
243
- logger.warn({ err }, "Failed to emit alert");
244
- }
245
- }
246
-
247
- write(input: string): void {
248
- process.stdout.write(input);
249
- }
250
-
251
- writeln(input: string): void {
252
- process.stdout.write(`${input}\n`);
253
- }
254
-
255
- lineBreak() {
256
- this.writeln("");
257
- }
258
-
259
- header(header: string, chalkFn: ChalkInstance = chalk.green): void {
260
- const cols = this.terminalWidth > 0 ? this.terminalWidth : 80;
261
- const width = Math.max(0, cols - header.length - 4);
262
- this.writeln(chalkFn(`\n── ${header} ${"─".repeat(width)} `));
263
- }
264
-
265
- async box(header: string, content: string): Promise<void> {
266
- const cols = this.terminalWidth > 0 ? this.terminalWidth : 80;
267
- const width = Math.max(4, cols - 4);
268
-
269
- // Helper to strip ANSI sequences for accurate visible-width calculation
270
- const stripAnsi = (s: string): string =>
271
- // biome-ignore lint/suspicious/noControlCharactersInRegex: need to detect ansi control characters
272
- s.replace(/\x1B\[[0-?]*[ -/]*[@-~]/g, "");
273
-
274
- const paddedHeader = ` ${header} `;
275
- const headerVisibleLen = stripAnsi(paddedHeader).length;
276
- const headerStartPos = 1;
277
-
278
- // Top border with header (use visible header length)
279
- const leftDashes = headerStartPos;
280
- const rightDashes = Math.max(0, width - leftDashes - headerVisibleLen);
281
- const topBorder = `┌${"─".repeat(leftDashes)}${paddedHeader}${"─".repeat(rightDashes)}┐`;
282
-
283
- // Prepare inner content: format markdown first, then wrap to inner width
284
- const innerWidth = Math.max(1, width - 2);
285
- const formatted = applyMarkdown(content);
286
- const wrapped = wrapAnsi(formatted, innerWidth, { trim: false });
287
-
288
- const contentLines = wrapped
289
- .split("\n")
290
- .map((line) => {
291
- const visibleLen = stripAnsi(line).length;
292
- const padCount = Math.max(0, innerWidth - visibleLen);
293
- return `│ ${line}${" ".repeat(padCount)} │`;
294
- })
295
- .join("\n");
296
-
297
- // Bottom border
298
- const bottomBorder = `└${"─".repeat(width)}┘`;
299
-
300
- // Write the box
301
- this.writeln(`${topBorder}\n${contentLines}\n${bottomBorder}`);
302
- }
303
-
304
- hr(chalkFn: ChalkInstance = chalk.gray): void {
305
- const cols = this.terminalWidth > 0 ? this.terminalWidth : 80;
306
- this.writeln(chalkFn(`${"─".repeat(Math.max(1, cols - 1))} `));
307
- }
308
-
309
- /**
310
- * Create a clickable link in the terminal if supported
311
- */
312
- link(text: string, url: string): string {
313
- return terminalLink(text, url);
314
- }
315
-
316
- /**
317
- * Display a table of data
318
- */
319
- table(
320
- data: [string, string | number][],
321
- options: { header?: string[]; colWidths?: number[] } = {},
322
- ): void {
323
- const { header, colWidths } = options;
324
- // Calculate column widths based on terminal width
325
- const padding = 5; // Account for table borders and padding
326
- const availableWidth = Math.max(10, this.terminalWidth - padding);
327
- const colCount = header?.length ?? 1;
328
- const width = Math.max(
329
- 10,
330
- Math.floor(availableWidth / Math.max(1, colCount)),
331
- );
332
- const computedColWidths: number[] = colWidths
333
- ? colWidths.map((percent) =>
334
- Math.max(10, Math.floor((percent / 100) * availableWidth)),
335
- )
336
- : new Array(colCount).fill(width);
337
-
338
- const table = new Table({
339
- head: header,
340
- colWidths: computedColWidths,
341
- wordWrap: true, // Enable word wrapping for the description column
342
- });
343
-
344
- table.push(...data);
345
-
346
- this.writeln(table.toString());
347
- }
348
-
349
- /**
350
- * Create a spinner for showing progress
351
- */
352
- spinner(text: string, id = "default"): SpinnerInstance {
353
- // Clean up existing spinner with the same ID
354
- if (this.activeSpinners.has(id)) {
355
- this.activeSpinners.get(id)?.stop();
356
- this.activeSpinners.delete(id);
357
- }
358
-
359
- // Create spinner only if progress indicators are enabled and terminal is interactive
360
- if (this.config.showProgressIndicators && this.isInteractive) {
361
- const spinner = ora({
362
- text,
363
- spinner: "dots",
364
- color: "cyan",
365
- }).start();
366
-
367
- const spinnerInstance: SpinnerInstance = {
368
- id,
369
- update: (newText: string) => {
370
- spinner.text = newText;
371
- return spinnerInstance;
372
- },
373
- succeed: (text?: string) => {
374
- spinner.succeed(text);
375
- this.activeSpinners.delete(id);
376
- return spinnerInstance;
377
- },
378
- fail: (text?: string) => {
379
- spinner.fail(text);
380
- this.activeSpinners.delete(id);
381
- return spinnerInstance;
382
- },
383
- warn: (text?: string) => {
384
- spinner.warn(text);
385
- this.activeSpinners.delete(id);
386
- return spinnerInstance;
387
- },
388
- info: (text?: string) => {
389
- spinner.info(text);
390
- this.activeSpinners.delete(id);
391
- return spinnerInstance;
392
- },
393
- clear: () => {
394
- spinner.clear();
395
- this.activeSpinners.delete(id);
396
- return spinnerInstance;
397
- },
398
- stop: () => {
399
- spinner.stop();
400
- this.activeSpinners.delete(id);
401
- return spinnerInstance;
402
- },
403
- };
404
-
405
- this.activeSpinners.set(id, spinnerInstance);
406
- return spinnerInstance;
407
- }
408
- // Fallback for non-interactive terminals or when progress indicators are disabled
409
- console.info(text);
410
-
411
- // Return a dummy spinner
412
- const dummySpinner: SpinnerInstance = {
413
- id,
414
- update: (newText: string) => {
415
- if (newText !== text) {
416
- console.info(newText);
417
- }
418
- return dummySpinner;
419
- },
420
- succeed: (text?: string) => {
421
- if (text) {
422
- this.success(text);
423
- }
424
- return dummySpinner;
425
- },
426
- fail: (text?: string) => {
427
- if (text) {
428
- this.error(text);
429
- }
430
- return dummySpinner;
431
- },
432
- warn: (text?: string) => {
433
- if (text) {
434
- this.warn(text);
435
- }
436
- return dummySpinner;
437
- },
438
- info: (text?: string) => {
439
- if (text) {
440
- this.info(text);
441
- }
442
- return dummySpinner;
443
- },
444
- clear: () => {
445
- return dummySpinner;
446
- },
447
- stop: () => {
448
- return dummySpinner;
449
- },
450
- };
451
-
452
- return dummySpinner;
453
- }
454
-
455
- /**
456
- * Displays a horizontal progress bar in the console.
457
- * @param current The current value.
458
- * @param total The target value.
459
- */
460
- displayProgressBar(current: number, total: number): void {
461
- const terminalWidth = this.terminalWidth > 0 ? this.terminalWidth : 80; // Default to 80 if columns not available
462
-
463
- // Function to format numbers concisely (e.g., 1.2K, 5M)
464
- const formatNumber = (num: number): string => {
465
- if (num < 1000) {
466
- return num.toString();
467
- }
468
- if (num < 1_000_000) {
469
- return `${(num / 1000).toFixed(1)}K`;
470
- }
471
- if (num < 1_000_000_000) {
472
- return `${(num / 1_000_000).toFixed(1)}M`;
473
- }
474
- return `${(num / 1_000_000_000).toFixed(1)}G`;
475
- };
476
-
477
- const currentFormatted = formatNumber(current);
478
- const totalFormatted = formatNumber(total);
479
- const progressText = `${currentFormatted}/${totalFormatted}`;
480
- const progressTextLength = progressText.length + 1; // Add 1 for space
481
-
482
- const progressBarMaxWidth = Math.max(
483
- 1,
484
- terminalWidth - progressTextLength - 1,
485
- );
486
-
487
- const percentage = total === 0 ? 1 : current / total;
488
- const filledWidth = Math.max(
489
- 0,
490
- Math.min(
491
- progressBarMaxWidth,
492
- Math.floor(percentage * progressBarMaxWidth),
493
- ),
494
- );
495
- const emptyWidth = Math.max(0, progressBarMaxWidth - filledWidth);
496
-
497
- const a = chalk.yellow("─"); //"█"
498
- const b = chalk.gray("─"); // "░"
499
- const filledBar = a.repeat(filledWidth);
500
- const emptyBar = b.repeat(emptyWidth);
501
-
502
- // Use \r to move cursor to the beginning of the line for updates
503
- this.writeln(`\r${filledBar}${emptyBar} ${progressText} `);
504
- }
505
-
506
- private formatMarkdown(content: string, wrap = false): string {
507
- const columns = this.terminalWidth;
508
- const formatted = applyMarkdown(content);
509
-
510
- if (wrap) {
511
- return wrapAnsi(formatted, columns - 6, { trim: false });
512
- }
513
- return formatted;
514
- }
515
- }
516
-
517
- // Re-export the types
518
- export * from "./types.ts";
@@ -1,89 +0,0 @@
1
- const markdownHeaderRegex = /^#{1,6}\s/m;
2
- const markdownBoldRegex = /(\*\*|__)(.*?)\1/;
3
- const markdownItalicRegex = /(\*|_)(.*?)\1/;
4
- const markdownCodeRegex = /`{1,3}[^`]+`{1,3}/;
5
- const markdownLinkRegex = /\((.*?)\]\((.*?)\)/;
6
- const markdownBlockquoteRegex = /^>\s/m;
7
- const markdownUnorderedListRegex = /^-\s|\*\s|\+\s/m;
8
- const markdownOrderedListRegex = /^\d+\.\s/m;
9
- const markdownHorizontalRuleRegex = /^---$/m;
10
- const markdownImageRegex = /!\[(.*?)\]\((.*?)\)/;
11
-
12
- export function isMarkdown(input: string): boolean {
13
- // Simple heuristics: look for common markdown syntax
14
- const markdownPatterns = [
15
- markdownHeaderRegex, // headings
16
- markdownBoldRegex, // bold
17
- markdownItalicRegex, // italic
18
- markdownCodeRegex, // inline code or code block
19
- markdownLinkRegex, // links
20
- markdownBlockquoteRegex, // blockquote
21
- markdownUnorderedListRegex, // unordered list
22
- markdownOrderedListRegex, // ordered list
23
- markdownHorizontalRuleRegex, // horizontal rule
24
- markdownImageRegex, // images
25
- ];
26
- return markdownPatterns.some((pattern) => pattern.test(input));
27
- }
28
-
29
- function getDepth1ListNumber(i: number): string {
30
- if (i <= 0) {
31
- return "";
32
- }
33
- const letters: string[] = [];
34
- let num = i;
35
- while (num > 0) {
36
- num--; // Adjust for 0-indexing
37
- letters.unshift(String.fromCharCode(97 + (num % 26)));
38
- num = Math.floor(num / 26);
39
- }
40
- return letters.join("");
41
- }
42
-
43
- function getDepth2ListNumber(i: number): string {
44
- if (i <= 0) {
45
- return "";
46
- }
47
- const romanNumerals = [
48
- ["m", 1000],
49
- ["cm", 900],
50
- ["d", 500],
51
- ["cd", 400],
52
- ["c", 100],
53
- ["xc", 90],
54
- ["l", 50],
55
- ["xl", 40],
56
- ["x", 10],
57
- ["ix", 9],
58
- ["v", 5],
59
- ["iv", 4],
60
- ["i", 1],
61
- ] as const;
62
-
63
- let num = i;
64
- let result = "";
65
- for (const [roman, value] of romanNumerals) {
66
- while (num >= value) {
67
- result += roman;
68
- num -= value;
69
- }
70
- }
71
- return result;
72
- }
73
-
74
- export function getListNumber(
75
- listDepth: number,
76
- orderedListNumber: number,
77
- ): string {
78
- switch (listDepth) {
79
- case 0:
80
- case 1:
81
- return orderedListNumber.toString();
82
- case 2:
83
- return getDepth1ListNumber(orderedListNumber);
84
- case 3:
85
- return getDepth2ListNumber(orderedListNumber);
86
- default:
87
- return orderedListNumber.toString();
88
- }
89
- }