How HKUDS/CLI-Anything Handles Token Resolution for $-References in Style Fields

CLI‑Anything resolves $‑references in style fields by building a token map from user arguments and built-ins, then applying a regex substitution that replaces ${tokenName} with concrete values before sending the message to the Pi-Coding Agent.

The HKUDS/CLI-Anything extension enables dynamic command specifications through style fields containing $‑token placeholders. Understanding how this token resolution for $-references in style fields works reveals a deterministic pipeline that bridges user input with agent action.

Where Token Resolution Happens

The core logic resides in src/styleResolver.ts. This module exports a single function that performs the actual string substitution:

export function resolveStyleTokens(
  rawStyle: string,
  tokenMap: Record<string, string>
): string {
  return rawStyle.replace(/\${([^}]+)}/g, (_, name) =>
    tokenMap[name] ?? `\${${name}}`
  );
}

The function uses the regex /\$\{([^}]+)\}/g to scan the raw style string. For each captured token name, it returns the mapped value or leaves the placeholder intact if the token is undefined.

The Four-Step Resolution Pipeline

Step 1: Parse the Style Field

The extension reads the raw style string from a command specification asset, such as commands/cli-anything.md. These files declare visual styling or resource paths using ${...} syntax.

Step 2: Build the Token Map

Before rendering, CLI‑Anything constructs a tokenMap object containing:

  • User argument tokens — values extracted from the ${userArgs} block
  • Built-in path tokens — automatically injected system directories:
Token Resolves To
${guidesDir} Absolute path to the guides folder
${scriptsDir} Absolute path to the scripts folder
${templatesDir} Absolute path to the templates folder
${__dirname} Directory containing the extension itself

Step 3: Execute Regex Substitution

The resolveStyleTokens function iterates through all ${...} patterns. Unmatched tokens remain as placeholders, allowing the Pi-Coding Agent to request missing values later.

Step 4: Finalize for Agent Consumption

The fully resolved style string passes to pi.sendUserMessage. Because substitution occurs before the agent session begins, all filesystem references point to verified locations.

Entry Point Integration in index.ts

The extension entry point orchestrates token resolution before agent handoff:

const tokenMap = {
  guidesDir,
  scriptsDir,
  templatesDir,
  __dirname,
  // …additional tokens derived from userArgs
};
const style = resolveStyleTokens(commandMd, tokenMap);

This guarantees that any $‑reference in a style field resolves to a concrete value or a deliberate placeholder.

Practical Examples of $-Reference Resolution

Example 1: Built-in Directory Token

Command specification file (commands/cli-anything.md):


# cli-anything.md

...
style: "background: url(${templatesDir}/theme.png);"

When invoked with /cli-anything /path/to/app, the output becomes:

{
  "style": "background: url(/home/user/.cache/cli-anything/templates/theme.png);"
}

Example 2: User-Provided Token

// In index.ts
const userArgs = "theme=dark";
const tokenMap = {
  ...defaultTokens,
  theme: "dark"
};
const resolved = resolveStyleTokens('color: ${theme};', tokenMap);
// → "color: dark;"

Error Handling for Missing Tokens

The implementation deliberately preserves unmatched placeholders. Compare:

tokenMap[name] ?? `\${${name}}`

This fallback mechanism enables graceful degradation — the agent can detect unresolved tokens and request the missing value through its tool interface rather than failing silently or throwing errors.

Key Files in the Resolution System

File Purpose
src/styleResolver.ts Core ${token} substitution logic
index.ts Token map construction and orchestration
commands/cli-anything.md Command specs with style fields
templates/ Assets referenced via $‑references

Summary

  • Primary implementation: resolveStyleTokens() in src/styleResolver.ts handles all $‑reference substitution
  • Regex pattern: /\$\{([^}]+)\}/g extracts token names from style strings
  • Token sources: User arguments merge with built-in directory paths (guidesDir, scriptsDir, templatesDir, __dirname)
  • Safety mechanism: Unresolved tokens remain as placeholders for agent-side handling
  • Execution timing: Resolution occurs before pi.sendUserMessage, ensuring valid filesystem paths

Frequently Asked Questions

What happens if a $-reference token is missing?

The placeholder remains unchanged in the output string. The Pi-Coding Agent can then identify the unresolved token and request the missing value through its read tool, enabling interactive resolution rather than hard failures.

Can users define custom tokens beyond the built-in directories?

Yes. The tokenMap accepts arbitrary key-value pairs derived from the ${userArgs} block. Any argument parsed from user input can be injected into the map and referenced in style fields using standard ${customToken} syntax.

Why does CLI-Anything resolve tokens before sending to the agent?

Pre-resolution guarantees that all filesystem paths are absolute and verified before the agent session begins. This eliminates path resolution ambiguity, ensures the agent's read tool accesses correct assets immediately, and prevents directory traversal issues from unvalidated relative paths.

Where are the built-in directory tokens initialized?

The guidesDir, scriptsDir, and templatesDir tokens are computed in index.ts based on the extension's installation location and cached asset directories. These are combined with ${__dirname} (the extension's own directory) before being passed to resolveStyleTokens().

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →