@cldmv/slothlet 2.8.0 → 2.9.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.
Files changed (37) hide show
  1. package/AGENT-USAGE.md +1 -1
  2. package/README.md +253 -1578
  3. package/dist/lib/helpers/als-eventemitter.mjs +4 -5
  4. package/dist/lib/helpers/api_builder/add_api.mjs +237 -0
  5. package/dist/lib/helpers/api_builder/analysis.mjs +522 -0
  6. package/dist/lib/helpers/api_builder/construction.mjs +457 -0
  7. package/dist/lib/helpers/api_builder/decisions.mjs +737 -0
  8. package/dist/lib/helpers/api_builder.mjs +16 -1567
  9. package/dist/lib/helpers/utilities.mjs +121 -0
  10. package/dist/lib/runtime/runtime-asynclocalstorage.mjs +44 -17
  11. package/dist/lib/runtime/runtime-livebindings.mjs +18 -3
  12. package/dist/lib/runtime/runtime.mjs +3 -3
  13. package/dist/slothlet.mjs +146 -746
  14. package/docs/API-RULES-CONDITIONS.md +508 -0
  15. package/{API-RULES.md → docs/API-RULES.md} +127 -72
  16. package/package.json +11 -9
  17. package/types/dist/lib/helpers/als-eventemitter.d.mts.map +1 -1
  18. package/types/dist/lib/helpers/api_builder/add_api.d.mts +60 -0
  19. package/types/dist/lib/helpers/api_builder/add_api.d.mts.map +1 -0
  20. package/types/dist/lib/helpers/api_builder/analysis.d.mts +189 -0
  21. package/types/dist/lib/helpers/api_builder/analysis.d.mts.map +1 -0
  22. package/types/dist/lib/helpers/api_builder/construction.d.mts +107 -0
  23. package/types/dist/lib/helpers/api_builder/construction.d.mts.map +1 -0
  24. package/types/dist/lib/helpers/api_builder/decisions.d.mts +213 -0
  25. package/types/dist/lib/helpers/api_builder/decisions.d.mts.map +1 -0
  26. package/types/dist/lib/helpers/api_builder.d.mts +5 -448
  27. package/types/dist/lib/helpers/api_builder.d.mts.map +1 -1
  28. package/types/dist/lib/helpers/utilities.d.mts +120 -0
  29. package/types/dist/lib/helpers/utilities.d.mts.map +1 -0
  30. package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts +7 -0
  31. package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts.map +1 -1
  32. package/types/dist/lib/runtime/runtime-livebindings.d.mts +8 -0
  33. package/types/dist/lib/runtime/runtime-livebindings.d.mts.map +1 -1
  34. package/types/dist/slothlet.d.mts +0 -11
  35. package/types/dist/slothlet.d.mts.map +1 -1
  36. package/types/index.d.mts +0 -1
  37. package/API-RULES-CONDITIONS.md +0 -367
@@ -1,367 +0,0 @@
1
- # Slothlet Source Code Conditions Reference
2
-
3
- **Reference Document for All API Generation Conditional Logic**
4
-
5
- - **Commit ID**: `c2f081a321c738f86196fdfdb19b6a5a706022ef`
6
- - **Date**: October 27, 2025
7
- - **Purpose**: Complete traceability of all conditional statements that control slothlet API structure generation
8
-
9
- ---
10
-
11
- ## Table of Contents
12
-
13
- 1. [getFlatteningDecision() Conditions](#getflatteningdecision-conditions)
14
- 2. [processModuleForAPI() Conditions](#processmoduleforapi-conditions)
15
- 3. [buildCategoryStructure() Single-File Conditions](#buildcategorystructure-single-file-conditions)
16
- 4. [buildCategoryDecisions() Multi-File Conditions](#buildcategorydecisions-multi-file-conditions)
17
- 5. [multidefault_getFlatteningDecision() Conditions](#multidefault_getflatteningdecision-conditions)
18
-
19
- ---
20
-
21
- ## getFlatteningDecision() Conditions
22
-
23
- **File**: `src/lib/helpers/api_builder.mjs`
24
- **Function**: `getFlatteningDecision(options)`
25
- **Lines**: 544-632
26
- **Commit**: `c2f081a321c738f86196fdfdb19b6a5a706022ef`
27
-
28
- ### C01: Self-Referential Check
29
-
30
- **Line**: 558
31
- **Condition**: `if (isSelfReferential)`
32
- **Description**: Self-referential exports (where filename matches an exported property) never flatten to avoid infinite nesting
33
- **Result**: Returns `preserveAsNamespace: true, shouldFlatten: false`
34
-
35
- ### C02: Multi-Default Context With Default
36
-
37
- **Line**: 570
38
- **Condition**: `if (hasMultipleDefaultExports)` → `if (moduleHasDefault)`
39
- **Description**: In multi-default context, modules WITH default exports are preserved as namespaces
40
- **Result**: Returns `preserveAsNamespace: true, shouldFlatten: false`
41
-
42
- ### C03: Multi-Default Context Without Default
43
-
44
- **Line**: 570 → 580
45
- **Condition**: `if (hasMultipleDefaultExports)` → `else` (when !moduleHasDefault)
46
- **Description**: In multi-default context, modules WITHOUT default exports are flattened to avoid empty namespaces
47
- **Result**: Returns `shouldFlatten: true, flattenToRoot: true, flattenToCategory: true`
48
-
49
- ### C04: Auto-Flatten Single Named Export
50
-
51
- **Line**: 593
52
- **Condition**: `if (moduleKeys.length === 1 && moduleKeys[0] === apiPathKey)`
53
- **Description**: When module exports single named export matching filename, use the export directly
54
- **Result**: Returns `shouldFlatten: true, useAutoFlattening: true`
55
-
56
- ### C05: Filename Matches Container
57
-
58
- **Line**: 605
59
- **Condition**: `if (categoryName && fileName === categoryName && !moduleHasDefault && moduleKeys.length > 0)`
60
- **Description**: When filename matches folder name and has named exports but no default, flatten to category level
61
- **Result**: Returns `shouldFlatten: true, flattenToCategory: true`
62
-
63
- ### C06: Single File Context
64
-
65
- **Line**: 617
66
- **Condition**: `if (totalModules === 1 && !moduleHasDefault && moduleKeys.length > 0)`
67
- **Description**: In single-file context with named exports only, flatten to eliminate unnecessary nesting
68
- **Result**: Returns `shouldFlatten: true, flattenToRoot: true, flattenToCategory: true`
69
-
70
- ### C07: Default Fallback
71
-
72
- **Line**: 629
73
- **Condition**: Default case (no conditions matched)
74
- **Description**: Traditional namespace preservation when no flattening rules apply
75
- **Result**: Returns `preserveAsNamespace: true, shouldFlatten: false`
76
-
77
- ---
78
-
79
- ## processModuleForAPI() Conditions
80
-
81
- **File**: `src/lib/helpers/api_builder.mjs`
82
- **Function**: `processModuleForAPI(options)`
83
- **Lines**: 685-826
84
- **Commit**: `c2f081a321c738f86196fdfdb19b6a5a706022ef`
85
-
86
- ### C08: Has Default Function
87
-
88
- **Line**: 713
89
- **Condition**: `if (hasDefaultFunction)`
90
- **Description**: Handles modules that export functions as default (either direct function or mod.default function)
91
-
92
- #### C08a: Multi-Default Function Non-Self-Referential
93
-
94
- **Line**: 716
95
- **Condition**: `if (hasMultipleDefaultExports && !isSelfReferential)`
96
- **Description**: In multi-default context, function defaults use filename as API key to avoid conflicts
97
- **Result**: `apiAssignments[apiPathKey] = mod, namespaced = true`
98
-
99
- #### C08b: Self-Referential Function
100
-
101
- **Line**: 728
102
- **Condition**: `else if (isSelfReferential)`
103
- **Description**: Self-referential function exports preserve as namespace
104
- **Result**: `apiAssignments[apiPathKey] = mod, namespaced = true`
105
-
106
- #### C08c: Traditional Default Function
107
-
108
- **Line**: 736 → 748
109
- **Condition**: `else` → `if (mode === "root" && getRootDefault && setRootDefault && !hasMultipleDefaultExports && !getRootDefault())`
110
- **Description**: In root context with no existing root function, set as the callable root API
111
- **Result**: `setRootDefault(defaultFunction), rootDefaultSet = true`
112
-
113
- #### C08d: Function As Namespace
114
-
115
- **Line**: 758
116
- **Condition**: `else` (when C08c doesn't apply)
117
- **Description**: In subfolder context or when root already exists, treat function as namespace
118
- **Result**: `apiAssignments[apiPathKey] = mod, namespaced = true`
119
-
120
- ### C09: Non-Function Modules
121
-
122
- **Line**: 766
123
- **Condition**: `else` (when !hasDefaultFunction)
124
- **Description**: Handles object exports, named-only exports, and non-function defaults
125
-
126
- #### C09a: Use Auto-Flattening
127
-
128
- **Line**: 782
129
- **Condition**: `if (decision.useAutoFlattening)`
130
- **Description**: Apply auto-flattening decision from getFlatteningDecision()
131
- **Result**: `apiAssignments[apiPathKey] = mod[moduleKeys[0]], flattened = true`
132
-
133
- #### C09b: Flatten To Root/Category
134
-
135
- **Line**: 786
136
- **Condition**: `else if (decision.flattenToRoot || decision.flattenToCategory)`
137
- **Description**: Merge all named exports into target based on flattening decision
138
- **Result**: Loop assigns `apiAssignments[key] = mod[key], flattened = true`
139
-
140
- #### C09c: Self-Referential Non-Function
141
-
142
- **Line**: 797
143
- **Condition**: `else if (isSelfReferential)`
144
- **Description**: Self-referential non-function exports use direct property access
145
- **Result**: `apiAssignments[apiPathKey] = mod[apiPathKey] || mod, namespaced = true`
146
-
147
- #### C09d: Traditional Namespace
148
-
149
- **Line**: 801
150
- **Condition**: `else`
151
- **Description**: Default behavior preserves module as namespace
152
- **Result**: `apiAssignments[apiPathKey] = mod, namespaced = true`
153
-
154
- ---
155
-
156
- ## buildCategoryStructure() Single-File Conditions
157
-
158
- **File**: `src/lib/helpers/api_builder.mjs`
159
- **Function**: `buildCategoryStructure(categoryPath, options)`
160
- **Lines**: 950-1080
161
- **Commit**: `c2f081a321c738f86196fdfdb19b6a5a706022ef`
162
-
163
- ### C10: Single-File Function Folder Match
164
-
165
- **Line**: 984
166
- **Condition**: `if (moduleName === categoryName && typeof mod === "function" && currentDepth > 0)`
167
- **Description**: Flatten when filename matches folder name and exports function (not at root level)
168
- **Result**: Return function directly with name set to categoryName
169
-
170
- ### C11: Single-File Object Folder Match
171
-
172
- **Line**: 994
173
- **Condition**: `if (moduleName === categoryName && mod && typeof mod === "object" && !Array.isArray(mod) && currentDepth > 0)`
174
- **Description**: Handle object exports where filename matches folder name (not at root level)
175
-
176
- #### C11a: Single Named Export Match
177
-
178
- **Line**: 1000
179
- **Condition**: `if (moduleKeys.length === 1 && moduleKeys[0] === moduleName)`
180
- **Description**: When single named export matches filename, return the export contents directly
181
- **Result**: `return mod[moduleName]`
182
-
183
- #### C11b: Multiple Exports (Default Spread)
184
-
185
- **Line**: 1009
186
- **Condition**: `if (moduleKeys.length > 1)`
187
- **Description**: Multiple exports indicate spread default + named exports, flatten the merged object
188
- **Result**: `return mod` (already spread)
189
-
190
- #### C11c: Folder Match Fallback
191
-
192
- **Line**: Default case within C11
193
- **Description**: Other object cases where filename matches folder
194
- **Result**: `return mod`
195
-
196
- ### C12: Parent-Level Flattening
197
-
198
- **Line**: 1018
199
- **Condition**: `if (moduleFiles.length === 1 && currentDepth > 0 && mod && typeof mod === "object" && !Array.isArray(mod))`
200
- **Description**: Eliminate intermediate filename namespace for generic filenames
201
-
202
- #### C12a: Generic Filename Single Export
203
-
204
- **Line**: 1026
205
- **Condition**: `if (moduleKeys.length === 1 && isGenericFilename)`
206
- **Description**: Single export with generic filename (singlefile, index, main, default) gets promoted
207
- **Result**: `return { [moduleKeys[0]]: exportValue }`
208
-
209
- ### C13: Function Name Matches Folder
210
-
211
- **Line**: 1039
212
- **Condition**: `if (functionNameMatchesFolder && currentDepth > 0)`
213
- **Description**: Function name matches folder name case-insensitively (not at root level)
214
- **Result**: Return function directly with preserved name
215
-
216
- ### C14: Function Name Matches Filename
217
-
218
- **Line**: 1049
219
- **Condition**: `if (functionNameMatchesFilename)`
220
- **Description**: Use original function name instead of sanitized filename when they match semantically
221
- **Result**: `return { [mod.name]: mod }`
222
-
223
- ### C15: Default Function Export
224
-
225
- **Line**: 1053
226
- **Condition**: `if (typeof mod === "function" && (!mod.name || mod.name === "default" || mod.__slothletDefault === true) && currentDepth > 0)`
227
- **Description**: Flatten functions marked as default exports (not at root level)
228
- **Result**: Return function directly with name set to categoryName
229
-
230
- ### C16: Auto-Flatten Single Named Export
231
-
232
- **Line**: 1063
233
- **Condition**: `if (moduleKeys.length === 1 && moduleKeys[0] === moduleName)`
234
- **Description**: Second instance for auto-flattening single named export matching filename
235
- **Result**: `return mod[moduleName]`
236
-
237
- ### C17: Single-File Default Fallback
238
-
239
- **Line**: 1067
240
- **Condition**: Default case for single files
241
- **Description**: Preserve as namespace when no flattening rules apply
242
- **Result**: `return { [moduleName]: mod }`
243
-
244
- ---
245
-
246
- ## buildCategoryDecisions() Multi-File Conditions
247
-
248
- **File**: `src/lib/helpers/api_builder.mjs`
249
- **Function**: `buildCategoryDecisions(categoryPath, options)`
250
- **Lines**: 1710-1750
251
- **Commit**: `c2f081a321c738f86196fdfdb19b6a5a706022ef`
252
-
253
- ### C18: Has Preferred Export Names
254
-
255
- **Line**: 1709
256
- **Condition**: `if (hasPreferredName)` (from function name preference logic)
257
- **Description**: Use original function names over sanitized filenames when they match semantically
258
- **Result**: `moduleDecision.specialHandling = "preferred-export-names"`
259
-
260
- ### C19: Self-Referential Multi-File
261
-
262
- **Line**: 1712
263
- **Condition**: `else if (selfReferentialFiles.has(moduleName))`
264
- **Description**: Self-referential files in multi-file context get special namespace handling
265
- **Result**: `moduleDecision.type = "self-referential"`
266
-
267
- ### C20: Multi-File Flattening Scenarios
268
-
269
- **Line**: 1715
270
- **Condition**: `else` (when not preferred names or self-referential)
271
- **Description**: Various flattening scenarios for standard multi-file processing
272
-
273
- #### C20a: Single Default Object
274
-
275
- **Line**: 1723
276
- **Condition**: `if (!hasMultipleDefaultExports && mod.default && typeof mod.default === "object")`
277
- **Description**: Single default export object (not in multi-default context) gets flattened
278
- **Result**: `moduleDecision.shouldFlatten = true, flattenType = "single-default-object"`
279
-
280
- #### C20b: Multi-Default No Default
281
-
282
- **Line**: 1727
283
- **Condition**: `else if (hasMultipleDefaultExports && !mod.default && moduleKeys.length > 0)`
284
- **Description**: In multi-default context, modules WITHOUT defaults are flattened to category
285
- **Result**: `moduleDecision.shouldFlatten = true, flattenType = "multi-default-no-default"`
286
-
287
- #### C20c: Single Named Export Match
288
-
289
- **Line**: 1731
290
- **Condition**: `else if (moduleKeys.length === 1 && moduleKeys[0] === apiPathKey)`
291
- **Description**: Auto-flatten when module exports single named export matching filename
292
- **Result**: `moduleDecision.shouldFlatten = true, flattenType = "single-named-export-match"`
293
-
294
- #### C20d: Category Name Match Flatten
295
-
296
- **Line**: 1736
297
- **Condition**: `else if (!mod.default && moduleKeys.length > 0 && moduleName === categoryName)`
298
- **Description**: Module filename matches folder name with no default → flatten to category
299
- **Result**: `moduleDecision.shouldFlatten = true, flattenType = "category-name-match-flatten"`
300
-
301
- #### C20e: Standard Object Export
302
-
303
- **Line**: 1740
304
- **Condition**: `else`
305
- **Description**: Standard object export without special flattening
306
- **Result**: `moduleDecision.apiPathKey = apiPathKey`
307
-
308
- ---
309
-
310
- ## multidefault_getFlatteningDecision() Conditions
311
-
312
- **File**: `src/lib/helpers/multidefault.mjs`
313
- **Function**: `multidefault_getFlatteningDecision(options)`
314
- **Lines**: 168-220
315
- **Commit**: `c2f081a321c738f86196fdfdb19b6a5a706022ef`
316
-
317
- ### C21: Multi-Default Self-Referential
318
-
319
- **Line**: 168
320
- **Condition**: `if (isSelfReferential)`
321
- **Description**: Self-referential default exports in multi-default context treat as namespace
322
- **Result**: Returns `shouldFlatten: false, preserveAsNamespace: true`
323
-
324
- ### C22: Multi-Default With Default
325
-
326
- **Line**: 178 → 179
327
- **Condition**: `if (hasMultipleDefaultExports)` → `if (moduleHasDefault)`
328
- **Description**: Multi-default context modules WITH default exports preserve as namespaces
329
- **Result**: Returns `shouldFlatten: false, preserveAsNamespace: true`
330
-
331
- ### C23: Multi-Default Without Default
332
-
333
- **Line**: 178 → 186
334
- **Condition**: `if (hasMultipleDefaultExports)` → `else` (when !moduleHasDefault)
335
- **Description**: Multi-default context modules WITHOUT default exports flatten to root
336
- **Result**: Returns `shouldFlatten: true, flattenToRoot: true`
337
-
338
- ### C24: Multi-Default Single Named Export
339
-
340
- **Line**: 200
341
- **Condition**: `if (moduleKeys.length === 1 && moduleKeys[0] === apiPathKey)`
342
- **Description**: Single named export matching filename in multi-default context
343
- **Result**: Returns `shouldFlatten: true, flattenToRoot: false`
344
-
345
- ### C25: Multi-Default Single File No Default
346
-
347
- **Line**: 211
348
- **Condition**: `if (!moduleHasDefault && moduleKeys.length > 0 && totalModuleCount === 1)`
349
- **Description**: Single file with no default, only named exports in multi-default context
350
- **Result**: Returns `shouldFlatten: true, flattenToRoot: true`
351
-
352
- ### C26: Multi-Default Default Fallback
353
-
354
- **Line**: 220+
355
- **Condition**: Default case (no conditions matched)
356
- **Description**: Preserve as namespace when no multi-default flattening rules apply
357
- **Result**: Returns `preserveAsNamespace: true, shouldFlatten: false`
358
-
359
- ---
360
-
361
- ## Summary
362
-
363
- **Total Conditions Found**: 26 distinct conditional statements (plus their nested conditions)
364
- **Primary Functions**: 5 key functions containing API generation logic
365
- **Coverage Gap**: Previous API-RULES.md documented only 2 of these 26 conditions
366
-
367
- **Key Finding**: The majority of slothlet's API structure decisions are controlled by these 26 conditions across 5 functions. Any changes to API generation behavior require understanding and potentially modifying these conditional statements.