Skip to content

Conversation

@rossmanko
Copy link
Contributor

@rossmanko rossmanko commented Jan 2, 2026

Summary by CodeRabbit

  • New Features

    • Local Sandbox tab in Settings with token management, connection status, and quick-start commands
    • HTTP request tool with sandboxed request execution and interactive outputs
    • Security Guardrails UI with per-guardrail toggles, severity labels, reset and save actions
    • Scope Exclusions setting to restrict operations against specified hosts/URLs
  • Improvements

    • Increased token limits for Pro/Team to 64k
    • Better save/error feedback and toasts for customization changes

✏️ Tip: You can customize this high-level summary in your review settings.

- Add scope_exclusions field to user_customization table
- Add Scope Exclusions editor UI in Agents settings tab
- Move Local Sandbox to separate settings tab
- Add scope exclusion checks to http_request and terminal tools
- Add system prompt warning for excluded targets
- Support wildcards (*.example.com) and CIDR notation
- Create reusable Textarea UI component
@vercel
Copy link

vercel bot commented Jan 2, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
hackerai Ready Ready Preview, Comment Jan 3, 2026 7:24pm

@coderabbitai
Copy link

coderabbitai bot commented Jan 2, 2026

📝 Walkthrough

Walkthrough

This PR adds scope exclusions and a Guardrails system, a sandboxed HTTP request tool, Local Sandbox UI, and updates tools/context plumbing and user customization to persist scope_exclusions and guardrails_config; it also removes regenerationCount from message flows and adjusts system-prompt/type locations.

Changes

Cohort / File(s) Summary
Scope Exclusions & Guardrails Core
lib/ai/tools/utils/scope-exclusions.ts, lib/ai/tools/utils/guardrails.ts
Add parsing/matching for scope exclusions (wildcard/CIDR), guardrail definitions, UI conversion helpers, effective-merge logic, and command-checking that can WARN/BLOCK.
HTTP Request Tool & Integration
lib/ai/tools/http-request.ts, app/components/tools/HttpRequestToolHandler.tsx
New createHttpRequest tool that runs curl in sandbox with validation, streaming, truncation (500 KB), metadata; plus UI handler to render tool output and sidebar integration.
Tool Initialization & Context
lib/ai/tools/index.ts, types/agent.ts, lib/ai/tools/run-terminal-cmd.ts
createTools signature changed to accept scopeExclusions and guardrailsConfig; ToolContext extended; run-terminal-cmd performs guardrail and scope-exclusion pre-checks and early-blocks execution.
Local Sandbox UI
app/components/LocalSandboxTab.tsx, app/components/SandboxSelector.tsx, app/components/SettingsDialog.tsx
Adds LocalSandboxTab UI (token management, quick-start commands), extends LocalConnection with lastSeen, and wires Local Sandbox tab into SettingsDialog.
AgentsTab: Guardrails & Exclusions UI
app/components/AgentsTab.tsx
Replace token workflow with scope exclusions editor and Security Guardrails UI (per-guardrail toggles, severity labels, save/reset, change tracking); persists via userCustomization hooks.
User Customization Schema & Backend
convex/schema.ts, convex/userCustomization.ts
Add scope_exclusions and guardrails_config fields, enforce 5000-byte limit, persist/trim values, and surface them in get/save APIs.
Message/Regeneration Simplification
convex/messages.ts, lib/db/actions.ts, lib/api/chat-handler.ts, app/hooks/useChatHandlers.ts
Remove regenerationCount from payloads/returns and related logic; adjust handlers and saveMessage usages accordingly.
System Prompt & Types Reorg
lib/system-prompt.ts, lib/system-prompt/personality.ts, lib/system-prompt/bio.ts, types/user.ts, types/index.ts
Inject scope exclusions into system prompts for agents; move/add UserCustomization/PersonalityType into types/user.ts and re-export; update imports.
Sidebar & UI Utilities
lib/utils/sidebar-utils.ts, app/components/MessagePartHandler.tsx, components/ui/textarea.tsx
Add handling for tool-http_request in sidebar extraction and MessagePartHandler; add new Textarea component used by UI.
Misc: Providers, Tokens, Docs
lib/ai/providers.ts, lib/token-utils.ts, lib/ai/tools/update-memory.ts
Change agent-vision-model provider mapping; raise MAX_TOKENS_PRO_AND_TEAM to 64000 and tweak truncation text; add doc note about task-specific authorizations.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Frontend as Frontend (AgentsTab/Chat)
    participant API as Chat Handler
    participant ToolMgr as Tools Initialization
    participant Guardrails as Guardrails Engine
    participant Scope as Scope Exclusions
    participant Sandbox as Sandbox Runner

    User->>Frontend: Triggers agent action / enters command
    Frontend->>API: Request (uses userCustomization)
    API->>ToolMgr: createTools(scopeExclusions, guardrailsConfig)
    ToolMgr-->>API: Tools initialized with context
    Frontend->>API: Execute command via run-terminal-cmd
    API->>Guardrails: checkCommandGuardrails(command, guardrails)
    Guardrails-->>API: result (ALLOW / WARN / BLOCK)
    alt BLOCK (CRITICAL)
        API-->>Frontend: Return block error (exitCode 1, reason)
        Frontend-->>User: Display guardrail block
    else ALLOW or WARN
        API->>Scope: checkCommandScopeExclusion(command, exclusions)
        Scope-->>API: matched exclusion or null
        alt Exclusion matched
            API-->>Frontend: Return exclusion error (exitCode 1, details)
            Frontend-->>User: Display exclusion block
        else Allowed
            API->>Sandbox: Run command (curl) with streaming
            Sandbox-->>API: Streamed output + exit code
            API-->>Frontend: Append tool result message
            Frontend-->>User: Display streaming output
        end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • refactor: update sandbox template #91 — Modifies the tools subsystem and replaces/removes the Python tool in lib/ai/tools/index.ts, directly overlapping the HTTP-request/tool changes.
  • Daily branch 2025 09 05 #21 — Changes user customization and system-prompt wiring; overlaps schema and prompt plumbing for scope_exclusions/guardrails_config.
  • Daily branch 2025 11 17 #103 — Touches lib/ai/tools/run-terminal-cmd.ts (execution/time limits) and is related to the pre-execution guardrail/scope checks added here.

Poem

🐰 Hop, I nibble at logs and strings,

I guard the hops of risky things.
Exclusions drawn, guardrails set—no fright,
Curl runs safe within the sandboxed night,
I celebrate the code that keeps us light.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'Feat/agent v2' is vague and does not convey meaningful information about the changeset; it uses a generic versioning label without describing the actual features or changes introduced. Replace with a descriptive title that summarizes the main feature (e.g., 'Add HTTP request tool, guardrails system, and local sandbox management' or 'Introduce security guardrails and scope exclusions for agent tools').
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1aa851f and c426bca.

📒 Files selected for processing (2)
  • lib/ai/providers.ts
  • lib/ai/tools/todo-write.ts
✅ Files skipped from review due to trivial changes (1)
  • lib/ai/tools/todo-write.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-06T13:31:08.519Z
Learnt from: RostyslavManko
Repo: hackerai-tech/hackerai PR: 21
File: app/api/chat/route.ts:121-128
Timestamp: 2025-09-06T13:31:08.519Z
Learning: The vision model (NEXT_PUBLIC_VISION_MODEL) used for processing media files also supports tool calling, so overriding to vision-model in Agent mode with media files does not break tool functionality.

Applied to files:

  • lib/ai/providers.ts
🔇 Additional comments (1)
lib/ai/providers.ts (1)

14-14: Model change is valid. The x-ai/grok-4.1-fast model fully supports vision and multimodal inputs (JPG/PNG), matching the capabilities of the previous Gemini Flash model. No breaking changes for media file processing.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (7)
components/ui/textarea.tsx (1)

1-1: Consider removing explicit React import with modern JSX transform.

With React 17+ and the new JSX transform, explicitly importing React is no longer necessary for JSX syntax. The import can be safely removed unless you're using other React APIs directly.

🔎 Proposed refactor
-import * as React from "react";
-
 import { cn } from "@/lib/utils";
+import type { ComponentProps } from "react";

Then update the component signature:

-function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
+function Textarea({ className, ...props }: ComponentProps<"textarea">) {
types/agent.ts (1)

40-40: LGTM! Field addition extends tool context appropriately.

The scopeExclusions property is correctly added as an optional string to the ToolContext interface. The string type is appropriate for serialized exclusion data that gets parsed by utilities in lib/ai/tools/utils/scope-exclusions.ts.

Consider adding a JSDoc comment to document the expected format and usage:

📝 Optional documentation enhancement
  mode: ChatMode;
  isE2BSandbox: IsE2BSandboxFn;
+  /** Serialized scope exclusions to restrict tool operations (e.g., blocked commands or URLs) */
  scopeExclusions?: string;
}
app/components/tools/HttpRequestToolHandler.tsx (1)

25-46: Validate structure before type assertions.

The code uses type assertions (as) to cast input and output without runtime validation. If the actual structure differs from the expected shape, this could lead to silent failures or incorrect behavior.

Consider adding runtime validation or using a type guard to ensure the structure matches expectations before accessing properties. Alternatively, rely on optional chaining throughout (which you already do in most places) and add early returns if critical properties are missing.

🔎 Example validation approach
  const httpInput = input as {
    url: string;
    method?: string;
    // ... rest of type
  };
  
+ // Validate critical properties
+ if (!httpInput?.url) {
+   console.warn('HttpRequestToolHandler: Missing required url in input');
+   return null;
+ }

  const httpOutput = output as {
    success: boolean;
    output: string;
    // ... rest of type
  };
app/components/LocalSandboxTab.tsx (1)

20-28: Consider documenting the PRODUCTION_CONVEX_URL constant.

The hardcoded production URL creates a dependency on the @hackerai/local@latest package configuration. Consider adding a comment explaining that this must stay in sync with the package's expected backend URL, or extracting it to a shared configuration file if it's used elsewhere.

app/components/AgentsTab.tsx (1)

44-54: Consider combining the two useEffects for clarity.

The two useEffect hooks could be consolidated since they share the same dependency (userCustomization?.scope_exclusions). However, this separation is acceptable as they serve distinct purposes: one initializes state, the other tracks changes.

🔎 Optional consolidated approach
-  // Load initial scope exclusions from user customization
-  useEffect(() => {
-    if (userCustomization?.scope_exclusions !== undefined) {
-      setScopeExclusions(userCustomization.scope_exclusions || "");
-    }
-  }, [userCustomization?.scope_exclusions]);
-
-  // Track changes
-  useEffect(() => {
-    const original = userCustomization?.scope_exclusions || "";
-    setHasChanges(scopeExclusions !== original);
-  }, [scopeExclusions, userCustomization?.scope_exclusions]);
+  // Load initial scope exclusions and track changes
+  const originalExclusions = userCustomization?.scope_exclusions || "";
+  
+  useEffect(() => {
+    if (userCustomization?.scope_exclusions !== undefined) {
+      setScopeExclusions(userCustomization.scope_exclusions || "");
+    }
+  }, [userCustomization?.scope_exclusions]);
+
+  const hasChanges = scopeExclusions !== originalExclusions;
lib/ai/tools/utils/scope-exclusions.ts (1)

53-63: Potential integer overflow with bitwise operations on 32-bit numbers.

JavaScript bitwise operators convert operands to 32-bit signed integers. For IP addresses starting with octets ≥128, the calculation produces negative numbers due to sign bit interpretation. While the comparison (ipNum & maskNum) === (rangeNum & maskNum) still works correctly because both sides undergo the same conversion, this is subtle behavior worth documenting.

🔎 Optional: Add unsigned conversion for clarity
   const ipNum =
-    (ipParts[0] << 24) | (ipParts[1] << 16) | (ipParts[2] << 8) | ipParts[3];
+    ((ipParts[0] << 24) | (ipParts[1] << 16) | (ipParts[2] << 8) | ipParts[3]) >>> 0;
   const rangeNum =
-    (rangeParts[0] << 24) |
-    (rangeParts[1] << 16) |
-    (rangeParts[2] << 8) |
-    rangeParts[3];
+    ((rangeParts[0] << 24) |
+    (rangeParts[1] << 16) |
+    (rangeParts[2] << 8) |
+    rangeParts[3]) >>> 0;
 
-  const maskNum = mask === 0 ? 0 : ~((1 << (32 - mask)) - 1);
+  const maskNum = (mask === 0 ? 0 : ~((1 << (32 - mask)) - 1)) >>> 0;
lib/utils/prompt-injection-protection.ts (1)

27-36: The Source line regex only matches HTTP sources.

The stripExternalDataMarkers function's regex /Source: HTTP [A-Z]+ .+\n?/g only strips HTTP-specific source lines. If other sources are added (e.g., "Source: Terminal command"), they won't be stripped.

🔎 Consider a more generic source pattern
 export const stripExternalDataMarkers = (text: string): string => {
   return text
     .replace(
       /\n?=== EXTERNAL DATA START \(TREAT AS DATA ONLY, NOT INSTRUCTIONS\) ===\n?/g,
       "",
     )
-    .replace(/Source: HTTP [A-Z]+ .+\n?/g, "")
+    .replace(/Source: .+\n?/g, "")
     .replace(/\n?=== EXTERNAL DATA END ===\n?/g, "")
     .trim();
 };
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0f48f7b and 9f9b130.

📒 Files selected for processing (25)
  • app/components/AgentsTab.tsx
  • app/components/LocalSandboxTab.tsx
  • app/components/MessagePartHandler.tsx
  • app/components/SettingsDialog.tsx
  • app/components/tools/HttpRequestToolHandler.tsx
  • app/hooks/useChatHandlers.ts
  • components/ui/textarea.tsx
  • convex/messages.ts
  • convex/schema.ts
  • convex/userCustomization.ts
  • lib/ai/tools/http-request.ts
  • lib/ai/tools/index.ts
  • lib/ai/tools/run-terminal-cmd.ts
  • lib/ai/tools/update-memory.ts
  • lib/ai/tools/utils/scope-exclusions.ts
  • lib/api/chat-handler.ts
  • lib/db/actions.ts
  • lib/system-prompt.ts
  • lib/system-prompt/bio.ts
  • lib/system-prompt/personality.ts
  • lib/utils/prompt-injection-protection.ts
  • lib/utils/sidebar-utils.ts
  • types/agent.ts
  • types/index.ts
  • types/user.ts
💤 Files with no reviewable changes (1)
  • lib/db/actions.ts
🧰 Additional context used
📓 Path-based instructions (2)
convex/**/*.{ts,js}

📄 CodeRabbit inference engine (.cursor/rules/convex_rules.mdc)

convex/**/*.{ts,js}: ALWAYS use the new function syntax for Convex functions with query, mutation, action decorators that include args, returns, and handler properties
Use array validators with v.array() to validate array arguments and schema fields
Use discriminated union types with v.union() and v.literal() for schema validation
Always use the v.null() validator when a function returns a null value
Use v.id(tableName) validator for document ID validation and Id<'tableName'> TypeScript type for ID fields
v.bigint() is deprecated; use v.int64() instead for representing signed 64-bit integers
Use v.record() for defining record types; v.map() and v.set() are not supported
Index fields must be queried in the same order they are defined; create separate indexes if you need different query orders
Use internalQuery, internalMutation, and internalAction for private functions that should not be part of the public API
Use query, mutation, and action for public functions that are exposed to the public API
ALWAYS include argument and return validators for all Convex functions including query, internalQuery, mutation, internalMutation, action, and internalAction
Functions that don't return anything should include returns: v.null() as the output validator
Functions implicitly return null in JavaScript if they have no return statement
Use ctx.runQuery to call a query from a query, mutation, or action
Use ctx.runMutation to call a mutation from a mutation or action
Use ctx.runAction to call an action from an action
Only call an action from another action if you need to cross runtimes (e.g., V8 to Node); otherwise extract shared code into a helper async function
Use as few calls from actions to queries and mutations as possible to avoid race conditions from split transaction logic
Pass a FunctionReference to ctx.runQuery, ctx.runMutation, or ctx.runAction; do not pass the callee function directly
When usi...

Files:

  • convex/schema.ts
  • convex/messages.ts
  • convex/userCustomization.ts
convex/schema.ts

📄 CodeRabbit inference engine (.cursor/rules/convex_rules.mdc)

convex/schema.ts: Always define schema in convex/schema.ts using defineSchema and defineTable imported from convex/server
System fields _creationTime (v.number()) and _id (v.id(tableName)) are automatically added to all documents; do not redefine them
Always include all index fields in the index name; for example, an index on ['field1', 'field2'] should be named 'by_field1_and_field2'

Files:

  • convex/schema.ts
🧠 Learnings (14)
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/schema.ts : System fields `_creationTime` (v.number()) and `_id` (v.id(tableName)) are automatically added to all documents; do not redefine them

Applied to files:

  • convex/schema.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Always add `'use node';` to the top of files containing actions that use Node.js built-in modules

Applied to files:

  • types/index.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Use `query`, `mutation`, and `action` for public functions that are exposed to the public API

Applied to files:

  • app/components/AgentsTab.tsx
  • convex/messages.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Use `ctx.runQuery` to call a query from a query, mutation, or action

Applied to files:

  • app/components/AgentsTab.tsx
  • convex/messages.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Use as few calls from actions to queries and mutations as possible to avoid race conditions from split transaction logic

Applied to files:

  • app/components/AgentsTab.tsx
  • convex/messages.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Use `internalQuery`, `internalMutation`, and `internalAction` for private functions that should not be part of the public API

Applied to files:

  • app/components/AgentsTab.tsx
  • convex/messages.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Thoughtfully organize files with public query, mutation, or action functions within the `convex/` directory for file-based routing

Applied to files:

  • app/components/AgentsTab.tsx
  • convex/messages.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Use `ctx.runMutation` to call a mutation from a mutation or action

Applied to files:

  • app/components/AgentsTab.tsx
📚 Learning: 2025-11-28T01:16:26.536Z
Learnt from: fkesheh
Repo: hackerai-tech/hackerai PR: 114
File: lib/ai/tools/utils/convex-sandbox.ts:95-145
Timestamp: 2025-11-28T01:16:26.536Z
Learning: In the local sandbox architecture (lib/ai/tools/utils/convex-sandbox.ts), background command execution semantics are handled by the local sandbox client (packages/local/src/index.ts), not by the ConvexSandbox class. When background: true, the local client immediately submits a result with empty output and PID after spawning the process, causing waitForResult() to resolve immediately and maintaining E2B-compatible non-blocking behavior.

Applied to files:

  • app/components/LocalSandboxTab.tsx
  • lib/ai/tools/run-terminal-cmd.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : ALWAYS include argument and return validators for all Convex functions including `query`, `internalQuery`, `mutation`, `internalMutation`, `action`, and `internalAction`

Applied to files:

  • convex/messages.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Function references for internal functions use the `internal` object from `convex/_generated/api.ts` with file-based routing (e.g., `internal.example.g` for function `g` in `convex/example.ts`)

Applied to files:

  • convex/messages.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : When using `ctx.runQuery`, `ctx.runMutation`, or `ctx.runAction` to call a function in the same file, add a type annotation on the return value to work around TypeScript circularity limitations

Applied to files:

  • convex/messages.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/schema.ts : Always define schema in `convex/schema.ts` using `defineSchema` and `defineTable` imported from `convex/server`

Applied to files:

  • convex/messages.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Use the helper TypeScript type `Id<'tableName'>` imported from `_generated/dataModel` to type document IDs for strict type checking

Applied to files:

  • convex/messages.ts
🧬 Code graph analysis (9)
app/components/tools/HttpRequestToolHandler.tsx (3)
types/chat.ts (3)
  • ChatStatus (81-81)
  • SidebarTerminal (26-33)
  • isSidebarTerminal (50-54)
app/contexts/GlobalState.tsx (1)
  • useGlobalState (752-758)
lib/utils/prompt-injection-protection.ts (1)
  • stripExternalDataMarkers (27-36)
components/ui/textarea.tsx (1)
lib/utils.ts (1)
  • cn (23-25)
app/components/MessagePartHandler.tsx (1)
app/components/tools/HttpRequestToolHandler.tsx (1)
  • HttpRequestToolHandler (16-179)
lib/utils/prompt-injection-protection.ts (1)
e2e/page-objects/ChatComponent.ts (1)
  • messages (28-32)
app/components/LocalSandboxTab.tsx (2)
__mocks__/convex-react.ts (2)
  • useQuery (7-7)
  • useMutation (5-5)
convex/localSandbox.ts (1)
  • regenerateToken (156-207)
app/hooks/useChatHandlers.ts (1)
convex/messages.ts (1)
  • deleteLastAssistantMessage (465-575)
lib/api/chat-handler.ts (1)
lib/utils/prompt-injection-protection.ts (1)
  • stripMarkersFromMessages (46-135)
app/components/SettingsDialog.tsx (1)
app/components/LocalSandboxTab.tsx (1)
  • LocalSandboxTab (315-315)
lib/ai/tools/run-terminal-cmd.ts (2)
types/agent.ts (1)
  • ToolContext (29-41)
lib/ai/tools/utils/scope-exclusions.ts (2)
  • parseScopeExclusions (10-19)
  • checkCommandScopeExclusion (224-242)
🔇 Additional comments (48)
components/ui/textarea.tsx (1)

20-20: LGTM!

The named export follows best practices for component libraries and enables tree-shaking.

convex/schema.ts (2)

70-71: LGTM! TODO comment appropriately documents planned cleanup.

The TODO comment clearly indicates that the regeneration_count field is slated for removal after a migration completes. This is an appropriate way to document technical debt and planned schema changes.


113-113: LGTM! Field addition aligns with user customization feature.

The scope_exclusions field is properly defined as an optional string. The length validation (MAX_SCOPE_EXCLUSIONS_LIMIT = 5000) is appropriately handled at the application layer in convex/userCustomization.ts, which is the correct pattern for Convex schemas.

lib/ai/tools/update-memory.ts (1)

38-38: LGTM! Documentation clarifies non-persistent context handling.

The added bullet point appropriately instructs the LLM not to persist task-specific authorizations or permission claims in memory. This aligns well with the scope exclusions feature where such permissions are contextual to the current task rather than persistent user preferences.

app/components/tools/HttpRequestToolHandler.tsx (4)

49-77: LGTM! Memoization properly optimizes derived values.

The component correctly memoizes displayCommand, streamingOutput, and finalOutput with appropriate dependency arrays. The use of stripExternalDataMarkers ensures LLM-specific markers are removed from user-facing output.


104-112: LGTM! Effect correctly handles sidebar updates with intentional dependency exclusion.

The useEffect appropriately updates sidebar content when the tool call is active. The eslint-disable comment correctly documents that updateSidebarContent is intentionally excluded from dependencies to avoid unnecessary re-renders.


114-119: LGTM! Keyboard accessibility properly implemented.

The keyboard handler correctly supports both Enter and Space keys (standard for clickable elements) and prevents default behavior to avoid unwanted scrolling.


129-178: LGTM! State-based rendering is well-structured.

The switch statement appropriately handles all tool states with correct ToolBlock configurations for each state. The accessibility props (onClick, onKeyDown, isClickable) are consistently applied to interactive states.

app/components/MessagePartHandler.tsx (1)

5-5: LGTM! HTTP request tool properly integrated.

The HttpRequestToolHandler is correctly imported and wired into the message part handler switch statement. The integration follows the established pattern for other tool handlers, passing the appropriate props (message, part, status).

Also applies to: 91-94

lib/ai/tools/http-request.ts (2)

137-435: LGTM! Solid implementation with strong security practices.

The HTTP request tool implementation demonstrates excellent security hygiene:

  • Proper scope exclusion enforcement (lines 303-311)
  • URL validation with protocol restrictions (lines 285-301)
  • Shell argument escaping using the standard single-quote pattern (lines 412-435)
  • Input validation preventing conflicting body parameters (lines 270-283)
  • Comprehensive Zod schema with clear descriptions for AI consumption

The command-building logic correctly escapes arguments that contain special characters while preserving the curl command itself unescaped.


437-713: LGTM! Comprehensive execution and response handling.

The sandbox execution logic is well-structured:

  • Proper health check with automatic sandbox recreation (lines 441-450)
  • Abort signal handling prevents resource leaks (lines 472-492)
  • Multi-layered security: response truncation (lines 574-580), token limits (line 660), and prompt injection protection (lines 662-666)
  • Graceful error handling throughout the execution chain
  • Security indicator detection adds valuable metadata (lines 614-655)

The implementation correctly streams terminal output while maintaining a complete result for the final response.

lib/system-prompt/bio.ts (1)

1-1: LGTM! Import source updated to use centralized types.

The change aligns with the PR's type system refactoring, moving UserCustomization from a local module to the central @/types barrel export. This improves maintainability and type consistency across the codebase.

types/index.ts (1)

4-4: LGTM! User types added to barrel export.

The addition extends the central type exports to include user-related types (UserCustomization, PersonalityType), supporting the type system refactoring across the PR. This enables importing these types via @/types throughout the codebase.

lib/utils/sidebar-utils.ts (1)

137-163: LGTM! HTTP request handling integrated consistently.

The new HTTP request tool handling follows the established pattern for terminal commands and Python execution:

  • Constructs a readable command representation (${method} ${url})
  • Leverages the existing terminal streaming infrastructure (lines 143-145)
  • Properly extracts output from multiple sources with appropriate fallbacks (lines 147-153)
  • Correctly sets isBackground: false since HTTP requests are foreground operations

The implementation ensures HTTP tool results appear in the sidebar with the same user experience as other command executions.

app/hooks/useChatHandlers.ts (1)

307-310: LGTM! Correctly updated for regeneration count removal.

The change properly aligns with the backend mutation update where deleteLastAssistantMessage now returns null instead of regenerationCount. The removal of regeneration count tracking throughout the system is reflected correctly here—the value is no longer captured or used.

This is consistent with the broader PR changes that eliminate regeneration count tracking from the message persistence layer.

app/components/SettingsDialog.tsx (3)

12-12: LGTM!

The new imports for the Server icon and LocalSandboxTab component are properly structured.

Also applies to: 23-23


46-60: LGTM!

The conditional tab logic correctly includes the Local Sandbox tab for Pro, Ultra, and Team users. The nested ternary is readable and follows the existing pattern in the codebase.


166-167: LGTM!

The LocalSandboxTab rendering follows the established pattern for tab content rendering.

lib/system-prompt/personality.ts (1)

1-1: LGTM!

Good refactoring to centralize the PersonalityType definition in the types module. This improves maintainability and provides a single source of truth for the type.

app/components/LocalSandboxTab.tsx (4)

51-89: LGTM!

The CommandBlock component provides clear visual distinction for dangerous mode commands with appropriate warning styling and messaging.


91-99: LGTM!

State management and Convex query setup follow React and Convex best practices correctly.


100-135: LGTM!

The token management handlers provide appropriate error handling and user feedback via toast notifications. The regenerate flow correctly resets the token visibility state.


257-298: LGTM!

The Quick Start command blocks properly handle token visibility:

  • Display shows <token> placeholder when token is hidden
  • Copy functionality always uses the actual token (or "YOUR_TOKEN" if not generated)

This provides good UX by not exposing the token visually while still allowing functional copying.

lib/system-prompt.ts (3)

2-3: LGTM!

The import refactoring centralizes UserCustomization in the types module, improving maintainability and consistency across the codebase.


241-253: LGTM!

The getScopeExclusionsSection helper properly validates input and generates clear instructions for the AI to enforce scope restrictions on HTTP requests and terminal commands.


306-311: LGTM!

The scope exclusions section is correctly integrated into the agent mode prompt construction, with appropriate null checks and conditional logic.

types/user.ts (1)

1-12: LGTM!

The type definitions are well-structured with appropriate use of readonly modifiers for immutability. The UserCustomization interface provides a clean contract for user personalization data, and the PersonalityType union ensures type safety for personality options.

lib/ai/tools/run-terminal-cmd.ts (3)

14-17: LGTM!

Clean import of scope exclusion utilities. The named imports align with the exported functions from scope-exclusions.ts.


23-30: LGTM!

Good defensive handling with scopeExclusions || "" fallback when parsing. The exclusions list is computed once at tool creation time rather than per-execution, which is efficient.


113-126: LGTM!

The scope exclusion check is well-placed before any sandbox interaction, preventing blocked commands from consuming resources. The error message is informative and includes both the matched target and exclusion pattern for debugging.

app/components/AgentsTab.tsx (2)

70-92: LGTM!

The save handler properly manages loading state and error handling. Using ConvexError for structured error extraction is appropriate for Convex mutations.


145-196: LGTM!

Well-structured UI with appropriate accessibility attributes (aria-label), clear instructions, and proper button state management. The placeholder examples effectively communicate the expected input format.

lib/ai/tools/index.ts (3)

44-44: LGTM!

The scopeExclusions parameter is appropriately optional and positioned at the end of the parameter list to maintain backwards compatibility.


83-84: LGTM!

The scopeExclusions is correctly threaded into the ToolContext, making it available to all tools that need to perform scope validation.


94-94: Verify that http_request tool should be available in "ask" mode.

The http_request tool is added to allTools but line 104-112 shows that "ask" mode only includes update_memory and web tools. Confirm this is intentional—HTTP requests from "ask" mode are blocked, which seems correct for a non-agent mode.

lib/api/chat-handler.ts (3)

222-223: LGTM!

Correctly passes scope_exclusions from user customization to the tool context, enabling scope-based command filtering.


300-303: LGTM!

Good approach to strip external data markers from older tool outputs to reduce token consumption while maintaining protection for the current step's results.


338-342: LGTM!

Consistent application of stripMarkersFromMessages across all return paths in prepareStep ensures token savings regardless of the code path taken.

Also applies to: 356-361, 376-378

lib/ai/tools/utils/scope-exclusions.ts (3)

152-218: Consider additional edge cases in target extraction.

The regex patterns are comprehensive for common tools. A few observations:

  1. The URL regex https?:\/\/([^\s/:]+) correctly captures the hostname
  2. Tool patterns handle common pentesting tools well
  3. The deduplication via new Set() is efficient

One edge case: commands with targets in environment variables (e.g., nmap $TARGET) won't be caught, but this is acceptable as the actual value isn't known at parse time.


10-19: LGTM!

Clean parsing logic that handles both newline and comma separators. The lowercase normalization ensures case-insensitive matching.


82-114: LGTM!

The matching logic correctly handles direct matches, wildcard patterns, and CIDR ranges in a clear priority order.

lib/utils/prompt-injection-protection.ts (2)

46-135: LGTM!

Well-designed function that correctly preserves markers on the last tool message (for current step protection) while stripping from older messages (for token savings). The handling of three different content structures ensures compatibility with various AI SDK message formats.


10-21: LGTM!

Clear marker format with explicit instructions to treat content as data. Including the source in the wrapped block aids debugging.

convex/messages.ts (2)

1-6: LGTM!

The imports are correctly organized. The internalMutation import aligns with Convex best practices for internal functions. Based on coding guidelines, this follows the pattern of using appropriate function decorators.


484-484: No breaking change - caller does not use the return value.

The mutation deleteLastAssistantMessage is called in app/hooks/useChatHandlers.ts without capturing or using the return value. The caller simply awaits the mutation without destructuring any result, so the change from v.object({ regenerationCount: v.number() }) to v.null() will not cause any failures.

Likely an incorrect or invalid review comment.

convex/userCustomization.ts (3)

131-131: LGTM!

The scope_exclusions field is correctly added to the return type and properly propagated from the database query result.

Also applies to: 158-158


185-185: LGTM!

The scope_exclusions field is correctly added to the backend variant's return type, maintaining consistency with the standard query function.

Also applies to: 209-209


16-16: LGTM. The scope_exclusions field implementation is correct and the database schema has been properly updated.

The implementation correctly follows Convex patterns with proper argument validators (line 16), consistent validation logic with other fields (lines 62–70), appropriate trimming and undefined fallback (line 90), and correct return types/values in both queries (lines 131, 158, 185, 209). The schema in convex/schema.ts line 113 includes scope_exclusions: v.optional(v.string()).

- Add guardrails.ts with 9 dangerous command patterns (rm -rf, fork bombs, disk wipe, curl/wget pipe to shell, reverse shells, env exfil, sudoers edit)
- Add guardrails_config field to user_customization schema
- Integrate guardrails check into run-terminal-cmd.ts before command execution
- Add Security Guardrails UI section in AgentsTab with toggle switches
- Users can enable/disable individual guardrails and save preferences
- All guardrails enabled by default with CRITICAL severity (blocking)
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (6)
convex/userCustomization.ts (1)

16-17: LGTM on new field additions and validation.

The new scope_exclusions and guardrails_config fields are properly added with correct Convex validators (v.optional(v.string())). The MAX_SCOPE_EXCLUSIONS_LIMIT constant appropriately limits both fields.

Minor observation: Consider renaming MAX_SCOPE_EXCLUSIONS_LIMIT to something more generic like MAX_TEXT_CONFIG_LIMIT since it's used for both scope exclusions and guardrails config, improving code clarity.

Also applies to: 30-30

convex/schema.ts (1)

70-71: Migration tracking noted.

The TODO comment for regeneration_count removal after migration is helpful. Consider creating a tracking issue to ensure this cleanup happens.

Would you like me to open an issue to track the removal of regeneration_count after migration completes?

app/components/AgentsTab.tsx (1)

88-94: Variable shadowing: hasChanges shadows state setter variable name.

At line 89, const hasChanges shadows the state variable hasChanges from line 49. While this works due to scoping, it can cause confusion. Consider renaming the local variable:

   useEffect(() => {
-    const hasChanges = hasGuardrailChanges(
+    const guardrailsChanged = hasGuardrailChanges(
       guardrails,
       userCustomization?.guardrails_config,
     );
-    setGuardrailChanges(hasChanges);
+    setGuardrailChanges(guardrailsChanged);
   }, [guardrails, userCustomization?.guardrails_config]);
lib/ai/tools/utils/guardrails.ts (1)

56-56: Severity type mismatch between enum and UI interface.

GuardrailConfigUI.severity (line 56) accepts "critical" | "high" | "medium" | "low" but the Severity enum (lines 18-24) also includes INFO. Since all DEFAULT_GUARDRAILS currently use Severity.CRITICAL, this isn't a runtime issue, but the type inconsistency could cause problems if lower-severity guardrails are added later.

🔎 Suggested fix to align types
 export interface GuardrailConfigUI {
   id: string;
   name: string;
   description: string;
   enabled: boolean;
-  severity: "critical" | "high" | "medium" | "low";
+  severity: "critical" | "high" | "medium" | "low" | "info";
 }

Also applies to: 18-24

lib/system-prompt.ts (2)

232-237: Consider specifying the expected format for scope exclusions.

The prompt instructs the AI to verify targets against "domains, IPs, networks, or subdomains" but doesn't specify the expected format. Consider adding examples to clarify:

  • Domain format: example.com, *.example.com
  • IP format: 192.168.1.1
  • Network format: 192.168.1.0/24
  • Subdomain matching rules

This will help ensure consistent interpretation by both the AI and users configuring scope exclusions.

🔎 Proposed enhancement with format examples
  return `<scope_restrictions>
 CRITICAL: Stay in scope. NEVER attack, scan, probe, or make requests to the following targets:
 ${scopeExclusions}
 
+Expected formats:
+- Domains: example.com (exact), *.example.com (wildcard subdomain)
+- IP addresses: 192.168.1.1 (single IP)
+- Networks: 192.168.1.0/24 (CIDR notation)
+
 Before making any HTTP request or running any terminal command that interacts with external targets, verify the target is NOT in this exclusion list. If a target matches any of the above exclusions (domains, IPs, networks, or subdomains), refuse the action and inform the user that the target is out of scope.
 </scope_restrictions>`;

291-296: Conditional scope exclusions integration looks good.

The implementation correctly:

  • Restricts scope exclusions to agent mode where security boundaries are critical
  • Uses optional chaining to safely access the field
  • Delegates formatting to the dedicated helper function

For maximum prominence, consider placing the scope restrictions section immediately after the base prompt and before other instructions. Security boundaries might have higher priority than bio and memory context. However, the current placement is acceptable and maintains logical flow.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9f9b130 and ee6d947.

📒 Files selected for processing (10)
  • app/components/AgentsTab.tsx
  • convex/schema.ts
  • convex/userCustomization.ts
  • lib/ai/tools/index.ts
  • lib/ai/tools/run-terminal-cmd.ts
  • lib/ai/tools/utils/guardrails.ts
  • lib/api/chat-handler.ts
  • lib/system-prompt.ts
  • lib/token-utils.ts
  • types/agent.ts
✅ Files skipped from review due to trivial changes (1)
  • lib/token-utils.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • types/agent.ts
  • lib/api/chat-handler.ts
🧰 Additional context used
📓 Path-based instructions (2)
convex/**/*.{ts,js}

📄 CodeRabbit inference engine (.cursor/rules/convex_rules.mdc)

convex/**/*.{ts,js}: ALWAYS use the new function syntax for Convex functions with query, mutation, action decorators that include args, returns, and handler properties
Use array validators with v.array() to validate array arguments and schema fields
Use discriminated union types with v.union() and v.literal() for schema validation
Always use the v.null() validator when a function returns a null value
Use v.id(tableName) validator for document ID validation and Id<'tableName'> TypeScript type for ID fields
v.bigint() is deprecated; use v.int64() instead for representing signed 64-bit integers
Use v.record() for defining record types; v.map() and v.set() are not supported
Index fields must be queried in the same order they are defined; create separate indexes if you need different query orders
Use internalQuery, internalMutation, and internalAction for private functions that should not be part of the public API
Use query, mutation, and action for public functions that are exposed to the public API
ALWAYS include argument and return validators for all Convex functions including query, internalQuery, mutation, internalMutation, action, and internalAction
Functions that don't return anything should include returns: v.null() as the output validator
Functions implicitly return null in JavaScript if they have no return statement
Use ctx.runQuery to call a query from a query, mutation, or action
Use ctx.runMutation to call a mutation from a mutation or action
Use ctx.runAction to call an action from an action
Only call an action from another action if you need to cross runtimes (e.g., V8 to Node); otherwise extract shared code into a helper async function
Use as few calls from actions to queries and mutations as possible to avoid race conditions from split transaction logic
Pass a FunctionReference to ctx.runQuery, ctx.runMutation, or ctx.runAction; do not pass the callee function directly
When usi...

Files:

  • convex/schema.ts
  • convex/userCustomization.ts
convex/schema.ts

📄 CodeRabbit inference engine (.cursor/rules/convex_rules.mdc)

convex/schema.ts: Always define schema in convex/schema.ts using defineSchema and defineTable imported from convex/server
System fields _creationTime (v.number()) and _id (v.id(tableName)) are automatically added to all documents; do not redefine them
Always include all index fields in the index name; for example, an index on ['field1', 'field2'] should be named 'by_field1_and_field2'

Files:

  • convex/schema.ts
🧠 Learnings (10)
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Use `query`, `mutation`, and `action` for public functions that are exposed to the public API

Applied to files:

  • app/components/AgentsTab.tsx
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Use `ctx.runQuery` to call a query from a query, mutation, or action

Applied to files:

  • app/components/AgentsTab.tsx
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Use as few calls from actions to queries and mutations as possible to avoid race conditions from split transaction logic

Applied to files:

  • app/components/AgentsTab.tsx
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Use `internalQuery`, `internalMutation`, and `internalAction` for private functions that should not be part of the public API

Applied to files:

  • app/components/AgentsTab.tsx
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Thoughtfully organize files with public query, mutation, or action functions within the `convex/` directory for file-based routing

Applied to files:

  • app/components/AgentsTab.tsx
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Use `ctx.runMutation` to call a mutation from a mutation or action

Applied to files:

  • app/components/AgentsTab.tsx
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/schema.ts : System fields `_creationTime` (v.number()) and `_id` (v.id(tableName)) are automatically added to all documents; do not redefine them

Applied to files:

  • convex/schema.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/schema.ts : Always define schema in `convex/schema.ts` using `defineSchema` and `defineTable` imported from `convex/server`

Applied to files:

  • convex/schema.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Use `v.id(tableName)` validator for document ID validation and `Id<'tableName'>` TypeScript type for ID fields

Applied to files:

  • convex/schema.ts
📚 Learning: 2025-11-28T01:16:26.536Z
Learnt from: fkesheh
Repo: hackerai-tech/hackerai PR: 114
File: lib/ai/tools/utils/convex-sandbox.ts:95-145
Timestamp: 2025-11-28T01:16:26.536Z
Learning: In the local sandbox architecture (lib/ai/tools/utils/convex-sandbox.ts), background command execution semantics are handled by the local sandbox client (packages/local/src/index.ts), not by the ConvexSandbox class. When background: true, the local client immediately submits a result with empty output and PID after spawning the process, causing waitForResult() to resolve immediately and maintaining E2B-compatible non-blocking behavior.

Applied to files:

  • lib/ai/tools/run-terminal-cmd.ts
🧬 Code graph analysis (2)
app/components/AgentsTab.tsx (5)
lib/ai/tools/utils/guardrails.ts (5)
  • GuardrailConfigUI (51-57)
  • getDefaultGuardrailsUI (285-287)
  • parseAndMergeGuardrailsConfig (293-304)
  • hasGuardrailChanges (318-342)
  • formatGuardrailsConfigForSave (309-313)
components/ui/label.tsx (1)
  • Label (26-26)
components/ui/switch.tsx (1)
  • Switch (31-31)
components/ui/button.tsx (1)
  • Button (59-59)
components/ui/textarea.tsx (1)
  • Textarea (20-20)
lib/ai/tools/index.ts (1)
lib/ai/tools/http-request.ts (1)
  • createHttpRequest (137-713)
🪛 ast-grep (0.40.3)
lib/ai/tools/utils/guardrails.ts

[warning] 231-231: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(patternStr, "i")
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)

🔇 Additional comments (13)
convex/userCustomization.ts (1)

131-179: Queries properly extended with new fields.

Both getUserCustomization and getUserCustomizationForBackend correctly include the new scope_exclusions and guardrails_config fields in their return validators and return objects. The implementation follows Convex best practices with proper validation.

Also applies to: 184-231

convex/schema.ts (1)

113-114: Schema correctly extended for new user customization fields.

The scope_exclusions and guardrails_config fields are properly added as optional strings, matching the validators in convex/userCustomization.ts. No indexes needed since these fields are not used for querying.

lib/ai/tools/index.ts (2)

96-96: Verify if http_request should be excluded in "ask" mode.

The http_request tool is added to allTools unconditionally (line 96), but in "ask" mode (lines 106-114), only update_memory and web are included. This means http_request is available in "agent" mode but not "ask" mode, which seems intentional based on the tool's security-focused nature. Please confirm this is the expected behavior.

Also applies to: 106-114


44-45: Context properly extended with new configuration fields.

The scopeExclusions and guardrailsConfig parameters are correctly added to the createTools function signature and propagated to the ToolContext. This enables tools like run_terminal_cmd and http_request to enforce scope and security restrictions.

Also applies to: 84-85

app/components/AgentsTab.tsx (3)

65-69: Consider combining useEffect hooks for related state initialization.

The two useEffect hooks for loading scope_exclusions (lines 65-69) and guardrails_config (lines 71-79) could be combined into a single effect since they both depend on userCustomization data loading. However, keeping them separate provides clearer intent and is acceptable.

Also applies to: 71-79


116-138: Good error handling with ConvexError extraction.

Both save handlers (handleSaveScopeExclusions and handleSaveGuardrails) properly extract error messages from ConvexError.data.message, falling back gracefully to error.message or a default string. This provides meaningful feedback to users.

Also applies to: 140-163


220-315: Security Guardrails UI is well-implemented.

The collapsible guardrails section has proper accessibility attributes (aria-expanded, aria-label), clear severity indicators with color coding, and appropriate warning messaging about the risks of disabling guardrails. The "Reset to Defaults" functionality provides a good UX escape hatch.

lib/ai/tools/run-terminal-cmd.ts (2)

36-36: Efficient pre-parsing of configuration.

Good design choice to parse scopeExclusions and guardrailsConfig once during tool creation (lines 36, 39-40) rather than on every command execution. This avoids redundant parsing overhead.

Also applies to: 39-40


123-148: Security checks correctly implemented before command execution.

The guardrail check (lines 123-133) runs before scope exclusion check (lines 135-148), establishing proper priority: security policy violations are caught first. Both checks return early with exitCode: 1 and descriptive error messages, preventing any sandbox interaction for blocked commands.

The error messages are helpful, including the specific policy name and pattern that triggered the block, which aids debugging while not exposing sensitive implementation details.

lib/ai/tools/utils/guardrails.ts (3)

230-253: ReDoS risk mitigated by hardcoded patterns.

The static analysis tool flags a potential ReDoS vulnerability at line 231 where new RegExp(patternStr, "i") constructs a regex from a variable. However, in this implementation, patternStr comes exclusively from DEFAULT_GUARDRAILS (hardcoded patterns), not from user input. Users can only toggle guardrails on/off via enabled, not modify patterns.

This is a false positive for the current design. If pattern customization is added in the future, consider using a regex validation library like safe-regex or recheck.


79-171: Comprehensive guardrail patterns covering common attack vectors.

The DEFAULT_GUARDRAILS array covers critical dangerous patterns:

  • Recursive deletion (rm -rf /)
  • Fork bombs
  • Disk wiping (dd if=/dev/zero)
  • Filesystem formatting (mkfs)
  • Remote code execution (curl | bash, wget | bash)
  • Reverse shells (bash, netcat, python, socat)
  • Environment exfiltration
  • Sudoers modification

All are correctly set to Severity.CRITICAL with enabled: true by default.


325-341: Change detection logic handles edge cases correctly.

The hasGuardrailChanges function properly handles:

  1. Empty saved config → compares against defaults
  2. Existing saved config → compares current state against saved state

The iteration at lines 336-340 only checks if current values differ from saved, which is correct for detecting "unsaved changes" state.

lib/system-prompt.ts (1)

2-3: Verify the UserCustomization type export and structure.

The type import has been moved from a local module to the global @/types barrel export. The UserCustomization interface is properly exported from @/types (via the star export in types/index.ts) and includes the new scope_exclusions?: string field.

- Update LocalConnection interface to include lastSeen: number to match listConnections query return type
- Remove unnecessary type assertions in LocalSandboxTab and SandboxSelector components
- Fixes type mismatch that was hidden by force-casting
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
convex/migrations/clearRegenerationCount.ts (1)

21-44: LGTM - Migration logic is correct.

The migration correctly:

  • Uses internalMutation with proper validators
  • Queries using the by_regeneration_count index with gte() filter
  • Patches each message to set regeneration_count to undefined
  • Returns the count of processed messages

The use of .collect() is acceptable for most datasets. If you expect a very large number of messages (>100k) with regeneration_count set, consider processing in batches.

Optional: Batch processing for very large datasets

If you expect to process a very large number of messages, consider implementing batch processing:

export const clear = internalMutation({
  args: {
    batchSize: v.optional(v.number()),
  },
  returns: v.object({
    processed: v.number(),
  }),
  handler: async (ctx, args) => {
    const batchSize = args.batchSize ?? 100;
    let processed = 0;
    
    while (true) {
      const messages = await ctx.db
        .query("messages")
        .withIndex("by_regeneration_count", (q) => q.gte("regeneration_count", 0))
        .take(batchSize);
      
      if (messages.length === 0) break;
      
      for (const message of messages) {
        await ctx.db.patch(message._id, {
          regeneration_count: undefined,
        });
      }
      
      processed += messages.length;
      
      if (messages.length < batchSize) break;
    }
    
    return { processed };
  },
});

Note: You would need to run this multiple times until processed returns 0.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 57a24f4 and a76c147.

⛔ Files ignored due to path filters (1)
  • convex/_generated/api.d.ts is excluded by !**/_generated/**
📒 Files selected for processing (2)
  • convex/migrations/clearRegenerationCount.ts
  • convex/schema.ts
🧰 Additional context used
📓 Path-based instructions (2)
convex/**/*.{ts,js}

📄 CodeRabbit inference engine (.cursor/rules/convex_rules.mdc)

convex/**/*.{ts,js}: ALWAYS use the new function syntax for Convex functions with query, mutation, action decorators that include args, returns, and handler properties
Use array validators with v.array() to validate array arguments and schema fields
Use discriminated union types with v.union() and v.literal() for schema validation
Always use the v.null() validator when a function returns a null value
Use v.id(tableName) validator for document ID validation and Id<'tableName'> TypeScript type for ID fields
v.bigint() is deprecated; use v.int64() instead for representing signed 64-bit integers
Use v.record() for defining record types; v.map() and v.set() are not supported
Index fields must be queried in the same order they are defined; create separate indexes if you need different query orders
Use internalQuery, internalMutation, and internalAction for private functions that should not be part of the public API
Use query, mutation, and action for public functions that are exposed to the public API
ALWAYS include argument and return validators for all Convex functions including query, internalQuery, mutation, internalMutation, action, and internalAction
Functions that don't return anything should include returns: v.null() as the output validator
Functions implicitly return null in JavaScript if they have no return statement
Use ctx.runQuery to call a query from a query, mutation, or action
Use ctx.runMutation to call a mutation from a mutation or action
Use ctx.runAction to call an action from an action
Only call an action from another action if you need to cross runtimes (e.g., V8 to Node); otherwise extract shared code into a helper async function
Use as few calls from actions to queries and mutations as possible to avoid race conditions from split transaction logic
Pass a FunctionReference to ctx.runQuery, ctx.runMutation, or ctx.runAction; do not pass the callee function directly
When usi...

Files:

  • convex/migrations/clearRegenerationCount.ts
  • convex/schema.ts
convex/schema.ts

📄 CodeRabbit inference engine (.cursor/rules/convex_rules.mdc)

convex/schema.ts: Always define schema in convex/schema.ts using defineSchema and defineTable imported from convex/server
System fields _creationTime (v.number()) and _id (v.id(tableName)) are automatically added to all documents; do not redefine them
Always include all index fields in the index name; for example, an index on ['field1', 'field2'] should be named 'by_field1_and_field2'

Files:

  • convex/schema.ts
🧠 Learnings (11)
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Use `internalQuery`, `internalMutation`, and `internalAction` for private functions that should not be part of the public API

Applied to files:

  • convex/migrations/clearRegenerationCount.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Thoughtfully organize files with public query, mutation, or action functions within the `convex/` directory for file-based routing

Applied to files:

  • convex/migrations/clearRegenerationCount.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Use `query`, `mutation`, and `action` for public functions that are exposed to the public API

Applied to files:

  • convex/migrations/clearRegenerationCount.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : When using `ctx.runQuery`, `ctx.runMutation`, or `ctx.runAction` to call a function in the same file, add a type annotation on the return value to work around TypeScript circularity limitations

Applied to files:

  • convex/migrations/clearRegenerationCount.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Use `ctx.runMutation` to call a mutation from a mutation or action

Applied to files:

  • convex/migrations/clearRegenerationCount.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Convex queries do NOT support `.delete()`; instead `.collect()` the results, iterate, and call `ctx.db.delete(row._id)` on each result

Applied to files:

  • convex/migrations/clearRegenerationCount.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/schema.ts : System fields `_creationTime` (v.number()) and `_id` (v.id(tableName)) are automatically added to all documents; do not redefine them

Applied to files:

  • convex/schema.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Index fields must be queried in the same order they are defined; create separate indexes if you need different query orders

Applied to files:

  • convex/schema.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/schema.ts : Always include all index fields in the index name; for example, an index on ['field1', 'field2'] should be named 'by_field1_and_field2'

Applied to files:

  • convex/schema.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/schema.ts : Always define schema in `convex/schema.ts` using `defineSchema` and `defineTable` imported from `convex/server`

Applied to files:

  • convex/schema.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Use `v.id(tableName)` validator for document ID validation and `Id<'tableName'>` TypeScript type for ID fields

Applied to files:

  • convex/schema.ts
🔇 Additional comments (4)
convex/schema.ts (3)

70-71: LGTM - Temporary field for migration.

The regeneration_count field is correctly defined as optional to support the migration process. The TODO comment clearly indicates this is temporary.


115-116: LGTM - New user customization fields.

The scope_exclusions and guardrails_config fields are properly defined as optional strings, consistent with the pattern used for other user_customization fields.


77-78: Verify no new writes to regeneration_count before index removal.

The index naming follows conventions and the TODO is clear. Verification confirms that no code is currently writing to the regeneration_count field outside of the dedicated migration (convex/migrations/clearRegenerationCount.ts). The migration properly clears the field from all messages using the by_regeneration_count index and sets the field to undefined. The field and index can be safely removed from the schema once the migration completes.

convex/migrations/clearRegenerationCount.ts (1)

1-14: LGTM - Clear documentation and correct imports.

The migration includes excellent documentation explaining the purpose, execution steps, and cleanup tasks. The imports are correct.

- Remove sanitizeExternalResponse usage from HTTP request tool
- Remove stripExternalDataMarkers usage from HttpRequestToolHandler
- Remove stripMarkersFromMessages usage from chat handler
- Delete prompt-injection-protection.ts utility file
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
app/components/tools/HttpRequestToolHandler.tsx (1)

100-108: Add explanation for the ESLint disable directive.

The eslint-disable comment on Line 107 suppresses the exhaustive-deps warning, presumably because updateSidebarContent is stable. Consider adding a brief comment explaining why this dependency is intentionally omitted to improve code maintainability.

🔎 Suggested improvement
  useEffect(() => {
    if (!isSidebarActive) return;

    updateSidebarContent({
      output: finalOutput,
      isExecuting,
    });
-   // eslint-disable-next-line react-hooks/exhaustive-deps
+   // eslint-disable-next-line react-hooks/exhaustive-deps
+   // updateSidebarContent is stable from context and doesn't need to be in deps
  }, [isSidebarActive, finalOutput, isExecuting]);
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a76c147 and 9c8faa0.

📒 Files selected for processing (5)
  • app/components/tools/HttpRequestToolHandler.tsx
  • convex/migrations/clearRegenerationCount.ts
  • lib/ai/tools/http-request.ts
  • lib/api/chat-handler.ts
  • lib/token-utils.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • lib/token-utils.ts
🧰 Additional context used
📓 Path-based instructions (1)
convex/**/*.{ts,js}

📄 CodeRabbit inference engine (.cursor/rules/convex_rules.mdc)

convex/**/*.{ts,js}: ALWAYS use the new function syntax for Convex functions with query, mutation, action decorators that include args, returns, and handler properties
Use array validators with v.array() to validate array arguments and schema fields
Use discriminated union types with v.union() and v.literal() for schema validation
Always use the v.null() validator when a function returns a null value
Use v.id(tableName) validator for document ID validation and Id<'tableName'> TypeScript type for ID fields
v.bigint() is deprecated; use v.int64() instead for representing signed 64-bit integers
Use v.record() for defining record types; v.map() and v.set() are not supported
Index fields must be queried in the same order they are defined; create separate indexes if you need different query orders
Use internalQuery, internalMutation, and internalAction for private functions that should not be part of the public API
Use query, mutation, and action for public functions that are exposed to the public API
ALWAYS include argument and return validators for all Convex functions including query, internalQuery, mutation, internalMutation, action, and internalAction
Functions that don't return anything should include returns: v.null() as the output validator
Functions implicitly return null in JavaScript if they have no return statement
Use ctx.runQuery to call a query from a query, mutation, or action
Use ctx.runMutation to call a mutation from a mutation or action
Use ctx.runAction to call an action from an action
Only call an action from another action if you need to cross runtimes (e.g., V8 to Node); otherwise extract shared code into a helper async function
Use as few calls from actions to queries and mutations as possible to avoid race conditions from split transaction logic
Pass a FunctionReference to ctx.runQuery, ctx.runMutation, or ctx.runAction; do not pass the callee function directly
When usi...

Files:

  • convex/migrations/clearRegenerationCount.ts
🧠 Learnings (6)
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Use `internalQuery`, `internalMutation`, and `internalAction` for private functions that should not be part of the public API

Applied to files:

  • convex/migrations/clearRegenerationCount.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Thoughtfully organize files with public query, mutation, or action functions within the `convex/` directory for file-based routing

Applied to files:

  • convex/migrations/clearRegenerationCount.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Use `query`, `mutation`, and `action` for public functions that are exposed to the public API

Applied to files:

  • convex/migrations/clearRegenerationCount.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : When using `ctx.runQuery`, `ctx.runMutation`, or `ctx.runAction` to call a function in the same file, add a type annotation on the return value to work around TypeScript circularity limitations

Applied to files:

  • convex/migrations/clearRegenerationCount.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Use `ctx.runMutation` to call a mutation from a mutation or action

Applied to files:

  • convex/migrations/clearRegenerationCount.ts
📚 Learning: 2025-12-24T18:09:08.574Z
Learnt from: CR
Repo: hackerai-tech/hackerai PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-24T18:09:08.574Z
Learning: Applies to convex/**/*.{ts,js} : Use as few calls from actions to queries and mutations as possible to avoid race conditions from split transaction logic

Applied to files:

  • convex/migrations/clearRegenerationCount.ts
🧬 Code graph analysis (1)
app/components/tools/HttpRequestToolHandler.tsx (2)
types/chat.ts (3)
  • ChatStatus (81-81)
  • SidebarTerminal (26-33)
  • isSidebarTerminal (50-54)
app/contexts/GlobalState.tsx (1)
  • useGlobalState (752-758)
🔇 Additional comments (17)
convex/migrations/clearRegenerationCount.ts (1)

18-43: LGTM! Well-structured migration with clear documentation.

The migration correctly uses internalMutation with proper validators, implements batched processing, and includes helpful usage instructions. The implementation follows Convex best practices.

app/components/tools/HttpRequestToolHandler.tsx (1)

110-174: LGTM! Keyboard navigation and state handling are well implemented.

The event handlers and state-based rendering logic are correct. Keyboard accessibility with Enter/Space keys and the switch statement covering all tool states demonstrate good attention to detail.

lib/api/chat-handler.ts (3)

221-222: LGTM! Correct propagation of user customization settings.

The scope exclusions and guardrails configuration are properly extracted from userCustomization and passed to createTools with appropriate optional chaining.


349-352: LGTM! Proper conditional return structure.

The return statement correctly includes messages and conditionally adds the system prompt when available. This aligns with the updated prepareStep behavior described in the PR.


367-370: LGTM! Consistent return structure after memory update.

After refreshing the system prompt, the function correctly returns both messages and the updated system prompt.

lib/ai/tools/http-request.ts (12)

20-22: LGTM! Standard shell escaping for single quotes.

The shell escape implementation correctly handles single quotes using the standard '\'' pattern for safe shell argument construction.


27-93: LGTM! Robust curl output parsing with proper fallbacks.

The parsing logic correctly handles multiple delimiter formats and edge cases. The fallback to treating all output as body when no header separator is found is a reasonable defensive approach.


269-282: LGTM! Clear mutual exclusivity validation.

The validation correctly ensures only one body parameter type is provided at a time with a clear error message.


284-300: LGTM! Proper URL validation with protocol restrictions.

The URL validation correctly restricts to HTTP/HTTPS protocols and provides clear error messages for invalid URLs or unsupported schemes.


302-310: LGTM! Proper scope exclusion enforcement.

The scope exclusion check is correctly implemented and provides a clear error message that includes the matched pattern, helping users understand why their request was blocked.


333-358: LGTM! Well-designed header conflict resolution.

The header normalization and conflict resolution logic correctly handles case-insensitivity per HTTP standards and ensures typed parameters (like json_body and cookies) take precedence over generic headers to prevent duplicates.


411-434: LGTM! Comprehensive shell escaping for command safety.

The command building logic properly identifies and escapes arguments containing shell special characters, preventing command injection while keeping simple arguments unescaped for readability.


440-450: LGTM! Robust sandbox health check with automatic recovery.

The health check implementation correctly handles unhealthy sandboxes by recreating them, ensuring reliable command execution.


467-492: LGTM! Proper abort signal handling with race condition prevention.

The promise-based execution correctly handles abort signals with a resolved flag to prevent double resolution, and checks for pre-aborted signals before starting execution.


573-579: LGTM! Appropriate response size limiting with clear warnings.

The truncation logic properly limits response size to prevent excessive token usage and clearly indicates when truncation occurs with formatted byte counts.


614-654: LGTM! Valuable security indicator detection for penetration testing.

The security detection logic provides useful insights into WAFs, CDNs, and security headers present on the target, which is essential for security assessment workflows.


657-659: LGTM! Layered truncation strategy for token management.

Applying token-based truncation after byte-based truncation provides a robust safety mechanism to ensure outputs remain within model token limits.

- Change examples from coding tasks to security testing scenarios
- Update 'When to Use' section for vulnerability assessments
- Update 'When NOT to Use' with pentesting-appropriate exclusions
- Revise task states terminology (e.g., 'Currently testing')
- Add security-focused task breakdown examples
@rossmanko rossmanko merged commit 7cfa7a9 into main Jan 3, 2026
4 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Jan 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants