Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
158 commits
Select commit Hold shift + click to select a range
90ad37f
feat: add {env:VAR} interpolation support to markdown frontmatter
ariane-emory Dec 5, 2025
4c89ebc
refactor: extract interpolateData function to reduce code churn
ariane-emory Dec 5, 2025
dbeeb67
refactor: reduce test code churn with helper function
ariane-emory Dec 5, 2025
7d498f9
refactor: rename interpolateData to interpolateEnvironmentVariables f…
ariane-emory Dec 5, 2025
c8f4921
Merge remote-tracking branch 'upstream/dev' into feat/markdown-frontm…
ariane-emory Dec 5, 2025
f277413
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 5, 2025
6cb3bb7
Merge remote-tracking branch 'upstream/dev' into feat/markdown-frontm…
ariane-emory Dec 5, 2025
454362e
Merge remote-tracking branch 'upstream/dev' into feat/markdown-frontm…
ariane-emory Dec 6, 2025
c3ae916
Merge remote-tracking branch 'upstream/dev' into feat/markdown-frontm…
ariane-emory Dec 6, 2025
e2b89fb
Merge remote-tracking branch 'upstream/dev' into feat/markdown-frontm…
ariane-emory Dec 7, 2025
8150897
Merge remote-tracking branch 'upstream/dev' into feat/markdown-frontm…
ariane-emory Dec 7, 2025
9d348b5
Merge remote-tracking branch 'upstream/dev' into feat/markdown-frontm…
ariane-emory Dec 7, 2025
b45b2d7
Merge remote-tracking branch 'upstream/dev' into feat/markdown-frontm…
ariane-emory Dec 7, 2025
0aadeea
Merge remote-tracking branch 'upstream/dev' into feat/markdown-frontm…
ariane-emory Dec 8, 2025
9f0cb53
Merge remote-tracking branch 'upstream/dev' into feat/markdown-frontm…
ariane-emory Dec 8, 2025
7a1f904
Fix TypeScript error: remove cacheKey from FileContents interface usage
ariane-emory Dec 8, 2025
14f7851
revert file
ariane-emory Dec 8, 2025
1f8d1f1
Merge remote-tracking branch 'upstream/dev' into feat/markdown-frontm…
ariane-emory Dec 9, 2025
9f2e75d
Merge remote-tracking branch 'upstream/dev' into feat/markdown-frontm…
ariane-emory Dec 9, 2025
43297fc
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 9, 2025
0d32508
Merge remote-tracking branch 'upstream/dev' into feat/markdown-frontm…
ariane-emory Dec 10, 2025
96b0905
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 10, 2025
2ef2b89
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 10, 2025
a7684bd
Merge remote-tracking branch 'upstream/dev' into feat/markdown-frontm…
ariane-emory Dec 10, 2025
eac918d
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 10, 2025
c6b21a0
Merge remote-tracking branch 'upstream/dev' into feat/markdown-frontm…
ariane-emory Dec 10, 2025
2eece5e
Fix type error: useKittyKeyboard should be boolean
ariane-emory Dec 10, 2025
6e1a875
Merge remote-tracking branch 'upstream/dev' into feat/markdown-frontm…
ariane-emory Dec 10, 2025
729a402
fix: uncorrupt
ariane-emory Dec 11, 2025
e6a0675
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 11, 2025
3a7dc58
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 11, 2025
7bcb694
Merge branch 'dev' into repair/feat/markdown-frontmatter-interpolation
ariane-emory Dec 13, 2025
f5571b0
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 17, 2025
bcbee72
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 17, 2025
1aff921
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 18, 2025
c6b4627
Merge remote-tracking branch 'origin/dev' into feat/markdown-frontmat…
ariane-emory Dec 19, 2025
f043f65
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 19, 2025
a1c7091
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 20, 2025
9afaa8b
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 20, 2025
1390765
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 21, 2025
b583399
Update generated types after merge from dev
ariane-emory Dec 21, 2025
eb0e297
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 22, 2025
b0fceec
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 23, 2025
e71fd22
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 23, 2025
74856a8
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 23, 2025
67d1a88
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 23, 2025
b894d65
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 23, 2025
d7a1efe
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 24, 2025
3a379c1
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 24, 2025
b0782f9
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 24, 2025
16bfd74
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 24, 2025
1138764
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 25, 2025
5ad2e40
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 25, 2025
1b31e18
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 25, 2025
253f241
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 26, 2025
2af2d25
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 27, 2025
c15e41e
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 27, 2025
d15a0de
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 27, 2025
3e4e2dc
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 28, 2025
de9bf17
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 28, 2025
f20dbbe
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 28, 2025
d95d241
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 29, 2025
e94328a
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 29, 2025
782bd09
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 29, 2025
abb0f9c
Merge branch 'feat/markdown-frontmatter-interpolation' of github.com:…
ariane-emory Dec 29, 2025
2926707
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 29, 2025
e2ecfa1
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 29, 2025
1f558d9
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 29, 2025
0406a83
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 30, 2025
ad8cb42
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 30, 2025
a5d3f46
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 30, 2025
2282a5a
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 30, 2025
bbdd409
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 30, 2025
c61c763
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 30, 2025
bc4632b
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Dec 31, 2025
d8c2bfd
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 1, 2026
9046075
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 1, 2026
1eca9a5
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 1, 2026
874ffe1
Merge remote-tracking branch 'origin/dev' into feat/markdown-frontmat…
ariane-emory Jan 2, 2026
13b4909
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 3, 2026
daefe6a
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 3, 2026
3dfb635
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 4, 2026
ce78333
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 4, 2026
4ce8c6a
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 4, 2026
9219614
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 5, 2026
0ac8c53
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 5, 2026
0fcbead
tidy: refert a file
ariane-emory Jan 5, 2026
aff971e
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 5, 2026
da4c3fb
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 5, 2026
1094029
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 6, 2026
4eb3e4d
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 6, 2026
02e162a
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 6, 2026
cd4371c
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 6, 2026
d0c7970
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 6, 2026
b6359ae
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 7, 2026
74438c7
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 7, 2026
4807650
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 7, 2026
1280cf9
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 7, 2026
3b948be
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 7, 2026
1ce4247
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 11, 2026
3619415
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 13, 2026
a517299
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 13, 2026
ffa8c9f
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 13, 2026
2f0d623
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 15, 2026
5544473
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 16, 2026
cc9d27c
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 17, 2026
a745adc
Resolve merge conflict in markdown.ts - remove conflict markers
ariane-emory Jan 17, 2026
5a3b95f
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 17, 2026
67eb048
docs: document {env:VAR} interpolation in markdown frontmatter
ariane-emory Jan 18, 2026
5a81820
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 19, 2026
0d1f079
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 20, 2026
78b3678
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 22, 2026
0afc214
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 23, 2026
b76263e
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 25, 2026
bf22bde
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 25, 2026
a1f628f
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 26, 2026
ef46618
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 27, 2026
6992cf2
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 29, 2026
e736c6d
Merge dev into feat/markdown-frontmatter-interpolation
ariane-emory Jan 29, 2026
7ab2f54
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Jan 30, 2026
58acbf5
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Feb 1, 2026
b7a9813
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Feb 2, 2026
1e34364
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Feb 3, 2026
ed1b402
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Feb 4, 2026
9394ede
Add keybinding for toggle thinking display
ariane-emory Feb 4, 2026
b4008e8
Change thinking_toggle default to none
ariane-emory Feb 4, 2026
4fea247
Rename thinking_toggle to display_thinking
ariane-emory Feb 4, 2026
675721b
Merge branch 'dev' into feat/keybindable-hide-show-thinking-toggle
ariane-emory Feb 4, 2026
5b7c6dc
Merge dev into feat/markdown-frontmatter-interpolation
ariane-emory Feb 4, 2026
30f4c07
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Feb 5, 2026
615ecd6
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Feb 6, 2026
1a574b6
Merge dev into feat/markdown-frontmatter-interpolation
ariane-emory Feb 7, 2026
bff40c8
Merge dev into feat/markdown-frontmatter-interpolation
ariane-emory Feb 10, 2026
99bacce
Merge branch 'feat/markdown-frontmatter-interpolation' of github.com:…
ariane-emory Feb 10, 2026
131ecc1
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Feb 11, 2026
17b0bd1
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Feb 12, 2026
7d9db06
Merge dev into feat/markdown-frontmatter-interpolation
ariane-emory Feb 13, 2026
870307c
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Feb 14, 2026
aa5b571
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Feb 15, 2026
11e4c1a
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Feb 15, 2026
e336e37
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Feb 17, 2026
3fa5531
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Feb 19, 2026
b7cf51f
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Feb 19, 2026
71cd794
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Feb 20, 2026
c05688f
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Feb 20, 2026
59d2ac6
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Feb 21, 2026
ef8bd9d
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Feb 26, 2026
f77aa77
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Feb 26, 2026
70fe5e4
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Mar 5, 2026
b7a893b
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Mar 8, 2026
59ffd2c
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Mar 8, 2026
06c14ba
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Mar 13, 2026
55267d0
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Mar 20, 2026
8e251a8
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Mar 20, 2026
b77d343
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Mar 24, 2026
3d966b8
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Mar 24, 2026
a03b9cc
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Mar 24, 2026
87a1966
Merge branch 'dev' into feat/markdown-frontmatter-interpolation
ariane-emory Apr 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions packages/opencode/src/config/markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,30 @@ export namespace ConfigMarkdown {
return content.replace(frontmatter, () => processed)
}

// Perform {env:VAR} interpolation on frontmatter data only
function interpolateEnvironmentVariables(obj: any): any {
if (typeof obj === "string") {
return obj.replace(/\{env:([^}]+)\}/g, (_, varName) => {
return process.env[varName] || ""
})
} else if (Array.isArray(obj)) {
return obj.map(interpolateEnvironmentVariables)
} else if (obj && typeof obj === "object") {
const result: any = {}
for (const [key, value] of Object.entries(obj)) {
result[key] = interpolateEnvironmentVariables(value)
}
return result
}
return obj
}

export async function parse(filePath: string) {
const template = await Filesystem.readText(filePath)

try {
const md = matter(template)
md.data = interpolateEnvironmentVariables(md.data)
return md
} catch {
try {
Expand Down
85 changes: 85 additions & 0 deletions packages/opencode/test/config/markdown.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,3 +226,88 @@ describe("ConfigMarkdown: frontmatter has weird model id", async () => {
expect(result.content.trim()).toBe("Strictly follow da rules")
})
})

// Helper function to reduce test code duplication
async function parseMarkdownWithEnv(markdown: string) {
const tempFile = `/tmp/test-agent-${Date.now()}.md`
await Bun.write(tempFile, markdown)
try {
return await ConfigMarkdown.parse(tempFile)
} finally {
await Bun.file(tempFile).delete()
}
}

// Tests for {env:VAR} interpolation in frontmatter
test("should interpolate {env:VAR} in frontmatter", async () => {
process.env.TEST_MODEL = "gpt-4"
process.env.TEST_DESCRIPTION = "Test agent description"

const markdownWithEnv = `---
description: "{env:TEST_DESCRIPTION}"
model: "{env:TEST_MODEL}"
mode: primary
---

# Agent Content

This is the agent content.`

const result = await parseMarkdownWithEnv(markdownWithEnv)

expect(result.data.description).toBe("Test agent description")
expect(result.data.model).toBe("gpt-4")
expect(result.data.mode).toBe("primary")
expect(result.content).toContain("Agent Content")
})

test("should handle missing environment variables gracefully", async () => {
delete process.env.NONEXISTENT_VAR

const markdownWithMissingEnv = `---
description: "Description with {env:NONEXISTENT_VAR} missing"
model: "gpt-3.5-turbo"
---

# Agent Content`

const result = await parseMarkdownWithEnv(markdownWithMissingEnv)

expect(result.data.description).toBe("Description with missing")
expect(result.data.model).toBe("gpt-3.5-turbo")
})

test("should interpolate multiple environment variables in same field", async () => {
process.env.PREFIX = "AI"
process.env.SUFFIX = "Assistant"

const markdownWithMultipleEnv = `---
description: "{env:PREFIX} {env:SUFFIX}"
model: "gpt-4"
---

# Agent Content`

const result = await parseMarkdownWithEnv(markdownWithMultipleEnv)

expect(result.data.description).toBe("AI Assistant")
expect(result.data.model).toBe("gpt-4")
})

test("should not interpolate {env:VAR} in markdown body content", async () => {
process.env.BODY_VAR = "should not appear"

const markdownWithEnvInBody = `---
description: "Test agent"
model: "gpt-4"
---

# Agent Content

This should not interpolate: {env:BODY_VAR}`

const result = await parseMarkdownWithEnv(markdownWithEnvInBody)

expect(result.data.description).toBe("Test agent")
expect(result.content).toContain("{env:BODY_VAR}")
})
39 changes: 39 additions & 0 deletions packages/web/src/content/docs/agents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,45 @@ Provide constructive feedback without making direct changes.

The markdown file name becomes the agent name. For example, `review.md` creates a `review` agent.

#### Environment variables

You can use environment variables in markdown agent frontmatter using the `{env:VAR_NAME}` syntax. This is useful for dynamic configuration, such as selecting models based on environment.

```markdown title="~/.config/opencode/agents/flexible.md"
---
description: "Agent using environment-configured model"
mode: primary
model: "{env:OPENCODE_MODEL}"
---

Your prompt content here.
```

If the environment variable is not set, it will be replaced with an empty string.

:::note
Environment variable interpolation only applies to frontmatter fields, not to the markdown body content. This prevents accidental substitution of `{env:VAR}` patterns that may appear as examples or documentation in your prompt.
:::

This enables workflows like tiered model selection:

```bash frame="none"
# Set different models for different purposes
export OPENCODE_HIGH_MODEL=anthropic/claude-opus-4-5
export OPENCODE_MID_MODEL=anthropic/claude-sonnet-4-20250514
export OPENCODE_LOW_MODEL=anthropic/claude-haiku-4-20250514
```

Then reference them in your agents:

```markdown title="~/.config/opencode/agents/planner.md"
---
description: "High-capability planning agent"
mode: primary
model: "{env:OPENCODE_HIGH_MODEL}"
---
```

---

## Options
Expand Down
Loading