@gaunt-sloth/review 2.0.0-alpha.3 → 2.0.0-alpha.30

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/README.md CHANGED
@@ -1,77 +1,119 @@
1
1
  # @gaunt-sloth/review
2
2
 
3
- Review and question-answering functionality for Gaunt Sloth.
3
+ The review engine behind `gth review` / `gth pr`, packaged for embedding: run an AI code review
4
+ programmatically from your own tool or pipeline, or via the standalone `gaunt-sloth-review`
5
+ binary. Also contains the content/requirement sources (GitHub, local git diff, Jira, file, text) that feed it.
6
+
7
+ **When to depend on this package** — you want review results inside your own process or a
8
+ minimal CI job. It has no dependency on `commander`, MCP, or A2A, so the install stays small.
9
+ If you want the interactive CLI (chat/code sessions, TUI, MCP tools), install the fat
10
+ [`gaunt-sloth`](https://www.npmjs.com/package/gaunt-sloth) app instead — it wires this same
11
+ module into `gth review` and `gth pr`.
4
12
 
5
13
  ## Installation
6
14
 
7
- This package does not include any AI provider packages. This is by design to
8
- keep the install minimal and avoid pulling in providers you don't use. Install
9
- the review package together with the provider required by your configuration:
15
+ AI providers are not bundled (they are optional peer dependencies of
16
+ [`@gaunt-sloth/core`](https://www.npmjs.com/package/@gaunt-sloth/core)); install the one your
17
+ config uses:
10
18
 
11
19
  ```bash
12
20
  # OpenRouter / OpenAI
13
- npm install -g @gaunt-sloth/review @langchain/openai
21
+ npm install @gaunt-sloth/review @langchain/openai
14
22
 
15
23
  # Google (Vertex AI / AI Studio)
16
- npm install -g @gaunt-sloth/review @langchain/google
24
+ npm install @gaunt-sloth/review @langchain/google
17
25
 
18
26
  # Anthropic
19
- npm install -g @gaunt-sloth/review @langchain/anthropic
27
+ npm install @gaunt-sloth/review @langchain/anthropic
20
28
 
21
29
  # Groq
22
- npm install -g @gaunt-sloth/review @langchain/groq
30
+ npm install @gaunt-sloth/review @langchain/groq
23
31
  ```
24
32
 
25
- See [`@gaunt-sloth/core`](../core) for the full list of supported providers.
33
+ ## Embedding: review a diff programmatically
34
+
35
+ I want to run a Gaunt Sloth review over a diff from my own Node script and fail the build on a
36
+ bad rating. Create `.gsloth.config.json` next to the script:
37
+
38
+ ```json
39
+ {
40
+ "llm": { "type": "anthropic", "model": "claude-sonnet-4-5" },
41
+ "commands": {
42
+ "review": { "rating": { "enabled": true, "passThreshold": 6 } }
43
+ }
44
+ }
45
+ ```
26
46
 
27
- ## Contents
47
+ Then run a review over a diff (`node review-diff.mjs change.diff`):
48
+
49
+ ```js
50
+ // review-diff.mjs
51
+ import { readFileSync } from 'node:fs';
52
+ import { initConfig } from '@gaunt-sloth/core/config.js';
53
+ import {
54
+ readBackstory,
55
+ readGuidelines,
56
+ readReviewInstructions,
57
+ } from '@gaunt-sloth/core/utils/llmUtils.js';
58
+ import { review } from '@gaunt-sloth/review';
59
+
60
+ const config = await initConfig({}); // loads .gsloth.config.* from the working directory
61
+ const preamble = [readBackstory(config), readGuidelines(config), readReviewInstructions(config)]
62
+ .filter(Boolean)
63
+ .join('\n');
64
+ const diff = readFileSync(process.argv[2], 'utf8');
65
+
66
+ await review('embedded-review', preamble, diff, config);
67
+ process.exit(process.exitCode ?? 0);
68
+ ```
28
69
 
29
- - Review module (`reviewModule`) diff and content review orchestration
30
- - Question answering module (`questionAnsweringModule`)
31
- - Command utilities (`commandUtils`)
32
- - Content and requirement sources: `file`, `text`, `ghPrDiff`, `ghIssue`, `jiraIssue`, `jiraIssueLegacy`
33
- - Jira client
34
- - Review rate middleware
70
+ The review text is written to stdout. With rating enabled, `review()` sets `process.exitCode = 1`
71
+ when the rating comes back below `passThreshold` (or when the model fails to produce a rating),
72
+ so the script exits non-zero exactly when `gth review` would — that is the whole embed contract.
73
+ Configuration (provider, prompts, rating thresholds) is the standard Gaunt Sloth config, see
74
+ [the configuration guide](https://github.com/pukeko-robotics/gaunt-sloth/blob/main/docs/configuration/index.md).
35
75
 
36
- ## CLI
76
+ This exact flow is verified by the workspace embed e2e (`pnpm run test:embed`), which packs the
77
+ published tarballs and runs the snippet above from a temp-dir consumer against a stub model.
37
78
 
38
- The package ships a standalone binary `gaunt-sloth-review` for CI-friendly reviews that does not depend on `commander`. This makes it suitable for embedding in pipelines where a minimal footprint is preferred.
79
+ ## Standalone CLI: `gaunt-sloth-review`
80
+
81
+ The package's one binary, for CI-friendly reviews with a minimal footprint:
39
82
 
40
83
  ```bash
41
- gaunt-sloth-review <pr-number> [requirement-ids...]
84
+ gaunt-sloth-review 123 # review PR 123 (uses the configured content source, GitHub by default)
85
+ gaunt-sloth-review 123 45 # ...with requirements from issue 45
42
86
  gaunt-sloth-review --version
43
87
  ```
44
88
 
45
89
  ### Identity profiles
46
90
 
47
- To use a different config profile (e.g. separate provider/auth for CI vs local),
48
- set the `GSLOTH_IDENTITY_PROFILE` environment variable:
91
+ To use a different config profile (e.g. separate provider/auth for CI vs local), set the
92
+ `GSLOTH_IDENTITY_PROFILE` environment variable:
49
93
 
50
94
  ```bash
51
95
  GSLOTH_IDENTITY_PROFILE=review gaunt-sloth-review 123
52
96
  ```
53
97
 
54
- This loads config from `.gsloth-settings/review/` instead of the default
55
- `.gsloth/` directory. Useful when CI uses different credentials or a different
56
- LLM provider than local development.
57
-
58
- ## Dependencies
59
-
60
- - `@gaunt-sloth/core` (required)
61
-
62
- No MCP, no A2A, no commander. This is intentional to keep the package lightweight for CI use.
98
+ This loads config from `.gsloth-settings/review/` instead of the default `.gsloth/` directory.
99
+ Useful when CI uses different credentials or a different LLM provider than local development.
63
100
 
64
101
  ## Exports
65
102
 
66
- ```js
67
- import { reviewModule } from '@gaunt-sloth/review/reviewModule.js';
68
- import { questionAnsweringModule } from '@gaunt-sloth/review/questionAnsweringModule.js';
69
- import { commandUtils } from '@gaunt-sloth/review/commandUtils.js';
70
- ```
103
+ - `@gaunt-sloth/review` (the root export) is the public API: the review module (`review`,
104
+ `ReviewContext`), `commandUtils`, and the `gh` read-file tool — plus, deliberately, the whole
105
+ `@gaunt-sloth/core` config barrel (`initConfig`, `GthConfig`, `DEFAULT_CONFIG`, …), re-exported
106
+ so an embedder can resolve config from the review root without importing core directly.
107
+ This surface is what the embed example above and the fat CLI use.
108
+ - `@gaunt-sloth/review/<path>.js` deep paths (e.g.
109
+ `@gaunt-sloth/review/modules/reviewModule.js`) mirror the package's internal `dist/` layout
110
+ 1:1 and are deliberately kept open for reach-in. They are supported at your own risk: internal
111
+ files can move between alpha/minor versions without a deprecation cycle. Prefer the root
112
+ export where it suffices.
71
113
 
72
114
  ## Related packages
73
115
 
74
- - [`@gaunt-sloth/core`](../core) — Core utilities, config, and agent infrastructure
75
- - [`@gaunt-sloth/agent`](../agent) — Agent runtime: built-in tools, filesystem toolkit, middleware registry, API server, AG-UI, MCP, and A2A integration
76
- - [`@gaunt-sloth/review`](../review) — Review and Q&A modules with standalone CLI (this package)
77
- - [`gaunt-sloth`](../app) — Main CLI application
116
+ - [`@gaunt-sloth/core`](https://www.npmjs.com/package/@gaunt-sloth/core) — Core utilities, config, and agent infrastructure ([source](https://github.com/pukeko-robotics/gaunt-sloth/tree/main/packages/core))
117
+ - [`@gaunt-sloth/agent`](https://www.npmjs.com/package/@gaunt-sloth/agent) — Agent runtime: built-in tools, filesystem toolkit, middleware registry, API server, AG-UI, MCP, and A2A integration ([source](https://github.com/pukeko-robotics/gaunt-sloth/tree/main/packages/agent))
118
+ - [`@gaunt-sloth/batch`](https://www.npmjs.com/package/@gaunt-sloth/batch) — Batch / eval / workflow runtime ([source](https://github.com/pukeko-robotics/gaunt-sloth/tree/main/packages/batch))
119
+ - [`gaunt-sloth`](https://www.npmjs.com/package/gaunt-sloth) — Main CLI application ([source](https://github.com/pukeko-robotics/gaunt-sloth/tree/main/packages/app))
package/cli.js CHANGED
@@ -25,8 +25,11 @@ setEntryPoint(import.meta.url);
25
25
  import { initConfig } from '@gaunt-sloth/core/config.js';
26
26
  import { review } from '#src/modules/reviewModule.js';
27
27
  import { displayError } from '@gaunt-sloth/core/utils/consoleUtils.js';
28
- import { getContentFromSource, getRequirementsFromSource } from '#src/commands/commandUtils.js';
29
- import { buildSystemMessages } from '@gaunt-sloth/core/utils/llmUtils.js';
28
+ import {
29
+ getContentFromSource,
30
+ getRequirementsFromSource,
31
+ getReviewPreamble,
32
+ } from '#src/commands/commandUtils.js';
30
33
 
31
34
  async function main() {
32
35
  try {
@@ -53,11 +56,9 @@ async function main() {
53
56
  }
54
57
  }
55
58
 
56
- // Build preamble from system messages
57
- const preamble = buildSystemMessages(config, 'pr');
58
- const preambleText = preamble
59
- .map((m) => (typeof m.content === 'string' ? m.content : ''))
60
- .join('\n');
59
+ // Build the review preamble (backstory + guidelines + review instructions + optional
60
+ // system prompt), the same composition `gth review` / `gth pr` use.
61
+ const preambleText = getReviewPreamble(config);
61
62
 
62
63
  // Combine requirements and content for the review
63
64
  const diffWithReqs = requirements
@@ -1,33 +1,33 @@
1
1
  import type { GthConfig } from '@gaunt-sloth/core/config.js';
2
2
  /**
3
- * Requirements sources. Expected to be in `.sources/` dir.
3
+ * Compose the review system preamble the way the fat CLI's `gth review` / `gth pr` do:
4
+ * backstory + guidelines + review instructions + the optional project system prompt, each
5
+ * segment honouring the GS2-43 `prompts.*` config. Empty segments are dropped rather than
6
+ * left as blank lines (the shape the README embed example documents).
7
+ */
8
+ export declare function getReviewPreamble(config: GthConfig): string;
9
+ /**
10
+ * Requirement sources. Expected to be in `.sources/` dir.
4
11
  * Aliases are mapped to actual sources in this file
5
12
  */
6
- export declare const REQUIREMENTS_PROVIDERS: {
7
- readonly 'jira-legacy': "jiraIssueLegacySource.js";
8
- readonly jira: "jiraIssueSource.js";
9
- readonly github: "ghIssueSource.js";
10
- readonly text: "textSource.js";
11
- readonly file: "fileSource.js";
13
+ export declare const REQUIREMENTS_SOURCES: {
14
+ readonly 'jira-legacy': 'jiraIssueLegacySource.js';
15
+ readonly jira: 'jiraIssueSource.js';
16
+ readonly github: 'ghIssueSource.js';
17
+ readonly text: 'textSource.js';
18
+ readonly file: 'fileSource.js';
12
19
  };
13
- export type RequirementsProviderType = keyof typeof REQUIREMENTS_PROVIDERS;
20
+ export type RequirementSourceType = keyof typeof REQUIREMENTS_SOURCES;
14
21
  /**
15
22
  * Content sources. Expected to be in `.sources/` dir.
16
23
  * Aliases are mapped to actual sources in this file
17
24
  */
18
- export declare const CONTENT_PROVIDERS: {
19
- readonly github: "ghPrDiffSource.js";
20
- readonly text: "textSource.js";
21
- readonly file: "fileSource.js";
25
+ export declare const CONTENT_SOURCES: {
26
+ readonly github: 'ghPrDiffSource.js';
27
+ readonly git: 'gitDiffSource.js';
28
+ readonly text: 'textSource.js';
29
+ readonly file: 'fileSource.js';
22
30
  };
23
- export type ContentProviderType = keyof typeof CONTENT_PROVIDERS;
24
- export declare function getRequirementsFromSource(requirementsProvider: RequirementsProviderType | undefined, requirementsId: string | undefined, config: GthConfig): Promise<string>;
25
- export declare function getContentFromSource(contentProvider: ContentProviderType | undefined, contentId: string | undefined, config: GthConfig): Promise<string>;
26
- /**
27
- * @deprecated Use getRequirementsFromSource instead
28
- */
29
- export declare const getRequirementsFromProvider: typeof getRequirementsFromSource;
30
- /**
31
- * @deprecated Use getContentFromSource instead
32
- */
33
- export declare const getContentFromProvider: typeof getContentFromSource;
31
+ export type ContentSourceType = keyof typeof CONTENT_SOURCES;
32
+ export declare function getRequirementsFromSource(requirementSource: RequirementSourceType | undefined, requirementsId: string | undefined, config: GthConfig): Promise<string>;
33
+ export declare function getContentFromSource(contentSource: ContentSourceType | undefined, contentId: string | undefined, config: GthConfig): Promise<string>;
@@ -1,10 +1,26 @@
1
1
  import { displayError } from '@gaunt-sloth/core/utils/consoleUtils.js';
2
- import { wrapContent } from '@gaunt-sloth/core/utils/llmUtils.js';
2
+ import { readBackstory, readGuidelines, readReviewInstructions, readSystemPrompt, wrapContent, } from '@gaunt-sloth/core/utils/llmUtils.js';
3
3
  /**
4
- * Requirements sources. Expected to be in `.sources/` dir.
4
+ * Compose the review system preamble the way the fat CLI's `gth review` / `gth pr` do:
5
+ * backstory + guidelines + review instructions + the optional project system prompt, each
6
+ * segment honouring the GS2-43 `prompts.*` config. Empty segments are dropped rather than
7
+ * left as blank lines (the shape the README embed example documents).
8
+ */
9
+ export function getReviewPreamble(config) {
10
+ return [
11
+ readBackstory(config),
12
+ readGuidelines(config),
13
+ readReviewInstructions(config),
14
+ readSystemPrompt(config),
15
+ ]
16
+ .filter(Boolean)
17
+ .join('\n');
18
+ }
19
+ /**
20
+ * Requirement sources. Expected to be in `.sources/` dir.
5
21
  * Aliases are mapped to actual sources in this file
6
22
  */
7
- export const REQUIREMENTS_PROVIDERS = {
23
+ export const REQUIREMENTS_SOURCES = {
8
24
  'jira-legacy': 'jiraIssueLegacySource.js',
9
25
  jira: 'jiraIssueSource.js',
10
26
  github: 'ghIssueSource.js',
@@ -15,44 +31,37 @@ export const REQUIREMENTS_PROVIDERS = {
15
31
  * Content sources. Expected to be in `.sources/` dir.
16
32
  * Aliases are mapped to actual sources in this file
17
33
  */
18
- export const CONTENT_PROVIDERS = {
34
+ export const CONTENT_SOURCES = {
19
35
  github: 'ghPrDiffSource.js',
36
+ git: 'gitDiffSource.js',
20
37
  text: 'textSource.js',
21
38
  file: 'fileSource.js',
22
39
  };
23
- export async function getRequirementsFromSource(requirementsProvider, requirementsId, config) {
24
- const requirements = await getFromProvider(requirementsProvider, requirementsId, (config?.requirementsProviderConfig ?? {})[requirementsProvider], REQUIREMENTS_PROVIDERS);
25
- return wrapContent(requirements, requirementsProvider, 'requirements');
40
+ export async function getRequirementsFromSource(requirementSource, requirementsId, config) {
41
+ const requirements = await getFromSource(requirementSource, requirementsId, (config?.requirementSourceConfig ?? {})[requirementSource], REQUIREMENTS_SOURCES);
42
+ return wrapContent(requirements, requirementSource, 'requirements');
26
43
  }
27
- export async function getContentFromSource(contentProvider, contentId, config) {
28
- const content = await getFromProvider(contentProvider, contentId, (config?.contentProviderConfig ?? {})[contentProvider], CONTENT_PROVIDERS);
29
- return wrapContent(content, contentProvider, contentProvider === 'github' ? 'GitHub diff' : 'content');
44
+ export async function getContentFromSource(contentSource, contentId, config) {
45
+ const content = await getFromSource(contentSource, contentId, (config?.contentSourceConfig ?? {})[contentSource], CONTENT_SOURCES);
46
+ return wrapContent(content, contentSource, contentSource === 'github' ? 'GitHub diff' : contentSource === 'git' ? 'git diff' : 'content');
30
47
  }
31
- /**
32
- * @deprecated Use getRequirementsFromSource instead
33
- */
34
- export const getRequirementsFromProvider = getRequirementsFromSource;
35
- /**
36
- * @deprecated Use getContentFromSource instead
37
- */
38
- export const getContentFromProvider = getContentFromSource;
39
- async function getFromProvider(provider, id,
48
+ async function getFromSource(source, id,
40
49
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
41
- config, legitPredefinedProviders) {
42
- if (typeof provider === 'string') {
43
- // Use one of the predefined providers
44
- if (legitPredefinedProviders[provider]) {
45
- const providerPath = `#src/sources/${legitPredefinedProviders[provider]}`;
46
- const { get } = await import(providerPath);
50
+ config, legitPredefinedSources) {
51
+ if (typeof source === 'string') {
52
+ // Use one of the predefined sources
53
+ if (legitPredefinedSources[source]) {
54
+ const sourcePath = `#src/sources/${legitPredefinedSources[source]}`;
55
+ const { get } = await import(sourcePath);
47
56
  return await get(config, id);
48
57
  }
49
58
  else {
50
- displayError(`Unknown provider: ${provider}. Continuing without it.`);
59
+ displayError(`Unknown source: ${source}. Continuing without it.`);
51
60
  }
52
61
  }
53
- else if (typeof provider === 'function') {
62
+ else if (typeof source === 'function') {
54
63
  // Type assertion to handle function call
55
- return await provider(id);
64
+ return await source(id);
56
65
  }
57
66
  return '';
58
67
  }
@@ -1 +1 @@
1
- {"version":3,"file":"commandUtils.js","sourceRoot":"","sources":["../../src/commands/commandUtils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAEvE,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAElE;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,aAAa,EAAE,0BAA0B;IACzC,IAAI,EAAE,oBAAoB;IAC1B,MAAM,EAAE,kBAAkB;IAC1B,IAAI,EAAE,eAAe;IACrB,IAAI,EAAE,eAAe;CACb,CAAC;AAIX;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,MAAM,EAAE,mBAAmB;IAC3B,IAAI,EAAE,eAAe;IACrB,IAAI,EAAE,eAAe;CACb,CAAC;AAIX,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,oBAA0D,EAC1D,cAAkC,EAClC,MAAiB;IAEjB,MAAM,YAAY,GAAG,MAAM,eAAe,CACxC,oBAAoB,EACpB,cAAc,EACd,CAAC,MAAM,EAAE,0BAA0B,IAAI,EAAE,CAAC,CAAC,oBAA8B,CAAC,EAC1E,sBAAsB,CACvB,CAAC;IACF,OAAO,WAAW,CAAC,YAAY,EAAE,oBAAoB,EAAE,cAAc,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,eAAgD,EAChD,SAA6B,EAC7B,MAAiB;IAEjB,MAAM,OAAO,GAAG,MAAM,eAAe,CACnC,eAAe,EACf,SAAS,EACT,CAAC,MAAM,EAAE,qBAAqB,IAAI,EAAE,CAAC,CAAC,eAAyB,CAAC,EAChE,iBAAiB,CAClB,CAAC;IACF,OAAO,WAAW,CAChB,OAAO,EACP,eAAe,EACf,eAAe,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CACzD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,yBAAyB,CAAC;AAErE;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,oBAAoB,CAAC;AAE3D,KAAK,UAAU,eAAe,CAC5B,QAAoE,EACpE,EAAsB;AACtB,8DAA8D;AAC9D,MAAW,EACX,wBAAkF;IAElF,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,sCAAsC;QACtC,IAAI,wBAAwB,CAAC,QAAiD,CAAC,EAAE,CAAC;YAChF,MAAM,YAAY,GAAG,gBAAgB,wBAAwB,CAAC,QAAiD,CAAC,EAAE,CAAC;YACnH,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;YAC3C,OAAO,MAAM,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,YAAY,CAAC,qBAAqB,QAAQ,0BAA0B,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;SAAM,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;QAC1C,yCAAyC;QACzC,OAAO,MAAO,QAAwD,CAAC,EAAE,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC"}
1
+ {"version":3,"file":"commandUtils.js","sourceRoot":"","sources":["../../src/commands/commandUtils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAEvE,OAAO,EACL,aAAa,EACb,cAAc,EACd,sBAAsB,EACtB,gBAAgB,EAChB,WAAW,GACZ,MAAM,qCAAqC,CAAC;AAE7C;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAiB;IACjD,OAAO;QACL,aAAa,CAAC,MAAM,CAAC;QACrB,cAAc,CAAC,MAAM,CAAC;QACtB,sBAAsB,CAAC,MAAM,CAAC;QAC9B,gBAAgB,CAAC,MAAM,CAAC;KACzB;SACE,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,aAAa,EAAE,0BAA0B;IACzC,IAAI,EAAE,oBAAoB;IAC1B,MAAM,EAAE,kBAAkB;IAC1B,IAAI,EAAE,eAAe;IACrB,IAAI,EAAE,eAAe;CACb,CAAC;AAIX;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,MAAM,EAAE,mBAAmB;IAC3B,GAAG,EAAE,kBAAkB;IACvB,IAAI,EAAE,eAAe;IACrB,IAAI,EAAE,eAAe;CACb,CAAC;AAIX,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,iBAAoD,EACpD,cAAkC,EAClC,MAAiB;IAEjB,MAAM,YAAY,GAAG,MAAM,aAAa,CACtC,iBAAiB,EACjB,cAAc,EACd,CAAC,MAAM,EAAE,uBAAuB,IAAI,EAAE,CAAC,CAAC,iBAA2B,CAAC,EACpE,oBAAoB,CACrB,CAAC;IACF,OAAO,WAAW,CAAC,YAAY,EAAE,iBAAiB,EAAE,cAAc,CAAC,CAAC;AACtE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,aAA4C,EAC5C,SAA6B,EAC7B,MAAiB;IAEjB,MAAM,OAAO,GAAG,MAAM,aAAa,CACjC,aAAa,EACb,SAAS,EACT,CAAC,MAAM,EAAE,mBAAmB,IAAI,EAAE,CAAC,CAAC,aAAuB,CAAC,EAC5D,eAAe,CAChB,CAAC;IACF,OAAO,WAAW,CAChB,OAAO,EACP,aAAa,EACb,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,KAAK,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAC9F,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,MAA6D,EAC7D,EAAsB;AACtB,8DAA8D;AAC9D,MAAW,EACX,sBAA4E;IAE5E,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,oCAAoC;QACpC,IAAI,sBAAsB,CAAC,MAA6C,CAAC,EAAE,CAAC;YAC1E,MAAM,UAAU,GAAG,gBAAgB,sBAAsB,CAAC,MAA6C,CAAC,EAAE,CAAC;YAC3G,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;YACzC,OAAO,MAAM,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,YAAY,CAAC,mBAAmB,MAAM,0BAA0B,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;SAAM,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;QACxC,yCAAyC;QACzC,OAAO,MAAO,MAAsD,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"jiraClient.js","sourceRoot":"","sources":["../../../src/helpers/jira/jiraClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"jiraClient.js","sourceRoot":"","sources":["../../../src/helpers/jira/jiraClient.ts"],"names":[],"mappings":"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"}
@@ -5,4 +5,16 @@ export interface ReviewContext {
5
5
  /** PR number under review; undefined in `gth pr` discovery mode (current branch's PR). */
6
6
  prId?: string;
7
7
  }
8
- export declare function review(source: string, preamble: string, diff: string, config: GthConfig, command?: 'pr' | 'review', resolvers?: AgentResolvers, reviewContext?: ReviewContext): Promise<void>;
8
+ /**
9
+ * Run a review of `diff` and print the verdict.
10
+ *
11
+ * @param source - Source label, used for the output file name.
12
+ * @param _preamble - Ignored (GS2-79); see the body comment. Retained positionally so existing
13
+ * callers need no change, exactly as `runSingleShot` retains its own.
14
+ * @param diff - The content under review.
15
+ * @param config - The resolved config.
16
+ * @param command - `review` or `pr`; selects the command config and the agent's mode prompt.
17
+ * @param resolvers - Optional agent resolvers (tools/middleware).
18
+ * @param reviewContext - Extra review context (binds GitHub-only tools to the PR under review).
19
+ */
20
+ export declare function review(source: string, _preamble: string, diff: string, config: GthConfig, command?: 'pr' | 'review', resolvers?: AgentResolvers, reviewContext?: ReviewContext): Promise<void>;
@@ -1,6 +1,6 @@
1
1
  import { defaultStatusCallback, displayDebug, displayError, displayInfo, displaySuccess, displayWarning, flushSessionLog, initSessionLogging, stopSessionLogging, } from '@gaunt-sloth/core/utils/consoleUtils.js';
2
2
  import { getCommandOutputFilePath } from '#src/utils/fileUtils.js';
3
- import { HumanMessage, SystemMessage } from '@langchain/core/messages';
3
+ import { HumanMessage } from '@langchain/core/messages';
4
4
  import { GthAgentRunner } from '@gaunt-sloth/core/core/GthAgentRunner.js';
5
5
  import { MemorySaver } from '@langchain/langgraph';
6
6
  import { ProgressIndicator } from '@gaunt-sloth/core/utils/ProgressIndicator.js';
@@ -8,66 +8,113 @@ import { createReviewRateMiddleware, REVIEW_RATE_ARTIFACT_KEY, } from '#src/midd
8
8
  import { deleteArtifact, getArtifact } from '@gaunt-sloth/core/state/artifactStore.js';
9
9
  import { setExitCode } from '@gaunt-sloth/core/utils/systemUtils.js';
10
10
  import { get as getGhReadFileTool, GTH_GH_READ_FILE_TOOL_NAME } from '#src/tools/ghReadFileTool.js';
11
- export async function review(source, preamble, diff, config, command = 'review', resolvers, reviewContext) {
11
+ /**
12
+ * Run a review of `diff` and print the verdict.
13
+ *
14
+ * @param source - Source label, used for the output file name.
15
+ * @param _preamble - Ignored (GS2-79); see the body comment. Retained positionally so existing
16
+ * callers need no change, exactly as `runSingleShot` retains its own.
17
+ * @param diff - The content under review.
18
+ * @param config - The resolved config.
19
+ * @param command - `review` or `pr`; selects the command config and the agent's mode prompt.
20
+ * @param resolvers - Optional agent resolvers (tools/middleware).
21
+ * @param reviewContext - Extra review context (binds GitHub-only tools to the PR under review).
22
+ */
23
+ export async function review(source,
24
+ // GS2-79: `_preamble` is retained for signature stability but is NO LONGER injected as a leading
25
+ // SystemMessage. Both agent backends COMPOSE the full system prompt themselves — backstory +
26
+ // guidelines + the per-command mode prompt + system prompt — and hand it to createAgent as
27
+ // `systemPrompt`; for `review`/`pr` that mode prompt IS the review instructions (core's
28
+ // `readModePrompt`). Passing this preamble as well produced TWO system messages, which
29
+ // `@langchain/anthropic` rejects outright ("System messages are only permitted as the first
30
+ // passed message"), breaking every `gth review` and `gth pr` run on Anthropic on both backends
31
+ // (Google/OpenAI silently merged them, so only Anthropic showed it). The same removal was made in
32
+ // `runSingleShot` and `conversation` for the same reason.
33
+ //
34
+ // Dropping it is content-preserving ONLY because the backends now select the review instructions:
35
+ // before that they composed the CHAT prompt for `review`/`pr`, so removing the preamble alone
36
+ // would have silently turned a review into a chat. `GthPromptParity.spec.ts` pins that.
37
+ _preamble, diff, config, command = 'review', resolvers, reviewContext) {
12
38
  const progressIndicator = config.streamOutput ? undefined : new ProgressIndicator('Reviewing.');
13
- const messages = [new SystemMessage(preamble), new HumanMessage(diff)];
14
- // REL-2: optionally give the review agent a `gh api` file-read tool so it can fetch the FULL
15
- // contents of a file when the PR diff truncates large changes. Only added in a GitHub PR
16
- // context (the content source resolves to GitHub); a graceful no-op otherwise. Reads through
17
- // the GitHub API rather than the workspace filesystem, so it is safe under pull_request_target.
18
- maybeAddGhReadFileTool(config, command, reviewContext?.prId);
19
- // Prepare logging path (if enabled by config)
20
- const filePath = getCommandOutputFilePath(config, source);
21
- if (filePath) {
22
- initSessionLogging(filePath, config.streamSessionInferenceLog);
23
- }
24
- const rateConfig = config.commands?.[command]?.rating;
25
- if (rateConfig && rateConfig.enabled !== false) {
26
- const confMiddleware = config.middleware || [];
27
- const middlewareWithoutReviewRate = confMiddleware.filter((mw) => {
28
- return !(typeof mw === 'object' &&
29
- mw !== null &&
30
- 'name' in mw &&
31
- mw.name === 'review-rate');
32
- });
33
- // Resolve review-rate middleware directly rather than going through the registry
34
- const reviewRateMiddleware = await createReviewRateMiddleware(rateConfig, config);
35
- config.middleware = [...middlewareWithoutReviewRate, reviewRateMiddleware];
36
- }
37
- // When no resolvers are provided (e.g. standalone review CLI, without @gaunt-sloth/agent's
38
- // resolvers), supply a minimal middleware resolver that passes through already-resolved
39
- // middleware. The full `gaunt-sloth` CLI injects @gaunt-sloth/agent's resolvers instead.
40
- const effectiveResolvers = resolvers ?? {
41
- resolveMiddleware: async (middleware) => middleware ?? [],
42
- };
43
- const runner = new GthAgentRunner(defaultStatusCallback, effectiveResolvers);
44
39
  try {
45
- await runner.init(command, config, new MemorySaver());
46
- await runner.processMessages(messages);
47
- }
48
- catch (error) {
49
- displayDebug(error instanceof Error ? error : String(error));
50
- const reason = error instanceof Error ? error.message : String(error);
51
- displayError(reason ? `Failed to run review with agent.\n\n${reason}` : 'Failed to run review with agent.');
52
- }
53
- finally {
54
- await runner.cleanup();
55
- }
56
- progressIndicator?.stop();
57
- handleRatingResult(rateConfig, command);
58
- // Close the file AFTER rating is written
59
- if (filePath) {
40
+ // Only the human turn: the agent supplies the system prompt via `createAgent({ systemPrompt })`.
41
+ const messages = [new HumanMessage(diff)];
42
+ // REL-2: optionally give the review agent a `gh api` file-read tool so it can fetch the FULL
43
+ // contents of a file when the PR diff truncates large changes. Only added in a GitHub PR
44
+ // context (the content source resolves to GitHub); a graceful no-op otherwise. Reads through
45
+ // the GitHub API rather than the workspace filesystem, so it is safe under pull_request_target.
46
+ maybeAddGhReadFileTool(config, command, reviewContext?.prId);
47
+ // Prepare logging path (if enabled by config)
48
+ const filePath = getCommandOutputFilePath(config, source);
49
+ if (filePath) {
50
+ initSessionLogging(filePath, config.streamSessionInferenceLog);
51
+ }
52
+ const rateConfig = config.commands?.[command]?.rating;
53
+ if (rateConfig && rateConfig.enabled !== false) {
54
+ const confMiddleware = config.middleware || [];
55
+ const middlewareWithoutReviewRate = confMiddleware.filter((mw) => {
56
+ return !(typeof mw === 'object' &&
57
+ mw !== null &&
58
+ 'name' in mw &&
59
+ mw.name === 'review-rate');
60
+ });
61
+ // Resolve review-rate middleware directly rather than going through the registry
62
+ const reviewRateMiddleware = await createReviewRateMiddleware(rateConfig, config);
63
+ config.middleware = [...middlewareWithoutReviewRate, reviewRateMiddleware];
64
+ }
65
+ // When no resolvers are provided (e.g. standalone review CLI, without @gaunt-sloth/agent's
66
+ // resolvers), supply a minimal middleware resolver that passes through already-resolved
67
+ // middleware. The full `gaunt-sloth` CLI injects @gaunt-sloth/agent's resolvers instead.
68
+ const effectiveResolvers = resolvers ?? {
69
+ resolveMiddleware: async (middleware) => middleware ?? [],
70
+ };
71
+ // GS2-81: no backend factory, so `review`/`pr` always run the lean agent — `@gaunt-sloth/review`
72
+ // is a leaf package that does not depend on `@gaunt-sloth/agent` and cannot reach the deep
73
+ // backend. `agent.backend` is therefore a command-scoped key, and the runner says so out loud
74
+ // when a config asks for `deep` here rather than dropping it in silence. Giving this package a
75
+ // dependency on the agent package to honour the key instead would invert the layering AND
76
+ // silently change what an existing review does.
77
+ const runner = new GthAgentRunner(defaultStatusCallback, effectiveResolvers);
60
78
  try {
61
- flushSessionLog();
62
- stopSessionLogging();
63
- displaySuccess(`\n\nThis report can be found in ${filePath}`);
79
+ await runner.init(command, config, new MemorySaver());
80
+ await runner.processMessages(messages);
64
81
  }
65
82
  catch (error) {
66
83
  displayDebug(error instanceof Error ? error : String(error));
67
- displayError(`Failed to write review to file: ${filePath}`);
84
+ const reason = error instanceof Error ? error.message : String(error);
85
+ displayError(reason
86
+ ? `Failed to run review with agent.\n\n${reason}`
87
+ : 'Failed to run review with agent.');
88
+ }
89
+ finally {
90
+ await runner.cleanup();
68
91
  }
92
+ progressIndicator?.stop();
93
+ handleRatingResult(rateConfig, command);
94
+ // Close the file AFTER rating is written
95
+ if (filePath) {
96
+ try {
97
+ flushSessionLog();
98
+ stopSessionLogging();
99
+ displaySuccess(`\n\nThis report can be found in ${filePath}`);
100
+ }
101
+ catch (error) {
102
+ displayDebug(error instanceof Error ? error : String(error));
103
+ displayError(`Failed to write review to file: ${filePath}`);
104
+ }
105
+ }
106
+ deleteArtifact(REVIEW_RATE_ARTIFACT_KEY);
107
+ }
108
+ finally {
109
+ // EXT-53: the indicator owns a 1s setInterval — an active libuv handle that keeps Node's event
110
+ // loop from ever draining, so leaking it hangs the CLI forever after the work is done. The
111
+ // `stop()` above sits where it does for output ordering (before the rating result / the
112
+ // "report can be found in …" line); this `finally` guarantees the handle is also released when
113
+ // anything above throws — notably `createReviewRateMiddleware()`, which is awaited outside any
114
+ // catch, and `runner.cleanup()`, whose own `finally` rethrows straight past the `stop()`.
115
+ // `stop()` is idempotent, so the normal path's second call is a no-op.
116
+ progressIndicator?.stop();
69
117
  }
70
- deleteArtifact(REVIEW_RATE_ARTIFACT_KEY);
71
118
  }
72
119
  /**
73
120
  * REL-2: conditionally inject the optional `gh api` file-read tool into the review agent's tools.
@@ -81,11 +128,7 @@ export async function review(source, preamble, diff, config, command = 'review',
81
128
  */
82
129
  function maybeAddGhReadFileTool(config, command, prId) {
83
130
  const commandConfig = config.commands?.[command];
84
- // Honor deprecated alias too: contentProvider.
85
- const contentSource = commandConfig?.contentSource ??
86
- commandConfig?.contentProvider ??
87
- config.contentSource ??
88
- config.contentProvider;
131
+ const contentSource = commandConfig?.contentSource ?? config.contentSource;
89
132
  if (contentSource !== 'github') {
90
133
  return;
91
134
  }
@@ -1 +1 @@
1
- {"version":3,"file":"reviewModule.js","sourceRoot":"","sources":["../../src/modules/reviewModule.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reviewModule.js","sourceRoot":"","sources":["../../src/modules/reviewModule.ts"],"names":[],"mappings":"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"}
@@ -21,16 +21,16 @@ export async function get(_, issueId) {
21
21
  return null;
22
22
  }
23
23
  const issueLabel = /^\d+$/.test(issueId) ? `#${issueId}` : issueId;
24
+ // EXT-53: the indicator is constructed OUTSIDE the try and cleared in a `finally`. It owns a 1s
25
+ // setInterval — an active libuv handle — so a `stop()` reachable only on the success path leaves
26
+ // the event loop un-drainable and the process never exits. This is especially nasty here because
27
+ // a failed issue fetch is a SOFT failure (returns null, the review proceeds), so the hang is
28
+ // invisible: the command succeeds and then simply never returns.
29
+ const progress = new ProgressIndicator(`Fetching GitHub issue ${issueLabel}`);
30
+ let issueContent;
24
31
  try {
25
32
  // Use the GitHub CLI to fetch issue details
26
- const progress = new ProgressIndicator(`Fetching GitHub issue ${issueLabel}`);
27
- const issueContent = await execAsync(`gh issue view ${issueId}`);
28
- progress.stop();
29
- if (!issueContent) {
30
- displayWarning(`No content found for GitHub issue ${issueLabel}`);
31
- return null;
32
- }
33
- return `GitHub Issue: ${issueLabel}\n\n${issueContent}`;
33
+ issueContent = await execAsync(`gh issue view ${issueId}`);
34
34
  }
35
35
  catch (error) {
36
36
  displayWarning(`
@@ -39,5 +39,13 @@ Consider checking if gh cli (https://cli.github.com/) is installed and authentic
39
39
  `);
40
40
  return null;
41
41
  }
42
+ finally {
43
+ progress.stop();
44
+ }
45
+ if (!issueContent) {
46
+ displayWarning(`No content found for GitHub issue ${issueLabel}`);
47
+ return null;
48
+ }
49
+ return `GitHub Issue: ${issueLabel}\n\n${issueContent}`;
42
50
  }
43
51
  //# sourceMappingURL=ghIssueSource.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ghIssueSource.js","sourceRoot":"","sources":["../../src/sources/ghIssueSource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8CAA8C,CAAC;AAEjF,6FAA6F;AAC7F,sFAAsF;AACtF,kFAAkF;AAClF,MAAM,iBAAiB,GAAG,gEAAgE,CAAC;AAE3F;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,GAAG,CACvB,CAAwB,EACxB,OAA2B;IAE3B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,cAAc,CAAC,iCAAiC,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACrC,cAAc,CACZ,mCAAmC,OAAO,8FAA8F,CACzI,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;IAEnE,IAAI,CAAC;QACH,4CAA4C;QAC5C,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC,yBAAyB,UAAU,EAAE,CAAC,CAAC;QAC9E,MAAM,YAAY,GAAG,MAAM,SAAS,CAAC,iBAAiB,OAAO,EAAE,CAAC,CAAC;QACjE,QAAQ,CAAC,IAAI,EAAE,CAAC;QAEhB,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,cAAc,CAAC,qCAAqC,UAAU,EAAE,CAAC,CAAC;YAClE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,iBAAiB,UAAU,OAAO,YAAY,EAAE,CAAC;IAC1D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,cAAc,CAAC;6BACU,UAAU,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;;KAE7F,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"ghIssueSource.js","sourceRoot":"","sources":["../../src/sources/ghIssueSource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8CAA8C,CAAC;AAEjF,6FAA6F;AAC7F,sFAAsF;AACtF,kFAAkF;AAClF,MAAM,iBAAiB,GAAG,gEAAgE,CAAC;AAE3F;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,GAAG,CACvB,CAAwB,EACxB,OAA2B;IAE3B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,cAAc,CAAC,iCAAiC,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACrC,cAAc,CACZ,mCAAmC,OAAO,8FAA8F,CACzI,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;IAEnE,gGAAgG;IAChG,iGAAiG;IACjG,iGAAiG;IACjG,6FAA6F;IAC7F,iEAAiE;IACjE,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC,yBAAyB,UAAU,EAAE,CAAC,CAAC;IAC9E,IAAI,YAAoB,CAAC;IACzB,IAAI,CAAC;QACH,4CAA4C;QAC5C,YAAY,GAAG,MAAM,SAAS,CAAC,iBAAiB,OAAO,EAAE,CAAC,CAAC;IAC7D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,cAAc,CAAC;6BACU,UAAU,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;;KAE7F,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;YAAS,CAAC;QACT,QAAQ,CAAC,IAAI,EAAE,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,cAAc,CAAC,qCAAqC,UAAU,EAAE,CAAC,CAAC;QAClE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,iBAAiB,UAAU,OAAO,YAAY,EAAE,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { ProviderConfig } from './types.js';
2
+ /**
3
+ * Gets a local diff via `git --no-pager diff [refRange]` — review the working tree (or a
4
+ * ref range) without GitHub and without piping a diff through stdin.
5
+ *
6
+ * @param _ config (unused in this source)
7
+ * @param refRange optional revision selection passed to `git diff`, e.g. `origin/main...HEAD`
8
+ * or `HEAD~3`. When omitted, diffs the working tree against the index (plain `git diff`).
9
+ * @returns the diff content; throws with a clear message outside a git repository, on a bad
10
+ * ref, or when the diff is empty (an empty review would otherwise run against no content).
11
+ */
12
+ export declare function get(_: ProviderConfig | null, refRange: string | undefined): Promise<string | null>;
@@ -0,0 +1,75 @@
1
+ import { ProgressIndicator } from '@gaunt-sloth/core/utils/ProgressIndicator.js';
2
+ /**
3
+ * `git diff` can emit multi-megabyte output for large changes; the node default (1 MiB)
4
+ * would truncate-and-fail such runs.
5
+ */
6
+ const MAX_DIFF_BUFFER = 32 * 1024 * 1024;
7
+ /**
8
+ * Gets a local diff via `git --no-pager diff [refRange]` — review the working tree (or a
9
+ * ref range) without GitHub and without piping a diff through stdin.
10
+ *
11
+ * @param _ config (unused in this source)
12
+ * @param refRange optional revision selection passed to `git diff`, e.g. `origin/main...HEAD`
13
+ * or `HEAD~3`. When omitted, diffs the working tree against the index (plain `git diff`).
14
+ * @returns the diff content; throws with a clear message outside a git repository, on a bad
15
+ * ref, or when the diff is empty (an empty review would otherwise run against no content).
16
+ */
17
+ export async function get(_, refRange) {
18
+ // Args go to execFile (no shell), so shell metacharacters are inert; still reject
19
+ // option-shaped input so an id can never become a git flag (e.g. `--output=<file>`).
20
+ if (refRange && refRange.startsWith('-')) {
21
+ throw new Error(`Invalid git diff argument "${refRange}"; expected a ref or ref range (e.g. "origin/main...HEAD"), not an option.`);
22
+ }
23
+ const label = refRange ? `for "${refRange}"` : 'for the working tree';
24
+ const gitArgs = ['--no-pager', 'diff', ...(refRange ? [refRange] : [])];
25
+ const progress = new ProgressIndicator(`Getting local git diff ${label}`);
26
+ try {
27
+ const diffContent = await runGit(gitArgs);
28
+ progress.stop();
29
+ if (!diffContent.trim()) {
30
+ throw new Error(`No changes found in git diff ${label}; nothing to review.`);
31
+ }
32
+ return `Local git diff ${label}\n\n${diffContent}`;
33
+ }
34
+ catch (error) {
35
+ progress.stop();
36
+ const reason = error instanceof Error ? error.message : String(error);
37
+ if (reason.startsWith('No changes found')) {
38
+ throw new Error(reason);
39
+ }
40
+ throw new Error(`Failed to get git diff ${label}: ${reason}\nConsider checking that you are inside a git repository and the ref range is valid.`);
41
+ }
42
+ }
43
+ /**
44
+ * Run git with an args array (execFile, no shell). Rejects on a non-zero exit or spawn
45
+ * failure with git's stderr as the reason; benign stderr chatter on a zero exit is ignored
46
+ * (unlike systemUtils.execAsync, which rejects on any stderr output).
47
+ */
48
+ async function runGit(args) {
49
+ const { execFile } = await import('node:child_process');
50
+ return new Promise((resolve, reject) => {
51
+ execFile('git', args, { maxBuffer: MAX_DIFF_BUFFER }, (error, stdout, stderr) => {
52
+ if (error) {
53
+ reject(new Error(extractGitError(stderr ?? '', error.message)));
54
+ return;
55
+ }
56
+ resolve(stdout);
57
+ });
58
+ });
59
+ }
60
+ /**
61
+ * Reduce git's stderr to the one meaningful line. Outside a repository `git diff` appends
62
+ * its entire `--no-index` usage screen after the warning line; that wall of text is noise
63
+ * in a CLI error. Prefer the `fatal:` line when present, else the first non-empty line.
64
+ */
65
+ function extractGitError(stderr, fallback) {
66
+ const lines = stderr
67
+ .split('\n')
68
+ .map((line) => line.trim())
69
+ .filter(Boolean);
70
+ if (lines.length === 0) {
71
+ return fallback;
72
+ }
73
+ return lines.find((line) => line.startsWith('fatal:')) ?? lines[0];
74
+ }
75
+ //# sourceMappingURL=gitDiffSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitDiffSource.js","sourceRoot":"","sources":["../../src/sources/gitDiffSource.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,8 @@ import type { JiraConfig } from './types.js';
2
2
  /**
3
3
  * Gets Jira issue using Atlassian REST API v3 with Personal Access Token
4
4
  *
5
- * TODO we need to figure out how would this work with public jira.
5
+ * Requires an authenticated Atlassian Cloud instance (Cloud ID + API token); anonymous
6
+ * access to a public Jira instance is not supported.
6
7
  *
7
8
  * @param config Jira configuration
8
9
  * @param issueId Jira issue ID
@@ -3,7 +3,8 @@ import { getJiraCredentials, jiraRequest, } from '#src/helpers/jira/jiraClient.j
3
3
  /**
4
4
  * Gets Jira issue using Atlassian REST API v3 with Personal Access Token
5
5
  *
6
- * TODO we need to figure out how would this work with public jira.
6
+ * Requires an authenticated Atlassian Cloud instance (Cloud ID + API token); anonymous
7
+ * access to a public Jira instance is not supported.
7
8
  *
8
9
  * @param config Jira configuration
9
10
  * @param issueId Jira issue ID
@@ -1 +1 @@
1
- {"version":3,"file":"jiraIssueSource.js","sourceRoot":"","sources":["../../src/sources/jiraIssueSource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAEhG,OAAO,EACL,kBAAkB,EAClB,WAAW,GAEZ,MAAM,iCAAiC,CAAC;AAYzC;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,GAAG,CACvB,MAAkC,EAClC,OAA2B;IAE3B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,cAAc,CAAC,yBAAyB,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,cAAc,CAAC,sBAAsB,CAAC,CAAC;QACvC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAE/C,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACvD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,IAAI,CAAC;QACd,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;IACvF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,YAAY,CACV,6BAA6B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CACtF,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,KAAK,UAAU,YAAY,CACzB,WAAoC,EACpC,OAAe;IAEf,sGAAsG;IAEtG,0KAA0K;IAC1K,sHAAsH;IACtH,8CAA8C;IAC9C,qHAAqH;IACrH,qGAAqG;IAErG,IAAI,WAAW,CAAC,UAAU,EAAE,CAAC;QAC3B,OAAO,CAAC,sBAAsB,WAAW,CAAC,UAAU,GAAG,OAAO,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,wFAAwF;IACxF,MAAM,OAAO,GAAG,6BAA6B,CAAC,CAAC,wCAAwC;IAEvF,OAAO,WAAW,CAAoB,WAAW,EAAE,qBAAqB,OAAO,GAAG,OAAO,EAAE,EAAE;QAC3F,MAAM,EAAE,KAAK;KACd,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"jiraIssueSource.js","sourceRoot":"","sources":["../../src/sources/jiraIssueSource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAEhG,OAAO,EACL,kBAAkB,EAClB,WAAW,GAEZ,MAAM,iCAAiC,CAAC;AAYzC;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,GAAG,CACvB,MAAkC,EAClC,OAA2B;IAE3B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,cAAc,CAAC,yBAAyB,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,cAAc,CAAC,sBAAsB,CAAC,CAAC;QACvC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAE/C,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACvD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,IAAI,CAAC;QACd,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;IACvF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,YAAY,CACV,6BAA6B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CACtF,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,KAAK,UAAU,YAAY,CACzB,WAAoC,EACpC,OAAe;IAEf,sGAAsG;IAEtG,0KAA0K;IAC1K,sHAAsH;IACtH,8CAA8C;IAC9C,qHAAqH;IACrH,qGAAqG;IAErG,IAAI,WAAW,CAAC,UAAU,EAAE,CAAC;QAC3B,OAAO,CAAC,sBAAsB,WAAW,CAAC,UAAU,GAAG,OAAO,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,wFAAwF;IACxF,MAAM,OAAO,GAAG,6BAA6B,CAAC,CAAC,wCAAwC;IAEvF,OAAO,WAAW,CAAoB,WAAW,EAAE,qBAAqB,OAAO,GAAG,OAAO,EAAE,EAAE;QAC3F,MAAM,EAAE,KAAK;KACd,CAAC,CAAC;AACL,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gaunt-sloth/review",
3
- "version": "2.0.0-alpha.3",
3
+ "version": "2.0.0-alpha.30",
4
4
  "description": "Review functionality for Gaunt Sloth",
5
5
  "license": "MIT",
6
6
  "author": "Andrew Kondratev",
@@ -34,11 +34,11 @@
34
34
  "#src/*.js": "./dist/*.js"
35
35
  },
36
36
  "dependencies": {
37
- "@langchain/core": "^1.2.0",
38
- "@langchain/langgraph": "^1.4.4",
39
- "langchain": "^1.5.0",
40
- "zod": "^3.25.0 || ^4.0.0",
41
- "@gaunt-sloth/core": "2.0.0-alpha.3"
37
+ "@langchain/core": "^1.2.3",
38
+ "@langchain/langgraph": "^1.4.8",
39
+ "langchain": "^1.5.4",
40
+ "zod": "^4.4.3",
41
+ "@gaunt-sloth/core": "2.0.0-alpha.30"
42
42
  },
43
43
  "files": [
44
44
  "./dist/*",