Skip to content

[codex] Refactor agent registry and add custom agent CRUD groundwork#2994

Merged
Kitenite merged 13 commits into
mainfrom
add-amp-code-support-add-amp-code-support
Mar 31, 2026
Merged

[codex] Refactor agent registry and add custom agent CRUD groundwork#2994
Kitenite merged 13 commits into
mainfrom
add-amp-code-support-add-amp-code-support

Conversation

@Kitenite
Copy link
Copy Markdown
Collaborator

@Kitenite Kitenite commented Mar 29, 2026

Summary

  • move built-in terminal agent metadata into a shared manifest so command building, catalog entries, and default preset seeding derive from one source of truth
  • refactor desktop agent setup to use capability-driven setup targets instead of a hardcoded sequence of per-agent wrapper calls
  • add Amp Code as a built-in terminal agent, including wrapper support, prompt execution via amp -x, docs, and the official Amp square mark icon
  • add custom terminal agent CRUD groundwork in desktop settings using agentCustomDefinitions, including create, update, delete, and normalization helpers
  • keep Amp MCP support user-facing by parsing user-provided .amp/settings.json, while stopping this repo from tracking its own Amp workspace settings
  • derive the MCP start-agent description from the supported agent list and clean up lint in the new agent-settings tests

Why

Adding Amp exposed that first-class agent support was still spread across several hardcoded lists and setup paths. That made each new built-in agent more expensive to add and left the existing custom-agent schema without explicit CRUD support.

This repo also should not commit workspace-specific Amp settings for itself. Amp config support is useful for users in their own repos, but keeping a repo-owned .amp/settings.json here is unnecessary and misleading.

Impact

  • Built-in agent additions are now mostly manifest-driven.
  • The desktop settings backend has a stable surface for future user-facing custom-agent management.
  • Amp is available as a supported agent without requiring Superset to carry a repo-local Amp workspace config.

Validation

  • bun test packages/shared/src/agent-command.test.ts apps/desktop/src/main/lib/agent-setup/agent-wrappers.test.ts packages/chat/src/server/desktop/router/mcp-overview/mcp-overview.test.ts apps/desktop/src/shared/utils/agent-settings.test.ts apps/desktop/src/lib/trpc/routers/settings/agent-preset-router.utils.test.ts
  • bunx turbo run typecheck --filter=./packages/shared --filter=./packages/mcp --filter=./packages/chat --filter=./packages/ui --filter=./apps/desktop
  • bun run lint
  • Manual Amp CLI verification:
    • amp
    • amp --help
    • amp -x --help
    • amp -x "Reply with exactly OK"
    • printf "Reply with exactly OK\n" | amp -x
    • amp -x "$(cat prompt.txt)"

The execute-mode checks reached Amp correctly but failed with Amp's paid-credit requirement for -x (402), which confirms the command shapes are correct even though full non-interactive execution is blocked on account state.

Summary by CodeRabbit

  • New Features

    • Added Amp Code as a fully supported agent with wrapper and integration support
    • Enabled custom terminal agent creation, updates, and deletion via API
    • Added MCP configuration support for Amp CLI (.amp/settings.json)
    • Added Amp as a quick-add terminal preset template
  • Documentation

    • Updated supported agents list to include Amp Code
    • Added Amp CLI MCP setup and configuration examples
    • Added Amp terminal preset documentation

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 29, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds Amp Code CLI as a supported terminal agent, introduces custom agent creation/update/delete via TRPC mutations with schema validation, refactors builtin agent definitions into a typed manifest catalog, extends MCP configuration to read from .amp/settings.json, and consolidates agent setup infrastructure.

Changes

Cohort / File(s) Summary
Documentation & Configuration
.gitignore, AGENTS.md, README.md, apps/docs/content/docs/*, apps/desktop/docs/EXTERNAL_FILES.md
Added Amp agent to supported agents list, updated MCP config guidance, documented Amp terminal preset template, and added .amp/ directory to gitignore.
Custom Agent Validation & Schemas
apps/desktop/src/lib/trpc/routers/settings/agent-preset-router.utils.ts, apps/desktop/src/lib/trpc/routers/settings/agent-preset-router.utils.test.ts
Introduced Zod schemas (createCustomAgentInputSchema, updateCustomAgentInputSchema) and normalization helpers (normalizeCreateCustomAgentInput, normalizeCustomAgentPatch) with task prompt template validation and field trimming logic.
Custom Agent CRUD & Persistence
apps/desktop/src/lib/trpc/routers/settings/index.ts, apps/desktop/src/shared/utils/agent-settings.ts, apps/desktop/src/shared/utils/agent-settings.test.ts
Added three new TRPC mutations (createCustomAgent, updateCustomAgent, deleteCustomAgent), implemented custom definition storage/retrieval helpers (getCustomAgentDefinitionById, upsertCustomAgentDefinition, applyCustomAgentDefinitionPatch, deleteCustomAgentDefinition), and added persistence via saveAgentCustomDefinitions.
Amp Agent Setup Infrastructure
apps/desktop/src/main/lib/agent-setup/agent-wrappers-amp.ts, apps/desktop/src/main/lib/agent-setup/desktop-agent-capabilities.ts, apps/desktop/src/main/lib/agent-setup/desktop-agent-setup.ts, apps/desktop/src/main/lib/agent-setup/agent-wrappers.ts
Defined createAmpWrapper() to generate Amp CLI passthrough script, consolidated agent setup actions/targets into DESKTOP_AGENT_SETUP_TARGETS manifest, and created setupDesktopAgentCapabilities() orchestrator function.
Agent Setup Refactoring
apps/desktop/src/main/lib/agent-setup/index.ts, apps/desktop/src/main/lib/agent-setup/agent-wrappers-common.ts, apps/desktop/src/main/lib/agent-setup/shell-wrappers.ts
Replaced inline agent initialization calls with consolidated setupDesktopAgentCapabilities() call; moved SUPERSET_MANAGED_BINARIES to centralized desktop-agent-capabilities module.
Builtin Agent Catalog & Refactoring
packages/shared/src/builtin-terminal-agents.ts, packages/shared/src/agent-command.ts, packages/shared/src/agent-catalog.ts
Created BuiltinTerminalAgentManifest interface and BUILTIN_TERMINAL_AGENTS typed catalog; refactored AGENT_TYPES, AGENT_LABELS, AGENT_PRESET_COMMANDS, and AGENT_PROMPT_COMMANDS to derive from centralized manifest instead of inline definitions.
Agent Command & Prompt Building
packages/shared/src/agent-command.test.ts
Added test case for buildAgentPromptCommand with Amp agent executing via -x flag with heredoc-style prompt injection.
MCP Configuration Support
packages/chat/src/server/desktop/router/mcp-overview/mcp-overview.ts, packages/chat/src/server/desktop/router/mcp-overview/mcp-overview.test.ts
Extended MCP server configuration reading to support .amp/settings.json with amp.mcpServers key; implemented structured file-scanning with per-file schema validators and fallback precedence.
MCP Session Tools
packages/mcp/src/tools/devices/start-agent-session/shared.ts
Updated agent field description to dynamically generate supported agent list via describeSupportedAgents() helper instead of static string.
Preset Icons
packages/ui/src/assets/icons/preset-icons/index.ts
Added ampIcon import and amp entry to PRESET_ICONS map for both light and dark theme variants.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client / UI
    participant API as TRPC Router
    participant Validation as Normalization
    participant Storage as Settings Store
    participant Preset as Preset Resolver
    
    Client->>API: createCustomAgent(label, command, promptCommand, taskPromptTemplate)
    API->>Validation: normalizeCreateCustomAgentInput(input)
    Validation->>Validation: validate fields, trim strings, validate task prompt template
    alt Invalid Input
        Validation-->>API: throw TRPCError(BAD_REQUEST)
        API-->>Client: error
    else Valid Input
        Validation-->>API: normalized definition
        API->>Storage: upsertCustomAgentDefinition(definition with custom:uuid id)
        Storage->>Storage: add/replace in customDefinitions array
        API->>Storage: saveAgentCustomDefinitions(definitions)
        Storage-->>API: saved
        API->>Preset: resolveAgentPreset(custom:uuid)
        Preset-->>API: resolved preset with user-provided fields
        API-->>Client: { id, label, command, promptCommand, ... }
    end
Loading
sequenceDiagram
    participant Client as Chat Client
    participant MCP as MCP Overview
    participant FileReader as File System
    participant Parser as JSON/Zod Parser
    
    Client->>MCP: getMcpOverview(cwd)
    MCP->>FileReader: iterate config files (.amp/settings.json, .mcp.json, ...)
    
    alt .amp/settings.json exists
        FileReader-->>MCP: file content
        MCP->>Parser: parse JSON → extract amp.mcpServers
        alt Valid JSON
            Parser-->>MCP: servers array
            MCP-->>Client: { sourcePath: .amp/settings.json, servers: [...] }
        else Invalid JSON
            Parser-->>MCP: error (fallback)
            MCP->>FileReader: try next file (.mcp.json)
        end
    else .mcp.json exists
        FileReader-->>MCP: file content
        MCP->>Parser: parse JSON → extract mcpServers
        Parser-->>MCP: servers array
        MCP-->>Client: { sourcePath: .mcp.json, servers: [...] }
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 A fluffy agent hops in view,
Amp Code CLI, something new!
With custom creations and schemas so bright,
Refactored catalogs, everything's tight!
Custom agents leap—setup takes flight! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.41% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title mentions refactoring agent registry and custom agent CRUD, which aligns with the PR's main changes (centralizing agent metadata and adding custom agent CRUD). However, it omits the significant Amp Code integration, which is prominently featured in the PR description and changes.
Description check ✅ Passed The PR description is comprehensive, covering all major objectives: agent manifest refactoring, desktop agent setup redesign, Amp integration, custom agent CRUD, MCP support, and validation steps. It follows the template structure with Summary, Why, Impact, and Validation sections.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch add-amp-code-support-add-amp-code-support

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@Kitenite Kitenite marked this pull request as ready for review March 30, 2026 03:07
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

No issues found across 30 files

Copy link
Copy Markdown
Contributor

@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 (4)
packages/chat/src/server/desktop/router/mcp-overview/mcp-overview.ts (1)

16-19: Consider extracting the duplicated mcpServers reader.

The readServers callbacks for .mastracode/mcp.json and .mcp.json are identical.

🔧 Optional DRY improvement
+const readMcpServers = (parsed: unknown) => {
+	const result = mcpSettingsSchema.safeParse(parsed);
+	return result.success ? result.data.mcpServers : null;
+};
+
 const MCP_SETTINGS_FILES = [
 	{
 		relativePath: ".mastracode/mcp.json",
-		readServers: (parsed: unknown) => {
-			const result = mcpSettingsSchema.safeParse(parsed);
-			return result.success ? result.data.mcpServers : null;
-		},
+		readServers: readMcpServers,
 	},
 	{
 		relativePath: ".amp/settings.json",
 		readServers: (parsed: unknown) => {
 			const result = ampMcpSettingsSchema.safeParse(parsed);
 			return result.success ? result.data["amp.mcpServers"] : null;
 		},
 	},
 	{
 		relativePath: ".mcp.json",
-		readServers: (parsed: unknown) => {
-			const result = mcpSettingsSchema.safeParse(parsed);
-			return result.success ? result.data.mcpServers : null;
-		},
+		readServers: readMcpServers,
 	},
 ] as const;

Also applies to: 30-33

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/chat/src/server/desktop/router/mcp-overview/mcp-overview.ts` around
lines 16 - 19, Extract the duplicated logic that reads mcpServers into a single
helper function (e.g., readMcpServers) and use it for both callbacks;
specifically, create a function that accepts parsed: unknown, calls
mcpSettingsSchema.safeParse(parsed), and returns result.success ?
result.data.mcpServers : null, then replace the inline readServers
implementations for the `.mastracode/mcp.json` and `.mcp.json` entries with
references to this new helper (keep references to mcpSettingsSchema.safeParse
and the mcpServers field so behavior is unchanged).
apps/desktop/src/lib/trpc/routers/settings/index.ts (2)

239-266: Potential TOCTOU issue with double database reads.

The mutation reads readRawAgentCustomDefinitions() twice: once to look up the definition (line 243) and again when calling upsertCustomAgentDefinition (line 254). In a concurrent environment, another mutation could modify the definitions between these reads, potentially causing unexpected behavior.

Consider reading once and reusing:

🔧 Suggested improvement
 updateCustomAgent: publicProcedure
   .input(updateCustomAgentInputSchema)
   .mutation(({ input }) => {
+    const currentDefinitions = readRawAgentCustomDefinitions();
     const definition = getCustomAgentDefinitionById({
-      customDefinitions: readRawAgentCustomDefinitions(),
+      customDefinitions: currentDefinitions,
       id: input.id as `custom:${string}`,
     });
     if (!definition) {
       throw new TRPCError({
         code: "NOT_FOUND",
         message: `Custom agent ${input.id} not found`,
       });
     }

     const nextDefinitions = upsertCustomAgentDefinition({
-      currentDefinitions: readRawAgentCustomDefinitions(),
+      currentDefinitions,
       definition: applyCustomAgentDefinitionPatch({
         definition,
         patch: normalizeCustomAgentPatch(input.patch),
       }),
     });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/desktop/src/lib/trpc/routers/settings/index.ts` around lines 239 - 266,
The mutation updateCustomAgent currently calls readRawAgentCustomDefinitions()
twice which creates a TOCTOU race; fix it by reading the definitions once into a
local variable (e.g., const currentDefinitions =
readRawAgentCustomDefinitions()) and then use currentDefinitions for
getCustomAgentDefinitionById(...) and pass currentDefinitions into
upsertCustomAgentDefinition(...); apply the patch via
applyCustomAgentDefinitionPatch(...) against the single-read definition and then
call saveAgentCustomDefinitions(nextDefinitions) and return the resolved preset
as before.

267-295: Same TOCTOU consideration applies to deleteCustomAgent.

Similar to updateCustomAgent, this mutation reads the definitions twice. Additionally, the cleanup of preset overrides (lines 287-292) is a good practice to prevent orphaned data.

🔧 Suggested improvement
 deleteCustomAgent: publicProcedure
   .input(z.object({ id: z.string().regex(/^custom:/) }))
   .mutation(({ input }) => {
+    const currentDefinitions = readRawAgentCustomDefinitions();
     const existingDefinition = getCustomAgentDefinitionById({
-      customDefinitions: readRawAgentCustomDefinitions(),
+      customDefinitions: currentDefinitions,
       id: input.id as `custom:${string}`,
     });
     if (!existingDefinition) {
       throw new TRPCError({
         code: "NOT_FOUND",
         message: `Custom agent ${input.id} not found`,
       });
     }

     saveAgentCustomDefinitions(
       deleteCustomAgentDefinition({
-        currentDefinitions: readRawAgentCustomDefinitions(),
+        currentDefinitions,
         id: input.id as `custom:${string}`,
       }),
     );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/desktop/src/lib/trpc/routers/settings/index.ts` around lines 267 - 295,
The deleteCustomAgent mutation currently performs TOCTOU by calling
readRawAgentCustomDefinitions() twice and then operating on separate snapshots;
instead, read the current definitions once into a const (use that single value
for getCustomAgentDefinitionById and deleteCustomAgentDefinition) and similarly
read overrides once into a const for resetAgentPresetOverride, then pass those
single snapshots to saveAgentCustomDefinitions and saveAgentPresetOverrides
respectively; update the deleteCustomAgent handler to use these locals and keep
calls to getCustomAgentDefinitionById, deleteCustomAgentDefinition,
resetAgentPresetOverride, saveAgentCustomDefinitions, and
saveAgentPresetOverrides but always operate on the same in-memory values to
avoid race conditions.
packages/shared/src/builtin-terminal-agents.ts (1)

21-31: Add a duplicate-id guard for the built-in manifest.

createAgentRecord/fromEntries will silently overwrite on duplicate id. A fail-fast assertion would prevent subtle catalog corruption.

Suggested patch
+function assertUniqueAgentIds(
+	agents: readonly BuiltinTerminalAgentManifest[],
+): void {
+	const seen = new Set<string>();
+	for (const { id } of agents) {
+		if (seen.has(id)) {
+			throw new Error(`Duplicate builtin terminal agent id: ${id}`);
+		}
+		seen.add(id);
+	}
+}
+
 export const BUILTIN_TERMINAL_AGENTS = [
   // ...
 ] as const satisfies readonly BuiltinTerminalAgentManifest[];
+
+assertUniqueAgentIds(BUILTIN_TERMINAL_AGENTS);

Also applies to: 33-114

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/shared/src/builtin-terminal-agents.ts` around lines 21 - 31, The
createAgentRecord function silently overwrites entries when two manifests share
the same id; update it to perform a fail-fast duplicate-id check before calling
Object.fromEntries: iterate agents (or map over them) while tracking seen ids in
a Set, and if agent.id is already present throw or assert with a clear message
including the duplicate id and preferably the agent manifest identity; only
after the check proceed to build and return the Record using getValue(agent).
Also apply the same duplicate-id guard to any other helper that builds records
from BuiltinTerminalAgentManifest in this file (the analogous function/block
around the other record creation).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/desktop/src/lib/trpc/routers/settings/agent-preset-router.utils.ts`:
- Around line 38-45: The id regex in updateCustomAgentInputSchema currently
allows the bare "custom:" value; tighten it so ids must include at least one
character after the prefix (rejecting exactly "custom:"). Update the id
validation in updateCustomAgentInputSchema to use a regex that requires one or
more characters after "custom:" (e.g., change from /^custom:/ to a pattern like
/^custom:.+/) so the schema rejects bare "custom:" at input validation time.

---

Nitpick comments:
In `@apps/desktop/src/lib/trpc/routers/settings/index.ts`:
- Around line 239-266: The mutation updateCustomAgent currently calls
readRawAgentCustomDefinitions() twice which creates a TOCTOU race; fix it by
reading the definitions once into a local variable (e.g., const
currentDefinitions = readRawAgentCustomDefinitions()) and then use
currentDefinitions for getCustomAgentDefinitionById(...) and pass
currentDefinitions into upsertCustomAgentDefinition(...); apply the patch via
applyCustomAgentDefinitionPatch(...) against the single-read definition and then
call saveAgentCustomDefinitions(nextDefinitions) and return the resolved preset
as before.
- Around line 267-295: The deleteCustomAgent mutation currently performs TOCTOU
by calling readRawAgentCustomDefinitions() twice and then operating on separate
snapshots; instead, read the current definitions once into a const (use that
single value for getCustomAgentDefinitionById and deleteCustomAgentDefinition)
and similarly read overrides once into a const for resetAgentPresetOverride,
then pass those single snapshots to saveAgentCustomDefinitions and
saveAgentPresetOverrides respectively; update the deleteCustomAgent handler to
use these locals and keep calls to getCustomAgentDefinitionById,
deleteCustomAgentDefinition, resetAgentPresetOverride,
saveAgentCustomDefinitions, and saveAgentPresetOverrides but always operate on
the same in-memory values to avoid race conditions.

In `@packages/chat/src/server/desktop/router/mcp-overview/mcp-overview.ts`:
- Around line 16-19: Extract the duplicated logic that reads mcpServers into a
single helper function (e.g., readMcpServers) and use it for both callbacks;
specifically, create a function that accepts parsed: unknown, calls
mcpSettingsSchema.safeParse(parsed), and returns result.success ?
result.data.mcpServers : null, then replace the inline readServers
implementations for the `.mastracode/mcp.json` and `.mcp.json` entries with
references to this new helper (keep references to mcpSettingsSchema.safeParse
and the mcpServers field so behavior is unchanged).

In `@packages/shared/src/builtin-terminal-agents.ts`:
- Around line 21-31: The createAgentRecord function silently overwrites entries
when two manifests share the same id; update it to perform a fail-fast
duplicate-id check before calling Object.fromEntries: iterate agents (or map
over them) while tracking seen ids in a Set, and if agent.id is already present
throw or assert with a clear message including the duplicate id and preferably
the agent manifest identity; only after the check proceed to build and return
the Record using getValue(agent). Also apply the same duplicate-id guard to any
other helper that builds records from BuiltinTerminalAgentManifest in this file
(the analogous function/block around the other record creation).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ebca65d3-5c32-49c9-a15a-ebb5021a15cc

📥 Commits

Reviewing files that changed from the base of the PR and between 8dc5c38 and 6875bb8.

⛔ Files ignored due to path filters (1)
  • packages/ui/src/assets/icons/preset-icons/amp.svg is excluded by !**/*.svg
📒 Files selected for processing (29)
  • .amp/settings.json
  • .gitignore
  • AGENTS.md
  • README.md
  • apps/desktop/docs/EXTERNAL_FILES.md
  • apps/desktop/src/lib/trpc/routers/settings/agent-preset-router.utils.test.ts
  • apps/desktop/src/lib/trpc/routers/settings/agent-preset-router.utils.ts
  • apps/desktop/src/lib/trpc/routers/settings/index.ts
  • apps/desktop/src/main/lib/agent-setup/agent-wrappers-amp.ts
  • apps/desktop/src/main/lib/agent-setup/agent-wrappers-common.ts
  • apps/desktop/src/main/lib/agent-setup/agent-wrappers.test.ts
  • apps/desktop/src/main/lib/agent-setup/agent-wrappers.ts
  • apps/desktop/src/main/lib/agent-setup/desktop-agent-capabilities.ts
  • apps/desktop/src/main/lib/agent-setup/desktop-agent-setup.ts
  • apps/desktop/src/main/lib/agent-setup/index.ts
  • apps/desktop/src/main/lib/agent-setup/shell-wrappers.ts
  • apps/desktop/src/shared/utils/agent-settings.test.ts
  • apps/desktop/src/shared/utils/agent-settings.ts
  • apps/docs/content/docs/agent-integration.mdx
  • apps/docs/content/docs/mcp.mdx
  • apps/docs/content/docs/terminal-presets.mdx
  • packages/chat/src/server/desktop/router/mcp-overview/mcp-overview.test.ts
  • packages/chat/src/server/desktop/router/mcp-overview/mcp-overview.ts
  • packages/mcp/src/tools/devices/start-agent-session/shared.ts
  • packages/shared/src/agent-catalog.ts
  • packages/shared/src/agent-command.test.ts
  • packages/shared/src/agent-command.ts
  • packages/shared/src/builtin-terminal-agents.ts
  • packages/ui/src/assets/icons/preset-icons/index.ts

Comment on lines +38 to +45
export const updateCustomAgentInputSchema = z.object({
id: z.string().regex(/^custom:/),
patch: createCustomAgentInputSchema
.partial()
.refine((patch) => Object.keys(patch).length > 0, {
message: "Patch must include at least one field",
}),
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Tighten custom-agent id validation.

Line 39 currently accepts a bare custom: id. That should be rejected at input validation time.

Suggested patch
 export const updateCustomAgentInputSchema = z.object({
-	id: z.string().regex(/^custom:/),
+	id: z.string().regex(/^custom:.+$/, {
+		message: "id must start with 'custom:' and include a non-empty suffix",
+	}),
 	patch: createCustomAgentInputSchema
 		.partial()
 		.refine((patch) => Object.keys(patch).length > 0, {
 			message: "Patch must include at least one field",
 		}),
 });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const updateCustomAgentInputSchema = z.object({
id: z.string().regex(/^custom:/),
patch: createCustomAgentInputSchema
.partial()
.refine((patch) => Object.keys(patch).length > 0, {
message: "Patch must include at least one field",
}),
});
export const updateCustomAgentInputSchema = z.object({
id: z.string().regex(/^custom:.+$/, {
message: "id must start with 'custom:' and include a non-empty suffix",
}),
patch: createCustomAgentInputSchema
.partial()
.refine((patch) => Object.keys(patch).length > 0, {
message: "Patch must include at least one field",
}),
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/desktop/src/lib/trpc/routers/settings/agent-preset-router.utils.ts`
around lines 38 - 45, The id regex in updateCustomAgentInputSchema currently
allows the bare "custom:" value; tighten it so ids must include at least one
character after the prefix (rejecting exactly "custom:"). Update the id
validation in updateCustomAgentInputSchema to use a regex that requires one or
more characters after "custom:" (e.g., change from /^custom:/ to a pattern like
/^custom:.+/) so the schema rejects bare "custom:" at input validation time.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 30, 2026

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

  • ✅ Neon database branch
  • ✅ Electric Fly.io app

Thank you for your contribution! 🎉

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.

1 participant