Skip to content

Conversation

@Eric-Guo
Copy link
Contributor

@Eric-Guo Eric-Guo commented Jan 18, 2026

Close #5054

The key difference between this PR and #5092 is this PR allow ENV usage in markdown body.

I already including a real use case in document and give the warning of security concerns.

Notice current json configuration of prompt allow using ENV, so I think using ENV in markdown body should also allowed.

Other coding agent like kimi-cli using ENV in their system prompt, so security concerns is not as serious as the first sight.

Copilot AI review requested due to automatic review settings January 18, 2026 15:49
@github-actions
Copy link
Contributor

The following comment was made by an LLM, it may be inaccurate:

Potential Duplicate Found:

Why they're related: Both PRs address the same issue (#5054) and implement the exact same feature: {env:VAR} substitution support in markdown-based configuration files. PR #5092 appears to have already resolved this issue, so PR #9261 may be a duplicate.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request adds environment variable substitution functionality to markdown-based agent configuration parsing. Users can now use the {env:VAR_NAME} syntax in both frontmatter and prompt content of markdown agent files, with unset variables being replaced with empty strings.

Changes:

  • Added substituteEnv() function to perform environment variable replacement using {env:VAR} syntax
  • Integrated environment variable substitution into the markdown parsing pipeline
  • Added comprehensive test coverage for the new functionality including edge cases
  • Updated documentation with usage examples and security guidance

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
packages/opencode/src/config/markdown.ts Implements the substituteEnv function and integrates it into the parse pipeline
packages/opencode/test/config/markdown.test.ts Adds comprehensive test suite with proper environment variable setup/teardown
packages/opencode/test/config/fixtures/env-frontmatter.md Test fixture demonstrating env var substitution in both frontmatter and content
packages/web/src/content/docs/agents.mdx Documents the new feature with usage examples and security considerations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@ariane-emory
Copy link
Contributor

ariane-emory commented Jan 18, 2026

After consultation with a couple of models and further review of the code changes, I do believe that I have come to the conclusion that my take in #5092 does adhere more closely to the original requestor of the Issue's request in #5054 to provide replacement only in the YAML/frontmatter. The version here does expand the scope slightly by providing replacement throughout the body as well.

Whether this expansion in scope is desirable or not I'll leave to the maintainers to decide as I don't hold any strong opinion on that aspect myself.

In any case, either PR seems that it would give the original requestor the ability to do what they wanted to do surely the resolution of their issue would provide them with a pleasant surprise - and if they're happy, so am I, so hopefully one of these PRs will come in to a safe landing.

@Eric-Guo Eric-Guo force-pushed the substitute_env_in_markdown branch from b4be2bf to db8a8c2 Compare January 18, 2026 17:41
@Eric-Guo
Copy link
Contributor Author

Thanks your review, I update the document with my real usage, I need ENV in markdown body, so hoping this PR can be choosen. (otherwise, I have to write the prompt in jsonc....)

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +194 to +262
describe("ConfigMarkdown: env substitution", () => {
const tokenKey = "TEST_MCP_TOKEN"
const emptyKey = "EMPTY_ENV_VAR"
const prevToken = process.env[tokenKey]
const prevEmpty = process.env[emptyKey]
let parsed: Awaited<ReturnType<typeof ConfigMarkdown.parse>>

beforeAll(async () => {
process.env[tokenKey] = "abc123"
delete process.env[emptyKey]
parsed = await ConfigMarkdown.parse(import.meta.dir + "/fixtures/env-frontmatter.md")
})

afterAll(() => {
if (prevToken === undefined) delete process.env[tokenKey]
else process.env[tokenKey] = prevToken
if (prevEmpty === undefined) delete process.env[emptyKey]
else process.env[emptyKey] = prevEmpty
})

test("should substitute env vars in frontmatter", () => {
expect(parsed.data.description).toBe("Token is abc123")
})

test("should substitute missing env vars with empty string in frontmatter", () => {
expect(parsed.data.note).toBe("")
})

test("should substitute env vars in content", () => {
expect(parsed.content).toContain("Token: abc123")
expect(parsed.content).toContain("Missing: ")
})
})
Copy link

Copilot AI Jan 18, 2026

Choose a reason for hiding this comment

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

The test only verifies that env variables are replaced with their values or empty strings, but doesn't test edge cases like nested braces, malformed patterns, or special characters in variable names. Consider adding test cases for: 1) Multiple substitutions in the same line, 2) Variables with underscores and numbers, 3) Malformed patterns like {env:} or {env:VAR with spaces}, 4) Variables that contain special regex characters.

Copilot uses AI. Check for mistakes.
```markdown title="~/.config/opencode/agents/mcdonalds.md"
---
name: "McDonalds"
description: Agent to help you ordering McDonalds
Copy link

Copilot AI Jan 18, 2026

Choose a reason for hiding this comment

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

The description contains a grammatical error. It should be "Agent to help you order from McDonalds" instead of "Agent to help you ordering McDonalds".

Suggested change
description: Agent to help you ordering McDonalds
description: Agent to help you order from McDonalds

Copilot uses AI. Check for mistakes.
@ariane-emory
Copy link
Contributor

ariane-emory commented Jan 18, 2026

@Eric-Guo I expect that surely you must already be aware, but just in case: you can of course already achieve your terminal goal of using environment variable in the body by using shell expansions. It's not a markedly efficient way to do it, of course, since we're starting a whole shell just to get at an environment variable, but it does work, so it could perhaps suffice in the meantime.

Best of luck!

@Eric-Guo
Copy link
Contributor Author

Eric-Guo commented Jan 18, 2026

you can of course already achieve your terminal goal of using environment variable in the body by using shell expansions.

How to do that? I don't know it can, seems not mention in document.

It sounds useful but more crazy and less security (of course)...

But if I can do that, this PR is no need. 😊

@ariane-emory
Copy link
Contributor

ariane-emory commented Jan 18, 2026

You would do what is shown here: https://opencode.ai/docs/commands/#shell-output

Simply use a command such as echo ${SOME_ENVIRONMENT_VARIABLE}, as I show here in one of my own test commands (https://github.com/ariane-emory/opencode-config-supplemental/blob/main/command-disabled/debug-env.md):

Screenshot 2026-01-18 at 1 23 45 PM

As stated previously, it's probably not the most efficient way to do it, but it should work.

@Eric-Guo Eric-Guo force-pushed the substitute_env_in_markdown branch from c675b6e to 39dcd7b Compare January 19, 2026 01:11
@Eric-Guo
Copy link
Contributor Author

What I known is command is need to trigger by user, anyway to let the command being triggerd automatically at starting, without user need to do any action? i.e. system prompt can calling command directly?

If answer is no, it's more my need....

@ariane-emory
Copy link
Contributor

ariane-emory commented Jan 19, 2026

The commands in the shell expansions run each time you run the slash command. This is in most cases beneficial: after all, if you run the date command, you want the current date every time and if you run ls to see the files in a directory you presumably want to know what files are there right now, not what files used to be there an hour ago during startup. This probably isn't usually so important for echoing environment variables that are in most cases unlikely to change during runtime, but there could perhaps be some corner case that I'm overlooking. No, slash commands cannot be called mechanically by system prompts, they are meant to be invoked by the user.

@Eric-Guo Eric-Guo force-pushed the substitute_env_in_markdown branch 6 times, most recently from 6d02317 to 2fcd86e Compare January 22, 2026 02:53
@Eric-Guo Eric-Guo force-pushed the substitute_env_in_markdown branch 4 times, most recently from d5e033a to 9cfdf94 Compare January 28, 2026 07:02
@Eric-Guo Eric-Guo force-pushed the substitute_env_in_markdown branch 3 times, most recently from 4cc021c to becedb8 Compare January 29, 2026 11:45
opencode and others added 3 commits January 30, 2026 06:48
…ng sent back as assistant message content (anomalyco#11270)

Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
…nt definitions in .md now get env values injected before frontmatter/prompt parsing.
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.

[FEATURE]: {env:MY_VAR} support in agent yaml

3 participants