@cldmv/slothlet 2.8.0 → 2.10.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 (59) hide show
  1. package/AGENT-USAGE.md +1 -1
  2. package/README.md +300 -1557
  3. package/dist/lib/engine/slothlet_child.mjs +1 -1
  4. package/dist/lib/engine/slothlet_engine.mjs +1 -1
  5. package/dist/lib/engine/slothlet_esm.mjs +1 -1
  6. package/dist/lib/engine/slothlet_helpers.mjs +1 -1
  7. package/dist/lib/engine/slothlet_worker.mjs +1 -1
  8. package/dist/lib/helpers/als-eventemitter.mjs +5 -6
  9. package/dist/lib/helpers/api_builder/add_api.mjs +292 -0
  10. package/dist/lib/helpers/api_builder/analysis.mjs +532 -0
  11. package/dist/lib/helpers/api_builder/construction.mjs +457 -0
  12. package/dist/lib/helpers/api_builder/decisions.mjs +737 -0
  13. package/dist/lib/helpers/api_builder/metadata.mjs +248 -0
  14. package/dist/lib/helpers/api_builder.mjs +17 -1568
  15. package/dist/lib/helpers/auto-wrap.mjs +1 -1
  16. package/dist/lib/helpers/hooks.mjs +1 -1
  17. package/dist/lib/helpers/instance-manager.mjs +1 -1
  18. package/dist/lib/helpers/metadata-api.mjs +201 -0
  19. package/dist/lib/helpers/multidefault.mjs +12 -3
  20. package/dist/lib/helpers/resolve-from-caller.mjs +1 -1
  21. package/dist/lib/helpers/sanitize.mjs +1 -1
  22. package/dist/lib/helpers/utilities.mjs +121 -0
  23. package/dist/lib/modes/slothlet_eager.mjs +1 -1
  24. package/dist/lib/modes/slothlet_lazy.mjs +10 -1
  25. package/dist/lib/runtime/runtime-asynclocalstorage.mjs +49 -18
  26. package/dist/lib/runtime/runtime-livebindings.mjs +23 -4
  27. package/dist/lib/runtime/runtime.mjs +15 -4
  28. package/dist/slothlet.mjs +164 -748
  29. package/docs/API-RULES-CONDITIONS.md +508 -0
  30. package/{API-RULES.md → docs/API-RULES.md} +127 -72
  31. package/package.json +11 -9
  32. package/types/dist/lib/helpers/als-eventemitter.d.mts.map +1 -1
  33. package/types/dist/lib/helpers/api_builder/add_api.d.mts +76 -0
  34. package/types/dist/lib/helpers/api_builder/add_api.d.mts.map +1 -0
  35. package/types/dist/lib/helpers/api_builder/analysis.d.mts +189 -0
  36. package/types/dist/lib/helpers/api_builder/analysis.d.mts.map +1 -0
  37. package/types/dist/lib/helpers/api_builder/construction.d.mts +107 -0
  38. package/types/dist/lib/helpers/api_builder/construction.d.mts.map +1 -0
  39. package/types/dist/lib/helpers/api_builder/decisions.d.mts +213 -0
  40. package/types/dist/lib/helpers/api_builder/decisions.d.mts.map +1 -0
  41. package/types/dist/lib/helpers/api_builder/metadata.d.mts +99 -0
  42. package/types/dist/lib/helpers/api_builder/metadata.d.mts.map +1 -0
  43. package/types/dist/lib/helpers/api_builder.d.mts +5 -448
  44. package/types/dist/lib/helpers/api_builder.d.mts.map +1 -1
  45. package/types/dist/lib/helpers/metadata-api.d.mts +132 -0
  46. package/types/dist/lib/helpers/metadata-api.d.mts.map +1 -0
  47. package/types/dist/lib/helpers/multidefault.d.mts.map +1 -1
  48. package/types/dist/lib/helpers/utilities.d.mts +120 -0
  49. package/types/dist/lib/helpers/utilities.d.mts.map +1 -0
  50. package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts +9 -0
  51. package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts.map +1 -1
  52. package/types/dist/lib/runtime/runtime-livebindings.d.mts +10 -0
  53. package/types/dist/lib/runtime/runtime-livebindings.d.mts.map +1 -1
  54. package/types/dist/lib/runtime/runtime.d.mts +1 -0
  55. package/types/dist/lib/runtime/runtime.d.mts.map +1 -1
  56. package/types/dist/slothlet.d.mts +0 -11
  57. package/types/dist/slothlet.d.mts.map +1 -1
  58. package/types/index.d.mts +0 -1
  59. package/API-RULES-CONDITIONS.md +0 -367
@@ -0,0 +1,508 @@
1
+ # Slothlet Source Code Conditions Reference
2
+
3
+ **Reference Document for All API Generation Conditional Logic**
4
+
5
+ - **Commit ID**: `a50531d1ba712f0c4efd9ab9b7cf8f62a0d379da`
6
+ - **Date**: December 30, 2025
7
+ - **Purpose**: Complete traceability of all conditional statements that control slothlet API structure generation
8
+ - **Status**: ? **CURRENT AND ACCURATE**
9
+
10
+ ---
11
+
12
+ ## Overview
13
+
14
+ This document catalogs every conditional statement in slothlet's API generation system. Each condition is numbered (C01, C02, etc.) with exact line numbers and direct links to source code.
15
+
16
+ **Core Decision Functions:**
17
+
18
+ - [`getFlatteningDecision()`](#getflatteningdecision-conditions) - 4 rules controlling when modules flatten
19
+ - [`processModuleForAPI()`](#processmoduleforapi-conditions) - 9 conditions for module processing
20
+ - [`buildCategoryDecisions()`](#buildcategorydecisions-conditions) - 11 decisions for directory structure
21
+ - [`buildCategoryStructure()`](#buildcategorystructure-conditions) - 6 structural assembly conditions
22
+ - [`multidefault_getFlatteningDecision()`](#multidefault_getflatteningdecision-conditions) - 4 multi-default rules
23
+
24
+ ---
25
+
26
+ ## Table of Contents
27
+
28
+ 1. [getFlatteningDecision() Conditions](#getflatteningdecision-conditions) (4 rules)
29
+ 2. [processModuleForAPI() Conditions](#processmoduleforapi-conditions) (9 conditions)
30
+ 3. [buildCategoryDecisions() Conditions](#buildcategorydecisions-conditions) (11 decisions)
31
+ 4. [buildCategoryStructure() Conditions](#buildcategorystructure-conditions) (6 structural)
32
+ 5. [multidefault_getFlatteningDecision() Conditions](#multidefault_getflatteningdecision-conditions) (4 rules)
33
+
34
+ ---
35
+
36
+ ## getFlatteningDecision() Conditions
37
+
38
+ **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L87-L189)
39
+ **Function**: `getFlatteningDecision(options)`
40
+ **Lines**: [87-189](../src/lib/helpers/api_builder/decisions.mjs#L87-L189)
41
+
42
+ This function determines whether and how to flatten module exports to avoid unnecessary nesting.
43
+
44
+ ### C01: Self-Referential Check
45
+
46
+ **Line**: [105](../src/lib/helpers/api_builder/decisions.mjs#L105)
47
+ **Condition**: `if (isSelfReferential)`
48
+ **Purpose**: Self-referential exports (where filename matches an exported property) never flatten to avoid infinite nesting
49
+ **Result**: `shouldFlatten: false, preserveAsNamespace: true`
50
+ **Reason**: `"self-referential export"`
51
+
52
+ **Example**: `math.mjs` exports `{ math: { add, subtract } }` → preserves as namespace to avoid circular structure
53
+
54
+ ---
55
+
56
+ ### C02: Multi-Default Context With Default Export
57
+
58
+ **Line**: [117](../src/lib/helpers/api_builder/decisions.mjs#L117)
59
+ **Condition**: `if (hasMultipleDefaultExports)` → [118](../src/lib/helpers/api_builder/decisions.mjs#L118): `if (moduleHasDefault)`
60
+ **Purpose**: In multi-default context, modules WITH default exports are preserved as namespaces to avoid conflicts
61
+ **Result**: `shouldFlatten: false, preserveAsNamespace: true`
62
+ **Reason**: `"multi-default context with default export"`
63
+
64
+ **Example**: Folder has 3 files with default exports → each keeps namespace to prevent collision
65
+
66
+ ---
67
+
68
+ ### C03: Multi-Default Context Without Default Export
69
+
70
+ **Line**: [117](../src/lib/helpers/api_builder/decisions.mjs#L117) → [129](../src/lib/helpers/api_builder/decisions.mjs#L129): `else`
71
+ **Condition**: `if (hasMultipleDefaultExports)` → `else` (when !moduleHasDefault)
72
+ **Purpose**: In multi-default context, modules WITHOUT default exports flatten to avoid empty namespaces
73
+ **Result**: `shouldFlatten: true, flattenToRoot: true, flattenToCategory: true`
74
+ **Reason**: `"multi-default context without default export"`
75
+
76
+ **Example**: Folder has mix of default/named exports → named-only files flatten to category level
77
+
78
+ ---
79
+
80
+ ### C04: Auto-Flatten Single Named Export Matching Filename
81
+
82
+ **Line**: [142](../src/lib/helpers/api_builder/decisions.mjs#L142)
83
+ **Condition**: `if (moduleKeys.length === 1 && moduleKeys[0] === apiPathKey)`
84
+ **Purpose**: When module exports single named export matching filename, use the export directly
85
+ **Result**: `shouldFlatten: true, useAutoFlattening: true`
86
+ **Reason**: `"auto-flatten single named export matching filename"`
87
+
88
+ **Example**: `math.mjs` exports `{ math: { add } }` → becomes `api.math.add()` not `api.math.math.add()`
89
+
90
+ ---
91
+
92
+ ### C05: Filename Matches Container (Category-Level Flatten)
93
+
94
+ **Line**: [154](../src/lib/helpers/api_builder/decisions.mjs#L154)
95
+ **Condition**: `if (categoryName && fileName === categoryName && !moduleHasDefault && moduleKeys.length > 0)`
96
+ **Purpose**: When filename matches folder name and has named exports but no default, flatten to category level
97
+ **Result**: `shouldFlatten: true, flattenToCategory: true`
98
+ **Reason**: `"filename matches container, flatten to category"`
99
+
100
+ **Example**: `math/math.mjs` with named exports → flattens to `api.math.add()` not `api.math.math.add()`
101
+
102
+ ---
103
+
104
+ ### C06: Single File Context (COMMENTED OUT)
105
+
106
+ **Lines**: [169-182](../src/lib/helpers/api_builder/decisions.mjs#L169-L182)
107
+ **Status**: ?? **DISABLED** - Commented out in current code
108
+ **Original Purpose**: Flatten single-file folders with named exports only
109
+ **Comment**: "This rule reduces API path flexibility. If users want flattening, they can use other rules like naming the file to match the folder."
110
+
111
+ ---
112
+
113
+ ### C07: Default Fallback - Preserve as Namespace
114
+
115
+ **Line**: [184](../src/lib/helpers/api_builder/decisions.mjs#L184)
116
+ **Condition**: Default case (no conditions matched)
117
+ **Purpose**: Traditional namespace preservation when no flattening rules apply
118
+ **Result**: `shouldFlatten: false, preserveAsNamespace: true`
119
+ **Reason**: `"traditional namespace preservation"`
120
+
121
+ ---
122
+
123
+ ## processModuleForAPI() Conditions
124
+
125
+ **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L315-L466)
126
+ **Function**: `processModuleForAPI(options)`
127
+ **Lines**: [315-466](../src/lib/helpers/api_builder/decisions.mjs#L315-L466)
128
+
129
+ This function processes individual modules and determines how they integrate into the API structure.
130
+
131
+ ### C08: Has Default Function Export
132
+
133
+ **Line**: [345](../src/lib/helpers/api_builder/decisions.mjs#L345)
134
+ **Condition**: `if (hasDefaultFunction)`
135
+ **Purpose**: Handles modules that export functions as default (either direct function or mod.default function)
136
+ **Branches**: 3 major sub-conditions (C08a, C08b, C08c)
137
+
138
+ ---
139
+
140
+ #### C08a: Multi-Default Function (Non-Self-Referential)
141
+
142
+ **Line**: [351](../src/lib/helpers/api_builder/decisions.mjs#L351)
143
+ **Condition**: `if (hasMultipleDefaultExports && !isSelfReferential)`
144
+ **Purpose**: In multi-default context, function defaults use filename as API key to avoid conflicts
145
+ **Result**: `apiAssignments[apiPathKey] = mod, namespaced = true`
146
+
147
+ **Example**: Multiple files with function defaults → each uses filename as namespace key
148
+
149
+ ---
150
+
151
+ #### C08b: Self-Referential Function
152
+
153
+ **Line**: [361](../src/lib/helpers/api_builder/decisions.mjs#L361)
154
+ **Condition**: `else if (isSelfReferential)`
155
+ **Purpose**: Self-referential function exports preserve as namespace
156
+ **Result**: `apiAssignments[apiPathKey] = mod, namespaced = true`
157
+
158
+ **Example**: `logger.mjs` exports function with `logger` property → preserves namespace structure
159
+
160
+ ---
161
+
162
+ #### C08c: Traditional Default Function - Root API
163
+
164
+ **Line**: [378](../src/lib/helpers/api_builder/decisions.mjs#L378)
165
+ **Condition**: `if (mode === "root" && getRootDefault && setRootDefault && !hasMultipleDefaultExports && !getRootDefault())`
166
+ **Purpose**: In root context with no existing root function, set as the callable root API
167
+ **Result**: `setRootDefault(defaultFunction), rootDefaultSet = true`
168
+
169
+ **Example**: Root folder has single default function → API becomes callable: `api()`
170
+
171
+ ---
172
+
173
+ #### C08d: Function As Namespace (Subfolder Context)
174
+
175
+ **Line**: [387](../src/lib/helpers/api_builder/decisions.mjs#L387)
176
+ **Condition**: `else` (when C08c doesn't apply)
177
+ **Purpose**: In subfolder context or when root already exists, treat function as namespace
178
+ **Result**: `apiAssignments[apiPathKey] = mod, namespaced = true`
179
+
180
+ ---
181
+
182
+ ### C09: Non-Function Modules (Objects/Named Exports)
183
+
184
+ **Line**: [398](../src/lib/helpers/api_builder/decisions.mjs#L398)
185
+ **Condition**: `else` (when !hasDefaultFunction)
186
+ **Purpose**: Handles object exports, named-only exports, and non-function defaults
187
+ **Branches**: 4 sub-conditions based on flattening decision
188
+
189
+ ---
190
+
191
+ #### C09a: Use Auto-Flattening
192
+
193
+ **Line**: [425](../src/lib/helpers/api_builder/decisions.mjs#L425)
194
+ **Condition**: `if (decision.useAutoFlattening)`
195
+ **Purpose**: Apply auto-flattening decision from getFlatteningDecision()
196
+ **Result**: `apiAssignments[apiPathKey] = mod[moduleKeys[0]], flattened = true`
197
+
198
+ ---
199
+
200
+ #### C09b: Flatten To Root/Category
201
+
202
+ **Line**: [429](../src/lib/helpers/api_builder/decisions.mjs#L429)
203
+ **Condition**: `else if (decision.flattenToRoot || decision.flattenToCategory)`
204
+ **Purpose**: Merge all named exports into target based on flattening decision
205
+ **Result**: Loop assigns `apiAssignments[key] = mod[key], flattened = true`
206
+
207
+ ---
208
+
209
+ #### C09c: Self-Referential Non-Function
210
+
211
+ **Line**: [440](../src/lib/helpers/api_builder/decisions.mjs#L440)
212
+ **Condition**: `else if (isSelfReferential)`
213
+ **Purpose**: Self-referential non-function exports use direct property access
214
+ **Result**: `apiAssignments[apiPathKey] = mod[apiPathKey] || mod, namespaced = true`
215
+
216
+ ---
217
+
218
+ #### C09d: Traditional Namespace Preservation
219
+
220
+ **Line**: [444](../src/lib/helpers/api_builder/decisions.mjs#L444)
221
+ **Condition**: `else`
222
+ **Purpose**: Default behavior preserves module as namespace
223
+ **Result**: `apiAssignments[apiPathKey] = mod, namespaced = true`
224
+
225
+ ---
226
+
227
+ ## buildCategoryDecisions() Conditions
228
+
229
+ **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L505-L899)
230
+ **Function**: `buildCategoryDecisions(categoryPath, options)`
231
+ **Lines**: [505-899](../src/lib/helpers/api_builder/decisions.mjs#L505-L899)
232
+
233
+ Centralized category building decisions - analyzes directories and returns structural decisions.
234
+
235
+ ### C10: Single-File Function Folder Match
236
+
237
+ **Line**: [584](../src/lib/helpers/api_builder/decisions.mjs#L584)
238
+ **Condition**: `if (moduleName === categoryName && typeof mod === "function" && currentDepth > 0)`
239
+ **Purpose**: Flatten when filename matches folder name and exports function (not at root level)
240
+ **Result**: `shouldFlatten: true, flattenType: "function-folder-match"`
241
+
242
+ **Example**: `nest/nest.mjs` exports function → becomes `api.nest()` not `api.nest.nest()`
243
+
244
+ ---
245
+
246
+ ### C11: Default Export Flattening (CJS/ESM Uniform)
247
+
248
+ **Line**: [593](../src/lib/helpers/api_builder/decisions.mjs#L593)
249
+ **Condition**: `if (analysis.hasDefault && analysis.defaultExportType === "object" && moduleName === categoryName && currentDepth > 0)`
250
+ **Purpose**: Flatten default object exports when filename matches folder (handles both CJS and ESM uniformly)
251
+ **Result**: `shouldFlatten: true, flattenType: "default-export-flatten"`
252
+
253
+ ---
254
+
255
+ ### C12: Object Auto-Flatten (Single Named Export Match)
256
+
257
+ **Line**: [604](../src/lib/helpers/api_builder/decisions.mjs#L604)
258
+ **Condition**: `if (moduleName === categoryName && mod && typeof mod === "object" && !Array.isArray(mod) && currentDepth > 0)`
259
+ **Sub-condition**: [609](../src/lib/helpers/api_builder/decisions.mjs#L609): `if (moduleKeys.length === 1 && moduleKeys[0] === moduleName)`
260
+ **Purpose**: When single named export matches filename, flatten the object contents
261
+ **Result**: `shouldFlatten: true, flattenType: "object-auto-flatten"`
262
+
263
+ ---
264
+
265
+ ### C13: Filename-Folder Exact Match Flattening
266
+
267
+ **Line**: [619](../src/lib/helpers/api_builder/decisions.mjs#L619)
268
+ **Condition**: `if (fileBaseName === categoryName && moduleKeys.length > 0)`
269
+ **Purpose**: Avoid double nesting when file basename matches folder (e.g., nest/nest.mjs)
270
+ **Result**: `shouldFlatten: true, flattenType: "filename-folder-match-flatten"`
271
+
272
+ ---
273
+
274
+ ### C14: Parent-Level Flattening (Generic Filenames)
275
+
276
+ **Line**: [641](../src/lib/helpers/api_builder/decisions.mjs#L641)
277
+ **Condition**: `if (moduleFiles.length === 1 && currentDepth > 0 && mod && typeof mod === "object" && !Array.isArray(mod))`
278
+ **Sub-condition**: [649](../src/lib/helpers/api_builder/decisions.mjs#L649): `if (moduleKeys.length === 1 && isGenericFilename)`
279
+ **Purpose**: Eliminate intermediate namespace for generic filenames (singlefile, index, main, default)
280
+ **Result**: `shouldFlatten: true, flattenType: "parent-level-flatten"`
281
+
282
+ **Example**: `nest4/singlefile.mjs` → `api.nest4.beta()` not `api.nest4.singlefile.beta()`
283
+
284
+ ---
285
+
286
+ ### C15: Function Name Matches Folder
287
+
288
+ **Line**: [663](../src/lib/helpers/api_builder/decisions.mjs#L663)
289
+ **Condition**: `if (functionNameMatchesFolder && currentDepth > 0)`
290
+ **Purpose**: Flatten when function name matches folder name (case-insensitive), prefer function name
291
+ **Result**: `shouldFlatten: true, flattenType: "function-folder-match", preferredName: mod.name`
292
+
293
+ ---
294
+
295
+ ### C16: Function Name Matches Filename (Name Preference)
296
+
297
+ **Line**: [671](../src/lib/helpers/api_builder/decisions.mjs#L671)
298
+ **Condition**: `if (functionNameMatchesFilename)`
299
+ **Purpose**: Use original function name instead of sanitized filename when they match semantically
300
+ **Result**: `shouldFlatten: false, preferredName: mod.name`
301
+
302
+ **Example**: `auto-ip.mjs` exports `autoIP` function → uses `autoIP` not `autoIp`
303
+
304
+ ---
305
+
306
+ ### C17: Default Function Export
307
+
308
+ **Line**: [680](../src/lib/helpers/api_builder/decisions.mjs#L680)
309
+ **Condition**: `if (typeof mod === "function" && (!mod.name || mod.name === "default" || mod.__slothletDefault === true) && currentDepth > 0)`
310
+ **Purpose**: Flatten functions marked as default exports (not at root level)
311
+ **Result**: `shouldFlatten: true, flattenType: "default-function"`
312
+
313
+ ---
314
+
315
+ ### C18: Single Named Export Match (Secondary Check)
316
+
317
+ **Line**: [693](../src/lib/helpers/api_builder/decisions.mjs#L693)
318
+ **Condition**: `if (moduleKeys.length === 1 && moduleKeys[0] === moduleName)`
319
+ **Purpose**: Auto-flatten when module exports single named export matching filename
320
+ **Result**: `shouldFlatten: true, flattenType: "object-auto-flatten"`
321
+
322
+ ---
323
+
324
+ ### C19: Multi-File Function with Preferred Name
325
+
326
+ **Line**: [844](../src/lib/helpers/api_builder/decisions.mjs#L844)
327
+ **Condition**: `if (hasPreferredName)` (from function name preference logic)
328
+ **Purpose**: Use original function names over sanitized filenames when they match semantically
329
+ **Result**: `specialHandling: "preferred-export-names"`
330
+
331
+ ---
332
+
333
+ ### C20: Multi-File Self-Referential
334
+
335
+ **Line**: [846](../src/lib/helpers/api_builder/decisions.mjs#L846)
336
+ **Condition**: `else if (selfReferentialFiles.has(moduleName))`
337
+ **Purpose**: Self-referential files in multi-file context get special namespace handling
338
+ **Result**: `type: "self-referential"`
339
+
340
+ ---
341
+
342
+ ### C21: Multi-File Flattening Scenarios
343
+
344
+ **Line**: [753](../src/lib/helpers/api_builder/decisions.mjs#L753)
345
+ **Condition**: `else` (standard multi-file processing)
346
+ **Sub-conditions**: 4 flattening scenarios (C21a-C21d)
347
+
348
+ #### C21a: Single Default Object
349
+
350
+ **Line**: [859](../src/lib/helpers/api_builder/decisions.mjs#L859)
351
+ **Condition**: `if (!hasMultipleDefaultExports && mod.default && typeof mod.default === "object")`
352
+ **Result**: `shouldFlatten: true, flattenType: "single-default-object"`
353
+
354
+ #### C21b: Multi-Default No Default
355
+
356
+ **Line**: [863](../src/lib/helpers/api_builder/decisions.mjs#L863)
357
+ **Condition**: `else if (hasMultipleDefaultExports && !mod.default && moduleKeys.length > 0)`
358
+ **Result**: `shouldFlatten: true, flattenType: "multi-default-no-default"`
359
+
360
+ #### C21c: Single Named Export Match
361
+
362
+ **Line**: [867](../src/lib/helpers/api_builder/decisions.mjs#L867)
363
+ **Condition**: `else if (moduleKeys.length === 1 && moduleKeys[0] === apiPathKey)`
364
+ **Result**: `shouldFlatten: true, flattenType: "single-named-export-match"`
365
+
366
+ #### C21d: Category Name Match Flatten
367
+
368
+ **Line**: [873](../src/lib/helpers/api_builder/decisions.mjs#L873)
369
+ **Condition**: `else if (!mod.default && moduleKeys.length > 0 && moduleName === categoryName)`
370
+ **Result**: `shouldFlatten: true, flattenType: "category-name-match-flatten"`
371
+
372
+ ---
373
+
374
+ ## buildCategoryStructure() Conditions
375
+
376
+ **File**: [`src/lib/helpers/api_builder/construction.mjs`](../src/lib/helpers/api_builder/construction.mjs#L125-L555)
377
+ **Function**: `buildCategoryStructure(categoryPath, options)`
378
+ **Lines**: [125-555](../src/lib/helpers/api_builder/construction.mjs#L125-L555)
379
+
380
+ Assembles the actual API structure based on decisions from buildCategoryDecisions().
381
+
382
+ ### C22: Single-File Flattening Cases
383
+
384
+ **Line**: [145](../src/lib/helpers/api_builder/construction.mjs#L145)
385
+ **Condition**: `if (decisions.shouldFlatten)`
386
+ **Purpose**: Apply flattening decisions to single-file cases
387
+ **Branches**: 5 flatten types handled via switch statement [146-175](../src/lib/helpers/api_builder/construction.mjs#L146-L175)
388
+
389
+ ### C23: Single-File Preferred Name (No Flatten)
390
+
391
+ **Line**: [180](../src/lib/helpers/api_builder/construction.mjs#L180)
392
+ **Condition**: `if (decisions.preferredName && decisions.preferredName !== moduleName)`
393
+ **Purpose**: Use preferred name without flattening
394
+ **Result**: `return { [decisions.preferredName]: mod }`
395
+
396
+ ### C24: Category Merge Special Handling
397
+
398
+ **Line**: [195](../src/lib/helpers/api_builder/construction.mjs#L195)
399
+ **Condition**: `if (specialHandling === "category-merge")`
400
+ **Purpose**: Merge logic when module filename matches category name
401
+ **Result**: Merges module contents into categoryModules
402
+
403
+ ### C25: Multi-File Flattening
404
+
405
+ **Line**: [217](../src/lib/helpers/api_builder/construction.mjs#L217)
406
+ **Condition**: `if (shouldFlatten)`
407
+ **Purpose**: Apply various flattening strategies in multi-file context
408
+ **Branches**: Switch statement handling 4 flatten types [218-318](../src/lib/helpers/api_builder/construction.mjs#L218-L318)
409
+
410
+ **Special Case - Double Proxy Layer**: [245-290](../src/lib/helpers/api_builder/construction.mjs#L245-L290)
411
+ When Proxy assignment fails, creates wrapper proxy to ensure API completeness while preserving original proxy behavior
412
+
413
+ ### C26: Upward Flattening (Single Key Matching Category)
414
+
415
+ **Line**: [384](../src/lib/helpers/api_builder/construction.mjs#L384)
416
+ **Condition**: `if (keys.length === 1)`
417
+ **Sub-condition**: [386](../src/lib/helpers/api_builder/construction.mjs#L386): `if (singleKey === categoryName)`
418
+ **Purpose**: When category contains single key matching category name, flatten upward
419
+ **Result**: Return contents directly, avoiding redundant nesting
420
+
421
+ ---
422
+
423
+ ## multidefault_getFlatteningDecision() Conditions
424
+
425
+ **File**: [`src/lib/helpers/multidefault.mjs`](../src/lib/helpers/multidefault.mjs#L178-L262)
426
+ **Function**: `multidefault_getFlatteningDecision(options)`
427
+ **Lines**: [178-262](../src/lib/helpers/multidefault.mjs#L178-L262)
428
+
429
+ Specialized flattening logic for multi-default export contexts.
430
+
431
+ ### C27: Multi-Default Self-Referential
432
+
433
+ **Line**: [199](../src/lib/helpers/multidefault.mjs#L199)
434
+ **Condition**: `if (isSelfReferential)`
435
+ **Purpose**: Self-referential default exports in multi-default context preserve as namespace
436
+ **Result**: `shouldFlatten: false, preserveAsNamespace: true`
437
+ **Reason**: `"self-referential default export"`
438
+
439
+ ### C28: Multi-Default With Default Export
440
+
441
+ **Line**: [202](../src/lib/helpers/multidefault.mjs#L202)
442
+ **Condition**: `if (hasMultipleDefaultExports)` → [203](../src/lib/helpers/multidefault.mjs#L203): `if (moduleHasDefault)`
443
+ **Purpose**: Modules WITH default exports in multi-default context preserve as namespaces
444
+ **Result**: `shouldFlatten: false, preserveAsNamespace: true`
445
+ **Reason**: `"multi-default context with default export"`
446
+
447
+ ### C29: Multi-Default Without Default Export
448
+
449
+ **Line**: [209](../src/lib/helpers/multidefault.mjs#L209) ? [219](../src/lib/helpers/multidefault.mjs#L219): `else`
450
+ **Condition**: `if (hasMultipleDefaultExports)` → `else` (when !moduleHasDefault)
451
+ **Purpose**: Modules WITHOUT default exports in multi-default context flatten to root
452
+ **Result**: `shouldFlatten: true, flattenToRoot: true`
453
+ **Reason**: `"multi-default context without default export"`
454
+
455
+ ### C30: Single Named Export Match
456
+
457
+ **Line**: [227](../src/lib/helpers/multidefault.mjs#L227)
458
+ **Condition**: `if (moduleKeys.length === 1 && moduleKeys[0] === apiPathKey)`
459
+ **Purpose**: Single named export matching filename in multi-default context
460
+ **Result**: `shouldFlatten: true, flattenToRoot: false`
461
+ **Reason**: `"single named export matching filename"`
462
+
463
+ ### C31: Single File No Default (Commented Out)
464
+
465
+ **Lines**: [238-247](../src/lib/helpers/multidefault.mjs#L238-L247)
466
+ **Status**: ⚠️ **DISABLED** - Commented out
467
+ **Original Purpose**: Flatten single file with named exports only in multi-default context
468
+
469
+ ### C32: Default Namespace Preservation
470
+
471
+ **Line**: [250](../src/lib/helpers/multidefault.mjs#L250)
472
+ **Condition**: Default case
473
+ **Purpose**: Preserve as namespace when no multi-default flattening rules apply
474
+ **Result**: `shouldFlatten: false, preserveAsNamespace: true`
475
+ **Reason**: `"default namespace preservation"`
476
+
477
+ ---
478
+
479
+ ## Summary
480
+
481
+ **Total Active Conditions**: 32 documented conditions (2 commented out: C06, C31)
482
+ **Primary Functions**: 5 key functions containing API generation logic
483
+ **File Locations**: 3 source files across api_builder/ and multidefault.mjs
484
+
485
+ ### Condition Categories
486
+
487
+ - **Flattening Rules** (7): C01-C07
488
+ - **Module Processing** (9): C08-C09d
489
+ - **Category Decisions** (13): C10-C21d
490
+ - **Structural Assembly** (5): C22-C26
491
+ - **Multi-Default Logic** (6): C27-C32
492
+
493
+ ### Key Architectural Patterns
494
+
495
+ 1. **Self-Referential Protection**: Multiple conditions (C01, C08b, C09c, C20, C27) prevent circular structures
496
+ 2. **Multi-Default Coordination**: Specialized handling (C02, C03, C08a, C21b, C28, C29) prevents naming conflicts
497
+ 3. **Smart Flattening**: Auto-detection (C04, C05, C12, C13, C18, C30) reduces unnecessary nesting
498
+ 4. **Name Preservation**: Function name preference (C16, C19) maintains semantic meaning
499
+ 5. **Depth Awareness**: Many conditions check `currentDepth > 0` to preserve root-level structure
500
+
501
+ ---
502
+
503
+ ## Document Maintenance
504
+
505
+ **Last Full Audit**: December 30, 2025
506
+ **Commit**: a50531d1ba712f0c4efd9ab9b7cf8f62a0d379da
507
+ **Lines Verified**: All line numbers manually verified against source code
508
+ **Links**: All GitHub-style links use `#Lxxx-Lyyy` format for precise navigation