@travisennis/acai 0.0.1 → 0.0.3
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.
- package/README.md +3 -4
- package/dist/commands/health-command.d.ts +2 -0
- package/dist/commands/health-command.js +59 -0
- package/dist/commands/manager.js +2 -0
- package/dist/commands/paste-command.d.ts +1 -1
- package/dist/commands/paste-command.js +155 -11
- package/dist/commands/reset-command.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -1
- package/dist/models/openrouter-provider.d.ts +4 -1
- package/dist/models/openrouter-provider.js +46 -4
- package/dist/models/providers.d.ts +1 -1
- package/dist/prompts/manager.d.ts +1 -0
- package/dist/prompts/manager.js +10 -0
- package/dist/prompts.js +8 -6
- package/dist/repl.js +49 -26
- package/dist/terminal/formatting.d.ts +16 -5
- package/dist/terminal/formatting.js +40 -6
- package/dist/terminal/index.d.ts +1 -1
- package/dist/terminal/index.js +54 -14
- package/dist/terminal/markdown.js +0 -1
- package/dist/terminal/supports-color.d.ts +16 -0
- package/dist/terminal/supports-color.js +121 -0
- package/dist/terminal/supports-hyperlinks.d.ts +7 -0
- package/dist/terminal/supports-hyperlinks.js +98 -0
- package/dist/tools/bash.js +95 -117
- package/dist/tools/code-interpreter.js +11 -1
- package/dist/tools/command-validation.d.ts +7 -3
- package/dist/tools/command-validation.js +67 -23
- package/dist/tools/delete-file.d.ts +4 -1
- package/dist/tools/delete-file.js +47 -3
- package/dist/tools/git-utils.d.ts +6 -0
- package/dist/tools/git-utils.js +89 -12
- package/dist/tools/grep.d.ts +20 -0
- package/dist/tools/grep.js +128 -40
- package/dist/tools/index.d.ts +2 -18
- package/dist/tools/index.js +4 -18
- package/package.json +30 -20
- package/.acai/acai.json +0 -9
- package/.acai/prompts/add-openrouter-model.md +0 -13
- package/.acai/prompts/project-status.md +0 -4
- package/.acai/prompts/update-architecture-document.md +0 -9
- package/.acai/rules/learned-rules.md +0 -9
- package/.ai/docs/available-tools.txt +0 -3
- package/.ai/docs/cognitive_complexity_refactoring_progress.md +0 -65
- package/.ai/docs/deleted_tools.md +0 -168
- package/.ai/docs/deleted_tools_88ced9ef.md +0 -56
- package/.ai/docs/image-pasting.md +0 -46
- package/.ai/docs/initialize-app.md +0 -117
- package/.ai/docs/issue-4-plan.md +0 -44
- package/.ai/docs/marked-renderer-debug.md +0 -15
- package/.ai/docs/marked-renderer-refactor-plan.md +0 -64
- package/.ai/docs/memory-use-cases.md +0 -55
- package/.ai/docs/prompt-consistency.md +0 -31
- package/.ai/docs/refactoring-tools.md +0 -98
- package/.ai/docs/system-prompt-update.md +0 -174
- package/.ai/docs/system_prompt.txt +0 -210
- package/.ai/docs/tasks.md +0 -49
- package/.ai/plan.md +0 -131
- package/.ai/prompt.md +0 -1
- package/.ai/scripts/fetch_models.js +0 -27
- package/.ai/scripts/generateSystemPrompt.ts +0 -15
- package/.ai/scripts/list-tools.mjs +0 -4
- package/.ai/scripts/p5_geometric_shapes.js +0 -149
- package/.husky/commit-msg +0 -1
- package/.husky/pre-commit +0 -3
- package/.husky/pre-push +0 -1
- package/.ignore +0 -4
- package/AGENTS.md +0 -25
- package/ARCHITECTURE.md +0 -304
- package/TODO.md +0 -2
- package/biome.json +0 -61
- package/commitlint.config.js +0 -3
- package/dist/source/cli.d.ts +0 -19
- package/dist/source/cli.js +0 -116
- package/dist/source/commands/application-log-command.d.ts +0 -2
- package/dist/source/commands/application-log-command.js +0 -43
- package/dist/source/commands/clear-command.d.ts +0 -2
- package/dist/source/commands/clear-command.js +0 -12
- package/dist/source/commands/compact-command.d.ts +0 -2
- package/dist/source/commands/compact-command.js +0 -51
- package/dist/source/commands/copy-command.d.ts +0 -2
- package/dist/source/commands/copy-command.js +0 -51
- package/dist/source/commands/edit-command.d.ts +0 -2
- package/dist/source/commands/edit-command.js +0 -53
- package/dist/source/commands/edit-prompt-command.d.ts +0 -2
- package/dist/source/commands/edit-prompt-command.js +0 -25
- package/dist/source/commands/exit-command.d.ts +0 -2
- package/dist/source/commands/exit-command.js +0 -14
- package/dist/source/commands/files-command.d.ts +0 -2
- package/dist/source/commands/files-command.js +0 -63
- package/dist/source/commands/generate-rules-command.d.ts +0 -2
- package/dist/source/commands/generate-rules-command.js +0 -61
- package/dist/source/commands/help-command.d.ts +0 -2
- package/dist/source/commands/help-command.js +0 -19
- package/dist/source/commands/init-command.d.ts +0 -2
- package/dist/source/commands/init-command.js +0 -40
- package/dist/source/commands/last-log-command.d.ts +0 -2
- package/dist/source/commands/last-log-command.js +0 -76
- package/dist/source/commands/manager.d.ts +0 -22
- package/dist/source/commands/manager.js +0 -123
- package/dist/source/commands/model-command.d.ts +0 -2
- package/dist/source/commands/model-command.js +0 -84
- package/dist/source/commands/paste-command.d.ts +0 -2
- package/dist/source/commands/paste-command.js +0 -40
- package/dist/source/commands/prompt-command.d.ts +0 -2
- package/dist/source/commands/prompt-command.js +0 -111
- package/dist/source/commands/reset-command.d.ts +0 -2
- package/dist/source/commands/reset-command.js +0 -16
- package/dist/source/commands/rules-command.d.ts +0 -2
- package/dist/source/commands/rules-command.js +0 -68
- package/dist/source/commands/save-command.d.ts +0 -2
- package/dist/source/commands/save-command.js +0 -14
- package/dist/source/commands/types.d.ts +0 -26
- package/dist/source/commands/types.js +0 -1
- package/dist/source/commands/usage-command.d.ts +0 -2
- package/dist/source/commands/usage-command.js +0 -21
- package/dist/source/config.d.ts +0 -60
- package/dist/source/config.js +0 -193
- package/dist/source/conversation-analyzer.d.ts +0 -10
- package/dist/source/conversation-analyzer.js +0 -88
- package/dist/source/dedent.d.ts +0 -3
- package/dist/source/dedent.js +0 -38
- package/dist/source/formatting.d.ts +0 -17
- package/dist/source/formatting.js +0 -103
- package/dist/source/index.d.ts +0 -18
- package/dist/source/index.js +0 -213
- package/dist/source/logger.d.ts +0 -2
- package/dist/source/logger.js +0 -24
- package/dist/source/mentions.d.ts +0 -9
- package/dist/source/mentions.js +0 -182
- package/dist/source/messages.d.ts +0 -69
- package/dist/source/messages.js +0 -261
- package/dist/source/middleware/audit-message.d.ts +0 -5
- package/dist/source/middleware/audit-message.js +0 -95
- package/dist/source/middleware/index.d.ts +0 -2
- package/dist/source/middleware/index.js +0 -2
- package/dist/source/middleware/rate-limit.d.ts +0 -4
- package/dist/source/middleware/rate-limit.js +0 -17
- package/dist/source/models/ai-config.d.ts +0 -12
- package/dist/source/models/ai-config.js +0 -87
- package/dist/source/models/anthropic-provider.d.ts +0 -25
- package/dist/source/models/anthropic-provider.js +0 -184
- package/dist/source/models/deepseek-provider.d.ts +0 -20
- package/dist/source/models/deepseek-provider.js +0 -42
- package/dist/source/models/google-provider.d.ts +0 -19
- package/dist/source/models/google-provider.js +0 -56
- package/dist/source/models/manager.d.ts +0 -15
- package/dist/source/models/manager.js +0 -48
- package/dist/source/models/openai-provider.d.ts +0 -22
- package/dist/source/models/openai-provider.js +0 -70
- package/dist/source/models/openrouter-provider.d.ts +0 -36
- package/dist/source/models/openrouter-provider.js +0 -276
- package/dist/source/models/providers.d.ts +0 -33
- package/dist/source/models/providers.js +0 -116
- package/dist/source/models/xai-provider.d.ts +0 -20
- package/dist/source/models/xai-provider.js +0 -47
- package/dist/source/parsing.d.ts +0 -2
- package/dist/source/parsing.js +0 -18
- package/dist/source/prompts/manager.d.ts +0 -19
- package/dist/source/prompts/manager.js +0 -71
- package/dist/source/prompts.d.ts +0 -4
- package/dist/source/prompts.js +0 -158
- package/dist/source/repl-prompt.d.ts +0 -14
- package/dist/source/repl-prompt.js +0 -147
- package/dist/source/repl.d.ts +0 -27
- package/dist/source/repl.js +0 -431
- package/dist/source/terminal/formatting.d.ts +0 -37
- package/dist/source/terminal/formatting.js +0 -106
- package/dist/source/terminal/index.d.ts +0 -94
- package/dist/source/terminal/index.js +0 -420
- package/dist/source/terminal/markdown-utils.d.ts +0 -2
- package/dist/source/terminal/markdown-utils.js +0 -81
- package/dist/source/terminal/markdown.d.ts +0 -1
- package/dist/source/terminal/markdown.js +0 -111
- package/dist/source/terminal/types.d.ts +0 -71
- package/dist/source/terminal/types.js +0 -1
- package/dist/source/terminal-output.d.ts +0 -8
- package/dist/source/terminal-output.js +0 -213
- package/dist/source/terminal-output.test.d.ts +0 -8
- package/dist/source/terminal-output.test.js +0 -213
- package/dist/source/token-tracker.d.ts +0 -14
- package/dist/source/token-tracker.js +0 -53
- package/dist/source/token-utils.d.ts +0 -7
- package/dist/source/token-utils.js +0 -13
- package/dist/source/tools/agent.d.ts +0 -17
- package/dist/source/tools/agent.js +0 -87
- package/dist/source/tools/bash.d.ts +0 -19
- package/dist/source/tools/bash.js +0 -294
- package/dist/source/tools/code-interpreter.d.ts +0 -12
- package/dist/source/tools/code-interpreter.js +0 -131
- package/dist/source/tools/command-validation.d.ts +0 -8
- package/dist/source/tools/command-validation.js +0 -69
- package/dist/source/tools/delete-file.d.ts +0 -12
- package/dist/source/tools/delete-file.js +0 -56
- package/dist/source/tools/directory-tree.d.ts +0 -12
- package/dist/source/tools/directory-tree.js +0 -38
- package/dist/source/tools/edit-file.d.ts +0 -19
- package/dist/source/tools/edit-file.js +0 -107
- package/dist/source/tools/filesystem-utils.d.ts +0 -22
- package/dist/source/tools/filesystem-utils.js +0 -191
- package/dist/source/tools/git-utils.d.ts +0 -14
- package/dist/source/tools/git-utils.js +0 -64
- package/dist/source/tools/grep.d.ts +0 -17
- package/dist/source/tools/grep.js +0 -138
- package/dist/source/tools/index.d.ts +0 -161
- package/dist/source/tools/index.js +0 -209
- package/dist/source/tools/memory-read.d.ts +0 -13
- package/dist/source/tools/memory-read.js +0 -135
- package/dist/source/tools/memory-write.d.ts +0 -12
- package/dist/source/tools/memory-write.js +0 -83
- package/dist/source/tools/move-file.d.ts +0 -13
- package/dist/source/tools/move-file.js +0 -44
- package/dist/source/tools/read-file.d.ts +0 -17
- package/dist/source/tools/read-file.js +0 -86
- package/dist/source/tools/read-multiple-files.d.ts +0 -14
- package/dist/source/tools/read-multiple-files.js +0 -55
- package/dist/source/tools/save-file.d.ts +0 -17
- package/dist/source/tools/save-file.js +0 -98
- package/dist/source/tools/think.d.ts +0 -11
- package/dist/source/tools/think.js +0 -45
- package/dist/source/tools/types.d.ts +0 -29
- package/dist/source/tools/types.js +0 -14
- package/dist/source/tools/web-fetch.d.ts +0 -47
- package/dist/source/tools/web-fetch.js +0 -246
- package/dist/source/tools/web-search.d.ts +0 -13
- package/dist/source/tools/web-search.js +0 -80
- package/dist/source/utils/process.d.ts +0 -36
- package/dist/source/utils/process.js +0 -75
- package/dist/source/version.d.ts +0 -1
- package/dist/source/version.js +0 -21
- package/dist/terminal-output.d.ts +0 -8
- package/dist/terminal-output.js +0 -213
- package/dist/tools/memory-read.d.ts +0 -13
- package/dist/tools/memory-read.js +0 -135
- package/dist/tools/memory-write.d.ts +0 -12
- package/dist/tools/memory-write.js +0 -83
- package/knip.json +0 -5
- package/source/cli.ts +0 -172
- package/source/commands/application-log-command.ts +0 -53
- package/source/commands/clear-command.ts +0 -14
- package/source/commands/compact-command.ts +0 -64
- package/source/commands/copy-command.ts +0 -55
- package/source/commands/edit-command.ts +0 -63
- package/source/commands/edit-prompt-command.ts +0 -31
- package/source/commands/exit-command.ts +0 -18
- package/source/commands/files-command.ts +0 -85
- package/source/commands/generate-rules-command.ts +0 -82
- package/source/commands/help-command.ts +0 -27
- package/source/commands/init-command.ts +0 -48
- package/source/commands/last-log-command.ts +0 -88
- package/source/commands/manager.ts +0 -151
- package/source/commands/model-command.ts +0 -123
- package/source/commands/paste-command.ts +0 -62
- package/source/commands/prompt-command.ts +0 -150
- package/source/commands/reset-command.ts +0 -22
- package/source/commands/rules-command.ts +0 -76
- package/source/commands/save-command.ts +0 -20
- package/source/commands/types.ts +0 -28
- package/source/commands/usage-command.ts +0 -26
- package/source/config.ts +0 -223
- package/source/conversation-analyzer.ts +0 -115
- package/source/dedent.ts +0 -53
- package/source/formatting.ts +0 -132
- package/source/index.ts +0 -240
- package/source/logger.ts +0 -29
- package/source/mentions.ts +0 -227
- package/source/messages.ts +0 -360
- package/source/middleware/audit-message.ts +0 -133
- package/source/middleware/index.ts +0 -2
- package/source/middleware/rate-limit.ts +0 -24
- package/source/models/ai-config.ts +0 -109
- package/source/models/anthropic-provider.ts +0 -199
- package/source/models/deepseek-provider.ts +0 -53
- package/source/models/google-provider.ts +0 -68
- package/source/models/manager.ts +0 -84
- package/source/models/openai-provider.ts +0 -81
- package/source/models/openrouter-provider.ts +0 -288
- package/source/models/providers.ts +0 -197
- package/source/models/xai-provider.ts +0 -59
- package/source/parsing.ts +0 -20
- package/source/prompts/manager.ts +0 -90
- package/source/prompts.ts +0 -172
- package/source/repl-prompt.ts +0 -196
- package/source/repl.ts +0 -572
- package/source/terminal/formatting.ts +0 -121
- package/source/terminal/index.ts +0 -518
- package/source/terminal/markdown-utils.ts +0 -89
- package/source/terminal/markdown.ts +0 -155
- package/source/terminal/types.ts +0 -84
- package/source/terminal-output.test.ts +0 -266
- package/source/token-tracker.ts +0 -78
- package/source/token-utils.ts +0 -17
- package/source/tools/agent.ts +0 -107
- package/source/tools/bash.ts +0 -367
- package/source/tools/code-interpreter.ts +0 -172
- package/source/tools/command-validation.ts +0 -81
- package/source/tools/delete-file.ts +0 -71
- package/source/tools/directory-tree.ts +0 -54
- package/source/tools/edit-file.ts +0 -155
- package/source/tools/filesystem-utils.ts +0 -265
- package/source/tools/git-utils.ts +0 -70
- package/source/tools/grep.ts +0 -184
- package/source/tools/index.ts +0 -278
- package/source/tools/memory-read.ts +0 -174
- package/source/tools/memory-write.ts +0 -105
- package/source/tools/move-file.ts +0 -59
- package/source/tools/read-file.ts +0 -129
- package/source/tools/read-multiple-files.ts +0 -80
- package/source/tools/save-file.ts +0 -147
- package/source/tools/think.ts +0 -51
- package/source/tools/types.ts +0 -58
- package/source/tools/web-fetch.ts +0 -327
- package/source/tools/web-search.ts +0 -101
- package/source/utils/process.ts +0 -121
- package/source/version.ts +0 -21
- package/test/commands/copy-command.test.ts +0 -69
- package/test/config.test.ts +0 -200
- package/test/terminal/markdown-utils.test.ts +0 -124
- package/test/tools/bash-tool.test.ts +0 -58
- package/test/tools/code-interpreter.test.ts +0 -91
- package/test/tools/command-validation.test.ts +0 -48
- package/tsconfig.build.json +0 -9
- package/tsconfig.json +0 -30
package/dist/repl.js
CHANGED
|
@@ -8,7 +8,7 @@ import { AiConfig } from "./models/ai-config.js";
|
|
|
8
8
|
import { systemPrompt } from "./prompts.js";
|
|
9
9
|
import { ReplPrompt } from "./repl-prompt.js";
|
|
10
10
|
import { isMarkdown } from "./terminal/markdown-utils.js";
|
|
11
|
-
import { getCurrentBranch, getDiffStat, hasUncommittedChanges, inGitDirectory, } from "./tools/git-utils.js"; // Modified import
|
|
11
|
+
import { getCurrentBranch, getDiffStat, getGitStatus, hasUncommittedChanges, inGitDirectory, } from "./tools/git-utils.js"; // Modified import
|
|
12
12
|
import { initAgents, initTools } from "./tools/index.js";
|
|
13
13
|
export class Repl {
|
|
14
14
|
options;
|
|
@@ -39,16 +39,8 @@ export class Repl {
|
|
|
39
39
|
prevCb = cb;
|
|
40
40
|
const langModel = modelManager.getModel("repl");
|
|
41
41
|
const modelConfig = modelManager.getModelMetadata("repl");
|
|
42
|
-
const currentDir = process.cwd().split("/").pop() || process.cwd();
|
|
43
|
-
const branch = await getCurrentBranch();
|
|
44
|
-
let branchDisplay = "";
|
|
45
|
-
if (branch) {
|
|
46
|
-
const hasChanges = await hasUncommittedChanges();
|
|
47
|
-
const asterisk = hasChanges ? "*" : "";
|
|
48
|
-
branchDisplay = ` ${chalk.gray(branch + asterisk)}`;
|
|
49
|
-
}
|
|
50
42
|
terminal.hr();
|
|
51
|
-
terminal.writeln(
|
|
43
|
+
terminal.writeln(await getProjectStatusLine());
|
|
52
44
|
terminal.writeln(chalk.dim(langModel.modelId));
|
|
53
45
|
terminal.displayProgressBar(currentContextWindow, modelConfig.contextWindow);
|
|
54
46
|
if (!promptManager.isPending()) {
|
|
@@ -84,7 +76,8 @@ export class Repl {
|
|
|
84
76
|
// flag to see if the user prompt has added context
|
|
85
77
|
const hasAddedContext = promptManager.hasContext();
|
|
86
78
|
if (hasAddedContext) {
|
|
87
|
-
|
|
79
|
+
const contextTokenCount = promptManager.getContextTokenCount();
|
|
80
|
+
terminal.info(`Context will be added to prompt. (${contextTokenCount} tokens)`);
|
|
88
81
|
terminal.lineBreak();
|
|
89
82
|
}
|
|
90
83
|
const userPrompt = promptManager.get();
|
|
@@ -152,23 +145,19 @@ export class Repl {
|
|
|
152
145
|
}
|
|
153
146
|
// Create a more visual representation of steps/tool usage
|
|
154
147
|
this.displayToolUse(result, terminal);
|
|
155
|
-
if (await inGitDirectory()) {
|
|
156
|
-
// Added check
|
|
157
|
-
const stats = await getDiffStat();
|
|
158
|
-
terminal.writeln(`${chalk.dim("Files changed:")} ${chalk.yellow(stats.filesChanged)} ` +
|
|
159
|
-
`${chalk.green(`+${stats.insertions}`)} ` + // Insertions first (green)
|
|
160
|
-
`${chalk.red(`-${stats.deletions}`)}`);
|
|
161
|
-
}
|
|
162
148
|
const total = result.totalUsage ??
|
|
163
149
|
result.usage;
|
|
164
|
-
const
|
|
150
|
+
const inputTokens = isNumber(total.inputTokens)
|
|
165
151
|
? total.inputTokens
|
|
166
152
|
: 0;
|
|
167
|
-
const
|
|
153
|
+
const outputTokens = isNumber(total.outputTokens)
|
|
168
154
|
? total.outputTokens
|
|
169
155
|
: 0;
|
|
170
|
-
const tokenSummary = `Tokens: ↑ ${
|
|
156
|
+
const tokenSummary = `Tokens: ↑ ${inputTokens} ↓ ${outputTokens}`;
|
|
171
157
|
terminal.writeln(chalk.dim(tokenSummary));
|
|
158
|
+
const inputCost = modelConfig.costPerInputToken * inputTokens;
|
|
159
|
+
const outputCost = modelConfig.costPerOutputToken * outputTokens;
|
|
160
|
+
terminal.writeln(chalk.dim(`Cost: $${(inputCost + outputCost).toFixed(2)}`));
|
|
172
161
|
// Track aggregate usage across all steps when available
|
|
173
162
|
tokenTracker.trackUsage("repl", total);
|
|
174
163
|
// Derive current context window from final step usage
|
|
@@ -241,8 +230,8 @@ export class Repl {
|
|
|
241
230
|
terminal.write(chalk.dim("\n</think>\n\n"));
|
|
242
231
|
}
|
|
243
232
|
// if there is accumulatedText, display it
|
|
244
|
-
if (accumulatedText) {
|
|
245
|
-
terminal.writeln(`${chalk.blue.bold("●")}
|
|
233
|
+
if (accumulatedText.trim()) {
|
|
234
|
+
terminal.writeln(`${chalk.blue.bold("● Response:")}`);
|
|
246
235
|
terminal.display(accumulatedText, true);
|
|
247
236
|
terminal.lineBreak();
|
|
248
237
|
}
|
|
@@ -255,8 +244,8 @@ export class Repl {
|
|
|
255
244
|
terminal.write(chalk.gray("\n</think>\n\n"));
|
|
256
245
|
}
|
|
257
246
|
// if there is accumulatedText, display it
|
|
258
|
-
if (accumulatedText) {
|
|
259
|
-
terminal.writeln(`${chalk.green.bold("●")}
|
|
247
|
+
if (accumulatedText.trim()) {
|
|
248
|
+
terminal.writeln(`${chalk.green.bold("● Response:")}`);
|
|
260
249
|
terminal.display(accumulatedText, true);
|
|
261
250
|
terminal.lineBreak();
|
|
262
251
|
}
|
|
@@ -325,6 +314,7 @@ export class Repl {
|
|
|
325
314
|
}
|
|
326
315
|
}
|
|
327
316
|
if (toolsCalled.length > 0) {
|
|
317
|
+
terminal.lineBreak();
|
|
328
318
|
terminal.writeln(chalk.dim("Tools:"));
|
|
329
319
|
for (const toolCalled of toolsCalled) {
|
|
330
320
|
const colorFn = toolColors.get(toolCalled) ?? chalk.white;
|
|
@@ -361,7 +351,9 @@ function displayToolMessages(messages, terminal) {
|
|
|
361
351
|
case "tool-error":
|
|
362
352
|
_handleToolErrorMessage(msg.data, terminal);
|
|
363
353
|
break;
|
|
364
|
-
|
|
354
|
+
case "tool-init":
|
|
355
|
+
// 'tool-init' is handled before the loop, so nothing to do here.
|
|
356
|
+
break;
|
|
365
357
|
default:
|
|
366
358
|
// Optional: Log an unexpected event type for debugging, or do nothing.
|
|
367
359
|
logger.debug(`Unhandled tool message event: ${msg.event}`);
|
|
@@ -429,3 +421,34 @@ const toolCallRepair = (modelManager, terminal) => {
|
|
|
429
421
|
};
|
|
430
422
|
return fn;
|
|
431
423
|
};
|
|
424
|
+
async function getProjectStatusLine() {
|
|
425
|
+
//
|
|
426
|
+
const currentDir = process.cwd().split("/").pop() || process.cwd();
|
|
427
|
+
const branch = await getCurrentBranch();
|
|
428
|
+
let gitStatus = "";
|
|
429
|
+
if (branch) {
|
|
430
|
+
const hasChanges = await hasUncommittedChanges();
|
|
431
|
+
const asterisk = hasChanges ? "*" : "";
|
|
432
|
+
gitStatus = ` ${chalk.gray(branch + asterisk)}`;
|
|
433
|
+
}
|
|
434
|
+
if (await inGitDirectory()) {
|
|
435
|
+
// Added check
|
|
436
|
+
const stats = await getDiffStat();
|
|
437
|
+
const fileChanges = await getGitStatus();
|
|
438
|
+
let fileStatus = "";
|
|
439
|
+
if (fileChanges.added)
|
|
440
|
+
fileStatus += ` +${fileChanges.added}`;
|
|
441
|
+
if (fileChanges.modified)
|
|
442
|
+
fileStatus += ` ~${fileChanges.modified}`;
|
|
443
|
+
if (fileChanges.deleted)
|
|
444
|
+
fileStatus += ` -${fileChanges.deleted}`;
|
|
445
|
+
if (fileChanges.untracked)
|
|
446
|
+
fileStatus += ` ?${fileChanges.untracked}`;
|
|
447
|
+
gitStatus +=
|
|
448
|
+
" " +
|
|
449
|
+
`${chalk.dim("[")}${chalk.yellow(fileStatus.trim())} ` +
|
|
450
|
+
`${chalk.green(`+${stats.insertions}`)} ` + // Insertions first (green)
|
|
451
|
+
`${chalk.red(`-${stats.deletions}`)}${chalk.dim("]")}`; // Deletions last (red)
|
|
452
|
+
}
|
|
453
|
+
return `${chalk.blue(currentDir)}${gitStatus}`;
|
|
454
|
+
}
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Terminal Formatting Utilities
|
|
3
|
-
*
|
|
4
|
-
* Provides functions for formatting and displaying text in the terminal.
|
|
5
|
-
*/
|
|
6
1
|
/**
|
|
7
2
|
* Clear the terminal screen
|
|
8
3
|
*/
|
|
@@ -34,4 +29,20 @@ export declare function getTerminalSize(): {
|
|
|
34
29
|
* Word wrap text to the specified width
|
|
35
30
|
*/
|
|
36
31
|
export declare function wordWrap(text: string, width: number): string;
|
|
32
|
+
export declare const ESC = "\u001B[";
|
|
33
|
+
export declare const OSC = "\u001B]";
|
|
34
|
+
export declare const BEL = "\u0007";
|
|
35
|
+
export declare const SEP = ";";
|
|
37
36
|
export declare const link: (text: string, url: string) => string;
|
|
37
|
+
export declare const image: (data: string | Buffer, options?: {
|
|
38
|
+
width?: number | string;
|
|
39
|
+
height?: number | string;
|
|
40
|
+
preserveAspectRatio?: boolean;
|
|
41
|
+
}) => string;
|
|
42
|
+
export declare function ansiRegex({ onlyFirst }?: {
|
|
43
|
+
onlyFirst?: boolean | undefined;
|
|
44
|
+
}): RegExp;
|
|
45
|
+
/**
|
|
46
|
+
* Strip ANSI escape sequences from a string
|
|
47
|
+
*/
|
|
48
|
+
export declare function stripAnsi(s: string): string;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Provides functions for formatting and displaying text in the terminal.
|
|
5
5
|
*/
|
|
6
|
-
import
|
|
6
|
+
import { supportsHyperlinks } from "./supports-hyperlinks.js";
|
|
7
7
|
/**
|
|
8
8
|
* Clear the terminal screen
|
|
9
9
|
*/
|
|
@@ -99,8 +99,42 @@ function wrapLine(line, width) {
|
|
|
99
99
|
}
|
|
100
100
|
return wrappedLines.join("\n");
|
|
101
101
|
}
|
|
102
|
-
|
|
103
|
-
const OSC = "\u001B]";
|
|
104
|
-
const BEL = "\u0007";
|
|
105
|
-
const SEP = ";";
|
|
106
|
-
export const link = (text, url) =>
|
|
102
|
+
export const ESC = "\u001B[";
|
|
103
|
+
export const OSC = "\u001B]";
|
|
104
|
+
export const BEL = "\u0007";
|
|
105
|
+
export const SEP = ";";
|
|
106
|
+
export const link = (text, url) => {
|
|
107
|
+
if (supportsHyperlinks.stdout) {
|
|
108
|
+
return [OSC, "8", SEP, SEP, url, BEL, text, OSC, "8", SEP, SEP, BEL].join("");
|
|
109
|
+
}
|
|
110
|
+
return `[${text}](${url})`;
|
|
111
|
+
};
|
|
112
|
+
export const image = (data, options = {}) => {
|
|
113
|
+
let returnValue = `${OSC}1337;File=inline=1`;
|
|
114
|
+
if (options.width) {
|
|
115
|
+
returnValue += `;width=${options.width}`;
|
|
116
|
+
}
|
|
117
|
+
if (options.height) {
|
|
118
|
+
returnValue += `;height=${options.height}`;
|
|
119
|
+
}
|
|
120
|
+
if (options.preserveAspectRatio === false) {
|
|
121
|
+
returnValue += ";preserveAspectRatio=0";
|
|
122
|
+
}
|
|
123
|
+
return `${returnValue}:${Buffer.from(data).toString("base64")}${BEL}`;
|
|
124
|
+
};
|
|
125
|
+
export function ansiRegex({ onlyFirst = false } = {}) {
|
|
126
|
+
// Valid string terminator sequences are BEL, ESC\, and 0x9c
|
|
127
|
+
const st = "(?:\\u0007|\\u001B\\u005C|\\u009C)";
|
|
128
|
+
const pattern = [
|
|
129
|
+
`[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?${st})`,
|
|
130
|
+
"(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))",
|
|
131
|
+
].join("|");
|
|
132
|
+
return new RegExp(pattern, onlyFirst ? undefined : "g");
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Strip ANSI escape sequences from a string
|
|
136
|
+
*/
|
|
137
|
+
export function stripAnsi(s) {
|
|
138
|
+
// biome-ignore lint/suspicious/noControlCharactersInRegex: need to detect ansi control characters
|
|
139
|
+
return s.replace(/\x1B\[[0-?]*[ -/]*[@-~]/g, "");
|
|
140
|
+
}
|
package/dist/terminal/index.d.ts
CHANGED
package/dist/terminal/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import ora from "ora";
|
|
|
10
10
|
import wrapAnsi from "wrap-ansi";
|
|
11
11
|
import { logger } from "../logger.js";
|
|
12
12
|
import { getPackageVersion } from "../version.js";
|
|
13
|
-
import { clearTerminal, getTerminalSize, setTerminalTitle, link as terminalLink, } from "./formatting.js";
|
|
13
|
+
import { clearTerminal, getTerminalSize, setTerminalTitle, stripAnsi, link as terminalLink, } from "./formatting.js";
|
|
14
14
|
import { applyMarkdown } from "./markdown.js";
|
|
15
15
|
/**
|
|
16
16
|
* Initialize the terminal interface
|
|
@@ -214,9 +214,6 @@ export class Terminal {
|
|
|
214
214
|
const cols = this.terminalWidth > 0 ? this.terminalWidth : 80;
|
|
215
215
|
const width = Math.max(4, cols - 4);
|
|
216
216
|
// Helper to strip ANSI sequences for accurate visible-width calculation
|
|
217
|
-
const stripAnsi = (s) =>
|
|
218
|
-
// biome-ignore lint/suspicious/noControlCharactersInRegex: need to detect ansi control characters
|
|
219
|
-
s.replace(/\x1B\[[0-?]*[ -/]*[@-~]/g, "");
|
|
220
217
|
const paddedHeader = ` ${header} `;
|
|
221
218
|
const headerVisibleLen = stripAnsi(paddedHeader).length;
|
|
222
219
|
const headerStartPos = 1;
|
|
@@ -249,27 +246,68 @@ export class Terminal {
|
|
|
249
246
|
* Create a clickable link in the terminal if supported
|
|
250
247
|
*/
|
|
251
248
|
link(text, url) {
|
|
252
|
-
return terminalLink(text, url);
|
|
249
|
+
return chalk.underline.blue(terminalLink(text, url));
|
|
253
250
|
}
|
|
254
251
|
/**
|
|
255
252
|
* Display a table of data
|
|
256
253
|
*/
|
|
257
254
|
table(data, options = {}) {
|
|
258
255
|
const { header, colWidths } = options;
|
|
256
|
+
// Determine number of columns from data or header
|
|
257
|
+
let colCount = header?.length;
|
|
258
|
+
if (colCount === undefined) {
|
|
259
|
+
colCount = data.length > 0 && data[0] ? data[0].length : 1;
|
|
260
|
+
}
|
|
259
261
|
// Calculate column widths based on terminal width
|
|
260
262
|
const padding = 5; // Account for table borders and padding
|
|
261
|
-
const availableWidth = Math.max(
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
263
|
+
const availableWidth = Math.max(20, this.terminalWidth - padding);
|
|
264
|
+
let computedColWidths;
|
|
265
|
+
if (colWidths && colWidths.length === colCount) {
|
|
266
|
+
// Use provided percentages
|
|
267
|
+
computedColWidths = colWidths.map((percent) => Math.max(10, Math.floor((percent / 100) * availableWidth)));
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
// Distribute width evenly with minimum width per column
|
|
271
|
+
const minColWidth = 15;
|
|
272
|
+
const maxColsThatFit = Math.floor(availableWidth / minColWidth);
|
|
273
|
+
const actualColCount = Math.min(colCount, maxColsThatFit);
|
|
274
|
+
if (actualColCount === 1) {
|
|
275
|
+
computedColWidths = [availableWidth];
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
// Calculate base width and distribute remaining pixels
|
|
279
|
+
const baseWidth = Math.floor(availableWidth / actualColCount);
|
|
280
|
+
const remainder = availableWidth % actualColCount;
|
|
281
|
+
computedColWidths = Array(actualColCount).fill(baseWidth);
|
|
282
|
+
// Distribute remainder pixels to first few columns
|
|
283
|
+
for (let i = 0; i < remainder && i < actualColCount; i++) {
|
|
284
|
+
computedColWidths[i] = (computedColWidths[i] || 0) + 1;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
// If we have fewer computed widths than columns, extend the array
|
|
288
|
+
while (computedColWidths.length < colCount) {
|
|
289
|
+
computedColWidths.push(minColWidth);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
267
292
|
const table = new Table({
|
|
268
293
|
head: header,
|
|
269
294
|
colWidths: computedColWidths,
|
|
270
|
-
wordWrap: true,
|
|
295
|
+
wordWrap: true,
|
|
296
|
+
wrapOnWordBoundary: true,
|
|
297
|
+
});
|
|
298
|
+
// Ensure all data rows have the same number of columns
|
|
299
|
+
const normalizedData = data.map((row) => {
|
|
300
|
+
if (row.length < colCount) {
|
|
301
|
+
// Pad with empty strings if row has fewer columns
|
|
302
|
+
return [...row, ...Array(colCount - row.length).fill("")];
|
|
303
|
+
}
|
|
304
|
+
if (row.length > colCount) {
|
|
305
|
+
// Truncate if row has more columns
|
|
306
|
+
return row.slice(0, colCount);
|
|
307
|
+
}
|
|
308
|
+
return row;
|
|
271
309
|
});
|
|
272
|
-
table.push(...
|
|
310
|
+
table.push(...normalizedData);
|
|
273
311
|
this.writeln(table.toString());
|
|
274
312
|
}
|
|
275
313
|
/**
|
|
@@ -400,7 +438,9 @@ export class Terminal {
|
|
|
400
438
|
const percentage = total === 0 ? 1 : current / total;
|
|
401
439
|
const filledWidth = Math.max(0, Math.min(progressBarMaxWidth, Math.floor(percentage * progressBarMaxWidth)));
|
|
402
440
|
const emptyWidth = Math.max(0, progressBarMaxWidth - filledWidth);
|
|
403
|
-
const a =
|
|
441
|
+
const a = filledWidth / progressBarMaxWidth > 0.5
|
|
442
|
+
? chalk.red("─")
|
|
443
|
+
: chalk.yellow("─"); //"█"
|
|
404
444
|
const b = chalk.gray("─"); // "░"
|
|
405
445
|
const filledBar = a.repeat(filledWidth);
|
|
406
446
|
const emptyBar = b.repeat(emptyWidth);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
interface ColorSupport {
|
|
2
|
+
level: number;
|
|
3
|
+
hasBasic: boolean;
|
|
4
|
+
has256: boolean;
|
|
5
|
+
has16m: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function createSupportsColor(stream: {
|
|
8
|
+
isTty?: boolean;
|
|
9
|
+
}, options?: {
|
|
10
|
+
streamIsTty?: boolean;
|
|
11
|
+
}): ColorSupport | false;
|
|
12
|
+
export declare const supportsColor: {
|
|
13
|
+
stdout: false | ColorSupport;
|
|
14
|
+
stderr: false | ColorSupport;
|
|
15
|
+
};
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// based on https://raw.githubusercontent.com/chalk/supports-color/refs/heads/main/index.js
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import tty from "node:tty";
|
|
5
|
+
const { env } = process;
|
|
6
|
+
function envForceColor() {
|
|
7
|
+
if (!("FORCE_COLOR" in env)) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
if (env["FORCE_COLOR"] === "true") {
|
|
11
|
+
return 1;
|
|
12
|
+
}
|
|
13
|
+
if (env["FORCE_COLOR"] === "false") {
|
|
14
|
+
return 0;
|
|
15
|
+
}
|
|
16
|
+
if (env["FORCE_COLOR"] && env["FORCE_COLOR"].length === 0) {
|
|
17
|
+
return 1;
|
|
18
|
+
}
|
|
19
|
+
const level = Math.min(Number.parseInt(env["FORCE_COLOR"] || "0", 10), 3);
|
|
20
|
+
if (![0, 1, 2, 3].includes(level)) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
return level;
|
|
24
|
+
}
|
|
25
|
+
function translateLevel(level) {
|
|
26
|
+
if (level === 0) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
level,
|
|
31
|
+
hasBasic: true,
|
|
32
|
+
has256: level >= 2,
|
|
33
|
+
has16m: level >= 3,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function _supportsColor(haveStream, options = {}) {
|
|
37
|
+
const noFlagForceColor = envForceColor();
|
|
38
|
+
const forceColor = noFlagForceColor;
|
|
39
|
+
if (forceColor === 0) {
|
|
40
|
+
return 0;
|
|
41
|
+
}
|
|
42
|
+
// Check for Azure DevOps pipelines.
|
|
43
|
+
// Has to be above the `!streamIsTTY` check.
|
|
44
|
+
if ("TF_BUILD" in env && "AGENT_NAME" in env) {
|
|
45
|
+
return 1;
|
|
46
|
+
}
|
|
47
|
+
if (haveStream && !options.streamIsTty && forceColor === undefined) {
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
const min = forceColor || 0;
|
|
51
|
+
if (env["TERM"] === "dumb") {
|
|
52
|
+
return min;
|
|
53
|
+
}
|
|
54
|
+
if (process.platform === "win32") {
|
|
55
|
+
// Windows 10 build 10586 is the first Windows release that supports 256 colors.
|
|
56
|
+
// Windows 10 build 14931 is the first release that supports 16m/TrueColor.
|
|
57
|
+
const osRelease = os.release().split(".");
|
|
58
|
+
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10_586) {
|
|
59
|
+
return Number(osRelease[2]) >= 14_931 ? 3 : 2;
|
|
60
|
+
}
|
|
61
|
+
return 1;
|
|
62
|
+
}
|
|
63
|
+
if ("CI" in env) {
|
|
64
|
+
if (["GITHUB_ACTIONS", "GITEA_ACTIONS", "CIRCLECI"].some((key) => key in env)) {
|
|
65
|
+
return 3;
|
|
66
|
+
}
|
|
67
|
+
if (["TRAVIS", "APPVEYOR", "GITLAB_CI", "BUILDKITE", "DRONE"].some((sign) => sign in env) ||
|
|
68
|
+
env["CI_NAME"] === "codeship") {
|
|
69
|
+
return 1;
|
|
70
|
+
}
|
|
71
|
+
return min;
|
|
72
|
+
}
|
|
73
|
+
if ("TEAMCITY_VERSION" in env) {
|
|
74
|
+
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env["TEAMCITY_VERSION"] || "")
|
|
75
|
+
? 1
|
|
76
|
+
: 0;
|
|
77
|
+
}
|
|
78
|
+
if (env["COLORTERM"] === "truecolor") {
|
|
79
|
+
return 3;
|
|
80
|
+
}
|
|
81
|
+
if (env["TERM"] === "xterm-kitty") {
|
|
82
|
+
return 3;
|
|
83
|
+
}
|
|
84
|
+
if (env["TERM"] === "xterm-ghostty") {
|
|
85
|
+
return 3;
|
|
86
|
+
}
|
|
87
|
+
if ("TERM_PROGRAM" in env) {
|
|
88
|
+
const termProgramVersion = String(env["TERM_PROGRAM_VERSION"] || "0");
|
|
89
|
+
const version = Number.parseInt(termProgramVersion.split(".")[0] ?? "0", 10);
|
|
90
|
+
switch (env["TERM_PROGRAM"]) {
|
|
91
|
+
case "iTerm.app": {
|
|
92
|
+
return version >= 3 ? 3 : 2;
|
|
93
|
+
}
|
|
94
|
+
case "Apple_Terminal": {
|
|
95
|
+
return 2;
|
|
96
|
+
}
|
|
97
|
+
// No default
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (/-256(color)?$/i.test(env["TERM"] || "")) {
|
|
101
|
+
return 2;
|
|
102
|
+
}
|
|
103
|
+
if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env["TERM"] || "")) {
|
|
104
|
+
return 1;
|
|
105
|
+
}
|
|
106
|
+
if ("COLORTERM" in env) {
|
|
107
|
+
return 1;
|
|
108
|
+
}
|
|
109
|
+
return min;
|
|
110
|
+
}
|
|
111
|
+
export function createSupportsColor(stream, options = {}) {
|
|
112
|
+
const level = _supportsColor(true, {
|
|
113
|
+
streamIsTty: stream?.isTty,
|
|
114
|
+
...options,
|
|
115
|
+
});
|
|
116
|
+
return translateLevel(level);
|
|
117
|
+
}
|
|
118
|
+
export const supportsColor = {
|
|
119
|
+
stdout: createSupportsColor({ isTty: tty.isatty(1) }),
|
|
120
|
+
stderr: createSupportsColor({ isTty: tty.isatty(2) }),
|
|
121
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// based on https://raw.githubusercontent.com/chalk/supports-hyperlinks/refs/heads/main/index.js
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
import { createSupportsColor } from "./supports-color.js";
|
|
4
|
+
function parseVersion(versionString = "") {
|
|
5
|
+
if (/^\d{3,4}$/.test(versionString)) {
|
|
6
|
+
// Env var doesn't always use dots. example: 4601 => 46.1.0
|
|
7
|
+
const match = /(\d{1,2})(\d{2})/.exec(versionString) ?? [];
|
|
8
|
+
return {
|
|
9
|
+
major: 0,
|
|
10
|
+
minor: Number.parseInt(match[1] ?? "0", 10),
|
|
11
|
+
patch: Number.parseInt(match[2] ?? "0", 10),
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
const versions = (versionString ?? "")
|
|
15
|
+
.split(".")
|
|
16
|
+
.map((n) => Number.parseInt(n, 10));
|
|
17
|
+
return {
|
|
18
|
+
major: versions[0] ?? 0,
|
|
19
|
+
minor: versions[1] ?? 0,
|
|
20
|
+
patch: versions[2] ?? 0,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export function createSupportsHyperlinks(stream) {
|
|
24
|
+
const { CI, CURSOR_TRACE_ID, FORCE_HYPERLINK, NETLIFY, TEAMCITY_VERSION, TERM_PROGRAM, TERM_PROGRAM_VERSION, VTE_VERSION, TERM, } = process.env;
|
|
25
|
+
if (FORCE_HYPERLINK) {
|
|
26
|
+
return !(FORCE_HYPERLINK.length > 0 && Number.parseInt(FORCE_HYPERLINK, 10) === 0);
|
|
27
|
+
}
|
|
28
|
+
// Netlify does not run a TTY, it does not need `supportsColor` check
|
|
29
|
+
if (NETLIFY) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
// If they specify no colors, they probably don't want hyperlinks.
|
|
33
|
+
if (!createSupportsColor(stream)) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
if (stream && !stream.isTty) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
// Windows Terminal
|
|
40
|
+
if ("WT_SESSION" in process.env) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
if (process.platform === "win32") {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
if (CI) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
if (TEAMCITY_VERSION) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
if (TERM_PROGRAM) {
|
|
53
|
+
const version = parseVersion(TERM_PROGRAM_VERSION);
|
|
54
|
+
switch (TERM_PROGRAM) {
|
|
55
|
+
case "iTerm.app": {
|
|
56
|
+
if (version.major === 3) {
|
|
57
|
+
return version.minor >= 1;
|
|
58
|
+
}
|
|
59
|
+
return version.major > 3;
|
|
60
|
+
}
|
|
61
|
+
case "WezTerm": {
|
|
62
|
+
return version.major >= 20_200_620;
|
|
63
|
+
}
|
|
64
|
+
case "vscode": {
|
|
65
|
+
// Cursor forked VS Code and supports hyperlinks in 0.x.x
|
|
66
|
+
if (CURSOR_TRACE_ID) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
// eslint-disable-next-line no-mixed-operators
|
|
70
|
+
return (version.major > 1 || (version.major === 1 && version.minor >= 72));
|
|
71
|
+
}
|
|
72
|
+
case "ghostty": {
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
// No default
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (VTE_VERSION) {
|
|
79
|
+
// 0.50.0 was supposed to support hyperlinks, but throws a segfault
|
|
80
|
+
if (VTE_VERSION === "0.50.0") {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
const version = parseVersion(VTE_VERSION);
|
|
84
|
+
return version.major > 0 || version.minor >= 50;
|
|
85
|
+
}
|
|
86
|
+
switch (TERM) {
|
|
87
|
+
case "alacritty": {
|
|
88
|
+
// Support added in v0.11 (2022-10-13)
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
// No default
|
|
92
|
+
}
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
export const supportsHyperlinks = {
|
|
96
|
+
stdout: createSupportsHyperlinks({ isTty: process.stdout.isTTY }),
|
|
97
|
+
stderr: createSupportsHyperlinks({ isTty: process.stderr.isTTY }),
|
|
98
|
+
};
|