rhachet-roles-ehmpathy 1.17.14 → 1.17.16

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.
@@ -0,0 +1,109 @@
1
+ ### .rule = require-hook-wrapper-pattern
2
+
3
+ #### .what
4
+ wrap procedures with hooks via composition, not inline decoration
5
+
6
+ #### .pattern
7
+ ```ts
8
+ const _procedureName = (input: {...}, context: {...}) => {
9
+ // implementation
10
+ };
11
+
12
+ export const procedureName = withHook(_procedureName);
13
+ ```
14
+
15
+ #### .why
16
+
17
+ this pattern minimizes code diffs when hooks are added, changed, or removed:
18
+
19
+ - **add a hook** → 1 line changes (the export line)
20
+ - **remove a hook** → 1 line changes (the export line)
21
+ - **change hook order** → 1 line changes (the export line)
22
+
23
+ the alternative — inline wrapping at the function declaration — causes the entire function body to shift indentation, which produces noisy diffs that obscure the actual change.
24
+
25
+ #### .examples
26
+
27
+ ##### ✅ good — wrapper pattern
28
+
29
+ ```ts
30
+ /**
31
+ * .what = sends an invoice to the customer
32
+ * .why = triggers billing workflow
33
+ */
34
+ const _sendInvoice = async (
35
+ input: { invoice: Invoice },
36
+ context: { log: LogMethods },
37
+ ): Promise<{ sent: boolean }> => {
38
+ // implementation stays clean and unindented
39
+ context.log.info('sending invoice', { invoiceId: input.invoice.id });
40
+ return { sent: true };
41
+ };
42
+
43
+ export const sendInvoice = withLogTrail(_sendInvoice);
44
+ ```
45
+
46
+ ##### ✅ good — multiple hooks composed
47
+
48
+ ```ts
49
+ const _processPayment = async (
50
+ input: { payment: Payment },
51
+ context: { log: LogMethods },
52
+ ): Promise<{ success: boolean }> => {
53
+ // implementation
54
+ };
55
+
56
+ // hooks compose right-to-left: withRetry runs first, then withLogTrail
57
+ export const processPayment = withLogTrail(
58
+ withRetry(_processPayment, { maxAttempts: 3 }),
59
+ );
60
+ ```
61
+
62
+ ##### ⛔ bad — inline decoration
63
+
64
+ ```ts
65
+ // ⛔ adding/removing the wrapper shifts the entire function body
66
+ export const sendInvoice = withLogTrail(async (
67
+ input: { invoice: Invoice },
68
+ context: { log: LogMethods },
69
+ ): Promise<{ sent: boolean }> => {
70
+ // every line here will show as "changed" in the diff
71
+ // when the hook is added or removed
72
+ context.log.info('sending invoice', { invoiceId: input.invoice.id });
73
+ return { sent: true };
74
+ });
75
+ ```
76
+
77
+ #### .diff comparison
78
+
79
+ when adding `withLogTrail` to an existing function:
80
+
81
+ **wrapper pattern diff (clean):**
82
+ ```diff
83
+ - export const sendInvoice = _sendInvoice;
84
+ + export const sendInvoice = withLogTrail(_sendInvoice);
85
+ ```
86
+
87
+ **inline pattern diff (noisy):**
88
+ ```diff
89
+ - export const sendInvoice = async (
90
+ + export const sendInvoice = withLogTrail(async (
91
+ input: { invoice: Invoice },
92
+ context: { log: LogMethods },
93
+ ): Promise<{ sent: boolean }> => {
94
+ context.log.info('sending invoice', { invoiceId: input.invoice.id });
95
+ return { sent: true };
96
+ - };
97
+ + });
98
+ ```
99
+
100
+ the wrapper pattern produces a 1-line diff; the inline pattern touches every line of the function.
101
+
102
+ #### .naming
103
+
104
+ - prefix the unwrapped procedure with `_` (e.g., `_sendInvoice`)
105
+ - export the wrapped version without prefix (e.g., `sendInvoice`)
106
+ - this signals that `_sendInvoice` is internal and should not be imported directly
107
+
108
+ #### .enforcement
109
+ inline hook decoration = **BLOCKER**
@@ -30,20 +30,36 @@ the same rename via sedreplace = 2 tool calls (dry-run + execute) = minimal toke
30
30
  # dry-run first (default) - see what would change
31
31
  npx rhachet run --skill sedreplace --old "oldName" --new "newName"
32
32
 
33
- # filter to specific file types
34
- npx rhachet run --skill sedreplace --old "oldName" --new "newName" --glob "*.ts"
33
+ # filter to specific file types (recursive)
34
+ npx rhachet run --skill sedreplace --old "oldName" --new "newName" --glob "**/*.ts"
35
+
36
+ # filter to files in a specific directory
37
+ npx rhachet run --skill sedreplace --old "oldName" --new "newName" --glob "src/**/*.ts"
35
38
 
36
39
  # apply changes after review of dry-run
37
40
  npx rhachet run --skill sedreplace --old "oldName" --new "newName" --execute
38
41
  ```
39
42
 
43
+ ### glob pattern semantics
44
+
45
+ the `--glob` option uses shell glob semantics:
46
+
47
+ | pattern | matches |
48
+ |---------|---------|
49
+ | `*.ts` | `.ts` files in root directory only |
50
+ | `**/*.ts` | all `.ts` files recursively |
51
+ | `src/*.ts` | `.ts` files directly in `src/` |
52
+ | `src/**/*.ts` | `.ts` files recursively in `src/` |
53
+ | `*.{ts,tsx}` | `.ts` and `.tsx` files in root |
54
+ | `**/*.{ts,tsx}` | all `.ts` and `.tsx` files recursively |
55
+
40
56
  ## .examples
41
57
 
42
58
  ### rename a function
43
59
 
44
60
  ```sh
45
61
  # rename getUserById -> findUserByUuid across all .ts files
46
- npx rhachet run --skill sedreplace --old "getUserById" --new "findUserByUuid" --glob "*.ts" --execute
62
+ npx rhachet run --skill sedreplace --old "getUserById" --new "findUserByUuid" --glob "**/*.ts" --execute
47
63
  ```
48
64
 
49
65
  ### update an import path
@@ -81,8 +81,10 @@ if ! git rev-parse --git-dir > /dev/null 2>&1; then
81
81
  fi
82
82
 
83
83
  # get git-tracked files, optionally filtered by glob
84
+ # note: use :(glob) magic pathspec for proper shell-like glob behavior
85
+ # without this, git ls-files uses pathspec matching where * matches /
84
86
  if [[ -n "$GLOB_FILTER" ]]; then
85
- FILES=$(git ls-files "$GLOB_FILTER")
87
+ FILES=$(git ls-files ":(glob)$GLOB_FILTER")
86
88
  else
87
89
  FILES=$(git ls-files)
88
90
  fi
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "rhachet-roles-ehmpathy",
3
3
  "author": "ehmpathy",
4
4
  "description": "empathetic software construction roles and skills, via rhachet",
5
- "version": "1.17.14",
5
+ "version": "1.17.16",
6
6
  "repository": "ehmpathy/rhachet-roles-ehmpathy",
7
7
  "homepage": "https://github.com/ehmpathy/rhachet-roles-ehmpathy",
8
8
  "keywords": [