diff --git a/src/specify_cli/__init__.py b/src/specify_cli/__init__.py index 3918963c8..5282b1980 100644 --- a/src/specify_cli/__init__.py +++ b/src/specify_cli/__init__.py @@ -2697,6 +2697,12 @@ def agent_switch( if agent_folder: agent_dir = project_path / agent_folder.rstrip("/") if agent_dir.is_dir(): + if not force: + console.print(f"[yellow]No install manifest found for '{current_agent}' (legacy project).[/yellow]") + console.print(f" Directory to remove: {agent_dir}") + if not typer.confirm("Remove this directory?"): + console.print("[dim]Aborted. Use --force to skip this check.[/dim]") + raise typer.Exit(0) shutil.rmtree(agent_dir) console.print(f" [green]✓[/green] {current_agent} directory removed (legacy)") else: @@ -2708,6 +2714,12 @@ def agent_switch( if agent_folder: agent_dir = project_path / agent_folder.rstrip("/") if agent_dir.is_dir(): + if not force: + console.print(f"[yellow]No agent pack found for '{current_agent}' (legacy project).[/yellow]") + console.print(f" Directory to remove: {agent_dir}") + if not typer.confirm("Remove this directory?"): + console.print("[dim]Aborted. Use --force to skip this check.[/dim]") + raise typer.Exit(0) shutil.rmtree(agent_dir) console.print(f" [green]✓[/green] {current_agent} directory removed (legacy)") @@ -2757,6 +2769,7 @@ def agent_switch( # Update init options options["ai"] = agent_id + options["agent_pack"] = True options.pop("agent_switch_error", None) # clear any previous error init_options_file.write_text(json.dumps(options, indent=2), encoding="utf-8") diff --git a/src/specify_cli/agent_pack.py b/src/specify_cli/agent_pack.py index 144a1a6e2..78f6de88d 100644 --- a/src/specify_cli/agent_pack.py +++ b/src/specify_cli/agent_pack.py @@ -721,6 +721,14 @@ def resolve_agent_pack( manifest_file = pack_dir / MANIFEST_FILENAME if manifest_file.is_file(): manifest = AgentManifest.from_yaml(manifest_file) + # Verify the manifest's declared ID matches the requested + # agent_id to prevent a malicious override from injecting + # a different ID (used for file paths and module names). + if manifest.id != agent_id: + raise PackResolutionError( + f"Agent pack manifest ID '{manifest.id}' does not match " + f"requested ID '{agent_id}' (in {pack_dir})." + ) if source == "embedded": embedded_manifest = manifest diff --git a/src/specify_cli/agents.py b/src/specify_cli/agents.py index 4f1ab728f..4165e3f3d 100644 --- a/src/specify_cli/agents.py +++ b/src/specify_cli/agents.py @@ -47,6 +47,12 @@ class CommandRegistrar: "args": "$ARGUMENTS", "extension": ".md" }, + "cursor-agent": { + "dir": ".cursor/commands", + "format": "markdown", + "args": "$ARGUMENTS", + "extension": ".md" + }, "qwen": { "dir": ".qwen/commands", "format": "markdown",