Introduction

In the DSH plugin ecosystem, Steno focuses on solving the problem of repeatedly typing high-frequency commands. It uses the message.beforeSend hook to replace #tag with predefined full text before a message is sent. This plugin is maintained by JohnXu22786 and is released under the MIT license.

Core Features

  • Instant expansion: #tag in a message will be replaced with the configured full text before sending.
  • Multi-library management: Supports multiple YAML snippet libraries; priority follows load order, and duplicate tags trigger warnings.
  • Alias support: A single snippet can be bound to multiple trigger names (aliases).
  • Variable placeholders: Supports {{name}} and {{name:default}}, with values provided by the host.
  • Recursive composition: A snippet body can reference other #tag entries; built-in cycle detection, depth limit (default 8), and expansion count limit (default 200) are included.
  • Code protection: tags in fenced code blocks (``) and inline code () will not expand.
  • CLI tools: Provides command-line tools such as steno.save, steno.remove, and steno.search.

Installation and Initialization

Installing the plugin requires Node.js version >= 22.18.

  1. Install the plugin:
dsh plugin --profile demo add github:JohnXu22786/snippet-expander
  1. Initialize the configuration file:
npx dsh-steno init

After initialization, the default configuration file is located at ~/.dsh/steno/core.yaml.

Configuration and Usage

Edit the YAML file to add a snippet:

name: core
entries:
  - tag: careful
    aliases: [safe]
    description: strict mode
    body: |
      Reason step by reason, self-check before output, ask when in doubt, do not speculate.

Type #careful in a message, and the system will automatically replace it with the defined body text.

Matching Rules

  • The trigger format is # + tag name.
  • A tag must start with a letter (case-sensitive) and may contain letters, numbers, _, and -.
  • #123 and Markdown headings (such as # Heading) will not match.
  • In non-space languages such as Chinese, #tag can directly follow Chinese characters (e.g., 请#专注模式).
  • The escape form \#tag will output the literal #tag.
  • Tags inside code blocks will not expand.

Recursion and Limits

When a snippet body references another tag, the plugin performs recursive expansion, subject to the following limits:
1. Cycle detection: The same tag will not appear in its own expansion chain.
2. Depth limit: The default maximum depth is 8.
3. Count limit: A single message defaults to a maximum of 200 expansions.

Notes

  • Node version: Node.js >= 22.18 is required.
  • Library priority: Library files take priority by load order; earlier files override later files with the same tag name.
  • Placeholder behavior: {{name}} remains unchanged when no value is provided; {{name:default}} uses the default value; tag expansion inside placeholders is not supported.
  • Duplicate tags: Duplicate tags within the same library cause an error; duplicate tags across different libraries only trigger a warning, and the version loaded earlier is used.

References

  • GitHub repository: https://github.com/JohnXu22786/snippet-expander