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
@@ -1,82 +1,72 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import
|
4
|
-
import {
|
5
|
-
import {
|
6
|
-
import {
|
7
|
-
import {
|
8
|
-
|
9
|
-
/**
|
10
|
-
* Ask a question and get an answer from the LLM
|
11
|
-
* @param
|
12
|
-
* @param
|
13
|
-
* @param
|
14
|
-
*/
|
15
|
-
export async function askQuestion(source, preamble, content) {
|
16
|
-
const progressIndicator = new ProgressIndicator(
|
17
|
-
const outputContent = await askQuestionInner(slothContext, () => progressIndicator.indicate(), preamble, content);
|
18
|
-
const filePath = path.resolve(getCurrentDir(), toFileSafeString(source)+'-'+fileSafeLocalDate()+
|
19
|
-
display(`\nwriting ${filePath}`);
|
20
|
-
// TODO highlight LLM output with something like Prism.JS
|
21
|
-
display('\n' + outputContent);
|
22
|
-
try {
|
23
|
-
writeFileSync(filePath, outputContent);
|
24
|
-
displaySuccess(`This report can be found in ${filePath}`);
|
25
|
-
}
|
26
|
-
|
27
|
-
displayError(
|
28
|
-
|
29
|
-
// exit
|
30
|
-
|
31
|
-
}
|
32
|
-
|
33
|
-
/**
|
34
|
-
* Inner function to ask a question and get an answer from the LLM
|
35
|
-
* @param
|
36
|
-
* @param
|
37
|
-
* @param
|
38
|
-
* @param
|
39
|
-
* @returns
|
40
|
-
*/
|
41
|
-
export async function askQuestionInner(context, indicateProgress, preamble, content) {
|
42
|
-
// This node receives the current state (messages) and invokes the LLM
|
43
|
-
const callModel = async (state) => {
|
44
|
-
// state.messages will contain the list including the system preamble and user diff
|
45
|
-
const response = await context.config.llm.invoke(state.messages);
|
46
|
-
// MessagesAnnotation expects the node to return the new message(s) to be added to the state.
|
47
|
-
// Wrap the response in an array if it's a single message object.
|
48
|
-
return { messages: response };
|
49
|
-
};
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
.
|
55
|
-
.addEdge(
|
56
|
-
|
57
|
-
|
58
|
-
//
|
59
|
-
const
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
const
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
},
|
74
|
-
];
|
75
|
-
|
76
|
-
indicateProgress();
|
77
|
-
// TODO create proper progress indicator for async tasks.
|
78
|
-
const progress = setInterval(() => indicateProgress(), 1000);
|
79
|
-
const output = await app.invoke({messages}, context.session);
|
80
|
-
clearInterval(progress);
|
81
|
-
return extractLastMessageContent(output);
|
82
|
-
}
|
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 { HumanMessage, SystemMessage } from '@langchain/core/messages';
|
6
|
+
import { END, MemorySaver, MessagesAnnotation, START, StateGraph } from '@langchain/langgraph';
|
7
|
+
import { writeFileSync } from 'node:fs';
|
8
|
+
import * as path from 'node:path';
|
9
|
+
/**
|
10
|
+
* Ask a question and get an answer from the LLM
|
11
|
+
* @param source - The source of the question (used for file naming)
|
12
|
+
* @param preamble - The preamble to send to the LLM
|
13
|
+
* @param content - The content of the question
|
14
|
+
*/
|
15
|
+
export async function askQuestion(source, preamble, content) {
|
16
|
+
const progressIndicator = new ProgressIndicator('Thinking.');
|
17
|
+
const outputContent = await askQuestionInner(slothContext, () => progressIndicator.indicate(), preamble, content);
|
18
|
+
const filePath = path.resolve(getCurrentDir(), toFileSafeString(source) + '-' + fileSafeLocalDate() + '.md');
|
19
|
+
display(`\nwriting ${filePath}`);
|
20
|
+
// TODO highlight LLM output with something like Prism.JS
|
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
|
+
/**
|
34
|
+
* Inner function to ask a question and get an answer from the LLM
|
35
|
+
* @param context - The context object
|
36
|
+
* @param indicateProgress - Function to indicate progress
|
37
|
+
* @param preamble - The preamble to send to the LLM
|
38
|
+
* @param content - The content of the question
|
39
|
+
* @returns The answer from the LLM
|
40
|
+
*/
|
41
|
+
export async function askQuestionInner(context, indicateProgress, preamble, content) {
|
42
|
+
// This node receives the current state (messages) and invokes the LLM
|
43
|
+
const callModel = async (state) => {
|
44
|
+
// state.messages will contain the list including the system preamble and user diff
|
45
|
+
const response = await context.config.llm.invoke(state.messages);
|
46
|
+
// MessagesAnnotation expects the node to return the new message(s) to be added to the state.
|
47
|
+
// Wrap the response in an array if it's a single message object.
|
48
|
+
return { messages: response };
|
49
|
+
};
|
50
|
+
// Define the graph structure with MessagesAnnotation state
|
51
|
+
const workflow = new StateGraph(MessagesAnnotation)
|
52
|
+
// Define the node and edge
|
53
|
+
.addNode('model', callModel)
|
54
|
+
.addEdge(START, 'model') // Start at the 'model' node
|
55
|
+
.addEdge('model', END); // End after the 'model' node completes
|
56
|
+
// Set up memory (optional but good practice for potential future multi-turn interactions)
|
57
|
+
const memory = new MemorySaver();
|
58
|
+
// Compile the workflow into a runnable app
|
59
|
+
const app = workflow.compile({ checkpointer: memory });
|
60
|
+
// Construct the initial the messages including the preamble as a system message
|
61
|
+
const messages = [new SystemMessage(preamble), new HumanMessage(content)];
|
62
|
+
indicateProgress();
|
63
|
+
// TODO create proper progress indicator for async tasks.
|
64
|
+
const progress = setInterval(() => indicateProgress(), 1000);
|
65
|
+
const output = await app.invoke({ messages }, context.session);
|
66
|
+
clearInterval(progress);
|
67
|
+
const lastMessage = output.messages[output.messages.length - 1];
|
68
|
+
return typeof lastMessage.content === 'string'
|
69
|
+
? lastMessage.content
|
70
|
+
: JSON.stringify(lastMessage.content);
|
71
|
+
}
|
72
|
+
//# sourceMappingURL=questionAnsweringModule.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"questionAnsweringModule.js","sourceRoot":"","sources":["../../src/modules/questionAnsweringModule.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,4 @@
|
|
1
|
+
import type { SlothContext } from '#src/config.js';
|
2
|
+
import type { ProgressCallback } from '#src/modules/types.js';
|
3
|
+
export declare function review(source: string, preamble: string, diff: string): Promise<void>;
|
4
|
+
export declare function reviewInner(context: SlothContext, indicateProgress: ProgressCallback, preamble: string, diff: string): Promise<string>;
|
@@ -1,31 +1,31 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import
|
4
|
-
import {
|
5
|
-
import {
|
6
|
-
import {
|
7
|
-
import {
|
8
|
-
|
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 { HumanMessage, SystemMessage } from '@langchain/core/messages';
|
6
|
+
import { END, MemorySaver, MessagesAnnotation, START, StateGraph } from '@langchain/langgraph';
|
7
|
+
import { writeFileSync } from 'node:fs';
|
8
|
+
import path from 'node:path';
|
9
9
|
export async function review(source, preamble, diff) {
|
10
|
-
const progressIndicator = new ProgressIndicator(
|
10
|
+
const progressIndicator = new ProgressIndicator('Reviewing.');
|
11
11
|
const outputContent = await reviewInner(slothContext, () => progressIndicator.indicate(), preamble, diff);
|
12
|
-
const filePath = path.resolve(getCurrentDir(), toFileSafeString(source)+'-'+fileSafeLocalDate()+
|
13
|
-
stdout.write(
|
12
|
+
const filePath = path.resolve(getCurrentDir(), toFileSafeString(source) + '-' + fileSafeLocalDate() + '.md');
|
13
|
+
stdout.write('\n');
|
14
14
|
display(`writing ${filePath}`);
|
15
|
-
stdout.write(
|
15
|
+
stdout.write('\n');
|
16
16
|
// TODO highlight LLM output with something like Prism.JS (maybe system emoj are enough ✅⚠️❌)
|
17
17
|
display(outputContent);
|
18
18
|
try {
|
19
19
|
writeFileSync(filePath, outputContent);
|
20
20
|
displaySuccess(`This report can be found in ${filePath}`);
|
21
|
-
}
|
22
|
-
|
21
|
+
}
|
22
|
+
catch (error) {
|
23
|
+
displayDebug(error instanceof Error ? error : String(error));
|
23
24
|
displayError(`Failed to write review to file: ${filePath}`);
|
24
25
|
// Consider if you want to exit or just log the error
|
25
26
|
// exit(1);
|
26
27
|
}
|
27
28
|
}
|
28
|
-
|
29
29
|
export async function reviewInner(context, indicateProgress, preamble, diff) {
|
30
30
|
// This node receives the current state (messages) and invokes the LLM
|
31
31
|
const callModel = async (state) => {
|
@@ -35,36 +35,26 @@ export async function reviewInner(context, indicateProgress, preamble, diff) {
|
|
35
35
|
// Wrap the response in an array if it's a single message object.
|
36
36
|
return { messages: response };
|
37
37
|
};
|
38
|
-
|
39
38
|
// Define the graph structure with MessagesAnnotation state
|
40
39
|
const workflow = new StateGraph(MessagesAnnotation)
|
41
40
|
// Define the node and edge
|
42
|
-
.addNode(
|
43
|
-
.addEdge(START,
|
44
|
-
.addEdge(
|
45
|
-
|
41
|
+
.addNode('model', callModel)
|
42
|
+
.addEdge(START, 'model') // Start at the 'model' node
|
43
|
+
.addEdge('model', END); // End after the 'model' node completes
|
46
44
|
// Set up memory (optional but good practice for potential future multi-turn interactions)
|
47
45
|
const memory = new MemorySaver(); // TODO extract to config
|
48
|
-
|
49
46
|
// Compile the workflow into a runnable app
|
50
47
|
const app = workflow.compile({ checkpointer: memory });
|
51
|
-
|
52
48
|
// Construct the initial the messages including the preamble as a system message
|
53
|
-
const messages = [
|
54
|
-
{
|
55
|
-
role: "system",
|
56
|
-
content: preamble, // The preamble goes here
|
57
|
-
},
|
58
|
-
{
|
59
|
-
role: "user",
|
60
|
-
content: diff, // The code diff goes here
|
61
|
-
},
|
62
|
-
];
|
63
|
-
|
49
|
+
const messages = [new SystemMessage(preamble), new HumanMessage(diff)];
|
64
50
|
indicateProgress();
|
65
51
|
// TODO create proper progress indicator for async tasks.
|
66
52
|
const progress = setInterval(() => indicateProgress(), 1000);
|
67
|
-
const output = await app.invoke({messages}, context.session);
|
53
|
+
const output = await app.invoke({ messages }, context.session);
|
68
54
|
clearInterval(progress);
|
69
|
-
|
55
|
+
const lastMessage = output.messages[output.messages.length - 1];
|
56
|
+
return typeof lastMessage.content === 'string'
|
57
|
+
? lastMessage.content
|
58
|
+
: JSON.stringify(lastMessage.content);
|
70
59
|
}
|
60
|
+
//# sourceMappingURL=reviewModule.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"reviewModule.js","sourceRoot":"","sources":["../../src/modules/reviewModule.ts"],"names":[],"mappings":"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"}
|
@@ -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,7 @@
|
|
1
|
+
export declare function readInternalPreamble(): string;
|
2
|
+
export declare function readPreamble(preambleFilename: string): string;
|
3
|
+
/**
|
4
|
+
* This function expects https://cli.github.com/ to be installed and authenticated.
|
5
|
+
* It does something like `gh pr diff 42`
|
6
|
+
*/
|
7
|
+
export declare function getPrDiff(pr: string): Promise<string>;
|
package/dist/prompt.js
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
import { resolve } from 'node:path';
|
2
|
+
import { GSLOTH_BACKSTORY } from '#src/config.js';
|
3
|
+
import { readFileSyncWithMessages, spawnCommand } from '#src/utils.js';
|
4
|
+
import { displayError } from '#src/consoleUtils.js';
|
5
|
+
import { exit, getCurrentDir, getInstallDir } from '#src/systemUtils.js';
|
6
|
+
export function readInternalPreamble() {
|
7
|
+
const installDir = getInstallDir();
|
8
|
+
const filePath = resolve(installDir, GSLOTH_BACKSTORY);
|
9
|
+
return readFileSyncWithMessages(filePath, 'Error reading internal preamble file at:') || '';
|
10
|
+
}
|
11
|
+
export function readPreamble(preambleFilename) {
|
12
|
+
const currentDir = getCurrentDir();
|
13
|
+
const filePath = resolve(currentDir, preambleFilename);
|
14
|
+
return (readFileSyncWithMessages(filePath, 'Error reading preamble file at:', 'Consider running `gsloth init` to set up your project. Check `gsloth init --help` to see options.') || '');
|
15
|
+
}
|
16
|
+
/**
|
17
|
+
* This function expects https://cli.github.com/ to be installed and authenticated.
|
18
|
+
* It does something like `gh pr diff 42`
|
19
|
+
*/
|
20
|
+
export async function getPrDiff(pr) {
|
21
|
+
// TODO makes sense to check if gh is available and authenticated
|
22
|
+
try {
|
23
|
+
return await spawnCommand('gh', ['pr', 'diff', pr], 'Loading PR diff...', 'Loaded PR diff.');
|
24
|
+
}
|
25
|
+
catch (e) {
|
26
|
+
displayError(e instanceof Error ? e.toString() : String(e));
|
27
|
+
displayError(`Failed to call "gh pr diff ${pr}", see message above for details.`);
|
28
|
+
exit();
|
29
|
+
return ''; // This line will never be reached due to exit()
|
30
|
+
}
|
31
|
+
}
|
32
|
+
//# sourceMappingURL=prompt.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,wBAAwB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzE,MAAM,UAAU,oBAAoB;IAClC,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;IACvD,OAAO,wBAAwB,CAAC,QAAQ,EAAE,0CAA0C,CAAC,IAAI,EAAE,CAAC;AAC9F,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,gBAAwB;IACnD,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;IACvD,OAAO,CACL,wBAAwB,CACtB,QAAQ,EACR,iCAAiC,EACjC,mGAAmG,CACpG,IAAI,EAAE,CACR,CAAC;AACJ,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>;
|