gaunt-sloth-assistant 0.1.5 → 0.3.0
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/{.gsloth.preamble.review.md → .gsloth.guidelines.md} +0 -8
- package/.gsloth.review.md +7 -0
- 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 +27 -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 +142 -0
- package/dist/commands/reviewCommand.js.map +1 -0
- package/dist/config.d.ts +84 -0
- package/dist/config.js +180 -0
- package/dist/config.js.map +1 -0
- package/dist/configs/anthropic.d.ts +4 -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 +26 -0
- package/dist/index.js.map +1 -0
- package/dist/llmUtils.d.ts +4 -0
- package/dist/llmUtils.js +39 -0
- package/dist/llmUtils.js.map +1 -0
- package/dist/modules/questionAnsweringModule.d.ts +7 -0
- package/dist/modules/questionAnsweringModule.js +33 -0
- package/dist/modules/questionAnsweringModule.js.map +1 -0
- package/dist/modules/reviewModule.d.ts +1 -0
- package/dist/modules/reviewModule.js +29 -0
- 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 +8 -0
- package/dist/prompt.js +45 -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 +32 -0
- package/dist/systemUtils.js +70 -0
- package/dist/systemUtils.js.map +1 -0
- package/dist/utils.d.ts +49 -0
- package/dist/utils.js +192 -0
- package/dist/utils.js.map +1 -0
- package/docs/CONFIGURATION.md +99 -10
- package/docs/RELEASE-HOWTO.md +7 -1
- package/eslint.config.js +99 -21
- package/gth-ASK-2025-05-16T14-11-39.md +3 -0
- package/gth-ASK-2025-05-16T14-18-27.md +3 -0
- package/gth-ASK-2025-05-16T14-18-56.md +1 -0
- package/gth-ASK-2025-05-16T14-41-20.md +3 -0
- package/gth-ASK-2025-05-16T14-43-31.md +51 -0
- package/gth-ASK-2025-05-16T16-05-52.md +62 -0
- package/gth-DIFF-review-2025-05-16T16-07-53.md +56 -0
- package/gth-DIFF-review-2025-05-16T16-18-55.md +292 -0
- package/index.js +10 -27
- package/package.json +26 -15
- package/src/commands/askCommand.ts +35 -0
- package/src/commands/initCommand.ts +19 -0
- package/src/commands/reviewCommand.ts +223 -0
- package/src/config.ts +269 -0
- package/src/configs/anthropic.ts +57 -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 +30 -0
- package/src/llmUtils.ts +54 -0
- package/src/modules/questionAnsweringModule.ts +44 -0
- package/src/modules/reviewModule.ts +31 -0
- package/src/modules/types.ts +23 -0
- package/src/prompt.ts +54 -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 +90 -0
- package/src/utils.ts +232 -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/modules/questionAnsweringModule.js +0 -82
- package/src/modules/reviewModule.js +0 -70
- 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/src/utils.js +0 -173
- /package/{.gsloth.preamble.internal.md → .gsloth.backstory.md} +0 -0
@@ -1,33 +1,28 @@
|
|
1
1
|
import chalk from 'chalk';
|
2
|
-
import {debug as systemDebug, error as systemError, log} from '
|
3
|
-
|
2
|
+
import { debug as systemDebug, error as systemError, log } from '#src/systemUtils.js';
|
4
3
|
// TODO it seems like commander supports coloured output, maybe dependency to chalk can be removed
|
5
|
-
|
6
|
-
export function displayError (message) {
|
4
|
+
export function displayError(message) {
|
7
5
|
systemError(chalk.red(message));
|
8
6
|
}
|
9
|
-
|
10
|
-
export function displayWarning (message) {
|
7
|
+
export function displayWarning(message) {
|
11
8
|
systemError(chalk.yellow(message));
|
12
9
|
}
|
13
|
-
|
14
|
-
export function displaySuccess (message) {
|
10
|
+
export function displaySuccess(message) {
|
15
11
|
systemError(chalk.green(message));
|
16
12
|
}
|
17
|
-
|
18
|
-
export function displayInfo (message) {
|
13
|
+
export function displayInfo(message) {
|
19
14
|
systemError(chalk.blue(message));
|
20
15
|
}
|
21
|
-
|
22
16
|
export function display(message) {
|
23
17
|
log(message);
|
24
18
|
}
|
25
|
-
|
26
19
|
export function displayDebug(message) {
|
27
20
|
// TODO make it controlled by config
|
28
|
-
if (message
|
29
|
-
systemDebug(message.stack);
|
30
|
-
}
|
21
|
+
if (message instanceof Error) {
|
22
|
+
systemDebug(message.stack || '');
|
23
|
+
}
|
24
|
+
else if (message !== undefined) {
|
31
25
|
systemDebug(message);
|
32
26
|
}
|
33
27
|
}
|
28
|
+
//# sourceMappingURL=consoleUtils.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"consoleUtils.js","sourceRoot":"","sources":["../src/consoleUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,KAAK,IAAI,WAAW,EAAE,KAAK,IAAI,WAAW,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAEtF,kGAAkG;AAElG,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,OAAe;IACrC,GAAG,CAAC,OAAO,CAAC,CAAC;AACf,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAmC;IAC9D,oCAAoC;IACpC,IAAI,OAAO,YAAY,KAAK,EAAE,CAAC;QAC7B,WAAW,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IACnC,CAAC;SAAM,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QACjC,WAAW,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
package/dist/index.js
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
import { Command } from 'commander';
|
2
|
+
import { askCommand } from '#src/commands/askCommand.js';
|
3
|
+
import { initCommand } from '#src/commands/initCommand.js';
|
4
|
+
import { reviewCommand } from '#src/commands/reviewCommand.js';
|
5
|
+
import { slothContext } from '#src/config.js';
|
6
|
+
import { getSlothVersion } from '#src/utils.js';
|
7
|
+
import { argv, readStdin } from '#src/systemUtils.js';
|
8
|
+
import { setVerbose } from '#src/llmUtils.js';
|
9
|
+
const program = new Command();
|
10
|
+
program
|
11
|
+
.name('gsloth')
|
12
|
+
.description('Gaunt Sloth Assistant reviewing your PRs')
|
13
|
+
.version(getSlothVersion())
|
14
|
+
.option('--verbose', 'Print entire prompt sent to LLM.');
|
15
|
+
// Parse global options before binding any commands
|
16
|
+
program.parseOptions(argv);
|
17
|
+
if (program.getOptionValue('verbose')) {
|
18
|
+
// Set global prompt debug
|
19
|
+
setVerbose(true);
|
20
|
+
}
|
21
|
+
initCommand(program);
|
22
|
+
reviewCommand(program, slothContext);
|
23
|
+
askCommand(program);
|
24
|
+
// TODO add general interactive chat command
|
25
|
+
await readStdin(program);
|
26
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CAAC,0CAA0C,CAAC;KACvD,OAAO,CAAC,eAAe,EAAE,CAAC;KAC1B,MAAM,CAAC,WAAW,EAAE,kCAAkC,CAAC,CAAC;AAE3D,mDAAmD;AACnD,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;AAC3B,IAAI,OAAO,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,CAAC;IACtC,0BAA0B;IAC1B,UAAU,CAAC,IAAI,CAAC,CAAC;AACnB,CAAC;AAED,WAAW,CAAC,OAAO,CAAC,CAAC;AACrB,aAAa,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;AACrC,UAAU,CAAC,OAAO,CAAC,CAAC;AACpB,4CAA4C;AAE5C,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC"}
|
@@ -0,0 +1,4 @@
|
|
1
|
+
import { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
2
|
+
import { BaseLanguageModelCallOptions } from '@langchain/core/language_models/base';
|
3
|
+
export declare function invoke(llm: BaseChatModel, options: Partial<BaseLanguageModelCallOptions>, systemMessage: string, prompt: string): Promise<string>;
|
4
|
+
export declare function setVerbose(debug: boolean): void;
|
package/dist/llmUtils.js
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
import { HumanMessage, SystemMessage } from '@langchain/core/messages';
|
2
|
+
import { END, MemorySaver, MessagesAnnotation, START, StateGraph } from '@langchain/langgraph';
|
3
|
+
const llmGlobalSettings = {
|
4
|
+
verbose: false,
|
5
|
+
};
|
6
|
+
export async function invoke(llm, options, systemMessage, prompt) {
|
7
|
+
if (llmGlobalSettings.verbose) {
|
8
|
+
llm.verbose = true;
|
9
|
+
}
|
10
|
+
// This node receives the current state (messages) and invokes the LLM
|
11
|
+
const callModel = async (state) => {
|
12
|
+
// state.messages will contain the list including the system systemMessage and user diff
|
13
|
+
const response = await llm.invoke(state.messages);
|
14
|
+
// MessagesAnnotation expects the node to return the new message(s) to be added to the state.
|
15
|
+
// Wrap the response in an array if it's a single message object.
|
16
|
+
return { messages: response };
|
17
|
+
};
|
18
|
+
// Define the graph structure with MessagesAnnotation state
|
19
|
+
const workflow = new StateGraph(MessagesAnnotation)
|
20
|
+
// Define the node and edge
|
21
|
+
.addNode('model', callModel)
|
22
|
+
.addEdge(START, 'model') // Start at the 'model' node
|
23
|
+
.addEdge('model', END); // End after the 'model' node completes
|
24
|
+
// Set up memory (optional but good practice for potential future multi-turn interactions)
|
25
|
+
const memory = new MemorySaver();
|
26
|
+
// Compile the workflow into a runnable app
|
27
|
+
const app = workflow.compile({ checkpointer: memory });
|
28
|
+
// Construct the initial the messages including the systemMessage as a system message
|
29
|
+
const messages = [new SystemMessage(systemMessage), new HumanMessage(prompt)];
|
30
|
+
const output = await app.invoke({ messages }, options);
|
31
|
+
const lastMessage = output.messages[output.messages.length - 1];
|
32
|
+
return typeof lastMessage.content === 'string'
|
33
|
+
? lastMessage.content
|
34
|
+
: JSON.stringify(lastMessage.content);
|
35
|
+
}
|
36
|
+
export function setVerbose(debug) {
|
37
|
+
llmGlobalSettings.verbose = debug;
|
38
|
+
}
|
39
|
+
//# sourceMappingURL=llmUtils.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"llmUtils.js","sourceRoot":"","sources":["../src/llmUtils.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEvF,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,kBAAkB,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAG/F,MAAM,iBAAiB,GAAG;IACxB,OAAO,EAAE,KAAK;CACf,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,GAAkB,EAClB,OAA8C,EAC9C,aAAqB,EACrB,MAAc;IAEd,IAAI,iBAAiB,CAAC,OAAO,EAAE,CAAC;QAC9B,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC;IACrB,CAAC;IACD,sEAAsE;IACtE,MAAM,SAAS,GAAG,KAAK,EAAE,KAAY,EAAyC,EAAE;QAC9E,wFAAwF;QACxF,MAAM,QAAQ,GAAG,MAAO,GAAqB,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACrE,6FAA6F;QAC7F,iEAAiE;QACjE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;IAChC,CAAC,CAAC;IAEF,2DAA2D;IAC3D,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,kBAAkB,CAAC;QACjD,2BAA2B;SAC1B,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC;SAC3B,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,4BAA4B;SACpD,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,uCAAuC;IAEjE,0FAA0F;IAC1F,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;IAEjC,2CAA2C;IAC3C,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC;IAEvD,qFAAqF;IACrF,MAAM,QAAQ,GAAc,CAAC,IAAI,aAAa,CAAC,aAAa,CAAC,EAAE,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;IAEzF,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC;IACvD,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAChE,OAAO,OAAO,WAAW,CAAC,OAAO,KAAK,QAAQ;QAC5C,CAAC,CAAC,WAAW,CAAC,OAAO;QACrB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,iBAAiB,CAAC,OAAO,GAAG,KAAK,CAAC;AACpC,CAAC"}
|
@@ -0,0 +1,7 @@
|
|
1
|
+
/**
|
2
|
+
* Ask a question and get an answer from the LLM
|
3
|
+
* @param source - The source of the question (used for file naming)
|
4
|
+
* @param preamble - The preamble to send to the LLM
|
5
|
+
* @param content - The content of the question
|
6
|
+
*/
|
7
|
+
export declare function askQuestion(source: string, preamble: string, content: string): Promise<void>;
|
@@ -0,0 +1,33 @@
|
|
1
|
+
import { slothContext } from '#src/config.js';
|
2
|
+
import { display, displayError, displaySuccess } from '#src/consoleUtils.js';
|
3
|
+
import { getCurrentDir } from '#src/systemUtils.js';
|
4
|
+
import { fileSafeLocalDate, ProgressIndicator, toFileSafeString } from '#src/utils.js';
|
5
|
+
import { writeFileSync } from 'node:fs';
|
6
|
+
import * as path from 'node:path';
|
7
|
+
import { invoke } from '#src/llmUtils.js';
|
8
|
+
/**
|
9
|
+
* Ask a question and get an answer from the LLM
|
10
|
+
* @param source - The source of the question (used for file naming)
|
11
|
+
* @param preamble - The preamble to send to the LLM
|
12
|
+
* @param content - The content of the question
|
13
|
+
*/
|
14
|
+
export async function askQuestion(source, preamble, content) {
|
15
|
+
const progressIndicator = new ProgressIndicator('Thinking.');
|
16
|
+
const outputContent = await invoke(slothContext.config.llm, slothContext.session, preamble, content);
|
17
|
+
progressIndicator.stop();
|
18
|
+
const filePath = path.resolve(getCurrentDir(), toFileSafeString(source) + '-' + fileSafeLocalDate() + '.md');
|
19
|
+
display(`\nwriting ${filePath}`);
|
20
|
+
// TODO highlight LLM output with something like Prism.JS (maybe system emoj are enough ✅⚠️❌)
|
21
|
+
display('\n' + outputContent);
|
22
|
+
try {
|
23
|
+
writeFileSync(filePath, outputContent);
|
24
|
+
displaySuccess(`This report can be found in ${filePath}`);
|
25
|
+
}
|
26
|
+
catch (error) {
|
27
|
+
displayError(`Failed to write answer to file: ${filePath}`);
|
28
|
+
displayError(error instanceof Error ? error.message : String(error));
|
29
|
+
// TODO Consider if we want to exit or just log the error
|
30
|
+
// exit(1);
|
31
|
+
}
|
32
|
+
}
|
33
|
+
//# sourceMappingURL=questionAnsweringModule.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"questionAnsweringModule.js","sourceRoot":"","sources":["../../src/modules/questionAnsweringModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACvF,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAc,EACd,QAAgB,EAChB,OAAe;IAEf,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAC7D,MAAM,aAAa,GAAG,MAAM,MAAM,CAChC,YAAY,CAAC,MAAM,CAAC,GAAG,EACvB,YAAY,CAAC,OAAO,EACpB,QAAQ,EACR,OAAO,CACR,CAAC;IACF,iBAAiB,CAAC,IAAI,EAAE,CAAC;IACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAC3B,aAAa,EAAE,EACf,gBAAgB,CAAC,MAAM,CAAC,GAAG,GAAG,GAAG,iBAAiB,EAAE,GAAG,KAAK,CAC7D,CAAC;IACF,OAAO,CAAC,aAAa,QAAQ,EAAE,CAAC,CAAC;IACjC,6FAA6F;IAC7F,OAAO,CAAC,IAAI,GAAG,aAAa,CAAC,CAAC;IAC9B,IAAI,CAAC;QACH,aAAa,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QACvC,cAAc,CAAC,+BAA+B,QAAQ,EAAE,CAAC,CAAC;IAC5D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,YAAY,CAAC,mCAAmC,QAAQ,EAAE,CAAC,CAAC;QAC5D,YAAY,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACrE,yDAAyD;QACzD,WAAW;IACb,CAAC;AACH,CAAC"}
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare function review(source: string, preamble: string, diff: string): Promise<void>;
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import { slothContext } from '#src/config.js';
|
2
|
+
import { display, displayDebug, displayError, displaySuccess } from '#src/consoleUtils.js';
|
3
|
+
import { getCurrentDir, stdout } from '#src/systemUtils.js';
|
4
|
+
import { fileSafeLocalDate, ProgressIndicator, toFileSafeString } from '#src/utils.js';
|
5
|
+
import { writeFileSync } from 'node:fs';
|
6
|
+
import path from 'node:path';
|
7
|
+
import { invoke } from '#src/llmUtils.js';
|
8
|
+
export async function review(source, preamble, diff) {
|
9
|
+
const progressIndicator = new ProgressIndicator('Reviewing.');
|
10
|
+
const outputContent = await invoke(slothContext.config.llm, slothContext.session, preamble, diff);
|
11
|
+
progressIndicator.stop();
|
12
|
+
const filePath = path.resolve(getCurrentDir(), toFileSafeString(source) + '-' + fileSafeLocalDate() + '.md');
|
13
|
+
stdout.write('\n');
|
14
|
+
display(`writing ${filePath}`);
|
15
|
+
stdout.write('\n');
|
16
|
+
// TODO highlight LLM output with something like Prism.JS (maybe system emoj are enough ✅⚠️❌)
|
17
|
+
display(outputContent);
|
18
|
+
try {
|
19
|
+
writeFileSync(filePath, outputContent);
|
20
|
+
displaySuccess(`This report can be found in ${filePath}`);
|
21
|
+
}
|
22
|
+
catch (error) {
|
23
|
+
displayDebug(error instanceof Error ? error : String(error));
|
24
|
+
displayError(`Failed to write review to file: ${filePath}`);
|
25
|
+
// Consider if you want to exit or just log the error
|
26
|
+
// exit(1);
|
27
|
+
}
|
28
|
+
}
|
29
|
+
//# sourceMappingURL=reviewModule.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"reviewModule.js","sourceRoot":"","sources":["../../src/modules/reviewModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3F,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACvF,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,MAAc,EAAE,QAAgB,EAAE,IAAY;IACzE,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAC9D,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAClG,iBAAiB,CAAC,IAAI,EAAE,CAAC;IACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAC3B,aAAa,EAAE,EACf,gBAAgB,CAAC,MAAM,CAAC,GAAG,GAAG,GAAG,iBAAiB,EAAE,GAAG,KAAK,CAC7D,CAAC;IACF,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnB,OAAO,CAAC,WAAW,QAAQ,EAAE,CAAC,CAAC;IAC/B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnB,6FAA6F;IAC7F,OAAO,CAAC,aAAa,CAAC,CAAC;IACvB,IAAI,CAAC;QACH,aAAa,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QACvC,cAAc,CAAC,+BAA+B,QAAQ,EAAE,CAAC,CAAC;IAC5D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,YAAY,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC7D,YAAY,CAAC,mCAAmC,QAAQ,EAAE,CAAC,CAAC;QAC5D,qDAAqD;QACrD,WAAW;IACb,CAAC;AACH,CAAC"}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import type { BaseMessage } from '@langchain/core/messages';
|
2
|
+
export type Message = BaseMessage;
|
3
|
+
export interface State {
|
4
|
+
messages: Message[];
|
5
|
+
}
|
6
|
+
export interface ProgressCallback {
|
7
|
+
(): void;
|
8
|
+
}
|
9
|
+
export interface ReviewOptions {
|
10
|
+
source: string;
|
11
|
+
preamble: string;
|
12
|
+
diff: string;
|
13
|
+
}
|
14
|
+
export interface QuestionOptions {
|
15
|
+
source: string;
|
16
|
+
preamble: string;
|
17
|
+
content: string;
|
18
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/modules/types.ts"],"names":[],"mappings":""}
|
package/dist/prompt.d.ts
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
export declare function readBackstory(): string;
|
2
|
+
export declare function readGuidelines(guidelinesFilename: string): string;
|
3
|
+
export declare function readReviewInstructions(reviewInstructions: string): string;
|
4
|
+
/**
|
5
|
+
* This function expects https://cli.github.com/ to be installed and authenticated.
|
6
|
+
* It does something like `gh pr diff 42`
|
7
|
+
*/
|
8
|
+
export declare function getPrDiff(pr: string): Promise<string>;
|
package/dist/prompt.js
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
import { readFileFromCurrentDir, readFileFromCurrentOrInstallDir, spawnCommand, } from '#src/utils.js';
|
2
|
+
import { displayError } from '#src/consoleUtils.js';
|
3
|
+
import { exit } from '#src/systemUtils.js';
|
4
|
+
import { GSLOTH_BACKSTORY } from '#src/config.js';
|
5
|
+
export function readBackstory() {
|
6
|
+
return readFileFromCurrentOrInstallDir(GSLOTH_BACKSTORY, true);
|
7
|
+
}
|
8
|
+
export function readGuidelines(guidelinesFilename) {
|
9
|
+
try {
|
10
|
+
return readFileFromCurrentDir(guidelinesFilename);
|
11
|
+
}
|
12
|
+
catch (error) {
|
13
|
+
displayError('Consider running `gsloth init` to set up your project. Check `gsloth init --help` to see options.');
|
14
|
+
throw error;
|
15
|
+
}
|
16
|
+
}
|
17
|
+
export function readReviewInstructions(reviewInstructions) {
|
18
|
+
return readConfigPromptFile(reviewInstructions);
|
19
|
+
}
|
20
|
+
function readConfigPromptFile(guidelinesFilename) {
|
21
|
+
try {
|
22
|
+
return readFileFromCurrentOrInstallDir(guidelinesFilename);
|
23
|
+
}
|
24
|
+
catch (error) {
|
25
|
+
displayError('Consider running `gsloth init` to set up your project. Check `gsloth init --help` to see options.');
|
26
|
+
throw error;
|
27
|
+
}
|
28
|
+
}
|
29
|
+
/**
|
30
|
+
* This function expects https://cli.github.com/ to be installed and authenticated.
|
31
|
+
* It does something like `gh pr diff 42`
|
32
|
+
*/
|
33
|
+
export async function getPrDiff(pr) {
|
34
|
+
// TODO makes sense to check if gh is available and authenticated
|
35
|
+
try {
|
36
|
+
return await spawnCommand('gh', ['pr', 'diff', pr], 'Loading PR diff...', 'Loaded PR diff.');
|
37
|
+
}
|
38
|
+
catch (e) {
|
39
|
+
displayError(e instanceof Error ? e.toString() : String(e));
|
40
|
+
displayError(`Failed to call "gh pr diff ${pr}", see message above for details.`);
|
41
|
+
exit();
|
42
|
+
return ''; // This line will never be reached due to exit()
|
43
|
+
}
|
44
|
+
}
|
45
|
+
//# sourceMappingURL=prompt.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,+BAA+B,EAC/B,YAAY,GACb,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,UAAU,aAAa;IAC3B,OAAO,+BAA+B,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,kBAA0B;IACvD,IAAI,CAAC;QACH,OAAO,sBAAsB,CAAC,kBAAkB,CAAC,CAAC;IACpD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,YAAY,CACV,mGAAmG,CACpG,CAAC;QACF,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,kBAA0B;IAC/D,OAAO,oBAAoB,CAAC,kBAAkB,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,oBAAoB,CAAC,kBAA0B;IACtD,IAAI,CAAC;QACH,OAAO,+BAA+B,CAAC,kBAAkB,CAAC,CAAC;IAC7D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,YAAY,CACV,mGAAmG,CACpG,CAAC;QACF,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,EAAU;IACxC,iEAAiE;IACjE,IAAI,CAAC;QACH,OAAO,MAAM,YAAY,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,oBAAoB,EAAE,iBAAiB,CAAC,CAAC;IAC/F,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,YAAY,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,YAAY,CAAC,8BAA8B,EAAE,mCAAmC,CAAC,CAAC;QAClF,IAAI,EAAE,CAAC;QACP,OAAO,EAAE,CAAC,CAAC,gDAAgD;IAC7D,CAAC;AACH,CAAC"}
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import type { ProviderConfig } from './types.js';
|
2
|
+
/**
|
3
|
+
* Reads the text file from current dir
|
4
|
+
* @param _ config (unused in this provider)
|
5
|
+
* @param fileName
|
6
|
+
* @returns file contents
|
7
|
+
*/
|
8
|
+
export declare function get(_: ProviderConfig | null, fileName: string | undefined): Promise<string | null>;
|
@@ -0,0 +1,20 @@
|
|
1
|
+
import { resolve } from 'node:path';
|
2
|
+
import { display } from '#src/consoleUtils.js';
|
3
|
+
import { readFileSyncWithMessages } from '#src/utils.js';
|
4
|
+
import { getCurrentDir } from '#src/systemUtils.js';
|
5
|
+
/**
|
6
|
+
* Reads the text file from current dir
|
7
|
+
* @param _ config (unused in this provider)
|
8
|
+
* @param fileName
|
9
|
+
* @returns file contents
|
10
|
+
*/
|
11
|
+
export async function get(_, fileName) {
|
12
|
+
if (!fileName) {
|
13
|
+
return null;
|
14
|
+
}
|
15
|
+
const currentDir = getCurrentDir();
|
16
|
+
const filePath = resolve(currentDir, fileName);
|
17
|
+
display(`Reading file ${fileName}...`);
|
18
|
+
return readFileSyncWithMessages(filePath);
|
19
|
+
}
|
20
|
+
//# sourceMappingURL=file.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/providers/file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,GAAG,CACvB,CAAwB,EACxB,QAA4B;IAE5B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC/C,OAAO,CAAC,gBAAgB,QAAQ,KAAK,CAAC,CAAC;IACvC,OAAO,wBAAwB,CAAC,QAAQ,CAAC,CAAC;AAC5C,CAAC"}
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import type { ProviderConfig } from './types.js';
|
2
|
+
/**
|
3
|
+
* Gets PR diff using gh command line tool
|
4
|
+
* @param _ config (unused in this provider)
|
5
|
+
* @param pr PR number
|
6
|
+
* @returns PR diff
|
7
|
+
*/
|
8
|
+
export declare function get(_: ProviderConfig | null, pr: string | undefined): Promise<string | null>;
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { displayWarning } from '#src/consoleUtils.js';
|
2
|
+
import { execAsync } from '#src/utils.js';
|
3
|
+
/**
|
4
|
+
* Gets PR diff using gh command line tool
|
5
|
+
* @param _ config (unused in this provider)
|
6
|
+
* @param pr PR number
|
7
|
+
* @returns PR diff
|
8
|
+
*/
|
9
|
+
export async function get(_, pr) {
|
10
|
+
if (!pr) {
|
11
|
+
displayWarning('No PR provided');
|
12
|
+
return null;
|
13
|
+
}
|
14
|
+
return execAsync(`gh pr diff ${pr}`);
|
15
|
+
}
|
16
|
+
//# sourceMappingURL=ghPrDiffProvider.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"ghPrDiffProvider.js","sourceRoot":"","sources":["../../src/providers/ghPrDiffProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAG1C;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,GAAG,CACvB,CAAwB,EACxB,EAAsB;IAEtB,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,cAAc,CAAC,gBAAgB,CAAC,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,SAAS,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;AACvC,CAAC"}
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import type { JiraConfig } from "./types.js";
|
2
|
+
/**
|
3
|
+
* Gets Jira issue using Atlassian REST API v2
|
4
|
+
* @param config Jira configuration
|
5
|
+
* @param issueId Jira issue ID
|
6
|
+
* @returns Jira issue content
|
7
|
+
*/
|
8
|
+
export declare function get(config: JiraConfig | null, issueId: string | undefined): Promise<string | null>;
|
@@ -0,0 +1,62 @@
|
|
1
|
+
import { displayError, displayWarning } from "#src/consoleUtils.js";
|
2
|
+
/**
|
3
|
+
* Gets Jira issue using Atlassian REST API v2
|
4
|
+
* @param config Jira configuration
|
5
|
+
* @param issueId Jira issue ID
|
6
|
+
* @returns Jira issue content
|
7
|
+
*/
|
8
|
+
export async function get(config, issueId) {
|
9
|
+
if (!config) {
|
10
|
+
displayWarning("No Jira config provided");
|
11
|
+
return null;
|
12
|
+
}
|
13
|
+
if (!issueId) {
|
14
|
+
displayWarning("No issue ID provided");
|
15
|
+
return null;
|
16
|
+
}
|
17
|
+
if (!config.username) {
|
18
|
+
displayWarning("No Jira username provided");
|
19
|
+
return null;
|
20
|
+
}
|
21
|
+
if (!config.baseUrl) {
|
22
|
+
displayWarning("No Jira base URL provided");
|
23
|
+
return null;
|
24
|
+
}
|
25
|
+
if (!config.token) {
|
26
|
+
displayWarning("No Jira token provided");
|
27
|
+
return null;
|
28
|
+
}
|
29
|
+
try {
|
30
|
+
const issue = await getJiraIssue(config, issueId);
|
31
|
+
if (!issue) {
|
32
|
+
return null;
|
33
|
+
}
|
34
|
+
const summary = issue.fields.summary;
|
35
|
+
const description = issue.fields.description;
|
36
|
+
return `Jira Issue: ${issueId}\nSummary: ${summary}\n\nDescription:\n${description}`;
|
37
|
+
}
|
38
|
+
catch (error) {
|
39
|
+
displayError(`Failed to get Jira issue: ${error instanceof Error ? error.message : String(error)}`);
|
40
|
+
return null;
|
41
|
+
}
|
42
|
+
}
|
43
|
+
/**
|
44
|
+
* Helper function to get Jira issue details
|
45
|
+
* @param config Jira configuration
|
46
|
+
* @param issueId Jira issue ID
|
47
|
+
* @returns Jira issue response
|
48
|
+
*/
|
49
|
+
async function getJiraIssue(config, issueId) {
|
50
|
+
const auth = Buffer.from(`${config.username}:${config.token}`).toString('base64');
|
51
|
+
const response = await fetch(`${config.baseUrl}/rest/api/2/issue/${issueId}`, {
|
52
|
+
headers: {
|
53
|
+
'Authorization': `Basic ${auth}`,
|
54
|
+
'Accept': 'application/json'
|
55
|
+
}
|
56
|
+
});
|
57
|
+
if (!response.ok) {
|
58
|
+
throw new Error(`Failed to fetch Jira issue: ${response.statusText}`);
|
59
|
+
}
|
60
|
+
return response.json();
|
61
|
+
}
|
62
|
+
//# sourceMappingURL=jiraIssueLegacyAccessTokenProvider.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"jiraIssueLegacyAccessTokenProvider.js","sourceRoot":"","sources":["../../src/providers/jiraIssueLegacyAccessTokenProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAYpE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,MAAyB,EAAE,OAA2B;IAC5E,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,cAAc,CAAC,yBAAyB,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,cAAc,CAAC,sBAAsB,CAAC,CAAC;QACvC,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QACnB,cAAc,CAAC,2BAA2B,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAClB,cAAc,CAAC,2BAA2B,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAChB,cAAc,CAAC,wBAAwB,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,IAAI,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAClD,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC;QACrC,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC;QAE7C,OAAO,eAAe,OAAO,cAAc,OAAO,qBAAqB,WAAW,EAAE,CAAC;IACzF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,YAAY,CAAC,6BAA6B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACpG,OAAO,IAAI,CAAC;IAChB,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,YAAY,CAAC,MAAkB,EAAE,OAAe;IAC3D,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAClF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,CAAC,OAAO,qBAAqB,OAAO,EAAE,EAAE;QAC1E,OAAO,EAAE;YACL,eAAe,EAAE,SAAS,IAAI,EAAE;YAChC,QAAQ,EAAE,kBAAkB;SAC/B;KACJ,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,+BAA+B,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;AAC3B,CAAC"}
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import type { JiraLegacyConfig } from '#src/providers/types.js';
|
2
|
+
/**
|
3
|
+
* Gets Jira issue using Atlassian REST API v2 with unscoped API token (aka Legacy Token)
|
4
|
+
* @param config Jira configuration
|
5
|
+
* @param issueId Jira issue ID
|
6
|
+
* @returns Jira issue content
|
7
|
+
*/
|
8
|
+
export declare function get(config: Partial<JiraLegacyConfig>, issueId: string | undefined): Promise<string | null>;
|
@@ -0,0 +1,74 @@
|
|
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 v2 with unscoped API token (aka Legacy Token)
|
5
|
+
* @param config Jira configuration
|
6
|
+
* @param issueId Jira issue ID
|
7
|
+
* @returns Jira issue content
|
8
|
+
*/
|
9
|
+
export async function get(config, issueId) {
|
10
|
+
if (!config) {
|
11
|
+
displayWarning('No Jira config provided');
|
12
|
+
return null;
|
13
|
+
}
|
14
|
+
if (!issueId) {
|
15
|
+
displayWarning('No issue ID provided');
|
16
|
+
return null;
|
17
|
+
}
|
18
|
+
if (!config.baseUrl) {
|
19
|
+
displayWarning('No Jira base URL provided');
|
20
|
+
return null;
|
21
|
+
}
|
22
|
+
// Get username from environment variable or config
|
23
|
+
const username = env.JIRA_USERNAME || config.username;
|
24
|
+
if (!username) {
|
25
|
+
throw new Error('Missing JIRA username. The username can be defined as JIRA_USERNAME environment variable or as "username" in config.');
|
26
|
+
}
|
27
|
+
// Get token from environment variable or config
|
28
|
+
const token = env.JIRA_LEGACY_API_TOKEN || config.token;
|
29
|
+
if (!token) {
|
30
|
+
throw new Error('Missing JIRA Legacy API token. The legacy token can be defined as JIRA_LEGACY_API_TOKEN environment variable or as "token" in config.');
|
31
|
+
}
|
32
|
+
try {
|
33
|
+
const issue = await getJiraIssue({
|
34
|
+
...config,
|
35
|
+
username,
|
36
|
+
token,
|
37
|
+
}, issueId);
|
38
|
+
if (!issue) {
|
39
|
+
return null;
|
40
|
+
}
|
41
|
+
const summary = issue.fields.summary;
|
42
|
+
const description = issue.fields.description;
|
43
|
+
return `Jira Issue: ${issueId}\nSummary: ${summary}\n\nDescription:\n${description}`;
|
44
|
+
}
|
45
|
+
catch (error) {
|
46
|
+
displayError(`Failed to get Jira issue: ${error instanceof Error ? error.message : String(error)}`);
|
47
|
+
return null;
|
48
|
+
}
|
49
|
+
}
|
50
|
+
/**
|
51
|
+
* Helper function to get Jira issue details
|
52
|
+
* @param config Jira configuration
|
53
|
+
* @param issueId Jira issue ID
|
54
|
+
* @returns Jira issue response
|
55
|
+
*/
|
56
|
+
async function getJiraIssue(config, issueId) {
|
57
|
+
const auth = Buffer.from(`${config.username}:${config.token}`).toString('base64');
|
58
|
+
const url = `${config.baseUrl}${issueId}`;
|
59
|
+
if (config.displayUrl) {
|
60
|
+
display(`Loading Jira issue ${config.displayUrl}${issueId}`);
|
61
|
+
}
|
62
|
+
display(`Retrieving jira from api ${url.replace(/^https?:\/\//, '')}`);
|
63
|
+
const response = await fetch(url, {
|
64
|
+
headers: {
|
65
|
+
Authorization: `Basic ${auth}`,
|
66
|
+
Accept: 'application/json',
|
67
|
+
},
|
68
|
+
});
|
69
|
+
if (!response.ok) {
|
70
|
+
throw new Error(`Failed to fetch Jira issue from ${url} with status: ${response.statusText}`);
|
71
|
+
}
|
72
|
+
return response.json();
|
73
|
+
}
|
74
|
+
//# sourceMappingURL=jiraIssueLegacyProvider.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"jiraIssueLegacyProvider.js","sourceRoot":"","sources":["../../src/providers/jiraIssueLegacyProvider.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import type { JiraConfig } from './types.js';
|
2
|
+
/**
|
3
|
+
* Gets Jira issue using Atlassian REST API v3 with Personal Access Token
|
4
|
+
*
|
5
|
+
* TODO we need to figure out how would this work with public jira.
|
6
|
+
*
|
7
|
+
* @param config Jira configuration
|
8
|
+
* @param issueId Jira issue ID
|
9
|
+
* @returns Jira issue content
|
10
|
+
*/
|
11
|
+
export declare function get(config: Partial<JiraConfig> | null, issueId: string | undefined): Promise<string | null>;
|