@cldmv/slothlet 2.6.1 โ 2.7.0
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 +536 -0
- package/API-RULES-CONDITIONS.md +367 -0
- package/API-RULES.md +777 -0
- package/README.md +631 -39
- package/dist/lib/helpers/hooks.mjs +381 -0
- package/dist/lib/modes/slothlet_lazy.mjs +25 -19
- package/dist/lib/runtime/runtime-asynclocalstorage.mjs +97 -16
- package/dist/lib/runtime/runtime-livebindings.mjs +127 -5
- package/dist/slothlet.mjs +50 -2
- package/package.json +12 -8
- package/types/dist/lib/helpers/hooks.d.mts +330 -0
- package/types/dist/lib/helpers/hooks.d.mts.map +1 -0
- package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts.map +1 -1
- package/types/dist/lib/runtime/runtime-livebindings.d.mts +4 -3
- package/types/dist/lib/runtime/runtime-livebindings.d.mts.map +1 -1
- package/types/dist/slothlet.d.mts +7 -0
- package/types/dist/slothlet.d.mts.map +1 -1
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.
|