@gaunt-sloth/core 0.0.1

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 (89) hide show
  1. package/.gsloth.backstory.md +17 -0
  2. package/.gsloth.chat.md +11 -0
  3. package/.gsloth.code.md +27 -0
  4. package/.gsloth.guidelines.md +1 -0
  5. package/.gsloth.review.md +15 -0
  6. package/.gsloth.system.md +10 -0
  7. package/README.md +27 -0
  8. package/dist/config.d.ts +533 -0
  9. package/dist/config.js +412 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/constants.d.ts +13 -0
  12. package/dist/constants.js +14 -0
  13. package/dist/constants.js.map +1 -0
  14. package/dist/core/GthAgentRunner.d.ts +27 -0
  15. package/dist/core/GthAgentRunner.js +109 -0
  16. package/dist/core/GthAgentRunner.js.map +1 -0
  17. package/dist/core/GthLangChainAgent.d.ts +56 -0
  18. package/dist/core/GthLangChainAgent.js +355 -0
  19. package/dist/core/GthLangChainAgent.js.map +1 -0
  20. package/dist/core/types.d.ts +39 -0
  21. package/dist/core/types.js +16 -0
  22. package/dist/core/types.js.map +1 -0
  23. package/dist/index.d.ts +3 -0
  24. package/dist/index.js +4 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/providers/anthropic.d.ts +7 -0
  27. package/dist/providers/anthropic.js +34 -0
  28. package/dist/providers/anthropic.js.map +1 -0
  29. package/dist/providers/deepseek.d.ts +4 -0
  30. package/dist/providers/deepseek.js +30 -0
  31. package/dist/providers/deepseek.js.map +1 -0
  32. package/dist/providers/fake.d.ts +3 -0
  33. package/dist/providers/fake.js +12 -0
  34. package/dist/providers/fake.js.map +1 -0
  35. package/dist/providers/google-genai.d.ts +7 -0
  36. package/dist/providers/google-genai.js +34 -0
  37. package/dist/providers/google-genai.js.map +1 -0
  38. package/dist/providers/groq.d.ts +4 -0
  39. package/dist/providers/groq.js +30 -0
  40. package/dist/providers/groq.js.map +1 -0
  41. package/dist/providers/openai.d.ts +5 -0
  42. package/dist/providers/openai.js +46 -0
  43. package/dist/providers/openai.js.map +1 -0
  44. package/dist/providers/openrouter.d.ts +5 -0
  45. package/dist/providers/openrouter.js +57 -0
  46. package/dist/providers/openrouter.js.map +1 -0
  47. package/dist/providers/vertexai.d.ts +7 -0
  48. package/dist/providers/vertexai.js +41 -0
  49. package/dist/providers/vertexai.js.map +1 -0
  50. package/dist/providers/xai.d.ts +4 -0
  51. package/dist/providers/xai.js +30 -0
  52. package/dist/providers/xai.js.map +1 -0
  53. package/dist/state/artifactStore.d.ts +21 -0
  54. package/dist/state/artifactStore.js +30 -0
  55. package/dist/state/artifactStore.js.map +1 -0
  56. package/dist/utils/ProgressIndicator.d.ts +7 -0
  57. package/dist/utils/ProgressIndicator.js +26 -0
  58. package/dist/utils/ProgressIndicator.js.map +1 -0
  59. package/dist/utils/aiignoreUtils.d.ts +29 -0
  60. package/dist/utils/aiignoreUtils.js +82 -0
  61. package/dist/utils/aiignoreUtils.js.map +1 -0
  62. package/dist/utils/binaryOutputUtils.d.ts +13 -0
  63. package/dist/utils/binaryOutputUtils.js +138 -0
  64. package/dist/utils/binaryOutputUtils.js.map +1 -0
  65. package/dist/utils/consoleUtils.d.ts +76 -0
  66. package/dist/utils/consoleUtils.js +230 -0
  67. package/dist/utils/consoleUtils.js.map +1 -0
  68. package/dist/utils/debugUtils.d.ts +20 -0
  69. package/dist/utils/debugUtils.js +89 -0
  70. package/dist/utils/debugUtils.js.map +1 -0
  71. package/dist/utils/fileUtils.d.ts +68 -0
  72. package/dist/utils/fileUtils.js +216 -0
  73. package/dist/utils/fileUtils.js.map +1 -0
  74. package/dist/utils/globalConfigUtils.d.ts +28 -0
  75. package/dist/utils/globalConfigUtils.js +61 -0
  76. package/dist/utils/globalConfigUtils.js.map +1 -0
  77. package/dist/utils/llmUtils.d.ts +39 -0
  78. package/dist/utils/llmUtils.js +153 -0
  79. package/dist/utils/llmUtils.js.map +1 -0
  80. package/dist/utils/stringUtils.d.ts +4 -0
  81. package/dist/utils/stringUtils.js +10 -0
  82. package/dist/utils/stringUtils.js.map +1 -0
  83. package/dist/utils/systemUtils.d.ts +70 -0
  84. package/dist/utils/systemUtils.js +207 -0
  85. package/dist/utils/systemUtils.js.map +1 -0
  86. package/dist/utils/vertexaiUtils.d.ts +2 -0
  87. package/dist/utils/vertexaiUtils.js +18 -0
  88. package/dist/utils/vertexaiUtils.js.map +1 -0
  89. package/package.json +57 -0
@@ -0,0 +1,138 @@
1
+ import { writeFileSync, existsSync } from 'node:fs';
2
+ import { fileSafeLocalDate, getGslothFilePath, toFileSafeString } from '#src/utils/fileUtils.js';
3
+ const MIME_TYPE_EXTENSIONS = {
4
+ 'image/png': 'png',
5
+ 'image/jpeg': 'jpg',
6
+ 'image/gif': 'gif',
7
+ 'image/webp': 'webp',
8
+ 'image/svg+xml': 'svg',
9
+ 'image/heic': 'heic',
10
+ 'application/pdf': 'pdf',
11
+ 'audio/mpeg': 'mp3',
12
+ 'audio/mp4': 'm4a',
13
+ 'audio/wav': 'wav',
14
+ 'video/mp4': 'mp4',
15
+ };
16
+ function getMimeExtension(mimeType) {
17
+ const normalized = mimeType.trim().toLowerCase();
18
+ if (MIME_TYPE_EXTENSIONS[normalized]) {
19
+ return MIME_TYPE_EXTENSIONS[normalized];
20
+ }
21
+ const subtype = normalized.split('/')[1]?.split(';')[0]?.trim();
22
+ if (!subtype) {
23
+ return 'bin';
24
+ }
25
+ if (subtype === 'jpeg') {
26
+ return 'jpg';
27
+ }
28
+ if (subtype.includes('+xml')) {
29
+ return subtype.split('+')[0];
30
+ }
31
+ if (/^[a-z0-9]+$/.test(subtype) && subtype.length <= 4) {
32
+ return subtype;
33
+ }
34
+ return 'bin';
35
+ }
36
+ function getBinaryOutputFilePath(command, extension) {
37
+ const dateTimeStr = fileSafeLocalDate();
38
+ const commandStr = toFileSafeString((command ?? 'output').toUpperCase());
39
+ const normalizedExtension = extension.replace(/^\./, '') || 'bin';
40
+ const filename = `gth_${dateTimeStr}_${commandStr}.${normalizedExtension}`;
41
+ const initialPath = getGslothFilePath(filename);
42
+ if (!existsSync(initialPath)) {
43
+ return initialPath;
44
+ }
45
+ const suffixBase = initialPath.slice(0, -(normalizedExtension.length + 1));
46
+ for (let suffix = 2; suffix < 1000; suffix++) {
47
+ const candidate = `${suffixBase}_${suffix}.${normalizedExtension}`;
48
+ if (!existsSync(candidate)) {
49
+ return candidate;
50
+ }
51
+ }
52
+ return `${suffixBase}_${Date.now()}.${normalizedExtension}`;
53
+ }
54
+ export function extractInlineBinaryBlocks(content) {
55
+ if (!Array.isArray(content)) {
56
+ return [];
57
+ }
58
+ return content.flatMap((block, index) => {
59
+ if (block &&
60
+ typeof block === 'object' &&
61
+ 'type' in block &&
62
+ block.type === 'inlineData' &&
63
+ 'inlineData' in block &&
64
+ block.inlineData &&
65
+ typeof block.inlineData === 'object' &&
66
+ 'mimeType' in block.inlineData &&
67
+ 'data' in block.inlineData &&
68
+ typeof block.inlineData.mimeType === 'string' &&
69
+ typeof block.inlineData.data === 'string') {
70
+ return [
71
+ {
72
+ index,
73
+ mimeType: block.inlineData.mimeType,
74
+ data: block.inlineData.data,
75
+ },
76
+ ];
77
+ }
78
+ return [];
79
+ });
80
+ }
81
+ export function renderAssistantContent(content, binaryPlaceholders = new Map()) {
82
+ if (content === undefined || content === null) {
83
+ return '';
84
+ }
85
+ if (typeof content === 'string') {
86
+ return content;
87
+ }
88
+ if (!Array.isArray(content)) {
89
+ return String(content);
90
+ }
91
+ return content
92
+ .map((block, index) => {
93
+ if (binaryPlaceholders.has(index)) {
94
+ return binaryPlaceholders.get(index);
95
+ }
96
+ if (typeof block === 'string') {
97
+ return block;
98
+ }
99
+ if (block && typeof block === 'object' && 'type' in block && block.type === 'text') {
100
+ if ('text' in block && typeof block.text === 'string') {
101
+ return block.text;
102
+ }
103
+ }
104
+ return JSON.stringify(block);
105
+ })
106
+ .filter((part) => !!part && part.trim().length > 0)
107
+ .join('\n');
108
+ }
109
+ export function materializeBinaryOutputs(content, command) {
110
+ const binaryBlocks = extractInlineBinaryBlocks(content);
111
+ if (binaryBlocks.length === 0) {
112
+ return {
113
+ renderedContent: renderAssistantContent(content),
114
+ successMessages: [],
115
+ };
116
+ }
117
+ const placeholderMap = new Map();
118
+ const successMessages = [];
119
+ for (const binaryBlock of binaryBlocks) {
120
+ const extension = getMimeExtension(binaryBlock.mimeType);
121
+ const filePath = getBinaryOutputFilePath(command, extension);
122
+ try {
123
+ writeFileSync(filePath, Buffer.from(binaryBlock.data, 'base64'));
124
+ const placeholder = `[Binary model output saved: ${binaryBlock.mimeType} -> ${filePath}]`;
125
+ placeholderMap.set(binaryBlock.index, placeholder);
126
+ successMessages.push(`Wrote model output (${binaryBlock.mimeType}) to ${filePath}`);
127
+ }
128
+ catch {
129
+ const errorPlaceholder = `[Failed to save binary output: ${binaryBlock.mimeType}]`;
130
+ placeholderMap.set(binaryBlock.index, errorPlaceholder);
131
+ }
132
+ }
133
+ return {
134
+ renderedContent: renderAssistantContent(content, placeholderMap),
135
+ successMessages,
136
+ };
137
+ }
138
+ //# sourceMappingURL=binaryOutputUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binaryOutputUtils.js","sourceRoot":"","sources":["../../src/utils/binaryOutputUtils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ import { StatusLevel, StatusUpdateCallback } from '#src/core/types.js';
2
+ export declare const initSessionLogging: (logFileName: string, enableLogging: boolean) => void;
3
+ /**
4
+ * Set the console logging level.
5
+ * Only messages at or above this level will be displayed.
6
+ * @param level - The minimum level to display
7
+ */
8
+ export declare const setConsoleLevel: (level: StatusLevel) => void;
9
+ /**
10
+ * Get the current console logging level.
11
+ * @returns The current console level
12
+ */
13
+ export declare const getConsoleLevel: () => StatusLevel;
14
+ /**
15
+ * Reset console level to default (INFO) for testing purposes
16
+ */
17
+ export declare const resetConsoleLevel: () => void;
18
+ export declare const flushSessionLog: () => void;
19
+ export declare const stopSessionLogging: () => void;
20
+ export declare function displayError(message: string): void;
21
+ export declare function displayWarning(message: string): void;
22
+ export declare function displaySuccess(message: string): void;
23
+ export declare function displayInfo(message: string): void;
24
+ export declare function display(message: string): void;
25
+ export declare function formatInputPrompt(message: string): string;
26
+ /**
27
+ * Display a debug message to the console and log it.
28
+ * This function also integrates with debugUtils to output logs when at debug level.
29
+ * Note: There is also a dedicated debug() function in debugUtils for more detailed logging.
30
+ * @param message - The message to display (string, Error, or undefined)
31
+ */
32
+ export declare function displayDebug(message: string | Error | undefined): void;
33
+ export declare const defaultStatusCallback: StatusUpdateCallback;
34
+ /**
35
+ * Result of attempting to parse a CLI value as boolean-or-string.
36
+ * When kind === 'boolean', value is a boolean.
37
+ * When kind === 'string', value is a non-empty string.
38
+ * When kind === 'none', no usable value was provided (undefined/null/empty).
39
+ */
40
+ export type BooleanOrStringParseResult = {
41
+ kind: 'boolean';
42
+ value: boolean;
43
+ } | {
44
+ kind: 'string';
45
+ value: string;
46
+ } | {
47
+ kind: 'none';
48
+ };
49
+ /**
50
+ * Parse a CLI option value into either:
51
+ * - a boolean (when value looks like a true/false token),
52
+ * - a non-empty string (otherwise),
53
+ * - or none (when value is nullish or only whitespace).
54
+ *
55
+ * Recognized false-like tokens (case-insensitive): 'false', '0', 'n', 'no'
56
+ * Recognized true-like tokens (case-insensitive): 'true', '1', 'y', 'yes'
57
+ *
58
+ * Examples:
59
+ * parseBooleanOrString('n') => { kind: 'boolean', value: false }
60
+ * parseBooleanOrString('0') => { kind: 'boolean', value: false }
61
+ * parseBooleanOrString('true') => { kind: 'boolean', value: true }
62
+ * parseBooleanOrString('1') => { kind: 'boolean', value: true }
63
+ * parseBooleanOrString('review.md') => { kind: 'string', value: 'review.md' }
64
+ * parseBooleanOrString(' ') => { kind: 'none' }
65
+ * parseBooleanOrString(undefined) => { kind: 'none' }
66
+ */
67
+ export declare function parseBooleanOrString(value: unknown): BooleanOrStringParseResult;
68
+ /**
69
+ * Convenience wrapper that returns a union directly instead of the tagged result.
70
+ *
71
+ * Returns:
72
+ * - boolean when the input is a boolean-like token
73
+ * - string when the input is non-empty and not a boolean-like token
74
+ * - undefined when the input is nullish or empty/whitespace
75
+ */
76
+ export declare function coerceBooleanOrString(value: unknown): boolean | string | undefined;
@@ -0,0 +1,230 @@
1
+ import { StatusLevel } from '#src/core/types.js';
2
+ import * as su from '#src/utils/systemUtils.js';
3
+ import { closeLogStream, initLogStream, stream, writeToLogStream } from '#src/utils/systemUtils.js';
4
+ import { debugLog } from '#src/utils/debugUtils.js';
5
+ const loggingState = {
6
+ sessionLogFile: undefined,
7
+ enableSessionLogging: false,
8
+ };
9
+ const consoleLevelState = {
10
+ currentLevel: StatusLevel.INFO, // Default to INFO level, not debug
11
+ };
12
+ // ANSI color codes
13
+ const ANSI_COLORS = {
14
+ red: '\x1b[31m',
15
+ yellow: '\x1b[33m',
16
+ green: '\x1b[32m',
17
+ magenta: '\x1b[35m',
18
+ dim: '\x1b[2m',
19
+ reset: '\x1b[0m',
20
+ };
21
+ // Helper functions for ANSI coloring
22
+ function colorText(text, color) {
23
+ if (!su.getUseColour()) {
24
+ return text;
25
+ }
26
+ return `${ANSI_COLORS[color]}${text}${ANSI_COLORS.reset}`;
27
+ }
28
+ // Stream-based logging function
29
+ const writeToSessionLog = (message) => {
30
+ if (loggingState.enableSessionLogging) {
31
+ // Strip ANSI color codes before logging to file
32
+ const cleanMessage = message.replace(/\x1b\[[0-9;]*m/g, '');
33
+ writeToLogStream(cleanMessage);
34
+ }
35
+ };
36
+ // Public functions for session logging management
37
+ export const initSessionLogging = (logFileName, enableLogging) => {
38
+ loggingState.sessionLogFile = enableLogging ? logFileName : undefined;
39
+ loggingState.enableSessionLogging = enableLogging;
40
+ if (enableLogging && logFileName) {
41
+ initLogStream(logFileName);
42
+ }
43
+ };
44
+ /**
45
+ * Set the console logging level.
46
+ * Only messages at or above this level will be displayed.
47
+ * @param level - The minimum level to display
48
+ */
49
+ export const setConsoleLevel = (level) => {
50
+ consoleLevelState.currentLevel = level;
51
+ };
52
+ /**
53
+ * Get the current console logging level.
54
+ * @returns The current console level
55
+ */
56
+ export const getConsoleLevel = () => {
57
+ return consoleLevelState.currentLevel;
58
+ };
59
+ /**
60
+ * Reset console level to default (INFO) for testing purposes
61
+ */
62
+ export const resetConsoleLevel = () => {
63
+ consoleLevelState.currentLevel = StatusLevel.INFO;
64
+ };
65
+ /**
66
+ * Check if a given status level should be displayed based on current console level.
67
+ * @param level - The status level to check
68
+ * @returns true if the level should be displayed
69
+ */
70
+ function shouldDisplayLevel(level) {
71
+ // Use enum values for comparison (higher values = more verbose)
72
+ return level >= consoleLevelState.currentLevel;
73
+ }
74
+ export const flushSessionLog = () => {
75
+ // Streams auto-flush, so this is now a no-op for API compatibility
76
+ // Could potentially force flush if needed in the future
77
+ };
78
+ export const stopSessionLogging = () => {
79
+ closeLogStream();
80
+ loggingState.sessionLogFile = undefined;
81
+ loggingState.enableSessionLogging = false;
82
+ };
83
+ export function displayError(message) {
84
+ if (!shouldDisplayLevel(StatusLevel.ERROR))
85
+ return;
86
+ const coloredMessage = colorText(message, 'red');
87
+ writeToSessionLog(message + '\n');
88
+ su.log(coloredMessage);
89
+ }
90
+ export function displayWarning(message) {
91
+ if (!shouldDisplayLevel(StatusLevel.WARNING))
92
+ return;
93
+ const coloredMessage = colorText(message, 'yellow');
94
+ writeToSessionLog(message + '\n');
95
+ su.warn(coloredMessage);
96
+ }
97
+ export function displaySuccess(message) {
98
+ if (!shouldDisplayLevel(StatusLevel.SUCCESS))
99
+ return;
100
+ const coloredMessage = colorText(message, 'green');
101
+ writeToSessionLog(message + '\n');
102
+ su.log(coloredMessage);
103
+ }
104
+ export function displayInfo(message) {
105
+ if (!shouldDisplayLevel(StatusLevel.INFO))
106
+ return;
107
+ const coloredMessage = colorText(message, 'dim');
108
+ writeToSessionLog(message + '\n');
109
+ su.info(coloredMessage);
110
+ }
111
+ export function display(message) {
112
+ if (!shouldDisplayLevel(StatusLevel.DISPLAY))
113
+ return;
114
+ writeToSessionLog(message + '\n');
115
+ su.log(message);
116
+ }
117
+ export function formatInputPrompt(message) {
118
+ return colorText(message, 'magenta');
119
+ }
120
+ /**
121
+ * Display a debug message to the console and log it.
122
+ * This function also integrates with debugUtils to output logs when at debug level.
123
+ * Note: There is also a dedicated debug() function in debugUtils for more detailed logging.
124
+ * @param message - The message to display (string, Error, or undefined)
125
+ */
126
+ export function displayDebug(message) {
127
+ if (!shouldDisplayLevel(StatusLevel.DEBUG))
128
+ return;
129
+ if (message instanceof Error) {
130
+ const stackTrace = message.stack || '';
131
+ writeToSessionLog(stackTrace + '\n');
132
+ su.debug(stackTrace);
133
+ // Also log to debugUtils when at debug level
134
+ debugLog(stackTrace);
135
+ }
136
+ else if (message !== undefined) {
137
+ writeToSessionLog(message + '\n');
138
+ su.debug(message);
139
+ // Also log to debugUtils when at debug level
140
+ debugLog(message);
141
+ }
142
+ }
143
+ // Create status update callback
144
+ export const defaultStatusCallback = (level, message) => {
145
+ switch (level) {
146
+ case StatusLevel.INFO:
147
+ displayInfo(message);
148
+ break;
149
+ case StatusLevel.WARNING:
150
+ displayWarning(message);
151
+ break;
152
+ case StatusLevel.ERROR:
153
+ displayError(message);
154
+ break;
155
+ case StatusLevel.SUCCESS:
156
+ displaySuccess(message);
157
+ break;
158
+ case StatusLevel.DEBUG:
159
+ displayDebug(message);
160
+ break;
161
+ case StatusLevel.DISPLAY:
162
+ display(message);
163
+ break;
164
+ case StatusLevel.STREAM:
165
+ if (shouldDisplayLevel(StatusLevel.STREAM)) {
166
+ writeToSessionLog(message);
167
+ stream(message);
168
+ }
169
+ break;
170
+ }
171
+ };
172
+ /**
173
+ * Parse a CLI option value into either:
174
+ * - a boolean (when value looks like a true/false token),
175
+ * - a non-empty string (otherwise),
176
+ * - or none (when value is nullish or only whitespace).
177
+ *
178
+ * Recognized false-like tokens (case-insensitive): 'false', '0', 'n', 'no'
179
+ * Recognized true-like tokens (case-insensitive): 'true', '1', 'y', 'yes'
180
+ *
181
+ * Examples:
182
+ * parseBooleanOrString('n') => { kind: 'boolean', value: false }
183
+ * parseBooleanOrString('0') => { kind: 'boolean', value: false }
184
+ * parseBooleanOrString('true') => { kind: 'boolean', value: true }
185
+ * parseBooleanOrString('1') => { kind: 'boolean', value: true }
186
+ * parseBooleanOrString('review.md') => { kind: 'string', value: 'review.md' }
187
+ * parseBooleanOrString(' ') => { kind: 'none' }
188
+ * parseBooleanOrString(undefined) => { kind: 'none' }
189
+ */
190
+ export function parseBooleanOrString(value) {
191
+ if (value === undefined || value === null) {
192
+ return { kind: 'none' };
193
+ }
194
+ const str = String(value);
195
+ const trimmed = str.trim();
196
+ if (trimmed.length === 0) {
197
+ return { kind: 'none' };
198
+ }
199
+ const lower = trimmed.toLowerCase();
200
+ // False-like tokens
201
+ if (lower === 'false' || lower === '0' || lower === 'n' || lower === 'no') {
202
+ return { kind: 'boolean', value: false };
203
+ }
204
+ // True-like tokens
205
+ if (lower === 'true' || lower === '1' || lower === 'y' || lower === 'yes') {
206
+ return { kind: 'boolean', value: true };
207
+ }
208
+ // Otherwise, treat as a string (e.g., filename/path)
209
+ return { kind: 'string', value: trimmed };
210
+ }
211
+ /**
212
+ * Convenience wrapper that returns a union directly instead of the tagged result.
213
+ *
214
+ * Returns:
215
+ * - boolean when the input is a boolean-like token
216
+ * - string when the input is non-empty and not a boolean-like token
217
+ * - undefined when the input is nullish or empty/whitespace
218
+ */
219
+ export function coerceBooleanOrString(value) {
220
+ const parsed = parseBooleanOrString(value);
221
+ switch (parsed.kind) {
222
+ case 'boolean':
223
+ return parsed.value;
224
+ case 'string':
225
+ return parsed.value;
226
+ default:
227
+ return undefined;
228
+ }
229
+ }
230
+ //# sourceMappingURL=consoleUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consoleUtils.js","sourceRoot":"","sources":["../../src/utils/consoleUtils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Initialize debug logging based on config
3
+ */
4
+ export declare function initDebugLogging(enabled: boolean): void;
5
+ /**
6
+ * Log a debug message to the log file
7
+ */
8
+ export declare function debugLog(message: string): void;
9
+ /**
10
+ * Log multiple lines with proper formatting
11
+ */
12
+ export declare function debugLogMultiline(title: string, content: string): void;
13
+ /**
14
+ * Log an object using Node.js inspect with reasonable depth
15
+ */
16
+ export declare function debugLogObject(title: string, obj: unknown): void;
17
+ /**
18
+ * Log error with stack trace
19
+ */
20
+ export declare function debugLogError(context: string, error: unknown): void;
@@ -0,0 +1,89 @@
1
+ import { appendFileSync, mkdirSync } from 'node:fs';
2
+ import { dirname, resolve } from 'node:path';
3
+ import { inspect } from 'node:util';
4
+ const DEBUG_LOG_FILE = 'gaunt-sloth.log';
5
+ let debugEnabled = false;
6
+ /**
7
+ * Initialize debug logging based on config
8
+ */
9
+ export function initDebugLogging(enabled) {
10
+ debugEnabled = enabled;
11
+ if (debugEnabled) {
12
+ // Ensure the log file directory exists
13
+ const logPath = resolve(DEBUG_LOG_FILE);
14
+ const logDir = dirname(logPath);
15
+ try {
16
+ mkdirSync(logDir, { recursive: true });
17
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
18
+ }
19
+ catch (error) {
20
+ // Directory might already exist, ignore error
21
+ }
22
+ // Log initialization
23
+ debugLog('=== Debug logging initialized ===');
24
+ debugLog(`Timestamp: ${new Date().toISOString()}`);
25
+ debugLog(`Log file: ${logPath}`);
26
+ debugLog('================================\n');
27
+ }
28
+ }
29
+ /**
30
+ * Log a debug message to the log file
31
+ */
32
+ export function debugLog(message) {
33
+ if (!debugEnabled)
34
+ return;
35
+ const timestamp = new Date().toISOString();
36
+ const logEntry = `[${timestamp}] ${message}\n`;
37
+ try {
38
+ appendFileSync(resolve(DEBUG_LOG_FILE), logEntry, 'utf8');
39
+ }
40
+ catch (error) {
41
+ // Ignore logging errors to prevent breaking the main flow
42
+ console.error('Failed to write to debug log:', error);
43
+ }
44
+ }
45
+ /**
46
+ * Log multiple lines with proper formatting
47
+ */
48
+ export function debugLogMultiline(title, content) {
49
+ if (!debugEnabled)
50
+ return;
51
+ debugLog(`=== ${title} ===`);
52
+ debugLog(content);
53
+ debugLog(`=== End ${title} ===\n`);
54
+ }
55
+ /**
56
+ * Log an object using Node.js inspect with reasonable depth
57
+ */
58
+ export function debugLogObject(title, obj) {
59
+ if (!debugEnabled)
60
+ return;
61
+ try {
62
+ // Use Node.js inspect with reasonable depth and no colors for log files
63
+ const formatted = inspect(obj, { showHidden: false, depth: 3, colors: false });
64
+ debugLogMultiline(title, formatted);
65
+ }
66
+ catch (error) {
67
+ debugLog(`Failed to inspect ${title}: ${error}`);
68
+ }
69
+ }
70
+ /**
71
+ * Log error with stack trace
72
+ */
73
+ export function debugLogError(context, error) {
74
+ if (!debugEnabled)
75
+ return;
76
+ debugLog(`❌ Error in ${context}:`);
77
+ if (error instanceof Error) {
78
+ debugLog(` Message: ${error.message}`);
79
+ if (error.stack) {
80
+ debugLog(' Stack trace:');
81
+ error.stack.split('\n').forEach((line) => debugLog(` ${line}`));
82
+ }
83
+ }
84
+ else {
85
+ debugLog(` Error: ${String(error)}`);
86
+ }
87
+ debugLog('');
88
+ }
89
+ //# sourceMappingURL=debugUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debugUtils.js","sourceRoot":"","sources":["../../src/utils/debugUtils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Checks if .gsloth directory exists in the project root
3
+ * @returns Boolean indicating whether .gsloth directory exists
4
+ */
5
+ export declare function gslothDirExists(): boolean;
6
+ /**
7
+ * Gets the path where gsloth should write files based on .gsloth directory existence
8
+ * @param filename The filename to append to the path
9
+ * @returns The resolved path where the file should be written
10
+ */
11
+ export declare function getGslothFilePath(filename: string): string;
12
+ /**
13
+ * Gets the path where gsloth should write configuration files based on .gsloth directory existence.
14
+ * The main difference from {@link #getGslothConfigReadPath} is that this getGslothConfigWritePath
15
+ * method creates internal settings directory if it does not exist.
16
+ *
17
+ * If .gsloth dir exists returns `projectdir/.gsloth/.gsloth-settings`
18
+ * If .gsloth dir does not exist returns `projectdir`
19
+ *
20
+ * @param filename The configuration filename
21
+ * @returns The resolved path where the configuration file should be written
22
+ */
23
+ export declare function getGslothConfigWritePath(filename: string): string;
24
+ /**
25
+ * Gets the path where gsloth should look for configuration files based on .gsloth directory existence
26
+ * @param filename The configuration filename to look for
27
+ * @param identityProfileRaw The identity profile dir within GSLOTH_SETTINGS_DIR to look for the configuration file in.
28
+ * @returns The resolved path where the configuration file should be found
29
+ */
30
+ export declare function getGslothConfigReadPath(filename: string, identityProfileRaw: string | undefined): string;
31
+ /**
32
+ * Resolve an explicit output path string to an absolute file path.
33
+ * Concerned only with string values:
34
+ * - If the string includes a path separator, resolve relative to project root and ensure parent directories exist.
35
+ * - If it's a bare filename, place it under .gsloth/ when present, otherwise project root.
36
+ */
37
+ export declare function resolveOutputPath(writeOutputToFile: string): string;
38
+ export declare function toFileSafeString(string: string): string;
39
+ /**
40
+ * Returns a formatted date string in the format YYYY-MM-DD_HH-MM-SS using local time
41
+ * @returns A formatted date string
42
+ */
43
+ export declare function fileSafeLocalDate(): string;
44
+ /**
45
+ * Generates a standardized filename with the format: gth_YYYY-MM-DD_HH-MM-SS_COMMAND.md
46
+ * @param command - The command that created the file (ASK, REVIEW, PR, etc.)
47
+ * @returns A standardized filename string
48
+ */
49
+ export declare function generateStandardFileName(command: string): string;
50
+ export declare function readFileFromProjectDir(fileName: string): string;
51
+ export declare function readFileFromInstallDir(filePath: string): string;
52
+ export declare function writeFileIfNotExistsWithMessages(filePath: string, content: string): void;
53
+ export declare function appendToFile(filePath: string, content: string): void;
54
+ export declare function readFileSyncWithMessages(filePath: string, errorMessageIn?: string, noFileMessage?: string): string;
55
+ /**
56
+ * Dynamically imports a module from a file path from the outside of the installation dir
57
+ * @returns A promise that resolves to the imported module
58
+ */
59
+ export declare function importExternalFile(filePath: string): Promise<Record<string, any>>;
60
+ /**
61
+ * Returns the output file path for a given command execution based on configuration.
62
+ * - If writeOutputToFile is false, returns null.
63
+ * - If writeOutputToFile is a string, resolves it without generating a default filename.
64
+ * - If writeOutputToFile is true, generates a standard filename from source and resolves it under .gsloth/ (when present) or project root.
65
+ */
66
+ export declare function getCommandOutputFilePath(config: {
67
+ writeOutputToFile: boolean | string;
68
+ }, source: string): string | null;