@in-the-loop-labs/pair-review 3.2.0 → 3.2.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@in-the-loop-labs/pair-review",
3
- "version": "3.2.0",
3
+ "version": "3.2.1",
4
4
  "description": "Your AI-powered code review partner - Close the feedback loop with AI coding agents",
5
5
  "main": "src/server.js",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pair-review",
3
- "version": "3.2.0",
3
+ "version": "3.2.1",
4
4
  "description": "pair-review app integration — Open PRs and local changes in the pair-review web UI, run server-side AI analysis, and address review feedback. Requires the pair-review MCP server.",
5
5
  "author": {
6
6
  "name": "in-the-loop-labs",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "code-critic",
3
- "version": "3.2.0",
3
+ "version": "3.2.1",
4
4
  "description": "AI-powered code review analysis — Run three-level AI analysis and implement-review-fix loops directly in your coding agent. Works standalone, no server required.",
5
5
  "author": {
6
6
  "name": "in-the-loop-labs",
package/public/css/pr.css CHANGED
@@ -12085,6 +12085,25 @@ body.resizing * {
12085
12085
  padding: 0;
12086
12086
  }
12087
12087
 
12088
+ .chat-panel__message--assistant .chat-panel__bubble table {
12089
+ border-collapse: collapse;
12090
+ font-size: 12px;
12091
+ margin: 8px 0;
12092
+ overflow-x: auto;
12093
+ display: block;
12094
+ }
12095
+
12096
+ .chat-panel__message--assistant .chat-panel__bubble th,
12097
+ .chat-panel__message--assistant .chat-panel__bubble td {
12098
+ border: 1px solid var(--color-border-primary);
12099
+ padding: 4px 8px;
12100
+ }
12101
+
12102
+ .chat-panel__message--assistant .chat-panel__bubble th {
12103
+ background: var(--color-bg-tertiary);
12104
+ font-weight: 600;
12105
+ }
12106
+
12088
12107
  .chat-panel__message--assistant .chat-panel__bubble ul,
12089
12108
  .chat-panel__message--assistant .chat-panel__bubble ol {
12090
12109
  margin: 4px 0;
@@ -13287,7 +13306,7 @@ body.resizing * {
13287
13306
  box-shadow: 0 4px 16px var(--color-shadow, rgba(0, 0, 0, 0.12));
13288
13307
  z-index: 100;
13289
13308
  padding: 6px 0;
13290
- max-height: 420px;
13309
+ max-height: min(calc(100vh - 120px), 80vh);
13291
13310
  overflow-y: auto;
13292
13311
  }
13293
13312
 
@@ -130,6 +130,8 @@ class PiProvider extends AIProvider {
130
130
  * @param {string[]} configOverrides.extra_args - Additional CLI arguments
131
131
  * @param {Object} configOverrides.env - Additional environment variables
132
132
  * @param {Object[]} configOverrides.models - Custom model definitions
133
+ * @param {boolean} [configOverrides.load_skills=true] - When false, adds --no-skills to suppress skill auto-discovery
134
+ * @param {boolean} [configOverrides.app_extensions=true] - When false, omits the -e task extension flag
133
135
  */
134
136
  constructor(model, configOverrides = {}) {
135
137
  super(model || 'default');
@@ -197,19 +199,25 @@ class PiProvider extends AIProvider {
197
199
  // The task extension is loaded to give the model a subagent tool for delegating
198
200
  // work to isolated subprocesses, preserving the main context window.
199
201
  // --no-prompt-templates: prompt templates can't be triggered in -p mode, so suppress
200
- // them to avoid wasting context. Skills and extensions are left enabled so the
201
- // subprocess has access to the user's configured environment. To disable them,
202
- // add --no-skills or --no-extensions to extra_args in provider/model config.
202
+ // them to avoid wasting context.
203
+ // load_skills (default true): when false, adds --no-skills to suppress auto-discovery.
204
+ // Explicit --skill args from built-in models (e.g. multi-model) still load.
205
+ // app_extensions (default true): when false, omits the -e task extension flag.
206
+ // Useful when auto-discovery already loads the extension (e.g. developing pair-review).
207
+ const loadSkills = configOverrides.load_skills !== false;
208
+ const appExtensions = configOverrides.app_extensions !== false;
203
209
  const sessionArgs = process.env.PAIR_REVIEW_PI_SESSION ? [] : ['--no-session'];
210
+ const extensionArgs = appExtensions ? ['-e', TASK_EXTENSION_DIR] : [];
211
+ const skillArgs = loadSkills ? [] : ['--no-skills'];
204
212
  let baseArgs;
205
213
  if (configOverrides.yolo) {
206
214
  baseArgs = ['-p', '--mode', 'json', ...cliModelArgs, ...sessionArgs,
207
215
  '--no-prompt-templates',
208
- '-e', TASK_EXTENSION_DIR];
216
+ ...extensionArgs, ...skillArgs];
209
217
  } else {
210
218
  baseArgs = ['-p', '--mode', 'json', ...cliModelArgs, '--tools', 'read,bash,grep,find,ls', ...sessionArgs,
211
219
  '--no-prompt-templates',
212
- '-e', TASK_EXTENSION_DIR];
220
+ ...extensionArgs, ...skillArgs];
213
221
  }
214
222
  const builtInArgs = builtIn?.extra_args || [];
215
223
  const providerArgs = configOverrides.extra_args || [];
@@ -532,6 +532,8 @@ function applyConfigOverrides(config) {
532
532
  installInstructions: providerConfig.installInstructions,
533
533
  extra_args: providerConfig.extra_args,
534
534
  env: providerConfig.env,
535
+ load_skills: providerConfig.load_skills,
536
+ app_extensions: providerConfig.app_extensions,
535
537
  models: AliasClass.getModels() !== BaseClass.getModels() ? AliasClass.getModels() : null
536
538
  });
537
539
  logger.debug(`Registered aliased provider: ${providerId} (base: ${providerConfig.type})`);
@@ -557,6 +559,8 @@ function applyConfigOverrides(config) {
557
559
  installInstructions: providerConfig.installInstructions,
558
560
  extra_args: providerConfig.extra_args,
559
561
  env: providerConfig.env,
562
+ load_skills: providerConfig.load_skills,
563
+ app_extensions: providerConfig.app_extensions,
560
564
  models: processedModels
561
565
  });
562
566
  }
@@ -121,6 +121,8 @@ function getChatProvider(id) {
121
121
  if (overrides.extra_args && Array.isArray(overrides.extra_args)) {
122
122
  provider.args = [...provider.args, ...overrides.extra_args];
123
123
  }
124
+ if (overrides.load_skills !== undefined) provider.load_skills = overrides.load_skills;
125
+ if (overrides.app_extensions !== undefined) provider.app_extensions = overrides.app_extensions;
124
126
  if (provider.command.includes(' ')) {
125
127
  provider.useShell = true;
126
128
  }
@@ -142,6 +144,8 @@ function getChatProvider(id) {
142
144
  if (overrides.extra_args && Array.isArray(overrides.extra_args)) {
143
145
  merged.args = [...(merged.args || []), ...overrides.extra_args];
144
146
  }
147
+ if (overrides.load_skills !== undefined) merged.load_skills = overrides.load_skills;
148
+ if (overrides.app_extensions !== undefined) merged.app_extensions = overrides.app_extensions;
145
149
  // For multi-word commands (e.g. "devx claude"), use shell mode
146
150
  if (merged.command && merged.command.includes(' ')) {
147
151
  merged.useShell = true;
@@ -37,6 +37,7 @@ class PiBridge extends EventEmitter {
37
37
  * @param {string[]} [options.extensions] - Array of extension directory paths to load via -e
38
38
  * @param {string[]} [options.extraArgs] - Extra CLI args to append (e.g., from config extra_args)
39
39
  * @param {string} [options.sessionPath] - Path to a session file for resumption
40
+ * @param {boolean} [options.loadSkills] - When false, adds --no-skills to suppress auto-discovery (default: true)
40
41
  */
41
42
  constructor(options = {}) {
42
43
  super();
@@ -52,6 +53,7 @@ class PiBridge extends EventEmitter {
52
53
  this.extensions = options.extensions || [];
53
54
  this.extraArgs = options.extraArgs || [];
54
55
  this.sessionPath = options.sessionPath || null;
56
+ this.loadSkills = options.loadSkills !== false;
55
57
 
56
58
  this._process = null;
57
59
  this._readline = null;
@@ -290,6 +292,12 @@ class PiBridge extends EventEmitter {
290
292
  args.push('-e', ext);
291
293
  }
292
294
 
295
+ // Suppress skill auto-discovery when loadSkills is false.
296
+ // Explicit --skill entries above still load.
297
+ if (!this.loadSkills) {
298
+ args.push('--no-skills');
299
+ }
300
+
293
301
  // Append extra args from provider config (e.g., extra_args in chat_providers).
294
302
  // These go last so they can override earlier flags if needed.
295
303
  if (this.extraArgs.length > 0) {
@@ -575,6 +575,9 @@ class ChatSessionManager {
575
575
  // which would forward it as `--provider pi` to the Pi CLI. The CLI's --provider flag
576
576
  // expects a model provider ("google", "anthropic", etc.) and should only come from
577
577
  // explicit user configuration (providerDef.provider).
578
+ // app_extensions (default true): when false, omit pair-review's task extension.
579
+ // load_skills (default true): when false, suppress Pi's skill auto-discovery.
580
+ const appExtensions = def?.app_extensions !== false;
578
581
  return new PiBridge({
579
582
  ...options,
580
583
  provider: def?.provider || null,
@@ -584,7 +587,8 @@ class ChatSessionManager {
584
587
  env: def?.env,
585
588
  useShell: def?.useShell,
586
589
  tools: CHAT_TOOLS,
587
- extensions: [taskExtensionDir],
590
+ extensions: appExtensions ? [taskExtensionDir] : [],
591
+ loadSkills: def?.load_skills,
588
592
  });
589
593
  }
590
594