@in-the-loop-labs/pair-review 3.3.5 → 3.3.7
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/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin-code-critic/.claude-plugin/plugin.json +1 -1
- package/public/js/components/AIPanel.js +3 -14
- package/public/js/modules/diff-renderer.js +100 -7
- package/public/js/modules/file-comment-manager.js +34 -13
- package/public/js/modules/suggestion-manager.js +22 -6
- package/public/js/pr.js +3 -3
- package/public/js/repo-settings.js +37 -7
- package/src/ai/claude-provider.js +12 -1
- package/src/ai/codex-provider.js +134 -44
- package/src/ai/index.js +3 -1
- package/src/ai/pi-provider.js +403 -77
- package/src/ai/provider.js +6 -3
- package/src/config.js +12 -0
- package/src/git/diff-flags.js +5 -1
- package/src/git/worktree.js +23 -4
- package/src/local-review.js +26 -10
- package/src/main.js +1 -1
- package/src/routes/pr.js +26 -10
- package/src/utils/diff-file-list.js +111 -2
- package/src/utils/paths.js +4 -0
package/src/ai/codex-provider.js
CHANGED
|
@@ -23,31 +23,65 @@ const BIN_DIR = path.join(__dirname, '..', '..', 'bin');
|
|
|
23
23
|
* Based on OpenAI Codex Models guide (developers.openai.com/codex/models)
|
|
24
24
|
* - gpt-5.4-nano: Cheapest model ($0.20/$1.25 per MTok), good for surface scans
|
|
25
25
|
* - gpt-5.4-mini: Fast with 400k context ($0.75/$4.50 per MTok)
|
|
26
|
-
* - gpt-5.4: Flagship model combining coding, reasoning, and agentic workflows
|
|
27
26
|
* - gpt-5.3-codex: Industry-leading coding model for complex engineering tasks
|
|
27
|
+
* - gpt-5.4 / gpt-5.5: Exposed only via -high / -xhigh reasoning variants so the
|
|
28
|
+
* selected effort level is always explicit.
|
|
29
|
+
*
|
|
30
|
+
* Reasoning-effort variants (-high / -xhigh) use `cli_model` to pass the base
|
|
31
|
+
* model ID to `codex exec -m` and add `-c model_reasoning_effort="..."` via
|
|
32
|
+
* extra_args so Codex picks up the effort level through its config override.
|
|
28
33
|
*
|
|
29
34
|
* Deprecated (April 2026): gpt-5.1-codex-mini, gpt-5.1-codex-max, gpt-5.1-codex
|
|
30
35
|
*/
|
|
31
36
|
const CODEX_MODELS = [
|
|
32
37
|
{
|
|
33
|
-
id: 'gpt-5.4-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
name: 'GPT-5.4 Mini',
|
|
44
|
-
tier: 'balanced',
|
|
45
|
-
tagline: 'Best Balance',
|
|
46
|
-
description: 'Fast reviews with 400k context—good balance of speed and capability for everyday PR review.',
|
|
38
|
+
id: 'gpt-5.4-high',
|
|
39
|
+
// Alias keeps results/councils saved under the previous bare `gpt-5.4`
|
|
40
|
+
// model ID resolving to the now-explicit high-effort variant.
|
|
41
|
+
aliases: ['gpt-5.4'],
|
|
42
|
+
cli_model: 'gpt-5.4',
|
|
43
|
+
extra_args: ['-c', 'model_reasoning_effort="high"'],
|
|
44
|
+
name: 'GPT-5.4 High',
|
|
45
|
+
tier: 'thorough',
|
|
46
|
+
tagline: 'Deep Review',
|
|
47
|
+
description: 'GPT-5.4 with high reasoning effort for complex multi-file reviews, architectural consistency, and subtle behavioral regressions.',
|
|
47
48
|
badge: 'Recommended',
|
|
48
49
|
badgeClass: 'badge-recommended',
|
|
49
50
|
default: true
|
|
50
51
|
},
|
|
52
|
+
{
|
|
53
|
+
id: 'gpt-5.4-xhigh',
|
|
54
|
+
cli_model: 'gpt-5.4',
|
|
55
|
+
extra_args: ['-c', 'model_reasoning_effort="xhigh"'],
|
|
56
|
+
name: 'GPT-5.4 XHigh',
|
|
57
|
+
tier: 'thorough',
|
|
58
|
+
tagline: 'Max Depth',
|
|
59
|
+
description: 'GPT-5.4 with extra-high reasoning effort for difficult reviews that need broad context, careful tradeoff analysis, and deeper issue validation.',
|
|
60
|
+
badge: 'Extra High',
|
|
61
|
+
badgeClass: 'badge-power'
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: 'gpt-5.5-high',
|
|
65
|
+
cli_model: 'gpt-5.5',
|
|
66
|
+
extra_args: ['-c', 'model_reasoning_effort="high"'],
|
|
67
|
+
name: 'GPT-5.5 High',
|
|
68
|
+
tier: 'thorough',
|
|
69
|
+
tagline: 'Latest Deep',
|
|
70
|
+
description: 'Latest-generation GPT model with high reasoning effort for demanding PR reviews, strong code understanding, and careful cross-file analysis.',
|
|
71
|
+
badge: 'High Effort',
|
|
72
|
+
badgeClass: 'badge-power'
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
id: 'gpt-5.5-xhigh',
|
|
76
|
+
cli_model: 'gpt-5.5',
|
|
77
|
+
extra_args: ['-c', 'model_reasoning_effort="xhigh"'],
|
|
78
|
+
name: 'GPT-5.5 XHigh',
|
|
79
|
+
tier: 'thorough',
|
|
80
|
+
tagline: 'Frontier Depth',
|
|
81
|
+
description: 'GPT-5.5 with extra-high reasoning effort for the hardest reviews: architecture, concurrency, security-sensitive changes, and large codebase context.',
|
|
82
|
+
badge: 'Max Reasoning',
|
|
83
|
+
badgeClass: 'badge-power'
|
|
84
|
+
},
|
|
51
85
|
{
|
|
52
86
|
id: 'gpt-5.3-codex',
|
|
53
87
|
name: 'GPT-5.3 Codex',
|
|
@@ -58,13 +92,22 @@ const CODEX_MODELS = [
|
|
|
58
92
|
badgeClass: 'badge-power'
|
|
59
93
|
},
|
|
60
94
|
{
|
|
61
|
-
id: 'gpt-5.4',
|
|
62
|
-
name: 'GPT-5.4',
|
|
63
|
-
tier: '
|
|
64
|
-
tagline: '
|
|
65
|
-
description: '
|
|
66
|
-
badge: '
|
|
67
|
-
badgeClass: 'badge-
|
|
95
|
+
id: 'gpt-5.4-mini',
|
|
96
|
+
name: 'GPT-5.4 Mini',
|
|
97
|
+
tier: 'balanced',
|
|
98
|
+
tagline: 'Best Balance',
|
|
99
|
+
description: 'Fast reviews with 400k context—good balance of speed and capability for everyday PR review.',
|
|
100
|
+
badge: 'Fast',
|
|
101
|
+
badgeClass: 'badge-speed'
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
id: 'gpt-5.4-nano',
|
|
105
|
+
name: 'GPT-5.4 Nano',
|
|
106
|
+
tier: 'fast',
|
|
107
|
+
tagline: 'Cheapest',
|
|
108
|
+
description: 'Ultra-low-cost surface scans for style issues, obvious bugs, and lint-level feedback.',
|
|
109
|
+
badge: 'Cheapest',
|
|
110
|
+
badgeClass: 'badge-speed'
|
|
68
111
|
}
|
|
69
112
|
];
|
|
70
113
|
|
|
@@ -78,7 +121,7 @@ class CodexProvider extends AIProvider {
|
|
|
78
121
|
* @param {Object} configOverrides.env - Additional environment variables
|
|
79
122
|
* @param {Object[]} configOverrides.models - Custom model definitions
|
|
80
123
|
*/
|
|
81
|
-
constructor(model = 'gpt-5.4-
|
|
124
|
+
constructor(model = 'gpt-5.4-high', configOverrides = {}) {
|
|
82
125
|
super(model);
|
|
83
126
|
|
|
84
127
|
// Command precedence: ENV > config > default
|
|
@@ -127,27 +170,70 @@ class CodexProvider extends AIProvider {
|
|
|
127
170
|
// same two-tier pattern as chat-providers.js: args replaces, extra_args appends.
|
|
128
171
|
const defaultShellEnvArgs = ['-c', 'allow_login_shell=false', '-c', 'shell_environment_policy.include_only=["PATH","HOME","USER","GH_TOKEN","GITHUB_TOKEN"]'];
|
|
129
172
|
const configArgs = configOverrides.args || defaultShellEnvArgs;
|
|
130
|
-
const baseArgs = ['exec', '-m', model, '--json', ...sandboxArgs, ...configArgs, '-'];
|
|
131
|
-
const providerArgs = configOverrides.extra_args || [];
|
|
132
|
-
const modelConfig = configOverrides.models?.find(m => m.id === model);
|
|
133
|
-
const modelArgs = modelConfig?.extra_args || [];
|
|
134
173
|
|
|
135
|
-
//
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
174
|
+
// Resolve cli_model + extra_args + env from built-in model, provider config,
|
|
175
|
+
// and per-model config. This is what lets reasoning variants like
|
|
176
|
+
// gpt-5.4-high pass `-m gpt-5.4` plus `-c model_reasoning_effort="high"`.
|
|
177
|
+
const { cliModel, extraArgs, env } = this._resolveModelConfig(model);
|
|
178
|
+
|
|
179
|
+
// IMPORTANT: `-` (stdin marker) must come LAST, after any extra_args.
|
|
180
|
+
// Reasoning variants contribute `-c model_reasoning_effort="..."` via
|
|
181
|
+
// extraArgs; if '-' were placed inside baseArgs those flags would land
|
|
182
|
+
// after the positional stdin marker and be ignored. `buildArgsForModel`
|
|
183
|
+
// enforces the same invariant for the extraction path.
|
|
184
|
+
const baseArgs = ['exec', '-m', cliModel, '--json', ...sandboxArgs, ...configArgs];
|
|
185
|
+
|
|
186
|
+
this.extraEnv = env;
|
|
140
187
|
|
|
141
188
|
if (this.useShell) {
|
|
142
189
|
// In shell mode, build full command string with args
|
|
143
|
-
this.command = `${codexCmd} ${quoteShellArgs([...baseArgs, ...
|
|
190
|
+
this.command = `${codexCmd} ${quoteShellArgs([...baseArgs, ...extraArgs, '-']).join(' ')}`;
|
|
144
191
|
this.args = [];
|
|
145
192
|
} else {
|
|
146
193
|
this.command = codexCmd;
|
|
147
|
-
this.args = [...baseArgs, ...
|
|
194
|
+
this.args = [...baseArgs, ...extraArgs, '-'];
|
|
148
195
|
}
|
|
149
196
|
}
|
|
150
197
|
|
|
198
|
+
/**
|
|
199
|
+
* Resolve model configuration by looking up built-in and config override definitions.
|
|
200
|
+
* Produces the CLI model ID (for `-m`), merged extra_args, and merged env.
|
|
201
|
+
*
|
|
202
|
+
* Precedence for cli_model: config model > built-in model > modelId.
|
|
203
|
+
* `cli_model` lets reasoning-effort variants (e.g. `gpt-5.4-high`) pass the
|
|
204
|
+
* base model (`gpt-5.4`) to `codex exec -m` while adding reasoning overrides
|
|
205
|
+
* via extra_args.
|
|
206
|
+
*
|
|
207
|
+
* @param {string} modelId
|
|
208
|
+
* @returns {{ builtIn: Object|undefined, configModel: Object|undefined, cliModel: string, extraArgs: string[], env: Object }}
|
|
209
|
+
* @private
|
|
210
|
+
*/
|
|
211
|
+
_resolveModelConfig(modelId) {
|
|
212
|
+
const configOverrides = this.configOverrides || {};
|
|
213
|
+
|
|
214
|
+
const builtIn = CODEX_MODELS.find(m => m.id === modelId || (m.aliases && m.aliases.includes(modelId)));
|
|
215
|
+
const configModel = configOverrides.models?.find(m => m.id === modelId);
|
|
216
|
+
|
|
217
|
+
const cliModel = configModel?.cli_model !== undefined
|
|
218
|
+
? configModel.cli_model
|
|
219
|
+
: (builtIn?.cli_model !== undefined ? builtIn.cli_model : modelId);
|
|
220
|
+
|
|
221
|
+
// Three-way merge for extra_args: built-in model → provider config → per-model config
|
|
222
|
+
const builtInArgs = builtIn?.extra_args || [];
|
|
223
|
+
const providerArgs = configOverrides.extra_args || [];
|
|
224
|
+
const configModelArgs = configModel?.extra_args || [];
|
|
225
|
+
const extraArgs = [...builtInArgs, ...providerArgs, ...configModelArgs];
|
|
226
|
+
|
|
227
|
+
// Three-way merge for env: built-in model → provider config → per-model config
|
|
228
|
+
const env = {
|
|
229
|
+
...(builtIn?.env || {}),
|
|
230
|
+
...(configOverrides.env || {}),
|
|
231
|
+
...(configModel?.env || {})
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
return { builtIn, configModel, cliModel, extraArgs, env };
|
|
235
|
+
}
|
|
236
|
+
|
|
151
237
|
/**
|
|
152
238
|
* Execute Codex CLI with a prompt
|
|
153
239
|
* @param {string} prompt - The prompt to send to Codex
|
|
@@ -572,17 +658,16 @@ class CodexProvider extends AIProvider {
|
|
|
572
658
|
* @returns {string[]} Complete args array for the CLI
|
|
573
659
|
*/
|
|
574
660
|
buildArgsForModel(model) {
|
|
661
|
+
// Resolve cli_model + merged extra_args so reasoning-effort variants behave
|
|
662
|
+
// the same for extraction as they do for the main analysis call.
|
|
663
|
+
const { cliModel, extraArgs } = this._resolveModelConfig(model);
|
|
664
|
+
|
|
575
665
|
// Base args for extraction (read-only sandbox, no shell access needed)
|
|
576
666
|
// Note: '-' (stdin marker) must come LAST, after any extra_args
|
|
577
|
-
const baseArgs = ['exec', '-m',
|
|
578
|
-
// Provider-level extra_args (from configOverrides)
|
|
579
|
-
const providerArgs = this.configOverrides?.extra_args || [];
|
|
580
|
-
// Model-specific extra_args (from the model config for the given model)
|
|
581
|
-
const modelConfig = this.configOverrides?.models?.find(m => m.id === model);
|
|
582
|
-
const modelArgs = modelConfig?.extra_args || [];
|
|
667
|
+
const baseArgs = ['exec', '-m', cliModel, '--json', '--sandbox', 'read-only', '--full-auto'];
|
|
583
668
|
|
|
584
669
|
// Append stdin marker '-' at the end after all other args
|
|
585
|
-
return [...baseArgs, ...
|
|
670
|
+
return [...baseArgs, ...extraArgs, '-'];
|
|
586
671
|
}
|
|
587
672
|
|
|
588
673
|
/**
|
|
@@ -598,20 +683,25 @@ class CodexProvider extends AIProvider {
|
|
|
598
683
|
|
|
599
684
|
// Build args consistently using the shared method, applying provider and model extra_args
|
|
600
685
|
const args = this.buildArgsForModel(model);
|
|
686
|
+
// Surface merged env (built-in + provider + per-model) so the extraction
|
|
687
|
+
// spawn matches the contract used by other providers.
|
|
688
|
+
const { env } = this._resolveModelConfig(model);
|
|
601
689
|
|
|
602
690
|
if (useShell) {
|
|
603
691
|
return {
|
|
604
692
|
command: `${codexCmd} ${quoteShellArgs(args).join(' ')}`,
|
|
605
693
|
args: [],
|
|
606
694
|
useShell: true,
|
|
607
|
-
promptViaStdin: true
|
|
695
|
+
promptViaStdin: true,
|
|
696
|
+
env
|
|
608
697
|
};
|
|
609
698
|
}
|
|
610
699
|
return {
|
|
611
700
|
command: codexCmd,
|
|
612
701
|
args,
|
|
613
702
|
useShell: false,
|
|
614
|
-
promptViaStdin: true
|
|
703
|
+
promptViaStdin: true,
|
|
704
|
+
env
|
|
615
705
|
};
|
|
616
706
|
}
|
|
617
707
|
|
|
@@ -700,7 +790,7 @@ class CodexProvider extends AIProvider {
|
|
|
700
790
|
}
|
|
701
791
|
|
|
702
792
|
static getDefaultModel() {
|
|
703
|
-
return 'gpt-5.4-
|
|
793
|
+
return 'gpt-5.4-high';
|
|
704
794
|
}
|
|
705
795
|
|
|
706
796
|
static getInstallInstructions() {
|
package/src/ai/index.js
CHANGED
|
@@ -21,7 +21,8 @@ const {
|
|
|
21
21
|
inferModelDefaults,
|
|
22
22
|
resolveDefaultModel,
|
|
23
23
|
prettifyModelId,
|
|
24
|
-
createAliasedProviderClass
|
|
24
|
+
createAliasedProviderClass,
|
|
25
|
+
getTierForModel
|
|
25
26
|
} = require('./provider');
|
|
26
27
|
|
|
27
28
|
// Load the availability checking module
|
|
@@ -73,6 +74,7 @@ module.exports = {
|
|
|
73
74
|
inferModelDefaults,
|
|
74
75
|
resolveDefaultModel,
|
|
75
76
|
prettifyModelId,
|
|
77
|
+
getTierForModel,
|
|
76
78
|
|
|
77
79
|
// Provider factories
|
|
78
80
|
createExecutableProviderClass,
|