You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I searched existing issues and did not find a duplicate.
I am describing a concrete problem or use case, not just a vague idea.
Area
apps/desktop
Problem or use case
T3 Code delegates instruction loading to each provider's native discovery of hard-coded filenames: CLAUDE.md via settingSources for Claude, AGENTS.md for Codex. There is no way to say "also load this file, from this path, for this provider instance."
Two problems follow.
1. Provider instances pointed at a non-default backend have nowhere to put backend-specific rules.
A common setup is claudex: the Claude Code CLI driven against OpenAI's Codex backend through a local CLIProxyAPI on 127.0.0.1:8317, billed against a ChatGPT subscription, with ANTHROPIC_BASE_URL and ANTHROPIC_AUTH_TOKEN overridden. It is the same harness — same tools, same skills — with a different model underneath.
That configuration needs its own rules, because behaviour differs from stock Claude Code: ENABLE_TOOL_SEARCH is off (deferred-tool discovery is unreliable on non-Claude models), tool-use concurrency is capped (the backend handles bursts poorly), and the subagent roster differs. Those rules must apply to that provider instance only — they are wrong for a stock Claude thread — and there is currently no slot for them anywhere.
2. The Claude provider never sees AGENTS.md.
Claude Code discovers CLAUDE.md, not AGENTS.md. In a repo that standardised on AGENTS.md — as this one has — a Claude thread starts with the agent unaware of the repo's own conventions, and the user re-supplies them by hand in the first message of every thread. The file is sitting in the working directory; nothing reads it.
Proposed solution
A settings list of instruction files that T3 Code reads and assembles itself, instead of delegating to provider filename conventions.
Entries are paths — absolute, ~-relative, or repo-root-relative.
Two scopes — global (every project) and per-project (stored with the project, so a repo's own file is picked up automatically on switch).
Per-entry provider filter — claude, codex, *, or a specific provider instance. Rules written for one backend must not leak into a thread running on another.
Ordered; T3 reads and concatenates. All applicable entries are read in order, joined into one payload, and handed to the provider through its native mechanism (--append-system-prompt-file for Claude, the equivalent config path for Codex; or as prefix to the first prompt in the new chat).
Missing files are skipped, not fatal — with a visible note in the work log, so a typo'd path doesn't fail silently.
The concatenation is load-bearing, not an implementation detail: claude keeps only the last--append-system-prompt-file and silently discards earlier ones. Multiple sources can only be delivered as a single merged file.
Ordering and framing. When both user-level and repo-level entries are active, repo content should land after user-level content, wrapped in a short block identifying it as repository content, with the user-level rules re-asserted afterwards. A repo instruction file is third-party data — in a cloned repo it may be adversarial — and should not sit where it appears to override the user's own rules. Only whatever assembles the payload can apply that framing.
Why this matters
Anyone running a provider instance against a non-default backend needs per-instance rules, and today has nowhere to put them. If you working in an AGENTS.md repo through the Claude provider you may manually re-supplying context on every new thread.
Both are currently solved on my side with a shell wrapper that sits between the user and the CLI. That works from a terminal and is structurally impossible in T3 Code, because T3 Code invokes the provider itself — there is no seam for a launcher. Users who have this working in their terminal cannot bring it to the GUI, which is a concrete reason to keep a terminal open alongside T3 Code.
It also removes a class of silent failure. Passing the flag twice looks like it works and quietly drops the first file; a repo-relative path in a static argument string never resolves. Both fail without an error message.
Smallest useful scope
For the Claude provider, load the repo-root AGENTS.md in addition to CLAUDE.md.
For the Claudex, load the user CLAUDEX and repo-root AGENTS.md in addition to CLAUDE.md.
Alternatives considered
Launch arguments (#1971, #2892). The closest existing mechanism, and for one static absolute path it may already work. It cannot be extended to cover this:
The operation needed is file I/O, not an argument. Sources must be read from disk, concatenated, and framed before the CLI is invoked. Launch arguments are a static string; there is no read step in that path. Note that allowing repeated flags in the launch-args parser would not fix this — claude itself also keeps only the last one, so the merge is mandatory regardless of how arguments are stored.
Static strings are not interpolated against the working directory, so ./AGENTS.md cannot be expressed. Only an absolute path works, re-edited in settings on every project switch — which defeats the purpose for the most common case.
No project scope. Launch arguments belong to a provider instance, not a project.
No validation, ordering, or framing. Nothing checks the path exists or controls what lands where.
A wrapper script. What I use today outside T3 Code: it reads the claudex rules file and the repo's AGENTS.md, merges them into one temp file, frames the repo section as content that cannot override the rules above it, re-asserts those rules after it, passes the result via --append-system-prompt-file, refuses to launch if the rules file is missing, and rejects any user-supplied --append-system-prompt* flag that would silently replace the merged payload. Every step is file I/O and string assembly performed before the CLI starts — which is exactly why it cannot be expressed as configuration, and why it doesn't survive the move into T3 Code.
Symlinking AGENTS.md to CLAUDE.md. Works per-repo, pollutes the repo or the ignore file, and does nothing for problem 1.
Risks or tradeoffs
Prompt-injection surface. Auto-loading a repo file means cloning a repo can inject text into the system prompt. This is already true of native AGENTS.md/CLAUDE.md discovery, but a configurable list widens it. Mitigated by the framing block described above, and by keeping repo-scoped entries opt-in per project.
Provider divergence. Each provider has a different injection mechanism, and Codex's is config-based rather than a flag. The abstraction has to be "assemble a payload, hand it to the adapter" rather than "pass this flag."
Reload semantics. If a file changes mid-thread, is it re-read? Simplest answer is no — read at session start only — but it should be a stated choice rather than an accident.
Related in this repo: #1233 (global agent prompt, single fixed file, no provider filter), #1283 / #1334 (native Claude setting sources; standard filenames only), #2397 (session-scoped notes), #1971 / #2892 (provider launch arguments, the current workaround), #737 and #1740 (adjacent prompt/skill/subagent customisation).
Before submitting
Area
apps/desktop
Problem or use case
T3 Code delegates instruction loading to each provider's native discovery of hard-coded filenames:
CLAUDE.mdviasettingSourcesfor Claude,AGENTS.mdfor Codex. There is no way to say "also load this file, from this path, for this provider instance."Two problems follow.
1. Provider instances pointed at a non-default backend have nowhere to put backend-specific rules.
A common setup is claudex: the Claude Code CLI driven against OpenAI's Codex backend through a local CLIProxyAPI on
127.0.0.1:8317, billed against a ChatGPT subscription, withANTHROPIC_BASE_URLandANTHROPIC_AUTH_TOKENoverridden. It is the same harness — same tools, same skills — with a different model underneath.That configuration needs its own rules, because behaviour differs from stock Claude Code:
ENABLE_TOOL_SEARCHis off (deferred-tool discovery is unreliable on non-Claude models), tool-use concurrency is capped (the backend handles bursts poorly), and the subagent roster differs. Those rules must apply to that provider instance only — they are wrong for a stock Claude thread — and there is currently no slot for them anywhere.2. The Claude provider never sees
AGENTS.md.Claude Code discovers
CLAUDE.md, notAGENTS.md. In a repo that standardised onAGENTS.md— as this one has — a Claude thread starts with the agent unaware of the repo's own conventions, and the user re-supplies them by hand in the first message of every thread. The file is sitting in the working directory; nothing reads it.Proposed solution
A settings list of instruction files that T3 Code reads and assembles itself, instead of delegating to provider filename conventions.
~-relative, or repo-root-relative.claude,codex,*, or a specific provider instance. Rules written for one backend must not leak into a thread running on another.--append-system-prompt-filefor Claude, the equivalent config path for Codex; or as prefix to the first prompt in the new chat).The concatenation is load-bearing, not an implementation detail:
claudekeeps only the last--append-system-prompt-fileand silently discards earlier ones. Multiple sources can only be delivered as a single merged file.Ordering and framing. When both user-level and repo-level entries are active, repo content should land after user-level content, wrapped in a short block identifying it as repository content, with the user-level rules re-asserted afterwards. A repo instruction file is third-party data — in a cloned repo it may be adversarial — and should not sit where it appears to override the user's own rules. Only whatever assembles the payload can apply that framing.
Why this matters
Anyone running a provider instance against a non-default backend needs per-instance rules, and today has nowhere to put them. If you working in an
AGENTS.mdrepo through the Claude provider you may manually re-supplying context on every new thread.Both are currently solved on my side with a shell wrapper that sits between the user and the CLI. That works from a terminal and is structurally impossible in T3 Code, because T3 Code invokes the provider itself — there is no seam for a launcher. Users who have this working in their terminal cannot bring it to the GUI, which is a concrete reason to keep a terminal open alongside T3 Code.
It also removes a class of silent failure. Passing the flag twice looks like it works and quietly drops the first file; a repo-relative path in a static argument string never resolves. Both fail without an error message.
Smallest useful scope
AGENTS.mdin addition toCLAUDE.md.CLAUDEXand repo-rootAGENTS.mdin addition toCLAUDE.md.Alternatives considered
Launch arguments (#1971, #2892). The closest existing mechanism, and for one static absolute path it may already work. It cannot be extended to cover this:
claudeitself also keeps only the last one, so the merge is mandatory regardless of how arguments are stored../AGENTS.mdcannot be expressed. Only an absolute path works, re-edited in settings on every project switch — which defeats the purpose for the most common case.A wrapper script. What I use today outside T3 Code: it reads the claudex rules file and the repo's
AGENTS.md, merges them into one temp file, frames the repo section as content that cannot override the rules above it, re-asserts those rules after it, passes the result via--append-system-prompt-file, refuses to launch if the rules file is missing, and rejects any user-supplied--append-system-prompt*flag that would silently replace the merged payload. Every step is file I/O and string assembly performed before the CLI starts — which is exactly why it cannot be expressed as configuration, and why it doesn't survive the move into T3 Code.Symlinking
AGENTS.mdtoCLAUDE.md. Works per-repo, pollutes the repo or the ignore file, and does nothing for problem 1.Risks or tradeoffs
AGENTS.md/CLAUDE.mddiscovery, but a configurable list widens it. Mitigated by the framing block described above, and by keeping repo-scoped entries opt-in per project.Examples or references
claudex setup guide (the configuration described above): https://claude.ai/code/artifact/e0a0e13e-6f60-4615-8e4b-3a8b8e3d1c41
Prior art for the general shape — user-specified files merged into the system prompt, with scope layering:
ccc, a Claude Code launcher with global/preset/project configuration layers: https://github.com/3rd/ccc--append-system-prompt-filefamily that Claude Code already ships: Feature: Add system prompt customization flags openai/codex#11588Related in this repo: #1233 (global agent prompt, single fixed file, no provider filter), #1283 / #1334 (native Claude setting sources; standard filenames only), #2397 (session-scoped notes), #1971 / #2892 (provider launch arguments, the current workaround), #737 and #1740 (adjacent prompt/skill/subagent customisation).
Contribution