@in-the-loop-labs/pair-review 2.6.2 → 2.7.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.
Files changed (50) hide show
  1. package/bin/git-diff-lines +1 -1
  2. package/package.json +1 -1
  3. package/plugin/.claude-plugin/plugin.json +1 -1
  4. package/plugin-code-critic/.claude-plugin/plugin.json +1 -1
  5. package/plugin-code-critic/skills/analyze/scripts/git-diff-lines +1 -1
  6. package/public/css/pr.css +201 -0
  7. package/public/index.html +168 -3
  8. package/public/js/components/AIPanel.js +16 -2
  9. package/public/js/components/ChatPanel.js +41 -6
  10. package/public/js/components/ConfirmDialog.js +21 -2
  11. package/public/js/components/CouncilProgressModal.js +13 -0
  12. package/public/js/components/DiffOptionsDropdown.js +410 -23
  13. package/public/js/components/SuggestionNavigator.js +12 -5
  14. package/public/js/components/TabTitle.js +96 -0
  15. package/public/js/components/Toast.js +6 -0
  16. package/public/js/index.js +648 -43
  17. package/public/js/local.js +569 -76
  18. package/public/js/modules/analysis-history.js +3 -2
  19. package/public/js/modules/comment-manager.js +5 -0
  20. package/public/js/modules/comment-minimizer.js +304 -0
  21. package/public/js/pr.js +82 -6
  22. package/public/local.html +14 -0
  23. package/public/pr.html +3 -0
  24. package/src/ai/analyzer.js +22 -16
  25. package/src/ai/cursor-agent-provider.js +21 -12
  26. package/src/chat/prompt-builder.js +3 -3
  27. package/src/config.js +2 -0
  28. package/src/database.js +590 -39
  29. package/src/git/base-branch.js +173 -0
  30. package/src/git/sha-abbrev.js +35 -0
  31. package/src/git/worktree.js +3 -2
  32. package/src/github/client.js +32 -1
  33. package/src/hooks/hook-runner.js +100 -0
  34. package/src/hooks/payloads.js +212 -0
  35. package/src/local-review.js +468 -129
  36. package/src/local-scope.js +58 -0
  37. package/src/main.js +57 -6
  38. package/src/routes/analyses.js +73 -10
  39. package/src/routes/chat.js +33 -0
  40. package/src/routes/config.js +1 -0
  41. package/src/routes/github-collections.js +2 -2
  42. package/src/routes/local.js +734 -68
  43. package/src/routes/mcp.js +20 -10
  44. package/src/routes/pr.js +92 -14
  45. package/src/routes/setup.js +1 -0
  46. package/src/routes/worktrees.js +212 -148
  47. package/src/server.js +30 -0
  48. package/src/setup/local-setup.js +46 -5
  49. package/src/setup/pr-setup.js +28 -5
  50. package/src/utils/diff-file-list.js +1 -1
@@ -0,0 +1,96 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ /**
3
+ * TabTitle — manages the browser tab title with flash-on-completion support.
4
+ *
5
+ * Usage:
6
+ * window.tabTitle = new TabTitle();
7
+ * window.tabTitle.setBase('PR #123'); // → "pair-review - PR #123"
8
+ * window.tabTitle.flashComplete(); // flashes "✓ Review Complete" until tab gains focus
9
+ * window.tabTitle.flashFailed(); // flashes "✗ Review Failed" until tab gains focus
10
+ */
11
+ class TabTitle {
12
+ constructor() {
13
+ this._base = '';
14
+ this._flashInterval = null;
15
+ this._flashTimeout = null;
16
+ this._onVisibility = this._onVisibilityChange.bind(this);
17
+ }
18
+
19
+ /**
20
+ * Set the base identifier shown in the tab title.
21
+ * @param {string} identifier - e.g. "PR #123" or "feature/dark-mode"
22
+ */
23
+ setBase(identifier) {
24
+ this._base = identifier;
25
+ this._apply();
26
+ }
27
+
28
+ /** Flash "✓ Review Complete" until the tab gains focus. */
29
+ flashComplete() {
30
+ this._flash('✓ Review Complete');
31
+ }
32
+
33
+ /** Flash "✗ Review Failed" until the tab gains focus. */
34
+ flashFailed() {
35
+ this._flash('✗ Review Failed');
36
+ }
37
+
38
+ // ---------------------------------------------------------------------------
39
+ // Internal
40
+ // ---------------------------------------------------------------------------
41
+
42
+ _format(suffix) {
43
+ return suffix ? `pair-review - ${suffix}` : 'pair-review';
44
+ }
45
+
46
+ _apply() {
47
+ document.title = this._format(this._base);
48
+ }
49
+
50
+ _flash(message) {
51
+ this._stopFlash();
52
+
53
+ // If the tab is already visible, just show the message briefly then revert.
54
+ if (!document.hidden) {
55
+ document.title = this._format(message);
56
+ this._flashTimeout = setTimeout(() => this._apply(), 3000);
57
+ return;
58
+ }
59
+
60
+ // Tab is hidden — alternate between message and base title.
61
+ let showMessage = true;
62
+ document.title = this._format(message);
63
+
64
+ this._flashInterval = setInterval(() => {
65
+ showMessage = !showMessage;
66
+ document.title = showMessage
67
+ ? this._format(message)
68
+ : this._format(this._base);
69
+ }, 1000);
70
+
71
+ document.addEventListener('visibilitychange', this._onVisibility);
72
+ }
73
+
74
+ _onVisibilityChange() {
75
+ if (!document.hidden) {
76
+ this._stopFlash();
77
+ }
78
+ }
79
+
80
+ _stopFlash() {
81
+ if (this._flashTimeout) {
82
+ clearTimeout(this._flashTimeout);
83
+ this._flashTimeout = null;
84
+ }
85
+ if (this._flashInterval) {
86
+ clearInterval(this._flashInterval);
87
+ this._flashInterval = null;
88
+ }
89
+ document.removeEventListener('visibilitychange', this._onVisibility);
90
+ this._apply();
91
+ }
92
+ }
93
+
94
+ if (typeof module !== 'undefined') {
95
+ module.exports = { TabTitle };
96
+ }
@@ -8,6 +8,12 @@ class Toast {
8
8
  this.toastContainer = null;
9
9
  this.activeToasts = [];
10
10
  this.createContainer();
11
+
12
+ // Convenience aliases — matches the conventional toast API (toast.error(), toast.success(), etc.)
13
+ this.error = this.showError.bind(this);
14
+ this.success = this.showSuccess.bind(this);
15
+ this.warning = this.showWarning.bind(this);
16
+ this.info = this.showInfo.bind(this);
11
17
  }
12
18
 
13
19
  /**