@cldmv/slothlet 2.11.0 → 3.0.1

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.
Files changed (189) hide show
  1. package/AGENT-USAGE.md +355 -325
  2. package/README.md +554 -238
  3. package/dist/lib/builders/api-assignment.mjs +605 -0
  4. package/dist/lib/builders/api_builder.mjs +1073 -0
  5. package/dist/lib/builders/builder.mjs +94 -0
  6. package/dist/lib/builders/modes-processor.mjs +1816 -0
  7. package/dist/lib/errors.mjs +227 -0
  8. package/dist/lib/factories/component-base.mjs +96 -0
  9. package/dist/lib/factories/context.mjs +38 -0
  10. package/dist/lib/handlers/api-cache-manager.mjs +216 -0
  11. package/dist/lib/handlers/api-manager.mjs +2364 -0
  12. package/dist/lib/handlers/context-async.mjs +184 -0
  13. package/dist/lib/handlers/context-live.mjs +184 -0
  14. package/dist/lib/handlers/hook-manager.mjs +789 -0
  15. package/dist/lib/handlers/lifecycle-token.mjs +44 -0
  16. package/dist/lib/handlers/lifecycle.mjs +131 -0
  17. package/dist/lib/handlers/materialize-manager.mjs +64 -0
  18. package/dist/lib/handlers/metadata.mjs +500 -0
  19. package/dist/lib/handlers/ownership.mjs +338 -0
  20. package/dist/lib/handlers/unified-wrapper.mjs +3031 -0
  21. package/dist/lib/helpers/class-instance-wrapper.mjs +125 -0
  22. package/dist/lib/helpers/config.mjs +343 -0
  23. package/dist/lib/helpers/eventemitter-context.mjs +365 -0
  24. package/dist/lib/helpers/hint-detector.mjs +63 -0
  25. package/dist/lib/helpers/modes-utils.mjs +53 -0
  26. package/dist/lib/helpers/resolve-from-caller.mjs +123 -117
  27. package/dist/lib/helpers/sanitize.mjs +247 -168
  28. package/dist/lib/helpers/utilities.mjs +46 -81
  29. package/dist/lib/i18n/languages/de-de.json +377 -0
  30. package/dist/lib/i18n/languages/en-gb.json +377 -0
  31. package/dist/lib/i18n/languages/en-us.json +377 -0
  32. package/dist/lib/i18n/languages/es-mx.json +377 -0
  33. package/dist/lib/i18n/languages/fr-fr.json +377 -0
  34. package/dist/lib/i18n/languages/hi-in.json +377 -0
  35. package/dist/lib/i18n/languages/ja-jp.json +377 -0
  36. package/dist/lib/i18n/languages/ko-kr.json +377 -0
  37. package/dist/lib/i18n/languages/pt-br.json +377 -0
  38. package/dist/lib/i18n/languages/ru-ru.json +377 -0
  39. package/dist/lib/i18n/languages/zh-cn.json +377 -0
  40. package/dist/lib/i18n/translations.mjs +140 -0
  41. package/dist/lib/modes/eager.mjs +75 -0
  42. package/dist/lib/modes/lazy.mjs +97 -0
  43. package/dist/lib/processors/flatten.mjs +453 -0
  44. package/dist/lib/processors/loader.mjs +355 -0
  45. package/dist/lib/processors/type-generator.mjs +291 -0
  46. package/dist/lib/processors/typescript.mjs +188 -0
  47. package/dist/lib/runtime/runtime-asynclocalstorage.mjs +80 -522
  48. package/dist/lib/runtime/runtime-livebindings.mjs +45 -390
  49. package/dist/lib/runtime/runtime.mjs +39 -159
  50. package/dist/slothlet.mjs +525 -744
  51. package/docs/API-RULES.md +338 -486
  52. package/index.cjs +4 -4
  53. package/index.mjs +82 -45
  54. package/package.json +143 -30
  55. package/types/dist/lib/builders/api-assignment.d.mts +97 -0
  56. package/types/dist/lib/builders/api-assignment.d.mts.map +1 -0
  57. package/types/dist/lib/builders/api_builder.d.mts +96 -0
  58. package/types/dist/lib/builders/api_builder.d.mts.map +1 -0
  59. package/types/dist/lib/builders/builder.d.mts +60 -0
  60. package/types/dist/lib/builders/builder.d.mts.map +1 -0
  61. package/types/dist/lib/builders/modes-processor.d.mts +32 -0
  62. package/types/dist/lib/builders/modes-processor.d.mts.map +1 -0
  63. package/types/dist/lib/errors.d.mts +118 -0
  64. package/types/dist/lib/errors.d.mts.map +1 -0
  65. package/types/dist/lib/factories/component-base.d.mts +182 -0
  66. package/types/dist/lib/factories/component-base.d.mts.map +1 -0
  67. package/types/dist/lib/factories/context.d.mts +26 -0
  68. package/types/dist/lib/factories/context.d.mts.map +1 -0
  69. package/types/dist/lib/handlers/api-cache-manager.d.mts +208 -0
  70. package/types/dist/lib/handlers/api-cache-manager.d.mts.map +1 -0
  71. package/types/dist/lib/handlers/api-manager.d.mts +392 -0
  72. package/types/dist/lib/handlers/api-manager.d.mts.map +1 -0
  73. package/types/dist/lib/handlers/context-async.d.mts +66 -0
  74. package/types/dist/lib/handlers/context-async.d.mts.map +1 -0
  75. package/types/dist/lib/handlers/context-live.d.mts +65 -0
  76. package/types/dist/lib/handlers/context-live.d.mts.map +1 -0
  77. package/types/dist/lib/handlers/hook-manager.d.mts +199 -0
  78. package/types/dist/lib/handlers/hook-manager.d.mts.map +1 -0
  79. package/types/dist/lib/handlers/lifecycle-token.d.mts +49 -0
  80. package/types/dist/lib/handlers/lifecycle-token.d.mts.map +1 -0
  81. package/types/dist/lib/handlers/lifecycle.d.mts +90 -0
  82. package/types/dist/lib/handlers/lifecycle.d.mts.map +1 -0
  83. package/types/dist/lib/handlers/materialize-manager.d.mts +75 -0
  84. package/types/dist/lib/handlers/materialize-manager.d.mts.map +1 -0
  85. package/types/dist/lib/handlers/metadata.d.mts +215 -0
  86. package/types/dist/lib/handlers/metadata.d.mts.map +1 -0
  87. package/types/dist/lib/handlers/ownership.d.mts +170 -0
  88. package/types/dist/lib/handlers/ownership.d.mts.map +1 -0
  89. package/types/dist/lib/handlers/unified-wrapper.d.mts +250 -0
  90. package/types/dist/lib/handlers/unified-wrapper.d.mts.map +1 -0
  91. package/types/dist/lib/helpers/class-instance-wrapper.d.mts +54 -0
  92. package/types/dist/lib/helpers/class-instance-wrapper.d.mts.map +1 -0
  93. package/types/dist/lib/helpers/config.d.mts +96 -0
  94. package/types/dist/lib/helpers/config.d.mts.map +1 -0
  95. package/types/dist/lib/helpers/eventemitter-context.d.mts +31 -0
  96. package/types/dist/lib/helpers/eventemitter-context.d.mts.map +1 -0
  97. package/types/dist/lib/helpers/hint-detector.d.mts +20 -0
  98. package/types/dist/lib/helpers/hint-detector.d.mts.map +1 -0
  99. package/types/dist/lib/helpers/modes-utils.d.mts +35 -0
  100. package/types/dist/lib/helpers/modes-utils.d.mts.map +1 -0
  101. package/types/dist/lib/helpers/resolve-from-caller.d.mts +29 -145
  102. package/types/dist/lib/helpers/resolve-from-caller.d.mts.map +1 -1
  103. package/types/dist/lib/helpers/sanitize.d.mts +95 -94
  104. package/types/dist/lib/helpers/sanitize.d.mts.map +1 -1
  105. package/types/dist/lib/helpers/utilities.d.mts +53 -116
  106. package/types/dist/lib/helpers/utilities.d.mts.map +1 -1
  107. package/types/dist/lib/i18n/translations.d.mts +39 -0
  108. package/types/dist/lib/i18n/translations.d.mts.map +1 -0
  109. package/types/dist/lib/modes/eager.d.mts +36 -0
  110. package/types/dist/lib/modes/eager.d.mts.map +1 -0
  111. package/types/dist/lib/modes/lazy.d.mts +49 -0
  112. package/types/dist/lib/modes/lazy.d.mts.map +1 -0
  113. package/types/dist/lib/processors/flatten.d.mts +114 -0
  114. package/types/dist/lib/processors/flatten.d.mts.map +1 -0
  115. package/types/dist/lib/processors/loader.d.mts +47 -0
  116. package/types/dist/lib/processors/loader.d.mts.map +1 -0
  117. package/types/dist/lib/processors/type-generator.d.mts +19 -0
  118. package/types/dist/lib/processors/type-generator.d.mts.map +1 -0
  119. package/types/dist/lib/processors/typescript.d.mts +55 -0
  120. package/types/dist/lib/processors/typescript.d.mts.map +1 -0
  121. package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts +47 -42
  122. package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts.map +1 -1
  123. package/types/dist/lib/runtime/runtime-livebindings.d.mts +34 -65
  124. package/types/dist/lib/runtime/runtime-livebindings.d.mts.map +1 -1
  125. package/types/dist/lib/runtime/runtime.d.mts +39 -9
  126. package/types/dist/lib/runtime/runtime.d.mts.map +1 -1
  127. package/types/dist/slothlet.d.mts +184 -111
  128. package/types/dist/slothlet.d.mts.map +1 -1
  129. package/types/index.d.mts +1 -3
  130. package/dist/lib/engine/README.md +0 -21
  131. package/dist/lib/engine/slothlet_child.mjs +0 -59
  132. package/dist/lib/engine/slothlet_engine.mjs +0 -372
  133. package/dist/lib/engine/slothlet_esm.mjs +0 -230
  134. package/dist/lib/engine/slothlet_helpers.mjs +0 -455
  135. package/dist/lib/engine/slothlet_worker.mjs +0 -149
  136. package/dist/lib/helpers/als-eventemitter.mjs +0 -256
  137. package/dist/lib/helpers/api_builder/add_api.mjs +0 -553
  138. package/dist/lib/helpers/api_builder/analysis.mjs +0 -532
  139. package/dist/lib/helpers/api_builder/construction.mjs +0 -495
  140. package/dist/lib/helpers/api_builder/decisions.mjs +0 -748
  141. package/dist/lib/helpers/api_builder/metadata.mjs +0 -248
  142. package/dist/lib/helpers/api_builder.mjs +0 -41
  143. package/dist/lib/helpers/auto-wrap.mjs +0 -62
  144. package/dist/lib/helpers/hooks.mjs +0 -389
  145. package/dist/lib/helpers/instance-manager.mjs +0 -111
  146. package/dist/lib/helpers/metadata-api.mjs +0 -201
  147. package/dist/lib/helpers/multidefault.mjs +0 -216
  148. package/dist/lib/modes/slothlet_eager.mjs +0 -154
  149. package/dist/lib/modes/slothlet_lazy.mjs +0 -594
  150. package/docs/API-RULES-CONDITIONS.md +0 -712
  151. package/types/dist/lib/engine/slothlet_child.d.mts +0 -2
  152. package/types/dist/lib/engine/slothlet_child.d.mts.map +0 -1
  153. package/types/dist/lib/engine/slothlet_engine.d.mts +0 -31
  154. package/types/dist/lib/engine/slothlet_engine.d.mts.map +0 -1
  155. package/types/dist/lib/engine/slothlet_esm.d.mts +0 -19
  156. package/types/dist/lib/engine/slothlet_esm.d.mts.map +0 -1
  157. package/types/dist/lib/engine/slothlet_helpers.d.mts +0 -25
  158. package/types/dist/lib/engine/slothlet_helpers.d.mts.map +0 -1
  159. package/types/dist/lib/engine/slothlet_worker.d.mts +0 -2
  160. package/types/dist/lib/engine/slothlet_worker.d.mts.map +0 -1
  161. package/types/dist/lib/helpers/als-eventemitter.d.mts +0 -56
  162. package/types/dist/lib/helpers/als-eventemitter.d.mts.map +0 -1
  163. package/types/dist/lib/helpers/api_builder/add_api.d.mts +0 -102
  164. package/types/dist/lib/helpers/api_builder/add_api.d.mts.map +0 -1
  165. package/types/dist/lib/helpers/api_builder/analysis.d.mts +0 -189
  166. package/types/dist/lib/helpers/api_builder/analysis.d.mts.map +0 -1
  167. package/types/dist/lib/helpers/api_builder/construction.d.mts +0 -107
  168. package/types/dist/lib/helpers/api_builder/construction.d.mts.map +0 -1
  169. package/types/dist/lib/helpers/api_builder/decisions.d.mts +0 -213
  170. package/types/dist/lib/helpers/api_builder/decisions.d.mts.map +0 -1
  171. package/types/dist/lib/helpers/api_builder/metadata.d.mts +0 -99
  172. package/types/dist/lib/helpers/api_builder/metadata.d.mts.map +0 -1
  173. package/types/dist/lib/helpers/api_builder.d.mts +0 -6
  174. package/types/dist/lib/helpers/api_builder.d.mts.map +0 -1
  175. package/types/dist/lib/helpers/auto-wrap.d.mts +0 -49
  176. package/types/dist/lib/helpers/auto-wrap.d.mts.map +0 -1
  177. package/types/dist/lib/helpers/hooks.d.mts +0 -342
  178. package/types/dist/lib/helpers/hooks.d.mts.map +0 -1
  179. package/types/dist/lib/helpers/instance-manager.d.mts +0 -41
  180. package/types/dist/lib/helpers/instance-manager.d.mts.map +0 -1
  181. package/types/dist/lib/helpers/metadata-api.d.mts +0 -132
  182. package/types/dist/lib/helpers/metadata-api.d.mts.map +0 -1
  183. package/types/dist/lib/helpers/multidefault.d.mts +0 -90
  184. package/types/dist/lib/helpers/multidefault.d.mts.map +0 -1
  185. package/types/dist/lib/modes/slothlet_eager.d.mts +0 -65
  186. package/types/dist/lib/modes/slothlet_eager.d.mts.map +0 -1
  187. package/types/dist/lib/modes/slothlet_lazy.d.mts +0 -31
  188. package/types/dist/lib/modes/slothlet_lazy.d.mts.map +0 -1
  189. package/types/index.d.mts.map +0 -1
package/AGENT-USAGE.md CHANGED
@@ -2,87 +2,68 @@
2
2
 
3
3
  > **Critical**: This guide prevents AI agents from making architectural mistakes when building Slothlet API modules.
4
4
 
5
- ## 📋 **Related Documentation**
5
+ ## 📋 Related Documentation
6
6
 
7
- - **[API-RULES.md](./API-RULES.md)** - 778+ lines of verified API transformation rules with test examples
8
- - **[README.md](./README.md)** - Complete project overview and usage examples
9
- - **[api_tests/\*/README.md](./api_tests/)** - Live examples demonstrating each pattern mentioned below
7
+ - **[`docs/API-RULES.md`](docs/API-RULES.md)** - All 13 API transformation rules with verified test examples
8
+ - **[`README.md`](README.md)** - Complete project overview and usage examples
9
+ - **[`api_tests/*/README.md`](api_tests/)** - Live examples demonstrating each pattern below
10
10
 
11
11
  ---
12
12
 
13
13
  ## 🚫 NEVER DO: Cross-Module Imports
14
14
 
15
- **The #1 mistake AI agents make with Slothlet**: Trying to import API files from each other.
15
+ **The #1 mistake AI agents make with Slothlet**: Importing API files from each other.
16
16
 
17
17
  ```js
18
18
  // ❌ WRONG - Do NOT import API modules from each other
19
19
  import { math } from "./math/math.mjs"; // BREAKS SLOTHLET
20
20
  import { config } from "../config.mjs"; // BREAKS SLOTHLET
21
21
  import { util } from "./util/util.mjs"; // BREAKS SLOTHLET
22
-
23
- // ❌ WRONG - Do NOT use relative imports between API modules
24
- import { someFunction } from "../../other-api.mjs"; // BREAKS SLOTHLET
25
22
  ```
26
23
 
27
24
  **Why this breaks Slothlet**:
28
25
 
29
- - Slothlet builds your API structure dynamically
26
+ - Slothlet builds API structure dynamically at runtime
30
27
  - Cross-imports create circular dependencies
31
28
  - Breaks lazy loading and context isolation
32
- - Defeats the purpose of module loading framework
29
+ - Defeats the purpose of the module loading framework
33
30
 
34
31
  ## ✅ CORRECT: Use Slothlet's Live-Binding System
35
32
 
36
33
  ```js
37
34
  // ✅ CORRECT - Import from Slothlet runtime for cross-module access
38
- import { self, context, reference } from "@cldmv/slothlet/runtime";
35
+ import { self, context } from "@cldmv/slothlet/runtime";
39
36
 
40
- // ✅ CORRECT - Access other modules through `self`
41
37
  export const myModule = {
42
38
  async processData(input) {
43
- // Access other API modules via `self`
39
+ // Access other API modules via `self` (live binding - always current)
44
40
  const mathResult = self.math.add(2, 3);
45
41
  const configValue = self.config.get("setting");
46
-
47
- return `Processed: ${input}, Math: ${mathResult}, Config: ${configValue}`;
42
+ // context holds the current request/call context
43
+ console.log(`Caller: ${context.userId}`);
44
+ return `Processed: ${input}, Math: ${mathResult}`;
48
45
  }
49
46
  };
50
47
  ```
51
48
 
52
- ## 🏗️ Slothlet API Module Patterns
49
+ ---
50
+
51
+ ## 🏗️ API Module Patterns
53
52
 
54
53
  ### Pattern 1: Simple Object Export (Most Common)
55
54
 
56
55
  **File**: `math/math.mjs` → **API**: `api.math.add()`, `api.math.multiply()`
57
56
 
58
57
  ```js
59
- /**
60
- * @fileoverview Math operations module. Internal file (not exported in package.json).
61
- * @module api_test.math
62
- * @memberof module:api_test
63
- */
64
-
65
- // ✅ Import runtime for cross-module access (if needed)
66
- // import { self, context, reference } from "@cldmv/slothlet/runtime";
67
-
68
- /**
69
- * Math operations object accessed as `api.math`.
70
- * @alias module:api_test.math
71
- */
72
58
  export const math = {
73
- add(a, b) {
74
- return a + b;
75
- },
76
-
77
- multiply(a, b) {
78
- return a * b;
79
- }
59
+ add(a, b) { return a + b; },
60
+ multiply(a, b) { return a * b; }
80
61
  };
81
62
  ```
82
63
 
83
64
  **Result**: Filename matches folder (`math/math.mjs`) → Auto-flattening → `api.math.add()` (not `api.math.math.add()`)
84
65
 
85
- > 📖 **See**: [API-RULES.md Rule 1](./API-RULES.md#rule-1-filename-matches-container-flattening) for technical implementation details
66
+ > 📖 See [API-RULES.md Rule 1](docs/API-RULES.md) for flattening details.
86
67
 
87
68
  ### Pattern 2: Multiple Files in Folder
88
69
 
@@ -90,47 +71,31 @@ export const math = {
90
71
 
91
72
  ```js
92
73
  // File: multi/alpha.mjs
93
- export const alpha = {
94
- hello() {
95
- return "alpha hello";
96
- }
97
- };
74
+ export const alpha = { hello() { return "alpha hello"; } };
98
75
 
99
76
  // File: multi/beta.mjs
100
- export const beta = {
101
- world() {
102
- return "beta world";
103
- }
104
- };
77
+ export const beta = { world() { return "beta world"; } };
105
78
  ```
106
79
 
107
- **Result**: Different filenames from folder → No flattening → Nested structure preserved
108
-
109
- > 📖 **See**: [API-RULES.md Rule 2](./API-RULES.md#rule-2-named-only-export-collection) for multi-file folder processing
80
+ **Result**: Different filenames from folder → No flattening → Nested structure preserved.
110
81
 
111
82
  ### Pattern 3: Default Function Export
112
83
 
113
84
  **File**: `funcmod/funcmod.mjs` → **API**: `api.funcmod(name)`
114
85
 
115
86
  ```js
116
- /**
117
- * Default function export accessed as `api.funcmod()`.
118
- * @param {string} name - Name to greet
119
- * @returns {string} Greeting message
120
- */
121
87
  export default function funcmod(name) {
122
88
  return `Hello, ${name}!`;
123
89
  }
124
90
  ```
125
91
 
126
- **Result**: Filename matches folder + default export → Function flattened to `api.funcmod()`
92
+ **Result**: Filename matches folder + default export → Function flattened to `api.funcmod()`.
127
93
 
128
94
  ### Pattern 4: Root-Level API Functions
129
95
 
130
96
  **File**: `root-function.mjs` → **API**: `api(name)` + `api.rootFunctionShout()`
131
97
 
132
98
  ```js
133
- // ✅ Root-level file creates top-level API methods
134
99
  export default function greet(name) {
135
100
  return `Hello, ${name}!`;
136
101
  }
@@ -140,283 +105,358 @@ export function rootFunctionShout(message) {
140
105
  }
141
106
  ```
142
107
 
143
- **Result**: Root file with default export → `api()` callable + named exports as `api.methodName()`
144
-
145
- > 📖 **See**: [API-RULES.md Rule 4](./API-RULES.md#rule-4-default-export-container-pattern) for root-level default export handling
108
+ **Result**: Root file with default export → `api()` callable + named exports as top-level `api.methodName()`.
146
109
 
147
110
  ### Pattern 5: AddApi Special File Pattern (Rule 11)
148
111
 
149
- **File**: `addapi.mjs` loaded via `addApi()` → **API**: Always flattened for API extensions
112
+ Files named `addapi.mjs` always flatten regardless of `autoFlatten` setting:
150
113
 
151
114
  ```js
152
115
  // File: plugins/addapi.mjs
153
- /**
154
- * Special addapi.mjs file for runtime API extensions.
155
- * Always flattens regardless of autoFlatten setting.
156
- */
157
- export function initializePlugin() {
158
- return "Plugin initialized";
159
- }
160
-
161
- export function cleanup() {
162
- return "Plugin cleaned up";
163
- }
164
-
165
- export function configure(options) {
166
- return `Configured with ${options}`;
167
- }
168
-
169
- // Usage:
170
- await api.addApi("plugins", "./plugins-folder");
116
+ export function initializePlugin() { return "Plugin initialized"; }
117
+ export function cleanup() { return "Plugin cleaned up"; }
118
+ ```
171
119
 
172
- // Result: Always flattened (no .addapi. level)
173
- api.plugins.initializePlugin(); // ✅ Direct extension
174
- api.plugins.cleanup(); // ✅ No intermediate namespace
175
- api.plugins.configure(opts); // ✅ Seamless integration
120
+ ```js
121
+ await api.slothlet.api.add("plugins", "./plugins-folder");
122
+ api.plugins.initializePlugin(); // ✅ Direct extension - no intermediate namespace
176
123
  ```
177
124
 
178
- **Result**: `addapi.mjs` always flattens Perfect for plugin systems and runtime extensions
125
+ > 📖 See [API-RULES.md Rule 11](docs/API-RULES.md) for addApi flattening details.
179
126
 
180
- **Use Cases**:
127
+ ---
181
128
 
182
- - 🔌 **Plugin Systems**: Runtime plugin loading
183
- - 🔄 **Hot Reloading**: Dynamic API updates during development
184
- - 📦 **Modular Extensions**: Clean extension of existing API surfaces
129
+ ## 🔄 Operating Modes
185
130
 
186
- > 📖 **See**: [API-RULES.md Rule 11](./API-RULES.md#rule-11-addapi-special-file-pattern) for technical implementation details
131
+ Slothlet supports two loading modes set via `mode:` in the config:
187
132
 
188
- ## 🔄 Cross-Module Communication Patterns
133
+ ### Eager Mode (default)
189
134
 
190
- ### Using Live Bindings
135
+ All modules are loaded synchronously at `await slothlet(...)`. The API is fully populated before `slothlet()` resolves.
191
136
 
192
137
  ```js
193
- // File: interop/esm-module.mjs
194
- import { self, context } from "@cldmv/slothlet/runtime";
138
+ const api = await slothlet({ dir: "./api" }); // mode: "eager" is default
139
+ // All api.* properties are immediately available
140
+ ```
195
141
 
196
- export const interopEsm = {
197
- async testCrossCall(a, b) {
198
- console.log(`ESM Context: User=${context.user}`);
142
+ ### Lazy Mode
199
143
 
200
- // CORRECT - Access other modules via self
201
- if (self?.mathCjs?.multiply) {
202
- const result = self.mathCjs.multiply(a, b);
203
- return result;
204
- }
144
+ Modules are loaded on first access via transparent proxy. `slothlet()` resolves immediately without loading any files.
205
145
 
206
- throw new Error("CJS mathCjs.multiply not available via self");
207
- }
208
- };
146
+ ```js
147
+ const api = await slothlet({
148
+ dir: "./api",
149
+ mode: "lazy"
150
+ });
151
+ // api.math is a proxy - file not loaded yet
152
+ const result = api.math.add(2, 3); // First access triggers load
209
153
  ```
210
154
 
211
- ### Context Isolation
155
+ #### Background Materialization
156
+
157
+ Enable `backgroundMaterialize: true` to pre-load all modules in the background immediately after init (still non-blocking):
212
158
 
213
159
  ```js
214
- // Each Slothlet instance gets isolated context
215
- const api1 = await slothlet({
160
+ const api = await slothlet({
216
161
  dir: "./api",
217
- context: { user: "alice", session: "session1" }
162
+ mode: "lazy",
163
+ backgroundMaterialize: true
218
164
  });
219
165
 
220
- const api2 = await slothlet({
221
- dir: "./api",
222
- context: { user: "bob", session: "session2" }
166
+ // Subscribe to completion event
167
+ api.slothlet.lifecycle.on("materialized:complete", (data) => {
168
+ console.log(`${data.total} modules materialized`);
223
169
  });
224
170
 
225
- // Contexts are isolated - alice can't see bob's data
171
+ // Or await all modules to be ready
172
+ await api.slothlet.materialize.wait();
173
+
174
+ // Or check current progress
175
+ const stats = api.slothlet.materialize.get();
176
+ // { total, materialized, remaining, percentage }
226
177
  ```
227
178
 
228
- ## 🎣 Hook System (v2.6.4+)
179
+ **Important**: Lazy mode hot reload intentionally restores modules to an unmaterialized state on reload (references are not preserved). Eager mode preserves existing references by merging into the live wrapper.
180
+
181
+ ---
182
+
183
+ ## 🎣 Hook System
229
184
 
230
- Slothlet provides a powerful hook system for intercepting and modifying API function calls. Hooks work across all modes and runtimes.
185
+ Hooks intercept API function calls. They work across all modes. See [`docs/HOOKS.md`](docs/HOOKS.md) for the full reference.
231
186
 
232
187
  ### Hook Configuration
233
188
 
234
189
  ```js
235
- // Enable hooks with default settings
236
- const api = await slothlet({
237
- dir: "./api",
238
- hooks: true // Enables all hooks with pattern "**"
239
- });
190
+ // Simple enable (default pattern "**")
191
+ const api = await slothlet({ dir: "./api", hook: true });
240
192
 
241
- // Enable with error suppression
193
+ // Enable with default pattern filter
194
+ const api = await slothlet({ dir: "./api", hook: "database.*" });
195
+
196
+ // Full configuration
242
197
  const api = await slothlet({
243
198
  dir: "./api",
244
- hooks: {
199
+ hook: {
245
200
  enabled: true,
246
201
  pattern: "**",
247
- suppressErrors: true // Errors reported to error hooks only, not thrown
202
+ suppressErrors: false // true = errors suppressed (returns undefined instead of throwing)
248
203
  }
249
204
  });
250
205
  ```
251
206
 
252
207
  ### Hook Types
253
208
 
254
- **Four hook types available:**
255
-
256
- - **`before`**: Intercept before function execution
257
- - Modify arguments
258
- - Cancel execution (short-circuit) and return custom value
259
- - Validation and pre-processing
260
-
261
- - **`after`**: Transform results after execution
262
- - Transform return values
263
- - Only runs if function executes
264
- - Chain transformations
265
-
266
- - **`always`**: Observe final result (read-only)
267
- - Always executes (even on short-circuit)
268
- - Cannot modify result
269
- - Perfect for logging and metrics
270
-
271
- - **`error`**: Monitor and handle errors
272
- - Receives detailed error context
273
- - Source tracking (before/function/after/always)
274
- - Error class identification
209
+ - **`before`** - Executes before the function. Can modify arguments or short-circuit. **Must be synchronous.**
210
+ - **`after`** - Executes after successful completion. Can transform the return value.
211
+ - **`always`** - Read-only observer. Always executes (even on short-circuit). Return value ignored.
212
+ - **`error`** - Executes only when an error occurs. Receives error with source tracking.
275
213
 
276
214
  ### Basic Hook Usage
277
215
 
216
+ The `hook.on(typePattern, handler, options)` signature uses `"type:pattern"` as the first argument:
217
+
278
218
  ```js
279
219
  // Before hook - modify arguments
280
- api.hooks.on(
281
- "validate-input",
282
- "before",
283
- ({ path, args }) => {
284
- console.log(`Calling ${path} with:`, args);
285
- return [args[0] * 2, args[1] * 2]; // Modified args
220
+ api.slothlet.hook.on(
221
+ "before:math.add",
222
+ ({ path, args, ctx }) => {
223
+ return [args[0] * 2, args[1] * 2]; // Return array to replace arguments
224
+ // Return any non-array non-undefined value to short-circuit (skip function)
225
+ // Return undefined to continue with original args
286
226
  },
287
- { pattern: "math.add", priority: 100 }
227
+ { id: "double-args", priority: 100 }
288
228
  );
289
229
 
290
230
  // After hook - transform result
291
- api.hooks.on(
292
- "format-output",
293
- "after",
294
- ({ path, result }) => {
295
- return result * 10; // Transform result
231
+ api.slothlet.hook.on(
232
+ "after:math.*",
233
+ ({ path, args, result, ctx }) => {
234
+ return result * 10; // Return value to replace result; undefined = no change
296
235
  },
297
- { pattern: "math.*" }
236
+ { id: "scale-result" }
298
237
  );
299
238
 
300
239
  // Always hook - observe (read-only)
301
- api.hooks.on(
302
- "log-final",
303
- "always",
304
- ({ path, result }) => {
305
- console.log(`Final: ${path} = ${result}`);
240
+ api.slothlet.hook.on(
241
+ "always:**",
242
+ ({ path, result, hasError, errors }) => {
243
+ if (hasError) console.error(`${path} failed:`, errors);
244
+ else console.log(`${path} returned:`, result);
245
+ // Return value is ignored
306
246
  },
307
- { pattern: "**" }
247
+ { id: "logger" }
308
248
  );
309
249
 
310
250
  // Error hook - monitor failures
311
- api.hooks.on(
312
- "error-monitor",
313
- "error",
314
- ({ path, error, source, errorType }) => {
315
- console.error(`${source.type} error in ${path}:`, error.message);
316
- console.error(`Error type: ${errorType}`);
251
+ api.slothlet.hook.on(
252
+ "error:**",
253
+ ({ path, error, source }) => {
254
+ // source.type: "before" | "after" | "always" | "function"
255
+ console.error(`Error in ${path} (from ${source.type}):`, error.message);
317
256
  },
318
- { pattern: "**" }
257
+ { id: "error-monitor" }
319
258
  );
320
259
  ```
321
260
 
322
- ### Hook Pattern Matching
261
+ ### Pattern Matching
323
262
 
324
- ```js
325
- // Exact match
326
- api.hooks.on("hook1", "before", handler, { pattern: "math.add" });
263
+ | Syntax | Description | Example |
264
+ |---|---|---|
265
+ | `exact.path` | Exact match | `"before:math.add"` |
266
+ | `namespace.*` | All functions in namespace | `"after:math.*"` |
267
+ | `*.funcName` | Function name across namespaces | `"always:*.add"` |
268
+ | `**` | All functions | `"error:**"` |
269
+ | `{a,b}` | Brace expansion | `"before:{math,utils}.*"` |
270
+ | `!pattern` | Negation | `"before:!internal.*"` |
327
271
 
328
- // Namespace wildcard
329
- api.hooks.on("hook2", "before", handler, { pattern: "math.*" });
272
+ ### Hook Subsets
330
273
 
331
- // Function wildcard
332
- api.hooks.on("hook3", "before", handler, { pattern: "*.add" });
333
-
334
- // All functions
335
- api.hooks.on("hook4", "before", handler, { pattern: "**" });
336
- ```
274
+ Each hook type has three ordered execution phases:
337
275
 
338
- ### Short-Circuit Execution
276
+ | Subset | Order | Typical use |
277
+ |---|---|---|
278
+ | `"before"` | First | Auth checks, security validation |
279
+ | `"primary"` | Middle (default) | Main hook logic |
280
+ | `"after"` | Last | Audit trails, cleanup |
339
281
 
340
282
  ```js
341
- // Return non-undefined value to short-circuit
342
- api.hooks.on(
343
- "cache-check",
344
- "before",
345
- ({ path, args }) => {
346
- const key = JSON.stringify({ path, args });
347
- if (cache.has(key)) {
348
- return cache.get(key); // Skip function execution
349
- }
350
- // Return undefined to continue
351
- },
352
- { pattern: "**", priority: 1000 }
283
+ api.slothlet.hook.on(
284
+ "before:protected.*",
285
+ ({ ctx }) => { if (!ctx.user) throw new Error("Unauthorized"); },
286
+ { id: "auth", subset: "before", priority: 2000 }
353
287
  );
354
288
  ```
355
289
 
356
- ### Error Suppression
290
+ ### Hook Management
291
+
292
+ ```js
293
+ // Remove by ID
294
+ api.slothlet.hook.remove({ id: "my-hook" });
295
+ api.slothlet.hook.off("my-hook"); // alias for remove
296
+
297
+ // Remove by filter
298
+ api.slothlet.hook.remove({ type: "before", pattern: "math.*" });
357
299
 
358
- Error hooks **ALWAYS receive errors** regardless of the `suppressErrors` setting. This option only controls whether errors are thrown after error hooks execute.
300
+ // Remove all
301
+ api.slothlet.hook.clear();
359
302
 
360
- **Important**: Hooks must be enabled (`enabled: true`) for error hooks to work. If hooks are disabled, all hooks (including error hooks) are bypassed and errors throw normally.
303
+ // List hooks
304
+ const all = api.slothlet.hook.list();
305
+ const active = api.slothlet.hook.list({ enabled: true });
361
306
 
362
- **Default behavior (`suppressErrors: false`)**:
307
+ // Enable / disable without unregistering
308
+ api.slothlet.hook.disable(); // disable all
309
+ api.slothlet.hook.disable({ pattern: "math.*" });
310
+ api.slothlet.hook.enable(); // re-enable all
311
+ api.slothlet.hook.enable({ type: "before" });
312
+ ```
363
313
 
364
- - Errors sent to error hooks, THEN thrown
365
- - Application crashes on uncaught errors
314
+ ---
366
315
 
367
- **Suppressed errors (`suppressErrors: true`)**:
316
+ ## 🔄 Per-Request Context
368
317
 
369
- - Errors sent to error hooks, BUT NOT thrown
370
- - Function returns `undefined` instead of throwing
371
- - All hook errors suppressed (before, after, always)
372
- - Perfect for resilient systems with monitoring
318
+ Execute functions with temporary merged context using `api.slothlet.context`:
373
319
 
374
320
  ```js
375
321
  const api = await slothlet({
376
322
  dir: "./api",
377
- hooks: {
378
- enabled: true,
379
- suppressErrors: true // Suppress all errors
380
- }
323
+ context: { appName: "MyApp", version: "3.0" }
381
324
  });
382
325
 
383
- api.hooks.on(
384
- "error-log",
385
- "error",
386
- ({ path, error }) => {
387
- // Log error without crashing app
388
- sendToMonitoring(path, error);
389
- },
390
- { pattern: "**" }
326
+ // run() - execute a function inside a scoped context
327
+ await api.slothlet.context.run({ userId: "alice", role: "admin" }, async () => {
328
+ // Inside this scope: context = { appName, version, userId, role }
329
+ await api.database.query();
330
+ await api.audit.log();
331
+ });
332
+
333
+ // scope() - return a new API object with merged context
334
+ const scopedApi = api.slothlet.context.scope({ userId: "bob" });
335
+ await scopedApi.database.query(); // context includes userId: "bob"
336
+ ```
337
+
338
+ ### Deep Merge Strategy
339
+
340
+ ```js
341
+ // Default: shallow merge (top-level properties replaced)
342
+ await api.slothlet.context.run({ newProp: "value" }, handler);
343
+
344
+ // Deep merge: nested objects recursively merged
345
+ await api.slothlet.context.run(
346
+ { nested: { prop: "value" } },
347
+ handler,
348
+ { mergeStrategy: "deep" }
391
349
  );
350
+ ```
392
351
 
393
- // Function fails gracefully
394
- const result = await api.riskyOperation();
395
- if (result === undefined) {
396
- console.log("Operation failed but didn't crash");
397
- }
352
+ ### Automatic EventEmitter Context Propagation
353
+
354
+ Context propagates automatically through EventEmitter callbacks:
355
+
356
+ ```js
357
+ import net from "net";
358
+ import { context } from "@cldmv/slothlet/runtime";
359
+
360
+ export const server = {
361
+ async start() {
362
+ const tcpServer = net.createServer((socket) => {
363
+ // Context automatically available in connection handler
364
+ console.log(`User ${context.userId} connected`);
365
+
366
+ socket.on("data", (data) => {
367
+ // Context preserved in nested event callbacks
368
+ console.log(`Data from ${context.userId}: ${data}`);
369
+ });
370
+ });
371
+ tcpServer.listen(3000);
372
+ }
373
+ };
398
374
  ```
399
375
 
400
- ### Hook Management
376
+ Works with: TCP servers, HTTP servers, custom EventEmitters, unlimited nested callbacks.
377
+
378
+ > 📖 See [`docs/CONTEXT-PROPAGATION.md`](docs/CONTEXT-PROPAGATION.md) for full documentation.
379
+
380
+ ---
381
+
382
+ ## 🏷️ Metadata System
383
+
384
+ Tag API paths with metadata for authorization, auditing, and security. See [`docs/METADATA.md`](docs/METADATA.md) for the full reference.
385
+
386
+ ```js
387
+ // Set metadata when loading (via api.slothlet.api.add)
388
+ await api.slothlet.api.add("plugins/trusted", "./trusted-dir", {
389
+ metadata: { trusted: true, securityLevel: "high" }
390
+ });
391
+
392
+ // Set metadata at runtime
393
+ api.slothlet.metadata.set("plugins.trusted.someFunc", { version: 2 });
394
+ api.slothlet.metadata.setGlobal({ environment: "production" });
395
+ api.slothlet.metadata.setFor("plugins/trusted", { owner: "core-team" });
396
+
397
+ // Read metadata inside a module
398
+ import { self } from "@cldmv/slothlet/runtime";
399
+
400
+ export const secureOperation = {
401
+ async execute() {
402
+ // Access metadata via api.slothlet.metadata from within a module via self
403
+ // Or read it externally:
404
+ // const meta = api.slothlet.metadata.get("plugins.trusted.execute");
405
+ return "Authorized execution";
406
+ }
407
+ };
408
+ ```
409
+
410
+ ---
411
+
412
+ ## 🔁 Hot Reload / Dynamic API Management
401
413
 
402
414
  ```js
403
- // Register hook and get ID
404
- const hookId = api.hooks.on("my-hook", "before", handler, { pattern: "**" });
415
+ // Add new modules at runtime
416
+ await api.slothlet.api.add("newModule", "./new-module-path");
417
+ await api.slothlet.api.add("plugins", "./plugins", { collision: "merge" });
418
+
419
+ // Remove modules by path
420
+ await api.slothlet.api.remove("oldModule");
421
+
422
+ // Reload all modules
423
+ await api.slothlet.reload();
424
+
425
+ // Reload specific API path
426
+ await api.slothlet.api.reload("database.*");
427
+ await api.slothlet.api.reload("plugins.auth");
428
+ ```
429
+
430
+ > **Lazy mode reload behavior**: In lazy mode, reload restores modules to an unmaterialized proxy state - existing references to lazy wrappers are intentionally not preserved. Eager mode merges new module exports into the existing live wrapper, preserving references.
431
+
432
+ > 📖 See [`docs/RELOAD.md`](docs/RELOAD.md) for reload system documentation.
433
+
434
+ ---
405
435
 
406
- // Remove specific hook
407
- api.hooks.off(hookId);
436
+ ## Lifecycle Events
408
437
 
409
- // Clear all hooks
410
- api.hooks.clear();
438
+ Subscribe to internal API events via `api.slothlet.lifecycle`:
411
439
 
412
- // List registered hooks
413
- const hooks = api.hooks.list();
440
+ ```js
441
+ // Available events
442
+ api.slothlet.lifecycle.on("materialized:complete", (data) => {
443
+ console.log(`${data.total} modules materialized`);
444
+ });
414
445
 
415
- // Enable/disable hooks at runtime
416
- api.hooks.disable(); // Fast-path bypass
417
- api.hooks.enable("database.*"); // Re-enable with new pattern
446
+ api.slothlet.lifecycle.on("impl:changed", (data) => {
447
+ console.log(`Module at ${data.apiPath} was reloaded`);
448
+ });
449
+
450
+ // Unsubscribe
451
+ const handler = (data) => console.log(data);
452
+ api.slothlet.lifecycle.on("materialized:complete", handler);
453
+ api.slothlet.lifecycle.off("materialized:complete", handler);
418
454
  ```
419
455
 
456
+ **Available events**: `"materialized:complete"`, `"impl:created"`, `"impl:changed"`, `"impl:removed"`
457
+
458
+ ---
459
+
420
460
  ## 📁 File Organization Best Practices
421
461
 
422
462
  ### ✅ Clean Folder Structure
@@ -425,7 +465,7 @@ api.hooks.enable("database.*"); // Re-enable with new pattern
425
465
  api/
426
466
  ├── config.mjs → api.config.*
427
467
  ├── math/
428
- │ └── math.mjs → api.math.* (flattened)
468
+ │ └── math.mjs → api.math.* (flattened - filename matches folder)
429
469
  ├── util/
430
470
  │ ├── util.mjs → api.util.* (flattened methods)
431
471
  │ ├── extract.mjs → api.util.extract.*
@@ -438,140 +478,130 @@ api/
438
478
  └── beta.mjs → api.multi.beta.*
439
479
  ```
440
480
 
441
- ### ✅ Module Naming Conventions
481
+ ### ✅ Naming Conventions
442
482
 
443
- - **Filename matches folder** → Auto-flattening (cleaner API)
483
+ - **Filename matches folder** → Auto-flattening (`math/math.mjs` → `api.math.*`)
444
484
  - **Different filename** → Nested structure preserved
445
485
  - **Dash-separated names** → camelCase API (`auto-ip.mjs` → `api.autoIP`)
446
- - **Function name preference** → Original capitalization preserved (`autoIP`, `parseJSON`) - [See API-RULES.md Rule 9](./API-RULES.md#rule-9-function-name-preference-over-sanitization)
447
-
448
- ## 🧪 JSDoc Documentation Patterns
449
-
450
- > 📖 **For detailed JSDoc templates and examples**, see [.github/copilot-instructions.md - JSDoc Standards](./.github/copilot-instructions.md#-jsdoc-standards--patterns)
486
+ - **Function name preferred** → Original capitalization kept over sanitized form
487
+ (see [Rule 9](docs/API-RULES.md))
451
488
 
452
- ### ✅ Primary Module File (One per folder)
453
-
454
- ```js
455
- /**
456
- * @fileoverview Math operations for API testing.
457
- * @module api_test
458
- * @name api_test
459
- * @alias @cldmv/slothlet/api_tests/api_test
460
- */
461
- ```
462
-
463
- ### ✅ Secondary Contributing Files
464
-
465
- ```js
466
- /**
467
- * @fileoverview Math utilities. Internal file (not exported in package.json).
468
- * @module api_test.math
469
- * @memberof module:api_test
470
- */
471
- ```
472
-
473
- ### ✅ Live-Binding Imports Pattern
474
-
475
- ```js
476
- // ✅ Always include runtime imports (even if commented out for structure)
477
- // import { self, context, reference } from "@cldmv/slothlet/runtime";
478
- ```
489
+ ---
479
490
 
480
491
  ## 🚨 Common AI Agent Mistakes
481
492
 
482
- > 📖 **For complete technical details on all API transformation rules**, see [API-RULES.md](./API-RULES.md) (778+ lines of verified examples)
483
-
484
493
  ### ❌ Mistake 1: Cross-Module Imports
485
494
 
486
495
  ```js
487
496
  // ❌ WRONG
488
497
  import { config } from "./config.mjs";
498
+ // ✅ CORRECT
499
+ import { self } from "@cldmv/slothlet/runtime";
500
+ // then: self.config.get(...)
489
501
  ```
490
502
 
491
- ### ❌ Mistake 2: Missing Runtime Imports
503
+ ### ❌ Mistake 2: Using V2 API Surface
492
504
 
493
505
  ```js
494
- // ❌ WRONG - No way to access other modules
495
- export const module = {
496
- method() {
497
- // How do I access other modules? 🤔
498
- }
499
- };
506
+ // ❌ WRONG (v2 API - does not exist in v3)
507
+ await api.addApi("plugins", "./dir");
508
+ await api.reloadApi("math.*");
509
+ api.hooks.on("validate", "before", handler, { pattern: "math.*" });
510
+ await api.run({ userId: "alice" }, fn);
511
+
512
+ // ✅ CORRECT (v3 API)
513
+ await api.slothlet.api.add("plugins", "./dir");
514
+ await api.slothlet.api.reload("math.*");
515
+ api.slothlet.hook.on("before:math.*", handler);
516
+ await api.slothlet.context.run({ userId: "alice" }, fn);
500
517
  ```
501
518
 
502
- ### ❌ Mistake 3: Wrong JSDoc Module Patterns
519
+ ### ❌ Mistake 3: Wrong Hook Config Key
503
520
 
504
521
  ```js
505
- // ❌ WRONG - Multiple @module declarations create duplicates
506
- /**
507
- * @module api_test ← Already declared elsewhere
508
- * @module api_test.math ← Should only use @memberof
509
- */
522
+ // ❌ WRONG
523
+ const api = await slothlet({ dir: "./api", hooks: true }); // "hooks" plural
524
+
525
+ // CORRECT
526
+ const api = await slothlet({ dir: "./api", hook: true }); // "hook" singular
510
527
  ```
511
528
 
512
529
  ### ❌ Mistake 4: Breaking Auto-Flattening
513
530
 
514
531
  ```js
515
- // File: math/calculator.mjs (different name than folder)
516
- export const math = {
517
- /* methods */
518
- };
519
- // Result: api.math.calculator.math.* (nested, not flattened)
532
+ // File: math/calculator.mjs (different name from folder)
533
+ export const math = { /* methods */ };
534
+ // Result: api.math.calculator.math.* ← extra nesting, not flattened
520
535
 
521
536
  // ✅ CORRECT: File math/math.mjs
522
- export const math = {
523
- /* methods */
524
- };
525
- // Result: api.math.* (flattened)
537
+ export const math = { /* methods */ };
538
+ // Result: api.math.* ← flattened
526
539
  ```
527
540
 
528
- ## AI Agent Checklist
541
+ ### Mistake 5: Using lifecycle.subscribe / lifecycle.emit
542
+
543
+ ```js
544
+ // ❌ WRONG - subscribe/emit are internal
545
+ api.slothlet.lifecycle.subscribe("materialized:complete", handler);
546
+ api.slothlet.lifecycle.emit("impl:changed", data);
547
+
548
+ // ✅ CORRECT - public surface is on/off only
549
+ api.slothlet.lifecycle.on("materialized:complete", handler);
550
+ api.slothlet.lifecycle.off("materialized:complete", handler);
551
+ ```
552
+
553
+ ---
529
554
 
530
- When building Slothlet API modules:
555
+ ## AI Agent Checklist
531
556
 
532
- - [ ] **NO cross-module imports** - Use `self` from runtime instead
533
- - [ ] **Import runtime** - `import { self, context, reference } from "@cldmv/slothlet/runtime"`
557
+ - [ ] **No cross-module imports** - use `self` from `@cldmv/slothlet/runtime` instead
534
558
  - [ ] **Match filename to folder** for cleaner APIs (auto-flattening)
535
- - [ ] **Use proper JSDoc patterns** - One `@module` per folder, `@memberof` for secondary files
536
- - [ ] **Test cross-module access** via `self.otherModule.method()`
537
- - [ ] **Include context usage** if module needs user/session data
538
- - [ ] **Consider hooks** - Will functions be intercepted? Need error monitoring?
539
- - [ ] **Double quotes everywhere** - Follow Slothlet coding standards
559
+ - [ ] **Hook config key is `hook:` (singular)**, not `hooks:`
560
+ - [ ] **Hook API** is `api.slothlet.hook.*`, not `api.hooks.*`
561
+ - [ ] **Context API** is `api.slothlet.context.run/scope()`, not `api.run/scope()`
562
+ - [ ] **Reload/add/remove** is `api.slothlet.api.add/remove/reload()`, not `api.addApi()` etc.
563
+ - [ ] **Lifecycle** uses `api.slothlet.lifecycle.on/off()` only
564
+ - [ ] **Lazy mode**: if using background materialization, use `api.slothlet.materialize.wait()` before accessing the API
565
+ - [ ] **Hook subsets**: auth/security → `subset: "before"`, main logic → `"primary"`, audit → `"after"`
566
+ - [ ] **Double quotes everywhere** - follow Slothlet coding standards
567
+
568
+ ---
540
569
 
541
570
  ## 📚 Reference Examples
542
571
 
543
572
  - **Auto-flattening**: `api_tests/api_test/math/math.mjs`
544
573
  - **Multi-file folders**: `api_tests/api_test/multi/`
545
- - **Cross-module calls**: `api_tests/api_test_mixed/interop/`
574
+ - **Cross-module calls**: `api_tests/api_test_mixed/`
546
575
  - **Root-level APIs**: `api_tests/api_test/root-function.mjs`
547
576
  - **Nested structures**: `api_tests/api_test/nested/date/`
548
577
 
549
- ## 📖 Essential Documentation for AI Agents
550
-
551
- ### 🏗️ **Core Architecture & Patterns**
552
-
553
- - **[`API-RULES.md`](./API-RULES.md)** - **CRITICAL** - Comprehensive verified rules for API transformation (778+ lines of verified examples)
554
- - **[`API-RULES-CONDITIONS.md`](./API-RULES-CONDITIONS.md)** - Technical reference for all conditional logic controlling API generation
555
-
556
- ### � **Usage & Installation**
557
-
558
- - **[`README.md`](./README.md)** - Complete project overview, installation, and usage examples
578
+ ---
559
579
 
560
- ### 🧪 **Live Examples & Patterns**
580
+ ## 📖 Essential Documentation
561
581
 
562
- - **[`api_tests/api_test/README.md`](./api_tests/api_test/README.md)** - ESM module patterns and filename-folder flattening
563
- - **[`api_tests/api_test_cjs/README.md`](./api_tests/api_test_cjs/)** - CommonJS module patterns and interoperability
564
- - **[`api_tests/api_test_mixed/README.md`](./api_tests/api_test_mixed/)** - Mixed ESM/CJS patterns and live-binding examples
582
+ ### Core Architecture
565
583
 
566
- ### 🔧 **Advanced Pattern Documentation**
584
+ - **[`docs/API-RULES.md`](docs/API-RULES.md)** - All 13 API transformation rules
585
+ - **[`docs/API-RULES/API-RULES-CONDITIONS.md`](docs/API-RULES/API-RULES-CONDITIONS.md)** - All C01–C34 conditional logic
586
+ - **[`docs/API-RULES/API-FLATTENING.md`](docs/API-RULES/API-FLATTENING.md)** - Flattening rules F01–F08
567
587
 
568
- - **[`docs/generated/api_tests/`](./docs/generated/api_tests/)** - Generated documentation for all test module patterns
588
+ ### Configuration & Features
569
589
 
570
- ### **Critical Reading Order for AI Agents**
590
+ - **[`docs/CONFIGURATION.md`](docs/CONFIGURATION.md)** - All config options
591
+ - **[`docs/HOOKS.md`](docs/HOOKS.md)** - Hook system (types, subsets, patterns, management)
592
+ - **[`docs/METADATA.md`](docs/METADATA.md)** - Metadata system
593
+ - **[`docs/CONTEXT-PROPAGATION.md`](docs/CONTEXT-PROPAGATION.md)** - Per-request context and EventEmitter propagation
594
+ - **[`docs/RELOAD.md`](docs/RELOAD.md)** - Hot reload and dynamic API management
595
+ - **[`docs/LIFECYCLE.md`](docs/LIFECYCLE.md)** - Lazy mode, materialization, and lifecycle events
596
+ - **[`docs/SANITIZATION.md`](docs/SANITIZATION.md)** - Property name sanitization rules
597
+ - **[`docs/I18N.md`](docs/I18N.md)** - Internationalization and language support
598
+ - **[`docs/PERFORMANCE.md`](docs/PERFORMANCE.md)** - Performance characteristics and benchmarks
571
599
 
572
- 1. **This file (`AGENT-USAGE.md`)** - Prevents major architectural mistakes
573
- 2. **[`README.md`](./README.md)** - Complete project context and installation
574
- 3. **[`API-RULES.md`](./API-RULES.md)** - Understand verified API transformation patterns
575
- 4. **[`api_tests/*/README.md`](./api_tests/)** - Live examples of each pattern
600
+ ### Critical Reading Order for AI Agents
576
601
 
577
- Understanding these patterns and documentation is essential for building effective Slothlet APIs that work with the framework rather than against it.
602
+ 1. **This file** - Prevents architectural mistakes
603
+ 2. **[`README.md`](README.md)** - Project overview and quickstart
604
+ 3. **[`docs/API-RULES.md`](docs/API-RULES.md)** - API transformation rules
605
+ 4. **[`docs/HOOKS.md`](docs/HOOKS.md)** - Hook system (if needed)
606
+ 5. **[`docs/METADATA.md`](docs/METADATA.md)** - Metadata system (if needed)
607
+ 6. **[`api_tests/api_test/README.md`](api_tests/api_test/README.md)** - Live examples