@ariane-emory/must-have-plugin
v1.0.2
Published
OpenCode plugin that applies configurable prompt text replacements, including RFC2119 keyword capitalization.
Maintainers
Readme
A MUST-have plugin
Automatically replaces text patterns in your prompts before they're sent to the LLM.
Installation
From npm
Add the published package to your OpenCode config:
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["@ariane-emory/must-have-plugin"]
}OpenCode installs npm plugins automatically at startup.
The published package also includes MUST-have-plugin.custom-sample.jsonc as a starter config you can copy into ~/.config/opencode/MUST-have-plugin.jsonc.
From Source
npm install
npm run buildThen copy the built file into your OpenCode plugins directory:
mkdir -p ~/.config/opencode/plugins
cp dist/index.js ~/.config/opencode/plugins/MUST-have-plugin.jsThe sample config file is available at the package root as MUST-have-plugin.custom-sample.jsonc.
What It Does
Performs case-insensitive string replacements on user-typed prompts. The primary use case is auto-capitalizing RFC2119 keywords (MUST, SHOULD, MAY, etc.) in technical specifications.
Example: Typing "the system must validate input" becomes "the system MUST validate input".
Features
- Case-insensitive matching:
must,Must, andMUSTall match - Word boundary aware: Won't replace
mayinsidemaybe - Multi-word phrases:
must notis matched as a unit (beforemustalone) - Hot reload: Config changes take effect immediately (no restart needed)
- JSONC support: Comments and trailing commas allowed in config file
Scope
- Only replaces text in user-typed prompts
- Does NOT modify file content attached via
@mentions - Does NOT modify slash command output
Configuration
Config file: ~/.config/opencode/MUST-have-plugin.jsonc
If the config file doesn't exist, it's automatically created with RFC2119 defaults.
Default Configuration
{
// Uncomment to enable debug logging (logs appear in OpenCode's log file)
// "debug": true,
"replacements": {
"must": "MUST",
"must not": "MUST NOT",
"required": "REQUIRED",
"shall": "SHALL",
"shall not": "SHALL NOT",
"should": "SHOULD",
"should not": "SHOULD NOT",
"recommended": "RECOMMENDED",
"not recommended": "NOT RECOMMENDED",
"may": "MAY",
"optional": "OPTIONAL"
}
}Custom Replacements
Add your own replacement pairs to the replacements object:
{
// Uncomment to enable debug logging (view with: tail -f /tmp/opencode-replacer-debug.log)
// "debug": true,
"replacements": {
"bl.md": "~/.config/opencode/supplemental/md/branch-list.md",
"dfp": "Diagnose and fix this problem: ",
"mnm": "Make no mistakes!",
"rfc!": "The key words \"**MUST**\", \"**MUST NOT**\", \"**REQUIRED**\", \"**SHALL**\", \"**SHALL NOT**\", \"**SHOULD**\", \"**SHOULD NOT**\", \"**RECOMMENDED**\", \"**MAY**\", and \"**OPTIONAL**\" in this message are to be interpreted as described in RFC2119.\n\n",
"pto": "push that to origin,",
"mb": "return to the initial branch and merge the new branch back in.",
"always": "**ALWAYS**",
"ever": "**EVER**",
"head": "HEAD",
"may not": "**MAY NOT**",
"may": "**MAY**",
"must always": "**MUST ALWAYS**",
"must never" : "**MUST NEVER**",
"must not" : "**MUST NOT**",
"must": "**MUST**",
"mustn't" : "**MUST NOT**",
"never": "**NEVER**",
"not recommended": "**NOT RECOMMENDED**",
"nothing": "**NOTHING**",
"not": "**NOT**",
"optional": "**OPTIONAL**",
"ought": "**SHOULD**",
"oughtn't": "**SHOULD NOT**",
"recommended": "**RECOMMENDED**",
"required": "**REQUIRED**",
"shall not": "**SHALL NOT**",
"shan't": "**SHALL NOT**",
"shall": "**SHALL**",
"should not": "**SHOULD NOT**",
"shouldn't": "**SHOULD NOT**",
"should": "**SHOULD**",
}
}Configuration Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| debug | boolean | false | Enable debug logging to OpenCode's log file |
| replacements | object | RFC2119 keywords | Key-value pairs for text replacement |
Debug Logging
Logs are written to OpenCode's unified log file using the SDK logging system.
Log location: ~/.local/share/opencode/log/dev.log
Enable debug mode to see what replacements are being made:
- Edit
~/.config/opencode/MUST-have-plugin.jsonc - Uncomment or add
"debug": true - View logs in real-time (filtering by this plugin):
tail -f ~/.local/share/opencode/log/dev.log | grep "MUST-have-plugin"Or view all recent plugin logs:
grep "MUST-have-plugin" ~/.local/share/opencode/log/dev.log | tail -20Log Format
Logs use OpenCode's standard format with structured metadata:
INFO 2026-01-20T15:30:42 +2ms service=MUST-have-plugin Plugin loaded
INFO 2026-01-20T15:31:05 +5ms service=MUST-have-plugin Applied 3 replacement(s) replacements={"must":{"value":"MUST","count":2},"should":{"value":"SHOULD","count":1}}RFC2119 Keywords
The default configuration includes all keywords from RFC 2119, which defines requirement levels for use in technical specifications:
| Keyword | Meaning | |---------|---------| | MUST / REQUIRED / SHALL | Absolute requirement | | MUST NOT / SHALL NOT | Absolute prohibition | | SHOULD / RECOMMENDED | Recommended, but valid reasons may exist to ignore | | SHOULD NOT / NOT RECOMMENDED | Not recommended, but may be acceptable in some cases | | MAY / OPTIONAL | Truly optional |
Troubleshooting
Replacements not working
- Check that the config file exists:
cat ~/.config/opencode/MUST-have-plugin.jsonc - Verify JSONC syntax is valid (comments and trailing commas are allowed)
- Enable debug mode and check the log file
Unexpected replacements
- Replacements use word boundaries, so
mustwon't match insidecustomer - Multi-word phrases are matched first, so
must notwon't becomeMUST not - Check for typos in your replacement keys
Config changes not taking effect
The plugin re-reads the config on every message, so changes should be immediate. If not:
- Verify you saved the config file
- Check for JSONC syntax errors
- Restart OpenCode as a last resort
Publishing
npm install
npm login
npm run build
npm publish --access publicnpm publish does not install dev dependencies for you. Run npm install first in a fresh checkout so typescript and @types/node are available for the prepublishOnly build.
For a preflight check before publishing, run npm publish --dry-run.
