@diegopetrucci/pi-extensions 0.1.73 → 0.1.76
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 +9 -4
- package/extensions/agent-workflow-audit/index.ts +1398 -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 +853 -767
- 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/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 +1 -1
- package/extensions/code-reviewer/index.ts +1598 -1350
- package/extensions/code-reviewer/package.json +1 -1
- package/extensions/confirm-destructive/README.md +1 -1
- package/extensions/confirm-destructive/index.ts +55 -51
- package/extensions/confirm-destructive/package.json +1 -1
- package/extensions/context-cap/index.ts +312 -304
- package/extensions/context-cap/package.json +1 -1
- package/extensions/context-inspector/index.ts +1211 -1064
- package/extensions/context-inspector/package.json +1 -1
- package/extensions/contrarian/index.ts +1854 -1735
- package/extensions/contrarian/package.json +1 -1
- package/extensions/dirty-repo-guard/index.ts +41 -41
- package/extensions/dynamic-context-pruning/README.md +6 -38
- package/extensions/dynamic-context-pruning/index.ts +2124 -1980
- package/extensions/dynamic-context-pruning/package.json +1 -1
- package/extensions/fast/README.md +71 -21
- package/extensions/fast/index.ts +513 -313
- 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 +88 -88
- package/extensions/inline-bash/package.json +1 -1
- package/extensions/librarian/index.ts +1669 -1419
- package/extensions/librarian/package.json +1 -1
- package/extensions/minimal-footer/index.ts +994 -1012
- package/extensions/minimal-footer/openai-usage.ts +195 -190
- 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/index.ts +1731 -1625
- package/extensions/oracle/package.json +1 -1
- package/extensions/permission-gate/index.ts +658 -608
- 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/index.ts +282 -264
- 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 +284 -265
- package/extensions/triage-comments/README.md +2 -2
- package/extensions/triage-comments/index.ts +2294 -1882
- package/extensions/triage-comments/package.json +1 -1
- package/package.json +6 -3
- 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,275 +1,35 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { dirname, join } from "node:path";
|
|
3
|
-
import {
|
|
4
|
-
CONFIG_DIR_NAME,
|
|
5
|
-
getAgentDir,
|
|
6
|
-
type ExtensionAPI,
|
|
7
|
-
type ExtensionContext,
|
|
8
|
-
} from "@earendil-works/pi-coding-agent";
|
|
1
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
9
2
|
|
|
10
3
|
const EXTENSION_ID = "openai-fast";
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
|
|
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
|
-
|
|
40
|
-
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
type ProjectConfigContext = {
|
|
44
|
-
cwd: string;
|
|
45
|
-
isProjectTrusted?: () => boolean;
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
type RecursivePartial<T> = {
|
|
49
|
-
[P in keyof T]?: T[P] extends object ? RecursivePartial<T[P]> : T[P];
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
type PayloadRecord = Record<string, unknown>;
|
|
53
|
-
|
|
54
|
-
type Eligibility = {
|
|
55
|
-
eligible: boolean;
|
|
56
|
-
modelKey: string;
|
|
57
|
-
reason?: string;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
function readConfigFile(path: string): RecursivePartial<OpenAIFastConfig> {
|
|
61
|
-
if (!existsSync(path)) return {};
|
|
62
|
-
|
|
63
|
-
try {
|
|
64
|
-
const parsed = JSON.parse(readFileSync(path, "utf-8"));
|
|
65
|
-
return isPayloadRecord(parsed) ? (parsed as RecursivePartial<OpenAIFastConfig>) : {};
|
|
66
|
-
} catch (error) {
|
|
67
|
-
console.error(`Warning: Could not parse ${path}: ${error}`);
|
|
68
|
-
return {};
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function normalizeBoolean(value: unknown, fallback: boolean): boolean {
|
|
73
|
-
return typeof value === "boolean" ? value : fallback;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function mergeConfig(
|
|
77
|
-
base: OpenAIFastConfig,
|
|
78
|
-
overrides: RecursivePartial<OpenAIFastConfig>,
|
|
79
|
-
): OpenAIFastConfig {
|
|
80
|
-
return {
|
|
81
|
-
enabled: normalizeBoolean(overrides.enabled, base.enabled),
|
|
82
|
-
showStatus: normalizeBoolean(overrides.showStatus, base.showStatus),
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function canReadProjectConfig(ctx: ProjectConfigContext): boolean {
|
|
87
|
-
return typeof ctx.isProjectTrusted === "function" && ctx.isProjectTrusted();
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function findProjectConfigPath(cwd: string): string {
|
|
91
|
-
let current = cwd;
|
|
92
|
-
while (true) {
|
|
93
|
-
const candidate = join(current, CONFIG_DIR_NAME, "openai-fast.json");
|
|
94
|
-
if (existsSync(candidate)) return candidate;
|
|
95
|
-
|
|
96
|
-
const parent = dirname(current);
|
|
97
|
-
if (parent === current) return join(cwd, CONFIG_DIR_NAME, "openai-fast.json");
|
|
98
|
-
current = parent;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function loadConfig(ctx: ProjectConfigContext): OpenAIFastConfig {
|
|
103
|
-
const globalConfig = readConfigFile(join(getAgentDir(), "extensions", "openai-fast.json"));
|
|
104
|
-
const projectConfig = canReadProjectConfig(ctx) ? readConfigFile(findProjectConfigPath(ctx.cwd)) : {};
|
|
105
|
-
return mergeConfig(mergeConfig(DEFAULT_CONFIG, globalConfig), projectConfig);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function isPayloadRecord(payload: unknown): payload is PayloadRecord {
|
|
109
|
-
return typeof payload === "object" && payload !== null && !Array.isArray(payload);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function modelKey(ctx: ExtensionContext): string {
|
|
113
|
-
const model = ctx.model;
|
|
114
|
-
return model ? `${model.provider}/${model.id}` : "no-model";
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function isFastEnabled(state: SessionState): boolean {
|
|
118
|
-
if (state.override === "on") return true;
|
|
119
|
-
if (state.override === "off") return false;
|
|
120
|
-
return state.config.enabled;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
function describeMode(state: SessionState): string {
|
|
124
|
-
if (state.override === "on") return "on (session override)";
|
|
125
|
-
if (state.override === "off") return "off (session override)";
|
|
126
|
-
return state.config.enabled ? "on (config default)" : "off (config default)";
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
function getEligibility(ctx: ExtensionContext): Eligibility {
|
|
130
|
-
const model = ctx.model;
|
|
131
|
-
if (!model) {
|
|
132
|
-
return { eligible: false, modelKey: "no-model", reason: "no model is selected" };
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const key = `${model.provider}/${model.id}`;
|
|
136
|
-
if (model.provider !== PROVIDER_ID) {
|
|
137
|
-
return {
|
|
138
|
-
eligible: false,
|
|
139
|
-
modelKey: key,
|
|
140
|
-
reason: `current provider is ${model.provider}, not ${PROVIDER_ID}`,
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if (model.api !== API_ID) {
|
|
145
|
-
return {
|
|
146
|
-
eligible: false,
|
|
147
|
-
modelKey: key,
|
|
148
|
-
reason: `current API is ${model.api}, not ${API_ID}`,
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
if (!SUPPORTED_MODELS.has(model.id)) {
|
|
153
|
-
return {
|
|
154
|
-
eligible: false,
|
|
155
|
-
modelKey: key,
|
|
156
|
-
reason: `Fast mode is only enabled for ${SUPPORTED_MODELS_LABEL}`,
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
if (!ctx.modelRegistry.isUsingOAuth(model)) {
|
|
161
|
-
return {
|
|
162
|
-
eligible: false,
|
|
163
|
-
modelKey: key,
|
|
164
|
-
reason: "ChatGPT OAuth auth is required; API-key auth is intentionally not used",
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
return { eligible: true, modelKey: key };
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
function updateStatus(ctx: ExtensionContext, state: SessionState): void {
|
|
172
|
-
if (!ctx.hasUI) return;
|
|
173
|
-
if (!state.config.showStatus) {
|
|
174
|
-
ctx.ui.setStatus(EXTENSION_ID, undefined);
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
const eligibility = getEligibility(ctx);
|
|
179
|
-
ctx.ui.setStatus(
|
|
180
|
-
EXTENSION_ID,
|
|
181
|
-
isFastEnabled(state) && eligibility.eligible ? "fast" : undefined,
|
|
182
|
-
);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
function getStatusMessage(ctx: ExtensionContext, state: SessionState): string {
|
|
186
|
-
const enabled = isFastEnabled(state);
|
|
187
|
-
const eligibility = getEligibility(ctx);
|
|
188
|
-
const active = enabled && eligibility.eligible;
|
|
189
|
-
const injected = state.lastInjectedAt
|
|
190
|
-
? ` Last injected for ${state.lastInjectedModel ?? "unknown model"} ${Math.max(0, Math.round((Date.now() - state.lastInjectedAt) / 1000))}s ago.`
|
|
191
|
-
: "";
|
|
192
|
-
|
|
193
|
-
if (active) {
|
|
194
|
-
return `OpenAI Fast mode is ${describeMode(state)} and active for ${eligibility.modelKey}; requests will use service_tier=${FAST_SERVICE_TIER}.${injected}`;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
if (enabled) {
|
|
198
|
-
return `OpenAI Fast mode is ${describeMode(state)}, but inactive for ${eligibility.modelKey}: ${eligibility.reason}.${injected}`;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
return `OpenAI Fast mode is ${describeMode(state)}. Current model: ${eligibility.modelKey}.${injected}`;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
function injectFastServiceTier(
|
|
205
|
-
payload: unknown,
|
|
206
|
-
ctx: ExtensionContext,
|
|
207
|
-
state: SessionState,
|
|
208
|
-
): PayloadRecord | undefined {
|
|
209
|
-
if (!isFastEnabled(state)) return undefined;
|
|
210
|
-
if (!getEligibility(ctx).eligible) return undefined;
|
|
211
|
-
if (!isPayloadRecord(payload)) return undefined;
|
|
212
|
-
if (payload.model !== ctx.model?.id) return undefined;
|
|
213
|
-
if ("service_tier" in payload) return undefined;
|
|
214
|
-
|
|
215
|
-
state.lastInjectedAt = Date.now();
|
|
216
|
-
state.lastInjectedModel = modelKey(ctx);
|
|
217
|
-
return {
|
|
218
|
-
...payload,
|
|
219
|
-
service_tier: FAST_SERVICE_TIER,
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
export default function openAIFastExtension(pi: ExtensionAPI) {
|
|
224
|
-
const states = new WeakMap<object, SessionState>();
|
|
225
|
-
|
|
226
|
-
function getState(ctx: ExtensionContext): SessionState {
|
|
227
|
-
let state = states.get(ctx.sessionManager);
|
|
228
|
-
if (!state) {
|
|
229
|
-
state = {
|
|
230
|
-
config: loadConfig(ctx),
|
|
231
|
-
override: "auto",
|
|
232
|
-
};
|
|
233
|
-
states.set(ctx.sessionManager, state);
|
|
234
|
-
}
|
|
235
|
-
return state;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
pi.on("session_start", (_event, ctx) => {
|
|
239
|
-
const state: SessionState = {
|
|
240
|
-
config: loadConfig(ctx),
|
|
241
|
-
override: "auto",
|
|
242
|
-
};
|
|
243
|
-
states.set(ctx.sessionManager, state);
|
|
244
|
-
updateStatus(ctx, state);
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
pi.on("model_select", (_event, ctx) => {
|
|
248
|
-
updateStatus(ctx, getState(ctx));
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
pi.on("before_provider_request", (event, ctx) => {
|
|
252
|
-
const state = getState(ctx);
|
|
253
|
-
const nextPayload = injectFastServiceTier(event.payload, ctx, state);
|
|
254
|
-
updateStatus(ctx, state);
|
|
255
|
-
return nextPayload;
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
pi.registerCommand("fast", {
|
|
259
|
-
description: "Toggle OpenAI Codex Fast mode for ChatGPT-auth GPT-5.5 and GPT-5.6 Codex variants",
|
|
260
|
-
getArgumentCompletions: () => null,
|
|
261
|
-
handler: async (args, ctx) => {
|
|
262
|
-
const state = getState(ctx);
|
|
263
|
-
const action = args.trim();
|
|
264
|
-
|
|
265
|
-
if (!action) {
|
|
266
|
-
state.override = isFastEnabled(state) ? "off" : "on";
|
|
267
|
-
updateStatus(ctx, state);
|
|
268
|
-
ctx.ui.notify(getStatusMessage(ctx, state), "info");
|
|
269
|
-
return;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
ctx.ui.notify("Usage: /fast", "warning");
|
|
273
|
-
},
|
|
274
|
-
});
|
|
4
|
+
const FAST_BETA = "fast-mode-2026-02-01";
|
|
5
|
+
const DEPRECATION_NOTICE =
|
|
6
|
+
"openai-fast is deprecated and no longer changes provider requests. Use the unified fast extension (/fast) instead.";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Deprecated leftover of the provider-specific Fast stack.
|
|
10
|
+
* The collection loads extensions/fast only. This package keeps the published
|
|
11
|
+
* npm name working. It does not read config, register commands, or inject Fast
|
|
12
|
+
* fields. Startup only clears leftover footer status and the Fast beta header,
|
|
13
|
+
* which /reload otherwise keeps from the previous extension runtime.
|
|
14
|
+
*/
|
|
15
|
+
function stripFastBeta(headers: Record<string, string> | undefined): void {
|
|
16
|
+
if (!headers) return;
|
|
17
|
+
for (const key of Object.keys(headers)) {
|
|
18
|
+
if (key.toLowerCase() !== "anthropic-beta") continue;
|
|
19
|
+
const next = headers[key]
|
|
20
|
+
.split(",")
|
|
21
|
+
.map((part) => part.trim())
|
|
22
|
+
.filter((part) => part && part !== FAST_BETA);
|
|
23
|
+
if (next.length === 0) delete headers[key];
|
|
24
|
+
else headers[key] = next.join(",");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export default function openAIFastExtension(pi: ExtensionAPI): void {
|
|
29
|
+
pi.on("session_start", (_event, ctx) => {
|
|
30
|
+
stripFastBeta(ctx.model?.headers);
|
|
31
|
+
if (!ctx.hasUI) return;
|
|
32
|
+
ctx.ui.setStatus(EXTENSION_ID, undefined);
|
|
33
|
+
ctx.ui.notify(DEPRECATION_NOTICE, "warning");
|
|
34
|
+
});
|
|
275
35
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diegopetrucci/pi-openai-fast",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.18",
|
|
4
|
+
"description": "Deprecated standalone leftover. Does not change provider requests; use @diegopetrucci/pi-fast.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
7
7
|
"pi",
|
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
},
|
|
18
18
|
"files": [
|
|
19
19
|
"index.ts",
|
|
20
|
-
"openai-fast.example.json",
|
|
21
20
|
"README.md",
|
|
22
21
|
".pi-fleet-tested-version"
|
|
23
22
|
],
|