gaunt-sloth-assistant 0.1.5 → 0.2.2
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/.prettierrc.json +9 -0
- package/README.md +177 -158
- package/ROADMAP.md +1 -1
- package/dist/commands/askCommand.d.ts +6 -0
- package/dist/commands/askCommand.js +26 -0
- package/dist/commands/askCommand.js.map +1 -0
- package/dist/commands/initCommand.d.ts +6 -0
- package/dist/commands/initCommand.js +16 -0
- package/dist/commands/initCommand.js.map +1 -0
- package/dist/commands/reviewCommand.d.ts +3 -0
- package/dist/commands/reviewCommand.js +128 -0
- package/dist/commands/reviewCommand.js.map +1 -0
- package/dist/config.d.ts +80 -0
- package/dist/config.js +178 -0
- package/dist/config.js.map +1 -0
- package/dist/configs/anthropic.d.ts +5 -0
- package/{src → dist}/configs/anthropic.js +45 -48
- package/dist/configs/anthropic.js.map +1 -0
- package/dist/configs/fake.d.ts +3 -0
- package/{src → dist}/configs/fake.js +11 -14
- package/dist/configs/fake.js.map +1 -0
- package/dist/configs/groq.d.ts +4 -0
- package/{src → dist}/configs/groq.js +10 -13
- package/dist/configs/groq.js.map +1 -0
- package/dist/configs/types.d.ts +14 -0
- package/dist/configs/types.js +2 -0
- package/dist/configs/types.js.map +1 -0
- package/dist/configs/vertexai.d.ts +4 -0
- package/{src → dist}/configs/vertexai.js +44 -47
- package/dist/configs/vertexai.js.map +1 -0
- package/dist/consoleUtils.d.ts +6 -0
- package/{src → dist}/consoleUtils.js +10 -15
- package/dist/consoleUtils.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/questionAnsweringModule.d.ts +18 -0
- package/{src → dist}/modules/questionAnsweringModule.js +72 -82
- package/dist/modules/questionAnsweringModule.js.map +1 -0
- package/dist/modules/reviewModule.d.ts +4 -0
- package/{src → dist}/modules/reviewModule.js +25 -35
- package/dist/modules/reviewModule.js.map +1 -0
- package/dist/modules/types.d.ts +18 -0
- package/dist/modules/types.js +2 -0
- package/dist/modules/types.js.map +1 -0
- package/dist/prompt.d.ts +7 -0
- package/dist/prompt.js +32 -0
- package/dist/prompt.js.map +1 -0
- package/dist/providers/file.d.ts +8 -0
- package/dist/providers/file.js +20 -0
- package/dist/providers/file.js.map +1 -0
- package/dist/providers/ghPrDiffProvider.d.ts +8 -0
- package/dist/providers/ghPrDiffProvider.js +16 -0
- package/dist/providers/ghPrDiffProvider.js.map +1 -0
- package/dist/providers/jiraIssueLegacyAccessTokenProvider.d.ts +8 -0
- package/dist/providers/jiraIssueLegacyAccessTokenProvider.js +62 -0
- package/dist/providers/jiraIssueLegacyAccessTokenProvider.js.map +1 -0
- package/dist/providers/jiraIssueLegacyProvider.d.ts +8 -0
- package/dist/providers/jiraIssueLegacyProvider.js +74 -0
- package/dist/providers/jiraIssueLegacyProvider.js.map +1 -0
- package/dist/providers/jiraIssueProvider.d.ts +11 -0
- package/dist/providers/jiraIssueProvider.js +96 -0
- package/dist/providers/jiraIssueProvider.js.map +1 -0
- package/dist/providers/text.d.ts +8 -0
- package/dist/providers/text.js +10 -0
- package/dist/providers/text.js.map +1 -0
- package/dist/providers/types.d.ts +21 -0
- package/dist/providers/types.js +2 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/systemUtils.d.ts +22 -0
- package/dist/systemUtils.js +36 -0
- package/dist/systemUtils.js.map +1 -0
- package/dist/utils.d.ts +49 -0
- package/{src → dist}/utils.js +73 -60
- package/dist/utils.js.map +1 -0
- package/docs/CONFIGURATION.md +95 -6
- package/docs/RELEASE-HOWTO.md +1 -1
- package/eslint.config.js +99 -21
- package/index.js +10 -27
- package/package.json +26 -15
- package/src/commands/askCommand.ts +34 -0
- package/src/commands/initCommand.ts +19 -0
- package/src/commands/reviewCommand.ts +209 -0
- package/src/config.ts +266 -0
- package/src/configs/anthropic.ts +55 -0
- package/src/configs/fake.ts +15 -0
- package/src/configs/groq.ts +54 -0
- package/src/configs/vertexai.ts +53 -0
- package/src/consoleUtils.ts +33 -0
- package/src/index.ts +21 -0
- package/src/modules/questionAnsweringModule.ts +97 -0
- package/src/modules/reviewModule.ts +81 -0
- package/src/modules/types.ts +23 -0
- package/src/prompt.ts +39 -0
- package/src/providers/file.ts +24 -0
- package/src/providers/ghPrDiffProvider.ts +20 -0
- package/src/providers/jiraIssueLegacyProvider.ts +103 -0
- package/src/providers/jiraIssueProvider.ts +133 -0
- package/src/providers/text.ts +14 -0
- package/src/providers/types.ts +24 -0
- package/src/systemUtils.ts +52 -0
- package/src/utils.ts +225 -0
- package/tsconfig.json +24 -0
- package/vitest.config.ts +13 -0
- package/.eslint.config.mjs +0 -72
- package/.github/dependabot.yml +0 -11
- package/.github/workflows/ci.yml +0 -33
- package/spec/.gsloth.config.js +0 -22
- package/spec/.gsloth.config.json +0 -25
- package/spec/askCommand.spec.js +0 -92
- package/spec/config.spec.js +0 -421
- package/spec/initCommand.spec.js +0 -55
- package/spec/predefinedConfigs.spec.js +0 -100
- package/spec/questionAnsweringModule.spec.js +0 -137
- package/spec/reviewCommand.spec.js +0 -222
- package/spec/reviewModule.spec.js +0 -28
- package/spec/support/jasmine.mjs +0 -14
- package/src/commands/askCommand.js +0 -27
- package/src/commands/initCommand.js +0 -17
- package/src/commands/reviewCommand.js +0 -154
- package/src/config.js +0 -177
- package/src/prompt.js +0 -34
- package/src/providers/file.js +0 -19
- package/src/providers/ghPrDiffProvider.js +0 -11
- package/src/providers/jiraIssueLegacyAccessTokenProvider.js +0 -84
- package/src/providers/text.js +0 -6
- package/src/systemUtils.js +0 -32
- /package/{.gsloth.preamble.internal.md → .gsloth.backstory.md} +0 -0
@@ -0,0 +1,96 @@
|
|
1
|
+
import { display, displayError, displayWarning } from '#src/consoleUtils.js';
|
2
|
+
import { env } from '#src/systemUtils.js';
|
3
|
+
/**
|
4
|
+
* Gets Jira issue using Atlassian REST API v3 with Personal Access Token
|
5
|
+
*
|
6
|
+
* TODO we need to figure out how would this work with public jira.
|
7
|
+
*
|
8
|
+
* @param config Jira configuration
|
9
|
+
* @param issueId Jira issue ID
|
10
|
+
* @returns Jira issue content
|
11
|
+
*/
|
12
|
+
export async function get(config, issueId) {
|
13
|
+
if (!config) {
|
14
|
+
displayWarning('No Jira config provided');
|
15
|
+
return null;
|
16
|
+
}
|
17
|
+
if (!issueId) {
|
18
|
+
displayWarning('No issue ID provided');
|
19
|
+
return null;
|
20
|
+
}
|
21
|
+
// Get username from environment variable or config
|
22
|
+
const username = env.JIRA_USERNAME || config.username;
|
23
|
+
if (!username) {
|
24
|
+
throw new Error('Missing JIRA username. The username can be defined as JIRA_USERNAME environment variable or as "username" in config.');
|
25
|
+
}
|
26
|
+
// Get token from environment variable or config
|
27
|
+
const token = env.JIRA_API_PAT_TOKEN || config.token;
|
28
|
+
if (!token) {
|
29
|
+
throw new Error('Missing JIRA PAT token. The token can be defined as JIRA_API_PAT_TOKEN environment variable or as "token" in config.');
|
30
|
+
}
|
31
|
+
// Get cloud ID from environment variable or config
|
32
|
+
const cloudId = env.JIRA_CLOUD_ID || config.cloudId;
|
33
|
+
if (!cloudId) {
|
34
|
+
throw new Error('Missing JIRA Cloud ID. The Cloud ID can be defined as JIRA_CLOUD_ID environment variable or as "cloudId" in config.');
|
35
|
+
}
|
36
|
+
try {
|
37
|
+
const issue = await getJiraIssue({
|
38
|
+
...config,
|
39
|
+
username,
|
40
|
+
token,
|
41
|
+
cloudId,
|
42
|
+
}, issueId);
|
43
|
+
if (!issue) {
|
44
|
+
return null;
|
45
|
+
}
|
46
|
+
const summary = issue.fields.summary;
|
47
|
+
const description = issue.fields.description;
|
48
|
+
return `Jira Issue: ${issueId}\nSummary: ${summary}\n\nDescription:\n${description}`;
|
49
|
+
}
|
50
|
+
catch (error) {
|
51
|
+
displayError(`Failed to get Jira issue: ${error instanceof Error ? error.message : String(error)}`);
|
52
|
+
return null;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
/**
|
56
|
+
* Helper function to get Jira issue details using Atlassian REST API v3
|
57
|
+
* @param config Jira configuration
|
58
|
+
* @param jiraKey Jira issue ID
|
59
|
+
* @returns Jira issue response
|
60
|
+
*/
|
61
|
+
async function getJiraIssue(config, jiraKey) {
|
62
|
+
// Jira Cloud ID can be found by authenticated user at https://company.atlassian.net/_edge/tenant_info
|
63
|
+
// According to doc https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/#api-rest-api-3-issue-issueidorkey-get permissions to read this resource:
|
64
|
+
// either Classic (RECOMMENDED) read:jira-work
|
65
|
+
// or Granular read:issue-meta:jira, read:issue-security-level:jira, read:issue.vote:jira, read:issue.changelog:jira, read:avatar:jira, read:issue:jira, read:status:jira, read:user:jira, read:field-configuration:jira
|
66
|
+
const apiUrl = `https://api.atlassian.com/ex/jira/${config.cloudId}/rest/api/3/issue/${jiraKey}`;
|
67
|
+
if (config.displayUrl) {
|
68
|
+
display(`Loading Jira issue ${config.displayUrl}${jiraKey}`);
|
69
|
+
}
|
70
|
+
display(`Retrieving jira from api ${apiUrl.replace(/^https?:\/\//, '')}`);
|
71
|
+
// Encode credentials for Basic Authentication header
|
72
|
+
const credentials = `${config.username}:${config.token}`;
|
73
|
+
const encodedCredentials = Buffer.from(credentials).toString('base64');
|
74
|
+
const authHeader = `Basic ${encodedCredentials}`;
|
75
|
+
// Define request headers
|
76
|
+
const headers = {
|
77
|
+
Authorization: authHeader,
|
78
|
+
Accept: 'application/json; charset=utf-8',
|
79
|
+
'Accept-Language': 'en-US,en;q=0.9', // Prevents errors in other languages
|
80
|
+
};
|
81
|
+
const response = await fetch(apiUrl, {
|
82
|
+
method: 'GET',
|
83
|
+
headers: headers,
|
84
|
+
});
|
85
|
+
if (!response?.ok) {
|
86
|
+
try {
|
87
|
+
const errorData = await response.json();
|
88
|
+
throw new Error(`Failed to fetch Jira issue: ${response.statusText} - ${JSON.stringify(errorData)}`);
|
89
|
+
}
|
90
|
+
catch (_e) {
|
91
|
+
throw new Error(`Failed to fetch Jira issue: ${response?.statusText}`);
|
92
|
+
}
|
93
|
+
}
|
94
|
+
return response.json();
|
95
|
+
}
|
96
|
+
//# sourceMappingURL=jiraIssueProvider.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"jiraIssueProvider.js","sourceRoot":"","sources":["../../src/providers/jiraIssueProvider.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import type { ProviderConfig } from './types.js';
|
2
|
+
/**
|
3
|
+
* Returns the provided text as is
|
4
|
+
* @param _ config (unused in this provider)
|
5
|
+
* @param text Text to return
|
6
|
+
* @returns The provided text
|
7
|
+
*/
|
8
|
+
export declare function get(_: ProviderConfig | null, text: string | undefined): Promise<string | null>;
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/providers/text.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,GAAG,CACvB,CAAwB,EACxB,IAAwB;IAExB,OAAO,IAAI,IAAI,IAAI,CAAC;AACtB,CAAC"}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
export interface ProviderConfig {
|
2
|
+
username?: string;
|
3
|
+
token?: string;
|
4
|
+
baseUrl?: string;
|
5
|
+
[key: string]: unknown;
|
6
|
+
}
|
7
|
+
export interface JiraLegacyConfig extends ProviderConfig {
|
8
|
+
username: string;
|
9
|
+
baseUrl: string;
|
10
|
+
displayUrl?: string;
|
11
|
+
token: string;
|
12
|
+
}
|
13
|
+
export interface JiraConfig extends ProviderConfig {
|
14
|
+
cloudId: string;
|
15
|
+
username: string;
|
16
|
+
displayUrl?: string;
|
17
|
+
token: string;
|
18
|
+
}
|
19
|
+
export interface Provider {
|
20
|
+
get: (config: ProviderConfig | null, id: string | undefined) => Promise<string | null>;
|
21
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":""}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
export declare const getCurrentDir: () => string;
|
2
|
+
export declare const getInstallDir: () => string;
|
3
|
+
export declare const exit: (code?: number) => never;
|
4
|
+
export declare const stdin: NodeJS.ReadStream & {
|
5
|
+
fd: 0;
|
6
|
+
};
|
7
|
+
export declare const stdout: NodeJS.WriteStream & {
|
8
|
+
fd: 1;
|
9
|
+
};
|
10
|
+
export declare const argv: string[];
|
11
|
+
export declare const env: NodeJS.ProcessEnv;
|
12
|
+
/**
|
13
|
+
* Provide the path to the entry point of the application.
|
14
|
+
* This is used to set the install directory.
|
15
|
+
* This is called from index.js root entry point.
|
16
|
+
*/
|
17
|
+
export declare const setEntryPoint: (indexJs: string) => void;
|
18
|
+
export declare const log: (message: string) => void;
|
19
|
+
export declare const error: (message: string) => void;
|
20
|
+
export declare const warn: (message: string) => void;
|
21
|
+
export declare const info: (message: string) => void;
|
22
|
+
export declare const debug: (message: string) => void;
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import { dirname, resolve } from 'node:path';
|
2
|
+
import { fileURLToPath } from 'url';
|
3
|
+
const innerState = {
|
4
|
+
installDir: undefined,
|
5
|
+
};
|
6
|
+
// Process-related functions and objects
|
7
|
+
export const getCurrentDir = () => process.cwd();
|
8
|
+
export const getInstallDir = () => {
|
9
|
+
if (innerState.installDir) {
|
10
|
+
return innerState.installDir;
|
11
|
+
}
|
12
|
+
throw new Error('Install directory not set');
|
13
|
+
};
|
14
|
+
export const exit = (code) => process.exit(code || 0);
|
15
|
+
export const stdin = process.stdin;
|
16
|
+
export const stdout = process.stdout;
|
17
|
+
export const argv = process.argv;
|
18
|
+
export const env = process.env;
|
19
|
+
// noinspection JSUnusedGlobalSymbols
|
20
|
+
/**
|
21
|
+
* Provide the path to the entry point of the application.
|
22
|
+
* This is used to set the install directory.
|
23
|
+
* This is called from index.js root entry point.
|
24
|
+
*/
|
25
|
+
export const setEntryPoint = (indexJs) => {
|
26
|
+
const filePath = fileURLToPath(indexJs);
|
27
|
+
const dirPath = dirname(filePath);
|
28
|
+
innerState.installDir = resolve(dirPath);
|
29
|
+
};
|
30
|
+
// Console-related functions
|
31
|
+
export const log = (message) => console.log(message);
|
32
|
+
export const error = (message) => console.error(message);
|
33
|
+
export const warn = (message) => console.warn(message);
|
34
|
+
export const info = (message) => console.info(message);
|
35
|
+
export const debug = (message) => console.debug(message);
|
36
|
+
//# sourceMappingURL=systemUtils.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"systemUtils.js","sourceRoot":"","sources":["../src/systemUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAepC,MAAM,UAAU,GAAe;IAC7B,UAAU,EAAE,SAAS;CACtB,CAAC;AAEF,wCAAwC;AACxC,MAAM,CAAC,MAAM,aAAa,GAAG,GAAW,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;AACzD,MAAM,CAAC,MAAM,aAAa,GAAG,GAAW,EAAE;IACxC,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;QAC1B,OAAO,UAAU,CAAC,UAAU,CAAC;IAC/B,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;AAC/C,CAAC,CAAC;AACF,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,IAAa,EAAS,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;AACtE,MAAM,CAAC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;AACnC,MAAM,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;AACrC,MAAM,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;AACjC,MAAM,CAAC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;AAE/B,qCAAqC;AACrC;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,OAAe,EAAQ,EAAE;IACrD,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAClC,UAAU,CAAC,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC3C,CAAC,CAAC;AAEF,4BAA4B;AAC5B,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,OAAe,EAAQ,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AACnE,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,OAAe,EAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AACvE,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,OAAe,EAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACrE,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,OAAe,EAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACrE,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,OAAe,EAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC"}
|
package/dist/utils.d.ts
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
import { SlothConfig } from '#src/config.js';
|
2
|
+
import { Command } from 'commander';
|
3
|
+
export declare function toFileSafeString(string: string): string;
|
4
|
+
export declare function fileSafeLocalDate(): string;
|
5
|
+
export declare function readFileFromCurrentDir(fileName: string): string;
|
6
|
+
export declare function writeFileIfNotExistsWithMessages(filePath: string, content: string): void;
|
7
|
+
export declare function readFileSyncWithMessages(filePath: string, errorMessageIn?: string, noFileMessage?: string): string;
|
8
|
+
export declare function readStdin(program: Command): Promise<void>;
|
9
|
+
export declare function spawnCommand(command: string, args: string[], progressMessage: string, successMessage: string): Promise<string>;
|
10
|
+
export declare function getSlothVersion(): string;
|
11
|
+
export declare class ProgressIndicator {
|
12
|
+
private hasBeenCalled;
|
13
|
+
private initialMessage;
|
14
|
+
constructor(initialMessage: string);
|
15
|
+
indicate(): void;
|
16
|
+
}
|
17
|
+
interface LLMOutput {
|
18
|
+
messages: Array<{
|
19
|
+
content: string;
|
20
|
+
}>;
|
21
|
+
}
|
22
|
+
/**
|
23
|
+
* Extracts the content of the last message from an LLM response
|
24
|
+
* @param output - The output from the LLM containing messages
|
25
|
+
* @returns The content of the last message
|
26
|
+
*/
|
27
|
+
export declare function extractLastMessageContent(output: LLMOutput): string;
|
28
|
+
/**
|
29
|
+
* Dynamically imports a module from a file path from the outside of the installation dir
|
30
|
+
* @param filePath - The path to the file to import
|
31
|
+
* @returns A promise that resolves to the imported module
|
32
|
+
*/
|
33
|
+
export declare function importExternalFile(filePath: string): Promise<{
|
34
|
+
configure: (module: string) => Promise<Partial<SlothConfig>>;
|
35
|
+
}>;
|
36
|
+
/**
|
37
|
+
* Alias for importExternalFile for backward compatibility with tests
|
38
|
+
* @param filePath - The path to the file to import
|
39
|
+
* @returns A promise that resolves to the imported module
|
40
|
+
*/
|
41
|
+
export declare const importFromFilePath: typeof importExternalFile;
|
42
|
+
/**
|
43
|
+
* Reads multiple files from the current directory and returns their contents
|
44
|
+
* @param fileNames - Array of file names to read
|
45
|
+
* @returns Combined content of all files with proper formatting
|
46
|
+
*/
|
47
|
+
export declare function readMultipleFilesFromCurrentDir(fileNames: string | string[]): string;
|
48
|
+
export declare function execAsync(command: string): Promise<string>;
|
49
|
+
export {};
|
package/{src → dist}/utils.js
RENAMED
@@ -1,90 +1,89 @@
|
|
1
|
-
import {display, displayError, displaySuccess, displayWarning} from
|
2
|
-
import {existsSync, readFileSync, writeFileSync} from
|
3
|
-
import {slothContext} from
|
4
|
-
import {resolve} from
|
5
|
-
import {spawn} from
|
6
|
-
import {exit, stdin, stdout, argv} from
|
7
|
-
import url from
|
8
|
-
|
1
|
+
import { display, displayError, displaySuccess, displayWarning } from '#src/consoleUtils.js';
|
2
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
3
|
+
import { slothContext } from '#src/config.js';
|
4
|
+
import { resolve } from 'node:path';
|
5
|
+
import { spawn } from 'node:child_process';
|
6
|
+
import { exit, stdin, stdout, argv, getCurrentDir, getInstallDir } from '#src/systemUtils.js';
|
7
|
+
import url from 'node:url';
|
9
8
|
export function toFileSafeString(string) {
|
10
9
|
return string.replace(/[^A-Za-z0-9]/g, '-');
|
11
10
|
}
|
12
|
-
|
13
11
|
export function fileSafeLocalDate() {
|
14
12
|
const date = new Date();
|
15
13
|
const offsetMs = date.getTimezoneOffset() * 60 * 1000;
|
16
|
-
const msLocal =
|
14
|
+
const msLocal = date.getTime() - offsetMs;
|
17
15
|
const dateLocal = new Date(msLocal);
|
18
16
|
const iso = dateLocal.toISOString();
|
19
17
|
const isoLocal = iso.slice(0, 19);
|
20
18
|
return toFileSafeString(isoLocal);
|
21
19
|
}
|
22
|
-
|
23
20
|
export function readFileFromCurrentDir(fileName) {
|
24
|
-
const
|
21
|
+
const currentDir = getCurrentDir();
|
22
|
+
const filePath = resolve(currentDir, fileName);
|
25
23
|
display(`Reading file ${fileName}...`);
|
26
24
|
return readFileSyncWithMessages(filePath);
|
27
25
|
}
|
28
|
-
|
29
26
|
export function writeFileIfNotExistsWithMessages(filePath, content) {
|
30
27
|
display(`checking ${filePath} existence`);
|
31
28
|
if (!existsSync(filePath)) {
|
32
29
|
writeFileSync(filePath, content);
|
33
30
|
displaySuccess(`Created ${filePath}`);
|
34
|
-
}
|
31
|
+
}
|
32
|
+
else {
|
35
33
|
displayWarning(`${filePath} already exists`);
|
36
34
|
}
|
37
35
|
}
|
38
|
-
|
39
36
|
export function readFileSyncWithMessages(filePath, errorMessageIn, noFileMessage) {
|
40
37
|
const errorMessage = errorMessageIn ?? 'Error reading file at: ';
|
41
38
|
try {
|
42
39
|
return readFileSync(filePath, { encoding: 'utf8' });
|
43
|
-
}
|
40
|
+
}
|
41
|
+
catch (error) {
|
44
42
|
displayError(errorMessage + filePath);
|
45
43
|
if (error.code === 'ENOENT') {
|
46
44
|
displayWarning(noFileMessage ?? 'Please ensure the file exists.');
|
47
|
-
}
|
45
|
+
}
|
46
|
+
else {
|
48
47
|
displayError(error.message);
|
49
48
|
}
|
50
49
|
exit(1); // Exit gracefully after error
|
50
|
+
throw error; // This line will never be reached due to exit(1), but satisfies TypeScript
|
51
51
|
}
|
52
52
|
}
|
53
|
-
|
54
53
|
export function readStdin(program) {
|
55
|
-
return new Promise((
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
54
|
+
return new Promise((resolvePromise) => {
|
55
|
+
if (stdin.isTTY) {
|
56
|
+
program.parseAsync().then(() => resolvePromise());
|
57
|
+
}
|
58
|
+
else {
|
60
59
|
// Support piping diff into gsloth
|
61
|
-
|
62
|
-
|
60
|
+
const progressIndicator = new ProgressIndicator('reading STDIN');
|
61
|
+
progressIndicator.indicate();
|
62
|
+
stdin.on('readable', function () {
|
63
63
|
const chunk = this.read();
|
64
|
-
|
64
|
+
progressIndicator.indicate();
|
65
65
|
if (chunk !== null) {
|
66
|
-
|
66
|
+
const chunkStr = chunk.toString('utf8');
|
67
|
+
slothContext.stdin = slothContext.stdin + chunkStr;
|
67
68
|
}
|
68
69
|
});
|
69
|
-
stdin.on('end', function() {
|
70
|
-
|
71
|
-
program.parseAsync(argv).then(resolve);
|
70
|
+
stdin.on('end', function () {
|
71
|
+
program.parseAsync(argv).then(() => resolvePromise());
|
72
72
|
});
|
73
73
|
}
|
74
74
|
});
|
75
75
|
}
|
76
|
-
|
77
76
|
export async function spawnCommand(command, args, progressMessage, successMessage) {
|
78
77
|
return new Promise((resolve, reject) => {
|
79
|
-
|
80
|
-
const out = {stdout: '', stderr: ''};
|
78
|
+
const progressIndicator = new ProgressIndicator(progressMessage);
|
79
|
+
const out = { stdout: '', stderr: '' };
|
81
80
|
const spawned = spawn(command, args);
|
82
81
|
spawned.stdout.on('data', async (stdoutChunk) => {
|
83
|
-
|
82
|
+
progressIndicator.indicate();
|
84
83
|
out.stdout += stdoutChunk.toString();
|
85
84
|
});
|
86
85
|
spawned.stderr.on('data', (err) => {
|
87
|
-
|
86
|
+
progressIndicator.indicate();
|
88
87
|
out.stderr += err.toString();
|
89
88
|
});
|
90
89
|
spawned.on('error', (err) => {
|
@@ -94,43 +93,42 @@ export async function spawnCommand(command, args, progressMessage, successMessag
|
|
94
93
|
if (code === 0) {
|
95
94
|
display(successMessage);
|
96
95
|
resolve(out.stdout);
|
97
|
-
}
|
96
|
+
}
|
97
|
+
else {
|
98
98
|
displayError(`Failed to spawn command with code ${code}`);
|
99
99
|
reject(out.stdout + ' ' + out.stderr);
|
100
100
|
}
|
101
101
|
});
|
102
102
|
});
|
103
103
|
}
|
104
|
-
|
105
104
|
export function getSlothVersion() {
|
106
|
-
|
105
|
+
// TODO figure out if this can be injected with TS
|
106
|
+
const installDir = getInstallDir();
|
107
|
+
const jsonPath = resolve(installDir, 'package.json');
|
107
108
|
const projectJson = readFileSync(jsonPath, { encoding: 'utf8' });
|
108
109
|
return JSON.parse(projectJson).version;
|
109
110
|
}
|
110
|
-
|
111
|
-
|
112
111
|
export class ProgressIndicator {
|
113
|
-
|
112
|
+
hasBeenCalled;
|
113
|
+
initialMessage;
|
114
114
|
constructor(initialMessage) {
|
115
115
|
this.hasBeenCalled = false;
|
116
116
|
this.initialMessage = initialMessage;
|
117
117
|
}
|
118
|
-
|
119
118
|
indicate() {
|
120
119
|
if (this.hasBeenCalled) {
|
121
120
|
stdout.write('.');
|
122
|
-
}
|
121
|
+
}
|
122
|
+
else {
|
123
123
|
this.hasBeenCalled = true;
|
124
124
|
stdout.write(this.initialMessage);
|
125
125
|
}
|
126
126
|
}
|
127
|
-
|
128
127
|
}
|
129
|
-
|
130
128
|
/**
|
131
129
|
* Extracts the content of the last message from an LLM response
|
132
|
-
* @param
|
133
|
-
* @returns
|
130
|
+
* @param output - The output from the LLM containing messages
|
131
|
+
* @returns The content of the last message
|
134
132
|
*/
|
135
133
|
export function extractLastMessageContent(output) {
|
136
134
|
if (!output || !output.messages || !output.messages.length) {
|
@@ -138,36 +136,51 @@ export function extractLastMessageContent(output) {
|
|
138
136
|
}
|
139
137
|
return output.messages[output.messages.length - 1].content;
|
140
138
|
}
|
141
|
-
|
142
139
|
/**
|
143
140
|
* Dynamically imports a module from a file path from the outside of the installation dir
|
144
|
-
* @param
|
145
|
-
* @returns
|
141
|
+
* @param filePath - The path to the file to import
|
142
|
+
* @returns A promise that resolves to the imported module
|
146
143
|
*/
|
147
144
|
export function importExternalFile(filePath) {
|
148
|
-
const configFileUrl = url.pathToFileURL(filePath);
|
145
|
+
const configFileUrl = url.pathToFileURL(filePath).toString();
|
149
146
|
return import(configFileUrl);
|
150
147
|
}
|
151
|
-
|
152
148
|
/**
|
153
149
|
* Alias for importExternalFile for backward compatibility with tests
|
154
|
-
* @param
|
155
|
-
* @returns
|
150
|
+
* @param filePath - The path to the file to import
|
151
|
+
* @returns A promise that resolves to the imported module
|
156
152
|
*/
|
157
153
|
export const importFromFilePath = importExternalFile;
|
158
|
-
|
159
154
|
/**
|
160
155
|
* Reads multiple files from the current directory and returns their contents
|
161
|
-
* @param
|
162
|
-
* @returns
|
156
|
+
* @param fileNames - Array of file names to read
|
157
|
+
* @returns Combined content of all files with proper formatting
|
163
158
|
*/
|
164
159
|
export function readMultipleFilesFromCurrentDir(fileNames) {
|
165
160
|
if (!Array.isArray(fileNames)) {
|
166
161
|
return readFileFromCurrentDir(fileNames);
|
167
162
|
}
|
168
|
-
|
169
|
-
|
163
|
+
return fileNames
|
164
|
+
.map((fileName) => {
|
170
165
|
const content = readFileFromCurrentDir(fileName);
|
171
166
|
return `${fileName}:\n\`\`\`\n${content}\n\`\`\``;
|
172
|
-
})
|
167
|
+
})
|
168
|
+
.join('\n\n');
|
169
|
+
}
|
170
|
+
export async function execAsync(command) {
|
171
|
+
const { exec } = await import('node:child_process');
|
172
|
+
return new Promise((resolve, reject) => {
|
173
|
+
exec(command, (error, stdout, stderr) => {
|
174
|
+
if (error) {
|
175
|
+
reject(error);
|
176
|
+
return;
|
177
|
+
}
|
178
|
+
if (stderr) {
|
179
|
+
reject(new Error(stderr));
|
180
|
+
return;
|
181
|
+
}
|
182
|
+
resolve(stdout.trim());
|
183
|
+
});
|
184
|
+
});
|
173
185
|
}
|
186
|
+
//# sourceMappingURL=utils.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
|