@sharpee/lang-en-us 0.9.61-beta

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 (287) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +105 -0
  3. package/dist-npm/actions/about.d.ts +35 -0
  4. package/dist-npm/actions/about.d.ts.map +1 -0
  5. package/dist-npm/actions/about.js +50 -0
  6. package/dist-npm/actions/about.js.map +1 -0
  7. package/dist-npm/actions/again.d.ts +16 -0
  8. package/dist-npm/actions/again.d.ts.map +1 -0
  9. package/dist-npm/actions/again.js +23 -0
  10. package/dist-npm/actions/again.js.map +1 -0
  11. package/dist-npm/actions/answering.d.ts +29 -0
  12. package/dist-npm/actions/answering.d.ts.map +1 -0
  13. package/dist-npm/actions/answering.js +44 -0
  14. package/dist-npm/actions/answering.js.map +1 -0
  15. package/dist-npm/actions/asking.d.ts +31 -0
  16. package/dist-npm/actions/asking.d.ts.map +1 -0
  17. package/dist-npm/actions/asking.js +44 -0
  18. package/dist-npm/actions/asking.js.map +1 -0
  19. package/dist-npm/actions/attacking.d.ts +82 -0
  20. package/dist-npm/actions/attacking.d.ts.map +1 -0
  21. package/dist-npm/actions/attacking.js +111 -0
  22. package/dist-npm/actions/attacking.js.map +1 -0
  23. package/dist-npm/actions/climbing.d.ts +27 -0
  24. package/dist-npm/actions/climbing.d.ts.map +1 -0
  25. package/dist-npm/actions/climbing.js +48 -0
  26. package/dist-npm/actions/climbing.js.map +1 -0
  27. package/dist-npm/actions/closing.d.ts +21 -0
  28. package/dist-npm/actions/closing.d.ts.map +1 -0
  29. package/dist-npm/actions/closing.js +27 -0
  30. package/dist-npm/actions/closing.js.map +1 -0
  31. package/dist-npm/actions/drinking.d.ts +40 -0
  32. package/dist-npm/actions/drinking.d.ts.map +1 -0
  33. package/dist-npm/actions/drinking.js +57 -0
  34. package/dist-npm/actions/drinking.js.map +1 -0
  35. package/dist-npm/actions/dropping.d.ts +22 -0
  36. package/dist-npm/actions/dropping.d.ts.map +1 -0
  37. package/dist-npm/actions/dropping.js +31 -0
  38. package/dist-npm/actions/dropping.js.map +1 -0
  39. package/dist-npm/actions/eating.d.ts +37 -0
  40. package/dist-npm/actions/eating.d.ts.map +1 -0
  41. package/dist-npm/actions/eating.js +54 -0
  42. package/dist-npm/actions/eating.js.map +1 -0
  43. package/dist-npm/actions/entering.d.ts +26 -0
  44. package/dist-npm/actions/entering.d.ts.map +1 -0
  45. package/dist-npm/actions/entering.js +49 -0
  46. package/dist-npm/actions/entering.js.map +1 -0
  47. package/dist-npm/actions/examining.d.ts +37 -0
  48. package/dist-npm/actions/examining.d.ts.map +1 -0
  49. package/dist-npm/actions/examining.js +50 -0
  50. package/dist-npm/actions/examining.js.map +1 -0
  51. package/dist-npm/actions/exiting.d.ts +23 -0
  52. package/dist-npm/actions/exiting.d.ts.map +1 -0
  53. package/dist-npm/actions/exiting.js +40 -0
  54. package/dist-npm/actions/exiting.js.map +1 -0
  55. package/dist-npm/actions/giving.d.ts +30 -0
  56. package/dist-npm/actions/giving.d.ts.map +1 -0
  57. package/dist-npm/actions/giving.js +45 -0
  58. package/dist-npm/actions/giving.js.map +1 -0
  59. package/dist-npm/actions/going.d.ts +35 -0
  60. package/dist-npm/actions/going.d.ts.map +1 -0
  61. package/dist-npm/actions/going.js +45 -0
  62. package/dist-npm/actions/going.js.map +1 -0
  63. package/dist-npm/actions/help.d.ts +26 -0
  64. package/dist-npm/actions/help.d.ts.map +1 -0
  65. package/dist-npm/actions/help.js +44 -0
  66. package/dist-npm/actions/help.js.map +1 -0
  67. package/dist-npm/actions/index.d.ts +1327 -0
  68. package/dist-npm/actions/index.d.ts.map +1 -0
  69. package/dist-npm/actions/index.js +208 -0
  70. package/dist-npm/actions/index.js.map +1 -0
  71. package/dist-npm/actions/inserting.d.ts +25 -0
  72. package/dist-npm/actions/inserting.d.ts.map +1 -0
  73. package/dist-npm/actions/inserting.js +33 -0
  74. package/dist-npm/actions/inserting.js.map +1 -0
  75. package/dist-npm/actions/inventory.d.ts +32 -0
  76. package/dist-npm/actions/inventory.d.ts.map +1 -0
  77. package/dist-npm/actions/inventory.js +41 -0
  78. package/dist-npm/actions/inventory.js.map +1 -0
  79. package/dist-npm/actions/listening.d.ts +26 -0
  80. package/dist-npm/actions/listening.d.ts.map +1 -0
  81. package/dist-npm/actions/listening.js +37 -0
  82. package/dist-npm/actions/listening.js.map +1 -0
  83. package/dist-npm/actions/locking.d.ts +25 -0
  84. package/dist-npm/actions/locking.d.ts.map +1 -0
  85. package/dist-npm/actions/locking.js +33 -0
  86. package/dist-npm/actions/locking.js.map +1 -0
  87. package/dist-npm/actions/looking.d.ts +23 -0
  88. package/dist-npm/actions/looking.d.ts.map +1 -0
  89. package/dist-npm/actions/looking.js +34 -0
  90. package/dist-npm/actions/looking.js.map +1 -0
  91. package/dist-npm/actions/lowering.d.ts +22 -0
  92. package/dist-npm/actions/lowering.d.ts.map +1 -0
  93. package/dist-npm/actions/lowering.js +29 -0
  94. package/dist-npm/actions/lowering.js.map +1 -0
  95. package/dist-npm/actions/opening.d.ts +23 -0
  96. package/dist-npm/actions/opening.d.ts.map +1 -0
  97. package/dist-npm/actions/opening.js +30 -0
  98. package/dist-npm/actions/opening.js.map +1 -0
  99. package/dist-npm/actions/pulling.d.ts +35 -0
  100. package/dist-npm/actions/pulling.d.ts.map +1 -0
  101. package/dist-npm/actions/pulling.js +53 -0
  102. package/dist-npm/actions/pulling.js.map +1 -0
  103. package/dist-npm/actions/pushing.d.ts +30 -0
  104. package/dist-npm/actions/pushing.d.ts.map +1 -0
  105. package/dist-npm/actions/pushing.js +45 -0
  106. package/dist-npm/actions/pushing.js.map +1 -0
  107. package/dist-npm/actions/putting.d.ts +28 -0
  108. package/dist-npm/actions/putting.d.ts.map +1 -0
  109. package/dist-npm/actions/putting.js +40 -0
  110. package/dist-npm/actions/putting.js.map +1 -0
  111. package/dist-npm/actions/quitting.d.ts +31 -0
  112. package/dist-npm/actions/quitting.d.ts.map +1 -0
  113. package/dist-npm/actions/quitting.js +47 -0
  114. package/dist-npm/actions/quitting.js.map +1 -0
  115. package/dist-npm/actions/raising.d.ts +22 -0
  116. package/dist-npm/actions/raising.d.ts.map +1 -0
  117. package/dist-npm/actions/raising.js +30 -0
  118. package/dist-npm/actions/raising.js.map +1 -0
  119. package/dist-npm/actions/reading.d.ts +23 -0
  120. package/dist-npm/actions/reading.d.ts.map +1 -0
  121. package/dist-npm/actions/reading.js +32 -0
  122. package/dist-npm/actions/reading.js.map +1 -0
  123. package/dist-npm/actions/removing.d.ts +25 -0
  124. package/dist-npm/actions/removing.d.ts.map +1 -0
  125. package/dist-npm/actions/removing.js +34 -0
  126. package/dist-npm/actions/removing.js.map +1 -0
  127. package/dist-npm/actions/restoring.d.ts +35 -0
  128. package/dist-npm/actions/restoring.d.ts.map +1 -0
  129. package/dist-npm/actions/restoring.js +51 -0
  130. package/dist-npm/actions/restoring.js.map +1 -0
  131. package/dist-npm/actions/saving.d.ts +33 -0
  132. package/dist-npm/actions/saving.d.ts.map +1 -0
  133. package/dist-npm/actions/saving.js +48 -0
  134. package/dist-npm/actions/saving.js.map +1 -0
  135. package/dist-npm/actions/scoring.d.ts +42 -0
  136. package/dist-npm/actions/scoring.d.ts.map +1 -0
  137. package/dist-npm/actions/scoring.js +70 -0
  138. package/dist-npm/actions/scoring.js.map +1 -0
  139. package/dist-npm/actions/searching.d.ts +26 -0
  140. package/dist-npm/actions/searching.d.ts.map +1 -0
  141. package/dist-npm/actions/searching.js +40 -0
  142. package/dist-npm/actions/searching.js.map +1 -0
  143. package/dist-npm/actions/showing.d.ts +29 -0
  144. package/dist-npm/actions/showing.d.ts.map +1 -0
  145. package/dist-npm/actions/showing.js +40 -0
  146. package/dist-npm/actions/showing.js.map +1 -0
  147. package/dist-npm/actions/sleeping.d.ts +28 -0
  148. package/dist-npm/actions/sleeping.d.ts.map +1 -0
  149. package/dist-npm/actions/sleeping.js +41 -0
  150. package/dist-npm/actions/sleeping.js.map +1 -0
  151. package/dist-npm/actions/smelling.d.ts +30 -0
  152. package/dist-npm/actions/smelling.d.ts.map +1 -0
  153. package/dist-npm/actions/smelling.js +43 -0
  154. package/dist-npm/actions/smelling.js.map +1 -0
  155. package/dist-npm/actions/switching-off.d.ts +28 -0
  156. package/dist-npm/actions/switching-off.d.ts.map +1 -0
  157. package/dist-npm/actions/switching-off.js +42 -0
  158. package/dist-npm/actions/switching-off.js.map +1 -0
  159. package/dist-npm/actions/switching-on.d.ts +28 -0
  160. package/dist-npm/actions/switching-on.d.ts.map +1 -0
  161. package/dist-npm/actions/switching-on.js +42 -0
  162. package/dist-npm/actions/switching-on.js.map +1 -0
  163. package/dist-npm/actions/taking-off.d.ts +20 -0
  164. package/dist-npm/actions/taking-off.d.ts.map +1 -0
  165. package/dist-npm/actions/taking-off.js +28 -0
  166. package/dist-npm/actions/taking-off.js.map +1 -0
  167. package/dist-npm/actions/taking.d.ts +26 -0
  168. package/dist-npm/actions/taking.d.ts.map +1 -0
  169. package/dist-npm/actions/taking.js +36 -0
  170. package/dist-npm/actions/taking.js.map +1 -0
  171. package/dist-npm/actions/talking.d.ts +33 -0
  172. package/dist-npm/actions/talking.d.ts.map +1 -0
  173. package/dist-npm/actions/talking.js +49 -0
  174. package/dist-npm/actions/talking.js.map +1 -0
  175. package/dist-npm/actions/telling.d.ts +30 -0
  176. package/dist-npm/actions/telling.d.ts.map +1 -0
  177. package/dist-npm/actions/telling.js +42 -0
  178. package/dist-npm/actions/telling.js.map +1 -0
  179. package/dist-npm/actions/throwing.d.ts +39 -0
  180. package/dist-npm/actions/throwing.d.ts.map +1 -0
  181. package/dist-npm/actions/throwing.js +60 -0
  182. package/dist-npm/actions/throwing.js.map +1 -0
  183. package/dist-npm/actions/touching.d.ts +36 -0
  184. package/dist-npm/actions/touching.d.ts.map +1 -0
  185. package/dist-npm/actions/touching.js +50 -0
  186. package/dist-npm/actions/touching.js.map +1 -0
  187. package/dist-npm/actions/turning.d.ts +40 -0
  188. package/dist-npm/actions/turning.d.ts.map +1 -0
  189. package/dist-npm/actions/turning.js +62 -0
  190. package/dist-npm/actions/turning.js.map +1 -0
  191. package/dist-npm/actions/undoing.d.ts +19 -0
  192. package/dist-npm/actions/undoing.d.ts.map +1 -0
  193. package/dist-npm/actions/undoing.js +26 -0
  194. package/dist-npm/actions/undoing.js.map +1 -0
  195. package/dist-npm/actions/unlocking.d.ts +25 -0
  196. package/dist-npm/actions/unlocking.d.ts.map +1 -0
  197. package/dist-npm/actions/unlocking.js +32 -0
  198. package/dist-npm/actions/unlocking.js.map +1 -0
  199. package/dist-npm/actions/using.d.ts +43 -0
  200. package/dist-npm/actions/using.d.ts.map +1 -0
  201. package/dist-npm/actions/using.js +61 -0
  202. package/dist-npm/actions/using.js.map +1 -0
  203. package/dist-npm/actions/version.d.ts +18 -0
  204. package/dist-npm/actions/version.d.ts.map +1 -0
  205. package/dist-npm/actions/version.js +26 -0
  206. package/dist-npm/actions/version.js.map +1 -0
  207. package/dist-npm/actions/waiting.d.ts +27 -0
  208. package/dist-npm/actions/waiting.d.ts.map +1 -0
  209. package/dist-npm/actions/waiting.js +36 -0
  210. package/dist-npm/actions/waiting.js.map +1 -0
  211. package/dist-npm/actions/wearing.d.ts +22 -0
  212. package/dist-npm/actions/wearing.d.ts.map +1 -0
  213. package/dist-npm/actions/wearing.js +30 -0
  214. package/dist-npm/actions/wearing.js.map +1 -0
  215. package/dist-npm/data/events.d.ts +134 -0
  216. package/dist-npm/data/events.d.ts.map +1 -0
  217. package/dist-npm/data/events.js +301 -0
  218. package/dist-npm/data/events.js.map +1 -0
  219. package/dist-npm/data/messages.d.ts +141 -0
  220. package/dist-npm/data/messages.d.ts.map +1 -0
  221. package/dist-npm/data/messages.js +300 -0
  222. package/dist-npm/data/messages.js.map +1 -0
  223. package/dist-npm/data/templates.d.ts +257 -0
  224. package/dist-npm/data/templates.d.ts.map +1 -0
  225. package/dist-npm/data/templates.js +289 -0
  226. package/dist-npm/data/templates.js.map +1 -0
  227. package/dist-npm/data/verbs.d.ts +68 -0
  228. package/dist-npm/data/verbs.d.ts.map +1 -0
  229. package/dist-npm/data/verbs.js +324 -0
  230. package/dist-npm/data/verbs.js.map +1 -0
  231. package/dist-npm/data/words.d.ts +79 -0
  232. package/dist-npm/data/words.d.ts.map +1 -0
  233. package/dist-npm/data/words.js +218 -0
  234. package/dist-npm/data/words.js.map +1 -0
  235. package/dist-npm/formatters/article.d.ts +41 -0
  236. package/dist-npm/formatters/article.d.ts.map +1 -0
  237. package/dist-npm/formatters/article.js +143 -0
  238. package/dist-npm/formatters/article.js.map +1 -0
  239. package/dist-npm/formatters/index.d.ts +18 -0
  240. package/dist-npm/formatters/index.d.ts.map +1 -0
  241. package/dist-npm/formatters/index.js +38 -0
  242. package/dist-npm/formatters/index.js.map +1 -0
  243. package/dist-npm/formatters/list.d.ts +38 -0
  244. package/dist-npm/formatters/list.d.ts.map +1 -0
  245. package/dist-npm/formatters/list.js +94 -0
  246. package/dist-npm/formatters/list.js.map +1 -0
  247. package/dist-npm/formatters/registry.d.ts +48 -0
  248. package/dist-npm/formatters/registry.d.ts.map +1 -0
  249. package/dist-npm/formatters/registry.js +128 -0
  250. package/dist-npm/formatters/registry.js.map +1 -0
  251. package/dist-npm/formatters/text.d.ts +33 -0
  252. package/dist-npm/formatters/text.d.ts.map +1 -0
  253. package/dist-npm/formatters/text.js +80 -0
  254. package/dist-npm/formatters/text.js.map +1 -0
  255. package/dist-npm/formatters/types.d.ts +41 -0
  256. package/dist-npm/formatters/types.d.ts.map +1 -0
  257. package/dist-npm/formatters/types.js +14 -0
  258. package/dist-npm/formatters/types.js.map +1 -0
  259. package/dist-npm/grammar.d.ts +189 -0
  260. package/dist-npm/grammar.d.ts.map +1 -0
  261. package/dist-npm/grammar.js +203 -0
  262. package/dist-npm/grammar.js.map +1 -0
  263. package/dist-npm/index.d.ts +22 -0
  264. package/dist-npm/index.d.ts.map +1 -0
  265. package/dist-npm/index.js +59 -0
  266. package/dist-npm/index.js.map +1 -0
  267. package/dist-npm/language-provider.d.ts +159 -0
  268. package/dist-npm/language-provider.d.ts.map +1 -0
  269. package/dist-npm/language-provider.js +527 -0
  270. package/dist-npm/language-provider.js.map +1 -0
  271. package/dist-npm/npc/index.d.ts +5 -0
  272. package/dist-npm/npc/index.d.ts.map +1 -0
  273. package/dist-npm/npc/index.js +21 -0
  274. package/dist-npm/npc/index.js.map +1 -0
  275. package/dist-npm/npc/npc.d.ts +43 -0
  276. package/dist-npm/npc/npc.d.ts.map +1 -0
  277. package/dist-npm/npc/npc.js +55 -0
  278. package/dist-npm/npc/npc.js.map +1 -0
  279. package/dist-npm/perspective/index.d.ts +5 -0
  280. package/dist-npm/perspective/index.d.ts.map +1 -0
  281. package/dist-npm/perspective/index.js +12 -0
  282. package/dist-npm/perspective/index.js.map +1 -0
  283. package/dist-npm/perspective/placeholder-resolver.d.ts +102 -0
  284. package/dist-npm/perspective/placeholder-resolver.d.ts.map +1 -0
  285. package/dist-npm/perspective/placeholder-resolver.js +275 -0
  286. package/dist-npm/perspective/placeholder-resolver.js.map +1 -0
  287. package/package.json +65 -0
@@ -0,0 +1,159 @@
1
+ /**
2
+ * English Language Provider
3
+ *
4
+ * Self-contained language implementation with no external dependencies
5
+ * Enhanced to support getMessage interface for text service
6
+ */
7
+ import { ParserLanguageProvider, ActionHelp, VerbVocabulary, DirectionVocabulary, SpecialVocabulary, LanguageGrammarPattern } from '@sharpee/if-domain';
8
+ import { NarrativeContext } from './perspective';
9
+ import { FormatterRegistry, FormatterContext, EntityInfo } from './formatters';
10
+ /**
11
+ * English language data and rules
12
+ */
13
+ export declare class EnglishLanguageProvider implements ParserLanguageProvider {
14
+ readonly languageCode = "en-US";
15
+ readonly languageName = "English (US)";
16
+ readonly textDirection: "ltr";
17
+ private messages;
18
+ private customActionPatterns;
19
+ private narrativeContext;
20
+ private formatterRegistry;
21
+ private entityLookup?;
22
+ constructor();
23
+ /**
24
+ * Load core system messages (command failures, etc.)
25
+ * These are used by text-service for command.failed events
26
+ */
27
+ private loadCoreMessages;
28
+ /**
29
+ * Set narrative settings for perspective-aware message resolution (ADR-089)
30
+ *
31
+ * This should be called by the engine after loading a story to configure
32
+ * how {You}, {your}, {take} placeholders are resolved.
33
+ *
34
+ * @param settings Narrative settings from story config
35
+ */
36
+ setNarrativeSettings(settings: NarrativeContext): void;
37
+ /**
38
+ * Get current narrative context
39
+ */
40
+ getNarrativeContext(): NarrativeContext;
41
+ /**
42
+ * Load messages from all action language definitions
43
+ */
44
+ private loadActionMessages;
45
+ /**
46
+ * Load NPC messages (ADR-070)
47
+ */
48
+ private loadNpcMessages;
49
+ /**
50
+ * Get a message by its ID with optional parameter substitution
51
+ *
52
+ * Supports three types of placeholders:
53
+ * 1. Perspective placeholders (ADR-089): {You}, {your}, {take}, etc.
54
+ * - Resolved based on narrative context (1st/2nd/3rd person)
55
+ * 2. Formatted placeholders (ADR-095): {a:item}, {items:list}, etc.
56
+ * - Applies formatters before substitution
57
+ * 3. Simple placeholders: {item}, {target}, etc.
58
+ * - Replaced with values from params object
59
+ *
60
+ * @param messageId Full message ID (e.g., 'if.action.taking.taken')
61
+ * @param params Parameters to substitute in the message
62
+ * @returns The resolved message text, or null if not found
63
+ */
64
+ getMessage(messageId: string, params?: Record<string, any>): string;
65
+ /**
66
+ * Set entity lookup function for formatters (ADR-095)
67
+ *
68
+ * This allows formatters to look up entity info (nounType, etc.)
69
+ * for proper article selection.
70
+ *
71
+ * @param lookup Function that returns EntityInfo for an entity ID
72
+ */
73
+ setEntityLookup(lookup: (id: string) => EntityInfo | undefined): void;
74
+ /**
75
+ * Register a custom formatter (ADR-095)
76
+ *
77
+ * Stories can register custom formatters for special formatting needs.
78
+ *
79
+ * @param name Formatter name (used in templates as {name:placeholder})
80
+ * @param formatter Formatter function
81
+ */
82
+ registerFormatter(name: string, formatter: (value: any, context: FormatterContext) => string): void;
83
+ /**
84
+ * Get the formatter registry (for testing or advanced use)
85
+ */
86
+ getFormatterRegistry(): FormatterRegistry;
87
+ /**
88
+ * Check if a message exists
89
+ * @param messageId The message identifier
90
+ * @returns True if the message exists
91
+ */
92
+ hasMessage(messageId: string): boolean;
93
+ /**
94
+ * Get patterns/aliases for an action
95
+ * @param actionId The action identifier (e.g., 'if.action.taking')
96
+ * @returns Array of patterns or undefined if action not found
97
+ */
98
+ getActionPatterns(actionId: string): string[] | undefined;
99
+ /**
100
+ * Get structured help information for an action
101
+ * @param actionId The action identifier (e.g., 'if.action.taking')
102
+ * @returns Structured help information or undefined if not found
103
+ */
104
+ getActionHelp(actionId: string): ActionHelp | undefined;
105
+ /**
106
+ * Get all supported actions
107
+ * @returns Array of action IDs
108
+ */
109
+ getSupportedActions(): string[];
110
+ /**
111
+ * Get entity name/description
112
+ * @param entity Entity object or ID
113
+ * @returns Entity name or fallback
114
+ */
115
+ getEntityName(entity: any): string;
116
+ /**
117
+ * Get all messages for a given action
118
+ * @param actionId Action identifier
119
+ * @returns Map of message keys to messages
120
+ */
121
+ getActionMessages(actionId: string): Map<string, string> | null;
122
+ getVerbs(): VerbVocabulary[];
123
+ getDirections(): DirectionVocabulary[];
124
+ getSpecialVocabulary(): SpecialVocabulary;
125
+ getCommonAdjectives(): string[];
126
+ getCommonNouns(): string[];
127
+ getPrepositions(): string[];
128
+ getDeterminers(): string[];
129
+ getConjunctions(): string[];
130
+ getNumbers(): string[];
131
+ getGrammarPatterns(): LanguageGrammarPattern[];
132
+ lemmatize(word: string): string;
133
+ expandAbbreviation(abbreviation: string): string | null;
134
+ formatList(items: string[], conjunction?: 'and' | 'or'): string;
135
+ getIndefiniteArticle(noun: string): string;
136
+ pluralize(noun: string): string;
137
+ isIgnoreWord(word: string): boolean;
138
+ /**
139
+ * Add a custom message to the language provider
140
+ * @param messageId The message identifier (e.g., 'custom.action.message')
141
+ * @param template The message template with optional {param} placeholders
142
+ */
143
+ addMessage(messageId: string, template: string): void;
144
+ /**
145
+ * Add help information for a custom action
146
+ * @param actionId The action identifier (e.g., 'custom.action.foo')
147
+ * @param help The help information including usage, description, examples
148
+ */
149
+ addActionHelp(actionId: string, help: ActionHelp): void;
150
+ /**
151
+ * Add custom patterns/aliases for an action
152
+ * @param actionId The action identifier
153
+ * @param patterns Array of verb patterns/aliases
154
+ */
155
+ addActionPatterns(actionId: string, patterns: string[]): void;
156
+ }
157
+ declare const _default: EnglishLanguageProvider;
158
+ export default _default;
159
+ //# sourceMappingURL=language-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"language-provider.d.ts","sourceRoot":"","sources":["../src/language-provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAoB,sBAAsB,EAAE,UAAU,EAAE,cAAc,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAK1K,OAAO,EACL,gBAAgB,EAGjB,MAAM,eAAe,CAAC;AACvB,OAAO,EAGL,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACX,MAAM,cAAc,CAAC;AAItB;;GAEG;AACH,qBAAa,uBAAwB,YAAW,sBAAsB;IACpE,QAAQ,CAAC,YAAY,WAAW;IAChC,QAAQ,CAAC,YAAY,kBAAkB;IACvC,QAAQ,CAAC,aAAa,EAAG,KAAK,CAAU;IAGxC,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,oBAAoB,CAA+B;IAG3D,OAAO,CAAC,gBAAgB,CAA+C;IAGvE,OAAO,CAAC,iBAAiB,CAAoB;IAG7C,OAAO,CAAC,YAAY,CAAC,CAAyC;;IAa9D;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAgBxB;;;;;;;OAOG;IACH,oBAAoB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI;IAItD;;OAEG;IACH,mBAAmB,IAAI,gBAAgB;IAIvC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAY1B;;OAEG;IACH,OAAO,CAAC,eAAe;IAQvB;;;;;;;;;;;;;;OAcG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM;IAsBnE;;;;;;;OAOG;IACH,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,UAAU,GAAG,SAAS,GAAG,IAAI;IAIrE;;;;;;;OAOG;IACH,iBAAiB,CACf,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB,KAAK,MAAM,GAC3D,IAAI;IAIP;;OAEG;IACH,oBAAoB,IAAI,iBAAiB;IAIzC;;;;OAIG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAItC;;;;OAIG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS;IAgBzD;;;;OAIG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAqCvD;;;OAGG;IACH,mBAAmB,IAAI,MAAM,EAAE;IAI/B;;;;OAIG;IACH,aAAa,CAAC,MAAM,EAAE,GAAG,GAAG,MAAM;IAqClC;;;;OAIG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAe/D,QAAQ,IAAI,cAAc,EAAE;IAW5B,aAAa,IAAI,mBAAmB,EAAE;IAiBtC,oBAAoB,IAAI,iBAAiB;IASzC,mBAAmB,IAAI,MAAM,EAAE;IAI/B,cAAc,IAAI,MAAM,EAAE;IAI1B,eAAe,IAAI,MAAM,EAAE;IAI3B,cAAc,IAAI,MAAM,EAAE;IAI1B,eAAe,IAAI,MAAM,EAAE;IAI3B,UAAU,IAAI,MAAM,EAAE;IAItB,kBAAkB,IAAI,sBAAsB,EAAE;IAmC9C,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAsC/B,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIvD,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,WAAW,GAAE,KAAK,GAAG,IAAY,GAAG,MAAM;IAUtE,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAe1C,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IA2C/B,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAInC;;;;OAIG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAIrD;;;;OAIG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI;IAiBvD;;;;OAIG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI;CAe9D;;AAGD,wBAA6C"}
@@ -0,0 +1,527 @@
1
+ "use strict";
2
+ /**
3
+ * English Language Provider
4
+ *
5
+ * Self-contained language implementation with no external dependencies
6
+ * Enhanced to support getMessage interface for text service
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.EnglishLanguageProvider = void 0;
10
+ const verbs_1 = require("./data/verbs");
11
+ const words_1 = require("./data/words");
12
+ const actions_1 = require("./actions");
13
+ const npc_1 = require("./npc");
14
+ const perspective_1 = require("./perspective");
15
+ const formatters_1 = require("./formatters");
16
+ // Types are now imported from @sharpee/if-domain
17
+ /**
18
+ * English language data and rules
19
+ */
20
+ class EnglishLanguageProvider {
21
+ languageCode = 'en-US';
22
+ languageName = 'English (US)';
23
+ textDirection = 'ltr';
24
+ // Message storage
25
+ messages = new Map();
26
+ customActionPatterns = new Map();
27
+ // Narrative context for perspective-aware message resolution (ADR-089)
28
+ narrativeContext = perspective_1.DEFAULT_NARRATIVE_CONTEXT;
29
+ // Formatter registry for {a:item}, {items:list}, etc. (ADR-095)
30
+ formatterRegistry;
31
+ // Entity lookup function for formatters (set by engine)
32
+ entityLookup;
33
+ constructor() {
34
+ // Initialize formatter registry
35
+ this.formatterRegistry = (0, formatters_1.createFormatterRegistry)();
36
+ // Load core system messages
37
+ this.loadCoreMessages();
38
+ // Load all action messages
39
+ this.loadActionMessages();
40
+ // Load NPC messages (ADR-070)
41
+ this.loadNpcMessages();
42
+ }
43
+ /**
44
+ * Load core system messages (command failures, etc.)
45
+ * These are used by text-service for command.failed events
46
+ */
47
+ loadCoreMessages() {
48
+ const coreMessages = {
49
+ 'core.entity_not_found': "You can't see any such thing.",
50
+ 'core.ambiguous_reference': "Which do you mean?",
51
+ 'core.disambiguation_prompt': "Which do you mean: {options}?",
52
+ 'core.command_not_understood': "I don't understand that command.",
53
+ 'core.command_failed': "I don't understand that.",
54
+ // Game lifecycle messages
55
+ 'game.started.banner': "{title}\nBy {author}\n\nType HELP for instructions.",
56
+ };
57
+ for (const [key, value] of Object.entries(coreMessages)) {
58
+ this.messages.set(key, value);
59
+ }
60
+ }
61
+ /**
62
+ * Set narrative settings for perspective-aware message resolution (ADR-089)
63
+ *
64
+ * This should be called by the engine after loading a story to configure
65
+ * how {You}, {your}, {take} placeholders are resolved.
66
+ *
67
+ * @param settings Narrative settings from story config
68
+ */
69
+ setNarrativeSettings(settings) {
70
+ this.narrativeContext = settings;
71
+ }
72
+ /**
73
+ * Get current narrative context
74
+ */
75
+ getNarrativeContext() {
76
+ return this.narrativeContext;
77
+ }
78
+ /**
79
+ * Load messages from all action language definitions
80
+ */
81
+ loadActionMessages() {
82
+ for (const actionLang of actions_1.standardActionLanguage) {
83
+ if (actionLang.messages) {
84
+ Object.entries(actionLang.messages).forEach(([key, value]) => {
85
+ // Store with full action ID prefix
86
+ const fullKey = `${actionLang.actionId}.${key}`;
87
+ this.messages.set(fullKey, value);
88
+ });
89
+ }
90
+ }
91
+ }
92
+ /**
93
+ * Load NPC messages (ADR-070)
94
+ */
95
+ loadNpcMessages() {
96
+ if (npc_1.npcLanguage.messages) {
97
+ for (const [key, value] of Object.entries(npc_1.npcLanguage.messages)) {
98
+ this.messages.set(key, value);
99
+ }
100
+ }
101
+ }
102
+ /**
103
+ * Get a message by its ID with optional parameter substitution
104
+ *
105
+ * Supports three types of placeholders:
106
+ * 1. Perspective placeholders (ADR-089): {You}, {your}, {take}, etc.
107
+ * - Resolved based on narrative context (1st/2nd/3rd person)
108
+ * 2. Formatted placeholders (ADR-095): {a:item}, {items:list}, etc.
109
+ * - Applies formatters before substitution
110
+ * 3. Simple placeholders: {item}, {target}, etc.
111
+ * - Replaced with values from params object
112
+ *
113
+ * @param messageId Full message ID (e.g., 'if.action.taking.taken')
114
+ * @param params Parameters to substitute in the message
115
+ * @returns The resolved message text, or null if not found
116
+ */
117
+ getMessage(messageId, params) {
118
+ let message = this.messages.get(messageId);
119
+ if (!message) {
120
+ return messageId; // Return the ID as fallback
121
+ }
122
+ // Step 1: Resolve perspective placeholders (ADR-089)
123
+ // This handles {You}, {your}, {take}, etc.
124
+ message = (0, perspective_1.resolvePerspectivePlaceholders)(message, this.narrativeContext);
125
+ // Step 2: Apply formatters and substitute parameters (ADR-095)
126
+ if (params) {
127
+ const context = {
128
+ getEntity: this.entityLookup,
129
+ };
130
+ message = (0, formatters_1.formatMessage)(message, params, this.formatterRegistry, context);
131
+ }
132
+ return message;
133
+ }
134
+ /**
135
+ * Set entity lookup function for formatters (ADR-095)
136
+ *
137
+ * This allows formatters to look up entity info (nounType, etc.)
138
+ * for proper article selection.
139
+ *
140
+ * @param lookup Function that returns EntityInfo for an entity ID
141
+ */
142
+ setEntityLookup(lookup) {
143
+ this.entityLookup = lookup;
144
+ }
145
+ /**
146
+ * Register a custom formatter (ADR-095)
147
+ *
148
+ * Stories can register custom formatters for special formatting needs.
149
+ *
150
+ * @param name Formatter name (used in templates as {name:placeholder})
151
+ * @param formatter Formatter function
152
+ */
153
+ registerFormatter(name, formatter) {
154
+ this.formatterRegistry.set(name, formatter);
155
+ }
156
+ /**
157
+ * Get the formatter registry (for testing or advanced use)
158
+ */
159
+ getFormatterRegistry() {
160
+ return this.formatterRegistry;
161
+ }
162
+ /**
163
+ * Check if a message exists
164
+ * @param messageId The message identifier
165
+ * @returns True if the message exists
166
+ */
167
+ hasMessage(messageId) {
168
+ return this.messages.has(messageId);
169
+ }
170
+ /**
171
+ * Get patterns/aliases for an action
172
+ * @param actionId The action identifier (e.g., 'if.action.taking')
173
+ * @returns Array of patterns or undefined if action not found
174
+ */
175
+ getActionPatterns(actionId) {
176
+ // First check custom patterns
177
+ const customPatterns = this.customActionPatterns.get(actionId);
178
+ // Then check standard action language
179
+ const actionLang = actions_1.standardActionLanguage.find(lang => lang.actionId === actionId);
180
+ const standardPatterns = actionLang?.patterns;
181
+ // Merge both sources if they exist
182
+ if (customPatterns && standardPatterns) {
183
+ return [...standardPatterns, ...customPatterns];
184
+ }
185
+ return customPatterns || standardPatterns;
186
+ }
187
+ /**
188
+ * Get structured help information for an action
189
+ * @param actionId The action identifier (e.g., 'if.action.taking')
190
+ * @returns Structured help information or undefined if not found
191
+ */
192
+ getActionHelp(actionId) {
193
+ const actionLang = actions_1.standardActionLanguage.find(lang => lang.actionId === actionId);
194
+ if (!actionLang) {
195
+ return undefined;
196
+ }
197
+ // Extract verbs from patterns
198
+ const verbs = [];
199
+ if (actionLang.patterns) {
200
+ actionLang.patterns.forEach(pattern => {
201
+ // Extract the verb from patterns like "take [something]"
202
+ const match = pattern.match(/^(\w+)/);
203
+ if (match) {
204
+ const verb = match[1].toUpperCase();
205
+ if (!verbs.includes(verb)) {
206
+ verbs.push(verb);
207
+ }
208
+ }
209
+ });
210
+ }
211
+ // Parse examples from help object
212
+ let examples = [];
213
+ if (actionLang.help?.examples) {
214
+ // Split by comma and trim
215
+ examples = actionLang.help.examples.split(',').map(ex => ex.trim());
216
+ }
217
+ return {
218
+ description: actionLang.help?.description || 'No description available.',
219
+ verbs,
220
+ examples,
221
+ summary: actionLang.help?.summary
222
+ };
223
+ }
224
+ /**
225
+ * Get all supported actions
226
+ * @returns Array of action IDs
227
+ */
228
+ getSupportedActions() {
229
+ return actions_1.standardActionLanguage.map(lang => lang.actionId);
230
+ }
231
+ /**
232
+ * Get entity name/description
233
+ * @param entity Entity object or ID
234
+ * @returns Entity name or fallback
235
+ */
236
+ getEntityName(entity) {
237
+ if (!entity)
238
+ return 'something';
239
+ // If it's a string, return it
240
+ if (typeof entity === 'string') {
241
+ return entity;
242
+ }
243
+ // Try various properties
244
+ if (entity.name) {
245
+ return entity.name;
246
+ }
247
+ // Try identity trait
248
+ if (entity.traits && entity.traits.get) {
249
+ const identity = entity.traits.get('IDENTITY');
250
+ if (identity && identity.name) {
251
+ return identity.name;
252
+ }
253
+ }
254
+ // Try direct trait access
255
+ if (entity.get && typeof entity.get === 'function') {
256
+ const identity = entity.get('IDENTITY');
257
+ if (identity && identity.name) {
258
+ return identity.name;
259
+ }
260
+ }
261
+ // Fall back to ID
262
+ if (entity.id) {
263
+ return entity.id;
264
+ }
265
+ return 'something';
266
+ }
267
+ /**
268
+ * Get all messages for a given action
269
+ * @param actionId Action identifier
270
+ * @returns Map of message keys to messages
271
+ */
272
+ getActionMessages(actionId) {
273
+ const actionMessages = new Map();
274
+ const prefix = `${actionId}.`;
275
+ // Find all messages for this action
276
+ for (const [key, value] of this.messages) {
277
+ if (key.startsWith(prefix)) {
278
+ const messageKey = key.substring(prefix.length);
279
+ actionMessages.set(messageKey, value);
280
+ }
281
+ }
282
+ return actionMessages.size > 0 ? actionMessages : null;
283
+ }
284
+ getVerbs() {
285
+ return verbs_1.englishVerbs.map(verb => ({
286
+ actionId: verb.action,
287
+ verbs: verb.verbs,
288
+ pattern: verb.requiresObject ?
289
+ (verb.allowsIndirectObject ? 'VERB_OBJ_PREP_OBJ' : 'VERB_OBJ') :
290
+ 'VERB_ONLY',
291
+ prepositions: verb.allowsIndirectObject ? ['in', 'on', 'to', 'with'] : undefined
292
+ }));
293
+ }
294
+ getDirections() {
295
+ return [
296
+ { direction: 'north', words: ['north'], abbreviations: ['n'] },
297
+ { direction: 'south', words: ['south'], abbreviations: ['s'] },
298
+ { direction: 'east', words: ['east'], abbreviations: ['e'] },
299
+ { direction: 'west', words: ['west'], abbreviations: ['w'] },
300
+ { direction: 'northeast', words: ['northeast'], abbreviations: ['ne'] },
301
+ { direction: 'northwest', words: ['northwest'], abbreviations: ['nw'] },
302
+ { direction: 'southeast', words: ['southeast'], abbreviations: ['se'] },
303
+ { direction: 'southwest', words: ['southwest'], abbreviations: ['sw'] },
304
+ { direction: 'up', words: ['up', 'upward', 'upwards'], abbreviations: ['u'] },
305
+ { direction: 'down', words: ['down', 'downward', 'downwards'], abbreviations: ['d'] },
306
+ { direction: 'in', words: ['in', 'inside'] },
307
+ { direction: 'out', words: ['out', 'outside'] }
308
+ ];
309
+ }
310
+ getSpecialVocabulary() {
311
+ return {
312
+ articles: words_1.englishWords.articles,
313
+ pronouns: words_1.englishWords.pronouns,
314
+ allWords: ['all', 'everything', 'every'],
315
+ exceptWords: ['except', 'but']
316
+ };
317
+ }
318
+ getCommonAdjectives() {
319
+ return words_1.englishWords.commonAdjectives;
320
+ }
321
+ getCommonNouns() {
322
+ return words_1.englishWords.commonNouns || [];
323
+ }
324
+ getPrepositions() {
325
+ return words_1.englishWords.prepositions;
326
+ }
327
+ getDeterminers() {
328
+ return words_1.englishWords.determiners || [];
329
+ }
330
+ getConjunctions() {
331
+ return words_1.englishWords.conjunctions || [];
332
+ }
333
+ getNumbers() {
334
+ return words_1.englishWords.numberWords || [];
335
+ }
336
+ getGrammarPatterns() {
337
+ return [
338
+ {
339
+ name: 'verb_noun_prep_noun',
340
+ pattern: 'VERB NOUN+ PREP NOUN+',
341
+ example: 'put ball in box',
342
+ priority: 100
343
+ },
344
+ {
345
+ name: 'verb_prep_noun',
346
+ pattern: 'VERB PREP NOUN+',
347
+ example: 'look at painting',
348
+ priority: 90
349
+ },
350
+ {
351
+ name: 'verb_noun',
352
+ pattern: 'VERB NOUN+',
353
+ example: 'take ball',
354
+ priority: 80
355
+ },
356
+ {
357
+ name: 'verb_only',
358
+ pattern: 'VERB',
359
+ example: 'look',
360
+ priority: 70
361
+ },
362
+ {
363
+ name: 'direction_only',
364
+ pattern: 'DIRECTION',
365
+ example: 'north',
366
+ priority: 60
367
+ }
368
+ ];
369
+ }
370
+ lemmatize(word) {
371
+ if (!word)
372
+ return '';
373
+ const lower = word.toLowerCase();
374
+ // Check irregular plurals
375
+ const singular = words_1.irregularPlurals.get(lower);
376
+ if (singular)
377
+ return singular;
378
+ // Handle special cases first
379
+ if (lower === 'yes' || lower === 'ties')
380
+ return lower;
381
+ // Simple rules for common endings
382
+ if (lower.endsWith('ies') && lower.length > 4) {
383
+ return lower.slice(0, -3) + 'y';
384
+ }
385
+ if (lower.endsWith('es') && lower.length > 3) {
386
+ // Don't lemmatize words like 'yes'
387
+ if (lower === 'yes')
388
+ return lower;
389
+ return lower.slice(0, -2);
390
+ }
391
+ if (lower.endsWith('s') && !lower.endsWith('ss') && lower.length > 2) {
392
+ return lower.slice(0, -1);
393
+ }
394
+ if (lower.endsWith('ed') && lower.length > 3) {
395
+ // Handle double consonants (dropped -> drop)
396
+ if (lower.length > 4 && lower[lower.length - 3] === lower[lower.length - 4]) {
397
+ return lower.slice(0, -3);
398
+ }
399
+ return lower.slice(0, -2);
400
+ }
401
+ if (lower.endsWith('ing') && lower.length > 4 && !lower.includes('-')) {
402
+ return lower.slice(0, -3);
403
+ }
404
+ return lower;
405
+ }
406
+ expandAbbreviation(abbreviation) {
407
+ return words_1.abbreviations.get(abbreviation.toLowerCase()) || null;
408
+ }
409
+ formatList(items, conjunction = 'and') {
410
+ if (items.length === 0)
411
+ return '';
412
+ if (items.length === 1)
413
+ return items[0];
414
+ if (items.length === 2)
415
+ return `${items[0]} ${conjunction} ${items[1]}`;
416
+ const allButLast = items.slice(0, -1);
417
+ const last = items[items.length - 1];
418
+ return `${allButLast.join(', ')}, ${conjunction} ${last}`;
419
+ }
420
+ getIndefiniteArticle(noun) {
421
+ if (!noun || noun.length === 0)
422
+ return 'a';
423
+ const firstChar = noun[0].toLowerCase();
424
+ const vowels = ['a', 'e', 'i', 'o', 'u'];
425
+ // Special cases
426
+ if (noun.toLowerCase().startsWith('hour'))
427
+ return 'an';
428
+ if (noun.toLowerCase().startsWith('honest'))
429
+ return 'an';
430
+ if (noun.toLowerCase().startsWith('uni'))
431
+ return 'a';
432
+ if (noun.toLowerCase().startsWith('one'))
433
+ return 'a';
434
+ return vowels.includes(firstChar) ? 'an' : 'a';
435
+ }
436
+ pluralize(noun) {
437
+ if (!noun)
438
+ return 's';
439
+ const lower = noun.toLowerCase();
440
+ // Check irregular plurals - the map is plural->singular, so we need to reverse lookup
441
+ for (const [plural, singular] of words_1.irregularPlurals) {
442
+ if (singular === lower) {
443
+ // Preserve the case pattern of the original noun
444
+ if (noun === noun.toUpperCase()) {
445
+ return plural.toUpperCase();
446
+ }
447
+ else if (noun[0] === noun[0].toUpperCase()) {
448
+ return plural[0].toUpperCase() + plural.slice(1);
449
+ }
450
+ return plural;
451
+ }
452
+ }
453
+ // Regular rules
454
+ if (lower.endsWith('s') || lower.endsWith('x') || lower.endsWith('z') ||
455
+ lower.endsWith('ch') || lower.endsWith('sh')) {
456
+ return noun + 'es';
457
+ }
458
+ if (lower.endsWith('y') && !['a', 'e', 'i', 'o', 'u'].includes(lower[lower.length - 2])) {
459
+ // Special handling for case preservation with -ies
460
+ if (noun === noun.toUpperCase()) {
461
+ return noun.slice(0, -1) + 'IES';
462
+ }
463
+ return noun.slice(0, -1) + 'ies';
464
+ }
465
+ if (lower.endsWith('f')) {
466
+ return noun.slice(0, -1) + 'ves';
467
+ }
468
+ if (lower.endsWith('fe')) {
469
+ return noun.slice(0, -2) + 'ves';
470
+ }
471
+ return noun + 's';
472
+ }
473
+ isIgnoreWord(word) {
474
+ return words_1.englishWords.ignoreWords.includes(word.toLowerCase());
475
+ }
476
+ /**
477
+ * Add a custom message to the language provider
478
+ * @param messageId The message identifier (e.g., 'custom.action.message')
479
+ * @param template The message template with optional {param} placeholders
480
+ */
481
+ addMessage(messageId, template) {
482
+ this.messages.set(messageId, template);
483
+ }
484
+ /**
485
+ * Add help information for a custom action
486
+ * @param actionId The action identifier (e.g., 'custom.action.foo')
487
+ * @param help The help information including usage, description, examples
488
+ */
489
+ addActionHelp(actionId, help) {
490
+ // Store the help information associated with the action
491
+ // This would require maintaining a separate help registry
492
+ // For now, we'll store it as messages with a special prefix
493
+ if (help.summary) {
494
+ this.messages.set(`${actionId}.help.summary`, help.summary);
495
+ }
496
+ if (help.description) {
497
+ this.messages.set(`${actionId}.help.description`, help.description);
498
+ }
499
+ if (help.examples) {
500
+ help.examples.forEach((example, index) => {
501
+ this.messages.set(`${actionId}.help.example.${index}`, example);
502
+ });
503
+ }
504
+ }
505
+ /**
506
+ * Add custom patterns/aliases for an action
507
+ * @param actionId The action identifier
508
+ * @param patterns Array of verb patterns/aliases
509
+ */
510
+ addActionPatterns(actionId, patterns) {
511
+ // Get existing custom patterns
512
+ const existing = this.customActionPatterns.get(actionId) || [];
513
+ // Merge with new patterns (avoiding duplicates)
514
+ const merged = [...existing];
515
+ for (const pattern of patterns) {
516
+ if (!merged.includes(pattern)) {
517
+ merged.push(pattern);
518
+ }
519
+ }
520
+ // Store the merged patterns
521
+ this.customActionPatterns.set(actionId, merged);
522
+ }
523
+ }
524
+ exports.EnglishLanguageProvider = EnglishLanguageProvider;
525
+ // Default export - create an instance
526
+ exports.default = new EnglishLanguageProvider();
527
+ //# sourceMappingURL=language-provider.js.map