@archivist-gg/dnd5e 0.3.1 → 0.3.5

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 (259) hide show
  1. package/LICENSES/SRD.md +25 -6
  2. package/dist/armor/armor.codec.js +4 -3
  3. package/dist/armor/armor.parser.js +3 -2
  4. package/dist/armor/armor.schema.d.ts +4 -0
  5. package/dist/armor/armor.schema.js +2 -1
  6. package/dist/armor/armor.types.d.ts +8 -0
  7. package/dist/background/background.codec.js +7 -6
  8. package/dist/background/background.parser.js +6 -5
  9. package/dist/background/background.schema.d.ts +26 -0
  10. package/dist/background/background.schema.js +5 -4
  11. package/dist/background/background.types.d.ts +22 -0
  12. package/dist/{chunk-4TIJKN6O.js → chunk-23LZLBJK.js} +1 -1
  13. package/dist/{chunk-AFKTJXRA.js → chunk-2DFENQIJ.js} +18 -0
  14. package/dist/chunk-2FRUSVZS.js +489 -0
  15. package/dist/chunk-2VDTW7QO.js +1580 -0
  16. package/dist/{chunk-ZZGEVJKX.js → chunk-3JOTQW7A.js} +1 -1
  17. package/dist/{chunk-5ZBE4CWV.js → chunk-3PZHBLFG.js} +1 -1
  18. package/dist/chunk-4U55VNC7.js +22 -0
  19. package/dist/{chunk-4JHOHWBI.js → chunk-4XTNPNQB.js} +1 -1
  20. package/dist/{chunk-HCP3GMHS.js → chunk-5N2GW72F.js} +15 -2
  21. package/dist/{chunk-42Y5IJKT.js → chunk-5RKLL2AD.js} +5 -1
  22. package/dist/{chunk-SE7AZDR3.js → chunk-63XQXPZL.js} +29 -3
  23. package/dist/{chunk-4F6AIZ36.js → chunk-6BFWZW6T.js} +1 -1
  24. package/dist/{chunk-GJOI2GHP.js → chunk-6GNXYAYP.js} +1 -1
  25. package/dist/{chunk-66XXW2Z2.js → chunk-6PXTNCBP.js} +2 -2
  26. package/dist/chunk-6X2NV665.js +33 -0
  27. package/dist/{chunk-LV4SNWZQ.js → chunk-6X4KUDMU.js} +8 -1
  28. package/dist/{chunk-ZMR77DDL.js → chunk-AW3EHF3L.js} +1 -1
  29. package/dist/{chunk-TLYDBT5F.js → chunk-CGRLQ34U.js} +64 -7
  30. package/dist/chunk-CJYCVNW2.js +7 -0
  31. package/dist/{chunk-XLSVNUTK.js → chunk-CV5XDJKU.js} +1 -1
  32. package/dist/{chunk-RAWJTA45.js → chunk-DEEHHLAP.js} +1 -1
  33. package/dist/{chunk-6IRYTM5V.js → chunk-DPUJDOKV.js} +119 -28
  34. package/dist/{chunk-GE4TLPWM.js → chunk-EHDATXP7.js} +1 -1
  35. package/dist/chunk-EVMUJYUD.js +195 -0
  36. package/dist/{chunk-K6Q5OUGK.js → chunk-GFZ7PITJ.js} +86 -10
  37. package/dist/{chunk-6NK2MUD3.js → chunk-HZA7OE7N.js} +9 -2
  38. package/dist/{chunk-TN6ZLTNU.js → chunk-I2NDWFDD.js} +51 -4
  39. package/dist/{chunk-3DZ74AKK.js → chunk-IN4M4X7P.js} +8 -2
  40. package/dist/chunk-IUAAXXNO.js +58 -0
  41. package/dist/{chunk-NXSWH3AE.js → chunk-IWRVOCT5.js} +1 -1
  42. package/dist/{chunk-XJNECUPT.js → chunk-JC5UNIVM.js} +19 -0
  43. package/dist/{chunk-24GFQU7T.js → chunk-JSZ4H6AQ.js} +1 -1
  44. package/dist/{chunk-XTIQWSFM.js → chunk-KADJZGZY.js} +1 -1
  45. package/dist/{chunk-L7E2UT5A.js → chunk-KK33PIDN.js} +5 -1
  46. package/dist/chunk-KPEJMNRD.js +302 -0
  47. package/dist/chunk-KU3YLF6D.js +106 -0
  48. package/dist/{chunk-5INR4NSL.js → chunk-LDDCNPHD.js} +1 -1
  49. package/dist/chunk-LVQLWRCU.js +15 -0
  50. package/dist/chunk-MI7P3NX3.js +161 -0
  51. package/dist/{chunk-PHQRGDRQ.js → chunk-N3A5ICBO.js} +5 -1
  52. package/dist/chunk-O4SRD3J5.js +165 -0
  53. package/dist/chunk-OAXWSVJB.js +81 -0
  54. package/dist/chunk-OZP6JFGT.js +162 -0
  55. package/dist/{chunk-NAEPSZAM.js → chunk-PDJSUH24.js} +24 -2
  56. package/dist/chunk-PP2UHLBA.js +50 -0
  57. package/dist/chunk-PVCEA4HZ.js +6 -0
  58. package/dist/{chunk-RSDRMH54.js → chunk-RF4TYCA2.js} +1 -1
  59. package/dist/chunk-RLGQ5PZZ.js +16 -0
  60. package/dist/chunk-RVXC6ZHY.js +89 -0
  61. package/dist/chunk-S7REMWW4.js +21 -0
  62. package/dist/{chunk-7VJ6BOA5.js → chunk-SMLXZUBH.js} +9 -1
  63. package/dist/chunk-TOM66P2P.js +38 -0
  64. package/dist/chunk-UA5KS2PL.js +26 -0
  65. package/dist/{chunk-N6N74K6X.js → chunk-UBBKSYBY.js} +1 -1
  66. package/dist/{chunk-353WXS6S.js → chunk-UIRMA5KM.js} +1 -1
  67. package/dist/{chunk-BIK4DFWK.js → chunk-ULCQ73LA.js} +1 -1
  68. package/dist/{chunk-2BWAID3Y.js → chunk-UMWIPLLM.js} +29 -3
  69. package/dist/chunk-UQ3ZFCWD.js +178 -0
  70. package/dist/chunk-UXPGW4TI.js +101 -0
  71. package/dist/chunk-V2MJE6NC.js +133 -0
  72. package/dist/{chunk-D3CLOBE3.js → chunk-V373TRJE.js} +48 -10
  73. package/dist/chunk-VQAXTIBW.js +100 -0
  74. package/dist/chunk-W74BCA7V.js +159 -0
  75. package/dist/{chunk-WP2CX2JO.js → chunk-WELIKLZF.js} +22 -1
  76. package/dist/{chunk-MDEJHMKK.js → chunk-WHVLNFTG.js} +26 -5
  77. package/dist/{chunk-GZ46OVGZ.js → chunk-WSVMLNTO.js} +1 -1
  78. package/dist/{chunk-4LZJXJJS.js → chunk-WXWPK3LI.js} +6 -2
  79. package/dist/chunk-X3D6LXUU.js +185 -0
  80. package/dist/chunk-XJ2F2WO6.js +8 -0
  81. package/dist/{chunk-73HOFQQ5.js → chunk-Y4AGLCY6.js} +1 -1
  82. package/dist/chunk-YBLDE5CG.js +42 -0
  83. package/dist/{chunk-JEYQU3JT.js → chunk-YHYTW5QA.js} +2 -18
  84. package/dist/{chunk-PZOWBI3B.js → chunk-YLL2QXY2.js} +7 -2
  85. package/dist/class/class.codec.js +12 -9
  86. package/dist/class/class.parser.js +11 -8
  87. package/dist/class/class.schema.d.ts +55 -3
  88. package/dist/class/class.schema.js +9 -7
  89. package/dist/class/class.types.d.ts +48 -3
  90. package/dist/condition/condition.codec.d.ts +9 -0
  91. package/dist/condition/condition.entity-type.d.ts +2 -0
  92. package/dist/condition/condition.parser.d.ts +13 -0
  93. package/dist/condition/condition.parser.js +7 -0
  94. package/dist/condition/condition.schema.d.ts +29 -0
  95. package/dist/condition/condition.types.d.ts +15 -0
  96. package/dist/condition/condition.types.js +0 -0
  97. package/dist/dnd/constants.d.ts +22 -0
  98. package/dist/dnd/constants.js +9 -3
  99. package/dist/dnd/formula-tags.js +2 -2
  100. package/dist/dnd/math.d.ts +26 -0
  101. package/dist/dnd/math.js +12 -2
  102. package/dist/dnd/prose-tags.js +1 -1
  103. package/dist/dnd/resource-formula.d.ts +36 -10
  104. package/dist/dnd/resource-formula.js +10 -155
  105. package/dist/dnd/srd-tag-converter.js +3 -3
  106. package/dist/dnd/tag-grammar.js +1 -1
  107. package/dist/dnd/warn-once.d.ts +2 -0
  108. package/dist/dnd/warn-once.js +8 -0
  109. package/dist/entities/base-item-resolver.js +2 -2
  110. package/dist/entities/slug.d.ts +13 -0
  111. package/dist/entities/slug.js +5 -3
  112. package/dist/entities/wikilink-display.d.ts +3 -0
  113. package/dist/entities/wikilink-display.js +10 -0
  114. package/dist/feat/feat.category-codes.d.ts +32 -0
  115. package/dist/feat/feat.category-codes.js +14 -0
  116. package/dist/feat/feat.codec.js +7 -5
  117. package/dist/feat/feat.parser.js +6 -4
  118. package/dist/feat/feat.schema.d.ts +239 -0
  119. package/dist/feat/feat.schema.js +5 -3
  120. package/dist/feat/feat.types.d.ts +37 -1
  121. package/dist/index.js +2033 -6907
  122. package/dist/item/item.codec.js +4 -3
  123. package/dist/item/item.enrichment.js +4 -4
  124. package/dist/item/item.parser.js +3 -2
  125. package/dist/item/item.schema.d.ts +69 -3
  126. package/dist/item/item.schema.js +2 -1
  127. package/dist/item/item.types.d.ts +69 -3
  128. package/dist/monster/monster.codec.d.ts +7 -6
  129. package/dist/monster/monster.enrichment.js +4 -4
  130. package/dist/monster/monster.format.d.ts +135 -0
  131. package/dist/monster/monster.format.js +78 -0
  132. package/dist/monster/monster.parser.d.ts +6 -1
  133. package/dist/monster/monster.parser.js +10 -1
  134. package/dist/monster/monster.schema.d.ts +369 -0
  135. package/dist/monster/monster.schema.js +34 -0
  136. package/dist/monster/monster.types.d.ts +200 -14
  137. package/dist/optional-feature/optional-feature.codec.js +6 -5
  138. package/dist/optional-feature/optional-feature.parser.js +5 -4
  139. package/dist/optional-feature/optional-feature.schema.d.ts +185 -0
  140. package/dist/optional-feature/optional-feature.schema.js +4 -3
  141. package/dist/pack.d.ts +1 -1
  142. package/dist/pc/conditions.constants.d.ts +0 -1
  143. package/dist/pc/conditions.constants.js +1 -3
  144. package/dist/pc/decision-recognizer.js +1 -1
  145. package/dist/pc/pc.additional-spells.d.ts +47 -0
  146. package/dist/pc/pc.additional-spells.js +23 -0
  147. package/dist/pc/pc.asi-flatten.d.ts +18 -0
  148. package/dist/pc/pc.decision-engine.d.ts +105 -17
  149. package/dist/pc/pc.decision-engine.js +28 -12
  150. package/dist/pc/pc.defense-normalize.d.ts +11 -0
  151. package/dist/pc/pc.defense-normalize.js +6 -0
  152. package/dist/pc/pc.equipment.d.ts +31 -2
  153. package/dist/pc/pc.equipment.js +12 -8
  154. package/dist/pc/pc.feature-effects.d.ts +234 -11
  155. package/dist/pc/pc.feature-effects.js +21 -5
  156. package/dist/pc/pc.parser.js +2 -2
  157. package/dist/pc/pc.pools.d.ts +11 -3
  158. package/dist/pc/pc.pools.js +9 -13
  159. package/dist/pc/pc.proficiencies.d.ts +54 -29
  160. package/dist/pc/pc.proficiencies.js +74 -95
  161. package/dist/pc/pc.proficiency-grants.d.ts +58 -0
  162. package/dist/pc/pc.proficiency-normalize.d.ts +24 -0
  163. package/dist/pc/pc.proficiency-normalize.js +12 -0
  164. package/dist/pc/pc.proficiency-query.d.ts +13 -0
  165. package/dist/pc/pc.proficiency-query.js +1 -1
  166. package/dist/pc/pc.recalc.d.ts +69 -14
  167. package/dist/pc/pc.recalc.js +261 -122
  168. package/dist/pc/pc.resolver.d.ts +34 -8
  169. package/dist/pc/pc.resolver.js +27 -12
  170. package/dist/pc/pc.resource-seed.d.ts +3 -2
  171. package/dist/pc/pc.resource-seed.js +19 -17
  172. package/dist/pc/pc.resources.d.ts +87 -0
  173. package/dist/pc/pc.resources.js +21 -0
  174. package/dist/pc/pc.rest.d.ts +10 -1
  175. package/dist/pc/pc.rest.js +66 -12
  176. package/dist/pc/pc.schema.d.ts +139 -3
  177. package/dist/pc/pc.schema.js +4 -2
  178. package/dist/pc/pc.slotting.js +3 -3
  179. package/dist/pc/pc.spellcasting.d.ts +75 -6
  180. package/dist/pc/pc.spellcasting.js +16 -6
  181. package/dist/pc/pc.table-column.d.ts +23 -0
  182. package/dist/pc/pc.table-column.js +13 -3
  183. package/dist/pc/pc.types.d.ts +251 -12
  184. package/dist/pc/pool-layout.d.ts +47 -0
  185. package/dist/pc/pool-layout.js +16 -0
  186. package/dist/pc/roll-scope.d.ts +2 -0
  187. package/dist/pc/roll-scope.js +8 -0
  188. package/dist/pc/roll-tag-labels.d.ts +40 -0
  189. package/dist/pc/roll-tag-labels.js +17 -0
  190. package/dist/pc/spell-source.d.ts +21 -0
  191. package/dist/pc/spell-source.js +13 -0
  192. package/dist/race/race.codec.js +9 -7
  193. package/dist/race/race.parser.js +8 -6
  194. package/dist/race/race.schema.d.ts +51 -1
  195. package/dist/race/race.schema.js +8 -5
  196. package/dist/race/race.structural.d.ts +7 -0
  197. package/dist/race/race.structural.js +6 -0
  198. package/dist/race/race.types.d.ts +20 -0
  199. package/dist/schemas/attack-schema.d.ts +5 -0
  200. package/dist/schemas/caster-type-schema.d.ts +14 -0
  201. package/dist/schemas/caster-type-schema.js +6 -0
  202. package/dist/schemas/choice-schema.js +2 -2
  203. package/dist/schemas/entity-extras-schema.d.ts +53 -0
  204. package/dist/schemas/entity-extras-schema.js +10 -0
  205. package/dist/schemas/equipment-grant-schema.d.ts +2 -0
  206. package/dist/schemas/equipment-grant-schema.js +1 -1
  207. package/dist/schemas/feature-alias.d.ts +34 -0
  208. package/dist/schemas/feature-effect-schema.d.ts +133 -0
  209. package/dist/schemas/feature-effect-schema.js +1 -1
  210. package/dist/schemas/feature-schema.d.ts +8 -0
  211. package/dist/schemas/feature-schema.js +6 -4
  212. package/dist/schemas/resource-schema.d.ts +43 -0
  213. package/dist/schemas/resource-schema.js +1 -1
  214. package/dist/schemas/selection-pool-schema.d.ts +2 -0
  215. package/dist/schemas/selection-pool-schema.js +1 -1
  216. package/dist/spell/spell.access.js +23 -3
  217. package/dist/spell/spell.codec.js +4 -3
  218. package/dist/spell/spell.enrichment.js +4 -4
  219. package/dist/spell/spell.parser.d.ts +30 -0
  220. package/dist/spell/spell.parser.js +9 -2
  221. package/dist/spell/spell.scaling.d.ts +27 -6
  222. package/dist/spell/spell.scaling.js +25 -6
  223. package/dist/spell/spell.schema.d.ts +44 -2
  224. package/dist/spell/spell.schema.js +2 -1
  225. package/dist/spell/spell.types.d.ts +14 -0
  226. package/dist/subclass/subclass.codec.d.ts +1 -1
  227. package/dist/subclass/subclass.codec.js +11 -8
  228. package/dist/subclass/subclass.parser.js +10 -7
  229. package/dist/subclass/subclass.schema.d.ts +54 -7
  230. package/dist/subclass/subclass.schema.js +8 -6
  231. package/dist/subclass/subclass.types.d.ts +20 -2
  232. package/dist/types/choice.d.ts +53 -2
  233. package/dist/types/choice.js +13 -1
  234. package/dist/types/equipment-grant.d.ts +8 -1
  235. package/dist/types/feature-effect.d.ts +85 -23
  236. package/dist/types/feature.d.ts +70 -1
  237. package/dist/types/optional-feature.types.d.ts +28 -0
  238. package/dist/types/resource.d.ts +21 -1
  239. package/dist/types/selection-pool.d.ts +17 -2
  240. package/dist/weapon/weapon.classify.js +2 -2
  241. package/dist/weapon/weapon.codec.js +4 -3
  242. package/dist/weapon/weapon.parser.js +3 -2
  243. package/dist/weapon/weapon.schema.d.ts +4 -0
  244. package/dist/weapon/weapon.schema.js +2 -1
  245. package/dist/weapon/weapon.types.d.ts +8 -0
  246. package/package.json +2 -2
  247. package/dist/chunk-5XUXXAQJ.js +0 -30
  248. package/dist/chunk-7P65Q426.js +0 -158
  249. package/dist/chunk-7TEK5KK7.js +0 -49
  250. package/dist/chunk-AIRFC5NQ.js +0 -143
  251. package/dist/chunk-CZPMTQOY.js +0 -68
  252. package/dist/chunk-N2JE7BWL.js +0 -81
  253. package/dist/chunk-NXR3BD2V.js +0 -90
  254. package/dist/chunk-O5EYMKFH.js +0 -6
  255. package/dist/chunk-Q5K6LWBZ.js +0 -45
  256. package/dist/chunk-TNUFPIXI.js +0 -1110
  257. package/dist/chunk-TZK36BU7.js +0 -38
  258. package/dist/chunk-W7HWMMBF.js +0 -46
  259. package/dist/chunk-Y4I74YEG.js +0 -33
@@ -0,0 +1,47 @@
1
+ import type { EntryAffordance, PoolLayout } from "../types/selection-pool.js";
2
+ import type { ResolvedPoolEntry } from "./pc.types.js";
3
+ /** The ONE `rendering_hint` → `PoolLayout` table (R4-G4 §4.2.2, invariant 3): a DATA table in the
4
+ * RESET_LABELS shape. Absent keys route to the default, and R4-G5 added NONE: `pool-selection` and
5
+ * `stance` are a measured empty delta (spec §10) and `granted-die-to-ally` became a per-ROW affordance
6
+ * in the table below, so this one still holds exactly the two G4 keys. */
7
+ export declare const RENDERING_HINT_LAYOUT: Readonly<Record<string, PoolLayout>>;
8
+ /** The majority mapped hint over the pool's members; members with an empty or unmapped hint do not
9
+ * vote; no votes → undefined; a tie between two mapped values → undefined (Gate 0 Q8).
10
+ * UNMAPPED is decided by OWN-property lookup, never by truthiness of a plain index (review M-2):
11
+ * `rendering_hint` is a free `z.string().optional()` on converter data, so a member may carry any
12
+ * string, and an object-literal table answers the `Object.prototype` keys through the prototype
13
+ * chain. Measured 2026-09-06 on this table: `constructor`, `toString`, `hasOwnProperty` and
14
+ * `valueOf` each index to a FUNCTION and each has `hasOwnProperty` false, while the two mapped
15
+ * hints, `dice-pool` and `point-pool`, are the only keys that are both a string and own (review
16
+ * M-1: the earlier wording named `dice-pool` alone). Without the guard a lone junk hint voted that
17
+ * function as the layout, and one junk member beside genuine `dice-pool` members collapsed a
18
+ * correct majority into a phantom tie. */
19
+ export declare function derivePoolLayout(entries: ReadonlyArray<ResolvedPoolEntry>): PoolLayout | undefined;
20
+ /** The ONE `rendering_hint` to `EntryAffordance` table (R4-G5 §4.2.1, invariant 3): the PER-ENTRY sibling of
21
+ * `RENDERING_HINT_LAYOUT`. `granted-die-to-ally` is its only key, and the four documents carrying it
22
+ * (Commander's Strike x2, Rally x2) are field-identical to the other 39 maneuvers except that hint, so a
23
+ * per-row affordance is the only place their meaning can land. `stance` gets NO key (its three hinted documents
24
+ * are field-identical to three unhinted siblings: a measured empty delta) and `pool-selection` none. */
25
+ export declare const RENDERING_HINT_AFFORDANCE: Readonly<Record<string, EntryAffordance>>;
26
+ /** The entry's affordance, by OWN-property lookup (`derivePoolLayout`'s precedent, invariant 3): `rendering_hint`
27
+ * is a free `z.string().optional()` on converter data, so a member may carry ANY string, and an object-literal
28
+ * table answers `constructor` / `toString` / `hasOwnProperty` / `valueOf` through the prototype chain with a
29
+ * FUNCTION. Absent, empty and unmapped hints all return undefined. */
30
+ export declare function deriveEntryAffordance(entity: ResolvedPoolEntry["entity"]): EntryAffordance | undefined;
31
+ /** Caption TEMPLATES per affordance, in the `RESET_LABELS` shape: the game sentence lives in DATA here, never in
32
+ * a renderer (invariant 3). `{amount}` and `{die}` are filled by `formatAffordanceCaption`.
33
+ *
34
+ * The two placeholders ABUT (R4 {G5, G6} live rider N-1-12): the sheet read `1 d8 to an ally`, which is not how
35
+ * a die is written. `{die}` is a FACE by contract · the caller passes what `resolveScalingDie` returns, which is
36
+ * `base` or one of `scaling`'s entries, and every one of those in shipped data is face-shaped ("d6" throughout
37
+ * the SRD runtime JSON and the compendium bundle) · so amount and face compose into one dice expression. */
38
+ export declare const AFFORDANCE_CAPTIONS: Readonly<Record<EntryAffordance, string>>;
39
+ /** Fill an affordance's caption template. PURE, and pure on purpose: the caller supplies values it has ALREADY
40
+ * resolved (the plugin resolves the die through `resolveScalingDie` at the owner's class level, exactly as the
41
+ * shipped spend control resolves its own "(d8)" label), so no renderer ever holds the sentence and no engine
42
+ * module ever needs the character. A placeholder with no value is left VERBATIM rather than printed as
43
+ * "undefined". */
44
+ export declare function formatAffordanceCaption(affordance: EntryAffordance, values: {
45
+ amount: number;
46
+ die: string;
47
+ }): string;
@@ -0,0 +1,16 @@
1
+ import {
2
+ AFFORDANCE_CAPTIONS,
3
+ RENDERING_HINT_AFFORDANCE,
4
+ RENDERING_HINT_LAYOUT,
5
+ deriveEntryAffordance,
6
+ derivePoolLayout,
7
+ formatAffordanceCaption
8
+ } from "../chunk-PP2UHLBA.js";
9
+ export {
10
+ AFFORDANCE_CAPTIONS,
11
+ RENDERING_HINT_AFFORDANCE,
12
+ RENDERING_HINT_LAYOUT,
13
+ deriveEntryAffordance,
14
+ derivePoolLayout,
15
+ formatAffordanceCaption
16
+ };
@@ -0,0 +1,2 @@
1
+ import type { RollKind } from "./pc.types.js";
2
+ export declare function normalizeRollScope(raw: string | undefined, _roll: RollKind): string[] | undefined;
@@ -0,0 +1,8 @@
1
+ import {
2
+ normalizeRollScope
3
+ } from "../chunk-TOM66P2P.js";
4
+ import "../chunk-KU3YLF6D.js";
5
+ import "../chunk-WELIKLZF.js";
6
+ export {
7
+ normalizeRollScope
8
+ };
@@ -0,0 +1,40 @@
1
+ /**
2
+ * R4-G3a §5.2 · the tag mechanism's DATA tables: the single source of every roll/outcome tag
3
+ * TEXT the plugin's three chip surfaces render.
4
+ *
5
+ * Invariant 3: captions and tag texts derive from the effect's own fields through ONE
6
+ * data-shaped table per concern; a closed vocabulary `switch` on game data inside a component is
7
+ * the smell this replaces (all three surfaces spelled `mode === "advantage" ? "ADV" : "DIS"`,
8
+ * which renders "DIS" for a `reroll` the moment `mode` widens: a green tree with a false chip).
9
+ *
10
+ * `Record<RollModifierMode, …>` / `Record<RollKind, …>` are load-bearing: the aliases come from
11
+ * `pc.types.ts`, so widening `RollModifierEntry.mode` without extending these tables is a COMPILE
12
+ * error, not a silent misrender (§14 row 8i's control).
13
+ *
14
+ * `ROLL_MODE_WORD` and `ROLL_NOUN` are the PROSE halves (Task 3 consumes them for feature-card
15
+ * captions); `ROLL_MODE_TAG` is the terse chip half.
16
+ *
17
+ * `ROLL_NOUN` is keyed `RollKind | "any"`, one member wider than the folded `RollModifierEntry`.
18
+ * The fold FANS OUT `roll: "any"` into one entry per roll type (§6.2.1), so no chip surface ever
19
+ * sees it; the RAW effect on a feature row still carries it, and Task 3 captions raw effects. Its
20
+ * noun is "rolls" rather than a stand-in member: an `any` modifier covers checks, saves AND attacks
21
+ * at once, so borrowing "ability checks" for it understates the scope in prose.
22
+ *
23
+ * Never an "EVA" literal for the outcome tag:
24
+ * Evasion is only one of four bearers, and Spellfire Sorcery is not Evasion.
25
+ */
26
+ import type { RollModifierMode, RollKind, SaveOutcome } from "./pc.types.js";
27
+ export declare const ROLL_MODE_TAG: Record<RollModifierMode, string>;
28
+ export declare const ROLL_MODE_WORD: Record<RollModifierMode, string>;
29
+ export declare const ROLL_NOUN: Record<RollKind | "any", string>;
30
+ export declare const AUTO_FAIL_TAG = "AUTO-FAIL";
31
+ /** R4-G7 T8 RIDER-20 (F-ADV) · the ONE glyph a CONDITIONAL tag appends to its text: a `roll-modifier` entry that carries a
32
+ * `condition`, or a `scope` the normaliser could not map (the qualifier the converter left in `scope`), and a `save-outcome`
33
+ * entry that carries a `condition`. `ADV` alone reads "always"; `ADV*` says "only sometimes, hover for when". The chip
34
+ * carriers append it to the `ROLL_MODE_TAG` / `saveOutcomeTag` text, so the glyph is spelled here once. */
35
+ export declare const CONDITIONAL_TAG_MARK = "*";
36
+ /** The closed `save-outcome` result vocabulary as display glyphs: how much damage you still take.
37
+ * `Record<SaveOutcome, string>` (the alias from pc.types.ts) so the union is spelled once. */
38
+ export declare const OUTCOME: Record<SaveOutcome, string>;
39
+ /** `{none, half}` → "0/½": success outcome over failure outcome. */
40
+ export declare const saveOutcomeTag: (onSuccess: SaveOutcome, onFailure: SaveOutcome) => string;
@@ -0,0 +1,17 @@
1
+ // src/pc/roll-tag-labels.ts
2
+ var ROLL_MODE_TAG = { advantage: "ADV", disadvantage: "DIS", reroll: "RR", "add-d4": "+D4" };
3
+ var ROLL_MODE_WORD = { advantage: "advantage", disadvantage: "disadvantage", reroll: "a reroll", "add-d4": "+1d4" };
4
+ var ROLL_NOUN = { "ability-check": "ability checks", "saving-throw": "saving throws", attack: "attack rolls", any: "rolls" };
5
+ var AUTO_FAIL_TAG = "AUTO-FAIL";
6
+ var CONDITIONAL_TAG_MARK = "*";
7
+ var OUTCOME = { none: "0", half: "\xBD", full: "1" };
8
+ var saveOutcomeTag = (onSuccess, onFailure) => `${OUTCOME[onSuccess]}/${OUTCOME[onFailure]}`;
9
+ export {
10
+ AUTO_FAIL_TAG,
11
+ CONDITIONAL_TAG_MARK,
12
+ OUTCOME,
13
+ ROLL_MODE_TAG,
14
+ ROLL_MODE_WORD,
15
+ ROLL_NOUN,
16
+ saveOutcomeTag
17
+ };
@@ -0,0 +1,21 @@
1
+ import type { ResolvedSpell } from "./pc.types.js";
2
+ /** R4-G3b §6 · ONE data-shaped routing descriptor per ResolvedSpell.source, read by the plugin's Spells-tab components in
3
+ * place of thirteen hardcoded `source ===` arms (the standing rule: policy from data, never a vocabulary switch in a
4
+ * component). No `label` (nothing renders a source caption; a provenance caption is G8's) and no `removable` (that is
5
+ * ResolvedSpell.persisted: membership in character.spells.known). `domain` is declared but NO grant producer
6
+ * hardcodes it; the one thing that reaches a sheet carrying it is a hand-authored `spells.known[].source:
7
+ * domain`, permitted by pc.schema.ts and passed through by normalizeKnownSpell (pc.spellcasting.ts). */
8
+ export interface SpellSourceDescriptor {
9
+ /** The row's DC / attack bonus come from its own `ability` when it carries one, not from a class. */
10
+ ownAbility: boolean;
11
+ /** Which surface the row belongs to: the class/grant spellbook sections, or Scrolls & Consumables. */
12
+ section: "spellbook" | "consumable";
13
+ /** A leveled row at a level the character owns no slot for gets its own free-cast block. */
14
+ freeCastWhenNoSlot: boolean;
15
+ /** The row is preparable/lockable in the Prepare list (and seeds its level filter chips). */
16
+ showInPrepare: boolean;
17
+ /** The row is a grant, so it lifts the Spells tab's "No Spellcasting" empty state on its own. */
18
+ countsAsGranted: boolean;
19
+ }
20
+ export declare const SPELL_SOURCE: Record<ResolvedSpell["source"], SpellSourceDescriptor>;
21
+ export declare const spellSource: (s: Pick<ResolvedSpell, "source">) => SpellSourceDescriptor;
@@ -0,0 +1,13 @@
1
+ // src/pc/spell-source.ts
2
+ var SPELL_SOURCE = {
3
+ class: { ownAbility: false, section: "spellbook", freeCastWhenNoSlot: false, showInPrepare: true, countsAsGranted: false },
4
+ feat: { ownAbility: true, section: "spellbook", freeCastWhenNoSlot: true, showInPrepare: true, countsAsGranted: true },
5
+ item: { ownAbility: false, section: "consumable", freeCastWhenNoSlot: false, showInPrepare: false, countsAsGranted: true },
6
+ race: { ownAbility: true, section: "spellbook", freeCastWhenNoSlot: true, showInPrepare: true, countsAsGranted: true },
7
+ domain: { ownAbility: false, section: "spellbook", freeCastWhenNoSlot: false, showInPrepare: true, countsAsGranted: false }
8
+ };
9
+ var spellSource = (s) => SPELL_SOURCE[s.source];
10
+ export {
11
+ SPELL_SOURCE,
12
+ spellSource
13
+ };
@@ -1,13 +1,15 @@
1
1
  import {
2
2
  raceCodec
3
- } from "../chunk-ZZGEVJKX.js";
4
- import "../chunk-PHQRGDRQ.js";
5
- import "../chunk-2BWAID3Y.js";
6
- import "../chunk-CZPMTQOY.js";
3
+ } from "../chunk-3JOTQW7A.js";
4
+ import "../chunk-N3A5ICBO.js";
5
+ import "../chunk-UMWIPLLM.js";
6
+ import "../chunk-4U55VNC7.js";
7
+ import "../chunk-W74BCA7V.js";
7
8
  import "../chunk-WYGD2UGN.js";
8
- import "../chunk-PZOWBI3B.js";
9
- import "../chunk-NXSWH3AE.js";
10
- import "../chunk-NXR3BD2V.js";
9
+ import "../chunk-YLL2QXY2.js";
10
+ import "../chunk-IWRVOCT5.js";
11
+ import "../chunk-X3D6LXUU.js";
12
+ import "../chunk-UA5KS2PL.js";
11
13
  export {
12
14
  raceCodec
13
15
  };
@@ -1,12 +1,14 @@
1
1
  import {
2
2
  parseRace
3
- } from "../chunk-PHQRGDRQ.js";
4
- import "../chunk-2BWAID3Y.js";
5
- import "../chunk-CZPMTQOY.js";
3
+ } from "../chunk-N3A5ICBO.js";
4
+ import "../chunk-UMWIPLLM.js";
5
+ import "../chunk-4U55VNC7.js";
6
+ import "../chunk-W74BCA7V.js";
6
7
  import "../chunk-WYGD2UGN.js";
7
- import "../chunk-PZOWBI3B.js";
8
- import "../chunk-NXSWH3AE.js";
9
- import "../chunk-NXR3BD2V.js";
8
+ import "../chunk-YLL2QXY2.js";
9
+ import "../chunk-IWRVOCT5.js";
10
+ import "../chunk-X3D6LXUU.js";
11
+ import "../chunk-UA5KS2PL.js";
10
12
  export {
11
13
  parseRace
12
14
  };
@@ -1,4 +1,23 @@
1
1
  import { z } from "zod";
2
+ /** Exported so the SRD overlay validates AUTHORED fixed increases against the
3
+ * FIXED ARM canonical output is validated against, derived from this one
4
+ * definition so the two cannot drift. Note the precise relationship:
5
+ * `raceEntitySchema` below validates `ability_score_increases` with `asiSchema`,
6
+ * the UNION, of which this is one arm · `overlay.schema.ts` deliberately narrows
7
+ * to this arm alone, because the choice-shaped arm folds nothing at runtime
8
+ * (`flattenRaceAsi` reads only `"ability" in asi`), so rejecting it at authoring
9
+ * time is a guard, not a limitation. */
10
+ export declare const fixedAsiSchema: z.ZodObject<{
11
+ ability: z.ZodEnum<{
12
+ str: "str";
13
+ dex: "dex";
14
+ con: "con";
15
+ int: "int";
16
+ wis: "wis";
17
+ cha: "cha";
18
+ }>;
19
+ amount: z.ZodNumber;
20
+ }, z.core.$strip>;
2
21
  export declare const raceEntitySchema: z.ZodObject<{
3
22
  slug: z.ZodString;
4
23
  name: z.ZodString;
@@ -10,8 +29,8 @@ export declare const raceEntitySchema: z.ZodObject<{
10
29
  description: z.ZodString;
11
30
  size: z.ZodEnum<{
12
31
  medium: "medium";
13
- tiny: "tiny";
14
32
  small: "small";
33
+ tiny: "tiny";
15
34
  large: "large";
16
35
  huge: "huge";
17
36
  }>;
@@ -64,4 +83,35 @@ export declare const raceEntitySchema: z.ZodObject<{
64
83
  traits: z.ZodArray<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
65
84
  choices: z.ZodOptional<z.ZodArray<z.ZodType<import("../index.js").Choice, unknown, z.core.$ZodTypeInternals<import("../index.js").Choice, unknown>>>>;
66
85
  subspecies_of: z.ZodOptional<z.ZodString>;
86
+ rendering_hint: z.ZodOptional<z.ZodString>;
87
+ has_fluff: z.ZodOptional<z.ZodBoolean>;
88
+ has_fluff_images: z.ZodOptional<z.ZodBoolean>;
89
+ creature_type: z.ZodOptional<z.ZodArray<z.ZodString>>;
90
+ creature_type_tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
91
+ additional_spells: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodObject<{
92
+ name: z.ZodOptional<z.ZodString>;
93
+ ability: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
94
+ choose: z.ZodArray<z.ZodString>;
95
+ }, z.core.$strip>]>>;
96
+ known: z.ZodOptional<z.ZodUnknown>;
97
+ innate: z.ZodOptional<z.ZodUnknown>;
98
+ prepared: z.ZodOptional<z.ZodUnknown>;
99
+ expanded: z.ZodOptional<z.ZodUnknown>;
100
+ resourceName: z.ZodOptional<z.ZodString>;
101
+ }, z.core.$strip>>, z.ZodObject<{
102
+ name: z.ZodOptional<z.ZodString>;
103
+ ability: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
104
+ choose: z.ZodArray<z.ZodString>;
105
+ }, z.core.$strip>]>>;
106
+ known: z.ZodOptional<z.ZodUnknown>;
107
+ innate: z.ZodOptional<z.ZodUnknown>;
108
+ prepared: z.ZodOptional<z.ZodUnknown>;
109
+ expanded: z.ZodOptional<z.ZodUnknown>;
110
+ resourceName: z.ZodOptional<z.ZodString>;
111
+ }, z.core.$strip>]>>;
112
+ trait_tags: z.ZodOptional<z.ZodUnknown>;
113
+ lineage: z.ZodOptional<z.ZodUnknown>;
114
+ height_and_weight: z.ZodOptional<z.ZodUnknown>;
115
+ sound_clip: z.ZodOptional<z.ZodUnknown>;
116
+ image: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
67
117
  }, z.core.$strip>;
@@ -1,11 +1,14 @@
1
1
  import {
2
+ fixedAsiSchema,
2
3
  raceEntitySchema
3
- } from "../chunk-2BWAID3Y.js";
4
- import "../chunk-CZPMTQOY.js";
4
+ } from "../chunk-UMWIPLLM.js";
5
+ import "../chunk-W74BCA7V.js";
5
6
  import "../chunk-WYGD2UGN.js";
6
- import "../chunk-PZOWBI3B.js";
7
- import "../chunk-NXSWH3AE.js";
8
- import "../chunk-NXR3BD2V.js";
7
+ import "../chunk-YLL2QXY2.js";
8
+ import "../chunk-IWRVOCT5.js";
9
+ import "../chunk-X3D6LXUU.js";
10
+ import "../chunk-UA5KS2PL.js";
9
11
  export {
12
+ fixedAsiSchema,
10
13
  raceEntitySchema
11
14
  };
@@ -0,0 +1,7 @@
1
+ /** R4-G3b §5.2.9 · the STRUCTURAL pseudo-choices of a race entry: Size / Speed / Darkvision are surfaced as glance tiles
2
+ * and are not content. Shared by the plugin's two trait-name folds (keyed on TRAIT NAMES, lowercased) and by the
3
+ * resolver's `additional_spells` race gate (keyed on select-inline CHOICE IDS; on the corpus only `size` occurs as an
4
+ * id, 18 carriers, 17 saved by this exemption). A measured v1 exception to the schema-not-renderer rule: it must never
5
+ * grow into an allowlist of lineage ids (the structural replacement is the NEXT-REGEN / G7 ask). NOT imported by any
6
+ * schema, parser, codec or srd module (the T6/T12 grep guard keeps it out of the generators graph). */
7
+ export declare const RACE_STRUCTURAL_PSEUDO: ReadonlySet<string>;
@@ -0,0 +1,6 @@
1
+ import {
2
+ RACE_STRUCTURAL_PSEUDO
3
+ } from "../chunk-PVCEA4HZ.js";
4
+ export {
5
+ RACE_STRUCTURAL_PSEUDO
6
+ };
@@ -1,5 +1,6 @@
1
1
  import type { Feature, Ability, Speed, Choice } from "@archivist-gg/dnd5e";
2
2
  import type { Edition } from "@archivist-gg/dnd5e/types/edition";
3
+ import type { AdditionalSpellsEntry } from "@archivist-gg/dnd5e/schemas/entity-extras-schema";
3
4
  export type Size = "tiny" | "small" | "medium" | "large" | "huge";
4
5
  export type FixedAbilityIncrease = {
5
6
  ability: Ability;
@@ -41,4 +42,23 @@ export interface RaceEntity {
41
42
  traits: Feature[];
42
43
  choices?: Choice[];
43
44
  subspecies_of?: string;
45
+ /** Converter/bundle extras declared by race.schema.ts §2.3. Every one is optional: none is
46
+ * read by the pc pipeline today, and declaring them is what stops the parser silently
47
+ * dropping them (the "declare or lose" rule). */
48
+ rendering_hint?: string;
49
+ has_fluff?: boolean;
50
+ has_fluff_images?: boolean;
51
+ creature_type?: string[];
52
+ creature_type_tags?: string[];
53
+ /** DUAL ARITY (§2.8): the converter emits an array on 109 docs, the shipped SRD bundle a bare
54
+ * object on 3 (`SRD 2024/Races/{Elf,Tiefling}.md`, `SRD 5e/Races/Tiefling.md`). */
55
+ additional_spells?: AdditionalSpellsEntry[] | AdditionalSpellsEntry;
56
+ /** The four RAW 5etools passthroughs: `unknown` mirrors the schema's `z.unknown()`. Today's
57
+ * variant set is a snapshot, not a contract, so the type stays maximally loose. */
58
+ trait_tags?: unknown;
59
+ lineage?: unknown;
60
+ height_and_weight?: unknown;
61
+ sound_clip?: unknown;
62
+ /** One wikilink, or an array of them for the multi-fluff-image emit. */
63
+ image?: string | string[];
44
64
  }
@@ -35,4 +35,9 @@ export declare const attackSchema: z.ZodObject<{
35
35
  reach: z.ZodOptional<z.ZodNumber>;
36
36
  }, z.core.$strip>>;
37
37
  condition: z.ZodOptional<z.ZodString>;
38
+ bonus: z.ZodOptional<z.ZodNumber>;
39
+ extra_damage: z.ZodOptional<z.ZodObject<{
40
+ dice: z.ZodString;
41
+ type: z.ZodString;
42
+ }, z.core.$strip>>;
38
43
  }, z.core.$strip>;
@@ -0,0 +1,14 @@
1
+ import { z } from "zod";
2
+ /** THE caster-type vocabulary, declared once (R4-G1a D6a). "artificer" is a fifth progression (level-1 slots,
3
+ * then the half-caster table; multiclass contributes half its levels rounded UP; prepared count is Int mod +
4
+ * floor(level/2) when no table column supplies it). The XPHB Paladin and Ranger carry it in the converter's
5
+ * emission. Imported by the class and subclass schemas, the class types, pc.types and the generator's overlay
6
+ * schema and class merger: never redeclare it. */
7
+ export declare const casterTypeEnum: z.ZodEnum<{
8
+ half: "half";
9
+ full: "full";
10
+ pact: "pact";
11
+ third: "third";
12
+ artificer: "artificer";
13
+ }>;
14
+ export type CasterType = z.infer<typeof casterTypeEnum>;
@@ -0,0 +1,6 @@
1
+ import {
2
+ casterTypeEnum
3
+ } from "../chunk-CJYCVNW2.js";
4
+ export {
5
+ casterTypeEnum
6
+ };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  choiceSchema
3
- } from "../chunk-NXSWH3AE.js";
4
- import "../chunk-NXR3BD2V.js";
3
+ } from "../chunk-IWRVOCT5.js";
4
+ import "../chunk-X3D6LXUU.js";
5
5
  export {
6
6
  choiceSchema
7
7
  };
@@ -0,0 +1,53 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Shared leaf schemas for the entity "extras" the converter and the SRD bundle
4
+ * emit on more than one root. Six root schemas will import from here (race,
5
+ * feat, optional-feature, background, class, subclass; the wiring lands in T2/T3)
6
+ * so a shape is declared ONCE.
7
+ *
8
+ * Everything here is additive and `.optional()` at the point of use: no
9
+ * `.default()`, no tightening, no new required field. A raw-blob leaf is always
10
+ * `z.unknown().optional()` — a bare `z.unknown()` inside `z.object` is NOT
11
+ * optional under zod v4 (`safeParse({})` fails `expected nonoptional`).
12
+ */
13
+ /** Images-ON emit (scripts/lib/image-format.ts): one wikilink string, or an array for ≥2 fluff
14
+ * images; `thumbnail` monster-only. ZERO carriers on the frozen images-OFF tree — see §9.4.
15
+ * NO .nonempty() on the array arm (gate1-r1 f13): the variant set is unestablished (Gate 0
16
+ * finding 25) and the phase's own rule — a new declaration must be INCAPABLE of refusing —
17
+ * outranks a speculative arity constraint on the one key a future convert:images run feeds. */
18
+ export declare const imageField: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
19
+ /** 5etools additionalSpells. Key-set measured COMPLETE over all 52 distinct sets on 5 roots:
20
+ * {ability, expanded, innate, known, name, prepared, resourceName} (Gate 0 finding 5).
21
+ * Loose leaves are deliberate: level keys are arbitrary strings ("1","s0","_","1e","pb","cha"…),
22
+ * the known.'1' string-keying is converter-owned (A §7.2) and passes through VERBATIM. */
23
+ export declare const additionalSpellsEntrySchema: z.ZodObject<{
24
+ name: z.ZodOptional<z.ZodString>;
25
+ ability: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
26
+ choose: z.ZodArray<z.ZodString>;
27
+ }, z.core.$strip>]>>;
28
+ known: z.ZodOptional<z.ZodUnknown>;
29
+ innate: z.ZodOptional<z.ZodUnknown>;
30
+ prepared: z.ZodOptional<z.ZodUnknown>;
31
+ expanded: z.ZodOptional<z.ZodUnknown>;
32
+ resourceName: z.ZodOptional<z.ZodString>;
33
+ }, z.core.$strip>;
34
+ /** optionalfeature_progression / feat_progression containers. Measured distribution (finding 4):
35
+ * `progression` is a record on 42 of 46 containers (keys numeric strings + "*", values number) and
36
+ * an ARRAY (number[], len 20) on class.optionalfeature_progression ONLY (4 docs: both PHB Warlocks,
37
+ * TCE + Eberron Artificer). `featureType` (camelCase) is the ONLY spelling on all 13 subclass
38
+ * optionalfeature_progression containers; `feature_type` (snake) on class/feat/optional-feature —
39
+ * true of their optionalfeature_progression containers; `class.feat_progression`'s 16 containers
40
+ * carry neither spelling; `required` on 2 subclass docs ({"3": ["Elemental Attunement|PHB"]}).
41
+ * Union order is SAFE
42
+ * (executed: record.safeParse(array) fails invalid_type). Distribution recorded in T0's census
43
+ * baseline — NO test asserts it; §9.3 characterises the SHAPES only. */
44
+ export declare const progressionSchema: z.ZodObject<{
45
+ name: z.ZodString;
46
+ progression: z.ZodUnion<readonly [z.ZodRecord<z.ZodString, z.ZodNumber>, z.ZodArray<z.ZodNumber>]>;
47
+ feature_type: z.ZodOptional<z.ZodArray<z.ZodString>>;
48
+ featureType: z.ZodOptional<z.ZodArray<z.ZodString>>;
49
+ category: z.ZodOptional<z.ZodArray<z.ZodString>>;
50
+ required: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
51
+ }, z.core.$strip>;
52
+ export type AdditionalSpellsEntry = z.infer<typeof additionalSpellsEntrySchema>;
53
+ export type ProgressionEntry = z.infer<typeof progressionSchema>;
@@ -0,0 +1,10 @@
1
+ import {
2
+ additionalSpellsEntrySchema,
3
+ imageField,
4
+ progressionSchema
5
+ } from "../chunk-UA5KS2PL.js";
6
+ export {
7
+ additionalSpellsEntrySchema,
8
+ imageField,
9
+ progressionSchema
10
+ };
@@ -1,5 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import type { EquipmentGrant, EquipmentOption, StartingEquipmentEntry, StartingGold } from "../types/equipment-grant.js";
3
+ /** Every arm stays `.strict()`: one stray key refuses the whole document on purpose (the builder's render path
4
+ * maps over grants). The three passthrough keys are DECLARED, not tolerated. */
3
5
  export declare const equipmentGrantSchema: z.ZodType<EquipmentGrant>;
4
6
  export declare const equipmentOptionSchema: z.ZodType<EquipmentOption>;
5
7
  export declare const startingEquipmentEntrySchema: z.ZodType<StartingEquipmentEntry>;
@@ -3,7 +3,7 @@ import {
3
3
  equipmentOptionSchema,
4
4
  startingEquipmentEntrySchema,
5
5
  startingGoldSchema
6
- } from "../chunk-3DZ74AKK.js";
6
+ } from "../chunk-IN4M4X7P.js";
7
7
  export {
8
8
  equipmentGrantSchema,
9
9
  equipmentOptionSchema,
@@ -0,0 +1,34 @@
1
+ /** R4-G3a §10.2.1: the SRD bundle spells a race trait's action cost `action_cost`; the canonical key is
2
+ * `action`. Alias fills a hole, declared wins, never deleted (the `armor.parser.ts` strength_required
3
+ * precedent; the resolver's optional-feature grant alias is the in-repo precedent for the KEY).
4
+ *
5
+ * No `package.json` exports entry, because the plugin never imports this module: the sheet's resolver
6
+ * applies the alias at resolve time through `withResolvedActionCost` (R4-G3a Task 12), and the ONE plugin
7
+ * site that reads a race trait's action cost off the RAW registry entity (the race block's tracker gate,
8
+ * R4-G3b §11) reads BOTH spellings with a nullish fallback rather than importing this helper. Not imported
9
+ * is NOT the same as parser-internal, and the module is not parser-internal: MEASURED 2026-09-04, every
10
+ * export here reaches the plugin's built `main.js`, `withResolvedActionCost` through `pc/pc.resolver.ts`
11
+ * and the raw-YAML aliasers through the race / class / subclass parsers, which the plugin pulls in with
12
+ * `dnd5ePack` (pack → entity types → codecs → parsers). What is parser-only is where the aliasers RUN:
13
+ * their three call sites are `race.parser.ts`, `class.parser.ts` and `subclass.parser.ts`, so they fire on
14
+ * the entity-note codec path and never on the sheet's, which reads RAW registry objects.
15
+ *
16
+ * This one is applied on the RAW YAML object before `safeParse`, so the aliased value goes through the
17
+ * same enum validation as a declared one (an out-of-vocabulary `action_cost` refuses the document rather
18
+ * than smuggling a bad `action` past the schema). */
19
+ export declare function aliasFeatureActionCost(f: Record<string, unknown>): void;
20
+ /** The list form: race `traits[]`, and one level's `features_by_level[lvl]` array. Non-arrays and
21
+ * non-object members are left alone; a malformed document is the schema's business, not ours. */
22
+ export declare function aliasFeatureListActionCost(list: unknown): void;
23
+ /** The `features_by_level` record form, shared by the class and subclass parsers. Zero bundle
24
+ * carriers live here today; it is aliased for symmetry so a future class-side `action_cost` is
25
+ * not a second silent routing bug. */
26
+ export declare function aliasFeaturesByLevelActionCost(byLevel: unknown): void;
27
+ /** Resolve-time mirror of `aliasFeatureActionCost` (R4-G3a Task 12): the PC sheet resolves RAW registry entities
28
+ * (never parsed by dnd5e), so the parser-side alias is invisible to it. Returns the same object when nothing applies
29
+ * (registry entities are shared and must not be mutated), else a shallow copy with `action` filled from
30
+ * `action_cost`. Declared `action` wins. */
31
+ export declare function withResolvedActionCost<T extends {
32
+ action?: unknown;
33
+ action_cost?: unknown;
34
+ }>(f: T): T;