@diegopetrucci/pi-extensions 0.1.74 → 0.1.78
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/LICENSE +2 -0
- package/README.md +17 -12
- package/extensions/agent-workflow-audit/README.md +1 -1
- package/extensions/agent-workflow-audit/index.ts +1631 -1009
- package/extensions/agent-workflow-audit/package.json +1 -1
- package/extensions/annotate-git-diff/README.md +3 -1
- package/extensions/annotate-git-diff/clipboard.ts +109 -100
- package/extensions/annotate-git-diff/git.ts +846 -768
- package/extensions/annotate-git-diff/glimpseui.d.ts +87 -78
- package/extensions/annotate-git-diff/index.ts +712 -671
- package/extensions/annotate-git-diff/package.json +1 -1
- package/extensions/annotate-git-diff/prompt.ts +45 -45
- package/extensions/annotate-git-diff/quiet-glimpse.ts +161 -155
- package/extensions/annotate-git-diff/review-server.ts +337 -311
- package/extensions/annotate-git-diff/types.ts +132 -132
- package/extensions/annotate-git-diff/ui.ts +27 -27
- package/extensions/annotate-git-diff/watch.ts +74 -74
- package/extensions/annotate-git-diff/web/app.js +1947 -1884
- package/extensions/annotate-git-diff/web/index.html +5 -6
- package/extensions/annotate-last-message/README.md +1 -1
- package/extensions/annotate-last-message/glimpseui.d.ts +87 -78
- package/extensions/annotate-last-message/index.ts +210 -206
- package/extensions/annotate-last-message/package.json +1 -1
- package/extensions/annotate-last-message/prompt.ts +87 -66
- package/extensions/annotate-last-message/quiet-glimpse.ts +161 -155
- package/extensions/annotate-last-message/session.ts +94 -89
- package/extensions/annotate-last-message/theme.ts +199 -193
- package/extensions/annotate-last-message/types.ts +23 -23
- package/extensions/annotate-last-message/ui.ts +27 -25
- package/extensions/annotate-last-message/web/app.js +4 -7
- package/extensions/annotate-last-message/web/index.html +3 -3
- package/extensions/annotate-last-message/web/md-renderer.js +1 -1
- package/extensions/brrr/README.md +1 -1
- package/extensions/brrr/index.ts +213 -191
- package/extensions/brrr/package.json +1 -1
- package/extensions/claude-fast/README.md +5 -79
- package/extensions/claude-fast/index.ts +31 -289
- package/extensions/claude-fast/package.json +2 -3
- package/extensions/code-reviewer/README.md +6 -6
- package/extensions/code-reviewer/index.ts +1825 -1373
- package/extensions/code-reviewer/package.json +1 -1
- package/extensions/confirm-destructive/README.md +1 -1
- package/extensions/confirm-destructive/index.ts +50 -52
- package/extensions/confirm-destructive/package.json +1 -1
- package/extensions/context-cap/README.md +9 -9
- package/extensions/context-cap/index.ts +313 -305
- package/extensions/context-cap/package.json +2 -2
- package/extensions/context-inspector/index.ts +1211 -1064
- package/extensions/context-inspector/package.json +1 -1
- package/extensions/contrarian/README.md +4 -3
- package/extensions/contrarian/index.ts +1863 -1737
- package/extensions/contrarian/package.json +1 -1
- package/extensions/dirty-repo-guard/index.ts +37 -41
- package/extensions/dirty-repo-guard/package.json +1 -1
- package/extensions/dynamic-context-pruning/README.md +11 -43
- package/extensions/dynamic-context-pruning/index.ts +2131 -2105
- package/extensions/dynamic-context-pruning/package.json +1 -1
- package/extensions/fast/README.md +52 -14
- package/extensions/fast/index.ts +513 -317
- package/extensions/fast/package.json +1 -1
- package/extensions/git-footer/README.md +1 -1
- package/extensions/git-footer/index.ts +458 -411
- package/extensions/git-footer/package.json +2 -3
- package/extensions/gnosis/index.ts +180 -130
- package/extensions/gnosis/package.json +1 -1
- package/extensions/inline-bash/index.ts +87 -103
- package/extensions/inline-bash/package.json +1 -1
- package/extensions/librarian/README.md +1 -1
- package/extensions/librarian/index.ts +1877 -1419
- package/extensions/librarian/package.json +1 -1
- package/extensions/minimal-footer/README.md +5 -5
- package/extensions/minimal-footer/index.ts +987 -1012
- package/extensions/minimal-footer/minimal-footer.example.json +1 -1
- package/extensions/minimal-footer/openai-usage.ts +195 -190
- package/extensions/minimal-footer/package.json +1 -1
- package/extensions/notify/index.ts +222 -230
- package/extensions/notify/package.json +1 -1
- package/extensions/openai-fast/README.md +5 -73
- package/extensions/openai-fast/index.ts +32 -272
- package/extensions/openai-fast/package.json +2 -3
- package/extensions/oracle/README.md +4 -3
- package/extensions/oracle/index.ts +1740 -1627
- package/extensions/oracle/package.json +1 -1
- package/extensions/permission-gate/README.md +3 -0
- package/extensions/permission-gate/index.ts +785 -612
- package/extensions/permission-gate/package.json +1 -1
- package/extensions/permission-gate/powershell-safety.ts +840 -793
- package/extensions/project-mcp-json/.pi-fleet-tested-version +1 -0
- package/extensions/project-mcp-json/README.md +199 -0
- package/extensions/project-mcp-json/config.ts +564 -0
- package/extensions/project-mcp-json/index.ts +119 -0
- package/extensions/project-mcp-json/package.json +38 -0
- package/extensions/quiet-tools/.pi-fleet-tested-version +1 -1
- package/extensions/quiet-tools/README.md +30 -19
- package/extensions/quiet-tools/index.ts +376 -291
- package/extensions/quiet-tools/package.json +2 -2
- package/extensions/review/README.md +2 -2
- package/extensions/review/index.ts +1745 -1872
- package/extensions/review/package.json +1 -1
- package/extensions/todo/index.ts +280 -280
- package/extensions/todo/package.json +1 -1
- package/extensions/triage-comments/README.md +6 -4
- package/extensions/triage-comments/index.ts +2620 -1888
- package/extensions/triage-comments/package.json +1 -1
- package/package.json +9 -6
- package/assets/social-preview.png +0 -0
- package/extensions/claude-fast/claude-fast.example.json +0 -4
- package/extensions/openai-fast/openai-fast.example.json +0 -4
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
Theme,
|
|
3
|
-
ThemeBg,
|
|
4
|
-
ThemeColor,
|
|
5
|
-
} from "@earendil-works/pi-coding-agent";
|
|
1
|
+
import type { Theme, ThemeBg, ThemeColor } from "@earendil-works/pi-coding-agent";
|
|
6
2
|
|
|
7
3
|
/**
|
|
8
4
|
* The small public part of Pi's active theme used by the native annotation UI.
|
|
@@ -11,209 +7,219 @@ import type {
|
|
|
11
7
|
export type AnnotateTheme = Pick<Theme, "appearance" | "colors" | "fg" | "bg">;
|
|
12
8
|
|
|
13
9
|
const DARK_FALLBACK: Readonly<Record<string, string>> = {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
10
|
+
"--color-scheme": "dark",
|
|
11
|
+
"--bg": "#0d1117",
|
|
12
|
+
"--panel": "#151b23",
|
|
13
|
+
"--panel-hover": "#1f242c",
|
|
14
|
+
"--inset": "#0b1118",
|
|
15
|
+
"--border": "#30363d",
|
|
16
|
+
"--border-muted": "#21262d",
|
|
17
|
+
"--text": "#f0f6fc",
|
|
18
|
+
"--muted": "#8a8a8a",
|
|
19
|
+
"--dim": "#585858",
|
|
20
|
+
"--accent": "#f4c95d",
|
|
21
|
+
"--success": "#7ee787",
|
|
22
|
+
"--error": "#ffb3b3",
|
|
23
|
+
"--warning": "#f4c95d",
|
|
24
|
+
"--mdHeading": "#f4c95d",
|
|
25
|
+
"--mdLink": "#7dd3fc",
|
|
26
|
+
"--mdLinkUrl": "#8a8a8a",
|
|
27
|
+
"--mdCode": "#9b7bff",
|
|
28
|
+
"--mdCodeBlock": "inherit",
|
|
29
|
+
"--mdCodeBlockBorder": "#6f42c1",
|
|
30
|
+
"--mdQuote": "#8a8a8a",
|
|
31
|
+
"--mdQuoteBorder": "#6f42c1",
|
|
32
|
+
"--mdHr": "#585858",
|
|
33
|
+
"--mdListBullet": "#f4c95d",
|
|
34
|
+
"--mdBold": "inherit",
|
|
35
|
+
"--mdItalic": "inherit",
|
|
40
36
|
};
|
|
41
37
|
|
|
42
38
|
const LIGHT_FALLBACK: Readonly<Record<string, string>> = {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
39
|
+
"--color-scheme": "light",
|
|
40
|
+
"--bg": "#f6f8fa",
|
|
41
|
+
"--panel": "#ffffff",
|
|
42
|
+
"--panel-hover": "#f3f4f6",
|
|
43
|
+
"--inset": "#f6f8fa",
|
|
44
|
+
"--border": "#d0d7de",
|
|
45
|
+
"--border-muted": "#afb8c1",
|
|
46
|
+
"--text": "#1f2328",
|
|
47
|
+
"--muted": "#57606a",
|
|
48
|
+
"--dim": "#6e7781",
|
|
49
|
+
"--accent": "#8250df",
|
|
50
|
+
"--success": "#1a7f37",
|
|
51
|
+
"--error": "#cf222e",
|
|
52
|
+
"--warning": "#9a6700",
|
|
53
|
+
"--mdHeading": "#9a6700",
|
|
54
|
+
"--mdLink": "#0969da",
|
|
55
|
+
"--mdLinkUrl": "#57606a",
|
|
56
|
+
"--mdCode": "#8250df",
|
|
57
|
+
"--mdCodeBlock": "#1a7f37",
|
|
58
|
+
"--mdCodeBlockBorder": "#6e7781",
|
|
59
|
+
"--mdQuote": "#57606a",
|
|
60
|
+
"--mdQuoteBorder": "#6e7781",
|
|
61
|
+
"--mdHr": "#8c959f",
|
|
62
|
+
"--mdListBullet": "#8250df",
|
|
63
|
+
"--mdBold": "inherit",
|
|
64
|
+
"--mdItalic": "inherit",
|
|
69
65
|
};
|
|
70
66
|
|
|
71
67
|
const BASIC_ANSI_COLORS: Readonly<Record<number, string>> = {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
68
|
+
0: "#000000",
|
|
69
|
+
1: "#800000",
|
|
70
|
+
2: "#008000",
|
|
71
|
+
3: "#808000",
|
|
72
|
+
4: "#000080",
|
|
73
|
+
5: "#800080",
|
|
74
|
+
6: "#008080",
|
|
75
|
+
7: "#c0c0c0",
|
|
76
|
+
8: "#808080",
|
|
77
|
+
9: "#ff0000",
|
|
78
|
+
10: "#00ff00",
|
|
79
|
+
11: "#ffff00",
|
|
80
|
+
12: "#0000ff",
|
|
81
|
+
13: "#ff00ff",
|
|
82
|
+
14: "#00ffff",
|
|
83
|
+
15: "#ffffff",
|
|
88
84
|
};
|
|
89
85
|
|
|
90
86
|
const CUBE_LEVELS = [0, 95, 135, 175, 215, 255] as const;
|
|
91
87
|
const SENTINEL = "X";
|
|
92
88
|
|
|
93
89
|
const FOREGROUND_THEME_VARS: ReadonlyArray<{ token: ThemeColor; cssVar: string }> = [
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
90
|
+
{ token: "text", cssVar: "--text" },
|
|
91
|
+
{ token: "muted", cssVar: "--muted" },
|
|
92
|
+
{ token: "dim", cssVar: "--dim" },
|
|
93
|
+
{ token: "accent", cssVar: "--accent" },
|
|
94
|
+
{ token: "success", cssVar: "--success" },
|
|
95
|
+
{ token: "error", cssVar: "--error" },
|
|
96
|
+
{ token: "warning", cssVar: "--warning" },
|
|
97
|
+
{ token: "mdHeading", cssVar: "--mdHeading" },
|
|
98
|
+
{ token: "mdLink", cssVar: "--mdLink" },
|
|
99
|
+
{ token: "mdLinkUrl", cssVar: "--mdLinkUrl" },
|
|
100
|
+
{ token: "mdCode", cssVar: "--mdCode" },
|
|
101
|
+
{ token: "mdCodeBlock", cssVar: "--mdCodeBlock" },
|
|
102
|
+
{ token: "mdCodeBlockBorder", cssVar: "--mdCodeBlockBorder" },
|
|
103
|
+
{ token: "mdQuote", cssVar: "--mdQuote" },
|
|
104
|
+
{ token: "mdQuoteBorder", cssVar: "--mdQuoteBorder" },
|
|
105
|
+
{ token: "mdHr", cssVar: "--mdHr" },
|
|
106
|
+
{ token: "mdListBullet", cssVar: "--mdListBullet" },
|
|
107
|
+
{ token: "border", cssVar: "--border" },
|
|
108
|
+
{ token: "borderMuted", cssVar: "--border-muted" },
|
|
113
109
|
];
|
|
114
110
|
|
|
115
111
|
const BACKGROUND_THEME_VARS: ReadonlyArray<{ token: ThemeBg; cssVar: string }> = [
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
112
|
+
{ token: "customMessageBg", cssVar: "--panel" },
|
|
113
|
+
{ token: "selectedBg", cssVar: "--panel-hover" },
|
|
114
|
+
{ token: "toolPendingBg", cssVar: "--inset" },
|
|
119
115
|
];
|
|
120
116
|
|
|
121
117
|
function toHex(value: number): string {
|
|
122
|
-
|
|
123
|
-
|
|
118
|
+
const clamped = Math.min(255, Math.max(0, Math.round(value)));
|
|
119
|
+
return clamped.toString(16).padStart(2, "0");
|
|
124
120
|
}
|
|
125
121
|
|
|
126
122
|
function xterm256ToHex(index: number): string | null {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
123
|
+
if (!Number.isInteger(index) || index < 0 || index > 255) return null;
|
|
124
|
+
if (index < 16) return BASIC_ANSI_COLORS[index] ?? null;
|
|
125
|
+
if (index >= 232) {
|
|
126
|
+
const value = 8 + (index - 232) * 10;
|
|
127
|
+
const hex = toHex(value);
|
|
128
|
+
return `#${hex}${hex}${hex}`;
|
|
129
|
+
}
|
|
130
|
+
const cubeIndex = index - 16;
|
|
131
|
+
const blue = cubeIndex % 6;
|
|
132
|
+
const green = Math.floor(cubeIndex / 6) % 6;
|
|
133
|
+
const red = Math.floor(cubeIndex / 36) % 6;
|
|
134
|
+
return `#${toHex(CUBE_LEVELS[red])}${toHex(CUBE_LEVELS[green])}${toHex(CUBE_LEVELS[blue])}`;
|
|
139
135
|
}
|
|
140
136
|
|
|
141
137
|
function colorValueToHex(value: unknown): string | null {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
138
|
+
if (typeof value !== "object" || value == null) return null;
|
|
139
|
+
const color = value as { kind?: unknown; r?: unknown; g?: unknown; b?: unknown; index?: unknown };
|
|
140
|
+
if (color.kind === "rgb") {
|
|
141
|
+
const channels = [color.r, color.g, color.b];
|
|
142
|
+
if (
|
|
143
|
+
!channels.every(
|
|
144
|
+
(channel) =>
|
|
145
|
+
typeof channel === "number" && Number.isFinite(channel) && channel >= 0 && channel <= 255,
|
|
146
|
+
)
|
|
147
|
+
) {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
return `#${toHex(color.r as number)}${toHex(color.g as number)}${toHex(color.b as number)}`;
|
|
151
|
+
}
|
|
152
|
+
if (color.kind === "indexed" && typeof color.index === "number") {
|
|
153
|
+
return xterm256ToHex(color.index);
|
|
154
|
+
}
|
|
155
|
+
// OKLCH values are intentionally handled through theme.fg/theme.bg below.
|
|
156
|
+
// Those public helpers account for Pi's configured terminal color mode.
|
|
157
|
+
return null;
|
|
157
158
|
}
|
|
158
159
|
|
|
159
160
|
function ansiColorToHex(value: unknown, background: boolean): string | null {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
161
|
+
if (typeof value !== "string") return null;
|
|
162
|
+
const match = new RegExp(`^\\u001b\\[([0-9;]+)m`).exec(value);
|
|
163
|
+
if (!match) return null;
|
|
164
|
+
const params = match[1].split(";").map(Number);
|
|
165
|
+
const [mode, kind, first, second, third] = params;
|
|
166
|
+
const expectedMode = background ? 48 : 38;
|
|
167
|
+
if (mode !== expectedMode) {
|
|
168
|
+
if (!background && ((mode >= 30 && mode <= 37) || (mode >= 90 && mode <= 97))) {
|
|
169
|
+
return xterm256ToHex(mode >= 90 ? mode - 82 : mode - 30);
|
|
170
|
+
}
|
|
171
|
+
if (background && ((mode >= 40 && mode <= 47) || (mode >= 100 && mode <= 107))) {
|
|
172
|
+
return xterm256ToHex(mode >= 100 ? mode - 92 : mode - 40);
|
|
173
|
+
}
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
if (kind === 2 && params.length >= 5) {
|
|
177
|
+
const channels = [first, second, third];
|
|
178
|
+
if (!channels.every((channel) => Number.isInteger(channel) && channel >= 0 && channel <= 255))
|
|
179
|
+
return null;
|
|
180
|
+
return `#${toHex(first)}${toHex(second)}${toHex(third)}`;
|
|
181
|
+
}
|
|
182
|
+
if (kind === 5 && params.length >= 3) return xterm256ToHex(first);
|
|
183
|
+
return null;
|
|
182
184
|
}
|
|
183
185
|
|
|
184
|
-
function readThemeColor(
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
186
|
+
function readThemeColor(
|
|
187
|
+
theme: AnnotateTheme,
|
|
188
|
+
token: ThemeColor | ThemeBg,
|
|
189
|
+
background: boolean,
|
|
190
|
+
): string | null {
|
|
191
|
+
let colors: Readonly<Record<string, unknown>> | undefined;
|
|
192
|
+
try {
|
|
193
|
+
colors = theme.colors as Readonly<Record<string, unknown>>;
|
|
194
|
+
} catch {
|
|
195
|
+
colors = undefined;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
let colorValue: unknown;
|
|
199
|
+
try {
|
|
200
|
+
colorValue = colors?.[token];
|
|
201
|
+
} catch {
|
|
202
|
+
colorValue = undefined;
|
|
203
|
+
}
|
|
204
|
+
const fromColors = colorValueToHex(colorValue);
|
|
205
|
+
if (fromColors != null) return fromColors;
|
|
206
|
+
|
|
207
|
+
try {
|
|
208
|
+
const styled = background
|
|
209
|
+
? theme.bg(token as ThemeBg, SENTINEL)
|
|
210
|
+
: theme.fg(token as ThemeColor, SENTINEL);
|
|
211
|
+
return ansiColorToHex(styled, background);
|
|
212
|
+
} catch {
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
209
215
|
}
|
|
210
216
|
|
|
211
217
|
function readAppearance(theme: AnnotateTheme | null | undefined): "dark" | "light" {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
218
|
+
try {
|
|
219
|
+
return theme?.appearance === "light" ? "light" : "dark";
|
|
220
|
+
} catch {
|
|
221
|
+
return "dark";
|
|
222
|
+
}
|
|
217
223
|
}
|
|
218
224
|
|
|
219
225
|
/**
|
|
@@ -224,24 +230,24 @@ function readAppearance(theme: AnnotateTheme | null | undefined): "dark" | "ligh
|
|
|
224
230
|
* native annotation window unreadable or prevent it from opening.
|
|
225
231
|
*/
|
|
226
232
|
export function getThemeCssVars(theme?: AnnotateTheme | null): Record<string, string> {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
233
|
+
const vars: Record<string, string> = {
|
|
234
|
+
...(readAppearance(theme) === "light" ? LIGHT_FALLBACK : DARK_FALLBACK),
|
|
235
|
+
};
|
|
236
|
+
if (theme == null) return vars;
|
|
237
|
+
|
|
238
|
+
for (const { token, cssVar } of FOREGROUND_THEME_VARS) {
|
|
239
|
+
const color = readThemeColor(theme, token, false);
|
|
240
|
+
if (color != null) vars[cssVar] = color;
|
|
241
|
+
}
|
|
242
|
+
for (const { token, cssVar } of BACKGROUND_THEME_VARS) {
|
|
243
|
+
const color = readThemeColor(theme, token, true);
|
|
244
|
+
if (color != null) vars[cssVar] = color;
|
|
245
|
+
}
|
|
246
|
+
return vars;
|
|
241
247
|
}
|
|
242
248
|
|
|
243
249
|
export const __testing = {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
250
|
+
ansiColorToHex,
|
|
251
|
+
colorValueToHex,
|
|
252
|
+
xterm256ToHex,
|
|
247
253
|
};
|
|
@@ -1,46 +1,46 @@
|
|
|
1
1
|
export interface LastAssistantMessageLine {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
number: number;
|
|
3
|
+
text: string;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
export interface LastAssistantMessageSection {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
text: string;
|
|
7
|
+
id: string;
|
|
8
|
+
index: number;
|
|
9
|
+
startLine: number;
|
|
10
|
+
endLine: number;
|
|
11
|
+
preview: string;
|
|
13
12
|
}
|
|
14
13
|
|
|
15
14
|
export interface LastAssistantMessageData {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
sections: LastAssistantMessageSection[];
|
|
15
|
+
lines: LastAssistantMessageLine[];
|
|
16
|
+
sections: LastAssistantMessageSection[];
|
|
19
17
|
}
|
|
20
18
|
|
|
21
19
|
export type LastAssistantMessageLookupResult =
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
| { ok: true; data: LastAssistantMessageData }
|
|
21
|
+
| { ok: false; code: "missing" | "incomplete" | "empty"; message: string };
|
|
24
22
|
|
|
25
23
|
export interface AnnotateLastMessageInlineComment {
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
line: number;
|
|
25
|
+
body: string;
|
|
28
26
|
}
|
|
29
27
|
|
|
30
28
|
export interface AnnotateLastMessageSectionComment {
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
sectionId: string;
|
|
30
|
+
body: string;
|
|
33
31
|
}
|
|
34
32
|
|
|
35
33
|
export interface AnnotateLastMessageSubmitPayload {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
type: "submit";
|
|
35
|
+
overallComment: string;
|
|
36
|
+
inlineComments: AnnotateLastMessageInlineComment[];
|
|
37
|
+
sectionComments: AnnotateLastMessageSectionComment[];
|
|
40
38
|
}
|
|
41
39
|
|
|
42
40
|
export interface AnnotateLastMessageCancelPayload {
|
|
43
|
-
|
|
41
|
+
type: "cancel";
|
|
44
42
|
}
|
|
45
43
|
|
|
46
|
-
export type AnnotateLastMessageWindowMessage =
|
|
44
|
+
export type AnnotateLastMessageWindowMessage =
|
|
45
|
+
| AnnotateLastMessageSubmitPayload
|
|
46
|
+
| AnnotateLastMessageCancelPayload;
|
|
@@ -10,40 +10,42 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
|
10
10
|
const webDir = join(__dirname, "web");
|
|
11
11
|
|
|
12
12
|
function escapeForInlineScript(value: string): string {
|
|
13
|
-
|
|
13
|
+
return value.replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026");
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
function escapeInlineScriptSource(value: string): string {
|
|
17
|
-
|
|
17
|
+
return value.replace(/<\/(script)/gi, "<\\/$1");
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
function buildThemeCssBlock(vars: Record<string, string>): string {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
const declarations = Object.entries(vars)
|
|
22
|
+
.map(([key, value]) => ` ${key}: ${value};`)
|
|
23
|
+
.join("\n");
|
|
24
|
+
return `:root {\n${declarations}\n}`;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export function buildAnnotateLastMessageHtml(
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
data: LastAssistantMessageData,
|
|
29
|
+
theme?: AnnotateTheme,
|
|
30
30
|
): string {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
31
|
+
const templateHtml = readFileSync(join(webDir, "index.html"), "utf8");
|
|
32
|
+
const mdRendererJs = escapeInlineScriptSource(
|
|
33
|
+
readFileSync(join(webDir, "md-renderer.js"), "utf8"),
|
|
34
|
+
);
|
|
35
|
+
const appJs = escapeInlineScriptSource(readFileSync(join(webDir, "app.js"), "utf8"));
|
|
36
|
+
const payload = escapeForInlineScript(JSON.stringify(data));
|
|
37
|
+
const themeBlock = buildThemeCssBlock(getThemeCssVars(theme));
|
|
38
|
+
const replacements = new Map([
|
|
39
|
+
['"__INLINE_DATA__"', payload],
|
|
40
|
+
["__INLINE_MD_RENDERER_JS__", mdRendererJs],
|
|
41
|
+
["__INLINE_JS__", appJs],
|
|
42
|
+
["__INLINE_THEME__", themeBlock],
|
|
43
|
+
]);
|
|
42
44
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
// Replace the original template in one pass so marker-like message data,
|
|
46
|
+
// theme values, or runtime source is never scanned as another placeholder.
|
|
47
|
+
return templateHtml.replace(
|
|
48
|
+
/"__INLINE_DATA__"|__INLINE_MD_RENDERER_JS__|__INLINE_JS__|__INLINE_THEME__/g,
|
|
49
|
+
(marker) => replacements.get(marker) ?? marker,
|
|
50
|
+
);
|
|
49
51
|
}
|
|
@@ -305,9 +305,6 @@ function createSectionCard(section) {
|
|
|
305
305
|
meta.textContent = lineRange;
|
|
306
306
|
card.append(meta);
|
|
307
307
|
|
|
308
|
-
// Render the exact source lines in this section. Do not parse section.text
|
|
309
|
-
// independently: its opening fence may be in an earlier section separated
|
|
310
|
-
// by a blank line.
|
|
311
308
|
const preview = document.createElement("div");
|
|
312
309
|
preview.className = "section-preview markdown-content";
|
|
313
310
|
|
|
@@ -316,9 +313,7 @@ function createSectionCard(section) {
|
|
|
316
313
|
const sourceLines =
|
|
317
314
|
startIndex >= 0 && endIndex >= startIndex && endIndex <= messageData.lines.length
|
|
318
315
|
? messageData.lines.slice(startIndex, endIndex).map((line) => line.text)
|
|
319
|
-
:
|
|
320
|
-
? section.text.split("\n")
|
|
321
|
-
: [];
|
|
316
|
+
: [];
|
|
322
317
|
for (let idx = 0; idx < sourceLines.length; idx++) {
|
|
323
318
|
const lineDiv = document.createElement("div");
|
|
324
319
|
const sourceIndex = startIndex >= 0 ? startIndex + idx : -1;
|
|
@@ -342,7 +337,9 @@ function createSectionCard(section) {
|
|
|
342
337
|
function renderMessageLines() {
|
|
343
338
|
elements.messageLines.replaceChildren();
|
|
344
339
|
for (let i = 0; i < messageData.lines.length; i++) {
|
|
345
|
-
elements.messageLines.append(
|
|
340
|
+
elements.messageLines.append(
|
|
341
|
+
createLineRow(messageData.lines[i], fullMessageFenceState[i].lineType),
|
|
342
|
+
);
|
|
346
343
|
}
|
|
347
344
|
}
|
|
348
345
|
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
* overrides semantic and Markdown colours from ctx.ui.theme. When Pi's theme
|
|
11
11
|
* cannot provide a token, the matching dark/light fallback remains readable.
|
|
12
12
|
*
|
|
13
|
-
* The --md* fallback values below are kept in sync with
|
|
14
|
-
*
|
|
13
|
+
* The --md* fallback values below are kept in sync with DARK_FALLBACK
|
|
14
|
+
* in theme.ts so this template renders correctly when the injected
|
|
15
15
|
* theme block is absent (e.g. opened standalone in a browser for debugging).
|
|
16
16
|
*/
|
|
17
17
|
:root {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
--error: #ffb3b3;
|
|
32
32
|
--warning: #f4c95d;
|
|
33
33
|
|
|
34
|
-
/* Markdown token colours — kept in sync with
|
|
34
|
+
/* Markdown token colours — kept in sync with DARK_FALLBACK in theme.ts */
|
|
35
35
|
--mdHeading: #f4c95d;
|
|
36
36
|
--mdLink: #7dd3fc;
|
|
37
37
|
--mdLinkUrl: #8a8a8a;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* global globalThis */
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* annotate-last-message: pure markdown line parser.
|
|
5
5
|
*
|
|
6
6
|
* Single source of truth for the parsing logic. ui.ts reads this file and
|
|
7
7
|
* inlines it as a dedicated script before app.js, so globalThis.__tlhMdRenderer
|
|
@@ -83,4 +83,4 @@ Example:
|
|
|
83
83
|
|
|
84
84
|
- Hooks the `agent_settled` event so automatic retries, compaction retries, and queued follow-ups do not trigger intermediate notifications.
|
|
85
85
|
- The extension sends directly to the brrr webhook; it does not require the `brrr` CLI at runtime.
|
|
86
|
-
- By default, notifications are skipped unless the Mac has been idle for at least 20 seconds.
|
|
86
|
+
- Idle skip is macOS-only. By default, notifications are skipped unless the Mac has been idle for at least 20 seconds. Non-macOS always notifies.
|