opencode-sat 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +180 -0
  3. package/dist/sat.d.ts +4 -0
  4. package/dist/sat.d.ts.map +1 -0
  5. package/dist/sat.js +62 -0
  6. package/dist/sat.js.map +1 -0
  7. package/dist/src/append.d.ts +23 -0
  8. package/dist/src/append.d.ts.map +1 -0
  9. package/dist/src/append.js +57 -0
  10. package/dist/src/append.js.map +1 -0
  11. package/dist/src/discover.d.ts +11 -0
  12. package/dist/src/discover.d.ts.map +1 -0
  13. package/dist/src/discover.js +98 -0
  14. package/dist/src/discover.js.map +1 -0
  15. package/dist/src/format-prompt.d.ts +3 -0
  16. package/dist/src/format-prompt.d.ts.map +1 -0
  17. package/dist/src/format-prompt.js +92 -0
  18. package/dist/src/format-prompt.js.map +1 -0
  19. package/dist/src/opencode/notify.d.ts +10 -0
  20. package/dist/src/opencode/notify.d.ts.map +1 -0
  21. package/dist/src/opencode/notify.js +14 -0
  22. package/dist/src/opencode/notify.js.map +1 -0
  23. package/dist/src/process-prompt.d.ts +21 -0
  24. package/dist/src/process-prompt.d.ts.map +1 -0
  25. package/dist/src/process-prompt.js +20 -0
  26. package/dist/src/process-prompt.js.map +1 -0
  27. package/dist/src/process.d.ts +26 -0
  28. package/dist/src/process.d.ts.map +1 -0
  29. package/dist/src/process.js +56 -0
  30. package/dist/src/process.js.map +1 -0
  31. package/dist/src/prompt-prompt.d.ts +3 -0
  32. package/dist/src/prompt-prompt.d.ts.map +1 -0
  33. package/dist/src/prompt-prompt.js +47 -0
  34. package/dist/src/prompt-prompt.js.map +1 -0
  35. package/dist/src/prompt-schema.d.ts +22 -0
  36. package/dist/src/prompt-schema.d.ts.map +1 -0
  37. package/dist/src/prompt-schema.js +33 -0
  38. package/dist/src/prompt-schema.js.map +1 -0
  39. package/dist/src/prompt.d.ts +7 -0
  40. package/dist/src/prompt.d.ts.map +1 -0
  41. package/dist/src/prompt.js +84 -0
  42. package/dist/src/prompt.js.map +1 -0
  43. package/dist/src/resolve.d.ts +4 -0
  44. package/dist/src/resolve.d.ts.map +1 -0
  45. package/dist/src/resolve.js +19 -0
  46. package/dist/src/resolve.js.map +1 -0
  47. package/dist/src/rule-schema.d.ts +69 -0
  48. package/dist/src/rule-schema.d.ts.map +1 -0
  49. package/dist/src/rule-schema.js +47 -0
  50. package/dist/src/rule-schema.js.map +1 -0
  51. package/dist/src/session.d.ts +23 -0
  52. package/dist/src/session.d.ts.map +1 -0
  53. package/dist/src/session.js +112 -0
  54. package/dist/src/session.js.map +1 -0
  55. package/dist/src/tools.d.ts +59 -0
  56. package/dist/src/tools.d.ts.map +1 -0
  57. package/dist/src/tools.js +221 -0
  58. package/dist/src/tools.js.map +1 -0
  59. package/dist/src/utils/compare.d.ts +23 -0
  60. package/dist/src/utils/compare.d.ts.map +1 -0
  61. package/dist/src/utils/compare.js +116 -0
  62. package/dist/src/utils/compare.js.map +1 -0
  63. package/dist/src/utils/extractLlmError.d.ts +13 -0
  64. package/dist/src/utils/extractLlmError.d.ts.map +1 -0
  65. package/dist/src/utils/extractLlmError.js +12 -0
  66. package/dist/src/utils/extractLlmError.js.map +1 -0
  67. package/dist/src/utils/safe.d.ts +14 -0
  68. package/dist/src/utils/safe.d.ts.map +1 -0
  69. package/dist/src/utils/safe.js +31 -0
  70. package/dist/src/utils/safe.js.map +1 -0
  71. package/dist/src/utils/stripCodeFences.d.ts +2 -0
  72. package/dist/src/utils/stripCodeFences.d.ts.map +1 -0
  73. package/dist/src/utils/stripCodeFences.js +9 -0
  74. package/dist/src/utils/stripCodeFences.js.map +1 -0
  75. package/dist/src/utils/validate.d.ts +19 -0
  76. package/dist/src/utils/validate.d.ts.map +1 -0
  77. package/dist/src/utils/validate.js +30 -0
  78. package/dist/src/utils/validate.js.map +1 -0
  79. package/package.json +59 -0
@@ -0,0 +1,112 @@
1
+ import { buildRetryPrompt } from './prompt';
2
+ import { extractLlmError } from './utils/extractLlmError';
3
+ import { stripCodeFences } from './utils/stripCodeFences';
4
+ import { formatValidationError, validateJson } from './utils/validate';
5
+ const MAX_RETRIES = 3;
6
+ // runtime type guards for untyped SDK responses
7
+ const isRecord = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
8
+ const isPart = (v) => isRecord(v) && typeof v.type === 'string';
9
+ const isPartArray = (v) => Array.isArray(v) && v.every(isPart);
10
+ const isMessageInfo = (v) => isRecord(v) && typeof v.role === 'string';
11
+ const isMessageEntry = (v) => isRecord(v) && isMessageInfo(v.info) && isPartArray(v.parts);
12
+ const isMessageEntryArray = (v) => Array.isArray(v) && v.every(isMessageEntry);
13
+ // extract text content from response parts
14
+ export const extractText = (parts) => {
15
+ return parts
16
+ .filter((p) => p.type === 'text' && p.text)
17
+ .map((p) => p.text || '')
18
+ .join('');
19
+ };
20
+ // detect model from the calling session's most recent assistant message
21
+ export const detectModel = async (client, sessionId) => {
22
+ const messagesResult = await client.session.messages({ path: { id: sessionId } });
23
+ if (!messagesResult.data) {
24
+ return null;
25
+ }
26
+ const messages = messagesResult.data;
27
+ if (!isMessageEntryArray(messages)) {
28
+ return null;
29
+ }
30
+ for (let i = messages.length - 1; i >= 0; i--) {
31
+ const message = messages[i];
32
+ if (!message) {
33
+ continue;
34
+ }
35
+ const info = message.info;
36
+ if (info.role === 'assistant' && info.providerID && info.modelID) {
37
+ return {
38
+ providerID: info.providerID,
39
+ modelID: info.modelID,
40
+ };
41
+ }
42
+ }
43
+ return null;
44
+ };
45
+ // prompt the LLM and validate the response, retrying on failure
46
+ export const promptWithRetry = async (options) => {
47
+ let prompt = options.initialPrompt;
48
+ let lastError = '';
49
+ for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
50
+ const response = await options.client.session.prompt({
51
+ path: { id: options.sessionId },
52
+ body: {
53
+ parts: [{ type: 'text', text: prompt }],
54
+ tools: {},
55
+ model: options.model,
56
+ },
57
+ });
58
+ // no response data means a transport/API failure, not retryable
59
+ if (!response.data) {
60
+ return {
61
+ data: null,
62
+ error: 'No response from LLM (attempt ' + (attempt + 1) + ')',
63
+ };
64
+ }
65
+ const info = response.data.info;
66
+ if (!isMessageInfo(info)) {
67
+ return {
68
+ data: null,
69
+ error: 'Unexpected response shape: missing info (attempt ' + (attempt + 1) + ')',
70
+ };
71
+ }
72
+ const llmError = extractLlmError(info);
73
+ if (llmError) {
74
+ return {
75
+ data: null,
76
+ error: llmError,
77
+ };
78
+ }
79
+ const parts = response.data.parts;
80
+ if (!isPartArray(parts)) {
81
+ return {
82
+ data: null,
83
+ error: 'Unexpected response shape: missing parts (attempt ' + (attempt + 1) + ')',
84
+ };
85
+ }
86
+ // empty text is a model issue, retryable
87
+ const text = extractText(parts);
88
+ if (!text) {
89
+ lastError = 'Empty response';
90
+ prompt = buildRetryPrompt('Empty response. Return valid JSON.');
91
+ continue;
92
+ }
93
+ // validate against schema
94
+ const cleaned = stripCodeFences(text);
95
+ const validation = validateJson(cleaned, options.schema);
96
+ if (validation.error) {
97
+ const errorMsg = formatValidationError(validation);
98
+ lastError = errorMsg + ' | raw: ' + cleaned.slice(0, 200);
99
+ prompt = buildRetryPrompt(errorMsg);
100
+ continue;
101
+ }
102
+ return {
103
+ data: validation.data,
104
+ error: null,
105
+ };
106
+ }
107
+ return {
108
+ data: null,
109
+ error: 'Failed after ' + MAX_RETRIES + ' attempts. Last error: ' + lastError,
110
+ };
111
+ };
112
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import type { PluginInput } from '@opencode-ai/plugin';
2
+ import { type FormatMode } from './prompt.ts';
3
+ type Client = PluginInput['client'];
4
+ type ToolDeps = {
5
+ directory: string;
6
+ client: Client;
7
+ };
8
+ type RewriteToolOptions = {
9
+ description: string;
10
+ deps: ToolDeps;
11
+ };
12
+ export declare const createRewriteTool: (options: RewriteToolOptions) => {
13
+ description: string;
14
+ args: {
15
+ mode: import("zod").ZodOptional<import("zod").ZodString>;
16
+ files: import("zod").ZodOptional<import("zod").ZodString>;
17
+ };
18
+ execute(args: {
19
+ mode?: string | undefined;
20
+ files?: string | undefined;
21
+ }, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
22
+ };
23
+ type AppendToolOptions = {
24
+ description: string;
25
+ deps: ToolDeps;
26
+ toolName: string;
27
+ sessionTitle: string;
28
+ defaultMode: FormatMode;
29
+ successPrefix: string;
30
+ hasMode: boolean;
31
+ };
32
+ export declare const createAppendTool: (options: AppendToolOptions) => {
33
+ description: string;
34
+ args: {
35
+ mode?: import("zod").ZodOptional<import("zod").ZodString> | undefined;
36
+ input: import("zod").ZodString;
37
+ file: import("zod").ZodOptional<import("zod").ZodString>;
38
+ };
39
+ execute(args: {
40
+ mode?: unknown;
41
+ input: string;
42
+ file?: string | undefined;
43
+ }, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
44
+ };
45
+ type RefineToolOptions = {
46
+ description: string;
47
+ deps: ToolDeps;
48
+ };
49
+ export declare const createRefineTool: (options: RefineToolOptions) => {
50
+ description: string;
51
+ args: {
52
+ input: import("zod").ZodString;
53
+ };
54
+ execute(args: {
55
+ input: string;
56
+ }, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
57
+ };
58
+ export {};
59
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAOtD,OAAO,EAAE,KAAK,UAAU,EAAgB,MAAM,aAAa,CAAA;AAM3D,KAAK,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAA;AAEnC,KAAK,QAAQ,GAAG;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAmFD,KAAK,kBAAkB,GAAG;IACxB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,QAAQ,CAAA;CACf,CAAA;AAED,eAAO,MAAM,iBAAiB,GAAI,SAAS,kBAAkB;;;;;;;;;;CAiE5D,CAAA;AAED,KAAK,iBAAiB,GAAG;IACvB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,QAAQ,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,UAAU,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,OAAO,CAAA;CACjB,CAAA;AAED,eAAO,MAAM,gBAAgB,GAAI,SAAS,iBAAiB;;;;;;;;;;;;CA+E1D,CAAA;AAED,KAAK,iBAAiB,GAAG;IACvB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,QAAQ,CAAA;CACf,CAAA;AAED,eAAO,MAAM,gBAAgB,GAAI,SAAS,iBAAiB;;;;;;;;CA8C1D,CAAA"}
@@ -0,0 +1,221 @@
1
+ import { tool } from '@opencode-ai/plugin';
2
+ import { basename } from 'node:path';
3
+ import { appendRules } from "./append.js";
4
+ import { sendResult } from "./opencode/notify.js";
5
+ import { processFile } from "./process.js";
6
+ import { processPrompt } from "./process-prompt.js";
7
+ import { isFormatMode } from "./prompt.js";
8
+ import { resolveFiles } from "./resolve.js";
9
+ import { detectModel, promptWithRetry } from "./session.js";
10
+ import { buildTable } from "./utils/compare.js";
11
+ import { safeAsync } from "./utils/safe.js";
12
+ const ERROR_LABELS = {
13
+ readError: 'Read failed',
14
+ parseError: 'Parse failed',
15
+ formatError: 'Format failed',
16
+ writeError: 'Write failed',
17
+ };
18
+ const toTableRow = (result) => {
19
+ if (result.status === 'success') {
20
+ return {
21
+ file: basename(result.path),
22
+ status: 'Success',
23
+ rules: result.rulesCount,
24
+ comparison: result.comparison,
25
+ };
26
+ }
27
+ const label = ERROR_LABELS[result.status] || result.status;
28
+ return {
29
+ file: basename(result.path),
30
+ status: label,
31
+ };
32
+ };
33
+ const createSession = async (options) => {
34
+ const model = await detectModel(options.client, options.sessionID);
35
+ if (!model) {
36
+ return {
37
+ ok: false,
38
+ error: 'Could not detect current model. Send a message first, then call ' + options.toolName + '.',
39
+ };
40
+ }
41
+ const sessionResult = await options.client.session.create({ body: { title: options.title } });
42
+ if (!sessionResult.data) {
43
+ return {
44
+ ok: false,
45
+ error: 'Failed to create internal session',
46
+ };
47
+ }
48
+ const sessionId = sessionResult.data.id;
49
+ const prompt = (text, schema) => (promptWithRetry({
50
+ client: options.client,
51
+ sessionId,
52
+ initialPrompt: text,
53
+ schema,
54
+ model,
55
+ }));
56
+ return {
57
+ ok: true,
58
+ sessionId,
59
+ prompt,
60
+ };
61
+ };
62
+ export const createRewriteTool = (options) => {
63
+ return tool({
64
+ description: options.description,
65
+ args: {
66
+ mode: tool.schema.string().optional().describe('Output format: verbose, balanced, or concise (default: balanced)'),
67
+ files: tool.schema.string().optional().describe('Comma-separated file paths to process instead of discovering from opencode.json'),
68
+ },
69
+ async execute(args, context) {
70
+ const mode = isFormatMode(args.mode) ? args.mode : 'balanced';
71
+ try {
72
+ const resolved = await resolveFiles(options.deps.directory, args.files);
73
+ if (resolved.error !== null) {
74
+ return resolved.error;
75
+ }
76
+ const session = await createSession({
77
+ client: options.deps.client,
78
+ sessionID: context.sessionID,
79
+ title: 'SAT Rewrite',
80
+ toolName: 'rewrite-instructions',
81
+ });
82
+ if (!session.ok) {
83
+ return session.error;
84
+ }
85
+ const fileResults = [];
86
+ for (const file of resolved.data) {
87
+ if (context.abort.aborted) {
88
+ break;
89
+ }
90
+ fileResults.push(await processFile({
91
+ file,
92
+ prompt: session.prompt,
93
+ mode,
94
+ }));
95
+ }
96
+ await safeAsync(() => options.deps.client.session.delete({
97
+ path: { id: session.sessionId },
98
+ }));
99
+ const table = buildTable(fileResults.map(toTableRow));
100
+ if (table.length > 0) {
101
+ await sendResult({
102
+ client: options.deps.client,
103
+ sessionID: context.sessionID,
104
+ text: table,
105
+ });
106
+ }
107
+ return table;
108
+ }
109
+ catch (err) {
110
+ const msg = err instanceof Error ? err.message : String(err);
111
+ return 'rewrite-instructions error: ' + msg;
112
+ }
113
+ },
114
+ });
115
+ };
116
+ export const createAppendTool = (options) => {
117
+ return tool({
118
+ description: options.description,
119
+ args: {
120
+ input: tool.schema.string().describe('Unstructured text describing the rule(s) to add'),
121
+ file: tool.schema.string().optional().describe('File path to append to. If omitted, uses the first discovered instruction file.'),
122
+ ...(options.hasMode
123
+ ? {
124
+ mode: tool.schema.string().optional().describe('Output format: verbose, balanced, or concise (default: balanced)'),
125
+ }
126
+ : {}),
127
+ },
128
+ async execute(args, context) {
129
+ const mode = options.hasMode && isFormatMode(args.mode) ? args.mode : options.defaultMode;
130
+ try {
131
+ let filePath = args.file;
132
+ if (!filePath) {
133
+ const resolved = await resolveFiles(options.deps.directory);
134
+ if (resolved.error !== null) {
135
+ return resolved.error;
136
+ }
137
+ const first = resolved.data[0];
138
+ if (!first) {
139
+ return 'No instruction files found in opencode.json';
140
+ }
141
+ filePath = first.path;
142
+ }
143
+ const session = await createSession({
144
+ client: options.deps.client,
145
+ sessionID: context.sessionID,
146
+ title: options.sessionTitle,
147
+ toolName: options.toolName,
148
+ });
149
+ if (!session.ok) {
150
+ return session.error;
151
+ }
152
+ const result = await appendRules({
153
+ input: args.input,
154
+ filePath,
155
+ directory: options.deps.directory,
156
+ prompt: session.prompt,
157
+ mode,
158
+ });
159
+ await safeAsync(() => options.deps.client.session.delete({
160
+ path: { id: session.sessionId },
161
+ }));
162
+ if (result.status !== 'success') {
163
+ return result.status + ': ' + result.error;
164
+ }
165
+ const msg = options.successPrefix + result.rulesCount + ' rule(s) to ' + result.path;
166
+ await sendResult({
167
+ client: options.deps.client,
168
+ sessionID: context.sessionID,
169
+ text: msg,
170
+ });
171
+ return msg;
172
+ }
173
+ catch (err) {
174
+ const msg = err instanceof Error ? err.message : String(err);
175
+ return options.toolName + ' error: ' + msg;
176
+ }
177
+ },
178
+ });
179
+ };
180
+ export const createRefineTool = (options) => {
181
+ return tool({
182
+ description: options.description,
183
+ args: {
184
+ input: tool.schema.string().describe('Raw unstructured user input to refine into a structured prompt'),
185
+ },
186
+ async execute(args, context) {
187
+ try {
188
+ const session = await createSession({
189
+ client: options.deps.client,
190
+ sessionID: context.sessionID,
191
+ title: 'SAT Refine',
192
+ toolName: 'refine-prompt',
193
+ });
194
+ if (!session.ok) {
195
+ return session.error;
196
+ }
197
+ const result = await processPrompt({
198
+ input: args.input,
199
+ prompt: session.prompt,
200
+ });
201
+ await safeAsync(() => options.deps.client.session.delete({
202
+ path: { id: session.sessionId },
203
+ }));
204
+ if (result.status !== 'success') {
205
+ return 'refine-prompt parse error: ' + result.error;
206
+ }
207
+ await sendResult({
208
+ client: options.deps.client,
209
+ sessionID: context.sessionID,
210
+ text: result.formatted,
211
+ });
212
+ return result.formatted;
213
+ }
214
+ catch (err) {
215
+ const msg = err instanceof Error ? err.message : String(err);
216
+ return 'refine-prompt error: ' + msg;
217
+ }
218
+ },
219
+ });
220
+ };
221
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ export type ComparisonResult = {
2
+ file: string;
3
+ originalBytes: number;
4
+ generatedBytes: number;
5
+ difference: number;
6
+ percentChange: number;
7
+ };
8
+ export declare const compareBytes: (file: string, original: string, generated: string) => ComparisonResult;
9
+ export type ComparisonSummary = {
10
+ totalOriginal: number;
11
+ totalGenerated: number;
12
+ totalDifference: number;
13
+ totalPercentChange: number;
14
+ };
15
+ export declare const summarize: (results: ComparisonResult[]) => ComparisonSummary;
16
+ export type TableRow = {
17
+ file: string;
18
+ status: string;
19
+ rules?: number;
20
+ comparison?: ComparisonResult;
21
+ };
22
+ export declare const buildTable: (rows: TableRow[]) => string;
23
+ //# sourceMappingURL=compare.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../../src/utils/compare.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,aAAa,EAAE,MAAM,CAAA;IACrB,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;CACtB,CAAA;AAGD,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,EAAE,UAAU,MAAM,EAAE,WAAW,MAAM,KAAG,gBAahF,CAAA;AAQD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,aAAa,EAAE,MAAM,CAAA;IACrB,cAAc,EAAE,MAAM,CAAA;IACtB,eAAe,EAAE,MAAM,CAAA;IACvB,kBAAkB,EAAE,MAAM,CAAA;CAC3B,CAAA;AAGD,eAAO,MAAM,SAAS,GAAI,SAAS,gBAAgB,EAAE,KAAG,iBAYvD,CAAA;AAqBD,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,gBAAgB,CAAA;CAC9B,CAAA;AAGD,eAAO,MAAM,UAAU,GAAI,MAAM,QAAQ,EAAE,KAAG,MAwE7C,CAAA"}
@@ -0,0 +1,116 @@
1
+ import Table from 'cli-table3';
2
+ // compare byte sizes of two strings and return diff stats
3
+ export const compareBytes = (file, original, generated) => {
4
+ const originalBytes = new TextEncoder().encode(original).length;
5
+ const generatedBytes = new TextEncoder().encode(generated).length;
6
+ const difference = originalBytes - generatedBytes;
7
+ const percentChange = originalBytes === 0 ? 0 : (difference / originalBytes) * 100;
8
+ return {
9
+ file,
10
+ originalBytes,
11
+ generatedBytes,
12
+ difference,
13
+ percentChange,
14
+ };
15
+ };
16
+ // format a percent change string with direction indicator
17
+ const formatChange = (difference, percentChange) => {
18
+ const prefix = difference > 0 ? '\u2212' : '+';
19
+ return prefix + Math.abs(percentChange).toFixed(1) + '%';
20
+ };
21
+ // summarize an array of comparison results into totals
22
+ export const summarize = (results) => {
23
+ const totalOriginal = results.reduce((sum, r) => sum + r.originalBytes, 0);
24
+ const totalGenerated = results.reduce((sum, r) => sum + r.generatedBytes, 0);
25
+ const totalDifference = totalOriginal - totalGenerated;
26
+ const totalPercentChange = totalOriginal === 0 ? 0 : (totalDifference / totalOriginal) * 100;
27
+ return {
28
+ totalOriginal,
29
+ totalGenerated,
30
+ totalDifference,
31
+ totalPercentChange,
32
+ };
33
+ };
34
+ // no-border chars config for cli-table3
35
+ const NO_BORDERS = {
36
+ 'top': '',
37
+ 'top-mid': '',
38
+ 'top-left': '',
39
+ 'top-right': '',
40
+ 'bottom': '',
41
+ 'bottom-mid': '',
42
+ 'bottom-left': '',
43
+ 'bottom-right': '',
44
+ 'left': '',
45
+ 'left-mid': '',
46
+ 'mid': '',
47
+ 'mid-mid': '',
48
+ 'right': '',
49
+ 'right-mid': '',
50
+ 'middle': ' ',
51
+ };
52
+ // build a results table as a string
53
+ export const buildTable = (rows) => {
54
+ if (rows.length === 0) {
55
+ return '';
56
+ }
57
+ const table = new Table({
58
+ head: ['File', 'Status', 'Rules', 'Original', 'Generated', 'Diff', 'Change'],
59
+ chars: NO_BORDERS,
60
+ style: {
61
+ head: [],
62
+ border: [],
63
+ 'padding-left': 0,
64
+ 'padding-right': 0,
65
+ },
66
+ colAligns: ['left', 'left', 'right', 'right', 'right', 'right', 'right'],
67
+ });
68
+ const sorted = [...rows].sort((a, b) => {
69
+ const aDiff = a.comparison ? Math.abs(a.comparison.difference) : 0;
70
+ const bDiff = b.comparison ? Math.abs(b.comparison.difference) : 0;
71
+ return bDiff - aDiff;
72
+ });
73
+ for (const row of sorted) {
74
+ const c = row.comparison;
75
+ table.push([
76
+ row.file,
77
+ row.status,
78
+ row.rules !== undefined ? row.rules : '',
79
+ c ? c.originalBytes : '',
80
+ c ? c.generatedBytes : '',
81
+ c ? c.difference : '',
82
+ c ? formatChange(c.difference, c.percentChange) : '',
83
+ ]);
84
+ }
85
+ const comparisons = [];
86
+ for (const row of rows) {
87
+ if (row.comparison !== undefined) {
88
+ comparisons.push(row.comparison);
89
+ }
90
+ }
91
+ const totals = summarize(comparisons);
92
+ const totalRules = rows.reduce((sum, r) => sum + (r.rules !== undefined ? r.rules : 0), 0);
93
+ table.push([
94
+ 'TOTAL',
95
+ '',
96
+ totalRules > 0 ? totalRules : '',
97
+ totals.totalOriginal > 0 ? totals.totalOriginal : '',
98
+ totals.totalGenerated > 0 ? totals.totalGenerated : '',
99
+ totals.totalDifference !== 0 ? totals.totalDifference : '',
100
+ totals.totalOriginal > 0 ? formatChange(totals.totalDifference, totals.totalPercentChange) : '',
101
+ ]);
102
+ // insert separator lines after header and before TOTAL
103
+ const lines = table.toString().split('\n');
104
+ const width = lines.reduce((max, line) => Math.max(max, line.length), 0);
105
+ const separator = '\u2500'.repeat(width);
106
+ lines.splice(1, 0, separator);
107
+ lines.splice(lines.length - 1, 0, separator);
108
+ if (totals.totalOriginal === 0) {
109
+ return lines.join('\n');
110
+ }
111
+ const summary = (totals.totalDifference > 0 ? 'SAVED ' : 'INCREASED ')
112
+ + Math.abs(totals.totalDifference) + ' bytes ('
113
+ + Math.abs(totals.totalPercentChange).toFixed(1) + '%)';
114
+ return lines.join('\n') + '\n\n' + summary;
115
+ };
116
+ //# sourceMappingURL=compare.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare.js","sourceRoot":"","sources":["../../../src/utils/compare.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export type MessageInfo = {
2
+ role: string;
3
+ providerID?: string;
4
+ modelID?: string;
5
+ error?: {
6
+ name?: string;
7
+ data?: {
8
+ message?: string;
9
+ };
10
+ };
11
+ };
12
+ export declare const extractLlmError: (info: MessageInfo) => string | null;
13
+ //# sourceMappingURL=extractLlmError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractLlmError.d.ts","sourceRoot":"","sources":["../../../src/utils/extractLlmError.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE;QACN,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,IAAI,CAAC,EAAE;YACL,OAAO,CAAC,EAAE,MAAM,CAAA;SACjB,CAAA;KACF,CAAA;CACF,CAAA;AAGD,eAAO,MAAM,eAAe,GAAI,MAAM,WAAW,KAAG,MAAM,GAAG,IAW5D,CAAA"}
@@ -0,0 +1,12 @@
1
+ // extract error message from LLM response info
2
+ export const extractLlmError = (info) => {
3
+ if (!info.error) {
4
+ return null;
5
+ }
6
+ const err = info.error;
7
+ if (err.data && err.data.message) {
8
+ return err.data.message;
9
+ }
10
+ return err.name || 'Unknown LLM error';
11
+ };
12
+ //# sourceMappingURL=extractLlmError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractLlmError.js","sourceRoot":"","sources":["../../../src/utils/extractLlmError.ts"],"names":[],"mappings":"AAYA,+CAA+C;AAC/C,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAAiB,EAAiB,EAAE;IAClE,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAA;IACtB,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QACjC,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,CAAA;IACzB,CAAC;IAED,OAAO,GAAG,CAAC,IAAI,IAAI,mBAAmB,CAAA;AACxC,CAAC,CAAA"}
@@ -0,0 +1,14 @@
1
+ type ResultSuccess<T> = {
2
+ data: T;
3
+ error: null;
4
+ };
5
+ type ResultError<E> = {
6
+ data: null;
7
+ error: E;
8
+ };
9
+ export type Result<T, E = string> = ResultSuccess<T> | ResultError<E>;
10
+ type SafeResult<T> = Result<T, Error>;
11
+ export declare const safe: <T>(fn: () => T) => SafeResult<T>;
12
+ export declare const safeAsync: <T>(fn: () => Promise<T>) => Promise<SafeResult<T>>;
13
+ export {};
14
+ //# sourceMappingURL=safe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safe.d.ts","sourceRoot":"","sources":["../../../src/utils/safe.ts"],"names":[],"mappings":"AAAA,KAAK,aAAa,CAAC,CAAC,IAAI;IACtB,IAAI,EAAE,CAAC,CAAA;IACP,KAAK,EAAE,IAAI,CAAA;CACZ,CAAA;AAED,KAAK,WAAW,CAAC,CAAC,IAAI;IACpB,IAAI,EAAE,IAAI,CAAA;IACV,KAAK,EAAE,CAAC,CAAA;CACT,CAAA;AAED,MAAM,MAAM,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM,IAAI,aAAa,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;AAErE,KAAK,UAAU,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;AAErC,eAAO,MAAM,IAAI,GAAI,CAAC,EAAE,IAAI,MAAM,CAAC,KAAG,UAAU,CAAC,CAAC,CAajD,CAAA;AAED,eAAO,MAAM,SAAS,GAAU,CAAC,EAAE,IAAI,MAAM,OAAO,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAa9E,CAAA"}