@cldmv/slothlet 2.6.3 โ†’ 2.7.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.
package/AGENT-USAGE.md ADDED
@@ -0,0 +1,536 @@
1
+ # AGENT-USAGE.md: Building Slothlet API Folders
2
+
3
+ > **Critical**: This guide prevents AI agents from making architectural mistakes when building Slothlet API modules.
4
+
5
+ ## ๐Ÿ“‹ **Related Documentation**
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
10
+
11
+ ---
12
+
13
+ ## ๐Ÿšซ NEVER DO: Cross-Module Imports
14
+
15
+ **The #1 mistake AI agents make with Slothlet**: Trying to import API files from each other.
16
+
17
+ ```js
18
+ // โŒ WRONG - Do NOT import API modules from each other
19
+ import { math } from "./math/math.mjs"; // BREAKS SLOTHLET
20
+ import { config } from "../config.mjs"; // BREAKS SLOTHLET
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
+ ```
26
+
27
+ **Why this breaks Slothlet**:
28
+
29
+ - Slothlet builds your API structure dynamically
30
+ - Cross-imports create circular dependencies
31
+ - Breaks lazy loading and context isolation
32
+ - Defeats the purpose of module loading framework
33
+
34
+ ## โœ… CORRECT: Use Slothlet's Live-Binding System
35
+
36
+ ```js
37
+ // โœ… CORRECT - Import from Slothlet runtime for cross-module access
38
+ import { self, context, reference } from "@cldmv/slothlet/runtime";
39
+
40
+ // โœ… CORRECT - Access other modules through `self`
41
+ export const myModule = {
42
+ async processData(input) {
43
+ // Access other API modules via `self`
44
+ const mathResult = self.math.add(2, 3);
45
+ const configValue = self.config.get("setting");
46
+
47
+ return `Processed: ${input}, Math: ${mathResult}, Config: ${configValue}`;
48
+ }
49
+ };
50
+ ```
51
+
52
+ ## ๐Ÿ—๏ธ Slothlet API Module Patterns
53
+
54
+ ### Pattern 1: Simple Object Export (Most Common)
55
+
56
+ **File**: `math/math.mjs` โ†’ **API**: `api.math.add()`, `api.math.multiply()`
57
+
58
+ ```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
+ export const math = {
73
+ add(a, b) {
74
+ return a + b;
75
+ },
76
+
77
+ multiply(a, b) {
78
+ return a * b;
79
+ }
80
+ };
81
+ ```
82
+
83
+ **Result**: Filename matches folder (`math/math.mjs`) โ†’ Auto-flattening โ†’ `api.math.add()` (not `api.math.math.add()`)
84
+
85
+ > ๐Ÿ“– **See**: [API-RULES.md Rule 1](./API-RULES.md#rule-1-filename-matches-container-flattening) for technical implementation details
86
+
87
+ ### Pattern 2: Multiple Files in Folder
88
+
89
+ **Files**: `multi/alpha.mjs`, `multi/beta.mjs` โ†’ **API**: `api.multi.alpha.hello()`, `api.multi.beta.world()`
90
+
91
+ ```js
92
+ // File: multi/alpha.mjs
93
+ export const alpha = {
94
+ hello() {
95
+ return "alpha hello";
96
+ }
97
+ };
98
+
99
+ // File: multi/beta.mjs
100
+ export const beta = {
101
+ world() {
102
+ return "beta world";
103
+ }
104
+ };
105
+ ```
106
+
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
110
+
111
+ ### Pattern 3: Default Function Export
112
+
113
+ **File**: `funcmod/funcmod.mjs` โ†’ **API**: `api.funcmod(name)`
114
+
115
+ ```js
116
+ /**
117
+ * Default function export accessed as `api.funcmod()`.
118
+ * @param {string} name - Name to greet
119
+ * @returns {string} Greeting message
120
+ */
121
+ export default function funcmod(name) {
122
+ return `Hello, ${name}!`;
123
+ }
124
+ ```
125
+
126
+ **Result**: Filename matches folder + default export โ†’ Function flattened to `api.funcmod()`
127
+
128
+ ### Pattern 4: Root-Level API Functions
129
+
130
+ **File**: `root-function.mjs` โ†’ **API**: `api(name)` + `api.rootFunctionShout()`
131
+
132
+ ```js
133
+ // โœ… Root-level file creates top-level API methods
134
+ export default function greet(name) {
135
+ return `Hello, ${name}!`;
136
+ }
137
+
138
+ export function rootFunctionShout(message) {
139
+ return message.toUpperCase();
140
+ }
141
+ ```
142
+
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
146
+
147
+ ## ๐Ÿ”„ Cross-Module Communication Patterns
148
+
149
+ ### โœ… Using Live Bindings
150
+
151
+ ```js
152
+ // File: interop/esm-module.mjs
153
+ import { self, context } from "@cldmv/slothlet/runtime";
154
+
155
+ export const interopEsm = {
156
+ async testCrossCall(a, b) {
157
+ console.log(`ESM Context: User=${context.user}`);
158
+
159
+ // โœ… CORRECT - Access other modules via self
160
+ if (self?.mathCjs?.multiply) {
161
+ const result = self.mathCjs.multiply(a, b);
162
+ return result;
163
+ }
164
+
165
+ throw new Error("CJS mathCjs.multiply not available via self");
166
+ }
167
+ };
168
+ ```
169
+
170
+ ### โœ… Context Isolation
171
+
172
+ ```js
173
+ // Each Slothlet instance gets isolated context
174
+ const api1 = await slothlet({
175
+ dir: "./api",
176
+ context: { user: "alice", session: "session1" }
177
+ });
178
+
179
+ const api2 = await slothlet({
180
+ dir: "./api",
181
+ context: { user: "bob", session: "session2" }
182
+ });
183
+
184
+ // Contexts are isolated - alice can't see bob's data
185
+ ```
186
+
187
+ ## ๐ŸŽฃ Hook System (v2.6.4+)
188
+
189
+ Slothlet provides a powerful hook system for intercepting and modifying API function calls. Hooks work across all modes and runtimes.
190
+
191
+ ### Hook Configuration
192
+
193
+ ```js
194
+ // Enable hooks with default settings
195
+ const api = await slothlet({
196
+ dir: "./api",
197
+ hooks: true // Enables all hooks with pattern "**"
198
+ });
199
+
200
+ // Enable with error suppression
201
+ const api = await slothlet({
202
+ dir: "./api",
203
+ hooks: {
204
+ enabled: true,
205
+ pattern: "**",
206
+ suppressErrors: true // Errors reported to error hooks only, not thrown
207
+ }
208
+ });
209
+ ```
210
+
211
+ ### Hook Types
212
+
213
+ **Four hook types available:**
214
+
215
+ - **`before`**: Intercept before function execution
216
+ - Modify arguments
217
+ - Cancel execution (short-circuit) and return custom value
218
+ - Validation and pre-processing
219
+
220
+ - **`after`**: Transform results after execution
221
+ - Transform return values
222
+ - Only runs if function executes
223
+ - Chain transformations
224
+
225
+ - **`always`**: Observe final result (read-only)
226
+ - Always executes (even on short-circuit)
227
+ - Cannot modify result
228
+ - Perfect for logging and metrics
229
+
230
+ - **`error`**: Monitor and handle errors
231
+ - Receives detailed error context
232
+ - Source tracking (before/function/after/always)
233
+ - Error class identification
234
+
235
+ ### Basic Hook Usage
236
+
237
+ ```js
238
+ // Before hook - modify arguments
239
+ api.hooks.on(
240
+ "validate-input",
241
+ "before",
242
+ ({ path, args }) => {
243
+ console.log(`Calling ${path} with:`, args);
244
+ return [args[0] * 2, args[1] * 2]; // Modified args
245
+ },
246
+ { pattern: "math.add", priority: 100 }
247
+ );
248
+
249
+ // After hook - transform result
250
+ api.hooks.on(
251
+ "format-output",
252
+ "after",
253
+ ({ path, result }) => {
254
+ return result * 10; // Transform result
255
+ },
256
+ { pattern: "math.*" }
257
+ );
258
+
259
+ // Always hook - observe (read-only)
260
+ api.hooks.on(
261
+ "log-final",
262
+ "always",
263
+ ({ path, result }) => {
264
+ console.log(`Final: ${path} = ${result}`);
265
+ },
266
+ { pattern: "**" }
267
+ );
268
+
269
+ // Error hook - monitor failures
270
+ api.hooks.on(
271
+ "error-monitor",
272
+ "error",
273
+ ({ path, error, source, errorType }) => {
274
+ console.error(`${source.type} error in ${path}:`, error.message);
275
+ console.error(`Error type: ${errorType}`);
276
+ },
277
+ { pattern: "**" }
278
+ );
279
+ ```
280
+
281
+ ### Hook Pattern Matching
282
+
283
+ ```js
284
+ // Exact match
285
+ api.hooks.on("hook1", "before", handler, { pattern: "math.add" });
286
+
287
+ // Namespace wildcard
288
+ api.hooks.on("hook2", "before", handler, { pattern: "math.*" });
289
+
290
+ // Function wildcard
291
+ api.hooks.on("hook3", "before", handler, { pattern: "*.add" });
292
+
293
+ // All functions
294
+ api.hooks.on("hook4", "before", handler, { pattern: "**" });
295
+ ```
296
+
297
+ ### Short-Circuit Execution
298
+
299
+ ```js
300
+ // Return non-undefined value to short-circuit
301
+ api.hooks.on(
302
+ "cache-check",
303
+ "before",
304
+ ({ path, args }) => {
305
+ const key = JSON.stringify({ path, args });
306
+ if (cache.has(key)) {
307
+ return cache.get(key); // Skip function execution
308
+ }
309
+ // Return undefined to continue
310
+ },
311
+ { pattern: "**", priority: 1000 }
312
+ );
313
+ ```
314
+
315
+ ### Error Suppression
316
+
317
+ Error hooks **ALWAYS receive errors** regardless of the `suppressErrors` setting. This option only controls whether errors are thrown after error hooks execute.
318
+
319
+ **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.
320
+
321
+ **Default behavior (`suppressErrors: false`)**:
322
+
323
+ - Errors sent to error hooks, THEN thrown
324
+ - Application crashes on uncaught errors
325
+
326
+ **Suppressed errors (`suppressErrors: true`)**:
327
+
328
+ - Errors sent to error hooks, BUT NOT thrown
329
+ - Function returns `undefined` instead of throwing
330
+ - All hook errors suppressed (before, after, always)
331
+ - Perfect for resilient systems with monitoring
332
+
333
+ ```js
334
+ const api = await slothlet({
335
+ dir: "./api",
336
+ hooks: {
337
+ enabled: true,
338
+ suppressErrors: true // Suppress all errors
339
+ }
340
+ });
341
+
342
+ api.hooks.on(
343
+ "error-log",
344
+ "error",
345
+ ({ path, error }) => {
346
+ // Log error without crashing app
347
+ sendToMonitoring(path, error);
348
+ },
349
+ { pattern: "**" }
350
+ );
351
+
352
+ // Function fails gracefully
353
+ const result = await api.riskyOperation();
354
+ if (result === undefined) {
355
+ console.log("Operation failed but didn't crash");
356
+ }
357
+ ```
358
+
359
+ ### Hook Management
360
+
361
+ ```js
362
+ // Register hook and get ID
363
+ const hookId = api.hooks.on("my-hook", "before", handler, { pattern: "**" });
364
+
365
+ // Remove specific hook
366
+ api.hooks.off(hookId);
367
+
368
+ // Clear all hooks
369
+ api.hooks.clear();
370
+
371
+ // List registered hooks
372
+ const hooks = api.hooks.list();
373
+
374
+ // Enable/disable hooks at runtime
375
+ api.hooks.disable(); // Fast-path bypass
376
+ api.hooks.enable("database.*"); // Re-enable with new pattern
377
+ ```
378
+
379
+ ## ๐Ÿ“ File Organization Best Practices
380
+
381
+ ### โœ… Clean Folder Structure
382
+
383
+ ```text
384
+ api/
385
+ โ”œโ”€โ”€ config.mjs โ†’ api.config.*
386
+ โ”œโ”€โ”€ math/
387
+ โ”‚ โ””โ”€โ”€ math.mjs โ†’ api.math.* (flattened)
388
+ โ”œโ”€โ”€ util/
389
+ โ”‚ โ”œโ”€โ”€ util.mjs โ†’ api.util.* (flattened methods)
390
+ โ”‚ โ”œโ”€โ”€ extract.mjs โ†’ api.util.extract.*
391
+ โ”‚ โ””โ”€โ”€ controller.mjs โ†’ api.util.controller.*
392
+ โ”œโ”€โ”€ nested/
393
+ โ”‚ โ””โ”€โ”€ date/
394
+ โ”‚ โ””โ”€โ”€ date.mjs โ†’ api.nested.date.*
395
+ โ””โ”€โ”€ multi/
396
+ โ”œโ”€โ”€ alpha.mjs โ†’ api.multi.alpha.*
397
+ โ””โ”€โ”€ beta.mjs โ†’ api.multi.beta.*
398
+ ```
399
+
400
+ ### โœ… Module Naming Conventions
401
+
402
+ - **Filename matches folder** โ†’ Auto-flattening (cleaner API)
403
+ - **Different filename** โ†’ Nested structure preserved
404
+ - **Dash-separated names** โ†’ camelCase API (`auto-ip.mjs` โ†’ `api.autoIP`)
405
+ - **Function name preference** โ†’ Original capitalization preserved (`autoIP`, `parseJSON`) - [See API-RULES.md Rule 9](./API-RULES.md#rule-9-function-name-preference-over-sanitization)
406
+
407
+ ## ๐Ÿงช JSDoc Documentation Patterns
408
+
409
+ > ๐Ÿ“– **For detailed JSDoc templates and examples**, see [.github/copilot-instructions.md - JSDoc Standards](./.github/copilot-instructions.md#-jsdoc-standards--patterns)
410
+
411
+ ### โœ… Primary Module File (One per folder)
412
+
413
+ ```js
414
+ /**
415
+ * @fileoverview Math operations for API testing.
416
+ * @module api_test
417
+ * @name api_test
418
+ * @alias @cldmv/slothlet/api_tests/api_test
419
+ */
420
+ ```
421
+
422
+ ### โœ… Secondary Contributing Files
423
+
424
+ ```js
425
+ /**
426
+ * @fileoverview Math utilities. Internal file (not exported in package.json).
427
+ * @module api_test.math
428
+ * @memberof module:api_test
429
+ */
430
+ ```
431
+
432
+ ### โœ… Live-Binding Imports Pattern
433
+
434
+ ```js
435
+ // โœ… Always include runtime imports (even if commented out for structure)
436
+ // import { self, context, reference } from "@cldmv/slothlet/runtime";
437
+ ```
438
+
439
+ ## ๐Ÿšจ Common AI Agent Mistakes
440
+
441
+ > ๐Ÿ“– **For complete technical details on all API transformation rules**, see [API-RULES.md](./API-RULES.md) (778+ lines of verified examples)
442
+
443
+ ### โŒ Mistake 1: Cross-Module Imports
444
+
445
+ ```js
446
+ // โŒ WRONG
447
+ import { config } from "./config.mjs";
448
+ ```
449
+
450
+ ### โŒ Mistake 2: Missing Runtime Imports
451
+
452
+ ```js
453
+ // โŒ WRONG - No way to access other modules
454
+ export const module = {
455
+ method() {
456
+ // How do I access other modules? ๐Ÿค”
457
+ }
458
+ };
459
+ ```
460
+
461
+ ### โŒ Mistake 3: Wrong JSDoc Module Patterns
462
+
463
+ ```js
464
+ // โŒ WRONG - Multiple @module declarations create duplicates
465
+ /**
466
+ * @module api_test โ† Already declared elsewhere
467
+ * @module api_test.math โ† Should only use @memberof
468
+ */
469
+ ```
470
+
471
+ ### โŒ Mistake 4: Breaking Auto-Flattening
472
+
473
+ ```js
474
+ // File: math/calculator.mjs (different name than folder)
475
+ export const math = {
476
+ /* methods */
477
+ };
478
+ // Result: api.math.calculator.math.* (nested, not flattened)
479
+
480
+ // โœ… CORRECT: File math/math.mjs
481
+ export const math = {
482
+ /* methods */
483
+ };
484
+ // Result: api.math.* (flattened)
485
+ ```
486
+
487
+ ## โœ… AI Agent Checklist
488
+
489
+ When building Slothlet API modules:
490
+
491
+ - [ ] **NO cross-module imports** - Use `self` from runtime instead
492
+ - [ ] **Import runtime** - `import { self, context, reference } from "@cldmv/slothlet/runtime"`
493
+ - [ ] **Match filename to folder** for cleaner APIs (auto-flattening)
494
+ - [ ] **Use proper JSDoc patterns** - One `@module` per folder, `@memberof` for secondary files
495
+ - [ ] **Test cross-module access** via `self.otherModule.method()`
496
+ - [ ] **Include context usage** if module needs user/session data
497
+ - [ ] **Consider hooks** - Will functions be intercepted? Need error monitoring?
498
+ - [ ] **Double quotes everywhere** - Follow Slothlet coding standards
499
+
500
+ ## ๐Ÿ“š Reference Examples
501
+
502
+ - **Auto-flattening**: `api_tests/api_test/math/math.mjs`
503
+ - **Multi-file folders**: `api_tests/api_test/multi/`
504
+ - **Cross-module calls**: `api_tests/api_test_mixed/interop/`
505
+ - **Root-level APIs**: `api_tests/api_test/root-function.mjs`
506
+ - **Nested structures**: `api_tests/api_test/nested/date/`
507
+
508
+ ## ๐Ÿ“– Essential Documentation for AI Agents
509
+
510
+ ### ๐Ÿ—๏ธ **Core Architecture & Patterns**
511
+
512
+ - **[`API-RULES.md`](./API-RULES.md)** - **CRITICAL** - Comprehensive verified rules for API transformation (778+ lines of verified examples)
513
+ - **[`API-RULES-CONDITIONS.md`](./API-RULES-CONDITIONS.md)** - Technical reference for all conditional logic controlling API generation
514
+
515
+ ### ๏ฟฝ **Usage & Installation**
516
+
517
+ - **[`README.md`](./README.md)** - Complete project overview, installation, and usage examples
518
+
519
+ ### ๐Ÿงช **Live Examples & Patterns**
520
+
521
+ - **[`api_tests/api_test/README.md`](./api_tests/api_test/README.md)** - ESM module patterns and filename-folder flattening
522
+ - **[`api_tests/api_test_cjs/README.md`](./api_tests/api_test_cjs/)** - CommonJS module patterns and interoperability
523
+ - **[`api_tests/api_test_mixed/README.md`](./api_tests/api_test_mixed/)** - Mixed ESM/CJS patterns and live-binding examples
524
+
525
+ ### ๐Ÿ”ง **Advanced Pattern Documentation**
526
+
527
+ - **[`docs/api_tests/`](./docs/api_tests/)** - Generated documentation for all test module patterns
528
+
529
+ ### โšก **Critical Reading Order for AI Agents**
530
+
531
+ 1. **This file (`AGENT-USAGE.md`)** - Prevents major architectural mistakes
532
+ 2. **[`README.md`](./README.md)** - Complete project context and installation
533
+ 3. **[`API-RULES.md`](./API-RULES.md)** - Understand verified API transformation patterns
534
+ 4. **[`api_tests/*/README.md`](./api_tests/)** - Live examples of each pattern
535
+
536
+ Understanding these patterns and documentation is essential for building effective Slothlet APIs that work with the framework rather than against it.