squads-cli 0.4.8 → 0.4.9
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/dist/{chunk-IDZYXBZY.js → chunk-HIQ2APYR.js} +13 -269
- package/dist/chunk-HIQ2APYR.js.map +1 -0
- package/dist/chunk-HKWCBCEK.js +225 -0
- package/dist/chunk-HKWCBCEK.js.map +1 -0
- package/dist/chunk-NA3IECJA.js +288 -0
- package/dist/chunk-NA3IECJA.js.map +1 -0
- package/dist/cli.js +358 -573
- package/dist/cli.js.map +1 -1
- package/dist/{sessions-B6GVXJ2H.js → sessions-R4VWIGFR.js} +3 -2
- package/dist/terminal-JZSAQSN7.js +53 -0
- package/dist/terminal-JZSAQSN7.js.map +1 -0
- package/dist/update-MAY6EXFQ.js +17 -0
- package/dist/update-MAY6EXFQ.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-IDZYXBZY.js.map +0 -1
- /package/dist/{sessions-B6GVXJ2H.js.map → sessions-R4VWIGFR.js.map} +0 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
__require
|
|
4
|
+
} from "./chunk-7OCVIDC7.js";
|
|
5
|
+
|
|
6
|
+
// src/lib/update.ts
|
|
7
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, unlinkSync } from "fs";
|
|
8
|
+
import { join, dirname } from "path";
|
|
9
|
+
import { homedir } from "os";
|
|
10
|
+
import { execSync } from "child_process";
|
|
11
|
+
import { fileURLToPath } from "url";
|
|
12
|
+
function getPackageVersion() {
|
|
13
|
+
try {
|
|
14
|
+
const __filename2 = fileURLToPath(import.meta.url);
|
|
15
|
+
const __dirname2 = dirname(__filename2);
|
|
16
|
+
const possiblePaths = [
|
|
17
|
+
join(__dirname2, "..", "..", "package.json"),
|
|
18
|
+
// From dist/lib/
|
|
19
|
+
join(__dirname2, "..", "package.json"),
|
|
20
|
+
// From dist/
|
|
21
|
+
join(__dirname2, "package.json")
|
|
22
|
+
// Same dir
|
|
23
|
+
];
|
|
24
|
+
for (const pkgPath of possiblePaths) {
|
|
25
|
+
if (existsSync(pkgPath)) {
|
|
26
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
27
|
+
return pkg.version || "0.0.0";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
} catch {
|
|
31
|
+
}
|
|
32
|
+
return "0.0.0";
|
|
33
|
+
}
|
|
34
|
+
var CURRENT_VERSION = getPackageVersion();
|
|
35
|
+
var CACHE_DIR = join(homedir(), ".squads");
|
|
36
|
+
var CACHE_FILE = join(CACHE_DIR, "update-check.json");
|
|
37
|
+
var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
38
|
+
function isNewerVersion(v1, v2) {
|
|
39
|
+
const parts1 = v1.replace(/^v/, "").split(".").map(Number);
|
|
40
|
+
const parts2 = v2.replace(/^v/, "").split(".").map(Number);
|
|
41
|
+
for (let i = 0; i < 3; i++) {
|
|
42
|
+
const p1 = parts1[i] || 0;
|
|
43
|
+
const p2 = parts2[i] || 0;
|
|
44
|
+
if (p2 > p1) return true;
|
|
45
|
+
if (p2 < p1) return false;
|
|
46
|
+
}
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
function readCache() {
|
|
50
|
+
try {
|
|
51
|
+
if (!existsSync(CACHE_FILE)) return null;
|
|
52
|
+
const data = JSON.parse(readFileSync(CACHE_FILE, "utf-8"));
|
|
53
|
+
return data;
|
|
54
|
+
} catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function writeCache(latestVersion) {
|
|
59
|
+
try {
|
|
60
|
+
if (!existsSync(CACHE_DIR)) {
|
|
61
|
+
mkdirSync(CACHE_DIR, { recursive: true });
|
|
62
|
+
}
|
|
63
|
+
const cache = {
|
|
64
|
+
latestVersion,
|
|
65
|
+
checkedAt: Date.now()
|
|
66
|
+
};
|
|
67
|
+
writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2));
|
|
68
|
+
} catch {
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function fetchLatestVersion() {
|
|
72
|
+
try {
|
|
73
|
+
const result = execSync("npm view squads-cli version 2>/dev/null", {
|
|
74
|
+
encoding: "utf-8",
|
|
75
|
+
timeout: 5e3
|
|
76
|
+
}).trim();
|
|
77
|
+
return result || null;
|
|
78
|
+
} catch {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function checkForUpdate() {
|
|
83
|
+
const result = {
|
|
84
|
+
currentVersion: CURRENT_VERSION,
|
|
85
|
+
latestVersion: CURRENT_VERSION,
|
|
86
|
+
updateAvailable: false
|
|
87
|
+
};
|
|
88
|
+
const cache = readCache();
|
|
89
|
+
const now = Date.now();
|
|
90
|
+
if (cache) {
|
|
91
|
+
result.latestVersion = cache.latestVersion;
|
|
92
|
+
result.updateAvailable = isNewerVersion(CURRENT_VERSION, cache.latestVersion);
|
|
93
|
+
if (now - cache.checkedAt >= CACHE_TTL_MS) {
|
|
94
|
+
triggerBackgroundRefresh();
|
|
95
|
+
}
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
triggerBackgroundRefresh();
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
function triggerBackgroundRefresh() {
|
|
102
|
+
try {
|
|
103
|
+
const { spawn } = __require("child_process");
|
|
104
|
+
const child = spawn("npm", ["view", "squads-cli", "version"], {
|
|
105
|
+
detached: true,
|
|
106
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
107
|
+
shell: true
|
|
108
|
+
});
|
|
109
|
+
let output = "";
|
|
110
|
+
child.stdout?.on("data", (data) => {
|
|
111
|
+
output += data.toString();
|
|
112
|
+
});
|
|
113
|
+
child.on("close", () => {
|
|
114
|
+
const version = output.trim();
|
|
115
|
+
if (version && /^\d+\.\d+\.\d+/.test(version)) {
|
|
116
|
+
writeCache(version);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
child.unref();
|
|
120
|
+
} catch {
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function getCurrentVersion() {
|
|
124
|
+
return CURRENT_VERSION;
|
|
125
|
+
}
|
|
126
|
+
function performUpdate() {
|
|
127
|
+
try {
|
|
128
|
+
execSync("npm update -g squads-cli", {
|
|
129
|
+
encoding: "utf-8",
|
|
130
|
+
stdio: "inherit",
|
|
131
|
+
timeout: 12e4
|
|
132
|
+
// 2 minutes
|
|
133
|
+
});
|
|
134
|
+
try {
|
|
135
|
+
unlinkSync(CACHE_FILE);
|
|
136
|
+
} catch {
|
|
137
|
+
}
|
|
138
|
+
return { success: true };
|
|
139
|
+
} catch (err) {
|
|
140
|
+
return {
|
|
141
|
+
success: false,
|
|
142
|
+
error: err instanceof Error ? err.message : "Unknown error"
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function refreshVersionCache() {
|
|
147
|
+
const latestVersion = fetchLatestVersion();
|
|
148
|
+
if (latestVersion) {
|
|
149
|
+
writeCache(latestVersion);
|
|
150
|
+
return {
|
|
151
|
+
currentVersion: CURRENT_VERSION,
|
|
152
|
+
latestVersion,
|
|
153
|
+
updateAvailable: isNewerVersion(CURRENT_VERSION, latestVersion)
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
return checkForUpdate();
|
|
157
|
+
}
|
|
158
|
+
var AUTO_UPDATE_CACHE_FILE = join(CACHE_DIR, "auto-update.json");
|
|
159
|
+
var AUTO_UPDATE_COOLDOWN_MS = 60 * 60 * 1e3;
|
|
160
|
+
function readAutoUpdateCache() {
|
|
161
|
+
try {
|
|
162
|
+
if (!existsSync(AUTO_UPDATE_CACHE_FILE)) return null;
|
|
163
|
+
return JSON.parse(readFileSync(AUTO_UPDATE_CACHE_FILE, "utf-8"));
|
|
164
|
+
} catch {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function writeAutoUpdateCache(cache) {
|
|
169
|
+
try {
|
|
170
|
+
if (!existsSync(CACHE_DIR)) {
|
|
171
|
+
mkdirSync(CACHE_DIR, { recursive: true });
|
|
172
|
+
}
|
|
173
|
+
writeFileSync(AUTO_UPDATE_CACHE_FILE, JSON.stringify(cache, null, 2));
|
|
174
|
+
} catch {
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
async function autoUpdateOnStartup(silent = false) {
|
|
178
|
+
if (process.env.CI || process.env.SQUADS_NO_AUTO_UPDATE) return;
|
|
179
|
+
const autoCache = readAutoUpdateCache();
|
|
180
|
+
const now = Date.now();
|
|
181
|
+
if (autoCache && now - autoCache.lastAttempt < AUTO_UPDATE_COOLDOWN_MS) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const info = checkForUpdate();
|
|
185
|
+
if (!info.updateAvailable) return;
|
|
186
|
+
writeAutoUpdateCache({ lastAttempt: now, lastSuccess: autoCache?.lastSuccess });
|
|
187
|
+
try {
|
|
188
|
+
const { spawn } = await import("child_process");
|
|
189
|
+
const child = spawn("npm", ["update", "-g", "squads-cli"], {
|
|
190
|
+
detached: true,
|
|
191
|
+
stdio: silent ? "ignore" : ["ignore", "pipe", "pipe"],
|
|
192
|
+
shell: true
|
|
193
|
+
});
|
|
194
|
+
if (!silent && child.stdout) {
|
|
195
|
+
await new Promise((resolve) => {
|
|
196
|
+
child.on("close", (code) => {
|
|
197
|
+
if (code === 0) {
|
|
198
|
+
console.log(`
|
|
199
|
+
\x1B[32m\u2713\x1B[0m Update successful! v${info.latestVersion} will be used on your next run.
|
|
200
|
+
`);
|
|
201
|
+
writeAutoUpdateCache({ lastAttempt: now, lastSuccess: now });
|
|
202
|
+
try {
|
|
203
|
+
unlinkSync(CACHE_FILE);
|
|
204
|
+
} catch {
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
resolve();
|
|
208
|
+
});
|
|
209
|
+
setTimeout(() => resolve(), 3e4);
|
|
210
|
+
});
|
|
211
|
+
} else {
|
|
212
|
+
child.unref();
|
|
213
|
+
}
|
|
214
|
+
} catch {
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export {
|
|
219
|
+
checkForUpdate,
|
|
220
|
+
getCurrentVersion,
|
|
221
|
+
performUpdate,
|
|
222
|
+
refreshVersionCache,
|
|
223
|
+
autoUpdateOnStartup
|
|
224
|
+
};
|
|
225
|
+
//# sourceMappingURL=chunk-HKWCBCEK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/update.ts"],"sourcesContent":["/**\n * Update checker for squads-cli\n * Checks npm registry for newer versions and caches result\n */\n\nimport { existsSync, readFileSync, writeFileSync, mkdirSync, unlinkSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { homedir } from 'os';\nimport { execSync } from 'child_process';\nimport { fileURLToPath } from 'url';\n\n// Get current version from package.json\nfunction getPackageVersion(): string {\n try {\n // Try to find package.json relative to this module\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n\n // Look up from dist/lib to find package.json\n const possiblePaths = [\n join(__dirname, '..', '..', 'package.json'), // From dist/lib/\n join(__dirname, '..', 'package.json'), // From dist/\n join(__dirname, 'package.json'), // Same dir\n ];\n\n for (const pkgPath of possiblePaths) {\n if (existsSync(pkgPath)) {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n return pkg.version || '0.0.0';\n }\n }\n } catch {\n // Ignore errors\n }\n return '0.0.0';\n}\n\nconst CURRENT_VERSION = getPackageVersion();\n\n// Cache settings\nconst CACHE_DIR = join(homedir(), '.squads');\nconst CACHE_FILE = join(CACHE_DIR, 'update-check.json');\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours\n\ninterface UpdateCache {\n latestVersion: string;\n checkedAt: number;\n}\n\nexport interface UpdateInfo {\n currentVersion: string;\n latestVersion: string;\n updateAvailable: boolean;\n}\n\n/**\n * Compare semantic versions\n * Returns true if v2 > v1\n */\nfunction isNewerVersion(v1: string, v2: string): boolean {\n const parts1 = v1.replace(/^v/, '').split('.').map(Number);\n const parts2 = v2.replace(/^v/, '').split('.').map(Number);\n\n for (let i = 0; i < 3; i++) {\n const p1 = parts1[i] || 0;\n const p2 = parts2[i] || 0;\n if (p2 > p1) return true;\n if (p2 < p1) return false;\n }\n return false;\n}\n\n/**\n * Read cached update info\n */\nfunction readCache(): UpdateCache | null {\n try {\n if (!existsSync(CACHE_FILE)) return null;\n const data = JSON.parse(readFileSync(CACHE_FILE, 'utf-8'));\n return data as UpdateCache;\n } catch {\n return null;\n }\n}\n\n/**\n * Write update info to cache\n */\nfunction writeCache(latestVersion: string): void {\n try {\n if (!existsSync(CACHE_DIR)) {\n mkdirSync(CACHE_DIR, { recursive: true });\n }\n const cache: UpdateCache = {\n latestVersion,\n checkedAt: Date.now(),\n };\n writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2));\n } catch {\n // Ignore cache write errors\n }\n}\n\n/**\n * Fetch latest version from npm registry\n */\nfunction fetchLatestVersion(): string | null {\n try {\n const result = execSync('npm view squads-cli version 2>/dev/null', {\n encoding: 'utf-8',\n timeout: 5000,\n }).trim();\n return result || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Check for updates (uses cache to avoid frequent npm calls)\n * Non-blocking: returns cached data immediately, triggers background refresh if stale\n */\nexport function checkForUpdate(): UpdateInfo {\n const result: UpdateInfo = {\n currentVersion: CURRENT_VERSION,\n latestVersion: CURRENT_VERSION,\n updateAvailable: false,\n };\n\n // Check cache first\n const cache = readCache();\n const now = Date.now();\n\n if (cache) {\n // Always use cached value immediately for fast response\n result.latestVersion = cache.latestVersion;\n result.updateAvailable = isNewerVersion(CURRENT_VERSION, cache.latestVersion);\n\n // If cache is stale, trigger background refresh (non-blocking)\n if ((now - cache.checkedAt) >= CACHE_TTL_MS) {\n // Fire and forget - don't await\n triggerBackgroundRefresh();\n }\n return result;\n }\n\n // No cache at all - trigger background refresh and return defaults\n triggerBackgroundRefresh();\n return result;\n}\n\n/**\n * Trigger a background version check that doesn't block the CLI\n * Uses spawn to run npm in a detached process\n */\nfunction triggerBackgroundRefresh(): void {\n try {\n // Use spawn with detached: true to run in background\n // This won't block the main process\n const { spawn } = require('child_process') as typeof import('child_process');\n const child = spawn('npm', ['view', 'squads-cli', 'version'], {\n detached: true,\n stdio: ['ignore', 'pipe', 'ignore'],\n shell: true,\n });\n\n // Collect output\n let output = '';\n child.stdout?.on('data', (data: Buffer) => {\n output += data.toString();\n });\n\n child.on('close', () => {\n const version = output.trim();\n if (version && /^\\d+\\.\\d+\\.\\d+/.test(version)) {\n writeCache(version);\n }\n });\n\n // Unref to allow main process to exit\n child.unref();\n } catch {\n // Ignore errors - background refresh is best effort\n }\n}\n\n/**\n * Get current version\n */\nexport function getCurrentVersion(): string {\n return CURRENT_VERSION;\n}\n\n/**\n * Perform the actual update via npm\n * Returns true if successful\n */\nexport function performUpdate(): { success: boolean; error?: string } {\n try {\n execSync('npm update -g squads-cli', {\n encoding: 'utf-8',\n stdio: 'inherit',\n timeout: 120000, // 2 minutes\n });\n // Clear cache so next check fetches fresh\n try {\n unlinkSync(CACHE_FILE);\n } catch {\n // Ignore\n }\n return { success: true };\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : 'Unknown error',\n };\n }\n}\n\n/**\n * Force refresh the version cache (bypass TTL)\n */\nexport function refreshVersionCache(): UpdateInfo {\n const latestVersion = fetchLatestVersion();\n if (latestVersion) {\n writeCache(latestVersion);\n return {\n currentVersion: CURRENT_VERSION,\n latestVersion,\n updateAvailable: isNewerVersion(CURRENT_VERSION, latestVersion),\n };\n }\n return checkForUpdate();\n}\n\n// Auto-update settings\nconst AUTO_UPDATE_CACHE_FILE = join(CACHE_DIR, 'auto-update.json');\nconst AUTO_UPDATE_COOLDOWN_MS = 60 * 60 * 1000; // 1 hour cooldown between auto-update attempts\n\ninterface AutoUpdateCache {\n lastAttempt: number;\n lastSuccess?: number;\n}\n\nfunction readAutoUpdateCache(): AutoUpdateCache | null {\n try {\n if (!existsSync(AUTO_UPDATE_CACHE_FILE)) return null;\n return JSON.parse(readFileSync(AUTO_UPDATE_CACHE_FILE, 'utf-8'));\n } catch {\n return null;\n }\n}\n\nfunction writeAutoUpdateCache(cache: AutoUpdateCache): void {\n try {\n if (!existsSync(CACHE_DIR)) {\n mkdirSync(CACHE_DIR, { recursive: true });\n }\n writeFileSync(AUTO_UPDATE_CACHE_FILE, JSON.stringify(cache, null, 2));\n } catch {\n // Ignore errors\n }\n}\n\n/**\n * Seamless auto-update on CLI startup (like Gemini CLI)\n * Checks for updates and auto-installs without prompting.\n * Shows a message on success: \"Update successful! The new version will be used on your next run.\"\n *\n * @param silent - If true, don't show any output (for background checks)\n * @returns Promise that resolves when check/update is complete\n */\nexport async function autoUpdateOnStartup(silent = false): Promise<void> {\n // Skip in CI or if auto-update disabled\n if (process.env.CI || process.env.SQUADS_NO_AUTO_UPDATE) return;\n\n // Check cooldown - don't spam npm\n const autoCache = readAutoUpdateCache();\n const now = Date.now();\n if (autoCache && (now - autoCache.lastAttempt) < AUTO_UPDATE_COOLDOWN_MS) {\n return; // Too soon since last attempt\n }\n\n // Check if update is available\n const info = checkForUpdate();\n if (!info.updateAvailable) return;\n\n // Write attempt timestamp before trying\n writeAutoUpdateCache({ lastAttempt: now, lastSuccess: autoCache?.lastSuccess });\n\n // Perform update silently in background using spawn\n try {\n const { spawn } = await import('child_process');\n\n // Run npm update in background\n const child = spawn('npm', ['update', '-g', 'squads-cli'], {\n detached: true,\n stdio: silent ? 'ignore' : ['ignore', 'pipe', 'pipe'],\n shell: true,\n });\n\n if (!silent && child.stdout) {\n // Wait for completion and check result\n await new Promise<void>((resolve) => {\n child.on('close', (code) => {\n if (code === 0) {\n // Success - show Gemini-style message\n console.log(`\\n \\x1b[32m✓\\x1b[0m Update successful! v${info.latestVersion} will be used on your next run.\\n`);\n writeAutoUpdateCache({ lastAttempt: now, lastSuccess: now });\n // Clear version cache so next startup detects new version\n try { unlinkSync(CACHE_FILE); } catch { /* ignore */ }\n }\n resolve();\n });\n\n // Timeout after 30 seconds\n setTimeout(() => resolve(), 30000);\n });\n } else {\n // Silent mode - just fire and forget\n child.unref();\n }\n } catch {\n // Ignore errors - auto-update is best effort\n }\n}\n"],"mappings":"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","names":["__filename","__dirname"]}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/lib/terminal.ts
|
|
4
|
+
var ESC = "\x1B[";
|
|
5
|
+
var RESET = `${ESC}0m`;
|
|
6
|
+
function supportsTrueColor() {
|
|
7
|
+
const colorterm = process.env.COLORTERM;
|
|
8
|
+
if (colorterm === "truecolor" || colorterm === "24bit") return true;
|
|
9
|
+
const term = process.env.TERM || "";
|
|
10
|
+
if (term.includes("256color") || term.includes("truecolor")) return true;
|
|
11
|
+
if (process.env.TERM_PROGRAM === "iTerm.app") return true;
|
|
12
|
+
if (process.env.TERM_PROGRAM === "vscode") return true;
|
|
13
|
+
if (process.env.WT_SESSION) return true;
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
var USE_TRUE_COLOR = supportsTrueColor();
|
|
17
|
+
var rgb = (r, g, b) => `${ESC}38;2;${r};${g};${b}m`;
|
|
18
|
+
var bgRgb = (r, g, b) => `${ESC}48;2;${r};${g};${b}m`;
|
|
19
|
+
var ansi = {
|
|
20
|
+
purple: `${ESC}35m`,
|
|
21
|
+
// magenta
|
|
22
|
+
pink: `${ESC}95m`,
|
|
23
|
+
// bright magenta
|
|
24
|
+
cyan: `${ESC}36m`,
|
|
25
|
+
// cyan
|
|
26
|
+
green: `${ESC}32m`,
|
|
27
|
+
// green
|
|
28
|
+
yellow: `${ESC}33m`,
|
|
29
|
+
// yellow
|
|
30
|
+
red: `${ESC}31m`,
|
|
31
|
+
// red
|
|
32
|
+
gray: `${ESC}90m`,
|
|
33
|
+
// bright black (gray)
|
|
34
|
+
dim: `${ESC}90m`,
|
|
35
|
+
// bright black (gray)
|
|
36
|
+
white: `${ESC}97m`
|
|
37
|
+
// bright white
|
|
38
|
+
};
|
|
39
|
+
var colors = USE_TRUE_COLOR ? {
|
|
40
|
+
purple: rgb(168, 85, 247),
|
|
41
|
+
// #a855f7
|
|
42
|
+
pink: rgb(236, 72, 153),
|
|
43
|
+
// #ec4899
|
|
44
|
+
cyan: rgb(6, 182, 212),
|
|
45
|
+
// #06b6d4
|
|
46
|
+
green: rgb(16, 185, 129),
|
|
47
|
+
// #10b981
|
|
48
|
+
yellow: rgb(234, 179, 8),
|
|
49
|
+
// #eab308
|
|
50
|
+
red: rgb(239, 68, 68),
|
|
51
|
+
// #ef4444
|
|
52
|
+
gray: rgb(107, 114, 128),
|
|
53
|
+
// #6b7280
|
|
54
|
+
dim: rgb(75, 85, 99),
|
|
55
|
+
// #4b5563
|
|
56
|
+
white: rgb(255, 255, 255)
|
|
57
|
+
} : ansi;
|
|
58
|
+
var bold = `${ESC}1m`;
|
|
59
|
+
var dim = `${ESC}2m`;
|
|
60
|
+
var cursor = {
|
|
61
|
+
hide: `${ESC}?25l`,
|
|
62
|
+
show: `${ESC}?25h`,
|
|
63
|
+
up: (n = 1) => `${ESC}${n}A`,
|
|
64
|
+
down: (n = 1) => `${ESC}${n}B`,
|
|
65
|
+
left: (n = 1) => `${ESC}${n}D`,
|
|
66
|
+
right: (n = 1) => `${ESC}${n}C`,
|
|
67
|
+
to: (x, y) => `${ESC}${y};${x}H`,
|
|
68
|
+
save: `${ESC}s`,
|
|
69
|
+
restore: `${ESC}u`
|
|
70
|
+
};
|
|
71
|
+
var clear = {
|
|
72
|
+
line: `${ESC}2K`,
|
|
73
|
+
toEnd: `${ESC}0K`,
|
|
74
|
+
screen: `${ESC}2J${ESC}0;0H`
|
|
75
|
+
};
|
|
76
|
+
function supportsUnicode() {
|
|
77
|
+
if (process.platform === "win32") {
|
|
78
|
+
if (process.env.WT_SESSION) return true;
|
|
79
|
+
if (process.env.ConEmuTask) return true;
|
|
80
|
+
if (process.env.LANG?.includes("UTF") || process.env.LC_ALL?.includes("UTF")) return true;
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
if (process.env.SQUADS_ASCII !== void 0) return false;
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
var USE_UNICODE = supportsUnicode();
|
|
87
|
+
function gradient(text) {
|
|
88
|
+
const stops = [
|
|
89
|
+
[168, 85, 247],
|
|
90
|
+
// purple
|
|
91
|
+
[192, 132, 252],
|
|
92
|
+
// purple-light
|
|
93
|
+
[232, 121, 249],
|
|
94
|
+
// pink
|
|
95
|
+
[244, 114, 182],
|
|
96
|
+
// pink-light
|
|
97
|
+
[251, 113, 133]
|
|
98
|
+
// rose
|
|
99
|
+
];
|
|
100
|
+
let result = "";
|
|
101
|
+
for (let i = 0; i < text.length; i++) {
|
|
102
|
+
const t = i / Math.max(text.length - 1, 1);
|
|
103
|
+
const stopIndex = t * (stops.length - 1);
|
|
104
|
+
const lower = Math.floor(stopIndex);
|
|
105
|
+
const upper = Math.min(lower + 1, stops.length - 1);
|
|
106
|
+
const blend = stopIndex - lower;
|
|
107
|
+
const r = Math.round(stops[lower][0] + (stops[upper][0] - stops[lower][0]) * blend);
|
|
108
|
+
const g = Math.round(stops[lower][1] + (stops[upper][1] - stops[lower][1]) * blend);
|
|
109
|
+
const b = Math.round(stops[lower][2] + (stops[upper][2] - stops[lower][2]) * blend);
|
|
110
|
+
result += rgb(r, g, b) + text[i];
|
|
111
|
+
}
|
|
112
|
+
return result + RESET;
|
|
113
|
+
}
|
|
114
|
+
var BAR_FILLED = USE_UNICODE ? "\u2501" : "=";
|
|
115
|
+
var BAR_EMPTY = USE_UNICODE ? "\u2501" : "-";
|
|
116
|
+
function progressBar(percent, width = 20) {
|
|
117
|
+
const clampedPercent = Math.max(0, Math.min(100, percent || 0));
|
|
118
|
+
const filled = Math.round(clampedPercent / 100 * width);
|
|
119
|
+
const empty = Math.max(0, width - filled);
|
|
120
|
+
let bar = "";
|
|
121
|
+
for (let i = 0; i < filled; i++) {
|
|
122
|
+
const t = i / Math.max(filled - 1, 1);
|
|
123
|
+
const r = Math.round(16 + (168 - 16) * t);
|
|
124
|
+
const g = Math.round(185 + (85 - 185) * t);
|
|
125
|
+
const b = Math.round(129 + (247 - 129) * t);
|
|
126
|
+
bar += rgb(r, g, b) + BAR_FILLED;
|
|
127
|
+
}
|
|
128
|
+
bar += colors.dim + BAR_EMPTY.repeat(empty) + RESET;
|
|
129
|
+
return bar;
|
|
130
|
+
}
|
|
131
|
+
var box = USE_UNICODE ? {
|
|
132
|
+
topLeft: "\u250C",
|
|
133
|
+
topRight: "\u2510",
|
|
134
|
+
bottomLeft: "\u2514",
|
|
135
|
+
bottomRight: "\u2518",
|
|
136
|
+
horizontal: "\u2500",
|
|
137
|
+
vertical: "\u2502",
|
|
138
|
+
teeRight: "\u251C",
|
|
139
|
+
teeLeft: "\u2524"
|
|
140
|
+
} : {
|
|
141
|
+
topLeft: "+",
|
|
142
|
+
topRight: "+",
|
|
143
|
+
bottomLeft: "+",
|
|
144
|
+
bottomRight: "+",
|
|
145
|
+
horizontal: "-",
|
|
146
|
+
vertical: "|",
|
|
147
|
+
teeRight: "+",
|
|
148
|
+
teeLeft: "+"
|
|
149
|
+
};
|
|
150
|
+
function padEnd(str, len) {
|
|
151
|
+
const visible = str.replace(/\x1b\[[0-9;]*m/g, "");
|
|
152
|
+
const pad = Math.max(0, len - visible.length);
|
|
153
|
+
return str + " ".repeat(pad);
|
|
154
|
+
}
|
|
155
|
+
function truncate(str, len) {
|
|
156
|
+
const visible = str.replace(/\x1b\[[0-9;]*m/g, "");
|
|
157
|
+
if (visible.length <= len) return str;
|
|
158
|
+
let result = "";
|
|
159
|
+
let count = 0;
|
|
160
|
+
let i = 0;
|
|
161
|
+
while (i < str.length && count < len - 1) {
|
|
162
|
+
if (str[i] === "\x1B") {
|
|
163
|
+
const end = str.indexOf("m", i);
|
|
164
|
+
if (end !== -1) {
|
|
165
|
+
result += str.slice(i, end + 1);
|
|
166
|
+
i = end + 1;
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
result += str[i];
|
|
171
|
+
count++;
|
|
172
|
+
i++;
|
|
173
|
+
}
|
|
174
|
+
return result + colors.dim + "\u2026" + RESET;
|
|
175
|
+
}
|
|
176
|
+
var spinnerFrames = USE_UNICODE ? ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"] : ["-", "\\", "|", "/"];
|
|
177
|
+
var icons = USE_UNICODE ? {
|
|
178
|
+
success: `${colors.green}\u25CF${RESET}`,
|
|
179
|
+
warning: `${colors.yellow}\u25CB${RESET}`,
|
|
180
|
+
error: `${colors.red}\u25CF${RESET}`,
|
|
181
|
+
pending: `${colors.dim}\u25CB${RESET}`,
|
|
182
|
+
active: `${colors.green}\u25CF${RESET}`,
|
|
183
|
+
running: `${colors.yellow}\u25C6${RESET}`,
|
|
184
|
+
progress: `${colors.cyan}\u25C6${RESET}`,
|
|
185
|
+
empty: `${colors.dim}\u25C7${RESET}`
|
|
186
|
+
} : {
|
|
187
|
+
success: `${colors.green}*${RESET}`,
|
|
188
|
+
warning: `${colors.yellow}!${RESET}`,
|
|
189
|
+
error: `${colors.red}x${RESET}`,
|
|
190
|
+
pending: `${colors.dim}o${RESET}`,
|
|
191
|
+
active: `${colors.green}*${RESET}`,
|
|
192
|
+
running: `${colors.yellow}>${RESET}`,
|
|
193
|
+
progress: `${colors.cyan}>${RESET}`,
|
|
194
|
+
empty: `${colors.dim}.${RESET}`
|
|
195
|
+
};
|
|
196
|
+
function stripAnsi(str) {
|
|
197
|
+
return str.replace(/\x1b\[[0-9;]*m/g, "");
|
|
198
|
+
}
|
|
199
|
+
function isAiCli() {
|
|
200
|
+
if (process.env.CLAUDECODE !== void 0) return true;
|
|
201
|
+
if (process.env.GEMINI_API_KEY !== void 0) return true;
|
|
202
|
+
if (process.env.CURSOR_CHANNEL !== void 0) return true;
|
|
203
|
+
if (process.env.CODY_AUTH !== void 0) return true;
|
|
204
|
+
if (process.env.CODEIUM_API_KEY !== void 0) return true;
|
|
205
|
+
if (process.env.GITHUB_COPILOT_CLI !== void 0) return true;
|
|
206
|
+
if (process.env.AIDER_MODEL !== void 0) return true;
|
|
207
|
+
if (process.env.CONTINUE_GLOBAL_DIR !== void 0) return true;
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
function isColorEnabled() {
|
|
211
|
+
if (process.env.NO_COLOR !== void 0) return false;
|
|
212
|
+
if (process.env.FORCE_COLOR !== void 0) return true;
|
|
213
|
+
if (isAiCli()) return true;
|
|
214
|
+
return process.stdout.isTTY ?? false;
|
|
215
|
+
}
|
|
216
|
+
function write(str) {
|
|
217
|
+
const output = isColorEnabled() ? str : stripAnsi(str);
|
|
218
|
+
process.stdout.write(output);
|
|
219
|
+
}
|
|
220
|
+
function writeLine(str = "") {
|
|
221
|
+
const output = isColorEnabled() ? str : stripAnsi(str);
|
|
222
|
+
process.stdout.write(output + "\n");
|
|
223
|
+
}
|
|
224
|
+
var SPARKLINE_BLOCKS = USE_UNICODE ? ["\u2581", "\u2582", "\u2583", "\u2584", "\u2585", "\u2586", "\u2587", "\u2588"] : ["_", ".", "-", "=", "+", "#", "#", "#"];
|
|
225
|
+
function sparkline(values, _width) {
|
|
226
|
+
if (values.length === 0) return "";
|
|
227
|
+
const max = Math.max(...values, 1);
|
|
228
|
+
let result = "";
|
|
229
|
+
for (const val of values) {
|
|
230
|
+
const normalized = val / max;
|
|
231
|
+
const blockIndex = Math.min(Math.floor(normalized * SPARKLINE_BLOCKS.length), SPARKLINE_BLOCKS.length - 1);
|
|
232
|
+
if (normalized === 0) {
|
|
233
|
+
result += colors.dim + SPARKLINE_BLOCKS[0];
|
|
234
|
+
} else if (normalized < 0.5) {
|
|
235
|
+
result += colors.cyan + SPARKLINE_BLOCKS[blockIndex];
|
|
236
|
+
} else {
|
|
237
|
+
result += colors.green + SPARKLINE_BLOCKS[blockIndex];
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return result + RESET;
|
|
241
|
+
}
|
|
242
|
+
function barChart(value, max, width = 20, label) {
|
|
243
|
+
const safeValue = Math.max(0, value || 0);
|
|
244
|
+
const safeMax = Math.max(1, max || 1);
|
|
245
|
+
const ratio = Math.min(1, safeValue / safeMax);
|
|
246
|
+
const filled = Math.round(ratio * width);
|
|
247
|
+
const empty = width - filled;
|
|
248
|
+
let bar = "";
|
|
249
|
+
for (let i = 0; i < filled; i++) {
|
|
250
|
+
const t = i / Math.max(filled - 1, 1);
|
|
251
|
+
const r = Math.round(16 + (6 - 16) * t);
|
|
252
|
+
const g = Math.round(185 + (182 - 185) * t);
|
|
253
|
+
const b = Math.round(129 + (212 - 129) * t);
|
|
254
|
+
bar += rgb(r, g, b) + BAR_FILLED;
|
|
255
|
+
}
|
|
256
|
+
bar += colors.dim + BAR_EMPTY.repeat(empty) + RESET;
|
|
257
|
+
if (label) {
|
|
258
|
+
return `${bar} ${label}`;
|
|
259
|
+
}
|
|
260
|
+
return bar;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export {
|
|
264
|
+
ESC,
|
|
265
|
+
RESET,
|
|
266
|
+
rgb,
|
|
267
|
+
bgRgb,
|
|
268
|
+
colors,
|
|
269
|
+
bold,
|
|
270
|
+
dim,
|
|
271
|
+
cursor,
|
|
272
|
+
clear,
|
|
273
|
+
gradient,
|
|
274
|
+
progressBar,
|
|
275
|
+
box,
|
|
276
|
+
padEnd,
|
|
277
|
+
truncate,
|
|
278
|
+
spinnerFrames,
|
|
279
|
+
icons,
|
|
280
|
+
stripAnsi,
|
|
281
|
+
isAiCli,
|
|
282
|
+
isColorEnabled,
|
|
283
|
+
write,
|
|
284
|
+
writeLine,
|
|
285
|
+
sparkline,
|
|
286
|
+
barChart
|
|
287
|
+
};
|
|
288
|
+
//# sourceMappingURL=chunk-NA3IECJA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/terminal.ts"],"sourcesContent":["// Terminal utilities - Bun-style approach\n// Raw ANSI for performance, no heavy deps\n\n// ANSI escape codes\nexport const ESC = '\\x1b[';\nexport const RESET = `${ESC}0m`;\n\n// Detect true color support\nfunction supportsTrueColor(): boolean {\n const colorterm = process.env.COLORTERM;\n if (colorterm === 'truecolor' || colorterm === '24bit') return true;\n const term = process.env.TERM || '';\n if (term.includes('256color') || term.includes('truecolor')) return true;\n // iTerm2, VS Code, modern terminals\n if (process.env.TERM_PROGRAM === 'iTerm.app') return true;\n if (process.env.TERM_PROGRAM === 'vscode') return true;\n if (process.env.WT_SESSION) return true; // Windows Terminal\n return false;\n}\n\nconst USE_TRUE_COLOR = supportsTrueColor();\n\n// Colors - use 24-bit RGB if supported, fallback to basic ANSI\nexport const rgb = (r: number, g: number, b: number) => `${ESC}38;2;${r};${g};${b}m`;\nexport const bgRgb = (r: number, g: number, b: number) => `${ESC}48;2;${r};${g};${b}m`;\n\n// Basic ANSI color codes (work everywhere)\nconst ansi = {\n purple: `${ESC}35m`, // magenta\n pink: `${ESC}95m`, // bright magenta\n cyan: `${ESC}36m`, // cyan\n green: `${ESC}32m`, // green\n yellow: `${ESC}33m`, // yellow\n red: `${ESC}31m`, // red\n gray: `${ESC}90m`, // bright black (gray)\n dim: `${ESC}90m`, // bright black (gray)\n white: `${ESC}97m`, // bright white\n};\n\n// Named colors (our brand palette) - with fallback\nexport const colors = USE_TRUE_COLOR ? {\n purple: rgb(168, 85, 247), // #a855f7\n pink: rgb(236, 72, 153), // #ec4899\n cyan: rgb(6, 182, 212), // #06b6d4\n green: rgb(16, 185, 129), // #10b981\n yellow: rgb(234, 179, 8), // #eab308\n red: rgb(239, 68, 68), // #ef4444\n gray: rgb(107, 114, 128), // #6b7280\n dim: rgb(75, 85, 99), // #4b5563\n white: rgb(255, 255, 255),\n} : ansi;\n\n// Styles\nexport const bold = `${ESC}1m`;\nexport const dim = `${ESC}2m`;\n\n// Cursor control\nexport const cursor = {\n hide: `${ESC}?25l`,\n show: `${ESC}?25h`,\n up: (n = 1) => `${ESC}${n}A`,\n down: (n = 1) => `${ESC}${n}B`,\n left: (n = 1) => `${ESC}${n}D`,\n right: (n = 1) => `${ESC}${n}C`,\n to: (x: number, y: number) => `${ESC}${y};${x}H`,\n save: `${ESC}s`,\n restore: `${ESC}u`,\n};\n\n// Clear\nexport const clear = {\n line: `${ESC}2K`,\n toEnd: `${ESC}0K`,\n screen: `${ESC}2J${ESC}0;0H`,\n};\n\n// Check if terminal supports Unicode\nfunction supportsUnicode(): boolean {\n // Windows CMD typically doesn't support Unicode well\n if (process.platform === 'win32') {\n // Windows Terminal supports Unicode\n if (process.env.WT_SESSION) return true;\n // ConEmu supports Unicode\n if (process.env.ConEmuTask) return true;\n // Fallback: check for UTF-8 codepage\n if (process.env.LANG?.includes('UTF') || process.env.LC_ALL?.includes('UTF')) return true;\n return false;\n }\n // Most modern terminals on macOS/Linux support Unicode\n // But AI CLIs might not render them well in their output\n // Force ASCII for known problematic environments\n if (process.env.SQUADS_ASCII !== undefined) return false;\n return true;\n}\n\nconst USE_UNICODE = supportsUnicode();\n\n// Gradient text (purple → pink → cyan)\nexport function gradient(text: string): string {\n const stops = [\n [168, 85, 247], // purple\n [192, 132, 252], // purple-light\n [232, 121, 249], // pink\n [244, 114, 182], // pink-light\n [251, 113, 133], // rose\n ];\n\n let result = '';\n for (let i = 0; i < text.length; i++) {\n const t = i / Math.max(text.length - 1, 1);\n const stopIndex = t * (stops.length - 1);\n const lower = Math.floor(stopIndex);\n const upper = Math.min(lower + 1, stops.length - 1);\n const blend = stopIndex - lower;\n\n const r = Math.round(stops[lower][0] + (stops[upper][0] - stops[lower][0]) * blend);\n const g = Math.round(stops[lower][1] + (stops[upper][1] - stops[lower][1]) * blend);\n const b = Math.round(stops[lower][2] + (stops[upper][2] - stops[lower][2]) * blend);\n\n result += rgb(r, g, b) + text[i];\n }\n return result + RESET;\n}\n\n// Progress bar characters\nconst BAR_FILLED = USE_UNICODE ? '━' : '=';\nconst BAR_EMPTY = USE_UNICODE ? '━' : '-';\n\n// Progress bar with gradient fill\nexport function progressBar(percent: number, width = 20): string {\n // Clamp values to prevent negative repeat counts\n const clampedPercent = Math.max(0, Math.min(100, percent || 0));\n const filled = Math.round((clampedPercent / 100) * width);\n const empty = Math.max(0, width - filled);\n\n let bar = '';\n for (let i = 0; i < filled; i++) {\n const t = i / Math.max(filled - 1, 1);\n const r = Math.round(16 + (168 - 16) * t);\n const g = Math.round(185 + (85 - 185) * t);\n const b = Math.round(129 + (247 - 129) * t);\n bar += rgb(r, g, b) + BAR_FILLED;\n }\n\n bar += colors.dim + BAR_EMPTY.repeat(empty) + RESET;\n return bar;\n}\n\n// Box drawing - with ASCII fallback\nexport const box = USE_UNICODE ? {\n topLeft: '┌',\n topRight: '┐',\n bottomLeft: '└',\n bottomRight: '┘',\n horizontal: '─',\n vertical: '│',\n teeRight: '├',\n teeLeft: '┤',\n} : {\n topLeft: '+',\n topRight: '+',\n bottomLeft: '+',\n bottomRight: '+',\n horizontal: '-',\n vertical: '|',\n teeRight: '+',\n teeLeft: '+',\n};\n\n// Format helpers\nexport function padEnd(str: string, len: number): string {\n // Strip ANSI codes for length calculation\n const visible = str.replace(/\\x1b\\[[0-9;]*m/g, '');\n const pad = Math.max(0, len - visible.length);\n return str + ' '.repeat(pad);\n}\n\nexport function truncate(str: string, len: number): string {\n const visible = str.replace(/\\x1b\\[[0-9;]*m/g, '');\n if (visible.length <= len) return str;\n\n // Simple truncation (won't handle mid-ANSI truncation perfectly)\n let result = '';\n let count = 0;\n let i = 0;\n\n while (i < str.length && count < len - 1) {\n if (str[i] === '\\x1b') {\n const end = str.indexOf('m', i);\n if (end !== -1) {\n result += str.slice(i, end + 1);\n i = end + 1;\n continue;\n }\n }\n result += str[i];\n count++;\n i++;\n }\n\n return result + colors.dim + '…' + RESET;\n}\n\n// Spinner frames - with ASCII fallback\nexport const spinnerFrames = USE_UNICODE\n ? ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']\n : ['-', '\\\\', '|', '/'];\n\n// Status icons - with ASCII fallback\nexport const icons = USE_UNICODE ? {\n success: `${colors.green}●${RESET}`,\n warning: `${colors.yellow}○${RESET}`,\n error: `${colors.red}●${RESET}`,\n pending: `${colors.dim}○${RESET}`,\n active: `${colors.green}●${RESET}`,\n running: `${colors.yellow}◆${RESET}`,\n progress: `${colors.cyan}◆${RESET}`,\n empty: `${colors.dim}◇${RESET}`,\n} : {\n success: `${colors.green}*${RESET}`,\n warning: `${colors.yellow}!${RESET}`,\n error: `${colors.red}x${RESET}`,\n pending: `${colors.dim}o${RESET}`,\n active: `${colors.green}*${RESET}`,\n running: `${colors.yellow}>${RESET}`,\n progress: `${colors.cyan}>${RESET}`,\n empty: `${colors.dim}.${RESET}`,\n};\n\n// Strip ANSI escape codes from a string\nexport function stripAnsi(str: string): string {\n return str.replace(/\\x1b\\[[0-9;]*m/g, '');\n}\n\n// Check if running under an AI coding assistant\nexport function isAiCli(): boolean {\n // Claude Code\n if (process.env.CLAUDECODE !== undefined) return true;\n // Gemini CLI\n if (process.env.GEMINI_API_KEY !== undefined) return true;\n // Cursor\n if (process.env.CURSOR_CHANNEL !== undefined) return true;\n // Sourcegraph Cody\n if (process.env.CODY_AUTH !== undefined) return true;\n // Windsurf (Codeium)\n if (process.env.CODEIUM_API_KEY !== undefined) return true;\n // Copilot CLI\n if (process.env.GITHUB_COPILOT_CLI !== undefined) return true;\n // Aider\n if (process.env.AIDER_MODEL !== undefined) return true;\n // Continue.dev\n if (process.env.CONTINUE_GLOBAL_DIR !== undefined) return true;\n return false;\n}\n\n// Check if we should use colors (TTY detection)\nexport function isColorEnabled(): boolean {\n // NO_COLOR environment variable (standard: https://no-color.org/)\n if (process.env.NO_COLOR !== undefined) return false;\n // Force color via environment variable\n if (process.env.FORCE_COLOR !== undefined) return true;\n // AI coding assistants - enable colors (they support ANSI)\n if (isAiCli()) return true;\n // Check if output is a TTY\n return process.stdout.isTTY ?? false;\n}\n\n// Write without newline (strips ANSI codes when piped)\nexport function write(str: string): void {\n const output = isColorEnabled() ? str : stripAnsi(str);\n process.stdout.write(output);\n}\n\n// Write line (strips ANSI codes when piped)\nexport function writeLine(str = ''): void {\n const output = isColorEnabled() ? str : stripAnsi(str);\n process.stdout.write(output + '\\n');\n}\n\n// Sparkline characters - Unicode blocks vs ASCII\nconst SPARKLINE_BLOCKS = USE_UNICODE\n ? ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█']\n : ['_', '.', '-', '=', '+', '#', '#', '#'];\n\n// Sparkline chart using block characters\nexport function sparkline(values: number[], _width?: number): string {\n if (values.length === 0) return '';\n\n const max = Math.max(...values, 1);\n\n let result = '';\n for (const val of values) {\n const normalized = val / max;\n const blockIndex = Math.min(Math.floor(normalized * SPARKLINE_BLOCKS.length), SPARKLINE_BLOCKS.length - 1);\n\n // Color gradient from dim to cyan to green based on value\n if (normalized === 0) {\n result += colors.dim + SPARKLINE_BLOCKS[0];\n } else if (normalized < 0.5) {\n result += colors.cyan + SPARKLINE_BLOCKS[blockIndex];\n } else {\n result += colors.green + SPARKLINE_BLOCKS[blockIndex];\n }\n }\n\n return result + RESET;\n}\n\n// Bar chart (horizontal)\nexport function barChart(value: number, max: number, width: number = 20, label?: string): string {\n // Guard against invalid inputs to prevent crashes\n const safeValue = Math.max(0, value || 0);\n const safeMax = Math.max(1, max || 1); // Prevent division by zero\n const ratio = Math.min(1, safeValue / safeMax); // Clamp ratio to 0-1\n const filled = Math.round(ratio * width);\n const empty = width - filled;\n\n let bar = '';\n for (let i = 0; i < filled; i++) {\n const t = i / Math.max(filled - 1, 1);\n // Green to cyan gradient\n const r = Math.round(16 + (6 - 16) * t);\n const g = Math.round(185 + (182 - 185) * t);\n const b = Math.round(129 + (212 - 129) * t);\n bar += rgb(r, g, b) + BAR_FILLED;\n }\n\n bar += colors.dim + BAR_EMPTY.repeat(empty) + RESET;\n\n if (label) {\n return `${bar} ${label}`;\n }\n return bar;\n}\n"],"mappings":"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","names":[]}
|