@posthog/agent 2.3.74 → 2.3.80
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/dist/agent.js +35 -5
- package/dist/agent.js.map +1 -1
- package/dist/posthog-api.js +1 -1
- package/dist/posthog-api.js.map +1 -1
- package/dist/server/agent-server.d.ts +1 -0
- package/dist/server/agent-server.js +36 -5
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +42 -6
- package/dist/server/bin.cjs.map +1 -1
- package/package.json +1 -1
- package/src/adapters/claude/claude-agent.ts +6 -2
- package/src/adapters/claude/permissions/permission-handlers.ts +35 -1
- package/src/adapters/claude/types.ts +1 -0
- package/src/server/agent-server.ts +1 -0
- package/src/server/bin.ts +12 -0
- package/src/server/types.ts +1 -0
package/package.json
CHANGED
|
@@ -817,7 +817,7 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
|
|
|
817
817
|
cwd,
|
|
818
818
|
mcpServers,
|
|
819
819
|
permissionMode,
|
|
820
|
-
canUseTool: this.createCanUseTool(sessionId),
|
|
820
|
+
canUseTool: this.createCanUseTool(sessionId, meta?.allowedDomains),
|
|
821
821
|
logger: this.logger,
|
|
822
822
|
systemPrompt,
|
|
823
823
|
userProvidedOptions: meta?.claudeCode?.options,
|
|
@@ -978,7 +978,10 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
|
|
|
978
978
|
return { sessionId, modes, models, configOptions };
|
|
979
979
|
}
|
|
980
980
|
|
|
981
|
-
private createCanUseTool(
|
|
981
|
+
private createCanUseTool(
|
|
982
|
+
sessionId: string,
|
|
983
|
+
allowedDomains?: string[],
|
|
984
|
+
): CanUseTool {
|
|
982
985
|
return async (toolName, toolInput, { suggestions, toolUseID, signal }) =>
|
|
983
986
|
canUseTool({
|
|
984
987
|
session: this.session,
|
|
@@ -993,6 +996,7 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
|
|
|
993
996
|
logger: this.logger,
|
|
994
997
|
updateConfigOption: (configId: string, value: string) =>
|
|
995
998
|
this.updateConfigOption(configId, value),
|
|
999
|
+
allowedDomains,
|
|
996
1000
|
});
|
|
997
1001
|
}
|
|
998
1002
|
|
|
@@ -49,6 +49,7 @@ interface ToolHandlerContext {
|
|
|
49
49
|
fileContentCache: { [key: string]: string };
|
|
50
50
|
logger: Logger;
|
|
51
51
|
updateConfigOption: (configId: string, value: string) => Promise<void>;
|
|
52
|
+
allowedDomains?: string[];
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
async function emitToolDenial(
|
|
@@ -422,10 +423,43 @@ function handlePlanFileException(
|
|
|
422
423
|
};
|
|
423
424
|
}
|
|
424
425
|
|
|
426
|
+
function extractDomainFromUrl(url: string): string | null {
|
|
427
|
+
try {
|
|
428
|
+
return new URL(url).hostname;
|
|
429
|
+
} catch {
|
|
430
|
+
return null;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
function isDomainAllowed(hostname: string, allowedDomains: string[]): boolean {
|
|
435
|
+
return allowedDomains.some((pattern) => {
|
|
436
|
+
if (pattern.startsWith("*.")) {
|
|
437
|
+
const suffix = pattern.slice(1); // ".example.com"
|
|
438
|
+
return hostname === pattern.slice(2) || hostname.endsWith(suffix);
|
|
439
|
+
}
|
|
440
|
+
return hostname === pattern;
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
|
|
425
444
|
export async function canUseTool(
|
|
426
445
|
context: ToolHandlerContext,
|
|
427
446
|
): Promise<ToolPermissionResult> {
|
|
428
|
-
const { toolName, toolInput, session } = context;
|
|
447
|
+
const { toolName, toolInput, session, allowedDomains } = context;
|
|
448
|
+
|
|
449
|
+
// Enforce domain allowlist for web tools
|
|
450
|
+
if (allowedDomains && allowedDomains.length > 0) {
|
|
451
|
+
if (toolName === "WebFetch" || toolName === "WebSearch") {
|
|
452
|
+
const url = toolInput.url as string | undefined;
|
|
453
|
+
if (url) {
|
|
454
|
+
const hostname = extractDomainFromUrl(url);
|
|
455
|
+
if (hostname && !isDomainAllowed(hostname, allowedDomains)) {
|
|
456
|
+
const message = `Domain "${hostname}" is not in the allowed list: ${allowedDomains.join(", ")}`;
|
|
457
|
+
await emitToolDenial(context, message);
|
|
458
|
+
return { behavior: "deny", message, interrupt: false };
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
429
463
|
|
|
430
464
|
if (isToolAllowedForMode(toolName, session.permissionMode)) {
|
|
431
465
|
return {
|
|
@@ -707,6 +707,7 @@ export class AgentServer {
|
|
|
707
707
|
sessionId: payload.run_id,
|
|
708
708
|
taskRunId: payload.run_id,
|
|
709
709
|
systemPrompt: this.buildSessionSystemPrompt(prUrl),
|
|
710
|
+
allowedDomains: this.config.allowedDomains,
|
|
710
711
|
...(this.config.claudeCode?.plugins?.length && {
|
|
711
712
|
claudeCode: {
|
|
712
713
|
options: {
|
package/src/server/bin.ts
CHANGED
|
@@ -79,6 +79,10 @@ program
|
|
|
79
79
|
"--claudeCodeConfig <json>",
|
|
80
80
|
"Claude Code config as JSON (systemPrompt, systemPromptAppend, plugins)",
|
|
81
81
|
)
|
|
82
|
+
.option(
|
|
83
|
+
"--allowedDomains <domains>",
|
|
84
|
+
"Comma-separated list of domains allowed for web tools (WebFetch, WebSearch)",
|
|
85
|
+
)
|
|
82
86
|
.action(async (options) => {
|
|
83
87
|
const envResult = envSchema.safeParse(process.env);
|
|
84
88
|
|
|
@@ -105,6 +109,13 @@ program
|
|
|
105
109
|
"--claudeCodeConfig",
|
|
106
110
|
);
|
|
107
111
|
|
|
112
|
+
const allowedDomains = options.allowedDomains
|
|
113
|
+
? options.allowedDomains
|
|
114
|
+
.split(",")
|
|
115
|
+
.map((d: string) => d.trim())
|
|
116
|
+
.filter(Boolean)
|
|
117
|
+
: undefined;
|
|
118
|
+
|
|
108
119
|
const server = new AgentServer({
|
|
109
120
|
port: parseInt(options.port, 10),
|
|
110
121
|
jwtPublicKey: env.JWT_PUBLIC_KEY,
|
|
@@ -118,6 +129,7 @@ program
|
|
|
118
129
|
mcpServers,
|
|
119
130
|
baseBranch: options.baseBranch,
|
|
120
131
|
claudeCode,
|
|
132
|
+
allowedDomains,
|
|
121
133
|
});
|
|
122
134
|
|
|
123
135
|
process.on("SIGINT", async () => {
|