Skip to content

feat: ask a coding agent on this computer for help, with consent - #246

Open
autoidm-jon wants to merge 4 commits into
mainfrom
feat/coding-agents
Open

autoidm-jon wants to merge 4 commits into
mainfrom
feat/coding-agents

Conversation

@autoidm-jon

@autoidm-jon autoidm-jon commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Adds an internal ask(request, context) that finds Claude Code, Codex, or Cursor, asks the user once per agent for consent, and runs one read-only request at low effort with .env values removed. Inside an agent's own session it starts no second agent; python -m pdt.coding_agents shows what pdt finds.


Note

Medium Risk
Spawns local coding agents with file read access and handles secrets via redaction and env stripping; mistakes could leak credentials or widen agent capabilities despite sandbox flags.

Overview
Adds pdt.coding_agents with a single ask(request, context) API that can delegate help requests to Claude Code, Codex, or Cursor when those CLIs are on PATH. The flow picks an agent (stored preference in user settings.yml, or an interactive choice when several are allowed), prompts once per agent for consent, and runs a read-only, low-effort subprocess with agent-specific sandbox flags (e.g. no MCP/hooks for Claude, ignore user config/rules for Codex). .env secret values (4+ chars) are stripped from the payload and matching env vars are omitted from the child process; when pdt already runs inside an agent session it prints the formatted request instead of spawning another agent.

Scaffolded AGENTS.md now tells agents never to read, print, or change .env or secret values, pointing users to pdt validate / pdt secrets instead. python -m pdt.coding_agents exposes status and a manual ask path. Broad unit tests cover consent, multi-agent selection, secret handling, timeouts, and sandbox flags.

Reviewed by Cursor Bugbot for commit 31af184. Bugbot is set up for automated code reviews on this repo. Configure here.

@autoidm-jon

autoidm-jon commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor Author

Adversarial review: Codex gpt-6.1-sol, effort xhigh, three rounds

Goal, as the reviewer restated it: pdt should send a caller's prompt and chosen context to an installed Claude Code, Codex, or Cursor agent. It should remember consent separately for each agent in user settings. It should remember an agent choice only when necessary. Each request should use low effort and return the answer. Inside an existing agent session, pdt should provide the information without starting another agent. First consent requires an interactive terminal. Context must exclude secret values. This change should provide the general API and a way to try it, without implementing future scenarios.

# Round Severity Disposition Finding Action
1 1 Blocker 🟡 Partly fixed Secret values stayed in the text: process values, app-folder .env files, short values. Process values and <project>/*/.env are read. The 4-character minimum stays, because replacing 1 would change every "1" in a log.
2 1 Blocker ⏸ Open The agent can read .env itself with its own file tools. .env names are removed from the agent's environment, and the consent text says the agent can read files. Isolation is open.
3 1 Blocker ✅ Fixed Claude kept its MCP tools and hooks. --strict-mcp-config and disableAllHooks for Claude, --ignore-user-config for Codex.
4 1 Should-fix ✅ Fixed Cursor lost low effort when no -low model was listed. pdt sends nothing and says why.
5 1 Should-fix ✅ Fixed Agent calls had no timeouts; model discovery read stdin. Timeouts of 60 s and 300 s; discovery closes stdin.
6 1 Should-fix ✅ Fixed Two commands at the same time could lose a consent. Config lock and atomic write.
7 1 Should-fix ✅ Fixed With no terminal, pdt rejected the only allowed agent. With no terminal, agents with stored consent count.
8 1 Should-fix ✅ Fixed A settings file of the wrong shape gave a traceback. ConfigError names the file and the key.
9 2 Should-fix ✅ Fixed A project .env was missed when PDT_PROJECT names another folder. Read from the project folder.
10 2 Should-fix ✅ Fixed cursor-agent models got the full environment. Secret names removed.
11 2 Should-fix ✅ Fixed All discovery failures printed the same message. One reason for each kind of failure.
12 2 Should-fix ⏸ Open A timeout stops only the direct child process. Not fixed in this PR.
13 2 Should-fix ⏸ Open Managed Claude hooks, Codex hooks outside config.toml, and Cursor hooks still run. Open, together with item 2.
14 2 Should-fix ✅ Fixed The consent text did not state the 4-character rule. Added.
15 3 Should-fix ✅ Fixed On Windows, a lowercase .env name did not match the uppercase environment name. Case-insensitive match, with a test.

Open decisions: items 2 and 13 (how far to keep .env away from the agent), item 12: not part of this PR.

Round 3 confirmed the round-2 fixes.

@github-actions

Copy link
Copy Markdown

PR tier: tier::architectural (rules said review; Claude raised it)

  • raised from review: src/pdt/coding_agents.py adds two persisted config keys, coding-agent and coding-agent-consent, in a new user-level settings file ~/.local/share/pdt/settings.yml that AGENTS.md's list of files written outside the project does not cover
  • it is secret handling: env_secrets() harvests every .env value plus the matching os.environ values and redacts them by substring with a 4-character floor before handing text and a filtered env to a third-party process
  • it depends on third-party CLIs pdt cannot install (shutil.which on claude/codex/cursor-agent, otherwise it prints 'pdt found no coding agent'), against the guiding principle that a required tool installs itself
  • no caller exists: grep for coding_agents outside the module and its test finds nothing, no cli.py command and no AGENTS.md rule, so the intended user-facing surface is not determinable from the diff

A changed diff is scored again. Job log: https://github.com/AutoIDM/pdt/actions/runs/39282021156

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 3 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2eec78f. Configure here.

Comment thread src/pdt/coding_agents.py
low = next((model for model in models if model.endswith("-low")), None)
if low is None:
raise AgentCommandError(f"{program} models lists no low-effort model for your account")
return [program, "-p", "--trust", "--mode", "ask", "--model", low]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor run skips MCP and hook isolation

Medium Severity

Claude and Codex are launched so user MCP servers and hooks cannot run, but the Cursor command is only -p --trust --mode ask. Consent still says the agent cannot change files. User Cursor MCP servers and hooks can still load and take actions that --mode ask does not cover.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 2eec78f. Configure here.

Comment thread src/pdt/coding_agents.py Outdated
text = "\n\n".join([request, *(f"## {heading}\n{body}" for heading, body in context.items())])
for value in sorted(secrets, key=len, reverse=True):
text = text.replace(value, REMOVED)
return text

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Common env values redact the prompt

Medium Severity

Every .env value of four or more characters is substring-replaced in the request. Ordinary flag values such as true, false, none, info, and prod are treated as secrets, so much of the prompt can become <secret removed> and the agent gets a mangled question.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 2eec78f. Configure here.

Comment thread src/pdt/coding_agents.py Outdated
if not isinstance(answers, dict) or not all(isinstance(answer, bool)
for answer in answers.values()):
raise ConfigError(f"{SETTINGS}: {CONSENT_KEY} must list each coding agent with true "
"or false, for example `claude: false` on its own line under it")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Consent validation accepts falsy mappings

Low Severity

read_settings does settings.get(CONSENT_KEY) or {} before checking the type, so YAML false, [], or 0 for coding-agent-consent is treated as an empty mapping instead of a ConfigError. Editing the key to false to revoke consent is silently ignored and pdt prompts again.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 2eec78f. Configure here.

@github-actions

Copy link
Copy Markdown

PR tier: tier::architectural (rules said review; Claude raised it)

  • src/pdt/coding_agents.py adds two user-level config keys (coding-agent, coding-agent-consent) in a brand-new settings.yml under data_home(), where every existing path there is a cache or download; AGENTS.md is not updated
  • Secret handling: env_secrets()/message() redact .env values by substring match with a 4-char floor before sending text to a third-party coding agent, and strip those names from the child env
  • New external execution path: subprocess.run launches claude/codex/cursor-agent with hand-tuned sandbox flags, a dependency on tools pdt does not install, contrary to the install-itself principle
  • Purpose is not fully determinable: no cli.py or command wiring calls ask(); the only entry point is python -m pdt.coding_agents

A changed diff is scored again. Job log: https://github.com/AutoIDM/pdt/actions/runs/39415480829

@autoidm-jon

autoidm-jon commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor Author

Code review of 31af1840..6cf93ad1

Goal: pdt can get help from a coding agent on the local computer when an error occurs, after a single consent that the user can turn off.

Reviewer: Codex gpt-6.1-sol at xhigh. Checks on 6cf93ad1: uv run pytest -q 2128 passed and 1 skipped, uv run --group dev ruff check passed.

# Severity Disposition Finding Action
N1 nit ⏸️ Open Claude Code applies a Read deny rule to Grep and Glob as best effort, and Glob still returns file paths (docs). The Read(//**/.env) rule is the documented syntax, but it does not guarantee that no .env content reaches the agent. The text rule at the start of each message is the second protection. None in this PR.
N2 nit ⏸️ Not changed A settings file from an earlier build of this PR, with one answer per agent, now gives coding-agent-consent must be true or false when pdt calls an agent. Ordinary pdt commands still work. No release contains the per-agent format. None: the format never shipped.

Checks that passed:

  • The question asks for permission to use a coding agent on this computer when the agent can help, and No is the default. ask() checks for an installed agent, then asks for consent, then chooses the agent. No start-up path asks.
  • false stops every call, also when an agent choice is stored.
  • With no terminal, a missing or false consent sends nothing. With several agents and no stored choice, pdt prints guidance and calls none.

@github-actions

github-actions Bot commented Nov 4, 2026

Copy link
Copy Markdown

PR tier: tier::architectural (rules said review; Claude raised it)

  • src/pdt/coding_agents.py is built around secret handling: env_secrets() reads every .env, message() redacts values at SHORTEST_SECRET = 4 so shorter or reformatted secrets leak, and the child env is filtered by name; AGENTS.md lists secret or credential handling as architectural
  • Adds a new user-level config file and two keys, SETTINGS = config.data_home() / 'pdt' / 'settings.yml' with 'coding-agent' and 'coding-agent-consent', a config surface AGENTS.md's config rules do not describe
  • Introduces a new external runtime: subprocess calls to third-party claude/codex/cursor-agent CLIs whose sandboxing depends on per-vendor flags (--strict-mcp-config, --ignore-rules, -s read-only, --mode ask) that differ per tool and will drift
  • src/pdt/scaffold.py changes the AGENTS.md rules pdt writes into every user project, adding a directive about .env and pdt secrets

A changed diff is scored again. Job log: https://github.com/AutoIDM/pdt/actions/runs/41847620266

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant