@agentuity/cli 0.0.106 → 0.0.108
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/cmd/build/entry-generator.d.ts.map +1 -1
- package/dist/cmd/build/entry-generator.js +43 -50
- package/dist/cmd/build/entry-generator.js.map +1 -1
- package/dist/cmd/build/index.d.ts.map +1 -1
- package/dist/cmd/build/index.js +9 -9
- package/dist/cmd/build/index.js.map +1 -1
- package/dist/cmd/build/typecheck.d.ts +23 -0
- package/dist/cmd/build/typecheck.d.ts.map +1 -0
- package/dist/cmd/build/typecheck.js +38 -0
- package/dist/cmd/build/typecheck.js.map +1 -0
- package/dist/cmd/build/vite/metadata-generator.d.ts +2 -1
- package/dist/cmd/build/vite/metadata-generator.d.ts.map +1 -1
- package/dist/cmd/build/vite/metadata-generator.js +14 -0
- package/dist/cmd/build/vite/metadata-generator.js.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server-config.d.ts.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server-config.js +15 -8
- package/dist/cmd/build/vite/vite-asset-server-config.js.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server.d.ts.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server.js +6 -2
- package/dist/cmd/build/vite/vite-asset-server.js.map +1 -1
- package/dist/cmd/build/vite/vite-builder.d.ts +2 -1
- package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -1
- package/dist/cmd/build/vite/vite-builder.js +15 -2
- package/dist/cmd/build/vite/vite-builder.js.map +1 -1
- package/dist/cmd/build/vite-bundler.d.ts +2 -1
- package/dist/cmd/build/vite-bundler.d.ts.map +1 -1
- package/dist/cmd/build/vite-bundler.js +2 -1
- package/dist/cmd/build/vite-bundler.js.map +1 -1
- package/dist/cmd/cloud/deploy.d.ts.map +1 -1
- package/dist/cmd/cloud/deploy.js +50 -24
- package/dist/cmd/cloud/deploy.js.map +1 -1
- package/dist/cmd/dev/index.d.ts.map +1 -1
- package/dist/cmd/dev/index.js +623 -578
- package/dist/cmd/dev/index.js.map +1 -1
- package/dist/schema-parser.d.ts.map +1 -1
- package/dist/schema-parser.js +17 -3
- package/dist/schema-parser.js.map +1 -1
- package/dist/tsc-output-parser.d.ts +54 -0
- package/dist/tsc-output-parser.d.ts.map +1 -0
- package/dist/tsc-output-parser.js +926 -0
- package/dist/tsc-output-parser.js.map +1 -0
- package/dist/tui.d.ts +77 -0
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +27 -2
- package/dist/tui.js.map +1 -1
- package/dist/types.d.ts +24 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +22 -0
- package/dist/types.js.map +1 -1
- package/dist/typescript-errors.d.ts +26 -0
- package/dist/typescript-errors.d.ts.map +1 -0
- package/dist/typescript-errors.js +249 -0
- package/dist/typescript-errors.js.map +1 -0
- package/package.json +4 -4
- package/src/cmd/build/entry-generator.ts +43 -51
- package/src/cmd/build/index.ts +13 -10
- package/src/cmd/build/typecheck.ts +55 -0
- package/src/cmd/build/vite/metadata-generator.ts +17 -1
- package/src/cmd/build/vite/vite-asset-server-config.ts +17 -8
- package/src/cmd/build/vite/vite-asset-server.ts +6 -2
- package/src/cmd/build/vite/vite-builder.ts +16 -3
- package/src/cmd/build/vite-bundler.ts +4 -1
- package/src/cmd/cloud/deploy.ts +68 -32
- package/src/cmd/dev/index.ts +713 -657
- package/src/schema-parser.ts +17 -3
- package/src/tsc-output-parser.ts +1115 -0
- package/src/tui.ts +40 -2
- package/src/types.ts +25 -0
- package/src/typescript-errors.ts +382 -0
- package/dist/schemas/deploy.d.ts +0 -24
- package/dist/schemas/deploy.d.ts.map +0 -1
- package/dist/schemas/deploy.js +0 -26
- package/dist/schemas/deploy.js.map +0 -1
- package/src/schemas/deploy.ts +0 -28
package/src/tui.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* Uses Bun's built-in color support and ANSI escape codes.
|
|
6
6
|
*/
|
|
7
7
|
import { stringWidth } from 'bun';
|
|
8
|
+
import { resolve } from 'node:path';
|
|
8
9
|
import { colorize } from 'json-colorizer';
|
|
9
10
|
import enquirer from 'enquirer';
|
|
10
11
|
import { type OrganizationList, projectList } from '@agentuity/server';
|
|
@@ -135,7 +136,7 @@ export function isDarkMode(): boolean {
|
|
|
135
136
|
return currentColorScheme === 'dark';
|
|
136
137
|
}
|
|
137
138
|
|
|
138
|
-
function getColor(colorKey: keyof ReturnType<typeof getColors>): string {
|
|
139
|
+
export function getColor(colorKey: keyof ReturnType<typeof getColors>): string {
|
|
139
140
|
const COLORS = getColors();
|
|
140
141
|
const color = COLORS[colorKey];
|
|
141
142
|
if (typeof color === 'string') {
|
|
@@ -325,6 +326,43 @@ export function supportsHyperlinks(): boolean {
|
|
|
325
326
|
);
|
|
326
327
|
}
|
|
327
328
|
|
|
329
|
+
export function fileUrl(file: string, line?: number, col?: number): string {
|
|
330
|
+
const abs = resolve(file);
|
|
331
|
+
|
|
332
|
+
// VS Code understands both file:// and vscode://,
|
|
333
|
+
// but vscode:// allows line + column everywhere
|
|
334
|
+
let url = `vscode://file/${abs}`;
|
|
335
|
+
|
|
336
|
+
if (line != null) {
|
|
337
|
+
url += `:${line}`;
|
|
338
|
+
if (col != null) url += `:${col}`;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return url;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
export function sourceLink(
|
|
345
|
+
file: string,
|
|
346
|
+
line: number,
|
|
347
|
+
col: number,
|
|
348
|
+
display?: string,
|
|
349
|
+
color?: string
|
|
350
|
+
): string {
|
|
351
|
+
const label = `${file}:${line}:${col}`;
|
|
352
|
+
const url = fileUrl(file, line, col);
|
|
353
|
+
|
|
354
|
+
if (supportsHyperlinks()) {
|
|
355
|
+
return link(url, display ?? label, color);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Cmd/Ctrl-click fallback
|
|
359
|
+
if (color) {
|
|
360
|
+
return color + label + getColor('reset');
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
return label;
|
|
364
|
+
}
|
|
365
|
+
|
|
328
366
|
/**
|
|
329
367
|
* Print a bulleted list item
|
|
330
368
|
*/
|
|
@@ -380,7 +418,7 @@ export function stripAnsi(str: string): string {
|
|
|
380
418
|
* Truncate a string to a maximum display width, handling ANSI codes and Unicode correctly
|
|
381
419
|
* Preserves ANSI escape sequences and doesn't break multi-byte characters or grapheme clusters
|
|
382
420
|
*/
|
|
383
|
-
function truncateToWidth(str: string, maxWidth: number, ellipsis = '...'): string {
|
|
421
|
+
export function truncateToWidth(str: string, maxWidth: number, ellipsis = '...'): string {
|
|
384
422
|
const totalWidth = getDisplayWidth(str);
|
|
385
423
|
if (totalWidth <= maxWidth) {
|
|
386
424
|
return str;
|
package/src/types.ts
CHANGED
|
@@ -559,3 +559,28 @@ export const ProjectSchema = zod.object({
|
|
|
559
559
|
export const BuildMetadataSchema = ServerBuildMetadataSchema;
|
|
560
560
|
export type BuildMetadata = zod.infer<typeof BuildMetadataSchema>;
|
|
561
561
|
export type Project = zod.infer<typeof ProjectSchema>;
|
|
562
|
+
|
|
563
|
+
export const DeployOptionsSchema = zod.object({
|
|
564
|
+
logsUrl: zod.url().optional().describe('The url to the CI build logs'),
|
|
565
|
+
trigger: zod
|
|
566
|
+
.enum(['cli', 'workflow', 'webhook'])
|
|
567
|
+
.default('cli')
|
|
568
|
+
.optional()
|
|
569
|
+
.describe('The trigger that caused the build'),
|
|
570
|
+
commitUrl: zod.url().optional().describe('The url to the CI commit'),
|
|
571
|
+
message: zod.string().optional().describe('The message to associate with this deployment'),
|
|
572
|
+
commit: zod.string().optional().describe('The commit SHA for this deployment'),
|
|
573
|
+
branch: zod.string().optional().describe('The git branch for this deployment'),
|
|
574
|
+
provider: zod.string().optional().describe('The CI provider name (attempts to autodetect)'),
|
|
575
|
+
repo: zod.string().optional().describe('The repo url'),
|
|
576
|
+
event: zod
|
|
577
|
+
.enum(['pull_request', 'push', 'manual', 'workflow'])
|
|
578
|
+
.default('manual')
|
|
579
|
+
.optional()
|
|
580
|
+
.describe('The event that triggered the deployment'),
|
|
581
|
+
pullRequestNumber: zod.number().optional().describe('the pull request number'),
|
|
582
|
+
pullRequestCommentId: zod.string().optional().describe('the pull request comment id'),
|
|
583
|
+
pullRequestURL: zod.url().optional().describe('the pull request url'),
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
export type DeployOptions = z.infer<typeof DeployOptionsSchema>;
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rust-style TypeScript error formatting
|
|
3
|
+
*
|
|
4
|
+
* Formats TypeScript compiler errors in a style similar to Rust's compiler output,
|
|
5
|
+
* with source code context, error highlighting, and helpful formatting.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
import type { GrammarItem } from './tsc-output-parser';
|
|
10
|
+
import {
|
|
11
|
+
colorError,
|
|
12
|
+
colorPrimary,
|
|
13
|
+
colorInfo,
|
|
14
|
+
colorMuted,
|
|
15
|
+
bold,
|
|
16
|
+
link,
|
|
17
|
+
getDisplayWidth,
|
|
18
|
+
getColor,
|
|
19
|
+
plural,
|
|
20
|
+
sourceLink,
|
|
21
|
+
truncateToWidth,
|
|
22
|
+
} from './tui';
|
|
23
|
+
import { symbols } from './tui/symbols';
|
|
24
|
+
|
|
25
|
+
interface TypeScriptError {
|
|
26
|
+
path: string;
|
|
27
|
+
line: number;
|
|
28
|
+
col: number;
|
|
29
|
+
errorCode: string;
|
|
30
|
+
message: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interface ErrorCodeLine {
|
|
34
|
+
content: string;
|
|
35
|
+
rawWidth: number;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface PreparedError {
|
|
39
|
+
error: TypeScriptError;
|
|
40
|
+
header: string;
|
|
41
|
+
location: string;
|
|
42
|
+
codeLines: ErrorCodeLine[];
|
|
43
|
+
maxContentWidth: number;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Check if a GrammarItem is a TypeScript error (not a warning or other diagnostic)
|
|
48
|
+
*/
|
|
49
|
+
function isTsErrorItem(item: GrammarItem): boolean {
|
|
50
|
+
return item.type === 'Item' && item.value?.tsError?.value?.type === 'error';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Parse GrammarItem array into structured TypeScript errors
|
|
55
|
+
*/
|
|
56
|
+
function parseErrors(items: GrammarItem[]): TypeScriptError[] {
|
|
57
|
+
const errors: TypeScriptError[] = [];
|
|
58
|
+
|
|
59
|
+
for (const item of items) {
|
|
60
|
+
if (!isTsErrorItem(item) || !item.value) continue;
|
|
61
|
+
|
|
62
|
+
const val = item.value;
|
|
63
|
+
errors.push({
|
|
64
|
+
path: val.path?.value ?? 'unknown',
|
|
65
|
+
line: val.cursor?.value?.line ?? 0,
|
|
66
|
+
col: val.cursor?.value?.col ?? 0,
|
|
67
|
+
errorCode: val.tsError?.value?.errorString ?? 'TS0000',
|
|
68
|
+
message: (val.message?.value ?? '').trim(),
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return errors;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
interface SourceContext {
|
|
76
|
+
before: string | null;
|
|
77
|
+
beforeLineNum: number;
|
|
78
|
+
current: string;
|
|
79
|
+
after: string | null;
|
|
80
|
+
afterLineNum: number;
|
|
81
|
+
total: number;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Read source lines with context (line before, current, line after)
|
|
86
|
+
*/
|
|
87
|
+
async function getSourceContext(
|
|
88
|
+
filePath: string,
|
|
89
|
+
lineNumber: number
|
|
90
|
+
): Promise<SourceContext | null> {
|
|
91
|
+
try {
|
|
92
|
+
const file = Bun.file(filePath);
|
|
93
|
+
if (!(await file.exists())) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
const content = await file.text();
|
|
97
|
+
const lines = content.split('\n');
|
|
98
|
+
if (lineNumber <= 0 || lineNumber > lines.length) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const current = lines[lineNumber - 1];
|
|
103
|
+
const before = lineNumber > 1 ? lines[lineNumber - 2] : null;
|
|
104
|
+
const after = lineNumber < lines.length ? lines[lineNumber] : null;
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
before: before !== null && before.trim() !== '' ? before : null,
|
|
108
|
+
beforeLineNum: lineNumber - 1,
|
|
109
|
+
current,
|
|
110
|
+
after: after !== null && after.trim() !== '' ? after : null,
|
|
111
|
+
afterLineNum: lineNumber + 1,
|
|
112
|
+
total: lines.length,
|
|
113
|
+
};
|
|
114
|
+
} catch {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Prepare error data without rendering (first pass)
|
|
121
|
+
*/
|
|
122
|
+
async function prepareError(
|
|
123
|
+
error: TypeScriptError,
|
|
124
|
+
projectDir: string,
|
|
125
|
+
maxAvailableWidth: number
|
|
126
|
+
): Promise<PreparedError> {
|
|
127
|
+
const fullPath = error.path.startsWith('/') ? error.path : `${projectDir}/${error.path}`;
|
|
128
|
+
|
|
129
|
+
// Error header
|
|
130
|
+
const url = link(
|
|
131
|
+
`https://typescript.tv/errors/#${error.errorCode}`,
|
|
132
|
+
`error[${error.errorCode}]`,
|
|
133
|
+
getColor('error')
|
|
134
|
+
);
|
|
135
|
+
const header = ' ' + url + colorMuted(': ') + bold(error.message);
|
|
136
|
+
|
|
137
|
+
// File location
|
|
138
|
+
const vscodelink = sourceLink(
|
|
139
|
+
join(projectDir, error.path),
|
|
140
|
+
error.line,
|
|
141
|
+
error.col,
|
|
142
|
+
`${error.path}:${error.line}:${error.col}`,
|
|
143
|
+
getColor('info')
|
|
144
|
+
);
|
|
145
|
+
const location = colorInfo(` ${vscodelink}`);
|
|
146
|
+
|
|
147
|
+
const codeLines: ErrorCodeLine[] = [];
|
|
148
|
+
|
|
149
|
+
// Get source code context
|
|
150
|
+
const context = await getSourceContext(fullPath, error.line);
|
|
151
|
+
|
|
152
|
+
if (context !== null) {
|
|
153
|
+
const maxLineNum = Math.max(
|
|
154
|
+
context.before !== null ? context.beforeLineNum : error.line,
|
|
155
|
+
error.line,
|
|
156
|
+
context.after !== null ? context.afterLineNum : error.line
|
|
157
|
+
);
|
|
158
|
+
const lineNumWidth = String(maxLineNum).length;
|
|
159
|
+
const formatLineNum = (num: number) => String(num).padStart(lineNumWidth);
|
|
160
|
+
const padding = ' '.repeat(lineNumWidth);
|
|
161
|
+
const linePrefix = lineNumWidth + 3;
|
|
162
|
+
|
|
163
|
+
const truncateCodeLine = (lineNum: string, separator: string, code: string): string => {
|
|
164
|
+
const prefixWidth = getDisplayWidth(lineNum) + getDisplayWidth(separator) + 1;
|
|
165
|
+
const availableForCode = maxAvailableWidth - prefixWidth;
|
|
166
|
+
if (availableForCode > 10 && getDisplayWidth(code) > availableForCode) {
|
|
167
|
+
return `${lineNum}${separator} ${truncateToWidth(code, availableForCode, '…')}`;
|
|
168
|
+
}
|
|
169
|
+
return `${lineNum}${separator} ${code}`;
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
if (context.beforeLineNum > 1) {
|
|
173
|
+
const dots = '.'.repeat(String(context.beforeLineNum).length);
|
|
174
|
+
const content = colorMuted(`${dots} ${symbols.bar}`);
|
|
175
|
+
codeLines.push({ content, rawWidth: getDisplayWidth(content) });
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Context line before (muted)
|
|
179
|
+
if (context.before !== null) {
|
|
180
|
+
const lineContent = truncateCodeLine(
|
|
181
|
+
formatLineNum(context.beforeLineNum),
|
|
182
|
+
` ${symbols.bar}`,
|
|
183
|
+
context.before
|
|
184
|
+
);
|
|
185
|
+
const content = colorMuted(lineContent);
|
|
186
|
+
codeLines.push({ content, rawWidth: getDisplayWidth(content) });
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Error line (primary color)
|
|
190
|
+
const truncatedCurrent =
|
|
191
|
+
getDisplayWidth(context.current) > maxAvailableWidth - linePrefix
|
|
192
|
+
? truncateToWidth(context.current, maxAvailableWidth - linePrefix, '…')
|
|
193
|
+
: context.current;
|
|
194
|
+
const errorLineContent = `${colorInfo(formatLineNum(error.line))} ${colorMuted(symbols.bar)} ${colorPrimary(truncatedCurrent)}`;
|
|
195
|
+
codeLines.push({ content: errorLineContent, rawWidth: getDisplayWidth(errorLineContent) });
|
|
196
|
+
|
|
197
|
+
// Error pointer line with carets
|
|
198
|
+
const col = Math.max(0, error.col - 1);
|
|
199
|
+
let underlineLength = 1;
|
|
200
|
+
const restOfLine = context.current.slice(col);
|
|
201
|
+
const identifierMatch = restOfLine.match(/^[a-zA-Z_$][a-zA-Z0-9_$]*/);
|
|
202
|
+
if (identifierMatch) {
|
|
203
|
+
underlineLength = identifierMatch[0].length;
|
|
204
|
+
} else {
|
|
205
|
+
const tokenMatch = restOfLine.match(/^\S+/);
|
|
206
|
+
if (tokenMatch) {
|
|
207
|
+
underlineLength = Math.min(tokenMatch[0].length, 20);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const maxCaretWidth = maxAvailableWidth - linePrefix;
|
|
212
|
+
const caretStart = Math.min(col, maxCaretWidth - 1);
|
|
213
|
+
const caretLen = Math.min(underlineLength, maxCaretWidth - caretStart);
|
|
214
|
+
const carets = caretLen > 0 ? '^'.repeat(caretLen) : '^';
|
|
215
|
+
const caretPadding = ' '.repeat(caretStart);
|
|
216
|
+
const caretLine = `${padding} ${colorMuted(symbols.bar)} ${caretPadding}${colorError(carets)}`;
|
|
217
|
+
codeLines.push({ content: caretLine, rawWidth: getDisplayWidth(caretLine) });
|
|
218
|
+
|
|
219
|
+
// Context line after (muted)
|
|
220
|
+
if (context.after !== null) {
|
|
221
|
+
const lineContent = truncateCodeLine(
|
|
222
|
+
formatLineNum(context.afterLineNum),
|
|
223
|
+
` ${symbols.bar}`,
|
|
224
|
+
context.after
|
|
225
|
+
);
|
|
226
|
+
const content = colorMuted(lineContent);
|
|
227
|
+
codeLines.push({ content, rawWidth: getDisplayWidth(content) });
|
|
228
|
+
}
|
|
229
|
+
if (context.afterLineNum + 1 < context.total) {
|
|
230
|
+
const dots = '.'.repeat(String(context.afterLineNum).length);
|
|
231
|
+
const content = colorMuted(`${dots} ${symbols.bar}`);
|
|
232
|
+
codeLines.push({ content, rawWidth: getDisplayWidth(content) });
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const maxContentWidth = codeLines.length > 0 ? Math.max(...codeLines.map((l) => l.rawWidth)) : 0;
|
|
237
|
+
|
|
238
|
+
return {
|
|
239
|
+
error,
|
|
240
|
+
header,
|
|
241
|
+
location,
|
|
242
|
+
codeLines,
|
|
243
|
+
maxContentWidth,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Render a prepared error with a specific box width
|
|
249
|
+
*/
|
|
250
|
+
function renderError(prepared: PreparedError, boxContentWidth: number): string {
|
|
251
|
+
const lines: string[] = [];
|
|
252
|
+
|
|
253
|
+
lines.push(prepared.header);
|
|
254
|
+
lines.push(prepared.location);
|
|
255
|
+
|
|
256
|
+
if (prepared.codeLines.length > 0) {
|
|
257
|
+
const boxWidth = boxContentWidth + 2;
|
|
258
|
+
|
|
259
|
+
// Draw box
|
|
260
|
+
lines.push(
|
|
261
|
+
colorMuted(` ${symbols.cornerTL}${symbols.barH.repeat(boxWidth)}${symbols.cornerTR}`)
|
|
262
|
+
);
|
|
263
|
+
for (const codeLine of prepared.codeLines) {
|
|
264
|
+
const rightPad = ' '.repeat(Math.max(0, boxContentWidth - codeLine.rawWidth));
|
|
265
|
+
lines.push(
|
|
266
|
+
colorMuted(` ${symbols.bar}`) +
|
|
267
|
+
` ${codeLine.content}${rightPad} ` +
|
|
268
|
+
colorMuted(symbols.bar)
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
lines.push(
|
|
272
|
+
colorMuted(` ${symbols.cornerBL}${symbols.barH.repeat(boxWidth)}${symbols.cornerBR}`)
|
|
273
|
+
);
|
|
274
|
+
} else {
|
|
275
|
+
lines.push(colorMuted(' (source not available)'));
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return lines.join('\n') + '\n';
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Group errors by file for better organization
|
|
283
|
+
*/
|
|
284
|
+
function groupErrorsByFile(errors: TypeScriptError[]): Map<string, TypeScriptError[]> {
|
|
285
|
+
const grouped = new Map<string, TypeScriptError[]>();
|
|
286
|
+
|
|
287
|
+
for (const error of errors) {
|
|
288
|
+
const existing = grouped.get(error.path) ?? [];
|
|
289
|
+
existing.push(error);
|
|
290
|
+
grouped.set(error.path, existing);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
for (const errors of grouped.values()) {
|
|
294
|
+
errors.sort((a, b) => a.line - b.line || a.col - b.col);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return grouped;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export interface FormatOptions {
|
|
301
|
+
/** Project directory for resolving relative paths */
|
|
302
|
+
projectDir: string;
|
|
303
|
+
/** Maximum number of errors to display (default: all) */
|
|
304
|
+
maxErrors?: number;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Format TypeScript errors in Rust-style output
|
|
309
|
+
*/
|
|
310
|
+
export async function formatTypeScriptErrors(
|
|
311
|
+
items: GrammarItem[],
|
|
312
|
+
options: FormatOptions
|
|
313
|
+
): Promise<string> {
|
|
314
|
+
const errors = parseErrors(items);
|
|
315
|
+
|
|
316
|
+
if (errors.length === 0) {
|
|
317
|
+
return '';
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Calculate terminal constraints
|
|
321
|
+
const terminalWidth = process.stdout.columns || 80;
|
|
322
|
+
const boxChrome = 6;
|
|
323
|
+
const maxAvailableWidth = terminalWidth - boxChrome;
|
|
324
|
+
|
|
325
|
+
// First pass: prepare all errors and collect their widths
|
|
326
|
+
const groupedErrors = groupErrorsByFile(errors);
|
|
327
|
+
const maxErrors = options.maxErrors ?? errors.length;
|
|
328
|
+
const preparedErrors: PreparedError[] = [];
|
|
329
|
+
|
|
330
|
+
let displayedCount = 0;
|
|
331
|
+
for (const [, fileErrors] of groupedErrors) {
|
|
332
|
+
for (const error of fileErrors) {
|
|
333
|
+
if (displayedCount >= maxErrors) break;
|
|
334
|
+
|
|
335
|
+
const prepared = await prepareError(error, options.projectDir, maxAvailableWidth);
|
|
336
|
+
preparedErrors.push(prepared);
|
|
337
|
+
displayedCount++;
|
|
338
|
+
}
|
|
339
|
+
if (displayedCount >= maxErrors) break;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Calculate uniform box width (max content width across all errors, capped at terminal width)
|
|
343
|
+
const globalMaxContentWidth = Math.max(...preparedErrors.map((p) => p.maxContentWidth));
|
|
344
|
+
const uniformBoxContentWidth = Math.min(globalMaxContentWidth, maxAvailableWidth);
|
|
345
|
+
|
|
346
|
+
// Second pass: render all errors with uniform width
|
|
347
|
+
const output: string[] = [];
|
|
348
|
+
for (const prepared of preparedErrors) {
|
|
349
|
+
output.push(renderError(prepared, uniformBoxContentWidth));
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Summary line
|
|
353
|
+
const totalErrors = errors.length;
|
|
354
|
+
const hiddenCount = totalErrors - displayedCount;
|
|
355
|
+
|
|
356
|
+
let msg = bold(
|
|
357
|
+
colorPrimary(
|
|
358
|
+
`aborting due to ${totalErrors} TypeScript compiler ${plural(totalErrors, 'error', 'errors')}`
|
|
359
|
+
)
|
|
360
|
+
);
|
|
361
|
+
|
|
362
|
+
if (hiddenCount > 0) {
|
|
363
|
+
msg += colorMuted(` (${hiddenCount} not shown)`);
|
|
364
|
+
}
|
|
365
|
+
output.push(`${bold(colorError('error'))}: ${msg}`);
|
|
366
|
+
|
|
367
|
+
return output.join('\n');
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Check if the parsed result contains any errors
|
|
372
|
+
*/
|
|
373
|
+
export function hasErrors(items: GrammarItem[]): boolean {
|
|
374
|
+
return items.some(isTsErrorItem);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Get the count of errors
|
|
379
|
+
*/
|
|
380
|
+
export function getErrorCount(items: GrammarItem[]): number {
|
|
381
|
+
return items.filter(isTsErrorItem).length;
|
|
382
|
+
}
|
package/dist/schemas/deploy.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
export declare const DeployOptionsSchema: z.ZodObject<{
|
|
3
|
-
tag: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodString>>>;
|
|
4
|
-
logsUrl: z.ZodOptional<z.ZodURL>;
|
|
5
|
-
trigger: z.ZodOptional<z.ZodDefault<z.ZodEnum<{
|
|
6
|
-
cli: "cli";
|
|
7
|
-
workflow: "workflow";
|
|
8
|
-
webhook: "webhook";
|
|
9
|
-
}>>>;
|
|
10
|
-
commitUrl: z.ZodOptional<z.ZodURL>;
|
|
11
|
-
message: z.ZodOptional<z.ZodString>;
|
|
12
|
-
provider: z.ZodOptional<z.ZodString>;
|
|
13
|
-
event: z.ZodOptional<z.ZodDefault<z.ZodEnum<{
|
|
14
|
-
push: "push";
|
|
15
|
-
pull_request: "pull_request";
|
|
16
|
-
manual: "manual";
|
|
17
|
-
workflow: "workflow";
|
|
18
|
-
}>>>;
|
|
19
|
-
pullRequestNumber: z.ZodOptional<z.ZodNumber>;
|
|
20
|
-
pullRequestCommentId: z.ZodOptional<z.ZodString>;
|
|
21
|
-
pullRequestURL: z.ZodOptional<z.ZodURL>;
|
|
22
|
-
}, z.core.$strip>;
|
|
23
|
-
export type DeployOptions = z.infer<typeof DeployOptionsSchema>;
|
|
24
|
-
//# sourceMappingURL=deploy.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/schemas/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;iBAuB9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
|
package/dist/schemas/deploy.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
export const DeployOptionsSchema = z.object({
|
|
3
|
-
tag: z
|
|
4
|
-
.array(z.string())
|
|
5
|
-
.default(['latest'])
|
|
6
|
-
.optional()
|
|
7
|
-
.describe('One or more tags to add to the deployment'),
|
|
8
|
-
logsUrl: z.url().optional().describe('The url to the CI build logs'),
|
|
9
|
-
trigger: z
|
|
10
|
-
.enum(['cli', 'workflow', 'webhook'])
|
|
11
|
-
.default('cli')
|
|
12
|
-
.optional()
|
|
13
|
-
.describe('The trigger that caused the build'),
|
|
14
|
-
commitUrl: z.url().optional().describe('The url to the CI commit'),
|
|
15
|
-
message: z.string().optional().describe('The message to associate with this deployment'),
|
|
16
|
-
provider: z.string().optional().describe('The CI provider name (attempts to autodetect)'),
|
|
17
|
-
event: z
|
|
18
|
-
.enum(['pull_request', 'push', 'manual', 'workflow'])
|
|
19
|
-
.default('manual')
|
|
20
|
-
.optional()
|
|
21
|
-
.describe('The event that triggered the deployment'),
|
|
22
|
-
pullRequestNumber: z.number().optional().describe('the pull request number'),
|
|
23
|
-
pullRequestCommentId: z.string().optional().describe('the pull request comment id'),
|
|
24
|
-
pullRequestURL: z.url().optional().describe('the pull request url'),
|
|
25
|
-
});
|
|
26
|
-
//# sourceMappingURL=deploy.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/schemas/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,GAAG,EAAE,CAAC;SACJ,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC;SACnB,QAAQ,EAAE;SACV,QAAQ,CAAC,2CAA2C,CAAC;IACvD,OAAO,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;IACpE,OAAO,EAAE,CAAC;SACR,IAAI,CAAC,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;SACpC,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,EAAE;SACV,QAAQ,CAAC,mCAAmC,CAAC;IAC/C,SAAS,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;IAClE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;IACxF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;IACzF,KAAK,EAAE,CAAC;SACN,IAAI,CAAC,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;SACpD,OAAO,CAAC,QAAQ,CAAC;SACjB,QAAQ,EAAE;SACV,QAAQ,CAAC,yCAAyC,CAAC;IACrD,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;IAC5E,oBAAoB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;IACnF,cAAc,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;CACnE,CAAC,CAAC"}
|
package/src/schemas/deploy.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
|
|
3
|
-
export const DeployOptionsSchema = z.object({
|
|
4
|
-
tag: z
|
|
5
|
-
.array(z.string())
|
|
6
|
-
.default(['latest'])
|
|
7
|
-
.optional()
|
|
8
|
-
.describe('One or more tags to add to the deployment'),
|
|
9
|
-
logsUrl: z.url().optional().describe('The url to the CI build logs'),
|
|
10
|
-
trigger: z
|
|
11
|
-
.enum(['cli', 'workflow', 'webhook'])
|
|
12
|
-
.default('cli')
|
|
13
|
-
.optional()
|
|
14
|
-
.describe('The trigger that caused the build'),
|
|
15
|
-
commitUrl: z.url().optional().describe('The url to the CI commit'),
|
|
16
|
-
message: z.string().optional().describe('The message to associate with this deployment'),
|
|
17
|
-
provider: z.string().optional().describe('The CI provider name (attempts to autodetect)'),
|
|
18
|
-
event: z
|
|
19
|
-
.enum(['pull_request', 'push', 'manual', 'workflow'])
|
|
20
|
-
.default('manual')
|
|
21
|
-
.optional()
|
|
22
|
-
.describe('The event that triggered the deployment'),
|
|
23
|
-
pullRequestNumber: z.number().optional().describe('the pull request number'),
|
|
24
|
-
pullRequestCommentId: z.string().optional().describe('the pull request comment id'),
|
|
25
|
-
pullRequestURL: z.url().optional().describe('the pull request url'),
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
export type DeployOptions = z.infer<typeof DeployOptionsSchema>;
|