Skip to content

Commit 9cfea4a

Browse files
committed
refactor: replace $vars and <stdin> with _prefix template variables
- Change template variable syntax from $varname to _varname for LiquidJS compatibility - Replace <stdin> tag wrapping with _stdin template variable - CLI flags now use --_varname to match frontmatter _varname keys - Update all tests and documentation to reflect new syntax Breaking changes: - Template vars now use underscore prefix: _name instead of $name - Body syntax: {{ _name }} instead of {{ name }} - CLI override: --_name instead of --name - Stdin access: {{ _stdin }} instead of <stdin> tags
1 parent 43ca821 commit 9cfea4a

10 files changed

Lines changed: 212 additions & 233 deletions

CLAUDE.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ bun run md task.claude.md
6464

6565
- **`types.ts`** - Core TypeScript interfaces
6666
- `AgentFrontmatter`: Simple interface with system keys + passthrough
67-
- System keys: `args`, `env`, `$1`/`$2`/etc.
67+
- System keys: `_varname` (template vars), `env`, `$1`/`$2`/etc.
6868

6969
- **`schema.ts`** - Minimal Zod validation (system keys only, rest passthrough)
7070

@@ -91,7 +91,8 @@ Commands are resolved in priority order:
9191
### Frontmatter Keys
9292

9393
**System keys** (consumed by md, not passed to command):
94-
- `args`: Named positional arguments for template vars
94+
- `_varname`: Template variables (e.g., `_name: "default"``{{ _name }}` in body → `--_name` CLI flag)
95+
- `_stdin`: Auto-injected template variable containing piped input
9596
- `env` (object form): Sets process.env before execution
9697
- `$1`, `$2`, etc.: Map positional args to flags
9798
- `_interactive`: Enable interactive mode (overrides print-mode defaults)
@@ -151,10 +152,11 @@ commands:
151152
152153
Uses [LiquidJS](https://liquidjs.com/) for full template support:
153154
154-
- Variables: `{{ variable }}`
155-
- Conditionals: `{% if force %}--force{% endif %}`
156-
- Filters: `{{ name | upcase }}`, `{{ value | default: "fallback" }}`
157-
- `args:` frontmatter to consume CLI positionals as template vars
155+
- Variables: `{{ _varname }}` (use `_` prefix for template vars)
156+
- Stdin: `{{ _stdin }}` (auto-injected from piped input)
157+
- Conditionals: `{% if _force %}--force{% endif %}`
158+
- Filters: `{{ _name | upcase }}`, `{{ _value | default: "fallback" }}`
159+
- CLI override: `--_varname value` matches `_varname` in frontmatter
158160

159161
## Testing Patterns
160162

GUIDE.md

Lines changed: 54 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,22 @@ md 01-hello.claude.md
2828

2929
## 2. The Configurator
3030

31-
**Concept:** *Hijacked Flags & Defaults*
32-
Variables starting with `$` define defaults that can be overridden by CLI flags.
31+
**Concept:** *Template Variables & Defaults*
32+
Variables starting with `_` define defaults that can be overridden by CLI flags.
3333

3434
**File:** `02-config.gemini.md`
3535

3636
```markdown
3737
---
3838
model: gemini-1.5-flash
39-
# Default values
40-
$env: development
41-
$port: 8080
39+
# Template variables with defaults
40+
_env: development
41+
_port: 8080
4242
# Pass-through flags for Gemini
4343
temperature: 0.1
4444
json: true
4545
---
46-
Generate a JSON configuration for a server running in **{{ env }}** mode on port **{{ port }}**.
46+
Generate a JSON configuration for a server running in **{{ _env }}** mode on port **{{ _port }}**.
4747
Return ONLY the raw JSON.
4848
```
4949

@@ -54,28 +54,29 @@ Return ONLY the raw JSON.
5454
md 02-config.gemini.md
5555

5656
# Override with flags
57-
md 02-config.gemini.md --env production --port 3000
57+
md 02-config.gemini.md --_env production --_port 3000
5858
```
5959

6060
---
6161

6262
## 3. The Logic Gate
6363

64-
**Concept:** *Conditionals & Args*
65-
Use `args` to map positional arguments, and LiquidJS tags to change the prompt dynamically.
64+
**Concept:** *Conditionals & Template Variables*
65+
Use `_varname` to define template variables, and LiquidJS tags to change the prompt dynamically.
6666

6767
**File:** `03-deploy.copilot.md`
6868

6969
```markdown
7070
---
71-
args: [service_name, platform]
71+
_service_name: ""
72+
_platform: docker
7273
model: gpt-4
7374
---
74-
Generate a deployment script for {{ service_name }}.
75+
Generate a deployment script for {{ _service_name }}.
7576

76-
{% if platform == 'k8s' %}
77+
{% if _platform == 'k8s' %}
7778
Generate a Kubernetes Deployment YAML. Include liveness probes.
78-
{% elsif platform == 'aws' %}
79+
{% elsif _platform == 'aws' %}
7980
Generate an AWS Lambda SAM template.
8081
{% else %}
8182
Generate a simple Dockerfile.
@@ -85,7 +86,7 @@ Generate a simple Dockerfile.
8586
**Run it:**
8687

8788
```bash
88-
md 03-deploy.copilot.md "auth-service" "k8s"
89+
md 03-deploy.copilot.md --_service_name "auth-service" --_platform "k8s"
8990
```
9091

9192
---
@@ -177,15 +178,17 @@ md 06-audit.gemini.md
177178
## 7. The Unix Filter
178179

179180
**Concept:** *Standard Input (Stdin)*
180-
`md` automatically wraps piped input in `<stdin>` tags, allowing agents to act as filters in Unix pipes.
181+
Piped input is available as the `_stdin` template variable, allowing agents to act as filters in Unix pipes.
181182

182183
**File:** `07-describe-changes.claude.md`
183184

184185
```markdown
185186
---
186187
model: haiku
187188
---
188-
Generate a concise PR description for the changes in <stdin>.
189+
Generate a concise PR description for these changes:
190+
{{ _stdin }}
191+
189192
Include a "Summary" and "Key Changes" section.
190193
```
191194

@@ -208,7 +211,8 @@ Pipe the output of one agent (The Summarizer) into another (The Critic).
208211
---
209212
model: haiku
210213
---
211-
Summarize the file content in <stdin> into a high-level architecture description.
214+
Summarize the file content into a high-level architecture description:
215+
{{ _stdin }}
212216
```
213217

214218
**File:** `08b-critique.claude.md`
@@ -217,7 +221,9 @@ Summarize the file content in <stdin> into a high-level architecture description
217221
---
218222
model: opus
219223
---
220-
You are a Principal Engineer. Critique the architecture description provided in <stdin>.
224+
You are a Principal Engineer. Critique this architecture description:
225+
{{ _stdin }}
226+
221227
Identify bottlenecks and suggest scalability improvements.
222228
```
223229

@@ -257,25 +263,25 @@ An "Architect" agent generates a shell script that spawns multiple "Worker" agen
257263

258264
```markdown
259265
---
260-
args: [task]
266+
_task: ""
261267
model: sonnet
262268
---
263-
You are a worker bee. Implement this task in the current directory: {{ task }}
269+
You are a worker bee. Implement this task in the current directory: {{ _task }}
264270
Write the code to a file named `implementation.ts`.
265271
```
266272

267273
**The Architect:** `10-architect.claude.md`
268274

269275
```markdown
270276
---
271-
args: [goal]
277+
_goal: ""
272278
model: opus
273279
---
274-
You are a Fleet Commander. Break down the goal "{{ goal }}" into 2 parallel sub-tasks.
280+
You are a Fleet Commander. Break down the goal "{{ _goal }}" into 2 parallel sub-tasks.
275281

276282
Generate a BASH script that:
277283
1. Creates 2 git worktrees (`wt-frontend` and `wt-backend`) on new branches.
278-
2. Inside each worktree, runs `md ../10-worker.claude.md "sub-task description"`.
284+
2. Inside each worktree, runs `md ../10-worker.claude.md --_task "sub-task description"`.
279285
3. Runs them in the background (`&`) and `wait`s for them to finish.
280286

281287
Output ONLY the raw bash script.
@@ -286,7 +292,7 @@ Output ONLY the raw bash script.
286292
```bash
287293
# 1. The Architect creates the plan and script
288294
# 2. We pipe the script to sh to execute the swarm immediately
289-
md 10-architect.claude.md "Build a login page with a fastify backend" | sh
295+
md 10-architect.claude.md --_goal "Build a login page with a fastify backend" | sh
290296
```
291297

292298
---
@@ -300,22 +306,25 @@ While Part 1 focused on power and complexity, Part 2 focuses on **User Experienc
300306
## 11. The Interactive Wizard
301307

302308
**Concept:** *Variable Recovery*
303-
**UX Problem:** You wrote a prompt with variables, but you don't want to memorize the argument order.
309+
**UX Problem:** You wrote a prompt with variables, but you don't want to memorize the flags.
304310
**Solution:** If you forget to provide variables, `md` detects them and turns the CLI into an interactive form.
305311

306312
**File:** `11-onboarding.claude.md`
307313

308314
```markdown
309315
---
316+
_name: ""
317+
_department: ""
318+
_manager: ""
310319
model: sonnet
311320
---
312-
Welcome to the team, {{ name }}!
321+
Welcome to the team, {{ _name }}!
313322

314-
Please generate a warm onboarding email for a new engineer joining the {{ department }} team.
315-
Mention that their manager is {{ manager }}.
323+
Please generate a warm onboarding email for a new engineer joining the {{ _department }} team.
324+
Mention that their manager is {{ _manager }}.
316325
```
317326

318-
**Run it (without arguments):**
327+
**Run it (without flags):**
319328

320329
```bash
321330
md 11-onboarding.claude.md
@@ -325,9 +334,9 @@ md 11-onboarding.claude.md
325334

326335
```text
327336
Missing required variables. Please provide values:
328-
? name: Alice
329-
? department: Platform
330-
? manager: Bob
337+
? _name: Alice
338+
? _department: Platform
339+
? _manager: Bob
331340
```
332341

333342
*UX Benefit: Turns static scripts into interactive tools automatically.*
@@ -400,9 +409,9 @@ chmod +x daily-report
400409

401410
## 14. The "Knobs & Dials" Interface
402411

403-
**Concept:** *Hijacked Configuration ($vars)*
412+
**Concept:** *Template Variables with Defaults*
404413
**UX Problem:** You want to expose configuration settings (defaults) that users can easily override via flags.
405-
**Solution:** Variables starting with `$` in the frontmatter define defaults that are "hijacked" (consumed) by the template system.
414+
**Solution:** Variables starting with `_` in the frontmatter define defaults that can be overridden via `--_varname` flags.
406415

407416
**File:** `14-translator.gpt.md`
408417

@@ -411,24 +420,25 @@ chmod +x daily-report
411420
command: openai
412421
model: gpt-4o
413422
# Default configuration
414-
$lang: Spanish
415-
$tone: Professional
423+
_lang: Spanish
424+
_tone: Professional
425+
_text: ""
416426
---
417-
Translate the following text into {{ lang }}. Keep the tone {{ tone }}.
427+
Translate the following text into {{ _lang }}. Keep the tone {{ _tone }}.
418428

419429
<text>
420-
{{ $1 }}
430+
{{ _text }}
421431
</text>
422432
```
423433

424434
**Run it:**
425435

426436
```bash
427437
# Use defaults
428-
md 14-translator.gpt.md "Hello World"
438+
md 14-translator.gpt.md --_text "Hello World"
429439

430440
# Tweak the knobs via flags
431-
md 14-translator.gpt.md "Hello World" --lang "Pirate" --tone "Aggressive"
441+
md 14-translator.gpt.md --_text "Hello World" --_lang "Pirate" --_tone "Aggressive"
432442
```
433443

434444
*UX Benefit: Creates a stable CLI interface for your prompts.*
@@ -588,14 +598,14 @@ md logs
588598

589599
```markdown
590600
---
591-
args: [goal]
601+
_goal: ""
592602
model: sonnet
593603
---
594604
I want to create a new markdown-agent file.
595-
Goal: {{ goal }}
605+
Goal: {{ _goal }}
596606

597607
Write the full content of a `.md` file that accomplishes this.
598-
Include appropriate frontmatter defaults (model, args).
608+
Include appropriate frontmatter defaults (model, _varname template variables).
599609
Use standard `md` features like `@imports` if the goal implies reading code.
600610

601611
Output ONLY the raw markdown code block.
@@ -604,7 +614,7 @@ Output ONLY the raw markdown code block.
604614
**Run it:**
605615

606616
```bash
607-
md 20-agent-smith.claude.md "Review my rust code" > review-rust.claude.md
617+
md 20-agent-smith.claude.md --_goal "Review my rust code" > review-rust.claude.md
608618
```
609619

610620
*UX Benefit: The tool helps you build the tool.*

0 commit comments

Comments
 (0)