{"_id":"@ariane-emory/must-have-plugin","_rev":"3-df337a5b45ed5d686e5934c014f24e96","name":"@ariane-emory/must-have-plugin","dist-tags":{"latest":"1.0.2"},"versions":{"1.0.0":{"name":"@ariane-emory/must-have-plugin","version":"1.0.0","keywords":["opencode","opencode-plugin","plugin","rfc2119","text-replacement"],"author":{"name":"Ariane Emory"},"license":"MIT","_id":"@ariane-emory/must-have-plugin@1.0.0","maintainers":[{"name":"ariane-emory","email":"ariane.emory@protonmail.com"}],"homepage":"https://github.com/ariane-emory/MUST-have-plugin#readme","bugs":{"url":"https://github.com/ariane-emory/MUST-have-plugin/issues"},"dist":{"shasum":"f413f1a297d8991c03a7b08beb1b9d082d47f4da","tarball":"https://registry.npmjs.org/@ariane-emory/must-have-plugin/-/must-have-plugin-1.0.0.tgz","fileCount":5,"integrity":"sha512-0CPUkDX8e4KDr/PNAp3yRhUXW+Bm1eqvOuepmaBvSWT8kvPfJd8PIGxuzys+RYQPT6RpScLZIuCWjJJiXsdNuA==","signatures":[{"sig":"MEUCIQCgKi49C8OjABKk8GuFnc6UPFPGMnd/ZgIxqxt4aNaa5wIgLTe6gRMb2GQHsjfmCNs4YD2N7H6tE0X2tZMe28xts1U=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":19766},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","$schema":"https://json.schemastore.org/package.json","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"b6cc771e8e83052a51333b3c0f6c1506f11813da","scripts":{"build":"tsc","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"ariane-emory","email":"ariane.emory@protonmail.com"},"repository":{"url":"git+https://github.com/ariane-emory/MUST-have-plugin.git","type":"git"},"_npmVersion":"11.8.0","description":"OpenCode plugin that applies configurable prompt text replacements, including RFC2119 keyword capitalization.","directories":{},"_nodeVersion":"25.2.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.2","@types/node":"^22.13.9","@opencode-ai/plugin":"^1.4.3"},"peerDependencies":{"@opencode-ai/plugin":">=1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/must-have-plugin_1.0.0_1775787104848_0.37009360469017905","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@ariane-emory/must-have-plugin","version":"1.0.1","keywords":["opencode","opencode-plugin","plugin","rfc2119","text-replacement"],"author":{"name":"Ariane Emory"},"license":"MIT","_id":"@ariane-emory/must-have-plugin@1.0.1","maintainers":[{"name":"ariane-emory","email":"ariane.emory@protonmail.com"}],"homepage":"https://github.com/ariane-emory/MUST-have-plugin#readme","bugs":{"url":"https://github.com/ariane-emory/MUST-have-plugin/issues"},"dist":{"shasum":"57db07cdc8a7c428fd33511c6fe23eab0f9adf0f","tarball":"https://registry.npmjs.org/@ariane-emory/must-have-plugin/-/must-have-plugin-1.0.1.tgz","fileCount":7,"integrity":"sha512-f3CAaF+FbaiSqHAnk0Rr7UFQKdHHI9EBs4JXFrXE9iRKj99cpJPxvK7vHgibEix0JCtBMsV5sAQv9AzuXa0fsA==","signatures":[{"sig":"MEYCIQD/YY7XR8rnM5+f4CYeBBpgEcjLS7KpTqixjTuSTHinfQIhAJq1jRHAocQd1FoH75YpiHd/8vHBVDdfqE+u38S5Sf+y","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":20056},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","$schema":"https://json.schemastore.org/package.json","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.js"}},"gitHead":"0904a1fd46248beda493bf72009547d25266bde3","scripts":{"build":"tsc","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"ariane-emory","email":"ariane.emory@protonmail.com"},"repository":{"url":"git+https://github.com/ariane-emory/MUST-have-plugin.git","type":"git"},"_npmVersion":"11.8.0","description":"OpenCode plugin that applies configurable prompt text replacements, including RFC2119 keyword capitalization.","directories":{},"_nodeVersion":"25.2.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.2","@types/node":"^22.13.9","@opencode-ai/plugin":"^1.4.3"},"peerDependencies":{"@opencode-ai/plugin":">=1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/must-have-plugin_1.0.1_1775788485742_0.9957416407292519","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"$schema":"https://json.schemastore.org/package.json","name":"@ariane-emory/must-have-plugin","version":"1.0.2","description":"OpenCode plugin that applies configurable prompt text replacements, including RFC2119 keyword capitalization.","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"},"./server":{"import":"./dist/server.js","types":"./dist/server.d.ts"}},"scripts":{"build":"tsc","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"keywords":["opencode","opencode-plugin","plugin","rfc2119","text-replacement"],"author":{"name":"Ariane Emory"},"license":"MIT","homepage":"https://github.com/ariane-emory/MUST-have-plugin#readme","repository":{"type":"git","url":"git+https://github.com/ariane-emory/MUST-have-plugin.git"},"bugs":{"url":"https://github.com/ariane-emory/MUST-have-plugin/issues"},"publishConfig":{"access":"public"},"peerDependencies":{"@opencode-ai/plugin":">=1.0.0"},"devDependencies":{"@opencode-ai/plugin":"^1.4.3","@types/node":"^22.13.9","typescript":"^5.8.2"},"gitHead":"31ede2fde3447f6de9b9a75572b1db1a5df59e1a","_id":"@ariane-emory/must-have-plugin@1.0.2","_nodeVersion":"25.2.1","_npmVersion":"11.8.0","dist":{"integrity":"sha512-pyDJ1PRsxbxngvdL0fs3NdB0P2fa9dv4Y20iEzw/KE0qlwwP2+eq62OCedVvtOk2u1hTB99UJ+YOUT7mxu811A==","shasum":"174a9e65aa684fc22d0f2ef09fa746846b295186","tarball":"https://registry.npmjs.org/@ariane-emory/must-have-plugin/-/must-have-plugin-1.0.2.tgz","fileCount":8,"unpackedSize":21794,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCID9bQz3fkJXbR0QyHQFwuO8YJfdz4mZkuF/k4UMLwznWAiEA6Bnm0gcyuhT5PLlv1QPcBAy8kHUMvqb/Tyj+QJxYSDk="}]},"_npmUser":{"name":"ariane-emory","email":"ariane.emory@protonmail.com"},"directories":{},"maintainers":[{"name":"ariane-emory","email":"ariane.emory@protonmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/must-have-plugin_1.0.2_1775831832431_0.6793931230402688"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-10T02:11:44.756Z","modified":"2026-04-10T14:37:12.693Z","1.0.0":"2026-04-10T02:11:45.004Z","1.0.1":"2026-04-10T02:34:45.889Z","1.0.2":"2026-04-10T14:37:12.579Z"},"bugs":{"url":"https://github.com/ariane-emory/MUST-have-plugin/issues"},"author":{"name":"Ariane Emory"},"license":"MIT","homepage":"https://github.com/ariane-emory/MUST-have-plugin#readme","keywords":["opencode","opencode-plugin","plugin","rfc2119","text-replacement"],"repository":{"type":"git","url":"git+https://github.com/ariane-emory/MUST-have-plugin.git"},"description":"OpenCode plugin that applies configurable prompt text replacements, including RFC2119 keyword capitalization.","maintainers":[{"name":"ariane-emory","email":"ariane.emory@protonmail.com"}],"readme":"# A MUST-have plugin\n\nAutomatically replaces text patterns in your prompts before they're sent to the LLM.\n\n## Installation\n\n### From npm\n\nAdd the published package to your OpenCode config:\n\n```json\n{\n  \"$schema\": \"https://opencode.ai/config.json\",\n  \"plugin\": [\"@ariane-emory/must-have-plugin\"]\n}\n```\n\nOpenCode installs npm plugins automatically at startup.\n\nThe published package also includes `MUST-have-plugin.custom-sample.jsonc` as a starter config you can copy into `~/.config/opencode/MUST-have-plugin.jsonc`.\n\n### From Source\n\n```bash\nnpm install\nnpm run build\n```\n\nThen copy the built file into your OpenCode plugins directory:\n\n```bash\nmkdir -p ~/.config/opencode/plugins\ncp dist/index.js ~/.config/opencode/plugins/MUST-have-plugin.js\n```\n\nThe sample config file is available at the package root as `MUST-have-plugin.custom-sample.jsonc`.\n\n## What It Does\n\nPerforms case-insensitive string replacements on user-typed prompts. The primary use case is auto-capitalizing RFC2119 keywords (MUST, SHOULD, MAY, etc.) in technical specifications.\n\n**Example**: Typing `\"the system must validate input\"` becomes `\"the system MUST validate input\"`.\n\n### Features\n\n- **Case-insensitive matching**: `must`, `Must`, and `MUST` all match\n- **Word boundary aware**: Won't replace `may` inside `maybe`\n- **Multi-word phrases**: `must not` is matched as a unit (before `must` alone)\n- **Hot reload**: Config changes take effect immediately (no restart needed)\n- **JSONC support**: Comments and trailing commas allowed in config file\n\n### Scope\n\n- Only replaces text in user-typed prompts\n- Does NOT modify file content attached via `@` mentions\n- Does NOT modify slash command output\n\n## Configuration\n\n**Config file**: `~/.config/opencode/MUST-have-plugin.jsonc`\n\nIf the config file doesn't exist, it's automatically created with RFC2119 defaults.\n\n### Default Configuration\n\n```jsonc\n{\n  // Uncomment to enable debug logging (logs appear in OpenCode's log file)\n  // \"debug\": true,\n\n  \"replacements\": {\n    \"must\": \"MUST\",\n    \"must not\": \"MUST NOT\",\n    \"required\": \"REQUIRED\",\n    \"shall\": \"SHALL\",\n    \"shall not\": \"SHALL NOT\",\n    \"should\": \"SHOULD\",\n    \"should not\": \"SHOULD NOT\",\n    \"recommended\": \"RECOMMENDED\",\n    \"not recommended\": \"NOT RECOMMENDED\",\n    \"may\": \"MAY\",\n    \"optional\": \"OPTIONAL\"\n  }\n}\n```\n\n### Custom Replacements\n\nAdd your own replacement pairs to the `replacements` object:\n\n```jsonc\n{\n  // Uncomment to enable debug logging (view with: tail -f /tmp/opencode-replacer-debug.log)\n  // \"debug\": true,\n\n  \"replacements\": {\n    \"bl.md\": \"~/.config/opencode/supplemental/md/branch-list.md\",\n    \"dfp\": \"Diagnose and fix this problem: \",\n    \"mnm\": \"Make no mistakes!\",\n    \"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\",\n\n    \"pto\": \"push that to origin,\",\n    \"mb\": \"return to the initial branch and merge the new branch back in.\",\n\n    \"always\": \"**ALWAYS**\",\n    \"ever\": \"**EVER**\",\n    \"head\": \"HEAD\",\n    \"may not\": \"**MAY NOT**\",\n    \"may\": \"**MAY**\",\n    \"must always\": \"**MUST ALWAYS**\",\n    \"must never\" : \"**MUST NEVER**\",\n    \"must not\" : \"**MUST NOT**\",\n    \"must\": \"**MUST**\",\n    \"mustn't\" : \"**MUST NOT**\",\n    \"never\": \"**NEVER**\",\n    \"not recommended\": \"**NOT RECOMMENDED**\",\n    \"nothing\": \"**NOTHING**\",\n    \"not\": \"**NOT**\",\n    \"optional\": \"**OPTIONAL**\",\n    \"ought\": \"**SHOULD**\",\n    \"oughtn't\": \"**SHOULD NOT**\",\n    \"recommended\": \"**RECOMMENDED**\",\n    \"required\": \"**REQUIRED**\",\n    \"shall not\": \"**SHALL NOT**\",\n    \"shan't\": \"**SHALL NOT**\",\n    \"shall\": \"**SHALL**\",\n    \"should not\": \"**SHOULD NOT**\",\n    \"shouldn't\": \"**SHOULD NOT**\",\n    \"should\": \"**SHOULD**\",\n  }\n}\n```\n\n### Configuration Options\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `debug` | boolean | `false` | Enable debug logging to OpenCode's log file |\n| `replacements` | object | RFC2119 keywords | Key-value pairs for text replacement |\n\n## Debug Logging\n\nLogs are written to OpenCode's unified log file using the SDK logging system.\n\n**Log location**: `~/.local/share/opencode/log/dev.log`\n\nEnable debug mode to see what replacements are being made:\n\n1. Edit `~/.config/opencode/MUST-have-plugin.jsonc`\n2. Uncomment or add `\"debug\": true`\n3. View logs in real-time (filtering by this plugin):\n\n```bash\ntail -f ~/.local/share/opencode/log/dev.log | grep \"MUST-have-plugin\"\n```\n\nOr view all recent plugin logs:\n\n```bash\ngrep \"MUST-have-plugin\" ~/.local/share/opencode/log/dev.log | tail -20\n```\n\n### Log Format\n\nLogs use OpenCode's standard format with structured metadata:\n\n```\nINFO  2026-01-20T15:30:42 +2ms service=MUST-have-plugin Plugin loaded\nINFO  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}}\n```\n\n## RFC2119 Keywords\n\nThe default configuration includes all keywords from [RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119), which defines requirement levels for use in technical specifications:\n\n| Keyword | Meaning |\n|---------|---------|\n| MUST / REQUIRED / SHALL | Absolute requirement |\n| MUST NOT / SHALL NOT | Absolute prohibition |\n| SHOULD / RECOMMENDED | Recommended, but valid reasons may exist to ignore |\n| SHOULD NOT / NOT RECOMMENDED | Not recommended, but may be acceptable in some cases |\n| MAY / OPTIONAL | Truly optional |\n\n## Troubleshooting\n\n### Replacements not working\n\n1. Check that the config file exists: `cat ~/.config/opencode/MUST-have-plugin.jsonc`\n2. Verify JSONC syntax is valid (comments and trailing commas are allowed)\n3. Enable debug mode and check the log file\n\n### Unexpected replacements\n\n- Replacements use word boundaries, so `must` won't match inside `customer`\n- Multi-word phrases are matched first, so `must not` won't become `MUST not`\n- Check for typos in your replacement keys\n\n### Config changes not taking effect\n\nThe plugin re-reads the config on every message, so changes should be immediate. If not:\n\n1. Verify you saved the config file\n2. Check for JSONC syntax errors\n3. Restart OpenCode as a last resort\n\n## Publishing\n\n```bash\nnpm install\nnpm login\nnpm run build\nnpm publish --access public\n```\n\n`npm 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.\n\nFor a preflight check before publishing, run `npm publish --dry-run`.\n","readmeFilename":"README.md"}