sf-git-ai-meta-insights 2.1.0 → 2.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/CHANGELOG.md +14 -0
- package/README.md +77 -28
- package/lib/ai/llmProviderConfig.d.ts +8 -0
- package/lib/ai/llmProviderConfig.js +2 -0
- package/lib/ai/llmProviderConfig.js.map +1 -0
- package/lib/ai/salesforceMetadataPrompt.d.ts +2 -2
- package/lib/ai/salesforceMetadataPrompt.js +2 -1
- package/lib/ai/salesforceMetadataPrompt.js.map +1 -1
- package/lib/commands/sgai/metadata/summarize.d.ts +6 -1
- package/lib/commands/sgai/metadata/summarize.js +52 -4
- package/lib/commands/sgai/metadata/summarize.js.map +1 -1
- package/messages/sgai.metadata.summarize.md +45 -4
- package/oclif.manifest.json +49 -7
- package/package.json +41 -21
- package/lib/ai/openAiConfig.d.ts +0 -5
- package/lib/ai/openAiConfig.js +0 -2
- package/lib/ai/openAiConfig.js.map +0 -1
- package/oclif.lock +0 -9685
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.3.0](https://github.com/mcarvin8/sf-git-ai-meta-insights/compare/v2.2.0...v2.3.0) (2026-04-24)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **diff:** add CLI flags for unified-diff token-reduction controls ([#20](https://github.com/mcarvin8/sf-git-ai-meta-insights/issues/20)) ([cbc5523](https://github.com/mcarvin8/sf-git-ai-meta-insights/commit/cbc5523959bbbc2f38aa1410a6f24170f2163c7b))
|
|
9
|
+
|
|
10
|
+
## [2.2.0](https://github.com/mcarvin8/sf-git-ai-meta-insights/compare/v2.1.0...v2.2.0) (2026-04-21)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* **ai:** support all Vercel AI SDK providers via smart-diff v2 ([#16](https://github.com/mcarvin8/sf-git-ai-meta-insights/issues/16)) ([8be7458](https://github.com/mcarvin8/sf-git-ai-meta-insights/commit/8be7458111081e5cad3f07646b08346154f2401b))
|
|
16
|
+
|
|
3
17
|
## [2.1.0](https://github.com/mcarvin8/sf-git-ai-meta-insights/compare/v2.0.1...v2.1.0) (2026-04-19)
|
|
4
18
|
|
|
5
19
|
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
## Overview
|
|
11
11
|
|
|
12
|
-
This plugin summarizes metadata changes between two Git refs, optionally filters commits by message, and writes a Markdown file using
|
|
12
|
+
This plugin summarizes metadata changes between two Git refs, optionally filters commits by message, and writes a Markdown file using any LLM provider supported by the [Vercel AI SDK](https://sdk.vercel.ai) — OpenAI, Anthropic, Google Gemini, Amazon Bedrock, Mistral, Cohere, Groq, xAI, DeepSeek, or any OpenAI-compatible gateway. A configured provider (API key, base URL, and/or default headers) is **required**.
|
|
13
13
|
|
|
14
14
|

|
|
15
15
|
|
|
@@ -27,18 +27,23 @@ Summarize metadata changes between two Git refs and write the generated summary
|
|
|
27
27
|
|
|
28
28
|
#### Flags
|
|
29
29
|
|
|
30
|
-
| Flag | Short | Required | Default | Description
|
|
31
|
-
| ----------------------------- | ----- | -------- | --------------------- |
|
|
32
|
-
| `--from` | `-f` | Yes | | Start reference for the git diff range (e.g. `HEAD~1`, a tag, or a commit hash).
|
|
33
|
-
| `--to` | `-t` | No | `HEAD` | End reference for the git diff range.
|
|
34
|
-
| `--commit-message-include` | `-m` | No | | Include commits whose messages match any of these regex patterns (repeatable, OR).
|
|
35
|
-
| `--commit-message-exclude` | `-e` | No | | Exclude commits whose messages match any of these regex patterns (repeatable, OR).
|
|
36
|
-
| `--include-package-directory` | `-i` | No | | Extra repo-relative package paths merged with `sfdx-project.json` directories (repeatable).
|
|
37
|
-
| `--exclude-package-directory` | `-x` | No | | Exclude package paths from the configured list and add git `:(exclude)` pathspecs (repeatable).
|
|
38
|
-
| `--team` | | No | | Team or squad label for the summary (also via `METADATA_AUDIT_TEAM` or `SF_GIT_AI_TEAM`).
|
|
39
|
-
| `--output` | `-p` | No | `metadata-summary.md` | Output file path for the generated summary.
|
|
40
|
-
| `--model` | | No | `gpt-4o-mini`
|
|
41
|
-
| `--max-diff-chars` | | No | | Max characters of unified diff text sent to the model (5,000–5,000,000).
|
|
30
|
+
| Flag | Short | Required | Default | Description |
|
|
31
|
+
| ----------------------------- | ----- | -------- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
32
|
+
| `--from` | `-f` | Yes | | Start reference for the git diff range (e.g. `HEAD~1`, a tag, or a commit hash). |
|
|
33
|
+
| `--to` | `-t` | No | `HEAD` | End reference for the git diff range. |
|
|
34
|
+
| `--commit-message-include` | `-m` | No | | Include commits whose messages match any of these regex patterns (repeatable, OR). |
|
|
35
|
+
| `--commit-message-exclude` | `-e` | No | | Exclude commits whose messages match any of these regex patterns (repeatable, OR). |
|
|
36
|
+
| `--include-package-directory` | `-i` | No | | Extra repo-relative package paths merged with `sfdx-project.json` directories (repeatable). |
|
|
37
|
+
| `--exclude-package-directory` | `-x` | No | | Exclude package paths from the configured list and add git `:(exclude)` pathspecs (repeatable). |
|
|
38
|
+
| `--team` | | No | | Team or squad label for the summary (also via `METADATA_AUDIT_TEAM` or `SF_GIT_AI_TEAM`). |
|
|
39
|
+
| `--output` | `-p` | No | `metadata-summary.md` | Output file path for the generated summary. |
|
|
40
|
+
| `--model` | | No | _provider default_ | Override the chat model id. Defaults to the resolved provider's default (e.g. `gpt-4o-mini` for OpenAI, `claude-3-5-haiku-latest` for Anthropic). Can also be set with `LLM_MODEL`. |
|
|
41
|
+
| `--max-diff-chars` | | No | | Max characters of unified diff text sent to the model (5,000–5,000,000). |
|
|
42
|
+
| `--context-lines` | | No | _git default (3)_ | `git diff -U<n>` context lines around each change (0–1,000). Lower values cut tokens on modification-heavy diffs. |
|
|
43
|
+
| `--ignore-whitespace` | | No | `false` | Pass `-w` / `--ignore-all-space` to `git diff` so whitespace-only hunks don't consume tokens (also applied to `--numstat` / `--name-status`). |
|
|
44
|
+
| `--strip-diff-preamble` | | No | `false` | Drop low-value `diff --git`/`index`/`mode`/`similarity`/`rename`/`copy` lines from the unified diff; `--- a/…`, `+++ b/…`, and `@@` hunk headers are kept. |
|
|
45
|
+
| `--max-hunk-lines` | | No | | Cap each hunk's body (1–100,000); anything past the limit is elided to a single marker. `@@` header and `DiffSummary` totals stay intact. |
|
|
46
|
+
| `--exclude-default-noise` | | No | `false` | Merge smart-diff's built-in `DEFAULT_NOISE_EXCLUDES` list (lockfiles, `dist`, `build`, `out`, `coverage`, `node_modules`, `__snapshots__`) into excluded pathspecs. |
|
|
42
47
|
|
|
43
48
|
#### Examples
|
|
44
49
|
|
|
@@ -67,36 +72,82 @@ Summarize only commits whose messages match a regex:
|
|
|
67
72
|
sf sgai metadata summarize --from main --to HEAD --commit-message-include "(feature|fix)"
|
|
68
73
|
```
|
|
69
74
|
|
|
70
|
-
|
|
75
|
+
Override the chat model (any model id your configured provider supports):
|
|
71
76
|
|
|
72
77
|
```bash
|
|
73
|
-
sf sgai metadata summarize --from HEAD~1 --to HEAD --model
|
|
78
|
+
sf sgai metadata summarize --from HEAD~1 --to HEAD --model claude-3-5-sonnet-latest
|
|
74
79
|
```
|
|
75
80
|
|
|
81
|
+
Reduce LLM token cost with unified-diff shaping (ignore whitespace, trim context, elide huge hunks, strip low-value preamble lines):
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
sf sgai metadata summarize \
|
|
85
|
+
--from HEAD~5 --to HEAD \
|
|
86
|
+
--ignore-whitespace \
|
|
87
|
+
--context-lines 1 \
|
|
88
|
+
--strip-diff-preamble \
|
|
89
|
+
--max-hunk-lines 400
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
These flags only reshape the unified diff text sent to the model — the structured change inventory (file counts, additions, deletions) is computed separately and is always accurate. See the [`@mcarvin/smart-diff` "Reducing tokens" guide](https://github.com/mcarvin8/smart-diff#reducing-tokens) for details on each option.
|
|
93
|
+
|
|
76
94
|
## Requirements
|
|
77
95
|
|
|
78
96
|
- `sf` CLI installed
|
|
79
97
|
- Node.js 20 or later
|
|
80
|
-
-
|
|
98
|
+
- A configured LLM provider—see [Provider configuration](#provider-configuration)
|
|
81
99
|
- A Salesforce DX project repository with a `sfdx-project.json` file present in the repo root (unless you pass only `--include-package-directory` paths)
|
|
82
100
|
- [Git Bash](https://git-scm.com/install/)
|
|
83
101
|
|
|
84
102
|
This plugin reads `packageDirectories` from `sfdx-project.json` (when present) to scope the git diff, merges optional CLI include/exclude paths, then sends context to the model.
|
|
85
103
|
|
|
86
|
-
###
|
|
104
|
+
### Provider configuration
|
|
87
105
|
|
|
88
|
-
The plugin
|
|
106
|
+
The plugin delegates provider resolution to [`@mcarvin/smart-diff`](https://github.com/mcarvin8/smart-diff), which uses the Vercel AI SDK. Any of the supported providers below will work — set credentials for whichever one you want to use. If multiple are set, `LLM_PROVIDER` explicitly selects one; otherwise the resolver auto-detects based on which env vars are present.
|
|
89
107
|
|
|
90
|
-
|
|
|
91
|
-
|
|
|
92
|
-
| `
|
|
93
|
-
| `
|
|
94
|
-
| `
|
|
108
|
+
| Provider (`LLM_PROVIDER`) | Credential env vars | Default model |
|
|
109
|
+
| ------------------------- | -------------------------------------------------------------------------- | ------------------------------------------ |
|
|
110
|
+
| `openai` | `OPENAI_API_KEY` or `LLM_API_KEY` | `gpt-4o-mini` |
|
|
111
|
+
| `openai-compatible` | `LLM_BASE_URL`/`OPENAI_BASE_URL` (required); API key and/or custom headers | `gpt-4o-mini` |
|
|
112
|
+
| `anthropic` | `ANTHROPIC_API_KEY` | `claude-3-5-haiku-latest` |
|
|
113
|
+
| `google` | `GOOGLE_GENERATIVE_AI_API_KEY` or `GOOGLE_API_KEY` | `gemini-2.0-flash` |
|
|
114
|
+
| `bedrock` | Standard AWS credential chain (env / profile / role) | `anthropic.claude-3-5-haiku-20241022-v1:0` |
|
|
115
|
+
| `mistral` | `MISTRAL_API_KEY` | `mistral-small-latest` |
|
|
116
|
+
| `cohere` | `COHERE_API_KEY` | `command-r-08-2024` |
|
|
117
|
+
| `groq` | `GROQ_API_KEY` | `llama-3.1-8b-instant` |
|
|
118
|
+
| `xai` | `XAI_API_KEY` | `grok-2-latest` |
|
|
119
|
+
| `deepseek` | `DEEPSEEK_API_KEY` | `deepseek-chat` |
|
|
120
|
+
|
|
121
|
+
All supported provider SDKs ship with the plugin — once you run `sf plugins install sf-git-ai-meta-insights`, no extra `npm install` is needed to switch between OpenAI, Anthropic, Google, Bedrock, Mistral, Cohere, Groq, xAI, or DeepSeek. Just set the env vars for whichever provider you want to use.
|
|
122
|
+
|
|
123
|
+
#### Common env vars
|
|
124
|
+
|
|
125
|
+
| Variable | Purpose |
|
|
126
|
+
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- |
|
|
127
|
+
| `LLM_PROVIDER` | Explicit provider id from the table above. |
|
|
128
|
+
| `LLM_MODEL` | Overrides the per-provider default model id (also settable per-run via `--model`). |
|
|
129
|
+
| `OPENAI_BASE_URL` / `LLM_BASE_URL` | Base URL for an OpenAI-compatible gateway; presence alone auto-selects the `openai-compatible` provider. |
|
|
130
|
+
| `OPENAI_DEFAULT_HEADERS` / `LLM_DEFAULT_HEADERS` | JSON object of extra headers merged onto OpenAI / OpenAI-compatible requests. `LLM_*` overrides `OPENAI_*` key-by-key. |
|
|
131
|
+
| `OPENAI_MAX_DIFF_CHARS` / `LLM_MAX_DIFF_CHARS` | Max size of unified diff text sent to the model (default ~120k characters). Also settable per-run via `--max-diff-chars`. |
|
|
95
132
|
|
|
96
133
|
> `LLM_*` variants override their `OPENAI_*` counterparts when both are set.
|
|
97
|
-
> For the full list of supported environment variables, see the [`@mcarvin/smart-diff` documentation](https://github.com/mcarvin8/smart-diff#
|
|
134
|
+
> For the full list of supported environment variables, see the [`@mcarvin/smart-diff` documentation](https://github.com/mcarvin8/smart-diff#provider-configuration).
|
|
135
|
+
|
|
136
|
+
#### Example: native OpenAI
|
|
98
137
|
|
|
99
|
-
|
|
138
|
+
```powershell
|
|
139
|
+
$env:OPENAI_API_KEY = "sk-..."
|
|
140
|
+
sf sgai metadata summarize --from HEAD~1 --to HEAD
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
#### Example: Anthropic Claude
|
|
144
|
+
|
|
145
|
+
```powershell
|
|
146
|
+
$env:ANTHROPIC_API_KEY = "sk-ant-..."
|
|
147
|
+
sf sgai metadata summarize --from HEAD~1 --to HEAD --model claude-3-5-sonnet-latest
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
#### Example: company-managed OpenAI-compatible gateway
|
|
100
151
|
|
|
101
152
|
```powershell
|
|
102
153
|
$env:LLM_BASE_URL = "https://llm-gateway.mycompany.example/v1"
|
|
@@ -104,11 +155,9 @@ $env:LLM_DEFAULT_HEADERS = '{"Authorization":"Bearer <token>","x-tenant-id":"sal
|
|
|
104
155
|
sf sgai metadata summarize --from HEAD~1 --to HEAD
|
|
105
156
|
```
|
|
106
157
|
|
|
107
|
-

|
|
108
|
-
|
|
109
158
|
## Built With
|
|
110
159
|
|
|
111
|
-
The plugin's core logic is imported from [`@mcarvin/smart-diff`](https://github.com/mcarvin8/smart-diff) library,
|
|
160
|
+
The plugin's core logic is imported from the [`@mcarvin/smart-diff`](https://github.com/mcarvin8/smart-diff) library, a general-purpose tool that turns git diffs from any repository into Markdown summaries using any Vercel AI SDK provider.
|
|
112
161
|
|
|
113
162
|
## License
|
|
114
163
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM provider configuration — re-exported from `@mcarvin/smart-diff` so this plugin shares one implementation.
|
|
3
|
+
*
|
|
4
|
+
* `@mcarvin/smart-diff` v2 uses the Vercel AI SDK under the hood and supports OpenAI, OpenAI-compatible
|
|
5
|
+
* gateways, Anthropic, Google, Bedrock, Mistral, Cohere, Groq, xAI, and DeepSeek.
|
|
6
|
+
*/
|
|
7
|
+
export type { LlmProviderId, ResolveLanguageModelOptions } from '@mcarvin/smart-diff';
|
|
8
|
+
export { LLM_GATEWAY_REQUIRED_MESSAGE, defaultModelForProvider, detectLlmProvider, isLlmProviderConfigured, parseLlmDefaultHeadersFromEnv, resolveLanguageModel, resolveLlmBaseUrl, } from '@mcarvin/smart-diff';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llmProviderConfig.js","sourceRoot":"","sources":["../../src/ai/llmProviderConfig.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,EACvB,iBAAiB,EACjB,uBAAuB,EACvB,6BAA6B,EAC7B,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,qBAAqB,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/** System prompt
|
|
2
|
-
export declare const SALESFORCE_METADATA_SYSTEM_PROMPT = "You are a senior Salesforce architect helping developers understand Salesforce metadata changes from the git context they supplied.\nYou receive: commit subject lines (when available), changed metadata paths, and unified git patch(es) scoped to Salesforce metadata package directories\u2014either one range diff or concatenated per-commit patches, depending on how the diff was produced. Patches may be truncated mid-section with an explicit marker\u2014do not infer changes beyond visible lines.\nExplain what functionality changed: user-visible behavior, automations, integrations, data model, and security/access. Tie claims to the patch when possible.\nProduce a concise, developer-focused summary in Markdown.\nUse sections: Highlights, Risky or breaking changes, Data model changes, Automation & flows, Security & access.\nGroup related changes; do not list every individual component or file. When multiple commits appear in the context, briefly separate notable themes by commit when helpful.";
|
|
1
|
+
/** System prompt used by the configured LLM provider when summarizing Salesforce metadata git changes. */
|
|
2
|
+
export declare const SALESFORCE_METADATA_SYSTEM_PROMPT = "You are a senior Salesforce architect helping developers understand Salesforce metadata changes from the git context they supplied.\nYou receive: commit subject lines (when available), changed metadata paths, and unified git patch(es) scoped to Salesforce metadata package directories\u2014either one range diff or concatenated per-commit patches, depending on how the diff was produced. Patches may be truncated mid-section with an explicit marker\u2014do not infer changes beyond visible lines.\nExplain what functionality changed: user-visible behavior, automations, integrations, data model, and security/access. Tie claims to the patch when possible.\nProduce a concise, developer-focused summary in Markdown.\nBegin the output with the exact top-level heading \"# Metadata Change Summary\" (or \"# <Team> \u2013 Metadata Change Summary\" when the user message contains a Team line) and no content above it.\nUse sections: Highlights, Risky or breaking changes, Data model changes, Automation & flows, Security & access.\nGroup related changes; do not list every individual component or file. When multiple commits appear in the context, briefly separate notable themes by commit when helpful.";
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
/** System prompt
|
|
1
|
+
/** System prompt used by the configured LLM provider when summarizing Salesforce metadata git changes. */
|
|
2
2
|
export const SALESFORCE_METADATA_SYSTEM_PROMPT = `You are a senior Salesforce architect helping developers understand Salesforce metadata changes from the git context they supplied.
|
|
3
3
|
You receive: commit subject lines (when available), changed metadata paths, and unified git patch(es) scoped to Salesforce metadata package directories—either one range diff or concatenated per-commit patches, depending on how the diff was produced. Patches may be truncated mid-section with an explicit marker—do not infer changes beyond visible lines.
|
|
4
4
|
Explain what functionality changed: user-visible behavior, automations, integrations, data model, and security/access. Tie claims to the patch when possible.
|
|
5
5
|
Produce a concise, developer-focused summary in Markdown.
|
|
6
|
+
Begin the output with the exact top-level heading "# Metadata Change Summary" (or "# <Team> – Metadata Change Summary" when the user message contains a Team line) and no content above it.
|
|
6
7
|
Use sections: Highlights, Risky or breaking changes, Data model changes, Automation & flows, Security & access.
|
|
7
8
|
Group related changes; do not list every individual component or file. When multiple commits appear in the context, briefly separate notable themes by commit when helpful.`;
|
|
8
9
|
//# sourceMappingURL=salesforceMetadataPrompt.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"salesforceMetadataPrompt.js","sourceRoot":"","sources":["../../src/ai/salesforceMetadataPrompt.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"salesforceMetadataPrompt.js","sourceRoot":"","sources":["../../src/ai/salesforceMetadataPrompt.ts"],"names":[],"mappings":"AAAA,0GAA0G;AAC1G,MAAM,CAAC,MAAM,iCAAiC,GAAG;;;;;;4KAM2H,CAAC"}
|
|
@@ -15,8 +15,13 @@ export default class SgaiMetadataSummarize extends SfCommand<SgaiMetadataSummari
|
|
|
15
15
|
'exclude-package-directory': import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
16
|
team: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
17
|
output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
18
|
-
model: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
18
|
+
model: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
19
19
|
'max-diff-chars': import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
20
|
+
'context-lines': import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
21
|
+
'ignore-whitespace': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
22
|
+
'strip-diff-preamble': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
23
|
+
'max-hunk-lines': import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
24
|
+
'exclude-default-noise': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
20
25
|
};
|
|
21
26
|
run(): Promise<SgaiMetadataSummarizeResult>;
|
|
22
27
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { writeFile } from 'node:fs/promises';
|
|
2
2
|
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
|
|
3
3
|
import { Messages, SfError } from '@salesforce/core';
|
|
4
|
-
import { createGitClient, filterCommitsByMessageRegexes, getCommits,
|
|
4
|
+
import { createGitClient, filterCommitsByMessageRegexes, getCommits, isLlmProviderConfigured, LLM_GATEWAY_REQUIRED_MESSAGE, summarizeGitDiff, } from '@mcarvin/smart-diff';
|
|
5
5
|
import { SALESFORCE_METADATA_SYSTEM_PROMPT } from '../../../ai/salesforceMetadataPrompt.js';
|
|
6
6
|
import { resolveMetadataSummaryTeam } from '../../../salesforce/metadataSummaryContext.js';
|
|
7
7
|
import { getSalesforceMetadataIncludeFolders, normalizeRepoRelativeFolderPath, } from '../../../salesforce/sfdxPackagePaths.js';
|
|
@@ -14,6 +14,20 @@ function validateMaxDiffCharsRange(maxDiffChars) {
|
|
|
14
14
|
throw new SfError(`--max-diff-chars must be between 5000 and 5,000,000 (received ${maxDiffChars}).`, 'InvalidMaxDiffChars');
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
+
function validateContextLinesRange(contextLines) {
|
|
18
|
+
if (contextLines === undefined)
|
|
19
|
+
return;
|
|
20
|
+
if (!Number.isInteger(contextLines) || contextLines < 0 || contextLines > 1000) {
|
|
21
|
+
throw new SfError(`--context-lines must be an integer between 0 and 1000 (received ${contextLines}).`, 'InvalidContextLines');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function validateMaxHunkLinesRange(maxHunkLines) {
|
|
25
|
+
if (maxHunkLines === undefined)
|
|
26
|
+
return;
|
|
27
|
+
if (!Number.isInteger(maxHunkLines) || maxHunkLines < 1 || maxHunkLines > 100_000) {
|
|
28
|
+
throw new SfError(`--max-hunk-lines must be an integer between 1 and 100,000 (received ${maxHunkLines}).`, 'InvalidMaxHunkLines');
|
|
29
|
+
}
|
|
30
|
+
}
|
|
17
31
|
function getValidatedCommitMessageRegexLists(flags) {
|
|
18
32
|
const include = mergeUniqueStrings((flags['commit-message-include'] ?? []).map((s) => s.trim()).filter((s) => s.length > 0));
|
|
19
33
|
const exclude = (flags['commit-message-exclude'] ?? []).map((s) => s.trim()).filter((s) => s.length > 0);
|
|
@@ -145,19 +159,48 @@ export default class SgaiMetadataSummarize extends SfCommand {
|
|
|
145
159
|
summary: messages.getMessage('flags.model.summary'),
|
|
146
160
|
description: messages.getMessage('flags.model.description'),
|
|
147
161
|
required: false,
|
|
148
|
-
default: 'gpt-4o-mini',
|
|
149
162
|
}),
|
|
150
163
|
'max-diff-chars': Flags.integer({
|
|
151
164
|
summary: messages.getMessage('flags.max-diff-chars.summary'),
|
|
152
165
|
description: messages.getMessage('flags.max-diff-chars.description'),
|
|
153
166
|
required: false,
|
|
154
167
|
}),
|
|
168
|
+
'context-lines': Flags.integer({
|
|
169
|
+
summary: messages.getMessage('flags.context-lines.summary'),
|
|
170
|
+
description: messages.getMessage('flags.context-lines.description'),
|
|
171
|
+
required: false,
|
|
172
|
+
}),
|
|
173
|
+
'ignore-whitespace': Flags.boolean({
|
|
174
|
+
summary: messages.getMessage('flags.ignore-whitespace.summary'),
|
|
175
|
+
description: messages.getMessage('flags.ignore-whitespace.description'),
|
|
176
|
+
required: false,
|
|
177
|
+
default: false,
|
|
178
|
+
}),
|
|
179
|
+
'strip-diff-preamble': Flags.boolean({
|
|
180
|
+
summary: messages.getMessage('flags.strip-diff-preamble.summary'),
|
|
181
|
+
description: messages.getMessage('flags.strip-diff-preamble.description'),
|
|
182
|
+
required: false,
|
|
183
|
+
default: false,
|
|
184
|
+
}),
|
|
185
|
+
'max-hunk-lines': Flags.integer({
|
|
186
|
+
summary: messages.getMessage('flags.max-hunk-lines.summary'),
|
|
187
|
+
description: messages.getMessage('flags.max-hunk-lines.description'),
|
|
188
|
+
required: false,
|
|
189
|
+
}),
|
|
190
|
+
'exclude-default-noise': Flags.boolean({
|
|
191
|
+
summary: messages.getMessage('flags.exclude-default-noise.summary'),
|
|
192
|
+
description: messages.getMessage('flags.exclude-default-noise.description'),
|
|
193
|
+
required: false,
|
|
194
|
+
default: false,
|
|
195
|
+
}),
|
|
155
196
|
};
|
|
156
197
|
async run() {
|
|
157
198
|
const { flags } = await this.parse(SgaiMetadataSummarize);
|
|
158
199
|
validateMaxDiffCharsRange(flags['max-diff-chars']);
|
|
159
|
-
|
|
160
|
-
|
|
200
|
+
validateContextLinesRange(flags['context-lines']);
|
|
201
|
+
validateMaxHunkLinesRange(flags['max-hunk-lines']);
|
|
202
|
+
if (!isLlmProviderConfigured()) {
|
|
203
|
+
throw new SfError(LLM_GATEWAY_REQUIRED_MESSAGE, 'NoLlmProvider');
|
|
161
204
|
}
|
|
162
205
|
const from = flags.from;
|
|
163
206
|
const to = flags.to ?? 'HEAD';
|
|
@@ -186,6 +229,11 @@ export default class SgaiMetadataSummarize extends SfCommand {
|
|
|
186
229
|
maxDiffChars: maxDiffCharsFlag,
|
|
187
230
|
commitMessageIncludeRegexes: commitMessageIncludeRegexes.length > 0 ? commitMessageIncludeRegexes : undefined,
|
|
188
231
|
commitMessageExcludeRegexes: commitMessageExcludeFromFlag.length > 0 ? commitMessageExcludeFromFlag : undefined,
|
|
232
|
+
contextLines: flags['context-lines'],
|
|
233
|
+
ignoreWhitespace: flags['ignore-whitespace'] || undefined,
|
|
234
|
+
stripDiffPreamble: flags['strip-diff-preamble'] || undefined,
|
|
235
|
+
maxHunkLines: flags['max-hunk-lines'],
|
|
236
|
+
excludeDefaultNoise: flags['exclude-default-noise'] || undefined,
|
|
189
237
|
});
|
|
190
238
|
await writeFile(outputPath, summary, 'utf8');
|
|
191
239
|
this.log(`Generated metadata summary at ${outputPath}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summarize.js","sourceRoot":"","sources":["../../../../src/commands/sgai/metadata/summarize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,EACL,eAAe,EACf,6BAA6B,EAC7B,UAAU,EACV,4BAA4B,EAC5B,
|
|
1
|
+
{"version":3,"file":"summarize.js","sourceRoot":"","sources":["../../../../src/commands/sgai/metadata/summarize.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ Generate an AI-powered summary of changed Salesforce metadata from a git diff.
|
|
|
4
4
|
|
|
5
5
|
# description
|
|
6
6
|
|
|
7
|
-
Summarize metadata changes between two Git refs using
|
|
7
|
+
Summarize metadata changes between two Git refs using any LLM provider supported by the Vercel AI SDK — OpenAI, Anthropic, Google Gemini, Amazon Bedrock, Mistral, Cohere, Groq, xAI, DeepSeek, or any OpenAI-compatible gateway. A configured provider (API key, base URL, and/or default headers) is required — see the README for environment variables. Optionally filter commits by include/exclude message regexes, narrow paths with `--include-package-directory` / `--exclude-package-directory`, and write the model output to a markdown file.
|
|
8
8
|
|
|
9
9
|
# errors.noPackageDirectories
|
|
10
10
|
|
|
@@ -68,7 +68,7 @@ Optional team or squad label for the summary.
|
|
|
68
68
|
|
|
69
69
|
# flags.team.description
|
|
70
70
|
|
|
71
|
-
When set, includes a team line in the
|
|
71
|
+
When set, includes a team line in the LLM user prompt. If omitted, `METADATA_AUDIT_TEAM` or `SF_GIT_AI_TEAM` is used when set; otherwise no team is included.
|
|
72
72
|
|
|
73
73
|
# flags.output.summary
|
|
74
74
|
|
|
@@ -80,11 +80,11 @@ The path to the markdown file where the AI summary is written. Defaults to metad
|
|
|
80
80
|
|
|
81
81
|
# flags.model.summary
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
Chat model id used for the summary.
|
|
84
84
|
|
|
85
85
|
# flags.model.description
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
Override the chat model used when creating the AI-generated metadata summary. Must be a model id supported by the resolved LLM provider (for example `gpt-4o` for OpenAI, `claude-3-5-sonnet-latest` for Anthropic, `gemini-2.0-flash` for Google). When omitted, the plugin uses `LLM_MODEL` if set, otherwise the resolved provider's default model.
|
|
88
88
|
|
|
89
89
|
# flags.max-diff-chars.summary
|
|
90
90
|
|
|
@@ -94,9 +94,50 @@ Maximum size of the unified diff sent to the LLM (characters).
|
|
|
94
94
|
|
|
95
95
|
Large metadata diffs can exceed the model context window. The plugin sends at most this many characters of the unified diff (plus a fixed preamble). Allowed range is 5000 through 5000000 when set. Defaults to a conservative limit when unset; override with `LLM_MAX_DIFF_CHARS` or this flag. Only increase if your model and gateway support a larger context.
|
|
96
96
|
|
|
97
|
+
# flags.context-lines.summary
|
|
98
|
+
|
|
99
|
+
Number of context lines around each change in the unified diff.
|
|
100
|
+
|
|
101
|
+
# flags.context-lines.description
|
|
102
|
+
|
|
103
|
+
Sets `git diff -U<n>` when building the unified diff sent to the model. Lower values (1 or 0) are typically the single biggest token saver on modification-heavy diffs because they drop unchanged surrounding lines from each hunk. The structured diff summary (file counts and line totals) still reflects the full change. Allowed range is 0 through 1000 when set. When omitted, git's default (3) is used.
|
|
104
|
+
|
|
105
|
+
# flags.ignore-whitespace.summary
|
|
106
|
+
|
|
107
|
+
Ignore whitespace-only changes when building the diff.
|
|
108
|
+
|
|
109
|
+
# flags.ignore-whitespace.description
|
|
110
|
+
|
|
111
|
+
Passes `-w` / `--ignore-all-space` to `git diff` so pure-whitespace hunks don't consume tokens in the unified diff. This is also applied to the `--numstat` and `--name-status` calls used for the structured summary so file counts and line totals stay consistent with the diff text. Useful for Salesforce metadata XML where formatting churn is common. Defaults to false.
|
|
112
|
+
|
|
113
|
+
# flags.strip-diff-preamble.summary
|
|
114
|
+
|
|
115
|
+
Strip low-value `diff --git`/`index`/`mode`/`similarity`/`rename`/`copy` lines from the unified diff.
|
|
116
|
+
|
|
117
|
+
# flags.strip-diff-preamble.description
|
|
118
|
+
|
|
119
|
+
When set, removes the per-file git diff preamble lines that contain almost no semantic information (`diff --git`, `index`, `new file mode`, `deleted file mode`, `old mode`, `new mode`, `similarity index`, `dissimilarity index`, `rename from`/`rename to`, `copy from`/`copy to`). The `--- a/…`, `+++ b/…`, and `@@` hunk headers are preserved so the model can still attribute changes to files. Defaults to false.
|
|
120
|
+
|
|
121
|
+
# flags.max-hunk-lines.summary
|
|
122
|
+
|
|
123
|
+
Cap the body of each diff hunk; anything past the limit is elided.
|
|
124
|
+
|
|
125
|
+
# flags.max-hunk-lines.description
|
|
126
|
+
|
|
127
|
+
Limits the number of body lines retained per `@@` hunk in the unified diff. Lines past the limit are replaced with a single elision marker so the `@@` header and the structured diff summary totals are preserved. Use this to prevent a single massive hunk (for example a regenerated metadata file) from dominating the LLM prompt. Allowed range is 1 through 100000 when set. When omitted, hunks are not truncated.
|
|
128
|
+
|
|
129
|
+
# flags.exclude-default-noise.summary
|
|
130
|
+
|
|
131
|
+
Merge smart-diff's built-in "noise" exclude list into the excluded paths.
|
|
132
|
+
|
|
133
|
+
# flags.exclude-default-noise.description
|
|
134
|
+
|
|
135
|
+
When set, the plugin merges smart-diff's `DEFAULT_NOISE_EXCLUDES` list (lockfiles, `dist`, `build`, `out`, `coverage`, `node_modules`, `__snapshots__`) into the set of excluded pathspecs passed to git. This is additive with any `--exclude-package-directory` values you provide. Defaults to false, because Salesforce DX repos rarely contain these folders inside package directories; enable it if your repo does.
|
|
136
|
+
|
|
97
137
|
# examples
|
|
98
138
|
|
|
99
139
|
- <%= config.bin %> <%= command.id %> --from HEAD~5 --to HEAD --commit-message-include "(feature|fix)" --output changes.md
|
|
100
140
|
- <%= config.bin %> <%= command.id %> --from HEAD~5 --to HEAD --commit-message-include "feat" --commit-message-exclude "wip" --exclude-package-directory force-app/main/default/lwc/temp
|
|
101
141
|
- <%= config.bin %> <%= command.id %> --team "Revenue Cloud" --from release/cut --to HEAD
|
|
102
142
|
- <%= config.bin %> <%= command.id %> --from abc1234 --to HEAD
|
|
143
|
+
- <%= config.bin %> <%= command.id %> --from HEAD~5 --to HEAD --ignore-whitespace --context-lines 1 --strip-diff-preamble --max-hunk-lines 400
|
package/oclif.manifest.json
CHANGED
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
"sgai:metadata:summarize": {
|
|
4
4
|
"aliases": [],
|
|
5
5
|
"args": {},
|
|
6
|
-
"description": "Summarize metadata changes between two Git refs using
|
|
6
|
+
"description": "Summarize metadata changes between two Git refs using any LLM provider supported by the Vercel AI SDK — OpenAI, Anthropic, Google Gemini, Amazon Bedrock, Mistral, Cohere, Groq, xAI, DeepSeek, or any OpenAI-compatible gateway. A configured provider (API key, base URL, and/or default headers) is required — see the README for environment variables. Optionally filter commits by include/exclude message regexes, narrow paths with `--include-package-directory` / `--exclude-package-directory`, and write the model output to a markdown file.",
|
|
7
7
|
"examples": [
|
|
8
8
|
"<%= config.bin %> <%= command.id %> --from HEAD~5 --to HEAD --commit-message-include \"(feature|fix)\" --output changes.md",
|
|
9
9
|
"<%= config.bin %> <%= command.id %> --from HEAD~5 --to HEAD --commit-message-include \"feat\" --commit-message-exclude \"wip\" --exclude-package-directory force-app/main/default/lwc/temp",
|
|
10
10
|
"<%= config.bin %> <%= command.id %> --team \"Revenue Cloud\" --from release/cut --to HEAD",
|
|
11
|
-
"<%= config.bin %> <%= command.id %> --from abc1234 --to HEAD"
|
|
11
|
+
"<%= config.bin %> <%= command.id %> --from abc1234 --to HEAD",
|
|
12
|
+
"<%= config.bin %> <%= command.id %> --from HEAD~5 --to HEAD --ignore-whitespace --context-lines 1 --strip-diff-preamble --max-hunk-lines 400"
|
|
12
13
|
],
|
|
13
14
|
"flags": {
|
|
14
15
|
"json": {
|
|
@@ -87,7 +88,7 @@
|
|
|
87
88
|
"type": "option"
|
|
88
89
|
},
|
|
89
90
|
"team": {
|
|
90
|
-
"description": "When set, includes a team line in the
|
|
91
|
+
"description": "When set, includes a team line in the LLM user prompt. If omitted, `METADATA_AUDIT_TEAM` or `SF_GIT_AI_TEAM` is used when set; otherwise no team is included.",
|
|
91
92
|
"name": "team",
|
|
92
93
|
"required": false,
|
|
93
94
|
"summary": "Optional team or squad label for the summary.",
|
|
@@ -107,11 +108,10 @@
|
|
|
107
108
|
"type": "option"
|
|
108
109
|
},
|
|
109
110
|
"model": {
|
|
110
|
-
"description": "
|
|
111
|
+
"description": "Override the chat model used when creating the AI-generated metadata summary. Must be a model id supported by the resolved LLM provider (for example `gpt-4o` for OpenAI, `claude-3-5-sonnet-latest` for Anthropic, `gemini-2.0-flash` for Google). When omitted, the plugin uses `LLM_MODEL` if set, otherwise the resolved provider's default model.",
|
|
111
112
|
"name": "model",
|
|
112
113
|
"required": false,
|
|
113
|
-
"summary": "
|
|
114
|
-
"default": "gpt-4o-mini",
|
|
114
|
+
"summary": "Chat model id used for the summary.",
|
|
115
115
|
"hasDynamicHelp": false,
|
|
116
116
|
"multiple": false,
|
|
117
117
|
"type": "option"
|
|
@@ -124,6 +124,48 @@
|
|
|
124
124
|
"hasDynamicHelp": false,
|
|
125
125
|
"multiple": false,
|
|
126
126
|
"type": "option"
|
|
127
|
+
},
|
|
128
|
+
"context-lines": {
|
|
129
|
+
"description": "Sets `git diff -U<n>` when building the unified diff sent to the model. Lower values (1 or 0) are typically the single biggest token saver on modification-heavy diffs because they drop unchanged surrounding lines from each hunk. The structured diff summary (file counts and line totals) still reflects the full change. Allowed range is 0 through 1000 when set. When omitted, git's default (3) is used.",
|
|
130
|
+
"name": "context-lines",
|
|
131
|
+
"required": false,
|
|
132
|
+
"summary": "Number of context lines around each change in the unified diff.",
|
|
133
|
+
"hasDynamicHelp": false,
|
|
134
|
+
"multiple": false,
|
|
135
|
+
"type": "option"
|
|
136
|
+
},
|
|
137
|
+
"ignore-whitespace": {
|
|
138
|
+
"description": "Passes `-w` / `--ignore-all-space` to `git diff` so pure-whitespace hunks don't consume tokens in the unified diff. This is also applied to the `--numstat` and `--name-status` calls used for the structured summary so file counts and line totals stay consistent with the diff text. Useful for Salesforce metadata XML where formatting churn is common. Defaults to false.",
|
|
139
|
+
"name": "ignore-whitespace",
|
|
140
|
+
"required": false,
|
|
141
|
+
"summary": "Ignore whitespace-only changes when building the diff.",
|
|
142
|
+
"allowNo": false,
|
|
143
|
+
"type": "boolean"
|
|
144
|
+
},
|
|
145
|
+
"strip-diff-preamble": {
|
|
146
|
+
"description": "When set, removes the per-file git diff preamble lines that contain almost no semantic information (`diff --git`, `index`, `new file mode`, `deleted file mode`, `old mode`, `new mode`, `similarity index`, `dissimilarity index`, `rename from`/`rename to`, `copy from`/`copy to`). The `--- a/…`, `+++ b/…`, and `@@` hunk headers are preserved so the model can still attribute changes to files. Defaults to false.",
|
|
147
|
+
"name": "strip-diff-preamble",
|
|
148
|
+
"required": false,
|
|
149
|
+
"summary": "Strip low-value `diff --git`/`index`/`mode`/`similarity`/`rename`/`copy` lines from the unified diff.",
|
|
150
|
+
"allowNo": false,
|
|
151
|
+
"type": "boolean"
|
|
152
|
+
},
|
|
153
|
+
"max-hunk-lines": {
|
|
154
|
+
"description": "Limits the number of body lines retained per `@@` hunk in the unified diff. Lines past the limit are replaced with a single elision marker so the `@@` header and the structured diff summary totals are preserved. Use this to prevent a single massive hunk (for example a regenerated metadata file) from dominating the LLM prompt. Allowed range is 1 through 100000 when set. When omitted, hunks are not truncated.",
|
|
155
|
+
"name": "max-hunk-lines",
|
|
156
|
+
"required": false,
|
|
157
|
+
"summary": "Cap the body of each diff hunk; anything past the limit is elided.",
|
|
158
|
+
"hasDynamicHelp": false,
|
|
159
|
+
"multiple": false,
|
|
160
|
+
"type": "option"
|
|
161
|
+
},
|
|
162
|
+
"exclude-default-noise": {
|
|
163
|
+
"description": "When set, the plugin merges smart-diff's `DEFAULT_NOISE_EXCLUDES` list (lockfiles, `dist`, `build`, `out`, `coverage`, `node_modules`, `__snapshots__`) into the set of excluded pathspecs passed to git. This is additive with any `--exclude-package-directory` values you provide. Defaults to false, because Salesforce DX repos rarely contain these folders inside package directories; enable it if your repo does.",
|
|
164
|
+
"name": "exclude-default-noise",
|
|
165
|
+
"required": false,
|
|
166
|
+
"summary": "Merge smart-diff's built-in \"noise\" exclude list into the excluded paths.",
|
|
167
|
+
"allowNo": false,
|
|
168
|
+
"type": "boolean"
|
|
127
169
|
}
|
|
128
170
|
},
|
|
129
171
|
"hasDynamicHelp": false,
|
|
@@ -154,5 +196,5 @@
|
|
|
154
196
|
]
|
|
155
197
|
}
|
|
156
198
|
},
|
|
157
|
-
"version": "2.
|
|
199
|
+
"version": "2.3.0"
|
|
158
200
|
}
|