pi-must-have-extension 0.4.7 → 0.4.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.4.9] - 2026-04-01
4
+
5
+ ### Changed
6
+ - Fixed image link and README formatting
7
+ - Added npm keywords for discoverability (`pi-package`, `pi-extension`, `pi-coding-agent`, `coding-agent`)
8
+ - Added Related Pi Extensions cross-linking section to README
9
+
10
+ ## [0.4.8] - 2026-04-01
11
+
12
+ ### Changed
13
+ - Updated `@mariozechner/pi-coding-agent` peer dependency to ^0.64.0
14
+ - Updated `typescript` dev dependency to ^6.0.2
15
+
3
16
  ## [0.4.7] - 2026-03-23
4
17
 
5
18
  ### Changed
package/README.md CHANGED
@@ -1,178 +1,186 @@
1
- # pi-must-have-extension
2
-
3
- Normalize RFC 2119 language in Pi prompts by automatically rewriting lowercase modal terms (`must`, `should not`, `optional`) into uppercase normative forms (`MUST`, `SHOULD NOT`, `OPTIONAL`).
4
-
5
- ![pi-must-have-extension](https://raw.githubusercontent.com/MasuRii/pi-must-have-extension/main/asset/pi-must-have-extension.png)
6
-
7
- ## Demo
8
-
9
- [![Watch demo video](https://raw.githubusercontent.com/MasuRii/pi-must-have-extension/main/asset/pi-must-have-extension.png)](https://github.com/user-attachments/assets/22149125-8976-4d06-98cb-e7cfa180476d)
10
-
11
- ## Features
12
-
13
- - **RFC 2119/8174 compliance** — Transforms modal keywords to standard uppercase notation
14
- - **Intelligent matching** — Case-insensitive with longest-first phrase replacement
15
- - **Word-boundary aware** — Does not replace keywords embedded inside larger words
16
- - **Configurable replacements** — Customize or extend the default keyword mappings
17
- - **Input filtering** — Leaves slash commands (`/`) and shell input (`!`) unchanged
18
- - **Auto-configuration** — Creates a default config file when none exists
19
- - **Legacy migration** — Automatically migrates configs from previous plugin versions
20
- - **Debug mode** — Optional TUI notifications showing replacement counts
21
-
22
- ## Installation
23
-
24
- ### Local Extension Folder
25
-
26
- Copy this repository to one of the following locations:
27
-
28
- ```text
29
- ~/.pi/agent/extensions/pi-must-have-extension # Global (all projects)
30
- .pi/extensions/pi-must-have-extension # Project-specific
31
- ```
32
-
33
- Pi will auto-discover the extension on startup.
34
-
35
- ### NPM Package
36
-
37
- ```bash
38
- pi install npm:pi-must-have-extension
39
- ```
40
-
41
- ## Usage
42
-
43
- Once installed, the extension works automatically. When you type prompts containing RFC 2119 keywords:
44
-
45
- **Input:**
46
- ```text
47
- The function must validate input and should log errors.
48
- ```
49
-
50
- **Transformed to:**
51
- ```text
52
- The function MUST validate input and SHOULD log errors.
53
- ```
54
-
55
- ### Skipped Input
56
-
57
- The extension does not transform:
58
-
59
- - Slash commands (e.g., `/help`, `/reload`)
60
- - Shell commands (e.g., `!ls`, `!git status`)
61
- - Empty input
62
-
63
- ## Configuration
64
-
65
- The extension uses a JSONC configuration file (JSON with comments):
66
-
67
- ```text
68
- ~/.pi/agent/extensions/pi-must-have-extension/config.jsonc
69
- ```
70
-
71
- ### Default Configuration
72
-
73
- ```jsonc
74
- {
75
- // Enable debug notifications in the TUI
76
- // "debug": true,
77
-
78
- "replacements": {
79
- "must": "MUST",
80
- "must not": "MUST NOT",
81
- "required": "REQUIRED",
82
- "shall": "SHALL",
83
- "shall not": "SHALL NOT",
84
- "should": "SHOULD",
85
- "should not": "SHOULD NOT",
86
- "recommended": "RECOMMENDED",
87
- "not recommended": "NOT RECOMMENDED",
88
- "may": "MAY",
89
- "optional": "OPTIONAL"
90
- }
91
- }
92
- ```
93
-
94
- ### Configuration Options
95
-
96
- | Option | Type | Default | Description |
97
- |--------|------|---------|-------------|
98
- | `debug` | `boolean` | `false` | Enable TUI notifications showing replacement counts |
99
- | `replacements` | `object` | RFC 2119 defaults | Key-value map of terms to replace |
100
-
101
- ### Custom Replacements
102
-
103
- You can add custom replacement rules or modify existing ones:
104
-
105
- ```jsonc
106
- {
107
- "replacements": {
108
- // Standard RFC 2119
109
- "must": "MUST",
110
- "should": "SHOULD",
111
-
112
- // Custom shortcuts
113
- "rfc!": "The key words in this document are to be interpreted as described in RFC 2119.\n\n",
114
- "always": "**ALWAYS**",
115
- "never": "**NEVER**"
116
- }
117
- }
118
- ```
119
-
120
- An advanced replacement sample is included at `config/replacements.custom-sample.jsonc`.
121
-
122
- ### Legacy Config Paths
123
-
124
- The extension supports migration from previous versions. Legacy configs are read from:
125
-
126
- ```text
127
- ~/.pi/agent/extensions/pi-must-have-plugin/config.jsonc
128
- ~/.pi/agent/extensions/must-have-plugin/config.jsonc
129
- ~/.config/opencode/MUST-have-plugin.jsonc
130
- ```
131
-
132
- On first run, legacy configs are automatically migrated to the new location.
133
-
134
- ## Technical Details
135
-
136
- ### How It Works
137
-
138
- 1. **Session start**: Ensures config exists (creates default or migrates legacy)
139
- 2. **Input event**: Intercepts user prompts before sending to the agent
140
- 3. **Pattern matching**: Uses regex with word boundaries and longest-match-first ordering
141
- 4. **Transformation**: Returns modified text while preserving images and other input data
142
-
143
- ### Project Structure
144
-
145
- ```text
146
- ├── index.ts # Pi extension entrypoint
147
- ├── src/
148
- ├── index.ts # Extension event wiring
149
- │ ├── constants.ts # Paths, defaults, and extension name
150
- │ ├── types.ts # TypeScript interfaces
151
- │ ├── config/
152
- ├── config-loader.ts # Config loading and migration
153
- │ │ └── jsonc.ts # JSONC parser (strips comments)
154
- │ └── replacements/
155
- └── replacement-engine.ts # Core replacement logic
156
- ├── config/
157
- ├── config.example.jsonc # Starter template
158
- └── replacements.custom-sample.jsonc # Advanced samples
159
- └── test/
160
- └── replacement-engine.test.ts # Unit tests
161
- ```
162
-
163
- ### Development
164
-
165
- ```bash
166
- npm install # Install dependencies
167
- npm run build # Type-check with TypeScript
168
- npm run test # Run test suite
169
- npm run check # Build + test
170
- ```
171
-
172
- ## Origin
173
-
174
- This extension is a Pi-harness adaptation of [ariane-emory/MUST-have-plugin](https://github.com/ariane-emory/MUST-have-plugin), converted into a modular TypeScript Pi extension.
175
-
176
- ## License
177
-
178
- MIT
1
+ # pi-must-have-extension
2
+
3
+ Normalize RFC 2119 language in Pi prompts by automatically rewriting lowercase modal terms (`must`, `should not`, `optional`) into uppercase normative forms (`MUST`, `SHOULD NOT`, `OPTIONAL`).
4
+
5
+ <img width="1360" height="752" alt="image" src="https://github.com/user-attachments/assets/d5aff97e-ac69-48d1-a071-c7f5460899e4" />
6
+
7
+
8
+ ## Demo
9
+
10
+ [![Watch demo video](https://raw.githubusercontent.com/MasuRii/pi-must-have-extension/main/asset/pi-must-have-extension.png)](https://github.com/user-attachments/assets/22149125-8976-4d06-98cb-e7cfa180476d)
11
+
12
+ ## Features
13
+
14
+ - **RFC 2119/8174 compliance** — Transforms modal keywords to standard uppercase notation
15
+ - **Intelligent matching** — Case-insensitive with longest-first phrase replacement
16
+ - **Word-boundary aware** — Does not replace keywords embedded inside larger words
17
+ - **Configurable replacements** — Customize or extend the default keyword mappings
18
+ - **Input filtering** — Leaves slash commands (`/`) and shell input (`!`) unchanged
19
+ - **Auto-configuration** — Creates a default config file when none exists
20
+ - **Legacy migration** — Automatically migrates configs from previous plugin versions
21
+ - **Debug mode** — Optional TUI notifications showing replacement counts
22
+
23
+ ## Installation
24
+
25
+ ### Local Extension Folder
26
+
27
+ Copy this repository to one of the following locations:
28
+
29
+ ```text
30
+ ~/.pi/agent/extensions/pi-must-have-extension # Global (all projects)
31
+ .pi/extensions/pi-must-have-extension # Project-specific
32
+ ```
33
+
34
+ Pi will auto-discover the extension on startup.
35
+
36
+ ### NPM Package
37
+
38
+ ```bash
39
+ pi install npm:pi-must-have-extension
40
+ ```
41
+
42
+ ## Usage
43
+
44
+ Once installed, the extension works automatically. When you type prompts containing RFC 2119 keywords:
45
+
46
+ **Input:**
47
+ ```text
48
+ The function must validate input and should log errors.
49
+ ```
50
+
51
+ **Transformed to:**
52
+ ```text
53
+ The function MUST validate input and SHOULD log errors.
54
+ ```
55
+
56
+ ### Skipped Input
57
+
58
+ The extension does not transform:
59
+
60
+ - Slash commands (e.g., `/help`, `/reload`)
61
+ - Shell commands (e.g., `!ls`, `!git status`)
62
+ - Empty input
63
+
64
+ ## Configuration
65
+
66
+ The extension uses a JSONC configuration file (JSON with comments):
67
+
68
+ ```text
69
+ ~/.pi/agent/extensions/pi-must-have-extension/config.jsonc
70
+ ```
71
+
72
+ ### Default Configuration
73
+
74
+ ```jsonc
75
+ {
76
+ // Enable debug notifications in the TUI
77
+ // "debug": true,
78
+
79
+ "replacements": {
80
+ "must": "MUST",
81
+ "must not": "MUST NOT",
82
+ "required": "REQUIRED",
83
+ "shall": "SHALL",
84
+ "shall not": "SHALL NOT",
85
+ "should": "SHOULD",
86
+ "should not": "SHOULD NOT",
87
+ "recommended": "RECOMMENDED",
88
+ "not recommended": "NOT RECOMMENDED",
89
+ "may": "MAY",
90
+ "optional": "OPTIONAL"
91
+ }
92
+ }
93
+ ```
94
+
95
+ ### Configuration Options
96
+
97
+ | Option | Type | Default | Description |
98
+ |--------|------|---------|-------------|
99
+ | `debug` | `boolean` | `false` | Enable TUI notifications showing replacement counts |
100
+ | `replacements` | `object` | RFC 2119 defaults | Key-value map of terms to replace |
101
+
102
+ ### Custom Replacements
103
+
104
+ You can add custom replacement rules or modify existing ones:
105
+
106
+ ```jsonc
107
+ {
108
+ "replacements": {
109
+ // Standard RFC 2119
110
+ "must": "MUST",
111
+ "should": "SHOULD",
112
+
113
+ // Custom shortcuts
114
+ "rfc!": "The key words in this document are to be interpreted as described in RFC 2119.\n\n",
115
+ "always": "**ALWAYS**",
116
+ "never": "**NEVER**"
117
+ }
118
+ }
119
+ ```
120
+
121
+ An advanced replacement sample is included at `config/replacements.custom-sample.jsonc`.
122
+
123
+ ### Legacy Config Paths
124
+
125
+ The extension supports migration from previous versions. Legacy configs are read from:
126
+
127
+ ```text
128
+ ~/.pi/agent/extensions/pi-must-have-plugin/config.jsonc
129
+ ~/.pi/agent/extensions/must-have-plugin/config.jsonc
130
+ ~/.config/opencode/MUST-have-plugin.jsonc
131
+ ```
132
+
133
+ On first run, legacy configs are automatically migrated to the new location.
134
+
135
+ ## Technical Details
136
+
137
+ ### How It Works
138
+
139
+ 1. **Session start**: Ensures config exists (creates default or migrates legacy)
140
+ 2. **Input event**: Intercepts user prompts before sending to the agent
141
+ 3. **Pattern matching**: Uses regex with word boundaries and longest-match-first ordering
142
+ 4. **Transformation**: Returns modified text while preserving images and other input data
143
+
144
+ ### Project Structure
145
+
146
+ ```text
147
+ ├── index.ts # Pi extension entrypoint
148
+ ├── src/
149
+ │ ├── index.ts # Extension event wiring
150
+ │ ├── constants.ts # Paths, defaults, and extension name
151
+ │ ├── types.ts # TypeScript interfaces
152
+ │ ├── config/
153
+ │ │ ├── config-loader.ts # Config loading and migration
154
+ └── jsonc.ts # JSONC parser (strips comments)
155
+ └── replacements/
156
+ │ └── replacement-engine.ts # Core replacement logic
157
+ ├── config/
158
+ ├── config.example.jsonc # Starter template
159
+ └── replacements.custom-sample.jsonc # Advanced samples
160
+ └── test/
161
+ └── replacement-engine.test.ts # Unit tests
162
+ ```
163
+
164
+ ### Development
165
+
166
+ ```bash
167
+ npm install # Install dependencies
168
+ npm run build # Type-check with TypeScript
169
+ npm run test # Run test suite
170
+ npm run check # Build + test
171
+ ```
172
+
173
+ ## Origin
174
+
175
+ This extension is a Pi-harness adaptation of [ariane-emory/MUST-have-plugin](https://github.com/ariane-emory/MUST-have-plugin), converted into a modular TypeScript Pi extension.
176
+
177
+ ## Related Pi Extensions
178
+
179
+ - [pi-permission-system](https://github.com/MasuRii/pi-permission-system) — Permission enforcement for tool and command access
180
+ - [pi-tool-display](https://github.com/MasuRii/pi-tool-display) — Compact tool rendering and diff visualization
181
+ - [pi-rtk-optimizer](https://github.com/MasuRii/pi-rtk-optimizer) — RTK command rewriting and output compaction
182
+ - [pi-multi-auth](https://github.com/MasuRii/pi-multi-auth) — Multi-provider credential management and quota-aware rotation
183
+
184
+ ## License
185
+
186
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-must-have-extension",
3
- "version": "0.4.7",
3
+ "version": "0.4.9",
4
4
  "description": "RFC 2119 keyword normalizer extension for the Pi coding agent.",
5
5
  "type": "module",
6
6
  "main": "./index.ts",
@@ -35,6 +35,8 @@
35
35
  "bcp14",
36
36
  "prompt-normalization",
37
37
  "prompt-rewrite",
38
+ "prompt-engineering",
39
+ "keyword-normalization",
38
40
  "compliance",
39
41
  "jsonc"
40
42
  ],
@@ -60,11 +62,11 @@
60
62
  ]
61
63
  },
62
64
  "peerDependencies": {
63
- "@mariozechner/pi-coding-agent": "*"
65
+ "@mariozechner/pi-coding-agent": "^0.64.0"
64
66
  },
65
67
  "devDependencies": {
66
- "@mariozechner/pi-coding-agent": "^0.62.0",
68
+ "@mariozechner/pi-coding-agent": "^0.64.0",
67
69
  "@types/node": "^25.5.0",
68
- "typescript": "^5.9.3"
70
+ "typescript": "^6.0.2"
69
71
  }
70
72
  }
package/src/constants.ts CHANGED
@@ -1,63 +1,63 @@
1
- import { homedir } from "node:os";
2
- import { join } from "node:path";
3
- import type { MustHaveExtensionConfig } from "./types.js";
4
-
5
- export const EXTENSION_NAME = "pi-must-have-extension";
6
- export const CONFIG_DIR = join(homedir(), ".pi", "agent", "extensions", EXTENSION_NAME);
7
- export const CONFIG_PATH = join(CONFIG_DIR, "config.jsonc");
8
-
9
- export const LEGACY_PI_MUST_HAVE_PLUGIN_CONFIG_PATH = join(
10
- homedir(),
11
- ".pi",
12
- "agent",
13
- "extensions",
14
- "pi-must-have-plugin",
15
- "config.jsonc",
16
- );
17
- export const LEGACY_MUST_HAVE_PLUGIN_CONFIG_PATH = join(
18
- homedir(),
19
- ".pi",
20
- "agent",
21
- "extensions",
22
- "must-have-plugin",
23
- "config.jsonc",
24
- );
25
- export const LEGACY_OPENCODE_CONFIG_PATH = join(homedir(), ".config", "opencode", "MUST-have-plugin.jsonc");
26
-
27
- export const RFC2119_DEFAULTS: Readonly<Record<string, string>> = {
28
- must: "MUST",
29
- "must not": "MUST NOT",
30
- required: "REQUIRED",
31
- shall: "SHALL",
32
- "shall not": "SHALL NOT",
33
- should: "SHOULD",
34
- "should not": "SHOULD NOT",
35
- recommended: "RECOMMENDED",
36
- "not recommended": "NOT RECOMMENDED",
37
- may: "MAY",
38
- optional: "OPTIONAL",
39
- };
40
-
41
- export const FALLBACK_CONFIG: MustHaveExtensionConfig = {
42
- debug: false,
43
- replacements: { ...RFC2119_DEFAULTS },
44
- };
45
-
46
- export const DEFAULT_CONFIG = `{
47
- // Enable debug notifications in the TUI
48
- // "debug": true,
49
-
50
- "replacements": {
51
- "must": "MUST",
52
- "must not": "MUST NOT",
53
- "required": "REQUIRED",
54
- "shall": "SHALL",
55
- "shall not": "SHALL NOT",
56
- "should": "SHOULD",
57
- "should not": "SHOULD NOT",
58
- "recommended": "RECOMMENDED",
59
- "not recommended": "NOT RECOMMENDED",
60
- "may": "MAY",
61
- "optional": "OPTIONAL"
62
- }
63
- }\n`;
1
+ import { homedir } from "node:os";
2
+ import { join } from "node:path";
3
+ import type { MustHaveExtensionConfig } from "./types.js";
4
+
5
+ export const EXTENSION_NAME = "pi-must-have-extension";
6
+ export const CONFIG_DIR = join(homedir(), ".pi", "agent", "extensions", EXTENSION_NAME);
7
+ export const CONFIG_PATH = join(CONFIG_DIR, "config.jsonc");
8
+
9
+ export const LEGACY_PI_MUST_HAVE_PLUGIN_CONFIG_PATH = join(
10
+ homedir(),
11
+ ".pi",
12
+ "agent",
13
+ "extensions",
14
+ "pi-must-have-plugin",
15
+ "config.jsonc",
16
+ );
17
+ export const LEGACY_MUST_HAVE_PLUGIN_CONFIG_PATH = join(
18
+ homedir(),
19
+ ".pi",
20
+ "agent",
21
+ "extensions",
22
+ "must-have-plugin",
23
+ "config.jsonc",
24
+ );
25
+ export const LEGACY_OPENCODE_CONFIG_PATH = join(homedir(), ".config", "opencode", "MUST-have-plugin.jsonc");
26
+
27
+ export const RFC2119_DEFAULTS: Readonly<Record<string, string>> = {
28
+ must: "MUST",
29
+ "must not": "MUST NOT",
30
+ required: "REQUIRED",
31
+ shall: "SHALL",
32
+ "shall not": "SHALL NOT",
33
+ should: "SHOULD",
34
+ "should not": "SHOULD NOT",
35
+ recommended: "RECOMMENDED",
36
+ "not recommended": "NOT RECOMMENDED",
37
+ may: "MAY",
38
+ optional: "OPTIONAL",
39
+ };
40
+
41
+ export const FALLBACK_CONFIG: MustHaveExtensionConfig = {
42
+ debug: false,
43
+ replacements: { ...RFC2119_DEFAULTS },
44
+ };
45
+
46
+ export const DEFAULT_CONFIG = `{
47
+ // Enable debug notifications in the TUI
48
+ // "debug": true,
49
+
50
+ "replacements": {
51
+ "must": "MUST",
52
+ "must not": "MUST NOT",
53
+ "required": "REQUIRED",
54
+ "shall": "SHALL",
55
+ "shall not": "SHALL NOT",
56
+ "should": "SHOULD",
57
+ "should not": "SHOULD NOT",
58
+ "recommended": "RECOMMENDED",
59
+ "not recommended": "NOT RECOMMENDED",
60
+ "may": "MAY",
61
+ "optional": "OPTIONAL"
62
+ }
63
+ }\n`;