Skip to content

Commit d6c831c

Browse files
committed
feat: add PI_WEBFETCH env toggle to disable extension
1 parent dc4cf7f commit d6c831c

2 files changed

Lines changed: 76 additions & 0 deletions

File tree

src/index.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,43 @@ interface ResultLike<TDetails> {
88
details?: TDetails;
99
}
1010

11+
const ENABLE_ENV = "PI_WEBFETCH";
12+
13+
function parseEnableEnv(envVar: string): boolean {
14+
const envValue = process.env[envVar];
15+
if (!envValue) {
16+
return true;
17+
}
18+
19+
const normalized = envValue.trim().toLowerCase();
20+
if (normalized === "0" || normalized === "false" || normalized === "no" || normalized === "off") {
21+
return false;
22+
}
23+
24+
if (normalized === "1" || normalized === "true" || normalized === "yes" || normalized === "on") {
25+
return true;
26+
}
27+
28+
// Unknown values fall back to default-on behavior.
29+
return true;
30+
}
31+
32+
export function isWebfetchEnabled(): boolean {
33+
return parseEnableEnv(ENABLE_ENV);
34+
}
35+
1136
/**
1237
* pi-webfetch — URL retrieval for the pi coding agent.
1338
*
1439
* Registers one LLM-callable tool:
1540
* - webfetch — fetch URL content as markdown, text, or html.
1641
*/
1742
export default function (pi: ExtensionAPI): void {
43+
// When PI_WEBFETCH disables the extension, keep factory callable but skip all registration side effects.
44+
if (!isWebfetchEnabled()) {
45+
return;
46+
}
47+
1848
pi.registerTool({
1949
...webfetch,
2050
renderCall: (args, theme) => renderWebfetchCall(args as never, theme),

test/index.test.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { describe, expect, it, vi } from "vitest";
2+
import webfetchExtension, { isWebfetchEnabled } from "../src/index.js";
3+
4+
const ENABLE_ENV = "PI_WEBFETCH";
5+
6+
describe("webfetch extension toggle", () => {
7+
it("returns true when PI_WEBFETCH is unset", () => {
8+
delete process.env[ENABLE_ENV];
9+
expect(isWebfetchEnabled()).toBe(true);
10+
});
11+
12+
it.each(["1", "true", "yes", "on", " TRUE ", "\tYeS\n"])(
13+
"returns true for truthy PI_WEBFETCH value %s",
14+
(envValue) => {
15+
process.env[ENABLE_ENV] = envValue;
16+
expect(isWebfetchEnabled()).toBe(true);
17+
},
18+
);
19+
20+
it.each(["0", "false", "no", "off", " OFF ", "\nNo\t"])(
21+
"returns false for falsy PI_WEBFETCH value %s",
22+
(envValue) => {
23+
process.env[ENABLE_ENV] = envValue;
24+
expect(isWebfetchEnabled()).toBe(false);
25+
},
26+
);
27+
28+
it("returns true for unknown PI_WEBFETCH values", () => {
29+
process.env[ENABLE_ENV] = "definitely";
30+
expect(isWebfetchEnabled()).toBe(true);
31+
});
32+
33+
it("is a no-op when PI_WEBFETCH is disabled", () => {
34+
process.env[ENABLE_ENV] = "0";
35+
const registerTool = vi.fn();
36+
webfetchExtension({ registerTool } as never);
37+
expect(registerTool).not.toHaveBeenCalled();
38+
});
39+
40+
it("registers the webfetch tool when PI_WEBFETCH is unset", () => {
41+
delete process.env[ENABLE_ENV];
42+
const registerTool = vi.fn();
43+
webfetchExtension({ registerTool } as never);
44+
expect(registerTool).toHaveBeenCalledTimes(1);
45+
});
46+
});

0 commit comments

Comments
 (0)